Euterpea 2.0.4 → 2.0.5
raw patch · 122 files changed
+224/−117 lines, 122 filesdep ~PortMidibinary-addedPVP: major bump suggested
API removals or changes: PVP suggests a major version bump
Dependency ranges changed: PortMidi
API changes (from Hackage documentation)
Files
- .git/COMMIT_EDITMSG +3/−1
- .git/FETCH_HEAD +1/−1
- .git/ORIG_HEAD +1/−1
- .git/index binary
- .git/logs/HEAD +8/−0
- .git/logs/refs/heads/master +8/−0
- .git/logs/refs/remotes/origin/master +8/−0
- .git/objects/01/024db2f04aee6d9f60a91476631c20da20a599 binary
- .git/objects/02/38550e704e099e5372a409461f44547ea79b98 binary
- .git/objects/02/727d144f7ab7d1800989ad4c5168028fd03247 binary
- .git/objects/03/5dbf6733fe0e251e1d6763cc2cf1f92ec45b97 binary
- .git/objects/06/8ccf9b2b17b09afeb0945d8eea4e1ec9b5931b binary
- .git/objects/08/3f9c4ba34a66851c760b9606c31278e056e017 binary
- .git/objects/0a/43fe37ff7154b4ae2f767e21231fd4351d9af1 binary
- .git/objects/0a/761e547df00e9dc91da0a5099bf002fe064369 +1/−0
- .git/objects/0d/3b143490c5d1bc828167dea1870dde9cd4a6ed binary
- .git/objects/0e/1c38b33561bb4a50232bd0c9afbdc9aeb4fc76 binary
- .git/objects/0f/da2b43ce06c5f2bd8decb72778ac85da009fc5 binary
- .git/objects/10/940a60108e8947be43e6c5454b36703f3af527 binary
- .git/objects/17/e94f9e475ee049f36dfd19fee87e4e1fa9074a binary
- .git/objects/1a/c4c067ddd2305527b67e2aa9e56b19dfb3c808 binary
- .git/objects/1b/74031fc6b4b883f5b04cd072f3b2d31251ee89 binary
- .git/objects/1c/efbe95003d3a2016fb90f8131040cf38236ef3 binary
- .git/objects/1e/bd6e31aa5d954bcc0ccb6ac76b82ed892efb69 +1/−0
- .git/objects/1f/5f132d6440f505b17add35a81b31f4a6499b06 binary
- .git/objects/24/55b6c3cb801aeac9d6187d5f7b26dd93b946c5 binary
- .git/objects/29/529e1996bba392c92087b0f650514c6399bee7 binary
- .git/objects/2a/9bea58331ca40b8b405f96ea5d3d247e7289f0 binary
- .git/objects/2b/1cbcde96e1c5090959a5874b0c692f87c33105 binary
- .git/objects/2e/6373695d1691df1d2172af4bab2e5d9a2b8cba binary
- .git/objects/2f/6595b291855c3afb62baa5f782de4acc472782 binary
- .git/objects/2f/f6fa63f2e9efaa4004c30e4a5f491bbe2dce79 binary
- .git/objects/33/1bb2029ff2d4b87f05d3b9d0968c29e2a49c95 +1/−0
- .git/objects/37/f795427c8e51b753de9d7ee5b858d9394bb50d binary
- .git/objects/39/463363d990ed242c0be4bcdcd09b6f1f4ddf51 binary
- .git/objects/3a/3f19d55b74d7aec2bd414cc388f0c581d037f5 binary
- .git/objects/3b/5d8b976e4848d4a39e7b0004bbf070df857f56 binary
- .git/objects/3c/4d533b912c3934c8f5d31f74ecd1738a14d1ea binary
- .git/objects/40/f7e1bcd3efe61dbaf46344cc8b4449c05adb1c too large to diff
- .git/objects/41/cd1beb04060f4de58355deec1958f1879357b9 binary
- .git/objects/42/a10db85f8de9ab90bd19b81ee041a157360902 binary
- .git/objects/44/ab1907cf3f73e27e932b5f9adbc1aff0055bd9 binary
- .git/objects/46/a33e2dc6a3ec2742374414f9bc62e88613f7b0 binary
- .git/objects/49/cb068c76678f59d50ff054d774c193fb8fb0ee binary
- .git/objects/4d/e09d19a52859416eebe7337b734228c36eeaea binary
- .git/objects/51/cd2dac70f36461ce75efa6dd04f4191cfb85a2 binary
- .git/objects/52/e61beeaa81f6b0c835d6c85fc13eac3efa4370 binary
- .git/objects/56/1a90e094ad0eb02d529258e705dc2eb8567006 binary
- .git/objects/58/0c534bc0e4a8acd956e26c44fdbe771daaeaee binary
- .git/objects/5b/3b5b7a40203f6670d667ccf1490af895b2532e binary
- .git/objects/5f/076dc7ec4d470f347d83ebdac8a52b61089ed6 binary
- .git/objects/64/b3cbe8b2375dc3a504cc49645a7c302d3bb03e binary
- .git/objects/66/ea5696732fb7b770ef550c4058ccfe97df5307 binary
- .git/objects/6a/3307ad57c076c3495045be348827023ba172f3 binary
- .git/objects/77/a0936d0edcb6a31830b464e6cc3eb066beffa9 +1/−0
- .git/objects/78/da1cc02000e99d137b8e57cdac5cfa0e1d61f0 binary
- .git/objects/7d/ee88664cf47d7a9c21afea2d12124baeba342a binary
- .git/objects/7e/4055ac6f1a57043bf851e0ac6895e48701dfb6 binary
- .git/objects/85/d332148dd5d2895c168281bd8f722082fb4642 binary
- .git/objects/8a/8fe51cee7f28ddddda4a8ea391fc12c9535fd4 binary
- .git/objects/8b/db3e4a0a2d31a39225a6dce662d10354bb03fb binary
- .git/objects/8e/4353c7c431de8e9b96c548c56404725cebf8d7 binary
- .git/objects/90/7abff0690c0ed58be55989ef2baadd94ec74d6 binary
- .git/objects/91/319c18ed3cd939faff2d9ddece6f22b3f3ff89 binary
- .git/objects/91/7dd66d08b00840b6875838915e705cf274b67b binary
- .git/objects/92/1a567f84fd3c619896da656e8c6215500b0ee8 binary
- .git/objects/98/a4d35831b52864d3c04205efcf32d97fa71141 binary
- .git/objects/9d/13ddca6950d8ab266b2af51b7cfff182897246 binary
- .git/objects/9d/34353ee46571bf1ae1cd47576fd101f90adc6c binary
- .git/objects/9f/96656243a99efc634be16ce9bbc37153ddf901 binary
- .git/objects/a1/22b4153c502a959c1781b50c2d7a7c4aee9236 binary
- .git/objects/a2/1ce4cc33277796834cce54e132c455745fdc4a binary
- .git/objects/a3/0a6d1ed203bc1d93004fd1b0dad1d1375bd83a binary
- .git/objects/a3/c414d613cc00d65abcb35bc2becfd8750c1ea2 binary
- .git/objects/a4/5ecb0d529ba48d8eca951b686178162bb56fed binary
- .git/objects/a7/759cfaaf8d9cb9689de568e618cfdd0117725c binary
- .git/objects/aa/54f8d378706ccebc9f919eb858343684c0db35 binary
- .git/objects/ab/968e1f5138259bf03a437adf6aeab81d2305f7 binary
- .git/objects/ac/4e27878b2d3c880435a26a956fc06090678680 binary
- .git/objects/af/7a81d59cb968562885db868d11c23397fe76c4 binary
- .git/objects/b1/13c29eb1f0e31fabe30a3806d50c684682ce7b binary
- .git/objects/b2/090cd8ae9dc5c97258a85c28874be97a4236fb +2/−0
- .git/objects/b3/318124d370ece16dadd88471b7da08edaec784 binary
- .git/objects/b4/54931a04f9f5ed704efee42f581efd7bab6ea6 binary
- .git/objects/b5/2e7337b8ceb6af3917335286122e5583beb623 binary
- .git/objects/b8/d039f25c74aae5847108e06578fabd6044b08f binary
- .git/objects/b9/3609b90dd7ff47b06e8207118b7ced0423302b binary
- .git/objects/ba/79d76d21f4f8570c2291f34c4e6a7c032ba6a6 binary
- .git/objects/bc/44a1c3065f4425ff4bd0bdeea06c9148d54b69 binary
- .git/objects/bc/89ee9a47fb06ef5908208609064789fab994a3 binary
- .git/objects/c0/f9a2c81ce54e952d2c2345e8181cbd1fad4e5e binary
- .git/objects/c1/0871f26e532d8caecda1aaa201b3e8dc9e14a9 binary
- .git/objects/c2/71a1a77c1de0661216fa046482d63798131c7d binary
- .git/objects/c4/441dcae1ecbcf7950a80c92988f2e2e11fa204 binary
- .git/objects/c6/8c3a9f599e56b40150c0f49e8ee9bd86f3341a binary
- .git/objects/c8/5202f17668f31b25d58e0868e6da237523220b binary
- .git/objects/ce/8098efc2f498451b940e76ce332d69d455e46a binary
- .git/objects/d2/68f5a8f9eeddb031e901170352e31333b42733 binary
- .git/objects/d2/72327d92a665b172ef4cfaaf7a5c20d5db5b90 binary
- .git/objects/d2/b862f369c5ac596bf5f12063d78d6b8a6ee225 binary
- .git/objects/d9/65d92c5335eadacaf9a72230f79d4dff573b27 binary
- .git/objects/db/c4cd70d46015b2e76f28354b4f938d2cd070ff binary
- .git/objects/dc/354a20d31288878085d56b43ebfe3aa820522a binary
- .git/objects/df/0bbaa2086cf56f42500389a0bff5d532e7fc63 binary
- .git/objects/e3/836fe2cf6a77d8ec3d8a7bbbe3822251fb5ed9 +1/−0
- .git/objects/e4/c9ce6d2f62995a25daa505e8211cf7b355dbf4 binary
- .git/objects/e6/9de29bb2d1d6434b8b29ae775ad8c2e48c5391 binary
- .git/objects/e9/5fe8336982a811e3ddc1e3fcf64f5a3767ac1b binary
- .git/objects/ee/5e4a1390a0d0f1e9d0ce02680a74f952b32955 binary
- .git/objects/f0/ad62e4e42168fd3ab7e5945083d01e058c6231 binary
- .git/objects/f2/773f0019369b986b4ff6750d919fca7e9294fa binary
- .git/objects/f8/214bd47c4577ee917f6f53f61fc6a12422a996 binary
- .git/objects/f9/918de49c23fa56c9da20dcf3fd47ce0cf37b99 binary
- .git/objects/ff/910b318efc137a01b3fd719c0c603c06260935 binary
- .git/refs/heads/master +1/−1
- .git/refs/remotes/origin/master +1/−1
- Euterpea.cabal +14/−14
- Euterpea/IO/MIDI/MidiIO.lhs +7/−6
- Euterpea/IO/MIDI/Play.lhs +51/−44
- Euterpea/IO/MIDI/ToMidi2.lhs +65/−0
- Euterpea/Music.lhs +43/−43
- ReadMe.txt +6/−5
@@ -1,1 +1,3 @@-Binary encoding fixes.+EnableGUI reference removed++Refernece removed to a file that no longer exists in Euterpea2.
@@ -1,1 +1,1 @@-02f0974406cb38a71a2bdfe8204e87bd0cd03892 branch 'master' of https://github.com/Euterpea/Euterpea2+77a0936d0edcb6a31830b464e6cc3eb066beffa9 branch 'master' of https://github.com/Euterpea/Euterpea2
@@ -1,1 +1,1 @@-bd913f30e7561f8c842deaed7b028823aa822203+b93609b90dd7ff47b06e8207118b7ced0423302b
binary file changed (2436 → 2532 bytes)
@@ -3,3 +3,11 @@ ef06402d714aa53dae0ba9c74b68d8b4ddea1329 957f3714d66fa6bd059f71b91a1e725b1d2e08a5 Donya Quick <donyaquick@gmail.com> 1499191363 -0400 commit: Misc changes 957f3714d66fa6bd059f71b91a1e725b1d2e08a5 bd913f30e7561f8c842deaed7b028823aa822203 Donya Quick <donyaquick@gmail.com> 1499192677 -0400 commit: Binary encoding fixes. bd913f30e7561f8c842deaed7b028823aa822203 02f0974406cb38a71a2bdfe8204e87bd0cd03892 Donya Quick <donyaquick@gmail.com> 1503766667 -0400 pull --no-rebase --progress origin: Fast-forward+02f0974406cb38a71a2bdfe8204e87bd0cd03892 b2090cd8ae9dc5c97258a85c28874be97a4236fb Donya Quick <donyaquick@gmail.com> 1503778592 -0400 pull --no-rebase --progress origin: Fast-forward+b2090cd8ae9dc5c97258a85c28874be97a4236fb b3318124d370ece16dadd88471b7da08edaec784 Donya Quick <donyaquick@gmail.com> 1503780940 -0400 commit: Documentation update+b3318124d370ece16dadd88471b7da08edaec784 1ebd6e31aa5d954bcc0ccb6ac76b82ed892efb69 Donya Quick <donyaquick@gmail.com> 1527371401 -0400 commit: HCodecs version bumped.+1ebd6e31aa5d954bcc0ccb6ac76b82ed892efb69 331bb2029ff2d4b87f05d3b9d0968c29e2a49c95 Donya Quick <donyaquick@gmail.com> 1530127543 -0400 pull --no-rebase --progress origin: Fast-forward+331bb2029ff2d4b87f05d3b9d0968c29e2a49c95 1ac4c067ddd2305527b67e2aa9e56b19dfb3c808 Donya Quick <donyaquick@gmail.com> 1530149500 -0400 pull --no-rebase --progress origin: Fast-forward+1ac4c067ddd2305527b67e2aa9e56b19dfb3c808 e4c9ce6d2f62995a25daa505e8211cf7b355dbf4 Donya Quick <donyaquick@gmail.com> 1530468209 -0400 commit: PortMidi version change (0.1.6.1)+e4c9ce6d2f62995a25daa505e8211cf7b355dbf4 b93609b90dd7ff47b06e8207118b7ced0423302b Donya Quick <donyaquick@gmail.com> 1530490248 -0400 commit: EnableGUI reference removed+b93609b90dd7ff47b06e8207118b7ced0423302b 77a0936d0edcb6a31830b464e6cc3eb066beffa9 Donya Quick <donyaquick@gmail.com> 1530492169 -0400 pull --no-rebase --progress origin: Fast-forward
@@ -3,3 +3,11 @@ ef06402d714aa53dae0ba9c74b68d8b4ddea1329 957f3714d66fa6bd059f71b91a1e725b1d2e08a5 Donya Quick <donyaquick@gmail.com> 1499191363 -0400 commit: Misc changes 957f3714d66fa6bd059f71b91a1e725b1d2e08a5 bd913f30e7561f8c842deaed7b028823aa822203 Donya Quick <donyaquick@gmail.com> 1499192677 -0400 commit: Binary encoding fixes. bd913f30e7561f8c842deaed7b028823aa822203 02f0974406cb38a71a2bdfe8204e87bd0cd03892 Donya Quick <donyaquick@gmail.com> 1503766667 -0400 pull --no-rebase --progress origin: Fast-forward+02f0974406cb38a71a2bdfe8204e87bd0cd03892 b2090cd8ae9dc5c97258a85c28874be97a4236fb Donya Quick <donyaquick@gmail.com> 1503778592 -0400 pull --no-rebase --progress origin: Fast-forward+b2090cd8ae9dc5c97258a85c28874be97a4236fb b3318124d370ece16dadd88471b7da08edaec784 Donya Quick <donyaquick@gmail.com> 1503780940 -0400 commit: Documentation update+b3318124d370ece16dadd88471b7da08edaec784 1ebd6e31aa5d954bcc0ccb6ac76b82ed892efb69 Donya Quick <donyaquick@gmail.com> 1527371401 -0400 commit: HCodecs version bumped.+1ebd6e31aa5d954bcc0ccb6ac76b82ed892efb69 331bb2029ff2d4b87f05d3b9d0968c29e2a49c95 Donya Quick <donyaquick@gmail.com> 1530127543 -0400 pull --no-rebase --progress origin: Fast-forward+331bb2029ff2d4b87f05d3b9d0968c29e2a49c95 1ac4c067ddd2305527b67e2aa9e56b19dfb3c808 Donya Quick <donyaquick@gmail.com> 1530149500 -0400 pull --no-rebase --progress origin: Fast-forward+1ac4c067ddd2305527b67e2aa9e56b19dfb3c808 e4c9ce6d2f62995a25daa505e8211cf7b355dbf4 Donya Quick <donyaquick@gmail.com> 1530468209 -0400 commit: PortMidi version change (0.1.6.1)+e4c9ce6d2f62995a25daa505e8211cf7b355dbf4 b93609b90dd7ff47b06e8207118b7ced0423302b Donya Quick <donyaquick@gmail.com> 1530490248 -0400 commit: EnableGUI reference removed+b93609b90dd7ff47b06e8207118b7ced0423302b 77a0936d0edcb6a31830b464e6cc3eb066beffa9 Donya Quick <donyaquick@gmail.com> 1530492169 -0400 pull --no-rebase --progress origin: Fast-forward
@@ -1,3 +1,11 @@ 23b0fe619f7f91be4123ef976dd9284c11c1093a ef06402d714aa53dae0ba9c74b68d8b4ddea1329 Donya Quick <donyaquick@gmail.com> 1496256683 -0500 fetch --progress --prune origin: fast-forward ef06402d714aa53dae0ba9c74b68d8b4ddea1329 bd913f30e7561f8c842deaed7b028823aa822203 Donya Quick <donyaquick@gmail.com> 1499192681 -0400 update by push bd913f30e7561f8c842deaed7b028823aa822203 02f0974406cb38a71a2bdfe8204e87bd0cd03892 Donya Quick <donyaquick@gmail.com> 1503766664 -0400 fetch --progress --prune origin: fast-forward+02f0974406cb38a71a2bdfe8204e87bd0cd03892 b2090cd8ae9dc5c97258a85c28874be97a4236fb Donya Quick <donyaquick@gmail.com> 1503778572 -0400 fetch --progress --prune origin: fast-forward+b2090cd8ae9dc5c97258a85c28874be97a4236fb b3318124d370ece16dadd88471b7da08edaec784 Donya Quick <donyaquick@gmail.com> 1503780945 -0400 update by push+b3318124d370ece16dadd88471b7da08edaec784 1ebd6e31aa5d954bcc0ccb6ac76b82ed892efb69 Donya Quick <donyaquick@gmail.com> 1527371408 -0400 update by push+1ebd6e31aa5d954bcc0ccb6ac76b82ed892efb69 331bb2029ff2d4b87f05d3b9d0968c29e2a49c95 Donya Quick <donyaquick@gmail.com> 1530127542 -0400 fetch --progress --prune origin: fast-forward+331bb2029ff2d4b87f05d3b9d0968c29e2a49c95 1ac4c067ddd2305527b67e2aa9e56b19dfb3c808 Donya Quick <donyaquick@gmail.com> 1530149467 -0400 fetch --progress --prune origin: fast-forward+1ac4c067ddd2305527b67e2aa9e56b19dfb3c808 e4c9ce6d2f62995a25daa505e8211cf7b355dbf4 Donya Quick <donyaquick@gmail.com> 1530468215 -0400 update by push+e4c9ce6d2f62995a25daa505e8211cf7b355dbf4 b93609b90dd7ff47b06e8207118b7ced0423302b Donya Quick <donyaquick@gmail.com> 1530490263 -0400 update by push+b93609b90dd7ff47b06e8207118b7ced0423302b 77a0936d0edcb6a31830b464e6cc3eb066beffa9 Donya Quick <donyaquick@gmail.com> 1530492166 -0400 fetch --progress --prune origin: fast-forward
binary file changed (absent → 23035 bytes)
binary file changed (absent → 1341 bytes)
binary file changed (absent → 1136 bytes)
binary file changed (absent → 137 bytes)
binary file changed (absent → 11835 bytes)
binary file changed (absent → 6897 bytes)
binary file changed (absent → 13537 bytes)
@@ -0,0 +1,1 @@+x+)JMU0´0f040031QðMÌÌÓËÈdH{6Xûö÷¡<gþM¿Ì¬$añkÂg®EíÙ}hßù¥<r *SKJôR+R¾?Üsùý3Ù]_]Ît»xº-¢(£aÕøÍùO|âùk¥?<ûµùr¶o"²Ô¢âÌü<ÐmO7H½:yM¢6¾ZíîänGO×
binary file changed (absent → 1133 bytes)
binary file changed (absent → 244 bytes)
binary file changed (absent → 82 bytes)
binary file changed (absent → 901 bytes)
binary file changed (absent → 10296 bytes)
binary file changed (absent → 251 bytes)
binary file changed (absent → 83 bytes)
binary file changed (absent → 187 bytes)
@@ -0,0 +1,1 @@+xAnà E»æsZ`C¤¨ª.²l0ÀТqm\5·¯s îþûú_z¡Õ;(gúÊÆZÅÉF9z´£É¡×Mætòr<wðZ£Ce¢¶ã¹sÆ¢·¤ãH¬3öþÕVxkóàcÏáçøïG~ý¬ËZ}ÕDxFJq´cçÿ½ÅõÒ" ~xÝrÁïuá8qiu¡}.¹ß!å_Há¶ï úÁÜ`5?³¯\s
binary file changed (absent → 243 bytes)
binary file changed (absent → 36 bytes)
binary file changed (absent → 155 bytes)
binary file changed (absent → 513632 bytes)
binary file changed (absent → 5567 bytes)
binary file changed (absent → 487 bytes)
binary file changed (absent → 4179 bytes)
binary file changed (absent → 244 bytes)
@@ -0,0 +1,1 @@+xAnÂ0E»ö)æ qìØ©ªXpz±=Q1 ³àö W`÷ßôËÜÚÔapö«¯" CN-¹@RÈ^5Ä+YÒÂQh ¯l^åÑ!D"Ä>jÆ :¦S@Âàc"åLäÙÞúm^á<?^m*ð]ßð|ïÓµñt?¹ý¢£%8 G4»Ý?vù¬6¿Âµ lKå.Õü*I
binary file changed (absent → 244 bytes)
binary file changed (absent → 13697 bytes)
binary file changed (absent → 272 bytes)
binary file changed (absent → 1152 bytes)
binary file changed (absent → 82 bytes)
file too large to diff
binary file changed (absent → 3984 bytes)
binary file changed (absent → 1133 bytes)
binary file changed (absent → 75 bytes)
binary file changed (absent → 13286 bytes)
binary file changed (absent → 1138 bytes)
binary file changed (absent → 5445 bytes)
binary file changed (absent → 8785 bytes)
binary file changed (absent → 262 bytes)
binary file changed (absent → 521 bytes)
binary file changed (absent → 4780 bytes)
binary file changed (absent → 9778 bytes)
binary file changed (absent → 107 bytes)
binary file changed (absent → 100 bytes)
binary file changed (absent → 1919 bytes)
binary file changed (absent → 39242 bytes)
@@ -0,0 +1,1 @@+xKnÃ0D»Ö)xÔÏ"È"ÈLnZQã(zûÚWÈnæó0¥Õ:wp~øè«*x(Çà¨$)zÑ,¤9Å$ÙçÀQÌï¸êg?`æ"4MMÉÚÄTT08ïѱý»pi·¿®Ï¹üÀ§ìå¾çóWçåXZ=Cv68`@4Ý>v}omd~tÚ"`ÕÚ^*æ²K
binary file changed (absent → 3363 bytes)
binary file changed (absent → 272 bytes)
binary file changed (absent → 6252 bytes)
binary file changed (absent → 52183 bytes)
binary file changed (absent → 136 bytes)
binary file changed (absent → 1554 bytes)
binary file changed (absent → 26705 bytes)
binary file changed (absent → 21992 bytes)
binary file changed (absent → 4886 bytes)
binary file changed (absent → 6403 bytes)
binary file changed (absent → 16081 bytes)
binary file changed (absent → 159997 bytes)
binary file changed (absent → 6754 bytes)
binary file changed (absent → 80 bytes)
binary file changed (absent → 7599 bytes)
binary file changed (absent → 17388 bytes)
binary file changed (absent → 94853 bytes)
binary file changed (absent → 662399 bytes)
binary file changed (absent → 1514 bytes)
binary file changed (absent → 1813 bytes)
binary file changed (absent → 297 bytes)
binary file changed (absent → 42041 bytes)
binary file changed (absent → 73 bytes)
binary file changed (absent → 4195 bytes)
binary file changed (absent → 4867 bytes)
binary file changed (absent → 136 bytes)
@@ -0,0 +1,2 @@+xA E]s+. Zhb/2CtQ-5éí½ÿÿâ½äó4¯¦ÅSE4a±ëM:°hc(Ç´§DÙ÷ªÒ,¥i°ïô17´ÓY'ÁÿÄ«hmÏiÖi*éëQ÷½H[ª\öqÓ¦ô> óú@ññ®É¿zH¤ð¦×¨É¢¾üGÿ
binary file changed (absent → 169 bytes)
binary file changed (absent → 243 bytes)
binary file changed (absent → 8653 bytes)
binary file changed (absent → 1161 bytes)
binary file changed (absent → 216 bytes)
binary file changed (absent → 24169 bytes)
binary file changed (absent → 244 bytes)
binary file changed (absent → 270 bytes)
binary file changed (absent → 355 bytes)
binary file changed (absent → 4866 bytes)
binary file changed (absent → 142866 bytes)
binary file changed (absent → 15615 bytes)
binary file changed (absent → 715 bytes)
binary file changed (absent → 8225 bytes)
binary file changed (absent → 1549 bytes)
binary file changed (absent → 82 bytes)
binary file changed (absent → 5131 bytes)
binary file changed (absent → 3975 bytes)
binary file changed (absent → 108550 bytes)
binary file changed (absent → 297 bytes)
binary file changed (absent → 244 bytes)
binary file changed (absent → 23317 bytes)
@@ -0,0 +1,1 @@+xSÁnÓ@@"õqé66 ¤,5©4"=õ²ØÉ&]ÕÃzSÑ=q@|¸ò|0»öÆ6J9@VÚ7Oo_v=8Éb×ëööaòùèõøoPd¤ÁWïÈ$QM n£ÏÜzmá`øÄyn¿Z'ê¥=~Á^×VWgý»{ÞóàVÖø5Dµâq khÞ-ùV_.%íú¤Cz»a¾ßª~ØúÏ..ÞŬÇä(åaL¯Ü>ñ_Qp±71Þ2Hß½àvVh·O0^7¨³BdÊ^?Ìitn6ñAõùV£÷ú½-ûèR¥S½ï×&À¨»]zÏõwZëSëwÛhý²n¶zR[ÎmK7²WVú>z(q"1Ì÷©4ñuÚ½ÒdÈèo]i¾!ã6íÂ9ëü¢ÁP¬Ì7"%DdPö#¥¼÷¯#Y')ÍåϹ¤vHTê+ÞQ¼§ÒbNÕUiyx¬¸©ÿ;NÕD£l²LXÆå«¡ý·ûÔÒqåKÁ6géoúÞæï¸rUº<¥øoWüärÁrz"ÞD)Ñq6§|>Í`ªèH%ú ÈNÉ
binary file changed (absent → 222 bytes)
binary file changed (absent → 15 bytes)
binary file changed (absent → 1161 bytes)
binary file changed (absent → 242 bytes)
binary file changed (absent → 7502 bytes)
binary file changed (absent → 243 bytes)
binary file changed (absent → 158 bytes)
binary file changed (absent → 244 bytes)
binary file changed (absent → 27874 bytes)
@@ -1,1 +1,1 @@-02f0974406cb38a71a2bdfe8204e87bd0cd03892+77a0936d0edcb6a31830b464e6cc3eb066beffa9
@@ -1,1 +1,1 @@-02f0974406cb38a71a2bdfe8204e87bd0cd03892+77a0936d0edcb6a31830b464e6cc3eb066beffa9
@@ -1,17 +1,17 @@ name: Euterpea -version: 2.0.4 +version: 2.0.5 Cabal-Version: >= 1.8 license: BSD3 license-file: License -copyright: Copyright (c) 2008-2016 Euterpea authors +copyright: Copyright (c) 2008-2017 Euterpea authors category: Sound stability: experimental build-type: Custom author: Paul Hudak <paul.hudak@yale.edu>, Eric Cheng <eric.cheng@aya.yale.edu>, Hai (Paul) Liu <hai.liu@aya.yale.edu>, - Donya Quick <donyaquick@gmail.com>, - Dan Winograd-Cort <dwincort@gmail.com > + Donya Quick <donyaquick@gmail.com>, + Dan Winograd-Cort <dwincort@gmail.com > maintainer: Donya Quick <donyaquick@gmail.com> bug-reports: https://github.com/Euterpea/Euterpea2/issues homepage: http://www.euterpea.com @@ -27,8 +27,7 @@ MIDI; and low-level audio processing, sound synthesis, and instrument design. extra-source-files: - ReadMe.txt, - Euterpea/Examples/EnableGUI.hs + ReadMe.txt Library hs-source-dirs: . @@ -52,20 +51,21 @@ Euterpea.IO.MIDI.FromMidi2, Euterpea.IO.MIDI.GeneralMidi, Euterpea.IO.MIDI.ToMidi, + Euterpea.IO.MIDI.ToMidi2, Euterpea.IO.MIDI.Play, Euterpea.IO.MIDI.ExportMidiFile, Euterpea.IO.MIDI other-modules: build-depends: base >= 4 && < 5, - arrows == 0.4.4.1, - array>=0.5.0.0 && <=0.5.2.0, - deepseq>=1.3.0.2 && <=1.4.3.0, - random>=1.0.1.1 && <=1.1, - PortMidi==0.1.5.2, - HCodecs == 0.5, - stm==2.4.4.1, - containers>=0.5.5.1 && <=0.5.7.1, + arrows >= 0.4 && < 0.5, + array>=0.5.0.0 && <=0.6, + deepseq>=1.3.0.2 && <=1.5, + random>=1.0.1.1 && <=1.2, + PortMidi==0.1.6.1, + HCodecs == 0.5.1, + stm >= 2.4 && <2.5, + containers>=0.5.5.1 && <0.6, bytestring>=0.10.4.0 && <= 0.10.9, heap >= 1.0 && < 2.0, ghc-prim
@@ -21,7 +21,8 @@ > openInput, openOutput, readEvents, > close, writeShort, getErrorText, terminate, initialize, > PMError (NoError, BufferOverflow), PMStream, -> PMEvent (..), PMMsg (PMMsg)) +> PMEvent (..), PMMsg (PMMsg), +> encodeMsg, decodeMsg) > import Control.Exception (finally) > import Control.Concurrent > import Control.Concurrent.STM.TChan @@ -272,7 +273,7 @@ > else reportError "pollMidiCB" e > Left l -> do > now <- getTimeNow -> case mapMaybe (msgToMidi . message) l of +> case mapMaybe (msgToMidi . decodeMsg . message) l of > [] -> return () > ms -> callback (now, ms) @@ -296,7 +297,7 @@ > else reportError "pollMIDI" e >> return Nothing > Left l -> do > now <- getTimeNow -> case mapMaybe (msgToMidi . message) l of +> case mapMaybe (msgToMidi . decodeMsg . message) l of > [] -> return Nothing > ms -> return $ Just (now, ms) @@ -421,7 +422,7 @@ > if isTrackEnd msg > then return () > else case midiEvent msg of -> Just m -> writeMsg s t m +> Just m -> writeMsg s t $ encodeMsg m > Nothing -> return () > writeMsg s t m = do > e <- writeShort s (PMEvent m (round (t * 1e3))) @@ -486,7 +487,7 @@ > process t msg = if isTrackEnd msg > then return True > else case midiEvent msg of -> Just m -> writeMsg t m +> Just m -> writeMsg t $ encodeMsg m > Nothing -> return False > writeMsg t m = do > e <- writeShort s (PMEvent m (round (t * 1e3))) @@ -650,7 +651,7 @@ > sendEvts start now [] = loop start s fin > sendEvts start now (e@(PMEvent m t):l) = do > let t0 = maybe t id start -> case msgToMidi m of +> case msgToMidi $ decodeMsg m of > Just m' -> do > done <- callback (now + fromIntegral (t - t0) / 1E3, m') > if done then close s >> return () else sendEvts (Just t0) now l
@@ -42,9 +42,9 @@ > perfAlg :: Music1 -> [MEvent] > } -Default parameters are the default pmap+context, allowing for infinite playback, -using a linear channel assignment policy for 16 channels with percussion on -channel 9 (which is channel 10 when indexing from 1), using the default MIDI +Default parameters are the default pmap+context, allowing for infinite playback, +using a linear channel assignment policy for 16 channels with percussion on +channel 9 (which is channel 10 when indexing from 1), using the default MIDI device as set by the operating system, and using a closing offset of 1.0sec. > defParams = PlayParams False (linearCP 16 9) Nothing 1.0 perform1 @@ -68,15 +68,15 @@ > playC :: (ToMusic1 a, NFData a) => PlayParams -> Music a -> IO () > playC p = if strict p then playStrict p else playInf p -Getting a list of all MIDI input and output devices, showing both -their device IDs and names. +Getting a list of all MIDI input and output devices, showing both +their device IDs and names. > devices = do > (devsIn, devsOut) <- getAllDevices > let f (devid, devname) = " "++show devid ++ "\t" ++ name devname ++ "\n" > strIn = concatMap f devsIn > strOut = concatMap f devsOut -> putStrLn "\nInput devices: " >> putStrLn strIn +> putStrLn "\nInput devices: " >> putStrLn strIn > putStrLn "Output devices: " >> putStrLn strOut @@ -85,16 +85,16 @@ ------------------------------------ Strict playback: timing will be as close to perfect as possible, but the -Music value must be finite. Timing will be correct starting from the first -note, even if there is a long computation offset prior to any sound. +Music value must be finite. Timing will be correct starting from the first +note, even if there is a long computation offset prior to any sound. > playStrict :: (ToMusic1 a, NFData a) => PlayParams -> Music a -> IO () > playStrict p m = m `deepseq` -> let x = toMidi (perfAlg p $ toMusic1 m) +> let x = toMidi (perfAlg p $ toMusic1 m) > in x `deepseq` playM' (devID p) x > playM' :: Maybe OutputDeviceID -> Midi -> IO () -> playM' devID midi = handleCtrlC $ do +> playM' devID midi = handleCtrlC $ do > initialize > (maybe (defaultOutput playMidi) playMidi devID) midi > terminate @@ -103,7 +103,7 @@ > handleCtrlC op = onException op terminate -Infinite playback: arbitrarily long music values can be played, although +Infinite playback: arbitrarily long music values can be played, although with the compromise that timing may be imperfect due to lazy evaluation of the Music value. Delays may happen if a section of the Music value is time- consuming to compute. Infinite parallelism is not supported. @@ -115,12 +115,19 @@ > threadDelay $ round (closeDelay p * 1000000) > terminateMidi > return () where +> resolveOutDev Nothing = unsafeOutputID 0 +> resolveOutDev (Just x) = x > handleCtrlC :: IO a -> IO a -> handleCtrlC op = onException op terminateMidi +> handleCtrlC op = onException op (stopMidiOut (resolveOutDev $ devID p) 16) +> stopMidiOut :: OutputDeviceID -> Channel -> IO () +> stopMidiOut dev i = if i<0 then threadDelay 1000000 >> terminateMidi else do +> deliverMidiEvent dev (0, Std $ ControlChange i 123 0) +> stopMidiOut dev (i-1) + > playRec dev [] = return () -> playRec dev (x@(t,m):ms) = -> if t > 0 then threadDelay (toMicroSec t) >> playRec dev ((0,m):ms) else +> playRec dev (x@(t,m):ms) = +> if t > 0 then threadDelay (toMicroSec t) >> playRec dev ((0,m):ms) else > let mNow = x : takeWhile ((<=0).fst) ms > mLater = drop (length mNow - 1) ms > in doMidiOut dev (Just $ mNow) >> playRec dev mLater where @@ -136,13 +143,13 @@ --------------------------------- Music to message conversion will take place differently depending -on the channel assignment method. Using linearCP will assign the first -n instruments to channels 0 through n-1 (or 1 through n). Using -dynamicCP will fill up n channels and then replace the last-used +on the channel assignment method. Using linearCP will assign the first +n instruments to channels 0 through n-1 (or 1 through n). Using +dynamicCP will fill up n channels and then replace the last-used instrument's channel with the new instrument. Some synthesizers only recognize 10 unique channels, others use the -full 16 allowed by general MIDI. Drums are usually on channel 9 +full 16 allowed by general MIDI. Drums are usually on channel 9 (channel 10 when indexing from 1), but not always. Sometimes drums can be assigned to a custom channel. @@ -153,20 +160,20 @@ > type ChannelMap = [(InstrumentName, Channel)] Given an InstrumentName and a ChannelMap, a ChannelMapFun picks a new -channel to assign to the instrument and retruns both that and the +channel to assign to the instrument and retruns both that and the updated ChannelMap. This is done each time a new InstrumentName is encountered (in other words, it is not in the current ChannelMap). > type ChannelMapFun = InstrumentName -> ChannelMap -> (Channel, ChannelMap) -The function below first converts to ANote values and then to Std On/Off +The function below first converts to ANote values and then to Std On/Off pairs. This is needed to avoid timing issues associated with using ANote and trying to call terminateMIDI, since if there is an ANote at the end it will sometimes have its NoteOff lost, which can cause errors. > musicToMsgs' :: (ToMusic1 a) => PlayParams -> Music a -> [(Time, MidiMessage)] -> musicToMsgs' p m = -> let perf = perfAlg p $ toMusic1 m -- obtain the performance +> musicToMsgs' p m = +> let perf = perfAlg p $ toMusic1 m -- obtain the performance > evsA = channelMap (chanPolicy p) [] perf -- time-stamped ANote values > evs = stdMerge evsA -- merged On/Off events sorted by absolute time > times = map fst evs -- absolute times in seconds @@ -175,49 +182,49 @@ > -- stdMerge: converts ANotes into a sorted list of On/Off events > stdMerge :: [(Time, MidiMessage)] -> [(Time, MidiMessage)] > stdMerge [] = [] -> stdMerge ((t,ANote c k v d):es) = -> (t, Std $ NoteOn c k v) : -> stdMerge (insertBy (\(a,b) (x,y) -> compare a x) (t+d, Std $ NoteOff c k v) es) -> stdMerge (e1:es) = e1 : stdMerge es +> stdMerge ((t,ANote c k v d):es) = +> (t, Std $ NoteOn c k v) : +> stdMerge (insertBy (\(a,b) (x,y) -> compare a x) (t+d, Std $ NoteOff c k v) es) +> stdMerge (e1:es) = e1 : stdMerge es > -- channelMap: performs instrument assignment for a list of Events > channelMap :: ChannelMapFun -> ChannelMap -> [MEvent] -> [(Time, MidiMessage)] > channelMap cf cMap [] = [] -> channelMap cf cMap (e:es) = +> channelMap cf cMap (e:es) = > let i = eInst e > ((chan, cMap'), newI) = case lookup i cMap of Nothing -> (cf i cMap, True) > Just x -> ((x, cMap), False) -> e' = (fromRational (eTime e), -> ANote chan (ePitch e) (eVol e) (fromRational $ eDur e)) +> e' = (fromRational (eTime e), +> ANote chan (ePitch e) (eVol e) (fromRational $ eDur e)) > es' = channelMap cf cMap' es > iNum = if i==Percussion then 0 else fromEnum i -> in if newI then (fst e', Std $ ProgramChange chan iNum) : e' : es' -> else e' : es' +> in if newI then (fst e', Std $ ProgramChange chan iNum) : e' : es' +> else e' : es' -The linearCP channel map just fills up channels left to right until it hits -the maximum number and then throws an error. Percussion is handled as a +The linearCP channel map just fills up channels left to right until it hits +the maximum number and then throws an error. Percussion is handled as a special case. > type NumChannels = Int -- maximum number of channels (i.e. 0-15 is 16 channels) > type PercChan = Int -- percussion channel, using indexing from zero -> linearCP :: NumChannels -> PercChan -> ChannelMapFun -> linearCP cLim pChan i cMap = if i==Percussion then (pChan, (i,pChan):cMap) else +> linearCP :: NumChannels -> PercChan -> ChannelMapFun +> linearCP cLim pChan i cMap = if i==Percussion then (pChan, (i,pChan):cMap) else > let n = length $ filter ((/=Percussion). fst) cMap -> newChan = if n>=pChan then n+1 else n -- step over the percussion channel +> newChan = if n>=pChan then n+1 else n -- step over the percussion channel > in if newChan < cLim then (newChan, (i, newChan) : cMap) else -> error ("Cannot use more than "++show cLim++" instruments.") +> error ("Cannot use more than "++show cLim++" instruments.") -For the dynamicCP channel map, new assignements are added in the left side -of the channel map/list. This means that the item farthest to the right +For the dynamicCP channel map, new assignements are added in the left side +of the channel map/list. This means that the item farthest to the right is the oldest and should be replaced when the table is full. Percussion is handled separately. -> dynamicCP :: NumChannels -> PercChan -> ChannelMapFun -> dynamicCP cLim pChan i cMap = +> dynamicCP :: NumChannels -> PercChan -> ChannelMapFun +> dynamicCP cLim pChan i cMap = > if i==Percussion then (pChan, (i, pChan):cMap) else > let cMapNoP = filter ((/=Percussion). fst) cMap > extra = if length cMapNoP == length cMap then [] else [(Percussion, pChan)] -> newChan = snd $ last cMapNoP +> newChan = snd $ last cMapNoP > in if length cMapNoP < cLim - 1 then linearCP cLim pChan i cMap > else (newChan, (i, newChan) : (take (length cMapNoP - 1) cMapNoP)++extra) @@ -226,7 +233,7 @@ instruments are found that are not accounted for, an error is thrown. > predefinedCP :: ChannelMap -> ChannelMapFun -> predefinedCP cMapFixed i _ = case lookup i cMapFixed of +> predefinedCP cMapFixed i _ = case lookup i cMapFixed of > Nothing -> error (show i ++ " is not included in the channel map.") > Just c -> (c, cMapFixed) @@ -254,7 +261,7 @@ > rnf (TempoChange t) = rnf t > rnf x = () -- no other message types are currently used by Euterpea -> instance NFData MidiMessage where +> instance NFData MidiMessage where > rnf (Std m) = rnf m > rnf (ANote c k v d) = rnf c `seq` rnf k `seq` rnf v `seq` rnf d
@@ -0,0 +1,65 @@+ToMidi2: a module for allowing multiple tracks with the same GM instrument. +Author: Donya Quick + +The writeMidi2 function allows use of the CustomInstrument constructor +in a very specific way to permit two tracks that have the same instrument. +The expected format is: + +CustomInstrument "GMInstrumentName UniqueIdentifier" + +For example: + + import Euterpea + import Euterpea.IO.MIDI.ToMidi2 + m = instrument (CustomInstrument "Flute A") (c 4 qn :+: d 4 qn) :=: + instrument (CustomInstrument "Flute B") (c 5 qn) :=: + instrument HonkyTonkPiano (rest hn :+: c 4 hn) + main = writeMidi2 "test.mid" m + +This will create a MIDI file with three tracks, two of which are assigned +the Flute instrument and the third with the HonkyTonkPiano instrument. + +Note: this module does NOT allow specification of particular track numbers. +The order in which the tracks appear in the MIDI file is determined by the +structure of the particular Music value. + +> module Euterpea.IO.MIDI.ToMidi2 (writeMidi2, resolveInstrumentName) where +> import Euterpea.IO.MIDI.ToMidi +> import Euterpea.IO.MIDI.GeneralMidi +> import Euterpea.IO.MIDI.MEvent +> import Euterpea.Music +> import Euterpea.IO.MIDI.ExportMidiFile +> import Data.List +> import Codec.Midi + +> instNameOnly :: String -> String +> instNameOnly [] = [] +> instNameOnly (x:xs) = if x==' ' then [] else x : instNameOnly xs + +> resolveInstrumentName :: InstrumentName -> InstrumentName +> resolveInstrumentName x@(CustomInstrument s) = +> let iName = instNameOnly s +> allInsts = take 128 $ enumFrom AcousticGrandPiano +> i = maybe (-1) id $ findIndex (==iName) $ map show $ allInsts +> in if i >= 0 then allInsts !! i else x +> resolveInstrumentName x = x + +> resolveMEventInsts :: [(InstrumentName, [MEvent])] -> [(InstrumentName, [MEvent])] +> resolveMEventInsts = map f1 where +> f1 (iname, mevs) = (resolveInstrumentName iname, map f2 mevs) +> f2 mev = mev{eInst = resolveInstrumentName (eInst mev)} + + +> writeMidi2 :: ToMusic1 a => FilePath -> Music a -> IO () +> writeMidi2 fn m = exportMidiFile fn $ toMidiUPM2 defUpm $ perform m + +> toMidiUPM2 :: UserPatchMap -> [MEvent] -> Midi +> toMidiUPM2 upm pf = +> let split = resolveMEventInsts $ splitByInst pf +> insts = map fst split +> rightMap = if (allValid upm insts) then upm +> else (makeGMMap insts) +> in Midi (if length split == 1 then SingleTrack +> else MultiTrack) +> (TicksPerBeat division) +> (map (fromAbsTime . mevsToMessages rightMap) split)
@@ -9,18 +9,18 @@ > type Octave = Int > type Pitch = (PitchClass, Octave) > type Dur = Rational -> data PitchClass = Cff | Cf | C | Dff | Cs | Df | Css | D | Eff | Ds +> data PitchClass = Cff | Cf | C | Dff | Cs | Df | Css | D | Eff | Ds > | Ef | Fff | Dss | E | Ff | Es | F | Gff | Ess | Fs -> | Gf | Fss | G | Aff | Gs | Af | Gss | A | Bff | As +> | Gf | Fss | G | Aff | Gs | Af | Gss | A | Bff | As > | Bf | Ass | B | Bs | Bss > deriving (Show, Eq, Ord, Read, Enum, Bounded) -> data Primitive a = Note Dur a -> | Rest Dur +> data Primitive a = Note Dur a +> | Rest Dur > deriving (Show, Eq, Ord) -> data Music a = -> Prim (Primitive a) -- primitive value +> data Music a = +> Prim (Primitive a) -- primitive value > | Music a :+: Music a -- sequential composition > | Music a :=: Music a -- parallel composition > | Modify Control (Music a) -- modifier @@ -35,26 +35,26 @@ > | Custom String -- for user-specified controls > deriving (Show, Eq, Ord) -> data Mode = Major | Minor | -> Ionian | Dorian | Phrygian | Lydian | Mixolydian | Aeolian | Locrian | +> data Mode = Major | Minor | +> Ionian | Dorian | Phrygian | Lydian | Mixolydian | Aeolian | Locrian | > CustomMode String > deriving (Show, Eq, Ord) > data InstrumentName = > AcousticGrandPiano | BrightAcousticPiano | ElectricGrandPiano > | HonkyTonkPiano | RhodesPiano | ChorusedPiano -> | Harpsichord | Clavinet | Celesta -> | Glockenspiel | MusicBox | Vibraphone +> | Harpsichord | Clavinet | Celesta +> | Glockenspiel | MusicBox | Vibraphone > | Marimba | Xylophone | TubularBells -> | Dulcimer | HammondOrgan | PercussiveOrgan +> | Dulcimer | HammondOrgan | PercussiveOrgan > | RockOrgan | ChurchOrgan | ReedOrgan > | Accordion | Harmonica | TangoAccordion > | AcousticGuitarNylon | AcousticGuitarSteel | ElectricGuitarJazz > | ElectricGuitarClean | ElectricGuitarMuted | OverdrivenGuitar > | DistortionGuitar | GuitarHarmonics | AcousticBass > | ElectricBassFingered | ElectricBassPicked | FretlessBass -> | SlapBass1 | SlapBass2 | SynthBass1 -> | SynthBass2 | Violin | Viola +> | SlapBass1 | SlapBass2 | SynthBass1 +> | SynthBass2 | Violin | Viola > | Cello | Contrabass | TremoloStrings > | PizzicatoStrings | OrchestralHarp | Timpani > | StringEnsemble1 | StringEnsemble2 | SynthStrings1 @@ -62,8 +62,8 @@ > | SynthVoice | OrchestraHit | Trumpet > | Trombone | Tuba | MutedTrumpet > | FrenchHorn | BrassSection | SynthBrass1 -> | SynthBrass2 | SopranoSax | AltoSax -> | TenorSax | BaritoneSax | Oboe +> | SynthBrass2 | SopranoSax | AltoSax +> | TenorSax | BaritoneSax | Oboe > | Bassoon | EnglishHorn | Clarinet > | Piccolo | Flute | Recorder > | PanFlute | BlownBottle | Shakuhachi @@ -77,8 +77,8 @@ > | FX4Atmosphere | FX5Brightness | FX6Goblins > | FX7Echoes | FX8SciFi | Sitar > | Banjo | Shamisen | Koto -> | Kalimba | Bagpipe | Fiddle -> | Shanai | TinkleBell | Agogo +> | Kalimba | Bagpipe | Fiddle +> | Shanai | TinkleBell | Agogo > | SteelDrums | Woodblock | TaikoDrum > | MelodicDrum | SynthDrum | ReverseCymbal > | GuitarFretNoise | BreathNoise | Seashore @@ -125,7 +125,7 @@ > addVolume :: Volume -> Music Pitch -> Music (Pitch,Volume) > addVolume v = mMap (\p -> (p,v)) -> data NoteAttribute = +> data NoteAttribute = > Volume Int -- MIDI convention: 0=min, 127=max > | Fingering Integer > | Dynamics String @@ -155,6 +155,9 @@ > instance ToMusic1 (AbsPitch) where > toMusic1 = mMap (\a -> (pitch a, [])) +> instance ToMusic1 (AbsPitch, Volume) where +> toMusic1 = mMap (\(p,v) -> (pitch p, [Volume v])) + > note :: Dur -> a -> Music a > note d p = Prim (Note d p) @@ -177,7 +180,7 @@ > keysig pc mo m = Modify (KeySig pc mo) m > cff,cf,c,cs,css,dff,df,d,ds,dss,eff,ef,e,es,ess,fff,ff,f, -> fs,fss,gff,gf,g,gs,gss,aff,af,a,as,ass,bff,bf,b,bs,bss :: +> fs,fss,gff,gf,g,gs,gss,aff,af,a,as,ass,bff,bf,b,bs,bss :: > Octave -> Dur -> Music Pitch > cff o d = note d (Cff, o); cf o d = note d (Cf, o) @@ -200,10 +203,10 @@ > bss o d = note d (Bss, o) -> bn, wn, hn, qn, en, sn, tn, sfn, dwn, dhn, +> bn, wn, hn, qn, en, sn, tn, sfn, dwn, dhn, > dqn, den, dsn, dtn, ddhn, ddqn, dden :: Dur -> bnr, wnr, hnr, qnr, enr, snr, tnr, sfnr, dwnr, dhnr, +> bnr, wnr, hnr, qnr, enr, snr, tnr, sfnr, dwnr, dhnr, > dqnr, denr, dsnr, dtnr, ddhnr, ddqnr, ddenr :: Music Pitch > bn = 2; bnr = rest bn -- brevis rest @@ -228,10 +231,10 @@ The conversion for Pitch and AbsPitch differs from previous versions of Euterpea. In Euterpea 1.x, (C,5) was pitch number 60, which is not -the most common interpretation. While there is no universal standard +the most common interpretation. While there is no universal standard for which octave should be octave 0, it is far more common to have the -pitch number relationship that (C,4) = 60. Since this change has been -requested many times in previous versions of Euterpea, the following +pitch number relationship that (C,4) = 60. Since this change has been +requested many times in previous versions of Euterpea, the following standard is now in place as of version 2.0.0: pitch 0 = (C,-1) @@ -243,16 +246,16 @@ > pcToInt :: PitchClass -> Int > pcToInt pc = case pc of -> Cff -> -2; Cf -> -1; C -> 0; Cs -> 1; Css -> 2; -> Dff -> 0; Df -> 1; D -> 2; Ds -> 3; Dss -> 4; -> Eff -> 2; Ef -> 3; E -> 4; Es -> 5; Ess -> 6; -> Fff -> 3; Ff -> 4; F -> 5; Fs -> 6; Fss -> 7; -> Gff -> 5; Gf -> 6; G -> 7; Gs -> 8; Gss -> 9; +> Cff -> -2; Cf -> -1; C -> 0; Cs -> 1; Css -> 2; +> Dff -> 0; Df -> 1; D -> 2; Ds -> 3; Dss -> 4; +> Eff -> 2; Ef -> 3; E -> 4; Es -> 5; Ess -> 6; +> Fff -> 3; Ff -> 4; F -> 5; Fs -> 6; Fss -> 7; +> Gff -> 5; Gf -> 6; G -> 7; Gs -> 8; Gss -> 9; > Aff -> 7; Af -> 8; A -> 9; As -> 10; Ass -> 11; > Bff -> 9; Bf -> 10; B -> 11; Bs -> 12; Bss -> 13 > pitch :: AbsPitch -> Pitch -> pitch ap = +> pitch ap = > let (oct, n) = divMod ap 12 > in ([C,Cs,D,Ds,E,F,Fs,G,Gs,A,As,B] !! n, oct-1) @@ -288,7 +291,7 @@ > lineToList :: Music a -> [Music a] > lineToList (Prim (Rest 0)) = [] > lineToList (n :+: ns) = n : lineToList ns -> lineToList _ = +> lineToList _ = > error "lineToList: argument not created by function line" > invertAt :: Pitch -> Music Pitch -> Music Pitch @@ -298,7 +301,7 @@ > invertAt1 pRef = mMap (\(p,x) -> (pitch (2 * absPitch pRef - absPitch p),x)) > invert :: Music Pitch -> Music Pitch -> invert m = +> invert m = > let pRef = mFold pFun (++) (++) (flip const) m > in if null pRef then m -- no pitches in the structure! > else invertAt (head pRef) m @@ -306,7 +309,7 @@ > pFun _ = [] > invert1 :: Music (Pitch,a) -> Music (Pitch,a) -> invert1 m = +> invert1 m = > let pRef = mFold pFun (++) (++) (flip const) m > in if null pRef then m -- no pitches! > else invertAt1 (head pRef) m @@ -317,7 +320,7 @@ > retro n@(Prim _) = n > retro (Modify c m) = Modify c (retro m) > retro (m1 :+: m2) = retro m2 :+: retro m1 -> retro (m1 :=: m2) = +> retro (m1 :=: m2) = > let d1 = dur m1 > d2 = dur m2 > in if d1>d2 then retro m1 :=: (rest (d1-d2) :+: retro m2) @@ -360,7 +363,7 @@ > removeZeros :: Music a -> Music a > removeZeros (Prim p) = Prim p -> removeZeros (m1 :+: m2) = +> removeZeros (m1 :+: m2) = > let m'1 = removeZeros m1 > m'2 = removeZeros m2 > in case (m'1,m'2) of @@ -387,12 +390,12 @@ > in d1 ++ map (+(last d1)) (durL m2) > durL (m1 :=: m2) = mergeLD (durL m1) (durL m2) > durL (Modify (Tempo r) m) = map (/r) (durL m) -> durL (Modify _ m) = durL m +> durL (Modify _ m) = durL m > mergeLD :: LazyDur -> LazyDur -> LazyDur > mergeLD [] ld = ld > mergeLD ld [] = ld -> mergeLD ld1@(d1:ds1) ld2@(d2:ds2) = +> mergeLD ld1@(d1:ds1) ld2@(d2:ds2) = > if d1<d2 then d1 : mergeLD ds1 ld2 > else d2 : mergeLD ld1 ds2 @@ -407,7 +410,7 @@ > cutL ld (Prim (Note oldD p)) = note (minL ld oldD) p > cutL ld (Prim (Rest oldD)) = rest (minL ld oldD) > cutL ld (m1 :=: m2) = cutL ld m1 :=: cutL ld m2 -> cutL ld (m1 :+: m2) = +> cutL ld (m1 :+: m2) = > let m'1 = cutL ld m1 > m'2 = cutL (map (\d -> d - dur m'1) ld) m2 > in m'1 :+: m'2 @@ -456,7 +459,7 @@ > fmap = mMap -> mFold :: (Primitive a -> b) -> (b->b->b) -> (b->b->b) -> +> mFold :: (Primitive a -> b) -> (b->b->b) -> (b->b->b) -> > (Control -> b -> b) -> Music a -> b > mFold f (+:) (=:) g m = > let rec = mFold f (+:) (=:) g @@ -483,7 +486,7 @@ > scaleDurations r (Prim (Rest d)) = rest (d/r) > scaleDurations r (m1 :+: m2) = scaleDurations r m1 :+: scaleDurations r m2 > scaleDurations r (m1 :=: m2) = scaleDurations r m1 :=: scaleDurations r m2 -> scaleDurations r (Modify c m) = Modify c (scaleDurations r m) +> scaleDurations r (Modify c m) = Modify c (scaleDurations r m) > changeInstrument :: InstrumentName -> Music a -> Music a > changeInstrument i m = Modify (Instrument i) $ removeInstruments m @@ -494,6 +497,3 @@ > removeInstruments (m1 :+: m2) = removeInstruments m1 :+: removeInstruments m2 > removeInstruments (m1 :=: m2) = removeInstruments m1 :=: removeInstruments m2 > removeInstruments m = m - - -
@@ -1,5 +1,5 @@-Version 2.0.4 -Last modified: 04-July-2017 +Version 2.0.5 +Last modified: 26-June-2018 Website: http://www.euterpea.com _____ _ | ___| | | @@ -10,15 +10,16 @@ | | |_| + +Maintainers: + Donya Quick <donyaquick@gmail.com> + Authors: Paul Hudak Eric Cheng Hai (Paul) Liu Donya Quick Dan Winograd-Cort - -Maintainers: - Donya Quick <donyaquick@gmail.com> Euterpea is a domain-specific language embedded in Haskell for computer music research, education, and development, providing