mirror of
https://github.com/ZDoom/fluidsynth.git
synced 2025-04-08 00:31:11 +00:00
Add Polymono Support (#306)
This commit implements the polymono functionality as per MIDI spec. closes #306 resolves #158 Squashed commit of the following: commit b56e92b378f21b7fbc189e8c580d85e679c2ee3f Merge: 07f4c5330c9dda
Author: derselbst <tom.mbrt@googlemail.com> Date: Sat Mar 3 14:20:23 2018 +0100 Merge branch 'master' into polymono commit 07f4c53b9a0e46f511134d39d72073523fc3e202 Author: derselbst <tom.mbrt@googlemail.com> Date: Fri Mar 2 16:51:46 2018 +0100 update API docs for polymono commit 82c74ff07251e0fb34b15a066f501bf1e968a51c Merge: f07e515ba2c053
Author: derselbst <tom.mbrt@googlemail.com> Date: Fri Mar 2 10:41:43 2018 +0100 Merge branch 'master' into polymono commit f07e515ebdeb3d075bd9307ebf8768a6ffaae3e3 Author: derselbst <tom.mbrt@googlemail.com> Date: Fri Mar 2 10:39:44 2018 +0100 clarify comment commit 7635825325a168f9ee383afd8023d82d4c33c185 Author: jjceresa <jjc_fluid@orange.fr> Date: Thu Mar 1 04:13:52 2018 +0100 Enhancement of portamento performance calculation. - The lost of performance is now -0.5% rather -12%. commit 09cb1d3ec6ced215adec9faa09fac5cae6c0f8fc Author: jjceresa <jjc_fluid@orange.fr> Date: Wed Feb 21 19:40:17 2018 +0100 moving polymono commands among synth commands commit 63b8c480226b15d5d5bee5de8e1722a93ff69493 Author: jjceresa <jjc_fluid@orange.fr> Date: Wed Feb 21 03:16:10 2018 +0100 fixes comments, FLUID_INLINE, update pdf commit 49c1ee39d2ef525ac0af22ab22a4d8f8d49ab0e9 Merge: 200c8604a0a736
Author: derselbst <tom.mbrt@googlemail.com> Date: Sun Feb 11 17:38:31 2018 +0100 Merge branch 'master' into polymono commit 200c8609582560d781c0d49b99a9d02bdb7d2a2a Author: jjceresa <jjc_fluid@orange.fr> Date: Thu Feb 8 23:27:28 2018 +0100 Fixes typos, update /doc/polymono commit 9f6474cee712f947a0227957acbb4d1e4f56f2d6 Merge: cb7f43f 28b1bef Author: jjceresa <jjc_fluid@orange.fr> Date: Wed Feb 7 00:44:52 2018 +0100 merge before updating pdf document. commit cb7f43feb56edeed016b0b3ad7293fbd64beb7ae Author: jjceresa <jjc_fluid@orange.fr> Date: Wed Feb 7 00:40:52 2018 +0100 fixes typos in pdf document commit 28b1bef97a498ea5e15fdffb57b861998642bd5a Author: derselbst <tom.mbrt@googlemail.com> Date: Tue Feb 6 23:02:05 2018 +0100 avoid type redefinition warning commit 551940854053ccf0ff0d4cfd21d0e6328a9e657c Author: jjceresa <jjc_fluid@orange.fr> Date: Tue Feb 6 18:58:16 2018 +0100 cleanup fluid_synth.c commit 263f9badcb7f75bf8027df60abb20b3354ea67e2 Author: derselbst <tom.mbrt@googlemail.com> Date: Tue Feb 6 16:36:55 2018 +0100 cleanup fluid_synth.h commit fd58bc0c22756b67e75c80ed8efecfed9baf2901 Author: derselbst <tom.mbrt@googlemail.com> Date: Tue Feb 6 16:30:46 2018 +0100 move synth API macros back to fluid_synth.c commit 101ea0961a18c4724d7bd7f4d47f5a7fc27bb679 Author: derselbst <tom.mbrt@googlemail.com> Date: Tue Feb 6 16:17:15 2018 +0100 rename fluid_synth_mono.c to fluid_synth_monopoly.c commit ec60840304fdebf4d854a0879045249e9a90af79 Author: derselbst <tom.mbrt@googlemail.com> Date: Tue Feb 6 16:05:06 2018 +0100 move fluid_synth_polymono functions back to fluid_synth.c commit b18e99d34fcfef1444f235bed4c866985433f072 Author: derselbst <tom.mbrt@googlemail.com> Date: Tue Feb 6 15:43:18 2018 +0100 explicitly check for default_vel2att_mod commit ceeba2af7824c3e12f6a5302d79d4e582732141d Author: jjceresa <jjc_fluid@orange.fr> Date: Sun Feb 4 22:30:17 2018 +0100 Using INVALID_NOTE instead of -1 - polishing fluid_synth_noteon_monopoly_legato(). - Adds chapter "introducing Poly/mono basic channels API" (2.6.1) in pdf. commit 04d1a2119ad4847797c9cfc848a4158c6b0b3ce8 Author: derselbst <tom.mbrt@googlemail.com> Date: Sun Feb 4 19:49:25 2018 +0100 const correctness commit 7583bc24ad21df5e01b73b685f50e8a2eef3b2f3 Author: derselbst <tom.mbrt@googlemail.com> Date: Sun Feb 4 19:45:05 2018 +0100 fix naming convention commit a8e109f9f1ec3a55b6e0b9bfd9163e6dd4ea9e09 Author: jjceresa <jjc_fluid@orange.fr> Date: Sun Feb 4 01:39:58 2018 +0100 fixes comments, update pdf commit 1f33394a6579f9ee7341246df3e110db6926abeb Author: derselbst <tom.mbrt@googlemail.com> Date: Sat Feb 3 17:19:33 2018 +0100 remove duplicate comments commit e9451695aafece991af74ee2cfb9368d256c728a Author: derselbst <tom.mbrt@googlemail.com> Date: Sat Feb 3 17:06:09 2018 +0100 specify enum types explicitly commit f810f1942eaf19447ed29487209e227d7c4f8bd6 Author: jjceresa <jjc_fluid@orange.fr> Date: Fri Feb 2 18:54:03 2018 +0100 fix construction of new_mode - cleanup comment commit 3108da38ecc877e2f7428db0a988e1f05d324743 Author: derselbst <tom.mbrt@googlemail.com> Date: Fri Feb 2 11:42:44 2018 +0100 cleanup fluid_synth_cc_LOCAL() commit d61eea6aeff75cfb051e4baf546ff26073c2e62b Author: derselbst <tom.mbrt@googlemail.com> Date: Fri Feb 2 11:18:46 2018 +0100 inline warn string commit b7ed427470309e85c44da632f6fe9a319fc49683 Author: derselbst <tom.mbrt@googlemail.com> Date: Fri Feb 2 11:16:14 2018 +0100 unlock API mutex commit bc12603c993bf4af8ad260e18fd79f46e98c0785 Author: jjceresa <jjc_fluid@orange.fr> Date: Fri Feb 2 00:33:04 2018 +0100 fix comments in fluid_synth_polymono.c commit 34d8b73d856e3a0f664bfc816f20beff5f340627 Author: jjceresa <jjc_fluid@orange.fr> Date: Thu Feb 1 23:59:27 2018 +0100 fixes typos in comments commit eba067d735118077bf6bd8bb4ebb4bdab5046258 Author: jjceresa <jjc_fluid@orange.fr> Date: Thu Feb 1 23:47:58 2018 +0100 moving fluid_synth_check_next_basic_channel() commit 7976be599a4940ec0dc4420954ef8cfe310dd386 Author: jjceresa <jjc_fluid@orange.fr> Date: Wed Jan 31 23:26:42 2018 +0100 fluid_synth_set_basic_channel_LOCAL cannot change an existing basic channels. - Both fluid_synth_set_basic_channel_LOCAL() and fluid_synth_set_basic_channel_LOCAL() behave the same way. - Update documentation pdf. commit a22d1a35fac5b4f697c1d41ae3e368a61a27d653 Author: jjceresa <jjc_fluid@orange.fr> Date: Tue Jan 30 14:07:50 2018 +0100 command setbasicchannels can change an existing basic channel. - fix comments. - update documentation pdf. commit 4777f7b1f428935691be7d1289cb244c56137793 Author: jjceresa <jjc_fluid@orange.fr> Date: Mon Jan 29 23:37:16 2018 +0100 fluid_synth_set_basic_channel() is not allowed to change an existing basic channel commit 5161e4cec71a5c09eed08510458544257b7a66b2 Merge: 435d0622a4b208
Author: derselbst <tom.mbrt@googlemail.com> Date: Sat Jan 27 14:40:58 2018 +0100 Merge branch 'master' into polymono commit 435d062513583dea397686ec8fd442eba732f820 Author: jjceresa <jjc_fluid@orange.fr> Date: Sat Jan 27 00:09:42 2018 +0100 Fixes typos, update pdf documentation commit 13a8c6c6dd1a7dc861e367aed286c7f071b4e0ea Author: jjceresa <jjc_fluid@orange.fr> Date: Fri Jan 26 19:49:18 2018 +0100 correct comments of fluid_synth_set_basic_channel() - comments compliant with MIDI spec when val is 0. "means all possible channels from basic channel to MIDI count - 1". commit 0689257d8f1e880617a6039b677c1fe26a02d27b Author: derselbst <tom.mbrt@googlemail.com> Date: Thu Jan 25 20:03:07 2018 +0100 remove redundant channel mode flags from public API commit d632e30c419652cbb5e986fb35aeaf055dfc5b43 Author: derselbst <tom.mbrt@googlemail.com> Date: Thu Jan 25 19:57:11 2018 +0100 make fluid_synth_get_basic_channel() only return MIDI modes not fluidsynth's internal flags commit d1aa433e4a9aa1121bfaa78e1aa33e7ea5a88bae Author: derselbst <tom.mbrt@googlemail.com> Date: Thu Jan 25 19:43:42 2018 +0100 update API doc of fluid_synth_reset_basic_channel() commit b96f17b0c95a43e172da876108cb50756d023f94 Author: derselbst <tom.mbrt@googlemail.com> Date: Thu Jan 25 19:34:21 2018 +0100 make val of fluid_synth_set_basic_channel() compliant to MIDI spec commit 904fd36bc1fa7013665190d3a54469094892c0ec Author: derselbst <tom.mbrt@googlemail.com> Date: Thu Jan 25 19:25:16 2018 +0100 rename fluid_synth_reset_basic_channels() to fluid_synth_reset_basic_channel() commit 15a52f6bdfda37f5b25909ad566405543b4c0572 Author: derselbst <tom.mbrt@googlemail.com> Date: Thu Jan 25 19:21:00 2018 +0100 API doc cleanup and clarification commit 74c22da6fbfc3444cba448945579e451c28a333b Author: jjceresa <jjc_fluid@orange.fr> Date: Wed Jan 24 13:50:45 2018 +0100 Fixes mores comments in synth.h, fluid_cmd.c, fluid_synth_polymono.c commit 6718cfe68e8e4209bfc396d53bdc71f27edea1ba Author: jjceresa <jjc_fluid@orange.fr> Date: Tue Jan 23 20:19:17 2018 +0100 fix build, fix minor comments commit 9a4d9afc4230a3ff1ebfe8f5035ddd4aee1d4484 Author: jjceresa <jjc_fluid@orange.fr> Date: Tue Jan 23 19:53:12 2018 +0100 Cleanup basic channels API. - Removing fluid_basic_channels_infos struct. - Removing fluid_synth_get_basic_channels() API. - Clarifying fluid_synth_reset_basic_channels() API and fluid_synth_set_basic_channel() APIs. - Changes commands resetbasicchannels , setbasicchannels accordling to API changes. - Replace fluid_synth_get_channel_mode() API by fluid_synth_get_basic_channel() API. commit a2ec80ded11f95fcbde842c69b69efd8023c0e44 Author: jjceresa <jjc_fluid@orange.fr> Date: Fri Jan 19 13:35:32 2018 +0100 update examples in /doc/polymono, fix comments commit 1f283c49551d546db2394ba376291f716f8f3bbc Author: jjceresa <jjc_fluid@orange.fr> Date: Thu Jan 18 18:15:47 2018 +0100 remame SIZE_MONOLIST to FLUID_CHANNEL_SIZE_MONOLIST commit 06093a23e42379ba05ba888937bc9351208583c0 Author: jjceresa <jjc_fluid@orange.fr> Date: Thu Jan 18 16:08:43 2018 +0100 Adding comments compliant with MIDI specs. - Adding comments compliant with MIDI spec. for val parameters. - Cleanup comments. - Cleanup pdf document. commit 87e1dbda569b91f5f585232e4ca9086ac579b350 Author: jjceresa <jjc_fluid@orange.fr> Date: Mon Jan 15 10:23:43 2018 +0100 Adding fluid_synth_get_previous_basic_channel() commit 82fa1702643a506667c6d997962ac63381ce81ce Author: jjceresa <jjc_fluid@orange.fr> Date: Sun Jan 14 11:28:37 2018 +0100 adding fluid_channel_update_legato_staccato_state() commit 3309b6f172c56e9cb7c95fbeb09f6ebfe88351da Author: jjceresa <jjc_fluid@orange.fr> Date: Fri Jan 12 22:49:22 2018 +0100 integrates fluid_channel_keep_lastnote_monolist() commit 92f1e9230d065c8153baf64b77222891de417c99 Author: jjceresa <jjc_fluid@orange.fr> Date: Thu Jan 11 02:24:53 2018 +0100 adds comments commit f4241272d8fdd70da268fbdf04458055f084c446 Author: jjceresa <jjc_fluid@orange.fr> Date: Thu Jan 11 01:32:53 2018 +0100 Removing prev field in mononote struct - this is replaced by adding i_prev parameter in functions fluid_channel_search_monolist(),fluid_channel_remove_monolist(). commit b09da5ed213ba36279755a306c379d33e3cd3716 Author: jjceresa <jjc_fluid@orange.fr> Date: Thu Jan 11 01:28:11 2018 +0100 update comment API, update pdf commit 3308ca252d1f5894be6d9c26bb1763a2efb6a5a9 Author: derselbst <tom.mbrt@googlemail.com> Date: Wed Jan 10 11:01:45 2018 +0100 use fluid_cb2amp rather than fluid_atten2amp fixes build commit 6d648f44aeb1132e0f576521c2f35c4e30e7122f Merge: f881a0837218ba
Author: derselbst <tom.mbrt@googlemail.com> Date: Wed Jan 10 11:00:41 2018 +0100 Merge branch 'master' into polymono commit f881a08e6b3019f07a675e3dc11972364f1e4620 Author: jjceresa <jjc_fluid@orange.fr> Date: Wed Jan 10 09:51:23 2018 +0100 naming convention for fluid_synth_polymono commit bfb359a3299c7c6cc3384aa11a63eac354d93b62 Author: jjceresa <jjc_fluid@orange.fr> Date: Tue Jan 9 13:16:52 2018 +0100 apply allman braces commit 9275d7ae677463f8354c1163d9fd5af92a669b40 Author: jjceresa <jjc_fluid@orange.fr> Date: Tue Jan 9 11:23:18 2018 +0100 adding result checking functions commit 6e3c804ca4a43394929b6f77b6f43d486ea1db24 Author: jjceresa <jjc_fluid@orange.fr> Date: Mon Jan 8 12:48:39 2018 +0100 removing tabs mixed with spaces commit 94c46a8b689db7ce2e214f574d061d1f61f73e4b Author: jjceresa <jjc_fluid@orange.fr> Date: Sun Jan 7 19:29:01 2018 +0100 fix comment commit 1bedf8d5d4c547a7d7c9b920e7bfefa8204ed894 Author: jjceresa <jjc_fluid@orange.fr> Date: Sun Jan 7 19:05:06 2018 +0100 rename key_sustained, cleanup, fix typos commit 959144acad2312085ade3071c2cfa5b82ab87511 Author: jjceresa <jjc_fluid@orange.fr> Date: Sun Jan 7 04:36:27 2018 +0100 fix typos in comments commit c7b25cfd120f70c5b4092e5c625e903eeb40afdc Author: jjceresa <jjc_fluid@orange.fr> Date: Sun Jan 7 04:17:15 2018 +0100 cleanup on search/remove monolist functions commit 756424065e67913b09a1945413cde4513f727426 Author: derselbst <tom.mbrt@googlemail.com> Date: Sat Jan 6 20:22:22 2018 +0100 fix typo commit da991a236fac2e273aa9d60acb89061db956e980 Author: derselbst <tom.mbrt@googlemail.com> Date: Sat Jan 6 20:20:51 2018 +0100 use FLUID_STRCMP wrapper macro commit 0dc6d9bcd06615f9d33dfea7beec5fa29dc7230c Author: jjceresa <jjc_fluid@orange.fr> Date: Sat Jan 6 00:22:48 2018 +0100 simplify arguments checking functions commit 0103aa4ab08ab3cc8fe12906e8193f6a2a1984bd Author: jjceresa <jjc_fluid@orange.fr> Date: Fri Jan 5 16:57:12 2018 +0100 fix build warning commit 26773a567b894e2720038a26752b56b8705f4464 Author: jjceresa <jjc_fluid@orange.fr> Date: Fri Jan 5 16:04:17 2018 +0100 declare release_voice_on_same_note_LOCAL in fluid_synth.h commit 693ba8d300d824674b3d3d0dea0d89eb46a83e69 Author: jjceresa <jjc_fluid@orange.fr> Date: Fri Jan 5 15:50:39 2018 +0100 fix global cc, update comment, update pdf commit 9d35a509480aef4ea5be09c453fc0c5ce7e53077 Author: jjceresa <jjc_fluid@orange.fr> Date: Fri Jan 5 14:44:22 2018 +0100 adding arguments checking functions commit bd63cd2021bf46a78454884ba5c76a9659d3e5ee Author: jjceresa <jjc_fluid@orange.fr> Date: Thu Jan 4 18:01:57 2018 +0100 missing static const commit 4d24109b457a038cfb70d7e2fbe7fbbd1e25d05c Author: derselbst <tom.mbrt@googlemail.com> Date: Wed Jan 3 20:04:38 2018 +0100 apply naming convention to is_valid_note commit b1b6738b982cddd4c08839f557a46a6c8b23fa02 Author: derselbst <tom.mbrt@googlemail.com> Date: Wed Jan 3 20:00:46 2018 +0100 reoder fluid_channel_* declarations commit 56279b2622d738c1c910d7c64a30ab055670a6a1 Author: derselbst <tom.mbrt@googlemail.com> Date: Wed Jan 3 19:56:40 2018 +0100 move fluid_channel_*() functions to fluid_chan.c commit 2e54feb3beb0b89ec2203de259fa93c5343f1dfe Author: derselbst <tom.mbrt@googlemail.com> Date: Wed Jan 3 19:30:46 2018 +0100 more naming convention for fluid_synth_mono.c commit cd84bf96af7b4219920b5b070fbbf606eb5a21ef Author: jjceresa <jjc_fluid@orange.fr> Date: Wed Jan 3 18:57:13 2018 +0100 simplify portamemto pitch calc. commit af98b362ed0d471c46b7f1475c3c0de469d4f432 Author: derselbst <tom.mbrt@googlemail.com> Date: Wed Jan 3 10:37:42 2018 +0100 readd accidently removed custom_breath2att_mod fix build commit 1a4d5d392bee44677ed8e633d2acf4589b3dfdf6 Author: derselbst <tom.mbrt@googlemail.com> Date: Wed Jan 3 10:35:16 2018 +0100 make fluid_gen_info static again commit da4481dc278069cdc7452cd5e533613191df4830 Author: derselbst <tom.mbrt@googlemail.com> Date: Wed Jan 3 10:35:08 2018 +0100 fix comments commit fa6734bcdc66c581de39ff8db56d737852111a86 Merge: 47a0718dd2b78a
Author: derselbst <tom.mbrt@googlemail.com> Date: Wed Jan 3 10:14:35 2018 +0100 Merge branch 'master' into polymono commit 47a0718175ca8bd900d8ed823d502f0ef004a7d5 Author: derselbst <tom.mbrt@googlemail.com> Date: Wed Jan 3 10:11:36 2018 +0100 cleanup fluid_synth_*() forward decl. commit c730bcf296c0e5895158ef08bbee278a33e43e93 Author: derselbst <tom.mbrt@googlemail.com> Date: Wed Jan 3 10:06:32 2018 +0100 move polymono fluid_channel_* macros to fluid_chan.h commit 228c7bca6a17c13ac5a82d8faaf3fbc1fba39162 Author: derselbst <tom.mbrt@googlemail.com> Date: Wed Jan 3 09:57:09 2018 +0100 apply naming convention to polymono helper macros commit 0d2e16497f93b02649041a7dd5ff0697e94b443c Author: jjceresa <jjc_fluid@orange.fr> Date: Mon Jan 1 22:36:10 2018 +0100 move param checking, FLUID_API_ENTRY_CHAN to API, cleanup commit 1d73cec83bc4da75b754191db0105097874c8f39 Author: derselbst <tom.mbrt@googlemail.com> Date: Mon Jan 1 17:52:59 2018 +0100 remove redundant null termination for FLUID_SNPRINTF commit bca5472c347ef17203dfe7d37311a24b1c608b64 Merge: e64b08a70dffe7
Author: derselbst <tom.mbrt@googlemail.com> Date: Mon Jan 1 17:49:25 2018 +0100 Merge branch 'master' into polymono commit e64b08a800976bd5176a594f93ea4e050db5846c Author: jjceresa <jjc_fluid@orange.fr> Date: Sun Dec 31 15:22:54 2017 +0100 fix scope mode names commit fba23b6a018a96c4cb3779b43de79eb1b82b0495 Author: jjceresa <jjc_fluid@orange.fr> Date: Sun Dec 31 14:53:11 2017 +0100 fix comments, typo errors, update doc commit 330826eb4739e8521a31d58205359a353e7fc9ef Author: jjceresa <jjc_fluid@orange.fr> Date: Sun Dec 31 05:34:37 2017 +0100 adding mode name for shell command commit 52689198d1224540b36fc584aad0d885c9eea39a Author: jjceresa <jjc_fluid@orange.fr> Date: Sat Dec 30 22:48:37 2017 +0100 update doc API fluid_synth_set_basic_channel() commit 329df43f5d67a99b8dcdf2c7c6dd35bec6b3e356 Author: jjceresa <jjc_fluid@orange.fr> Date: Sat Dec 30 19:18:45 2017 +0100 fluid_synth_get_channel_mode() return basicchan commit 29de66116b2bf7a1545818a0604adf5a0559420f Author: jjceresa <jjc_fluid@orange.fr> Date: Sat Dec 30 17:59:32 2017 +0100 Simplfying fluid_synth_set_basic_channel signature - also cleanup variable declarations (static, scope, ...). - calling fluid_synth_set_basic_channel_LOCAL() instead of fluid_synth_set_basic_channel(). commit 5e9bc3977a9a3616ac4697c6b16e186656cd2baf Author: jjceresa <jjc_fluid@orange.fr> Date: Sat Dec 30 03:39:24 2017 +0100 cleanup status variable and rename variables commit 650ad51af9fcb1fa88ab64cfad868ce0d80fc917 Author: jjceresa <jjc_fluid@orange.fr> Date: Sat Dec 30 00:55:16 2017 +0100 remove basic channels settings update FluidPolyMono-0004.pdf - removing basic channels settings. - addding comment for Global channel. commit 1bbb520ab9b5c9b5cb954f3bc3d0ecf929237369 Author: jjceresa <jjc_fluid@orange.fr> Date: Sat Dec 30 00:49:31 2017 +0100 update comments on breat flags commit 795321aa8710c409dccd4773ccd8491f5427a7d9 Author: derselbst <tom.mbrt@googlemail.com> Date: Fri Dec 29 20:28:30 2017 +0100 reorder synth API macros commit e1589234d01a62e304e8edf53107e5a404829367 Author: derselbst <tom.mbrt@googlemail.com> Date: Fri Dec 29 20:20:52 2017 +0100 introduce FLUID_API_RETURN_IF_CHAN_DISABLED macro for synth to reduce nesting commit f8dee9b6ab02140d2104167fe7d273bfcf597abb Author: derselbst <tom.mbrt@googlemail.com> Date: Fri Dec 29 19:42:15 2017 +0100 correct API comment of fluid_synth_cc() commit 41083f4b970fa46e652609f92302f228dc6fe550 Author: derselbst <tom.mbrt@googlemail.com> Date: Fri Dec 29 10:49:43 2017 +0100 fix build forgot to commit fluid_synth.c commit ac04f365c715615f44885445ba7666050c655525 Author: derselbst <tom.mbrt@googlemail.com> Date: Fri Dec 29 10:49:03 2017 +0100 remove redundant fluid_channel_get_cc_portamento helper macro commit d707f5e0bc8807c4c43b51eb0503ef91f0d5c8b9 Author: derselbst <tom.mbrt@googlemail.com> Date: Fri Dec 29 10:45:13 2017 +0100 fix naming of fluid_channel helper macros commit fa38f6a9b2c3250f9dd77e5fd94a7107790ad1f6 Author: derselbst <tom.mbrt@googlemail.com> Date: Fri Dec 29 10:44:49 2017 +0100 handle BREATH_MSB is switch-case commit c68c7eb40cd020f0a0b068d8497328692c8e0800 Author: jjceresa <jjc_fluid@orange.fr> Date: Fri Dec 29 00:20:10 2017 +0100 fix comment in enum fluid_basic_channel_modes commit 56a63af296bc90f8b0e8bd075e7b4b57d2425310 Merge: c29e401 d35601a Author: derselbst <tom.mbrt@googlemail.com> Date: Thu Dec 28 20:33:19 2017 +0100 Merge branch 'polymono' of https://github.com/FluidSynth/fluidsynth into polymono commit c29e40157921a2de0abe8e8d7ff467ea63bc33a7 Author: derselbst <tom.mbrt@googlemail.com> Date: Thu Dec 28 20:32:33 2017 +0100 reorder polymono API calls to place them after the other synth functions commit 6ac82ff2b7a4b4079ec5121b40fe06bd13a4d08c Author: derselbst <tom.mbrt@googlemail.com> Date: Thu Dec 28 20:29:52 2017 +0100 cleanup polymono API comments commit d35601ae5a71bfbb11f2e6ea79c5a7bf766f6983 Author: jjceresa <jjc_fluid@orange.fr> Date: Thu Dec 28 19:15:10 2017 +0100 Fix typo in FluidPolyMono-0004.pdf Cleanup fluid_synth.c commit 731c59bcd64ac4e1ef06decf36774ed771c7bd41 Author: jjceresa <jjc_fluid@orange.fr> Date: Thu Dec 28 16:50:03 2017 +0100 Fix parameters checking in commands with no arguments. commit 6d0fa0f53ed07edaf0a71bc219d807ee35a5f50d Author: jjceresa <jjc_fluid@orange.fr> Date: Wed Dec 27 11:33:58 2017 +0100 update doc/polymono/readme.txt commit 3fa932e9188e27241be4acb4c4d3360ba630eda7 Author: jjceresa <32781294+jjceresa@users.noreply.github.com> Date: Sun Dec 24 22:20:05 2017 +0100 - Fix typos errors. commit 59e2ed3cc52c782dbad17847f083b96fff004165 Author: jjceresa <32781294+jjceresa@users.noreply.github.com> Date: Sun Dec 24 00:03:57 2017 +0100 Comments additions. commit 88f11588750b1e8196508c19e32e98ca540bf3f2 Author: jjceresa <32781294+jjceresa@users.noreply.github.com> Date: Sat Dec 23 23:42:21 2017 +0100 Removing fluid_voice_update_release() signature. commit 9b8cd5e5532a6f87ed516b83f728509f2ad0d890 Author: jjceresa <32781294+jjceresa@users.noreply.github.com> Date: Sat Dec 23 23:38:50 2017 +0100 Removing fluid_voice_update_release(). - removing fluid_voice_update_release(). - adding comments. commit 2787d150deb0c64519507f4fbfa8ef58a28d11b9 Author: jjceresa <32781294+jjceresa@users.noreply.github.com> Date: Sat Dec 23 23:24:55 2017 +0100 Using fluid_voice_release() in legato mode 0. substitute fluid_voice_update_release() by fluid_voice_release(). commit 68f7c7778b07a384d3d1648bb34bcf705a05affb Author: jjceresa <32781294+jjceresa@users.noreply.github.com> Date: Sat Dec 23 23:14:12 2017 +0100 Add comments to poly/mono public API. commit 51cedfdfed88883e00f08e4e9253f5bf08cb5287 Author: jjceresa <32781294+jjceresa@users.noreply.github.com> Date: Sat Dec 23 00:55:09 2017 +0100 Update FluidPolyMono-0004.pdf -Cleanup chapter 1. -Update doc API. commit 1ac23daf6dd10f1d1c0afc52bf1d7182d4d0538f Author: jjceresa <32781294+jjceresa@users.noreply.github.com> Date: Fri Dec 22 23:12:38 2017 +0100 Change enum in fluid_cmd.c commit 902f603c102689b58f86dfd789c01155d26c8bd8 Author: jjceresa <32781294+jjceresa@users.noreply.github.com> Date: Fri Dec 22 23:09:38 2017 +0100 Change enum names in fluid_synth_polymono.c commit df52819193c058cbce9201af647e740931889900 Author: jjceresa <32781294+jjceresa@users.noreply.github.com> Date: Fri Dec 22 23:03:59 2017 +0100 Change enum names in fluid_synth_mono.c commit 8aea95e0f4276d9904f9428e9a2cc93d8188a3e3 Author: jjceresa <32781294+jjceresa@users.noreply.github.com> Date: Fri Dec 22 22:56:29 2017 +0100 Change enum names in fluid_chan.c commit da0e94c2a8d8d7af8c5bbd81de7fa4cb7953372b Author: jjceresa <32781294+jjceresa@users.noreply.github.com> Date: Fri Dec 22 22:52:54 2017 +0100 Change legato and portamento enum -Change enum LegatoMode to enum fluid__channel_legato_mode. -Change enum PortamentoModeto enum fluid__fluid__channel_portamento_mode commit 75309ef3a322050b4d452144028ca909fef0977c Author: jjceresa <32781294+jjceresa@users.noreply.github.com> Date: Fri Dec 22 19:22:30 2017 +0100 Channel mode and Breath in commands Make use of enum fluid_basic_channel_mode_flags. commit 0aca0a4e9405dc2201f7201904a0192af0f4f5d4 Author: jjceresa <32781294+jjceresa@users.noreply.github.com> Date: Fri Dec 22 19:14:12 2017 +0100 Channel mode and breath in fluid_synth_polymono.c Make use of new enum fluid_basic_channel_mode_flags commit 4828760f45326884322d850ec50401825ded997b Author: jjceresa <32781294+jjceresa@users.noreply.github.com> Date: Fri Dec 22 18:52:59 2017 +0100 Rename enum in Fluid_synth_mono.c Make use of new values enum fluid_basic_channel_mode_flags commit a0246d16ed5db3d5771a9a60c13d66c628e11447 Author: jjceresa <32781294+jjceresa@users.noreply.github.com> Date: Fri Dec 22 18:44:31 2017 +0100 Rename enum in fluid_synth.c Make use of new enum fluid_basic_channel_mode_flags commit ba6dea233ab6667361eaefbb0e9b8cacbab6724f Author: jjceresa <32781294+jjceresa@users.noreply.github.com> Date: Fri Dec 22 18:10:34 2017 +0100 Change MONO name Change MONO to FLUID_CHANNEL_POLY_OFF commit 091bf7f3eeab75f1d5766592da9e6a0b1b1da5f4 Author: jjceresa <32781294+jjceresa@users.noreply.github.com> Date: Fri Dec 22 18:04:48 2017 +0100 Renaming enum fluid_basic_channel_mode_flags -Renaming enum fluid_basic_channel_mode_flags values. -Integrating Breath mode in enum fluid_basic_channel_mode_flags values. commit de945f2bb3af2692f9268e3afb37093709d47845 Author: jjceresa <32781294+jjceresa@users.noreply.github.com> Date: Fri Dec 22 03:56:40 2017 +0100 Move signatures to fluid_chan.h commit 614b74202b7c2d6aaf6b75cc524c908523549e37 Author: jjceresa <32781294+jjceresa@users.noreply.github.com> Date: Fri Dec 22 03:54:36 2017 +0100 Add sigature functions. void fluid_channel_set_onenote_monolist(fluid_channel_t* chan, unsigned char key, unsigned char vel); void fluid_channel_clear_monolist(fluid_channel_t* chan); void fluid_channel_invalid_prev_note_staccato(fluid_channel_t* chan); void fluid_channel_cc_legato(fluid_channel_t* chan, int value); void fluid_channel_cc_breath_note_on_off(fluid_channel_t* chan, int value); commit 963a37a36f3c2b2d494deeb472efe8b4ce5365a7 Author: jjceresa <32781294+jjceresa@users.noreply.github.com> Date: Fri Dec 22 01:39:25 2017 +0100 fix incorrect cast fix incorrect unsigned cast. remove unused extern. commit 67ff72659f4e83a0e0e24912e919071ae692f590 Author: jjceresa <32781294+jjceresa@users.noreply.github.com> Date: Wed Dec 20 23:45:12 2017 +0100 fix comments - fix help commands strings commit 2c4aff8773a363fa5902f1425c302bd4da8c8c68 Author: jjceresa <32781294+jjceresa@users.noreply.github.com> Date: Wed Dec 20 23:11:53 2017 +0100 Fix comments. commit 301712ac4686d2768aa6d441492a172f805c7fc4 Author: jjceresa <32781294+jjceresa@users.noreply.github.com> Date: Wed Dec 20 23:02:55 2017 +0100 Update FluidPolyMono-0004.pdf commit d4c4d0fc1382ee8795d3565d2373e8c2f36600a4 Author: jjceresa <32781294+jjceresa@users.noreply.github.com> Date: Wed Dec 20 22:45:07 2017 +0100 Update FluidPolyMono-0004.pdf commit 410b073565395ce6bc73194c99d9f8d48d632642 Author: jjceresa <32781294+jjceresa@users.noreply.github.com> Date: Wed Dec 20 22:33:44 2017 +0100 Add files via upload commit 0ce5bc65a676144631a3264ef27a6602b87152ae Author: jjceresa <32781294+jjceresa@users.noreply.github.com> Date: Wed Dec 20 19:27:16 2017 +0100 Update poly_mono_4.txt commit 088fd806464187dc23e07c843c3a25925a94313f Author: jjceresa <32781294+jjceresa@users.noreply.github.com> Date: Wed Dec 20 19:22:36 2017 +0100 Adds files leg_port_00.txt - leg_port_01.txt commit 9b98446a3f1c49c7bfcd51eb00a726eb918cdb70 Author: jjceresa <32781294+jjceresa@users.noreply.github.com> Date: Wed Dec 20 19:13:29 2017 +0100 Delete leg_por_4.txt commit c832a9b123af5456bce860197786f50555111652 Author: jjceresa <32781294+jjceresa@users.noreply.github.com> Date: Wed Dec 20 19:13:12 2017 +0100 Delete leg_por_3.txt commit 8cacbb99375b37310e30c1a681bcdcb204a9bd91 Author: jjceresa <32781294+jjceresa@users.noreply.github.com> Date: Wed Dec 20 19:12:57 2017 +0100 Delete leg_por_2.txt commit af04826db6ca384ed1797fcedf9200db40bbe458 Author: jjceresa <32781294+jjceresa@users.noreply.github.com> Date: Wed Dec 20 19:12:42 2017 +0100 Delete leg_por_1.txt commit 0cdf52de97779720917839f842d776eb7e1a7856 Author: jjceresa <32781294+jjceresa@users.noreply.github.com> Date: Wed Dec 20 19:12:25 2017 +0100 Delete leg_por_0.txt commit d750fe34dbd918bf0f3e6be391befc16c962bd1d Author: jjceresa <32781294+jjceresa@users.noreply.github.com> Date: Wed Dec 20 19:10:12 2017 +0100 Update leg_01.txt commit 1d9541d8cddb3a761d26739556275560d43acc10 Author: jjceresa <32781294+jjceresa@users.noreply.github.com> Date: Wed Dec 20 19:08:53 2017 +0100 Update leg_00.txt commit 237f6d500c375aea569930c675ff3463796e71b6 Author: jjceresa <32781294+jjceresa@users.noreply.github.com> Date: Wed Dec 20 19:03:44 2017 +0100 Delete Legato_demo.sf2 commit e875c02fbe8bf11fb3cb3ffc847e1d786c952a15 Author: jjceresa <32781294+jjceresa@users.noreply.github.com> Date: Wed Dec 20 19:01:34 2017 +0100 Update readme.txt Removing soundfont file commit 07335cfdb93a6b65d595debdef7973b53adfb62e Author: jjceresa <32781294+jjceresa@users.noreply.github.com> Date: Wed Dec 20 00:36:23 2017 +0100 Add FluidPolyMono-0004.pdf commit aa94b3fe12a1301a23c10a3f69a8212d18c36d8e Author: jjceresa <32781294+jjceresa@users.noreply.github.com> Date: Wed Dec 20 00:34:36 2017 +0100 Update readme.txt commit 3aa942922149541102f2c46584aac1aa1341c5ab Author: jjceresa <32781294+jjceresa@users.noreply.github.com> Date: Wed Dec 20 00:33:54 2017 +0100 Delete FluidPolyMono-0003.pdf commit ddd9b2de37d056a20b430f113e351ea6c786fc8e Author: jjceresa <32781294+jjceresa@users.noreply.github.com> Date: Wed Dec 20 00:30:52 2017 +0100 documentation files adding/update leg_00.txt leg_01.txt poly_mono_0.txt poly_mono_1.txt poly_mono_2.txt poly_mono_3.txt poly_mono_4.txt poly_mono_5.txt commit 89983fb42eb54a6bab5b6045e5a31a6800ef23ba Author: jjceresa <32781294+jjceresa@users.noreply.github.com> Date: Wed Dec 20 00:26:50 2017 +0100 Update readme.txt Removing legato modes 0,3,4 Tutorials examples addition chapter 2.1 poly_mono_0.txt poly_mono_1.txt poly_mono_2.txt poly_mono_3.txt poly_mono_4.txt poly_mono_5.txt commit dcedce20d79d317c834bfd6c961a3fdf87ed1f7f Author: jjceresa <32781294+jjceresa@users.noreply.github.com> Date: Wed Dec 20 00:17:56 2017 +0100 Delete leg_2.txt commit a9d765def0170e204027abfa42fc02acfdd47704 Author: jjceresa <32781294+jjceresa@users.noreply.github.com> Date: Wed Dec 20 00:17:29 2017 +0100 Delete leg_1.txt commit 8e0fc533d69cb261c0cfd6a8f58fe729b758ab0e Author: jjceresa <32781294+jjceresa@users.noreply.github.com> Date: Wed Dec 20 00:17:00 2017 +0100 Delete leg_4.txt commit ae670075e592241830ef539c9bf26c4cd84a3a47 Author: jjceresa <32781294+jjceresa@users.noreply.github.com> Date: Wed Dec 20 00:16:14 2017 +0100 Delete leg_3.txt commit 6040f7575277f53c8803155d58fd158cb8e29a5f Author: jjceresa <32781294+jjceresa@users.noreply.github.com> Date: Wed Dec 20 00:15:23 2017 +0100 Delete leg_0.txt commit 1e8c4ad4dc7b6ecd0727a73b0ac814679b9fd4f3 Author: jjceresa <32781294+jjceresa@users.noreply.github.com> Date: Tue Dec 19 23:34:03 2017 +0100 fix build type conflict. commit a0fa4debd6fc21d652edfabaaf963b31babcd045 Author: jjceresa <32781294+jjceresa@users.noreply.github.com> Date: Tue Dec 19 23:21:10 2017 +0100 Removing legato modes (0,3,4). commit f53476bfc0c46b313f5b293243a3f3b6d9c3af64 Author: jjceresa <32781294+jjceresa@users.noreply.github.com> Date: Tue Dec 19 23:01:50 2017 +0100 Removing legato modes (0,3,4). commit d69868bdb8179e1eb75661d6b02799de0d7a3e48 Author: jjceresa <32781294+jjceresa@users.noreply.github.com> Date: Tue Dec 19 22:57:22 2017 +0100 Removing legato modes (0,3,4). commit ebd37fdb680e3062f0174fe7c414b3fce6b8c60f Author: jjceresa <32781294+jjceresa@users.noreply.github.com> Date: Tue Dec 19 22:53:38 2017 +0100 Removing legato modes (0,3,4). commit 265eeb4f321a8bab54ae6aa700474d96a3c83951 Author: jjceresa <32781294+jjceresa@users.noreply.github.com> Date: Tue Dec 19 22:47:25 2017 +0100 Removing legato modes (0,3,4). commit 601216e83e01953c58ceabd0e44cc4f361d1c4ae Author: jjceresa <32781294+jjceresa@users.noreply.github.com> Date: Tue Dec 19 22:44:18 2017 +0100 Removing legato modes (0,3,4). commit 16b0e65697d57d3bc653e3419d924799b37e3a01 Author: jjceresa <32781294+jjceresa@users.noreply.github.com> Date: Tue Dec 19 22:39:17 2017 +0100 Removing legato modes (0,3,4). commit 5c4b9322e7b6f8600be9849d869233f20beb3d4c Author: jjceresa <32781294+jjceresa@users.noreply.github.com> Date: Tue Dec 19 22:31:16 2017 +0100 Two legato modes 1 and 2 (rnumbered 0 and 1). Removing legato modes (0,3,4). Legato modes 1,2 are numbered 0,1 respectively. commit 8c4096910e9e44c896f7169345d6a262a17e522d Author: jjceresa <32781294+jjceresa@users.noreply.github.com> Date: Tue Dec 19 22:25:33 2017 +0100 Two legato modes 0 and 1 (dfefault mode: 1). commit fb4205b215648efc1949708073f68237eed8679a Author: jjceresa <32781294+jjceresa@users.noreply.github.com> Date: Tue Dec 19 22:20:56 2017 +0100 Two legato modes 1 and 2 (rnumbered 0 and 1). Removing legato modes (0,3,4). Legato modes 1,2 are numbered 0,1 respectively. commit d0adfe31f4961d034483a95705ac8b86839cf11d Author: derselbst <tom.mbrt@googlemail.com> Date: Sat Dec 16 11:42:31 2017 +0100 refactor poly mono bit flags commit da5ac8dd79479b6a19f5c3608be7ec3507a5b637 Merge: 13754fa07a167c
Author: derselbst <tom.mbrt@googlemail.com> Date: Sat Dec 16 10:37:34 2017 +0100 Merge branch 'master' into polymono commit 13754fad6acbce51bdf5b57526a4ca243948a3ed Author: jjceresa <32781294+jjceresa@users.noreply.github.com> Date: Fri Dec 15 19:38:04 2017 +0100 Fix bug in new_fluid_preset_zone(). Add missing initialization since moving ignoreInstrumentZone check to fluid_zone_inside_range(). commit 64dc235485a004e7b0f6e8f9afae1375321f6afa Author: derselbst <tom.mbrt@googlemail.com> Date: Wed Dec 13 13:41:32 2017 +0100 move ignoreInstrumentZone check to fluid_zone_inside_range() commit 427a513e2caac645bc571a8fbe7e3a513f874fa1 Author: derselbst <tom.mbrt@googlemail.com> Date: Wed Dec 13 13:20:36 2017 +0100 fix spelling of IGNORE_INST_ZONE commit c9b74903f1e54976b0ed3e5d4aa5e5a2ba2f8c1c Author: derselbst <tom.mbrt@googlemail.com> Date: Wed Dec 13 13:17:32 2017 +0100 remove redundant NULL check fixes #302 commit 9c8f41be408475ebc8a16dbf468067c795ee5830 Merge: 09fcf6c5806d9e
Author: derselbst <tom.mbrt@googlemail.com> Date: Sun Dec 10 10:03:31 2017 +0100 Merge branch 'master' into polymono commit 09fcf6c3fc36739a29b79008224dd0b46f827cd1 Merge: 94408841629f9f
Author: derselbst <tom.mbrt@googlemail.com> Date: Sat Dec 9 15:16:51 2017 +0100 Merge branch 'master' into polymono commit 944088440f4c91ce712909a12af1332b09b9a1c5 Author: jjceresa <32781294+jjceresa@users.noreply.github.com> Date: Tue Dec 5 00:51:55 2017 +0100 fix bug GEN_VELRANGE commit 73caf02a323776bd320d30624ebe4dd60a1c940f Author: derselbst <tom.mbrt@gmail.com> Date: Sun Dec 3 14:59:30 2017 +0100 cleanup commit b0f43feac5de166f5791d6203d4c78f9f4f3ab38 Author: derselbst <tom.mbrt@gmail.com> Date: Sun Dec 3 14:31:45 2017 +0100 rename fluid_inst_zone_range_t to fluid_zone_range_t find . -type f -exec sed -i 's/fluid_inst_zone_range_t/fluid_zone_range_t/g' {} + commit 133b418ca5641579eb22cacb5059c48b642b8f5e Author: derselbst <tom.mbrt@gmail.com> Date: Sun Dec 3 14:28:45 2017 +0100 make use of range struct for presets as well remove code duplications commit 42e23a5e398520959bf1124439539e0f278a80fc Author: derselbst <tom.mbrt@gmail.com> Date: Sun Dec 3 13:44:33 2017 +0100 remove zone_range from _fluid_synth_t prefer explicit parameter passing rather than hacky non-threadsafe param struct saving commit 2bc061557b9aedb9a2c0f891488aeb1122272395 Merge: 6037bdbcdfe8d3
Author: derselbst <tom.mbrt@gmail.com> Date: Sun Dec 3 13:31:57 2017 +0100 Merge branch 'master' into polymono commit 6037bdbd30f793b007c589b5f870cabea2c85c6a Author: jjceresa <32781294+jjceresa@users.noreply.github.com> Date: Wed Nov 29 23:45:10 2017 +0100 fix parameter flfuid_voice_init() commit bb0da222bd420989b63b0229568b178e8da3e293 Author: jjceresa <32781294+jjceresa@users.noreply.github.com> Date: Wed Nov 29 23:24:12 2017 +0100 fix IGNORE_INST_Z0NE commit d8752cc835b52eda6122dba7d6ab2354a7e83deb Author: jjceresa <32781294+jjceresa@users.noreply.github.com> Date: Wed Nov 29 23:16:56 2017 +0100 fix fluid_voice_init in voice.h commit 41e4b77fe5f6fc0766b1974d5031d516a7ff0c11 Author: jjceresa <32781294+jjceresa@users.noreply.github.com> Date: Wed Nov 29 23:04:45 2017 +0100 Add zone_range tp poly_mono.c commit f3550d18e74845a09800af8aef12f5c5da21fc7b Author: jjceresa <32781294+jjceresa@users.noreply.github.com> Date: Wed Nov 29 22:51:30 2017 +0100 Add zone_range to fluid_voice_init() commit 2e9ebad6cb5bd44e82674e87ef4fb7b88b9b9445 Author: jjceresa <32781294+jjceresa@users.noreply.github.com> Date: Wed Nov 29 22:48:13 2017 +0100 Add zone_range to fluid_voice_t commit d779583c490d85ea8b14481fcedbe50efda27aed Author: jjceresa <32781294+jjceresa@users.noreply.github.com> Date: Wed Nov 29 22:41:45 2017 +0100 restore fluid_synth_alloc_voice signature restore fluid_synth_alloc_voice signature to synth.h commit 27a4e4407843cfb7c7c86b6a99c0f10d43ad4326 Author: jjceresa <32781294+jjceresa@users.noreply.github.com> Date: Wed Nov 29 22:36:06 2017 +0100 Add zone_range to fluid_synth.c Restore API signature luid_synth_alloc_voice() commit f4749fc88372a32b055a6dcb6a1b00e247d15c6b Author: jjceresa <32781294+jjceresa@users.noreply.github.com> Date: Wed Nov 29 22:27:03 2017 +0100 Add zone_range to fluid_synth.h commit 7250f40d7aa3dc074c3ffd6dfb1e6aa2821c26f2 Author: jjceresa <32781294+jjceresa@users.noreply.github.com> Date: Wed Nov 29 22:24:37 2017 +0100 Add zone_range to ramsfont commit a3ffce39355c7fcb86c25ae5c0254758a502b1f3 Author: jjceresa <32781294+jjceresa@users.noreply.github.com> Date: Wed Nov 29 22:19:39 2017 +0100 Adding zone_range. commit e2f99a91e58950373f99032eb1fa752805ed8eee Author: jjceresa <32781294+jjceresa@users.noreply.github.com> Date: Wed Nov 29 22:03:44 2017 +0100 type fluid_inst_zone_range_t commit adb5e74311b6010289d7f672985cc24f9153bcfd Author: jjceresa <32781294+jjceresa@users.noreply.github.com> Date: Wed Nov 29 21:57:05 2017 +0100 Adding fluid_inst_zone_range_t in fluid_inst_zone_t commit 89ed46f063301096f0ce4a3b673a8fce3b6c4cde Merge: 45773e17ed5d1f
Author: derselbst <tom.mbrt@googlemail.com> Date: Fri Nov 24 17:40:17 2017 +0100 Merge branch 'master' into polymono commit 45773e14d21a56085da7344d0168fb87a9a58607 Author: jjceresa <32781294+jjceresa@users.noreply.github.com> Date: Thu Nov 23 23:44:10 2017 +0100 Ignore voices when there is no instrument zone. commit 156eb2f547cff9e0bca43830ed35f9bb315e48c4 Author: jjceresa <32781294+jjceresa@users.noreply.github.com> Date: Sat Nov 11 00:03:29 2017 +0100 Fix warning build commit 1b1233014a3d8b1fdf043d1fdd4ea51cb6b0aaf9 Author: jjceresa <32781294+jjceresa@users.noreply.github.com> Date: Fri Nov 10 20:06:23 2017 +0100 Fix fluid_voice_is_on(voice) commit 88317aaaa8e33f999393a0a582110642e1726e93 Author: jjceresa <32781294+jjceresa@users.noreply.github.com> Date: Fri Nov 10 19:55:30 2017 +0100 Replacement of macro _ON(voice ) Replacement of macro _ON() by fluid_voice_is_on() Note : fluid_voice_is_on() isn't yet in fluid_voice.h, so to avoid a failing build we define fluid_voice_is_on() extern. commit 0ba247f2c6c5b93c3354069b791b46be9d9b6235 Author: jjceresa <32781294+jjceresa@users.noreply.github.com> Date: Fri Nov 10 18:35:34 2017 +0100 Fix functions naming in chapter 4. commit aeaceefa24b03f0ff28b6fb734c56ab40d16fbf8 Author: jjceresa <32781294+jjceresa@users.noreply.github.com> Date: Fri Nov 10 18:34:25 2017 +0100 Delete FluidPolyMono-0003.pdf commit 24f1fa56974dde407007b48f065f0779d78ddfb5 Author: jjceresa <32781294+jjceresa@users.noreply.github.com> Date: Fri Nov 10 18:31:25 2017 +0100 Addition of missing comments Comments in fluid_synth_noteon_LOCAL(), fluid_synth_damp_voices_by_sustain_LOCAL(), fluid_synth_damp_voices_by_sostenuto_LOCAL() commit 023a101642fc246c542e900cabdbc1dae24829f0 Author: jjceresa <32781294+jjceresa@users.noreply.github.com> Date: Thu Nov 9 23:15:59 2017 +0100 renaming functions commit 87e26ff24b7f30731ff59878f444c58747dc3277 Author: jjceresa <32781294+jjceresa@users.noreply.github.com> Date: Thu Nov 9 23:08:46 2017 +0100 Renaming functions commit 1b41b67e6fd9ec4ee789abc0448bec8db8923046 Author: jjceresa <32781294+jjceresa@users.noreply.github.com> Date: Thu Nov 9 23:04:54 2017 +0100 renaming functions commit 486dfed111bce8e48b4bad59d0330e4593e92cbf Author: jjceresa <32781294+jjceresa@users.noreply.github.com> Date: Thu Nov 9 22:59:41 2017 +0100 Renaming functions commit 0d5269520b652114251c13f0d87b2c8ec062a60c Author: jjceresa <32781294+jjceresa@users.noreply.github.com> Date: Thu Nov 9 22:01:24 2017 +0100 Fix build commit 7c0c3c2944ee15a69d7e1b6c1ae6d4c35f062156 Author: jjceresa <32781294+jjceresa@users.noreply.github.com> Date: Thu Nov 9 21:58:46 2017 +0100 Fix build commit 1c7958250d48bdfa46b7df8918d087323ee9bc4c Author: jjceresa <32781294+jjceresa@users.noreply.github.com> Date: Thu Nov 9 20:15:35 2017 +0100 fix build commit dd4c86a2245c76c74781fa3dfa236cd9acfd225e Author: jjceresa <32781294+jjceresa@users.noreply.github.com> Date: Thu Nov 9 20:02:32 2017 +0100 Fix build commit 490d0745dc6e6338b2641f68bac8da86a83b6ed7 Author: jjceresa <32781294+jjceresa@users.noreply.github.com> Date: Thu Nov 9 19:49:29 2017 +0100 Add macro #define _ON(voice) to fix build commit 553a1dc13b87ea0158c7dd2cab8aa7787dc60f2f Author: jjceresa <32781294+jjceresa@users.noreply.github.com> Date: Thu Nov 9 18:26:04 2017 +0100 Fix build in legato_on_off() commit e075c1e7ba695f3529422c74a77ed2571368a729 Author: jjceresa <32781294+jjceresa@users.noreply.github.com> Date: Thu Nov 9 18:22:10 2017 +0100 Fix comments commit fe763339e3ac3872afcb7bbf557884d31306868a Author: jjceresa <32781294+jjceresa@users.noreply.github.com> Date: Thu Nov 9 18:19:01 2017 +0100 Fix comments commit 662a3632d863fab6e9a949e4030f3018cea49660 Author: jjceresa <32781294+jjceresa@users.noreply.github.com> Date: Thu Nov 9 16:41:37 2017 +0100 Updating Chapter 4 commit e15a0198fe6af9c52004159933faeb7cc7bdb0fc Author: jjceresa <32781294+jjceresa@users.noreply.github.com> Date: Thu Nov 9 16:40:30 2017 +0100 Delete FluidPolyMono-0003.pdf commit 5bec835f3aa7c4d605a04d66b7eadce9aaf2e276 Author: jjceresa <32781294+jjceresa@users.noreply.github.com> Date: Thu Nov 9 16:01:00 2017 +0100 Renaming fluid_synth_noteon_mono_legato() Renaming fluid_synth_noteon_mono_legato() to fluid_synth_noteon_monopoly_legato() commit 1192769461366dbe496ae41d3ba24f97418013eb Author: jjceresa <32781294+jjceresa@users.noreply.github.com> Date: Thu Nov 9 15:56:17 2017 +0100 Renaming fluid_synth_noteon_mono_legato() Renaming fluid_synth_noteon_mono_legato() to fluid_synth_noteon_monopoly_legato() commit f76b3062f8ec32ad0cc361af3b4755db128e020e Author: jjceresa <32781294+jjceresa@users.noreply.github.com> Date: Thu Nov 9 15:52:51 2017 +0100 Renaming fluid_synth_noteon_mono_legato() Renaming fluid_synth_noteon_mono_legato() to fluid_synth_noteon_monopoly_legato() commit b80684df57523f55f346c95e4731756715821572 Author: jjceresa <32781294+jjceresa@users.noreply.github.com> Date: Thu Nov 9 15:47:57 2017 +0100 Renaming fluid_synth_noteon_mono_legato() Renaming fluid_synth_noteon_mono_legato() to fluid_synth_noteon_monopoly_legato() commit 181affa17f9099fb3606ee326ee819ad4736cc6b Author: jjceresa <32781294+jjceresa@users.noreply.github.com> Date: Thu Nov 9 15:45:51 2017 +0100 Renaming fluid_synth_noteon_mono_legato() Renaming fluid_synth_noteon_mono_legato() to fluid_synth_noteon_monopoly_legato() commit 2efbfa98c7a2f80a11a8847ff3d89cc2d545f971 Author: jjceresa <32781294+jjceresa@users.noreply.github.com> Date: Thu Nov 9 00:11:39 2017 +0100 Update documentation Addition of figures in chapter 4. Part 4: Appendices for understanding implementations in FluidSynth. commit a32b12b15c37669c1c1bda9228955bacd9844400 Author: jjceresa <32781294+jjceresa@users.noreply.github.com> Date: Thu Nov 9 00:08:26 2017 +0100 Delete FluidPolyMono-0003.pdf commit ee3820fedd5024131ecbf0f6a66936792c651818 Author: jjceresa <32781294+jjceresa@users.noreply.github.com> Date: Thu Nov 9 00:01:45 2017 +0100 Comments addition Comment addition about the size of monolist SIZE_MONOLIST. commit fbf496d8f7c79ed8a72ffb22a12f0ead28815084 Author: jjceresa <32781294+jjceresa@users.noreply.github.com> Date: Wed Nov 8 23:57:59 2017 +0100 Comments addition Comments addition relative to FluidPolyMono-0003.pdf chapter 4: "Appendices for understanding implementations in FluidSynth" commit af551859b7558e73915c6fefab873c0ebb46221c Author: jjceresa <32781294+jjceresa@users.noreply.github.com> Date: Tue Nov 7 00:29:30 2017 +0100 Update FluidPolyMono.pdf Removing obsoletes chapters. Adding appendices for understanding implementations in FluidSynth (see chapter 4). commit 8953f099bcfbeb58ecbf0b4ad69e97d004cef7bd Author: jjceresa <32781294+jjceresa@users.noreply.github.com> Date: Tue Nov 7 00:26:36 2017 +0100 Delete FluidPolyMono-0003.pdf commit d000ddac93df0c12ecbe4b2de6b3d4fee1b6b06e Author: jjceresa <32781294+jjceresa@users.noreply.github.com> Date: Tue Nov 7 00:23:33 2017 +0100 Fix typos errors commit 539c0b3c5db214765ada1ac214391bea33aa2f97 Author: jjceresa <32781294+jjceresa@users.noreply.github.com> Date: Tue Nov 7 00:19:06 2017 +0100 Fix typos errors commit 168669bb603fff83166e3c8df1aff972415dd921 Author: jjceresa <32781294+jjceresa@users.noreply.github.com> Date: Sun Nov 5 03:11:11 2017 +0100 correction typos erros commit 8afb104f880660c08556f712aa804c2cb889eb2d Author: jjceresa <32781294+jjceresa@users.noreply.github.com> Date: Sun Nov 5 02:16:02 2017 +0100 Adding a new chapter. Adding chapter : 3.11. PART 3: APPENDICES FOR UNDERSTANDING IMPLEMENTATIONS IN FS. commit d21a528e474e13d62ac4141d224b9d1d16ca8a29 Author: jjceresa <32781294+jjceresa@users.noreply.github.com> Date: Sun Nov 5 02:13:16 2017 +0100 delete FluidPolyMono-0003.pdf commit 942d911dc886ef391cb8975b93c4380c1c4d8977 Author: jjceresa <32781294+jjceresa@users.noreply.github.com> Date: Sun Nov 5 02:07:08 2017 +0100 changes functions name invalid_prev_note_staccato(), legato_on_off(),breath_note_on_off() commit 62c2529ae3f983797713b64cdaaa2e4c2cb2e3c9 Author: jjceresa <32781294+jjceresa@users.noreply.github.com> Date: Sun Nov 5 02:01:03 2017 +0100 Changes names functions invalid_prev_note_staccato(),legato_on_off(), breath_note_on_off() commit 10271467d86530b16ef606ddbda964215e73690e Author: jjceresa <32781294+jjceresa@users.noreply.github.com> Date: Sun Nov 5 01:53:35 2017 +0100 update functions documentation Documentation addition. Correct get_fromkey_portamento_legato() name. Changes names: legato_on_off(), breath_note_on_off(),invalid_prev_note_staccato() commit decf7817706a5ade25903730d11135acfee77817 Merge: 84ee8b330c0a72
Author: derselbst <tom.mbrt@gmail.com> Date: Sat Nov 4 08:52:21 2017 +0100 Merge branch 'master' into polymono commit 84ee8b3304d87485cd21d802214d670183e51c17 Author: jjceresa <32781294+jjceresa@users.noreply.github.com> Date: Thu Nov 2 20:18:03 2017 +0100 Polishing and documenting commit 99eaf83cef87555926c0078eb38912901a80b003 Author: jjceresa <32781294+jjceresa@users.noreply.github.com> Date: Thu Nov 2 20:14:36 2017 +0100 Polishing and documenting commit 172a9b0cae9aef9a18abb31aa4c2d7543b4ea054 Author: jjceresa <32781294+jjceresa@users.noreply.github.com> Date: Thu Nov 2 19:43:51 2017 +0100 Polishing commit 0d0b47181df5cea717ab848e88e5e87a2ce643e1 Author: jjceresa <32781294+jjceresa@users.noreply.github.com> Date: Thu Nov 2 19:00:41 2017 +0100 Polishing commit f55273986d847e99814bd92d8fc109dea02a85f3 Author: jjceresa <32781294+jjceresa@users.noreply.github.com> Date: Thu Nov 2 18:50:38 2017 +0100 Polishing commit fb6f0eac8ce50a987ff438e942d59d1c24b769c4 Author: jjceresa <32781294+jjceresa@users.noreply.github.com> Date: Thu Nov 2 18:43:54 2017 +0100 Polishing commit fe8e7f692d89be52a95ae2726b1b20870c7fe042 Author: jjceresa <32781294+jjceresa@users.noreply.github.com> Date: Thu Nov 2 18:35:56 2017 +0100 Polishing commit 8e37f562c14141c573a13bb43e9612a3586e672e Author: jjceresa <32781294+jjceresa@users.noreply.github.com> Date: Thu Nov 2 18:23:06 2017 +0100 polishing commit 8a20a766f995c3c5d9928bb46270758fc92c29a1 Author: jjceresa <32781294+jjceresa@users.noreply.github.com> Date: Thu Nov 2 18:18:25 2017 +0100 polishing commit 3dab1a0edc973c0ddfa762b214a22dff4d2e9bb5 Author: jjceresa <32781294+jjceresa@users.noreply.github.com> Date: Mon Oct 30 01:23:11 2017 +0100 Again avoid macros Avoid GetPortamentoMode, GetLegatoMode macros commit d39cfe5a199cb7179a174d11dadbfd2bcb992088 Author: jjceresa <32781294+jjceresa@users.noreply.github.com> Date: Mon Oct 30 01:18:44 2017 +0100 Again avoiding macros Avoid GetChanPortamentoMode, GetChanLegatoMode macros commit bb519495956f5e3d0bc5264d3aea491e5de85afb Author: jjceresa <32781294+jjceresa@users.noreply.github.com> Date: Mon Oct 30 01:11:54 2017 +0100 Again avoiding macros Avoiding GetChanLegatoMode, GetChanPortamentoMode macros commit c31449626ad195b3fd44215f8bd51be8cfcc6a29 Author: jjceresa <32781294+jjceresa@users.noreply.github.com> Date: Mon Oct 30 00:40:05 2017 +0100 Add FluidPolyMono-0003.pdf Adding explanations about the legato detector (3.4.3). Adding example about breathmode (3.4.5). commit 53f215e602156ecfbb8aeef81ba7a19e201313d4 Author: jjceresa <32781294+jjceresa@users.noreply.github.com> Date: Mon Oct 30 00:38:15 2017 +0100 Delete FluidPolyMono-0003.pdf commit 7dcde051986ae8b17c0613e83f0253db647dd1ee Author: jjceresa <32781294+jjceresa@users.noreply.github.com> Date: Mon Oct 30 00:30:20 2017 +0100 Again avoiding macros commit 8afbb4503a98d9caa9a85f703d19740bd07ade36 Author: jjceresa <32781294+jjceresa@users.noreply.github.com> Date: Mon Oct 30 00:24:57 2017 +0100 Again avoid macros commit 4e2a6750c15973cb2515c2f9b7971d821b04031a Author: jjceresa <32781294+jjceresa@users.noreply.github.com> Date: Mon Oct 30 00:16:04 2017 +0100 Again avoid macros commit 21ae600907287e87f35a8f9c1cd1e0fe6e920565 Author: jjceresa <32781294+jjceresa@users.noreply.github.com> Date: Mon Oct 30 00:02:41 2017 +0100 Again avoiding macros commit a0ec029bd886682b3d88ed8150ef90c29a75eec7 Author: jjceresa <32781294+jjceresa@users.noreply.github.com> Date: Sun Oct 29 23:46:53 2017 +0100 Again avoiding macros commit 1e583799f6690253bfcad4cbc4fb5fb0f5b9fa99 Author: jjceresa <32781294+jjceresa@users.noreply.github.com> Date: Sun Oct 29 23:18:26 2017 +0100 avoiding macros commit d92445b99f0a3fd7f896bd03afca05eaa1271b9c Author: jjceresa <32781294+jjceresa@users.noreply.github.com> Date: Fri Oct 27 16:37:34 2017 +0200 Avoid nested macros commit 71d6a180cb574a754e30a821b52b1a975bc4b2f6 Author: jjceresa <32781294+jjceresa@users.noreply.github.com> Date: Fri Oct 27 16:13:30 2017 +0200 avoid nested macros commit e22013c37d01734c4bc535eba65e6b2cd8db0aad Author: jjceresa <32781294+jjceresa@users.noreply.github.com> Date: Fri Oct 27 15:40:47 2017 +0200 Avoid nested macros commit 92ba702ffca8284470f45d6568ffa6d81be3a5db Author: jjceresa <32781294+jjceresa@users.noreply.github.com> Date: Fri Oct 27 14:54:19 2017 +0200 Cleanup macro. commit 2a31e93320907779cd7f56d62991bcce00bedaba Author: jjceresa <32781294+jjceresa@users.noreply.github.com> Date: Fri Oct 27 14:49:52 2017 +0200 Removing nested macros. commit 9433f2bf2c91939fddb67ba24057225c9e1be7a7 Merge: 71f7c35cdd9f75
Author: derselbst <tom.mbrt@googlemail.com> Date: Thu Oct 26 19:56:02 2017 +0200 Merge branch 'master' into polymono commit 71f7c35a77e8192596f95df6894dae5e2a653dc2 Author: derselbst <tom.mbrt@googlemail.com> Date: Wed Oct 25 10:38:05 2017 +0200 remove static from fluid_gen_info to fix build commit 6c70db9065f81bc323eadcd654a5d5800ca4622c Merge: 1dbae28e485129
Author: derselbst <tom.mbrt@googlemail.com> Date: Wed Oct 25 09:55:15 2017 +0200 Merge branch 'master' into polymono commit 1dbae2874f68d1eb62db2ab34dcb4e3e1105f47d Author: jjceresa <32781294+jjceresa@users.noreply.github.com> Date: Tue Oct 24 03:02:32 2017 +0200 Add FluidPolyMono-0003.pdf Correction API documentation (see 2.6.1, 2.6.4) commit f01b955de22c4551821199aa670c713a4456e14a Author: jjceresa <32781294+jjceresa@users.noreply.github.com> Date: Tue Oct 24 02:57:18 2017 +0200 Delete FluidPolyMono-0003.pdf commit b557289b5f6c3ccb531c6c38b45fc61e089a83bc Author: jjceresa <32781294+jjceresa@users.noreply.github.com> Date: Tue Oct 24 02:55:31 2017 +0200 Replacing FLUID_POLYMONO_WARNING by FLUID_FAILED commit 2d06adef8af6e8d2cef2e03ab669270a727a1742 Author: jjceresa <32781294+jjceresa@users.noreply.github.com> Date: Tue Oct 24 02:52:06 2017 +0200 Replacing FLUID_POLYMONO_WARNING by FLUID_FAILED commit 06108d9f7a61f8773cac02bc32749859e415794e Author: jjceresa <32781294+jjceresa@users.noreply.github.com> Date: Tue Oct 24 02:38:23 2017 +0200 Replacing FLUID_POLYMONO_WARNING by FLUID_FAILED commit 66b85fb38ec24bb3468e5b8c205a8b15a0002272 Author: jjceresa <32781294+jjceresa@users.noreply.github.com> Date: Fri Oct 20 16:08:46 2017 +0200 Polymono documentation has moved to ./doc/polymono commit 1a03ef03e1ad1043152224cf604ec2bb47756f74 Author: jjceresa <32781294+jjceresa@users.noreply.github.com> Date: Fri Oct 20 15:41:21 2017 +0200 Adapt functions names to follow fluidsynth conventions. commit d40cf8798612eea9accf41aba7e325d6a69f326e Author: jjceresa <32781294+jjceresa@users.noreply.github.com> Date: Fri Oct 20 15:33:42 2017 +0200 Adapt functions naming to follow fluidsynth conventions. commit 49423cb8bfb7b19b9164d6e642b4549468f003f7 Author: jjceresa <32781294+jjceresa@users.noreply.github.com> Date: Fri Oct 20 15:28:08 2017 +0200 Adapt functions names to fluidsynth conventions Avoiding abbreviations. Change functions names to follow fluidsynth conventions commit bc5345ab1c37173cf075b6572dbff5d8bd57a85a Author: jjceresa <32781294+jjceresa@users.noreply.github.com> Date: Fri Oct 20 14:56:41 2017 +0200 Clarify variables spelling and bug fix Avoiding abbreviations in comments and variables names. Bug fix. commit 1f0a1ad3cbf1180ed242eb5997b18b79a98db6ba Author: jjceresa <32781294+jjceresa@users.noreply.github.com> Date: Fri Oct 20 14:48:00 2017 +0200 Clarify variables meaning avoiding abbreviations in comment and variables. commit c947686bfc8d6adde47c831a411d639938df8428 Author: jjceresa <32781294+jjceresa@users.noreply.github.com> Date: Fri Oct 20 14:35:05 2017 +0200 Clarify comments. Avoiding abbreviations on comments commit 7e7296e276b1c9ef254788634e5e2bc565dec211 Author: jjceresa <32781294+jjceresa@users.noreply.github.com> Date: Fri Oct 20 01:34:53 2017 +0200 Adding others documentation files. commit 4a6417ff8fb3afa60f6cd39f6b299759e122398c Author: jjceresa <32781294+jjceresa@users.noreply.github.com> Date: Fri Oct 20 01:32:02 2017 +0200 Create readme.txt commit 3babbed01e6fb3a264bb61d6e0be0d67e45cd853 Author: jjceresa <32781294+jjceresa@users.noreply.github.com> Date: Wed Oct 18 16:27:48 2017 +0200 Update and fix API parameters checking in fluid_synth_polymono.c Fix correction in Poly/Mono API fluid_synth_get_channel_mode() fluid_synth_set_legato_mode(), fluid_synth_get_legato_mode() fluid_synth_set_portamento_mode(), fluid_synth_get_portamento_mode() fluid_synth_set_breath_mode(),fluid_synth_get_breath_mode() commit 98234eb7c146c75bd25cef0813b1f1b12d93ad84 Merge: bb7b483b908c04
Author: derselbst <tom.mbrt@googlemail.com> Date: Wed Oct 18 13:18:05 2017 +0200 Merge branch 'master' into polymono commit bb7b48340cde04ee7c8e0d19942e45de3fa5197e Author: derselbst <tom.mbrt@googlemail.com> Date: Wed Oct 18 12:51:19 2017 +0200 fix param check for fluid_synth_set_basic_channel() commit b2157bdc4aa614647ff0a32d46b53941999d6fed Author: derselbst <tom.mbrt@googlemail.com> Date: Wed Oct 18 12:34:14 2017 +0200 another param check fix for fluid_synth_reset_basic_channels() commit 2ff7dccb555099f1f508e5318aa295338638123a Author: derselbst <tom.mbrt@googlemail.com> Date: Wed Oct 18 10:52:40 2017 +0200 correctly check parameters and enter synth API for fluid_synth_reset_basic_channels() commit 55ca184b1fa1a2bfa61918d155e9b8d7a32d2c0e Author: derselbst <tom.mbrt@googlemail.com> Date: Wed Oct 18 10:29:05 2017 +0200 move synth API entry macros to header so they are usable in polymono and mono synth files commit deb1ea53a121625eaa913b9b16f4a63a8eb4183e Author: derselbst <tom.mbrt@googlemail.com> Date: Wed Oct 18 10:25:17 2017 +0200 Revert "Update API parameter checking" This reverts commit 8ca4c7d16130c928580f410af9c79663fc8d069e. Crashes if synth == NULL commit 8ca4c7d16130c928580f410af9c79663fc8d069e Author: jjceresa <32781294+jjceresa@users.noreply.github.com> Date: Tue Oct 17 20:50:26 2017 +0200 Update API parameter checking Update Poly mono API parameters checking to be thread safe. commit d5b95232efcc14c072d9237c26a5bd68fe647b69 Author: jjceresa <32781294+jjceresa@users.noreply.github.com> Date: Mon Oct 16 18:25:48 2017 +0200 Cleaning up the documentation Cleaning up the documentation, comments, typos errors. commit 72d9cdfc99cef9da1638adfde86138444a8f6817 Author: jjceresa <32781294+jjceresa@users.noreply.github.com> Date: Mon Oct 16 17:45:52 2017 +0200 cleaning up the API documentation cleaning up the API documentation and comments so it is usable with doxygen. commit bf587f4998267ebfbbc7682abdb1abec3fc12009 Author: derselbst <tom.mbrt@googlemail.com> Date: Sun Oct 15 13:31:24 2017 +0200 move polymono shell commands to fluid_cmd and fix build commit 20d417e83b42ea0403f484d4c45d3723a3616c13 Author: derselbst <tom.mbrt@googlemail.com> Date: Sun Oct 15 13:30:49 2017 +0200 fix public synth portamento function decl commit f1a9856f5f79c1fd7e9e31bdf2c1c3276545ad94 Author: derselbst <tom.mbrt@googlemail.com> Date: Sun Oct 15 11:34:48 2017 +0200 move function decl. to header commit 4c75d038973413e97e9c52b19237cae4850e592b Author: derselbst <tom.mbrt@googlemail.com> Date: Sun Oct 15 11:12:17 2017 +0200 fluid_synth_noteoff_monopoly(): use voice getter functions commit fa00735fa1af49089026abf30f6763e3481bccf2 Author: derselbst <tom.mbrt@googlemail.com> Date: Sun Oct 15 11:05:00 2017 +0200 fix declaration of fluid_voice_noteoff() commit f53c00f2e0defa91a49185919b4ea451e4b58ac9 Author: derselbst <tom.mbrt@googlemail.com> Date: Sun Oct 15 11:02:18 2017 +0200 fix broken merge of fluid_synth_program_change() commit c18f88df9a8fd80a0ad58ad3a08ea12c6eb10681 Author: derselbst <tom.mbrt@googlemail.com> Date: Sun Oct 15 11:01:58 2017 +0200 reorder modulator decalaration commit 12b378244be1b137dfc1e18e4e928bed8073e7c2 Author: derselbst <tom.mbrt@googlemail.com> Date: Sun Oct 15 10:42:30 2017 +0200 rename breath2att modulator commit ba3b3c855a8dbcab1a4b8601f52577600061fd42 Author: derselbst <tom.mbrt@googlemail.com> Date: Sun Oct 15 10:35:42 2017 +0200 manually resolved conflict in fluid_synth_alloc_voice() for polymono commit 7b31b8605c94bea44dbacc0779ded1ef7b3eaaab Author: derselbst <tom.mbrt@googlemail.com> Date: Sat Oct 14 11:25:49 2017 +0200 fix indentation commit 1d1d03cb3a27a99643e5f6a4d701b137191cd1b1 Author: derselbst <tom.mbrt@googlemail.com> Date: Sat Oct 14 11:24:52 2017 +0200 manually merge fluid_synth_noteoff_monopoly() commit f8fa5d6534553fbb7d617f06620fd3b746349cdd Author: derselbst <tom.mbrt@googlemail.com> Date: Sat Oct 14 11:12:37 2017 +0200 refactor fluid_voice_noteoff() to return void commit 3430db0dce1ff0084da60beb157fb36ca1a23c7d Author: derselbst <tom.mbrt@googlemail.com> Date: Sat Oct 14 10:35:45 2017 +0200 add PDF documenting polymono functionality commit e3818abe427a14bcd05d7c959cd6d125533b4219 Author: derselbst <tom.mbrt@googlemail.com> Date: Sat Oct 14 10:34:52 2017 +0200 manually resolve fluid_voice_calculate_pitch() conflict commit b94d42b3923bfcab0a270903ad69bba2d3531089 Author: derselbst <tom.mbrt@googlemail.com> Date: Tue Oct 10 22:49:16 2017 +0200 move polymono synth files to correct dir commit 2719e03cfce460a132477080d383e5de5de70fed Merge: badddc50902b26
Author: derselbst <tom.mbrt@googlemail.com> Date: Tue Oct 10 21:03:49 2017 +0200 Merge branch 'master' into polymono a few too complex conflicts remain unresolved commit badddc5b43e064b597c72992434a9786f1367597 Author: jjceresa <32781294+jjceresa@users.noreply.github.com> Date: Mon Oct 9 17:50:58 2017 +0200 applied jjc's poly mono patch start of poly/mono implementation, addressing #158
This commit is contained in:
parent
30c9ddaed5
commit
e24a41a447
43 changed files with 4055 additions and 432 deletions
|
@ -125,6 +125,13 @@ Changes in FluidSynth 2.0.0 concerning developers:
|
|||
- struct _fluid_preset_t
|
||||
- add an additional general-purpose IIR filter, see fluid_synth_set_custom_filter()
|
||||
- add a custom sinusoidal modulator mapping function, see #FLUID_MOD_SIN
|
||||
- implement polymono support according to MIDI specs:
|
||||
- add basic channel support, see fluid_synth_reset_basic_channel(), fluid_synth_set_basic_channel(), fluid_synth_get_basic_channel()
|
||||
- implement MIDI modes Omni On, Omni Off, Poly, Mono, see #fluid_basic_channel_modes
|
||||
- implement portamento control, see fluid_synth_set_portamento_mode(), fluid_synth_get_portamento_mode()
|
||||
- implement legato control, see fluid_synth_set_legato_mode(), fluid_synth_get_legato_mode()
|
||||
- implement breath control, see fluid_synth_set_breath_mode(), fluid_synth_get_breath_mode()
|
||||
|
||||
|
||||
\section NewIn1_1_9 Whats new in 1.1.9?
|
||||
|
||||
|
|
BIN
doc/polymono/FluidPolyMono-0004.pdf
Normal file
BIN
doc/polymono/FluidPolyMono-0004.pdf
Normal file
Binary file not shown.
103
doc/polymono/leg_00.txt
Normal file
103
doc/polymono/leg_00.txt
Normal file
|
@ -0,0 +1,103 @@
|
|||
echo "legato mode 0 (retrigger), egal velocity on n1,n2,n3..."
|
||||
echo "---------------------------------------------------------"
|
||||
# Sounfont: GeneralUser GS 1.471 S. Christian Collins
|
||||
# Some presets
|
||||
# 0: Piano 0 ; short release
|
||||
# 16:organ 24:guitar
|
||||
# 52: Choir Aahs 53: Voice Oohs
|
||||
#
|
||||
# 56:trumpet 57:trombone 58:tuba 59:muted trumpet
|
||||
# 60:French horn 61:Brass section
|
||||
# 62:Synth brass 1 63:Synth Brass 2
|
||||
# 64:Soprano sax 65:Alto sax 66:Tenor sax 67:Baritone sax.
|
||||
# 68:Oboe 69:English horn 70:Bassoon 71:Clarinet
|
||||
# 72:piccolo 73:Flute 74:Recorder 75:Pan flute
|
||||
#
|
||||
# 99:atmosphere; attack longer than organ, release longer than piano
|
||||
# 100:brillance , 101:gobelin
|
||||
|
||||
echo "preset 73:flute"
|
||||
prog 0 73
|
||||
echo "legato mode:0"
|
||||
setlegatomode 0 0
|
||||
echo "legato On"
|
||||
cc 0 68 127
|
||||
echo "noteon C 60 vel=127, during 1000 ms"
|
||||
noteon 0 60 127
|
||||
sleep 1000
|
||||
echo "noteon D,legato up C->D (60->62, vel=127), during 1000 ms"
|
||||
echo "noteoff C"
|
||||
noteon 0 62 127
|
||||
noteoff 0 60
|
||||
sleep 1000
|
||||
echo "noteon E,legato up D->E (62->64, vel=127), during 1000 ms"
|
||||
echo "noteoff D"
|
||||
noteon 0 64 127
|
||||
noteoff 0 62
|
||||
sleep 1000
|
||||
echo "noteon F,legato up E->F (64->65, vel=127), during 1000 ms"
|
||||
echo "noteoff E"
|
||||
noteon 0 65 127
|
||||
noteoff 0 64
|
||||
sleep 1000
|
||||
echo "noteon G,legato up F->G (65->67, vel=127), during 1000 ms"
|
||||
echo "noteoff F"
|
||||
noteon 0 67 127
|
||||
noteoff 0 65
|
||||
sleep 1000
|
||||
echo "noteon A,legato up G->A (67->69, vel=127), during 1000 ms"
|
||||
echo "noteoff G"
|
||||
noteon 0 69 127
|
||||
noteoff 0 67
|
||||
sleep 1000
|
||||
echo "noteon B,legato up A->B (69->71, vel=127), during 1000 ms"
|
||||
echo "noteoff A"
|
||||
noteon 0 71 127
|
||||
noteoff 0 69
|
||||
sleep 1000
|
||||
echo "noteon C,legato up B->C (71->72, vel=127), during 1000 ms"
|
||||
echo "noteoff B"
|
||||
noteon 0 72 127
|
||||
noteoff 0 71
|
||||
sleep 1000
|
||||
echo "noteon B,legato down C->B (72->71, vel=127), during 1000 ms"
|
||||
echo "noteoff C"
|
||||
noteon 0 71 127
|
||||
noteoff 0 72
|
||||
sleep 1000
|
||||
echo "noteon A,legato down B->A (71->69, vel=127), during 1000 ms"
|
||||
echo "noteoff B"
|
||||
noteon 0 69 127
|
||||
noteoff 0 71
|
||||
sleep 1000
|
||||
echo "noteon G,legato down A->G (69->67, vel=127), during 1000 ms"
|
||||
echo "noteoff A"
|
||||
noteon 0 67 127
|
||||
noteoff 0 69
|
||||
sleep 1000
|
||||
echo "noteon F,legato down G->F (67->65, vel=127), during 1000 ms"
|
||||
echo "noteoff G"
|
||||
noteon 0 65 127
|
||||
noteoff 0 67
|
||||
sleep 1000
|
||||
echo "noteon E,legato down F->E (65->64, vel=127), during 1000 ms"
|
||||
echo "noteoff F"
|
||||
noteon 0 64 127
|
||||
noteoff 0 65
|
||||
sleep 1000
|
||||
echo "noteon D,legato down E->D (64->62, vel=127), during 1000 ms"
|
||||
echo "noteoff E"
|
||||
noteon 0 62 127
|
||||
noteoff 0 64
|
||||
sleep 1000
|
||||
echo "noteon C,legato down D->C (62->60, vel=127), during 1000 ms"
|
||||
echo "noteoff D"
|
||||
noteon 0 60 127
|
||||
noteoff 0 62
|
||||
sleep 1000
|
||||
echo "noteoff C"
|
||||
noteoff 0 60
|
||||
sleep 1000
|
||||
echo "legato Off"
|
||||
cc 0 68 0
|
||||
echo "End legato mode 1 (retrigger_1)"
|
103
doc/polymono/leg_01.txt
Normal file
103
doc/polymono/leg_01.txt
Normal file
|
@ -0,0 +1,103 @@
|
|||
echo "legato mode 1 (multi-retrigger), egal velocity on n1,n2,n3..."
|
||||
echo "-------------------------------------------------------------"
|
||||
# Sounfont: GeneralUser GS 1.471 S. Christian Collins
|
||||
# Some presets
|
||||
# 0: Piano 0 ; short release
|
||||
# 16:organ 24:guitar
|
||||
# 52: Choir Aahs 53: Voice Oohs
|
||||
#
|
||||
# 56:trumpet 57:trombone 58:tuba 59:muted trumpet
|
||||
# 60:French horn 61:Brass section
|
||||
# 62:Synth brass 1 63:Synth Brass 2
|
||||
# 64:Soprano sax 65:Alto sax 66:Tenor sax 67:Baritone sax.
|
||||
# 68:Oboe 69:English horn 70:Bassoon 71:Clarinet
|
||||
# 72:piccolo 73:Flute 74:Recorder 75:Pan flute
|
||||
#
|
||||
# 99:atmosphere; attack longer than organ, release longer than piano
|
||||
# 100:brillance , 101:gobelin
|
||||
|
||||
echo "preset 73:flute"
|
||||
prog 0 73
|
||||
echo "legato mode:1"
|
||||
setlegatomode 0 1
|
||||
echo "legato On"
|
||||
cc 0 68 127
|
||||
echo "noteon C 60 vel=127, during 1000 ms"
|
||||
noteon 0 60 127
|
||||
sleep 1000
|
||||
echo "noteon D,legato up C->D (60->62, vel=127), during 1000 ms"
|
||||
echo "noteoff C"
|
||||
noteon 0 62 127
|
||||
noteoff 0 60
|
||||
sleep 1000
|
||||
echo "noteon E,legato up D->E (62->64, vel=127), during 1000 ms"
|
||||
echo "noteoff D"
|
||||
noteon 0 64 127
|
||||
noteoff 0 62
|
||||
sleep 1000
|
||||
echo "noteon F,legato up E->F (64->65, vel=127), during 1000 ms"
|
||||
echo "noteoff E"
|
||||
noteon 0 65 127
|
||||
noteoff 0 64
|
||||
sleep 1000
|
||||
echo "noteon G,legato up F->G (65->67, vel=127), during 1000 ms"
|
||||
echo "noteoff F"
|
||||
noteon 0 67 127
|
||||
noteoff 0 65
|
||||
sleep 1000
|
||||
echo "noteon A,legato up G->A (67->69, vel=127), during 1000 ms"
|
||||
echo "noteoff G"
|
||||
noteon 0 69 127
|
||||
noteoff 0 67
|
||||
sleep 1000
|
||||
echo "noteon B,legato up A->B (69->71, vel=127), during 1000 ms"
|
||||
echo "noteoff A"
|
||||
noteon 0 71 127
|
||||
noteoff 0 69
|
||||
sleep 1000
|
||||
echo "noteon C,legato up B->C (71->72, vel=127), during 1000 ms"
|
||||
echo "noteoff B"
|
||||
noteon 0 72 127
|
||||
noteoff 0 71
|
||||
sleep 1000
|
||||
echo "noteon B,legato down C->B (72->71, vel=127), during 1000 ms"
|
||||
echo "noteoff C"
|
||||
noteon 0 71 127
|
||||
noteoff 0 72
|
||||
sleep 1000
|
||||
echo "noteon A,legato down B->A (71->69, vel=127), during 1000 ms"
|
||||
echo "noteoff B"
|
||||
noteon 0 69 127
|
||||
noteoff 0 71
|
||||
sleep 1000
|
||||
echo "noteon G,legato down A->G (69->67, vel=127), during 1000 ms"
|
||||
echo "noteoff A"
|
||||
noteon 0 67 127
|
||||
noteoff 0 69
|
||||
sleep 1000
|
||||
echo "noteon F,legato down G->F (67->65, vel=127), during 1000 ms"
|
||||
echo "noteoff G"
|
||||
noteon 0 65 127
|
||||
noteoff 0 67
|
||||
sleep 1000
|
||||
echo "noteon E,legato down F->E (65->64, vel=127), during 1000 ms"
|
||||
echo "noteoff F"
|
||||
noteon 0 64 127
|
||||
noteoff 0 65
|
||||
sleep 1000
|
||||
echo "noteon D,legato down E->D (64->62, vel=127), during 1000 ms"
|
||||
echo "noteoff E"
|
||||
noteon 0 62 127
|
||||
noteoff 0 64
|
||||
sleep 1000
|
||||
echo "noteon C,legato down D->C (62->60, vel=127), during 1000 ms"
|
||||
echo "noteoff D"
|
||||
noteon 0 60 127
|
||||
noteoff 0 62
|
||||
sleep 1000
|
||||
echo "noteoff C"
|
||||
noteoff 0 60
|
||||
sleep 1000
|
||||
echo "legato Off"
|
||||
cc 0 68 0
|
||||
echo "End legato mode 2 (multi-retrigger)"
|
107
doc/polymono/leg_por_00.txt
Normal file
107
doc/polymono/leg_por_00.txt
Normal file
|
@ -0,0 +1,107 @@
|
|||
echo "legato mode 0 (retrigger), egal velocity on n1,n2,n3..."
|
||||
echo "with portamento."
|
||||
echo "---------------------------------------------------------"
|
||||
# Sounfont: GeneralUser GS 1.471 S. Christian Collins
|
||||
# Some presets
|
||||
# 0: Piano 0 ; short release
|
||||
# 16:organ 24:guitar
|
||||
# 52: Choir Aahs 53: Voice Oohs
|
||||
#
|
||||
# 56:trumpet 57:trombone 58:tuba 59:muted trumpet
|
||||
# 60:French horn 61:Brass section
|
||||
# 62:Synth brass 1 63:Synth Brass 2
|
||||
# 64:Soprano sax 65:Alto sax 66:Tenor sax 67:Baritone sax.
|
||||
# 68:Oboe 69:English horn 70:Bassoon 71:Clarinet
|
||||
# 72:piccolo 73:Flute 74:Recorder 75:Pan flute
|
||||
#
|
||||
# 99:atmosphere; attack longer than organ, release longer than piano
|
||||
# 100:brillance , 101:gobelin
|
||||
|
||||
echo "preset 73:flute"
|
||||
prog 0 73
|
||||
echo "legato mode:0"
|
||||
setlegatomode 0 0
|
||||
echo "legato On, portamento On"
|
||||
cc 0 68 127
|
||||
cc 0 5 2
|
||||
cc 0 65 127
|
||||
echo "noteon C 60 vel=127, during 1000 ms"
|
||||
noteon 0 60 127
|
||||
sleep 1000
|
||||
echo "noteon D,legato up C->D (60->62, vel=127), during 1000 ms"
|
||||
echo "noteoff C"
|
||||
noteon 0 62 127
|
||||
noteoff 0 60
|
||||
sleep 1000
|
||||
echo "noteon E,legato up D->E (62->64, vel=127), during 1000 ms"
|
||||
echo "noteoff D"
|
||||
noteon 0 64 127
|
||||
noteoff 0 62
|
||||
sleep 1000
|
||||
echo "noteon F,legato up E->F (64->65, vel=127), during 1000 ms"
|
||||
echo "noteoff E"
|
||||
noteon 0 65 127
|
||||
noteoff 0 64
|
||||
sleep 1000
|
||||
echo "noteon G,legato up F->G (65->67, vel=127), during 1000 ms"
|
||||
echo "noteoff F"
|
||||
noteon 0 67 127
|
||||
noteoff 0 65
|
||||
sleep 1000
|
||||
echo "noteon A,legato up G->A (67->69, vel=127), during 1000 ms"
|
||||
echo "noteoff G"
|
||||
noteon 0 69 127
|
||||
noteoff 0 67
|
||||
sleep 1000
|
||||
echo "noteon B,legato up A->B (69->71, vel=127), during 1000 ms"
|
||||
echo "noteoff A"
|
||||
noteon 0 71 127
|
||||
noteoff 0 69
|
||||
sleep 1000
|
||||
echo "noteon C,legato up B->C (71->72, vel=127), during 1000 ms"
|
||||
echo "noteoff B"
|
||||
noteon 0 72 127
|
||||
noteoff 0 71
|
||||
sleep 1000
|
||||
echo "noteon B,legato down C->B (72->71, vel=127), during 1000 ms"
|
||||
echo "noteoff C"
|
||||
noteon 0 71 127
|
||||
noteoff 0 72
|
||||
sleep 1000
|
||||
echo "noteon A,legato down B->A (71->69, vel=127), during 1000 ms"
|
||||
echo "noteoff B"
|
||||
noteon 0 69 127
|
||||
noteoff 0 71
|
||||
sleep 1000
|
||||
echo "noteon G,legato down A->G (69->67, vel=127), during 1000 ms"
|
||||
echo "noteoff A"
|
||||
noteon 0 67 127
|
||||
noteoff 0 69
|
||||
sleep 1000
|
||||
echo "noteon F,legato down G->F (67->65, vel=127), during 1000 ms"
|
||||
echo "noteoff G"
|
||||
noteon 0 65 127
|
||||
noteoff 0 67
|
||||
sleep 1000
|
||||
echo "noteon E,legato down F->E (65->64, vel=127), during 1000 ms"
|
||||
echo "noteoff F"
|
||||
noteon 0 64 127
|
||||
noteoff 0 65
|
||||
sleep 1000
|
||||
echo "noteon D,legato down E->D (64->62, vel=127), during 1000 ms"
|
||||
echo "noteoff E"
|
||||
noteon 0 62 127
|
||||
noteoff 0 64
|
||||
sleep 1000
|
||||
echo "noteon C,legato down D->C (62->60, vel=127), during 1000 ms"
|
||||
echo "noteoff D"
|
||||
noteon 0 60 127
|
||||
noteoff 0 62
|
||||
sleep 1000
|
||||
echo "noteoff C"
|
||||
noteoff 0 60
|
||||
sleep 1000
|
||||
echo "legato Off, portamento off"
|
||||
cc 0 68 0
|
||||
cc 0 65 0
|
||||
echo "End legato mode 1 (retrigger_1) with portamento"
|
107
doc/polymono/leg_por_01.txt
Normal file
107
doc/polymono/leg_por_01.txt
Normal file
|
@ -0,0 +1,107 @@
|
|||
echo "legato mode 1 (multi-retrigger), egal velocity on n1,n2,n3..."
|
||||
echo "with portamento."
|
||||
echo "-------------------------------------------------------------"
|
||||
# Sounfont: GeneralUser GS 1.471 S. Christian Collins
|
||||
# Some presets
|
||||
# 0: Piano 0 ; short release
|
||||
# 16:organ 24:guitar
|
||||
# 52: Choir Aahs 53: Voice Oohs
|
||||
#
|
||||
# 56:trumpet 57:trombone 58:tuba 59:muted trumpet
|
||||
# 60:French horn 61:Brass section
|
||||
# 62:Synth brass 1 63:Synth Brass 2
|
||||
# 64:Soprano sax 65:Alto sax 66:Tenor sax 67:Baritone sax.
|
||||
# 68:Oboe 69:English horn 70:Bassoon 71:Clarinet
|
||||
# 72:piccolo 73:Flute 74:Recorder 75:Pan flute
|
||||
#
|
||||
# 99:atmosphere; attack longer than organ, release longer than piano
|
||||
# 100:brillance , 101:gobelin
|
||||
|
||||
echo "preset 73:flute"
|
||||
prog 0 73
|
||||
echo "legato mode:1"
|
||||
setlegatomode 0 1
|
||||
echo "legato On, portamento On"
|
||||
cc 0 68 127
|
||||
cc 0 5 2
|
||||
cc 0 65 127
|
||||
echo "noteon C 60 vel=127, during 1000 ms"
|
||||
noteon 0 60 127
|
||||
sleep 1000
|
||||
echo "noteon D,legato up C->D (60->62, vel=127), during 1000 ms"
|
||||
echo "noteoff C"
|
||||
noteon 0 62 127
|
||||
noteoff 0 60
|
||||
sleep 1000
|
||||
echo "noteon E,legato up D->E (62->64, vel=127), during 1000 ms"
|
||||
echo "noteoff D"
|
||||
noteon 0 64 127
|
||||
noteoff 0 62
|
||||
sleep 1000
|
||||
echo "noteon F,legato up E->F (64->65, vel=127), during 1000 ms"
|
||||
echo "noteoff E"
|
||||
noteon 0 65 127
|
||||
noteoff 0 64
|
||||
sleep 1000
|
||||
echo "noteon G,legato up F->G (65->67, vel=127), during 1000 ms"
|
||||
echo "noteoff F"
|
||||
noteon 0 67 127
|
||||
noteoff 0 65
|
||||
sleep 1000
|
||||
echo "noteon A,legato up G->A (67->69, vel=127), during 1000 ms"
|
||||
echo "noteoff G"
|
||||
noteon 0 69 127
|
||||
noteoff 0 67
|
||||
sleep 1000
|
||||
echo "noteon B,legato up A->B (69->71, vel=127), during 1000 ms"
|
||||
echo "noteoff A"
|
||||
noteon 0 71 127
|
||||
noteoff 0 69
|
||||
sleep 1000
|
||||
echo "noteon C,legato up B->C (71->72, vel=127), during 1000 ms"
|
||||
echo "noteoff B"
|
||||
noteon 0 72 127
|
||||
noteoff 0 71
|
||||
sleep 1000
|
||||
echo "noteon B,legato down C->B (72->71, vel=127), during 1000 ms"
|
||||
echo "noteoff C"
|
||||
noteon 0 71 127
|
||||
noteoff 0 72
|
||||
sleep 1000
|
||||
echo "noteon A,legato down B->A (71->69, vel=127), during 1000 ms"
|
||||
echo "noteoff B"
|
||||
noteon 0 69 127
|
||||
noteoff 0 71
|
||||
sleep 1000
|
||||
echo "noteon G,legato down A->G (69->67, vel=127), during 1000 ms"
|
||||
echo "noteoff A"
|
||||
noteon 0 67 127
|
||||
noteoff 0 69
|
||||
sleep 1000
|
||||
echo "noteon F,legato down G->F (67->65, vel=127), during 1000 ms"
|
||||
echo "noteoff G"
|
||||
noteon 0 65 127
|
||||
noteoff 0 67
|
||||
sleep 1000
|
||||
echo "noteon E,legato down F->E (65->64, vel=127), during 1000 ms"
|
||||
echo "noteoff F"
|
||||
noteon 0 64 127
|
||||
noteoff 0 65
|
||||
sleep 1000
|
||||
echo "noteon D,legato down E->D (64->62, vel=127), during 1000 ms"
|
||||
echo "noteoff E"
|
||||
noteon 0 62 127
|
||||
noteoff 0 64
|
||||
sleep 1000
|
||||
echo "noteon C,legato down D->C (62->60, vel=127), during 1000 ms"
|
||||
echo "noteoff D"
|
||||
noteon 0 60 127
|
||||
noteoff 0 62
|
||||
sleep 1000
|
||||
echo "noteoff C"
|
||||
noteoff 0 60
|
||||
sleep 1000
|
||||
echo "legato Off, portamento off"
|
||||
cc 0 68 0
|
||||
cc 0 65 0
|
||||
echo "End legato mode 2 (multi-retrigger) with portamento"
|
8
doc/polymono/poly_mono_0.txt
Normal file
8
doc/polymono/poly_mono_0.txt
Normal file
|
@ -0,0 +1,8 @@
|
|||
# What are default 'basic channels' in FluidSynth ?
|
||||
#--------------------------------------------------
|
||||
# At initialization the default basic channel is defined by settings (see 2.2).
|
||||
|
||||
# type the command basicchannels to display actual basic channels.
|
||||
basicchannels
|
||||
|
||||
# end
|
25
doc/polymono/poly_mono_1.txt
Normal file
25
doc/polymono/poly_mono_1.txt
Normal file
|
@ -0,0 +1,25 @@
|
|||
# How to change the whole set of actual basic channels ?
|
||||
# -------------------------------------------------------------
|
||||
# Assuming you want to set 2 groups of channels
|
||||
# Group 1: first channel 5 in poly mode, only one channel
|
||||
# Group 2: first channel 10 in mono mode , only one channel
|
||||
|
||||
# Group 1 should have following settings:
|
||||
# basic channel 5, mode poly, omni off, (mode 2).
|
||||
|
||||
# Group 2 should have the following settings:
|
||||
# basic channel 10, mode mono, omni off, (mode 3), composed of one channel.
|
||||
|
||||
# First use the command resetbasicchannels to reset all basic channels
|
||||
resetbasicchannels
|
||||
|
||||
# Then use command setbasicchannels using numbered mode:
|
||||
setbasicchannels 5 2 0 10 3 1
|
||||
# or using named mode:
|
||||
# setbasicchannels 5 poly_omnioff 0 10 mono_omnioff 1
|
||||
|
||||
# Use basicchannels command to verify your settings
|
||||
basicchannels
|
||||
|
||||
|
||||
# end
|
22
doc/polymono/poly_mono_2.txt
Normal file
22
doc/polymono/poly_mono_2.txt
Normal file
|
@ -0,0 +1,22 @@
|
|||
# How to add a new basic channel among others actual basic channels ?
|
||||
# -------------------------------------------------------------------
|
||||
# Perhaps you have already set several groups of basics channels and
|
||||
# you want add a new one without modifying actual groups.
|
||||
# Assuming following actual groups:
|
||||
|
||||
# Basic channel: 5, poly omni off(mode 2), nbr: 1
|
||||
# Basic channel: 10, mono omni off(mode 3), nbr: 1
|
||||
|
||||
# Now we want to add a new group 3:
|
||||
# Group 3 should have the following settings:
|
||||
# basic channel 13, mode mono, omni off, (mode 3) composed of 2 channels.
|
||||
|
||||
# Use command setbasicchannels using numbered mode:
|
||||
setbasicchannels 13 3 2
|
||||
# or using named mode:
|
||||
# setbasicchannels 13 mono_omnioff 2
|
||||
|
||||
Use basicchannels command to verify your settings
|
||||
basicchannels
|
||||
|
||||
# end
|
26
doc/polymono/poly_mono_3.txt
Normal file
26
doc/polymono/poly_mono_3.txt
Normal file
|
@ -0,0 +1,26 @@
|
|||
# How to change an actual basic channel ?
|
||||
# ---------------------------------------
|
||||
# Perhaps you have already set several groups of basics channels
|
||||
# and you want change the settings of one.
|
||||
|
||||
# Assuming following actual groups:
|
||||
# -Group 1:Basic channel: 5, poly omni off(mode 2), nbr: 1
|
||||
# -Group 2:Basic channel: 10, mono omni off(mode 3), nbr: 1
|
||||
# -Group 3:Basic channel: 13, mono omni off(mode 3), nbr: 2
|
||||
|
||||
# Now we want to change group 1:
|
||||
# Group 1 should have the following settings:
|
||||
# -basic channel 5, mode poly, omni on, (mode 0) composed of 4 channels in this group.
|
||||
|
||||
#First use the command resetbasicchannels to clear the group intended to be changed.
|
||||
resetbasicchannels 5
|
||||
|
||||
# Then use command setbasicchannels using numbered mode:
|
||||
setbasicchannels 5 0 4
|
||||
# or Using named mode:
|
||||
# setbasicchannels 5 poly_omnion 4
|
||||
|
||||
# Use basicchannels command to verify your settings
|
||||
basicchannels
|
||||
|
||||
# end
|
25
doc/polymono/poly_mono_4.txt
Normal file
25
doc/polymono/poly_mono_4.txt
Normal file
|
@ -0,0 +1,25 @@
|
|||
# How to change an actual basic channel and an add new one ?
|
||||
# --------------------------------------------------------
|
||||
# Note that command setbasicchannels allows to add or change
|
||||
# groups of basics channels.
|
||||
#
|
||||
# Note also that the commands allows this to more than one
|
||||
# groups executing only one command:
|
||||
|
||||
# The following command restores Group 1 to the state:
|
||||
# -Group 1:Basic channel: 5, poly omni off(mode 2), nbr: 1
|
||||
# Then adds a new group:
|
||||
# -Group 0:Basic channel: 2, mono omni on(mode 1), composed of 3 possible channels in this group
|
||||
|
||||
#First use the command resetbasicchannels to clear the group intended to be changed.
|
||||
resetbasicchannels 5
|
||||
|
||||
# Use command setbasicchannels to change a group and add a new one, using numbered mode:
|
||||
setbasicchannels 5 2 0 2 1 3
|
||||
# or using named mode:
|
||||
# setbasicchannels 5 poly_omnioff 0 2 mono_omnion 3
|
||||
|
||||
# Use basicchannels command to verify your settings
|
||||
basicchannels
|
||||
|
||||
# end
|
9
doc/polymono/poly_mono_5.txt
Normal file
9
doc/polymono/poly_mono_5.txt
Normal file
|
@ -0,0 +1,9 @@
|
|||
# How to know the state of one or more MIDI channels ?
|
||||
# -----------------------------------------------------
|
||||
# Use the command channelsmode [chan1 chan2 ….]
|
||||
channelsmode
|
||||
|
||||
# To display the state of MIDI channels 2,5, 10, 13 only
|
||||
channelsmode 2 5 10 13
|
||||
|
||||
# end
|
22
doc/polymono/readme.txt
Normal file
22
doc/polymono/readme.txt
Normal file
|
@ -0,0 +1,22 @@
|
|||
/fluidSynth/doc/polymono directory contains:
|
||||
|
||||
1) FluidPolyMono-0004.pdf, the documentation of poly/mono functionalities.
|
||||
2) tutorials examples files:
|
||||
2.1) tutorials chapter 2.1
|
||||
poly_mono_0.txt
|
||||
poly_mono_1.txt
|
||||
poly_mono_2.txt
|
||||
poly_mono_3.txt
|
||||
poly_mono_4.txt
|
||||
poly_mono_5.txt
|
||||
|
||||
2.2) tutorials chapter 3.1
|
||||
leg_00.txt
|
||||
leg_01.txt
|
||||
leg_por_00.txt
|
||||
leg_por_01.txt
|
||||
|
||||
This tutorials files are usable directly on the FluidSynth console application.
|
||||
There are described in the pdf file (chapters 2.1 and 3.1).
|
||||
|
||||
jean-jacques ceresa
|
|
@ -50,7 +50,6 @@ FLUIDSYNTH_API fluid_synth_t* new_fluid_synth(fluid_settings_t* settings);
|
|||
FLUIDSYNTH_API void delete_fluid_synth(fluid_synth_t* synth);
|
||||
FLUIDSYNTH_API fluid_settings_t* fluid_synth_get_settings(fluid_synth_t* synth);
|
||||
|
||||
|
||||
/* MIDI channel messages */
|
||||
|
||||
FLUIDSYNTH_API int fluid_synth_noteon(fluid_synth_t* synth, int chan, int key, int vel);
|
||||
|
@ -124,11 +123,6 @@ FLUIDSYNTH_API int fluid_synth_get_bank_offset(fluid_synth_t* synth, int sfont_i
|
|||
|
||||
/* Reverb */
|
||||
|
||||
/*
|
||||
*
|
||||
* Reverb
|
||||
*
|
||||
*/
|
||||
|
||||
FLUIDSYNTH_API int fluid_synth_set_reverb(fluid_synth_t* synth, double roomsize,
|
||||
double damping, double width, double level);
|
||||
|
@ -303,7 +297,8 @@ typedef int (*fluid_audio_callback_t)(fluid_synth_t* synth, int len,
|
|||
/* Synthesizer's interface to handle SoundFont loaders */
|
||||
|
||||
FLUIDSYNTH_API void fluid_synth_add_sfloader(fluid_synth_t* synth, fluid_sfloader_t* loader);
|
||||
FLUIDSYNTH_API fluid_voice_t* fluid_synth_alloc_voice(fluid_synth_t* synth, fluid_sample_t* sample,
|
||||
FLUIDSYNTH_API fluid_voice_t* fluid_synth_alloc_voice(fluid_synth_t* synth,
|
||||
fluid_sample_t* sample,
|
||||
int channum, int key, int vel);
|
||||
FLUIDSYNTH_API void fluid_synth_start_voice(fluid_synth_t* synth, fluid_voice_t* voice);
|
||||
FLUIDSYNTH_API void fluid_synth_get_voicelist(fluid_synth_t* synth,
|
||||
|
@ -330,6 +325,84 @@ FLUIDSYNTH_API int fluid_synth_set_custom_filter(fluid_synth_t*, int type, int f
|
|||
|
||||
FLUIDSYNTH_API fluid_ladspa_fx_t *fluid_synth_get_ladspa_fx(fluid_synth_t *synth);
|
||||
|
||||
|
||||
/* API: Poly mono mode */
|
||||
|
||||
/** Interface to poly/mono mode variables
|
||||
*
|
||||
* Channel mode bits OR-ed together so that it matches with the midi spec: poly omnion (0), mono omnion (1), poly omnioff (2), mono omnioff (3)
|
||||
*/
|
||||
enum fluid_channel_mode_flags
|
||||
{
|
||||
FLUID_CHANNEL_POLY_OFF = 0x01, /**< if flag is set, the basic channel is in mono on state, if not set poly is on */
|
||||
FLUID_CHANNEL_OMNI_OFF = 0x02, /**< if flag is set, the basic channel is in omni off state, if not set omni is on */
|
||||
};
|
||||
|
||||
/** Indicates the breath mode a channel is set to */
|
||||
enum fluid_channel_breath_flags
|
||||
{
|
||||
FLUID_CHANNEL_BREATH_POLY = 0x10, /**< when channel is poly, this flag indicates that the default velocity to initial attenuation modulator is replaced by a breath to initial attenuation modulator */
|
||||
FLUID_CHANNEL_BREATH_MONO = 0x20, /**< when channel is mono, this flag indicates that the default velocity to initial attenuation modulator is replaced by a breath modulator */
|
||||
FLUID_CHANNEL_BREATH_SYNC = 0x40, /**< when channel is mono, this flag indicates that the breath controler(MSB)triggers noteon/noteoff on the running note */
|
||||
};
|
||||
|
||||
/** Indicates the mode a basic channel is set to */
|
||||
enum fluid_basic_channel_modes
|
||||
{
|
||||
FLUID_CHANNEL_MODE_MASK = (FLUID_CHANNEL_OMNI_OFF | FLUID_CHANNEL_POLY_OFF), /**< Mask Poly and Omni bits of #fluid_channel_mode_flags, usually only used internally */
|
||||
FLUID_CHANNEL_MODE_OMNION_POLY = FLUID_CHANNEL_MODE_MASK & (~FLUID_CHANNEL_OMNI_OFF & ~FLUID_CHANNEL_POLY_OFF), /**< corresponds to MIDI mode 0 */
|
||||
FLUID_CHANNEL_MODE_OMNION_MONO = FLUID_CHANNEL_MODE_MASK & (~FLUID_CHANNEL_OMNI_OFF & FLUID_CHANNEL_POLY_OFF), /**< corresponds to MIDI mode 1 */
|
||||
FLUID_CHANNEL_MODE_OMNIOFF_POLY = FLUID_CHANNEL_MODE_MASK & (FLUID_CHANNEL_OMNI_OFF & ~FLUID_CHANNEL_POLY_OFF), /**< corresponds to MIDI mode 2 */
|
||||
FLUID_CHANNEL_MODE_OMNIOFF_MONO = FLUID_CHANNEL_MODE_MASK & (FLUID_CHANNEL_OMNI_OFF | FLUID_CHANNEL_POLY_OFF), /**< corresponds to MIDI mode 3 */
|
||||
FLUID_CHANNEL_MODE_LAST /**< @internal Value defines the count of basic channel modes (#fluid_basic_channel_modes) @warning This symbol is not part of the public API and ABI stability guarantee and may change at any time! */
|
||||
};
|
||||
|
||||
FLUIDSYNTH_API int fluid_synth_reset_basic_channel(fluid_synth_t* synth, int chan);
|
||||
|
||||
FLUIDSYNTH_API int fluid_synth_get_basic_channel(fluid_synth_t* synth, int chan,
|
||||
int *basic_chan_out,
|
||||
int *mode_chan_out,
|
||||
int *basic_val_out );
|
||||
FLUIDSYNTH_API int fluid_synth_set_basic_channel(fluid_synth_t* synth, int chan, int mode, int val);
|
||||
|
||||
/** Interface to mono legato mode
|
||||
*
|
||||
* Indicates the legato mode a channel is set to
|
||||
* n1,n2,n3,.. is a legato passage. n1 is the first note, and n2,n3,n4 are played legato with previous note. */
|
||||
enum fluid_channel_legato_mode
|
||||
{
|
||||
FLUID_CHANNEL_LEGATO_MODE_RETRIGGER, /**< Mode 0 - Release previous note, start a new note */
|
||||
FLUID_CHANNEL_LEGATO_MODE_MULTI_RETRIGGER, /**< Mode 1 - On contiguous notes retrigger in attack section using current value, shape attack using current dynamic and make use of previous voices if any */
|
||||
FLUID_CHANNEL_LEGATO_MODE_LAST /**< @internal Value defines the count of legato modes (#fluid_channel_legato_mode) @warning This symbol is not part of the public API and ABI stability guarantee and may change at any time! */
|
||||
};
|
||||
|
||||
FLUIDSYNTH_API int fluid_synth_set_legato_mode(fluid_synth_t* synth, int chan, int legatomode);
|
||||
FLUIDSYNTH_API int fluid_synth_get_legato_mode(fluid_synth_t* synth, int chan, int *legatomode);
|
||||
|
||||
/** Interface to portamento mode
|
||||
*
|
||||
* Indicates the portamento mode a channel is set to
|
||||
*/
|
||||
enum fluid_channel_portamento_mode
|
||||
{
|
||||
FLUID_CHANNEL_PORTAMENTO_MODE_EACH_NOTE, /**< Mode 0 - Portamento on each note (staccato or legato) */
|
||||
FLUID_CHANNEL_PORTAMENTO_MODE_LEGATO_ONLY, /**< Mode 1 - Portamento only on legato note */
|
||||
FLUID_CHANNEL_PORTAMENTO_MODE_STACCATO_ONLY, /**< Mode 2 - Portamento only on staccato note */
|
||||
FLUID_CHANNEL_PORTAMENTO_MODE_LAST /**< @internal Value defines the count of portamento modes (#fluid_channel_portamento_mode) @warning This symbol is not part of the public API and ABI stability guarantee and may change at any time! */
|
||||
};
|
||||
|
||||
FLUIDSYNTH_API int fluid_synth_set_portamento_mode(fluid_synth_t* synth,
|
||||
int chan, int portamentomode);
|
||||
FLUIDSYNTH_API int fluid_synth_get_portamento_mode(fluid_synth_t* synth,
|
||||
int chan, int * portamentomode);
|
||||
|
||||
/* Interface to breath mode */
|
||||
FLUIDSYNTH_API int fluid_synth_set_breath_mode(fluid_synth_t* synth,
|
||||
int chan, int breathmode);
|
||||
FLUIDSYNTH_API int fluid_synth_get_breath_mode(fluid_synth_t* synth,
|
||||
int chan, int *breathmode);
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -157,6 +157,7 @@ set ( libfluidsynth_SOURCES
|
|||
synth/fluid_mod.h
|
||||
synth/fluid_synth.c
|
||||
synth/fluid_synth.h
|
||||
synth/fluid_synth_monopoly.c
|
||||
synth/fluid_tuning.c
|
||||
synth/fluid_tuning.h
|
||||
synth/fluid_voice.c
|
||||
|
|
|
@ -78,30 +78,32 @@ void fluid_shell_settings(fluid_settings_t* settings)
|
|||
/** the table of all handled commands */
|
||||
|
||||
static const fluid_cmd_t fluid_commands[] = {
|
||||
/* general commands */
|
||||
{ "help", "general", fluid_handle_help,
|
||||
"help Show help topics ('help TOPIC' for more info)" },
|
||||
"help Shows help topics ('help TOPIC' for more info)" },
|
||||
{ "quit", "general", fluid_handle_quit,
|
||||
"quit Quit the synthesizer" },
|
||||
{ "source", "general", fluid_handle_source,
|
||||
"source filename Load a file and parse every line as a command" },
|
||||
"source filename Loads a file and parse every line as a command" },
|
||||
/* event commands */
|
||||
{ "noteon", "event", fluid_handle_noteon,
|
||||
"noteon chan key vel Send noteon" },
|
||||
"noteon chan key vel Sends noteon" },
|
||||
{ "noteoff", "event", fluid_handle_noteoff,
|
||||
"noteoff chan key Send noteoff" },
|
||||
"noteoff chan key Sends noteoff" },
|
||||
{ "pitch_bend", "event", fluid_handle_pitch_bend,
|
||||
"pitch_bend chan offset Bend pitch" },
|
||||
"pitch_bend chan offset Bends pitch" },
|
||||
{ "pitch_bend_range", "event", fluid_handle_pitch_bend_range,
|
||||
"pitch_bend chan range Set bend pitch range" },
|
||||
"pitch_bend chan range Sets bend pitch range" },
|
||||
{ "cc", "event", fluid_handle_cc,
|
||||
"cc chan ctrl value Send control-change message" },
|
||||
"cc chan ctrl value Sends control-change message" },
|
||||
{ "prog", "event", fluid_handle_prog,
|
||||
"prog chan num Send program-change message" },
|
||||
"prog chan num Sends program-change message" },
|
||||
{ "select", "event", fluid_handle_select,
|
||||
"select chan sfont bank prog Combination of bank-select and program-change" },
|
||||
{ "load", "general", fluid_handle_load,
|
||||
"load file [reset] [bankofs] Load SoundFont (reset=0|1, def 1; bankofs=n, def 0)" },
|
||||
"load file [reset] [bankofs] Loads SoundFont (reset=0|1, def 1; bankofs=n, def 0)" },
|
||||
{ "unload", "general", fluid_handle_unload,
|
||||
"unload id [reset] Unload SoundFont by ID (reset=0|1, default 1)"},
|
||||
"unload id [reset] Unloads SoundFont by ID (reset=0|1, default 1)"},
|
||||
{ "reload", "general", fluid_handle_reload,
|
||||
"reload id Reload the SoundFont with the specified ID" },
|
||||
{ "fonts", "general", fluid_handle_fonts,
|
||||
|
@ -114,6 +116,28 @@ static const fluid_cmd_t fluid_commands[] = {
|
|||
"interp num Choose interpolation method for all channels" },
|
||||
{ "interpc", "general", fluid_handle_interpc,
|
||||
"interpc chan num Choose interpolation method for one channel" },
|
||||
/* polymono commands */
|
||||
{ "basicchannels", "polymono", fluid_handle_basicchannels,
|
||||
"basicchannels Prints the list of basic channels"},
|
||||
{ "resetbasicchannels", "polymono", fluid_handle_resetbasicchannels,
|
||||
"resetbasicchannels [chan1 chan2..] Resets all or some basic channels"},
|
||||
{ "setbasicchannels", "polymono", fluid_handle_setbasicchannels,
|
||||
"setbasicchannels [chan mode val...] Sets default, adds basic channels"},
|
||||
{ "channelsmode", "polymono", fluid_handle_channelsmode,
|
||||
"channelsmode [chan1 chan2..] Prints channels mode"},
|
||||
{ "legatomode", "polymono", fluid_handle_legatomode,
|
||||
"legatomode [chan1 chan2..] Prints channels legato mode"},
|
||||
{ "setlegatomode", "polymono", fluid_handle_setlegatomode,
|
||||
"setlegatomode chan mode [chan mode..] Sets legato mode"},
|
||||
{ "portamentomode", "polymono", fluid_handle_portamentomode,
|
||||
"portamentomode [chan1 chan2..] Prints channels portamento mode"},
|
||||
{ "setportamentomode", "polymono", fluid_handle_setportamentomode,
|
||||
"setportamentomode chan mode [chan mode..] Sets portamento mode"},
|
||||
{ "breathmode", "polymono", fluid_handle_breathmode,
|
||||
"breathmode [chan1 chan2..] Prints channels breath mode"},
|
||||
{ "setbreathmode", "polymono", fluid_handle_setbreathmode,
|
||||
"setbreathmode chan poly(1/0) mono(1/0) breath_sync(1/0) [..] Sets breath mode"},
|
||||
/* reverb commands */
|
||||
{ "rev_preset", "reverb", fluid_handle_reverbpreset,
|
||||
"rev_preset num Load preset num into the reverb unit" },
|
||||
{ "rev_setroomsize", "reverb", fluid_handle_reverbsetroomsize,
|
||||
|
@ -126,6 +150,7 @@ static const fluid_cmd_t fluid_commands[] = {
|
|||
"rev_setlevel num Change reverb level" },
|
||||
{ "reverb", "reverb", fluid_handle_reverb,
|
||||
"reverb [0|1|on|off] Turn the reverb on or off" },
|
||||
/* chorus commands */
|
||||
{ "cho_set_nr", "chorus", fluid_handle_chorusnr,
|
||||
"cho_set_nr n Use n delay lines (default 3)" },
|
||||
{ "cho_set_level", "chorus", fluid_handle_choruslevel,
|
||||
|
@ -140,6 +165,7 @@ static const fluid_cmd_t fluid_commands[] = {
|
|||
"gain value Set the master gain (0 < gain < 5)" },
|
||||
{ "voice_count", "general", fluid_handle_voice_count,
|
||||
"voice_count Get number of active synthesis voices" },
|
||||
/* tuning commands */
|
||||
{ "tuning", "tuning", fluid_handle_tuning,
|
||||
"tuning name bank prog Create a tuning with name, bank number, \n"
|
||||
" and program number (0 <= bank,prog <= 127)" },
|
||||
|
@ -155,6 +181,7 @@ static const fluid_cmd_t fluid_commands[] = {
|
|||
"dumptuning bank prog Print the pitch details of the tuning" },
|
||||
{ "reset", "general", fluid_handle_reset,
|
||||
"reset System reset (all notes off, reset controllers)" },
|
||||
/* settings commands */
|
||||
{ "set", "settings", fluid_handle_set,
|
||||
"set name value Set the value of a controller or settings" },
|
||||
{ "get", "settings", fluid_handle_get,
|
||||
|
@ -165,7 +192,10 @@ static const fluid_cmd_t fluid_commands[] = {
|
|||
"settings Print out all settings" },
|
||||
{ "echo", "general", fluid_handle_echo,
|
||||
"echo arg Print arg" },
|
||||
/* LADSPA-related commands */
|
||||
/* Sleep command, useful to insert a delay between commands */
|
||||
{ "sleep", "general", fluid_handle_sleep,
|
||||
"sleep duration sleep duration(in ms)" },
|
||||
/* LADSPA-related commands */
|
||||
#ifdef LADSPA
|
||||
{ "ladspa_effect", "ladspa", fluid_handle_ladspa_effect,
|
||||
"ladspa_effect Create a new effect from a LADSPA plugin"},
|
||||
|
@ -184,6 +214,7 @@ static const fluid_cmd_t fluid_commands[] = {
|
|||
{ "ladspa_reset", "ladspa", fluid_handle_ladspa_reset,
|
||||
"ladspa_reset Stop and reset LADSPA effects"},
|
||||
#endif
|
||||
/* router commands */
|
||||
{ "router_clear", "router", fluid_handle_router_clear,
|
||||
"router_clear Clears all routing rules from the midi router"},
|
||||
{ "router_default", "router", fluid_handle_router_default,
|
||||
|
@ -619,7 +650,7 @@ fluid_handle_channels(void* data, int ac, char** av, fluid_ostream_t out)
|
|||
int verbose = 0;
|
||||
int i;
|
||||
|
||||
if (ac > 0 && strcmp( av[0], "-verbose") == 0) verbose = 1;
|
||||
if (ac > 0 && FLUID_STRCMP( av[0], "-verbose") == 0) verbose = 1;
|
||||
|
||||
for (i = 0; i < fluid_synth_count_midi_channels(handler->synth); i++) {
|
||||
preset = fluid_synth_get_channel_preset(handler->synth, i);
|
||||
|
@ -873,9 +904,9 @@ fluid_handle_reverb(void* data, int ac, char** av, fluid_ostream_t out)
|
|||
return FLUID_FAILED;
|
||||
}
|
||||
|
||||
if ((strcmp(av[0], "0") == 0) || (strcmp(av[0], "off") == 0)) {
|
||||
if ((FLUID_STRCMP(av[0], "0") == 0) || (FLUID_STRCMP(av[0], "off") == 0)) {
|
||||
fluid_synth_set_reverb_on(handler->synth,0);
|
||||
} else if ((strcmp(av[0], "1") == 0) || (strcmp(av[0], "on") == 0)) {
|
||||
} else if ((FLUID_STRCMP(av[0], "1") == 0) || (FLUID_STRCMP(av[0], "on") == 0)) {
|
||||
fluid_synth_set_reverb_on(handler->synth,1);
|
||||
} else {
|
||||
fluid_ostream_printf(out, "reverb: invalid arguments %s [0|1|on|off]", av[0]);
|
||||
|
@ -960,9 +991,9 @@ fluid_handle_chorus(void* data, int ac, char** av, fluid_ostream_t out)
|
|||
return FLUID_FAILED;
|
||||
}
|
||||
|
||||
if ((strcmp(av[0], "0") == 0) || (strcmp(av[0], "off") == 0)) {
|
||||
if ((FLUID_STRCMP(av[0], "0") == 0) || (FLUID_STRCMP(av[0], "off") == 0)) {
|
||||
fluid_synth_set_chorus_on(handler->synth,0);
|
||||
} else if ((strcmp(av[0], "1") == 0) || (strcmp(av[0], "on") == 0)) {
|
||||
} else if ((FLUID_STRCMP(av[0], "1") == 0) || (FLUID_STRCMP(av[0], "on") == 0)) {
|
||||
fluid_synth_set_chorus_on(handler->synth,1);
|
||||
} else {
|
||||
fluid_ostream_printf(out, "chorus: invalid arguments %s [0|1|on|off]", av[0]);
|
||||
|
@ -990,6 +1021,28 @@ fluid_handle_echo(void* data, int ac, char** av, fluid_ostream_t out)
|
|||
return FLUID_OK;
|
||||
}
|
||||
|
||||
/* Purpose:
|
||||
* Sleep during a time in ms
|
||||
* The command itself is useful to insert a delay between commands.
|
||||
* It can help for exemple to build a small song using noteon/noteoff commands
|
||||
* in a command file.
|
||||
*/
|
||||
int
|
||||
fluid_handle_sleep(void *data, int ac, char** av, fluid_ostream_t out)
|
||||
{
|
||||
if (ac < 1) {
|
||||
fluid_ostream_printf(out, "sleep: too few arguments.\n");
|
||||
return -1;
|
||||
}
|
||||
if (!fluid_is_number(av[0])) {
|
||||
fluid_ostream_printf(out, "sleep: argument should be a number in ms.\n");
|
||||
return -1;
|
||||
}
|
||||
fluid_msleep(atoi(av[0])); /* delay in milliseconds */
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
fluid_handle_source(void* data, int ac, char** av, fluid_ostream_t out)
|
||||
{
|
||||
|
@ -1651,7 +1704,7 @@ fluid_handle_help(void* data, int ac, char** av, fluid_ostream_t out)
|
|||
if (ac >= 1) {
|
||||
topic = av[0];
|
||||
}
|
||||
if (strcmp(topic,"help") == 0){
|
||||
if (FLUID_STRCMP(topic,"help") == 0){
|
||||
/* "help help": Print a list of all topics */
|
||||
fluid_ostream_printf(out,
|
||||
"*** Help topics:***\n"
|
||||
|
@ -1660,7 +1713,7 @@ fluid_handle_help(void* data, int ac, char** av, fluid_ostream_t out)
|
|||
int listed_first_time = 1;
|
||||
unsigned int ii;
|
||||
for (ii = 0; ii < i; ii++){
|
||||
if (strcmp(fluid_commands[i].topic, fluid_commands[ii].topic) == 0){
|
||||
if (FLUID_STRCMP(fluid_commands[i].topic, fluid_commands[ii].topic) == 0){
|
||||
listed_first_time = 0;
|
||||
}; /* if topic has already been listed */
|
||||
}; /* for all topics (inner loop) */
|
||||
|
@ -1672,7 +1725,7 @@ fluid_handle_help(void* data, int ac, char** av, fluid_ostream_t out)
|
|||
/* help (arbitrary topic or "all") */
|
||||
for (i = 0; i < FLUID_N_ELEMENTS(fluid_commands); i++) {
|
||||
if (fluid_commands[i].help != NULL) {
|
||||
if (strcmp(topic,"all") == 0 || strcmp(topic,fluid_commands[i].topic) == 0){
|
||||
if (FLUID_STRCMP(topic,"all") == 0 || FLUID_STRCMP(topic,fluid_commands[i].topic) == 0){
|
||||
fluid_ostream_printf(out, "%s\n", fluid_commands[i].help);
|
||||
count++;
|
||||
}; /* if it matches the topic */
|
||||
|
@ -1869,6 +1922,785 @@ int fluid_handle_router_par2(void* data, int ac, char** av, fluid_ostream_t out)
|
|||
return FLUID_OK;
|
||||
}
|
||||
|
||||
/** commands Poly/mono mode *************************************************/
|
||||
|
||||
static const char * mode_name[]={"poly omni on (0)","mono omni on (1)",
|
||||
"poly omni off(2)","mono omni off(3)"};
|
||||
/*
|
||||
Prints result message for commands: basicchannels, resetbasicchannels.
|
||||
Prints all basic channels and print a warning if there is no basic channel.
|
||||
|
||||
@param synth the synth instance.
|
||||
@param out output stream.
|
||||
*/
|
||||
static int print_basic_channels(fluid_synth_t* synth, fluid_ostream_t out)
|
||||
{
|
||||
static const char * warning_msg = "Warning: no basic channels. All MIDI channels are disabled.\n"
|
||||
"Make use of setbasicchannels to set at least a default basic channel.\n";
|
||||
|
||||
int n_chan= synth->midi_channels;
|
||||
int i , n= 0;
|
||||
/* prints all basic channels */
|
||||
for (i =0; i< n_chan; i++)
|
||||
{
|
||||
int basic_chan, mode_chan,val;
|
||||
if( fluid_synth_get_basic_channel(synth, i, &basic_chan, &mode_chan, &val) == FLUID_OK)
|
||||
{
|
||||
if (basic_chan == i)
|
||||
{
|
||||
n++;
|
||||
fluid_ostream_printf(out,"Basic channel:%3d, %s, nbr:%3d\n", i,
|
||||
mode_name[mode_chan & FLUID_CHANNEL_MODE_MASK ],
|
||||
val);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
return FLUID_FAILED; /* error */
|
||||
}
|
||||
}
|
||||
/* prints a warning if there is no basic channel */
|
||||
if (n == 0)
|
||||
{
|
||||
fluid_ostream_printf(out, warning_msg);
|
||||
}
|
||||
return FLUID_OK;
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------------------------
|
||||
basicchannels
|
||||
Prints the list of all MIDI basic channels informations
|
||||
example:
|
||||
|
||||
Basic channel: 0, poly omni on (0), nbr: 3
|
||||
Basic channel: 3, poly omni off(2), nbr: 1
|
||||
Basic channel: 8, mono omni off(3), nbr: 2
|
||||
Basic channel: 13, mono omni on (1), nbr: 3
|
||||
*/
|
||||
int fluid_handle_basicchannels (void* data, int ac, char** av,
|
||||
fluid_ostream_t out)
|
||||
{
|
||||
FLUID_ENTRY_COMMAND(data);
|
||||
fluid_synth_t* synth = handler->synth;
|
||||
return print_basic_channels(synth, out);
|
||||
}
|
||||
|
||||
/*
|
||||
Searchs a mode name and returns the channel mode number.
|
||||
name must be: poly_omnion, mono_omnion, poly_omnioff, mono_omnioff.
|
||||
@param name to search.
|
||||
@return channel mode number (0 to 3) if name is valid, -1 otherwise.
|
||||
*/
|
||||
static int get_channel_mode_num(char * name)
|
||||
{
|
||||
/* argument names for channel mode parameter (see resetbasicchannels and
|
||||
setbasicchannels commands*/
|
||||
static const char * name_channel_mode [FLUID_CHANNEL_MODE_LAST]=
|
||||
{"poly_omnion","mono_omnion","poly_omnioff","mono_omnioff"};
|
||||
int i;
|
||||
for (i = 0 ; i < FLUID_CHANNEL_MODE_LAST;i++)
|
||||
{
|
||||
if ( ! FLUID_STRCMP (name, name_channel_mode[i]))
|
||||
{
|
||||
return i;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
static const char *invalid_arg_msg ="invalid argument\n";
|
||||
/*
|
||||
checks basic channels arguments: chan1 mode1 val chan2 mode2 val2 ...
|
||||
All arguments can be numeric. mode parameter can be a name.
|
||||
Each group entry must have 3 parameters (chan,mode,val).
|
||||
|
||||
@param ac argument count.
|
||||
@param av argument table.
|
||||
@param out output stream.
|
||||
@param name_cde command name prefix.
|
||||
@return 0 if arguments are valid, -1 otherwise.
|
||||
*/
|
||||
static int check_basicchannels_arguments(int ac, char** av,
|
||||
fluid_ostream_t out, char const * name_cde)
|
||||
{
|
||||
static const char *too_few_arg_msg = "too few argument, chan mode val [chan mode val]...\n";
|
||||
int i;
|
||||
for (i = 0; i < ac; i++)
|
||||
{
|
||||
/* checks parameters for list entries: chan1 mode1 val chan2 mode2 val2 ...*/
|
||||
/* all parameters can be numeric. mode parameter can be a name. */
|
||||
if (!fluid_is_number(av[i]) &&
|
||||
( (i % 3 != 1) || get_channel_mode_num(av[i]) < 0 ))
|
||||
{
|
||||
fluid_ostream_printf(out, "%s: %s",name_cde, invalid_arg_msg);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
if (ac % 3)
|
||||
{ /* each group entry needs 3 parameters: basicchan,mode,val */
|
||||
fluid_ostream_printf(out, "%s: channel %d, %s\n",name_cde,
|
||||
atoi(av[((ac/3) * 3)]),too_few_arg_msg);
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
checks channels arguments: chan1 chan2 ...
|
||||
all arguments must be numeric.
|
||||
|
||||
@param ac argument count.
|
||||
@param av argument table.
|
||||
@param out output stream.
|
||||
@param name_cde command name prefix.
|
||||
@return 0 if arguments are valid, -1 otherwise.
|
||||
*/
|
||||
static int check_channels_arguments(int ac, char** av,
|
||||
fluid_ostream_t out, char const * name_cde)
|
||||
{
|
||||
int i;
|
||||
for (i = 0; i < ac; i++)
|
||||
{
|
||||
if (!fluid_is_number(av[i]))
|
||||
{
|
||||
fluid_ostream_printf(out, "%s: %s",name_cde, invalid_arg_msg);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------------------------
|
||||
resetbasicchannels
|
||||
|
||||
With no parameters the command resets all basic channels.
|
||||
Note: Be aware than when a synth instance has no basic channels, all channels
|
||||
are disabled.
|
||||
In the intend to get some MIDI channels enabled, use the command setbasicchannels.
|
||||
|
||||
resetbasicchannels chan1 [chan2 . . .]
|
||||
Resets basic channel group chan1, basic channel group chan2 . . .
|
||||
*/
|
||||
int fluid_handle_resetbasicchannels (void* data, int ac, char** av,
|
||||
fluid_ostream_t out)
|
||||
{
|
||||
static const char * name_cde="resetbasicchannels";
|
||||
FLUID_ENTRY_COMMAND(data);
|
||||
fluid_synth_t* synth = handler->synth;
|
||||
|
||||
/* checks channels arguments: chan1 chan2 .... */
|
||||
if (check_channels_arguments(ac,av,out,name_cde ) < 0)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (ac )
|
||||
{ /* resetbasicchannels chan1 [chan2 . . .] */
|
||||
int i;
|
||||
for (i = 0; i < ac; i++)
|
||||
{
|
||||
int chan = atoi(av[i]);
|
||||
int result = fluid_synth_reset_basic_channel(synth, chan);
|
||||
if (result == FLUID_FAILED)
|
||||
{
|
||||
fluid_ostream_printf(out,"%s: channel %3d, %s", name_cde, chan,invalid_arg_msg);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* resets all basic channels */
|
||||
fluid_synth_reset_basic_channel(synth, -1);
|
||||
}
|
||||
/* prints result */
|
||||
return print_basic_channels(synth, out);
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------------------------
|
||||
setbasicchannels
|
||||
|
||||
With no parameters the command sets one channel basic at basic channel 0 in
|
||||
Omni On Poly (i.e all the MIDI channels are polyphonic).
|
||||
|
||||
setbasicchannels chan1 mode1 nbr1 [chan2 mode2 nbr2] ... ...
|
||||
|
||||
Adds basic channel 1 and 2
|
||||
|
||||
The command fails if any channels overlaps any existing basic channel groups.
|
||||
To make room if necessary, existing basic channel groups can be cleared using
|
||||
resetbasicchannels command.
|
||||
Mode can be a numeric value or a name:
|
||||
numeric: 0 to 3 or
|
||||
name: poly_omnion , mono_omnion, poly_omnioff, mono_omnioff.
|
||||
*/
|
||||
int fluid_handle_setbasicchannels (void* data, int ac, char** av,
|
||||
fluid_ostream_t out)
|
||||
{
|
||||
static const char * name_cde="setbasicchannels";
|
||||
FLUID_ENTRY_COMMAND(data);
|
||||
fluid_synth_t* synth = handler->synth;
|
||||
int result;
|
||||
int i,n ;
|
||||
|
||||
if(!ac)
|
||||
{
|
||||
/* sets one default basic channel */
|
||||
fluid_synth_reset_basic_channel(synth, -1); /* reset all basic channels */
|
||||
/* sets one basic channel Omni On Poly (i.e all the MIDI channels are polyphonic) */
|
||||
fluid_synth_set_basic_channel( synth, 0, FLUID_CHANNEL_MODE_OMNION_POLY,0);
|
||||
return 0;
|
||||
}
|
||||
/* checks parameters: chan1 mode1 val1 chan2 mode2 val2 */
|
||||
if (check_basicchannels_arguments(ac,av,out,name_cde) < 0)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
n = ac / 3; /* number of basic channel information */
|
||||
for (i = 0; i < n; i++)
|
||||
{
|
||||
int basicchan, mode, val;
|
||||
|
||||
basicchan = atoi(av[(i * 3)]); /* chan is numeric */
|
||||
if (fluid_is_number(av[(i * 3)+1]))
|
||||
{ /* chan is numeric */
|
||||
mode = atoi(av[(i * 3)+1]);
|
||||
}
|
||||
else
|
||||
{ /* mode is a name */
|
||||
mode = get_channel_mode_num(av[(i * 3)+1]);
|
||||
}
|
||||
val = atoi(av[(i * 3)+2]); /* val is numeric */
|
||||
|
||||
/* changes or sets basic channels */
|
||||
result = fluid_synth_set_basic_channel(synth, basicchan, mode, val);
|
||||
if (result == FLUID_FAILED)
|
||||
{
|
||||
fluid_ostream_printf(out,"%s: channel %3d, mode %3d, nbr %3d, %s",
|
||||
name_cde, basicchan, mode, val, invalid_arg_msg);
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
Print result message : "channel:x is outside MIDI channel count(y)"
|
||||
for commands: channelsmode, portamentomode, legatomode, breathmode,setbreathmode.
|
||||
@param out output stream.
|
||||
@param name_cde command name prefix.
|
||||
@param chan, MIDI channel number x.
|
||||
@param n_chan, number of MIDI channels y.
|
||||
*/
|
||||
static void print_channel_is_outside_count(fluid_ostream_t out, char const * name_cde,
|
||||
int chan, int n_chan)
|
||||
{
|
||||
fluid_ostream_printf(out,"%s: channel %3d is outside MIDI channel count(%d)\n",
|
||||
name_cde, chan, n_chan);
|
||||
}
|
||||
|
||||
|
||||
/*-----------------------------------------------------------------------------
|
||||
channelsmode
|
||||
Prints channel mode of all MIDI channels (Poly/mono, Enabled, Basic Channel)
|
||||
example
|
||||
|
||||
Channel , Status , Type , Mode , Nbr of channels
|
||||
channel: 0, disabled
|
||||
channel: 1, disabled
|
||||
channel: 2, disabled
|
||||
channel: 3, disabled
|
||||
channel: 4, disabled
|
||||
channel: 5, enabled, basic channel, mono omni off(3), nbr: 2
|
||||
channel: 6, enabled, -- , mono , --
|
||||
channel: 7, disabled
|
||||
channel: 8, disabled
|
||||
channel: 9, disabled
|
||||
channel: 10, enabled, basic channel, mono omni off(3), nbr: 4
|
||||
channel: 11, enabled, -- , mono , --
|
||||
channel: 12, enabled, -- , mono , --
|
||||
channel: 13, enabled, -- , mono , --
|
||||
channel: 14, disabled
|
||||
channel: 15, disabled
|
||||
|
||||
channelsmode chan1 chan2
|
||||
Prints only channel mode of MIDI channels chan1, chan2
|
||||
*/
|
||||
int fluid_handle_channelsmode (void* data, int ac, char** av,
|
||||
fluid_ostream_t out)
|
||||
{
|
||||
static const char * header =
|
||||
"Channel , Status , Type , Mode , Nbr of channels\n";
|
||||
static const char * name_cde="channelsmode";
|
||||
FLUID_ENTRY_COMMAND(data);
|
||||
fluid_synth_t* synth = handler->synth;
|
||||
|
||||
int i, n, n_chan= synth->midi_channels;
|
||||
|
||||
/* checks parameters: chan1 chan2 .... */
|
||||
if (check_channels_arguments(ac,av,out,name_cde) < 0)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
if (ac )
|
||||
{
|
||||
n = ac; /* prints ac MIDI channels number */
|
||||
}
|
||||
else
|
||||
{
|
||||
n= n_chan; /* prints all MIDI channels number */
|
||||
}
|
||||
/* prints header */
|
||||
fluid_ostream_printf(out, header);
|
||||
for (i = 0; i < n; i++)
|
||||
{
|
||||
int basic_chan, mode, val;
|
||||
int chan = ac ? atoi(av[i]): i;
|
||||
int result = fluid_synth_get_basic_channel(synth, chan, &basic_chan, &mode, &val);
|
||||
if (result == FLUID_OK)
|
||||
{
|
||||
if(basic_chan != FLUID_FAILED)
|
||||
{ /* This channel is enabled */
|
||||
const char * p_basicchan; /* field basic channel */
|
||||
const char * p_mode; /* field mode */
|
||||
const char *p_nbr; /* field Nbr */
|
||||
static const char * blank="--"; /* field empty */
|
||||
if (chan == basic_chan)
|
||||
{ /* This channel is a basic channel */
|
||||
char nbr[10]; /* field Nbr */
|
||||
FLUID_SNPRINTF(nbr,sizeof(nbr),"nbr:%3d",val);
|
||||
p_nbr = nbr;
|
||||
p_mode = mode_name[mode];
|
||||
p_basicchan = "basic channel";
|
||||
}
|
||||
else
|
||||
{ /* This channel is member of a basic channel group */
|
||||
p_basicchan = blank;
|
||||
if(mode & FLUID_CHANNEL_POLY_OFF) p_mode = "mono";
|
||||
else p_mode = "poly";
|
||||
p_nbr = blank;
|
||||
}
|
||||
fluid_ostream_printf(out,
|
||||
"channel:%3d, enabled, %-13s, %-16s, %s\n",
|
||||
chan,
|
||||
p_basicchan,
|
||||
p_mode,
|
||||
p_nbr);
|
||||
}
|
||||
else
|
||||
{
|
||||
fluid_ostream_printf(out, "channel:%3d, disabled\n", chan);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
print_channel_is_outside_count(out, name_cde, chan, n_chan);
|
||||
if(i < n-1)
|
||||
{
|
||||
fluid_ostream_printf(out, header);
|
||||
}
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/** commands mono legato mode ***********************************************/
|
||||
/*
|
||||
Prints result message for commands: legatomode, portamentomode.
|
||||
@param result result from the command (FLUID_OK,FLUID_FAILED).
|
||||
@param out output stream.
|
||||
@param name_cde command name prefix.
|
||||
@param chan MIDI channel number to display.
|
||||
@param name_mode name of the mode to display.
|
||||
@param n_chan, number of MIDI channels.
|
||||
*/
|
||||
static void print_result_get_channel_mode(int result, fluid_ostream_t out,
|
||||
char const * name_cde, int chan,
|
||||
char const * name_mode, int n_chan )
|
||||
{
|
||||
if (result == FLUID_OK)
|
||||
{
|
||||
fluid_ostream_printf(out,"%s: channel %3d, %s\n", name_cde, chan, name_mode);
|
||||
}
|
||||
else
|
||||
{
|
||||
print_channel_is_outside_count(out, name_cde, chan, n_chan);
|
||||
}
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------------------------
|
||||
legatomode
|
||||
Prints legato mode of all MIDI channels
|
||||
example
|
||||
|
||||
channel: 0, (1)multi-retrigger
|
||||
channel: 1, (0)retrigger
|
||||
channel: 2, (1)multi-retrigger
|
||||
.....
|
||||
|
||||
legatomode chan1 chan2
|
||||
Prints only legato mode of MIDI channels chan1, chan2
|
||||
*/
|
||||
int fluid_handle_legatomode(void* data, int ac, char** av,
|
||||
fluid_ostream_t out)
|
||||
{
|
||||
static const char * name_cde="legatomode";
|
||||
static const char * name_legato_mode[FLUID_CHANNEL_LEGATO_MODE_LAST]=
|
||||
{ "(0)retrigger","(1)multi-retrigger" };
|
||||
|
||||
FLUID_ENTRY_COMMAND(data);
|
||||
fluid_synth_t* synth = handler->synth;
|
||||
int mode = 0;
|
||||
int i, n, n_chan= synth->midi_channels;
|
||||
|
||||
/* checks channels arguments: chan1 chan2 .... */
|
||||
if (check_channels_arguments(ac, av, out, name_cde) < 0)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (ac )
|
||||
{
|
||||
n = ac; /* prints ac MIDI channels number */
|
||||
}
|
||||
else
|
||||
{
|
||||
n= n_chan; /* prints all MIDI channels number */
|
||||
}
|
||||
/* prints header */
|
||||
fluid_ostream_printf(out,"Channel , legato mode\n");
|
||||
for (i = 0; i < n; i++)
|
||||
{
|
||||
int chan = ac ? atoi(av[i]): i;
|
||||
int result = fluid_synth_get_legato_mode(synth, chan, &mode);
|
||||
print_result_get_channel_mode(result, out, name_cde, chan, name_legato_mode[mode], n_chan);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
checks channels arguments by group:
|
||||
-example by group of 2 arguments: chan1 val1 chan2 val2 .. ..
|
||||
-example by group of 4 arguments: chan1 val1 val2 val3 chan2 val1 val2 val3 ....
|
||||
|
||||
all arguments must be numeric.
|
||||
|
||||
@param ac argument count.
|
||||
@param av argument table.
|
||||
@param nbr_arg_group number of arguments by group expected.
|
||||
@param out output stream.
|
||||
@param name_cde command name prefix.
|
||||
@param nbr_arg_group_msg message when the number of argument by group is invalid.
|
||||
@return 0 if arguments are valid, -1 otherwise.
|
||||
*/
|
||||
static int check_channels_group_arguments(int ac, char** av, int nbr_arg_group,
|
||||
fluid_ostream_t out,
|
||||
char const * name_cde,
|
||||
char const * nbr_arg_group_msg
|
||||
)
|
||||
{
|
||||
if (ac)
|
||||
{
|
||||
/* checks channels numeric arguments */
|
||||
if (check_channels_arguments(ac, av, out, name_cde) < 0)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
if (ac % nbr_arg_group)
|
||||
{ /* each group entry needs nbr_arg_group parameters */
|
||||
fluid_ostream_printf(out, "%s: channel %d, %s\n",name_cde,
|
||||
atoi(av[((ac/nbr_arg_group) * nbr_arg_group)]),
|
||||
nbr_arg_group_msg);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
fluid_ostream_printf(out, "%s: %s",name_cde, nbr_arg_group_msg);
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
Prints result message for commands: setlegatomode, setportamentomode.
|
||||
@param result result from the command (FLUID_FAILED).
|
||||
@param out output stream.
|
||||
@param name_cde command name prefix.
|
||||
@param chan, MIDI channel number to display.
|
||||
@param mode, mode value to display.
|
||||
*/
|
||||
static void print_result_set_channel_mode(int result, fluid_ostream_t out,
|
||||
char const * name_cde,
|
||||
int chan, int mode)
|
||||
{
|
||||
if (result == FLUID_FAILED)
|
||||
{
|
||||
fluid_ostream_printf(out,"%s: channel %3d, mode %3d, %s", name_cde, chan, mode, invalid_arg_msg);
|
||||
}
|
||||
}
|
||||
|
||||
static const char *too_few_arg_chan_mode_msg = "too few argument, chan mode [chan mode]...\n";
|
||||
/*-----------------------------------------------------------------------------
|
||||
setlegatomode chan0 mode1 [chan1 mode0] .. ..
|
||||
|
||||
Changes legato mode for channels chan0 and [chan1]
|
||||
*/
|
||||
int fluid_handle_setlegatomode(void* data, int ac, char** av,
|
||||
fluid_ostream_t out)
|
||||
{
|
||||
static const char * name_cde="setlegatomode";
|
||||
FLUID_ENTRY_COMMAND(data);
|
||||
fluid_synth_t* synth = handler->synth;
|
||||
int i,n ;
|
||||
|
||||
/* checks channels arguments by group of 2: chan1 val1 chan2 val1 .. ..*/
|
||||
if (check_channels_group_arguments(ac, av, 2, out, name_cde, too_few_arg_chan_mode_msg) < 0)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
n = ac / 2; /* number of legato groups informations */
|
||||
for (i = 0; i < n; i++)
|
||||
{
|
||||
int chan = atoi(av[(i * 2)]);
|
||||
int mode = atoi(av[(i * 2)+1]);
|
||||
/* changes legato mode */
|
||||
|
||||
int result = fluid_synth_set_legato_mode(synth,chan,mode);
|
||||
print_result_set_channel_mode(result, out, name_cde, chan, mode);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/** commands mono/poly portamento mode **************************************/
|
||||
|
||||
/*-----------------------------------------------------------------------------
|
||||
portamentomode
|
||||
Prints portamento mode of all MIDI channels
|
||||
example
|
||||
|
||||
channel: 0, (2)staccato only
|
||||
channel: 1, (1)legato only
|
||||
channel: 2, (0)each note
|
||||
channel: 3, (1)legato only
|
||||
.....
|
||||
|
||||
portamentomode chan1 chan2
|
||||
Prints only portamento mode of MIDI channels chan1, chan2
|
||||
*/
|
||||
int fluid_handle_portamentomode(void* data, int ac, char** av,
|
||||
fluid_ostream_t out)
|
||||
{
|
||||
static const char * name_cde="portamentomode";
|
||||
static const char * name_portamento_mode[FLUID_CHANNEL_PORTAMENTO_MODE_LAST]=
|
||||
{ "(0)each note", "(1)legato only", "(2)staccato only" };
|
||||
|
||||
FLUID_ENTRY_COMMAND(data);
|
||||
fluid_synth_t* synth = handler->synth;
|
||||
int mode = 0;
|
||||
int i, n, n_chan= synth->midi_channels;
|
||||
|
||||
/* checks channels arguments: chan1 chan2 . . . */
|
||||
if (check_channels_arguments(ac, av, out, name_cde) < 0)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
if (ac )
|
||||
{
|
||||
n = ac; /* prints ac MIDI channels number */
|
||||
}
|
||||
else
|
||||
{
|
||||
n= n_chan; /* prints all MIDI channels number */
|
||||
}
|
||||
/* prints header */
|
||||
fluid_ostream_printf(out,"Channel , portamento mode\n");
|
||||
for (i = 0; i < n; i++)
|
||||
{
|
||||
int chan = ac ? atoi(av[i]): i;
|
||||
int result = fluid_synth_get_portamento_mode(synth, chan, &mode);
|
||||
print_result_get_channel_mode(result, out, name_cde, chan, name_portamento_mode[mode], n_chan);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------------------------
|
||||
setportamentomode chan1 mode1 [chan2 mode2] .. ..
|
||||
|
||||
Changes portamento mode for channels chan1 and [chan2]
|
||||
*/
|
||||
int fluid_handle_setportamentomode(void* data, int ac, char** av,
|
||||
fluid_ostream_t out)
|
||||
{
|
||||
static const char * name_cde="setportamentomode";
|
||||
FLUID_ENTRY_COMMAND(data);
|
||||
fluid_synth_t* synth = handler->synth;
|
||||
int i,n ;
|
||||
|
||||
/* checks channels arguments by group of 2: chan1 val1 chan2 val1 .. .. */
|
||||
if (check_channels_group_arguments(ac, av, 2, out, name_cde, too_few_arg_chan_mode_msg) < 0)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
n = ac / 2; /* number of portamento groups informations */
|
||||
for (i = 0; i < n; i++)
|
||||
{
|
||||
int chan = atoi(av[(i * 2)]);
|
||||
int mode = atoi(av[(i * 2)+1]);
|
||||
/* changes portamento mode */
|
||||
|
||||
int result = fluid_synth_set_portamento_mode(synth,chan,mode);
|
||||
print_result_set_channel_mode(result, out, name_cde, chan, mode);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/** commands mono/poly breath mode *******************************************/
|
||||
/*-----------------------------------------------------------------------------
|
||||
breathmode
|
||||
Prints breath options of all MIDI channels.
|
||||
poly breath on/off, mono breath on/off, breath sync on/off
|
||||
|
||||
example
|
||||
|
||||
Channel , poly breath , mono breath , breath sync
|
||||
channel: 0, off , off , off
|
||||
channel: 1, off , off , off
|
||||
channel: 2, off , off , off
|
||||
.....
|
||||
|
||||
breathmode chan1 chan2
|
||||
Prints only breath mode of MIDI channels chan1, chan2
|
||||
*/
|
||||
int fluid_handle_breathmode(void* data, int ac, char** av,
|
||||
fluid_ostream_t out)
|
||||
{
|
||||
static const char * name_cde="breathmode";
|
||||
static const char * header="Channel , poly breath , mono breath , breath sync\n";
|
||||
FLUID_ENTRY_COMMAND(data);
|
||||
fluid_synth_t* synth = handler->synth;
|
||||
int breathmode;
|
||||
int i, n, n_chan= synth->midi_channels;
|
||||
|
||||
/* checks channels arguments: chan1 chan2 . . . */
|
||||
if (check_channels_arguments(ac, av, out, name_cde) < 0)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (ac )
|
||||
{
|
||||
n = ac; /* prints ac MIDI channels number */
|
||||
}
|
||||
else
|
||||
{
|
||||
n= n_chan; /* prints all MIDI channels number */
|
||||
}
|
||||
/* prints header */
|
||||
fluid_ostream_printf(out, header);
|
||||
for (i = 0; i < n; i++)
|
||||
{
|
||||
int chan = ac ? atoi(av[i]): i;
|
||||
int result = fluid_synth_get_breath_mode(synth, chan, &breathmode);
|
||||
if (result == FLUID_OK)
|
||||
{
|
||||
static const char * on_msg ="on";
|
||||
static const char * off_msg ="off";
|
||||
const char * msg_poly_breath, * msg_mono_breath, * msg_breath_sync;
|
||||
if (breathmode & FLUID_CHANNEL_BREATH_POLY)
|
||||
{
|
||||
msg_poly_breath =on_msg;
|
||||
}
|
||||
else
|
||||
{
|
||||
msg_poly_breath = off_msg;
|
||||
}
|
||||
if (breathmode & FLUID_CHANNEL_BREATH_MONO)
|
||||
{
|
||||
msg_mono_breath =on_msg;
|
||||
}
|
||||
else
|
||||
{
|
||||
msg_mono_breath = off_msg;
|
||||
}
|
||||
if (breathmode & FLUID_CHANNEL_BREATH_SYNC)
|
||||
{
|
||||
msg_breath_sync =on_msg;
|
||||
}
|
||||
else
|
||||
{
|
||||
msg_breath_sync = off_msg;
|
||||
}
|
||||
fluid_ostream_printf(out,"channel:%3d, %-12s, %-12s, %-11s\n",chan,
|
||||
msg_poly_breath, msg_mono_breath, msg_breath_sync);
|
||||
}
|
||||
else
|
||||
{
|
||||
print_channel_is_outside_count(out, name_cde, chan, n_chan);
|
||||
if(i < n-1)
|
||||
{
|
||||
fluid_ostream_printf(out, header);
|
||||
}
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------------------------
|
||||
setbreathmode chan1 poly_breath_mode(1/0) mono_breath_mode(1/0) mono_breath_sync(1/0)
|
||||
|
||||
Changes breath options for channels chan1 [chan2] .. ..
|
||||
|
||||
Example: setbreathmode 4 0 1 1
|
||||
|
||||
Parameter 1 is the channel number (i.e 4).
|
||||
Parameter 2 is the " Breath modulator " enable/disable for poly mode (i.e disabled).
|
||||
Parameter 3 is the " Breath modulator " enabe/disable for mono mode (i.e enabled).
|
||||
Parameter 4 is "breath sync noteOn/Off" enable/disable for mono mode only (i.e enabled).
|
||||
|
||||
*/
|
||||
int fluid_handle_setbreathmode(void* data, int ac, char** av,
|
||||
fluid_ostream_t out)
|
||||
{
|
||||
static const char * name_cde="setbreathmode";
|
||||
static const char *too_few_arg_breath_msg =
|
||||
"too few argument:\nchan 1/0(breath poly) 1/0(breath mono) 1/0(breath sync mono)[..]\n";
|
||||
|
||||
FLUID_ENTRY_COMMAND(data);
|
||||
fluid_synth_t* synth = handler->synth;
|
||||
int i,n, n_chan= synth->midi_channels;
|
||||
|
||||
/* checks channels arguments by group of 4:
|
||||
chan1 val1 val2 val3 chan2 val1 val2 val3 .... ....*/
|
||||
if (check_channels_group_arguments(ac, av, 4, out, name_cde, too_few_arg_breath_msg) < 0)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
n = ac / 4; /* number of breath groups informations */
|
||||
for (i = 0; i < n; i++)
|
||||
{
|
||||
int result;
|
||||
int chan = atoi(av[(i * 4)]);
|
||||
int poly_breath = atoi(av[(i * 4)+1]);
|
||||
int mono_breath = atoi(av[(i * 4)+2]);
|
||||
int breath_sync = atoi(av[(i * 4)+3]);
|
||||
int breath_infos = 0;
|
||||
/* changes breath infos */
|
||||
if(poly_breath) breath_infos |= FLUID_CHANNEL_BREATH_POLY;
|
||||
if(mono_breath) breath_infos |= FLUID_CHANNEL_BREATH_MONO;
|
||||
if(breath_sync) breath_infos |= FLUID_CHANNEL_BREATH_SYNC;
|
||||
result = fluid_synth_set_breath_mode(synth,chan,breath_infos);
|
||||
if (result == FLUID_FAILED)
|
||||
{
|
||||
print_channel_is_outside_count(out, name_cde, chan, n_chan);
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
#ifdef LADSPA
|
||||
|
||||
#define CHECK_LADSPA_ENABLED(_fx, _out) \
|
||||
|
|
|
@ -84,6 +84,19 @@ int fluid_handle_router_chan(void* data, int ac, char** av, fluid_ostream_t out)
|
|||
int fluid_handle_router_par1(void* data, int ac, char** av, fluid_ostream_t out);
|
||||
int fluid_handle_router_par2(void* data, int ac, char** av, fluid_ostream_t out);
|
||||
|
||||
int fluid_handle_basicchannels (void* data, int ac, char** av, fluid_ostream_t out);
|
||||
int fluid_handle_resetbasicchannels (void* data, int ac, char** av, fluid_ostream_t out);
|
||||
int fluid_handle_setbasicchannels (void* data, int ac, char** av, fluid_ostream_t out);
|
||||
int fluid_handle_channelsmode (void* data, int ac, char** av, fluid_ostream_t out);
|
||||
int fluid_handle_legatomode(void* data, int ac, char** av, fluid_ostream_t out);
|
||||
int fluid_handle_setlegatomode(void* data, int ac, char** av, fluid_ostream_t out);
|
||||
int fluid_handle_portamentomode(void* data, int ac, char** av, fluid_ostream_t out);
|
||||
int fluid_handle_setportamentomode(void* data, int ac, char** av, fluid_ostream_t out);
|
||||
int fluid_handle_breathmode(void* data, int ac, char** av, fluid_ostream_t out);
|
||||
int fluid_handle_setbreathmode(void* data, int ac, char** av, fluid_ostream_t out);
|
||||
int fluid_handle_sleep(void *data, int ac, char** av, fluid_ostream_t out);
|
||||
|
||||
|
||||
#ifdef LADSPA
|
||||
int fluid_handle_ladspa_effect(void *data, int ac, char **av, fluid_ostream_t out);
|
||||
int fluid_handle_ladspa_link(void *data, int ac, char **av, fluid_ostream_t out);
|
||||
|
@ -95,6 +108,7 @@ int fluid_handle_ladspa_stop(void *data, int ac, char **av, fluid_ostream_t out)
|
|||
int fluid_handle_ladspa_reset(void *data, int ac, char **av, fluid_ostream_t out);
|
||||
#endif
|
||||
|
||||
|
||||
/**
|
||||
* Command handler function prototype.
|
||||
* @param data User defined data
|
||||
|
|
|
@ -145,7 +145,7 @@ fluid_lash_run (void * data)
|
|||
|
||||
while ( (config = lash_get_config (fluid_lash_client)) )
|
||||
{
|
||||
if (strcmp (lash_config_get_key (config), "soundfont count") == 0)
|
||||
if (FLUID_STRCMP (lash_config_get_key (config), "soundfont count") == 0)
|
||||
pending_restores = lash_config_get_value_int (config);
|
||||
else
|
||||
{
|
||||
|
|
|
@ -48,13 +48,13 @@ static pid_t _gettid(void) {
|
|||
}
|
||||
|
||||
static int translate_error(const char *name) {
|
||||
if (strcmp(name, DBUS_ERROR_NO_MEMORY) == 0)
|
||||
if (FLUID_STRCMP(name, DBUS_ERROR_NO_MEMORY) == 0)
|
||||
return -ENOMEM;
|
||||
if (strcmp(name, DBUS_ERROR_SERVICE_UNKNOWN) == 0 ||
|
||||
strcmp(name, DBUS_ERROR_NAME_HAS_NO_OWNER) == 0)
|
||||
if (FLUID_STRCMP(name, DBUS_ERROR_SERVICE_UNKNOWN) == 0 ||
|
||||
FLUID_STRCMP(name, DBUS_ERROR_NAME_HAS_NO_OWNER) == 0)
|
||||
return -ENOENT;
|
||||
if (strcmp(name, DBUS_ERROR_ACCESS_DENIED) == 0 ||
|
||||
strcmp(name, DBUS_ERROR_AUTH_FAILED) == 0)
|
||||
if (FLUID_STRCMP(name, DBUS_ERROR_ACCESS_DENIED) == 0 ||
|
||||
FLUID_STRCMP(name, DBUS_ERROR_AUTH_FAILED) == 0)
|
||||
return -EACCES;
|
||||
|
||||
return -EIO;
|
||||
|
|
|
@ -216,7 +216,7 @@ new_fluid_portaudio_driver (fluid_settings_t *settings, fluid_synth_t *synth)
|
|||
outputParams.suggestedLatency = (PaTime)period_size / sample_rate;
|
||||
|
||||
/* Locate the device if specified */
|
||||
if (strcmp (device, PORTAUDIO_DEFAULT_DEVICE) != 0)
|
||||
if (FLUID_STRCMP (device, PORTAUDIO_DEFAULT_DEVICE) != 0)
|
||||
{ /* The intended device is not the default device name, so we search
|
||||
a device among available devices */
|
||||
int numDevices;
|
||||
|
@ -239,7 +239,7 @@ new_fluid_portaudio_driver (fluid_settings_t *settings, fluid_synth_t *synth)
|
|||
if(name)
|
||||
{
|
||||
/* We see if the name corresponds to audio.portaudio.device */
|
||||
char found = (strcmp (device, name) == 0);
|
||||
char found = (FLUID_STRCMP (device, name) == 0);
|
||||
FLUID_FREE (name);
|
||||
|
||||
if(found)
|
||||
|
|
|
@ -115,19 +115,19 @@ new_fluid_pulse_audio_driver2(fluid_settings_t* settings,
|
|||
fluid_settings_getint(settings, "audio.pulseaudio.adjust-latency", &adjust_latency);
|
||||
|
||||
if (media_role != NULL) {
|
||||
if (strcmp(media_role, "") != 0) {
|
||||
if (FLUID_STRCMP(media_role, "") != 0) {
|
||||
g_setenv("PULSE_PROP_media.role", media_role, TRUE);
|
||||
}
|
||||
FLUID_FREE (media_role); /* -- free media_role string */
|
||||
}
|
||||
|
||||
if (server && strcmp (server, "default") == 0)
|
||||
if (server && FLUID_STRCMP (server, "default") == 0)
|
||||
{
|
||||
FLUID_FREE (server); /* -- free server string */
|
||||
server = NULL;
|
||||
}
|
||||
|
||||
if (device && strcmp (device, "default") == 0)
|
||||
if (device && FLUID_STRCMP (device, "default") == 0)
|
||||
{
|
||||
FLUID_FREE (device); /* -- free device string */
|
||||
device = NULL;
|
||||
|
|
|
@ -70,13 +70,13 @@ void process_o_cmd_line_option(fluid_settings_t* settings, char* optarg)
|
|||
}
|
||||
|
||||
/* did user request list of settings */
|
||||
if (strcmp (optarg, "help") == 0)
|
||||
if (FLUID_STRCMP (optarg, "help") == 0)
|
||||
{
|
||||
option_help = 1;
|
||||
return;
|
||||
}
|
||||
|
||||
if (strcmp (optarg, "") == 0) {
|
||||
if (FLUID_STRCMP (optarg, "") == 0) {
|
||||
fprintf (stderr, "Invalid -o option (name part is empty)\n");
|
||||
return;
|
||||
}
|
||||
|
@ -374,7 +374,7 @@ int main(int argc, char** argv)
|
|||
else fluid_settings_setstr(settings, "audio.driver", optarg);
|
||||
break;
|
||||
case 'C':
|
||||
if ((optarg != NULL) && ((strcmp(optarg, "0") == 0) || (strcmp(optarg, "no") == 0))) {
|
||||
if ((optarg != NULL) && ((FLUID_STRCMP(optarg, "0") == 0) || (FLUID_STRCMP(optarg, "no") == 0))) {
|
||||
fluid_settings_setint(settings, "synth.chorus.active", FALSE);
|
||||
} else {
|
||||
fluid_settings_setint(settings, "synth.chorus.active", TRUE);
|
||||
|
@ -473,7 +473,7 @@ int main(int argc, char** argv)
|
|||
fluid_settings_setstr(settings, "midi.portname", optarg);
|
||||
break;
|
||||
case 'R':
|
||||
if ((optarg != NULL) && ((strcmp(optarg, "0") == 0) || (strcmp(optarg, "no") == 0))) {
|
||||
if ((optarg != NULL) && ((FLUID_STRCMP(optarg, "0") == 0) || (FLUID_STRCMP(optarg, "no") == 0))) {
|
||||
fluid_settings_setint(settings, "synth.reverb.active", FALSE);
|
||||
} else {
|
||||
fluid_settings_setint(settings, "synth.reverb.active", TRUE);
|
||||
|
|
|
@ -349,7 +349,7 @@ fluid_midi_file_read_track(fluid_midi_file *mf, fluid_player_t *player, int num)
|
|||
"An non-ascii track header found, corrupt file");
|
||||
return FLUID_FAILED;
|
||||
|
||||
} else if (strcmp((char *) id, "MTrk") == 0) {
|
||||
} else if (FLUID_STRCMP((char *) id, "MTrk") == 0) {
|
||||
|
||||
found_track = 1;
|
||||
|
||||
|
|
|
@ -106,7 +106,7 @@ enum fluid_midi_control_change {
|
|||
PORTAMENTO_SWITCH = 0x41,
|
||||
SOSTENUTO_SWITCH = 0x42,
|
||||
SOFT_PEDAL_SWITCH = 0x43,
|
||||
LEGATO_SWITCH = 0x45,
|
||||
LEGATO_SWITCH = 0x44,
|
||||
HOLD2_SWITCH = 0x45,
|
||||
SOUND_CTRL1 = 0x46,
|
||||
SOUND_CTRL2 = 0x47,
|
||||
|
|
|
@ -252,7 +252,7 @@ static fluid_seq_id_t get_fluidsynth_dest(fluid_sequencer_t* seq)
|
|||
for (i = 0; i < j; i++) {
|
||||
id = fluid_sequencer_get_client_id(seq, i);
|
||||
name = fluid_sequencer_get_client_name(seq, id);
|
||||
if (name && (strcmp(name, "fluidsynth") == 0)) {
|
||||
if (name && (FLUID_STRCMP(name, "fluidsynth") == 0)) {
|
||||
return id;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -95,9 +95,11 @@ fluid_adsr_env_calc(fluid_adsr_env_t* env, int is_volenv)
|
|||
env->section++;
|
||||
env->count = 0;
|
||||
}
|
||||
else env->count++;
|
||||
|
||||
env->val = x;
|
||||
env->count++;
|
||||
|
||||
|
||||
}
|
||||
|
||||
/* This one cannot be inlined since it is referenced in
|
||||
|
|
|
@ -319,11 +319,37 @@ fluid_rvoice_write (fluid_rvoice_t* voice, fluid_real_t *dsp_buf)
|
|||
* buffer. It is the ratio between the frequencies of original
|
||||
* waveform and output waveform.*/
|
||||
voice->dsp.phase_incr = fluid_ct2hz_real(voice->dsp.pitch +
|
||||
voice->dsp.pitchoffset +
|
||||
fluid_lfo_get_val(&voice->envlfo.modlfo) * voice->envlfo.modlfo_to_pitch
|
||||
+ fluid_lfo_get_val(&voice->envlfo.viblfo) * voice->envlfo.viblfo_to_pitch
|
||||
+ fluid_adsr_env_get_val(&voice->envlfo.modenv) * voice->envlfo.modenv_to_pitch)
|
||||
/ voice->dsp.root_pitch_hz;
|
||||
|
||||
/******************* portamento ****************/
|
||||
/* pitchoffset is updated if enabled.
|
||||
Pitchoffset will be added to dsp pitch at next phase calculation time */
|
||||
|
||||
/* In most cases portamento will be disabled. Thus first verify that portamento is
|
||||
* enabled before updating pitchoffset and before disabling portamento when necessary,
|
||||
* in order to keep the performance loss at minimum.
|
||||
* If the algorithm would first update pitchoffset and then verify if portamento
|
||||
* needs to be disabled, there would be a significant performance drop on a x87 FPU
|
||||
*/
|
||||
if (voice->dsp.pitchinc > 0.0f)
|
||||
{ /* portamento is enabled, so update pitchoffset */
|
||||
voice->dsp.pitchoffset += voice->dsp.pitchinc;
|
||||
/* when pitchoffset reaches 0.0f, portamento is disabled */
|
||||
if (voice->dsp.pitchoffset > 0.0f)
|
||||
voice->dsp.pitchoffset = voice->dsp.pitchinc = 0.0f;
|
||||
}
|
||||
else if (voice->dsp.pitchinc < 0.0f)
|
||||
{ /* portamento is enabled, so update pitchoffset */
|
||||
voice->dsp.pitchoffset += voice->dsp.pitchinc;
|
||||
/* when pitchoffset reaches 0.0f, portamento is disabled */
|
||||
if (voice->dsp.pitchoffset < 0.0f)
|
||||
voice->dsp.pitchoffset = voice->dsp.pitchinc = 0.0f;
|
||||
}
|
||||
|
||||
fluid_check_fpe ("voice_write phase calculation");
|
||||
|
||||
/* if phase_incr is not advancing, set it to the minimum fraction value (prevent stuckage) */
|
||||
|
@ -363,11 +389,11 @@ fluid_rvoice_write (fluid_rvoice_t* voice, fluid_real_t *dsp_buf)
|
|||
/*************** resonant filter ******************/
|
||||
|
||||
fluid_iir_filter_calc(&voice->resonant_filter, voice->dsp.output_rate,
|
||||
fluid_lfo_get_val(&voice->envlfo.modlfo) * voice->envlfo.modlfo_to_fc +
|
||||
fluid_adsr_env_get_val(&voice->envlfo.modenv) * voice->envlfo.modenv_to_fc);
|
||||
fluid_lfo_get_val(&voice->envlfo.modlfo) * voice->envlfo.modlfo_to_fc +
|
||||
fluid_adsr_env_get_val(&voice->envlfo.modenv) * voice->envlfo.modenv_to_fc);
|
||||
|
||||
fluid_iir_filter_apply(&voice->resonant_filter, dsp_buf, count);
|
||||
|
||||
|
||||
/* additional custom filter - only uses the fixed modulator, no lfos... */
|
||||
fluid_iir_filter_calc(&voice->resonant_custom_filter, voice->dsp.output_rate, 0);
|
||||
fluid_iir_filter_apply(&voice->resonant_custom_filter, dsp_buf, count);
|
||||
|
@ -478,7 +504,11 @@ fluid_rvoice_reset(fluid_rvoice_t* voice)
|
|||
calculate the volume increment during
|
||||
processing */
|
||||
|
||||
/* mod env initialization*/
|
||||
/* legato initialization */
|
||||
voice->dsp.pitchoffset = 0.0; /* portamento initialization */
|
||||
voice->dsp.pitchinc = 0.0;
|
||||
|
||||
/* mod env initialization*/
|
||||
fluid_adsr_env_reset(&voice->envlfo.modenv);
|
||||
|
||||
/* vol env initialization */
|
||||
|
@ -530,6 +560,102 @@ fluid_rvoice_noteoff(fluid_rvoice_t* voice, unsigned int min_ticks)
|
|||
fluid_adsr_env_set_section(&voice->envlfo.modenv, FLUID_VOICE_ENVRELEASE);
|
||||
}
|
||||
|
||||
/**
|
||||
* skips to Attack section
|
||||
*
|
||||
* Updates vol and attack data
|
||||
* Correction on volume val to achieve equivalent amplitude at noteOn legato
|
||||
*
|
||||
* @param voice the synthesis voice to be updated
|
||||
*/
|
||||
static FLUID_INLINE void fluid_rvoice_local_retrigger_attack (fluid_rvoice_t* voice)
|
||||
{
|
||||
/* skips to Attack section */
|
||||
/* Once in Attack section, current count must be reset, to be sure
|
||||
that the section will be not be prematurely finished. */
|
||||
fluid_adsr_env_set_section(&voice->envlfo.volenv, FLUID_VOICE_ENVATTACK);
|
||||
{
|
||||
/* Correction on volume val to achieve equivalent amplitude at noteOn legato */
|
||||
fluid_env_data_t* env_data;
|
||||
fluid_real_t peak = fluid_cb2amp (voice->dsp.attenuation);
|
||||
fluid_real_t prev_peak = fluid_cb2amp (voice->dsp.prev_attenuation);
|
||||
voice->envlfo.volenv.val = (voice->envlfo.volenv.val * prev_peak) / peak;
|
||||
/* Correction on slope direction for Attack section */
|
||||
env_data = &voice->envlfo.volenv.data[FLUID_VOICE_ENVATTACK];
|
||||
if(voice->envlfo.volenv.val <=1.0f)
|
||||
{ /* slope attack for legato note needs to be positive from val up to 1 */
|
||||
env_data->increment = 1.0f / env_data->count;
|
||||
env_data->min = -1.0f; env_data->max = 1.0f;
|
||||
}
|
||||
else
|
||||
{ /* slope attack for legato note needs to be negative: from val down to 1 */
|
||||
env_data->increment = -voice->envlfo.volenv.val / env_data->count;
|
||||
env_data->min = 1.0f; env_data->max = voice->envlfo.volenv.val;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Used by legato Mode : multi_retrigger
|
||||
* see fluid_synth_noteon_mono_legato_multi_retrigger()
|
||||
* @param voice the synthesis voice to be updated
|
||||
*/
|
||||
void
|
||||
fluid_rvoice_multi_retrigger_attack (fluid_rvoice_t* voice)
|
||||
{
|
||||
int section = fluid_adsr_env_get_section(&voice->envlfo.volenv);
|
||||
/*-------------------------------------------------------------------------
|
||||
Section skip for volume envelope
|
||||
--------------------------------------------------------------------------*/
|
||||
if (section >= FLUID_VOICE_ENVHOLD)
|
||||
{
|
||||
/* DECAY, SUSTAIN,RELEASE section use logarithmic scaling. Calculates new
|
||||
volenv_val to achieve equivalent amplitude during the attack phase
|
||||
for seamless volume transition. */
|
||||
fluid_real_t amp_cb, env_value;
|
||||
amp_cb = 960.0f * (1.0f - fluid_adsr_env_get_val(&voice->envlfo.volenv));
|
||||
env_value = fluid_cb2amp(amp_cb); /* a bit of optimization */
|
||||
fluid_clip (env_value, 0.0, 1.0);
|
||||
fluid_adsr_env_set_val(&voice->envlfo.volenv, env_value);
|
||||
/* next, skips to Attack section */
|
||||
}
|
||||
/* skips to Attack section from any section */
|
||||
/* Update vol and attack data */
|
||||
fluid_rvoice_local_retrigger_attack(voice);
|
||||
/*-------------------------------------------------------------------------
|
||||
Section skip for modulation envelope
|
||||
--------------------------------------------------------------------------*/
|
||||
/* Skips from any section to ATTACK section */
|
||||
fluid_adsr_env_set_section(&voice->envlfo.modenv, FLUID_VOICE_ENVATTACK);
|
||||
/* Actually (v 1.1.6) all sections are linear, so there is no need to
|
||||
correct val value. However soundfont 2.01/2.4 spec. says that Attack should
|
||||
be convex (see issue #153 from Christian Collins). In the case Attack
|
||||
section would be changed to a non linear shape it will be necessary to do
|
||||
a correction for seamless val transition. Here is the place to do this */
|
||||
}
|
||||
|
||||
/**
|
||||
* sets the portamento dsp parameters: dsp.pitchoffset, dsp.pitchinc
|
||||
* @param voice rvoice to set portamento.
|
||||
* @param countinc increment count number.
|
||||
* @param pitchoffset pitch offset to apply to voice dsp.pitch.
|
||||
*
|
||||
* Notes:
|
||||
* 1) To get continuous portamento between consecutive noteOn (n1,n2,n3...),
|
||||
* pitchoffset is accumulated in current dsp pitchoffset.
|
||||
* 2) And to get constant portamento duration, dsp pitch increment is updated.
|
||||
*/
|
||||
void fluid_rvoice_set_portamento(fluid_rvoice_t * voice, unsigned int countinc,
|
||||
fluid_real_t pitchoffset)
|
||||
{
|
||||
if (countinc)
|
||||
{
|
||||
voice->dsp.pitchoffset += pitchoffset;
|
||||
voice->dsp.pitchinc = - voice->dsp.pitchoffset / countinc;
|
||||
}
|
||||
/* Then during the voice processing (in fluid_rvoice_write()),
|
||||
dsp.pitchoffset will be incremented by dsp pitchinc. */
|
||||
}
|
||||
|
||||
void
|
||||
fluid_rvoice_set_output_rate(fluid_rvoice_t* voice, fluid_real_t value)
|
||||
|
@ -559,6 +685,7 @@ fluid_rvoice_set_pitch(fluid_rvoice_t* voice, fluid_real_t value)
|
|||
void
|
||||
fluid_rvoice_set_attenuation(fluid_rvoice_t* voice, fluid_real_t value)
|
||||
{
|
||||
voice->dsp.prev_attenuation = voice->dsp.attenuation;
|
||||
voice->dsp.attenuation = value;
|
||||
}
|
||||
|
||||
|
|
|
@ -96,6 +96,10 @@ struct _fluid_rvoice_dsp_t
|
|||
int loopend; /* Note: first point following the loop (superimposed on loopstart) */
|
||||
enum fluid_loop samplemode;
|
||||
|
||||
/* Stuff needed for portamento calculations */
|
||||
fluid_real_t pitchoffset; /* the portamento range in midicents */
|
||||
fluid_real_t pitchinc; /* the portamento increment in midicents */
|
||||
|
||||
/* Stuff needed for phase calculations */
|
||||
|
||||
fluid_real_t pitch; /* the pitch in midicents */
|
||||
|
@ -106,6 +110,8 @@ struct _fluid_rvoice_dsp_t
|
|||
|
||||
int has_looped; /* Flag that is set as soon as the first loop is completed. */
|
||||
fluid_real_t attenuation; /* the attenuation in centibels */
|
||||
fluid_real_t prev_attenuation; /* the previous attenuation in centibels
|
||||
used by fluid_rvoice_multi_retrigger_attack() */
|
||||
fluid_real_t min_attenuation_cB; /* Estimate on the smallest possible attenuation
|
||||
* during the lifetime of the voice */
|
||||
fluid_real_t amplitude_that_reaches_noise_floor_nonloop;
|
||||
|
@ -167,7 +173,9 @@ void fluid_rvoice_buffers_set_mapping(fluid_rvoice_buffers_t* buffers,
|
|||
unsigned int bufnum, int mapping);
|
||||
|
||||
/* Dynamic update functions */
|
||||
|
||||
void fluid_rvoice_set_portamento(fluid_rvoice_t * voice, unsigned int countinc,
|
||||
fluid_real_t pitchoffset);
|
||||
void fluid_rvoice_multi_retrigger_attack(fluid_rvoice_t* voice);
|
||||
void fluid_rvoice_noteoff(fluid_rvoice_t* voice, unsigned int min_ticks);
|
||||
void fluid_rvoice_voiceoff(fluid_rvoice_t* voice);
|
||||
void fluid_rvoice_reset(fluid_rvoice_t* voice);
|
||||
|
|
|
@ -103,6 +103,9 @@ fluid_rvoice_event_dispatch(fluid_rvoice_event_t* event)
|
|||
EVENTFUNC_I1(fluid_rvoice_noteoff, fluid_rvoice_t*);
|
||||
EVENTFUNC_0(fluid_rvoice_voiceoff, fluid_rvoice_t*);
|
||||
EVENTFUNC_0(fluid_rvoice_reset, fluid_rvoice_t*);
|
||||
|
||||
EVENTFUNC_0(fluid_rvoice_multi_retrigger_attack, fluid_rvoice_t*);
|
||||
EVENTFUNC_IR(fluid_rvoice_set_portamento, fluid_rvoice_t*);
|
||||
|
||||
EVENTFUNC_IIR4(fluid_adsr_env_set_data, fluid_adsr_env_t*);
|
||||
|
||||
|
|
|
@ -25,6 +25,7 @@
|
|||
#include "fluid_defsfont.h"
|
||||
#include "fluid_sfont.h"
|
||||
#include "fluid_sys.h"
|
||||
#include "fluid_synth.h"
|
||||
|
||||
#if LIBSNDFILE_SUPPORT
|
||||
#include <sndfile.h>
|
||||
|
@ -52,7 +53,7 @@
|
|||
*/
|
||||
fluid_sfloader_t* new_fluid_defsfloader(fluid_settings_t* settings)
|
||||
{
|
||||
fluid_sfloader_t* loader;
|
||||
fluid_sfloader_t* loader;
|
||||
fluid_return_val_if_fail(settings != NULL, NULL);
|
||||
|
||||
loader = new_fluid_sfloader(fluid_defsfloader_load, delete_fluid_sfloader);
|
||||
|
@ -64,7 +65,7 @@ fluid_sfloader_t* new_fluid_defsfloader(fluid_settings_t* settings)
|
|||
}
|
||||
|
||||
fluid_sfloader_set_data(loader, settings);
|
||||
|
||||
|
||||
return loader;
|
||||
}
|
||||
|
||||
|
@ -91,7 +92,7 @@ fluid_sfont_t* fluid_defsfloader_load(fluid_sfloader_t* loader, const char* file
|
|||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
fluid_sfont_set_iteration_start(sfont, fluid_defsfont_sfont_iteration_start);
|
||||
fluid_sfont_set_iteration_next(sfont, fluid_defsfont_sfont_iteration_next);
|
||||
fluid_sfont_set_data(sfont, defsfont);
|
||||
|
@ -274,7 +275,7 @@ static int fluid_cached_sampledata_load(char *filename,
|
|||
}
|
||||
|
||||
for (cached_sampledata = all_cached_sampledata; cached_sampledata; cached_sampledata = cached_sampledata->next) {
|
||||
if (strcmp(filename, cached_sampledata->filename))
|
||||
if (FLUID_STRCMP(filename, cached_sampledata->filename))
|
||||
continue;
|
||||
if (cached_sampledata->modification_time != modification_time)
|
||||
continue;
|
||||
|
@ -854,7 +855,7 @@ fluid_defpreset_noteon(fluid_defpreset_t* preset, fluid_synth_t* synth, int chan
|
|||
|
||||
/* check if the note falls into the key and velocity range of this
|
||||
preset */
|
||||
if (fluid_preset_zone_inside_range(preset_zone, key, vel)) {
|
||||
if (fluid_zone_inside_range(&preset_zone->range, key, vel)) {
|
||||
|
||||
inst = fluid_preset_zone_get_inst(preset_zone);
|
||||
global_inst_zone = fluid_inst_get_global_zone(inst);
|
||||
|
@ -862,7 +863,6 @@ fluid_defpreset_noteon(fluid_defpreset_t* preset, fluid_synth_t* synth, int chan
|
|||
/* run thru all the zones of this instrument */
|
||||
inst_zone = fluid_inst_get_zone(inst);
|
||||
while (inst_zone != NULL) {
|
||||
|
||||
/* make sure this instrument zone has a valid sample */
|
||||
sample = fluid_inst_zone_get_sample(inst_zone);
|
||||
if ((sample == NULL) || fluid_sample_in_rom(sample)) {
|
||||
|
@ -870,15 +870,14 @@ fluid_defpreset_noteon(fluid_defpreset_t* preset, fluid_synth_t* synth, int chan
|
|||
continue;
|
||||
}
|
||||
|
||||
/* check if the note falls into the key and velocity range of this
|
||||
instrument */
|
||||
/* check if the instrument zone is ignored and the note falls into
|
||||
the key and velocity range of this instrument zone.
|
||||
An instrument zone must be ignored when its voice is already running
|
||||
played by a legato passage (see fluid_synth_noteon_monopoly_legato()) */
|
||||
if (fluid_zone_inside_range(&inst_zone->range, key, vel)) {
|
||||
|
||||
if (fluid_inst_zone_inside_range(inst_zone, key, vel) && (sample != NULL)) {
|
||||
|
||||
/* this is a good zone. allocate a new synthesis process and
|
||||
initialize it */
|
||||
|
||||
voice = fluid_synth_alloc_voice(synth, sample, chan, key, vel);
|
||||
/* this is a good zone. allocate a new synthesis process and initialize it */
|
||||
voice = fluid_synth_alloc_voice_LOCAL(synth, sample, chan, key, vel, &inst_zone->range);
|
||||
if (voice == NULL) {
|
||||
return FLUID_FAILED;
|
||||
}
|
||||
|
@ -1144,6 +1143,11 @@ fluid_defpreset_get_global_zone(fluid_defpreset_t* preset)
|
|||
return preset->global_zone;
|
||||
}
|
||||
|
||||
/***************************************************************
|
||||
*
|
||||
* PRESET_ZONE
|
||||
*/
|
||||
|
||||
/*
|
||||
* fluid_preset_zone_next
|
||||
*/
|
||||
|
@ -1176,10 +1180,11 @@ new_fluid_preset_zone(char *name)
|
|||
}
|
||||
FLUID_STRCPY(zone->name, name);
|
||||
zone->inst = NULL;
|
||||
zone->keylo = 0;
|
||||
zone->keyhi = 128;
|
||||
zone->vello = 0;
|
||||
zone->velhi = 128;
|
||||
zone->range.keylo = 0;
|
||||
zone->range.keyhi = 128;
|
||||
zone->range.vello = 0;
|
||||
zone->range.velhi = 128;
|
||||
zone->range.ignore = FALSE;
|
||||
|
||||
/* Flag all generators as unused (default, they will be set when they are found
|
||||
* in the sound font).
|
||||
|
@ -1189,11 +1194,6 @@ new_fluid_preset_zone(char *name)
|
|||
return zone;
|
||||
}
|
||||
|
||||
/***************************************************************
|
||||
*
|
||||
* PRESET_ZONE
|
||||
*/
|
||||
|
||||
/*
|
||||
* delete_fluid_preset_zone
|
||||
*/
|
||||
|
@ -1230,12 +1230,12 @@ fluid_preset_zone_import_sfont(fluid_preset_zone_t* zone, SFZone *sfzone, fluid_
|
|||
sfgen = (SFGen *) r->data;
|
||||
switch (sfgen->id) {
|
||||
case GEN_KEYRANGE:
|
||||
zone->keylo = (int) sfgen->amount.range.lo;
|
||||
zone->keyhi = (int) sfgen->amount.range.hi;
|
||||
zone->range.keylo = sfgen->amount.range.lo;
|
||||
zone->range.keyhi = sfgen->amount.range.hi;
|
||||
break;
|
||||
case GEN_VELRANGE:
|
||||
zone->vello = (int) sfgen->amount.range.lo;
|
||||
zone->velhi = (int) sfgen->amount.range.hi;
|
||||
zone->range.vello = sfgen->amount.range.lo;
|
||||
zone->range.velhi = sfgen->amount.range.hi;
|
||||
break;
|
||||
case GEN_ATTENUATION:
|
||||
/* EMU8k/10k hardware applies a scale factor to initial attenuation generator values set at
|
||||
|
@ -1257,7 +1257,8 @@ fluid_preset_zone_import_sfont(fluid_preset_zone_t* zone, SFZone *sfzone, fluid_
|
|||
FLUID_LOG(FLUID_ERR, "Out of memory");
|
||||
return FLUID_FAILED;
|
||||
}
|
||||
if (fluid_inst_import_sfont(zone->inst, (SFInst *) sfzone->instsamp->data, sfont) != FLUID_OK) {
|
||||
if (fluid_inst_import_sfont(zone, zone->inst,
|
||||
(SFInst *) sfzone->instsamp->data, sfont) != FLUID_OK) {
|
||||
return FLUID_FAILED;
|
||||
}
|
||||
}
|
||||
|
@ -1404,17 +1405,6 @@ fluid_preset_zone_get_inst(fluid_preset_zone_t* zone)
|
|||
return zone->inst;
|
||||
}
|
||||
|
||||
/*
|
||||
* fluid_preset_zone_inside_range
|
||||
*/
|
||||
int
|
||||
fluid_preset_zone_inside_range(fluid_preset_zone_t* zone, int key, int vel)
|
||||
{
|
||||
return ((zone->keylo <= key) &&
|
||||
(zone->keyhi >= key) &&
|
||||
(zone->vello <= vel) &&
|
||||
(zone->velhi >= vel));
|
||||
}
|
||||
|
||||
/***************************************************************
|
||||
*
|
||||
|
@ -1474,7 +1464,8 @@ fluid_inst_set_global_zone(fluid_inst_t* inst, fluid_inst_zone_t* zone)
|
|||
* fluid_inst_import_sfont
|
||||
*/
|
||||
int
|
||||
fluid_inst_import_sfont(fluid_inst_t* inst, SFInst *sfinst, fluid_defsfont_t* sfont)
|
||||
fluid_inst_import_sfont(fluid_preset_zone_t* zonePZ, fluid_inst_t* inst,
|
||||
SFInst *sfinst, fluid_defsfont_t* sfont)
|
||||
{
|
||||
fluid_list_t *p;
|
||||
SFZone* sfzone;
|
||||
|
@ -1500,7 +1491,7 @@ fluid_inst_import_sfont(fluid_inst_t* inst, SFInst *sfinst, fluid_defsfont_t* sf
|
|||
return FLUID_FAILED;
|
||||
}
|
||||
|
||||
if (fluid_inst_zone_import_sfont(zone, sfzone, sfont) != FLUID_OK) {
|
||||
if (fluid_inst_zone_import_sfont(zonePZ,zone, sfzone, sfont) != FLUID_OK) {
|
||||
delete_fluid_inst_zone(zone);
|
||||
return FLUID_FAILED;
|
||||
}
|
||||
|
@ -1580,11 +1571,11 @@ new_fluid_inst_zone(char* name)
|
|||
}
|
||||
FLUID_STRCPY(zone->name, name);
|
||||
zone->sample = NULL;
|
||||
zone->keylo = 0;
|
||||
zone->keyhi = 128;
|
||||
zone->vello = 0;
|
||||
zone->velhi = 128;
|
||||
|
||||
zone->range.keylo = 0;
|
||||
zone->range.keyhi = 128;
|
||||
zone->range.vello = 0;
|
||||
zone->range.velhi = 128;
|
||||
zone->range.ignore = FALSE;
|
||||
/* Flag the generators as unused.
|
||||
* This also sets the generator values to default, but they will be overwritten anyway, if used.*/
|
||||
fluid_gen_set_default_values(&zone->gen[0]);
|
||||
|
@ -1627,7 +1618,8 @@ fluid_inst_zone_next(fluid_inst_zone_t* zone)
|
|||
* fluid_inst_zone_import_sfont
|
||||
*/
|
||||
int
|
||||
fluid_inst_zone_import_sfont(fluid_inst_zone_t* zone, SFZone *sfzone, fluid_defsfont_t* sfont)
|
||||
fluid_inst_zone_import_sfont(fluid_preset_zone_t* preset_zone, fluid_inst_zone_t* zone,
|
||||
SFZone *sfzone, fluid_defsfont_t* sfont)
|
||||
{
|
||||
fluid_list_t *r;
|
||||
SFGen* sfgen;
|
||||
|
@ -1637,12 +1629,12 @@ fluid_inst_zone_import_sfont(fluid_inst_zone_t* zone, SFZone *sfzone, fluid_defs
|
|||
sfgen = (SFGen *) r->data;
|
||||
switch (sfgen->id) {
|
||||
case GEN_KEYRANGE:
|
||||
zone->keylo = (int) sfgen->amount.range.lo;
|
||||
zone->keyhi = (int) sfgen->amount.range.hi;
|
||||
zone->range.keylo = sfgen->amount.range.lo;
|
||||
zone->range.keyhi = sfgen->amount.range.hi;
|
||||
break;
|
||||
case GEN_VELRANGE:
|
||||
zone->vello = (int) sfgen->amount.range.lo;
|
||||
zone->velhi = (int) sfgen->amount.range.hi;
|
||||
zone->range.vello = sfgen->amount.range.lo;
|
||||
zone->range.velhi = sfgen->amount.range.hi;
|
||||
break;
|
||||
case GEN_ATTENUATION:
|
||||
/* EMU8k/10k hardware applies a scale factor to initial attenuation generator values set at
|
||||
|
@ -1659,6 +1651,13 @@ fluid_inst_zone_import_sfont(fluid_inst_zone_t* zone, SFZone *sfzone, fluid_defs
|
|||
}
|
||||
r = fluid_list_next(r);
|
||||
}
|
||||
|
||||
/* adjust instrument zone keyrange to integrate preset zone keyrange */
|
||||
if (preset_zone->range.keylo > zone->range.keylo) zone->range.keylo = preset_zone->range.keylo;
|
||||
if (preset_zone->range.keyhi < zone->range.keyhi) zone->range.keyhi = preset_zone->range.keyhi;
|
||||
/* adjust instrument zone to integrate preset zone velrange */
|
||||
if (preset_zone->range.vello > zone->range.vello) zone->range.vello = preset_zone->range.vello;
|
||||
if (preset_zone->range.velhi < zone->range.velhi) zone->range.velhi = preset_zone->range.velhi;
|
||||
|
||||
/* FIXME */
|
||||
/* if (zone->gen[GEN_EXCLUSIVECLASS].flags == GEN_SET) { */
|
||||
|
@ -1808,16 +1807,20 @@ fluid_inst_zone_get_sample(fluid_inst_zone_t* zone)
|
|||
return zone->sample;
|
||||
}
|
||||
|
||||
/*
|
||||
* fluid_inst_zone_inside_range
|
||||
*/
|
||||
|
||||
int
|
||||
fluid_inst_zone_inside_range(fluid_inst_zone_t* zone, int key, int vel)
|
||||
fluid_zone_inside_range(fluid_zone_range_t* range, int key, int vel)
|
||||
{
|
||||
return ((zone->keylo <= key) &&
|
||||
(zone->keyhi >= key) &&
|
||||
(zone->vello <= vel) &&
|
||||
(zone->velhi >= vel));
|
||||
/* ignoreInstrumentZone is set in mono legato playing */
|
||||
int ignore_zone = range->ignore;
|
||||
|
||||
/* Reset the 'ignore' request */
|
||||
range->ignore = FALSE;
|
||||
|
||||
return !ignore_zone && ((range->keylo <= key) &&
|
||||
(range->keyhi >= key) &&
|
||||
(range->vello <= vel) &&
|
||||
(range->velhi >= vel));
|
||||
}
|
||||
|
||||
/***************************************************************
|
||||
|
|
|
@ -343,7 +343,18 @@ typedef struct _fluid_defsfont_t fluid_defsfont_t;
|
|||
typedef struct _fluid_defpreset_t fluid_defpreset_t;
|
||||
typedef struct _fluid_preset_zone_t fluid_preset_zone_t;
|
||||
typedef struct _fluid_inst_t fluid_inst_t;
|
||||
typedef struct _fluid_inst_zone_t fluid_inst_zone_t;
|
||||
typedef struct _fluid_inst_zone_t fluid_inst_zone_t; /**< Soundfont Instrument Zone */
|
||||
|
||||
/* defines the velocity and key range for a zone */
|
||||
struct _fluid_zone_range_t
|
||||
{
|
||||
int keylo;
|
||||
int keyhi;
|
||||
int vello;
|
||||
int velhi;
|
||||
unsigned char ignore; /* set to TRUE for legato playing to ignore this range zone */
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
|
||||
|
@ -367,6 +378,7 @@ int fluid_defpreset_preset_get_banknum(fluid_preset_t* preset);
|
|||
int fluid_defpreset_preset_get_num(fluid_preset_t* preset);
|
||||
int fluid_defpreset_preset_noteon(fluid_preset_t* preset, fluid_synth_t* synth, int chan, int key, int vel);
|
||||
|
||||
int fluid_zone_inside_range(fluid_zone_range_t* zone_range, int key, int vel);
|
||||
|
||||
/*
|
||||
* fluid_defsfont_t
|
||||
|
@ -441,10 +453,7 @@ struct _fluid_preset_zone_t
|
|||
fluid_preset_zone_t* next;
|
||||
char* name;
|
||||
fluid_inst_t* inst;
|
||||
int keylo;
|
||||
int keyhi;
|
||||
int vello;
|
||||
int velhi;
|
||||
fluid_zone_range_t range;
|
||||
fluid_gen_t gen[GEN_LAST];
|
||||
fluid_mod_t * mod; /* List of modulators */
|
||||
};
|
||||
|
@ -453,7 +462,6 @@ fluid_preset_zone_t* new_fluid_preset_zone(char* name);
|
|||
void delete_fluid_preset_zone(fluid_preset_zone_t* zone);
|
||||
fluid_preset_zone_t* fluid_preset_zone_next(fluid_preset_zone_t* preset);
|
||||
int fluid_preset_zone_import_sfont(fluid_preset_zone_t* zone, SFZone* sfzone, fluid_defsfont_t* sfont);
|
||||
int fluid_preset_zone_inside_range(fluid_preset_zone_t* zone, int key, int vel);
|
||||
fluid_inst_t* fluid_preset_zone_get_inst(fluid_preset_zone_t* zone);
|
||||
|
||||
/*
|
||||
|
@ -467,8 +475,9 @@ struct _fluid_inst_t
|
|||
};
|
||||
|
||||
fluid_inst_t* new_fluid_inst(void);
|
||||
int fluid_inst_import_sfont(fluid_preset_zone_t* zonePZ, fluid_inst_t* inst,
|
||||
SFInst *sfinst, fluid_defsfont_t* sfont);
|
||||
void delete_fluid_inst(fluid_inst_t* inst);
|
||||
int fluid_inst_import_sfont(fluid_inst_t* inst, SFInst *sfinst, fluid_defsfont_t* sfont);
|
||||
int fluid_inst_set_global_zone(fluid_inst_t* inst, fluid_inst_zone_t* zone);
|
||||
int fluid_inst_add_zone(fluid_inst_t* inst, fluid_inst_zone_t* zone);
|
||||
fluid_inst_zone_t* fluid_inst_get_zone(fluid_inst_t* inst);
|
||||
|
@ -482,19 +491,17 @@ struct _fluid_inst_zone_t
|
|||
fluid_inst_zone_t* next;
|
||||
char* name;
|
||||
fluid_sample_t* sample;
|
||||
int keylo;
|
||||
int keyhi;
|
||||
int vello;
|
||||
int velhi;
|
||||
fluid_zone_range_t range;
|
||||
fluid_gen_t gen[GEN_LAST];
|
||||
fluid_mod_t * mod; /* List of modulators */
|
||||
};
|
||||
|
||||
|
||||
fluid_inst_zone_t* new_fluid_inst_zone(char* name);
|
||||
void delete_fluid_inst_zone(fluid_inst_zone_t* zone);
|
||||
fluid_inst_zone_t* fluid_inst_zone_next(fluid_inst_zone_t* zone);
|
||||
int fluid_inst_zone_import_sfont(fluid_inst_zone_t* zone, SFZone *sfzone, fluid_defsfont_t* sfont);
|
||||
int fluid_inst_zone_inside_range(fluid_inst_zone_t* zone, int key, int vel);
|
||||
int fluid_inst_zone_import_sfont(fluid_preset_zone_t* zonePZ,
|
||||
fluid_inst_zone_t* zone, SFZone *sfzone, fluid_defsfont_t* sfont);
|
||||
fluid_sample_t* fluid_inst_zone_get_sample(fluid_inst_zone_t* zone);
|
||||
|
||||
|
||||
|
|
|
@ -91,7 +91,7 @@ fluid_ramsfont_create_sfont()
|
|||
if (ramsfont == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
sfont = new_fluid_sfont(fluid_ramsfont_sfont_get_name,
|
||||
fluid_ramsfont_sfont_get_preset,
|
||||
fluid_ramsfont_sfont_delete);
|
||||
|
@ -99,11 +99,11 @@ fluid_ramsfont_create_sfont()
|
|||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
fluid_sfont_set_iteration_start(sfont, fluid_ramsfont_sfont_iteration_start);
|
||||
fluid_sfont_set_iteration_next(sfont, fluid_ramsfont_sfont_iteration_next);
|
||||
fluid_sfont_set_data(sfont, ramsfont);
|
||||
|
||||
|
||||
return sfont;
|
||||
}
|
||||
|
||||
|
@ -631,8 +631,8 @@ fluid_rampreset_add_sample (fluid_rampreset_t* preset, fluid_sample_t* sample,
|
|||
}
|
||||
|
||||
izone->sample = sample;
|
||||
izone->keylo = lokey;
|
||||
izone->keyhi = hikey;
|
||||
izone->range.keylo = lokey;
|
||||
izone->range.keyhi = hikey;
|
||||
|
||||
// give the preset the name of the sample
|
||||
FLUID_MEMCPY(preset->name, sample->name, 20);
|
||||
|
@ -881,7 +881,7 @@ fluid_rampreset_noteon (fluid_rampreset_t* preset, fluid_synth_t* synth, int cha
|
|||
|
||||
/* check if the note falls into the key and velocity range of this
|
||||
preset */
|
||||
if (fluid_preset_zone_inside_range(preset_zone, key, vel)) {
|
||||
if (fluid_zone_inside_range(&preset_zone->range, key, vel)) {
|
||||
|
||||
inst = fluid_preset_zone_get_inst(preset_zone);
|
||||
global_inst_zone = fluid_inst_get_global_zone(inst);
|
||||
|
@ -889,7 +889,7 @@ fluid_rampreset_noteon (fluid_rampreset_t* preset, fluid_synth_t* synth, int cha
|
|||
/* run thru all the zones of this instrument */
|
||||
inst_zone = fluid_inst_get_zone(inst);
|
||||
while (inst_zone != NULL) {
|
||||
|
||||
|
||||
/* make sure this instrument zone has a valid sample */
|
||||
sample = fluid_inst_zone_get_sample(inst_zone);
|
||||
if ((sample == NULL) || fluid_sample_in_rom(sample)) {
|
||||
|
@ -897,15 +897,14 @@ fluid_rampreset_noteon (fluid_rampreset_t* preset, fluid_synth_t* synth, int cha
|
|||
continue;
|
||||
}
|
||||
|
||||
/* check if the note falls into the key and velocity range of this
|
||||
instrument */
|
||||
/* check if the instrument zone doesn't be ignored and the note falls into
|
||||
the key and velocity range of this instrument zone.
|
||||
An instrument zone must be ignored when its voice is already running
|
||||
played by a legato passage (see fluid_synth_noteon_monopoly_legato()) */
|
||||
if (fluid_zone_inside_range(&inst_zone->range, key, vel)) {
|
||||
|
||||
if (fluid_inst_zone_inside_range(inst_zone, key, vel) && (sample != NULL)) {
|
||||
|
||||
/* this is a good zone. allocate a new synthesis process and
|
||||
initialize it */
|
||||
|
||||
voice = fluid_synth_alloc_voice(synth, sample, chan, key, vel);
|
||||
/* this is a good zone. allocate a new synthesis process and initialize it */
|
||||
voice = fluid_synth_alloc_voice_LOCAL(synth, sample, chan, key, vel, &inst_zone->range);
|
||||
if (voice == NULL) {
|
||||
return FLUID_FAILED;
|
||||
}
|
||||
|
|
|
@ -65,10 +65,27 @@ static void
|
|||
fluid_channel_init(fluid_channel_t* chan)
|
||||
{
|
||||
fluid_preset_t *newpreset;
|
||||
int prognum, banknum;
|
||||
int i, prognum, banknum;
|
||||
|
||||
chan->sostenuto_orderid = 0;
|
||||
|
||||
/*--- Init poly/mono modes variables --------------------------------------*/
|
||||
chan->mode = 0;
|
||||
chan->mode_val = 0;
|
||||
/* monophonic list initialization */
|
||||
for (i=0; i < FLUID_CHANNEL_SIZE_MONOLIST; i++)
|
||||
{
|
||||
chan->monolist[i].next = i+1;
|
||||
}
|
||||
chan->monolist[FLUID_CHANNEL_SIZE_MONOLIST -1].next = 0; /* ending element chained to the 1st */
|
||||
chan->i_last = chan->n_notes = 0; /* clears the list */
|
||||
chan->i_first = chan->monolist[chan->i_last].next; /* first note index in the list */
|
||||
fluid_channel_clear_prev_note(chan); /* Mark previous note invalid */
|
||||
/*---*/
|
||||
chan->key_mono_sustained = INVALID_NOTE; /* No previous mono note sustained */
|
||||
chan->legatomode = FLUID_CHANNEL_LEGATO_MODE_MULTI_RETRIGGER; /* Default mode */
|
||||
chan->portamentomode = FLUID_CHANNEL_PORTAMENTO_MODE_LEGATO_ONLY; /* Default mode */
|
||||
/*--- End of poly/mono initialization --------------------------------------*/
|
||||
|
||||
chan->channel_type = (chan->channum == 9) ? CHANNEL_TYPE_DRUM : CHANNEL_TYPE_MELODIC;
|
||||
prognum = 0;
|
||||
banknum = (chan->channel_type == CHANNEL_TYPE_DRUM) ? DRUM_INST_BANK : 0;
|
||||
|
@ -131,6 +148,8 @@ fluid_channel_init_ctrl(fluid_channel_t* chan, int is_all_ctrl_off)
|
|||
for (i = 0; i < 128; i++) {
|
||||
fluid_channel_set_cc (chan, i, 0);
|
||||
}
|
||||
fluid_channel_clear_portamento(chan); /* Clear PTC receive */
|
||||
chan->previous_cc_breath = 0;/* Reset previous breath */
|
||||
}
|
||||
|
||||
/* Reset polyphonic key pressure on all voices */
|
||||
|
@ -300,3 +319,309 @@ fluid_channel_get_sfont_bank_prog(fluid_channel_t* chan, int *sfont,
|
|||
if (bank) *bank = (sfont_bank_prog & BANK_MASKVAL) >> BANK_SHIFTVAL;
|
||||
if (prog) *prog = (sfont_bank_prog & PROG_MASKVAL) >> PROG_SHIFTVAL;
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates legato/ staccato playing state
|
||||
* The function is called:
|
||||
* - on noteon before adding a note into the monolist.
|
||||
* - on noteoff after removing a note out of the monolist.
|
||||
* @param chan fluid_channel_t.
|
||||
*/
|
||||
static void
|
||||
fluid_channel_update_legato_staccato_state(fluid_channel_t* chan)
|
||||
{
|
||||
/* Updates legato/ staccato playing state */
|
||||
if (chan->n_notes)
|
||||
{
|
||||
chan->mode |= FLUID_CHANNEL_LEGATO_PLAYING; /* Legato state */
|
||||
}
|
||||
else
|
||||
{
|
||||
chan->mode &= ~ FLUID_CHANNEL_LEGATO_PLAYING; /* Staccato state */
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a note into the monophonic list. The function is part of the legato
|
||||
* detector. fluid_channel_add_monolist() is intended to be called by
|
||||
* fluid_synth_noteon_mono_LOCAL().
|
||||
*
|
||||
* When a note is added at noteOn each element is use in the forward direction
|
||||
* and indexed by i_last variable.
|
||||
*
|
||||
* @param chan fluid_channel_t.
|
||||
* @param key MIDI note number (0-127).
|
||||
* @param vel MIDI velocity (0-127, 0=noteoff).
|
||||
* @param onenote. When 1 the function adds the note but the monophonic list
|
||||
* keeps only one note (used on noteOn poly).
|
||||
* Note: i_last index keeps a trace of the most recent note added.
|
||||
* prev_note keeps a trace of the note prior i_last note.
|
||||
* FLUID_CHANNEL_LEGATO_PLAYING bit keeps trace of legato/staccato playing state.
|
||||
*
|
||||
* More informations in FluidPolyMono-0004.pdf chapter 4 (Appendices).
|
||||
*/
|
||||
void
|
||||
fluid_channel_add_monolist(fluid_channel_t* chan, unsigned char key,
|
||||
unsigned char vel, unsigned char onenote)
|
||||
{
|
||||
unsigned char i_last = chan->i_last;
|
||||
/* Updates legato/ staccato playing state */
|
||||
fluid_channel_update_legato_staccato_state(chan);
|
||||
if (chan->n_notes)
|
||||
{
|
||||
/* keeps trace of the note prior last note */
|
||||
chan->prev_note = chan->monolist[i_last].note;
|
||||
}
|
||||
/* moves i_last forward before writing new note */
|
||||
i_last = chan->monolist[i_last].next;
|
||||
chan->i_last = i_last; /* now ilast indexes the last note */
|
||||
chan->monolist[i_last].note = key; /* we save note and velocity */
|
||||
chan->monolist[i_last].vel = vel;
|
||||
if (onenote)
|
||||
{ /* clears monolist before one note addition */
|
||||
chan->i_first = i_last;
|
||||
chan->n_notes = 0;
|
||||
}
|
||||
if(chan->n_notes < FLUID_CHANNEL_SIZE_MONOLIST)
|
||||
{
|
||||
chan->n_notes++; /* updates n_notes */
|
||||
}
|
||||
else
|
||||
{ /* The end of buffer is reach. So circular motion for i_first */
|
||||
/* i_first index is moved forward */
|
||||
chan->i_first = chan->monolist[i_last].next;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Searching a note in the monophonic list. The function is part of the legato
|
||||
* detector. fluid_channel_search_monolist() is intended to be called by
|
||||
* fluid_synth_noteoff_mono_LOCAL().
|
||||
*
|
||||
* The search starts from the first note in the list indexed by i_first
|
||||
|
||||
* @param chan fluid_channel_t.
|
||||
* @param key MIDI note number (0-127) to search.
|
||||
* @param i_prev pointer on returned index of the note prior the note to search.
|
||||
* @return index of the note if find, FLUID_FAILED otherwise.
|
||||
*
|
||||
*/
|
||||
int
|
||||
fluid_channel_search_monolist(fluid_channel_t* chan, unsigned char key , int * i_prev)
|
||||
{
|
||||
short n = chan->n_notes; /* number of notes in monophonic list */
|
||||
short j,i= chan->i_first; /* searching starts from i_first included */
|
||||
for (j=0 ; j < n ; j++)
|
||||
{
|
||||
if(chan->monolist[i].note == key)
|
||||
{
|
||||
if (i == chan->i_first)
|
||||
{ /* tracking index of the previous note (i_prev) */
|
||||
for (j = chan->i_last ; n < FLUID_CHANNEL_SIZE_MONOLIST; n++)
|
||||
{
|
||||
j =chan->monolist[j].next;
|
||||
}
|
||||
* i_prev = j; /* returns index of the previous note */
|
||||
}
|
||||
return i; /* returns index of the note to search */
|
||||
}
|
||||
* i_prev = i; /* tracking index of the previous note (i_prev) */
|
||||
i = chan->monolist[i].next; /* next element */
|
||||
}
|
||||
return FLUID_FAILED; /* not found */
|
||||
}
|
||||
|
||||
/**
|
||||
* removes a note from the monophonic list. The function is part of
|
||||
* the legato detector.
|
||||
* fluid_channel_remove_monolist() is intended to be called by
|
||||
* fluid_synth_noteoff_mono_LOCAL().
|
||||
*
|
||||
* When a note is removed at noteOff the element concerned is fast unlinked
|
||||
* and relinked after the i_last element.
|
||||
*
|
||||
* @param chan fluid_channel_t.
|
||||
* @param
|
||||
* i, index of the note to remove. If i is invalid or the list is
|
||||
* empty, the function do nothing and returns FLUID_FAILED.
|
||||
* @param
|
||||
* On input, i_prev is a pointer on index of the note previous i.
|
||||
* On output i_prev is a pointer on index of the note previous i if i is the last note
|
||||
* in the list,FLUID_FAILED otherwise. When the returned index is valid it means
|
||||
* a legato detection on noteoff.
|
||||
*
|
||||
* Note: the following variables in Channel keeps trace of the situation.
|
||||
* - i_last index keeps a trace of the most recent note played even if
|
||||
* the list is empty.
|
||||
* - prev_note keeps a trace of the note removed if it is i_last.
|
||||
* - FLUID_CHANNEL_LEGATO_PLAYING bit keeps a trace of legato/staccato playing state.
|
||||
*
|
||||
* More informations in FluidPolyMono-0004.pdf chapter 4 (Appendices).
|
||||
*/
|
||||
void
|
||||
fluid_channel_remove_monolist(fluid_channel_t* chan, int i, int * i_prev)
|
||||
{
|
||||
unsigned char i_last = chan->i_last;
|
||||
/* checks if index is valid */
|
||||
if( i < 0 || i >= FLUID_CHANNEL_SIZE_MONOLIST || !chan->n_notes)
|
||||
{
|
||||
* i_prev = FLUID_FAILED;
|
||||
}
|
||||
/* The element is about to be removed and inserted between i_last and next */
|
||||
/* Note: when i is egal to i_last or egal to i_first, removing/inserting
|
||||
isn't necessary */
|
||||
if (i == i_last)
|
||||
{ /* Removing/Inserting isn't necessary */
|
||||
/* keeps trace of the note prior last note */
|
||||
chan->prev_note= chan->monolist[i_last].note;
|
||||
/* moves i_last backward to the previous */
|
||||
chan->i_last = *i_prev; /* i_last index is moved backward */
|
||||
}
|
||||
else
|
||||
{ /* i is before i_last */
|
||||
if(i == chan->i_first)
|
||||
{
|
||||
/* Removing/inserting isn't necessary */
|
||||
/* i_first index is moved forward to the next element*/
|
||||
chan->i_first = chan->monolist[i].next;
|
||||
}
|
||||
else
|
||||
{ /* i is between i_first and i_last */
|
||||
/* Unlinks element i and inserts after i_last */
|
||||
chan->monolist[* i_prev].next = chan->monolist[i].next; /* unlinks i */
|
||||
/*inserts i after i_last */
|
||||
chan->monolist[i].next = chan->monolist[i_last].next;
|
||||
chan->monolist[i_last].next = i;
|
||||
}
|
||||
* i_prev = FLUID_FAILED;
|
||||
}
|
||||
chan->n_notes--; /* updates the number of note in the list */
|
||||
/* Updates legato/ staccato playing state */
|
||||
fluid_channel_update_legato_staccato_state(chan);
|
||||
}
|
||||
|
||||
/**
|
||||
* On noteOff on a polyphonic channel,the monophonic list is fully flushed.
|
||||
*
|
||||
* @param chan fluid_channel_t.
|
||||
* Note: i_last index keeps a trace of the most recent note played even if
|
||||
* the list is empty.
|
||||
* prev_note keeps a trace of the note i_last .
|
||||
* FLUID_CHANNEL_LEGATO_PLAYING bit keeps a trace of legato/staccato playing.
|
||||
*/
|
||||
void fluid_channel_clear_monolist(fluid_channel_t* chan)
|
||||
{
|
||||
/* keeps trace off the most recent note played */
|
||||
chan->prev_note= chan->monolist[chan->i_last].note;
|
||||
|
||||
/* flushes the monolist */
|
||||
chan->i_first = chan->monolist[chan->i_last].next;
|
||||
chan->n_notes = 0;
|
||||
/* Update legato/ sataccato playing state */
|
||||
chan->mode &= ~ FLUID_CHANNEL_LEGATO_PLAYING; /* Staccato state */
|
||||
}
|
||||
|
||||
/**
|
||||
* On noteOn on a polyphonic channel,adds the note into the monophonic list
|
||||
* keeping only this note.
|
||||
* @param
|
||||
* chan fluid_channel_t.
|
||||
* key, vel, note and velocity added in the monolist
|
||||
* Note: i_last index keeps a trace of the most recent note inserted.
|
||||
* prev_note keeps a trace of the note prior i_last note.
|
||||
* FLUID_CHANNEL_LEGATO_PLAYING bit keeps trace of legato/staccato playing.
|
||||
*/
|
||||
void fluid_channel_set_onenote_monolist(fluid_channel_t* chan, unsigned char key,
|
||||
unsigned char vel)
|
||||
{
|
||||
fluid_channel_add_monolist(chan, key, vel,1);
|
||||
}
|
||||
|
||||
/**
|
||||
* The function changes the state (Valid/Invalid) of the previous note played in
|
||||
* a staccato manner (fluid_channel_prev_note()).
|
||||
* When potamento mode 'each note' or 'staccato only' is selected, on next
|
||||
* noteOn a portamento will be started from the most recent note played
|
||||
* staccato.
|
||||
* It will be possible that it isn't appropriate. To give the musician the
|
||||
* possibility to choose a portamento from this note , prev_note will be forced
|
||||
* to invalid state on noteOff if portamento pedal is Off.
|
||||
*
|
||||
* The function is intended to be called when the following event occurs:
|
||||
* - On noteOff (in poly or mono mode), to mark prev_note invalid.
|
||||
* - On Portamento Off(in poly or mono mode), to mark prev_note invalid.
|
||||
* @param chan fluid_channel_t.
|
||||
*/
|
||||
void fluid_channel_invalid_prev_note_staccato(fluid_channel_t* chan)
|
||||
{
|
||||
/* checks if the playing is staccato */
|
||||
if(!(chan->mode & FLUID_CHANNEL_LEGATO_PLAYING))
|
||||
/* checks if portamento pedal is off */
|
||||
if(! fluid_channel_portamento(chan))
|
||||
{ /* forces prev_note invalid */
|
||||
fluid_channel_clear_prev_note(chan);
|
||||
}
|
||||
/* else prev_note still remains valid for next fromkey portamento */
|
||||
}
|
||||
|
||||
/**
|
||||
* The function handles poly/mono commutation on legato pedal On/Off.
|
||||
* @param chan fluid_channel_t.
|
||||
* @param value, value of the CC legato.
|
||||
*/
|
||||
void fluid_channel_cc_legato(fluid_channel_t* chan, int value)
|
||||
{
|
||||
/* Special handling of the monophonic list */
|
||||
if (!(chan->mode & FLUID_CHANNEL_POLY_OFF) && chan->n_notes) /* The monophonic list have notes */
|
||||
{
|
||||
if (value < 64 ) /* legato is released */
|
||||
{ /* returns from monophonic to polyphonic with notes in the monophonic list */
|
||||
|
||||
/* The monophonic list is flushed keeping last note only
|
||||
Note: i_last index keeps a trace of the most recent note played.
|
||||
prev_note keeps a trace of the note i_last.
|
||||
FLUID_CHANNEL_LEGATO_PLAYING bit keeps trace of legato/staccato playing.
|
||||
*/
|
||||
chan->i_first = chan->i_last;
|
||||
chan->n_notes = 1;
|
||||
}
|
||||
else /* legato is depressed */
|
||||
{ /* Inters in monophonic from polyphonic with note in monophonic list */
|
||||
/* Stops the running note to remain coherent with Breath Sync mode */
|
||||
if ((chan->mode & FLUID_CHANNEL_BREATH_SYNC) && !fluid_channel_breath_msb(chan))
|
||||
{
|
||||
fluid_synth_noteoff_monopoly(chan->synth,chan->channum,
|
||||
fluid_channel_last_note(chan),1);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* The function handles CC Breath On/Off detection. When a channel is in
|
||||
* Breath Sync mode and in monophonic playing, the breath controller allows
|
||||
* to trigger noteon/noteoff note when the musician starts to breath (noteon) and
|
||||
* stops to breath (noteoff).
|
||||
* @param chan fluid_channel_t.
|
||||
* @param value, value of the CC Breath..
|
||||
*/
|
||||
void fluid_channel_cc_breath_note_on_off(fluid_channel_t* chan, int value)
|
||||
{
|
||||
if ((chan->mode & FLUID_CHANNEL_BREATH_SYNC) && fluid_channel_is_playing_mono(chan) &&
|
||||
(chan->n_notes))
|
||||
{
|
||||
/* The monophonic list isn't empty */
|
||||
if((value > 0) && (chan->previous_cc_breath == 0))
|
||||
{ /* CC Breath On detection */
|
||||
fluid_synth_noteon_mono_staccato(chan->synth,chan->channum,
|
||||
fluid_channel_last_note(chan),
|
||||
fluid_channel_last_vel(chan));
|
||||
}
|
||||
else if( (value == 0) && (chan->previous_cc_breath > 0))
|
||||
{ /* CC Breath Off detection */
|
||||
fluid_synth_noteoff_monopoly(chan->synth, chan->channum,
|
||||
fluid_channel_last_note(chan), 1);
|
||||
}
|
||||
}
|
||||
chan->previous_cc_breath = value;
|
||||
}
|
||||
|
|
|
@ -25,6 +25,50 @@
|
|||
#include "fluid_midi.h"
|
||||
#include "fluid_tuning.h"
|
||||
|
||||
/* The mononophonic list is part of the legato detector for monophonic mode */
|
||||
/* see fluid_synth_monopoly.c about a description of the legato detector device */
|
||||
/* Size of the monophonic list
|
||||
- 1 is the minimum. it allows playing legato passage of any number
|
||||
of notes on noteon only.
|
||||
- Size above 1 allows playing legato on noteon but also on noteOff.
|
||||
This allows the musician to play fast trills.
|
||||
This feature is particularly usful when the MIDI input device is a keyboard.
|
||||
Choosing a size of 10 is sufficient (because most musicians have only 10
|
||||
fingers when playing a monophonic instrument).
|
||||
*/
|
||||
#define FLUID_CHANNEL_SIZE_MONOLIST 10
|
||||
|
||||
/*
|
||||
|
||||
The monophonic list
|
||||
+------------------------------------------------+
|
||||
| +----+ +----+ +----+ +----+ |
|
||||
| |note| |note| |note| |note| |
|
||||
+--->|vel |-->|vel |-->....-->|vel |-->|vel |----+
|
||||
+----+ +----+ +----+ +----+
|
||||
/|\ /|\
|
||||
| |
|
||||
i_first i_last
|
||||
|
||||
The monophonic list is a circular buffer of FLUID_CHANNEL_SIZE_MONOLIST elements.
|
||||
Each element is linked forward at initialisation time.
|
||||
- when a note is added at noteOn (see fluid_channel_add_monolist()) each
|
||||
element is use in the forward direction and indexed by i_last variable.
|
||||
- when a note is removed at noteOff (see fluid_channel_remove_monolist()),
|
||||
the element concerned is fast unlinked and relinked after the i_last element.
|
||||
|
||||
The most recent note added is indexed by i_last.
|
||||
The most ancient note added is the first note indexed by i_first. i_first is
|
||||
moving in the forward direction in a circular manner.
|
||||
|
||||
*/
|
||||
struct mononote
|
||||
{
|
||||
unsigned char next; /* next note */
|
||||
unsigned char note; /* note */
|
||||
unsigned char vel; /* velocity */
|
||||
};
|
||||
|
||||
/*
|
||||
* fluid_channel_t
|
||||
*
|
||||
|
@ -35,7 +79,23 @@ struct _fluid_channel_t
|
|||
{
|
||||
fluid_synth_t* synth; /**< Parent synthesizer instance */
|
||||
int channum; /**< MIDI channel number */
|
||||
|
||||
|
||||
/* Poly Mono variables see macro access description */
|
||||
int mode; /**< Poly Mono mode */
|
||||
int mode_val; /**< number of channel in basic channel group */
|
||||
/* monophonic list - legato detector */
|
||||
struct mononote monolist[FLUID_CHANNEL_SIZE_MONOLIST]; /**< monophonic list */
|
||||
unsigned char i_first; /**< First note index */
|
||||
unsigned char i_last; /**< most recent note index since the most recent add */
|
||||
unsigned char prev_note; /**< previous note of the most recent add/remove */
|
||||
unsigned char n_notes; /**< actual number of notes in the list */
|
||||
/*--*/
|
||||
int key_mono_sustained; /**< previous sustained monophonic note */
|
||||
enum fluid_channel_legato_mode legatomode; /**< legato mode */
|
||||
enum fluid_channel_portamento_mode portamentomode; /**< portamento mode */
|
||||
int previous_cc_breath; /**< Previous Breath */
|
||||
/*- End of Poly/mono variables description */
|
||||
|
||||
int sfont_bank_prog; /**< SoundFont ID (bit 21-31), bank (bit 7-20), program (bit 0-6) */
|
||||
fluid_preset_t* preset; /**< Selected preset */
|
||||
|
||||
|
@ -136,6 +196,12 @@ int fluid_channel_get_interp_method(fluid_channel_t* chan);
|
|||
((chan)->tuning_prog)
|
||||
#define fluid_channel_set_tuning_prog(chan, prog) \
|
||||
((chan)->tuning_prog = (prog))
|
||||
#define fluid_channel_portamentotime(_c) \
|
||||
((_c)->cc[PORTAMENTO_TIME_MSB] * 128 + (_c)->cc[PORTAMENTO_TIME_LSB])
|
||||
#define fluid_channel_portamento(_c) ((_c)->cc[PORTAMENTO_SWITCH] >= 64)
|
||||
#define fluid_channel_breath_msb(_c) ((_c)->cc[BREATH_MSB] > 0)
|
||||
#define fluid_channel_clear_portamento(_c) ((_c)->cc[PORTAMENTO_CTRL] = INVALID_NOTE)
|
||||
#define fluid_channel_legato(_c) ((_c)->cc[LEGATO_SWITCH] >= 64)
|
||||
#define fluid_channel_sustained(_c) ((_c)->cc[SUSTAIN_SWITCH] >= 64)
|
||||
#define fluid_channel_sostenuto(_c) ((_c)->cc[SOSTENUTO_SWITCH] >= 64)
|
||||
#define fluid_channel_set_gen(_c, _n, _v, _a) { (_c)->gen[_n] = _v; (_c)->gen_abs[_n] = _a; }
|
||||
|
@ -144,4 +210,83 @@ int fluid_channel_get_interp_method(fluid_channel_t* chan);
|
|||
#define fluid_channel_get_min_note_length_ticks(chan) \
|
||||
((chan)->synth->min_note_length_ticks)
|
||||
|
||||
/* Macros interface to poly/mono mode variables */
|
||||
#define MASK_BASICCHANINFOS (FLUID_CHANNEL_MODE_MASK|FLUID_CHANNEL_BASIC|FLUID_CHANNEL_ENABLED)
|
||||
/* Set the basic channel infos for a MIDI basic channel */
|
||||
#define fluid_channel_set_basic_channel_info(chan,Infos) \
|
||||
(chan->mode = (chan->mode & ~MASK_BASICCHANINFOS) | (Infos & MASK_BASICCHANINFOS))
|
||||
/* Reset the basic channel infos for a MIDI basic channel */
|
||||
#define fluid_channel_reset_basic_channel_info(chan) (chan->mode &= ~MASK_BASICCHANINFOS)
|
||||
|
||||
/* Macros interface to breath variables */
|
||||
#define FLUID_CHANNEL_BREATH_MASK (FLUID_CHANNEL_BREATH_POLY|FLUID_CHANNEL_BREATH_MONO|FLUID_CHANNEL_BREATH_SYNC)
|
||||
/* Set the breath infos for a MIDI channel */
|
||||
#define fluid_channel_set_breath_info(chan,BreathInfos) \
|
||||
(chan->mode = (chan->mode & ~FLUID_CHANNEL_BREATH_MASK) | (BreathInfos & FLUID_CHANNEL_BREATH_MASK))
|
||||
/* Get the breath infos for a MIDI channel */
|
||||
#define fluid_channel_get_breath_info(chan) (chan->mode & FLUID_CHANNEL_BREATH_MASK)
|
||||
|
||||
/* Returns true when channel is mono or legato is on */
|
||||
#define fluid_channel_is_playing_mono(chan) ((chan->mode & FLUID_CHANNEL_POLY_OFF) ||\
|
||||
fluid_channel_legato(chan))
|
||||
|
||||
/* Macros interface to monophonic list variables */
|
||||
#define INVALID_NOTE 255
|
||||
/* Returns true when a note is a valid note */
|
||||
#define fluid_channel_is_valid_note(n) (n != INVALID_NOTE)
|
||||
/* Marks prev_note as invalid. */
|
||||
#define fluid_channel_clear_prev_note(chan) (chan->prev_note = INVALID_NOTE)
|
||||
|
||||
/* Returns the most recent note from i_last entry of the monophonic list */
|
||||
#define fluid_channel_last_note(chan) (chan->monolist[chan->i_last].note)
|
||||
|
||||
/* Returns the most recent velocity from i_last entry of the monophonic list */
|
||||
#define fluid_channel_last_vel(chan) (chan->monolist[chan->i_last].vel)
|
||||
|
||||
/*
|
||||
prev_note is used to determine fromkey_portamento as well as
|
||||
fromkey_legato (see fluid_synth_get_fromkey_portamento_legato()).
|
||||
|
||||
prev_note is updated on noteOn/noteOff mono by the legato detector as this:
|
||||
- On noteOn mono, before adding a new note into the monolist,the most
|
||||
recent note in the list (i.e at i_last position) is kept in prev_note.
|
||||
- Similarly, on noteOff mono , before removing a note out of the monolist,
|
||||
the most recent note (i.e those at i_last position) is kept in prev_note.
|
||||
*/
|
||||
#define fluid_channel_prev_note(chan) (chan->prev_note)
|
||||
|
||||
/* Interface to poly/mono mode variables */
|
||||
enum fluid_channel_mode_flags_internal
|
||||
{
|
||||
FLUID_CHANNEL_BASIC = 0x04, /**< if flag set the corresponding midi channel is a basic channel */
|
||||
FLUID_CHANNEL_ENABLED = 0x08, /**< if flag set the corresponding midi channel is enabled, else disabled, i.e. channel ignores any MIDI messages */
|
||||
|
||||
/*
|
||||
FLUID_CHANNEL_LEGATO_PLAYING bit of channel mode keeps trace of the legato /staccato
|
||||
state playing.
|
||||
FLUID_CHANNEL_LEGATO_PLAYING bit is updated on noteOn/noteOff mono by the legato detector:
|
||||
- On noteOn, before inserting a new note into the monolist.
|
||||
- On noteOff, after removing a note out of the monolist.
|
||||
|
||||
- On noteOn, this state is used by fluid_synth_noteon_mono_LOCAL()
|
||||
to play the current note legato or staccato.
|
||||
- On noteOff, this state is used by fluid_synth_noteoff_mono_LOCAL()
|
||||
to play the current noteOff legato with the most recent note.
|
||||
*/
|
||||
/* bit7, 1: means legato playing , 0: means staccato playing */
|
||||
FLUID_CHANNEL_LEGATO_PLAYING = 0x80
|
||||
};
|
||||
|
||||
/* End of interface to monophonic list variables */
|
||||
|
||||
void fluid_channel_add_monolist(fluid_channel_t* chan, unsigned char key, unsigned char vel, unsigned char onenote);
|
||||
int fluid_channel_search_monolist(fluid_channel_t* chan, unsigned char key , int * i_prev);
|
||||
void fluid_channel_remove_monolist(fluid_channel_t* chan, int i, int * i_prev);
|
||||
void fluid_channel_clear_monolist(fluid_channel_t* chan);
|
||||
void fluid_channel_set_onenote_monolist(fluid_channel_t* chan, unsigned char key, unsigned char vel);
|
||||
void fluid_channel_invalid_prev_note_staccato(fluid_channel_t* chan);
|
||||
void fluid_channel_cc_legato(fluid_channel_t* chan, int value);
|
||||
void fluid_channel_cc_breath_note_on_off(fluid_channel_t* chan, int value);
|
||||
|
||||
|
||||
#endif /* _FLUID_CHAN_H */
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -46,7 +46,6 @@
|
|||
|
||||
#define FLUID_UNSET_PROGRAM 128 /* Program number used to unset a preset */
|
||||
|
||||
|
||||
/***************************************************************
|
||||
*
|
||||
* ENUM
|
||||
|
@ -136,6 +135,7 @@ struct _fluid_synth_t
|
|||
int active_voice_count; /**< count of active voices */
|
||||
unsigned int noteid; /**< the id is incremented for every new note. it's used for noteoff's */
|
||||
unsigned int storeid;
|
||||
int fromkey_portamento; /**< fromkey portamento */
|
||||
fluid_rvoice_eventhandler_t* eventhandler;
|
||||
|
||||
double reverb_roomsize; /**< Shadow of reverb roomsize */
|
||||
|
@ -174,13 +174,6 @@ fluid_preset_t* fluid_synth_find_preset(fluid_synth_t* synth,
|
|||
unsigned int banknum,
|
||||
unsigned int prognum);
|
||||
void fluid_synth_sfont_unref (fluid_synth_t *synth, fluid_sfont_t *sfont);
|
||||
|
||||
|
||||
int fluid_synth_all_notes_off(fluid_synth_t* synth, int chan);
|
||||
int fluid_synth_all_sounds_off(fluid_synth_t* synth, int chan);
|
||||
int fluid_synth_kill_voice(fluid_synth_t* synth, fluid_voice_t * voice);
|
||||
|
||||
void fluid_synth_print_voice(fluid_synth_t* synth);
|
||||
|
||||
void fluid_synth_dither_s16(int *dither_index, int len, float* lin, float* rin,
|
||||
void* lout, int loff, int lincr,
|
||||
|
@ -198,8 +191,6 @@ int fluid_synth_set_chorus_full(fluid_synth_t* synth, int set, int nr, double le
|
|||
fluid_sample_timer_t* new_fluid_sample_timer(fluid_synth_t* synth, fluid_timer_callback_t callback, void* data);
|
||||
void delete_fluid_sample_timer(fluid_synth_t* synth, fluid_sample_timer_t* timer);
|
||||
|
||||
void fluid_synth_api_enter(fluid_synth_t* synth);
|
||||
void fluid_synth_api_exit(fluid_synth_t* synth);
|
||||
|
||||
void fluid_synth_process_event_queue(fluid_synth_t* synth);
|
||||
|
||||
|
@ -209,7 +200,19 @@ int fluid_synth_set_gen2 (fluid_synth_t* synth, int chan,
|
|||
/*
|
||||
* misc
|
||||
*/
|
||||
|
||||
void fluid_synth_settings(fluid_settings_t* settings);
|
||||
|
||||
|
||||
/* extern declared in fluid_synth_monopoly.c */
|
||||
|
||||
int fluid_synth_noteon_mono_staccato(fluid_synth_t* synth,int chan,int key,int vel);
|
||||
int fluid_synth_noteon_mono_LOCAL(fluid_synth_t* synth, int chan, int key, int vel);
|
||||
int fluid_synth_noteoff_mono_LOCAL(fluid_synth_t* synth, int chan, int key);
|
||||
int fluid_synth_noteon_monopoly_legato(fluid_synth_t* synth, int chan, int fromkey, int tokey, int vel);
|
||||
int fluid_synth_noteoff_monopoly(fluid_synth_t* synth, int chan, int key, char Mono);
|
||||
|
||||
fluid_voice_t*
|
||||
fluid_synth_alloc_voice_LOCAL(fluid_synth_t* synth, fluid_sample_t* sample, int chan, int key, int vel, fluid_zone_range_t* zone_range);
|
||||
|
||||
void fluid_synth_release_voice_on_same_note_LOCAL(fluid_synth_t* synth, int chan, int key);
|
||||
#endif /* _FLUID_SYNTH_H */
|
||||
|
|
685
src/synth/fluid_synth_monopoly.c
Normal file
685
src/synth/fluid_synth_monopoly.c
Normal file
|
@ -0,0 +1,685 @@
|
|||
/* FluidSynth - A Software Synthesizer
|
||||
*
|
||||
* Copyright (C) 2003 Peter Hanappe and others.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Library General Public License
|
||||
* as published by the Free Software Foundation; either version 2 of
|
||||
* the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Library General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Library General Public
|
||||
* License along with this library; if not, write to the Free
|
||||
* Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
||||
* 02110-1301, USA
|
||||
*/
|
||||
|
||||
#include "fluid_synth.h"
|
||||
#include "fluid_chan.h"
|
||||
#include "fluid_defsfont.h"
|
||||
|
||||
|
||||
/******************************************************************************
|
||||
The legato detector is composed as this,
|
||||
variables:
|
||||
- monolist: monophonic list variable.
|
||||
- prev_note: to store the most recent note before adding on noteon or before
|
||||
removing on noteoff.
|
||||
- FLUID_CHANNEL_LEGATO_PLAYING: legato/staccato state bit that informs on
|
||||
legato or staccato playing.
|
||||
functions:
|
||||
- fluid_channel_add_monolist(), for inserting a new note.
|
||||
- fluid_channel_search_monolist(), for searching the position of a note
|
||||
into the list.
|
||||
- fluid_channel_remove_monolist(), for removing a note from the list.
|
||||
|
||||
The monophonic list
|
||||
+------------------------------------------------+
|
||||
| +----+ +----+ +----+ +----+ |
|
||||
| |note| |note| |note| |note| |
|
||||
+--->|vel |-->|vel |-->....-->|vel |-->|vel |----+
|
||||
+----+ +----+ +----+ +----+
|
||||
/|\ /|\
|
||||
| |
|
||||
i_first i_last
|
||||
|
||||
The list allows an easy automatic detection of a legato passage when it is
|
||||
played on a MIDI keyboard input device.
|
||||
It is useful also when the input device is an ewi (electronic wind instrument)
|
||||
or evi (electronic valve instrument) and these instruments are unable to send
|
||||
MIDI CC legato on/off.
|
||||
|
||||
The list memorizes the notes in playing order.
|
||||
- (a) On noteOn n2, if a previous note n1 exists, there is a legato
|
||||
detection with n1 (with or without portamento from n1 to n2 See note below).
|
||||
- (b) On noteOff of the running note n2, if a previous note n1 exists,
|
||||
there is a legato detection from n2 to n1, allowing fast trills playing
|
||||
(with or without portamento from n2 to n1. See note below).
|
||||
|
||||
Notes in the list are inserted to the end of the list that works like a
|
||||
circular buffer.The features are:
|
||||
|
||||
1) It is always possible to play an infinite legato passage in
|
||||
direct order (n1_On,n2_On,n3_On,....).
|
||||
|
||||
2) Playing legato in the reverse order (n10_Off, n9_Off,,...) helps in
|
||||
fast trills playing as the list memorizes 10 most recent notes.
|
||||
|
||||
3) Playing an infinite lagato passage in ascendant or descendant order,
|
||||
without playing trills is always possible using the usual way like this:
|
||||
First we begin with an ascendant passage,
|
||||
n1On, (n2On,n1Off), (n3On,n2Off) , (n4On,n3Off), then
|
||||
we continue with a descendant passage
|
||||
(n3On,n4off), (n2On,n3off), (n1On,n2off), n1Off...and so on
|
||||
|
||||
Each MIDI channel have a legato detector.
|
||||
|
||||
Note:
|
||||
Portamento is a feature independant of the legato detector. So
|
||||
portamento isn't part of the lagato detector. However portamento
|
||||
(when enabled) is triggered at noteOn (like legato). Like in legato
|
||||
situation it is usual to have a portamento from a note 'fromkey' to another
|
||||
note 'tokey'. Portamento fromkey note choice is determined at noteOn by
|
||||
fluid_synth_get_fromkey_portamento_legato() (see below).
|
||||
|
||||
More informations in FluidPolyMono-0004.pdf chapter 4 (Appendices).
|
||||
******************************************************************************/
|
||||
|
||||
|
||||
/*****************************************************************************
|
||||
Portamento related functions in Poly or Mono mode
|
||||
******************************************************************************/
|
||||
|
||||
/**
|
||||
* fluid_synth_get_fromkey_portamento_legato returns two informations:
|
||||
* - fromkey note for portamento.
|
||||
* - fromkey note for legato.
|
||||
* +-----> fromkey_portamento
|
||||
* ______|________
|
||||
* portamento modes >------->| |
|
||||
* | get_fromkey |
|
||||
* Porta.on/off >------------------------->|_______________|
|
||||
* (PTC) |
|
||||
* +-----> fromkey_legato
|
||||
*
|
||||
* The functions is intended to be call on noteOn mono
|
||||
* see fluid_synth_noteon_mono_staccato(), fluid_synth_noteon_monopoly_legato()
|
||||
* -------
|
||||
* 1)The function determines if a portamento must occur on next noteOn.
|
||||
* The value returned is 'fromkey portamento' which is the pitchstart key
|
||||
* of a portamento, as function of PTC or (default_fromkey, prev_note) both
|
||||
* if Portamento On. By order of precedence the result is:
|
||||
* 1.1) PTC have precedence over Portamento On.
|
||||
* If CC PTC has been received, its value supersedes and any
|
||||
* portamento pedal On, default_fromkey,prev_note or portamento mode.
|
||||
* 1.2) Otherwise ,when Portamento On the function takes the following value:
|
||||
* - default_fromkey if valid
|
||||
* - otherwise prev_note(prev_note is the note prior the most recent
|
||||
* note played).
|
||||
* Then portamento mode is applied to validate the value choosen.
|
||||
* Where portamento mode is:
|
||||
* - each note, a portamento occurs on each note.
|
||||
* - legato only, portamento only on notes played legato.
|
||||
* - staccato only, portamento only on notes played staccato.
|
||||
* 1.3) Otherwise, portamento is off,INVALID_NOTE is returned (portamento is disabled).
|
||||
* ------
|
||||
* 2)The function determines if a legato playing must occur on next noteOn.
|
||||
* 'fromkey legato note' is returned as a function of default_fromkey, PTC,
|
||||
* current mono/poly mode,actual 'staccato/legato' playing state and prev_note.
|
||||
* By order of precedence the result is:
|
||||
* 2.1) If valid, default_fromkey have precedence over any others values.
|
||||
* 2.2) Otherwise if CC PTC has been received its value is returned.
|
||||
* 2.3) Otherwise fromkey legato is determined from the mono/poly mode,
|
||||
* the actual 'staccato/legato' playing state (FLUID_CHANNEL_LEGATO_PLAYING) and prev_note
|
||||
* as this:
|
||||
* - in (poly/Mono) staccato , INVALID_NOTE is returned.
|
||||
* - in poly legato , actually we don't want playing legato. So
|
||||
* INVALID_NOTE is returned.
|
||||
* - in mono legato , prev_note is returned.
|
||||
*
|
||||
* On input
|
||||
* @param chan fluid_channel_t.
|
||||
* @param defaultFromkey, the defaut 'fromkey portamento' note or 'fromkey legato'
|
||||
* note (see description above).
|
||||
*
|
||||
* @return
|
||||
* 1)'fromkey portamento' is returned in fluid_synth_t.fromkey_portamento.
|
||||
* If valid,it means that portamento is enabled .
|
||||
*
|
||||
* 2)The 'fromkey legato' note is returned.
|
||||
*
|
||||
* Notes about usage:
|
||||
* The function is intended to be called when the following event occurs:
|
||||
* - On noteOn (Poly or Mono) after insertion in the monophonic list.
|
||||
* - On noteOff(mono legato playing). In this case, default_fromkey must be valid.
|
||||
*
|
||||
* Typical calling usage:
|
||||
* - In poly, default_fromkey must be INVALID_NOTE.
|
||||
* - In mono staccato playing,default_fromkey must be INVALID_NOTE.
|
||||
* - In mono legato playing,default_fromkey must be valid.
|
||||
*/
|
||||
static unsigned char fluid_synth_get_fromkey_portamento_legato(fluid_channel_t* chan,
|
||||
unsigned char default_fromkey)
|
||||
{
|
||||
unsigned char ptc = fluid_channel_get_cc(chan, PORTAMENTO_CTRL);
|
||||
if(fluid_channel_is_valid_note(ptc))
|
||||
{ /* CC PTC has been received */
|
||||
fluid_channel_clear_portamento(chan); /* clears the CC PTC receive */
|
||||
chan->synth->fromkey_portamento = ptc;/* returns fromkey portamento */
|
||||
/* returns fromkey legato */
|
||||
if(!fluid_channel_is_valid_note(default_fromkey))
|
||||
{
|
||||
default_fromkey= ptc;
|
||||
}
|
||||
}
|
||||
else
|
||||
{ /* determines and returns fromkey portamento */
|
||||
unsigned char fromkey_portamento = INVALID_NOTE;
|
||||
if(fluid_channel_portamento(chan))
|
||||
{ /* Portamento when Portamento pedal is On */
|
||||
/* 'fromkey portamento'is determined from the portamento mode
|
||||
and the most recent note played (prev_note)*/
|
||||
unsigned char portamentomode = chan->portamentomode;
|
||||
if(fluid_channel_is_valid_note(default_fromkey))
|
||||
{
|
||||
fromkey_portamento = default_fromkey; /* on each note */
|
||||
}
|
||||
else
|
||||
{
|
||||
fromkey_portamento = fluid_channel_prev_note(chan); /* on each note */
|
||||
}
|
||||
if(portamentomode == FLUID_CHANNEL_PORTAMENTO_MODE_LEGATO_ONLY)
|
||||
{ /* Mode portamento:legato only */
|
||||
if(!(chan->mode & FLUID_CHANNEL_LEGATO_PLAYING))
|
||||
{
|
||||
fromkey_portamento = INVALID_NOTE;
|
||||
}
|
||||
}
|
||||
else if(portamentomode == FLUID_CHANNEL_PORTAMENTO_MODE_STACCATO_ONLY)
|
||||
{ /* Mode portamento:staccato only */
|
||||
if(chan->mode & FLUID_CHANNEL_LEGATO_PLAYING)
|
||||
{
|
||||
fromkey_portamento = INVALID_NOTE;
|
||||
}
|
||||
}
|
||||
/* else Mode portamento: on each note (staccato/legato) */
|
||||
}
|
||||
/* Returns fromkey portamento */
|
||||
chan->synth->fromkey_portamento = fromkey_portamento;
|
||||
/* Determines and returns fromkey legato */
|
||||
if(!fluid_channel_is_valid_note(default_fromkey))
|
||||
{
|
||||
/* in staccato (poly/Mono) returns INVALID_NOTE */
|
||||
/* In mono mode legato playing returns the note prior most
|
||||
recent note played */
|
||||
if (fluid_channel_is_playing_mono(chan) && (chan->mode & FLUID_CHANNEL_LEGATO_PLAYING))
|
||||
{
|
||||
default_fromkey = fluid_channel_prev_note(chan); /* note prior last note */
|
||||
}
|
||||
/* In poly mode legato playing, actually we don't want playing legato.
|
||||
So returns INVALID_NOTE */
|
||||
}
|
||||
}
|
||||
return default_fromkey; /* Returns legato fromkey */
|
||||
}
|
||||
|
||||
/*****************************************************************************
|
||||
noteon - noteoff functions in Mono mode
|
||||
******************************************************************************/
|
||||
/*
|
||||
* noteon - noteoff on a channel in "monophonic playing".
|
||||
*
|
||||
* A channel needs to be played monophonic if this channel has been set in
|
||||
* monophonic mode by basic channel API.(see fluid_synth_polymono.c).
|
||||
* A channel needs also to be played monophonic if it has been set in
|
||||
* polyphonic mode and legato pedal is On during the playing.
|
||||
* When a channel is in "monophonic playing" state, only one note at a time can be
|
||||
* played in a staccato or legato manner (with or without portamento).
|
||||
* More informations in FluidPolyMono-0004.pdf chapter 4 (Appendices).
|
||||
* _______________
|
||||
* ________________ | noteon |
|
||||
* | legato detector| O-->| mono_staccato |--*-> preset_noteon
|
||||
* noteon_mono ->| (add_monolist) |--O-- |_______________| | (with or without)
|
||||
* LOCAL |________________| O /|\ | (portamento)
|
||||
* /|\ set_onenote | | fromkey |
|
||||
* | | | portamento|
|
||||
* noteOn poly >---*------------------* | |
|
||||
* | | |
|
||||
* | _____ |________ |
|
||||
* portamento modes >--- | ->| | |
|
||||
* | | get_fromkey | |
|
||||
* Porta.on/off >--------------------- | ->|_______________| |
|
||||
* (PTC) | | |
|
||||
* | fromkey | fromkey |
|
||||
* | legato | portamento|
|
||||
* | _____\|/_______ |
|
||||
* *-->| noteon |--/
|
||||
* | | monopoly |
|
||||
* | | legato |----> voices
|
||||
* legato modes >------- | ->|_______________| triggering
|
||||
* | (with or without)
|
||||
* | (portamento)
|
||||
* |
|
||||
* |
|
||||
* noteOff poly >---*----------------- | ---------+
|
||||
* | clear | |
|
||||
* _\|/_____________ | |
|
||||
* | legato detector | O |
|
||||
* noteoff_mono->|(search_monolist)|-O-- _____\|/_______
|
||||
* LOCAL |(remove_monolist)| O-->| noteoff |
|
||||
* |_________________| | monopoly |----> noteoff
|
||||
* Sust.on/off >------------------------->|_______________|
|
||||
* Sost.on/off
|
||||
------------------------------------------------------------------------------*/
|
||||
int fluid_synth_noteoff_monopoly(fluid_synth_t* synth, int chan, int key,
|
||||
char Mono);
|
||||
|
||||
int fluid_synth_noteon_monopoly_legato(fluid_synth_t* synth, int chan,
|
||||
int fromkey, int tokey, int vel);
|
||||
|
||||
/**
|
||||
* Plays a noteon event for a Synth instance in "monophonic playing" state.
|
||||
* Please see the description above about "monophonic playing".
|
||||
* _______________
|
||||
* ________________ | noteon |
|
||||
* | legato detector| O-->| mono_staccato |--->preset_noteon
|
||||
* noteon_mono ->| (add_monolist) |--O-- |_______________|
|
||||
* LOCAL |________________| O
|
||||
* |
|
||||
* |
|
||||
* |
|
||||
* |
|
||||
* |
|
||||
* |
|
||||
* |
|
||||
* |
|
||||
* |
|
||||
* | _______________
|
||||
* | | noteon |
|
||||
* +-->| monopoly |
|
||||
* | legato |---> voices
|
||||
* |_______________| triggering
|
||||
*
|
||||
* The function uses the legato detector (see above) to determine if the note must
|
||||
* be played staccato or legato.
|
||||
*
|
||||
* @param synth instance.
|
||||
* @param chan MIDI channel number (0 to MIDI channel count - 1).
|
||||
* @param key MIDI note number (0-127).
|
||||
* @param vel MIDI velocity (0-127).
|
||||
* @return FLUID_OK on success, FLUID_FAILED otherwise.
|
||||
*/
|
||||
int fluid_synth_noteon_mono_LOCAL(fluid_synth_t* synth, int chan,
|
||||
int key, int vel)
|
||||
{
|
||||
fluid_channel_t* channel = synth->channel[chan];
|
||||
|
||||
/* Adds the note into the monophonic list */
|
||||
fluid_channel_add_monolist(channel,(unsigned char)key,(unsigned char)vel,0);
|
||||
|
||||
/* in Breath Sync mode, the noteon triggering is postponed
|
||||
until the musician starts blowing in the breath controller */
|
||||
if (!(channel->mode & FLUID_CHANNEL_BREATH_SYNC) ||
|
||||
fluid_channel_breath_msb(channel) )
|
||||
{
|
||||
/* legato/staccato playing detection */
|
||||
if(channel->mode & FLUID_CHANNEL_LEGATO_PLAYING)
|
||||
{ /* legato playing */
|
||||
/* legato from prev_note to key */
|
||||
/* the voices from prev_note key number are to be used to play key number */
|
||||
/* fromkey must be valid */
|
||||
return fluid_synth_noteon_monopoly_legato(synth, chan,
|
||||
fluid_channel_prev_note(channel), key, vel);
|
||||
}
|
||||
else
|
||||
{ /* staccato playing */
|
||||
return fluid_synth_noteon_mono_staccato(synth, chan, key, vel);
|
||||
}
|
||||
}
|
||||
else return FLUID_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* Plays a noteoff event for a Synth instance in "monophonic playing" state.
|
||||
* Please see the description above about "monophonic playing"
|
||||
*
|
||||
* _______________
|
||||
* | noteon |
|
||||
* +-->| monopoly |
|
||||
* | | legato |----> voices
|
||||
* | |_______________| triggering
|
||||
* | (with or without)
|
||||
* | (portamento)
|
||||
* |
|
||||
* |
|
||||
* |
|
||||
* |
|
||||
* |
|
||||
* |
|
||||
* _________________ |
|
||||
* | legato detector | O
|
||||
* noteoff_mono->|(search_monolist)|-O-- _______________
|
||||
* LOCAL |(remove_monolist)| O-->| noteoff |
|
||||
* |_________________| | monopoly |----> noteoff
|
||||
* |_______________|
|
||||
*
|
||||
* The function uses the legato detector (see above) to determine if the noteoff must
|
||||
* be played staccato or legato.
|
||||
*
|
||||
* @param synth instance.
|
||||
* @param chan MIDI channel number (0 to MIDI channel count - 1).
|
||||
* @param key MIDI note number (0-127).
|
||||
* @return FLUID_OK on success, FLUID_FAILED otherwise.
|
||||
*/
|
||||
int fluid_synth_noteoff_mono_LOCAL(fluid_synth_t* synth, int chan, int key)
|
||||
{
|
||||
int status;
|
||||
int i,i_prev;
|
||||
fluid_channel_t* channel = synth->channel[chan];
|
||||
/* searching the note in the monophonic list */
|
||||
i=fluid_channel_search_monolist(channel, (unsigned char)key , &i_prev);
|
||||
|
||||
if (i >= 0)
|
||||
{ /* the note is in the monophonic list */
|
||||
/* Removes the note from the monophonic list */
|
||||
fluid_channel_remove_monolist(channel,i , &i_prev);
|
||||
|
||||
/* in Breath Sync mode, the noteoff triggering is done
|
||||
if the musician is blowing in the breath controller */
|
||||
if (!(channel->mode & FLUID_CHANNEL_BREATH_SYNC) ||
|
||||
fluid_channel_breath_msb(channel) )
|
||||
{
|
||||
/* legato playing detection */
|
||||
if(channel->mode & FLUID_CHANNEL_LEGATO_PLAYING)
|
||||
{ /* the list contains others notes */
|
||||
if(i_prev >= 0)
|
||||
{ /* legato playing detection on noteoff */
|
||||
/* legato from key to i_prev key */
|
||||
/* the voices from key number are to be used to
|
||||
play i_prev key number. */
|
||||
status = fluid_synth_noteon_monopoly_legato(synth, chan,
|
||||
key, channel->monolist[i_prev].note,
|
||||
channel->monolist[i_prev].vel);
|
||||
}
|
||||
/* else the note doesn't need to be played off */
|
||||
else
|
||||
{
|
||||
status = FLUID_OK;
|
||||
}
|
||||
}
|
||||
else
|
||||
{ /* the monophonic list is empty */
|
||||
/* plays the monophonic note noteoff and eventually held
|
||||
by sustain/sostenuto */
|
||||
status = fluid_synth_noteoff_monopoly(synth, chan, key, 1);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
status = FLUID_OK;
|
||||
}
|
||||
}
|
||||
else
|
||||
{ /* the note is not found in the list so the note was
|
||||
played On when the channel was in polyphonic playing */
|
||||
/* plays the noteoff as for polyphonic */
|
||||
status = fluid_synth_noteoff_monopoly(synth, chan, key, 0);
|
||||
}
|
||||
return status;
|
||||
}
|
||||
|
||||
/*----------------------------------------------------------------------------
|
||||
staccato playing
|
||||
-----------------------------------------------------------------------------*/
|
||||
/**
|
||||
* Plays noteon for a monophonic note in staccato manner.
|
||||
* Please see the description above about "monophonic playing".
|
||||
* _______________
|
||||
* | noteon |
|
||||
* noteon_mono >------------------------>| mono_staccato |----> preset_noteon
|
||||
* |_______________| (with or without)
|
||||
* LOCAL /|\ (portamento)
|
||||
* | fromkey
|
||||
* | portamento
|
||||
* |
|
||||
* |
|
||||
* ______|________
|
||||
* portamento modes >----->| |
|
||||
* | get_fromkey |
|
||||
* Porta.on/off >----------------------->|_______________|
|
||||
* Portamento
|
||||
* (PTC)
|
||||
*
|
||||
* We are in staccato situation (where no previous note have been depressed).
|
||||
* Before the note been passed to fluid_preset_noteon(), the function must determine
|
||||
* the from_key_portamento parameter used by fluid_preset_noteon().
|
||||
*
|
||||
* from_key_portamento is returned by fluid_synth_get_fromkey_portamento_legato() function.
|
||||
* fromkey_portamento is set to valid/invalid key value depending of the portamento
|
||||
* modes (see portamento mode API) , CC portamento On/Off , and CC portamento control
|
||||
* (PTC).
|
||||
*
|
||||
* @param synth instance.
|
||||
* @param chan MIDI channel number (0 to MIDI channel count - 1).
|
||||
* @param key MIDI note number (0-127).
|
||||
* @param vel MIDI velocity (0-127).
|
||||
* @return FLUID_OK on success, FLUID_FAILED otherwise.
|
||||
*/
|
||||
int
|
||||
fluid_synth_noteon_mono_staccato(fluid_synth_t* synth,int chan,int key,int vel)
|
||||
{
|
||||
fluid_channel_t* channel = synth->channel[chan];
|
||||
|
||||
/* Before playing a new note, if a previous monophonic note is currently
|
||||
sustained it needs to be released */
|
||||
fluid_synth_release_voice_on_same_note_LOCAL(synth,chan, channel->key_mono_sustained);
|
||||
/* Get possible 'fromkey portamento' */
|
||||
fluid_synth_get_fromkey_portamento_legato( channel, INVALID_NOTE);
|
||||
/* The note needs to be played by voices allocation */
|
||||
return fluid_preset_noteon(channel->preset, synth, chan, key, vel);
|
||||
}
|
||||
|
||||
/**
|
||||
* Plays noteoff for a polyphonic or monophonic note
|
||||
* Please see the description above about "monophonic playing".
|
||||
*
|
||||
*
|
||||
* noteOff poly >---------------------------------+
|
||||
* |
|
||||
* |
|
||||
* |
|
||||
* noteoff_mono _____\|/_______
|
||||
* LOCAL >------------------------->| noteoff |
|
||||
* | monopoly |----> noteoff
|
||||
* Sust.on/off >------------------------->|_______________|
|
||||
* Sost.on/off
|
||||
*
|
||||
* The function has the same behaviour when the noteoff is poly of mono, except
|
||||
* that for mono noteoff, if any pedal (sustain or sostenuto ) is depressed, the
|
||||
* key is memorized. This is neccessary when the next mono note will be played
|
||||
* staccato, as any current mono note currently sustained will need to be released
|
||||
* (see fluid_synth_noteon_mono_staccato()).
|
||||
* Note also that for a monophonic legato passage, the function is called only when
|
||||
* the last noteoff of the passage occurs. That means that if sustain or sostenuto
|
||||
* is depressed, only the last note of a legato passage will be sustained.
|
||||
*
|
||||
* @param synth instance.
|
||||
* @param chan MIDI channel number (0 to MIDI channel count - 1).
|
||||
* @param key MIDI note number (0-127).
|
||||
* @param Mono, 1 noteoff on monophonic note.
|
||||
* 0 noteoff on polyphonic note.
|
||||
* @return FLUID_OK on success, FLUID_FAILED otherwise.
|
||||
*
|
||||
* Note: On return, on monophonic, possible sustained note is memorized in
|
||||
* key_mono_sustained. Memorization is done here on noteOff.
|
||||
*/
|
||||
int fluid_synth_noteoff_monopoly(fluid_synth_t* synth, int chan, int key,
|
||||
char Mono)
|
||||
{
|
||||
int status = FLUID_FAILED;
|
||||
fluid_voice_t* voice;
|
||||
int i;
|
||||
fluid_channel_t* channel = synth->channel[chan];
|
||||
/* Key_sustained is prepared to return no note sustained (INVALID_NOTE) */
|
||||
if (Mono)
|
||||
{
|
||||
channel->key_mono_sustained = INVALID_NOTE; /* no mono note sustained */
|
||||
}
|
||||
/* noteoff for all voices with same chan and same key */
|
||||
for (i = 0; i < synth->polyphony; i++)
|
||||
{
|
||||
voice = synth->voice[i];
|
||||
if (fluid_voice_is_on(voice) &&
|
||||
fluid_voice_get_channel(voice) == chan &&
|
||||
fluid_voice_get_key(voice) == key)
|
||||
{
|
||||
if (synth->verbose)
|
||||
{
|
||||
int used_voices = 0;
|
||||
int k;
|
||||
for (k = 0; k < synth->polyphony; k++)
|
||||
{
|
||||
if (!_AVAILABLE(synth->voice[k]))
|
||||
{
|
||||
used_voices++;
|
||||
}
|
||||
}
|
||||
FLUID_LOG(FLUID_INFO, "noteoff\t%d\t%d\t%d\t%05d\t%.3f\t%d",
|
||||
fluid_voice_get_channel(voice), fluid_voice_get_key(voice), 0,
|
||||
fluid_voice_get_id(voice),
|
||||
(fluid_curtime() - synth->start) / 1000.0f,
|
||||
used_voices);
|
||||
} /* if verbose */
|
||||
|
||||
fluid_voice_noteoff(voice);
|
||||
/* noteoff on monophonic note */
|
||||
/* Key memorization if the note is sustained */
|
||||
if(Mono &&
|
||||
(fluid_voice_is_sustained(voice) || fluid_voice_is_sostenuto(voice)))
|
||||
{
|
||||
channel->key_mono_sustained = key;
|
||||
}
|
||||
status = FLUID_OK;
|
||||
} /* if voice on */
|
||||
} /* for all voices */
|
||||
return status;
|
||||
}
|
||||
|
||||
/*----------------------------------------------------------------------------
|
||||
legato playing
|
||||
-----------------------------------------------------------------------------*/
|
||||
/**
|
||||
* Plays noteon for a monophonic note played legato.
|
||||
* Please see the description above about "monophonic playing".
|
||||
*
|
||||
*
|
||||
* _______________
|
||||
* portamento modes >----->| |
|
||||
* | get_fromkey |
|
||||
* Porta.on/off >----------------------->|_______________|
|
||||
* Portamento |
|
||||
* (PTC) | +-->preset_noteon
|
||||
* fromkey | fromkey | (with or without)
|
||||
* legato | portamento| (portamento)
|
||||
* _____\|/_______ |
|
||||
* | noteon |--+
|
||||
* noteon_mono >------------------------>| monopoly |
|
||||
* LOCAL | legato |----->voices
|
||||
* |_______________| triggering
|
||||
* /|\ (with or without)
|
||||
* | (portamento)
|
||||
* legato modes >-----------------+
|
||||
*
|
||||
* We are in legato situation (where a previous note has been depressed).
|
||||
* The function must determine the from_key_portamento and from_key_legato parameters
|
||||
* used respectively by fluid_preset_noteon() function and voices triggering functions.
|
||||
*
|
||||
* from_key_portamento and from_key_legato are returned by
|
||||
* fluid_synth_get_fromkey_portamento_legato() function.
|
||||
* fromkey_portamento is set to valid/invalid key value depending of the portamento
|
||||
* modes (see portamento mode API), CC portamento On/Off, and CC portamento control
|
||||
* (PTC).
|
||||
* Then, depending of the legato modes (see legato mode API), the function will call
|
||||
* the appropriate triggering functions.
|
||||
* @param synth instance.
|
||||
* @param chan MIDI channel number (0 to MIDI channel count - 1).
|
||||
* @param fromkey MIDI note number (0-127).
|
||||
* @param tokey MIDI note number (0-127).
|
||||
* @param vel MIDI velocity (0-127).
|
||||
* @return FLUID_OK on success, FLUID_FAILED otherwise.
|
||||
*
|
||||
* Note: The voices with key 'fromkey' are to be used to play key 'tokey'.
|
||||
* The function is able to play legato through Preset Zone(s) (PZ) and
|
||||
* Instrument Zone(s) (IZ) as far as possible.
|
||||
* When key tokey is outside the current Instrument Zone, Preset Zone,
|
||||
* current 'fromkey' voices are released. If necessary new voices
|
||||
* are restarted when tokey enters inside new Instrument(s) Zones,Preset Zone(s).
|
||||
* More informations in FluidPolyMono-0004.pdf chapter 4.7 (Appendices).
|
||||
*/
|
||||
int fluid_synth_noteon_monopoly_legato(fluid_synth_t* synth, int chan,
|
||||
int fromkey, int tokey, int vel)
|
||||
{
|
||||
fluid_channel_t* channel = synth->channel[chan];
|
||||
unsigned char legatomode = channel->legatomode;
|
||||
fluid_voice_t* voice;
|
||||
int i ;
|
||||
/* Gets possible 'fromkey portamento' and possible 'fromkey legato' note */
|
||||
fromkey = fluid_synth_get_fromkey_portamento_legato( channel, (unsigned char)fromkey);
|
||||
|
||||
if (fluid_channel_is_valid_note(fromkey)) for (i = 0; i < synth->polyphony; i++)
|
||||
{
|
||||
/* searching fromkey voices: only those who don't have 'note off' */
|
||||
voice = synth->voice[i];
|
||||
if (fluid_voice_is_on(voice) &&
|
||||
fluid_voice_get_channel(voice) == chan &&
|
||||
fluid_voice_get_key(voice) == fromkey)
|
||||
{
|
||||
fluid_zone_range_t * zone_range = voice->zone_range;
|
||||
/* Ignores voice when there is no instrument zone (i.e no zone_range). Otherwise
|
||||
checks if tokey is inside the range of the running voice */
|
||||
if (zone_range && fluid_zone_inside_range(zone_range, tokey, vel))
|
||||
{
|
||||
switch (legatomode)
|
||||
{
|
||||
case FLUID_CHANNEL_LEGATO_MODE_RETRIGGER: /* mode 0 */
|
||||
fluid_voice_release(voice); /* normal release */
|
||||
break;
|
||||
|
||||
case FLUID_CHANNEL_LEGATO_MODE_MULTI_RETRIGGER: /* mode 1 */
|
||||
/* Skip in attack section */
|
||||
fluid_voice_update_multi_retrigger_attack(voice,tokey,vel);
|
||||
|
||||
/* Starts portamento if enabled */
|
||||
if(fluid_channel_is_valid_note(synth->fromkey_portamento))
|
||||
{
|
||||
/* Sends portamento parameters to the voice dsp */
|
||||
fluid_voice_update_portamento(voice,
|
||||
synth->fromkey_portamento,
|
||||
tokey);
|
||||
}
|
||||
/* The voice is now used to play tokey in legato manner */
|
||||
/* Marks this Instrument Zone to be ignored during next
|
||||
fluid_preset_noteon() */
|
||||
zone_range->ignore = TRUE;
|
||||
break;
|
||||
|
||||
default: /* Invalid mode: this should never happen */
|
||||
FLUID_LOG(FLUID_WARN, "Failed to execute legato mode: %d",
|
||||
legatomode);
|
||||
return FLUID_FAILED;
|
||||
}
|
||||
}
|
||||
else
|
||||
{ /* tokey note is outside the voice range, so the voice is released */
|
||||
fluid_voice_release(voice);
|
||||
}
|
||||
}
|
||||
}
|
||||
/* May be,tokey will enter in new others Insrument Zone(s),Preset Zone(s), in
|
||||
this case it needs to be played by voices allocation */
|
||||
return fluid_preset_noteon(channel->preset,synth,chan,tokey,vel);
|
||||
}
|
|
@ -27,6 +27,7 @@
|
|||
#include "fluid_sys.h"
|
||||
#include "fluid_sfont.h"
|
||||
#include "fluid_rvoice_event.h"
|
||||
#include "fluid_defsfont.h"
|
||||
|
||||
/* used for filter turn off optimization - if filter cutoff is above the
|
||||
specified value and filter q is below the other value, turn filter off */
|
||||
|
@ -241,9 +242,14 @@ delete_fluid_voice(fluid_voice_t* voice)
|
|||
/* fluid_voice_init
|
||||
*
|
||||
* Initialize the synthesis process
|
||||
* inst_zone, the Instrument Zone contains the sample, Keyrange,Velrange
|
||||
* of the voice.
|
||||
* When playing legato (n1,n2) in mono mode, n2 will use n1 voices
|
||||
* as far as n2 still enters in Keyrange,Velrange of n1.
|
||||
*/
|
||||
int
|
||||
fluid_voice_init(fluid_voice_t* voice, fluid_sample_t* sample,
|
||||
fluid_voice_init(fluid_voice_t* voice, fluid_sample_t* sample,
|
||||
fluid_zone_range_t *inst_zone_range,
|
||||
fluid_channel_t* channel, int key, int vel, unsigned int id,
|
||||
unsigned int start_time, fluid_real_t gain)
|
||||
{
|
||||
|
@ -266,6 +272,7 @@ fluid_voice_init(fluid_voice_t* voice, fluid_sample_t* sample,
|
|||
if (voice->sample)
|
||||
fluid_voice_off(voice);
|
||||
|
||||
voice->zone_range = inst_zone_range; /* Instrument zone range for legato */
|
||||
voice->id = id;
|
||||
voice->chan = fluid_channel_get_num(channel);
|
||||
voice->key = (unsigned char) key;
|
||||
|
@ -453,14 +460,18 @@ fluid_voice_calculate_gain_amplitude(const fluid_voice_t* voice, fluid_real_t ga
|
|||
return gain * voice->synth_gain / (INT24_MAX * 1.0f);
|
||||
}
|
||||
|
||||
void
|
||||
fluid_voice_calculate_gen_pitch(fluid_voice_t* voice)
|
||||
/* Useful to return the nominal pitch of a key */
|
||||
/* The nominal pitch is dependant of voice->root_pitch,tuning, and
|
||||
GEN_SCALETUNE generator.
|
||||
This is useful to set the value of GEN_PITCH generator on noteOn.
|
||||
This is useful to get the beginning/ending pitch for portamento.
|
||||
*/
|
||||
fluid_real_t fluid_voice_calculate_pitch(fluid_voice_t* voice, int key)
|
||||
{
|
||||
fluid_tuning_t* tuning;
|
||||
fluid_real_t x;
|
||||
fluid_real_t x,pitch;
|
||||
|
||||
/* The GEN_PITCH is a hack to fit the pitch bend controller into the
|
||||
* modulator paradigm. Now the nominal pitch of the key is set.
|
||||
/* Now the nominal pitch of the key is returned.
|
||||
* Note about SCALETUNE: SF2.01 8.1.3 says, that this generator is a
|
||||
* non-realtime parameter. So we don't allow modulation (as opposed
|
||||
* to fluid_voice_gen_value(voice, GEN_SCALETUNE) When the scale tuning is varied,
|
||||
|
@ -469,15 +480,22 @@ fluid_voice_calculate_gen_pitch(fluid_voice_t* voice)
|
|||
if (fluid_channel_has_tuning(voice->channel)) {
|
||||
tuning = fluid_channel_get_tuning (voice->channel);
|
||||
x = fluid_tuning_get_pitch (tuning, (int)(voice->root_pitch / 100.0f));
|
||||
voice->gen[GEN_PITCH].val = voice->gen[GEN_SCALETUNE].val / 100.0f *
|
||||
(fluid_tuning_get_pitch (tuning, fluid_voice_get_actual_key(voice)) - x) + x;
|
||||
pitch = voice->gen[GEN_SCALETUNE].val / 100.0f *
|
||||
(fluid_tuning_get_pitch (tuning, key) - x) + x;
|
||||
} else {
|
||||
voice->gen[GEN_PITCH].val = voice->gen[GEN_SCALETUNE].val
|
||||
* (fluid_voice_get_actual_key(voice) - voice->root_pitch / 100.0f) + voice->root_pitch;
|
||||
pitch = voice->gen[GEN_SCALETUNE].val
|
||||
* (key - voice->root_pitch / 100.0f) + voice->root_pitch;
|
||||
}
|
||||
|
||||
return pitch;
|
||||
}
|
||||
|
||||
void
|
||||
fluid_voice_calculate_gen_pitch(fluid_voice_t* voice)
|
||||
{
|
||||
voice->gen[GEN_PITCH].val = fluid_voice_calculate_pitch(voice, fluid_voice_get_actual_key(voice));
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* fluid_voice_calculate_runtime_synthesis_parameters
|
||||
*
|
||||
|
@ -596,6 +614,17 @@ fluid_voice_calculate_runtime_synthesis_parameters(fluid_voice_t* voice)
|
|||
fluid_voice_update_param(voice, list_of_generators_to_initialize[n]);
|
||||
}
|
||||
|
||||
/* Start portamento if enabled */
|
||||
{ /* fromkey note comes from "GetFromKeyPortamentoLegato()" detector.
|
||||
When fromkey is set to ValidNote , portamento is started */
|
||||
/* Return fromkey portamento */
|
||||
int fromkey = voice->channel->synth->fromkey_portamento;
|
||||
if(fluid_channel_is_valid_note(fromkey))
|
||||
{ /* Send portamento parameters to the voice dsp */
|
||||
fluid_voice_update_portamento(voice,fromkey, fluid_voice_get_actual_key(voice));
|
||||
}
|
||||
}
|
||||
|
||||
/* Make an estimate on how loud this voice can get at any time (attenuation). */
|
||||
UPDATE_RVOICE_R1(fluid_rvoice_set_min_attenuation_cB,
|
||||
fluid_voice_get_lower_boundary_for_attenuation(voice));
|
||||
|
@ -701,7 +730,7 @@ fluid_voice_update_param(fluid_voice_t* voice, int gen)
|
|||
/* range checking is done in the fluid_pan and fluid_balance functions */
|
||||
voice->pan = fluid_voice_gen_value(voice, GEN_PAN);
|
||||
voice->balance = fluid_voice_gen_value(voice, GEN_CUSTOM_BALANCE);
|
||||
|
||||
|
||||
/* left amp */
|
||||
UPDATE_RVOICE_BUFFERS2(fluid_rvoice_buffers_set_amp, 0,
|
||||
fluid_voice_calculate_gain_amplitude(voice,
|
||||
|
@ -798,7 +827,7 @@ fluid_voice_update_param(fluid_voice_t* voice, int gen)
|
|||
case GEN_CUSTOM_FILTERQ:
|
||||
UPDATE_RVOICE_CUSTOM_FILTER1(fluid_iir_filter_set_q, x);
|
||||
break;
|
||||
|
||||
|
||||
case GEN_MODLFOTOPITCH:
|
||||
fluid_clip(x, -12000.0, 12000.0);
|
||||
UPDATE_RVOICE_R1(fluid_rvoice_set_modlfo_to_pitch, x);
|
||||
|
@ -1164,6 +1193,72 @@ int fluid_voice_modulate_all(fluid_voice_t* voice)
|
|||
return FLUID_OK;
|
||||
}
|
||||
|
||||
/** legato update functions --------------------------------------------------*/
|
||||
/* Updates voice portamento parameters
|
||||
*
|
||||
* @voice voice the synthesis voice
|
||||
* @fromkey the beginning pitch of portamento.
|
||||
* @tokey the ending pitch of portamento.
|
||||
*
|
||||
* The function calculates pitch offset and increment, then these parameters
|
||||
* are send to the dsp.
|
||||
*/
|
||||
void fluid_voice_update_portamento (fluid_voice_t* voice, int fromkey,int tokey)
|
||||
|
||||
{
|
||||
fluid_channel_t* channel= voice->channel;
|
||||
|
||||
/* calculates pitch offset */
|
||||
fluid_real_t PitchBeg = fluid_voice_calculate_pitch(voice,fromkey);
|
||||
fluid_real_t PitchEnd = fluid_voice_calculate_pitch(voice,tokey);
|
||||
fluid_real_t pitchoffset = PitchBeg - PitchEnd;
|
||||
|
||||
/* Calculates increment countinc */
|
||||
/* Increment is function of PortamentoTime (ms)*/
|
||||
unsigned int countinc = (unsigned int)(((fluid_real_t)voice->output_rate *
|
||||
0.001f *
|
||||
(fluid_real_t)fluid_channel_portamentotime(channel)) /
|
||||
(fluid_real_t)FLUID_BUFSIZE +0.5);
|
||||
|
||||
/* Sends portamento parameters to the voice dsp */
|
||||
UPDATE_RVOICE2(fluid_rvoice_set_portamento, countinc, pitchoffset);
|
||||
}
|
||||
|
||||
/*---------------------------------------------------------------*/
|
||||
/*legato mode 1: multi_retrigger
|
||||
*
|
||||
* Modulates all generators dependent of key,vel.
|
||||
* Forces the voice envelopes in the attack section (legato mode 1).
|
||||
*
|
||||
* @voice voice the synthesis voice
|
||||
* @tokey the new key to be applied to this voice.
|
||||
* @vel the new velocity to be applied to this voice.
|
||||
*/
|
||||
void fluid_voice_update_multi_retrigger_attack(fluid_voice_t* voice,
|
||||
int tokey, int vel)
|
||||
{
|
||||
voice->key = tokey; /* new note */
|
||||
voice->vel = vel; /* new velocity */
|
||||
/* Updates generators dependent of velocity */
|
||||
/* Modulates GEN_ATTENUATION (and others ) before calling
|
||||
fluid_rvoice_multi_retrigger_attack().*/
|
||||
fluid_voice_modulate(voice, FALSE, FLUID_MOD_VELOCITY);
|
||||
|
||||
/* Updates generator dependent of voice->key */
|
||||
fluid_voice_update_param(voice, GEN_KEYTOMODENVHOLD);
|
||||
fluid_voice_update_param(voice, GEN_KEYTOMODENVDECAY);
|
||||
fluid_voice_update_param(voice, GEN_KEYTOVOLENVHOLD);
|
||||
fluid_voice_update_param(voice, GEN_KEYTOVOLENVDECAY);
|
||||
|
||||
/* Updates pitch generator */
|
||||
fluid_voice_calculate_gen_pitch(voice);
|
||||
fluid_voice_update_param(voice, GEN_PITCH);
|
||||
|
||||
/* updates adsr generator */
|
||||
UPDATE_RVOICE0(fluid_rvoice_multi_retrigger_attack);
|
||||
}
|
||||
/** end of legato update functions */
|
||||
|
||||
/*
|
||||
Force the voice into release stage. Useful anywhere a voice
|
||||
needs to be damped even if pedals (sustain sostenuto) are depressed.
|
||||
|
@ -1183,8 +1278,9 @@ fluid_voice_release(fluid_voice_t* voice)
|
|||
* fluid_voice_noteoff
|
||||
*
|
||||
* Sending a noteoff event will advance the envelopes to section 5 (release).
|
||||
* The function is convenient for polyphonic or monophonic note
|
||||
*/
|
||||
int
|
||||
void
|
||||
fluid_voice_noteoff(fluid_voice_t* voice)
|
||||
{
|
||||
fluid_channel_t* channel;
|
||||
|
@ -1201,13 +1297,11 @@ fluid_voice_noteoff(fluid_voice_t* voice)
|
|||
}
|
||||
/* Or sustain a note under Sustain pedal */
|
||||
else if (fluid_channel_sustained(channel)) {
|
||||
voice->status = FLUID_VOICE_SUSTAINED;
|
||||
voice->status = FLUID_VOICE_SUSTAINED;
|
||||
}
|
||||
/* Or force the voice to release stage */
|
||||
else
|
||||
fluid_voice_release(voice);
|
||||
|
||||
return FLUID_OK;
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
|
@ -33,7 +33,6 @@
|
|||
|
||||
#define NO_CHANNEL 0xff
|
||||
|
||||
|
||||
typedef struct _fluid_overflow_prio_t fluid_overflow_prio_t;
|
||||
|
||||
struct _fluid_overflow_prio_t
|
||||
|
@ -73,6 +72,7 @@ struct _fluid_voice_t
|
|||
fluid_gen_t gen[GEN_LAST];
|
||||
fluid_mod_t mod[FLUID_NUM_MOD];
|
||||
int mod_count;
|
||||
fluid_zone_range_t * zone_range; /* instrument zone range*/
|
||||
fluid_sample_t* sample; /* Pointer to sample (dupe in rvoice) */
|
||||
|
||||
/* basic parameters */
|
||||
|
@ -123,7 +123,8 @@ void fluid_voice_calculate_gen_pitch(fluid_voice_t* voice);
|
|||
|
||||
int fluid_voice_write (fluid_voice_t* voice, fluid_real_t *dsp_buf);
|
||||
|
||||
int fluid_voice_init(fluid_voice_t* voice, fluid_sample_t* sample,
|
||||
int fluid_voice_init(fluid_voice_t* voice, fluid_sample_t* sample,
|
||||
fluid_zone_range_t *inst_zone_range,
|
||||
fluid_channel_t* channel, int key, int vel,
|
||||
unsigned int id, unsigned int time, fluid_real_t gain);
|
||||
|
||||
|
@ -146,8 +147,15 @@ int fluid_voice_set_output_rate(fluid_voice_t* voice, fluid_real_t value);
|
|||
function.*/
|
||||
void fluid_voice_update_param(fluid_voice_t* voice, int gen);
|
||||
|
||||
/** legato modes */
|
||||
/* force in the attack section for legato mode multi_retrigger: 1 */
|
||||
void fluid_voice_update_multi_retrigger_attack(fluid_voice_t* voice,int tokey, int vel);
|
||||
/* Update portamento parameter */
|
||||
void fluid_voice_update_portamento (fluid_voice_t* voice, int fromkey, int tokey);
|
||||
|
||||
|
||||
void fluid_voice_release(fluid_voice_t* voice);
|
||||
int fluid_voice_noteoff(fluid_voice_t* voice);
|
||||
void fluid_voice_noteoff(fluid_voice_t* voice);
|
||||
void fluid_voice_off(fluid_voice_t* voice);
|
||||
void fluid_voice_stop(fluid_voice_t* voice);
|
||||
void fluid_voice_overflow_rvoice_finished(fluid_voice_t* voice);
|
||||
|
|
|
@ -1209,7 +1209,7 @@ fluid_str_equal (const void *v1, const void *v2)
|
|||
const char *string1 = v1;
|
||||
const char *string2 = v2;
|
||||
|
||||
return strcmp (string1, string2) == 0;
|
||||
return FLUID_STRCMP (string1, string2) == 0;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -915,7 +915,7 @@ fluid_istream_gets (fluid_istream_t in, char* buf, int len)
|
|||
* @return Number of bytes written or -1 on error
|
||||
*/
|
||||
int
|
||||
fluid_ostream_printf (fluid_ostream_t out, char* format, ...)
|
||||
fluid_ostream_printf (fluid_ostream_t out, const char* format, ...)
|
||||
{
|
||||
char buf[4096];
|
||||
va_list args;
|
||||
|
|
|
@ -341,7 +341,7 @@ typedef GModule fluid_module_t;
|
|||
fluid_istream_t fluid_get_stdin (void);
|
||||
fluid_ostream_t fluid_get_stdout (void);
|
||||
int fluid_istream_readline(fluid_istream_t in, fluid_ostream_t out, char* prompt, char* buf, int len);
|
||||
int fluid_ostream_printf (fluid_ostream_t out, char* format, ...);
|
||||
int fluid_ostream_printf (fluid_ostream_t out, const char* format, ...);
|
||||
|
||||
/* The function should return 0 if no error occured, non-zero
|
||||
otherwise. If the function return non-zero, the socket will be
|
||||
|
|
|
@ -199,6 +199,7 @@ typedef struct _fluid_hashtable_t fluid_hashtable_t;
|
|||
typedef struct _fluid_client_t fluid_client_t;
|
||||
typedef struct _fluid_server_socket_t fluid_server_socket_t;
|
||||
typedef struct _fluid_sample_timer_t fluid_sample_timer_t;
|
||||
typedef struct _fluid_zone_range_t fluid_zone_range_t;
|
||||
|
||||
/***************************************************************
|
||||
*
|
||||
|
|
Loading…
Reference in a new issue