Compare commits
2313 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| fd83e006ec | |||
| e51574c764 | |||
| 893a1bedbc | |||
| 4621a7b426 | |||
| 4808313e70 | |||
| 1fb9311d82 | |||
| dd34daed42 | |||
| 830428fb06 | |||
| 0ca7ab2cf8 | |||
| a0c39989f5 | |||
| 209d09ae13 | |||
| 0c030f7d9c | |||
| 2d800e99e2 | |||
| 0518ecca14 | |||
| 43b9027611 | |||
| 40ea4f4b46 | |||
| 4f624cb734 | |||
| b03013d6a7 | |||
| 9e79d144de | |||
| 40b3f60cde | |||
| 2b27d243ca | |||
| 2f07c46e20 | |||
| 3da1b540fd | |||
| 92dde81296 | |||
| e2368eb960 | |||
| 3e71a7cb94 | |||
| b92ad830ef | |||
| fc7adccd6f | |||
| 97bf718d0e | |||
| eb6360e1f8 | |||
| 41b1ba146a | |||
| 6450d0cbca | |||
| 4e281350a0 | |||
| e868dad61c | |||
| 4a3d36a176 | |||
| f3dddb6e63 | |||
| 3c3e3b123b | |||
| f02a9935c6 | |||
| 3711735ed9 | |||
| 2c802cc10a | |||
| e2e502970c | |||
| 404d601666 | |||
| 252fc40f78 | |||
| fb21a73b4e | |||
| 138a4c6d92 | |||
| c802bfccef | |||
| fae4959db3 | |||
| 8a67e5cfa2 | |||
| 617def3ef0 | |||
| 4f5aafe59f | |||
| a14383d6cc | |||
| fe1903fb56 | |||
| f0d27e5f91 | |||
| a852669dce | |||
| 3240894cd5 | |||
| 0b679167c9 | |||
| 5ac0a93fba | |||
| f7655d44a2 | |||
| 38e6bfb702 | |||
| 20ede6de59 | |||
| 5c70e6b9ab | |||
| 9bd3b88a58 | |||
| e60281c927 | |||
| 01136ecd51 | |||
| 1212523470 | |||
| 73105b2d4b | |||
| 06ab9cf70e | |||
| a3d4868ef4 | |||
| 815b03855b | |||
| 6750bbb1d7 | |||
| 43c8c4fa29 | |||
| 25b8a95987 | |||
| 99fcd6f816 | |||
| 513c6db0d5 | |||
| 1b7f01b7cc | |||
| a4f21aaa64 | |||
| 39bc2ba65c | |||
| d598f82722 | |||
| c22408cb2a | |||
| 8c3419ed48 | |||
| a98361ebbe | |||
| 999f0783c5 | |||
| 2a6dd2f243 | |||
| f3349221c6 | |||
| 65c7c468cc | |||
| ebdf636759 | |||
| 6b870714a9 | |||
| 708f3ccc3d | |||
| 84f4afa5f2 | |||
| 991e21a712 | |||
| 1a9cf7ab80 | |||
| 9501f1cb9e | |||
| d52cb3708b | |||
| fa8d374613 | |||
| 0d26b0dcc2 | |||
| a6287fd407 | |||
| 16bdf79d4c | |||
| 0b47844606 | |||
| 468759e6ab | |||
| f138774d78 | |||
| 068da3fe83 | |||
| 29b11db13f | |||
| dca6254b35 | |||
| cccec40e87 | |||
| b5d9d8e005 | |||
| 825c5b5282 | |||
| 25ca179389 | |||
| 8bd0592e3f | |||
| 06a0d1b86e | |||
| 41b2c2f3bb | |||
| 68faef5b84 | |||
| abf1309fb6 | |||
| d3891af36e | |||
| ed82194260 | |||
| 012e61b105 | |||
| d19d7321d9 | |||
| d4e82d441e | |||
| 2ceea21f76 | |||
| 12327da4fe | |||
| 52d403b0d1 | |||
| ccd35bffe7 | |||
| d1c93525ed | |||
| f0732426f2 | |||
| eedbd1e81c | |||
| 6005e7f27f | |||
| e779e64c95 | |||
| 3baaf99a6e | |||
| 4a86983a6f | |||
| c19d9d3452 | |||
| 79b6d89b3f | |||
| 535e8fd0f7 | |||
| a240abb6c8 | |||
| dd9d30e248 | |||
| 95535ce99e | |||
| df2e82da78 | |||
| a1daec66e2 | |||
| 657ee85136 | |||
| 965306b296 | |||
| 28086f6cb7 | |||
| 45bb010b28 | |||
| 90e0c74721 | |||
| a20341ac2a | |||
| 7635afcb52 | |||
| 74aee374a6 | |||
| 4f70766b95 | |||
| 9f58edd7a8 | |||
| 0f3a575a09 | |||
| ec74fb9ba2 | |||
| ff809f2271 | |||
| 41f52fdd6a | |||
| aa827790bd | |||
| 38e7bd5359 | |||
| 613ce3f976 | |||
| ce8a0a9fd5 | |||
| f59e4ba7c2 | |||
| df469bfdea | |||
| f4642953d4 | |||
| 88b0c30152 | |||
| 01183ad93b | |||
| 3f97af4c8c | |||
| 4c5cb2189b | |||
| 98ff6f990a | |||
| aaa81e00b7 | |||
| 1c44a96768 | |||
| 34fef456c8 | |||
| 7e81918f7b | |||
| 1b840a3db8 | |||
| 4e440fff62 | |||
| 81208acd6e | |||
| af3b5c23c8 | |||
| 9f208417df | |||
| f1ce139997 | |||
| f56dddfa73 | |||
| 2bf1979d4a | |||
| 89cab3cd39 | |||
| 6723d27e06 | |||
| 1c03025090 | |||
| 7a37a63b8e | |||
| 2b5fdad2c8 | |||
| a6f9ede849 | |||
| 78dac1bf4a | |||
| 795909c39e | |||
| 3c042a054d | |||
| 332d66c183 | |||
| de006947ac | |||
| 8a128e5d25 | |||
| 34cbacf424 | |||
| f2fa5e7c88 | |||
| 3b735cc34a | |||
| 238caa1492 | |||
| e5ebe345ad | |||
| 965608356f | |||
| bc1ce7b3ac | |||
| 6a3619c40f | |||
| 50fa9a44be | |||
| 4937a48bd9 | |||
| 987a81c4de | |||
| f5e0500df4 | |||
| 37924887e8 | |||
| 0db7c4131b | |||
| a56a974149 | |||
| af7f3768fa | |||
| 0865db564f | |||
| 2b020040b4 | |||
| 3ae5fcbd7e | |||
| ac4fc4026c | |||
| 9737f68315 | |||
| 2a8c26e390 | |||
| 3c395a82db | |||
| 15c6b9b165 | |||
| 147fd9de4e | |||
| 0bca771a88 | |||
| f4ff63e271 | |||
| bbcf4e8c1d | |||
| 2859357939 | |||
| 2cbb565d09 | |||
| 4d157d2849 | |||
| 64cd763e19 | |||
| c3f387da70 | |||
| 6ebeb3b4f7 | |||
| 2e18baa3c8 | |||
| c9e87a19a9 | |||
| 3b87e29e63 | |||
| e9a20cb985 | |||
| cfc5205569 | |||
| 17dfaa3aae | |||
| 0a3eba08d8 | |||
| add53e28c2 | |||
| f42f655ea9 | |||
| 8304fc1bef | |||
| ea84fee952 | |||
| d6fd52a0e5 | |||
| 0dde7dd88a | |||
| 1323e11701 | |||
| 7ac9944bb3 | |||
| e32e2fd6b8 | |||
| 6bd535bed0 | |||
| 524c88c402 | |||
| 1c096b101d | |||
| 583dc8dbca | |||
| befa4e7528 | |||
| bc6751237c | |||
| 6f3be31b60 | |||
| 8001d86751 | |||
| acca3e5a21 | |||
| d17f835e74 | |||
| ef1f8aa9a0 | |||
| a5ac6eb524 | |||
| ac84d95c6e | |||
| 785f52aa29 | |||
| 051195a991 | |||
| 90ca6675c2 | |||
| 0db9730a50 | |||
| ad2643d8af | |||
| 46840ee787 | |||
| 1e0282a238 | |||
| 259e4f5b38 | |||
| e44229c74e | |||
| 92827cc467 | |||
| dd3d5bc2d4 | |||
| b4c7b3309a | |||
| 010a66487d | |||
| aed35fd811 | |||
| 8d9838012d | |||
| 57d36ec582 | |||
| febc2a50cb | |||
| 74e128bd0f | |||
| c34d78f417 | |||
| 611bd0b2d3 | |||
| 267d38cf20 | |||
| 26456f13e1 | |||
| 2484c44db0 | |||
| a8a13fcbd8 | |||
| 0a193c5645 | |||
| 2450ee1723 | |||
| 67f1cdfcbe | |||
| 549d542a31 | |||
| 2cdb58fb85 | |||
| 68ab232364 | |||
| 871d61f3f9 | |||
| b08bd3746e | |||
| 39ab0b0aa3 | |||
| 5c70cacc13 | |||
| 8c2cd057b2 | |||
| fdc4133ac9 | |||
| 3833c021c0 | |||
| cafbd9461e | |||
| 6995ac1ed2 | |||
| 58e3dc3d52 | |||
| 3e49e79140 | |||
| dec8e81211 | |||
| 4188a5f3f3 | |||
| 31d124582b | |||
| 248e079301 | |||
| 5ce850570f | |||
| 648464a2da | |||
| 29f77003c0 | |||
| dfa38ed7a5 | |||
| 66c918c84b | |||
| 77f55da6c7 | |||
| d6af7cdcb2 | |||
| 0ad8047820 | |||
| 2115f578e9 | |||
| 511b4790d0 | |||
| d6491e21f9 | |||
| cff0f938e5 | |||
| 5418519637 | |||
| b023dbe7b8 | |||
| 8092cd9205 | |||
| 60da5bd338 | |||
| c9e64596a4 | |||
| 08bd5e8b37 | |||
| 125b743e5c | |||
| 9a3eb397f4 | |||
| 84c1f2bfd0 | |||
| d7ba49ea62 | |||
| e47557630e | |||
| f6a1e53f19 | |||
| a0a015f19f | |||
| e3bea63f94 | |||
| 6b154025ab | |||
| b9b2bdb37a | |||
| 7b35c77062 | |||
| c23cfdcfa1 | |||
| 929e9bfac1 | |||
| b51afb74da | |||
| 5a43cd3b64 | |||
| 5d08563975 | |||
| adb83ad3c0 | |||
| 2d0e028993 | |||
| 703d72f20e | |||
| b7d67d8bcc | |||
| 7e5b13aabd | |||
| 7fbcb4b9e6 | |||
| 767a5b3c73 | |||
| a08080bd82 | |||
| 415bf58a06 | |||
| 3b517bfa59 | |||
| e356527a88 | |||
| 07e34cc3cf | |||
| f7f1dd1346 | |||
| 92ccacdc77 | |||
| b5ed2a5351 | |||
| 55c5e4fe92 | |||
| 3b165809cc | |||
| 5c59e6e704 | |||
| ef2f237276 | |||
| 0af14c7a11 | |||
| 8ef777ebbe | |||
| 305d790a19 | |||
| 1f3c1091d3 | |||
| 663b43f4f1 | |||
| 3e0cf0f239 | |||
| 560f34e3df | |||
| 335232207d | |||
| 93e71f0554 | |||
| 0efbf7bc9e | |||
| 3daaa078fb | |||
| 647448a32b | |||
| f7a8e3db35 | |||
| 7747c320a8 | |||
| ebc69bc870 | |||
| 10e2b7ecbf | |||
| 842a698f2b | |||
| f5f519aa80 | |||
| 7db29a2332 | |||
| 6e70ae9958 | |||
| e190fc9416 | |||
| 1a4a0abd1a | |||
| dddacc25a5 | |||
| 2ba2da467c | |||
| f2b64fd111 | |||
| 6623f69476 | |||
| db36574667 | |||
| 3131104595 | |||
| f64bdc4bd4 | |||
| fe6e532c87 | |||
| 5cdeeb47f3 | |||
| bc1bb7f90f | |||
| 0f0141b9dd | |||
| 302c08a14b | |||
| b643f13a6e | |||
| 487d05a73e | |||
| 91ed077eba | |||
| 49433c2074 | |||
| a93ff6ef3c | |||
| 44e10c4f69 | |||
| 7a832c4522 | |||
| 7d0faba424 | |||
| 01d942628b | |||
| 2a9012c94d | |||
| b571926a6d | |||
| f784aa704d | |||
| 153affac12 | |||
| e5d365a3d9 | |||
| 6ffaabeb75 | |||
| 06debb153d | |||
| 51e6786f31 | |||
| 50ef19720d | |||
| db4d62d17c | |||
| 8d24bd720f | |||
| 55556f0e6c | |||
| 7d9cabebff | |||
| 9602c46809 | |||
| 85daab0d5e | |||
| 105faa1935 | |||
| b299b90964 | |||
| 346f1ac293 | |||
| 6e113eea89 | |||
| 54f906b347 | |||
| 4b252bc494 | |||
| b192165fb4 | |||
| f887f4efdd | |||
| b37e54eead | |||
| ea4f458c1d | |||
| 394c76d64f | |||
| d34fc21a50 | |||
| f5435aa2de | |||
| e88f954cbf | |||
| fe897f291b | |||
| fbb6239299 | |||
| ae1633497c | |||
| 00b0e64bd2 | |||
| 2747c87893 | |||
| 2285c79ded | |||
| 230e784b9e | |||
| 4b88168edb | |||
| f29fbdf088 | |||
| 233acff3c4 | |||
| 5e625c9a68 | |||
| da4408835d | |||
| b78b8f0c82 | |||
| 484e8f07a0 | |||
| 504cdadd60 | |||
| 45c10229d9 | |||
| 973b92b8fd | |||
| 6ba0fd25a2 | |||
| 1dde8ad60b | |||
| 45b9cbe2b3 | |||
| 14912229b1 | |||
| 2b64df05e6 | |||
| 01d8d956da | |||
| 4f0d862cbe | |||
| e2ccc6f98e | |||
| d24ada7ab7 | |||
| 54e2316b65 | |||
| 58316a97d5 | |||
| 771ef3e8d5 | |||
| 65ed18960e | |||
| 799f8da333 | |||
| 40bb8bd9dc | |||
| 426f0273cb | |||
| 03ec2d6fc7 | |||
| e4f14fdc61 | |||
| 418c766493 | |||
| 4a65747a4b | |||
| 6dc194ed1d | |||
| 1aa69e77e9 | |||
| 6ac16867b4 | |||
| bbc679a5db | |||
| 592fb2b913 | |||
| f68f3f5f86 | |||
| 5f23860880 | |||
| faf59a7cba | |||
| cc2cb1142b | |||
| eb8be88866 | |||
| e43e1bd7f5 | |||
| eb586b0ed7 | |||
| 75aa96a4a6 | |||
| 10257f485a | |||
| deee6a73f0 | |||
| 84ba0a94c0 | |||
| 5d17cef55f | |||
| 70f1a7e3ca | |||
| 60785eab8e | |||
| 7e9af6f406 | |||
| 6b272ff585 | |||
| fecd679f33 | |||
| 2ab0e3521c | |||
| 9afd6b2858 | |||
| 670c88a64c | |||
| 425ff7cb00 | |||
| 1140b3ae83 | |||
| 5e1d1a52ba | |||
| e394d14cda | |||
| 9f073b6f1b | |||
| b375b130ba | |||
| 3fb6351212 | |||
| 61be01efc1 | |||
| 23bda38be0 | |||
| e6a0dd10a9 | |||
| ef68aa39f8 | |||
| b4b492c417 | |||
| a98e381c8e | |||
| 18f87b97d5 | |||
| c211f1d3fe | |||
| deb84cfdac | |||
| 7ad1b45d11 | |||
| 47161150d7 | |||
| 8e6832407a | |||
| 9166432ccf | |||
| 0107e74986 | |||
| c605e06e07 | |||
| 15a8e58225 | |||
| 4393b6b05f | |||
| ed037698fd | |||
| e870c22f87 | |||
| fd6f03cf74 | |||
| 706f407ed5 | |||
| dd3abd0f16 | |||
| 3fda804217 | |||
| 1d1440ac64 | |||
| 119768001c | |||
| 3ee92a2b33 | |||
| f87b607a53 | |||
| b4ba83ec34 | |||
| d807c4bf87 | |||
| 423f89c908 | |||
| 8d07bc41c9 | |||
| 86ef115e21 | |||
| 1dd8aa9b6f | |||
| f520257463 | |||
| 00dc3088c8 | |||
| e52e4b1a8c | |||
| 0ef3a30b84 | |||
| b375897374 | |||
| 2b2ce8bf3b | |||
| 47c8c15878 | |||
| fa36435290 | |||
| 4b83123cb8 | |||
| 37b17c8c78 | |||
| 51e81f4867 | |||
| ae7b61b040 | |||
| 5a2a534240 | |||
| 09258ca5c1 | |||
| e0966d99a1 | |||
| 66a700729b | |||
| a7266442c2 | |||
| cf34b9c04e | |||
| 530597347c | |||
| c543611897 | |||
| d88596e13c | |||
| c59bbe7c22 | |||
| d4670faafd | |||
| e772fb7d0e | |||
| 29ba8f9f1a | |||
| 61af4d715c | |||
| 535091e36c | |||
| 5b7f8c1816 | |||
| 18216ab1a9 | |||
| 5500ed9209 | |||
| 886f874ff3 | |||
| 466cac328f | |||
| 06caac2619 | |||
| 2691c33b55 | |||
| 7f6844e48d | |||
| a5a929ff72 | |||
| 84b5311257 | |||
| 6a97f6a327 | |||
| dfd02817fa | |||
| 222d2363cd | |||
| 14c117ffd3 | |||
| d5df2ad3ce | |||
| c56b2734fd | |||
| 5eebe73f79 | |||
| 21d400e3c6 | |||
| d270188578 | |||
| fcf9034c2b | |||
| 956e6f95ec | |||
| 50913948a0 | |||
| a5c02556e6 | |||
| 319f40462f | |||
| e5374f60c9 | |||
| 75679c959a | |||
| 628356a294 | |||
| 0fba3b0e1e | |||
| 92a650c827 | |||
| 3bbde05e0e | |||
| 3324bab81e | |||
| 81133769de | |||
| a7d3779dfa | |||
| 75fee8c11f | |||
| 9e11b0a8c6 | |||
| 5861920453 | |||
| eb277cc578 | |||
| 20fd648729 | |||
| 11caba9807 | |||
| 35b4b31d57 | |||
| a5c74e324c | |||
| e1cbf06653 | |||
| 5a1959f0cf | |||
| 7f5074949e | |||
| cf10a8d321 | |||
| a05006b06a | |||
| eb0b96752a | |||
| 2f453eba35 | |||
| 8b2e1fdd9a | |||
| c99b32a8ec | |||
| 92f95e4d94 | |||
| d1011f8d37 | |||
| a486045f7c | |||
| 0e7dc93681 | |||
| a7bbf7a741 | |||
| bfa782f329 | |||
| bed37a148c | |||
| bf19186223 | |||
| 087e75d47f | |||
| 9e2600cac4 | |||
| 3c27c24dec | |||
| 1b81642db5 | |||
| d3a6de3f86 | |||
| f4925a0e6a | |||
| b6b3ca6e6f | |||
| 53572da7de | |||
| 8a0e0265bc | |||
| 0ada7b2da5 | |||
| 1dee1245ff | |||
| e9da6950ee | |||
| 12abd75aed | |||
| 044774ed72 | |||
| cf56b0733b | |||
| 2b0a63003f | |||
| deef98658b | |||
| d9544d006b | |||
| 6a2b2a0aed | |||
| 9060d0cc36 | |||
| b4f9f89480 | |||
| a9b6b284c0 | |||
| da62f50528 | |||
| e84e38cc19 | |||
| 9266a37276 | |||
| ff8ee68852 | |||
| 470b506952 | |||
| de8a447ea5 | |||
| b2f4520ba1 | |||
| a4b1239f45 | |||
| 43350f9066 | |||
| 0988023d30 | |||
| e81e20446f | |||
| 64080250ff | |||
| 4e19f82a2b | |||
| 97743e32c2 | |||
| b8d53fb7e9 | |||
| 390d94ec97 | |||
| e01092a0da | |||
| 312e9a436d | |||
| e43470da7a | |||
| d3e7a26db6 | |||
| 8c2a2a5c9d | |||
| bf2ac6625c | |||
| edb386eb1e | |||
| cc3dd648ac | |||
| 98b2fa6cb5 | |||
| b615c7d0a2 | |||
| 7e06a10f73 | |||
| d46db2f648 | |||
| 6d77aabb23 | |||
| a7b9ee6bcb | |||
| 0e5c221a3c | |||
| 25f7c27043 | |||
| ec3b78e52d | |||
| 4e903c84cf | |||
| ae3ec4e767 | |||
| fd22226242 | |||
| fe1e046ea6 | |||
| 2171aaa35c | |||
| 97024151e4 | |||
| 62dfea43c6 | |||
| a4f8408150 | |||
| 80f2b787ef | |||
| 404cfde33e | |||
| 145bc6da6b | |||
| 69b10e2d7c | |||
| 25e86e8e91 | |||
| 780417ba39 | |||
| 9f159bfb33 | |||
| c2e9cda2d1 | |||
| 1d6ecee64f | |||
| 3ee2826565 | |||
| 0ceea27b44 | |||
| 0dc5837b82 | |||
| b4cbb3380a | |||
| d9cb2baf4a | |||
| 8f456f68ff | |||
| 54a421ec58 | |||
| 6ce420afe3 | |||
| 8028770901 | |||
| d51b93f869 | |||
| ab2b62c980 | |||
| 97fa7cc9ac | |||
| 2648a9b011 | |||
| 1fdc25df75 | |||
| 4db24af59a | |||
| d85c12c385 | |||
| ccd8cbc2a9 | |||
| 1075cce7b3 | |||
| 89f438df71 | |||
| 97027a7ad9 | |||
| 3a8ef2f0d6 | |||
| 4c8e6dead1 | |||
| c19a7408d9 | |||
| c7b9d27b85 | |||
| 30510dc478 | |||
| b788ae52b0 | |||
| ccbd67eab6 | |||
| f21b1eefda | |||
| 6cd55a0a10 | |||
| 0c5c63f4ba | |||
| 3dcd1e793e | |||
| 419294cddd | |||
| b9448a476e | |||
| 238a747414 | |||
| c35433ec7a | |||
| e8c9da0124 | |||
| 18cf6e3210 | |||
| c9205a58ae | |||
| 23d693cd06 | |||
| 724ad0d893 | |||
| 7a0df8553f | |||
| 477215883f | |||
| 05114815ba | |||
| 9080d5fda0 | |||
| 108b43458f | |||
| 3dfd67680c | |||
| 3a2fa18744 | |||
| 370c9f553d | |||
| e80aa008b2 | |||
| 812d91cbf8 | |||
| 942c8bf8a7 | |||
| b6b3e2f1cc | |||
| ee5ff943f3 | |||
| b28f48c1bd | |||
| 49e2fa428f | |||
| 2fcf97e207 | |||
| f3ac3cd1e2 | |||
| dd74757319 | |||
| ab0b5d9890 | |||
| 23f576360c | |||
| d7bd9c7559 | |||
| 9fb91f70aa | |||
| a32a3bcda8 | |||
| 16dc73ff48 | |||
| 0a1321aaae | |||
| 189add1d5a | |||
| 755062fb76 | |||
| 7d577832cd | |||
| c4866afbe0 | |||
| ee60248d19 | |||
| d546813c05 | |||
| f02d9e22d7 | |||
| cc67f45892 | |||
| c6a110ec59 | |||
| 7408396fd4 | |||
| da081b81c4 | |||
| 500ad776ea | |||
| e4a2b69b37 | |||
| 8eaa9bb469 | |||
| b283dd3682 | |||
| 4a5dd73a3c | |||
| 950570b8c3 | |||
| 72beb577b6 | |||
| de65ee08c9 | |||
| c06f4eb7f7 | |||
| 0abe13e3ad | |||
| 2ac808ffa2 | |||
| 58078e2c1e | |||
| 01503f8a7b | |||
| aa99e1220b | |||
| 783375af56 | |||
| 1d9f21f6dc | |||
| 0900c281a3 | |||
| f8c4b16c30 | |||
| c567339718 | |||
| 5eceb593e9 | |||
| 82244f298c | |||
| 3ab20d4ccb | |||
| ccc2644e6b | |||
| 7e2155d937 | |||
| c696d4dbb2 | |||
| f5195ee4f2 | |||
| 9f25ad42c1 | |||
| 1d4dc7d7a9 | |||
| 65d42083e1 | |||
| 6992a67dd9 | |||
| 922f5fa081 | |||
| 199df253ca | |||
| c1f435cc18 | |||
| 858592832f | |||
| a97211b572 | |||
| f196a9fc67 | |||
| 7ea71d8bfa | |||
| 9b615a0add | |||
| 4540034039 | |||
| 29d58f3d84 | |||
| 5290c820b4 | |||
| 22ad15e1f1 | |||
| 80b8abb0ec | |||
| 529ff3197a | |||
| b036bc9e04 | |||
| 9989f33fc2 | |||
| ba4456d24a | |||
| 00718ca03f | |||
| 6b8475b435 | |||
| e51295c79e | |||
| b40aa8636b | |||
| b3645df56f | |||
| 711f0a29ec | |||
| e8e1286572 | |||
| 3d722b9ba0 | |||
| 4ac0a507e0 | |||
| d54908d946 | |||
| 6ba5128f72 | |||
| c96a6c2b1b | |||
| 0b0588cc37 | |||
| 742bb12498 | |||
| f00017c8c1 | |||
| d976d02936 | |||
| 45f0886eba | |||
| 057fef88ae | |||
| 8148626ba3 | |||
| 14ffb8bd9b | |||
| 2f8510db31 | |||
| 38a4d9a6c5 | |||
| 9f5bf5f930 | |||
| 04dad28228 | |||
| a96f817738 | |||
| 8a51a7ea2d | |||
| b3cb511c06 | |||
| 7e3d02d991 | |||
| 412cec73de | |||
| a72c0f7470 | |||
| 45a245d7de | |||
| 1e60481040 | |||
| cda4c738e8 | |||
| f7c176e8ca | |||
| 3e2bc847d8 | |||
| b5092a6212 | |||
| 81d401eab5 | |||
| f986f7dfad | |||
| bcbc1dea25 | |||
| c8326ab328 | |||
| 91c6bc58dc | |||
| c722579c18 | |||
| 2f3bd5b5d9 | |||
| fad80a4f92 | |||
| 1b0a55f44c | |||
| 14b359beb0 | |||
| f32876d4bd | |||
| 13f9dbe582 | |||
| 8dfa2560b1 | |||
| 0c8c3b16d2 | |||
| 3d2812bd35 | |||
| a0e5cbc47f | |||
| d5ddc6acee | |||
| 30750d8763 | |||
| 3e4659076a | |||
| 7cd6327969 | |||
| 77128d298e | |||
| 1e8a379a03 | |||
| b889823b21 | |||
| 9723c553b6 | |||
| 6bfb0371eb | |||
| 1348bf2476 | |||
| 36446f3a58 | |||
| 5a484f7493 | |||
| 244d60fb96 | |||
| 0ae9638aa5 | |||
| 55b893c784 | |||
| c9b6bc848f | |||
| f97310c757 | |||
| 87b3520d02 | |||
| 887de0523f | |||
| a7a1f802a8 | |||
| 163cc62a00 | |||
| 5f566ebf05 | |||
| 1622986467 | |||
| ce6db53e5f | |||
| 292ea0607d | |||
| 3bd7256dc8 | |||
| da2429a1d0 | |||
| 54b5f35125 | |||
| 23bfb03d2a | |||
| 7381b1a696 | |||
| 99bcb7a0f6 | |||
| 17773c5644 | |||
| e1e47c6e43 | |||
| 2bb3d31d5c | |||
| 2a7bf1234b | |||
| e56e462317 | |||
| 3245e992c3 | |||
| 1299fa2801 | |||
| 52c78194b3 | |||
| 58466a304b | |||
| 51c09e94b8 | |||
| 22ccaf7f4a | |||
| b237ebba44 | |||
| 6038bbd6ec | |||
| 84a67ef766 | |||
| e03df97919 | |||
| 7bedd9ef7a | |||
| 72cd670636 | |||
| 9b028e76d2 | |||
| 479b4c9531 | |||
| 28f7d2151e | |||
| cd1560e2b0 | |||
| 87b4c93af9 | |||
| 0393d4ba71 | |||
| 717a0592ba | |||
| a67aff220f | |||
| e47e9c5ac3 | |||
| 4cd9367520 | |||
| c4ac014a0c | |||
| 21c99ca1e8 | |||
| 2cd3e9bcdb | |||
| f56fbbb777 | |||
| b64156aa2b | |||
| 5cb4129bc7 | |||
| bed264ad77 | |||
| f8be0448b0 | |||
| 75fa891e0a | |||
| 21574f7e16 | |||
| 0903a7f1e0 | |||
| c8d385c998 | |||
| 4c35bfbc10 | |||
| 83e322c5f3 | |||
| 6020b964c7 | |||
| b2d5367830 | |||
| d307ee8c2f | |||
| 202f57552a | |||
| 5ba864b6da | |||
| 30e97d5223 | |||
| 69be02c0fd | |||
| eefda551de | |||
| ac7ca07221 | |||
| b043390ec2 | |||
| 4c94ba6d8a | |||
| 7b87519c15 | |||
| 14bfe0293a | |||
| 931d422443 | |||
| 895150eebe | |||
| a5ccae5779 | |||
| 1635132fd5 | |||
| 048aee66cf | |||
| aea2868ce1 | |||
| 723755788d | |||
| 032d0836a7 | |||
| 5736bbc3e4 | |||
| 1b773a8585 | |||
| 3f0214ed6b | |||
| ea83608ee4 | |||
| 8cae1aee80 | |||
| 3db061e670 | |||
| efaaf9b5f9 | |||
| c451bf370d | |||
| 212b187447 | |||
| ac9a6e891f | |||
| 1fc44d5788 | |||
| 913c70557d | |||
| e8b785677d | |||
| 5c17eb69cb | |||
| f6d1e0f299 | |||
| e42bdc2022 | |||
| cf44f499b8 | |||
| 39c984fda8 | |||
| 9c23bc53b7 | |||
| 96b6cd46e6 | |||
| bc6e3879d4 | |||
| 3dcfd0dc98 | |||
| 40b8934487 | |||
| 0d39ac6528 | |||
| 157e1394d6 | |||
| edf78b077e | |||
| 753e64c76c | |||
| 3a072a294d | |||
| 23ae3c69b5 | |||
| bef9c5e2d5 | |||
| 58add24830 | |||
| fdffbfd2c4 | |||
| 357f841e88 | |||
| 7d73ac4405 | |||
| c429a5be25 | |||
| fba58fb1f0 | |||
| dad7f1cf0f | |||
| 8bee7a2b7f | |||
| 632b4e6332 | |||
| f26798bd19 | |||
| 7f4dcefc80 | |||
| d702cb9b49 | |||
| 2081228055 | |||
| f85283c036 | |||
| 14d6ab384d | |||
| 62036745f3 | |||
| 264274685a | |||
| 1babf28491 | |||
| 5a15dc4ddf | |||
| 0f782b385b | |||
| 1534fcfafd | |||
| 1c7ed6e693 | |||
| 0c5c56cf88 | |||
| 53c5275aa4 | |||
| c93d7a1721 | |||
| 9c7dad1bdf | |||
| bfe09b933e | |||
| 823f5779e1 | |||
| 96a18ba1d5 | |||
| b8bb41107c | |||
| ccffb7e380 | |||
| 39088b2035 | |||
| 8db05b8c17 | |||
| ba069ded40 | |||
| 6b8209fdc9 | |||
| ccf62fc525 | |||
| 6bfab6427a | |||
| aab4f85383 | |||
| 99b9208896 | |||
| 7402e3743d | |||
| 7ddfacb58f | |||
| c7a80418d9 | |||
| e98104dac8 | |||
| 884f668855 | |||
| 2bbe9d1b1f | |||
| 91c3cffe41 | |||
| 60a55aa897 | |||
| 9325a78043 | |||
| cd0e80126c | |||
| 1778c0d7d8 | |||
| b07901f1a0 | |||
| a15a1abb21 | |||
| 7da2eea8f0 | |||
| 596a1af7d9 | |||
| 6b6a7757ce | |||
| 8a6266239c | |||
| d83af679bd | |||
| af005668da | |||
| d07e94056d | |||
| 4d7aab1df4 | |||
| c3cbfecbae | |||
| a9d9553fff | |||
| 5cdf774ea7 | |||
| b75d4beb1a | |||
| 35a0430c81 | |||
| 1b5caa4112 | |||
| cbbb04eb40 | |||
| 7396aaf2c2 | |||
| 555ccce4ee | |||
| b838d123f8 | |||
| 1d3926e187 | |||
| 194f8fc791 | |||
| c316766144 | |||
| c00b2f9254 | |||
| 35c38e0b5e | |||
| 87ef4eeb36 | |||
| 06f5f0b7c8 | |||
| 9f91ff4734 | |||
| f7936b4709 | |||
| 60965e3a6c | |||
| b5cb2d633c | |||
| 810734718b | |||
| ca48c2e51b | |||
| 86ed2ee72b | |||
| 2abeed069b | |||
| 569106acd3 | |||
| 507d2f8afb | |||
| 54769a823e | |||
| cf3287f8ec | |||
| c5fbc9f05c | |||
| 2940b0f390 | |||
| 442e41f825 | |||
| e95b718cf4 | |||
| 143c08bfcb | |||
| b3902c8950 | |||
| 7210796cb8 | |||
| 949cfe2ceb | |||
| c39f27d5f8 | |||
| c9ac4f06ff | |||
| 674b14faa3 | |||
| a8fdcd30a5 | |||
| db3cb23c1d | |||
| 7972f7a2da | |||
| 8c3d50be28 | |||
| 4198f3062c | |||
| c2a6efc77a | |||
| 6928487aa1 | |||
| e608317e70 | |||
| 64b5d7a519 | |||
| eef41e76d7 | |||
| d583f7f307 | |||
| f97eca34df | |||
| 1363e044ac | |||
| 9967d4eadd | |||
| 2972de1047 | |||
| 38db4115fc | |||
| 0e824914b2 | |||
| 7832a6d1d8 | |||
| 0cce93a1f8 | |||
| 679f2480c9 | |||
| db7ca2c7ca | |||
| e2850df07e | |||
| 48def2fecb | |||
| ba236ad108 | |||
| 9a28402b90 | |||
| 8c705cc4ea | |||
| 24aaa24b5c | |||
| fd795a7eeb | |||
| abdc254e55 | |||
| f843b7e2e3 | |||
| eea86ab891 | |||
| d7a452588c | |||
| 56d9418119 | |||
| 0109104027 | |||
| c9c965ef85 | |||
| af3adf5244 | |||
| 43f97b4da1 | |||
| 63f07db303 | |||
| 2e9ca89dd3 | |||
| 8586aeabe8 | |||
| c031b4d5d0 | |||
| d91b3464a4 | |||
| 650d94e1a6 | |||
| 543134a6d2 | |||
| ab2626f9df | |||
| d50f9249d6 | |||
| 10a9753183 | |||
| 1e8718fe87 | |||
| 678d0b87d0 | |||
| 319dfce300 | |||
| c3e86933d0 | |||
| 936acf8c10 | |||
| 358d402cd0 | |||
| d11593eb5c | |||
| 4bdedc7fde | |||
| 9be625d6e8 | |||
| 898b245bb2 | |||
| be37f10fed | |||
| a87f651b4d | |||
| 575195a283 | |||
| 5621ee4239 | |||
| f5c4e67aef | |||
| 2f7de9d696 | |||
| 9cee723e92 | |||
| 4a1c0fedca | |||
| b510958f9e | |||
| d6c8bb35b4 | |||
| 4899674b6c | |||
| 4eeed5376f | |||
| 77ad538e68 | |||
| b699aca65b | |||
| ffd19fe961 | |||
| 208912ceac | |||
| 89c253ce41 | |||
| b1d4508d90 | |||
| 8249dc8559 | |||
| 59fe4f8a36 | |||
| acb493665d | |||
| 73123bc313 | |||
| 947aa1342c | |||
| 20c8f9fe31 | |||
| 66ee3bc217 | |||
| 031a2a1b1e | |||
| 9c87b73ad5 | |||
| 97139a530f | |||
| b483b1e380 | |||
| d9126eeb2c | |||
| d8048e136f | |||
| fd64fea279 | |||
| 667fd24c84 | |||
| 9ffb38d6be | |||
| 13397feccf | |||
| 57b05fb6d4 | |||
| 41a2c25b5a | |||
| b214249290 | |||
| 8dad1c382b | |||
| 6713a47d38 | |||
| 02e0223fe8 | |||
| 6c4add67e1 | |||
| 2b7324c06e | |||
| c95bd6cadf | |||
| d73694d3e6 | |||
| 5d607f9484 | |||
| 816c38e9e4 | |||
| 09130e5dcd | |||
| b87447787a | |||
| 5a548f8366 | |||
| 023658605e | |||
| 031111014b | |||
| b5b9303e66 | |||
| 3deaa2fad3 | |||
| c3cd4c80b2 | |||
| be3f3c4bf0 | |||
| d1ca8b4470 | |||
| 72e3386c6a | |||
| 4010a6b745 | |||
| 0218957eb5 | |||
| cd65ab7dfa | |||
| c4adf541c1 | |||
| 88e3a22772 | |||
| 191803ad53 | |||
| 1b7be672fa | |||
| 9581325b9c | |||
| 59990acc2a | |||
| 0bf7716332 | |||
| 3339e5dc6a | |||
| 30b3f68ddf | |||
| 75552f2765 | |||
| 4a0bf9fd44 | |||
| fa28098a83 | |||
| 646409cbdf | |||
| 9e8fb89a52 | |||
| 14441e0e53 | |||
| 7f5814c4d8 | |||
| e3afc3587e | |||
| 8a52c44d15 | |||
| e6e18732b5 | |||
| 3f8ae8f1ce | |||
| a79129835c | |||
| 6fcaecdc9f | |||
| 8dc8090888 | |||
| 4db2f1ec7d | |||
| 06fa030260 | |||
| 018f9fc278 | |||
| c0f6d46cd8 | |||
| 8e43b1fe04 | |||
| 04df919a1c | |||
| f82e628f08 | |||
| 07a7c03adb | |||
| e800f8c0a7 | |||
| d02dbef9d2 | |||
| 55262bc6e9 | |||
| 51ed22afb9 | |||
| 0cf32e2946 | |||
| 693ab4d8bc | |||
| e4869b447c | |||
| 547f356131 | |||
| 017ab1b3fd | |||
| 07ef566de1 | |||
| 3c8a29a179 | |||
| f74032d244 | |||
| eb489ac886 | |||
| 986628b8b2 | |||
| da4f5c6f96 | |||
| f09ae196a8 | |||
| 3e702ae2bc | |||
| 490d1c6a8e | |||
| 0e748d98d5 | |||
| c41e893361 | |||
| 2fd8d6916b | |||
| b4eaf1ab5a | |||
| 3c8e9a7f24 | |||
| 67ec72284d | |||
| 754a122aa0 | |||
| 0486d633c6 | |||
| 09b063002b | |||
| 8828f4d0e5 | |||
| 9495cf71fd | |||
| 4d0f70439c | |||
| d3bb5d4fcb | |||
| 61315d4dfb | |||
| 2a123a4760 | |||
| 4689ffb72d | |||
| d2895c7985 | |||
| 6abb9d151e | |||
| 08827efae3 | |||
| 16c05d2c05 | |||
| 4d4d699780 | |||
| ca1ec4b221 | |||
| facb922f3e | |||
| d7987677ac | |||
| 5fbbfa482f | |||
| 7287b5cd3c | |||
| 0692cf304d | |||
| 88ebe7e4c1 | |||
| d647ed60e8 | |||
| 1cb29ece08 | |||
| de8b7fbc5f | |||
| 98d78f7ff9 | |||
| 3d1eb7dcad | |||
| e1c0b5ea24 | |||
| 30820c1bde | |||
| 46b9802902 | |||
| b6fb28de1a | |||
| 17fc4ba5e3 | |||
| 596514f7aa | |||
| 6e3a6f90e9 | |||
| fbd6439bd2 | |||
| f72c735f9e | |||
| 9b23fc5db8 | |||
| aaff188b3b | |||
| 2595d85cca | |||
| 2c96c29938 | |||
| 65919b7037 | |||
| f1bb7c33f1 | |||
| 8e7a4046d0 | |||
| f4e0c6a348 | |||
| 885a5e9f90 | |||
| 22e3e9a18b | |||
| 445cde2dd4 | |||
| 3dd58cf765 | |||
| cd87061749 | |||
| 1311e051d9 | |||
| c9363832fe | |||
| 6ab22e7cbb | |||
| bb13f7f234 | |||
| 13ba253aec | |||
| c58469e234 | |||
| 57a03bc2b5 | |||
| a7b4e0b5c5 | |||
| bbb45e326c | |||
| dfe3e402a8 | |||
| e884da50ea | |||
| 4c576631ad | |||
| 5f6f046d25 | |||
| 65e033c64b | |||
| 07346da740 | |||
| c95f182a90 | |||
| 289c74788e | |||
| 65a8d9278d | |||
| 887c830d56 | |||
| 6db4e08efb | |||
| 4f81bce800 | |||
| 932fcfa8bf | |||
| 314832e35a | |||
| 6a9dd185e6 | |||
| 2172827f43 | |||
| 90e9cd970a | |||
| 845ca95888 | |||
| 92d8d2f8a4 | |||
| 7cd52b2857 | |||
| 9fbd6c6c3f | |||
| 08fdc5fa98 | |||
| 7e362249ff | |||
| 9fa2db0227 | |||
| 4c75a72a90 | |||
| a0b2778161 | |||
| bc6d94cd25 | |||
| e70141e57b | |||
| 2e70b82eaa | |||
| 117ed52091 | |||
| e9d5e53dbe | |||
| e308694521 | |||
| 7e498012ff | |||
| f98bf32be8 | |||
| 0f2ed8c84d | |||
| 8d67cdfaab | |||
| 67ba924ed3 | |||
| 764cfb6a0d | |||
| 4e3c945093 | |||
| 8558bc1d41 | |||
| 03f56419d0 | |||
| 3ee9d24c3f | |||
| 9b1ad6c873 | |||
| 97daaade8a | |||
| 8a1d5a21c3 | |||
| 301a8ba3a4 | |||
| 2d4453968d | |||
| a2580a85a8 | |||
| 8a0e15ff37 | |||
| 8953a73fb1 | |||
| 1a2883ae9a | |||
| a2358ffc41 | |||
| 33eb2786f8 | |||
| c8ec4fd505 | |||
| fe98ab5398 | |||
| 76be7eb1e7 | |||
| 6e32812bc1 | |||
| 50a7be6385 | |||
| 3763c95784 | |||
| 5fa5252648 | |||
| 1e82561a22 | |||
| ba32a52bb6 | |||
| 6027fda0ce | |||
| e5cae87502 | |||
| ba0ec1b4ba | |||
| 2acd6f52f1 | |||
| b520228bc6 | |||
| 343a8241ab | |||
| 00525274a0 | |||
| 2915d9dbd9 | |||
| 0c49e5ba56 | |||
| b65bc45236 | |||
| 94b7e5a227 | |||
| 928572d384 | |||
| 2d1988bb6f | |||
| e007dc3614 | |||
| 2ed929eadc | |||
| f1924fa7ea | |||
| df822513fa | |||
| 762bdaeee1 | |||
| 8003278a55 | |||
| 5f22d30fc9 | |||
| d6dc855511 | |||
| 8f49f2c25e | |||
| f4304ca062 | |||
| 044662e4b7 | |||
| d9d8319c22 | |||
| 56b094767b | |||
| 98bc60cfb7 | |||
| 2aacca76de | |||
| aea615edb3 | |||
| f6b2dfd09f | |||
| 7f9bcfbc7d | |||
| 22cc5af1fe | |||
| 0dc3f1984e | |||
| e74976e645 | |||
| 91278608c5 | |||
| 8e2d765671 | |||
| 2af39e51f8 | |||
| 1504cf8812 | |||
| 3bece35bbd | |||
| ae41ad5d1e | |||
| ee61f7a55c | |||
| 241ddf76d4 | |||
| fe6e73ede9 | |||
| 8dab4c418c | |||
| 41e2c41ecc | |||
| 30108c7855 | |||
| 40ba9db406 | |||
| f1f2941511 | |||
| d886fb118b | |||
| 46d46c49a8 | |||
| 40dd1fb853 | |||
| ab77fc14d5 | |||
| e0d0edc0fc | |||
| 7eb124d99c | |||
| 88f236ccd3 | |||
| 34a0c998cd | |||
| e658df493a | |||
| b2a257b6b0 | |||
| cde577690a | |||
| c85d53cfbe | |||
| 26127cd2f2 | |||
| 42d9140afe | |||
| 52ad28df92 | |||
| 58ba5fd0dd | |||
| 71cc91cc4a | |||
| 6db3463d17 | |||
| 969818db6f | |||
| d4b191d27d | |||
| 6b23f2dfa3 | |||
| 17e6840f92 | |||
| a1f987c016 | |||
| cff805e0a3 | |||
| 25a941666a | |||
| 8c59849ea4 | |||
| f9e569099c | |||
| 6fd6e4eacf | |||
| ce07270973 | |||
| ac05863f72 | |||
| 7f6df7695c | |||
| ed58571079 | |||
| 80fbe8a788 | |||
| 0fdec056fa | |||
| 1915fe831f | |||
| 98c01a40e6 | |||
| 33234d605a | |||
| c6defe9a6d | |||
| 244daba501 | |||
| 43dadcd9e4 | |||
| 90db244b5f | |||
| e98f1205e5 | |||
| 2205f91e5f | |||
| da1dee351d | |||
| 694e9a5fec | |||
| 9ac5d8ad2d | |||
| 706b9f2357 | |||
| 55b3675dee | |||
| dc86563486 | |||
| ebccfa93c3 | |||
| e9f4576d4d | |||
| 880902fecc | |||
| 96cf5b7282 | |||
| f89c9f7ea4 | |||
| 27a4c871fd | |||
| 37190b2caf | |||
| c6b948323e | |||
| ad2957ed98 | |||
| c469bfcb9e | |||
| 3d16be1822 | |||
| ad10d4ee74 | |||
| 3ba3c1ca31 | |||
| 4ad28964de | |||
| 15ce7fb8f7 | |||
| 80a22b6484 | |||
| 8cfac7c6b8 | |||
| 9ac6b4c2c8 | |||
| 861a933b7b | |||
| 58e5404d61 | |||
| 3676fdc4db | |||
| e7a555a953 | |||
| 1e6ba29cd2 | |||
| c5c83882b3 | |||
| ea3bc0518c | |||
| 2d46a1001e | |||
| 4edd7fe647 | |||
| ad5dfab428 | |||
| 85838c1d57 | |||
| 4fbb3ccf66 | |||
| 7f533c6a25 | |||
| 6dab9d54d1 | |||
| 7ed5d12717 | |||
| 23b2c1f902 | |||
| 5d579dd1a8 | |||
| 0ce138341c | |||
| 61b682131e | |||
| a53e3dda75 | |||
| 2220c22c90 | |||
| e3a70e5021 | |||
| af4faaf666 | |||
| f2548570b8 | |||
| d678f1d88b | |||
| f0ce1bff3e | |||
| ab3c23478d | |||
| 4e65e9bfa9 | |||
| 053aeee5d3 | |||
| 1652dc02ab | |||
| 099c2f3593 | |||
| 0378422fcb | |||
| 0760415d08 | |||
| 5730ccaa39 | |||
| aaa7082aa8 | |||
| 5d7815beed | |||
| a0ee2ccce7 | |||
| 110be7f500 | |||
| 52663e8a44 | |||
| 8646647b3e | |||
| a04dac670e | |||
| 81dd71dd71 | |||
| 4d15391c88 | |||
| fc2473f826 | |||
| 000d848f0b | |||
| 3c5007352e | |||
| e0fa497948 | |||
| f082c73539 | |||
| d4f8bd665f | |||
| 58d0db6eab | |||
| 1544ddf0a5 | |||
| 488ec612bb | |||
| 484702a2e5 | |||
| 371058fb9e | |||
| 97b00670f5 | |||
| 704b386cc5 | |||
| aace50ebf4 | |||
| 49201e892b | |||
| 19b8deba66 | |||
| 068c0076af | |||
| 37c93a6ad8 | |||
| 1b1c76da34 | |||
| 5db1aec1d1 | |||
| 05ca5c88ef | |||
| 980167c99b | |||
| 76f8c1e4e2 | |||
| b273d616ad | |||
| c16b895460 | |||
| ec1a4884d9 | |||
| bb4ed8b1db | |||
| 4e54f93477 | |||
| 4ac1772149 | |||
| 3f235c51f6 | |||
| 7bdf0d5156 | |||
| d2a6fd58a3 | |||
| 05098862c5 | |||
| c8dd0246da | |||
| b3c389c0a0 | |||
| 15b9fc9099 | |||
| 1c14c13c2f | |||
| b79b92967f | |||
| f77832fea2 | |||
| 4ce8a17afd | |||
| 702c62c9a2 | |||
| 661059bf0f | |||
| 7fb4c4ce4f | |||
| 52834744fa | |||
| 3e9934e810 | |||
| 556e9b8fee | |||
| ef92c63455 | |||
| ae8858c516 | |||
| 0691486813 | |||
| 49db3bf916 | |||
| 99f28f25b0 | |||
| 27358c8ce8 | |||
| 899fbdfe08 | |||
| eea23a012a | |||
| 2235a53824 | |||
| 52f82f0b94 | |||
| a572b13743 | |||
| 4340a6f8fe | |||
| 4be97dc735 | |||
| 799126df0e | |||
| a65ec178df | |||
| cf4027df38 | |||
| 127b845960 | |||
| e3637b8452 | |||
| 745d36dc76 | |||
| 2355d6a4a0 | |||
| e1965fe7d9 | |||
| 781444d12c | |||
| b6571904ce | |||
| 97b25755e7 | |||
| bdfafb454b | |||
| 0fee20a415 | |||
| 186e0f3b04 | |||
| 2e6c5e590f | |||
| 9d4e715ee7 | |||
| 932e5ec9b8 | |||
| af5fb1d535 | |||
| 2953daebf5 | |||
| dd82b68175 | |||
| 05a081a7b8 | |||
| 9c417d33cc | |||
| 975f92fc84 | |||
| 0097beb84c | |||
| 65e16cc8bb | |||
| 2687155200 | |||
| 49321961e8 | |||
| 65f43637ce | |||
| f37cfc486d | |||
| a337a59fb8 | |||
| ec917e8e2f | |||
| 89d84131a4 | |||
| 2033f60d24 | |||
| d4159430f0 | |||
| 14255a38fc | |||
| 6c5f1b78d7 | |||
| 1f2d3a0132 | |||
| c23e4ed412 | |||
| 8c0118e7ae | |||
| 9d4107a515 | |||
| d07b9c2c11 | |||
| 3108a6a997 | |||
| b734cab6fc | |||
| 08b1bed38b | |||
| df6320eb0a | |||
| 80f1ec0d7e | |||
| 98f4f5a4f0 | |||
| 8feb089f5c | |||
| 2ba3a88ace | |||
| 1f10195c47 | |||
| dc40702b53 | |||
| a9e0e57797 | |||
| 9b47048231 | |||
| c05a3d3549 | |||
| 2083884ae3 | |||
| 2f644c7ed5 | |||
| d17c4a098c | |||
| 96303893bc | |||
| a329f9c84a | |||
| fc96e965ae | |||
| 365a62d63a | |||
| 3a87c3c3ba | |||
| 54dc26b145 | |||
| 78c1629aeb | |||
| bd518ed264 | |||
| 56379bffac | |||
| 11d7a0e394 | |||
| 3ad86a1c1b | |||
| 931f5875cd | |||
| f22b02a762 | |||
| 505f61ff43 | |||
| 0c2efa1253 | |||
| 5921e18be2 | |||
| 5b9e6fe440 | |||
| 35ba7d70dc | |||
| 026b4b8f4c | |||
| c924a50bed | |||
| 574792d2e1 | |||
| ab2eb5a603 | |||
| 3d7f925d52 | |||
| 93b584ff84 | |||
| 705849ca73 | |||
| 1a57f095e8 | |||
| ac9c2e8c4a | |||
| 45f8efec41 | |||
| ef7df2416d | |||
| cb113315f7 | |||
| d61f90a9c2 | |||
| 3d11fb219e | |||
| 4d9a368f96 | |||
| 43220b604c | |||
| 91f28fa87c | |||
| 82547db2db | |||
| 64ac3a4739 | |||
| c90616b963 | |||
| 0ceaa01c3d | |||
| 7d7e503603 | |||
| 7ee81eac0f | |||
| c9a08fc7b2 | |||
| 69ab93a824 | |||
| 179b660eee | |||
| a0ef7be9a5 | |||
| 2a735b14dc | |||
| a294dd8d9b | |||
| dc1522282b | |||
| 528a4c6a02 | |||
| 1770a8b62b | |||
| 77a0a6de95 | |||
| c1fd977e79 | |||
| cbbda93292 | |||
| c6340ce12d | |||
| 7bc739e965 | |||
| 9f988808c7 | |||
| 6e9ce47a4b | |||
| 89f59c0e1c | |||
| 3793919892 | |||
| d1699d50f6 | |||
| b94d950b1e | |||
| d3e77a0f63 | |||
| 965a71ee90 | |||
| fd794b44b2 | |||
| c9dcba17a9 | |||
| 88de4e15b3 | |||
| 7f0c6629b9 | |||
| f6ca39403d | |||
| ea7cf35ea4 | |||
| accea119d9 | |||
| 6ea7b43c90 | |||
| ddfad996a9 | |||
| d786f99094 | |||
| 008563450c | |||
| 69c238a2e6 | |||
| b3fdf170b1 | |||
| 56cc038603 | |||
| 4c83c689a8 | |||
| 2b7953c472 | |||
| 368ef1cea9 | |||
| bd696a6b37 | |||
| a9fc272e39 | |||
| c5952d1ddc | |||
| 656a406377 | |||
| 5fcd6cc510 | |||
| e09b6020a6 | |||
| 84d2d623b6 | |||
| 1694e5bd12 | |||
| 5170e251f9 | |||
| 4697e946d3 | |||
| 9286e3984c | |||
| 88f3d747b7 | |||
| d4427c54ea | |||
| 92ade80557 | |||
| 8138446b8c | |||
| 58ecc7fad4 | |||
| 311cc5c62f | |||
| 4a928ea9fa | |||
| c1eb444a39 | |||
| b5270e0bb3 | |||
| 6cfc31777b | |||
| 0e1e8503e0 | |||
| 974d0b4e91 | |||
| d66832a39c | |||
| d5889a941f | |||
| 6248e986e5 | |||
| 786b98a013 | |||
| f63d8dbf38 | |||
| 15aad09ce7 | |||
| fdd314f7f8 | |||
| 39b456d88c | |||
| d930fb8d3d | |||
| 3ec64eb0fd | |||
| d81c9819b8 | |||
| 98ce1d14c1 | |||
| 69f9ab88b9 | |||
| 1a0676f0eb | |||
| 658923175f | |||
| 877f4340ba | |||
| 35a9ccb41f | |||
| c7c2f9385f | |||
| d1f3dbb9a1 | |||
| cfb30fe975 | |||
| 2d1b378ef2 | |||
| 06bbee2449 | |||
| 85bc300dfa | |||
| 0662adacb9 | |||
| 65a153da6c | |||
| c5ee010640 | |||
| 1b18b4a0ee | |||
| 58765aab6b | |||
| 1483af1baa | |||
| 13979793f6 | |||
| 9c228e7625 | |||
| 6a667b36d1 | |||
| fe37f1968d | |||
| 4565bdd7ce | |||
| 5f3c07ca3b | |||
| 8d1da6a8ca | |||
| ff8e09495d | |||
| e868eef679 | |||
| ea90f781ff | |||
| c1b161b44b | |||
| aa84b2e328 | |||
| ebc1602816 | |||
| dcd6a55529 | |||
| fb258a7416 | |||
| 5aed927887 | |||
| d964bb9f2f | |||
| 87dc7a5b97 | |||
| ae63ca481d | |||
| 8e599103b6 | |||
| af0140e260 | |||
| 9d43907710 | |||
| a3fcd67a82 | |||
| fe3a43e2d4 | |||
| e095047b02 | |||
| 31a106344f | |||
| b0a82aa420 | |||
| c003d6032d | |||
| 1665595138 | |||
| bbccf76b45 | |||
| 1f47fa9243 | |||
| 7b24a12a66 | |||
| 921e7ac3e9 | |||
| 8d807add41 | |||
| 8501fce38b | |||
| 55d7984582 | |||
| 8dbac9c0bd | |||
| 47b8510b0c | |||
| 4e399b41cd | |||
| bdec1e037f | |||
| 9924cce466 | |||
| d3ecbd75af | |||
| 75b65ab2a2 | |||
| eca8825ab4 | |||
| 9f9b7cf885 | |||
| cd695d7f15 | |||
| 9c0ae597cd | |||
| 4461b4c56f | |||
| 93361118b7 | |||
| 50f963f6c6 | |||
| 67c3e47ed4 | |||
| f14cf8289e | |||
| 790aa68621 | |||
| 6d1d61026d | |||
| a4e3ca933b | |||
| 1fb58f9f8e | |||
| 86e0b9386d | |||
| c7c4cf221a | |||
| d6e439244a | |||
| 5ff225fa1b | |||
| 2a77e840cc | |||
| 00272883f6 | |||
| bd6f3b1273 | |||
| 4e9767bb22 | |||
| 1d54b7a266 | |||
| c9506d939a | |||
| 21217824b7 | |||
| 8024df2991 | |||
| f72b6fe717 | |||
| 8d29d25d60 | |||
| af8e7ab984 | |||
| 4289d5de7d | |||
| 83734aff0e | |||
| 617b6728d3 | |||
| 7a8fd6cb20 | |||
| 55da339586 | |||
| 774eae0f2f | |||
| 201b108a54 | |||
| bdbdbcea26 | |||
| f6c1a21cf0 | |||
| c953072a15 | |||
| 93f3e9357b | |||
| 8ea8b49464 | |||
| 62cef44dcb | |||
| a2edc95207 | |||
| 4cd41e3e08 | |||
| b641f993ac | |||
| e2905b6bc9 | |||
| e11b59a80f | |||
| 0ae02e8ad4 | |||
| 2cbdffab86 | |||
| 86eefdb2a8 | |||
| 750399ccd7 | |||
| fb97ca6022 | |||
| cbcaa54173 | |||
| 94e3fca702 | |||
| ffff104554 | |||
| 307a9dd1b2 | |||
| 5dff8ea820 | |||
| 49648fe22d | |||
| 9f037e8980 | |||
| 12f81bcbb9 | |||
| 6636131d3b | |||
| eeea9631ce | |||
| f9d228c30a | |||
| d516f8c4bd | |||
| 5d1c3a0c63 | |||
| 396f2d6050 | |||
| e25b01c3a2 | |||
| b29a24afb0 | |||
| d6d1dba3d2 | |||
| 8b36a9d121 | |||
| 59ed9338d8 | |||
| b444dea63b | |||
| 1816c8bd37 | |||
| c27948a7ee | |||
| 832dc8a585 | |||
| bb121e68a6 | |||
| 1ec26fd789 | |||
| 4ff4a7e3b9 | |||
| 6bb14e45ce | |||
| 45dc804819 | |||
| 81db01ebf1 | |||
| 06c576a945 | |||
| 929b025fd6 | |||
| 7976de05a5 | |||
| 70c88879ab | |||
| 276ee63b99 | |||
| 487f0dde75 | |||
| c8f700930a | |||
| decbe4df45 | |||
| 462f27c129 | |||
| 2d1191697a | |||
| 0b5a0d1e79 | |||
| 0b7eb9f118 | |||
| dc26261065 | |||
| 9bea67fb1c | |||
| 8246bc3418 | |||
| 01e32b58da | |||
| 9d05ff0468 | |||
| 510ccc7f17 | |||
| 43067ed2b8 | |||
| 4e4c9aef15 | |||
| 4031ee5ef0 | |||
| e079291202 | |||
| 826c641668 | |||
| 6ae845fd9e | |||
| a78fd58dca | |||
| a8ae610489 | |||
| b86a1e5797 | |||
| 45552a68ce | |||
| d46655fbb2 | |||
| 87fee8c504 | |||
| 9ff0617807 | |||
| 243939f94f | |||
| 739385bd89 | |||
| 32060f53cd | |||
| 4ee3972f15 | |||
| 00a9cf4a85 | |||
| 1dcd538ad9 | |||
| a8973514ba | |||
| 0ac9e57d28 | |||
| 5460e85c40 | |||
| 432f0ba34c | |||
| 7e01e53445 | |||
| 043fe6edd2 | |||
| ef68e5d0ff | |||
| c6f3a4e062 | |||
| 87ed53c7f6 | |||
| 89e9437b84 | |||
| 1454c46b5f | |||
| 0fac1e9115 | |||
| f3a3358e63 | |||
| 3c122b0bef | |||
| 7940003d06 | |||
| 45b16ff456 | |||
| 9341f4f884 | |||
| 2c20f26784 | |||
| 2a21a449b4 | |||
| 74dc7090fd | |||
| e12ac95d69 | |||
| 34ea7eba9e | |||
| 6d3ba44f55 | |||
| 5a8ad67660 | |||
| f1e442408b | |||
| a946af4463 | |||
| e01cd92d56 | |||
| 923af8c3a6 | |||
| ac04cf57fa | |||
| 1f6c4e01db | |||
| 04135723a2 | |||
| 93fbdb1e6c | |||
| c1de15f840 | |||
| 3be399c555 | |||
| 1f5453075c | |||
| 33a74f1594 | |||
| e4da1224cb | |||
| 5c2a47620c | |||
| 1bfa7609d2 | |||
| 7e8501123a | |||
| c447eeb2c7 | |||
| ad19cea6e0 | |||
| 0ce29863e3 | |||
| 7a7a4844f4 | |||
| a2adbb1ab5 | |||
| a97fc792d8 | |||
| e9a6a1d6f5 | |||
| f245f0ef87 | |||
| a30f431b63 | |||
| 58f48f20e2 | |||
| ee1b02b709 | |||
| 55c790c9ff | |||
| 65b69f3308 | |||
| c67fbd72dd | |||
| 30f57d0824 | |||
| 1c54018111 | |||
| e80e1b6d9f | |||
| 437f00d6de | |||
| fc6d6b1601 | |||
| 9306e36d52 | |||
| 61122a5093 | |||
| a8a4ff8af1 | |||
| 8a857c35ee | |||
| 89ddd7d8e5 | |||
| 8d0c4ccb3b | |||
| 8ee47d5573 | |||
| 9e88011417 | |||
| f8949ee7a1 | |||
| 62aa2d0ba7 | |||
| ace047d625 | |||
| d6277db209 | |||
| 7ebb28327f | |||
| 86931cbde4 | |||
| 6d7be151dc | |||
| 07227b9806 | |||
| 8348d719cd | |||
| 0fcefd865b | |||
| 57c2e9b5f8 | |||
| 7d7fc39035 | |||
| 351105b3df | |||
| cbfc33215b | |||
| 5a93b56673 | |||
| 1f4c69c17a | |||
| f5b19fad20 | |||
| bc60818e9a | |||
| f82c88f016 | |||
| 98e86decad | |||
| aaf2c0ebd4 | |||
| 778b74cae1 | |||
| 43ee1edd97 | |||
| dd7e23740b | |||
| 1acd6da745 | |||
| 3056f91ec5 | |||
| ed03570e1a | |||
| 2ec0e48d06 | |||
| 8b54d59b8c | |||
| f6a4dbabdd | |||
| a71c291bcb | |||
| 55b9ccc2de | |||
| 67d67a3bf6 | |||
| 591de1ecb4 | |||
| 3dad17c263 | |||
| eefc18170d | |||
| 5f84c5339d | |||
| 2d461379ef | |||
| c8123756ff | |||
| 76c7789ee7 | |||
| 13a2e6ef1f | |||
| 0ecb34b850 | |||
| 1f86c48d95 | |||
| 7e1295df9a | |||
| 482b160c8a | |||
| 181eb95b13 | |||
| c0ccd31a3e | |||
| d72b132c57 | |||
| 506912aed7 | |||
| 670d70d3c9 | |||
| 010f7d12f4 | |||
| da684564ea | |||
| fc4c867f27 | |||
| 9ba30c4e20 | |||
| 15334e56cd | |||
| ffa42ff22c | |||
| a7c62dbabc | |||
| eda1e41152 | |||
| af5a5b76ec | |||
| 87f3a0dc16 | |||
| 2c80a80704 | |||
| 301a4c4a95 | |||
| 8fc4a3b724 | |||
| cb6f040005 | |||
| b91c2e4a99 | |||
| 59a71b1454 | |||
| 36f133a5ae | |||
| 74a58c0d09 | |||
| bfa1107781 | |||
| 11397f7667 | |||
| 6e9e8239ef | |||
| af9932d28b | |||
| 87ff8a65e9 | |||
| 7b6f207790 | |||
| 8672008e43 | |||
| c8cd193346 | |||
| be292e5f0b | |||
| 3863dcc9cb | |||
| a2568409fc | |||
| 6567cdd7b5 | |||
| 5bbf55a401 | |||
| 4a530e2146 | |||
| 27ba8f7b60 | |||
| 6bfdb57a5b | |||
| 26e8ea60a5 | |||
| f4ea188ffa | |||
| 1266580420 | |||
| 16d96eed7b | |||
| fa76168683 | |||
| 5f3329b2c9 | |||
| db541f3cfa | |||
| 3e19ba6ca8 | |||
| ac8c082b89 | |||
| 084df2a229 | |||
| 22557070ec | |||
| f8ef66954c | |||
| ef59901e7c | |||
| cfe620ccb5 | |||
| 453b015225 | |||
| c1cf9ae8f6 | |||
| f1414c650e | |||
| 869b041f2f | |||
| 8621fbb015 | |||
| 597e01153e | |||
| d3e5fcd13e | |||
| 3e0f9cc716 | |||
| c7e49c9f57 | |||
| e2ed8ff2bf | |||
| 559c786d0c | |||
| c3a7480961 | |||
| a75e75aef5 | |||
| d45b1207d0 | |||
| 5a9e24dea1 | |||
| dc8132e965 | |||
| 20bcdc1ef6 | |||
| 93c0f61050 | |||
| 3a8c543f8b | |||
| 9e96156451 | |||
| 19aabd6d02 | |||
| 87b5d7bc7b | |||
| 646714b585 | |||
| eba60c30c5 | |||
| e66bb09156 | |||
| 0042b1f80d | |||
| 6d416ee734 | |||
| 97d3a45aff | |||
| 9e9ff44b17 | |||
| f369be148f | |||
| 3a09e446b3 | |||
| 2d0b12e49e | |||
| 55e2f294ac | |||
| 2a4b467f08 | |||
| 2ae9da696a | |||
| 376997c3ef | |||
| e963782b8c | |||
| 86c01aa62c | |||
| 15783d25e7 | |||
| 3243f69f21 | |||
| 10a87f510c | |||
| ca6feeda29 | |||
| cecf778de3 | |||
| fe79ab351a | |||
| dc0a3a6653 | |||
| fed346c285 | |||
| cad9b367a5 | |||
| 6e86146a25 | |||
| 49d9695ad9 | |||
| e15bc6b9ba | |||
| 28093a6dcb | |||
| 2af5498804 | |||
| 2b42d7fdb8 | |||
| 9b3c4faa34 | |||
| 847b3e8b61 | |||
| b1bdd7c89f | |||
| ffe7a11866 | |||
| 8c3188bc7d | |||
| 880196e5a8 | |||
| d523b440e3 | |||
| f2875d5d13 | |||
| b0720333cc | |||
| c3446a10fa | |||
| fbc869eed7 | |||
| e3e4dbbccf | |||
| 7fda645b16 | |||
| ec7f20644d | |||
| 3d5fa91703 | |||
| e8acfb069c | |||
| 4c38ed272d | |||
| acbb4f8e6c | |||
| 13a3fe8a7a | |||
| 3dd3cd4ceb | |||
| 80fcbc8adc | |||
| 33680accea | |||
| 081e593e2b | |||
| b4ffdfab81 | |||
| 1ea4aac799 | |||
| 4d6c292757 | |||
| 655a83c5c5 | |||
| e8b576bc25 | |||
| 01404ed7af | |||
| ad6237f6f7 | |||
| d06c64e1c4 | |||
| b4ad3186dd | |||
| 5f1c0450b3 | |||
| 04b62f77e3 | |||
| 029dff3f40 | |||
| 342f639771 | |||
| b5a2baafe5 | |||
| 781e4e5be4 | |||
| f3dddb5e99 | |||
| 9a5e892cad | |||
| 0317362662 | |||
| 6b403a76e8 | |||
| 6bf6c6fb7b | |||
| 29618bee10 | |||
| db80f682c9 | |||
| e1cdbac5a0 | |||
| 543eb9d217 | |||
| bc963463f3 | |||
| 86b7b3d54b | |||
| 799ba1f954 | |||
| 1a3e39e452 | |||
| 7dc73815ae | |||
| 4caf2c7edd | |||
| 1b9d740244 | |||
| 497ada9c77 | |||
| 73e386dc6f | |||
| 43cfc097de | |||
| 6735fc7911 | |||
| be34dbe608 | |||
| 70102e7cd3 | |||
| 8ad16145f6 | |||
| bb7b18d4e1 | |||
| 4742dedb45 | |||
| 10a9bc62bf | |||
| 8cbbf17519 | |||
| 24f433b938 | |||
| abc69dd3d0 | |||
| bf87aed459 | |||
| 42306f93b3 | |||
| 03ca50fa70 | |||
| 7b1b8bd741 | |||
| a11f25e47b | |||
| a6213ebfc7 | |||
| b95fcf5da1 | |||
| 707e596811 | |||
| 5678041b92 | |||
| 7f850d8fb0 | |||
| 7edc576e9c | |||
| 0041a09576 | |||
| 0f06254ecf | |||
| ff5245ca8a | |||
| fe925ada59 | |||
| b6596f38b9 | |||
| 16fb3f6db5 | |||
| a2e2522612 | |||
| df07e8a65b | |||
| 729f076c3b | |||
| dfc0118b8b | |||
| d9ef062caf | |||
| 2b8ce3b4cf | |||
| a27b855a39 | |||
| 1634b69faf | |||
| 59fa1f90d5 | |||
| e519338a2b | |||
| 7a4870bd97 | |||
| a552e32a9a | |||
| 29c6238b52 | |||
| 38db8eb64b | |||
| 3bbbf8a025 | |||
| 978764cb6b | |||
| 893ecf1af2 | |||
| aa453b4e9e | |||
| f8089d2026 | |||
| 40241b4e97 | |||
| f10408739e | |||
| e1d0ad749b | |||
| 2a5a5b5c1b | |||
| a97ecb8690 | |||
| bc56c00a9a | |||
| 1e3ad2f9ce | |||
| 9c97f07ec9 | |||
| 312108a0d3 | |||
| 5e48be27b8 | |||
| 9ed574b399 | |||
| 4e2f8e305e | |||
| 3d78d93b40 | |||
| 5a2f509104 | |||
| d6288d63c6 | |||
| 96bd020bd3 | |||
| 8dc2aef058 | |||
| d43486f894 | |||
| 229bc0d7e1 | |||
| 7bf9ebf545 | |||
| 1e9302f564 | |||
| a433ae0ff4 | |||
| e5609279da | |||
| afd3b71849 | |||
| 4cc64fa9a8 | |||
| 7f55372727 | |||
| 919b8c5bd1 | |||
| a281027876 | |||
| 72ce653bcf | |||
| 17c8881444 | |||
| 6aabc837a9 | |||
| 233e6f1765 | |||
| 9adc20e4e7 | |||
| bdf16bf601 | |||
| cf03bfa156 | |||
| d4f556836a | |||
| ebb30ec5b0 | |||
| 168d8e3bee | |||
| 654788f2cf | |||
| 06f2076f04 | |||
| fc43a13927 | |||
| 28f80fa113 | |||
| 9ebf1c1431 | |||
| 8795932420 | |||
| be50a5f992 | |||
| 7086f5f84c | |||
| 670487b4dd | |||
| 0ac746df57 | |||
| 7458273634 | |||
| aa386041e7 | |||
| 44e0fa9325 | |||
| 91d214d713 | |||
| 635f673b95 | |||
| 35a82970a3 | |||
| ac9bef0b31 | |||
| f6bb6cc891 | |||
| 56ff747463 |
+5
-1
@@ -1 +1,5 @@
|
||||
CMakeConf
|
||||
build
|
||||
winbuild
|
||||
include/sndio.h
|
||||
include/sys
|
||||
openal-soft.kdev4
|
||||
|
||||
+116
-38
@@ -18,6 +18,16 @@
|
||||
* Or go to http://www.gnu.org/copyleft/lgpl.html
|
||||
*/
|
||||
|
||||
#ifdef _WIN32
|
||||
#ifdef __MINGW32__
|
||||
#define _WIN32_IE 0x501
|
||||
#else
|
||||
#define _WIN32_IE 0x400
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <ctype.h>
|
||||
@@ -25,6 +35,10 @@
|
||||
|
||||
#include "alMain.h"
|
||||
|
||||
#ifdef _WIN32_IE
|
||||
#include <shlobj.h>
|
||||
#endif
|
||||
|
||||
typedef struct ConfigEntry {
|
||||
char *key;
|
||||
char *value;
|
||||
@@ -33,11 +47,11 @@ typedef struct ConfigEntry {
|
||||
typedef struct ConfigBlock {
|
||||
char *name;
|
||||
ConfigEntry *entries;
|
||||
size_t entryCount;
|
||||
unsigned int entryCount;
|
||||
} ConfigBlock;
|
||||
|
||||
static ConfigBlock *cfgBlocks;
|
||||
static size_t cfgCount;
|
||||
static unsigned int cfgCount;
|
||||
|
||||
static char buffer[1024];
|
||||
|
||||
@@ -48,7 +62,7 @@ static void LoadConfigFromFile(FILE *f)
|
||||
|
||||
while(fgets(buffer, sizeof(buffer), f))
|
||||
{
|
||||
size_t i = 0;
|
||||
int i = 0;
|
||||
|
||||
while(isspace(buffer[i]))
|
||||
i++;
|
||||
@@ -60,6 +74,7 @@ static void LoadConfigFromFile(FILE *f)
|
||||
if(buffer[0] == '[')
|
||||
{
|
||||
ConfigBlock *nextBlock;
|
||||
unsigned int i;
|
||||
|
||||
i = 1;
|
||||
while(buffer[i] && buffer[i] != ']')
|
||||
@@ -67,7 +82,7 @@ static void LoadConfigFromFile(FILE *f)
|
||||
|
||||
if(!buffer[i])
|
||||
{
|
||||
AL_PRINT("config parse error: bad line \"%s\"\n", buffer);
|
||||
ERR("config parse error: bad line \"%s\"\n", buffer);
|
||||
continue;
|
||||
}
|
||||
buffer[i] = 0;
|
||||
@@ -77,7 +92,7 @@ static void LoadConfigFromFile(FILE *f)
|
||||
if(buffer[i] && !isspace(buffer[i]))
|
||||
{
|
||||
if(buffer[i] != '#')
|
||||
AL_PRINT("config warning: extra data after block: \"%s\"\n", buffer+i);
|
||||
WARN("config warning: extra data after block: \"%s\"\n", buffer+i);
|
||||
break;
|
||||
}
|
||||
} while(buffer[i]);
|
||||
@@ -88,7 +103,7 @@ static void LoadConfigFromFile(FILE *f)
|
||||
if(strcasecmp(cfgBlocks[i].name, buffer+1) == 0)
|
||||
{
|
||||
nextBlock = cfgBlocks+i;
|
||||
// AL_PRINT("found block '%s'\n", nextBlock->name);
|
||||
TRACE("found block '%s'\n", nextBlock->name);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -98,7 +113,7 @@ static void LoadConfigFromFile(FILE *f)
|
||||
nextBlock = realloc(cfgBlocks, (cfgCount+1)*sizeof(ConfigBlock));
|
||||
if(!nextBlock)
|
||||
{
|
||||
AL_PRINT("config parse error: error reallocating config blocks\n");
|
||||
ERR("config parse error: error reallocating config blocks\n");
|
||||
continue;
|
||||
}
|
||||
cfgBlocks = nextBlock;
|
||||
@@ -109,7 +124,7 @@ static void LoadConfigFromFile(FILE *f)
|
||||
nextBlock->entries = NULL;
|
||||
nextBlock->entryCount = 0;
|
||||
|
||||
// AL_PRINT("found new block '%s'\n", nextBlock->name);
|
||||
TRACE("found new block '%s'\n", nextBlock->name);
|
||||
}
|
||||
curBlock = nextBlock;
|
||||
continue;
|
||||
@@ -123,7 +138,7 @@ static void LoadConfigFromFile(FILE *f)
|
||||
|
||||
if(!buffer[i] || buffer[i] == '#' || i == 0)
|
||||
{
|
||||
AL_PRINT("config parse error: malformed option line: \"%s\"\n", buffer);
|
||||
ERR("config parse error: malformed option line: \"%s\"\n", buffer);
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -136,7 +151,7 @@ static void LoadConfigFromFile(FILE *f)
|
||||
i++;
|
||||
if(buffer[i] != '=')
|
||||
{
|
||||
AL_PRINT("config parse error: option without a value: \"%s\"\n", buffer);
|
||||
ERR("config parse error: option without a value: \"%s\"\n", buffer);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
@@ -147,20 +162,20 @@ static void LoadConfigFromFile(FILE *f)
|
||||
|
||||
/* Check if we already have this option set */
|
||||
ent = curBlock->entries;
|
||||
while((size_t)(ent-curBlock->entries) < curBlock->entryCount)
|
||||
while((unsigned int)(ent-curBlock->entries) < curBlock->entryCount)
|
||||
{
|
||||
if(strcasecmp(ent->key, buffer) == 0)
|
||||
break;
|
||||
ent++;
|
||||
}
|
||||
|
||||
if((size_t)(ent-curBlock->entries) >= curBlock->entryCount)
|
||||
if((unsigned int)(ent-curBlock->entries) >= curBlock->entryCount)
|
||||
{
|
||||
/* Allocate a new option entry */
|
||||
ent = realloc(curBlock->entries, (curBlock->entryCount+1)*sizeof(ConfigEntry));
|
||||
if(!ent)
|
||||
{
|
||||
AL_PRINT("config parse error: error reallocating config entries\n");
|
||||
ERR("config parse error: error reallocating config entries\n");
|
||||
continue;
|
||||
}
|
||||
curBlock->entries = ent;
|
||||
@@ -180,18 +195,19 @@ static void LoadConfigFromFile(FILE *f)
|
||||
i++;
|
||||
do {
|
||||
i--;
|
||||
} while(isspace(buffer[i]));
|
||||
} while(i >= 0 && isspace(buffer[i]));
|
||||
buffer[++i] = 0;
|
||||
|
||||
free(ent->value);
|
||||
ent->value = strdup(buffer);
|
||||
|
||||
// AL_PRINT("found '%s' = '%s'\n", ent->key, ent->value);
|
||||
TRACE("found '%s' = '%s'\n", ent->key, ent->value);
|
||||
}
|
||||
}
|
||||
|
||||
void ReadALConfig(void)
|
||||
{
|
||||
const char *str;
|
||||
FILE *f;
|
||||
|
||||
cfgBlocks = calloc(1, sizeof(ConfigBlock));
|
||||
@@ -199,16 +215,27 @@ void ReadALConfig(void)
|
||||
cfgCount = 1;
|
||||
|
||||
#ifdef _WIN32
|
||||
if(SHGetSpecialFolderPathA(NULL, buffer, CSIDL_APPDATA, FALSE) != FALSE)
|
||||
{
|
||||
size_t p = strlen(buffer);
|
||||
snprintf(buffer+p, sizeof(buffer)-p, "\\alsoft.ini");
|
||||
f = fopen(buffer, "rt");
|
||||
if(f)
|
||||
{
|
||||
LoadConfigFromFile(f);
|
||||
fclose(f);
|
||||
}
|
||||
}
|
||||
#else
|
||||
f = fopen("/etc/openal/config", "r");
|
||||
f = fopen("/etc/openal/alsoft.conf", "r");
|
||||
if(f)
|
||||
{
|
||||
LoadConfigFromFile(f);
|
||||
fclose(f);
|
||||
}
|
||||
if(getenv("HOME") && *(getenv("HOME")))
|
||||
if((str=getenv("HOME")) != NULL && *str)
|
||||
{
|
||||
snprintf(buffer, sizeof(buffer), "%s/.openalrc", getenv("HOME"));
|
||||
snprintf(buffer, sizeof(buffer), "%s/.alsoftrc", str);
|
||||
f = fopen(buffer, "r");
|
||||
if(f)
|
||||
{
|
||||
@@ -217,15 +244,24 @@ void ReadALConfig(void)
|
||||
}
|
||||
}
|
||||
#endif
|
||||
if((str=getenv("ALSOFT_CONF")) != NULL && *str)
|
||||
{
|
||||
f = fopen(str, "r");
|
||||
if(f)
|
||||
{
|
||||
LoadConfigFromFile(f);
|
||||
fclose(f);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void FreeALConfig(void)
|
||||
{
|
||||
size_t i;
|
||||
unsigned int i;
|
||||
|
||||
for(i = 0;i < cfgCount;i++)
|
||||
{
|
||||
size_t j;
|
||||
unsigned int j;
|
||||
for(j = 0;j < cfgBlocks[i].entryCount;j++)
|
||||
{
|
||||
free(cfgBlocks[i].entries[j].key);
|
||||
@@ -241,45 +277,87 @@ void FreeALConfig(void)
|
||||
|
||||
const char *GetConfigValue(const char *blockName, const char *keyName, const char *def)
|
||||
{
|
||||
size_t i, j;
|
||||
unsigned int i, j;
|
||||
|
||||
if(keyName)
|
||||
if(!keyName)
|
||||
return def;
|
||||
|
||||
if(!blockName)
|
||||
blockName = "general";
|
||||
|
||||
for(i = 0;i < cfgCount;i++)
|
||||
{
|
||||
if(!blockName)
|
||||
blockName = "general";
|
||||
if(strcasecmp(cfgBlocks[i].name, blockName) != 0)
|
||||
continue;
|
||||
|
||||
for(i = 0;i < cfgCount;i++)
|
||||
for(j = 0;j < cfgBlocks[i].entryCount;j++)
|
||||
{
|
||||
if(strcasecmp(cfgBlocks[i].name, blockName) != 0)
|
||||
continue;
|
||||
|
||||
for(j = 0;j < cfgBlocks[i].entryCount;j++)
|
||||
if(strcasecmp(cfgBlocks[i].entries[j].key, keyName) == 0)
|
||||
{
|
||||
if(strcasecmp(cfgBlocks[i].entries[j].key, keyName) == 0)
|
||||
TRACE("Found %s:%s = \"%s\"\n", blockName, keyName,
|
||||
cfgBlocks[i].entries[j].value);
|
||||
if(cfgBlocks[i].entries[j].value[0])
|
||||
return cfgBlocks[i].entries[j].value;
|
||||
return def;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
TRACE("Key %s:%s not found\n", blockName, keyName);
|
||||
return def;
|
||||
}
|
||||
|
||||
int GetConfigValueInt(const char *blockName, const char *keyName, int def)
|
||||
int ConfigValueExists(const char *blockName, const char *keyName)
|
||||
{
|
||||
const char *val = GetConfigValue(blockName, keyName, "");
|
||||
|
||||
if(!val[0]) return def;
|
||||
return strtol(val, NULL, 0);
|
||||
return !!val[0];
|
||||
}
|
||||
|
||||
float GetConfigValueFloat(const char *blockName, const char *keyName, float def)
|
||||
int ConfigValueStr(const char *blockName, const char *keyName, const char **ret)
|
||||
{
|
||||
const char *val = GetConfigValue(blockName, keyName, "");
|
||||
if(!val[0]) return 0;
|
||||
|
||||
*ret = val;
|
||||
return 1;
|
||||
}
|
||||
|
||||
int ConfigValueInt(const char *blockName, const char *keyName, int *ret)
|
||||
{
|
||||
const char *val = GetConfigValue(blockName, keyName, "");
|
||||
if(!val[0]) return 0;
|
||||
|
||||
*ret = strtol(val, NULL, 0);
|
||||
return 1;
|
||||
}
|
||||
|
||||
int ConfigValueUInt(const char *blockName, const char *keyName, unsigned int *ret)
|
||||
{
|
||||
const char *val = GetConfigValue(blockName, keyName, "");
|
||||
if(!val[0]) return 0;
|
||||
|
||||
*ret = strtoul(val, NULL, 0);
|
||||
return 1;
|
||||
}
|
||||
|
||||
int ConfigValueFloat(const char *blockName, const char *keyName, float *ret)
|
||||
{
|
||||
const char *val = GetConfigValue(blockName, keyName, "");
|
||||
if(!val[0]) return 0;
|
||||
|
||||
if(!val[0]) return def;
|
||||
#ifdef HAVE_STRTOF
|
||||
return strtof(val, NULL);
|
||||
*ret = strtof(val, NULL);
|
||||
#else
|
||||
return (float)strtod(val, NULL);
|
||||
*ret = (float)strtod(val, NULL);
|
||||
#endif
|
||||
return 1;
|
||||
}
|
||||
|
||||
int GetConfigValueBool(const char *blockName, const char *keyName, int def)
|
||||
{
|
||||
const char *val = GetConfigValue(blockName, keyName, "");
|
||||
|
||||
if(!val[0]) return !!def;
|
||||
return (strcasecmp(val, "true") == 0 || strcasecmp(val, "yes") == 0 ||
|
||||
strcasecmp(val, "on") == 0 || atoi(val) != 0);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,100 @@
|
||||
/**
|
||||
* OpenAL cross platform audio library
|
||||
* Copyright (C) 2011 by Chris Robinson.
|
||||
* 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., 59 Temple Place - Suite 330,
|
||||
* Boston, MA 02111-1307, USA.
|
||||
* Or go to http://www.gnu.org/copyleft/lgpl.html
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "alMain.h"
|
||||
#include "alFilter.h"
|
||||
#include "alAuxEffectSlot.h"
|
||||
#include "alError.h"
|
||||
#include "alu.h"
|
||||
|
||||
|
||||
typedef struct ALdedicatedState {
|
||||
// Must be first in all effects!
|
||||
ALeffectState state;
|
||||
|
||||
ALfloat gains[MaxChannels];
|
||||
} ALdedicatedState;
|
||||
|
||||
|
||||
static ALvoid DedicatedDestroy(ALeffectState *effect)
|
||||
{
|
||||
ALdedicatedState *state = (ALdedicatedState*)effect;
|
||||
free(state);
|
||||
}
|
||||
|
||||
static ALboolean DedicatedDeviceUpdate(ALeffectState *effect, ALCdevice *Device)
|
||||
{
|
||||
(void)effect;
|
||||
(void)Device;
|
||||
return AL_TRUE;
|
||||
}
|
||||
|
||||
static ALvoid DedicatedUpdate(ALeffectState *effect, ALCdevice *device, const ALeffectslot *Slot)
|
||||
{
|
||||
ALdedicatedState *state = (ALdedicatedState*)effect;
|
||||
ALfloat Gain;
|
||||
ALsizei s;
|
||||
|
||||
Gain = Slot->Gain * Slot->effect.Dedicated.Gain;
|
||||
for(s = 0;s < MaxChannels;s++)
|
||||
state->gains[s] = 0.0f;
|
||||
|
||||
if(Slot->effect.type == AL_EFFECT_DEDICATED_DIALOGUE)
|
||||
ComputeAngleGains(device, atan2f(0.0f, 1.0f), 0.0f, Gain, state->gains);
|
||||
else if(Slot->effect.type == AL_EFFECT_DEDICATED_LOW_FREQUENCY_EFFECT)
|
||||
state->gains[LFE] = Gain;
|
||||
}
|
||||
|
||||
static ALvoid DedicatedProcess(ALeffectState *effect, ALuint SamplesToDo, const ALfloat *RESTRICT SamplesIn, ALfloat (*RESTRICT SamplesOut)[BUFFERSIZE])
|
||||
{
|
||||
ALdedicatedState *state = (ALdedicatedState*)effect;
|
||||
const ALfloat *gains = state->gains;
|
||||
ALuint i, c;
|
||||
|
||||
for(c = 0;c < MaxChannels;c++)
|
||||
{
|
||||
for(i = 0;i < SamplesToDo;i++)
|
||||
SamplesOut[c][i] = SamplesIn[i] * gains[c];
|
||||
}
|
||||
}
|
||||
|
||||
ALeffectState *DedicatedCreate(void)
|
||||
{
|
||||
ALdedicatedState *state;
|
||||
ALsizei s;
|
||||
|
||||
state = malloc(sizeof(*state));
|
||||
if(!state)
|
||||
return NULL;
|
||||
|
||||
state->state.Destroy = DedicatedDestroy;
|
||||
state->state.DeviceUpdate = DedicatedDeviceUpdate;
|
||||
state->state.Update = DedicatedUpdate;
|
||||
state->state.Process = DedicatedProcess;
|
||||
|
||||
for(s = 0;s < MaxChannels;s++)
|
||||
state->gains[s] = 0.0f;
|
||||
|
||||
return &state->state;
|
||||
}
|
||||
+184
@@ -0,0 +1,184 @@
|
||||
/**
|
||||
* OpenAL cross platform audio library
|
||||
* Copyright (C) 2009 by Chris Robinson.
|
||||
* 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., 59 Temple Place - Suite 330,
|
||||
* Boston, MA 02111-1307, USA.
|
||||
* Or go to http://www.gnu.org/copyleft/lgpl.html
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <math.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "alMain.h"
|
||||
#include "alFilter.h"
|
||||
#include "alAuxEffectSlot.h"
|
||||
#include "alError.h"
|
||||
#include "alu.h"
|
||||
|
||||
|
||||
typedef struct ALechoState {
|
||||
// Must be first in all effects!
|
||||
ALeffectState state;
|
||||
|
||||
ALfloat *SampleBuffer;
|
||||
ALuint BufferLength;
|
||||
|
||||
// The echo is two tap. The delay is the number of samples from before the
|
||||
// current offset
|
||||
struct {
|
||||
ALuint delay;
|
||||
} Tap[2];
|
||||
ALuint Offset;
|
||||
/* The panning gains for the two taps */
|
||||
ALfloat Gain[2][MaxChannels];
|
||||
|
||||
ALfloat FeedGain;
|
||||
|
||||
FILTER iirFilter;
|
||||
ALfloat history[2];
|
||||
} ALechoState;
|
||||
|
||||
static ALvoid EchoDestroy(ALeffectState *effect)
|
||||
{
|
||||
ALechoState *state = (ALechoState*)effect;
|
||||
if(state)
|
||||
{
|
||||
free(state->SampleBuffer);
|
||||
state->SampleBuffer = NULL;
|
||||
free(state);
|
||||
}
|
||||
}
|
||||
|
||||
static ALboolean EchoDeviceUpdate(ALeffectState *effect, ALCdevice *Device)
|
||||
{
|
||||
ALechoState *state = (ALechoState*)effect;
|
||||
ALuint maxlen, i;
|
||||
|
||||
// Use the next power of 2 for the buffer length, so the tap offsets can be
|
||||
// wrapped using a mask instead of a modulo
|
||||
maxlen = fastf2u(AL_ECHO_MAX_DELAY * Device->Frequency) + 1;
|
||||
maxlen += fastf2u(AL_ECHO_MAX_LRDELAY * Device->Frequency) + 1;
|
||||
maxlen = NextPowerOf2(maxlen);
|
||||
|
||||
if(maxlen != state->BufferLength)
|
||||
{
|
||||
void *temp;
|
||||
|
||||
temp = realloc(state->SampleBuffer, maxlen * sizeof(ALfloat));
|
||||
if(!temp)
|
||||
return AL_FALSE;
|
||||
state->SampleBuffer = temp;
|
||||
state->BufferLength = maxlen;
|
||||
}
|
||||
for(i = 0;i < state->BufferLength;i++)
|
||||
state->SampleBuffer[i] = 0.0f;
|
||||
|
||||
return AL_TRUE;
|
||||
}
|
||||
|
||||
static ALvoid EchoUpdate(ALeffectState *effect, ALCdevice *Device, const ALeffectslot *Slot)
|
||||
{
|
||||
ALechoState *state = (ALechoState*)effect;
|
||||
ALuint frequency = Device->Frequency;
|
||||
ALfloat lrpan, cw, g, gain;
|
||||
ALfloat dirGain;
|
||||
ALuint i;
|
||||
|
||||
state->Tap[0].delay = fastf2u(Slot->effect.Echo.Delay * frequency) + 1;
|
||||
state->Tap[1].delay = fastf2u(Slot->effect.Echo.LRDelay * frequency);
|
||||
state->Tap[1].delay += state->Tap[0].delay;
|
||||
|
||||
lrpan = Slot->effect.Echo.Spread;
|
||||
|
||||
state->FeedGain = Slot->effect.Echo.Feedback;
|
||||
|
||||
cw = cosf(F_PI*2.0f * LOWPASSFREQREF / frequency);
|
||||
g = 1.0f - Slot->effect.Echo.Damping;
|
||||
state->iirFilter.coeff = lpCoeffCalc(g, cw);
|
||||
|
||||
gain = Slot->Gain;
|
||||
for(i = 0;i < MaxChannels;i++)
|
||||
{
|
||||
state->Gain[0][i] = 0.0f;
|
||||
state->Gain[1][i] = 0.0f;
|
||||
}
|
||||
|
||||
dirGain = fabsf(lrpan);
|
||||
|
||||
/* First tap panning */
|
||||
ComputeAngleGains(Device, atan2f(-lrpan, 0.0f), (1.0f-dirGain)*F_PI, gain, state->Gain[0]);
|
||||
|
||||
/* Second tap panning */
|
||||
ComputeAngleGains(Device, atan2f(+lrpan, 0.0f), (1.0f-dirGain)*F_PI, gain, state->Gain[1]);
|
||||
}
|
||||
|
||||
static ALvoid EchoProcess(ALeffectState *effect, ALuint SamplesToDo, const ALfloat *RESTRICT SamplesIn, ALfloat (*RESTRICT SamplesOut)[BUFFERSIZE])
|
||||
{
|
||||
ALechoState *state = (ALechoState*)effect;
|
||||
const ALuint mask = state->BufferLength-1;
|
||||
const ALuint tap1 = state->Tap[0].delay;
|
||||
const ALuint tap2 = state->Tap[1].delay;
|
||||
ALuint offset = state->Offset;
|
||||
ALfloat smp;
|
||||
ALuint i, k;
|
||||
|
||||
for(i = 0;i < SamplesToDo;i++,offset++)
|
||||
{
|
||||
/* First tap */
|
||||
smp = state->SampleBuffer[(offset-tap1) & mask];
|
||||
for(k = 0;k < MaxChannels;k++)
|
||||
SamplesOut[k][i] += smp * state->Gain[0][k];
|
||||
|
||||
/* Second tap */
|
||||
smp = state->SampleBuffer[(offset-tap2) & mask];
|
||||
for(k = 0;k < MaxChannels;k++)
|
||||
SamplesOut[k][i] += smp * state->Gain[1][k];
|
||||
|
||||
// Apply damping and feedback gain to the second tap, and mix in the
|
||||
// new sample
|
||||
smp = lpFilter2P(&state->iirFilter, 0, smp+SamplesIn[i]);
|
||||
state->SampleBuffer[offset&mask] = smp * state->FeedGain;
|
||||
}
|
||||
state->Offset = offset;
|
||||
}
|
||||
|
||||
ALeffectState *EchoCreate(void)
|
||||
{
|
||||
ALechoState *state;
|
||||
|
||||
state = malloc(sizeof(*state));
|
||||
if(!state)
|
||||
return NULL;
|
||||
|
||||
state->state.Destroy = EchoDestroy;
|
||||
state->state.DeviceUpdate = EchoDeviceUpdate;
|
||||
state->state.Update = EchoUpdate;
|
||||
state->state.Process = EchoProcess;
|
||||
|
||||
state->BufferLength = 0;
|
||||
state->SampleBuffer = NULL;
|
||||
|
||||
state->Tap[0].delay = 0;
|
||||
state->Tap[1].delay = 0;
|
||||
state->Offset = 0;
|
||||
|
||||
state->iirFilter.coeff = 0.0f;
|
||||
state->iirFilter.history[0] = 0.0f;
|
||||
state->iirFilter.history[1] = 0.0f;
|
||||
|
||||
return &state->state;
|
||||
}
|
||||
@@ -0,0 +1,204 @@
|
||||
/**
|
||||
* OpenAL cross platform audio library
|
||||
* Copyright (C) 2009 by Chris Robinson.
|
||||
* 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., 59 Temple Place - Suite 330,
|
||||
* Boston, MA 02111-1307, USA.
|
||||
* Or go to http://www.gnu.org/copyleft/lgpl.html
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <math.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "alMain.h"
|
||||
#include "alFilter.h"
|
||||
#include "alAuxEffectSlot.h"
|
||||
#include "alError.h"
|
||||
#include "alu.h"
|
||||
|
||||
|
||||
typedef struct ALmodulatorState {
|
||||
// Must be first in all effects!
|
||||
ALeffectState state;
|
||||
|
||||
enum {
|
||||
SINUSOID,
|
||||
SAWTOOTH,
|
||||
SQUARE
|
||||
} Waveform;
|
||||
|
||||
ALuint index;
|
||||
ALuint step;
|
||||
|
||||
ALfloat Gain[MaxChannels];
|
||||
|
||||
FILTER iirFilter;
|
||||
ALfloat history[1];
|
||||
} ALmodulatorState;
|
||||
|
||||
#define WAVEFORM_FRACBITS 16
|
||||
#define WAVEFORM_FRACONE (1<<WAVEFORM_FRACBITS)
|
||||
#define WAVEFORM_FRACMASK (WAVEFORM_FRACONE-1)
|
||||
|
||||
static __inline ALfloat Sin(ALuint index)
|
||||
{
|
||||
return sinf(index * (F_PI*2.0f / WAVEFORM_FRACONE));
|
||||
}
|
||||
|
||||
static __inline ALfloat Saw(ALuint index)
|
||||
{
|
||||
return index*(2.0f/WAVEFORM_FRACONE) - 1.0f;
|
||||
}
|
||||
|
||||
static __inline ALfloat Square(ALuint index)
|
||||
{
|
||||
return ((index>>(WAVEFORM_FRACBITS-1))&1)*2.0f - 1.0f;
|
||||
}
|
||||
|
||||
|
||||
static __inline ALfloat hpFilter1P(FILTER *iir, ALuint offset, ALfloat input)
|
||||
{
|
||||
ALfloat *history = &iir->history[offset];
|
||||
ALfloat a = iir->coeff;
|
||||
ALfloat output = input;
|
||||
|
||||
output = output + (history[0]-output)*a;
|
||||
history[0] = output;
|
||||
|
||||
return input - output;
|
||||
}
|
||||
|
||||
|
||||
#define DECL_TEMPLATE(func) \
|
||||
static void Process##func(ALmodulatorState *state, ALuint SamplesToDo, \
|
||||
const ALfloat *RESTRICT SamplesIn, \
|
||||
ALfloat (*RESTRICT SamplesOut)[BUFFERSIZE]) \
|
||||
{ \
|
||||
const ALuint step = state->step; \
|
||||
ALuint index = state->index; \
|
||||
ALfloat samp; \
|
||||
ALuint i, k; \
|
||||
\
|
||||
for(i = 0;i < SamplesToDo;i++) \
|
||||
{ \
|
||||
samp = SamplesIn[i]; \
|
||||
\
|
||||
index += step; \
|
||||
index &= WAVEFORM_FRACMASK; \
|
||||
samp *= func(index); \
|
||||
\
|
||||
samp = hpFilter1P(&state->iirFilter, 0, samp); \
|
||||
\
|
||||
for(k = 0;k < MaxChannels;k++) \
|
||||
SamplesOut[k][i] += state->Gain[k] * samp; \
|
||||
} \
|
||||
state->index = index; \
|
||||
}
|
||||
|
||||
DECL_TEMPLATE(Sin)
|
||||
DECL_TEMPLATE(Saw)
|
||||
DECL_TEMPLATE(Square)
|
||||
|
||||
#undef DECL_TEMPLATE
|
||||
|
||||
|
||||
static ALvoid ModulatorDestroy(ALeffectState *effect)
|
||||
{
|
||||
ALmodulatorState *state = (ALmodulatorState*)effect;
|
||||
free(state);
|
||||
}
|
||||
|
||||
static ALboolean ModulatorDeviceUpdate(ALeffectState *effect, ALCdevice *Device)
|
||||
{
|
||||
return AL_TRUE;
|
||||
(void)effect;
|
||||
(void)Device;
|
||||
}
|
||||
|
||||
static ALvoid ModulatorUpdate(ALeffectState *effect, ALCdevice *Device, const ALeffectslot *Slot)
|
||||
{
|
||||
ALmodulatorState *state = (ALmodulatorState*)effect;
|
||||
ALfloat gain, cw, a = 0.0f;
|
||||
ALuint index;
|
||||
|
||||
if(Slot->effect.Modulator.Waveform == AL_RING_MODULATOR_SINUSOID)
|
||||
state->Waveform = SINUSOID;
|
||||
else if(Slot->effect.Modulator.Waveform == AL_RING_MODULATOR_SAWTOOTH)
|
||||
state->Waveform = SAWTOOTH;
|
||||
else if(Slot->effect.Modulator.Waveform == AL_RING_MODULATOR_SQUARE)
|
||||
state->Waveform = SQUARE;
|
||||
|
||||
state->step = fastf2u(Slot->effect.Modulator.Frequency*WAVEFORM_FRACONE /
|
||||
Device->Frequency);
|
||||
if(state->step == 0) state->step = 1;
|
||||
|
||||
cw = cosf(F_PI*2.0f * Slot->effect.Modulator.HighPassCutoff /
|
||||
Device->Frequency);
|
||||
a = (2.0f-cw) - sqrtf(powf(2.0f-cw, 2.0f) - 1.0f);
|
||||
state->iirFilter.coeff = a;
|
||||
|
||||
gain = sqrtf(1.0f/Device->NumChan);
|
||||
gain *= Slot->Gain;
|
||||
for(index = 0;index < MaxChannels;index++)
|
||||
state->Gain[index] = 0.0f;
|
||||
for(index = 0;index < Device->NumChan;index++)
|
||||
{
|
||||
enum Channel chan = Device->Speaker2Chan[index];
|
||||
state->Gain[chan] = gain;
|
||||
}
|
||||
}
|
||||
|
||||
static ALvoid ModulatorProcess(ALeffectState *effect, ALuint SamplesToDo, const ALfloat *RESTRICT SamplesIn, ALfloat (*RESTRICT SamplesOut)[BUFFERSIZE])
|
||||
{
|
||||
ALmodulatorState *state = (ALmodulatorState*)effect;
|
||||
|
||||
switch(state->Waveform)
|
||||
{
|
||||
case SINUSOID:
|
||||
ProcessSin(state, SamplesToDo, SamplesIn, SamplesOut);
|
||||
break;
|
||||
|
||||
case SAWTOOTH:
|
||||
ProcessSaw(state, SamplesToDo, SamplesIn, SamplesOut);
|
||||
break;
|
||||
|
||||
case SQUARE:
|
||||
ProcessSquare(state, SamplesToDo, SamplesIn, SamplesOut);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
ALeffectState *ModulatorCreate(void)
|
||||
{
|
||||
ALmodulatorState *state;
|
||||
|
||||
state = malloc(sizeof(*state));
|
||||
if(!state)
|
||||
return NULL;
|
||||
|
||||
state->state.Destroy = ModulatorDestroy;
|
||||
state->state.DeviceUpdate = ModulatorDeviceUpdate;
|
||||
state->state.Update = ModulatorUpdate;
|
||||
state->state.Process = ModulatorProcess;
|
||||
|
||||
state->index = 0;
|
||||
state->step = 1;
|
||||
|
||||
state->iirFilter.coeff = 0.0f;
|
||||
state->iirFilter.history[0] = 0.0f;
|
||||
|
||||
return &state->state;
|
||||
}
|
||||
+1283
File diff suppressed because it is too large
Load Diff
+34
-25
@@ -18,11 +18,11 @@
|
||||
* Or go to http://www.gnu.org/copyleft/lgpl.html
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include "alMain.h"
|
||||
|
||||
|
||||
@@ -40,18 +40,15 @@ struct RingBuffer {
|
||||
|
||||
RingBuffer *CreateRingBuffer(ALsizei frame_size, ALsizei length)
|
||||
{
|
||||
RingBuffer *ring = calloc(1, sizeof(*ring));
|
||||
RingBuffer *ring = calloc(1, sizeof(*ring) + ((length+1) * frame_size));
|
||||
if(ring)
|
||||
{
|
||||
ring->mem = (ALubyte*)(ring+1);
|
||||
|
||||
ring->frame_size = frame_size;
|
||||
ring->length = length+1;
|
||||
ring->write_pos = 1;
|
||||
ring->mem = malloc((length+1)*frame_size);
|
||||
if(!ring->mem)
|
||||
{
|
||||
free(ring);
|
||||
ring = NULL;
|
||||
}
|
||||
ring->read_pos = 0;
|
||||
ring->write_pos = 0;
|
||||
|
||||
InitializeCriticalSection(&ring->cs);
|
||||
}
|
||||
@@ -63,45 +60,58 @@ void DestroyRingBuffer(RingBuffer *ring)
|
||||
if(ring)
|
||||
{
|
||||
DeleteCriticalSection(&ring->cs);
|
||||
free(ring->mem);
|
||||
free(ring);
|
||||
}
|
||||
}
|
||||
|
||||
ALsizei RingBufferSize(RingBuffer *ring)
|
||||
{
|
||||
return (ring->write_pos-ring->read_pos-1+ring->length) % ring->length;
|
||||
ALsizei s;
|
||||
|
||||
EnterCriticalSection(&ring->cs);
|
||||
s = (ring->write_pos-ring->read_pos+ring->length) % ring->length;
|
||||
LeaveCriticalSection(&ring->cs);
|
||||
|
||||
return s;
|
||||
}
|
||||
|
||||
void WriteRingBuffer(RingBuffer *ring, const ALubyte *data, ALsizei len)
|
||||
{
|
||||
int remain = ring->length - ring->write_pos;
|
||||
int remain;
|
||||
|
||||
EnterCriticalSection(&ring->cs);
|
||||
|
||||
if((ring->read_pos-ring->write_pos+ring->length)%ring->length < len)
|
||||
ring->read_pos = (ring->write_pos+len) % ring->length;
|
||||
remain = (ring->read_pos-ring->write_pos-1+ring->length) % ring->length;
|
||||
if(remain < len) len = remain;
|
||||
|
||||
if(remain < len)
|
||||
if(len > 0)
|
||||
{
|
||||
memcpy(ring->mem+(ring->write_pos*ring->frame_size), data, remain*ring->frame_size);
|
||||
memcpy(ring->mem, data+(remain*ring->frame_size), (len-remain)*ring->frame_size);
|
||||
}
|
||||
else
|
||||
memcpy(ring->mem+(ring->write_pos*ring->frame_size), data, len*ring->frame_size);
|
||||
remain = ring->length - ring->write_pos;
|
||||
if(remain < len)
|
||||
{
|
||||
memcpy(ring->mem+(ring->write_pos*ring->frame_size), data,
|
||||
remain*ring->frame_size);
|
||||
memcpy(ring->mem, data+(remain*ring->frame_size),
|
||||
(len-remain)*ring->frame_size);
|
||||
}
|
||||
else
|
||||
memcpy(ring->mem+(ring->write_pos*ring->frame_size), data,
|
||||
len*ring->frame_size);
|
||||
|
||||
ring->write_pos += len;
|
||||
ring->write_pos %= ring->length;
|
||||
ring->write_pos += len;
|
||||
ring->write_pos %= ring->length;
|
||||
}
|
||||
|
||||
LeaveCriticalSection(&ring->cs);
|
||||
}
|
||||
|
||||
void ReadRingBuffer(RingBuffer *ring, ALubyte *data, ALsizei len)
|
||||
{
|
||||
int remain = ring->length - ring->read_pos;
|
||||
int remain;
|
||||
|
||||
EnterCriticalSection(&ring->cs);
|
||||
|
||||
remain = ring->length - ring->read_pos;
|
||||
if(remain < len)
|
||||
{
|
||||
memcpy(data, ring->mem+(ring->read_pos*ring->frame_size), remain*ring->frame_size);
|
||||
@@ -115,4 +125,3 @@ void ReadRingBuffer(RingBuffer *ring, ALubyte *data, ALsizei len)
|
||||
|
||||
LeaveCriticalSection(&ring->cs);
|
||||
}
|
||||
|
||||
|
||||
+33
-14
@@ -18,16 +18,17 @@
|
||||
* Or go to http://www.gnu.org/copyleft/lgpl.html
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "alMain.h"
|
||||
#include "alThunk.h"
|
||||
|
||||
#define THREAD_STACK_SIZE (1*1024*1024) /* 1MB */
|
||||
|
||||
#ifdef _WIN32
|
||||
|
||||
#include <windows.h>
|
||||
|
||||
typedef struct {
|
||||
ALuint (*func)(ALvoid*);
|
||||
ALvoid *ptr;
|
||||
@@ -47,13 +48,14 @@ static DWORD CALLBACK StarterFunc(void *ptr)
|
||||
|
||||
ALvoid *StartThread(ALuint (*func)(ALvoid*), ALvoid *ptr)
|
||||
{
|
||||
DWORD dummy;
|
||||
ThreadInfo *inf = malloc(sizeof(ThreadInfo));
|
||||
if(!inf) return 0;
|
||||
|
||||
inf->func = func;
|
||||
inf->ptr = ptr;
|
||||
|
||||
inf->thread = CreateThread(NULL, 0, StarterFunc, inf, 0, NULL);
|
||||
inf->thread = CreateThread(NULL, THREAD_STACK_SIZE, StarterFunc, inf, 0, &dummy);
|
||||
if(!inf->thread)
|
||||
{
|
||||
free(inf);
|
||||
@@ -70,6 +72,7 @@ ALuint StopThread(ALvoid *thread)
|
||||
|
||||
WaitForSingleObject(inf->thread, INFINITE);
|
||||
GetExitCodeThread(inf->thread, &ret);
|
||||
CloseHandle(inf->thread);
|
||||
|
||||
free(inf);
|
||||
|
||||
@@ -83,30 +86,44 @@ ALuint StopThread(ALvoid *thread)
|
||||
typedef struct {
|
||||
ALuint (*func)(ALvoid*);
|
||||
ALvoid *ptr;
|
||||
ALuint ret;
|
||||
pthread_t thread;
|
||||
} ThreadInfo;
|
||||
|
||||
static void *StarterFunc(void *ptr)
|
||||
{
|
||||
ThreadInfo *inf = (ThreadInfo*)ptr;
|
||||
ALint ret;
|
||||
|
||||
ret = inf->func(inf->ptr);
|
||||
return (void*)ret;
|
||||
inf->ret = inf->func(inf->ptr);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
ALvoid *StartThread(ALuint (*func)(ALvoid*), ALvoid *ptr)
|
||||
{
|
||||
pthread_attr_t attr;
|
||||
ThreadInfo *inf = malloc(sizeof(ThreadInfo));
|
||||
if(!inf) return 0;
|
||||
if(!inf) return NULL;
|
||||
|
||||
inf->func = func;
|
||||
inf->ptr = ptr;
|
||||
if(pthread_create(&inf->thread, NULL, StarterFunc, inf) != 0)
|
||||
if(pthread_attr_init(&attr) != 0)
|
||||
{
|
||||
free(inf);
|
||||
return NULL;
|
||||
}
|
||||
if(pthread_attr_setstacksize(&attr, THREAD_STACK_SIZE) != 0)
|
||||
{
|
||||
pthread_attr_destroy(&attr);
|
||||
free(inf);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
inf->func = func;
|
||||
inf->ptr = ptr;
|
||||
if(pthread_create(&inf->thread, &attr, StarterFunc, inf) != 0)
|
||||
{
|
||||
pthread_attr_destroy(&attr);
|
||||
free(inf);
|
||||
return NULL;
|
||||
}
|
||||
pthread_attr_destroy(&attr);
|
||||
|
||||
return inf;
|
||||
}
|
||||
@@ -114,12 +131,14 @@ ALvoid *StartThread(ALuint (*func)(ALvoid*), ALvoid *ptr)
|
||||
ALuint StopThread(ALvoid *thread)
|
||||
{
|
||||
ThreadInfo *inf = thread;
|
||||
void *ret;
|
||||
ALuint ret;
|
||||
|
||||
pthread_join(inf->thread, NULL);
|
||||
ret = inf->ret;
|
||||
|
||||
pthread_join(inf->thread, &ret);
|
||||
free(inf);
|
||||
|
||||
return (ALuint)ret;
|
||||
return ret;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
-912
@@ -1,912 +0,0 @@
|
||||
/**
|
||||
* OpenAL cross platform audio library
|
||||
* Copyright (C) 1999-2007 by authors.
|
||||
* 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., 59 Temple Place - Suite 330,
|
||||
* Boston, MA 02111-1307, USA.
|
||||
* Or go to http://www.gnu.org/copyleft/lgpl.html
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <memory.h>
|
||||
#ifdef HAVE_DLFCN_H
|
||||
#include <dlfcn.h>
|
||||
#endif
|
||||
#include "alMain.h"
|
||||
#include "AL/al.h"
|
||||
#include "AL/alc.h"
|
||||
|
||||
#include <alsa/asoundlib.h>
|
||||
|
||||
|
||||
typedef struct {
|
||||
snd_pcm_t *pcmHandle;
|
||||
snd_pcm_format_t format;
|
||||
|
||||
ALvoid *buffer;
|
||||
ALsizei size;
|
||||
|
||||
int killNow;
|
||||
ALvoid *thread;
|
||||
} alsa_data;
|
||||
|
||||
typedef struct {
|
||||
ALCchar *name;
|
||||
int card, dev;
|
||||
} DevMap;
|
||||
|
||||
static void *alsa_handle;
|
||||
#define MAKE_FUNC(f) static typeof(f) * p##f
|
||||
MAKE_FUNC(snd_strerror);
|
||||
MAKE_FUNC(snd_pcm_open);
|
||||
MAKE_FUNC(snd_pcm_close);
|
||||
MAKE_FUNC(snd_pcm_nonblock);
|
||||
MAKE_FUNC(snd_pcm_frames_to_bytes);
|
||||
MAKE_FUNC(snd_pcm_hw_params_malloc);
|
||||
MAKE_FUNC(snd_pcm_hw_params_free);
|
||||
MAKE_FUNC(snd_pcm_hw_params_any);
|
||||
MAKE_FUNC(snd_pcm_hw_params_set_access);
|
||||
MAKE_FUNC(snd_pcm_hw_params_set_format);
|
||||
MAKE_FUNC(snd_pcm_hw_params_set_channels);
|
||||
MAKE_FUNC(snd_pcm_hw_params_set_periods_near);
|
||||
MAKE_FUNC(snd_pcm_hw_params_set_rate_near);
|
||||
MAKE_FUNC(snd_pcm_hw_params_set_rate);
|
||||
MAKE_FUNC(snd_pcm_hw_params_set_buffer_size_near);
|
||||
MAKE_FUNC(snd_pcm_hw_params_set_buffer_size_min);
|
||||
MAKE_FUNC(snd_pcm_hw_params_get_access);
|
||||
MAKE_FUNC(snd_pcm_hw_params);
|
||||
MAKE_FUNC(snd_pcm_prepare);
|
||||
MAKE_FUNC(snd_pcm_start);
|
||||
MAKE_FUNC(snd_pcm_resume);
|
||||
MAKE_FUNC(snd_pcm_state);
|
||||
MAKE_FUNC(snd_pcm_avail_update);
|
||||
MAKE_FUNC(snd_pcm_areas_silence);
|
||||
MAKE_FUNC(snd_pcm_mmap_begin);
|
||||
MAKE_FUNC(snd_pcm_mmap_commit);
|
||||
MAKE_FUNC(snd_pcm_writei);
|
||||
MAKE_FUNC(snd_pcm_drain);
|
||||
MAKE_FUNC(snd_pcm_info_malloc);
|
||||
MAKE_FUNC(snd_pcm_info_free);
|
||||
MAKE_FUNC(snd_pcm_info_set_device);
|
||||
MAKE_FUNC(snd_pcm_info_set_subdevice);
|
||||
MAKE_FUNC(snd_pcm_info_set_stream);
|
||||
MAKE_FUNC(snd_pcm_info_get_name);
|
||||
MAKE_FUNC(snd_ctl_pcm_next_device);
|
||||
MAKE_FUNC(snd_ctl_pcm_info);
|
||||
MAKE_FUNC(snd_ctl_open);
|
||||
MAKE_FUNC(snd_ctl_close);
|
||||
MAKE_FUNC(snd_ctl_card_info_malloc);
|
||||
MAKE_FUNC(snd_ctl_card_info_free);
|
||||
MAKE_FUNC(snd_ctl_card_info);
|
||||
MAKE_FUNC(snd_ctl_card_info_get_name);
|
||||
MAKE_FUNC(snd_card_next);
|
||||
#undef MAKE_FUNC
|
||||
|
||||
#define MAX_DEVICES 16
|
||||
#define MAX_ALL_DEVICES 32
|
||||
|
||||
static DevMap allDevNameMap[MAX_ALL_DEVICES];
|
||||
static ALCchar *alsaDeviceList[MAX_DEVICES];
|
||||
static ALCchar *alsaCaptureDeviceList[MAX_DEVICES];
|
||||
|
||||
static int xrun_recovery(snd_pcm_t *handle, int err)
|
||||
{
|
||||
if (err == -EPIPE)
|
||||
{ /* under-run */
|
||||
err = psnd_pcm_prepare(handle);
|
||||
if(err >= 0)
|
||||
err = psnd_pcm_start(handle);
|
||||
if (err < 0)
|
||||
AL_PRINT("prepare failed: %s\n", psnd_strerror(err));
|
||||
}
|
||||
else if (err == -ESTRPIPE)
|
||||
{
|
||||
while ((err = psnd_pcm_resume(handle)) == -EAGAIN)
|
||||
usleep(1); /* wait until the suspend flag is released */
|
||||
if (err < 0)
|
||||
{
|
||||
err = psnd_pcm_prepare(handle);
|
||||
if(err >= 0)
|
||||
err = psnd_pcm_start(handle);
|
||||
if (err < 0)
|
||||
AL_PRINT("prepare failed: %s\n", psnd_strerror(err));
|
||||
}
|
||||
}
|
||||
return err;
|
||||
}
|
||||
|
||||
|
||||
static ALuint ALSAProc(ALvoid *ptr)
|
||||
{
|
||||
ALCdevice *pDevice = (ALCdevice*)ptr;
|
||||
alsa_data *data = (alsa_data*)pDevice->ExtraData;
|
||||
const snd_pcm_channel_area_t *areas = NULL;
|
||||
snd_pcm_sframes_t avail, commitres;
|
||||
snd_pcm_uframes_t offset, frames;
|
||||
char *WritePtr;
|
||||
int WriteCnt;
|
||||
int err;
|
||||
|
||||
while(!data->killNow)
|
||||
{
|
||||
snd_pcm_state_t state = psnd_pcm_state(data->pcmHandle);
|
||||
if(state == SND_PCM_STATE_XRUN)
|
||||
{
|
||||
err = xrun_recovery(data->pcmHandle, -EPIPE);
|
||||
if (err < 0)
|
||||
{
|
||||
AL_PRINT("XRUN recovery failed: %s\n", psnd_strerror(err));
|
||||
break;
|
||||
}
|
||||
}
|
||||
else if (state == SND_PCM_STATE_SUSPENDED)
|
||||
{
|
||||
err = xrun_recovery(data->pcmHandle, -ESTRPIPE);
|
||||
if (err < 0)
|
||||
{
|
||||
AL_PRINT("SUSPEND recovery failed: %s\n", psnd_strerror(err));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
avail = psnd_pcm_avail_update(data->pcmHandle);
|
||||
if(avail < 0)
|
||||
{
|
||||
err = xrun_recovery(data->pcmHandle, avail);
|
||||
if (err < 0)
|
||||
{
|
||||
AL_PRINT("available update failed: %s\n", psnd_strerror(err));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// make sure there's frames to process
|
||||
if(avail == 0)
|
||||
{
|
||||
usleep(1000);
|
||||
continue;
|
||||
}
|
||||
|
||||
// it is possible that contiguous areas are smaller, thus we use a loop
|
||||
while (avail > 0)
|
||||
{
|
||||
frames = avail;
|
||||
|
||||
err = psnd_pcm_mmap_begin(data->pcmHandle, &areas, &offset, &frames);
|
||||
if (err < 0)
|
||||
{
|
||||
err = xrun_recovery(data->pcmHandle, err);
|
||||
if (err < 0)
|
||||
AL_PRINT("mmap begin error: %s\n", psnd_strerror(err));
|
||||
break;
|
||||
}
|
||||
|
||||
SuspendContext(NULL);
|
||||
WritePtr = (char*)areas->addr + (offset * areas->step / 8);
|
||||
WriteCnt = psnd_pcm_frames_to_bytes(data->pcmHandle, frames);
|
||||
aluMixData(pDevice->Context, WritePtr, WriteCnt, pDevice->Format);
|
||||
ProcessContext(NULL);
|
||||
|
||||
commitres = psnd_pcm_mmap_commit(data->pcmHandle, offset, frames);
|
||||
if (commitres < 0 || (commitres-frames) != 0)
|
||||
{
|
||||
AL_PRINT("mmap commit error: %s\n",
|
||||
psnd_strerror(commitres >= 0 ? -EPIPE : commitres));
|
||||
break;
|
||||
}
|
||||
|
||||
avail -= frames;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static ALuint ALSANoMMapProc(ALvoid *ptr)
|
||||
{
|
||||
ALCdevice *pDevice = (ALCdevice*)ptr;
|
||||
alsa_data *data = (alsa_data*)pDevice->ExtraData;
|
||||
snd_pcm_sframes_t avail;
|
||||
char *WritePtr;
|
||||
|
||||
while(!data->killNow)
|
||||
{
|
||||
SuspendContext(NULL);
|
||||
aluMixData(pDevice->Context, data->buffer, data->size, pDevice->Format);
|
||||
ProcessContext(NULL);
|
||||
|
||||
WritePtr = data->buffer;
|
||||
avail = (snd_pcm_uframes_t)data->size / psnd_pcm_frames_to_bytes(data->pcmHandle, 1);
|
||||
while(avail > 0)
|
||||
{
|
||||
int ret = psnd_pcm_writei(data->pcmHandle, WritePtr, avail);
|
||||
switch (ret)
|
||||
{
|
||||
case -EAGAIN:
|
||||
continue;
|
||||
case -ESTRPIPE:
|
||||
do {
|
||||
ret = psnd_pcm_resume(data->pcmHandle);
|
||||
} while(ret == -EAGAIN);
|
||||
break;
|
||||
case -EPIPE:
|
||||
break;
|
||||
default:
|
||||
if (ret >= 0)
|
||||
{
|
||||
WritePtr += psnd_pcm_frames_to_bytes(data->pcmHandle, ret);
|
||||
avail -= ret;
|
||||
}
|
||||
break;
|
||||
}
|
||||
if (ret < 0)
|
||||
{
|
||||
ret = psnd_pcm_prepare(data->pcmHandle);
|
||||
if(ret < 0)
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void fill_silence(snd_pcm_t *pcmHandle, snd_pcm_format_t alsaFormat, int channels)
|
||||
{
|
||||
const snd_pcm_channel_area_t *areas = NULL;
|
||||
snd_pcm_sframes_t avail, commitres;
|
||||
snd_pcm_uframes_t offset, frames;
|
||||
int err;
|
||||
|
||||
avail = psnd_pcm_avail_update(pcmHandle);
|
||||
if(avail < 0)
|
||||
{
|
||||
err = xrun_recovery(pcmHandle, avail);
|
||||
if (err < 0)
|
||||
{
|
||||
AL_PRINT("available update failed: %s\n", psnd_strerror(err));
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// it is possible that contiguous areas are smaller, thus we use a loop
|
||||
while (avail > 0)
|
||||
{
|
||||
frames = avail;
|
||||
|
||||
err = psnd_pcm_mmap_begin(pcmHandle, &areas, &offset, &frames);
|
||||
if (err < 0)
|
||||
{
|
||||
err = xrun_recovery(pcmHandle, err);
|
||||
if (err < 0)
|
||||
{
|
||||
AL_PRINT("mmap begin error: %s\n", psnd_strerror(err));
|
||||
break;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
psnd_pcm_areas_silence(areas, offset, channels, frames, alsaFormat);
|
||||
|
||||
commitres = psnd_pcm_mmap_commit(pcmHandle, offset, frames);
|
||||
if (commitres < 0 || (commitres-frames) != 0)
|
||||
{
|
||||
AL_PRINT("mmap commit error: %s\n",
|
||||
psnd_strerror(commitres >= 0 ? -EPIPE : commitres));
|
||||
break;
|
||||
}
|
||||
|
||||
avail -= frames;
|
||||
}
|
||||
}
|
||||
|
||||
static ALCboolean alsa_open_playback(ALCdevice *device, const ALCchar *deviceName)
|
||||
{
|
||||
snd_pcm_uframes_t bufferSizeInFrames;
|
||||
snd_pcm_hw_params_t *p = NULL;
|
||||
snd_pcm_access_t access;
|
||||
unsigned int periods;
|
||||
alsa_data *data;
|
||||
char driver[64];
|
||||
char *err;
|
||||
int i;
|
||||
|
||||
strncpy(driver, GetConfigValue("alsa", "device", "default"), sizeof(driver)-1);
|
||||
driver[sizeof(driver)-1] = 0;
|
||||
if(deviceName)
|
||||
{
|
||||
size_t idx;
|
||||
|
||||
for(idx = 0;idx < MAX_ALL_DEVICES;idx++)
|
||||
{
|
||||
if(allDevNameMap[idx].name &&
|
||||
strcmp(deviceName, allDevNameMap[idx].name) == 0)
|
||||
{
|
||||
device->szDeviceName = allDevNameMap[idx].name;
|
||||
if(idx > 0)
|
||||
sprintf(driver, "hw:%d,%d", allDevNameMap[idx].card, allDevNameMap[idx].dev);
|
||||
goto open_alsa;
|
||||
}
|
||||
}
|
||||
for(idx = 0;idx < MAX_DEVICES;idx++)
|
||||
{
|
||||
if(alsaDeviceList[idx] &&
|
||||
strcmp(deviceName, alsaDeviceList[idx]) == 0)
|
||||
{
|
||||
device->szDeviceName = alsaDeviceList[idx];
|
||||
if(idx > 0)
|
||||
sprintf(driver, "hw:%zd,0", idx-1);
|
||||
goto open_alsa;
|
||||
}
|
||||
}
|
||||
return ALC_FALSE;
|
||||
}
|
||||
else
|
||||
device->szDeviceName = alsaDeviceList[0];
|
||||
|
||||
open_alsa:
|
||||
data = (alsa_data*)calloc(1, sizeof(alsa_data));
|
||||
|
||||
i = psnd_pcm_open(&data->pcmHandle, driver, SND_PCM_STREAM_PLAYBACK, SND_PCM_NONBLOCK);
|
||||
if(i < 0)
|
||||
{
|
||||
usleep(200000);
|
||||
i = psnd_pcm_open(&data->pcmHandle, driver, SND_PCM_STREAM_PLAYBACK, SND_PCM_NONBLOCK);
|
||||
}
|
||||
if(i >= 0)
|
||||
{
|
||||
i = psnd_pcm_nonblock(data->pcmHandle, 0);
|
||||
if(i < 0)
|
||||
psnd_pcm_close(data->pcmHandle);
|
||||
}
|
||||
if(i < 0)
|
||||
{
|
||||
free(data);
|
||||
AL_PRINT("Could not open playback device '%s': %s\n", driver, psnd_strerror(i));
|
||||
return ALC_FALSE;
|
||||
}
|
||||
|
||||
switch(aluBytesFromFormat(device->Format))
|
||||
{
|
||||
case 1:
|
||||
data->format = SND_PCM_FORMAT_U8;
|
||||
break;
|
||||
case 2:
|
||||
data->format = SND_PCM_FORMAT_S16;
|
||||
break;
|
||||
default:
|
||||
data->format = SND_PCM_FORMAT_UNKNOWN;
|
||||
AL_PRINT("Unknown format?! %x\n", device->Format);
|
||||
}
|
||||
|
||||
periods = GetConfigValueInt("alsa", "periods", 4);
|
||||
if((int)periods <= 0)
|
||||
periods = 4;
|
||||
bufferSizeInFrames = device->UpdateFreq / periods;
|
||||
|
||||
psnd_pcm_hw_params_malloc(&p);
|
||||
#define ok(func, str) (i=(func),((i<0)?(err=(str)),0:1))
|
||||
/* start with the largest configuration space possible */
|
||||
if(!(ok(psnd_pcm_hw_params_any(data->pcmHandle, p), "any") &&
|
||||
/* set interleaved access */
|
||||
(ok(psnd_pcm_hw_params_set_access(data->pcmHandle, p, SND_PCM_ACCESS_MMAP_INTERLEAVED), "set access") ||
|
||||
ok(psnd_pcm_hw_params_set_access(data->pcmHandle, p, SND_PCM_ACCESS_RW_INTERLEAVED), "set access")) &&
|
||||
/* set format (implicitly sets sample bits) */
|
||||
ok(psnd_pcm_hw_params_set_format(data->pcmHandle, p, data->format), "set format") &&
|
||||
/* set channels (implicitly sets frame bits) */
|
||||
ok(psnd_pcm_hw_params_set_channels(data->pcmHandle, p, device->Channels), "set channels") &&
|
||||
/* set periods (implicitly constrains period/buffer parameters) */
|
||||
ok(psnd_pcm_hw_params_set_periods_near(data->pcmHandle, p, &periods, NULL), "set periods near") &&
|
||||
/* set rate (implicitly constrains period/buffer parameters) */
|
||||
ok(psnd_pcm_hw_params_set_rate_near(data->pcmHandle, p, &device->Frequency, NULL), "set rate near") &&
|
||||
/* set buffer size in frame units (implicitly sets period size/bytes/time and buffer time/bytes) */
|
||||
ok(psnd_pcm_hw_params_set_buffer_size_near(data->pcmHandle, p, &bufferSizeInFrames), "set buffer size near") &&
|
||||
/* install and prepare hardware configuration */
|
||||
ok(psnd_pcm_hw_params(data->pcmHandle, p), "set params")))
|
||||
{
|
||||
AL_PRINT("%s failed: %s\n", err, psnd_strerror(i));
|
||||
psnd_pcm_hw_params_free(p);
|
||||
psnd_pcm_close(data->pcmHandle);
|
||||
free(data);
|
||||
return ALC_FALSE;
|
||||
}
|
||||
#undef ok
|
||||
|
||||
if((i=psnd_pcm_hw_params_get_access(p, &access)) < 0)
|
||||
{
|
||||
AL_PRINT("get_access failed: %s\n", psnd_strerror(i));
|
||||
psnd_pcm_hw_params_free(p);
|
||||
psnd_pcm_close(data->pcmHandle);
|
||||
free(data);
|
||||
return ALC_FALSE;
|
||||
}
|
||||
|
||||
psnd_pcm_hw_params_free(p);
|
||||
|
||||
device->MaxNoOfSources = 256;
|
||||
device->UpdateFreq = bufferSizeInFrames;
|
||||
|
||||
data->size = psnd_pcm_frames_to_bytes(data->pcmHandle, device->UpdateFreq);
|
||||
if(access == SND_PCM_ACCESS_RW_INTERLEAVED)
|
||||
{
|
||||
data->buffer = malloc(data->size);
|
||||
if(!data->buffer)
|
||||
{
|
||||
AL_PRINT("buffer malloc failed\n");
|
||||
psnd_pcm_close(data->pcmHandle);
|
||||
free(data);
|
||||
return ALC_FALSE;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
i = psnd_pcm_prepare(data->pcmHandle);
|
||||
if(i < 0)
|
||||
{
|
||||
AL_PRINT("prepare error: %s\n", psnd_strerror(i));
|
||||
psnd_pcm_close(data->pcmHandle);
|
||||
free(data->buffer);
|
||||
free(data);
|
||||
return ALC_FALSE;
|
||||
}
|
||||
|
||||
fill_silence(data->pcmHandle, data->format, device->Channels);
|
||||
|
||||
i = psnd_pcm_start(data->pcmHandle);
|
||||
if(i < 0)
|
||||
{
|
||||
AL_PRINT("start error: %s\n", psnd_strerror(i));
|
||||
psnd_pcm_close(data->pcmHandle);
|
||||
free(data->buffer);
|
||||
free(data);
|
||||
return ALC_FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
device->ExtraData = data;
|
||||
if(access == SND_PCM_ACCESS_RW_INTERLEAVED)
|
||||
data->thread = StartThread(ALSANoMMapProc, device);
|
||||
else
|
||||
data->thread = StartThread(ALSAProc, device);
|
||||
if(data->thread == NULL)
|
||||
{
|
||||
psnd_pcm_close(data->pcmHandle);
|
||||
device->ExtraData = NULL;
|
||||
free(data->buffer);
|
||||
free(data);
|
||||
return ALC_FALSE;
|
||||
}
|
||||
|
||||
return ALC_TRUE;
|
||||
}
|
||||
|
||||
static void alsa_close_playback(ALCdevice *device)
|
||||
{
|
||||
alsa_data *data = (alsa_data*)device->ExtraData;
|
||||
data->killNow = 1;
|
||||
StopThread(data->thread);
|
||||
psnd_pcm_close(data->pcmHandle);
|
||||
|
||||
free(data->buffer);
|
||||
free(data);
|
||||
device->ExtraData = NULL;
|
||||
}
|
||||
|
||||
|
||||
static ALCboolean alsa_open_capture(ALCdevice *pDevice, const ALCchar *deviceName, ALCuint frequency, ALCenum format, ALCsizei SampleSize)
|
||||
{
|
||||
snd_pcm_format_t alsaFormat;
|
||||
snd_pcm_hw_params_t *p;
|
||||
unsigned int periods = 4;
|
||||
snd_pcm_uframes_t bufferSizeInFrames;
|
||||
alsa_data *data;
|
||||
char driver[64];
|
||||
char *err;
|
||||
int i;
|
||||
|
||||
strncpy(driver, GetConfigValue("alsa", "capture", "default"), sizeof(driver)-1);
|
||||
driver[sizeof(driver)-1] = 0;
|
||||
if(deviceName)
|
||||
{
|
||||
size_t idx;
|
||||
|
||||
for(idx = 0;idx < MAX_DEVICES;idx++)
|
||||
{
|
||||
if(alsaCaptureDeviceList[idx] &&
|
||||
strcmp(deviceName, alsaCaptureDeviceList[idx]) == 0)
|
||||
{
|
||||
pDevice->szDeviceName = alsaCaptureDeviceList[idx];
|
||||
if(idx > 0)
|
||||
sprintf(driver, "hw:%zd,0", idx-1);
|
||||
goto open_alsa;
|
||||
}
|
||||
}
|
||||
return ALC_FALSE;
|
||||
}
|
||||
else
|
||||
pDevice->szDeviceName = alsaCaptureDeviceList[0];
|
||||
|
||||
open_alsa:
|
||||
data = (alsa_data*)calloc(1, sizeof(alsa_data));
|
||||
|
||||
i = psnd_pcm_open(&data->pcmHandle, driver, SND_PCM_STREAM_CAPTURE, SND_PCM_NONBLOCK);
|
||||
if(i < 0)
|
||||
{
|
||||
usleep(200000);
|
||||
i = psnd_pcm_open(&data->pcmHandle, driver, SND_PCM_STREAM_CAPTURE, SND_PCM_NONBLOCK);
|
||||
}
|
||||
if(i >= 0)
|
||||
{
|
||||
i = psnd_pcm_nonblock(data->pcmHandle, 0);
|
||||
if(i < 0)
|
||||
psnd_pcm_close(data->pcmHandle);
|
||||
}
|
||||
if(i < 0)
|
||||
{
|
||||
free(data);
|
||||
AL_PRINT("Could not open capture device '%s': %s\n", driver, psnd_strerror(i));
|
||||
return ALC_FALSE;
|
||||
}
|
||||
|
||||
switch(aluBytesFromFormat(format))
|
||||
{
|
||||
case 1:
|
||||
alsaFormat = SND_PCM_FORMAT_U8;
|
||||
break;
|
||||
case 2:
|
||||
alsaFormat = SND_PCM_FORMAT_S16;
|
||||
break;
|
||||
default:
|
||||
alsaFormat = SND_PCM_FORMAT_UNKNOWN;
|
||||
AL_PRINT("Unknown format?! %x\n", format);
|
||||
}
|
||||
|
||||
bufferSizeInFrames = SampleSize / periods;
|
||||
|
||||
psnd_pcm_hw_params_malloc(&p);
|
||||
#define ok(func, str) (i=(func),((i<0)?(err=(str)),0:1))
|
||||
/* start with the largest configuration space possible */
|
||||
if(!(ok(psnd_pcm_hw_params_any(data->pcmHandle, p), "any") &&
|
||||
/* set interleaved access */
|
||||
ok(psnd_pcm_hw_params_set_access(data->pcmHandle, p, SND_PCM_ACCESS_MMAP_INTERLEAVED), "set access") &&
|
||||
/* set format (implicitly sets sample bits) */
|
||||
ok(psnd_pcm_hw_params_set_format(data->pcmHandle, p, alsaFormat), "set format") &&
|
||||
/* set channels (implicitly sets frame bits) */
|
||||
ok(psnd_pcm_hw_params_set_channels(data->pcmHandle, p, pDevice->Channels), "set channels") &&
|
||||
/* set periods (implicitly constrains period/buffer parameters) */
|
||||
ok(psnd_pcm_hw_params_set_periods_near(data->pcmHandle, p, &periods, NULL), "set periods near") &&
|
||||
/* set rate (implicitly constrains period/buffer parameters) */
|
||||
ok(psnd_pcm_hw_params_set_rate(data->pcmHandle, p, frequency, 0), "set rate") &&
|
||||
/* set buffer size in frame units (implicitly sets period size/bytes/time and buffer time/bytes) */
|
||||
ok(psnd_pcm_hw_params_set_buffer_size_min(data->pcmHandle, p, &bufferSizeInFrames), "set buffer size min") &&
|
||||
/* install and prepare hardware configuration */
|
||||
ok(psnd_pcm_hw_params(data->pcmHandle, p), "set params")))
|
||||
{
|
||||
AL_PRINT("%s failed: %s\n", err, psnd_strerror(i));
|
||||
psnd_pcm_hw_params_free(p);
|
||||
psnd_pcm_close(data->pcmHandle);
|
||||
free(data);
|
||||
return ALC_FALSE;
|
||||
}
|
||||
#undef ok
|
||||
psnd_pcm_hw_params_free(p);
|
||||
|
||||
i = psnd_pcm_prepare(data->pcmHandle);
|
||||
if(i < 0)
|
||||
{
|
||||
AL_PRINT("prepare error: %s\n", psnd_strerror(i));
|
||||
psnd_pcm_close(data->pcmHandle);
|
||||
free(data);
|
||||
return ALC_FALSE;
|
||||
}
|
||||
|
||||
pDevice->ExtraData = data;
|
||||
return ALC_TRUE;
|
||||
}
|
||||
|
||||
static void alsa_close_capture(ALCdevice *pDevice)
|
||||
{
|
||||
alsa_data *data = (alsa_data*)pDevice->ExtraData;
|
||||
psnd_pcm_close(data->pcmHandle);
|
||||
|
||||
free(data);
|
||||
pDevice->ExtraData = NULL;
|
||||
}
|
||||
|
||||
static void alsa_start_capture(ALCdevice *pDevice)
|
||||
{
|
||||
alsa_data *data = (alsa_data*)pDevice->ExtraData;
|
||||
psnd_pcm_start(data->pcmHandle);
|
||||
}
|
||||
|
||||
static void alsa_stop_capture(ALCdevice *pDevice)
|
||||
{
|
||||
alsa_data *data = (alsa_data*)pDevice->ExtraData;
|
||||
psnd_pcm_drain(data->pcmHandle);
|
||||
}
|
||||
|
||||
static void alsa_capture_samples(ALCdevice *pDevice, ALCvoid *pBuffer, ALCuint lSamples)
|
||||
{
|
||||
alsa_data *data = (alsa_data*)pDevice->ExtraData;
|
||||
const snd_pcm_channel_area_t *areas = NULL;
|
||||
snd_pcm_sframes_t frames, commitres;
|
||||
snd_pcm_uframes_t size, offset;
|
||||
int err;
|
||||
|
||||
frames = psnd_pcm_avail_update(data->pcmHandle);
|
||||
if(frames < 0)
|
||||
{
|
||||
err = xrun_recovery(data->pcmHandle, frames);
|
||||
if (err < 0)
|
||||
AL_PRINT("available update failed: %s\n", psnd_strerror(err));
|
||||
else
|
||||
frames = psnd_pcm_avail_update(data->pcmHandle);
|
||||
}
|
||||
if (frames < (snd_pcm_sframes_t)lSamples)
|
||||
{
|
||||
SetALCError(ALC_INVALID_VALUE);
|
||||
return;
|
||||
}
|
||||
|
||||
// it is possible that contiguous areas are smaller, thus we use a loop
|
||||
while (lSamples > 0)
|
||||
{
|
||||
char *Pointer;
|
||||
int Count;
|
||||
|
||||
size = lSamples;
|
||||
err = psnd_pcm_mmap_begin(data->pcmHandle, &areas, &offset, &size);
|
||||
if (err < 0)
|
||||
{
|
||||
err = xrun_recovery(data->pcmHandle, err);
|
||||
if (err < 0)
|
||||
{
|
||||
AL_PRINT("mmap begin error: %s\n", psnd_strerror(err));
|
||||
break;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
Pointer = (char*)areas->addr + (offset * areas->step / 8);
|
||||
Count = size * pDevice->FrameSize;
|
||||
|
||||
memcpy(pBuffer, Pointer, Count);
|
||||
pBuffer = (char*)pBuffer + Count;
|
||||
|
||||
commitres = psnd_pcm_mmap_commit(data->pcmHandle, offset, size);
|
||||
if (commitres < 0 || (commitres-size) != 0)
|
||||
{
|
||||
AL_PRINT("mmap commit error: %s\n",
|
||||
psnd_strerror(commitres >= 0 ? -EPIPE : commitres));
|
||||
break;
|
||||
}
|
||||
|
||||
lSamples -= size;
|
||||
}
|
||||
}
|
||||
|
||||
static ALCuint alsa_available_samples(ALCdevice *pDevice)
|
||||
{
|
||||
alsa_data *data = (alsa_data*)pDevice->ExtraData;
|
||||
snd_pcm_sframes_t frames = psnd_pcm_avail_update(data->pcmHandle);
|
||||
if(frames < 0)
|
||||
{
|
||||
int err = xrun_recovery(data->pcmHandle, frames);
|
||||
if (err < 0)
|
||||
AL_PRINT("available update failed: %s\n", psnd_strerror(err));
|
||||
else
|
||||
frames = psnd_pcm_avail_update(data->pcmHandle);
|
||||
if(frames < 0) /* ew.. */
|
||||
SetALCError(ALC_INVALID_DEVICE);
|
||||
}
|
||||
return max(frames, 0);
|
||||
}
|
||||
|
||||
|
||||
BackendFuncs alsa_funcs = {
|
||||
alsa_open_playback,
|
||||
alsa_close_playback,
|
||||
alsa_open_capture,
|
||||
alsa_close_capture,
|
||||
alsa_start_capture,
|
||||
alsa_stop_capture,
|
||||
alsa_capture_samples,
|
||||
alsa_available_samples
|
||||
};
|
||||
|
||||
void alc_alsa_init(BackendFuncs *func_list)
|
||||
{
|
||||
snd_ctl_t *handle;
|
||||
int card, err, dev, idx = 1;
|
||||
snd_ctl_card_info_t *info;
|
||||
snd_pcm_info_t *pcminfo;
|
||||
snd_pcm_stream_t stream = SND_PCM_STREAM_PLAYBACK;
|
||||
char name[128];
|
||||
char *str;
|
||||
|
||||
*func_list = alsa_funcs;
|
||||
|
||||
#ifdef HAVE_DLFCN_H
|
||||
alsa_handle = dlopen("libasound.so.2", RTLD_NOW);
|
||||
if(!alsa_handle)
|
||||
return;
|
||||
dlerror();
|
||||
|
||||
#define LOAD_FUNC(f) do { \
|
||||
p##f = (typeof(f)*)dlsym(alsa_handle, #f); \
|
||||
if((str=dlerror()) != NULL) \
|
||||
{ \
|
||||
dlclose(alsa_handle); \
|
||||
alsa_handle = NULL; \
|
||||
AL_PRINT("Could not load %s from libasound.so.2: %s\n", #f, str); \
|
||||
return; \
|
||||
} \
|
||||
} while(0)
|
||||
#else
|
||||
str = NULL;
|
||||
alsa_handle = NULL;
|
||||
#define LOAD_FUNC(f) p##f = f
|
||||
#endif
|
||||
|
||||
LOAD_FUNC(snd_strerror);
|
||||
LOAD_FUNC(snd_pcm_open);
|
||||
LOAD_FUNC(snd_pcm_close);
|
||||
LOAD_FUNC(snd_pcm_nonblock);
|
||||
LOAD_FUNC(snd_pcm_frames_to_bytes);
|
||||
LOAD_FUNC(snd_pcm_hw_params_malloc);
|
||||
LOAD_FUNC(snd_pcm_hw_params_free);
|
||||
LOAD_FUNC(snd_pcm_hw_params_any);
|
||||
LOAD_FUNC(snd_pcm_hw_params_set_access);
|
||||
LOAD_FUNC(snd_pcm_hw_params_set_format);
|
||||
LOAD_FUNC(snd_pcm_hw_params_set_channels);
|
||||
LOAD_FUNC(snd_pcm_hw_params_set_periods_near);
|
||||
LOAD_FUNC(snd_pcm_hw_params_set_rate_near);
|
||||
LOAD_FUNC(snd_pcm_hw_params_set_rate);
|
||||
LOAD_FUNC(snd_pcm_hw_params_set_buffer_size_near);
|
||||
LOAD_FUNC(snd_pcm_hw_params_set_buffer_size_min);
|
||||
LOAD_FUNC(snd_pcm_hw_params_get_access);
|
||||
LOAD_FUNC(snd_pcm_hw_params);
|
||||
LOAD_FUNC(snd_pcm_prepare);
|
||||
LOAD_FUNC(snd_pcm_start);
|
||||
LOAD_FUNC(snd_pcm_resume);
|
||||
LOAD_FUNC(snd_pcm_state);
|
||||
LOAD_FUNC(snd_pcm_avail_update);
|
||||
LOAD_FUNC(snd_pcm_areas_silence);
|
||||
LOAD_FUNC(snd_pcm_mmap_begin);
|
||||
LOAD_FUNC(snd_pcm_mmap_commit);
|
||||
LOAD_FUNC(snd_pcm_writei);
|
||||
LOAD_FUNC(snd_pcm_drain);
|
||||
|
||||
LOAD_FUNC(snd_pcm_info_malloc);
|
||||
LOAD_FUNC(snd_pcm_info_free);
|
||||
LOAD_FUNC(snd_pcm_info_set_device);
|
||||
LOAD_FUNC(snd_pcm_info_set_subdevice);
|
||||
LOAD_FUNC(snd_pcm_info_set_stream);
|
||||
LOAD_FUNC(snd_pcm_info_get_name);
|
||||
LOAD_FUNC(snd_ctl_pcm_next_device);
|
||||
LOAD_FUNC(snd_ctl_pcm_info);
|
||||
LOAD_FUNC(snd_ctl_open);
|
||||
LOAD_FUNC(snd_ctl_close);
|
||||
LOAD_FUNC(snd_ctl_card_info_malloc);
|
||||
LOAD_FUNC(snd_ctl_card_info_free);
|
||||
LOAD_FUNC(snd_ctl_card_info);
|
||||
LOAD_FUNC(snd_ctl_card_info_get_name);
|
||||
LOAD_FUNC(snd_card_next);
|
||||
|
||||
#undef LOAD_FUNC
|
||||
|
||||
psnd_ctl_card_info_malloc(&info);
|
||||
psnd_pcm_info_malloc(&pcminfo);
|
||||
|
||||
card = -1;
|
||||
if(psnd_card_next(&card) < 0 || card < 0)
|
||||
AL_PRINT("no playback cards found...\n");
|
||||
else
|
||||
{
|
||||
alsaDeviceList[0] = AppendDeviceList("ALSA Software on default");
|
||||
allDevNameMap[0].name = AppendAllDeviceList("ALSA Software on default");
|
||||
}
|
||||
|
||||
while (card >= 0) {
|
||||
sprintf(name, "hw:%d", card);
|
||||
if ((err = psnd_ctl_open(&handle, name, 0)) < 0) {
|
||||
AL_PRINT("control open (%i): %s\n", card, psnd_strerror(err));
|
||||
goto next_card;
|
||||
}
|
||||
if ((err = psnd_ctl_card_info(handle, info)) < 0) {
|
||||
AL_PRINT("control hardware info (%i): %s\n", card, psnd_strerror(err));
|
||||
psnd_ctl_close(handle);
|
||||
goto next_card;
|
||||
}
|
||||
if(card < MAX_DEVICES-1) {
|
||||
snprintf(name, sizeof(name), "ALSA Software on %s",
|
||||
psnd_ctl_card_info_get_name(info));
|
||||
alsaDeviceList[card+1] = AppendDeviceList(name);
|
||||
}
|
||||
|
||||
dev = -1;
|
||||
while (idx < MAX_ALL_DEVICES) {
|
||||
const char *cname, *dname;
|
||||
|
||||
if (psnd_ctl_pcm_next_device(handle, &dev)<0)
|
||||
AL_PRINT("snd_ctl_pcm_next_device failed\n");
|
||||
if (dev < 0)
|
||||
break;
|
||||
psnd_pcm_info_set_device(pcminfo, dev);
|
||||
psnd_pcm_info_set_subdevice(pcminfo, 0);
|
||||
psnd_pcm_info_set_stream(pcminfo, stream);
|
||||
if ((err = psnd_ctl_pcm_info(handle, pcminfo)) < 0) {
|
||||
if (err != -ENOENT)
|
||||
AL_PRINT("control digital audio info (%i): %s\n", card, psnd_strerror(err));
|
||||
continue;
|
||||
}
|
||||
|
||||
cname = psnd_ctl_card_info_get_name(info);
|
||||
dname = psnd_pcm_info_get_name(pcminfo);
|
||||
snprintf(name, sizeof(name), "ALSA Software on %s [%s]",
|
||||
cname, dname);
|
||||
allDevNameMap[idx].name = AppendAllDeviceList(name);
|
||||
allDevNameMap[idx].card = card;
|
||||
allDevNameMap[idx].dev = dev;
|
||||
idx++;
|
||||
}
|
||||
psnd_ctl_close(handle);
|
||||
next_card:
|
||||
if(psnd_card_next(&card) < 0) {
|
||||
AL_PRINT("snd_card_next failed\n");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
stream = SND_PCM_STREAM_CAPTURE;
|
||||
|
||||
card = -1;
|
||||
if(psnd_card_next(&card) < 0 || card < 0) {
|
||||
AL_PRINT("no capture cards found...\n");
|
||||
psnd_pcm_info_free(pcminfo);
|
||||
psnd_ctl_card_info_free(info);
|
||||
return;
|
||||
}
|
||||
|
||||
alsaCaptureDeviceList[0] = AppendCaptureDeviceList("ALSA Capture on default");
|
||||
|
||||
while (card >= 0) {
|
||||
sprintf(name, "hw:%d", card);
|
||||
handle = NULL;
|
||||
if ((err = psnd_ctl_open(&handle, name, 0)) < 0) {
|
||||
AL_PRINT("control open (%i): %s\n", card, psnd_strerror(err));
|
||||
}
|
||||
if (err >= 0 && (err = psnd_ctl_card_info(handle, info)) < 0) {
|
||||
AL_PRINT("control hardware info (%i): %s\n", card, psnd_strerror(err));
|
||||
psnd_ctl_close(handle);
|
||||
}
|
||||
else if (err >= 0 && card < MAX_DEVICES-1)
|
||||
{
|
||||
snprintf(name, sizeof(name), "ALSA Capture on %s",
|
||||
psnd_ctl_card_info_get_name(info));
|
||||
alsaCaptureDeviceList[card+1] = AppendCaptureDeviceList(name);
|
||||
}
|
||||
if(handle) psnd_ctl_close(handle);
|
||||
if(psnd_card_next(&card) < 0) {
|
||||
AL_PRINT("snd_card_next failed\n");
|
||||
break;
|
||||
}
|
||||
}
|
||||
psnd_pcm_info_free(pcminfo);
|
||||
psnd_ctl_card_info_free(info);
|
||||
}
|
||||
+1371
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,706 @@
|
||||
/**
|
||||
* OpenAL cross platform audio library
|
||||
* Copyright (C) 1999-2007 by authors.
|
||||
* 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., 59 Temple Place - Suite 330,
|
||||
* Boston, MA 02111-1307, USA.
|
||||
* Or go to http://www.gnu.org/copyleft/lgpl.html
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "alMain.h"
|
||||
#include "alu.h"
|
||||
|
||||
#include <CoreServices/CoreServices.h>
|
||||
#include <unistd.h>
|
||||
#include <AudioUnit/AudioUnit.h>
|
||||
#include <AudioToolbox/AudioToolbox.h>
|
||||
|
||||
|
||||
typedef struct {
|
||||
AudioUnit audioUnit;
|
||||
|
||||
ALuint frameSize;
|
||||
ALdouble sampleRateRatio; // Ratio of hardware sample rate / requested sample rate
|
||||
AudioStreamBasicDescription format; // This is the OpenAL format as a CoreAudio ASBD
|
||||
|
||||
AudioConverterRef audioConverter; // Sample rate converter if needed
|
||||
AudioBufferList *bufferList; // Buffer for data coming from the input device
|
||||
ALCvoid *resampleBuffer; // Buffer for returned RingBuffer data when resampling
|
||||
|
||||
RingBuffer *ring;
|
||||
} ca_data;
|
||||
|
||||
static const ALCchar ca_device[] = "CoreAudio Default";
|
||||
|
||||
|
||||
static void destroy_buffer_list(AudioBufferList* list)
|
||||
{
|
||||
if(list)
|
||||
{
|
||||
UInt32 i;
|
||||
for(i = 0;i < list->mNumberBuffers;i++)
|
||||
free(list->mBuffers[i].mData);
|
||||
free(list);
|
||||
}
|
||||
}
|
||||
|
||||
static AudioBufferList* allocate_buffer_list(UInt32 channelCount, UInt32 byteSize)
|
||||
{
|
||||
AudioBufferList *list;
|
||||
|
||||
list = calloc(1, sizeof(AudioBufferList) + sizeof(AudioBuffer));
|
||||
if(list)
|
||||
{
|
||||
list->mNumberBuffers = 1;
|
||||
|
||||
list->mBuffers[0].mNumberChannels = channelCount;
|
||||
list->mBuffers[0].mDataByteSize = byteSize;
|
||||
list->mBuffers[0].mData = malloc(byteSize);
|
||||
if(list->mBuffers[0].mData == NULL)
|
||||
{
|
||||
free(list);
|
||||
list = NULL;
|
||||
}
|
||||
}
|
||||
return list;
|
||||
}
|
||||
|
||||
static OSStatus ca_callback(void *inRefCon, AudioUnitRenderActionFlags *ioActionFlags, const AudioTimeStamp *inTimeStamp,
|
||||
UInt32 inBusNumber, UInt32 inNumberFrames, AudioBufferList *ioData)
|
||||
{
|
||||
ALCdevice *device = (ALCdevice*)inRefCon;
|
||||
ca_data *data = (ca_data*)device->ExtraData;
|
||||
|
||||
aluMixData(device, ioData->mBuffers[0].mData,
|
||||
ioData->mBuffers[0].mDataByteSize / data->frameSize);
|
||||
|
||||
return noErr;
|
||||
}
|
||||
|
||||
static OSStatus ca_capture_conversion_callback(AudioConverterRef inAudioConverter, UInt32 *ioNumberDataPackets,
|
||||
AudioBufferList *ioData, AudioStreamPacketDescription **outDataPacketDescription, void* inUserData)
|
||||
{
|
||||
ALCdevice *device = (ALCdevice*)inUserData;
|
||||
ca_data *data = (ca_data*)device->ExtraData;
|
||||
|
||||
// Read from the ring buffer and store temporarily in a large buffer
|
||||
ReadRingBuffer(data->ring, data->resampleBuffer, (ALsizei)(*ioNumberDataPackets));
|
||||
|
||||
// Set the input data
|
||||
ioData->mNumberBuffers = 1;
|
||||
ioData->mBuffers[0].mNumberChannels = data->format.mChannelsPerFrame;
|
||||
ioData->mBuffers[0].mData = data->resampleBuffer;
|
||||
ioData->mBuffers[0].mDataByteSize = (*ioNumberDataPackets) * data->format.mBytesPerFrame;
|
||||
|
||||
return noErr;
|
||||
}
|
||||
|
||||
static OSStatus ca_capture_callback(void *inRefCon, AudioUnitRenderActionFlags *ioActionFlags,
|
||||
const AudioTimeStamp *inTimeStamp, UInt32 inBusNumber,
|
||||
UInt32 inNumberFrames, AudioBufferList *ioData)
|
||||
{
|
||||
ALCdevice *device = (ALCdevice*)inRefCon;
|
||||
ca_data *data = (ca_data*)device->ExtraData;
|
||||
AudioUnitRenderActionFlags flags = 0;
|
||||
OSStatus err;
|
||||
|
||||
// fill the bufferList with data from the input device
|
||||
err = AudioUnitRender(data->audioUnit, &flags, inTimeStamp, 1, inNumberFrames, data->bufferList);
|
||||
if(err != noErr)
|
||||
{
|
||||
ERR("AudioUnitRender error: %d\n", err);
|
||||
return err;
|
||||
}
|
||||
|
||||
WriteRingBuffer(data->ring, data->bufferList->mBuffers[0].mData, inNumberFrames);
|
||||
|
||||
return noErr;
|
||||
}
|
||||
|
||||
static ALCenum ca_open_playback(ALCdevice *device, const ALCchar *deviceName)
|
||||
{
|
||||
ComponentDescription desc;
|
||||
Component comp;
|
||||
ca_data *data;
|
||||
OSStatus err;
|
||||
|
||||
if(!deviceName)
|
||||
deviceName = ca_device;
|
||||
else if(strcmp(deviceName, ca_device) != 0)
|
||||
return ALC_INVALID_VALUE;
|
||||
|
||||
/* open the default output unit */
|
||||
desc.componentType = kAudioUnitType_Output;
|
||||
desc.componentSubType = kAudioUnitSubType_DefaultOutput;
|
||||
desc.componentManufacturer = kAudioUnitManufacturer_Apple;
|
||||
desc.componentFlags = 0;
|
||||
desc.componentFlagsMask = 0;
|
||||
|
||||
comp = FindNextComponent(NULL, &desc);
|
||||
if(comp == NULL)
|
||||
{
|
||||
ERR("FindNextComponent failed\n");
|
||||
return ALC_INVALID_VALUE;
|
||||
}
|
||||
|
||||
data = calloc(1, sizeof(*data));
|
||||
|
||||
err = OpenAComponent(comp, &data->audioUnit);
|
||||
if(err != noErr)
|
||||
{
|
||||
ERR("OpenAComponent failed\n");
|
||||
free(data);
|
||||
return ALC_INVALID_VALUE;
|
||||
}
|
||||
|
||||
/* init and start the default audio unit... */
|
||||
err = AudioUnitInitialize(data->audioUnit);
|
||||
if(err != noErr)
|
||||
{
|
||||
ERR("AudioUnitInitialize failed\n");
|
||||
CloseComponent(data->audioUnit);
|
||||
free(data);
|
||||
return ALC_INVALID_VALUE;
|
||||
}
|
||||
|
||||
device->DeviceName = strdup(deviceName);
|
||||
device->ExtraData = data;
|
||||
return ALC_NO_ERROR;
|
||||
}
|
||||
|
||||
static void ca_close_playback(ALCdevice *device)
|
||||
{
|
||||
ca_data *data = (ca_data*)device->ExtraData;
|
||||
|
||||
AudioUnitUninitialize(data->audioUnit);
|
||||
CloseComponent(data->audioUnit);
|
||||
|
||||
free(data);
|
||||
device->ExtraData = NULL;
|
||||
}
|
||||
|
||||
static ALCboolean ca_reset_playback(ALCdevice *device)
|
||||
{
|
||||
ca_data *data = (ca_data*)device->ExtraData;
|
||||
AudioStreamBasicDescription streamFormat;
|
||||
AURenderCallbackStruct input;
|
||||
OSStatus err;
|
||||
UInt32 size;
|
||||
|
||||
err = AudioUnitUninitialize(data->audioUnit);
|
||||
if(err != noErr)
|
||||
ERR("-- AudioUnitUninitialize failed.\n");
|
||||
|
||||
/* retrieve default output unit's properties (output side) */
|
||||
size = sizeof(AudioStreamBasicDescription);
|
||||
err = AudioUnitGetProperty(data->audioUnit, kAudioUnitProperty_StreamFormat, kAudioUnitScope_Output, 0, &streamFormat, &size);
|
||||
if(err != noErr || size != sizeof(AudioStreamBasicDescription))
|
||||
{
|
||||
ERR("AudioUnitGetProperty failed\n");
|
||||
return ALC_FALSE;
|
||||
}
|
||||
|
||||
#if 0
|
||||
TRACE("Output streamFormat of default output unit -\n");
|
||||
TRACE(" streamFormat.mFramesPerPacket = %d\n", streamFormat.mFramesPerPacket);
|
||||
TRACE(" streamFormat.mChannelsPerFrame = %d\n", streamFormat.mChannelsPerFrame);
|
||||
TRACE(" streamFormat.mBitsPerChannel = %d\n", streamFormat.mBitsPerChannel);
|
||||
TRACE(" streamFormat.mBytesPerPacket = %d\n", streamFormat.mBytesPerPacket);
|
||||
TRACE(" streamFormat.mBytesPerFrame = %d\n", streamFormat.mBytesPerFrame);
|
||||
TRACE(" streamFormat.mSampleRate = %5.0f\n", streamFormat.mSampleRate);
|
||||
#endif
|
||||
|
||||
/* set default output unit's input side to match output side */
|
||||
err = AudioUnitSetProperty(data->audioUnit, kAudioUnitProperty_StreamFormat, kAudioUnitScope_Input, 0, &streamFormat, size);
|
||||
if(err != noErr)
|
||||
{
|
||||
ERR("AudioUnitSetProperty failed\n");
|
||||
return ALC_FALSE;
|
||||
}
|
||||
|
||||
if(device->Frequency != streamFormat.mSampleRate)
|
||||
{
|
||||
device->UpdateSize = (ALuint)((ALuint64)device->UpdateSize *
|
||||
streamFormat.mSampleRate /
|
||||
device->Frequency);
|
||||
device->Frequency = streamFormat.mSampleRate;
|
||||
}
|
||||
|
||||
/* FIXME: How to tell what channels are what in the output device, and how
|
||||
* to specify what we're giving? eg, 6.0 vs 5.1 */
|
||||
switch(streamFormat.mChannelsPerFrame)
|
||||
{
|
||||
case 1:
|
||||
device->FmtChans = DevFmtMono;
|
||||
break;
|
||||
case 2:
|
||||
device->FmtChans = DevFmtStereo;
|
||||
break;
|
||||
case 4:
|
||||
device->FmtChans = DevFmtQuad;
|
||||
break;
|
||||
case 6:
|
||||
device->FmtChans = DevFmtX51;
|
||||
break;
|
||||
case 7:
|
||||
device->FmtChans = DevFmtX61;
|
||||
break;
|
||||
case 8:
|
||||
device->FmtChans = DevFmtX71;
|
||||
break;
|
||||
default:
|
||||
ERR("Unhandled channel count (%d), using Stereo\n", streamFormat.mChannelsPerFrame);
|
||||
device->FmtChans = DevFmtStereo;
|
||||
streamFormat.mChannelsPerFrame = 2;
|
||||
break;
|
||||
}
|
||||
SetDefaultWFXChannelOrder(device);
|
||||
|
||||
/* use channel count and sample rate from the default output unit's current
|
||||
* parameters, but reset everything else */
|
||||
streamFormat.mFramesPerPacket = 1;
|
||||
streamFormat.mFormatFlags = 0;
|
||||
switch(device->FmtType)
|
||||
{
|
||||
case DevFmtUByte:
|
||||
device->FmtType = DevFmtByte;
|
||||
/* fall-through */
|
||||
case DevFmtByte:
|
||||
streamFormat.mFormatFlags = kLinearPCMFormatFlagIsSignedInteger;
|
||||
streamFormat.mBitsPerChannel = 8;
|
||||
break;
|
||||
case DevFmtUShort:
|
||||
device->FmtType = DevFmtShort;
|
||||
/* fall-through */
|
||||
case DevFmtShort:
|
||||
streamFormat.mFormatFlags = kLinearPCMFormatFlagIsSignedInteger;
|
||||
streamFormat.mBitsPerChannel = 16;
|
||||
break;
|
||||
case DevFmtUInt:
|
||||
device->FmtType = DevFmtInt;
|
||||
/* fall-through */
|
||||
case DevFmtInt:
|
||||
streamFormat.mFormatFlags = kLinearPCMFormatFlagIsSignedInteger;
|
||||
streamFormat.mBitsPerChannel = 32;
|
||||
break;
|
||||
case DevFmtFloat:
|
||||
streamFormat.mFormatFlags = kLinearPCMFormatFlagIsFloat;
|
||||
streamFormat.mBitsPerChannel = 32;
|
||||
break;
|
||||
}
|
||||
streamFormat.mBytesPerFrame = streamFormat.mChannelsPerFrame *
|
||||
streamFormat.mBitsPerChannel / 8;
|
||||
streamFormat.mBytesPerPacket = streamFormat.mBytesPerFrame;
|
||||
streamFormat.mFormatID = kAudioFormatLinearPCM;
|
||||
streamFormat.mFormatFlags |= kAudioFormatFlagsNativeEndian |
|
||||
kLinearPCMFormatFlagIsPacked;
|
||||
|
||||
err = AudioUnitSetProperty(data->audioUnit, kAudioUnitProperty_StreamFormat, kAudioUnitScope_Input, 0, &streamFormat, sizeof(AudioStreamBasicDescription));
|
||||
if(err != noErr)
|
||||
{
|
||||
ERR("AudioUnitSetProperty failed\n");
|
||||
return ALC_FALSE;
|
||||
}
|
||||
|
||||
/* setup callback */
|
||||
data->frameSize = FrameSizeFromDevFmt(device->FmtChans, device->FmtType);
|
||||
input.inputProc = ca_callback;
|
||||
input.inputProcRefCon = device;
|
||||
|
||||
err = AudioUnitSetProperty(data->audioUnit, kAudioUnitProperty_SetRenderCallback, kAudioUnitScope_Input, 0, &input, sizeof(AURenderCallbackStruct));
|
||||
if(err != noErr)
|
||||
{
|
||||
ERR("AudioUnitSetProperty failed\n");
|
||||
return ALC_FALSE;
|
||||
}
|
||||
|
||||
/* init the default audio unit... */
|
||||
err = AudioUnitInitialize(data->audioUnit);
|
||||
if(err != noErr)
|
||||
{
|
||||
ERR("AudioUnitInitialize failed\n");
|
||||
return ALC_FALSE;
|
||||
}
|
||||
|
||||
return ALC_TRUE;
|
||||
}
|
||||
|
||||
static ALCboolean ca_start_playback(ALCdevice *device)
|
||||
{
|
||||
ca_data *data = (ca_data*)device->ExtraData;
|
||||
OSStatus err;
|
||||
|
||||
err = AudioOutputUnitStart(data->audioUnit);
|
||||
if(err != noErr)
|
||||
{
|
||||
ERR("AudioOutputUnitStart failed\n");
|
||||
return ALC_FALSE;
|
||||
}
|
||||
|
||||
return ALC_TRUE;
|
||||
}
|
||||
|
||||
static void ca_stop_playback(ALCdevice *device)
|
||||
{
|
||||
ca_data *data = (ca_data*)device->ExtraData;
|
||||
OSStatus err;
|
||||
|
||||
err = AudioOutputUnitStop(data->audioUnit);
|
||||
if(err != noErr)
|
||||
ERR("AudioOutputUnitStop failed\n");
|
||||
}
|
||||
|
||||
static ALCenum ca_open_capture(ALCdevice *device, const ALCchar *deviceName)
|
||||
{
|
||||
AudioStreamBasicDescription requestedFormat; // The application requested format
|
||||
AudioStreamBasicDescription hardwareFormat; // The hardware format
|
||||
AudioStreamBasicDescription outputFormat; // The AudioUnit output format
|
||||
AURenderCallbackStruct input;
|
||||
ComponentDescription desc;
|
||||
AudioDeviceID inputDevice;
|
||||
UInt32 outputFrameCount;
|
||||
UInt32 propertySize;
|
||||
UInt32 enableIO;
|
||||
Component comp;
|
||||
ca_data *data;
|
||||
OSStatus err;
|
||||
|
||||
desc.componentType = kAudioUnitType_Output;
|
||||
desc.componentSubType = kAudioUnitSubType_HALOutput;
|
||||
desc.componentManufacturer = kAudioUnitManufacturer_Apple;
|
||||
desc.componentFlags = 0;
|
||||
desc.componentFlagsMask = 0;
|
||||
|
||||
// Search for component with given description
|
||||
comp = FindNextComponent(NULL, &desc);
|
||||
if(comp == NULL)
|
||||
{
|
||||
ERR("FindNextComponent failed\n");
|
||||
return ALC_INVALID_VALUE;
|
||||
}
|
||||
|
||||
data = calloc(1, sizeof(*data));
|
||||
device->ExtraData = data;
|
||||
|
||||
// Open the component
|
||||
err = OpenAComponent(comp, &data->audioUnit);
|
||||
if(err != noErr)
|
||||
{
|
||||
ERR("OpenAComponent failed\n");
|
||||
goto error;
|
||||
}
|
||||
|
||||
// Turn off AudioUnit output
|
||||
enableIO = 0;
|
||||
err = AudioUnitSetProperty(data->audioUnit, kAudioOutputUnitProperty_EnableIO, kAudioUnitScope_Output, 0, &enableIO, sizeof(ALuint));
|
||||
if(err != noErr)
|
||||
{
|
||||
ERR("AudioUnitSetProperty failed\n");
|
||||
goto error;
|
||||
}
|
||||
|
||||
// Turn on AudioUnit input
|
||||
enableIO = 1;
|
||||
err = AudioUnitSetProperty(data->audioUnit, kAudioOutputUnitProperty_EnableIO, kAudioUnitScope_Input, 1, &enableIO, sizeof(ALuint));
|
||||
if(err != noErr)
|
||||
{
|
||||
ERR("AudioUnitSetProperty failed\n");
|
||||
goto error;
|
||||
}
|
||||
|
||||
// Get the default input device
|
||||
propertySize = sizeof(AudioDeviceID);
|
||||
err = AudioHardwareGetProperty(kAudioHardwarePropertyDefaultInputDevice, &propertySize, &inputDevice);
|
||||
if(err != noErr)
|
||||
{
|
||||
ERR("AudioHardwareGetProperty failed\n");
|
||||
goto error;
|
||||
}
|
||||
|
||||
if(inputDevice == kAudioDeviceUnknown)
|
||||
{
|
||||
ERR("No input device found\n");
|
||||
goto error;
|
||||
}
|
||||
|
||||
// Track the input device
|
||||
err = AudioUnitSetProperty(data->audioUnit, kAudioOutputUnitProperty_CurrentDevice, kAudioUnitScope_Global, 0, &inputDevice, sizeof(AudioDeviceID));
|
||||
if(err != noErr)
|
||||
{
|
||||
ERR("AudioUnitSetProperty failed\n");
|
||||
goto error;
|
||||
}
|
||||
|
||||
// set capture callback
|
||||
input.inputProc = ca_capture_callback;
|
||||
input.inputProcRefCon = device;
|
||||
|
||||
err = AudioUnitSetProperty(data->audioUnit, kAudioOutputUnitProperty_SetInputCallback, kAudioUnitScope_Global, 0, &input, sizeof(AURenderCallbackStruct));
|
||||
if(err != noErr)
|
||||
{
|
||||
ERR("AudioUnitSetProperty failed\n");
|
||||
goto error;
|
||||
}
|
||||
|
||||
// Initialize the device
|
||||
err = AudioUnitInitialize(data->audioUnit);
|
||||
if(err != noErr)
|
||||
{
|
||||
ERR("AudioUnitInitialize failed\n");
|
||||
goto error;
|
||||
}
|
||||
|
||||
// Get the hardware format
|
||||
propertySize = sizeof(AudioStreamBasicDescription);
|
||||
err = AudioUnitGetProperty(data->audioUnit, kAudioUnitProperty_StreamFormat, kAudioUnitScope_Input, 1, &hardwareFormat, &propertySize);
|
||||
if(err != noErr || propertySize != sizeof(AudioStreamBasicDescription))
|
||||
{
|
||||
ERR("AudioUnitGetProperty failed\n");
|
||||
goto error;
|
||||
}
|
||||
|
||||
// Set up the requested format description
|
||||
switch(device->FmtType)
|
||||
{
|
||||
case DevFmtUByte:
|
||||
requestedFormat.mBitsPerChannel = 8;
|
||||
requestedFormat.mFormatFlags = kAudioFormatFlagIsPacked;
|
||||
break;
|
||||
case DevFmtShort:
|
||||
requestedFormat.mBitsPerChannel = 16;
|
||||
requestedFormat.mFormatFlags = kAudioFormatFlagIsSignedInteger | kAudioFormatFlagsNativeEndian | kAudioFormatFlagIsPacked;
|
||||
break;
|
||||
case DevFmtInt:
|
||||
requestedFormat.mBitsPerChannel = 32;
|
||||
requestedFormat.mFormatFlags = kAudioFormatFlagIsSignedInteger | kAudioFormatFlagsNativeEndian | kAudioFormatFlagIsPacked;
|
||||
break;
|
||||
case DevFmtFloat:
|
||||
requestedFormat.mBitsPerChannel = 32;
|
||||
requestedFormat.mFormatFlags = kAudioFormatFlagIsPacked;
|
||||
break;
|
||||
case DevFmtByte:
|
||||
case DevFmtUShort:
|
||||
case DevFmtUInt:
|
||||
ERR("%s samples not supported\n", DevFmtTypeString(device->FmtType));
|
||||
goto error;
|
||||
}
|
||||
|
||||
switch(device->FmtChans)
|
||||
{
|
||||
case DevFmtMono:
|
||||
requestedFormat.mChannelsPerFrame = 1;
|
||||
break;
|
||||
case DevFmtStereo:
|
||||
requestedFormat.mChannelsPerFrame = 2;
|
||||
break;
|
||||
|
||||
case DevFmtQuad:
|
||||
case DevFmtX51:
|
||||
case DevFmtX51Side:
|
||||
case DevFmtX61:
|
||||
case DevFmtX71:
|
||||
ERR("%s not supported\n", DevFmtChannelsString(device->FmtChans));
|
||||
goto error;
|
||||
}
|
||||
|
||||
requestedFormat.mBytesPerFrame = requestedFormat.mChannelsPerFrame * requestedFormat.mBitsPerChannel / 8;
|
||||
requestedFormat.mBytesPerPacket = requestedFormat.mBytesPerFrame;
|
||||
requestedFormat.mSampleRate = device->Frequency;
|
||||
requestedFormat.mFormatID = kAudioFormatLinearPCM;
|
||||
requestedFormat.mReserved = 0;
|
||||
requestedFormat.mFramesPerPacket = 1;
|
||||
|
||||
// save requested format description for later use
|
||||
data->format = requestedFormat;
|
||||
data->frameSize = FrameSizeFromDevFmt(device->FmtChans, device->FmtType);
|
||||
|
||||
// Use intermediate format for sample rate conversion (outputFormat)
|
||||
// Set sample rate to the same as hardware for resampling later
|
||||
outputFormat = requestedFormat;
|
||||
outputFormat.mSampleRate = hardwareFormat.mSampleRate;
|
||||
|
||||
// Determine sample rate ratio for resampling
|
||||
data->sampleRateRatio = outputFormat.mSampleRate / device->Frequency;
|
||||
|
||||
// The output format should be the requested format, but using the hardware sample rate
|
||||
// This is because the AudioUnit will automatically scale other properties, except for sample rate
|
||||
err = AudioUnitSetProperty(data->audioUnit, kAudioUnitProperty_StreamFormat, kAudioUnitScope_Output, 1, (void *)&outputFormat, sizeof(outputFormat));
|
||||
if(err != noErr)
|
||||
{
|
||||
ERR("AudioUnitSetProperty failed\n");
|
||||
goto error;
|
||||
}
|
||||
|
||||
// Set the AudioUnit output format frame count
|
||||
outputFrameCount = device->UpdateSize * data->sampleRateRatio;
|
||||
err = AudioUnitSetProperty(data->audioUnit, kAudioUnitProperty_MaximumFramesPerSlice, kAudioUnitScope_Output, 0, &outputFrameCount, sizeof(outputFrameCount));
|
||||
if(err != noErr)
|
||||
{
|
||||
ERR("AudioUnitSetProperty failed: %d\n", err);
|
||||
goto error;
|
||||
}
|
||||
|
||||
// Set up sample converter
|
||||
err = AudioConverterNew(&outputFormat, &requestedFormat, &data->audioConverter);
|
||||
if(err != noErr)
|
||||
{
|
||||
ERR("AudioConverterNew failed: %d\n", err);
|
||||
goto error;
|
||||
}
|
||||
|
||||
// Create a buffer for use in the resample callback
|
||||
data->resampleBuffer = malloc(device->UpdateSize * data->frameSize * data->sampleRateRatio);
|
||||
|
||||
// Allocate buffer for the AudioUnit output
|
||||
data->bufferList = allocate_buffer_list(outputFormat.mChannelsPerFrame, device->UpdateSize * data->frameSize * data->sampleRateRatio);
|
||||
if(data->bufferList == NULL)
|
||||
goto error;
|
||||
|
||||
data->ring = CreateRingBuffer(data->frameSize, (device->UpdateSize * data->sampleRateRatio) * device->NumUpdates);
|
||||
if(data->ring == NULL)
|
||||
goto error;
|
||||
|
||||
return ALC_NO_ERROR;
|
||||
|
||||
error:
|
||||
DestroyRingBuffer(data->ring);
|
||||
free(data->resampleBuffer);
|
||||
destroy_buffer_list(data->bufferList);
|
||||
|
||||
if(data->audioConverter)
|
||||
AudioConverterDispose(data->audioConverter);
|
||||
if(data->audioUnit)
|
||||
CloseComponent(data->audioUnit);
|
||||
|
||||
free(data);
|
||||
device->ExtraData = NULL;
|
||||
|
||||
return ALC_INVALID_VALUE;
|
||||
}
|
||||
|
||||
static void ca_close_capture(ALCdevice *device)
|
||||
{
|
||||
ca_data *data = (ca_data*)device->ExtraData;
|
||||
|
||||
DestroyRingBuffer(data->ring);
|
||||
free(data->resampleBuffer);
|
||||
destroy_buffer_list(data->bufferList);
|
||||
|
||||
AudioConverterDispose(data->audioConverter);
|
||||
CloseComponent(data->audioUnit);
|
||||
|
||||
free(data);
|
||||
device->ExtraData = NULL;
|
||||
}
|
||||
|
||||
static void ca_start_capture(ALCdevice *device)
|
||||
{
|
||||
ca_data *data = (ca_data*)device->ExtraData;
|
||||
OSStatus err = AudioOutputUnitStart(data->audioUnit);
|
||||
if(err != noErr)
|
||||
ERR("AudioOutputUnitStart failed\n");
|
||||
}
|
||||
|
||||
static void ca_stop_capture(ALCdevice *device)
|
||||
{
|
||||
ca_data *data = (ca_data*)device->ExtraData;
|
||||
OSStatus err = AudioOutputUnitStop(data->audioUnit);
|
||||
if(err != noErr)
|
||||
ERR("AudioOutputUnitStop failed\n");
|
||||
}
|
||||
|
||||
static ALCenum ca_capture_samples(ALCdevice *device, ALCvoid *buffer, ALCuint samples)
|
||||
{
|
||||
ca_data *data = (ca_data*)device->ExtraData;
|
||||
AudioBufferList *list;
|
||||
UInt32 frameCount;
|
||||
OSStatus err;
|
||||
|
||||
// If no samples are requested, just return
|
||||
if(samples == 0)
|
||||
return ALC_NO_ERROR;
|
||||
|
||||
// Allocate a temporary AudioBufferList to use as the return resamples data
|
||||
list = alloca(sizeof(AudioBufferList) + sizeof(AudioBuffer));
|
||||
|
||||
// Point the resampling buffer to the capture buffer
|
||||
list->mNumberBuffers = 1;
|
||||
list->mBuffers[0].mNumberChannels = data->format.mChannelsPerFrame;
|
||||
list->mBuffers[0].mDataByteSize = samples * data->frameSize;
|
||||
list->mBuffers[0].mData = buffer;
|
||||
|
||||
// Resample into another AudioBufferList
|
||||
frameCount = samples;
|
||||
err = AudioConverterFillComplexBuffer(data->audioConverter, ca_capture_conversion_callback,
|
||||
device, &frameCount, list, NULL);
|
||||
if(err != noErr)
|
||||
{
|
||||
ERR("AudioConverterFillComplexBuffer error: %d\n", err);
|
||||
return ALC_INVALID_VALUE;
|
||||
}
|
||||
return ALC_NO_ERROR;
|
||||
}
|
||||
|
||||
static ALCuint ca_available_samples(ALCdevice *device)
|
||||
{
|
||||
ca_data *data = device->ExtraData;
|
||||
return RingBufferSize(data->ring) / data->sampleRateRatio;
|
||||
}
|
||||
|
||||
|
||||
static const BackendFuncs ca_funcs = {
|
||||
ca_open_playback,
|
||||
ca_close_playback,
|
||||
ca_reset_playback,
|
||||
ca_start_playback,
|
||||
ca_stop_playback,
|
||||
ca_open_capture,
|
||||
ca_close_capture,
|
||||
ca_start_capture,
|
||||
ca_stop_capture,
|
||||
ca_capture_samples,
|
||||
ca_available_samples,
|
||||
ALCdevice_LockDefault,
|
||||
ALCdevice_UnlockDefault,
|
||||
ALCdevice_GetLatencyDefault
|
||||
};
|
||||
|
||||
ALCboolean alc_ca_init(BackendFuncs *func_list)
|
||||
{
|
||||
*func_list = ca_funcs;
|
||||
return ALC_TRUE;
|
||||
}
|
||||
|
||||
void alc_ca_deinit(void)
|
||||
{
|
||||
}
|
||||
|
||||
void alc_ca_probe(enum DevProbe type)
|
||||
{
|
||||
switch(type)
|
||||
{
|
||||
case ALL_DEVICE_PROBE:
|
||||
AppendAllDevicesList(ca_device);
|
||||
break;
|
||||
case CAPTURE_DEVICE_PROBE:
|
||||
AppendCaptureDeviceList(ca_device);
|
||||
break;
|
||||
}
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,88 @@
|
||||
/**
|
||||
* OpenAL cross platform audio library
|
||||
* Copyright (C) 2011 by Chris Robinson
|
||||
* 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., 59 Temple Place - Suite 330,
|
||||
* Boston, MA 02111-1307, USA.
|
||||
* Or go to http://www.gnu.org/copyleft/lgpl.html
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "alMain.h"
|
||||
#include "alu.h"
|
||||
|
||||
|
||||
static ALCenum loopback_open_playback(ALCdevice *device, const ALCchar *deviceName)
|
||||
{
|
||||
device->DeviceName = strdup(deviceName);
|
||||
return ALC_NO_ERROR;
|
||||
}
|
||||
|
||||
static void loopback_close_playback(ALCdevice *device)
|
||||
{
|
||||
(void)device;
|
||||
}
|
||||
|
||||
static ALCboolean loopback_reset_playback(ALCdevice *device)
|
||||
{
|
||||
SetDefaultWFXChannelOrder(device);
|
||||
return ALC_TRUE;
|
||||
}
|
||||
|
||||
static ALCboolean loopback_start_playback(ALCdevice *device)
|
||||
{
|
||||
return ALC_TRUE;
|
||||
(void)device;
|
||||
}
|
||||
|
||||
static void loopback_stop_playback(ALCdevice *device)
|
||||
{
|
||||
(void)device;
|
||||
}
|
||||
|
||||
|
||||
static const BackendFuncs loopback_funcs = {
|
||||
loopback_open_playback,
|
||||
loopback_close_playback,
|
||||
loopback_reset_playback,
|
||||
loopback_start_playback,
|
||||
loopback_stop_playback,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
ALCdevice_LockDefault,
|
||||
ALCdevice_UnlockDefault,
|
||||
ALCdevice_GetLatencyDefault
|
||||
};
|
||||
|
||||
ALCboolean alc_loopback_init(BackendFuncs *func_list)
|
||||
{
|
||||
*func_list = loopback_funcs;
|
||||
return ALC_TRUE;
|
||||
}
|
||||
|
||||
void alc_loopback_deinit(void)
|
||||
{
|
||||
}
|
||||
|
||||
void alc_loopback_probe(enum DevProbe type)
|
||||
{
|
||||
(void)type;
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,172 @@
|
||||
/**
|
||||
* OpenAL cross platform audio library
|
||||
* Copyright (C) 2010 by Chris Robinson
|
||||
* 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., 59 Temple Place - Suite 330,
|
||||
* Boston, MA 02111-1307, USA.
|
||||
* Or go to http://www.gnu.org/copyleft/lgpl.html
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
#ifdef HAVE_WINDOWS_H
|
||||
#include <windows.h>
|
||||
#endif
|
||||
|
||||
#include "alMain.h"
|
||||
#include "alu.h"
|
||||
|
||||
|
||||
typedef struct {
|
||||
volatile int killNow;
|
||||
ALvoid *thread;
|
||||
} null_data;
|
||||
|
||||
|
||||
static const ALCchar nullDevice[] = "No Output";
|
||||
|
||||
static ALuint NullProc(ALvoid *ptr)
|
||||
{
|
||||
ALCdevice *Device = (ALCdevice*)ptr;
|
||||
null_data *data = (null_data*)Device->ExtraData;
|
||||
ALuint now, start;
|
||||
ALuint64 avail, done;
|
||||
const ALuint restTime = (ALuint64)Device->UpdateSize * 1000 /
|
||||
Device->Frequency / 2;
|
||||
|
||||
done = 0;
|
||||
start = timeGetTime();
|
||||
while(!data->killNow && Device->Connected)
|
||||
{
|
||||
now = timeGetTime();
|
||||
|
||||
avail = (ALuint64)(now-start) * Device->Frequency / 1000;
|
||||
if(avail < done)
|
||||
{
|
||||
/* Timer wrapped (50 days???). Add the remainder of the cycle to
|
||||
* the available count and reset the number of samples done */
|
||||
avail += ((ALuint64)1<<32)*Device->Frequency/1000 - done;
|
||||
done = 0;
|
||||
}
|
||||
if(avail-done < Device->UpdateSize)
|
||||
{
|
||||
Sleep(restTime);
|
||||
continue;
|
||||
}
|
||||
|
||||
while(avail-done >= Device->UpdateSize)
|
||||
{
|
||||
aluMixData(Device, NULL, Device->UpdateSize);
|
||||
done += Device->UpdateSize;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static ALCenum null_open_playback(ALCdevice *device, const ALCchar *deviceName)
|
||||
{
|
||||
null_data *data;
|
||||
|
||||
if(!deviceName)
|
||||
deviceName = nullDevice;
|
||||
else if(strcmp(deviceName, nullDevice) != 0)
|
||||
return ALC_INVALID_VALUE;
|
||||
|
||||
data = (null_data*)calloc(1, sizeof(*data));
|
||||
|
||||
device->DeviceName = strdup(deviceName);
|
||||
device->ExtraData = data;
|
||||
return ALC_NO_ERROR;
|
||||
}
|
||||
|
||||
static void null_close_playback(ALCdevice *device)
|
||||
{
|
||||
null_data *data = (null_data*)device->ExtraData;
|
||||
|
||||
free(data);
|
||||
device->ExtraData = NULL;
|
||||
}
|
||||
|
||||
static ALCboolean null_reset_playback(ALCdevice *device)
|
||||
{
|
||||
SetDefaultWFXChannelOrder(device);
|
||||
return ALC_TRUE;
|
||||
}
|
||||
|
||||
static ALCboolean null_start_playback(ALCdevice *device)
|
||||
{
|
||||
null_data *data = (null_data*)device->ExtraData;
|
||||
|
||||
data->thread = StartThread(NullProc, device);
|
||||
if(data->thread == NULL)
|
||||
return ALC_FALSE;
|
||||
|
||||
return ALC_TRUE;
|
||||
}
|
||||
|
||||
static void null_stop_playback(ALCdevice *device)
|
||||
{
|
||||
null_data *data = (null_data*)device->ExtraData;
|
||||
|
||||
if(!data->thread)
|
||||
return;
|
||||
|
||||
data->killNow = 1;
|
||||
StopThread(data->thread);
|
||||
data->thread = NULL;
|
||||
|
||||
data->killNow = 0;
|
||||
}
|
||||
|
||||
|
||||
static const BackendFuncs null_funcs = {
|
||||
null_open_playback,
|
||||
null_close_playback,
|
||||
null_reset_playback,
|
||||
null_start_playback,
|
||||
null_stop_playback,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
ALCdevice_LockDefault,
|
||||
ALCdevice_UnlockDefault,
|
||||
ALCdevice_GetLatencyDefault
|
||||
};
|
||||
|
||||
ALCboolean alc_null_init(BackendFuncs *func_list)
|
||||
{
|
||||
*func_list = null_funcs;
|
||||
return ALC_TRUE;
|
||||
}
|
||||
|
||||
void alc_null_deinit(void)
|
||||
{
|
||||
}
|
||||
|
||||
void alc_null_probe(enum DevProbe type)
|
||||
{
|
||||
switch(type)
|
||||
{
|
||||
case ALL_DEVICE_PROBE:
|
||||
AppendAllDevicesList(nullDevice);
|
||||
break;
|
||||
case CAPTURE_DEVICE_PROBE:
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,442 @@
|
||||
/*
|
||||
* Copyright (C) 2011 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
/* This is an OpenAL backend for Android using the native audio APIs based on
|
||||
* OpenSL ES 1.0.1. It is based on source code for the native-audio sample app
|
||||
* bundled with NDK.
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "alMain.h"
|
||||
#include "alu.h"
|
||||
|
||||
|
||||
#include <SLES/OpenSLES.h>
|
||||
#if 1
|
||||
#include <SLES/OpenSLES_Android.h>
|
||||
#else
|
||||
extern SLAPIENTRY const SLInterfaceID SL_IID_ANDROIDSIMPLEBUFFERQUEUE;
|
||||
|
||||
struct SLAndroidSimpleBufferQueueItf_;
|
||||
typedef const struct SLAndroidSimpleBufferQueueItf_ * const * SLAndroidSimpleBufferQueueItf;
|
||||
|
||||
typedef void (*slAndroidSimpleBufferQueueCallback)(SLAndroidSimpleBufferQueueItf caller, void *pContext);
|
||||
|
||||
typedef struct SLAndroidSimpleBufferQueueState_ {
|
||||
SLuint32 count;
|
||||
SLuint32 index;
|
||||
} SLAndroidSimpleBufferQueueState;
|
||||
|
||||
|
||||
struct SLAndroidSimpleBufferQueueItf_ {
|
||||
SLresult (*Enqueue) (
|
||||
SLAndroidSimpleBufferQueueItf self,
|
||||
const void *pBuffer,
|
||||
SLuint32 size
|
||||
);
|
||||
SLresult (*Clear) (
|
||||
SLAndroidSimpleBufferQueueItf self
|
||||
);
|
||||
SLresult (*GetState) (
|
||||
SLAndroidSimpleBufferQueueItf self,
|
||||
SLAndroidSimpleBufferQueueState *pState
|
||||
);
|
||||
SLresult (*RegisterCallback) (
|
||||
SLAndroidSimpleBufferQueueItf self,
|
||||
slAndroidSimpleBufferQueueCallback callback,
|
||||
void* pContext
|
||||
);
|
||||
};
|
||||
|
||||
#define SL_DATALOCATOR_ANDROIDSIMPLEBUFFERQUEUE ((SLuint32) 0x800007BD)
|
||||
|
||||
typedef struct SLDataLocator_AndroidSimpleBufferQueue {
|
||||
SLuint32 locatorType;
|
||||
SLuint32 numBuffers;
|
||||
} SLDataLocator_AndroidSimpleBufferQueue;
|
||||
|
||||
#endif
|
||||
|
||||
/* Helper macros */
|
||||
#define SLObjectItf_Realize(a,b) ((*(a))->Realize((a),(b)))
|
||||
#define SLObjectItf_GetInterface(a,b,c) ((*(a))->GetInterface((a),(b),(c)))
|
||||
#define SLObjectItf_Destroy(a) ((*(a))->Destroy((a)))
|
||||
|
||||
#define SLEngineItf_CreateOutputMix(a,b,c,d,e) ((*(a))->CreateOutputMix((a),(b),(c),(d),(e)))
|
||||
#define SLEngineItf_CreateAudioPlayer(a,b,c,d,e,f,g) ((*(a))->CreateAudioPlayer((a),(b),(c),(d),(e),(f),(g)))
|
||||
|
||||
#define SLPlayItf_SetPlayState(a,b) ((*(a))->SetPlayState((a),(b)))
|
||||
|
||||
|
||||
typedef struct {
|
||||
/* engine interfaces */
|
||||
SLObjectItf engineObject;
|
||||
SLEngineItf engine;
|
||||
|
||||
/* output mix interfaces */
|
||||
SLObjectItf outputMix;
|
||||
|
||||
/* buffer queue player interfaces */
|
||||
SLObjectItf bufferQueueObject;
|
||||
|
||||
void *buffer;
|
||||
ALuint bufferSize;
|
||||
|
||||
ALuint frameSize;
|
||||
} osl_data;
|
||||
|
||||
|
||||
static const ALCchar opensl_device[] = "OpenSL";
|
||||
|
||||
|
||||
static SLuint32 GetChannelMask(enum DevFmtChannels chans)
|
||||
{
|
||||
switch(chans)
|
||||
{
|
||||
case DevFmtMono: return SL_SPEAKER_FRONT_CENTER;
|
||||
case DevFmtStereo: return SL_SPEAKER_FRONT_LEFT|SL_SPEAKER_FRONT_RIGHT;
|
||||
case DevFmtQuad: return SL_SPEAKER_FRONT_LEFT|SL_SPEAKER_FRONT_RIGHT|
|
||||
SL_SPEAKER_BACK_LEFT|SL_SPEAKER_BACK_RIGHT;
|
||||
case DevFmtX51: return SL_SPEAKER_FRONT_LEFT|SL_SPEAKER_FRONT_RIGHT|
|
||||
SL_SPEAKER_FRONT_CENTER|SL_SPEAKER_LOW_FREQUENCY|
|
||||
SL_SPEAKER_BACK_LEFT|SL_SPEAKER_BACK_RIGHT;
|
||||
case DevFmtX61: return SL_SPEAKER_FRONT_LEFT|SL_SPEAKER_FRONT_RIGHT|
|
||||
SL_SPEAKER_FRONT_CENTER|SL_SPEAKER_LOW_FREQUENCY|
|
||||
SL_SPEAKER_BACK_CENTER|
|
||||
SL_SPEAKER_SIDE_LEFT|SL_SPEAKER_SIDE_RIGHT;
|
||||
case DevFmtX71: return SL_SPEAKER_FRONT_LEFT|SL_SPEAKER_FRONT_RIGHT|
|
||||
SL_SPEAKER_FRONT_CENTER|SL_SPEAKER_LOW_FREQUENCY|
|
||||
SL_SPEAKER_BACK_LEFT|SL_SPEAKER_BACK_RIGHT|
|
||||
SL_SPEAKER_SIDE_LEFT|SL_SPEAKER_SIDE_RIGHT;
|
||||
case DevFmtX51Side: return SL_SPEAKER_FRONT_LEFT|SL_SPEAKER_FRONT_RIGHT|
|
||||
SL_SPEAKER_FRONT_CENTER|SL_SPEAKER_LOW_FREQUENCY|
|
||||
SL_SPEAKER_SIDE_LEFT|SL_SPEAKER_SIDE_RIGHT;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const char *res_str(SLresult result)
|
||||
{
|
||||
switch(result)
|
||||
{
|
||||
case SL_RESULT_SUCCESS: return "Success";
|
||||
case SL_RESULT_PRECONDITIONS_VIOLATED: return "Preconditions violated";
|
||||
case SL_RESULT_PARAMETER_INVALID: return "Parameter invalid";
|
||||
case SL_RESULT_MEMORY_FAILURE: return "Memory failure";
|
||||
case SL_RESULT_RESOURCE_ERROR: return "Resource error";
|
||||
case SL_RESULT_RESOURCE_LOST: return "Resource lost";
|
||||
case SL_RESULT_IO_ERROR: return "I/O error";
|
||||
case SL_RESULT_BUFFER_INSUFFICIENT: return "Buffer insufficient";
|
||||
case SL_RESULT_CONTENT_CORRUPTED: return "Content corrupted";
|
||||
case SL_RESULT_CONTENT_UNSUPPORTED: return "Content unsupported";
|
||||
case SL_RESULT_CONTENT_NOT_FOUND: return "Content not found";
|
||||
case SL_RESULT_PERMISSION_DENIED: return "Permission denied";
|
||||
case SL_RESULT_FEATURE_UNSUPPORTED: return "Feature unsupported";
|
||||
case SL_RESULT_INTERNAL_ERROR: return "Internal error";
|
||||
case SL_RESULT_UNKNOWN_ERROR: return "Unknown error";
|
||||
case SL_RESULT_OPERATION_ABORTED: return "Operation aborted";
|
||||
case SL_RESULT_CONTROL_LOST: return "Control lost";
|
||||
case SL_RESULT_READONLY: return "ReadOnly";
|
||||
case SL_RESULT_ENGINEOPTION_UNSUPPORTED: return "Engine option unsupported";
|
||||
case SL_RESULT_SOURCE_SINK_INCOMPATIBLE: return "Source/Sink incompatible";
|
||||
}
|
||||
return "Unknown error code";
|
||||
}
|
||||
|
||||
#define PRINTERR(x, s) do { \
|
||||
if((x) != SL_RESULT_SUCCESS) \
|
||||
ERR("%s: %s\n", (s), res_str((x))); \
|
||||
} while(0)
|
||||
|
||||
/* this callback handler is called every time a buffer finishes playing */
|
||||
static void opensl_callback(SLAndroidSimpleBufferQueueItf bq, void *context)
|
||||
{
|
||||
ALCdevice *Device = context;
|
||||
osl_data *data = Device->ExtraData;
|
||||
SLresult result;
|
||||
|
||||
aluMixData(Device, data->buffer, data->bufferSize/data->frameSize);
|
||||
|
||||
result = (*bq)->Enqueue(bq, data->buffer, data->bufferSize);
|
||||
PRINTERR(result, "bq->Enqueue");
|
||||
}
|
||||
|
||||
|
||||
static ALCenum opensl_open_playback(ALCdevice *Device, const ALCchar *deviceName)
|
||||
{
|
||||
osl_data *data = NULL;
|
||||
SLresult result;
|
||||
|
||||
if(!deviceName)
|
||||
deviceName = opensl_device;
|
||||
else if(strcmp(deviceName, opensl_device) != 0)
|
||||
return ALC_INVALID_VALUE;
|
||||
|
||||
data = calloc(1, sizeof(*data));
|
||||
if(!data)
|
||||
return ALC_OUT_OF_MEMORY;
|
||||
|
||||
// create engine
|
||||
result = slCreateEngine(&data->engineObject, 0, NULL, 0, NULL, NULL);
|
||||
PRINTERR(result, "slCreateEngine");
|
||||
if(SL_RESULT_SUCCESS == result)
|
||||
{
|
||||
result = SLObjectItf_Realize(data->engineObject, SL_BOOLEAN_FALSE);
|
||||
PRINTERR(result, "engine->Realize");
|
||||
}
|
||||
if(SL_RESULT_SUCCESS == result)
|
||||
{
|
||||
result = SLObjectItf_GetInterface(data->engineObject, SL_IID_ENGINE, &data->engine);
|
||||
PRINTERR(result, "engine->GetInterface");
|
||||
}
|
||||
if(SL_RESULT_SUCCESS == result)
|
||||
{
|
||||
result = SLEngineItf_CreateOutputMix(data->engine, &data->outputMix, 0, NULL, NULL);
|
||||
PRINTERR(result, "engine->CreateOutputMix");
|
||||
}
|
||||
if(SL_RESULT_SUCCESS == result)
|
||||
{
|
||||
result = SLObjectItf_Realize(data->outputMix, SL_BOOLEAN_FALSE);
|
||||
PRINTERR(result, "outputMix->Realize");
|
||||
}
|
||||
|
||||
if(SL_RESULT_SUCCESS != result)
|
||||
{
|
||||
if(data->outputMix != NULL)
|
||||
SLObjectItf_Destroy(data->outputMix);
|
||||
data->outputMix = NULL;
|
||||
|
||||
if(data->engineObject != NULL)
|
||||
SLObjectItf_Destroy(data->engineObject);
|
||||
data->engineObject = NULL;
|
||||
data->engine = NULL;
|
||||
|
||||
free(data);
|
||||
return ALC_INVALID_VALUE;
|
||||
}
|
||||
|
||||
Device->DeviceName = strdup(deviceName);
|
||||
Device->ExtraData = data;
|
||||
|
||||
return ALC_NO_ERROR;
|
||||
}
|
||||
|
||||
|
||||
static void opensl_close_playback(ALCdevice *Device)
|
||||
{
|
||||
osl_data *data = Device->ExtraData;
|
||||
|
||||
if(data->bufferQueueObject != NULL)
|
||||
SLObjectItf_Destroy(data->bufferQueueObject);
|
||||
data->bufferQueueObject = NULL;
|
||||
|
||||
SLObjectItf_Destroy(data->outputMix);
|
||||
data->outputMix = NULL;
|
||||
|
||||
SLObjectItf_Destroy(data->engineObject);
|
||||
data->engineObject = NULL;
|
||||
data->engine = NULL;
|
||||
|
||||
free(data);
|
||||
Device->ExtraData = NULL;
|
||||
}
|
||||
|
||||
static ALCboolean opensl_reset_playback(ALCdevice *Device)
|
||||
{
|
||||
osl_data *data = Device->ExtraData;
|
||||
SLDataLocator_AndroidSimpleBufferQueue loc_bufq;
|
||||
SLDataLocator_OutputMix loc_outmix;
|
||||
SLDataFormat_PCM format_pcm;
|
||||
SLDataSource audioSrc;
|
||||
SLDataSink audioSnk;
|
||||
SLInterfaceID id;
|
||||
SLboolean req;
|
||||
SLresult result;
|
||||
|
||||
|
||||
Device->UpdateSize = (ALuint64)Device->UpdateSize * 44100 / Device->Frequency;
|
||||
Device->UpdateSize = Device->UpdateSize * Device->NumUpdates / 2;
|
||||
Device->NumUpdates = 2;
|
||||
|
||||
Device->Frequency = 44100;
|
||||
Device->FmtChans = DevFmtStereo;
|
||||
Device->FmtType = DevFmtShort;
|
||||
|
||||
SetDefaultWFXChannelOrder(Device);
|
||||
|
||||
|
||||
id = SL_IID_ANDROIDSIMPLEBUFFERQUEUE;
|
||||
req = SL_BOOLEAN_TRUE;
|
||||
|
||||
loc_bufq.locatorType = SL_DATALOCATOR_ANDROIDSIMPLEBUFFERQUEUE;
|
||||
loc_bufq.numBuffers = Device->NumUpdates;
|
||||
|
||||
format_pcm.formatType = SL_DATAFORMAT_PCM;
|
||||
format_pcm.numChannels = ChannelsFromDevFmt(Device->FmtChans);
|
||||
format_pcm.samplesPerSec = Device->Frequency * 1000;
|
||||
format_pcm.bitsPerSample = BytesFromDevFmt(Device->FmtType) * 8;
|
||||
format_pcm.containerSize = format_pcm.bitsPerSample;
|
||||
format_pcm.channelMask = GetChannelMask(Device->FmtChans);
|
||||
format_pcm.endianness = SL_BYTEORDER_NATIVE;
|
||||
|
||||
audioSrc.pLocator = &loc_bufq;
|
||||
audioSrc.pFormat = &format_pcm;
|
||||
|
||||
loc_outmix.locatorType = SL_DATALOCATOR_OUTPUTMIX;
|
||||
loc_outmix.outputMix = data->outputMix;
|
||||
audioSnk.pLocator = &loc_outmix;
|
||||
audioSnk.pFormat = NULL;
|
||||
|
||||
|
||||
if(data->bufferQueueObject != NULL)
|
||||
SLObjectItf_Destroy(data->bufferQueueObject);
|
||||
data->bufferQueueObject = NULL;
|
||||
|
||||
result = SLEngineItf_CreateAudioPlayer(data->engine, &data->bufferQueueObject, &audioSrc, &audioSnk, 1, &id, &req);
|
||||
PRINTERR(result, "engine->CreateAudioPlayer");
|
||||
if(SL_RESULT_SUCCESS == result)
|
||||
{
|
||||
result = SLObjectItf_Realize(data->bufferQueueObject, SL_BOOLEAN_FALSE);
|
||||
PRINTERR(result, "bufferQueue->Realize");
|
||||
}
|
||||
|
||||
if(SL_RESULT_SUCCESS != result)
|
||||
{
|
||||
if(data->bufferQueueObject != NULL)
|
||||
SLObjectItf_Destroy(data->bufferQueueObject);
|
||||
data->bufferQueueObject = NULL;
|
||||
|
||||
return ALC_FALSE;
|
||||
}
|
||||
|
||||
return ALC_TRUE;
|
||||
}
|
||||
|
||||
static ALCboolean opensl_start_playback(ALCdevice *Device)
|
||||
{
|
||||
osl_data *data = Device->ExtraData;
|
||||
SLAndroidSimpleBufferQueueItf bufferQueue;
|
||||
SLPlayItf player;
|
||||
SLresult result;
|
||||
ALuint i;
|
||||
|
||||
result = SLObjectItf_GetInterface(data->bufferQueueObject, SL_IID_BUFFERQUEUE, &bufferQueue);
|
||||
PRINTERR(result, "bufferQueue->GetInterface");
|
||||
if(SL_RESULT_SUCCESS == result)
|
||||
{
|
||||
result = (*bufferQueue)->RegisterCallback(bufferQueue, opensl_callback, Device);
|
||||
PRINTERR(result, "bufferQueue->RegisterCallback");
|
||||
}
|
||||
if(SL_RESULT_SUCCESS == result)
|
||||
{
|
||||
data->frameSize = FrameSizeFromDevFmt(Device->FmtChans, Device->FmtType);
|
||||
data->bufferSize = Device->UpdateSize * data->frameSize;
|
||||
data->buffer = calloc(1, data->bufferSize);
|
||||
if(!data->buffer)
|
||||
{
|
||||
result = SL_RESULT_MEMORY_FAILURE;
|
||||
PRINTERR(result, "calloc");
|
||||
}
|
||||
}
|
||||
/* enqueue the first buffer to kick off the callbacks */
|
||||
for(i = 0;i < Device->NumUpdates;i++)
|
||||
{
|
||||
if(SL_RESULT_SUCCESS == result)
|
||||
{
|
||||
result = (*bufferQueue)->Enqueue(bufferQueue, data->buffer, data->bufferSize);
|
||||
PRINTERR(result, "bufferQueue->Enqueue");
|
||||
}
|
||||
}
|
||||
if(SL_RESULT_SUCCESS == result)
|
||||
{
|
||||
result = SLObjectItf_GetInterface(data->bufferQueueObject, SL_IID_PLAY, &player);
|
||||
PRINTERR(result, "bufferQueue->GetInterface");
|
||||
}
|
||||
if(SL_RESULT_SUCCESS == result)
|
||||
{
|
||||
result = SLPlayItf_SetPlayState(player, SL_PLAYSTATE_PLAYING);
|
||||
PRINTERR(result, "player->SetPlayState");
|
||||
}
|
||||
|
||||
if(SL_RESULT_SUCCESS != result)
|
||||
{
|
||||
if(data->bufferQueueObject != NULL)
|
||||
SLObjectItf_Destroy(data->bufferQueueObject);
|
||||
data->bufferQueueObject = NULL;
|
||||
|
||||
free(data->buffer);
|
||||
data->buffer = NULL;
|
||||
data->bufferSize = 0;
|
||||
|
||||
return ALC_FALSE;
|
||||
}
|
||||
|
||||
return ALC_TRUE;
|
||||
}
|
||||
|
||||
|
||||
static void opensl_stop_playback(ALCdevice *Device)
|
||||
{
|
||||
osl_data *data = Device->ExtraData;
|
||||
|
||||
free(data->buffer);
|
||||
data->buffer = NULL;
|
||||
data->bufferSize = 0;
|
||||
}
|
||||
|
||||
|
||||
static const BackendFuncs opensl_funcs = {
|
||||
opensl_open_playback,
|
||||
opensl_close_playback,
|
||||
opensl_reset_playback,
|
||||
opensl_start_playback,
|
||||
opensl_stop_playback,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
ALCdevice_LockDefault,
|
||||
ALCdevice_UnlockDefault,
|
||||
ALCdevice_GetLatencyDefault
|
||||
};
|
||||
|
||||
|
||||
ALCboolean alc_opensl_init(BackendFuncs *func_list)
|
||||
{
|
||||
*func_list = opensl_funcs;
|
||||
return ALC_TRUE;
|
||||
}
|
||||
|
||||
void alc_opensl_deinit(void)
|
||||
{
|
||||
}
|
||||
|
||||
void alc_opensl_probe(enum DevProbe type)
|
||||
{
|
||||
switch(type)
|
||||
{
|
||||
case ALL_DEVICE_PROBE:
|
||||
AppendAllDevicesList(opensl_device);
|
||||
break;
|
||||
case CAPTURE_DEVICE_PROBE:
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,537 @@
|
||||
/**
|
||||
* OpenAL cross platform audio library
|
||||
* Copyright (C) 1999-2007 by authors.
|
||||
* 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., 59 Temple Place - Suite 330,
|
||||
* Boston, MA 02111-1307, USA.
|
||||
* Or go to http://www.gnu.org/copyleft/lgpl.html
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <sys/ioctl.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <fcntl.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <memory.h>
|
||||
#include <unistd.h>
|
||||
#include <errno.h>
|
||||
#include <math.h>
|
||||
|
||||
#include "alMain.h"
|
||||
#include "alu.h"
|
||||
|
||||
#include <sys/soundcard.h>
|
||||
|
||||
/*
|
||||
* The OSS documentation talks about SOUND_MIXER_READ, but the header
|
||||
* only contains MIXER_READ. Play safe. Same for WRITE.
|
||||
*/
|
||||
#ifndef SOUND_MIXER_READ
|
||||
#define SOUND_MIXER_READ MIXER_READ
|
||||
#endif
|
||||
#ifndef SOUND_MIXER_WRITE
|
||||
#define SOUND_MIXER_WRITE MIXER_WRITE
|
||||
#endif
|
||||
|
||||
static const ALCchar oss_device[] = "OSS Default";
|
||||
|
||||
static const char *oss_driver = "/dev/dsp";
|
||||
static const char *oss_capture = "/dev/dsp";
|
||||
|
||||
typedef struct {
|
||||
int fd;
|
||||
volatile int killNow;
|
||||
ALvoid *thread;
|
||||
|
||||
ALubyte *mix_data;
|
||||
int data_size;
|
||||
|
||||
RingBuffer *ring;
|
||||
int doCapture;
|
||||
} oss_data;
|
||||
|
||||
|
||||
static int log2i(ALCuint x)
|
||||
{
|
||||
int y = 0;
|
||||
while (x > 1)
|
||||
{
|
||||
x >>= 1;
|
||||
y++;
|
||||
}
|
||||
return y;
|
||||
}
|
||||
|
||||
|
||||
static ALuint OSSProc(ALvoid *ptr)
|
||||
{
|
||||
ALCdevice *Device = (ALCdevice*)ptr;
|
||||
oss_data *data = (oss_data*)Device->ExtraData;
|
||||
ALint frameSize;
|
||||
ssize_t wrote;
|
||||
|
||||
SetRTPriority();
|
||||
|
||||
frameSize = FrameSizeFromDevFmt(Device->FmtChans, Device->FmtType);
|
||||
|
||||
while(!data->killNow && Device->Connected)
|
||||
{
|
||||
ALint len = data->data_size;
|
||||
ALubyte *WritePtr = data->mix_data;
|
||||
|
||||
aluMixData(Device, WritePtr, len/frameSize);
|
||||
while(len > 0 && !data->killNow)
|
||||
{
|
||||
wrote = write(data->fd, WritePtr, len);
|
||||
if(wrote < 0)
|
||||
{
|
||||
if(errno != EAGAIN && errno != EWOULDBLOCK && errno != EINTR)
|
||||
{
|
||||
ERR("write failed: %s\n", strerror(errno));
|
||||
ALCdevice_Lock(Device);
|
||||
aluHandleDisconnect(Device);
|
||||
ALCdevice_Unlock(Device);
|
||||
break;
|
||||
}
|
||||
|
||||
Sleep(1);
|
||||
continue;
|
||||
}
|
||||
|
||||
len -= wrote;
|
||||
WritePtr += wrote;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static ALuint OSSCaptureProc(ALvoid *ptr)
|
||||
{
|
||||
ALCdevice *Device = (ALCdevice*)ptr;
|
||||
oss_data *data = (oss_data*)Device->ExtraData;
|
||||
int frameSize;
|
||||
int amt;
|
||||
|
||||
SetRTPriority();
|
||||
|
||||
frameSize = FrameSizeFromDevFmt(Device->FmtChans, Device->FmtType);
|
||||
|
||||
while(!data->killNow)
|
||||
{
|
||||
amt = read(data->fd, data->mix_data, data->data_size);
|
||||
if(amt < 0)
|
||||
{
|
||||
ERR("read failed: %s\n", strerror(errno));
|
||||
ALCdevice_Lock(Device);
|
||||
aluHandleDisconnect(Device);
|
||||
ALCdevice_Unlock(Device);
|
||||
break;
|
||||
}
|
||||
if(amt == 0)
|
||||
{
|
||||
Sleep(1);
|
||||
continue;
|
||||
}
|
||||
if(data->doCapture)
|
||||
WriteRingBuffer(data->ring, data->mix_data, amt/frameSize);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static ALCenum oss_open_playback(ALCdevice *device, const ALCchar *deviceName)
|
||||
{
|
||||
oss_data *data;
|
||||
|
||||
if(!deviceName)
|
||||
deviceName = oss_device;
|
||||
else if(strcmp(deviceName, oss_device) != 0)
|
||||
return ALC_INVALID_VALUE;
|
||||
|
||||
data = (oss_data*)calloc(1, sizeof(oss_data));
|
||||
data->killNow = 0;
|
||||
|
||||
data->fd = open(oss_driver, O_WRONLY);
|
||||
if(data->fd == -1)
|
||||
{
|
||||
free(data);
|
||||
ERR("Could not open %s: %s\n", oss_driver, strerror(errno));
|
||||
return ALC_INVALID_VALUE;
|
||||
}
|
||||
|
||||
device->DeviceName = strdup(deviceName);
|
||||
device->ExtraData = data;
|
||||
return ALC_NO_ERROR;
|
||||
}
|
||||
|
||||
static void oss_close_playback(ALCdevice *device)
|
||||
{
|
||||
oss_data *data = (oss_data*)device->ExtraData;
|
||||
|
||||
close(data->fd);
|
||||
free(data);
|
||||
device->ExtraData = NULL;
|
||||
}
|
||||
|
||||
static ALCboolean oss_reset_playback(ALCdevice *device)
|
||||
{
|
||||
oss_data *data = (oss_data*)device->ExtraData;
|
||||
int numFragmentsLogSize;
|
||||
int log2FragmentSize;
|
||||
unsigned int periods;
|
||||
audio_buf_info info;
|
||||
ALuint frameSize;
|
||||
int numChannels;
|
||||
int ossFormat;
|
||||
int ossSpeed;
|
||||
char *err;
|
||||
|
||||
switch(device->FmtType)
|
||||
{
|
||||
case DevFmtByte:
|
||||
ossFormat = AFMT_S8;
|
||||
break;
|
||||
case DevFmtUByte:
|
||||
ossFormat = AFMT_U8;
|
||||
break;
|
||||
case DevFmtUShort:
|
||||
case DevFmtInt:
|
||||
case DevFmtUInt:
|
||||
case DevFmtFloat:
|
||||
device->FmtType = DevFmtShort;
|
||||
/* fall-through */
|
||||
case DevFmtShort:
|
||||
ossFormat = AFMT_S16_NE;
|
||||
break;
|
||||
}
|
||||
|
||||
periods = device->NumUpdates;
|
||||
numChannels = ChannelsFromDevFmt(device->FmtChans);
|
||||
frameSize = numChannels * BytesFromDevFmt(device->FmtType);
|
||||
|
||||
ossSpeed = device->Frequency;
|
||||
log2FragmentSize = log2i(device->UpdateSize * frameSize);
|
||||
|
||||
/* according to the OSS spec, 16 bytes are the minimum */
|
||||
if (log2FragmentSize < 4)
|
||||
log2FragmentSize = 4;
|
||||
/* Subtract one period since the temp mixing buffer counts as one. Still
|
||||
* need at least two on the card, though. */
|
||||
if(periods > 2) periods--;
|
||||
numFragmentsLogSize = (periods << 16) | log2FragmentSize;
|
||||
|
||||
#define CHECKERR(func) if((func) < 0) { \
|
||||
err = #func; \
|
||||
goto err; \
|
||||
}
|
||||
/* Don't fail if SETFRAGMENT fails. We can handle just about anything
|
||||
* that's reported back via GETOSPACE */
|
||||
ioctl(data->fd, SNDCTL_DSP_SETFRAGMENT, &numFragmentsLogSize);
|
||||
CHECKERR(ioctl(data->fd, SNDCTL_DSP_SETFMT, &ossFormat));
|
||||
CHECKERR(ioctl(data->fd, SNDCTL_DSP_CHANNELS, &numChannels));
|
||||
CHECKERR(ioctl(data->fd, SNDCTL_DSP_SPEED, &ossSpeed));
|
||||
CHECKERR(ioctl(data->fd, SNDCTL_DSP_GETOSPACE, &info));
|
||||
if(0)
|
||||
{
|
||||
err:
|
||||
ERR("%s failed: %s\n", err, strerror(errno));
|
||||
return ALC_FALSE;
|
||||
}
|
||||
#undef CHECKERR
|
||||
|
||||
if((int)ChannelsFromDevFmt(device->FmtChans) != numChannels)
|
||||
{
|
||||
ERR("Failed to set %s, got %d channels instead\n", DevFmtChannelsString(device->FmtChans), numChannels);
|
||||
return ALC_FALSE;
|
||||
}
|
||||
|
||||
if(!((ossFormat == AFMT_S8 && device->FmtType == DevFmtByte) ||
|
||||
(ossFormat == AFMT_U8 && device->FmtType == DevFmtUByte) ||
|
||||
(ossFormat == AFMT_S16_NE && device->FmtType == DevFmtShort)))
|
||||
{
|
||||
ERR("Failed to set %s samples, got OSS format %#x\n", DevFmtTypeString(device->FmtType), ossFormat);
|
||||
return ALC_FALSE;
|
||||
}
|
||||
|
||||
device->Frequency = ossSpeed;
|
||||
device->UpdateSize = info.fragsize / frameSize;
|
||||
device->NumUpdates = info.fragments + 1;
|
||||
|
||||
SetDefaultChannelOrder(device);
|
||||
|
||||
return ALC_TRUE;
|
||||
}
|
||||
|
||||
static ALCboolean oss_start_playback(ALCdevice *device)
|
||||
{
|
||||
oss_data *data = (oss_data*)device->ExtraData;
|
||||
|
||||
data->data_size = device->UpdateSize * FrameSizeFromDevFmt(device->FmtChans, device->FmtType);
|
||||
data->mix_data = calloc(1, data->data_size);
|
||||
|
||||
data->thread = StartThread(OSSProc, device);
|
||||
if(data->thread == NULL)
|
||||
{
|
||||
free(data->mix_data);
|
||||
data->mix_data = NULL;
|
||||
return ALC_FALSE;
|
||||
}
|
||||
|
||||
return ALC_TRUE;
|
||||
}
|
||||
|
||||
static void oss_stop_playback(ALCdevice *device)
|
||||
{
|
||||
oss_data *data = (oss_data*)device->ExtraData;
|
||||
|
||||
if(!data->thread)
|
||||
return;
|
||||
|
||||
data->killNow = 1;
|
||||
StopThread(data->thread);
|
||||
data->thread = NULL;
|
||||
|
||||
data->killNow = 0;
|
||||
if(ioctl(data->fd, SNDCTL_DSP_RESET) != 0)
|
||||
ERR("Error resetting device: %s\n", strerror(errno));
|
||||
|
||||
free(data->mix_data);
|
||||
data->mix_data = NULL;
|
||||
}
|
||||
|
||||
|
||||
static ALCenum oss_open_capture(ALCdevice *device, const ALCchar *deviceName)
|
||||
{
|
||||
int numFragmentsLogSize;
|
||||
int log2FragmentSize;
|
||||
unsigned int periods;
|
||||
audio_buf_info info;
|
||||
ALuint frameSize;
|
||||
int numChannels;
|
||||
oss_data *data;
|
||||
int ossFormat;
|
||||
int ossSpeed;
|
||||
char *err;
|
||||
|
||||
if(!deviceName)
|
||||
deviceName = oss_device;
|
||||
else if(strcmp(deviceName, oss_device) != 0)
|
||||
return ALC_INVALID_VALUE;
|
||||
|
||||
data = (oss_data*)calloc(1, sizeof(oss_data));
|
||||
data->killNow = 0;
|
||||
|
||||
data->fd = open(oss_capture, O_RDONLY);
|
||||
if(data->fd == -1)
|
||||
{
|
||||
free(data);
|
||||
ERR("Could not open %s: %s\n", oss_capture, strerror(errno));
|
||||
return ALC_INVALID_VALUE;
|
||||
}
|
||||
|
||||
switch(device->FmtType)
|
||||
{
|
||||
case DevFmtByte:
|
||||
ossFormat = AFMT_S8;
|
||||
break;
|
||||
case DevFmtUByte:
|
||||
ossFormat = AFMT_U8;
|
||||
break;
|
||||
case DevFmtShort:
|
||||
ossFormat = AFMT_S16_NE;
|
||||
break;
|
||||
case DevFmtUShort:
|
||||
case DevFmtInt:
|
||||
case DevFmtUInt:
|
||||
case DevFmtFloat:
|
||||
free(data);
|
||||
ERR("%s capture samples not supported\n", DevFmtTypeString(device->FmtType));
|
||||
return ALC_INVALID_VALUE;
|
||||
}
|
||||
|
||||
periods = 4;
|
||||
numChannels = ChannelsFromDevFmt(device->FmtChans);
|
||||
frameSize = numChannels * BytesFromDevFmt(device->FmtType);
|
||||
ossSpeed = device->Frequency;
|
||||
log2FragmentSize = log2i(device->UpdateSize * device->NumUpdates *
|
||||
frameSize / periods);
|
||||
|
||||
/* according to the OSS spec, 16 bytes are the minimum */
|
||||
if (log2FragmentSize < 4)
|
||||
log2FragmentSize = 4;
|
||||
numFragmentsLogSize = (periods << 16) | log2FragmentSize;
|
||||
|
||||
#define CHECKERR(func) if((func) < 0) { \
|
||||
err = #func; \
|
||||
goto err; \
|
||||
}
|
||||
CHECKERR(ioctl(data->fd, SNDCTL_DSP_SETFRAGMENT, &numFragmentsLogSize));
|
||||
CHECKERR(ioctl(data->fd, SNDCTL_DSP_SETFMT, &ossFormat));
|
||||
CHECKERR(ioctl(data->fd, SNDCTL_DSP_CHANNELS, &numChannels));
|
||||
CHECKERR(ioctl(data->fd, SNDCTL_DSP_SPEED, &ossSpeed));
|
||||
CHECKERR(ioctl(data->fd, SNDCTL_DSP_GETISPACE, &info));
|
||||
if(0)
|
||||
{
|
||||
err:
|
||||
ERR("%s failed: %s\n", err, strerror(errno));
|
||||
close(data->fd);
|
||||
free(data);
|
||||
return ALC_INVALID_VALUE;
|
||||
}
|
||||
#undef CHECKERR
|
||||
|
||||
if((int)ChannelsFromDevFmt(device->FmtChans) != numChannels)
|
||||
{
|
||||
ERR("Failed to set %s, got %d channels instead\n", DevFmtChannelsString(device->FmtChans), numChannels);
|
||||
close(data->fd);
|
||||
free(data);
|
||||
return ALC_INVALID_VALUE;
|
||||
}
|
||||
|
||||
if(!((ossFormat == AFMT_S8 && device->FmtType == DevFmtByte) ||
|
||||
(ossFormat == AFMT_U8 && device->FmtType == DevFmtUByte) ||
|
||||
(ossFormat == AFMT_S16_NE && device->FmtType == DevFmtShort)))
|
||||
{
|
||||
ERR("Failed to set %s samples, got OSS format %#x\n", DevFmtTypeString(device->FmtType), ossFormat);
|
||||
close(data->fd);
|
||||
free(data);
|
||||
return ALC_INVALID_VALUE;
|
||||
}
|
||||
|
||||
data->ring = CreateRingBuffer(frameSize, device->UpdateSize * device->NumUpdates);
|
||||
if(!data->ring)
|
||||
{
|
||||
ERR("Ring buffer create failed\n");
|
||||
close(data->fd);
|
||||
free(data);
|
||||
return ALC_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
data->data_size = info.fragsize;
|
||||
data->mix_data = calloc(1, data->data_size);
|
||||
|
||||
device->ExtraData = data;
|
||||
data->thread = StartThread(OSSCaptureProc, device);
|
||||
if(data->thread == NULL)
|
||||
{
|
||||
device->ExtraData = NULL;
|
||||
free(data->mix_data);
|
||||
free(data);
|
||||
return ALC_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
device->DeviceName = strdup(deviceName);
|
||||
return ALC_NO_ERROR;
|
||||
}
|
||||
|
||||
static void oss_close_capture(ALCdevice *device)
|
||||
{
|
||||
oss_data *data = (oss_data*)device->ExtraData;
|
||||
data->killNow = 1;
|
||||
StopThread(data->thread);
|
||||
|
||||
close(data->fd);
|
||||
|
||||
DestroyRingBuffer(data->ring);
|
||||
|
||||
free(data->mix_data);
|
||||
free(data);
|
||||
device->ExtraData = NULL;
|
||||
}
|
||||
|
||||
static void oss_start_capture(ALCdevice *Device)
|
||||
{
|
||||
oss_data *data = (oss_data*)Device->ExtraData;
|
||||
data->doCapture = 1;
|
||||
}
|
||||
|
||||
static void oss_stop_capture(ALCdevice *Device)
|
||||
{
|
||||
oss_data *data = (oss_data*)Device->ExtraData;
|
||||
data->doCapture = 0;
|
||||
}
|
||||
|
||||
static ALCenum oss_capture_samples(ALCdevice *Device, ALCvoid *pBuffer, ALCuint lSamples)
|
||||
{
|
||||
oss_data *data = (oss_data*)Device->ExtraData;
|
||||
ReadRingBuffer(data->ring, pBuffer, lSamples);
|
||||
return ALC_NO_ERROR;
|
||||
}
|
||||
|
||||
static ALCuint oss_available_samples(ALCdevice *Device)
|
||||
{
|
||||
oss_data *data = (oss_data*)Device->ExtraData;
|
||||
return RingBufferSize(data->ring);
|
||||
}
|
||||
|
||||
|
||||
static const BackendFuncs oss_funcs = {
|
||||
oss_open_playback,
|
||||
oss_close_playback,
|
||||
oss_reset_playback,
|
||||
oss_start_playback,
|
||||
oss_stop_playback,
|
||||
oss_open_capture,
|
||||
oss_close_capture,
|
||||
oss_start_capture,
|
||||
oss_stop_capture,
|
||||
oss_capture_samples,
|
||||
oss_available_samples,
|
||||
ALCdevice_LockDefault,
|
||||
ALCdevice_UnlockDefault,
|
||||
ALCdevice_GetLatencyDefault
|
||||
};
|
||||
|
||||
ALCboolean alc_oss_init(BackendFuncs *func_list)
|
||||
{
|
||||
ConfigValueStr("oss", "device", &oss_driver);
|
||||
ConfigValueStr("oss", "capture", &oss_capture);
|
||||
|
||||
*func_list = oss_funcs;
|
||||
return ALC_TRUE;
|
||||
}
|
||||
|
||||
void alc_oss_deinit(void)
|
||||
{
|
||||
}
|
||||
|
||||
void alc_oss_probe(enum DevProbe type)
|
||||
{
|
||||
switch(type)
|
||||
{
|
||||
case ALL_DEVICE_PROBE:
|
||||
{
|
||||
#ifdef HAVE_STAT
|
||||
struct stat buf;
|
||||
if(stat(oss_driver, &buf) == 0)
|
||||
#endif
|
||||
AppendAllDevicesList(oss_device);
|
||||
}
|
||||
break;
|
||||
|
||||
case CAPTURE_DEVICE_PROBE:
|
||||
{
|
||||
#ifdef HAVE_STAT
|
||||
struct stat buf;
|
||||
if(stat(oss_capture, &buf) == 0)
|
||||
#endif
|
||||
AppendCaptureDeviceList(oss_device);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,472 @@
|
||||
/**
|
||||
* OpenAL cross platform audio library
|
||||
* Copyright (C) 1999-2007 by authors.
|
||||
* 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., 59 Temple Place - Suite 330,
|
||||
* Boston, MA 02111-1307, USA.
|
||||
* Or go to http://www.gnu.org/copyleft/lgpl.html
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "alMain.h"
|
||||
#include "alu.h"
|
||||
|
||||
#include <portaudio.h>
|
||||
|
||||
|
||||
static const ALCchar pa_device[] = "PortAudio Default";
|
||||
|
||||
|
||||
#ifdef HAVE_DYNLOAD
|
||||
static void *pa_handle;
|
||||
#define MAKE_FUNC(x) static typeof(x) * p##x
|
||||
MAKE_FUNC(Pa_Initialize);
|
||||
MAKE_FUNC(Pa_Terminate);
|
||||
MAKE_FUNC(Pa_GetErrorText);
|
||||
MAKE_FUNC(Pa_StartStream);
|
||||
MAKE_FUNC(Pa_StopStream);
|
||||
MAKE_FUNC(Pa_OpenStream);
|
||||
MAKE_FUNC(Pa_CloseStream);
|
||||
MAKE_FUNC(Pa_GetDefaultOutputDevice);
|
||||
MAKE_FUNC(Pa_GetStreamInfo);
|
||||
#undef MAKE_FUNC
|
||||
|
||||
#define Pa_Initialize pPa_Initialize
|
||||
#define Pa_Terminate pPa_Terminate
|
||||
#define Pa_GetErrorText pPa_GetErrorText
|
||||
#define Pa_StartStream pPa_StartStream
|
||||
#define Pa_StopStream pPa_StopStream
|
||||
#define Pa_OpenStream pPa_OpenStream
|
||||
#define Pa_CloseStream pPa_CloseStream
|
||||
#define Pa_GetDefaultOutputDevice pPa_GetDefaultOutputDevice
|
||||
#define Pa_GetStreamInfo pPa_GetStreamInfo
|
||||
#endif
|
||||
|
||||
static ALCboolean pa_load(void)
|
||||
{
|
||||
PaError err;
|
||||
|
||||
#ifdef HAVE_DYNLOAD
|
||||
if(!pa_handle)
|
||||
{
|
||||
#ifdef _WIN32
|
||||
# define PALIB "portaudio.dll"
|
||||
#elif defined(__APPLE__) && defined(__MACH__)
|
||||
# define PALIB "libportaudio.2.dylib"
|
||||
#elif defined(__OpenBSD__)
|
||||
# define PALIB "libportaudio.so"
|
||||
#else
|
||||
# define PALIB "libportaudio.so.2"
|
||||
#endif
|
||||
|
||||
pa_handle = LoadLib(PALIB);
|
||||
if(!pa_handle)
|
||||
return ALC_FALSE;
|
||||
|
||||
#define LOAD_FUNC(f) do { \
|
||||
p##f = GetSymbol(pa_handle, #f); \
|
||||
if(p##f == NULL) \
|
||||
{ \
|
||||
CloseLib(pa_handle); \
|
||||
pa_handle = NULL; \
|
||||
return ALC_FALSE; \
|
||||
} \
|
||||
} while(0)
|
||||
LOAD_FUNC(Pa_Initialize);
|
||||
LOAD_FUNC(Pa_Terminate);
|
||||
LOAD_FUNC(Pa_GetErrorText);
|
||||
LOAD_FUNC(Pa_StartStream);
|
||||
LOAD_FUNC(Pa_StopStream);
|
||||
LOAD_FUNC(Pa_OpenStream);
|
||||
LOAD_FUNC(Pa_CloseStream);
|
||||
LOAD_FUNC(Pa_GetDefaultOutputDevice);
|
||||
LOAD_FUNC(Pa_GetStreamInfo);
|
||||
#undef LOAD_FUNC
|
||||
|
||||
if((err=Pa_Initialize()) != paNoError)
|
||||
{
|
||||
ERR("Pa_Initialize() returned an error: %s\n", Pa_GetErrorText(err));
|
||||
CloseLib(pa_handle);
|
||||
pa_handle = NULL;
|
||||
return ALC_FALSE;
|
||||
}
|
||||
}
|
||||
#else
|
||||
if((err=Pa_Initialize()) != paNoError)
|
||||
{
|
||||
ERR("Pa_Initialize() returned an error: %s\n", Pa_GetErrorText(err));
|
||||
return ALC_FALSE;
|
||||
}
|
||||
#endif
|
||||
return ALC_TRUE;
|
||||
}
|
||||
|
||||
|
||||
typedef struct {
|
||||
PaStream *stream;
|
||||
PaStreamParameters params;
|
||||
ALuint update_size;
|
||||
|
||||
RingBuffer *ring;
|
||||
} pa_data;
|
||||
|
||||
|
||||
static int pa_callback(const void *inputBuffer, void *outputBuffer,
|
||||
unsigned long framesPerBuffer, const PaStreamCallbackTimeInfo *timeInfo,
|
||||
const PaStreamCallbackFlags statusFlags, void *userData)
|
||||
{
|
||||
ALCdevice *device = (ALCdevice*)userData;
|
||||
|
||||
(void)inputBuffer;
|
||||
(void)timeInfo;
|
||||
(void)statusFlags;
|
||||
|
||||
aluMixData(device, outputBuffer, framesPerBuffer);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int pa_capture_cb(const void *inputBuffer, void *outputBuffer,
|
||||
unsigned long framesPerBuffer, const PaStreamCallbackTimeInfo *timeInfo,
|
||||
const PaStreamCallbackFlags statusFlags, void *userData)
|
||||
{
|
||||
ALCdevice *device = (ALCdevice*)userData;
|
||||
pa_data *data = (pa_data*)device->ExtraData;
|
||||
|
||||
(void)outputBuffer;
|
||||
(void)timeInfo;
|
||||
(void)statusFlags;
|
||||
|
||||
WriteRingBuffer(data->ring, inputBuffer, framesPerBuffer);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static ALCenum pa_open_playback(ALCdevice *device, const ALCchar *deviceName)
|
||||
{
|
||||
pa_data *data;
|
||||
PaError err;
|
||||
|
||||
if(!deviceName)
|
||||
deviceName = pa_device;
|
||||
else if(strcmp(deviceName, pa_device) != 0)
|
||||
return ALC_INVALID_VALUE;
|
||||
|
||||
data = (pa_data*)calloc(1, sizeof(pa_data));
|
||||
data->update_size = device->UpdateSize;
|
||||
|
||||
data->params.device = -1;
|
||||
if(!ConfigValueInt("port", "device", &data->params.device) ||
|
||||
data->params.device < 0)
|
||||
data->params.device = Pa_GetDefaultOutputDevice();
|
||||
data->params.suggestedLatency = (device->UpdateSize*device->NumUpdates) /
|
||||
(float)device->Frequency;
|
||||
data->params.hostApiSpecificStreamInfo = NULL;
|
||||
|
||||
data->params.channelCount = ((device->FmtChans == DevFmtMono) ? 1 : 2);
|
||||
|
||||
switch(device->FmtType)
|
||||
{
|
||||
case DevFmtByte:
|
||||
data->params.sampleFormat = paInt8;
|
||||
break;
|
||||
case DevFmtUByte:
|
||||
data->params.sampleFormat = paUInt8;
|
||||
break;
|
||||
case DevFmtUShort:
|
||||
/* fall-through */
|
||||
case DevFmtShort:
|
||||
data->params.sampleFormat = paInt16;
|
||||
break;
|
||||
case DevFmtUInt:
|
||||
/* fall-through */
|
||||
case DevFmtInt:
|
||||
data->params.sampleFormat = paInt32;
|
||||
break;
|
||||
case DevFmtFloat:
|
||||
data->params.sampleFormat = paFloat32;
|
||||
break;
|
||||
}
|
||||
|
||||
retry_open:
|
||||
err = Pa_OpenStream(&data->stream, NULL, &data->params, device->Frequency,
|
||||
device->UpdateSize, paNoFlag, pa_callback, device);
|
||||
if(err != paNoError)
|
||||
{
|
||||
if(data->params.sampleFormat == paFloat32)
|
||||
{
|
||||
data->params.sampleFormat = paInt16;
|
||||
goto retry_open;
|
||||
}
|
||||
ERR("Pa_OpenStream() returned an error: %s\n", Pa_GetErrorText(err));
|
||||
free(data);
|
||||
return ALC_INVALID_VALUE;
|
||||
}
|
||||
|
||||
device->ExtraData = data;
|
||||
device->DeviceName = strdup(deviceName);
|
||||
|
||||
return ALC_NO_ERROR;
|
||||
}
|
||||
|
||||
static void pa_close_playback(ALCdevice *device)
|
||||
{
|
||||
pa_data *data = (pa_data*)device->ExtraData;
|
||||
PaError err;
|
||||
|
||||
err = Pa_CloseStream(data->stream);
|
||||
if(err != paNoError)
|
||||
ERR("Error closing stream: %s\n", Pa_GetErrorText(err));
|
||||
|
||||
free(data);
|
||||
device->ExtraData = NULL;
|
||||
}
|
||||
|
||||
static ALCboolean pa_reset_playback(ALCdevice *device)
|
||||
{
|
||||
pa_data *data = (pa_data*)device->ExtraData;
|
||||
const PaStreamInfo *streamInfo;
|
||||
|
||||
streamInfo = Pa_GetStreamInfo(data->stream);
|
||||
device->Frequency = streamInfo->sampleRate;
|
||||
device->UpdateSize = data->update_size;
|
||||
|
||||
if(data->params.sampleFormat == paInt8)
|
||||
device->FmtType = DevFmtByte;
|
||||
else if(data->params.sampleFormat == paUInt8)
|
||||
device->FmtType = DevFmtUByte;
|
||||
else if(data->params.sampleFormat == paInt16)
|
||||
device->FmtType = DevFmtShort;
|
||||
else if(data->params.sampleFormat == paInt32)
|
||||
device->FmtType = DevFmtInt;
|
||||
else if(data->params.sampleFormat == paFloat32)
|
||||
device->FmtType = DevFmtFloat;
|
||||
else
|
||||
{
|
||||
ERR("Unexpected sample format: 0x%lx\n", data->params.sampleFormat);
|
||||
return ALC_FALSE;
|
||||
}
|
||||
|
||||
if(data->params.channelCount == 2)
|
||||
device->FmtChans = DevFmtStereo;
|
||||
else if(data->params.channelCount == 1)
|
||||
device->FmtChans = DevFmtMono;
|
||||
else
|
||||
{
|
||||
ERR("Unexpected channel count: %u\n", data->params.channelCount);
|
||||
return ALC_FALSE;
|
||||
}
|
||||
SetDefaultChannelOrder(device);
|
||||
|
||||
return ALC_TRUE;
|
||||
}
|
||||
|
||||
static ALCboolean pa_start_playback(ALCdevice *device)
|
||||
{
|
||||
pa_data *data = (pa_data*)device->ExtraData;
|
||||
PaError err;
|
||||
|
||||
err = Pa_StartStream(data->stream);
|
||||
if(err != paNoError)
|
||||
{
|
||||
ERR("Pa_StartStream() returned an error: %s\n", Pa_GetErrorText(err));
|
||||
return ALC_FALSE;
|
||||
}
|
||||
|
||||
return ALC_TRUE;
|
||||
}
|
||||
|
||||
static void pa_stop_playback(ALCdevice *device)
|
||||
{
|
||||
pa_data *data = (pa_data*)device->ExtraData;
|
||||
PaError err;
|
||||
|
||||
err = Pa_StopStream(data->stream);
|
||||
if(err != paNoError)
|
||||
ERR("Error stopping stream: %s\n", Pa_GetErrorText(err));
|
||||
}
|
||||
|
||||
|
||||
static ALCenum pa_open_capture(ALCdevice *device, const ALCchar *deviceName)
|
||||
{
|
||||
ALuint frame_size;
|
||||
pa_data *data;
|
||||
PaError err;
|
||||
|
||||
if(!deviceName)
|
||||
deviceName = pa_device;
|
||||
else if(strcmp(deviceName, pa_device) != 0)
|
||||
return ALC_INVALID_VALUE;
|
||||
|
||||
data = (pa_data*)calloc(1, sizeof(pa_data));
|
||||
if(data == NULL)
|
||||
return ALC_OUT_OF_MEMORY;
|
||||
|
||||
frame_size = FrameSizeFromDevFmt(device->FmtChans, device->FmtType);
|
||||
data->ring = CreateRingBuffer(frame_size, device->UpdateSize*device->NumUpdates);
|
||||
if(data->ring == NULL)
|
||||
goto error;
|
||||
|
||||
data->params.device = -1;
|
||||
if(!ConfigValueInt("port", "capture", &data->params.device) ||
|
||||
data->params.device < 0)
|
||||
data->params.device = Pa_GetDefaultOutputDevice();
|
||||
data->params.suggestedLatency = 0.0f;
|
||||
data->params.hostApiSpecificStreamInfo = NULL;
|
||||
|
||||
switch(device->FmtType)
|
||||
{
|
||||
case DevFmtByte:
|
||||
data->params.sampleFormat = paInt8;
|
||||
break;
|
||||
case DevFmtUByte:
|
||||
data->params.sampleFormat = paUInt8;
|
||||
break;
|
||||
case DevFmtShort:
|
||||
data->params.sampleFormat = paInt16;
|
||||
break;
|
||||
case DevFmtInt:
|
||||
data->params.sampleFormat = paInt32;
|
||||
break;
|
||||
case DevFmtFloat:
|
||||
data->params.sampleFormat = paFloat32;
|
||||
break;
|
||||
case DevFmtUInt:
|
||||
case DevFmtUShort:
|
||||
ERR("%s samples not supported\n", DevFmtTypeString(device->FmtType));
|
||||
goto error;
|
||||
}
|
||||
data->params.channelCount = ChannelsFromDevFmt(device->FmtChans);
|
||||
|
||||
err = Pa_OpenStream(&data->stream, &data->params, NULL, device->Frequency,
|
||||
paFramesPerBufferUnspecified, paNoFlag, pa_capture_cb, device);
|
||||
if(err != paNoError)
|
||||
{
|
||||
ERR("Pa_OpenStream() returned an error: %s\n", Pa_GetErrorText(err));
|
||||
goto error;
|
||||
}
|
||||
|
||||
device->DeviceName = strdup(deviceName);
|
||||
|
||||
device->ExtraData = data;
|
||||
return ALC_NO_ERROR;
|
||||
|
||||
error:
|
||||
DestroyRingBuffer(data->ring);
|
||||
free(data);
|
||||
return ALC_INVALID_VALUE;
|
||||
}
|
||||
|
||||
static void pa_close_capture(ALCdevice *device)
|
||||
{
|
||||
pa_data *data = (pa_data*)device->ExtraData;
|
||||
PaError err;
|
||||
|
||||
err = Pa_CloseStream(data->stream);
|
||||
if(err != paNoError)
|
||||
ERR("Error closing stream: %s\n", Pa_GetErrorText(err));
|
||||
|
||||
free(data);
|
||||
device->ExtraData = NULL;
|
||||
}
|
||||
|
||||
static void pa_start_capture(ALCdevice *device)
|
||||
{
|
||||
pa_data *data = device->ExtraData;
|
||||
PaError err;
|
||||
|
||||
err = Pa_StartStream(data->stream);
|
||||
if(err != paNoError)
|
||||
ERR("Error starting stream: %s\n", Pa_GetErrorText(err));
|
||||
}
|
||||
|
||||
static void pa_stop_capture(ALCdevice *device)
|
||||
{
|
||||
pa_data *data = (pa_data*)device->ExtraData;
|
||||
PaError err;
|
||||
|
||||
err = Pa_StopStream(data->stream);
|
||||
if(err != paNoError)
|
||||
ERR("Error stopping stream: %s\n", Pa_GetErrorText(err));
|
||||
}
|
||||
|
||||
static ALCenum pa_capture_samples(ALCdevice *device, ALCvoid *buffer, ALCuint samples)
|
||||
{
|
||||
pa_data *data = device->ExtraData;
|
||||
ReadRingBuffer(data->ring, buffer, samples);
|
||||
return ALC_NO_ERROR;
|
||||
}
|
||||
|
||||
static ALCuint pa_available_samples(ALCdevice *device)
|
||||
{
|
||||
pa_data *data = device->ExtraData;
|
||||
return RingBufferSize(data->ring);
|
||||
}
|
||||
|
||||
|
||||
static const BackendFuncs pa_funcs = {
|
||||
pa_open_playback,
|
||||
pa_close_playback,
|
||||
pa_reset_playback,
|
||||
pa_start_playback,
|
||||
pa_stop_playback,
|
||||
pa_open_capture,
|
||||
pa_close_capture,
|
||||
pa_start_capture,
|
||||
pa_stop_capture,
|
||||
pa_capture_samples,
|
||||
pa_available_samples,
|
||||
ALCdevice_LockDefault,
|
||||
ALCdevice_UnlockDefault,
|
||||
ALCdevice_GetLatencyDefault
|
||||
};
|
||||
|
||||
ALCboolean alc_pa_init(BackendFuncs *func_list)
|
||||
{
|
||||
if(!pa_load())
|
||||
return ALC_FALSE;
|
||||
*func_list = pa_funcs;
|
||||
return ALC_TRUE;
|
||||
}
|
||||
|
||||
void alc_pa_deinit(void)
|
||||
{
|
||||
#ifdef HAVE_DYNLOAD
|
||||
if(pa_handle)
|
||||
{
|
||||
Pa_Terminate();
|
||||
CloseLib(pa_handle);
|
||||
pa_handle = NULL;
|
||||
}
|
||||
#else
|
||||
Pa_Terminate();
|
||||
#endif
|
||||
}
|
||||
|
||||
void alc_pa_probe(enum DevProbe type)
|
||||
{
|
||||
switch(type)
|
||||
{
|
||||
case ALL_DEVICE_PROBE:
|
||||
AppendAllDevicesList(pa_device);
|
||||
break;
|
||||
case CAPTURE_DEVICE_PROBE:
|
||||
AppendCaptureDeviceList(pa_device);
|
||||
break;
|
||||
}
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,296 @@
|
||||
/**
|
||||
* OpenAL cross platform audio library
|
||||
* Copyright (C) 1999-2007 by authors.
|
||||
* 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., 59 Temple Place - Suite 330,
|
||||
* Boston, MA 02111-1307, USA.
|
||||
* Or go to http://www.gnu.org/copyleft/lgpl.html
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "alMain.h"
|
||||
#include "alu.h"
|
||||
|
||||
#include <sndio.h>
|
||||
|
||||
|
||||
static const ALCchar sndio_device[] = "SndIO Default";
|
||||
|
||||
|
||||
static ALCboolean sndio_load(void)
|
||||
{
|
||||
return ALC_TRUE;
|
||||
}
|
||||
|
||||
|
||||
typedef struct {
|
||||
struct sio_hdl *sndHandle;
|
||||
|
||||
ALvoid *mix_data;
|
||||
ALsizei data_size;
|
||||
|
||||
volatile int killNow;
|
||||
ALvoid *thread;
|
||||
} sndio_data;
|
||||
|
||||
|
||||
static ALuint sndio_proc(ALvoid *ptr)
|
||||
{
|
||||
ALCdevice *device = ptr;
|
||||
sndio_data *data = device->ExtraData;
|
||||
ALsizei frameSize;
|
||||
size_t wrote;
|
||||
|
||||
SetRTPriority();
|
||||
|
||||
frameSize = FrameSizeFromDevFmt(device->FmtChans, device->FmtType);
|
||||
|
||||
while(!data->killNow && device->Connected)
|
||||
{
|
||||
ALsizei len = data->data_size;
|
||||
ALubyte *WritePtr = data->mix_data;
|
||||
|
||||
aluMixData(device, WritePtr, len/frameSize);
|
||||
while(len > 0 && !data->killNow)
|
||||
{
|
||||
wrote = sio_write(data->sndHandle, WritePtr, len);
|
||||
if(wrote == 0)
|
||||
{
|
||||
ERR("sio_write failed\n");
|
||||
ALCdevice_Lock(device);
|
||||
aluHandleDisconnect(device);
|
||||
ALCdevice_Unlock(device);
|
||||
break;
|
||||
}
|
||||
|
||||
len -= wrote;
|
||||
WritePtr += wrote;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
static ALCenum sndio_open_playback(ALCdevice *device, const ALCchar *deviceName)
|
||||
{
|
||||
sndio_data *data;
|
||||
|
||||
if(!deviceName)
|
||||
deviceName = sndio_device;
|
||||
else if(strcmp(deviceName, sndio_device) != 0)
|
||||
return ALC_INVALID_VALUE;
|
||||
|
||||
data = calloc(1, sizeof(*data));
|
||||
data->killNow = 0;
|
||||
|
||||
data->sndHandle = sio_open(NULL, SIO_PLAY, 0);
|
||||
if(data->sndHandle == NULL)
|
||||
{
|
||||
free(data);
|
||||
ERR("Could not open device\n");
|
||||
return ALC_INVALID_VALUE;
|
||||
}
|
||||
|
||||
device->DeviceName = strdup(deviceName);
|
||||
device->ExtraData = data;
|
||||
|
||||
return ALC_NO_ERROR;
|
||||
}
|
||||
|
||||
static void sndio_close_playback(ALCdevice *device)
|
||||
{
|
||||
sndio_data *data = device->ExtraData;
|
||||
|
||||
sio_close(data->sndHandle);
|
||||
free(data);
|
||||
device->ExtraData = NULL;
|
||||
}
|
||||
|
||||
static ALCboolean sndio_reset_playback(ALCdevice *device)
|
||||
{
|
||||
sndio_data *data = device->ExtraData;
|
||||
struct sio_par par;
|
||||
|
||||
sio_initpar(&par);
|
||||
|
||||
par.rate = device->Frequency;
|
||||
par.pchan = ((device->FmtChans != DevFmtMono) ? 2 : 1);
|
||||
|
||||
switch(device->FmtType)
|
||||
{
|
||||
case DevFmtByte:
|
||||
par.bits = 8;
|
||||
par.sig = 1;
|
||||
break;
|
||||
case DevFmtUByte:
|
||||
par.bits = 8;
|
||||
par.sig = 0;
|
||||
break;
|
||||
case DevFmtFloat:
|
||||
case DevFmtShort:
|
||||
par.bits = 16;
|
||||
par.sig = 1;
|
||||
break;
|
||||
case DevFmtUShort:
|
||||
par.bits = 16;
|
||||
par.sig = 0;
|
||||
break;
|
||||
case DevFmtInt:
|
||||
par.bits = 32;
|
||||
par.sig = 1;
|
||||
break;
|
||||
case DevFmtUInt:
|
||||
par.bits = 32;
|
||||
par.sig = 0;
|
||||
break;
|
||||
}
|
||||
par.le = SIO_LE_NATIVE;
|
||||
|
||||
par.round = device->UpdateSize;
|
||||
par.appbufsz = device->UpdateSize * (device->NumUpdates-1);
|
||||
if(!par.appbufsz) par.appbufsz = device->UpdateSize;
|
||||
|
||||
if(!sio_setpar(data->sndHandle, &par) || !sio_getpar(data->sndHandle, &par))
|
||||
{
|
||||
ERR("Failed to set device parameters\n");
|
||||
return ALC_FALSE;
|
||||
}
|
||||
|
||||
if(par.bits != par.bps*8)
|
||||
{
|
||||
ERR("Padded samples not supported (%u of %u bits)\n", par.bits, par.bps*8);
|
||||
return ALC_FALSE;
|
||||
}
|
||||
|
||||
device->Frequency = par.rate;
|
||||
device->FmtChans = ((par.pchan==1) ? DevFmtMono : DevFmtStereo);
|
||||
|
||||
if(par.bits == 8 && par.sig == 1)
|
||||
device->FmtType = DevFmtByte;
|
||||
else if(par.bits == 8 && par.sig == 0)
|
||||
device->FmtType = DevFmtUByte;
|
||||
else if(par.bits == 16 && par.sig == 1)
|
||||
device->FmtType = DevFmtShort;
|
||||
else if(par.bits == 16 && par.sig == 0)
|
||||
device->FmtType = DevFmtUShort;
|
||||
else if(par.bits == 32 && par.sig == 1)
|
||||
device->FmtType = DevFmtInt;
|
||||
else if(par.bits == 32 && par.sig == 0)
|
||||
device->FmtType = DevFmtUInt;
|
||||
else
|
||||
{
|
||||
ERR("Unhandled sample format: %s %u-bit\n", (par.sig?"signed":"unsigned"), par.bits);
|
||||
return ALC_FALSE;
|
||||
}
|
||||
|
||||
device->UpdateSize = par.round;
|
||||
device->NumUpdates = (par.bufsz/par.round) + 1;
|
||||
|
||||
SetDefaultChannelOrder(device);
|
||||
|
||||
return ALC_TRUE;
|
||||
}
|
||||
|
||||
static ALCboolean sndio_start_playback(ALCdevice *device)
|
||||
{
|
||||
sndio_data *data = device->ExtraData;
|
||||
|
||||
if(!sio_start(data->sndHandle))
|
||||
{
|
||||
ERR("Error starting playback\n");
|
||||
return ALC_FALSE;
|
||||
}
|
||||
|
||||
data->data_size = device->UpdateSize * FrameSizeFromDevFmt(device->FmtChans, device->FmtType);
|
||||
data->mix_data = calloc(1, data->data_size);
|
||||
|
||||
data->thread = StartThread(sndio_proc, device);
|
||||
if(data->thread == NULL)
|
||||
{
|
||||
sio_stop(data->sndHandle);
|
||||
free(data->mix_data);
|
||||
data->mix_data = NULL;
|
||||
return ALC_FALSE;
|
||||
}
|
||||
|
||||
return ALC_TRUE;
|
||||
}
|
||||
|
||||
static void sndio_stop_playback(ALCdevice *device)
|
||||
{
|
||||
sndio_data *data = device->ExtraData;
|
||||
|
||||
if(!data->thread)
|
||||
return;
|
||||
|
||||
data->killNow = 1;
|
||||
StopThread(data->thread);
|
||||
data->thread = NULL;
|
||||
|
||||
data->killNow = 0;
|
||||
if(!sio_stop(data->sndHandle))
|
||||
ERR("Error stopping device\n");
|
||||
|
||||
free(data->mix_data);
|
||||
data->mix_data = NULL;
|
||||
}
|
||||
|
||||
|
||||
static const BackendFuncs sndio_funcs = {
|
||||
sndio_open_playback,
|
||||
sndio_close_playback,
|
||||
sndio_reset_playback,
|
||||
sndio_start_playback,
|
||||
sndio_stop_playback,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
ALCdevice_LockDefault,
|
||||
ALCdevice_UnlockDefault,
|
||||
ALCdevice_GetLatencyDefault
|
||||
};
|
||||
|
||||
ALCboolean alc_sndio_init(BackendFuncs *func_list)
|
||||
{
|
||||
if(!sndio_load())
|
||||
return ALC_FALSE;
|
||||
*func_list = sndio_funcs;
|
||||
return ALC_TRUE;
|
||||
}
|
||||
|
||||
void alc_sndio_deinit(void)
|
||||
{
|
||||
}
|
||||
|
||||
void alc_sndio_probe(enum DevProbe type)
|
||||
{
|
||||
switch(type)
|
||||
{
|
||||
case ALL_DEVICE_PROBE:
|
||||
AppendAllDevicesList(sndio_device);
|
||||
break;
|
||||
case CAPTURE_DEVICE_PROBE:
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,287 @@
|
||||
/**
|
||||
* OpenAL cross platform audio library
|
||||
* Copyright (C) 1999-2007 by authors.
|
||||
* 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., 59 Temple Place - Suite 330,
|
||||
* Boston, MA 02111-1307, USA.
|
||||
* Or go to http://www.gnu.org/copyleft/lgpl.html
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <sys/ioctl.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <fcntl.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <memory.h>
|
||||
#include <unistd.h>
|
||||
#include <errno.h>
|
||||
#include <math.h>
|
||||
|
||||
#include "alMain.h"
|
||||
#include "alu.h"
|
||||
|
||||
#include <sys/audioio.h>
|
||||
|
||||
|
||||
static const ALCchar solaris_device[] = "Solaris Default";
|
||||
|
||||
static const char *solaris_driver = "/dev/audio";
|
||||
|
||||
typedef struct {
|
||||
int fd;
|
||||
volatile int killNow;
|
||||
ALvoid *thread;
|
||||
|
||||
ALubyte *mix_data;
|
||||
int data_size;
|
||||
} solaris_data;
|
||||
|
||||
|
||||
static ALuint SolarisProc(ALvoid *ptr)
|
||||
{
|
||||
ALCdevice *Device = (ALCdevice*)ptr;
|
||||
solaris_data *data = (solaris_data*)Device->ExtraData;
|
||||
ALint frameSize;
|
||||
int wrote;
|
||||
|
||||
SetRTPriority();
|
||||
|
||||
frameSize = FrameSizeFromDevFmt(Device->FmtChans, Device->FmtType);
|
||||
|
||||
while(!data->killNow && Device->Connected)
|
||||
{
|
||||
ALint len = data->data_size;
|
||||
ALubyte *WritePtr = data->mix_data;
|
||||
|
||||
aluMixData(Device, WritePtr, len/frameSize);
|
||||
while(len > 0 && !data->killNow)
|
||||
{
|
||||
wrote = write(data->fd, WritePtr, len);
|
||||
if(wrote < 0)
|
||||
{
|
||||
if(errno != EAGAIN && errno != EWOULDBLOCK && errno != EINTR)
|
||||
{
|
||||
ERR("write failed: %s\n", strerror(errno));
|
||||
ALCdevice_Lock(Device);
|
||||
aluHandleDisconnect(Device);
|
||||
ALCdevice_Unlock(Device);
|
||||
break;
|
||||
}
|
||||
|
||||
Sleep(1);
|
||||
continue;
|
||||
}
|
||||
|
||||
len -= wrote;
|
||||
WritePtr += wrote;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static ALCenum solaris_open_playback(ALCdevice *device, const ALCchar *deviceName)
|
||||
{
|
||||
solaris_data *data;
|
||||
|
||||
if(!deviceName)
|
||||
deviceName = solaris_device;
|
||||
else if(strcmp(deviceName, solaris_device) != 0)
|
||||
return ALC_INVALID_VALUE;
|
||||
|
||||
data = (solaris_data*)calloc(1, sizeof(solaris_data));
|
||||
data->killNow = 0;
|
||||
|
||||
data->fd = open(solaris_driver, O_WRONLY);
|
||||
if(data->fd == -1)
|
||||
{
|
||||
free(data);
|
||||
ERR("Could not open %s: %s\n", solaris_driver, strerror(errno));
|
||||
return ALC_INVALID_VALUE;
|
||||
}
|
||||
|
||||
device->DeviceName = strdup(deviceName);
|
||||
device->ExtraData = data;
|
||||
return ALC_NO_ERROR;
|
||||
}
|
||||
|
||||
static void solaris_close_playback(ALCdevice *device)
|
||||
{
|
||||
solaris_data *data = (solaris_data*)device->ExtraData;
|
||||
|
||||
close(data->fd);
|
||||
free(data);
|
||||
device->ExtraData = NULL;
|
||||
}
|
||||
|
||||
static ALCboolean solaris_reset_playback(ALCdevice *device)
|
||||
{
|
||||
solaris_data *data = (solaris_data*)device->ExtraData;
|
||||
audio_info_t info;
|
||||
ALuint frameSize;
|
||||
int numChannels;
|
||||
|
||||
AUDIO_INITINFO(&info);
|
||||
|
||||
info.play.sample_rate = device->Frequency;
|
||||
|
||||
if(device->FmtChans != DevFmtMono)
|
||||
device->FmtChans = DevFmtStereo;
|
||||
numChannels = ChannelsFromDevFmt(device->FmtChans);
|
||||
info.play.channels = numChannels;
|
||||
|
||||
switch(device->FmtType)
|
||||
{
|
||||
case DevFmtByte:
|
||||
info.play.precision = 8;
|
||||
info.play.encoding = AUDIO_ENCODING_LINEAR;
|
||||
break;
|
||||
case DevFmtUByte:
|
||||
info.play.precision = 8;
|
||||
info.play.encoding = AUDIO_ENCODING_LINEAR8;
|
||||
break;
|
||||
case DevFmtUShort:
|
||||
case DevFmtInt:
|
||||
case DevFmtUInt:
|
||||
case DevFmtFloat:
|
||||
device->FmtType = DevFmtShort;
|
||||
/* fall-through */
|
||||
case DevFmtShort:
|
||||
info.play.precision = 16;
|
||||
info.play.encoding = AUDIO_ENCODING_LINEAR;
|
||||
break;
|
||||
}
|
||||
|
||||
frameSize = numChannels * BytesFromDevFmt(device->FmtType);
|
||||
info.play.buffer_size = device->UpdateSize*device->NumUpdates * frameSize;
|
||||
|
||||
if(ioctl(data->fd, AUDIO_SETINFO, &info) < 0)
|
||||
{
|
||||
ERR("ioctl failed: %s\n", strerror(errno));
|
||||
return ALC_FALSE;
|
||||
}
|
||||
|
||||
if(ChannelsFromDevFmt(device->FmtChans) != info.play.channels)
|
||||
{
|
||||
ERR("Could not set %d channels, got %d instead\n", ChannelsFromDevFmt(device->FmtChans), info.play.channels);
|
||||
return ALC_FALSE;
|
||||
}
|
||||
|
||||
if(!((info.play.precision == 8 && info.play.encoding == AUDIO_ENCODING_LINEAR8 && device->FmtType == DevFmtUByte) ||
|
||||
(info.play.precision == 8 && info.play.encoding == AUDIO_ENCODING_LINEAR && device->FmtType == DevFmtByte) ||
|
||||
(info.play.precision == 16 && info.play.encoding == AUDIO_ENCODING_LINEAR && device->FmtType == DevFmtShort) ||
|
||||
(info.play.precision == 32 && info.play.encoding == AUDIO_ENCODING_LINEAR && device->FmtType == DevFmtInt)))
|
||||
{
|
||||
ERR("Could not set %s samples, got %d (0x%x)\n", DevFmtTypeString(device->FmtType),
|
||||
info.play.precision, info.play.encoding);
|
||||
return ALC_FALSE;
|
||||
}
|
||||
|
||||
device->Frequency = info.play.sample_rate;
|
||||
device->UpdateSize = (info.play.buffer_size/device->NumUpdates) + 1;
|
||||
|
||||
SetDefaultChannelOrder(device);
|
||||
|
||||
return ALC_TRUE;
|
||||
}
|
||||
|
||||
static ALCboolean solaris_start_playback(ALCdevice *device)
|
||||
{
|
||||
solaris_data *data = (solaris_data*)device->ExtraData;
|
||||
|
||||
data->data_size = device->UpdateSize * FrameSizeFromDevFmt(device->FmtChans, device->FmtType);
|
||||
data->mix_data = calloc(1, data->data_size);
|
||||
|
||||
data->thread = StartThread(SolarisProc, device);
|
||||
if(data->thread == NULL)
|
||||
{
|
||||
free(data->mix_data);
|
||||
data->mix_data = NULL;
|
||||
return ALC_FALSE;
|
||||
}
|
||||
|
||||
return ALC_TRUE;
|
||||
}
|
||||
|
||||
static void solaris_stop_playback(ALCdevice *device)
|
||||
{
|
||||
solaris_data *data = (solaris_data*)device->ExtraData;
|
||||
|
||||
if(!data->thread)
|
||||
return;
|
||||
|
||||
data->killNow = 1;
|
||||
StopThread(data->thread);
|
||||
data->thread = NULL;
|
||||
|
||||
data->killNow = 0;
|
||||
if(ioctl(data->fd, AUDIO_DRAIN) < 0)
|
||||
ERR("Error draining device: %s\n", strerror(errno));
|
||||
|
||||
free(data->mix_data);
|
||||
data->mix_data = NULL;
|
||||
}
|
||||
|
||||
|
||||
static const BackendFuncs solaris_funcs = {
|
||||
solaris_open_playback,
|
||||
solaris_close_playback,
|
||||
solaris_reset_playback,
|
||||
solaris_start_playback,
|
||||
solaris_stop_playback,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
ALCdevice_LockDefault,
|
||||
ALCdevice_UnlockDefault,
|
||||
ALCdevice_GetLatencyDefault
|
||||
};
|
||||
|
||||
ALCboolean alc_solaris_init(BackendFuncs *func_list)
|
||||
{
|
||||
ConfigValueStr("solaris", "device", &solaris_driver);
|
||||
|
||||
*func_list = solaris_funcs;
|
||||
return ALC_TRUE;
|
||||
}
|
||||
|
||||
void alc_solaris_deinit(void)
|
||||
{
|
||||
}
|
||||
|
||||
void alc_solaris_probe(enum DevProbe type)
|
||||
{
|
||||
switch(type)
|
||||
{
|
||||
case ALL_DEVICE_PROBE:
|
||||
{
|
||||
#ifdef HAVE_STAT
|
||||
struct stat buf;
|
||||
if(stat(solaris_driver, &buf) == 0)
|
||||
#endif
|
||||
AppendAllDevicesList(solaris_device);
|
||||
}
|
||||
break;
|
||||
|
||||
case CAPTURE_DEVICE_PROBE:
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,370 @@
|
||||
/**
|
||||
* OpenAL cross platform audio library
|
||||
* Copyright (C) 1999-2007 by authors.
|
||||
* 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., 59 Temple Place - Suite 330,
|
||||
* Boston, MA 02111-1307, USA.
|
||||
* Or go to http://www.gnu.org/copyleft/lgpl.html
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <memory.h>
|
||||
#ifdef HAVE_WINDOWS_H
|
||||
#include <windows.h>
|
||||
#endif
|
||||
|
||||
#include "alMain.h"
|
||||
#include "alu.h"
|
||||
|
||||
|
||||
typedef struct {
|
||||
FILE *f;
|
||||
long DataStart;
|
||||
|
||||
ALvoid *buffer;
|
||||
ALuint size;
|
||||
|
||||
volatile int killNow;
|
||||
ALvoid *thread;
|
||||
} wave_data;
|
||||
|
||||
|
||||
static const ALCchar waveDevice[] = "Wave File Writer";
|
||||
|
||||
static const ALubyte SUBTYPE_PCM[] = {
|
||||
0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x80, 0x00, 0x00, 0xaa,
|
||||
0x00, 0x38, 0x9b, 0x71
|
||||
};
|
||||
static const ALubyte SUBTYPE_FLOAT[] = {
|
||||
0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x80, 0x00, 0x00, 0xaa,
|
||||
0x00, 0x38, 0x9b, 0x71
|
||||
};
|
||||
|
||||
static const ALuint channel_masks[] = {
|
||||
0, /* invalid */
|
||||
0x4, /* Mono */
|
||||
0x1 | 0x2, /* Stereo */
|
||||
0, /* 3 channel */
|
||||
0x1 | 0x2 | 0x10 | 0x20, /* Quad */
|
||||
0, /* 5 channel */
|
||||
0x1 | 0x2 | 0x4 | 0x8 | 0x10 | 0x20, /* 5.1 */
|
||||
0x1 | 0x2 | 0x4 | 0x8 | 0x100 | 0x200 | 0x400, /* 6.1 */
|
||||
0x1 | 0x2 | 0x4 | 0x8 | 0x10 | 0x20 | 0x200 | 0x400, /* 7.1 */
|
||||
};
|
||||
|
||||
|
||||
static void fwrite16le(ALushort val, FILE *f)
|
||||
{
|
||||
fputc(val&0xff, f);
|
||||
fputc((val>>8)&0xff, f);
|
||||
}
|
||||
|
||||
static void fwrite32le(ALuint val, FILE *f)
|
||||
{
|
||||
fputc(val&0xff, f);
|
||||
fputc((val>>8)&0xff, f);
|
||||
fputc((val>>16)&0xff, f);
|
||||
fputc((val>>24)&0xff, f);
|
||||
}
|
||||
|
||||
|
||||
static ALuint WaveProc(ALvoid *ptr)
|
||||
{
|
||||
ALCdevice *Device = (ALCdevice*)ptr;
|
||||
wave_data *data = (wave_data*)Device->ExtraData;
|
||||
ALuint frameSize;
|
||||
ALuint now, start;
|
||||
ALuint64 avail, done;
|
||||
size_t fs;
|
||||
const ALuint restTime = (ALuint64)Device->UpdateSize * 1000 /
|
||||
Device->Frequency / 2;
|
||||
|
||||
frameSize = FrameSizeFromDevFmt(Device->FmtChans, Device->FmtType);
|
||||
|
||||
done = 0;
|
||||
start = timeGetTime();
|
||||
while(!data->killNow && Device->Connected)
|
||||
{
|
||||
now = timeGetTime();
|
||||
|
||||
avail = (ALuint64)(now-start) * Device->Frequency / 1000;
|
||||
if(avail < done)
|
||||
{
|
||||
/* Timer wrapped (50 days???). Add the remainder of the cycle to
|
||||
* the available count and reset the number of samples done */
|
||||
avail += ((ALuint64)1<<32)*Device->Frequency/1000 - done;
|
||||
done = 0;
|
||||
}
|
||||
if(avail-done < Device->UpdateSize)
|
||||
{
|
||||
Sleep(restTime);
|
||||
continue;
|
||||
}
|
||||
|
||||
while(avail-done >= Device->UpdateSize)
|
||||
{
|
||||
aluMixData(Device, data->buffer, Device->UpdateSize);
|
||||
done += Device->UpdateSize;
|
||||
|
||||
if(!IS_LITTLE_ENDIAN)
|
||||
{
|
||||
ALuint bytesize = BytesFromDevFmt(Device->FmtType);
|
||||
ALubyte *bytes = data->buffer;
|
||||
ALuint i;
|
||||
|
||||
if(bytesize == 1)
|
||||
{
|
||||
for(i = 0;i < data->size;i++)
|
||||
fputc(bytes[i], data->f);
|
||||
}
|
||||
else if(bytesize == 2)
|
||||
{
|
||||
for(i = 0;i < data->size;i++)
|
||||
fputc(bytes[i^1], data->f);
|
||||
}
|
||||
else if(bytesize == 4)
|
||||
{
|
||||
for(i = 0;i < data->size;i++)
|
||||
fputc(bytes[i^3], data->f);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
fs = fwrite(data->buffer, frameSize, Device->UpdateSize,
|
||||
data->f);
|
||||
fs = fs;
|
||||
}
|
||||
if(ferror(data->f))
|
||||
{
|
||||
ERR("Error writing to file\n");
|
||||
ALCdevice_Lock(Device);
|
||||
aluHandleDisconnect(Device);
|
||||
ALCdevice_Unlock(Device);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static ALCenum wave_open_playback(ALCdevice *device, const ALCchar *deviceName)
|
||||
{
|
||||
wave_data *data;
|
||||
const char *fname;
|
||||
|
||||
fname = GetConfigValue("wave", "file", "");
|
||||
if(!fname[0])
|
||||
return ALC_INVALID_VALUE;
|
||||
|
||||
if(!deviceName)
|
||||
deviceName = waveDevice;
|
||||
else if(strcmp(deviceName, waveDevice) != 0)
|
||||
return ALC_INVALID_VALUE;
|
||||
|
||||
data = (wave_data*)calloc(1, sizeof(wave_data));
|
||||
|
||||
data->f = fopen(fname, "wb");
|
||||
if(!data->f)
|
||||
{
|
||||
free(data);
|
||||
ERR("Could not open file '%s': %s\n", fname, strerror(errno));
|
||||
return ALC_INVALID_VALUE;
|
||||
}
|
||||
|
||||
device->DeviceName = strdup(deviceName);
|
||||
device->ExtraData = data;
|
||||
return ALC_NO_ERROR;
|
||||
}
|
||||
|
||||
static void wave_close_playback(ALCdevice *device)
|
||||
{
|
||||
wave_data *data = (wave_data*)device->ExtraData;
|
||||
|
||||
fclose(data->f);
|
||||
free(data);
|
||||
device->ExtraData = NULL;
|
||||
}
|
||||
|
||||
static ALCboolean wave_reset_playback(ALCdevice *device)
|
||||
{
|
||||
wave_data *data = (wave_data*)device->ExtraData;
|
||||
ALuint channels=0, bits=0;
|
||||
size_t val;
|
||||
|
||||
fseek(data->f, 0, SEEK_SET);
|
||||
clearerr(data->f);
|
||||
|
||||
switch(device->FmtType)
|
||||
{
|
||||
case DevFmtByte:
|
||||
device->FmtType = DevFmtUByte;
|
||||
break;
|
||||
case DevFmtUShort:
|
||||
device->FmtType = DevFmtShort;
|
||||
break;
|
||||
case DevFmtUInt:
|
||||
device->FmtType = DevFmtInt;
|
||||
break;
|
||||
case DevFmtUByte:
|
||||
case DevFmtShort:
|
||||
case DevFmtInt:
|
||||
case DevFmtFloat:
|
||||
break;
|
||||
}
|
||||
bits = BytesFromDevFmt(device->FmtType) * 8;
|
||||
channels = ChannelsFromDevFmt(device->FmtChans);
|
||||
|
||||
fprintf(data->f, "RIFF");
|
||||
fwrite32le(0xFFFFFFFF, data->f); // 'RIFF' header len; filled in at close
|
||||
|
||||
fprintf(data->f, "WAVE");
|
||||
|
||||
fprintf(data->f, "fmt ");
|
||||
fwrite32le(40, data->f); // 'fmt ' header len; 40 bytes for EXTENSIBLE
|
||||
|
||||
// 16-bit val, format type id (extensible: 0xFFFE)
|
||||
fwrite16le(0xFFFE, data->f);
|
||||
// 16-bit val, channel count
|
||||
fwrite16le(channels, data->f);
|
||||
// 32-bit val, frequency
|
||||
fwrite32le(device->Frequency, data->f);
|
||||
// 32-bit val, bytes per second
|
||||
fwrite32le(device->Frequency * channels * bits / 8, data->f);
|
||||
// 16-bit val, frame size
|
||||
fwrite16le(channels * bits / 8, data->f);
|
||||
// 16-bit val, bits per sample
|
||||
fwrite16le(bits, data->f);
|
||||
// 16-bit val, extra byte count
|
||||
fwrite16le(22, data->f);
|
||||
// 16-bit val, valid bits per sample
|
||||
fwrite16le(bits, data->f);
|
||||
// 32-bit val, channel mask
|
||||
fwrite32le(channel_masks[channels], data->f);
|
||||
// 16 byte GUID, sub-type format
|
||||
val = fwrite(((bits==32) ? SUBTYPE_FLOAT : SUBTYPE_PCM), 1, 16, data->f);
|
||||
val = val;
|
||||
|
||||
fprintf(data->f, "data");
|
||||
fwrite32le(0xFFFFFFFF, data->f); // 'data' header len; filled in at close
|
||||
|
||||
if(ferror(data->f))
|
||||
{
|
||||
ERR("Error writing header: %s\n", strerror(errno));
|
||||
return ALC_FALSE;
|
||||
}
|
||||
data->DataStart = ftell(data->f);
|
||||
|
||||
SetDefaultWFXChannelOrder(device);
|
||||
|
||||
return ALC_TRUE;
|
||||
}
|
||||
|
||||
static ALCboolean wave_start_playback(ALCdevice *device)
|
||||
{
|
||||
wave_data *data = (wave_data*)device->ExtraData;
|
||||
|
||||
data->size = device->UpdateSize * FrameSizeFromDevFmt(device->FmtChans, device->FmtType);
|
||||
data->buffer = malloc(data->size);
|
||||
if(!data->buffer)
|
||||
{
|
||||
ERR("Buffer malloc failed\n");
|
||||
return ALC_FALSE;
|
||||
}
|
||||
|
||||
data->thread = StartThread(WaveProc, device);
|
||||
if(data->thread == NULL)
|
||||
{
|
||||
free(data->buffer);
|
||||
data->buffer = NULL;
|
||||
return ALC_FALSE;
|
||||
}
|
||||
|
||||
return ALC_TRUE;
|
||||
}
|
||||
|
||||
static void wave_stop_playback(ALCdevice *device)
|
||||
{
|
||||
wave_data *data = (wave_data*)device->ExtraData;
|
||||
ALuint dataLen;
|
||||
long size;
|
||||
|
||||
if(!data->thread)
|
||||
return;
|
||||
|
||||
data->killNow = 1;
|
||||
StopThread(data->thread);
|
||||
data->thread = NULL;
|
||||
|
||||
data->killNow = 0;
|
||||
|
||||
free(data->buffer);
|
||||
data->buffer = NULL;
|
||||
|
||||
size = ftell(data->f);
|
||||
if(size > 0)
|
||||
{
|
||||
dataLen = size - data->DataStart;
|
||||
if(fseek(data->f, data->DataStart-4, SEEK_SET) == 0)
|
||||
fwrite32le(dataLen, data->f); // 'data' header len
|
||||
if(fseek(data->f, 4, SEEK_SET) == 0)
|
||||
fwrite32le(size-8, data->f); // 'WAVE' header len
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static const BackendFuncs wave_funcs = {
|
||||
wave_open_playback,
|
||||
wave_close_playback,
|
||||
wave_reset_playback,
|
||||
wave_start_playback,
|
||||
wave_stop_playback,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
ALCdevice_LockDefault,
|
||||
ALCdevice_UnlockDefault,
|
||||
ALCdevice_GetLatencyDefault
|
||||
};
|
||||
|
||||
ALCboolean alc_wave_init(BackendFuncs *func_list)
|
||||
{
|
||||
*func_list = wave_funcs;
|
||||
return ALC_TRUE;
|
||||
}
|
||||
|
||||
void alc_wave_deinit(void)
|
||||
{
|
||||
}
|
||||
|
||||
void alc_wave_probe(enum DevProbe type)
|
||||
{
|
||||
if(!ConfigValueExists("wave", "file"))
|
||||
return;
|
||||
|
||||
switch(type)
|
||||
{
|
||||
case ALL_DEVICE_PROBE:
|
||||
AppendAllDevicesList(waveDevice);
|
||||
break;
|
||||
case CAPTURE_DEVICE_PROBE:
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,774 @@
|
||||
/**
|
||||
* OpenAL cross platform audio library
|
||||
* Copyright (C) 1999-2007 by authors.
|
||||
* 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., 59 Temple Place - Suite 330,
|
||||
* Boston, MA 02111-1307, USA.
|
||||
* Or go to http://www.gnu.org/copyleft/lgpl.html
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <memory.h>
|
||||
|
||||
#include <windows.h>
|
||||
#include <mmsystem.h>
|
||||
|
||||
#include "alMain.h"
|
||||
#include "alu.h"
|
||||
|
||||
#ifndef WAVE_FORMAT_IEEE_FLOAT
|
||||
#define WAVE_FORMAT_IEEE_FLOAT 0x0003
|
||||
#endif
|
||||
|
||||
|
||||
typedef struct {
|
||||
// MMSYSTEM Device
|
||||
volatile ALboolean killNow;
|
||||
HANDLE WaveThreadEvent;
|
||||
HANDLE WaveThread;
|
||||
DWORD WaveThreadID;
|
||||
volatile LONG WaveBuffersCommitted;
|
||||
WAVEHDR WaveBuffer[4];
|
||||
|
||||
union {
|
||||
HWAVEIN In;
|
||||
HWAVEOUT Out;
|
||||
} WaveHandle;
|
||||
|
||||
WAVEFORMATEX Format;
|
||||
|
||||
RingBuffer *Ring;
|
||||
} WinMMData;
|
||||
|
||||
|
||||
static ALCchar **PlaybackDeviceList;
|
||||
static ALuint NumPlaybackDevices;
|
||||
static ALCchar **CaptureDeviceList;
|
||||
static ALuint NumCaptureDevices;
|
||||
|
||||
|
||||
static void ProbePlaybackDevices(void)
|
||||
{
|
||||
ALuint i;
|
||||
|
||||
for(i = 0;i < NumPlaybackDevices;i++)
|
||||
free(PlaybackDeviceList[i]);
|
||||
|
||||
NumPlaybackDevices = waveOutGetNumDevs();
|
||||
PlaybackDeviceList = realloc(PlaybackDeviceList, sizeof(ALCchar*) * NumPlaybackDevices);
|
||||
for(i = 0;i < NumPlaybackDevices;i++)
|
||||
{
|
||||
WAVEOUTCAPS WaveCaps;
|
||||
|
||||
PlaybackDeviceList[i] = NULL;
|
||||
if(waveOutGetDevCaps(i, &WaveCaps, sizeof(WaveCaps)) == MMSYSERR_NOERROR)
|
||||
{
|
||||
char name[1024];
|
||||
ALuint count, j;
|
||||
|
||||
count = 0;
|
||||
do {
|
||||
if(count == 0)
|
||||
snprintf(name, sizeof(name), "%s", WaveCaps.szPname);
|
||||
else
|
||||
snprintf(name, sizeof(name), "%s #%d", WaveCaps.szPname, count+1);
|
||||
count++;
|
||||
|
||||
for(j = 0;j < i;j++)
|
||||
{
|
||||
if(strcmp(name, PlaybackDeviceList[j]) == 0)
|
||||
break;
|
||||
}
|
||||
} while(j != i);
|
||||
|
||||
PlaybackDeviceList[i] = strdup(name);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void ProbeCaptureDevices(void)
|
||||
{
|
||||
ALuint i;
|
||||
|
||||
for(i = 0;i < NumCaptureDevices;i++)
|
||||
free(CaptureDeviceList[i]);
|
||||
|
||||
NumCaptureDevices = waveInGetNumDevs();
|
||||
CaptureDeviceList = realloc(CaptureDeviceList, sizeof(ALCchar*) * NumCaptureDevices);
|
||||
for(i = 0;i < NumCaptureDevices;i++)
|
||||
{
|
||||
WAVEINCAPS WaveInCaps;
|
||||
|
||||
CaptureDeviceList[i] = NULL;
|
||||
if(waveInGetDevCaps(i, &WaveInCaps, sizeof(WAVEINCAPS)) == MMSYSERR_NOERROR)
|
||||
{
|
||||
char name[1024];
|
||||
ALuint count, j;
|
||||
|
||||
count = 0;
|
||||
do {
|
||||
if(count == 0)
|
||||
snprintf(name, sizeof(name), "%s", WaveInCaps.szPname);
|
||||
else
|
||||
snprintf(name, sizeof(name), "%s #%d", WaveInCaps.szPname, count+1);
|
||||
count++;
|
||||
|
||||
for(j = 0;j < i;j++)
|
||||
{
|
||||
if(strcmp(name, CaptureDeviceList[j]) == 0)
|
||||
break;
|
||||
}
|
||||
} while(j != i);
|
||||
|
||||
CaptureDeviceList[i] = strdup(name);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
WaveOutProc
|
||||
|
||||
Posts a message to 'PlaybackThreadProc' everytime a WaveOut Buffer is completed and
|
||||
returns to the application (for more data)
|
||||
*/
|
||||
static void CALLBACK WaveOutProc(HWAVEOUT device, UINT msg, DWORD_PTR instance, DWORD_PTR param1, DWORD_PTR param2)
|
||||
{
|
||||
ALCdevice *Device = (ALCdevice*)instance;
|
||||
WinMMData *data = Device->ExtraData;
|
||||
|
||||
(void)device;
|
||||
(void)param2;
|
||||
|
||||
if(msg != WOM_DONE)
|
||||
return;
|
||||
|
||||
InterlockedDecrement(&data->WaveBuffersCommitted);
|
||||
PostThreadMessage(data->WaveThreadID, msg, 0, param1);
|
||||
}
|
||||
|
||||
/*
|
||||
PlaybackThreadProc
|
||||
|
||||
Used by "MMSYSTEM" Device. Called when a WaveOut buffer has used up its
|
||||
audio data.
|
||||
*/
|
||||
static DWORD WINAPI PlaybackThreadProc(LPVOID param)
|
||||
{
|
||||
ALCdevice *Device = (ALCdevice*)param;
|
||||
WinMMData *data = Device->ExtraData;
|
||||
LPWAVEHDR WaveHdr;
|
||||
ALuint FrameSize;
|
||||
MSG msg;
|
||||
|
||||
FrameSize = FrameSizeFromDevFmt(Device->FmtChans, Device->FmtType);
|
||||
|
||||
SetRTPriority();
|
||||
|
||||
while(GetMessage(&msg, NULL, 0, 0))
|
||||
{
|
||||
if(msg.message != WOM_DONE)
|
||||
continue;
|
||||
|
||||
if(data->killNow)
|
||||
{
|
||||
if(data->WaveBuffersCommitted == 0)
|
||||
break;
|
||||
continue;
|
||||
}
|
||||
|
||||
WaveHdr = ((LPWAVEHDR)msg.lParam);
|
||||
aluMixData(Device, WaveHdr->lpData, WaveHdr->dwBufferLength/FrameSize);
|
||||
|
||||
// Send buffer back to play more data
|
||||
waveOutWrite(data->WaveHandle.Out, WaveHdr, sizeof(WAVEHDR));
|
||||
InterlockedIncrement(&data->WaveBuffersCommitted);
|
||||
}
|
||||
|
||||
// Signal Wave Thread completed event
|
||||
if(data->WaveThreadEvent)
|
||||
SetEvent(data->WaveThreadEvent);
|
||||
|
||||
ExitThread(0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
WaveInProc
|
||||
|
||||
Posts a message to 'CaptureThreadProc' everytime a WaveIn Buffer is completed and
|
||||
returns to the application (with more data)
|
||||
*/
|
||||
static void CALLBACK WaveInProc(HWAVEIN device, UINT msg, DWORD_PTR instance, DWORD_PTR param1, DWORD_PTR param2)
|
||||
{
|
||||
ALCdevice *Device = (ALCdevice*)instance;
|
||||
WinMMData *data = Device->ExtraData;
|
||||
|
||||
(void)device;
|
||||
(void)param2;
|
||||
|
||||
if(msg != WIM_DATA)
|
||||
return;
|
||||
|
||||
InterlockedDecrement(&data->WaveBuffersCommitted);
|
||||
PostThreadMessage(data->WaveThreadID, msg, 0, param1);
|
||||
}
|
||||
|
||||
/*
|
||||
CaptureThreadProc
|
||||
|
||||
Used by "MMSYSTEM" Device. Called when a WaveIn buffer had been filled with new
|
||||
audio data.
|
||||
*/
|
||||
static DWORD WINAPI CaptureThreadProc(LPVOID param)
|
||||
{
|
||||
ALCdevice *Device = (ALCdevice*)param;
|
||||
WinMMData *data = Device->ExtraData;
|
||||
LPWAVEHDR WaveHdr;
|
||||
ALuint FrameSize;
|
||||
MSG msg;
|
||||
|
||||
FrameSize = FrameSizeFromDevFmt(Device->FmtChans, Device->FmtType);
|
||||
|
||||
while(GetMessage(&msg, NULL, 0, 0))
|
||||
{
|
||||
if(msg.message != WIM_DATA)
|
||||
continue;
|
||||
/* Don't wait for other buffers to finish before quitting. We're
|
||||
* closing so we don't need them. */
|
||||
if(data->killNow)
|
||||
break;
|
||||
|
||||
WaveHdr = ((LPWAVEHDR)msg.lParam);
|
||||
WriteRingBuffer(data->Ring, (ALubyte*)WaveHdr->lpData, WaveHdr->dwBytesRecorded/FrameSize);
|
||||
|
||||
// Send buffer back to capture more data
|
||||
waveInAddBuffer(data->WaveHandle.In, WaveHdr, sizeof(WAVEHDR));
|
||||
InterlockedIncrement(&data->WaveBuffersCommitted);
|
||||
}
|
||||
|
||||
// Signal Wave Thread completed event
|
||||
if(data->WaveThreadEvent)
|
||||
SetEvent(data->WaveThreadEvent);
|
||||
|
||||
ExitThread(0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static ALCenum WinMMOpenPlayback(ALCdevice *Device, const ALCchar *deviceName)
|
||||
{
|
||||
WinMMData *data = NULL;
|
||||
UINT DeviceID = 0;
|
||||
MMRESULT res;
|
||||
ALuint i = 0;
|
||||
|
||||
if(!PlaybackDeviceList)
|
||||
ProbePlaybackDevices();
|
||||
|
||||
// Find the Device ID matching the deviceName if valid
|
||||
for(i = 0;i < NumPlaybackDevices;i++)
|
||||
{
|
||||
if(PlaybackDeviceList[i] &&
|
||||
(!deviceName || strcmp(deviceName, PlaybackDeviceList[i]) == 0))
|
||||
{
|
||||
DeviceID = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if(i == NumPlaybackDevices)
|
||||
return ALC_INVALID_VALUE;
|
||||
|
||||
data = calloc(1, sizeof(*data));
|
||||
if(!data)
|
||||
return ALC_OUT_OF_MEMORY;
|
||||
Device->ExtraData = data;
|
||||
|
||||
retry_open:
|
||||
memset(&data->Format, 0, sizeof(WAVEFORMATEX));
|
||||
if(Device->FmtType == DevFmtFloat)
|
||||
{
|
||||
data->Format.wFormatTag = WAVE_FORMAT_IEEE_FLOAT;
|
||||
data->Format.wBitsPerSample = 32;
|
||||
}
|
||||
else
|
||||
{
|
||||
data->Format.wFormatTag = WAVE_FORMAT_PCM;
|
||||
if(Device->FmtType == DevFmtUByte || Device->FmtType == DevFmtByte)
|
||||
data->Format.wBitsPerSample = 8;
|
||||
else
|
||||
data->Format.wBitsPerSample = 16;
|
||||
}
|
||||
data->Format.nChannels = ((Device->FmtChans == DevFmtMono) ? 1 : 2);
|
||||
data->Format.nBlockAlign = data->Format.wBitsPerSample *
|
||||
data->Format.nChannels / 8;
|
||||
data->Format.nSamplesPerSec = Device->Frequency;
|
||||
data->Format.nAvgBytesPerSec = data->Format.nSamplesPerSec *
|
||||
data->Format.nBlockAlign;
|
||||
data->Format.cbSize = 0;
|
||||
|
||||
if((res=waveOutOpen(&data->WaveHandle.Out, DeviceID, &data->Format, (DWORD_PTR)&WaveOutProc, (DWORD_PTR)Device, CALLBACK_FUNCTION)) != MMSYSERR_NOERROR)
|
||||
{
|
||||
if(Device->FmtType == DevFmtFloat)
|
||||
{
|
||||
Device->FmtType = DevFmtShort;
|
||||
goto retry_open;
|
||||
}
|
||||
ERR("waveOutOpen failed: %u\n", res);
|
||||
goto failure;
|
||||
}
|
||||
|
||||
data->WaveThreadEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
|
||||
if(data->WaveThreadEvent == NULL)
|
||||
{
|
||||
ERR("CreateEvent failed: %lu\n", GetLastError());
|
||||
goto failure;
|
||||
}
|
||||
|
||||
Device->DeviceName = strdup(PlaybackDeviceList[DeviceID]);
|
||||
return ALC_NO_ERROR;
|
||||
|
||||
failure:
|
||||
if(data->WaveThreadEvent)
|
||||
CloseHandle(data->WaveThreadEvent);
|
||||
|
||||
if(data->WaveHandle.Out)
|
||||
waveOutClose(data->WaveHandle.Out);
|
||||
|
||||
free(data);
|
||||
Device->ExtraData = NULL;
|
||||
return ALC_INVALID_VALUE;
|
||||
}
|
||||
|
||||
static void WinMMClosePlayback(ALCdevice *device)
|
||||
{
|
||||
WinMMData *data = (WinMMData*)device->ExtraData;
|
||||
|
||||
// Close the Wave device
|
||||
CloseHandle(data->WaveThreadEvent);
|
||||
data->WaveThreadEvent = 0;
|
||||
|
||||
waveOutClose(data->WaveHandle.Out);
|
||||
data->WaveHandle.Out = 0;
|
||||
|
||||
free(data);
|
||||
device->ExtraData = NULL;
|
||||
}
|
||||
|
||||
static ALCboolean WinMMResetPlayback(ALCdevice *device)
|
||||
{
|
||||
WinMMData *data = (WinMMData*)device->ExtraData;
|
||||
|
||||
device->UpdateSize = (ALuint)((ALuint64)device->UpdateSize *
|
||||
data->Format.nSamplesPerSec /
|
||||
device->Frequency);
|
||||
device->UpdateSize = (device->UpdateSize*device->NumUpdates + 3) / 4;
|
||||
device->NumUpdates = 4;
|
||||
device->Frequency = data->Format.nSamplesPerSec;
|
||||
|
||||
if(data->Format.wFormatTag == WAVE_FORMAT_IEEE_FLOAT)
|
||||
{
|
||||
if(data->Format.wBitsPerSample == 32)
|
||||
device->FmtType = DevFmtFloat;
|
||||
else
|
||||
{
|
||||
ERR("Unhandled IEEE float sample depth: %d\n", data->Format.wBitsPerSample);
|
||||
return ALC_FALSE;
|
||||
}
|
||||
}
|
||||
else if(data->Format.wFormatTag == WAVE_FORMAT_PCM)
|
||||
{
|
||||
if(data->Format.wBitsPerSample == 16)
|
||||
device->FmtType = DevFmtShort;
|
||||
else if(data->Format.wBitsPerSample == 8)
|
||||
device->FmtType = DevFmtUByte;
|
||||
else
|
||||
{
|
||||
ERR("Unhandled PCM sample depth: %d\n", data->Format.wBitsPerSample);
|
||||
return ALC_FALSE;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
ERR("Unhandled format tag: 0x%04x\n", data->Format.wFormatTag);
|
||||
return ALC_FALSE;
|
||||
}
|
||||
|
||||
if(data->Format.nChannels == 2)
|
||||
device->FmtChans = DevFmtStereo;
|
||||
else if(data->Format.nChannels == 1)
|
||||
device->FmtChans = DevFmtMono;
|
||||
else
|
||||
{
|
||||
ERR("Unhandled channel count: %d\n", data->Format.nChannels);
|
||||
return ALC_FALSE;
|
||||
}
|
||||
SetDefaultWFXChannelOrder(device);
|
||||
|
||||
return ALC_TRUE;
|
||||
}
|
||||
|
||||
static ALCboolean WinMMStartPlayback(ALCdevice *device)
|
||||
{
|
||||
WinMMData *data = (WinMMData*)device->ExtraData;
|
||||
ALbyte *BufferData;
|
||||
ALint BufferSize;
|
||||
ALuint i;
|
||||
|
||||
data->WaveThread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)PlaybackThreadProc, (LPVOID)device, 0, &data->WaveThreadID);
|
||||
if(data->WaveThread == NULL)
|
||||
return ALC_FALSE;
|
||||
|
||||
data->WaveBuffersCommitted = 0;
|
||||
|
||||
// Create 4 Buffers
|
||||
BufferSize = device->UpdateSize*device->NumUpdates / 4;
|
||||
BufferSize *= FrameSizeFromDevFmt(device->FmtChans, device->FmtType);
|
||||
|
||||
BufferData = calloc(4, BufferSize);
|
||||
for(i = 0;i < 4;i++)
|
||||
{
|
||||
memset(&data->WaveBuffer[i], 0, sizeof(WAVEHDR));
|
||||
data->WaveBuffer[i].dwBufferLength = BufferSize;
|
||||
data->WaveBuffer[i].lpData = ((i==0) ? (LPSTR)BufferData :
|
||||
(data->WaveBuffer[i-1].lpData +
|
||||
data->WaveBuffer[i-1].dwBufferLength));
|
||||
waveOutPrepareHeader(data->WaveHandle.Out, &data->WaveBuffer[i], sizeof(WAVEHDR));
|
||||
waveOutWrite(data->WaveHandle.Out, &data->WaveBuffer[i], sizeof(WAVEHDR));
|
||||
InterlockedIncrement(&data->WaveBuffersCommitted);
|
||||
}
|
||||
|
||||
return ALC_TRUE;
|
||||
}
|
||||
|
||||
static void WinMMStopPlayback(ALCdevice *device)
|
||||
{
|
||||
WinMMData *data = (WinMMData*)device->ExtraData;
|
||||
void *buffer = NULL;
|
||||
int i;
|
||||
|
||||
if(data->WaveThread == NULL)
|
||||
return;
|
||||
|
||||
// Set flag to stop processing headers
|
||||
data->killNow = AL_TRUE;
|
||||
|
||||
// Wait for signal that Wave Thread has been destroyed
|
||||
WaitForSingleObjectEx(data->WaveThreadEvent, 5000, FALSE);
|
||||
|
||||
CloseHandle(data->WaveThread);
|
||||
data->WaveThread = 0;
|
||||
|
||||
data->killNow = AL_FALSE;
|
||||
|
||||
// Release the wave buffers
|
||||
for(i = 0;i < 4;i++)
|
||||
{
|
||||
waveOutUnprepareHeader(data->WaveHandle.Out, &data->WaveBuffer[i], sizeof(WAVEHDR));
|
||||
if(i == 0) buffer = data->WaveBuffer[i].lpData;
|
||||
data->WaveBuffer[i].lpData = NULL;
|
||||
}
|
||||
free(buffer);
|
||||
}
|
||||
|
||||
|
||||
static ALCenum WinMMOpenCapture(ALCdevice *Device, const ALCchar *deviceName)
|
||||
{
|
||||
ALbyte *BufferData = NULL;
|
||||
DWORD CapturedDataSize;
|
||||
WinMMData *data = NULL;
|
||||
UINT DeviceID = 0;
|
||||
ALint BufferSize;
|
||||
MMRESULT res;
|
||||
ALuint i;
|
||||
|
||||
if(!CaptureDeviceList)
|
||||
ProbeCaptureDevices();
|
||||
|
||||
// Find the Device ID matching the deviceName if valid
|
||||
for(i = 0;i < NumCaptureDevices;i++)
|
||||
{
|
||||
if(CaptureDeviceList[i] &&
|
||||
(!deviceName || strcmp(deviceName, CaptureDeviceList[i]) == 0))
|
||||
{
|
||||
DeviceID = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if(i == NumCaptureDevices)
|
||||
return ALC_INVALID_VALUE;
|
||||
|
||||
switch(Device->FmtChans)
|
||||
{
|
||||
case DevFmtMono:
|
||||
case DevFmtStereo:
|
||||
break;
|
||||
|
||||
case DevFmtQuad:
|
||||
case DevFmtX51:
|
||||
case DevFmtX51Side:
|
||||
case DevFmtX61:
|
||||
case DevFmtX71:
|
||||
return ALC_INVALID_ENUM;
|
||||
}
|
||||
|
||||
switch(Device->FmtType)
|
||||
{
|
||||
case DevFmtUByte:
|
||||
case DevFmtShort:
|
||||
case DevFmtInt:
|
||||
case DevFmtFloat:
|
||||
break;
|
||||
|
||||
case DevFmtByte:
|
||||
case DevFmtUShort:
|
||||
case DevFmtUInt:
|
||||
return ALC_INVALID_ENUM;
|
||||
}
|
||||
|
||||
data = calloc(1, sizeof(*data));
|
||||
if(!data)
|
||||
return ALC_OUT_OF_MEMORY;
|
||||
Device->ExtraData = data;
|
||||
|
||||
memset(&data->Format, 0, sizeof(WAVEFORMATEX));
|
||||
data->Format.wFormatTag = ((Device->FmtType == DevFmtFloat) ?
|
||||
WAVE_FORMAT_IEEE_FLOAT : WAVE_FORMAT_PCM);
|
||||
data->Format.nChannels = ChannelsFromDevFmt(Device->FmtChans);
|
||||
data->Format.wBitsPerSample = BytesFromDevFmt(Device->FmtType) * 8;
|
||||
data->Format.nBlockAlign = data->Format.wBitsPerSample *
|
||||
data->Format.nChannels / 8;
|
||||
data->Format.nSamplesPerSec = Device->Frequency;
|
||||
data->Format.nAvgBytesPerSec = data->Format.nSamplesPerSec *
|
||||
data->Format.nBlockAlign;
|
||||
data->Format.cbSize = 0;
|
||||
|
||||
if((res=waveInOpen(&data->WaveHandle.In, DeviceID, &data->Format, (DWORD_PTR)&WaveInProc, (DWORD_PTR)Device, CALLBACK_FUNCTION)) != MMSYSERR_NOERROR)
|
||||
{
|
||||
ERR("waveInOpen failed: %u\n", res);
|
||||
goto failure;
|
||||
}
|
||||
|
||||
data->WaveThreadEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
|
||||
if(data->WaveThreadEvent == NULL)
|
||||
{
|
||||
ERR("CreateEvent failed: %lu\n", GetLastError());
|
||||
goto failure;
|
||||
}
|
||||
|
||||
// Allocate circular memory buffer for the captured audio
|
||||
CapturedDataSize = Device->UpdateSize*Device->NumUpdates;
|
||||
|
||||
// Make sure circular buffer is at least 100ms in size
|
||||
if(CapturedDataSize < (data->Format.nSamplesPerSec / 10))
|
||||
CapturedDataSize = data->Format.nSamplesPerSec / 10;
|
||||
|
||||
data->Ring = CreateRingBuffer(data->Format.nBlockAlign, CapturedDataSize);
|
||||
if(!data->Ring)
|
||||
goto failure;
|
||||
|
||||
data->WaveBuffersCommitted = 0;
|
||||
|
||||
// Create 4 Buffers of 50ms each
|
||||
BufferSize = data->Format.nAvgBytesPerSec / 20;
|
||||
BufferSize -= (BufferSize % data->Format.nBlockAlign);
|
||||
|
||||
BufferData = calloc(4, BufferSize);
|
||||
if(!BufferData)
|
||||
goto failure;
|
||||
|
||||
for(i = 0;i < 4;i++)
|
||||
{
|
||||
memset(&data->WaveBuffer[i], 0, sizeof(WAVEHDR));
|
||||
data->WaveBuffer[i].dwBufferLength = BufferSize;
|
||||
data->WaveBuffer[i].lpData = ((i==0) ? (LPSTR)BufferData :
|
||||
(data->WaveBuffer[i-1].lpData +
|
||||
data->WaveBuffer[i-1].dwBufferLength));
|
||||
data->WaveBuffer[i].dwFlags = 0;
|
||||
data->WaveBuffer[i].dwLoops = 0;
|
||||
waveInPrepareHeader(data->WaveHandle.In, &data->WaveBuffer[i], sizeof(WAVEHDR));
|
||||
waveInAddBuffer(data->WaveHandle.In, &data->WaveBuffer[i], sizeof(WAVEHDR));
|
||||
InterlockedIncrement(&data->WaveBuffersCommitted);
|
||||
}
|
||||
|
||||
data->WaveThread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)CaptureThreadProc, (LPVOID)Device, 0, &data->WaveThreadID);
|
||||
if (data->WaveThread == NULL)
|
||||
goto failure;
|
||||
|
||||
Device->DeviceName = strdup(CaptureDeviceList[DeviceID]);
|
||||
return ALC_NO_ERROR;
|
||||
|
||||
failure:
|
||||
if(data->WaveThread)
|
||||
CloseHandle(data->WaveThread);
|
||||
|
||||
if(BufferData)
|
||||
{
|
||||
for(i = 0;i < 4;i++)
|
||||
waveInUnprepareHeader(data->WaveHandle.In, &data->WaveBuffer[i], sizeof(WAVEHDR));
|
||||
free(BufferData);
|
||||
}
|
||||
|
||||
if(data->Ring)
|
||||
DestroyRingBuffer(data->Ring);
|
||||
|
||||
if(data->WaveThreadEvent)
|
||||
CloseHandle(data->WaveThreadEvent);
|
||||
|
||||
if(data->WaveHandle.In)
|
||||
waveInClose(data->WaveHandle.In);
|
||||
|
||||
free(data);
|
||||
Device->ExtraData = NULL;
|
||||
return ALC_INVALID_VALUE;
|
||||
}
|
||||
|
||||
static void WinMMCloseCapture(ALCdevice *Device)
|
||||
{
|
||||
WinMMData *data = (WinMMData*)Device->ExtraData;
|
||||
void *buffer = NULL;
|
||||
int i;
|
||||
|
||||
/* Tell the processing thread to quit and wait for it to do so. */
|
||||
data->killNow = AL_TRUE;
|
||||
PostThreadMessage(data->WaveThreadID, WM_QUIT, 0, 0);
|
||||
|
||||
WaitForSingleObjectEx(data->WaveThreadEvent, 5000, FALSE);
|
||||
|
||||
/* Make sure capture is stopped and all pending buffers are flushed. */
|
||||
waveInReset(data->WaveHandle.In);
|
||||
|
||||
CloseHandle(data->WaveThread);
|
||||
data->WaveThread = 0;
|
||||
|
||||
// Release the wave buffers
|
||||
for(i = 0;i < 4;i++)
|
||||
{
|
||||
waveInUnprepareHeader(data->WaveHandle.In, &data->WaveBuffer[i], sizeof(WAVEHDR));
|
||||
if(i == 0) buffer = data->WaveBuffer[i].lpData;
|
||||
data->WaveBuffer[i].lpData = NULL;
|
||||
}
|
||||
free(buffer);
|
||||
|
||||
DestroyRingBuffer(data->Ring);
|
||||
data->Ring = NULL;
|
||||
|
||||
// Close the Wave device
|
||||
CloseHandle(data->WaveThreadEvent);
|
||||
data->WaveThreadEvent = 0;
|
||||
|
||||
waveInClose(data->WaveHandle.In);
|
||||
data->WaveHandle.In = 0;
|
||||
|
||||
free(data);
|
||||
Device->ExtraData = NULL;
|
||||
}
|
||||
|
||||
static void WinMMStartCapture(ALCdevice *Device)
|
||||
{
|
||||
WinMMData *data = (WinMMData*)Device->ExtraData;
|
||||
waveInStart(data->WaveHandle.In);
|
||||
}
|
||||
|
||||
static void WinMMStopCapture(ALCdevice *Device)
|
||||
{
|
||||
WinMMData *data = (WinMMData*)Device->ExtraData;
|
||||
waveInStop(data->WaveHandle.In);
|
||||
}
|
||||
|
||||
static ALCenum WinMMCaptureSamples(ALCdevice *Device, ALCvoid *Buffer, ALCuint Samples)
|
||||
{
|
||||
WinMMData *data = (WinMMData*)Device->ExtraData;
|
||||
ReadRingBuffer(data->Ring, Buffer, Samples);
|
||||
return ALC_NO_ERROR;
|
||||
}
|
||||
|
||||
static ALCuint WinMMAvailableSamples(ALCdevice *Device)
|
||||
{
|
||||
WinMMData *data = (WinMMData*)Device->ExtraData;
|
||||
return RingBufferSize(data->Ring);
|
||||
}
|
||||
|
||||
|
||||
static const BackendFuncs WinMMFuncs = {
|
||||
WinMMOpenPlayback,
|
||||
WinMMClosePlayback,
|
||||
WinMMResetPlayback,
|
||||
WinMMStartPlayback,
|
||||
WinMMStopPlayback,
|
||||
WinMMOpenCapture,
|
||||
WinMMCloseCapture,
|
||||
WinMMStartCapture,
|
||||
WinMMStopCapture,
|
||||
WinMMCaptureSamples,
|
||||
WinMMAvailableSamples,
|
||||
ALCdevice_LockDefault,
|
||||
ALCdevice_UnlockDefault,
|
||||
ALCdevice_GetLatencyDefault
|
||||
};
|
||||
|
||||
ALCboolean alcWinMMInit(BackendFuncs *FuncList)
|
||||
{
|
||||
*FuncList = WinMMFuncs;
|
||||
return ALC_TRUE;
|
||||
}
|
||||
|
||||
void alcWinMMDeinit()
|
||||
{
|
||||
ALuint i;
|
||||
|
||||
for(i = 0;i < NumPlaybackDevices;i++)
|
||||
free(PlaybackDeviceList[i]);
|
||||
free(PlaybackDeviceList);
|
||||
PlaybackDeviceList = NULL;
|
||||
|
||||
NumPlaybackDevices = 0;
|
||||
|
||||
|
||||
for(i = 0;i < NumCaptureDevices;i++)
|
||||
free(CaptureDeviceList[i]);
|
||||
free(CaptureDeviceList);
|
||||
CaptureDeviceList = NULL;
|
||||
|
||||
NumCaptureDevices = 0;
|
||||
}
|
||||
|
||||
void alcWinMMProbe(enum DevProbe type)
|
||||
{
|
||||
ALuint i;
|
||||
|
||||
switch(type)
|
||||
{
|
||||
case ALL_DEVICE_PROBE:
|
||||
ProbePlaybackDevices();
|
||||
for(i = 0;i < NumPlaybackDevices;i++)
|
||||
{
|
||||
if(PlaybackDeviceList[i])
|
||||
AppendAllDevicesList(PlaybackDeviceList[i]);
|
||||
}
|
||||
break;
|
||||
|
||||
case CAPTURE_DEVICE_PROBE:
|
||||
ProbeCaptureDevices();
|
||||
for(i = 0;i < NumCaptureDevices;i++)
|
||||
{
|
||||
if(CaptureDeviceList[i])
|
||||
AppendCaptureDeviceList(CaptureDeviceList[i]);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
+185
-201
@@ -1,201 +1,185 @@
|
||||
/*-
|
||||
* Copyright (c) 2005 Boris Mikhaylov
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining
|
||||
* a copy of this software and associated documentation files (the
|
||||
* "Software"), to deal in the Software without restriction, including
|
||||
* without limitation the rights to use, copy, modify, merge, publish,
|
||||
* distribute, sublicense, and/or sell copies of the Software, and to
|
||||
* permit persons to whom the Software is furnished to do so, subject to
|
||||
* the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be
|
||||
* included in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
||||
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include <math.h>
|
||||
|
||||
#include "bs2b.h"
|
||||
|
||||
#ifndef M_PI
|
||||
#define M_PI 3.14159265358979323846
|
||||
#endif
|
||||
|
||||
/* Single pole IIR filter.
|
||||
* O[n] = a0*I[n] + a1*I[n-1] + b1*O[n-1]
|
||||
*/
|
||||
|
||||
/* Lowpass filter */
|
||||
#define lo_filter(in, out_1) (bs2b->a0_lo*(in) + bs2b->b1_lo*(out_1))
|
||||
|
||||
/* Highboost filter */
|
||||
#define hi_filter(in, in_1, out_1) (bs2b->a0_hi*(in) + bs2b->a1_hi*(in_1) + bs2b->b1_hi*(out_1))
|
||||
|
||||
/* Set up all data. */
|
||||
static void init(struct bs2b *bs2b)
|
||||
{
|
||||
double Fc_lo, Fc_hi;
|
||||
double G_lo, G_hi;
|
||||
double x;
|
||||
|
||||
if ((bs2b->srate > 192000) || (bs2b->srate < 2000))
|
||||
bs2b->srate = BS2B_DEFAULT_SRATE;
|
||||
|
||||
switch(bs2b->level)
|
||||
{
|
||||
case BS2B_LOW_CLEVEL: /* Low crossfeed level */
|
||||
Fc_lo = 360.0;
|
||||
Fc_hi = 501.0;
|
||||
G_lo = 0.398107170553497;
|
||||
G_hi = 0.205671765275719;
|
||||
break;
|
||||
|
||||
case BS2B_MIDDLE_CLEVEL: /* Middle crossfeed level */
|
||||
Fc_lo = 500.0;
|
||||
Fc_hi = 711.0;
|
||||
G_lo = 0.459726988530872;
|
||||
G_hi = 0.228208484414988;
|
||||
break;
|
||||
|
||||
case BS2B_HIGH_CLEVEL: /* High crossfeed level (virtual speakers are closer to itself) */
|
||||
Fc_lo = 700.0;
|
||||
Fc_hi = 1021.0;
|
||||
G_lo = 0.530884444230988;
|
||||
G_hi = 0.250105790667544;
|
||||
break;
|
||||
|
||||
case BS2B_LOW_ECLEVEL: /* Low easy crossfeed level */
|
||||
Fc_lo = 360.0;
|
||||
Fc_hi = 494.0;
|
||||
G_lo = 0.316227766016838;
|
||||
G_hi = 0.168236228897329;
|
||||
break;
|
||||
|
||||
case BS2B_MIDDLE_ECLEVEL: /* Middle easy crossfeed level */
|
||||
Fc_lo = 500.0;
|
||||
Fc_hi = 689.0;
|
||||
G_lo = 0.354813389233575;
|
||||
G_hi = 0.187169483835901;
|
||||
break;
|
||||
|
||||
default: /* High easy crossfeed level */
|
||||
bs2b->level = BS2B_HIGH_ECLEVEL;
|
||||
|
||||
Fc_lo = 700.0;
|
||||
Fc_hi = 975.0;
|
||||
G_lo = 0.398107170553497;
|
||||
G_hi = 0.205671765275719;
|
||||
break;
|
||||
} /* switch */
|
||||
|
||||
/* $fc = $Fc / $s;
|
||||
* $d = 1 / 2 / pi / $fc;
|
||||
* $x = exp(-1 / $d);
|
||||
*/
|
||||
|
||||
x = exp(-2.0 * M_PI * Fc_lo / bs2b->srate);
|
||||
bs2b->b1_lo = x;
|
||||
bs2b->a0_lo = G_lo * (1.0 - x);
|
||||
|
||||
x = exp(-2.0 * M_PI * Fc_hi / bs2b->srate);
|
||||
bs2b->b1_hi = x;
|
||||
bs2b->a0_hi = 1.0 - G_hi * (1.0 - x);
|
||||
bs2b->a1_hi = -x;
|
||||
|
||||
bs2b->gain = 1.0 / (1.0 - G_hi + G_lo);
|
||||
|
||||
bs2b_clear(bs2b);
|
||||
} /* init */
|
||||
|
||||
/* Exported functions.
|
||||
* See descriptions in "bs2b.h"
|
||||
*/
|
||||
|
||||
void bs2b_set_level(struct bs2b *bs2b, int level)
|
||||
{
|
||||
if(level == bs2b->level)
|
||||
return;
|
||||
bs2b->level = level;
|
||||
init(bs2b);
|
||||
} /* bs2b_set_level */
|
||||
|
||||
int bs2b_get_level(struct bs2b *bs2b)
|
||||
{
|
||||
return bs2b->level;
|
||||
} /* bs2b_get_level */
|
||||
|
||||
void bs2b_set_srate(struct bs2b *bs2b, int srate)
|
||||
{
|
||||
if (srate == bs2b->srate)
|
||||
return;
|
||||
bs2b->srate = srate;
|
||||
init(bs2b);
|
||||
} /* bs2b_set_srate */
|
||||
|
||||
int bs2b_get_srate(struct bs2b *bs2b)
|
||||
{
|
||||
return bs2b->srate;
|
||||
} /* bs2b_get_srate */
|
||||
|
||||
void bs2b_clear(struct bs2b *bs2b)
|
||||
{
|
||||
int loopv = sizeof(bs2b->last_sample);
|
||||
|
||||
while (loopv)
|
||||
{
|
||||
((char *)&bs2b->last_sample)[--loopv] = 0;
|
||||
}
|
||||
} /* bs2b_clear */
|
||||
|
||||
int bs2b_is_clear(struct bs2b *bs2b)
|
||||
{
|
||||
int loopv = sizeof(bs2b->last_sample);
|
||||
|
||||
while (loopv)
|
||||
{
|
||||
if (((char *)&bs2b->last_sample)[--loopv] != 0)
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
} /* bs2b_is_clear */
|
||||
|
||||
void bs2b_cross_feed(struct bs2b *bs2b, float *sample)
|
||||
{
|
||||
/* Lowpass filter */
|
||||
bs2b->last_sample.lo[0] = lo_filter(sample[0], bs2b->last_sample.lo[0]);
|
||||
bs2b->last_sample.lo[1] = lo_filter(sample[1], bs2b->last_sample.lo[1]);
|
||||
|
||||
/* Highboost filter */
|
||||
bs2b->last_sample.hi[0] = hi_filter(sample[0], bs2b->last_sample.asis[0], bs2b->last_sample.hi[0]);
|
||||
bs2b->last_sample.hi[1] = hi_filter(sample[1], bs2b->last_sample.asis[1], bs2b->last_sample.hi[1]);
|
||||
bs2b->last_sample.asis[0] = sample[0];
|
||||
bs2b->last_sample.asis[1] = sample[1];
|
||||
|
||||
/* Crossfeed */
|
||||
sample[0] = bs2b->last_sample.hi[0] + bs2b->last_sample.lo[1];
|
||||
sample[1] = bs2b->last_sample.hi[1] + bs2b->last_sample.lo[0];
|
||||
|
||||
/* Bass boost cause allpass attenuation */
|
||||
sample[0] *= bs2b->gain;
|
||||
sample[1] *= bs2b->gain;
|
||||
|
||||
/* Clipping of overloaded samples */
|
||||
#if 0
|
||||
if (sample[0] > 1.0)
|
||||
sample[0] = 1.0;
|
||||
if (sample[0] < -1.0)
|
||||
sample[0] = -1.0;
|
||||
if (sample[1] > 1.0)
|
||||
sample[1] = 1.0;
|
||||
if (sample[1] < -1.0)
|
||||
sample[1] = -1.0;
|
||||
#endif
|
||||
} /* bs2b_cross_feed */
|
||||
/*-
|
||||
* Copyright (c) 2005 Boris Mikhaylov
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining
|
||||
* a copy of this software and associated documentation files (the
|
||||
* "Software"), to deal in the Software without restriction, including
|
||||
* without limitation the rights to use, copy, modify, merge, publish,
|
||||
* distribute, sublicense, and/or sell copies of the Software, and to
|
||||
* permit persons to whom the Software is furnished to do so, subject to
|
||||
* the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be
|
||||
* included in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
||||
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <math.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "bs2b.h"
|
||||
|
||||
#ifndef M_PI
|
||||
#define M_PI 3.14159265358979323846
|
||||
#endif
|
||||
|
||||
/* Single pole IIR filter.
|
||||
* O[n] = a0*I[n] + a1*I[n-1] + b1*O[n-1]
|
||||
*/
|
||||
|
||||
/* Lowpass filter */
|
||||
#define lo_filter(in, out_1) (bs2b->a0_lo*(in) + bs2b->b1_lo*(out_1))
|
||||
|
||||
/* Highboost filter */
|
||||
#define hi_filter(in, in_1, out_1) (bs2b->a0_hi*(in) + bs2b->a1_hi*(in_1) + bs2b->b1_hi*(out_1))
|
||||
|
||||
/* Set up all data. */
|
||||
static void init(struct bs2b *bs2b)
|
||||
{
|
||||
double Fc_lo, Fc_hi;
|
||||
double G_lo, G_hi;
|
||||
double x;
|
||||
|
||||
if ((bs2b->srate > 192000) || (bs2b->srate < 2000))
|
||||
bs2b->srate = BS2B_DEFAULT_SRATE;
|
||||
|
||||
switch(bs2b->level)
|
||||
{
|
||||
case BS2B_LOW_CLEVEL: /* Low crossfeed level */
|
||||
Fc_lo = 360.0;
|
||||
Fc_hi = 501.0;
|
||||
G_lo = 0.398107170553497;
|
||||
G_hi = 0.205671765275719;
|
||||
break;
|
||||
|
||||
case BS2B_MIDDLE_CLEVEL: /* Middle crossfeed level */
|
||||
Fc_lo = 500.0;
|
||||
Fc_hi = 711.0;
|
||||
G_lo = 0.459726988530872;
|
||||
G_hi = 0.228208484414988;
|
||||
break;
|
||||
|
||||
case BS2B_HIGH_CLEVEL: /* High crossfeed level (virtual speakers are closer to itself) */
|
||||
Fc_lo = 700.0;
|
||||
Fc_hi = 1021.0;
|
||||
G_lo = 0.530884444230988;
|
||||
G_hi = 0.250105790667544;
|
||||
break;
|
||||
|
||||
case BS2B_LOW_ECLEVEL: /* Low easy crossfeed level */
|
||||
Fc_lo = 360.0;
|
||||
Fc_hi = 494.0;
|
||||
G_lo = 0.316227766016838;
|
||||
G_hi = 0.168236228897329;
|
||||
break;
|
||||
|
||||
case BS2B_MIDDLE_ECLEVEL: /* Middle easy crossfeed level */
|
||||
Fc_lo = 500.0;
|
||||
Fc_hi = 689.0;
|
||||
G_lo = 0.354813389233575;
|
||||
G_hi = 0.187169483835901;
|
||||
break;
|
||||
|
||||
default: /* High easy crossfeed level */
|
||||
bs2b->level = BS2B_HIGH_ECLEVEL;
|
||||
|
||||
Fc_lo = 700.0;
|
||||
Fc_hi = 975.0;
|
||||
G_lo = 0.398107170553497;
|
||||
G_hi = 0.205671765275719;
|
||||
break;
|
||||
} /* switch */
|
||||
|
||||
/* $fc = $Fc / $s;
|
||||
* $d = 1 / 2 / pi / $fc;
|
||||
* $x = exp(-1 / $d);
|
||||
*/
|
||||
|
||||
x = exp(-2.0 * M_PI * Fc_lo / bs2b->srate);
|
||||
bs2b->b1_lo = x;
|
||||
bs2b->a0_lo = G_lo * (1.0 - x);
|
||||
|
||||
x = exp(-2.0 * M_PI * Fc_hi / bs2b->srate);
|
||||
bs2b->b1_hi = x;
|
||||
bs2b->a0_hi = 1.0 - G_hi * (1.0 - x);
|
||||
bs2b->a1_hi = -x;
|
||||
|
||||
bs2b->gain = 1.0f / (float)(1.0 - G_hi + G_lo);
|
||||
} /* init */
|
||||
|
||||
/* Exported functions.
|
||||
* See descriptions in "bs2b.h"
|
||||
*/
|
||||
|
||||
void bs2b_set_level(struct bs2b *bs2b, int level)
|
||||
{
|
||||
if(level == bs2b->level)
|
||||
return;
|
||||
bs2b->level = level;
|
||||
init(bs2b);
|
||||
} /* bs2b_set_level */
|
||||
|
||||
int bs2b_get_level(struct bs2b *bs2b)
|
||||
{
|
||||
return bs2b->level;
|
||||
} /* bs2b_get_level */
|
||||
|
||||
void bs2b_set_srate(struct bs2b *bs2b, int srate)
|
||||
{
|
||||
if (srate == bs2b->srate)
|
||||
return;
|
||||
bs2b->srate = srate;
|
||||
init(bs2b);
|
||||
} /* bs2b_set_srate */
|
||||
|
||||
int bs2b_get_srate(struct bs2b *bs2b)
|
||||
{
|
||||
return bs2b->srate;
|
||||
} /* bs2b_get_srate */
|
||||
|
||||
void bs2b_clear(struct bs2b *bs2b)
|
||||
{
|
||||
memset(&bs2b->last_sample, 0, sizeof(bs2b->last_sample));
|
||||
} /* bs2b_clear */
|
||||
|
||||
void bs2b_cross_feed(struct bs2b *bs2b, float *sample)
|
||||
{
|
||||
/* Lowpass filter */
|
||||
bs2b->last_sample.lo[0] = lo_filter(sample[0], bs2b->last_sample.lo[0]);
|
||||
bs2b->last_sample.lo[1] = lo_filter(sample[1], bs2b->last_sample.lo[1]);
|
||||
|
||||
/* Highboost filter */
|
||||
bs2b->last_sample.hi[0] = hi_filter(sample[0], bs2b->last_sample.asis[0], bs2b->last_sample.hi[0]);
|
||||
bs2b->last_sample.hi[1] = hi_filter(sample[1], bs2b->last_sample.asis[1], bs2b->last_sample.hi[1]);
|
||||
bs2b->last_sample.asis[0] = sample[0];
|
||||
bs2b->last_sample.asis[1] = sample[1];
|
||||
|
||||
/* Crossfeed */
|
||||
sample[0] = (float)(bs2b->last_sample.hi[0] + bs2b->last_sample.lo[1]);
|
||||
sample[1] = (float)(bs2b->last_sample.hi[1] + bs2b->last_sample.lo[0]);
|
||||
|
||||
/* Bass boost cause allpass attenuation */
|
||||
sample[0] *= bs2b->gain;
|
||||
sample[1] *= bs2b->gain;
|
||||
|
||||
/* Clipping of overloaded samples */
|
||||
#if 0
|
||||
if (sample[0] > 1.0)
|
||||
sample[0] = 1.0;
|
||||
if (sample[0] < -1.0)
|
||||
sample[0] = -1.0;
|
||||
if (sample[1] > 1.0)
|
||||
sample[1] = 1.0;
|
||||
if (sample[1] < -1.0)
|
||||
sample[1] = -1.0;
|
||||
#endif
|
||||
} /* bs2b_cross_feed */
|
||||
|
||||
-285
@@ -1,285 +0,0 @@
|
||||
/**
|
||||
* OpenAL cross platform audio library
|
||||
* Copyright (C) 1999-2007 by authors.
|
||||
* 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., 59 Temple Place - Suite 330,
|
||||
* Boston, MA 02111-1307, USA.
|
||||
* Or go to http://www.gnu.org/copyleft/lgpl.html
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <memory.h>
|
||||
|
||||
#include <windows.h>
|
||||
#include <mmsystem.h>
|
||||
#include <dsound.h>
|
||||
|
||||
#include "alMain.h"
|
||||
#include "AL/al.h"
|
||||
#include "AL/alc.h"
|
||||
|
||||
|
||||
typedef struct {
|
||||
// DirectSound Playback Device
|
||||
LPDIRECTSOUND lpDS;
|
||||
LPDIRECTSOUNDBUFFER DSpbuffer;
|
||||
LPDIRECTSOUNDBUFFER DSsbuffer;
|
||||
MMRESULT ulDSTimerID;
|
||||
DWORD OldWriteCursor;
|
||||
} DSoundData;
|
||||
|
||||
|
||||
static ALCchar *DeviceList[16];
|
||||
|
||||
static void CALLBACK DirectSoundProc(UINT uID,UINT uReserved,DWORD_PTR dwUser,DWORD_PTR dwReserved1,DWORD_PTR dwReserved2)
|
||||
{
|
||||
ALCdevice *pDevice = (ALCdevice *)dwUser;
|
||||
DSoundData *pData = pDevice->ExtraData;
|
||||
DWORD PlayCursor,WriteCursor;
|
||||
BYTE *WritePtr1,*WritePtr2;
|
||||
DWORD WriteCnt1,WriteCnt2;
|
||||
WAVEFORMATEX OutputType;
|
||||
DWORD BytesPlayed;
|
||||
DWORD BufSize;
|
||||
HRESULT DSRes;
|
||||
|
||||
(void)uID;
|
||||
(void)uReserved;
|
||||
(void)dwReserved1;
|
||||
(void)dwReserved2;
|
||||
|
||||
BufSize = pDevice->UpdateFreq * 2 * pDevice->FrameSize;
|
||||
|
||||
// Get current play and write cursors
|
||||
IDirectSoundBuffer_GetCurrentPosition(pData->DSsbuffer,&PlayCursor,&WriteCursor);
|
||||
if (!pData->OldWriteCursor) pData->OldWriteCursor=WriteCursor-PlayCursor;
|
||||
|
||||
// Get the output format and figure the number of bytes played (block aligned)
|
||||
IDirectSoundBuffer_GetFormat(pData->DSsbuffer,&OutputType,sizeof(WAVEFORMATEX),NULL);
|
||||
BytesPlayed=((((WriteCursor<pData->OldWriteCursor)?(BufSize+WriteCursor-pData->OldWriteCursor):(WriteCursor-pData->OldWriteCursor))/OutputType.nBlockAlign)*OutputType.nBlockAlign);
|
||||
|
||||
// Lock output buffer started at 40msec in front of the old write cursor (15msec in front of the actual write cursor)
|
||||
DSRes=IDirectSoundBuffer_Lock(pData->DSsbuffer,(pData->OldWriteCursor+(OutputType.nSamplesPerSec/25)*OutputType.nBlockAlign)%BufSize,BytesPlayed,(LPVOID*)&WritePtr1,&WriteCnt1,(LPVOID*)&WritePtr2,&WriteCnt2,0);
|
||||
|
||||
// If the buffer is lost, restore it, play and lock
|
||||
if (DSRes==DSERR_BUFFERLOST)
|
||||
{
|
||||
IDirectSoundBuffer_Restore(pData->DSsbuffer);
|
||||
IDirectSoundBuffer_Play(pData->DSsbuffer,0,0,DSBPLAY_LOOPING);
|
||||
DSRes=IDirectSoundBuffer_Lock(pData->DSsbuffer,(pData->OldWriteCursor+(OutputType.nSamplesPerSec/25)*OutputType.nBlockAlign)%BufSize,BytesPlayed,(LPVOID*)&WritePtr1,&WriteCnt1,(LPVOID*)&WritePtr2,&WriteCnt2,0);
|
||||
}
|
||||
|
||||
// Successfully locked the output buffer
|
||||
if (DSRes==DS_OK)
|
||||
{
|
||||
// If we have an active context, mix data directly into output buffer otherwise fill with silence
|
||||
SuspendContext(NULL);
|
||||
if (WritePtr1)
|
||||
aluMixData(pDevice->Context, WritePtr1, WriteCnt1, pDevice->Format);
|
||||
if (WritePtr2)
|
||||
aluMixData(pDevice->Context, WritePtr2, WriteCnt2, pDevice->Format);
|
||||
ProcessContext(NULL);
|
||||
|
||||
// Unlock output buffer only when successfully locked
|
||||
IDirectSoundBuffer_Unlock(pData->DSsbuffer,WritePtr1,WriteCnt1,WritePtr2,WriteCnt2);
|
||||
}
|
||||
|
||||
// Update old write cursor location
|
||||
pData->OldWriteCursor=((pData->OldWriteCursor+BytesPlayed)%BufSize);
|
||||
}
|
||||
|
||||
|
||||
static ALCboolean DSoundOpenPlayback(ALCdevice *device, const ALCchar *deviceName)
|
||||
{
|
||||
DSBUFFERDESC DSBDescription;
|
||||
DSoundData *pData = NULL;
|
||||
WAVEFORMATEX OutputType;
|
||||
HRESULT hr;
|
||||
|
||||
if(deviceName)
|
||||
{
|
||||
int i;
|
||||
for(i = 0;DeviceList[i];i++)
|
||||
{
|
||||
if(strcmp(deviceName, DeviceList[i]) == 0)
|
||||
{
|
||||
device->szDeviceName = DeviceList[i];
|
||||
break;
|
||||
}
|
||||
}
|
||||
if(!DeviceList[i])
|
||||
return ALC_FALSE;
|
||||
}
|
||||
else
|
||||
device->szDeviceName = DeviceList[0];
|
||||
|
||||
//Platform specific
|
||||
memset(&OutputType, 0, sizeof(WAVEFORMATEX));
|
||||
OutputType.wFormatTag = WAVE_FORMAT_PCM;
|
||||
OutputType.nChannels = device->Channels;
|
||||
OutputType.wBitsPerSample = aluBytesFromFormat(device->Format) * 8;
|
||||
OutputType.nBlockAlign = OutputType.nChannels*OutputType.wBitsPerSample/8;
|
||||
OutputType.nSamplesPerSec = device->Frequency;
|
||||
OutputType.nAvgBytesPerSec = OutputType.nSamplesPerSec*OutputType.nBlockAlign;
|
||||
OutputType.cbSize = 0;
|
||||
|
||||
//Initialise requested device
|
||||
|
||||
pData = calloc(1, sizeof(DSoundData));
|
||||
if(!pData)
|
||||
{
|
||||
SetALCError(ALC_OUT_OF_MEMORY);
|
||||
return ALC_FALSE;
|
||||
}
|
||||
|
||||
//Init COM
|
||||
CoInitialize(NULL);
|
||||
|
||||
//DirectSound Init code
|
||||
hr = CoCreateInstance(&CLSID_DirectSound, NULL, CLSCTX_INPROC_SERVER, &IID_IDirectSound, (LPVOID*)&pData->lpDS);
|
||||
if(SUCCEEDED(hr))
|
||||
hr = IDirectSound_Initialize(pData->lpDS, NULL);
|
||||
if(SUCCEEDED(hr))
|
||||
hr = IDirectSound_SetCooperativeLevel(pData->lpDS, GetForegroundWindow(), DSSCL_PRIORITY);
|
||||
|
||||
if(SUCCEEDED(hr))
|
||||
{
|
||||
memset(&DSBDescription,0,sizeof(DSBUFFERDESC));
|
||||
DSBDescription.dwSize=sizeof(DSBUFFERDESC);
|
||||
DSBDescription.dwFlags=DSBCAPS_PRIMARYBUFFER;
|
||||
hr = IDirectSound_CreateSoundBuffer(pData->lpDS, &DSBDescription, &pData->DSpbuffer, NULL);
|
||||
}
|
||||
if(SUCCEEDED(hr))
|
||||
hr = IDirectSoundBuffer_SetFormat(pData->DSpbuffer,&OutputType);
|
||||
|
||||
if(SUCCEEDED(hr))
|
||||
{
|
||||
memset(&DSBDescription,0,sizeof(DSBUFFERDESC));
|
||||
DSBDescription.dwSize=sizeof(DSBUFFERDESC);
|
||||
DSBDescription.dwFlags=DSBCAPS_GLOBALFOCUS|DSBCAPS_GETCURRENTPOSITION2;
|
||||
DSBDescription.dwBufferBytes=device->UpdateFreq * 2 * device->FrameSize;
|
||||
DSBDescription.lpwfxFormat=&OutputType;
|
||||
hr = IDirectSound_CreateSoundBuffer(pData->lpDS, &DSBDescription, &pData->DSsbuffer, NULL);
|
||||
}
|
||||
|
||||
if(SUCCEEDED(hr))
|
||||
hr = IDirectSoundBuffer_Play(pData->DSsbuffer, 0, 0, DSBPLAY_LOOPING);
|
||||
|
||||
if(FAILED(hr))
|
||||
{
|
||||
if (pData->DSsbuffer)
|
||||
IDirectSoundBuffer_Release(pData->DSsbuffer);
|
||||
if (pData->DSpbuffer)
|
||||
IDirectSoundBuffer_Release(pData->DSpbuffer);
|
||||
if (pData->lpDS)
|
||||
IDirectSound_Release(pData->lpDS);
|
||||
|
||||
free(pData);
|
||||
return ALC_FALSE;
|
||||
}
|
||||
|
||||
pData->ulDSTimerID = timeSetEvent(25, 0, (LPTIMECALLBACK)DirectSoundProc, (DWORD)device, (UINT)TIME_CALLBACK_FUNCTION|TIME_PERIODIC);
|
||||
device->MaxNoOfSources = 256;
|
||||
|
||||
device->ExtraData = pData;
|
||||
return ALC_TRUE;
|
||||
}
|
||||
|
||||
static void DSoundClosePlayback(ALCdevice *device)
|
||||
{
|
||||
DSoundData *pData = device->ExtraData;
|
||||
|
||||
// Stop and release the DS timer
|
||||
if (pData->ulDSTimerID)
|
||||
timeKillEvent(pData->ulDSTimerID);
|
||||
|
||||
// Wait ... just in case any timer events happen
|
||||
Sleep(100);
|
||||
|
||||
SuspendContext(NULL);
|
||||
|
||||
if (pData->DSsbuffer)
|
||||
IDirectSoundBuffer_Release(pData->DSsbuffer);
|
||||
if (pData->DSpbuffer)
|
||||
IDirectSoundBuffer_Release(pData->DSpbuffer);
|
||||
IDirectSound_Release(pData->lpDS);
|
||||
|
||||
//Deinit COM
|
||||
CoUninitialize();
|
||||
|
||||
ProcessContext(NULL);
|
||||
|
||||
free(pData);
|
||||
device->ExtraData = NULL;
|
||||
}
|
||||
|
||||
|
||||
static ALCboolean DSoundOpenCapture(ALCdevice *pDevice, const ALCchar *deviceName, ALCuint frequency, ALCenum format, ALCsizei SampleSize)
|
||||
{
|
||||
(void)pDevice;
|
||||
(void)deviceName;
|
||||
(void)frequency;
|
||||
(void)format;
|
||||
(void)SampleSize;
|
||||
return ALC_FALSE;
|
||||
}
|
||||
|
||||
static void DSoundCloseCapture(ALCdevice *pDevice)
|
||||
{
|
||||
(void)pDevice;
|
||||
}
|
||||
|
||||
static void DSoundStartCapture(ALCdevice *pDevice)
|
||||
{
|
||||
(void)pDevice;
|
||||
}
|
||||
|
||||
static void DSoundStopCapture(ALCdevice *pDevice)
|
||||
{
|
||||
(void)pDevice;
|
||||
}
|
||||
|
||||
static void DSoundCaptureSamples(ALCdevice *pDevice, ALCvoid *pBuffer, ALCuint lSamples)
|
||||
{
|
||||
(void)pDevice;
|
||||
(void)pBuffer;
|
||||
(void)lSamples;
|
||||
}
|
||||
|
||||
static ALCuint DSoundAvailableSamples(ALCdevice *pDevice)
|
||||
{
|
||||
(void)pDevice;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
BackendFuncs DSoundFuncs = {
|
||||
DSoundOpenPlayback,
|
||||
DSoundClosePlayback,
|
||||
DSoundOpenCapture,
|
||||
DSoundCloseCapture,
|
||||
DSoundStartCapture,
|
||||
DSoundStopCapture,
|
||||
DSoundCaptureSamples,
|
||||
DSoundAvailableSamples
|
||||
};
|
||||
|
||||
void alcDSoundInit(BackendFuncs *FuncList)
|
||||
{
|
||||
*FuncList = DSoundFuncs;
|
||||
|
||||
DeviceList[0] = AppendDeviceList("DirectSound Software");
|
||||
AppendAllDeviceList(DeviceList[0]);
|
||||
}
|
||||
+674
@@ -0,0 +1,674 @@
|
||||
/**
|
||||
* OpenAL cross platform audio library
|
||||
* Copyright (C) 2011 by authors.
|
||||
* 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., 59 Temple Place - Suite 330,
|
||||
* Boston, MA 02111-1307, USA.
|
||||
* Or go to http://www.gnu.org/copyleft/lgpl.html
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <time.h>
|
||||
#include <errno.h>
|
||||
#include <stdarg.h>
|
||||
#ifdef HAVE_MALLOC_H
|
||||
#include <malloc.h>
|
||||
#endif
|
||||
|
||||
#if defined(HAVE_GUIDDEF_H) || defined(HAVE_INITGUID_H)
|
||||
#define INITGUID
|
||||
#include <windows.h>
|
||||
#ifdef HAVE_GUIDDEF_H
|
||||
#include <guiddef.h>
|
||||
#else
|
||||
#include <initguid.h>
|
||||
#endif
|
||||
|
||||
DEFINE_GUID(KSDATAFORMAT_SUBTYPE_PCM, 0x00000001, 0x0000, 0x0010, 0x80,0x00, 0x00,0xaa,0x00,0x38,0x9b,0x71);
|
||||
DEFINE_GUID(KSDATAFORMAT_SUBTYPE_IEEE_FLOAT, 0x00000003, 0x0000, 0x0010, 0x80,0x00, 0x00,0xaa,0x00,0x38,0x9b,0x71);
|
||||
|
||||
DEFINE_GUID(IID_IDirectSoundNotify, 0xb0210783, 0x89cd, 0x11d0, 0xaf,0x08, 0x00,0xa0,0xc9,0x25,0xcd,0x16);
|
||||
|
||||
DEFINE_GUID(CLSID_MMDeviceEnumerator, 0xbcde0395, 0xe52f, 0x467c, 0x8e,0x3d, 0xc4,0x57,0x92,0x91,0x69,0x2e);
|
||||
DEFINE_GUID(IID_IMMDeviceEnumerator, 0xa95664d2, 0x9614, 0x4f35, 0xa7,0x46, 0xde,0x8d,0xb6,0x36,0x17,0xe6);
|
||||
DEFINE_GUID(IID_IAudioClient, 0x1cb9ad4c, 0xdbfa, 0x4c32, 0xb1,0x78, 0xc2,0xf5,0x68,0xa7,0x03,0xb2);
|
||||
DEFINE_GUID(IID_IAudioRenderClient, 0xf294acfc, 0x3146, 0x4483, 0xa7,0xbf, 0xad,0xdc,0xa7,0xc2,0x60,0xe2);
|
||||
|
||||
#ifdef HAVE_MMDEVAPI
|
||||
#include <devpropdef.h>
|
||||
DEFINE_DEVPROPKEY(DEVPKEY_Device_FriendlyName, 0xa45c254e, 0xdf1c, 0x4efd, 0x80,0x20, 0x67,0xd1,0x46,0xa8,0x50,0xe0, 14);
|
||||
#endif
|
||||
#endif
|
||||
#ifdef HAVE_DLFCN_H
|
||||
#include <dlfcn.h>
|
||||
#endif
|
||||
#ifdef HAVE_CPUID_H
|
||||
#include <cpuid.h>
|
||||
#endif
|
||||
#ifdef HAVE_FLOAT_H
|
||||
#include <float.h>
|
||||
#endif
|
||||
#ifdef HAVE_IEEEFP_H
|
||||
#include <ieeefp.h>
|
||||
#endif
|
||||
|
||||
#include "alMain.h"
|
||||
|
||||
ALuint CPUCapFlags = 0;
|
||||
|
||||
|
||||
void FillCPUCaps(ALuint capfilter)
|
||||
{
|
||||
ALuint caps = 0;
|
||||
|
||||
/* FIXME: We really should get this for all available CPUs in case different
|
||||
* CPUs have different caps (is that possible on one machine?). */
|
||||
#if defined(HAVE_CPUID_H) && (defined(__i386__) || defined(__x86_64__) || \
|
||||
defined(_M_IX86) || defined(_M_X64))
|
||||
union {
|
||||
unsigned int regs[4];
|
||||
char str[sizeof(unsigned int[4])];
|
||||
} cpuinf[3];
|
||||
|
||||
if(!__get_cpuid(0, &cpuinf[0].regs[0], &cpuinf[0].regs[1], &cpuinf[0].regs[2], &cpuinf[0].regs[3]))
|
||||
ERR("Failed to get CPUID\n");
|
||||
else
|
||||
{
|
||||
unsigned int maxfunc = cpuinf[0].regs[0];
|
||||
unsigned int maxextfunc = 0;
|
||||
|
||||
if(__get_cpuid(0x80000000, &cpuinf[0].regs[0], &cpuinf[0].regs[1], &cpuinf[0].regs[2], &cpuinf[0].regs[3]))
|
||||
maxextfunc = cpuinf[0].regs[0];
|
||||
TRACE("Detected max CPUID function: 0x%x (ext. 0x%x)\n", maxfunc, maxextfunc);
|
||||
|
||||
TRACE("Vendor ID: \"%.4s%.4s%.4s\"\n", cpuinf[0].str+4, cpuinf[0].str+12, cpuinf[0].str+8);
|
||||
if(maxextfunc >= 0x80000004 &&
|
||||
__get_cpuid(0x80000002, &cpuinf[0].regs[0], &cpuinf[0].regs[1], &cpuinf[0].regs[2], &cpuinf[0].regs[3]) &&
|
||||
__get_cpuid(0x80000003, &cpuinf[1].regs[0], &cpuinf[1].regs[1], &cpuinf[1].regs[2], &cpuinf[1].regs[3]) &&
|
||||
__get_cpuid(0x80000004, &cpuinf[2].regs[0], &cpuinf[2].regs[1], &cpuinf[2].regs[2], &cpuinf[2].regs[3]))
|
||||
TRACE("Name: \"%.16s%.16s%.16s\"\n", cpuinf[0].str, cpuinf[1].str, cpuinf[2].str);
|
||||
|
||||
if(maxfunc >= 1 &&
|
||||
__get_cpuid(1, &cpuinf[0].regs[0], &cpuinf[0].regs[1], &cpuinf[0].regs[2], &cpuinf[0].regs[3]))
|
||||
{
|
||||
#ifdef bit_SSE
|
||||
if((cpuinf[0].regs[3]&bit_SSE))
|
||||
caps |= CPU_CAP_SSE;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
#elif defined(HAVE_WINDOWS_H)
|
||||
HMODULE k32 = GetModuleHandleA("kernel32.dll");
|
||||
BOOL (WINAPI*IsProcessorFeaturePresent)(DWORD ProcessorFeature);
|
||||
IsProcessorFeaturePresent = (BOOL(WINAPI*)(DWORD))GetProcAddress(k32, "IsProcessorFeaturePresent");
|
||||
if(!IsProcessorFeaturePresent)
|
||||
ERR("IsProcessorFeaturePresent not available; CPU caps not detected\n");
|
||||
else
|
||||
{
|
||||
if(IsProcessorFeaturePresent(PF_XMMI_INSTRUCTIONS_AVAILABLE))
|
||||
caps |= CPU_CAP_SSE;
|
||||
}
|
||||
#endif
|
||||
#ifdef HAVE_NEON
|
||||
/* Assume Neon support if compiled with it */
|
||||
caps |= CPU_CAP_NEON;
|
||||
#endif
|
||||
|
||||
TRACE("Got caps:%s%s%s\n", ((caps&CPU_CAP_SSE)?((capfilter&CPU_CAP_SSE)?" SSE":" (SSE)"):""),
|
||||
((caps&CPU_CAP_NEON)?((capfilter&CPU_CAP_NEON)?" Neon":" (Neon)"):""),
|
||||
((!caps)?" -none-":""));
|
||||
CPUCapFlags = caps & capfilter;
|
||||
}
|
||||
|
||||
|
||||
void *al_malloc(size_t alignment, size_t size)
|
||||
{
|
||||
#if defined(HAVE_ALIGNED_ALLOC)
|
||||
size = (size+(alignment-1))&~(alignment-1);
|
||||
return aligned_alloc(alignment, size);
|
||||
#elif defined(HAVE_POSIX_MEMALIGN)
|
||||
void *ret;
|
||||
if(posix_memalign(&ret, alignment, size) == 0)
|
||||
return ret;
|
||||
return NULL;
|
||||
#elif defined(HAVE__ALIGNED_MALLOC)
|
||||
return _aligned_malloc(size, alignment);
|
||||
#else
|
||||
char *ret = malloc(size+alignment);
|
||||
if(ret != NULL)
|
||||
{
|
||||
*(ret++) = 0x00;
|
||||
while(((ALintptrEXT)ret&(alignment-1)) != 0)
|
||||
*(ret++) = 0x55;
|
||||
}
|
||||
return ret;
|
||||
#endif
|
||||
}
|
||||
|
||||
void *al_calloc(size_t alignment, size_t size)
|
||||
{
|
||||
void *ret = al_malloc(alignment, size);
|
||||
if(ret) memset(ret, 0, size);
|
||||
return ret;
|
||||
}
|
||||
|
||||
void al_free(void *ptr)
|
||||
{
|
||||
#if defined(HAVE_ALIGNED_ALLOC) || defined(HAVE_POSIX_MEMALIGN)
|
||||
free(ptr);
|
||||
#elif defined(HAVE__ALIGNED_MALLOC)
|
||||
_aligned_free(ptr);
|
||||
#else
|
||||
if(ptr != NULL)
|
||||
{
|
||||
char *finder = ptr;
|
||||
do {
|
||||
--finder;
|
||||
} while(*finder == 0x55);
|
||||
free(finder);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
#if (defined(HAVE___CONTROL87_2) || defined(HAVE__CONTROLFP)) && (defined(__x86_64__) || defined(_M_X64))
|
||||
/* Win64 doesn't allow us to set the precision control. */
|
||||
#undef _MCW_PC
|
||||
#define _MCW_PC 0
|
||||
#endif
|
||||
|
||||
void SetMixerFPUMode(FPUCtl *ctl)
|
||||
{
|
||||
#if defined(__GNUC__) && (defined(__i386__) || defined(__x86_64__))
|
||||
unsigned short fpuState;
|
||||
__asm__ __volatile__("fnstcw %0" : "=m" (*&fpuState));
|
||||
ctl->state = fpuState;
|
||||
fpuState &= ~0x300; /* clear precision to single */
|
||||
fpuState |= 0xC00; /* set round-to-zero */
|
||||
__asm__ __volatile__("fldcw %0" : : "m" (*&fpuState));
|
||||
#ifdef HAVE_SSE
|
||||
if((CPUCapFlags&CPU_CAP_SSE))
|
||||
{
|
||||
int sseState;
|
||||
__asm__ __volatile__("stmxcsr %0" : "=m" (*&sseState));
|
||||
ctl->sse_state = sseState;
|
||||
sseState |= 0x0C00; /* set round-to-zero */
|
||||
sseState |= 0x8000; /* set flush-to-zero */
|
||||
__asm__ __volatile__("ldmxcsr %0" : : "m" (*&sseState));
|
||||
}
|
||||
#endif
|
||||
#elif defined(HAVE___CONTROL87_2)
|
||||
int mode;
|
||||
__control87_2(0, 0, &ctl->state, NULL);
|
||||
__control87_2(_RC_CHOP|_PC_24, _MCW_RC|_MCW_PC, &mode, NULL);
|
||||
#ifdef HAVE_SSE
|
||||
if((CPUCapFlags&CPU_CAP_SSE))
|
||||
{
|
||||
__control87_2(0, 0, NULL, &ctl->sse_state);
|
||||
__control87_2(_RC_CHOP|_DN_FLUSH, _MCW_RC|_MCW_DN, NULL, &mode);
|
||||
}
|
||||
#endif
|
||||
#elif defined(HAVE__CONTROLFP)
|
||||
ctl->state = _controlfp(0, 0);
|
||||
(void)_controlfp(_RC_CHOP|_PC_24, _MCW_RC|_MCW_PC);
|
||||
#elif defined(HAVE_FESETROUND)
|
||||
ctl->state = fegetround();
|
||||
#ifdef FE_TOWARDZERO
|
||||
fesetround(FE_TOWARDZERO);
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
|
||||
void RestoreFPUMode(const FPUCtl *ctl)
|
||||
{
|
||||
#if defined(__GNUC__) && (defined(__i386__) || defined(__x86_64__))
|
||||
unsigned short fpuState = ctl->state;
|
||||
__asm__ __volatile__("fldcw %0" : : "m" (*&fpuState));
|
||||
#ifdef HAVE_SSE
|
||||
if((CPUCapFlags&CPU_CAP_SSE))
|
||||
__asm__ __volatile__("ldmxcsr %0" : : "m" (*&ctl->sse_state));
|
||||
#endif
|
||||
#elif defined(HAVE___CONTROL87_2)
|
||||
int mode;
|
||||
__control87_2(ctl->state, _MCW_RC|_MCW_PC, &mode, NULL);
|
||||
#ifdef HAVE_SSE
|
||||
if((CPUCapFlags&CPU_CAP_SSE))
|
||||
__control87_2(ctl->sse_state, _MCW_RC|_MCW_DN, NULL, &mode);
|
||||
#endif
|
||||
#elif defined(HAVE__CONTROLFP)
|
||||
_controlfp(ctl->state, _MCW_RC|_MCW_PC);
|
||||
#elif defined(HAVE_FESETROUND)
|
||||
fesetround(ctl->state);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
#ifdef _WIN32
|
||||
void pthread_once(pthread_once_t *once, void (*callback)(void))
|
||||
{
|
||||
LONG ret;
|
||||
while((ret=InterlockedExchange(once, 1)) == 1)
|
||||
sched_yield();
|
||||
if(ret == 0)
|
||||
callback();
|
||||
InterlockedExchange(once, 2);
|
||||
}
|
||||
|
||||
|
||||
int pthread_key_create(pthread_key_t *key, void (*callback)(void*))
|
||||
{
|
||||
*key = TlsAlloc();
|
||||
if(callback)
|
||||
InsertUIntMapEntry(&TlsDestructor, *key, callback);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int pthread_key_delete(pthread_key_t key)
|
||||
{
|
||||
InsertUIntMapEntry(&TlsDestructor, key, NULL);
|
||||
TlsFree(key);
|
||||
return 0;
|
||||
}
|
||||
|
||||
void *pthread_getspecific(pthread_key_t key)
|
||||
{ return TlsGetValue(key); }
|
||||
|
||||
int pthread_setspecific(pthread_key_t key, void *val)
|
||||
{
|
||||
TlsSetValue(key, val);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
void *LoadLib(const char *name)
|
||||
{ return LoadLibraryA(name); }
|
||||
void CloseLib(void *handle)
|
||||
{ FreeLibrary((HANDLE)handle); }
|
||||
void *GetSymbol(void *handle, const char *name)
|
||||
{
|
||||
void *ret;
|
||||
|
||||
ret = (void*)GetProcAddress((HANDLE)handle, name);
|
||||
if(ret == NULL)
|
||||
ERR("Failed to load %s\n", name);
|
||||
return ret;
|
||||
}
|
||||
|
||||
WCHAR *strdupW(const WCHAR *str)
|
||||
{
|
||||
const WCHAR *n;
|
||||
WCHAR *ret;
|
||||
size_t len;
|
||||
|
||||
n = str;
|
||||
while(*n) n++;
|
||||
len = n - str;
|
||||
|
||||
ret = calloc(sizeof(WCHAR), len+1);
|
||||
if(ret != NULL)
|
||||
memcpy(ret, str, sizeof(WCHAR)*len);
|
||||
return ret;
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
#include <pthread.h>
|
||||
#ifdef HAVE_PTHREAD_NP_H
|
||||
#include <pthread_np.h>
|
||||
#endif
|
||||
#include <sched.h>
|
||||
|
||||
void InitializeCriticalSection(CRITICAL_SECTION *cs)
|
||||
{
|
||||
pthread_mutexattr_t attrib;
|
||||
int ret;
|
||||
|
||||
ret = pthread_mutexattr_init(&attrib);
|
||||
assert(ret == 0);
|
||||
|
||||
ret = pthread_mutexattr_settype(&attrib, PTHREAD_MUTEX_RECURSIVE);
|
||||
#ifdef HAVE_PTHREAD_NP_H
|
||||
if(ret != 0)
|
||||
ret = pthread_mutexattr_setkind_np(&attrib, PTHREAD_MUTEX_RECURSIVE);
|
||||
#endif
|
||||
assert(ret == 0);
|
||||
ret = pthread_mutex_init(cs, &attrib);
|
||||
assert(ret == 0);
|
||||
|
||||
pthread_mutexattr_destroy(&attrib);
|
||||
}
|
||||
void DeleteCriticalSection(CRITICAL_SECTION *cs)
|
||||
{
|
||||
int ret;
|
||||
ret = pthread_mutex_destroy(cs);
|
||||
assert(ret == 0);
|
||||
}
|
||||
void EnterCriticalSection(CRITICAL_SECTION *cs)
|
||||
{
|
||||
int ret;
|
||||
ret = pthread_mutex_lock(cs);
|
||||
assert(ret == 0);
|
||||
}
|
||||
void LeaveCriticalSection(CRITICAL_SECTION *cs)
|
||||
{
|
||||
int ret;
|
||||
ret = pthread_mutex_unlock(cs);
|
||||
assert(ret == 0);
|
||||
}
|
||||
|
||||
/* NOTE: This wrapper isn't quite accurate as it returns an ALuint, as opposed
|
||||
* to the expected DWORD. Both are defined as unsigned 32-bit types, however.
|
||||
* Additionally, Win32 is supposed to measure the time since Windows started,
|
||||
* as opposed to the actual time. */
|
||||
ALuint timeGetTime(void)
|
||||
{
|
||||
#if _POSIX_TIMERS > 0
|
||||
struct timespec ts;
|
||||
int ret = -1;
|
||||
|
||||
#if defined(_POSIX_MONOTONIC_CLOCK) && (_POSIX_MONOTONIC_CLOCK >= 0)
|
||||
#if _POSIX_MONOTONIC_CLOCK == 0
|
||||
static int hasmono = 0;
|
||||
if(hasmono > 0 || (hasmono == 0 &&
|
||||
(hasmono=sysconf(_SC_MONOTONIC_CLOCK)) > 0))
|
||||
#endif
|
||||
ret = clock_gettime(CLOCK_MONOTONIC, &ts);
|
||||
#endif
|
||||
if(ret != 0)
|
||||
ret = clock_gettime(CLOCK_REALTIME, &ts);
|
||||
assert(ret == 0);
|
||||
|
||||
return ts.tv_nsec/1000000 + ts.tv_sec*1000;
|
||||
#else
|
||||
struct timeval tv;
|
||||
int ret;
|
||||
|
||||
ret = gettimeofday(&tv, NULL);
|
||||
assert(ret == 0);
|
||||
|
||||
return tv.tv_usec/1000 + tv.tv_sec*1000;
|
||||
#endif
|
||||
}
|
||||
|
||||
void Sleep(ALuint t)
|
||||
{
|
||||
struct timespec tv, rem;
|
||||
tv.tv_nsec = (t*1000000)%1000000000;
|
||||
tv.tv_sec = t/1000;
|
||||
|
||||
while(nanosleep(&tv, &rem) == -1 && errno == EINTR)
|
||||
tv = rem;
|
||||
}
|
||||
|
||||
#ifdef HAVE_DLFCN_H
|
||||
|
||||
void *LoadLib(const char *name)
|
||||
{
|
||||
const char *err;
|
||||
void *handle;
|
||||
|
||||
dlerror();
|
||||
handle = dlopen(name, RTLD_NOW);
|
||||
if((err=dlerror()) != NULL)
|
||||
handle = NULL;
|
||||
return handle;
|
||||
}
|
||||
void CloseLib(void *handle)
|
||||
{ dlclose(handle); }
|
||||
void *GetSymbol(void *handle, const char *name)
|
||||
{
|
||||
const char *err;
|
||||
void *sym;
|
||||
|
||||
dlerror();
|
||||
sym = dlsym(handle, name);
|
||||
if((err=dlerror()) != NULL)
|
||||
{
|
||||
WARN("Failed to load %s: %s\n", name, err);
|
||||
sym = NULL;
|
||||
}
|
||||
return sym;
|
||||
}
|
||||
|
||||
#endif
|
||||
#endif
|
||||
|
||||
|
||||
void al_print(const char *type, const char *func, const char *fmt, ...)
|
||||
{
|
||||
char str[256];
|
||||
int i;
|
||||
|
||||
i = snprintf(str, sizeof(str), "AL lib: %s %s: ", type, func);
|
||||
if(i > 0 && (unsigned int)i < sizeof(str))
|
||||
{
|
||||
va_list ap;
|
||||
va_start(ap, fmt);
|
||||
vsnprintf(str+i, sizeof(str)-i, fmt, ap);
|
||||
va_end(ap);
|
||||
}
|
||||
str[sizeof(str)-1] = 0;
|
||||
|
||||
fprintf(LogFile, "%s", str);
|
||||
fflush(LogFile);
|
||||
}
|
||||
|
||||
|
||||
void SetRTPriority(void)
|
||||
{
|
||||
ALboolean failed = AL_FALSE;
|
||||
|
||||
#ifdef _WIN32
|
||||
if(RTPrioLevel > 0)
|
||||
failed = !SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_TIME_CRITICAL);
|
||||
#elif defined(HAVE_PTHREAD_SETSCHEDPARAM) && !defined(__OpenBSD__)
|
||||
if(RTPrioLevel > 0)
|
||||
{
|
||||
struct sched_param param;
|
||||
/* Use the minimum real-time priority possible for now (on Linux this
|
||||
* should be 1 for SCHED_RR) */
|
||||
param.sched_priority = sched_get_priority_min(SCHED_RR);
|
||||
failed = !!pthread_setschedparam(pthread_self(), SCHED_RR, ¶m);
|
||||
}
|
||||
#else
|
||||
/* Real-time priority not available */
|
||||
failed = (RTPrioLevel>0);
|
||||
#endif
|
||||
if(failed)
|
||||
ERR("Failed to set priority level for thread\n");
|
||||
}
|
||||
|
||||
|
||||
static void Lock(volatile ALenum *l)
|
||||
{
|
||||
while(ExchangeInt(l, AL_TRUE) == AL_TRUE)
|
||||
sched_yield();
|
||||
}
|
||||
|
||||
static void Unlock(volatile ALenum *l)
|
||||
{
|
||||
ExchangeInt(l, AL_FALSE);
|
||||
}
|
||||
|
||||
void RWLockInit(RWLock *lock)
|
||||
{
|
||||
lock->read_count = 0;
|
||||
lock->write_count = 0;
|
||||
lock->read_lock = AL_FALSE;
|
||||
lock->read_entry_lock = AL_FALSE;
|
||||
lock->write_lock = AL_FALSE;
|
||||
}
|
||||
|
||||
void ReadLock(RWLock *lock)
|
||||
{
|
||||
Lock(&lock->read_entry_lock);
|
||||
Lock(&lock->read_lock);
|
||||
if(IncrementRef(&lock->read_count) == 1)
|
||||
Lock(&lock->write_lock);
|
||||
Unlock(&lock->read_lock);
|
||||
Unlock(&lock->read_entry_lock);
|
||||
}
|
||||
|
||||
void ReadUnlock(RWLock *lock)
|
||||
{
|
||||
if(DecrementRef(&lock->read_count) == 0)
|
||||
Unlock(&lock->write_lock);
|
||||
}
|
||||
|
||||
void WriteLock(RWLock *lock)
|
||||
{
|
||||
if(IncrementRef(&lock->write_count) == 1)
|
||||
Lock(&lock->read_lock);
|
||||
Lock(&lock->write_lock);
|
||||
}
|
||||
|
||||
void WriteUnlock(RWLock *lock)
|
||||
{
|
||||
Unlock(&lock->write_lock);
|
||||
if(DecrementRef(&lock->write_count) == 0)
|
||||
Unlock(&lock->read_lock);
|
||||
}
|
||||
|
||||
|
||||
void InitUIntMap(UIntMap *map, ALsizei limit)
|
||||
{
|
||||
map->array = NULL;
|
||||
map->size = 0;
|
||||
map->maxsize = 0;
|
||||
map->limit = limit;
|
||||
RWLockInit(&map->lock);
|
||||
}
|
||||
|
||||
void ResetUIntMap(UIntMap *map)
|
||||
{
|
||||
WriteLock(&map->lock);
|
||||
free(map->array);
|
||||
map->array = NULL;
|
||||
map->size = 0;
|
||||
map->maxsize = 0;
|
||||
WriteUnlock(&map->lock);
|
||||
}
|
||||
|
||||
ALenum InsertUIntMapEntry(UIntMap *map, ALuint key, ALvoid *value)
|
||||
{
|
||||
ALsizei pos = 0;
|
||||
|
||||
WriteLock(&map->lock);
|
||||
if(map->size > 0)
|
||||
{
|
||||
ALsizei low = 0;
|
||||
ALsizei high = map->size - 1;
|
||||
while(low < high)
|
||||
{
|
||||
ALsizei mid = low + (high-low)/2;
|
||||
if(map->array[mid].key < key)
|
||||
low = mid + 1;
|
||||
else
|
||||
high = mid;
|
||||
}
|
||||
if(map->array[low].key < key)
|
||||
low++;
|
||||
pos = low;
|
||||
}
|
||||
|
||||
if(pos == map->size || map->array[pos].key != key)
|
||||
{
|
||||
if(map->size == map->limit)
|
||||
{
|
||||
WriteUnlock(&map->lock);
|
||||
return AL_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
if(map->size == map->maxsize)
|
||||
{
|
||||
ALvoid *temp = NULL;
|
||||
ALsizei newsize;
|
||||
|
||||
newsize = (map->maxsize ? (map->maxsize<<1) : 4);
|
||||
if(newsize >= map->maxsize)
|
||||
temp = realloc(map->array, newsize*sizeof(map->array[0]));
|
||||
if(!temp)
|
||||
{
|
||||
WriteUnlock(&map->lock);
|
||||
return AL_OUT_OF_MEMORY;
|
||||
}
|
||||
map->array = temp;
|
||||
map->maxsize = newsize;
|
||||
}
|
||||
|
||||
if(pos < map->size)
|
||||
memmove(&map->array[pos+1], &map->array[pos],
|
||||
(map->size-pos)*sizeof(map->array[0]));
|
||||
map->size++;
|
||||
}
|
||||
map->array[pos].key = key;
|
||||
map->array[pos].value = value;
|
||||
WriteUnlock(&map->lock);
|
||||
|
||||
return AL_NO_ERROR;
|
||||
}
|
||||
|
||||
ALvoid *RemoveUIntMapKey(UIntMap *map, ALuint key)
|
||||
{
|
||||
ALvoid *ptr = NULL;
|
||||
WriteLock(&map->lock);
|
||||
if(map->size > 0)
|
||||
{
|
||||
ALsizei low = 0;
|
||||
ALsizei high = map->size - 1;
|
||||
while(low < high)
|
||||
{
|
||||
ALsizei mid = low + (high-low)/2;
|
||||
if(map->array[mid].key < key)
|
||||
low = mid + 1;
|
||||
else
|
||||
high = mid;
|
||||
}
|
||||
if(map->array[low].key == key)
|
||||
{
|
||||
ptr = map->array[low].value;
|
||||
if(low < map->size-1)
|
||||
memmove(&map->array[low], &map->array[low+1],
|
||||
(map->size-1-low)*sizeof(map->array[0]));
|
||||
map->size--;
|
||||
}
|
||||
}
|
||||
WriteUnlock(&map->lock);
|
||||
return ptr;
|
||||
}
|
||||
|
||||
ALvoid *LookupUIntMapKey(UIntMap *map, ALuint key)
|
||||
{
|
||||
ALvoid *ptr = NULL;
|
||||
ReadLock(&map->lock);
|
||||
if(map->size > 0)
|
||||
{
|
||||
ALsizei low = 0;
|
||||
ALsizei high = map->size - 1;
|
||||
while(low < high)
|
||||
{
|
||||
ALsizei mid = low + (high-low)/2;
|
||||
if(map->array[mid].key < key)
|
||||
low = mid + 1;
|
||||
else
|
||||
high = mid;
|
||||
}
|
||||
if(map->array[low].key == key)
|
||||
ptr = map->array[low].value;
|
||||
}
|
||||
ReadUnlock(&map->lock);
|
||||
return ptr;
|
||||
}
|
||||
+804
@@ -0,0 +1,804 @@
|
||||
/**
|
||||
* OpenAL cross platform audio library
|
||||
* Copyright (C) 2011 by Chris Robinson
|
||||
* 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., 59 Temple Place - Suite 330,
|
||||
* Boston, MA 02111-1307, USA.
|
||||
* Or go to http://www.gnu.org/copyleft/lgpl.html
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <ctype.h>
|
||||
|
||||
#include "AL/al.h"
|
||||
#include "AL/alc.h"
|
||||
#include "alMain.h"
|
||||
#include "alSource.h"
|
||||
#include "alu.h"
|
||||
|
||||
|
||||
#ifndef PATH_MAX
|
||||
#define PATH_MAX 4096
|
||||
#endif
|
||||
|
||||
|
||||
/* Current data set limits defined by the makehrtf utility. */
|
||||
#define MIN_IR_SIZE (8)
|
||||
#define MAX_IR_SIZE (128)
|
||||
#define MOD_IR_SIZE (8)
|
||||
|
||||
#define MIN_EV_COUNT (5)
|
||||
#define MAX_EV_COUNT (128)
|
||||
|
||||
#define MIN_AZ_COUNT (1)
|
||||
#define MAX_AZ_COUNT (128)
|
||||
|
||||
struct Hrtf {
|
||||
ALuint sampleRate;
|
||||
ALuint irSize;
|
||||
ALubyte evCount;
|
||||
|
||||
const ALubyte *azCount;
|
||||
const ALushort *evOffset;
|
||||
const ALshort *coeffs;
|
||||
const ALubyte *delays;
|
||||
|
||||
struct Hrtf *next;
|
||||
};
|
||||
|
||||
static const ALchar magicMarker00[8] = "MinPHR00";
|
||||
static const ALchar magicMarker01[8] = "MinPHR01";
|
||||
|
||||
/* Define the default HRTF:
|
||||
* ALubyte defaultAzCount [DefaultHrtf.evCount]
|
||||
* ALushort defaultEvOffset [DefaultHrtf.evCount]
|
||||
* ALshort defaultCoeffs [DefaultHrtf.irCount * defaultHrtf.irSize]
|
||||
* ALubyte defaultDelays [DefaultHrtf.irCount]
|
||||
*
|
||||
* struct Hrtf DefaultHrtf
|
||||
*/
|
||||
#include "hrtf_tables.inc"
|
||||
|
||||
static struct Hrtf *LoadedHrtfs = NULL;
|
||||
|
||||
/* Calculate the elevation indices given the polar elevation in radians.
|
||||
* This will return two indices between 0 and (Hrtf->evCount - 1) and an
|
||||
* interpolation factor between 0.0 and 1.0.
|
||||
*/
|
||||
static void CalcEvIndices(const struct Hrtf *Hrtf, ALfloat ev, ALuint *evidx, ALfloat *evmu)
|
||||
{
|
||||
ev = (F_PI_2 + ev) * (Hrtf->evCount-1) / F_PI;
|
||||
evidx[0] = fastf2u(ev);
|
||||
evidx[1] = minu(evidx[0] + 1, Hrtf->evCount-1);
|
||||
*evmu = ev - evidx[0];
|
||||
}
|
||||
|
||||
/* Calculate the azimuth indices given the polar azimuth in radians. This
|
||||
* will return two indices between 0 and (Hrtf->azCount[ei] - 1) and an
|
||||
* interpolation factor between 0.0 and 1.0.
|
||||
*/
|
||||
static void CalcAzIndices(const struct Hrtf *Hrtf, ALuint evidx, ALfloat az, ALuint *azidx, ALfloat *azmu)
|
||||
{
|
||||
az = (F_PI*2.0f + az) * Hrtf->azCount[evidx] / (F_PI*2.0f);
|
||||
azidx[0] = fastf2u(az) % Hrtf->azCount[evidx];
|
||||
azidx[1] = (azidx[0] + 1) % Hrtf->azCount[evidx];
|
||||
*azmu = az - floorf(az);
|
||||
}
|
||||
|
||||
/* Calculates the normalized HRTF transition factor (delta) from the changes
|
||||
* in gain and listener to source angle between updates. The result is a
|
||||
* normalized delta factor that can be used to calculate moving HRIR stepping
|
||||
* values.
|
||||
*/
|
||||
ALfloat CalcHrtfDelta(ALfloat oldGain, ALfloat newGain, const ALfloat olddir[3], const ALfloat newdir[3])
|
||||
{
|
||||
ALfloat gainChange, angleChange, change;
|
||||
|
||||
// Calculate the normalized dB gain change.
|
||||
newGain = maxf(newGain, 0.0001f);
|
||||
oldGain = maxf(oldGain, 0.0001f);
|
||||
gainChange = fabsf(log10f(newGain / oldGain) / log10f(0.0001f));
|
||||
|
||||
// Calculate the normalized listener to source angle change when there is
|
||||
// enough gain to notice it.
|
||||
angleChange = 0.0f;
|
||||
if(gainChange > 0.0001f || newGain > 0.0001f)
|
||||
{
|
||||
// No angle change when the directions are equal or degenerate (when
|
||||
// both have zero length).
|
||||
if(newdir[0]-olddir[0] || newdir[1]-olddir[1] || newdir[2]-olddir[2])
|
||||
angleChange = acosf(olddir[0]*newdir[0] +
|
||||
olddir[1]*newdir[1] +
|
||||
olddir[2]*newdir[2]) / F_PI;
|
||||
|
||||
}
|
||||
|
||||
// Use the largest of the two changes for the delta factor, and apply a
|
||||
// significance shaping function to it.
|
||||
change = maxf(angleChange * 25.0f, gainChange) * 2.0f;
|
||||
return minf(change, 1.0f);
|
||||
}
|
||||
|
||||
/* Calculates static HRIR coefficients and delays for the given polar
|
||||
* elevation and azimuth in radians. Linear interpolation is used to
|
||||
* increase the apparent resolution of the HRIR data set. The coefficients
|
||||
* are also normalized and attenuated by the specified gain.
|
||||
*/
|
||||
void GetLerpedHrtfCoeffs(const struct Hrtf *Hrtf, ALfloat elevation, ALfloat azimuth, ALfloat gain, ALfloat (*coeffs)[2], ALuint *delays)
|
||||
{
|
||||
ALuint evidx[2], azidx[2];
|
||||
ALuint lidx[4], ridx[4];
|
||||
ALfloat mu[3], blend[4];
|
||||
ALuint i;
|
||||
|
||||
// Claculate elevation indices and interpolation factor.
|
||||
CalcEvIndices(Hrtf, elevation, evidx, &mu[2]);
|
||||
|
||||
// Calculate azimuth indices and interpolation factor for the first
|
||||
// elevation.
|
||||
CalcAzIndices(Hrtf, evidx[0], azimuth, azidx, &mu[0]);
|
||||
|
||||
// Calculate the first set of linear HRIR indices for left and right
|
||||
// channels.
|
||||
lidx[0] = Hrtf->evOffset[evidx[0]] + azidx[0];
|
||||
lidx[1] = Hrtf->evOffset[evidx[0]] + azidx[1];
|
||||
ridx[0] = Hrtf->evOffset[evidx[0]] + ((Hrtf->azCount[evidx[0]]-azidx[0]) % Hrtf->azCount[evidx[0]]);
|
||||
ridx[1] = Hrtf->evOffset[evidx[0]] + ((Hrtf->azCount[evidx[0]]-azidx[1]) % Hrtf->azCount[evidx[0]]);
|
||||
|
||||
// Calculate azimuth indices and interpolation factor for the second
|
||||
// elevation.
|
||||
CalcAzIndices(Hrtf, evidx[1], azimuth, azidx, &mu[1]);
|
||||
|
||||
// Calculate the second set of linear HRIR indices for left and right
|
||||
// channels.
|
||||
lidx[2] = Hrtf->evOffset[evidx[1]] + azidx[0];
|
||||
lidx[3] = Hrtf->evOffset[evidx[1]] + azidx[1];
|
||||
ridx[2] = Hrtf->evOffset[evidx[1]] + ((Hrtf->azCount[evidx[1]]-azidx[0]) % Hrtf->azCount[evidx[1]]);
|
||||
ridx[3] = Hrtf->evOffset[evidx[1]] + ((Hrtf->azCount[evidx[1]]-azidx[1]) % Hrtf->azCount[evidx[1]]);
|
||||
|
||||
/* Calculate 4 blending weights for 2D bilinear interpolation. */
|
||||
blend[0] = (1.0f-mu[0]) * (1.0f-mu[2]);
|
||||
blend[1] = ( mu[0]) * (1.0f-mu[2]);
|
||||
blend[2] = (1.0f-mu[1]) * ( mu[2]);
|
||||
blend[3] = ( mu[1]) * ( mu[2]);
|
||||
|
||||
/* Calculate the HRIR delays using linear interpolation. */
|
||||
delays[0] = fastf2u(Hrtf->delays[lidx[0]]*blend[0] + Hrtf->delays[lidx[1]]*blend[1] +
|
||||
Hrtf->delays[lidx[2]]*blend[2] + Hrtf->delays[lidx[3]]*blend[3] +
|
||||
0.5f) << HRTFDELAY_BITS;
|
||||
delays[1] = fastf2u(Hrtf->delays[ridx[0]]*blend[0] + Hrtf->delays[ridx[1]]*blend[1] +
|
||||
Hrtf->delays[ridx[2]]*blend[2] + Hrtf->delays[ridx[3]]*blend[3] +
|
||||
0.5f) << HRTFDELAY_BITS;
|
||||
|
||||
/* Calculate the sample offsets for the HRIR indices. */
|
||||
lidx[0] *= Hrtf->irSize;
|
||||
lidx[1] *= Hrtf->irSize;
|
||||
lidx[2] *= Hrtf->irSize;
|
||||
lidx[3] *= Hrtf->irSize;
|
||||
ridx[0] *= Hrtf->irSize;
|
||||
ridx[1] *= Hrtf->irSize;
|
||||
ridx[2] *= Hrtf->irSize;
|
||||
ridx[3] *= Hrtf->irSize;
|
||||
|
||||
/* Calculate the normalized and attenuated HRIR coefficients using linear
|
||||
* interpolation when there is enough gain to warrant it. Zero the
|
||||
* coefficients if gain is too low.
|
||||
*/
|
||||
if(gain > 0.0001f)
|
||||
{
|
||||
gain *= 1.0f/32767.0f;
|
||||
for(i = 0;i < Hrtf->irSize;i++)
|
||||
{
|
||||
coeffs[i][0] = (Hrtf->coeffs[lidx[0]+i]*blend[0] +
|
||||
Hrtf->coeffs[lidx[1]+i]*blend[1] +
|
||||
Hrtf->coeffs[lidx[2]+i]*blend[2] +
|
||||
Hrtf->coeffs[lidx[3]+i]*blend[3]) * gain;
|
||||
coeffs[i][1] = (Hrtf->coeffs[ridx[0]+i]*blend[0] +
|
||||
Hrtf->coeffs[ridx[1]+i]*blend[1] +
|
||||
Hrtf->coeffs[ridx[2]+i]*blend[2] +
|
||||
Hrtf->coeffs[ridx[3]+i]*blend[3]) * gain;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for(i = 0;i < Hrtf->irSize;i++)
|
||||
{
|
||||
coeffs[i][0] = 0.0f;
|
||||
coeffs[i][1] = 0.0f;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Calculates the moving HRIR target coefficients, target delays, and
|
||||
* stepping values for the given polar elevation and azimuth in radians.
|
||||
* Linear interpolation is used to increase the apparent resolution of the
|
||||
* HRIR data set. The coefficients are also normalized and attenuated by the
|
||||
* specified gain. Stepping resolution and count is determined using the
|
||||
* given delta factor between 0.0 and 1.0.
|
||||
*/
|
||||
ALuint GetMovingHrtfCoeffs(const struct Hrtf *Hrtf, ALfloat elevation, ALfloat azimuth, ALfloat gain, ALfloat delta, ALint counter, ALfloat (*coeffs)[2], ALuint *delays, ALfloat (*coeffStep)[2], ALint *delayStep)
|
||||
{
|
||||
ALuint evidx[2], azidx[2];
|
||||
ALuint lidx[4], ridx[4];
|
||||
ALfloat mu[3], blend[4];
|
||||
ALfloat left, right;
|
||||
ALfloat step;
|
||||
ALuint i;
|
||||
|
||||
// Claculate elevation indices and interpolation factor.
|
||||
CalcEvIndices(Hrtf, elevation, evidx, &mu[2]);
|
||||
|
||||
// Calculate azimuth indices and interpolation factor for the first
|
||||
// elevation.
|
||||
CalcAzIndices(Hrtf, evidx[0], azimuth, azidx, &mu[0]);
|
||||
|
||||
// Calculate the first set of linear HRIR indices for left and right
|
||||
// channels.
|
||||
lidx[0] = Hrtf->evOffset[evidx[0]] + azidx[0];
|
||||
lidx[1] = Hrtf->evOffset[evidx[0]] + azidx[1];
|
||||
ridx[0] = Hrtf->evOffset[evidx[0]] + ((Hrtf->azCount[evidx[0]]-azidx[0]) % Hrtf->azCount[evidx[0]]);
|
||||
ridx[1] = Hrtf->evOffset[evidx[0]] + ((Hrtf->azCount[evidx[0]]-azidx[1]) % Hrtf->azCount[evidx[0]]);
|
||||
|
||||
// Calculate azimuth indices and interpolation factor for the second
|
||||
// elevation.
|
||||
CalcAzIndices(Hrtf, evidx[1], azimuth, azidx, &mu[1]);
|
||||
|
||||
// Calculate the second set of linear HRIR indices for left and right
|
||||
// channels.
|
||||
lidx[2] = Hrtf->evOffset[evidx[1]] + azidx[0];
|
||||
lidx[3] = Hrtf->evOffset[evidx[1]] + azidx[1];
|
||||
ridx[2] = Hrtf->evOffset[evidx[1]] + ((Hrtf->azCount[evidx[1]]-azidx[0]) % Hrtf->azCount[evidx[1]]);
|
||||
ridx[3] = Hrtf->evOffset[evidx[1]] + ((Hrtf->azCount[evidx[1]]-azidx[1]) % Hrtf->azCount[evidx[1]]);
|
||||
|
||||
// Calculate the stepping parameters.
|
||||
delta = maxf(floorf(delta*(Hrtf->sampleRate*0.015f) + 0.5f), 1.0f);
|
||||
step = 1.0f / delta;
|
||||
|
||||
/* Calculate 4 blending weights for 2D bilinear interpolation. */
|
||||
blend[0] = (1.0f-mu[0]) * (1.0f-mu[2]);
|
||||
blend[1] = ( mu[0]) * (1.0f-mu[2]);
|
||||
blend[2] = (1.0f-mu[1]) * ( mu[2]);
|
||||
blend[3] = ( mu[1]) * ( mu[2]);
|
||||
|
||||
/* Calculate the HRIR delays using linear interpolation. Then calculate
|
||||
* the delay stepping values using the target and previous running
|
||||
* delays.
|
||||
*/
|
||||
left = (ALfloat)(delays[0] - (delayStep[0] * counter));
|
||||
right = (ALfloat)(delays[1] - (delayStep[1] * counter));
|
||||
|
||||
delays[0] = fastf2u(Hrtf->delays[lidx[0]]*blend[0] + Hrtf->delays[lidx[1]]*blend[1] +
|
||||
Hrtf->delays[lidx[2]]*blend[2] + Hrtf->delays[lidx[3]]*blend[3] +
|
||||
0.5f) << HRTFDELAY_BITS;
|
||||
delays[1] = fastf2u(Hrtf->delays[ridx[0]]*blend[0] + Hrtf->delays[ridx[1]]*blend[1] +
|
||||
Hrtf->delays[ridx[2]]*blend[2] + Hrtf->delays[ridx[3]]*blend[3] +
|
||||
0.5f) << HRTFDELAY_BITS;
|
||||
|
||||
delayStep[0] = fastf2i(step * (delays[0] - left));
|
||||
delayStep[1] = fastf2i(step * (delays[1] - right));
|
||||
|
||||
/* Calculate the sample offsets for the HRIR indices. */
|
||||
lidx[0] *= Hrtf->irSize;
|
||||
lidx[1] *= Hrtf->irSize;
|
||||
lidx[2] *= Hrtf->irSize;
|
||||
lidx[3] *= Hrtf->irSize;
|
||||
ridx[0] *= Hrtf->irSize;
|
||||
ridx[1] *= Hrtf->irSize;
|
||||
ridx[2] *= Hrtf->irSize;
|
||||
ridx[3] *= Hrtf->irSize;
|
||||
|
||||
/* Calculate the normalized and attenuated target HRIR coefficients using
|
||||
* linear interpolation when there is enough gain to warrant it. Zero
|
||||
* the target coefficients if gain is too low. Then calculate the
|
||||
* coefficient stepping values using the target and previous running
|
||||
* coefficients.
|
||||
*/
|
||||
if(gain > 0.0001f)
|
||||
{
|
||||
gain *= 1.0f/32767.0f;
|
||||
for(i = 0;i < HRIR_LENGTH;i++)
|
||||
{
|
||||
left = coeffs[i][0] - (coeffStep[i][0] * counter);
|
||||
right = coeffs[i][1] - (coeffStep[i][1] * counter);
|
||||
|
||||
coeffs[i][0] = (Hrtf->coeffs[lidx[0]+i]*blend[0] +
|
||||
Hrtf->coeffs[lidx[1]+i]*blend[1] +
|
||||
Hrtf->coeffs[lidx[2]+i]*blend[2] +
|
||||
Hrtf->coeffs[lidx[3]+i]*blend[3]) * gain;
|
||||
coeffs[i][1] = (Hrtf->coeffs[ridx[0]+i]*blend[0] +
|
||||
Hrtf->coeffs[ridx[1]+i]*blend[1] +
|
||||
Hrtf->coeffs[ridx[2]+i]*blend[2] +
|
||||
Hrtf->coeffs[ridx[3]+i]*blend[3]) * gain;
|
||||
|
||||
coeffStep[i][0] = step * (coeffs[i][0] - left);
|
||||
coeffStep[i][1] = step * (coeffs[i][1] - right);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for(i = 0;i < HRIR_LENGTH;i++)
|
||||
{
|
||||
left = coeffs[i][0] - (coeffStep[i][0] * counter);
|
||||
right = coeffs[i][1] - (coeffStep[i][1] * counter);
|
||||
|
||||
coeffs[i][0] = 0.0f;
|
||||
coeffs[i][1] = 0.0f;
|
||||
|
||||
coeffStep[i][0] = step * -left;
|
||||
coeffStep[i][1] = step * -right;
|
||||
}
|
||||
}
|
||||
|
||||
/* The stepping count is the number of samples necessary for the HRIR to
|
||||
* complete its transition. The mixer will only apply stepping for this
|
||||
* many samples.
|
||||
*/
|
||||
return fastf2u(delta);
|
||||
}
|
||||
|
||||
|
||||
static struct Hrtf *LoadHrtf00(FILE *f, ALuint deviceRate)
|
||||
{
|
||||
const ALubyte maxDelay = SRC_HISTORY_LENGTH-1;
|
||||
struct Hrtf *Hrtf = NULL;
|
||||
ALboolean failed = AL_FALSE;
|
||||
ALuint rate = 0, irCount = 0;
|
||||
ALushort irSize = 0;
|
||||
ALubyte evCount = 0;
|
||||
ALubyte *azCount = NULL;
|
||||
ALushort *evOffset = NULL;
|
||||
ALshort *coeffs = NULL;
|
||||
ALubyte *delays = NULL;
|
||||
ALuint i, j;
|
||||
|
||||
rate = fgetc(f);
|
||||
rate |= fgetc(f)<<8;
|
||||
rate |= fgetc(f)<<16;
|
||||
rate |= fgetc(f)<<24;
|
||||
|
||||
irCount = fgetc(f);
|
||||
irCount |= fgetc(f)<<8;
|
||||
|
||||
irSize = fgetc(f);
|
||||
irSize |= fgetc(f)<<8;
|
||||
|
||||
evCount = fgetc(f);
|
||||
|
||||
if(rate != deviceRate)
|
||||
{
|
||||
ERR("HRIR rate does not match device rate: rate=%d (%d)\n",
|
||||
rate, deviceRate);
|
||||
failed = AL_TRUE;
|
||||
}
|
||||
if(irSize < MIN_IR_SIZE || irSize > MAX_IR_SIZE || (irSize%MOD_IR_SIZE))
|
||||
{
|
||||
ERR("Unsupported HRIR size: irSize=%d (%d to %d by %d)\n",
|
||||
irSize, MIN_IR_SIZE, MAX_IR_SIZE, MOD_IR_SIZE);
|
||||
failed = AL_TRUE;
|
||||
}
|
||||
if(evCount < MIN_EV_COUNT || evCount > MAX_EV_COUNT)
|
||||
{
|
||||
ERR("Unsupported elevation count: evCount=%d (%d to %d)\n",
|
||||
evCount, MIN_EV_COUNT, MAX_EV_COUNT);
|
||||
failed = AL_TRUE;
|
||||
}
|
||||
|
||||
if(failed)
|
||||
return NULL;
|
||||
|
||||
azCount = malloc(sizeof(azCount[0])*evCount);
|
||||
evOffset = malloc(sizeof(evOffset[0])*evCount);
|
||||
if(azCount == NULL || evOffset == NULL)
|
||||
{
|
||||
ERR("Out of memory.\n");
|
||||
failed = AL_TRUE;
|
||||
}
|
||||
|
||||
if(!failed)
|
||||
{
|
||||
evOffset[0] = fgetc(f);
|
||||
evOffset[0] |= fgetc(f)<<8;
|
||||
for(i = 1;i < evCount;i++)
|
||||
{
|
||||
evOffset[i] = fgetc(f);
|
||||
evOffset[i] |= fgetc(f)<<8;
|
||||
if(evOffset[i] <= evOffset[i-1])
|
||||
{
|
||||
ERR("Invalid evOffset: evOffset[%d]=%d (last=%d)\n",
|
||||
i, evOffset[i], evOffset[i-1]);
|
||||
failed = AL_TRUE;
|
||||
}
|
||||
|
||||
azCount[i-1] = evOffset[i] - evOffset[i-1];
|
||||
if(azCount[i-1] < MIN_AZ_COUNT || azCount[i-1] > MAX_AZ_COUNT)
|
||||
{
|
||||
ERR("Unsupported azimuth count: azCount[%d]=%d (%d to %d)\n",
|
||||
i-1, azCount[i-1], MIN_AZ_COUNT, MAX_AZ_COUNT);
|
||||
failed = AL_TRUE;
|
||||
}
|
||||
}
|
||||
if(irCount <= evOffset[i-1])
|
||||
{
|
||||
ERR("Invalid evOffset: evOffset[%d]=%d (irCount=%d)\n",
|
||||
i-1, evOffset[i-1], irCount);
|
||||
failed = AL_TRUE;
|
||||
}
|
||||
|
||||
azCount[i-1] = irCount - evOffset[i-1];
|
||||
if(azCount[i-1] < MIN_AZ_COUNT || azCount[i-1] > MAX_AZ_COUNT)
|
||||
{
|
||||
ERR("Unsupported azimuth count: azCount[%d]=%d (%d to %d)\n",
|
||||
i-1, azCount[i-1], MIN_AZ_COUNT, MAX_AZ_COUNT);
|
||||
failed = AL_TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
if(!failed)
|
||||
{
|
||||
coeffs = malloc(sizeof(coeffs[0])*irSize*irCount);
|
||||
delays = malloc(sizeof(delays[0])*irCount);
|
||||
if(coeffs == NULL || delays == NULL)
|
||||
{
|
||||
ERR("Out of memory.\n");
|
||||
failed = AL_TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
if(!failed)
|
||||
{
|
||||
for(i = 0;i < irCount*irSize;i+=irSize)
|
||||
{
|
||||
for(j = 0;j < irSize;j++)
|
||||
{
|
||||
ALshort coeff;
|
||||
coeff = fgetc(f);
|
||||
coeff |= fgetc(f)<<8;
|
||||
coeffs[i+j] = coeff;
|
||||
}
|
||||
}
|
||||
for(i = 0;i < irCount;i++)
|
||||
{
|
||||
delays[i] = fgetc(f);
|
||||
if(delays[i] > maxDelay)
|
||||
{
|
||||
ERR("Invalid delays[%d]: %d (%d)\n", i, delays[i], maxDelay);
|
||||
failed = AL_TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
if(feof(f))
|
||||
{
|
||||
ERR("Premature end of data\n");
|
||||
failed = AL_TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
if(!failed)
|
||||
{
|
||||
Hrtf = malloc(sizeof(struct Hrtf));
|
||||
if(Hrtf == NULL)
|
||||
{
|
||||
ERR("Out of memory.\n");
|
||||
failed = AL_TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
if(!failed)
|
||||
{
|
||||
Hrtf->sampleRate = rate;
|
||||
Hrtf->irSize = irSize;
|
||||
Hrtf->evCount = evCount;
|
||||
Hrtf->azCount = azCount;
|
||||
Hrtf->evOffset = evOffset;
|
||||
Hrtf->coeffs = coeffs;
|
||||
Hrtf->delays = delays;
|
||||
Hrtf->next = NULL;
|
||||
return Hrtf;
|
||||
}
|
||||
|
||||
free(azCount);
|
||||
free(evOffset);
|
||||
free(coeffs);
|
||||
free(delays);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
static struct Hrtf *LoadHrtf01(FILE *f, ALuint deviceRate)
|
||||
{
|
||||
const ALubyte maxDelay = SRC_HISTORY_LENGTH-1;
|
||||
struct Hrtf *Hrtf = NULL;
|
||||
ALboolean failed = AL_FALSE;
|
||||
ALuint rate = 0, irCount = 0;
|
||||
ALubyte irSize = 0, evCount = 0;
|
||||
ALubyte *azCount = NULL;
|
||||
ALushort *evOffset = NULL;
|
||||
ALshort *coeffs = NULL;
|
||||
ALubyte *delays = NULL;
|
||||
ALuint i, j;
|
||||
|
||||
rate = fgetc(f);
|
||||
rate |= fgetc(f)<<8;
|
||||
rate |= fgetc(f)<<16;
|
||||
rate |= fgetc(f)<<24;
|
||||
|
||||
irSize = fgetc(f);
|
||||
|
||||
evCount = fgetc(f);
|
||||
|
||||
if(rate != deviceRate)
|
||||
{
|
||||
ERR("HRIR rate does not match device rate: rate=%d (%d)\n",
|
||||
rate, deviceRate);
|
||||
failed = AL_TRUE;
|
||||
}
|
||||
if(irSize < MIN_IR_SIZE || irSize > MAX_IR_SIZE || (irSize%MOD_IR_SIZE))
|
||||
{
|
||||
ERR("Unsupported HRIR size: irSize=%d (%d to %d by %d)\n",
|
||||
irSize, MIN_IR_SIZE, MAX_IR_SIZE, MOD_IR_SIZE);
|
||||
failed = AL_TRUE;
|
||||
}
|
||||
if(evCount < MIN_EV_COUNT || evCount > MAX_EV_COUNT)
|
||||
{
|
||||
ERR("Unsupported elevation count: evCount=%d (%d to %d)\n",
|
||||
evCount, MIN_EV_COUNT, MAX_EV_COUNT);
|
||||
failed = AL_TRUE;
|
||||
}
|
||||
|
||||
if(failed)
|
||||
return NULL;
|
||||
|
||||
azCount = malloc(sizeof(azCount[0])*evCount);
|
||||
evOffset = malloc(sizeof(evOffset[0])*evCount);
|
||||
if(azCount == NULL || evOffset == NULL)
|
||||
{
|
||||
ERR("Out of memory.\n");
|
||||
failed = AL_TRUE;
|
||||
}
|
||||
|
||||
if(!failed)
|
||||
{
|
||||
for(i = 0;i < evCount;i++)
|
||||
{
|
||||
azCount[i] = fgetc(f);
|
||||
if(azCount[i] < MIN_AZ_COUNT || azCount[i] > MAX_AZ_COUNT)
|
||||
{
|
||||
ERR("Unsupported azimuth count: azCount[%d]=%d (%d to %d)\n",
|
||||
i, azCount[i], MIN_AZ_COUNT, MAX_AZ_COUNT);
|
||||
failed = AL_TRUE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(!failed)
|
||||
{
|
||||
evOffset[0] = 0;
|
||||
irCount = azCount[0];
|
||||
for(i = 1;i < evCount;i++)
|
||||
{
|
||||
evOffset[i] = evOffset[i-1] + azCount[i-1];
|
||||
irCount += azCount[i];
|
||||
}
|
||||
|
||||
coeffs = malloc(sizeof(coeffs[0])*irSize*irCount);
|
||||
delays = malloc(sizeof(delays[0])*irCount);
|
||||
if(coeffs == NULL || delays == NULL)
|
||||
{
|
||||
ERR("Out of memory.\n");
|
||||
failed = AL_TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
if(!failed)
|
||||
{
|
||||
for(i = 0;i < irCount*irSize;i+=irSize)
|
||||
{
|
||||
for(j = 0;j < irSize;j++)
|
||||
{
|
||||
ALshort coeff;
|
||||
coeff = fgetc(f);
|
||||
coeff |= fgetc(f)<<8;
|
||||
coeffs[i+j] = coeff;
|
||||
}
|
||||
}
|
||||
for(i = 0;i < irCount;i++)
|
||||
{
|
||||
delays[i] = fgetc(f);
|
||||
if(delays[i] > maxDelay)
|
||||
{
|
||||
ERR("Invalid delays[%d]: %d (%d)\n", i, delays[i], maxDelay);
|
||||
failed = AL_TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
if(feof(f))
|
||||
{
|
||||
ERR("Premature end of data\n");
|
||||
failed = AL_TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
if(!failed)
|
||||
{
|
||||
Hrtf = malloc(sizeof(struct Hrtf));
|
||||
if(Hrtf == NULL)
|
||||
{
|
||||
ERR("Out of memory.\n");
|
||||
failed = AL_TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
if(!failed)
|
||||
{
|
||||
Hrtf->sampleRate = rate;
|
||||
Hrtf->irSize = irSize;
|
||||
Hrtf->evCount = evCount;
|
||||
Hrtf->azCount = azCount;
|
||||
Hrtf->evOffset = evOffset;
|
||||
Hrtf->coeffs = coeffs;
|
||||
Hrtf->delays = delays;
|
||||
Hrtf->next = NULL;
|
||||
return Hrtf;
|
||||
}
|
||||
|
||||
free(azCount);
|
||||
free(evOffset);
|
||||
free(coeffs);
|
||||
free(delays);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
static struct Hrtf *LoadHrtf(ALuint deviceRate)
|
||||
{
|
||||
const char *fnamelist = NULL;
|
||||
|
||||
if(!ConfigValueStr(NULL, "hrtf_tables", &fnamelist))
|
||||
return NULL;
|
||||
while(*fnamelist != '\0')
|
||||
{
|
||||
struct Hrtf *Hrtf = NULL;
|
||||
char fname[PATH_MAX];
|
||||
ALchar magic[8];
|
||||
ALuint i;
|
||||
FILE *f;
|
||||
|
||||
while(isspace(*fnamelist) || *fnamelist == ',')
|
||||
fnamelist++;
|
||||
i = 0;
|
||||
while(*fnamelist != '\0' && *fnamelist != ',')
|
||||
{
|
||||
const char *next = strpbrk(fnamelist, "%,");
|
||||
while(fnamelist != next && *fnamelist && i < sizeof(fname))
|
||||
fname[i++] = *(fnamelist++);
|
||||
|
||||
if(!next || *next == ',')
|
||||
break;
|
||||
|
||||
/* *next == '%' */
|
||||
next++;
|
||||
if(*next == 'r')
|
||||
{
|
||||
int wrote = snprintf(&fname[i], sizeof(fname)-i, "%u", deviceRate);
|
||||
i += minu(wrote, sizeof(fname)-i);
|
||||
next++;
|
||||
}
|
||||
else if(*next == '%')
|
||||
{
|
||||
if(i < sizeof(fname))
|
||||
fname[i++] = '%';
|
||||
next++;
|
||||
}
|
||||
else
|
||||
ERR("Invalid marker '%%%c'\n", *next);
|
||||
fnamelist = next;
|
||||
}
|
||||
i = minu(i, sizeof(fname)-1);
|
||||
fname[i] = '\0';
|
||||
while(i > 0 && isspace(fname[i-1]))
|
||||
i--;
|
||||
fname[i] = '\0';
|
||||
|
||||
if(fname[0] == '\0')
|
||||
continue;
|
||||
|
||||
TRACE("Loading %s...\n", fname);
|
||||
f = fopen(fname, "rb");
|
||||
if(f == NULL)
|
||||
{
|
||||
ERR("Could not open %s\n", fname);
|
||||
continue;
|
||||
}
|
||||
|
||||
if(fread(magic, 1, sizeof(magic), f) != sizeof(magic))
|
||||
ERR("Failed to read header from %s\n", fname);
|
||||
else
|
||||
{
|
||||
if(memcmp(magic, magicMarker00, sizeof(magicMarker00)) == 0)
|
||||
{
|
||||
TRACE("Detected data set format v0\n");
|
||||
Hrtf = LoadHrtf00(f, deviceRate);
|
||||
}
|
||||
else if(memcmp(magic, magicMarker01, sizeof(magicMarker01)) == 0)
|
||||
{
|
||||
TRACE("Detected data set format v1\n");
|
||||
Hrtf = LoadHrtf01(f, deviceRate);
|
||||
}
|
||||
else
|
||||
ERR("Invalid header in %s: \"%.8s\"\n", fname, magic);
|
||||
}
|
||||
|
||||
fclose(f);
|
||||
f = NULL;
|
||||
|
||||
if(Hrtf)
|
||||
{
|
||||
Hrtf->next = LoadedHrtfs;
|
||||
LoadedHrtfs = Hrtf;
|
||||
TRACE("Loaded HRTF support for format: %s %uhz\n",
|
||||
DevFmtChannelsString(DevFmtStereo), Hrtf->sampleRate);
|
||||
return Hrtf;
|
||||
}
|
||||
|
||||
ERR("Failed to load %s\n", fname);
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
const struct Hrtf *GetHrtf(ALCdevice *device)
|
||||
{
|
||||
if(device->FmtChans == DevFmtStereo)
|
||||
{
|
||||
struct Hrtf *Hrtf = LoadedHrtfs;
|
||||
while(Hrtf != NULL)
|
||||
{
|
||||
if(device->Frequency == Hrtf->sampleRate)
|
||||
return Hrtf;
|
||||
Hrtf = Hrtf->next;
|
||||
}
|
||||
|
||||
Hrtf = LoadHrtf(device->Frequency);
|
||||
if(Hrtf != NULL)
|
||||
return Hrtf;
|
||||
|
||||
if(device->Frequency == DefaultHrtf.sampleRate)
|
||||
return &DefaultHrtf;
|
||||
}
|
||||
ERR("Incompatible format: %s %uhz\n",
|
||||
DevFmtChannelsString(device->FmtChans), device->Frequency);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void FreeHrtfs(void)
|
||||
{
|
||||
struct Hrtf *Hrtf = NULL;
|
||||
|
||||
while((Hrtf=LoadedHrtfs) != NULL)
|
||||
{
|
||||
LoadedHrtfs = Hrtf->next;
|
||||
free((void*)Hrtf->azCount);
|
||||
free((void*)Hrtf->evOffset);
|
||||
free((void*)Hrtf->coeffs);
|
||||
free((void*)Hrtf->delays);
|
||||
free(Hrtf);
|
||||
}
|
||||
}
|
||||
|
||||
ALuint GetHrtfIrSize (const struct Hrtf *Hrtf)
|
||||
{
|
||||
return Hrtf->irSize;
|
||||
}
|
||||
@@ -0,0 +1,848 @@
|
||||
/* Elevation metrics */
|
||||
static const ALubyte defaultAzCount[19] = { 1, 12, 24, 36, 45, 56, 60, 72, 72, 72, 72, 72, 60, 56, 45, 36, 24, 12, 1, };
|
||||
static const ALushort defaultEvOffset[19] = { 0, 1, 13, 37, 73, 118, 174, 234, 306, 378, 450, 522, 594, 654, 710, 755, 791, 815, 827, };
|
||||
|
||||
/* HRIR Coefficients */
|
||||
static const ALshort defaultCoeffs[26496] =
|
||||
{
|
||||
+6117, +8354, +3531, +2903, +1118, +342, +874, -822, -2447, -1309, +579, -133, -617, -1093, -998, -416, -244, -202, -84, -134, -375, -200, -416, -331, -408, -614, -489, -332, -207, -97, -7, -145,
|
||||
+6958, +8678, +3013, +3274, +1145, +25, +847, -771, -2501, -1666, +534, +86, -597, -917, -967, -916, -367, -80, -198, -215, -475, -312, -442, -372, -399, -554, -517, -249, -103, -75, -5, -176,
|
||||
+6349, +8083, +2935, +2854, +1109, +344, +851, -891, -2351, -1252, +506, -191, -559, -861, -745, -485, -327, -77, -17, -172, -405, -189, -402, -350, -459, -599, -449, -315, -184, -77, +13, -134,
|
||||
+5910, +7494, +2698, +2625, +992, +373, +884, -825, -2197, -962, +698, -127, -425, -759, -697, -286, -213, -171, -64, -127, -336, -131, -355, -271, -368, -553, -428, -299, -179, -74, +4, -137,
|
||||
+5808, +7380, +2660, +2585, +1001, +453, +998, -698, -2078, -854, +773, -100, -470, -857, -730, -241, -185, -179, -63, -114, -325, -112, -322, -220, -300, -507, -404, -297, -216, -122, -35, -168,
|
||||
+5957, +7591, +2687, +2503, +871, +340, +913, -821, -2282, -1053, +775, -16, -459, -904, -784, -240, -114, -100, -12, -59, -285, -105, -334, -253, -340, -532, -400, -251, -127, -17, +33, -156,
|
||||
+6515, +8209, +2752, +2639, +892, +326, +895, -1074, -2683, -1313, +854, -53, -682, -1135, -939, -316, -155, -153, -32, -64, -346, -124, -339, -249, -345, -543, -400, -232, -129, -39, +38, -120,
|
||||
+6887, +8888, +3060, +2770, +926, +146, +833, -1245, -2800, -1317, +584, -231, -619, -1119, -983, -413, -244, -71, -9, -143, -405, -183, -399, -307, -420, -595, -439, -302, -153, -55, +34, -129,
|
||||
+7340, +9090, +2964, +3130, +1162, +115, +612, -1577, -2702, -692, +458, -1019, -864, -943, -587, -190, -434, -226, +41, -162, -398, -144, -463, -353, -533, -708, -464, -374, -270, -103, +2, -187,
|
||||
+8348, +9865, +2233, +2503, +594, +154, +1277, -1477, -3002, -433, +1280, -991, -1387, -1385, -643, +20, -514, -498, -16, -150, -545, -145, -486, -329, -539, -846, -509, -326, -250, -110, +9, -211,
|
||||
+8668, +10241, +2446, +2335, +160, +133, +1408, -1244, -3403, -895, +1742, -269, -1341, -2123, -1100, +207, -94, -571, -238, -198, -607, -211, -581, -326, -492, -792, -539, -293, -202, -119, -28, -265,
|
||||
+8261, +10052, +3261, +2775, +344, +65, +1000, -1138, -3661, -1615, +1337, +126, -290, -1970, -1899, -55, +143, -202, -175, -248, -492, -207, -591, -284, -495, -901, -578, -409, -197, -51, +38, -151,
|
||||
+7749, +9628, +3084, +3049, +870, +16, +727, -1159, -2880, -1819, +969, +83, -717, -1031, -1759, -1055, -39, -9, -26, -31, -379, -324, -646, -479, -344, -651, -608, -341, -196, -48, +22, -160,
|
||||
+7872, +8889, +2424, +3846, +1113, -405, +870, -636, -2562, -2175, +535, +438, -627, -691, -988, -1594, -378, +123, -383, -287, -574, -435, -436, -421, -370, -475, -575, -138, +9, -79, -10, -210,
|
||||
+7007, +8290, +2692, +3507, +1037, -125, +838, -876, -2265, -1597, +225, -49, -510, -580, -573, -987, -677, +32, +42, -236, -535, -281, -374, -349, -433, -522, -408, -257, -182, -133, +15, -132,
|
||||
+6475, +7694, +2419, +2913, +1152, +342, +794, -920, -2186, -1265, +352, -196, -457, -569, -494, -665, -413, +113, +33, -239, -428, -173, -379, -384, -517, -559, -408, -308, -159, -59, +31, -118,
|
||||
+5981, +7105, +2165, +2692, +1134, +347, +767, -876, -2030, -957, +421, -294, -318, -441, -466, -416, -281, -39, -27, -194, -378, -156, -345, -274, -384, -498, -440, -344, -158, -51, +21, -134,
|
||||
+5468, +6465, +2050, +2460, +952, +446, +858, -776, -1849, -646, +711, -106, -171, -377, -412, -225, -208, -139, -49, -122, -280, -59, -288, -217, -330, -482, -372, -276, -153, -54, +11, -123,
|
||||
+5247, +6086, +1760, +2189, +842, +506, +1054, -433, -1470, -298, +965, +30, -189, -498, -477, -163, -126, -106, -24, -94, -283, -72, -247, -143, -266, -434, -302, -196, -110, -68, -52, -213,
|
||||
+5232, +6232, +1996, +2383, +983, +625, +1098, -519, -1614, -432, +848, -66, -286, -585, -461, -110, -157, -165, -46, -92, -261, -20, -217, -109, -190, -394, -333, -281, -239, -151, -66, -182,
|
||||
+5323, +6297, +1900, +2226, +867, +582, +1114, -514, -1700, -507, +886, -53, -362, -695, -545, -42, +42, -2, +24, -89, -290, -90, -302, -188, -238, -341, -202, -173, -185, -163, -115, -218,
|
||||
+5574, +6674, +1997, +2183, +707, +407, +936, -776, -2047, -829, +914, +130, -285, -696, -573, -93, +9, -5, +50, +20, -186, -16, -247, -182, -271, -441, -315, -175, -47, +63, +58, -176,
|
||||
+6045, +7217, +2109, +2333, +722, +394, +912, -1008, -2484, -1201, +940, +97, -533, -929, -717, -112, +69, +18, +107, +96, -204, -31, -262, -175, -230, -397, -254, -106, -72, -21, +17, -112,
|
||||
+6856, +7935, +1962, +2469, +717, +365, +900, -1353, -2894, -1309, +1170, +26, -784, -1168, -861, -220, -61, -113, +16, +18, -323, -43, -253, -171, -282, -468, -311, -130, -56, +10, +78, -94,
|
||||
+7514, +8789, +1982, +2483, +712, +262, +907, -1695, -3191, -1325, +1153, -23, -806, -1333, -975, -279, -115, -59, -35, -42, -373, -130, -392, -273, -384, -542, -334, -150, -38, +4, +93, -104,
|
||||
+7708, +9393, +2471, +2673, +752, -59, +807, -1726, -3115, -1282, +555, -307, -586, -1146, -966, -429, -241, +103, +48, -175, -435, -160, -372, -287, -438, -565, -385, -281, -93, -15, +72, -115,
|
||||
+7961, +9595, +2700, +3173, +1089, -199, +393, -2045, -2982, -748, +119, -1067, -577, -787, -541, -413, -602, -36, +144, -149, -336, -111, -417, -324, -553, -659, -425, -410, -226, -58, +56, -137,
|
||||
+8750, +9725, +2189, +3527, +1193, -202, +307, -2424, -2793, +130, +87, -2091, -927, -659, -104, -33, -745, -205, +211, -231, -414, -73, -531, -374, -686, -789, -410, -438, -340, -94, +17, -238,
|
||||
+9887, +10729, +1149, +2712, +812, -159, +1171, -2374, -3238, +573, +900, -2331, -1559, -881, +10, +282, -825, -483, +230, -178, -567, -74, -569, -393, -734, -962, -410, -384, -393, -161, +71, -197,
|
||||
+11064, +11221, +279, +2282, +77, +57, +1829, -2384, -3518, +811, +1905, -2262, -2145, -1529, -99, +470, -985, -810, +158, -183, -755, -35, -580, -314, -703, -1105, -476, -311, -308, -116, +33, -294,
|
||||
+11675, +11698, +209, +1859, -553, +242, +2236, -2105, -4055, +456, +2775, -1639, -2377, -2493, -525, +885, -700, -1033, -74, -269, -767, -30, -730, -335, -644, -1070, -436, -206, -262, -87, -13, -377,
|
||||
+11801, +11992, +657, +1830, -875, +135, +2141, -1883, -4508, -144, +3105, -728, -2249, -3247, -939, +1040, -70, -1098, -336, -229, -882, -166, -780, -279, -597, -994, -559, -229, -208, -150, -49, -410,
|
||||
+11441, +12041, +1632, +2283, -957, -39, +1816, -1840, -4880, -918, +2879, +121, -1146, -3647, -1711, +1051, +438, -745, -603, -262, -776, -209, -700, -151, -609, -1078, -625, -402, -194, -201, -9, -262,
|
||||
+10865, +11676, +2584, +2613, -586, -83, +1224, -1524, -5125, -1724, +2382, +303, +58, -3199, -2831, +663, +561, -315, -300, -369, -601, -190, -808, -177, -617, -1246, -617, -484, -161, +7, +81, -166,
|
||||
+10191, +11218, +2753, +3225, -135, -314, +1139, -1492, -4741, -2381, +2120, +202, +83, -1978, -3635, -327, +757, +52, -23, -340, -548, -69, -879, -641, -441, -1126, -641, -329, -170, +77, +67, -175,
|
||||
+9689, +10846, +2307, +3298, +545, -344, +602, -1494, -3324, -2412, +1584, +308, -905, -920, -2772, -1685, +423, +196, -11, +88, -409, -493, -902, -608, -212, -710, -760, -321, -179, +12, +47, -183,
|
||||
+8953, +9908, +2218, +3607, +920, -373, +599, -1197, -2905, -2314, +1261, +665, -1096, -819, -1580, -2014, -168, +187, -326, -97, -344, -334, -636, -572, -272, -489, -771, -288, -106, -59, +97, -199,
|
||||
+8864, +8963, +1784, +4657, +969, -956, +982, -415, -2657, -2862, +633, +942, -750, -396, -1083, -2461, -216, +391, -668, -329, -673, -573, -389, -489, -318, -379, -677, +16, +122, -114, -18, -247,
|
||||
+7756, +8469, +2432, +4304, +831, -834, +867, -757, -2207, -2102, -12, +321, -466, -174, -519, -1837, -871, +255, +23, -250, -677, -423, -326, -339, -330, -413, -490, -195, -73, -162, -2, -152,
|
||||
+7061, +7757, +2298, +3660, +972, -50, +816, -871, -2023, -1762, +29, +39, -419, -270, -323, -1264, -738, +345, +74, -339, -535, -233, -317, -423, -530, -487, -350, -279, -220, -117, +68, -96,
|
||||
+6469, +7209, +2035, +3061, +1233, +321, +690, -887, -1952, -1381, +126, -112, -325, -222, -261, -975, -473, +378, +46, -334, -435, -156, -344, -439, -577, -492, -370, -312, -132, -41, +48, -98,
|
||||
+5924, +6587, +1791, +2840, +1306, +325, +630, -832, -1787, -1021, +168, -250, -169, -97, -250, -687, -289, +202, -37, -279, -361, -130, -348, -361, -448, -399, -386, -361, -133, -16, +50, -129,
|
||||
+5282, +6011, +1719, +2545, +1130, +445, +720, -784, -1642, -749, +308, -187, +39, -21, -232, -423, -260, +27, -35, -215, -317, -45, -205, -222, -390, -439, -388, -320, -115, -45, +11, -94,
|
||||
+4741, +5315, +1665, +2368, +986, +543, +781, -655, -1403, -392, +608, -36, +147, +49, -163, -239, -215, -100, -40, -117, -205, +8, -213, -171, -294, -397, -329, -264, -127, -36, +13, -103,
|
||||
+4473, +4913, +1415, +2018, +802, +585, +981, -314, -1070, -10, +964, +194, +186, -38, -233, -201, -159, -68, +40, -54, -215, -5, -156, -100, -249, -363, -242, -160, -67, -14, -33, -215,
|
||||
+4287, +4651, +1225, +2028, +1002, +772, +1151, -74, -767, +174, +960, +71, -57, -266, -220, -24, -57, -86, -63, -101, -197, +12, -123, -8, -137, -308, -225, -169, -123, -121, -128, -237,
|
||||
+4337, +4965, +1624, +2246, +1058, +843, +1155, -266, -1056, -75, +799, +3, -60, -285, -202, -30, -153, -156, -30, -66, -178, +71, -100, -2, -76, -278, -279, -283, -274, -184, -98, -187,
|
||||
+4443, +5025, +1531, +2119, +997, +856, +1205, -260, -1169, -213, +764, -10, -150, -366, -219, +89, +76, -16, -38, -108, -204, -23, -212, -56, -66, -154, -135, -246, -290, -240, -153, -192,
|
||||
+4604, +5187, +1421, +1877, +708, +663, +1129, -291, -1278, -255, +968, +170, -109, -537, -478, +41, +175, +171, +207, -3, -219, -11, -242, -189, -190, -256, -119, -13, -31, -100, -174, -309,
|
||||
+4923, +5652, +1529, +1902, +624, +528, +924, -671, -1743, -664, +996, +326, -100, -476, -372, +25, +128, +85, +100, +106, -73, +61, -152, -121, -199, -342, -237, -104, +32, +141, +70, -204,
|
||||
+5421, +6220, +1615, +2041, +613, +476, +868, -945, -2209, -1062, +1028, +282, -361, -678, -462, +90, +247, +119, +166, +124, -141, +83, -164, -99, -131, -291, -197, -34, +4, +4, +72, -42,
|
||||
+6190, +6818, +1507, +2236, +597, +518, +893, -1240, -2699, -1316, +1269, +222, -676, -957, -667, -54, +151, +26, +170, +185, -160, +80, -150, -125, -158, -266, -176, +4, -12, -12, +35, -111,
|
||||
+7121, +7541, +1201, +2394, +583, +455, +869, -1653, -3075, -1304, +1541, +95, -937, -1178, -764, -132, +36, -84, +64, +109, -308, +44, -155, -103, -220, -385, -224, -28, +7, +54, +114, -67,
|
||||
+7954, +8408, +983, +2438, +632, +359, +872, -2062, -3411, -1245, +1676, +31, -1048, -1363, -832, -150, -48, -120, +14, +94, -364, -58, -298, -170, -314, -457, -245, -56, +16, +70, +176, -53,
|
||||
+8426, +9277, +1223, +2430, +532, +133, +944, -2316, -3533, -1292, +1244, -43, -818, -1449, -1029, -259, -53, +135, -32, -56, -402, -136, -404, -282, -407, -503, -267, -114, +46, +41, +136, -109,
|
||||
+8583, +9860, +1762, +2634, +598, -282, +801, -2272, -3373, -1211, +481, -346, -524, -1183, -947, -470, -228, +324, +74, -228, -460, -132, -337, -273, -462, -518, -331, -270, -26, +19, +110, -100,
|
||||
+8789, +10123, +2143, +3154, +907, -539, +350, -2551, -3191, -653, -134, -1144, -348, -706, -562, -559, -647, +213, +190, -170, -308, -125, -412, -293, -550, -593, -367, -441, -161, -3, +111, -113,
|
||||
+9368, +10135, +1939, +3756, +1190, -650, -93, -2909, -2955, +75, -583, -2117, -371, -455, -4, -431, -1040, +118, +327, -275, -298, -31, -480, -340, -761, -730, -381, -524, -283, -44, +42, -215,
|
||||
+10370, +10210, +1204, +4156, +1175, -623, -28, -3363, -2672, +1145, -623, -3309, -728, -270, +428, +27, -1178, -99, +420, -357, -415, +13, -626, -389, -869, -847, -326, -533, -414, -65, +33, -301,
|
||||
+11635, +11075, -31, +3531, +952, -550, +724, -3443, -3032, +1791, +130, -3849, -1409, -370, +688, +391, -1323, -332, +504, -391, -598, +96, -680, -457, -950, -1002, -305, -479, -469, -136, +71, -286,
|
||||
+13207, +11905, -1547, +2772, +301, -274, +1873, -3587, -3556, +2285, +1234, -3973, -2188, -835, +809, +672, -1631, -769, +602, -241, -847, +83, -674, -374, -941, -1208, -342, -448, -473, -101, +134, -318,
|
||||
+14337, +12287, -2399, +2422, -469, +62, +2531, -3616, -3929, +2464, +2354, -3991, -2785, -1503, +623, +891, -1697, -1088, +457, -261, -1009, +151, -717, -276, -913, -1388, -372, -300, -384, -112, +67, -401,
|
||||
+15087, +12820, -2744, +1910, -1184, +425, +3120, -3448, -4563, +2187, +3466, -3489, -3173, -2589, +266, +1446, -1532, -1382, +191, -327, -1016, +193, -847, -301, -888, -1367, -296, -177, -336, -114, +20, -474,
|
||||
+15581, +13124, -2434, +1591, -1676, +521, +3195, -3036, -5227, +1724, +4250, -2658, -3404, -3573, -56, +1861, -986, -1649, +4, -355, -1041, +91, -1052, -239, -767, -1287, -362, -121, -296, -58, -65, -569,
|
||||
+15601, +13452, -1914, +1563, -2007, +399, +3052, -2823, -5735, +1036, +4617, -1613, -3294, -4431, -451, +2051, -245, -1777, -331, -235, -1215, -48, -1032, -173, -736, -1221, -537, -142, -232, -189, -69, -580,
|
||||
+15203, +13689, -870, +1955, -2244, +197, +2769, -2807, -6122, +172, +4587, -487, -2272, -5183, -1225, +2226, +446, -1489, -791, -175, -1171, -107, -880, -30, -790, -1309, -587, -320, -186, -316, -13, -442,
|
||||
+14648, +13594, +409, +2248, -2137, -16, +2270, -2431, -6673, -665, +4167, +189, -766, -5403, -2316, +2230, +741, -1027, -813, -342, -840, -164, -978, +109, -745, -1474, -642, -547, -154, -159, +47, -247,
|
||||
+13996, +13109, +1461, +2499, -1685, -37, +1524, -2013, -6863, -1546, +3712, +317, +445, -4840, -3714, +1807, +920, -566, -438, -485, -703, -148, -1075, +6, -791, -1647, -584, -567, -97, +72, +120, -190,
|
||||
+13165, +12534, +1976, +3362, -1471, -314, +1381, -1961, -6484, -2520, +3399, +361, +831, -3679, -5026, +938, +1344, -192, -237, -452, -597, -58, -1183, -507, -582, -1548, -641, -480, -68, +246, +63, -219,
|
||||
+12626, +12250, +1611, +3690, -681, -941, +1250, -1619, -5566, -2944, +3036, +177, +25, -1933, -5154, -665, +1470, +164, +107, -276, -664, -178, -1249, -762, -296, -1315, -631, -232, -234, +180, +66, -251,
|
||||
+11980, +11934, +1167, +3735, +109, -727, +510, -1829, -3781, -3108, +2485, +496, -1203, -728, -4093, -2241, +1182, +347, -49, +233, -470, -711, -1173, -711, -7, -812, -944, -259, -161, +83, +61, -212,
|
||||
+11247, +11010, +1120, +4114, +574, -764, +386, -1687, -3259, -2815, +2128, +825, -1544, -509, -2722, -2986, +467, +444, -350, +190, -276, -570, -1067, -700, +132, -512, -1156, -281, -35, -10, +123, -207,
|
||||
+10116, +9947, +1402, +4469, +759, -942, +664, -954, -2962, -3136, +1495, +1323, -1375, -529, -1640, -2951, +60, +455, -723, -188, -423, -428, -490, -651, -326, -390, -839, -121, -11, -87, +128, -262,
|
||||
+9934, +8876, +1128, +5737, +644, -1620, +1223, -109, -2816, -3751, +890, +1596, -1024, +3, -1280, -3531, +194, +690, -1086, -313, -780, -731, -285, -592, -233, -265, -834, +227, +227, -185, -20, -287,
|
||||
+8502, +8500, +2204, +5212, +430, -1605, +1028, -561, -2155, -2773, -185, +874, -495, +321, -570, -2903, -846, +586, -74, -234, -828, -571, -225, -357, -205, -310, -640, -115, +58, -204, -18, -162,
|
||||
+7584, +7772, +2171, +4547, +704, -725, +925, -716, -1861, -2401, -267, +505, -407, +183, -244, -2138, -927, +680, +60, -459, -671, -326, -222, -451, -469, -353, -358, -211, -203, -191, +84, -98,
|
||||
+6877, +7100, +2027, +3726, +1015, +37, +675, -791, -1748, -2003, -196, +244, -318, +111, -88, -1694, -708, +748, +20, -457, -485, -226, -270, -512, -629, -427, -353, -293, -167, -97, +74, -60,
|
||||
+6094, +6516, +1758, +3125, +1461, +313, +506, -750, -1620, -1508, -142, +48, -126, +224, -68, -1338, -382, +704, -7, -454, -398, -106, -300, -528, -626, -363, -337, -340, -80, +0, +68, -81,
|
||||
+5474, +5821, +1573, +2970, +1494, +257, +449, -672, -1419, -1123, -157, -119, +81, +343, -71, -994, -247, +423, -94, -356, -314, -117, -307, -403, -455, -271, -389, -398, -91, +12, +63, -119,
|
||||
+4706, +5219, +1556, +2650, +1342, +394, +527, -623, -1238, -816, -65, -106, +329, +424, -62, -677, -264, +193, -57, -276, -283, -47, -151, -234, -379, -329, -417, -360, -71, -27, +20, -78,
|
||||
+3969, +4463, +1642, +2395, +1176, +599, +584, -518, -1032, -470, +216, +31, +488, +473, -5, -409, -215, +23, -78, -181, -137, +68, -136, -185, -309, -316, -333, -291, -98, -38, +10, -54,
|
||||
+3424, +3827, +1536, +2086, +1002, +678, +738, -333, -681, +35, +605, +269, +533, +528, +71, -284, -241, -104, +39, -20, -139, +38, -65, -74, -225, -293, -257, -229, -78, +5, +12, -102,
|
||||
+3209, +3445, +1231, +1747, +899, +784, +1000, +168, -305, +345, +880, +396, +496, +306, -68, -218, -102, -1, +55, -36, -135, +45, -28, -19, -180, -238, -160, -103, -27, -22, -94, -255,
|
||||
+2989, +3191, +1074, +1836, +1186, +989, +1156, +381, -8, +502, +823, +223, +193, +66, +7, +5, -16, -56, -80, -81, -98, +68, +12, +88, -46, -191, -160, -138, -110, -149, -188, -250,
|
||||
+3027, +3528, +1478, +2058, +1276, +1085, +1144, +149, -311, +281, +686, +149, +146, +19, +50, +25, -119, -132, -55, -57, -69, +143, +32, +105, +37, -167, -229, -266, -280, -209, -151, -192,
|
||||
+3214, +3748, +1601, +2025, +1190, +1116, +1202, +89, -552, -87, +478, +220, +213, +9, +55, +81, -6, -61, -71, -93, -61, +81, -92, +76, +154, -10, -220, -365, -342, -251, -170, -159,
|
||||
+3266, +3741, +1347, +1791, +1078, +1077, +1224, +91, -623, +51, +737, +114, -29, -162, -63, +235, +299, +125, +20, -78, -150, -17, -140, -29, -21, +31, +66, -141, -296, -306, -239, -221,
|
||||
+3541, +4062, +1288, +1550, +718, +829, +1077, -44, -837, -142, +945, +448, +111, -311, -297, +101, +259, +279, +274, +70, -83, +51, -163, -131, -124, -170, -40, +66, +53, -44, -202, -351,
|
||||
+3954, +4589, +1351, +1593, +636, +691, +854, -482, -1382, -587, +1032, +601, +79, -242, -184, +108, +254, +168, +138, +202, +51, +122, -43, -74, -123, -230, -173, -35, +112, +219, +65, -237,
|
||||
+4535, +5212, +1390, +1740, +598, +607, +776, -814, -1908, -1025, +1099, +545, -214, -426, -239, +239, +413, +193, +207, +182, -47, +183, -57, -40, -30, -175, -148, +40, +73, +37, +118, +7,
|
||||
+5318, +5785, +1269, +1968, +575, +658, +805, -1127, -2442, -1307, +1372, +466, -591, -725, -443, +119, +395, +164, +270, +354, -56, +110, -69, -55, -25, -139, -51, +109, +11, +15, +19, -56,
|
||||
+6436, +6460, +882, +2236, +497, +666, +802, -1573, -2941, -1397, +1743, +286, -941, -976, -603, -18, +243, -4, +204, +282, -184, +170, -29, -57, -91, -187, -111, +112, +41, +27, +68, -96,
|
||||
+7585, +7281, +373, +2458, +491, +542, +790, -2104, -3319, -1286, +2043, +126, -1200, -1227, -664, -50, +85, -70, +93, +172, -322, +133, -69, -86, -185, -297, -168, +53, +66, +96, +196, +7,
|
||||
+8554, +8204, +13, +2518, +545, +433, +808, -2585, -3651, -1161, +2167, +23, -1301, -1412, -719, -73, +18, -111, +45, +202, -388, -7, -242, -122, -287, -383, -162, +38, +78, +115, +239, -27,
|
||||
+9212, +9220, +103, +2448, +407, +223, +921, -2981, -3805, -1200, +1719, +26, -1055, -1626, -929, -188, +43, +226, -94, +18, -406, -89, -400, -275, -396, -440, -171, +13, +140, +43, +175, -97,
|
||||
+9425, +9997, +611, +2554, +412, -263, +952, -2951, -3684, -1187, +857, -167, -621, -1410, -1053, -347, -65, +452, -3, -165, -453, -143, -340, -269, -451, -441, -242, -198, +101, +82, +181, -110,
|
||||
+9602, +10483, +1219, +2947, +590, -759, +563, -2991, -3446, -797, -98, -815, -218, -921, -768, -633, -444, +563, +104, -246, -350, -155, -369, -240, -521, -488, -298, -401, -10, +50, +144, -115,
|
||||
+9910, +10681, +1487, +3547, +923, -1024, +61, -3330, -3146, -137, -870, -1590, +8, -449, -298, -772, -939, +485, +312, -243, -240, -78, -399, -324, -669, -567, -332, -547, -156, +25, +160, -93,
|
||||
+10699, +10561, +1144, +4345, +1148, -1198, -465, -3692, -2804, +756, -1507, -2809, +121, -169, +369, -651, -1433, +435, +473, -418, -220, +23, -526, -346, -932, -715, -318, -648, -289, -5, +58, -250,
|
||||
+11865, +10458, +321, +5013, +1084, -1187, -415, -4235, -2391, +1999, -1758, -4266, -88, +147, +902, -193, -1705, +234, +619, -537, -297, +92, -743, -384, -1023, -815, -255, -684, -426, -12, +35, -330,
|
||||
+13346, +11005, -1112, +4810, +949, -1079, +138, -4587, -2456, +3025, -1295, -5300, -712, +202, +1270, +293, -1889, -46, +762, -642, -552, +226, -817, -466, -1180, -995, -171, -630, -552, -62, +74, -399,
|
||||
+14971, +12208, -3034, +3816, +594, -863, +1619, -4784, -3319, +3684, -109, -5706, -1550, +27, +1400, +652, -2108, -458, +869, -483, -776, +220, -858, -433, -1201, -1254, -117, -550, -640, -140, +204, -318,
|
||||
+16995, +12596, -4875, +3443, -244, -334, +2668, -5173, -3649, +4366, +1153, -6044, -2514, -559, +1728, +927, -2652, -901, +1093, -410, -1143, +329, -841, -335, -1196, -1458, -195, -525, -564, -33, +194, -462,
|
||||
+18241, +12894, -5826, +3138, -1130, +187, +3380, -5255, -4143, +4561, +2499, -6195, -3183, -1309, +1509, +1233, -2676, -1266, +894, -425, -1299, +432, -922, -204, -1176, -1686, -183, -313, -482, -86, +105, -535,
|
||||
+19257, +13367, -6379, +2592, -1984, +792, +4070, -5179, -4919, +4384, +3882, -5784, -3709, -2594, +1250, +1947, -2577, -1645, +617, -476, -1302, +491, -1070, -197, -1169, -1676, -76, -162, -446, -100, +47, -614,
|
||||
+19926, +13767, -6244, +2039, -2577, +1096, +4300, -4713, -5817, +3943, +5112, -5041, -4213, -3795, +981, +2627, -2147, -2070, +431, -519, -1281, +436, -1355, -148, -989, -1627, -104, -51, -433, -15, -50, -735,
|
||||
+20240, +14125, -5799, +1784, -3007, +1064, +4265, -4313, -6590, +3386, +5836, -3972, -4474, -4840, +741, +2976, -1373, -2410, +167, -416, -1413, +247, -1435, -24, -966, -1480, -291, -55, -313, -65, -145, -781,
|
||||
+20015, +14601, -5023, +1828, -3407, +908, +4058, -4144, -7140, +2450, +6274, -2630, -4153, -5964, +216, +3298, -453, -2534, -345, -178, -1641, +157, -1311, +64, -954, -1504, -457, -98, -260, -285, -55, -762,
|
||||
+19554, +14863, -3770, +2150, -3733, +724, +3709, -4072, -7621, +1495, +6312, -1303, -3056, -6981, -603, +3594, +321, -2274, -920, -58, -1568, +72, -1120, +198, -1037, -1588, -525, -300, -179, -434, +24, -584,
|
||||
+18917, +14814, -2183, +2351, -3715, +455, +3162, -3571, -8351, +569, +5938, -361, -1346, -7547, -1834, +3783, +700, -1769, -1070, -238, -1132, -62, -1211, +391, -1003, -1782, -585, -567, -111, -272, +77, -349,
|
||||
+18106, +14727, -945, +2225, -3047, +302, +2302, -2969, -8873, -290, +5489, -62, +243, -7348, -3434, +3665, +911, -1246, -777, -513, -915, -51, -1324, +362, -1049, -1967, -506, -762, +16, -24, +82, -173,
|
||||
+17254, +13805, +460, +2982, -2958, +154, +1644, -2479, -8779, -1643, +5145, +181, +1378, -6455, -5404, +3105, +1393, -741, -423, -612, -704, -72, -1484, +78, -955, -2125, -465, -626, +16, +278, +142, -257,
|
||||
+16265, +13474, +690, +3849, -2566, -357, +1746, -2519, -8172, -2680, +5031, +100, +1311, -4691, -6912, +1980, +2040, -358, -216, -622, -649, +103, -1622, -626, -497, -1964, -571, -423, -30, +370, +49, -249,
|
||||
+15646, +13159, +261, +4311, -1678, -1288, +1621, -1987, -7004, -3335, +4543, -14, +302, -2477, -7170, -48, +2406, +32, +137, -377, -773, -133, -1665, -841, -152, -1691, -589, -158, -270, +328, +50, -306,
|
||||
+14914, +12999, -328, +4365, -702, -1133, +553, -2016, -4671, -4043, +4026, +360, -1378, -617, -6226, -2166, +2377, +298, -4, +327, -691, -899, -1434, -845, +201, -1106, -1032, -122, -210, +203, +45, -267,
|
||||
+13958, +12124, -373, +4782, +21, -1129, +272, -2320, -3404, -3627, +3139, +1060, -2160, -3, -4519, -3752, +1820, +541, -476, +570, -311, -1038, -1434, -687, +457, -671, -1457, -167, -11, +62, +118, -218,
|
||||
+12918, +10973, -67, +5240, +257, -1386, +443, -1503, -3392, -3835, +2924, +1581, -2328, -20, -2956, -4208, +1045, +694, -894, +202, -292, -645, -959, -841, +200, -409, -1380, -60, +24, -53, +228, -310,
|
||||
+11453, +9857, +558, +5625, +370, -1608, +838, -661, -3107, -4122, +1928, +2028, -1762, -127, -1944, -4054, +595, +740, -1213, -166, -505, -568, -347, -773, -312, -278, -974, +83, +83, -136, +142, -319,
|
||||
+11087, +8602, +495, +7107, +58, -2371, +1638, +267, -3072, -4860, +1382, +2390, -1510, +558, -1623, -4806, +939, +963, -1665, -194, -913, -908, -115, -747, -101, -144, -1056, +521, +304, -293, -8, -330,
|
||||
+9334, +8472, +2057, +6324, -243, -2522, +1386, -290, -2159, -3680, -245, +1661, -676, +956, -788, -4263, -533, +965, -282, -154, -1031, -742, -56, -400, -21, -215, -885, +31, +223, -288, -38, -168,
|
||||
+8202, +7850, +2127, +5711, +161, -1682, +1271, -489, -1744, -3323, -499, +1254, -540, +771, -297, -3344, -963, +1117, -26, -591, -845, -454, -64, -490, -350, -197, -438, -86, -170, -321, +106, -106,
|
||||
+7291, +7027, +2168, +4730, +564, -540, +844, -580, -1481, -2901, -474, +853, -365, +616, -57, -2666, -805, +1195, -67, -613, -593, -252, -128, -623, -577, -254, -297, -288, -279, -138, +171, -54,
|
||||
+6561, +6470, +2014, +3851, +1081, +55, +479, -597, -1428, -2456, -448, +615, -253, +562, +94, -2318, -595, +1226, -130, -587, -411, -244, -197, -635, -712, -320, -371, -307, -113, -95, +84, -14,
|
||||
+5624, +5918, +1762, +3266, +1692, +206, +288, -499, -1267, -1883, -464, +389, +31, +706, +63, -1900, -243, +1098, -142, -584, -335, -87, -244, -648, -669, -209, -339, -372, -24, +17, +83, -55,
|
||||
+4953, +5180, +1625, +3144, +1769, +106, +214, -394, -1053, -1453, -538, +193, +277, +807, +43, -1499, -93, +748, -239, -450, -232, -115, -285, -525, -481, -91, -398, -447, -39, +45, +83, -112,
|
||||
+4115, +4607, +1619, +2888, +1682, +161, +244, -329, -812, -1141, -599, +67, +593, +924, +29, -1137, -210, +449, -129, -365, -249, -133, -121, -277, -340, -178, -530, -428, -2, -6, +39, -84,
|
||||
+3177, +4024, +1786, +2341, +1485, +534, +375, -316, -681, -795, -329, +287, +817, +880, +57, -781, -190, +258, -112, -286, -153, +95, +56, -236, -403, -237, -370, -335, -19, -47, -2, +10,
|
||||
+2412, +3137, +2012, +2211, +1367, +699, +342, -131, -395, -414, -56, +329, +935, +975, +138, -528, -171, +55, -126, -152, +41, +119, -74, -171, -229, -182, -327, -290, -76, -28, +10, -11,
|
||||
+1837, +2561, +1897, +1806, +1200, +798, +563, +60, +7, +156, +349, +604, +923, +1022, +216, -431, -239, -64, +75, +24, -47, +67, +76, -40, -176, -179, -231, -224, -40, +27, +0, -75,
|
||||
+1620, +2181, +1603, +1392, +1074, +916, +849, +620, +322, +470, +694, +763, +907, +764, +43, -376, -76, +71, +101, -3, -39, +86, +110, +0, -148, -121, -113, -69, +18, +9, -117, -268,
|
||||
+1298, +1691, +1267, +1399, +1307, +1124, +1131, +1104, +891, +667, +567, +575, +628, +507, +105, -108, +52, +24, -45, -25, -34, +55, +160, +131, -29, -57, -79, -54, -16, -156, -247, -286,
|
||||
+1179, +1848, +1466, +1730, +1760, +1293, +1046, +857, +729, +698, +565, +381, +236, +320, +318, +91, +9, -97, -187, -79, +91, +171, +186, +225, +142, -75, -156, -189, -210, -232, -263, -201,
|
||||
+1352, +2405, +2052, +1820, +1528, +1334, +1064, +583, +298, +292, +336, +420, +473, +384, +247, -41, -172, -129, -4, +7, +46, +224, +188, +178, +173, -32, -241, -326, -370, -251, -162, -160,
|
||||
+1579, +2518, +2005, +1719, +1482, +1383, +1139, +573, +88, -86, +163, +548, +481, +335, +281, +88, +49, -30, -101, -73, +80, +110, +12, +172, +343, +170, -228, -430, -393, -298, -216, -120,
|
||||
+1583, +2450, +1680, +1499, +1447, +1389, +1184, +570, +27, +164, +464, +283, +128, +199, +220, +325, +423, +123, -72, -74, -43, -22, -19, +72, +115, +277, +185, -229, -439, -410, -283, -162,
|
||||
+1893, +2685, +1508, +1157, +986, +1135, +1120, +583, -124, +57, +765, +643, +287, -137, -232, +275, +511, +407, +350, +8, -96, +73, -79, -165, +36, +100, +98, +172, -6, -229, -385, -374,
|
||||
+2209, +3190, +1517, +1044, +774, +938, +848, +161, -496, -290, +950, +973, +315, -37, -73, +18, +254, +388, +315, +238, +180, +91, -63, -33, -110, -192, -12, +129, +232, +155, -164, -407,
|
||||
+2814, +3765, +1508, +1224, +774, +836, +645, -346, -1219, -800, +1084, +985, +184, +33, +8, +229, +466, +169, +87, +354, +189, +192, +160, -56, +4, -65, -184, -15, +177, +366, +142, -203,
|
||||
+3495, +4412, +1460, +1383, +688, +753, +615, -665, -1708, -1197, +1222, +875, -213, -223, -72, +363, +610, +259, +273, +267, +37, +270, +44, +9, +100, -45, -90, +149, +122, +13, +149, +90,
|
||||
+4347, +4935, +1271, +1660, +643, +828, +646, -1007, -2278, -1449, +1567, +759, -633, -516, -277, +238, +622, +239, +355, +523, +20, +141, +46, -6, +111, -2, +46, +213, +21, +33, +1, +6,
|
||||
+5621, +5545, +799, +2031, +504, +892, +652, -1492, -2860, -1584, +2032, +530, -1030, -782, -469, +89, +432, +59, +340, +429, -61, +279, +83, -74, +47, +39, -51, +241, +56, -19, +59, -78,
|
||||
+6893, +6162, +149, +2382, +396, +828, +623, -2048, -3200, -1408, +2392, +211, -1344, -961, -526, -16, +350, -90, +203, +396, -312, +253, +114, +45, -53, -188, -37, +217, +87, +120, +108, -66,
|
||||
+8235, +7080, -573, +2693, +417, +618, +659, -2697, -3569, -1230, +2683, +76, -1575, -1280, -539, +24, +87, -57, +104, +215, -351, +233, +5, -119, -156, -194, -147, +124, +129, +137, +322, +117,
|
||||
+9244, +7992, -1030, +2743, +479, +517, +696, -3209, -3857, -1043, +2739, -57, -1623, -1427, -588, -20, +90, -120, +74, +343, -449, +31, -200, -78, -273, -310, -78, +136, +134, +157, +303, -20,
|
||||
+10028, +9088, -1078, +2631, +294, +324, +855, -3729, -3984, -1086, +2220, +48, -1346, -1774, -793, -139, +148, +326, -185, +119, -427, -45, -395, -273, -382, -360, -77, +135, +222, +28, +223, -85,
|
||||
+10294, +10035, -677, +2629, +250, -196, +1099, -3767, -3909, -1145, +1327, -1, -804, -1656, -1142, -169, +106, +562, -120, -57, -462, -169, -331, -270, -431, -351, -156, -128, +239, +131, +252, -134,
|
||||
+10483, +10682, -44, +2812, +332, -824, +879, -3596, -3635, -1021, +145, -213, -350, -1319, -899, -635, -133, +919, -37, -375, -472, -69, -227, -286, -527, -354, -246, -281, +155, +54, +190, -76,
|
||||
+10698, +11090, +572, +3361, +554, -1371, +356, -3757, -3360, -322, -956, -1204, +285, -664, -624, -896, -670, +916, +86, -272, -203, -223, -395, -193, -602, -435, -271, -578, +42, +87, +178, -136,
|
||||
+11106, +11176, +704, +4050, +883, -1630, -180, -4140, -2927, +390, -1871, -1878, +528, -231, -70, -1098, -1213, +889, +383, -352, -139, -56, -382, -365, -792, -502, -300, -681, -116, +59, +212, -78,
|
||||
+12036, +10896, +310, +5032, +1033, -1870, -823, -4447, -2503, +1349, -2741, -3214, +855, +29, +682, -1055, -1808, +920, +555, -599, -93, +53, -545, -351, -1135, -651, -258, -802, -256, +44, +72, -285,
|
||||
+13249, +10533, -420, +6055, +876, -1900, -821, -5027, -1957, +2680, -3299, -4856, +928, +484, +1323, -695, -2251, +831, +740, -767, -47, +126, -881, -350, -1161, -698, -223, -889, -359, +46, +17, -320,
|
||||
+14864, +10460, -1804, +6568, +665, -1731, -635, -5767, -1405, +4093, -3512, -6402, +622, +675, +1688, -26, -2440, +393, +956, -897, -408, +254, -945, -393, -1446, -932, -12, -855, -629, +79, +67, -544,
|
||||
+16627, +11397, -3842, +5964, +612, -1624, +440, -5965, -2042, +5011, -2485, -7307, -214, +766, +2141, +296, -2808, +260, +1140, -1052, -587, +505, -1093, -517, -1488, -1064, +12, -788, -651, -39, +118, -479,
|
||||
+18518, +12633, -6334, +4990, +229, -1244, +2367, -6506, -3133, +5859, -1129, -7799, -1129, +600, +2173, +719, -3075, -318, +1316, -740, -910, +425, -1093, -394, -1508, -1432, +145, -700, -804, -94, +327, -401,
|
||||
+20973, +12619, -8500, +4951, -770, -461, +3392, -7134, -3315, +6719, +196, -8369, -2213, +3, +2743, +961, -3843, -722, +1691, -730, -1369, +644, -1082, -293, -1519, -1634, +52, -689, -686, +59, +271, -608,
|
||||
+22297, +12836, -9690, +4807, -1655, +104, +4092, -7312, -3771, +7038, +1693, -8910, -3012, -482, +2558, +1188, -3919, -1129, +1548, -693, -1611, +794, -1184, -115, -1465, -1976, +34, -436, -598, -24, +171, -683,
|
||||
+23980, +12855, -10608, +4407, -2867, +1228, +4914, -7539, -4560, +7253, +3208, -8777, -3558, -1999, +2512, +1964, -3980, -1552, +1290, -765, -1611, +896, -1300, -1, -1603, -2008, +250, -237, -601, -60, +99, -743,
|
||||
+24531, +13684, -11034, +3704, -3405, +1665, +5463, -7291, -5568, +6806, +4893, -8341, -4325, -3233, +2310, +2880, -3885, -2013, +1022, -727, -1606, +925, -1552, -68, -1433, -1949, +261, -130, -552, -62, +43, -848,
|
||||
+25399, +13806, -10659, +3086, -4032, +2086, +5508, -6663, -6694, +6473, +6232, -7551, -4944, -4555, +2202, +3628, -3339, -2592, +933, -785, -1566, +810, -1901, +111, -1220, -1934, +196, +16, -580, +86, -113, -983,
|
||||
+25699, +14205, -10203, +2771, -4453, +2044, +5466, -6220, -7611, +5940, +7067, -6399, -5381, -5665, +2085, +3997, -2469, -3078, +674, -608, -1758, +594, -1930, +265, -1252, -1733, -62, +13, -409, -15, -218, -1005,
|
||||
+25576, +14678, -9511, +2627, -4889, +1979, +5231, -5940, -8313, +5036, +7731, -5018, -5437, -6902, +1757, +4371, -1482, -3465, +202, -277, -2109, +514, -1803, +302, -1201, -1716, -327, +65, -365, -277, -95, -1022,
|
||||
+24917, +15555, -8325, +2832, -5406, +1692, +5071, -5894, -8820, +3797, +8250, -3317, -4558, -8452, +986, +4981, -445, -3381, -624, +98, -2239, +474, -1567, +517, -1341, -1880, -275, -194, -234, -524, +73, -946,
|
||||
+24560, +15279, -6686, +3008, -5680, +1683, +4433, -5659, -9447, +3055, +7994, -2069, -3264, -9450, +188, +5223, +139, -3059, -1138, +123, -1936, +284, -1347, +532, -1421, -1864, -486, -372, -126, -624, +111, -613,
|
||||
+23630, +15485, -4781, +2918, -5523, +1209, +3879, -4787, -10506, +1989, +7668, -1020, -1165, -10262, -1408, +5686, +432, -2423, -1223, -173, -1294, +57, -1598, +885, -1360, -2222, -434, -735, -7, -301, +148, -390,
|
||||
+22705, +15510, -3489, +2520, -4580, +974, +2845, -3997, -11138, +1148, +7254, -749, +544, -10123, -3273, +5720, +656, -1873, -901, -539, -1078, +82, -1698, +797, -1433, -2392, -307, -961, +186, -54, +102, -179,
|
||||
+21833, +14435, -1480, +2989, -4502, +876, +1865, -3114, -11297, -386, +7023, -399, +2038, -9446, -5658, +5465, +1168, -1290, -470, -782, -783, -20, -1877, +659, -1411, -2696, -156, -783, +130, +317, +217, -316,
|
||||
+20537, +13992, -708, +4279, -4744, +442, +1972, -3237, -10625, -1985, +6923, -199, +2505, -7991, -7936, +4778, +2128, -1048, -448, -664, -657, +84, -2053, -179, -858, -2526, -357, -737, +238, +571, -51, -298,
|
||||
+19638, +14025, -1030, +4778, -3659, -452, +2274, -3224, -9891, -2808, +7103, -662, +1734, -5223, -9487, +3226, +2912, -583, -44, -906, -673, +388, -2239, -882, -152, -2483, -417, -219, -101, +496, +27, -274,
|
||||
+19049, +13570, -1555, +5415, -2800, -1809, +2085, -2243, -8328, -3763, +6265, -489, +380, -2622, -9535, +545, +3560, -254, +273, -392, -940, -193, -2156, -847, +103, -2093, -472, -40, -391, +519, -11, -393,
|
||||
+18168, +13590, -2249, +5443, -1644, -1455, +603, -2301, -5416, -4970, +5891, +62, -1742, -291, -8568, -1959, +3759, +29, -30, +506, -899, -1149, -1711, -913, +543, -1423, -1173, +54, -259, +333, +11, -312,
|
||||
+17035, +12827, -2281, +5894, -726, -1489, +185, -2933, -3444, -4639, +4541, +1190, -2977, +751, -6689, -4331, +3534, +367, -666, +1029, -430, -1560, -1739, -617, +856, -909, -1806, +43, +2, +135, +104, -229,
|
||||
+16109, +11603, -1857, +6452, -517, -1810, +245, -2043, -3755, -4481, +4547, +1368, -3096, +727, -4933, -5160, +2492, +733, -1012, +720, -307, -1028, -1535, -868, +957, -652, -2015, +138, +117, -22, +249, -321,
|
||||
+14557, +10522, -1242, +6803, -315, -2135, +723, -1118, -3548, -5279, +4014, +2629, -3572, +779, -3115, -5769, +2018, +890, -1739, +290, -311, -714, -642, -1091, +163, -204, -1599, +276, +13, -124, +387, -488,
|
||||
+12812, +9467, -224, +7139, -314, -2365, +1207, -230, -3341, -5355, +2557, +2879, -2315, +419, -2362, -5322, +1454, +982, -1883, -47, -628, -728, -93, -958, -294, -130, -1142, +362, +163, -228, +155, -376,
|
||||
+13067, +8369, -144, +8730, -2405, -3459, +1450, -1502, -5332, -4279, +6473, +1714, -1900, +3709, -1903, -4707, +1918, +120, -2550, -1093, -1848, -621, -724, -1598, -147, -744, -877, +540, -151, -509, +318, -28,
|
||||
+10904, +8241, +866, +7747, -891, -4073, +130, -1350, -3923, -2891, +4427, +2115, -885, +2373, -1299, -4343, +153, +77, -1658, -317, -1588, -605, +53, -1825, -85, -335, -1528, -11, -42, -273, +59, -76,
|
||||
+9279, +7452, +1520, +7064, -405, -3081, +178, -1385, -2926, -2332, +3123, +1898, -776, +1781, -925, -3718, -102, -120, -1233, -82, -1199, -290, +2, -1550, -49, -380, -1428, -264, -245, -270, +11, -162,
|
||||
+7668, +6712, +2160, +6267, +54, -2125, +134, -1110, -2049, -2036, +2189, +1460, -699, +1339, -688, -3011, -497, -119, -970, -142, -497, +186, +37, -1292, -184, -526, -1267, -503, -546, -437, +10, -9,
|
||||
+6368, +6134, +2492, +5439, +623, -1515, +73, -449, -1505, -1848, +1544, +1044, -644, +955, -348, -2562, -737, -6, -786, +148, +175, +380, -63, -1068, -366, -637, -1119, -714, -616, -443, -44, +1,
|
||||
+5309, +5691, +2463, +4700, +1132, -1190, +301, +59, -1194, -1566, +901, +654, -559, +719, -197, -2168, -766, +93, -248, +496, +263, +194, -53, -903, -530, -692, -1037, -585, -576, -463, -126, -99,
|
||||
+4671, +5240, +2273, +4089, +1224, -820, +599, +183, -902, -1333, +289, +350, -412, +640, -190, -1832, -504, +307, +145, +562, +47, +10, -140, -891, -579, -467, -751, -658, -629, -412, -121, -71,
|
||||
+4304, +4612, +2145, +3630, +1141, -235, +799, +247, -609, -1181, -104, +233, -152, +634, +32, -1399, -325, +524, +389, +368, -139, -41, -258, -648, -199, -313, -764, -659, -480, -282, -35, +38,
|
||||
+3883, +4121, +1999, +3085, +1218, +245, +812, +308, -391, -1122, -309, +165, +293, +913, +46, -1198, -224, +714, +439, +55, -298, +56, +12, -400, -192, -282, -674, -589, -276, -72, +113, +77,
|
||||
+3262, +3880, +1810, +2399, +1483, +674, +763, +273, -288, -1047, -181, +700, +489, +675, +71, -953, -158, +742, +296, -120, -45, +156, +92, -270, -319, -271, -421, -326, -57, +99, -64, -314,
|
||||
+2385, +3308, +1933, +2191, +1681, +725, +640, +373, +136, -286, -143, +637, +683, +410, +103, -565, -257, +619, +421, -40, +28, +179, +55, -233, -135, -54, -204, -72, -29, -217, -320, -330,
|
||||
+1874, +3072, +1941, +1419, +1419, +1279, +891, +484, +398, +297, +230, +463, +469, +136, +85, -228, -107, +538, +410, +40, -27, +98, +145, +77, +20, +54, +21, -272, -370, -309, -248, -206,
|
||||
+1591, +2376, +1629, +1368, +1569, +1437, +1231, +1006, +583, +432, +297, +204, +299, +145, -140, +13, +312, +339, +220, +17, +14, +285, +382, +203, +101, -101, -334, -332, -302, -287, -184, -195,
|
||||
+1470, +1787, +1502, +1987, +1911, +1545, +1043, +878, +865, +431, +197, +86, +12, +101, +92, +101, +251, +178, +190, +346, +300, +250, +251, +133, -107, -287, -400, -336, -238, -260, -239, -257,
|
||||
+1914, +2455, +1662, +1958, +1844, +1522, +942, +380, +248, +262, +332, +128, +22, +126, +219, +6, -12, +304, +516, +586, +402, +88, -170, -256, -295, -306, -261, -267, -279, -273, -326, -327,
|
||||
+1650, +2454, +1992, +2081, +1838, +1445, +722, +274, +244, +203, +344, +372, +259, +83, -81, -61, +209, +336, +515, +666, +466, +145, -229, -453, -374, -308, -238, -216, -280, -231, -312, -373,
|
||||
+1972, +2726, +1615, +1875, +1444, +1065, +882, +237, +52, +429, +512, +299, +333, -155, -232, +94, +178, +234, +473, +659, +391, +136, -262, -514, -398, -381, -424, -222, -224, -324, -266, -374,
|
||||
+1944, +2569, +1405, +1599, +1309, +1157, +866, +373, +250, +451, +528, +453, +471, +1, +55, +191, +129, +155, +283, +436, +597, +713, +68, -320, -396, -509, -294, -216, -242, -220, -186, -273,
|
||||
+2213, +2847, +1259, +1256, +996, +980, +849, +260, -32, +445, +818, +478, +247, +265, +193, +76, +464, +202, +102, +347, +222, +450, +618, +397, -308, -565, -442, -327, -186, -168, -163, -249,
|
||||
+2697, +3456, +1227, +1213, +572, +517, +850, +102, -387, +192, +924, +490, +415, +251, -28, +334, +487, +237, +455, +306, -44, +361, +407, +349, +369, -96, -484, -382, -224, -207, -148, -176,
|
||||
+3120, +3716, +1221, +1448, +755, +624, +603, -564, -1136, +136, +1257, +246, +285, +171, -38, +383, +232, +372, +711, +324, +99, +204, -9, +285, +321, +68, +177, -36, -413, -443, -150, -173,
|
||||
+3790, +4330, +1096, +1569, +784, +588, +463, -1059, -1653, +106, +1501, +73, -126, -239, -105, +460, +435, +368, +402, +389, +91, +309, +250, +37, -30, -24, +199, +248, +66, -210, -381, -373,
|
||||
+4622, +5180, +929, +1541, +623, +502, +584, -1498, -2233, +215, +1742, -187, -310, -505, -413, +362, +388, +344, +575, +292, -268, +436, +270, +95, +161, -323, -90, +279, +151, -2, +128, -96,
|
||||
+5681, +5925, +575, +1587, +609, +492, +477, -2071, -2626, +569, +1878, -446, -437, -854, -523, +332, +170, +294, +523, +68, -219, +380, -38, +251, +114, -335, +23, -101, -23, +248, +375, +75,
|
||||
+6767, +6666, +205, +1705, +662, +498, +302, -2825, -2958, +1150, +2042, -710, -533, -1232, -642, +377, +122, +237, +348, -95, -351, +388, -30, +5, -60, -377, -119, +125, +76, -40, +330, +247,
|
||||
+7914, +7510, -124, +1761, +488, +420, +174, -3558, -3104, +1640, +2028, -832, -567, -1607, -766, +361, +95, +311, +212, -352, -461, +375, -113, -24, -351, -633, -128, +128, +9, -5, +457, +80,
|
||||
+8830, +8494, -246, +1750, +304, +130, +113, -4143, -3165, +1945, +1825, -857, -549, -1777, -958, +191, +133, +387, +88, -480, -608, +386, -265, -246, -302, -723, -280, -84, -50, +74, +350, +96,
|
||||
+9314, +9665, +71, +1635, +346, -372, -34, -4328, -3176, +2030, +1536, -817, -547, -1732, -1016, -133, +66, +591, +24, -506, -733, +116, -40, -327, -495, -730, -460, +25, -137, -166, +374, -5,
|
||||
+9168, +10764, +1097, +1383, +468, -796, -470, -4274, -3169, +1769, +1273, -725, -691, -1625, -1027, -452, -36, +630, +83, -652, -832, +127, -43, -349, -695, -737, -514, -168, -181, -314, +338, +138,
|
||||
+8846, +11350, +2560, +1552, +433, -953, -869, -4243, -3192, +1361, +998, -476, -837, -1626, -886, -800, -125, +635, -124, -228, -816, -255, -7, -394, -552, -761, -755, -414, -246, -133, +444, +75,
|
||||
+8964, +11306, +3527, +2438, +253, -982, -961, -4230, -3082, +755, +442, -71, -869, -1742, -700, -1038, -454, +793, +25, -389, -604, -243, +7, -464, -738, -765, -951, -330, -59, -171, +251, +95,
|
||||
+9403, +11033, +3733, +3695, +308, -1271, -992, -4163, -2722, +92, -735, +217, -696, -1699, -422, -1673, -402, +984, -229, -198, -530, -373, +28, -463, -956, -681, -906, -518, -289, -162, +497, +102,
|
||||
+10184, +10713, +3388, +4822, +577, -1450, -980, -3974, -2096, -266, -2455, +170, -229, -2033, +139, -1657, -867, +1176, -218, -154, -435, -585, +36, -392, -1039, -506, -950, -753, -269, -164, +336, -63,
|
||||
+11469, +10305, +2546, +5881, +499, -1455, -857, -3843, -1101, -509, -4401, -50, +59, -2342, +782, -1732, -924, +1406, -569, -258, -144, -530, -49, -395, -1238, -446, -756, -782, -536, -315, +337, -105,
|
||||
+12812, +9997, +1333, +7068, +255, -1649, -308, -3676, +7, -196, -6478, -1003, +993, -2770, +1003, -1205, -1230, +1463, -713, -345, +195, -392, -236, -389, -1244, -431, -777, -964, -608, -183, +371, -471,
|
||||
+14298, +10024, -465, +8212, +114, -2512, +382, -3674, +1378, +663, -8685, -2459, +1859, -2562, +871, -988, -1367, +1466, -684, -580, +254, -110, -241, -347, -1398, -758, -715, -816, -729, -361, +154, -579,
|
||||
+15791, +10811, -2667, +8435, +624, -3271, +1069, -3748, +2502, +2079, -10027, -4329, +2301, -1901, +666, -578, -1480, +1296, -627, -770, +123, +401, -53, -652, -1473, -822, -551, -788, -1234, -414, +540, -655,
|
||||
+17964, +11856, -5206, +7310, +1001, -3366, +1912, -4139, +2658, +3650, -10394, -6002, +1938, -1051, +777, -287, -1664, +896, -566, -1001, +87, +651, -41, -918, -1419, -920, -813, -755, -1256, -323, +672, -811,
|
||||
+20009, +12521, -7253, +6282, +961, -3398, +2583, -4837, +2731, +5771, -10940, -7407, +1508, -472, +1186, -388, -1734, +332, -519, -1043, -71, +553, -29, -952, -1661, -1165, -989, -425, -1171, -377, +657, -839,
|
||||
+22177, +13864, -9457, +4361, +273, -2050, +3806, -6178, +2512, +7329, -10722, -7725, +990, -611, +1552, -139, -1889, -63, -466, -1163, -297, +596, -38, -1172, -1902, -1306, -955, -76, -1070, -458, +771, -742,
|
||||
+24345, +14808, -11064, +2917, -761, -281, +4365, -7368, +2909, +8263, -9604, -7789, +243, -1094, +2044, +574, -2131, -536, -396, -1094, -498, +632, -243, -1137, -1962, -1496, -848, +190, -940, -375, +1054, -832,
|
||||
+26147, +15550, -12303, +1685, -1810, +967, +4288, -7960, +2974, +9042, -8220, -8190, -317, -1893, +2641, +1163, -2716, -789, -273, -1142, -847, +531, -446, -868, -2137, -1852, -734, +364, -774, -243, +1065, -1025,
|
||||
+27659, +16152, -13062, +755, -2711, +1616, +4052, -7901, +2526, +9678, -6491, -8602, -661, -2830, +3049, +1720, -3198, -833, -91, -1450, -1161, +618, -586, -618, -2344, -2144, -611, +510, -566, -204, +872, -1008,
|
||||
+28303, +17220, -13451, +40, -3448, +1563, +3863, -7612, +1462, +10219, -4267, -9081, -1078, -3763, +2992, +2435, -3478, -882, -13, -1844, -1413, +823, -875, -471, -2328, -2410, -559, +601, -471, -315, +732, -991,
|
||||
+29181, +17405, -13114, -304, -4240, +1458, +3452, -7492, +539, +10765, -2404, -8991, -1702, -4595, +2982, +2817, -3292, -1057, +74, -2172, -1478, +872, -1165, -289, -2195, -2469, -548, +634, -663, -287, +578, -1042,
|
||||
+29321, +17827, -12348, -557, -5122, +1071, +3363, -7877, -467, +11248, -887, -8472, -2373, -5291, +2598, +3058, -2743, -1532, +107, -2142, -1752, +699, -1290, -111, -1997, -2388, -740, +468, -816, -385, +487, -985,
|
||||
+28805, +18575, -11075, -519, -6256, +621, +3883, -8757, -1416, +11447, +404, -7310, -2751, -5966, +1821, +3238, -1902, -1967, -52, -1838, -2084, +568, -1247, +63, -1562, -2577, -1051, +401, -1056, -280, +613, -1053,
|
||||
+27710, +19425, -9278, -279, -7398, +89, +4632, -9740, -2488, +11491, +1418, -5692, -2452, -7072, +956, +3436, -1270, -1977, -465, -1644, -2124, +549, -1018, +267, -1537, -2600, -1365, +17, -689, -160, +642, -1022,
|
||||
+26524, +19729, -7061, +31, -8340, -267, +5003, -10177, -3987, +11429, +2435, -4362, -1321, -8478, +66, +3718, -1132, -1735, -895, -1806, -1690, +886, -1190, +400, -1479, -2883, -1377, -121, -394, -59, +689, -900,
|
||||
+24731, +20271, -4631, +239, -8724, -1229, +4844, -9185, -6220, +10730, +4243, -3815, +672, -9539, -1506, +4100, -1430, -1335, -947, -2166, -1162, +1047, -1494, +767, -1758, -3042, -837, -474, -154, +165, +571, -941,
|
||||
+23477, +19815, -2244, +479, -9027, -1898, +3618, -7399, -7878, +9201, +6108, -3552, +2583, -9590, -3747, +4198, -1760, -1193, -323, -2539, -1400, +1397, -1635, +542, -1400, -3228, -438, -316, -265, +162, +498, -845,
|
||||
+22603, +18971, -668, +1272, -8642, -2638, +2333, -6179, -8347, +7433, +7800, -2940, +3459, -8248, -6239, +4034, -1687, -1398, +219, -2550, -1401, +1181, -1707, +569, -817, -3297, +15, -296, -506, +401, +364, -924,
|
||||
+21958, +18536, -765, +2387, -7488, -4223, +1716, -5274, -8935, +6110, +9409, -2450, +3540, -6393, -8448, +3758, -1179, -2277, +576, -2418, -1529, +1177, -1880, +420, +14, -3051, -213, -188, -381, +229, +231, -793,
|
||||
+22176, +17185, -1463, +4151, -7417, -5322, +1894, -4670, -9301, +4733, +10404, -1838, +3744, -5092, -9471, +2688, -467, -2307, -46, -2508, -1717, +1645, -1714, +18, +585, -2841, -290, -132, -583, +271, +215, -863,
|
||||
+21283, +15947, -1061, +5846, -8289, -5644, +2856, -4640, -8855, +2098, +10641, -385, +3529, -2820, -10460, +1131, +531, -2119, -590, -2947, -2184, +2054, -1090, -387, +1198, -3026, -869, +546, -650, +116, +60, -894,
|
||||
+19683, +14620, -396, +7001, -7790, -5818, +2880, -3841, -8800, -338, +10153, +959, +3167, -585, -10098, -824, +1447, -2278, -872, -2755, -2996, +1653, -697, +272, +1462, -3849, -1195, +1382, -669, -246, -11, -701,
|
||||
+19043, +12870, -2025, +8715, -5341, -5810, +2282, -4136, -8408, -1971, +10181, +1931, +1229, +1395, -8274, -2327, +1832, -1907, -1520, -2677, -3203, +831, -255, +370, +1503, -3747, -1696, +1786, -499, -464, -64, -480,
|
||||
+17772, +11494, -1905, +9490, -4457, -5781, +2323, -3030, -7953, -3525, +9683, +2138, -957, +3838, -5603, -4565, +2549, -1532, -2419, -1808, -2980, +12, -610, -213, +1746, -2508, -2211, +1172, +20, -342, -24, -448,
|
||||
+16172, +10332, -1197, +9288, -3999, -4949, +1874, -2282, -7098, -4475, +8985, +1667, -1887, +4717, -3907, -5051, +2520, -1200, -2844, -1330, -2611, -280, -1072, -1112, +1423, -1375, -1811, +550, -258, -177, +416, -403,
|
||||
+14861, +9191, -894, +9322, -3451, -4203, +1793, -2119, -6076, -4508, +7671, +1778, -2043, +4285, -2907, -4648, +2360, -879, -2603, -1241, -2298, -406, -1008, -1513, +521, -984, -1055, +584, -582, -325, +664, -263,
|
||||
+15154, +9134, -4908, +9650, +694, -5568, -98, -860, -5127, -4048, +7837, -470, -3638, +3508, -972, -2437, +3394, +805, -1417, +31, -1653, -577, -2362, -2979, -580, -1077, -1684, -192, -259, +22, +565, -429,
|
||||
+12672, +9048, -2546, +8370, +349, -5006, +73, -1080, -4272, -3672, +5900, +444, -2326, +2893, -1066, -2332, +2479, +666, -949, -82, -1657, -457, -1794, -2452, -454, -1165, -1497, -205, -372, -240, +406, -163,
|
||||
+10640, +8312, -1031, +7498, +500, -3857, +463, -1057, -3977, -3222, +4691, +603, -1571, +2325, -824, -2114, +1780, +754, -897, -192, -1342, -620, -1307, -1779, -405, -857, -1348, -343, -250, -417, +44, -237,
|
||||
+8848, +7462, +273, +6812, +521, -2799, +1008, -1064, -3777, -2718, +3754, +821, -1252, +1806, -375, -2145, +1225, +906, -817, -265, -1155, -585, -1036, -1174, -21, -762, -1257, -311, -233, -510, -203, -397,
|
||||
+7576, +6767, +783, +6094, +949, -1930, +961, -934, -3200, -2533, +3115, +1137, -1365, +1382, -102, -2040, +908, +789, -690, -334, -1018, -480, -555, -707, -43, -640, -1047, -255, -386, -684, -317, -445,
|
||||
+6758, +6214, +818, +5337, +1627, -1135, +432, -710, -2305, -2322, +2540, +1251, -1296, +892, -62, -1566, +663, +551, -577, -337, -682, -77, -179, -659, -184, -409, -797, -413, -574, -679, -216, -506,
|
||||
+5676, +5613, +1210, +4774, +1859, -559, +347, -565, -1759, -1969, +1960, +1004, -1099, +525, -53, -1205, +350, +369, -435, -6, -319, -23, -94, -656, -285, -373, -741, -563, -562, -531, -260, -514,
|
||||
+4838, +5040, +1571, +4251, +1972, -105, +267, -310, -1227, -1573, +1267, +789, -798, +205, +14, -944, +147, +508, -9, +9, -221, +150, -128, -742, -391, -376, -652, -447, -470, -469, -201, -405,
|
||||
+3971, +4513, +1934, +3945, +1836, +92, +581, -63, -938, -1357, +811, +579, -793, +202, +181, -781, +327, +624, -92, +15, +0, +147, -352, -881, -357, -191, -505, -444, -412, -282, -88, -284,
|
||||
+3487, +4143, +1924, +3589, +1775, +195, +713, +196, -635, -1287, +387, +393, -687, +361, +568, -535, +98, +502, -1, +100, +31, -150, -611, -593, -111, -190, -456, -382, -216, -81, -181, -553,
|
||||
+3301, +3728, +1795, +3379, +1523, +332, +960, +396, -543, -1253, +191, +235, -129, +880, +351, -652, +117, +445, +130, +39, -216, -238, -343, -293, -61, -146, -363, -182, -162, -325, -424, -636,
|
||||
+3158, +3429, +1574, +3069, +1415, +510, +1197, +428, -494, -1109, +222, +719, +168, +681, +275, -640, +81, +477, +19, -67, -36, -85, -122, -162, +45, -5, -361, -356, -380, -419, -409, -428,
|
||||
+2927, +3070, +1345, +2819, +1417, +712, +1293, +444, -262, -476, +280, +510, +400, +568, +118, -618, -112, +442, +241, +165, -34, -72, +77, +111, +94, -334, -675, -432, -303, -274, -306, -497,
|
||||
+2770, +2981, +1085, +2080, +1492, +1281, +1415, +707, +136, -480, +296, +711, +259, +268, -123, -614, +243, +742, +216, +47, +81, +319, +285, -194, -408, -500, -506, -280, -185, -330, -423, -456,
|
||||
+2145, +2721, +1165, +1872, +1627, +1355, +2019, +1188, +250, -296, -84, +490, +282, +67, -115, -178, +405, +756, +354, +121, +267, +315, -30, -468, -422, -383, -385, -212, -269, -357, -406, -427,
|
||||
+1842, +2681, +1515, +1848, +2108, +1608, +1340, +1172, +512, -174, -238, -168, -13, +491, +474, +113, +382, +613, +415, +165, +91, -47, -298, -384, -349, -382, -402, -278, -199, -319, -431, -344,
|
||||
+1494, +2675, +2068, +1863, +2114, +2048, +1472, +644, +14, -248, -149, +107, +179, +299, +556, +612, +502, +443, +238, -13, -145, -180, -250, -339, -297, -336, -446, -377, -225, -244, -239, -265,
|
||||
+1925, +2822, +1707, +2248, +2162, +1532, +1572, +666, -432, -363, +210, +212, +263, +498, +470, +699, +813, +253, -219, -217, -141, -158, -176, -306, -384, -385, -364, -200, -281, -326, -188, -200,
|
||||
+1895, +2793, +1934, +2045, +1846, +1354, +1196, +799, +59, -3, +248, +165, +197, +407, +651, +831, +698, +67, -242, -221, -251, -169, -144, -186, -354, -464, -369, -235, -233, -217, -227, -253,
|
||||
+2070, +3085, +1525, +1328, +1530, +1219, +1048, +1205, +562, -2, +387, +198, +130, +544, +658, +484, +722, +457, -348, -457, -175, -78, -253, -223, -258, -370, -406, -378, -222, -139, -199, -290,
|
||||
+2157, +2952, +1156, +902, +1034, +1185, +1499, +1126, +501, +624, +479, -49, +331, +597, +587, +621, +629, +548, +175, -291, -470, -235, -85, -52, -278, -368, -303, -369, -323, -238, -97, -173,
|
||||
+2202, +2907, +1140, +947, +996, +914, +968, +769, +506, +769, +808, +471, +171, +297, +838, +683, +510, +567, +580, +137, -151, -326, -508, -27, -10, -284, -285, -236, -358, -292, -161, -179,
|
||||
+2228, +3053, +1096, +862, +1274, +1155, +755, +13, -357, +880, +1376, +402, +198, +406, +514, +671, +748, +486, +514, +663, +288, -200, -289, -329, -436, -55, -28, -272, -239, -283, -290, -193,
|
||||
+2611, +3293, +974, +955, +1269, +1230, +755, -497, -748, +618, +1056, +494, +365, +41, +465, +810, +420, +494, +736, +416, +453, +551, -173, -405, -427, -456, -169, -36, -153, -282, -273, -363,
|
||||
+3071, +3880, +1049, +902, +1063, +1099, +721, -721, -1094, +709, +1109, -47, +104, +119, +412, +545, +413, +580, +520, +543, +532, +362, +329, +140, -499, -431, -240, -372, -190, -30, -169, -356,
|
||||
+3643, +4399, +965, +972, +1042, +1109, +628, -1277, -1336, +964, +1149, -203, -182, -383, +345, +664, +317, +410, +437, +373, +394, +662, +276, +180, +133, -200, -383, -376, -281, -286, -117, -162,
|
||||
+4308, +4895, +774, +1151, +1170, +1121, +455, -1795, -1513, +1267, +1131, -396, -245, -566, +93, +375, +376, +540, +286, +94, +297, +541, +252, +439, +34, +129, +201, -368, -356, -264, -280, -354,
|
||||
+5087, +5494, +565, +1262, +1166, +1002, +246, -2296, -1418, +1649, +899, -695, -391, -688, +139, +229, +44, +521, +312, -3, +101, +250, +192, +280, +43, +280, +150, +88, +29, -357, -310, -372,
|
||||
+5947, +6051, +327, +1497, +1239, +800, -127, -2807, -1134, +2147, +640, -918, -589, -888, +220, +107, +62, +477, +59, -49, +73, +198, -35, +79, -132, +175, +309, +137, +146, +162, -75, -593,
|
||||
+6826, +6642, +77, +1786, +1321, +527, -620, -3298, -663, +2560, +320, -1067, -693, -1064, +226, -95, -6, +673, -51, -262, -29, +141, -44, -11, -506, +62, +205, +6, +401, +111, +23, -56,
|
||||
+7619, +7443, -127, +1929, +1356, +155, -1099, -3708, -137, +2846, -83, -1160, -806, -1101, +269, -385, -138, +769, -105, -266, -156, -64, -45, -101, -607, -105, -82, +19, +101, +44, +338, -87,
|
||||
+8308, +8291, -181, +1996, +1443, -217, -1606, -4093, +424, +3041, -446, -1225, -972, -1051, +348, -589, -310, +757, -179, -230, -151, -213, -150, -169, -724, -105, -113, -531, +38, +251, +144, +14,
|
||||
+8643, +9273, +110, +1817, +1665, -587, -2048, -4412, +705, +3223, -686, -1244, -1233, -1013, +428, -696, -381, +630, -323, -238, -129, -251, -193, -373, -663, -295, -481, -278, -3, -42, +123, -69,
|
||||
+8492, +10281, +986, +1409, +1924, -770, -2443, -4558, +552, +3340, -711, -1234, -1461, -1100, +472, -719, -429, +587, -437, -400, -100, -332, -135, -347, -1076, -422, -280, -435, -79, -23, +2, -146,
|
||||
+8125, +10926, +2345, +1150, +1899, -669, -2844, -4563, +156, +3228, -595, -1223, -1573, -1303, +463, -750, -482, +579, -448, -544, -287, -237, -139, -775, -987, -370, -466, -463, -189, -20, +78, -37,
|
||||
+7991, +11060, +3529, +1603, +1541, -533, -3046, -4622, -35, +2877, -564, -1180, -1626, -1431, +402, -852, -505, +583, -405, -609, -263, -542, -401, -426, -1162, -560, -503, -504, -197, +50, +140, -226,
|
||||
+8113, +10987, +4130, +2562, +1381, -747, -2977, -4641, -186, +2488, -599, -1166, -1769, -1438, +351, -1006, -539, +563, -351, -314, -744, -723, -154, -612, -1117, -726, -662, -455, -57, +40, -92, -256,
|
||||
+8541, +10760, +4178, +3497, +1698, -1029, -2982, -4222, -351, +1963, -668, -970, -2110, -1515, +400, -1246, -614, +645, -262, -603, -476, -696, -449, -571, -1094, -668, -849, -390, -123, -169, +68, -29,
|
||||
+9463, +10347, +3864, +4361, +1905, -1015, -3375, -3543, -178, +968, -787, -513, -2341, -1829, +501, -1686, -325, +497, -681, +38, -559, -871, -367, -691, -1137, -482, -872, -677, -284, +7, +225, -241,
|
||||
+10674, +9874, +3106, +5362, +1727, -766, -3609, -3015, +543, -431, -1222, +153, -2336, -2209, +365, -1836, -554, +242, -426, +197, -633, -802, -399, -696, -1174, -325, -1145, -803, -31, -108, -43, -199,
|
||||
+11979, +9620, +1869, +6561, +1461, -835, -3245, -2641, +1610, -1691, -2279, +974, -2010, -2575, +505, -2638, -686, +670, -1065, +774, -478, -978, -319, -585, -1119, -498, -1130, -708, -19, -296, -40, -290,
|
||||
+13201, +9744, +157, +7624, +1518, -1581, -2587, -2110, +2716, -2532, -3960, +1424, -1264, -2535, -109, -3054, -615, +404, -1230, +1095, -263, -1158, -337, -435, -1109, -466, -1189, -812, +84, -300, -171, -443,
|
||||
+14767, +10074, -1860, +8018, +1956, -2430, -2103, -1372, +3819, -2797, -5967, +1234, +173, -2924, -421, -3162, -1160, +752, -1619, +1210, +95, -1349, -306, -444, -1114, -283, -1142, -1053, +276, -314, -302, -597,
|
||||
+16745, +11407, -4630, +6674, +3018, -2190, -1545, -1323, +4470, -2021, -7769, +629, +1347, -2958, -574, -3466, -1241, +900, -1709, +1083, +268, -1132, -420, -544, -1164, -33, -940, -1138, +189, -205, -362, -753,
|
||||
+18725, +12859, -7380, +4619, +4068, -1417, -1079, -1554, +4711, -1055, -8876, -550, +1948, -2355, -915, -3587, -1380, +839, -1610, +894, +413, -1080, -618, -661, -1073, +37, -840, -1169, +44, -15, -345, -1019,
|
||||
+20617, +14278, -9830, +2481, +4741, -181, -623, -1858, +4753, +25, -9421, -1889, +2095, -1425, -1076, -3758, -1263, +565, -1542, +933, +391, -1113, -672, -722, -1015, -8, -886, -996, +4, +105, -420, -1228,
|
||||
+22971, +14648, -11936, +1010, +4670, +1158, -431, -2361, +5156, +1040, -10169, -3060, +2153, -790, -797, -4032, -1000, +16, -1618, +1257, +163, -1228, -657, -703, -1282, -23, -913, -801, -89, +33, -392, -1315,
|
||||
+25010, +15029, -13660, +283, +4193, +2237, -295, -3037, +6357, +2181, -11344, -3815, +2283, -582, +157, -4078, -1205, -374, -1568, +1582, -149, -1216, -484, -731, -1677, +102, -841, -808, -116, +31, -256, -1422,
|
||||
+26769, +15204, -15115, +212, +3256, +2746, -305, -3981, +8274, +2753, -12585, -4021, +1747, -336, +1272, -4084, -1750, -584, -1463, +1491, -429, -1113, -280, -912, -2029, +54, -759, -856, -175, +86, -304, -1461,
|
||||
+28266, +15342, -16203, +581, +2138, +2848, -458, -4840, +10385, +2925, -13189, -4103, +831, +88, +2199, -3878, -2349, -502, -1510, +1038, -429, -929, -129, -1132, -2297, -63, -611, -925, -177, +40, -335, -1317,
|
||||
+29815, +15252, -16897, +1083, +956, +2943, -891, -5377, +12108, +2999, -12962, -4416, +24, +360, +3011, -3485, -2819, -229, -1736, +410, -242, -574, -195, -1310, -2449, -114, -453, -1000, -245, +121, -272, -1376,
|
||||
+30704, +15809, -17499, +1266, -67, +2973, -1441, -5841, +12884, +3441, -12109, -5095, -636, +265, +3716, -2998, -3240, +129, -2153, -287, -24, -180, -492, -1366, -2616, -99, -271, -1307, -188, +298, -393, -1578,
|
||||
+31618, +16165, -17687, +1138, -966, +3162, -2242, -6103, +13031, +3994, -10855, -5814, -1132, -114, +4440, -2576, -3472, +441, -2571, -925, +179, +66, -731, -1305, -2901, +118, -240, -1556, +32, +256, -573, -1665,
|
||||
+32352, +16428, -17457, +790, -1672, +3290, -2962, -6399, +12571, +4836, -9536, -6362, -1498, -662, +5052, -2203, -3513, +550, -2849, -1412, +253, +166, -883, -1139, -3109, +166, -209, -1529, +21, +58, -646, -1719,
|
||||
+32443, +17279, -16999, +233, -2175, +3032, -2969, -7266, +11609, +6215, -8405, -6559, -1896, -1197, +5401, -1763, -3376, +385, -2990, -1689, +180, +133, -974, -846, -3214, -83, +9, -1520, -177, -60, -770, -1566,
|
||||
+31892, +18478, -16118, -275, -2655, +2351, -2206, -8781, +10331, +8020, -7513, -6312, -2325, -1753, +5424, -1170, -3047, -34, -3062, -1782, +143, -158, -877, -571, -3280, -291, -54, -1441, -346, -233, -674, -1187,
|
||||
+30789, +19780, -14759, -548, -3198, +1460, -1025, -10799, +8894, +10055, -6732, -5809, -2497, -2429, +5133, -346, -2659, -573, -3168, -1582, +53, -566, -705, -356, -3272, -629, -135, -1412, -494, -112, -434, -955,
|
||||
+29203, +20906, -12769, -646, -3914, +632, +128, -12834, +7097, +11981, -5813, -5212, -2227, -3391, +4539, +673, -2372, -1121, -3072, -1520, +50, -953, -749, -83, -3467, -767, -412, -1439, -216, +10, -266, -671,
|
||||
+27369, +21887, -10304, -719, -4689, +134, +1044, -14260, +4701, +13487, -4266, -4865, -1191, -4653, +3796, +1775, -2279, -1199, -3034, -1527, +71, -1028, -1358, +221, -3301, -1300, -376, -1263, +67, +149, +70, -544,
|
||||
+25668, +22491, -8130, -702, -4924, -592, +1193, -14383, +1825, +13879, -1753, -4990, +70, -5585, +2485, +3061, -2364, -1028, -2910, -1941, +216, -1133, -2116, +371, -3234, -1474, -105, -1358, +438, +510, +66, -745,
|
||||
+24445, +22594, -6916, -408, -4078, -1908, +266, -13241, -891, +13193, +1079, -5162, +987, -5936, +931, +4120, -2150, -1025, -2529, -2729, -156, -699, -2958, -77, -2635, -1480, +97, -1388, +718, +673, -84, -802,
|
||||
+24036, +21606, -6204, +627, -3020, -3027, -1363, -11604, -2945, +12413, +3083, -5038, +1938, -6484, +131, +4636, -1658, -795, -2484, -3507, -351, -682, -3613, +80, -2402, -1272, +354, -1476, +898, +717, -205, -856,
|
||||
+23746, +20456, -5957, +1984, -1938, -4319, -2729, -9544, -5054, +11531, +5123, -5779, +3222, -6434, -1058, +5531, -1261, -866, -2359, -3656, -1163, -839, -3784, +272, -1846, -1591, +565, -1292, +952, +517, -310, -562,
|
||||
+23960, +19174, -6448, +3094, -1039, -5368, -3542, -7116, -6317, +9363, +7378, -6843, +3456, -4600, -3042, +6646, -852, -1642, -1443, -3885, -1943, -945, -3873, +318, -958, -2243, +620, -863, +528, +698, -367, -469,
|
||||
+23567, +18274, -6810, +4250, -385, -6084, -3975, -5591, -6825, +6911, +9455, -6771, +1918, -2142, -4373, +6456, +835, -2708, -1024, -3507, -2457, -992, -4100, +133, -369, -2407, +311, -628, +321, +831, -178, -597,
|
||||
+23143, +16836, -6902, +5727, -531, -6291, -3459, -5161, -7193, +5338, +10494, -6386, +648, -1274, -4124, +6012, +1743, -2864, -1093, -2840, -2832, -626, -4269, -880, -83, -2116, +209, -691, +146, +839, -37, -502,
|
||||
+22711, +15714, -7208, +6876, -1112, -6813, -1895, -4170, -8096, +3464, +11809, -6438, -833, +596, -4557, +5103, +2952, -2724, -1144, -2460, -2916, -73, -4033, -2509, -346, -1558, +340, -324, -568, +509, +520, -161,
|
||||
+21883, +15259, -8430, +8064, -235, -8167, -638, -2887, -8285, +800, +12561, -5050, -2930, +2356, -4439, +2991, +4720, -2205, -1490, -1642, -3457, +613, -3421, -4138, -736, -1237, +241, +437, -924, -343, +1118, +203,
|
||||
+21336, +14054, -8898, +8815, +778, -8299, -1119, -1073, -7651, -2227, +13016, -3460, -4273, +3243, -3776, +1237, +5044, -803, -1471, -1297, -3268, +457, -2964, -4426, -1137, -1555, +51, +1032, -730, -630, +878, +351,
|
||||
+20364, +12658, -8776, +9749, +928, -8029, -658, -913, -7055, -3196, +11978, -2563, -4312, +3779, -3422, -39, +4857, -93, -856, -1070, -2919, +46, -2987, -3874, -1261, -1841, -597, +1113, -366, -282, +474, -132,
|
||||
+19013, +11105, -7802, +10307, +543, -7199, -275, -1181, -6482, -3416, +10634, -2108, -4042, +4151, -2777, -1409, +4761, +291, -1107, -73, -2791, -368, -2750, -3871, -721, -1726, -1380, +656, -107, +32, +532, -418,
|
||||
+17238, +9876, -6359, +10305, +398, -6315, -102, -1089, -5867, -3730, +9349, -1363, -3939, +4046, -1704, -2280, +4126, +804, -1450, +148, -1982, -710, -2585, -3457, -636, -1203, -1796, +107, -115, +106, +736, -435,
|
||||
+16850, +7680, -7300, +12520, +2285, -8479, -1087, +427, -4800, -1828, +6635, -3369, -2358, +3423, -1655, -892, +2571, -327, -160, +642, -662, +1201, -1048, -1605, +229, -1235, -1428, -365, -1650, -1331, -434, -718,
|
||||
+14445, +7248, -5479, +10890, +2224, -6676, -847, +20, -3992, -1849, +5544, -2552, -2301, +2914, -1338, -1107, +2267, -66, -274, +451, -432, +1011, -1109, -1445, +210, -1200, -1152, -150, -1229, -1064, -619, -638,
|
||||
+12262, +7034, -3826, +9064, +2556, -4912, -1000, -85, -3259, -1912, +4712, -1765, -2260, +2378, -779, -1142, +1866, +240, -211, +297, -362, +843, -852, -1395, +26, -936, -987, +115, -841, -918, -540, -612,
|
||||
+10302, +6772, -2608, +7425, +3047, -3580, -1144, +38, -2705, -1968, +3948, -1167, -2245, +1845, -376, -1032, +1522, +265, -101, +261, -453, +682, -692, -1289, -83, -615, -752, -59, -567, -670, -472, -618,
|
||||
+8655, +6443, -1690, +6216, +3422, -2584, -975, +289, -2316, -1951, +3369, -755, -2184, +1494, -28, -828, +1147, +375, +103, +99, -381, +549, -584, -1004, +111, -444, -718, -65, -432, -490, -423, -480,
|
||||
+7221, +6029, -1043, +5350, +3704, -1861, -720, +491, -2015, -1932, +2857, -505, -2070, +1231, +249, -749, +916, +588, -26, +2, -231, +492, -373, -773, +146, -331, -639, -153, -420, -446, -268, -366,
|
||||
+6149, +5337, -522, +4890, +3705, -1298, -409, +653, -1896, -1811, +2394, -329, -1930, +1021, +457, -665, +862, +483, -128, +133, -8, +453, -352, -564, +224, -355, -685, -251, -418, -327, -123, -232,
|
||||
+5347, +4865, -12, +4345, +3331, -784, +8, +681, -1713, -1654, +1950, -310, -1698, +1128, +488, -580, +778, +296, +168, +368, -71, +403, -167, -481, +0, -380, -642, -237, -238, -203, -161, -399,
|
||||
+4513, +4458, +327, +3862, +3291, -212, +50, +538, -1286, -1648, +1413, -6, -1274, +809, +432, -246, +709, +464, +342, +239, -48, +380, -170, -546, -158, -340, -484, -110, -208, -423, -383, -436,
|
||||
+3737, +4010, +796, +3404, +3194, +416, -10, +338, -902, -1429, +1024, +156, -1024, +609, +727, +264, +595, +355, +422, +205, -29, +258, -264, -566, -23, -135, -442, -273, -489, -465, -296, -300,
|
||||
+3244, +3768, +1128, +2910, +3135, +692, -253, +385, -416, -1327, +523, +399, -524, +860, +1068, +205, +374, +460, +341, +111, -88, +108, -72, -266, -80, -420, -614, -364, -338, -321, -247, -281,
|
||||
+2573, +3501, +1542, +2422, +3009, +997, -86, +399, -529, -1166, +615, +927, +3, +728, +933, +166, +369, +430, +133, +29, +88, +270, -37, -461, -485, -479, -438, -286, -266, -299, -341, -359,
|
||||
+2231, +3444, +1513, +2040, +3101, +1062, -319, +337, -154, -486, +938, +903, +105, +773, +781, +97, +163, +295, +372, +236, +56, -55, -435, -564, -350, -311, -370, -314, -370, -380, -309, -324,
|
||||
+2099, +3103, +1628, +2260, +2332, +675, +355, +998, +218, -292, +974, +821, +239, +834, +457, -122, +408, +649, +268, -133, -357, -207, -248, -398, -297, -330, -451, -420, -307, -346, -285, -262,
|
||||
+2122, +2791, +1338, +2074, +2185, +1299, +1098, +1022, +96, -224, +1143, +1002, +34, +360, +626, +337, +351, +217, -313, -387, -92, +1, -292, -456, -393, -443, -464, -373, -291, -249, -256, -321,
|
||||
+1707, +2474, +1550, +2358, +2684, +1380, +926, +1182, +372, +34, +972, +722, +127, +725, +656, -121, -188, -80, -126, -77, -58, -130, -419, -521, -423, -415, -422, -288, -194, -281, -292, -289,
|
||||
+2009, +3271, +2261, +2063, +1937, +1369, +1101, +993, +457, +278, +709, +981, +479, -169, -163, -155, -17, +78, -53, -120, -289, -340, -416, -495, -424, -327, -303, -303, -181, -220, -289, -318,
|
||||
+2008, +3310, +2283, +1883, +1850, +1562, +1336, +1209, +776, +362, +614, +893, +94, -536, -228, +27, +139, +104, -127, -295, -281, -260, -428, -460, -357, -327, -324, -261, -177, -196, -244, -322,
|
||||
+1917, +2862, +1700, +1658, +1732, +1613, +1699, +1958, +1364, +660, +516, +154, +109, -111, -309, -59, +186, +33, -209, -177, -238, -291, -369, -419, -336, -324, -384, -275, -151, -205, -230, -271,
|
||||
+2083, +2983, +1506, +1369, +1260, +1246, +1868, +2065, +1340, +757, +550, +543, +648, -21, -250, -120, -176, +2, -56, -272, -389, -249, -240, -367, -275, -212, -264, -298, -255, -207, -278, -316,
|
||||
+2198, +2902, +1108, +1182, +1319, +951, +937, +1441, +1654, +1337, +1100, +824, +681, +876, +211, -700, -323, -124, -65, -79, -310, -308, -251, -253, -245, -200, -273, -191, -287, -316, -203, -334,
|
||||
+2056, +2797, +1106, +1111, +1388, +1207, +805, +382, +604, +1281, +1542, +1132, +810, +896, +1118, +443, -493, -486, -254, -141, -40, -152, -378, -280, -153, -282, -256, -141, -244, -319, -313, -273,
|
||||
+2227, +2815, +713, +806, +1269, +1147, +860, +283, +11, +688, +1122, +928, +1193, +1393, +1389, +1011, +515, +126, -365, -592, -318, -110, -213, -289, -293, -274, -243, -88, -185, -280, -240, -271,
|
||||
+2487, +3077, +731, +1027, +1384, +982, +654, -128, +18, +996, +561, +73, +591, +932, +1479, +1270, +870, +925, +448, -201, -501, -563, -415, -115, -143, -320, -310, -120, -171, -247, -175, -287,
|
||||
+2775, +3186, +631, +1392, +1798, +1197, +294, -934, -91, +1380, +530, -194, +56, +369, +981, +652, +864, +1272, +870, +557, +177, -277, -677, -549, -265, -205, -167, -195, -284, -238, -143, -268,
|
||||
+3354, +3952, +622, +1159, +1616, +1212, +384, -1193, -171, +1340, +276, -317, +73, +202, +505, +358, +412, +812, +941, +759, +457, +303, +14, -361, -589, -473, -252, -41, -106, -338, -312, -210,
|
||||
+3851, +4360, +508, +1396, +1995, +1083, -118, -1646, +204, +1680, -168, -602, -109, +183, +637, +36, +22, +528, +357, +402, +649, +527, +382, +246, -154, -411, -536, -224, -139, -252, -213, -373,
|
||||
+4411, +4791, +385, +1660, +2324, +1023, -690, -2047, +660, +1766, -479, -607, -315, +44, +662, -70, -18, +284, +30, +175, +102, +352, +562, +305, +304, +207, -224, -238, -340, -387, -265, -275,
|
||||
+5196, +5589, +252, +1519, +2294, +877, -1040, -2105, +1073, +1563, -889, -523, -328, -3, +615, -267, -54, +275, -150, -65, -69, +83, +148, +190, +385, +349, +230, +269, -184, -470, -345, -462,
|
||||
+5718, +5975, +175, +2056, +2782, +433, -1979, -2126, +1813, +1397, -1262, -508, -449, +38, +582, -483, -40, +268, -347, -79, -259, -144, +146, -223, +11, +368, +235, +504, +304, -118, -274, -506,
|
||||
+6315, +6714, +139, +2135, +3020, +109, -2674, -1982, +2425, +978, -1604, -368, -505, +111, +586, -693, -117, +249, -464, -85, -325, -245, +4, -438, -62, +108, +23, +446, +291, +123, +139, -256,
|
||||
+6745, +7502, +262, +2112, +3265, -191, -3399, -1845, +3011, +575, -2029, -233, -551, +131, +609, -828, -184, +190, -609, -176, -413, -318, +53, -619, -305, +55, -89, +207, +130, -29, +147, +100,
|
||||
+7135, +8455, +528, +1753, +3383, -342, -3912, -1715, +3302, +347, -2377, -280, -478, +73, +666, -864, -309, +173, -675, -305, -523, -417, -31, -619, -370, -108, -188, +168, -8, -183, -48, -243,
|
||||
+7313, +9335, +990, +1537, +3442, -503, -4294, -1670, +3510, +231, -2617, -467, -433, +51, +676, -780, -520, +145, -610, -381, -642, -599, -117, -669, -413, -163, -232, +54, +96, -400, -473, -157,
|
||||
+7366, +10104, +1617, +1432, +3413, -641, -4433, -1789, +3563, +295, -2857, -581, -471, -47, +733, -715, -694, +95, -548, -428, -666, -773, -215, -762, -547, -237, -183, +203, -336, -503, -328, -397,
|
||||
+7627, +10884, +2189, +1075, +3085, -556, -4178, -2011, +3118, +500, -2883, -799, -373, -262, +585, -455, -843, -134, -419, -461, -781, -795, -264, -872, -798, -151, -218, -232, -138, -459, -588, -350,
|
||||
+7805, +11222, +3062, +1025, +2511, +140, -3881, -2575, +2792, +742, -2671, -862, -572, -376, +526, -340, -707, -443, -595, -287, -600, -934, -448, -730, -617, -528, -615, +39, -258, -504, -448, -459,
|
||||
+8363, +10906, +3309, +2010, +2235, +305, -3931, -2743, +2509, +616, -2212, -1029, -818, -300, +441, -402, -584, -720, -757, -88, -693, -1025, -498, -478, -772, -805, -578, -256, -196, -436, -534, -482,
|
||||
+9029, +10207, +3227, +3604, +2126, +318, -3990, -2699, +2282, -66, -1506, -870, -1243, -147, +313, -594, -347, -843, -960, -75, -980, -749, -429, -936, -470, -770, -924, -178, -239, -505, -518, -435,
|
||||
+9921, +9094, +2287, +6032, +2825, -665, -3976, -1942, +1634, -1240, -452, -499, -1858, -63, +175, -661, -141, -1007, -1221, -134, -966, -783, -874, -746, -300, -913, -822, -399, -257, -376, -363, -634,
|
||||
+11207, +8923, +714, +7384, +3504, -1787, -3331, -478, +667, -3182, +480, +632, -2340, -174, -41, -734, +254, -1209, -1563, +237, -1495, -1119, -374, -1179, -176, -742, -854, -326, -296, -187, -407, -889,
|
||||
+12500, +9128, -1225, +8120, +4706, -2957, -3096, +1429, +224, -5655, +633, +2334, -2476, -521, -246, -1021, +659, -1250, -1598, -102, -1942, -946, -536, -1243, -56, -809, -795, -9, -245, -516, -388, -591,
|
||||
+13676, +9715, -3224, +8146, +6300, -3786, -3252, +3385, +497, -7984, -273, +4084, -1795, -1036, -439, -1428, +900, -738, -2169, -270, -1884, -1560, -244, -1157, -225, -702, -726, +327, -337, -781, -147, -433,
|
||||
+15154, +10710, -5567, +6975, +8141, -3612, -4028, +4575, +1224, -9451, -1863, +5048, -504, -1304, -849, -1887, +1317, -802, -2679, +65, -2243, -1967, -192, -1025, -170, -751, -680, +394, -331, -789, -111, -452,
|
||||
+16751, +11590, -7670, +5697, +9423, -3002, -4671, +5673, +1938, -10472, -3508, +5316, +1125, -1098, -1562, -2113, +1531, -1067, -2689, -22, -2225, -2260, -408, -719, -88, -730, -829, +416, -248, -657, -207, -430,
|
||||
+19048, +11932, -9850, +4534, +10090, -1984, -5054, +6461, +2293, -11027, -4690, +4999, +2637, -594, -2197, -2457, +1788, -1314, -2837, +89, -2336, -2296, -497, -623, +34, -680, -1066, +461, -55, -678, -251, -446,
|
||||
+21615, +12285, -12393, +3218, +10447, -513, -5263, +6448, +2499, -11072, -5490, +4213, +3638, +192, -2622, -3085, +2128, -1593, -3108, +258, -2535, -2078, -721, -584, +167, -802, -1230, +548, +77, -824, -300, -503,
|
||||
+23814, +13115, -14900, +2298, +10402, +898, -5101, +6133, +3297, -10978, -6160, +3330, +4213, +1402, -2845, -3633, +2406, -1782, -3197, +506, -2620, -1975, -705, -585, +213, -896, -1169, +725, -33, -930, -208, -501,
|
||||
+26386, +12827, -16969, +2278, +9703, +1341, -4735, +5967, +4345, -11169, -7039, +2751, +4328, +2440, -3053, -3808, +2333, -2300, -2829, +717, -2947, -2030, -466, -759, +120, -952, -975, +828, -420, -898, -159, -497,
|
||||
+27944, +13492, -18792, +2616, +8679, +1183, -4343, +5611, +6445, -11341, -8610, +2448, +4449, +2910, -2638, -3722, +1665, -2447, -2294, +737, -3191, -2075, -286, -1008, +16, -802, -857, +864, -755, -842, -70, -604,
|
||||
+29685, +13246, -19821, +3525, +7289, +438, -4363, +5714, +8745, -11618, -10243, +2318, +4494, +2830, -1737, -3623, +798, -2252, -1923, +676, -3494, -1846, -281, -1396, -10, -574, -760, +810, -964, -876, +89, -884,
|
||||
+30876, +13227, -20231, +4464, +5889, -395, -4997, +6035, +11190, -11731, -11571, +2002, +4359, +2564, -389, -3809, +115, -1644, -2030, +671, -3672, -1473, -429, -1750, -81, -276, -628, +609, -946, -950, +127, -1298,
|
||||
+31278, +13828, -20217, +5005, +4867, -1003, -6198, +6112, +13378, -11330, -12204, +1134, +4093, +2243, +984, -3911, -507, -785, -2404, +550, -3517, -1127, -734, -1985, -167, -11, -527, +311, -626, -1201, -142, -1426,
|
||||
+31763, +14606, -20213, +4922, +4300, -1334, -7821, +5934, +15019, -10488, -12296, -244, +3894, +2145, +1899, -3668, -996, -217, -2645, +278, -3186, -960, -1050, -2098, -246, +125, -509, +271, -479, -1663, -297, -1411,
|
||||
+32059, +15063, -19624, +4534, +3996, -1550, -9300, +5401, +15706, -8935, -11963, -1825, +3576, +2337, +2148, -3207, -1061, -200, -2557, +23, -2815, -964, -1297, -2112, -372, +106, -371, +213, -866, -1642, -555, -1453,
|
||||
+31594, +16148, -18709, +3873, +3953, -1965, -10020, +3854, +16002, -6585, -11621, -3362, +3109, +2803, +1915, -2572, -712, -591, -2348, +118, -2607, -1103, -1413, -2224, -397, +185, -559, -36, -1026, -1584, -771, -1168,
|
||||
+30561, +17638, -17451, +3091, +3826, -2310, -9959, +1289, +16030, -3803, -11272, -4403, +2328, +3336, +1431, -1843, -11, -1291, -1874, +345, -2491, -1351, -1564, -2198, -272, -81, -1106, +216, -1299, -1439, -527, -1224,
|
||||
+29054, +19377, -15810, +1898, +3337, -2040, -9228, -2236, +15567, -882, -10760, -4753, +1128, +3442, +1193, -1335, +949, -1929, -1501, +721, -2539, -1679, -1649, -1976, -762, -420, -1351, +363, -1271, -1184, -487, -1395,
|
||||
+27602, +19984, -13330, +1384, +2220, -1553, -8967, -5440, +14956, +1794, -10257, -4554, -131, +2570, +2016, -1408, +1844, -1852, -1851, +1473, -2793, -1890, -1630, -2378, -1270, -515, -1540, +663, -952, -1427, -261, -1350,
|
||||
+25630, +20290, -10249, +1324, +1107, -1114, -8918, -8485, +14115, +4665, -9857, -4277, -756, +606, +3451, -1301, +1865, -565, -2709, +1877, -2367, -2459, -1746, -2677, -1920, -340, -1413, +665, -508, -1675, -66, -1466,
|
||||
+23903, +20683, -7286, +510, -377, -53, -7840, -11202, +11907, +7374, -9146, -4087, -105, -1982, +4052, -56, +1078, +860, -2851, +1241, -1622, -2794, -2100, -2674, -2293, -321, -1039, +386, -96, -1780, -277, -1191,
|
||||
+22823, +20723, -6390, +1262, +38, -1708, -6903, -11540, +8654, +9407, -7731, -4726, +1287, -3835, +3356, +1929, +303, +1232, -2157, +96, -909, -2590, -2708, -1999, -2763, -486, -647, +74, -134, -1612, -437, -1074,
|
||||
+23286, +19705, -6984, +2708, +768, -3874, -6807, -9892, +5577, +9767, -5818, -5461, +2601, -4494, +2384, +2776, +168, +931, -1602, -159, -1262, -1698, -2885, -1466, -2698, -1301, -450, -206, -5, -1620, -620, -969,
|
||||
+23121, +19255, -7571, +3875, +1563, -5614, -6214, -8564, +2641, +9601, -3111, -6567, +3743, -4320, +945, +3692, -1043, +1590, -1282, -840, -479, -978, -2698, -1087, -2537, -2252, -520, -532, +376, -1513, -1259, -735,
|
||||
+23895, +17231, -7926, +5603, +1022, -6360, -5559, -7729, +248, +9659, -1110, -7381, +4032, -2981, -753, +3497, -675, +212, -226, -663, -11, -138, -2841, -1009, -2052, -2616, -1508, -419, +202, -1307, -1387, -864,
|
||||
+24342, +16471, -9991, +7124, +2357, -8386, -5329, -5315, -1440, +7468, +1850, -7622, +3025, -1191, -1868, +2925, -544, -837, +462, +724, -295, +355, -2494, -1379, -1397, -2680, -2066, -975, -223, -1077, -799, -950,
|
||||
+24670, +15431, -12280, +9290, +3619, -10800, -4710, -2736, -2869, +4919, +4375, -7414, +1744, +298, -2787, +2517, -329, -1185, +786, +1117, +234, +534, -2350, -1334, -1274, -2503, -2002, -1594, -1255, -755, -99, -851,
|
||||
+25053, +13472, -13783, +11903, +3737, -12350, -3755, -973, -3561, +2410, +5792, -6487, +903, +639, -3500, +2947, +120, -1823, +1427, +635, +328, +1654, -2795, -1081, -1079, -2818, -1321, -1807, -2368, -781, +236, -570,
|
||||
+25116, +10992, -14060, +14345, +2919, -12891, -2578, +298, -4831, +849, +7344, -6355, -113, +1687, -3785, +2243, +1525, -1852, +673, +891, +28, +1939, -1939, -1636, -642, -2710, -1531, -1027, -2946, -1438, +260, -246,
|
||||
+23985, +9052, -12782, +15373, +1674, -11878, -1468, -66, -5434, +491, +7676, -6469, -622, +2840, -3942, +1270, +2660, -1561, +29, +815, -200, +1925, -1493, -1644, -301, -2510, -1767, -674, -2584, -1874, -316, -165,
|
||||
+21931, +7984, -10773, +14942, +1323, -10330, -1496, -41, -5153, -560, +7563, -5510, -1367, +3202, -3067, +472, +2598, -1083, +280, +328, -550, +2171, -1750, -1359, +265, -2505, -1617, -565, -2257, -1696, -689, -545,
|
||||
+19430, +7714, -9051, +13883, +1898, -9550, -1479, +550, -5119, -1546, +7412, -4342, -2191, +3447, -2123, -382, +2504, -635, +149, +475, -754, +1639, -1244, -1582, +373, -1789, -1679, -351, -2065, -1520, -554, -754,
|
||||
+15748, +5880, -5425, +14058, +1054, -9150, +6, +395, -3696, +26, +2379, -3599, +1707, +2155, -2493, -381, +1177, -628, -908, +221, -185, +13, -490, +744, +822, +168, +287, -448, -1045, -444, -892, -1472,
|
||||
+13423, +5793, -3949, +12100, +1504, -7414, -200, +63, -3202, +36, +2192, -2942, +1203, +1913, -1964, -650, +802, -427, -791, -12, -102, +329, -386, +362, +832, +203, -6, -415, -837, -549, -728, -965,
|
||||
+11547, +5785, -2873, +10302, +2118, -6063, -463, +55, -2706, -44, +2080, -2250, +641, +1766, -1389, -907, +655, -241, -693, -30, +34, +406, -343, +364, +574, +40, +171, -246, -795, -541, -534, -664,
|
||||
+9992, +5645, -2205, +8952, +2516, -5038, -463, +97, -2247, -98, +1995, -1860, +247, +1695, -1144, -964, +569, -79, -605, +22, +220, +235, -242, +317, +304, +54, +320, -69, -720, -432, -411, -602,
|
||||
+8782, +5267, -1688, +7925, +2586, -4032, -444, +186, -1797, -191, +1866, -1605, +27, +1498, -942, -933, +555, +32, -524, +199, +141, +118, -129, +149, +324, +142, +325, +78, -560, -385, -344, -545,
|
||||
+7729, +4882, -1177, +6873, +2650, -3039, -407, +340, -1509, -165, +1693, -1465, -61, +1352, -781, -864, +627, +111, -305, +152, +24, +234, -129, +182, +391, +215, +338, +94, -398, -277, -266, -463,
|
||||
+6682, +4405, -731, +6123, +2845, -2298, -387, +459, -1188, -176, +1393, -1251, -73, +1145, -660, -560, +620, +101, -161, +95, +165, +308, -117, +224, +453, +233, +340, +124, -276, -83, -284, -652,
|
||||
+5690, +4114, -370, +5337, +2959, -1597, -302, +540, -969, -272, +1211, -1020, -123, +962, -388, -419, +496, +293, -68, +198, +277, +243, -1, +258, +446, +244, +316, +224, -197, -287, -538, -753,
|
||||
+4886, +3783, -77, +4739, +3009, -1004, -171, +567, -808, -296, +1071, -732, -150, +762, -143, -243, +583, +495, +70, +295, +285, +282, +109, +300, +419, +303, +318, -41, -410, -429, -543, -696,
|
||||
+4226, +3500, +214, +4230, +2888, -619, +78, +571, -807, -209, +1096, -674, -362, +872, +202, -45, +765, +519, +142, +420, +299, +326, +177, +298, +271, +19, +43, -216, -432, -470, -647, -770,
|
||||
+3932, +3487, +332, +3583, +2646, -337, +285, +627, -784, -249, +992, -484, -225, +1185, +515, -8, +833, +683, +354, +372, +256, +357, +26, -114, -52, -13, -48, -275, -631, -669, -560, -678,
|
||||
+3417, +3033, +572, +3583, +2497, -132, +512, +448, -821, -41, +1094, -215, +63, +1208, +613, +421, +1026, +661, +269, +268, +157, -77, -316, -230, -50, -15, -270, -450, -631, -506, -489, -682,
|
||||
+3181, +2995, +715, +3281, +2345, -67, +347, +573, -324, +109, +1136, +26, +360, +1541, +983, +492, +841, +521, -21, -138, -249, -144, -314, -277, -62, -239, -335, -379, -509, -456, -497, -624,
|
||||
+2727, +2772, +1072, +2985, +1995, +392, +618, +698, +14, +104, +1230, +616, +773, +1489, +881, +385, +451, -79, -396, -153, -251, -293, -476, -335, -58, -202, -314, -426, -485, -422, -544, -580,
|
||||
+2494, +2557, +1043, +2809, +2364, +870, +612, +794, +496, +543, +1308, +960, +905, +1098, +463, -159, -22, -97, -245, -365, -543, -373, -259, -109, -161, -351, -340, -303, -434, -540, -495, -424,
|
||||
+2244, +2930, +1654, +2496, +2296, +1063, +990, +1335, +682, +721, +1328, +513, +346, +642, +45, -321, -153, -280, -469, -425, -401, -290, -203, -148, -250, -401, -344, -391, -436, -433, -426, -380,
|
||||
+2037, +3030, +1906, +2584, +3062, +1893, +990, +1134, +771, +385, +555, +134, +140, +441, -13, -448, -353, -397, -487, -345, -327, -238, -229, -306, -339, -347, -307, -358, -440, -470, -365, -304,
|
||||
+2260, +3620, +2531, +2997, +2841, +1693, +1371, +1050, +54, -313, +437, +310, -186, +172, -15, -693, -347, -145, -477, -380, -271, -292, -232, -289, -368, -327, -359, -335, -337, -420, -362, -300,
|
||||
+2676, +4646, +3139, +2421, +2169, +1461, +1102, +750, +196, +85, +103, -264, -85, +79, -270, -444, -278, -319, -366, -267, -356, -287, -310, -325, -320, -352, -353, -348, -336, -368, -283, -304,
|
||||
+2949, +4690, +2841, +1992, +1689, +1410, +1437, +860, +277, +660, +273, -352, -345, -179, +121, -193, -595, -313, -69, -302, -301, -297, -388, -283, -359, -329, -293, -304, -317, -316, -248, -264,
|
||||
+2663, +4197, +2446, +1659, +1599, +1195, +1150, +1390, +834, +702, +922, +74, -262, -12, -178, -353, -146, -141, -372, -189, -146, -406, -452, -309, -320, -299, -251, -248, -234, -286, -278, -279,
|
||||
+2398, +3447, +2003, +1730, +1358, +984, +1031, +668, +683, +1466, +1326, +833, +547, +62, +124, -145, -512, -263, -44, -260, -496, -309, -241, -380, -321, -210, -197, -195, -288, -327, -348, -283,
|
||||
+1987, +2518, +1256, +1700, +1770, +1374, +486, -161, +666, +1239, +1117, +1441, +1412, +1138, +952, +102, -154, -108, -471, -390, -130, -296, -423, -224, -149, -219, -273, -144, -187, -306, -316, -312,
|
||||
+2277, +2839, +857, +1089, +1531, +1252, +447, -170, +485, +946, +625, +786, +1274, +1596, +1572, +803, +425, +213, -154, -308, -514, -316, -104, -287, -376, -112, -81, -229, -298, -346, -243, -269,
|
||||
+2475, +3091, +1057, +1202, +1523, +1181, +155, -419, +779, +1083, +35, +243, +607, +800, +1330, +1039, +902, +962, +366, -99, -203, -378, -433, -305, -177, -196, -314, -134, -130, -427, -342, -186,
|
||||
+2867, +3436, +954, +1406, +1896, +1116, -228, -668, +1005, +1052, -200, +160, +322, +441, +627, +249, +723, +1109, +691, +570, +250, -239, -146, -317, -437, -152, -136, -255, -367, -288, -235, -306,
|
||||
+3223, +4037, +1059, +1327, +1971, +1123, -496, -724, +1262, +822, -504, +196, +267, +346, +542, -168, +79, +604, +516, +608, +511, +379, +188, -138, -157, -106, -291, -239, -240, -438, -390, -237,
|
||||
+3604, +4513, +1093, +1460, +2232, +986, -1011, -692, +1601, +582, -689, +154, +137, +264, +549, -231, -112, +308, -5, +126, +288, +386, +454, +334, +190, +65, -9, -169, -440, -448, -309, -360,
|
||||
+4214, +5204, +1001, +1333, +2363, +811, -1317, -468, +1657, +218, -774, +195, +54, +193, +477, -310, -143, +220, -205, -91, -167, -47, +273, +245, +485, +588, +199, -41, -178, -454, -469, -319,
|
||||
+4699, +5772, +1037, +1391, +2580, +571, -1811, -137, +1930, -248, -876, +278, -102, +158, +529, -367, -232, +173, -250, -176, -332, -250, -145, -125, +369, +578, +501, +334, -24, -230, -185, -365,
|
||||
+5288, +6343, +926, +1516, +2837, +116, -2274, +403, +2022, -767, -921, +321, -140, +29, +469, -385, -290, +151, -299, -257, -451, -381, -272, -339, +52, +314, +302, +289, +305, +49, -70, -194,
|
||||
+5726, +6820, +1096, +1667, +3026, -179, -2850, +907, +2339, -1355, -1017, +450, -163, -66, +415, -378, -412, +166, -245, -345, -541, -415, -353, -452, -62, +81, +100, +97, +117, +54, +153, +24,
|
||||
+6153, +7423, +1241, +1705, +3192, -342, -3363, +1287, +2593, -1875, -1019, +557, -240, -122, +319, -290, -434, +2, -201, -386, -582, -375, -458, -561, -160, +6, +81, -90, -141, -171, +10, +136,
|
||||
+6828, +8181, +890, +1848, +3361, -805, -3382, +1527, +2488, -2165, -973, +617, -316, -246, +308, -188, -549, -125, -176, -412, -641, -381, -560, -633, -100, -94, -15, -180, -313, -244, -131, -157,
|
||||
+7339, +8745, +841, +2086, +3460, -1152, -3508, +1614, +2597, -2420, -1103, +713, -354, -350, +308, -133, -681, -241, -127, -375, -784, -526, -527, -641, -141, -117, -177, -223, -325, -365, -249, -300,
|
||||
+7574, +9152, +1067, +2490, +3582, -1504, -3603, +1572, +2713, -2475, -1389, +742, -241, -424, +146, -29, -689, -412, -49, -482, -922, -508, -528, -656, -326, -236, +0, -242, -494, -465, -250, -363,
|
||||
+7771, +9477, +1527, +2680, +3445, -1316, -3581, +1119, +2776, -2355, -1714, +883, -172, -648, +99, -15, -445, -536, -388, -395, -960, -596, -496, -760, -479, -221, +19, -221, -514, -524, -422, -579,
|
||||
+8021, +9527, +2130, +2911, +3042, -704, -3474, +429, +2652, -2057, -1809, +694, -37, -769, -100, +184, -247, -761, -609, -325, -1000, -680, -746, -736, -332, -408, -31, -128, -468, -729, -608, -586,
|
||||
+8404, +9096, +2503, +3785, +2807, -578, -3480, +263, +2211, -1959, -1522, +174, -65, -508, -392, +128, +9, -898, -776, -193, -1245, -945, -832, -687, -337, -524, -93, -26, -595, -926, -547, -887,
|
||||
+8807, +8295, +2417, +5558, +3298, -1393, -3611, +1274, +1418, -2498, -541, -286, -448, +137, -733, -107, +472, -919, -800, -132, -1516, -1020, -876, -819, -258, -573, -75, -222, -470, -870, -816, -827,
|
||||
+9721, +7750, +1320, +7320, +3992, -2723, -3178, +2422, -20, -3129, +726, -465, -1243, +477, -680, -418, +820, -960, -919, -87, -1553, -1159, -1230, -839, -90, -743, -335, -154, -533, -893, -664, -1012,
|
||||
+10870, +7707, -280, +8285, +5199, -3799, -2870, +3710, -1420, -4018, +2054, -220, -2214, +514, -188, -855, +1016, -762, -1123, +24, -1500, -1380, -1443, -763, -169, -955, -493, -100, -557, -806, -616, -1159,
|
||||
+11833, +8327, -2134, +8341, +6953, -4401, -2931, +5077, -2393, -5396, +3185, +626, -3054, -50, +496, -988, +898, -338, -1369, +122, -1461, -1366, -1542, -1049, -218, -1029, -640, -181, -361, -866, -501, -1048,
|
||||
+12829, +9031, -3811, +7670, +8588, -4509, -3175, +6408, -3118, -7036, +3841, +1817, -3527, -1043, +839, -699, +618, +2, -1465, -51, -1246, -1421, -1712, -1253, -467, -1107, -577, -354, -342, -807, -350, -891,
|
||||
+14193, +9389, -5197, +6872, +9549, -4273, -3139, +7727, -3898, -8441, +3999, +3031, -3444, -2122, +727, -197, +556, +113, -1327, -318, -1040, -1564, -1813, -1380, -747, -1085, -601, -339, -469, -645, -199, -888,
|
||||
+15661, +9657, -6466, +6233, +9751, -3871, -2723, +8959, -4623, -9557, +3687, +4006, -2825, -3063, +218, +188, +872, +40, -1085, -476, -1213, -1459, -1966, -1538, -758, -1196, -697, -106, -518, -710, -84, -846,
|
||||
+17612, +9338, -7642, +6082, +9245, -3958, -1634, +10145, -5734, -10179, +3233, +4461, -2053, -3596, -499, +236, +1471, -53, -824, -783, -1511, -1205, -2322, -1376, -936, -1374, -531, +50, -558, -860, -125, -756,
|
||||
+19463, +9219, -8893, +6261, +8413, -4281, -363, +11374, -6530, -10787, +2801, +4644, -1342, -3682, -1194, -39, +2157, +139, -767, -1072, -1682, -1101, -2364, -1296, -1186, -1329, -395, +235, -591, -1146, -127, -554,
|
||||
+21650, +9391, -10922, +6081, +8229, -4220, +202, +11812, -6628, -11097, +2478, +4559, -1182, -3433, -1549, -554, +2784, +461, -1205, -1027, -1704, -1258, -2251, -1431, -1146, -1205, -447, +400, -669, -1391, -60, -370,
|
||||
+23618, +9863, -13021, +6004, +8047, -4224, +416, +12157, -6101, -11654, +2261, +4560, -1406, -3057, -1488, -1343, +3208, +953, -1820, -705, -1697, -1485, -2065, -1531, -1035, -1118, -452, +413, -760, -1496, +104, -350,
|
||||
+25507, +10091, -14633, +6037, +7728, -4437, +358, +12536, -5172, -12313, +2012, +4630, -1785, -2622, -1212, -2223, +3337, +1463, -2227, -360, -1728, -1658, -1788, -1625, -1024, -963, -484, +363, -873, -1530, +387, -597,
|
||||
+26627, +10861, -15853, +5976, +7293, -4687, -371, +13070, -3740, -13126, +1550, +4641, -1970, -2334, -931, -3002, +3015, +1972, -2297, -262, -1622, -1706, -1631, -1718, -1043, -847, -523, +200, -913, -1491, +419, -863,
|
||||
+27529, +11441, -16338, +5805, +6853, -5062, -1537, +13789, -2342, -13609, +1025, +4352, -1778, -2113, -836, -3461, +2445, +2244, -1905, -447, -1343, -1486, -1806, -1634, -1063, -761, -595, -38, -809, -1509, +121, -852,
|
||||
+28224, +11700, -16026, +5571, +6480, -5603, -2945, +14554, -1154, -13550, +445, +3703, -1208, -1832, -1081, -3648, +1918, +2132, -1094, -755, -1071, -949, -2221, -1385, -1073, -728, -775, -144, -846, -1640, -17, -888,
|
||||
+28214, +12317, -15132, +5336, +6093, -6385, -4398, +15063, +169, -13141, -349, +2865, -289, -1493, -1675, -3631, +1627, +1567, -67, -871, -1083, -137, -2567, -1204, -1005, -901, -818, -487, -1098, -1321, -264, -1047,
|
||||
+27674, +13198, -13952, +5049, +5725, -7019, -5818, +14656, +1734, -12326, -1241, +1915, +642, -1155, -2395, -3373, +1425, +664, +785, -409, -1488, +642, -2474, -1372, -798, -1009, -1376, -899, -968, -1199, -318, -1143,
|
||||
+26652, +14012, -12267, +5200, +5059, -7687, -7096, +13622, +3659, -11441, -2232, +1136, +1363, -745, -2920, -3117, +1275, -215, +1173, +578, -1926, +1018, -1813, -1727, -552, -1508, -1936, -882, -1218, -880, -117, -1274,
|
||||
+25476, +14976, -10645, +5041, +4465, -7268, -8563, +11373, +5951, -10470, -2967, +695, +1268, -121, -2916, -3040, +1232, -1049, +1136, +1691, -1847, +783, -939, -1782, -1189, -1393, -2259, -1210, -1263, -527, +246, -1345,
|
||||
+24418, +15887, -9483, +5106, +3650, -6572, -9308, +8066, +7947, -9122, -3698, +546, +799, +234, -2298, -3040, +979, -1401, +660, +2460, -1414, +581, -594, -1924, -1571, -1185, -2342, -1526, -1293, -276, +512, -1388,
|
||||
+23795, +16122, -8471, +5677, +2738, -6335, -9272, +4879, +8930, -7283, -4533, +587, +584, -12, -1140, -3045, +596, -1168, -297, +2828, -664, +171, -697, -1636, -1755, -862, -2122, -1839, -1085, -590, +469, -1065,
|
||||
+23181, +16390, -7741, +6442, +2203, -6740, -8434, +1898, +8933, -4752, -5617, +579, +1155, -849, +75, -2508, -62, -548, -1446, +2589, +243, -427, -620, -1078, -1599, -627, -1538, -1798, -1522, -1117, +586, -608,
|
||||
+22030, +16813, -6552, +6365, +1905, -6491, -7923, -1054, +8742, -2377, -6611, +561, +1892, -1729, +1053, -1623, -1078, +90, -2143, +1121, +1073, -290, -801, -281, -1302, -213, -1096, -1925, -1798, -1686, +156, -224,
|
||||
+21251, +16564, -5227, +6101, +1298, -5618, -7958, -3289, +8275, -752, -6864, +468, +2279, -1970, +1851, -1720, -1502, +720, -2997, -87, +1066, +346, -609, +374, -840, -207, -612, -1924, -1832, -2459, -669, -2,
|
||||
+21059, +15707, -4300, +6487, +399, -4731, -7511, -5182, +7533, +993, -7053, +282, +3472, -2462, +1927, -1518, -1924, +1110, -3285, -499, +296, +615, +989, +279, -802, +498, -387, -1895, -1824, -2715, -1623, -344,
|
||||
+21308, +14470, -4242, +7387, -252, -4583, -6956, -6093, +6238, +2376, -6555, -258, +4580, -2860, +1045, -858, -2358, +1013, -2617, -1140, +487, +118, +1239, +1477, -1144, +905, +15, -2196, -1670, -2549, -2403, -914,
|
||||
+21749, +13551, -6010, +9423, +237, -6449, -5831, -5696, +4659, +3069, -5379, -988, +5203, -3101, -229, +148, -2474, +413, -1565, -777, +245, -263, +270, +2911, -521, +46, +1169, -2577, -2021, -1583, -2762, -1790,
|
||||
+22949, +11670, -8631, +12918, +409, -9740, -4092, -3756, +2385, +3036, -3324, -2593, +5421, -2472, -2044, +991, -1723, -438, -884, +258, -444, -546, -80, +2348, +873, +112, +640, -1839, -2303, -1429, -2266, -2374,
|
||||
+23912, +9195, -9740, +15651, -753, -10898, -2348, -2548, +736, +2645, -1865, -3420, +5193, -2092, -2914, +1332, -608, -827, -805, +690, -265, -735, -758, +2026, +1239, +685, +402, -1265, -2108, -2026, -1548, -2057,
|
||||
+24116, +7253, -10354, +17453, -1244, -12053, -838, -452, -1755, +1608, +585, -4398, +4021, -759, -3062, +841, +208, -518, -792, +316, -185, -122, -1534, +1707, +1529, +201, +1161, -889, -2381, -1596, -1536, -1868,
|
||||
+22899, +6009, -9723, +18156, -1387, -12297, +387, +197, -3319, +1403, +1627, -5089, +3452, +505, -3305, +713, +563, -709, -310, -26, -425, +286, -1418, +1157, +1256, +363, +1114, -493, -2226, -1184, -1308, -2261,
|
||||
+20564, +5546, -8226, +17550, -828, -11490, +294, +435, -3523, +690, +1926, -4747, +2908, +1152, -2973, +467, +625, -707, -390, +101, -449, +40, -906, +959, +763, +546, +863, -551, -1476, -956, -1217, -2071,
|
||||
+18013, +5812, -6919, +15896, +403, -10591, +67, +717, -3782, +91, +2336, -4162, +2130, +1919, -2779, -103, +1086, -691, -833, +297, -250, -202, -650, +1014, +731, +166, +703, -484, -1293, -477, -1156, -1837,
|
||||
+15954, +7279, -4696, +11257, -415, -7760, +15, -732, -924, +300, -779, -1111, +2316, +31, -1667, -359, +362, -476, -1406, +77, +201, +160, +31, +184, +33, +618, +402, -142, -19, -131, -351, -177,
|
||||
+13494, +6705, -2870, +10505, -334, -6612, +28, -1001, -670, +405, -783, -1035, +2308, +178, -1639, -390, +219, -411, -1192, +78, +48, +72, +135, +215, +200, +619, +296, -179, +63, -49, -474, -174,
|
||||
+11237, +6344, -1097, +9098, -68, -4982, -506, -1321, -184, +563, -966, -831, +2204, +226, -1398, -487, +210, -400, -1067, +109, +7, -13, +137, +290, +364, +506, +81, -34, +85, -87, -211, -95,
|
||||
+9435, +6226, -171, +7621, +609, -3889, -842, -1290, +79, +593, -877, -638, +1778, +372, -1115, -612, +133, -304, -919, +84, +28, -9, +49, +403, +518, +117, +63, +315, +9, -189, +148, +127,
|
||||
+8281, +6134, -52, +6557, +1253, -3449, -792, -804, +3, +410, -398, -491, +1170, +585, -801, -816, +97, -92, -760, -8, +125, +10, +14, +591, +350, +20, +334, +355, -11, +73, +387, +50,
|
||||
+7625, +5926, -212, +5732, +1440, -2973, -409, -538, -153, +402, +53, -528, +814, +714, -773, -751, +187, -25, -685, +71, +194, -126, +301, +656, +141, +177, +495, +460, +123, +277, +255, -206,
|
||||
+6929, +5539, -213, +5156, +1489, -2470, -128, -421, -216, +512, +263, -626, +604, +666, -598, -609, +135, +2, -569, +170, +101, +124, +603, +290, +211, +558, +624, +396, +73, +189, -68, -300,
|
||||
+6185, +4980, +12, +4844, +1476, -2007, +5, -218, -48, +475, +186, -579, +652, +583, -532, -454, +163, -44, -351, +323, +185, +454, +519, +323, +554, +596, +513, +149, -59, +27, -156, -301,
|
||||
+5578, +4710, +139, +4160, +1511, -1429, +247, -167, -134, +535, +301, -478, +484, +512, -357, -355, +143, +139, +9, +323, +460, +774, +454, +456, +460, +265, +311, +29, -141, -56, -157, -425,
|
||||
+4834, +4247, +381, +3890, +1667, -1077, +239, -52, +64, +515, +186, -374, +470, +446, -204, -178, +260, +402, +264, +582, +786, +717, +277, +144, +133, +174, +219, +36, -212, -220, -241, -491,
|
||||
+4111, +3866, +739, +3569, +1573, -633, +462, -99, +98, +570, +132, -353, +509, +570, +1, -45, +535, +857, +514, +702, +653, +127, -67, +94, +33, +142, +132, -176, -297, -218, -361, -612,
|
||||
+3730, +3751, +749, +2995, +1740, -73, +398, -128, +157, +562, +322, -106, +526, +653, +398, +535, +911, +896, +331, +268, +196, +17, -50, +13, -44, +14, +4, -239, -323, -300, -491, -605,
|
||||
+2892, +3209, +1362, +3059, +1608, +182, +476, -76, +432, +661, +242, +160, +1034, +1084, +626, +638, +748, +381, -9, +164, +81, +56, -148, -220, -132, -95, -61, -252, -388, -412, -527, -492,
|
||||
+2752, +3422, +1354, +2301, +1710, +560, +500, +0, +522, +1109, +816, +680, +1165, +1033, +440, -19, +152, +356, +205, +72, -219, -249, -230, -203, -210, -180, -256, -370, -297, -417, -460, -470,
|
||||
+2213, +3015, +1710, +2495, +1858, +590, +641, +619, +1215, +1482, +1045, +756, +541, +266, +10, +87, +388, +325, -149, -273, -65, -313, -465, -315, -243, -222, -297, -239, -314, -374, -410, -472,
|
||||
+2378, +3632, +1949, +1796, +1538, +1419, +1931, +1407, +1042, +906, +324, -55, +57, +281, +416, +73, -141, +104, -125, -338, -346, -567, -456, -178, -236, -293, -193, -168, -347, -459, -409, -412,
|
||||
+2533, +3615, +2312, +2871, +2388, +1873, +1924, +743, -6, +118, +67, +58, +149, +131, +262, -115, -211, -1, -357, -465, -469, -597, -378, -114, -162, -284, -237, -201, -345, -426, -423, -455,
|
||||
+2942, +4615, +3780, +3595, +1951, +1001, +577, -3, -9, +178, +100, -150, -79, +35, +232, -191, -343, -241, -527, -515, -469, -366, -285, -260, -253, -164, -168, -307, -405, -445, -401, -430,
|
||||
+3532, +6354, +4764, +2112, +192, +502, +1060, +740, -280, -481, -6, +64, -3, -232, +35, -123, -425, -424, -500, -331, -403, -411, -380, -233, -195, -219, -156, -328, -390, -471, -421, -332,
|
||||
+3754, +6378, +3302, +1176, +770, +1524, +1808, +405, -520, -9, +89, -401, +38, -134, -211, -179, -439, -279, -348, -439, -354, -411, -499, -252, -186, -273, -220, -306, -347, -364, -422, -391,
|
||||
+2291, +3472, +1957, +1996, +2277, +2297, +2104, +987, +507, +706, +356, -152, -298, -91, -5, -385, -390, -196, -226, -195, -416, -447, -287, -389, -410, -244, -292, -350, -178, -230, -400, -417,
|
||||
+1819, +2518, +1138, +1323, +2016, +2067, +1584, +1227, +1540, +1527, +1077, +599, +319, +222, -133, -344, -224, -354, -392, -98, -287, -313, -172, -348, -336, -273, -365, -452, -322, -244, -281, -244,
|
||||
+1991, +2736, +1265, +1355, +1696, +1270, +711, +599, +1244, +1618, +1273, +1004, +935, +768, +344, -110, -219, -251, -264, -319, -400, -274, -131, -258, -317, -231, -396, -403, -299, -400, -335, -208,
|
||||
+2251, +2968, +994, +1270, +1801, +1182, +278, +85, +960, +1169, +719, +996, +1351, +1194, +875, +354, +176, -35, -282, -178, -385, -406, -153, -263, -175, -84, -340, -346, -297, -435, -353, -295,
|
||||
+2479, +3474, +1165, +1200, +1738, +845, +57, +328, +1004, +611, +199, +546, +759, +1002, +1149, +732, +519, +336, +110, +42, -306, -317, -221, -391, -190, -72, -254, -255, -285, -409, -356, -289,
|
||||
+2648, +3711, +1310, +1382, +2036, +687, -508, +326, +1209, +455, +69, +381, +353, +462, +570, +467, +723, +755, +406, +258, +135, -71, -226, -267, -244, -225, -239, -248, -226, -295, -370, -333,
|
||||
+2964, +4131, +1490, +1331, +2035, +615, -807, +460, +1251, +53, -30, +484, +328, +176, +292, +67, +31, +459, +630, +520, +346, +231, +64, -123, -179, -163, -253, -368, -325, -244, -286, -364,
|
||||
+3240, +4589, +1670, +1277, +2158, +577, -1140, +581, +1323, -227, -122, +553, +290, +100, +235, -70, -152, +21, +69, +287, +434, +552, +333, +96, +114, -5, -177, -258, -330, -382, -258, -309,
|
||||
+3730, +5196, +1638, +1123, +2168, +499, -1274, +755, +1209, -628, -139, +668, +292, -40, +122, -92, -234, -100, -101, -83, -135, +285, +479, +374, +279, +151, +85, -119, -293, -348, -282, -381,
|
||||
+4119, +5684, +1732, +1126, +2228, +300, -1467, +1077, +1204, -1061, -263, +742, +305, -24, +37, -204, -274, -137, -131, -189, -340, -114, +44, +178, +404, +348, +234, +110, -83, -267, -257, -291,
|
||||
+4622, +6186, +1693, +1242, +2320, -46, -1538, +1517, +1127, -1483, -304, +841, +294, -67, +5, -203, -308, -200, -102, -217, -386, -222, -141, -99, +23, +201, +346, +265, +65, -52, -11, -200,
|
||||
+5193, +6638, +1553, +1499, +2388, -594, -1569, +2013, +985, -1862, -401, +847, +342, -127, -49, -265, -391, -279, -24, -258, -446, -237, -373, -107, -35, -174, -57, +100, +163, +130, +55, -58,
|
||||
+5824, +7125, +1374, +1701, +2443, -1077, -1576, +2426, +806, -2127, -438, +769, +324, -176, +41, -326, -603, -328, -5, -213, -487, -284, -470, -142, -47, -263, -242, -262, -124, +12, +120, +33,
|
||||
+6335, +7628, +1408, +1800, +2526, -1396, -1736, +2894, +798, -2493, -400, +738, +274, -165, +15, -222, -694, -482, +72, -261, -572, -116, -475, -277, -17, -291, -261, -317, -412, -297, -56, +28,
|
||||
+6761, +8075, +1459, +2066, +2609, -1964, -1828, +3359, +727, -2782, -456, +715, +208, -232, -18, -148, -747, -627, +81, -302, -698, -121, -406, -325, -107, -219, -294, -466, -521, -391, -176, -288,
|
||||
+7157, +8606, +1581, +2068, +2784, -2202, -2039, +3602, +767, -2899, -542, +707, +104, -260, -9, -128, -676, -844, +64, -130, -840, -253, -381, -284, -107, -233, -282, -564, -568, -421, -261, -447,
|
||||
+7410, +9322, +1838, +1630, +3033, -1959, -2478, +3478, +916, -2764, -738, +578, +126, -372, +30, -107, -667, -935, -60, -32, -777, -452, -481, -148, -144, -362, -257, -530, -598, -498, -436, -437,
|
||||
+7600, +9757, +2318, +1422, +3068, -1530, -2951, +3205, +1134, -2618, -848, +362, +153, -421, -49, -52, -609, -1028, -173, +13, -822, -437, -527, -269, -108, -428, -361, -411, -698, -654, -354, -475,
|
||||
+8104, +9762, +2543, +1907, +2993, -1492, -3123, +3108, +1007, -2376, -799, +85, +225, -462, -207, +76, -422, -1156, -330, +104, -791, -492, -526, -345, -141, -393, -383, -537, -744, -705, -190, -505,
|
||||
+8909, +9413, +2318, +2985, +3009, -1948, -3050, +3168, +425, -2046, -543, -270, +167, -483, -337, +79, -154, -1299, -550, +186, -643, -695, -585, -287, -262, -358, -406, -740, -843, -531, -265, -573,
|
||||
+9426, +9025, +2181, +4009, +3640, -2472, -3407, +3777, -384, -2061, +272, -562, -296, -282, -348, -201, +397, -1463, -821, +375, -577, -753, -723, -199, -322, -387, -483, -747, -845, -590, -326, -571,
|
||||
+10108, +8385, +1400, +6014, +4224, -3846, -2895, +4634, -1924, -2185, +1409, -691, -736, -445, -160, -496, +690, -1211, -1255, +419, -429, -745, -766, -201, -456, -411, -561, -544, -937, -907, -160, -739,
|
||||
+10943, +8373, +46, +7110, +5244, -4697, -2467, +5334, -3432, -2574, +2681, -670, -1220, -664, +155, -796, +596, -633, -1639, +276, -169, -751, -786, -162, -512, -556, -561, -560, -872, -1006, -393, -823,
|
||||
+12145, +8720, -1664, +7093, +6723, -4974, -2355, +5841, -4655, -3092, +3716, -397, -1752, -903, +493, -914, +75, -59, -1625, -196, +169, -746, -800, +30, -700, -607, -584, -846, -650, -980, -876, -718,
|
||||
+13449, +9173, -3433, +6797, +7856, -4807, -2042, +6051, -5634, -3740, +4384, +233, -2242, -1265, +790, -884, -471, +114, -1201, -709, +233, -517, -817, +265, -855, -714, -702, -983, -688, -985, -936, -805,
|
||||
+14554, +9843, -4692, +5589, +8876, -3969, -1993, +6452, -6471, -4465, +4658, +1064, -2464, -1808, +1040, -734, -892, -140, -587, -969, -47, -87, -824, +496, -902, -929, -759, -1132, -899, -928, -701, -988,
|
||||
+15499, +10690, -5588, +4019, +9370, -2825, -1817, +6925, -7237, -5143, +4618, +1819, -2391, -2377, +1112, -527, -1082, -687, -144, -864, -451, +270, -610, +501, -919, -981, -876, -1386, -1039, -897, -490, -928,
|
||||
+17184, +10743, -6654, +3458, +8941, -2496, -296, +6958, -8428, -5131, +4435, +2201, -2279, -2678, +1041, -465, -1059, -1191, -112, -563, -633, +396, -146, +255, -999, -772, -1178, -1541, -1165, -955, -285, -586,
|
||||
+18439, +11433, -7884, +3086, +8223, -2330, +1154, +7363, -9381, -5433, +4476, +2299, -2058, -2772, +772, -429, -922, -1487, -412, -319, -459, +489, +179, +4, -920, -666, -1378, -1593, -1381, -989, -70, -199,
|
||||
+20043, +11571, -8926, +2927, +7480, -2933, +2814, +7900, -10432, -5634, +4629, +2163, -2083, -2501, +322, -605, -660, -1666, -795, -420, +2, +773, +28, -86, -714, -788, -1426, -1661, -1631, -934, -18, +154,
|
||||
+21100, +12438, -9991, +2658, +6924, -3598, +3640, +9112, -11048, -6263, +4923, +1936, -2083, -2127, -90, -1004, -241, -1755, -1109, -655, +353, +1477, -496, -26, -322, -1103, -1235, -1773, -1804, -950, -17, +340,
|
||||
+22220, +13016, -10684, +2238, +6616, -4544, +3961, +10464, -11476, -6710, +4989, +1692, -2097, -1740, -471, -1509, +171, -1891, -1172, -1008, +446, +2361, -1007, -80, +206, -1448, -1059, -1719, -2148, -946, -187, +379,
|
||||
+23160, +13514, -10970, +1648, +6564, -5582, +3717, +11856, -11585, -6851, +4668, +1415, -1888, -1527, -831, -1885, +423, -2020, -993, -1361, +246, +3145, -1090, -388, +815, -1543, -1101, -1488, -2586, -1060, -470, +329,
|
||||
+23984, +13865, -11140, +1506, +6153, -6455, +3221, +12728, -11274, -6683, +4149, +879, -1350, -1515, -1321, -1966, +480, -2107, -735, -1620, -134, +3538, -695, -707, +1213, -1214, -1434, -1269, -3012, -1293, -736, +72,
|
||||
+24782, +14120, -11236, +1961, +5253, -7111, +2788, +12880, -10420, -6360, +3471, +290, -601, -1551, -1881, -1800, +635, -2271, -409, -1692, -623, +3484, +102, -645, +1121, -484, -1860, -1402, -3095, -1550, -1113, -154,
|
||||
+24478, +15178, -10478, +1270, +5126, -7637, +1416, +13108, -9038, -6194, +2475, -43, +4, -1635, -2240, -1773, +998, -2517, -301, -1320, -1403, +2910, +1377, -319, +543, +368, -2377, -1572, -2886, -2071, -1188, -610,
|
||||
+23336, +16618, -8704, -223, +5298, -7565, -968, +13263, -6982, -6465, +1742, -449, +352, -1376, -2596, -1623, +1240, -2651, -286, -899, -1898, +1936, +2438, +528, -375, +750, -2161, -1941, -2664, -2274, -1304, -958,
|
||||
+22712, +17229, -7217, -356, +4386, -7099, -2807, +12389, -4621, -6839, +1425, -975, +424, -777, -2826, -1526, +1422, -2734, -246, -516, -2068, +1271, +2387, +1470, -861, +696, -1581, -2206, -2447, -2243, -1214, -1282,
|
||||
+22892, +17053, -6909, +1550, +2504, -7309, -2981, +10387, -2761, -6478, +847, -1462, +747, -527, -2541, -1653, +1330, -2326, -581, +131, -2018, +687, +1356, +2090, -263, +54, -772, -2199, -2423, -1678, -1280, -1950,
|
||||
+22958, +16963, -6994, +3862, +804, -8094, -2421, +7964, -1267, -5599, -222, -1546, +1312, -701, -1892, -1941, +925, -1306, -1223, +805, -1822, -507, +577, +2232, +644, +10, -622, -1590, -2129, -1759, -1313, -2053,
|
||||
+22795, +16811, -6665, +5414, -231, -8963, -2057, +5715, -140, -4502, -1495, -1224, +1967, -1203, -1238, -1944, +128, +141, -1762, +375, -1151, -1442, -293, +2236, +1381, +482, -421, -1050, -2081, -1865, -1013, -2075,
|
||||
+22156, +16822, -5737, +5914, -531, -9248, -2574, +3914, +921, -3656, -2319, -843, +2476, -1480, -1050, -1438, -455, +614, -1691, -640, -770, -1051, -1218, +1623, +1962, +1863, -702, -1229, -1009, -2137, -1191, -1810,
|
||||
+21420, +16785, -4799, +6154, -663, -9035, -3372, +2102, +2124, -2833, -3110, -133, +2641, -1601, -638, -1248, -923, +605, -1675, -1249, -658, -53, -1902, +1335, +2038, +2064, +272, -1486, -537, -2097, -1156, -1644,
|
||||
+21361, +15629, -3750, +6528, -1323, -8215, -4323, +464, +3132, -1840, -3943, +437, +3186, -1861, -582, -1384, -980, +77, -1818, -753, -1149, +490, -779, +520, +1069, +2103, +1599, -1602, -997, -1118, -1205, -1803,
|
||||
+20330, +15116, -2198, +6125, -1778, -6323, -6028, -1388, +5002, -1330, -4769, +1469, +3125, -2056, -350, -2178, -854, +367, -2722, -22, -540, -99, +456, +351, -11, +1824, +1553, -531, -893, -1195, -631, -1855,
|
||||
+20062, +13940, -1073, +5901, -2918, -4148, -6485, -3763, +6395, -76, -5571, +1976, +3170, -2469, -500, -2482, -418, +183, -3077, +751, +150, -824, +890, +1089, -685, +923, +962, +419, -69, -1542, -261, -1391,
|
||||
+21165, +12566, -2644, +7196, -3419, -4374, -5591, -3941, +6004, +491, -4989, +1625, +3132, -2899, -840, -2060, -308, +352, -2926, +725, +461, -401, +854, +946, -597, +286, +687, +245, +522, -714, -834, -655,
|
||||
+22181, +10753, -4743, +9694, -3820, -6164, -3751, -3237, +4762, +962, -4786, +856, +3566, -3082, -1668, -1292, +74, +282, -2679, +317, +654, +206, +432, +672, -272, -199, +427, +115, +322, +278, -897, -731,
|
||||
+21833, +9209, -6007, +12315, -3453, -8356, -2210, -1380, +3074, +222, -3684, +199, +3572, -2831, -2010, -495, +19, -33, -2094, +470, +147, +334, +628, +538, -358, +45, -17, -272, +825, +112, -396, -410,
|
||||
+21222, +7854, -6428, +13904, -3314, -9841, -311, -717, +1107, +600, -2989, -732, +3598, -2074, -2105, -29, +34, -558, -1422, +552, -367, +238, +799, +488, -473, +119, +72, -314, +618, +130, -262, -1,
|
||||
+19959, +7458, -6254, +13163, -2749, -8575, +168, -1541, +524, +795, -2410, -1167, +3370, -1359, -1981, +131, -37, -600, -1272, +322, -134, +241, +366, +572, -360, -40, +508, -76, -11, +77, -84, -39,
|
||||
+18263, +7315, -5697, +12058, -1512, -7911, -155, -1097, -277, +440, -1476, -1163, +2794, -682, -1653, -226, +195, -447, -1525, +167, +243, +191, +5, +420, -166, +267, +536, -17, -141, -216, +13, -120,
|
||||
+14574, +8295, -838, +5767, -2715, -2520, -1691, -1773, +1779, -38, -2463, +993, +2121, -1350, -803, -1187, +196, -325, -1656, +367, -300, -397, +308, +424, +622, +1154, -257, -779, -260, -661, -212, +363,
|
||||
+12640, +8177, -514, +5232, -1427, -2829, -1332, -1356, +968, +94, -1951, +761, +1867, -950, -840, -1080, +224, -469, -1525, +376, -426, -453, +483, +403, +530, +830, -326, -345, -235, -760, -56, +349,
|
||||
+11044, +7881, -148, +5139, -839, -2943, -771, -1231, +563, +131, -1472, +726, +1552, -637, -706, -854, +77, -516, -1176, +229, -479, -289, +444, +438, +558, +439, -291, +63, -149, -710, +13, +439,
|
||||
+9448, +7315, +777, +4791, -766, -2291, -640, -1240, +566, +79, -1184, +670, +1401, -496, -584, -601, -102, -472, -972, +95, -341, -227, +329, +485, +481, +177, -40, +272, -35, -470, -18, +555,
|
||||
+7784, +6813, +1919, +4053, -580, -1299, -807, -1308, +740, +180, -1143, +616, +1306, -404, -321, -523, -263, -345, -754, -11, -288, -134, +224, +482, +339, +206, +285, +426, +140, -377, +51, +463,
|
||||
+6153, +6246, +2936, +3514, -265, -522, -963, -1330, +954, +278, -1137, +468, +1183, -27, -199, -727, -188, -39, -737, -145, -161, -167, +296, +467, +191, +475, +664, +574, +50, -370, +118, +236,
|
||||
+5216, +5838, +3133, +3059, +1, -157, -756, -1165, +778, +326, -848, +372, +928, +178, -109, -801, -20, +104, -796, -199, -47, -58, +362, +449, +343, +811, +845, +385, -220, -311, +33, +113,
|
||||
+4597, +5368, +3150, +2849, +47, +176, -392, -1164, +650, +523, -570, +155, +748, +467, -67, -777, +130, +87, -748, -20, -18, +143, +685, +510, +516, +926, +646, +76, -295, -314, +101, +201,
|
||||
+4160, +4800, +2975, +2878, +215, +185, -346, -879, +720, +434, -577, +142, +805, +500, -153, -718, +261, +104, -689, +154, +246, +528, +763, +288, +509, +781, +225, -155, -161, -171, -27, -42,
|
||||
+4047, +4610, +2554, +2523, +343, +309, -161, -677, +639, +395, -412, +331, +729, +219, -6, -351, +190, +142, -205, +534, +514, +540, +360, +158, +449, +446, +134, -82, -194, -248, -36, -79,
|
||||
+3681, +4202, +2459, +2522, +468, +335, -124, -483, +720, +451, -371, +292, +718, +292, +137, -143, +474, +547, +124, +441, +403, +249, +3, +182, +383, +387, +48, -193, -191, -244, -51, -202,
|
||||
+3418, +3958, +2332, +2406, +561, +275, -16, -147, +764, +316, -330, +555, +677, +300, +712, +391, +554, +506, -31, +195, +200, -92, +90, +358, +160, +198, -1, -186, -221, -248, -146, -268,
|
||||
+3294, +3885, +2237, +2055, +440, +495, +330, -195, +594, +558, -92, +562, +1070, +915, +915, +255, +158, +177, -224, +85, +144, -90, +60, +179, +169, +71, -152, -244, -264, -222, -259, -374,
|
||||
+3036, +3530, +2299, +2284, +540, +283, +250, +363, +785, +420, +481, +1288, +1245, +678, +546, -172, -123, +52, -133, +151, -76, -120, +87, +168, +37, -127, -184, -303, -217, -273, -383, -412,
|
||||
+2951, +3684, +2445, +1884, +210, +635, +675, +547, +1250, +1227, +765, +965, +798, +86, +80, -228, +0, +39, -228, +30, -27, -42, +25, +53, -221, -186, -201, -304, -216, -403, -409, -382,
|
||||
+2948, +3672, +2453, +1863, +191, +765, +1578, +1710, +1229, +774, +415, +256, +396, -103, +36, -65, -268, -80, -64, -3, -34, -116, -164, -71, -281, -296, -229, -301, -271, -378, -434, -341,
|
||||
+2843, +3566, +2452, +2150, +1119, +1466, +1682, +1795, +928, -254, -261, +372, +403, -274, -165, -161, -184, -111, -88, -48, -200, -201, -180, -289, -413, -275, -295, -256, -268, -441, -348, -288,
|
||||
+2564, +4101, +3460, +2647, +1410, +1412, +1574, +983, +11, +28, -27, +71, +225, -244, +4, -163, -265, +10, -151, -168, -99, -187, -352, -372, -357, -210, -195, -232, -258, -356, -289, -290,
|
||||
+3244, +5969, +3950, +1503, +762, +1387, +767, +390, +603, -90, -364, -54, +452, -41, -367, -79, -184, -274, -111, -48, -196, -322, -399, -360, -258, -194, -183, -224, -289, -330, -316, -345,
|
||||
+3784, +6054, +3526, +1790, +389, +352, +1278, +1092, -88, -197, +260, -59, +139, +65, -157, -256, -333, -279, -121, -80, -211, -244, -442, -312, -216, -247, -254, -250, -268, -326, -359, -335,
|
||||
+2822, +5085, +3846, +2069, +435, +648, +1401, +1023, +236, -6, +341, +350, +172, -40, +34, -202, -361, -272, -304, -204, -29, -187, -395, -181, -217, -302, -314, -303, -311, -325, -288, -335,
|
||||
+2707, +4855, +2989, +1364, +947, +1039, +1087, +968, +768, +256, +227, +682, +564, +111, +39, -39, -213, -415, -274, -193, -240, -136, -135, -139, -171, -174, -321, -402, -386, -337, -287, -323,
|
||||
+2574, +4549, +2481, +1104, +1330, +907, +475, +1038, +988, +424, +619, +680, +540, +614, +433, -71, -59, -64, -397, -356, -134, -141, -286, +11, +52, -193, -195, -312, -434, -438, -356, -279,
|
||||
+2422, +4172, +2328, +1283, +1472, +647, +125, +1006, +879, +224, +547, +905, +832, +557, +435, +418, +214, -78, -116, -201, -318, -253, -140, -84, -96, +29, -87, -310, -305, -394, -495, -381,
|
||||
+2457, +4168, +2312, +1258, +1473, +568, -47, +1024, +903, -67, +189, +852, +771, +615, +723, +347, +177, +387, +190, -226, -97, -8, -307, -173, +62, -42, -182, -125, -211, -363, -347, -400,
|
||||
+2479, +4135, +2339, +1562, +1610, +192, -248, +1300, +909, -337, +81, +690, +508, +388, +636, +433, +219, +291, +303, +164, +7, +21, +31, -36, -110, -67, -84, -238, -296, -215, -282, -331,
|
||||
+2624, +4417, +2420, +1461, +1611, +190, -334, +1254, +921, -411, -37, +569, +431, +277, +366, +238, +20, +196, +411, +163, +23, +266, +197, +88, +161, +35, -197, -291, -298, -316, -320, -247,
|
||||
+2857, +4661, +2448, +1599, +1644, -52, -369, +1426, +846, -542, -64, +578, +333, +106, +438, +207, -300, -149, +268, +191, +20, +247, +302, +342, +299, +211, +96, -235, -456, -375, -272, -328,
|
||||
+3188, +5067, +2423, +1526, +1665, -114, -379, +1420, +746, -615, -22, +514, +244, +36, +349, +284, -291, -398, -114, +35, -95, +71, +386, +395, +370, +407, +245, -45, -298, -398, -392, -348,
|
||||
+3392, +5464, +2575, +1426, +1705, -141, -510, +1546, +697, -819, -14, +541, +205, -81, +197, +362, -172, -517, -262, -166, -340, -129, +171, +384, +434, +397, +374, +107, -152, -237, -310, -366,
|
||||
+3778, +5985, +2547, +1224, +1789, -132, -599, +1611, +647, -931, +4, +483, +130, -67, +79, +336, -105, -481, -339, -274, -374, -355, -90, +280, +364, +297, +401, +185, -84, -89, -184, -264,
|
||||
+4238, +6510, +2468, +1077, +1860, -270, -600, +1756, +466, -1066, +75, +520, -27, -200, +61, +302, -74, -470, -390, -308, -412, -437, -214, +90, +251, +154, +227, +157, -56, -78, -125, -116,
|
||||
+4791, +7085, +2292, +969, +1933, -473, -530, +1936, +231, -1156, +164, +537, -117, -309, +2, +238, -84, -390, -352, -407, -462, -398, -204, -73, +172, +87, +45, +57, -238, -129, -20, -64,
|
||||
+5298, +7657, +2183, +875, +2016, -753, -494, +2218, -13, -1312, +267, +578, -182, -441, -93, +196, -122, -393, -302, -435, -513, -440, -113, -135, -14, +190, -70, -156, -337, -293, -128, -66,
|
||||
+5772, +8287, +2120, +701, +2131, -1043, -540, +2502, -218, -1459, +344, +564, -207, -513, -279, +141, -129, -411, -314, -481, -509, -495, -83, -55, -189, +147, -1, -322, -411, -420, -358, -159,
|
||||
+6156, +8940, +2162, +466, +2269, -1223, -655, +2753, -350, -1564, +441, +587, -308, -513, -366, -30, -129, -409, -289, -486, -560, -558, -73, +140, -206, -105, +70, -261, -507, -464, -575, -293,
|
||||
+6742, +9493, +2028, +426, +2287, -1512, -626, +2857, -609, -1493, +499, +542, -410, -555, -338, -271, -242, -367, -235, -522, -637, -614, -88, +199, -77, -219, -130, -145, -572, -543, -605, -493,
|
||||
+7455, +9892, +1817, +673, +2165, -1782, -526, +2877, -874, -1369, +613, +482, -471, -664, -187, -495, -430, -293, -210, -463, -712, -671, -39, +162, -43, -26, -317, -285, -509, -579, -619, -592,
|
||||
+8019, +10193, +1826, +947, +2060, -1895, -616, +2838, -973, -1270, +603, +513, -417, -884, -78, -555, -646, -328, -167, -385, -659, -776, -74, +250, -111, +117, -295, -476, -508, -590, -658, -581,
|
||||
+8488, +10358, +1977, +1265, +2015, -1887, -920, +2788, -1005, -1210, +617, +441, -268, -1020, -166, -487, -785, -574, -79, -286, -605, -796, -270, +464, -155, +23, -164, -502, -600, -692, -661, -560,
|
||||
+9032, +10338, +2002, +1761, +2191, -2067, -1283, +2872, -1174, -1205, +746, +309, -249, -938, -329, -531, -744, -897, -123, -86, -627, -738, -388, +469, +0, -188, -125, -361, -727, -819, -607, -613,
|
||||
+9864, +10088, +1523, +2776, +2578, -2733, -1373, +3075, -1563, -1189, +922, +251, -375, -786, -321, -773, -647, -1025, -380, +85, -536, -746, -274, +305, +98, -159, -216, -318, -746, -852, -593, -682,
|
||||
+10598, +9701, +940, +4274, +3058, -3831, -1125, +3536, -2290, -1265, +1285, +276, -567, -754, -134, -923, -659, -1033, -713, +96, -164, -899, -154, +299, +14, +105, -391, -378, -574, -830, -773, -577,
|
||||
+10878, +9347, +643, +5807, +3528, -5043, -576, +4279, -3492, -1535, +1951, +350, -873, -858, +153, -941, -755, -1006, -1030, -132, +274, -915, -234, +450, -136, +336, -408, -493, -454, -795, -947, -437,
|
||||
+11510, +9866, -517, +5809, +4860, -5267, -967, +4693, -4147, -1854, +2440, +298, -1178, -888, +429, -1109, -918, -824, -1173, -606, +385, -531, -456, +537, -109, +345, -322, -566, -435, -822, -1034, -491,
|
||||
+12635, +10354, -1762, +5073, +6221, -4898, -1391, +4717, -4535, -2049, +2756, +364, -1594, -867, +721, -1229, -1148, -678, -1099, -989, +154, -84, -438, +418, +119, +303, -273, -468, -478, -915, -1048, -631,
|
||||
+13739, +10931, -3039, +4229, +7036, -3993, -1627, +4425, -4683, -2247, +2950, +515, -2020, -897, +930, -1302, -1368, -646, -958, -1207, -291, +233, -188, +154, +374, +357, -256, -270, -569, -1081, -1002, -747,
|
||||
+14744, +11698, -4040, +3065, +7514, -2833, -1645, +3985, -4805, -2328, +2928, +769, -2368, -998, +1104, -1337, -1464, -742, -746, -1258, -738, +270, +219, -28, +461, +565, -183, -98, -674, -1208, -1015, -822,
|
||||
+15661, +12563, -4797, +1712, +7684, -1798, -1303, +3560, -5128, -2181, +2756, +928, -2517, -1206, +1167, -1348, -1484, -913, -576, -1200, -996, -13, +556, +59, +345, +829, -12, -35, -778, -1229, -1099, -956,
|
||||
+16364, +13610, -5417, +358, +7606, -1081, -694, +3363, -5713, -1853, +2574, +824, -2410, -1460, +1029, -1325, -1426, -1134, -452, -1081, -1063, -425, +647, +304, +234, +1059, +210, -50, -832, -1188, -1210, -1113,
|
||||
+17301, +14490, -6249, -381, +7171, -884, +239, +3371, -6504, -1381, +2548, +400, -2128, -1591, +701, -1356, -1209, -1399, -313, -902, -1081, -684, +503, +524, +231, +1359, +398, -161, -776, -1179, -1300, -1239,
|
||||
+19090, +14422, -7537, +119, +6088, -1186, +1568, +3110, -7218, -739, +2538, -295, -1756, -1656, +234, -1424, -1032, -1537, -233, -694, -1129, -779, +292, +571, +268, +1771, +559, -457, -623, -1262, -1420, -1267,
|
||||
+20805, +14336, -8736, +920, +4704, -1494, +2649, +2925, -7561, -328, +2504, -973, -1224, -1901, -205, -1369, -1023, -1413, -248, -538, -1010, -940, +175, +531, +207, +2290, +770, -842, -494, -1328, -1610, -1150,
|
||||
+22109, +14485, -9555, +1595, +3405, -1875, +3399, +2878, -7467, -159, +2320, -1375, -756, -2191, -602, -1235, -972, -1286, -262, -418, -788, -1088, +82, +594, -8, +2708, +1095, -1168, -535, -1285, -1751, -974,
|
||||
+22911, +14859, -9889, +1889, +2263, -2415, +3753, +2933, -7127, -227, +1986, -1630, -415, -2450, -1051, -1037, -827, -1434, -165, -366, -647, -1068, -154, +882, -368, +2616, +1524, -1241, -905, -1145, -1703, -979,
|
||||
+23245, +15363, -9604, +1856, +1322, -3040, +3776, +3098, -6633, -350, +1568, -1819, -103, -2618, -1435, -794, -655, -1757, +41, -318, -654, -746, -459, +1267, -738, +1911, +2006, -928, -1339, -994, -1484, -1026,
|
||||
+23048, +16128, -8809, +1596, +486, -3594, +3405, +3364, -5994, -577, +1227, -2110, +338, -2650, -1697, -633, -515, -2058, +200, -158, -867, -14, -786, +1297, -792, +869, +2115, -163, -1403, -1180, -994, -927,
|
||||
+22809, +16473, -7468, +1279, -304, -4094, +2691, +3769, -5530, -656, +858, -2440, +917, -2540, -1937, -596, -384, -2335, +377, -58, -950, +797, -1345, +1069, -434, -289, +1797, +898, -1234, -1327, -340, -1167,
|
||||
+22287, +16759, -6019, +907, -957, -4847, +1807, +4137, -5333, -671, +434, -2757, +1592, -2484, -2177, -772, -331, -2403, +180, +397, -1148, +952, -1488, +457, +9, -900, +941, +1571, -432, -1370, -331, -1254,
|
||||
+21687, +17120, -4653, +1201, -1531, -5605, +1233, +4224, -4907, -618, +334, -2824, +2339, -2255, -2444, -777, -345, -2119, +138, +690, -1476, +1035, -1282, -255, +720, -854, -197, +2118, +560, -1484, -235, -840,
|
||||
+20812, +17571, -3517, +1604, -1925, -6559, +655, +3983, -4426, -559, +260, -2689, +2858, -2122, -2599, -1007, -244, -1381, -668, +771, -1403, +492, -756, -404, +502, +93, -695, +1167, +1322, -839, -247, -943,
|
||||
+20139, +17539, -2371, +1932, -2101, -7422, -134, +3611, -3812, -412, +185, -2382, +3168, -1970, -3046, -567, -229, -1405, -1029, +419, -1307, +375, -467, -375, +380, +1214, -1001, -411, +2033, -274, -430, -799,
|
||||
+19753, +17050, -1457, +2572, -2382, -8049, -965, +2983, -2716, -235, -326, -1321, +2916, -2171, -2296, -826, -571, -1104, -1712, +62, -637, +159, -684, +668, +232, +865, +69, -1322, +1025, +254, +67, -588,
|
||||
+19313, +16611, -863, +3251, -2596, -8557, -2035, +2815, -1745, -84, -572, -839, +2943, -1918, -2229, -1014, -802, -1378, -1915, +318, -814, +322, -33, +499, +177, +995, +794, -1733, -313, +324, +698, -311,
|
||||
+19432, +15373, -280, +4094, -3296, -8664, -2599, +2170, -225, -30, -1542, +594, +2691, -2281, -1544, -1686, -1307, -903, -1915, -153, -126, +698, -360, +340, +825, +1064, +273, -993, -998, -689, +1129, +142,
|
||||
+19161, +14270, +164, +4902, -4023, -8420, -3080, +1712, +839, +173, -2097, +1066, +2771, -2396, -1584, -2406, -841, -783, -2457, +724, +24, +6, +115, +460, +603, +1331, -24, -638, -844, -1849, +898, +543,
|
||||
+18185, +13294, +1396, +5056, -4975, -6537, -4217, +256, +3477, -142, -3597, +2330, +2565, -2744, -1485, -2544, -786, -568, -2073, +767, -278, -87, +712, +47, +286, +1855, +49, -975, -401, -2019, -110, +720,
|
||||
+18313, +12559, +1145, +3915, -4788, -4611, -4800, -248, +4385, -385, -3737, +2444, +2059, -2542, -1236, -3085, -90, -60, -2227, +677, -342, +170, +590, -167, +444, +1928, +89, -943, -588, -1828, -345, +588,
|
||||
+19047, +11703, -955, +4365, -4893, -3853, -3267, -1533, +4299, +134, -4009, +2112, +2030, -2635, -1305, -2227, -55, -224, -2038, +767, -148, -368, +345, +393, +586, +1413, +142, -763, -846, -1547, -218, +199,
|
||||
+19014, +10464, -2335, +5732, -4481, -4151, -2526, -849, +3281, -472, -3208, +1847, +1902, -2824, -779, -1622, -183, -396, -1924, +1079, -378, -665, +394, +566, +672, +1279, -35, -701, -812, -1354, +31, +44,
|
||||
+18162, +9492, -3044, +7090, -3964, -4906, -1033, -851, +1796, -66, -2783, +1424, +1900, -2369, -665, -1270, -198, -516, -1532, +747, -522, -404, +331, +314, +897, +1359, -338, -718, -601, -1136, +5, +342,
|
||||
+16598, +8667, -2195, +6902, -3696, -3649, -980, -1771, +1921, -11, -2768, +1203, +2093, -1882, -722, -1121, -151, -296, -1570, +398, -363, -287, +171, +326, +918, +1214, -295, -849, -425, -762, -169, +362,
|
||||
+14574, +8452, +258, +4430, -4365, -2407, +102, -220, -223, -832, -1852, +1615, +1202, -2022, +253, -1216, -444, -63, -1455, +368, -312, -727, +373, +217, -412, +849, +339, -186, +129, -916, -296, -195,
|
||||
+12278, +8141, +1428, +3486, -3243, -1249, -493, -560, +165, -592, -1924, +1327, +1447, -1595, +92, -1011, -282, -108, -1214, +238, -313, -593, +289, +150, -236, +853, +317, -36, -85, -842, +19, -3,
|
||||
+9818, +8134, +2487, +2440, -2082, -590, -823, -829, +309, -432, -1752, +1141, +1209, -1118, +27, -830, -297, -203, -900, +148, -415, -552, +316, +48, -77, +666, +249, +139, -158, -658, +206, +196,
|
||||
+8218, +7700, +2637, +2474, -1307, -764, -546, -580, +192, -485, -1350, +993, +1042, -888, +8, -569, -372, -127, -680, -31, -355, -306, +131, -53, +119, +550, +383, +249, -130, -272, +357, +9,
|
||||
+7260, +6952, +2528, +2729, -947, -957, -177, -207, -119, -455, -915, +762, +893, -798, +106, -330, -495, -95, -429, -94, -346, -203, -44, +24, +289, +567, +633, +250, -96, -40, +210, -228,
|
||||
+6314, +6251, +2666, +2794, -629, -891, -34, +102, -183, -316, -716, +491, +887, -525, +110, -285, -414, +113, -262, -316, -185, -38, -118, +319, +459, +666, +731, +112, -104, -55, +52, -322,
|
||||
+5417, +5613, +2827, +2816, -327, -838, +28, +455, -189, -286, -591, +343, +896, -378, +146, -174, -275, +223, -276, -286, +110, +144, +58, +429, +461, +747, +496, -173, -50, +14, -42, -390,
|
||||
+4737, +5252, +2774, +2553, +28, -656, +97, +596, -174, -128, -477, +136, +904, -37, +86, -133, -68, +253, -71, +76, +414, +107, +44, +523, +339, +397, +292, -77, +23, -24, -184, -339,
|
||||
+3981, +4689, +2974, +2705, +128, -673, +191, +862, -76, -188, -396, +170, +926, +95, +102, -7, +257, +567, +232, +227, +237, +46, +2, +205, +229, +329, +244, -63, +38, -31, -270, -262,
|
||||
+3639, +4461, +2924, +2330, +166, -438, +386, +823, -29, -56, -316, +227, +932, +175, +339, +566, +570, +436, +183, +186, -95, -222, +17, +187, +153, +207, +145, +26, +72, -187, -282, -293,
|
||||
+3259, +4171, +2982, +2255, +67, -366, +661, +923, -74, +111, -202, +162, +1330, +741, +513, +485, +402, +353, -62, -283, -157, +6, -120, +24, +146, +186, +148, -35, -33, -267, -322, -309,
|
||||
+3122, +4118, +2900, +1944, +0, -98, +882, +1021, -181, +159, +515, +745, +1264, +473, +425, +351, -23, -30, -118, -265, -166, -97, -186, +192, +98, -114, +91, +11, -210, -322, -297, -412,
|
||||
+3235, +4303, +2623, +1571, +77, +285, +881, +1185, +547, +613, +652, +402, +925, +370, -45, -8, +19, -59, -264, -364, +11, +81, -230, -1, -128, -117, +119, -34, -321, -411, -265, -385,
|
||||
+3389, +4725, +2245, +1203, +58, +908, +2020, +1399, +334, +357, +538, +113, +387, +96, +39, -34, -209, -107, -173, -4, +62, -200, -339, -98, -124, -103, +123, -133, -427, -315, -196, -296,
|
||||
+3432, +4882, +1947, +1109, +1266, +1747, +1687, +1007, +236, +86, +163, -84, +293, +0, -42, -68, -271, +122, +155, -210, -251, -156, -291, -288, -163, +38, -58, -180, -248, -250, -248, -317,
|
||||
+3101, +4702, +2964, +1975, +929, +1541, +1764, +744, -57, -59, +188, -44, +87, -46, -2, +54, +100, +125, -120, -181, -166, -232, -402, -239, -149, -71, +43, -36, -164, -289, -356, -319,
|
||||
+3896, +5904, +2447, +896, +1159, +1573, +1310, +595, -175, -62, +179, +2, +162, -166, +142, +495, +86, -291, -23, -10, -305, -361, -351, -199, -209, +43, +163, +6, -270, -382, -312, -377,
|
||||
+4111, +6381, +2053, +273, +1154, +1396, +1209, +828, +5, -261, +331, +111, +75, +99, +333, +466, -15, -97, -25, -78, -294, -279, -352, -332, -105, +81, +175, -17, -195, -388, -359, -345,
|
||||
+3095, +5772, +3360, +570, +281, +922, +1379, +1273, +83, -225, +436, +376, -8, +55, +499, +520, +210, -84, -45, +41, -164, -351, -289, -251, -244, +17, +144, +52, -153, -277, -319, -362,
|
||||
+2581, +5083, +3747, +1205, +166, +554, +1050, +1250, +302, -212, +397, +598, +127, +67, +436, +383, +436, +172, +39, +53, -182, -180, -149, -287, -291, -5, +118, -12, -207, -177, -214, -333,
|
||||
+2552, +4951, +3531, +1372, +349, +359, +972, +1271, +183, -443, +321, +679, +210, +58, +442, +429, +340, +218, +211, +180, -63, -124, -120, -161, -112, -103, +24, +72, -222, -300, -275, -209,
|
||||
+2665, +4956, +3357, +1460, +482, +248, +879, +1296, +212, -508, +150, +505, +100, +12, +412, +341, +306, +406, +139, +62, +128, -3, -44, -39, -12, -31, +66, +41, -175, -338, -364, -294,
|
||||
+2910, +5172, +3202, +1418, +526, +219, +908, +1323, +135, -544, +153, +494, +74, -268, +195, +282, +179, +422, +266, +64, +20, -95, +137, +155, -18, +190, +178, +50, -99, -282, -367, -378,
|
||||
+3106, +5510, +3157, +1272, +654, +172, +826, +1393, +101, -594, +108, +460, +164, -335, -22, +133, -125, +219, +461, +52, -105, -110, +31, +176, +54, +285, +298, +145, +61, -223, -389, -316,
|
||||
+3368, +5932, +3118, +1145, +758, +78, +765, +1468, +37, -717, +138, +457, +120, -290, -144, +62, -257, -129, +404, +63, -206, -153, -100, +152, +60, +155, +386, +264, +71, -31, -197, -377,
|
||||
+3733, +6456, +3058, +942, +889, +25, +681, +1552, -15, -820, +148, +459, +69, -211, -190, -47, -265, -323, +274, +169, -372, -347, -72, +87, +21, +34, +374, +281, +11, +98, -68, -219,
|
||||
+4188, +7066, +2967, +691, +995, -34, +635, +1651, -188, -887, +235, +437, -43, -227, -100, -139, -354, -381, +96, +266, -304, -584, -157, +39, -36, +7, +204, +218, +59, +6, -48, -108,
|
||||
+4746, +7725, +2804, +457, +1072, -163, +664, +1759, -458, -963, +395, +430, -203, -287, -43, -200, -465, -426, -10, +200, -148, -659, -283, +63, -164, -51, +108, +49, +5, -21, -57, -176,
|
||||
+5293, +8424, +2691, +200, +1075, -352, +722, +1883, -811, -1091, +593, +430, -407, -391, +9, -266, -633, -524, -73, +107, -103, -596, -428, +55, -134, -199, +69, -190, -167, +13, -143, -226,
|
||||
+5863, +9141, +2667, +40, +1052, -543, +868, +2094, -1172, -1177, +878, +497, -546, -487, +104, -257, -732, -597, -153, +94, -40, -473, -388, -65, +22, -141, -52, -184, -372, -50, -90, -264,
|
||||
+6256, +9830, +2894, -163, +970, -781, +879, +2372, -1514, -1408, +1131, +611, -714, -628, +124, -250, -817, -728, -318, +48, +3, -481, -237, -140, -63, +59, -165, -299, -349, -283, -158, -207,
|
||||
+6594, +10538, +3188, -331, +878, -910, +803, +2530, -1667, -1658, +1306, +784, -813, -792, +152, -249, -880, -762, -546, -74, +192, -563, -200, +88, -247, +128, -7, -470, -416, -264, -343, -125,
|
||||
+6837, +11211, +3624, -582, +873, -887, +585, +2486, -1630, -1804, +1272, +974, -837, -900, +104, -254, -971, -753, -648, -416, +302, -345, -395, +287, -167, -70, +229, -446, -659, -259, -391, -167,
|
||||
+7304, +11778, +3694, -565, +932, -974, +429, +2281, -1610, -1825, +1167, +1061, -833, -962, +48, -273, -1134, -738, -667, -706, +131, -22, -389, +150, +154, -245, +198, -184, -827, -453, -344, -269,
|
||||
+8235, +12147, +3165, -179, +1250, -1280, +244, +2247, -1802, -1646, +1035, +1095, -763, -1091, +127, -372, -1161, -866, -623, -801, -185, +121, -30, -44, +248, -32, -42, -16, -686, -726, -403, -227,
|
||||
+9297, +12266, +2226, +787, +1787, -2113, +102, +2510, -2139, -1611, +994, +1052, -665, -1269, +199, -511, -1125, -991, -710, -778, -421, -49, +341, +106, +24, +220, -125, -69, -467, -801, -641, -218,
|
||||
+10147, +12083, +1353, +2463, +2227, -3535, +293, +3115, -2724, -1863, +1270, +952, -736, -1330, +259, -696, -1131, -995, -849, -797, -533, -301, +461, +439, -103, +301, -72, -178, -379, -650, -774, -450,
|
||||
+10811, +11594, +849, +4553, +2308, -5080, +959, +3783, -3596, -2129, +1832, +791, -1018, -1161, +326, -938, -1147, -869, -944, -907, -502, -461, +355, +652, +38, +401, -29, -244, -390, -373, -749, -645,
|
||||
+12468, +11803, -955, +4782, +3329, -5109, +523, +3592, -3808, -2001, +2054, +456, -1328, -944, +309, -1271, -1148, -913, -864, -1037, -475, -486, +86, +849, +201, +318, +27, -164, -495, -300, -684, -554,
|
||||
+14105, +12174, -2678, +4502, +4313, -4564, -152, +3309, -3818, -1885, +2202, +220, -1631, -822, +354, -1654, -1062, -1037, -689, -1076, -553, -275, -262, +847, +479, +306, -29, -31, -462, -290, -612, -344,
|
||||
+15495, +12899, -4263, +3779, +5080, -3531, -900, +2885, -3629, -1828, +2258, +22, -1763, -951, +442, -1975, -1049, -1113, -557, -940, -769, +0, -446, +597, +677, +483, -199, +94, -302, -403, -398, -267,
|
||||
+17119, +13318, -5617, +3044, +5263, -2373, -1299, +2236, -3473, -1545, +2114, -220, -1690, -1270, +432, -2146, -1156, -1068, -496, -761, -890, +68, -296, +183, +744, +728, -384, +229, -162, -523, -141, -307,
|
||||
+18484, +13996, -6861, +2361, +5043, -1327, -1316, +1482, -3224, -1275, +1889, -488, -1425, -1754, +345, -2172, -1331, -893, -513, -608, -886, +7, -57, -56, +527, +1062, -513, +203, +21, -599, -22, -277,
|
||||
+19664, +14808, -7930, +1852, +4472, -629, -944, +743, -2898, -1130, +1684, -714, -1190, -2160, +165, -2109, -1400, -723, -585, -442, -817, -87, +159, -22, +135, +1403, -577, -74, +264, -623, -30, -70,
|
||||
+21117, +15043, -8651, +1665, +3562, -302, -433, +306, -2732, -998, +1479, -897, -1082, -2373, -85, -2001, -1270, -757, -612, -253, -784, -73, +231, +244, -130, +1411, -530, -488, +338, -544, +88, +69,
|
||||
+22154, +15465, -8959, +1402, +2531, -346, +86, +155, -2719, -964, +1298, -1197, -837, -2538, -368, -1715, -1223, -911, -611, -54, -781, -33, +268, +653, -384, +1073, -318, -957, +90, -192, +241, +104,
|
||||
+22859, +15907, -8818, +1234, +1297, -584, +637, +95, -2746, -892, +980, -1473, -344, -2665, -593, -1404, -1232, -1113, -586, +219, -920, +190, +386, +763, -501, +647, -217, -1200, -157, -60, +514, +428,
|
||||
+23324, +16162, -8220, +1233, -271, -830, +1044, +4, -2761, -848, +545, -1644, +393, -2819, -805, -1116, -1381, -1232, -481, +245, -798, +446, +127, +832, -496, +109, -143, -1012, -512, -218, +1023, +636,
|
||||
+23496, +16326, -7279, +1262, -1985, -1155, +1282, -135, -2863, -819, +135, -1617, +1191, -3031, -953, -1076, -1474, -1177, -641, +567, -852, +321, -9, +770, -595, -103, +21, -1077, -316, -427, +637, +1058,
|
||||
+23095, +16685, -5961, +1382, -3468, -1694, +1418, -258, -2996, -670, +47, -1596, +2016, -3064, -1350, -839, -1582, -979, -545, +371, -989, +403, -350, +690, -257, -300, +78, -651, -207, -824, +183, +1360,
|
||||
+23064, +16194, -4345, +1405, -4772, -2458, +1309, -309, -3246, -87, -265, -1329, +2641, -3203, -1669, -828, -1062, -1045, -1017, +329, -1074, +156, -379, +809, -266, -110, +348, -721, -327, -460, -318, +476,
|
||||
+22166, +16307, -2720, +1513, -5503, -3602, +868, +57, -3167, +189, -262, -1102, +3165, -3419, -1892, +19, -1444, -1300, -1087, -50, -1052, +281, -440, +743, +297, +10, -121, -326, +62, -941, -205, -296,
|
||||
+21370, +16040, -1198, +1538, -5866, -4987, +180, +1090, -3147, +120, +48, -770, +2709, -2688, -1726, -511, -1299, -1588, -1418, -44, -787, -13, -172, +1224, -173, +86, +190, -419, +152, -1134, +61, -580,
|
||||
+20588, +15763, -447, +2263, -6362, -6502, +294, +1839, -3312, +732, -314, -780, +3610, -2936, -1826, -471, -1919, -1347, -1286, -339, -634, +489, -63, +635, +27, +550, -117, -722, +816, -1169, -430, +0,
|
||||
+20517, +14351, +399, +2893, -7361, -6720, +201, +2186, -2610, +382, -514, +112, +3193, -2866, -1734, -1281, -1564, -810, -1919, -87, +325, -151, -301, +1086, -74, +249, +48, -598, +812, -904, -810, +141,
|
||||
+19676, +13347, +1269, +2990, -7493, -6742, +83, +2235, -1954, +838, -1855, +980, +3383, -3609, -1607, -1296, -1241, -963, -1499, +306, -188, -169, +134, +680, -311, +474, +114, -498, +603, -657, -632, -512,
|
||||
+18294, +12994, +1651, +2477, -6776, -5594, -1193, +2361, -74, -729, -2110, +2060, +2280, -3521, -925, -1755, -1040, +4, -1831, -24, +217, -146, -194, +523, -89, +412, +148, -368, +547, -585, -520, -748,
|
||||
+18558, +12123, -346, +2881, -6362, -4645, -59, +1181, -164, -263, -2409, +2048, +1834, -3453, -616, -1525, -435, -206, -2101, +563, +264, -775, -79, +639, -65, +370, -42, -65, +678, -907, -609, -386,
|
||||
+17685, +10480, -40, +3473, -6519, -2739, -508, +476, +794, -1230, -2572, +2593, +1476, -3576, +141, -1207, -497, -277, -1926, +798, -90, -892, +128, +624, -265, +467, +194, -122, +569, -901, -567, -322,
|
||||
+16309, +9199, +186, +4082, -5385, -2804, -279, +710, -5, -1375, -2021, +2397, +953, -2773, +531, -1321, -456, -212, -1629, +612, -269, -841, +361, +372, -412, +797, +264, -230, +451, -838, -585, -226,
|
||||
+15571, +11264, +2379, +478, -10208, -3446, +2999, +3275, -500, -1930, -3348, +266, +1652, -1984, +1186, -362, -580, +611, -665, +483, -71, -639, -236, -683, -414, +551, -551, -99, +973, -315, +229, -109,
|
||||
+13108, +11000, +3186, +1280, -8696, -4695, +2112, +2705, +415, -824, -3163, -516, +1162, -1069, +990, -408, -449, +725, -557, +276, +252, -440, -211, -595, -598, +266, -697, +52, +1118, -108, +414, -97,
|
||||
+11346, +10103, +3442, +1763, -7242, -4319, +1504, +1898, +542, -443, -2642, -793, +1114, -726, +553, -274, -403, +642, -397, +111, +268, -218, -281, -579, -486, +53, -591, +203, +993, +104, +363, -159,
|
||||
+9333, +9181, +4026, +1891, -5737, -3665, +628, +1442, +686, -179, -2080, -924, +1011, -560, +271, -128, -344, +546, -210, +21, +313, -35, -349, -508, -402, +17, -265, +291, +786, +199, +233, -195,
|
||||
+7824, +8565, +4450, +1794, -4594, -3174, +140, +1252, +671, +30, -1593, -927, +798, -461, +248, -40, -339, +534, -12, -10, +342, +33, -332, -281, -185, +20, -144, +273, +558, +171, +139, -239,
|
||||
+6337, +7830, +4715, +1908, -3553, -2897, -163, +1081, +702, +211, -1249, -839, +616, -437, +196, +111, -267, +479, +135, +12, +326, +212, -47, -34, -177, -218, -105, +167, +266, +120, +84, -158,
|
||||
+5342, +7158, +4878, +2188, -2903, -2714, -263, +1026, +804, +276, -973, -621, +425, -432, +323, +229, -177, +523, +156, +236, +666, +314, -37, +11, -270, -439, -68, +145, +155, +196, +77, -226,
|
||||
+4764, +6717, +4705, +2043, -2555, -2349, -213, +866, +792, +353, -756, -574, +302, -362, +407, +259, -158, +679, +475, +400, +570, +170, -131, -157, -526, -408, +47, -28, +159, +57, -96, +32,
|
||||
+4181, +6120, +4609, +2151, -2225, -2162, -181, +900, +848, +365, -518, -436, +242, -269, +393, +570, +370, +732, +393, +271, +373, -75, -324, -138, -536, -326, +93, -221, -12, +223, +50, -24,
|
||||
+4015, +5982, +4273, +1823, -2038, -1791, +35, +933, +871, +389, -235, -337, +148, +75, +824, +806, +274, +455, +265, +150, +178, -130, -231, -188, -435, -270, -151, -8, +202, +32, -30, +38,
|
||||
+3935, +5782, +3945, +1507, -1917, -1335, +323, +927, +964, +503, -86, -55, +602, +326, +626, +524, +61, +238, +130, +138, +142, -108, -297, -233, -424, -97, +144, -211, +2, +11, +59, +102,
|
||||
+3902, +5745, +3557, +1311, -1656, -1075, +626, +1068, +893, +711, +517, +29, +271, +228, +356, +317, +28, +184, +167, +138, +52, -157, -344, -161, +13, -100, -239, -186, +14, +16, +22, +148,
|
||||
+3628, +5656, +3399, +1258, -1213, -703, +858, +1220, +1301, +913, +184, -182, +3, -30, +266, +240, +91, +140, +96, +72, +8, -109, -120, +190, -242, -389, -174, -137, -134, -75, +225, -41,
|
||||
+3635, +5627, +3156, +1153, -667, -305, +1152, +1542, +949, +463, +84, -274, -67, -129, +266, +232, +17, +66, +88, +199, -87, +174, +189, -310, -329, -218, -244, -286, -93, -9, -62, +33,
|
||||
+3750, +5696, +2978, +1126, -254, +215, +1221, +1141, +606, +286, +8, -220, -48, -224, +233, +223, -143, +120, +323, +31, +156, +458, -282, -324, -203, -336, -370, -173, -80, -307, +26, +219,
|
||||
+3708, +6007, +3252, +1084, -197, +131, +973, +976, +487, +259, +136, -370, -69, -106, +43, +210, -33, +247, +171, +273, +554, -86, -293, -37, -371, -530, -251, -143, -337, -184, +155, +321,
|
||||
+3943, +6405, +3364, +855, -445, -300, +746, +1177, +555, +245, +158, -422, -186, -48, +127, +143, +129, +192, +83, +689, +384, -278, -109, -102, -392, -521, -225, -363, -322, +86, +221, +118,
|
||||
+3963, +6788, +3553, +597, -677, -627, +588, +1136, +500, +391, +206, -514, -153, +22, +70, +197, +285, -39, +123, +985, +227, -286, +1, -155, -441, -352, -267, -542, -311, +209, +364, -112,
|
||||
+3772, +6899, +3947, +501, -937, -727, +636, +1168, +340, +109, +160, -312, -140, -4, +244, +180, +122, +45, +73, +884, +451, -250, -58, -111, -413, -290, -294, -523, -289, +122, +331, -74,
|
||||
+3462, +6882, +4502, +695, -1202, -904, +656, +1374, +518, -169, -142, -383, -288, +151, +492, +188, +134, +104, -153, +774, +761, -195, -124, +19, -277, -262, -247, -438, -285, +127, +319, -81,
|
||||
+3402, +6922, +4775, +801, -1378, -1083, +663, +1537, +602, -245, -249, -453, -540, -124, +493, +404, +124, +134, -71, +426, +838, +18, -287, -73, -153, -110, -193, -451, -296, +175, +269, -23,
|
||||
+3560, +7157, +4846, +842, -1601, -1246, +801, +1630, +679, -335, -317, -376, -611, -299, +272, +320, +96, +184, +134, +295, +750, +284, -376, -324, -110, -14, -46, -352, -273, +168, +253, +68,
|
||||
+3781, +7518, +5064, +780, -1878, -1426, +861, +1887, +678, -490, -323, -360, -585, -337, +124, +225, -92, -87, +272, +304, +648, +580, -207, -590, -353, -33, +88, -214, -276, +256, +259, +93,
|
||||
+4023, +8013, +5260, +520, -2126, -1537, +904, +2110, +621, -684, -367, -338, -545, -334, +31, +151, -90, -326, +98, +316, +484, +602, +136, -551, -624, -186, +88, -177, -281, +258, +226, +119,
|
||||
+4437, +8672, +5470, +189, -2426, -1777, +1004, +2534, +471, -984, -417, -281, -536, -313, +40, +69, -119, -424, -33, +239, +301, +445, +325, -371, -639, -347, -13, -119, -335, +161, +141, +68,
|
||||
+4952, +9349, +5539, -179, -2758, -2011, +1219, +2888, +279, -1276, -463, -211, -592, -300, +102, -4, -169, -480, -76, +194, +168, +301, +339, -242, -691, -395, -6, -107, -357, +112, +26, -204,
|
||||
+5239, +10282, +5947, -647, -3196, -2226, +1311, +3315, +161, -1681, -491, -173, -597, -373, +170, -45, -294, -440, -175, +126, +127, +78, +331, -124, -648, -478, -149, -83, -176, +24, -84, -362,
|
||||
+5839, +11149, +6005, -1123, -3665, -2327, +1613, +3627, -71, -2065, -429, -99, -639, -410, +251, -61, -421, -436, -166, +117, +55, -75, +317, -59, -558, -473, -198, -174, -157, +173, -146, -406,
|
||||
+6264, +12031, +6260, -1503, -4165, -2511, +1902, +3881, -220, -2443, -428, +51, -706, -495, +320, -9, -559, -492, -144, +113, +44, -260, +228, +46, -480, -381, -268, -203, -217, +218, -114, -429,
|
||||
+6813, +12945, +6569, -1945, -4848, -2783, +2188, +4127, -523, -2951, -443, +204, -809, -654, +274, +56, -695, -599, -243, +84, +37, -469, +12, +64, -398, -293, -252, -328, -254, +98, -55, -527,
|
||||
+7209, +13717, +6921, -1967, -5316, -3090, +2544, +4308, -606, -3304, -485, +501, -832, -729, +300, +116, -725, -556, -280, +71, +96, -513, -156, +86, -225, -237, -54, -372, -184, +51, -70, -428,
|
||||
+7996, +14426, +6885, -1822, -5825, -3511, +3030, +4353, -912, -3620, -593, +764, -830, -921, +358, +119, -837, -534, -312, +44, +63, -481, -430, -53, +49, -227, +88, -308, -219, +114, -168, -425,
|
||||
+8882, +15071, +6412, -1835, -5966, -3673, +3408, +4119, -1227, -3662, -763, +899, -746, -1111, +359, +151, -942, -516, -330, +17, -16, -403, -535, -393, +280, -94, +75, -119, -291, +140, -109, -538,
|
||||
+10567, +15752, +4909, -1935, -5684, -3567, +3668, +3636, -1744, -3453, -930, +847, -522, -1336, +279, +135, -969, -534, -297, -7, -169, -364, -497, -748, +299, +223, -60, +142, -209, -44, +74, -643,
|
||||
+11943, +15859, +3693, -1168, -5342, -4152, +3859, +3672, -2239, -3456, -946, +824, -414, -1484, +211, +82, -987, -499, -174, -100, -272, -362, -415, -898, +70, +599, -127, +237, +12, -204, +166, -634,
|
||||
+13286, +15772, +2438, -128, -4984, -4823, +4009, +3750, -2786, -3502, -799, +696, -411, -1556, +156, -56, -1055, -395, +29, -275, -377, -305, -450, -921, -205, +832, -22, +179, +243, -241, +88, -561,
|
||||
+15203, +16245, +66, +61, -3930, -4645, +3668, +3392, -3154, -3516, -581, +453, -338, -1692, +34, -193, -1068, -347, +256, -295, -574, -274, -592, -759, -402, +757, +277, +182, +289, -131, -87, -538,
|
||||
+17246, +16423, -2122, -11, -3063, -3961, +3236, +2949, -3315, -3590, -360, +310, -300, -1854, +21, -379, -1001, -238, +408, -257, -762, -185, -742, -584, -408, +586, +464, +330, +189, -58, -105, -673,
|
||||
+19117, +17194, -4525, -594, -2040, -2928, +2541, +2436, -3174, -3955, -153, +154, -238, -2084, -35, -538, -893, -103, +477, -124, -1066, -60, -862, -458, -281, +408, +389, +584, +66, -198, +49, -844,
|
||||
+20721, +17777, -6299, -1368, -1442, -1849, +1965, +2056, -2976, -4357, -43, +20, -202, -2215, -94, -626, -745, -20, +462, +11, -1311, +50, -912, -421, -24, +317, +54, +773, +39, -439, +197, -803,
|
||||
+22510, +18390, -7885, -2507, -1141, -610, +1490, +1800, -2821, -4825, -36, -196, -92, -2264, -98, -656, -568, +0, +406, +174, -1496, +186, -1014, -271, +276, +136, -341, +713, +119, -602, +263, -543,
|
||||
+23764, +19077, -8920, -3523, -1276, +188, +1429, +1689, -2771, -5201, -193, -427, +128, -2191, -88, -582, -532, -60, +345, +366, -1555, +193, -996, -85, +266, +23, -631, +431, +299, -553, +232, -344,
|
||||
+24818, +19733, -9528, -4328, -1918, +770, +1688, +1610, -2757, -5522, -511, -645, +585, -2065, -55, -440, -631, -162, +378, +612, -1616, +251, -901, -119, +151, -32, -905, +195, +543, -403, +171, -190,
|
||||
+25942, +20257, -9828, -5006, -3337, +1229, +2251, +1491, -2816, -5884, -1016, -737, +1357, -2026, +75, -408, -894, -120, +477, +717, -1428, +314, -1223, -176, -2, -219, -932, +91, +634, -169, +260, -194,
|
||||
+26806, +20370, -9612, -5429, -4920, +1516, +2696, +1428, -3018, -6052, -1361, -633, +1984, -1981, +130, -617, -894, -5, +427, +963, -1258, -100, -1423, -216, -233, -165, -732, -55, +587, +188, +254, -445,
|
||||
+27209, +20584, -8793, -5848, -6861, +1389, +3245, +1326, -3300, -5756, -1708, -571, +2761, -2008, -124, -572, -811, +83, +640, +854, -1485, -319, -1727, -286, -130, -52, -610, -82, +598, +192, +317, -394,
|
||||
+26893, +21151, -7832, -5916, -8592, +716, +3831, +1043, -3056, -5275, -2081, -436, +3209, -2095, -313, -337, -686, +446, +148, +578, -1361, -677, -1772, -79, -85, -62, -326, -96, +288, +256, +729, -628,
|
||||
+26953, +20650, -6193, -5839, -10706, -128, +4025, +1350, -2673, -4655, -2334, -397, +3476, -2270, -280, +333, -640, -63, -135, +292, -1261, -713, -1609, +24, -62, +134, -367, -195, +342, +253, +839, -600,
|
||||
+26223, +20702, -4716, -5564, -12304, -1451, +4411, +2099, -2421, -4083, -2432, -598, +3439, -2035, +238, +317, -1138, -105, -496, +286, -908, -750, -1436, +173, -78, -80, -177, -33, +173, +164, +1062, -575,
|
||||
+25928, +19969, -3485, -5141, -13936, -2549, +5094, +2717, -2372, -3260, -2726, -1115, +3984, -1704, +8, +193, -1565, -173, -413, +254, -689, -651, -1111, -74, -302, +129, -24, -206, +176, +212, +1048, -582,
|
||||
+25176, +19122, -2331, -4479, -15530, -3096, +5493, +3261, -1783, -2862, -3340, -611, +4094, -2064, +150, -498, -1520, +306, -690, +346, -212, -559, -1329, -185, -92, +42, -36, -161, +240, +170, +921, -542,
|
||||
+24482, +17970, -1385, -4296, -15673, -3520, +5482, +4107, -1928, -2384, -3245, -840, +4078, -2209, -307, -382, -1158, +232, -617, +670, -229, -809, -1085, -111, -314, +49, +102, -188, +256, +76, +933, -522,
|
||||
+23018, +16730, -558, -3503, -15157, -4048, +5380, +4222, -1077, -2064, -4052, -288, +3518, -2565, -42, -296, -1035, +526, -341, +255, -181, -591, -933, -333, -446, +264, +149, -398, +317, +312, +625, -550,
|
||||
+21612, +15388, -80, -2338, -14307, -4401, +4806, +4911, -877, -2366, -3925, -404, +3244, -2585, +155, -320, -674, +881, -905, +291, +164, -706, -883, -428, -426, +443, -108, -467, +714, +169, +330, -367,
|
||||
+19859, +13489, +594, -510, -13595, -4524, +5021, +4279, -755, -2023, -4414, +179, +2843, -2732, +498, -73, -330, +471, -963, +610, +149, -898, -638, -432, -427, +380, -223, -282, +814, +29, +168, -248,
|
||||
+17742, +12321, +1537, +213, -12421, -3676, +4012, +3612, -294, -2291, -3920, +331, +2249, -2515, +892, +37, -643, +510, -767, +581, +11, -855, -358, -539, -531, +491, -270, -331, +960, -123, +115, -173,
|
||||
+16821, +11926, +463, -1706, -11380, -169, +5057, +1524, -1492, -1439, -2644, -359, +2193, -2391, +635, +125, -644, +317, -422, +472, -172, -610, -637, -211, -252, -7, -26, -80, -218, -217, +829, -147,
|
||||
+13656, +11995, +3238, -883, -11164, -2746, +3338, +2611, +688, -1041, -2888, -1083, +1213, -1539, +1161, +189, -818, +634, -355, +123, +274, -342, -515, +152, -873, -436, -4, -321, +327, +309, +783, -46,
|
||||
+11207, +10925, +3942, -83, -8816, -2936, +2399, +2271, +597, -709, -2174, -1110, +823, -992, +937, +143, -694, +584, -237, +52, +375, -217, -303, +162, -792, -361, +105, -252, +214, +381, +632, -19,
|
||||
+9243, +9941, +4245, +657, -6939, -2976, +1760, +1792, +578, -304, -1653, -1098, +643, -655, +689, +159, -542, +528, -131, +56, +430, -13, -221, +210, -469, -319, +52, -319, +110, +335, +494, +43,
|
||||
+7775, +9004, +4364, +1074, -5566, -2771, +1288, +1356, +632, -19, -1266, -996, +487, -456, +486, +214, -418, +456, -8, +91, +463, +193, -8, +266, -378, -438, -88, -360, -112, +272, +544, +30,
|
||||
+6749, +8329, +4226, +1199, -4454, -2378, +954, +1109, +723, +141, -897, -819, +428, -339, +428, +308, -281, +463, +96, +331, +672, +327, +10, +166, -357, -510, -211, -393, -151, +319, +576, +31,
|
||||
+5988, +7653, +4116, +1168, -3765, -2038, +743, +915, +737, +259, -623, -668, +285, -262, +442, +295, -206, +564, +342, +402, +543, +169, -105, +70, -443, -594, -251, -433, -272, +334, +502, -77,
|
||||
+5467, +7250, +3847, +1019, -3110, -1692, +669, +871, +822, +369, -365, -484, +245, -133, +474, +473, +20, +567, +337, +288, +369, +117, -150, +13, -324, -594, -356, -414, -226, +271, +602, +138,
|
||||
+5122, +6973, +3542, +803, -2565, -1389, +713, +947, +893, +463, -170, -291, +235, +82, +633, +446, -49, +345, +308, +240, +201, +133, -77, -9, -324, -573, -352, -476, -45, +494, +363, +16,
|
||||
+4855, +6836, +3247, +531, -2098, -1103, +840, +1094, +882, +577, -75, -121, +401, +26, +454, +321, -151, +130, +276, +269, +118, +152, -61, -115, -199, -507, -538, -83, +76, +24, +184, +126,
|
||||
+4686, +6807, +3020, +381, -1698, -797, +985, +1300, +880, +654, +193, -260, +327, -18, +295, +312, -217, +5, +244, +427, +89, +60, +69, +22, -305, -328, -97, -385, -172, +69, +91, +154,
|
||||
+4632, +6769, +2880, +360, -1379, -630, +1032, +1346, +1008, +601, +155, -416, +54, +91, +208, +254, -266, -94, +300, +314, +94, +118, +154, -112, -59, +83, -557, -570, -137, +42, +28, +65,
|
||||
+4540, +6825, +2991, +442, -1145, -666, +903, +1315, +922, +656, +103, -490, -32, -70, +234, +239, -193, -130, +219, +288, +5, +292, +9, +89, +428, -439, -684, -356, -314, -42, +168, -24,
|
||||
+4565, +7043, +3133, +398, -1092, -628, +698, +1105, +781, +505, +302, -393, -208, -57, +80, +210, -27, -27, +131, +97, +164, +95, +10, +715, +96, -727, -439, -390, -341, +7, +168, -278,
|
||||
+4628, +7376, +3330, +175, -1131, -632, +658, +1096, +468, +306, +276, -396, -10, -64, +41, +226, -104, +83, +212, +65, +61, -40, +256, +815, -181, -624, -368, -423, -196, +109, -11, -411,
|
||||
+4617, +7799, +3588, -63, -1282, -806, +761, +1267, +342, +103, +9, -566, -109, +89, +288, +207, -102, +37, +103, +149, +142, -173, +222, +878, -329, -612, -244, -446, -47, +197, -164, -416,
|
||||
+4660, +8175, +3965, -277, -1581, -952, +885, +1487, +358, +16, -136, -742, -411, +6, +351, +359, +99, +41, +67, +54, +185, -145, +158, +875, -393, -637, -194, -414, +89, +273, -162, -421,
|
||||
+4721, +8663, +4296, -438, -1910, -1208, +1075, +1666, +396, -64, -205, -776, -575, -199, +234, +288, +60, +190, +260, +39, +105, -43, -107, +796, -78, -840, -343, -310, +149, +286, -89, -348,
|
||||
+4872, +9194, +4729, -774, -2386, -1225, +1197, +1899, +429, -345, -152, -738, -728, -229, +85, +167, -114, +11, +383, +94, +153, +194, -391, +530, +269, -869, -518, -280, +55, +314, -13, -367,
|
||||
+5066, +9823, +5271, -1107, -2955, -1313, +1335, +2152, +396, -624, -133, -598, -828, -241, +24, +42, -162, -203, +299, +184, -39, +336, -145, +68, +454, -442, -819, -503, +69, +300, -63, -319,
|
||||
+5153, +10511, +6095, -1484, -3588, -1456, +1423, +2504, +356, -975, -219, -396, -876, -284, +78, -92, -239, -325, +171, +296, -163, +80, +60, -117, +343, +144, -711, -771, -136, +164, +7, -305,
|
||||
+5279, +11273, +7005, -1898, -4346, -1576, +1570, +2874, +319, -1413, -325, -192, -896, -360, +145, -111, -363, -399, +61, +261, +19, -193, -117, -56, -9, +423, -34, -872, -482, +162, -138, -388,
|
||||
+6056, +12428, +7017, -2743, -5015, -1595, +2092, +3133, -74, -1835, -369, -82, -887, -433, +159, -124, -505, -444, +1, +176, +57, -207, -371, -191, -116, +297, +399, -455, -738, -65, -85, -546,
|
||||
+6550, +13417, +7566, -3351, -5854, -1576, +2466, +3359, -262, -2321, -480, +199, -992, -483, +233, -211, -561, -459, -82, +172, +17, -196, -387, -532, -129, +223, +460, +107, -612, -458, -73, -511,
|
||||
+7012, +14309, +8271, -3829, -6828, -1561, +2860, +3523, -456, -2805, -697, +575, -1040, -702, +326, -213, -692, -488, -58, +49, +67, -318, -318, -681, -441, +323, +421, +317, -109, -624, -463, -340,
|
||||
+8016, +15374, +8120, -4423, -7514, -1497, +3500, +3557, -967, -3143, -754, +778, -1014, -873, +371, -263, -697, -565, +8, +40, -65, -294, -389, -676, -607, +208, +557, +311, +173, -239, -863, -535,
|
||||
+8871, +16239, +8063, -4588, -8132, -1638, +4115, +3491, -1344, -3391, -963, +994, -922, -1121, +393, -248, -762, -536, +34, +55, -184, -324, -431, -662, -593, -42, +629, +427, +134, +214, -755, -1041,
|
||||
+9741, +17020, +7674, -4576, -8426, -2000, +4611, +3393, -1757, -3551, -1213, +1115, -851, -1378, +299, -217, -824, -499, +46, +51, -282, -489, -415, -741, -447, -171, +355, +641, +79, +272, -284, -1349,
|
||||
+11312, +17790, +6362, -4799, -8173, -2096, +4973, +3237, -2301, -3658, -1190, +1112, -886, -1482, +185, -250, -754, -451, +117, +102, -439, -579, -427, -793, -304, +10, -28, +635, +235, +100, +114, -1241,
|
||||
+13177, +18485, +4498, -4942, -7590, -1947, +5032, +3048, -2673, -3843, -991, +968, -867, -1596, +107, -286, -639, -361, +165, +232, -672, -529, -499, -772, -195, +286, -298, +389, +407, -34, +287, -927,
|
||||
+15061, +19221, +2298, -5197, -6823, -1696, +4782, +2846, -2873, -4171, -778, +660, -800, -1706, -5, -268, -588, -254, +120, +358, -929, -400, -614, -747, -72, +413, -441, -8, +458, -76, +301, -594,
|
||||
+17417, +19661, -218, -5533, -6027, -1097, +4358, +2666, -3090, -4449, -601, +308, -686, -1718, -14, -284, -463, -238, +124, +408, -1064, -243, -713, -651, +62, +367, -575, -268, +316, -31, +381, -321,
|
||||
+19867, +19942, -2698, -5917, -5419, -356, +3943, +2529, -3315, -4768, -533, -59, -432, -1576, -30, -272, -359, -356, +203, +452, -1089, -118, -778, -495, +49, +184, -640, -440, +103, +121, +489, -151,
|
||||
+22000, +20274, -4928, -6244, -5183, +422, +3657, +2387, -3535, -5191, -499, -408, +124, -1486, -39, -209, -489, -410, +327, +558, -1091, -6, -842, -510, -62, +53, -686, -527, +27, +247, +412, +120,
|
||||
+23867, +20630, -6764, -6611, -5435, +1219, +3584, +2132, -3790, -5664, -426, -579, +849, -1544, +115, -346, -693, -253, +402, +737, -1086, +70, -1208, -570, -77, -89, -681, -321, -84, +142, +497, +304,
|
||||
+25427, +20921, -8048, -7062, -6069, +1884, +3693, +1754, -4141, -5893, -210, -678, +1594, -1604, +126, -548, -678, -23, +392, +982, -1152, -266, -1531, -447, -207, -3, -478, -227, -288, +201, +484, +187,
|
||||
+26670, +20956, -8821, -7361, -6968, +2286, +3959, +1161, -4414, -5482, -257, -597, +2261, -1827, +18, -485, -493, +96, +432, +895, -1493, -446, -1665, -450, +33, +175, -509, -150, -228, -15, +349, +351,
|
||||
+27247, +21029, -9279, -7221, -8186, +2443, +4316, +433, -4111, -5058, -277, -461, +2624, -2135, +8, -68, -470, +172, -50, +659, -1495, -578, -1725, -94, +295, -26, -297, -74, -411, -173, +430, +303,
|
||||
+27900, +20315, -8903, -7184, -9921, +2431, +4704, +385, -3980, -4367, -496, -493, +2857, -2265, +375, +207, -681, -337, -225, +556, -1409, -535, -1534, +66, +228, +14, -233, -136, -400, -267, +410, +268,
|
||||
+27607, +19995, -8273, -6960, -11863, +2111, +5727, +206, -3669, -3625, -950, -750, +3372, -2159, +511, +126, -1428, -249, -334, +460, -1027, -385, -1566, +110, +211, -88, -105, -186, -370, -401, +501, +177,
|
||||
+27622, +18453, -7307, -6733, -13561, +2585, +6218, +129, -3285, -2980, -1630, -393, +3761, -2468, +529, -441, -1518, +13, -480, +602, -588, -563, -1536, +165, +105, -89, -91, -163, -357, -425, +580, -7,
|
||||
+26712, +17271, -6277, -6285, -14362, +2609, +6500, +415, -3110, -2459, -1751, -325, +3747, -2769, +192, -404, -1346, +67, -259, +700, -500, -685, -1381, +215, -122, -46, -21, -142, -291, -476, +628, -31,
|
||||
+24769, +16230, -5111, -5257, -14397, +2104, +6670, +474, -2600, -1910, -2144, -355, +3491, -3153, +319, -229, -1416, +584, -304, +502, -383, -651, -1149, -88, -115, +8, -18, -89, -321, -449, +713, -173,
|
||||
+22531, +14663, -3328, -4140, -13801, +1449, +6057, +1180, -2109, -1891, -2239, -499, +2901, -2827, +365, -277, -887, +650, -524, +392, -96, -669, -1178, -67, -149, -9, +23, -125, -229, -396, +626, -144,
|
||||
+19895, +13154, -1419, -2898, -12707, +438, +5719, +1680, -2070, -1480, -2520, -641, +2754, -2677, +403, +34, -653, +479, -618, +548, -55, -828, -839, -119, -236, +37, -10, -61, -202, -414, +734, -50,
|
||||
+15813, +10164, -3306, -1259, -4293, +3357, +1973, -2111, -1944, +200, +219, -308, +1352, -2193, +64, -117, -1126, +153, -436, +60, -137, -521, -663, +805, -86, +19, +120, -674, -64, -483, -254, +28,
|
||||
+13540, +9962, -1922, -1329, -4062, +2676, +2356, -1429, -1777, +3, -53, -302, +1192, -1816, -26, +30, -863, +65, -256, +68, -137, -483, -700, +634, +28, +18, +255, -495, -126, -392, -252, -65,
|
||||
+11634, +9561, -699, -1265, -3629, +2134, +2474, -898, -1471, -172, -210, -167, +1001, -1414, -33, +173, -616, +55, -78, +97, -92, -391, -629, +503, +182, +60, +264, -359, -148, -296, -278, -94,
|
||||
+10116, +9195, +85, -1190, -3168, +1756, +2451, -457, -1159, -296, -215, -72, +824, -1068, +57, +267, -418, +80, +67, +164, -62, -236, -495, +399, +241, +62, +228, -255, -153, -255, -222, -97,
|
||||
+8972, +8865, +505, -1212, -2723, +1474, +2315, -138, -916, -335, -184, -65, +679, -767, +131, +280, -267, +100, +140, +232, -22, -124, -428, +222, +224, +45, +106, -204, -143, -199, -220, -223,
|
||||
+8143, +8550, +717, -1226, -2288, +1267, +2150, +132, -720, -286, -144, -49, +640, -554, +197, +300, -154, +119, +220, +280, -45, -61, -392, +43, +178, +16, +16, -111, -123, -218, -232, -196,
|
||||
+7519, +8353, +812, -1237, -1913, +1117, +2025, +376, -587, -178, -1, -84, +685, -393, +217, +358, -60, +126, +213, +332, -84, -72, -329, -119, +124, +96, -34, -68, -117, -163, -197, -307,
|
||||
+7138, +8193, +814, -1279, -1576, +1064, +1902, +541, -519, -85, +237, -175, +678, -205, +145, +407, -22, +33, +193, +347, -106, -168, -290, -132, +40, +147, -63, -81, -15, -226, -137, +56,
|
||||
+6765, +8188, +868, -1293, -1277, +1051, +1806, +584, -405, -124, +486, -108, +449, +28, +127, +224, +67, +7, +73, +339, -51, -243, -320, +0, -67, +74, +55, -80, -93, +50, +86, -210,
|
||||
+6619, +8107, +942, -1282, -1022, +1117, +1715, +528, -435, -63, +479, +47, +396, -99, +275, +103, -92, +116, +36, +186, -20, -104, -395, -86, -10, +55, +1, -128, +248, +155, -185, -146,
|
||||
+6506, +8197, +996, -1294, -821, +1178, +1651, +459, -560, -146, +509, -44, +460, -45, +85, +200, -171, -75, +154, +145, -147, -20, -290, -290, -60, +165, -210, +91, +457, -145, -98, -174,
|
||||
+6582, +8378, +972, -1387, -629, +1360, +1678, +371, -630, -289, +430, -31, +347, +59, +235, +84, -170, +9, -19, +188, -18, -105, -290, -206, -28, -83, -58, +442, +120, -133, +100, -328,
|
||||
+6729, +8662, +933, -1675, -529, +1529, +1750, +352, -860, -415, +386, -244, +217, +58, +206, +210, -193, -125, +73, +64, -149, +23, -388, -231, +36, -212, +36, +433, -79, -64, +4, -312,
|
||||
+6891, +9095, +950, -1986, -500, +1682, +1851, +373, -983, -585, +394, -308, -13, -44, +240, +173, -175, +14, +14, +51, -151, -125, -432, -103, +46, -279, +169, +405, -280, -72, +3, -309,
|
||||
+7140, +9633, +936, -2394, -433, +1844, +1940, +403, -1165, -606, +441, -410, -140, -123, +140, +125, -224, -22, +162, +113, -243, -123, -493, -210, +171, -184, +103, +464, -305, -188, -101, -278,
|
||||
+7579, +10153, +808, -2790, -377, +2061, +1958, +319, -1378, -620, +599, -484, -299, -248, +140, +31, -407, -65, +163, +117, -205, -114, -553, -215, +158, -225, +53, +587, -241, -398, -127, -310,
|
||||
+8098, +10746, +572, -3255, -297, +2282, +1951, +145, -1630, -671, +779, -545, -492, -334, +56, -74, -517, -231, +85, +61, -318, -68, -487, -259, +155, -163, -275, +532, +118, -570, -295, -288,
|
||||
+8856, +11416, +228, -3688, -131, +2625, +1937, -65, -1888, -582, +1023, -544, -642, -393, +130, -159, -647, -205, +40, -68, -349, -125, -337, -110, +114, -18, -391, +244, +381, -387, -478, -229,
|
||||
+9699, +12034, -166, -4109, -4, +2965, +1853, -341, -2231, -485, +1256, -561, -825, -509, +157, -201, -806, -277, +86, -284, -419, -202, -354, +141, +75, -8, -343, -105, +372, -52, -654, -293,
|
||||
+10543, +12775, -545, -4510, +87, +3328, +1796, -636, -2510, -451, +1566, -593, -960, -599, +156, -239, -879, -366, +153, -404, -550, -174, -435, +353, +148, -50, -279, -255, +87, +310, -515, -582,
|
||||
+11200, +13601, -758, -4805, +51, +3618, +1817, -936, -2667, -529, +1865, -619, -1077, -658, +152, -290, -948, -411, +137, -381, -707, -102, -513, +487, +276, -91, -256, -301, -183, +365, -56, -808,
|
||||
+11970, +14337, -1048, -4982, -71, +3819, +1800, -1224, -2823, -587, +2067, -657, -1227, -698, +129, -342, -1036, -477, +85, -363, -801, -49, -525, +479, +403, -110, -295, -362, -353, +170, +366, -705,
|
||||
+12952, +14790, -1411, -4961, -192, +3874, +1746, -1433, -2954, -613, +2172, -717, -1346, -744, +115, -409, -1087, -567, +16, -356, -787, -59, -428, +439, +419, -85, -317, -480, -441, -15, +471, -306,
|
||||
+13912, +15283, -1898, -4796, -288, +3733, +1713, -1566, -3031, -703, +2247, -785, -1394, -782, +55, -432, -1125, -661, -51, -311, -721, -96, -300, +422, +338, -39, -314, -612, -519, -71, +296, +100,
|
||||
+14855, +15823, -2738, -4516, -305, +3389, +1721, -1674, -3103, -885, +2277, -894, -1325, -878, -28, -456, -1189, -726, -166, -184, -719, -109, -219, +375, +189, +34, -370, -698, -563, -131, +49, +307,
|
||||
+16338, +16003, -4097, -3971, -183, +3015, +1641, -1812, -3218, -959, +2300, -1062, -1053, -1052, -10, -553, -1252, -711, -213, -61, -766, +9, -305, +359, +93, +64, -446, -677, -520, -329, -54, +380,
|
||||
+18251, +15738, -5808, -3185, -135, +2789, +1385, -1959, -3407, -901, +2346, -1243, -701, -1229, +42, -723, -1269, -588, -226, -66, -699, +25, -533, +532, -57, +38, -378, -632, -576, -478, +14, +227,
|
||||
+20108, +15232, -7463, -2359, -182, +2680, +993, -2135, -3628, -757, +2465, -1466, -282, -1397, +30, -889, -1150, -413, -456, +70, -740, -222, -483, +617, -261, +207, -289, -809, -541, -427, -149, +45,
|
||||
+21818, +14565, -8920, -1528, -323, +2633, +590, -2360, -3741, -408, +2485, -1626, +257, -1681, +37, -834, -979, -443, -529, +77, -986, -154, -547, +693, -157, +334, -410, -839, -327, -606, -328, +75,
|
||||
+23103, +13939, -10069, -743, -746, +2659, +301, -2677, -3587, -100, +2394, -1612, +709, -2069, +297, -672, -1108, -278, -883, +30, -908, -351, -497, +1045, -177, +252, -316, -804, -379, -726, -359, +57,
|
||||
+23945, +13086, -10548, -173, -1474, +2865, +166, -2907, -3401, +227, +2202, -1525, +1022, -2203, +552, -677, -1107, -549, -996, +157, -1089, -304, -261, +1165, -310, +418, -308, -941, -344, -785, -396, +51,
|
||||
+24255, +12118, -10245, -13, -2426, +3265, +310, -3204, -3183, +647, +1733, -1352, +1565, -2480, +734, -599, -1582, -399, -1019, +24, -846, -257, -242, +1202, -199, +374, -346, -1003, -311, -777, -466, +127,
|
||||
+23709, +11520, -9531, -151, -3388, +3855, +550, -3483, -2789, +731, +1250, -841, +1752, -2633, +801, -862, -1583, -318, -1087, +206, -657, -373, -274, +1353, -271, +302, -334, -1032, -204, -865, -432, +235,
|
||||
+22428, +11143, -8405, -496, -4041, +4230, +889, -3448, -2615, +728, +1070, -660, +1947, -2748, +486, -621, -1697, -171, -896, +282, -583, -459, -269, +1324, -316, +161, -148, -1048, -191, -833, -297, +216,
|
||||
+20761, +10556, -6721, -940, -4366, +4259, +1328, -3270, -2442, +888, +519, -254, +1808, -2851, +481, -564, -1534, -32, -625, +157, -458, -456, -349, +1175, -358, +206, -68, -1025, -144, -651, -305, +204,
|
||||
+18483, +10322, -5051, -1232, -4488, +3998, +1699, -2851, -2083, +521, +346, -174, +1484, -2533, +230, -316, -1365, +115, -496, +12, -245, -474, -558, +987, -219, +124, +13, -912, -46, -573, -264, +159,
|
||||
+15151, +10407, -3905, -1083, -1883, +2118, +367, -2185, -1952, +542, +790, -175, +1158, -1491, +303, +11, -942, -141, -277, +14, -417, -305, -403, +619, -260, -27, +128, -617, -289, -452, -406, -109,
|
||||
+12885, +10154, -2446, -1435, -1886, +1994, +819, -1625, -1685, +115, +676, -116, +950, -1122, +70, +152, -656, +7, -100, +33, -249, -339, -518, +467, -154, -64, +221, -437, -240, -376, -360, -167,
|
||||
+11026, +9815, -1373, -1604, -1732, +1727, +1082, -1042, -1489, -153, +594, -120, +851, -783, -35, +259, -348, +25, +24, +163, -205, -275, -535, +286, -60, -104, +181, -299, -203, -314, -276, -258,
|
||||
+9638, +9479, -718, -1704, -1525, +1463, +1205, -627, -1291, -289, +532, -105, +728, -476, -29, +265, -147, +9, +102, +238, -168, -228, -548, +99, -70, -181, +55, -160, -166, -274, -267, -318,
|
||||
+8752, +9179, -333, -1745, -1266, +1296, +1255, -331, -1103, -308, +517, +6, +654, -256, +108, +218, -57, +66, +139, +248, -132, -162, -550, -73, -107, -216, +35, -13, -164, -279, -126, -282,
|
||||
+8140, +9001, -85, -1784, -995, +1204, +1247, -134, -1072, -291, +536, +70, +685, -204, +206, +280, -165, +40, +195, +187, -211, -72, -529, -292, -102, -127, -36, -76, -58, -138, -270, -89,
|
||||
+7821, +8936, +29, -1810, -714, +1265, +1138, -40, -1096, -420, +649, +5, +642, -11, +138, +306, -111, -183, +147, +285, -330, -213, -387, -248, -250, -102, -97, -86, +22, -265, +130, +187,
|
||||
+7807, +9028, -50, -1866, -441, +1451, +1138, -195, -1118, -490, +518, +2, +517, +35, +307, +254, -153, -103, +7, +126, -244, -245, -496, -140, -99, -332, -144, +49, -205, +61, +387, -266,
|
||||
+7883, +9354, -84, -2058, -175, +1671, +1191, -268, -1313, -554, +542, -204, +353, +81, +268, +401, -95, -139, +119, +41, -495, -190, -362, -215, -155, -154, -74, -308, -29, +393, -17, -331,
|
||||
+8309, +9731, -294, -2293, +42, +1934, +1203, -363, -1445, -664, +574, -270, +131, -85, +298, +391, -163, +29, +228, -28, -529, -302, -516, -77, -71, -224, -65, -236, +37, +234, -157, -305,
|
||||
+8910, +10272, -662, -2606, +320, +2118, +1145, -521, -1640, -652, +647, -370, -95, -197, +260, +249, -276, +1, +311, +7, -540, -340, -597, -115, -162, -109, -41, -330, +23, +288, -224, -561,
|
||||
+9705, +10883, -1159, -2876, +618, +2308, +939, -735, -1827, -569, +847, -551, -252, -350, +282, +190, -540, -53, +297, -89, -533, -247, -636, +1, -229, -304, +0, -239, -164, +169, +30, -627,
|
||||
+10729, +11542, -1791, -3053, +931, +2475, +682, -1055, -1976, -419, +1145, -742, -457, -399, +293, +130, -657, -195, +215, -136, -668, -129, -569, +112, -117, -431, -109, -273, -261, +33, +231, -480,
|
||||
+11880, +12255, -2434, -3089, +1163, +2572, +450, -1357, -2085, -232, +1467, -892, -621, -438, +381, +30, -732, -214, +65, -162, -709, -100, -437, +212, -28, -368, -165, -380, -411, -90, +291, -64,
|
||||
+13138, +12910, -3157, -3037, +1198, +2492, +221, -1627, -2212, -103, +1693, -1094, -727, -513, +408, -69, -857, -306, -36, -187, -773, -78, -367, +223, -33, -259, -244, -476, -574, -270, +164, +260,
|
||||
+14397, +13579, -3910, -2827, +1090, +2265, +96, -1784, -2287, -52, +1872, -1249, -736, -567, +401, -118, -956, -410, -92, -132, -795, +4, -347, +213, -84, -122, -283, -544, -622, -487, +74, +387,
|
||||
+15830, +13982, -4898, -2472, +856, +1874, -58, -1916, -2412, -69, +1931, -1394, -672, -679, +358, -219, -1064, -512, -131, -146, -801, +55, -460, +223, -217, -78, -273, -623, -663, -737, +48, +327,
|
||||
+17467, +14082, -6145, -1897, +641, +1483, -284, -1985, -2544, -62, +2082, -1574, -443, -758, +315, -348, -1052, -474, -316, -34, -792, -77, -456, +264, -381, +42, -169, -787, -651, -765, -87, +204,
|
||||
+19204, +13692, -7428, -1120, +469, +1144, -634, -1991, -2737, +205, +2197, -1785, +24, -916, +275, -357, -852, -637, -399, +114, -1061, -13, -468, +245, -296, +208, -219, -909, -451, -819, -365, +209,
|
||||
+20434, +13223, -8548, -342, +182, +828, -924, -2160, -2725, +468, +2161, -1789, +445, -1242, +435, -205, -999, -575, -649, -4, -1029, -158, -482, +542, -293, +181, -169, -874, -514, -927, -442, +127,
|
||||
+21071, +12403, -8865, +245, -318, +823, -1130, -2243, -2635, +724, +2101, -1684, +725, -1293, +626, -269, -883, -830, -829, +105, -1203, -105, -238, +653, -371, +371, -143, -1016, -532, -886, -493, +33,
|
||||
+20789, +11662, -8363, +332, -911, +1138, -984, -2430, -2493, +1026, +1715, -1379, +1228, -1581, +803, -170, -1256, -633, -926, +9, -905, -125, -208, +782, -256, +313, -208, -993, -501, -825, -526, -5,
|
||||
+19596, +11016, -7150, -54, -1442, +1677, -696, -2554, -2277, +940, +1405, -817, +1246, -1536, +683, -288, -1142, -645, -762, +96, -739, -256, -171, +923, -379, +209, -146, -915, -439, -791, -471, +64,
|
||||
+17572, +10705, -5607, -659, -1779, +2017, -199, -2475, -2231, +834, +1110, -554, +1413, -1693, +462, -69, -1229, -319, -565, +61, -598, -344, -187, +729, -361, +89, -38, -790, -417, -617, -384, -60,
|
||||
+13984, +10256, -4374, -387, +520, +1170, -465, -1651, -1737, +620, +1299, -598, +593, -692, +507, -106, -759, -500, -601, +13, -482, -134, -166, +603, -169, +64, -79, -688, -462, -543, -415, -231,
|
||||
+12758, +10312, -3687, -1357, +269, +1735, +98, -1444, -1892, +26, +1171, -327, +678, -523, +452, +210, -645, -277, -231, -18, -408, -233, -377, +567, -155, -104, +72, -516, -401, -434, -355, -174,
|
||||
+11716, +10426, -3021, -2050, -38, +1840, +528, -1068, -1835, -336, +989, -214, +710, -348, +420, +365, -440, -231, -16, +39, -429, -185, -574, +332, -35, -237, +26, -307, -370, -373, -221, -235,
|
||||
+11134, +10529, -2662, -2372, -80, +1872, +687, -929, -1758, -466, +868, -263, +670, -278, +447, +463, -382, -147, +37, -28, -515, -135, -648, +44, +50, -206, -64, -271, -287, -346, -196, -161,
|
||||
+11076, +10636, -2726, -2397, +319, +2006, +654, -1075, -1802, -427, +898, -371, +393, -170, +406, +444, -274, -100, +119, -97, -686, -259, -554, +17, -61, -105, -68, -278, -240, -444, -157, +31,
|
||||
+11612, +10554, -3129, -2035, +925, +2135, +343, -1322, -1834, -253, +981, -508, +127, -339, +524, +263, -428, +146, +113, -216, -691, -403, -615, +161, -3, -171, -98, -195, -334, -500, -145, +70,
|
||||
+12375, +10683, -3543, -1496, +1375, +1878, -63, -1524, -1717, +100, +1163, -755, -161, -335, +443, +21, -544, +0, +88, -275, -693, -316, -565, +159, -85, -8, -150, -333, -390, -555, -137, +51,
|
||||
+13451, +11029, -4018, -1046, +1272, +1286, -363, -1499, -1496, +592, +1316, -1108, -273, -352, +296, -275, -635, -344, -118, -175, -740, -127, -424, +105, -164, +113, -179, -568, -399, -627, -271, +78,
|
||||
+14734, +11620, -4801, -879, +695, +632, -389, -1350, -1318, +1007, +1424, -1500, -74, -505, -4, -282, -945, -711, -166, -124, -792, +39, -391, +77, -83, +118, -326, -662, -381, -867, -393, +164,
|
||||
+15985, +11630, -5516, -532, +203, +208, -354, -1214, -1189, +1341, +1442, -1615, +268, -744, -62, -254, -1183, -868, -259, -11, -770, +72, -261, +154, +24, +109, -377, -617, -514, -967, -389, +157,
|
||||
+16167, +11377, -5735, -169, +103, +84, -542, -1299, -1254, +1362, +1544, -1556, +422, -670, -103, -248, -1015, -1157, -377, +88, -926, +197, -106, +201, +13, +190, -354, -777, -517, -923, -458, +58,
|
||||
+15468, +10670, -5248, +0, +346, +442, -693, -1493, -1502, +1200, +1468, -1209, +625, -745, +218, -158, -964, -895, -623, +11, -688, +93, -44, +335, -4, +183, -327, -757, -508, -710, -494, -108,
|
||||
+11864, +10338, -3078, -621, +1333, +599, -268, -1143, -1003, +1077, +1244, -764, -17, -195, +147, -60, -510, -758, -332, -70, -719, -16, -15, +316, +287, +250, -355, -886, -747, -549, -54, +215,
|
||||
};
|
||||
|
||||
/* HRIR Delays */
|
||||
static const ALubyte defaultDelays[828] =
|
||||
{
|
||||
12, 12, 13, 14, 14, 14, 13, 12, 11, 10, 10, 10, 11, 12, 13, 14, 15, 15, 16, 16, 16, 15, 15, 14, 13, 12, 11, 10, 9, 8, 8, 8, 8, 8, 9, 10, 11, 12, 13, 14, 15, 16, 16, 17, 18, 18, 18, 18, 18, 17, 16, 16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 7, 6, 6, 6, 6, 6, 7, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 18, 19, 20, 20, 20, 20, 20, 19, 19, 18, 17, 16, 15, 14, 13, 12, 11, 10, 9, 8, 8, 7, 6, 5, 5, 5, 4, 4, 4, 5, 5, 6, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 19, 20, 21, 21, 22, 22, 22, 22, 22, 21, 21, 20, 19, 19, 18, 17, 16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 6, 5, 4, 4, 3, 3, 3, 3, 3, 3, 3, 4, 4, 5, 6, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 22, 23, 24, 24, 24, 24, 24, 23, 22, 22, 21, 20, 19, 18, 17, 16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 4, 3, 3, 2, 2, 2, 2, 2, 2, 2, 3, 3, 4, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 19, 20, 21, 22, 23, 24, 24, 25, 26, 26, 26, 26, 26, 25, 24, 24, 23, 22, 21, 20, 19, 19, 18, 17, 16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 6, 5, 4, 3, 3, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 3, 3, 4, 5, 6, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 26, 27, 28, 28, 28, 27, 26, 26, 25, 24, 23, 22, 21, 20, 19, 18, 17, 16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 4, 3, 2, 2, 1, 1, 1, 0, 0, 0, 0, 0, 1, 1, 1, 2, 2, 3, 4, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 29, 28, 27, 26, 25, 24, 23, 22, 21, 20, 19, 18, 17, 16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 4, 3, 2, 2, 1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1, 2, 2, 3, 4, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 26, 27, 28, 28, 28, 27, 26, 26, 25, 24, 23, 22, 21, 20, 19, 18, 17, 16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 4, 3, 2, 2, 1, 1, 1, 0, 0, 0, 0, 0, 1, 1, 1, 2, 2, 3, 4, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 19, 20, 21, 22, 23, 24, 24, 25, 26, 26, 26, 26, 26, 25, 24, 24, 23, 22, 21, 20, 19, 19, 18, 17, 16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 6, 5, 4, 3, 3, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 3, 3, 4, 5, 6, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 22, 23, 24, 24, 24, 24, 24, 23, 22, 22, 21, 20, 19, 18, 17, 16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 4, 3, 3, 2, 2, 2, 2, 2, 2, 2, 3, 3, 4, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 19, 20, 21, 21, 22, 22, 22, 22, 22, 21, 21, 20, 19, 19, 18, 17, 16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 6, 5, 4, 4, 3, 3, 3, 3, 3, 3, 3, 4, 4, 5, 6, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 18, 19, 20, 20, 20, 20, 20, 19, 19, 18, 17, 16, 15, 14, 13, 12, 11, 10, 9, 8, 8, 7, 6, 5, 5, 5, 4, 4, 4, 5, 5, 6, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 16, 17, 18, 18, 18, 18, 18, 17, 16, 16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 7, 6, 6, 6, 6, 6, 7, 7, 8, 9, 10, 11, 12, 13, 14, 15, 15, 16, 16, 16, 15, 15, 14, 13, 12, 11, 10, 9, 8, 8, 8, 8, 8, 9, 10, 11, 12, 13, 14, 14, 14, 13, 12, 11, 10, 10, 10, 11, 12,
|
||||
};
|
||||
|
||||
/* Default HRTF Definition */
|
||||
static const struct Hrtf DefaultHrtf = {
|
||||
44100, 32, 19, defaultAzCount, defaultEvOffset,
|
||||
defaultCoeffs, defaultDelays, NULL
|
||||
};
|
||||
+421
@@ -0,0 +1,421 @@
|
||||
/**
|
||||
* OpenAL cross platform audio library
|
||||
* Copyright (C) 1999-2007 by authors.
|
||||
* 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., 59 Temple Place - Suite 330,
|
||||
* Boston, MA 02111-1307, USA.
|
||||
* Or go to http://www.gnu.org/copyleft/lgpl.html
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <math.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <ctype.h>
|
||||
#include <assert.h>
|
||||
|
||||
#include "alMain.h"
|
||||
#include "AL/al.h"
|
||||
#include "AL/alc.h"
|
||||
#include "alSource.h"
|
||||
#include "alBuffer.h"
|
||||
#include "alListener.h"
|
||||
#include "alAuxEffectSlot.h"
|
||||
#include "alu.h"
|
||||
#include "bs2b.h"
|
||||
|
||||
|
||||
static __inline ALfloat Sample_ALbyte(ALbyte val)
|
||||
{ return val * (1.0f/127.0f); }
|
||||
|
||||
static __inline ALfloat Sample_ALshort(ALshort val)
|
||||
{ return val * (1.0f/32767.0f); }
|
||||
|
||||
static __inline ALfloat Sample_ALfloat(ALfloat val)
|
||||
{ return val; }
|
||||
|
||||
#define DECL_TEMPLATE(T) \
|
||||
static void Load_##T(ALfloat *dst, const T *src, ALuint srcstep, ALuint samples)\
|
||||
{ \
|
||||
ALuint i; \
|
||||
for(i = 0;i < samples;i++) \
|
||||
dst[i] = Sample_##T(src[i*srcstep]); \
|
||||
}
|
||||
|
||||
DECL_TEMPLATE(ALbyte)
|
||||
DECL_TEMPLATE(ALshort)
|
||||
DECL_TEMPLATE(ALfloat)
|
||||
|
||||
#undef DECL_TEMPLATE
|
||||
|
||||
static void LoadData(ALfloat *dst, const ALvoid *src, ALuint srcstep, enum FmtType srctype, ALuint samples)
|
||||
{
|
||||
switch(srctype)
|
||||
{
|
||||
case FmtByte:
|
||||
Load_ALbyte(dst, src, srcstep, samples);
|
||||
break;
|
||||
case FmtShort:
|
||||
Load_ALshort(dst, src, srcstep, samples);
|
||||
break;
|
||||
case FmtFloat:
|
||||
Load_ALfloat(dst, src, srcstep, samples);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void SilenceData(ALfloat *dst, ALuint samples)
|
||||
{
|
||||
ALuint i;
|
||||
for(i = 0;i < samples;i++)
|
||||
dst[i] = 0.0f;
|
||||
}
|
||||
|
||||
|
||||
static void Filter2P(FILTER *filter, ALuint chan, ALfloat *RESTRICT dst,
|
||||
const ALfloat *RESTRICT src, ALuint numsamples)
|
||||
{
|
||||
ALuint i;
|
||||
for(i = 0;i < numsamples;i++)
|
||||
dst[i] = lpFilter2P(filter, chan, src[i]);
|
||||
dst[i] = lpFilter2PC(filter, chan, src[i]);
|
||||
}
|
||||
|
||||
|
||||
ALvoid MixSource(ALsource *Source, ALCdevice *Device, ALuint SamplesToDo)
|
||||
{
|
||||
ALbufferlistitem *BufferListItem;
|
||||
ALuint DataPosInt, DataPosFrac;
|
||||
ALuint BuffersPlayed;
|
||||
ALboolean Looping;
|
||||
ALuint increment;
|
||||
enum Resampler Resampler;
|
||||
ALenum State;
|
||||
ALuint OutPos;
|
||||
ALuint NumChannels;
|
||||
ALuint SampleSize;
|
||||
ALint64 DataSize64;
|
||||
ALuint chan, j;
|
||||
|
||||
/* Get source info */
|
||||
State = Source->state;
|
||||
BuffersPlayed = Source->BuffersPlayed;
|
||||
DataPosInt = Source->position;
|
||||
DataPosFrac = Source->position_fraction;
|
||||
Looping = Source->Looping;
|
||||
increment = Source->Params.Step;
|
||||
Resampler = (increment==FRACTIONONE) ? PointResampler : Source->Resampler;
|
||||
NumChannels = Source->NumChannels;
|
||||
SampleSize = Source->SampleSize;
|
||||
|
||||
/* Get current buffer queue item */
|
||||
BufferListItem = Source->queue;
|
||||
for(j = 0;j < BuffersPlayed;j++)
|
||||
BufferListItem = BufferListItem->next;
|
||||
|
||||
OutPos = 0;
|
||||
do {
|
||||
const ALuint BufferPrePadding = ResamplerPrePadding[Resampler];
|
||||
const ALuint BufferPadding = ResamplerPadding[Resampler];
|
||||
ALuint SrcBufferSize, DstBufferSize;
|
||||
|
||||
/* Figure out how many buffer bytes will be needed */
|
||||
DataSize64 = SamplesToDo-OutPos+1;
|
||||
DataSize64 *= increment;
|
||||
DataSize64 += DataPosFrac+FRACTIONMASK;
|
||||
DataSize64 >>= FRACTIONBITS;
|
||||
DataSize64 += BufferPadding+BufferPrePadding;
|
||||
|
||||
SrcBufferSize = (ALuint)mini64(DataSize64, BUFFERSIZE);
|
||||
|
||||
/* Figure out how many samples we can actually mix from this. */
|
||||
DataSize64 = SrcBufferSize;
|
||||
DataSize64 -= BufferPadding+BufferPrePadding;
|
||||
DataSize64 <<= FRACTIONBITS;
|
||||
DataSize64 -= increment;
|
||||
DataSize64 -= DataPosFrac;
|
||||
|
||||
DstBufferSize = (ALuint)((DataSize64+(increment-1)) / increment);
|
||||
DstBufferSize = minu(DstBufferSize, (SamplesToDo-OutPos));
|
||||
|
||||
/* Some mixers like having a multiple of 4, so try to give that unless
|
||||
* this is the last update. */
|
||||
if(OutPos+DstBufferSize < SamplesToDo)
|
||||
DstBufferSize &= ~3;
|
||||
|
||||
for(chan = 0;chan < NumChannels;chan++)
|
||||
{
|
||||
ALfloat *SrcData = Device->SampleData1;
|
||||
ALfloat *ResampledData = Device->SampleData2;
|
||||
ALuint SrcDataSize = 0;
|
||||
|
||||
if(Source->SourceType == AL_STATIC)
|
||||
{
|
||||
const ALbuffer *ALBuffer = Source->queue->buffer;
|
||||
const ALubyte *Data = ALBuffer->data;
|
||||
ALuint DataSize;
|
||||
ALuint pos;
|
||||
|
||||
/* If current pos is beyond the loop range, do not loop */
|
||||
if(Looping == AL_FALSE || DataPosInt >= (ALuint)ALBuffer->LoopEnd)
|
||||
{
|
||||
Looping = AL_FALSE;
|
||||
|
||||
if(DataPosInt >= BufferPrePadding)
|
||||
pos = DataPosInt - BufferPrePadding;
|
||||
else
|
||||
{
|
||||
DataSize = BufferPrePadding - DataPosInt;
|
||||
DataSize = minu(SrcBufferSize - SrcDataSize, DataSize);
|
||||
|
||||
SilenceData(&SrcData[SrcDataSize], DataSize);
|
||||
SrcDataSize += DataSize;
|
||||
|
||||
pos = 0;
|
||||
}
|
||||
|
||||
/* Copy what's left to play in the source buffer, and clear the
|
||||
* rest of the temp buffer */
|
||||
DataSize = minu(SrcBufferSize - SrcDataSize, ALBuffer->SampleLen - pos);
|
||||
|
||||
LoadData(&SrcData[SrcDataSize], &Data[(pos*NumChannels + chan)*SampleSize],
|
||||
NumChannels, ALBuffer->FmtType, DataSize);
|
||||
SrcDataSize += DataSize;
|
||||
|
||||
SilenceData(&SrcData[SrcDataSize], SrcBufferSize - SrcDataSize);
|
||||
SrcDataSize += SrcBufferSize - SrcDataSize;
|
||||
}
|
||||
else
|
||||
{
|
||||
ALuint LoopStart = ALBuffer->LoopStart;
|
||||
ALuint LoopEnd = ALBuffer->LoopEnd;
|
||||
|
||||
if(DataPosInt >= LoopStart)
|
||||
{
|
||||
pos = DataPosInt-LoopStart;
|
||||
while(pos < BufferPrePadding)
|
||||
pos += LoopEnd-LoopStart;
|
||||
pos -= BufferPrePadding;
|
||||
pos += LoopStart;
|
||||
}
|
||||
else if(DataPosInt >= BufferPrePadding)
|
||||
pos = DataPosInt - BufferPrePadding;
|
||||
else
|
||||
{
|
||||
DataSize = BufferPrePadding - DataPosInt;
|
||||
DataSize = minu(SrcBufferSize - SrcDataSize, DataSize);
|
||||
|
||||
SilenceData(&SrcData[SrcDataSize], DataSize);
|
||||
SrcDataSize += DataSize;
|
||||
|
||||
pos = 0;
|
||||
}
|
||||
|
||||
/* Copy what's left of this loop iteration, then copy repeats
|
||||
* of the loop section */
|
||||
DataSize = LoopEnd - pos;
|
||||
DataSize = minu(SrcBufferSize - SrcDataSize, DataSize);
|
||||
|
||||
LoadData(&SrcData[SrcDataSize], &Data[(pos*NumChannels + chan)*SampleSize],
|
||||
NumChannels, ALBuffer->FmtType, DataSize);
|
||||
SrcDataSize += DataSize;
|
||||
|
||||
DataSize = LoopEnd-LoopStart;
|
||||
while(SrcBufferSize > SrcDataSize)
|
||||
{
|
||||
DataSize = minu(SrcBufferSize - SrcDataSize, DataSize);
|
||||
|
||||
LoadData(&SrcData[SrcDataSize], &Data[(LoopStart*NumChannels + chan)*SampleSize],
|
||||
NumChannels, ALBuffer->FmtType, DataSize);
|
||||
SrcDataSize += DataSize;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Crawl the buffer queue to fill in the temp buffer */
|
||||
ALbufferlistitem *tmpiter = BufferListItem;
|
||||
ALuint pos;
|
||||
|
||||
if(DataPosInt >= BufferPrePadding)
|
||||
pos = DataPosInt - BufferPrePadding;
|
||||
else
|
||||
{
|
||||
pos = BufferPrePadding - DataPosInt;
|
||||
while(pos > 0)
|
||||
{
|
||||
if(!tmpiter->prev && !Looping)
|
||||
{
|
||||
ALuint DataSize = minu(SrcBufferSize - SrcDataSize, pos);
|
||||
|
||||
SilenceData(&SrcData[SrcDataSize], DataSize);
|
||||
SrcDataSize += DataSize;
|
||||
|
||||
pos = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
if(tmpiter->prev)
|
||||
tmpiter = tmpiter->prev;
|
||||
else
|
||||
{
|
||||
while(tmpiter->next)
|
||||
tmpiter = tmpiter->next;
|
||||
}
|
||||
|
||||
if(tmpiter->buffer)
|
||||
{
|
||||
if((ALuint)tmpiter->buffer->SampleLen > pos)
|
||||
{
|
||||
pos = tmpiter->buffer->SampleLen - pos;
|
||||
break;
|
||||
}
|
||||
pos -= tmpiter->buffer->SampleLen;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
while(tmpiter && SrcBufferSize > SrcDataSize)
|
||||
{
|
||||
const ALbuffer *ALBuffer;
|
||||
if((ALBuffer=tmpiter->buffer) != NULL)
|
||||
{
|
||||
const ALubyte *Data = ALBuffer->data;
|
||||
ALuint DataSize = ALBuffer->SampleLen;
|
||||
|
||||
/* Skip the data already played */
|
||||
if(DataSize <= pos)
|
||||
pos -= DataSize;
|
||||
else
|
||||
{
|
||||
Data += (pos*NumChannels + chan)*SampleSize;
|
||||
DataSize -= pos;
|
||||
pos -= pos;
|
||||
|
||||
DataSize = minu(SrcBufferSize - SrcDataSize, DataSize);
|
||||
LoadData(&SrcData[SrcDataSize], Data, NumChannels,
|
||||
ALBuffer->FmtType, DataSize);
|
||||
SrcDataSize += DataSize;
|
||||
}
|
||||
}
|
||||
tmpiter = tmpiter->next;
|
||||
if(!tmpiter && Looping)
|
||||
tmpiter = Source->queue;
|
||||
else if(!tmpiter)
|
||||
{
|
||||
SilenceData(&SrcData[SrcDataSize], SrcBufferSize - SrcDataSize);
|
||||
SrcDataSize += SrcBufferSize - SrcDataSize;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Now resample, then filter and mix to the appropriate outputs. */
|
||||
Source->Params.Resample(&SrcData[BufferPrePadding], DataPosFrac,
|
||||
increment, ResampledData, DstBufferSize);
|
||||
|
||||
{
|
||||
DirectParams *directparms = &Source->Params.Direct;
|
||||
|
||||
Filter2P(&directparms->iirFilter, chan, SrcData, ResampledData,
|
||||
DstBufferSize);
|
||||
Source->Params.DryMix(directparms, SrcData, chan, OutPos,
|
||||
SamplesToDo, DstBufferSize);
|
||||
}
|
||||
|
||||
for(j = 0;j < Device->NumAuxSends;j++)
|
||||
{
|
||||
SendParams *sendparms = &Source->Params.Send[j];
|
||||
if(!sendparms->Slot)
|
||||
continue;
|
||||
|
||||
Filter2P(&sendparms->iirFilter, chan, SrcData, ResampledData,
|
||||
DstBufferSize);
|
||||
Source->Params.WetMix(sendparms, SrcData, OutPos,
|
||||
SamplesToDo, DstBufferSize);
|
||||
}
|
||||
}
|
||||
/* Update positions */
|
||||
for(j = 0;j < DstBufferSize;j++)
|
||||
{
|
||||
DataPosFrac += increment;
|
||||
DataPosInt += DataPosFrac>>FRACTIONBITS;
|
||||
DataPosFrac &= FRACTIONMASK;
|
||||
}
|
||||
OutPos += DstBufferSize;
|
||||
|
||||
/* Handle looping sources */
|
||||
while(1)
|
||||
{
|
||||
const ALbuffer *ALBuffer;
|
||||
ALuint DataSize = 0;
|
||||
ALuint LoopStart = 0;
|
||||
ALuint LoopEnd = 0;
|
||||
|
||||
if((ALBuffer=BufferListItem->buffer) != NULL)
|
||||
{
|
||||
DataSize = ALBuffer->SampleLen;
|
||||
LoopStart = ALBuffer->LoopStart;
|
||||
LoopEnd = ALBuffer->LoopEnd;
|
||||
if(LoopEnd > DataPosInt)
|
||||
break;
|
||||
}
|
||||
|
||||
if(Looping && Source->SourceType == AL_STATIC)
|
||||
{
|
||||
DataPosInt = ((DataPosInt-LoopStart)%(LoopEnd-LoopStart)) + LoopStart;
|
||||
break;
|
||||
}
|
||||
|
||||
if(DataSize > DataPosInt)
|
||||
break;
|
||||
|
||||
if(BufferListItem->next)
|
||||
{
|
||||
BufferListItem = BufferListItem->next;
|
||||
BuffersPlayed++;
|
||||
}
|
||||
else if(Looping)
|
||||
{
|
||||
BufferListItem = Source->queue;
|
||||
BuffersPlayed = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
State = AL_STOPPED;
|
||||
BufferListItem = Source->queue;
|
||||
BuffersPlayed = Source->BuffersInQueue;
|
||||
DataPosInt = 0;
|
||||
DataPosFrac = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
DataPosInt -= DataSize;
|
||||
}
|
||||
} while(State == AL_PLAYING && OutPos < SamplesToDo);
|
||||
|
||||
/* Update source info */
|
||||
Source->state = State;
|
||||
Source->BuffersPlayed = BuffersPlayed;
|
||||
Source->position = DataPosInt;
|
||||
Source->position_fraction = DataPosFrac;
|
||||
Source->Hrtf.Offset += OutPos;
|
||||
if(State == AL_PLAYING)
|
||||
Source->Hrtf.Counter = maxu(Source->Hrtf.Counter, OutPos) - OutPos;
|
||||
else
|
||||
{
|
||||
Source->Hrtf.Counter = 0;
|
||||
Source->Hrtf.Moving = AL_FALSE;
|
||||
}
|
||||
}
|
||||
+131
@@ -0,0 +1,131 @@
|
||||
#include "config.h"
|
||||
|
||||
#include <assert.h>
|
||||
|
||||
#include "alMain.h"
|
||||
#include "alu.h"
|
||||
#include "alSource.h"
|
||||
#include "alAuxEffectSlot.h"
|
||||
|
||||
|
||||
static __inline ALfloat point32(const ALfloat *vals, ALuint frac)
|
||||
{ return vals[0]; (void)frac; }
|
||||
static __inline ALfloat lerp32(const ALfloat *vals, ALuint frac)
|
||||
{ return lerp(vals[0], vals[1], frac * (1.0f/FRACTIONONE)); }
|
||||
static __inline ALfloat cubic32(const ALfloat *vals, ALuint frac)
|
||||
{ return cubic(vals[-1], vals[0], vals[1], vals[2], frac * (1.0f/FRACTIONONE)); }
|
||||
|
||||
void Resample_copy32_C(const ALfloat *data, ALuint frac,
|
||||
ALuint increment, ALfloat *RESTRICT OutBuffer, ALuint BufferSize)
|
||||
{
|
||||
(void)frac;
|
||||
assert(increment==FRACTIONONE);
|
||||
memcpy(OutBuffer, data, (BufferSize+1)*sizeof(ALfloat));
|
||||
}
|
||||
|
||||
#define DECL_TEMPLATE(Sampler) \
|
||||
void Resample_##Sampler##_C(const ALfloat *data, ALuint frac, \
|
||||
ALuint increment, ALfloat *RESTRICT OutBuffer, ALuint BufferSize) \
|
||||
{ \
|
||||
ALuint pos = 0; \
|
||||
ALuint i; \
|
||||
\
|
||||
for(i = 0;i < BufferSize+1;i++) \
|
||||
{ \
|
||||
OutBuffer[i] = Sampler(data + pos, frac); \
|
||||
\
|
||||
frac += increment; \
|
||||
pos += frac>>FRACTIONBITS; \
|
||||
frac &= FRACTIONMASK; \
|
||||
} \
|
||||
}
|
||||
|
||||
DECL_TEMPLATE(point32)
|
||||
DECL_TEMPLATE(lerp32)
|
||||
DECL_TEMPLATE(cubic32)
|
||||
|
||||
#undef DECL_TEMPLATE
|
||||
|
||||
|
||||
static __inline void ApplyCoeffsStep(ALuint Offset, ALfloat (*RESTRICT Values)[2],
|
||||
const ALuint IrSize,
|
||||
ALfloat (*RESTRICT Coeffs)[2],
|
||||
const ALfloat (*RESTRICT CoeffStep)[2],
|
||||
ALfloat left, ALfloat right)
|
||||
{
|
||||
ALuint c;
|
||||
for(c = 0;c < IrSize;c++)
|
||||
{
|
||||
const ALuint off = (Offset+c)&HRIR_MASK;
|
||||
Values[off][0] += Coeffs[c][0] * left;
|
||||
Values[off][1] += Coeffs[c][1] * right;
|
||||
Coeffs[c][0] += CoeffStep[c][0];
|
||||
Coeffs[c][1] += CoeffStep[c][1];
|
||||
}
|
||||
}
|
||||
|
||||
static __inline void ApplyCoeffs(ALuint Offset, ALfloat (*RESTRICT Values)[2],
|
||||
const ALuint IrSize,
|
||||
ALfloat (*RESTRICT Coeffs)[2],
|
||||
ALfloat left, ALfloat right)
|
||||
{
|
||||
ALuint c;
|
||||
for(c = 0;c < IrSize;c++)
|
||||
{
|
||||
const ALuint off = (Offset+c)&HRIR_MASK;
|
||||
Values[off][0] += Coeffs[c][0] * left;
|
||||
Values[off][1] += Coeffs[c][1] * right;
|
||||
}
|
||||
}
|
||||
|
||||
#define SUFFIX C
|
||||
#include "mixer_inc.c"
|
||||
#undef SUFFIX
|
||||
|
||||
|
||||
void MixDirect_C(const DirectParams *params, const ALfloat *RESTRICT data, ALuint srcchan,
|
||||
ALuint OutPos, ALuint SamplesToDo, ALuint BufferSize)
|
||||
{
|
||||
ALfloat (*RESTRICT DryBuffer)[BUFFERSIZE] = params->OutBuffer;
|
||||
ALfloat *RESTRICT ClickRemoval = params->ClickRemoval;
|
||||
ALfloat *RESTRICT PendingClicks = params->PendingClicks;
|
||||
ALfloat DrySend;
|
||||
ALuint pos;
|
||||
ALuint c;
|
||||
|
||||
for(c = 0;c < MaxChannels;c++)
|
||||
{
|
||||
DrySend = params->Gains[srcchan][c];
|
||||
if(DrySend < 0.00001f)
|
||||
continue;
|
||||
|
||||
if(OutPos == 0)
|
||||
ClickRemoval[c] -= data[0]*DrySend;
|
||||
for(pos = 0;pos < BufferSize;pos++)
|
||||
DryBuffer[c][OutPos+pos] += data[pos]*DrySend;
|
||||
if(OutPos+pos == SamplesToDo)
|
||||
PendingClicks[c] += data[pos]*DrySend;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void MixSend_C(const SendParams *params, const ALfloat *RESTRICT data,
|
||||
ALuint OutPos, ALuint SamplesToDo, ALuint BufferSize)
|
||||
{
|
||||
ALeffectslot *Slot = params->Slot;
|
||||
ALfloat (*RESTRICT WetBuffer)[BUFFERSIZE] = Slot->WetBuffer;
|
||||
ALfloat *RESTRICT WetClickRemoval = Slot->ClickRemoval;
|
||||
ALfloat *RESTRICT WetPendingClicks = Slot->PendingClicks;
|
||||
ALfloat WetSend = params->Gain;
|
||||
ALuint pos;
|
||||
|
||||
if(WetSend < 0.00001f)
|
||||
return;
|
||||
|
||||
if(OutPos == 0)
|
||||
WetClickRemoval[0] -= data[0] * WetSend;
|
||||
for(pos = 0;pos < BufferSize;pos++)
|
||||
WetBuffer[0][OutPos+pos] += data[pos] * WetSend;
|
||||
if(OutPos+pos == SamplesToDo)
|
||||
WetPendingClicks[0] += data[pos] * WetSend;
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
#ifndef MIXER_DEFS_H
|
||||
#define MIXER_DEFS_H
|
||||
|
||||
#include "AL/alc.h"
|
||||
#include "AL/al.h"
|
||||
#include "alMain.h"
|
||||
|
||||
struct DirectParams;
|
||||
struct SendParams;
|
||||
|
||||
/* C resamplers */
|
||||
void Resample_copy32_C(const ALfloat *src, ALuint frac, ALuint increment, ALfloat *RESTRICT dst, ALuint dstlen);
|
||||
void Resample_point32_C(const ALfloat *src, ALuint frac, ALuint increment, ALfloat *RESTRICT dst, ALuint dstlen);
|
||||
void Resample_lerp32_C(const ALfloat *src, ALuint frac, ALuint increment, ALfloat *RESTRICT dst, ALuint dstlen);
|
||||
void Resample_cubic32_C(const ALfloat *src, ALuint frac, ALuint increment, ALfloat *RESTRICT dst, ALuint dstlen);
|
||||
|
||||
|
||||
/* C mixers */
|
||||
void MixDirect_Hrtf_C(const struct DirectParams*,const ALfloat*RESTRICT,ALuint,ALuint,ALuint,ALuint);
|
||||
void MixDirect_C(const struct DirectParams*,const ALfloat*RESTRICT,ALuint,ALuint,ALuint,ALuint);
|
||||
void MixSend_C(const struct SendParams*,const ALfloat*RESTRICT,ALuint,ALuint,ALuint);
|
||||
|
||||
/* SSE mixers */
|
||||
void MixDirect_Hrtf_SSE(const struct DirectParams*,const ALfloat*RESTRICT,ALuint,ALuint,ALuint,ALuint);
|
||||
void MixDirect_SSE(const struct DirectParams*,const ALfloat*RESTRICT,ALuint,ALuint,ALuint,ALuint);
|
||||
void MixSend_SSE(const struct SendParams*,const ALfloat*RESTRICT,ALuint,ALuint,ALuint);
|
||||
|
||||
/* Neon mixers */
|
||||
void MixDirect_Hrtf_Neon(const struct DirectParams*,const ALfloat*RESTRICT,ALuint,ALuint,ALuint,ALuint);
|
||||
|
||||
#endif /* MIXER_DEFS_H */
|
||||
+141
@@ -0,0 +1,141 @@
|
||||
#include "config.h"
|
||||
|
||||
#include "alMain.h"
|
||||
#include "alSource.h"
|
||||
#include "mixer_defs.h"
|
||||
|
||||
#ifdef __GNUC__
|
||||
#define LIKELY(x) __builtin_expect(!!(x), 1)
|
||||
#define UNLIKELY(x) __builtin_expect(!!(x), 0)
|
||||
#else
|
||||
#define LIKELY(x) (x)
|
||||
#define UNLIKELY(x) (x)
|
||||
#endif
|
||||
|
||||
#define REAL_MERGE2(a,b) a##b
|
||||
#define MERGE2(a,b) REAL_MERGE2(a,b)
|
||||
|
||||
#define MixDirect_Hrtf MERGE2(MixDirect_Hrtf_,SUFFIX)
|
||||
|
||||
|
||||
static __inline void ApplyCoeffsStep(ALuint Offset, ALfloat (*RESTRICT Values)[2],
|
||||
const ALuint irSize,
|
||||
ALfloat (*RESTRICT Coeffs)[2],
|
||||
const ALfloat (*RESTRICT CoeffStep)[2],
|
||||
ALfloat left, ALfloat right);
|
||||
static __inline void ApplyCoeffs(ALuint Offset, ALfloat (*RESTRICT Values)[2],
|
||||
const ALuint irSize,
|
||||
ALfloat (*RESTRICT Coeffs)[2],
|
||||
ALfloat left, ALfloat right);
|
||||
|
||||
|
||||
void MixDirect_Hrtf(const DirectParams *params, const ALfloat *RESTRICT data, ALuint srcchan,
|
||||
ALuint OutPos, ALuint SamplesToDo, ALuint BufferSize)
|
||||
{
|
||||
ALfloat (*RESTRICT DryBuffer)[BUFFERSIZE] = params->OutBuffer;
|
||||
ALfloat *RESTRICT ClickRemoval = params->ClickRemoval;
|
||||
ALfloat *RESTRICT PendingClicks = params->PendingClicks;
|
||||
const ALuint IrSize = params->Hrtf.Params.IrSize;
|
||||
const ALint *RESTRICT DelayStep = params->Hrtf.Params.DelayStep;
|
||||
const ALfloat (*RESTRICT CoeffStep)[2] = params->Hrtf.Params.CoeffStep;
|
||||
const ALfloat (*RESTRICT TargetCoeffs)[2] = params->Hrtf.Params.Coeffs[srcchan];
|
||||
const ALuint *RESTRICT TargetDelay = params->Hrtf.Params.Delay[srcchan];
|
||||
ALfloat *RESTRICT History = params->Hrtf.State->History[srcchan];
|
||||
ALfloat (*RESTRICT Values)[2] = params->Hrtf.State->Values[srcchan];
|
||||
ALint Counter = maxu(params->Hrtf.State->Counter, OutPos) - OutPos;
|
||||
ALuint Offset = params->Hrtf.State->Offset + OutPos;
|
||||
ALIGN(16) ALfloat Coeffs[HRIR_LENGTH][2];
|
||||
ALuint Delay[2];
|
||||
ALfloat left, right;
|
||||
ALuint pos;
|
||||
ALuint c;
|
||||
|
||||
pos = 0;
|
||||
for(c = 0;c < IrSize;c++)
|
||||
{
|
||||
Coeffs[c][0] = TargetCoeffs[c][0] - (CoeffStep[c][0]*Counter);
|
||||
Coeffs[c][1] = TargetCoeffs[c][1] - (CoeffStep[c][1]*Counter);
|
||||
}
|
||||
|
||||
Delay[0] = TargetDelay[0] - (DelayStep[0]*Counter);
|
||||
Delay[1] = TargetDelay[1] - (DelayStep[1]*Counter);
|
||||
|
||||
if(LIKELY(OutPos == 0))
|
||||
{
|
||||
History[Offset&SRC_HISTORY_MASK] = data[pos];
|
||||
left = lerp(History[(Offset-(Delay[0]>>HRTFDELAY_BITS))&SRC_HISTORY_MASK],
|
||||
History[(Offset-(Delay[0]>>HRTFDELAY_BITS)-1)&SRC_HISTORY_MASK],
|
||||
(Delay[0]&HRTFDELAY_MASK)*(1.0f/HRTFDELAY_FRACONE));
|
||||
right = lerp(History[(Offset-(Delay[1]>>HRTFDELAY_BITS))&SRC_HISTORY_MASK],
|
||||
History[(Offset-(Delay[1]>>HRTFDELAY_BITS)-1)&SRC_HISTORY_MASK],
|
||||
(Delay[1]&HRTFDELAY_MASK)*(1.0f/HRTFDELAY_FRACONE));
|
||||
|
||||
ClickRemoval[FrontLeft] -= Values[(Offset+1)&HRIR_MASK][0] +
|
||||
Coeffs[0][0] * left;
|
||||
ClickRemoval[FrontRight] -= Values[(Offset+1)&HRIR_MASK][1] +
|
||||
Coeffs[0][1] * right;
|
||||
}
|
||||
for(pos = 0;pos < BufferSize && Counter > 0;pos++)
|
||||
{
|
||||
History[Offset&SRC_HISTORY_MASK] = data[pos];
|
||||
left = lerp(History[(Offset-(Delay[0]>>HRTFDELAY_BITS))&SRC_HISTORY_MASK],
|
||||
History[(Offset-(Delay[0]>>HRTFDELAY_BITS)-1)&SRC_HISTORY_MASK],
|
||||
(Delay[0]&HRTFDELAY_MASK)*(1.0f/HRTFDELAY_FRACONE));
|
||||
right = lerp(History[(Offset-(Delay[1]>>HRTFDELAY_BITS))&SRC_HISTORY_MASK],
|
||||
History[(Offset-(Delay[1]>>HRTFDELAY_BITS)-1)&SRC_HISTORY_MASK],
|
||||
(Delay[1]&HRTFDELAY_MASK)*(1.0f/HRTFDELAY_FRACONE));
|
||||
|
||||
Delay[0] += DelayStep[0];
|
||||
Delay[1] += DelayStep[1];
|
||||
|
||||
Values[(Offset+IrSize)&HRIR_MASK][0] = 0.0f;
|
||||
Values[(Offset+IrSize)&HRIR_MASK][1] = 0.0f;
|
||||
Offset++;
|
||||
|
||||
ApplyCoeffsStep(Offset, Values, IrSize, Coeffs, CoeffStep, left, right);
|
||||
DryBuffer[FrontLeft][OutPos] += Values[Offset&HRIR_MASK][0];
|
||||
DryBuffer[FrontRight][OutPos] += Values[Offset&HRIR_MASK][1];
|
||||
|
||||
OutPos++;
|
||||
Counter--;
|
||||
}
|
||||
|
||||
Delay[0] >>= HRTFDELAY_BITS;
|
||||
Delay[1] >>= HRTFDELAY_BITS;
|
||||
for(;pos < BufferSize;pos++)
|
||||
{
|
||||
History[Offset&SRC_HISTORY_MASK] = data[pos];
|
||||
left = History[(Offset-Delay[0])&SRC_HISTORY_MASK];
|
||||
right = History[(Offset-Delay[1])&SRC_HISTORY_MASK];
|
||||
|
||||
Values[(Offset+IrSize)&HRIR_MASK][0] = 0.0f;
|
||||
Values[(Offset+IrSize)&HRIR_MASK][1] = 0.0f;
|
||||
Offset++;
|
||||
|
||||
ApplyCoeffs(Offset, Values, IrSize, Coeffs, left, right);
|
||||
DryBuffer[FrontLeft][OutPos] += Values[Offset&HRIR_MASK][0];
|
||||
DryBuffer[FrontRight][OutPos] += Values[Offset&HRIR_MASK][1];
|
||||
|
||||
OutPos++;
|
||||
}
|
||||
if(LIKELY(OutPos == SamplesToDo))
|
||||
{
|
||||
History[Offset&SRC_HISTORY_MASK] = data[pos];
|
||||
left = History[(Offset-Delay[0])&SRC_HISTORY_MASK];
|
||||
right = History[(Offset-Delay[1])&SRC_HISTORY_MASK];
|
||||
|
||||
PendingClicks[FrontLeft] += Values[(Offset+1)&HRIR_MASK][0] +
|
||||
Coeffs[0][0] * left;
|
||||
PendingClicks[FrontRight] += Values[(Offset+1)&HRIR_MASK][1] +
|
||||
Coeffs[0][1] * right;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#undef MixDirect_Hrtf
|
||||
|
||||
#undef MERGE2
|
||||
#undef REAL_MERGE2
|
||||
|
||||
#undef UNLIKELY
|
||||
#undef LIKELY
|
||||
@@ -0,0 +1,61 @@
|
||||
#include "config.h"
|
||||
|
||||
#ifdef HAVE_ARM_NEON_H
|
||||
#include <arm_neon.h>
|
||||
#endif
|
||||
|
||||
#include "AL/al.h"
|
||||
#include "AL/alc.h"
|
||||
#include "alMain.h"
|
||||
#include "alu.h"
|
||||
|
||||
|
||||
static __inline void ApplyCoeffsStep(ALuint Offset, ALfloat (*RESTRICT Values)[2],
|
||||
const ALuint IrSize,
|
||||
ALfloat (*RESTRICT Coeffs)[2],
|
||||
const ALfloat (*RESTRICT CoeffStep)[2],
|
||||
ALfloat left, ALfloat right)
|
||||
{
|
||||
ALuint c;
|
||||
for(c = 0;c < IrSize;c++)
|
||||
{
|
||||
const ALuint off = (Offset+c)&HRIR_MASK;
|
||||
Values[off][0] += Coeffs[c][0] * left;
|
||||
Values[off][1] += Coeffs[c][1] * right;
|
||||
Coeffs[c][0] += CoeffStep[c][0];
|
||||
Coeffs[c][1] += CoeffStep[c][1];
|
||||
}
|
||||
}
|
||||
|
||||
static __inline void ApplyCoeffs(ALuint Offset, ALfloat (*RESTRICT Values)[2],
|
||||
const ALuint IrSize,
|
||||
ALfloat (*RESTRICT Coeffs)[2],
|
||||
ALfloat left, ALfloat right)
|
||||
{
|
||||
ALuint c;
|
||||
float32x4_t leftright4;
|
||||
{
|
||||
float32x2_t leftright2 = vdup_n_f32(0.0);
|
||||
leftright2 = vset_lane_f32(left, leftright2, 0);
|
||||
leftright2 = vset_lane_f32(right, leftright2, 1);
|
||||
leftright4 = vcombine_f32(leftright2, leftright2);
|
||||
}
|
||||
for(c = 0;c < IrSize;c += 2)
|
||||
{
|
||||
const ALuint o0 = (Offset+c)&HRIR_MASK;
|
||||
const ALuint o1 = (o0+1)&HRIR_MASK;
|
||||
float32x4_t vals = vcombine_f32(vld1_f32((float32_t*)&Values[o0][0]),
|
||||
vld1_f32((float32_t*)&Values[o1][0]));
|
||||
float32x4_t coefs = vld1q_f32((float32_t*)&Coeffs[c][0]);
|
||||
|
||||
vals = vmlaq_f32(vals, coefs, leftright4);
|
||||
|
||||
vst1_f32((float32_t*)&Values[o0][0], vget_low_f32(vals));
|
||||
vst1_f32((float32_t*)&Values[o1][0], vget_high_f32(vals));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#define SUFFIX Neon
|
||||
#include "mixer_inc.c"
|
||||
#undef SUFFIX
|
||||
+204
@@ -0,0 +1,204 @@
|
||||
#include "config.h"
|
||||
|
||||
#ifdef HAVE_XMMINTRIN_H
|
||||
#include <xmmintrin.h>
|
||||
#endif
|
||||
|
||||
#include "AL/al.h"
|
||||
#include "AL/alc.h"
|
||||
#include "alMain.h"
|
||||
#include "alu.h"
|
||||
|
||||
#include "alSource.h"
|
||||
#include "alAuxEffectSlot.h"
|
||||
#include "mixer_defs.h"
|
||||
|
||||
|
||||
static __inline void ApplyCoeffsStep(ALuint Offset, ALfloat (*RESTRICT Values)[2],
|
||||
const ALuint IrSize,
|
||||
ALfloat (*RESTRICT Coeffs)[2],
|
||||
const ALfloat (*RESTRICT CoeffStep)[2],
|
||||
ALfloat left, ALfloat right)
|
||||
{
|
||||
const __m128 lrlr = { left, right, left, right };
|
||||
__m128 coeffs, deltas, imp0, imp1;
|
||||
__m128 vals = _mm_setzero_ps();
|
||||
ALuint i;
|
||||
|
||||
if((Offset&1))
|
||||
{
|
||||
const ALuint o0 = Offset&HRIR_MASK;
|
||||
const ALuint o1 = (Offset+IrSize-1)&HRIR_MASK;
|
||||
|
||||
coeffs = _mm_load_ps(&Coeffs[0][0]);
|
||||
deltas = _mm_load_ps(&CoeffStep[0][0]);
|
||||
vals = _mm_loadl_pi(vals, (__m64*)&Values[o0][0]);
|
||||
imp0 = _mm_mul_ps(lrlr, coeffs);
|
||||
coeffs = _mm_add_ps(coeffs, deltas);
|
||||
vals = _mm_add_ps(imp0, vals);
|
||||
_mm_store_ps(&Coeffs[0][0], coeffs);
|
||||
_mm_storel_pi((__m64*)&Values[o0][0], vals);
|
||||
for(i = 1;i < IrSize-1;i += 2)
|
||||
{
|
||||
const ALuint o2 = (Offset+i)&HRIR_MASK;
|
||||
|
||||
coeffs = _mm_load_ps(&Coeffs[i+1][0]);
|
||||
deltas = _mm_load_ps(&CoeffStep[i+1][0]);
|
||||
vals = _mm_load_ps(&Values[o2][0]);
|
||||
imp1 = _mm_mul_ps(lrlr, coeffs);
|
||||
coeffs = _mm_add_ps(coeffs, deltas);
|
||||
imp0 = _mm_shuffle_ps(imp0, imp1, _MM_SHUFFLE(1, 0, 3, 2));
|
||||
vals = _mm_add_ps(imp0, vals);
|
||||
_mm_store_ps(&Coeffs[i+1][0], coeffs);
|
||||
_mm_store_ps(&Values[o2][0], vals);
|
||||
imp0 = imp1;
|
||||
}
|
||||
vals = _mm_loadl_pi(vals, (__m64*)&Values[o1][0]);
|
||||
imp0 = _mm_movehl_ps(imp0, imp0);
|
||||
vals = _mm_add_ps(imp0, vals);
|
||||
_mm_storel_pi((__m64*)&Values[o1][0], vals);
|
||||
}
|
||||
else
|
||||
{
|
||||
for(i = 0;i < IrSize;i += 2)
|
||||
{
|
||||
const ALuint o = (Offset + i)&HRIR_MASK;
|
||||
|
||||
coeffs = _mm_load_ps(&Coeffs[i][0]);
|
||||
deltas = _mm_load_ps(&CoeffStep[i][0]);
|
||||
vals = _mm_load_ps(&Values[o][0]);
|
||||
imp0 = _mm_mul_ps(lrlr, coeffs);
|
||||
coeffs = _mm_add_ps(coeffs, deltas);
|
||||
vals = _mm_add_ps(imp0, vals);
|
||||
_mm_store_ps(&Coeffs[i][0], coeffs);
|
||||
_mm_store_ps(&Values[o][0], vals);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static __inline void ApplyCoeffs(ALuint Offset, ALfloat (*RESTRICT Values)[2],
|
||||
const ALuint IrSize,
|
||||
ALfloat (*RESTRICT Coeffs)[2],
|
||||
ALfloat left, ALfloat right)
|
||||
{
|
||||
const __m128 lrlr = { left, right, left, right };
|
||||
__m128 vals = _mm_setzero_ps();
|
||||
__m128 coeffs;
|
||||
ALuint i;
|
||||
|
||||
if((Offset&1))
|
||||
{
|
||||
const ALuint o0 = Offset&HRIR_MASK;
|
||||
const ALuint o1 = (Offset+IrSize-1)&HRIR_MASK;
|
||||
__m128 imp0, imp1;
|
||||
|
||||
coeffs = _mm_load_ps(&Coeffs[0][0]);
|
||||
vals = _mm_loadl_pi(vals, (__m64*)&Values[o0][0]);
|
||||
imp0 = _mm_mul_ps(lrlr, coeffs);
|
||||
vals = _mm_add_ps(imp0, vals);
|
||||
_mm_storel_pi((__m64*)&Values[o0][0], vals);
|
||||
for(i = 1;i < IrSize-1;i += 2)
|
||||
{
|
||||
const ALuint o2 = (Offset+i)&HRIR_MASK;
|
||||
|
||||
coeffs = _mm_load_ps(&Coeffs[i+1][0]);
|
||||
vals = _mm_load_ps(&Values[o2][0]);
|
||||
imp1 = _mm_mul_ps(lrlr, coeffs);
|
||||
imp0 = _mm_shuffle_ps(imp0, imp1, _MM_SHUFFLE(1, 0, 3, 2));
|
||||
vals = _mm_add_ps(imp0, vals);
|
||||
_mm_store_ps(&Values[o2][0], vals);
|
||||
imp0 = imp1;
|
||||
}
|
||||
vals = _mm_loadl_pi(vals, (__m64*)&Values[o1][0]);
|
||||
imp0 = _mm_movehl_ps(imp0, imp0);
|
||||
vals = _mm_add_ps(imp0, vals);
|
||||
_mm_storel_pi((__m64*)&Values[o1][0], vals);
|
||||
}
|
||||
else
|
||||
{
|
||||
for(i = 0;i < IrSize;i += 2)
|
||||
{
|
||||
const ALuint o = (Offset + i)&HRIR_MASK;
|
||||
|
||||
coeffs = _mm_load_ps(&Coeffs[i][0]);
|
||||
vals = _mm_load_ps(&Values[o][0]);
|
||||
vals = _mm_add_ps(vals, _mm_mul_ps(lrlr, coeffs));
|
||||
_mm_store_ps(&Values[o][0], vals);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#define SUFFIX SSE
|
||||
#include "mixer_inc.c"
|
||||
#undef SUFFIX
|
||||
|
||||
|
||||
void MixDirect_SSE(const DirectParams *params, const ALfloat *RESTRICT data, ALuint srcchan,
|
||||
ALuint OutPos, ALuint SamplesToDo, ALuint BufferSize)
|
||||
{
|
||||
ALfloat (*RESTRICT DryBuffer)[BUFFERSIZE] = params->OutBuffer;
|
||||
ALfloat *RESTRICT ClickRemoval = params->ClickRemoval;
|
||||
ALfloat *RESTRICT PendingClicks = params->PendingClicks;
|
||||
ALfloat DrySend;
|
||||
ALuint pos;
|
||||
ALuint c;
|
||||
|
||||
for(c = 0;c < MaxChannels;c++)
|
||||
{
|
||||
__m128 gain;
|
||||
|
||||
DrySend = params->Gains[srcchan][c];
|
||||
if(DrySend < 0.00001f)
|
||||
continue;
|
||||
|
||||
if(OutPos == 0)
|
||||
ClickRemoval[c] -= data[0]*DrySend;
|
||||
|
||||
gain = _mm_set1_ps(DrySend);
|
||||
for(pos = 0;pos < BufferSize-3;pos += 4)
|
||||
{
|
||||
const __m128 val4 = _mm_load_ps(&data[pos]);
|
||||
__m128 dry4 = _mm_load_ps(&DryBuffer[c][OutPos+pos]);
|
||||
dry4 = _mm_add_ps(dry4, _mm_mul_ps(val4, gain));
|
||||
_mm_store_ps(&DryBuffer[c][OutPos+pos], dry4);
|
||||
}
|
||||
for(;pos < BufferSize;pos++)
|
||||
DryBuffer[c][OutPos+pos] += data[pos]*DrySend;
|
||||
|
||||
if(OutPos+pos == SamplesToDo)
|
||||
PendingClicks[c] += data[pos]*DrySend;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void MixSend_SSE(const SendParams *params, const ALfloat *RESTRICT data,
|
||||
ALuint OutPos, ALuint SamplesToDo, ALuint BufferSize)
|
||||
{
|
||||
ALeffectslot *Slot = params->Slot;
|
||||
ALfloat (*RESTRICT WetBuffer)[BUFFERSIZE] = Slot->WetBuffer;
|
||||
ALfloat *RESTRICT WetClickRemoval = Slot->ClickRemoval;
|
||||
ALfloat *RESTRICT WetPendingClicks = Slot->PendingClicks;
|
||||
const ALfloat WetGain = params->Gain;
|
||||
__m128 gain;
|
||||
ALuint pos;
|
||||
|
||||
if(WetGain < 0.00001f)
|
||||
return;
|
||||
|
||||
if(OutPos == 0)
|
||||
WetClickRemoval[0] -= data[0] * WetGain;
|
||||
|
||||
gain = _mm_set1_ps(WetGain);
|
||||
for(pos = 0;pos < BufferSize-3;pos+=4)
|
||||
{
|
||||
const __m128 val4 = _mm_load_ps(&data[pos]);
|
||||
__m128 wet4 = _mm_load_ps(&WetBuffer[0][OutPos+pos]);
|
||||
wet4 = _mm_add_ps(wet4, _mm_mul_ps(val4, gain));
|
||||
_mm_store_ps(&WetBuffer[0][OutPos+pos], wet4);
|
||||
}
|
||||
for(;pos < BufferSize;pos++)
|
||||
WetBuffer[0][OutPos+pos] += data[pos] * WetGain;
|
||||
|
||||
if(OutPos+pos == SamplesToDo)
|
||||
WetPendingClicks[0] += data[pos] * WetGain;
|
||||
}
|
||||
@@ -1,487 +0,0 @@
|
||||
/**
|
||||
* OpenAL cross platform audio library
|
||||
* Copyright (C) 1999-2007 by authors.
|
||||
* 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., 59 Temple Place - Suite 330,
|
||||
* Boston, MA 02111-1307, USA.
|
||||
* Or go to http://www.gnu.org/copyleft/lgpl.html
|
||||
*/
|
||||
|
||||
#include <sys/ioctl.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <fcntl.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <memory.h>
|
||||
#include <unistd.h>
|
||||
#include <errno.h>
|
||||
#include <math.h>
|
||||
#include "alMain.h"
|
||||
#include "AL/al.h"
|
||||
#include "AL/alc.h"
|
||||
|
||||
#include <sys/soundcard.h>
|
||||
|
||||
/*
|
||||
* The OSS documentation talks about SOUND_MIXER_READ, but the header
|
||||
* only contains MIXER_READ. Play safe. Same for WRITE.
|
||||
*/
|
||||
#ifndef SOUND_MIXER_READ
|
||||
#define SOUND_MIXER_READ MIXER_READ
|
||||
#endif
|
||||
#ifndef SOUND_MIXER_WRITE
|
||||
#define SOUND_MIXER_WRITE MIXER_WRITE
|
||||
#endif
|
||||
|
||||
static char *oss_device;
|
||||
static char *oss_device_capture;
|
||||
|
||||
typedef struct {
|
||||
int fd;
|
||||
int killNow;
|
||||
ALvoid *thread;
|
||||
|
||||
ALubyte *mix_data;
|
||||
int data_size;
|
||||
int silence;
|
||||
|
||||
RingBuffer *ring;
|
||||
int doCapture;
|
||||
} oss_data;
|
||||
|
||||
|
||||
static int log2i(ALCuint x)
|
||||
{
|
||||
int y = 0;
|
||||
while (x > 1)
|
||||
{
|
||||
x >>= 1;
|
||||
y++;
|
||||
}
|
||||
return y;
|
||||
}
|
||||
|
||||
|
||||
static ALuint OSSProc(ALvoid *ptr)
|
||||
{
|
||||
ALCdevice *pDevice = (ALCdevice*)ptr;
|
||||
oss_data *data = (oss_data*)pDevice->ExtraData;
|
||||
int remaining = 0;
|
||||
int wrote;
|
||||
|
||||
while(!data->killNow)
|
||||
{
|
||||
int len = data->data_size - remaining;
|
||||
|
||||
if(len > 0)
|
||||
{
|
||||
SuspendContext(NULL);
|
||||
aluMixData(pDevice->Context, data->mix_data+remaining, len, pDevice->Format);
|
||||
ProcessContext(NULL);
|
||||
}
|
||||
|
||||
remaining += len;
|
||||
wrote = write(data->fd, data->mix_data, remaining);
|
||||
if(wrote < 0)
|
||||
{
|
||||
AL_PRINT("write failed: %s\n", strerror(errno));
|
||||
remaining = 0;
|
||||
}
|
||||
else if(wrote > 0)
|
||||
{
|
||||
remaining -= wrote;
|
||||
if(remaining > 0)
|
||||
memmove(data->mix_data, data->mix_data+wrote, remaining);
|
||||
}
|
||||
else
|
||||
usleep(1000);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static ALuint OSSCaptureProc(ALvoid *ptr)
|
||||
{
|
||||
ALCdevice *pDevice = (ALCdevice*)ptr;
|
||||
oss_data *data = (oss_data*)pDevice->ExtraData;
|
||||
int frameSize;
|
||||
int amt;
|
||||
|
||||
frameSize = aluBytesFromFormat(pDevice->Format);
|
||||
frameSize *= aluChannelsFromFormat(pDevice->Format);
|
||||
|
||||
while(!data->killNow)
|
||||
{
|
||||
amt = read(data->fd, data->mix_data, data->data_size);
|
||||
if(amt < 0)
|
||||
{
|
||||
AL_PRINT("read failed: %s\n", strerror(errno));
|
||||
break;
|
||||
}
|
||||
if(amt == 0)
|
||||
{
|
||||
usleep(1000);
|
||||
continue;
|
||||
}
|
||||
if(data->doCapture)
|
||||
WriteRingBuffer(data->ring, data->mix_data, amt/frameSize);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static ALCboolean oss_open_playback(ALCdevice *device, const ALCchar *deviceName)
|
||||
{
|
||||
int numFragmentsLogSize;
|
||||
int log2FragmentSize;
|
||||
unsigned int periods;
|
||||
audio_buf_info info;
|
||||
char driver[64];
|
||||
int numChannels;
|
||||
oss_data *data;
|
||||
int ossFormat;
|
||||
int ossSpeed;
|
||||
char *err;
|
||||
int i;
|
||||
|
||||
strncpy(driver, GetConfigValue("oss", "device", "/dev/dsp"), sizeof(driver)-1);
|
||||
driver[sizeof(driver)-1] = 0;
|
||||
if(deviceName)
|
||||
{
|
||||
if(strcmp(deviceName, oss_device))
|
||||
return ALC_FALSE;
|
||||
device->szDeviceName = oss_device;
|
||||
}
|
||||
else
|
||||
device->szDeviceName = oss_device;
|
||||
|
||||
data = (oss_data*)calloc(1, sizeof(oss_data));
|
||||
data->killNow = 0;
|
||||
|
||||
data->fd = open(driver, O_WRONLY);
|
||||
if(data->fd == -1)
|
||||
{
|
||||
free(data);
|
||||
AL_PRINT("Could not open %s: %s\n", driver, strerror(errno));
|
||||
return ALC_FALSE;
|
||||
}
|
||||
|
||||
switch(aluBytesFromFormat(device->Format))
|
||||
{
|
||||
case 1:
|
||||
data->silence = 0x80;
|
||||
ossFormat = AFMT_U8;
|
||||
break;
|
||||
case 2:
|
||||
data->silence = 0;
|
||||
ossFormat = AFMT_S16_NE;
|
||||
break;
|
||||
default:
|
||||
ossFormat = -1;
|
||||
AL_PRINT("Unknown format?! %x\n", device->Format);
|
||||
}
|
||||
|
||||
periods = GetConfigValueInt("oss", "periods", 4);
|
||||
if((int)periods <= 0)
|
||||
periods = 4;
|
||||
numChannels = device->Channels;
|
||||
ossSpeed = device->Frequency;
|
||||
log2FragmentSize = log2i(device->UpdateFreq * device->FrameSize / periods);
|
||||
|
||||
/* according to the OSS spec, 16 bytes are the minimum */
|
||||
if (log2FragmentSize < 4)
|
||||
log2FragmentSize = 4;
|
||||
numFragmentsLogSize = (periods << 16) | log2FragmentSize;
|
||||
|
||||
#define ok(func, str) (i=(func),((i<0)?(err=(str)),0:1))
|
||||
if (!(ok(ioctl(data->fd, SNDCTL_DSP_SETFRAGMENT, &numFragmentsLogSize), "set fragment") &&
|
||||
ok(ioctl(data->fd, SNDCTL_DSP_SETFMT, &ossFormat), "set format") &&
|
||||
ok(ioctl(data->fd, SNDCTL_DSP_CHANNELS, &numChannels), "set channels") &&
|
||||
ok(ioctl(data->fd, SNDCTL_DSP_SPEED, &ossSpeed), "set speed") &&
|
||||
ok(ioctl(data->fd, SNDCTL_DSP_GETOSPACE, &info), "get space")))
|
||||
{
|
||||
AL_PRINT("%s failed: %s\n", err, strerror(errno));
|
||||
close(data->fd);
|
||||
free(data);
|
||||
return ALC_FALSE;
|
||||
}
|
||||
#undef ok
|
||||
|
||||
device->Frequency = ossSpeed;
|
||||
|
||||
if((int)device->Channels != numChannels)
|
||||
{
|
||||
AL_PRINT("Could not set %d channels, got %d instead\n", device->Channels, numChannels);
|
||||
close(data->fd);
|
||||
free(data);
|
||||
return ALC_FALSE;
|
||||
}
|
||||
|
||||
if(!((ossFormat == AFMT_U8 && aluBytesFromFormat(device->Format) == 1) ||
|
||||
(ossFormat == AFMT_S16_NE && aluBytesFromFormat(device->Format) == 2)))
|
||||
{
|
||||
AL_PRINT("Could not set %d-bit output, got format %#x\n", aluBytesFromFormat(device->Format)*8, ossFormat);
|
||||
close(data->fd);
|
||||
free(data);
|
||||
return ALC_FALSE;
|
||||
}
|
||||
|
||||
device->UpdateFreq = info.fragsize / device->FrameSize;
|
||||
|
||||
data->data_size = device->UpdateFreq * device->FrameSize;
|
||||
data->mix_data = calloc(1, data->data_size);
|
||||
|
||||
device->MaxNoOfSources = 256;
|
||||
|
||||
device->ExtraData = data;
|
||||
data->thread = StartThread(OSSProc, device);
|
||||
if(data->thread == NULL)
|
||||
{
|
||||
device->ExtraData = NULL;
|
||||
free(data->mix_data);
|
||||
free(data);
|
||||
return ALC_FALSE;
|
||||
}
|
||||
|
||||
return ALC_TRUE;
|
||||
}
|
||||
|
||||
static void oss_close_playback(ALCdevice *device)
|
||||
{
|
||||
oss_data *data = (oss_data*)device->ExtraData;
|
||||
data->killNow = 1;
|
||||
StopThread(data->thread);
|
||||
|
||||
close(data->fd);
|
||||
|
||||
free(data->mix_data);
|
||||
free(data);
|
||||
device->ExtraData = NULL;
|
||||
}
|
||||
|
||||
|
||||
static ALCboolean oss_open_capture(ALCdevice *device, const ALCchar *deviceName, ALCuint frequency, ALCenum format, ALCsizei SampleSize)
|
||||
{
|
||||
int numFragmentsLogSize;
|
||||
int log2FragmentSize;
|
||||
unsigned int periods;
|
||||
audio_buf_info info;
|
||||
int numChannels;
|
||||
char driver[64];
|
||||
oss_data *data;
|
||||
int ossFormat;
|
||||
int ossSpeed;
|
||||
char *err;
|
||||
int i;
|
||||
|
||||
strncpy(driver, GetConfigValue("oss", "capture", "/dev/dsp"), sizeof(driver)-1);
|
||||
driver[sizeof(driver)-1] = 0;
|
||||
if(deviceName)
|
||||
{
|
||||
if(strcmp(deviceName, oss_device_capture))
|
||||
return ALC_FALSE;
|
||||
device->szDeviceName = oss_device_capture;
|
||||
}
|
||||
else
|
||||
device->szDeviceName = oss_device_capture;
|
||||
|
||||
data = (oss_data*)calloc(1, sizeof(oss_data));
|
||||
data->killNow = 0;
|
||||
|
||||
data->fd = open(driver, O_RDONLY);
|
||||
if(data->fd == -1)
|
||||
{
|
||||
free(data);
|
||||
AL_PRINT("Could not open %s: %s\n", driver, strerror(errno));
|
||||
return ALC_FALSE;
|
||||
}
|
||||
|
||||
switch(aluBytesFromFormat(format))
|
||||
{
|
||||
case 1:
|
||||
data->silence = 0x80;
|
||||
ossFormat = AFMT_U8;
|
||||
break;
|
||||
case 2:
|
||||
data->silence = 0;
|
||||
ossFormat = AFMT_S16_NE;
|
||||
break;
|
||||
default:
|
||||
ossFormat = -1;
|
||||
AL_PRINT("Unknown format?! %x\n", device->Format);
|
||||
}
|
||||
|
||||
periods = 4;
|
||||
numChannels = device->Channels;
|
||||
ossSpeed = frequency;
|
||||
log2FragmentSize = log2i(device->UpdateFreq * device->FrameSize / periods);
|
||||
|
||||
/* according to the OSS spec, 16 bytes are the minimum */
|
||||
if (log2FragmentSize < 4)
|
||||
log2FragmentSize = 4;
|
||||
numFragmentsLogSize = (periods << 16) | log2FragmentSize;
|
||||
|
||||
#define ok(func, str) (i=(func),((i<0)?(err=(str)),0:1))
|
||||
if (!(ok(ioctl(data->fd, SNDCTL_DSP_SETFRAGMENT, &numFragmentsLogSize), "set fragment") &&
|
||||
ok(ioctl(data->fd, SNDCTL_DSP_SETFMT, &ossFormat), "set format") &&
|
||||
ok(ioctl(data->fd, SNDCTL_DSP_CHANNELS, &numChannels), "set channels") &&
|
||||
ok(ioctl(data->fd, SNDCTL_DSP_SPEED, &ossSpeed), "set speed") &&
|
||||
ok(ioctl(data->fd, SNDCTL_DSP_GETISPACE, &info), "get space")))
|
||||
{
|
||||
AL_PRINT("%s failed: %s\n", err, strerror(errno));
|
||||
close(data->fd);
|
||||
free(data);
|
||||
return ALC_FALSE;
|
||||
}
|
||||
#undef ok
|
||||
|
||||
device->Channels = numChannels;
|
||||
device->Frequency = ossSpeed;
|
||||
device->Format = 0;
|
||||
if(ossFormat == AFMT_U8)
|
||||
{
|
||||
if(device->Channels == 1)
|
||||
{
|
||||
device->Format = AL_FORMAT_MONO8;
|
||||
device->FrameSize = 1;
|
||||
}
|
||||
else if(device->Channels == 2)
|
||||
{
|
||||
device->Format = AL_FORMAT_STEREO8;
|
||||
device->FrameSize = 2;
|
||||
}
|
||||
else if(device->Channels == 4)
|
||||
{
|
||||
device->Format = AL_FORMAT_QUAD8;
|
||||
device->FrameSize = 4;
|
||||
}
|
||||
}
|
||||
else if(ossFormat == AFMT_S16_NE)
|
||||
{
|
||||
if(device->Channels == 1)
|
||||
{
|
||||
device->Format = AL_FORMAT_MONO16;
|
||||
device->FrameSize = 2;
|
||||
}
|
||||
else if(device->Channels == 2)
|
||||
{
|
||||
device->Format = AL_FORMAT_STEREO16;
|
||||
device->FrameSize = 4;
|
||||
}
|
||||
else if(device->Channels == 4)
|
||||
{
|
||||
device->Format = AL_FORMAT_QUAD16;
|
||||
device->FrameSize = 8;
|
||||
}
|
||||
}
|
||||
|
||||
if(!device->Format)
|
||||
{
|
||||
AL_PRINT("returned unknown format: %#x %d!\n", ossFormat, numChannels);
|
||||
close(data->fd);
|
||||
free(data);
|
||||
return ALC_FALSE;
|
||||
}
|
||||
|
||||
data->ring = CreateRingBuffer(device->FrameSize, SampleSize);
|
||||
if(!data->ring)
|
||||
{
|
||||
AL_PRINT("ring buffer create failed\n");
|
||||
close(data->fd);
|
||||
free(data);
|
||||
return ALC_FALSE;
|
||||
}
|
||||
|
||||
device->UpdateFreq = info.fragsize / device->FrameSize;
|
||||
|
||||
data->data_size = device->UpdateFreq * device->FrameSize * info.fragments;
|
||||
data->mix_data = calloc(1, data->data_size);
|
||||
|
||||
device->ExtraData = data;
|
||||
data->thread = StartThread(OSSCaptureProc, device);
|
||||
if(data->thread == NULL)
|
||||
{
|
||||
device->ExtraData = NULL;
|
||||
free(data->mix_data);
|
||||
free(data);
|
||||
return ALC_FALSE;
|
||||
}
|
||||
|
||||
return ALC_TRUE;
|
||||
}
|
||||
|
||||
static void oss_close_capture(ALCdevice *device)
|
||||
{
|
||||
oss_data *data = (oss_data*)device->ExtraData;
|
||||
data->killNow = 1;
|
||||
StopThread(data->thread);
|
||||
|
||||
close(data->fd);
|
||||
|
||||
DestroyRingBuffer(data->ring);
|
||||
|
||||
free(data->mix_data);
|
||||
free(data);
|
||||
device->ExtraData = NULL;
|
||||
}
|
||||
|
||||
static void oss_start_capture(ALCdevice *pDevice)
|
||||
{
|
||||
oss_data *data = (oss_data*)pDevice->ExtraData;
|
||||
data->doCapture = 1;
|
||||
}
|
||||
|
||||
static void oss_stop_capture(ALCdevice *pDevice)
|
||||
{
|
||||
oss_data *data = (oss_data*)pDevice->ExtraData;
|
||||
data->doCapture = 0;
|
||||
}
|
||||
|
||||
static void oss_capture_samples(ALCdevice *pDevice, ALCvoid *pBuffer, ALCuint lSamples)
|
||||
{
|
||||
oss_data *data = (oss_data*)pDevice->ExtraData;
|
||||
if(lSamples <= (ALCuint)RingBufferSize(data->ring))
|
||||
ReadRingBuffer(data->ring, pBuffer, lSamples);
|
||||
else
|
||||
SetALCError(ALC_INVALID_VALUE);
|
||||
}
|
||||
|
||||
static ALCuint oss_available_samples(ALCdevice *pDevice)
|
||||
{
|
||||
oss_data *data = (oss_data*)pDevice->ExtraData;
|
||||
return RingBufferSize(data->ring);
|
||||
}
|
||||
|
||||
|
||||
BackendFuncs oss_funcs = {
|
||||
oss_open_playback,
|
||||
oss_close_playback,
|
||||
oss_open_capture,
|
||||
oss_close_capture,
|
||||
oss_start_capture,
|
||||
oss_stop_capture,
|
||||
oss_capture_samples,
|
||||
oss_available_samples
|
||||
};
|
||||
|
||||
void alc_oss_init(BackendFuncs *func_list)
|
||||
{
|
||||
*func_list = oss_funcs;
|
||||
|
||||
oss_device = AppendDeviceList("OSS Software");
|
||||
AppendAllDeviceList(oss_device);
|
||||
|
||||
oss_device_capture = AppendCaptureDeviceList("OSS Capture");
|
||||
}
|
||||
+450
@@ -0,0 +1,450 @@
|
||||
/**
|
||||
* OpenAL cross platform audio library
|
||||
* Copyright (C) 1999-2010 by authors.
|
||||
* 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., 59 Temple Place - Suite 330,
|
||||
* Boston, MA 02111-1307, USA.
|
||||
* Or go to http://www.gnu.org/copyleft/lgpl.html
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <math.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <ctype.h>
|
||||
#include <assert.h>
|
||||
|
||||
#include "alMain.h"
|
||||
#include "AL/al.h"
|
||||
#include "AL/alc.h"
|
||||
#include "alu.h"
|
||||
|
||||
static void SetSpeakerArrangement(const char *name, ALfloat SpeakerAngle[MaxChannels],
|
||||
enum Channel Speaker2Chan[MaxChannels], ALint chans)
|
||||
{
|
||||
char *confkey, *next;
|
||||
char *layout_str;
|
||||
char *sep, *end;
|
||||
enum Channel val;
|
||||
const char *str;
|
||||
int i;
|
||||
|
||||
if(!ConfigValueStr(NULL, name, &str) && !ConfigValueStr(NULL, "layout", &str))
|
||||
return;
|
||||
|
||||
layout_str = strdup(str);
|
||||
next = confkey = layout_str;
|
||||
while(next && *next)
|
||||
{
|
||||
confkey = next;
|
||||
next = strchr(confkey, ',');
|
||||
if(next)
|
||||
{
|
||||
*next = 0;
|
||||
do {
|
||||
next++;
|
||||
} while(isspace(*next) || *next == ',');
|
||||
}
|
||||
|
||||
sep = strchr(confkey, '=');
|
||||
if(!sep || confkey == sep)
|
||||
{
|
||||
ERR("Malformed speaker key: %s\n", confkey);
|
||||
continue;
|
||||
}
|
||||
|
||||
end = sep - 1;
|
||||
while(isspace(*end) && end != confkey)
|
||||
end--;
|
||||
*(++end) = 0;
|
||||
|
||||
if(strcmp(confkey, "fl") == 0 || strcmp(confkey, "front-left") == 0)
|
||||
val = FrontLeft;
|
||||
else if(strcmp(confkey, "fr") == 0 || strcmp(confkey, "front-right") == 0)
|
||||
val = FrontRight;
|
||||
else if(strcmp(confkey, "fc") == 0 || strcmp(confkey, "front-center") == 0)
|
||||
val = FrontCenter;
|
||||
else if(strcmp(confkey, "bl") == 0 || strcmp(confkey, "back-left") == 0)
|
||||
val = BackLeft;
|
||||
else if(strcmp(confkey, "br") == 0 || strcmp(confkey, "back-right") == 0)
|
||||
val = BackRight;
|
||||
else if(strcmp(confkey, "bc") == 0 || strcmp(confkey, "back-center") == 0)
|
||||
val = BackCenter;
|
||||
else if(strcmp(confkey, "sl") == 0 || strcmp(confkey, "side-left") == 0)
|
||||
val = SideLeft;
|
||||
else if(strcmp(confkey, "sr") == 0 || strcmp(confkey, "side-right") == 0)
|
||||
val = SideRight;
|
||||
else
|
||||
{
|
||||
ERR("Unknown speaker for %s: \"%s\"\n", name, confkey);
|
||||
continue;
|
||||
}
|
||||
|
||||
*(sep++) = 0;
|
||||
while(isspace(*sep))
|
||||
sep++;
|
||||
|
||||
for(i = 0;i < chans;i++)
|
||||
{
|
||||
if(Speaker2Chan[i] == val)
|
||||
{
|
||||
long angle = strtol(sep, NULL, 10);
|
||||
if(angle >= -180 && angle <= 180)
|
||||
SpeakerAngle[i] = angle * F_PI/180.0f;
|
||||
else
|
||||
ERR("Invalid angle for speaker \"%s\": %ld\n", confkey, angle);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
free(layout_str);
|
||||
layout_str = NULL;
|
||||
|
||||
for(i = 0;i < chans;i++)
|
||||
{
|
||||
int min = i;
|
||||
int i2;
|
||||
|
||||
for(i2 = i+1;i2 < chans;i2++)
|
||||
{
|
||||
if(SpeakerAngle[i2] < SpeakerAngle[min])
|
||||
min = i2;
|
||||
}
|
||||
|
||||
if(min != i)
|
||||
{
|
||||
ALfloat tmpf;
|
||||
enum Channel tmpc;
|
||||
|
||||
tmpf = SpeakerAngle[i];
|
||||
SpeakerAngle[i] = SpeakerAngle[min];
|
||||
SpeakerAngle[min] = tmpf;
|
||||
|
||||
tmpc = Speaker2Chan[i];
|
||||
Speaker2Chan[i] = Speaker2Chan[min];
|
||||
Speaker2Chan[min] = tmpc;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* ComputeAngleGains
|
||||
*
|
||||
* Sets channel gains based on a given source's angle and its half-width. The
|
||||
* angle and hwidth parameters are in radians.
|
||||
*/
|
||||
ALvoid ComputeAngleGains(const ALCdevice *device, ALfloat angle, ALfloat hwidth, ALfloat ingain, ALfloat *gains)
|
||||
{
|
||||
ALfloat tmpgains[MaxChannels] = { 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f };
|
||||
enum Channel Speaker2Chan[MaxChannels];
|
||||
ALfloat SpeakerAngle[MaxChannels];
|
||||
ALfloat langle, rangle;
|
||||
ALfloat a;
|
||||
ALuint i;
|
||||
|
||||
for(i = 0;i < device->NumChan;i++)
|
||||
Speaker2Chan[i] = device->Speaker2Chan[i];
|
||||
for(i = 0;i < device->NumChan;i++)
|
||||
SpeakerAngle[i] = device->SpeakerAngle[i];
|
||||
|
||||
/* Some easy special-cases first... */
|
||||
if(device->NumChan == 1 || hwidth >= F_PI)
|
||||
{
|
||||
/* Full coverage for all speakers. */
|
||||
for(i = 0;i < device->NumChan;i++)
|
||||
{
|
||||
enum Channel chan = Speaker2Chan[i];
|
||||
gains[chan] = ingain;
|
||||
}
|
||||
return;
|
||||
}
|
||||
if(hwidth <= 0.0f)
|
||||
{
|
||||
/* Infinitely small sound point. */
|
||||
for(i = 0;i < device->NumChan-1;i++)
|
||||
{
|
||||
if(angle >= SpeakerAngle[i] && angle < SpeakerAngle[i+1])
|
||||
{
|
||||
/* Sound is between speakers i and i+1 */
|
||||
a = (angle-SpeakerAngle[i]) /
|
||||
(SpeakerAngle[i+1]-SpeakerAngle[i]);
|
||||
gains[Speaker2Chan[i]] = sqrtf(1.0f-a) * ingain;
|
||||
gains[Speaker2Chan[i+1]] = sqrtf( a) * ingain;
|
||||
return;
|
||||
}
|
||||
}
|
||||
/* Sound is between last and first speakers */
|
||||
if(angle < SpeakerAngle[0])
|
||||
angle += F_PI*2.0f;
|
||||
a = (angle-SpeakerAngle[i]) /
|
||||
(F_PI*2.0f + SpeakerAngle[0]-SpeakerAngle[i]);
|
||||
gains[Speaker2Chan[i]] = sqrtf(1.0f-a) * ingain;
|
||||
gains[Speaker2Chan[0]] = sqrtf( a) * ingain;
|
||||
return;
|
||||
}
|
||||
|
||||
if(fabsf(angle)+hwidth > F_PI)
|
||||
{
|
||||
/* The coverage area would go outside of -pi...+pi. Instead, rotate the
|
||||
* speaker angles so it would be as if angle=0, and keep them wrapped
|
||||
* within -pi...+pi. */
|
||||
if(angle > 0.0f)
|
||||
{
|
||||
ALuint done = 0;
|
||||
ALuint i = 0;
|
||||
while(i < device->NumChan && device->SpeakerAngle[i]-angle < -F_PI)
|
||||
i++;
|
||||
for(done = 0;i < device->NumChan;done++)
|
||||
{
|
||||
SpeakerAngle[done] = device->SpeakerAngle[i]-angle;
|
||||
Speaker2Chan[done] = device->Speaker2Chan[i];
|
||||
i++;
|
||||
}
|
||||
for(i = 0;done < device->NumChan;i++)
|
||||
{
|
||||
SpeakerAngle[done] = device->SpeakerAngle[i]-angle + F_PI*2.0f;
|
||||
Speaker2Chan[done] = device->Speaker2Chan[i];
|
||||
done++;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* NOTE: '< device->NumChan' on the iterators is correct here since
|
||||
* we need to handle index 0. Because the iterators are unsigned,
|
||||
* they'll underflow and wrap to become 0xFFFFFFFF, which will
|
||||
* break as expected. */
|
||||
ALuint done = device->NumChan-1;
|
||||
ALuint i = device->NumChan-1;
|
||||
while(i < device->NumChan && device->SpeakerAngle[i]-angle > F_PI)
|
||||
i--;
|
||||
for(done = device->NumChan-1;i < device->NumChan;done--)
|
||||
{
|
||||
SpeakerAngle[done] = device->SpeakerAngle[i]-angle;
|
||||
Speaker2Chan[done] = device->Speaker2Chan[i];
|
||||
i--;
|
||||
}
|
||||
for(i = device->NumChan-1;done < device->NumChan;i--)
|
||||
{
|
||||
SpeakerAngle[done] = device->SpeakerAngle[i]-angle - F_PI*2.0f;
|
||||
Speaker2Chan[done] = device->Speaker2Chan[i];
|
||||
done--;
|
||||
}
|
||||
}
|
||||
angle = 0.0f;
|
||||
}
|
||||
langle = angle - hwidth;
|
||||
rangle = angle + hwidth;
|
||||
|
||||
/* First speaker */
|
||||
i = 0;
|
||||
do {
|
||||
ALuint last = device->NumChan-1;
|
||||
enum Channel chan = Speaker2Chan[i];
|
||||
|
||||
if(SpeakerAngle[i] >= langle && SpeakerAngle[i] <= rangle)
|
||||
{
|
||||
tmpgains[chan] = 1.0f;
|
||||
continue;
|
||||
}
|
||||
|
||||
if(SpeakerAngle[i] < langle && SpeakerAngle[i+1] > langle)
|
||||
{
|
||||
a = (langle-SpeakerAngle[i]) /
|
||||
(SpeakerAngle[i+1]-SpeakerAngle[i]);
|
||||
tmpgains[chan] = lerp(tmpgains[chan], 1.0f, 1.0f-a);
|
||||
}
|
||||
if(SpeakerAngle[i] > rangle)
|
||||
{
|
||||
a = (F_PI*2.0f + rangle-SpeakerAngle[last]) /
|
||||
(F_PI*2.0f + SpeakerAngle[i]-SpeakerAngle[last]);
|
||||
tmpgains[chan] = lerp(tmpgains[chan], 1.0f, a);
|
||||
}
|
||||
else if(SpeakerAngle[last] < rangle)
|
||||
{
|
||||
a = (rangle-SpeakerAngle[last]) /
|
||||
(F_PI*2.0f + SpeakerAngle[i]-SpeakerAngle[last]);
|
||||
tmpgains[chan] = lerp(tmpgains[chan], 1.0f, a);
|
||||
}
|
||||
} while(0);
|
||||
|
||||
for(i = 1;i < device->NumChan-1;i++)
|
||||
{
|
||||
enum Channel chan = Speaker2Chan[i];
|
||||
if(SpeakerAngle[i] >= langle && SpeakerAngle[i] <= rangle)
|
||||
{
|
||||
tmpgains[chan] = 1.0f;
|
||||
continue;
|
||||
}
|
||||
|
||||
if(SpeakerAngle[i] < langle && SpeakerAngle[i+1] > langle)
|
||||
{
|
||||
a = (langle-SpeakerAngle[i]) /
|
||||
(SpeakerAngle[i+1]-SpeakerAngle[i]);
|
||||
tmpgains[chan] = lerp(tmpgains[chan], 1.0f, 1.0f-a);
|
||||
}
|
||||
if(SpeakerAngle[i] > rangle && SpeakerAngle[i-1] < rangle)
|
||||
{
|
||||
a = (rangle-SpeakerAngle[i-1]) /
|
||||
(SpeakerAngle[i]-SpeakerAngle[i-1]);
|
||||
tmpgains[chan] = lerp(tmpgains[chan], 1.0f, a);
|
||||
}
|
||||
}
|
||||
|
||||
/* Last speaker */
|
||||
i = device->NumChan-1;
|
||||
do {
|
||||
enum Channel chan = Speaker2Chan[i];
|
||||
if(SpeakerAngle[i] >= langle && SpeakerAngle[i] <= rangle)
|
||||
{
|
||||
tmpgains[Speaker2Chan[i]] = 1.0f;
|
||||
continue;
|
||||
}
|
||||
if(SpeakerAngle[i] > rangle && SpeakerAngle[i-1] < rangle)
|
||||
{
|
||||
a = (rangle-SpeakerAngle[i-1]) /
|
||||
(SpeakerAngle[i]-SpeakerAngle[i-1]);
|
||||
tmpgains[chan] = lerp(tmpgains[chan], 1.0f, a);
|
||||
}
|
||||
if(SpeakerAngle[i] < langle)
|
||||
{
|
||||
a = (langle-SpeakerAngle[i]) /
|
||||
(F_PI*2.0f + SpeakerAngle[0]-SpeakerAngle[i]);
|
||||
tmpgains[chan] = lerp(tmpgains[chan], 1.0f, 1.0f-a);
|
||||
}
|
||||
else if(SpeakerAngle[0] > langle)
|
||||
{
|
||||
a = (F_PI*2.0f + langle-SpeakerAngle[i]) /
|
||||
(F_PI*2.0f + SpeakerAngle[0]-SpeakerAngle[i]);
|
||||
tmpgains[chan] = lerp(tmpgains[chan], 1.0f, 1.0f-a);
|
||||
}
|
||||
} while(0);
|
||||
|
||||
for(i = 0;i < device->NumChan;i++)
|
||||
{
|
||||
enum Channel chan = device->Speaker2Chan[i];
|
||||
gains[chan] = sqrtf(tmpgains[chan]) * ingain;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
ALvoid aluInitPanning(ALCdevice *Device)
|
||||
{
|
||||
const char *layoutname = NULL;
|
||||
enum Channel *Speaker2Chan;
|
||||
ALfloat *SpeakerAngle;
|
||||
|
||||
Speaker2Chan = Device->Speaker2Chan;
|
||||
SpeakerAngle = Device->SpeakerAngle;
|
||||
switch(Device->FmtChans)
|
||||
{
|
||||
case DevFmtMono:
|
||||
Device->NumChan = 1;
|
||||
Speaker2Chan[0] = FrontCenter;
|
||||
SpeakerAngle[0] = F_PI/180.0f * 0.0f;
|
||||
layoutname = NULL;
|
||||
break;
|
||||
|
||||
case DevFmtStereo:
|
||||
Device->NumChan = 2;
|
||||
Speaker2Chan[0] = FrontLeft;
|
||||
Speaker2Chan[1] = FrontRight;
|
||||
SpeakerAngle[0] = F_PI/180.0f * -90.0f;
|
||||
SpeakerAngle[1] = F_PI/180.0f * 90.0f;
|
||||
layoutname = "layout_stereo";
|
||||
break;
|
||||
|
||||
case DevFmtQuad:
|
||||
Device->NumChan = 4;
|
||||
Speaker2Chan[0] = BackLeft;
|
||||
Speaker2Chan[1] = FrontLeft;
|
||||
Speaker2Chan[2] = FrontRight;
|
||||
Speaker2Chan[3] = BackRight;
|
||||
SpeakerAngle[0] = F_PI/180.0f * -135.0f;
|
||||
SpeakerAngle[1] = F_PI/180.0f * -45.0f;
|
||||
SpeakerAngle[2] = F_PI/180.0f * 45.0f;
|
||||
SpeakerAngle[3] = F_PI/180.0f * 135.0f;
|
||||
layoutname = "layout_quad";
|
||||
break;
|
||||
|
||||
case DevFmtX51:
|
||||
Device->NumChan = 5;
|
||||
Speaker2Chan[0] = BackLeft;
|
||||
Speaker2Chan[1] = FrontLeft;
|
||||
Speaker2Chan[2] = FrontCenter;
|
||||
Speaker2Chan[3] = FrontRight;
|
||||
Speaker2Chan[4] = BackRight;
|
||||
SpeakerAngle[0] = F_PI/180.0f * -110.0f;
|
||||
SpeakerAngle[1] = F_PI/180.0f * -30.0f;
|
||||
SpeakerAngle[2] = F_PI/180.0f * 0.0f;
|
||||
SpeakerAngle[3] = F_PI/180.0f * 30.0f;
|
||||
SpeakerAngle[4] = F_PI/180.0f * 110.0f;
|
||||
layoutname = "layout_surround51";
|
||||
break;
|
||||
|
||||
case DevFmtX51Side:
|
||||
Device->NumChan = 5;
|
||||
Speaker2Chan[0] = SideLeft;
|
||||
Speaker2Chan[1] = FrontLeft;
|
||||
Speaker2Chan[2] = FrontCenter;
|
||||
Speaker2Chan[3] = FrontRight;
|
||||
Speaker2Chan[4] = SideRight;
|
||||
SpeakerAngle[0] = F_PI/180.0f * -90.0f;
|
||||
SpeakerAngle[1] = F_PI/180.0f * -30.0f;
|
||||
SpeakerAngle[2] = F_PI/180.0f * 0.0f;
|
||||
SpeakerAngle[3] = F_PI/180.0f * 30.0f;
|
||||
SpeakerAngle[4] = F_PI/180.0f * 90.0f;
|
||||
layoutname = "layout_side51";
|
||||
break;
|
||||
|
||||
case DevFmtX61:
|
||||
Device->NumChan = 6;
|
||||
Speaker2Chan[0] = SideLeft;
|
||||
Speaker2Chan[1] = FrontLeft;
|
||||
Speaker2Chan[2] = FrontCenter;
|
||||
Speaker2Chan[3] = FrontRight;
|
||||
Speaker2Chan[4] = SideRight;
|
||||
Speaker2Chan[5] = BackCenter;
|
||||
SpeakerAngle[0] = F_PI/180.0f * -90.0f;
|
||||
SpeakerAngle[1] = F_PI/180.0f * -30.0f;
|
||||
SpeakerAngle[2] = F_PI/180.0f * 0.0f;
|
||||
SpeakerAngle[3] = F_PI/180.0f * 30.0f;
|
||||
SpeakerAngle[4] = F_PI/180.0f * 90.0f;
|
||||
SpeakerAngle[5] = F_PI/180.0f * 180.0f;
|
||||
layoutname = "layout_surround61";
|
||||
break;
|
||||
|
||||
case DevFmtX71:
|
||||
Device->NumChan = 7;
|
||||
Speaker2Chan[0] = BackLeft;
|
||||
Speaker2Chan[1] = SideLeft;
|
||||
Speaker2Chan[2] = FrontLeft;
|
||||
Speaker2Chan[3] = FrontCenter;
|
||||
Speaker2Chan[4] = FrontRight;
|
||||
Speaker2Chan[5] = SideRight;
|
||||
Speaker2Chan[6] = BackRight;
|
||||
SpeakerAngle[0] = F_PI/180.0f * -150.0f;
|
||||
SpeakerAngle[1] = F_PI/180.0f * -90.0f;
|
||||
SpeakerAngle[2] = F_PI/180.0f * -30.0f;
|
||||
SpeakerAngle[3] = F_PI/180.0f * 0.0f;
|
||||
SpeakerAngle[4] = F_PI/180.0f * 30.0f;
|
||||
SpeakerAngle[5] = F_PI/180.0f * 90.0f;
|
||||
SpeakerAngle[6] = F_PI/180.0f * 150.0f;
|
||||
layoutname = "layout_surround71";
|
||||
break;
|
||||
}
|
||||
if(layoutname && Device->Type != Loopback)
|
||||
SetSpeakerArrangement(layoutname, SpeakerAngle, Speaker2Chan, Device->NumChan);
|
||||
}
|
||||
-420
@@ -1,420 +0,0 @@
|
||||
/**
|
||||
* OpenAL cross platform audio library
|
||||
* Copyright (C) 1999-2007 by authors.
|
||||
* 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., 59 Temple Place - Suite 330,
|
||||
* Boston, MA 02111-1307, USA.
|
||||
* Or go to http://www.gnu.org/copyleft/lgpl.html
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <memory.h>
|
||||
|
||||
#include <windows.h>
|
||||
#include <mmsystem.h>
|
||||
|
||||
#include "alMain.h"
|
||||
#include "AL/al.h"
|
||||
#include "AL/alc.h"
|
||||
|
||||
|
||||
typedef struct {
|
||||
// MMSYSTEM Capture Device
|
||||
ALboolean bWaveInShutdown;
|
||||
HANDLE hWaveInHdrEvent;
|
||||
HANDLE hWaveInThreadEvent;
|
||||
HANDLE hWaveInThread;
|
||||
DWORD ulWaveInThreadID;
|
||||
ALint lWaveInBuffersCommitted;
|
||||
HWAVEIN hWaveInHandle;
|
||||
WAVEHDR WaveInBuffer[4];
|
||||
ALCchar *pCapturedSampleData;
|
||||
ALuint ulCapturedDataSize;
|
||||
ALuint ulReadCapturedDataPos;
|
||||
ALuint ulWriteCapturedDataPos;
|
||||
} WinMMData;
|
||||
|
||||
|
||||
static ALCchar *CaptureDeviceList[16];
|
||||
|
||||
/*
|
||||
WaveInProc
|
||||
|
||||
Posts a message to 'CaptureThreadProc' everytime a WaveIn Buffer is completed and
|
||||
returns to the application (with more data)
|
||||
*/
|
||||
static void CALLBACK WaveInProc(HWAVEIN hDevice,UINT uMsg,DWORD_PTR dwInstance,DWORD_PTR dwParam1,DWORD_PTR dwParam2)
|
||||
{
|
||||
ALCdevice *pDevice = (ALCdevice *)dwInstance;
|
||||
WinMMData *pData = pDevice->ExtraData;
|
||||
|
||||
(void)hDevice;
|
||||
(void)dwParam2;
|
||||
|
||||
if ((uMsg==WIM_DATA) && (pDevice))
|
||||
{
|
||||
// Decrement number of buffers in use
|
||||
pData->lWaveInBuffersCommitted--;
|
||||
|
||||
if (pData->bWaveInShutdown == AL_FALSE)
|
||||
{
|
||||
// Notify Wave Processor Thread that a Wave Header has returned
|
||||
PostThreadMessage(pData->ulWaveInThreadID,uMsg,0,dwParam1);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (pData->lWaveInBuffersCommitted == 0)
|
||||
{
|
||||
// Signal Wave Buffers Returned event
|
||||
if (pData->hWaveInHdrEvent)
|
||||
SetEvent(pData->hWaveInHdrEvent);
|
||||
|
||||
// Post 'Quit' Message to WaveIn Processor Thread
|
||||
PostThreadMessage(pData->ulWaveInThreadID,WM_QUIT,0,0);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
CaptureThreadProc
|
||||
|
||||
Used by "MMSYSTEM" Device. Called when a WaveIn buffer had been filled with new
|
||||
audio data.
|
||||
*/
|
||||
DWORD WINAPI CaptureThreadProc(LPVOID lpParameter)
|
||||
{
|
||||
ALCdevice *pDevice = (ALCdevice*)lpParameter;
|
||||
WinMMData *pData = pDevice->ExtraData;
|
||||
ALuint ulOffset, ulMaxSize, ulSection;
|
||||
LPWAVEHDR pWaveHdr;
|
||||
MSG msg;
|
||||
|
||||
while (GetMessage(&msg, NULL, 0, 0))
|
||||
{
|
||||
if ((msg.message==WIM_DATA)&&(!pData->bWaveInShutdown))
|
||||
{
|
||||
SuspendContext(NULL);
|
||||
|
||||
pWaveHdr = ((LPWAVEHDR)msg.lParam);
|
||||
|
||||
// Calculate offset in local buffer to write data to
|
||||
ulOffset = pData->ulWriteCapturedDataPos % pData->ulCapturedDataSize;
|
||||
|
||||
if ((ulOffset + pWaveHdr->dwBytesRecorded) > pData->ulCapturedDataSize)
|
||||
{
|
||||
ulSection = pData->ulCapturedDataSize - ulOffset;
|
||||
memcpy(pData->pCapturedSampleData + ulOffset, pWaveHdr->lpData, ulSection);
|
||||
memcpy(pData->pCapturedSampleData, pWaveHdr->lpData + ulSection, pWaveHdr->dwBytesRecorded - ulSection);
|
||||
}
|
||||
else
|
||||
{
|
||||
memcpy(pData->pCapturedSampleData + ulOffset, pWaveHdr->lpData, pWaveHdr->dwBytesRecorded);
|
||||
}
|
||||
|
||||
pData->ulWriteCapturedDataPos += pWaveHdr->dwBytesRecorded;
|
||||
|
||||
if (pData->ulWriteCapturedDataPos > (pData->ulReadCapturedDataPos + pData->ulCapturedDataSize))
|
||||
{
|
||||
// Application has not read enough audio data from the capture buffer so data has been
|
||||
// overwritten. Reset ReadPosition.
|
||||
pData->ulReadCapturedDataPos = pData->ulWriteCapturedDataPos - pData->ulCapturedDataSize;
|
||||
}
|
||||
|
||||
// To prevent an over-flow prevent the offset values from getting too large
|
||||
ulMaxSize = pData->ulCapturedDataSize << 4;
|
||||
if ((pData->ulReadCapturedDataPos > ulMaxSize) && (pData->ulWriteCapturedDataPos > ulMaxSize))
|
||||
{
|
||||
pData->ulReadCapturedDataPos -= ulMaxSize;
|
||||
pData->ulWriteCapturedDataPos -= ulMaxSize;
|
||||
}
|
||||
|
||||
// Send buffer back to capture more data
|
||||
waveInAddBuffer(pData->hWaveInHandle,pWaveHdr,sizeof(WAVEHDR));
|
||||
pData->lWaveInBuffersCommitted++;
|
||||
|
||||
ProcessContext(NULL);
|
||||
}
|
||||
}
|
||||
|
||||
// Signal Wave Thread completed event
|
||||
if (pData->hWaveInThreadEvent)
|
||||
SetEvent(pData->hWaveInThreadEvent);
|
||||
|
||||
ExitThread(0);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static ALCboolean WinMMOpenPlayback(ALCdevice *device, const ALCchar *deviceName)
|
||||
{
|
||||
(void)device;
|
||||
(void)deviceName;
|
||||
return ALC_FALSE;
|
||||
}
|
||||
|
||||
static void WinMMClosePlayback(ALCdevice *device)
|
||||
{
|
||||
(void)device;
|
||||
}
|
||||
|
||||
|
||||
static ALCboolean WinMMOpenCapture(ALCdevice *pDevice, const ALCchar *deviceName, ALCuint frequency, ALCenum format, ALCsizei SampleSize)
|
||||
{
|
||||
WAVEFORMATEX wfexCaptureFormat;
|
||||
WinMMData *pData = NULL;
|
||||
ALint lDeviceID = 0;
|
||||
ALint lBufferSize;
|
||||
ALint i;
|
||||
|
||||
(void)format;
|
||||
|
||||
// Find the Device ID matching the deviceName if valid
|
||||
if (deviceName)
|
||||
{
|
||||
for(i = 0;CaptureDeviceList[i];i++)
|
||||
{
|
||||
if (!strcmp(deviceName, CaptureDeviceList[i]))
|
||||
{
|
||||
lDeviceID = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if(!CaptureDeviceList[i])
|
||||
return ALC_FALSE;
|
||||
}
|
||||
pDevice->szDeviceName = CaptureDeviceList[lDeviceID];
|
||||
|
||||
pData = calloc(1, sizeof(*pData));
|
||||
if(!pData)
|
||||
{
|
||||
SetALCError(ALC_OUT_OF_MEMORY);
|
||||
return ALC_FALSE;
|
||||
}
|
||||
|
||||
memset(&wfexCaptureFormat, 0, sizeof(WAVEFORMATEX));
|
||||
wfexCaptureFormat.wFormatTag = WAVE_FORMAT_PCM;
|
||||
wfexCaptureFormat.nChannels = pDevice->Channels;
|
||||
wfexCaptureFormat.wBitsPerSample = pDevice->FrameSize / pDevice->Channels * 8;
|
||||
wfexCaptureFormat.nBlockAlign = pDevice->FrameSize;
|
||||
wfexCaptureFormat.nSamplesPerSec = frequency;
|
||||
wfexCaptureFormat.nAvgBytesPerSec = wfexCaptureFormat.nSamplesPerSec *
|
||||
pDevice->FrameSize;
|
||||
wfexCaptureFormat.cbSize = 0;
|
||||
|
||||
if (waveInOpen(&pData->hWaveInHandle, lDeviceID, &wfexCaptureFormat, (DWORD_PTR)&WaveInProc, (DWORD_PTR)pDevice, CALLBACK_FUNCTION) != MMSYSERR_NOERROR)
|
||||
goto failure;
|
||||
|
||||
pData->hWaveInHdrEvent = CreateEvent(NULL, AL_TRUE, AL_FALSE, "WaveInAllHeadersReturned");
|
||||
if (pData->hWaveInHdrEvent == NULL)
|
||||
goto failure;
|
||||
|
||||
pData->hWaveInThreadEvent = CreateEvent(NULL, AL_TRUE, AL_FALSE, "WaveInThreadDestroyed");
|
||||
if (pData->hWaveInThreadEvent == NULL)
|
||||
goto failure;
|
||||
|
||||
pData->hWaveInThread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)CaptureThreadProc, (LPVOID)pDevice, 0, &pData->ulWaveInThreadID);
|
||||
if (pData->hWaveInThread == NULL)
|
||||
goto failure;
|
||||
|
||||
// Allocate circular memory buffer for the captured audio
|
||||
pData->ulCapturedDataSize = SampleSize * wfexCaptureFormat.nBlockAlign;
|
||||
|
||||
// Make sure circular buffer is at least 100ms in size (and an exact multiple of
|
||||
// the block alignment
|
||||
if (pData->ulCapturedDataSize < (wfexCaptureFormat.nAvgBytesPerSec / 10))
|
||||
{
|
||||
pData->ulCapturedDataSize = wfexCaptureFormat.nAvgBytesPerSec / 10;
|
||||
pData->ulCapturedDataSize -= (pData->ulCapturedDataSize % wfexCaptureFormat.nBlockAlign);
|
||||
}
|
||||
|
||||
pData->pCapturedSampleData = (ALCchar*)malloc(pData->ulCapturedDataSize);
|
||||
pData->lWaveInBuffersCommitted=0;
|
||||
|
||||
// Create 4 Buffers of 50ms each
|
||||
lBufferSize = wfexCaptureFormat.nAvgBytesPerSec / 20;
|
||||
lBufferSize -= (lBufferSize % wfexCaptureFormat.nBlockAlign);
|
||||
|
||||
for (i=0;i<4;i++)
|
||||
{
|
||||
memset(&pData->WaveInBuffer[i], 0, sizeof(WAVEHDR));
|
||||
pData->WaveInBuffer[i].dwBufferLength = lBufferSize;
|
||||
pData->WaveInBuffer[i].lpData = calloc(1,pData->WaveInBuffer[i].dwBufferLength);
|
||||
pData->WaveInBuffer[i].dwFlags = 0;
|
||||
pData->WaveInBuffer[i].dwLoops = 0;
|
||||
waveInPrepareHeader(pData->hWaveInHandle, &pData->WaveInBuffer[i], sizeof(WAVEHDR));
|
||||
waveInAddBuffer(pData->hWaveInHandle, &pData->WaveInBuffer[i], sizeof(WAVEHDR));
|
||||
pData->lWaveInBuffersCommitted++;
|
||||
}
|
||||
|
||||
pData->ulReadCapturedDataPos = 0;
|
||||
pData->ulWriteCapturedDataPos = 0;
|
||||
|
||||
pDevice->ExtraData = pData;
|
||||
return ALC_TRUE;
|
||||
|
||||
failure:
|
||||
if (pData->hWaveInThreadEvent)
|
||||
CloseHandle(pData->hWaveInThreadEvent);
|
||||
if (pData->hWaveInHdrEvent)
|
||||
CloseHandle(pData->hWaveInHdrEvent);
|
||||
if (pData->hWaveInHandle)
|
||||
waveInClose(pData->hWaveInHandle);
|
||||
|
||||
free(pData);
|
||||
return ALC_FALSE;
|
||||
}
|
||||
|
||||
static void WinMMCloseCapture(ALCdevice *pDevice)
|
||||
{
|
||||
WinMMData *pData = (WinMMData*)pDevice->ExtraData;
|
||||
int i;
|
||||
|
||||
// Call waveOutReset to shutdown wave device
|
||||
pData->bWaveInShutdown = AL_TRUE;
|
||||
waveInReset(pData->hWaveInHandle);
|
||||
|
||||
// Wait for signal that all Wave Buffers have returned
|
||||
WaitForSingleObjectEx(pData->hWaveInHdrEvent, 5000, FALSE);
|
||||
|
||||
// Wait for signal that Wave Thread has been destroyed
|
||||
WaitForSingleObjectEx(pData->hWaveInThreadEvent, 5000, FALSE);
|
||||
|
||||
// Release the wave buffers
|
||||
for (i=0;i<4;i++)
|
||||
{
|
||||
waveInUnprepareHeader(pData->hWaveInHandle, &pData->WaveInBuffer[i], sizeof(WAVEHDR));
|
||||
free(pData->WaveInBuffer[i].lpData);
|
||||
}
|
||||
|
||||
// Free Audio Buffer data
|
||||
free(pData->pCapturedSampleData);
|
||||
pData->pCapturedSampleData = NULL;
|
||||
|
||||
// Close the Wave device
|
||||
waveInClose(pData->hWaveInHandle);
|
||||
pData->hWaveInHandle = 0;
|
||||
|
||||
CloseHandle(pData->hWaveInThread);
|
||||
pData->hWaveInThread = 0;
|
||||
|
||||
if (pData->hWaveInHdrEvent)
|
||||
{
|
||||
CloseHandle(pData->hWaveInHdrEvent);
|
||||
pData->hWaveInHdrEvent = 0;
|
||||
}
|
||||
|
||||
if (pData->hWaveInThreadEvent)
|
||||
{
|
||||
CloseHandle(pData->hWaveInThreadEvent);
|
||||
pData->hWaveInThreadEvent = 0;
|
||||
}
|
||||
|
||||
free(pData);
|
||||
pDevice->ExtraData = NULL;
|
||||
}
|
||||
|
||||
static void WinMMStartCapture(ALCdevice *pDevice)
|
||||
{
|
||||
WinMMData *pData = (WinMMData*)pDevice->ExtraData;
|
||||
waveInStart(pData->hWaveInHandle);
|
||||
}
|
||||
|
||||
static void WinMMStopCapture(ALCdevice *pDevice)
|
||||
{
|
||||
WinMMData *pData = (WinMMData*)pDevice->ExtraData;
|
||||
waveInStop(pData->hWaveInHandle);
|
||||
}
|
||||
|
||||
static void WinMMCaptureSamples(ALCdevice *pDevice, ALCvoid *pBuffer, ALCuint lSamples)
|
||||
{
|
||||
WinMMData *pData = (WinMMData*)pDevice->ExtraData;
|
||||
ALuint ulSamples = (unsigned long)lSamples;
|
||||
ALuint ulBytes, ulBytesToCopy;
|
||||
ALuint ulCapturedSamples;
|
||||
ALuint ulReadOffset;
|
||||
|
||||
// Check that we have the requested numbers of Samples
|
||||
ulCapturedSamples = (pData->ulWriteCapturedDataPos - pData->ulReadCapturedDataPos) / pDevice->FrameSize;
|
||||
if(ulSamples > ulCapturedSamples)
|
||||
{
|
||||
SetALCError(ALC_INVALID_VALUE);
|
||||
return;
|
||||
}
|
||||
|
||||
ulBytes = ulSamples * pDevice->FrameSize;
|
||||
|
||||
// Get Read Offset
|
||||
ulReadOffset = (pData->ulReadCapturedDataPos % pData->ulCapturedDataSize);
|
||||
|
||||
// Check for wrap-around condition
|
||||
if ((ulReadOffset + ulBytes) > pData->ulCapturedDataSize)
|
||||
{
|
||||
// Copy data from last Read position to end of data
|
||||
ulBytesToCopy = pData->ulCapturedDataSize - ulReadOffset;
|
||||
memcpy(pBuffer, pData->pCapturedSampleData + ulReadOffset, ulBytesToCopy);
|
||||
|
||||
// Copy rest of the data from the start of the captured data
|
||||
memcpy(((char *)pBuffer) + ulBytesToCopy, pData->pCapturedSampleData, ulBytes - ulBytesToCopy);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Copy data from the read position in the captured data
|
||||
memcpy(pBuffer, pData->pCapturedSampleData + ulReadOffset, ulBytes);
|
||||
}
|
||||
|
||||
// Update Read Position
|
||||
pData->ulReadCapturedDataPos += ulBytes;
|
||||
}
|
||||
|
||||
static ALCuint WinMMAvailableSamples(ALCdevice *pDevice)
|
||||
{
|
||||
WinMMData *pData = (WinMMData*)pDevice->ExtraData;
|
||||
ALCuint lCapturedBytes = (pData->ulWriteCapturedDataPos - pData->ulReadCapturedDataPos);
|
||||
return lCapturedBytes / pDevice->FrameSize;
|
||||
}
|
||||
|
||||
|
||||
BackendFuncs WinMMFuncs = {
|
||||
WinMMOpenPlayback,
|
||||
WinMMClosePlayback,
|
||||
WinMMOpenCapture,
|
||||
WinMMCloseCapture,
|
||||
WinMMStartCapture,
|
||||
WinMMStopCapture,
|
||||
WinMMCaptureSamples,
|
||||
WinMMAvailableSamples
|
||||
};
|
||||
|
||||
void alcWinMMInit(BackendFuncs *FuncList)
|
||||
{
|
||||
ALint lNumDevs;
|
||||
ALint lLoop;
|
||||
|
||||
*FuncList = WinMMFuncs;
|
||||
|
||||
lNumDevs = waveInGetNumDevs();
|
||||
for (lLoop = 0; lLoop < lNumDevs; lLoop++)
|
||||
{
|
||||
WAVEINCAPS WaveInCaps;
|
||||
if(waveInGetDevCaps(lLoop, &WaveInCaps, sizeof(WAVEINCAPS)) == MMSYSERR_NOERROR)
|
||||
{
|
||||
char name[128];
|
||||
snprintf(name, sizeof(name), "WaveIn on %s", WaveInCaps.szPname);
|
||||
CaptureDeviceList[lLoop] = AppendCaptureDeviceList(name);
|
||||
}
|
||||
}
|
||||
}
|
||||
+687
-128
@@ -1,53 +1,160 @@
|
||||
# CMake build file list for OpenAL
|
||||
|
||||
CMAKE_MINIMUM_REQUIRED(VERSION 2.4)
|
||||
|
||||
IF(COMMAND CMAKE_POLICY)
|
||||
CMAKE_POLICY(SET CMP0003 NEW)
|
||||
ENDIF(COMMAND CMAKE_POLICY)
|
||||
|
||||
SET(CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/cmake")
|
||||
|
||||
INCLUDE(CheckFunctionExists)
|
||||
INCLUDE(CheckLibraryExists)
|
||||
INCLUDE(CheckSharedFunctionExists)
|
||||
INCLUDE(CheckIncludeFile)
|
||||
INCLUDE(CheckIncludeFiles)
|
||||
INCLUDE(CheckSymbolExists)
|
||||
INCLUDE(CheckCCompilerFlag)
|
||||
INCLUDE(CheckCSourceCompiles)
|
||||
INCLUDE(CheckTypeSize)
|
||||
INCLUDE(FindPkgConfig)
|
||||
|
||||
|
||||
PROJECT(OpenAL)
|
||||
PROJECT(OpenAL C)
|
||||
|
||||
|
||||
SET(CMAKE_ALLOW_LOOSE_LOOP_CONSTRUCTS TRUE)
|
||||
|
||||
|
||||
OPTION(ALSA "ALSA backend" ON)
|
||||
OPTION(OSS "OSS backend" ON)
|
||||
OPTION(DSOUND "DirectSound backend" ON)
|
||||
OPTION(WINMM "Windows Multimedia backend" ON)
|
||||
OPTION(SSE "Check for SSE CPU extensions" ON)
|
||||
OPTION(NEON "Check for ARM Neon CPU extensions" ON)
|
||||
|
||||
OPTION(DLOPEN "Use the dlopen API for loading optional libs" ON)
|
||||
OPTION(REQUIRE_SSE "Require SSE CPU extensions" OFF)
|
||||
OPTION(REQUIRE_NEON "Require ARM Neon CPU extensions" OFF)
|
||||
|
||||
OPTION(DEBUG "Build lib in debug mode" OFF)
|
||||
OPTION(NODEBUG "Disable all debug info for optimizations" OFF)
|
||||
OPTION(WERROR "Treat compile warnings as errors" OFF)
|
||||
|
||||
OPTION(ALSA "Check for ALSA backend" ON)
|
||||
OPTION(OSS "Check for OSS backend" ON)
|
||||
OPTION(SOLARIS "Check for Solaris backend" ON)
|
||||
OPTION(SNDIO "Check for SndIO backend" ON)
|
||||
OPTION(MMDEVAPI "Check for MMDevApi" ON)
|
||||
OPTION(DSOUND "Check for DirectSound backend" ON)
|
||||
OPTION(WINMM "Check for Windows Multimedia backend" ON)
|
||||
OPTION(PORTAUDIO "Check for PortAudio backend" ON)
|
||||
OPTION(PULSEAUDIO "Check for PulseAudio backend" ON)
|
||||
OPTION(COREAUDIO "Check for CoreAudio backend" ON)
|
||||
OPTION(OPENSL "Check for OpenSL backend" ON)
|
||||
OPTION(WAVE "Enable Wave Writer backend" ON)
|
||||
|
||||
OPTION(REQUIRE_ALSA "Require ALSA backend" OFF)
|
||||
OPTION(REQUIRE_OSS "Require OSS backend" OFF)
|
||||
OPTION(REQUIRE_SOLARIS "Require Solaris backend" OFF)
|
||||
OPTION(REQUIRE_SNDIO "Require SndIO backend" OFF)
|
||||
OPTION(REQUIRE_MMDEVAPI "Require MMDevApi" OFF)
|
||||
OPTION(REQUIRE_DSOUND "Require DirectSound backend" OFF)
|
||||
OPTION(REQUIRE_WINMM "Require Windows Multimedia backend" OFF)
|
||||
OPTION(REQUIRE_PORTAUDIO "Require PortAudio backend" OFF)
|
||||
OPTION(REQUIRE_PULSEAUDIO "Require PulseAudio backend" OFF)
|
||||
OPTION(REQUIRE_COREAUDIO "Require CoreAudio backend" OFF)
|
||||
OPTION(REQUIRE_OPENSL "Require OpenSL backend" OFF)
|
||||
|
||||
OPTION(DLOPEN "Check for the dlopen API for loading optional libs" ON)
|
||||
|
||||
OPTION(WERROR "Treat compile warnings as errors" OFF)
|
||||
|
||||
OPTION(UTILS "Build and install utility programs" ON)
|
||||
|
||||
OPTION(EXAMPLES "Build and install example programs" ON)
|
||||
|
||||
OPTION(ALSOFT_CONFIG "Install alsoft.conf sample configuration file" ON)
|
||||
|
||||
|
||||
IF(WIN32)
|
||||
SET(LIBNAME OpenAL32)
|
||||
ADD_DEFINITIONS("-D_WIN32 -D_WIN32_WINNT=0x0501")
|
||||
ELSE()
|
||||
SET(LIBNAME openal)
|
||||
ENDIF()
|
||||
|
||||
IF(NOT LIBTYPE)
|
||||
SET(LIBTYPE SHARED)
|
||||
ENDIF()
|
||||
|
||||
SET(LIB_MAJOR_VERSION "1")
|
||||
SET(LIB_MINOR_VERSION "1")
|
||||
SET(LIB_BUILD_VERSION "93")
|
||||
SET(LIB_VERSION "${LIB_MAJOR_VERSION}.${LIB_MINOR_VERSION}.${LIB_BUILD_VERSION}")
|
||||
SET(LIB_MINOR_VERSION "15")
|
||||
SET(LIB_VERSION "${LIB_MAJOR_VERSION}.${LIB_MINOR_VERSION}")
|
||||
|
||||
SET(EXPORT_DECL "")
|
||||
SET(ALIGN_DECL "")
|
||||
SET(RESTRICT_DECL "")
|
||||
|
||||
|
||||
CHECK_TYPE_SIZE("long" SIZEOF_LONG)
|
||||
CHECK_TYPE_SIZE("long long" SIZEOF_LONG_LONG)
|
||||
CHECK_TYPE_SIZE("unsigned int" SIZEOF_UINT)
|
||||
CHECK_TYPE_SIZE("void*" SIZEOF_VOIDP)
|
||||
|
||||
|
||||
CHECK_C_SOURCE_COMPILES("int *restrict foo;
|
||||
int main() {return 0;}" HAVE_RESTRICT)
|
||||
IF(HAVE_RESTRICT)
|
||||
SET(RESTRICT_DECL "restrict")
|
||||
ELSE()
|
||||
CHECK_C_SOURCE_COMPILES("int *__restrict foo;
|
||||
int main() {return 0;}" HAVE___RESTRICT)
|
||||
IF(HAVE___RESTRICT)
|
||||
SET(RESTRICT_DECL "__restrict")
|
||||
ENDIF()
|
||||
ENDIF()
|
||||
|
||||
|
||||
# Add definitions, compiler switches, etc.
|
||||
INCLUDE_DIRECTORIES(OpenAL32/Include include "${OpenAL_BINARY_DIR}")
|
||||
|
||||
IF("${MSVC}")
|
||||
IF(NOT CMAKE_BUILD_TYPE)
|
||||
SET(CMAKE_BUILD_TYPE RelWithDebInfo CACHE STRING
|
||||
"Choose the type of build, options are: Debug Release RelWithDebInfo MinSizeRel."
|
||||
FORCE)
|
||||
ENDIF()
|
||||
IF(NOT CMAKE_DEBUG_POSTFIX)
|
||||
SET(CMAKE_DEBUG_POSTFIX "" CACHE STRING
|
||||
"Library postfix for debug builds. Normally left blank."
|
||||
FORCE)
|
||||
ENDIF()
|
||||
|
||||
IF(MSVC)
|
||||
# ???
|
||||
SET(CMAKE_C_FLAGS_RELWITHDEBINFO "${CMAKE_C_FLAGS_RELWITHDEBINFO} -D_DEBUG")
|
||||
SET(CMAKE_C_FLAGS_MINSIZEREL "${CMAKE_C_FLAGS_MINSIZEREL} -DNDEBUG")
|
||||
SET(CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE} -DNDEBUG")
|
||||
SET(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} -D_DEBUG")
|
||||
ADD_DEFINITIONS(-D_CRT_SECURE_NO_WARNINGS)
|
||||
ADD_DEFINITIONS(-D_CRT_NONSTDC_NO_DEPRECATE)
|
||||
|
||||
IF(NOT DXSDK_DIR)
|
||||
STRING(REGEX REPLACE "\\\\" "/" DXSDK_DIR "$ENV{DXSDK_DIR}")
|
||||
ELSE()
|
||||
STRING(REGEX REPLACE "\\\\" "/" DXSDK_DIR "${DXSDK_DIR}")
|
||||
ENDIF()
|
||||
IF(DXSDK_DIR)
|
||||
MESSAGE(STATUS "Using DirectX SDK directory: ${DXSDK_DIR}")
|
||||
SET(CMAKE_REQUIRED_INCLUDES ${CMAKE_REQUIRED_INCLUDES} "${DXSDK_DIR}/Include")
|
||||
INCLUDE_DIRECTORIES("${DXSDK_DIR}/Include")
|
||||
LINK_DIRECTORIES("${DXSDK_DIR}/Lib")
|
||||
ENDIF()
|
||||
|
||||
OPTION(FORCE_STATIC_VCRT "Force /MT for static VC runtimes" OFF)
|
||||
IF(FORCE_STATIC_VCRT)
|
||||
FOREACH(flag_var
|
||||
CMAKE_C_FLAGS CMAKE_C_FLAGS_DEBUG CMAKE_C_FLAGS_RELEASE
|
||||
CMAKE_C_FLAGS_MINSIZEREL CMAKE_C_FLAGS_RELWITHDEBINFO)
|
||||
IF(${flag_var} MATCHES "/MD")
|
||||
STRING(REGEX REPLACE "/MD" "/MT" ${flag_var} "${${flag_var}}")
|
||||
ENDIF()
|
||||
ENDFOREACH(flag_var)
|
||||
ENDIF()
|
||||
ELSE()
|
||||
ADD_DEFINITIONS(-Wall)
|
||||
ADD_DEFINITIONS(-Winline -Wall)
|
||||
CHECK_C_COMPILER_FLAG(-Wextra HAVE_W_EXTRA)
|
||||
IF("${HAVE_W_EXTRA}")
|
||||
IF(HAVE_W_EXTRA)
|
||||
ADD_DEFINITIONS(-Wextra)
|
||||
ENDIF()
|
||||
|
||||
@@ -55,222 +162,598 @@ ELSE()
|
||||
ADD_DEFINITIONS(-Werror)
|
||||
ENDIF()
|
||||
|
||||
IF(DEBUG)
|
||||
ADD_DEFINITIONS(-g3)
|
||||
ELSEIF(NODEBUG)
|
||||
ADD_DEFINITIONS(-O2 -funroll-loops -fomit-frame-pointer)
|
||||
SET(CMAKE_C_FLAGS_RELWITHDEBINFO "-g -O2 -D_DEBUG" CACHE STRING
|
||||
"Flags used by the compiler during Release with Debug Info builds."
|
||||
FORCE)
|
||||
SET(CMAKE_C_FLAGS_MINSIZEREL "-Os -DNDEBUG" CACHE STRING
|
||||
"Flags used by the compiler during release minsize builds."
|
||||
FORCE)
|
||||
SET(CMAKE_C_FLAGS_RELEASE "-O2 -fomit-frame-pointer -DNDEBUG" CACHE STRING
|
||||
"Flags used by the compiler during release builds"
|
||||
FORCE)
|
||||
SET(CMAKE_C_FLAGS_DEBUG "-g3 -D_DEBUG" CACHE STRING
|
||||
"Flags used by the compiler during debug builds."
|
||||
FORCE)
|
||||
|
||||
CHECK_C_SOURCE_COMPILES("int foo() __attribute__((destructor));
|
||||
int main() {return 0;}" HAVE_GCC_DESTRUCTOR)
|
||||
ENDIF()
|
||||
|
||||
# Set visibility/export options if available
|
||||
IF(WIN32)
|
||||
SET(EXPORT_DECL "__declspec(dllexport)")
|
||||
SET(ALIGN_DECL "__declspec(align(x))")
|
||||
|
||||
OPTION(WINE "Enable use of Wine headers when compiling" OFF)
|
||||
IF(WINE)
|
||||
FIND_PATH(WINE_INCLUDE_DIR library.h
|
||||
PATHS
|
||||
/usr/include/wine
|
||||
/usr/local/include/wine
|
||||
CMAKE_FIND_ROOT_PATH_BOTH)
|
||||
IF(WINE_INCLUDE_DIR)
|
||||
MESSAGE(STATUS "Found Wine header files - ${WINE_INCLUDE_DIR}" )
|
||||
INCLUDE_DIRECTORIES("${WINE_INCLUDE_DIR}/windows")
|
||||
SET(CMAKE_REQUIRED_INCLUDES ${CMAKE_REQUIRED_INCLUDES} "${WINE_INCLUDE_DIR}/windows")
|
||||
ELSE()
|
||||
MESSAGE(STATUS "Could not find Wine header files" )
|
||||
ENDIF()
|
||||
ENDIF()
|
||||
ELSE()
|
||||
SET(OLD_REQUIRED_FLAGS "${CMAKE_REQUIRED_FLAGS}")
|
||||
# Yes GCC, really don't accept visibility modes you don't support
|
||||
SET(CMAKE_REQUIRED_FLAGS "${OLD_REQUIRED_FLAGS} -Wattributes -Werror")
|
||||
|
||||
CHECK_C_SOURCE_COMPILES("int foo() __attribute__((visibility(\"protected\")));
|
||||
int main() {return 0;}" HAVE_GCC_PROTECTED_VISIBILITY)
|
||||
IF(HAVE_GCC_PROTECTED_VISIBILITY)
|
||||
SET(EXPORT_DECL "__attribute__((visibility(\"protected\")))")
|
||||
ELSE()
|
||||
ADD_DEFINITIONS(-g -O2 -funroll-loops)
|
||||
CHECK_C_SOURCE_COMPILES("int foo() __attribute__((visibility(\"default\")));
|
||||
int main() {return 0;}" HAVE_GCC_DEFAULT_VISIBILITY)
|
||||
IF(HAVE_GCC_DEFAULT_VISIBILITY)
|
||||
SET(EXPORT_DECL "__attribute__((visibility(\"default\")))")
|
||||
ENDIF()
|
||||
ENDIF()
|
||||
|
||||
# The mixer doesn't like GCC's strict aliasing optimizations. Make sure
|
||||
# it's turned off
|
||||
CHECK_C_COMPILER_FLAG(-fstrict-aliasing HAVE_STRICT_ALIASING)
|
||||
IF("${HAVE_STRICT_ALIASING}")
|
||||
ADD_DEFINITIONS(-fno-strict-aliasing)
|
||||
ENDIF()
|
||||
|
||||
# Set visibility options if available
|
||||
IF(NOT "${WIN32}")
|
||||
CHECK_C_SOURCE_COMPILES("int foo() __attribute__((destructor));
|
||||
int main() {return 0;}" HAVE_GCC_DESTRUCTOR)
|
||||
|
||||
CHECK_C_COMPILER_FLAG(-fvisibility=hidden HAVE_VISIBILITY_SWITCH)
|
||||
IF("${HAVE_VISIBILITY_SWITCH}")
|
||||
CHECK_C_SOURCE_COMPILES("int foo() __attribute__((visibility(\"default\")));
|
||||
int main() {return 0;}" HAVE_GCC_VISIBILITY)
|
||||
IF("${HAVE_GCC_VISIBILITY}")
|
||||
ADD_DEFINITIONS(-fvisibility=hidden -DHAVE_GCC_VISIBILITY)
|
||||
IF(HAVE_GCC_PROTECTED_VISIBILITY OR HAVE_GCC_DEFAULT_VISIBILITY)
|
||||
CHECK_C_COMPILER_FLAG(-fvisibility=internal HAVE_VISIBILITY_INTERNAL_SWITCH)
|
||||
IF(HAVE_VISIBILITY_INTERNAL_SWITCH)
|
||||
ADD_DEFINITIONS(-fvisibility=internal)
|
||||
ELSE()
|
||||
CHECK_C_COMPILER_FLAG(-fvisibility=hidden HAVE_VISIBILITY_HIDDEN_SWITCH)
|
||||
IF(HAVE_VISIBILITY_HIDDEN_SWITCH)
|
||||
ADD_DEFINITIONS(-fvisibility=hidden)
|
||||
ENDIF()
|
||||
ENDIF()
|
||||
ENDIF()
|
||||
|
||||
CHECK_C_SOURCE_COMPILES("int foo __attribute__((aligned(16)));
|
||||
int main() {return 0;}" HAVE_ATTRIBUTE_ALIGNED)
|
||||
IF(HAVE_ATTRIBUTE_ALIGNED)
|
||||
SET(ALIGN_DECL "__attribute__((aligned(x)))")
|
||||
ENDIF()
|
||||
|
||||
SET(CMAKE_REQUIRED_FLAGS "${OLD_REQUIRED_FLAGS}")
|
||||
ENDIF()
|
||||
|
||||
IF(DEBUG)
|
||||
ADD_DEFINITIONS(-D_DEBUG)
|
||||
ELSEIF(NODEBUG)
|
||||
ADD_DEFINITIONS(-DNDEBUG)
|
||||
SET(SSE_SWITCH "")
|
||||
CHECK_C_COMPILER_FLAG(-msse HAVE_MSSE_SWITCH)
|
||||
IF(HAVE_MSSE_SWITCH)
|
||||
SET(SSE_SWITCH "-msse")
|
||||
ENDIF()
|
||||
|
||||
CHECK_LIBRARY_EXISTS(m sqrtf "" HAVE_SQRTF)
|
||||
IF("${HAVE_SQRTF}")
|
||||
CHECK_C_SOURCE_COMPILES("int foo(const char *str, ...) __attribute__((format(printf, 1, 2)));
|
||||
int main() {return 0;}" HAVE_GCC_FORMAT)
|
||||
|
||||
CHECK_INCLUDE_FILE(malloc.h HAVE_MALLOC_H)
|
||||
CHECK_INCLUDE_FILE(cpuid.h HAVE_CPUID_H)
|
||||
CHECK_INCLUDE_FILE(fenv.h HAVE_FENV_H)
|
||||
CHECK_INCLUDE_FILE(float.h HAVE_FLOAT_H)
|
||||
CHECK_INCLUDE_FILE(ieeefp.h HAVE_IEEEFP_H)
|
||||
CHECK_INCLUDE_FILE(guiddef.h HAVE_GUIDDEF_H)
|
||||
IF(NOT HAVE_GUIDDEF_H)
|
||||
CHECK_INCLUDE_FILE(initguid.h HAVE_INITGUID_H)
|
||||
ENDIF()
|
||||
|
||||
# Some systems need libm for some of the following math functions to work
|
||||
CHECK_LIBRARY_EXISTS(m pow "" HAVE_LIBM)
|
||||
IF(HAVE_LIBM)
|
||||
SET(EXTRA_LIBS m ${EXTRA_LIBS})
|
||||
SET(CMAKE_REQUIRED_LIBRARIES ${CMAKE_REQUIRED_LIBRARIES} m)
|
||||
ENDIF()
|
||||
CHECK_FUNCTION_EXISTS(strtof HAVE_STRTOF)
|
||||
|
||||
|
||||
CHECK_SYMBOL_EXISTS(aligned_alloc stdlib.h HAVE_ALIGNED_ALLOC)
|
||||
CHECK_SYMBOL_EXISTS(posix_memalign stdlib.h HAVE_POSIX_MEMALIGN)
|
||||
CHECK_SYMBOL_EXISTS(_aligned_malloc malloc.h HAVE__ALIGNED_MALLOC)
|
||||
CHECK_SYMBOL_EXISTS(lrintf math.h HAVE_LRINTF)
|
||||
|
||||
IF(HAVE_FENV_H)
|
||||
CHECK_SYMBOL_EXISTS(fesetround fenv.h HAVE_FESETROUND)
|
||||
ENDIF()
|
||||
IF(HAVE_FLOAT_H)
|
||||
CHECK_SYMBOL_EXISTS(_controlfp float.h HAVE__CONTROLFP)
|
||||
CHECK_SYMBOL_EXISTS(__control87_2 float.h HAVE___CONTROL87_2)
|
||||
ENDIF()
|
||||
|
||||
CHECK_FUNCTION_EXISTS(strtof HAVE_STRTOF)
|
||||
CHECK_FUNCTION_EXISTS(stat HAVE_STAT)
|
||||
CHECK_FUNCTION_EXISTS(strcasecmp HAVE_STRCASECMP)
|
||||
IF(NOT "${HAVE_STRCASECMP}")
|
||||
IF(NOT HAVE_STRCASECMP)
|
||||
CHECK_FUNCTION_EXISTS(_stricmp HAVE__STRICMP)
|
||||
IF(NOT "${HAVE__STRICMP}")
|
||||
IF(NOT HAVE__STRICMP)
|
||||
MESSAGE(FATAL_ERROR "No case-insensitive compare function found, please report!")
|
||||
ENDIF()
|
||||
|
||||
ADD_DEFINITIONS(-Dstrcasecmp=_stricmp)
|
||||
ENDIF()
|
||||
|
||||
CHECK_FUNCTION_EXISTS(strncasecmp HAVE_STRNCASECMP)
|
||||
IF(NOT HAVE_STRNCASECMP)
|
||||
CHECK_FUNCTION_EXISTS(_strnicmp HAVE__STRNICMP)
|
||||
IF(NOT HAVE__STRNICMP)
|
||||
MESSAGE(FATAL_ERROR "No case-insensitive size-limitted compare function found, please report!")
|
||||
ENDIF()
|
||||
|
||||
ADD_DEFINITIONS(-Dstrncasecmp=_strnicmp)
|
||||
ENDIF()
|
||||
|
||||
CHECK_FUNCTION_EXISTS(snprintf HAVE_SNPRINTF)
|
||||
IF(NOT "${HAVE_SNPRINTF}")
|
||||
IF(NOT HAVE_SNPRINTF)
|
||||
CHECK_FUNCTION_EXISTS(_snprintf HAVE__SNPRINTF)
|
||||
IF(NOT "${HAVE__SNPRINTF}")
|
||||
IF(NOT HAVE__SNPRINTF)
|
||||
MESSAGE(FATAL_ERROR "No snprintf function found, please report!")
|
||||
ENDIF()
|
||||
|
||||
ADD_DEFINITIONS(-Dsnprintf=_snprintf)
|
||||
ENDIF()
|
||||
|
||||
CHECK_FUNCTION_EXISTS(vsnprintf HAVE_VSNPRINTF)
|
||||
IF(NOT HAVE_VSNPRINTF)
|
||||
CHECK_FUNCTION_EXISTS(_vsnprintf HAVE__VSNPRINTF)
|
||||
IF(NOT HAVE__VSNPRINTF)
|
||||
MESSAGE(FATAL_ERROR "No vsnprintf function found, please report!")
|
||||
ENDIF()
|
||||
|
||||
ADD_DEFINITIONS(-Dvsnprintf=_vsnprintf)
|
||||
ENDIF()
|
||||
|
||||
CHECK_SYMBOL_EXISTS(isfinite math.h HAVE_ISFINITE)
|
||||
IF(NOT HAVE_ISFINITE)
|
||||
CHECK_FUNCTION_EXISTS(finite HAVE_FINITE)
|
||||
IF(NOT HAVE_FINITE)
|
||||
CHECK_FUNCTION_EXISTS(_finite HAVE__FINITE)
|
||||
IF(NOT HAVE__FINITE)
|
||||
MESSAGE(FATAL_ERROR "No isfinite function found, please report!")
|
||||
ENDIF()
|
||||
ADD_DEFINITIONS(-Disfinite=_finite)
|
||||
ELSE()
|
||||
ADD_DEFINITIONS(-Disfinite=finite)
|
||||
ENDIF()
|
||||
ENDIF()
|
||||
|
||||
CHECK_SYMBOL_EXISTS(isnan math.h HAVE_ISNAN)
|
||||
IF(NOT HAVE_ISNAN)
|
||||
CHECK_FUNCTION_EXISTS(_isnan HAVE__ISNAN)
|
||||
IF(NOT HAVE__ISNAN)
|
||||
MESSAGE(FATAL_ERROR "No isnan function found, please report!")
|
||||
ENDIF()
|
||||
|
||||
ADD_DEFINITIONS(-Disnan=_isnan)
|
||||
ENDIF()
|
||||
|
||||
|
||||
# Check for the dlopen API (for dynamicly loading backend libs)
|
||||
IF(DLOPEN)
|
||||
CHECK_INCLUDE_FILE(dlfcn.h HAVE_DLFCN_H)
|
||||
IF("${HAVE_DLFCN_H}")
|
||||
IF(HAVE_DLFCN_H)
|
||||
CHECK_LIBRARY_EXISTS(dl dlopen "" HAVE_LIBDL)
|
||||
IF("${HAVE_LIBDL}")
|
||||
IF(HAVE_LIBDL)
|
||||
SET(EXTRA_LIBS dl ${EXTRA_LIBS})
|
||||
ENDIF()
|
||||
ENDIF()
|
||||
ENDIF()
|
||||
|
||||
# Check if we have Windows headers
|
||||
CHECK_INCLUDE_FILE(windows.h HAVE_WINDOWS_H)
|
||||
IF(NOT "${HAVE_WINDOWS_H}")
|
||||
# We need pthreads outside of Windows
|
||||
CHECK_INCLUDE_FILE(pthread.h HAVE_PTHREAD_H)
|
||||
IF(NOT "${HAVE_PTHREAD_H}")
|
||||
MESSAGE(FATAL_ERROR "PThreads is required for non-Windows builds!")
|
||||
CHECK_INCLUDE_FILE(windows.h HAVE_WINDOWS_H -D_WIN32_WINNT=0x0501)
|
||||
IF(NOT HAVE_WINDOWS_H)
|
||||
CHECK_FUNCTION_EXISTS(gettimeofday HAVE_GETTIMEOFDAY)
|
||||
IF(NOT HAVE_GETTIMEOFDAY)
|
||||
MESSAGE(FATAL_ERROR "No timing function found!")
|
||||
ENDIF()
|
||||
|
||||
# _GNU_SOURCE is needed on some systems for extra attributes, and
|
||||
# _REENTRANT is needed for libc thread-safety
|
||||
ADD_DEFINITIONS(-D_GNU_SOURCE=1 -D_REENTRANT)
|
||||
CHECK_FUNCTION_EXISTS(nanosleep HAVE_NANOSLEEP)
|
||||
IF(NOT HAVE_NANOSLEEP)
|
||||
MESSAGE(FATAL_ERROR "No sleep function found!")
|
||||
ENDIF()
|
||||
|
||||
CHECK_C_COMPILER_FLAG(-pthread HAVE_PTHREAD)
|
||||
IF(HAVE_PTHREAD)
|
||||
ADD_DEFINITIONS(-pthread)
|
||||
SET(EXTRA_LIBS ${EXTRA_LIBS} -pthread)
|
||||
ENDIF()
|
||||
|
||||
# We need pthreads outside of Windows
|
||||
CHECK_INCLUDE_FILE(pthread.h HAVE_PTHREAD_H)
|
||||
IF(NOT HAVE_PTHREAD_H)
|
||||
MESSAGE(FATAL_ERROR "PThreads is required for non-Windows builds!")
|
||||
ENDIF()
|
||||
# Some systems need pthread_np.h to get recursive mutexes
|
||||
CHECK_INCLUDE_FILES("pthread.h;pthread_np.h" HAVE_PTHREAD_NP_H)
|
||||
|
||||
# _GNU_SOURCE is needed on some systems for extra attributes
|
||||
ADD_DEFINITIONS(-D_GNU_SOURCE=1)
|
||||
CHECK_LIBRARY_EXISTS(pthread pthread_create "" HAVE_LIBPTHREAD)
|
||||
IF("${HAVE_LIBPTHREAD}")
|
||||
IF(HAVE_LIBPTHREAD)
|
||||
SET(EXTRA_LIBS pthread ${EXTRA_LIBS})
|
||||
ENDIF()
|
||||
|
||||
CHECK_LIBRARY_EXISTS(pthread pthread_setschedparam "" HAVE_PTHREAD_SETSCHEDPARAM)
|
||||
|
||||
CHECK_LIBRARY_EXISTS(rt clock_gettime "" HAVE_LIBRT)
|
||||
IF(HAVE_LIBRT)
|
||||
SET(EXTRA_LIBS rt ${EXTRA_LIBS})
|
||||
ENDIF()
|
||||
ENDIF()
|
||||
|
||||
# Check for a 64-bit type
|
||||
CHECK_INCLUDE_FILE(stdint.h HAVE_STDINT_H)
|
||||
IF(NOT "${HAVE_STDINT_H}")
|
||||
IF("${HAVE_WINDOWS_H}")
|
||||
CHECK_C_SOURCE_COMPILES("\#include <windows.h>
|
||||
IF(NOT HAVE_STDINT_H)
|
||||
IF(HAVE_WINDOWS_H)
|
||||
CHECK_C_SOURCE_COMPILES("\#define _WIN32_WINNT 0x0501
|
||||
\#include <windows.h>
|
||||
__int64 foo;
|
||||
int main() {return 0;}" HAVE___INT64)
|
||||
ENDIF()
|
||||
IF(NOT "${HAVE___INT64}")
|
||||
IF(NOT "${SIZEOF_LONG}" MATCHES "8")
|
||||
IF(NOT "${SIZEOF_LONG_LONG}" MATCHES "8")
|
||||
IF(NOT HAVE___INT64)
|
||||
IF(NOT SIZEOF_LONG MATCHES "8")
|
||||
IF(NOT SIZEOF_LONG_LONG MATCHES "8")
|
||||
MESSAGE(FATAL_ERROR "No 64-bit types found, please report!")
|
||||
ENDIF()
|
||||
ENDIF()
|
||||
ENDIF()
|
||||
ENDIF()
|
||||
|
||||
# Windows needs winmm for timeGetTime, even if the backend is disabled
|
||||
CHECK_SHARED_FUNCTION_EXISTS(timeGetTime "windows.h;mmsystem.h" winmm "" HAVE_LIBWINMM)
|
||||
IF(HAVE_LIBWINMM)
|
||||
SET(EXTRA_LIBS winmm ${EXTRA_LIBS})
|
||||
SET(PKG_CONFIG_LIBS ${PKG_CONFIG_LIBS} -lwinmm)
|
||||
ENDIF()
|
||||
|
||||
SET(OPENAL_OBJS OpenAL32/alBuffer.c
|
||||
|
||||
SET(OPENAL_OBJS OpenAL32/alAuxEffectSlot.c
|
||||
OpenAL32/alBuffer.c
|
||||
OpenAL32/alEffect.c
|
||||
OpenAL32/alError.c
|
||||
OpenAL32/alExtension.c
|
||||
OpenAL32/alFilter.c
|
||||
OpenAL32/alListener.c
|
||||
OpenAL32/alSource.c
|
||||
OpenAL32/alState.c
|
||||
OpenAL32/alThunk.c
|
||||
OpenAL32/OpenAL32.c
|
||||
)
|
||||
SET(ALC_OBJS Alc/ALc.c
|
||||
Alc/ALu.c
|
||||
Alc/alcConfig.c
|
||||
Alc/alcDedicated.c
|
||||
Alc/alcEcho.c
|
||||
Alc/alcModulator.c
|
||||
Alc/alcReverb.c
|
||||
Alc/alcRing.c
|
||||
Alc/alcThread.c
|
||||
Alc/bs2b.c
|
||||
Alc/helpers.c
|
||||
Alc/panning.c
|
||||
Alc/hrtf.c
|
||||
Alc/mixer.c
|
||||
Alc/mixer_c.c
|
||||
)
|
||||
|
||||
|
||||
SET(CPU_EXTS "Default")
|
||||
SET(HAVE_SSE 0)
|
||||
SET(HAVE_NEON 0)
|
||||
|
||||
# Check for SSE support
|
||||
IF(SSE AND ALIGN_DECL)
|
||||
CHECK_INCLUDE_FILE(xmmintrin.h HAVE_XMMINTRIN_H "${SSE_SWITCH}")
|
||||
IF(HAVE_XMMINTRIN_H)
|
||||
SET(HAVE_SSE 1)
|
||||
SET(ALC_OBJS ${ALC_OBJS} Alc/mixer_sse.c)
|
||||
IF(SSE_SWITCH)
|
||||
SET_SOURCE_FILES_PROPERTIES(Alc/mixer_sse.c PROPERTIES
|
||||
COMPILE_FLAGS "${SSE_SWITCH}")
|
||||
ENDIF()
|
||||
SET(CPU_EXTS "${CPU_EXTS}, SSE")
|
||||
ENDIF()
|
||||
ENDIF()
|
||||
IF(REQUIRE_SSE AND NOT HAVE_SSE)
|
||||
MESSAGE(FATAL_ERROR "Failed to enabled required SSE CPU extensions")
|
||||
ENDIF()
|
||||
|
||||
# Check for ARM Neon support
|
||||
IF(NEON)
|
||||
CHECK_INCLUDE_FILE(arm_neon.h HAVE_ARM_NEON_H)
|
||||
IF(HAVE_ARM_NEON_H)
|
||||
SET(HAVE_NEON 1)
|
||||
SET(ALC_OBJS ${ALC_OBJS} Alc/mixer_neon.c)
|
||||
SET(CPU_EXTS "${CPU_EXTS}, Neon")
|
||||
ENDIF()
|
||||
ENDIF()
|
||||
IF(REQUIRE_NEON AND NOT HAVE_NEON)
|
||||
MESSAGE(FATAL_ERROR "Failed to enabled required ARM Neon CPU extensions")
|
||||
ENDIF()
|
||||
|
||||
|
||||
SET(ALC_OBJS ${ALC_OBJS}
|
||||
# Default backends, always available
|
||||
Alc/backends/loopback.c
|
||||
Alc/backends/null.c
|
||||
)
|
||||
|
||||
SET(BACKENDS "")
|
||||
SET(HAVE_ALSA 0)
|
||||
SET(HAVE_OSS 0)
|
||||
SET(HAVE_SOLARIS 0)
|
||||
SET(HAVE_SNDIO 0)
|
||||
SET(HAVE_DSOUND 0)
|
||||
SET(HAVE_MMDEVAPI 0)
|
||||
SET(HAVE_WINMM 0)
|
||||
SET(HAVE_PORTAUDIO 0)
|
||||
SET(HAVE_PULSEAUDIO 0)
|
||||
SET(HAVE_COREAUDIO 0)
|
||||
SET(HAVE_OPENSL 0)
|
||||
SET(HAVE_WAVE 0)
|
||||
|
||||
# Check ALSA backend
|
||||
IF(ALSA)
|
||||
CHECK_INCLUDE_FILE(alsa/asoundlib.h HAVE_ALSA_ASOUNDLIB_H)
|
||||
IF("${HAVE_ALSA_ASOUNDLIB_H}")
|
||||
CHECK_LIBRARY_EXISTS(asound snd_pcm_open "" HAVE_LIBASOUND)
|
||||
IF("${HAVE_DLFCN_H}" OR "${HAVE_LIBASOUND}")
|
||||
IF(HAVE_ALSA_ASOUNDLIB_H)
|
||||
CHECK_SHARED_FUNCTION_EXISTS(snd_pcm_open "alsa/asoundlib.h" asound "" HAVE_LIBASOUND)
|
||||
IF(HAVE_LIBASOUND OR HAVE_DLFCN_H OR WIN32)
|
||||
SET(HAVE_ALSA 1)
|
||||
SET(ALC_OBJS ${ALC_OBJS} Alc/alsa.c)
|
||||
IF("${HAVE_DLFCN_H}")
|
||||
SET(BACKENDS ${BACKENDS} ALSA)
|
||||
SET(ALC_OBJS ${ALC_OBJS} Alc/backends/alsa.c)
|
||||
IF(HAVE_DLFCN_H OR WIN32)
|
||||
SET(BACKENDS "${BACKENDS} ALSA,")
|
||||
ELSE()
|
||||
SET(BACKENDS ${BACKENDS} ALSA\(linked\))
|
||||
SET(BACKENDS "${BACKENDS} ALSA \(linked\),")
|
||||
SET(EXTRA_LIBS asound ${EXTRA_LIBS})
|
||||
ENDIF()
|
||||
ENDIF()
|
||||
ENDIF()
|
||||
ENDIF()
|
||||
IF(REQUIRE_ALSA AND NOT HAVE_ALSA)
|
||||
MESSAGE(FATAL_ERROR "Failed to enabled required ALSA backend")
|
||||
ENDIF()
|
||||
|
||||
# Check OSS backend
|
||||
IF(OSS)
|
||||
CHECK_INCLUDE_FILE(sys/soundcard.h HAVE_SYS_SOUNDCARD_H)
|
||||
IF("${HAVE_SYS_SOUNDCARD_H}")
|
||||
IF(HAVE_SYS_SOUNDCARD_H)
|
||||
SET(HAVE_OSS 1)
|
||||
SET(ALC_OBJS ${ALC_OBJS} Alc/oss.c)
|
||||
SET(BACKENDS ${BACKENDS} OSS)
|
||||
SET(ALC_OBJS ${ALC_OBJS} Alc/backends/oss.c)
|
||||
SET(BACKENDS "${BACKENDS} OSS,")
|
||||
ENDIF()
|
||||
ENDIF()
|
||||
IF(REQUIRE_OSS AND NOT HAVE_OSS)
|
||||
MESSAGE(FATAL_ERROR "Failed to enabled required OSS backend")
|
||||
ENDIF()
|
||||
|
||||
# Check Solaris backend
|
||||
IF(SOLARIS)
|
||||
CHECK_INCLUDE_FILE(sys/audioio.h HAVE_SYS_AUDIOIO_H)
|
||||
IF(HAVE_SYS_AUDIOIO_H)
|
||||
SET(HAVE_SOLARIS 1)
|
||||
SET(ALC_OBJS ${ALC_OBJS} Alc/backends/solaris.c)
|
||||
SET(BACKENDS "${BACKENDS} Solaris,")
|
||||
ENDIF()
|
||||
ENDIF()
|
||||
IF(REQUIRE_SOLARIS AND NOT HAVE_SOLARIS)
|
||||
MESSAGE(FATAL_ERROR "Failed to enabled required Solaris backend")
|
||||
ENDIF()
|
||||
|
||||
# Check SndIO backend
|
||||
IF(SNDIO)
|
||||
CHECK_INCLUDE_FILE(sndio.h HAVE_SNDIO_H)
|
||||
IF(HAVE_SNDIO_H)
|
||||
CHECK_SHARED_FUNCTION_EXISTS(sio_open "sndio.h" sndio "" HAVE_LIBSNDIO)
|
||||
IF(HAVE_LIBSNDIO)
|
||||
SET(HAVE_SNDIO 1)
|
||||
SET(ALC_OBJS ${ALC_OBJS} Alc/backends/sndio.c)
|
||||
SET(BACKENDS "${BACKENDS} SndIO \(linked\),")
|
||||
SET(EXTRA_LIBS sndio ${EXTRA_LIBS})
|
||||
ENDIF()
|
||||
ENDIF()
|
||||
ENDIF()
|
||||
IF(REQUIRE_SNDIO AND NOT HAVE_SNDIO)
|
||||
MESSAGE(FATAL_ERROR "Failed to enabled required SndIO backend")
|
||||
ENDIF()
|
||||
|
||||
# Check for MMDevApi backend
|
||||
IF(HAVE_WINDOWS_H)
|
||||
IF(MMDEVAPI)
|
||||
CHECK_INCLUDE_FILE(mmdeviceapi.h HAVE_MMDEVICEAPI_H)
|
||||
IF(HAVE_MMDEVICEAPI_H)
|
||||
SET(HAVE_MMDEVAPI 1)
|
||||
SET(ALC_OBJS ${ALC_OBJS} Alc/backends/mmdevapi.c)
|
||||
|
||||
SET(BACKENDS "${BACKENDS} MMDevApi,")
|
||||
ENDIF()
|
||||
ENDIF()
|
||||
ENDIF()
|
||||
IF(REQUIRE_MMDEVAPI AND NOT HAVE_MMDEVAPI)
|
||||
MESSAGE(FATAL_ERROR "Failed to enabled required MMDevApi backend")
|
||||
ENDIF()
|
||||
|
||||
# Check DSound/MMSystem backend
|
||||
IF("${HAVE_WINDOWS_H}")
|
||||
SET(CMAKE_REQUIRED_LIBRARIES ole32)
|
||||
CHECK_C_SOURCE_COMPILES("int main() {return 0;}" HAVE_LIBOLE32)
|
||||
SET(CMAKE_REQUIRED_LIBRARIES "")
|
||||
# CHECK_LIBRARY_EXISTS(ole32 CoInitialize "" HAVE_LIBOLE32)
|
||||
IF("${HAVE_LIBOLE32}")
|
||||
SET(EXTRA_LIBS ole32 ${EXTRA_LIBS})
|
||||
ENDIF()
|
||||
|
||||
IF(DSOUND)
|
||||
CHECK_INCLUDE_FILE(dsound.h HAVE_DSOUND_H)
|
||||
IF("${HAVE_DSOUND_H}")
|
||||
IF(DSOUND)
|
||||
CHECK_INCLUDE_FILE(dsound.h HAVE_DSOUND_H)
|
||||
IF(HAVE_DSOUND_H)
|
||||
CHECK_SHARED_FUNCTION_EXISTS(DirectSoundCreate "dsound.h" dsound "" HAVE_LIBDSOUND)
|
||||
IF(HAVE_LIBDSOUND OR HAVE_DLFCN_H OR WIN32)
|
||||
SET(HAVE_DSOUND 1)
|
||||
SET(ALC_OBJS ${ALC_OBJS} Alc/dsound.c)
|
||||
SET(BACKENDS ${BACKENDS} DirectSound)
|
||||
SET(ALC_OBJS ${ALC_OBJS} Alc/backends/dsound.c)
|
||||
|
||||
CHECK_LIBRARY_EXISTS(dxguid IID_IDirectSound "" HAVE_LIBDXGUID)
|
||||
IF("${HAVE_LIBDXGUID}")
|
||||
SET(EXTRA_LIBS dxguid ${EXTRA_LIBS})
|
||||
ENDIF()
|
||||
ENDIF()
|
||||
ENDIF()
|
||||
IF(WINMM)
|
||||
CHECK_INCLUDE_FILES("windows.h;mmsystem.h" HAVE_MMSYSTEM_H)
|
||||
IF("${HAVE_MMSYSTEM_H}")
|
||||
SET(HAVE_WINMM 1)
|
||||
SET(ALC_OBJS ${ALC_OBJS} Alc/winmm.c)
|
||||
SET(BACKENDS ${BACKENDS} WinMM)
|
||||
|
||||
SET(CMAKE_REQUIRED_LIBRARIES winmm)
|
||||
CHECK_C_SOURCE_COMPILES("int main() {return 0;}" HAVE_LIBWINMM)
|
||||
SET(CMAKE_REQUIRED_LIBRARIES "")
|
||||
# CHECK_LIBRARY_EXISTS(winmm waveInOpen "" HAVE_LIBWINMM)
|
||||
IF("${HAVE_LIBWINMM}")
|
||||
SET(EXTRA_LIBS winmm ${EXTRA_LIBS})
|
||||
IF(HAVE_DLFCN_H OR WIN32)
|
||||
SET(BACKENDS "${BACKENDS} DirectSound,")
|
||||
ELSE()
|
||||
SET(BACKENDS "${BACKENDS} DirectSound \(linked\),")
|
||||
SET(EXTRA_LIBS dsound ${EXTRA_LIBS})
|
||||
ENDIF()
|
||||
ENDIF()
|
||||
ENDIF()
|
||||
ENDIF()
|
||||
IF(REQUIRE_DSOUND AND NOT HAVE_DSOUND)
|
||||
MESSAGE(FATAL_ERROR "Failed to enabled required DSound backend")
|
||||
ENDIF()
|
||||
|
||||
IF(HAVE_WINDOWS_H)
|
||||
IF(WINMM)
|
||||
CHECK_INCLUDE_FILES("windows.h;mmsystem.h" HAVE_MMSYSTEM_H -D_WIN32_WINNT=0x0501)
|
||||
IF(HAVE_MMSYSTEM_H AND HAVE_LIBWINMM)
|
||||
SET(HAVE_WINMM 1)
|
||||
SET(ALC_OBJS ${ALC_OBJS} Alc/backends/winmm.c)
|
||||
SET(BACKENDS "${BACKENDS} WinMM,")
|
||||
ENDIF()
|
||||
ENDIF()
|
||||
ENDIF()
|
||||
IF(REQUIRE_WINMM AND NOT HAVE_WINMM)
|
||||
MESSAGE(FATAL_ERROR "Failed to enabled required WinMM backend")
|
||||
ENDIF()
|
||||
|
||||
# Check PortAudio backend
|
||||
IF(PORTAUDIO)
|
||||
CHECK_INCLUDE_FILE(portaudio.h HAVE_PORTAUDIO_H)
|
||||
IF(HAVE_PORTAUDIO_H)
|
||||
CHECK_SHARED_FUNCTION_EXISTS(Pa_Initialize "portaudio.h" portaudio "" HAVE_LIBPORTAUDIO)
|
||||
IF(HAVE_LIBPORTAUDIO OR HAVE_DLFCN_H OR WIN32)
|
||||
SET(HAVE_PORTAUDIO 1)
|
||||
SET(ALC_OBJS ${ALC_OBJS} Alc/backends/portaudio.c)
|
||||
IF(HAVE_DLFCN_H OR WIN32)
|
||||
SET(BACKENDS "${BACKENDS} PortAudio,")
|
||||
ELSE()
|
||||
SET(BACKENDS "${BACKENDS} PortAudio \(linked\),")
|
||||
SET(EXTRA_LIBS portaudio ${EXTRA_LIBS})
|
||||
ENDIF()
|
||||
ENDIF()
|
||||
ENDIF()
|
||||
ENDIF()
|
||||
IF(REQUIRE_PORTAUDIO AND NOT HAVE_PORTAUDIO)
|
||||
MESSAGE(FATAL_ERROR "Failed to enabled required PortAudio backend")
|
||||
ENDIF()
|
||||
|
||||
# Check PulseAudio backend
|
||||
IF(PULSEAUDIO)
|
||||
CHECK_INCLUDE_FILE(pulse/pulseaudio.h HAVE_PULSE_PULSEAUDIO_H)
|
||||
IF(HAVE_PULSE_PULSEAUDIO_H)
|
||||
CHECK_SHARED_FUNCTION_EXISTS(pa_context_new "pulse/pulseaudio.h" pulse "" HAVE_LIBPULSE)
|
||||
IF(HAVE_LIBPULSE OR HAVE_DLFCN_H OR WIN32)
|
||||
SET(HAVE_PULSEAUDIO 1)
|
||||
SET(ALC_OBJS ${ALC_OBJS} Alc/backends/pulseaudio.c)
|
||||
IF(HAVE_DLFCN_H OR WIN32)
|
||||
SET(BACKENDS "${BACKENDS} PulseAudio,")
|
||||
ELSE()
|
||||
SET(BACKENDS "${BACKENDS} PulseAudio \(linked\),")
|
||||
SET(EXTRA_LIBS pulse ${EXTRA_LIBS})
|
||||
ENDIF()
|
||||
ENDIF()
|
||||
ENDIF()
|
||||
ENDIF()
|
||||
IF(REQUIRE_PULSEAUDIO AND NOT HAVE_PULSEAUDIO)
|
||||
MESSAGE(FATAL_ERROR "Failed to enabled required PulseAudio backend")
|
||||
ENDIF()
|
||||
|
||||
# Check CoreAudio backend
|
||||
IF(COREAUDIO)
|
||||
CHECK_INCLUDE_FILE(/System/Library/Frameworks/CoreAudio.framework/Headers/CoreAudio.h HAVE_COREAUDIO_FRAMEWORK)
|
||||
IF(HAVE_COREAUDIO_FRAMEWORK)
|
||||
SET(HAVE_COREAUDIO 1)
|
||||
SET(ALC_OBJS ${ALC_OBJS} Alc/backends/coreaudio.c)
|
||||
SET(BACKENDS "${BACKENDS} CoreAudio,")
|
||||
SET(EXTRA_LIBS /System/Library/Frameworks/CoreAudio.framework ${EXTRA_LIBS})
|
||||
SET(EXTRA_LIBS /System/Library/Frameworks/AudioUnit.framework ${EXTRA_LIBS})
|
||||
SET(EXTRA_LIBS /System/Library/Frameworks/ApplicationServices.framework ${EXTRA_LIBS})
|
||||
|
||||
# Some versions of OSX may need the AudioToolbox framework. Add it if
|
||||
# it's found.
|
||||
FIND_LIBRARY(AUDIOTOOLBOX_LIBRARY
|
||||
NAMES AudioToolbox
|
||||
PATHS ~/Library/Frameworks
|
||||
/Library/Frameworks
|
||||
/System/Library/Frameworks
|
||||
)
|
||||
IF(AUDIOTOOLBOX_LIBRARY)
|
||||
SET(EXTRA_LIBS ${AUDIOTOOLBOX_LIBRARY} ${EXTRA_LIBS})
|
||||
ENDIF()
|
||||
ENDIF()
|
||||
ENDIF()
|
||||
IF(REQUIRE_COREAUDIO AND NOT HAVE_COREAUDIO)
|
||||
MESSAGE(FATAL_ERROR "Failed to enabled required CoreAudio backend")
|
||||
ENDIF()
|
||||
|
||||
# Check for OpenSL (Android) backend
|
||||
IF(OPENSL)
|
||||
CHECK_INCLUDE_FILES("SLES/OpenSLES.h;SLES/OpenSLES_Android.h" HAVE_SLES_OPENSLES_ANDROID_H)
|
||||
IF(HAVE_SLES_OPENSLES_ANDROID_H)
|
||||
CHECK_SHARED_FUNCTION_EXISTS(slCreateEngine "SLES/OpenSLES.h" OpenSLES "" HAVE_LIBOPENSLES)
|
||||
IF(HAVE_LIBOPENSLES)
|
||||
SET(HAVE_OPENSL 1)
|
||||
SET(ALC_OBJS ${ALC_OBJS} Alc/backends/opensl.c)
|
||||
SET(BACKENDS "${BACKENDS} OpenSL,")
|
||||
SET(EXTRA_LIBS OpenSLES ${EXTRA_LIBS})
|
||||
ENDIF()
|
||||
ENDIF()
|
||||
ENDIF()
|
||||
IF(REQUIRE_OPENSL AND NOT HAVE_OPENSL)
|
||||
MESSAGE(FATAL_ERROR "Failed to enabled required OpenSL backend")
|
||||
ENDIF()
|
||||
|
||||
# Optionally enable the Wave Writer backend
|
||||
IF(WAVE)
|
||||
SET(HAVE_WAVE 1)
|
||||
SET(ALC_OBJS ${ALC_OBJS} Alc/backends/wave.c)
|
||||
SET(BACKENDS "${BACKENDS} WaveFile,")
|
||||
ENDIF()
|
||||
|
||||
# This is always available
|
||||
SET(BACKENDS "${BACKENDS} Null")
|
||||
|
||||
IF(EXAMPLES)
|
||||
# Might be able to use earlier versions, but these definitely work
|
||||
PKG_CHECK_MODULES(FFMPEG libavcodec>=53.61.100 libavformat>=53.32.100 libavutil>=51.35.100)
|
||||
ENDIF()
|
||||
|
||||
IF(LIBTYPE STREQUAL "STATIC")
|
||||
ADD_DEFINITIONS(-DAL_LIBTYPE_STATIC)
|
||||
SET(PKG_CONFIG_CFLAGS -DAL_LIBTYPE_STATIC ${PKG_CONFIG_CFLAGS})
|
||||
ENDIF()
|
||||
|
||||
# Needed for openal.pc.in
|
||||
SET(prefix ${CMAKE_INSTALL_PREFIX})
|
||||
SET(exec_prefix "\${prefix}")
|
||||
SET(libdir "\${exec_prefix}/lib${LIB_SUFFIX}")
|
||||
SET(bindir "\${exec_prefix}/bin")
|
||||
SET(includedir "\${prefix}/include")
|
||||
SET(PACKAGE_VERSION "${LIB_VERSION}")
|
||||
|
||||
# End configuration
|
||||
CONFIGURE_FILE(
|
||||
"${OpenAL_SOURCE_DIR}/config.h.in"
|
||||
"${OpenAL_BINARY_DIR}/config.h")
|
||||
CONFIGURE_FILE(
|
||||
"${OpenAL_SOURCE_DIR}/openal.pc.in"
|
||||
"${OpenAL_BINARY_DIR}/openal.pc"
|
||||
@ONLY)
|
||||
|
||||
ADD_DEFINITIONS(-DAL_BUILD_LIBRARY)
|
||||
|
||||
# Build a shared library
|
||||
IF("${WIN32}")
|
||||
SET(LIBNAME openal32)
|
||||
ELSE()
|
||||
SET(LIBNAME openal)
|
||||
ENDIF()
|
||||
|
||||
ADD_LIBRARY(${LIBNAME} SHARED ${OPENAL_OBJS} ${ALC_OBJS})
|
||||
SET_TARGET_PROPERTIES(${LIBNAME} PROPERTIES VERSION ${LIB_VERSION}
|
||||
# Build a library
|
||||
ADD_LIBRARY(${LIBNAME} ${LIBTYPE} ${OPENAL_OBJS} ${ALC_OBJS})
|
||||
SET_TARGET_PROPERTIES(${LIBNAME} PROPERTIES DEFINE_SYMBOL AL_BUILD_LIBRARY
|
||||
COMPILE_FLAGS -DAL_ALEXT_PROTOTYPES
|
||||
VERSION ${LIB_VERSION}.0
|
||||
SOVERSION ${LIB_MAJOR_VERSION})
|
||||
IF("${WIN32}")
|
||||
IF(WIN32 AND NOT LIBTYPE STREQUAL "STATIC")
|
||||
SET_TARGET_PROPERTIES(${LIBNAME} PROPERTIES PREFIX "")
|
||||
ENDIF()
|
||||
|
||||
@@ -279,15 +762,91 @@ TARGET_LINK_LIBRARIES(${LIBNAME} ${EXTRA_LIBS})
|
||||
# Add an install target here
|
||||
INSTALL(TARGETS ${LIBNAME}
|
||||
RUNTIME DESTINATION bin
|
||||
LIBRARY DESTINATION lib
|
||||
ARCHIVE DESTINATION lib
|
||||
LIBRARY DESTINATION "lib${LIB_SUFFIX}"
|
||||
ARCHIVE DESTINATION "lib${LIB_SUFFIX}"
|
||||
)
|
||||
INSTALL(FILES include/AL/al.h
|
||||
include/AL/alc.h
|
||||
include/AL/alext.h
|
||||
include/AL/efx.h
|
||||
include/AL/efx-creative.h
|
||||
include/AL/efx-presets.h
|
||||
DESTINATION include/AL
|
||||
)
|
||||
INSTALL(FILES "${OpenAL_BINARY_DIR}/openal.pc"
|
||||
DESTINATION "lib${LIB_SUFFIX}/pkgconfig")
|
||||
|
||||
|
||||
MESSAGE(STATUS "")
|
||||
MESSAGE(STATUS "Building OpenAL with support for the following backends:")
|
||||
MESSAGE(STATUS " ${BACKENDS}")
|
||||
MESSAGE(STATUS "")
|
||||
MESSAGE(STATUS "Building with support for CPU extensions:")
|
||||
MESSAGE(STATUS " ${CPU_EXTS}")
|
||||
MESSAGE(STATUS "")
|
||||
|
||||
IF(WIN32)
|
||||
IF(NOT HAVE_DSOUND)
|
||||
MESSAGE(STATUS "WARNING: Building the Windows version without DirectSound output")
|
||||
MESSAGE(STATUS " This is probably NOT what you want!")
|
||||
MESSAGE(STATUS "")
|
||||
ENDIF()
|
||||
ENDIF()
|
||||
|
||||
# Install alsoft.conf configuration file
|
||||
IF(ALSOFT_CONFIG)
|
||||
INSTALL(FILES alsoftrc.sample
|
||||
DESTINATION share/openal
|
||||
)
|
||||
MESSAGE(STATUS "Installing sample configuration")
|
||||
MESSAGE(STATUS "")
|
||||
ENDIF()
|
||||
|
||||
IF(UTILS)
|
||||
ADD_EXECUTABLE(openal-info utils/openal-info.c)
|
||||
TARGET_LINK_LIBRARIES(openal-info ${LIBNAME})
|
||||
|
||||
ADD_EXECUTABLE(makehrtf utils/makehrtf.c)
|
||||
IF(HAVE_LIBM)
|
||||
TARGET_LINK_LIBRARIES(makehrtf m)
|
||||
ENDIF()
|
||||
|
||||
INSTALL(TARGETS openal-info makehrtf
|
||||
RUNTIME DESTINATION bin
|
||||
LIBRARY DESTINATION "lib${LIB_SUFFIX}"
|
||||
ARCHIVE DESTINATION "lib${LIB_SUFFIX}"
|
||||
)
|
||||
MESSAGE(STATUS "Building utility programs")
|
||||
MESSAGE(STATUS "")
|
||||
ENDIF()
|
||||
|
||||
IF(EXAMPLES)
|
||||
IF(FFMPEG_FOUND)
|
||||
ADD_EXECUTABLE(alstream examples/common/alhelpers.c
|
||||
examples/common/alffmpeg.c
|
||||
examples/alstream.c)
|
||||
TARGET_LINK_LIBRARIES(alstream ${FFMPEG_LIBRARIES} ${LIBNAME})
|
||||
SET_TARGET_PROPERTIES(alstream PROPERTIES COMPILE_FLAGS "${FFMPEG_CFLAGS}")
|
||||
|
||||
ADD_EXECUTABLE(alreverb examples/common/alhelpers.c
|
||||
examples/common/alffmpeg.c
|
||||
examples/alreverb.c)
|
||||
TARGET_LINK_LIBRARIES(alreverb ${FFMPEG_LIBRARIES} ${LIBNAME})
|
||||
SET_TARGET_PROPERTIES(alreverb PROPERTIES COMPILE_FLAGS "${FFMPEG_CFLAGS}")
|
||||
|
||||
ADD_EXECUTABLE(allatency examples/common/alhelpers.c
|
||||
examples/common/alffmpeg.c
|
||||
examples/allatency.c)
|
||||
TARGET_LINK_LIBRARIES(allatency ${FFMPEG_LIBRARIES} ${LIBNAME})
|
||||
SET_TARGET_PROPERTIES(allatency PROPERTIES COMPILE_FLAGS "${FFMPEG_CFLAGS}")
|
||||
|
||||
INSTALL(TARGETS alstream alreverb allatency
|
||||
RUNTIME DESTINATION bin
|
||||
LIBRARY DESTINATION "lib${LIB_SUFFIX}"
|
||||
ARCHIVE DESTINATION "lib${LIB_SUFFIX}"
|
||||
)
|
||||
|
||||
MESSAGE(STATUS "Building ffmpeg example programs")
|
||||
MESSAGE(STATUS "")
|
||||
ENDIF()
|
||||
ENDIF()
|
||||
|
||||
@@ -0,0 +1,61 @@
|
||||
#ifndef _AL_AUXEFFECTSLOT_H_
|
||||
#define _AL_AUXEFFECTSLOT_H_
|
||||
|
||||
#include "alMain.h"
|
||||
#include "alEffect.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
typedef struct ALeffectState {
|
||||
ALvoid (*Destroy)(struct ALeffectState *State);
|
||||
ALboolean (*DeviceUpdate)(struct ALeffectState *State, ALCdevice *Device);
|
||||
ALvoid (*Update)(struct ALeffectState *State, ALCdevice *Device, const struct ALeffectslot *Slot);
|
||||
ALvoid (*Process)(struct ALeffectState *State, ALuint SamplesToDo, const ALfloat *RESTRICT SamplesIn, ALfloat (*RESTRICT SamplesOut)[BUFFERSIZE]);
|
||||
} ALeffectState;
|
||||
|
||||
|
||||
typedef struct ALeffectslot
|
||||
{
|
||||
ALeffect effect;
|
||||
|
||||
volatile ALfloat Gain;
|
||||
volatile ALboolean AuxSendAuto;
|
||||
|
||||
volatile ALenum NeedsUpdate;
|
||||
ALeffectState *EffectState;
|
||||
|
||||
ALIGN(16) ALfloat WetBuffer[1][BUFFERSIZE];
|
||||
|
||||
ALfloat ClickRemoval[1];
|
||||
ALfloat PendingClicks[1];
|
||||
|
||||
RefCount ref;
|
||||
|
||||
/* Self ID */
|
||||
ALuint id;
|
||||
} ALeffectslot;
|
||||
|
||||
|
||||
ALenum InitEffectSlot(ALeffectslot *slot);
|
||||
ALvoid ReleaseALAuxiliaryEffectSlots(ALCcontext *Context);
|
||||
|
||||
ALeffectState *NoneCreate(void);
|
||||
ALeffectState *ReverbCreate(void);
|
||||
ALeffectState *EchoCreate(void);
|
||||
ALeffectState *ModulatorCreate(void);
|
||||
ALeffectState *DedicatedCreate(void);
|
||||
|
||||
#define ALeffectState_Destroy(a) ((a)->Destroy((a)))
|
||||
#define ALeffectState_DeviceUpdate(a,b) ((a)->DeviceUpdate((a),(b)))
|
||||
#define ALeffectState_Update(a,b,c) ((a)->Update((a),(b),(c)))
|
||||
#define ALeffectState_Process(a,b,c,d) ((a)->Process((a),(b),(c),(d)))
|
||||
|
||||
ALenum InitializeEffect(ALCdevice *Device, ALeffectslot *EffectSlot, ALeffect *effect);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
+84
-14
@@ -1,29 +1,99 @@
|
||||
#ifndef _AL_BUFFER_H_
|
||||
#define _AL_BUFFER_H_
|
||||
|
||||
#include "AL/al.h"
|
||||
#include "alMain.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#define UNUSED 0
|
||||
#define PENDING 1
|
||||
#define PROCESSED 2
|
||||
/* User formats */
|
||||
enum UserFmtType {
|
||||
UserFmtByte = AL_BYTE_SOFT,
|
||||
UserFmtUByte = AL_UNSIGNED_BYTE_SOFT,
|
||||
UserFmtShort = AL_SHORT_SOFT,
|
||||
UserFmtUShort = AL_UNSIGNED_SHORT_SOFT,
|
||||
UserFmtInt = AL_INT_SOFT,
|
||||
UserFmtUInt = AL_UNSIGNED_INT_SOFT,
|
||||
UserFmtFloat = AL_FLOAT_SOFT,
|
||||
UserFmtDouble = AL_DOUBLE_SOFT,
|
||||
UserFmtByte3 = AL_BYTE3_SOFT,
|
||||
UserFmtUByte3 = AL_UNSIGNED_BYTE3_SOFT,
|
||||
UserFmtMulaw,
|
||||
UserFmtAlaw,
|
||||
UserFmtIMA4,
|
||||
};
|
||||
enum UserFmtChannels {
|
||||
UserFmtMono = AL_MONO_SOFT,
|
||||
UserFmtStereo = AL_STEREO_SOFT,
|
||||
UserFmtRear = AL_REAR_SOFT,
|
||||
UserFmtQuad = AL_QUAD_SOFT,
|
||||
UserFmtX51 = AL_5POINT1_SOFT, /* (WFX order) */
|
||||
UserFmtX61 = AL_6POINT1_SOFT, /* (WFX order) */
|
||||
UserFmtX71 = AL_7POINT1_SOFT, /* (WFX order) */
|
||||
};
|
||||
|
||||
typedef struct ALbuffer_struct
|
||||
ALuint BytesFromUserFmt(enum UserFmtType type);
|
||||
ALuint ChannelsFromUserFmt(enum UserFmtChannels chans);
|
||||
static __inline ALuint FrameSizeFromUserFmt(enum UserFmtChannels chans,
|
||||
enum UserFmtType type)
|
||||
{
|
||||
ALenum format;
|
||||
ALenum eOriginalFormat;
|
||||
ALshort *data;
|
||||
ALsizei size;
|
||||
ALsizei frequency;
|
||||
ALenum state;
|
||||
ALuint refcount; // Number of sources using this buffer (deletion can only occur when this is 0)
|
||||
struct ALbuffer_struct *next;
|
||||
return ChannelsFromUserFmt(chans) * BytesFromUserFmt(type);
|
||||
}
|
||||
|
||||
|
||||
/* Storable formats */
|
||||
enum FmtType {
|
||||
FmtByte = UserFmtByte,
|
||||
FmtShort = UserFmtShort,
|
||||
FmtFloat = UserFmtFloat,
|
||||
};
|
||||
enum FmtChannels {
|
||||
FmtMono = UserFmtMono,
|
||||
FmtStereo = UserFmtStereo,
|
||||
FmtRear = UserFmtRear,
|
||||
FmtQuad = UserFmtQuad,
|
||||
FmtX51 = UserFmtX51,
|
||||
FmtX61 = UserFmtX61,
|
||||
FmtX71 = UserFmtX71,
|
||||
};
|
||||
|
||||
ALuint BytesFromFmt(enum FmtType type);
|
||||
ALuint ChannelsFromFmt(enum FmtChannels chans);
|
||||
static __inline ALuint FrameSizeFromFmt(enum FmtChannels chans, enum FmtType type)
|
||||
{
|
||||
return ChannelsFromFmt(chans) * BytesFromFmt(type);
|
||||
}
|
||||
|
||||
|
||||
typedef struct ALbuffer
|
||||
{
|
||||
ALvoid *data;
|
||||
|
||||
ALsizei Frequency;
|
||||
ALenum Format;
|
||||
ALsizei SampleLen;
|
||||
|
||||
enum FmtChannels FmtChannels;
|
||||
enum FmtType FmtType;
|
||||
|
||||
enum UserFmtChannels OriginalChannels;
|
||||
enum UserFmtType OriginalType;
|
||||
ALsizei OriginalSize;
|
||||
|
||||
ALsizei LoopStart;
|
||||
ALsizei LoopEnd;
|
||||
|
||||
/* Number of times buffer was attached to a source (deletion can only occur when 0) */
|
||||
RefCount ref;
|
||||
|
||||
RWLock lock;
|
||||
|
||||
/* Self ID */
|
||||
ALuint id;
|
||||
} ALbuffer;
|
||||
|
||||
ALvoid ReleaseALBuffers(ALvoid);
|
||||
ALvoid ReleaseALBuffers(ALCdevice *device);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
||||
@@ -0,0 +1,114 @@
|
||||
#ifndef _AL_EFFECT_H_
|
||||
#define _AL_EFFECT_H_
|
||||
|
||||
#include "alMain.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
enum {
|
||||
EAXREVERB = 0,
|
||||
REVERB,
|
||||
ECHO,
|
||||
MODULATOR,
|
||||
DEDICATED,
|
||||
|
||||
MAX_EFFECTS
|
||||
};
|
||||
extern ALboolean DisabledEffects[MAX_EFFECTS];
|
||||
|
||||
extern ALfloat ReverbBoost;
|
||||
extern ALboolean EmulateEAXReverb;
|
||||
|
||||
typedef struct ALeffect
|
||||
{
|
||||
// Effect type (AL_EFFECT_NULL, ...)
|
||||
ALenum type;
|
||||
|
||||
struct {
|
||||
// Shared Reverb Properties
|
||||
ALfloat Density;
|
||||
ALfloat Diffusion;
|
||||
ALfloat Gain;
|
||||
ALfloat GainHF;
|
||||
ALfloat DecayTime;
|
||||
ALfloat DecayHFRatio;
|
||||
ALfloat ReflectionsGain;
|
||||
ALfloat ReflectionsDelay;
|
||||
ALfloat LateReverbGain;
|
||||
ALfloat LateReverbDelay;
|
||||
ALfloat AirAbsorptionGainHF;
|
||||
ALfloat RoomRolloffFactor;
|
||||
ALboolean DecayHFLimit;
|
||||
|
||||
// Additional EAX Reverb Properties
|
||||
ALfloat GainLF;
|
||||
ALfloat DecayLFRatio;
|
||||
ALfloat ReflectionsPan[3];
|
||||
ALfloat LateReverbPan[3];
|
||||
ALfloat EchoTime;
|
||||
ALfloat EchoDepth;
|
||||
ALfloat ModulationTime;
|
||||
ALfloat ModulationDepth;
|
||||
ALfloat HFReference;
|
||||
ALfloat LFReference;
|
||||
} Reverb;
|
||||
|
||||
struct {
|
||||
ALfloat Delay;
|
||||
ALfloat LRDelay;
|
||||
|
||||
ALfloat Damping;
|
||||
ALfloat Feedback;
|
||||
|
||||
ALfloat Spread;
|
||||
} Echo;
|
||||
|
||||
struct {
|
||||
ALfloat Frequency;
|
||||
ALfloat HighPassCutoff;
|
||||
ALint Waveform;
|
||||
} Modulator;
|
||||
|
||||
struct {
|
||||
ALfloat Gain;
|
||||
} Dedicated;
|
||||
|
||||
void (*SetParami)(struct ALeffect *effect, ALCcontext *context, ALenum param, ALint val);
|
||||
void (*SetParamiv)(struct ALeffect *effect, ALCcontext *context, ALenum param, const ALint *vals);
|
||||
void (*SetParamf)(struct ALeffect *effect, ALCcontext *context, ALenum param, ALfloat val);
|
||||
void (*SetParamfv)(struct ALeffect *effect, ALCcontext *context, ALenum param, const ALfloat *vals);
|
||||
|
||||
void (*GetParami)(struct ALeffect *effect, ALCcontext *context, ALenum param, ALint *val);
|
||||
void (*GetParamiv)(struct ALeffect *effect, ALCcontext *context, ALenum param, ALint *vals);
|
||||
void (*GetParamf)(struct ALeffect *effect, ALCcontext *context, ALenum param, ALfloat *val);
|
||||
void (*GetParamfv)(struct ALeffect *effect, ALCcontext *context, ALenum param, ALfloat *vals);
|
||||
|
||||
/* Self ID */
|
||||
ALuint id;
|
||||
} ALeffect;
|
||||
|
||||
#define ALeffect_SetParami(x, c, p, v) ((x)->SetParami((x),(c),(p),(v)))
|
||||
#define ALeffect_SetParamiv(x, c, p, v) ((x)->SetParamiv((x),(c),(p),(v)))
|
||||
#define ALeffect_SetParamf(x, c, p, v) ((x)->SetParamf((x),(c),(p),(v)))
|
||||
#define ALeffect_SetParamfv(x, c, p, v) ((x)->SetParamfv((x),(c),(p),(v)))
|
||||
|
||||
#define ALeffect_GetParami(x, c, p, v) ((x)->GetParami((x),(c),(p),(v)))
|
||||
#define ALeffect_GetParamiv(x, c, p, v) ((x)->GetParamiv((x),(c),(p),(v)))
|
||||
#define ALeffect_GetParamf(x, c, p, v) ((x)->GetParamf((x),(c),(p),(v)))
|
||||
#define ALeffect_GetParamfv(x, c, p, v) ((x)->GetParamfv((x),(c),(p),(v)))
|
||||
|
||||
static __inline ALboolean IsReverbEffect(ALenum type)
|
||||
{ return type == AL_EFFECT_REVERB || type == AL_EFFECT_EAXREVERB; }
|
||||
|
||||
ALenum InitEffect(ALeffect *effect);
|
||||
ALvoid ReleaseALEffects(ALCdevice *device);
|
||||
|
||||
ALvoid LoadReverbPreset(const char *name, ALeffect *effect);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
@@ -1,13 +1,15 @@
|
||||
#ifndef _AL_ERROR_H_
|
||||
#define _AL_ERROR_H_
|
||||
|
||||
#include "AL/al.h"
|
||||
#include "alMain.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
ALvoid alSetError(ALenum errorCode);
|
||||
extern ALboolean TrapALError;
|
||||
|
||||
ALvoid alSetError(ALCcontext *Context, ALenum errorCode);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
||||
@@ -1,33 +0,0 @@
|
||||
#ifndef _AL_EXTENSION_H_
|
||||
#define _AL_EXTENSION_H_
|
||||
|
||||
#include "AL/al.h"
|
||||
#include "AL/alc.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
typedef struct ALextension_struct
|
||||
{
|
||||
ALchar *extName;
|
||||
ALvoid *address;
|
||||
} ALextension;
|
||||
|
||||
typedef struct ALfunction_struct
|
||||
{
|
||||
ALchar *funcName;
|
||||
ALvoid *address;
|
||||
} ALfunction;
|
||||
|
||||
typedef struct ALenum_struct
|
||||
{
|
||||
ALchar *enumName;
|
||||
ALenum value;
|
||||
} ALenums;
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,90 @@
|
||||
#ifndef _AL_FILTER_H_
|
||||
#define _AL_FILTER_H_
|
||||
|
||||
#include "alMain.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#define LOWPASSFREQREF (5000)
|
||||
|
||||
typedef struct {
|
||||
ALfloat coeff;
|
||||
#ifndef _MSC_VER
|
||||
ALfloat history[0];
|
||||
#else
|
||||
ALfloat history[1];
|
||||
#endif
|
||||
} FILTER;
|
||||
|
||||
static __inline ALfloat lpFilter2P(FILTER *iir, ALuint offset, ALfloat input)
|
||||
{
|
||||
ALfloat *history = &iir->history[offset*2];
|
||||
ALfloat a = iir->coeff;
|
||||
ALfloat output = input;
|
||||
|
||||
output = output + (history[0]-output)*a;
|
||||
history[0] = output;
|
||||
output = output + (history[1]-output)*a;
|
||||
history[1] = output;
|
||||
|
||||
return output;
|
||||
}
|
||||
|
||||
static __inline ALfloat lpFilter2PC(const FILTER *iir, ALuint offset, ALfloat input)
|
||||
{
|
||||
const ALfloat *history = &iir->history[offset*2];
|
||||
ALfloat a = iir->coeff;
|
||||
ALfloat output = input;
|
||||
|
||||
output = output + (history[0]-output)*a;
|
||||
output = output + (history[1]-output)*a;
|
||||
|
||||
return output;
|
||||
}
|
||||
|
||||
/* Calculates the low-pass filter coefficient given the pre-scaled gain and
|
||||
* cos(w) value. Note that g should be pre-scaled (sqr(gain) for one-pole,
|
||||
* sqrt(gain) for four-pole, etc) */
|
||||
ALfloat lpCoeffCalc(ALfloat g, ALfloat cw);
|
||||
|
||||
|
||||
typedef struct ALfilter {
|
||||
// Filter type (AL_FILTER_NULL, ...)
|
||||
ALenum type;
|
||||
|
||||
ALfloat Gain;
|
||||
ALfloat GainHF;
|
||||
|
||||
void (*SetParami)(struct ALfilter *filter, ALCcontext *context, ALenum param, ALint val);
|
||||
void (*SetParamiv)(struct ALfilter *filter, ALCcontext *context, ALenum param, const ALint *vals);
|
||||
void (*SetParamf)(struct ALfilter *filter, ALCcontext *context, ALenum param, ALfloat val);
|
||||
void (*SetParamfv)(struct ALfilter *filter, ALCcontext *context, ALenum param, const ALfloat *vals);
|
||||
|
||||
void (*GetParami)(struct ALfilter *filter, ALCcontext *context, ALenum param, ALint *val);
|
||||
void (*GetParamiv)(struct ALfilter *filter, ALCcontext *context, ALenum param, ALint *vals);
|
||||
void (*GetParamf)(struct ALfilter *filter, ALCcontext *context, ALenum param, ALfloat *val);
|
||||
void (*GetParamfv)(struct ALfilter *filter, ALCcontext *context, ALenum param, ALfloat *vals);
|
||||
|
||||
/* Self ID */
|
||||
ALuint id;
|
||||
} ALfilter;
|
||||
|
||||
#define ALfilter_SetParami(x, c, p, v) ((x)->SetParami((x),(c),(p),(v)))
|
||||
#define ALfilter_SetParamiv(x, c, p, v) ((x)->SetParamiv((x),(c),(p),(v)))
|
||||
#define ALfilter_SetParamf(x, c, p, v) ((x)->SetParamf((x),(c),(p),(v)))
|
||||
#define ALfilter_SetParamfv(x, c, p, v) ((x)->SetParamfv((x),(c),(p),(v)))
|
||||
|
||||
#define ALfilter_GetParami(x, c, p, v) ((x)->GetParami((x),(c),(p),(v)))
|
||||
#define ALfilter_GetParamiv(x, c, p, v) ((x)->GetParamiv((x),(c),(p),(v)))
|
||||
#define ALfilter_GetParamf(x, c, p, v) ((x)->GetParamf((x),(c),(p),(v)))
|
||||
#define ALfilter_GetParamfv(x, c, p, v) ((x)->GetParamfv((x),(c),(p),(v)))
|
||||
|
||||
ALvoid ReleaseALFilters(ALCdevice *device);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
@@ -1,19 +1,24 @@
|
||||
#ifndef _AL_LISTENER_H_
|
||||
#define _AL_LISTENER_H_
|
||||
|
||||
#include "AL/al.h"
|
||||
#include "alMain.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
typedef struct ALlistener_struct
|
||||
{
|
||||
ALfloat Position[3];
|
||||
ALfloat Velocity[3];
|
||||
ALfloat Forward[3];
|
||||
ALfloat Up[3];
|
||||
ALfloat Gain;
|
||||
typedef struct ALlistener {
|
||||
volatile ALfloat Position[3];
|
||||
volatile ALfloat Velocity[3];
|
||||
volatile ALfloat Forward[3];
|
||||
volatile ALfloat Up[3];
|
||||
volatile ALfloat Gain;
|
||||
volatile ALfloat MetersPerUnit;
|
||||
|
||||
struct {
|
||||
ALfloat Matrix[4][4];
|
||||
ALfloat Velocity[3];
|
||||
} Params;
|
||||
} ALlistener;
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
||||
+786
-119
@@ -2,197 +2,747 @@
|
||||
#define AL_MAIN_H
|
||||
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#include <stdarg.h>
|
||||
#include <assert.h>
|
||||
#include <math.h>
|
||||
|
||||
#include "alu.h"
|
||||
#ifdef HAVE_FENV_H
|
||||
#include <fenv.h>
|
||||
#endif
|
||||
|
||||
#include "AL/al.h"
|
||||
#include "AL/alc.h"
|
||||
#include "AL/alext.h"
|
||||
|
||||
#ifndef AL_SOFT_deferred_updates
|
||||
#define AL_SOFT_deferred_updates 1
|
||||
#define AL_DEFERRED_UPDATES_SOFT 0xC002
|
||||
typedef ALvoid (AL_APIENTRY*LPALDEFERUPDATESSOFT)(void);
|
||||
typedef ALvoid (AL_APIENTRY*LPALPROCESSUPDATESSOFT)(void);
|
||||
#ifdef AL_ALEXT_PROTOTYPES
|
||||
AL_API ALvoid AL_APIENTRY alDeferUpdatesSOFT(void);
|
||||
AL_API ALvoid AL_APIENTRY alProcessUpdatesSOFT(void);
|
||||
#endif
|
||||
#endif
|
||||
|
||||
|
||||
#if defined(HAVE_STDINT_H)
|
||||
#include <stdint.h>
|
||||
typedef int64_t ALint64;
|
||||
typedef uint64_t ALuint64;
|
||||
#elif defined(HAVE___INT64)
|
||||
typedef __int64 ALint64;
|
||||
typedef unsigned __int64 ALuint64;
|
||||
#elif (SIZEOF_LONG == 8)
|
||||
typedef long ALint64;
|
||||
typedef unsigned long ALuint64;
|
||||
#elif (SIZEOF_LONG_LONG == 8)
|
||||
typedef long long ALint64;
|
||||
typedef unsigned long long ALuint64;
|
||||
#endif
|
||||
|
||||
typedef ptrdiff_t ALintptrEXT;
|
||||
typedef ptrdiff_t ALsizeiptrEXT;
|
||||
|
||||
#define MAKEU64(x,y) (((ALuint64)(x)<<32)|(ALuint64)(y))
|
||||
|
||||
#ifdef HAVE_GCC_FORMAT
|
||||
#define PRINTF_STYLE(x, y) __attribute__((format(printf, (x), (y))))
|
||||
#else
|
||||
#define PRINTF_STYLE(x, y)
|
||||
#endif
|
||||
|
||||
|
||||
static const union {
|
||||
ALuint u;
|
||||
ALubyte b[sizeof(ALuint)];
|
||||
} EndianTest = { 1 };
|
||||
#define IS_LITTLE_ENDIAN (EndianTest.b[0] == 1)
|
||||
|
||||
#define COUNTOF(x) (sizeof((x))/sizeof((x)[0]))
|
||||
|
||||
#ifdef _WIN32
|
||||
|
||||
#define WIN32_LEAN_AND_MEAN
|
||||
#include <windows.h>
|
||||
//#define strcasecmp _stricmp
|
||||
|
||||
typedef DWORD pthread_key_t;
|
||||
int pthread_key_create(pthread_key_t *key, void (*callback)(void*));
|
||||
int pthread_key_delete(pthread_key_t key);
|
||||
void *pthread_getspecific(pthread_key_t key);
|
||||
int pthread_setspecific(pthread_key_t key, void *val);
|
||||
|
||||
#define HAVE_DYNLOAD 1
|
||||
void *LoadLib(const char *name);
|
||||
void CloseLib(void *handle);
|
||||
void *GetSymbol(void *handle, const char *name);
|
||||
|
||||
WCHAR *strdupW(const WCHAR *str);
|
||||
|
||||
typedef LONG pthread_once_t;
|
||||
#define PTHREAD_ONCE_INIT 0
|
||||
void pthread_once(pthread_once_t *once, void (*callback)(void));
|
||||
|
||||
static __inline int sched_yield(void)
|
||||
{ SwitchToThread(); return 0; }
|
||||
|
||||
#else
|
||||
|
||||
#include <unistd.h>
|
||||
#include <assert.h>
|
||||
#include <pthread.h>
|
||||
#include <sys/time.h>
|
||||
#include <time.h>
|
||||
#include <errno.h>
|
||||
|
||||
#define IsBadWritePtr(a,b) (0)
|
||||
#define IsBadWritePtr(a,b) ((a) == NULL && (b) != 0)
|
||||
|
||||
typedef pthread_mutex_t CRITICAL_SECTION;
|
||||
static inline void EnterCriticalSection(CRITICAL_SECTION *cs)
|
||||
{
|
||||
int ret;
|
||||
ret = pthread_mutex_lock(cs);
|
||||
assert(ret == 0);
|
||||
}
|
||||
static inline void LeaveCriticalSection(CRITICAL_SECTION *cs)
|
||||
{
|
||||
int ret;
|
||||
ret = pthread_mutex_unlock(cs);
|
||||
assert(ret == 0);
|
||||
}
|
||||
static inline void InitializeCriticalSection(CRITICAL_SECTION *cs)
|
||||
{
|
||||
pthread_mutexattr_t attrib;
|
||||
int ret;
|
||||
void InitializeCriticalSection(CRITICAL_SECTION *cs);
|
||||
void DeleteCriticalSection(CRITICAL_SECTION *cs);
|
||||
void EnterCriticalSection(CRITICAL_SECTION *cs);
|
||||
void LeaveCriticalSection(CRITICAL_SECTION *cs);
|
||||
|
||||
ret = pthread_mutexattr_init(&attrib);
|
||||
assert(ret == 0);
|
||||
ALuint timeGetTime(void);
|
||||
void Sleep(ALuint t);
|
||||
|
||||
ret = pthread_mutexattr_settype(&attrib, PTHREAD_MUTEX_RECURSIVE);
|
||||
assert(ret == 0);
|
||||
ret = pthread_mutex_init(cs, &attrib);
|
||||
assert(ret == 0);
|
||||
|
||||
pthread_mutexattr_destroy(&attrib);
|
||||
}
|
||||
|
||||
static inline void DeleteCriticalSection(CRITICAL_SECTION *cs)
|
||||
{
|
||||
int ret;
|
||||
ret = pthread_mutex_destroy(cs);
|
||||
assert(ret == 0);
|
||||
}
|
||||
|
||||
#define min(x,y) (((x)<(y))?(x):(y))
|
||||
#define max(x,y) (((x)>(y))?(x):(y))
|
||||
#if defined(HAVE_DLFCN_H)
|
||||
#define HAVE_DYNLOAD 1
|
||||
void *LoadLib(const char *name);
|
||||
void CloseLib(void *handle);
|
||||
void *GetSymbol(void *handle, const char *name);
|
||||
#endif
|
||||
|
||||
#include "alListener.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
{
|
||||
#endif
|
||||
|
||||
extern CRITICAL_SECTION _alMutex;
|
||||
typedef void *volatile XchgPtr;
|
||||
|
||||
extern char _alDebug[256];
|
||||
#if defined(__GNUC__) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 1))
|
||||
typedef ALuint RefCount;
|
||||
static __inline RefCount IncrementRef(volatile RefCount *ptr)
|
||||
{ return __sync_add_and_fetch(ptr, 1); }
|
||||
static __inline RefCount DecrementRef(volatile RefCount *ptr)
|
||||
{ return __sync_sub_and_fetch(ptr, 1); }
|
||||
|
||||
#define AL_PRINT(...) do { \
|
||||
int _al_print_i; \
|
||||
char *_al_print_fn = strrchr(__FILE__, '/'); \
|
||||
if(!_al_print_fn) _al_print_fn = __FILE__; \
|
||||
else _al_print_fn += 1; \
|
||||
_al_print_i = snprintf(_alDebug, sizeof(_alDebug), "AL lib: %s:%d: ", _al_print_fn, __LINE__); \
|
||||
if(_al_print_i < (int)sizeof(_alDebug) && _al_print_i > 0) \
|
||||
snprintf(_alDebug+_al_print_i, sizeof(_alDebug)-_al_print_i, __VA_ARGS__); \
|
||||
_alDebug[sizeof(_alDebug)-1] = 0; \
|
||||
fprintf(stderr, "%s", _alDebug); \
|
||||
} while(0)
|
||||
static __inline int ExchangeInt(volatile int *ptr, int newval)
|
||||
{
|
||||
return __sync_lock_test_and_set(ptr, newval);
|
||||
}
|
||||
static __inline void *ExchangePtr(XchgPtr *ptr, void *newval)
|
||||
{
|
||||
return __sync_lock_test_and_set(ptr, newval);
|
||||
}
|
||||
static __inline ALboolean CompExchangeInt(volatile int *ptr, int oldval, int newval)
|
||||
{
|
||||
return __sync_bool_compare_and_swap(ptr, oldval, newval);
|
||||
}
|
||||
static __inline ALboolean CompExchangePtr(XchgPtr *ptr, void *oldval, void *newval)
|
||||
{
|
||||
return __sync_bool_compare_and_swap(ptr, oldval, newval);
|
||||
}
|
||||
|
||||
#elif defined(__GNUC__) && (defined(__i386__) || defined(__x86_64__))
|
||||
|
||||
#define AL_FORMAT_MONO_FLOAT32 0x10010
|
||||
#define AL_FORMAT_STEREO_FLOAT32 0x10011
|
||||
static __inline int xaddl(volatile int *dest, int incr)
|
||||
{
|
||||
int ret;
|
||||
__asm__ __volatile__("lock; xaddl %0,(%1)"
|
||||
: "=r" (ret)
|
||||
: "r" (dest), "0" (incr)
|
||||
: "memory");
|
||||
return ret;
|
||||
}
|
||||
|
||||
#define AL_FORMAT_MONO_IMA4 0x1300
|
||||
#define AL_FORMAT_STEREO_IMA4 0x1301
|
||||
typedef int RefCount;
|
||||
static __inline RefCount IncrementRef(volatile RefCount *ptr)
|
||||
{ return xaddl(ptr, 1)+1; }
|
||||
static __inline RefCount DecrementRef(volatile RefCount *ptr)
|
||||
{ return xaddl(ptr, -1)-1; }
|
||||
|
||||
#define AL_FORMAT_51CHN8 0x120A
|
||||
#define AL_FORMAT_51CHN16 0x120B
|
||||
#define AL_FORMAT_51CHN32 0x120C
|
||||
#define AL_FORMAT_61CHN8 0x120D
|
||||
#define AL_FORMAT_61CHN16 0x120E
|
||||
#define AL_FORMAT_61CHN32 0x120F
|
||||
#define AL_FORMAT_71CHN8 0x1210
|
||||
#define AL_FORMAT_71CHN16 0x1211
|
||||
#define AL_FORMAT_71CHN32 0x1212
|
||||
#define AL_FORMAT_QUAD8 0x1204
|
||||
#define AL_FORMAT_QUAD16 0x1205
|
||||
#define AL_FORMAT_QUAD32 0x1206
|
||||
#define AL_FORMAT_REAR8 0x1207
|
||||
#define AL_FORMAT_REAR16 0x1208
|
||||
#define AL_FORMAT_REAR32 0x1209
|
||||
static __inline int ExchangeInt(volatile int *dest, int newval)
|
||||
{
|
||||
int ret;
|
||||
__asm__ __volatile__("lock; xchgl %0,(%1)"
|
||||
: "=r" (ret)
|
||||
: "r" (dest), "0" (newval)
|
||||
: "memory");
|
||||
return ret;
|
||||
}
|
||||
|
||||
#define SWMIXER_OUTPUT_RATE 44100
|
||||
static __inline ALboolean CompExchangeInt(volatile int *dest, int oldval, int newval)
|
||||
{
|
||||
int ret;
|
||||
__asm__ __volatile__("lock; cmpxchgl %2,(%1)"
|
||||
: "=a" (ret)
|
||||
: "r" (dest), "r" (newval), "0" (oldval)
|
||||
: "memory");
|
||||
return ret == oldval;
|
||||
}
|
||||
|
||||
static __inline void *ExchangePtr(XchgPtr *dest, void *newval)
|
||||
{
|
||||
void *ret;
|
||||
__asm__ __volatile__(
|
||||
#ifdef __i386__
|
||||
"lock; xchgl %0,(%1)"
|
||||
#else
|
||||
"lock; xchgq %0,(%1)"
|
||||
#endif
|
||||
: "=r" (ret)
|
||||
: "r" (dest), "0" (newval)
|
||||
: "memory"
|
||||
);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static __inline ALboolean CompExchangePtr(XchgPtr *dest, void *oldval, void *newval)
|
||||
{
|
||||
void *ret;
|
||||
__asm__ __volatile__(
|
||||
#ifdef __i386__
|
||||
"lock; cmpxchgl %2,(%1)"
|
||||
#else
|
||||
"lock; cmpxchgq %2,(%1)"
|
||||
#endif
|
||||
: "=a" (ret)
|
||||
: "r" (dest), "r" (newval), "0" (oldval)
|
||||
: "memory"
|
||||
);
|
||||
return ret == oldval;
|
||||
}
|
||||
|
||||
#elif defined(_WIN32)
|
||||
|
||||
typedef LONG RefCount;
|
||||
static __inline RefCount IncrementRef(volatile RefCount *ptr)
|
||||
{ return InterlockedIncrement(ptr); }
|
||||
static __inline RefCount DecrementRef(volatile RefCount *ptr)
|
||||
{ return InterlockedDecrement(ptr); }
|
||||
|
||||
extern ALbyte LONG_size_does_not_match_int[(sizeof(LONG)==sizeof(int))?1:-1];
|
||||
|
||||
static __inline int ExchangeInt(volatile int *ptr, int newval)
|
||||
{
|
||||
union {
|
||||
volatile int *i;
|
||||
volatile LONG *l;
|
||||
} u = { ptr };
|
||||
return InterlockedExchange(u.l, newval);
|
||||
}
|
||||
static __inline void *ExchangePtr(XchgPtr *ptr, void *newval)
|
||||
{
|
||||
return InterlockedExchangePointer(ptr, newval);
|
||||
}
|
||||
static __inline ALboolean CompExchangeInt(volatile int *ptr, int oldval, int newval)
|
||||
{
|
||||
union {
|
||||
volatile int *i;
|
||||
volatile LONG *l;
|
||||
} u = { ptr };
|
||||
return InterlockedCompareExchange(u.l, newval, oldval) == oldval;
|
||||
}
|
||||
static __inline ALboolean CompExchangePtr(XchgPtr *ptr, void *oldval, void *newval)
|
||||
{
|
||||
return InterlockedCompareExchangePointer(ptr, newval, oldval) == oldval;
|
||||
}
|
||||
|
||||
#elif defined(__APPLE__)
|
||||
|
||||
#include <libkern/OSAtomic.h>
|
||||
|
||||
typedef int32_t RefCount;
|
||||
static __inline RefCount IncrementRef(volatile RefCount *ptr)
|
||||
{ return OSAtomicIncrement32Barrier(ptr); }
|
||||
static __inline RefCount DecrementRef(volatile RefCount *ptr)
|
||||
{ return OSAtomicDecrement32Barrier(ptr); }
|
||||
|
||||
static __inline int ExchangeInt(volatile int *ptr, int newval)
|
||||
{
|
||||
/* Really? No regular old atomic swap? */
|
||||
int oldval;
|
||||
do {
|
||||
oldval = *ptr;
|
||||
} while(!OSAtomicCompareAndSwap32Barrier(oldval, newval, ptr));
|
||||
return oldval;
|
||||
}
|
||||
static __inline void *ExchangePtr(XchgPtr *ptr, void *newval)
|
||||
{
|
||||
void *oldval;
|
||||
do {
|
||||
oldval = *ptr;
|
||||
} while(!OSAtomicCompareAndSwapPtrBarrier(oldval, newval, ptr));
|
||||
return oldval;
|
||||
}
|
||||
static __inline ALboolean CompExchangeInt(volatile int *ptr, int oldval, int newval)
|
||||
{
|
||||
return OSAtomicCompareAndSwap32Barrier(oldval, newval, ptr);
|
||||
}
|
||||
static __inline ALboolean CompExchangePtr(XchgPtr *ptr, void *oldval, void *newval)
|
||||
{
|
||||
return OSAtomicCompareAndSwapPtrBarrier(oldval, newval, ptr);
|
||||
}
|
||||
|
||||
#else
|
||||
#error "No atomic functions available on this platform!"
|
||||
typedef ALuint RefCount;
|
||||
#endif
|
||||
|
||||
#define SPEEDOFSOUNDMETRESPERSEC (343.3f)
|
||||
|
||||
typedef struct {
|
||||
ALCboolean (*OpenPlayback)(ALCdevice*, const ALCchar*);
|
||||
void (*ClosePlayback)(ALCdevice*);
|
||||
volatile RefCount read_count;
|
||||
volatile RefCount write_count;
|
||||
volatile ALenum read_lock;
|
||||
volatile ALenum read_entry_lock;
|
||||
volatile ALenum write_lock;
|
||||
} RWLock;
|
||||
|
||||
ALCboolean (*OpenCapture)(ALCdevice*, const ALCchar*, ALCuint, ALCenum, ALCsizei);
|
||||
void RWLockInit(RWLock *lock);
|
||||
void ReadLock(RWLock *lock);
|
||||
void ReadUnlock(RWLock *lock);
|
||||
void WriteLock(RWLock *lock);
|
||||
void WriteUnlock(RWLock *lock);
|
||||
|
||||
|
||||
typedef struct UIntMap {
|
||||
struct {
|
||||
ALuint key;
|
||||
ALvoid *value;
|
||||
} *array;
|
||||
ALsizei size;
|
||||
ALsizei maxsize;
|
||||
ALsizei limit;
|
||||
RWLock lock;
|
||||
} UIntMap;
|
||||
extern UIntMap TlsDestructor;
|
||||
|
||||
void InitUIntMap(UIntMap *map, ALsizei limit);
|
||||
void ResetUIntMap(UIntMap *map);
|
||||
ALenum InsertUIntMapEntry(UIntMap *map, ALuint key, ALvoid *value);
|
||||
ALvoid *RemoveUIntMapKey(UIntMap *map, ALuint key);
|
||||
ALvoid *LookupUIntMapKey(UIntMap *map, ALuint key);
|
||||
|
||||
static __inline void LockUIntMapRead(UIntMap *map)
|
||||
{ ReadLock(&map->lock); }
|
||||
static __inline void UnlockUIntMapRead(UIntMap *map)
|
||||
{ ReadUnlock(&map->lock); }
|
||||
static __inline void LockUIntMapWrite(UIntMap *map)
|
||||
{ WriteLock(&map->lock); }
|
||||
static __inline void UnlockUIntMapWrite(UIntMap *map)
|
||||
{ WriteUnlock(&map->lock); }
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
struct Hrtf;
|
||||
|
||||
|
||||
#define DEFAULT_OUTPUT_RATE (44100)
|
||||
#define MIN_OUTPUT_RATE (8000)
|
||||
|
||||
|
||||
// Find the next power-of-2 for non-power-of-2 numbers.
|
||||
static __inline ALuint NextPowerOf2(ALuint value)
|
||||
{
|
||||
if(value > 0)
|
||||
{
|
||||
value--;
|
||||
value |= value>>1;
|
||||
value |= value>>2;
|
||||
value |= value>>4;
|
||||
value |= value>>8;
|
||||
value |= value>>16;
|
||||
}
|
||||
return value+1;
|
||||
}
|
||||
|
||||
/* Fast float-to-int conversion. Assumes the FPU is already in round-to-zero
|
||||
* mode. */
|
||||
static __inline ALint fastf2i(ALfloat f)
|
||||
{
|
||||
#ifdef HAVE_LRINTF
|
||||
return lrintf(f);
|
||||
#elif defined(_MSC_VER) && defined(_M_IX86)
|
||||
ALint i;
|
||||
__asm fld f
|
||||
__asm fistp i
|
||||
return i;
|
||||
#else
|
||||
return (ALint)f;
|
||||
#endif
|
||||
}
|
||||
|
||||
/* Fast float-to-uint conversion. Assumes the FPU is already in round-to-zero
|
||||
* mode. */
|
||||
static __inline ALuint fastf2u(ALfloat f)
|
||||
{ return fastf2i(f); }
|
||||
|
||||
|
||||
enum DevProbe {
|
||||
ALL_DEVICE_PROBE,
|
||||
CAPTURE_DEVICE_PROBE
|
||||
};
|
||||
|
||||
typedef struct {
|
||||
ALCenum (*OpenPlayback)(ALCdevice*, const ALCchar*);
|
||||
void (*ClosePlayback)(ALCdevice*);
|
||||
ALCboolean (*ResetPlayback)(ALCdevice*);
|
||||
ALCboolean (*StartPlayback)(ALCdevice*);
|
||||
void (*StopPlayback)(ALCdevice*);
|
||||
|
||||
ALCenum (*OpenCapture)(ALCdevice*, const ALCchar*);
|
||||
void (*CloseCapture)(ALCdevice*);
|
||||
void (*StartCapture)(ALCdevice*);
|
||||
void (*StopCapture)(ALCdevice*);
|
||||
void (*CaptureSamples)(ALCdevice*, void*, ALCuint);
|
||||
ALCenum (*CaptureSamples)(ALCdevice*, void*, ALCuint);
|
||||
ALCuint (*AvailableSamples)(ALCdevice*);
|
||||
|
||||
void (*Lock)(ALCdevice*);
|
||||
void (*Unlock)(ALCdevice*);
|
||||
|
||||
ALint64 (*GetLatency)(ALCdevice*);
|
||||
} BackendFuncs;
|
||||
|
||||
void alc_alsa_init(BackendFuncs *func_list);
|
||||
void alc_oss_init(BackendFuncs *func_list);
|
||||
void alcDSoundInit(BackendFuncs *func_list);
|
||||
void alcWinMMInit(BackendFuncs *FuncList);
|
||||
struct BackendInfo {
|
||||
const char *name;
|
||||
ALCboolean (*Init)(BackendFuncs*);
|
||||
void (*Deinit)(void);
|
||||
void (*Probe)(enum DevProbe);
|
||||
BackendFuncs Funcs;
|
||||
};
|
||||
|
||||
ALCboolean alc_alsa_init(BackendFuncs *func_list);
|
||||
void alc_alsa_deinit(void);
|
||||
void alc_alsa_probe(enum DevProbe type);
|
||||
ALCboolean alc_oss_init(BackendFuncs *func_list);
|
||||
void alc_oss_deinit(void);
|
||||
void alc_oss_probe(enum DevProbe type);
|
||||
ALCboolean alc_solaris_init(BackendFuncs *func_list);
|
||||
void alc_solaris_deinit(void);
|
||||
void alc_solaris_probe(enum DevProbe type);
|
||||
ALCboolean alc_sndio_init(BackendFuncs *func_list);
|
||||
void alc_sndio_deinit(void);
|
||||
void alc_sndio_probe(enum DevProbe type);
|
||||
ALCboolean alcMMDevApiInit(BackendFuncs *func_list);
|
||||
void alcMMDevApiDeinit(void);
|
||||
void alcMMDevApiProbe(enum DevProbe type);
|
||||
ALCboolean alcDSoundInit(BackendFuncs *func_list);
|
||||
void alcDSoundDeinit(void);
|
||||
void alcDSoundProbe(enum DevProbe type);
|
||||
ALCboolean alcWinMMInit(BackendFuncs *FuncList);
|
||||
void alcWinMMDeinit(void);
|
||||
void alcWinMMProbe(enum DevProbe type);
|
||||
ALCboolean alc_pa_init(BackendFuncs *func_list);
|
||||
void alc_pa_deinit(void);
|
||||
void alc_pa_probe(enum DevProbe type);
|
||||
ALCboolean alc_wave_init(BackendFuncs *func_list);
|
||||
void alc_wave_deinit(void);
|
||||
void alc_wave_probe(enum DevProbe type);
|
||||
ALCboolean alc_pulse_init(BackendFuncs *func_list);
|
||||
void alc_pulse_deinit(void);
|
||||
void alc_pulse_probe(enum DevProbe type);
|
||||
ALCboolean alc_ca_init(BackendFuncs *func_list);
|
||||
void alc_ca_deinit(void);
|
||||
void alc_ca_probe(enum DevProbe type);
|
||||
ALCboolean alc_opensl_init(BackendFuncs *func_list);
|
||||
void alc_opensl_deinit(void);
|
||||
void alc_opensl_probe(enum DevProbe type);
|
||||
ALCboolean alc_null_init(BackendFuncs *func_list);
|
||||
void alc_null_deinit(void);
|
||||
void alc_null_probe(enum DevProbe type);
|
||||
ALCboolean alc_loopback_init(BackendFuncs *func_list);
|
||||
void alc_loopback_deinit(void);
|
||||
void alc_loopback_probe(enum DevProbe type);
|
||||
|
||||
|
||||
enum DistanceModel {
|
||||
InverseDistanceClamped = AL_INVERSE_DISTANCE_CLAMPED,
|
||||
LinearDistanceClamped = AL_LINEAR_DISTANCE_CLAMPED,
|
||||
ExponentDistanceClamped = AL_EXPONENT_DISTANCE_CLAMPED,
|
||||
InverseDistance = AL_INVERSE_DISTANCE,
|
||||
LinearDistance = AL_LINEAR_DISTANCE,
|
||||
ExponentDistance = AL_EXPONENT_DISTANCE,
|
||||
DisableDistance = AL_NONE,
|
||||
|
||||
DefaultDistanceModel = InverseDistanceClamped
|
||||
};
|
||||
|
||||
enum Resampler {
|
||||
PointResampler,
|
||||
LinearResampler,
|
||||
CubicResampler,
|
||||
|
||||
ResamplerMax,
|
||||
};
|
||||
|
||||
enum Channel {
|
||||
FrontLeft = 0,
|
||||
FrontRight,
|
||||
FrontCenter,
|
||||
LFE,
|
||||
BackLeft,
|
||||
BackRight,
|
||||
BackCenter,
|
||||
SideLeft,
|
||||
SideRight,
|
||||
|
||||
MaxChannels,
|
||||
};
|
||||
|
||||
|
||||
/* Device formats */
|
||||
enum DevFmtType {
|
||||
DevFmtByte = ALC_BYTE_SOFT,
|
||||
DevFmtUByte = ALC_UNSIGNED_BYTE_SOFT,
|
||||
DevFmtShort = ALC_SHORT_SOFT,
|
||||
DevFmtUShort = ALC_UNSIGNED_SHORT_SOFT,
|
||||
DevFmtInt = ALC_INT_SOFT,
|
||||
DevFmtUInt = ALC_UNSIGNED_INT_SOFT,
|
||||
DevFmtFloat = ALC_FLOAT_SOFT,
|
||||
|
||||
DevFmtTypeDefault = DevFmtFloat
|
||||
};
|
||||
enum DevFmtChannels {
|
||||
DevFmtMono = ALC_MONO_SOFT,
|
||||
DevFmtStereo = ALC_STEREO_SOFT,
|
||||
DevFmtQuad = ALC_QUAD_SOFT,
|
||||
DevFmtX51 = ALC_5POINT1_SOFT,
|
||||
DevFmtX61 = ALC_6POINT1_SOFT,
|
||||
DevFmtX71 = ALC_7POINT1_SOFT,
|
||||
|
||||
/* Similar to 5.1, except using the side channels instead of back */
|
||||
DevFmtX51Side = 0x80000000,
|
||||
|
||||
DevFmtChannelsDefault = DevFmtStereo
|
||||
};
|
||||
|
||||
ALuint BytesFromDevFmt(enum DevFmtType type);
|
||||
ALuint ChannelsFromDevFmt(enum DevFmtChannels chans);
|
||||
static __inline ALuint FrameSizeFromDevFmt(enum DevFmtChannels chans,
|
||||
enum DevFmtType type)
|
||||
{
|
||||
return ChannelsFromDevFmt(chans) * BytesFromDevFmt(type);
|
||||
}
|
||||
|
||||
|
||||
extern const struct EffectList {
|
||||
const char *name;
|
||||
int type;
|
||||
const char *ename;
|
||||
ALenum val;
|
||||
} EffectList[];
|
||||
|
||||
|
||||
enum DeviceType {
|
||||
Playback,
|
||||
Capture,
|
||||
Loopback
|
||||
};
|
||||
|
||||
|
||||
/* Size for temporary storage of buffer data, in ALfloats. Larger values need
|
||||
* more memory, while smaller values may need more iterations. The value needs
|
||||
* to be a sensible size, however, as it constrains the max stepping value used
|
||||
* for mixing, as well as the maximum number of samples per mixing iteration.
|
||||
*
|
||||
* The mixer requires being able to do two samplings per mixing loop. With the
|
||||
* cubic resampler (which requires 3 padding samples), this limits a 2048
|
||||
* buffer size to about 2044. This means that buffer_freq*source_pitch cannot
|
||||
* exceed device_freq*2044 for a 32-bit buffer.
|
||||
*/
|
||||
#ifndef BUFFERSIZE
|
||||
#define BUFFERSIZE 2048
|
||||
#endif
|
||||
|
||||
|
||||
struct ALCdevice_struct
|
||||
{
|
||||
ALboolean InUse;
|
||||
ALboolean IsCaptureDevice;
|
||||
volatile RefCount ref;
|
||||
|
||||
ALCboolean Connected;
|
||||
enum DeviceType Type;
|
||||
|
||||
CRITICAL_SECTION Mutex;
|
||||
|
||||
ALuint Frequency;
|
||||
ALuint UpdateFreq;
|
||||
ALuint FrameSize;
|
||||
ALuint Channels;
|
||||
ALenum Format;
|
||||
ALuint UpdateSize;
|
||||
ALuint NumUpdates;
|
||||
enum DevFmtChannels FmtChans;
|
||||
enum DevFmtType FmtType;
|
||||
|
||||
ALCchar *szDeviceName;
|
||||
ALCchar *DeviceName;
|
||||
|
||||
volatile ALCenum LastError;
|
||||
|
||||
// Maximum number of sources that can be created
|
||||
ALuint MaxNoOfSources;
|
||||
// Maximum number of slots that can be created
|
||||
ALuint AuxiliaryEffectSlotMax;
|
||||
|
||||
// Context created on this device
|
||||
ALCcontext *Context;
|
||||
ALCuint NumMonoSources;
|
||||
ALCuint NumStereoSources;
|
||||
ALuint NumAuxSends;
|
||||
|
||||
// Map of Buffers for this device
|
||||
UIntMap BufferMap;
|
||||
|
||||
// Map of Effects for this device
|
||||
UIntMap EffectMap;
|
||||
|
||||
// Map of Filters for this device
|
||||
UIntMap FilterMap;
|
||||
|
||||
/* HRTF filter tables */
|
||||
const struct Hrtf *Hrtf;
|
||||
|
||||
// Stereo-to-binaural filter
|
||||
struct bs2b *Bs2b;
|
||||
ALCint Bs2bLevel;
|
||||
|
||||
// Device flags
|
||||
ALuint Flags;
|
||||
|
||||
ALuint ChannelOffsets[MaxChannels];
|
||||
|
||||
enum Channel Speaker2Chan[MaxChannels];
|
||||
ALfloat SpeakerAngle[MaxChannels];
|
||||
ALuint NumChan;
|
||||
|
||||
/* Temp storage used for mixing. +1 for the predictive sample. */
|
||||
ALIGN(16) ALfloat SampleData1[BUFFERSIZE+1];
|
||||
ALIGN(16) ALfloat SampleData2[BUFFERSIZE+1];
|
||||
|
||||
// Dry path buffer mix
|
||||
ALIGN(16) ALfloat DryBuffer[MaxChannels][BUFFERSIZE];
|
||||
|
||||
ALIGN(16) ALfloat ClickRemoval[MaxChannels];
|
||||
ALIGN(16) ALfloat PendingClicks[MaxChannels];
|
||||
|
||||
/* Default effect slot */
|
||||
struct ALeffectslot *DefaultSlot;
|
||||
|
||||
// Contexts created on this device
|
||||
ALCcontext *volatile ContextList;
|
||||
|
||||
BackendFuncs *Funcs;
|
||||
void *ExtraData; // For the backend's use
|
||||
|
||||
ALCdevice *volatile next;
|
||||
};
|
||||
|
||||
#define ALCdevice_OpenPlayback(a,b) ((a)->Funcs->OpenPlayback((a), (b)))
|
||||
#define ALCdevice_ClosePlayback(a) ((a)->Funcs->ClosePlayback((a)))
|
||||
#define ALCdevice_OpenCapture(a,b,c,d,e) ((a)->Funcs->OpenCapture((a), (b), (c), (d), (e)))
|
||||
#define ALCdevice_ResetPlayback(a) ((a)->Funcs->ResetPlayback((a)))
|
||||
#define ALCdevice_StartPlayback(a) ((a)->Funcs->StartPlayback((a)))
|
||||
#define ALCdevice_StopPlayback(a) ((a)->Funcs->StopPlayback((a)))
|
||||
#define ALCdevice_OpenCapture(a,b) ((a)->Funcs->OpenCapture((a), (b)))
|
||||
#define ALCdevice_CloseCapture(a) ((a)->Funcs->CloseCapture((a)))
|
||||
#define ALCdevice_StartCapture(a) ((a)->Funcs->StartCapture((a)))
|
||||
#define ALCdevice_StopCapture(a) ((a)->Funcs->StopCapture((a)))
|
||||
#define ALCdevice_CaptureSamples(a,b,c) ((a)->Funcs->CaptureSamples((a), (b), (c)))
|
||||
#define ALCdevice_AvailableSamples(a) ((a)->Funcs->AvailableSamples((a)))
|
||||
#define ALCdevice_Lock(a) ((a)->Funcs->Lock((a)))
|
||||
#define ALCdevice_Unlock(a) ((a)->Funcs->Unlock((a)))
|
||||
#define ALCdevice_GetLatency(a) ((a)->Funcs->GetLatency((a)))
|
||||
|
||||
// Frequency was requested by the app or config file
|
||||
#define DEVICE_FREQUENCY_REQUEST (1<<1)
|
||||
// Channel configuration was requested by the config file
|
||||
#define DEVICE_CHANNELS_REQUEST (1<<2)
|
||||
// Sample type was requested by the config file
|
||||
#define DEVICE_SAMPLE_TYPE_REQUEST (1<<3)
|
||||
|
||||
// Stereo sources cover 120-degree angles around +/-90
|
||||
#define DEVICE_WIDE_STEREO (1<<16)
|
||||
|
||||
// Specifies if the device is currently running
|
||||
#define DEVICE_RUNNING (1<<31)
|
||||
|
||||
/* Invalid channel offset */
|
||||
#define INVALID_OFFSET (~0u)
|
||||
|
||||
|
||||
#define LookupBuffer(m, k) ((struct ALbuffer*)LookupUIntMapKey(&(m)->BufferMap, (k)))
|
||||
#define LookupEffect(m, k) ((struct ALeffect*)LookupUIntMapKey(&(m)->EffectMap, (k)))
|
||||
#define LookupFilter(m, k) ((struct ALfilter*)LookupUIntMapKey(&(m)->FilterMap, (k)))
|
||||
#define RemoveBuffer(m, k) ((struct ALbuffer*)RemoveUIntMapKey(&(m)->BufferMap, (k)))
|
||||
#define RemoveEffect(m, k) ((struct ALeffect*)RemoveUIntMapKey(&(m)->EffectMap, (k)))
|
||||
#define RemoveFilter(m, k) ((struct ALfilter*)RemoveUIntMapKey(&(m)->FilterMap, (k)))
|
||||
|
||||
|
||||
struct ALCcontext_struct
|
||||
{
|
||||
ALlistener Listener;
|
||||
volatile RefCount ref;
|
||||
|
||||
struct ALsource *Source;
|
||||
ALuint SourceCount;
|
||||
struct ALlistener *Listener;
|
||||
|
||||
ALenum LastError;
|
||||
ALboolean InUse;
|
||||
UIntMap SourceMap;
|
||||
UIntMap EffectSlotMap;
|
||||
|
||||
ALuint Frequency;
|
||||
ALenum LastError;
|
||||
|
||||
ALenum DistanceModel;
|
||||
volatile ALenum UpdateSources;
|
||||
|
||||
ALfloat DopplerFactor;
|
||||
ALfloat DopplerVelocity;
|
||||
ALfloat flSpeedOfSound;
|
||||
volatile enum DistanceModel DistanceModel;
|
||||
volatile ALboolean SourceDistanceModel;
|
||||
|
||||
ALint lNumMonoSources;
|
||||
ALint lNumStereoSources;
|
||||
volatile ALfloat DopplerFactor;
|
||||
volatile ALfloat DopplerVelocity;
|
||||
volatile ALfloat SpeedOfSound;
|
||||
volatile ALenum DeferUpdates;
|
||||
|
||||
struct ALsource **ActiveSources;
|
||||
ALsizei ActiveSourceCount;
|
||||
ALsizei MaxActiveSources;
|
||||
|
||||
struct ALeffectslot **ActiveEffectSlots;
|
||||
ALsizei ActiveEffectSlotCount;
|
||||
ALsizei MaxActiveEffectSlots;
|
||||
|
||||
ALCdevice *Device;
|
||||
ALCchar ExtensionList[1024];
|
||||
const ALCchar *ExtensionList;
|
||||
|
||||
struct bs2b *bs2b;
|
||||
|
||||
ALCcontext *next;
|
||||
ALCcontext *volatile next;
|
||||
};
|
||||
|
||||
ALCchar *AppendDeviceList(char *name);
|
||||
ALCchar *AppendAllDeviceList(char *name);
|
||||
ALCchar *AppendCaptureDeviceList(char *name);
|
||||
#define LookupSource(m, k) ((struct ALsource*)LookupUIntMapKey(&(m)->SourceMap, (k)))
|
||||
#define LookupEffectSlot(m, k) ((struct ALeffectslot*)LookupUIntMapKey(&(m)->EffectSlotMap, (k)))
|
||||
#define RemoveSource(m, k) ((struct ALsource*)RemoveUIntMapKey(&(m)->SourceMap, (k)))
|
||||
#define RemoveEffectSlot(m, k) ((struct ALeffectslot*)RemoveUIntMapKey(&(m)->EffectSlotMap, (k)))
|
||||
|
||||
ALCvoid SetALCError(ALenum errorCode);
|
||||
|
||||
ALCvoid SuspendContext(ALCcontext *context);
|
||||
ALCvoid ProcessContext(ALCcontext *context);
|
||||
ALCcontext *GetContextRef(void);
|
||||
|
||||
void ALCcontext_IncRef(ALCcontext *context);
|
||||
void ALCcontext_DecRef(ALCcontext *context);
|
||||
|
||||
void AppendAllDevicesList(const ALCchar *name);
|
||||
void AppendCaptureDeviceList(const ALCchar *name);
|
||||
|
||||
void ALCdevice_LockDefault(ALCdevice *device);
|
||||
void ALCdevice_UnlockDefault(ALCdevice *device);
|
||||
ALint64 ALCdevice_GetLatencyDefault(ALCdevice *device);
|
||||
|
||||
static __inline void LockContext(ALCcontext *context)
|
||||
{ ALCdevice_Lock(context->Device); }
|
||||
static __inline void UnlockContext(ALCcontext *context)
|
||||
{ ALCdevice_Unlock(context->Device); }
|
||||
|
||||
|
||||
void *al_malloc(size_t alignment, size_t size);
|
||||
void *al_calloc(size_t alignment, size_t size);
|
||||
void al_free(void *ptr);
|
||||
|
||||
typedef struct {
|
||||
int state;
|
||||
#ifdef HAVE_SSE
|
||||
int sse_state;
|
||||
#endif
|
||||
} FPUCtl;
|
||||
void SetMixerFPUMode(FPUCtl *ctl);
|
||||
void RestoreFPUMode(const FPUCtl *ctl);
|
||||
|
||||
ALvoid *StartThread(ALuint (*func)(ALvoid*), ALvoid *ptr);
|
||||
ALuint StopThread(ALvoid *thread);
|
||||
@@ -206,9 +756,126 @@ void ReadRingBuffer(RingBuffer *ring, ALubyte *data, ALsizei len);
|
||||
|
||||
void ReadALConfig(void);
|
||||
void FreeALConfig(void);
|
||||
int ConfigValueExists(const char *blockName, const char *keyName);
|
||||
const char *GetConfigValue(const char *blockName, const char *keyName, const char *def);
|
||||
int GetConfigValueInt(const char *blockName, const char *keyName, int def);
|
||||
float GetConfigValueFloat(const char *blockName, const char *keyName, float def);
|
||||
int GetConfigValueBool(const char *blockName, const char *keyName, int def);
|
||||
int ConfigValueStr(const char *blockName, const char *keyName, const char **ret);
|
||||
int ConfigValueInt(const char *blockName, const char *keyName, int *ret);
|
||||
int ConfigValueUInt(const char *blockName, const char *keyName, unsigned int *ret);
|
||||
int ConfigValueFloat(const char *blockName, const char *keyName, float *ret);
|
||||
|
||||
void SetRTPriority(void);
|
||||
|
||||
void SetDefaultChannelOrder(ALCdevice *device);
|
||||
void SetDefaultWFXChannelOrder(ALCdevice *device);
|
||||
|
||||
const ALCchar *DevFmtTypeString(enum DevFmtType type);
|
||||
const ALCchar *DevFmtChannelsString(enum DevFmtChannels chans);
|
||||
|
||||
#define HRIR_BITS (7)
|
||||
#define HRIR_LENGTH (1<<HRIR_BITS)
|
||||
#define HRIR_MASK (HRIR_LENGTH-1)
|
||||
#define HRTFDELAY_BITS (20)
|
||||
#define HRTFDELAY_FRACONE (1<<HRTFDELAY_BITS)
|
||||
#define HRTFDELAY_MASK (HRTFDELAY_FRACONE-1)
|
||||
const struct Hrtf *GetHrtf(ALCdevice *device);
|
||||
void FreeHrtfs(void);
|
||||
ALuint GetHrtfIrSize (const struct Hrtf *Hrtf);
|
||||
ALfloat CalcHrtfDelta(ALfloat oldGain, ALfloat newGain, const ALfloat olddir[3], const ALfloat newdir[3]);
|
||||
void GetLerpedHrtfCoeffs(const struct Hrtf *Hrtf, ALfloat elevation, ALfloat azimuth, ALfloat gain, ALfloat (*coeffs)[2], ALuint *delays);
|
||||
ALuint GetMovingHrtfCoeffs(const struct Hrtf *Hrtf, ALfloat elevation, ALfloat azimuth, ALfloat gain, ALfloat delta, ALint counter, ALfloat (*coeffs)[2], ALuint *delays, ALfloat (*coeffStep)[2], ALint *delayStep);
|
||||
|
||||
void al_print(const char *type, const char *func, const char *fmt, ...) PRINTF_STYLE(3,4);
|
||||
#define AL_PRINT(T, ...) al_print((T), __FUNCTION__, __VA_ARGS__)
|
||||
|
||||
extern FILE *LogFile;
|
||||
enum LogLevel {
|
||||
NoLog,
|
||||
LogError,
|
||||
LogWarning,
|
||||
LogTrace,
|
||||
LogRef
|
||||
};
|
||||
extern enum LogLevel LogLevel;
|
||||
|
||||
#define TRACEREF(...) do { \
|
||||
if(LogLevel >= LogRef) \
|
||||
AL_PRINT("(--)", __VA_ARGS__); \
|
||||
} while(0)
|
||||
|
||||
#define TRACE(...) do { \
|
||||
if(LogLevel >= LogTrace) \
|
||||
AL_PRINT("(II)", __VA_ARGS__); \
|
||||
} while(0)
|
||||
|
||||
#define WARN(...) do { \
|
||||
if(LogLevel >= LogWarning) \
|
||||
AL_PRINT("(WW)", __VA_ARGS__); \
|
||||
} while(0)
|
||||
|
||||
#define ERR(...) do { \
|
||||
if(LogLevel >= LogError) \
|
||||
AL_PRINT("(EE)", __VA_ARGS__); \
|
||||
} while(0)
|
||||
|
||||
|
||||
extern ALint RTPrioLevel;
|
||||
|
||||
|
||||
extern ALuint CPUCapFlags;
|
||||
enum {
|
||||
CPU_CAP_SSE = 1<<0,
|
||||
CPU_CAP_NEON = 1<<1,
|
||||
};
|
||||
|
||||
void FillCPUCaps(ALuint capfilter);
|
||||
|
||||
|
||||
/**
|
||||
* Starts a try block. Must not be nested within another try block within the
|
||||
* same function.
|
||||
*/
|
||||
#define al_try do { \
|
||||
int _al_err=0; \
|
||||
_al_try_label: \
|
||||
if(_al_err == 0)
|
||||
/**
|
||||
* After a try or another catch block, runs the next block if the given value
|
||||
* was thrown.
|
||||
*/
|
||||
#define al_catch(val) else if(_al_err == (val))
|
||||
/**
|
||||
* After a try or catch block, runs the next block for any value thrown and not
|
||||
* caught.
|
||||
*/
|
||||
#define al_catchany() else
|
||||
/** Marks the end of the final catch (or the try) block. */
|
||||
#define al_endtry } while(0)
|
||||
|
||||
/**
|
||||
* The given integer value is "thrown" so as to be caught by a catch block.
|
||||
* Must be called in a try block within the same function. The value must not
|
||||
* be 0.
|
||||
*/
|
||||
#define al_throw(e) do { \
|
||||
_al_err = (e); \
|
||||
assert(_al_err != 0); \
|
||||
goto _al_try_label; \
|
||||
} while(0)
|
||||
/** Sets an AL error on the given context, before throwing the error code. */
|
||||
#define al_throwerr(ctx, err) do { \
|
||||
alSetError((ctx), (err)); \
|
||||
al_throw((err)); \
|
||||
} while(0)
|
||||
|
||||
/**
|
||||
* Throws an AL_INVALID_VALUE error with the given ctx if the given condition
|
||||
* is false.
|
||||
*/
|
||||
#define CHECK_VALUE(ctx, cond) do { \
|
||||
if(!(cond)) \
|
||||
al_throwerr((ctx), AL_INVALID_VALUE); \
|
||||
} while(0)
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
||||
+159
-40
@@ -1,68 +1,187 @@
|
||||
#ifndef _AL_SOURCE_H_
|
||||
#define _AL_SOURCE_H_
|
||||
|
||||
#define AL_NUM_SOURCE_PARAMS 128
|
||||
#define MAX_SENDS 4
|
||||
|
||||
#include "AL/al.h"
|
||||
#include "alMain.h"
|
||||
#include "alu.h"
|
||||
#include "alFilter.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#define SRC_HISTORY_BITS (6)
|
||||
#define SRC_HISTORY_LENGTH (1<<SRC_HISTORY_BITS)
|
||||
#define SRC_HISTORY_MASK (SRC_HISTORY_LENGTH-1)
|
||||
|
||||
extern enum Resampler DefaultResampler;
|
||||
|
||||
extern const ALsizei ResamplerPadding[ResamplerMax];
|
||||
extern const ALsizei ResamplerPrePadding[ResamplerMax];
|
||||
|
||||
|
||||
typedef struct ALbufferlistitem
|
||||
{
|
||||
ALuint buffer;
|
||||
ALuint bufferstate;
|
||||
ALuint flag;
|
||||
struct ALbuffer *buffer;
|
||||
struct ALbufferlistitem *next;
|
||||
struct ALbufferlistitem *prev;
|
||||
} ALbufferlistitem;
|
||||
|
||||
typedef struct HrtfState {
|
||||
ALboolean Moving;
|
||||
ALuint Counter;
|
||||
ALIGN(16) ALfloat History[MaxChannels][SRC_HISTORY_LENGTH];
|
||||
ALIGN(16) ALfloat Values[MaxChannels][HRIR_LENGTH][2];
|
||||
ALuint Offset;
|
||||
} HrtfState;
|
||||
|
||||
typedef struct HrtfParams {
|
||||
ALfloat Gain;
|
||||
ALfloat Dir[3];
|
||||
ALIGN(16) ALfloat Coeffs[MaxChannels][HRIR_LENGTH][2];
|
||||
ALIGN(16) ALfloat CoeffStep[HRIR_LENGTH][2];
|
||||
ALuint Delay[MaxChannels][2];
|
||||
ALint DelayStep[2];
|
||||
ALuint IrSize;
|
||||
} HrtfParams;
|
||||
|
||||
typedef struct DirectParams {
|
||||
ALfloat (*OutBuffer)[BUFFERSIZE];
|
||||
ALfloat *ClickRemoval;
|
||||
ALfloat *PendingClicks;
|
||||
|
||||
struct {
|
||||
HrtfParams Params;
|
||||
HrtfState *State;
|
||||
} Hrtf;
|
||||
|
||||
/* A mixing matrix. First subscript is the channel number of the input data
|
||||
* (regardless of channel configuration) and the second is the channel
|
||||
* target (eg. FrontLeft). Not used with HRTF. */
|
||||
ALfloat Gains[MaxChannels][MaxChannels];
|
||||
|
||||
/* A low-pass filter, using 2 chained one-pole filters. */
|
||||
FILTER iirFilter;
|
||||
ALfloat history[MaxChannels*2];
|
||||
} DirectParams;
|
||||
|
||||
typedef struct SendParams {
|
||||
struct ALeffectslot *Slot;
|
||||
|
||||
/* Gain control, which applies to all input channels to a single (mono)
|
||||
* output buffer. */
|
||||
ALfloat Gain;
|
||||
|
||||
/* A low-pass filter, using 2 chained one-pole filters. */
|
||||
FILTER iirFilter;
|
||||
ALfloat history[MaxChannels*2];
|
||||
} SendParams;
|
||||
|
||||
|
||||
typedef struct ALsource
|
||||
{
|
||||
ALfloat flPitch;
|
||||
ALfloat flGain;
|
||||
ALfloat flOuterGain;
|
||||
ALfloat flMinGain;
|
||||
ALfloat flMaxGain;
|
||||
ALfloat flInnerAngle;
|
||||
ALfloat flOuterAngle;
|
||||
ALfloat flRefDistance;
|
||||
ALfloat flMaxDistance;
|
||||
ALfloat flRollOffFactor;
|
||||
ALfloat vPosition[3];
|
||||
ALfloat vVelocity[3];
|
||||
ALfloat vOrientation[3];
|
||||
ALboolean bHeadRelative;
|
||||
ALboolean bLooping;
|
||||
/** Source properties. */
|
||||
volatile ALfloat Pitch;
|
||||
volatile ALfloat Gain;
|
||||
volatile ALfloat OuterGain;
|
||||
volatile ALfloat MinGain;
|
||||
volatile ALfloat MaxGain;
|
||||
volatile ALfloat InnerAngle;
|
||||
volatile ALfloat OuterAngle;
|
||||
volatile ALfloat RefDistance;
|
||||
volatile ALfloat MaxDistance;
|
||||
volatile ALfloat RollOffFactor;
|
||||
volatile ALfloat Position[3];
|
||||
volatile ALfloat Velocity[3];
|
||||
volatile ALfloat Orientation[3];
|
||||
volatile ALboolean HeadRelative;
|
||||
volatile ALboolean Looping;
|
||||
volatile enum DistanceModel DistanceModel;
|
||||
volatile ALboolean DirectChannels;
|
||||
|
||||
ALuint ulBufferID;
|
||||
volatile ALboolean DryGainHFAuto;
|
||||
volatile ALboolean WetGainAuto;
|
||||
volatile ALboolean WetGainHFAuto;
|
||||
volatile ALfloat OuterGainHF;
|
||||
|
||||
ALboolean inuse;
|
||||
ALboolean play;
|
||||
ALenum state;
|
||||
ALuint position;
|
||||
ALuint position_fraction;
|
||||
struct ALbufferlistitem *queue; // Linked list of buffers in queue
|
||||
ALuint BuffersInQueue; // Number of buffers in queue
|
||||
ALuint BuffersProcessed; // Number of buffers already processed (played)
|
||||
volatile ALfloat AirAbsorptionFactor;
|
||||
volatile ALfloat RoomRolloffFactor;
|
||||
volatile ALfloat DopplerFactor;
|
||||
|
||||
ALuint TotalBufferDataSize; // Total amount of data contained in the buffers queued for this source
|
||||
ALuint BuffersPlayed; // Number of buffers played on this loop
|
||||
ALuint BufferPosition; // Read position in audio data of current buffer
|
||||
enum Resampler Resampler;
|
||||
|
||||
// Index to itself
|
||||
ALuint source;
|
||||
/**
|
||||
* Last user-specified offset, and the offset type (bytes, samples, or
|
||||
* seconds).
|
||||
*/
|
||||
ALdouble Offset;
|
||||
ALenum OffsetType;
|
||||
|
||||
ALint lBytesPlayed;
|
||||
/** Source type (static, streaming, or undetermined) */
|
||||
volatile ALint SourceType;
|
||||
|
||||
ALint lOffset;
|
||||
ALint lOffsetType;
|
||||
/** Source state (initial, playing, paused, or stopped) */
|
||||
volatile ALenum state;
|
||||
ALenum new_state;
|
||||
|
||||
// Source Type (Static, Streaming, or Undetermined)
|
||||
ALint lSourceType;
|
||||
/**
|
||||
* Source offset in samples, relative to the currently playing buffer, NOT
|
||||
* the whole queue, and the fractional (fixed-point) offset to the next
|
||||
* sample.
|
||||
*/
|
||||
ALuint position;
|
||||
ALuint position_fraction;
|
||||
|
||||
struct ALsource *next;
|
||||
/** Source Buffer Queue info. */
|
||||
ALbufferlistitem *queue;
|
||||
ALuint BuffersInQueue;
|
||||
ALuint BuffersPlayed;
|
||||
|
||||
/** Current buffer sample info. */
|
||||
ALuint NumChannels;
|
||||
ALuint SampleSize;
|
||||
|
||||
/** Direct filter and auxiliary send info. */
|
||||
ALfloat DirectGain;
|
||||
ALfloat DirectGainHF;
|
||||
|
||||
struct {
|
||||
struct ALeffectslot *Slot;
|
||||
ALfloat Gain;
|
||||
ALfloat GainHF;
|
||||
} Send[MAX_SENDS];
|
||||
|
||||
/** HRTF info. */
|
||||
HrtfState Hrtf;
|
||||
|
||||
/** Current target parameters used for mixing. */
|
||||
struct {
|
||||
ResamplerFunc Resample;
|
||||
DryMixerFunc DryMix;
|
||||
WetMixerFunc WetMix;
|
||||
|
||||
ALint Step;
|
||||
|
||||
DirectParams Direct;
|
||||
|
||||
SendParams Send[MAX_SENDS];
|
||||
} Params;
|
||||
/** Source needs to update its mixing parameters. */
|
||||
volatile ALenum NeedsUpdate;
|
||||
|
||||
/** Method to update mixing parameters. */
|
||||
ALvoid (*Update)(struct ALsource *self, const ALCcontext *context);
|
||||
|
||||
/** Self ID */
|
||||
ALuint id;
|
||||
} ALsource;
|
||||
#define ALsource_Update(s,a) ((s)->Update(s,a))
|
||||
|
||||
ALvoid SetSourceState(ALsource *Source, ALCcontext *Context, ALenum state);
|
||||
ALboolean ApplyOffset(ALsource *Source);
|
||||
|
||||
ALvoid ReleaseALSources(ALCcontext *Context);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
||||
@@ -1,14 +0,0 @@
|
||||
#ifndef _AL_STATE_H_
|
||||
#define _AL_STATE_H_
|
||||
|
||||
#include "AL/al.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
@@ -1,42 +1,20 @@
|
||||
#ifndef _AL_THUNK_H_
|
||||
#define _AL_THUNK_H_
|
||||
#ifndef ALTHUNK_H
|
||||
#define ALTHUNK_H
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include "AL/al.h"
|
||||
#include "AL/alc.h"
|
||||
#include "alMain.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
void alThunkInit(void);
|
||||
void alThunkExit(void);
|
||||
ALuint alThunkAddEntry(ALvoid * ptr);
|
||||
void alThunkRemoveEntry(ALuint index);
|
||||
ALvoid *alThunkLookupEntry(ALuint index);
|
||||
|
||||
#if (SIZEOF_VOIDP > SIZEOF_UINT)
|
||||
|
||||
#define ALTHUNK_INIT() alThunkInit()
|
||||
#define ALTHUNK_EXIT() alThunkExit()
|
||||
#define ALTHUNK_ADDENTRY(p) alThunkAddEntry(p)
|
||||
#define ALTHUNK_REMOVEENTRY(i) alThunkRemoveEntry(i)
|
||||
#define ALTHUNK_LOOKUPENTRY(i) alThunkLookupEntry(i)
|
||||
|
||||
#else
|
||||
|
||||
#define ALTHUNK_INIT()
|
||||
#define ALTHUNK_EXIT()
|
||||
#define ALTHUNK_ADDENTRY(p) ((ALuint)p)
|
||||
#define ALTHUNK_REMOVEENTRY(i)
|
||||
#define ALTHUNK_LOOKUPENTRY(i) ((ALvoid*)(i))
|
||||
|
||||
#endif // (SIZEOF_VOIDP > SIZEOF_INT)
|
||||
void ThunkInit(void);
|
||||
void ThunkExit(void);
|
||||
ALenum NewThunkEntry(ALuint *index);
|
||||
void FreeThunkEntry(ALuint index);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif //_AL_THUNK_H_
|
||||
#endif //ALTHUNK_H
|
||||
|
||||
|
||||
+112
-5
@@ -1,16 +1,123 @@
|
||||
#ifndef _ALU_H_
|
||||
#define _ALU_H_
|
||||
|
||||
#include "AL/al.h"
|
||||
#include "AL/alc.h"
|
||||
#include "alMain.h"
|
||||
|
||||
#include <limits.h>
|
||||
#include <math.h>
|
||||
#ifdef HAVE_FLOAT_H
|
||||
#include <float.h>
|
||||
#endif
|
||||
#ifdef HAVE_IEEEFP_H
|
||||
#include <ieeefp.h>
|
||||
#endif
|
||||
|
||||
|
||||
#define F_PI (3.14159265358979323846f) /* pi */
|
||||
#define F_PI_2 (1.57079632679489661923f) /* pi/2 */
|
||||
|
||||
#ifndef FLT_EPSILON
|
||||
#define FLT_EPSILON (1.19209290e-07f)
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
__inline ALuint aluBytesFromFormat(ALenum format);
|
||||
__inline ALuint aluChannelsFromFormat(ALenum format);
|
||||
ALvoid aluMixData(ALCcontext *context,ALvoid *buffer,ALsizei size,ALenum format);
|
||||
struct ALsource;
|
||||
struct ALbuffer;
|
||||
struct DirectParams;
|
||||
struct SendParams;
|
||||
|
||||
typedef void (*ResamplerFunc)(const ALfloat *src, ALuint frac, ALuint increment,
|
||||
ALfloat *RESTRICT dst, ALuint dstlen);
|
||||
|
||||
typedef ALvoid (*DryMixerFunc)(const struct DirectParams *params,
|
||||
const ALfloat *RESTRICT data, ALuint srcchan,
|
||||
ALuint OutPos, ALuint SamplesToDo,
|
||||
ALuint BufferSize);
|
||||
typedef ALvoid (*WetMixerFunc)(const struct SendParams *params,
|
||||
const ALfloat *RESTRICT data,
|
||||
ALuint OutPos, ALuint SamplesToDo,
|
||||
ALuint BufferSize);
|
||||
|
||||
|
||||
#define SPEEDOFSOUNDMETRESPERSEC (343.3f)
|
||||
#define AIRABSORBGAINHF (0.99426f) /* -0.05dB */
|
||||
|
||||
#define FRACTIONBITS (14)
|
||||
#define FRACTIONONE (1<<FRACTIONBITS)
|
||||
#define FRACTIONMASK (FRACTIONONE-1)
|
||||
|
||||
|
||||
static __inline ALfloat minf(ALfloat a, ALfloat b)
|
||||
{ return ((a > b) ? b : a); }
|
||||
static __inline ALfloat maxf(ALfloat a, ALfloat b)
|
||||
{ return ((a > b) ? a : b); }
|
||||
static __inline ALfloat clampf(ALfloat val, ALfloat min, ALfloat max)
|
||||
{ return minf(max, maxf(min, val)); }
|
||||
|
||||
static __inline ALuint minu(ALuint a, ALuint b)
|
||||
{ return ((a > b) ? b : a); }
|
||||
static __inline ALuint maxu(ALuint a, ALuint b)
|
||||
{ return ((a > b) ? a : b); }
|
||||
static __inline ALuint clampu(ALuint val, ALuint min, ALuint max)
|
||||
{ return minu(max, maxu(min, val)); }
|
||||
|
||||
static __inline ALint mini(ALint a, ALint b)
|
||||
{ return ((a > b) ? b : a); }
|
||||
static __inline ALint maxi(ALint a, ALint b)
|
||||
{ return ((a > b) ? a : b); }
|
||||
static __inline ALint clampi(ALint val, ALint min, ALint max)
|
||||
{ return mini(max, maxi(min, val)); }
|
||||
|
||||
static __inline ALint64 mini64(ALint64 a, ALint64 b)
|
||||
{ return ((a > b) ? b : a); }
|
||||
static __inline ALint64 maxi64(ALint64 a, ALint64 b)
|
||||
{ return ((a > b) ? a : b); }
|
||||
static __inline ALint64 clampi64(ALint64 val, ALint64 min, ALint64 max)
|
||||
{ return mini64(max, maxi64(min, val)); }
|
||||
|
||||
static __inline ALuint64 minu64(ALuint64 a, ALuint64 b)
|
||||
{ return ((a > b) ? b : a); }
|
||||
static __inline ALuint64 maxu64(ALuint64 a, ALuint64 b)
|
||||
{ return ((a > b) ? a : b); }
|
||||
static __inline ALuint64 clampu64(ALuint64 val, ALuint64 min, ALuint64 max)
|
||||
{ return minu64(max, maxu64(min, val)); }
|
||||
|
||||
|
||||
static __inline ALfloat lerp(ALfloat val1, ALfloat val2, ALfloat mu)
|
||||
{
|
||||
return val1 + (val2-val1)*mu;
|
||||
}
|
||||
static __inline ALfloat cubic(ALfloat val0, ALfloat val1, ALfloat val2, ALfloat val3, ALfloat mu)
|
||||
{
|
||||
ALfloat mu2 = mu*mu;
|
||||
ALfloat a0 = -0.5f*val0 + 1.5f*val1 + -1.5f*val2 + 0.5f*val3;
|
||||
ALfloat a1 = val0 + -2.5f*val1 + 2.0f*val2 + -0.5f*val3;
|
||||
ALfloat a2 = -0.5f*val0 + 0.5f*val2;
|
||||
ALfloat a3 = val1;
|
||||
|
||||
return a0*mu*mu2 + a1*mu2 + a2*mu + a3;
|
||||
}
|
||||
|
||||
|
||||
ALvoid aluInitPanning(ALCdevice *Device);
|
||||
|
||||
ALvoid ComputeAngleGains(const ALCdevice *device, ALfloat angle, ALfloat hwidth, ALfloat ingain, ALfloat *gains);
|
||||
|
||||
ALvoid CalcSourceParams(struct ALsource *ALSource, const ALCcontext *ALContext);
|
||||
ALvoid CalcNonAttnSourceParams(struct ALsource *ALSource, const ALCcontext *ALContext);
|
||||
|
||||
ALvoid MixSource(struct ALsource *Source, ALCdevice *Device, ALuint SamplesToDo);
|
||||
|
||||
ALvoid aluMixData(ALCdevice *device, ALvoid *buffer, ALsizei size);
|
||||
/* Caller must lock the device. */
|
||||
ALvoid aluHandleDisconnect(ALCdevice *device);
|
||||
|
||||
extern ALfloat ConeScale;
|
||||
extern ALfloat ZScale;
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
||||
+106
-109
@@ -1,109 +1,106 @@
|
||||
/*-
|
||||
* Copyright (c) 2005 Boris Mikhaylov
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining
|
||||
* a copy of this software and associated documentation files (the
|
||||
* "Software"), to deal in the Software without restriction, including
|
||||
* without limitation the rights to use, copy, modify, merge, publish,
|
||||
* distribute, sublicense, and/or sell copies of the Software, and to
|
||||
* permit persons to whom the Software is furnished to do so, subject to
|
||||
* the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be
|
||||
* included in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
||||
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef BS2B_H
|
||||
#define BS2B_H
|
||||
|
||||
/* Number of crossfeed levels */
|
||||
#define BS2B_CLEVELS 3
|
||||
|
||||
/* Normal crossfeed levels */
|
||||
#define BS2B_HIGH_CLEVEL 3
|
||||
#define BS2B_MIDDLE_CLEVEL 2
|
||||
#define BS2B_LOW_CLEVEL 1
|
||||
|
||||
/* Easy crossfeed levels */
|
||||
#define BS2B_HIGH_ECLEVEL BS2B_HIGH_CLEVEL + BS2B_CLEVELS
|
||||
#define BS2B_MIDDLE_ECLEVEL BS2B_MIDDLE_CLEVEL + BS2B_CLEVELS
|
||||
#define BS2B_LOW_ECLEVEL BS2B_LOW_CLEVEL + BS2B_CLEVELS
|
||||
|
||||
/* Default crossfeed levels */
|
||||
#define BS2B_DEFAULT_CLEVEL BS2B_HIGH_ECLEVEL
|
||||
/* Default sample rate (Hz) */
|
||||
#define BS2B_DEFAULT_SRATE 44100
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif /* __cplusplus */
|
||||
|
||||
struct bs2b {
|
||||
int level; /* Crossfeed level */
|
||||
int srate; /* Sample rate (Hz) */
|
||||
|
||||
/* Lowpass IIR filter coefficients */
|
||||
double a0_lo;
|
||||
double b1_lo;
|
||||
|
||||
/* Highboost IIR filter coefficients */
|
||||
double a0_hi;
|
||||
double a1_hi;
|
||||
double b1_hi;
|
||||
|
||||
/* Global gain against overloading */
|
||||
double gain;
|
||||
|
||||
/* Buffer of last filtered sample.
|
||||
* [0] - first channel, [1] - second channel
|
||||
*/
|
||||
struct t_last_sample {
|
||||
double asis[2];
|
||||
double lo[2];
|
||||
double hi[2];
|
||||
} last_sample;
|
||||
};
|
||||
|
||||
/* Clear buffers and set new coefficients with new crossfeed level value.
|
||||
* level - crossfeed level of *LEVEL values.
|
||||
*/
|
||||
void bs2b_set_level(struct bs2b *bs2b, int level);
|
||||
|
||||
/* Return current crossfeed level value */
|
||||
int bs2b_get_level(struct bs2b *bs2b);
|
||||
|
||||
/* Clear buffers and set new coefficients with new sample rate value.
|
||||
* srate - sample rate by Hz.
|
||||
*/
|
||||
void bs2b_set_srate(struct bs2b *bs2b, int srate);
|
||||
|
||||
/* Return current sample rate value */
|
||||
int bs2b_get_srate(struct bs2b *bs2b);
|
||||
|
||||
/* Clear buffer */
|
||||
void bs2b_clear(struct bs2b *bs2b);
|
||||
|
||||
/* Return 1 if buffer is clear */
|
||||
int bs2b_is_clear(struct bs2b *bs2b);
|
||||
|
||||
/* Crossfeeds one stereo sample that are pointed by sample.
|
||||
* [0] - first channel, [1] - second channel.
|
||||
* Returns crossfided samle by sample pointer.
|
||||
*/
|
||||
|
||||
/* sample poits to floats */
|
||||
void bs2b_cross_feed(struct bs2b *bs2b, float *sample);
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /* extern "C" */
|
||||
#endif /* __cplusplus */
|
||||
|
||||
#endif /* BS2B_H */
|
||||
/*-
|
||||
* Copyright (c) 2005 Boris Mikhaylov
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining
|
||||
* a copy of this software and associated documentation files (the
|
||||
* "Software"), to deal in the Software without restriction, including
|
||||
* without limitation the rights to use, copy, modify, merge, publish,
|
||||
* distribute, sublicense, and/or sell copies of the Software, and to
|
||||
* permit persons to whom the Software is furnished to do so, subject to
|
||||
* the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be
|
||||
* included in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
||||
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef BS2B_H
|
||||
#define BS2B_H
|
||||
|
||||
/* Number of crossfeed levels */
|
||||
#define BS2B_CLEVELS 3
|
||||
|
||||
/* Normal crossfeed levels */
|
||||
#define BS2B_HIGH_CLEVEL 3
|
||||
#define BS2B_MIDDLE_CLEVEL 2
|
||||
#define BS2B_LOW_CLEVEL 1
|
||||
|
||||
/* Easy crossfeed levels */
|
||||
#define BS2B_HIGH_ECLEVEL BS2B_HIGH_CLEVEL + BS2B_CLEVELS
|
||||
#define BS2B_MIDDLE_ECLEVEL BS2B_MIDDLE_CLEVEL + BS2B_CLEVELS
|
||||
#define BS2B_LOW_ECLEVEL BS2B_LOW_CLEVEL + BS2B_CLEVELS
|
||||
|
||||
/* Default crossfeed levels */
|
||||
#define BS2B_DEFAULT_CLEVEL BS2B_HIGH_ECLEVEL
|
||||
/* Default sample rate (Hz) */
|
||||
#define BS2B_DEFAULT_SRATE 44100
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif /* __cplusplus */
|
||||
|
||||
struct bs2b {
|
||||
int level; /* Crossfeed level */
|
||||
int srate; /* Sample rate (Hz) */
|
||||
|
||||
/* Lowpass IIR filter coefficients */
|
||||
double a0_lo;
|
||||
double b1_lo;
|
||||
|
||||
/* Highboost IIR filter coefficients */
|
||||
double a0_hi;
|
||||
double a1_hi;
|
||||
double b1_hi;
|
||||
|
||||
/* Global gain against overloading */
|
||||
float gain;
|
||||
|
||||
/* Buffer of last filtered sample.
|
||||
* [0] - first channel, [1] - second channel
|
||||
*/
|
||||
struct t_last_sample {
|
||||
double asis[2];
|
||||
double lo[2];
|
||||
double hi[2];
|
||||
} last_sample;
|
||||
};
|
||||
|
||||
/* Clear buffers and set new coefficients with new crossfeed level value.
|
||||
* level - crossfeed level of *LEVEL values.
|
||||
*/
|
||||
void bs2b_set_level(struct bs2b *bs2b, int level);
|
||||
|
||||
/* Return current crossfeed level value */
|
||||
int bs2b_get_level(struct bs2b *bs2b);
|
||||
|
||||
/* Clear buffers and set new coefficients with new sample rate value.
|
||||
* srate - sample rate by Hz.
|
||||
*/
|
||||
void bs2b_set_srate(struct bs2b *bs2b, int srate);
|
||||
|
||||
/* Return current sample rate value */
|
||||
int bs2b_get_srate(struct bs2b *bs2b);
|
||||
|
||||
/* Clear buffer */
|
||||
void bs2b_clear(struct bs2b *bs2b);
|
||||
|
||||
/* Crossfeeds one stereo sample that are pointed by sample.
|
||||
* [0] - first channel, [1] - second channel.
|
||||
* Returns crossfided samle by sample pointer.
|
||||
*/
|
||||
|
||||
/* sample poits to floats */
|
||||
void bs2b_cross_feed(struct bs2b *bs2b, float *sample);
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /* extern "C" */
|
||||
#endif /* __cplusplus */
|
||||
|
||||
#endif /* BS2B_H */
|
||||
|
||||
@@ -1,63 +0,0 @@
|
||||
/**
|
||||
* OpenAL cross platform audio library
|
||||
* Copyright (C) 1999-2007 by authors.
|
||||
* 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., 59 Temple Place - Suite 330,
|
||||
* Boston, MA 02111-1307, USA.
|
||||
* Or go to http://www.gnu.org/copyleft/lgpl.html
|
||||
*/
|
||||
|
||||
#include "alMain.h"
|
||||
#include "alBuffer.h"
|
||||
#include "alThunk.h"
|
||||
|
||||
CRITICAL_SECTION _alMutex;
|
||||
|
||||
#ifdef _WIN32
|
||||
BOOL APIENTRY DllMain(HANDLE hModule,DWORD ul_reason_for_call,LPVOID lpReserved)
|
||||
{
|
||||
(void)lpReserved;
|
||||
|
||||
// Perform actions based on the reason for calling.
|
||||
switch(ul_reason_for_call)
|
||||
{
|
||||
case DLL_PROCESS_ATTACH:
|
||||
DisableThreadLibraryCalls(hModule);
|
||||
break;
|
||||
|
||||
case DLL_PROCESS_DETACH:
|
||||
ReleaseALBuffers();
|
||||
FreeALConfig();
|
||||
ALTHUNK_EXIT();
|
||||
DeleteCriticalSection(&_alMutex);
|
||||
break;
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
#else
|
||||
#ifdef HAVE_GCC_DESTRUCTOR
|
||||
static void my_deinit() __attribute__((destructor));
|
||||
static void my_deinit()
|
||||
{
|
||||
static ALenum once = AL_FALSE;
|
||||
if(once) return;
|
||||
once = AL_TRUE;
|
||||
|
||||
ReleaseALBuffers();
|
||||
FreeALConfig();
|
||||
ALTHUNK_EXIT();
|
||||
DeleteCriticalSection(&_alMutex);
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
@@ -0,0 +1,609 @@
|
||||
/**
|
||||
* OpenAL cross platform audio library
|
||||
* Copyright (C) 1999-2007 by authors.
|
||||
* 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., 59 Temple Place - Suite 330,
|
||||
* Boston, MA 02111-1307, USA.
|
||||
* Or go to http://www.gnu.org/copyleft/lgpl.html
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <math.h>
|
||||
|
||||
#include "AL/al.h"
|
||||
#include "AL/alc.h"
|
||||
#include "alMain.h"
|
||||
#include "alAuxEffectSlot.h"
|
||||
#include "alThunk.h"
|
||||
#include "alError.h"
|
||||
#include "alSource.h"
|
||||
|
||||
|
||||
static ALenum AddEffectSlotArray(ALCcontext *Context, ALsizei count, const ALuint *slots);
|
||||
static ALvoid RemoveEffectSlotArray(ALCcontext *Context, ALeffectslot *slot);
|
||||
|
||||
|
||||
AL_API ALvoid AL_APIENTRY alGenAuxiliaryEffectSlots(ALsizei n, ALuint *effectslots)
|
||||
{
|
||||
ALCcontext *Context;
|
||||
ALsizei cur = 0;
|
||||
|
||||
Context = GetContextRef();
|
||||
if(!Context) return;
|
||||
|
||||
al_try
|
||||
{
|
||||
ALenum err;
|
||||
|
||||
CHECK_VALUE(Context, n >= 0);
|
||||
for(cur = 0;cur < n;cur++)
|
||||
{
|
||||
ALeffectslot *slot = al_calloc(16, sizeof(ALeffectslot));
|
||||
err = AL_OUT_OF_MEMORY;
|
||||
if(!slot || (err=InitEffectSlot(slot)) != AL_NO_ERROR)
|
||||
{
|
||||
al_free(slot);
|
||||
al_throwerr(Context, err);
|
||||
break;
|
||||
}
|
||||
|
||||
err = NewThunkEntry(&slot->id);
|
||||
if(err == AL_NO_ERROR)
|
||||
err = InsertUIntMapEntry(&Context->EffectSlotMap, slot->id, slot);
|
||||
if(err != AL_NO_ERROR)
|
||||
{
|
||||
FreeThunkEntry(slot->id);
|
||||
ALeffectState_Destroy(slot->EffectState);
|
||||
al_free(slot);
|
||||
|
||||
al_throwerr(Context, err);
|
||||
}
|
||||
|
||||
effectslots[cur] = slot->id;
|
||||
}
|
||||
err = AddEffectSlotArray(Context, n, effectslots);
|
||||
if(err != AL_NO_ERROR)
|
||||
al_throwerr(Context, err);
|
||||
}
|
||||
al_catchany()
|
||||
{
|
||||
if(cur > 0)
|
||||
alDeleteAuxiliaryEffectSlots(cur, effectslots);
|
||||
}
|
||||
al_endtry;
|
||||
|
||||
ALCcontext_DecRef(Context);
|
||||
}
|
||||
|
||||
AL_API ALvoid AL_APIENTRY alDeleteAuxiliaryEffectSlots(ALsizei n, const ALuint *effectslots)
|
||||
{
|
||||
ALCcontext *Context;
|
||||
ALeffectslot *slot;
|
||||
ALsizei i;
|
||||
|
||||
Context = GetContextRef();
|
||||
if(!Context) return;
|
||||
|
||||
al_try
|
||||
{
|
||||
CHECK_VALUE(Context, n >= 0);
|
||||
for(i = 0;i < n;i++)
|
||||
{
|
||||
if((slot=LookupEffectSlot(Context, effectslots[i])) == NULL)
|
||||
al_throwerr(Context, AL_INVALID_NAME);
|
||||
if(slot->ref != 0)
|
||||
al_throwerr(Context, AL_INVALID_OPERATION);
|
||||
}
|
||||
|
||||
// All effectslots are valid
|
||||
for(i = 0;i < n;i++)
|
||||
{
|
||||
if((slot=RemoveEffectSlot(Context, effectslots[i])) == NULL)
|
||||
continue;
|
||||
FreeThunkEntry(slot->id);
|
||||
|
||||
RemoveEffectSlotArray(Context, slot);
|
||||
ALeffectState_Destroy(slot->EffectState);
|
||||
|
||||
memset(slot, 0, sizeof(*slot));
|
||||
al_free(slot);
|
||||
}
|
||||
}
|
||||
al_endtry;
|
||||
|
||||
ALCcontext_DecRef(Context);
|
||||
}
|
||||
|
||||
AL_API ALboolean AL_APIENTRY alIsAuxiliaryEffectSlot(ALuint effectslot)
|
||||
{
|
||||
ALCcontext *Context;
|
||||
ALboolean result;
|
||||
|
||||
Context = GetContextRef();
|
||||
if(!Context) return AL_FALSE;
|
||||
|
||||
result = (LookupEffectSlot(Context, effectslot) ? AL_TRUE : AL_FALSE);
|
||||
|
||||
ALCcontext_DecRef(Context);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
AL_API ALvoid AL_APIENTRY alAuxiliaryEffectSloti(ALuint effectslot, ALenum param, ALint value)
|
||||
{
|
||||
ALCcontext *Context;
|
||||
ALeffectslot *Slot;
|
||||
ALeffect *effect = NULL;
|
||||
ALenum err;
|
||||
|
||||
Context = GetContextRef();
|
||||
if(!Context) return;
|
||||
|
||||
al_try
|
||||
{
|
||||
ALCdevice *device = Context->Device;
|
||||
if((Slot=LookupEffectSlot(Context, effectslot)) == NULL)
|
||||
al_throwerr(Context, AL_INVALID_NAME);
|
||||
switch(param)
|
||||
{
|
||||
case AL_EFFECTSLOT_EFFECT:
|
||||
CHECK_VALUE(Context, value == 0 || (effect=LookupEffect(device, value)) != NULL);
|
||||
|
||||
err = InitializeEffect(device, Slot, effect);
|
||||
if(err != AL_NO_ERROR)
|
||||
al_throwerr(Context, err);
|
||||
Context->UpdateSources = AL_TRUE;
|
||||
break;
|
||||
|
||||
case AL_EFFECTSLOT_AUXILIARY_SEND_AUTO:
|
||||
CHECK_VALUE(Context, value == AL_TRUE || value == AL_FALSE);
|
||||
|
||||
Slot->AuxSendAuto = value;
|
||||
Context->UpdateSources = AL_TRUE;
|
||||
break;
|
||||
|
||||
default:
|
||||
al_throwerr(Context, AL_INVALID_ENUM);
|
||||
}
|
||||
}
|
||||
al_endtry;
|
||||
|
||||
ALCcontext_DecRef(Context);
|
||||
}
|
||||
|
||||
AL_API ALvoid AL_APIENTRY alAuxiliaryEffectSlotiv(ALuint effectslot, ALenum param, const ALint *values)
|
||||
{
|
||||
ALCcontext *Context;
|
||||
|
||||
switch(param)
|
||||
{
|
||||
case AL_EFFECTSLOT_EFFECT:
|
||||
case AL_EFFECTSLOT_AUXILIARY_SEND_AUTO:
|
||||
alAuxiliaryEffectSloti(effectslot, param, values[0]);
|
||||
return;
|
||||
}
|
||||
|
||||
Context = GetContextRef();
|
||||
if(!Context) return;
|
||||
|
||||
al_try
|
||||
{
|
||||
if(LookupEffectSlot(Context, effectslot) == NULL)
|
||||
al_throwerr(Context, AL_INVALID_NAME);
|
||||
switch(param)
|
||||
{
|
||||
default:
|
||||
al_throwerr(Context, AL_INVALID_ENUM);
|
||||
}
|
||||
}
|
||||
al_endtry;
|
||||
|
||||
ALCcontext_DecRef(Context);
|
||||
}
|
||||
|
||||
AL_API ALvoid AL_APIENTRY alAuxiliaryEffectSlotf(ALuint effectslot, ALenum param, ALfloat value)
|
||||
{
|
||||
ALCcontext *Context;
|
||||
ALeffectslot *Slot;
|
||||
|
||||
Context = GetContextRef();
|
||||
if(!Context) return;
|
||||
|
||||
al_try
|
||||
{
|
||||
if((Slot=LookupEffectSlot(Context, effectslot)) == NULL)
|
||||
al_throwerr(Context, AL_INVALID_NAME);
|
||||
switch(param)
|
||||
{
|
||||
case AL_EFFECTSLOT_GAIN:
|
||||
CHECK_VALUE(Context, value >= 0.0f && value <= 1.0f);
|
||||
|
||||
Slot->Gain = value;
|
||||
Slot->NeedsUpdate = AL_TRUE;
|
||||
break;
|
||||
|
||||
default:
|
||||
al_throwerr(Context, AL_INVALID_ENUM);
|
||||
}
|
||||
}
|
||||
al_endtry;
|
||||
|
||||
ALCcontext_DecRef(Context);
|
||||
}
|
||||
|
||||
AL_API ALvoid AL_APIENTRY alAuxiliaryEffectSlotfv(ALuint effectslot, ALenum param, const ALfloat *values)
|
||||
{
|
||||
ALCcontext *Context;
|
||||
|
||||
switch(param)
|
||||
{
|
||||
case AL_EFFECTSLOT_GAIN:
|
||||
alAuxiliaryEffectSlotf(effectslot, param, values[0]);
|
||||
return;
|
||||
}
|
||||
|
||||
Context = GetContextRef();
|
||||
if(!Context) return;
|
||||
|
||||
al_try
|
||||
{
|
||||
if(LookupEffectSlot(Context, effectslot) == NULL)
|
||||
al_throwerr(Context, AL_INVALID_NAME);
|
||||
switch(param)
|
||||
{
|
||||
default:
|
||||
al_throwerr(Context, AL_INVALID_ENUM);
|
||||
}
|
||||
}
|
||||
al_endtry;
|
||||
|
||||
ALCcontext_DecRef(Context);
|
||||
}
|
||||
|
||||
AL_API ALvoid AL_APIENTRY alGetAuxiliaryEffectSloti(ALuint effectslot, ALenum param, ALint *value)
|
||||
{
|
||||
ALCcontext *Context;
|
||||
ALeffectslot *Slot;
|
||||
|
||||
Context = GetContextRef();
|
||||
if(!Context) return;
|
||||
|
||||
al_try
|
||||
{
|
||||
if((Slot=LookupEffectSlot(Context, effectslot)) == NULL)
|
||||
al_throwerr(Context, AL_INVALID_NAME);
|
||||
switch(param)
|
||||
{
|
||||
case AL_EFFECTSLOT_EFFECT:
|
||||
*value = Slot->effect.id;
|
||||
break;
|
||||
|
||||
case AL_EFFECTSLOT_AUXILIARY_SEND_AUTO:
|
||||
*value = Slot->AuxSendAuto;
|
||||
break;
|
||||
|
||||
default:
|
||||
al_throwerr(Context, AL_INVALID_ENUM);
|
||||
}
|
||||
}
|
||||
al_endtry;
|
||||
|
||||
ALCcontext_DecRef(Context);
|
||||
}
|
||||
|
||||
AL_API ALvoid AL_APIENTRY alGetAuxiliaryEffectSlotiv(ALuint effectslot, ALenum param, ALint *values)
|
||||
{
|
||||
ALCcontext *Context;
|
||||
|
||||
switch(param)
|
||||
{
|
||||
case AL_EFFECTSLOT_EFFECT:
|
||||
case AL_EFFECTSLOT_AUXILIARY_SEND_AUTO:
|
||||
alGetAuxiliaryEffectSloti(effectslot, param, values);
|
||||
return;
|
||||
}
|
||||
|
||||
Context = GetContextRef();
|
||||
if(!Context) return;
|
||||
|
||||
al_try
|
||||
{
|
||||
if(LookupEffectSlot(Context, effectslot) == NULL)
|
||||
al_throwerr(Context, AL_INVALID_NAME);
|
||||
switch(param)
|
||||
{
|
||||
default:
|
||||
al_throwerr(Context, AL_INVALID_ENUM);
|
||||
}
|
||||
}
|
||||
al_endtry;
|
||||
|
||||
ALCcontext_DecRef(Context);
|
||||
}
|
||||
|
||||
AL_API ALvoid AL_APIENTRY alGetAuxiliaryEffectSlotf(ALuint effectslot, ALenum param, ALfloat *value)
|
||||
{
|
||||
ALCcontext *Context;
|
||||
ALeffectslot *Slot;
|
||||
|
||||
Context = GetContextRef();
|
||||
if(!Context) return;
|
||||
|
||||
al_try
|
||||
{
|
||||
if((Slot=LookupEffectSlot(Context, effectslot)) == NULL)
|
||||
al_throwerr(Context, AL_INVALID_NAME);
|
||||
switch(param)
|
||||
{
|
||||
case AL_EFFECTSLOT_GAIN:
|
||||
*value = Slot->Gain;
|
||||
break;
|
||||
|
||||
default:
|
||||
al_throwerr(Context, AL_INVALID_ENUM);
|
||||
}
|
||||
}
|
||||
al_endtry;
|
||||
|
||||
ALCcontext_DecRef(Context);
|
||||
}
|
||||
|
||||
AL_API ALvoid AL_APIENTRY alGetAuxiliaryEffectSlotfv(ALuint effectslot, ALenum param, ALfloat *values)
|
||||
{
|
||||
ALCcontext *Context;
|
||||
|
||||
switch(param)
|
||||
{
|
||||
case AL_EFFECTSLOT_GAIN:
|
||||
alGetAuxiliaryEffectSlotf(effectslot, param, values);
|
||||
return;
|
||||
}
|
||||
|
||||
Context = GetContextRef();
|
||||
if(!Context) return;
|
||||
|
||||
al_try
|
||||
{
|
||||
if(LookupEffectSlot(Context, effectslot) == NULL)
|
||||
al_throwerr(Context, AL_INVALID_NAME);
|
||||
switch(param)
|
||||
{
|
||||
default:
|
||||
al_throwerr(Context, AL_INVALID_ENUM);
|
||||
}
|
||||
}
|
||||
al_endtry;
|
||||
|
||||
ALCcontext_DecRef(Context);
|
||||
}
|
||||
|
||||
|
||||
static ALvoid NoneDestroy(ALeffectState *State)
|
||||
{ free(State); }
|
||||
static ALboolean NoneDeviceUpdate(ALeffectState *State, ALCdevice *Device)
|
||||
{
|
||||
return AL_TRUE;
|
||||
(void)State;
|
||||
(void)Device;
|
||||
}
|
||||
static ALvoid NoneUpdate(ALeffectState *State, ALCdevice *Device, const ALeffectslot *Slot)
|
||||
{
|
||||
(void)State;
|
||||
(void)Device;
|
||||
(void)Slot;
|
||||
}
|
||||
static ALvoid NoneProcess(ALeffectState *State, ALuint SamplesToDo, const ALfloat *RESTRICT SamplesIn, ALfloat (*RESTRICT SamplesOut)[BUFFERSIZE])
|
||||
{
|
||||
(void)State;
|
||||
(void)SamplesToDo;
|
||||
(void)SamplesIn;
|
||||
(void)SamplesOut;
|
||||
}
|
||||
ALeffectState *NoneCreate(void)
|
||||
{
|
||||
ALeffectState *state;
|
||||
|
||||
state = calloc(1, sizeof(*state));
|
||||
if(!state)
|
||||
return NULL;
|
||||
|
||||
state->Destroy = NoneDestroy;
|
||||
state->DeviceUpdate = NoneDeviceUpdate;
|
||||
state->Update = NoneUpdate;
|
||||
state->Process = NoneProcess;
|
||||
|
||||
return state;
|
||||
}
|
||||
|
||||
|
||||
static ALvoid RemoveEffectSlotArray(ALCcontext *Context, ALeffectslot *slot)
|
||||
{
|
||||
ALeffectslot **slotlist, **slotlistend;
|
||||
|
||||
LockContext(Context);
|
||||
slotlist = Context->ActiveEffectSlots;
|
||||
slotlistend = slotlist + Context->ActiveEffectSlotCount;
|
||||
while(slotlist != slotlistend)
|
||||
{
|
||||
if(*slotlist == slot)
|
||||
{
|
||||
*slotlist = *(--slotlistend);
|
||||
Context->ActiveEffectSlotCount--;
|
||||
break;
|
||||
}
|
||||
slotlist++;
|
||||
}
|
||||
UnlockContext(Context);
|
||||
}
|
||||
|
||||
static ALenum AddEffectSlotArray(ALCcontext *Context, ALsizei count, const ALuint *slots)
|
||||
{
|
||||
ALsizei i;
|
||||
|
||||
LockContext(Context);
|
||||
if(count > Context->MaxActiveEffectSlots-Context->ActiveEffectSlotCount)
|
||||
{
|
||||
ALsizei newcount;
|
||||
void *temp = NULL;
|
||||
|
||||
newcount = Context->MaxActiveEffectSlots ? (Context->MaxActiveEffectSlots<<1) : 1;
|
||||
if(newcount > Context->MaxActiveEffectSlots)
|
||||
temp = realloc(Context->ActiveEffectSlots,
|
||||
newcount * sizeof(*Context->ActiveEffectSlots));
|
||||
if(!temp)
|
||||
{
|
||||
UnlockContext(Context);
|
||||
return AL_OUT_OF_MEMORY;
|
||||
}
|
||||
Context->ActiveEffectSlots = temp;
|
||||
Context->MaxActiveEffectSlots = newcount;
|
||||
}
|
||||
for(i = 0;i < count;i++)
|
||||
{
|
||||
ALeffectslot *slot = LookupEffectSlot(Context, slots[i]);
|
||||
assert(slot != NULL);
|
||||
Context->ActiveEffectSlots[Context->ActiveEffectSlotCount++] = slot;
|
||||
}
|
||||
UnlockContext(Context);
|
||||
return AL_NO_ERROR;
|
||||
}
|
||||
|
||||
ALenum InitializeEffect(ALCdevice *Device, ALeffectslot *EffectSlot, ALeffect *effect)
|
||||
{
|
||||
ALenum newtype = (effect ? effect->type : AL_EFFECT_NULL);
|
||||
ALeffectState *State = NULL;
|
||||
ALenum err = AL_NO_ERROR;
|
||||
|
||||
ALCdevice_Lock(Device);
|
||||
if(newtype == AL_EFFECT_NULL && EffectSlot->effect.type != AL_EFFECT_NULL)
|
||||
{
|
||||
State = NoneCreate();
|
||||
if(!State) err = AL_OUT_OF_MEMORY;
|
||||
}
|
||||
else if(newtype == AL_EFFECT_EAXREVERB || newtype == AL_EFFECT_REVERB)
|
||||
{
|
||||
if(EffectSlot->effect.type != AL_EFFECT_EAXREVERB && EffectSlot->effect.type != AL_EFFECT_REVERB)
|
||||
{
|
||||
State = ReverbCreate();
|
||||
if(!State) err = AL_OUT_OF_MEMORY;
|
||||
}
|
||||
}
|
||||
else if(newtype == AL_EFFECT_ECHO && EffectSlot->effect.type != AL_EFFECT_ECHO)
|
||||
{
|
||||
State = EchoCreate();
|
||||
if(!State) err = AL_OUT_OF_MEMORY;
|
||||
}
|
||||
else if(newtype == AL_EFFECT_RING_MODULATOR && EffectSlot->effect.type != AL_EFFECT_RING_MODULATOR)
|
||||
{
|
||||
State = ModulatorCreate();
|
||||
if(!State) err = AL_OUT_OF_MEMORY;
|
||||
}
|
||||
else if(newtype == AL_EFFECT_DEDICATED_DIALOGUE || newtype == AL_EFFECT_DEDICATED_LOW_FREQUENCY_EFFECT)
|
||||
{
|
||||
if(EffectSlot->effect.type != AL_EFFECT_DEDICATED_DIALOGUE && EffectSlot->effect.type != AL_EFFECT_DEDICATED_LOW_FREQUENCY_EFFECT)
|
||||
{
|
||||
State = DedicatedCreate();
|
||||
if(!State) err = AL_OUT_OF_MEMORY;
|
||||
}
|
||||
}
|
||||
|
||||
if(err != AL_NO_ERROR)
|
||||
{
|
||||
ALCdevice_Unlock(Device);
|
||||
return err;
|
||||
}
|
||||
|
||||
if(State)
|
||||
{
|
||||
FPUCtl oldMode;
|
||||
SetMixerFPUMode(&oldMode);
|
||||
|
||||
if(ALeffectState_DeviceUpdate(State, Device) == AL_FALSE)
|
||||
{
|
||||
RestoreFPUMode(&oldMode);
|
||||
ALCdevice_Unlock(Device);
|
||||
ALeffectState_Destroy(State);
|
||||
return AL_OUT_OF_MEMORY;
|
||||
}
|
||||
State = ExchangePtr((XchgPtr*)&EffectSlot->EffectState, State);
|
||||
|
||||
if(!effect)
|
||||
memset(&EffectSlot->effect, 0, sizeof(EffectSlot->effect));
|
||||
else
|
||||
memcpy(&EffectSlot->effect, effect, sizeof(*effect));
|
||||
/* FIXME: This should be done asynchronously, but since the EffectState
|
||||
* object was changed, it needs an update before its Process method can
|
||||
* be called. */
|
||||
EffectSlot->NeedsUpdate = AL_FALSE;
|
||||
ALeffectState_Update(EffectSlot->EffectState, Device, EffectSlot);
|
||||
ALCdevice_Unlock(Device);
|
||||
|
||||
RestoreFPUMode(&oldMode);
|
||||
|
||||
ALeffectState_Destroy(State);
|
||||
State = NULL;
|
||||
}
|
||||
else
|
||||
{
|
||||
if(!effect)
|
||||
memset(&EffectSlot->effect, 0, sizeof(EffectSlot->effect));
|
||||
else
|
||||
memcpy(&EffectSlot->effect, effect, sizeof(*effect));
|
||||
ALCdevice_Unlock(Device);
|
||||
EffectSlot->NeedsUpdate = AL_TRUE;
|
||||
}
|
||||
|
||||
return AL_NO_ERROR;
|
||||
}
|
||||
|
||||
|
||||
ALenum InitEffectSlot(ALeffectslot *slot)
|
||||
{
|
||||
ALint i, c;
|
||||
|
||||
if(!(slot->EffectState=NoneCreate()))
|
||||
return AL_OUT_OF_MEMORY;
|
||||
|
||||
slot->Gain = 1.0;
|
||||
slot->AuxSendAuto = AL_TRUE;
|
||||
slot->NeedsUpdate = AL_FALSE;
|
||||
for(c = 0;c < 1;c++)
|
||||
{
|
||||
for(i = 0;i < BUFFERSIZE;i++)
|
||||
slot->WetBuffer[c][i] = 0.0f;
|
||||
slot->ClickRemoval[c] = 0.0f;
|
||||
slot->PendingClicks[c] = 0.0f;
|
||||
}
|
||||
slot->ref = 0;
|
||||
|
||||
return AL_NO_ERROR;
|
||||
}
|
||||
|
||||
ALvoid ReleaseALAuxiliaryEffectSlots(ALCcontext *Context)
|
||||
{
|
||||
ALsizei pos;
|
||||
for(pos = 0;pos < Context->EffectSlotMap.size;pos++)
|
||||
{
|
||||
ALeffectslot *temp = Context->EffectSlotMap.array[pos].value;
|
||||
Context->EffectSlotMap.array[pos].value = NULL;
|
||||
|
||||
ALeffectState_Destroy(temp->EffectState);
|
||||
|
||||
FreeThunkEntry(temp->id);
|
||||
memset(temp, 0, sizeof(ALeffectslot));
|
||||
al_free(temp);
|
||||
}
|
||||
}
|
||||
+1986
-841
File diff suppressed because it is too large
Load Diff
+1516
File diff suppressed because it is too large
Load Diff
+39
-25
@@ -18,40 +18,54 @@
|
||||
* Or go to http://www.gnu.org/copyleft/lgpl.html
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <signal.h>
|
||||
|
||||
#include "alMain.h"
|
||||
#include "AL/alc.h"
|
||||
#include "alError.h"
|
||||
|
||||
ALAPI ALenum ALAPIENTRY alGetError(ALvoid)
|
||||
ALboolean TrapALError = AL_FALSE;
|
||||
|
||||
ALvoid alSetError(ALCcontext *Context, ALenum errorCode)
|
||||
{
|
||||
ALCcontext *Context;
|
||||
ALenum errorCode;
|
||||
|
||||
Context = alcGetCurrentContext();
|
||||
SuspendContext(Context);
|
||||
|
||||
if (Context)
|
||||
{
|
||||
errorCode = Context->LastError;
|
||||
Context->LastError = AL_NO_ERROR;
|
||||
}
|
||||
else
|
||||
errorCode = AL_INVALID_OPERATION;
|
||||
|
||||
ProcessContext(Context);
|
||||
|
||||
return errorCode;
|
||||
if(TrapALError)
|
||||
{
|
||||
#ifdef _WIN32
|
||||
/* DebugBreak will cause an exception if there is no debugger */
|
||||
if(IsDebuggerPresent())
|
||||
DebugBreak();
|
||||
#elif defined(SIGTRAP)
|
||||
raise(SIGTRAP);
|
||||
#endif
|
||||
}
|
||||
CompExchangeInt(&Context->LastError, AL_NO_ERROR, errorCode);
|
||||
}
|
||||
|
||||
ALvoid alSetError(ALenum errorCode)
|
||||
AL_API ALenum AL_APIENTRY alGetError(void)
|
||||
{
|
||||
ALCcontext *Context;
|
||||
ALCcontext *Context;
|
||||
ALenum errorCode;
|
||||
|
||||
Context=alcGetCurrentContext();
|
||||
SuspendContext(Context);
|
||||
Context = GetContextRef();
|
||||
if(!Context)
|
||||
{
|
||||
if(TrapALError)
|
||||
{
|
||||
#ifdef _WIN32
|
||||
if(IsDebuggerPresent())
|
||||
DebugBreak();
|
||||
#elif defined(SIGTRAP)
|
||||
raise(SIGTRAP);
|
||||
#endif
|
||||
}
|
||||
return AL_INVALID_OPERATION;
|
||||
}
|
||||
|
||||
if (Context && Context->LastError == AL_NO_ERROR)
|
||||
Context->LastError = errorCode;
|
||||
errorCode = ExchangeInt(&Context->LastError, AL_NO_ERROR);
|
||||
|
||||
ProcessContext(Context);
|
||||
ALCcontext_DecRef(Context);
|
||||
|
||||
return errorCode;
|
||||
}
|
||||
|
||||
+50
-239
@@ -18,272 +18,83 @@
|
||||
* Or go to http://www.gnu.org/copyleft/lgpl.html
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <ctype.h>
|
||||
#include "alExtension.h"
|
||||
|
||||
#include "alError.h"
|
||||
#include "alMain.h"
|
||||
#include "alFilter.h"
|
||||
#include "alEffect.h"
|
||||
#include "alAuxEffectSlot.h"
|
||||
#include "alSource.h"
|
||||
#include "alBuffer.h"
|
||||
#include "AL/al.h"
|
||||
#include "AL/alc.h"
|
||||
|
||||
static ALfunction function[]= {
|
||||
{ "alEnable", (ALvoid *) alEnable },
|
||||
{ "alDisable", (ALvoid *) alDisable },
|
||||
{ "alIsEnabled", (ALvoid *) alIsEnabled },
|
||||
{ "alGetString", (ALvoid *) alGetString },
|
||||
{ "alGetBooleanv", (ALvoid *) alGetBooleanv },
|
||||
{ "alGetIntegerv", (ALvoid *) alGetIntegerv },
|
||||
{ "alGetFloatv", (ALvoid *) alGetFloatv },
|
||||
{ "alGetDoublev", (ALvoid *) alGetDoublev },
|
||||
{ "alGetBoolean", (ALvoid *) alGetBoolean },
|
||||
{ "alGetInteger", (ALvoid *) alGetInteger },
|
||||
{ "alGetFloat", (ALvoid *) alGetFloat },
|
||||
{ "alGetDouble", (ALvoid *) alGetDouble },
|
||||
{ "alGetError", (ALvoid *) alGetError },
|
||||
{ "alIsExtensionPresent", (ALvoid *) alIsExtensionPresent },
|
||||
{ "alGetProcAddress", (ALvoid *) alGetProcAddress },
|
||||
{ "alGetEnumValue", (ALvoid *) alGetEnumValue },
|
||||
{ "alListenerf", (ALvoid *) alListenerf },
|
||||
{ "alListener3f", (ALvoid *) alListener3f },
|
||||
{ "alListenerfv", (ALvoid *) alListenerfv },
|
||||
{ "alListeneri", (ALvoid *) alListeneri },
|
||||
{ "alListener3i", (ALvoid *) alListener3i },
|
||||
{ "alListeneriv", (ALvoid *) alListeneriv },
|
||||
{ "alGetListenerf", (ALvoid *) alGetListenerf },
|
||||
{ "alGetListener3f", (ALvoid *) alGetListener3f },
|
||||
{ "alGetListenerfv", (ALvoid *) alGetListenerfv },
|
||||
{ "alGetListeneri", (ALvoid *) alGetListeneri },
|
||||
{ "alGetListener3i", (ALvoid *) alGetListener3i },
|
||||
{ "alGetListeneriv", (ALvoid *) alGetListeneriv },
|
||||
{ "alGenSources", (ALvoid *) alGenSources },
|
||||
{ "alDeleteSources", (ALvoid *) alDeleteSources },
|
||||
{ "alIsSource", (ALvoid *) alIsSource },
|
||||
{ "alSourcef", (ALvoid *) alSourcef },
|
||||
{ "alSource3f", (ALvoid *) alSource3f },
|
||||
{ "alSourcefv", (ALvoid *) alSourcefv },
|
||||
{ "alSourcei", (ALvoid *) alSourcei },
|
||||
{ "alSource3i", (ALvoid *) alSource3i },
|
||||
{ "alSourceiv", (ALvoid *) alSourceiv },
|
||||
{ "alGetSourcef", (ALvoid *) alGetSourcef },
|
||||
{ "alGetSource3f", (ALvoid *) alGetSource3f },
|
||||
{ "alGetSourcefv", (ALvoid *) alGetSourcefv },
|
||||
{ "alGetSourcei", (ALvoid *) alGetSourcei },
|
||||
{ "alGetSource3i", (ALvoid *) alGetSource3i },
|
||||
{ "alGetSourceiv", (ALvoid *) alGetSourceiv },
|
||||
{ "alSourcePlayv", (ALvoid *) alSourcePlayv },
|
||||
{ "alSourceStopv", (ALvoid *) alSourceStopv },
|
||||
{ "alSourceRewindv", (ALvoid *) alSourceRewindv },
|
||||
{ "alSourcePausev", (ALvoid *) alSourcePausev },
|
||||
{ "alSourcePlay", (ALvoid *) alSourcePlay },
|
||||
{ "alSourceStop", (ALvoid *) alSourceStop },
|
||||
{ "alSourceRewind", (ALvoid *) alSourceRewind },
|
||||
{ "alSourcePause", (ALvoid *) alSourcePause },
|
||||
{ "alSourceQueueBuffers", (ALvoid *) alSourceQueueBuffers },
|
||||
{ "alSourceUnqueueBuffers", (ALvoid *) alSourceUnqueueBuffers },
|
||||
{ "alGenBuffers", (ALvoid *) alGenBuffers },
|
||||
{ "alDeleteBuffers", (ALvoid *) alDeleteBuffers },
|
||||
{ "alIsBuffer", (ALvoid *) alIsBuffer },
|
||||
{ "alBufferData", (ALvoid *) alBufferData },
|
||||
{ "alBufferf", (ALvoid *) alBufferf },
|
||||
{ "alBuffer3f", (ALvoid *) alBuffer3f },
|
||||
{ "alBufferfv", (ALvoid *) alBufferfv },
|
||||
{ "alBufferi", (ALvoid *) alBufferi },
|
||||
{ "alBuffer3i", (ALvoid *) alBuffer3i },
|
||||
{ "alBufferiv", (ALvoid *) alBufferiv },
|
||||
{ "alGetBufferf", (ALvoid *) alGetBufferf },
|
||||
{ "alGetBuffer3f", (ALvoid *) alGetBuffer3f },
|
||||
{ "alGetBufferfv", (ALvoid *) alGetBufferfv },
|
||||
{ "alGetBufferi", (ALvoid *) alGetBufferi },
|
||||
{ "alGetBuffer3i", (ALvoid *) alGetBuffer3i },
|
||||
{ "alGetBufferiv", (ALvoid *) alGetBufferiv },
|
||||
{ "alDopplerFactor", (ALvoid *) alDopplerFactor },
|
||||
{ "alDopplerVelocity", (ALvoid *) alDopplerVelocity },
|
||||
{ "alSpeedOfSound", (ALvoid *) alSpeedOfSound },
|
||||
{ "alDistanceModel", (ALvoid *) alDistanceModel },
|
||||
{ NULL, (ALvoid *) NULL } };
|
||||
|
||||
static ALenums enumeration[]={
|
||||
// Types
|
||||
{ (ALchar *)"AL_INVALID", AL_INVALID },
|
||||
{ (ALchar *)"AL_NONE", AL_NONE },
|
||||
{ (ALchar *)"AL_FALSE", AL_FALSE },
|
||||
{ (ALchar *)"AL_TRUE", AL_TRUE },
|
||||
|
||||
// Source and Listener Properties
|
||||
{ (ALchar *)"AL_SOURCE_RELATIVE", AL_SOURCE_RELATIVE },
|
||||
{ (ALchar *)"AL_CONE_INNER_ANGLE", AL_CONE_INNER_ANGLE },
|
||||
{ (ALchar *)"AL_CONE_OUTER_ANGLE", AL_CONE_OUTER_ANGLE },
|
||||
{ (ALchar *)"AL_PITCH", AL_PITCH },
|
||||
{ (ALchar *)"AL_POSITION", AL_POSITION },
|
||||
{ (ALchar *)"AL_DIRECTION", AL_DIRECTION },
|
||||
{ (ALchar *)"AL_VELOCITY", AL_VELOCITY },
|
||||
{ (ALchar *)"AL_LOOPING", AL_LOOPING },
|
||||
{ (ALchar *)"AL_BUFFER", AL_BUFFER },
|
||||
{ (ALchar *)"AL_GAIN", AL_GAIN },
|
||||
{ (ALchar *)"AL_MIN_GAIN", AL_MIN_GAIN },
|
||||
{ (ALchar *)"AL_MAX_GAIN", AL_MAX_GAIN },
|
||||
{ (ALchar *)"AL_ORIENTATION", AL_ORIENTATION },
|
||||
{ (ALchar *)"AL_REFERENCE_DISTANCE", AL_REFERENCE_DISTANCE },
|
||||
{ (ALchar *)"AL_ROLLOFF_FACTOR", AL_ROLLOFF_FACTOR },
|
||||
{ (ALchar *)"AL_CONE_OUTER_GAIN", AL_CONE_OUTER_GAIN },
|
||||
{ (ALchar *)"AL_MAX_DISTANCE", AL_MAX_DISTANCE },
|
||||
{ (ALchar *)"AL_SEC_OFFSET", AL_SEC_OFFSET },
|
||||
{ (ALchar *)"AL_SAMPLE_OFFSET", AL_SAMPLE_OFFSET },
|
||||
{ (ALchar *)"AL_BYTE_OFFSET", AL_BYTE_OFFSET },
|
||||
{ (ALchar *)"AL_SOURCE_TYPE", AL_SOURCE_TYPE },
|
||||
{ (ALchar *)"AL_STATIC", AL_STATIC },
|
||||
{ (ALchar *)"AL_STREAMING", AL_STREAMING },
|
||||
{ (ALchar *)"AL_UNDETERMINED", AL_UNDETERMINED },
|
||||
|
||||
// Source State information
|
||||
{ (ALchar *)"AL_SOURCE_STATE", AL_SOURCE_STATE },
|
||||
{ (ALchar *)"AL_INITIAL", AL_INITIAL },
|
||||
{ (ALchar *)"AL_PLAYING", AL_PLAYING },
|
||||
{ (ALchar *)"AL_PAUSED", AL_PAUSED },
|
||||
{ (ALchar *)"AL_STOPPED", AL_STOPPED },
|
||||
|
||||
// Queue information
|
||||
{ (ALchar *)"AL_BUFFERS_QUEUED", AL_BUFFERS_QUEUED },
|
||||
{ (ALchar *)"AL_BUFFERS_PROCESSED", AL_BUFFERS_PROCESSED },
|
||||
|
||||
// Buffer Formats
|
||||
{ (ALchar *)"AL_FORMAT_MONO8", AL_FORMAT_MONO8 },
|
||||
{ (ALchar *)"AL_FORMAT_MONO16", AL_FORMAT_MONO16 },
|
||||
{ (ALchar *)"AL_FORMAT_MONO_FLOAT32", AL_FORMAT_MONO_FLOAT32 },
|
||||
{ (ALchar *)"AL_FORMAT_STEREO8", AL_FORMAT_STEREO8 },
|
||||
{ (ALchar *)"AL_FORMAT_STEREO16", AL_FORMAT_STEREO16 },
|
||||
{ (ALchar *)"AL_FORMAT_STEREO_FLOAT32", AL_FORMAT_STEREO_FLOAT32 },
|
||||
{ (ALchar *)"AL_FORMAT_MONO_IMA4", AL_FORMAT_MONO_IMA4 },
|
||||
{ (ALchar *)"AL_FORMAT_STEREO_IMA4", AL_FORMAT_STEREO_IMA4 },
|
||||
{ (ALchar *)"AL_FORMAT_QUAD8", AL_FORMAT_QUAD8 },
|
||||
{ (ALchar *)"AL_FORMAT_QUAD16", AL_FORMAT_QUAD16 },
|
||||
{ (ALchar *)"AL_FORMAT_QUAD32", AL_FORMAT_QUAD32 },
|
||||
{ (ALchar *)"AL_FORMAT_51CHN8", AL_FORMAT_51CHN8 },
|
||||
{ (ALchar *)"AL_FORMAT_51CHN16", AL_FORMAT_51CHN16 },
|
||||
{ (ALchar *)"AL_FORMAT_51CHN32", AL_FORMAT_51CHN32 },
|
||||
{ (ALchar *)"AL_FORMAT_61CHN8", AL_FORMAT_61CHN8 },
|
||||
{ (ALchar *)"AL_FORMAT_61CHN16", AL_FORMAT_61CHN16 },
|
||||
{ (ALchar *)"AL_FORMAT_61CHN32", AL_FORMAT_61CHN32 },
|
||||
{ (ALchar *)"AL_FORMAT_71CHN8", AL_FORMAT_71CHN8 },
|
||||
{ (ALchar *)"AL_FORMAT_71CHN16", AL_FORMAT_71CHN16 },
|
||||
{ (ALchar *)"AL_FORMAT_71CHN32", AL_FORMAT_71CHN32 },
|
||||
{ (ALchar *)"AL_FORMAT_REAR8", AL_FORMAT_REAR8 },
|
||||
{ (ALchar *)"AL_FORMAT_REAR16", AL_FORMAT_REAR16 },
|
||||
{ (ALchar *)"AL_FORMAT_REAR32", AL_FORMAT_REAR32 },
|
||||
|
||||
// Buffer attributes
|
||||
{ (ALchar *)"AL_FREQUENCY", AL_FREQUENCY },
|
||||
{ (ALchar *)"AL_BITS", AL_BITS },
|
||||
{ (ALchar *)"AL_CHANNELS", AL_CHANNELS },
|
||||
{ (ALchar *)"AL_SIZE", AL_SIZE },
|
||||
|
||||
// Buffer States (not supported yet)
|
||||
{ (ALchar *)"AL_UNUSED", AL_UNUSED },
|
||||
{ (ALchar *)"AL_PENDING", AL_PENDING },
|
||||
{ (ALchar *)"AL_PROCESSED", AL_PROCESSED },
|
||||
|
||||
// AL Error Messages
|
||||
{ (ALchar *)"AL_NO_ERROR", AL_NO_ERROR },
|
||||
{ (ALchar *)"AL_INVALID_NAME", AL_INVALID_NAME },
|
||||
{ (ALchar *)"AL_INVALID_ENUM", AL_INVALID_ENUM },
|
||||
{ (ALchar *)"AL_INVALID_VALUE", AL_INVALID_VALUE },
|
||||
{ (ALchar *)"AL_INVALID_OPERATION", AL_INVALID_OPERATION },
|
||||
{ (ALchar *)"AL_OUT_OF_MEMORY", AL_OUT_OF_MEMORY },
|
||||
|
||||
// Context strings
|
||||
{ (ALchar *)"AL_VENDOR", AL_VENDOR },
|
||||
{ (ALchar *)"AL_VERSION", AL_VERSION },
|
||||
{ (ALchar *)"AL_RENDERER", AL_RENDERER },
|
||||
{ (ALchar *)"AL_EXTENSIONS", AL_EXTENSIONS },
|
||||
|
||||
// Global states
|
||||
{ (ALchar *)"AL_DOPPLER_FACTOR", AL_DOPPLER_FACTOR },
|
||||
{ (ALchar *)"AL_DOPPLER_VELOCITY", AL_DOPPLER_VELOCITY },
|
||||
{ (ALchar *)"AL_DISTANCE_MODEL", AL_DISTANCE_MODEL },
|
||||
{ (ALchar *)"AL_SPEED_OF_SOUND", AL_SPEED_OF_SOUND },
|
||||
|
||||
// Distance Models
|
||||
{ (ALchar *)"AL_INVERSE_DISTANCE", AL_INVERSE_DISTANCE },
|
||||
{ (ALchar *)"AL_INVERSE_DISTANCE_CLAMPED", AL_INVERSE_DISTANCE_CLAMPED },
|
||||
{ (ALchar *)"AL_LINEAR_DISTANCE", AL_LINEAR_DISTANCE },
|
||||
{ (ALchar *)"AL_LINEAR_DISTANCE_CLAMPED", AL_LINEAR_DISTANCE_CLAMPED },
|
||||
{ (ALchar *)"AL_EXPONENT_DISTANCE", AL_EXPONENT_DISTANCE },
|
||||
{ (ALchar *)"AL_EXPONENT_DISTANCE_CLAMPED", AL_EXPONENT_DISTANCE_CLAMPED },
|
||||
|
||||
// Default
|
||||
{ (ALchar *)NULL, (ALenum ) 0 } };
|
||||
const struct EffectList EffectList[] = {
|
||||
{ "eaxreverb", EAXREVERB, "AL_EFFECT_EAXREVERB", AL_EFFECT_EAXREVERB },
|
||||
{ "reverb", REVERB, "AL_EFFECT_REVERB", AL_EFFECT_REVERB },
|
||||
{ "echo", ECHO, "AL_EFFECT_ECHO", AL_EFFECT_ECHO },
|
||||
{ "modulator", MODULATOR, "AL_EFFECT_RING_MODULATOR", AL_EFFECT_RING_MODULATOR },
|
||||
{ "dedicated", DEDICATED, "AL_EFFECT_DEDICATED_LOW_FREQUENCY_EFFECT", AL_EFFECT_DEDICATED_LOW_FREQUENCY_EFFECT },
|
||||
{ "dedicated", DEDICATED, "AL_EFFECT_DEDICATED_DIALOGUE", AL_EFFECT_DEDICATED_DIALOGUE },
|
||||
{ NULL, 0, NULL, (ALenum)0 }
|
||||
};
|
||||
|
||||
|
||||
|
||||
ALAPI ALboolean ALAPIENTRY alIsExtensionPresent(const ALchar *extName)
|
||||
AL_API ALboolean AL_APIENTRY alIsExtensionPresent(const ALchar *extName)
|
||||
{
|
||||
ALboolean bIsSupported = AL_FALSE;
|
||||
ALCcontext *pContext;
|
||||
char *ptr, *ext;
|
||||
ALboolean ret = AL_FALSE;
|
||||
ALCcontext *Context;
|
||||
const char *ptr;
|
||||
size_t len;
|
||||
|
||||
if (!extName)
|
||||
Context = GetContextRef();
|
||||
if(!Context) return AL_FALSE;
|
||||
|
||||
al_try
|
||||
{
|
||||
alSetError(AL_INVALID_VALUE);
|
||||
return AL_FALSE;
|
||||
}
|
||||
CHECK_VALUE(Context, extName);
|
||||
|
||||
pContext = alcGetCurrentContext();
|
||||
if(!pContext)
|
||||
{
|
||||
alSetError(AL_INVALID_OPERATION);
|
||||
return AL_FALSE;
|
||||
}
|
||||
|
||||
ext = strdup(extName);
|
||||
ptr = ext;
|
||||
do {
|
||||
*ptr = (char)toupper(*ptr);
|
||||
} while(*(ptr++));
|
||||
|
||||
SuspendContext(pContext);
|
||||
|
||||
ptr = pContext->ExtensionList;
|
||||
while((ptr=strstr(ptr, ext)) != NULL)
|
||||
{
|
||||
if(ptr == pContext->ExtensionList || ptr[-1] == ' ')
|
||||
len = strlen(extName);
|
||||
ptr = Context->ExtensionList;
|
||||
while(ptr && *ptr)
|
||||
{
|
||||
char e = ptr[strlen(ext)];
|
||||
if(e == ' ' || e == 0)
|
||||
if(strncasecmp(ptr, extName, len) == 0 &&
|
||||
(ptr[len] == '\0' || isspace(ptr[len])))
|
||||
{
|
||||
bIsSupported = AL_TRUE;
|
||||
ret = AL_TRUE;
|
||||
break;
|
||||
}
|
||||
if((ptr=strchr(ptr, ' ')) != NULL)
|
||||
{
|
||||
do {
|
||||
++ptr;
|
||||
} while(isspace(*ptr));
|
||||
}
|
||||
}
|
||||
ptr++;
|
||||
}
|
||||
al_endtry;
|
||||
|
||||
ProcessContext(pContext);
|
||||
|
||||
free(ext);
|
||||
return bIsSupported;
|
||||
ALCcontext_DecRef(Context);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
ALAPI ALvoid * ALAPIENTRY alGetProcAddress(const ALchar *funcName)
|
||||
AL_API ALvoid* AL_APIENTRY alGetProcAddress(const ALchar *funcName)
|
||||
{
|
||||
ALsizei i = 0;
|
||||
|
||||
while(function[i].funcName &&
|
||||
strcmp((char*)function[i].funcName, (char*)funcName) != 0)
|
||||
i++;
|
||||
|
||||
return function[i].address;
|
||||
if(!funcName)
|
||||
return NULL;
|
||||
return alcGetProcAddress(NULL, funcName);
|
||||
}
|
||||
|
||||
/* NOTE: This function must be able to run without a context! */
|
||||
ALAPI ALenum ALAPIENTRY alGetEnumValue(const ALchar *enumName)
|
||||
AL_API ALenum AL_APIENTRY alGetEnumValue(const ALchar *enumName)
|
||||
{
|
||||
ALsizei i = 0;
|
||||
|
||||
while(enumeration[i].enumName &&
|
||||
strcmp(enumeration[i].enumName, enumName) != 0)
|
||||
i++;
|
||||
|
||||
return enumeration[i].value;
|
||||
if(!enumName)
|
||||
return (ALenum)0;
|
||||
return alcGetEnumValue(NULL, enumName);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,468 @@
|
||||
/**
|
||||
* OpenAL cross platform audio library
|
||||
* Copyright (C) 1999-2007 by authors.
|
||||
* 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., 59 Temple Place - Suite 330,
|
||||
* Boston, MA 02111-1307, USA.
|
||||
* Or go to http://www.gnu.org/copyleft/lgpl.html
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "alMain.h"
|
||||
#include "alu.h"
|
||||
#include "alFilter.h"
|
||||
#include "alThunk.h"
|
||||
#include "alError.h"
|
||||
|
||||
|
||||
static void InitFilterParams(ALfilter *filter, ALenum type);
|
||||
|
||||
|
||||
AL_API ALvoid AL_APIENTRY alGenFilters(ALsizei n, ALuint *filters)
|
||||
{
|
||||
ALCcontext *Context;
|
||||
ALsizei cur = 0;
|
||||
|
||||
Context = GetContextRef();
|
||||
if(!Context) return;
|
||||
|
||||
al_try
|
||||
{
|
||||
ALCdevice *device = Context->Device;
|
||||
ALenum err;
|
||||
|
||||
CHECK_VALUE(Context, n >= 0);
|
||||
for(cur = 0;cur < n;cur++)
|
||||
{
|
||||
ALfilter *filter = calloc(1, sizeof(ALfilter));
|
||||
if(!filter)
|
||||
al_throwerr(Context, AL_OUT_OF_MEMORY);
|
||||
InitFilterParams(filter, AL_FILTER_NULL);
|
||||
|
||||
err = NewThunkEntry(&filter->id);
|
||||
if(err == AL_NO_ERROR)
|
||||
err = InsertUIntMapEntry(&device->FilterMap, filter->id, filter);
|
||||
if(err != AL_NO_ERROR)
|
||||
{
|
||||
FreeThunkEntry(filter->id);
|
||||
memset(filter, 0, sizeof(ALfilter));
|
||||
free(filter);
|
||||
|
||||
al_throwerr(Context, err);
|
||||
}
|
||||
|
||||
filters[cur] = filter->id;
|
||||
}
|
||||
}
|
||||
al_catchany()
|
||||
{
|
||||
if(cur > 0)
|
||||
alDeleteFilters(cur, filters);
|
||||
}
|
||||
al_endtry;
|
||||
|
||||
ALCcontext_DecRef(Context);
|
||||
}
|
||||
|
||||
AL_API ALvoid AL_APIENTRY alDeleteFilters(ALsizei n, const ALuint *filters)
|
||||
{
|
||||
ALCcontext *Context;
|
||||
ALfilter *Filter;
|
||||
ALsizei i;
|
||||
|
||||
Context = GetContextRef();
|
||||
if(!Context) return;
|
||||
|
||||
al_try
|
||||
{
|
||||
ALCdevice *device = Context->Device;
|
||||
CHECK_VALUE(Context, n >= 0);
|
||||
for(i = 0;i < n;i++)
|
||||
{
|
||||
if(filters[i] && LookupFilter(device, filters[i]) == NULL)
|
||||
al_throwerr(Context, AL_INVALID_NAME);
|
||||
}
|
||||
|
||||
for(i = 0;i < n;i++)
|
||||
{
|
||||
if((Filter=RemoveFilter(device, filters[i])) == NULL)
|
||||
continue;
|
||||
FreeThunkEntry(Filter->id);
|
||||
|
||||
memset(Filter, 0, sizeof(*Filter));
|
||||
free(Filter);
|
||||
}
|
||||
}
|
||||
al_endtry;
|
||||
|
||||
ALCcontext_DecRef(Context);
|
||||
}
|
||||
|
||||
AL_API ALboolean AL_APIENTRY alIsFilter(ALuint filter)
|
||||
{
|
||||
ALCcontext *Context;
|
||||
ALboolean result;
|
||||
|
||||
Context = GetContextRef();
|
||||
if(!Context) return AL_FALSE;
|
||||
|
||||
result = ((!filter || LookupFilter(Context->Device, filter)) ?
|
||||
AL_TRUE : AL_FALSE);
|
||||
|
||||
ALCcontext_DecRef(Context);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
AL_API ALvoid AL_APIENTRY alFilteri(ALuint filter, ALenum param, ALint value)
|
||||
{
|
||||
ALCcontext *Context;
|
||||
ALCdevice *Device;
|
||||
ALfilter *ALFilter;
|
||||
|
||||
Context = GetContextRef();
|
||||
if(!Context) return;
|
||||
|
||||
Device = Context->Device;
|
||||
if((ALFilter=LookupFilter(Device, filter)) == NULL)
|
||||
alSetError(Context, AL_INVALID_NAME);
|
||||
else
|
||||
{
|
||||
if(param == AL_FILTER_TYPE)
|
||||
{
|
||||
if(value == AL_FILTER_NULL || value == AL_FILTER_LOWPASS)
|
||||
InitFilterParams(ALFilter, value);
|
||||
else
|
||||
alSetError(Context, AL_INVALID_VALUE);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Call the appropriate handler */
|
||||
ALfilter_SetParami(ALFilter, Context, param, value);
|
||||
}
|
||||
}
|
||||
|
||||
ALCcontext_DecRef(Context);
|
||||
}
|
||||
|
||||
AL_API ALvoid AL_APIENTRY alFilteriv(ALuint filter, ALenum param, const ALint *values)
|
||||
{
|
||||
ALCcontext *Context;
|
||||
ALCdevice *Device;
|
||||
ALfilter *ALFilter;
|
||||
|
||||
switch(param)
|
||||
{
|
||||
case AL_FILTER_TYPE:
|
||||
alFilteri(filter, param, values[0]);
|
||||
return;
|
||||
}
|
||||
|
||||
Context = GetContextRef();
|
||||
if(!Context) return;
|
||||
|
||||
Device = Context->Device;
|
||||
if((ALFilter=LookupFilter(Device, filter)) == NULL)
|
||||
alSetError(Context, AL_INVALID_NAME);
|
||||
else
|
||||
{
|
||||
/* Call the appropriate handler */
|
||||
ALfilter_SetParamiv(ALFilter, Context, param, values);
|
||||
}
|
||||
|
||||
ALCcontext_DecRef(Context);
|
||||
}
|
||||
|
||||
AL_API ALvoid AL_APIENTRY alFilterf(ALuint filter, ALenum param, ALfloat value)
|
||||
{
|
||||
ALCcontext *Context;
|
||||
ALCdevice *Device;
|
||||
ALfilter *ALFilter;
|
||||
|
||||
Context = GetContextRef();
|
||||
if(!Context) return;
|
||||
|
||||
Device = Context->Device;
|
||||
if((ALFilter=LookupFilter(Device, filter)) == NULL)
|
||||
alSetError(Context, AL_INVALID_NAME);
|
||||
else
|
||||
{
|
||||
/* Call the appropriate handler */
|
||||
ALfilter_SetParamf(ALFilter, Context, param, value);
|
||||
}
|
||||
|
||||
ALCcontext_DecRef(Context);
|
||||
}
|
||||
|
||||
AL_API ALvoid AL_APIENTRY alFilterfv(ALuint filter, ALenum param, const ALfloat *values)
|
||||
{
|
||||
ALCcontext *Context;
|
||||
ALCdevice *Device;
|
||||
ALfilter *ALFilter;
|
||||
|
||||
Context = GetContextRef();
|
||||
if(!Context) return;
|
||||
|
||||
Device = Context->Device;
|
||||
if((ALFilter=LookupFilter(Device, filter)) == NULL)
|
||||
alSetError(Context, AL_INVALID_NAME);
|
||||
else
|
||||
{
|
||||
/* Call the appropriate handler */
|
||||
ALfilter_SetParamfv(ALFilter, Context, param, values);
|
||||
}
|
||||
|
||||
ALCcontext_DecRef(Context);
|
||||
}
|
||||
|
||||
AL_API ALvoid AL_APIENTRY alGetFilteri(ALuint filter, ALenum param, ALint *value)
|
||||
{
|
||||
ALCcontext *Context;
|
||||
ALCdevice *Device;
|
||||
ALfilter *ALFilter;
|
||||
|
||||
Context = GetContextRef();
|
||||
if(!Context) return;
|
||||
|
||||
Device = Context->Device;
|
||||
if((ALFilter=LookupFilter(Device, filter)) == NULL)
|
||||
alSetError(Context, AL_INVALID_NAME);
|
||||
else
|
||||
{
|
||||
if(param == AL_FILTER_TYPE)
|
||||
*value = ALFilter->type;
|
||||
else
|
||||
{
|
||||
/* Call the appropriate handler */
|
||||
ALfilter_GetParami(ALFilter, Context, param, value);
|
||||
}
|
||||
}
|
||||
|
||||
ALCcontext_DecRef(Context);
|
||||
}
|
||||
|
||||
AL_API ALvoid AL_APIENTRY alGetFilteriv(ALuint filter, ALenum param, ALint *values)
|
||||
{
|
||||
ALCcontext *Context;
|
||||
ALCdevice *Device;
|
||||
ALfilter *ALFilter;
|
||||
|
||||
switch(param)
|
||||
{
|
||||
case AL_FILTER_TYPE:
|
||||
alGetFilteri(filter, param, values);
|
||||
return;
|
||||
}
|
||||
|
||||
Context = GetContextRef();
|
||||
if(!Context) return;
|
||||
|
||||
Device = Context->Device;
|
||||
if((ALFilter=LookupFilter(Device, filter)) == NULL)
|
||||
alSetError(Context, AL_INVALID_NAME);
|
||||
else
|
||||
{
|
||||
/* Call the appropriate handler */
|
||||
ALfilter_GetParamiv(ALFilter, Context, param, values);
|
||||
}
|
||||
|
||||
ALCcontext_DecRef(Context);
|
||||
}
|
||||
|
||||
AL_API ALvoid AL_APIENTRY alGetFilterf(ALuint filter, ALenum param, ALfloat *value)
|
||||
{
|
||||
ALCcontext *Context;
|
||||
ALCdevice *Device;
|
||||
ALfilter *ALFilter;
|
||||
|
||||
Context = GetContextRef();
|
||||
if(!Context) return;
|
||||
|
||||
Device = Context->Device;
|
||||
if((ALFilter=LookupFilter(Device, filter)) == NULL)
|
||||
alSetError(Context, AL_INVALID_NAME);
|
||||
else
|
||||
{
|
||||
/* Call the appropriate handler */
|
||||
ALfilter_GetParamf(ALFilter, Context, param, value);
|
||||
}
|
||||
|
||||
ALCcontext_DecRef(Context);
|
||||
}
|
||||
|
||||
AL_API ALvoid AL_APIENTRY alGetFilterfv(ALuint filter, ALenum param, ALfloat *values)
|
||||
{
|
||||
ALCcontext *Context;
|
||||
ALCdevice *Device;
|
||||
ALfilter *ALFilter;
|
||||
|
||||
Context = GetContextRef();
|
||||
if(!Context) return;
|
||||
|
||||
Device = Context->Device;
|
||||
if((ALFilter=LookupFilter(Device, filter)) == NULL)
|
||||
alSetError(Context, AL_INVALID_NAME);
|
||||
else
|
||||
{
|
||||
/* Call the appropriate handler */
|
||||
ALfilter_GetParamfv(ALFilter, Context, param, values);
|
||||
}
|
||||
|
||||
ALCcontext_DecRef(Context);
|
||||
}
|
||||
|
||||
|
||||
ALfloat lpCoeffCalc(ALfloat g, ALfloat cw)
|
||||
{
|
||||
ALfloat a = 0.0f;
|
||||
|
||||
if(g < 0.9999f) /* 1-epsilon */
|
||||
{
|
||||
/* Be careful with gains < 0.001, as that causes the coefficient head
|
||||
* towards 1, which will flatten the signal */
|
||||
g = maxf(g, 0.001f);
|
||||
a = (1 - g*cw - sqrtf(2*g*(1-cw) - g*g*(1 - cw*cw))) /
|
||||
(1 - g);
|
||||
}
|
||||
|
||||
return a;
|
||||
}
|
||||
|
||||
|
||||
static void lp_SetParami(ALfilter *filter, ALCcontext *context, ALenum param, ALint val)
|
||||
{ (void)filter;(void)param;(void)val; alSetError(context, AL_INVALID_ENUM); }
|
||||
static void lp_SetParamiv(ALfilter *filter, ALCcontext *context, ALenum param, const ALint *vals)
|
||||
{ (void)filter;(void)param;(void)vals; alSetError(context, AL_INVALID_ENUM); }
|
||||
static void lp_SetParamf(ALfilter *filter, ALCcontext *context, ALenum param, ALfloat val)
|
||||
{
|
||||
switch(param)
|
||||
{
|
||||
case AL_LOWPASS_GAIN:
|
||||
if(val >= AL_LOWPASS_MIN_GAIN && val <= AL_LOWPASS_MAX_GAIN)
|
||||
filter->Gain = val;
|
||||
else
|
||||
alSetError(context, AL_INVALID_VALUE);
|
||||
break;
|
||||
|
||||
case AL_LOWPASS_GAINHF:
|
||||
if(val >= AL_LOWPASS_MIN_GAINHF && val <= AL_LOWPASS_MAX_GAINHF)
|
||||
filter->GainHF = val;
|
||||
else
|
||||
alSetError(context, AL_INVALID_VALUE);
|
||||
break;
|
||||
|
||||
default:
|
||||
alSetError(context, AL_INVALID_ENUM);
|
||||
break;
|
||||
}
|
||||
}
|
||||
static void lp_SetParamfv(ALfilter *filter, ALCcontext *context, ALenum param, const ALfloat *vals)
|
||||
{
|
||||
lp_SetParamf(filter, context, param, vals[0]);
|
||||
}
|
||||
|
||||
static void lp_GetParami(ALfilter *filter, ALCcontext *context, ALenum param, ALint *val)
|
||||
{ (void)filter;(void)param;(void)val; alSetError(context, AL_INVALID_ENUM); }
|
||||
static void lp_GetParamiv(ALfilter *filter, ALCcontext *context, ALenum param, ALint *vals)
|
||||
{ (void)filter;(void)param;(void)vals; alSetError(context, AL_INVALID_ENUM); }
|
||||
static void lp_GetParamf(ALfilter *filter, ALCcontext *context, ALenum param, ALfloat *val)
|
||||
{
|
||||
switch(param)
|
||||
{
|
||||
case AL_LOWPASS_GAIN:
|
||||
*val = filter->Gain;
|
||||
break;
|
||||
|
||||
case AL_LOWPASS_GAINHF:
|
||||
*val = filter->GainHF;
|
||||
break;
|
||||
|
||||
default:
|
||||
alSetError(context, AL_INVALID_ENUM);
|
||||
break;
|
||||
}
|
||||
}
|
||||
static void lp_GetParamfv(ALfilter *filter, ALCcontext *context, ALenum param, ALfloat *vals)
|
||||
{
|
||||
lp_GetParamf(filter, context, param, vals);
|
||||
}
|
||||
|
||||
|
||||
static void null_SetParami(ALfilter *filter, ALCcontext *context, ALenum param, ALint val)
|
||||
{ (void)filter;(void)param;(void)val; alSetError(context, AL_INVALID_ENUM); }
|
||||
static void null_SetParamiv(ALfilter *filter, ALCcontext *context, ALenum param, const ALint *vals)
|
||||
{ (void)filter;(void)param;(void)vals; alSetError(context, AL_INVALID_ENUM); }
|
||||
static void null_SetParamf(ALfilter *filter, ALCcontext *context, ALenum param, ALfloat val)
|
||||
{ (void)filter;(void)param;(void)val; alSetError(context, AL_INVALID_ENUM); }
|
||||
static void null_SetParamfv(ALfilter *filter, ALCcontext *context, ALenum param, const ALfloat *vals)
|
||||
{ (void)filter;(void)param;(void)vals; alSetError(context, AL_INVALID_ENUM); }
|
||||
|
||||
static void null_GetParami(ALfilter *filter, ALCcontext *context, ALenum param, ALint *val)
|
||||
{ (void)filter;(void)param;(void)val; alSetError(context, AL_INVALID_ENUM); }
|
||||
static void null_GetParamiv(ALfilter *filter, ALCcontext *context, ALenum param, ALint *vals)
|
||||
{ (void)filter;(void)param;(void)vals; alSetError(context, AL_INVALID_ENUM); }
|
||||
static void null_GetParamf(ALfilter *filter, ALCcontext *context, ALenum param, ALfloat *val)
|
||||
{ (void)filter;(void)param;(void)val; alSetError(context, AL_INVALID_ENUM); }
|
||||
static void null_GetParamfv(ALfilter *filter, ALCcontext *context, ALenum param, ALfloat *vals)
|
||||
{ (void)filter;(void)param;(void)vals; alSetError(context, AL_INVALID_ENUM); }
|
||||
|
||||
|
||||
ALvoid ReleaseALFilters(ALCdevice *device)
|
||||
{
|
||||
ALsizei i;
|
||||
for(i = 0;i < device->FilterMap.size;i++)
|
||||
{
|
||||
ALfilter *temp = device->FilterMap.array[i].value;
|
||||
device->FilterMap.array[i].value = NULL;
|
||||
|
||||
// Release filter structure
|
||||
FreeThunkEntry(temp->id);
|
||||
memset(temp, 0, sizeof(ALfilter));
|
||||
free(temp);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void InitFilterParams(ALfilter *filter, ALenum type)
|
||||
{
|
||||
if(type == AL_FILTER_LOWPASS)
|
||||
{
|
||||
filter->Gain = AL_LOWPASS_DEFAULT_GAIN;
|
||||
filter->GainHF = AL_LOWPASS_DEFAULT_GAINHF;
|
||||
|
||||
filter->SetParami = lp_SetParami;
|
||||
filter->SetParamiv = lp_SetParamiv;
|
||||
filter->SetParamf = lp_SetParamf;
|
||||
filter->SetParamfv = lp_SetParamfv;
|
||||
filter->GetParami = lp_GetParami;
|
||||
filter->GetParamiv = lp_GetParamiv;
|
||||
filter->GetParamf = lp_GetParamf;
|
||||
filter->GetParamfv = lp_GetParamfv;
|
||||
}
|
||||
else
|
||||
{
|
||||
filter->SetParami = null_SetParami;
|
||||
filter->SetParamiv = null_SetParamiv;
|
||||
filter->SetParamf = null_SetParamf;
|
||||
filter->SetParamfv = null_SetParamfv;
|
||||
filter->GetParami = null_GetParami;
|
||||
filter->GetParamiv = null_GetParamiv;
|
||||
filter->GetParamf = null_GetParamf;
|
||||
filter->GetParamfv = null_GetParamfv;
|
||||
}
|
||||
filter->type = type;
|
||||
}
|
||||
+381
-422
@@ -18,496 +18,455 @@
|
||||
* Or go to http://www.gnu.org/copyleft/lgpl.html
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include "alMain.h"
|
||||
#include "AL/alc.h"
|
||||
#include "alError.h"
|
||||
#include "alListener.h"
|
||||
#include "alSource.h"
|
||||
|
||||
ALAPI ALvoid ALAPIENTRY alListenerf(ALenum eParam, ALfloat flValue)
|
||||
AL_API ALvoid AL_APIENTRY alListenerf(ALenum param, ALfloat value)
|
||||
{
|
||||
ALCcontext *pContext;
|
||||
ALCcontext *Context;
|
||||
|
||||
pContext = alcGetCurrentContext();
|
||||
if (pContext)
|
||||
Context = GetContextRef();
|
||||
if(!Context) return;
|
||||
|
||||
al_try
|
||||
{
|
||||
SuspendContext(pContext);
|
||||
|
||||
switch (eParam)
|
||||
switch(param)
|
||||
{
|
||||
case AL_GAIN:
|
||||
CHECK_VALUE(Context, value >= 0.0f && isfinite(value));
|
||||
|
||||
Context->Listener->Gain = value;
|
||||
Context->UpdateSources = AL_TRUE;
|
||||
break;
|
||||
|
||||
case AL_METERS_PER_UNIT:
|
||||
CHECK_VALUE(Context, value >= 0.0f && isfinite(value));
|
||||
|
||||
Context->Listener->MetersPerUnit = value;
|
||||
Context->UpdateSources = AL_TRUE;
|
||||
break;
|
||||
|
||||
default:
|
||||
al_throwerr(Context, AL_INVALID_ENUM);
|
||||
}
|
||||
}
|
||||
al_endtry;
|
||||
|
||||
ALCcontext_DecRef(Context);
|
||||
}
|
||||
|
||||
|
||||
AL_API ALvoid AL_APIENTRY alListener3f(ALenum param, ALfloat value1, ALfloat value2, ALfloat value3)
|
||||
{
|
||||
ALCcontext *Context;
|
||||
|
||||
Context = GetContextRef();
|
||||
if(!Context) return;
|
||||
|
||||
al_try
|
||||
{
|
||||
switch(param)
|
||||
{
|
||||
case AL_POSITION:
|
||||
CHECK_VALUE(Context, isfinite(value1) && isfinite(value2) && isfinite(value3));
|
||||
|
||||
LockContext(Context);
|
||||
Context->Listener->Position[0] = value1;
|
||||
Context->Listener->Position[1] = value2;
|
||||
Context->Listener->Position[2] = value3;
|
||||
Context->UpdateSources = AL_TRUE;
|
||||
UnlockContext(Context);
|
||||
break;
|
||||
|
||||
case AL_VELOCITY:
|
||||
CHECK_VALUE(Context, isfinite(value1) && isfinite(value2) && isfinite(value3));
|
||||
|
||||
LockContext(Context);
|
||||
Context->Listener->Velocity[0] = value1;
|
||||
Context->Listener->Velocity[1] = value2;
|
||||
Context->Listener->Velocity[2] = value3;
|
||||
Context->UpdateSources = AL_TRUE;
|
||||
UnlockContext(Context);
|
||||
break;
|
||||
|
||||
default:
|
||||
al_throwerr(Context, AL_INVALID_ENUM);
|
||||
}
|
||||
}
|
||||
al_endtry;
|
||||
|
||||
ALCcontext_DecRef(Context);
|
||||
}
|
||||
|
||||
|
||||
AL_API ALvoid AL_APIENTRY alListenerfv(ALenum param, const ALfloat *values)
|
||||
{
|
||||
ALCcontext *Context;
|
||||
|
||||
if(values)
|
||||
{
|
||||
switch(param)
|
||||
{
|
||||
case AL_GAIN:
|
||||
case AL_METERS_PER_UNIT:
|
||||
alListenerf(param, values[0]);
|
||||
return;
|
||||
|
||||
case AL_POSITION:
|
||||
case AL_VELOCITY:
|
||||
alListener3f(param, values[0], values[1], values[2]);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
Context = GetContextRef();
|
||||
if(!Context) return;
|
||||
|
||||
al_try
|
||||
{
|
||||
CHECK_VALUE(Context, values);
|
||||
switch(param)
|
||||
{
|
||||
case AL_ORIENTATION:
|
||||
CHECK_VALUE(Context, isfinite(values[0]) && isfinite(values[1]) &&
|
||||
isfinite(values[2]) && isfinite(values[3]) &&
|
||||
isfinite(values[4]) && isfinite(values[5]));
|
||||
|
||||
LockContext(Context);
|
||||
/* AT then UP */
|
||||
Context->Listener->Forward[0] = values[0];
|
||||
Context->Listener->Forward[1] = values[1];
|
||||
Context->Listener->Forward[2] = values[2];
|
||||
Context->Listener->Up[0] = values[3];
|
||||
Context->Listener->Up[1] = values[4];
|
||||
Context->Listener->Up[2] = values[5];
|
||||
Context->UpdateSources = AL_TRUE;
|
||||
UnlockContext(Context);
|
||||
break;
|
||||
|
||||
default:
|
||||
al_throwerr(Context, AL_INVALID_ENUM);
|
||||
}
|
||||
}
|
||||
al_endtry;
|
||||
|
||||
ALCcontext_DecRef(Context);
|
||||
}
|
||||
|
||||
|
||||
AL_API ALvoid AL_APIENTRY alListeneri(ALenum param, ALint value)
|
||||
{
|
||||
ALCcontext *Context;
|
||||
|
||||
(void)value;
|
||||
|
||||
Context = GetContextRef();
|
||||
if(!Context) return;
|
||||
|
||||
al_try
|
||||
{
|
||||
switch(param)
|
||||
{
|
||||
default:
|
||||
al_throwerr(Context, AL_INVALID_ENUM);
|
||||
}
|
||||
}
|
||||
al_endtry;
|
||||
|
||||
ALCcontext_DecRef(Context);
|
||||
}
|
||||
|
||||
|
||||
AL_API void AL_APIENTRY alListener3i(ALenum param, ALint value1, ALint value2, ALint value3)
|
||||
{
|
||||
ALCcontext *Context;
|
||||
|
||||
switch(param)
|
||||
{
|
||||
case AL_POSITION:
|
||||
case AL_VELOCITY:
|
||||
alListener3f(param, (ALfloat)value1, (ALfloat)value2, (ALfloat)value3);
|
||||
return;
|
||||
}
|
||||
|
||||
Context = GetContextRef();
|
||||
if(!Context) return;
|
||||
|
||||
al_try
|
||||
{
|
||||
switch(param)
|
||||
{
|
||||
default:
|
||||
al_throwerr(Context, AL_INVALID_ENUM);
|
||||
}
|
||||
}
|
||||
al_endtry;
|
||||
|
||||
ALCcontext_DecRef(Context);
|
||||
}
|
||||
|
||||
|
||||
AL_API void AL_APIENTRY alListeneriv(ALenum param, const ALint *values)
|
||||
{
|
||||
ALCcontext *Context;
|
||||
|
||||
if(values)
|
||||
{
|
||||
ALfloat fvals[6];
|
||||
switch(param)
|
||||
{
|
||||
case AL_POSITION:
|
||||
case AL_VELOCITY:
|
||||
alListener3f(param, (ALfloat)values[0], (ALfloat)values[1], (ALfloat)values[2]);
|
||||
return;
|
||||
|
||||
case AL_ORIENTATION:
|
||||
fvals[0] = (ALfloat)values[0];
|
||||
fvals[1] = (ALfloat)values[1];
|
||||
fvals[2] = (ALfloat)values[2];
|
||||
fvals[3] = (ALfloat)values[3];
|
||||
fvals[4] = (ALfloat)values[4];
|
||||
fvals[5] = (ALfloat)values[5];
|
||||
alListenerfv(param, fvals);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
Context = GetContextRef();
|
||||
if(!Context) return;
|
||||
|
||||
al_try
|
||||
{
|
||||
CHECK_VALUE(Context, values);
|
||||
switch(param)
|
||||
{
|
||||
default:
|
||||
al_throwerr(Context, AL_INVALID_ENUM);
|
||||
}
|
||||
}
|
||||
al_endtry;
|
||||
|
||||
ALCcontext_DecRef(Context);
|
||||
}
|
||||
|
||||
|
||||
AL_API ALvoid AL_APIENTRY alGetListenerf(ALenum param, ALfloat *value)
|
||||
{
|
||||
ALCcontext *Context;
|
||||
|
||||
Context = GetContextRef();
|
||||
if(!Context) return;
|
||||
|
||||
al_try
|
||||
{
|
||||
CHECK_VALUE(Context, value);
|
||||
switch(param)
|
||||
{
|
||||
case AL_GAIN:
|
||||
*value = Context->Listener->Gain;
|
||||
break;
|
||||
|
||||
case AL_METERS_PER_UNIT:
|
||||
*value = Context->Listener->MetersPerUnit;
|
||||
break;
|
||||
|
||||
default:
|
||||
al_throwerr(Context, AL_INVALID_ENUM);
|
||||
}
|
||||
}
|
||||
al_endtry;
|
||||
|
||||
ALCcontext_DecRef(Context);
|
||||
}
|
||||
|
||||
|
||||
AL_API ALvoid AL_APIENTRY alGetListener3f(ALenum param, ALfloat *value1, ALfloat *value2, ALfloat *value3)
|
||||
{
|
||||
ALCcontext *Context;
|
||||
|
||||
Context = GetContextRef();
|
||||
if(!Context) return;
|
||||
|
||||
al_try
|
||||
{
|
||||
CHECK_VALUE(Context, value1 && value2 && value3);
|
||||
switch(param)
|
||||
{
|
||||
case AL_POSITION:
|
||||
LockContext(Context);
|
||||
*value1 = Context->Listener->Position[0];
|
||||
*value2 = Context->Listener->Position[1];
|
||||
*value3 = Context->Listener->Position[2];
|
||||
UnlockContext(Context);
|
||||
break;
|
||||
|
||||
case AL_VELOCITY:
|
||||
LockContext(Context);
|
||||
*value1 = Context->Listener->Velocity[0];
|
||||
*value2 = Context->Listener->Velocity[1];
|
||||
*value3 = Context->Listener->Velocity[2];
|
||||
UnlockContext(Context);
|
||||
break;
|
||||
|
||||
default:
|
||||
al_throwerr(Context, AL_INVALID_ENUM);
|
||||
}
|
||||
}
|
||||
al_endtry;
|
||||
|
||||
ALCcontext_DecRef(Context);
|
||||
}
|
||||
|
||||
|
||||
AL_API ALvoid AL_APIENTRY alGetListenerfv(ALenum param, ALfloat *values)
|
||||
{
|
||||
ALCcontext *Context;
|
||||
|
||||
switch(param)
|
||||
{
|
||||
case AL_GAIN:
|
||||
if (flValue >= 0.0f)
|
||||
pContext->Listener.Gain = flValue;
|
||||
else
|
||||
alSetError(AL_INVALID_VALUE);
|
||||
break;
|
||||
case AL_METERS_PER_UNIT:
|
||||
alGetListenerf(param, values);
|
||||
return;
|
||||
|
||||
default:
|
||||
alSetError(AL_INVALID_ENUM);
|
||||
break;
|
||||
}
|
||||
|
||||
ProcessContext(pContext);
|
||||
}
|
||||
else
|
||||
alSetError(AL_INVALID_OPERATION);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
ALAPI ALvoid ALAPIENTRY alListener3f(ALenum eParam, ALfloat flValue1, ALfloat flValue2, ALfloat flValue3)
|
||||
{
|
||||
ALCcontext *pContext;
|
||||
|
||||
pContext = alcGetCurrentContext();
|
||||
if (pContext)
|
||||
{
|
||||
SuspendContext(pContext);
|
||||
|
||||
switch(eParam)
|
||||
{
|
||||
case AL_POSITION:
|
||||
pContext->Listener.Position[0] = flValue1;
|
||||
pContext->Listener.Position[1] = flValue2;
|
||||
pContext->Listener.Position[2] = flValue3;
|
||||
break;
|
||||
|
||||
case AL_VELOCITY:
|
||||
pContext->Listener.Velocity[0] = flValue1;
|
||||
pContext->Listener.Velocity[1] = flValue2;
|
||||
pContext->Listener.Velocity[2] = flValue3;
|
||||
break;
|
||||
|
||||
default:
|
||||
alSetError(AL_INVALID_ENUM);
|
||||
break;
|
||||
}
|
||||
|
||||
ProcessContext(pContext);
|
||||
}
|
||||
else
|
||||
alSetError(AL_INVALID_OPERATION);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
ALAPI ALvoid ALAPIENTRY alListenerfv(ALenum eParam, const ALfloat *pflValues)
|
||||
{
|
||||
ALCcontext *pContext;
|
||||
|
||||
pContext = alcGetCurrentContext();
|
||||
if (pContext)
|
||||
{
|
||||
SuspendContext(pContext);
|
||||
|
||||
if (pflValues)
|
||||
{
|
||||
switch (eParam)
|
||||
{
|
||||
case AL_GAIN:
|
||||
if (pflValues[0] >= 0.0f)
|
||||
pContext->Listener.Gain = pflValues[0];
|
||||
else
|
||||
alSetError(AL_INVALID_VALUE);
|
||||
break;
|
||||
|
||||
case AL_POSITION:
|
||||
pContext->Listener.Position[0] = pflValues[0];
|
||||
pContext->Listener.Position[1] = pflValues[1];
|
||||
pContext->Listener.Position[2] = pflValues[2];
|
||||
break;
|
||||
|
||||
case AL_VELOCITY:
|
||||
pContext->Listener.Velocity[0] = pflValues[0];
|
||||
pContext->Listener.Velocity[1] = pflValues[1];
|
||||
pContext->Listener.Velocity[2] = pflValues[2];
|
||||
break;
|
||||
|
||||
case AL_ORIENTATION:
|
||||
// AT then UP
|
||||
pContext->Listener.Forward[0] = pflValues[0];
|
||||
pContext->Listener.Forward[1] = pflValues[1];
|
||||
pContext->Listener.Forward[2] = pflValues[2];
|
||||
pContext->Listener.Up[0] = pflValues[3];
|
||||
pContext->Listener.Up[1] = pflValues[4];
|
||||
pContext->Listener.Up[2] = pflValues[5];
|
||||
break;
|
||||
|
||||
default:
|
||||
alSetError(AL_INVALID_ENUM);
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
alSetError(AL_INVALID_VALUE);
|
||||
|
||||
ProcessContext(pContext);
|
||||
}
|
||||
else
|
||||
alSetError(AL_INVALID_OPERATION);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
ALAPI ALvoid ALAPIENTRY alListeneri(ALenum eParam, ALint lValue)
|
||||
{
|
||||
ALCcontext *pContext;
|
||||
|
||||
(void)lValue;
|
||||
|
||||
pContext = alcGetCurrentContext();
|
||||
if (pContext)
|
||||
{
|
||||
SuspendContext(pContext);
|
||||
|
||||
switch (eParam)
|
||||
{
|
||||
default:
|
||||
alSetError(AL_INVALID_ENUM);
|
||||
break;
|
||||
}
|
||||
|
||||
ProcessContext(pContext);
|
||||
}
|
||||
else
|
||||
alSetError(AL_INVALID_OPERATION);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
ALAPI void ALAPIENTRY alListener3i(ALenum eParam, ALint lValue1, ALint lValue2, ALint lValue3)
|
||||
{
|
||||
ALCcontext *pContext;
|
||||
|
||||
pContext = alcGetCurrentContext();
|
||||
if (pContext)
|
||||
{
|
||||
SuspendContext(pContext);
|
||||
|
||||
switch(eParam)
|
||||
{
|
||||
case AL_POSITION:
|
||||
case AL_VELOCITY:
|
||||
alListener3f(eParam, (ALfloat)lValue1, (ALfloat)lValue2, (ALfloat)lValue3);
|
||||
break;
|
||||
|
||||
default:
|
||||
alSetError(AL_INVALID_ENUM);
|
||||
break;
|
||||
}
|
||||
|
||||
ProcessContext(pContext);
|
||||
alGetListener3f(param, values+0, values+1, values+2);
|
||||
return;
|
||||
}
|
||||
else
|
||||
alSetError(AL_INVALID_OPERATION);
|
||||
|
||||
return;
|
||||
}
|
||||
Context = GetContextRef();
|
||||
if(!Context) return;
|
||||
|
||||
|
||||
ALAPI void ALAPIENTRY alListeneriv( ALenum eParam, const ALint* plValues )
|
||||
{
|
||||
ALCcontext *pContext;
|
||||
ALfloat flValues[6];
|
||||
|
||||
pContext = alcGetCurrentContext();
|
||||
if (pContext)
|
||||
al_try
|
||||
{
|
||||
SuspendContext(pContext);
|
||||
|
||||
if (plValues)
|
||||
CHECK_VALUE(Context, values);
|
||||
switch(param)
|
||||
{
|
||||
switch (eParam)
|
||||
{
|
||||
case AL_POSITION:
|
||||
case AL_VELOCITY:
|
||||
flValues[0] = (ALfloat)plValues[0];
|
||||
flValues[1] = (ALfloat)plValues[1];
|
||||
flValues[2] = (ALfloat)plValues[2];
|
||||
alListenerfv(eParam, flValues);
|
||||
break;
|
||||
|
||||
case AL_ORIENTATION:
|
||||
flValues[0] = (ALfloat)plValues[0];
|
||||
flValues[1] = (ALfloat)plValues[1];
|
||||
flValues[2] = (ALfloat)plValues[2];
|
||||
flValues[3] = (ALfloat)plValues[3];
|
||||
flValues[4] = (ALfloat)plValues[4];
|
||||
flValues[5] = (ALfloat)plValues[5];
|
||||
alListenerfv(eParam, flValues);
|
||||
break;
|
||||
|
||||
default:
|
||||
alSetError(AL_INVALID_ENUM);
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
alSetError(AL_INVALID_VALUE);
|
||||
|
||||
ProcessContext(pContext);
|
||||
}
|
||||
else
|
||||
alSetError(AL_INVALID_OPERATION);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
ALAPI ALvoid ALAPIENTRY alGetListenerf(ALenum eParam, ALfloat *pflValue)
|
||||
{
|
||||
ALCcontext *pContext;
|
||||
|
||||
pContext = alcGetCurrentContext();
|
||||
if (pContext)
|
||||
{
|
||||
SuspendContext(pContext);
|
||||
|
||||
if (pflValue)
|
||||
{
|
||||
switch (eParam)
|
||||
{
|
||||
case AL_GAIN:
|
||||
*pflValue = pContext->Listener.Gain;
|
||||
break;
|
||||
|
||||
default:
|
||||
alSetError(AL_INVALID_ENUM);
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
alSetError(AL_INVALID_VALUE);
|
||||
|
||||
ProcessContext(pContext);
|
||||
}
|
||||
else
|
||||
alSetError(AL_INVALID_OPERATION);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
ALAPI ALvoid ALAPIENTRY alGetListener3f(ALenum eParam, ALfloat *pflValue1, ALfloat *pflValue2, ALfloat *pflValue3)
|
||||
{
|
||||
ALCcontext *pContext;
|
||||
|
||||
pContext = alcGetCurrentContext();
|
||||
if (pContext)
|
||||
{
|
||||
SuspendContext(pContext);
|
||||
|
||||
if ((pflValue1) && (pflValue2) && (pflValue3))
|
||||
{
|
||||
switch (eParam)
|
||||
{
|
||||
case AL_POSITION:
|
||||
*pflValue1 = pContext->Listener.Position[0];
|
||||
*pflValue2 = pContext->Listener.Position[1];
|
||||
*pflValue3 = pContext->Listener.Position[2];
|
||||
break;
|
||||
|
||||
case AL_VELOCITY:
|
||||
*pflValue1 = pContext->Listener.Velocity[0];
|
||||
*pflValue2 = pContext->Listener.Velocity[1];
|
||||
*pflValue3 = pContext->Listener.Velocity[2];
|
||||
break;
|
||||
|
||||
default:
|
||||
alSetError(AL_INVALID_ENUM);
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
alSetError(AL_INVALID_VALUE);
|
||||
|
||||
ProcessContext(pContext);
|
||||
}
|
||||
else
|
||||
alSetError(AL_INVALID_OPERATION);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
ALAPI ALvoid ALAPIENTRY alGetListenerfv(ALenum eParam, ALfloat *pflValues)
|
||||
{
|
||||
ALCcontext *pContext;
|
||||
|
||||
pContext = alcGetCurrentContext();
|
||||
if (pContext)
|
||||
{
|
||||
SuspendContext(pContext);
|
||||
|
||||
if (pflValues)
|
||||
{
|
||||
switch (eParam)
|
||||
{
|
||||
case AL_GAIN:
|
||||
pflValues[0] = pContext->Listener.Gain;
|
||||
break;
|
||||
|
||||
case AL_POSITION:
|
||||
pflValues[0] = pContext->Listener.Position[0];
|
||||
pflValues[1] = pContext->Listener.Position[1];
|
||||
pflValues[2] = pContext->Listener.Position[2];
|
||||
break;
|
||||
|
||||
case AL_VELOCITY:
|
||||
pflValues[0] = pContext->Listener.Velocity[0];
|
||||
pflValues[1] = pContext->Listener.Velocity[1];
|
||||
pflValues[2] = pContext->Listener.Velocity[2];
|
||||
break;
|
||||
|
||||
case AL_ORIENTATION:
|
||||
LockContext(Context);
|
||||
// AT then UP
|
||||
pflValues[0] = pContext->Listener.Forward[0];
|
||||
pflValues[1] = pContext->Listener.Forward[1];
|
||||
pflValues[2] = pContext->Listener.Forward[2];
|
||||
pflValues[3] = pContext->Listener.Up[0];
|
||||
pflValues[4] = pContext->Listener.Up[1];
|
||||
pflValues[5] = pContext->Listener.Up[2];
|
||||
values[0] = Context->Listener->Forward[0];
|
||||
values[1] = Context->Listener->Forward[1];
|
||||
values[2] = Context->Listener->Forward[2];
|
||||
values[3] = Context->Listener->Up[0];
|
||||
values[4] = Context->Listener->Up[1];
|
||||
values[5] = Context->Listener->Up[2];
|
||||
UnlockContext(Context);
|
||||
break;
|
||||
|
||||
default:
|
||||
alSetError(AL_INVALID_ENUM);
|
||||
break;
|
||||
}
|
||||
al_throwerr(Context, AL_INVALID_ENUM);
|
||||
}
|
||||
else
|
||||
alSetError(AL_INVALID_VALUE);
|
||||
|
||||
ProcessContext(pContext);
|
||||
}
|
||||
else
|
||||
alSetError(AL_INVALID_OPERATION);
|
||||
al_endtry;
|
||||
|
||||
return;
|
||||
ALCcontext_DecRef(Context);
|
||||
}
|
||||
|
||||
|
||||
ALAPI ALvoid ALAPIENTRY alGetListeneri(ALenum eParam, ALint *plValue)
|
||||
AL_API ALvoid AL_APIENTRY alGetListeneri(ALenum param, ALint *value)
|
||||
{
|
||||
ALCcontext *pContext;
|
||||
ALCcontext *Context;
|
||||
|
||||
pContext = alcGetCurrentContext();
|
||||
if (pContext)
|
||||
Context = GetContextRef();
|
||||
if(!Context) return;
|
||||
|
||||
al_try
|
||||
{
|
||||
SuspendContext(pContext);
|
||||
|
||||
if (plValue)
|
||||
CHECK_VALUE(Context, value);
|
||||
switch(param)
|
||||
{
|
||||
switch (eParam)
|
||||
{
|
||||
default:
|
||||
alSetError(AL_INVALID_ENUM);
|
||||
break;
|
||||
}
|
||||
al_throwerr(Context, AL_INVALID_ENUM);
|
||||
}
|
||||
else
|
||||
alSetError(AL_INVALID_VALUE);
|
||||
|
||||
ProcessContext(pContext);
|
||||
}
|
||||
else
|
||||
alSetError(AL_INVALID_OPERATION);
|
||||
al_endtry;
|
||||
|
||||
return;
|
||||
ALCcontext_DecRef(Context);
|
||||
}
|
||||
|
||||
|
||||
ALAPI void ALAPIENTRY alGetListener3i(ALenum eParam, ALint *plValue1, ALint *plValue2, ALint *plValue3)
|
||||
AL_API void AL_APIENTRY alGetListener3i(ALenum param, ALint *value1, ALint *value2, ALint *value3)
|
||||
{
|
||||
ALCcontext *pContext;
|
||||
ALCcontext *Context;
|
||||
|
||||
pContext = alcGetCurrentContext();
|
||||
if (pContext)
|
||||
Context = GetContextRef();
|
||||
if(!Context) return;
|
||||
|
||||
al_try
|
||||
{
|
||||
SuspendContext(pContext);
|
||||
|
||||
if ((plValue1) && (plValue2) && (plValue3))
|
||||
CHECK_VALUE(Context, value1 && value2 && value3);
|
||||
switch (param)
|
||||
{
|
||||
switch (eParam)
|
||||
{
|
||||
case AL_POSITION:
|
||||
*plValue1 = (ALint)pContext->Listener.Position[0];
|
||||
*plValue2 = (ALint)pContext->Listener.Position[1];
|
||||
*plValue3 = (ALint)pContext->Listener.Position[2];
|
||||
LockContext(Context);
|
||||
*value1 = (ALint)Context->Listener->Position[0];
|
||||
*value2 = (ALint)Context->Listener->Position[1];
|
||||
*value3 = (ALint)Context->Listener->Position[2];
|
||||
UnlockContext(Context);
|
||||
break;
|
||||
|
||||
case AL_VELOCITY:
|
||||
*plValue1 = (ALint)pContext->Listener.Velocity[0];
|
||||
*plValue2 = (ALint)pContext->Listener.Velocity[1];
|
||||
*plValue3 = (ALint)pContext->Listener.Velocity[2];
|
||||
LockContext(Context);
|
||||
*value1 = (ALint)Context->Listener->Velocity[0];
|
||||
*value2 = (ALint)Context->Listener->Velocity[1];
|
||||
*value3 = (ALint)Context->Listener->Velocity[2];
|
||||
UnlockContext(Context);
|
||||
break;
|
||||
|
||||
default:
|
||||
alSetError(AL_INVALID_ENUM);
|
||||
break;
|
||||
}
|
||||
al_throwerr(Context, AL_INVALID_ENUM);
|
||||
}
|
||||
else
|
||||
alSetError(AL_INVALID_VALUE);
|
||||
|
||||
ProcessContext(pContext);
|
||||
}
|
||||
else
|
||||
alSetError(AL_INVALID_OPERATION);
|
||||
al_endtry;
|
||||
|
||||
return;
|
||||
ALCcontext_DecRef(Context);
|
||||
}
|
||||
|
||||
|
||||
ALAPI void ALAPIENTRY alGetListeneriv(ALenum eParam, ALint* plValues)
|
||||
AL_API void AL_APIENTRY alGetListeneriv(ALenum param, ALint* values)
|
||||
{
|
||||
ALCcontext *pContext;
|
||||
ALCcontext *Context;
|
||||
|
||||
pContext = alcGetCurrentContext();
|
||||
if (pContext)
|
||||
switch(param)
|
||||
{
|
||||
SuspendContext(pContext);
|
||||
case AL_POSITION:
|
||||
case AL_VELOCITY:
|
||||
alGetListener3i(param, values+0, values+1, values+2);
|
||||
return;
|
||||
}
|
||||
|
||||
if (plValues)
|
||||
Context = GetContextRef();
|
||||
if(!Context) return;
|
||||
|
||||
al_try
|
||||
{
|
||||
CHECK_VALUE(Context, values);
|
||||
switch(param)
|
||||
{
|
||||
switch (eParam)
|
||||
{
|
||||
case AL_POSITION:
|
||||
plValues[0] = (ALint)pContext->Listener.Position[0];
|
||||
plValues[1] = (ALint)pContext->Listener.Position[1];
|
||||
plValues[2] = (ALint)pContext->Listener.Position[2];
|
||||
break;
|
||||
|
||||
case AL_VELOCITY:
|
||||
plValues[0] = (ALint)pContext->Listener.Velocity[0];
|
||||
plValues[1] = (ALint)pContext->Listener.Velocity[1];
|
||||
plValues[2] = (ALint)pContext->Listener.Velocity[2];
|
||||
break;
|
||||
|
||||
case AL_ORIENTATION:
|
||||
LockContext(Context);
|
||||
// AT then UP
|
||||
plValues[0] = (ALint)pContext->Listener.Forward[0];
|
||||
plValues[1] = (ALint)pContext->Listener.Forward[1];
|
||||
plValues[2] = (ALint)pContext->Listener.Forward[2];
|
||||
plValues[3] = (ALint)pContext->Listener.Up[0];
|
||||
plValues[4] = (ALint)pContext->Listener.Up[1];
|
||||
plValues[5] = (ALint)pContext->Listener.Up[2];
|
||||
values[0] = (ALint)Context->Listener->Forward[0];
|
||||
values[1] = (ALint)Context->Listener->Forward[1];
|
||||
values[2] = (ALint)Context->Listener->Forward[2];
|
||||
values[3] = (ALint)Context->Listener->Up[0];
|
||||
values[4] = (ALint)Context->Listener->Up[1];
|
||||
values[5] = (ALint)Context->Listener->Up[2];
|
||||
UnlockContext(Context);
|
||||
break;
|
||||
|
||||
default:
|
||||
alSetError(AL_INVALID_ENUM);
|
||||
break;
|
||||
}
|
||||
al_throwerr(Context, AL_INVALID_ENUM);
|
||||
}
|
||||
else
|
||||
alSetError(AL_INVALID_VALUE);
|
||||
|
||||
ProcessContext(pContext);
|
||||
}
|
||||
else
|
||||
alSetError(AL_INVALID_OPERATION);
|
||||
al_endtry;
|
||||
|
||||
return;
|
||||
ALCcontext_DecRef(Context);
|
||||
}
|
||||
|
||||
+2567
-1831
File diff suppressed because it is too large
Load Diff
+415
-418
File diff suppressed because it is too large
Load Diff
+43
-62
@@ -18,91 +18,72 @@
|
||||
* Or go to http://www.gnu.org/copyleft/lgpl.html
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "alMain.h"
|
||||
#include "alThunk.h"
|
||||
|
||||
typedef struct {
|
||||
ALvoid *ptr;
|
||||
ALboolean InUse;
|
||||
} ThunkEntry;
|
||||
|
||||
static ThunkEntry *g_ThunkArray;
|
||||
static ALuint g_ThunkArraySize;
|
||||
static ALenum *ThunkArray;
|
||||
static ALuint ThunkArraySize;
|
||||
static RWLock ThunkLock;
|
||||
|
||||
static CRITICAL_SECTION g_ThunkLock;
|
||||
|
||||
void alThunkInit(void)
|
||||
void ThunkInit(void)
|
||||
{
|
||||
InitializeCriticalSection(&g_ThunkLock);
|
||||
g_ThunkArraySize = 1;
|
||||
g_ThunkArray = calloc(1, g_ThunkArraySize * sizeof(ThunkEntry));
|
||||
RWLockInit(&ThunkLock);
|
||||
ThunkArraySize = 1;
|
||||
ThunkArray = calloc(1, ThunkArraySize * sizeof(*ThunkArray));
|
||||
}
|
||||
|
||||
void alThunkExit(void)
|
||||
void ThunkExit(void)
|
||||
{
|
||||
free(g_ThunkArray);
|
||||
g_ThunkArray = NULL;
|
||||
g_ThunkArraySize = 0;
|
||||
DeleteCriticalSection(&g_ThunkLock);
|
||||
free(ThunkArray);
|
||||
ThunkArray = NULL;
|
||||
ThunkArraySize = 0;
|
||||
}
|
||||
|
||||
ALuint alThunkAddEntry(ALvoid *ptr)
|
||||
ALenum NewThunkEntry(ALuint *index)
|
||||
{
|
||||
ALuint index;
|
||||
ALenum *NewList;
|
||||
ALuint i;
|
||||
|
||||
EnterCriticalSection(&g_ThunkLock);
|
||||
|
||||
for(index = 0;index < g_ThunkArraySize;index++)
|
||||
ReadLock(&ThunkLock);
|
||||
for(i = 0;i < ThunkArraySize;i++)
|
||||
{
|
||||
if(g_ThunkArray[index].InUse == AL_FALSE)
|
||||
break;
|
||||
}
|
||||
|
||||
if(index == g_ThunkArraySize)
|
||||
{
|
||||
ThunkEntry *NewList;
|
||||
|
||||
NewList = realloc(g_ThunkArray, g_ThunkArraySize*2 * sizeof(ThunkEntry));
|
||||
if(!NewList)
|
||||
if(ExchangeInt(&ThunkArray[i], AL_TRUE) == AL_FALSE)
|
||||
{
|
||||
LeaveCriticalSection(&g_ThunkLock);
|
||||
return 0;
|
||||
ReadUnlock(&ThunkLock);
|
||||
*index = i+1;
|
||||
return AL_NO_ERROR;
|
||||
}
|
||||
memset(&NewList[g_ThunkArraySize], 0, g_ThunkArraySize*sizeof(ThunkEntry));
|
||||
g_ThunkArraySize *= 2;
|
||||
g_ThunkArray = NewList;
|
||||
}
|
||||
ReadUnlock(&ThunkLock);
|
||||
|
||||
g_ThunkArray[index].ptr = ptr;
|
||||
g_ThunkArray[index].InUse = AL_TRUE;
|
||||
WriteLock(&ThunkLock);
|
||||
NewList = realloc(ThunkArray, ThunkArraySize*2 * sizeof(*ThunkArray));
|
||||
if(!NewList)
|
||||
{
|
||||
WriteUnlock(&ThunkLock);
|
||||
ERR("Realloc failed to increase to %u entries!\n", ThunkArraySize*2);
|
||||
return AL_OUT_OF_MEMORY;
|
||||
}
|
||||
memset(&NewList[ThunkArraySize], 0, ThunkArraySize*sizeof(*ThunkArray));
|
||||
ThunkArraySize *= 2;
|
||||
ThunkArray = NewList;
|
||||
|
||||
LeaveCriticalSection(&g_ThunkLock);
|
||||
ThunkArray[i] = AL_TRUE;
|
||||
WriteUnlock(&ThunkLock);
|
||||
|
||||
return index+1;
|
||||
*index = i+1;
|
||||
return AL_NO_ERROR;
|
||||
}
|
||||
|
||||
void alThunkRemoveEntry(ALuint index)
|
||||
void FreeThunkEntry(ALuint index)
|
||||
{
|
||||
EnterCriticalSection(&g_ThunkLock);
|
||||
|
||||
if(index > 0 && index <= g_ThunkArraySize)
|
||||
g_ThunkArray[index-1].InUse = AL_FALSE;
|
||||
|
||||
LeaveCriticalSection(&g_ThunkLock);
|
||||
}
|
||||
|
||||
ALvoid *alThunkLookupEntry(ALuint index)
|
||||
{
|
||||
ALvoid *ptr = NULL;
|
||||
|
||||
EnterCriticalSection(&g_ThunkLock);
|
||||
|
||||
if(index > 0 && index <= g_ThunkArraySize)
|
||||
ptr = g_ThunkArray[index-1].ptr;
|
||||
|
||||
LeaveCriticalSection(&g_ThunkLock);
|
||||
|
||||
return ptr;
|
||||
ReadLock(&ThunkLock);
|
||||
if(index > 0 && index <= ThunkArraySize)
|
||||
ExchangeInt(&ThunkArray[index-1], AL_FALSE);
|
||||
ReadUnlock(&ThunkLock);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,53 @@
|
||||
Source Install
|
||||
==============
|
||||
|
||||
To install OpenAL Soft, use your favorite shell to go into the build/
|
||||
directory, and run:
|
||||
|
||||
cmake ..
|
||||
|
||||
Assuming configuration went well, you can then build it, typically using GNU
|
||||
Make (KDevelop, MSVC, and others are possible depending on your system setup
|
||||
and CMake configuration).
|
||||
|
||||
Please Note: Double check that the appropriate backends were detected. Often,
|
||||
complaints of no sound, crashing, and missing devices can be solved by making
|
||||
sure the correct backends are being used. CMake's output will identify which
|
||||
backends were enabled.
|
||||
|
||||
For most systems, you will likely want to make sure ALSA, OSS, and PulseAudio
|
||||
were detected (if your target system uses them). For Windows, make sure
|
||||
DirectSound was detected.
|
||||
|
||||
|
||||
Utilities
|
||||
=========
|
||||
|
||||
The source package comes with an informational utility, openal-info, and is
|
||||
built by default. It prints out information provided by the ALC and AL sub-
|
||||
systems, including discovered devices, version information, and extensions.
|
||||
|
||||
|
||||
Configuration
|
||||
=============
|
||||
|
||||
OpenAL Soft can be configured on a per-user and per-system basis. This allows
|
||||
users and sysadmins to control information provided to applications, as well
|
||||
as application-agnostic behavior of the library. See alsoftrc.sample for
|
||||
available settings.
|
||||
|
||||
|
||||
Acknowledgements
|
||||
================
|
||||
|
||||
Special thanks go to:
|
||||
|
||||
Creative Labs for the original source code this is based off of.
|
||||
|
||||
Christopher Fitzgerald for the current reverb effect implementation, and
|
||||
helping with the low-pass filter.
|
||||
|
||||
Christian Borss for the 3D panning code the current implementation is heavilly
|
||||
based on.
|
||||
|
||||
Ben Davis for the idea behind the current click-removal code.
|
||||
@@ -0,0 +1,30 @@
|
||||
# Cross-compiling requires CMake 2.6 or newer. To use it from build/, call it
|
||||
# like this:
|
||||
# cmake .. -DCMAKE_TOOLCHAIN_FILE=../XCompile.txt -DHOST=i686-pc-mingw32
|
||||
# Where 'i686-pc-mingw32' is the host prefix for your cross-compiler. If you
|
||||
# already have a toolchain file setup, you may use that instead of this file.
|
||||
|
||||
# the name of the target operating system
|
||||
SET(CMAKE_SYSTEM_NAME Windows)
|
||||
|
||||
# which compilers to use for C and C++
|
||||
SET(CMAKE_C_COMPILER "${HOST}-gcc")
|
||||
SET(CMAKE_CXX_COMPILER "${HOST}-g++")
|
||||
|
||||
# here is the target environment located
|
||||
SET(CMAKE_FIND_ROOT_PATH "/usr/${HOST}")
|
||||
|
||||
# here is where stuff gets installed to
|
||||
SET(CMAKE_INSTALL_PREFIX "${CMAKE_FIND_ROOT_PATH}/usr" CACHE STRING "Install path prefix, prepended onto install directories." FORCE)
|
||||
|
||||
# adjust the default behaviour of the FIND_XXX() commands:
|
||||
# search headers and libraries in the target environment, search
|
||||
# programs in the host environment
|
||||
set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)
|
||||
set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
|
||||
set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)
|
||||
|
||||
# set env vars so that pkg-config will look in the appropriate directory for
|
||||
# .pc files (as there seems to be no way to force using ${HOST}-pkg-config)
|
||||
set(ENV{PKG_CONFIG_LIBDIR} "${CMAKE_INSTALL_PREFIX}/lib/pkgconfig")
|
||||
set(ENV{PKG_CONFIG_PATH} "")
|
||||
+328
@@ -0,0 +1,328 @@
|
||||
# OpenAL config file. Options that are not under a block or are under the
|
||||
# [general] block are for general, non-backend-specific options. Blocks may
|
||||
# appear multiple times, and duplicated options will take the last value
|
||||
# specified.
|
||||
# The system-wide settings can be put in /etc/openal/alsoft.conf and user-
|
||||
# specific override settings in ~/.alsoftrc.
|
||||
# For Windows, these settings should go into %AppData%\alsoft.ini
|
||||
|
||||
# Option and block names are case-insenstive. The supplied values are only
|
||||
# hints and may not be honored (though generally it'll try to get as close as
|
||||
# possible). Note: options that are left unset may default to app- or system-
|
||||
# specified values. These are the current available settings:
|
||||
|
||||
## disable-cpu-exts:
|
||||
# Disables use of the listed CPU extensions. Certain methods may utilize CPU
|
||||
# extensions when detected, and this option is useful for preventing those
|
||||
# extensions from being used. The available extensions are: sse, neon.
|
||||
# Specifying 'all' disables use of all extensions.
|
||||
#disable-cpu-exts =
|
||||
|
||||
## channels:
|
||||
# Sets the output channel configuration. If left unspecified, one will try to
|
||||
# be detected from the system, and defaulting to stereo. The available values
|
||||
# are: mono, stereo, quad, surround51, surround61, surround71
|
||||
#channels = stereo
|
||||
|
||||
## sample-type:
|
||||
# Sets the output sample type. Currently, all mixing is done with 32-bit float
|
||||
# and converted to the output sample type as needed. Available values are:
|
||||
# int8 - signed 8-bit int
|
||||
# uint8 - unsigned 8-bit int
|
||||
# int16 - signed 16-bit int
|
||||
# uint16 - unsigned 16-bit int
|
||||
# int32 - signed 32-bit int
|
||||
# uint32 - unsigned 32-bit int
|
||||
# float32 - 32-bit float
|
||||
#sample-type = float32
|
||||
|
||||
## hrtf:
|
||||
# Enables HRTF filters. These filters provide for better sound spatialization
|
||||
# while using headphones. The default filter will only work when output is
|
||||
# 44100hz stereo. While HRTF is active, the cf_level option is disabled.
|
||||
# Default is disabled since stereo speaker output quality may suffer.
|
||||
#hrtf = false
|
||||
|
||||
## hrtf_tables
|
||||
# Specifies a comma-separated list of files containing HRTF data sets. The
|
||||
# listed data sets can be used in place of or in addiiton to the the built-in
|
||||
# set. The format of the files are described in hrtf.txt. The filenames may
|
||||
# contain these markers, which will be replaced as needed:
|
||||
# %r - Device sampling rate
|
||||
# %% - Percent sign (%)
|
||||
# So if this is set to "kemar-%r-diffuse.mhr", it will try to open
|
||||
# "kemar-44100-diffuse.mhr" if the device is using 44100hz output, or
|
||||
# "kemar-48000-diffuse.mhr" if the device is using 48000hz output, etc.
|
||||
#hrtf_tables =
|
||||
|
||||
## cf_level:
|
||||
# Sets the crossfeed level for stereo output. Valid values are:
|
||||
# 0 - No crossfeed
|
||||
# 1 - Low crossfeed
|
||||
# 2 - Middle crossfeed
|
||||
# 3 - High crossfeed (virtual speakers are closer to itself)
|
||||
# 4 - Low easy crossfeed
|
||||
# 5 - Middle easy crossfeed
|
||||
# 6 - High easy crossfeed
|
||||
# Users of headphones may want to try various settings. Has no effect on non-
|
||||
# stereo modes.
|
||||
#cf_level = 0
|
||||
|
||||
## wide-stereo:
|
||||
# Specifies that stereo sources are given a width of about 120 degrees on each
|
||||
# channel, centering on -90 (left) and +90 (right), as opposed to being points
|
||||
# placed at -30 (left) and +30 (right). This can be useful for surround-sound
|
||||
# to give stereo sources a more encompassing sound. Note that the sound's
|
||||
# overall volume will be slightly reduced to account for the extra output.
|
||||
#wide-stereo = false
|
||||
|
||||
## frequency:
|
||||
# Sets the output frequency.
|
||||
#frequency = 44100
|
||||
|
||||
## resampler:
|
||||
# Selects the resampler used when mixing sources. Valid values are:
|
||||
# point - nearest sample, no interpolation
|
||||
# linear - extrapolates samples using a linear slope between samples
|
||||
# cubic - extrapolates samples using a Catmull-Rom spline
|
||||
# Specifying other values will result in using the default (linear).
|
||||
#resampler = linear
|
||||
|
||||
## rt-prio:
|
||||
# Sets real-time priority for the mixing thread. Not all drivers may use this
|
||||
# (eg. PortAudio) as they already control the priority of the mixing thread.
|
||||
# 0 and negative values will disable it. Note that this may constitute a
|
||||
# security risk since a real-time priority thread can indefinitely block
|
||||
# normal-priority threads if it fails to wait. As such, the default is
|
||||
# disabled.
|
||||
#rt-prio = 0
|
||||
|
||||
## period_size:
|
||||
# Sets the update period size, in frames. This is the number of frames needed
|
||||
# for each mixing update. Acceptable values range between 64 and 8192.
|
||||
#period_size = 1024
|
||||
|
||||
## periods:
|
||||
# Sets the number of update periods. Higher values create a larger mix ahead,
|
||||
# which helps protect against skips when the CPU is under load, but increases
|
||||
# the delay between a sound getting mixed and being heard. Acceptable values
|
||||
# range between 2 and 16.
|
||||
#periods = 4
|
||||
|
||||
## sources:
|
||||
# Sets the maximum number of allocatable sources. Lower values may help for
|
||||
# systems with apps that try to play more sounds than the CPU can handle.
|
||||
#sources = 256
|
||||
|
||||
## drivers:
|
||||
# Sets the backend driver list order, comma-seperated. Unknown backends and
|
||||
# duplicated names are ignored. Unlisted backends won't be considered for use
|
||||
# unless the list is ended with a comma (eg. 'oss,' will list OSS first
|
||||
# followed by all other available backends, while 'oss' will list OSS only).
|
||||
# Backends prepended with - won't be available for use (eg. '-oss,' will allow
|
||||
# all available backends except OSS). An empty list means the default.
|
||||
#drivers = pulse,alsa,core,oss,solaris,sndio,mmdevapi,dsound,winmm,port,opensl,null,wave
|
||||
|
||||
## excludefx:
|
||||
# Sets which effects to exclude, preventing apps from using them. This can
|
||||
# help for apps that try to use effects which are too CPU intensive for the
|
||||
# system to handle. Available effects are: eaxreverb,reverb,echo,modulator,
|
||||
# dedicated
|
||||
#excludefx =
|
||||
|
||||
## slots:
|
||||
# Sets the maximum number of Auxiliary Effect Slots an app can create. A slot
|
||||
# can use a non-negligible amount of CPU time if an effect is set on it even
|
||||
# if no sources are feeding it, so this may help when apps use more than the
|
||||
# system can handle.
|
||||
#slots = 4
|
||||
|
||||
## sends:
|
||||
# Sets the number of auxiliary sends per source. When not specified (default),
|
||||
# it allows the app to request how many it wants. The maximum value currently
|
||||
# possible is 4.
|
||||
#sends =
|
||||
|
||||
## layout:
|
||||
# Sets the virtual speaker layout. Values are specified in degrees, where 0 is
|
||||
# straight in front, negative goes left, and positive goes right. Unspecified
|
||||
# speakers will remain at their default positions (which are dependant on the
|
||||
# output format). Available speakers are back-left(bl), side-left(sl), front-
|
||||
# left(fl), front-center(fc), front-right(fr), side-right(sr), back-right(br),
|
||||
# and back-center(bc).
|
||||
#layout =
|
||||
|
||||
## layout_*:
|
||||
# Channel-specific layouts may be specified to override the layout option. The
|
||||
# same speakers as the layout option are available, and the default settings
|
||||
# are shown below.
|
||||
#layout_stereo = fl=-90, fr=90
|
||||
#layout_quad = fl=-45, fr=45, bl=-135, br=135
|
||||
#layout_surround51 = fl=-30, fr=30, fc=0, bl=-110, br=110
|
||||
#layout_surround61 = fl=-30, fr=30, fc=0, sl=-90, sr=90, bc=180
|
||||
#layout_surround71 = fl=-30, fr=30, fc=0, sl=-90, sr=90, bl=-150, br=150
|
||||
|
||||
## default-reverb:
|
||||
# A reverb preset that applies by default to all sources on send 0
|
||||
# (applications that set their own slots on send 0 will override this).
|
||||
# Available presets are: None, Generic, PaddedCell, Room, Bathroom,
|
||||
# Livingroom, Stoneroom, Auditorium, ConcertHall, Cave, Arena, Hangar,
|
||||
# CarpetedHallway, Hallway, StoneCorridor, Alley, Forest, City, Moutains,
|
||||
# Quarry, Plain, ParkingLot, SewerPipe, Underwater, Drugged, Dizzy, Psychotic.
|
||||
#default-reverb =
|
||||
|
||||
## trap-alc-error:
|
||||
# Generates a SIGTRAP signal when an ALC device error is generated, on systems
|
||||
# that support it. This helps when debugging, while trying to find the cause
|
||||
# of a device error. On Windows, a breakpoint exception is generated.
|
||||
#trap-alc-error = false
|
||||
|
||||
## trap-al-error:
|
||||
# Generates a SIGTRAP signal when an AL context error is generated, on systems
|
||||
# that support it. This helps when debugging, while trying to find the cause
|
||||
# of a context error. On Windows, a breakpoint exception is generated.
|
||||
#trap-al-error = false
|
||||
|
||||
##
|
||||
## Reverb effect stuff (includes EAX reverb)
|
||||
##
|
||||
[reverb]
|
||||
|
||||
## boost:
|
||||
# A global amplification for reverb output, expressed in decibels. The value
|
||||
# is logarithmic, so +6 will be a scale of (approximately) 2x, +12 will be a
|
||||
# scale of 4x, etc. Similarly, -6 will be about half, and -12 about 1/4th. A
|
||||
# value of 0 means no change.
|
||||
#boost = 0
|
||||
|
||||
## emulate-eax:
|
||||
# Allows the standard reverb effect to be used in place of EAX reverb. EAX
|
||||
# reverb processing is a bit more CPU intensive than standard, so this option
|
||||
# allows a simpler effect to be used at the loss of some quality.
|
||||
#emulate-eax = false
|
||||
|
||||
##
|
||||
## ALSA backend stuff
|
||||
##
|
||||
[alsa]
|
||||
|
||||
## device:
|
||||
# Sets the device name for the default playback device.
|
||||
#device = default
|
||||
|
||||
## device-prefix:
|
||||
# Sets the prefix used by the discovered (non-default) playback devices. This
|
||||
# will be appended with "CARD=c,DEV=d", where c is the card id and d is the
|
||||
# device index for the requested device name.
|
||||
#device-prefix = plughw:
|
||||
|
||||
## device-prefix-*:
|
||||
# Card- and device-specific prefixes may be used to override the device-prefix
|
||||
# option. The option may specify the card id (eg, device-prefix-NVidia), or
|
||||
# the card id and device index (eg, device-prefix-NVidia-0). The card id is
|
||||
# case-sensitive.
|
||||
#device-prefix- =
|
||||
|
||||
## capture:
|
||||
# Sets the device name for the default capture device.
|
||||
#capture = default
|
||||
|
||||
## capture-prefix:
|
||||
# Sets the prefix used by the discovered (non-default) capture devices. This
|
||||
# will be appended with "CARD=c,DEV=d", where c is the card id and d is the
|
||||
# device number for the requested device name.
|
||||
#capture-prefix = plughw:
|
||||
|
||||
## capture-prefix-*:
|
||||
# Card- and device-specific prefixes may be used to override the
|
||||
# capture-prefix option. The option may specify the card id (eg,
|
||||
# capture-prefix-NVidia), or the card id and device index (eg,
|
||||
# capture-prefix-NVidia-0). The card id is case-sensitive.
|
||||
#capture-prefix- =
|
||||
|
||||
## mmap:
|
||||
# Sets whether to try using mmap mode (helps reduce latencies and CPU
|
||||
# consumption). If mmap isn't available, it will automatically fall back to
|
||||
# non-mmap mode. True, yes, on, and non-0 values will attempt to use mmap. 0
|
||||
# and anything else will force mmap off.
|
||||
#mmap = true
|
||||
|
||||
##
|
||||
## OSS backend stuff
|
||||
##
|
||||
[oss]
|
||||
|
||||
## device:
|
||||
# Sets the device name for OSS output.
|
||||
#device = /dev/dsp
|
||||
|
||||
## capture:
|
||||
# Sets the device name for OSS capture.
|
||||
#capture = /dev/dsp
|
||||
|
||||
##
|
||||
## Solaris backend stuff
|
||||
##
|
||||
[solaris]
|
||||
|
||||
## device:
|
||||
# Sets the device name for Solaris output.
|
||||
#device = /dev/audio
|
||||
|
||||
##
|
||||
## MMDevApi backend stuff
|
||||
##
|
||||
[mmdevapi]
|
||||
|
||||
##
|
||||
## DirectSound backend stuff
|
||||
##
|
||||
[dsound]
|
||||
|
||||
##
|
||||
## Windows Multimedia backend stuff
|
||||
##
|
||||
[winmm]
|
||||
|
||||
##
|
||||
## PortAudio backend stuff
|
||||
##
|
||||
[port]
|
||||
|
||||
## device:
|
||||
# Sets the device index for output. Negative values will use the default as
|
||||
# given by PortAudio itself.
|
||||
#device = -1
|
||||
|
||||
## capture:
|
||||
# Sets the device index for capture. Negative values will use the default as
|
||||
# given by PortAudio itself.
|
||||
#capture = -1
|
||||
|
||||
##
|
||||
## PulseAudio backend stuff
|
||||
##
|
||||
[pulse]
|
||||
|
||||
## spawn-server:
|
||||
# Attempts to spawn a PulseAudio server when requesting to open a PulseAudio
|
||||
# device. Setting autospawn to false in PulseAudio's client.conf will still
|
||||
# prevent autospawning even if this is set to true.
|
||||
#spawn-server = true
|
||||
|
||||
## allow-moves:
|
||||
# Allows PulseAudio to move active streams to different devices. Note that the
|
||||
# device specifier seen by applications will not be updated when this occurs,
|
||||
# and neither will the AL device configuration (sample rate, format, etc).
|
||||
#allow-moves = false
|
||||
|
||||
##
|
||||
## Wave File Writer stuff
|
||||
##
|
||||
[wave]
|
||||
|
||||
## file:
|
||||
# Sets the filename of the wave file to write to. An empty name prevents the
|
||||
# backend from opening, even when explicitly requested.
|
||||
# THIS WILL OVERWRITE EXISTING FILES WITHOUT QUESTION!
|
||||
#file =
|
||||
@@ -0,0 +1,59 @@
|
||||
# - Check if the C source code provided in the SOURCE argument compiles.
|
||||
# CHECK_C_SOURCE_COMPILES(SOURCE VAR)
|
||||
#
|
||||
# FLAG - compiler flag to check
|
||||
# VAR - variable to store whether the source code compiled
|
||||
#
|
||||
# The following variables may be set before calling this macro to
|
||||
# modify the way the check is run:
|
||||
#
|
||||
# CMAKE_REQUIRED_FLAGS = string of compile command line flags
|
||||
# CMAKE_REQUIRED_DEFINITIONS = list of macros to define (-DFOO=bar)
|
||||
# CMAKE_REQUIRED_INCLUDES = list of include directories
|
||||
# CMAKE_REQUIRED_LIBRARIES = list of libraries to link
|
||||
|
||||
MACRO(CHECK_C_COMPILER_FLAG FLAG VAR)
|
||||
IF("${VAR}" MATCHES "^${VAR}$")
|
||||
SET(MACRO_CHECK_FUNCTION_DEFINITIONS
|
||||
"${FLAG} ${CMAKE_REQUIRED_FLAGS}")
|
||||
IF(CMAKE_REQUIRED_LIBRARIES)
|
||||
SET(CHECK_C_COMPILER_FLAG_ADD_LIBRARIES
|
||||
"-DLINK_LIBRARIES:STRING=${CMAKE_REQUIRED_LIBRARIES}")
|
||||
ELSE(CMAKE_REQUIRED_LIBRARIES)
|
||||
SET(CHECK_C_COMPILER_FLAG_ADD_LIBRARIES)
|
||||
ENDIF(CMAKE_REQUIRED_LIBRARIES)
|
||||
IF(CMAKE_REQUIRED_INCLUDES)
|
||||
SET(CHECK_C_COMPILER_FLAG_ADD_INCLUDES
|
||||
"-DINCLUDE_DIRECTORIES:STRING=${CMAKE_REQUIRED_INCLUDES}")
|
||||
ELSE(CMAKE_REQUIRED_INCLUDES)
|
||||
SET(CHECK_C_COMPILER_FLAG_ADD_INCLUDES)
|
||||
ENDIF(CMAKE_REQUIRED_INCLUDES)
|
||||
FILE(WRITE "${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp/src.c"
|
||||
"int main() {return 0;}\n")
|
||||
|
||||
MESSAGE(STATUS "Checking if C compiler supports ${FLAG}")
|
||||
TRY_COMPILE(${VAR}
|
||||
${CMAKE_BINARY_DIR}
|
||||
${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp/src.c
|
||||
COMPILE_DEFINITIONS ${CMAKE_REQUIRED_DEFINITIONS}
|
||||
CMAKE_FLAGS -DCOMPILE_DEFINITIONS:STRING=${MACRO_CHECK_FUNCTION_DEFINITIONS}
|
||||
"${CHECK_C_COMPILER_FLAG_ADD_LIBRARIES}"
|
||||
"${CHECK_C_COMPILER_FLAG_ADD_INCLUDES}"
|
||||
OUTPUT_VARIABLE OUTPUT)
|
||||
IF(${VAR})
|
||||
SET(${VAR} 1 CACHE INTERNAL "Test ${VAR}")
|
||||
MESSAGE(STATUS "Checking if C compiler supports ${FLAG} - Success")
|
||||
FILE(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeOutput.log
|
||||
"Performing C SOURCE FILE Test ${VAR} succeded with the following output:\n"
|
||||
"${OUTPUT}\n"
|
||||
"Source file was:\n${SOURCE}\n")
|
||||
ELSE(${VAR})
|
||||
MESSAGE(STATUS "Checking if C compiler supports ${FLAG} - Failed")
|
||||
SET(${VAR} "" CACHE INTERNAL "Test ${VAR}")
|
||||
FILE(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeError.log
|
||||
"Performing C SOURCE FILE Test ${VAR} failed with the following output:\n"
|
||||
"${OUTPUT}\n"
|
||||
"Source file was:\n${SOURCE}\n")
|
||||
ENDIF(${VAR})
|
||||
ENDIF("${VAR}" MATCHES "^${VAR}$")
|
||||
ENDMACRO(CHECK_C_COMPILER_FLAG)
|
||||
@@ -0,0 +1,92 @@
|
||||
# - Check if a symbol exists as a function, variable, or macro
|
||||
# CHECK_SYMBOL_EXISTS(<symbol> <files> <variable>)
|
||||
#
|
||||
# Check that the <symbol> is available after including given header
|
||||
# <files> and store the result in a <variable>. Specify the list
|
||||
# of files in one argument as a semicolon-separated list.
|
||||
#
|
||||
# If the header files define the symbol as a macro it is considered
|
||||
# available and assumed to work. If the header files declare the
|
||||
# symbol as a function or variable then the symbol must also be
|
||||
# available for linking. If the symbol is a type or enum value
|
||||
# it will not be recognized (consider using CheckTypeSize or
|
||||
# CheckCSourceCompiles).
|
||||
#
|
||||
# The following variables may be set before calling this macro to
|
||||
# modify the way the check is run:
|
||||
#
|
||||
# CMAKE_REQUIRED_FLAGS = string of compile command line flags
|
||||
# CMAKE_REQUIRED_DEFINITIONS = list of macros to define (-DFOO=bar)
|
||||
# CMAKE_REQUIRED_INCLUDES = list of include directories
|
||||
# CMAKE_REQUIRED_LIBRARIES = list of libraries to link
|
||||
|
||||
#=============================================================================
|
||||
# Copyright 2003-2011 Kitware, Inc.
|
||||
#
|
||||
# Distributed under the OSI-approved BSD License (the "License");
|
||||
# see accompanying file Copyright.txt for details.
|
||||
#
|
||||
# This software is distributed WITHOUT ANY WARRANTY; without even the
|
||||
# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
# See the License for more information.
|
||||
#=============================================================================
|
||||
# (To distribute this file outside of CMake, substitute the full
|
||||
# License text for the above reference.)
|
||||
|
||||
MACRO(CHECK_SHARED_FUNCTION_EXISTS SYMBOL FILES LIBRARY LOCATION VARIABLE)
|
||||
IF("${VARIABLE}" MATCHES "^${VARIABLE}$")
|
||||
SET(CMAKE_CONFIGURABLE_FILE_CONTENT "/* */\n")
|
||||
SET(MACRO_CHECK_SYMBOL_EXISTS_FLAGS ${CMAKE_REQUIRED_FLAGS})
|
||||
IF(CMAKE_REQUIRED_LIBRARIES)
|
||||
SET(CHECK_SYMBOL_EXISTS_LIBS
|
||||
"-DLINK_LIBRARIES:STRING=${CMAKE_REQUIRED_LIBRARIES};${LIBRARY}")
|
||||
ELSE(CMAKE_REQUIRED_LIBRARIES)
|
||||
SET(CHECK_SYMBOL_EXISTS_LIBS
|
||||
"-DLINK_LIBRARIES:STRING=${LIBRARY}")
|
||||
ENDIF(CMAKE_REQUIRED_LIBRARIES)
|
||||
IF(CMAKE_REQUIRED_INCLUDES)
|
||||
SET(CMAKE_SYMBOL_EXISTS_INCLUDES
|
||||
"-DINCLUDE_DIRECTORIES:STRING=${CMAKE_REQUIRED_INCLUDES}")
|
||||
ELSE(CMAKE_REQUIRED_INCLUDES)
|
||||
SET(CMAKE_SYMBOL_EXISTS_INCLUDES)
|
||||
ENDIF(CMAKE_REQUIRED_INCLUDES)
|
||||
FOREACH(FILE ${FILES})
|
||||
SET(CMAKE_CONFIGURABLE_FILE_CONTENT
|
||||
"${CMAKE_CONFIGURABLE_FILE_CONTENT}#include <${FILE}>\n")
|
||||
ENDFOREACH(FILE)
|
||||
SET(CMAKE_CONFIGURABLE_FILE_CONTENT
|
||||
"${CMAKE_CONFIGURABLE_FILE_CONTENT}\nvoid cmakeRequireSymbol(int dummy,...){(void)dummy;}\nint main()\n{\n cmakeRequireSymbol(0,&${SYMBOL});\n return 0;\n}\n")
|
||||
|
||||
CONFIGURE_FILE("${CMAKE_ROOT}/Modules/CMakeConfigurableFile.in"
|
||||
"${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp/CheckSymbolExists.c" @ONLY)
|
||||
|
||||
MESSAGE(STATUS "Looking for ${SYMBOL} in ${LIBRARY}")
|
||||
TRY_COMPILE(${VARIABLE}
|
||||
${CMAKE_BINARY_DIR}
|
||||
${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp/CheckSymbolExists.c
|
||||
COMPILE_DEFINITIONS ${CMAKE_REQUIRED_DEFINITIONS}
|
||||
CMAKE_FLAGS
|
||||
-DCOMPILE_DEFINITIONS:STRING=${MACRO_CHECK_SYMBOL_EXISTS_FLAGS}
|
||||
-DLINK_DIRECTORIES:STRING=${LOCATION}
|
||||
"${CHECK_SYMBOL_EXISTS_LIBS}"
|
||||
"${CMAKE_SYMBOL_EXISTS_INCLUDES}"
|
||||
OUTPUT_VARIABLE OUTPUT)
|
||||
IF(${VARIABLE})
|
||||
MESSAGE(STATUS "Looking for ${SYMBOL} in ${LIBRARY} - found")
|
||||
SET(${VARIABLE} 1 CACHE INTERNAL "Have symbol ${SYMBOL} in ${LIBRARY}")
|
||||
FILE(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeOutput.log
|
||||
"Determining if the ${SYMBOL} "
|
||||
"exist in ${LIBRARY} passed with the following output:\n"
|
||||
"${OUTPUT}\nFile ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp/CheckSymbolExists.c:\n"
|
||||
"${CMAKE_CONFIGURABLE_FILE_CONTENT}\n")
|
||||
ELSE(${VARIABLE})
|
||||
MESSAGE(STATUS "Looking for ${SYMBOL} in ${LIBRARY} - not found.")
|
||||
SET(${VARIABLE} "" CACHE INTERNAL "Have symbol ${SYMBOL} in ${LIBRARY}")
|
||||
FILE(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeError.log
|
||||
"Determining if the ${SYMBOL} "
|
||||
"exist in ${LIBRARY} failed with the following output:\n"
|
||||
"${OUTPUT}\nFile ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp/CheckSymbolExists.c:\n"
|
||||
"${CMAKE_CONFIGURABLE_FILE_CONTENT}\n")
|
||||
ENDIF(${VARIABLE})
|
||||
ENDIF("${VARIABLE}" MATCHES "^${VARIABLE}$")
|
||||
ENDMACRO(CHECK_SHARED_FUNCTION_EXISTS)
|
||||
+111
-16
@@ -1,5 +1,33 @@
|
||||
#ifndef CONFIG_H
|
||||
#define CONFIG_H
|
||||
/* API declaration export attribute */
|
||||
#define AL_API ${EXPORT_DECL}
|
||||
#define ALC_API ${EXPORT_DECL}
|
||||
|
||||
/* Define to the library version */
|
||||
#define ALSOFT_VERSION "${LIB_VERSION}"
|
||||
|
||||
/* Define any available alignment declaration */
|
||||
#define ALIGN(x) ${ALIGN_DECL}
|
||||
#ifdef __MINGW32__
|
||||
#define align(x) aligned(x)
|
||||
#endif
|
||||
|
||||
/* Define to the appropriate 'restrict' keyword */
|
||||
#define RESTRICT ${RESTRICT_DECL}
|
||||
|
||||
/* Define if we have the C11 aligned_alloc function */
|
||||
#cmakedefine HAVE_ALIGNED_ALLOC
|
||||
|
||||
/* Define if we have the posix_memalign function */
|
||||
#cmakedefine HAVE_POSIX_MEMALIGN
|
||||
|
||||
/* Define if we have the _aligned_malloc function */
|
||||
#cmakedefine HAVE__ALIGNED_MALLOC
|
||||
|
||||
/* Define if we have SSE CPU extensions */
|
||||
#cmakedefine HAVE_SSE
|
||||
|
||||
/* Define if we have ARM Neon CPU extensions */
|
||||
#cmakedefine HAVE_NEON
|
||||
|
||||
/* Define if we have the ALSA backend */
|
||||
#cmakedefine HAVE_ALSA
|
||||
@@ -7,24 +35,45 @@
|
||||
/* Define if we have the OSS backend */
|
||||
#cmakedefine HAVE_OSS
|
||||
|
||||
/* Define if we have the Solaris backend */
|
||||
#cmakedefine HAVE_SOLARIS
|
||||
|
||||
/* Define if we have the SndIO backend */
|
||||
#cmakedefine HAVE_SNDIO
|
||||
|
||||
/* Define if we have the MMDevApi backend */
|
||||
#cmakedefine HAVE_MMDEVAPI
|
||||
|
||||
/* Define if we have the DSound backend */
|
||||
#cmakedefine HAVE_DSOUND
|
||||
|
||||
/* Define if we have the Windows Multimedia backend */
|
||||
#cmakedefine HAVE_WINMM
|
||||
|
||||
/* Define if we have dlfcn.h */
|
||||
#cmakedefine HAVE_DLFCN_H
|
||||
/* Define if we have the PortAudio backend */
|
||||
#cmakedefine HAVE_PORTAUDIO
|
||||
|
||||
/* Define if we have the sqrtf function */
|
||||
#cmakedefine HAVE_SQRTF
|
||||
/* Define if we have the PulseAudio backend */
|
||||
#cmakedefine HAVE_PULSEAUDIO
|
||||
|
||||
/* Define if we have the CoreAudio backend */
|
||||
#cmakedefine HAVE_COREAUDIO
|
||||
|
||||
/* Define if we have the OpenSL backend */
|
||||
#cmakedefine HAVE_OPENSL
|
||||
|
||||
/* Define if we have the Wave Writer backend */
|
||||
#cmakedefine HAVE_WAVE
|
||||
|
||||
/* Define if we have the stat function */
|
||||
#cmakedefine HAVE_STAT
|
||||
|
||||
/* Define if we have the lrintf function */
|
||||
#cmakedefine HAVE_LRINTF
|
||||
|
||||
/* Define if we have the strtof function */
|
||||
#cmakedefine HAVE_STRTOF
|
||||
|
||||
/* Define if we have stdint.h */
|
||||
#cmakedefine HAVE_STDINT_H
|
||||
|
||||
/* Define if we have the __int64 type */
|
||||
#cmakedefine HAVE___INT64
|
||||
|
||||
@@ -34,13 +83,59 @@
|
||||
/* Define to the size of a long long int type */
|
||||
#cmakedefine SIZEOF_LONG_LONG ${SIZEOF_LONG_LONG}
|
||||
|
||||
/* Define to the size of an unsigned int type */
|
||||
#cmakedefine SIZEOF_UINT ${SIZEOF_UINT}
|
||||
|
||||
/* Define to the size of a void pointer type */
|
||||
#cmakedefine SIZEOF_VOIDP ${SIZEOF_VOIDP}
|
||||
|
||||
/* Define if we have GCC's destructor attribute */
|
||||
#cmakedefine HAVE_GCC_DESTRUCTOR
|
||||
|
||||
#endif
|
||||
/* Define if we have GCC's format attribute */
|
||||
#cmakedefine HAVE_GCC_FORMAT
|
||||
|
||||
/* Define if we have stdint.h */
|
||||
#cmakedefine HAVE_STDINT_H
|
||||
|
||||
/* Define if we have windows.h */
|
||||
#cmakedefine HAVE_WINDOWS_H
|
||||
|
||||
/* Define if we have dlfcn.h */
|
||||
#cmakedefine HAVE_DLFCN_H
|
||||
|
||||
/* Define if we have pthread_np.h */
|
||||
#cmakedefine HAVE_PTHREAD_NP_H
|
||||
|
||||
/* Define if we have xmmintrin.h */
|
||||
#cmakedefine HAVE_XMMINTRIN_H
|
||||
|
||||
/* Define if we have arm_neon.h */
|
||||
#cmakedefine HAVE_ARM_NEON_H
|
||||
|
||||
/* Define if we have malloc.h */
|
||||
#cmakedefine HAVE_MALLOC_H
|
||||
|
||||
/* Define if we have cpuid.h */
|
||||
#cmakedefine HAVE_CPUID_H
|
||||
|
||||
/* Define if we have guiddef.h */
|
||||
#cmakedefine HAVE_GUIDDEF_H
|
||||
|
||||
/* Define if we have initguid.h */
|
||||
#cmakedefine HAVE_INITGUID_H
|
||||
|
||||
/* Define if we have ieeefp.h */
|
||||
#cmakedefine HAVE_IEEEFP_H
|
||||
|
||||
/* Define if we have float.h */
|
||||
#cmakedefine HAVE_FLOAT_H
|
||||
|
||||
/* Define if we have fenv.h */
|
||||
#cmakedefine HAVE_FENV_H
|
||||
|
||||
/* Define if we have fesetround() */
|
||||
#cmakedefine HAVE_FESETROUND
|
||||
|
||||
/* Define if we have _controlfp() */
|
||||
#cmakedefine HAVE__CONTROLFP
|
||||
|
||||
/* Define if we have __control87_2() */
|
||||
#cmakedefine HAVE___CONTROL87_2
|
||||
|
||||
/* Define if we have pthread_setschedparam() */
|
||||
#cmakedefine HAVE_PTHREAD_SETSCHEDPARAM
|
||||
|
||||
@@ -0,0 +1,71 @@
|
||||
Useful Environment Variables
|
||||
|
||||
Below is a list of environment variables that can be set to aid with running or
|
||||
debugging apps that use OpenAL Soft. They should be set before the app is run.
|
||||
|
||||
*** Logging ***
|
||||
|
||||
ALSOFT_LOGLEVEL
|
||||
Specifies the amount of logging OpenAL Soft will write out:
|
||||
0 - Effectively disables all logging
|
||||
1 - Prints out errors only
|
||||
2 - Prints out warnings and errors
|
||||
3 - Prints out additional information, as well as warnings and errors
|
||||
4 - Same as 3, but also device and context reference count changes. This will
|
||||
print out *a lot* of info, and is generally not useful unless you're trying
|
||||
to track a reference leak within the library.
|
||||
|
||||
ALSOFT_LOGFILE
|
||||
Specifies a filename that logged output will be written to. Note that the file
|
||||
will be first cleared when logging is initialized.
|
||||
|
||||
*** Overrides ***
|
||||
|
||||
ALSOFT_CONF
|
||||
Specifies an additional configuration file to load settings from. These
|
||||
settings will take precedence over the global and user configs, but not other
|
||||
environment variable settings.
|
||||
|
||||
ALSOFT_DRIVERS
|
||||
Overrides the drivers config option. This specifies which backend drivers to
|
||||
consider or not consider for use. Please see the drivers option in
|
||||
alsoftrc.sample for a list of available drivers.
|
||||
|
||||
ALSOFT_DEFAULT_REVERB
|
||||
Specifies the default reverb preset to apply to sources. Please see the
|
||||
default-reverb option in alsoftrc.sample for additional information and a list
|
||||
of available presets.
|
||||
|
||||
ALSOFT_TRAP_AL_ERROR
|
||||
Set to "true" or "1" to force trapping AL errors. Like the trap-al-error config
|
||||
option, this will raise a SIGTRAP signal (or a breakpoint exception under
|
||||
Windows) when a context-level error is generated. Useful when run under a
|
||||
debugger as it will break execution right when the error occurs, making it
|
||||
easier to track the cause.
|
||||
|
||||
ALSOFT_TRAP_ALC_ERROR
|
||||
Set to "true" or "1" to force trapping ALC errors. Like the trap-alc-error
|
||||
config option, this will raise a SIGTRAP signal (or a breakpoint exception
|
||||
under Windows) when a device-level error is generated. Useful when run under a
|
||||
debugger as it will break execution right when the error occurs, making it
|
||||
easier to track the cause.
|
||||
|
||||
ALSOFT_TRAP_ERROR
|
||||
Set to "true" or "1" to force trapping both ALC and AL errors.
|
||||
|
||||
*** Compatibility ***
|
||||
|
||||
__ALSOFT_HALF_ANGLE_CONES
|
||||
Older versions of OpenAL Soft incorrectly calculated the cone angles to range
|
||||
between 0 and 180 degrees, instead of the expected range of 0 to 360 degrees.
|
||||
Setting this to "true" or "1" restores the old buggy behavior, for apps that
|
||||
were written to expect the incorrect range.
|
||||
|
||||
__ALSOFT_REVERSE_Z
|
||||
Applications that don't natively use OpenAL's coordinate system have to convert
|
||||
to it before passing in 3D coordinates. Depending on how exactly this is done,
|
||||
it can cause correct output for stereo but incorrect Z panning for surround
|
||||
sound (i.e., sounds that are supposed to be behind you sound like they're in
|
||||
front, and vice-versa). Setting this to "true" or "1" will negate the localized
|
||||
Z coordinate to attempt to fix output for apps that have incorrect front/back
|
||||
panning.
|
||||
@@ -0,0 +1,213 @@
|
||||
/*
|
||||
* OpenAL Source Latency Example
|
||||
*
|
||||
* Copyright (c) 2012 by Chris Robinson <chris.kcat@gmail.com>
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
/* This file contains an example for checking the latency of a sound. */
|
||||
|
||||
#include <stdio.h>
|
||||
#include <assert.h>
|
||||
#ifdef _WIN32
|
||||
#define WIN32_LEAN_AND_MEAN
|
||||
#include <windows.h>
|
||||
#else
|
||||
#include <unistd.h>
|
||||
#define Sleep(x) usleep((x)*1000)
|
||||
#endif
|
||||
|
||||
#include "AL/al.h"
|
||||
#include "AL/alc.h"
|
||||
#include "AL/alext.h"
|
||||
|
||||
#include "common/alhelpers.h"
|
||||
#include "common/alffmpeg.h"
|
||||
|
||||
|
||||
LPALBUFFERSAMPLESSOFT alBufferSamplesSOFT = wrap_BufferSamples;
|
||||
LPALISBUFFERFORMATSUPPORTEDSOFT alIsBufferFormatSupportedSOFT;
|
||||
|
||||
LPALSOURCEDSOFT alSourcedSOFT;
|
||||
LPALSOURCE3DSOFT alSource3dSOFT;
|
||||
LPALSOURCEDVSOFT alSourcedvSOFT;
|
||||
LPALGETSOURCEDSOFT alGetSourcedSOFT;
|
||||
LPALGETSOURCE3DSOFT alGetSource3dSOFT;
|
||||
LPALGETSOURCEDVSOFT alGetSourcedvSOFT;
|
||||
LPALSOURCEI64SOFT alSourcei64SOFT;
|
||||
LPALSOURCE3I64SOFT alSource3i64SOFT;
|
||||
LPALSOURCEI64VSOFT alSourcei64vSOFT;
|
||||
LPALGETSOURCEI64SOFT alGetSourcei64SOFT;
|
||||
LPALGETSOURCE3I64SOFT alGetSource3i64SOFT;
|
||||
LPALGETSOURCEI64VSOFT alGetSourcei64vSOFT;
|
||||
|
||||
/* LoadBuffer loads the named audio file into an OpenAL buffer object, and
|
||||
* returns the new buffer ID. */
|
||||
static ALuint LoadSound(const char *filename)
|
||||
{
|
||||
ALenum err, format, type, channels;
|
||||
ALuint rate, buffer;
|
||||
size_t datalen;
|
||||
void *data;
|
||||
FilePtr audiofile;
|
||||
StreamPtr sound;
|
||||
|
||||
/* Open the file and get the first stream from it */
|
||||
audiofile = openAVFile(filename);
|
||||
sound = getAVAudioStream(audiofile, 0);
|
||||
if(!sound)
|
||||
{
|
||||
fprintf(stderr, "Could not open audio in %s\n", filename);
|
||||
closeAVFile(audiofile);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Get the sound format, and figure out the OpenAL format */
|
||||
if(getAVAudioInfo(sound, &rate, &channels, &type) != 0)
|
||||
{
|
||||
fprintf(stderr, "Error getting audio info for %s\n", filename);
|
||||
closeAVFile(audiofile);
|
||||
return 0;
|
||||
}
|
||||
|
||||
format = GetFormat(channels, type, alIsBufferFormatSupportedSOFT);
|
||||
if(format == AL_NONE)
|
||||
{
|
||||
fprintf(stderr, "Unsupported format (%s, %s) for %s\n",
|
||||
ChannelsName(channels), TypeName(type), filename);
|
||||
closeAVFile(audiofile);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Decode the whole audio stream to a buffer. */
|
||||
data = decodeAVAudioStream(sound, &datalen);
|
||||
if(!data)
|
||||
{
|
||||
fprintf(stderr, "Failed to read audio from %s\n", filename);
|
||||
closeAVFile(audiofile);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Buffer the audio data into a new buffer object, then free the data and
|
||||
* close the file. */
|
||||
buffer = 0;
|
||||
alGenBuffers(1, &buffer);
|
||||
alBufferSamplesSOFT(buffer, rate, format, BytesToFrames(datalen, channels, type),
|
||||
channels, type, data);
|
||||
free(data);
|
||||
closeAVFile(audiofile);
|
||||
|
||||
/* Check if an error occured, and clean up if so. */
|
||||
err = alGetError();
|
||||
if(err != AL_NO_ERROR)
|
||||
{
|
||||
fprintf(stderr, "OpenAL Error: %s\n", alGetString(err));
|
||||
if(alIsBuffer(buffer))
|
||||
alDeleteBuffers(1, &buffer);
|
||||
return 0;
|
||||
}
|
||||
|
||||
return buffer;
|
||||
}
|
||||
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
ALuint source, buffer;
|
||||
ALdouble offsets[2];
|
||||
ALenum state;
|
||||
|
||||
/* Print out usage if no file was specified */
|
||||
if(argc < 2)
|
||||
{
|
||||
fprintf(stderr, "Usage: %s <filename>\n", argv[0]);
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Initialize OpenAL with the default device, and check for EFX support. */
|
||||
if(InitAL() != 0)
|
||||
return 1;
|
||||
|
||||
if(!alIsExtensionPresent("AL_SOFT_source_latency"))
|
||||
{
|
||||
fprintf(stderr, "Error: AL_SOFT_source_latency not supported\n");
|
||||
CloseAL();
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Define a macro to help load the function pointers. */
|
||||
#define LOAD_PROC(x) ((x) = alGetProcAddress(#x))
|
||||
LOAD_PROC(alSourcedSOFT);
|
||||
LOAD_PROC(alSource3dSOFT);
|
||||
LOAD_PROC(alSourcedvSOFT);
|
||||
LOAD_PROC(alGetSourcedSOFT);
|
||||
LOAD_PROC(alGetSource3dSOFT);
|
||||
LOAD_PROC(alGetSourcedvSOFT);
|
||||
LOAD_PROC(alSourcei64SOFT);
|
||||
LOAD_PROC(alSource3i64SOFT);
|
||||
LOAD_PROC(alSourcei64vSOFT);
|
||||
LOAD_PROC(alGetSourcei64SOFT);
|
||||
LOAD_PROC(alGetSource3i64SOFT);
|
||||
LOAD_PROC(alGetSourcei64vSOFT);
|
||||
|
||||
if(alIsExtensionPresent("AL_SOFT_buffer_samples"))
|
||||
{
|
||||
LOAD_PROC(alBufferSamplesSOFT);
|
||||
LOAD_PROC(alIsBufferFormatSupportedSOFT);
|
||||
}
|
||||
#undef LOAD_PROC
|
||||
|
||||
/* Load the sound into a buffer. */
|
||||
buffer = LoadSound(argv[1]);
|
||||
if(!buffer)
|
||||
{
|
||||
CloseAL();
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Create the source to play the sound with. */
|
||||
source = 0;
|
||||
alGenSources(1, &source);
|
||||
alSourcei(source, AL_BUFFER, buffer);
|
||||
assert(alGetError()==AL_NO_ERROR && "Failed to setup sound source");
|
||||
|
||||
/* Play the sound until it finishes. */
|
||||
alSourcePlay(source);
|
||||
do {
|
||||
Sleep(10);
|
||||
alGetSourcei(source, AL_SOURCE_STATE, &state);
|
||||
|
||||
/* Get the source offset and latency. AL_SEC_OFFSET_LATENCY_SOFT will
|
||||
* place the offset (in seconds) in offsets[0], and the time until that
|
||||
* offset will be heard (in seconds) in offsets[1]. */
|
||||
alGetSourcedvSOFT(source, AL_SEC_OFFSET_LATENCY_SOFT, offsets);
|
||||
printf("\rOffset: %f - Latency:%3u ms ", offsets[0], (ALuint)(offsets[1]*1000));
|
||||
fflush(stdout);
|
||||
} while(alGetError() == AL_NO_ERROR && state == AL_PLAYING);
|
||||
printf("\n");
|
||||
|
||||
/* All done. Delete resources, and close OpenAL. */
|
||||
alDeleteSources(1, &source);
|
||||
alDeleteBuffers(1, &buffer);
|
||||
|
||||
CloseAL();
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,337 @@
|
||||
/*
|
||||
* OpenAL Reverb Example
|
||||
*
|
||||
* Copyright (c) 2012 by Chris Robinson <chris.kcat@gmail.com>
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
/* This file contains an example for applying reverb to a sound. */
|
||||
|
||||
#include <stdio.h>
|
||||
#include <assert.h>
|
||||
#ifdef _WIN32
|
||||
#define WIN32_LEAN_AND_MEAN
|
||||
#include <windows.h>
|
||||
#else
|
||||
#include <unistd.h>
|
||||
#define Sleep(x) usleep((x)*1000)
|
||||
#endif
|
||||
|
||||
#include "AL/al.h"
|
||||
#include "AL/alc.h"
|
||||
#include "AL/alext.h"
|
||||
#include "AL/efx-presets.h"
|
||||
|
||||
#include "common/alhelpers.h"
|
||||
#include "common/alffmpeg.h"
|
||||
|
||||
|
||||
LPALBUFFERSAMPLESSOFT alBufferSamplesSOFT = wrap_BufferSamples;
|
||||
LPALISBUFFERFORMATSUPPORTEDSOFT alIsBufferFormatSupportedSOFT;
|
||||
|
||||
/* Effect object functions */
|
||||
LPALGENEFFECTS alGenEffects;
|
||||
LPALDELETEEFFECTS alDeleteEffects;
|
||||
LPALISEFFECT alIsEffect;
|
||||
LPALEFFECTI alEffecti;
|
||||
LPALEFFECTIV alEffectiv;
|
||||
LPALEFFECTF alEffectf;
|
||||
LPALEFFECTFV alEffectfv;
|
||||
LPALGETEFFECTI alGetEffecti;
|
||||
LPALGETEFFECTIV alGetEffectiv;
|
||||
LPALGETEFFECTF alGetEffectf;
|
||||
LPALGETEFFECTFV alGetEffectfv;
|
||||
|
||||
/* Auxiliary Effect Slot object functions */
|
||||
LPALGENAUXILIARYEFFECTSLOTS alGenAuxiliaryEffectSlots;
|
||||
LPALDELETEAUXILIARYEFFECTSLOTS alDeleteAuxiliaryEffectSlots;
|
||||
LPALISAUXILIARYEFFECTSLOT alIsAuxiliaryEffectSlot;
|
||||
LPALAUXILIARYEFFECTSLOTI alAuxiliaryEffectSloti;
|
||||
LPALAUXILIARYEFFECTSLOTIV alAuxiliaryEffectSlotiv;
|
||||
LPALAUXILIARYEFFECTSLOTF alAuxiliaryEffectSlotf;
|
||||
LPALAUXILIARYEFFECTSLOTFV alAuxiliaryEffectSlotfv;
|
||||
LPALGETAUXILIARYEFFECTSLOTI alGetAuxiliaryEffectSloti;
|
||||
LPALGETAUXILIARYEFFECTSLOTIV alGetAuxiliaryEffectSlotiv;
|
||||
LPALGETAUXILIARYEFFECTSLOTF alGetAuxiliaryEffectSlotf;
|
||||
LPALGETAUXILIARYEFFECTSLOTFV alGetAuxiliaryEffectSlotfv;
|
||||
|
||||
|
||||
/* LoadEffect loads the given reverb properties into a new OpenAL effect
|
||||
* object, and returns the new effect ID. */
|
||||
static ALuint LoadEffect(const EFXEAXREVERBPROPERTIES *reverb)
|
||||
{
|
||||
ALuint effect = 0;
|
||||
ALenum err;
|
||||
|
||||
/* Create the effect object and check if we can do EAX reverb. */
|
||||
alGenEffects(1, &effect);
|
||||
if(alGetEnumValue("AL_EFFECT_EAXREVERB") != 0)
|
||||
{
|
||||
printf("Using EAX Reverb\n");
|
||||
|
||||
/* EAX Reverb is available. Set the EAX effect type then load the
|
||||
* reverb properties. */
|
||||
alEffecti(effect, AL_EFFECT_TYPE, AL_EFFECT_EAXREVERB);
|
||||
|
||||
alEffectf(effect, AL_EAXREVERB_DENSITY, reverb->flDensity);
|
||||
alEffectf(effect, AL_EAXREVERB_DIFFUSION, reverb->flDiffusion);
|
||||
alEffectf(effect, AL_EAXREVERB_GAIN, reverb->flGain);
|
||||
alEffectf(effect, AL_EAXREVERB_GAINHF, reverb->flGainHF);
|
||||
alEffectf(effect, AL_EAXREVERB_GAINLF, reverb->flGainLF);
|
||||
alEffectf(effect, AL_EAXREVERB_DECAY_TIME, reverb->flDecayTime);
|
||||
alEffectf(effect, AL_EAXREVERB_DECAY_HFRATIO, reverb->flDecayHFRatio);
|
||||
alEffectf(effect, AL_EAXREVERB_DECAY_LFRATIO, reverb->flDecayLFRatio);
|
||||
alEffectf(effect, AL_EAXREVERB_REFLECTIONS_GAIN, reverb->flReflectionsGain);
|
||||
alEffectf(effect, AL_EAXREVERB_REFLECTIONS_DELAY, reverb->flReflectionsDelay);
|
||||
alEffectfv(effect, AL_EAXREVERB_REFLECTIONS_PAN, reverb->flReflectionsPan);
|
||||
alEffectf(effect, AL_EAXREVERB_LATE_REVERB_GAIN, reverb->flLateReverbGain);
|
||||
alEffectf(effect, AL_EAXREVERB_LATE_REVERB_DELAY, reverb->flLateReverbDelay);
|
||||
alEffectfv(effect, AL_EAXREVERB_LATE_REVERB_PAN, reverb->flLateReverbPan);
|
||||
alEffectf(effect, AL_EAXREVERB_ECHO_TIME, reverb->flEchoTime);
|
||||
alEffectf(effect, AL_EAXREVERB_ECHO_DEPTH, reverb->flEchoDepth);
|
||||
alEffectf(effect, AL_EAXREVERB_MODULATION_TIME, reverb->flModulationTime);
|
||||
alEffectf(effect, AL_EAXREVERB_MODULATION_DEPTH, reverb->flModulationDepth);
|
||||
alEffectf(effect, AL_EAXREVERB_AIR_ABSORPTION_GAINHF, reverb->flAirAbsorptionGainHF);
|
||||
alEffectf(effect, AL_EAXREVERB_HFREFERENCE, reverb->flHFReference);
|
||||
alEffectf(effect, AL_EAXREVERB_LFREFERENCE, reverb->flLFReference);
|
||||
alEffectf(effect, AL_EAXREVERB_ROOM_ROLLOFF_FACTOR, reverb->flRoomRolloffFactor);
|
||||
alEffecti(effect, AL_EAXREVERB_DECAY_HFLIMIT, reverb->iDecayHFLimit);
|
||||
}
|
||||
else
|
||||
{
|
||||
printf("Using Standard Reverb\n");
|
||||
|
||||
/* No EAX Reverb. Set the standard reverb effect type then load the
|
||||
* available reverb properties. */
|
||||
alEffecti(effect, AL_EFFECT_TYPE, AL_EFFECT_REVERB);
|
||||
|
||||
alEffectf(effect, AL_REVERB_DENSITY, reverb->flDensity);
|
||||
alEffectf(effect, AL_REVERB_DIFFUSION, reverb->flDiffusion);
|
||||
alEffectf(effect, AL_REVERB_GAIN, reverb->flGain);
|
||||
alEffectf(effect, AL_REVERB_GAINHF, reverb->flGainHF);
|
||||
alEffectf(effect, AL_REVERB_DECAY_TIME, reverb->flDecayTime);
|
||||
alEffectf(effect, AL_REVERB_DECAY_HFRATIO, reverb->flDecayHFRatio);
|
||||
alEffectf(effect, AL_REVERB_REFLECTIONS_GAIN, reverb->flReflectionsGain);
|
||||
alEffectf(effect, AL_REVERB_REFLECTIONS_DELAY, reverb->flReflectionsDelay);
|
||||
alEffectf(effect, AL_REVERB_LATE_REVERB_GAIN, reverb->flLateReverbGain);
|
||||
alEffectf(effect, AL_REVERB_LATE_REVERB_DELAY, reverb->flLateReverbDelay);
|
||||
alEffectf(effect, AL_REVERB_AIR_ABSORPTION_GAINHF, reverb->flAirAbsorptionGainHF);
|
||||
alEffectf(effect, AL_REVERB_ROOM_ROLLOFF_FACTOR, reverb->flRoomRolloffFactor);
|
||||
alEffecti(effect, AL_REVERB_DECAY_HFLIMIT, reverb->iDecayHFLimit);
|
||||
}
|
||||
|
||||
/* Check if an error occured, and clean up if so. */
|
||||
err = alGetError();
|
||||
if(err != AL_NO_ERROR)
|
||||
{
|
||||
fprintf(stderr, "OpenAL error: %s\n", alGetString(err));
|
||||
if(alIsEffect(effect))
|
||||
alDeleteEffects(1, &effect);
|
||||
return 0;
|
||||
}
|
||||
|
||||
return effect;
|
||||
}
|
||||
|
||||
|
||||
/* LoadBuffer loads the named audio file into an OpenAL buffer object, and
|
||||
* returns the new buffer ID. */
|
||||
static ALuint LoadSound(const char *filename)
|
||||
{
|
||||
ALenum err, format, type, channels;
|
||||
ALuint rate, buffer;
|
||||
size_t datalen;
|
||||
void *data;
|
||||
FilePtr audiofile;
|
||||
StreamPtr sound;
|
||||
|
||||
/* Open the file and get the first stream from it */
|
||||
audiofile = openAVFile(filename);
|
||||
sound = getAVAudioStream(audiofile, 0);
|
||||
if(!sound)
|
||||
{
|
||||
fprintf(stderr, "Could not open audio in %s\n", filename);
|
||||
closeAVFile(audiofile);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Get the sound format, and figure out the OpenAL format */
|
||||
if(getAVAudioInfo(sound, &rate, &channels, &type) != 0)
|
||||
{
|
||||
fprintf(stderr, "Error getting audio info for %s\n", filename);
|
||||
closeAVFile(audiofile);
|
||||
return 0;
|
||||
}
|
||||
|
||||
format = GetFormat(channels, type, alIsBufferFormatSupportedSOFT);
|
||||
if(format == AL_NONE)
|
||||
{
|
||||
fprintf(stderr, "Unsupported format (%s, %s) for %s\n",
|
||||
ChannelsName(channels), TypeName(type), filename);
|
||||
closeAVFile(audiofile);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Decode the whole audio stream to a buffer. */
|
||||
data = decodeAVAudioStream(sound, &datalen);
|
||||
if(!data)
|
||||
{
|
||||
fprintf(stderr, "Failed to read audio from %s\n", filename);
|
||||
closeAVFile(audiofile);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Buffer the audio data into a new buffer object, then free the data and
|
||||
* close the file. */
|
||||
buffer = 0;
|
||||
alGenBuffers(1, &buffer);
|
||||
alBufferSamplesSOFT(buffer, rate, format, BytesToFrames(datalen, channels, type),
|
||||
channels, type, data);
|
||||
free(data);
|
||||
closeAVFile(audiofile);
|
||||
|
||||
/* Check if an error occured, and clean up if so. */
|
||||
err = alGetError();
|
||||
if(err != AL_NO_ERROR)
|
||||
{
|
||||
fprintf(stderr, "OpenAL Error: %s\n", alGetString(err));
|
||||
if(alIsBuffer(buffer))
|
||||
alDeleteBuffers(1, &buffer);
|
||||
return 0;
|
||||
}
|
||||
|
||||
return buffer;
|
||||
}
|
||||
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
EFXEAXREVERBPROPERTIES reverb = EFX_REVERB_PRESET_GENERIC;
|
||||
ALuint source, buffer, effect, slot;
|
||||
ALenum state;
|
||||
|
||||
/* Print out usage if no file was specified */
|
||||
if(argc < 2)
|
||||
{
|
||||
fprintf(stderr, "Usage: %s <filename>\n", argv[0]);
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Initialize OpenAL with the default device, and check for EFX support. */
|
||||
if(InitAL() != 0)
|
||||
return 1;
|
||||
|
||||
if(!alcIsExtensionPresent(alcGetContextsDevice(alcGetCurrentContext()), "ALC_EXT_EFX"))
|
||||
{
|
||||
fprintf(stderr, "Error: EFX not supported\n");
|
||||
CloseAL();
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Define a macro to help load the function pointers. */
|
||||
#define LOAD_PROC(x) ((x) = alGetProcAddress(#x))
|
||||
LOAD_PROC(alGenEffects);
|
||||
LOAD_PROC(alDeleteEffects);
|
||||
LOAD_PROC(alIsEffect);
|
||||
LOAD_PROC(alEffecti);
|
||||
LOAD_PROC(alEffectiv);
|
||||
LOAD_PROC(alEffectf);
|
||||
LOAD_PROC(alEffectfv);
|
||||
LOAD_PROC(alGetEffecti);
|
||||
LOAD_PROC(alGetEffectiv);
|
||||
LOAD_PROC(alGetEffectf);
|
||||
LOAD_PROC(alGetEffectfv);
|
||||
|
||||
LOAD_PROC(alGenAuxiliaryEffectSlots);
|
||||
LOAD_PROC(alDeleteAuxiliaryEffectSlots);
|
||||
LOAD_PROC(alIsAuxiliaryEffectSlot);
|
||||
LOAD_PROC(alAuxiliaryEffectSloti);
|
||||
LOAD_PROC(alAuxiliaryEffectSlotiv);
|
||||
LOAD_PROC(alAuxiliaryEffectSlotf);
|
||||
LOAD_PROC(alAuxiliaryEffectSlotfv);
|
||||
LOAD_PROC(alGetAuxiliaryEffectSloti);
|
||||
LOAD_PROC(alGetAuxiliaryEffectSlotiv);
|
||||
LOAD_PROC(alGetAuxiliaryEffectSlotf);
|
||||
LOAD_PROC(alGetAuxiliaryEffectSlotfv);
|
||||
|
||||
if(alIsExtensionPresent("AL_SOFT_buffer_samples"))
|
||||
{
|
||||
LOAD_PROC(alBufferSamplesSOFT);
|
||||
LOAD_PROC(alIsBufferFormatSupportedSOFT);
|
||||
}
|
||||
#undef LOAD_PROC
|
||||
|
||||
/* Load the sound into a buffer. */
|
||||
buffer = LoadSound(argv[1]);
|
||||
if(!buffer)
|
||||
{
|
||||
CloseAL();
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Load the reverb into an effect. */
|
||||
effect = LoadEffect(&reverb);
|
||||
if(!effect)
|
||||
{
|
||||
alDeleteBuffers(1, &buffer);
|
||||
CloseAL();
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Create the effect slot object. This is what "plays" an effect on sources
|
||||
* that connect to it. */
|
||||
slot = 0;
|
||||
alGenAuxiliaryEffectSlots(1, &slot);
|
||||
|
||||
/* Tell the effect slot to use the loaded effect object. Note that the this
|
||||
* effectively copies the effect properties. You can modify or delete the
|
||||
* effect object afterward without affecting the effect slot.
|
||||
*/
|
||||
alAuxiliaryEffectSloti(slot, AL_EFFECTSLOT_EFFECT, effect);
|
||||
assert(alGetError()==AL_NO_ERROR && "Failed to set effect slot");
|
||||
|
||||
/* Create the source to play the sound with. */
|
||||
source = 0;
|
||||
alGenSources(1, &source);
|
||||
alSourcei(source, AL_BUFFER, buffer);
|
||||
|
||||
/* Connect the source to the effect slot. This tells the source to use the
|
||||
* effect slot 'slot', on send #0 with the AL_FILTER_NULL filter object.
|
||||
*/
|
||||
alSource3i(source, AL_AUXILIARY_SEND_FILTER, slot, 0, AL_FILTER_NULL);
|
||||
assert(alGetError()==AL_NO_ERROR && "Failed to setup sound source");
|
||||
|
||||
/* Play the sound until it finishes. */
|
||||
alSourcePlay(source);
|
||||
do {
|
||||
Sleep(10);
|
||||
alGetSourcei(source, AL_SOURCE_STATE, &state);
|
||||
} while(alGetError() == AL_NO_ERROR && state == AL_PLAYING);
|
||||
|
||||
/* All done. Delete resources, and close OpenAL. */
|
||||
alDeleteSources(1, &source);
|
||||
alDeleteAuxiliaryEffectSlots(1, &slot);
|
||||
alDeleteEffects(1, &effect);
|
||||
alDeleteBuffers(1, &buffer);
|
||||
|
||||
CloseAL();
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,347 @@
|
||||
/*
|
||||
* OpenAL Audio Stream Example
|
||||
*
|
||||
* Copyright (c) 2011 by Chris Robinson <chris.kcat@gmail.com>
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
/* This file contains a relatively simple streaming audio player. */
|
||||
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <signal.h>
|
||||
#include <assert.h>
|
||||
|
||||
#include "AL/al.h"
|
||||
#include "AL/alc.h"
|
||||
#include "AL/alext.h"
|
||||
|
||||
#include "common/alhelpers.h"
|
||||
#include "common/alffmpeg.h"
|
||||
|
||||
|
||||
LPALBUFFERSAMPLESSOFT alBufferSamplesSOFT = wrap_BufferSamples;
|
||||
LPALISBUFFERFORMATSUPPORTEDSOFT alIsBufferFormatSupportedSOFT = NULL;
|
||||
|
||||
|
||||
/* Define the number of buffers and buffer size (in samples) to use. 4 buffers
|
||||
* with 8192 samples each gives a nice per-chunk size, and lets the queue last
|
||||
* for almost 3/4ths of a second for a 44.1khz stream. */
|
||||
#define NUM_BUFFERS 4
|
||||
#define BUFFER_SIZE 8192
|
||||
|
||||
typedef struct StreamPlayer {
|
||||
/* These are the buffers and source to play out through OpenAL with */
|
||||
ALuint buffers[NUM_BUFFERS];
|
||||
ALuint source;
|
||||
|
||||
/* Handles for the audio stream */
|
||||
FilePtr file;
|
||||
StreamPtr stream;
|
||||
|
||||
/* A temporary data buffer for readAVAudioData to write to and pass to
|
||||
* OpenAL with */
|
||||
ALbyte *data;
|
||||
ALsizei datasize;
|
||||
|
||||
/* The format of the output stream */
|
||||
ALenum format;
|
||||
ALenum channels;
|
||||
ALenum type;
|
||||
ALuint rate;
|
||||
} StreamPlayer;
|
||||
|
||||
static StreamPlayer *NewPlayer(void);
|
||||
static void DeletePlayer(StreamPlayer *player);
|
||||
static int OpenPlayerFile(StreamPlayer *player, const char *filename);
|
||||
static void ClosePlayerFile(StreamPlayer *player);
|
||||
static int StartPlayer(StreamPlayer *player);
|
||||
static int UpdatePlayer(StreamPlayer *player);
|
||||
|
||||
/* Creates a new player object, and allocates the needed OpenAL source and
|
||||
* buffer objects. Error checking is simplified for the purposes of this
|
||||
* example, and will cause an abort if needed. */
|
||||
static StreamPlayer *NewPlayer(void)
|
||||
{
|
||||
StreamPlayer *player;
|
||||
|
||||
player = malloc(sizeof(*player));
|
||||
assert(player != NULL);
|
||||
|
||||
memset(player, 0, sizeof(*player));
|
||||
|
||||
/* Generate the buffers and source */
|
||||
alGenBuffers(NUM_BUFFERS, player->buffers);
|
||||
assert(alGetError() == AL_NO_ERROR && "Could not create buffers");
|
||||
|
||||
alGenSources(1, &player->source);
|
||||
assert(alGetError() == AL_NO_ERROR && "Could not create source");
|
||||
|
||||
/* Set parameters so mono sources play out the front-center speaker and
|
||||
* won't distance attenuate. */
|
||||
alSource3i(player->source, AL_POSITION, 0, 0, -1);
|
||||
alSourcei(player->source, AL_SOURCE_RELATIVE, AL_TRUE);
|
||||
alSourcei(player->source, AL_ROLLOFF_FACTOR, 0);
|
||||
assert(alGetError() == AL_NO_ERROR && "Could not set source parameters");
|
||||
|
||||
return player;
|
||||
}
|
||||
|
||||
/* Destroys a player object, deleting the source and buffers. No error handling
|
||||
* since these calls shouldn't fail with a properly-made player object. */
|
||||
static void DeletePlayer(StreamPlayer *player)
|
||||
{
|
||||
ClosePlayerFile(player);
|
||||
|
||||
alDeleteSources(1, &player->source);
|
||||
alDeleteBuffers(NUM_BUFFERS, player->buffers);
|
||||
if(alGetError() != AL_NO_ERROR)
|
||||
fprintf(stderr, "Failed to delete object IDs\n");
|
||||
|
||||
memset(player, 0, sizeof(*player));
|
||||
free(player);
|
||||
}
|
||||
|
||||
|
||||
/* Opens the first audio stream of the named file. If a file is already open,
|
||||
* it will be closed first. */
|
||||
static int OpenPlayerFile(StreamPlayer *player, const char *filename)
|
||||
{
|
||||
ClosePlayerFile(player);
|
||||
|
||||
/* Open the file and get the first stream from it */
|
||||
player->file = openAVFile(filename);
|
||||
player->stream = getAVAudioStream(player->file, 0);
|
||||
if(!player->stream)
|
||||
{
|
||||
fprintf(stderr, "Could not open audio in %s\n", filename);
|
||||
goto error;
|
||||
}
|
||||
|
||||
/* Get the stream format, and figure out the OpenAL format */
|
||||
if(getAVAudioInfo(player->stream, &player->rate, &player->channels,
|
||||
&player->type) != 0)
|
||||
{
|
||||
fprintf(stderr, "Error getting audio info for %s\n", filename);
|
||||
goto error;
|
||||
}
|
||||
|
||||
player->format = GetFormat(player->channels, player->type, alIsBufferFormatSupportedSOFT);
|
||||
if(player->format == 0)
|
||||
{
|
||||
fprintf(stderr, "Unsupported format (%s, %s) for %s\n",
|
||||
ChannelsName(player->channels), TypeName(player->type),
|
||||
filename);
|
||||
goto error;
|
||||
}
|
||||
|
||||
/* Allocate enough space for the temp buffer, given the format */
|
||||
player->datasize = FramesToBytes(BUFFER_SIZE, player->channels,
|
||||
player->type);
|
||||
player->data = malloc(player->datasize);
|
||||
if(player->data == NULL)
|
||||
{
|
||||
fprintf(stderr, "Error allocating %d bytes\n", player->datasize);
|
||||
goto error;
|
||||
}
|
||||
|
||||
return 1;
|
||||
|
||||
error:
|
||||
closeAVFile(player->file);
|
||||
player->file = NULL;
|
||||
player->stream = NULL;
|
||||
player->datasize = 0;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Closes the audio file stream */
|
||||
static void ClosePlayerFile(StreamPlayer *player)
|
||||
{
|
||||
closeAVFile(player->file);
|
||||
player->file = NULL;
|
||||
player->stream = NULL;
|
||||
|
||||
free(player->data);
|
||||
player->data = NULL;
|
||||
player->datasize = 0;
|
||||
}
|
||||
|
||||
|
||||
/* Prebuffers some audio from the file, and starts playing the source */
|
||||
static int StartPlayer(StreamPlayer *player)
|
||||
{
|
||||
size_t i, got;
|
||||
|
||||
/* Rewind the source position and clear the buffer queue */
|
||||
alSourceRewind(player->source);
|
||||
alSourcei(player->source, AL_BUFFER, 0);
|
||||
|
||||
/* Fill the buffer queue */
|
||||
for(i = 0;i < NUM_BUFFERS;i++)
|
||||
{
|
||||
/* Get some data to give it to the buffer */
|
||||
got = readAVAudioData(player->stream, player->data, player->datasize);
|
||||
if(got == 0) break;
|
||||
|
||||
alBufferSamplesSOFT(player->buffers[i], player->rate, player->format,
|
||||
BytesToFrames(got, player->channels, player->type),
|
||||
player->channels, player->type, player->data);
|
||||
}
|
||||
if(alGetError() != AL_NO_ERROR)
|
||||
{
|
||||
fprintf(stderr, "Error buffering for playback\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Now queue and start playback! */
|
||||
alSourceQueueBuffers(player->source, i, player->buffers);
|
||||
alSourcePlay(player->source);
|
||||
if(alGetError() != AL_NO_ERROR)
|
||||
{
|
||||
fprintf(stderr, "Error starting playback\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int UpdatePlayer(StreamPlayer *player)
|
||||
{
|
||||
ALint processed, state;
|
||||
|
||||
/* Get relevant source info */
|
||||
alGetSourcei(player->source, AL_SOURCE_STATE, &state);
|
||||
alGetSourcei(player->source, AL_BUFFERS_PROCESSED, &processed);
|
||||
if(alGetError() != AL_NO_ERROR)
|
||||
{
|
||||
fprintf(stderr, "Error checking source state\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Unqueue and handle each processed buffer */
|
||||
while(processed > 0)
|
||||
{
|
||||
ALuint bufid;
|
||||
size_t got;
|
||||
|
||||
alSourceUnqueueBuffers(player->source, 1, &bufid);
|
||||
processed--;
|
||||
|
||||
/* Read the next chunk of data, refill the buffer, and queue it
|
||||
* back on the source */
|
||||
got = readAVAudioData(player->stream, player->data, player->datasize);
|
||||
if(got > 0)
|
||||
{
|
||||
alBufferSamplesSOFT(bufid, player->rate, player->format,
|
||||
BytesToFrames(got, player->channels, player->type),
|
||||
player->channels, player->type, player->data);
|
||||
alSourceQueueBuffers(player->source, 1, &bufid);
|
||||
}
|
||||
if(alGetError() != AL_NO_ERROR)
|
||||
{
|
||||
fprintf(stderr, "Error buffering data\n");
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
/* Make sure the source hasn't underrun */
|
||||
if(state != AL_PLAYING && state != AL_PAUSED)
|
||||
{
|
||||
ALint queued;
|
||||
|
||||
/* If no buffers are queued, playback is finished */
|
||||
alGetSourcei(player->source, AL_BUFFERS_QUEUED, &queued);
|
||||
if(queued == 0)
|
||||
return 0;
|
||||
|
||||
alSourcePlay(player->source);
|
||||
if(alGetError() != AL_NO_ERROR)
|
||||
{
|
||||
fprintf(stderr, "Error restarting playback\n");
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
StreamPlayer *player;
|
||||
int i;
|
||||
|
||||
/* Print out usage if no file was specified */
|
||||
if(argc < 2)
|
||||
{
|
||||
fprintf(stderr, "Usage: %s <filenames...>\n", argv[0]);
|
||||
return 1;
|
||||
}
|
||||
|
||||
if(InitAL() != 0)
|
||||
return 1;
|
||||
|
||||
if(alIsExtensionPresent("AL_SOFT_buffer_samples"))
|
||||
{
|
||||
printf("AL_SOFT_buffer_samples supported!\n");
|
||||
alBufferSamplesSOFT = alGetProcAddress("alBufferSamplesSOFT");
|
||||
alIsBufferFormatSupportedSOFT = alGetProcAddress("alIsBufferFormatSupportedSOFT");
|
||||
}
|
||||
else
|
||||
printf("AL_SOFT_buffer_samples not supported\n");
|
||||
|
||||
player = NewPlayer();
|
||||
|
||||
/* Play each file listed on the command line */
|
||||
for(i = 1;i < argc;i++)
|
||||
{
|
||||
if(!OpenPlayerFile(player, argv[i]))
|
||||
continue;
|
||||
|
||||
printf("Playing %s (%s, %s, %dhz)\n", argv[i],
|
||||
TypeName(player->type), ChannelsName(player->channels),
|
||||
player->rate);
|
||||
fflush(stdout);
|
||||
|
||||
if(!StartPlayer(player))
|
||||
{
|
||||
ClosePlayerFile(player);
|
||||
continue;
|
||||
}
|
||||
|
||||
while(UpdatePlayer(player))
|
||||
Sleep(10);
|
||||
|
||||
/* All done with this file. Close it and go to the next */
|
||||
ClosePlayerFile(player);
|
||||
}
|
||||
printf("Done.\n");
|
||||
|
||||
/* All files done. Delete the player, and close OpenAL */
|
||||
DeletePlayer(player);
|
||||
player = NULL;
|
||||
|
||||
CloseAL();
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,638 @@
|
||||
/*
|
||||
* FFmpeg Decoder Helpers
|
||||
*
|
||||
* Copyright (c) 2011 by Chris Robinson <chris.kcat@gmail.com>
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
/* This file contains routines for helping to decode audio using libavformat
|
||||
* and libavcodec (ffmpeg). There's very little OpenAL-specific code here. */
|
||||
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <signal.h>
|
||||
#include <assert.h>
|
||||
|
||||
#include "AL/al.h"
|
||||
#include "AL/alc.h"
|
||||
#include "AL/alext.h"
|
||||
|
||||
#include "alhelpers.h"
|
||||
#include "alffmpeg.h"
|
||||
|
||||
|
||||
static size_t NextPowerOf2(size_t value)
|
||||
{
|
||||
size_t powerOf2 = 1;
|
||||
|
||||
if(value)
|
||||
{
|
||||
value--;
|
||||
while(value)
|
||||
{
|
||||
value >>= 1;
|
||||
powerOf2 <<= 1;
|
||||
}
|
||||
}
|
||||
return powerOf2;
|
||||
}
|
||||
|
||||
|
||||
struct MemData {
|
||||
char *buffer;
|
||||
size_t length;
|
||||
size_t pos;
|
||||
};
|
||||
|
||||
static int MemData_read(void *opaque, uint8_t *buf, int buf_size)
|
||||
{
|
||||
struct MemData *membuf = (struct MemData*)opaque;
|
||||
int rem = membuf->length - membuf->pos;
|
||||
|
||||
if(rem > buf_size)
|
||||
rem = buf_size;
|
||||
|
||||
memcpy(buf, &membuf->buffer[membuf->pos], rem);
|
||||
membuf->pos += rem;
|
||||
|
||||
return rem;
|
||||
}
|
||||
|
||||
static int MemData_write(void *opaque, uint8_t *buf, int buf_size)
|
||||
{
|
||||
struct MemData *membuf = (struct MemData*)opaque;
|
||||
int rem = membuf->length - membuf->pos;
|
||||
|
||||
if(rem > buf_size)
|
||||
rem = buf_size;
|
||||
|
||||
memcpy(&membuf->buffer[membuf->pos], buf, rem);
|
||||
membuf->pos += rem;
|
||||
|
||||
return rem;
|
||||
}
|
||||
|
||||
static int64_t MemData_seek(void *opaque, int64_t offset, int whence)
|
||||
{
|
||||
struct MemData *membuf = (struct MemData*)opaque;
|
||||
|
||||
whence &= ~AVSEEK_FORCE;
|
||||
switch(whence)
|
||||
{
|
||||
case SEEK_SET:
|
||||
if(offset < 0 || (uint64_t)offset > membuf->length)
|
||||
return -1;
|
||||
membuf->pos = offset;
|
||||
break;
|
||||
|
||||
case SEEK_CUR:
|
||||
if((offset >= 0 && (uint64_t)offset > membuf->length-membuf->pos) ||
|
||||
(offset < 0 && (uint64_t)(-offset) > membuf->pos))
|
||||
return -1;
|
||||
membuf->pos += offset;
|
||||
break;
|
||||
|
||||
case SEEK_END:
|
||||
if(offset > 0 || (uint64_t)(-offset) > membuf->length)
|
||||
return -1;
|
||||
membuf->pos = membuf->length + offset;
|
||||
break;
|
||||
|
||||
case AVSEEK_SIZE:
|
||||
return membuf->length;
|
||||
|
||||
default:
|
||||
return -1;
|
||||
}
|
||||
|
||||
return membuf->pos;
|
||||
}
|
||||
|
||||
|
||||
struct PacketList {
|
||||
AVPacket pkt;
|
||||
struct PacketList *next;
|
||||
};
|
||||
|
||||
struct MyStream {
|
||||
AVCodecContext *CodecCtx;
|
||||
int StreamIdx;
|
||||
|
||||
struct PacketList *Packets;
|
||||
|
||||
AVFrame *Frame;
|
||||
|
||||
const uint8_t *FrameData;
|
||||
size_t FrameDataSize;
|
||||
|
||||
FilePtr parent;
|
||||
};
|
||||
|
||||
struct MyFile {
|
||||
AVFormatContext *FmtCtx;
|
||||
|
||||
StreamPtr *Streams;
|
||||
size_t StreamsSize;
|
||||
|
||||
struct MemData membuf;
|
||||
};
|
||||
|
||||
|
||||
static int done_init = 0;
|
||||
|
||||
FilePtr openAVFile(const char *fname)
|
||||
{
|
||||
FilePtr file;
|
||||
|
||||
/* We need to make sure ffmpeg is initialized. Optionally silence warning
|
||||
* output from the lib */
|
||||
if(!done_init) {av_register_all();
|
||||
av_log_set_level(AV_LOG_ERROR);
|
||||
done_init = 1;}
|
||||
|
||||
file = (FilePtr)calloc(1, sizeof(*file));
|
||||
if(file && avformat_open_input(&file->FmtCtx, fname, NULL, NULL) == 0)
|
||||
{
|
||||
/* After opening, we must search for the stream information because not
|
||||
* all formats will have it in stream headers */
|
||||
if(avformat_find_stream_info(file->FmtCtx, NULL) >= 0)
|
||||
return file;
|
||||
avformat_close_input(&file->FmtCtx);
|
||||
}
|
||||
|
||||
free(file);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
FilePtr openAVData(const char *name, char *buffer, size_t buffer_len)
|
||||
{
|
||||
FilePtr file;
|
||||
|
||||
if(!done_init) {av_register_all();
|
||||
av_log_set_level(AV_LOG_ERROR);
|
||||
done_init = 1;}
|
||||
|
||||
if(!name)
|
||||
name = "";
|
||||
|
||||
file = (FilePtr)calloc(1, sizeof(*file));
|
||||
if(file && (file->FmtCtx=avformat_alloc_context()) != NULL)
|
||||
{
|
||||
file->membuf.buffer = buffer;
|
||||
file->membuf.length = buffer_len;
|
||||
file->membuf.pos = 0;
|
||||
|
||||
file->FmtCtx->pb = avio_alloc_context(NULL, 0, 0, &file->membuf,
|
||||
MemData_read, MemData_write,
|
||||
MemData_seek);
|
||||
if(file->FmtCtx->pb && avformat_open_input(&file->FmtCtx, name, NULL, NULL) == 0)
|
||||
{
|
||||
if(avformat_find_stream_info(file->FmtCtx, NULL) >= 0)
|
||||
return file;
|
||||
avformat_close_input(&file->FmtCtx);
|
||||
}
|
||||
if(file->FmtCtx)
|
||||
avformat_free_context(file->FmtCtx);
|
||||
file->FmtCtx = NULL;
|
||||
}
|
||||
|
||||
free(file);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
FilePtr openAVCustom(const char *name, void *user_data,
|
||||
int (*read_packet)(void *user_data, uint8_t *buf, int buf_size),
|
||||
int (*write_packet)(void *user_data, uint8_t *buf, int buf_size),
|
||||
int64_t (*seek)(void *user_data, int64_t offset, int whence))
|
||||
{
|
||||
FilePtr file;
|
||||
|
||||
if(!done_init) {av_register_all();
|
||||
av_log_set_level(AV_LOG_ERROR);
|
||||
done_init = 1;}
|
||||
|
||||
if(!name)
|
||||
name = "";
|
||||
|
||||
file = (FilePtr)calloc(1, sizeof(*file));
|
||||
if(file && (file->FmtCtx=avformat_alloc_context()) != NULL)
|
||||
{
|
||||
file->FmtCtx->pb = avio_alloc_context(NULL, 0, 0, user_data,
|
||||
read_packet, write_packet, seek);
|
||||
if(file->FmtCtx->pb && avformat_open_input(&file->FmtCtx, name, NULL, NULL) == 0)
|
||||
{
|
||||
if(avformat_find_stream_info(file->FmtCtx, NULL) >= 0)
|
||||
return file;
|
||||
avformat_close_input(&file->FmtCtx);
|
||||
}
|
||||
if(file->FmtCtx)
|
||||
avformat_free_context(file->FmtCtx);
|
||||
file->FmtCtx = NULL;
|
||||
}
|
||||
|
||||
free(file);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
void clearAVAudioData(StreamPtr stream)
|
||||
{
|
||||
while(stream->Packets)
|
||||
{
|
||||
struct PacketList *self;
|
||||
|
||||
self = stream->Packets;
|
||||
stream->Packets = self->next;
|
||||
|
||||
av_free_packet(&self->pkt);
|
||||
av_free(self);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void closeAVFile(FilePtr file)
|
||||
{
|
||||
size_t i;
|
||||
|
||||
if(!file) return;
|
||||
|
||||
for(i = 0;i < file->StreamsSize;i++)
|
||||
{
|
||||
StreamPtr stream = file->Streams[i];
|
||||
|
||||
while(stream->Packets)
|
||||
{
|
||||
struct PacketList *self;
|
||||
|
||||
self = stream->Packets;
|
||||
stream->Packets = self->next;
|
||||
|
||||
av_free_packet(&self->pkt);
|
||||
av_free(self);
|
||||
}
|
||||
|
||||
avcodec_close(stream->CodecCtx);
|
||||
av_free(stream->Frame);
|
||||
free(stream);
|
||||
}
|
||||
free(file->Streams);
|
||||
|
||||
avformat_close_input(&file->FmtCtx);
|
||||
free(file);
|
||||
}
|
||||
|
||||
|
||||
int getAVFileInfo(FilePtr file, int *numaudiostreams)
|
||||
{
|
||||
unsigned int i;
|
||||
int audiocount = 0;
|
||||
|
||||
if(!file) return 1;
|
||||
for(i = 0;i < file->FmtCtx->nb_streams;i++)
|
||||
{
|
||||
if(file->FmtCtx->streams[i]->codec->codec_type == AVMEDIA_TYPE_AUDIO)
|
||||
audiocount++;
|
||||
}
|
||||
*numaudiostreams = audiocount;
|
||||
return 0;
|
||||
}
|
||||
|
||||
StreamPtr getAVAudioStream(FilePtr file, int streamnum)
|
||||
{
|
||||
unsigned int i;
|
||||
if(!file) return NULL;
|
||||
for(i = 0;i < file->FmtCtx->nb_streams;i++)
|
||||
{
|
||||
if(file->FmtCtx->streams[i]->codec->codec_type != AVMEDIA_TYPE_AUDIO)
|
||||
continue;
|
||||
|
||||
if(streamnum == 0)
|
||||
{
|
||||
StreamPtr stream;
|
||||
AVCodec *codec;
|
||||
void *temp;
|
||||
size_t j;
|
||||
|
||||
/* Found the requested stream. Check if a handle to this stream
|
||||
* already exists and return it if it does */
|
||||
for(j = 0;j < file->StreamsSize;j++)
|
||||
{
|
||||
if(file->Streams[j]->StreamIdx == (int)i)
|
||||
return file->Streams[j];
|
||||
}
|
||||
|
||||
/* Doesn't yet exist. Now allocate a new stream object and fill in
|
||||
* its info */
|
||||
stream = (StreamPtr)calloc(1, sizeof(*stream));
|
||||
if(!stream) return NULL;
|
||||
|
||||
stream->parent = file;
|
||||
stream->CodecCtx = file->FmtCtx->streams[i]->codec;
|
||||
stream->StreamIdx = i;
|
||||
|
||||
/* Try to find the codec for the given codec ID, and open it */
|
||||
codec = avcodec_find_decoder(stream->CodecCtx->codec_id);
|
||||
if(!codec || avcodec_open2(stream->CodecCtx, codec, NULL) < 0)
|
||||
{
|
||||
free(stream);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Allocate space for the decoded data to be stored in before it
|
||||
* gets passed to the app */
|
||||
stream->Frame = avcodec_alloc_frame();
|
||||
if(!stream->Frame)
|
||||
{
|
||||
avcodec_close(stream->CodecCtx);
|
||||
free(stream);
|
||||
return NULL;
|
||||
}
|
||||
stream->FrameData = NULL;
|
||||
stream->FrameDataSize = 0;
|
||||
|
||||
/* Append the new stream object to the stream list. The original
|
||||
* pointer will remain valid if realloc fails, so we need to use
|
||||
* another pointer to watch for errors and not leak memory */
|
||||
temp = realloc(file->Streams, (file->StreamsSize+1) *
|
||||
sizeof(*file->Streams));
|
||||
if(!temp)
|
||||
{
|
||||
avcodec_close(stream->CodecCtx);
|
||||
av_free(stream->Frame);
|
||||
free(stream);
|
||||
return NULL;
|
||||
}
|
||||
file->Streams = (StreamPtr*)temp;
|
||||
file->Streams[file->StreamsSize++] = stream;
|
||||
return stream;
|
||||
}
|
||||
streamnum--;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int getAVAudioInfo(StreamPtr stream, ALuint *rate, ALenum *channels, ALenum *type)
|
||||
{
|
||||
if(!stream || stream->CodecCtx->codec_type != AVMEDIA_TYPE_AUDIO)
|
||||
return 1;
|
||||
|
||||
/* Get the sample type for OpenAL given the format detected by ffmpeg. */
|
||||
if(stream->CodecCtx->sample_fmt == AV_SAMPLE_FMT_U8)
|
||||
*type = AL_UNSIGNED_BYTE_SOFT;
|
||||
else if(stream->CodecCtx->sample_fmt == AV_SAMPLE_FMT_S16)
|
||||
*type = AL_SHORT_SOFT;
|
||||
else if(stream->CodecCtx->sample_fmt == AV_SAMPLE_FMT_S32)
|
||||
*type = AL_INT_SOFT;
|
||||
else if(stream->CodecCtx->sample_fmt == AV_SAMPLE_FMT_FLT)
|
||||
*type = AL_FLOAT_SOFT;
|
||||
else if(stream->CodecCtx->sample_fmt == AV_SAMPLE_FMT_DBL)
|
||||
*type = AL_DOUBLE_SOFT;
|
||||
else
|
||||
{
|
||||
fprintf(stderr, "Unsupported ffmpeg sample format: %s\n",
|
||||
av_get_sample_fmt_name(stream->CodecCtx->sample_fmt));
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Get the OpenAL channel configuration using the channel layout detected
|
||||
* by ffmpeg. NOTE: some file types may not specify a channel layout. In
|
||||
* that case, one must be guessed based on the channel count. */
|
||||
if(stream->CodecCtx->channel_layout == AV_CH_LAYOUT_MONO)
|
||||
*channels = AL_MONO_SOFT;
|
||||
else if(stream->CodecCtx->channel_layout == AV_CH_LAYOUT_STEREO)
|
||||
*channels = AL_STEREO_SOFT;
|
||||
else if(stream->CodecCtx->channel_layout == AV_CH_LAYOUT_QUAD)
|
||||
*channels = AL_QUAD_SOFT;
|
||||
else if(stream->CodecCtx->channel_layout == AV_CH_LAYOUT_5POINT1_BACK)
|
||||
*channels = AL_5POINT1_SOFT;
|
||||
else if(stream->CodecCtx->channel_layout == AV_CH_LAYOUT_7POINT1)
|
||||
*channels = AL_7POINT1_SOFT;
|
||||
else if(stream->CodecCtx->channel_layout == 0)
|
||||
{
|
||||
/* Unknown channel layout. Try to guess. */
|
||||
if(stream->CodecCtx->channels == 1)
|
||||
*channels = AL_MONO_SOFT;
|
||||
else if(stream->CodecCtx->channels == 2)
|
||||
*channels = AL_STEREO_SOFT;
|
||||
else
|
||||
{
|
||||
fprintf(stderr, "Unsupported ffmpeg raw channel count: %d\n",
|
||||
stream->CodecCtx->channels);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
char str[1024];
|
||||
av_get_channel_layout_string(str, sizeof(str), stream->CodecCtx->channels,
|
||||
stream->CodecCtx->channel_layout);
|
||||
fprintf(stderr, "Unsupported ffmpeg channel layout: %s\n", str);
|
||||
return 1;
|
||||
}
|
||||
|
||||
*rate = stream->CodecCtx->sample_rate;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/* Used by getAV*Data to search for more compressed data, and buffer it in the
|
||||
* correct stream. It won't buffer data for streams that the app doesn't have a
|
||||
* handle for. */
|
||||
static int getNextPacket(FilePtr file, int streamidx)
|
||||
{
|
||||
struct PacketList *packet;
|
||||
|
||||
packet = (struct PacketList*)av_malloc(sizeof(*packet));
|
||||
packet->next = NULL;
|
||||
|
||||
next_packet:
|
||||
while(av_read_frame(file->FmtCtx, &packet->pkt) >= 0)
|
||||
{
|
||||
StreamPtr *iter = file->Streams;
|
||||
StreamPtr *iter_end = iter + file->StreamsSize;
|
||||
|
||||
/* Check each stream the user has a handle for, looking for the one
|
||||
* this packet belongs to */
|
||||
while(iter != iter_end)
|
||||
{
|
||||
if((*iter)->StreamIdx == packet->pkt.stream_index)
|
||||
{
|
||||
struct PacketList **last;
|
||||
|
||||
last = &(*iter)->Packets;
|
||||
while(*last != NULL)
|
||||
last = &(*last)->next;
|
||||
|
||||
*last = packet;
|
||||
if((*iter)->StreamIdx == streamidx)
|
||||
return 1;
|
||||
|
||||
packet = (struct PacketList*)av_malloc(sizeof(*packet));
|
||||
packet->next = NULL;
|
||||
goto next_packet;
|
||||
}
|
||||
iter++;
|
||||
}
|
||||
/* Free the packet and look for another */
|
||||
av_free_packet(&packet->pkt);
|
||||
}
|
||||
|
||||
av_free(packet);
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint8_t *getAVAudioData(StreamPtr stream, size_t *length)
|
||||
{
|
||||
int got_frame;
|
||||
int len;
|
||||
|
||||
if(length) *length = 0;
|
||||
|
||||
if(!stream || stream->CodecCtx->codec_type != AVMEDIA_TYPE_AUDIO)
|
||||
return NULL;
|
||||
|
||||
next_packet:
|
||||
if(!stream->Packets && !getNextPacket(stream->parent, stream->StreamIdx))
|
||||
return NULL;
|
||||
|
||||
/* Decode some data, and check for errors */
|
||||
avcodec_get_frame_defaults(stream->Frame);
|
||||
while((len=avcodec_decode_audio4(stream->CodecCtx, stream->Frame,
|
||||
&got_frame, &stream->Packets->pkt)) < 0)
|
||||
{
|
||||
struct PacketList *self;
|
||||
|
||||
/* Error? Drop it and try the next, I guess... */
|
||||
self = stream->Packets;
|
||||
stream->Packets = self->next;
|
||||
|
||||
av_free_packet(&self->pkt);
|
||||
av_free(self);
|
||||
|
||||
if(!stream->Packets)
|
||||
goto next_packet;
|
||||
}
|
||||
|
||||
if(len < stream->Packets->pkt.size)
|
||||
{
|
||||
/* Move the unread data to the front and clear the end bits */
|
||||
int remaining = stream->Packets->pkt.size - len;
|
||||
memmove(stream->Packets->pkt.data, &stream->Packets->pkt.data[len],
|
||||
remaining);
|
||||
memset(&stream->Packets->pkt.data[remaining], 0,
|
||||
stream->Packets->pkt.size - remaining);
|
||||
stream->Packets->pkt.size -= len;
|
||||
}
|
||||
else
|
||||
{
|
||||
struct PacketList *self;
|
||||
|
||||
self = stream->Packets;
|
||||
stream->Packets = self->next;
|
||||
|
||||
av_free_packet(&self->pkt);
|
||||
av_free(self);
|
||||
}
|
||||
|
||||
if(!got_frame || stream->Frame->nb_samples == 0)
|
||||
goto next_packet;
|
||||
|
||||
/* Set the output buffer size */
|
||||
*length = av_samples_get_buffer_size(NULL, stream->CodecCtx->channels,
|
||||
stream->Frame->nb_samples,
|
||||
stream->CodecCtx->sample_fmt, 1);
|
||||
|
||||
return stream->Frame->data[0];
|
||||
}
|
||||
|
||||
size_t readAVAudioData(StreamPtr stream, void *data, size_t length)
|
||||
{
|
||||
size_t dec = 0;
|
||||
|
||||
if(!stream || stream->CodecCtx->codec_type != AVMEDIA_TYPE_AUDIO)
|
||||
return 0;
|
||||
|
||||
while(dec < length)
|
||||
{
|
||||
/* If there's no decoded data, find some */
|
||||
if(stream->FrameDataSize == 0)
|
||||
{
|
||||
stream->FrameData = getAVAudioData(stream, &stream->FrameDataSize);
|
||||
if(!stream->FrameData)
|
||||
break;
|
||||
}
|
||||
|
||||
if(stream->FrameDataSize > 0)
|
||||
{
|
||||
/* Get the amount of bytes remaining to be written, and clamp to
|
||||
* the amount of decoded data we have */
|
||||
size_t rem = length-dec;
|
||||
if(rem > stream->FrameDataSize)
|
||||
rem = stream->FrameDataSize;
|
||||
|
||||
/* Copy the data to the app's buffer and increment */
|
||||
if(data != NULL)
|
||||
{
|
||||
memcpy(data, stream->FrameData, rem);
|
||||
data = (char*)data + rem;
|
||||
}
|
||||
dec += rem;
|
||||
|
||||
/* If there's any decoded data left, move it to the front of the
|
||||
* buffer for next time */
|
||||
stream->FrameData += rem;
|
||||
stream->FrameDataSize -= rem;
|
||||
}
|
||||
}
|
||||
|
||||
/* Return the number of bytes we were able to get */
|
||||
return dec;
|
||||
}
|
||||
|
||||
void *decodeAVAudioStream(StreamPtr stream, size_t *length)
|
||||
{
|
||||
char *outbuf = NULL;
|
||||
size_t buflen = 0;
|
||||
void *inbuf;
|
||||
size_t got;
|
||||
|
||||
*length = 0;
|
||||
if(!stream || stream->CodecCtx->codec_type != AVMEDIA_TYPE_AUDIO)
|
||||
return NULL;
|
||||
|
||||
while((inbuf=getAVAudioData(stream, &got)) != NULL && got > 0)
|
||||
{
|
||||
void *ptr;
|
||||
|
||||
ptr = realloc(outbuf, NextPowerOf2(buflen+got));
|
||||
if(ptr == NULL)
|
||||
break;
|
||||
outbuf = (char*)ptr;
|
||||
|
||||
memcpy(&outbuf[buflen], inbuf, got);
|
||||
buflen += got;
|
||||
}
|
||||
outbuf = (char*)realloc(outbuf, buflen);
|
||||
|
||||
*length = buflen;
|
||||
return outbuf;
|
||||
}
|
||||
@@ -0,0 +1,66 @@
|
||||
#ifndef ALFFMPEG_H
|
||||
#define ALFFMPEG_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif /* __cplusplus */
|
||||
|
||||
#include <libavcodec/avcodec.h>
|
||||
#include <libavformat/avformat.h>
|
||||
|
||||
/* Opaque handles to files and streams. Apps don't need to concern themselves
|
||||
* with the internals */
|
||||
typedef struct MyFile *FilePtr;
|
||||
typedef struct MyStream *StreamPtr;
|
||||
|
||||
/* Opens a file with ffmpeg and sets up the streams' information */
|
||||
FilePtr openAVFile(const char *fname);
|
||||
|
||||
/* Opens a named file image with ffmpeg and sets up the streams' information */
|
||||
FilePtr openAVData(const char *name, char *buffer, size_t buffer_len);
|
||||
|
||||
/* Opens a named data stream with ffmpeg, using the specified data pointer and
|
||||
* callbacks, and sets up the streams' information */
|
||||
FilePtr openAVCustom(const char *name, void *user_data,
|
||||
int (*read_packet)(void *user_data, uint8_t *buf, int buf_size),
|
||||
int (*write_packet)(void *user_data, uint8_t *buf, int buf_size),
|
||||
int64_t (*seek)(void *user_data, int64_t offset, int whence));
|
||||
|
||||
/* Closes/frees an opened file and any of its streams */
|
||||
void closeAVFile(FilePtr file);
|
||||
|
||||
/* Reports certain information from the file, eg, the number of audio
|
||||
* streams. Returns 0 on success. */
|
||||
int getAVFileInfo(FilePtr file, int *numaudiostreams);
|
||||
|
||||
/* Retrieves a handle for the given audio stream number (generally 0, but some
|
||||
* files can have multiple audio streams in one file). */
|
||||
StreamPtr getAVAudioStream(FilePtr file, int streamnum);
|
||||
|
||||
/* Returns information about the given audio stream. Returns 0 on success. */
|
||||
int getAVAudioInfo(StreamPtr stream, ALuint *rate, ALenum *channels, ALenum *type);
|
||||
|
||||
/* Returns a pointer to the next available packet of decoded audio. Any data
|
||||
* from a previously-decoded packet is dropped. The size (in bytes) of the
|
||||
* returned data buffer is stored in 'length', and the returned pointer is only
|
||||
* valid until the next call to getAVAudioData or readAVAudioData. */
|
||||
uint8_t *getAVAudioData(StreamPtr stream, size_t *length);
|
||||
|
||||
/* The "meat" function. Decodes audio and writes, at most, length bytes into
|
||||
* the provided data buffer. Will only return less for end-of-stream or error
|
||||
* conditions. Returns the number of bytes written. */
|
||||
size_t readAVAudioData(StreamPtr stream, void *data, size_t length);
|
||||
|
||||
/* Decodes all remaining data from the stream and returns a buffer containing
|
||||
* the audio data, with the size stored in 'length'. The returned pointer must
|
||||
* be freed with a call to free(). Note that since this decodes the whole
|
||||
* stream, using it on lengthy streams (eg, music) will use a lot of memory.
|
||||
* Such streams are better handled using getAVAudioData or readAVAudioData to
|
||||
* keep smaller chunks in memory at any given time. */
|
||||
void *decodeAVAudioStream(StreamPtr stream, size_t *length);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif /* __cplusplus */
|
||||
|
||||
#endif /* ALFFMPEG_H */
|
||||
@@ -0,0 +1,327 @@
|
||||
/*
|
||||
* OpenAL Helpers
|
||||
*
|
||||
* Copyright (c) 2011 by Chris Robinson <chris.kcat@gmail.com>
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
/* This file contains routines to help with some menial OpenAL-related tasks,
|
||||
* such as opening a device and setting up a context, closing the device and
|
||||
* destroying its context, converting between frame counts and byte lengths,
|
||||
* finding an appropriate buffer format, and getting readable strings for
|
||||
* channel configs and sample types. */
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#include "AL/al.h"
|
||||
#include "AL/alc.h"
|
||||
#include "AL/alext.h"
|
||||
|
||||
#include "alhelpers.h"
|
||||
|
||||
|
||||
/* InitAL opens the default device and sets up a context using default
|
||||
* attributes, making the program ready to call OpenAL functions. */
|
||||
int InitAL(void)
|
||||
{
|
||||
ALCdevice *device;
|
||||
ALCcontext *ctx;
|
||||
|
||||
/* Open and initialize a device with default settings */
|
||||
device = alcOpenDevice(NULL);
|
||||
if(!device)
|
||||
{
|
||||
fprintf(stderr, "Could not open a device!\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
ctx = alcCreateContext(device, NULL);
|
||||
if(ctx == NULL || alcMakeContextCurrent(ctx) == ALC_FALSE)
|
||||
{
|
||||
if(ctx != NULL)
|
||||
alcDestroyContext(ctx);
|
||||
alcCloseDevice(device);
|
||||
fprintf(stderr, "Could not set a context!\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
printf("Opened \"%s\"\n", alcGetString(device, ALC_DEVICE_SPECIFIER));
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* CloseAL closes the device belonging to the current context, and destroys the
|
||||
* context. */
|
||||
void CloseAL(void)
|
||||
{
|
||||
ALCdevice *device;
|
||||
ALCcontext *ctx;
|
||||
|
||||
ctx = alcGetCurrentContext();
|
||||
if(ctx == NULL)
|
||||
return;
|
||||
|
||||
device = alcGetContextsDevice(ctx);
|
||||
|
||||
alcMakeContextCurrent(NULL);
|
||||
alcDestroyContext(ctx);
|
||||
alcCloseDevice(device);
|
||||
}
|
||||
|
||||
|
||||
/* GetFormat retrieves a compatible buffer format given the channel config and
|
||||
* sample type. If an alIsBufferFormatSupportedSOFT-compatible function is
|
||||
* provided, it will be called to find the closest-matching format from
|
||||
* AL_SOFT_buffer_samples. Returns AL_NONE (0) if no supported format can be
|
||||
* found. */
|
||||
ALenum GetFormat(ALenum channels, ALenum type, LPALISBUFFERFORMATSUPPORTEDSOFT palIsBufferFormatSupportedSOFT)
|
||||
{
|
||||
ALenum format = AL_NONE;
|
||||
|
||||
/* If using AL_SOFT_buffer_samples, try looking through its formats */
|
||||
if(palIsBufferFormatSupportedSOFT)
|
||||
{
|
||||
/* AL_SOFT_buffer_samples is more lenient with matching formats. The
|
||||
* specified sample type does not need to match the returned format,
|
||||
* but it is nice to try to get something close. */
|
||||
if(type == AL_UNSIGNED_BYTE_SOFT || type == AL_BYTE_SOFT)
|
||||
{
|
||||
if(channels == AL_MONO_SOFT) format = AL_MONO8_SOFT;
|
||||
else if(channels == AL_STEREO_SOFT) format = AL_STEREO8_SOFT;
|
||||
else if(channels == AL_QUAD_SOFT) format = AL_QUAD8_SOFT;
|
||||
else if(channels == AL_5POINT1_SOFT) format = AL_5POINT1_8_SOFT;
|
||||
else if(channels == AL_6POINT1_SOFT) format = AL_6POINT1_8_SOFT;
|
||||
else if(channels == AL_7POINT1_SOFT) format = AL_7POINT1_8_SOFT;
|
||||
}
|
||||
else if(type == AL_UNSIGNED_SHORT_SOFT || type == AL_SHORT_SOFT)
|
||||
{
|
||||
if(channels == AL_MONO_SOFT) format = AL_MONO16_SOFT;
|
||||
else if(channels == AL_STEREO_SOFT) format = AL_STEREO16_SOFT;
|
||||
else if(channels == AL_QUAD_SOFT) format = AL_QUAD16_SOFT;
|
||||
else if(channels == AL_5POINT1_SOFT) format = AL_5POINT1_16_SOFT;
|
||||
else if(channels == AL_6POINT1_SOFT) format = AL_6POINT1_16_SOFT;
|
||||
else if(channels == AL_7POINT1_SOFT) format = AL_7POINT1_16_SOFT;
|
||||
}
|
||||
else if(type == AL_UNSIGNED_BYTE3_SOFT || type == AL_BYTE3_SOFT ||
|
||||
type == AL_UNSIGNED_INT_SOFT || type == AL_INT_SOFT ||
|
||||
type == AL_FLOAT_SOFT || type == AL_DOUBLE_SOFT)
|
||||
{
|
||||
if(channels == AL_MONO_SOFT) format = AL_MONO32F_SOFT;
|
||||
else if(channels == AL_STEREO_SOFT) format = AL_STEREO32F_SOFT;
|
||||
else if(channels == AL_QUAD_SOFT) format = AL_QUAD32F_SOFT;
|
||||
else if(channels == AL_5POINT1_SOFT) format = AL_5POINT1_32F_SOFT;
|
||||
else if(channels == AL_6POINT1_SOFT) format = AL_6POINT1_32F_SOFT;
|
||||
else if(channels == AL_7POINT1_SOFT) format = AL_7POINT1_32F_SOFT;
|
||||
}
|
||||
|
||||
if(format != AL_NONE && !palIsBufferFormatSupportedSOFT(format))
|
||||
format = AL_NONE;
|
||||
|
||||
/* A matching format was not found or supported. Try 32-bit float. */
|
||||
if(format == AL_NONE)
|
||||
{
|
||||
if(channels == AL_MONO_SOFT) format = AL_MONO32F_SOFT;
|
||||
else if(channels == AL_STEREO_SOFT) format = AL_STEREO32F_SOFT;
|
||||
else if(channels == AL_QUAD_SOFT) format = AL_QUAD32F_SOFT;
|
||||
else if(channels == AL_5POINT1_SOFT) format = AL_5POINT1_32F_SOFT;
|
||||
else if(channels == AL_6POINT1_SOFT) format = AL_6POINT1_32F_SOFT;
|
||||
else if(channels == AL_7POINT1_SOFT) format = AL_7POINT1_32F_SOFT;
|
||||
|
||||
if(format != AL_NONE && !palIsBufferFormatSupportedSOFT(format))
|
||||
format = AL_NONE;
|
||||
}
|
||||
/* 32-bit float not supported. Try 16-bit int. */
|
||||
if(format == AL_NONE)
|
||||
{
|
||||
if(channels == AL_MONO_SOFT) format = AL_MONO16_SOFT;
|
||||
else if(channels == AL_STEREO_SOFT) format = AL_STEREO16_SOFT;
|
||||
else if(channels == AL_QUAD_SOFT) format = AL_QUAD16_SOFT;
|
||||
else if(channels == AL_5POINT1_SOFT) format = AL_5POINT1_16_SOFT;
|
||||
else if(channels == AL_6POINT1_SOFT) format = AL_6POINT1_16_SOFT;
|
||||
else if(channels == AL_7POINT1_SOFT) format = AL_7POINT1_16_SOFT;
|
||||
|
||||
if(format != AL_NONE && !palIsBufferFormatSupportedSOFT(format))
|
||||
format = AL_NONE;
|
||||
}
|
||||
/* 16-bit int not supported. Try 8-bit int. */
|
||||
if(format == AL_NONE)
|
||||
{
|
||||
if(channels == AL_MONO_SOFT) format = AL_MONO8_SOFT;
|
||||
else if(channels == AL_STEREO_SOFT) format = AL_STEREO8_SOFT;
|
||||
else if(channels == AL_QUAD_SOFT) format = AL_QUAD8_SOFT;
|
||||
else if(channels == AL_5POINT1_SOFT) format = AL_5POINT1_8_SOFT;
|
||||
else if(channels == AL_6POINT1_SOFT) format = AL_6POINT1_8_SOFT;
|
||||
else if(channels == AL_7POINT1_SOFT) format = AL_7POINT1_8_SOFT;
|
||||
|
||||
if(format != AL_NONE && !palIsBufferFormatSupportedSOFT(format))
|
||||
format = AL_NONE;
|
||||
}
|
||||
|
||||
return format;
|
||||
}
|
||||
|
||||
/* We use the AL_EXT_MCFORMATS extension to provide output of Quad, 5.1,
|
||||
* and 7.1 channel configs, AL_EXT_FLOAT32 for 32-bit float samples, and
|
||||
* AL_EXT_DOUBLE for 64-bit float samples. */
|
||||
if(type == AL_UNSIGNED_BYTE_SOFT)
|
||||
{
|
||||
if(channels == AL_MONO_SOFT)
|
||||
format = AL_FORMAT_MONO8;
|
||||
else if(channels == AL_STEREO_SOFT)
|
||||
format = AL_FORMAT_STEREO8;
|
||||
else if(alIsExtensionPresent("AL_EXT_MCFORMATS"))
|
||||
{
|
||||
if(channels == AL_QUAD_SOFT)
|
||||
format = alGetEnumValue("AL_FORMAT_QUAD8");
|
||||
else if(channels == AL_5POINT1_SOFT)
|
||||
format = alGetEnumValue("AL_FORMAT_51CHN8");
|
||||
else if(channels == AL_6POINT1_SOFT)
|
||||
format = alGetEnumValue("AL_FORMAT_61CHN8");
|
||||
else if(channels == AL_7POINT1_SOFT)
|
||||
format = alGetEnumValue("AL_FORMAT_71CHN8");
|
||||
}
|
||||
}
|
||||
else if(type == AL_SHORT_SOFT)
|
||||
{
|
||||
if(channels == AL_MONO_SOFT)
|
||||
format = AL_FORMAT_MONO16;
|
||||
else if(channels == AL_STEREO_SOFT)
|
||||
format = AL_FORMAT_STEREO16;
|
||||
else if(alIsExtensionPresent("AL_EXT_MCFORMATS"))
|
||||
{
|
||||
if(channels == AL_QUAD_SOFT)
|
||||
format = alGetEnumValue("AL_FORMAT_QUAD16");
|
||||
else if(channels == AL_5POINT1_SOFT)
|
||||
format = alGetEnumValue("AL_FORMAT_51CHN16");
|
||||
else if(channels == AL_6POINT1_SOFT)
|
||||
format = alGetEnumValue("AL_FORMAT_61CHN16");
|
||||
else if(channels == AL_7POINT1_SOFT)
|
||||
format = alGetEnumValue("AL_FORMAT_71CHN16");
|
||||
}
|
||||
}
|
||||
else if(type == AL_FLOAT_SOFT && alIsExtensionPresent("AL_EXT_FLOAT32"))
|
||||
{
|
||||
if(channels == AL_MONO_SOFT)
|
||||
format = alGetEnumValue("AL_FORMAT_MONO_FLOAT32");
|
||||
else if(channels == AL_STEREO_SOFT)
|
||||
format = alGetEnumValue("AL_FORMAT_STEREO_FLOAT32");
|
||||
else if(alIsExtensionPresent("AL_EXT_MCFORMATS"))
|
||||
{
|
||||
if(channels == AL_QUAD_SOFT)
|
||||
format = alGetEnumValue("AL_FORMAT_QUAD32");
|
||||
else if(channels == AL_5POINT1_SOFT)
|
||||
format = alGetEnumValue("AL_FORMAT_51CHN32");
|
||||
else if(channels == AL_6POINT1_SOFT)
|
||||
format = alGetEnumValue("AL_FORMAT_61CHN32");
|
||||
else if(channels == AL_7POINT1_SOFT)
|
||||
format = alGetEnumValue("AL_FORMAT_71CHN32");
|
||||
}
|
||||
}
|
||||
else if(type == AL_DOUBLE_SOFT && alIsExtensionPresent("AL_EXT_DOUBLE"))
|
||||
{
|
||||
if(channels == AL_MONO_SOFT)
|
||||
format = alGetEnumValue("AL_FORMAT_MONO_DOUBLE");
|
||||
else if(channels == AL_STEREO_SOFT)
|
||||
format = alGetEnumValue("AL_FORMAT_STEREO_DOUBLE");
|
||||
}
|
||||
|
||||
/* NOTE: It seems OSX returns -1 from alGetEnumValue for unknown enums, as
|
||||
* opposed to 0. Correct it. */
|
||||
if(format == -1)
|
||||
format = 0;
|
||||
|
||||
return format;
|
||||
}
|
||||
|
||||
|
||||
void AL_APIENTRY wrap_BufferSamples(ALuint buffer, ALuint samplerate,
|
||||
ALenum internalformat, ALsizei samples,
|
||||
ALenum channels, ALenum type,
|
||||
const ALvoid *data)
|
||||
{
|
||||
alBufferData(buffer, internalformat, data,
|
||||
FramesToBytes(samples, channels, type),
|
||||
samplerate);
|
||||
}
|
||||
|
||||
|
||||
const char *ChannelsName(ALenum chans)
|
||||
{
|
||||
switch(chans)
|
||||
{
|
||||
case AL_MONO_SOFT: return "Mono";
|
||||
case AL_STEREO_SOFT: return "Stereo";
|
||||
case AL_REAR_SOFT: return "Rear";
|
||||
case AL_QUAD_SOFT: return "Quadraphonic";
|
||||
case AL_5POINT1_SOFT: return "5.1 Surround";
|
||||
case AL_6POINT1_SOFT: return "6.1 Surround";
|
||||
case AL_7POINT1_SOFT: return "7.1 Surround";
|
||||
}
|
||||
return "Unknown Channels";
|
||||
}
|
||||
|
||||
const char *TypeName(ALenum type)
|
||||
{
|
||||
switch(type)
|
||||
{
|
||||
case AL_BYTE_SOFT: return "S8";
|
||||
case AL_UNSIGNED_BYTE_SOFT: return "U8";
|
||||
case AL_SHORT_SOFT: return "S16";
|
||||
case AL_UNSIGNED_SHORT_SOFT: return "U16";
|
||||
case AL_INT_SOFT: return "S32";
|
||||
case AL_UNSIGNED_INT_SOFT: return "U32";
|
||||
case AL_FLOAT_SOFT: return "Float32";
|
||||
case AL_DOUBLE_SOFT: return "Float64";
|
||||
}
|
||||
return "Unknown Type";
|
||||
}
|
||||
|
||||
|
||||
ALsizei FramesToBytes(ALsizei size, ALenum channels, ALenum type)
|
||||
{
|
||||
switch(channels)
|
||||
{
|
||||
case AL_MONO_SOFT: size *= 1; break;
|
||||
case AL_STEREO_SOFT: size *= 2; break;
|
||||
case AL_REAR_SOFT: size *= 2; break;
|
||||
case AL_QUAD_SOFT: size *= 4; break;
|
||||
case AL_5POINT1_SOFT: size *= 6; break;
|
||||
case AL_6POINT1_SOFT: size *= 7; break;
|
||||
case AL_7POINT1_SOFT: size *= 8; break;
|
||||
}
|
||||
|
||||
switch(type)
|
||||
{
|
||||
case AL_BYTE_SOFT: size *= sizeof(ALbyte); break;
|
||||
case AL_UNSIGNED_BYTE_SOFT: size *= sizeof(ALubyte); break;
|
||||
case AL_SHORT_SOFT: size *= sizeof(ALshort); break;
|
||||
case AL_UNSIGNED_SHORT_SOFT: size *= sizeof(ALushort); break;
|
||||
case AL_INT_SOFT: size *= sizeof(ALint); break;
|
||||
case AL_UNSIGNED_INT_SOFT: size *= sizeof(ALuint); break;
|
||||
case AL_FLOAT_SOFT: size *= sizeof(ALfloat); break;
|
||||
case AL_DOUBLE_SOFT: size *= sizeof(ALdouble); break;
|
||||
}
|
||||
|
||||
return size;
|
||||
}
|
||||
|
||||
ALsizei BytesToFrames(ALsizei size, ALenum channels, ALenum type)
|
||||
{
|
||||
return size / FramesToBytes(1, channels, type);
|
||||
}
|
||||
@@ -0,0 +1,47 @@
|
||||
#ifndef ALHELPERS_H
|
||||
#define ALHELPERS_H
|
||||
|
||||
#ifndef _WIN32
|
||||
#include <unistd.h>
|
||||
#define Sleep(x) usleep((x)*1000)
|
||||
#else
|
||||
#define WIN32_LEAN_AND_MEAN
|
||||
#include <windows.h>
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif /* __cplusplus */
|
||||
|
||||
/* Some helper functions to get the name from the channel and type enums. */
|
||||
const char *ChannelsName(ALenum chans);
|
||||
const char *TypeName(ALenum type);
|
||||
|
||||
/* Helpers to convert frame counts and byte lengths. */
|
||||
ALsizei FramesToBytes(ALsizei size, ALenum channels, ALenum type);
|
||||
ALsizei BytesToFrames(ALsizei size, ALenum channels, ALenum type);
|
||||
|
||||
/* Retrieves a compatible buffer format given the channel configuration and
|
||||
* sample type. If an alIsBufferFormatSupportedSOFT-compatible function is
|
||||
* provided, it will be called to find the closest-matching format from
|
||||
* AL_SOFT_buffer_samples. Returns AL_NONE (0) if no supported format can be
|
||||
* found. */
|
||||
ALenum GetFormat(ALenum channels, ALenum type, LPALISBUFFERFORMATSUPPORTEDSOFT palIsBufferFormatSupportedSOFT);
|
||||
|
||||
/* Loads samples into a buffer using the standard alBufferData call, but with a
|
||||
* LPALBUFFERSAMPLESSOFT-compatible prototype. Assumes internalformat is valid
|
||||
* for alBufferData, and that channels and type match it. */
|
||||
void AL_APIENTRY wrap_BufferSamples(ALuint buffer, ALuint samplerate,
|
||||
ALenum internalformat, ALsizei samples,
|
||||
ALenum channels, ALenum type,
|
||||
const ALvoid *data);
|
||||
|
||||
/* Easy device init/deinit functions. InitAL returns 0 on success. */
|
||||
int InitAL(void);
|
||||
void CloseAL(void);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif /* __cplusplus */
|
||||
|
||||
#endif /* ALHELPERS_H */
|
||||
@@ -0,0 +1,74 @@
|
||||
HRTF Support
|
||||
============
|
||||
|
||||
Starting with OpenAL Soft 1.14, HRTFs can be used to enable enhanced
|
||||
spatialization for both 3D (mono) and multi-channel sources, when used with
|
||||
headphones/stereo output. This can be enabled using the 'hrtf' config option.
|
||||
|
||||
For multi-channel sources this creates a virtual speaker effect, making it
|
||||
sound as if speakers provide a discrete position for each channel around the
|
||||
listener. For mono sources this provides much more versatility in the perceived
|
||||
placement of sounds, making it seem as though they are coming from all around,
|
||||
including above and below the listener, instead of just to the front, back, and
|
||||
sides.
|
||||
|
||||
The built-in data set is based on the KEMAR HRTF data provided by MIT, which
|
||||
can be found at <http://sound.media.mit.edu/resources/KEMAR.html>. It's only
|
||||
available when using 44100hz playback.
|
||||
|
||||
|
||||
External HRTF Data Sets
|
||||
=======================
|
||||
|
||||
OpenAL Soft also provides an option to use user-specified data sets, in
|
||||
addition to or in place of the built-in set. This allows users to provide their
|
||||
own data sets, which could be better suited for their heads, or to work with
|
||||
stereo speakers instead of headphones, or to support more playback sample
|
||||
rates, for example.
|
||||
|
||||
The file format is specified below. It uses little-endian byte order.
|
||||
|
||||
==
|
||||
ALchar magic[8] = "MinPHR01";
|
||||
ALuint sampleRate;
|
||||
|
||||
ALubyte hrirSize; /* Can be 8 to 128 in steps of 8. */
|
||||
ALubyte evCount; /* Can be 5 to 128. */
|
||||
|
||||
ALubyte azCount[evCount]; /* Each can be 1 to 128. */
|
||||
|
||||
/* NOTE: hrirCount is the sum of all azCounts */
|
||||
ALshort coefficients[hrirCount][hrirSize];
|
||||
ALubyte delays[hrirCount]; /* Each can be 0 to 63. */
|
||||
==
|
||||
|
||||
The data is described as thus:
|
||||
|
||||
The file first starts with the 8-byte marker, "MinPHR01", to identify it as an
|
||||
HRTF data set. This is followed by an unsigned 32-bit integer, specifying the
|
||||
sample rate the data set is designed for (OpenAL Soft will not use it if the
|
||||
output device's playback rate doesn't match).
|
||||
|
||||
Afterward, an unsigned 8-bit integer specifies how many sample points (or
|
||||
finite impulse response filter coefficients) make up each HRIR.
|
||||
|
||||
The following unsigned 8-bit integer specifies the number of elevations used
|
||||
by the data set. The elevations start at the bottom (-90 degrees), and
|
||||
increment upwards. Following this is an array of unsigned 8-bit integers, one
|
||||
for each elevation which specifies the number of azimuths (and thus HRIRs) that
|
||||
make up each elevation. Azimuths start clockwise from the front, constructing
|
||||
a full circle for the left ear only. The right ear uses the same HRIRs but in
|
||||
reverse (ie, left = angle, right = 360-angle).
|
||||
|
||||
The actual coefficients follow. Each coefficient is a signed 16-bit sample,
|
||||
with each HRIR being a consecutive number of sample points. The HRIRs must be
|
||||
minimum-phase. This allows the use of a smaller filter length, reducing
|
||||
computation. For reference, the built-in data set uses a 32-point filter while
|
||||
even the smallest data set provided by MIT used a 128-sample filter (a 4x
|
||||
reduction by applying minimum-phase reconstruction). Theoretically, one could
|
||||
further reduce the minimum-phase version down to a 16-point filter with only a
|
||||
small reduction in quality.
|
||||
|
||||
After the coefficients is an array of unsigned 8-bit delay values, one for
|
||||
each HRIR. This is the propagation delay (in samples) a signal must wait before
|
||||
being convolved with the corresponding minimum-phase HRIR filter.
|
||||
+515
-583
File diff suppressed because it is too large
Load Diff
+107
-151
@@ -5,16 +5,11 @@
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#if defined(_WIN32) && !defined(_XBOX)
|
||||
/* _OPENAL32LIB is deprecated */
|
||||
#if defined(AL_BUILD_LIBRARY) || defined (_OPENAL32LIB)
|
||||
#define ALC_API __declspec(dllexport)
|
||||
#else
|
||||
#ifndef ALC_API
|
||||
#if defined(AL_LIBTYPE_STATIC)
|
||||
#define ALC_API
|
||||
#elif defined(_WIN32)
|
||||
#define ALC_API __declspec(dllimport)
|
||||
#endif
|
||||
#else
|
||||
#if defined(AL_BUILD_LIBRARY) && defined(HAVE_GCC_VISIBILITY)
|
||||
#define ALC_API __attribute__((visibility("default")))
|
||||
#else
|
||||
#define ALC_API extern
|
||||
#endif
|
||||
@@ -26,25 +21,20 @@ extern "C" {
|
||||
#define ALC_APIENTRY
|
||||
#endif
|
||||
|
||||
#if defined(TARGET_OS_MAC) && TARGET_OS_MAC
|
||||
#pragma export on
|
||||
#endif
|
||||
|
||||
/*
|
||||
* The ALCAPI, ALCAPIENTRY, and ALC_INVALID macros are deprecated, but are
|
||||
* included for applications porting code from AL 1.0
|
||||
*/
|
||||
#define ALCAPI ALC_API
|
||||
#define ALCAPIENTRY ALC_APIENTRY
|
||||
#define ALC_INVALID 0
|
||||
/** Deprecated macro. */
|
||||
#define ALCAPI ALC_API
|
||||
#define ALCAPIENTRY ALC_APIENTRY
|
||||
#define ALC_INVALID 0
|
||||
|
||||
/** Supported ALC version? */
|
||||
#define ALC_VERSION_0_1 1
|
||||
|
||||
#define ALC_VERSION_0_1 1
|
||||
|
||||
/** Opaque device handle */
|
||||
typedef struct ALCdevice_struct ALCdevice;
|
||||
/** Opaque context handle */
|
||||
typedef struct ALCcontext_struct ALCcontext;
|
||||
|
||||
|
||||
/** 8-bit boolean */
|
||||
typedef char ALCboolean;
|
||||
|
||||
@@ -52,7 +42,7 @@ typedef char ALCboolean;
|
||||
typedef char ALCchar;
|
||||
|
||||
/** signed 8-bit 2's complement integer */
|
||||
typedef char ALCbyte;
|
||||
typedef signed char ALCbyte;
|
||||
|
||||
/** unsigned 8-bit integer */
|
||||
typedef unsigned char ALCubyte;
|
||||
@@ -87,192 +77,158 @@ typedef void ALCvoid;
|
||||
|
||||
/* Enumerant values begin at column 50. No tabs. */
|
||||
|
||||
/* Boolean False. */
|
||||
/** Boolean False. */
|
||||
#define ALC_FALSE 0
|
||||
|
||||
/* Boolean True. */
|
||||
/** Boolean True. */
|
||||
#define ALC_TRUE 1
|
||||
|
||||
/**
|
||||
* followed by <int> Hz
|
||||
*/
|
||||
/** Context attribute: <int> Hz. */
|
||||
#define ALC_FREQUENCY 0x1007
|
||||
|
||||
/**
|
||||
* followed by <int> Hz
|
||||
*/
|
||||
/** Context attribute: <int> Hz. */
|
||||
#define ALC_REFRESH 0x1008
|
||||
|
||||
/**
|
||||
* followed by AL_TRUE, AL_FALSE
|
||||
*/
|
||||
/** Context attribute: AL_TRUE or AL_FALSE. */
|
||||
#define ALC_SYNC 0x1009
|
||||
|
||||
/**
|
||||
* followed by <int> Num of requested Mono (3D) Sources
|
||||
*/
|
||||
/** Context attribute: <int> requested Mono (3D) Sources. */
|
||||
#define ALC_MONO_SOURCES 0x1010
|
||||
|
||||
/**
|
||||
* followed by <int> Num of requested Stereo Sources
|
||||
*/
|
||||
/** Context attribute: <int> requested Stereo Sources. */
|
||||
#define ALC_STEREO_SOURCES 0x1011
|
||||
|
||||
/**
|
||||
* errors
|
||||
*/
|
||||
/** No error. */
|
||||
#define ALC_NO_ERROR 0
|
||||
|
||||
/**
|
||||
* No error
|
||||
*/
|
||||
#define ALC_NO_ERROR ALC_FALSE
|
||||
|
||||
/**
|
||||
* No device
|
||||
*/
|
||||
/** Invalid device handle. */
|
||||
#define ALC_INVALID_DEVICE 0xA001
|
||||
|
||||
/**
|
||||
* invalid context ID
|
||||
*/
|
||||
/** Invalid context handle. */
|
||||
#define ALC_INVALID_CONTEXT 0xA002
|
||||
|
||||
/**
|
||||
* bad enum
|
||||
*/
|
||||
/** Invalid enum parameter passed to an ALC call. */
|
||||
#define ALC_INVALID_ENUM 0xA003
|
||||
|
||||
/**
|
||||
* bad value
|
||||
*/
|
||||
/** Invalid value parameter passed to an ALC call. */
|
||||
#define ALC_INVALID_VALUE 0xA004
|
||||
|
||||
/**
|
||||
* Out of memory.
|
||||
*/
|
||||
/** Out of memory. */
|
||||
#define ALC_OUT_OF_MEMORY 0xA005
|
||||
|
||||
|
||||
/**
|
||||
* The Specifier string for default device
|
||||
*/
|
||||
#define ALC_DEFAULT_DEVICE_SPECIFIER 0x1004
|
||||
#define ALC_DEVICE_SPECIFIER 0x1005
|
||||
#define ALC_EXTENSIONS 0x1006
|
||||
|
||||
/** Runtime ALC version. */
|
||||
#define ALC_MAJOR_VERSION 0x1000
|
||||
#define ALC_MINOR_VERSION 0x1001
|
||||
|
||||
/** Context attribute list properties. */
|
||||
#define ALC_ATTRIBUTES_SIZE 0x1002
|
||||
#define ALC_ALL_ATTRIBUTES 0x1003
|
||||
|
||||
/** String for the default device specifier. */
|
||||
#define ALC_DEFAULT_DEVICE_SPECIFIER 0x1004
|
||||
/**
|
||||
* ALC_ENUMERATE_ALL_EXT enums
|
||||
* String for the given device's specifier.
|
||||
*
|
||||
* If device handle is NULL, it is instead a null-char separated list of
|
||||
* strings of known device specifiers (list ends with an empty string).
|
||||
*/
|
||||
#define ALC_DEFAULT_ALL_DEVICES_SPECIFIER 0x1012
|
||||
#define ALC_ALL_DEVICES_SPECIFIER 0x1013
|
||||
#define ALC_DEVICE_SPECIFIER 0x1005
|
||||
/** String for space-separated list of ALC extensions. */
|
||||
#define ALC_EXTENSIONS 0x1006
|
||||
|
||||
|
||||
/** Capture extension */
|
||||
#define ALC_EXT_CAPTURE 1
|
||||
/**
|
||||
* Capture extension
|
||||
* String for the given capture device's specifier.
|
||||
*
|
||||
* If device handle is NULL, it is instead a null-char separated list of
|
||||
* strings of known capture device specifiers (list ends with an empty string).
|
||||
*/
|
||||
#define ALC_CAPTURE_DEVICE_SPECIFIER 0x310
|
||||
/** String for the default capture device specifier. */
|
||||
#define ALC_CAPTURE_DEFAULT_DEVICE_SPECIFIER 0x311
|
||||
/** Number of sample frames available for capture. */
|
||||
#define ALC_CAPTURE_SAMPLES 0x312
|
||||
|
||||
|
||||
/*
|
||||
* Context Management
|
||||
/** Enumerate All extension */
|
||||
#define ALC_ENUMERATE_ALL_EXT 1
|
||||
/** String for the default extended device specifier. */
|
||||
#define ALC_DEFAULT_ALL_DEVICES_SPECIFIER 0x1012
|
||||
/**
|
||||
* String for the given extended device's specifier.
|
||||
*
|
||||
* If device handle is NULL, it is instead a null-char separated list of
|
||||
* strings of known extended device specifiers (list ends with an empty string).
|
||||
*/
|
||||
ALC_API ALCcontext * ALC_APIENTRY alcCreateContext( ALCdevice *device, const ALCint* attrlist );
|
||||
|
||||
ALC_API ALCboolean ALC_APIENTRY alcMakeContextCurrent( ALCcontext *context );
|
||||
|
||||
ALC_API void ALC_APIENTRY alcProcessContext( ALCcontext *context );
|
||||
|
||||
ALC_API void ALC_APIENTRY alcSuspendContext( ALCcontext *context );
|
||||
|
||||
ALC_API void ALC_APIENTRY alcDestroyContext( ALCcontext *context );
|
||||
|
||||
ALC_API ALCcontext * ALC_APIENTRY alcGetCurrentContext( void );
|
||||
|
||||
ALC_API ALCdevice* ALC_APIENTRY alcGetContextsDevice( ALCcontext *context );
|
||||
#define ALC_ALL_DEVICES_SPECIFIER 0x1013
|
||||
|
||||
|
||||
/*
|
||||
* Device Management
|
||||
*/
|
||||
ALC_API ALCdevice * ALC_APIENTRY alcOpenDevice( const ALCchar *devicename );
|
||||
/** Context management. */
|
||||
ALC_API ALCcontext* ALC_APIENTRY alcCreateContext(ALCdevice *device, const ALCint* attrlist);
|
||||
ALC_API ALCboolean ALC_APIENTRY alcMakeContextCurrent(ALCcontext *context);
|
||||
ALC_API void ALC_APIENTRY alcProcessContext(ALCcontext *context);
|
||||
ALC_API void ALC_APIENTRY alcSuspendContext(ALCcontext *context);
|
||||
ALC_API void ALC_APIENTRY alcDestroyContext(ALCcontext *context);
|
||||
ALC_API ALCcontext* ALC_APIENTRY alcGetCurrentContext(void);
|
||||
ALC_API ALCdevice* ALC_APIENTRY alcGetContextsDevice(ALCcontext *context);
|
||||
|
||||
ALC_API ALCboolean ALC_APIENTRY alcCloseDevice( ALCdevice *device );
|
||||
/** Device management. */
|
||||
ALC_API ALCdevice* ALC_APIENTRY alcOpenDevice(const ALCchar *devicename);
|
||||
ALC_API ALCboolean ALC_APIENTRY alcCloseDevice(ALCdevice *device);
|
||||
|
||||
|
||||
/*
|
||||
/**
|
||||
* Error support.
|
||||
* Obtain the most recent Context error
|
||||
*
|
||||
* Obtain the most recent Device error.
|
||||
*/
|
||||
ALC_API ALCenum ALC_APIENTRY alcGetError( ALCdevice *device );
|
||||
ALC_API ALCenum ALC_APIENTRY alcGetError(ALCdevice *device);
|
||||
|
||||
|
||||
/*
|
||||
/**
|
||||
* Extension support.
|
||||
*
|
||||
* Query for the presence of an extension, and obtain any appropriate
|
||||
* function pointers and enum values.
|
||||
*/
|
||||
ALC_API ALCboolean ALC_APIENTRY alcIsExtensionPresent( ALCdevice *device, const ALCchar *extname );
|
||||
ALC_API ALCboolean ALC_APIENTRY alcIsExtensionPresent(ALCdevice *device, const ALCchar *extname);
|
||||
ALC_API void* ALC_APIENTRY alcGetProcAddress(ALCdevice *device, const ALCchar *funcname);
|
||||
ALC_API ALCenum ALC_APIENTRY alcGetEnumValue(ALCdevice *device, const ALCchar *enumname);
|
||||
|
||||
ALC_API void * ALC_APIENTRY alcGetProcAddress( ALCdevice *device, const ALCchar *funcname );
|
||||
/** Query function. */
|
||||
ALC_API const ALCchar* ALC_APIENTRY alcGetString(ALCdevice *device, ALCenum param);
|
||||
ALC_API void ALC_APIENTRY alcGetIntegerv(ALCdevice *device, ALCenum param, ALCsizei size, ALCint *values);
|
||||
|
||||
ALC_API ALCenum ALC_APIENTRY alcGetEnumValue( ALCdevice *device, const ALCchar *enumname );
|
||||
/** Capture function. */
|
||||
ALC_API ALCdevice* ALC_APIENTRY alcCaptureOpenDevice(const ALCchar *devicename, ALCuint frequency, ALCenum format, ALCsizei buffersize);
|
||||
ALC_API ALCboolean ALC_APIENTRY alcCaptureCloseDevice(ALCdevice *device);
|
||||
ALC_API void ALC_APIENTRY alcCaptureStart(ALCdevice *device);
|
||||
ALC_API void ALC_APIENTRY alcCaptureStop(ALCdevice *device);
|
||||
ALC_API void ALC_APIENTRY alcCaptureSamples(ALCdevice *device, ALCvoid *buffer, ALCsizei samples);
|
||||
|
||||
|
||||
/*
|
||||
* Query functions
|
||||
*/
|
||||
ALC_API const ALCchar * ALC_APIENTRY alcGetString( ALCdevice *device, ALCenum param );
|
||||
|
||||
ALC_API void ALC_APIENTRY alcGetIntegerv( ALCdevice *device, ALCenum param, ALCsizei size, ALCint *data );
|
||||
|
||||
|
||||
/*
|
||||
* Capture functions
|
||||
*/
|
||||
ALC_API ALCdevice* ALC_APIENTRY alcCaptureOpenDevice( const ALCchar *devicename, ALCuint frequency, ALCenum format, ALCsizei buffersize );
|
||||
|
||||
ALC_API ALCboolean ALC_APIENTRY alcCaptureCloseDevice( ALCdevice *device );
|
||||
|
||||
ALC_API void ALC_APIENTRY alcCaptureStart( ALCdevice *device );
|
||||
|
||||
ALC_API void ALC_APIENTRY alcCaptureStop( ALCdevice *device );
|
||||
|
||||
ALC_API void ALC_APIENTRY alcCaptureSamples( ALCdevice *device, ALCvoid *buffer, ALCsizei samples );
|
||||
|
||||
/*
|
||||
* Pointer-to-function types, useful for dynamically getting ALC entry points.
|
||||
*/
|
||||
typedef ALCcontext * (ALC_APIENTRY *LPALCCREATECONTEXT) (ALCdevice *device, const ALCint *attrlist);
|
||||
typedef ALCboolean (ALC_APIENTRY *LPALCMAKECONTEXTCURRENT)( ALCcontext *context );
|
||||
typedef void (ALC_APIENTRY *LPALCPROCESSCONTEXT)( ALCcontext *context );
|
||||
typedef void (ALC_APIENTRY *LPALCSUSPENDCONTEXT)( ALCcontext *context );
|
||||
typedef void (ALC_APIENTRY *LPALCDESTROYCONTEXT)( ALCcontext *context );
|
||||
typedef ALCcontext * (ALC_APIENTRY *LPALCGETCURRENTCONTEXT)( void );
|
||||
typedef ALCdevice * (ALC_APIENTRY *LPALCGETCONTEXTSDEVICE)( ALCcontext *context );
|
||||
typedef ALCdevice * (ALC_APIENTRY *LPALCOPENDEVICE)( const ALCchar *devicename );
|
||||
typedef ALCboolean (ALC_APIENTRY *LPALCCLOSEDEVICE)( ALCdevice *device );
|
||||
typedef ALCenum (ALC_APIENTRY *LPALCGETERROR)( ALCdevice *device );
|
||||
typedef ALCboolean (ALC_APIENTRY *LPALCISEXTENSIONPRESENT)( ALCdevice *device, const ALCchar *extname );
|
||||
typedef void * (ALC_APIENTRY *LPALCGETPROCADDRESS)(ALCdevice *device, const ALCchar *funcname );
|
||||
typedef ALCenum (ALC_APIENTRY *LPALCGETENUMVALUE)(ALCdevice *device, const ALCchar *enumname );
|
||||
typedef const ALCchar* (ALC_APIENTRY *LPALCGETSTRING)( ALCdevice *device, ALCenum param );
|
||||
typedef void (ALC_APIENTRY *LPALCGETINTEGERV)( ALCdevice *device, ALCenum param, ALCsizei size, ALCint *dest );
|
||||
typedef ALCdevice * (ALC_APIENTRY *LPALCCAPTUREOPENDEVICE)( const ALCchar *devicename, ALCuint frequency, ALCenum format, ALCsizei buffersize );
|
||||
typedef ALCboolean (ALC_APIENTRY *LPALCCAPTURECLOSEDEVICE)( ALCdevice *device );
|
||||
typedef void (ALC_APIENTRY *LPALCCAPTURESTART)( ALCdevice *device );
|
||||
typedef void (ALC_APIENTRY *LPALCCAPTURESTOP)( ALCdevice *device );
|
||||
typedef void (ALC_APIENTRY *LPALCCAPTURESAMPLES)( ALCdevice *device, ALCvoid *buffer, ALCsizei samples );
|
||||
|
||||
#if defined(TARGET_OS_MAC) && TARGET_OS_MAC
|
||||
#pragma export off
|
||||
#endif
|
||||
/** Pointer-to-function type, useful for dynamically getting ALC entry points. */
|
||||
typedef ALCcontext* (ALC_APIENTRY *LPALCCREATECONTEXT)(ALCdevice *device, const ALCint *attrlist);
|
||||
typedef ALCboolean (ALC_APIENTRY *LPALCMAKECONTEXTCURRENT)(ALCcontext *context);
|
||||
typedef void (ALC_APIENTRY *LPALCPROCESSCONTEXT)(ALCcontext *context);
|
||||
typedef void (ALC_APIENTRY *LPALCSUSPENDCONTEXT)(ALCcontext *context);
|
||||
typedef void (ALC_APIENTRY *LPALCDESTROYCONTEXT)(ALCcontext *context);
|
||||
typedef ALCcontext* (ALC_APIENTRY *LPALCGETCURRENTCONTEXT)(void);
|
||||
typedef ALCdevice* (ALC_APIENTRY *LPALCGETCONTEXTSDEVICE)(ALCcontext *context);
|
||||
typedef ALCdevice* (ALC_APIENTRY *LPALCOPENDEVICE)(const ALCchar *devicename);
|
||||
typedef ALCboolean (ALC_APIENTRY *LPALCCLOSEDEVICE)(ALCdevice *device);
|
||||
typedef ALCenum (ALC_APIENTRY *LPALCGETERROR)(ALCdevice *device);
|
||||
typedef ALCboolean (ALC_APIENTRY *LPALCISEXTENSIONPRESENT)(ALCdevice *device, const ALCchar *extname);
|
||||
typedef void* (ALC_APIENTRY *LPALCGETPROCADDRESS)(ALCdevice *device, const ALCchar *funcname);
|
||||
typedef ALCenum (ALC_APIENTRY *LPALCGETENUMVALUE)(ALCdevice *device, const ALCchar *enumname);
|
||||
typedef const ALCchar* (ALC_APIENTRY *LPALCGETSTRING)(ALCdevice *device, ALCenum param);
|
||||
typedef void (ALC_APIENTRY *LPALCGETINTEGERV)(ALCdevice *device, ALCenum param, ALCsizei size, ALCint *values);
|
||||
typedef ALCdevice* (ALC_APIENTRY *LPALCCAPTUREOPENDEVICE)(const ALCchar *devicename, ALCuint frequency, ALCenum format, ALCsizei buffersize);
|
||||
typedef ALCboolean (ALC_APIENTRY *LPALCCAPTURECLOSEDEVICE)(ALCdevice *device);
|
||||
typedef void (ALC_APIENTRY *LPALCCAPTURESTART)(ALCdevice *device);
|
||||
typedef void (ALC_APIENTRY *LPALCCAPTURESTOP)(ALCdevice *device);
|
||||
typedef void (ALC_APIENTRY *LPALCCAPTURESAMPLES)(ALCdevice *device, ALCvoid *buffer, ALCsizei samples);
|
||||
|
||||
#if defined(__cplusplus)
|
||||
}
|
||||
|
||||
@@ -0,0 +1,355 @@
|
||||
/**
|
||||
* OpenAL cross platform audio library
|
||||
* Copyright (C) 2008 by authors.
|
||||
* 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., 59 Temple Place - Suite 330,
|
||||
* Boston, MA 02111-1307, USA.
|
||||
* Or go to http://www.gnu.org/copyleft/lgpl.html
|
||||
*/
|
||||
|
||||
#ifndef AL_ALEXT_H
|
||||
#define AL_ALEXT_H
|
||||
|
||||
#include <stddef.h>
|
||||
/* Define int64_t and uint64_t types */
|
||||
#if defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L
|
||||
#include <inttypes.h>
|
||||
#elif defined(_WIN32) && defined(__GNUC__)
|
||||
#include <stdint.h>
|
||||
#elif defined(_WIN32)
|
||||
typedef __int64 int64_t;
|
||||
typedef unsigned __int64 uint64_t;
|
||||
#else
|
||||
/* Fallback if nothing above works */
|
||||
#include <inttypes.h>
|
||||
#endif
|
||||
|
||||
#include "alc.h"
|
||||
#include "al.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#ifndef AL_LOKI_IMA_ADPCM_format
|
||||
#define AL_LOKI_IMA_ADPCM_format 1
|
||||
#define AL_FORMAT_IMA_ADPCM_MONO16_EXT 0x10000
|
||||
#define AL_FORMAT_IMA_ADPCM_STEREO16_EXT 0x10001
|
||||
#endif
|
||||
|
||||
#ifndef AL_LOKI_WAVE_format
|
||||
#define AL_LOKI_WAVE_format 1
|
||||
#define AL_FORMAT_WAVE_EXT 0x10002
|
||||
#endif
|
||||
|
||||
#ifndef AL_EXT_vorbis
|
||||
#define AL_EXT_vorbis 1
|
||||
#define AL_FORMAT_VORBIS_EXT 0x10003
|
||||
#endif
|
||||
|
||||
#ifndef AL_LOKI_quadriphonic
|
||||
#define AL_LOKI_quadriphonic 1
|
||||
#define AL_FORMAT_QUAD8_LOKI 0x10004
|
||||
#define AL_FORMAT_QUAD16_LOKI 0x10005
|
||||
#endif
|
||||
|
||||
#ifndef AL_EXT_float32
|
||||
#define AL_EXT_float32 1
|
||||
#define AL_FORMAT_MONO_FLOAT32 0x10010
|
||||
#define AL_FORMAT_STEREO_FLOAT32 0x10011
|
||||
#endif
|
||||
|
||||
#ifndef AL_EXT_double
|
||||
#define AL_EXT_double 1
|
||||
#define AL_FORMAT_MONO_DOUBLE_EXT 0x10012
|
||||
#define AL_FORMAT_STEREO_DOUBLE_EXT 0x10013
|
||||
#endif
|
||||
|
||||
#ifndef AL_EXT_MULAW
|
||||
#define AL_EXT_MULAW 1
|
||||
#define AL_FORMAT_MONO_MULAW_EXT 0x10014
|
||||
#define AL_FORMAT_STEREO_MULAW_EXT 0x10015
|
||||
#endif
|
||||
|
||||
#ifndef AL_EXT_ALAW
|
||||
#define AL_EXT_ALAW 1
|
||||
#define AL_FORMAT_MONO_ALAW_EXT 0x10016
|
||||
#define AL_FORMAT_STEREO_ALAW_EXT 0x10017
|
||||
#endif
|
||||
|
||||
#ifndef ALC_LOKI_audio_channel
|
||||
#define ALC_LOKI_audio_channel 1
|
||||
#define ALC_CHAN_MAIN_LOKI 0x500001
|
||||
#define ALC_CHAN_PCM_LOKI 0x500002
|
||||
#define ALC_CHAN_CD_LOKI 0x500003
|
||||
#endif
|
||||
|
||||
#ifndef AL_EXT_MCFORMATS
|
||||
#define AL_EXT_MCFORMATS 1
|
||||
#define AL_FORMAT_QUAD8 0x1204
|
||||
#define AL_FORMAT_QUAD16 0x1205
|
||||
#define AL_FORMAT_QUAD32 0x1206
|
||||
#define AL_FORMAT_REAR8 0x1207
|
||||
#define AL_FORMAT_REAR16 0x1208
|
||||
#define AL_FORMAT_REAR32 0x1209
|
||||
#define AL_FORMAT_51CHN8 0x120A
|
||||
#define AL_FORMAT_51CHN16 0x120B
|
||||
#define AL_FORMAT_51CHN32 0x120C
|
||||
#define AL_FORMAT_61CHN8 0x120D
|
||||
#define AL_FORMAT_61CHN16 0x120E
|
||||
#define AL_FORMAT_61CHN32 0x120F
|
||||
#define AL_FORMAT_71CHN8 0x1210
|
||||
#define AL_FORMAT_71CHN16 0x1211
|
||||
#define AL_FORMAT_71CHN32 0x1212
|
||||
#endif
|
||||
|
||||
#ifndef AL_EXT_MULAW_MCFORMATS
|
||||
#define AL_EXT_MULAW_MCFORMATS 1
|
||||
#define AL_FORMAT_MONO_MULAW 0x10014
|
||||
#define AL_FORMAT_STEREO_MULAW 0x10015
|
||||
#define AL_FORMAT_QUAD_MULAW 0x10021
|
||||
#define AL_FORMAT_REAR_MULAW 0x10022
|
||||
#define AL_FORMAT_51CHN_MULAW 0x10023
|
||||
#define AL_FORMAT_61CHN_MULAW 0x10024
|
||||
#define AL_FORMAT_71CHN_MULAW 0x10025
|
||||
#endif
|
||||
|
||||
#ifndef AL_EXT_IMA4
|
||||
#define AL_EXT_IMA4 1
|
||||
#define AL_FORMAT_MONO_IMA4 0x1300
|
||||
#define AL_FORMAT_STEREO_IMA4 0x1301
|
||||
#endif
|
||||
|
||||
#ifndef AL_EXT_STATIC_BUFFER
|
||||
#define AL_EXT_STATIC_BUFFER 1
|
||||
typedef ALvoid (AL_APIENTRY*PFNALBUFFERDATASTATICPROC)(const ALint,ALenum,ALvoid*,ALsizei,ALsizei);
|
||||
#ifdef AL_ALEXT_PROTOTYPES
|
||||
AL_API ALvoid AL_APIENTRY alBufferDataStatic(const ALint buffer, ALenum format, ALvoid *data, ALsizei len, ALsizei freq);
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifndef ALC_EXT_EFX
|
||||
#define ALC_EXT_EFX 1
|
||||
#include "efx.h"
|
||||
#endif
|
||||
|
||||
#ifndef ALC_EXT_disconnect
|
||||
#define ALC_EXT_disconnect 1
|
||||
#define ALC_CONNECTED 0x313
|
||||
#endif
|
||||
|
||||
#ifndef ALC_EXT_thread_local_context
|
||||
#define ALC_EXT_thread_local_context 1
|
||||
typedef ALCboolean (ALC_APIENTRY*PFNALCSETTHREADCONTEXTPROC)(ALCcontext *context);
|
||||
typedef ALCcontext* (ALC_APIENTRY*PFNALCGETTHREADCONTEXTPROC)(void);
|
||||
#ifdef AL_ALEXT_PROTOTYPES
|
||||
ALC_API ALCboolean ALC_APIENTRY alcSetThreadContext(ALCcontext *context);
|
||||
ALC_API ALCcontext* ALC_APIENTRY alcGetThreadContext(void);
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifndef AL_EXT_source_distance_model
|
||||
#define AL_EXT_source_distance_model 1
|
||||
#define AL_SOURCE_DISTANCE_MODEL 0x200
|
||||
#endif
|
||||
|
||||
#ifndef AL_SOFT_buffer_sub_data
|
||||
#define AL_SOFT_buffer_sub_data 1
|
||||
#define AL_BYTE_RW_OFFSETS_SOFT 0x1031
|
||||
#define AL_SAMPLE_RW_OFFSETS_SOFT 0x1032
|
||||
typedef ALvoid (AL_APIENTRY*PFNALBUFFERSUBDATASOFTPROC)(ALuint,ALenum,const ALvoid*,ALsizei,ALsizei);
|
||||
#ifdef AL_ALEXT_PROTOTYPES
|
||||
AL_API ALvoid AL_APIENTRY alBufferSubDataSOFT(ALuint buffer,ALenum format,const ALvoid *data,ALsizei offset,ALsizei length);
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifndef AL_SOFT_loop_points
|
||||
#define AL_SOFT_loop_points 1
|
||||
#define AL_LOOP_POINTS_SOFT 0x2015
|
||||
#endif
|
||||
|
||||
#ifndef AL_EXT_FOLDBACK
|
||||
#define AL_EXT_FOLDBACK 1
|
||||
#define AL_EXT_FOLDBACK_NAME "AL_EXT_FOLDBACK"
|
||||
#define AL_FOLDBACK_EVENT_BLOCK 0x4112
|
||||
#define AL_FOLDBACK_EVENT_START 0x4111
|
||||
#define AL_FOLDBACK_EVENT_STOP 0x4113
|
||||
#define AL_FOLDBACK_MODE_MONO 0x4101
|
||||
#define AL_FOLDBACK_MODE_STEREO 0x4102
|
||||
typedef void (AL_APIENTRY*LPALFOLDBACKCALLBACK)(ALenum,ALsizei);
|
||||
typedef void (AL_APIENTRY*LPALREQUESTFOLDBACKSTART)(ALenum,ALsizei,ALsizei,ALfloat*,LPALFOLDBACKCALLBACK);
|
||||
typedef void (AL_APIENTRY*LPALREQUESTFOLDBACKSTOP)(void);
|
||||
#ifdef AL_ALEXT_PROTOTYPES
|
||||
AL_API void AL_APIENTRY alRequestFoldbackStart(ALenum mode,ALsizei count,ALsizei length,ALfloat *mem,LPALFOLDBACKCALLBACK callback);
|
||||
AL_API void AL_APIENTRY alRequestFoldbackStop(void);
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifndef ALC_EXT_DEDICATED
|
||||
#define ALC_EXT_DEDICATED 1
|
||||
#define AL_DEDICATED_GAIN 0x0001
|
||||
#define AL_EFFECT_DEDICATED_DIALOGUE 0x9001
|
||||
#define AL_EFFECT_DEDICATED_LOW_FREQUENCY_EFFECT 0x9000
|
||||
#endif
|
||||
|
||||
#ifndef AL_SOFT_buffer_samples
|
||||
#define AL_SOFT_buffer_samples 1
|
||||
/* Channel configurations */
|
||||
#define AL_MONO_SOFT 0x1500
|
||||
#define AL_STEREO_SOFT 0x1501
|
||||
#define AL_REAR_SOFT 0x1502
|
||||
#define AL_QUAD_SOFT 0x1503
|
||||
#define AL_5POINT1_SOFT 0x1504
|
||||
#define AL_6POINT1_SOFT 0x1505
|
||||
#define AL_7POINT1_SOFT 0x1506
|
||||
|
||||
/* Sample types */
|
||||
#define AL_BYTE_SOFT 0x1400
|
||||
#define AL_UNSIGNED_BYTE_SOFT 0x1401
|
||||
#define AL_SHORT_SOFT 0x1402
|
||||
#define AL_UNSIGNED_SHORT_SOFT 0x1403
|
||||
#define AL_INT_SOFT 0x1404
|
||||
#define AL_UNSIGNED_INT_SOFT 0x1405
|
||||
#define AL_FLOAT_SOFT 0x1406
|
||||
#define AL_DOUBLE_SOFT 0x1407
|
||||
#define AL_BYTE3_SOFT 0x1408
|
||||
#define AL_UNSIGNED_BYTE3_SOFT 0x1409
|
||||
|
||||
/* Storage formats */
|
||||
#define AL_MONO8_SOFT 0x1100
|
||||
#define AL_MONO16_SOFT 0x1101
|
||||
#define AL_MONO32F_SOFT 0x10010
|
||||
#define AL_STEREO8_SOFT 0x1102
|
||||
#define AL_STEREO16_SOFT 0x1103
|
||||
#define AL_STEREO32F_SOFT 0x10011
|
||||
#define AL_QUAD8_SOFT 0x1204
|
||||
#define AL_QUAD16_SOFT 0x1205
|
||||
#define AL_QUAD32F_SOFT 0x1206
|
||||
#define AL_REAR8_SOFT 0x1207
|
||||
#define AL_REAR16_SOFT 0x1208
|
||||
#define AL_REAR32F_SOFT 0x1209
|
||||
#define AL_5POINT1_8_SOFT 0x120A
|
||||
#define AL_5POINT1_16_SOFT 0x120B
|
||||
#define AL_5POINT1_32F_SOFT 0x120C
|
||||
#define AL_6POINT1_8_SOFT 0x120D
|
||||
#define AL_6POINT1_16_SOFT 0x120E
|
||||
#define AL_6POINT1_32F_SOFT 0x120F
|
||||
#define AL_7POINT1_8_SOFT 0x1210
|
||||
#define AL_7POINT1_16_SOFT 0x1211
|
||||
#define AL_7POINT1_32F_SOFT 0x1212
|
||||
|
||||
/* Buffer attributes */
|
||||
#define AL_INTERNAL_FORMAT_SOFT 0x2008
|
||||
#define AL_BYTE_LENGTH_SOFT 0x2009
|
||||
#define AL_SAMPLE_LENGTH_SOFT 0x200A
|
||||
#define AL_SEC_LENGTH_SOFT 0x200B
|
||||
|
||||
typedef void (AL_APIENTRY*LPALBUFFERSAMPLESSOFT)(ALuint,ALuint,ALenum,ALsizei,ALenum,ALenum,const ALvoid*);
|
||||
typedef void (AL_APIENTRY*LPALBUFFERSUBSAMPLESSOFT)(ALuint,ALsizei,ALsizei,ALenum,ALenum,const ALvoid*);
|
||||
typedef void (AL_APIENTRY*LPALGETBUFFERSAMPLESSOFT)(ALuint,ALsizei,ALsizei,ALenum,ALenum,ALvoid*);
|
||||
typedef ALboolean (AL_APIENTRY*LPALISBUFFERFORMATSUPPORTEDSOFT)(ALenum);
|
||||
#ifdef AL_ALEXT_PROTOTYPES
|
||||
AL_API void AL_APIENTRY alBufferSamplesSOFT(ALuint buffer, ALuint samplerate, ALenum internalformat, ALsizei samples, ALenum channels, ALenum type, const ALvoid *data);
|
||||
AL_API void AL_APIENTRY alBufferSubSamplesSOFT(ALuint buffer, ALsizei offset, ALsizei samples, ALenum channels, ALenum type, const ALvoid *data);
|
||||
AL_API void AL_APIENTRY alGetBufferSamplesSOFT(ALuint buffer, ALsizei offset, ALsizei samples, ALenum channels, ALenum type, ALvoid *data);
|
||||
AL_API ALboolean AL_APIENTRY alIsBufferFormatSupportedSOFT(ALenum format);
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifndef AL_SOFT_direct_channels
|
||||
#define AL_SOFT_direct_channels 1
|
||||
#define AL_DIRECT_CHANNELS_SOFT 0x1033
|
||||
#endif
|
||||
|
||||
#ifndef ALC_SOFT_loopback
|
||||
#define ALC_SOFT_loopback 1
|
||||
#define ALC_FORMAT_CHANNELS_SOFT 0x1990
|
||||
#define ALC_FORMAT_TYPE_SOFT 0x1991
|
||||
|
||||
/* Sample types */
|
||||
#define ALC_BYTE_SOFT 0x1400
|
||||
#define ALC_UNSIGNED_BYTE_SOFT 0x1401
|
||||
#define ALC_SHORT_SOFT 0x1402
|
||||
#define ALC_UNSIGNED_SHORT_SOFT 0x1403
|
||||
#define ALC_INT_SOFT 0x1404
|
||||
#define ALC_UNSIGNED_INT_SOFT 0x1405
|
||||
#define ALC_FLOAT_SOFT 0x1406
|
||||
|
||||
/* Channel configurations */
|
||||
#define ALC_MONO_SOFT 0x1500
|
||||
#define ALC_STEREO_SOFT 0x1501
|
||||
#define ALC_QUAD_SOFT 0x1503
|
||||
#define ALC_5POINT1_SOFT 0x1504
|
||||
#define ALC_6POINT1_SOFT 0x1505
|
||||
#define ALC_7POINT1_SOFT 0x1506
|
||||
|
||||
typedef ALCdevice* (ALC_APIENTRY*LPALCLOOPBACKOPENDEVICESOFT)(const ALCchar*);
|
||||
typedef ALCboolean (ALC_APIENTRY*LPALCISRENDERFORMATSUPPORTEDSOFT)(ALCdevice*,ALCsizei,ALCenum,ALCenum);
|
||||
typedef void (ALC_APIENTRY*LPALCRENDERSAMPLESSOFT)(ALCdevice*,ALCvoid*,ALCsizei);
|
||||
#ifdef AL_ALEXT_PROTOTYPES
|
||||
ALC_API ALCdevice* ALC_APIENTRY alcLoopbackOpenDeviceSOFT(const ALCchar *deviceName);
|
||||
ALC_API ALCboolean ALC_APIENTRY alcIsRenderFormatSupportedSOFT(ALCdevice *device, ALCsizei freq, ALCenum channels, ALCenum type);
|
||||
ALC_API void ALC_APIENTRY alcRenderSamplesSOFT(ALCdevice *device, ALCvoid *buffer, ALCsizei samples);
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifndef AL_EXT_STEREO_ANGLES
|
||||
#define AL_EXT_STEREO_ANGLES 1
|
||||
#define AL_STEREO_ANGLES 0x1030
|
||||
#endif
|
||||
|
||||
#ifndef AL_EXT_SOURCE_RADIUS
|
||||
#define AL_EXT_SOURCE_RADIUS 1
|
||||
#define AL_SOURCE_RADIUS 0x1031
|
||||
#endif
|
||||
|
||||
#ifndef AL_SOFT_source_latency
|
||||
#define AL_SOFT_source_latency 1
|
||||
#define AL_SAMPLE_OFFSET_LATENCY_SOFT 0x1200
|
||||
#define AL_SEC_OFFSET_LATENCY_SOFT 0x1201
|
||||
typedef int64_t ALint64SOFT;
|
||||
typedef uint64_t ALuint64SOFT;
|
||||
typedef void (AL_APIENTRY*LPALSOURCEDSOFT)(ALuint,ALenum,ALdouble);
|
||||
typedef void (AL_APIENTRY*LPALSOURCE3DSOFT)(ALuint,ALenum,ALdouble,ALdouble,ALdouble);
|
||||
typedef void (AL_APIENTRY*LPALSOURCEDVSOFT)(ALuint,ALenum,const ALdouble*);
|
||||
typedef void (AL_APIENTRY*LPALGETSOURCEDSOFT)(ALuint,ALenum,ALdouble*);
|
||||
typedef void (AL_APIENTRY*LPALGETSOURCE3DSOFT)(ALuint,ALenum,ALdouble*,ALdouble*,ALdouble*);
|
||||
typedef void (AL_APIENTRY*LPALGETSOURCEDVSOFT)(ALuint,ALenum,ALdouble*);
|
||||
typedef void (AL_APIENTRY*LPALSOURCEI64SOFT)(ALuint,ALenum,ALint64SOFT);
|
||||
typedef void (AL_APIENTRY*LPALSOURCE3I64SOFT)(ALuint,ALenum,ALint64SOFT,ALint64SOFT,ALint64SOFT);
|
||||
typedef void (AL_APIENTRY*LPALSOURCEI64VSOFT)(ALuint,ALenum,const ALint64SOFT*);
|
||||
typedef void (AL_APIENTRY*LPALGETSOURCEI64SOFT)(ALuint,ALenum,ALint64SOFT*);
|
||||
typedef void (AL_APIENTRY*LPALGETSOURCE3I64SOFT)(ALuint,ALenum,ALint64SOFT*,ALint64SOFT*,ALint64SOFT*);
|
||||
typedef void (AL_APIENTRY*LPALGETSOURCEI64VSOFT)(ALuint,ALenum,ALint64SOFT*);
|
||||
#ifdef AL_ALEXT_PROTOTYPES
|
||||
AL_API void AL_APIENTRY alSourcedSOFT(ALuint source, ALenum param, ALdouble value);
|
||||
AL_API void AL_APIENTRY alSource3dSOFT(ALuint source, ALenum param, ALdouble value1, ALdouble value2, ALdouble value3);
|
||||
AL_API void AL_APIENTRY alSourcedvSOFT(ALuint source, ALenum param, const ALdouble *values);
|
||||
AL_API void AL_APIENTRY alGetSourcedSOFT(ALuint source, ALenum param, ALdouble *value);
|
||||
AL_API void AL_APIENTRY alGetSource3dSOFT(ALuint source, ALenum param, ALdouble *value1, ALdouble *value2, ALdouble *value3);
|
||||
AL_API void AL_APIENTRY alGetSourcedvSOFT(ALuint source, ALenum param, ALdouble *values);
|
||||
AL_API void AL_APIENTRY alSourcei64SOFT(ALuint source, ALenum param, ALint64SOFT value);
|
||||
AL_API void AL_APIENTRY alSource3i64SOFT(ALuint source, ALenum param, ALint64SOFT value1, ALint64SOFT value2, ALint64SOFT value3);
|
||||
AL_API void AL_APIENTRY alSourcei64vSOFT(ALuint source, ALenum param, const ALint64SOFT *values);
|
||||
AL_API void AL_APIENTRY alGetSourcei64SOFT(ALuint source, ALenum param, ALint64SOFT *value);
|
||||
AL_API void AL_APIENTRY alGetSource3i64SOFT(ALuint source, ALenum param, ALint64SOFT *value1, ALint64SOFT *value2, ALint64SOFT *value3);
|
||||
AL_API void AL_APIENTRY alGetSourcei64vSOFT(ALuint source, ALenum param, ALint64SOFT *values);
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,3 @@
|
||||
/* The tokens that would be defined here are already defined in efx.h. This
|
||||
* empty file is here to provide compatibility with Windows-based projects
|
||||
* that would include it. */
|
||||
@@ -0,0 +1,402 @@
|
||||
/* Reverb presets for EFX */
|
||||
|
||||
#ifndef EFX_PRESETS_H
|
||||
#define EFX_PRESETS_H
|
||||
|
||||
#ifndef EFXEAXREVERBPROPERTIES_DEFINED
|
||||
#define EFXEAXREVERBPROPERTIES_DEFINED
|
||||
typedef struct {
|
||||
float flDensity;
|
||||
float flDiffusion;
|
||||
float flGain;
|
||||
float flGainHF;
|
||||
float flGainLF;
|
||||
float flDecayTime;
|
||||
float flDecayHFRatio;
|
||||
float flDecayLFRatio;
|
||||
float flReflectionsGain;
|
||||
float flReflectionsDelay;
|
||||
float flReflectionsPan[3];
|
||||
float flLateReverbGain;
|
||||
float flLateReverbDelay;
|
||||
float flLateReverbPan[3];
|
||||
float flEchoTime;
|
||||
float flEchoDepth;
|
||||
float flModulationTime;
|
||||
float flModulationDepth;
|
||||
float flAirAbsorptionGainHF;
|
||||
float flHFReference;
|
||||
float flLFReference;
|
||||
float flRoomRolloffFactor;
|
||||
int iDecayHFLimit;
|
||||
} EFXEAXREVERBPROPERTIES, *LPEFXEAXREVERBPROPERTIES;
|
||||
#endif
|
||||
|
||||
/* Default Presets */
|
||||
|
||||
#define EFX_REVERB_PRESET_GENERIC \
|
||||
{ 1.0000f, 1.0000f, 0.3162f, 0.8913f, 1.0000f, 1.4900f, 0.8300f, 1.0000f, 0.0500f, 0.0070f, { 0.0000f, 0.0000f, 0.0000f }, 1.2589f, 0.0110f, { 0.0000f, 0.0000f, 0.0000f }, 0.2500f, 0.0000f, 0.2500f, 0.0000f, 0.9943f, 5000.0000f, 250.0000f, 0.0000f, 0x1 }
|
||||
|
||||
#define EFX_REVERB_PRESET_PADDEDCELL \
|
||||
{ 0.1715f, 1.0000f, 0.3162f, 0.0010f, 1.0000f, 0.1700f, 0.1000f, 1.0000f, 0.2500f, 0.0010f, { 0.0000f, 0.0000f, 0.0000f }, 1.2691f, 0.0020f, { 0.0000f, 0.0000f, 0.0000f }, 0.2500f, 0.0000f, 0.2500f, 0.0000f, 0.9943f, 5000.0000f, 250.0000f, 0.0000f, 0x1 }
|
||||
|
||||
#define EFX_REVERB_PRESET_ROOM \
|
||||
{ 0.4287f, 1.0000f, 0.3162f, 0.5929f, 1.0000f, 0.4000f, 0.8300f, 1.0000f, 0.1503f, 0.0020f, { 0.0000f, 0.0000f, 0.0000f }, 1.0629f, 0.0030f, { 0.0000f, 0.0000f, 0.0000f }, 0.2500f, 0.0000f, 0.2500f, 0.0000f, 0.9943f, 5000.0000f, 250.0000f, 0.0000f, 0x1 }
|
||||
|
||||
#define EFX_REVERB_PRESET_BATHROOM \
|
||||
{ 0.1715f, 1.0000f, 0.3162f, 0.2512f, 1.0000f, 1.4900f, 0.5400f, 1.0000f, 0.6531f, 0.0070f, { 0.0000f, 0.0000f, 0.0000f }, 3.2734f, 0.0110f, { 0.0000f, 0.0000f, 0.0000f }, 0.2500f, 0.0000f, 0.2500f, 0.0000f, 0.9943f, 5000.0000f, 250.0000f, 0.0000f, 0x1 }
|
||||
|
||||
#define EFX_REVERB_PRESET_LIVINGROOM \
|
||||
{ 0.9766f, 1.0000f, 0.3162f, 0.0010f, 1.0000f, 0.5000f, 0.1000f, 1.0000f, 0.2051f, 0.0030f, { 0.0000f, 0.0000f, 0.0000f }, 0.2805f, 0.0040f, { 0.0000f, 0.0000f, 0.0000f }, 0.2500f, 0.0000f, 0.2500f, 0.0000f, 0.9943f, 5000.0000f, 250.0000f, 0.0000f, 0x1 }
|
||||
|
||||
#define EFX_REVERB_PRESET_STONEROOM \
|
||||
{ 1.0000f, 1.0000f, 0.3162f, 0.7079f, 1.0000f, 2.3100f, 0.6400f, 1.0000f, 0.4411f, 0.0120f, { 0.0000f, 0.0000f, 0.0000f }, 1.1003f, 0.0170f, { 0.0000f, 0.0000f, 0.0000f }, 0.2500f, 0.0000f, 0.2500f, 0.0000f, 0.9943f, 5000.0000f, 250.0000f, 0.0000f, 0x1 }
|
||||
|
||||
#define EFX_REVERB_PRESET_AUDITORIUM \
|
||||
{ 1.0000f, 1.0000f, 0.3162f, 0.5781f, 1.0000f, 4.3200f, 0.5900f, 1.0000f, 0.4032f, 0.0200f, { 0.0000f, 0.0000f, 0.0000f }, 0.7170f, 0.0300f, { 0.0000f, 0.0000f, 0.0000f }, 0.2500f, 0.0000f, 0.2500f, 0.0000f, 0.9943f, 5000.0000f, 250.0000f, 0.0000f, 0x1 }
|
||||
|
||||
#define EFX_REVERB_PRESET_CONCERTHALL \
|
||||
{ 1.0000f, 1.0000f, 0.3162f, 0.5623f, 1.0000f, 3.9200f, 0.7000f, 1.0000f, 0.2427f, 0.0200f, { 0.0000f, 0.0000f, 0.0000f }, 0.9977f, 0.0290f, { 0.0000f, 0.0000f, 0.0000f }, 0.2500f, 0.0000f, 0.2500f, 0.0000f, 0.9943f, 5000.0000f, 250.0000f, 0.0000f, 0x1 }
|
||||
|
||||
#define EFX_REVERB_PRESET_CAVE \
|
||||
{ 1.0000f, 1.0000f, 0.3162f, 1.0000f, 1.0000f, 2.9100f, 1.3000f, 1.0000f, 0.5000f, 0.0150f, { 0.0000f, 0.0000f, 0.0000f }, 0.7063f, 0.0220f, { 0.0000f, 0.0000f, 0.0000f }, 0.2500f, 0.0000f, 0.2500f, 0.0000f, 0.9943f, 5000.0000f, 250.0000f, 0.0000f, 0x0 }
|
||||
|
||||
#define EFX_REVERB_PRESET_ARENA \
|
||||
{ 1.0000f, 1.0000f, 0.3162f, 0.4477f, 1.0000f, 7.2400f, 0.3300f, 1.0000f, 0.2612f, 0.0200f, { 0.0000f, 0.0000f, 0.0000f }, 1.0186f, 0.0300f, { 0.0000f, 0.0000f, 0.0000f }, 0.2500f, 0.0000f, 0.2500f, 0.0000f, 0.9943f, 5000.0000f, 250.0000f, 0.0000f, 0x1 }
|
||||
|
||||
#define EFX_REVERB_PRESET_HANGAR \
|
||||
{ 1.0000f, 1.0000f, 0.3162f, 0.3162f, 1.0000f, 10.0500f, 0.2300f, 1.0000f, 0.5000f, 0.0200f, { 0.0000f, 0.0000f, 0.0000f }, 1.2560f, 0.0300f, { 0.0000f, 0.0000f, 0.0000f }, 0.2500f, 0.0000f, 0.2500f, 0.0000f, 0.9943f, 5000.0000f, 250.0000f, 0.0000f, 0x1 }
|
||||
|
||||
#define EFX_REVERB_PRESET_CARPETEDHALLWAY \
|
||||
{ 0.4287f, 1.0000f, 0.3162f, 0.0100f, 1.0000f, 0.3000f, 0.1000f, 1.0000f, 0.1215f, 0.0020f, { 0.0000f, 0.0000f, 0.0000f }, 0.1531f, 0.0300f, { 0.0000f, 0.0000f, 0.0000f }, 0.2500f, 0.0000f, 0.2500f, 0.0000f, 0.9943f, 5000.0000f, 250.0000f, 0.0000f, 0x1 }
|
||||
|
||||
#define EFX_REVERB_PRESET_HALLWAY \
|
||||
{ 0.3645f, 1.0000f, 0.3162f, 0.7079f, 1.0000f, 1.4900f, 0.5900f, 1.0000f, 0.2458f, 0.0070f, { 0.0000f, 0.0000f, 0.0000f }, 1.6615f, 0.0110f, { 0.0000f, 0.0000f, 0.0000f }, 0.2500f, 0.0000f, 0.2500f, 0.0000f, 0.9943f, 5000.0000f, 250.0000f, 0.0000f, 0x1 }
|
||||
|
||||
#define EFX_REVERB_PRESET_STONECORRIDOR \
|
||||
{ 1.0000f, 1.0000f, 0.3162f, 0.7612f, 1.0000f, 2.7000f, 0.7900f, 1.0000f, 0.2472f, 0.0130f, { 0.0000f, 0.0000f, 0.0000f }, 1.5758f, 0.0200f, { 0.0000f, 0.0000f, 0.0000f }, 0.2500f, 0.0000f, 0.2500f, 0.0000f, 0.9943f, 5000.0000f, 250.0000f, 0.0000f, 0x1 }
|
||||
|
||||
#define EFX_REVERB_PRESET_ALLEY \
|
||||
{ 1.0000f, 0.3000f, 0.3162f, 0.7328f, 1.0000f, 1.4900f, 0.8600f, 1.0000f, 0.2500f, 0.0070f, { 0.0000f, 0.0000f, 0.0000f }, 0.9954f, 0.0110f, { 0.0000f, 0.0000f, 0.0000f }, 0.1250f, 0.9500f, 0.2500f, 0.0000f, 0.9943f, 5000.0000f, 250.0000f, 0.0000f, 0x1 }
|
||||
|
||||
#define EFX_REVERB_PRESET_FOREST \
|
||||
{ 1.0000f, 0.3000f, 0.3162f, 0.0224f, 1.0000f, 1.4900f, 0.5400f, 1.0000f, 0.0525f, 0.1620f, { 0.0000f, 0.0000f, 0.0000f }, 0.7682f, 0.0880f, { 0.0000f, 0.0000f, 0.0000f }, 0.1250f, 1.0000f, 0.2500f, 0.0000f, 0.9943f, 5000.0000f, 250.0000f, 0.0000f, 0x1 }
|
||||
|
||||
#define EFX_REVERB_PRESET_CITY \
|
||||
{ 1.0000f, 0.5000f, 0.3162f, 0.3981f, 1.0000f, 1.4900f, 0.6700f, 1.0000f, 0.0730f, 0.0070f, { 0.0000f, 0.0000f, 0.0000f }, 0.1427f, 0.0110f, { 0.0000f, 0.0000f, 0.0000f }, 0.2500f, 0.0000f, 0.2500f, 0.0000f, 0.9943f, 5000.0000f, 250.0000f, 0.0000f, 0x1 }
|
||||
|
||||
#define EFX_REVERB_PRESET_MOUNTAINS \
|
||||
{ 1.0000f, 0.2700f, 0.3162f, 0.0562f, 1.0000f, 1.4900f, 0.2100f, 1.0000f, 0.0407f, 0.3000f, { 0.0000f, 0.0000f, 0.0000f }, 0.1919f, 0.1000f, { 0.0000f, 0.0000f, 0.0000f }, 0.2500f, 1.0000f, 0.2500f, 0.0000f, 0.9943f, 5000.0000f, 250.0000f, 0.0000f, 0x0 }
|
||||
|
||||
#define EFX_REVERB_PRESET_QUARRY \
|
||||
{ 1.0000f, 1.0000f, 0.3162f, 0.3162f, 1.0000f, 1.4900f, 0.8300f, 1.0000f, 0.0000f, 0.0610f, { 0.0000f, 0.0000f, 0.0000f }, 1.7783f, 0.0250f, { 0.0000f, 0.0000f, 0.0000f }, 0.1250f, 0.7000f, 0.2500f, 0.0000f, 0.9943f, 5000.0000f, 250.0000f, 0.0000f, 0x1 }
|
||||
|
||||
#define EFX_REVERB_PRESET_PLAIN \
|
||||
{ 1.0000f, 0.2100f, 0.3162f, 0.1000f, 1.0000f, 1.4900f, 0.5000f, 1.0000f, 0.0585f, 0.1790f, { 0.0000f, 0.0000f, 0.0000f }, 0.1089f, 0.1000f, { 0.0000f, 0.0000f, 0.0000f }, 0.2500f, 1.0000f, 0.2500f, 0.0000f, 0.9943f, 5000.0000f, 250.0000f, 0.0000f, 0x1 }
|
||||
|
||||
#define EFX_REVERB_PRESET_PARKINGLOT \
|
||||
{ 1.0000f, 1.0000f, 0.3162f, 1.0000f, 1.0000f, 1.6500f, 1.5000f, 1.0000f, 0.2082f, 0.0080f, { 0.0000f, 0.0000f, 0.0000f }, 0.2652f, 0.0120f, { 0.0000f, 0.0000f, 0.0000f }, 0.2500f, 0.0000f, 0.2500f, 0.0000f, 0.9943f, 5000.0000f, 250.0000f, 0.0000f, 0x0 }
|
||||
|
||||
#define EFX_REVERB_PRESET_SEWERPIPE \
|
||||
{ 0.3071f, 0.8000f, 0.3162f, 0.3162f, 1.0000f, 2.8100f, 0.1400f, 1.0000f, 1.6387f, 0.0140f, { 0.0000f, 0.0000f, 0.0000f }, 3.2471f, 0.0210f, { 0.0000f, 0.0000f, 0.0000f }, 0.2500f, 0.0000f, 0.2500f, 0.0000f, 0.9943f, 5000.0000f, 250.0000f, 0.0000f, 0x1 }
|
||||
|
||||
#define EFX_REVERB_PRESET_UNDERWATER \
|
||||
{ 0.3645f, 1.0000f, 0.3162f, 0.0100f, 1.0000f, 1.4900f, 0.1000f, 1.0000f, 0.5963f, 0.0070f, { 0.0000f, 0.0000f, 0.0000f }, 7.0795f, 0.0110f, { 0.0000f, 0.0000f, 0.0000f }, 0.2500f, 0.0000f, 1.1800f, 0.3480f, 0.9943f, 5000.0000f, 250.0000f, 0.0000f, 0x1 }
|
||||
|
||||
#define EFX_REVERB_PRESET_DRUGGED \
|
||||
{ 0.4287f, 0.5000f, 0.3162f, 1.0000f, 1.0000f, 8.3900f, 1.3900f, 1.0000f, 0.8760f, 0.0020f, { 0.0000f, 0.0000f, 0.0000f }, 3.1081f, 0.0300f, { 0.0000f, 0.0000f, 0.0000f }, 0.2500f, 0.0000f, 0.2500f, 1.0000f, 0.9943f, 5000.0000f, 250.0000f, 0.0000f, 0x0 }
|
||||
|
||||
#define EFX_REVERB_PRESET_DIZZY \
|
||||
{ 0.3645f, 0.6000f, 0.3162f, 0.6310f, 1.0000f, 17.2300f, 0.5600f, 1.0000f, 0.1392f, 0.0200f, { 0.0000f, 0.0000f, 0.0000f }, 0.4937f, 0.0300f, { 0.0000f, 0.0000f, 0.0000f }, 0.2500f, 1.0000f, 0.8100f, 0.3100f, 0.9943f, 5000.0000f, 250.0000f, 0.0000f, 0x0 }
|
||||
|
||||
#define EFX_REVERB_PRESET_PSYCHOTIC \
|
||||
{ 0.0625f, 0.5000f, 0.3162f, 0.8404f, 1.0000f, 7.5600f, 0.9100f, 1.0000f, 0.4864f, 0.0200f, { 0.0000f, 0.0000f, 0.0000f }, 2.4378f, 0.0300f, { 0.0000f, 0.0000f, 0.0000f }, 0.2500f, 0.0000f, 4.0000f, 1.0000f, 0.9943f, 5000.0000f, 250.0000f, 0.0000f, 0x0 }
|
||||
|
||||
/* Castle Presets */
|
||||
|
||||
#define EFX_REVERB_PRESET_CASTLE_SMALLROOM \
|
||||
{ 1.0000f, 0.8900f, 0.3162f, 0.3981f, 0.1000f, 1.2200f, 0.8300f, 0.3100f, 0.8913f, 0.0220f, { 0.0000f, 0.0000f, 0.0000f }, 1.9953f, 0.0110f, { 0.0000f, 0.0000f, 0.0000f }, 0.1380f, 0.0800f, 0.2500f, 0.0000f, 0.9943f, 5168.6001f, 139.5000f, 0.0000f, 0x1 }
|
||||
|
||||
#define EFX_REVERB_PRESET_CASTLE_SHORTPASSAGE \
|
||||
{ 1.0000f, 0.8900f, 0.3162f, 0.3162f, 0.1000f, 2.3200f, 0.8300f, 0.3100f, 0.8913f, 0.0070f, { 0.0000f, 0.0000f, 0.0000f }, 1.2589f, 0.0230f, { 0.0000f, 0.0000f, 0.0000f }, 0.1380f, 0.0800f, 0.2500f, 0.0000f, 0.9943f, 5168.6001f, 139.5000f, 0.0000f, 0x1 }
|
||||
|
||||
#define EFX_REVERB_PRESET_CASTLE_MEDIUMROOM \
|
||||
{ 1.0000f, 0.9300f, 0.3162f, 0.2818f, 0.1000f, 2.0400f, 0.8300f, 0.4600f, 0.6310f, 0.0220f, { 0.0000f, 0.0000f, 0.0000f }, 1.5849f, 0.0110f, { 0.0000f, 0.0000f, 0.0000f }, 0.1550f, 0.0300f, 0.2500f, 0.0000f, 0.9943f, 5168.6001f, 139.5000f, 0.0000f, 0x1 }
|
||||
|
||||
#define EFX_REVERB_PRESET_CASTLE_LARGEROOM \
|
||||
{ 1.0000f, 0.8200f, 0.3162f, 0.2818f, 0.1259f, 2.5300f, 0.8300f, 0.5000f, 0.4467f, 0.0340f, { 0.0000f, 0.0000f, 0.0000f }, 1.2589f, 0.0160f, { 0.0000f, 0.0000f, 0.0000f }, 0.1850f, 0.0700f, 0.2500f, 0.0000f, 0.9943f, 5168.6001f, 139.5000f, 0.0000f, 0x1 }
|
||||
|
||||
#define EFX_REVERB_PRESET_CASTLE_LONGPASSAGE \
|
||||
{ 1.0000f, 0.8900f, 0.3162f, 0.3981f, 0.1000f, 3.4200f, 0.8300f, 0.3100f, 0.8913f, 0.0070f, { 0.0000f, 0.0000f, 0.0000f }, 1.4125f, 0.0230f, { 0.0000f, 0.0000f, 0.0000f }, 0.1380f, 0.0800f, 0.2500f, 0.0000f, 0.9943f, 5168.6001f, 139.5000f, 0.0000f, 0x1 }
|
||||
|
||||
#define EFX_REVERB_PRESET_CASTLE_HALL \
|
||||
{ 1.0000f, 0.8100f, 0.3162f, 0.2818f, 0.1778f, 3.1400f, 0.7900f, 0.6200f, 0.1778f, 0.0560f, { 0.0000f, 0.0000f, 0.0000f }, 1.1220f, 0.0240f, { 0.0000f, 0.0000f, 0.0000f }, 0.2500f, 0.0000f, 0.2500f, 0.0000f, 0.9943f, 5168.6001f, 139.5000f, 0.0000f, 0x1 }
|
||||
|
||||
#define EFX_REVERB_PRESET_CASTLE_CUPBOARD \
|
||||
{ 1.0000f, 0.8900f, 0.3162f, 0.2818f, 0.1000f, 0.6700f, 0.8700f, 0.3100f, 1.4125f, 0.0100f, { 0.0000f, 0.0000f, 0.0000f }, 3.5481f, 0.0070f, { 0.0000f, 0.0000f, 0.0000f }, 0.1380f, 0.0800f, 0.2500f, 0.0000f, 0.9943f, 5168.6001f, 139.5000f, 0.0000f, 0x1 }
|
||||
|
||||
#define EFX_REVERB_PRESET_CASTLE_COURTYARD \
|
||||
{ 1.0000f, 0.4200f, 0.3162f, 0.4467f, 0.1995f, 2.1300f, 0.6100f, 0.2300f, 0.2239f, 0.1600f, { 0.0000f, 0.0000f, 0.0000f }, 0.7079f, 0.0360f, { 0.0000f, 0.0000f, 0.0000f }, 0.2500f, 0.3700f, 0.2500f, 0.0000f, 0.9943f, 5000.0000f, 250.0000f, 0.0000f, 0x0 }
|
||||
|
||||
#define EFX_REVERB_PRESET_CASTLE_ALCOVE \
|
||||
{ 1.0000f, 0.8900f, 0.3162f, 0.5012f, 0.1000f, 1.6400f, 0.8700f, 0.3100f, 1.0000f, 0.0070f, { 0.0000f, 0.0000f, 0.0000f }, 1.4125f, 0.0340f, { 0.0000f, 0.0000f, 0.0000f }, 0.1380f, 0.0800f, 0.2500f, 0.0000f, 0.9943f, 5168.6001f, 139.5000f, 0.0000f, 0x1 }
|
||||
|
||||
/* Factory Presets */
|
||||
|
||||
#define EFX_REVERB_PRESET_FACTORY_SMALLROOM \
|
||||
{ 0.3645f, 0.8200f, 0.3162f, 0.7943f, 0.5012f, 1.7200f, 0.6500f, 1.3100f, 0.7079f, 0.0100f, { 0.0000f, 0.0000f, 0.0000f }, 1.7783f, 0.0240f, { 0.0000f, 0.0000f, 0.0000f }, 0.1190f, 0.0700f, 0.2500f, 0.0000f, 0.9943f, 3762.6001f, 362.5000f, 0.0000f, 0x1 }
|
||||
|
||||
#define EFX_REVERB_PRESET_FACTORY_SHORTPASSAGE \
|
||||
{ 0.3645f, 0.6400f, 0.2512f, 0.7943f, 0.5012f, 2.5300f, 0.6500f, 1.3100f, 1.0000f, 0.0100f, { 0.0000f, 0.0000f, 0.0000f }, 1.2589f, 0.0380f, { 0.0000f, 0.0000f, 0.0000f }, 0.1350f, 0.2300f, 0.2500f, 0.0000f, 0.9943f, 3762.6001f, 362.5000f, 0.0000f, 0x1 }
|
||||
|
||||
#define EFX_REVERB_PRESET_FACTORY_MEDIUMROOM \
|
||||
{ 0.4287f, 0.8200f, 0.2512f, 0.7943f, 0.5012f, 2.7600f, 0.6500f, 1.3100f, 0.2818f, 0.0220f, { 0.0000f, 0.0000f, 0.0000f }, 1.4125f, 0.0230f, { 0.0000f, 0.0000f, 0.0000f }, 0.1740f, 0.0700f, 0.2500f, 0.0000f, 0.9943f, 3762.6001f, 362.5000f, 0.0000f, 0x1 }
|
||||
|
||||
#define EFX_REVERB_PRESET_FACTORY_LARGEROOM \
|
||||
{ 0.4287f, 0.7500f, 0.2512f, 0.7079f, 0.6310f, 4.2400f, 0.5100f, 1.3100f, 0.1778f, 0.0390f, { 0.0000f, 0.0000f, 0.0000f }, 1.1220f, 0.0230f, { 0.0000f, 0.0000f, 0.0000f }, 0.2310f, 0.0700f, 0.2500f, 0.0000f, 0.9943f, 3762.6001f, 362.5000f, 0.0000f, 0x1 }
|
||||
|
||||
#define EFX_REVERB_PRESET_FACTORY_LONGPASSAGE \
|
||||
{ 0.3645f, 0.6400f, 0.2512f, 0.7943f, 0.5012f, 4.0600f, 0.6500f, 1.3100f, 1.0000f, 0.0200f, { 0.0000f, 0.0000f, 0.0000f }, 1.2589f, 0.0370f, { 0.0000f, 0.0000f, 0.0000f }, 0.1350f, 0.2300f, 0.2500f, 0.0000f, 0.9943f, 3762.6001f, 362.5000f, 0.0000f, 0x1 }
|
||||
|
||||
#define EFX_REVERB_PRESET_FACTORY_HALL \
|
||||
{ 0.4287f, 0.7500f, 0.3162f, 0.7079f, 0.6310f, 7.4300f, 0.5100f, 1.3100f, 0.0631f, 0.0730f, { 0.0000f, 0.0000f, 0.0000f }, 0.8913f, 0.0270f, { 0.0000f, 0.0000f, 0.0000f }, 0.2500f, 0.0700f, 0.2500f, 0.0000f, 0.9943f, 3762.6001f, 362.5000f, 0.0000f, 0x1 }
|
||||
|
||||
#define EFX_REVERB_PRESET_FACTORY_CUPBOARD \
|
||||
{ 0.3071f, 0.6300f, 0.2512f, 0.7943f, 0.5012f, 0.4900f, 0.6500f, 1.3100f, 1.2589f, 0.0100f, { 0.0000f, 0.0000f, 0.0000f }, 1.9953f, 0.0320f, { 0.0000f, 0.0000f, 0.0000f }, 0.1070f, 0.0700f, 0.2500f, 0.0000f, 0.9943f, 3762.6001f, 362.5000f, 0.0000f, 0x1 }
|
||||
|
||||
#define EFX_REVERB_PRESET_FACTORY_COURTYARD \
|
||||
{ 0.3071f, 0.5700f, 0.3162f, 0.3162f, 0.6310f, 2.3200f, 0.2900f, 0.5600f, 0.2239f, 0.1400f, { 0.0000f, 0.0000f, 0.0000f }, 0.3981f, 0.0390f, { 0.0000f, 0.0000f, 0.0000f }, 0.2500f, 0.2900f, 0.2500f, 0.0000f, 0.9943f, 3762.6001f, 362.5000f, 0.0000f, 0x1 }
|
||||
|
||||
#define EFX_REVERB_PRESET_FACTORY_ALCOVE \
|
||||
{ 0.3645f, 0.5900f, 0.2512f, 0.7943f, 0.5012f, 3.1400f, 0.6500f, 1.3100f, 1.4125f, 0.0100f, { 0.0000f, 0.0000f, 0.0000f }, 1.0000f, 0.0380f, { 0.0000f, 0.0000f, 0.0000f }, 0.1140f, 0.1000f, 0.2500f, 0.0000f, 0.9943f, 3762.6001f, 362.5000f, 0.0000f, 0x1 }
|
||||
|
||||
/* Ice Palace Presets */
|
||||
|
||||
#define EFX_REVERB_PRESET_ICEPALACE_SMALLROOM \
|
||||
{ 1.0000f, 0.8400f, 0.3162f, 0.5623f, 0.2818f, 1.5100f, 1.5300f, 0.2700f, 0.8913f, 0.0100f, { 0.0000f, 0.0000f, 0.0000f }, 1.4125f, 0.0110f, { 0.0000f, 0.0000f, 0.0000f }, 0.1640f, 0.1400f, 0.2500f, 0.0000f, 0.9943f, 12428.5000f, 99.6000f, 0.0000f, 0x1 }
|
||||
|
||||
#define EFX_REVERB_PRESET_ICEPALACE_SHORTPASSAGE \
|
||||
{ 1.0000f, 0.7500f, 0.3162f, 0.5623f, 0.2818f, 1.7900f, 1.4600f, 0.2800f, 0.5012f, 0.0100f, { 0.0000f, 0.0000f, 0.0000f }, 1.1220f, 0.0190f, { 0.0000f, 0.0000f, 0.0000f }, 0.1770f, 0.0900f, 0.2500f, 0.0000f, 0.9943f, 12428.5000f, 99.6000f, 0.0000f, 0x1 }
|
||||
|
||||
#define EFX_REVERB_PRESET_ICEPALACE_MEDIUMROOM \
|
||||
{ 1.0000f, 0.8700f, 0.3162f, 0.5623f, 0.4467f, 2.2200f, 1.5300f, 0.3200f, 0.3981f, 0.0390f, { 0.0000f, 0.0000f, 0.0000f }, 1.1220f, 0.0270f, { 0.0000f, 0.0000f, 0.0000f }, 0.1860f, 0.1200f, 0.2500f, 0.0000f, 0.9943f, 12428.5000f, 99.6000f, 0.0000f, 0x1 }
|
||||
|
||||
#define EFX_REVERB_PRESET_ICEPALACE_LARGEROOM \
|
||||
{ 1.0000f, 0.8100f, 0.3162f, 0.5623f, 0.4467f, 3.1400f, 1.5300f, 0.3200f, 0.2512f, 0.0390f, { 0.0000f, 0.0000f, 0.0000f }, 1.0000f, 0.0270f, { 0.0000f, 0.0000f, 0.0000f }, 0.2140f, 0.1100f, 0.2500f, 0.0000f, 0.9943f, 12428.5000f, 99.6000f, 0.0000f, 0x1 }
|
||||
|
||||
#define EFX_REVERB_PRESET_ICEPALACE_LONGPASSAGE \
|
||||
{ 1.0000f, 0.7700f, 0.3162f, 0.5623f, 0.3981f, 3.0100f, 1.4600f, 0.2800f, 0.7943f, 0.0120f, { 0.0000f, 0.0000f, 0.0000f }, 1.2589f, 0.0250f, { 0.0000f, 0.0000f, 0.0000f }, 0.1860f, 0.0400f, 0.2500f, 0.0000f, 0.9943f, 12428.5000f, 99.6000f, 0.0000f, 0x1 }
|
||||
|
||||
#define EFX_REVERB_PRESET_ICEPALACE_HALL \
|
||||
{ 1.0000f, 0.7600f, 0.3162f, 0.4467f, 0.5623f, 5.4900f, 1.5300f, 0.3800f, 0.1122f, 0.0540f, { 0.0000f, 0.0000f, 0.0000f }, 0.6310f, 0.0520f, { 0.0000f, 0.0000f, 0.0000f }, 0.2260f, 0.1100f, 0.2500f, 0.0000f, 0.9943f, 12428.5000f, 99.6000f, 0.0000f, 0x1 }
|
||||
|
||||
#define EFX_REVERB_PRESET_ICEPALACE_CUPBOARD \
|
||||
{ 1.0000f, 0.8300f, 0.3162f, 0.5012f, 0.2239f, 0.7600f, 1.5300f, 0.2600f, 1.1220f, 0.0120f, { 0.0000f, 0.0000f, 0.0000f }, 1.9953f, 0.0160f, { 0.0000f, 0.0000f, 0.0000f }, 0.1430f, 0.0800f, 0.2500f, 0.0000f, 0.9943f, 12428.5000f, 99.6000f, 0.0000f, 0x1 }
|
||||
|
||||
#define EFX_REVERB_PRESET_ICEPALACE_COURTYARD \
|
||||
{ 1.0000f, 0.5900f, 0.3162f, 0.2818f, 0.3162f, 2.0400f, 1.2000f, 0.3800f, 0.3162f, 0.1730f, { 0.0000f, 0.0000f, 0.0000f }, 0.3162f, 0.0430f, { 0.0000f, 0.0000f, 0.0000f }, 0.2350f, 0.4800f, 0.2500f, 0.0000f, 0.9943f, 12428.5000f, 99.6000f, 0.0000f, 0x1 }
|
||||
|
||||
#define EFX_REVERB_PRESET_ICEPALACE_ALCOVE \
|
||||
{ 1.0000f, 0.8400f, 0.3162f, 0.5623f, 0.2818f, 2.7600f, 1.4600f, 0.2800f, 1.1220f, 0.0100f, { 0.0000f, 0.0000f, 0.0000f }, 0.8913f, 0.0300f, { 0.0000f, 0.0000f, 0.0000f }, 0.1610f, 0.0900f, 0.2500f, 0.0000f, 0.9943f, 12428.5000f, 99.6000f, 0.0000f, 0x1 }
|
||||
|
||||
/* Space Station Presets */
|
||||
|
||||
#define EFX_REVERB_PRESET_SPACESTATION_SMALLROOM \
|
||||
{ 0.2109f, 0.7000f, 0.3162f, 0.7079f, 0.8913f, 1.7200f, 0.8200f, 0.5500f, 0.7943f, 0.0070f, { 0.0000f, 0.0000f, 0.0000f }, 1.4125f, 0.0130f, { 0.0000f, 0.0000f, 0.0000f }, 0.1880f, 0.2600f, 0.2500f, 0.0000f, 0.9943f, 3316.1001f, 458.2000f, 0.0000f, 0x1 }
|
||||
|
||||
#define EFX_REVERB_PRESET_SPACESTATION_SHORTPASSAGE \
|
||||
{ 0.2109f, 0.8700f, 0.3162f, 0.6310f, 0.8913f, 3.5700f, 0.5000f, 0.5500f, 1.0000f, 0.0120f, { 0.0000f, 0.0000f, 0.0000f }, 1.1220f, 0.0160f, { 0.0000f, 0.0000f, 0.0000f }, 0.1720f, 0.2000f, 0.2500f, 0.0000f, 0.9943f, 3316.1001f, 458.2000f, 0.0000f, 0x1 }
|
||||
|
||||
#define EFX_REVERB_PRESET_SPACESTATION_MEDIUMROOM \
|
||||
{ 0.2109f, 0.7500f, 0.3162f, 0.6310f, 0.8913f, 3.0100f, 0.5000f, 0.5500f, 0.3981f, 0.0340f, { 0.0000f, 0.0000f, 0.0000f }, 1.1220f, 0.0350f, { 0.0000f, 0.0000f, 0.0000f }, 0.2090f, 0.3100f, 0.2500f, 0.0000f, 0.9943f, 3316.1001f, 458.2000f, 0.0000f, 0x1 }
|
||||
|
||||
#define EFX_REVERB_PRESET_SPACESTATION_LARGEROOM \
|
||||
{ 0.3645f, 0.8100f, 0.3162f, 0.6310f, 0.8913f, 3.8900f, 0.3800f, 0.6100f, 0.3162f, 0.0560f, { 0.0000f, 0.0000f, 0.0000f }, 0.8913f, 0.0350f, { 0.0000f, 0.0000f, 0.0000f }, 0.2330f, 0.2800f, 0.2500f, 0.0000f, 0.9943f, 3316.1001f, 458.2000f, 0.0000f, 0x1 }
|
||||
|
||||
#define EFX_REVERB_PRESET_SPACESTATION_LONGPASSAGE \
|
||||
{ 0.4287f, 0.8200f, 0.3162f, 0.6310f, 0.8913f, 4.6200f, 0.6200f, 0.5500f, 1.0000f, 0.0120f, { 0.0000f, 0.0000f, 0.0000f }, 1.2589f, 0.0310f, { 0.0000f, 0.0000f, 0.0000f }, 0.2500f, 0.2300f, 0.2500f, 0.0000f, 0.9943f, 3316.1001f, 458.2000f, 0.0000f, 0x1 }
|
||||
|
||||
#define EFX_REVERB_PRESET_SPACESTATION_HALL \
|
||||
{ 0.4287f, 0.8700f, 0.3162f, 0.6310f, 0.8913f, 7.1100f, 0.3800f, 0.6100f, 0.1778f, 0.1000f, { 0.0000f, 0.0000f, 0.0000f }, 0.6310f, 0.0470f, { 0.0000f, 0.0000f, 0.0000f }, 0.2500f, 0.2500f, 0.2500f, 0.0000f, 0.9943f, 3316.1001f, 458.2000f, 0.0000f, 0x1 }
|
||||
|
||||
#define EFX_REVERB_PRESET_SPACESTATION_CUPBOARD \
|
||||
{ 0.1715f, 0.5600f, 0.3162f, 0.7079f, 0.8913f, 0.7900f, 0.8100f, 0.5500f, 1.4125f, 0.0070f, { 0.0000f, 0.0000f, 0.0000f }, 1.7783f, 0.0180f, { 0.0000f, 0.0000f, 0.0000f }, 0.1810f, 0.3100f, 0.2500f, 0.0000f, 0.9943f, 3316.1001f, 458.2000f, 0.0000f, 0x1 }
|
||||
|
||||
#define EFX_REVERB_PRESET_SPACESTATION_ALCOVE \
|
||||
{ 0.2109f, 0.7800f, 0.3162f, 0.7079f, 0.8913f, 1.1600f, 0.8100f, 0.5500f, 1.4125f, 0.0070f, { 0.0000f, 0.0000f, 0.0000f }, 1.0000f, 0.0180f, { 0.0000f, 0.0000f, 0.0000f }, 0.1920f, 0.2100f, 0.2500f, 0.0000f, 0.9943f, 3316.1001f, 458.2000f, 0.0000f, 0x1 }
|
||||
|
||||
/* Wooden Galleon Presets */
|
||||
|
||||
#define EFX_REVERB_PRESET_WOODEN_SMALLROOM \
|
||||
{ 1.0000f, 1.0000f, 0.3162f, 0.1122f, 0.3162f, 0.7900f, 0.3200f, 0.8700f, 1.0000f, 0.0320f, { 0.0000f, 0.0000f, 0.0000f }, 0.8913f, 0.0290f, { 0.0000f, 0.0000f, 0.0000f }, 0.2500f, 0.0000f, 0.2500f, 0.0000f, 0.9943f, 4705.0000f, 99.6000f, 0.0000f, 0x1 }
|
||||
|
||||
#define EFX_REVERB_PRESET_WOODEN_SHORTPASSAGE \
|
||||
{ 1.0000f, 1.0000f, 0.3162f, 0.1259f, 0.3162f, 1.7500f, 0.5000f, 0.8700f, 0.8913f, 0.0120f, { 0.0000f, 0.0000f, 0.0000f }, 0.6310f, 0.0240f, { 0.0000f, 0.0000f, 0.0000f }, 0.2500f, 0.0000f, 0.2500f, 0.0000f, 0.9943f, 4705.0000f, 99.6000f, 0.0000f, 0x1 }
|
||||
|
||||
#define EFX_REVERB_PRESET_WOODEN_MEDIUMROOM \
|
||||
{ 1.0000f, 1.0000f, 0.3162f, 0.1000f, 0.2818f, 1.4700f, 0.4200f, 0.8200f, 0.8913f, 0.0490f, { 0.0000f, 0.0000f, 0.0000f }, 0.8913f, 0.0290f, { 0.0000f, 0.0000f, 0.0000f }, 0.2500f, 0.0000f, 0.2500f, 0.0000f, 0.9943f, 4705.0000f, 99.6000f, 0.0000f, 0x1 }
|
||||
|
||||
#define EFX_REVERB_PRESET_WOODEN_LARGEROOM \
|
||||
{ 1.0000f, 1.0000f, 0.3162f, 0.0891f, 0.2818f, 2.6500f, 0.3300f, 0.8200f, 0.8913f, 0.0660f, { 0.0000f, 0.0000f, 0.0000f }, 0.7943f, 0.0490f, { 0.0000f, 0.0000f, 0.0000f }, 0.2500f, 0.0000f, 0.2500f, 0.0000f, 0.9943f, 4705.0000f, 99.6000f, 0.0000f, 0x1 }
|
||||
|
||||
#define EFX_REVERB_PRESET_WOODEN_LONGPASSAGE \
|
||||
{ 1.0000f, 1.0000f, 0.3162f, 0.1000f, 0.3162f, 1.9900f, 0.4000f, 0.7900f, 1.0000f, 0.0200f, { 0.0000f, 0.0000f, 0.0000f }, 0.4467f, 0.0360f, { 0.0000f, 0.0000f, 0.0000f }, 0.2500f, 0.0000f, 0.2500f, 0.0000f, 0.9943f, 4705.0000f, 99.6000f, 0.0000f, 0x1 }
|
||||
|
||||
#define EFX_REVERB_PRESET_WOODEN_HALL \
|
||||
{ 1.0000f, 1.0000f, 0.3162f, 0.0794f, 0.2818f, 3.4500f, 0.3000f, 0.8200f, 0.8913f, 0.0880f, { 0.0000f, 0.0000f, 0.0000f }, 0.7943f, 0.0630f, { 0.0000f, 0.0000f, 0.0000f }, 0.2500f, 0.0000f, 0.2500f, 0.0000f, 0.9943f, 4705.0000f, 99.6000f, 0.0000f, 0x1 }
|
||||
|
||||
#define EFX_REVERB_PRESET_WOODEN_CUPBOARD \
|
||||
{ 1.0000f, 1.0000f, 0.3162f, 0.1413f, 0.3162f, 0.5600f, 0.4600f, 0.9100f, 1.1220f, 0.0120f, { 0.0000f, 0.0000f, 0.0000f }, 1.1220f, 0.0280f, { 0.0000f, 0.0000f, 0.0000f }, 0.2500f, 0.0000f, 0.2500f, 0.0000f, 0.9943f, 4705.0000f, 99.6000f, 0.0000f, 0x1 }
|
||||
|
||||
#define EFX_REVERB_PRESET_WOODEN_COURTYARD \
|
||||
{ 1.0000f, 0.6500f, 0.3162f, 0.0794f, 0.3162f, 1.7900f, 0.3500f, 0.7900f, 0.5623f, 0.1230f, { 0.0000f, 0.0000f, 0.0000f }, 0.1000f, 0.0320f, { 0.0000f, 0.0000f, 0.0000f }, 0.2500f, 0.0000f, 0.2500f, 0.0000f, 0.9943f, 4705.0000f, 99.6000f, 0.0000f, 0x1 }
|
||||
|
||||
#define EFX_REVERB_PRESET_WOODEN_ALCOVE \
|
||||
{ 1.0000f, 1.0000f, 0.3162f, 0.1259f, 0.3162f, 1.2200f, 0.6200f, 0.9100f, 1.1220f, 0.0120f, { 0.0000f, 0.0000f, 0.0000f }, 0.7079f, 0.0240f, { 0.0000f, 0.0000f, 0.0000f }, 0.2500f, 0.0000f, 0.2500f, 0.0000f, 0.9943f, 4705.0000f, 99.6000f, 0.0000f, 0x1 }
|
||||
|
||||
/* Sports Presets */
|
||||
|
||||
#define EFX_REVERB_PRESET_SPORT_EMPTYSTADIUM \
|
||||
{ 1.0000f, 1.0000f, 0.3162f, 0.4467f, 0.7943f, 6.2600f, 0.5100f, 1.1000f, 0.0631f, 0.1830f, { 0.0000f, 0.0000f, 0.0000f }, 0.3981f, 0.0380f, { 0.0000f, 0.0000f, 0.0000f }, 0.2500f, 0.0000f, 0.2500f, 0.0000f, 0.9943f, 5000.0000f, 250.0000f, 0.0000f, 0x1 }
|
||||
|
||||
#define EFX_REVERB_PRESET_SPORT_SQUASHCOURT \
|
||||
{ 1.0000f, 0.7500f, 0.3162f, 0.3162f, 0.7943f, 2.2200f, 0.9100f, 1.1600f, 0.4467f, 0.0070f, { 0.0000f, 0.0000f, 0.0000f }, 0.7943f, 0.0110f, { 0.0000f, 0.0000f, 0.0000f }, 0.1260f, 0.1900f, 0.2500f, 0.0000f, 0.9943f, 7176.8999f, 211.2000f, 0.0000f, 0x1 }
|
||||
|
||||
#define EFX_REVERB_PRESET_SPORT_SMALLSWIMMINGPOOL \
|
||||
{ 1.0000f, 0.7000f, 0.3162f, 0.7943f, 0.8913f, 2.7600f, 1.2500f, 1.1400f, 0.6310f, 0.0200f, { 0.0000f, 0.0000f, 0.0000f }, 0.7943f, 0.0300f, { 0.0000f, 0.0000f, 0.0000f }, 0.1790f, 0.1500f, 0.8950f, 0.1900f, 0.9943f, 5000.0000f, 250.0000f, 0.0000f, 0x0 }
|
||||
|
||||
#define EFX_REVERB_PRESET_SPORT_LARGESWIMMINGPOOL \
|
||||
{ 1.0000f, 0.8200f, 0.3162f, 0.7943f, 1.0000f, 5.4900f, 1.3100f, 1.1400f, 0.4467f, 0.0390f, { 0.0000f, 0.0000f, 0.0000f }, 0.5012f, 0.0490f, { 0.0000f, 0.0000f, 0.0000f }, 0.2220f, 0.5500f, 1.1590f, 0.2100f, 0.9943f, 5000.0000f, 250.0000f, 0.0000f, 0x0 }
|
||||
|
||||
#define EFX_REVERB_PRESET_SPORT_GYMNASIUM \
|
||||
{ 1.0000f, 0.8100f, 0.3162f, 0.4467f, 0.8913f, 3.1400f, 1.0600f, 1.3500f, 0.3981f, 0.0290f, { 0.0000f, 0.0000f, 0.0000f }, 0.5623f, 0.0450f, { 0.0000f, 0.0000f, 0.0000f }, 0.1460f, 0.1400f, 0.2500f, 0.0000f, 0.9943f, 7176.8999f, 211.2000f, 0.0000f, 0x1 }
|
||||
|
||||
#define EFX_REVERB_PRESET_SPORT_FULLSTADIUM \
|
||||
{ 1.0000f, 1.0000f, 0.3162f, 0.0708f, 0.7943f, 5.2500f, 0.1700f, 0.8000f, 0.1000f, 0.1880f, { 0.0000f, 0.0000f, 0.0000f }, 0.2818f, 0.0380f, { 0.0000f, 0.0000f, 0.0000f }, 0.2500f, 0.0000f, 0.2500f, 0.0000f, 0.9943f, 5000.0000f, 250.0000f, 0.0000f, 0x1 }
|
||||
|
||||
#define EFX_REVERB_PRESET_SPORT_STADIUMTANNOY \
|
||||
{ 1.0000f, 0.7800f, 0.3162f, 0.5623f, 0.5012f, 2.5300f, 0.8800f, 0.6800f, 0.2818f, 0.2300f, { 0.0000f, 0.0000f, 0.0000f }, 0.5012f, 0.0630f, { 0.0000f, 0.0000f, 0.0000f }, 0.2500f, 0.2000f, 0.2500f, 0.0000f, 0.9943f, 5000.0000f, 250.0000f, 0.0000f, 0x1 }
|
||||
|
||||
/* Prefab Presets */
|
||||
|
||||
#define EFX_REVERB_PRESET_PREFAB_WORKSHOP \
|
||||
{ 0.4287f, 1.0000f, 0.3162f, 0.1413f, 0.3981f, 0.7600f, 1.0000f, 1.0000f, 1.0000f, 0.0120f, { 0.0000f, 0.0000f, 0.0000f }, 1.1220f, 0.0120f, { 0.0000f, 0.0000f, 0.0000f }, 0.2500f, 0.0000f, 0.2500f, 0.0000f, 0.9943f, 5000.0000f, 250.0000f, 0.0000f, 0x0 }
|
||||
|
||||
#define EFX_REVERB_PRESET_PREFAB_SCHOOLROOM \
|
||||
{ 0.4022f, 0.6900f, 0.3162f, 0.6310f, 0.5012f, 0.9800f, 0.4500f, 0.1800f, 1.4125f, 0.0170f, { 0.0000f, 0.0000f, 0.0000f }, 1.4125f, 0.0150f, { 0.0000f, 0.0000f, 0.0000f }, 0.0950f, 0.1400f, 0.2500f, 0.0000f, 0.9943f, 7176.8999f, 211.2000f, 0.0000f, 0x1 }
|
||||
|
||||
#define EFX_REVERB_PRESET_PREFAB_PRACTISEROOM \
|
||||
{ 0.4022f, 0.8700f, 0.3162f, 0.3981f, 0.5012f, 1.1200f, 0.5600f, 0.1800f, 1.2589f, 0.0100f, { 0.0000f, 0.0000f, 0.0000f }, 1.4125f, 0.0110f, { 0.0000f, 0.0000f, 0.0000f }, 0.0950f, 0.1400f, 0.2500f, 0.0000f, 0.9943f, 7176.8999f, 211.2000f, 0.0000f, 0x1 }
|
||||
|
||||
#define EFX_REVERB_PRESET_PREFAB_OUTHOUSE \
|
||||
{ 1.0000f, 0.8200f, 0.3162f, 0.1122f, 0.1585f, 1.3800f, 0.3800f, 0.3500f, 0.8913f, 0.0240f, { 0.0000f, 0.0000f, -0.0000f }, 0.6310f, 0.0440f, { 0.0000f, 0.0000f, 0.0000f }, 0.1210f, 0.1700f, 0.2500f, 0.0000f, 0.9943f, 2854.3999f, 107.5000f, 0.0000f, 0x0 }
|
||||
|
||||
#define EFX_REVERB_PRESET_PREFAB_CARAVAN \
|
||||
{ 1.0000f, 1.0000f, 0.3162f, 0.0891f, 0.1259f, 0.4300f, 1.5000f, 1.0000f, 1.0000f, 0.0120f, { 0.0000f, 0.0000f, 0.0000f }, 1.9953f, 0.0120f, { 0.0000f, 0.0000f, 0.0000f }, 0.2500f, 0.0000f, 0.2500f, 0.0000f, 0.9943f, 5000.0000f, 250.0000f, 0.0000f, 0x0 }
|
||||
|
||||
/* Dome and Pipe Presets */
|
||||
|
||||
#define EFX_REVERB_PRESET_DOME_TOMB \
|
||||
{ 1.0000f, 0.7900f, 0.3162f, 0.3548f, 0.2239f, 4.1800f, 0.2100f, 0.1000f, 0.3868f, 0.0300f, { 0.0000f, 0.0000f, 0.0000f }, 1.6788f, 0.0220f, { 0.0000f, 0.0000f, 0.0000f }, 0.1770f, 0.1900f, 0.2500f, 0.0000f, 0.9943f, 2854.3999f, 20.0000f, 0.0000f, 0x0 }
|
||||
|
||||
#define EFX_REVERB_PRESET_PIPE_SMALL \
|
||||
{ 1.0000f, 1.0000f, 0.3162f, 0.3548f, 0.2239f, 5.0400f, 0.1000f, 0.1000f, 0.5012f, 0.0320f, { 0.0000f, 0.0000f, 0.0000f }, 2.5119f, 0.0150f, { 0.0000f, 0.0000f, 0.0000f }, 0.2500f, 0.0000f, 0.2500f, 0.0000f, 0.9943f, 2854.3999f, 20.0000f, 0.0000f, 0x1 }
|
||||
|
||||
#define EFX_REVERB_PRESET_DOME_SAINTPAULS \
|
||||
{ 1.0000f, 0.8700f, 0.3162f, 0.3548f, 0.2239f, 10.4800f, 0.1900f, 0.1000f, 0.1778f, 0.0900f, { 0.0000f, 0.0000f, 0.0000f }, 1.2589f, 0.0420f, { 0.0000f, 0.0000f, 0.0000f }, 0.2500f, 0.1200f, 0.2500f, 0.0000f, 0.9943f, 2854.3999f, 20.0000f, 0.0000f, 0x1 }
|
||||
|
||||
#define EFX_REVERB_PRESET_PIPE_LONGTHIN \
|
||||
{ 0.2560f, 0.9100f, 0.3162f, 0.4467f, 0.2818f, 9.2100f, 0.1800f, 0.1000f, 0.7079f, 0.0100f, { 0.0000f, 0.0000f, 0.0000f }, 0.7079f, 0.0220f, { 0.0000f, 0.0000f, 0.0000f }, 0.2500f, 0.0000f, 0.2500f, 0.0000f, 0.9943f, 2854.3999f, 20.0000f, 0.0000f, 0x0 }
|
||||
|
||||
#define EFX_REVERB_PRESET_PIPE_LARGE \
|
||||
{ 1.0000f, 1.0000f, 0.3162f, 0.3548f, 0.2239f, 8.4500f, 0.1000f, 0.1000f, 0.3981f, 0.0460f, { 0.0000f, 0.0000f, 0.0000f }, 1.5849f, 0.0320f, { 0.0000f, 0.0000f, 0.0000f }, 0.2500f, 0.0000f, 0.2500f, 0.0000f, 0.9943f, 2854.3999f, 20.0000f, 0.0000f, 0x1 }
|
||||
|
||||
#define EFX_REVERB_PRESET_PIPE_RESONANT \
|
||||
{ 0.1373f, 0.9100f, 0.3162f, 0.4467f, 0.2818f, 6.8100f, 0.1800f, 0.1000f, 0.7079f, 0.0100f, { 0.0000f, 0.0000f, 0.0000f }, 1.0000f, 0.0220f, { 0.0000f, 0.0000f, 0.0000f }, 0.2500f, 0.0000f, 0.2500f, 0.0000f, 0.9943f, 2854.3999f, 20.0000f, 0.0000f, 0x0 }
|
||||
|
||||
/* Outdoors Presets */
|
||||
|
||||
#define EFX_REVERB_PRESET_OUTDOORS_BACKYARD \
|
||||
{ 1.0000f, 0.4500f, 0.3162f, 0.2512f, 0.5012f, 1.1200f, 0.3400f, 0.4600f, 0.4467f, 0.0690f, { 0.0000f, 0.0000f, -0.0000f }, 0.7079f, 0.0230f, { 0.0000f, 0.0000f, 0.0000f }, 0.2180f, 0.3400f, 0.2500f, 0.0000f, 0.9943f, 4399.1001f, 242.9000f, 0.0000f, 0x0 }
|
||||
|
||||
#define EFX_REVERB_PRESET_OUTDOORS_ROLLINGPLAINS \
|
||||
{ 1.0000f, 0.0000f, 0.3162f, 0.0112f, 0.6310f, 2.1300f, 0.2100f, 0.4600f, 0.1778f, 0.3000f, { 0.0000f, 0.0000f, -0.0000f }, 0.4467f, 0.0190f, { 0.0000f, 0.0000f, 0.0000f }, 0.2500f, 1.0000f, 0.2500f, 0.0000f, 0.9943f, 4399.1001f, 242.9000f, 0.0000f, 0x0 }
|
||||
|
||||
#define EFX_REVERB_PRESET_OUTDOORS_DEEPCANYON \
|
||||
{ 1.0000f, 0.7400f, 0.3162f, 0.1778f, 0.6310f, 3.8900f, 0.2100f, 0.4600f, 0.3162f, 0.2230f, { 0.0000f, 0.0000f, -0.0000f }, 0.3548f, 0.0190f, { 0.0000f, 0.0000f, 0.0000f }, 0.2500f, 1.0000f, 0.2500f, 0.0000f, 0.9943f, 4399.1001f, 242.9000f, 0.0000f, 0x0 }
|
||||
|
||||
#define EFX_REVERB_PRESET_OUTDOORS_CREEK \
|
||||
{ 1.0000f, 0.3500f, 0.3162f, 0.1778f, 0.5012f, 2.1300f, 0.2100f, 0.4600f, 0.3981f, 0.1150f, { 0.0000f, 0.0000f, -0.0000f }, 0.1995f, 0.0310f, { 0.0000f, 0.0000f, 0.0000f }, 0.2180f, 0.3400f, 0.2500f, 0.0000f, 0.9943f, 4399.1001f, 242.9000f, 0.0000f, 0x0 }
|
||||
|
||||
#define EFX_REVERB_PRESET_OUTDOORS_VALLEY \
|
||||
{ 1.0000f, 0.2800f, 0.3162f, 0.0282f, 0.1585f, 2.8800f, 0.2600f, 0.3500f, 0.1413f, 0.2630f, { 0.0000f, 0.0000f, -0.0000f }, 0.3981f, 0.1000f, { 0.0000f, 0.0000f, 0.0000f }, 0.2500f, 0.3400f, 0.2500f, 0.0000f, 0.9943f, 2854.3999f, 107.5000f, 0.0000f, 0x0 }
|
||||
|
||||
/* Mood Presets */
|
||||
|
||||
#define EFX_REVERB_PRESET_MOOD_HEAVEN \
|
||||
{ 1.0000f, 0.9400f, 0.3162f, 0.7943f, 0.4467f, 5.0400f, 1.1200f, 0.5600f, 0.2427f, 0.0200f, { 0.0000f, 0.0000f, 0.0000f }, 1.2589f, 0.0290f, { 0.0000f, 0.0000f, 0.0000f }, 0.2500f, 0.0800f, 2.7420f, 0.0500f, 0.9977f, 5000.0000f, 250.0000f, 0.0000f, 0x1 }
|
||||
|
||||
#define EFX_REVERB_PRESET_MOOD_HELL \
|
||||
{ 1.0000f, 0.5700f, 0.3162f, 0.3548f, 0.4467f, 3.5700f, 0.4900f, 2.0000f, 0.0000f, 0.0200f, { 0.0000f, 0.0000f, 0.0000f }, 1.4125f, 0.0300f, { 0.0000f, 0.0000f, 0.0000f }, 0.1100f, 0.0400f, 2.1090f, 0.5200f, 0.9943f, 5000.0000f, 139.5000f, 0.0000f, 0x0 }
|
||||
|
||||
#define EFX_REVERB_PRESET_MOOD_MEMORY \
|
||||
{ 1.0000f, 0.8500f, 0.3162f, 0.6310f, 0.3548f, 4.0600f, 0.8200f, 0.5600f, 0.0398f, 0.0000f, { 0.0000f, 0.0000f, 0.0000f }, 1.1220f, 0.0000f, { 0.0000f, 0.0000f, 0.0000f }, 0.2500f, 0.0000f, 0.4740f, 0.4500f, 0.9886f, 5000.0000f, 250.0000f, 0.0000f, 0x0 }
|
||||
|
||||
/* Driving Presets */
|
||||
|
||||
#define EFX_REVERB_PRESET_DRIVING_COMMENTATOR \
|
||||
{ 1.0000f, 0.0000f, 3.1623f, 0.5623f, 0.5012f, 2.4200f, 0.8800f, 0.6800f, 0.1995f, 0.0930f, { 0.0000f, 0.0000f, 0.0000f }, 0.2512f, 0.0170f, { 0.0000f, 0.0000f, 0.0000f }, 0.2500f, 1.0000f, 0.2500f, 0.0000f, 0.9886f, 5000.0000f, 250.0000f, 0.0000f, 0x1 }
|
||||
|
||||
#define EFX_REVERB_PRESET_DRIVING_PITGARAGE \
|
||||
{ 0.4287f, 0.5900f, 0.3162f, 0.7079f, 0.5623f, 1.7200f, 0.9300f, 0.8700f, 0.5623f, 0.0000f, { 0.0000f, 0.0000f, 0.0000f }, 1.2589f, 0.0160f, { 0.0000f, 0.0000f, 0.0000f }, 0.2500f, 0.1100f, 0.2500f, 0.0000f, 0.9943f, 5000.0000f, 250.0000f, 0.0000f, 0x0 }
|
||||
|
||||
#define EFX_REVERB_PRESET_DRIVING_INCAR_RACER \
|
||||
{ 0.0832f, 0.8000f, 0.3162f, 1.0000f, 0.7943f, 0.1700f, 2.0000f, 0.4100f, 1.7783f, 0.0070f, { 0.0000f, 0.0000f, 0.0000f }, 0.7079f, 0.0150f, { 0.0000f, 0.0000f, 0.0000f }, 0.2500f, 0.0000f, 0.2500f, 0.0000f, 0.9943f, 10268.2002f, 251.0000f, 0.0000f, 0x1 }
|
||||
|
||||
#define EFX_REVERB_PRESET_DRIVING_INCAR_SPORTS \
|
||||
{ 0.0832f, 0.8000f, 0.3162f, 0.6310f, 1.0000f, 0.1700f, 0.7500f, 0.4100f, 1.0000f, 0.0100f, { 0.0000f, 0.0000f, 0.0000f }, 0.5623f, 0.0000f, { 0.0000f, 0.0000f, 0.0000f }, 0.2500f, 0.0000f, 0.2500f, 0.0000f, 0.9943f, 10268.2002f, 251.0000f, 0.0000f, 0x1 }
|
||||
|
||||
#define EFX_REVERB_PRESET_DRIVING_INCAR_LUXURY \
|
||||
{ 0.2560f, 1.0000f, 0.3162f, 0.1000f, 0.5012f, 0.1300f, 0.4100f, 0.4600f, 0.7943f, 0.0100f, { 0.0000f, 0.0000f, 0.0000f }, 1.5849f, 0.0100f, { 0.0000f, 0.0000f, 0.0000f }, 0.2500f, 0.0000f, 0.2500f, 0.0000f, 0.9943f, 10268.2002f, 251.0000f, 0.0000f, 0x1 }
|
||||
|
||||
#define EFX_REVERB_PRESET_DRIVING_FULLGRANDSTAND \
|
||||
{ 1.0000f, 1.0000f, 0.3162f, 0.2818f, 0.6310f, 3.0100f, 1.3700f, 1.2800f, 0.3548f, 0.0900f, { 0.0000f, 0.0000f, 0.0000f }, 0.1778f, 0.0490f, { 0.0000f, 0.0000f, 0.0000f }, 0.2500f, 0.0000f, 0.2500f, 0.0000f, 0.9943f, 10420.2002f, 250.0000f, 0.0000f, 0x0 }
|
||||
|
||||
#define EFX_REVERB_PRESET_DRIVING_EMPTYGRANDSTAND \
|
||||
{ 1.0000f, 1.0000f, 0.3162f, 1.0000f, 0.7943f, 4.6200f, 1.7500f, 1.4000f, 0.2082f, 0.0900f, { 0.0000f, 0.0000f, 0.0000f }, 0.2512f, 0.0490f, { 0.0000f, 0.0000f, 0.0000f }, 0.2500f, 0.0000f, 0.2500f, 0.0000f, 0.9943f, 10420.2002f, 250.0000f, 0.0000f, 0x0 }
|
||||
|
||||
#define EFX_REVERB_PRESET_DRIVING_TUNNEL \
|
||||
{ 1.0000f, 0.8100f, 0.3162f, 0.3981f, 0.8913f, 3.4200f, 0.9400f, 1.3100f, 0.7079f, 0.0510f, { 0.0000f, 0.0000f, 0.0000f }, 0.7079f, 0.0470f, { 0.0000f, 0.0000f, 0.0000f }, 0.2140f, 0.0500f, 0.2500f, 0.0000f, 0.9943f, 5000.0000f, 155.3000f, 0.0000f, 0x1 }
|
||||
|
||||
/* City Presets */
|
||||
|
||||
#define EFX_REVERB_PRESET_CITY_STREETS \
|
||||
{ 1.0000f, 0.7800f, 0.3162f, 0.7079f, 0.8913f, 1.7900f, 1.1200f, 0.9100f, 0.2818f, 0.0460f, { 0.0000f, 0.0000f, 0.0000f }, 0.1995f, 0.0280f, { 0.0000f, 0.0000f, 0.0000f }, 0.2500f, 0.2000f, 0.2500f, 0.0000f, 0.9943f, 5000.0000f, 250.0000f, 0.0000f, 0x1 }
|
||||
|
||||
#define EFX_REVERB_PRESET_CITY_SUBWAY \
|
||||
{ 1.0000f, 0.7400f, 0.3162f, 0.7079f, 0.8913f, 3.0100f, 1.2300f, 0.9100f, 0.7079f, 0.0460f, { 0.0000f, 0.0000f, 0.0000f }, 1.2589f, 0.0280f, { 0.0000f, 0.0000f, 0.0000f }, 0.1250f, 0.2100f, 0.2500f, 0.0000f, 0.9943f, 5000.0000f, 250.0000f, 0.0000f, 0x1 }
|
||||
|
||||
#define EFX_REVERB_PRESET_CITY_MUSEUM \
|
||||
{ 1.0000f, 0.8200f, 0.3162f, 0.1778f, 0.1778f, 3.2800f, 1.4000f, 0.5700f, 0.2512f, 0.0390f, { 0.0000f, 0.0000f, -0.0000f }, 0.8913f, 0.0340f, { 0.0000f, 0.0000f, 0.0000f }, 0.1300f, 0.1700f, 0.2500f, 0.0000f, 0.9943f, 2854.3999f, 107.5000f, 0.0000f, 0x0 }
|
||||
|
||||
#define EFX_REVERB_PRESET_CITY_LIBRARY \
|
||||
{ 1.0000f, 0.8200f, 0.3162f, 0.2818f, 0.0891f, 2.7600f, 0.8900f, 0.4100f, 0.3548f, 0.0290f, { 0.0000f, 0.0000f, -0.0000f }, 0.8913f, 0.0200f, { 0.0000f, 0.0000f, 0.0000f }, 0.1300f, 0.1700f, 0.2500f, 0.0000f, 0.9943f, 2854.3999f, 107.5000f, 0.0000f, 0x0 }
|
||||
|
||||
#define EFX_REVERB_PRESET_CITY_UNDERPASS \
|
||||
{ 1.0000f, 0.8200f, 0.3162f, 0.4467f, 0.8913f, 3.5700f, 1.1200f, 0.9100f, 0.3981f, 0.0590f, { 0.0000f, 0.0000f, 0.0000f }, 0.8913f, 0.0370f, { 0.0000f, 0.0000f, 0.0000f }, 0.2500f, 0.1400f, 0.2500f, 0.0000f, 0.9920f, 5000.0000f, 250.0000f, 0.0000f, 0x1 }
|
||||
|
||||
#define EFX_REVERB_PRESET_CITY_ABANDONED \
|
||||
{ 1.0000f, 0.6900f, 0.3162f, 0.7943f, 0.8913f, 3.2800f, 1.1700f, 0.9100f, 0.4467f, 0.0440f, { 0.0000f, 0.0000f, 0.0000f }, 0.2818f, 0.0240f, { 0.0000f, 0.0000f, 0.0000f }, 0.2500f, 0.2000f, 0.2500f, 0.0000f, 0.9966f, 5000.0000f, 250.0000f, 0.0000f, 0x1 }
|
||||
|
||||
/* Misc. Presets */
|
||||
|
||||
#define EFX_REVERB_PRESET_DUSTYROOM \
|
||||
{ 0.3645f, 0.5600f, 0.3162f, 0.7943f, 0.7079f, 1.7900f, 0.3800f, 0.2100f, 0.5012f, 0.0020f, { 0.0000f, 0.0000f, 0.0000f }, 1.2589f, 0.0060f, { 0.0000f, 0.0000f, 0.0000f }, 0.2020f, 0.0500f, 0.2500f, 0.0000f, 0.9886f, 13046.0000f, 163.3000f, 0.0000f, 0x1 }
|
||||
|
||||
#define EFX_REVERB_PRESET_CHAPEL \
|
||||
{ 1.0000f, 0.8400f, 0.3162f, 0.5623f, 1.0000f, 4.6200f, 0.6400f, 1.2300f, 0.4467f, 0.0320f, { 0.0000f, 0.0000f, 0.0000f }, 0.7943f, 0.0490f, { 0.0000f, 0.0000f, 0.0000f }, 0.2500f, 0.0000f, 0.2500f, 0.1100f, 0.9943f, 5000.0000f, 250.0000f, 0.0000f, 0x1 }
|
||||
|
||||
#define EFX_REVERB_PRESET_SMALLWATERROOM \
|
||||
{ 1.0000f, 0.7000f, 0.3162f, 0.4477f, 1.0000f, 1.5100f, 1.2500f, 1.1400f, 0.8913f, 0.0200f, { 0.0000f, 0.0000f, 0.0000f }, 1.4125f, 0.0300f, { 0.0000f, 0.0000f, 0.0000f }, 0.1790f, 0.1500f, 0.8950f, 0.1900f, 0.9920f, 5000.0000f, 250.0000f, 0.0000f, 0x0 }
|
||||
|
||||
#endif /* EFX_PRESETS_H */
|
||||
@@ -0,0 +1,761 @@
|
||||
#ifndef AL_EFX_H
|
||||
#define AL_EFX_H
|
||||
|
||||
|
||||
#include "alc.h"
|
||||
#include "al.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#define ALC_EXT_EFX_NAME "ALC_EXT_EFX"
|
||||
|
||||
#define ALC_EFX_MAJOR_VERSION 0x20001
|
||||
#define ALC_EFX_MINOR_VERSION 0x20002
|
||||
#define ALC_MAX_AUXILIARY_SENDS 0x20003
|
||||
|
||||
|
||||
/* Listener properties. */
|
||||
#define AL_METERS_PER_UNIT 0x20004
|
||||
|
||||
/* Source properties. */
|
||||
#define AL_DIRECT_FILTER 0x20005
|
||||
#define AL_AUXILIARY_SEND_FILTER 0x20006
|
||||
#define AL_AIR_ABSORPTION_FACTOR 0x20007
|
||||
#define AL_ROOM_ROLLOFF_FACTOR 0x20008
|
||||
#define AL_CONE_OUTER_GAINHF 0x20009
|
||||
#define AL_DIRECT_FILTER_GAINHF_AUTO 0x2000A
|
||||
#define AL_AUXILIARY_SEND_FILTER_GAIN_AUTO 0x2000B
|
||||
#define AL_AUXILIARY_SEND_FILTER_GAINHF_AUTO 0x2000C
|
||||
|
||||
|
||||
/* Effect properties. */
|
||||
|
||||
/* Reverb effect parameters */
|
||||
#define AL_REVERB_DENSITY 0x0001
|
||||
#define AL_REVERB_DIFFUSION 0x0002
|
||||
#define AL_REVERB_GAIN 0x0003
|
||||
#define AL_REVERB_GAINHF 0x0004
|
||||
#define AL_REVERB_DECAY_TIME 0x0005
|
||||
#define AL_REVERB_DECAY_HFRATIO 0x0006
|
||||
#define AL_REVERB_REFLECTIONS_GAIN 0x0007
|
||||
#define AL_REVERB_REFLECTIONS_DELAY 0x0008
|
||||
#define AL_REVERB_LATE_REVERB_GAIN 0x0009
|
||||
#define AL_REVERB_LATE_REVERB_DELAY 0x000A
|
||||
#define AL_REVERB_AIR_ABSORPTION_GAINHF 0x000B
|
||||
#define AL_REVERB_ROOM_ROLLOFF_FACTOR 0x000C
|
||||
#define AL_REVERB_DECAY_HFLIMIT 0x000D
|
||||
|
||||
/* EAX Reverb effect parameters */
|
||||
#define AL_EAXREVERB_DENSITY 0x0001
|
||||
#define AL_EAXREVERB_DIFFUSION 0x0002
|
||||
#define AL_EAXREVERB_GAIN 0x0003
|
||||
#define AL_EAXREVERB_GAINHF 0x0004
|
||||
#define AL_EAXREVERB_GAINLF 0x0005
|
||||
#define AL_EAXREVERB_DECAY_TIME 0x0006
|
||||
#define AL_EAXREVERB_DECAY_HFRATIO 0x0007
|
||||
#define AL_EAXREVERB_DECAY_LFRATIO 0x0008
|
||||
#define AL_EAXREVERB_REFLECTIONS_GAIN 0x0009
|
||||
#define AL_EAXREVERB_REFLECTIONS_DELAY 0x000A
|
||||
#define AL_EAXREVERB_REFLECTIONS_PAN 0x000B
|
||||
#define AL_EAXREVERB_LATE_REVERB_GAIN 0x000C
|
||||
#define AL_EAXREVERB_LATE_REVERB_DELAY 0x000D
|
||||
#define AL_EAXREVERB_LATE_REVERB_PAN 0x000E
|
||||
#define AL_EAXREVERB_ECHO_TIME 0x000F
|
||||
#define AL_EAXREVERB_ECHO_DEPTH 0x0010
|
||||
#define AL_EAXREVERB_MODULATION_TIME 0x0011
|
||||
#define AL_EAXREVERB_MODULATION_DEPTH 0x0012
|
||||
#define AL_EAXREVERB_AIR_ABSORPTION_GAINHF 0x0013
|
||||
#define AL_EAXREVERB_HFREFERENCE 0x0014
|
||||
#define AL_EAXREVERB_LFREFERENCE 0x0015
|
||||
#define AL_EAXREVERB_ROOM_ROLLOFF_FACTOR 0x0016
|
||||
#define AL_EAXREVERB_DECAY_HFLIMIT 0x0017
|
||||
|
||||
/* Chorus effect parameters */
|
||||
#define AL_CHORUS_WAVEFORM 0x0001
|
||||
#define AL_CHORUS_PHASE 0x0002
|
||||
#define AL_CHORUS_RATE 0x0003
|
||||
#define AL_CHORUS_DEPTH 0x0004
|
||||
#define AL_CHORUS_FEEDBACK 0x0005
|
||||
#define AL_CHORUS_DELAY 0x0006
|
||||
|
||||
/* Distortion effect parameters */
|
||||
#define AL_DISTORTION_EDGE 0x0001
|
||||
#define AL_DISTORTION_GAIN 0x0002
|
||||
#define AL_DISTORTION_LOWPASS_CUTOFF 0x0003
|
||||
#define AL_DISTORTION_EQCENTER 0x0004
|
||||
#define AL_DISTORTION_EQBANDWIDTH 0x0005
|
||||
|
||||
/* Echo effect parameters */
|
||||
#define AL_ECHO_DELAY 0x0001
|
||||
#define AL_ECHO_LRDELAY 0x0002
|
||||
#define AL_ECHO_DAMPING 0x0003
|
||||
#define AL_ECHO_FEEDBACK 0x0004
|
||||
#define AL_ECHO_SPREAD 0x0005
|
||||
|
||||
/* Flanger effect parameters */
|
||||
#define AL_FLANGER_WAVEFORM 0x0001
|
||||
#define AL_FLANGER_PHASE 0x0002
|
||||
#define AL_FLANGER_RATE 0x0003
|
||||
#define AL_FLANGER_DEPTH 0x0004
|
||||
#define AL_FLANGER_FEEDBACK 0x0005
|
||||
#define AL_FLANGER_DELAY 0x0006
|
||||
|
||||
/* Frequency shifter effect parameters */
|
||||
#define AL_FREQUENCY_SHIFTER_FREQUENCY 0x0001
|
||||
#define AL_FREQUENCY_SHIFTER_LEFT_DIRECTION 0x0002
|
||||
#define AL_FREQUENCY_SHIFTER_RIGHT_DIRECTION 0x0003
|
||||
|
||||
/* Vocal morpher effect parameters */
|
||||
#define AL_VOCAL_MORPHER_PHONEMEA 0x0001
|
||||
#define AL_VOCAL_MORPHER_PHONEMEA_COARSE_TUNING 0x0002
|
||||
#define AL_VOCAL_MORPHER_PHONEMEB 0x0003
|
||||
#define AL_VOCAL_MORPHER_PHONEMEB_COARSE_TUNING 0x0004
|
||||
#define AL_VOCAL_MORPHER_WAVEFORM 0x0005
|
||||
#define AL_VOCAL_MORPHER_RATE 0x0006
|
||||
|
||||
/* Pitchshifter effect parameters */
|
||||
#define AL_PITCH_SHIFTER_COARSE_TUNE 0x0001
|
||||
#define AL_PITCH_SHIFTER_FINE_TUNE 0x0002
|
||||
|
||||
/* Ringmodulator effect parameters */
|
||||
#define AL_RING_MODULATOR_FREQUENCY 0x0001
|
||||
#define AL_RING_MODULATOR_HIGHPASS_CUTOFF 0x0002
|
||||
#define AL_RING_MODULATOR_WAVEFORM 0x0003
|
||||
|
||||
/* Autowah effect parameters */
|
||||
#define AL_AUTOWAH_ATTACK_TIME 0x0001
|
||||
#define AL_AUTOWAH_RELEASE_TIME 0x0002
|
||||
#define AL_AUTOWAH_RESONANCE 0x0003
|
||||
#define AL_AUTOWAH_PEAK_GAIN 0x0004
|
||||
|
||||
/* Compressor effect parameters */
|
||||
#define AL_COMPRESSOR_ONOFF 0x0001
|
||||
|
||||
/* Equalizer effect parameters */
|
||||
#define AL_EQUALIZER_LOW_GAIN 0x0001
|
||||
#define AL_EQUALIZER_LOW_CUTOFF 0x0002
|
||||
#define AL_EQUALIZER_MID1_GAIN 0x0003
|
||||
#define AL_EQUALIZER_MID1_CENTER 0x0004
|
||||
#define AL_EQUALIZER_MID1_WIDTH 0x0005
|
||||
#define AL_EQUALIZER_MID2_GAIN 0x0006
|
||||
#define AL_EQUALIZER_MID2_CENTER 0x0007
|
||||
#define AL_EQUALIZER_MID2_WIDTH 0x0008
|
||||
#define AL_EQUALIZER_HIGH_GAIN 0x0009
|
||||
#define AL_EQUALIZER_HIGH_CUTOFF 0x000A
|
||||
|
||||
/* Effect type */
|
||||
#define AL_EFFECT_FIRST_PARAMETER 0x0000
|
||||
#define AL_EFFECT_LAST_PARAMETER 0x8000
|
||||
#define AL_EFFECT_TYPE 0x8001
|
||||
|
||||
/* Effect types, used with the AL_EFFECT_TYPE property */
|
||||
#define AL_EFFECT_NULL 0x0000
|
||||
#define AL_EFFECT_REVERB 0x0001
|
||||
#define AL_EFFECT_CHORUS 0x0002
|
||||
#define AL_EFFECT_DISTORTION 0x0003
|
||||
#define AL_EFFECT_ECHO 0x0004
|
||||
#define AL_EFFECT_FLANGER 0x0005
|
||||
#define AL_EFFECT_FREQUENCY_SHIFTER 0x0006
|
||||
#define AL_EFFECT_VOCAL_MORPHER 0x0007
|
||||
#define AL_EFFECT_PITCH_SHIFTER 0x0008
|
||||
#define AL_EFFECT_RING_MODULATOR 0x0009
|
||||
#define AL_EFFECT_AUTOWAH 0x000A
|
||||
#define AL_EFFECT_COMPRESSOR 0x000B
|
||||
#define AL_EFFECT_EQUALIZER 0x000C
|
||||
#define AL_EFFECT_EAXREVERB 0x8000
|
||||
|
||||
/* Auxiliary Effect Slot properties. */
|
||||
#define AL_EFFECTSLOT_EFFECT 0x0001
|
||||
#define AL_EFFECTSLOT_GAIN 0x0002
|
||||
#define AL_EFFECTSLOT_AUXILIARY_SEND_AUTO 0x0003
|
||||
|
||||
/* NULL Auxiliary Slot ID to disable a source send. */
|
||||
#define AL_EFFECTSLOT_NULL 0x0000
|
||||
|
||||
|
||||
/* Filter properties. */
|
||||
|
||||
/* Lowpass filter parameters */
|
||||
#define AL_LOWPASS_GAIN 0x0001
|
||||
#define AL_LOWPASS_GAINHF 0x0002
|
||||
|
||||
/* Highpass filter parameters */
|
||||
#define AL_HIGHPASS_GAIN 0x0001
|
||||
#define AL_HIGHPASS_GAINLF 0x0002
|
||||
|
||||
/* Bandpass filter parameters */
|
||||
#define AL_BANDPASS_GAIN 0x0001
|
||||
#define AL_BANDPASS_GAINLF 0x0002
|
||||
#define AL_BANDPASS_GAINHF 0x0003
|
||||
|
||||
/* Filter type */
|
||||
#define AL_FILTER_FIRST_PARAMETER 0x0000
|
||||
#define AL_FILTER_LAST_PARAMETER 0x8000
|
||||
#define AL_FILTER_TYPE 0x8001
|
||||
|
||||
/* Filter types, used with the AL_FILTER_TYPE property */
|
||||
#define AL_FILTER_NULL 0x0000
|
||||
#define AL_FILTER_LOWPASS 0x0001
|
||||
#define AL_FILTER_HIGHPASS 0x0002
|
||||
#define AL_FILTER_BANDPASS 0x0003
|
||||
|
||||
|
||||
/* Effect object function types. */
|
||||
typedef void (AL_APIENTRY *LPALGENEFFECTS)(ALsizei, ALuint*);
|
||||
typedef void (AL_APIENTRY *LPALDELETEEFFECTS)(ALsizei, const ALuint*);
|
||||
typedef ALboolean (AL_APIENTRY *LPALISEFFECT)(ALuint);
|
||||
typedef void (AL_APIENTRY *LPALEFFECTI)(ALuint, ALenum, ALint);
|
||||
typedef void (AL_APIENTRY *LPALEFFECTIV)(ALuint, ALenum, const ALint*);
|
||||
typedef void (AL_APIENTRY *LPALEFFECTF)(ALuint, ALenum, ALfloat);
|
||||
typedef void (AL_APIENTRY *LPALEFFECTFV)(ALuint, ALenum, const ALfloat*);
|
||||
typedef void (AL_APIENTRY *LPALGETEFFECTI)(ALuint, ALenum, ALint*);
|
||||
typedef void (AL_APIENTRY *LPALGETEFFECTIV)(ALuint, ALenum, ALint*);
|
||||
typedef void (AL_APIENTRY *LPALGETEFFECTF)(ALuint, ALenum, ALfloat*);
|
||||
typedef void (AL_APIENTRY *LPALGETEFFECTFV)(ALuint, ALenum, ALfloat*);
|
||||
|
||||
/* Filter object function types. */
|
||||
typedef void (AL_APIENTRY *LPALGENFILTERS)(ALsizei, ALuint*);
|
||||
typedef void (AL_APIENTRY *LPALDELETEFILTERS)(ALsizei, const ALuint*);
|
||||
typedef ALboolean (AL_APIENTRY *LPALISFILTER)(ALuint);
|
||||
typedef void (AL_APIENTRY *LPALFILTERI)(ALuint, ALenum, ALint);
|
||||
typedef void (AL_APIENTRY *LPALFILTERIV)(ALuint, ALenum, const ALint*);
|
||||
typedef void (AL_APIENTRY *LPALFILTERF)(ALuint, ALenum, ALfloat);
|
||||
typedef void (AL_APIENTRY *LPALFILTERFV)(ALuint, ALenum, const ALfloat*);
|
||||
typedef void (AL_APIENTRY *LPALGETFILTERI)(ALuint, ALenum, ALint*);
|
||||
typedef void (AL_APIENTRY *LPALGETFILTERIV)(ALuint, ALenum, ALint*);
|
||||
typedef void (AL_APIENTRY *LPALGETFILTERF)(ALuint, ALenum, ALfloat*);
|
||||
typedef void (AL_APIENTRY *LPALGETFILTERFV)(ALuint, ALenum, ALfloat*);
|
||||
|
||||
/* Auxiliary Effect Slot object function types. */
|
||||
typedef void (AL_APIENTRY *LPALGENAUXILIARYEFFECTSLOTS)(ALsizei, ALuint*);
|
||||
typedef void (AL_APIENTRY *LPALDELETEAUXILIARYEFFECTSLOTS)(ALsizei, const ALuint*);
|
||||
typedef ALboolean (AL_APIENTRY *LPALISAUXILIARYEFFECTSLOT)(ALuint);
|
||||
typedef void (AL_APIENTRY *LPALAUXILIARYEFFECTSLOTI)(ALuint, ALenum, ALint);
|
||||
typedef void (AL_APIENTRY *LPALAUXILIARYEFFECTSLOTIV)(ALuint, ALenum, const ALint*);
|
||||
typedef void (AL_APIENTRY *LPALAUXILIARYEFFECTSLOTF)(ALuint, ALenum, ALfloat);
|
||||
typedef void (AL_APIENTRY *LPALAUXILIARYEFFECTSLOTFV)(ALuint, ALenum, const ALfloat*);
|
||||
typedef void (AL_APIENTRY *LPALGETAUXILIARYEFFECTSLOTI)(ALuint, ALenum, ALint*);
|
||||
typedef void (AL_APIENTRY *LPALGETAUXILIARYEFFECTSLOTIV)(ALuint, ALenum, ALint*);
|
||||
typedef void (AL_APIENTRY *LPALGETAUXILIARYEFFECTSLOTF)(ALuint, ALenum, ALfloat*);
|
||||
typedef void (AL_APIENTRY *LPALGETAUXILIARYEFFECTSLOTFV)(ALuint, ALenum, ALfloat*);
|
||||
|
||||
#ifdef AL_ALEXT_PROTOTYPES
|
||||
AL_API ALvoid AL_APIENTRY alGenEffects(ALsizei n, ALuint *effects);
|
||||
AL_API ALvoid AL_APIENTRY alDeleteEffects(ALsizei n, const ALuint *effects);
|
||||
AL_API ALboolean AL_APIENTRY alIsEffect(ALuint effect);
|
||||
AL_API ALvoid AL_APIENTRY alEffecti(ALuint effect, ALenum param, ALint iValue);
|
||||
AL_API ALvoid AL_APIENTRY alEffectiv(ALuint effect, ALenum param, const ALint *piValues);
|
||||
AL_API ALvoid AL_APIENTRY alEffectf(ALuint effect, ALenum param, ALfloat flValue);
|
||||
AL_API ALvoid AL_APIENTRY alEffectfv(ALuint effect, ALenum param, const ALfloat *pflValues);
|
||||
AL_API ALvoid AL_APIENTRY alGetEffecti(ALuint effect, ALenum param, ALint *piValue);
|
||||
AL_API ALvoid AL_APIENTRY alGetEffectiv(ALuint effect, ALenum param, ALint *piValues);
|
||||
AL_API ALvoid AL_APIENTRY alGetEffectf(ALuint effect, ALenum param, ALfloat *pflValue);
|
||||
AL_API ALvoid AL_APIENTRY alGetEffectfv(ALuint effect, ALenum param, ALfloat *pflValues);
|
||||
|
||||
AL_API ALvoid AL_APIENTRY alGenFilters(ALsizei n, ALuint *filters);
|
||||
AL_API ALvoid AL_APIENTRY alDeleteFilters(ALsizei n, const ALuint *filters);
|
||||
AL_API ALboolean AL_APIENTRY alIsFilter(ALuint filter);
|
||||
AL_API ALvoid AL_APIENTRY alFilteri(ALuint filter, ALenum param, ALint iValue);
|
||||
AL_API ALvoid AL_APIENTRY alFilteriv(ALuint filter, ALenum param, const ALint *piValues);
|
||||
AL_API ALvoid AL_APIENTRY alFilterf(ALuint filter, ALenum param, ALfloat flValue);
|
||||
AL_API ALvoid AL_APIENTRY alFilterfv(ALuint filter, ALenum param, const ALfloat *pflValues);
|
||||
AL_API ALvoid AL_APIENTRY alGetFilteri(ALuint filter, ALenum param, ALint *piValue);
|
||||
AL_API ALvoid AL_APIENTRY alGetFilteriv(ALuint filter, ALenum param, ALint *piValues);
|
||||
AL_API ALvoid AL_APIENTRY alGetFilterf(ALuint filter, ALenum param, ALfloat *pflValue);
|
||||
AL_API ALvoid AL_APIENTRY alGetFilterfv(ALuint filter, ALenum param, ALfloat *pflValues);
|
||||
|
||||
AL_API ALvoid AL_APIENTRY alGenAuxiliaryEffectSlots(ALsizei n, ALuint *effectslots);
|
||||
AL_API ALvoid AL_APIENTRY alDeleteAuxiliaryEffectSlots(ALsizei n, const ALuint *effectslots);
|
||||
AL_API ALboolean AL_APIENTRY alIsAuxiliaryEffectSlot(ALuint effectslot);
|
||||
AL_API ALvoid AL_APIENTRY alAuxiliaryEffectSloti(ALuint effectslot, ALenum param, ALint iValue);
|
||||
AL_API ALvoid AL_APIENTRY alAuxiliaryEffectSlotiv(ALuint effectslot, ALenum param, const ALint *piValues);
|
||||
AL_API ALvoid AL_APIENTRY alAuxiliaryEffectSlotf(ALuint effectslot, ALenum param, ALfloat flValue);
|
||||
AL_API ALvoid AL_APIENTRY alAuxiliaryEffectSlotfv(ALuint effectslot, ALenum param, const ALfloat *pflValues);
|
||||
AL_API ALvoid AL_APIENTRY alGetAuxiliaryEffectSloti(ALuint effectslot, ALenum param, ALint *piValue);
|
||||
AL_API ALvoid AL_APIENTRY alGetAuxiliaryEffectSlotiv(ALuint effectslot, ALenum param, ALint *piValues);
|
||||
AL_API ALvoid AL_APIENTRY alGetAuxiliaryEffectSlotf(ALuint effectslot, ALenum param, ALfloat *pflValue);
|
||||
AL_API ALvoid AL_APIENTRY alGetAuxiliaryEffectSlotfv(ALuint effectslot, ALenum param, ALfloat *pflValues);
|
||||
#endif
|
||||
|
||||
/* Filter ranges and defaults. */
|
||||
|
||||
/* Lowpass filter */
|
||||
#define AL_LOWPASS_MIN_GAIN (0.0f)
|
||||
#define AL_LOWPASS_MAX_GAIN (1.0f)
|
||||
#define AL_LOWPASS_DEFAULT_GAIN (1.0f)
|
||||
|
||||
#define AL_LOWPASS_MIN_GAINHF (0.0f)
|
||||
#define AL_LOWPASS_MAX_GAINHF (1.0f)
|
||||
#define AL_LOWPASS_DEFAULT_GAINHF (1.0f)
|
||||
|
||||
/* Highpass filter */
|
||||
#define AL_HIGHPASS_MIN_GAIN (0.0f)
|
||||
#define AL_HIGHPASS_MAX_GAIN (1.0f)
|
||||
#define AL_HIGHPASS_DEFAULT_GAIN (1.0f)
|
||||
|
||||
#define AL_HIGHPASS_MIN_GAINLF (0.0f)
|
||||
#define AL_HIGHPASS_MAX_GAINLF (1.0f)
|
||||
#define AL_HIGHPASS_DEFAULT_GAINLF (1.0f)
|
||||
|
||||
/* Bandpass filter */
|
||||
#define AL_BANDPASS_MIN_GAIN (0.0f)
|
||||
#define AL_BANDPASS_MAX_GAIN (1.0f)
|
||||
#define AL_BANDPASS_DEFAULT_GAIN (1.0f)
|
||||
|
||||
#define AL_BANDPASS_MIN_GAINHF (0.0f)
|
||||
#define AL_BANDPASS_MAX_GAINHF (1.0f)
|
||||
#define AL_BANDPASS_DEFAULT_GAINHF (1.0f)
|
||||
|
||||
#define AL_BANDPASS_MIN_GAINLF (0.0f)
|
||||
#define AL_BANDPASS_MAX_GAINLF (1.0f)
|
||||
#define AL_BANDPASS_DEFAULT_GAINLF (1.0f)
|
||||
|
||||
|
||||
/* Effect parameter ranges and defaults. */
|
||||
|
||||
/* Standard reverb effect */
|
||||
#define AL_REVERB_MIN_DENSITY (0.0f)
|
||||
#define AL_REVERB_MAX_DENSITY (1.0f)
|
||||
#define AL_REVERB_DEFAULT_DENSITY (1.0f)
|
||||
|
||||
#define AL_REVERB_MIN_DIFFUSION (0.0f)
|
||||
#define AL_REVERB_MAX_DIFFUSION (1.0f)
|
||||
#define AL_REVERB_DEFAULT_DIFFUSION (1.0f)
|
||||
|
||||
#define AL_REVERB_MIN_GAIN (0.0f)
|
||||
#define AL_REVERB_MAX_GAIN (1.0f)
|
||||
#define AL_REVERB_DEFAULT_GAIN (0.32f)
|
||||
|
||||
#define AL_REVERB_MIN_GAINHF (0.0f)
|
||||
#define AL_REVERB_MAX_GAINHF (1.0f)
|
||||
#define AL_REVERB_DEFAULT_GAINHF (0.89f)
|
||||
|
||||
#define AL_REVERB_MIN_DECAY_TIME (0.1f)
|
||||
#define AL_REVERB_MAX_DECAY_TIME (20.0f)
|
||||
#define AL_REVERB_DEFAULT_DECAY_TIME (1.49f)
|
||||
|
||||
#define AL_REVERB_MIN_DECAY_HFRATIO (0.1f)
|
||||
#define AL_REVERB_MAX_DECAY_HFRATIO (2.0f)
|
||||
#define AL_REVERB_DEFAULT_DECAY_HFRATIO (0.83f)
|
||||
|
||||
#define AL_REVERB_MIN_REFLECTIONS_GAIN (0.0f)
|
||||
#define AL_REVERB_MAX_REFLECTIONS_GAIN (3.16f)
|
||||
#define AL_REVERB_DEFAULT_REFLECTIONS_GAIN (0.05f)
|
||||
|
||||
#define AL_REVERB_MIN_REFLECTIONS_DELAY (0.0f)
|
||||
#define AL_REVERB_MAX_REFLECTIONS_DELAY (0.3f)
|
||||
#define AL_REVERB_DEFAULT_REFLECTIONS_DELAY (0.007f)
|
||||
|
||||
#define AL_REVERB_MIN_LATE_REVERB_GAIN (0.0f)
|
||||
#define AL_REVERB_MAX_LATE_REVERB_GAIN (10.0f)
|
||||
#define AL_REVERB_DEFAULT_LATE_REVERB_GAIN (1.26f)
|
||||
|
||||
#define AL_REVERB_MIN_LATE_REVERB_DELAY (0.0f)
|
||||
#define AL_REVERB_MAX_LATE_REVERB_DELAY (0.1f)
|
||||
#define AL_REVERB_DEFAULT_LATE_REVERB_DELAY (0.011f)
|
||||
|
||||
#define AL_REVERB_MIN_AIR_ABSORPTION_GAINHF (0.892f)
|
||||
#define AL_REVERB_MAX_AIR_ABSORPTION_GAINHF (1.0f)
|
||||
#define AL_REVERB_DEFAULT_AIR_ABSORPTION_GAINHF (0.994f)
|
||||
|
||||
#define AL_REVERB_MIN_ROOM_ROLLOFF_FACTOR (0.0f)
|
||||
#define AL_REVERB_MAX_ROOM_ROLLOFF_FACTOR (10.0f)
|
||||
#define AL_REVERB_DEFAULT_ROOM_ROLLOFF_FACTOR (0.0f)
|
||||
|
||||
#define AL_REVERB_MIN_DECAY_HFLIMIT AL_FALSE
|
||||
#define AL_REVERB_MAX_DECAY_HFLIMIT AL_TRUE
|
||||
#define AL_REVERB_DEFAULT_DECAY_HFLIMIT AL_TRUE
|
||||
|
||||
/* EAX reverb effect */
|
||||
#define AL_EAXREVERB_MIN_DENSITY (0.0f)
|
||||
#define AL_EAXREVERB_MAX_DENSITY (1.0f)
|
||||
#define AL_EAXREVERB_DEFAULT_DENSITY (1.0f)
|
||||
|
||||
#define AL_EAXREVERB_MIN_DIFFUSION (0.0f)
|
||||
#define AL_EAXREVERB_MAX_DIFFUSION (1.0f)
|
||||
#define AL_EAXREVERB_DEFAULT_DIFFUSION (1.0f)
|
||||
|
||||
#define AL_EAXREVERB_MIN_GAIN (0.0f)
|
||||
#define AL_EAXREVERB_MAX_GAIN (1.0f)
|
||||
#define AL_EAXREVERB_DEFAULT_GAIN (0.32f)
|
||||
|
||||
#define AL_EAXREVERB_MIN_GAINHF (0.0f)
|
||||
#define AL_EAXREVERB_MAX_GAINHF (1.0f)
|
||||
#define AL_EAXREVERB_DEFAULT_GAINHF (0.89f)
|
||||
|
||||
#define AL_EAXREVERB_MIN_GAINLF (0.0f)
|
||||
#define AL_EAXREVERB_MAX_GAINLF (1.0f)
|
||||
#define AL_EAXREVERB_DEFAULT_GAINLF (1.0f)
|
||||
|
||||
#define AL_EAXREVERB_MIN_DECAY_TIME (0.1f)
|
||||
#define AL_EAXREVERB_MAX_DECAY_TIME (20.0f)
|
||||
#define AL_EAXREVERB_DEFAULT_DECAY_TIME (1.49f)
|
||||
|
||||
#define AL_EAXREVERB_MIN_DECAY_HFRATIO (0.1f)
|
||||
#define AL_EAXREVERB_MAX_DECAY_HFRATIO (2.0f)
|
||||
#define AL_EAXREVERB_DEFAULT_DECAY_HFRATIO (0.83f)
|
||||
|
||||
#define AL_EAXREVERB_MIN_DECAY_LFRATIO (0.1f)
|
||||
#define AL_EAXREVERB_MAX_DECAY_LFRATIO (2.0f)
|
||||
#define AL_EAXREVERB_DEFAULT_DECAY_LFRATIO (1.0f)
|
||||
|
||||
#define AL_EAXREVERB_MIN_REFLECTIONS_GAIN (0.0f)
|
||||
#define AL_EAXREVERB_MAX_REFLECTIONS_GAIN (3.16f)
|
||||
#define AL_EAXREVERB_DEFAULT_REFLECTIONS_GAIN (0.05f)
|
||||
|
||||
#define AL_EAXREVERB_MIN_REFLECTIONS_DELAY (0.0f)
|
||||
#define AL_EAXREVERB_MAX_REFLECTIONS_DELAY (0.3f)
|
||||
#define AL_EAXREVERB_DEFAULT_REFLECTIONS_DELAY (0.007f)
|
||||
|
||||
#define AL_EAXREVERB_DEFAULT_REFLECTIONS_PAN_XYZ (0.0f)
|
||||
|
||||
#define AL_EAXREVERB_MIN_LATE_REVERB_GAIN (0.0f)
|
||||
#define AL_EAXREVERB_MAX_LATE_REVERB_GAIN (10.0f)
|
||||
#define AL_EAXREVERB_DEFAULT_LATE_REVERB_GAIN (1.26f)
|
||||
|
||||
#define AL_EAXREVERB_MIN_LATE_REVERB_DELAY (0.0f)
|
||||
#define AL_EAXREVERB_MAX_LATE_REVERB_DELAY (0.1f)
|
||||
#define AL_EAXREVERB_DEFAULT_LATE_REVERB_DELAY (0.011f)
|
||||
|
||||
#define AL_EAXREVERB_DEFAULT_LATE_REVERB_PAN_XYZ (0.0f)
|
||||
|
||||
#define AL_EAXREVERB_MIN_ECHO_TIME (0.075f)
|
||||
#define AL_EAXREVERB_MAX_ECHO_TIME (0.25f)
|
||||
#define AL_EAXREVERB_DEFAULT_ECHO_TIME (0.25f)
|
||||
|
||||
#define AL_EAXREVERB_MIN_ECHO_DEPTH (0.0f)
|
||||
#define AL_EAXREVERB_MAX_ECHO_DEPTH (1.0f)
|
||||
#define AL_EAXREVERB_DEFAULT_ECHO_DEPTH (0.0f)
|
||||
|
||||
#define AL_EAXREVERB_MIN_MODULATION_TIME (0.04f)
|
||||
#define AL_EAXREVERB_MAX_MODULATION_TIME (4.0f)
|
||||
#define AL_EAXREVERB_DEFAULT_MODULATION_TIME (0.25f)
|
||||
|
||||
#define AL_EAXREVERB_MIN_MODULATION_DEPTH (0.0f)
|
||||
#define AL_EAXREVERB_MAX_MODULATION_DEPTH (1.0f)
|
||||
#define AL_EAXREVERB_DEFAULT_MODULATION_DEPTH (0.0f)
|
||||
|
||||
#define AL_EAXREVERB_MIN_AIR_ABSORPTION_GAINHF (0.892f)
|
||||
#define AL_EAXREVERB_MAX_AIR_ABSORPTION_GAINHF (1.0f)
|
||||
#define AL_EAXREVERB_DEFAULT_AIR_ABSORPTION_GAINHF (0.994f)
|
||||
|
||||
#define AL_EAXREVERB_MIN_HFREFERENCE (1000.0f)
|
||||
#define AL_EAXREVERB_MAX_HFREFERENCE (20000.0f)
|
||||
#define AL_EAXREVERB_DEFAULT_HFREFERENCE (5000.0f)
|
||||
|
||||
#define AL_EAXREVERB_MIN_LFREFERENCE (20.0f)
|
||||
#define AL_EAXREVERB_MAX_LFREFERENCE (1000.0f)
|
||||
#define AL_EAXREVERB_DEFAULT_LFREFERENCE (250.0f)
|
||||
|
||||
#define AL_EAXREVERB_MIN_ROOM_ROLLOFF_FACTOR (0.0f)
|
||||
#define AL_EAXREVERB_MAX_ROOM_ROLLOFF_FACTOR (10.0f)
|
||||
#define AL_EAXREVERB_DEFAULT_ROOM_ROLLOFF_FACTOR (0.0f)
|
||||
|
||||
#define AL_EAXREVERB_MIN_DECAY_HFLIMIT AL_FALSE
|
||||
#define AL_EAXREVERB_MAX_DECAY_HFLIMIT AL_TRUE
|
||||
#define AL_EAXREVERB_DEFAULT_DECAY_HFLIMIT AL_TRUE
|
||||
|
||||
/* Chorus effect */
|
||||
#define AL_CHORUS_WAVEFORM_SINUSOID (0)
|
||||
#define AL_CHORUS_WAVEFORM_TRIANGLE (1)
|
||||
|
||||
#define AL_CHORUS_MIN_WAVEFORM (0)
|
||||
#define AL_CHORUS_MAX_WAVEFORM (1)
|
||||
#define AL_CHORUS_DEFAULT_WAVEFORM (1)
|
||||
|
||||
#define AL_CHORUS_MIN_PHASE (-180)
|
||||
#define AL_CHORUS_MAX_PHASE (180)
|
||||
#define AL_CHORUS_DEFAULT_PHASE (90)
|
||||
|
||||
#define AL_CHORUS_MIN_RATE (0.0f)
|
||||
#define AL_CHORUS_MAX_RATE (10.0f)
|
||||
#define AL_CHORUS_DEFAULT_RATE (1.1f)
|
||||
|
||||
#define AL_CHORUS_MIN_DEPTH (0.0f)
|
||||
#define AL_CHORUS_MAX_DEPTH (1.0f)
|
||||
#define AL_CHORUS_DEFAULT_DEPTH (0.1f)
|
||||
|
||||
#define AL_CHORUS_MIN_FEEDBACK (-1.0f)
|
||||
#define AL_CHORUS_MAX_FEEDBACK (1.0f)
|
||||
#define AL_CHORUS_DEFAULT_FEEDBACK (0.25f)
|
||||
|
||||
#define AL_CHORUS_MIN_DELAY (0.0f)
|
||||
#define AL_CHORUS_MAX_DELAY (0.016f)
|
||||
#define AL_CHORUS_DEFAULT_DELAY (0.016f)
|
||||
|
||||
/* Distortion effect */
|
||||
#define AL_DISTORTION_MIN_EDGE (0.0f)
|
||||
#define AL_DISTORTION_MAX_EDGE (1.0f)
|
||||
#define AL_DISTORTION_DEFAULT_EDGE (0.2f)
|
||||
|
||||
#define AL_DISTORTION_MIN_GAIN (0.01f)
|
||||
#define AL_DISTORTION_MAX_GAIN (1.0f)
|
||||
#define AL_DISTORTION_DEFAULT_GAIN (0.05f)
|
||||
|
||||
#define AL_DISTORTION_MIN_LOWPASS_CUTOFF (80.0f)
|
||||
#define AL_DISTORTION_MAX_LOWPASS_CUTOFF (24000.0f)
|
||||
#define AL_DISTORTION_DEFAULT_LOWPASS_CUTOFF (8000.0f)
|
||||
|
||||
#define AL_DISTORTION_MIN_EQCENTER (80.0f)
|
||||
#define AL_DISTORTION_MAX_EQCENTER (24000.0f)
|
||||
#define AL_DISTORTION_DEFAULT_EQCENTER (3600.0f)
|
||||
|
||||
#define AL_DISTORTION_MIN_EQBANDWIDTH (80.0f)
|
||||
#define AL_DISTORTION_MAX_EQBANDWIDTH (24000.0f)
|
||||
#define AL_DISTORTION_DEFAULT_EQBANDWIDTH (3600.0f)
|
||||
|
||||
/* Echo effect */
|
||||
#define AL_ECHO_MIN_DELAY (0.0f)
|
||||
#define AL_ECHO_MAX_DELAY (0.207f)
|
||||
#define AL_ECHO_DEFAULT_DELAY (0.1f)
|
||||
|
||||
#define AL_ECHO_MIN_LRDELAY (0.0f)
|
||||
#define AL_ECHO_MAX_LRDELAY (0.404f)
|
||||
#define AL_ECHO_DEFAULT_LRDELAY (0.1f)
|
||||
|
||||
#define AL_ECHO_MIN_DAMPING (0.0f)
|
||||
#define AL_ECHO_MAX_DAMPING (0.99f)
|
||||
#define AL_ECHO_DEFAULT_DAMPING (0.5f)
|
||||
|
||||
#define AL_ECHO_MIN_FEEDBACK (0.0f)
|
||||
#define AL_ECHO_MAX_FEEDBACK (1.0f)
|
||||
#define AL_ECHO_DEFAULT_FEEDBACK (0.5f)
|
||||
|
||||
#define AL_ECHO_MIN_SPREAD (-1.0f)
|
||||
#define AL_ECHO_MAX_SPREAD (1.0f)
|
||||
#define AL_ECHO_DEFAULT_SPREAD (-1.0f)
|
||||
|
||||
/* Flanger effect */
|
||||
#define AL_FLANGER_WAVEFORM_SINUSOID (0)
|
||||
#define AL_FLANGER_WAVEFORM_TRIANGLE (1)
|
||||
|
||||
#define AL_FLANGER_MIN_WAVEFORM (0)
|
||||
#define AL_FLANGER_MAX_WAVEFORM (1)
|
||||
#define AL_FLANGER_DEFAULT_WAVEFORM (1)
|
||||
|
||||
#define AL_FLANGER_MIN_PHASE (-180)
|
||||
#define AL_FLANGER_MAX_PHASE (180)
|
||||
#define AL_FLANGER_DEFAULT_PHASE (0)
|
||||
|
||||
#define AL_FLANGER_MIN_RATE (0.0f)
|
||||
#define AL_FLANGER_MAX_RATE (10.0f)
|
||||
#define AL_FLANGER_DEFAULT_RATE (0.27f)
|
||||
|
||||
#define AL_FLANGER_MIN_DEPTH (0.0f)
|
||||
#define AL_FLANGER_MAX_DEPTH (1.0f)
|
||||
#define AL_FLANGER_DEFAULT_DEPTH (1.0f)
|
||||
|
||||
#define AL_FLANGER_MIN_FEEDBACK (-1.0f)
|
||||
#define AL_FLANGER_MAX_FEEDBACK (1.0f)
|
||||
#define AL_FLANGER_DEFAULT_FEEDBACK (-0.5f)
|
||||
|
||||
#define AL_FLANGER_MIN_DELAY (0.0f)
|
||||
#define AL_FLANGER_MAX_DELAY (0.004f)
|
||||
#define AL_FLANGER_DEFAULT_DELAY (0.002f)
|
||||
|
||||
/* Frequency shifter effect */
|
||||
#define AL_FREQUENCY_SHIFTER_MIN_FREQUENCY (0.0f)
|
||||
#define AL_FREQUENCY_SHIFTER_MAX_FREQUENCY (24000.0f)
|
||||
#define AL_FREQUENCY_SHIFTER_DEFAULT_FREQUENCY (0.0f)
|
||||
|
||||
#define AL_FREQUENCY_SHIFTER_MIN_LEFT_DIRECTION (0)
|
||||
#define AL_FREQUENCY_SHIFTER_MAX_LEFT_DIRECTION (2)
|
||||
#define AL_FREQUENCY_SHIFTER_DEFAULT_LEFT_DIRECTION (0)
|
||||
|
||||
#define AL_FREQUENCY_SHIFTER_DIRECTION_DOWN (0)
|
||||
#define AL_FREQUENCY_SHIFTER_DIRECTION_UP (1)
|
||||
#define AL_FREQUENCY_SHIFTER_DIRECTION_OFF (2)
|
||||
|
||||
#define AL_FREQUENCY_SHIFTER_MIN_RIGHT_DIRECTION (0)
|
||||
#define AL_FREQUENCY_SHIFTER_MAX_RIGHT_DIRECTION (2)
|
||||
#define AL_FREQUENCY_SHIFTER_DEFAULT_RIGHT_DIRECTION (0)
|
||||
|
||||
/* Vocal morpher effect */
|
||||
#define AL_VOCAL_MORPHER_MIN_PHONEMEA (0)
|
||||
#define AL_VOCAL_MORPHER_MAX_PHONEMEA (29)
|
||||
#define AL_VOCAL_MORPHER_DEFAULT_PHONEMEA (0)
|
||||
|
||||
#define AL_VOCAL_MORPHER_MIN_PHONEMEA_COARSE_TUNING (-24)
|
||||
#define AL_VOCAL_MORPHER_MAX_PHONEMEA_COARSE_TUNING (24)
|
||||
#define AL_VOCAL_MORPHER_DEFAULT_PHONEMEA_COARSE_TUNING (0)
|
||||
|
||||
#define AL_VOCAL_MORPHER_MIN_PHONEMEB (0)
|
||||
#define AL_VOCAL_MORPHER_MAX_PHONEMEB (29)
|
||||
#define AL_VOCAL_MORPHER_DEFAULT_PHONEMEB (10)
|
||||
|
||||
#define AL_VOCAL_MORPHER_MIN_PHONEMEB_COARSE_TUNING (-24)
|
||||
#define AL_VOCAL_MORPHER_MAX_PHONEMEB_COARSE_TUNING (24)
|
||||
#define AL_VOCAL_MORPHER_DEFAULT_PHONEMEB_COARSE_TUNING (0)
|
||||
|
||||
#define AL_VOCAL_MORPHER_PHONEME_A (0)
|
||||
#define AL_VOCAL_MORPHER_PHONEME_E (1)
|
||||
#define AL_VOCAL_MORPHER_PHONEME_I (2)
|
||||
#define AL_VOCAL_MORPHER_PHONEME_O (3)
|
||||
#define AL_VOCAL_MORPHER_PHONEME_U (4)
|
||||
#define AL_VOCAL_MORPHER_PHONEME_AA (5)
|
||||
#define AL_VOCAL_MORPHER_PHONEME_AE (6)
|
||||
#define AL_VOCAL_MORPHER_PHONEME_AH (7)
|
||||
#define AL_VOCAL_MORPHER_PHONEME_AO (8)
|
||||
#define AL_VOCAL_MORPHER_PHONEME_EH (9)
|
||||
#define AL_VOCAL_MORPHER_PHONEME_ER (10)
|
||||
#define AL_VOCAL_MORPHER_PHONEME_IH (11)
|
||||
#define AL_VOCAL_MORPHER_PHONEME_IY (12)
|
||||
#define AL_VOCAL_MORPHER_PHONEME_UH (13)
|
||||
#define AL_VOCAL_MORPHER_PHONEME_UW (14)
|
||||
#define AL_VOCAL_MORPHER_PHONEME_B (15)
|
||||
#define AL_VOCAL_MORPHER_PHONEME_D (16)
|
||||
#define AL_VOCAL_MORPHER_PHONEME_F (17)
|
||||
#define AL_VOCAL_MORPHER_PHONEME_G (18)
|
||||
#define AL_VOCAL_MORPHER_PHONEME_J (19)
|
||||
#define AL_VOCAL_MORPHER_PHONEME_K (20)
|
||||
#define AL_VOCAL_MORPHER_PHONEME_L (21)
|
||||
#define AL_VOCAL_MORPHER_PHONEME_M (22)
|
||||
#define AL_VOCAL_MORPHER_PHONEME_N (23)
|
||||
#define AL_VOCAL_MORPHER_PHONEME_P (24)
|
||||
#define AL_VOCAL_MORPHER_PHONEME_R (25)
|
||||
#define AL_VOCAL_MORPHER_PHONEME_S (26)
|
||||
#define AL_VOCAL_MORPHER_PHONEME_T (27)
|
||||
#define AL_VOCAL_MORPHER_PHONEME_V (28)
|
||||
#define AL_VOCAL_MORPHER_PHONEME_Z (29)
|
||||
|
||||
#define AL_VOCAL_MORPHER_WAVEFORM_SINUSOID (0)
|
||||
#define AL_VOCAL_MORPHER_WAVEFORM_TRIANGLE (1)
|
||||
#define AL_VOCAL_MORPHER_WAVEFORM_SAWTOOTH (2)
|
||||
|
||||
#define AL_VOCAL_MORPHER_MIN_WAVEFORM (0)
|
||||
#define AL_VOCAL_MORPHER_MAX_WAVEFORM (2)
|
||||
#define AL_VOCAL_MORPHER_DEFAULT_WAVEFORM (0)
|
||||
|
||||
#define AL_VOCAL_MORPHER_MIN_RATE (0.0f)
|
||||
#define AL_VOCAL_MORPHER_MAX_RATE (10.0f)
|
||||
#define AL_VOCAL_MORPHER_DEFAULT_RATE (1.41f)
|
||||
|
||||
/* Pitch shifter effect */
|
||||
#define AL_PITCH_SHIFTER_MIN_COARSE_TUNE (-12)
|
||||
#define AL_PITCH_SHIFTER_MAX_COARSE_TUNE (12)
|
||||
#define AL_PITCH_SHIFTER_DEFAULT_COARSE_TUNE (12)
|
||||
|
||||
#define AL_PITCH_SHIFTER_MIN_FINE_TUNE (-50)
|
||||
#define AL_PITCH_SHIFTER_MAX_FINE_TUNE (50)
|
||||
#define AL_PITCH_SHIFTER_DEFAULT_FINE_TUNE (0)
|
||||
|
||||
/* Ring modulator effect */
|
||||
#define AL_RING_MODULATOR_MIN_FREQUENCY (0.0f)
|
||||
#define AL_RING_MODULATOR_MAX_FREQUENCY (8000.0f)
|
||||
#define AL_RING_MODULATOR_DEFAULT_FREQUENCY (440.0f)
|
||||
|
||||
#define AL_RING_MODULATOR_MIN_HIGHPASS_CUTOFF (0.0f)
|
||||
#define AL_RING_MODULATOR_MAX_HIGHPASS_CUTOFF (24000.0f)
|
||||
#define AL_RING_MODULATOR_DEFAULT_HIGHPASS_CUTOFF (800.0f)
|
||||
|
||||
#define AL_RING_MODULATOR_SINUSOID (0)
|
||||
#define AL_RING_MODULATOR_SAWTOOTH (1)
|
||||
#define AL_RING_MODULATOR_SQUARE (2)
|
||||
|
||||
#define AL_RING_MODULATOR_MIN_WAVEFORM (0)
|
||||
#define AL_RING_MODULATOR_MAX_WAVEFORM (2)
|
||||
#define AL_RING_MODULATOR_DEFAULT_WAVEFORM (0)
|
||||
|
||||
/* Autowah effect */
|
||||
#define AL_AUTOWAH_MIN_ATTACK_TIME (0.0001f)
|
||||
#define AL_AUTOWAH_MAX_ATTACK_TIME (1.0f)
|
||||
#define AL_AUTOWAH_DEFAULT_ATTACK_TIME (0.06f)
|
||||
|
||||
#define AL_AUTOWAH_MIN_RELEASE_TIME (0.0001f)
|
||||
#define AL_AUTOWAH_MAX_RELEASE_TIME (1.0f)
|
||||
#define AL_AUTOWAH_DEFAULT_RELEASE_TIME (0.06f)
|
||||
|
||||
#define AL_AUTOWAH_MIN_RESONANCE (2.0f)
|
||||
#define AL_AUTOWAH_MAX_RESONANCE (1000.0f)
|
||||
#define AL_AUTOWAH_DEFAULT_RESONANCE (1000.0f)
|
||||
|
||||
#define AL_AUTOWAH_MIN_PEAK_GAIN (0.00003f)
|
||||
#define AL_AUTOWAH_MAX_PEAK_GAIN (31621.0f)
|
||||
#define AL_AUTOWAH_DEFAULT_PEAK_GAIN (11.22f)
|
||||
|
||||
/* Compressor effect */
|
||||
#define AL_COMPRESSOR_MIN_ONOFF (0)
|
||||
#define AL_COMPRESSOR_MAX_ONOFF (1)
|
||||
#define AL_COMPRESSOR_DEFAULT_ONOFF (1)
|
||||
|
||||
/* Equalizer effect */
|
||||
#define AL_EQUALIZER_MIN_LOW_GAIN (0.126f)
|
||||
#define AL_EQUALIZER_MAX_LOW_GAIN (7.943f)
|
||||
#define AL_EQUALIZER_DEFAULT_LOW_GAIN (1.0f)
|
||||
|
||||
#define AL_EQUALIZER_MIN_LOW_CUTOFF (50.0f)
|
||||
#define AL_EQUALIZER_MAX_LOW_CUTOFF (800.0f)
|
||||
#define AL_EQUALIZER_DEFAULT_LOW_CUTOFF (200.0f)
|
||||
|
||||
#define AL_EQUALIZER_MIN_MID1_GAIN (0.126f)
|
||||
#define AL_EQUALIZER_MAX_MID1_GAIN (7.943f)
|
||||
#define AL_EQUALIZER_DEFAULT_MID1_GAIN (1.0f)
|
||||
|
||||
#define AL_EQUALIZER_MIN_MID1_CENTER (200.0f)
|
||||
#define AL_EQUALIZER_MAX_MID1_CENTER (3000.0f)
|
||||
#define AL_EQUALIZER_DEFAULT_MID1_CENTER (500.0f)
|
||||
|
||||
#define AL_EQUALIZER_MIN_MID1_WIDTH (0.01f)
|
||||
#define AL_EQUALIZER_MAX_MID1_WIDTH (1.0f)
|
||||
#define AL_EQUALIZER_DEFAULT_MID1_WIDTH (1.0f)
|
||||
|
||||
#define AL_EQUALIZER_MIN_MID2_GAIN (0.126f)
|
||||
#define AL_EQUALIZER_MAX_MID2_GAIN (7.943f)
|
||||
#define AL_EQUALIZER_DEFAULT_MID2_GAIN (1.0f)
|
||||
|
||||
#define AL_EQUALIZER_MIN_MID2_CENTER (1000.0f)
|
||||
#define AL_EQUALIZER_MAX_MID2_CENTER (8000.0f)
|
||||
#define AL_EQUALIZER_DEFAULT_MID2_CENTER (3000.0f)
|
||||
|
||||
#define AL_EQUALIZER_MIN_MID2_WIDTH (0.01f)
|
||||
#define AL_EQUALIZER_MAX_MID2_WIDTH (1.0f)
|
||||
#define AL_EQUALIZER_DEFAULT_MID2_WIDTH (1.0f)
|
||||
|
||||
#define AL_EQUALIZER_MIN_HIGH_GAIN (0.126f)
|
||||
#define AL_EQUALIZER_MAX_HIGH_GAIN (7.943f)
|
||||
#define AL_EQUALIZER_DEFAULT_HIGH_GAIN (1.0f)
|
||||
|
||||
#define AL_EQUALIZER_MIN_HIGH_CUTOFF (4000.0f)
|
||||
#define AL_EQUALIZER_MAX_HIGH_CUTOFF (16000.0f)
|
||||
#define AL_EQUALIZER_DEFAULT_HIGH_CUTOFF (6000.0f)
|
||||
|
||||
|
||||
/* Source parameter value ranges and defaults. */
|
||||
#define AL_MIN_AIR_ABSORPTION_FACTOR (0.0f)
|
||||
#define AL_MAX_AIR_ABSORPTION_FACTOR (10.0f)
|
||||
#define AL_DEFAULT_AIR_ABSORPTION_FACTOR (0.0f)
|
||||
|
||||
#define AL_MIN_ROOM_ROLLOFF_FACTOR (0.0f)
|
||||
#define AL_MAX_ROOM_ROLLOFF_FACTOR (10.0f)
|
||||
#define AL_DEFAULT_ROOM_ROLLOFF_FACTOR (0.0f)
|
||||
|
||||
#define AL_MIN_CONE_OUTER_GAINHF (0.0f)
|
||||
#define AL_MAX_CONE_OUTER_GAINHF (1.0f)
|
||||
#define AL_DEFAULT_CONE_OUTER_GAINHF (1.0f)
|
||||
|
||||
#define AL_MIN_DIRECT_FILTER_GAINHF_AUTO AL_FALSE
|
||||
#define AL_MAX_DIRECT_FILTER_GAINHF_AUTO AL_TRUE
|
||||
#define AL_DEFAULT_DIRECT_FILTER_GAINHF_AUTO AL_TRUE
|
||||
|
||||
#define AL_MIN_AUXILIARY_SEND_FILTER_GAIN_AUTO AL_FALSE
|
||||
#define AL_MAX_AUXILIARY_SEND_FILTER_GAIN_AUTO AL_TRUE
|
||||
#define AL_DEFAULT_AUXILIARY_SEND_FILTER_GAIN_AUTO AL_TRUE
|
||||
|
||||
#define AL_MIN_AUXILIARY_SEND_FILTER_GAINHF_AUTO AL_FALSE
|
||||
#define AL_MAX_AUXILIARY_SEND_FILTER_GAINHF_AUTO AL_TRUE
|
||||
#define AL_DEFAULT_AUXILIARY_SEND_FILTER_GAINHF_AUTO AL_TRUE
|
||||
|
||||
|
||||
/* Listener parameter value ranges and defaults. */
|
||||
#define AL_MIN_METERS_PER_UNIT FLT_MIN
|
||||
#define AL_MAX_METERS_PER_UNIT FLT_MAX
|
||||
#define AL_DEFAULT_METERS_PER_UNIT (1.0f)
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /* extern "C" */
|
||||
#endif
|
||||
|
||||
#endif /* AL_EFX_H */
|
||||
-483
@@ -1,483 +0,0 @@
|
||||
|
||||
GNU LIBRARY GENERAL PUBLIC LICENSE
|
||||
Version 2, June 1991
|
||||
|
||||
Copyright (C) 1991 Free Software Foundation, Inc.
|
||||
675 Mass Ave, Cambridge, MA 02139, USA
|
||||
Everyone is permitted to copy and distribute verbatim copies
|
||||
of this license document, but changing it is not allowed.
|
||||
|
||||
[This is the first released version of the library GPL. It is
|
||||
numbered 2 because it goes with version 2 of the ordinary GPL.]
|
||||
|
||||
Preamble
|
||||
|
||||
The licenses for most software are designed to take away your
|
||||
freedom to share and change it. By contrast, the GNU General Public
|
||||
Licenses are intended to guarantee your freedom to share and change
|
||||
free software--to make sure the software is free for all its users.
|
||||
|
||||
This license, the Library General Public License, applies to some
|
||||
specially designated Free Software Foundation software, and to any
|
||||
other libraries whose authors decide to use it. You can use it for
|
||||
your libraries, too.
|
||||
|
||||
When we speak of free software, we are referring to freedom, not
|
||||
price. Our General Public Licenses are designed to make sure that you
|
||||
have the freedom to distribute copies of free software (and charge for
|
||||
this service if you wish), that you receive source code or can get it
|
||||
if you want it, that you can change the software or use pieces of it
|
||||
in new free programs; and that you know you can do these things.
|
||||
|
||||
To protect your rights, we need to make restrictions that forbid
|
||||
anyone to deny you these rights or to ask you to surrender the rights.
|
||||
These restrictions translate to certain responsibilities for you if
|
||||
you distribute copies of the library, or if you modify it.
|
||||
|
||||
For example, if you distribute copies of the library, whether gratis
|
||||
or for a fee, you must give the recipients all the rights that we gave
|
||||
you. You must make sure that they, too, receive or can get the source
|
||||
code. If you link a program with the library, you must provide
|
||||
complete object files to the recipients so that they can relink them
|
||||
with the library, after making changes to the library and recompiling
|
||||
it. And you must show them these terms so they know their rights.
|
||||
|
||||
Our method of protecting your rights has two steps: (1) copyright
|
||||
the library, and (2) offer you this license which gives you legal
|
||||
permission to copy, distribute and/or modify the library.
|
||||
|
||||
Also, for each distributor's protection, we want to make certain
|
||||
that everyone understands that there is no warranty for this free
|
||||
library. If the library is modified by someone else and passed on, we
|
||||
want its recipients to know that what they have is not the original
|
||||
version, so that any problems introduced by others will not reflect on
|
||||
the original authors' reputations.
|
||||
|
||||
Finally, any free program is threatened constantly by software
|
||||
patents. We wish to avoid the danger that companies distributing free
|
||||
software will individually obtain patent licenses, thus in effect
|
||||
transforming the program into proprietary software. To prevent this,
|
||||
we have made it clear that any patent must be licensed for everyone's
|
||||
free use or not licensed at all.
|
||||
|
||||
Most GNU software, including some libraries, is covered by the ordinary
|
||||
GNU General Public License, which was designed for utility programs. This
|
||||
license, the GNU Library General Public License, applies to certain
|
||||
designated libraries. This license is quite different from the ordinary
|
||||
one; be sure to read it in full, and don't assume that anything in it is
|
||||
the same as in the ordinary license.
|
||||
|
||||
The reason we have a separate public license for some libraries is that
|
||||
they blur the distinction we usually make between modifying or adding to a
|
||||
program and simply using it. Linking a program with a library, without
|
||||
changing the library, is in some sense simply using the library, and is
|
||||
analogous to running a utility program or application program. However, in
|
||||
a textual and legal sense, the linked executable is a combined work, a
|
||||
derivative of the original library, and the ordinary General Public License
|
||||
treats it as such.
|
||||
|
||||
Because of this blurred distinction, using the ordinary General
|
||||
Public License for libraries did not effectively promote software
|
||||
sharing, because most developers did not use the libraries. We
|
||||
concluded that weaker conditions might promote sharing better.
|
||||
|
||||
However, unrestricted linking of non-free programs would deprive the
|
||||
users of those programs of all benefit from the free status of the
|
||||
libraries themselves. This Library General Public License is intended to
|
||||
permit developers of non-free programs to use free libraries, while
|
||||
preserving your freedom as a user of such programs to change the free
|
||||
libraries that are incorporated in them. (We have not seen how to achieve
|
||||
this as regards changes in header files, but we have achieved it as regards
|
||||
changes in the actual functions of the Library.) The hope is that this
|
||||
will lead to faster development of free libraries.
|
||||
|
||||
The precise terms and conditions for copying, distribution and
|
||||
modification follow. Pay close attention to the difference between a
|
||||
"work based on the library" and a "work that uses the library". The
|
||||
former contains code derived from the library, while the latter only
|
||||
works together with the library.
|
||||
|
||||
Note that it is possible for a library to be covered by the ordinary
|
||||
General Public License rather than by this special one.
|
||||
|
||||
GNU LIBRARY GENERAL PUBLIC LICENSE
|
||||
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
|
||||
|
||||
0. This License Agreement applies to any software library which
|
||||
contains a notice placed by the copyright holder or other authorized
|
||||
party saying it may be distributed under the terms of this Library
|
||||
General Public License (also called "this License"). Each licensee is
|
||||
addressed as "you".
|
||||
|
||||
A "library" means a collection of software functions and/or data
|
||||
prepared so as to be conveniently linked with application programs
|
||||
(which use some of those functions and data) to form executables.
|
||||
|
||||
The "Library", below, refers to any such software library or work
|
||||
which has been distributed under these terms. A "work based on the
|
||||
Library" means either the Library or any derivative work under
|
||||
copyright law: that is to say, a work containing the Library or a
|
||||
portion of it, either verbatim or with modifications and/or translated
|
||||
straightforwardly into another language. (Hereinafter, translation is
|
||||
included without limitation in the term "modification".)
|
||||
|
||||
"Source code" for a work means the preferred form of the work for
|
||||
making modifications to it. For a library, complete source code means
|
||||
all the source code for all modules it contains, plus any associated
|
||||
interface definition files, plus the scripts used to control compilation
|
||||
and installation of the library.
|
||||
|
||||
Activities other than copying, distribution and modification are not
|
||||
covered by this License; they are outside its scope. The act of
|
||||
running a program using the Library is not restricted, and output from
|
||||
such a program is covered only if its contents constitute a work based
|
||||
on the Library (independent of the use of the Library in a tool for
|
||||
writing it). Whether that is true depends on what the Library does
|
||||
and what the program that uses the Library does.
|
||||
|
||||
1. You may copy and distribute verbatim copies of the Library's
|
||||
complete source code as you receive it, in any medium, provided that
|
||||
you conspicuously and appropriately publish on each copy an
|
||||
appropriate copyright notice and disclaimer of warranty; keep intact
|
||||
all the notices that refer to this License and to the absence of any
|
||||
warranty; and distribute a copy of this License along with the
|
||||
Library.
|
||||
|
||||
You may charge a fee for the physical act of transferring a copy,
|
||||
and you may at your option offer warranty protection in exchange for a
|
||||
fee.
|
||||
|
||||
2. You may modify your copy or copies of the Library or any portion
|
||||
of it, thus forming a work based on the Library, and copy and
|
||||
distribute such modifications or work under the terms of Section 1
|
||||
above, provided that you also meet all of these conditions:
|
||||
|
||||
a) The modified work must itself be a software library.
|
||||
|
||||
b) You must cause the files modified to carry prominent notices
|
||||
stating that you changed the files and the date of any change.
|
||||
|
||||
c) You must cause the whole of the work to be licensed at no
|
||||
charge to all third parties under the terms of this License.
|
||||
|
||||
d) If a facility in the modified Library refers to a function or a
|
||||
table of data to be supplied by an application program that uses
|
||||
the facility, other than as an argument passed when the facility
|
||||
is invoked, then you must make a good faith effort to ensure that,
|
||||
in the event an application does not supply such function or
|
||||
table, the facility still operates, and performs whatever part of
|
||||
its purpose remains meaningful.
|
||||
|
||||
(For example, a function in a library to compute square roots has
|
||||
a purpose that is entirely well-defined independent of the
|
||||
application. Therefore, Subsection 2d requires that any
|
||||
application-supplied function or table used by this function must
|
||||
be optional: if the application does not supply it, the square
|
||||
root function must still compute square roots.)
|
||||
|
||||
These requirements apply to the modified work as a whole. If
|
||||
identifiable sections of that work are not derived from the Library,
|
||||
and can be reasonably considered independent and separate works in
|
||||
themselves, then this License, and its terms, do not apply to those
|
||||
sections when you distribute them as separate works. But when you
|
||||
distribute the same sections as part of a whole which is a work based
|
||||
on the Library, the distribution of the whole must be on the terms of
|
||||
this License, whose permissions for other licensees extend to the
|
||||
entire whole, and thus to each and every part regardless of who wrote
|
||||
it.
|
||||
|
||||
Thus, it is not the intent of this section to claim rights or contest
|
||||
your rights to work written entirely by you; rather, the intent is to
|
||||
exercise the right to control the distribution of derivative or
|
||||
collective works based on the Library.
|
||||
|
||||
In addition, mere aggregation of another work not based on the Library
|
||||
with the Library (or with a work based on the Library) on a volume of
|
||||
a storage or distribution medium does not bring the other work under
|
||||
the scope of this License.
|
||||
|
||||
3. You may opt to apply the terms of the ordinary GNU General Public
|
||||
License instead of this License to a given copy of the Library. To do
|
||||
this, you must alter all the notices that refer to this License, so
|
||||
that they refer to the ordinary GNU General Public License, version 2,
|
||||
instead of to this License. (If a newer version than version 2 of the
|
||||
ordinary GNU General Public License has appeared, then you can specify
|
||||
that version instead if you wish.) Do not make any other change in
|
||||
these notices.
|
||||
|
||||
Once this change is made in a given copy, it is irreversible for
|
||||
that copy, so the ordinary GNU General Public License applies to all
|
||||
subsequent copies and derivative works made from that copy.
|
||||
|
||||
This option is useful when you wish to copy part of the code of
|
||||
the Library into a program that is not a library.
|
||||
|
||||
4. You may copy and distribute the Library (or a portion or
|
||||
derivative of it, under Section 2) in object code or executable form
|
||||
under the terms of Sections 1 and 2 above provided that you accompany
|
||||
it with the complete corresponding machine-readable source code, which
|
||||
must be distributed under the terms of Sections 1 and 2 above on a
|
||||
medium customarily used for software interchange.
|
||||
|
||||
If distribution of object code is made by offering access to copy
|
||||
from a designated place, then offering equivalent access to copy the
|
||||
source code from the same place satisfies the requirement to
|
||||
distribute the source code, even though third parties are not
|
||||
compelled to copy the source along with the object code.
|
||||
|
||||
5. A program that contains no derivative of any portion of the
|
||||
Library, but is designed to work with the Library by being compiled or
|
||||
linked with it, is called a "work that uses the Library". Such a
|
||||
work, in isolation, is not a derivative work of the Library, and
|
||||
therefore falls outside the scope of this License.
|
||||
|
||||
However, linking a "work that uses the Library" with the Library
|
||||
creates an executable that is a derivative of the Library (because it
|
||||
contains portions of the Library), rather than a "work that uses the
|
||||
library". The executable is therefore covered by this License.
|
||||
Section 6 states terms for distribution of such executables.
|
||||
|
||||
When a "work that uses the Library" uses material from a header file
|
||||
that is part of the Library, the object code for the work may be a
|
||||
derivative work of the Library even though the source code is not.
|
||||
Whether this is true is especially significant if the work can be
|
||||
linked without the Library, or if the work is itself a library. The
|
||||
threshold for this to be true is not precisely defined by law.
|
||||
|
||||
If such an object file uses only numerical parameters, data
|
||||
structure layouts and accessors, and small macros and small inline
|
||||
functions (ten lines or less in length), then the use of the object
|
||||
file is unrestricted, regardless of whether it is legally a derivative
|
||||
work. (Executables containing this object code plus portions of the
|
||||
Library will still fall under Section 6.)
|
||||
|
||||
Otherwise, if the work is a derivative of the Library, you may
|
||||
distribute the object code for the work under the terms of Section 6.
|
||||
Any executables containing that work also fall under Section 6,
|
||||
whether or not they are linked directly with the Library itself.
|
||||
|
||||
6. As an exception to the Sections above, you may also compile or
|
||||
link a "work that uses the Library" with the Library to produce a
|
||||
work containing portions of the Library, and distribute that work
|
||||
under terms of your choice, provided that the terms permit
|
||||
modification of the work for the customer's own use and reverse
|
||||
engineering for debugging such modifications.
|
||||
|
||||
You must give prominent notice with each copy of the work that the
|
||||
Library is used in it and that the Library and its use are covered by
|
||||
this License. You must supply a copy of this License. If the work
|
||||
during execution displays copyright notices, you must include the
|
||||
copyright notice for the Library among them, as well as a reference
|
||||
directing the user to the copy of this License. Also, you must do one
|
||||
of these things:
|
||||
|
||||
a) Accompany the work with the complete corresponding
|
||||
machine-readable source code for the Library including whatever
|
||||
changes were used in the work (which must be distributed under
|
||||
Sections 1 and 2 above); and, if the work is an executable linked
|
||||
with the Library, with the complete machine-readable "work that
|
||||
uses the Library", as object code and/or source code, so that the
|
||||
user can modify the Library and then relink to produce a modified
|
||||
executable containing the modified Library. (It is understood
|
||||
that the user who changes the contents of definitions files in the
|
||||
Library will not necessarily be able to recompile the application
|
||||
to use the modified definitions.)
|
||||
|
||||
b) Accompany the work with a written offer, valid for at
|
||||
least three years, to give the same user the materials
|
||||
specified in Subsection 6a, above, for a charge no more
|
||||
than the cost of performing this distribution.
|
||||
|
||||
c) If distribution of the work is made by offering access to copy
|
||||
from a designated place, offer equivalent access to copy the above
|
||||
specified materials from the same place.
|
||||
|
||||
d) Verify that the user has already received a copy of these
|
||||
materials or that you have already sent this user a copy.
|
||||
|
||||
For an executable, the required form of the "work that uses the
|
||||
Library" must include any data and utility programs needed for
|
||||
reproducing the executable from it. However, as a special exception,
|
||||
the source code distributed need not include anything that is normally
|
||||
distributed (in either source or binary form) with the major
|
||||
components (compiler, kernel, and so on) of the operating system on
|
||||
which the executable runs, unless that component itself accompanies
|
||||
the executable.
|
||||
|
||||
It may happen that this requirement contradicts the license
|
||||
restrictions of other proprietary libraries that do not normally
|
||||
accompany the operating system. Such a contradiction means you cannot
|
||||
use both them and the Library together in an executable that you
|
||||
distribute.
|
||||
|
||||
7. You may place library facilities that are a work based on the
|
||||
Library side-by-side in a single library together with other library
|
||||
facilities not covered by this License, and distribute such a combined
|
||||
library, provided that the separate distribution of the work based on
|
||||
the Library and of the other library facilities is otherwise
|
||||
permitted, and provided that you do these two things:
|
||||
|
||||
a) Accompany the combined library with a copy of the same work
|
||||
based on the Library, uncombined with any other library
|
||||
facilities. This must be distributed under the terms of the
|
||||
Sections above.
|
||||
|
||||
b) Give prominent notice with the combined library of the fact
|
||||
that part of it is a work based on the Library, and explaining
|
||||
where to find the accompanying uncombined form of the same work.
|
||||
|
||||
8. You may not copy, modify, sublicense, link with, or distribute
|
||||
the Library except as expressly provided under this License. Any
|
||||
attempt otherwise to copy, modify, sublicense, link with, or
|
||||
distribute the Library is void, and will automatically terminate your
|
||||
rights under this License. However, parties who have received copies,
|
||||
or rights, from you under this License will not have their licenses
|
||||
terminated so long as such parties remain in full compliance.
|
||||
|
||||
9. You are not required to accept this License, since you have not
|
||||
signed it. However, nothing else grants you permission to modify or
|
||||
distribute the Library or its derivative works. These actions are
|
||||
prohibited by law if you do not accept this License. Therefore, by
|
||||
modifying or distributing the Library (or any work based on the
|
||||
Library), you indicate your acceptance of this License to do so, and
|
||||
all its terms and conditions for copying, distributing or modifying
|
||||
the Library or works based on it.
|
||||
|
||||
10. Each time you redistribute the Library (or any work based on the
|
||||
Library), the recipient automatically receives a license from the
|
||||
original licensor to copy, distribute, link with or modify the Library
|
||||
subject to these terms and conditions. You may not impose any further
|
||||
restrictions on the recipients' exercise of the rights granted herein.
|
||||
You are not responsible for enforcing compliance by third parties to
|
||||
this License.
|
||||
|
||||
11. If, as a consequence of a court judgment or allegation of patent
|
||||
infringement or for any other reason (not limited to patent issues),
|
||||
conditions are imposed on you (whether by court order, agreement or
|
||||
otherwise) that contradict the conditions of this License, they do not
|
||||
excuse you from the conditions of this License. If you cannot
|
||||
distribute so as to satisfy simultaneously your obligations under this
|
||||
License and any other pertinent obligations, then as a consequence you
|
||||
may not distribute the Library at all. For example, if a patent
|
||||
license would not permit royalty-free redistribution of the Library by
|
||||
all those who receive copies directly or indirectly through you, then
|
||||
the only way you could satisfy both it and this License would be to
|
||||
refrain entirely from distribution of the Library.
|
||||
|
||||
If any portion of this section is held invalid or unenforceable under any
|
||||
particular circumstance, the balance of the section is intended to apply,
|
||||
and the section as a whole is intended to apply in other circumstances.
|
||||
|
||||
It is not the purpose of this section to induce you to infringe any
|
||||
patents or other property right claims or to contest validity of any
|
||||
such claims; this section has the sole purpose of protecting the
|
||||
integrity of the free software distribution system which is
|
||||
implemented by public license practices. Many people have made
|
||||
generous contributions to the wide range of software distributed
|
||||
through that system in reliance on consistent application of that
|
||||
system; it is up to the author/donor to decide if he or she is willing
|
||||
to distribute software through any other system and a licensee cannot
|
||||
impose that choice.
|
||||
|
||||
This section is intended to make thoroughly clear what is believed to
|
||||
be a consequence of the rest of this License.
|
||||
|
||||
12. If the distribution and/or use of the Library is restricted in
|
||||
certain countries either by patents or by copyrighted interfaces, the
|
||||
original copyright holder who places the Library under this License may add
|
||||
an explicit geographical distribution limitation excluding those countries,
|
||||
so that distribution is permitted only in or among countries not thus
|
||||
excluded. In such case, this License incorporates the limitation as if
|
||||
written in the body of this License.
|
||||
|
||||
13. The Free Software Foundation may publish revised and/or new
|
||||
versions of the Library General Public License from time to time.
|
||||
Such new versions will be similar in spirit to the present version,
|
||||
but may differ in detail to address new problems or concerns.
|
||||
|
||||
Each version is given a distinguishing version number. If the Library
|
||||
specifies a version number of this License which applies to it and
|
||||
"any later version", you have the option of following the terms and
|
||||
conditions either of that version or of any later version published by
|
||||
the Free Software Foundation. If the Library does not specify a
|
||||
license version number, you may choose any version ever published by
|
||||
the Free Software Foundation.
|
||||
|
||||
14. If you wish to incorporate parts of the Library into other free
|
||||
programs whose distribution conditions are incompatible with these,
|
||||
write to the author to ask for permission. For software which is
|
||||
copyrighted by the Free Software Foundation, write to the Free
|
||||
Software Foundation; we sometimes make exceptions for this. Our
|
||||
decision will be guided by the two goals of preserving the free status
|
||||
of all derivatives of our free software and of promoting the sharing
|
||||
and reuse of software generally.
|
||||
|
||||
NO WARRANTY
|
||||
|
||||
15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO
|
||||
WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW.
|
||||
EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR
|
||||
OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY
|
||||
KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE
|
||||
LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME
|
||||
THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
|
||||
|
||||
16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN
|
||||
WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY
|
||||
AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU
|
||||
FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR
|
||||
CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE
|
||||
LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING
|
||||
RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A
|
||||
FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF
|
||||
SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
|
||||
DAMAGES.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
Appendix: How to Apply These Terms to Your New Libraries
|
||||
|
||||
If you develop a new library, and you want it to be of the greatest
|
||||
possible use to the public, we recommend making it free software that
|
||||
everyone can redistribute and change. You can do so by permitting
|
||||
redistribution under these terms (or, alternatively, under the terms of the
|
||||
ordinary General Public License).
|
||||
|
||||
To apply these terms, attach the following notices to the library. It is
|
||||
safest to attach them to the start of each source file to most effectively
|
||||
convey the exclusion of warranty; and each file should have at least the
|
||||
"copyright" line and a pointer to where the full notice is found.
|
||||
|
||||
<one line to give the library's name and a brief idea of what it does.>
|
||||
Copyright (C) <year> <name of author>
|
||||
|
||||
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., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
|
||||
Also add information on how to contact you by electronic and paper mail.
|
||||
|
||||
You should also get your employer (if you work as a programmer) or your
|
||||
school, if any, to sign a "copyright disclaimer" for the library, if
|
||||
necessary. Here is a sample; alter the names:
|
||||
|
||||
Yoyodyne, Inc., hereby disclaims all copyright interest in the
|
||||
library `Frob' (a library for tweaking knobs) written by James Random Hacker.
|
||||
|
||||
<signature of Ty Coon>, 1 April 1990
|
||||
Ty Coon, President of Vice
|
||||
|
||||
That's all there is to it!
|
||||
|
||||
@@ -0,0 +1,11 @@
|
||||
prefix=@prefix@
|
||||
exec_prefix=@exec_prefix@
|
||||
libdir=@libdir@
|
||||
includedir=@includedir@
|
||||
|
||||
Name: OpenAL
|
||||
Description: OpenAL is a cross-platform 3D audio API
|
||||
Requires: @PKG_CONFIG_REQUIRES@
|
||||
Version: @PACKAGE_VERSION@
|
||||
Libs: -L${libdir} -l@LIBNAME@ @PKG_CONFIG_LIBS@
|
||||
Cflags: -I${includedir} -I${includedir}/AL @PKG_CONFIG_CFLAGS@
|
||||
@@ -1,69 +0,0 @@
|
||||
# OpenAL config file. Options that are not under a block or are under the
|
||||
# [general] block are for general, non-backend-specific options. Blocks may
|
||||
# appear multiple times, and duplicated options will take the last value
|
||||
# specified. The system-wide settings can be put in /etc/openal/config and
|
||||
# user-specific override settings in ~/.openalrc
|
||||
|
||||
# Option and block names are case-insenstive. The supplied values are only
|
||||
# hints and may not be honored (though generally it'll try to get as close as
|
||||
# possible). These are the current available settings:
|
||||
|
||||
format = AL_FORMAT_STEREO16 # Sets the output format. Can be one of:
|
||||
# AL_FORMAT_MONO8 (8-bit mono)
|
||||
# AL_FORMAT_STEREO8 (8-bit stereo)
|
||||
# AL_FORMAT_QUAD8 (8-bit 4-channel)
|
||||
# AL_FORMAT_51CHN8 (8-bit 5.1 output)
|
||||
# AL_FORMAT_61CHN8 (8-bit 6.1 output)
|
||||
# AL_FORMAT_71CHN8 (8-bit 7.1 output)
|
||||
# AL_FORMAT_MONO16 (16-bit mono)
|
||||
# AL_FORMAT_STEREO16 (16-bit stereo)
|
||||
# AL_FORMAT_QUAD16 (16-bit 4-channel)
|
||||
# AL_FORMAT_51CHN16 (16-bit 5.1 output)
|
||||
# AL_FORMAT_61CHN16 (16-bit 6.1 output)
|
||||
# AL_FORMAT_71CHN16 (16-bit 7.1 output)
|
||||
# Default is AL_FORMAT_STEREO16
|
||||
|
||||
cf_level = 0 # Sets the crossfeed level for stereo output. Valid values are:
|
||||
# 0 - No crossfeed
|
||||
# 1 - Low crossfeed
|
||||
# 2 - Middle crossfeed
|
||||
# 3 - High crossfeed (virtual speakers are closer to itself)
|
||||
# 4 - Low easy crossfeed
|
||||
# 5 - Middle easy crossfeed
|
||||
# 6 - High easy crossfeed
|
||||
# Default is 0. Users of headphones may want to try various
|
||||
# settings. Has no effect on non-stereo modes.
|
||||
|
||||
frequency = 44100 # Sets the output frequency. Default is 44100
|
||||
|
||||
refresh = 0 # Sets the number of frames-per-update. Default is calculated as
|
||||
# 8192*frequency/22050. Note that the actual granularity may or
|
||||
# may not be less than this.
|
||||
|
||||
drivers = # Sets the backend driver list order, comma-seperated. Unknown
|
||||
# backends and duplicated names are ignored, and unlisted backends
|
||||
# won't be considered for use. An empty list means the default.
|
||||
# Default is:
|
||||
# alsa,oss,dsound,winmm
|
||||
|
||||
[alsa] # ALSA backend stuff
|
||||
device = default # Sets the device name for the default playback device.
|
||||
# Default is default
|
||||
|
||||
periods = 4 # Sets the number of update buffers. Default is 4
|
||||
|
||||
capture = default # Sets the device name for the default capture device.
|
||||
# Default is default
|
||||
|
||||
[oss] # OSS backend stuff
|
||||
device = /dev/dsp # Sets the device name for OSS output. Default is /dev/dsp
|
||||
|
||||
periods = 4 # Sets the number of update buffers. Default is 4
|
||||
|
||||
capture = /dev/dsp # Sets the device name for OSS capture. Default is /dev/dsp
|
||||
|
||||
[dsound] # DirectSound backend stuff
|
||||
# Nothing yet...
|
||||
|
||||
[winmm] # Windows Multimedia backend stuff
|
||||
# Nothing yet...
|
||||
+2010
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,421 @@
|
||||
# This is a makehrtf HRIR definition file. It is used to define the layout
|
||||
# and source data to be processed into an OpenAL Soft compatible HRTF.
|
||||
#
|
||||
# This definition is used to transform an average of the left and right ear
|
||||
# HRIRs from any raw dataset from the IRCAM/AKG Listen HRTF database.
|
||||
#
|
||||
# The datasets are available free of charge from:
|
||||
#
|
||||
# http://recherche.ircam.fr/equipes/salles/listen/index.html
|
||||
#
|
||||
# Contact for the Listen HRTF Database:
|
||||
#
|
||||
# Olivier Warusfel <olivier.warusfel@ircam.fr>,
|
||||
# Room Acoustics Team, IRCAM
|
||||
# 1, place Igor Stravinsky
|
||||
# 75004 PARIS, France
|
||||
|
||||
rate = 44100
|
||||
|
||||
# The raw sets have up to 8192 samples, but 2048 seems large enough.
|
||||
points = 2048
|
||||
|
||||
# The IRCAM sets are not as dense as the MIT set.
|
||||
azimuths = 1, 6, 12, 24, 24, 24, 24, 24, 24, 24, 12, 6, 1
|
||||
|
||||
# No head radius was provided. Just use the average radius of 9 cm.
|
||||
radius = 0.09
|
||||
|
||||
# The distance between the source and the listener (in meters).
|
||||
distance = 1.95
|
||||
|
||||
# The IRCAM source azimuth is counter-clockwise, so it needs to be flipped.
|
||||
# Left and right ear HRIRs (from the respective WAVE channels) are averaged.
|
||||
|
||||
# Repalce all occurrences of IRC_#### for the desired subject (1005 was used
|
||||
# in this demonstration).
|
||||
|
||||
[ 3, 0 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T000_P315.wav"
|
||||
+ wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T000_P315.wav"
|
||||
[ 3, 1 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T345_P315.wav"
|
||||
+ wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T015_P315.wav"
|
||||
[ 3, 2 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T330_P315.wav"
|
||||
+ wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T030_P315.wav"
|
||||
[ 3, 3 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T315_P315.wav"
|
||||
+ wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T045_P315.wav"
|
||||
[ 3, 4 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T300_P315.wav"
|
||||
+ wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T060_P315.wav"
|
||||
[ 3, 5 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T285_P315.wav"
|
||||
+ wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T075_P315.wav"
|
||||
[ 3, 6 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T270_P315.wav"
|
||||
+ wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T090_P315.wav"
|
||||
[ 3, 7 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T255_P315.wav"
|
||||
+ wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T105_P315.wav"
|
||||
[ 3, 8 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T240_P315.wav"
|
||||
+ wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T120_P315.wav"
|
||||
[ 3, 9 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T225_P315.wav"
|
||||
+ wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T135_P315.wav"
|
||||
[ 3, 10 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T210_P315.wav"
|
||||
+ wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T150_P315.wav"
|
||||
[ 3, 11 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T195_P315.wav"
|
||||
+ wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T165_P315.wav"
|
||||
[ 3, 12 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T180_P315.wav"
|
||||
+ wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T180_P315.wav"
|
||||
[ 3, 13 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T165_P315.wav"
|
||||
+ wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T195_P315.wav"
|
||||
[ 3, 14 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T150_P315.wav"
|
||||
+ wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T210_P315.wav"
|
||||
[ 3, 15 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T135_P315.wav"
|
||||
+ wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T225_P315.wav"
|
||||
[ 3, 16 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T120_P315.wav"
|
||||
+ wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T240_P315.wav"
|
||||
[ 3, 17 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T105_P315.wav"
|
||||
+ wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T255_P315.wav"
|
||||
[ 3, 18 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T090_P315.wav"
|
||||
+ wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T270_P315.wav"
|
||||
[ 3, 19 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T075_P315.wav"
|
||||
+ wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T285_P315.wav"
|
||||
[ 3, 20 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T060_P315.wav"
|
||||
+ wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T300_P315.wav"
|
||||
[ 3, 21 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T045_P315.wav"
|
||||
+ wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T315_P315.wav"
|
||||
[ 3, 22 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T030_P315.wav"
|
||||
+ wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T330_P315.wav"
|
||||
[ 3, 23 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T015_P315.wav"
|
||||
+ wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T345_P315.wav"
|
||||
|
||||
[ 4, 0 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T000_P330.wav"
|
||||
+ wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T000_P330.wav"
|
||||
[ 4, 1 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T345_P330.wav"
|
||||
+ wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T015_P330.wav"
|
||||
[ 4, 2 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T330_P330.wav"
|
||||
+ wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T030_P330.wav"
|
||||
[ 4, 3 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T315_P330.wav"
|
||||
+ wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T045_P330.wav"
|
||||
[ 4, 4 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T300_P330.wav"
|
||||
+ wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T060_P330.wav"
|
||||
[ 4, 5 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T285_P330.wav"
|
||||
+ wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T075_P330.wav"
|
||||
[ 4, 6 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T270_P330.wav"
|
||||
+ wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T090_P330.wav"
|
||||
[ 4, 7 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T255_P330.wav"
|
||||
+ wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T105_P330.wav"
|
||||
[ 4, 8 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T240_P330.wav"
|
||||
+ wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T120_P330.wav"
|
||||
[ 4, 9 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T225_P330.wav"
|
||||
+ wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T135_P330.wav"
|
||||
[ 4, 10 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T210_P330.wav"
|
||||
+ wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T150_P330.wav"
|
||||
[ 4, 11 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T195_P330.wav"
|
||||
+ wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T165_P330.wav"
|
||||
[ 4, 12 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T180_P330.wav"
|
||||
+ wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T180_P330.wav"
|
||||
[ 4, 13 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T165_P330.wav"
|
||||
+ wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T195_P330.wav"
|
||||
[ 4, 14 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T150_P330.wav"
|
||||
+ wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T210_P330.wav"
|
||||
[ 4, 15 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T135_P330.wav"
|
||||
+ wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T225_P330.wav"
|
||||
[ 4, 16 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T120_P330.wav"
|
||||
+ wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T240_P330.wav"
|
||||
[ 4, 17 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T105_P330.wav"
|
||||
+ wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T255_P330.wav"
|
||||
[ 4, 18 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T090_P330.wav"
|
||||
+ wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T270_P330.wav"
|
||||
[ 4, 19 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T075_P330.wav"
|
||||
+ wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T285_P330.wav"
|
||||
[ 4, 20 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T060_P330.wav"
|
||||
+ wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T300_P330.wav"
|
||||
[ 4, 21 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T045_P330.wav"
|
||||
+ wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T315_P330.wav"
|
||||
[ 4, 22 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T030_P330.wav"
|
||||
+ wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T330_P330.wav"
|
||||
[ 4, 23 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T015_P330.wav"
|
||||
+ wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T345_P330.wav"
|
||||
|
||||
[ 5, 0 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T000_P345.wav"
|
||||
+ wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T000_P345.wav"
|
||||
[ 5, 1 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T345_P345.wav"
|
||||
+ wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T015_P345.wav"
|
||||
[ 5, 2 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T330_P345.wav"
|
||||
+ wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T030_P345.wav"
|
||||
[ 5, 3 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T315_P345.wav"
|
||||
+ wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T045_P345.wav"
|
||||
[ 5, 4 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T300_P345.wav"
|
||||
+ wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T060_P345.wav"
|
||||
[ 5, 5 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T285_P345.wav"
|
||||
+ wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T075_P345.wav"
|
||||
[ 5, 6 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T270_P345.wav"
|
||||
+ wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T090_P345.wav"
|
||||
[ 5, 7 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T255_P345.wav"
|
||||
+ wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T105_P345.wav"
|
||||
[ 5, 8 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T240_P345.wav"
|
||||
+ wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T120_P345.wav"
|
||||
[ 5, 9 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T225_P345.wav"
|
||||
+ wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T135_P345.wav"
|
||||
[ 5, 10 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T210_P345.wav"
|
||||
+ wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T150_P345.wav"
|
||||
[ 5, 11 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T195_P345.wav"
|
||||
+ wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T165_P345.wav"
|
||||
[ 5, 12 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T180_P345.wav"
|
||||
+ wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T180_P345.wav"
|
||||
[ 5, 13 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T165_P345.wav"
|
||||
+ wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T195_P345.wav"
|
||||
[ 5, 14 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T150_P345.wav"
|
||||
+ wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T210_P345.wav"
|
||||
[ 5, 15 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T135_P345.wav"
|
||||
+ wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T225_P345.wav"
|
||||
[ 5, 16 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T120_P345.wav"
|
||||
+ wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T240_P345.wav"
|
||||
[ 5, 17 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T105_P345.wav"
|
||||
+ wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T255_P345.wav"
|
||||
[ 5, 18 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T090_P345.wav"
|
||||
+ wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T270_P345.wav"
|
||||
[ 5, 19 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T075_P345.wav"
|
||||
+ wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T285_P345.wav"
|
||||
[ 5, 20 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T060_P345.wav"
|
||||
+ wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T300_P345.wav"
|
||||
[ 5, 21 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T045_P345.wav"
|
||||
+ wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T315_P345.wav"
|
||||
[ 5, 22 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T030_P345.wav"
|
||||
+ wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T330_P345.wav"
|
||||
[ 5, 23 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T015_P345.wav"
|
||||
+ wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T345_P345.wav"
|
||||
|
||||
[ 6, 0 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T000_P000.wav"
|
||||
+ wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T000_P000.wav"
|
||||
[ 6, 1 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T345_P000.wav"
|
||||
+ wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T015_P000.wav"
|
||||
[ 6, 2 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T330_P000.wav"
|
||||
+ wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T030_P000.wav"
|
||||
[ 6, 3 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T315_P000.wav"
|
||||
+ wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T045_P000.wav"
|
||||
[ 6, 4 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T300_P000.wav"
|
||||
+ wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T060_P000.wav"
|
||||
[ 6, 5 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T285_P000.wav"
|
||||
+ wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T075_P000.wav"
|
||||
[ 6, 6 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T270_P000.wav"
|
||||
+ wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T090_P000.wav"
|
||||
[ 6, 7 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T255_P000.wav"
|
||||
+ wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T105_P000.wav"
|
||||
[ 6, 8 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T240_P000.wav"
|
||||
+ wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T120_P000.wav"
|
||||
[ 6, 9 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T225_P000.wav"
|
||||
+ wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T135_P000.wav"
|
||||
[ 6, 10 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T210_P000.wav"
|
||||
+ wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T150_P000.wav"
|
||||
[ 6, 11 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T195_P000.wav"
|
||||
+ wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T165_P000.wav"
|
||||
[ 6, 12 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T180_P000.wav"
|
||||
+ wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T180_P000.wav"
|
||||
[ 6, 13 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T165_P000.wav"
|
||||
+ wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T195_P000.wav"
|
||||
[ 6, 14 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T150_P000.wav"
|
||||
+ wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T210_P000.wav"
|
||||
[ 6, 15 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T135_P000.wav"
|
||||
+ wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T225_P000.wav"
|
||||
[ 6, 16 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T120_P000.wav"
|
||||
+ wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T240_P000.wav"
|
||||
[ 6, 17 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T105_P000.wav"
|
||||
+ wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T255_P000.wav"
|
||||
[ 6, 18 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T090_P000.wav"
|
||||
+ wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T270_P000.wav"
|
||||
[ 6, 19 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T075_P000.wav"
|
||||
+ wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T285_P000.wav"
|
||||
[ 6, 20 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T060_P000.wav"
|
||||
+ wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T300_P000.wav"
|
||||
[ 6, 21 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T045_P000.wav"
|
||||
+ wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T315_P000.wav"
|
||||
[ 6, 22 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T030_P000.wav"
|
||||
+ wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T330_P000.wav"
|
||||
[ 6, 23 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T015_P000.wav"
|
||||
+ wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T345_P000.wav"
|
||||
|
||||
[ 7, 0 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T000_P015.wav"
|
||||
+ wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T000_P015.wav"
|
||||
[ 7, 1 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T345_P015.wav"
|
||||
+ wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T015_P015.wav"
|
||||
[ 7, 2 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T330_P015.wav"
|
||||
+ wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T030_P015.wav"
|
||||
[ 7, 3 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T315_P015.wav"
|
||||
+ wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T045_P015.wav"
|
||||
[ 7, 4 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T300_P015.wav"
|
||||
+ wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T060_P015.wav"
|
||||
[ 7, 5 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T285_P015.wav"
|
||||
+ wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T075_P015.wav"
|
||||
[ 7, 6 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T270_P015.wav"
|
||||
+ wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T090_P015.wav"
|
||||
[ 7, 7 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T255_P015.wav"
|
||||
+ wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T105_P015.wav"
|
||||
[ 7, 8 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T240_P015.wav"
|
||||
+ wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T120_P015.wav"
|
||||
[ 7, 9 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T225_P015.wav"
|
||||
+ wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T135_P015.wav"
|
||||
[ 7, 10 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T210_P015.wav"
|
||||
+ wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T150_P015.wav"
|
||||
[ 7, 11 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T195_P015.wav"
|
||||
+ wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T165_P015.wav"
|
||||
[ 7, 12 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T180_P015.wav"
|
||||
+ wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T180_P015.wav"
|
||||
[ 7, 13 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T165_P015.wav"
|
||||
+ wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T195_P015.wav"
|
||||
[ 7, 14 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T150_P015.wav"
|
||||
+ wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T210_P015.wav"
|
||||
[ 7, 15 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T135_P015.wav"
|
||||
+ wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T225_P015.wav"
|
||||
[ 7, 16 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T120_P015.wav"
|
||||
+ wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T240_P015.wav"
|
||||
[ 7, 17 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T105_P015.wav"
|
||||
+ wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T255_P015.wav"
|
||||
[ 7, 18 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T090_P015.wav"
|
||||
+ wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T270_P015.wav"
|
||||
[ 7, 19 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T075_P015.wav"
|
||||
+ wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T285_P015.wav"
|
||||
[ 7, 20 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T060_P015.wav"
|
||||
+ wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T300_P015.wav"
|
||||
[ 7, 21 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T045_P015.wav"
|
||||
+ wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T315_P015.wav"
|
||||
[ 7, 22 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T030_P015.wav"
|
||||
+ wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T330_P015.wav"
|
||||
[ 7, 23 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T015_P015.wav"
|
||||
+ wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T345_P015.wav"
|
||||
|
||||
[ 8, 0 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T000_P030.wav"
|
||||
+ wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T000_P030.wav"
|
||||
[ 8, 1 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T345_P030.wav"
|
||||
+ wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T015_P030.wav"
|
||||
[ 8, 2 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T330_P030.wav"
|
||||
+ wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T030_P030.wav"
|
||||
[ 8, 3 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T315_P030.wav"
|
||||
+ wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T045_P030.wav"
|
||||
[ 8, 4 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T300_P030.wav"
|
||||
+ wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T060_P030.wav"
|
||||
[ 8, 5 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T285_P030.wav"
|
||||
+ wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T075_P030.wav"
|
||||
[ 8, 6 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T270_P030.wav"
|
||||
+ wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T090_P030.wav"
|
||||
[ 8, 7 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T255_P030.wav"
|
||||
+ wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T105_P030.wav"
|
||||
[ 8, 8 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T240_P030.wav"
|
||||
+ wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T120_P030.wav"
|
||||
[ 8, 9 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T225_P030.wav"
|
||||
+ wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T135_P030.wav"
|
||||
[ 8, 10 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T210_P030.wav"
|
||||
+ wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T150_P030.wav"
|
||||
[ 8, 11 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T195_P030.wav"
|
||||
+ wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T165_P030.wav"
|
||||
[ 8, 12 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T180_P030.wav"
|
||||
+ wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T180_P030.wav"
|
||||
[ 8, 13 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T165_P030.wav"
|
||||
+ wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T195_P030.wav"
|
||||
[ 8, 14 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T150_P030.wav"
|
||||
+ wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T210_P030.wav"
|
||||
[ 8, 15 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T135_P030.wav"
|
||||
+ wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T225_P030.wav"
|
||||
[ 8, 16 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T120_P030.wav"
|
||||
+ wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T240_P030.wav"
|
||||
[ 8, 17 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T105_P030.wav"
|
||||
+ wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T255_P030.wav"
|
||||
[ 8, 18 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T090_P030.wav"
|
||||
+ wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T270_P030.wav"
|
||||
[ 8, 19 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T075_P030.wav"
|
||||
+ wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T285_P030.wav"
|
||||
[ 8, 20 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T060_P030.wav"
|
||||
+ wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T300_P030.wav"
|
||||
[ 8, 21 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T045_P030.wav"
|
||||
+ wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T315_P030.wav"
|
||||
[ 8, 22 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T030_P030.wav"
|
||||
+ wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T330_P030.wav"
|
||||
[ 8, 23 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T015_P030.wav"
|
||||
+ wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T345_P030.wav"
|
||||
|
||||
[ 9, 0 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T000_P045.wav"
|
||||
+ wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T000_P045.wav"
|
||||
[ 9, 1 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T345_P045.wav"
|
||||
+ wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T015_P045.wav"
|
||||
[ 9, 2 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T330_P045.wav"
|
||||
+ wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T030_P045.wav"
|
||||
[ 9, 3 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T315_P045.wav"
|
||||
+ wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T045_P045.wav"
|
||||
[ 9, 4 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T300_P045.wav"
|
||||
+ wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T060_P045.wav"
|
||||
[ 9, 5 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T285_P045.wav"
|
||||
+ wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T075_P045.wav"
|
||||
[ 9, 6 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T270_P045.wav"
|
||||
+ wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T090_P045.wav"
|
||||
[ 9, 7 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T255_P045.wav"
|
||||
+ wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T105_P045.wav"
|
||||
[ 9, 8 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T240_P045.wav"
|
||||
+ wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T120_P045.wav"
|
||||
[ 9, 9 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T225_P045.wav"
|
||||
+ wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T135_P045.wav"
|
||||
[ 9, 10 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T210_P045.wav"
|
||||
+ wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T150_P045.wav"
|
||||
[ 9, 11 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T195_P045.wav"
|
||||
+ wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T165_P045.wav"
|
||||
[ 9, 12 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T180_P045.wav"
|
||||
+ wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T180_P045.wav"
|
||||
[ 9, 13 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T165_P045.wav"
|
||||
+ wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T195_P045.wav"
|
||||
[ 9, 14 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T150_P045.wav"
|
||||
+ wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T210_P045.wav"
|
||||
[ 9, 15 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T135_P045.wav"
|
||||
+ wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T225_P045.wav"
|
||||
[ 9, 16 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T120_P045.wav"
|
||||
+ wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T240_P045.wav"
|
||||
[ 9, 17 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T105_P045.wav"
|
||||
+ wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T255_P045.wav"
|
||||
[ 9, 18 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T090_P045.wav"
|
||||
+ wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T270_P045.wav"
|
||||
[ 9, 19 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T075_P045.wav"
|
||||
+ wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T285_P045.wav"
|
||||
[ 9, 20 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T060_P045.wav"
|
||||
+ wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T300_P045.wav"
|
||||
[ 9, 21 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T045_P045.wav"
|
||||
+ wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T315_P045.wav"
|
||||
[ 9, 22 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T030_P045.wav"
|
||||
+ wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T330_P045.wav"
|
||||
[ 9, 23 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T015_P045.wav"
|
||||
+ wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T345_P045.wav"
|
||||
|
||||
[ 10, 0 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T000_P060.wav"
|
||||
+ wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T000_P060.wav"
|
||||
[ 10, 1 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T330_P060.wav"
|
||||
+ wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T030_P060.wav"
|
||||
[ 10, 2 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T300_P060.wav"
|
||||
+ wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T060_P060.wav"
|
||||
[ 10, 3 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T270_P060.wav"
|
||||
+ wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T090_P060.wav"
|
||||
[ 10, 4 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T240_P060.wav"
|
||||
+ wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T120_P060.wav"
|
||||
[ 10, 5 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T210_P060.wav"
|
||||
+ wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T150_P060.wav"
|
||||
[ 10, 6 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T180_P060.wav"
|
||||
+ wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T180_P060.wav"
|
||||
[ 10, 7 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T150_P060.wav"
|
||||
+ wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T210_P060.wav"
|
||||
[ 10, 8 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T120_P060.wav"
|
||||
+ wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T240_P060.wav"
|
||||
[ 10, 9 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T090_P060.wav"
|
||||
+ wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T270_P060.wav"
|
||||
[ 10, 10 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T060_P060.wav"
|
||||
+ wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T300_P060.wav"
|
||||
[ 10, 11 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T030_P060.wav"
|
||||
+ wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T330_P060.wav"
|
||||
|
||||
[ 11, 0 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T000_P075.wav"
|
||||
+ wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T000_P075.wav"
|
||||
[ 11, 1 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T300_P075.wav"
|
||||
+ wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T060_P075.wav"
|
||||
[ 11, 2 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T240_P075.wav"
|
||||
+ wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T120_P075.wav"
|
||||
[ 11, 3 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T180_P075.wav"
|
||||
+ wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T180_P075.wav"
|
||||
[ 11, 4 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T120_P075.wav"
|
||||
+ wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T240_P075.wav"
|
||||
[ 11, 5 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T060_P075.wav"
|
||||
+ wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T300_P075.wav"
|
||||
|
||||
[ 12, 0 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T000_P090.wav"
|
||||
+ wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T000_P090.wav"
|
||||
|
||||
@@ -0,0 +1,819 @@
|
||||
# This is a makehrtf HRIR definition file. It is used to define the layout
|
||||
# and source data to be processed into an OpenAL Soft compatible HRTF.
|
||||
#
|
||||
# This definition is used to transform the left ear HRIRs from the full set
|
||||
# of KEMAR HRIRs provided by Bill Gardner <billg@media.mit.edu> and Keith
|
||||
# Martin <kdm@media.mit.edu> of MIT Media Laboratory.
|
||||
#
|
||||
# The data (full.tar.Z or full.zip) is available from:
|
||||
#
|
||||
# http://sound.media.mit.edu/resources/KEMAR.html
|
||||
#
|
||||
# It is copyright 1994 by MIT Media Laboratory, and provided free of charge
|
||||
# with no restrictions on use so long as the authors (above) are cited.
|
||||
#
|
||||
# This definition is used to generate the internal HRTF table used by OpenAL
|
||||
# Soft.
|
||||
|
||||
# The following are the dataset metrics. They must always be specified at
|
||||
# start of a definition file, but their order is not important.
|
||||
|
||||
# Sampling rate of the HRIR data (in hertz).
|
||||
rate = 44100
|
||||
|
||||
# The number of points to use from the HRIR data. This should be a
|
||||
# sufficiently large value (to encompass the entire impulse response). It
|
||||
# cannot be smaller than the truncation size (default is 32) specified on the
|
||||
# command line.
|
||||
points = 512
|
||||
|
||||
# A list of the number of azimuths measured for each elevation. There must
|
||||
# be at least 5 elevations covering the 180 degrees for the dataset to be
|
||||
# viable.
|
||||
azimuths = 1, 12, 24, 36, 45, 56, 60, 72, 72, 72, 72, 72, 60, 56, 45, 36, 24, 12, 1
|
||||
|
||||
# The approximate radius (measured ear-to-ear) of the listener's head (in
|
||||
# meters). This does not have to match the dataset, since makehrtf uses a
|
||||
# spherical model to reconstruct the propagation delay.
|
||||
radius = 0.09
|
||||
|
||||
# The distance between the source and the listener (in meters). This does
|
||||
# have to match the dataset, but it's effect is minimal at the moment due to
|
||||
# the coupled nature of OpenAL Soft's HRTF model.
|
||||
distance = 1.4
|
||||
|
||||
# Following the metrics is the list of source HRIRs for each elevation and
|
||||
# azimuth pair. They don't have to be specified in order, but the final
|
||||
# composition must not be sparse. They can however begin above a number of
|
||||
# elevations (as typical for HRIR measurements).
|
||||
#
|
||||
# The elevation and azimuth indices are used to determine the resulting polar
|
||||
# coordinates following OpenAL Soft's convention (-90 degree elevation
|
||||
# increasing counter-clockwise from the bottom; 0 degree azimuth increasing
|
||||
# clockwise from the front).
|
||||
#
|
||||
# More than one HRIR can be used per source, in which case the average
|
||||
# magnitude response of all references for that source is used.
|
||||
#
|
||||
# Source specification is of the form (~BNF):
|
||||
#
|
||||
# source = '[' ev_index ',' az_index ']' '=' source_ref [ '+' source_ref ]*
|
||||
#
|
||||
# ev_index = unsigned_integer
|
||||
# az_index = unsigned_integer
|
||||
# source_ref = ref_spec ':' filename
|
||||
#
|
||||
# ref_spec = ( wave_fmt '(' wave_parms ')' [ '@' start_sample ] ) |
|
||||
# ( bin_fmt '(' bini_parms ')' [ '@' start_bytes ] ) |
|
||||
# ( bin_fmt '(' binf_parms ')' [ '@' start_bytes ] ) |
|
||||
# ( ascii_fmt '(' asci_parms ')' [ '@' start_elements ] ) |
|
||||
# ( ascii_fmt '(' ascf_parms ')' [ '@' start_elements ] )
|
||||
# filename = double_quoted_string
|
||||
#
|
||||
# wave_fmt = 'wave'
|
||||
# wave_parms = channel
|
||||
# bin_fmt = 'bin_le' | 'bin_be'
|
||||
# bini_parms = 'int' ',' byte_size [ ',' bin_sig_bits ] [ ';' skip_bytes ]
|
||||
# binf_parms = 'fp' ',' byte_size [ ';' skip_bytes ]
|
||||
# ascii_fmt = 'ascii'
|
||||
# asci_parms = 'int' ',' sig_bits [ ';' skip_elements ]
|
||||
# ascf_parms = 'fp' [ ';' skip_elements ]
|
||||
# start_sample = unsigned_integer
|
||||
# start_bytes = unsigned_integer
|
||||
# start_elements = unsigned_integer
|
||||
#
|
||||
# channel = unsigned_integer
|
||||
# byte_size = unsigned_integer
|
||||
# bin_sig_bits = signed_integer
|
||||
# skip_bytes = unsigned_integer
|
||||
# sig_bits = unsigned_integer
|
||||
# skip_elements = unsigned_integer
|
||||
#
|
||||
# For bin_sig_bits, positive values mean the significant bits start at the
|
||||
# MSB (padding toward the LSB) while negative values mean they start at the
|
||||
# LSB.
|
||||
|
||||
[ 5, 0 ] = wave (0) : "./MITfull/elev-40/L-40e000a.wav"
|
||||
[ 5, 1 ] = wave (0) : "./MITfull/elev-40/L-40e006a.wav"
|
||||
[ 5, 2 ] = wave (0) : "./MITfull/elev-40/L-40e013a.wav"
|
||||
[ 5, 3 ] = wave (0) : "./MITfull/elev-40/L-40e019a.wav"
|
||||
[ 5, 4 ] = wave (0) : "./MITfull/elev-40/L-40e026a.wav"
|
||||
[ 5, 5 ] = wave (0) : "./MITfull/elev-40/L-40e032a.wav"
|
||||
[ 5, 6 ] = wave (0) : "./MITfull/elev-40/L-40e039a.wav"
|
||||
[ 5, 7 ] = wave (0) : "./MITfull/elev-40/L-40e045a.wav"
|
||||
[ 5, 8 ] = wave (0) : "./MITfull/elev-40/L-40e051a.wav"
|
||||
[ 5, 9 ] = wave (0) : "./MITfull/elev-40/L-40e058a.wav"
|
||||
[ 5, 10 ] = wave (0) : "./MITfull/elev-40/L-40e064a.wav"
|
||||
[ 5, 11 ] = wave (0) : "./MITfull/elev-40/L-40e071a.wav"
|
||||
[ 5, 12 ] = wave (0) : "./MITfull/elev-40/L-40e077a.wav"
|
||||
[ 5, 13 ] = wave (0) : "./MITfull/elev-40/L-40e084a.wav"
|
||||
[ 5, 14 ] = wave (0) : "./MITfull/elev-40/L-40e090a.wav"
|
||||
[ 5, 15 ] = wave (0) : "./MITfull/elev-40/L-40e096a.wav"
|
||||
[ 5, 16 ] = wave (0) : "./MITfull/elev-40/L-40e103a.wav"
|
||||
[ 5, 17 ] = wave (0) : "./MITfull/elev-40/L-40e109a.wav"
|
||||
[ 5, 18 ] = wave (0) : "./MITfull/elev-40/L-40e116a.wav"
|
||||
[ 5, 19 ] = wave (0) : "./MITfull/elev-40/L-40e122a.wav"
|
||||
[ 5, 20 ] = wave (0) : "./MITfull/elev-40/L-40e129a.wav"
|
||||
[ 5, 21 ] = wave (0) : "./MITfull/elev-40/L-40e135a.wav"
|
||||
[ 5, 22 ] = wave (0) : "./MITfull/elev-40/L-40e141a.wav"
|
||||
[ 5, 23 ] = wave (0) : "./MITfull/elev-40/L-40e148a.wav"
|
||||
[ 5, 24 ] = wave (0) : "./MITfull/elev-40/L-40e154a.wav"
|
||||
[ 5, 25 ] = wave (0) : "./MITfull/elev-40/L-40e161a.wav"
|
||||
[ 5, 26 ] = wave (0) : "./MITfull/elev-40/L-40e167a.wav"
|
||||
[ 5, 27 ] = wave (0) : "./MITfull/elev-40/L-40e174a.wav"
|
||||
[ 5, 28 ] = wave (0) : "./MITfull/elev-40/L-40e180a.wav"
|
||||
[ 5, 29 ] = wave (0) : "./MITfull/elev-40/L-40e186a.wav"
|
||||
[ 5, 30 ] = wave (0) : "./MITfull/elev-40/L-40e193a.wav"
|
||||
[ 5, 31 ] = wave (0) : "./MITfull/elev-40/L-40e199a.wav"
|
||||
[ 5, 32 ] = wave (0) : "./MITfull/elev-40/L-40e206a.wav"
|
||||
[ 5, 33 ] = wave (0) : "./MITfull/elev-40/L-40e212a.wav"
|
||||
[ 5, 34 ] = wave (0) : "./MITfull/elev-40/L-40e219a.wav"
|
||||
[ 5, 35 ] = wave (0) : "./MITfull/elev-40/L-40e225a.wav"
|
||||
[ 5, 36 ] = wave (0) : "./MITfull/elev-40/L-40e231a.wav"
|
||||
[ 5, 37 ] = wave (0) : "./MITfull/elev-40/L-40e238a.wav"
|
||||
[ 5, 38 ] = wave (0) : "./MITfull/elev-40/L-40e244a.wav"
|
||||
[ 5, 39 ] = wave (0) : "./MITfull/elev-40/L-40e251a.wav"
|
||||
[ 5, 40 ] = wave (0) : "./MITfull/elev-40/L-40e257a.wav"
|
||||
[ 5, 41 ] = wave (0) : "./MITfull/elev-40/L-40e264a.wav"
|
||||
[ 5, 42 ] = wave (0) : "./MITfull/elev-40/L-40e270a.wav"
|
||||
[ 5, 43 ] = wave (0) : "./MITfull/elev-40/L-40e276a.wav"
|
||||
[ 5, 44 ] = wave (0) : "./MITfull/elev-40/L-40e283a.wav"
|
||||
[ 5, 45 ] = wave (0) : "./MITfull/elev-40/L-40e289a.wav"
|
||||
[ 5, 46 ] = wave (0) : "./MITfull/elev-40/L-40e296a.wav"
|
||||
[ 5, 47 ] = wave (0) : "./MITfull/elev-40/L-40e302a.wav"
|
||||
[ 5, 48 ] = wave (0) : "./MITfull/elev-40/L-40e309a.wav"
|
||||
[ 5, 49 ] = wave (0) : "./MITfull/elev-40/L-40e315a.wav"
|
||||
[ 5, 50 ] = wave (0) : "./MITfull/elev-40/L-40e321a.wav"
|
||||
[ 5, 51 ] = wave (0) : "./MITfull/elev-40/L-40e328a.wav"
|
||||
[ 5, 52 ] = wave (0) : "./MITfull/elev-40/L-40e334a.wav"
|
||||
[ 5, 53 ] = wave (0) : "./MITfull/elev-40/L-40e341a.wav"
|
||||
[ 5, 54 ] = wave (0) : "./MITfull/elev-40/L-40e347a.wav"
|
||||
[ 5, 55 ] = wave (0) : "./MITfull/elev-40/L-40e354a.wav"
|
||||
|
||||
[ 6, 0 ] = wave (0) : "./MITfull/elev-30/L-30e000a.wav"
|
||||
[ 6, 1 ] = wave (0) : "./MITfull/elev-30/L-30e006a.wav"
|
||||
[ 6, 2 ] = wave (0) : "./MITfull/elev-30/L-30e012a.wav"
|
||||
[ 6, 3 ] = wave (0) : "./MITfull/elev-30/L-30e018a.wav"
|
||||
[ 6, 4 ] = wave (0) : "./MITfull/elev-30/L-30e024a.wav"
|
||||
[ 6, 5 ] = wave (0) : "./MITfull/elev-30/L-30e030a.wav"
|
||||
[ 6, 6 ] = wave (0) : "./MITfull/elev-30/L-30e036a.wav"
|
||||
[ 6, 7 ] = wave (0) : "./MITfull/elev-30/L-30e042a.wav"
|
||||
[ 6, 8 ] = wave (0) : "./MITfull/elev-30/L-30e048a.wav"
|
||||
[ 6, 9 ] = wave (0) : "./MITfull/elev-30/L-30e054a.wav"
|
||||
[ 6, 10 ] = wave (0) : "./MITfull/elev-30/L-30e060a.wav"
|
||||
[ 6, 11 ] = wave (0) : "./MITfull/elev-30/L-30e066a.wav"
|
||||
[ 6, 12 ] = wave (0) : "./MITfull/elev-30/L-30e072a.wav"
|
||||
[ 6, 13 ] = wave (0) : "./MITfull/elev-30/L-30e078a.wav"
|
||||
[ 6, 14 ] = wave (0) : "./MITfull/elev-30/L-30e084a.wav"
|
||||
[ 6, 15 ] = wave (0) : "./MITfull/elev-30/L-30e090a.wav"
|
||||
[ 6, 16 ] = wave (0) : "./MITfull/elev-30/L-30e096a.wav"
|
||||
[ 6, 17 ] = wave (0) : "./MITfull/elev-30/L-30e102a.wav"
|
||||
[ 6, 18 ] = wave (0) : "./MITfull/elev-30/L-30e108a.wav"
|
||||
[ 6, 19 ] = wave (0) : "./MITfull/elev-30/L-30e114a.wav"
|
||||
[ 6, 20 ] = wave (0) : "./MITfull/elev-30/L-30e120a.wav"
|
||||
[ 6, 21 ] = wave (0) : "./MITfull/elev-30/L-30e126a.wav"
|
||||
[ 6, 22 ] = wave (0) : "./MITfull/elev-30/L-30e132a.wav"
|
||||
[ 6, 23 ] = wave (0) : "./MITfull/elev-30/L-30e138a.wav"
|
||||
[ 6, 24 ] = wave (0) : "./MITfull/elev-30/L-30e144a.wav"
|
||||
[ 6, 25 ] = wave (0) : "./MITfull/elev-30/L-30e150a.wav"
|
||||
[ 6, 26 ] = wave (0) : "./MITfull/elev-30/L-30e156a.wav"
|
||||
[ 6, 27 ] = wave (0) : "./MITfull/elev-30/L-30e162a.wav"
|
||||
[ 6, 28 ] = wave (0) : "./MITfull/elev-30/L-30e168a.wav"
|
||||
[ 6, 29 ] = wave (0) : "./MITfull/elev-30/L-30e174a.wav"
|
||||
[ 6, 30 ] = wave (0) : "./MITfull/elev-30/L-30e180a.wav"
|
||||
[ 6, 31 ] = wave (0) : "./MITfull/elev-30/L-30e186a.wav"
|
||||
[ 6, 32 ] = wave (0) : "./MITfull/elev-30/L-30e192a.wav"
|
||||
[ 6, 33 ] = wave (0) : "./MITfull/elev-30/L-30e198a.wav"
|
||||
[ 6, 34 ] = wave (0) : "./MITfull/elev-30/L-30e204a.wav"
|
||||
[ 6, 35 ] = wave (0) : "./MITfull/elev-30/L-30e210a.wav"
|
||||
[ 6, 36 ] = wave (0) : "./MITfull/elev-30/L-30e216a.wav"
|
||||
[ 6, 37 ] = wave (0) : "./MITfull/elev-30/L-30e222a.wav"
|
||||
[ 6, 38 ] = wave (0) : "./MITfull/elev-30/L-30e228a.wav"
|
||||
[ 6, 39 ] = wave (0) : "./MITfull/elev-30/L-30e234a.wav"
|
||||
[ 6, 40 ] = wave (0) : "./MITfull/elev-30/L-30e240a.wav"
|
||||
[ 6, 41 ] = wave (0) : "./MITfull/elev-30/L-30e246a.wav"
|
||||
[ 6, 42 ] = wave (0) : "./MITfull/elev-30/L-30e252a.wav"
|
||||
[ 6, 43 ] = wave (0) : "./MITfull/elev-30/L-30e258a.wav"
|
||||
[ 6, 44 ] = wave (0) : "./MITfull/elev-30/L-30e264a.wav"
|
||||
[ 6, 45 ] = wave (0) : "./MITfull/elev-30/L-30e270a.wav"
|
||||
[ 6, 46 ] = wave (0) : "./MITfull/elev-30/L-30e276a.wav"
|
||||
[ 6, 47 ] = wave (0) : "./MITfull/elev-30/L-30e282a.wav"
|
||||
[ 6, 48 ] = wave (0) : "./MITfull/elev-30/L-30e288a.wav"
|
||||
[ 6, 49 ] = wave (0) : "./MITfull/elev-30/L-30e294a.wav"
|
||||
[ 6, 50 ] = wave (0) : "./MITfull/elev-30/L-30e300a.wav"
|
||||
[ 6, 51 ] = wave (0) : "./MITfull/elev-30/L-30e306a.wav"
|
||||
[ 6, 52 ] = wave (0) : "./MITfull/elev-30/L-30e312a.wav"
|
||||
[ 6, 53 ] = wave (0) : "./MITfull/elev-30/L-30e318a.wav"
|
||||
[ 6, 54 ] = wave (0) : "./MITfull/elev-30/L-30e324a.wav"
|
||||
[ 6, 55 ] = wave (0) : "./MITfull/elev-30/L-30e330a.wav"
|
||||
[ 6, 56 ] = wave (0) : "./MITfull/elev-30/L-30e336a.wav"
|
||||
[ 6, 57 ] = wave (0) : "./MITfull/elev-30/L-30e342a.wav"
|
||||
[ 6, 58 ] = wave (0) : "./MITfull/elev-30/L-30e348a.wav"
|
||||
[ 6, 59 ] = wave (0) : "./MITfull/elev-30/L-30e354a.wav"
|
||||
|
||||
[ 7, 0 ] = wave (0) : "./MITfull/elev-20/L-20e000a.wav"
|
||||
[ 7, 1 ] = wave (0) : "./MITfull/elev-20/L-20e005a.wav"
|
||||
[ 7, 2 ] = wave (0) : "./MITfull/elev-20/L-20e010a.wav"
|
||||
[ 7, 3 ] = wave (0) : "./MITfull/elev-20/L-20e015a.wav"
|
||||
[ 7, 4 ] = wave (0) : "./MITfull/elev-20/L-20e020a.wav"
|
||||
[ 7, 5 ] = wave (0) : "./MITfull/elev-20/L-20e025a.wav"
|
||||
[ 7, 6 ] = wave (0) : "./MITfull/elev-20/L-20e030a.wav"
|
||||
[ 7, 7 ] = wave (0) : "./MITfull/elev-20/L-20e035a.wav"
|
||||
[ 7, 8 ] = wave (0) : "./MITfull/elev-20/L-20e040a.wav"
|
||||
[ 7, 9 ] = wave (0) : "./MITfull/elev-20/L-20e045a.wav"
|
||||
[ 7, 10 ] = wave (0) : "./MITfull/elev-20/L-20e050a.wav"
|
||||
[ 7, 11 ] = wave (0) : "./MITfull/elev-20/L-20e055a.wav"
|
||||
[ 7, 12 ] = wave (0) : "./MITfull/elev-20/L-20e060a.wav"
|
||||
[ 7, 13 ] = wave (0) : "./MITfull/elev-20/L-20e065a.wav"
|
||||
[ 7, 14 ] = wave (0) : "./MITfull/elev-20/L-20e070a.wav"
|
||||
[ 7, 15 ] = wave (0) : "./MITfull/elev-20/L-20e075a.wav"
|
||||
[ 7, 16 ] = wave (0) : "./MITfull/elev-20/L-20e080a.wav"
|
||||
[ 7, 17 ] = wave (0) : "./MITfull/elev-20/L-20e085a.wav"
|
||||
[ 7, 18 ] = wave (0) : "./MITfull/elev-20/L-20e090a.wav"
|
||||
[ 7, 19 ] = wave (0) : "./MITfull/elev-20/L-20e095a.wav"
|
||||
[ 7, 20 ] = wave (0) : "./MITfull/elev-20/L-20e100a.wav"
|
||||
[ 7, 21 ] = wave (0) : "./MITfull/elev-20/L-20e105a.wav"
|
||||
[ 7, 22 ] = wave (0) : "./MITfull/elev-20/L-20e110a.wav"
|
||||
[ 7, 23 ] = wave (0) : "./MITfull/elev-20/L-20e115a.wav"
|
||||
[ 7, 24 ] = wave (0) : "./MITfull/elev-20/L-20e120a.wav"
|
||||
[ 7, 25 ] = wave (0) : "./MITfull/elev-20/L-20e125a.wav"
|
||||
[ 7, 26 ] = wave (0) : "./MITfull/elev-20/L-20e130a.wav"
|
||||
[ 7, 27 ] = wave (0) : "./MITfull/elev-20/L-20e135a.wav"
|
||||
[ 7, 28 ] = wave (0) : "./MITfull/elev-20/L-20e140a.wav"
|
||||
[ 7, 29 ] = wave (0) : "./MITfull/elev-20/L-20e145a.wav"
|
||||
[ 7, 30 ] = wave (0) : "./MITfull/elev-20/L-20e150a.wav"
|
||||
[ 7, 31 ] = wave (0) : "./MITfull/elev-20/L-20e155a.wav"
|
||||
[ 7, 32 ] = wave (0) : "./MITfull/elev-20/L-20e160a.wav"
|
||||
[ 7, 33 ] = wave (0) : "./MITfull/elev-20/L-20e165a.wav"
|
||||
[ 7, 34 ] = wave (0) : "./MITfull/elev-20/L-20e170a.wav"
|
||||
[ 7, 35 ] = wave (0) : "./MITfull/elev-20/L-20e175a.wav"
|
||||
[ 7, 36 ] = wave (0) : "./MITfull/elev-20/L-20e180a.wav"
|
||||
[ 7, 37 ] = wave (0) : "./MITfull/elev-20/L-20e185a.wav"
|
||||
[ 7, 38 ] = wave (0) : "./MITfull/elev-20/L-20e190a.wav"
|
||||
[ 7, 39 ] = wave (0) : "./MITfull/elev-20/L-20e195a.wav"
|
||||
[ 7, 40 ] = wave (0) : "./MITfull/elev-20/L-20e200a.wav"
|
||||
[ 7, 41 ] = wave (0) : "./MITfull/elev-20/L-20e205a.wav"
|
||||
[ 7, 42 ] = wave (0) : "./MITfull/elev-20/L-20e210a.wav"
|
||||
[ 7, 43 ] = wave (0) : "./MITfull/elev-20/L-20e215a.wav"
|
||||
[ 7, 44 ] = wave (0) : "./MITfull/elev-20/L-20e220a.wav"
|
||||
[ 7, 45 ] = wave (0) : "./MITfull/elev-20/L-20e225a.wav"
|
||||
[ 7, 46 ] = wave (0) : "./MITfull/elev-20/L-20e230a.wav"
|
||||
[ 7, 47 ] = wave (0) : "./MITfull/elev-20/L-20e235a.wav"
|
||||
[ 7, 48 ] = wave (0) : "./MITfull/elev-20/L-20e240a.wav"
|
||||
[ 7, 49 ] = wave (0) : "./MITfull/elev-20/L-20e245a.wav"
|
||||
[ 7, 50 ] = wave (0) : "./MITfull/elev-20/L-20e250a.wav"
|
||||
[ 7, 51 ] = wave (0) : "./MITfull/elev-20/L-20e255a.wav"
|
||||
[ 7, 52 ] = wave (0) : "./MITfull/elev-20/L-20e260a.wav"
|
||||
[ 7, 53 ] = wave (0) : "./MITfull/elev-20/L-20e265a.wav"
|
||||
[ 7, 54 ] = wave (0) : "./MITfull/elev-20/L-20e270a.wav"
|
||||
[ 7, 55 ] = wave (0) : "./MITfull/elev-20/L-20e275a.wav"
|
||||
[ 7, 56 ] = wave (0) : "./MITfull/elev-20/L-20e280a.wav"
|
||||
[ 7, 57 ] = wave (0) : "./MITfull/elev-20/L-20e285a.wav"
|
||||
[ 7, 58 ] = wave (0) : "./MITfull/elev-20/L-20e290a.wav"
|
||||
[ 7, 59 ] = wave (0) : "./MITfull/elev-20/L-20e295a.wav"
|
||||
[ 7, 60 ] = wave (0) : "./MITfull/elev-20/L-20e300a.wav"
|
||||
[ 7, 61 ] = wave (0) : "./MITfull/elev-20/L-20e305a.wav"
|
||||
[ 7, 62 ] = wave (0) : "./MITfull/elev-20/L-20e310a.wav"
|
||||
[ 7, 63 ] = wave (0) : "./MITfull/elev-20/L-20e315a.wav"
|
||||
[ 7, 64 ] = wave (0) : "./MITfull/elev-20/L-20e320a.wav"
|
||||
[ 7, 65 ] = wave (0) : "./MITfull/elev-20/L-20e325a.wav"
|
||||
[ 7, 66 ] = wave (0) : "./MITfull/elev-20/L-20e330a.wav"
|
||||
[ 7, 67 ] = wave (0) : "./MITfull/elev-20/L-20e335a.wav"
|
||||
[ 7, 68 ] = wave (0) : "./MITfull/elev-20/L-20e340a.wav"
|
||||
[ 7, 69 ] = wave (0) : "./MITfull/elev-20/L-20e345a.wav"
|
||||
[ 7, 70 ] = wave (0) : "./MITfull/elev-20/L-20e350a.wav"
|
||||
[ 7, 71 ] = wave (0) : "./MITfull/elev-20/L-20e355a.wav"
|
||||
|
||||
[ 8, 0 ] = wave (0) : "./MITfull/elev-10/L-10e000a.wav"
|
||||
[ 8, 1 ] = wave (0) : "./MITfull/elev-10/L-10e005a.wav"
|
||||
[ 8, 2 ] = wave (0) : "./MITfull/elev-10/L-10e010a.wav"
|
||||
[ 8, 3 ] = wave (0) : "./MITfull/elev-10/L-10e015a.wav"
|
||||
[ 8, 4 ] = wave (0) : "./MITfull/elev-10/L-10e020a.wav"
|
||||
[ 8, 5 ] = wave (0) : "./MITfull/elev-10/L-10e025a.wav"
|
||||
[ 8, 6 ] = wave (0) : "./MITfull/elev-10/L-10e030a.wav"
|
||||
[ 8, 7 ] = wave (0) : "./MITfull/elev-10/L-10e035a.wav"
|
||||
[ 8, 8 ] = wave (0) : "./MITfull/elev-10/L-10e040a.wav"
|
||||
[ 8, 9 ] = wave (0) : "./MITfull/elev-10/L-10e045a.wav"
|
||||
[ 8, 10 ] = wave (0) : "./MITfull/elev-10/L-10e050a.wav"
|
||||
[ 8, 11 ] = wave (0) : "./MITfull/elev-10/L-10e055a.wav"
|
||||
[ 8, 12 ] = wave (0) : "./MITfull/elev-10/L-10e060a.wav"
|
||||
[ 8, 13 ] = wave (0) : "./MITfull/elev-10/L-10e065a.wav"
|
||||
[ 8, 14 ] = wave (0) : "./MITfull/elev-10/L-10e070a.wav"
|
||||
[ 8, 15 ] = wave (0) : "./MITfull/elev-10/L-10e075a.wav"
|
||||
[ 8, 16 ] = wave (0) : "./MITfull/elev-10/L-10e080a.wav"
|
||||
[ 8, 17 ] = wave (0) : "./MITfull/elev-10/L-10e085a.wav"
|
||||
[ 8, 18 ] = wave (0) : "./MITfull/elev-10/L-10e090a.wav"
|
||||
[ 8, 19 ] = wave (0) : "./MITfull/elev-10/L-10e095a.wav"
|
||||
[ 8, 20 ] = wave (0) : "./MITfull/elev-10/L-10e100a.wav"
|
||||
[ 8, 21 ] = wave (0) : "./MITfull/elev-10/L-10e105a.wav"
|
||||
[ 8, 22 ] = wave (0) : "./MITfull/elev-10/L-10e110a.wav"
|
||||
[ 8, 23 ] = wave (0) : "./MITfull/elev-10/L-10e115a.wav"
|
||||
[ 8, 24 ] = wave (0) : "./MITfull/elev-10/L-10e120a.wav"
|
||||
[ 8, 25 ] = wave (0) : "./MITfull/elev-10/L-10e125a.wav"
|
||||
[ 8, 26 ] = wave (0) : "./MITfull/elev-10/L-10e130a.wav"
|
||||
[ 8, 27 ] = wave (0) : "./MITfull/elev-10/L-10e135a.wav"
|
||||
[ 8, 28 ] = wave (0) : "./MITfull/elev-10/L-10e140a.wav"
|
||||
[ 8, 29 ] = wave (0) : "./MITfull/elev-10/L-10e145a.wav"
|
||||
[ 8, 30 ] = wave (0) : "./MITfull/elev-10/L-10e150a.wav"
|
||||
[ 8, 31 ] = wave (0) : "./MITfull/elev-10/L-10e155a.wav"
|
||||
[ 8, 32 ] = wave (0) : "./MITfull/elev-10/L-10e160a.wav"
|
||||
[ 8, 33 ] = wave (0) : "./MITfull/elev-10/L-10e165a.wav"
|
||||
[ 8, 34 ] = wave (0) : "./MITfull/elev-10/L-10e170a.wav"
|
||||
[ 8, 35 ] = wave (0) : "./MITfull/elev-10/L-10e175a.wav"
|
||||
[ 8, 36 ] = wave (0) : "./MITfull/elev-10/L-10e180a.wav"
|
||||
[ 8, 37 ] = wave (0) : "./MITfull/elev-10/L-10e185a.wav"
|
||||
[ 8, 38 ] = wave (0) : "./MITfull/elev-10/L-10e190a.wav"
|
||||
[ 8, 39 ] = wave (0) : "./MITfull/elev-10/L-10e195a.wav"
|
||||
[ 8, 40 ] = wave (0) : "./MITfull/elev-10/L-10e200a.wav"
|
||||
[ 8, 41 ] = wave (0) : "./MITfull/elev-10/L-10e205a.wav"
|
||||
[ 8, 42 ] = wave (0) : "./MITfull/elev-10/L-10e210a.wav"
|
||||
[ 8, 43 ] = wave (0) : "./MITfull/elev-10/L-10e215a.wav"
|
||||
[ 8, 44 ] = wave (0) : "./MITfull/elev-10/L-10e220a.wav"
|
||||
[ 8, 45 ] = wave (0) : "./MITfull/elev-10/L-10e225a.wav"
|
||||
[ 8, 46 ] = wave (0) : "./MITfull/elev-10/L-10e230a.wav"
|
||||
[ 8, 47 ] = wave (0) : "./MITfull/elev-10/L-10e235a.wav"
|
||||
[ 8, 48 ] = wave (0) : "./MITfull/elev-10/L-10e240a.wav"
|
||||
[ 8, 49 ] = wave (0) : "./MITfull/elev-10/L-10e245a.wav"
|
||||
[ 8, 50 ] = wave (0) : "./MITfull/elev-10/L-10e250a.wav"
|
||||
[ 8, 51 ] = wave (0) : "./MITfull/elev-10/L-10e255a.wav"
|
||||
[ 8, 52 ] = wave (0) : "./MITfull/elev-10/L-10e260a.wav"
|
||||
[ 8, 53 ] = wave (0) : "./MITfull/elev-10/L-10e265a.wav"
|
||||
[ 8, 54 ] = wave (0) : "./MITfull/elev-10/L-10e270a.wav"
|
||||
[ 8, 55 ] = wave (0) : "./MITfull/elev-10/L-10e275a.wav"
|
||||
[ 8, 56 ] = wave (0) : "./MITfull/elev-10/L-10e280a.wav"
|
||||
[ 8, 57 ] = wave (0) : "./MITfull/elev-10/L-10e285a.wav"
|
||||
[ 8, 58 ] = wave (0) : "./MITfull/elev-10/L-10e290a.wav"
|
||||
[ 8, 59 ] = wave (0) : "./MITfull/elev-10/L-10e295a.wav"
|
||||
[ 8, 60 ] = wave (0) : "./MITfull/elev-10/L-10e300a.wav"
|
||||
[ 8, 61 ] = wave (0) : "./MITfull/elev-10/L-10e305a.wav"
|
||||
[ 8, 62 ] = wave (0) : "./MITfull/elev-10/L-10e310a.wav"
|
||||
[ 8, 63 ] = wave (0) : "./MITfull/elev-10/L-10e315a.wav"
|
||||
[ 8, 64 ] = wave (0) : "./MITfull/elev-10/L-10e320a.wav"
|
||||
[ 8, 65 ] = wave (0) : "./MITfull/elev-10/L-10e325a.wav"
|
||||
[ 8, 66 ] = wave (0) : "./MITfull/elev-10/L-10e330a.wav"
|
||||
[ 8, 67 ] = wave (0) : "./MITfull/elev-10/L-10e335a.wav"
|
||||
[ 8, 68 ] = wave (0) : "./MITfull/elev-10/L-10e340a.wav"
|
||||
[ 8, 69 ] = wave (0) : "./MITfull/elev-10/L-10e345a.wav"
|
||||
[ 8, 70 ] = wave (0) : "./MITfull/elev-10/L-10e350a.wav"
|
||||
[ 8, 71 ] = wave (0) : "./MITfull/elev-10/L-10e355a.wav"
|
||||
|
||||
[ 9, 0 ] = wave (0) : "./MITfull/elev0/L0e000a.wav"
|
||||
[ 9, 1 ] = wave (0) : "./MITfull/elev0/L0e005a.wav"
|
||||
[ 9, 2 ] = wave (0) : "./MITfull/elev0/L0e010a.wav"
|
||||
[ 9, 3 ] = wave (0) : "./MITfull/elev0/L0e015a.wav"
|
||||
[ 9, 4 ] = wave (0) : "./MITfull/elev0/L0e020a.wav"
|
||||
[ 9, 5 ] = wave (0) : "./MITfull/elev0/L0e025a.wav"
|
||||
[ 9, 6 ] = wave (0) : "./MITfull/elev0/L0e030a.wav"
|
||||
[ 9, 7 ] = wave (0) : "./MITfull/elev0/L0e035a.wav"
|
||||
[ 9, 8 ] = wave (0) : "./MITfull/elev0/L0e040a.wav"
|
||||
[ 9, 9 ] = wave (0) : "./MITfull/elev0/L0e045a.wav"
|
||||
[ 9, 10 ] = wave (0) : "./MITfull/elev0/L0e050a.wav"
|
||||
[ 9, 11 ] = wave (0) : "./MITfull/elev0/L0e055a.wav"
|
||||
[ 9, 12 ] = wave (0) : "./MITfull/elev0/L0e060a.wav"
|
||||
[ 9, 13 ] = wave (0) : "./MITfull/elev0/L0e065a.wav"
|
||||
[ 9, 14 ] = wave (0) : "./MITfull/elev0/L0e070a.wav"
|
||||
[ 9, 15 ] = wave (0) : "./MITfull/elev0/L0e075a.wav"
|
||||
[ 9, 16 ] = wave (0) : "./MITfull/elev0/L0e080a.wav"
|
||||
[ 9, 17 ] = wave (0) : "./MITfull/elev0/L0e085a.wav"
|
||||
[ 9, 18 ] = wave (0) : "./MITfull/elev0/L0e090a.wav"
|
||||
[ 9, 19 ] = wave (0) : "./MITfull/elev0/L0e095a.wav"
|
||||
[ 9, 20 ] = wave (0) : "./MITfull/elev0/L0e100a.wav"
|
||||
[ 9, 21 ] = wave (0) : "./MITfull/elev0/L0e105a.wav"
|
||||
[ 9, 22 ] = wave (0) : "./MITfull/elev0/L0e110a.wav"
|
||||
[ 9, 23 ] = wave (0) : "./MITfull/elev0/L0e115a.wav"
|
||||
[ 9, 24 ] = wave (0) : "./MITfull/elev0/L0e120a.wav"
|
||||
[ 9, 25 ] = wave (0) : "./MITfull/elev0/L0e125a.wav"
|
||||
[ 9, 26 ] = wave (0) : "./MITfull/elev0/L0e130a.wav"
|
||||
[ 9, 27 ] = wave (0) : "./MITfull/elev0/L0e135a.wav"
|
||||
[ 9, 28 ] = wave (0) : "./MITfull/elev0/L0e140a.wav"
|
||||
[ 9, 29 ] = wave (0) : "./MITfull/elev0/L0e145a.wav"
|
||||
[ 9, 30 ] = wave (0) : "./MITfull/elev0/L0e150a.wav"
|
||||
[ 9, 31 ] = wave (0) : "./MITfull/elev0/L0e155a.wav"
|
||||
[ 9, 32 ] = wave (0) : "./MITfull/elev0/L0e160a.wav"
|
||||
[ 9, 33 ] = wave (0) : "./MITfull/elev0/L0e165a.wav"
|
||||
[ 9, 34 ] = wave (0) : "./MITfull/elev0/L0e170a.wav"
|
||||
[ 9, 35 ] = wave (0) : "./MITfull/elev0/L0e175a.wav"
|
||||
[ 9, 36 ] = wave (0) : "./MITfull/elev0/L0e180a.wav"
|
||||
[ 9, 37 ] = wave (0) : "./MITfull/elev0/L0e185a.wav"
|
||||
[ 9, 38 ] = wave (0) : "./MITfull/elev0/L0e190a.wav"
|
||||
[ 9, 39 ] = wave (0) : "./MITfull/elev0/L0e195a.wav"
|
||||
[ 9, 40 ] = wave (0) : "./MITfull/elev0/L0e200a.wav"
|
||||
[ 9, 41 ] = wave (0) : "./MITfull/elev0/L0e205a.wav"
|
||||
[ 9, 42 ] = wave (0) : "./MITfull/elev0/L0e210a.wav"
|
||||
[ 9, 43 ] = wave (0) : "./MITfull/elev0/L0e215a.wav"
|
||||
[ 9, 44 ] = wave (0) : "./MITfull/elev0/L0e220a.wav"
|
||||
[ 9, 45 ] = wave (0) : "./MITfull/elev0/L0e225a.wav"
|
||||
[ 9, 46 ] = wave (0) : "./MITfull/elev0/L0e230a.wav"
|
||||
[ 9, 47 ] = wave (0) : "./MITfull/elev0/L0e235a.wav"
|
||||
[ 9, 48 ] = wave (0) : "./MITfull/elev0/L0e240a.wav"
|
||||
[ 9, 49 ] = wave (0) : "./MITfull/elev0/L0e245a.wav"
|
||||
[ 9, 50 ] = wave (0) : "./MITfull/elev0/L0e250a.wav"
|
||||
[ 9, 51 ] = wave (0) : "./MITfull/elev0/L0e255a.wav"
|
||||
[ 9, 52 ] = wave (0) : "./MITfull/elev0/L0e260a.wav"
|
||||
[ 9, 53 ] = wave (0) : "./MITfull/elev0/L0e265a.wav"
|
||||
[ 9, 54 ] = wave (0) : "./MITfull/elev0/L0e270a.wav"
|
||||
[ 9, 55 ] = wave (0) : "./MITfull/elev0/L0e275a.wav"
|
||||
[ 9, 56 ] = wave (0) : "./MITfull/elev0/L0e280a.wav"
|
||||
[ 9, 57 ] = wave (0) : "./MITfull/elev0/L0e285a.wav"
|
||||
[ 9, 58 ] = wave (0) : "./MITfull/elev0/L0e290a.wav"
|
||||
[ 9, 59 ] = wave (0) : "./MITfull/elev0/L0e295a.wav"
|
||||
[ 9, 60 ] = wave (0) : "./MITfull/elev0/L0e300a.wav"
|
||||
[ 9, 61 ] = wave (0) : "./MITfull/elev0/L0e305a.wav"
|
||||
[ 9, 62 ] = wave (0) : "./MITfull/elev0/L0e310a.wav"
|
||||
[ 9, 63 ] = wave (0) : "./MITfull/elev0/L0e315a.wav"
|
||||
[ 9, 64 ] = wave (0) : "./MITfull/elev0/L0e320a.wav"
|
||||
[ 9, 65 ] = wave (0) : "./MITfull/elev0/L0e325a.wav"
|
||||
[ 9, 66 ] = wave (0) : "./MITfull/elev0/L0e330a.wav"
|
||||
[ 9, 67 ] = wave (0) : "./MITfull/elev0/L0e335a.wav"
|
||||
[ 9, 68 ] = wave (0) : "./MITfull/elev0/L0e340a.wav"
|
||||
[ 9, 69 ] = wave (0) : "./MITfull/elev0/L0e345a.wav"
|
||||
[ 9, 70 ] = wave (0) : "./MITfull/elev0/L0e350a.wav"
|
||||
[ 9, 71 ] = wave (0) : "./MITfull/elev0/L0e355a.wav"
|
||||
|
||||
[ 10, 0 ] = wave (0) : "./MITfull/elev10/L10e000a.wav"
|
||||
[ 10, 1 ] = wave (0) : "./MITfull/elev10/L10e005a.wav"
|
||||
[ 10, 2 ] = wave (0) : "./MITfull/elev10/L10e010a.wav"
|
||||
[ 10, 3 ] = wave (0) : "./MITfull/elev10/L10e015a.wav"
|
||||
[ 10, 4 ] = wave (0) : "./MITfull/elev10/L10e020a.wav"
|
||||
[ 10, 5 ] = wave (0) : "./MITfull/elev10/L10e025a.wav"
|
||||
[ 10, 6 ] = wave (0) : "./MITfull/elev10/L10e030a.wav"
|
||||
[ 10, 7 ] = wave (0) : "./MITfull/elev10/L10e035a.wav"
|
||||
[ 10, 8 ] = wave (0) : "./MITfull/elev10/L10e040a.wav"
|
||||
[ 10, 9 ] = wave (0) : "./MITfull/elev10/L10e045a.wav"
|
||||
[ 10, 10 ] = wave (0) : "./MITfull/elev10/L10e050a.wav"
|
||||
[ 10, 11 ] = wave (0) : "./MITfull/elev10/L10e055a.wav"
|
||||
[ 10, 12 ] = wave (0) : "./MITfull/elev10/L10e060a.wav"
|
||||
[ 10, 13 ] = wave (0) : "./MITfull/elev10/L10e065a.wav"
|
||||
[ 10, 14 ] = wave (0) : "./MITfull/elev10/L10e070a.wav"
|
||||
[ 10, 15 ] = wave (0) : "./MITfull/elev10/L10e075a.wav"
|
||||
[ 10, 16 ] = wave (0) : "./MITfull/elev10/L10e080a.wav"
|
||||
[ 10, 17 ] = wave (0) : "./MITfull/elev10/L10e085a.wav"
|
||||
[ 10, 18 ] = wave (0) : "./MITfull/elev10/L10e090a.wav"
|
||||
[ 10, 19 ] = wave (0) : "./MITfull/elev10/L10e095a.wav"
|
||||
[ 10, 20 ] = wave (0) : "./MITfull/elev10/L10e100a.wav"
|
||||
[ 10, 21 ] = wave (0) : "./MITfull/elev10/L10e105a.wav"
|
||||
[ 10, 22 ] = wave (0) : "./MITfull/elev10/L10e110a.wav"
|
||||
[ 10, 23 ] = wave (0) : "./MITfull/elev10/L10e115a.wav"
|
||||
[ 10, 24 ] = wave (0) : "./MITfull/elev10/L10e120a.wav"
|
||||
[ 10, 25 ] = wave (0) : "./MITfull/elev10/L10e125a.wav"
|
||||
[ 10, 26 ] = wave (0) : "./MITfull/elev10/L10e130a.wav"
|
||||
[ 10, 27 ] = wave (0) : "./MITfull/elev10/L10e135a.wav"
|
||||
[ 10, 28 ] = wave (0) : "./MITfull/elev10/L10e140a.wav"
|
||||
[ 10, 29 ] = wave (0) : "./MITfull/elev10/L10e145a.wav"
|
||||
[ 10, 30 ] = wave (0) : "./MITfull/elev10/L10e150a.wav"
|
||||
[ 10, 31 ] = wave (0) : "./MITfull/elev10/L10e155a.wav"
|
||||
[ 10, 32 ] = wave (0) : "./MITfull/elev10/L10e160a.wav"
|
||||
[ 10, 33 ] = wave (0) : "./MITfull/elev10/L10e165a.wav"
|
||||
[ 10, 34 ] = wave (0) : "./MITfull/elev10/L10e170a.wav"
|
||||
[ 10, 35 ] = wave (0) : "./MITfull/elev10/L10e175a.wav"
|
||||
[ 10, 36 ] = wave (0) : "./MITfull/elev10/L10e180a.wav"
|
||||
[ 10, 37 ] = wave (0) : "./MITfull/elev10/L10e185a.wav"
|
||||
[ 10, 38 ] = wave (0) : "./MITfull/elev10/L10e190a.wav"
|
||||
[ 10, 39 ] = wave (0) : "./MITfull/elev10/L10e195a.wav"
|
||||
[ 10, 40 ] = wave (0) : "./MITfull/elev10/L10e200a.wav"
|
||||
[ 10, 41 ] = wave (0) : "./MITfull/elev10/L10e205a.wav"
|
||||
[ 10, 42 ] = wave (0) : "./MITfull/elev10/L10e210a.wav"
|
||||
[ 10, 43 ] = wave (0) : "./MITfull/elev10/L10e215a.wav"
|
||||
[ 10, 44 ] = wave (0) : "./MITfull/elev10/L10e220a.wav"
|
||||
[ 10, 45 ] = wave (0) : "./MITfull/elev10/L10e225a.wav"
|
||||
[ 10, 46 ] = wave (0) : "./MITfull/elev10/L10e230a.wav"
|
||||
[ 10, 47 ] = wave (0) : "./MITfull/elev10/L10e235a.wav"
|
||||
[ 10, 48 ] = wave (0) : "./MITfull/elev10/L10e240a.wav"
|
||||
[ 10, 49 ] = wave (0) : "./MITfull/elev10/L10e245a.wav"
|
||||
[ 10, 50 ] = wave (0) : "./MITfull/elev10/L10e250a.wav"
|
||||
[ 10, 51 ] = wave (0) : "./MITfull/elev10/L10e255a.wav"
|
||||
[ 10, 52 ] = wave (0) : "./MITfull/elev10/L10e260a.wav"
|
||||
[ 10, 53 ] = wave (0) : "./MITfull/elev10/L10e265a.wav"
|
||||
[ 10, 54 ] = wave (0) : "./MITfull/elev10/L10e270a.wav"
|
||||
[ 10, 55 ] = wave (0) : "./MITfull/elev10/L10e275a.wav"
|
||||
[ 10, 56 ] = wave (0) : "./MITfull/elev10/L10e280a.wav"
|
||||
[ 10, 57 ] = wave (0) : "./MITfull/elev10/L10e285a.wav"
|
||||
[ 10, 58 ] = wave (0) : "./MITfull/elev10/L10e290a.wav"
|
||||
[ 10, 59 ] = wave (0) : "./MITfull/elev10/L10e295a.wav"
|
||||
[ 10, 60 ] = wave (0) : "./MITfull/elev10/L10e300a.wav"
|
||||
[ 10, 61 ] = wave (0) : "./MITfull/elev10/L10e305a.wav"
|
||||
[ 10, 62 ] = wave (0) : "./MITfull/elev10/L10e310a.wav"
|
||||
[ 10, 63 ] = wave (0) : "./MITfull/elev10/L10e315a.wav"
|
||||
[ 10, 64 ] = wave (0) : "./MITfull/elev10/L10e320a.wav"
|
||||
[ 10, 65 ] = wave (0) : "./MITfull/elev10/L10e325a.wav"
|
||||
[ 10, 66 ] = wave (0) : "./MITfull/elev10/L10e330a.wav"
|
||||
[ 10, 67 ] = wave (0) : "./MITfull/elev10/L10e335a.wav"
|
||||
[ 10, 68 ] = wave (0) : "./MITfull/elev10/L10e340a.wav"
|
||||
[ 10, 69 ] = wave (0) : "./MITfull/elev10/L10e345a.wav"
|
||||
[ 10, 70 ] = wave (0) : "./MITfull/elev10/L10e350a.wav"
|
||||
[ 10, 71 ] = wave (0) : "./MITfull/elev10/L10e355a.wav"
|
||||
|
||||
[ 11, 0 ] = wave (0) : "./MITfull/elev20/L20e000a.wav"
|
||||
[ 11, 1 ] = wave (0) : "./MITfull/elev20/L20e005a.wav"
|
||||
[ 11, 2 ] = wave (0) : "./MITfull/elev20/L20e010a.wav"
|
||||
[ 11, 3 ] = wave (0) : "./MITfull/elev20/L20e015a.wav"
|
||||
[ 11, 4 ] = wave (0) : "./MITfull/elev20/L20e020a.wav"
|
||||
[ 11, 5 ] = wave (0) : "./MITfull/elev20/L20e025a.wav"
|
||||
[ 11, 6 ] = wave (0) : "./MITfull/elev20/L20e030a.wav"
|
||||
[ 11, 7 ] = wave (0) : "./MITfull/elev20/L20e035a.wav"
|
||||
[ 11, 8 ] = wave (0) : "./MITfull/elev20/L20e040a.wav"
|
||||
[ 11, 9 ] = wave (0) : "./MITfull/elev20/L20e045a.wav"
|
||||
[ 11, 10 ] = wave (0) : "./MITfull/elev20/L20e050a.wav"
|
||||
[ 11, 11 ] = wave (0) : "./MITfull/elev20/L20e055a.wav"
|
||||
[ 11, 12 ] = wave (0) : "./MITfull/elev20/L20e060a.wav"
|
||||
[ 11, 13 ] = wave (0) : "./MITfull/elev20/L20e065a.wav"
|
||||
[ 11, 14 ] = wave (0) : "./MITfull/elev20/L20e070a.wav"
|
||||
[ 11, 15 ] = wave (0) : "./MITfull/elev20/L20e075a.wav"
|
||||
[ 11, 16 ] = wave (0) : "./MITfull/elev20/L20e080a.wav"
|
||||
[ 11, 17 ] = wave (0) : "./MITfull/elev20/L20e085a.wav"
|
||||
[ 11, 18 ] = wave (0) : "./MITfull/elev20/L20e090a.wav"
|
||||
[ 11, 19 ] = wave (0) : "./MITfull/elev20/L20e095a.wav"
|
||||
[ 11, 20 ] = wave (0) : "./MITfull/elev20/L20e100a.wav"
|
||||
[ 11, 21 ] = wave (0) : "./MITfull/elev20/L20e105a.wav"
|
||||
[ 11, 22 ] = wave (0) : "./MITfull/elev20/L20e110a.wav"
|
||||
[ 11, 23 ] = wave (0) : "./MITfull/elev20/L20e115a.wav"
|
||||
[ 11, 24 ] = wave (0) : "./MITfull/elev20/L20e120a.wav"
|
||||
[ 11, 25 ] = wave (0) : "./MITfull/elev20/L20e125a.wav"
|
||||
[ 11, 26 ] = wave (0) : "./MITfull/elev20/L20e130a.wav"
|
||||
[ 11, 27 ] = wave (0) : "./MITfull/elev20/L20e135a.wav"
|
||||
[ 11, 28 ] = wave (0) : "./MITfull/elev20/L20e140a.wav"
|
||||
[ 11, 29 ] = wave (0) : "./MITfull/elev20/L20e145a.wav"
|
||||
[ 11, 30 ] = wave (0) : "./MITfull/elev20/L20e150a.wav"
|
||||
[ 11, 31 ] = wave (0) : "./MITfull/elev20/L20e155a.wav"
|
||||
[ 11, 32 ] = wave (0) : "./MITfull/elev20/L20e160a.wav"
|
||||
[ 11, 33 ] = wave (0) : "./MITfull/elev20/L20e165a.wav"
|
||||
[ 11, 34 ] = wave (0) : "./MITfull/elev20/L20e170a.wav"
|
||||
[ 11, 35 ] = wave (0) : "./MITfull/elev20/L20e175a.wav"
|
||||
[ 11, 36 ] = wave (0) : "./MITfull/elev20/L20e180a.wav"
|
||||
[ 11, 37 ] = wave (0) : "./MITfull/elev20/L20e185a.wav"
|
||||
[ 11, 38 ] = wave (0) : "./MITfull/elev20/L20e190a.wav"
|
||||
[ 11, 39 ] = wave (0) : "./MITfull/elev20/L20e195a.wav"
|
||||
[ 11, 40 ] = wave (0) : "./MITfull/elev20/L20e200a.wav"
|
||||
[ 11, 41 ] = wave (0) : "./MITfull/elev20/L20e205a.wav"
|
||||
[ 11, 42 ] = wave (0) : "./MITfull/elev20/L20e210a.wav"
|
||||
[ 11, 43 ] = wave (0) : "./MITfull/elev20/L20e215a.wav"
|
||||
[ 11, 44 ] = wave (0) : "./MITfull/elev20/L20e220a.wav"
|
||||
[ 11, 45 ] = wave (0) : "./MITfull/elev20/L20e225a.wav"
|
||||
[ 11, 46 ] = wave (0) : "./MITfull/elev20/L20e230a.wav"
|
||||
[ 11, 47 ] = wave (0) : "./MITfull/elev20/L20e235a.wav"
|
||||
[ 11, 48 ] = wave (0) : "./MITfull/elev20/L20e240a.wav"
|
||||
[ 11, 49 ] = wave (0) : "./MITfull/elev20/L20e245a.wav"
|
||||
[ 11, 50 ] = wave (0) : "./MITfull/elev20/L20e250a.wav"
|
||||
[ 11, 51 ] = wave (0) : "./MITfull/elev20/L20e255a.wav"
|
||||
[ 11, 52 ] = wave (0) : "./MITfull/elev20/L20e260a.wav"
|
||||
[ 11, 53 ] = wave (0) : "./MITfull/elev20/L20e265a.wav"
|
||||
[ 11, 54 ] = wave (0) : "./MITfull/elev20/L20e270a.wav"
|
||||
[ 11, 55 ] = wave (0) : "./MITfull/elev20/L20e275a.wav"
|
||||
[ 11, 56 ] = wave (0) : "./MITfull/elev20/L20e280a.wav"
|
||||
[ 11, 57 ] = wave (0) : "./MITfull/elev20/L20e285a.wav"
|
||||
[ 11, 58 ] = wave (0) : "./MITfull/elev20/L20e290a.wav"
|
||||
[ 11, 59 ] = wave (0) : "./MITfull/elev20/L20e295a.wav"
|
||||
[ 11, 60 ] = wave (0) : "./MITfull/elev20/L20e300a.wav"
|
||||
[ 11, 61 ] = wave (0) : "./MITfull/elev20/L20e305a.wav"
|
||||
[ 11, 62 ] = wave (0) : "./MITfull/elev20/L20e310a.wav"
|
||||
[ 11, 63 ] = wave (0) : "./MITfull/elev20/L20e315a.wav"
|
||||
[ 11, 64 ] = wave (0) : "./MITfull/elev20/L20e320a.wav"
|
||||
[ 11, 65 ] = wave (0) : "./MITfull/elev20/L20e325a.wav"
|
||||
[ 11, 66 ] = wave (0) : "./MITfull/elev20/L20e330a.wav"
|
||||
[ 11, 67 ] = wave (0) : "./MITfull/elev20/L20e335a.wav"
|
||||
[ 11, 68 ] = wave (0) : "./MITfull/elev20/L20e340a.wav"
|
||||
[ 11, 69 ] = wave (0) : "./MITfull/elev20/L20e345a.wav"
|
||||
[ 11, 70 ] = wave (0) : "./MITfull/elev20/L20e350a.wav"
|
||||
[ 11, 71 ] = wave (0) : "./MITfull/elev20/L20e355a.wav"
|
||||
|
||||
[ 12, 0 ] = wave (0) : "./MITfull/elev30/L30e000a.wav"
|
||||
[ 12, 1 ] = wave (0) : "./MITfull/elev30/L30e006a.wav"
|
||||
[ 12, 2 ] = wave (0) : "./MITfull/elev30/L30e012a.wav"
|
||||
[ 12, 3 ] = wave (0) : "./MITfull/elev30/L30e018a.wav"
|
||||
[ 12, 4 ] = wave (0) : "./MITfull/elev30/L30e024a.wav"
|
||||
[ 12, 5 ] = wave (0) : "./MITfull/elev30/L30e030a.wav"
|
||||
[ 12, 6 ] = wave (0) : "./MITfull/elev30/L30e036a.wav"
|
||||
[ 12, 7 ] = wave (0) : "./MITfull/elev30/L30e042a.wav"
|
||||
[ 12, 8 ] = wave (0) : "./MITfull/elev30/L30e048a.wav"
|
||||
[ 12, 9 ] = wave (0) : "./MITfull/elev30/L30e054a.wav"
|
||||
[ 12, 10 ] = wave (0) : "./MITfull/elev30/L30e060a.wav"
|
||||
[ 12, 11 ] = wave (0) : "./MITfull/elev30/L30e066a.wav"
|
||||
[ 12, 12 ] = wave (0) : "./MITfull/elev30/L30e072a.wav"
|
||||
[ 12, 13 ] = wave (0) : "./MITfull/elev30/L30e078a.wav"
|
||||
[ 12, 14 ] = wave (0) : "./MITfull/elev30/L30e084a.wav"
|
||||
[ 12, 15 ] = wave (0) : "./MITfull/elev30/L30e090a.wav"
|
||||
[ 12, 16 ] = wave (0) : "./MITfull/elev30/L30e096a.wav"
|
||||
[ 12, 17 ] = wave (0) : "./MITfull/elev30/L30e102a.wav"
|
||||
[ 12, 18 ] = wave (0) : "./MITfull/elev30/L30e108a.wav"
|
||||
[ 12, 19 ] = wave (0) : "./MITfull/elev30/L30e114a.wav"
|
||||
[ 12, 20 ] = wave (0) : "./MITfull/elev30/L30e120a.wav"
|
||||
[ 12, 21 ] = wave (0) : "./MITfull/elev30/L30e126a.wav"
|
||||
[ 12, 22 ] = wave (0) : "./MITfull/elev30/L30e132a.wav"
|
||||
[ 12, 23 ] = wave (0) : "./MITfull/elev30/L30e138a.wav"
|
||||
[ 12, 24 ] = wave (0) : "./MITfull/elev30/L30e144a.wav"
|
||||
[ 12, 25 ] = wave (0) : "./MITfull/elev30/L30e150a.wav"
|
||||
[ 12, 26 ] = wave (0) : "./MITfull/elev30/L30e156a.wav"
|
||||
[ 12, 27 ] = wave (0) : "./MITfull/elev30/L30e162a.wav"
|
||||
[ 12, 28 ] = wave (0) : "./MITfull/elev30/L30e168a.wav"
|
||||
[ 12, 29 ] = wave (0) : "./MITfull/elev30/L30e174a.wav"
|
||||
[ 12, 30 ] = wave (0) : "./MITfull/elev30/L30e180a.wav"
|
||||
[ 12, 31 ] = wave (0) : "./MITfull/elev30/L30e186a.wav"
|
||||
[ 12, 32 ] = wave (0) : "./MITfull/elev30/L30e192a.wav"
|
||||
[ 12, 33 ] = wave (0) : "./MITfull/elev30/L30e198a.wav"
|
||||
[ 12, 34 ] = wave (0) : "./MITfull/elev30/L30e204a.wav"
|
||||
[ 12, 35 ] = wave (0) : "./MITfull/elev30/L30e210a.wav"
|
||||
[ 12, 36 ] = wave (0) : "./MITfull/elev30/L30e216a.wav"
|
||||
[ 12, 37 ] = wave (0) : "./MITfull/elev30/L30e222a.wav"
|
||||
[ 12, 38 ] = wave (0) : "./MITfull/elev30/L30e228a.wav"
|
||||
[ 12, 39 ] = wave (0) : "./MITfull/elev30/L30e234a.wav"
|
||||
[ 12, 40 ] = wave (0) : "./MITfull/elev30/L30e240a.wav"
|
||||
[ 12, 41 ] = wave (0) : "./MITfull/elev30/L30e246a.wav"
|
||||
[ 12, 42 ] = wave (0) : "./MITfull/elev30/L30e252a.wav"
|
||||
[ 12, 43 ] = wave (0) : "./MITfull/elev30/L30e258a.wav"
|
||||
[ 12, 44 ] = wave (0) : "./MITfull/elev30/L30e264a.wav"
|
||||
[ 12, 45 ] = wave (0) : "./MITfull/elev30/L30e270a.wav"
|
||||
[ 12, 46 ] = wave (0) : "./MITfull/elev30/L30e276a.wav"
|
||||
[ 12, 47 ] = wave (0) : "./MITfull/elev30/L30e282a.wav"
|
||||
[ 12, 48 ] = wave (0) : "./MITfull/elev30/L30e288a.wav"
|
||||
[ 12, 49 ] = wave (0) : "./MITfull/elev30/L30e294a.wav"
|
||||
[ 12, 50 ] = wave (0) : "./MITfull/elev30/L30e300a.wav"
|
||||
[ 12, 51 ] = wave (0) : "./MITfull/elev30/L30e306a.wav"
|
||||
[ 12, 52 ] = wave (0) : "./MITfull/elev30/L30e312a.wav"
|
||||
[ 12, 53 ] = wave (0) : "./MITfull/elev30/L30e318a.wav"
|
||||
[ 12, 54 ] = wave (0) : "./MITfull/elev30/L30e324a.wav"
|
||||
[ 12, 55 ] = wave (0) : "./MITfull/elev30/L30e330a.wav"
|
||||
[ 12, 56 ] = wave (0) : "./MITfull/elev30/L30e336a.wav"
|
||||
[ 12, 57 ] = wave (0) : "./MITfull/elev30/L30e342a.wav"
|
||||
[ 12, 58 ] = wave (0) : "./MITfull/elev30/L30e348a.wav"
|
||||
[ 12, 59 ] = wave (0) : "./MITfull/elev30/L30e354a.wav"
|
||||
|
||||
[ 13, 0 ] = wave (0) : "./MITfull/elev40/L40e000a.wav"
|
||||
[ 13, 1 ] = wave (0) : "./MITfull/elev40/L40e006a.wav"
|
||||
[ 13, 2 ] = wave (0) : "./MITfull/elev40/L40e013a.wav"
|
||||
[ 13, 3 ] = wave (0) : "./MITfull/elev40/L40e019a.wav"
|
||||
[ 13, 4 ] = wave (0) : "./MITfull/elev40/L40e026a.wav"
|
||||
[ 13, 5 ] = wave (0) : "./MITfull/elev40/L40e032a.wav"
|
||||
[ 13, 6 ] = wave (0) : "./MITfull/elev40/L40e039a.wav"
|
||||
[ 13, 7 ] = wave (0) : "./MITfull/elev40/L40e045a.wav"
|
||||
[ 13, 8 ] = wave (0) : "./MITfull/elev40/L40e051a.wav"
|
||||
[ 13, 9 ] = wave (0) : "./MITfull/elev40/L40e058a.wav"
|
||||
[ 13, 10 ] = wave (0) : "./MITfull/elev40/L40e064a.wav"
|
||||
[ 13, 11 ] = wave (0) : "./MITfull/elev40/L40e071a.wav"
|
||||
[ 13, 12 ] = wave (0) : "./MITfull/elev40/L40e077a.wav"
|
||||
[ 13, 13 ] = wave (0) : "./MITfull/elev40/L40e084a.wav"
|
||||
[ 13, 14 ] = wave (0) : "./MITfull/elev40/L40e090a.wav"
|
||||
[ 13, 15 ] = wave (0) : "./MITfull/elev40/L40e096a.wav"
|
||||
[ 13, 16 ] = wave (0) : "./MITfull/elev40/L40e103a.wav"
|
||||
[ 13, 17 ] = wave (0) : "./MITfull/elev40/L40e109a.wav"
|
||||
[ 13, 18 ] = wave (0) : "./MITfull/elev40/L40e116a.wav"
|
||||
[ 13, 19 ] = wave (0) : "./MITfull/elev40/L40e122a.wav"
|
||||
[ 13, 20 ] = wave (0) : "./MITfull/elev40/L40e129a.wav"
|
||||
[ 13, 21 ] = wave (0) : "./MITfull/elev40/L40e135a.wav"
|
||||
[ 13, 22 ] = wave (0) : "./MITfull/elev40/L40e141a.wav"
|
||||
[ 13, 23 ] = wave (0) : "./MITfull/elev40/L40e148a.wav"
|
||||
[ 13, 24 ] = wave (0) : "./MITfull/elev40/L40e154a.wav"
|
||||
[ 13, 25 ] = wave (0) : "./MITfull/elev40/L40e161a.wav"
|
||||
[ 13, 26 ] = wave (0) : "./MITfull/elev40/L40e167a.wav"
|
||||
[ 13, 27 ] = wave (0) : "./MITfull/elev40/L40e174a.wav"
|
||||
[ 13, 28 ] = wave (0) : "./MITfull/elev40/L40e180a.wav"
|
||||
[ 13, 29 ] = wave (0) : "./MITfull/elev40/L40e186a.wav"
|
||||
[ 13, 30 ] = wave (0) : "./MITfull/elev40/L40e193a.wav"
|
||||
[ 13, 31 ] = wave (0) : "./MITfull/elev40/L40e199a.wav"
|
||||
[ 13, 32 ] = wave (0) : "./MITfull/elev40/L40e206a.wav"
|
||||
[ 13, 33 ] = wave (0) : "./MITfull/elev40/L40e212a.wav"
|
||||
[ 13, 34 ] = wave (0) : "./MITfull/elev40/L40e219a.wav"
|
||||
[ 13, 35 ] = wave (0) : "./MITfull/elev40/L40e225a.wav"
|
||||
[ 13, 36 ] = wave (0) : "./MITfull/elev40/L40e231a.wav"
|
||||
[ 13, 37 ] = wave (0) : "./MITfull/elev40/L40e238a.wav"
|
||||
[ 13, 38 ] = wave (0) : "./MITfull/elev40/L40e244a.wav"
|
||||
[ 13, 39 ] = wave (0) : "./MITfull/elev40/L40e251a.wav"
|
||||
[ 13, 40 ] = wave (0) : "./MITfull/elev40/L40e257a.wav"
|
||||
[ 13, 41 ] = wave (0) : "./MITfull/elev40/L40e264a.wav"
|
||||
[ 13, 42 ] = wave (0) : "./MITfull/elev40/L40e270a.wav"
|
||||
[ 13, 43 ] = wave (0) : "./MITfull/elev40/L40e276a.wav"
|
||||
[ 13, 44 ] = wave (0) : "./MITfull/elev40/L40e283a.wav"
|
||||
[ 13, 45 ] = wave (0) : "./MITfull/elev40/L40e289a.wav"
|
||||
[ 13, 46 ] = wave (0) : "./MITfull/elev40/L40e296a.wav"
|
||||
[ 13, 47 ] = wave (0) : "./MITfull/elev40/L40e302a.wav"
|
||||
[ 13, 48 ] = wave (0) : "./MITfull/elev40/L40e309a.wav"
|
||||
[ 13, 49 ] = wave (0) : "./MITfull/elev40/L40e315a.wav"
|
||||
[ 13, 50 ] = wave (0) : "./MITfull/elev40/L40e321a.wav"
|
||||
[ 13, 51 ] = wave (0) : "./MITfull/elev40/L40e328a.wav"
|
||||
[ 13, 52 ] = wave (0) : "./MITfull/elev40/L40e334a.wav"
|
||||
[ 13, 53 ] = wave (0) : "./MITfull/elev40/L40e341a.wav"
|
||||
[ 13, 54 ] = wave (0) : "./MITfull/elev40/L40e347a.wav"
|
||||
[ 13, 55 ] = wave (0) : "./MITfull/elev40/L40e354a.wav"
|
||||
|
||||
[ 14, 0 ] = wave (0) : "./MITfull/elev50/L50e000a.wav"
|
||||
[ 14, 1 ] = wave (0) : "./MITfull/elev50/L50e008a.wav"
|
||||
[ 14, 2 ] = wave (0) : "./MITfull/elev50/L50e016a.wav"
|
||||
[ 14, 3 ] = wave (0) : "./MITfull/elev50/L50e024a.wav"
|
||||
[ 14, 4 ] = wave (0) : "./MITfull/elev50/L50e032a.wav"
|
||||
[ 14, 5 ] = wave (0) : "./MITfull/elev50/L50e040a.wav"
|
||||
[ 14, 6 ] = wave (0) : "./MITfull/elev50/L50e048a.wav"
|
||||
[ 14, 7 ] = wave (0) : "./MITfull/elev50/L50e056a.wav"
|
||||
[ 14, 8 ] = wave (0) : "./MITfull/elev50/L50e064a.wav"
|
||||
[ 14, 9 ] = wave (0) : "./MITfull/elev50/L50e072a.wav"
|
||||
[ 14, 10 ] = wave (0) : "./MITfull/elev50/L50e080a.wav"
|
||||
[ 14, 11 ] = wave (0) : "./MITfull/elev50/L50e088a.wav"
|
||||
[ 14, 12 ] = wave (0) : "./MITfull/elev50/L50e096a.wav"
|
||||
[ 14, 13 ] = wave (0) : "./MITfull/elev50/L50e104a.wav"
|
||||
[ 14, 14 ] = wave (0) : "./MITfull/elev50/L50e112a.wav"
|
||||
[ 14, 15 ] = wave (0) : "./MITfull/elev50/L50e120a.wav"
|
||||
[ 14, 16 ] = wave (0) : "./MITfull/elev50/L50e128a.wav"
|
||||
[ 14, 17 ] = wave (0) : "./MITfull/elev50/L50e136a.wav"
|
||||
[ 14, 18 ] = wave (0) : "./MITfull/elev50/L50e144a.wav"
|
||||
[ 14, 19 ] = wave (0) : "./MITfull/elev50/L50e152a.wav"
|
||||
[ 14, 20 ] = wave (0) : "./MITfull/elev50/L50e160a.wav"
|
||||
[ 14, 21 ] = wave (0) : "./MITfull/elev50/L50e168a.wav"
|
||||
[ 14, 22 ] = wave (0) : "./MITfull/elev50/L50e176a.wav"
|
||||
[ 14, 23 ] = wave (0) : "./MITfull/elev50/L50e184a.wav"
|
||||
[ 14, 24 ] = wave (0) : "./MITfull/elev50/L50e192a.wav"
|
||||
[ 14, 25 ] = wave (0) : "./MITfull/elev50/L50e200a.wav"
|
||||
[ 14, 26 ] = wave (0) : "./MITfull/elev50/L50e208a.wav"
|
||||
[ 14, 27 ] = wave (0) : "./MITfull/elev50/L50e216a.wav"
|
||||
[ 14, 28 ] = wave (0) : "./MITfull/elev50/L50e224a.wav"
|
||||
[ 14, 29 ] = wave (0) : "./MITfull/elev50/L50e232a.wav"
|
||||
[ 14, 30 ] = wave (0) : "./MITfull/elev50/L50e240a.wav"
|
||||
[ 14, 31 ] = wave (0) : "./MITfull/elev50/L50e248a.wav"
|
||||
[ 14, 32 ] = wave (0) : "./MITfull/elev50/L50e256a.wav"
|
||||
[ 14, 33 ] = wave (0) : "./MITfull/elev50/L50e264a.wav"
|
||||
[ 14, 34 ] = wave (0) : "./MITfull/elev50/L50e272a.wav"
|
||||
[ 14, 35 ] = wave (0) : "./MITfull/elev50/L50e280a.wav"
|
||||
[ 14, 36 ] = wave (0) : "./MITfull/elev50/L50e288a.wav"
|
||||
[ 14, 37 ] = wave (0) : "./MITfull/elev50/L50e296a.wav"
|
||||
[ 14, 38 ] = wave (0) : "./MITfull/elev50/L50e304a.wav"
|
||||
[ 14, 39 ] = wave (0) : "./MITfull/elev50/L50e312a.wav"
|
||||
[ 14, 40 ] = wave (0) : "./MITfull/elev50/L50e320a.wav"
|
||||
[ 14, 41 ] = wave (0) : "./MITfull/elev50/L50e328a.wav"
|
||||
[ 14, 42 ] = wave (0) : "./MITfull/elev50/L50e336a.wav"
|
||||
[ 14, 43 ] = wave (0) : "./MITfull/elev50/L50e344a.wav"
|
||||
[ 14, 44 ] = wave (0) : "./MITfull/elev50/L50e352a.wav"
|
||||
|
||||
[ 15, 0 ] = wave (0) : "./MITfull/elev60/L60e000a.wav"
|
||||
[ 15, 1 ] = wave (0) : "./MITfull/elev60/L60e010a.wav"
|
||||
[ 15, 2 ] = wave (0) : "./MITfull/elev60/L60e020a.wav"
|
||||
[ 15, 3 ] = wave (0) : "./MITfull/elev60/L60e030a.wav"
|
||||
[ 15, 4 ] = wave (0) : "./MITfull/elev60/L60e040a.wav"
|
||||
[ 15, 5 ] = wave (0) : "./MITfull/elev60/L60e050a.wav"
|
||||
[ 15, 6 ] = wave (0) : "./MITfull/elev60/L60e060a.wav"
|
||||
[ 15, 7 ] = wave (0) : "./MITfull/elev60/L60e070a.wav"
|
||||
[ 15, 8 ] = wave (0) : "./MITfull/elev60/L60e080a.wav"
|
||||
[ 15, 9 ] = wave (0) : "./MITfull/elev60/L60e090a.wav"
|
||||
[ 15, 10 ] = wave (0) : "./MITfull/elev60/L60e100a.wav"
|
||||
[ 15, 11 ] = wave (0) : "./MITfull/elev60/L60e110a.wav"
|
||||
[ 15, 12 ] = wave (0) : "./MITfull/elev60/L60e120a.wav"
|
||||
[ 15, 13 ] = wave (0) : "./MITfull/elev60/L60e130a.wav"
|
||||
[ 15, 14 ] = wave (0) : "./MITfull/elev60/L60e140a.wav"
|
||||
[ 15, 15 ] = wave (0) : "./MITfull/elev60/L60e150a.wav"
|
||||
[ 15, 16 ] = wave (0) : "./MITfull/elev60/L60e160a.wav"
|
||||
[ 15, 17 ] = wave (0) : "./MITfull/elev60/L60e170a.wav"
|
||||
[ 15, 18 ] = wave (0) : "./MITfull/elev60/L60e180a.wav"
|
||||
[ 15, 19 ] = wave (0) : "./MITfull/elev60/L60e190a.wav"
|
||||
[ 15, 20 ] = wave (0) : "./MITfull/elev60/L60e200a.wav"
|
||||
[ 15, 21 ] = wave (0) : "./MITfull/elev60/L60e210a.wav"
|
||||
[ 15, 22 ] = wave (0) : "./MITfull/elev60/L60e220a.wav"
|
||||
[ 15, 23 ] = wave (0) : "./MITfull/elev60/L60e230a.wav"
|
||||
[ 15, 24 ] = wave (0) : "./MITfull/elev60/L60e240a.wav"
|
||||
[ 15, 25 ] = wave (0) : "./MITfull/elev60/L60e250a.wav"
|
||||
[ 15, 26 ] = wave (0) : "./MITfull/elev60/L60e260a.wav"
|
||||
[ 15, 27 ] = wave (0) : "./MITfull/elev60/L60e270a.wav"
|
||||
[ 15, 28 ] = wave (0) : "./MITfull/elev60/L60e280a.wav"
|
||||
[ 15, 29 ] = wave (0) : "./MITfull/elev60/L60e290a.wav"
|
||||
[ 15, 30 ] = wave (0) : "./MITfull/elev60/L60e300a.wav"
|
||||
[ 15, 31 ] = wave (0) : "./MITfull/elev60/L60e310a.wav"
|
||||
[ 15, 32 ] = wave (0) : "./MITfull/elev60/L60e320a.wav"
|
||||
[ 15, 33 ] = wave (0) : "./MITfull/elev60/L60e330a.wav"
|
||||
[ 15, 34 ] = wave (0) : "./MITfull/elev60/L60e340a.wav"
|
||||
[ 15, 35 ] = wave (0) : "./MITfull/elev60/L60e350a.wav"
|
||||
|
||||
[ 16, 0 ] = wave (0) : "./MITfull/elev70/L70e000a.wav"
|
||||
[ 16, 1 ] = wave (0) : "./MITfull/elev70/L70e015a.wav"
|
||||
[ 16, 2 ] = wave (0) : "./MITfull/elev70/L70e030a.wav"
|
||||
[ 16, 3 ] = wave (0) : "./MITfull/elev70/L70e045a.wav"
|
||||
[ 16, 4 ] = wave (0) : "./MITfull/elev70/L70e060a.wav"
|
||||
[ 16, 5 ] = wave (0) : "./MITfull/elev70/L70e075a.wav"
|
||||
[ 16, 6 ] = wave (0) : "./MITfull/elev70/L70e090a.wav"
|
||||
[ 16, 7 ] = wave (0) : "./MITfull/elev70/L70e105a.wav"
|
||||
[ 16, 8 ] = wave (0) : "./MITfull/elev70/L70e120a.wav"
|
||||
[ 16, 9 ] = wave (0) : "./MITfull/elev70/L70e135a.wav"
|
||||
[ 16, 10 ] = wave (0) : "./MITfull/elev70/L70e150a.wav"
|
||||
[ 16, 11 ] = wave (0) : "./MITfull/elev70/L70e165a.wav"
|
||||
[ 16, 12 ] = wave (0) : "./MITfull/elev70/L70e180a.wav"
|
||||
[ 16, 13 ] = wave (0) : "./MITfull/elev70/L70e195a.wav"
|
||||
[ 16, 14 ] = wave (0) : "./MITfull/elev70/L70e210a.wav"
|
||||
[ 16, 15 ] = wave (0) : "./MITfull/elev70/L70e225a.wav"
|
||||
[ 16, 16 ] = wave (0) : "./MITfull/elev70/L70e240a.wav"
|
||||
[ 16, 17 ] = wave (0) : "./MITfull/elev70/L70e255a.wav"
|
||||
[ 16, 18 ] = wave (0) : "./MITfull/elev70/L70e270a.wav"
|
||||
[ 16, 19 ] = wave (0) : "./MITfull/elev70/L70e285a.wav"
|
||||
[ 16, 20 ] = wave (0) : "./MITfull/elev70/L70e300a.wav"
|
||||
[ 16, 21 ] = wave (0) : "./MITfull/elev70/L70e315a.wav"
|
||||
[ 16, 22 ] = wave (0) : "./MITfull/elev70/L70e330a.wav"
|
||||
[ 16, 23 ] = wave (0) : "./MITfull/elev70/L70e345a.wav"
|
||||
|
||||
[ 17, 0 ] = wave (0) : "./MITfull/elev80/L80e000a.wav"
|
||||
[ 17, 1 ] = wave (0) : "./MITfull/elev80/L80e030a.wav"
|
||||
[ 17, 2 ] = wave (0) : "./MITfull/elev80/L80e060a.wav"
|
||||
[ 17, 3 ] = wave (0) : "./MITfull/elev80/L80e090a.wav"
|
||||
[ 17, 4 ] = wave (0) : "./MITfull/elev80/L80e120a.wav"
|
||||
[ 17, 5 ] = wave (0) : "./MITfull/elev80/L80e150a.wav"
|
||||
[ 17, 6 ] = wave (0) : "./MITfull/elev80/L80e180a.wav"
|
||||
[ 17, 7 ] = wave (0) : "./MITfull/elev80/L80e210a.wav"
|
||||
[ 17, 8 ] = wave (0) : "./MITfull/elev80/L80e240a.wav"
|
||||
[ 17, 9 ] = wave (0) : "./MITfull/elev80/L80e270a.wav"
|
||||
[ 17, 10 ] = wave (0) : "./MITfull/elev80/L80e300a.wav"
|
||||
[ 17, 11 ] = wave (0) : "./MITfull/elev80/L80e330a.wav"
|
||||
|
||||
[ 18, 0 ] = wave (0) : "./MITfull/elev90/L90e000a.wav"
|
||||
|
||||
+2669
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,309 @@
|
||||
/*
|
||||
* OpenAL Info Utility
|
||||
*
|
||||
* Copyright (c) 2010 by Chris Robinson <chris.kcat@gmail.com>
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "AL/alc.h"
|
||||
#include "AL/al.h"
|
||||
#include "AL/alext.h"
|
||||
|
||||
#ifndef ALC_ENUMERATE_ALL_EXT
|
||||
#define ALC_DEFAULT_ALL_DEVICES_SPECIFIER 0x1012
|
||||
#define ALC_ALL_DEVICES_SPECIFIER 0x1013
|
||||
#endif
|
||||
|
||||
#ifndef ALC_EXT_EFX
|
||||
#define ALC_EFX_MAJOR_VERSION 0x20001
|
||||
#define ALC_EFX_MINOR_VERSION 0x20002
|
||||
#define ALC_MAX_AUXILIARY_SENDS 0x20003
|
||||
#endif
|
||||
|
||||
|
||||
#define MAX_WIDTH 80
|
||||
|
||||
static void printList(const char *list, char separator)
|
||||
{
|
||||
size_t col = MAX_WIDTH, len;
|
||||
const char *indent = " ";
|
||||
const char *next;
|
||||
|
||||
if(!list || *list == '\0')
|
||||
{
|
||||
fprintf(stdout, "\n%s!!! none !!!\n", indent);
|
||||
return;
|
||||
}
|
||||
|
||||
do {
|
||||
next = strchr(list, separator);
|
||||
if(next)
|
||||
{
|
||||
len = next-list;
|
||||
do {
|
||||
next++;
|
||||
} while(*next == separator);
|
||||
}
|
||||
else
|
||||
len = strlen(list);
|
||||
|
||||
if(len + col + 2 >= MAX_WIDTH)
|
||||
{
|
||||
fprintf(stdout, "\n%s", indent);
|
||||
col = strlen(indent);
|
||||
}
|
||||
else
|
||||
{
|
||||
fputc(' ', stdout);
|
||||
col++;
|
||||
}
|
||||
|
||||
len = fwrite(list, 1, len, stdout);
|
||||
col += len;
|
||||
|
||||
if(!next || *next == '\0')
|
||||
break;
|
||||
fputc(',', stdout);
|
||||
col++;
|
||||
|
||||
list = next;
|
||||
} while(1);
|
||||
fputc('\n', stdout);
|
||||
}
|
||||
|
||||
static void printDeviceList(const char *list)
|
||||
{
|
||||
if(!list || *list == '\0')
|
||||
printf(" !!! none !!!\n");
|
||||
else do {
|
||||
printf(" %s\n", list);
|
||||
list += strlen(list) + 1;
|
||||
} while(*list != '\0');
|
||||
}
|
||||
|
||||
|
||||
static ALenum checkALErrors(int linenum)
|
||||
{
|
||||
ALenum err = alGetError();
|
||||
if(err != AL_NO_ERROR)
|
||||
printf("OpenAL Error: %s (0x%x), @ %d\n", alGetString(err), err, linenum);
|
||||
return err;
|
||||
}
|
||||
#define checkALErrors() checkALErrors(__LINE__)
|
||||
|
||||
static ALCenum checkALCErrors(ALCdevice *device, int linenum)
|
||||
{
|
||||
ALCenum err = alcGetError(device);
|
||||
if(err != ALC_NO_ERROR)
|
||||
printf("ALC Error: %s (0x%x), @ %d\n", alcGetString(device, err), err, linenum);
|
||||
return err;
|
||||
}
|
||||
#define checkALCErrors(x) checkALCErrors((x),__LINE__)
|
||||
|
||||
|
||||
static void printALCInfo(ALCdevice *device)
|
||||
{
|
||||
ALCint major, minor;
|
||||
|
||||
if(device)
|
||||
{
|
||||
const ALCchar *devname = NULL;
|
||||
printf("\n");
|
||||
if(alcIsExtensionPresent(device, "ALC_ENUMERATE_ALL_EXT") != AL_FALSE)
|
||||
devname = alcGetString(device, ALC_ALL_DEVICES_SPECIFIER);
|
||||
if(checkALCErrors(device) != ALC_NO_ERROR || !devname)
|
||||
devname = alcGetString(device, ALC_DEVICE_SPECIFIER);
|
||||
printf("** Info for device \"%s\" **\n", devname);
|
||||
}
|
||||
alcGetIntegerv(device, ALC_MAJOR_VERSION, 1, &major);
|
||||
alcGetIntegerv(device, ALC_MINOR_VERSION, 1, &minor);
|
||||
if(checkALCErrors(device) == ALC_NO_ERROR)
|
||||
printf("ALC version: %d.%d\n", major, minor);
|
||||
if(device)
|
||||
{
|
||||
printf("ALC extensions:");
|
||||
printList(alcGetString(device, ALC_EXTENSIONS), ' ');
|
||||
checkALCErrors(device);
|
||||
}
|
||||
}
|
||||
|
||||
static void printALInfo(void)
|
||||
{
|
||||
printf("OpenAL vendor string: %s\n", alGetString(AL_VENDOR));
|
||||
printf("OpenAL renderer string: %s\n", alGetString(AL_RENDERER));
|
||||
printf("OpenAL version string: %s\n", alGetString(AL_VERSION));
|
||||
printf("OpenAL extensions:");
|
||||
printList(alGetString(AL_EXTENSIONS), ' ');
|
||||
checkALErrors();
|
||||
}
|
||||
|
||||
static void printEFXInfo(ALCdevice *device)
|
||||
{
|
||||
ALCint major, minor, sends;
|
||||
static const ALchar filters[][32] = {
|
||||
"AL_FILTER_LOWPASS", "AL_FILTER_HIGHPASS", "AL_FILTER_BANDPASS", ""
|
||||
};
|
||||
char filterNames[] = "Low-pass,High-pass,Band-pass,";
|
||||
static const ALchar effects[][32] = {
|
||||
"AL_EFFECT_EAXREVERB", "AL_EFFECT_REVERB", "AL_EFFECT_CHORUS",
|
||||
"AL_EFFECT_DISTORTION", "AL_EFFECT_ECHO", "AL_EFFECT_FLANGER",
|
||||
"AL_EFFECT_FREQUENCY_SHIFTER", "AL_EFFECT_VOCAL_MORPHER",
|
||||
"AL_EFFECT_PITCH_SHIFTER", "AL_EFFECT_RING_MODULATOR",
|
||||
"AL_EFFECT_AUTOWAH", "AL_EFFECT_COMPRESSOR", "AL_EFFECT_EQUALIZER", ""
|
||||
};
|
||||
static const ALchar dedeffects[][64] = {
|
||||
"AL_EFFECT_DEDICATED_DIALOGUE",
|
||||
"AL_EFFECT_DEDICATED_LOW_FREQUENCY_EFFECT", ""
|
||||
};
|
||||
char effectNames[] = "EAX Reverb,Reverb,Chorus,Distortion,Echo,Flanger,"
|
||||
"Frequency Shifter,Vocal Morpher,Pitch Shifter,"
|
||||
"Ring Modulator,Autowah,Compressor,Equalizer,"
|
||||
"Dedicated Dialog,Dedicated LFE,";
|
||||
char *current;
|
||||
int i;
|
||||
|
||||
if(alcIsExtensionPresent(device, "ALC_EXT_EFX") == AL_FALSE)
|
||||
{
|
||||
printf("EFX not available\n");
|
||||
return;
|
||||
}
|
||||
|
||||
alcGetIntegerv(device, ALC_EFX_MAJOR_VERSION, 1, &major);
|
||||
alcGetIntegerv(device, ALC_EFX_MINOR_VERSION, 1, &minor);
|
||||
if(checkALCErrors(device) == ALC_NO_ERROR)
|
||||
printf("EFX version: %d.%d\n", major, minor);
|
||||
alcGetIntegerv(device, ALC_MAX_AUXILIARY_SENDS, 1, &sends);
|
||||
if(checkALCErrors(device) == ALC_NO_ERROR)
|
||||
printf("Max auxiliary sends: %d\n", sends);
|
||||
|
||||
current = filterNames;
|
||||
for(i = 0;filters[i][0];i++)
|
||||
{
|
||||
char *next = strchr(current, ',');
|
||||
ALenum val;
|
||||
|
||||
val = alGetEnumValue(filters[i]);
|
||||
if(alGetError() != AL_NO_ERROR || val == 0 || val == -1)
|
||||
memmove(current, next+1, strlen(next));
|
||||
else
|
||||
current = next+1;
|
||||
}
|
||||
printf("Supported filters:");
|
||||
printList(filterNames, ',');
|
||||
|
||||
current = effectNames;
|
||||
for(i = 0;effects[i][0];i++)
|
||||
{
|
||||
char *next = strchr(current, ',');
|
||||
ALenum val;
|
||||
|
||||
val = alGetEnumValue(effects[i]);
|
||||
if(alGetError() != AL_NO_ERROR || val == 0 || val == -1)
|
||||
memmove(current, next+1, strlen(next));
|
||||
else
|
||||
current = next+1;
|
||||
}
|
||||
if(alcIsExtensionPresent(device, "ALC_EXT_DEDICATED"))
|
||||
{
|
||||
for(i = 0;dedeffects[i][0];i++)
|
||||
{
|
||||
char *next = strchr(current, ',');
|
||||
ALenum val;
|
||||
|
||||
val = alGetEnumValue(dedeffects[i]);
|
||||
if(alGetError() != AL_NO_ERROR || val == 0 || val == -1)
|
||||
memmove(current, next+1, strlen(next));
|
||||
else
|
||||
current = next+1;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for(i = 0;dedeffects[i][0];i++)
|
||||
{
|
||||
char *next = strchr(current, ',');
|
||||
memmove(current, next+1, strlen(next));
|
||||
}
|
||||
}
|
||||
printf("Supported effects:");
|
||||
printList(effectNames, ',');
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
ALCdevice *device;
|
||||
ALCcontext *context;
|
||||
|
||||
if(argc > 1 && (strcmp(argv[1], "--help") == 0 ||
|
||||
strcmp(argv[1], "-h") == 0))
|
||||
{
|
||||
printf("Usage: %s [playback device]\n", argv[0]);
|
||||
return 0;
|
||||
}
|
||||
|
||||
printf("Available playback devices:\n");
|
||||
if(alcIsExtensionPresent(NULL, "ALC_ENUMERATE_ALL_EXT") != AL_FALSE)
|
||||
printDeviceList(alcGetString(NULL, ALC_ALL_DEVICES_SPECIFIER));
|
||||
else
|
||||
printDeviceList(alcGetString(NULL, ALC_DEVICE_SPECIFIER));
|
||||
printf("Available capture devices:\n");
|
||||
printDeviceList(alcGetString(NULL, ALC_CAPTURE_DEVICE_SPECIFIER));
|
||||
|
||||
if(alcIsExtensionPresent(NULL, "ALC_ENUMERATE_ALL_EXT") != AL_FALSE)
|
||||
printf("Default playback device: %s\n",
|
||||
alcGetString(NULL, ALC_DEFAULT_ALL_DEVICES_SPECIFIER));
|
||||
else
|
||||
printf("Default playback device: %s\n",
|
||||
alcGetString(NULL, ALC_DEFAULT_DEVICE_SPECIFIER));
|
||||
printf("Default capture device: %s\n",
|
||||
alcGetString(NULL, ALC_CAPTURE_DEFAULT_DEVICE_SPECIFIER));
|
||||
|
||||
printALCInfo(NULL);
|
||||
|
||||
device = alcOpenDevice((argc>1) ? argv[1] : NULL);
|
||||
if(!device)
|
||||
{
|
||||
printf("\n!!! Failed to open %s !!!\n\n", ((argc>1) ? argv[1] : "default device"));
|
||||
return 1;
|
||||
}
|
||||
printALCInfo(device);
|
||||
|
||||
context = alcCreateContext(device, NULL);
|
||||
if(!context || alcMakeContextCurrent(context) == ALC_FALSE)
|
||||
{
|
||||
if(context)
|
||||
alcDestroyContext(context);
|
||||
alcCloseDevice(device);
|
||||
printf("\n!!! Failed to set a context !!!\n\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
printALInfo();
|
||||
printEFXInfo(device);
|
||||
|
||||
alcMakeContextCurrent(NULL);
|
||||
alcDestroyContext(context);
|
||||
alcCloseDevice(device);
|
||||
|
||||
return 0;
|
||||
}
|
||||
Reference in New Issue
Block a user