Compare commits

..

381 Commits

Author SHA1 Message Date
Chris Robinson 3ad86a1c1b Release 1.11.753 2010-01-17 17:46:27 -08:00
Chris Robinson 931f5875cd Fix speaker angle fixup 2010-01-12 09:11:46 -08:00
Chris Robinson f22b02a762 al_print doesn't need to be inline 2010-01-12 09:05:57 -08:00
Chris Robinson 505f61ff43 Properly trace the invalid speaker angle 2010-01-12 08:50:32 -08:00
Chris Robinson 0c2efa1253 Use GCC's format attribute for al_printf 2010-01-12 08:48:25 -08:00
Chris Robinson 5921e18be2 Fix some typos with the solaris backend 2010-01-12 08:28:07 -08:00
Chris Robinson 5b9e6fe440 Only allow 8- and 16-bit, and mono and stereo, wave file output 2010-01-12 08:26:25 -08:00
Chris Robinson 35ba7d70dc Consolidate some source offset handling code 2010-01-12 02:43:37 -08:00
Chris Robinson 026b4b8f4c Better handle large second offsets 2010-01-12 02:26:38 -08:00
Chris Robinson c924a50bed Don't use a flag to set an error when applying the source offset 2010-01-12 02:22:38 -08:00
Chris Robinson 574792d2e1 Fix Windows compilation 2010-01-11 23:47:03 -08:00
Chris Robinson ab2eb5a603 Check buffer size when copying padding instead of the data pointer 2010-01-11 10:58:33 -08:00
Chris Robinson 3d7f925d52 Add helpful values to the resampler enum 2010-01-11 07:02:29 -08:00
Chris Robinson 93b584ff84 Add a cosine resampler 2010-01-11 06:19:54 -08:00
Chris Robinson 705849ca73 Add an option for point resampling 2010-01-11 05:37:20 -08:00
Chris Robinson 1a57f095e8 Hold global lock during mixing only when iterating device contexts 2010-01-11 03:57:49 -08:00
Chris Robinson ac9c2e8c4a Cleanup OSS/Solaris loop a bit 2010-01-10 12:40:59 -08:00
Chris Robinson 45f8efec41 Return the default config string for empty entries 2010-01-09 06:48:43 -08:00
Chris Robinson ef7df2416d Hide OSS and Solaris devices if their files can't be stat'd 2010-01-09 06:40:50 -08:00
Chris Robinson cb113315f7 Promote AL_EXT_source_distance_model to complete 2010-01-09 03:27:16 -08:00
Chris Robinson d61f90a9c2 Make sure the device handle is valid when getting the device error 2010-01-09 03:25:13 -08:00
Chris Robinson 3d11fb219e Hold the default context extensions globally 2010-01-09 02:48:18 -08:00
Chris Robinson 4d9a368f96 Suppress connection refused errors
Since that just typically means the server isn't running
2010-01-08 01:43:27 -08:00
Chris Robinson 43220b604c Reduce some indentation 2010-01-08 01:21:57 -08:00
Chris Robinson 91f28fa87c Try the PulseAudio backend first 2010-01-08 01:08:27 -08:00
Chris Robinson 82547db2db Prepare the pcm handle after recovering 2010-01-06 23:02:28 -08:00
Chris Robinson 64ac3a4739 Use snd_pcm_recover in more places 2010-01-06 22:55:20 -08:00
Chris Robinson c90616b963 Use snd_pcm_recover to recover from certain device errors 2010-01-06 22:50:30 -08:00
Chris Robinson 0ceaa01c3d Adjust PulseAudio's capture latency 2009-12-30 15:33:16 -08:00
Chris Robinson 7d7e503603 Properly retrieve device-inspecific errors 2009-12-28 23:29:49 -08:00
Chris Robinson 7ee81eac0f Store ALC errors with the device when possible 2009-12-28 23:19:13 -08:00
Chris Robinson c9a08fc7b2 Remove some unneeded functions 2009-12-28 13:12:45 -08:00
Chris Robinson 69ab93a824 Add a function to check if a config option is set to a non-empty value 2009-12-28 13:08:15 -08:00
Chris Robinson 179b660eee Enforce a lower bound playback frequency of 8khz 2009-12-28 12:47:59 -08:00
Chris Robinson a0ef7be9a5 Improve layout parsing and allow using long names for speakers 2009-12-28 11:49:55 -08:00
Chris Robinson 2a735b14dc Add an option to spawn a PulseAudio server on request 2009-12-28 10:49:31 -08:00
Chris Robinson a294dd8d9b Be more lenient in signaling the mainloop 2009-12-28 10:15:59 -08:00
Chris Robinson dc1522282b Try to find a compatible format from Pulse's default sink 2009-12-27 11:05:59 -08:00
Chris Robinson 528a4c6a02 Update panning for existing AL contexts when creating a new one 2009-12-26 20:27:14 -08:00
Chris Robinson 1770a8b62b A NULL Pulse context won't have a valid error code 2009-12-26 12:18:16 -08:00
Chris Robinson 77a0a6de95 Wait for the buffer attrib update from pulse to finish 2009-12-26 11:30:41 -08:00
Chris Robinson c1fd977e79 Consolidate pulse capture failure path 2009-12-26 10:46:29 -08:00
Chris Robinson cbbda93292 Make sure a proper channel map is set for pulse capture 2009-12-26 09:17:03 -08:00
Chris Robinson c6340ce12d Clean up some loading checks 2009-12-26 08:49:11 -08:00
Chris Robinson 7bc739e965 Use the proper logging function 2009-12-26 08:16:25 -08:00
Chris Robinson 9f988808c7 Start and stop PortAudio's stream in the proper methods 2009-12-26 08:14:28 -08:00
Chris Robinson 6e9ce47a4b GetConfigValueBool should take an int, not a float 2009-12-26 07:42:57 -08:00
Chris Robinson 89f59c0e1c Shorten a long line 2009-12-26 07:42:16 -08:00
Chris Robinson 3793919892 Capture as much as possible directly from PulseAudio 2009-12-25 17:56:57 -08:00
Chris Robinson d1699d50f6 Add missing newline 2009-12-25 15:18:32 -08:00
Chris Robinson b94d950b1e Undefine no longer needed macro 2009-12-25 14:11:43 -08:00
Chris Robinson d3e77a0f63 Fix incorrect error check 2009-12-25 13:19:25 -08:00
Chris Robinson 965a71ee90 Only use pa_stream_set_buffer_attr_callback when available (0.9.15+) 2009-12-25 13:17:21 -08:00
Chris Robinson fd794b44b2 Use pa_stream_begin_write when available for "zero-copy" writing
Must be compiled against 0.9.16 or newer to be available. It will fall back to
the old method if the function is not available at run-time.
2009-12-25 13:11:17 -08:00
Chris Robinson c9dcba17a9 Check error returns instead of error string 2009-12-25 13:05:04 -08:00
Chris Robinson 88de4e15b3 Mark the source for updating when setting a buffer on it
Changing the buffer can change the playback format, which can require different
source parameter calculations. Queueing a buffer on a source that has no
buffers (or only buffers without a format, eg. buffer 0) has the same effect
2009-12-25 05:09:29 -08:00
Chris Robinson 7f0c6629b9 Use a 64-bit value to scale potentially-large numbers 2009-12-24 15:41:45 -08:00
Chris Robinson f6ca39403d Use the Pulse server-specified playback rate by default 2009-12-24 15:35:22 -08:00
Chris Robinson ea7cf35ea4 Use pa_xmalloc instead of pa_xmalloc0 2009-12-24 07:38:46 -08:00
Chris Robinson accea119d9 Update pulse capture ring buffer in 25ms chunks 2009-12-24 04:08:04 -08:00
Chris Robinson 6ea7b43c90 Don't force latency adjustment with PulseAudio 2009-12-23 13:59:58 -08:00
Chris Robinson ddfad996a9 Don't render mono as stereo 2009-12-21 02:59:30 -08:00
Chris Robinson d786f99094 Scale samples down when converting stereo to mono 2009-12-21 02:27:25 -08:00
Chris Robinson 008563450c Improve some indentations 2009-12-20 21:50:00 -08:00
Chris Robinson 69c238a2e6 Properly retrieve the device frequency 2009-12-20 21:19:57 -08:00
Chris Robinson b3fdf170b1 Fix header comment for AL_PITCH 2009-12-16 22:50:54 -08:00
Chris Robinson 56cc038603 Improve initial decay calculations for sends to reverb 2009-12-10 18:37:36 -08:00
Chris Robinson 4c83c689a8 Use the specified reverb air absorption value for wet sends 2009-12-10 18:22:45 -08:00
Chris Robinson 2b7953c472 Track whether a context is suspended or not 2009-12-09 12:14:53 -08:00
Chris Robinson 368ef1cea9 Store the source state locally after making sure it needs mixing 2009-12-09 11:56:53 -08:00
Chris Robinson bd696a6b37 Fix IMA ADPCM offset calculation 2009-12-09 09:50:09 -08:00
Chris Robinson a9fc272e39 Prettify CMake checks for compiler switches 2009-12-09 08:46:35 -08:00
Chris Robinson c5952d1ddc Move the pkg-config file to the base directory 2009-12-09 07:36:06 -08:00
Chris Robinson 656a406377 Use an inline function to calculate the low-pass filter coefficient 2009-12-09 07:21:59 -08:00
Chris Robinson 5fcd6cc510 Split non-attenuated source calculations into a separate function 2009-12-09 07:02:26 -08:00
Chris Robinson e09b6020a6 Fix typo for reverb creation 2009-12-09 06:46:06 -08:00
Chris Robinson 84d2d623b6 Add a head-dampening option
This simulates occlusion of the player's head for sounds coming from behind,
when outputing to mono or stereo
2009-12-08 14:18:07 -08:00
Chris Robinson 1694e5bd12 Store the original pre-clamped distance instead of re-computing it 2009-12-08 10:12:18 -08:00
Chris Robinson 5170e251f9 Use the correct wet filter history offset 2009-12-07 12:45:23 -08:00
Chris Robinson 4697e946d3 Internally store 32-bit float buffer data, and mix accordingly 2009-12-07 10:35:30 -08:00
Chris Robinson 9286e3984c Move default channel order setting out of the header 2009-12-07 04:19:33 -08:00
Chris Robinson 88f3d747b7 Add a simple README 2009-12-07 01:05:01 -08:00
Chris Robinson d4427c54ea Change internal order to match WFX 2009-12-07 00:51:27 -08:00
Chris Robinson 92ade80557 Fix 6.1 channel order 2009-12-07 00:49:56 -08:00
Chris Robinson 8138446b8c Restrict setting some wet path values to active sends only 2009-12-06 03:59:12 -08:00
Chris Robinson 58ecc7fad4 Check for potential NULL accesses with the IsBadWritePtr wrapper 2009-12-04 01:33:50 -08:00
Chris Robinson 311cc5c62f Don't wait to accept stream connections 2009-12-03 04:43:38 -08:00
Chris Robinson 4a928ea9fa Don't signal on synchronous changes and don't wait to accept context changes 2009-12-02 08:10:45 -08:00
Chris Robinson c1eb444a39 Remove some assumptions of 16-bit internal storage 2009-12-02 05:55:33 -08:00
Chris Robinson b5270e0bb3 Use a channel-map to specify the output device channel order 2009-12-02 04:03:51 -08:00
Chris Robinson 6cfc31777b Add an option for real-time priority mixing
Default to disable for now, as a safety precaution
2009-12-01 23:15:09 -08:00
Chris Robinson 0e1e8503e0 Properly accept PulseAudio's mainloop signal on connection failure 2009-12-01 22:42:43 -08:00
Chris Robinson 974d0b4e91 Fix retrieved update size from pulseaudio 2009-12-01 12:21:02 -08:00
Chris Robinson d66832a39c Accept a signal only when the pulseaudio stream/context is ready 2009-12-01 12:18:34 -08:00
Chris Robinson d5889a941f Clamp dry gain after cone attenuation is applied 2009-12-01 03:32:04 -08:00
Chris Robinson 6248e986e5 Don't complain if the length given by pulse isn't an exact multiple of the period size 2009-12-01 02:23:38 -08:00
Chris Robinson 786b98a013 Avoid setting a field redundantly 2009-11-29 23:07:04 -08:00
Chris Robinson f63d8dbf38 Enable real-time priority for ALSA, OSS, and DirectSound mixing loops 2009-11-29 23:02:21 -08:00
Chris Robinson 15aad09ce7 Check for the pthread_setschedparam function 2009-11-29 22:44:56 -08:00
Chris Robinson fdd314f7f8 Reset the kill flag after the thread has stopped 2009-11-29 10:22:12 -08:00
Chris Robinson 39b456d88c Add AL_EXT_double tokens to alext.h 2009-11-28 22:19:04 -08:00
Chris Robinson d930fb8d3d Call the Update effect method for null effects 2009-11-28 20:09:41 -08:00
Chris Robinson 3ec64eb0fd Call to the right databuffer function 2009-11-28 19:37:29 -08:00
Chris Robinson d81c9819b8 Remove unnecessary returns 2009-11-28 19:36:05 -08:00
Chris Robinson 98ce1d14c1 Update AL_EXTX_source_distance_model to require explicit enabling
The in-progress spec has been updated to reflect this
2009-11-27 20:05:21 -08:00
Chris Robinson 69f9ab88b9 Send multi-channel sources to auxiliary effect slots
They are downmixed to mono using a volume-preserving scalar, and passed
through a 1-pole low-pass filter (not chained)
2009-11-26 00:39:32 -08:00
Chris Robinson 1a0676f0eb Mark sources for updating when a new context is made from the device 2009-11-25 16:28:19 -08:00
Chris Robinson 658923175f Update source parameters only when they need changing 2009-11-25 16:21:47 -08:00
Chris Robinson 877f4340ba Base air absorption on distance attenuation, try 2 2009-11-24 21:19:11 -08:00
Chris Robinson 35a9ccb41f Revert "Base air absorption on the distance attenuation"
This reverts commit c7c2f9385f.

Fundamentally wrong. The -6dB rolloff is every doubling of the distance, and
the (scaled) -0.05dB rolloff is supposed to be every additional unit.
2009-11-24 01:39:34 -08:00
Chris Robinson c7c2f9385f Base air absorption on the distance attenuation 2009-11-23 16:25:37 -08:00
Chris Robinson d1f3dbb9a1 Make modulation index 0 map to offset 0 2009-11-23 04:14:12 -08:00
Chris Robinson cfb30fe975 Use a 4x4 matrix to transform coordinates 2009-11-23 04:13:51 -08:00
Chris Robinson 2d1b378ef2 Transform all relevant vectors for converting world-space to listener-space 2009-11-22 22:36:20 -08:00
Chris Robinson 06bbee2449 Add a function for 1-pole filtering 2009-11-22 21:20:27 -08:00
Chris Robinson 85bc300dfa ALCAPIENTRY is deprecated in favor of ALC_APIENTRY 2009-11-22 21:15:11 -08:00
Chris Robinson 0662adacb9 Fix alBufferDataStatic extension name in alext.h 2009-11-22 21:12:43 -08:00
Chris Robinson 65a153da6c Update the drivers config file comment 2009-11-22 15:43:05 -08:00
Chris Robinson c5ee010640 The echo should not take energy-attenuated input 2009-11-22 15:37:32 -08:00
Chris Robinson 1b18b4a0ee Allow unlisted backends to stay available when the drivers list ends with , 2009-11-22 01:06:05 -08:00
Chris Robinson 58765aab6b Print available devices before trying to open one 2009-11-19 19:02:16 -08:00
Chris Robinson 1483af1baa Watch for NULL and empty device lists 2009-11-19 18:49:24 -08:00
Chris Robinson 13979793f6 Display supported filters using a comma-separated listing 2009-11-19 18:46:23 -08:00
Chris Robinson 9c228e7625 Be clearer if device opening or context setup fails 2009-11-19 18:25:29 -08:00
Chris Robinson 6a667b36d1 Reorganize and improve the reverb effect
Code supplied by Christopher Fitzgerald. This update also implements the echo
and modulation parameters.
2009-11-19 14:05:04 -08:00
Chris Robinson fe37f1968d Better approximate the wet attenuation model for reverb 2009-11-19 11:06:41 -08:00
Chris Robinson 4565bdd7ce Make sure there's at least a one-sample delay for the echo's first tap 2009-11-19 10:42:41 -08:00
Chris Robinson 5f3c07ca3b Apply the reverb room rolloff factor for EAX reverb too 2009-11-19 10:29:10 -08:00
Chris Robinson 8d1da6a8ca Move NextPowerOf2 to alMain.h 2009-11-19 09:50:15 -08:00
Chris Robinson ff8e09495d Move aluCart2LUTpos to alu.h 2009-11-19 09:24:35 -08:00
Chris Robinson e868eef679 Make sure to set the new echo sample buffer and remove an unused macro 2009-11-18 17:34:08 -08:00
Chris Robinson ea90f781ff Release 1.10.622 2009-11-08 21:36:44 -08:00
Chris Robinson c1b161b44b Handle NULL effect objects as AL_EFFECT_NULL effects 2009-11-05 20:50:56 -08:00
Chris Robinson aa84b2e328 Handle setting AL_EFFECT_NULL effect types on a slot 2009-11-05 18:22:43 -08:00
Chris Robinson ebc1602816 Use the DXSDK_DIR variable when set 2009-11-02 14:57:48 -08:00
Chris Robinson dcd6a55529 Use a realtime clock for measuring time 2009-11-01 10:03:05 -08:00
Chris Robinson fb258a7416 Properly lock the device when setting it disconnected 2009-11-01 09:29:20 -08:00
Chris Robinson 5aed927887 Watch for stream and context failures from pulse, and report disconnects 2009-10-31 20:05:15 -07:00
Chris Robinson d964bb9f2f Fix length calculation for pulse 2009-10-31 19:30:12 -07:00
Chris Robinson 87dc7a5b97 Set a proper channel map for PulseAudio 2009-10-31 19:29:41 -07:00
Chris Robinson ae63ca481d Mix all updates PulseAudio requests 2009-10-31 17:59:30 -07:00
Chris Robinson 8e599103b6 Watch for buffer attribute changes from PulseAudio 2009-10-31 17:57:35 -07:00
Chris Robinson af0140e260 Use signals to watch for state changes
This partially reverts commit 617b6728d3
2009-10-31 17:52:26 -07:00
Chris Robinson 9d43907710 Properly free the device name 2009-10-31 13:25:26 -07:00
Chris Robinson a3fcd67a82 Remove some unneeded buffer fields, make padding a constant amount 2009-10-25 08:31:28 -07:00
Chris Robinson fe3a43e2d4 Remove the format and frequency from the source, get them manually 2009-10-25 06:26:19 -07:00
Chris Robinson e095047b02 Small fixups 2009-10-25 06:16:21 -07:00
Chris Robinson 31a106344f Calculate more store only once per loop 2009-10-25 05:34:47 -07:00
Chris Robinson b0a82aa420 Store the buffer format and frequency in the source when updated 2009-10-25 05:03:22 -07:00
Chris Robinson c003d6032d Retreive and store source params once per mix update 2009-10-25 04:39:36 -07:00
Chris Robinson 1665595138 Remove unneeded bufferlistitem properties 2009-10-25 02:59:31 -07:00
Chris Robinson bbccf76b45 Dereference left over buffers and slots when sources are released 2009-10-24 07:09:44 -07:00
Chris Robinson 1f47fa9243 Try 32-bit float before 16-bit, and stereo before mono 2009-10-24 03:20:47 -07:00
Chris Robinson 7b24a12a66 Check for the -pthread switch instead of using _REENTRANT 2009-10-23 10:36:32 -07:00
Chris Robinson 921e7ac3e9 Store the buffer handle directly in the source and buffer queue list 2009-10-22 09:31:26 -07:00
Chris Robinson 8d807add41 Store the bufferID in the buffer struct 2009-10-22 08:53:59 -07:00
Chris Robinson 8501fce38b Remove unused source fields 2009-10-21 15:40:09 -07:00
Chris Robinson 55d7984582 Set the calculated source parameters directly 2009-10-21 15:31:21 -07:00
Chris Robinson 8dbac9c0bd Store the calculated source parameters in the source struct 2009-10-21 14:25:54 -07:00
Chris Robinson 47b8510b0c Don't assume 16-bit samples 2009-10-21 13:50:53 -07:00
Chris Robinson 4e399b41cd Calculate source filter coefficients with the source parameters 2009-10-21 13:08:50 -07:00
Chris Robinson bdec1e037f Remove unnecessary variable 2009-10-21 12:48:04 -07:00
Chris Robinson 9924cce466 Make sure the ALSA device list is reset if no cards are found 2009-10-21 11:53:45 -07:00
Chris Robinson d3ecbd75af Clear the echo and delay lines even if the buffer doesn't change size 2009-10-21 02:03:33 -07:00
Chris Robinson 75b65ab2a2 Remove the Frequency field from the context 2009-10-20 13:47:55 -07:00
Chris Robinson eca8825ab4 Explicitly suspend the context being processed for mixing 2009-10-20 13:38:02 -07:00
Chris Robinson 9f9b7cf885 Make sure the context is properly locked while updating slots and sends 2009-10-20 13:02:28 -07:00
Chris Robinson cd695d7f15 Allow creating multiple contexts on a device 2009-10-20 12:58:19 -07:00
Chris Robinson 9c0ae597cd Make sure the effect slots and source sends are properly updated
Slots need to be updated due to possible frequency changes, and source sends
need to be updated in case some active sends were disabled
2009-10-20 12:53:07 -07:00
Chris Robinson 4461b4c56f Be more tolerant with resetting the fragment size 2009-10-20 12:28:51 -07:00
Chris Robinson 93361118b7 Store a device's contexts in a dynamic array 2009-10-20 11:54:04 -07:00
Chris Robinson 50f963f6c6 Don't try to clamp the listener-to-source velocity for local sources
Local sources will always have a 0 VLS value
2009-10-20 11:03:16 -07:00
Chris Robinson 67c3e47ed4 Avoid handling NaN when scaling float samples for output 2009-10-20 09:48:09 -07:00
Chris Robinson f14cf8289e Add a method to update device-dependant effect parameters.
The effect state's update method will be called afterwards
2009-10-20 08:31:44 -07:00
Chris Robinson 790aa68621 Reduce indentation for CalcSourceParams 2009-10-19 13:25:40 -07:00
Chris Robinson 6d1d61026d Be context-agnostic in the effect Create functions
This allows the effect Update functions to handle the playback frequency being
changed. By default the effects assume a maximum frequency of 192khz, however,
it can go higher at the cost of the sample buffers being cleared and the risk
of an abort() if reallocation fails
2009-10-19 07:46:53 -07:00
Chris Robinson a4e3ca933b EINTR is not a fatal write error 2009-10-19 00:33:00 -07:00
Chris Robinson 1fb58f9f8e Fix OSS and Solaris playback loop check 2009-10-17 22:17:59 -07:00
Chris Robinson 86e0b9386d Remove duplicate check in ALSA mmap playback 2009-10-16 10:57:58 -07:00
Chris Robinson c7c4cf221a Make the dry buffer part of the device 2009-10-09 01:06:33 -07:00
Chris Robinson d6e439244a Rename SetALCError for consistency 2009-10-07 04:32:14 -07:00
Chris Robinson 5ff225fa1b Add missing ) in pulseaudio backend 2009-10-02 07:34:49 -07:00
Chris Robinson 2a77e840cc Fix type casts for 7.1 output 2009-09-30 16:02:49 -07:00
Chris Robinson 00272883f6 Fallback to 16-bit or 8-bit, or mono, if ALSA doesn't accept the request 2009-09-27 08:35:10 -07:00
Chris Robinson bd6f3b1273 Report disconnect if the device fails to reset 2009-09-27 04:58:42 -07:00
Chris Robinson 4e9767bb22 Don't store the ALSA format 2009-09-27 04:03:11 -07:00
Chris Robinson 1d54b7a266 Fix capture, too 2009-09-27 03:57:19 -07:00
Chris Robinson c9506d939a Make sure ALSA properly loads, and fix the thread stop condition 2009-09-27 01:12:42 -07:00
Chris Robinson 21217824b7 Avoid duplicate error handling 2009-09-27 00:58:11 -07:00
Chris Robinson 8024df2991 Load backend libs on-demand 2009-09-27 00:21:40 -07:00
Chris Robinson f72b6fe717 Release 1.9.563 2009-09-26 01:42:21 -07:00
Chris Robinson 8d29d25d60 Condense some local variables 2009-09-24 14:51:40 -07:00
Chris Robinson af8e7ab984 Check the source start position in alSourcePlayv instead of the mixer 2009-09-24 12:24:10 -07:00
Chris Robinson 4289d5de7d Parse the attribute list and reset the device before creating the context 2009-09-24 11:31:01 -07:00
Chris Robinson 83734aff0e Slightly improve the multi-channel mixing loops 2009-09-24 08:52:51 -07:00
Chris Robinson 617b6728d3 Remove the state callbacks and watch for changes synchronously 2009-09-24 00:26:41 -07:00
Chris Robinson 7a8fd6cb20 Get rid of unnecessary messages from pulseaudio 2009-09-23 08:34:15 -07:00
Chris Robinson 55da339586 Properly clean up the pulse device 2009-09-23 08:19:00 -07:00
Chris Robinson 774eae0f2f Silence unused parameter warning 2009-09-23 07:10:23 -07:00
Chris Robinson 201b108a54 Attempt to reload backend libs when probing, if they didn't initially load 2009-09-23 01:33:58 -07:00
Chris Robinson bdbdbcea26 Update in properly-sized chunks for PulseAudio 2009-09-23 01:24:10 -07:00
Chris Robinson f6c1a21cf0 Properly flip the backend entries when sorting the device list 2009-09-22 04:42:46 -07:00
Chris Robinson c953072a15 Fix reset condition check 2009-09-22 00:16:21 -07:00
Chris Robinson 93f3e9357b (Re)allocate and clear the stereo-to-binaural filter as needed 2009-09-21 23:52:59 -07:00
Chris Robinson 8ea8b49464 Avoid locking a NULL context when a device is disconnected 2009-09-21 23:31:04 -07:00
Chris Robinson 62cef44dcb Reinitialize the stereo-to-binaural filter after resetting the device 2009-09-21 23:25:26 -07:00
Chris Robinson a2edc95207 Properly set the number of sends requested by the app 2009-09-21 23:18:39 -07:00
Chris Robinson 4cd41e3e08 Don't allow setting an invalid auxiliary send 2009-09-21 23:09:31 -07:00
Chris Robinson b641f993ac Hide the wave writer device if no output file is set 2009-09-21 05:03:40 -07:00
Chris Robinson e2905b6bc9 Properly handle forced 32-bit float output with DSound 2009-09-21 02:57:17 -07:00
Chris Robinson e11b59a80f Return imediately if trying to set an unknown format 2009-09-21 02:53:33 -07:00
Chris Robinson 0ae02e8ad4 Support floating point capture for backends that can handle it 2009-09-21 02:31:33 -07:00
Chris Robinson 2cbdffab86 Create the ALSA capture ring buffer with the proper size 2009-09-21 02:14:32 -07:00
Chris Robinson 86eefdb2a8 Mix all pending periods at once instead of one at a time 2009-09-20 00:44:39 -07:00
Chris Robinson 750399ccd7 Let verify_state restore from an ALSA underrun 2009-09-20 00:40:23 -07:00
Chris Robinson fb97ca6022 Remove left-over backend-specific period options 2009-09-16 23:29:32 -07:00
Chris Robinson cbcaa54173 Store the number of periods in the device instead of the buffer size
Also keep all the fields in sync
2009-09-16 22:58:54 -07:00
Chris Robinson 94e3fca702 Remove unnecessary parameters, and rename methods 2009-09-16 00:24:44 -07:00
Chris Robinson ffff104554 Restore the device frequency using the stream info 2009-09-16 00:08:11 -07:00
Chris Robinson 307a9dd1b2 Update the frequency with what the stream actually got set with 2009-09-15 23:14:14 -07:00
Chris Robinson 5dff8ea820 Properly terminate PortAudio when closing 2009-09-15 22:45:27 -07:00
Chris Robinson 49648fe22d Make a GetConfigValueBool function and use it 2009-09-15 22:18:13 -07:00
Chris Robinson 9f037e8980 Pass the device to aluMixData 2009-09-15 19:30:27 -07:00
Chris Robinson 12f81bcbb9 Move the stereo-to-binaural filter to the device 2009-09-15 19:06:47 -07:00
Chris Robinson 6636131d3b Pass the frame count to aluMixData 2009-09-15 18:19:00 -07:00
Chris Robinson eeea9631ce Split the source mixing loop into a separate function
Helps reduce the function size and indentation levels
2009-09-15 17:56:31 -07:00
Chris Robinson f9d228c30a Add missing context checks 2009-09-12 20:22:03 -07:00
Chris Robinson d516f8c4bd Update comment 2009-09-12 20:02:45 -07:00
Chris Robinson 5d1c3a0c63 Fix wave writer backend 2009-09-12 19:58:36 -07:00
Chris Robinson 396f2d6050 Mix the proper size for every update, and notify disconnects 2009-09-12 19:36:16 -07:00
Chris Robinson e25b01c3a2 Start Solaris playback when a context is ready 2009-09-12 18:19:52 -07:00
Chris Robinson b29a24afb0 Move the default out-of-tree build dir to build 2009-09-12 17:54:27 -07:00
Chris Robinson d6d1dba3d2 Initialize OpenAL with a constructor call instead of first-use 2009-09-12 17:49:08 -07:00
Chris Robinson 8b36a9d121 Get rid of deinit code duplication 2009-09-12 17:29:35 -07:00
Chris Robinson 59ed9338d8 Add support for the in-progress ALC_EXT_thread_local_context extension 2009-09-12 16:45:46 -07:00
Chris Robinson b444dea63b Fix compilation for Windows 2009-08-28 06:33:59 -07:00
Chris Robinson 1816c8bd37 Make a copy of the default device name for the app
The pointer to it could otherwise change if the device list is rebuilt, which
would be bad if the app has it
2009-08-27 20:13:35 -07:00
Chris Robinson c27948a7ee Don't free a NULL handle 2009-08-27 19:01:12 -07:00
Chris Robinson 832dc8a585 Remove unnecessary vars and rework device name checks 2009-08-27 18:55:18 -07:00
Chris Robinson bb121e68a6 Rebuild device lists when retrieving them 2009-08-27 06:09:33 -07:00
Chris Robinson 1ec26fd789 Dynamically allocate device lists 2009-08-27 03:55:36 -07:00
Chris Robinson 4ff4a7e3b9 Close some libs when deinitializing 2009-08-27 03:12:54 -07:00
Chris Robinson 6bb14e45ce Store a copy of the device name in the device 2009-08-27 02:53:09 -07:00
Chris Robinson 45dc804819 Store copies of the device names in the individual backends 2009-08-27 01:47:41 -07:00
Chris Robinson 81db01ebf1 Add a method to deinitialize backends 2009-08-26 23:45:00 -07:00
Chris Robinson 06c576a945 Support disconnect for OSS and Solaris 2009-08-26 21:49:38 -07:00
Chris Robinson 929b025fd6 Support disconnect for ALSA playback and capture
As a consequence for capture, mmap is no longer supported. Later on, supporting
mmap capture to write directly into the ring buffer is a possibility.
2009-08-26 21:27:10 -07:00
Chris Robinson 7976de05a5 Add base support for ALC_EXT_disconnect
Individual backends need to be updated to handle disconnection events
2009-08-26 19:15:17 -07:00
Chris Robinson 70c88879ab Add ALC_EXT_disconnect to alext.h 2009-08-26 18:29:25 -07:00
Chris Robinson 276ee63b99 Define PATH_MAX if it isn't already 2009-08-19 12:59:40 -07:00
Chris Robinson 487f0dde75 Print source and auxiliary slot debug warnings from alcDestroyContext 2009-08-16 16:11:22 -07:00
Chris Robinson c8f700930a More modifications and fixes for context checks 2009-08-16 16:02:13 -07:00
Chris Robinson decbe4df45 Modify some context checks 2009-08-16 15:09:36 -07:00
Chris Robinson 462f27c129 Use a function to retrieve the current context in an already-locked state
This should help prevent race-conditions with a context being destroyed between
breing retrieved and locked
2009-08-16 14:09:23 -07:00
Chris Robinson 2d1191697a Fix the Solaris backend 2009-08-16 13:16:41 -07:00
Chris Robinson 0b5a0d1e79 Reset the target if the databuffer being deleted is currently selected 2009-08-16 11:12:13 -07:00
Chris Robinson 0b7eb9f118 Add in-progress working extension AL_EXTX_sample_buffer_object 2009-08-16 00:54:08 -07:00
Chris Robinson dc26261065 Support 32-bit float output 2009-08-15 13:20:35 -07:00
Chris Robinson 9bea67fb1c Use a function to convert float to unsigned byte 2009-08-15 11:33:38 -07:00
Chris Robinson 8246bc3418 Use a custom function to get the requested format 2009-08-15 10:32:54 -07:00
Chris Robinson 01e32b58da Fix some size checks 2009-08-15 10:01:55 -07:00
Chris Robinson 9d05ff0468 Verify the device pointer is a valid device 2009-08-15 09:55:08 -07:00
Chris Robinson 510ccc7f17 Store the effect and filter lists in the device 2009-08-15 09:39:18 -07:00
Chris Robinson 43067ed2b8 Store the buffer list in the device 2009-08-15 09:14:08 -07:00
Chris Robinson 4e4c9aef15 Calculate the buffer size and frame size when needed 2009-08-14 13:08:25 -07:00
Chris Robinson 4031ee5ef0 Fix speaker override check 2009-08-14 07:27:19 -07:00
Chris Robinson e079291202 Remove unnecessary function parameters 2009-08-13 19:36:14 -07:00
Chris Robinson 826c641668 Hold the lock while finding a capture device to open 2009-08-13 19:19:16 -07:00
Chris Robinson 6ae845fd9e Don't let the device frequency change when PortAudio gets a new context 2009-08-13 17:13:37 -07:00
Chris Robinson a78fd58dca Create PulseAudio's playback stream when the AL context is created 2009-08-13 17:08:47 -07:00
Chris Robinson a8ae610489 Set context frequency only if it successfully starts 2009-08-13 15:35:10 -07:00
Chris Robinson b86a1e5797 Add a note about app and system defaults 2009-08-13 13:48:06 -07:00
Chris Robinson 45552a68ce Hold the lock while initializing context playback 2009-08-13 13:32:42 -07:00
Chris Robinson d46655fbb2 Support the ALC_FREQUENCY context attribute 2009-08-13 13:28:35 -07:00
Chris Robinson 87fee8c504 Start DSound playback at context creation 2009-08-13 13:11:05 -07:00
Chris Robinson 9ff0617807 Don't clamp the wave writer's update size 2009-08-13 12:35:42 -07:00
Chris Robinson 243939f94f Allow delaying playback start until context creation, and don't use UpdateSize to store the buffer size
This will make it possible to support the context attributes (frequency,
refresh, etc) for some backends
2009-08-13 12:28:46 -07:00
Chris Robinson 739385bd89 Add AL_EXT_BUFFER_DATA_STATIC to alext.h 2009-08-13 10:10:34 -07:00
Chris Robinson 32060f53cd Reset the buffer played count when the queue is removed via the AL_BUFFER property 2009-08-11 14:16:30 -07:00
Chris Robinson 4ee3972f15 Update queued buffer states when source looping is toggled 2009-08-11 07:57:18 -07:00
Chris Robinson 00a9cf4a85 Remove more unneeded variables 2009-07-07 21:11:13 -07:00
Chris Robinson 1dcd538ad9 Remove unneeded variables 2009-07-07 21:01:41 -07:00
Chris Robinson a8973514ba Don't load functions if libpulse failed to open 2009-07-07 12:51:18 -07:00
Chris Robinson 0ac9e57d28 Store the requested mono/stereo source count and sends in the device
Although the properties are set as context attributes, they are queried from
the device. If multiple contexts per device are ever supported, it would not
be straight forward about where to read the values from. This way, the
attributes can be treated as device-specific attributes that are updated when
a new context is created.
2009-07-06 03:09:01 -07:00
Chris Robinson 5460e85c40 Set the right access mode for non-mmap capture 2009-07-02 20:50:12 -07:00
Chris Robinson 432f0ba34c Specify the right format for ALSA recording 2009-07-02 20:32:19 -07:00
Chris Robinson 7e01e53445 Fix parsing of layout configuration string 2009-07-02 20:31:36 -07:00
Chris Robinson 043fe6edd2 Release 1.8.466 2009-06-07 22:30:08 -07:00
Chris Robinson ef68e5d0ff Protect ring buffer access with the lock 2009-06-07 21:34:05 -07:00
Chris Robinson c6f3a4e062 Move a couple inline functions into the header 2009-06-07 20:16:41 -07:00
Chris Robinson 87ed53c7f6 Don't read deprecated config files 2009-06-07 20:12:01 -07:00
Alam Arias 89e9437b84 add check for _WAVEFORMATEXTENSIBLE_ and define _WIN32_IE before inlcuding any header 2009-06-07 19:43:42 -07:00
Chris Robinson 1454c46b5f Use a thread-safe static inline function for printing 2009-06-07 15:42:15 -07:00
Chris Robinson 0fac1e9115 Store the max number of auxiliary slots in the device 2009-06-07 14:53:22 -07:00
Chris Robinson f3a3358e63 Fix for MSVC
MSVC won't accept zero-sized arrays at the end of structs, if that struct is
used in another struct that's not also at the end. This wastes a float for each
FILTER object
2009-06-06 23:33:53 -07:00
Chris Robinson 3c122b0bef Set an error if effect creation fails 2009-05-31 11:54:49 -07:00
Chris Robinson 7940003d06 Set an error if NaN is given for panning values 2009-05-31 11:34:07 -07:00
Chris Robinson 45b16ff456 Use the generic FILTER object for the master effect filter
Also fix a couple comments
2009-05-30 12:54:53 -07:00
Chris Robinson 9341f4f884 Fixup panning gain calculations
Clamp the panning vector magnitude to 1, and use an energy-reduction method as
the vector magnitude increases (to simulate reverb area occlusion)
2009-05-30 00:32:17 -07:00
Chris Robinson 2c20f26784 Apply slot gain on slot output, not input 2009-05-29 16:51:00 -07:00
Chris Robinson 2a21a449b4 Slot gain changes should have an immediate effect 2009-05-29 13:50:58 -07:00
Chris Robinson 74dc7090fd Don't expose effect-specific structures 2009-05-29 13:30:50 -07:00
Chris Robinson e12ac95d69 Use the MIN/MAX/DEFAULT macros for checking and setting the effect parameters 2009-05-29 12:40:08 -07:00
Chris Robinson 34ea7eba9e Add preliminary support for the EAX Reverb effect
Not all parameters are supported yet, though it is a little more fuctional than
standard reverb
2009-05-29 01:32:54 -07:00
Chris Robinson 6d3ba44f55 Don't update the devicevalues before returning success 2009-05-27 07:02:33 -07:00
Chris Robinson 5a8ad67660 Lock the context before getting the mmap region to update 2009-05-26 14:54:59 -07:00
Chris Robinson f1e442408b Set the correct data size 2009-05-26 14:51:57 -07:00
Chris Robinson a946af4463 Simplify ALSA PCM parameter retrieval 2009-05-26 10:08:27 -07:00
Chris Robinson e01cd92d56 Set avail_min so snd_pcm_wait will wait for the full update to be ready 2009-05-26 10:03:17 -07:00
Chris Robinson 923af8c3a6 Don't update the source's gains in the sample mixing loop
Update copies stored on the stack instead, then update the source after mixing
2009-05-26 09:23:49 -07:00
Chris Robinson ac04cf57fa Make sure _CRT_SECURE_NO_WARNINGS is always defined for MSVC 2009-05-26 06:02:40 -07:00
Chris Robinson 1f6c4e01db Properly fall back to non-mmap capture if the parameters fail 2009-05-25 16:06:03 -07:00
Chris Robinson 04135723a2 Get rid of the ugly ok() macro 2009-05-25 13:07:49 -07:00
Chris Robinson 93fbdb1e6c Redo OSS mixing loop 2009-05-25 12:12:37 -07:00
Chris Robinson c1de15f840 Update in descrete amounts using the update size 2009-05-25 12:01:14 -07:00
Chris Robinson 3be399c555 Do not open pulseaudio if it didn't load 2009-05-19 06:37:22 -07:00
Chris Robinson 1f5453075c Dynamically load PulseAudio 2009-05-19 06:35:12 -07:00
Chris Robinson 33a74f1594 Clear the filter history directly 2009-05-17 22:50:07 -07:00
Chris Robinson e4da1224cb Optionally install the sample configuration file 2009-05-17 22:36:45 -07:00
Chris Robinson 5c2a47620c Reformat the sample config file 2009-05-17 22:24:29 -07:00
Chris Robinson 1bfa7609d2 Make the filter functions global inline, and use it for echo 2009-05-16 23:34:26 -07:00
Chris Robinson 7e8501123a Set some common macros in alu.h 2009-05-16 23:26:39 -07:00
Chris Robinson c447eeb2c7 Use the source reference distance to specify full panning magnitude
Sources that are closer than the specified reference distance will not pan to
full magnitude, thus providing a smoother transition as it moves around near
the listener
2009-05-16 03:54:16 -07:00
Chris Robinson ad19cea6e0 Make sure DSSPEAKER_5POINT1 is defined 2009-05-14 05:24:18 -07:00
Chris Robinson 0ce29863e3 Prevent spawning PulseAudio if it's not already running 2009-05-06 00:19:35 -07:00
Chris Robinson 7a7a4844f4 Make the filter history buffer size flexible
This lets the filter history buffer be as big as needed for a given use, so
that it can have a size large enough for the more demanding cases, but not be
wasteful for lesser-demanding cases, while not incuring the overhead of an
added pointer indirection
2009-04-16 05:43:09 -07:00
Chris Robinson a2adbb1ab5 Add a PulseAudio backend 2009-04-16 05:17:42 -07:00
Chris Robinson a97fc792d8 Increase the default maximum number of sends to 2 2009-04-14 22:18:47 -07:00
Chris Robinson e9a6a1d6f5 Use a 2-pole filter for the wet path low-pass filter
This should help keep CPU use from increasing a lot when the number of sends
increases. Also changes the function names to reflect the difference
2009-04-14 22:04:18 -07:00
Chris Robinson f245f0ef87 Make the number of source sends variable
The highest value is clamped to MAX_SENDS
2009-04-13 20:33:41 -07:00
Chris Robinson a30f431b63 Reduce the number of send loops 2009-04-13 02:50:40 -07:00
Chris Robinson 58f48f20e2 Rename Standard Reverb to Reverb 2009-04-13 02:01:21 -07:00
Chris Robinson ee1b02b709 Fix comment regarding the 3rd echo tap 2009-04-12 18:54:26 -07:00
Chris Robinson 55c790c9ff Add the Echo effect 2009-04-12 16:01:10 -07:00
Chris Robinson 65b69f3308 Fix air absorption 2009-04-11 20:27:55 -07:00
Chris Robinson c67fbd72dd Pay attention to the MAX_SENDS value 2009-04-11 20:04:46 -07:00
Chris Robinson 30f57d0824 Make auxiliary effect slot count configurable 2009-04-11 18:16:05 -07:00
Chris Robinson 1c54018111 Move the WetBuffer into the effect slot object
This should make it easier to support multiple slots
2009-04-11 17:04:55 -07:00
Chris Robinson e80e1b6d9f Use LIB_SUFFIX when creating the default lib install dir
Thanks to Hanno Böck for pointing this out
2009-04-07 12:11:41 -07:00
Chris Robinson 437f00d6de Add missing comment markers 2009-04-07 11:41:41 -07:00
Chris Robinson fc6d6b1601 Use the square of the values when calculating the density gain 2009-03-21 10:42:42 -07:00
Chris Robinson 9306e36d52 Make sure M_PI is defined for reverb 2009-03-15 23:14:40 -07:00
Chris Robinson 61122a5093 Release 1.7.411 2009-03-14 22:24:59 -07:00
Chris Robinson a8a4ff8af1 Constify some parameters 2009-03-13 23:08:15 -07:00
Chris Robinson 8a857c35ee Calculate filter coefficients in aluMixData 2009-03-13 22:58:54 -07:00
Chris Robinson 89ddd7d8e5 Don't modify the device struct until playback succesfully starts 2009-03-13 22:16:01 -07:00
Chris Robinson 8d0c4ccb3b The room rolloff factor can go up to 10 2009-03-13 02:12:45 -07:00
Chris Robinson 8ee47d5573 Dynamically load dsound when possible 2009-03-10 02:46:42 -07:00
Chris Robinson 9e88011417 Add a cast for setting a dummy pointer value 2009-03-10 02:20:05 -07:00
Chris Robinson f8949ee7a1 Always add the default ALSA device even if no cards are present 2009-03-10 01:46:51 -07:00
Chris Robinson 62aa2d0ba7 Only expose the default ALSA device in standard enumeration 2009-03-10 01:28:01 -07:00
Chris Robinson ace047d625 Append the card and device indices to the ALSA device strings 2009-03-10 01:21:42 -07:00
Chris Robinson d6277db209 Fix alsoftrc configuration sample comments 2009-03-10 01:08:03 -07:00
Chris Robinson 7ebb28327f Remove the SDL backend 2009-03-10 01:03:39 -07:00
Chris Robinson 86931cbde4 Add a PortAudio backend 2009-03-10 00:55:29 -07:00
Chris Robinson 6d7be151dc Remove the unneeded path from the cross-compiler commands 2009-03-06 20:09:44 -08:00
Chris Robinson 07227b9806 Use a modified reverb model that obeys the reverb parameters better 2009-03-02 18:48:23 -08:00
Chris Robinson 8348d719cd Clamp gain of multichannel sources 2009-02-10 15:15:49 -08:00
Chris Robinson 0fcefd865b Install the pkgconfig file to the correct directory 2009-02-10 14:39:48 -08:00
Chris Robinson 57c2e9b5f8 Include assert.h for assert() 2009-02-02 11:18:33 -08:00
Chris Robinson 7d7fc39035 Use calculated distance from reference for air absorption 2009-01-30 10:56:25 -08:00
Chris Robinson 351105b3df Fix incorrect comment 2009-01-30 10:53:09 -08:00
Chris Robinson cbfc33215b Use M_PI since it is sure to be defined 2009-01-27 07:11:58 -08:00
Chris Robinson 5a93b56673 Fix ignored return value warning 2009-01-26 08:10:05 -08:00
Chris Robinson 1f4c69c17a Use a matrix for up- and down-mixing channels 2009-01-25 22:11:07 -08:00
Chris Robinson f5b19fad20 Duplicate stereo onto the side channels as well as the back 2009-01-25 19:54:50 -08:00
Chris Robinson bc60818e9a Don't read stereo layout when output is mono 2009-01-25 19:33:52 -08:00
Chris Robinson f82c88f016 Add options for user-configurable speaker arrangements 2009-01-25 19:20:47 -08:00
Chris Robinson 98e86decad 6.1 uses front- and back-center, not left- and right-back channels 2009-01-24 15:13:14 -08:00
Chris Robinson aaf2c0ebd4 Seperate mixing loops depending on source channel configuration 2009-01-24 13:57:01 -08:00
Chris Robinson 778b74cae1 Reimplement panning using lookup tables, based on a patch by Christian Borss
This allows speaker positions to be specified by discrete angles around the
listener, providing more flexibility and configurability in placement.
Additional patches to take advantage of this are forthcoming.
2009-01-24 10:38:04 -08:00
Chris Robinson 43ee1edd97 Properly capitalize the libname in Win32 2009-01-10 21:23:53 -08:00
Chris Robinson dd7e23740b Remove XCOMPILEWIN32 option in favor of CMake 2.6's cross-compiling caps 2008-12-12 11:19:38 -08:00
Chris Robinson 1acd6da745 Search for SDL.h in addition to SDL/SDL.h 2008-12-12 11:09:23 -08:00
Chris Robinson 3056f91ec5 Apply the dry filter to multi-channel sources
Unlike mono sources, they use 2 chained one-pole filters instead of 4
2008-12-10 11:54:13 -08:00
Chris Robinson ed03570e1a Fix some CMake checks 2008-12-07 02:20:17 -08:00
Chris Robinson 2ec0e48d06 Protect playback device opening with a mutex lock 2008-12-07 01:07:54 -08:00
Chris Robinson 8b54d59b8c Add an SDL backend 2008-12-07 01:05:39 -08:00
Chris Robinson f6a4dbabdd Add cast for setting a dummy pointer value 2008-12-06 12:17:29 -08:00
Chris Robinson a71c291bcb Let CMAKE_DEBUG_POSTFIX be exposed for graphical CMake front-ends 2008-12-02 02:37:51 -08:00
Chris Robinson 55b9ccc2de Implement AL_EXTX_source_distance_model
As with other EXTX extensions, this is subject to change and removal as the
spec gets worked on
2008-11-25 18:56:10 -08:00
46 changed files with 10477 additions and 4974 deletions
+1 -1
View File
@@ -1 +1 @@
CMakeConf
build
+1008 -480
View File
File diff suppressed because it is too large Load Diff
+1325 -1004
View File
File diff suppressed because it is too large Load Diff
+25 -18
View File
@@ -18,6 +18,10 @@
* Or go to http://www.gnu.org/copyleft/lgpl.html
*/
#ifdef _WIN32
#define _WIN32_IE 0x400
#endif
#include "config.h"
#include <stdlib.h>
@@ -27,8 +31,7 @@
#include "alMain.h"
#ifdef _WIN32
#define _WIN32_IE 0x400
#ifdef _WIN32_IE
#include <shlobj.h>
#endif
@@ -219,13 +222,6 @@ void ReadALConfig(void)
}
#else
f = fopen("/etc/openal/alsoft.conf", "r");
if(!f)
{
f = fopen("/etc/openal/config", "r");
if(f)
AL_PRINT("Reading /etc/openal/config; this file is deprecated\n"
"\tPlease rename it to /etc/openal/alsoft.conf\n");
}
if(f)
{
LoadConfigFromFile(f);
@@ -235,14 +231,6 @@ void ReadALConfig(void)
{
snprintf(buffer, sizeof(buffer), "%s/.alsoftrc", getenv("HOME"));
f = fopen(buffer, "r");
if(!f)
{
snprintf(buffer, sizeof(buffer), "%s/.openalrc", getenv("HOME"));
f = fopen(buffer, "r");
if(f)
AL_PRINT("Reading ~/.openalrc; this file is deprecated\n"
"\tPlease rename it to ~/.alsoftrc\n");
}
if(f)
{
LoadConfigFromFile(f);
@@ -298,7 +286,11 @@ const char *GetConfigValue(const char *blockName, const char *keyName, const cha
for(j = 0;j < cfgBlocks[i].entryCount;j++)
{
if(strcasecmp(cfgBlocks[i].entries[j].key, keyName) == 0)
return cfgBlocks[i].entries[j].value;
{
if(cfgBlocks[i].entries[j].value[0])
return cfgBlocks[i].entries[j].value;
return def;
}
}
}
}
@@ -306,6 +298,12 @@ const char *GetConfigValue(const char *blockName, const char *keyName, const cha
return def;
}
int ConfigValueExists(const char *blockName, const char *keyName)
{
const char *val = GetConfigValue(blockName, keyName, "");
return !!val[0];
}
int GetConfigValueInt(const char *blockName, const char *keyName, int def)
{
const char *val = GetConfigValue(blockName, keyName, "");
@@ -325,3 +323,12 @@ float GetConfigValueFloat(const char *blockName, const char *keyName, float def)
return (float)strtod(val, NULL);
#endif
}
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);
}
+192
View File
@@ -0,0 +1,192 @@
/**
* 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 LR gains for the first tap. The second tap uses the reverse
ALfloat GainL;
ALfloat GainR;
ALfloat FeedGain;
FILTER iirFilter;
ALfloat history[2];
} ALechoState;
ALvoid EchoDestroy(ALeffectState *effect)
{
ALechoState *state = (ALechoState*)effect;
if(state)
{
free(state->SampleBuffer);
state->SampleBuffer = NULL;
free(state);
}
}
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 = (ALuint)(AL_ECHO_MAX_DELAY * Device->Frequency) + 1;
maxlen += (ALuint)(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)
{
alSetError(AL_OUT_OF_MEMORY);
return AL_FALSE;
}
state->SampleBuffer = temp;
state->BufferLength = maxlen;
}
for(i = 0;i < state->BufferLength;i++)
state->SampleBuffer[i] = 0.0f;
return AL_TRUE;
}
ALvoid EchoUpdate(ALeffectState *effect, ALCcontext *Context, const ALeffect *Effect)
{
ALechoState *state = (ALechoState*)effect;
ALuint frequency = Context->Device->Frequency;
ALfloat lrpan, cw, a, g;
state->Tap[0].delay = (ALuint)(Effect->Echo.Delay * frequency) + 1;
state->Tap[1].delay = (ALuint)(Effect->Echo.LRDelay * frequency);
state->Tap[1].delay += state->Tap[0].delay;
lrpan = Effect->Echo.Spread*0.5f + 0.5f;
state->GainL = aluSqrt( lrpan);
state->GainR = aluSqrt(1.0f-lrpan);
state->FeedGain = Effect->Echo.Feedback;
cw = cos(2.0*M_PI * LOWPASSFREQCUTOFF / frequency);
g = 1.0f - Effect->Echo.Damping;
a = 0.0f;
if(g < 0.9999f) // 1-epsilon
a = (1 - g*cw - aluSqrt(2*g*(1-cw) - g*g*(1 - cw*cw))) / (1 - g);
state->iirFilter.coeff = a;
}
ALvoid EchoProcess(ALeffectState *effect, const ALeffectslot *Slot, ALuint SamplesToDo, const ALfloat *SamplesIn, ALfloat (*SamplesOut)[OUTPUTCHANNELS])
{
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;
const ALfloat gain = Slot->Gain;
ALfloat samp[2], smp;
ALuint i;
for(i = 0;i < SamplesToDo;i++,offset++)
{
// Sample first tap
smp = state->SampleBuffer[(offset-tap1) & mask];
samp[0] = smp * state->GainL;
samp[1] = smp * state->GainR;
// Sample second tap. Reverse LR panning
smp = state->SampleBuffer[(offset-tap2) & mask];
samp[0] += smp * state->GainR;
samp[1] += smp * state->GainL;
// 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;
// Apply slot gain
samp[0] *= gain;
samp[1] *= gain;
SamplesOut[i][FRONT_LEFT] += samp[0];
SamplesOut[i][FRONT_RIGHT] += samp[1];
SamplesOut[i][SIDE_LEFT] += samp[0];
SamplesOut[i][SIDE_RIGHT] += samp[1];
SamplesOut[i][BACK_LEFT] += samp[0];
SamplesOut[i][BACK_RIGHT] += samp[1];
}
state->Offset = offset;
}
ALeffectState *EchoCreate(void)
{
ALechoState *state;
state = malloc(sizeof(*state));
if(!state)
{
alSetError(AL_OUT_OF_MEMORY);
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->GainL = 0.0f;
state->GainR = 0.0f;
state->iirFilter.coeff = 0.0f;
state->iirFilter.history[0] = 0.0f;
state->iirFilter.history[1] = 0.0f;
return &state->state;
}
+1128 -358
View File
File diff suppressed because it is too large Load Diff
+4 -2
View File
@@ -81,10 +81,11 @@ ALsizei RingBufferSize(RingBuffer *ring)
void WriteRingBuffer(RingBuffer *ring, const ALubyte *data, ALsizei len)
{
int remain = ring->length - ring->write_pos;
int remain;
EnterCriticalSection(&ring->cs);
remain = ring->length - ring->write_pos;
if((ring->read_pos-ring->write_pos+ring->length)%ring->length < len)
ring->read_pos = (ring->write_pos+len) % ring->length;
@@ -104,10 +105,11 @@ void WriteRingBuffer(RingBuffer *ring, const ALubyte *data, ALsizei len)
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);
+617 -587
View File
File diff suppressed because it is too large Load Diff
-2
View File
@@ -113,8 +113,6 @@ static void init(struct bs2b *bs2b)
bs2b->a1_hi = -x;
bs2b->gain = 1.0 / (1.0 - G_hi + G_lo);
bs2b_clear(bs2b);
} /* init */
/* Exported functions.
+256 -101
View File
@@ -28,19 +28,29 @@
#include <dsound.h>
#include <mmreg.h>
#ifndef _WAVEFORMATEXTENSIBLE_
#include <ks.h>
#include <ksmedia.h>
#endif
#include "alMain.h"
#include "AL/al.h"
#include "AL/alc.h"
#ifndef DSSPEAKER_5POINT1
#define DSSPEAKER_5POINT1 6
#endif
#ifndef DSSPEAKER_7POINT1
#define DSSPEAKER_7POINT1 7
#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);
static void *ds_handle;
static HRESULT (WINAPI *pDirectSoundCreate)(LPCGUID pcGuidDevice, LPDIRECTSOUND *ppDS, LPUNKNOWN pUnkOuter);
static HRESULT (WINAPI *pDirectSoundEnumerateA)(LPDSENUMCALLBACKA pDSEnumCallback, LPVOID pContext);
// Since DSound doesn't report the fragment size, emulate it
static int num_frags;
typedef struct {
// DirectSound Playback Device
@@ -57,36 +67,104 @@ typedef struct {
ALCchar *name;
GUID guid;
} DevMap;
static DevMap DeviceList[16];
static const ALCchar dsDevice[] = "DirectSound Software";
static DevMap *DeviceList;
static ALuint NumDevices;
static volatile ALuint load_count;
void *DSoundLoad(void)
{
if(load_count == 0)
{
#ifdef _WIN32
ds_handle = LoadLibraryA("dsound.dll");
if(ds_handle == NULL)
{
AL_PRINT("Failed to load dsound.dll\n");
return NULL;
}
#define LOAD_FUNC(f) do { \
p##f = (void*)GetProcAddress((HMODULE)ds_handle, #f); \
if(p##f == NULL) \
{ \
FreeLibrary(ds_handle); \
ds_handle = NULL; \
AL_PRINT("Could not load %s from dsound.dll\n", #f); \
return NULL; \
} \
} while(0)
#else
ds_handle = (void*)0xDEADBEEF;
#define LOAD_FUNC(f) p##f = f
#endif
LOAD_FUNC(DirectSoundCreate);
LOAD_FUNC(DirectSoundEnumerateA);
#undef LOAD_FUNC
}
++load_count;
return ds_handle;
}
void DSoundUnload(void)
{
if(load_count == 0 || --load_count > 0)
return;
#ifdef _WIN32
FreeLibrary(ds_handle);
#endif
ds_handle = NULL;
}
static ALuint DSoundProc(ALvoid *ptr)
{
ALCdevice *pDevice = (ALCdevice*)ptr;
DSoundData *pData = (DSoundData*)pDevice->ExtraData;
DSBCAPS DSBCaps;
DWORD LastCursor = 0;
DWORD PlayCursor;
VOID *WritePtr1, *WritePtr2;
DWORD WriteCnt1, WriteCnt2;
DWORD BufferSize;
DWORD FrameSize;
DWORD FragSize;
DWORD avail;
HRESULT err;
BufferSize = pDevice->UpdateSize * num_frags *
aluBytesFromFormat(pDevice->Format) *
aluChannelsFromFormat(pDevice->Format);
EnableRTPrio(RTPrioLevel);
memset(&DSBCaps, 0, sizeof(DSBCaps));
DSBCaps.dwSize = sizeof(DSBCaps);
err = IDirectSoundBuffer_GetCaps(pData->DSsbuffer, &DSBCaps);
if(FAILED(err))
{
AL_PRINT("Failed to get buffer caps: 0x%lx\n", err);
aluHandleDisconnect(pDevice);
return 1;
}
FrameSize = aluChannelsFromFormat(pDevice->Format) *
aluBytesFromFormat(pDevice->Format);
FragSize = pDevice->UpdateSize * FrameSize;
IDirectSoundBuffer_GetCurrentPosition(pData->DSsbuffer, &LastCursor, NULL);
while(!pData->killNow)
{
// Get current play and write cursors
IDirectSoundBuffer_GetCurrentPosition(pData->DSsbuffer, &PlayCursor, NULL);
avail = (PlayCursor-LastCursor+BufferSize) % BufferSize;
avail = (PlayCursor-LastCursor+DSBCaps.dwBufferBytes) % DSBCaps.dwBufferBytes;
if(avail < BufferSize/num_frags)
if(avail < FragSize)
{
Sleep(1);
continue;
}
avail -= avail%FragSize;
// Lock output buffer
WriteCnt1 = 0;
@@ -107,10 +185,8 @@ static ALuint DSoundProc(ALvoid *ptr)
if(SUCCEEDED(err))
{
// If we have an active context, mix data directly into output buffer otherwise fill with silence
SuspendContext(NULL);
aluMixData(pDevice->Context, WritePtr1, WriteCnt1, pDevice->Format);
aluMixData(pDevice->Context, WritePtr2, WriteCnt2, pDevice->Format);
ProcessContext(NULL);
aluMixData(pDevice, WritePtr1, WriteCnt1/FrameSize);
aluMixData(pDevice, WritePtr2, WriteCnt2/FrameSize);
// Unlock output buffer only when successfully locked
IDirectSoundBuffer_Unlock(pData->DSsbuffer, WritePtr1, WriteCnt1, WritePtr2, WriteCnt2);
@@ -120,7 +196,7 @@ static ALuint DSoundProc(ALvoid *ptr)
// Update old write cursor location
LastCursor += WriteCnt1+WriteCnt2;
LastCursor %= BufferSize;
LastCursor %= DSBCaps.dwBufferBytes;
}
return 0;
@@ -128,67 +204,98 @@ static ALuint DSoundProc(ALvoid *ptr)
static ALCboolean DSoundOpenPlayback(ALCdevice *device, const ALCchar *deviceName)
{
DSBUFFERDESC DSBDescription;
DSoundData *pData = NULL;
WAVEFORMATEXTENSIBLE OutputType;
DWORD frameSize = 0;
LPGUID guid = NULL;
DWORD speakers;
HRESULT hr;
if(deviceName)
if(!deviceName)
deviceName = dsDevice;
else if(strcmp(deviceName, dsDevice) != 0)
{
int i;
for(i = 0;DeviceList[i].name;i++)
ALuint i;
for(i = 0;i < NumDevices;i++)
{
if(strcmp(deviceName, DeviceList[i].name) == 0)
{
device->szDeviceName = DeviceList[i].name;
if(i > 0)
guid = &DeviceList[i].guid;
guid = &DeviceList[i].guid;
break;
}
}
if(!DeviceList[i].name)
if(i == NumDevices)
return ALC_FALSE;
}
else
device->szDeviceName = DeviceList[0].name;
memset(&OutputType, 0, sizeof(OutputType));
if(!DSoundLoad())
return ALC_FALSE;
//Initialise requested device
pData = calloc(1, sizeof(DSoundData));
if(!pData)
{
SetALCError(ALC_OUT_OF_MEMORY);
alcSetError(device, ALC_OUT_OF_MEMORY);
DSoundUnload();
return ALC_FALSE;
}
//DirectSound Init code
hr = DirectSoundCreate(guid, &pData->lpDS, NULL);
hr = pDirectSoundCreate(guid, &pData->lpDS, NULL);
if(SUCCEEDED(hr))
hr = IDirectSound_SetCooperativeLevel(pData->lpDS, GetForegroundWindow(), DSSCL_PRIORITY);
if(SUCCEEDED(hr))
if(FAILED(hr))
{
if(*(GetConfigValue(NULL, "format", "")) == 0)
hr = IDirectSound_GetSpeakerConfig(pData->lpDS, &speakers);
if(pData->lpDS)
IDirectSound_Release(pData->lpDS);
free(pData);
DSoundUnload();
return ALC_FALSE;
}
device->szDeviceName = strdup(deviceName);
device->ExtraData = pData;
return ALC_TRUE;
}
static void DSoundClosePlayback(ALCdevice *device)
{
DSoundData *pData = device->ExtraData;
IDirectSound_Release(pData->lpDS);
free(pData);
device->ExtraData = NULL;
DSoundUnload();
}
static ALCboolean DSoundResetPlayback(ALCdevice *device)
{
DSoundData *pData = (DSoundData*)device->ExtraData;
DSBUFFERDESC DSBDescription;
WAVEFORMATEXTENSIBLE OutputType;
DWORD frameSize = 0;
ALenum format = 0;
DWORD speakers;
HRESULT hr;
memset(&OutputType, 0, sizeof(OutputType));
hr = IDirectSound_GetSpeakerConfig(pData->lpDS, &speakers);
if(SUCCEEDED(hr) && ConfigValueExists(NULL, "format"))
{
if(aluChannelsFromFormat(device->Format) == 1)
speakers = DSSPEAKER_COMBINED(DSSPEAKER_MONO, 0);
else if(aluChannelsFromFormat(device->Format) == 2)
speakers = DSSPEAKER_COMBINED(DSSPEAKER_STEREO, 0);
else if(aluChannelsFromFormat(device->Format) == 4)
speakers = DSSPEAKER_COMBINED(DSSPEAKER_QUAD, 0);
else if(aluChannelsFromFormat(device->Format) == 6)
speakers = DSSPEAKER_COMBINED(DSSPEAKER_5POINT1, 0);
else if(aluChannelsFromFormat(device->Format) == 8)
speakers = DSSPEAKER_COMBINED(DSSPEAKER_7POINT1, 0);
else
{
if(device->Format == AL_FORMAT_MONO8 || device->Format == AL_FORMAT_MONO16)
speakers = DSSPEAKER_COMBINED(DSSPEAKER_MONO, 0);
else if(device->Format == AL_FORMAT_STEREO8 || device->Format == AL_FORMAT_STEREO16)
speakers = DSSPEAKER_COMBINED(DSSPEAKER_STEREO, 0);
else if(device->Format == AL_FORMAT_QUAD8 || device->Format == AL_FORMAT_QUAD16)
speakers = DSSPEAKER_COMBINED(DSSPEAKER_QUAD, 0);
else if(device->Format == AL_FORMAT_51CHN8 || device->Format == AL_FORMAT_51CHN16)
speakers = DSSPEAKER_COMBINED(DSSPEAKER_5POINT1, 0);
else if(device->Format == AL_FORMAT_71CHN8 || device->Format == AL_FORMAT_71CHN16)
speakers = DSSPEAKER_COMBINED(DSSPEAKER_7POINT1, 0);
else
hr = IDirectSound_GetSpeakerConfig(pData->lpDS, &speakers);
AL_PRINT("Unknown format: 0x%x\n", device->Format);
return ALC_FALSE;
}
}
if(SUCCEEDED(hr))
@@ -197,23 +304,29 @@ static ALCboolean DSoundOpenPlayback(ALCdevice *device, const ALCchar *deviceNam
if(speakers == DSSPEAKER_MONO)
{
if(aluBytesFromFormat(device->Format) == 1)
device->Format = AL_FORMAT_MONO8;
else
device->Format = AL_FORMAT_MONO16;
format = AL_FORMAT_MONO8;
else if(aluBytesFromFormat(device->Format) == 2)
format = AL_FORMAT_MONO16;
else if(aluBytesFromFormat(device->Format) == 4)
format = AL_FORMAT_MONO_FLOAT32;
}
else if(speakers == DSSPEAKER_STEREO)
{
if(aluBytesFromFormat(device->Format) == 1)
device->Format = AL_FORMAT_STEREO8;
else
device->Format = AL_FORMAT_STEREO16;
format = AL_FORMAT_STEREO8;
else if(aluBytesFromFormat(device->Format) == 2)
format = AL_FORMAT_STEREO16;
else if(aluBytesFromFormat(device->Format) == 4)
format = AL_FORMAT_STEREO_FLOAT32;
}
else if(speakers == DSSPEAKER_QUAD)
{
if(aluBytesFromFormat(device->Format) == 1)
device->Format = AL_FORMAT_QUAD8;
else
device->Format = AL_FORMAT_QUAD16;
format = AL_FORMAT_QUAD8;
else if(aluBytesFromFormat(device->Format) == 2)
format = AL_FORMAT_QUAD16;
else if(aluBytesFromFormat(device->Format) == 4)
format = AL_FORMAT_QUAD32;
OutputType.dwChannelMask = SPEAKER_FRONT_LEFT |
SPEAKER_FRONT_RIGHT |
SPEAKER_BACK_LEFT |
@@ -222,9 +335,11 @@ static ALCboolean DSoundOpenPlayback(ALCdevice *device, const ALCchar *deviceNam
else if(speakers == DSSPEAKER_5POINT1)
{
if(aluBytesFromFormat(device->Format) == 1)
device->Format = AL_FORMAT_51CHN8;
else
device->Format = AL_FORMAT_51CHN16;
format = AL_FORMAT_51CHN8;
else if(aluBytesFromFormat(device->Format) == 2)
format = AL_FORMAT_51CHN16;
else if(aluBytesFromFormat(device->Format) == 4)
format = AL_FORMAT_51CHN32;
OutputType.dwChannelMask = SPEAKER_FRONT_LEFT |
SPEAKER_FRONT_RIGHT |
SPEAKER_FRONT_CENTER |
@@ -235,9 +350,11 @@ static ALCboolean DSoundOpenPlayback(ALCdevice *device, const ALCchar *deviceNam
else if(speakers == DSSPEAKER_7POINT1)
{
if(aluBytesFromFormat(device->Format) == 1)
device->Format = AL_FORMAT_71CHN8;
else
device->Format = AL_FORMAT_71CHN16;
format = AL_FORMAT_71CHN8;
else if(aluBytesFromFormat(device->Format) == 2)
format = AL_FORMAT_71CHN16;
else if(aluBytesFromFormat(device->Format) == 4)
format = AL_FORMAT_71CHN32;
OutputType.dwChannelMask = SPEAKER_FRONT_LEFT |
SPEAKER_FRONT_RIGHT |
SPEAKER_FRONT_CENTER |
@@ -247,26 +364,28 @@ static ALCboolean DSoundOpenPlayback(ALCdevice *device, const ALCchar *deviceNam
SPEAKER_SIDE_LEFT |
SPEAKER_SIDE_RIGHT;
}
frameSize = aluBytesFromFormat(device->Format) *
aluChannelsFromFormat(device->Format);
else
format = device->Format;
frameSize = aluBytesFromFormat(format) * aluChannelsFromFormat(format);
OutputType.Format.wFormatTag = WAVE_FORMAT_PCM;
OutputType.Format.nChannels = aluChannelsFromFormat(device->Format);
OutputType.Format.wBitsPerSample = aluBytesFromFormat(device->Format) * 8;
OutputType.Format.nChannels = aluChannelsFromFormat(format);
OutputType.Format.wBitsPerSample = aluBytesFromFormat(format) * 8;
OutputType.Format.nBlockAlign = OutputType.Format.nChannels*OutputType.Format.wBitsPerSample/8;
OutputType.Format.nSamplesPerSec = device->Frequency;
OutputType.Format.nAvgBytesPerSec = OutputType.Format.nSamplesPerSec*OutputType.Format.nBlockAlign;
OutputType.Format.cbSize = 0;
device->UpdateSize /= num_frags;
}
if(OutputType.Format.nChannels > 2)
if(OutputType.Format.nChannels > 2 || OutputType.Format.wBitsPerSample > 16)
{
OutputType.Format.wFormatTag = WAVE_FORMAT_EXTENSIBLE;
OutputType.Samples.wValidBitsPerSample = OutputType.Format.wBitsPerSample;
OutputType.Format.cbSize = 22;
OutputType.SubFormat = KSDATAFORMAT_SUBTYPE_PCM;
if(OutputType.Format.wBitsPerSample == 32)
OutputType.SubFormat = KSDATAFORMAT_SUBTYPE_IEEE_FLOAT;
else
OutputType.SubFormat = KSDATAFORMAT_SUBTYPE_PCM;
}
else
{
@@ -286,7 +405,7 @@ static ALCboolean DSoundOpenPlayback(ALCdevice *device, const ALCchar *deviceNam
memset(&DSBDescription,0,sizeof(DSBUFFERDESC));
DSBDescription.dwSize=sizeof(DSBUFFERDESC);
DSBDescription.dwFlags=DSBCAPS_GLOBALFOCUS|DSBCAPS_GETCURRENTPOSITION2;
DSBDescription.dwBufferBytes=device->UpdateSize * num_frags * frameSize;
DSBDescription.dwBufferBytes=device->UpdateSize * device->NumUpdates * frameSize;
DSBDescription.lpwfxFormat=&OutputType.Format;
hr = IDirectSound_CreateSoundBuffer(pData->lpDS, &DSBDescription, &pData->DSsbuffer, NULL);
}
@@ -296,7 +415,8 @@ static ALCboolean DSoundOpenPlayback(ALCdevice *device, const ALCchar *deviceNam
if(SUCCEEDED(hr))
{
device->ExtraData = pData;
device->Format = format;
SetDefaultWFXChannelOrder(device);
pData->thread = StartThread(DSoundProc, device);
if(!pData->thread)
hr = E_FAIL;
@@ -306,42 +426,41 @@ static ALCboolean DSoundOpenPlayback(ALCdevice *device, const ALCchar *deviceNam
{
if (pData->DSsbuffer)
IDirectSoundBuffer_Release(pData->DSsbuffer);
pData->DSsbuffer = NULL;
if (pData->DSpbuffer)
IDirectSoundBuffer_Release(pData->DSpbuffer);
if (pData->lpDS)
IDirectSound_Release(pData->lpDS);
free(pData);
pData->DSpbuffer = NULL;
return ALC_FALSE;
}
return ALC_TRUE;
}
static void DSoundClosePlayback(ALCdevice *device)
static void DSoundStopPlayback(ALCdevice *device)
{
DSoundData *pData = device->ExtraData;
if(!pData->thread)
return;
pData->killNow = 1;
StopThread(pData->thread);
pData->thread = NULL;
pData->killNow = 0;
IDirectSoundBuffer_Release(pData->DSsbuffer);
pData->DSsbuffer = NULL;
if (pData->DSpbuffer)
IDirectSoundBuffer_Release(pData->DSpbuffer);
IDirectSound_Release(pData->lpDS);
free(pData);
device->ExtraData = NULL;
pData->DSpbuffer = NULL;
}
static ALCboolean DSoundOpenCapture(ALCdevice *pDevice, const ALCchar *deviceName, ALCuint frequency, ALCenum format, ALCsizei SampleSize)
static ALCboolean DSoundOpenCapture(ALCdevice *pDevice, const ALCchar *deviceName)
{
(void)pDevice;
(void)deviceName;
(void)frequency;
(void)format;
(void)SampleSize;
return ALC_FALSE;
}
@@ -377,6 +496,8 @@ static ALCuint DSoundAvailableSamples(ALCdevice *pDevice)
BackendFuncs DSoundFuncs = {
DSoundOpenPlayback,
DSoundClosePlayback,
DSoundResetPlayback,
DSoundStopPlayback,
DSoundOpenCapture,
DSoundCloseCapture,
DSoundStartCapture,
@@ -387,34 +508,68 @@ BackendFuncs DSoundFuncs = {
static BOOL CALLBACK DSoundEnumDevices(LPGUID guid, LPCSTR desc, LPCSTR drvname, LPVOID data)
{
size_t *iter = data;
(void)data;
(void)drvname;
if(guid)
{
char str[128];
snprintf(str, sizeof(str), "DirectSound Software on %s", desc);
DeviceList[*iter].name = AppendAllDeviceList(str);
DeviceList[*iter].guid = *guid;
(*iter)++;
void *temp;
temp = realloc(DeviceList, sizeof(DevMap) * (NumDevices+1));
if(temp)
{
DeviceList = temp;
snprintf(str, sizeof(str), "DirectSound Software on %s", desc);
AppendAllDeviceList(str);
DeviceList[NumDevices].name = strdup(str);
DeviceList[NumDevices].guid = *guid;
NumDevices++;
}
}
else
DeviceList[0].name = AppendDeviceList("DirectSound Software");
return TRUE;
}
void alcDSoundInit(BackendFuncs *FuncList)
{
size_t iter = 1;
HRESULT hr;
*FuncList = DSoundFuncs;
num_frags = GetConfigValueInt("dsound", "periods", 4);
if(num_frags < 2) num_frags = 2;
hr = DirectSoundEnumerate(DSoundEnumDevices, &iter);
if(FAILED(hr))
AL_PRINT("Error enumerating DirectSound devices (%#x)!\n", (unsigned int)hr);
}
void alcDSoundDeinit(void)
{
ALuint i;
for(i = 0;i < NumDevices;++i)
free(DeviceList[i].name);
free(DeviceList);
DeviceList = NULL;
NumDevices = 0;
}
void alcDSoundProbe(int type)
{
if(!DSoundLoad()) return;
if(type == DEVICE_PROBE)
AppendDeviceList(dsDevice);
else if(type == ALL_DEVICE_PROBE)
{
HRESULT hr;
ALuint i;
for(i = 0;i < NumDevices;++i)
free(DeviceList[i].name);
free(DeviceList);
DeviceList = NULL;
NumDevices = 0;
hr = pDirectSoundEnumerateA(DSoundEnumDevices, NULL);
if(FAILED(hr))
AL_PRINT("Error enumerating DirectSound devices (%#x)!\n", (unsigned int)hr);
}
DSoundUnload();
}
+155 -89
View File
@@ -47,8 +47,8 @@
#define SOUND_MIXER_WRITE MIXER_WRITE
#endif
static char *oss_device;
static char *oss_device_capture;
static const ALCchar oss_device[] = "OSS Software";
static const ALCchar oss_device_capture[] = "OSS Capture";
typedef struct {
int fd;
@@ -79,35 +79,39 @@ static ALuint OSSProc(ALvoid *ptr)
{
ALCdevice *pDevice = (ALCdevice*)ptr;
oss_data *data = (oss_data*)pDevice->ExtraData;
int remaining = 0;
int wrote;
ALint frameSize;
ssize_t wrote;
while(!data->killNow)
EnableRTPrio(RTPrioLevel);
frameSize = aluChannelsFromFormat(pDevice->Format) *
aluBytesFromFormat(pDevice->Format);
while(!data->killNow && pDevice->Connected)
{
int len = data->data_size - remaining;
ALint len = data->data_size;
ALubyte *WritePtr = data->mix_data;
if(len > 0)
aluMixData(pDevice, WritePtr, len/frameSize);
while(len > 0 && !data->killNow)
{
SuspendContext(NULL);
aluMixData(pDevice->Context, data->mix_data+remaining, len, pDevice->Format);
ProcessContext(NULL);
}
wrote = write(data->fd, WritePtr, len);
if(wrote < 0)
{
if(errno != EAGAIN && errno != EWOULDBLOCK && errno != EINTR)
{
AL_PRINT("write failed: %s\n", strerror(errno));
aluHandleDisconnect(pDevice);
break;
}
remaining += len;
wrote = write(data->fd, data->mix_data, remaining);
if(wrote < 0)
{
AL_PRINT("write failed: %s\n", strerror(errno));
remaining = 0;
Sleep(1);
continue;
}
len -= wrote;
WritePtr += wrote;
}
else if(wrote > 0)
{
remaining -= wrote;
if(remaining > 0)
memmove(data->mix_data, data->mix_data+wrote, remaining);
}
else
Sleep(1);
}
return 0;
@@ -120,6 +124,8 @@ static ALuint OSSCaptureProc(ALvoid *ptr)
int frameSize;
int amt;
EnableRTPrio(RTPrioLevel);
frameSize = aluBytesFromFormat(pDevice->Format);
frameSize *= aluChannelsFromFormat(pDevice->Format);
@@ -129,6 +135,7 @@ static ALuint OSSCaptureProc(ALvoid *ptr)
if(amt < 0)
{
AL_PRINT("read failed: %s\n", strerror(errno));
aluHandleDisconnect(pDevice);
break;
}
if(amt == 0)
@@ -145,29 +152,15 @@ static ALuint OSSCaptureProc(ALvoid *ptr)
static ALCboolean oss_open_playback(ALCdevice *device, const ALCchar *deviceName)
{
int numFragmentsLogSize;
int log2FragmentSize;
unsigned int periods;
audio_buf_info info;
ALuint frameSize;
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;
if(!deviceName)
deviceName = oss_device;
else if(strcmp(deviceName, oss_device) != 0)
return ALC_FALSE;
data = (oss_data*)calloc(1, sizeof(oss_data));
data->killNow = 0;
@@ -176,58 +169,95 @@ static ALCboolean oss_open_playback(ALCdevice *device, const ALCchar *deviceName
if(data->fd == -1)
{
free(data);
AL_PRINT("Could not open %s: %s\n", driver, strerror(errno));
if(errno != ENOENT)
AL_PRINT("Could not open %s: %s\n", driver, strerror(errno));
return ALC_FALSE;
}
device->szDeviceName = strdup(deviceName);
device->ExtraData = data;
return ALC_TRUE;
}
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;
int i;
switch(aluBytesFromFormat(device->Format))
{
case 1:
ossFormat = AFMT_U8;
break;
case 4:
switch(aluChannelsFromFormat(device->Format))
{
case 1: device->Format = AL_FORMAT_MONO16; break;
case 2: device->Format = AL_FORMAT_STEREO16; break;
case 4: device->Format = AL_FORMAT_QUAD16; break;
case 6: device->Format = AL_FORMAT_51CHN16; break;
case 7: device->Format = AL_FORMAT_61CHN16; break;
case 8: device->Format = AL_FORMAT_71CHN16; break;
}
/* fall-through */
case 2:
ossFormat = AFMT_S16_NE;
break;
default:
ossFormat = -1;
AL_PRINT("Unknown format?! %x\n", device->Format);
AL_PRINT("Unknown format: 0x%x\n", device->Format);
return ALC_FALSE;
}
periods = GetConfigValueInt("oss", "periods", 4);
if((int)periods <= 0)
periods = 4;
periods = device->NumUpdates;
numChannels = aluChannelsFromFormat(device->Format);
frameSize = numChannels * aluBytesFromFormat(device->Format);
ossSpeed = device->Frequency;
log2FragmentSize = log2i(device->UpdateSize * frameSize / periods);
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 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") &&
/* 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);
if (!(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)aluChannelsFromFormat(device->Format) != numChannels)
{
AL_PRINT("Could not set %d channels, got %d instead\n", aluChannelsFromFormat(device->Format), numChannels);
close(data->fd);
free(data);
return ALC_FALSE;
}
@@ -235,44 +265,50 @@ static ALCboolean oss_open_playback(ALCdevice *device, const ALCchar *deviceName
(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->Frequency = ossSpeed;
device->UpdateSize = info.fragsize / frameSize;
device->NumUpdates = info.fragments + 1;
data->data_size = device->UpdateSize * frameSize;
data->mix_data = calloc(1, data->data_size);
device->ExtraData = data;
SetDefaultChannelOrder(device);
data->thread = StartThread(OSSProc, device);
if(data->thread == NULL)
{
device->ExtraData = NULL;
free(data->mix_data);
free(data);
data->mix_data = NULL;
return ALC_FALSE;
}
return ALC_TRUE;
}
static void oss_close_playback(ALCdevice *device)
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;
close(data->fd);
data->killNow = 0;
if(ioctl(data->fd, SNDCTL_DSP_RESET) != 0)
AL_PRINT("Error resetting device: %s\n", strerror(errno));
free(data->mix_data);
free(data);
device->ExtraData = NULL;
data->mix_data = NULL;
}
static ALCboolean oss_open_capture(ALCdevice *device, const ALCchar *deviceName, ALCuint frequency, ALCenum format, ALCsizei SampleSize)
static ALCboolean oss_open_capture(ALCdevice *device, const ALCchar *deviceName)
{
int numFragmentsLogSize;
int log2FragmentSize;
@@ -289,14 +325,10 @@ static ALCboolean oss_open_capture(ALCdevice *device, const ALCchar *deviceName,
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;
if(!deviceName)
deviceName = oss_device_capture;
else if(strcmp(deviceName, oss_device_capture) != 0)
return ALC_FALSE;
data = (oss_data*)calloc(1, sizeof(oss_data));
data->killNow = 0;
@@ -305,11 +337,12 @@ static ALCboolean oss_open_capture(ALCdevice *device, const ALCchar *deviceName,
if(data->fd == -1)
{
free(data);
AL_PRINT("Could not open %s: %s\n", driver, strerror(errno));
if(errno != ENOENT)
AL_PRINT("Could not open %s: %s\n", driver, strerror(errno));
return ALC_FALSE;
}
switch(aluBytesFromFormat(format))
switch(aluBytesFromFormat(device->Format))
{
case 1:
ossFormat = AFMT_U8;
@@ -318,15 +351,18 @@ static ALCboolean oss_open_capture(ALCdevice *device, const ALCchar *deviceName,
ossFormat = AFMT_S16_NE;
break;
default:
ossFormat = -1;
AL_PRINT("Unknown format?! %x\n", device->Format);
AL_PRINT("Unknown format: 0x%x\n", device->Format);
close(data->fd);
free(data);
return ALC_FALSE;
}
periods = 4;
numChannels = aluChannelsFromFormat(device->Format);
frameSize = numChannels * aluBytesFromFormat(device->Format);
ossSpeed = frequency;
log2FragmentSize = log2i(SampleSize * frameSize / periods);
ossSpeed = device->Frequency;
log2FragmentSize = log2i(device->UpdateSize * device->NumUpdates *
frameSize / periods);
/* according to the OSS spec, 16 bytes are the minimum */
if (log2FragmentSize < 4)
@@ -364,7 +400,7 @@ static ALCboolean oss_open_capture(ALCdevice *device, const ALCchar *deviceName,
return ALC_FALSE;
}
data->ring = CreateRingBuffer(frameSize, SampleSize);
data->ring = CreateRingBuffer(frameSize, device->UpdateSize * device->NumUpdates);
if(!data->ring)
{
AL_PRINT("ring buffer create failed\n");
@@ -386,6 +422,7 @@ static ALCboolean oss_open_capture(ALCdevice *device, const ALCchar *deviceName,
return ALC_FALSE;
}
device->szDeviceName = strdup(deviceName);
return ALC_TRUE;
}
@@ -422,7 +459,7 @@ static void oss_capture_samples(ALCdevice *pDevice, ALCvoid *pBuffer, ALCuint lS
if(lSamples <= (ALCuint)RingBufferSize(data->ring))
ReadRingBuffer(data->ring, pBuffer, lSamples);
else
SetALCError(ALC_INVALID_VALUE);
alcSetError(pDevice, ALC_INVALID_VALUE);
}
static ALCuint oss_available_samples(ALCdevice *pDevice)
@@ -435,6 +472,8 @@ static ALCuint oss_available_samples(ALCdevice *pDevice)
BackendFuncs oss_funcs = {
oss_open_playback,
oss_close_playback,
oss_reset_playback,
oss_stop_playback,
oss_open_capture,
oss_close_capture,
oss_start_capture,
@@ -446,9 +485,36 @@ BackendFuncs oss_funcs = {
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");
}
void alc_oss_deinit(void)
{
}
void alc_oss_probe(int type)
{
if(type == DEVICE_PROBE)
{
#ifdef HAVE_STAT
struct stat buf;
if(stat(GetConfigValue("oss", "device", "/dev/dsp"), &buf) == 0)
#endif
AppendDeviceList(oss_device);
}
else if(type == ALL_DEVICE_PROBE)
{
#ifdef HAVE_STAT
struct stat buf;
if(stat(GetConfigValue("oss", "device", "/dev/dsp"), &buf) == 0)
#endif
AppendAllDeviceList(oss_device);
}
else if(type == CAPTURE_DEVICE_PROBE)
{
#ifdef HAVE_STAT
struct stat buf;
if(stat(GetConfigValue("oss", "capture", "/dev/dsp"), &buf) == 0)
#endif
AppendCaptureDeviceList(oss_device_capture);
}
}
+298
View File
@@ -0,0 +1,298 @@
/**
* 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 "AL/al.h"
#include "AL/alc.h"
#ifdef HAVE_DLFCN_H
#include <dlfcn.h>
#endif
#include <portaudio.h>
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
static const ALCchar pa_device[] = "PortAudio Software";
static volatile ALuint load_count;
void *pa_load(void)
{
const char *str;
PaError err;
if(load_count == 0)
{
#ifdef HAVE_DLFCN_H
#if defined(__APPLE__) && defined(__MACH__)
# define PALIB "libportaudio.2.dylib"
#else
# define PALIB "libportaudio.so.2"
#endif
pa_handle = dlopen(PALIB, RTLD_NOW);
if(!pa_handle)
return NULL;
dlerror();
#define LOAD_FUNC(f) do { \
p##f = (typeof(f)*)dlsym(pa_handle, #f); \
if((str=dlerror()) != NULL) \
{ \
dlclose(pa_handle); \
pa_handle = NULL; \
AL_PRINT("Could not load %s from "PALIB": %s\n", #f, str); \
return NULL; \
} \
} while(0)
#else
str = NULL;
pa_handle = (void*)0xDEADBEEF;
#define LOAD_FUNC(f) p##f = f
#endif
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=pPa_Initialize()) != paNoError)
{
AL_PRINT("Pa_Initialize() returned an error: %s\n", pPa_GetErrorText(err));
#ifdef HAVE_DLFCN_H
dlclose(pa_handle);
#endif
pa_handle = NULL;
return NULL;
}
}
++load_count;
return pa_handle;
}
void pa_unload(void)
{
if(load_count == 0 || --load_count > 0)
return;
pPa_Terminate();
#ifdef HAVE_DLFCN_H
dlclose(pa_handle);
#endif
pa_handle = NULL;
}
typedef struct {
PaStream *stream;
} 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 ALCboolean pa_open_playback(ALCdevice *device, const ALCchar *deviceName)
{
const PaStreamInfo *streamInfo;
PaStreamParameters outParams;
pa_data *data;
PaError err;
if(!deviceName)
deviceName = pa_device;
else if(strcmp(deviceName, pa_device) != 0)
return ALC_FALSE;
if(!pa_load())
return ALC_FALSE;
data = (pa_data*)calloc(1, sizeof(pa_data));
device->ExtraData = data;
outParams.device = GetConfigValueInt("port", "device", -1);
if(outParams.device < 0)
outParams.device = pPa_GetDefaultOutputDevice();
outParams.suggestedLatency = (device->UpdateSize*device->NumUpdates) /
(float)device->Frequency;
outParams.hostApiSpecificStreamInfo = NULL;
switch(aluBytesFromFormat(device->Format))
{
case 1:
outParams.sampleFormat = paUInt8;
break;
case 2:
outParams.sampleFormat = paInt16;
break;
case 4:
outParams.sampleFormat = paFloat32;
break;
default:
AL_PRINT("Unknown format: 0x%x\n", device->Format);
device->ExtraData = NULL;
free(data);
pa_unload();
return ALC_FALSE;
}
outParams.channelCount = aluChannelsFromFormat(device->Format);
SetDefaultChannelOrder(device);
err = pPa_OpenStream(&data->stream, NULL, &outParams, device->Frequency,
device->UpdateSize, paNoFlag, pa_callback, device);
if(err != paNoError)
{
AL_PRINT("Pa_OpenStream() returned an error: %s\n", pPa_GetErrorText(err));
device->ExtraData = NULL;
free(data);
pa_unload();
return ALC_FALSE;
}
streamInfo = pPa_GetStreamInfo(data->stream);
device->szDeviceName = strdup(deviceName);
device->Frequency = streamInfo->sampleRate;
return ALC_TRUE;
}
static void pa_close_playback(ALCdevice *device)
{
pa_data *data = (pa_data*)device->ExtraData;
PaError err;
err = pPa_CloseStream(data->stream);
if(err != paNoError)
AL_PRINT("Error closing stream: %s\n", pPa_GetErrorText(err));
free(data);
device->ExtraData = NULL;
pa_unload();
}
static ALCboolean pa_reset_playback(ALCdevice *device)
{
pa_data *data = (pa_data*)device->ExtraData;
const PaStreamInfo *streamInfo;
PaError err;
streamInfo = pPa_GetStreamInfo(data->stream);
device->Frequency = streamInfo->sampleRate;
err = pPa_StartStream(data->stream);
if(err != paNoError)
{
AL_PRINT("Pa_StartStream() returned an error: %s\n", pPa_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 = pPa_StopStream(data->stream);
if(err != paNoError)
AL_PRINT("Error stopping stream: %s\n", pPa_GetErrorText(err));
}
static ALCboolean pa_open_capture(ALCdevice *device, const ALCchar *deviceName)
{
return ALC_FALSE;
(void)device;
(void)deviceName;
}
static const BackendFuncs pa_funcs = {
pa_open_playback,
pa_close_playback,
pa_reset_playback,
pa_stop_playback,
pa_open_capture,
NULL,
NULL,
NULL,
NULL,
NULL
};
void alc_pa_init(BackendFuncs *func_list)
{
*func_list = pa_funcs;
}
void alc_pa_deinit(void)
{
}
void alc_pa_probe(int type)
{
if(!pa_load()) return;
if(type == DEVICE_PROBE)
AppendDeviceList(pa_device);
else if(type == ALL_DEVICE_PROBE)
AppendAllDeviceList(pa_device);
pa_unload();
}
+1012
View File
File diff suppressed because it is too large Load Diff
+105 -58
View File
@@ -37,7 +37,7 @@
#include <sys/audioio.h>
static char *solaris_device;
static const ALCchar solaris_device[] = "Solaris Software";
typedef struct {
int fd;
@@ -54,34 +54,39 @@ static ALuint SolarisProc(ALvoid *ptr)
ALCdevice *pDevice = (ALCdevice*)ptr;
solaris_data *data = (solaris_data*)pDevice->ExtraData;
int remaining = 0;
ALint frameSize;
int wrote;
while(!data->killNow)
EnableRTPrio(RTPrioLevel);
frameSize = aluChannelsFromFormat(pDevice->Format) *
aluBytesFromFormat(pDevice->Format);
while(!data->killNow && pDevice->Connected)
{
int len = data->data_size - remaining;
ALint len = data->data_size;
ALubyte *WritePtr = data->mix_data;
if(len > 0)
aluMixData(pDevice, WritePtr, len/frameSize);
while(len > 0 && !data->killNow)
{
SuspendContext(NULL);
aluMixData(pDevice->Context, data->mix_data+remaining, len, pDevice->Format);
ProcessContext(NULL);
}
wrote = write(data->fd, WritePtr, len);
if(wrote < 0)
{
if(errno != EAGAIN && errno != EWOULDBLOCK && errno != EINTR)
{
AL_PRINT("write failed: %s\n", strerror(errno));
aluHandleDisconnect(pDevice);
break;
}
remaining += len;
wrote = write(data->fd, data->mix_data, remaining);
if(wrote < 0)
{
AL_PRINT("write failed: %s\n", strerror(errno));
remaining = 0;
Sleep(1);
continue;
}
len -= wrote;
WritePtr += wrote;
}
else if(wrote > 0)
{
remaining -= wrote;
if(remaining > 0)
memmove(data->mix_data, data->mix_data+wrote, remaining);
}
else
Sleep(1);
}
return 0;
@@ -90,22 +95,15 @@ static ALuint SolarisProc(ALvoid *ptr)
static ALCboolean solaris_open_playback(ALCdevice *device, const ALCchar *deviceName)
{
audio_info_t info;
ALuint frameSize;
char driver[64];
int numChannels;
solaris_data *data;
strncpy(driver, GetConfigValue("solaris", "device", "/dev/audio"), sizeof(driver)-1);
driver[sizeof(driver)-1] = 0;
if(deviceName)
{
if(strcmp(deviceName, solaris_device))
return ALC_FALSE;
device->szDeviceName = solaris_device;
}
else
device->szDeviceName = solaris_device;
if(!deviceName)
deviceName = solaris_device;
else if(strcmp(deviceName, solaris_device) != 0)
return ALC_FALSE;
data = (solaris_data*)calloc(1, sizeof(solaris_data));
data->killNow = 0;
@@ -114,14 +112,33 @@ static ALCboolean solaris_open_playback(ALCdevice *device, const ALCchar *device
if(data->fd == -1)
{
free(data);
AL_PRINT("Could not open %s: %s\n", driver, strerror(errno));
if(errno != ENOENT)
AL_PRINT("Could not open %s: %s\n", driver, strerror(errno));
return ALC_FALSE;
}
numChannels = aluChannelsFromFormat(device->Format);
device->szDeviceName = strdup(deviceName);
device->ExtraData = data;
return ALC_TRUE;
}
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;
info.play.channels = numChannels;
switch(aluBytesFromFormat(device->Format))
{
@@ -129,32 +146,42 @@ static ALCboolean solaris_open_playback(ALCdevice *device, const ALCchar *device
info.play.precision = 8;
info.play.encoding = AUDIO_ENCODING_LINEAR8;
break;
case 4:
switch(numChannels)
{
case 1: device->Format = AL_FORMAT_MONO16; break;
case 2: device->Format = AL_FORMAT_STEREO16; break;
case 4: device->Format = AL_FORMAT_QUAD16; break;
case 6: device->Format = AL_FORMAT_51CHN16; break;
case 7: device->Format = AL_FORMAT_61CHN16; break;
case 8: device->Format = AL_FORMAT_71CHN16; break;
}
/* fall-through */
case 2:
info.play.precision = 16;
info.play.encoding = AUDIO_ENCODING_LINEAR;
break;
default:
AL_PRINT("Unknown format?! %x\n", device->Format);
AL_PRINT("Unknown format: 0x%x\n", device->Format);
return ALC_FALSE;
}
numChannels = aluChannelsFromFormat(device->Format);
info.play.sample_rate = device->Frequency;
info.play.channels = numChannels;
frameSize = numChannels * aluBytesFromFormat(device->Format);
info.play.buffer_size = device->UpdateSize * frameSize;
info.play.buffer_size = device->UpdateSize*device->NumUpdates * frameSize;
if(ioctl(data->fd, AUDIO_SETINFO, &info) < 0)
{
AL_PRINT("ioctl failed: %s\n", strerror(errno));
close(data->fd);
free(data);
return ALC_FALSE;
}
device->Frequency = info.play.sample_rate;
if(aluChannelsFromFormat(device->Format) != info.play.channels)
{
AL_PRINT("Could not set %d channels, got %d instead\n", aluChannelsFromFormat(device->Format), info.play.channels);
close(data->fd);
free(data);
return ALC_FALSE;
}
@@ -162,40 +189,43 @@ static ALCboolean solaris_open_playback(ALCdevice *device, const ALCchar *device
(info.play.precision == 16 && aluBytesFromFormat(device->Format) == 2)))
{
AL_PRINT("Could not set %d-bit output, got %d\n", aluBytesFromFormat(device->Format)*8, info.play.precision);
close(data->fd);
free(data);
return ALC_FALSE;
}
device->UpdateSize = info.play.buffer_size / 4;
device->Frequency = info.play.sample_rate;
device->UpdateSize = (info.play.buffer_size/device->NumUpdates) + 1;
data->data_size = device->UpdateSize * frameSize;
data->mix_data = calloc(1, data->data_size);
device->ExtraData = data;
SetDefaultChannelOrder(device);
data->thread = StartThread(SolarisProc, device);
if(data->thread == NULL)
{
device->ExtraData = NULL;
free(data->mix_data);
free(data);
data->mix_data = NULL;
return ALC_FALSE;
}
return ALC_TRUE;
}
static void solaris_close_playback(ALCdevice *device)
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;
close(data->fd);
data->killNow = 0;
free(data->mix_data);
free(data);
device->ExtraData = NULL;
data->mix_data = NULL;
}
@@ -241,6 +271,8 @@ static ALCuint solaris_available_samples(ALCdevice *pDevice)
BackendFuncs solaris_funcs = {
solaris_open_playback,
solaris_close_playback,
solaris_reset_playback,
solaris_stop_playback,
solaris_open_capture,
solaris_close_capture,
solaris_start_capture,
@@ -252,7 +284,22 @@ BackendFuncs solaris_funcs = {
void alc_solaris_init(BackendFuncs *func_list)
{
*func_list = solaris_funcs;
solaris_device = AppendDeviceList("Solaris Software");
AppendAllDeviceList(solaris_device);
}
void alc_solaris_deinit(void)
{
}
void alc_solaris_probe(int type)
{
#ifdef HAVE_STAT
struct stat buf;
if(stat(GetConfigValue("solaris", "device", "/dev/audio"), &buf) != 0)
return;
#endif
if(type == DEVICE_PROBE)
AppendDeviceList(solaris_device);
else if(type == ALL_DEVICE_PROBE)
AppendAllDeviceList(solaris_device);
}
+93 -100
View File
@@ -40,7 +40,7 @@ typedef struct {
} wave_data;
static ALCchar *waveDevice;
static const ALCchar waveDevice[] = "Wave File Writer";
static ALuint WaveProc(ALvoid *ptr)
@@ -49,7 +49,7 @@ static ALuint WaveProc(ALvoid *ptr)
wave_data *data = (wave_data*)pDevice->ExtraData;
ALuint frameSize;
ALuint now, last;
size_t WriteCnt;
size_t fs;
ALuint avail;
union {
short s;
@@ -61,43 +61,40 @@ static ALuint WaveProc(ALvoid *ptr)
aluChannelsFromFormat(pDevice->Format);
last = timeGetTime();
while(!data->killNow)
while(!data->killNow && pDevice->Connected)
{
now = timeGetTime();
avail = (now-last) * pDevice->Frequency / 1000;
if(avail < pDevice->UpdateSize/4)
if(avail < pDevice->UpdateSize)
{
Sleep(1);
continue;
}
while(avail > 0)
while(avail >= pDevice->UpdateSize)
{
SuspendContext(NULL);
WriteCnt = min(data->size, avail);
aluMixData(pDevice->Context, data->buffer, WriteCnt * frameSize,
pDevice->Format);
ProcessContext(NULL);
aluMixData(pDevice, data->buffer, pDevice->UpdateSize);
if(uSB.b[0] != 1 && aluBytesFromFormat(pDevice->Format) > 1)
{
ALubyte *bytes = data->buffer;
ALuint i;
for(i = 0;i < WriteCnt*frameSize;i++)
for(i = 0;i < data->size;i++)
fputc(bytes[i^1], data->f);
}
else
fwrite(data->buffer, frameSize, WriteCnt, data->f);
fs = fwrite(data->buffer, frameSize, pDevice->UpdateSize,
data->f);
if(ferror(data->f))
{
AL_PRINT("Error writing to file\n");
data->killNow = 1;
aluHandleDisconnect(pDevice);
break;
}
avail -= WriteCnt;
avail -= pDevice->UpdateSize;
}
last = now;
}
@@ -108,23 +105,16 @@ static ALuint WaveProc(ALvoid *ptr)
static ALCboolean wave_open_playback(ALCdevice *device, const ALCchar *deviceName)
{
wave_data *data;
ALuint channels;
ALuint bits;
const char *fname;
int i;
fname = GetConfigValue("wave", "file", "");
if(!fname[0])
return ALC_FALSE;
if(deviceName)
{
if(strcmp(deviceName, waveDevice) != 0)
return ALC_FALSE;
device->szDeviceName = waveDevice;
}
else
device->szDeviceName = waveDevice;
if(!deviceName)
deviceName = waveDevice;
else if(strcmp(deviceName, waveDevice) != 0)
return ALC_FALSE;
data = (wave_data*)calloc(1, sizeof(wave_data));
@@ -136,26 +126,49 @@ static ALCboolean wave_open_playback(ALCdevice *device, const ALCchar *deviceNam
return ALC_FALSE;
}
device->szDeviceName = strdup(deviceName);
device->ExtraData = data;
return ALC_TRUE;
}
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, bits, i;
fseek(data->f, 0, SEEK_SET);
clearerr(data->f);
bits = aluBytesFromFormat(device->Format) * 8;
channels = aluChannelsFromFormat(device->Format);
switch(bits)
{
case 8:
case 16:
if(channels == 0)
{
AL_PRINT("Unknown format?! %x\n", device->Format);
fclose(data->f);
free(data);
return ALC_FALSE;
}
break;
default:
AL_PRINT("Unknown format?! %x\n", device->Format);
fclose(data->f);
free(data);
return ALC_FALSE;
if(channels != 1 && channels != 2)
{
if(bits == 8)
device->Format = AL_FORMAT_STEREO8;
else
{
device->Format = AL_FORMAT_STEREO16;
bits = 16;
}
channels = 2;
}
else if(bits != 8 && bits != 16)
{
if(channels == 1)
device->Format = AL_FORMAT_MONO16;
else
device->Format = AL_FORMAT_STEREO16;
bits = 16;
}
fprintf(data->f, "RIFF");
@@ -205,47 +218,49 @@ static ALCboolean wave_open_playback(ALCdevice *device, const ALCchar *deviceNam
if(ferror(data->f))
{
AL_PRINT("Error writing header: %s\n", strerror(errno));
fclose(data->f);
free(data);
return ALC_FALSE;
}
data->DataStart = ftell(data->f);
device->UpdateSize = max(device->UpdateSize, 2048);
data->size = device->UpdateSize;
data->buffer = malloc(data->size * channels * bits / 8);
data->size = device->UpdateSize * channels * bits / 8;
data->buffer = malloc(data->size);
if(!data->buffer)
{
AL_PRINT("buffer malloc failed\n");
fclose(data->f);
free(data);
return ALC_FALSE;
}
device->ExtraData = data;
SetDefaultWFXChannelOrder(device);
data->thread = StartThread(WaveProc, device);
if(data->thread == NULL)
{
device->ExtraData = NULL;
fclose(data->f);
free(data->buffer);
free(data);
data->buffer = NULL;
return ALC_FALSE;
}
return ALC_TRUE;
}
static void wave_close_playback(ALCdevice *device)
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)
@@ -267,68 +282,46 @@ static void wave_close_playback(ALCdevice *device)
fputc((size>>24)&0xff, data->f);
}
}
fclose(data->f);
free(data->buffer);
free(data);
device->ExtraData = NULL;
}
static ALCboolean wave_open_capture(ALCdevice *pDevice, const ALCchar *deviceName, ALCuint frequency, ALCenum format, ALCsizei SampleSize)
static ALCboolean wave_open_capture(ALCdevice *pDevice, const ALCchar *deviceName)
{
(void)pDevice;
(void)deviceName;
(void)frequency;
(void)format;
(void)SampleSize;
return ALC_FALSE;
}
static void wave_close_capture(ALCdevice *pDevice)
{
(void)pDevice;
}
static void wave_start_capture(ALCdevice *pDevice)
{
(void)pDevice;
}
static void wave_stop_capture(ALCdevice *pDevice)
{
(void)pDevice;
}
static void wave_capture_samples(ALCdevice *pDevice, ALCvoid *pBuffer, ALCuint lSamples)
{
(void)pDevice;
(void)pBuffer;
(void)lSamples;
}
static ALCuint wave_available_samples(ALCdevice *pDevice)
{
(void)pDevice;
return 0;
}
BackendFuncs wave_funcs = {
wave_open_playback,
wave_close_playback,
wave_reset_playback,
wave_stop_playback,
wave_open_capture,
wave_close_capture,
wave_start_capture,
wave_stop_capture,
wave_capture_samples,
wave_available_samples
NULL,
NULL,
NULL,
NULL,
NULL
};
void alc_wave_init(BackendFuncs *func_list)
{
*func_list = wave_funcs;
waveDevice = AppendDeviceList("Wave File Writer");
AppendAllDeviceList(waveDevice);
}
void alc_wave_deinit(void)
{
}
void alc_wave_probe(int type)
{
if(!ConfigValueExists("wave", "file"))
return;
if(type == DEVICE_PROBE)
AppendDeviceList(waveDevice);
else if(type == ALL_DEVICE_PROBE)
AppendAllDeviceList(waveDevice);
}
+46 -18
View File
@@ -50,7 +50,8 @@ typedef struct {
} WinMMData;
static ALCchar *CaptureDeviceList[16];
static ALCchar **CaptureDeviceList;
static ALuint NumCaptureDevices;
/*
WaveInProc
@@ -175,20 +176,18 @@ static void WinMMClosePlayback(ALCdevice *device)
}
static ALCboolean WinMMOpenCapture(ALCdevice *pDevice, const ALCchar *deviceName, ALCuint frequency, ALCenum format, ALCsizei SampleSize)
static ALCboolean WinMMOpenCapture(ALCdevice *pDevice, const ALCchar *deviceName)
{
WAVEFORMATEX wfexCaptureFormat;
WinMMData *pData = NULL;
ALint lDeviceID = 0;
ALint lBufferSize;
ALint i;
(void)format;
ALuint i;
// Find the Device ID matching the deviceName if valid
if (deviceName)
{
for(i = 0;CaptureDeviceList[i];i++)
for(i = 0;i < NumCaptureDevices;i++)
{
if (!strcmp(deviceName, CaptureDeviceList[i]))
{
@@ -196,15 +195,14 @@ static ALCboolean WinMMOpenCapture(ALCdevice *pDevice, const ALCchar *deviceName
break;
}
}
if(!CaptureDeviceList[i])
if(i == NumCaptureDevices)
return ALC_FALSE;
}
pDevice->szDeviceName = CaptureDeviceList[lDeviceID];
pData = calloc(1, sizeof(*pData));
if(!pData)
{
SetALCError(ALC_OUT_OF_MEMORY);
alcSetError(pDevice, ALC_OUT_OF_MEMORY);
return ALC_FALSE;
}
@@ -214,7 +212,7 @@ static ALCboolean WinMMOpenCapture(ALCdevice *pDevice, const ALCchar *deviceName
wfexCaptureFormat.wBitsPerSample = aluBytesFromFormat(pDevice->Format) * 8;
wfexCaptureFormat.nBlockAlign = wfexCaptureFormat.wBitsPerSample *
wfexCaptureFormat.nChannels / 8;
wfexCaptureFormat.nSamplesPerSec = frequency;
wfexCaptureFormat.nSamplesPerSec = pDevice->Frequency;
wfexCaptureFormat.nAvgBytesPerSec = wfexCaptureFormat.nSamplesPerSec *
wfexCaptureFormat.nBlockAlign;
wfexCaptureFormat.cbSize = 0;
@@ -231,7 +229,8 @@ static ALCboolean WinMMOpenCapture(ALCdevice *pDevice, const ALCchar *deviceName
goto failure;
// Allocate circular memory buffer for the captured audio
pData->ulCapturedDataSize = SampleSize * wfexCaptureFormat.nBlockAlign;
pData->ulCapturedDataSize = pDevice->UpdateSize*pDevice->NumUpdates *
wfexCaptureFormat.nBlockAlign;
// Make sure circular buffer is at least 100ms in size (and an exact multiple of
// the block alignment
@@ -269,6 +268,7 @@ static ALCboolean WinMMOpenCapture(ALCdevice *pDevice, const ALCchar *deviceName
if (pData->hWaveInThread == NULL)
goto failure;
pDevice->szDeviceName = strdup(CaptureDeviceList[lDeviceID]);
return ALC_TRUE;
failure:
@@ -292,6 +292,7 @@ failure:
CloseHandle(pData->hWaveInThreadEvent);
free(pData);
pDevice->ExtraData = NULL;
return ALC_FALSE;
}
@@ -372,7 +373,7 @@ static void WinMMCaptureSamples(ALCdevice *pDevice, ALCvoid *pBuffer, ALCuint lS
frameSize;
if(ulSamples > ulCapturedSamples)
{
SetALCError(ALC_INVALID_VALUE);
alcSetError(pDevice, ALC_INVALID_VALUE);
return;
}
@@ -413,6 +414,8 @@ static ALCuint WinMMAvailableSamples(ALCdevice *pDevice)
BackendFuncs WinMMFuncs = {
WinMMOpenPlayback,
WinMMClosePlayback,
NULL,
NULL,
WinMMOpenCapture,
WinMMCloseCapture,
WinMMStartCapture,
@@ -423,20 +426,45 @@ BackendFuncs WinMMFuncs = {
void alcWinMMInit(BackendFuncs *FuncList)
{
ALint lNumDevs;
ALint lLoop;
*FuncList = WinMMFuncs;
}
lNumDevs = waveInGetNumDevs();
for (lLoop = 0; lLoop < lNumDevs; lLoop++)
void alcWinMMDeinit()
{
ALuint lLoop;
for(lLoop = 0; lLoop < NumCaptureDevices; lLoop++)
free(CaptureDeviceList[lLoop]);
free(CaptureDeviceList);
CaptureDeviceList = NULL;
NumCaptureDevices = 0;
}
void alcWinMMProbe(int type)
{
ALuint lLoop;
if(type != CAPTURE_DEVICE_PROBE)
return;
for(lLoop = 0; lLoop < NumCaptureDevices; lLoop++)
free(CaptureDeviceList[lLoop]);
NumCaptureDevices = waveInGetNumDevs();
CaptureDeviceList = realloc(CaptureDeviceList, sizeof(ALCchar*) * NumCaptureDevices);
for(lLoop = 0; lLoop < NumCaptureDevices; 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);
AppendCaptureDeviceList(name);
CaptureDeviceList[lLoop] = strdup(name);
}
else
CaptureDeviceList[lLoop] = strdup("");
}
}
+136 -36
View File
@@ -6,10 +6,13 @@ 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(CheckIncludeFile)
INCLUDE(CheckIncludeFiles)
INCLUDE(CheckSymbolExists)
INCLUDE(CheckCCompilerFlag)
INCLUDE(CheckCSourceCompiles)
INCLUDE(CheckTypeSize)
@@ -26,6 +29,8 @@ OPTION(OSS "Check for OSS backend" ON)
OPTION(SOLARIS "Check for Solaris backend" 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(DLOPEN "Check for the dlopen API for loading optional libs" ON)
@@ -33,22 +38,22 @@ OPTION(WERROR "Treat compile warnings as errors" OFF)
OPTION(EXAMPLES "Build example programs" ON)
OPTION(XCOMPILEWIN32 "Cross-compile to Win32" OFF)
OPTION(ALSOFT_CONFIG "Install alsoft.conf configuration file" OFF)
IF(WIN32 OR XCOMPILEWIN32)
SET(LIBNAME openal32)
IF(WIN32)
SET(LIBNAME OpenAL32)
ADD_DEFINITIONS("-D_WIN32")
ELSE()
SET(LIBNAME openal)
ENDIF()
SET(LIB_MAJOR_VERSION "1")
SET(LIB_MINOR_VERSION "6")
SET(LIB_BUILD_VERSION "372")
SET(LIB_MINOR_VERSION "11")
SET(LIB_BUILD_VERSION "753")
SET(LIB_VERSION "${LIB_MAJOR_VERSION}.${LIB_MINOR_VERSION}.${LIB_BUILD_VERSION}")
IF(NOT DEFINED LIB_INSTALL_DIR)
SET(LIB_INSTALL_DIR "lib")
SET(LIB_INSTALL_DIR "lib${LIB_SUFFIX}")
ENDIF(NOT DEFINED LIB_INSTALL_DIR)
@@ -66,6 +71,23 @@ IF(NOT CMAKE_BUILD_TYPE)
"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(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()
IF(MSVC)
# ???
@@ -73,10 +95,11 @@ IF(MSVC)
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)
ELSE()
ADD_DEFINITIONS(-Wall)
CHECK_C_COMPILER_FLAG(-Wextra HAVE_W_EXTRA)
IF("${HAVE_W_EXTRA}")
IF(HAVE_W_EXTRA)
ADD_DEFINITIONS(-Wextra)
ENDIF()
@@ -98,35 +121,41 @@ ELSE()
FORCE)
# Set visibility options if available
IF(NOT WIN32 AND NOT XCOMPILEWIN32)
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}")
IF(HAVE_VISIBILITY_SWITCH)
CHECK_C_SOURCE_COMPILES("int foo() __attribute__((visibility(\"default\")));
int main() {return 0;}" HAVE_GCC_VISIBILITY)
IF("${HAVE_GCC_VISIBILITY}")
IF(HAVE_GCC_VISIBILITY)
ADD_DEFINITIONS(-fvisibility=hidden -DHAVE_GCC_VISIBILITY)
ENDIF()
ENDIF()
ENDIF()
ENDIF()
CHECK_C_SOURCE_COMPILES("int foo(const char *str, ...) __attribute__((format(printf, 1, 2)));
int main() {return 0;}" HAVE_GCC_FORMAT)
CHECK_INCLUDE_FILE(fenv.h HAVE_FENV_H)
CHECK_INCLUDE_FILE(float.h HAVE_FLOAT_H)
CHECK_LIBRARY_EXISTS(m sqrtf "" HAVE_SQRTF)
CHECK_LIBRARY_EXISTS(m acosf "" HAVE_ACOSF)
CHECK_LIBRARY_EXISTS(m atanf "" HAVE_ATANF)
CHECK_LIBRARY_EXISTS(m fabsf "" HAVE_FABSF)
IF(HAVE_FENV_H)
CHECK_LIBRARY_EXISTS(m fesetround "" HAVE_FESETROUND)
ENDIF()
IF(HAVE_SQRTF OR HAVE_ACOSF OR HAVE_FESETROUND)
IF(HAVE_SQRTF OR HAVE_ACOSF OR HAVE_ATANF OR HAVE_FABSF OR HAVE_FESETROUND)
SET(EXTRA_LIBS m ${EXTRA_LIBS})
ENDIF()
CHECK_FUNCTION_EXISTS(strtof HAVE_STRTOF)
CHECK_FUNCTION_EXISTS(_controlfp HAVE__CONTROLFP)
CHECK_FUNCTION_EXISTS(stat HAVE_STAT)
CHECK_FUNCTION_EXISTS(strcasecmp HAVE_STRCASECMP)
IF(NOT HAVE_STRCASECMP)
CHECK_FUNCTION_EXISTS(_stricmp HAVE__STRICMP)
@@ -157,6 +186,27 @@ IF(NOT HAVE_SNPRINTF)
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(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)
@@ -181,22 +231,34 @@ IF(NOT HAVE_WINDOWS_H)
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, and
# _REENTRANT is needed for libc thread-safety
ADD_DEFINITIONS(-D_GNU_SOURCE=1 -D_REENTRANT)
ADD_DEFINITIONS(-D_GNU_SOURCE=1)
CHECK_LIBRARY_EXISTS(pthread pthread_create "" 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
@@ -220,6 +282,7 @@ ENDIF()
SET(OPENAL_OBJS OpenAL32/alAuxEffectSlot.c
OpenAL32/alBuffer.c
OpenAL32/alDatabuffer.c
OpenAL32/alEffect.c
OpenAL32/alError.c
OpenAL32/alExtension.c
@@ -232,6 +295,7 @@ SET(OPENAL_OBJS OpenAL32/alAuxEffectSlot.c
SET(ALC_OBJS Alc/ALc.c
Alc/ALu.c
Alc/alcConfig.c
Alc/alcEcho.c
Alc/alcReverb.c
Alc/alcRing.c
Alc/alcThread.c
@@ -283,16 +347,17 @@ ENDIF()
IF(DSOUND)
CHECK_INCLUDE_FILE(dsound.h HAVE_DSOUND_H)
IF(HAVE_DSOUND_H)
SET(HAVE_DSOUND 1)
SET(ALC_OBJS ${ALC_OBJS} Alc/dsound.c)
SET(BACKENDS "${BACKENDS} DirectSound,")
CHECK_LIBRARY_EXISTS(dsound DirectSoundCreate "" HAVE_LIBDSOUND)
IF(HAVE_LIBDSOUND OR WIN32)
SET(HAVE_DSOUND 1)
SET(ALC_OBJS ${ALC_OBJS} Alc/dsound.c)
SET(CMAKE_REQUIRED_LIBRARIES dsound)
CHECK_C_SOURCE_COMPILES("int main() {return 0;}" HAVE_LIBDSOUND)
SET(CMAKE_REQUIRED_LIBRARIES "")
# CHECK_LIBRARY_EXISTS(dsound DirectSoundCreate "" HAVE_LIBDSOUND)
IF(HAVE_LIBDSOUND)
SET(EXTRA_LIBS dsound ${EXTRA_LIBS})
IF(WIN32)
SET(BACKENDS "${BACKENDS} DirectSound,")
ELSE()
SET(BACKENDS "${BACKENDS} DirectSound \(linked\),")
SET(EXTRA_LIBS dsound ${EXTRA_LIBS})
ENDIF()
ENDIF()
ENDIF()
ENDIF()
@@ -315,6 +380,42 @@ IF(HAVE_WINDOWS_H)
ENDIF()
ENDIF()
# Check PortAudio backend
IF(PORTAUDIO)
CHECK_INCLUDE_FILE(portaudio.h HAVE_PORTAUDIO_H)
IF(HAVE_PORTAUDIO_H)
CHECK_LIBRARY_EXISTS(portaudio Pa_Initialize "" HAVE_LIBPORTAUDIO)
IF(HAVE_LIBPORTAUDIO)
SET(HAVE_PORTAUDIO 1)
SET(ALC_OBJS ${ALC_OBJS} Alc/portaudio.c)
IF(HAVE_DLFCN_H)
SET(BACKENDS "${BACKENDS} PortAudio,")
ELSE()
SET(BACKENDS "${BACKENDS} PortAudio \(linked\),")
SET(EXTRA_LIBS portaudio ${EXTRA_LIBS})
ENDIF()
ENDIF()
ENDIF()
ENDIF()
# Check PortAudio backend
IF(PULSEAUDIO)
CHECK_INCLUDE_FILE(pulse/pulseaudio.h HAVE_PULSE_PULSEAUDIO_H)
IF(HAVE_PULSE_PULSEAUDIO_H)
CHECK_LIBRARY_EXISTS(pulse pa_context_new "" HAVE_LIBPULSE)
IF(HAVE_LIBPULSE)
SET(HAVE_PULSEAUDIO 1)
SET(ALC_OBJS ${ALC_OBJS} Alc/pulseaudio.c)
IF(HAVE_DLFCN_H)
SET(BACKENDS "${BACKENDS} PulseAudio,")
ELSE()
SET(BACKENDS "${BACKENDS} PulseAudio \(linked\),")
SET(EXTRA_LIBS pulse ${EXTRA_LIBS})
ENDIF()
ENDIF()
ENDIF()
ENDIF()
# This is always available
SET(BACKENDS "${BACKENDS} WaveFile")
@@ -331,8 +432,8 @@ CONFIGURE_FILE(
"${OpenAL_SOURCE_DIR}/config.h.in"
"${OpenAL_BINARY_DIR}/config.h")
CONFIGURE_FILE(
"${OpenAL_SOURCE_DIR}/admin/pkgconfig/openal.pc.in"
"${OpenAL_BINARY_DIR}/admin/pkgconfig/openal.pc"
"${OpenAL_SOURCE_DIR}/openal.pc.in"
"${OpenAL_BINARY_DIR}/openal.pc"
@ONLY)
ADD_DEFINITIONS(-DAL_BUILD_LIBRARY)
@@ -347,15 +448,6 @@ SET_TARGET_PROPERTIES(${LIBNAME} PROPERTIES VERSION ${LIB_VERSION}
IF(WIN32)
SET_TARGET_PROPERTIES(${LIBNAME} PROPERTIES PREFIX "")
ENDIF()
IF(XCOMPILEWIN32)
SET_TARGET_PROPERTIES(${LIBNAME} PROPERTIES PREFIX "" SUFFIX .dll)
IF(EXAMPLES)
SET(EXAMPLES OFF)
MESSAGE(STATUS "")
MESSAGE(STATUS "Building examples disabled when cross-compiling")
ENDIF()
ENDIF()
SET_TARGET_PROPERTIES(${LIBNAME} PROPERTIES OUTPUT_NAME ${LIBNAME})
TARGET_LINK_LIBRARIES(${LIBNAME} ${EXTRA_LIBS})
@@ -370,8 +462,16 @@ INSTALL(FILES include/AL/al.h
include/AL/alext.h
DESTINATION include/AL
)
INSTALL(FILES "${OpenAL_BINARY_DIR}/admin/pkgconfig/openal.pc"
DESTINATION lib/pkgconfig)
INSTALL(FILES "${OpenAL_BINARY_DIR}/openal.pc"
DESTINATION "${LIB_INSTALL_DIR}/pkgconfig")
# Install alsoft.conf configuration file
IF(ALSOFT_CONFIG)
INSTALL(FILES alsoftrc.sample
DESTINATION /etc/openal
RENAME alsoft.conf
)
ENDIF()
IF(EXAMPLES)
ADD_EXECUTABLE(openal-info examples/openal-info.c)
@@ -388,7 +488,7 @@ MESSAGE(STATUS "Building OpenAL with support for the following backends:")
MESSAGE(STATUS " ${BACKENDS}")
MESSAGE(STATUS "")
IF(WIN32 OR XCOMPILEWIN32)
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!")
+24 -2
View File
@@ -4,7 +4,6 @@
#include "AL/al.h"
#include "alEffect.h"
#include "alFilter.h"
#include "alReverb.h"
#ifdef __cplusplus
extern "C" {
@@ -16,6 +15,8 @@ extern "C" {
#define AL_EFFECTSLOT_NULL 0x0000
typedef struct ALeffectState ALeffectState;
typedef struct ALeffectslot
{
ALeffect effect;
@@ -23,7 +24,9 @@ typedef struct ALeffectslot
ALfloat Gain;
ALboolean AuxSendAuto;
ALverbState *ReverbState;
ALeffectState *EffectState;
ALfloat WetBuffer[BUFFERSIZE];
ALuint refcount;
@@ -49,6 +52,25 @@ ALvoid AL_APIENTRY alGetAuxiliaryEffectSlotfv(ALuint effectslot, ALenum param, A
ALvoid ReleaseALAuxiliaryEffectSlots(ALCcontext *Context);
struct ALeffectState {
ALvoid (*Destroy)(ALeffectState *State);
ALboolean (*DeviceUpdate)(ALeffectState *State, ALCdevice *Device);
ALvoid (*Update)(ALeffectState *State, ALCcontext *Context, const ALeffect *Effect);
ALvoid (*Process)(ALeffectState *State, const ALeffectslot *Slot, ALuint SamplesToDo, const ALfloat *SamplesIn, ALfloat (*SamplesOut)[OUTPUTCHANNELS]);
};
ALeffectState *NoneCreate(void);
ALeffectState *EAXVerbCreate(void);
ALeffectState *VerbCreate(void);
ALeffectState *EchoCreate(void);
#define ALEffect_Destroy(a) ((a)->Destroy((a)))
#define ALEffect_DeviceUpdate(a,b) ((a)->DeviceUpdate((a),(b)))
#define ALEffect_Update(a,b,c) ((a)->Update((a),(b),(c)))
#define ALEffect_Process(a,b,c,d,e) ((a)->Process((a),(b),(c),(d),(e)))
#ifdef __cplusplus
}
#endif
+12 -10
View File
@@ -7,26 +7,28 @@
extern "C" {
#endif
#define UNUSED 0
#define PENDING 1
#define PROCESSED 2
#define BUFFER_PADDING 2
typedef struct ALbuffer_struct
typedef struct ALbuffer
{
ALfloat *data;
ALsizei size;
ALenum format;
ALenum eOriginalFormat;
ALshort *data;
ALsizei size;
ALsizei frequency;
ALsizei padding;
ALenum state;
ALuint refcount; // Number of sources using this buffer (deletion can only occur when this is 0)
struct ALbuffer_struct *next;
// Index to itself
ALuint buffer;
struct ALbuffer *next;
} ALbuffer;
ALvoid ALAPIENTRY alBufferSubDataEXT(ALuint buffer,ALenum format,const ALvoid *data,ALsizei offset,ALsizei length);
ALvoid ReleaseALBuffers(ALvoid);
ALvoid ReleaseALBuffers(ALCdevice *device);
#ifdef __cplusplus
}
+55
View File
@@ -0,0 +1,55 @@
#ifndef _AL_DATABUFFER_H_
#define _AL_DATABUFFER_H_
#include "AL/al.h"
#ifdef __cplusplus
extern "C" {
#endif
#define UNMAPPED 0
#define MAPPED 1
typedef struct ALdatabuffer
{
ALubyte *data;
ALuint size;
ALenum state;
ALenum usage;
/* Index to self */
ALuint databuffer;
struct ALdatabuffer *next;
} ALdatabuffer;
ALvoid ALAPIENTRY alGenDatabuffersEXT(ALsizei n,ALuint *puiBuffers);
ALvoid ALAPIENTRY alDeleteDatabuffersEXT(ALsizei n, const ALuint *puiBuffers);
ALboolean ALAPIENTRY alIsDatabufferEXT(ALuint uiBuffer);
ALvoid ALAPIENTRY alDatabufferDataEXT(ALuint buffer,const ALvoid *data,ALsizei size,ALenum usage);
ALvoid ALAPIENTRY alDatabufferSubDataEXT(ALuint buffer, ALuint start, ALsizei length, const ALvoid *data);
ALvoid ALAPIENTRY alGetDatabufferSubDataEXT(ALuint buffer, ALuint start, ALsizei length, ALvoid *data);
ALvoid ALAPIENTRY alDatabufferfEXT(ALuint buffer, ALenum eParam, ALfloat flValue);
ALvoid ALAPIENTRY alDatabufferfvEXT(ALuint buffer, ALenum eParam, const ALfloat* flValues);
ALvoid ALAPIENTRY alDatabufferiEXT(ALuint buffer, ALenum eParam, ALint lValue);
ALvoid ALAPIENTRY alDatabufferivEXT(ALuint buffer, ALenum eParam, const ALint* plValues);
ALvoid ALAPIENTRY alGetDatabufferfEXT(ALuint buffer, ALenum eParam, ALfloat *pflValue);
ALvoid ALAPIENTRY alGetDatabufferfvEXT(ALuint buffer, ALenum eParam, ALfloat* pflValues);
ALvoid ALAPIENTRY alGetDatabufferiEXT(ALuint buffer, ALenum eParam, ALint *plValue);
ALvoid ALAPIENTRY alGetDatabufferivEXT(ALuint buffer, ALenum eParam, ALint* plValues);
ALvoid ALAPIENTRY alSelectDatabufferEXT(ALenum target, ALuint uiBuffer);
ALvoid* ALAPIENTRY alMapDatabufferEXT(ALuint uiBuffer, ALuint start, ALsizei length, ALenum access);
ALvoid ALAPIENTRY alUnmapDatabufferEXT(ALuint uiBuffer);
ALvoid ReleaseALDatabuffers(ALCdevice *device);
#ifdef __cplusplus
}
#endif
#endif
+184 -6
View File
@@ -1,3 +1,5 @@
// NOTE: The effect structure is getting too large, it may be a good idea to
// start using a union or another form of unified storage.
#ifndef _AL_EFFECT_H_
#define _AL_EFFECT_H_
@@ -22,6 +24,7 @@ extern "C" {
#define AL_EFFECT_AUTOWAH 0x000A
#define AL_EFFECT_COMPRESSOR 0x000B
#define AL_EFFECT_EQUALIZER 0x000C
#define AL_EFFECT_EAXREVERB 0x8000
#define AL_REVERB_DENSITY 0x0001
#define AL_REVERB_DIFFUSION 0x0002
@@ -37,23 +40,176 @@ extern "C" {
#define AL_REVERB_ROOM_ROLLOFF_FACTOR 0x000C
#define AL_REVERB_DECAY_HFLIMIT 0x000D
#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)
#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
#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)
#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
#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)
enum {
REVERB = 0,
EAXREVERB = 0,
REVERB,
ECHO,
MAX_EFFECTS
};
extern ALboolean DisabledEffects[MAX_EFFECTS];
typedef struct ALeffect_struct
typedef struct ALeffect
{
// Effect type (AL_EFFECT_NULL, ...)
ALenum type;
struct {
// Shared Reverb Properties
ALfloat Density;
ALfloat Diffusion;
ALfloat Gain;
ALfloat GainHF;
ALfloat DecayTime;
@@ -65,12 +221,34 @@ typedef struct ALeffect_struct
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;
// Index to itself
ALuint effect;
struct ALeffect_struct *next;
struct ALeffect *next;
} ALeffect;
ALvoid AL_APIENTRY alGenEffects(ALsizei n, ALuint *effects);
@@ -87,7 +265,7 @@ ALvoid AL_APIENTRY alGetEffectiv(ALuint effect, ALenum param, ALint *piValues);
ALvoid AL_APIENTRY alGetEffectf(ALuint effect, ALenum param, ALfloat *pflValue);
ALvoid AL_APIENTRY alGetEffectfv(ALuint effect, ALenum param, ALfloat *pflValues);
ALvoid ReleaseALEffects(ALvoid);
ALvoid ReleaseALEffects(ALCdevice *device);
#ifdef __cplusplus
}
+70 -4
View File
@@ -2,16 +2,82 @@
#define _AL_FILTER_H_
#include "AL/al.h"
#include "alu.h"
#ifdef __cplusplus
extern "C" {
#endif
typedef struct {
ALfloat history[4];
ALfloat coeff;
#ifndef _MSC_VER
ALfloat history[0];
#else
ALfloat history[1];
#endif
} FILTER;
static __inline ALfloat lpFilter4P(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;
output = output + (history[1]-output)*a;
history[1] = output;
output = output + (history[2]-output)*a;
history[2] = output;
output = output + (history[3]-output)*a;
history[3] = output;
return output;
}
static __inline ALfloat lpFilter2P(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;
output = output + (history[1]-output)*a;
history[1] = output;
return output;
}
static __inline ALfloat lpFilter1P(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 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) */
static __inline ALfloat lpCoeffCalc(ALfloat g, ALfloat cw)
{
ALfloat a = 0.0f;
/* Be careful with gains < 0.01, as that causes the coefficient
* head towards 1, which will flatten the signal */
g = __max(g, 0.01f);
if(g < 0.9999f) /* 1-epsilon */
a = (1 - g*cw - aluSqrt(2*g*(1-cw) - g*g*(1 - cw*cw))) /
(1 - g);
return a;
}
#define AL_FILTER_TYPE 0x8001
#define AL_FILTER_NULL 0x0000
@@ -23,7 +89,7 @@ typedef struct {
#define AL_LOWPASS_GAINHF 0x0002
typedef struct ALfilter_struct
typedef struct ALfilter
{
// Filter type (AL_FILTER_NULL, ...)
ALenum type;
@@ -34,7 +100,7 @@ typedef struct ALfilter_struct
// Index to itself
ALuint filter;
struct ALfilter_struct *next;
struct ALfilter *next;
} ALfilter;
ALvoid AL_APIENTRY alGenFilters(ALsizei n, ALuint *filters);
@@ -51,7 +117,7 @@ ALvoid AL_APIENTRY alGetFilteriv(ALuint filter, ALenum param, ALint *piValues);
ALvoid AL_APIENTRY alGetFilterf(ALuint filter, ALenum param, ALfloat *pflValue);
ALvoid AL_APIENTRY alGetFilterfv(ALuint filter, ALenum param, ALfloat *pflValues);
ALvoid ReleaseALFilters(ALvoid);
ALvoid ReleaseALFilters(ALCdevice *device);
#ifdef __cplusplus
}
+173 -34
View File
@@ -3,13 +3,37 @@
#include <string.h>
#include <stdio.h>
#include "alu.h"
#include <stdarg.h>
#ifdef HAVE_FENV_H
#include <fenv.h>
#endif
#include "AL/al.h"
#include "AL/alc.h"
#include "AL/alext.h"
#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
#ifdef HAVE_GCC_FORMAT
#define PRINTF_STYLE(x, y) __attribute__((format(printf, (x), (y))))
#else
#define PRINTF_STYLE(x, y)
#endif
#ifdef _WIN32
#ifndef _WIN32_WINNT
@@ -17,8 +41,15 @@
#endif
#include <windows.h>
typedef DWORD tls_type;
#define tls_create(x) (*(x) = TlsAlloc())
#define tls_delete(x) TlsFree((x))
#define tls_get(x) TlsGetValue((x))
#define tls_set(x, a) TlsSetValue((x), (a))
#else
#include <unistd.h>
#include <assert.h>
#include <pthread.h>
#ifdef HAVE_PTHREAD_NP_H
@@ -28,7 +59,13 @@
#include <time.h>
#include <errno.h>
#define IsBadWritePtr(a,b) (0)
#define IsBadWritePtr(a,b) ((a) == NULL && (b) != 0)
typedef pthread_key_t tls_type;
#define tls_create(x) pthread_key_create((x), NULL)
#define tls_delete(x) pthread_key_delete((x))
#define tls_get(x) pthread_getspecific((x))
#define tls_set(x, a) pthread_setspecific((x), (a))
typedef pthread_mutex_t CRITICAL_SECTION;
static inline void EnterCriticalSection(CRITICAL_SECTION *cs)
@@ -76,13 +113,22 @@ static inline void DeleteCriticalSection(CRITICAL_SECTION *cs)
* as opposed to the actual time. */
static inline ALuint timeGetTime(void)
{
struct timeval tv;
int ret;
#ifdef _POSIX_TIMERS
struct timespec ts;
ret = clock_gettime(CLOCK_REALTIME, &ts);
assert(ret == 0);
return ts.tv_nsec/1000000 + ts.tv_sec*1000;
#else
struct timeval tv;
ret = gettimeofday(&tv, NULL);
assert(ret == 0);
return tv.tv_usec/1000 + tv.tv_sec*1000;
#endif
}
static inline void Sleep(ALuint t)
@@ -98,29 +144,13 @@ static inline void Sleep(ALuint t)
#define max(x,y) (((x)>(y))?(x):(y))
#endif
#include "AL/al.h"
#include "AL/alc.h"
#include "AL/alext.h"
#include "alListener.h"
#include "alu.h"
#ifdef __cplusplus
extern "C" {
#endif
extern char _alDebug[256];
#define AL_PRINT(...) do { \
int _al_print_i; \
const 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)
#define SWMIXER_OUTPUT_RATE 44100
@@ -129,12 +159,34 @@ extern char _alDebug[256];
#define LOWPASSFREQCUTOFF (5000)
#define DEFAULT_HEAD_DAMPEN (0.25f)
// Find the next power-of-2 for non-power-of-2 numbers.
static __inline ALuint NextPowerOf2(ALuint value)
{
ALuint powerOf2 = 1;
if(value)
{
value--;
while(value)
{
value >>= 1;
powerOf2 <<= 1;
}
}
return powerOf2;
}
typedef struct {
ALCboolean (*OpenPlayback)(ALCdevice*, const ALCchar*);
void (*ClosePlayback)(ALCdevice*);
ALCboolean (*ResetPlayback)(ALCdevice*);
void (*StopPlayback)(ALCdevice*);
ALCboolean (*OpenCapture)(ALCdevice*, const ALCchar*, ALCuint, ALCenum, ALCsizei);
ALCboolean (*OpenCapture)(ALCdevice*, const ALCchar*);
void (*CloseCapture)(ALCdevice*);
void (*StartCapture)(ALCdevice*);
void (*StopCapture)(ALCdevice*);
@@ -142,29 +194,92 @@ typedef struct {
ALCuint (*AvailableSamples)(ALCdevice*);
} BackendFuncs;
enum {
DEVICE_PROBE,
ALL_DEVICE_PROBE,
CAPTURE_DEVICE_PROBE
};
void alc_alsa_init(BackendFuncs *func_list);
void alc_alsa_deinit(void);
void alc_alsa_probe(int type);
void alc_oss_init(BackendFuncs *func_list);
void alc_oss_deinit(void);
void alc_oss_probe(int type);
void alc_solaris_init(BackendFuncs *func_list);
void alc_solaris_deinit(void);
void alc_solaris_probe(int type);
void alcDSoundInit(BackendFuncs *func_list);
void alcDSoundDeinit(void);
void alcDSoundProbe(int type);
void alcWinMMInit(BackendFuncs *FuncList);
void alcWinMMDeinit(void);
void alcWinMMProbe(int type);
void alc_pa_init(BackendFuncs *func_list);
void alc_pa_deinit(void);
void alc_pa_probe(int type);
void alc_wave_init(BackendFuncs *func_list);
void alc_wave_deinit(void);
void alc_wave_probe(int type);
void alc_pulse_init(BackendFuncs *func_list);
void alc_pulse_deinit(void);
void alc_pulse_probe(int type);
struct ALCdevice_struct
{
ALCboolean Connected;
ALboolean IsCaptureDevice;
ALuint Frequency;
ALuint UpdateSize;
ALuint NumUpdates;
ALenum Format;
ALCchar *szDeviceName;
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;
ALint lNumMonoSources;
ALint lNumStereoSources;
ALuint NumAuxSends;
// Linked List of Buffers for this device
struct ALbuffer *Buffers;
ALuint BufferCount;
// Linked List of Effects for this device
struct ALeffect *EffectList;
ALuint EffectCount;
// Linked List of Filters for this device
struct ALfilter *FilterList;
ALuint FilterCount;
// Linked List of Databuffers for this device
struct ALdatabuffer *Databuffers;
ALuint DatabufferCount;
// Stereo-to-binaural filter
struct bs2b *Bs2b;
ALCint Bs2bLevel;
// Simulated dampening from head occlusion
ALfloat HeadDampen;
// Dry path buffer mix
float DryBuffer[BUFFERSIZE][OUTPUTCHANNELS];
Channel DevChannels[OUTPUTCHANNELS];
// Contexts created on this device
ALCcontext **Contexts;
ALuint NumContexts;
BackendFuncs *Funcs;
void *ExtraData; // For the backend's use
@@ -174,7 +289,9 @@ struct ALCdevice_struct
#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_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)))
@@ -191,35 +308,41 @@ struct ALCcontext_struct
struct ALeffectslot *AuxiliaryEffectSlot;
ALuint AuxiliaryEffectSlotCount;
struct ALdatabuffer *SampleSource;
struct ALdatabuffer *SampleSink;
ALenum LastError;
ALboolean InUse;
ALuint Frequency;
ALboolean Suspended;
ALenum DistanceModel;
ALboolean SourceDistanceModel;
ALfloat DopplerFactor;
ALfloat DopplerVelocity;
ALfloat flSpeedOfSound;
ALint lNumMonoSources;
ALint lNumStereoSources;
ALfloat PanningLUT[OUTPUTCHANNELS * LUT_NUM];
ALint NumChan;
ALfloat ChannelMatrix[OUTPUTCHANNELS][OUTPUTCHANNELS];
ALCdevice *Device;
const ALCchar *ExtensionList;
struct bs2b *bs2b;
ALCcontext *next;
};
extern ALint RTPrioLevel;
ALCvoid ReleaseALC(ALCvoid);
ALCchar *AppendDeviceList(char *name);
ALCchar *AppendAllDeviceList(char *name);
ALCchar *AppendCaptureDeviceList(char *name);
void AppendDeviceList(const ALCchar *name);
void AppendAllDeviceList(const ALCchar *name);
void AppendCaptureDeviceList(const ALCchar *name);
ALCvoid SetALCError(ALenum errorCode);
ALCvoid alcSetError(ALCdevice *device, ALenum errorCode);
ALCvoid SuspendContext(ALCcontext *context);
ALCvoid ProcessContext(ALCcontext *context);
@@ -227,6 +350,8 @@ ALCvoid ProcessContext(ALCcontext *context);
ALvoid *StartThread(ALuint (*func)(ALvoid*), ALvoid *ptr);
ALuint StopThread(ALvoid *thread);
ALCcontext *GetContextSuspended(void);
typedef struct RingBuffer RingBuffer;
RingBuffer *CreateRingBuffer(ALsizei frame_size, ALsizei length);
void DestroyRingBuffer(RingBuffer *ring);
@@ -236,9 +361,23 @@ 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);
void EnableRTPrio(ALint level);
void SetDefaultChannelOrder(ALCdevice *device);
void SetDefaultWFXChannelOrder(ALCdevice *device);
void al_print(const char *fname, unsigned int line, const char *fmt, ...)
PRINTF_STYLE(3,4);
#define AL_PRINT(...) al_print(__FILE__, __LINE__, __VA_ARGS__)
ALCboolean ALCAPIENTRY alcMakeCurrent(ALCcontext *context);
ALCcontext* ALCAPIENTRY alcGetThreadContext(void);
#ifdef __cplusplus
}
-26
View File
@@ -1,26 +0,0 @@
#ifndef _AL_REVERB_H_
#define _AL_REVERB_H_
#include "AL/al.h"
#include "AL/alc.h"
#include "alMain.h"
#include "alAuxEffectSlot.h"
#include "alEffect.h"
#ifdef __cplusplus
extern "C" {
#endif
typedef struct ALverbState ALverbState;
ALverbState *VerbCreate(ALCcontext *Context);
ALvoid VerbDestroy(ALverbState *State);
ALvoid VerbUpdate(ALCcontext *Context, struct ALeffectslot *Slot, ALeffect *Effect);
ALvoid VerbProcess(ALverbState *State, ALuint SamplesToDo, const ALfloat *SamplesIn, ALfloat (*SamplesOut)[OUTPUTCHANNELS]);
#ifdef __cplusplus
}
#endif
#endif
+38 -20
View File
@@ -3,8 +3,7 @@
#define AL_NUM_SOURCE_PARAMS 128
/* This cannot be changed without working on the code! */
#define MAX_SENDS 1
#define MAX_SENDS 2
#include "alFilter.h"
#include "alu.h"
@@ -23,11 +22,20 @@
extern "C" {
#endif
typedef enum {
POINT_RESAMPLER = 0,
LINEAR_RESAMPLER,
COSINE_RESAMPLER,
RESAMPLER_MAX,
RESAMPLER_MIN = -1,
RESAMPLER_DEFAULT = LINEAR_RESAMPLER
} resampler_t;
extern resampler_t DefaultResampler;
typedef struct ALbufferlistitem
{
ALuint buffer;
ALuint bufferstate;
ALuint flag;
struct ALbuffer *buffer;
struct ALbufferlistitem *next;
} ALbufferlistitem;
@@ -48,27 +56,25 @@ typedef struct ALsource
ALfloat vOrientation[3];
ALboolean bHeadRelative;
ALboolean bLooping;
ALenum DistanceModel;
ALuint ulBufferID;
resampler_t Resampler;
ALboolean inuse;
ALboolean play;
ALenum state;
ALuint position;
ALuint position_fraction;
struct ALbuffer *Buffer;
struct ALbufferlistitem *queue; // Linked list of buffers in queue
ALuint BuffersInQueue; // Number of buffers in queue
ALuint TotalBufferDataSize; // Total amount of data contained in the buffers queued for this source
ALuint BuffersPlayed; // Number of buffers played on this loop
ALuint BuffersPlayed; // Number of buffers played on this loop
ALfilter DirectFilter;
struct {
struct ALeffectslot *Slot;
ALfilter WetFilter;
FILTER iirFilter;
} Send[MAX_SENDS];
ALboolean DryGainHFAuto;
@@ -76,17 +82,10 @@ typedef struct ALsource
ALboolean WetGainHFAuto;
ALfloat OuterGainHF;
FILTER iirFilter;
ALfloat AirAbsorptionFactor;
ALfloat RoomRolloffFactor;
ALfloat DopplerFactor;
// Index to itself
ALuint source;
ALint lOffset;
ALint lOffsetType;
@@ -95,9 +94,28 @@ typedef struct ALsource
// Current gains, which are ramped while mixed
ALfloat DryGains[OUTPUTCHANNELS];
ALfloat WetGain;
ALfloat WetGains[MAX_SENDS];
ALboolean FirstStart;
// Current target parameters used for mixing
ALboolean NeedsUpdate;
struct {
ALfloat DryGains[OUTPUTCHANNELS];
ALfloat WetGains[MAX_SENDS];
ALfloat Pitch;
struct {
FILTER iirFilter;
ALfloat history[OUTPUTCHANNELS];
} Send[MAX_SENDS];
FILTER iirFilter;
ALfloat history[OUTPUTCHANNELS*2];
} Params;
// Index to itself
ALuint source;
struct ALsource *next;
} ALsource;
+149 -9
View File
@@ -3,29 +3,169 @@
#include "AL/al.h"
#include "AL/alc.h"
#include "AL/alext.h"
#include <math.h>
#ifdef HAVE_FLOAT_H
#include <float.h>
#endif
#ifndef M_PI
#define M_PI 3.14159265358979323846 /* pi */
#define M_PI_2 1.57079632679489661923 /* pi/2 */
#endif
#ifdef HAVE_SQRTF
#define aluSqrt(x) ((ALfloat)sqrtf((float)(x)))
#else
#define aluSqrt(x) ((ALfloat)sqrt((double)(x)))
#endif
#ifdef HAVE_ACOSF
#define aluAcos(x) ((ALfloat)acosf((float)(x)))
#else
#define aluAcos(x) ((ALfloat)acos((double)(x)))
#endif
#ifdef HAVE_ATANF
#define aluAtan(x) ((ALfloat)atanf((float)(x)))
#else
#define aluAtan(x) ((ALfloat)atan((double)(x)))
#endif
#ifdef HAVE_FABSF
#define aluFabs(x) ((ALfloat)fabsf((float)(x)))
#else
#define aluFabs(x) ((ALfloat)fabs((double)(x)))
#endif
// fixes for mingw32.
#if defined(max) && !defined(__max)
#define __max max
#endif
#if defined(min) && !defined(__min)
#define __min min
#endif
#define QUADRANT_NUM 128
#define LUT_NUM (4 * QUADRANT_NUM)
#ifdef __cplusplus
extern "C" {
#endif
enum {
typedef enum {
FRONT_LEFT = 0,
FRONT_RIGHT,
SIDE_LEFT,
SIDE_RIGHT,
FRONT_CENTER,
LFE,
BACK_LEFT,
BACK_RIGHT,
CENTER,
LFE,
BACK_CENTER,
SIDE_LEFT,
SIDE_RIGHT,
OUTPUTCHANNELS
};
} Channel;
#define BUFFERSIZE 24000
extern ALboolean DuplicateStereo;
__inline ALuint aluBytesFromFormat(ALenum format);
__inline ALuint aluChannelsFromFormat(ALenum format);
ALvoid aluMixData(ALCcontext *context,ALvoid *buffer,ALsizei size,ALenum format);
/* NOTE: The AL_FORMAT_REAR* enums aren't handled here be cause they're
* converted to AL_FORMAT_QUAD* when loaded */
static __inline ALuint aluBytesFromFormat(ALenum format)
{
switch(format)
{
case AL_FORMAT_MONO8:
case AL_FORMAT_STEREO8:
case AL_FORMAT_QUAD8_LOKI:
case AL_FORMAT_QUAD8:
case AL_FORMAT_51CHN8:
case AL_FORMAT_61CHN8:
case AL_FORMAT_71CHN8:
return 1;
case AL_FORMAT_MONO16:
case AL_FORMAT_STEREO16:
case AL_FORMAT_QUAD16_LOKI:
case AL_FORMAT_QUAD16:
case AL_FORMAT_51CHN16:
case AL_FORMAT_61CHN16:
case AL_FORMAT_71CHN16:
return 2;
case AL_FORMAT_MONO_FLOAT32:
case AL_FORMAT_STEREO_FLOAT32:
case AL_FORMAT_QUAD32:
case AL_FORMAT_51CHN32:
case AL_FORMAT_61CHN32:
case AL_FORMAT_71CHN32:
return 4;
default:
return 0;
}
}
static __inline ALuint aluChannelsFromFormat(ALenum format)
{
switch(format)
{
case AL_FORMAT_MONO8:
case AL_FORMAT_MONO16:
case AL_FORMAT_MONO_FLOAT32:
return 1;
case AL_FORMAT_STEREO8:
case AL_FORMAT_STEREO16:
case AL_FORMAT_STEREO_FLOAT32:
return 2;
case AL_FORMAT_QUAD8_LOKI:
case AL_FORMAT_QUAD16_LOKI:
case AL_FORMAT_QUAD8:
case AL_FORMAT_QUAD16:
case AL_FORMAT_QUAD32:
return 4;
case AL_FORMAT_51CHN8:
case AL_FORMAT_51CHN16:
case AL_FORMAT_51CHN32:
return 6;
case AL_FORMAT_61CHN8:
case AL_FORMAT_61CHN16:
case AL_FORMAT_61CHN32:
return 7;
case AL_FORMAT_71CHN8:
case AL_FORMAT_71CHN16:
case AL_FORMAT_71CHN32:
return 8;
default:
return 0;
}
}
static __inline ALint aluCart2LUTpos(ALfloat re, ALfloat im)
{
ALint pos = 0;
ALfloat denom = aluFabs(re) + aluFabs(im);
if(denom > 0.0f)
pos = (ALint)(QUADRANT_NUM*aluFabs(im) / denom + 0.5);
if(re < 0.0)
pos = 2 * QUADRANT_NUM - pos;
if(im < 0.0)
pos = LUT_NUM - pos;
return pos%LUT_NUM;
}
ALvoid aluInitPanning(ALCcontext *Context);
ALvoid aluMixData(ALCdevice *device, ALvoid *buffer, ALsizei size);
ALvoid aluHandleDisconnect(ALCdevice *device);
#ifdef __cplusplus
}
+127 -101
View File
@@ -29,7 +29,7 @@
#include "alAuxEffectSlot.h"
#include "alThunk.h"
#include "alError.h"
#include "alReverb.h"
#include "alSource.h"
static ALvoid InitializeEffect(ALCcontext *Context, ALeffectslot *ALEffectSlot, ALeffect *effect);
@@ -38,20 +38,16 @@ static ALvoid InitializeEffect(ALCcontext *Context, ALeffectslot *ALEffectSlot,
ALvoid AL_APIENTRY alGenAuxiliaryEffectSlots(ALsizei n, ALuint *effectslots)
{
ALCcontext *Context;
ALsizei i;
ALsizei i, j;
Context = alcGetCurrentContext();
if(!Context)
{
alSetError(AL_INVALID_OPERATION);
return;
}
SuspendContext(Context);
Context = GetContextSuspended();
if(!Context) return;
if (n > 0)
{
/* NOTE: We only support one slot currently */
if(n == 1 && Context->AuxiliaryEffectSlotCount == 0)
ALCdevice *Device = Context->Device;
if(Context->AuxiliaryEffectSlotCount+n <= Device->AuxiliaryEffectSlotMax)
{
// Check that enough memory has been allocted in the 'effectslots' array for n Effect Slots
if (!IsBadWritePtr((void*)effectslots, n * sizeof(ALuint)))
@@ -64,9 +60,10 @@ ALvoid AL_APIENTRY alGenAuxiliaryEffectSlots(ALsizei n, ALuint *effectslots)
while(i < n)
{
*list = calloc(1, sizeof(ALeffectslot));
if(!(*list))
if(!(*list) || !((*list)->EffectState=NoneCreate()))
{
// We must have run out or memory
free(*list); *list = NULL;
alDeleteAuxiliaryEffectSlots(i, effectslots);
alSetError(AL_OUT_OF_MEMORY);
break;
@@ -74,6 +71,8 @@ ALvoid AL_APIENTRY alGenAuxiliaryEffectSlots(ALsizei n, ALuint *effectslots)
(*list)->Gain = 1.0;
(*list)->AuxSendAuto = AL_TRUE;
for(j = 0;j < BUFFERSIZE;j++)
(*list)->WetBuffer[j] = 0.0f;
(*list)->refcount = 0;
effectslots[i] = (ALuint)ALTHUNK_ADDENTRY(*list);
@@ -99,13 +98,8 @@ ALvoid AL_APIENTRY alDeleteAuxiliaryEffectSlots(ALsizei n, ALuint *effectslots)
ALeffectslot *ALAuxiliaryEffectSlot;
ALsizei i;
Context = alcGetCurrentContext();
if(!Context)
{
alSetError(AL_INVALID_OPERATION);
return;
}
SuspendContext(Context);
Context = GetContextSuspended();
if(!Context) return;
if (n >= 0)
{
@@ -149,7 +143,8 @@ ALvoid AL_APIENTRY alDeleteAuxiliaryEffectSlots(ALsizei n, ALuint *effectslots)
*list = (*list)->next;
ALTHUNK_REMOVEENTRY(ALAuxiliaryEffectSlot->effectslot);
VerbDestroy(ALAuxiliaryEffectSlot->ReverbState);
if(ALAuxiliaryEffectSlot->EffectState)
ALEffect_Destroy(ALAuxiliaryEffectSlot->EffectState);
memset(ALAuxiliaryEffectSlot, 0, sizeof(ALeffectslot));
free(ALAuxiliaryEffectSlot);
@@ -170,13 +165,8 @@ ALboolean AL_APIENTRY alIsAuxiliaryEffectSlot(ALuint effectslot)
ALCcontext *Context;
ALeffectslot **list;
Context = alcGetCurrentContext();
if(!Context)
{
alSetError(AL_INVALID_OPERATION);
return AL_FALSE;
}
SuspendContext(Context);
Context = GetContextSuspended();
if(!Context) return AL_FALSE;
list = &Context->AuxiliaryEffectSlot;
while(*list && (*list)->effectslot != effectslot)
@@ -190,14 +180,10 @@ ALboolean AL_APIENTRY alIsAuxiliaryEffectSlot(ALuint effectslot)
ALvoid AL_APIENTRY alAuxiliaryEffectSloti(ALuint effectslot, ALenum param, ALint iValue)
{
ALCcontext *Context;
ALboolean updateSources = AL_FALSE;
Context = alcGetCurrentContext();
if(!Context)
{
alSetError(AL_INVALID_OPERATION);
return;
}
SuspendContext(Context);
Context = GetContextSuspended();
if(!Context) return;
if (alIsAuxiliaryEffectSlot(effectslot))
{
@@ -210,6 +196,7 @@ ALvoid AL_APIENTRY alAuxiliaryEffectSloti(ALuint effectslot, ALenum param, ALint
{
ALeffect *effect = (ALeffect*)ALTHUNK_LOOKUPENTRY(iValue);
InitializeEffect(Context, ALEffectSlot, effect);
updateSources = AL_TRUE;
}
else
alSetError(AL_INVALID_VALUE);
@@ -217,7 +204,10 @@ ALvoid AL_APIENTRY alAuxiliaryEffectSloti(ALuint effectslot, ALenum param, ALint
case AL_EFFECTSLOT_AUXILIARY_SEND_AUTO:
if(iValue == AL_TRUE || iValue == AL_FALSE)
{
ALEffectSlot->AuxSendAuto = iValue;
updateSources = AL_TRUE;
}
else
alSetError(AL_INVALID_VALUE);
break;
@@ -230,6 +220,26 @@ ALvoid AL_APIENTRY alAuxiliaryEffectSloti(ALuint effectslot, ALenum param, ALint
else
alSetError(AL_INVALID_NAME);
// Force updating the sources that use this slot, since it affects the
// sending parameters
if(updateSources)
{
ALsource *source = Context->Source;
while(source)
{
ALuint i;
for(i = 0;i < MAX_SENDS;i++)
{
if(!source->Send[i].Slot ||
source->Send[i].Slot->effectslot != effectslot)
continue;
source->NeedsUpdate = AL_TRUE;
break;
}
source = source->next;
}
}
ProcessContext(Context);
}
@@ -237,13 +247,8 @@ ALvoid AL_APIENTRY alAuxiliaryEffectSlotiv(ALuint effectslot, ALenum param, ALin
{
ALCcontext *Context;
Context = alcGetCurrentContext();
if(!Context)
{
alSetError(AL_INVALID_OPERATION);
return;
}
SuspendContext(Context);
Context = GetContextSuspended();
if(!Context) return;
if (alIsAuxiliaryEffectSlot(effectslot))
{
@@ -269,13 +274,8 @@ ALvoid AL_APIENTRY alAuxiliaryEffectSlotf(ALuint effectslot, ALenum param, ALflo
{
ALCcontext *Context;
Context = alcGetCurrentContext();
if(!Context)
{
alSetError(AL_INVALID_OPERATION);
return;
}
SuspendContext(Context);
Context = GetContextSuspended();
if(!Context) return;
if (alIsAuxiliaryEffectSlot(effectslot))
{
@@ -305,13 +305,8 @@ ALvoid AL_APIENTRY alAuxiliaryEffectSlotfv(ALuint effectslot, ALenum param, ALfl
{
ALCcontext *Context;
Context = alcGetCurrentContext();
if(!Context)
{
alSetError(AL_INVALID_OPERATION);
return;
}
SuspendContext(Context);
Context = GetContextSuspended();
if(!Context) return;
if (alIsAuxiliaryEffectSlot(effectslot))
{
@@ -336,13 +331,8 @@ ALvoid AL_APIENTRY alGetAuxiliaryEffectSloti(ALuint effectslot, ALenum param, AL
{
ALCcontext *Context;
Context = alcGetCurrentContext();
if(!Context)
{
alSetError(AL_INVALID_OPERATION);
return;
}
SuspendContext(Context);
Context = GetContextSuspended();
if(!Context) return;
if (alIsAuxiliaryEffectSlot(effectslot))
{
@@ -373,13 +363,8 @@ ALvoid AL_APIENTRY alGetAuxiliaryEffectSlotiv(ALuint effectslot, ALenum param, A
{
ALCcontext *Context;
Context = alcGetCurrentContext();
if(!Context)
{
alSetError(AL_INVALID_OPERATION);
return;
}
SuspendContext(Context);
Context = GetContextSuspended();
if(!Context) return;
if (alIsAuxiliaryEffectSlot(effectslot))
{
@@ -405,13 +390,8 @@ ALvoid AL_APIENTRY alGetAuxiliaryEffectSlotf(ALuint effectslot, ALenum param, AL
{
ALCcontext *Context;
Context = alcGetCurrentContext();
if(!Context)
{
alSetError(AL_INVALID_OPERATION);
return;
}
SuspendContext(Context);
Context = GetContextSuspended();
if(!Context) return;
if (alIsAuxiliaryEffectSlot(effectslot))
{
@@ -438,13 +418,8 @@ ALvoid AL_APIENTRY alGetAuxiliaryEffectSlotfv(ALuint effectslot, ALenum param, A
{
ALCcontext *Context;
Context = alcGetCurrentContext();
if(!Context)
{
alSetError(AL_INVALID_OPERATION);
return;
}
SuspendContext(Context);
Context = GetContextSuspended();
if(!Context) return;
if (alIsAuxiliaryEffectSlot(effectslot))
{
@@ -466,39 +441,90 @@ ALvoid AL_APIENTRY alGetAuxiliaryEffectSlotfv(ALuint effectslot, ALenum param, A
}
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, ALCcontext *Context, const ALeffect *Effect)
{
(void)State;
(void)Context;
(void)Effect;
}
static ALvoid NoneProcess(ALeffectState *State, const ALeffectslot *Slot, ALuint SamplesToDo, const ALfloat *SamplesIn, ALfloat (*SamplesOut)[OUTPUTCHANNELS])
{
(void)State;
(void)Slot;
(void)SamplesToDo;
(void)SamplesIn;
(void)SamplesOut;
}
ALeffectState *NoneCreate(void)
{
ALeffectState *state;
state = calloc(1, sizeof(*state));
if(!state)
{
alSetError(AL_OUT_OF_MEMORY);
return NULL;
}
state->Destroy = NoneDestroy;
state->DeviceUpdate = NoneDeviceUpdate;
state->Update = NoneUpdate;
state->Process = NoneProcess;
return state;
}
static ALvoid InitializeEffect(ALCcontext *Context, ALeffectslot *ALEffectSlot, ALeffect *effect)
{
if(ALEffectSlot->effect.type != (effect?effect->type:AL_EFFECT_NULL))
{
ALeffectState *NewState = NULL;
if(!effect || effect->type == AL_EFFECT_NULL)
NewState = NoneCreate();
else if(effect->type == AL_EFFECT_EAXREVERB)
NewState = EAXVerbCreate();
else if(effect->type == AL_EFFECT_REVERB)
NewState = VerbCreate();
else if(effect->type == AL_EFFECT_ECHO)
NewState = EchoCreate();
/* No new state? An error occured.. */
if(NewState == NULL ||
ALEffect_DeviceUpdate(NewState, Context->Device) == AL_FALSE)
{
if(NewState)
ALEffect_Destroy(NewState);
return;
}
if(ALEffectSlot->EffectState)
ALEffect_Destroy(ALEffectSlot->EffectState);
ALEffectSlot->EffectState = NewState;
}
if(!effect)
{
memset(&ALEffectSlot->effect, 0, sizeof(ALEffectSlot->effect));
VerbDestroy(ALEffectSlot->ReverbState);
ALEffectSlot->ReverbState = NULL;
return;
}
if(effect->type == AL_EFFECT_REVERB)
{
if(!ALEffectSlot->ReverbState)
ALEffectSlot->ReverbState = VerbCreate(Context);
VerbUpdate(Context, ALEffectSlot, effect);
}
memcpy(&ALEffectSlot->effect, effect, sizeof(*effect));
else
memcpy(&ALEffectSlot->effect, effect, sizeof(*effect));
ALEffect_Update(ALEffectSlot->EffectState, Context, effect);
}
ALvoid ReleaseALAuxiliaryEffectSlots(ALCcontext *Context)
{
#ifdef _DEBUG
if(Context->AuxiliaryEffectSlotCount > 0)
AL_PRINT("alcDestroyContext(): deleting %d AuxiliaryEffectSlot(s)\n", Context->AuxiliaryEffectSlotCount);
#endif
while(Context->AuxiliaryEffectSlot)
{
ALeffectslot *temp = Context->AuxiliaryEffectSlot;
Context->AuxiliaryEffectSlot = Context->AuxiliaryEffectSlot->next;
// Release effectslot structure
VerbDestroy(temp->ReverbState);
if(temp->EffectState)
ALEffect_Destroy(temp->EffectState);
ALTHUNK_REMOVEENTRY(temp->effectslot);
memset(temp, 0, sizeof(ALeffectslot));
+145 -123
View File
@@ -18,8 +18,6 @@
* Or go to http://www.gnu.org/copyleft/lgpl.html
*/
#define _CRT_SECURE_NO_DEPRECATE // get rid of sprintf security warnings on VS2005
#include "config.h"
#include <stdlib.h>
@@ -30,13 +28,14 @@
#include "AL/alc.h"
#include "alError.h"
#include "alBuffer.h"
#include "alDatabuffer.h"
#include "alThunk.h"
static void LoadData(ALbuffer *ALBuf, const ALubyte *data, ALsizei size, ALuint freq, ALenum OrigFormat, ALenum NewFormat);
static void ConvertData(ALshort *dst, const ALvoid *src, ALint origBytes, ALsizei len);
static void ConvertDataRear(ALshort *dst, const ALvoid *src, ALint origBytes, ALsizei len);
static void ConvertDataIMA4(ALshort *dst, const ALvoid *src, ALint origChans, ALsizei len);
static void ConvertData(ALfloat *dst, const ALvoid *src, ALint origBytes, ALsizei len);
static void ConvertDataRear(ALfloat *dst, const ALvoid *src, ALint origBytes, ALsizei len);
static void ConvertDataIMA4(ALfloat *dst, const ALvoid *src, ALint origChans, ALsizei len);
/*
* AL Buffer Functions
@@ -51,9 +50,6 @@ static void ConvertDataIMA4(ALshort *dst, const ALvoid *src, ALint origChans, AL
* Global Variables
*/
static ALbuffer *g_pBuffers = NULL; // Linked List of Buffers
static ALuint g_uiBufferCount = 0; // Buffer Count
static const long g_IMAStep_size[89]={ // IMA ADPCM Stepsize table
7, 8, 9, 10, 11, 12, 13, 14, 16, 17, 19, 21, 23, 25, 28, 31,
34, 37, 41, 45, 50, 55, 60, 66, 73, 80, 88, 97, 107, 118, 130, 143,
@@ -83,16 +79,18 @@ ALAPI ALvoid ALAPIENTRY alGenBuffers(ALsizei n,ALuint *puiBuffers)
ALCcontext *Context;
ALsizei i=0;
Context = alcGetCurrentContext();
SuspendContext(Context);
Context = GetContextSuspended();
if(!Context) return;
// Check that we are actually generation some Buffers
if (n > 0)
{
ALCdevice *device = Context->Device;
// Check the pointer is valid (and points to enough memory to store Buffer Names)
if (!IsBadWritePtr((void*)puiBuffers, n * sizeof(ALuint)))
{
ALbuffer **list = &g_pBuffers;
ALbuffer **list = &device->Buffers;
while(*list)
list = &(*list)->next;
@@ -108,8 +106,9 @@ ALAPI ALvoid ALAPIENTRY alGenBuffers(ALsizei n,ALuint *puiBuffers)
}
puiBuffers[i] = (ALuint)ALTHUNK_ADDENTRY(*list);
(*list)->state = UNUSED;
g_uiBufferCount++;
(*list)->buffer = puiBuffers[i];
device->BufferCount++;
i++;
list = &(*list)->next;
@@ -123,8 +122,6 @@ ALAPI ALvoid ALAPIENTRY alGenBuffers(ALsizei n,ALuint *puiBuffers)
}
ProcessContext(Context);
return;
}
/*
@@ -139,12 +136,14 @@ ALAPI ALvoid ALAPIENTRY alDeleteBuffers(ALsizei n, const ALuint *puiBuffers)
ALsizei i;
ALboolean bFailed = AL_FALSE;
Context = alcGetCurrentContext();
SuspendContext(Context);
Context = GetContextSuspended();
if(!Context) return;
// Check we are actually Deleting some Buffers
if (n >= 0)
{
ALCdevice *device = Context->Device;
// Check that all the buffers are valid and can actually be deleted
for (i = 0; i < n; i++)
{
@@ -178,7 +177,7 @@ ALAPI ALvoid ALAPIENTRY alDeleteBuffers(ALsizei n, const ALuint *puiBuffers)
{
if (puiBuffers[i] && alIsBuffer(puiBuffers[i]))
{
ALbuffer **list = &g_pBuffers;
ALbuffer **list = &device->Buffers;
ALBuf=((ALbuffer *)ALTHUNK_LOOKUPENTRY(puiBuffers[i]));
while(*list && *list != ALBuf)
@@ -193,7 +192,7 @@ ALAPI ALvoid ALAPIENTRY alDeleteBuffers(ALsizei n, const ALuint *puiBuffers)
// Release buffer structure
ALTHUNK_REMOVEENTRY(puiBuffers[i]);
memset(ALBuf, 0, sizeof(ALbuffer));
g_uiBufferCount--;
device->BufferCount--;
free(ALBuf);
}
}
@@ -203,9 +202,6 @@ ALAPI ALvoid ALAPIENTRY alDeleteBuffers(ALsizei n, const ALuint *puiBuffers)
alSetError(AL_INVALID_VALUE);
ProcessContext(Context);
return;
}
/*
@@ -220,15 +216,17 @@ ALAPI ALboolean ALAPIENTRY alIsBuffer(ALuint uiBuffer)
ALbuffer *ALBuf;
ALbuffer *TgtALBuf;
Context = alcGetCurrentContext();
SuspendContext(Context);
Context = GetContextSuspended();
if(!Context) return AL_FALSE;
if (uiBuffer)
{
ALCdevice *device = Context->Device;
TgtALBuf = (ALbuffer *)ALTHUNK_LOOKUPENTRY(uiBuffer);
// Check through list of generated buffers for uiBuffer
ALBuf = g_pBuffers;
ALBuf = device->Buffers;
while (ALBuf)
{
if (ALBuf == TgtALBuf)
@@ -259,16 +257,31 @@ ALAPI ALboolean ALAPIENTRY alIsBuffer(ALuint uiBuffer)
ALAPI ALvoid ALAPIENTRY alBufferData(ALuint buffer,ALenum format,const ALvoid *data,ALsizei size,ALsizei freq)
{
ALCcontext *Context;
ALsizei padding = 2;
ALbuffer *ALBuf;
ALvoid *temp;
Context = alcGetCurrentContext();
SuspendContext(Context);
Context = GetContextSuspended();
if(!Context) return;
if (alIsBuffer(buffer) && (buffer != 0))
{
ALBuf=((ALbuffer *)ALTHUNK_LOOKUPENTRY(buffer));
if(Context->SampleSource)
{
ALuint offset;
if(Context->SampleSource->state == MAPPED)
{
alSetError(AL_INVALID_OPERATION);
ProcessContext(Context);
return;
}
offset = (ALuint)data;
data = Context->SampleSource->data + offset;
}
if ((ALBuf->refcount==0)&&(data))
{
switch(format)
@@ -276,20 +289,21 @@ ALAPI ALvoid ALAPIENTRY alBufferData(ALuint buffer,ALenum format,const ALvoid *d
case AL_FORMAT_MONO8:
case AL_FORMAT_MONO16:
case AL_FORMAT_MONO_FLOAT32:
LoadData(ALBuf, data, size, freq, format, AL_FORMAT_MONO16);
LoadData(ALBuf, data, size, freq, format, AL_FORMAT_MONO_FLOAT32);
break;
case AL_FORMAT_STEREO8:
case AL_FORMAT_STEREO16:
case AL_FORMAT_STEREO_FLOAT32:
LoadData(ALBuf, data, size, freq, format, AL_FORMAT_STEREO16);
LoadData(ALBuf, data, size, freq, format, AL_FORMAT_STEREO_FLOAT32);
break;
case AL_FORMAT_REAR8:
case AL_FORMAT_REAR16:
case AL_FORMAT_REAR32: {
ALuint NewFormat = AL_FORMAT_QUAD16;
ALuint NewFormat = AL_FORMAT_QUAD32;
ALuint NewChannels = aluChannelsFromFormat(NewFormat);
ALuint NewBytes = aluBytesFromFormat(NewFormat);
ALuint OrigBytes = ((format==AL_FORMAT_REAR8) ? 1 :
((format==AL_FORMAT_REAR16) ? 2 :
4));
@@ -305,20 +319,17 @@ ALAPI ALvoid ALAPIENTRY alBufferData(ALuint buffer,ALenum format,const ALvoid *d
size /= OrigBytes;
size *= 2;
// Samples are converted to 16 bit here
temp = realloc(ALBuf->data, (padding*NewChannels + size) * sizeof(ALshort));
// Samples are converted here
temp = realloc(ALBuf->data, (BUFFER_PADDING*NewChannels + size) * NewBytes);
if(temp)
{
ALBuf->data = temp;
ConvertDataRear(ALBuf->data, data, OrigBytes, size);
memset(&(ALBuf->data[size]), 0, padding*NewChannels*sizeof(ALshort));
ALBuf->format = NewFormat;
ALBuf->eOriginalFormat = format;
ALBuf->size = size*sizeof(ALshort);
ALBuf->size = size*NewBytes;
ALBuf->frequency = freq;
ALBuf->padding = padding;
}
else
alSetError(AL_OUT_OF_MEMORY);
@@ -329,30 +340,33 @@ ALAPI ALvoid ALAPIENTRY alBufferData(ALuint buffer,ALenum format,const ALvoid *d
case AL_FORMAT_QUAD8:
case AL_FORMAT_QUAD16:
case AL_FORMAT_QUAD32:
LoadData(ALBuf, data, size, freq, format, AL_FORMAT_QUAD16);
LoadData(ALBuf, data, size, freq, format, AL_FORMAT_QUAD32);
break;
case AL_FORMAT_51CHN8:
case AL_FORMAT_51CHN16:
case AL_FORMAT_51CHN32:
LoadData(ALBuf, data, size, freq, format, AL_FORMAT_51CHN16);
LoadData(ALBuf, data, size, freq, format, AL_FORMAT_51CHN32);
break;
case AL_FORMAT_61CHN8:
case AL_FORMAT_61CHN16:
case AL_FORMAT_61CHN32:
LoadData(ALBuf, data, size, freq, format, AL_FORMAT_61CHN16);
LoadData(ALBuf, data, size, freq, format, AL_FORMAT_61CHN32);
break;
case AL_FORMAT_71CHN8:
case AL_FORMAT_71CHN16:
case AL_FORMAT_71CHN32:
LoadData(ALBuf, data, size, freq, format, AL_FORMAT_71CHN16);
LoadData(ALBuf, data, size, freq, format, AL_FORMAT_71CHN32);
break;
case AL_FORMAT_MONO_IMA4:
case AL_FORMAT_STEREO_IMA4: {
int OrigChans = ((format==AL_FORMAT_MONO_IMA4) ? 1 : 2);
ALuint NewFormat = ((OrigChans==1) ? AL_FORMAT_MONO_FLOAT32 :
AL_FORMAT_STEREO_FLOAT32);
ALuint NewBytes = aluBytesFromFormat(NewFormat);
// Here is where things vary:
// nVidia and Apple use 64+1 samples per channel per block => block_size=36*chans bytes
@@ -367,19 +381,16 @@ ALAPI ALvoid ALAPIENTRY alBufferData(ALuint buffer,ALenum format,const ALvoid *d
size *= 65;
// Allocate extra padding samples
temp = realloc(ALBuf->data, (padding*OrigChans + size)*sizeof(ALshort));
temp = realloc(ALBuf->data, (BUFFER_PADDING*OrigChans + size)*NewBytes);
if(temp)
{
ALBuf->data = temp;
ConvertDataIMA4(ALBuf->data, data, OrigChans, size/65);
memset(&(ALBuf->data[size]), 0, padding*sizeof(ALshort)*OrigChans);
ALBuf->format = ((OrigChans==1) ? AL_FORMAT_MONO16 : AL_FORMAT_STEREO16);
ALBuf->format = NewFormat;
ALBuf->eOriginalFormat = format;
ALBuf->size = size*sizeof(ALshort);
ALBuf->size = size*NewBytes;
ALBuf->frequency = freq;
ALBuf->padding = padding;
}
else
alSetError(AL_OUT_OF_MEMORY);
@@ -415,12 +426,28 @@ ALvoid ALAPIENTRY alBufferSubDataEXT(ALuint buffer,ALenum format,const ALvoid *d
ALCcontext *Context;
ALbuffer *ALBuf;
Context = alcGetCurrentContext();
SuspendContext(Context);
Context = GetContextSuspended();
if(!Context) return;
if(alIsBuffer(buffer) && buffer != 0)
{
ALBuf = (ALbuffer*)ALTHUNK_LOOKUPENTRY(buffer);
if(Context->SampleSource)
{
ALuint offset;
if(Context->SampleSource->state == MAPPED)
{
alSetError(AL_INVALID_OPERATION);
ProcessContext(Context);
return;
}
offset = (ALuint)data;
data = Context->SampleSource->data + offset;
}
if(ALBuf->data == NULL)
{
// buffer does not have any data
@@ -441,6 +468,7 @@ ALvoid ALAPIENTRY alBufferSubDataEXT(ALuint buffer,ALenum format,const ALvoid *d
ALuint OrigBytes = ((format==AL_FORMAT_REAR8) ? 1 :
((format==AL_FORMAT_REAR16) ? 2 :
4));
ALuint NewBytes = aluBytesFromFormat(ALBuf->format);
if(ALBuf->eOriginalFormat != AL_FORMAT_REAR8 &&
ALBuf->eOriginalFormat != AL_FORMAT_REAR16 &&
@@ -450,7 +478,7 @@ ALvoid ALAPIENTRY alBufferSubDataEXT(ALuint buffer,ALenum format,const ALvoid *d
break;
}
if(ALBuf->size/4/sizeof(ALshort) < (ALuint)offset+length)
if(ALBuf->size/4/NewBytes < (ALuint)offset+length)
{
alSetError(AL_INVALID_VALUE);
break;
@@ -462,6 +490,7 @@ ALvoid ALAPIENTRY alBufferSubDataEXT(ALuint buffer,ALenum format,const ALvoid *d
case AL_FORMAT_MONO_IMA4:
case AL_FORMAT_STEREO_IMA4: {
int Channels = aluChannelsFromFormat(ALBuf->format);
ALuint Bytes = aluBytesFromFormat(ALBuf->format);
if(ALBuf->eOriginalFormat != format)
{
@@ -470,7 +499,7 @@ ALvoid ALAPIENTRY alBufferSubDataEXT(ALuint buffer,ALenum format,const ALvoid *d
}
if((offset%65) != 0 || (length%65) != 0 ||
ALBuf->size/Channels/sizeof(ALshort) < (ALuint)offset+length)
ALBuf->size/Channels/Bytes < (ALuint)offset+length)
{
alSetError(AL_INVALID_VALUE);
break;
@@ -482,6 +511,7 @@ ALvoid ALAPIENTRY alBufferSubDataEXT(ALuint buffer,ALenum format,const ALvoid *d
default: {
ALuint Channels = aluChannelsFromFormat(format);
ALuint Bytes = aluBytesFromFormat(format);
ALuint NewBytes = aluBytesFromFormat(ALBuf->format);
if(Channels != aluChannelsFromFormat(ALBuf->format))
{
@@ -489,7 +519,7 @@ ALvoid ALAPIENTRY alBufferSubDataEXT(ALuint buffer,ALenum format,const ALvoid *d
break;
}
if(ALBuf->size/Channels/sizeof(ALshort) < (ALuint)offset+length)
if(ALBuf->size/Channels/NewBytes < (ALuint)offset+length)
{
alSetError(AL_INVALID_VALUE);
break;
@@ -516,8 +546,8 @@ ALAPI void ALAPIENTRY alBufferf(ALuint buffer, ALenum eParam, ALfloat flValue)
(void)flValue;
pContext = alcGetCurrentContext();
SuspendContext(pContext);
pContext = GetContextSuspended();
if(!pContext) return;
if (alIsBuffer(buffer) && (buffer != 0))
{
@@ -545,8 +575,8 @@ ALAPI void ALAPIENTRY alBuffer3f(ALuint buffer, ALenum eParam, ALfloat flValue1,
(void)flValue2;
(void)flValue3;
pContext = alcGetCurrentContext();
SuspendContext(pContext);
pContext = GetContextSuspended();
if(!pContext) return;
if (alIsBuffer(buffer) && (buffer != 0))
{
@@ -572,8 +602,8 @@ ALAPI void ALAPIENTRY alBufferfv(ALuint buffer, ALenum eParam, const ALfloat* fl
(void)flValues;
pContext = alcGetCurrentContext();
SuspendContext(pContext);
pContext = GetContextSuspended();
if(!pContext) return;
if (alIsBuffer(buffer) && (buffer != 0))
{
@@ -599,8 +629,8 @@ ALAPI void ALAPIENTRY alBufferi(ALuint buffer, ALenum eParam, ALint lValue)
(void)lValue;
pContext = alcGetCurrentContext();
SuspendContext(pContext);
pContext = GetContextSuspended();
if(!pContext) return;
if (alIsBuffer(buffer) && (buffer != 0))
{
@@ -628,8 +658,8 @@ ALAPI void ALAPIENTRY alBuffer3i( ALuint buffer, ALenum eParam, ALint lValue1, A
(void)lValue2;
(void)lValue3;
pContext = alcGetCurrentContext();
SuspendContext(pContext);
pContext = GetContextSuspended();
if(!pContext) return;
if (alIsBuffer(buffer) && (buffer != 0))
{
@@ -655,8 +685,8 @@ ALAPI void ALAPIENTRY alBufferiv(ALuint buffer, ALenum eParam, const ALint* plVa
(void)plValues;
pContext = alcGetCurrentContext();
SuspendContext(pContext);
pContext = GetContextSuspended();
if(!pContext) return;
if (alIsBuffer(buffer) && (buffer != 0))
{
@@ -680,8 +710,8 @@ ALAPI ALvoid ALAPIENTRY alGetBufferf(ALuint buffer, ALenum eParam, ALfloat *pflV
{
ALCcontext *pContext;
pContext = alcGetCurrentContext();
SuspendContext(pContext);
pContext = GetContextSuspended();
if(!pContext) return;
if (pflValue)
{
@@ -712,8 +742,8 @@ ALAPI void ALAPIENTRY alGetBuffer3f(ALuint buffer, ALenum eParam, ALfloat* pflVa
{
ALCcontext *pContext;
pContext = alcGetCurrentContext();
SuspendContext(pContext);
pContext = GetContextSuspended();
if(!pContext) return;
if ((pflValue1) && (pflValue2) && (pflValue3))
{
@@ -744,8 +774,8 @@ ALAPI void ALAPIENTRY alGetBufferfv(ALuint buffer, ALenum eParam, ALfloat* pflVa
{
ALCcontext *pContext;
pContext = alcGetCurrentContext();
SuspendContext(pContext);
pContext = GetContextSuspended();
if(!pContext) return;
if (pflValues)
{
@@ -777,8 +807,8 @@ ALAPI ALvoid ALAPIENTRY alGetBufferi(ALuint buffer, ALenum eParam, ALint *plValu
ALCcontext *pContext;
ALbuffer *pBuffer;
pContext = alcGetCurrentContext();
SuspendContext(pContext);
pContext = GetContextSuspended();
if(!pContext) return;
if (plValue)
{
@@ -827,8 +857,8 @@ ALAPI void ALAPIENTRY alGetBuffer3i(ALuint buffer, ALenum eParam, ALint* plValue
{
ALCcontext *pContext;
pContext = alcGetCurrentContext();
SuspendContext(pContext);
pContext = GetContextSuspended();
if(!pContext) return;
if ((plValue1) && (plValue2) && (plValue3))
{
@@ -859,8 +889,8 @@ ALAPI void ALAPIENTRY alGetBufferiv(ALuint buffer, ALenum eParam, ALint* plValue
{
ALCcontext *pContext;
pContext = alcGetCurrentContext();
SuspendContext(pContext);
pContext = GetContextSuspended();
if(!pContext) return;
if (plValues)
{
@@ -897,19 +927,19 @@ ALAPI void ALAPIENTRY alGetBufferiv(ALuint buffer, ALenum eParam, ALint* plValue
* LoadData
*
* Loads the specified data into the buffer, using the specified formats.
* Currently, the new format must be 16-bit, and must have the same channel
* configuration as the original format. This does NOT handle compressed
* formats (eg. IMA4).
* Currently, the new format must be 32-bit float, and must have the same
* channel configuration as the original format. This does NOT handle
* compressed formats (eg. IMA4).
*/
static void LoadData(ALbuffer *ALBuf, const ALubyte *data, ALsizei size, ALuint freq, ALenum OrigFormat, ALenum NewFormat)
{
ALuint NewBytes = aluBytesFromFormat(NewFormat);
ALuint NewChannels = aluChannelsFromFormat(NewFormat);
ALuint OrigBytes = aluBytesFromFormat(OrigFormat);
ALuint OrigChannels = aluChannelsFromFormat(OrigFormat);
ALsizei padding = 2;
ALvoid *temp;
assert(aluBytesFromFormat(NewFormat) == 2);
assert(NewBytes == 4);
assert(NewChannels == OrigChannels);
if ((size%(OrigBytes*OrigChannels)) != 0)
@@ -918,49 +948,48 @@ static void LoadData(ALbuffer *ALBuf, const ALubyte *data, ALsizei size, ALuint
return;
}
// Samples are converted to 16 bit here
// Samples are converted here
size /= OrigBytes;
temp = realloc(ALBuf->data, (padding*NewChannels + size) * sizeof(ALshort));
temp = realloc(ALBuf->data, (BUFFER_PADDING*NewChannels + size) * NewBytes);
if(temp)
{
ALBuf->data = temp;
ConvertData(ALBuf->data, data, OrigBytes, size);
memset(&(ALBuf->data[size]), 0, padding*NewChannels*sizeof(ALshort));
ALBuf->format = NewFormat;
ALBuf->eOriginalFormat = OrigFormat;
ALBuf->size = size*sizeof(ALshort);
ALBuf->size = size*NewBytes;
ALBuf->frequency = freq;
ALBuf->padding = padding;
}
else
alSetError(AL_OUT_OF_MEMORY);
}
static void ConvertData(ALshort *dst, const ALvoid *src, ALint origBytes, ALsizei len)
static void ConvertData(ALfloat *dst, const ALvoid *src, ALint origBytes, ALsizei len)
{
ALsizei i;
ALint smp;
switch(origBytes)
{
case 1:
for(i = 0;i < len;i++)
dst[i] = ((ALshort)((ALubyte*)src)[i] - 128) << 8;
{
smp = ((ALubyte*)src)[i];
dst[i] = ((smp < 0x80) ? ((smp-128)/128.0f) : ((smp-128)/127.0f));
}
break;
case 2:
memcpy(dst, src, len*sizeof(ALshort));
for(i = 0;i < len;i++)
{
smp = ((ALshort*)src)[i];
dst[i] = ((smp < 0) ? (smp/32768.0f) : (smp/32767.0f));
}
break;
case 4:
for(i = 0;i < len;i++)
{
ALint smp;
smp = (((ALfloat*)src)[i] * 32767.5f - 0.5f);
smp = min(smp, 32767);
smp = max(smp, -32768);
dst[i] = (ALshort)smp;
}
dst[i] = ((ALfloat*)src)[i];
break;
default:
@@ -968,9 +997,10 @@ static void ConvertData(ALshort *dst, const ALvoid *src, ALint origBytes, ALsize
}
}
static void ConvertDataRear(ALshort *dst, const ALvoid *src, ALint origBytes, ALsizei len)
static void ConvertDataRear(ALfloat *dst, const ALvoid *src, ALint origBytes, ALsizei len)
{
ALsizei i;
ALint smp;
switch(origBytes)
{
case 1:
@@ -978,8 +1008,10 @@ static void ConvertDataRear(ALshort *dst, const ALvoid *src, ALint origBytes, AL
{
dst[i+0] = 0;
dst[i+1] = 0;
dst[i+2] = ((ALshort)((ALubyte*)src)[i/2+0] - 128) << 8;
dst[i+3] = ((ALshort)((ALubyte*)src)[i/2+1] - 128) << 8;
smp = ((ALubyte*)src)[i/2+0];
dst[i+2] = ((smp < 0x80) ? ((smp-128)/128.0f) : ((smp-128)/127.0f));
smp = ((ALubyte*)src)[i/2+1];
dst[i+3] = ((smp < 0x80) ? ((smp-128)/128.0f) : ((smp-128)/127.0f));
}
break;
@@ -988,25 +1020,20 @@ static void ConvertDataRear(ALshort *dst, const ALvoid *src, ALint origBytes, AL
{
dst[i+0] = 0;
dst[i+1] = 0;
dst[i+2] = ((ALshort*)src)[i/2+0];
dst[i+3] = ((ALshort*)src)[i/2+1];
smp = ((ALshort*)src)[i/2+0];
dst[i+2] = ((smp < 0) ? (smp/32768.0f) : (smp/32767.0f));
smp = ((ALshort*)src)[i/2+1];
dst[i+3] = ((smp < 0) ? (smp/32768.0f) : (smp/32767.0f));
}
break;
case 4:
for(i = 0;i < len;i+=4)
{
ALint smp;
dst[i+0] = 0;
dst[i+1] = 0;
smp = (((ALfloat*)src)[i/2+0] * 32767.5f - 0.5);
smp = min(smp, 32767);
smp = max(smp, -32768);
dst[i+2] = (ALshort)smp;
smp = (((ALfloat*)src)[i/2+1] * 32767.5f - 0.5);
smp = min(smp, 32767);
smp = max(smp, -32768);
dst[i+3] = (ALshort)smp;
dst[i+2] = ((ALfloat*)src)[i/2+0];
dst[i+3] = ((ALfloat*)src)[i/2+1];
}
break;
@@ -1015,7 +1042,7 @@ static void ConvertDataRear(ALshort *dst, const ALvoid *src, ALint origBytes, AL
}
}
static void ConvertDataIMA4(ALshort *dst, const ALvoid *src, ALint origChans, ALsizei len)
static void ConvertDataIMA4(ALfloat *dst, const ALvoid *src, ALint origChans, ALsizei len)
{
const ALuint *IMAData;
ALint Sample[2],Index[2];
@@ -1035,7 +1062,7 @@ static void ConvertDataIMA4(ALshort *dst, const ALvoid *src, ALint origChans, AL
Index[c] = ((Index[c]<0) ? 0 : Index[c]);
Index[c] = ((Index[c]>88) ? 88 : Index[c]);
dst[i*65*origChans + c] = (ALshort)Sample[c];
dst[i*65*origChans + c] = ((Sample[c] < 0) ? (Sample[c]/32768.0f) : (Sample[c]/32767.0f));
IMAData++;
}
@@ -1058,7 +1085,7 @@ static void ConvertDataIMA4(ALshort *dst, const ALvoid *src, ALint origChans, AL
if(Index[c]<0) Index[c] = 0;
else if(Index[c]>88) Index[c] = 88;
dst[(i*65+j+k)*origChans + c] = (ALshort)Sample[c];
dst[(i*65+j+k)*origChans + c] = ((Sample[c] < 0) ? (Sample[c]/32768.0f) : (Sample[c]/32767.0f));
IMACode[c] >>= 4;
}
}
@@ -1071,17 +1098,12 @@ static void ConvertDataIMA4(ALshort *dst, const ALvoid *src, ALint origChans, AL
*
* INTERNAL FN : Called by DLLMain on exit to destroy any buffers that still exist
*/
ALvoid ReleaseALBuffers(ALvoid)
ALvoid ReleaseALBuffers(ALCdevice *device)
{
ALbuffer *ALBuffer;
ALbuffer *ALBufferTemp;
#ifdef _DEBUG
if(g_uiBufferCount > 0)
AL_PRINT("exit(): deleting %d Buffer(s)\n", g_uiBufferCount);
#endif
ALBuffer = g_pBuffers;
ALBuffer = device->Buffers;
while(ALBuffer)
{
// Release sample data
@@ -1093,6 +1115,6 @@ ALvoid ReleaseALBuffers(ALvoid)
memset(ALBufferTemp, 0, sizeof(ALbuffer));
free(ALBufferTemp);
}
g_pBuffers = NULL;
g_uiBufferCount = 0;
device->Buffers = NULL;
device->BufferCount = 0;
}
+636
View File
@@ -0,0 +1,636 @@
/**
* 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 <assert.h>
#include "alMain.h"
#include "AL/al.h"
#include "AL/alc.h"
#include "AL/alext.h"
#include "alError.h"
#include "alDatabuffer.h"
#include "alThunk.h"
/*
* alGenDatabuffersEXT(ALsizei n, ALuint *puiBuffers)
*
* Generates n AL Databuffers, and stores the Databuffers Names in the array pointed to by puiBuffers
*/
ALvoid ALAPIENTRY alGenDatabuffersEXT(ALsizei n,ALuint *puiBuffers)
{
ALCcontext *Context;
ALsizei i=0;
Context = GetContextSuspended();
if(!Context) return;
/* Check that we are actually generation some Databuffers */
if(n > 0)
{
ALCdevice *device = Context->Device;
/* Check the pointer is valid (and points to enough memory to store
* Databuffer Names) */
if(!IsBadWritePtr((void*)puiBuffers, n * sizeof(ALuint)))
{
ALdatabuffer **list = &device->Databuffers;
while(*list)
list = &(*list)->next;
/* Create all the new Databuffers */
while(i < n)
{
*list = calloc(1, sizeof(ALdatabuffer));
if(!(*list))
{
alDeleteDatabuffersEXT(i, puiBuffers);
alSetError(AL_OUT_OF_MEMORY);
break;
}
puiBuffers[i] = (ALuint)ALTHUNK_ADDENTRY(*list);
(*list)->databuffer = puiBuffers[i];
(*list)->state = UNMAPPED;
device->DatabufferCount++;
i++;
list = &(*list)->next;
}
}
else
alSetError(AL_INVALID_VALUE);
}
ProcessContext(Context);
}
/*
* alDatabeleteBuffersEXT(ALsizei n, ALuint *puiBuffers)
*
* Deletes the n AL Databuffers pointed to by puiBuffers
*/
ALvoid ALAPIENTRY alDeleteDatabuffersEXT(ALsizei n, const ALuint *puiBuffers)
{
ALCcontext *Context;
ALdatabuffer *ALBuf;
ALsizei i;
ALboolean bFailed = AL_FALSE;
Context = GetContextSuspended();
if(!Context) return;
/* Check we are actually Deleting some Databuffers */
if(n >= 0)
{
ALCdevice *device = Context->Device;
/* Check that all the databuffers are valid and can actually be
* deleted */
for(i = 0;i < n;i++)
{
/* Check for valid Buffer ID (can be NULL buffer) */
if(alIsDatabufferEXT(puiBuffers[i]))
{
/* If not the NULL buffer, check that it's unmapped */
ALBuf = ((ALdatabuffer *)ALTHUNK_LOOKUPENTRY(puiBuffers[i]));
if(ALBuf)
{
if(ALBuf->state != UNMAPPED)
{
/* Databuffer still in use, cannot be deleted */
alSetError(AL_INVALID_OPERATION);
bFailed = AL_TRUE;
}
}
}
else
{
/* Invalid Databuffer */
alSetError(AL_INVALID_NAME);
bFailed = AL_TRUE;
}
}
/* If all the Databuffers were valid (and unmapped), then we can
* delete them */
if(!bFailed)
{
for(i = 0;i < n;i++)
{
if(puiBuffers[i] && alIsDatabufferEXT(puiBuffers[i]))
{
ALdatabuffer **list = &device->Databuffers;
ALBuf = (ALdatabuffer*)ALTHUNK_LOOKUPENTRY(puiBuffers[i]);
while(*list && *list != ALBuf)
list = &(*list)->next;
if(*list)
*list = (*list)->next;
if(ALBuf == Context->SampleSource)
Context->SampleSource = NULL;
if(ALBuf == Context->SampleSink)
Context->SampleSink = NULL;
// Release the memory used to store audio data
free(ALBuf->data);
// Release buffer structure
ALTHUNK_REMOVEENTRY(puiBuffers[i]);
memset(ALBuf, 0, sizeof(ALdatabuffer));
device->DatabufferCount--;
free(ALBuf);
}
}
}
}
else
alSetError(AL_INVALID_VALUE);
ProcessContext(Context);
}
/*
* alIsDatabufferEXT(ALuint uiBuffer)
*
* Checks if ulBuffer is a valid Databuffer Name
*/
ALboolean ALAPIENTRY alIsDatabufferEXT(ALuint uiBuffer)
{
ALCcontext *Context;
ALdatabuffer *ALBuf;
Context = GetContextSuspended();
if(!Context) return AL_FALSE;
/* Check through list of generated databuffers for uiBuffer */
ALBuf = Context->Device->Databuffers;
while(ALBuf && ALBuf->databuffer != uiBuffer)
ALBuf = ALBuf->next;
ProcessContext(Context);
return ((ALBuf || !uiBuffer) ? AL_TRUE : AL_FALSE);
}
/*
* alDatabufferDataEXT(ALuint buffer,ALvoid *data,ALsizei size,ALenum usage)
*
* Fill databuffer with data
*/
ALvoid ALAPIENTRY alDatabufferDataEXT(ALuint buffer,const ALvoid *data,ALsizei size,ALenum usage)
{
ALCcontext *Context;
ALdatabuffer *ALBuf;
ALvoid *temp;
Context = GetContextSuspended();
if(!Context) return;
if(alIsDatabufferEXT(buffer) && buffer != 0)
{
ALBuf = (ALdatabuffer*)ALTHUNK_LOOKUPENTRY(buffer);
if(ALBuf->state == UNMAPPED)
{
if(usage == AL_STREAM_WRITE_EXT || usage == AL_STREAM_READ_EXT ||
usage == AL_STREAM_COPY_EXT || usage == AL_STATIC_WRITE_EXT ||
usage == AL_STATIC_READ_EXT || usage == AL_STATIC_COPY_EXT ||
usage == AL_DYNAMIC_WRITE_EXT || usage == AL_DYNAMIC_READ_EXT ||
usage == AL_DYNAMIC_COPY_EXT)
{
/* (Re)allocate data */
temp = realloc(ALBuf->data, size);
if(temp)
{
ALBuf->data = temp;
ALBuf->size = size;
ALBuf->usage = usage;
if(data)
memcpy(ALBuf->data, data, size);
}
else
alSetError(AL_OUT_OF_MEMORY);
}
else
alSetError(AL_INVALID_ENUM);
}
else
alSetError(AL_INVALID_OPERATION);
}
else
alSetError(AL_INVALID_NAME);
ProcessContext(Context);
}
ALvoid ALAPIENTRY alDatabufferSubDataEXT(ALuint uiBuffer, ALuint start, ALsizei length, const ALvoid *data)
{
ALCcontext *pContext;
ALdatabuffer *pBuffer;
pContext = GetContextSuspended();
if(!pContext) return;
if(alIsDatabufferEXT(uiBuffer) && uiBuffer != 0)
{
pBuffer = (ALdatabuffer*)ALTHUNK_LOOKUPENTRY(uiBuffer);
if(length >= 0 && start+length <= pBuffer->size)
{
if(pBuffer->state == UNMAPPED)
memcpy(pBuffer->data+start, data, length);
else
alSetError(AL_INVALID_OPERATION);
}
else
alSetError(AL_INVALID_VALUE);
}
else
alSetError(AL_INVALID_NAME);
ProcessContext(pContext);
}
ALvoid ALAPIENTRY alGetDatabufferSubDataEXT(ALuint uiBuffer, ALuint start, ALsizei length, ALvoid *data)
{
ALCcontext *pContext;
ALdatabuffer *pBuffer;
pContext = GetContextSuspended();
if(!pContext) return;
if(alIsDatabufferEXT(uiBuffer) && uiBuffer != 0)
{
pBuffer = (ALdatabuffer*)ALTHUNK_LOOKUPENTRY(uiBuffer);
if(length >= 0 && start+length <= pBuffer->size)
{
if(pBuffer->state == UNMAPPED)
memcpy(data, pBuffer->data+start, length);
else
alSetError(AL_INVALID_OPERATION);
}
else
alSetError(AL_INVALID_VALUE);
}
else
alSetError(AL_INVALID_NAME);
ProcessContext(pContext);
}
ALvoid ALAPIENTRY alDatabufferfEXT(ALuint buffer, ALenum eParam, ALfloat flValue)
{
ALCcontext *pContext;
(void)flValue;
pContext = GetContextSuspended();
if(!pContext) return;
if(alIsDatabufferEXT(buffer) && buffer != 0)
{
switch(eParam)
{
default:
alSetError(AL_INVALID_ENUM);
break;
}
}
else
alSetError(AL_INVALID_NAME);
ProcessContext(pContext);
}
ALvoid ALAPIENTRY alDatabufferfvEXT(ALuint buffer, ALenum eParam, const ALfloat* flValues)
{
ALCcontext *pContext;
(void)flValues;
pContext = GetContextSuspended();
if(!pContext) return;
if(alIsDatabufferEXT(buffer) && buffer != 0)
{
switch(eParam)
{
default:
alSetError(AL_INVALID_ENUM);
break;
}
}
else
alSetError(AL_INVALID_NAME);
ProcessContext(pContext);
}
ALvoid ALAPIENTRY alDatabufferiEXT(ALuint buffer, ALenum eParam, ALint lValue)
{
ALCcontext *pContext;
(void)lValue;
pContext = GetContextSuspended();
if(!pContext) return;
if(alIsDatabufferEXT(buffer) && buffer != 0)
{
switch(eParam)
{
default:
alSetError(AL_INVALID_ENUM);
break;
}
}
else
alSetError(AL_INVALID_NAME);
ProcessContext(pContext);
}
ALvoid ALAPIENTRY alDatabufferivEXT(ALuint buffer, ALenum eParam, const ALint* plValues)
{
ALCcontext *pContext;
(void)plValues;
pContext = GetContextSuspended();
if(!pContext) return;
if(alIsDatabufferEXT(buffer) && buffer != 0)
{
switch(eParam)
{
default:
alSetError(AL_INVALID_ENUM);
break;
}
}
else
alSetError(AL_INVALID_NAME);
ProcessContext(pContext);
}
ALvoid ALAPIENTRY alGetDatabufferfEXT(ALuint buffer, ALenum eParam, ALfloat *pflValue)
{
ALCcontext *pContext;
pContext = GetContextSuspended();
if(!pContext) return;
if(pflValue)
{
if(alIsDatabufferEXT(buffer) && buffer != 0)
{
switch(eParam)
{
default:
alSetError(AL_INVALID_ENUM);
break;
}
}
else
alSetError(AL_INVALID_NAME);
}
else
alSetError(AL_INVALID_VALUE);
ProcessContext(pContext);
}
ALvoid ALAPIENTRY alGetDatabufferfvEXT(ALuint buffer, ALenum eParam, ALfloat* pflValues)
{
ALCcontext *pContext;
pContext = GetContextSuspended();
if(!pContext) return;
if(pflValues)
{
if(alIsDatabufferEXT(buffer) && buffer != 0)
{
switch(eParam)
{
default:
alSetError(AL_INVALID_ENUM);
break;
}
}
else
alSetError(AL_INVALID_NAME);
}
else
alSetError(AL_INVALID_VALUE);
ProcessContext(pContext);
}
ALvoid ALAPIENTRY alGetDatabufferiEXT(ALuint buffer, ALenum eParam, ALint *plValue)
{
ALCcontext *pContext;
ALdatabuffer *pBuffer;
pContext = GetContextSuspended();
if(!pContext) return;
if(plValue)
{
if(alIsDatabufferEXT(buffer) && buffer != 0)
{
pBuffer = (ALdatabuffer*)ALTHUNK_LOOKUPENTRY(buffer);
switch(eParam)
{
case AL_SIZE:
*plValue = pBuffer->size;
break;
default:
alSetError(AL_INVALID_ENUM);
break;
}
}
else
alSetError(AL_INVALID_NAME);
}
else
alSetError(AL_INVALID_VALUE);
ProcessContext(pContext);
}
ALvoid ALAPIENTRY alGetDatabufferivEXT(ALuint buffer, ALenum eParam, ALint* plValues)
{
ALCcontext *pContext;
pContext = GetContextSuspended();
if(!pContext) return;
if(plValues)
{
if(alIsDatabufferEXT(buffer) && buffer != 0)
{
switch (eParam)
{
case AL_SIZE:
alGetDatabufferiEXT(buffer, eParam, plValues);
break;
default:
alSetError(AL_INVALID_ENUM);
break;
}
}
else
alSetError(AL_INVALID_NAME);
}
else
alSetError(AL_INVALID_VALUE);
ProcessContext(pContext);
}
ALvoid ALAPIENTRY alSelectDatabufferEXT(ALenum target, ALuint uiBuffer)
{
ALCcontext *pContext;
ALdatabuffer *pBuffer;
pContext = GetContextSuspended();
if(!pContext) return;
if(alIsDatabufferEXT(uiBuffer))
{
pBuffer = (ALdatabuffer*)(uiBuffer ? ALTHUNK_LOOKUPENTRY(uiBuffer) : NULL);
if(target == AL_SAMPLE_SOURCE_EXT)
pContext->SampleSource = pBuffer;
else if(target == AL_SAMPLE_SINK_EXT)
pContext->SampleSink = pBuffer;
else
alSetError(AL_INVALID_VALUE);
}
else
alSetError(AL_INVALID_NAME);
ProcessContext(pContext);
}
ALvoid* ALAPIENTRY alMapDatabufferEXT(ALuint uiBuffer, ALuint start, ALsizei length, ALenum access)
{
ALCcontext *pContext;
ALdatabuffer *pBuffer;
ALvoid *ret = NULL;
pContext = GetContextSuspended();
if(!pContext) return NULL;
if(alIsDatabufferEXT(uiBuffer) && uiBuffer != 0)
{
pBuffer = (ALdatabuffer*)ALTHUNK_LOOKUPENTRY(uiBuffer);
if(length >= 0 && start+length <= pBuffer->size)
{
if(access == AL_READ_ONLY_EXT || access == AL_WRITE_ONLY_EXT ||
access == AL_READ_WRITE_EXT)
{
if(pBuffer->state == UNMAPPED)
{
ret = pBuffer->data + start;
pBuffer->state = MAPPED;
}
else
alSetError(AL_INVALID_OPERATION);
}
else
alSetError(AL_INVALID_ENUM);
}
else
alSetError(AL_INVALID_VALUE);
}
else
alSetError(AL_INVALID_NAME);
ProcessContext(pContext);
return ret;
}
ALvoid ALAPIENTRY alUnmapDatabufferEXT(ALuint uiBuffer)
{
ALCcontext *pContext;
ALdatabuffer *pBuffer;
pContext = GetContextSuspended();
if(!pContext) return;
if(alIsDatabufferEXT(uiBuffer) && uiBuffer != 0)
{
pBuffer = (ALdatabuffer*)ALTHUNK_LOOKUPENTRY(uiBuffer);
if(pBuffer->state == MAPPED)
pBuffer->state = UNMAPPED;
else
alSetError(AL_INVALID_OPERATION);
}
else
alSetError(AL_INVALID_NAME);
ProcessContext(pContext);
}
/*
* ReleaseALDatabuffers()
*
* INTERNAL FN : Called by DLLMain on exit to destroy any buffers that still exist
*/
ALvoid ReleaseALDatabuffers(ALCdevice *device)
{
ALdatabuffer *ALBuffer;
ALdatabuffer *ALBufferTemp;
ALBuffer = device->Databuffers;
while(ALBuffer)
{
// Release sample data
free(ALBuffer->data);
// Release Buffer structure
ALBufferTemp = ALBuffer;
ALBuffer = ALBuffer->next;
memset(ALBufferTemp, 0, sizeof(ALdatabuffer));
free(ALBufferTemp);
}
device->Databuffers = NULL;
device->DatabufferCount = 0;
}
+669 -77
View File
File diff suppressed because it is too large Load Diff
+16 -21
View File
@@ -26,34 +26,29 @@
ALAPI ALenum ALAPIENTRY alGetError(ALvoid)
{
ALCcontext *Context;
ALenum errorCode;
ALCcontext *Context;
ALenum errorCode;
Context = alcGetCurrentContext();
SuspendContext(Context);
Context = GetContextSuspended();
if(!Context) return AL_INVALID_OPERATION;
if (Context)
{
errorCode = Context->LastError;
Context->LastError = AL_NO_ERROR;
}
else
errorCode = AL_INVALID_OPERATION;
errorCode = Context->LastError;
Context->LastError = AL_NO_ERROR;
ProcessContext(Context);
ProcessContext(Context);
return errorCode;
return errorCode;
}
ALvoid alSetError(ALenum errorCode)
{
ALCcontext *Context;
ALCcontext *Context;
Context=alcGetCurrentContext();
SuspendContext(Context);
if (Context && Context->LastError == AL_NO_ERROR)
Context->LastError = errorCode;
ProcessContext(Context);
Context = GetContextSuspended();
if(Context)
{
if(Context->LastError == AL_NO_ERROR)
Context->LastError = errorCode;
ProcessContext(Context);
}
}
+21 -8
View File
@@ -29,6 +29,7 @@
#include "alFilter.h"
#include "alEffect.h"
#include "alAuxEffectSlot.h"
#include "alDatabuffer.h"
#include "alSource.h"
#include "alBuffer.h"
#include "AL/al.h"
@@ -147,6 +148,24 @@ static ALfunction function[]= {
{ "alBufferSubDataEXT", (ALvoid *) alBufferSubDataEXT },
{ "alGenDatabuffersEXT", (ALvoid *) alGenDatabuffersEXT },
{ "alDeleteDatabuffersEXT", (ALvoid *) alDeleteDatabuffersEXT },
{ "alIsDatabufferEXT", (ALvoid *) alIsDatabufferEXT },
{ "alDatabufferDataEXT", (ALvoid *) alDatabufferDataEXT },
{ "alDatabufferSubDataEXT", (ALvoid *) alDatabufferSubDataEXT },
{ "alGetDatabufferSubDataEXT", (ALvoid *) alGetDatabufferSubDataEXT },
{ "alDatabufferfEXT", (ALvoid *) alDatabufferfEXT },
{ "alDatabufferfvEXT", (ALvoid *) alDatabufferfvEXT },
{ "alDatabufferiEXT", (ALvoid *) alDatabufferiEXT },
{ "alDatabufferivEXT", (ALvoid *) alDatabufferivEXT },
{ "alGetDatabufferfEXT", (ALvoid *) alGetDatabufferfEXT },
{ "alGetDatabufferfvEXT", (ALvoid *) alGetDatabufferfvEXT },
{ "alGetDatabufferiEXT", (ALvoid *) alGetDatabufferiEXT },
{ "alGetDatabufferivEXT", (ALvoid *) alGetDatabufferivEXT },
{ "alSelectDatabufferEXT", (ALvoid *) alSelectDatabufferEXT },
{ "alMapDatabufferEXT", (ALvoid *) alMapDatabufferEXT },
{ "alUnmapDatabufferEXT", (ALvoid *) alUnmapDatabufferEXT },
{ NULL, (ALvoid *) NULL } };
static ALenums enumeration[]={
@@ -333,14 +352,8 @@ ALAPI ALboolean ALAPIENTRY alIsExtensionPresent(const ALchar *extName)
return AL_FALSE;
}
pContext = alcGetCurrentContext();
if(!pContext)
{
alSetError(AL_INVALID_OPERATION);
return AL_FALSE;
}
SuspendContext(pContext);
pContext = GetContextSuspended();
if(!pContext) return AL_FALSE;
len = strlen(extName);
ptr = pContext->ExtensionList;
+42 -43
View File
@@ -29,8 +29,6 @@
#include "alThunk.h"
#include "alError.h"
static ALfilter *g_FilterList;
static ALuint g_FilterCount;
static void InitFilterParams(ALfilter *filter, ALenum type);
@@ -40,15 +38,17 @@ ALvoid AL_APIENTRY alGenFilters(ALsizei n, ALuint *filters)
ALCcontext *Context;
ALsizei i;
Context = alcGetCurrentContext();
SuspendContext(Context);
Context = GetContextSuspended();
if(!Context) return;
if (n > 0)
{
ALCdevice *device = Context->Device;
// Check that enough memory has been allocted in the 'filters' array for n Filters
if (!IsBadWritePtr((void*)filters, n * sizeof(ALuint)))
{
ALfilter **list = &g_FilterList;
ALfilter **list = &device->FilterList;
while(*list)
list = &(*list)->next;
@@ -68,7 +68,7 @@ ALvoid AL_APIENTRY alGenFilters(ALsizei n, ALuint *filters)
(*list)->filter = filters[i];
InitFilterParams(*list, AL_FILTER_NULL);
g_FilterCount++;
device->FilterCount++;
i++;
list = &(*list)->next;
@@ -85,11 +85,13 @@ ALvoid AL_APIENTRY alDeleteFilters(ALsizei n, ALuint *filters)
ALfilter *ALFilter;
ALsizei i;
Context = alcGetCurrentContext();
SuspendContext(Context);
Context = GetContextSuspended();
if(!Context) return;
if (n >= 0)
{
ALCdevice *device = Context->Device;
// Check that all filters are valid
for (i = 0; i < n; i++)
{
@@ -113,7 +115,7 @@ ALvoid AL_APIENTRY alDeleteFilters(ALsizei n, ALuint *filters)
ALFilter = ((ALfilter*)ALTHUNK_LOOKUPENTRY(filters[i]));
// Remove Source from list of Sources
list = &g_FilterList;
list = &device->FilterList;
while(*list && *list != ALFilter)
list = &(*list)->next;
@@ -124,7 +126,7 @@ ALvoid AL_APIENTRY alDeleteFilters(ALsizei n, ALuint *filters)
memset(ALFilter, 0, sizeof(ALfilter));
free(ALFilter);
g_FilterCount--;
device->FilterCount--;
}
}
}
@@ -138,26 +140,26 @@ ALvoid AL_APIENTRY alDeleteFilters(ALsizei n, ALuint *filters)
ALboolean AL_APIENTRY alIsFilter(ALuint filter)
{
ALCcontext *Context;
ALfilter **list;
ALfilter *list;
Context = alcGetCurrentContext();
SuspendContext(Context);
Context = GetContextSuspended();
if(!Context) return AL_FALSE;
list = &g_FilterList;
while(*list && (*list)->filter != filter)
list = &(*list)->next;
list = Context->Device->FilterList;
while(list && list->filter != filter)
list = list->next;
ProcessContext(Context);
return ((*list || !filter) ? AL_TRUE : AL_FALSE);
return ((list || !filter) ? AL_TRUE : AL_FALSE);
}
ALvoid AL_APIENTRY alFilteri(ALuint filter, ALenum param, ALint iValue)
{
ALCcontext *Context;
Context = alcGetCurrentContext();
SuspendContext(Context);
Context = GetContextSuspended();
if(!Context) return;
if (filter && alIsFilter(filter))
{
@@ -188,8 +190,8 @@ ALvoid AL_APIENTRY alFilteriv(ALuint filter, ALenum param, ALint *piValues)
{
ALCcontext *Context;
Context = alcGetCurrentContext();
SuspendContext(Context);
Context = GetContextSuspended();
if(!Context) return;
if (filter && alIsFilter(filter))
{
@@ -214,8 +216,8 @@ ALvoid AL_APIENTRY alFilterf(ALuint filter, ALenum param, ALfloat flValue)
{
ALCcontext *Context;
Context = alcGetCurrentContext();
SuspendContext(Context);
Context = GetContextSuspended();
if(!Context) return;
if (filter && alIsFilter(filter))
{
@@ -261,8 +263,8 @@ ALvoid AL_APIENTRY alFilterfv(ALuint filter, ALenum param, ALfloat *pflValues)
{
ALCcontext *Context;
Context = alcGetCurrentContext();
SuspendContext(Context);
Context = GetContextSuspended();
if(!Context) return;
if (filter && alIsFilter(filter))
{
@@ -283,8 +285,8 @@ ALvoid AL_APIENTRY alGetFilteri(ALuint filter, ALenum param, ALint *piValue)
{
ALCcontext *Context;
Context = alcGetCurrentContext();
SuspendContext(Context);
Context = GetContextSuspended();
if(!Context) return;
if (filter && alIsFilter(filter))
{
@@ -311,8 +313,8 @@ ALvoid AL_APIENTRY alGetFilteriv(ALuint filter, ALenum param, ALint *piValues)
{
ALCcontext *Context;
Context = alcGetCurrentContext();
SuspendContext(Context);
Context = GetContextSuspended();
if(!Context) return;
if (filter && alIsFilter(filter))
{
@@ -337,8 +339,8 @@ ALvoid AL_APIENTRY alGetFilterf(ALuint filter, ALenum param, ALfloat *pflValue)
{
ALCcontext *Context;
Context = alcGetCurrentContext();
SuspendContext(Context);
Context = GetContextSuspended();
if(!Context) return;
if (filter && alIsFilter(filter))
{
@@ -378,8 +380,8 @@ ALvoid AL_APIENTRY alGetFilterfv(ALuint filter, ALenum param, ALfloat *pflValues
{
ALCcontext *Context;
Context = alcGetCurrentContext();
SuspendContext(Context);
Context = GetContextSuspended();
if(!Context) return;
if (filter && alIsFilter(filter))
{
@@ -397,23 +399,20 @@ ALvoid AL_APIENTRY alGetFilterfv(ALuint filter, ALenum param, ALfloat *pflValues
}
ALvoid ReleaseALFilters(ALvoid)
ALvoid ReleaseALFilters(ALCdevice *device)
{
#ifdef _DEBUG
if(g_FilterCount > 0)
AL_PRINT("exit(): deleting %d Filter(s)\n", g_FilterCount);
#endif
while(g_FilterList)
ALfilter *list = device->FilterList;
while(list)
{
ALfilter *temp = g_FilterList;
g_FilterList = g_FilterList->next;
ALfilter *temp = list;
list = list->next;
// Release filter structure
memset(temp, 0, sizeof(ALfilter));
free(temp);
}
g_FilterCount = 0;
device->FilterList = NULL;
device->FilterCount = 0;
}
+127 -180
View File
@@ -24,28 +24,34 @@
#include "AL/alc.h"
#include "alError.h"
#include "alListener.h"
#include "alSource.h"
ALAPI ALvoid ALAPIENTRY alListenerf(ALenum eParam, ALfloat flValue)
{
ALCcontext *pContext;
ALboolean updateAll = AL_FALSE;
pContext = alcGetCurrentContext();
if (pContext)
pContext = GetContextSuspended();
if(!pContext) return;
switch(eParam)
{
SuspendContext(pContext);
switch (eParam)
{
case AL_GAIN:
if (flValue >= 0.0f)
if(flValue >= 0.0f)
{
pContext->Listener.Gain = flValue;
updateAll = AL_TRUE;
}
else
alSetError(AL_INVALID_VALUE);
break;
case AL_METERS_PER_UNIT:
if (flValue > 0.0f)
if(flValue > 0.0f)
{
pContext->Listener.MetersPerUnit = flValue;
updateAll = AL_TRUE;
}
else
alSetError(AL_INVALID_VALUE);
break;
@@ -53,91 +59,88 @@ ALAPI ALvoid ALAPIENTRY alListenerf(ALenum eParam, ALfloat flValue)
default:
alSetError(AL_INVALID_ENUM);
break;
}
ProcessContext(pContext);
}
else
alSetError(AL_INVALID_OPERATION);
return;
// Force updating the sources for these parameters, since even head-
// relative sources are affected
if(updateAll)
{
ALsource *source = pContext->Source;
while(source)
{
source->NeedsUpdate = AL_TRUE;
source = source->next;
}
}
ProcessContext(pContext);
}
ALAPI ALvoid ALAPIENTRY alListener3f(ALenum eParam, ALfloat flValue1, ALfloat flValue2, ALfloat flValue3)
{
ALCcontext *pContext;
ALboolean updateWorld = AL_FALSE;
pContext = alcGetCurrentContext();
if (pContext)
pContext = GetContextSuspended();
if(!pContext) return;
switch(eParam)
{
SuspendContext(pContext);
switch(eParam)
{
case AL_POSITION:
pContext->Listener.Position[0] = flValue1;
pContext->Listener.Position[1] = flValue2;
pContext->Listener.Position[2] = flValue3;
updateWorld = AL_TRUE;
break;
case AL_VELOCITY:
pContext->Listener.Velocity[0] = flValue1;
pContext->Listener.Velocity[1] = flValue2;
pContext->Listener.Velocity[2] = flValue3;
updateWorld = AL_TRUE;
break;
default:
alSetError(AL_INVALID_ENUM);
break;
}
ProcessContext(pContext);
}
else
alSetError(AL_INVALID_OPERATION);
return;
if(updateWorld)
{
ALsource *source = pContext->Source;
while(source)
{
if(!source->bHeadRelative)
source->NeedsUpdate = AL_TRUE;
source = source->next;
}
}
ProcessContext(pContext);
}
ALAPI ALvoid ALAPIENTRY alListenerfv(ALenum eParam, const ALfloat *pflValues)
{
ALCcontext *pContext;
ALboolean updateWorld = AL_FALSE;
pContext = alcGetCurrentContext();
if (pContext)
pContext = GetContextSuspended();
if(!pContext) return;
if(pflValues)
{
SuspendContext(pContext);
if (pflValues)
switch(eParam)
{
switch (eParam)
{
case AL_GAIN:
if (pflValues[0] >= 0.0f)
pContext->Listener.Gain = pflValues[0];
else
alSetError(AL_INVALID_VALUE);
break;
case AL_METERS_PER_UNIT:
if (pflValues[0] > 0.0f)
pContext->Listener.MetersPerUnit = pflValues[0];
else
alSetError(AL_INVALID_VALUE);
alListenerf(eParam, pflValues[0]);
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];
alListener3f(eParam, pflValues[0], pflValues[1], pflValues[2]);
break;
case AL_ORIENTATION:
@@ -148,22 +151,29 @@ ALAPI ALvoid ALAPIENTRY alListenerfv(ALenum eParam, const ALfloat *pflValues)
pContext->Listener.Up[0] = pflValues[3];
pContext->Listener.Up[1] = pflValues[4];
pContext->Listener.Up[2] = pflValues[5];
updateWorld = AL_TRUE;
break;
default:
alSetError(AL_INVALID_ENUM);
break;
}
}
else
alSetError(AL_INVALID_VALUE);
ProcessContext(pContext);
}
else
alSetError(AL_INVALID_OPERATION);
alSetError(AL_INVALID_VALUE);
return;
if(updateWorld)
{
ALsource *source = pContext->Source;
while(source)
{
if(!source->bHeadRelative)
source->NeedsUpdate = AL_TRUE;
source = source->next;
}
}
ProcessContext(pContext);
}
@@ -173,24 +183,17 @@ ALAPI ALvoid ALAPIENTRY alListeneri(ALenum eParam, ALint lValue)
(void)lValue;
pContext = alcGetCurrentContext();
if (pContext)
{
SuspendContext(pContext);
pContext = GetContextSuspended();
if(!pContext) return;
switch (eParam)
{
switch(eParam)
{
default:
alSetError(AL_INVALID_ENUM);
break;
}
ProcessContext(pContext);
}
else
alSetError(AL_INVALID_OPERATION);
return;
ProcessContext(pContext);
}
@@ -198,13 +201,11 @@ ALAPI void ALAPIENTRY alListener3i(ALenum eParam, ALint lValue1, ALint lValue2,
{
ALCcontext *pContext;
pContext = alcGetCurrentContext();
if (pContext)
{
SuspendContext(pContext);
pContext = GetContextSuspended();
if(!pContext) return;
switch(eParam)
{
switch(eParam)
{
case AL_POSITION:
case AL_VELOCITY:
alListener3f(eParam, (ALfloat)lValue1, (ALfloat)lValue2, (ALfloat)lValue3);
@@ -213,14 +214,9 @@ ALAPI void ALAPIENTRY alListener3i(ALenum eParam, ALint lValue1, ALint lValue2,
default:
alSetError(AL_INVALID_ENUM);
break;
}
ProcessContext(pContext);
}
else
alSetError(AL_INVALID_OPERATION);
return;
ProcessContext(pContext);
}
@@ -229,15 +225,13 @@ ALAPI void ALAPIENTRY alListeneriv( ALenum eParam, const ALint* plValues )
ALCcontext *pContext;
ALfloat flValues[6];
pContext = alcGetCurrentContext();
if (pContext)
{
SuspendContext(pContext);
pContext = GetContextSuspended();
if(!pContext) return;
if (plValues)
if(plValues)
{
switch(eParam)
{
switch (eParam)
{
case AL_POSITION:
case AL_VELOCITY:
flValues[0] = (ALfloat)plValues[0];
@@ -259,17 +253,12 @@ ALAPI void ALAPIENTRY alListeneriv( ALenum eParam, const ALint* plValues )
default:
alSetError(AL_INVALID_ENUM);
break;
}
}
else
alSetError(AL_INVALID_VALUE);
ProcessContext(pContext);
}
else
alSetError(AL_INVALID_OPERATION);
alSetError(AL_INVALID_VALUE);
return;
ProcessContext(pContext);
}
@@ -277,15 +266,13 @@ ALAPI ALvoid ALAPIENTRY alGetListenerf(ALenum eParam, ALfloat *pflValue)
{
ALCcontext *pContext;
pContext = alcGetCurrentContext();
if (pContext)
{
SuspendContext(pContext);
pContext = GetContextSuspended();
if(!pContext) return;
if (pflValue)
if(pflValue)
{
switch(eParam)
{
switch (eParam)
{
case AL_GAIN:
*pflValue = pContext->Listener.Gain;
break;
@@ -297,17 +284,12 @@ ALAPI ALvoid ALAPIENTRY alGetListenerf(ALenum eParam, ALfloat *pflValue)
default:
alSetError(AL_INVALID_ENUM);
break;
}
}
else
alSetError(AL_INVALID_VALUE);
ProcessContext(pContext);
}
else
alSetError(AL_INVALID_OPERATION);
alSetError(AL_INVALID_VALUE);
return;
ProcessContext(pContext);
}
@@ -315,15 +297,13 @@ ALAPI ALvoid ALAPIENTRY alGetListener3f(ALenum eParam, ALfloat *pflValue1, ALflo
{
ALCcontext *pContext;
pContext = alcGetCurrentContext();
if (pContext)
{
SuspendContext(pContext);
pContext = GetContextSuspended();
if(!pContext) return;
if ((pflValue1) && (pflValue2) && (pflValue3))
if(pflValue1 && pflValue2 && pflValue3)
{
switch(eParam)
{
switch (eParam)
{
case AL_POSITION:
*pflValue1 = pContext->Listener.Position[0];
*pflValue2 = pContext->Listener.Position[1];
@@ -339,17 +319,12 @@ ALAPI ALvoid ALAPIENTRY alGetListener3f(ALenum eParam, ALfloat *pflValue1, ALflo
default:
alSetError(AL_INVALID_ENUM);
break;
}
}
else
alSetError(AL_INVALID_VALUE);
ProcessContext(pContext);
}
else
alSetError(AL_INVALID_OPERATION);
alSetError(AL_INVALID_VALUE);
return;
ProcessContext(pContext);
}
@@ -357,15 +332,13 @@ ALAPI ALvoid ALAPIENTRY alGetListenerfv(ALenum eParam, ALfloat *pflValues)
{
ALCcontext *pContext;
pContext = alcGetCurrentContext();
if (pContext)
{
SuspendContext(pContext);
pContext = GetContextSuspended();
if(!pContext) return;
if (pflValues)
if(pflValues)
{
switch(eParam)
{
switch (eParam)
{
case AL_GAIN:
pflValues[0] = pContext->Listener.Gain;
break;
@@ -399,17 +372,12 @@ ALAPI ALvoid ALAPIENTRY alGetListenerfv(ALenum eParam, ALfloat *pflValues)
default:
alSetError(AL_INVALID_ENUM);
break;
}
}
else
alSetError(AL_INVALID_VALUE);
ProcessContext(pContext);
}
else
alSetError(AL_INVALID_OPERATION);
alSetError(AL_INVALID_VALUE);
return;
ProcessContext(pContext);
}
@@ -417,29 +385,22 @@ ALAPI ALvoid ALAPIENTRY alGetListeneri(ALenum eParam, ALint *plValue)
{
ALCcontext *pContext;
pContext = alcGetCurrentContext();
if (pContext)
{
SuspendContext(pContext);
pContext = GetContextSuspended();
if(!pContext) return;
if (plValue)
if(plValue)
{
switch(eParam)
{
switch (eParam)
{
default:
alSetError(AL_INVALID_ENUM);
break;
}
}
else
alSetError(AL_INVALID_VALUE);
ProcessContext(pContext);
}
else
alSetError(AL_INVALID_OPERATION);
alSetError(AL_INVALID_VALUE);
return;
ProcessContext(pContext);
}
@@ -447,15 +408,13 @@ ALAPI void ALAPIENTRY alGetListener3i(ALenum eParam, ALint *plValue1, ALint *plV
{
ALCcontext *pContext;
pContext = alcGetCurrentContext();
if (pContext)
{
SuspendContext(pContext);
pContext = GetContextSuspended();
if(!pContext) return;
if ((plValue1) && (plValue2) && (plValue3))
if(plValue1 && plValue2 && plValue3)
{
switch (eParam)
{
switch (eParam)
{
case AL_POSITION:
*plValue1 = (ALint)pContext->Listener.Position[0];
*plValue2 = (ALint)pContext->Listener.Position[1];
@@ -471,17 +430,12 @@ ALAPI void ALAPIENTRY alGetListener3i(ALenum eParam, ALint *plValue1, ALint *plV
default:
alSetError(AL_INVALID_ENUM);
break;
}
}
else
alSetError(AL_INVALID_VALUE);
ProcessContext(pContext);
}
else
alSetError(AL_INVALID_OPERATION);
alSetError(AL_INVALID_VALUE);
return;
ProcessContext(pContext);
}
@@ -489,15 +443,13 @@ ALAPI void ALAPIENTRY alGetListeneriv(ALenum eParam, ALint* plValues)
{
ALCcontext *pContext;
pContext = alcGetCurrentContext();
if (pContext)
{
SuspendContext(pContext);
pContext = GetContextSuspended();
if(!pContext) return;
if (plValues)
if(plValues)
{
switch(eParam)
{
switch (eParam)
{
case AL_POSITION:
plValues[0] = (ALint)pContext->Listener.Position[0];
plValues[1] = (ALint)pContext->Listener.Position[1];
@@ -523,15 +475,10 @@ ALAPI void ALAPIENTRY alGetListeneriv(ALenum eParam, ALint* plValues)
default:
alSetError(AL_INVALID_ENUM);
break;
}
}
else
alSetError(AL_INVALID_VALUE);
ProcessContext(pContext);
}
else
alSetError(AL_INVALID_OPERATION);
alSetError(AL_INVALID_VALUE);
return;
ProcessContext(pContext);
}
+761 -942
View File
File diff suppressed because it is too large Load Diff
+347 -365
View File
@@ -23,8 +23,11 @@
#include <stdlib.h>
#include "alMain.h"
#include "AL/alc.h"
#include "AL/alext.h"
#include "alError.h"
#include "alSource.h"
#include "alState.h"
#include "alDatabuffer.h"
static const ALchar alVendor[] = "OpenAL Community";
static const ALchar alVersion[] = "1.1 ALSOFT "ALSOFT_VERSION;
@@ -41,51 +44,67 @@ static const ALchar alErrOutOfMemory[] = "Out of Memory";
ALAPI ALvoid ALAPIENTRY alEnable(ALenum capability)
{
ALCcontext *Context;
ALboolean updateSources = AL_FALSE;
Context=alcGetCurrentContext();
if (Context)
Context = GetContextSuspended();
if(!Context) return;
switch(capability)
{
SuspendContext(Context);
case AL_SOURCE_DISTANCE_MODEL:
Context->SourceDistanceModel = AL_TRUE;
updateSources = AL_TRUE;
break;
switch (capability)
default:
alSetError(AL_INVALID_ENUM);
break;
}
if(updateSources)
{
ALsource *source = Context->Source;
while(source)
{
default:
alSetError(AL_INVALID_ENUM);
break;
source->NeedsUpdate = AL_TRUE;
source = source->next;
}
}
ProcessContext(Context);
}
else
{
// Invalid Context
alSetError(AL_INVALID_OPERATION);
}
ProcessContext(Context);
}
ALAPI ALvoid ALAPIENTRY alDisable(ALenum capability)
{
ALCcontext *Context;
ALboolean updateSources = AL_FALSE;
Context=alcGetCurrentContext();
if (Context)
Context = GetContextSuspended();
if(!Context) return;
switch(capability)
{
SuspendContext(Context);
case AL_SOURCE_DISTANCE_MODEL:
Context->SourceDistanceModel = AL_FALSE;
updateSources = AL_TRUE;
break;
switch (capability)
default:
alSetError(AL_INVALID_ENUM);
break;
}
if(updateSources)
{
ALsource *source = Context->Source;
while(source)
{
default:
alSetError(AL_INVALID_ENUM);
break;
source->NeedsUpdate = AL_TRUE;
source = source->next;
}
}
ProcessContext(Context);
}
else
{
// Invalid Context
alSetError(AL_INVALID_OPERATION);
}
ProcessContext(Context);
}
ALAPI ALboolean ALAPIENTRY alIsEnabled(ALenum capability)
@@ -93,26 +112,22 @@ ALAPI ALboolean ALAPIENTRY alIsEnabled(ALenum capability)
ALCcontext *Context;
ALboolean value=AL_FALSE;
Context=alcGetCurrentContext();
if (Context)
{
SuspendContext(Context);
Context = GetContextSuspended();
if(!Context) return AL_FALSE;
switch (capability)
{
default:
alSetError(AL_INVALID_ENUM);
break;
}
ProcessContext(Context);
}
else
switch(capability)
{
// Invalid Context
alSetError(AL_INVALID_OPERATION);
case AL_SOURCE_DISTANCE_MODEL:
value = Context->SourceDistanceModel;
break;
default:
alSetError(AL_INVALID_ENUM);
break;
}
ProcessContext(Context);
return value;
}
@@ -121,46 +136,38 @@ ALAPI ALboolean ALAPIENTRY alGetBoolean(ALenum pname)
ALCcontext *Context;
ALboolean value=AL_FALSE;
Context=alcGetCurrentContext();
if (Context)
Context = GetContextSuspended();
if(!Context) return AL_FALSE;
switch(pname)
{
SuspendContext(Context);
case AL_DOPPLER_FACTOR:
if(Context->DopplerFactor != 0.0f)
value = AL_TRUE;
break;
switch (pname)
{
case AL_DOPPLER_FACTOR:
if (Context->DopplerFactor != 0.0f)
value = AL_TRUE;
break;
case AL_DOPPLER_VELOCITY:
if(Context->DopplerVelocity != 0.0f)
value = AL_TRUE;
break;
case AL_DOPPLER_VELOCITY:
if (Context->DopplerVelocity != 0.0f)
value = AL_TRUE;
break;
case AL_DISTANCE_MODEL:
if(Context->DistanceModel == AL_INVERSE_DISTANCE_CLAMPED)
value = AL_TRUE;
break;
case AL_DISTANCE_MODEL:
if (Context->DistanceModel == AL_INVERSE_DISTANCE_CLAMPED)
value = AL_TRUE;
break;
case AL_SPEED_OF_SOUND:
if(Context->flSpeedOfSound != 0.0f)
value = AL_TRUE;
break;
case AL_SPEED_OF_SOUND:
if (Context->flSpeedOfSound != 0.0f)
value = AL_TRUE;
break;
default:
alSetError(AL_INVALID_ENUM);
break;
}
ProcessContext(Context);
}
else
{
// Invalid Context
alSetError(AL_INVALID_OPERATION);
default:
alSetError(AL_INVALID_ENUM);
break;
}
ProcessContext(Context);
return value;
}
@@ -169,42 +176,34 @@ ALAPI ALdouble ALAPIENTRY alGetDouble(ALenum pname)
ALCcontext *Context;
ALdouble value = 0.0;
Context=alcGetCurrentContext();
if (Context)
Context = GetContextSuspended();
if(!Context) return 0.0;
switch(pname)
{
SuspendContext(Context);
case AL_DOPPLER_FACTOR:
value = (double)Context->DopplerFactor;
break;
switch (pname)
{
case AL_DOPPLER_FACTOR:
value = (double)Context->DopplerFactor;
break;
case AL_DOPPLER_VELOCITY:
value = (double)Context->DopplerVelocity;
break;
case AL_DOPPLER_VELOCITY:
value = (double)Context->DopplerVelocity;
break;
case AL_DISTANCE_MODEL:
value = (double)Context->DistanceModel;
break;
case AL_DISTANCE_MODEL:
value = (double)Context->DistanceModel;
break;
case AL_SPEED_OF_SOUND:
value = (double)Context->flSpeedOfSound;
break;
case AL_SPEED_OF_SOUND:
value = (double)Context->flSpeedOfSound;
break;
default:
alSetError(AL_INVALID_ENUM);
break;
}
ProcessContext(Context);
}
else
{
// Invalid Context
alSetError(AL_INVALID_OPERATION);
default:
alSetError(AL_INVALID_ENUM);
break;
}
ProcessContext(Context);
return value;
}
@@ -213,42 +212,34 @@ ALAPI ALfloat ALAPIENTRY alGetFloat(ALenum pname)
ALCcontext *Context;
ALfloat value = 0.0f;
Context=alcGetCurrentContext();
if (Context)
Context = GetContextSuspended();
if(!Context) return 0.0f;
switch(pname)
{
SuspendContext(Context);
case AL_DOPPLER_FACTOR:
value = Context->DopplerFactor;
break;
switch (pname)
{
case AL_DOPPLER_FACTOR:
value = Context->DopplerFactor;
break;
case AL_DOPPLER_VELOCITY:
value = Context->DopplerVelocity;
break;
case AL_DOPPLER_VELOCITY:
value = Context->DopplerVelocity;
break;
case AL_DISTANCE_MODEL:
value = (float)Context->DistanceModel;
break;
case AL_DISTANCE_MODEL:
value = (float)Context->DistanceModel;
break;
case AL_SPEED_OF_SOUND:
value = Context->flSpeedOfSound;
break;
case AL_SPEED_OF_SOUND:
value = Context->flSpeedOfSound;
break;
default:
alSetError(AL_INVALID_ENUM);
break;
}
ProcessContext(Context);
}
else
{
// Invalid Context
alSetError(AL_INVALID_OPERATION);
default:
alSetError(AL_INVALID_ENUM);
break;
}
ProcessContext(Context);
return value;
}
@@ -257,42 +248,48 @@ ALAPI ALint ALAPIENTRY alGetInteger(ALenum pname)
ALCcontext *Context;
ALint value = 0;
Context=alcGetCurrentContext();
if (Context)
Context = GetContextSuspended();
if(!Context) return 0;
switch(pname)
{
SuspendContext(Context);
case AL_DOPPLER_FACTOR:
value = (ALint)Context->DopplerFactor;
break;
switch (pname)
{
case AL_DOPPLER_FACTOR:
value = (ALint)Context->DopplerFactor;
break;
case AL_DOPPLER_VELOCITY:
value = (ALint)Context->DopplerVelocity;
break;
case AL_DOPPLER_VELOCITY:
value = (ALint)Context->DopplerVelocity;
break;
case AL_DISTANCE_MODEL:
value = (ALint)Context->DistanceModel;
break;
case AL_DISTANCE_MODEL:
value = (ALint)Context->DistanceModel;
break;
case AL_SPEED_OF_SOUND:
value = (ALint)Context->flSpeedOfSound;
break;
case AL_SPEED_OF_SOUND:
value = (ALint)Context->flSpeedOfSound;
break;
case AL_SAMPLE_SOURCE_EXT:
if(Context->SampleSource)
value = (ALint)Context->SampleSource->databuffer;
else
value = 0;
break;
default:
alSetError(AL_INVALID_ENUM);
break;
}
case AL_SAMPLE_SINK_EXT:
if(Context->SampleSink)
value = (ALint)Context->SampleSink->databuffer;
else
value = 0;
break;
ProcessContext(Context);
}
else
{
// Invalid Context
alSetError(AL_INVALID_OPERATION);
default:
alSetError(AL_INVALID_ENUM);
break;
}
ProcessContext(Context);
return value;
}
@@ -300,204 +297,178 @@ ALAPI ALvoid ALAPIENTRY alGetBooleanv(ALenum pname,ALboolean *data)
{
ALCcontext *Context;
Context=alcGetCurrentContext();
if (Context)
Context = GetContextSuspended();
if(!Context) return;
if(data)
{
SuspendContext(Context);
if (data)
switch(pname)
{
switch (pname)
{
case AL_DOPPLER_FACTOR:
*data = (ALboolean)((Context->DopplerFactor != 0.0f) ? AL_TRUE : AL_FALSE);
break;
case AL_DOPPLER_FACTOR:
*data = (ALboolean)((Context->DopplerFactor != 0.0f) ? AL_TRUE : AL_FALSE);
break;
case AL_DOPPLER_VELOCITY:
*data = (ALboolean)((Context->DopplerVelocity != 0.0f) ? AL_TRUE : AL_FALSE);
break;
case AL_DOPPLER_VELOCITY:
*data = (ALboolean)((Context->DopplerVelocity != 0.0f) ? AL_TRUE : AL_FALSE);
break;
case AL_DISTANCE_MODEL:
*data = (ALboolean)((Context->DistanceModel == AL_INVERSE_DISTANCE_CLAMPED) ? AL_TRUE : AL_FALSE);
break;
case AL_DISTANCE_MODEL:
*data = (ALboolean)((Context->DistanceModel == AL_INVERSE_DISTANCE_CLAMPED) ? AL_TRUE : AL_FALSE);
break;
case AL_SPEED_OF_SOUND:
*data = (ALboolean)((Context->flSpeedOfSound != 0.0f) ? AL_TRUE : AL_FALSE);
break;
case AL_SPEED_OF_SOUND:
*data = (ALboolean)((Context->flSpeedOfSound != 0.0f) ? AL_TRUE : AL_FALSE);
break;
default:
alSetError(AL_INVALID_ENUM);
break;
}
default:
alSetError(AL_INVALID_ENUM);
break;
}
else
{
// data is a NULL pointer
alSetError(AL_INVALID_VALUE);
}
ProcessContext(Context);
}
else
{
// Invalid Context
alSetError(AL_INVALID_OPERATION);
// data is a NULL pointer
alSetError(AL_INVALID_VALUE);
}
return;
ProcessContext(Context);
}
ALAPI ALvoid ALAPIENTRY alGetDoublev(ALenum pname,ALdouble *data)
{
ALCcontext *Context;
Context=alcGetCurrentContext();
if (Context)
Context = GetContextSuspended();
if(!Context) return;
if(data)
{
SuspendContext(Context);
if (data)
switch(pname)
{
switch (pname)
{
case AL_DOPPLER_FACTOR:
*data = (double)Context->DopplerFactor;
break;
case AL_DOPPLER_FACTOR:
*data = (double)Context->DopplerFactor;
break;
case AL_DOPPLER_VELOCITY:
*data = (double)Context->DopplerVelocity;
break;
case AL_DOPPLER_VELOCITY:
*data = (double)Context->DopplerVelocity;
break;
case AL_DISTANCE_MODEL:
*data = (double)Context->DistanceModel;
break;
case AL_DISTANCE_MODEL:
*data = (double)Context->DistanceModel;
break;
case AL_SPEED_OF_SOUND:
*data = (double)Context->flSpeedOfSound;
break;
case AL_SPEED_OF_SOUND:
*data = (double)Context->flSpeedOfSound;
break;
default:
alSetError(AL_INVALID_ENUM);
break;
}
default:
alSetError(AL_INVALID_ENUM);
break;
}
else
{
// data is a NULL pointer
alSetError(AL_INVALID_VALUE);
}
ProcessContext(Context);
}
else
{
// Invalid Context
alSetError(AL_INVALID_OPERATION);
// data is a NULL pointer
alSetError(AL_INVALID_VALUE);
}
return;
ProcessContext(Context);
}
ALAPI ALvoid ALAPIENTRY alGetFloatv(ALenum pname,ALfloat *data)
{
ALCcontext *Context;
Context=alcGetCurrentContext();
if (Context)
Context = GetContextSuspended();
if(!Context) return;
if(data)
{
SuspendContext(Context);
if (data)
switch(pname)
{
switch (pname)
{
case AL_DOPPLER_FACTOR:
*data = Context->DopplerFactor;
break;
case AL_DOPPLER_FACTOR:
*data = Context->DopplerFactor;
break;
case AL_DOPPLER_VELOCITY:
*data = Context->DopplerVelocity;
break;
case AL_DOPPLER_VELOCITY:
*data = Context->DopplerVelocity;
break;
case AL_DISTANCE_MODEL:
*data = (float)Context->DistanceModel;
break;
case AL_DISTANCE_MODEL:
*data = (float)Context->DistanceModel;
break;
case AL_SPEED_OF_SOUND:
*data = Context->flSpeedOfSound;
break;
case AL_SPEED_OF_SOUND:
*data = Context->flSpeedOfSound;
break;
default:
alSetError(AL_INVALID_ENUM);
break;
}
default:
alSetError(AL_INVALID_ENUM);
break;
}
else
{
// data is a NULL pointer
alSetError(AL_INVALID_VALUE);
}
ProcessContext(Context);
}
else
{
// Invalid Context
alSetError(AL_INVALID_OPERATION);
// data is a NULL pointer
alSetError(AL_INVALID_VALUE);
}
return;
ProcessContext(Context);
}
ALAPI ALvoid ALAPIENTRY alGetIntegerv(ALenum pname,ALint *data)
{
ALCcontext *Context;
Context=alcGetCurrentContext();
if (Context)
Context = GetContextSuspended();
if(!Context) return;
if(data)
{
SuspendContext(Context);
if (data)
switch(pname)
{
switch (pname)
{
case AL_DOPPLER_FACTOR:
*data = (ALint)Context->DopplerFactor;
break;
case AL_DOPPLER_FACTOR:
*data = (ALint)Context->DopplerFactor;
break;
case AL_DOPPLER_VELOCITY:
*data = (ALint)Context->DopplerVelocity;
break;
case AL_DOPPLER_VELOCITY:
*data = (ALint)Context->DopplerVelocity;
break;
case AL_DISTANCE_MODEL:
*data = (ALint)Context->DistanceModel;
break;
case AL_DISTANCE_MODEL:
*data = (ALint)Context->DistanceModel;
break;
case AL_SPEED_OF_SOUND:
*data = (ALint)Context->flSpeedOfSound;
break;
case AL_SPEED_OF_SOUND:
*data = (ALint)Context->flSpeedOfSound;
break;
default:
alSetError(AL_INVALID_ENUM);
break;
}
case AL_SAMPLE_SOURCE_EXT:
if(Context->SampleSource)
*data = (ALint)Context->SampleSource->databuffer;
else
*data = 0;
break;
case AL_SAMPLE_SINK_EXT:
if(Context->SampleSink)
*data = (ALint)Context->SampleSink->databuffer;
else
*data = 0;
break;
default:
alSetError(AL_INVALID_ENUM);
break;
}
else
{
// data is a NULL pointer
alSetError(AL_INVALID_VALUE);
}
ProcessContext(Context);
}
else
{
// Invalid Context
alSetError(AL_INVALID_OPERATION);
// data is a NULL pointer
alSetError(AL_INVALID_VALUE);
}
return;
ProcessContext(Context);
}
ALAPI const ALchar* ALAPIENTRY alGetString(ALenum pname)
@@ -505,14 +476,8 @@ ALAPI const ALchar* ALAPIENTRY alGetString(ALenum pname)
const ALchar *value;
ALCcontext *pContext;
pContext = alcGetCurrentContext();
if(!pContext)
{
alSetError(AL_INVALID_OPERATION);
return NULL;
}
SuspendContext(pContext);
pContext = GetContextSuspended();
if(!pContext) return NULL;
switch(pname)
{
@@ -570,110 +535,127 @@ ALAPI const ALchar* ALAPIENTRY alGetString(ALenum pname)
ALAPI ALvoid ALAPIENTRY alDopplerFactor(ALfloat value)
{
ALCcontext *Context;
ALboolean updateSources = AL_FALSE;
Context=alcGetCurrentContext();
if (Context)
Context = GetContextSuspended();
if(!Context) return;
if(value >= 0.0f)
{
SuspendContext(Context);
if (value>=0.0f)
Context->DopplerFactor = value;
else
alSetError(AL_INVALID_VALUE);
ProcessContext(Context);
Context->DopplerFactor = value;
updateSources = AL_TRUE;
}
else
alSetError(AL_INVALID_VALUE);
// Force updating the sources for these parameters, since even head-
// relative sources are affected
if(updateSources)
{
// Invalid Context
alSetError(AL_INVALID_OPERATION);
ALsource *source = Context->Source;
while(source)
{
source->NeedsUpdate = AL_TRUE;
source = source->next;
}
}
return;
ProcessContext(Context);
}
ALAPI ALvoid ALAPIENTRY alDopplerVelocity(ALfloat value)
{
ALCcontext *Context;
ALboolean updateSources = AL_FALSE;
Context=alcGetCurrentContext();
if (Context)
Context = GetContextSuspended();
if(!Context) return;
if(value > 0.0f)
{
SuspendContext(Context);
if (value>0.0f)
Context->DopplerVelocity=value;
else
alSetError(AL_INVALID_VALUE);
ProcessContext(Context);
Context->DopplerVelocity=value;
updateSources = AL_TRUE;
}
else
alSetError(AL_INVALID_VALUE);
if(updateSources)
{
// Invalid Context
alSetError(AL_INVALID_OPERATION);
ALsource *source = Context->Source;
while(source)
{
source->NeedsUpdate = AL_TRUE;
source = source->next;
}
}
return;
ProcessContext(Context);
}
ALAPI ALvoid ALAPIENTRY alSpeedOfSound(ALfloat flSpeedOfSound)
{
ALCcontext *pContext;
ALboolean updateSources = AL_FALSE;
pContext = alcGetCurrentContext();
if (pContext)
pContext = GetContextSuspended();
if(!pContext) return;
if(flSpeedOfSound > 0.0f)
{
SuspendContext(pContext);
if (flSpeedOfSound > 0.0f)
pContext->flSpeedOfSound = flSpeedOfSound;
else
alSetError(AL_INVALID_VALUE);
ProcessContext(pContext);
pContext->flSpeedOfSound = flSpeedOfSound;
updateSources = AL_TRUE;
}
else
alSetError(AL_INVALID_VALUE);
if(updateSources)
{
alSetError(AL_INVALID_OPERATION);
ALsource *source = pContext->Source;
while(source)
{
source->NeedsUpdate = AL_TRUE;
source = source->next;
}
}
return;
ProcessContext(pContext);
}
ALAPI ALvoid ALAPIENTRY alDistanceModel(ALenum value)
{
ALCcontext *Context;
ALboolean updateSources = AL_FALSE;
Context=alcGetCurrentContext();
if (Context)
Context = GetContextSuspended();
if(!Context) return;
switch(value)
{
SuspendContext(Context);
case AL_NONE:
case AL_INVERSE_DISTANCE:
case AL_INVERSE_DISTANCE_CLAMPED:
case AL_LINEAR_DISTANCE:
case AL_LINEAR_DISTANCE_CLAMPED:
case AL_EXPONENT_DISTANCE:
case AL_EXPONENT_DISTANCE_CLAMPED:
Context->DistanceModel = value;
updateSources = !Context->SourceDistanceModel;
break;
switch (value)
default:
alSetError(AL_INVALID_VALUE);
break;
}
if(updateSources)
{
ALsource *source = Context->Source;
while(source)
{
case AL_NONE:
case AL_INVERSE_DISTANCE:
case AL_INVERSE_DISTANCE_CLAMPED:
case AL_LINEAR_DISTANCE:
case AL_LINEAR_DISTANCE_CLAMPED:
case AL_EXPONENT_DISTANCE:
case AL_EXPONENT_DISTANCE_CLAMPED:
Context->DistanceModel = value;
break;
default:
alSetError(AL_INVALID_VALUE);
break;
source->NeedsUpdate = AL_TRUE;
source = source->next;
}
ProcessContext(Context);
}
else
{
// Invalid Context
alSetError(AL_INVALID_OPERATION);
}
return;
ProcessContext(Context);
}
+20
View File
@@ -0,0 +1,20 @@
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.
+23
View File
@@ -0,0 +1,23 @@
# Cross-compiling requires CMake 2.6 or newer. To cross-compile, first modify
# this file to set the proper settings and paths. Then use it from build/ like:
# cmake .. -DCMAKE_TOOLCHAIN_FILE=../XCompile.txt \
# -DCMAKE_INSTALL_PREFIX=/usr/mingw32/mingw
# 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 mingw32-gcc)
SET(CMAKE_CXX_COMPILER mingw32-g++)
# here is the target environment located
SET(CMAKE_FIND_ROOT_PATH /usr/mingw32/mingw)
# 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)
+217 -76
View File
@@ -10,98 +10,239 @@
# 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:
# possible). Note: options that are left unset may default to app- or system-
# specified values. 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
## format:
# 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)
# AL_FORMAT_MONO32 (32-bit float mono)
# AL_FORMAT_STEREO32 (32-bit float stereo)
# AL_FORMAT_QUAD32 (32-bit float 4-channel)
# AL_FORMAT_51CHN32 (32-bit float 5.1 output)
# AL_FORMAT_61CHN32 (32-bit float 6.1 output)
# AL_FORMAT_71CHN32 (32-bit float 7.1 output)
#format = 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.
## 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
frequency = 44100 # Sets the output frequency. Default is 44100
## head_dampen:
# Sets the amount of dampening on sounds emanating from behind the listener.
# This is used to simulate the natural occlusion of the head, which is
# typically missing with mono and stereo output, and as such, only works on
# mono and stereo output modes. Valid values range from 0 to 1 (inclusive),
# and higher values provide a stronger effect.
#head_dampen = 0.25
refresh = 4096 # Sets the buffer size, in frames. Default is 4096. Note that
# the actual granularity may or may not be less than this.
## frequency:
# Sets the output frequency.
#frequency = 44100
sources = 256 # 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. Default is 256
## resampler:
# Selects the resampler used when mixing sources. Valid values are:
# 0 - None (nearest sample, no interpolation)
# 1 - Linear (extrapolates samples using a linear slope between samples)
# 2 - Cosine (extrapolates using a (co)sine slope)
# Specifying other values will result in using the default (linear).
#resampler = 1
stereodup = # Sets whether to duplicate stereo sounds on the rear speakers for
# 4+ channel output. This can make stereo sources substantially
# louder than mono or even 4+ channel sources, but provides a
# "fuller" playback quality. True, yes, on, and non-0 values will
# duplicate stereo sources. 0 and anything else will cause stereo
# sounds to only play out the front speakers.
# Default is false
## rt-prio:
# Sets real-time priority for the mixing thread. Not all drivers may use this
# (eg. PulseAudio) 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
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,solaris,dsound,winmm,wave
## period_size:
# Sets the update period size, in frames. This is the number of frames needed
# for each mixing update. If the deprecated 'refresh' option is specified and
# this isn't, the value will be calculated as size = refresh/periods.
#period_size = 1024
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:
# reverb
# Default is empty (all available effects enabled)
## 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.
#periods = 4
[alsa] # ALSA backend stuff
device = default # Sets the device name for the default playback device.
# Default is default
## 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
periods = 0 # Sets the number of update buffers for playback. A value of 0
# means auto-select. Default is 0
## stereodup:
# Sets whether to duplicate stereo sounds on the rear and side speakers for 4+
# channel output. This can make stereo sources substantially louder than mono
# or even 4+ channel sources, but provides a "fuller" playback quality. True,
# yes, on, and non-0 values will duplicate stereo sources. 0 and anything else
# will cause stereo sounds to only play out the front speakers.
#stereodup = false
capture = default # Sets the device name for the default capture device.
# Default is default
## 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).
# An empty list means the default.
#drivers = pulse,alsa,oss,solaris,dsound,winmm,port,wave
mmap = true # 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.
# Default is true.
## 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
#excludefx =
[oss] # OSS backend stuff
device = /dev/dsp # Sets the device name for OSS output. Default is /dev/dsp
## 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
periods = 4 # Sets the number of update buffers. Default is 4
## sends:
# Sets the maximum number of auxiliary sends per source. The total number of
# sends possible is defined at compile time and thus can not be increased
# beyond the default (2).
#sends = 2
capture = /dev/dsp # Sets the device name for OSS capture. Default is /dev/dsp
## layout_STEREO:
# Sets the speaker layout when using stereo output. Values are specified in
# degrees, where 0 is straight in front, negative goes left, and positive goes
# right. The values must define a circular pattern, starting with the back-
# left at the most negative, around the front to back-center. Unspecified
# speakers will remain at their default position. Available speakers are
# front-left(fl) and front-right(fr).
#layout_STEREO = fl=-90, fr=90
[solaris] # Solaris backend stuff
device = /dev/audio # Sets the device name for Solaris output. Default is
# /dev/audio
## laytout_QUAD:
# Sets the speaker layout when using quadriphonic output. Available speakers
# are back-left(bl), front-left(fl), front-right(fr), and back-right(br).
#layout_QUAD = bl=-135, fl=-45, fr=45, br=135
[dsound] # DirectSound backend stuff
periods = 4 # Sets the number of updates for the output buffer. Default is 4
## layout_51CHN:
# Sets the speaker layout when using 5.1 output. Available speakers are back-
# left(bl), front-left(fl), front-center(fc), front-right(fr), and back-
# right(br).
#layout_51CHN = bl=-110, fl=-30, fc=0, fr=30, br=110
[winmm] # Windows Multimedia backend stuff
# Nothing yet...
## layout_61CHN:
# Sets the speaker layout when using 6.1 output. Available speakers are side-
# left(sl), front-left(fl), front-center(fc), front-right(fr), side-right(sr),
# and back-center(bc).
#layout_61CHN = sl=-90, fl=-30, fc=0, fr=30, sr=90, bc=180
[wave] # Wave File Writer stuff
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!
# Default is empty
## layout_71CHN:
# Sets the speaker layout when using 7.1 output. Available speakers are back-
# left(bl), side-left(sl), front-left(fl), front-center(fc), front-right(fr),
# side-right(sr), and back-right(br).
#layout_71CHN = bl=-150, sl=-90, fl=-30, fc=0, fr=30, sr=90, br=150
##
## ALSA backend stuff
##
[alsa]
## device:
# Sets the device name for the default playback device.
#device = default
## capture:
# Sets the device name for the default capture device.
#capture = default
## 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
##
## 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
##
## PulseAudio backend stuff
##
[pulse]
## spawn-server:
# Attempts to spawn a PulseAudio server when requesting to open a PulseAudio
# device. Note that some apps may open and probe all enumerated devices on
# startup, causing a server to spawn even if a PulseAudio device is not
# actually selected. Setting autospawn to false in Pulse's client.conf will
# still prevent autospawning even if this is set to true.
#spawn-server = 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 =
View File
+59
View 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)
+21
View File
@@ -19,15 +19,30 @@
/* Define if we have the Windows Multimedia backend */
#cmakedefine HAVE_WINMM
/* Define if we have the PortAudio backend */
#cmakedefine HAVE_PORTAUDIO
/* Define if we have the PulseAudio backend */
#cmakedefine HAVE_PULSEAUDIO
/* Define if we have dlfcn.h */
#cmakedefine HAVE_DLFCN_H
/* Define if we have the stat function */
#cmakedefine HAVE_STAT
/* Define if we have the sqrtf function */
#cmakedefine HAVE_SQRTF
/* Define if we have the acosf function */
#cmakedefine HAVE_ACOSF
/* Define if we have the atanf function */
#cmakedefine HAVE_ATANF
/* Define if we have the fabsf function */
#cmakedefine HAVE_FABSF
/* Define if we have the strtof function */
#cmakedefine HAVE_STRTOF
@@ -52,6 +67,9 @@
/* Define if we have GCC's destructor attribute */
#cmakedefine HAVE_GCC_DESTRUCTOR
/* Define if we have GCC's format attribute */
#cmakedefine HAVE_GCC_FORMAT
/* Define if we have pthread_np.h */
#cmakedefine HAVE_PTHREAD_NP_H
@@ -67,4 +85,7 @@
/* Define if we have _controlfp() */
#cmakedefine HAVE__CONTROLFP
/* Define if we have pthread_setschedparam() */
#cmakedefine HAVE_PTHREAD_SETSCHEDPARAM
#endif
+77 -71
View File
@@ -14,6 +14,7 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "AL/alc.h"
#include "AL/al.h"
@@ -67,18 +68,18 @@ static void indent(int *width)
printChar(' ', width);
}
static void printExtensions(const char *header, char separator, const char *extensions)
static void printList(const char *header, char separator, const char *list)
{
int width = 0, start = 0, end = 0;
printf("%s:\n", header);
if(extensions == NULL || extensions[0] == '\0')
if(list == NULL || list[0] == '\0')
return;
indent(&width);
while (1)
while(1)
{
if(extensions[end] == separator || extensions[end] == '\0')
if(list[end] == separator || list[end] == '\0')
{
if(width + end - start + 2 > maxmimumWidth)
{
@@ -87,14 +88,14 @@ static void printExtensions(const char *header, char separator, const char *exte
}
while(start < end)
{
printChar(extensions[start], &width);
printChar(list[start], &width);
start++;
}
if(extensions[end] == '\0')
if(list[end] == '\0')
break;
start++;
end++;
if(extensions[end] == '\0')
if(list[end] == '\0')
break;
printChar(',', &width);
printChar(' ', &width);
@@ -128,15 +129,14 @@ static void checkForErrors(void)
static void printDevices(ALCenum which, const char *kind)
{
const char *s = alcGetString(NULL, which);
checkForErrors();
printf("Available %sdevices:\n", kind);
while(*s != '\0')
{
printf("Available %s devices:\n", kind);
if(s == NULL || *s == '\0')
printf(" (none!)\n");
else do {
printf(" %s\n", s);
while(*s++ != '\0')
;
}
} while(*s != '\0');
}
static void printALCInfo (void)
@@ -144,33 +144,20 @@ static void printALCInfo (void)
ALCint major, minor;
ALCdevice *device;
if(alcIsExtensionPresent(NULL, (const ALCchar*)"ALC_ENUMERATION_EXT") == AL_TRUE)
{
if(alcIsExtensionPresent(NULL, (const ALCchar*)"ALC_ENUMERATE_ALL_EXT") == AL_TRUE)
printDevices(ALC_ALL_DEVICES_SPECIFIER, "playback ");
else
printDevices(ALC_DEVICE_SPECIFIER, "playback ");
printDevices(ALC_CAPTURE_DEVICE_SPECIFIER, "capture ");
}
else
printf("No device enumeration available\n");
printf("Default device: %s\n",
alcGetString(NULL, ALC_DEFAULT_DEVICE_SPECIFIER));
printf("Default capture device: %s\n",
alcGetString(NULL, ALC_CAPTURE_DEFAULT_DEVICE_SPECIFIER));
device = alcGetContextsDevice(alcGetCurrentContext());
checkForErrors();
printf("Default device: %s\n",
alcGetString(device, ALC_DEFAULT_DEVICE_SPECIFIER));
printf("Default capture device: %s\n",
alcGetString(device, ALC_CAPTURE_DEFAULT_DEVICE_SPECIFIER));
alcGetIntegerv(device, ALC_MAJOR_VERSION, 1, &major);
alcGetIntegerv(device, ALC_MINOR_VERSION, 1, &minor);
checkForErrors();
printf("ALC version: %d.%d\n", (int)major, (int)minor);
printExtensions("ALC extensions", ' ',
alcGetString(device, ALC_EXTENSIONS));
printList("ALC extensions", ' ', alcGetString(device, ALC_EXTENSIONS));
checkForErrors();
}
@@ -179,7 +166,7 @@ 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));
printExtensions("OpenAL extensions", ' ', alGetString(AL_EXTENSIONS));
printList("OpenAL extensions", ' ', alGetString(AL_EXTENSIONS));
checkForErrors();
}
@@ -189,37 +176,24 @@ static void printEFXInfo(void)
ALCdevice *device;
ALuint obj;
int i;
const struct {
ALenum type;
const char *name;
} effects[] = {
{ AL_EFFECT_EAXREVERB, "EAX Reverb" },
{ AL_EFFECT_REVERB, "Standard Reverb" },
{ AL_EFFECT_CHORUS, "Chorus" },
{ AL_EFFECT_DISTORTION, "Distortion" },
{ AL_EFFECT_ECHO, "Echo" },
{ AL_EFFECT_FLANGER, "Flanger" },
{ AL_EFFECT_FREQUENCY_SHIFTER, "Frequency Shifter" },
{ AL_EFFECT_VOCAL_MORPHER, "Vocal Morpher" },
{ AL_EFFECT_PITCH_SHIFTER, "Pitch Shifter" },
{ AL_EFFECT_RING_MODULATOR, "Ring Modulator" },
{ AL_EFFECT_AUTOWAH, "Autowah" },
{ AL_EFFECT_COMPRESSOR, "Compressor" },
{ AL_EFFECT_EQUALIZER, "Equalizer" },
{ AL_EFFECT_NULL, NULL }
const ALenum effects[] = {
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, AL_EFFECT_NULL
};
const struct {
ALenum type;
const char *name;
} filters[] = {
{ AL_FILTER_LOWPASS, "Low-pass" },
{ AL_FILTER_HIGHPASS, "High-pass" },
{ AL_FILTER_BANDPASS, "Band-pass" },
{ AL_FILTER_NULL, NULL }
char effectNames[] = "EAX Reverb,Reverb,Chorus,Distortion,Echo,Flanger,"
"Frequency Shifter,Vocal Morpher,Pitch Shifter,"
"Ring Modulator,Autowah,Compressor,Equalizer,";
const ALenum filters[] = {
AL_FILTER_LOWPASS, AL_FILTER_HIGHPASS, AL_FILTER_BANDPASS,
AL_FILTER_NULL
};
char filterNames[] = "Low-pass,High-pass,Band-pass,";
char *current;
device = alcGetContextsDevice(alcGetCurrentContext());
if(alcIsExtensionPresent(device, (const ALCchar*)"ALC_EXT_EFX") == AL_FALSE)
{
printf("EFX not available\n");
@@ -251,35 +225,67 @@ static void printEFXInfo(void)
p_alGenFilters(1, &obj);
checkForErrors();
printf("Available filters:\n");
for(i = 0;filters[i].type != AL_FILTER_NULL;i++)
current = filterNames;
for(i = 0;filters[i] != AL_FILTER_NULL;i++)
{
p_alFilteri(obj, AL_FILTER_TYPE, filters[i].type);
char *next = strchr(current, ',');
p_alFilteri(obj, AL_FILTER_TYPE, filters[i]);
if(alGetError() == AL_NO_ERROR)
printf(" %s\n", filters[i].name);
current = next+1;
else
memmove(current, next+1, strlen(next));
}
p_alDeleteFilters(1, &obj);
checkForErrors();
printList("Supported filters", ',', filterNames);
p_alGenEffects(1, &obj);
checkForErrors();
printf("Available effects:\n");
for(i = 0;effects[i].type != AL_EFFECT_NULL;i++)
current = effectNames;
for(i = 0;effects[i] != AL_EFFECT_NULL;i++)
{
p_alEffecti(obj, AL_EFFECT_TYPE, effects[i].type);
char *next = strchr(current, ',');
p_alEffecti(obj, AL_EFFECT_TYPE, effects[i]);
if(alGetError() == AL_NO_ERROR)
printf(" %s\n", effects[i].name);
current = next+1;
else
memmove(current, next+1, strlen(next));
}
p_alDeleteEffects(1, &obj);
checkForErrors();
printList("Supported effects", ',', effectNames);
}
int main()
{
ALCdevice *device = alcOpenDevice(NULL);
ALCcontext *context = alcCreateContext(device, NULL);
alcMakeContextCurrent(context);
checkForErrors();
ALCdevice *device;
ALCcontext *context;
if(alcIsExtensionPresent(NULL, (const ALCchar*)"ALC_ENUMERATION_EXT") == AL_TRUE)
{
if(alcIsExtensionPresent(NULL, (const ALCchar*)"ALC_ENUMERATE_ALL_EXT") == AL_TRUE)
printDevices(ALC_ALL_DEVICES_SPECIFIER, "playback");
else
printDevices(ALC_DEVICE_SPECIFIER, "playback");
printDevices(ALC_CAPTURE_DEVICE_SPECIFIER, "capture");
}
else
printf("No device enumeration available\n");
device = alcOpenDevice(NULL);
if(!device)
{
printf("Failed to open a device!\n");
exit(EXIT_FAILURE);
}
context = alcCreateContext(device, NULL);
if(!context || alcMakeContextCurrent(context) == ALC_FALSE)
{
printf("Failed to set a context!\n");
exit(EXIT_FAILURE);
}
printALCInfo();
printALInfo();
+1 -2
View File
@@ -117,8 +117,7 @@ typedef void ALvoid;
#define AL_CONE_OUTER_ANGLE 0x1002
/**
* Specify the pitch to be applied, either at source,
* or on mixer results, at listener.
* Specify the pitch to be applied at source.
* Range: [0.5-2.0]
* Default: 1.0
*/
+62
View File
@@ -53,6 +53,12 @@ extern "C" {
#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 ALC_LOKI_audio_channel
#define ALC_LOKI_audio_channel 1
#define ALC_CHAN_MAIN_LOKI 0x500001
@@ -99,6 +105,62 @@ extern "C" {
typedef ALvoid (AL_APIENTRY*PFNALBUFFERSUBDATAEXTPROC)(ALuint,ALenum,const ALvoid*,ALsizei,ALsizei);
#endif
#ifndef AL_EXT_STATIC_BUFFER
#define AL_EXT_STATIC_BUFFER 1
typedef ALvoid (AL_APIENTRY*PFNALBUFFERDATASTATICPROC)(const ALint,ALenum,ALvoid*,ALsizei,ALsizei);
#endif
#ifndef AL_EXT_sample_buffer_object
#define AL_EXT_sample_buffer_object 1
#define AL_SAMPLE_SOURCE_EXT 0x1040
#define AL_SAMPLE_SINK_EXT 0x1041
#define AL_READ_ONLY_EXT 0x1042
#define AL_WRITE_ONLY_EXT 0x1043
#define AL_READ_WRITE_EXT 0x1044
#define AL_STREAM_WRITE_EXT 0x1045
#define AL_STREAM_READ_EXT 0x1046
#define AL_STREAM_COPY_EXT 0x1047
#define AL_STATIC_WRITE_EXT 0x1048
#define AL_STATIC_READ_EXT 0x1049
#define AL_STATIC_COPY_EXT 0x104A
#define AL_DYNAMIC_WRITE_EXT 0x104B
#define AL_DYNAMIC_READ_EXT 0x104C
#define AL_DYNAMIC_COPY_EXT 0x104D
typedef ALvoid (AL_APIENTRY*PFNALGENDATABUFFERSEXTPROC)(ALsizei n,ALuint *puiBuffers);
typedef ALvoid (AL_APIENTRY*PFNALDELETEDATABUFFERSEXTPROC)(ALsizei n, const ALuint *puiBuffers);
typedef ALboolean (AL_APIENTRY*PFNALISDATABUFFEREXTPROC)(ALuint uiBuffer);
typedef ALvoid (AL_APIENTRY*PFNALDATABUFFERDATAEXTPROC)(ALuint buffer,const ALvoid *data,ALsizei size,ALenum usage);
typedef ALvoid (AL_APIENTRY*PFNALDATABUFFERSUBDATAEXTPROC)(ALuint buffer, ALuint start, ALsizei length, const ALvoid *);
typedef ALvoid (AL_APIENTRY*PFNALGETDATABUFFERSUBDATAEXTPROC)(ALuint buffer, ALuint start, ALsizei length, ALvoid *);
typedef ALvoid (AL_APIENTRY*PFNALDATABUFFERFEXTPROC)(ALuint buffer, ALenum eParam, ALfloat flValue);
typedef ALvoid (AL_APIENTRY*PFNALDATABUFFERFVEXTPROC)(ALuint buffer, ALenum eParam, const ALfloat* flValues);
typedef ALvoid (AL_APIENTRY*PFNALDATABUFFERIEXTPROC)(ALuint buffer, ALenum eParam, ALint lValue);
typedef ALvoid (AL_APIENTRY*PFNALDATABUFFERIVEXTPROC)(ALuint buffer, ALenum eParam, const ALint* plValues);
typedef ALvoid (AL_APIENTRY*PFNALGETDATABUFFERFEXTPROC)(ALuint buffer, ALenum eParam, ALfloat *pflValue);
typedef ALvoid (AL_APIENTRY*PFNALGETDATABUFFERFVEXTPROC)(ALuint buffer, ALenum eParam, ALfloat* pflValues);
typedef ALvoid (AL_APIENTRY*PFNALGETDATABUFFERIEXTPROC)(ALuint buffer, ALenum eParam, ALint *plValue);
typedef ALvoid (AL_APIENTRY*PFNALGETDATABUFFERIVEXTPROC)(ALuint buffer, ALenum eParam, ALint* plValues);
typedef ALvoid (AL_APIENTRY*PFNALSELECTDATABUFFEREXTPROC)(ALenum target, ALuint uiBuffer);
typedef ALvoid* (AL_APIENTRY*PFNALMAPDATABUFFEREXTPROC)(ALuint uiBuffer, ALuint start, ALsizei length, ALenum access);
typedef ALvoid (AL_APIENTRY*PFNALUNMAPDATABUFFEREXTPROC)(ALuint uiBuffer);
#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*PFNALCMAKECURRENTPROC)(ALCcontext *context);
typedef ALCcontext* (ALC_APIENTRY*PFNALCGETTHREADCONTEXTPROC)(void);
#endif
#ifndef AL_EXT_source_distance_model
#define AL_EXT_source_distance_model 1
#define AL_SOURCE_DISTANCE_MODEL 0x200
#endif
#ifdef __cplusplus
}
#endif