├── .gitattributes ├── .gitignore ├── CMakeLists.txt ├── Example ├── Example1_SimpleSound.cpp ├── Example2_WAV.cpp ├── Example3_MP3.cpp ├── Example4_OGG.cpp ├── Example5_Mixing.cpp ├── Example6_DynamicMixing.cpp └── Sound │ ├── Crysis 1.ogg │ ├── River Frows In You.mp3 │ ├── shot.wav │ ├── thunder.ogg │ └── voice.mp3 ├── Include └── OneSound │ ├── Export.h │ ├── Listener.h │ ├── OneSound.h │ ├── SoundType │ ├── Sound2D.h │ ├── Sound3D.h │ ├── SoundBuffer.h │ ├── SoundObject.h │ ├── SoundObjectState.h │ └── SoundStream.h │ ├── StreamType │ ├── AudioStream.h │ ├── MP3Stream.h │ ├── OGGStream.h │ └── WAVStream.h │ ├── Utility.h │ └── XAudio2Device.h ├── LICENSE ├── README.md ├── Source ├── Listener.cpp ├── OneSound.cpp ├── SoundType │ ├── Sound2D.cpp │ ├── Sound3D.cpp │ ├── SoundBuffer.cpp │ ├── SoundObject.cpp │ ├── SoundObjectState.cpp │ └── SoundStream.cpp ├── StreamType │ ├── AudioStream.cpp │ ├── MP3Stream.cpp │ └── OGGStream.cpp └── XAudio2Device.cpp └── ThirdParty └── Include ├── Vorbis ├── codec.h ├── ogg.h ├── os_types.h └── vorbisfile.h ├── XAudio2_7 ├── X3DAudio.h ├── XAudio2.h ├── XAudio2fx.h ├── audiodefs.h ├── comdecl.h └── xma2defs.h └── mpg123.h /.gitattributes: -------------------------------------------------------------------------------- 1 | # Auto detect text files and perform LF normalization 2 | * text=auto 3 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Prerequisites 2 | *.d 3 | 4 | # Compiled Object files 5 | *.slo 6 | *.lo 7 | *.o 8 | *.obj 9 | 10 | # Precompiled Headers 11 | *.gch 12 | *.pch 13 | 14 | # Compiled Dynamic libraries 15 | *.so 16 | *.dylib 17 | *.dll 18 | 19 | # Fortran module files 20 | *.mod 21 | *.smod 22 | 23 | # Compiled Static libraries 24 | *.lai 25 | *.la 26 | *.a 27 | *.lib 28 | 29 | # Executables 30 | *.exe 31 | *.out 32 | *.app 33 | -------------------------------------------------------------------------------- /CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # === CMake lists for the OneSound - (08/02/2018) === 2 | 3 | # Not sure it is correct written 4 | 5 | cmake_minimum_required (VERSION 3.0) 6 | project (OneSound) 7 | 8 | # === Build path === 9 | 10 | set(OUTPUT_DIR ${CMAKE_CURRENT_BINARY_DIR}/build) 11 | set(EXECUTABLE_OUTPUT_PATH ${OUTPUT_DIR} CACHE PATH "Build directory" FORCE) 12 | set(LIBRARY_OUTPUT_PATH ${OUTPUT_DIR} CACHE PATH "Build directory" FORCE) 13 | set(PROJECT_INCLUDE_DIR "${PROJECT_SOURCE_DIR}/include") 14 | 15 | # === Preprocessor definitions === 16 | 17 | macro(ADD_DEFINE IDENT) 18 | if(MSVC) 19 | add_definitions("/D${IDENT}") 20 | else() 21 | add_definitions("-D${IDENT}") 22 | endif() 23 | endmacro() 24 | 25 | macro(ADD_TEST_PROJECT TEST_NAME TEST_FILES) 26 | add_executable(${TEST_NAME} ${TEST_FILES}) 27 | target_link_libraries(${TEST_NAME} OneSound) 28 | set_target_properties(${TEST_NAME} PROPERTIES LINKER_LANGUAGE CXX DEBUG_POSTFIX "D") 29 | target_compile_features(${TEST_NAME} PRIVATE cxx_range_for) 30 | endmacro() 31 | 32 | file(GLOB FilesInclude ${PROJECT_INCLUDE_DIR}/OneSound/*.*) 33 | file(GLOB FilesSoundTypeI ${PROJECT_INCLUDE_DIR}/OneSound/SoundType/*.*) 34 | file(GLOB FilesStreamTypeI ${PROJECT_INCLUDE_DIR}/OneSound/StreamType/*.*) 35 | file(GLOB FilesSource ${PROJECT_SOURCE_DIR}/Source/*.*) 36 | file(GLOB FilesSoundType ${PROJECT_SOURCE_DIR}/Source/SoundType/*.*) 37 | file(GLOB FilesStreamType ${PROJECT_SOURCE_DIR}/Source/StreamType/*.*) 38 | 39 | set(FilesTest1 ${PROJECT_SOURCE_DIR}/example/Example1_SimpleSound.cpp) 40 | set(FilesTest2 ${PROJECT_SOURCE_DIR}/example/Example2_WAV.cpp) 41 | set(FilesTest3 ${PROJECT_SOURCE_DIR}/example/Example3_MP3.cpp) 42 | set(FilesTest4 ${PROJECT_SOURCE_DIR}/example/Example4_OGG.cpp) 43 | set(FilesTest5 ${PROJECT_SOURCE_DIR}/example/Example5_Mixing.cpp) 44 | set(FilesTest6 ${PROJECT_SOURCE_DIR}/example/Example6_DynamicMixing.cpp) 45 | 46 | source_group("Include" FILES ${FilesInclude}) 47 | source_group("Include\\SoundType" FILES ${FilesSoundTypeI}) 48 | source_group("Include\\StreamType" FILES ${FilesStreamTypeI}) 49 | source_group("Source" FILES ${FilesSource}) 50 | source_group("Source\\SoundType" FILES ${FilesSoundType}) 51 | source_group("Source\\StreamType" FILES ${FilesStreamType}) 52 | 53 | # === Include directories === 54 | 55 | include_directories("${PROJECT_INCLUDE_DIR}") 56 | 57 | set( 58 | FilesAll 59 | ${FilesInclude} 60 | ${FilesSoundTypeI} 61 | ${FilesStreamTypeI} 62 | ${FilesSource} 63 | ${FilesSoundType} 64 | ${FilesStreamType} 65 | ) 66 | 67 | # Main Project 68 | add_library(OneSound SHARED ${FilesAll}) 69 | set_target_properties(OneSound PROPERTIES LINKER_LANGUAGE CXX DEBUG_POSTFIX "D") 70 | target_compile_features(OneSound PRIVATE cxx_range_for) 71 | 72 | if(WIN32) 73 | target_link_libraries(OneSound Winmm) 74 | endif() 75 | 76 | ADD_TEST_PROJECT(Example1_SimpleSound ${FilesTest1}) 77 | ADD_TEST_PROJECT(Example2_WAV ${FilesTest2}) 78 | ADD_TEST_PROJECT(Example3_MP3 ${FilesTest3}) 79 | ADD_TEST_PROJECT(Example4_OGG ${FilesTest4}) 80 | ADD_TEST_PROJECT(Example5_Mixing ${FilesTest5}) 81 | ADD_TEST_PROJECT(Example6_DynamicMixing ${FilesTest6}) -------------------------------------------------------------------------------- /Example/Example1_SimpleSound.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Example 1 "Simple Sound" for OneSound. 3 | * Copyright ⓒ 2018 Valentyn Bondarenko. All rights reserved. 4 | * License: https://github.com/weelhelmer/OneSound/master/LICENSE 5 | */ 6 | 7 | #include "OneSound\OneSound.h" 8 | 9 | #include 10 | 11 | using namespace std; 12 | using namespace onesnd; 13 | 14 | int main() 15 | { 16 | try 17 | { 18 | // Create OneSound that initialize XAudio2 Device. 19 | auto one_sound = make_unique(); 20 | 21 | // Create a sound that not loops, plays at once and with 75% volume. 22 | auto sound_1 = make_unique(make_unique("Sound\\shot.wav"), 23 | false, // Looping 24 | true, // Playing 25 | 0.75f); // Volume 26 | 27 | cout << "Press any key to quit." << endl; 28 | auto i = char(); 29 | cin >> i; 30 | } 31 | catch (const std::runtime_error& e) 32 | { 33 | cerr << e.what() << endl; 34 | } 35 | 36 | return 0; 37 | } -------------------------------------------------------------------------------- /Example/Example2_WAV.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Example 2 "WAV" for OneSound. 3 | * Copyright ⓒ 2018 Valentyn Bondarenko. All rights reserved. 4 | * License: https://github.com/weelhelmer/OneSound/master/LICENSE 5 | */ 6 | 7 | #include "OneSound\OneSound.h" 8 | 9 | #include 10 | 11 | using namespace std; 12 | using namespace onesnd; 13 | 14 | int main() 15 | { 16 | try 17 | { 18 | auto one_sound = make_unique(false); 19 | 20 | // Print library info. 21 | cout << one_sound->getLibraryName() << ends 22 | << "v." << one_sound->getLibraryVersionStr() << ends 23 | << one_sound->getLibraryStatus() << endl; 24 | 25 | // We can initialize it in this way, but look at the OneSound arg. 26 | one_sound->initialize(); 27 | 28 | // The sound buffer is good for short effects like shots, steps or small nature details and so on. 29 | // Any sound plays in another thread. 30 | auto sound_1 = make_unique(make_unique("Sound\\shot.wav"), 31 | false, 32 | true, 33 | 0.3f); 34 | 35 | // The sound stream is good for the large effects like ambients, talks, unbreakable things. 36 | // NOTE: If we'll take a look at WAV formar then we'll see that it's not a good choice for streams. 37 | // Many sounds file get decades of MBs for a few minutes. 38 | // It would be prefer to use .ogg or .mp3 files in this case. 39 | /* 40 | auto sound_2 = make_unique(make_unique("Sound\\shot.wav"), 41 | false, 42 | true, 43 | 0.2f); 44 | */ 45 | 46 | cout << "Press any key to quit." << endl; 47 | auto i = char(); 48 | cin >> i; 49 | 50 | // Here the sound is stopped even if it is still playing. 51 | } 52 | catch (const runtime_error& e) 53 | { 54 | cout << e.what() << endl; 55 | } 56 | catch (...) 57 | { 58 | cerr << "Unknown exception." << endl; 59 | } 60 | 61 | return 0; 62 | } -------------------------------------------------------------------------------- /Example/Example3_MP3.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Example 3 "MP3" for OneSound. 3 | * Copyright ⓒ 2018 Valentyn Bondarenko. All rights reserved. 4 | * License: https://github.com/weelhelmer/OneSound/master/LICENSE 5 | */ 6 | 7 | #include "OneSound\OneSound.h" 8 | 9 | #include 10 | #include 11 | 12 | using namespace std; 13 | using namespace onesnd; 14 | 15 | int main() 16 | { 17 | try 18 | { 19 | auto one_sound = make_unique(); 20 | 21 | // Following two sounds will be almost playing in the time. 22 | auto sound_1 = make_shared(make_shared("Sound\\voice.mp3"), 23 | false, 24 | true, 25 | 1.0f); 26 | 27 | auto sound_2 = make_shared(make_shared("Sound\\River Frows In You.mp3"), 28 | false, 29 | true, 30 | 0.75f); 31 | 32 | const auto exit_key = '9'; 33 | cout << "Press" << ends << exit_key << ends << "to stop showing the information." << endl; 34 | cout << "XAudio2 memory usage (KB) per second:" << ends; 35 | 36 | while (sound_1->isPlaying() || sound_2->isPlaying()) 37 | { 38 | // Wait for 1 second. 39 | this_thread::sleep_for<>(1s); 40 | 41 | // Check the user press the target key. 42 | if (GetAsyncKeyState(exit_key) & 0x0001) // KEY & KEY_DOWN 43 | break; 44 | 45 | // Usefull function for debuging, for more details see XAUDIO2_PERFORMANCE_DATA structure. 46 | // Devide on 1024 to get kilobytes instead of bytes. 47 | cout << one_sound->getPerfomanceData().MemoryUsageInBytes / 1024 << ends; 48 | } 49 | 50 | cout << endl << "Press any key to quit." << endl; 51 | auto i = char(); 52 | cin >> i; 53 | } 54 | catch (const std::runtime_error& e) 55 | { 56 | cerr << e.what() << endl; 57 | } 58 | catch (...) 59 | { 60 | cerr << "Unknown exception." << endl; 61 | } 62 | 63 | return 0; 64 | } -------------------------------------------------------------------------------- /Example/Example4_OGG.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Example 4 "OGG" for OneSound. 3 | * Copyright ⓒ 2018 Valentyn Bondarenko. All rights reserved. 4 | * License: https://github.com/weelhelmer/OneSound/master/LICENSE 5 | */ 6 | 7 | #include "OneSound\OneSound.h" 8 | 9 | #include 10 | 11 | using namespace std; 12 | using namespace onesnd; 13 | 14 | int main() 15 | { 16 | try 17 | { 18 | auto one_sound = make_unique(); 19 | 20 | shared_ptr stream; 21 | vector> sounds; 22 | 23 | // Usefull lambdas for playing buffers/streams. 24 | 25 | // The first lambda for playing a sound. 26 | auto play_sound([&] (const fs::path& file_name, const bool& loop = false, const bool& play = true, const float& volume = 1.0f) 27 | { 28 | stream = make_shared(file_name); 29 | 30 | // Create a sound buffer without looping. 31 | // It plays at once beyond loading with 100% volume. 32 | // The sound is playing when we push it back into the vector. 33 | sounds.push_back(make_shared(stream, loop, play, volume)); 34 | }); 35 | 36 | // The second lambda for streaming a sound. 37 | auto stream_sound([&] (const fs::path& file_name, const bool& loop = false, const bool& play = true, const float& volume = 1.0f) 38 | { 39 | // NOTE: Only a few active streams. 40 | sounds.push_back( 41 | make_shared( 42 | make_shared(file_name), 43 | loop, 44 | play, 45 | volume) 46 | ); 47 | }); 48 | 49 | play_sound("Sound\\thunder.ogg", false, true, 0.79f); 50 | stream_sound("Sound\\Crysis 1.ogg", false, true, 1.0f); 51 | 52 | cout << "Press any key to quit." << endl; 53 | auto symbol = char(); 54 | cin >> symbol; 55 | } 56 | catch (const runtime_error& e) 57 | { 58 | cout << e.what() << endl; 59 | } 60 | catch (...) 61 | { 62 | cerr << "Unknown exception." << endl; 63 | } 64 | 65 | return 0; 66 | } -------------------------------------------------------------------------------- /Example/Example5_Mixing.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Example 5 "Mixing" for OneSound. 3 | * Copyright ⓒ 2018 Valentyn Bondarenko. All rights reserved. 4 | * License: https://github.com/weelhelmer/OneSound/master/LICENSE 5 | */ 6 | 7 | #include "OneSound\OneSound.h" 8 | 9 | #include 10 | 11 | using namespace std; 12 | using namespace onesnd; 13 | 14 | int main() 15 | { 16 | try 17 | { 18 | auto one_sound = make_unique(); 19 | 20 | shared_ptr buffer; 21 | vector> sounds; 22 | 23 | auto play_sound([&](const fs::path& file_name, const bool& loop = false, const bool& play = true, const float& volume = 1.0f) 24 | { 25 | buffer = make_unique(file_name); 26 | sounds.push_back(make_unique(buffer, loop, play, volume)); 27 | }); 28 | 29 | const auto exit_key = '1'; 30 | cout << "Press" << ends << exit_key << ends << "to stop asking the information." << endl; 31 | 32 | while (!GetAsyncKeyState(exit_key) & 0x0001) 33 | { 34 | auto file_name = fs::path(); 35 | cout << "Enter the sound's file name:" << ends; 36 | cin >> file_name; 37 | 38 | if (!fs::exists(file_name)) 39 | { 40 | cout << "Can't find file:" << ends << file_name << endl; 41 | continue; // Not to throw application. 42 | } 43 | 44 | auto loop = bool(); 45 | cout << "Enter the sound's looping(1 or 0): " << ends; 46 | cin >> loop; 47 | 48 | auto volume = float(); 49 | cout << "Enter the sound's volume(i.e. 0.3): " << ends; 50 | cin >> volume; 51 | 52 | play_sound(file_name, loop, true, volume); 53 | } 54 | 55 | cout << "Press any key to quit." << endl; 56 | auto i = char(); 57 | cin >> i; 58 | } 59 | catch (const exception& e) 60 | { 61 | cout << e.what() << endl; 62 | } 63 | catch (...) 64 | { 65 | cerr << "Unknown exception." << endl; 66 | } 67 | 68 | return 0; 69 | } -------------------------------------------------------------------------------- /Example/Example6_DynamicMixing.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Example 6 "DynamicMixing" for OneSound. 3 | * Copyright ⓒ 2018 Valentyn Bondarenko. All rights reserved. 4 | * License: https://github.com/weelhelmer/OneSound/master/LICENSE 5 | */ 6 | 7 | #include "OneSound\OneSound.h" 8 | 9 | #include 10 | #include 11 | #include 12 | 13 | using namespace std; 14 | using namespace onesnd; 15 | 16 | int main() 17 | { 18 | try 19 | { 20 | auto one_sound = make_shared(); 21 | 22 | array, 5> buffers; 23 | 24 | buffers[0] = make_shared(); 25 | buffers[0]->Load("Sound\\shot.wav"); // Load a sound after sound stream/buffer initialization. 26 | 27 | buffers[1] = make_shared(); 28 | buffers[1]->Load("Sound\\Crysis 1.ogg"); 29 | 30 | buffers[2] = make_shared("Sound\\thunder.ogg"); // Stream a sound dynamically. 31 | buffers[3] = make_shared("Sound\\thunder.ogg"); // Load a sound at once. 32 | buffers[4] = make_shared("Sound\\voice.mp3"); 33 | 34 | cout << "Keys:" << endl 35 | << "1 - Create Shot (OGG Buffer)" << endl 36 | << "2 - Create Crysis 1 (OGG Stream)" << endl 37 | << "3 - Create Forest (OGG Stream)" << endl 38 | << "4 - Create Thunder (WAV Buffer)" << endl 39 | << "5 - Create Voice (MP3 Stream)" << endl 40 | << "S - Stop all sounds" << endl << endl; 41 | 42 | vector> active_sounds; // We'll use it to keep track of generated sounds. 43 | 44 | auto isKeyDown([](int vkey) 45 | { 46 | if (GetAsyncKeyState(vkey) & 0x0001) 47 | return true; 48 | 49 | return false; 50 | }); 51 | 52 | const auto exit_key = '9'; 53 | cout << "Press" << ends << exit_key << ends << "to stop getting keys down." << endl; 54 | 55 | while (!isKeyDown(exit_key)) 56 | { 57 | if (isKeyDown('1')) 58 | active_sounds.push_back(make_shared(buffers[0], false, true)); 59 | 60 | if (isKeyDown('2')) 61 | { 62 | auto sound_2 = make_shared(buffers[1]); 63 | sound_2->play(); // It can be played anywhere. 64 | 65 | active_sounds.push_back(sound_2); 66 | } 67 | 68 | if (isKeyDown('3')) 69 | { 70 | auto sound_3 = make_shared(); 71 | sound_3->play(buffers[2], false, true, 0.7f); // Play whatever. 72 | 73 | active_sounds.push_back(sound_3); 74 | } 75 | 76 | if (isKeyDown('4')) 77 | { 78 | auto sound_4 = make_shared(buffers[3]); 79 | sound_4->play(); // Play whatever. 80 | 81 | active_sounds.push_back(sound_4); 82 | } 83 | 84 | if (isKeyDown('5')) 85 | active_sounds.push_back(make_shared(buffers[4], false, true)); 86 | 87 | if (isKeyDown('S')) 88 | { 89 | // Smooth fadeout over 300 ms. 90 | for (int i = 0; i < 10; ++i) 91 | { 92 | for (const auto& sound : active_sounds) // Gradually reduce all sounds by 0.05f. 93 | if (sound->getVolume() >= 0.1f) 94 | sound->setVolume(sound->getVolume() - 0.1f); 95 | 96 | this_thread::sleep_for<>(30ms); // 10x30ms = 300 ms 97 | } 98 | 99 | for (const auto sound : active_sounds) 100 | sound->stop(); 101 | 102 | active_sounds.clear(); 103 | } 104 | } 105 | 106 | active_sounds.clear(); 107 | 108 | cout << "Press any key to quit." << endl; 109 | auto i = char(); 110 | cin >> i; 111 | } 112 | catch (const runtime_error& e) 113 | { 114 | cout << e.what() << endl; 115 | } 116 | 117 | return 0; 118 | } -------------------------------------------------------------------------------- /Example/Sound/Crysis 1.ogg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xnhunter/OneSound/2a5b76329ff79ad5759c037acd8741b43c1195e7/Example/Sound/Crysis 1.ogg -------------------------------------------------------------------------------- /Example/Sound/River Frows In You.mp3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xnhunter/OneSound/2a5b76329ff79ad5759c037acd8741b43c1195e7/Example/Sound/River Frows In You.mp3 -------------------------------------------------------------------------------- /Example/Sound/shot.wav: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xnhunter/OneSound/2a5b76329ff79ad5759c037acd8741b43c1195e7/Example/Sound/shot.wav -------------------------------------------------------------------------------- /Example/Sound/thunder.ogg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xnhunter/OneSound/2a5b76329ff79ad5759c037acd8741b43c1195e7/Example/Sound/thunder.ogg -------------------------------------------------------------------------------- /Example/Sound/voice.mp3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xnhunter/OneSound/2a5b76329ff79ad5759c037acd8741b43c1195e7/Example/Sound/voice.mp3 -------------------------------------------------------------------------------- /Include/OneSound/Export.h: -------------------------------------------------------------------------------- 1 | /* 2 | * OneSound - Modern C++17 audio library for Windows OS with XAudio2 API 3 | * Copyright ⓒ 2018 Valentyn Bondarenko. All rights reserved. 4 | * License: https://github.com/weelhelmer/OneSound/master/LICENSE 5 | */ 6 | 7 | #pragma once 8 | 9 | namespace onesnd 10 | { 11 | #ifdef _MSC_VER 12 | # define ONE_SOUND_API __declspec(dllexport) 13 | #else 14 | # define ONE_SOUND_API 15 | # error Not a Windows platform. 16 | #endif 17 | } -------------------------------------------------------------------------------- /Include/OneSound/Listener.h: -------------------------------------------------------------------------------- 1 | /* 2 | * OneSound - Modern C++17 audio library for Windows OS with XAudio2 API 3 | * Copyright ⓒ 2018 Valentyn Bondarenko. All rights reserved. 4 | * License: https://github.com/weelhelmer/OneSound/master/LICENSE 5 | */ 6 | 7 | #pragma once 8 | 9 | #include "OneSound\Export.h" 10 | 11 | namespace onesnd 12 | { 13 | // REDO: Listener class. 14 | class Listener 15 | { 16 | public: 17 | Listener(); 18 | ~Listener(); 19 | 20 | Listener(const Listener&) = default; 21 | Listener(Listener&&) = default; 22 | 23 | Listener operator=(const Listener&) = delete; 24 | Listener operator=(Listener&&) = delete; 25 | 26 | public: 27 | void setVolume(float volume); 28 | float getVolume() const; 29 | }; 30 | } 31 | -------------------------------------------------------------------------------- /Include/OneSound/OneSound.h: -------------------------------------------------------------------------------- 1 | /* 2 | * OneSound - Modern C++17 audio library for Windows OS with XAudio2 API 3 | * Copyright ⓒ 2018 Valentyn Bondarenko. All rights reserved. 4 | * License: https://github.com/weelhelmer/OneSound/master/LICENSE 5 | */ 6 | 7 | #pragma once 8 | 9 | #include "OneSound\Export.h" 10 | 11 | #include "OneSound\SoundType\SoundBuffer.h" 12 | #include "OneSound\SoundType\SoundStream.h" 13 | 14 | #include "OneSound\SoundType\Sound2D.h" 15 | 16 | namespace onesnd 17 | { 18 | class ONE_SOUND_API OneSound 19 | { 20 | public: 21 | OneSound(const bool& has_initialize = true); // Param has_initialize gives us the 22 | // opportunity to initialize OneSound then. 23 | ~OneSound(); 24 | 25 | OneSound(const OneSound&) = delete; 26 | OneSound(OneSound&&) = delete; 27 | 28 | OneSound& operator=(const OneSound&) = delete; 29 | OneSound& operator=(OneSound&&) = delete; 30 | 31 | public: 32 | void initialize() const; 33 | 34 | XAUDIO2_PERFORMANCE_DATA getPerfomanceData() const; 35 | 36 | void finalize() const; 37 | 38 | public: 39 | unsigned long long getLibraryVersion() const; 40 | std::string getLibraryVersionStr() const; 41 | 42 | std::string getLibraryStatus() const; 43 | std::string getLibraryName() const; 44 | 45 | }; 46 | } -------------------------------------------------------------------------------- /Include/OneSound/SoundType/Sound2D.h: -------------------------------------------------------------------------------- 1 | /* 2 | * OneSound - Modern C++17 audio library for Windows OS with XAudio2 API 3 | * Copyright ⓒ 2018 Valentyn Bondarenko. All rights reserved. 4 | * License: https://github.com/weelhelmer/OneSound/master/LICENSE 5 | */ 6 | 7 | #pragma once 8 | 9 | #include "OneSound\Export.h" 10 | 11 | #include "OneSound\SoundType\SoundObject.h" 12 | 13 | namespace onesnd 14 | { 15 | class ONE_SOUND_API Sound2D : public SoundObject 16 | { 17 | public: 18 | Sound2D(); 19 | ~Sound2D() = default; 20 | 21 | Sound2D(const std::shared_ptr& sound, const bool& loop = false, const bool& play = false, const float& volume = 1.f); 22 | }; 23 | } 24 | -------------------------------------------------------------------------------- /Include/OneSound/SoundType/Sound3D.h: -------------------------------------------------------------------------------- 1 | /* 2 | * OneSound - Modern C++17 audio library for Windows OS with XAudio2 API 3 | * Copyright ⓒ 2018 Valentyn Bondarenko. All rights reserved. 4 | * License: https://github.com/weelhelmer/OneSound/master/LICENSE 5 | */ 6 | 7 | #pragma once 8 | 9 | #include "OneSound\Export.h" 10 | 11 | #include "OneSound\SoundType\SoundObject.h" 12 | 13 | namespace onesnd 14 | { 15 | class ONE_SOUND_API Sound3D : public SoundObject 16 | { 17 | public: 18 | Sound3D(); 19 | ~Sound3D() = default; 20 | 21 | Sound3D(const std::shared_ptr& sound, const bool& loop = false, const bool& play = false, const float& volume = 1.f); 22 | }; 23 | } 24 | -------------------------------------------------------------------------------- /Include/OneSound/SoundType/SoundBuffer.h: -------------------------------------------------------------------------------- 1 | /* 2 | * OneSound - Modern C++17 audio library for Windows OS with XAudio2 API 3 | * Copyright ⓒ 2018 Valentyn Bondarenko. All rights reserved. 4 | * License: https://github.com/weelhelmer/OneSound/master/LICENSE 5 | */ 6 | 7 | #pragma once 8 | 9 | #include "OneSound\Export.h" 10 | 11 | #include "OneSound\Utility.h" 12 | 13 | #include"OneSound\SoundType\SoundObject.h" 14 | 15 | namespace onesnd 16 | { 17 | struct XABuffer; 18 | /** 19 | * A simple SoundBuffer designed for loading small sound files into a static buffer. 20 | * Should be used for sound files smaller than 64KB (1.5s @ 41kHz). 21 | */ 22 | class ONE_SOUND_API SoundBuffer 23 | { 24 | protected: 25 | // number of references of this buffer held by SoundObjects; 26 | // NOTE: SoundBuffer can't be unloaded until referance_count == 0. 27 | int referance_count; 28 | XABuffer* xaBuffer; 29 | 30 | public: 31 | 32 | /** 33 | * Creates a new SoundBuffer object 34 | */ 35 | SoundBuffer(); 36 | 37 | /** 38 | * Creates a new SoundBuffer and loads the specified sound file 39 | * @param file Path to sound file to load 40 | */ 41 | SoundBuffer(const fs::path& file); 42 | 43 | /** 44 | * Destroyes and unloads this buffer 45 | */ 46 | virtual ~SoundBuffer(); 47 | 48 | XABuffer* getXABuffer() const { return xaBuffer; } 49 | 50 | /** 51 | * @return Frequency in Hz of this SoundBuffer data 52 | */ 53 | int Frequency() const; 54 | 55 | /** 56 | * @return Number of bits in a sample of this SoundBuffer data (8 or 16) 57 | */ 58 | int SampleBits() const; 59 | 60 | /** 61 | * @return Number of bytes in a sample of this SoundBuffer data (1 or 2) 62 | */ 63 | int SampleBytes() const; 64 | 65 | /** 66 | * @return Number of sound channels in the SoundBuffer data (1 or 2) 67 | */ 68 | int Channels() const; 69 | 70 | /** 71 | * @return Size of a full sample block in bytes [LL][RR] (1 to 4) 72 | */ 73 | int FullSampleSize() const; 74 | 75 | /** 76 | * @return Size of this SoundBuffer or SoundStream in BYTES 77 | */ 78 | int SizeBytes() const; 79 | 80 | /** 81 | * @return Number of Bytes Per Second for this audio data (Frequency * Channels * SampleBytes) 82 | */ 83 | int BytesPerSecond() const; 84 | 85 | /** 86 | * @return Size of this SoundBuffer in PCM SAMPLES 87 | */ 88 | virtual int Size() const; 89 | 90 | /** 91 | * @return Number of SoundObjects that still reference this SoundBuffer. 92 | */ 93 | int getReferanceCount() const; 94 | 95 | /** 96 | * @return TRUE if this object is a Sound stream 97 | */ 98 | virtual bool IsStream() const; 99 | 100 | /** 101 | * @return Wave format descriptor for this buffer 102 | */ 103 | const WAVEFORMATEX* WaveFormat() const; 104 | 105 | /** 106 | * @return Unique hash to distinguish between different Wave formats 107 | */ 108 | unsigned WaveFormatHash() const; 109 | 110 | /** 111 | * Loads this SoundBuffer with data found in the specified file. 112 | * Supported formats: .wav .mp3 113 | * @param file Sound file to load 114 | * @return TRUE if loading succeeded and a valid buffer was created. 115 | */ 116 | virtual bool Load(const fs::path& file); 117 | 118 | /** 119 | * Tries to release the underlying sound buffer and free the memory. 120 | * @note This function will fail if refCount > 0. This means there are SoundObjects still using this SoundBuffer 121 | * @return TRUE if SoundBuffer data was freed, FALSE if SoundBuffer is still used by a SoundObject. 122 | */ 123 | virtual bool Unload(); 124 | 125 | /** 126 | * Binds a specific source to this SoundBuffer and increases the refCount. 127 | * @param so SoundObject to bind to this SoundBuffer. 128 | * @return FALSE if the binding failed. TODO: POSSIBLE REASONS? 129 | */ 130 | virtual bool BindSource(SoundObject* so); 131 | 132 | /** 133 | * Unbinds a specific source from this SoundBuffer and decreases the refCount. 134 | * @param so SoundObject to unbind from this SoundBuffer. 135 | * @return FALSE if the unbinding failed. TODO: POSSIBLE REASONS? 136 | */ 137 | virtual bool UnbindSource(SoundObject* so); 138 | 139 | /** 140 | * Resets the buffer in the context of the specified SoundObject 141 | * @note Calls ResetStream on AudioStreams. 142 | * @param so SoundObject to reset this buffer for 143 | * @return TRUE if reset was successful 144 | */ 145 | virtual bool ResetBuffer(SoundObject* so); 146 | }; 147 | } -------------------------------------------------------------------------------- /Include/OneSound/SoundType/SoundObject.h: -------------------------------------------------------------------------------- 1 | /* 2 | * OneSound - Modern C++17 audio library for Windows OS with XAudio2 API 3 | * Copyright ⓒ 2018 Valentyn Bondarenko. All rights reserved. 4 | * License: https://github.com/weelhelmer/OneSound/master/LICENSE 5 | */ 6 | 7 | #pragma once 8 | 9 | #include "OneSound\Export.h" 10 | 11 | #include "OneSound\SoundType\SoundObjectState.h" 12 | 13 | #include "OneSound\SoundType\SoundBuffer.h" 14 | 15 | namespace onesnd 16 | { 17 | /** 18 | * Base for all the 3D and Ambient sound objects 19 | */ 20 | class ONE_SOUND_API SoundObject 21 | { 22 | protected: 23 | std::shared_ptr sound; // sound buffer/stream to use 24 | 25 | IXAudio2SourceVoice* source; // the sound source generator (interfaces XAudio2 to generate waveforms) 26 | SoundObjectState* state; // Holds and manages the current state of a SoundObject 27 | 28 | X3DAUDIO_EMITTER Emitter; // 3D sound emitter data (this object) 29 | 30 | /** 31 | * Creates an uninitialzed empty SoundObject 32 | */ 33 | SoundObject(); 34 | /** 35 | * Creates a soundobject with an attached buffer 36 | * @param sound SoundBuffer this object uses for playing sounds 37 | * @param loop True if sound looping is wished 38 | * @param play True if sound should start playing immediatelly 39 | */ 40 | SoundObject(const std::shared_ptr& sound, const bool& loop = false, const bool& play = false, const float& volume = 1.f); 41 | ~SoundObject(); // unhooks any sounds and frees resources 42 | 43 | public: 44 | /** 45 | * Sets the SoundBuffer or SoundStream for this SoundObject. Set NULL to remove and unbind the SoundBuffer. 46 | * @param sound Sound to bind to this object. Can be NULL to unbind sounds from this object. 47 | * @param loop [optional] Sets the sound looping or non-looping. Streams cannot be looped. 48 | */ 49 | void setSound(const std::shared_ptr& sound, const bool& loop = false, const bool& play = false, const float& volume = 1.f); 50 | 51 | /** 52 | * @return Current soundbuffer set to this soundobject 53 | */ 54 | inline std::shared_ptr getSound() const { return sound; } 55 | 56 | inline IXAudio2SourceVoice* getSource() const { return source; } 57 | 58 | /** 59 | * @return TRUE if this SoundObject has an attached SoundStream that can be streamed. 60 | */ 61 | bool isStreamable() const; 62 | 63 | /** 64 | * @return TRUE if this SoundObject is streamable and the End Of Stream was reached. 65 | */ 66 | bool isEOS() const; 67 | 68 | /** 69 | * Starts playing the sound. If the sound is already playing, it is rewinded and played again from the start. 70 | */ 71 | void play(); 72 | 73 | /** 74 | * Starts playing a new sound. Any older playing sounds will be stopped and replaced with this sound. 75 | * @param sound SoundBuffer or SoundStream to start playing 76 | * @param loop [false] Sets if the sound is looping or not. Streams are never loopable. 77 | */ 78 | void play(const std::shared_ptr& sound, const bool& loop = false, const bool& play = false, const float& volume = 1.f); 79 | 80 | /** 81 | * Stops playing the sound and unloads streaming buffers. 82 | */ 83 | void stop(); 84 | 85 | /** 86 | * Temporarily pauses sound playback and doesn't unload any streaming buffers. 87 | */ 88 | void pause(); 89 | 90 | /** 91 | * If current status is Playing, then this rewinds to start of the soundbuffer/stream and starts playing again. 92 | * If current status is NOT playing, then any stream resources are freed and the object is reset. 93 | */ 94 | void rewind(); 95 | 96 | /** 97 | * @return TRUE if the sound source is PLAYING. 98 | */ 99 | bool isPlaying() const; 100 | 101 | /** 102 | * @return TRUE if the sound source is STOPPED. 103 | */ 104 | bool isStopped() const; 105 | 106 | /** 107 | * @return TRUE if the sound source is PAUSED. 108 | */ 109 | bool isPaused() const; 110 | 111 | /** 112 | * @return TRUE if the sound source is at the beginning of the sound buffer. 113 | */ 114 | bool isInitial() const; 115 | 116 | /** 117 | * @return TRUE if the sound source is in LOOPING mode. 118 | */ 119 | bool isLooping() const; 120 | 121 | /** 122 | * Sets the looping mode of the sound source. 123 | */ 124 | void setLooping(const bool& looping); 125 | 126 | /** 127 | * Indicates the gain (volume amplification) applied. Range [0.0f .. 1.0f] 128 | * Each division by 2 equals an attenuation of -6dB. Each multiplicaton with 2 equals an amplification of +6dB. 129 | * A value of 0.0 is meaningless with respect to a logarithmic scale; it is interpreted as zero volume - the channel is effectively disabled. 130 | * @param gain Gain value between 0.0..1.0 131 | */ 132 | void setVolume(const float& gain); 133 | 134 | /** 135 | * @return Current gain value of this source 136 | */ 137 | float getVolume() const; 138 | 139 | /** 140 | * @return Gets the current playback position in the SoundBuffer or SoundStream in SAMPLES 141 | */ 142 | int getPlaybackPosition() const; 143 | 144 | /** 145 | * Sets the playback position of the underlying SoundBuffer or SoundStream in SAMPLES 146 | * @param seekpos Position in SAMPLES where to seek in the SoundBuffer or SoundStream [0..PlaybackSize] 147 | */ 148 | void setPlaybackPosition(int seekpos); 149 | 150 | /** 151 | * @return Playback size of the underlying SoundBuffer or SoundStream in SAMPLES 152 | */ 153 | int getPlaybackSize() const; 154 | 155 | /** 156 | * @return Number of samples processed every second (aka SampleRate or Frequency) 157 | */ 158 | int getSamplesPerSecond() const; 159 | }; 160 | } -------------------------------------------------------------------------------- /Include/OneSound/SoundType/SoundObjectState.h: -------------------------------------------------------------------------------- 1 | /* 2 | * OneSound - Modern C++17 audio library for Windows OS with XAudio2 API 3 | * Copyright ⓒ 2018 Valentyn Bondarenko. All rights reserved. 4 | * License: https://github.com/weelhelmer/OneSound/master/LICENSE 5 | */ 6 | 7 | #pragma once 8 | 9 | #include "OneSound\XAudio2Device.h" 10 | 11 | namespace onesnd 12 | { 13 | class SoundObject; 14 | 15 | struct SoundObjectState : public IXAudio2VoiceCallback 16 | { 17 | SoundObject* sound; 18 | bool isInitial; // is the Sound object Rewinded to its initial position? 19 | bool isPlaying = false; // is the Voice digesting buffers? 20 | bool isLoopable; // should this sound act as a loopable sound? 21 | bool isPaused; // currently paused? 22 | XABuffer shallow; // a shallow buffer reference (no actual data) 23 | 24 | SoundObjectState(SoundObject* so) : 25 | sound(so), 26 | isInitial(false), 27 | isPlaying(false), 28 | isLoopable(false), isPaused(false) 29 | { } 30 | 31 | void __stdcall OnStreamEnd() override; 32 | void __stdcall OnBufferEnd(void* ctx) override; 33 | 34 | void __stdcall OnVoiceProcessingPassStart(UINT32 samplesRequired) override 35 | { } 36 | void __stdcall OnVoiceProcessingPassEnd() override 37 | { } 38 | void __stdcall OnBufferStart(void* ctx) override 39 | { } 40 | void __stdcall OnLoopEnd(void* ctx) override 41 | { } 42 | void __stdcall OnVoiceError(void* ctx, HRESULT error) override 43 | { } 44 | }; 45 | } -------------------------------------------------------------------------------- /Include/OneSound/SoundType/SoundStream.h: -------------------------------------------------------------------------------- 1 | /* 2 | * OneSound - Modern C++17 audio library for Windows OS with XAudio2 API 3 | * Copyright ⓒ 2018 Valentyn Bondarenko. All rights reserved. 4 | * License: https://github.com/weelhelmer/OneSound/master/LICENSE 5 | */ 6 | 7 | #pragma once 8 | 9 | #include "OneSound\Export.h" 10 | 11 | #include "OneSound\Utility.h" 12 | 13 | #include "OneSound\SoundType\SoundBuffer.h" 14 | 15 | namespace onesnd 16 | { 17 | /** 18 | * SoundStream stream audio data from a file source. 19 | * Extremely useful for large file playback. Even a 4m long mp3 can take over 40mb of ram. 20 | * Multiple sources can be bound to this stream. 21 | */ 22 | class ONE_SOUND_API SoundStream : public SoundBuffer 23 | { 24 | protected: 25 | struct SO_ENTRY 26 | { 27 | SoundObject* obj; 28 | int base; // current PCM block offset 29 | int next; // the next PCM block offset to load 30 | 31 | XABuffer* front; // currently playing buffer - frontbuffer 32 | XABuffer* back; // enqueued backbuffer 33 | bool busy; // the stream is busy on an internal operation, all other operations are ignored 34 | 35 | inline SO_ENTRY(SoundObject* obj) : 36 | obj(obj), 37 | base(0), 38 | next(0), 39 | front(0), 40 | back(0), 41 | busy(false) 42 | { } 43 | }; 44 | 45 | std::vector alSources; // bound sources 46 | AudioStream* alStream; // streamer object 47 | 48 | public: 49 | /** 50 | * Creates a new SoundsStream object 51 | */ 52 | SoundStream(); 53 | 54 | /** 55 | * Creates a new SoundStream object and loads the specified sound file 56 | * @param file Path to the sound file to load 57 | */ 58 | SoundStream(const fs::path& file); 59 | 60 | /** 61 | * Destroys and unloads any resources held 62 | */ 63 | virtual ~SoundStream(); 64 | 65 | /** 66 | * @return Size of this SoundStream in PCM SAMPLES 67 | */ 68 | virtual int Size() const override; 69 | 70 | /** 71 | * @return TRUE if this object is a Sound stream 72 | */ 73 | virtual bool IsStream() const override; 74 | 75 | /** 76 | * Initializes this SoundStream with data found in the specified file. 77 | * Supported formats: .wav .mp3 78 | * @param file Sound file to load 79 | * @return TRUE if loading succeeded and a stream was initialized. 80 | */ 81 | virtual bool Load(const fs::path& file) override; 82 | 83 | /** 84 | * Tries to release the underlying sound buffers and free the memory. 85 | * @note This function will fail if refCount > 0. This means there are SoundObjects still using this SoundStream 86 | * @return TRUE if SoundStream data was freed, FALSE if SoundStream is still used by a SoundObject. 87 | */ 88 | virtual bool Unload() override; 89 | 90 | /** 91 | * Binds a specific source to this SoundStream and increases the refCount. 92 | * @param so SoundObject to bind to this SoundStream. 93 | * @return FALSE if the binding failed. TODO: POSSIBLE REASONS? 94 | */ 95 | virtual bool BindSource(SoundObject* so) override; 96 | 97 | /** 98 | * Unbinds a specific source from this SoundStream and decreases the refCount. 99 | * @param so SoundObject to unbind from this SoundStream. 100 | * @return FALSE if the unbinding failed. TODO: POSSIBLE REASONS? 101 | */ 102 | virtual bool UnbindSource(SoundObject* so) override; 103 | 104 | /** 105 | * Resets the buffer in the context of the specified SoundObject 106 | * @note Calls ResetStream on AudioStreams. 107 | * @param so SoundObject to reset this buffer for 108 | * @return TRUE if reset was successful 109 | */ 110 | virtual bool ResetBuffer(SoundObject* so) override; 111 | 112 | /** 113 | * Resets the stream by unloading previous buffers and requeuing the first two buffers. 114 | * @param so SoundObject to reset the stream for 115 | * @return TRUE if stream was successfully reloaded 116 | */ 117 | bool ResetStream(SoundObject* so); 118 | 119 | /** 120 | * Streams the next Buffer block from the stream. 121 | * @param so Specific SoundObject to stream with. 122 | * @return TRUE if a buffer was streamed. FALSE if EOS() or stream is busy. 123 | */ 124 | bool StreamNext(SoundObject* so); 125 | 126 | /** 127 | * @param so Specific SoundObject to check for end of stream 128 | * @return TRUE if End of Stream was reached or if there is no stream loaded 129 | */ 130 | bool IsEOS(const SoundObject* so) const; 131 | 132 | /** 133 | * @param so SoundObject to query index of 134 | * @return A valid pointer if this SoundObject is bound. Otherwise NULL. 135 | */ 136 | SO_ENTRY* GetSOEntry(const SoundObject* so) const; 137 | 138 | /** 139 | * Seeks to the specified sample position in the stream. 140 | * @note The SoundObject will stop playing and must be manually restarted! 141 | * @param so SoundObject to perform seek on 142 | * @param samplepos Position in the stream in samples [0..SoundStream::Size()] 143 | */ 144 | void Seek(SoundObject* so, int samplepos); 145 | 146 | protected: 147 | /** 148 | * Internal stream function. 149 | * @param soe SoundObject Entry to stream 150 | * @return TRUE if a buffer was streamed 151 | */ 152 | bool StreamNext(SO_ENTRY& soe); 153 | 154 | /** 155 | * [internal] Load streaming data into the specified SoundObject 156 | * at the optionally specified streamposition. 157 | * @param so SO_ENTRY handle to queue with stream data 158 | * @param streampos [optional] PCM byte position in stream where to seek data from. 159 | * If unspecified (default -1), stream will use the current streampos 160 | */ 161 | bool LoadStreamData(SO_ENTRY& so, int streampos = -1); 162 | 163 | /** 164 | * [internal] Unloads all queued data for the specified SoundObject 165 | * @param so SO_ENTRY handle to unqueue and unload data for 166 | */ 167 | void ClearStreamData(SO_ENTRY& so); 168 | }; 169 | } 170 | -------------------------------------------------------------------------------- /Include/OneSound/StreamType/AudioStream.h: -------------------------------------------------------------------------------- 1 | /* 2 | * OneSound - Modern C++17 audio library for Windows OS with XAudio2 API 3 | * Copyright ⓒ 2018 Valentyn Bondarenko. All rights reserved. 4 | * License: https://github.com/weelhelmer/OneSound/master/LICENSE 5 | */ 6 | 7 | #pragma once 8 | 9 | #include "OneSound\Export.h" 10 | 11 | #include 12 | 13 | namespace onesnd 14 | { 15 | /** 16 | * Basic AudioStreamer class for streaming audio data. 17 | * Data is decoded and presented in simple wave PCM format. 18 | * 19 | * The base implementation is actually the WAV streamer - other implementations 20 | * extend the virtual methods. 21 | */ 22 | class ONE_SOUND_API AudioStream 23 | { 24 | protected: 25 | int* FileHandle; // internally interpreted file handle 26 | int stream_size; // size of the audiostream in PCM bytes, not File bytes 27 | int stream_position; // current stream position in PCM bytes 28 | unsigned int sample_rate; // frequency (or rate) of the sound data, usually 20500 or 41000 (20.5kHz / 41kHz) 29 | unsigned char NumChannels; // number of channels in a sample block, usually 1 or 2 (Mono / Stereo) 30 | unsigned char SampleSize; // size (in bytes) of a sample, usually 1 to 2 bytes (8bit:1 / 16bit:2) 31 | unsigned char SampleBlockSize; // size (in bytes) of a sample block: SampleSize * NumChannels 32 | public: 33 | /** 34 | * Creates a new uninitialized AudioStreamer. 35 | * You should call OpenStream(file) to initialize the stream. 36 | */ 37 | AudioStream(); 38 | 39 | /** 40 | * Creates and Opens a new AudioStreamer. 41 | * @param file Full path to the audiofile to stream 42 | */ 43 | AudioStream(const fs::path& file); 44 | 45 | /** 46 | * Destroys the AudioStream and frees all held resources 47 | */ 48 | virtual ~AudioStream(); 49 | 50 | 51 | 52 | 53 | /** 54 | * Opens a new stream for reading. 55 | * @param file Audio file to open 56 | * @return TRUE if stream is successfully opened and initialized. FALSE if the stream open failed or it's already opened. 57 | */ 58 | virtual bool OpenStream(const fs::path& file); 59 | 60 | /** 61 | * Closes the stream and releases all resources held. 62 | */ 63 | virtual void CloseStream(); 64 | 65 | /** 66 | * Reads some Audio data from the underlying stream. 67 | * Audio data is decoded into PCM format, suitable for OpenAL. 68 | * @param dstBuffer Destination buffer that receives the data 69 | * @param dstSize Number of bytes to read. 64KB is good for streaming (gives ~1.5s of playback sound). 70 | * @return Number of bytes read. 0 if stream is uninitialized or end of stream reached. 71 | */ 72 | virtual int ReadSome(void* dstBuffer, int dstSize); 73 | 74 | /** 75 | * Seeks to the appropriate byte position in the stream. 76 | * This value is between: [0...StreamSize] 77 | * @param streampos Position in the stream to seek to in BYTES 78 | * @return The actual position where seeked, or 0 if out of bounds (this also means the stream was reset to 0). 79 | */ 80 | virtual unsigned int Seek(unsigned int streampos); 81 | 82 | /** 83 | * @return TRUE if the Stream has been opened. FALSE if it remains unopened. 84 | */ 85 | inline bool IsOpen() const 86 | { 87 | return FileHandle ? true : false; 88 | } 89 | 90 | /** 91 | * Resets the stream position to the beginning. 92 | */ 93 | inline void ResetStream() 94 | { 95 | Seek(0); 96 | } 97 | 98 | /** 99 | * @return Size of the stream in PCM bytes, not File bytes 100 | */ 101 | inline int Size() const 102 | { 103 | return stream_size; 104 | } 105 | 106 | /** 107 | * @return Position of the stream in PCM bytes 108 | */ 109 | inline int Position() const 110 | { 111 | return stream_position; 112 | } 113 | 114 | /** 115 | * @return Number of PCM bytes still available in the stream 116 | */ 117 | inline int Available() const 118 | { 119 | return stream_size - stream_position; 120 | } 121 | 122 | /** 123 | * @return TRUE if End Of Stream was reached 124 | */ 125 | inline bool IsEOS() const 126 | { 127 | return stream_position == stream_size; 128 | } 129 | 130 | /** 131 | * @return Playback frequency specified by the streamer. Usually 20500 or 41000 (20.5kHz / 41kHz) 132 | */ 133 | inline int Frequency() const 134 | { 135 | return int(sample_rate); 136 | } 137 | 138 | /** 139 | * @return Number of channels in this AudioStream. Usually 1 or 2 (Mono / Stereo) 140 | */ 141 | inline int Channels() const 142 | { 143 | return int(NumChannels); 144 | } 145 | 146 | /** 147 | * @return Size (in bytes) of a single channel sample. Usually 1 to 2 bytes (8bit:1 / 16bit:2) 148 | */ 149 | inline int SingleSampleSize() const 150 | { 151 | return int(SampleSize); 152 | } 153 | 154 | /** 155 | * @return Size (in bytes) of a full all channels sample. Usually 1 to 4 bytes ( Channels * SingleSampleSize : [LL][RR] ) 156 | */ 157 | inline int FullSampleBlockSize() const 158 | { 159 | return int(SampleBlockSize); 160 | } 161 | 162 | /** 163 | * @return Number of Bytes Per Second for the audio data in this stream 164 | */ 165 | inline int BytesPerSecond() const 166 | { 167 | return int(sample_rate) * int(SampleBlockSize); 168 | } 169 | }; 170 | 171 | /** 172 | * Automatically creates a specific AudioStreamer 173 | * instance depending on the specified file extension 174 | * or by the file header format if extension not specified. 175 | * @note The Stream is not Opened! You must do it manually. 176 | * @param file Audio file string 177 | * @return New dynamic instance of a specific AudioStreamer. Or NULL if the file format cannot be detected. 178 | */ 179 | AudioStream* createAudioStream(const char* file); 180 | 181 | /** 182 | * Automatically creates a specific AudioStreamer 183 | * instance depending on the specified file extension 184 | * or by the file header format if extension not specified. 185 | * 186 | * This initializes an already existing AudioStream instance. 187 | * 188 | * @note The Stream is not Opened! You must do it manually. 189 | * @param as AudioStream instance to create the streamer into. Can be any other AudioStream instance. 190 | * @param file Audio file string 191 | * @return TRUE if the instance was created. 192 | */ 193 | bool createAudioStream(AudioStream* as, const char* file); 194 | } -------------------------------------------------------------------------------- /Include/OneSound/StreamType/MP3Stream.h: -------------------------------------------------------------------------------- 1 | /* 2 | * OneSound - Modern C++17 audio library for Windows OS with XAudio2 API 3 | * Copyright ⓒ 2018 Valentyn Bondarenko. All rights reserved. 4 | * License: https://github.com/weelhelmer/OneSound/master/LICENSE 5 | */ 6 | 7 | #pragma once 8 | 9 | #include "OneSound\Export.h" 10 | 11 | #include "OneSound\StreamType\AudioStream.h" 12 | 13 | namespace onesnd 14 | { 15 | /** 16 | * AudioStream for streaming file in WAV format. 17 | * The stream is decoded into PCM format. 18 | */ 19 | class MP3Stream : public AudioStream 20 | { 21 | public: 22 | /** 23 | * Creates a new unitialized MP3 AudioStreamer. 24 | * You should call OpenStream(file) to initialize the stream. 25 | */ 26 | MP3Stream(); 27 | 28 | /** 29 | * Creates and Initializes a new MP3 AudioStreamer. 30 | */ 31 | MP3Stream(const fs::path& file); 32 | 33 | /** 34 | * Destroys the MP3 AudioStream and frees all held resources 35 | */ 36 | virtual ~MP3Stream(); 37 | 38 | 39 | 40 | /** 41 | * Opens a new stream for reading. 42 | * @param file Audio file to open 43 | * @return TRUE if stream is successfully opened and initialized. FALSE if the stream open failed or its already open. 44 | */ 45 | virtual bool OpenStream(const fs::path& file); 46 | 47 | /** 48 | * Closes the stream and releases all resources held. 49 | */ 50 | virtual void CloseStream(); 51 | 52 | /** 53 | * Reads some Audio data from the underlying stream. 54 | * Audio data is decoded into PCM format, suitable for OpenAL. 55 | * @param dstBuffer Destination buffer that receives the data 56 | * @param dstSize Number of bytes to read. 64KB is good for streaming (gives ~1.5s of playback sound). 57 | * @return Number of bytes read. 0 if stream is uninitialized or end of stream reached. 58 | */ 59 | virtual int ReadSome(void* dstBuffer, int dstSize); 60 | 61 | /** 62 | * Seeks to the appropriate byte position in the stream. 63 | * This value is between: [0...StreamSize] 64 | * @param streampos Position in the stream to seek to in BYTES 65 | * @return The actual position where seeked, or 0 if out of bounds (this also means the stream was reset to 0). 66 | */ 67 | virtual unsigned int Seek(unsigned int streampos); 68 | }; 69 | } -------------------------------------------------------------------------------- /Include/OneSound/StreamType/OGGStream.h: -------------------------------------------------------------------------------- 1 | /* 2 | * OneSound - Modern C++17 audio library for Windows OS with XAudio2 API 3 | * Copyright ⓒ 2018 Valentyn Bondarenko. All rights reserved. 4 | * License: https://github.com/weelhelmer/OneSound/master/LICENSE 5 | */ 6 | 7 | #pragma once 8 | 9 | #include "OneSound\Export.h" 10 | 11 | #include "OneSound\StreamType\AudioStream.h" 12 | 13 | namespace onesnd 14 | { 15 | /** 16 | * AudioStream for streaming file in WAV format. 17 | * The stream is decoded into PCM format. 18 | */ 19 | class OGGStream : public AudioStream 20 | { 21 | public: 22 | /** 23 | * Creates a new unitialized OGG AudioStreamer. 24 | * You should call OpenStream(file) to initialize the stream. 25 | */ 26 | OGGStream(); 27 | 28 | /** 29 | * Creates and Initializes a new OGG AudioStreamer. 30 | */ 31 | OGGStream(const fs::path& file); 32 | 33 | /** 34 | * Destroys the AudioStream and frees all held resources 35 | */ 36 | virtual ~OGGStream(); 37 | 38 | 39 | /** 40 | * Opens a new stream for reading. 41 | * @param file Audio file to open 42 | * @return TRUE if stream is successfully opened and initialized. FALSE if the stream open failed or its already open. 43 | */ 44 | virtual bool OpenStream(const fs::path& file); 45 | 46 | /** 47 | * Closes the stream and releases all resources held. 48 | */ 49 | virtual void CloseStream(); 50 | 51 | /** 52 | * Reads some Audio data from the underlying stream. 53 | * Audio data is decoded into PCM format, suitable for OpenAL. 54 | * @param dstBuffer Destination buffer that receives the data 55 | * @param dstSize Number of bytes to read. 64KB is good for streaming (gives ~1.5s of playback sound). 56 | * @return Number of bytes read. 0 if stream is uninitialized or end of stream reached. 57 | */ 58 | virtual int ReadSome(void* dstBuffer, int dstSize); 59 | 60 | /** 61 | * Seeks to the appropriate byte position in the stream. 62 | * This value is between: [0...StreamSize] 63 | * @param streampos Position in the stream to seek to in BYTES 64 | * @return The actual position where seeked, or 0 if out of bounds (this also means the stream was reset to 0). 65 | */ 66 | virtual unsigned int Seek(unsigned int streampos); 67 | }; 68 | } -------------------------------------------------------------------------------- /Include/OneSound/StreamType/WAVStream.h: -------------------------------------------------------------------------------- 1 | /* 2 | * OneSound - Modern C++17 audio library for Windows OS with XAudio2 API 3 | * Copyright ⓒ 2018 Valentyn Bondarenko. All rights reserved. 4 | * License: https://github.com/weelhelmer/OneSound/master/LICENSE 5 | */ 6 | 7 | #pragma once 8 | 9 | #include "OneSound\Export.h" 10 | 11 | #include "OneSound\StreamType\AudioStream.h" 12 | 13 | namespace onesnd 14 | { 15 | class ONE_SOUND_API WAVStream : public AudioStream 16 | { 17 | public: 18 | /** 19 | * Creates a new unitialized WAV AudioStreamer. 20 | * You should call OpenStream(file) to initialize the stream. 21 | */ 22 | inline WAVStream() : AudioStream() 23 | { } 24 | 25 | /** 26 | * Creates and Initializes a new WAV AudioStreamer. 27 | */ 28 | inline WAVStream(const fs::path& file) : AudioStream(file) 29 | { } 30 | }; 31 | } -------------------------------------------------------------------------------- /Include/OneSound/Utility.h: -------------------------------------------------------------------------------- 1 | /* 2 | * OneSound - Modern C++17 audio library for Windows OS with XAudio2 API 3 | * Copyright ⓒ 2018 Valentyn Bondarenko. All rights reserved. 4 | * License: https://github.com/weelhelmer/OneSound/master/LICENSE 5 | */ 6 | 7 | #pragma once 8 | 9 | #pragma warning (disable : 4251) 10 | #pragma warning (disable : 4172) 11 | 12 | #include 13 | 14 | #include 15 | #include 16 | #include 17 | 18 | namespace onesnd 19 | { 20 | //// Low Latency File IO straight to Windows API, with no beating around the bush 21 | 22 | // opens a file with read-only rights 23 | inline void* file_open_ro(const char* filename) 24 | { 25 | void* fh = CreateFileA(filename, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); 26 | if (fh == INVALID_HANDLE_VALUE) 27 | return NULL; 28 | 29 | return fh; 30 | } 31 | // close the file 32 | inline int file_close(void* handle) 33 | { 34 | CloseHandle(handle); 35 | return 0; 36 | } 37 | // reads bytes from opened file 38 | inline int file_read(void* handle, void* dst, size_t size) 39 | { 40 | DWORD bytesRead; 41 | ReadFile(handle, dst, size, &bytesRead, NULL); 42 | return (int)bytesRead; 43 | } 44 | // seeks the file pointer 45 | inline off_t file_seek(void* handle, off_t offset, int whence) 46 | { 47 | return SetFilePointer(handle, offset, NULL, whence); 48 | } 49 | // tells the current file position 50 | inline off_t file_tell(void* handle) 51 | { 52 | return SetFilePointer(handle, 0, NULL, FILE_CURRENT); 53 | } 54 | 55 | ///------ 56 | using namespace std::string_literals; 57 | namespace fs = std::experimental::filesystem; 58 | 59 | template 60 | inline void loadProcess(Process* var, const char* process_name, HMODULE dll_handle) 61 | { 62 | *var = reinterpret_cast(GetProcAddress(dll_handle, process_name)); 63 | } 64 | } 65 | -------------------------------------------------------------------------------- /Include/OneSound/XAudio2Device.h: -------------------------------------------------------------------------------- 1 | /* 2 | * OneSound - Modern C++17 audio library for Windows OS with XAudio2 API 3 | * Copyright ⓒ 2018 Valentyn Bondarenko. All rights reserved. 4 | * License: https://github.com/weelhelmer/OneSound/master/LICENSE 5 | */ 6 | 7 | #pragma once 8 | 9 | #include "OneSound\Export.h" 10 | 11 | #include "..\ThirdParty\Include\XAudio2_7\XAudio2.h" 12 | #include "..\ThirdParty\Include\XAudio2_7\X3DAudio.h" 13 | 14 | #if defined (_WIN32) 15 | # pragma comment(lib, "../ThirdParty/X3DAudio86.lib") 16 | #elif not defined (_WIN32) 17 | # pragma comment(lib, "../ThirdParty/X3DAudio64.lib") 18 | #endif 19 | 20 | namespace onesnd 21 | { 22 | class SoundBuffer; 23 | class AudioStream; 24 | 25 | class XAudio2Device 26 | { 27 | public: 28 | XAudio2Device() = default; 29 | ~XAudio2Device() = default; 30 | 31 | public: 32 | static XAudio2Device& instance() 33 | { 34 | static XAudio2Device xaudio2_device; 35 | return xaudio2_device; 36 | } 37 | 38 | public: 39 | void initialize(); 40 | void finalize(); 41 | 42 | IXAudio2* getEngine() const { return xEngine; } 43 | IXAudio2MasteringVoice* getMaster() const { return xMaster; } 44 | 45 | private: 46 | IXAudio2* xEngine; 47 | IXAudio2MasteringVoice* xMaster; 48 | X3DAUDIO_HANDLE x3DAudioHandle; 49 | X3DAUDIO_LISTENER xListener; 50 | }; 51 | 52 | struct XABuffer : XAUDIO2_BUFFER 53 | { 54 | WAVEFORMATEX wf; // wave format descriptor 55 | int nBytesPerSample; // number of bytes per single audio sample (1 or 2 bytes) 56 | int nPCMSamples; // number of PCM samples in the entire buffer 57 | unsigned wfHash; // waveformat pseudo-hash 58 | 59 | static XABuffer* create(SoundBuffer* ctx, int size, AudioStream* strm, int* pos = nullptr); 60 | static void destroy(XABuffer*& buffer); 61 | 62 | static void stream(XABuffer* buffer, AudioStream* strm, int* pos = nullptr); 63 | 64 | static int getBuffersQueued(IXAudio2SourceVoice* source); 65 | }; 66 | } -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright ⓒ 2018 Valentyn Bondarenko 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | OneSound 2 | ========== 3 | Modern library for audio playback supporting 3 common audio formats. The software provides a **high-performance** audio sources, it is written in C++17. The library is generally suited for a game engine or media applications. 4 | 5 | Overview 6 | -------- 7 | 8 | - **Version**: 1.0.5 9 | - **License**: [MIT](https://github.com/bondarenko-me/OneSound/master/LICENSE) 10 | - **Status**: Alpha 11 | 12 | Supported Platforms 13 | ------------------- 14 | - **Windows** 7 15 | - **Windows** 8/8.1 16 | - **Windows** 10 17 | 18 | Used Technology 19 | --------------- 20 | - **XAudio2** 21 | 22 | Supported Audio File Formats 23 | ---------------------- 24 | - **WAV** (Waveform Audio File Format) Playing buffers/Streaming 25 | - **MP3** (MPEG-1 Audio Layer 3) Playing buffers/Streaming 26 | - **OGG** (Ogg-Vorbis) Playing buffers/Streaming 27 | 28 | Dependencies 29 | --------------- 30 | - [**OGG Vorbis**](https://github.com/xiph/vorbis) 31 | - [**MPG123**](https://github.com/georgi/mpg123) 32 | 33 | Getting Started 34 | --------------- 35 | 36 | Play a sound with less code as possible: 37 | 38 | ```cpp 39 | #include 40 | #include 41 | 42 | using namespace std; 43 | using namespace onesnd; 44 | 45 | int main() 46 | { 47 | // Create OneSound that initialize XAudio2 Device. 48 | auto one_sound = make_unique(); 49 | 50 | // Create a sound that not loops, plays at once with 75% volume. 51 | auto sound_1 = make_unique(make_unique("Sound\\shot.wav"), 52 | false, // Looping 53 | true, // Playing 54 | 0.75f); // Volume 55 | 56 | cout << "Press any key to quit: "; 57 | auto i = char(); 58 | cin >> i; 59 | 60 | return 0; 61 | } 62 | ``` 63 | -------------------------------------------------------------------------------- /Source/Listener.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * OneSound - Modern C++17 audio library for Windows OS with XAudio2 API 3 | * Copyright ⓒ 2018 Valentyn Bondarenko. All rights reserved. 4 | * License: https://github.com/weelhelmer/OneSound/master/LICENSE 5 | */ 6 | 7 | #include "OneSound\Listener.h" 8 | 9 | #include "OneSound\XAudio2Device.h" 10 | 11 | namespace onesnd 12 | { 13 | void Listener::setVolume(float volume) 14 | { 15 | if (volume < 0.f) 16 | volume = 0.f; 17 | else if (volume > 1.f) 18 | volume = 1.f; 19 | else 20 | XAudio2Device::instance().getMaster()->SetVolume(volume); 21 | } 22 | 23 | float Listener::getVolume() const 24 | { 25 | float value; 26 | XAudio2Device::instance().getMaster()->GetVolume(&value); 27 | 28 | return value; 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /Source/OneSound.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * OneSound - Modern C++17 audio library for Windows OS with XAudio2 API 3 | * Copyright ⓒ 2018 Valentyn Bondarenko. All rights reserved. 4 | * License: https://github.com/weelhelmer/OneSound/master/LICENSE 5 | */ 6 | 7 | #include "OneSound\OneSound.h" 8 | 9 | namespace onesnd 10 | { 11 | OneSound::OneSound(const bool& has_initialize) 12 | { 13 | if(has_initialize) 14 | this->initialize(); 15 | }; 16 | 17 | XAUDIO2_PERFORMANCE_DATA OneSound::getPerfomanceData() const 18 | { 19 | XAUDIO2_PERFORMANCE_DATA pd; 20 | XAudio2Device::instance().getEngine()->GetPerformanceData(&pd); 21 | 22 | return pd; 23 | } 24 | 25 | OneSound::~OneSound() 26 | { 27 | this->finalize(); 28 | } 29 | 30 | void OneSound::initialize() const 31 | { 32 | if (!XAudio2Device::instance().getEngine()) 33 | XAudio2Device::instance().initialize(); 34 | } 35 | 36 | void OneSound::finalize() const 37 | { 38 | if (XAudio2Device::instance().getEngine()) 39 | XAudio2Device::instance().finalize(); 40 | } 41 | 42 | unsigned long long OneSound::getLibraryVersion() const 43 | { 44 | return 1ull; 45 | } 46 | 47 | std::string OneSound::getLibraryVersionStr() const 48 | { 49 | return "1.0"s; 50 | } 51 | 52 | std::string OneSound::getLibraryStatus() const 53 | { 54 | return "Alpha"s; 55 | } 56 | 57 | std::string OneSound::getLibraryName() const 58 | { 59 | return "OneSound"s; 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /Source/SoundType/Sound2D.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * OneSound - Modern C++17 audio library for Windows OS with XAudio2 API 3 | * Copyright ⓒ 2018 Valentyn Bondarenko. All rights reserved. 4 | * License: https://github.com/weelhelmer/OneSound/master/LICENSE 5 | */ 6 | 7 | #include "OneSound\SoundType\Sound2D.h" 8 | 9 | namespace onesnd 10 | { 11 | Sound2D::Sound2D() : SoundObject() 12 | { } 13 | 14 | Sound2D::Sound2D(const std::shared_ptr& sound, const bool& loop, const bool& play, const float& volume) : SoundObject(sound, loop, play, volume) 15 | { } 16 | } -------------------------------------------------------------------------------- /Source/SoundType/Sound3D.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * OneSound - Modern C++17 audio library for Windows OS with XAudio2 API 3 | * Copyright ⓒ 2018 Valentyn Bondarenko. All rights reserved. 4 | * License: https://github.com/weelhelmer/OneSound/master/LICENSE 5 | */ 6 | 7 | #include "OneSound\SoundType\Sound3D.h" 8 | 9 | namespace onesnd 10 | { 11 | Sound3D::Sound3D() : SoundObject() 12 | { } 13 | 14 | Sound3D::Sound3D(const std::shared_ptr& sound, const bool& loop, const bool& play, const float& volume) : SoundObject(sound, loop, play, volume) 15 | { } 16 | } -------------------------------------------------------------------------------- /Source/SoundType/SoundBuffer.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * OneSound - Modern C++17 audio library for Windows OS with XAudio2 API 3 | * Copyright ⓒ 2018 Valentyn Bondarenko. All rights reserved. 4 | * License: https://github.com/weelhelmer/OneSound/master/LICENSE 5 | */ 6 | 7 | #include "OneSound\SoundType\SoundObjectState.h" 8 | 9 | #include "OneSound\StreamType\AudioStream.h" 10 | #include "OneSound\SoundType\SoundBuffer.h" 11 | #include "OneSound\SoundType\SoundStream.h" 12 | 13 | namespace onesnd 14 | { 15 | SoundBuffer::SoundBuffer() : 16 | referance_count(0), 17 | xaBuffer(nullptr) 18 | { } 19 | 20 | SoundBuffer::SoundBuffer(const fs::path& file) : 21 | referance_count(0), 22 | xaBuffer(nullptr) 23 | { 24 | Load(file); 25 | } 26 | 27 | SoundBuffer::~SoundBuffer() 28 | { 29 | if (xaBuffer) 30 | Unload(); 31 | } 32 | 33 | int SoundBuffer::Frequency() const 34 | { 35 | return xaBuffer->wf.nSamplesPerSec; 36 | } 37 | 38 | int SoundBuffer::SampleBits() const 39 | { 40 | return xaBuffer->wf.wBitsPerSample; 41 | } 42 | 43 | int SoundBuffer::SampleBytes() const 44 | { 45 | return xaBuffer->nBytesPerSample; 46 | } 47 | 48 | int SoundBuffer::Channels() const 49 | { 50 | return xaBuffer->wf.nChannels; 51 | } 52 | 53 | int SoundBuffer::FullSampleSize() const 54 | { 55 | return xaBuffer->wf.nBlockAlign; 56 | } 57 | 58 | int SoundBuffer::SizeBytes() const 59 | { 60 | return xaBuffer->AudioBytes; 61 | } 62 | 63 | int SoundBuffer::BytesPerSecond() const 64 | { 65 | return xaBuffer->wf.nAvgBytesPerSec; 66 | } 67 | 68 | int SoundBuffer::Size() const 69 | { 70 | return xaBuffer->nPCMSamples; 71 | } 72 | 73 | int SoundBuffer::getReferanceCount() const 74 | { 75 | return referance_count; 76 | } 77 | 78 | bool SoundBuffer::IsStream() const 79 | { 80 | return false; 81 | } 82 | 83 | const WAVEFORMATEX* SoundBuffer::WaveFormat() const 84 | { 85 | return xaBuffer ? &xaBuffer->wf : nullptr; 86 | } 87 | 88 | unsigned SoundBuffer::WaveFormatHash() const 89 | { 90 | return xaBuffer ? xaBuffer->wfHash : 0; 91 | } 92 | 93 | bool SoundBuffer::Load(const fs::path& file) 94 | { 95 | if (XAudio2Device::instance().getEngine() == nullptr) 96 | throw std::runtime_error("Can't create sound because XAudio2 Device is not created."); 97 | 98 | if (xaBuffer) // is there existing data? 99 | return false; 100 | 101 | AudioStream mem; // temporary stream 102 | AudioStream* strm = &mem; 103 | if (!createAudioStream(strm, file.string().c_str())) 104 | return false; // invalid file format or file not found 105 | 106 | if (!strm->OpenStream(file)) 107 | return false; // failed to open the stream (probably not really correct format) 108 | 109 | xaBuffer = XABuffer::create(this, strm->Size(), strm); 110 | strm->CloseStream(); // close this manually, otherwise we get a nasty error when the dtor runs... 111 | 112 | return xaBuffer != nullptr; 113 | } 114 | 115 | bool SoundBuffer::Unload() 116 | { 117 | if (!xaBuffer) 118 | return true; // yes, its unloaded 119 | 120 | if (referance_count > 0) 121 | { 122 | //indebug(printf("SoundBuffer::Unload() Memory Leak: failed to delete alBuffer, because it's still in use.\n")); 123 | return false; // can't do anything here while still referenced 124 | } 125 | 126 | XABuffer::destroy(xaBuffer); 127 | 128 | return true; 129 | } 130 | 131 | bool SoundBuffer::BindSource(SoundObject* so) 132 | { 133 | if (!xaBuffer) 134 | return false; // no data 135 | 136 | if (so->getSound().get() == this) 137 | return false; // no double-binding dude, it will mess up referance_counting. 138 | 139 | so->getSource()->SubmitSourceBuffer(xaBuffer); // enqueue this buffer 140 | ++referance_count; 141 | 142 | return true; 143 | } 144 | 145 | bool SoundBuffer::UnbindSource(SoundObject* so) 146 | { 147 | if (so->getSound().get() == this) // correct buffer link? 148 | { 149 | so->getSource()->Stop(); // make sure its stopped (otherwise Flush won't work) 150 | if (XABuffer::getBuffersQueued(so->getSource())) 151 | so->getSource()->FlushSourceBuffers(); // ensure not in queue anymore 152 | 153 | --referance_count; 154 | } 155 | 156 | return true; 157 | } 158 | 159 | bool SoundBuffer::ResetBuffer(SoundObject* so) 160 | { 161 | if (!xaBuffer || !so->getSource()) 162 | return false; // nothing to do here 163 | 164 | so->getSource()->Stop(); 165 | if (XABuffer::getBuffersQueued(so->getSource())) // only flush IF we have buffers to flush 166 | so->getSource()->FlushSourceBuffers(); 167 | 168 | so->getSource()->SubmitSourceBuffer(xaBuffer); 169 | 170 | return true; 171 | } 172 | } 173 | -------------------------------------------------------------------------------- /Source/SoundType/SoundObject.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * OneSound - Modern C++17 audio library for Windows OS with XAudio2 API 3 | * Copyright ⓒ 2018 Valentyn Bondarenko. All rights reserved. 4 | * License: https://github.com/weelhelmer/OneSound/master/LICENSE 5 | */ 6 | 7 | #pragma once 8 | 9 | #include "OneSound\SoundType\SoundObject.h" 10 | 11 | #include "OneSound\SoundType\SoundBuffer.h" 12 | #include "OneSound\SoundType\SoundStream.h" 13 | 14 | #include "OneSound\XAudio2Device.h" 15 | 16 | #include "OneSound\StreamType\AudioStream.h" 17 | 18 | namespace onesnd 19 | { 20 | SoundObject::SoundObject() : 21 | sound(nullptr), 22 | source(nullptr), 23 | state(nullptr) 24 | { 25 | memset(&Emitter, 0, sizeof(Emitter)); 26 | Emitter.ChannelCount = 1; 27 | Emitter.CurveDistanceScaler = FLT_MIN; 28 | } 29 | 30 | SoundObject::SoundObject(const std::shared_ptr& sound, const bool& looping, const bool& playing, const float& volume) : 31 | sound(nullptr), 32 | source(nullptr), 33 | state(nullptr) 34 | { 35 | memset(&Emitter, 0, sizeof(Emitter)); 36 | Emitter.ChannelCount = 1; 37 | Emitter.CurveDistanceScaler = FLT_MIN; 38 | 39 | if (sound) 40 | setSound(sound); 41 | 42 | setLooping(looping); 43 | 44 | setVolume(volume); 45 | 46 | if (playing) 47 | play(); 48 | } 49 | 50 | SoundObject::~SoundObject() 51 | { 52 | if (sound) 53 | setSound(nullptr); 54 | 55 | if (source) 56 | { 57 | source->DestroyVoice(); 58 | source = nullptr; 59 | } 60 | } 61 | 62 | void SoundObject::setSound(const std::shared_ptr& sound_buf, const bool& loop, const bool& play, const float& volume) 63 | { 64 | if (sound) 65 | sound->UnbindSource(this); // unbind old, but still keep it around 66 | 67 | if (sound_buf) // new sound? 68 | { 69 | if (!source) // no Source object created yet? First init. 70 | state = new SoundObjectState(this); 71 | else if (sound_buf->WaveFormatHash() != sound->WaveFormatHash()) // WaveFormat has changed? 72 | source->DestroyVoice(); // Destroy old and re-create with new 73 | 74 | XAudio2Device::instance().getEngine()->CreateSourceVoice(&source, sound_buf->WaveFormat(), 0, 2.0F, state); 75 | 76 | sound_buf->BindSource(this); 77 | 78 | state->isInitial = true; 79 | state->isPlaying = play; 80 | state->isLoopable = loop; 81 | state->isPaused = false; 82 | 83 | sound = sound_buf; // set new Sound 84 | } 85 | } 86 | 87 | bool SoundObject::isStreamable() const 88 | { 89 | return sound && sound->IsStream(); 90 | } 91 | 92 | bool SoundObject::isEOS() const 93 | { 94 | return sound && sound->IsStream() && ((SoundStream*)sound.get())->IsEOS(this); 95 | } 96 | 97 | void SoundObject::play() 98 | { 99 | if (state->isPlaying) 100 | rewind(); // rewind to start of stream and continue playing 101 | else if (source) 102 | { 103 | state->isPlaying = true; 104 | state->isPaused = false; 105 | 106 | if (!XABuffer::getBuffersQueued(source)) // no buffers queued (track probably finished) 107 | { 108 | state->isInitial = true; 109 | sound->ResetBuffer(this); // reset buffer to beginning 110 | } 111 | 112 | source->Start(); // continue if paused or suspended 113 | } 114 | } 115 | 116 | void SoundObject::play(const std::shared_ptr& sound, const bool& loop, const bool& play, const float& volume) 117 | { 118 | if (sound) 119 | setSound(sound); 120 | 121 | setLooping(loop); 122 | 123 | setVolume(volume); 124 | 125 | if (play) 126 | this->play(); 127 | } 128 | 129 | void SoundObject::stop() 130 | { 131 | if (source && state->isPlaying) 132 | { 133 | // only if isPlaying, to avoid rewind 134 | state->isPlaying = false; 135 | state->isPaused = false; 136 | 137 | source->Stop(); 138 | source->FlushSourceBuffers(); 139 | } 140 | } 141 | 142 | void SoundObject::pause() 143 | { 144 | if (source) 145 | { 146 | state->isPlaying = false; 147 | state->isPaused = true; 148 | 149 | source->Stop(); // Stop() effectively pauses playback 150 | } 151 | } 152 | 153 | void SoundObject::rewind() 154 | { 155 | sound->ResetBuffer(this); // reset stream or buffer to initial state 156 | 157 | state->isInitial = true; 158 | state->isPaused = false; 159 | 160 | if (state->isPlaying) // should we continue playing? 161 | source->Start(); 162 | } 163 | 164 | bool SoundObject::isPlaying() const 165 | { 166 | return state && state->isPlaying; 167 | } 168 | 169 | bool SoundObject::isStopped() const 170 | { 171 | return !state || !state->isPlaying; 172 | } 173 | 174 | bool SoundObject::isPaused() const 175 | { 176 | return state && state->isPaused; 177 | } 178 | 179 | bool SoundObject::isInitial() const 180 | { 181 | return state && state->isInitial; 182 | } 183 | 184 | 185 | bool SoundObject::isLooping() const 186 | { 187 | return state && state->isLoopable; 188 | } 189 | 190 | void SoundObject::setLooping(const bool& looping) 191 | { 192 | if (state) 193 | state->isLoopable = looping; 194 | } 195 | 196 | void SoundObject::setVolume(const float& volume) 197 | { 198 | // HACK: Check the current volume if offered value is more than 1.0 or less than 0. 199 | // It can be even 1000.0f, but it couldn't be looked like the sound. 200 | if (volume > 1.f) 201 | source->SetVolume(1.f); 202 | else if (volume < 0.f) 203 | source->SetVolume(0.f); 204 | else 205 | source->SetVolume(volume); 206 | } 207 | 208 | float SoundObject::getVolume() const 209 | { 210 | float volume; 211 | source->GetVolume(&volume); 212 | return volume; 213 | } 214 | 215 | int SoundObject::getPlaybackPosition() const 216 | { 217 | if (!source) 218 | return 0; 219 | 220 | XAUDIO2_VOICE_STATE state; 221 | source->GetState(&state); 222 | 223 | return (int)state.SamplesPlayed; 224 | } 225 | 226 | void SoundObject::setPlaybackPosition(int seekpos) 227 | { 228 | if (!sound) 229 | return; 230 | 231 | if (sound->IsStream()) // stream objects 232 | ((SoundStream*)sound.get())->Seek(this, seekpos); // seek the stream 233 | else // single buffer objects 234 | { 235 | // first create a shallow copy of the xaBuffer: 236 | auto& shallow = state->shallow = *sound->getXABuffer(); 237 | shallow.PlayBegin = seekpos; 238 | shallow.PlayLength = shallow.nPCMSamples - seekpos; 239 | 240 | state->isPaused = false; 241 | source->Stop(); 242 | 243 | if (XABuffer::getBuffersQueued(source)) // only flush if there is something to flush 244 | source->FlushSourceBuffers(); 245 | 246 | source->SubmitSourceBuffer(&shallow); 247 | } 248 | 249 | if (state->isPlaying) 250 | source->Start(); 251 | } 252 | 253 | int SoundObject::getPlaybackSize() const 254 | { 255 | return sound ? sound->Size() : 0; 256 | } 257 | 258 | 259 | int SoundObject::getSamplesPerSecond() const 260 | { 261 | return sound ? sound->Frequency() : 0; 262 | } 263 | } 264 | -------------------------------------------------------------------------------- /Source/SoundType/SoundObjectState.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * OneSound - Modern C++17 audio library for Windows OS with XAudio2 API 3 | * Copyright ⓒ 2018 Valentyn Bondarenko. All rights reserved. 4 | * License: https://github.com/weelhelmer/OneSound/master/LICENSE 5 | */ 6 | 7 | #include "OneSound\SoundType\SoundObjectState.h" 8 | 9 | #include "OneSound\SoundType\SoundBuffer.h" 10 | #include "OneSound\SoundType\SoundStream.h" 11 | 12 | namespace onesnd 13 | { 14 | void __stdcall SoundObjectState::OnStreamEnd() 15 | { 16 | if (isLoopable) // loopable? 17 | sound->rewind(); // rewind the sound and continue playing 18 | else 19 | isPlaying = false; 20 | } 21 | 22 | // a buffer object finished processing 23 | void __stdcall SoundObjectState::OnBufferEnd(void* ctx) 24 | { 25 | isInitial = false; 26 | if (((SoundBuffer*)ctx)->IsStream()) 27 | { 28 | // stream fetch next buffer for this sound 29 | ((SoundStream*)ctx)->StreamNext(sound); 30 | } 31 | } 32 | } -------------------------------------------------------------------------------- /Source/SoundType/SoundStream.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * OneSound - Modern C++17 audio library for Windows OS with XAudio2 API 3 | * Copyright ⓒ 2018 Valentyn Bondarenko. All rights reserved. 4 | * License: https://github.com/weelhelmer/OneSound/master/LICENSE 5 | */ 6 | 7 | #include "OneSound\SoundType\SoundStream.h" 8 | 9 | #include "OneSound\StreamType\AudioStream.h" 10 | 11 | namespace onesnd 12 | { 13 | SoundStream::SoundStream() 14 | { } 15 | 16 | SoundStream::SoundStream(const fs::path& file) 17 | { 18 | Load(file); 19 | } 20 | 21 | SoundStream::~SoundStream() 22 | { 23 | if (xaBuffer) // active buffer? 24 | Unload(); 25 | } 26 | 27 | int SoundStream::Size() const 28 | { 29 | return alStream ? (alStream->Size() / FullSampleSize()) : 0; 30 | } 31 | 32 | bool SoundStream::IsStream() const 33 | { 34 | return true; 35 | } 36 | 37 | bool SoundStream::Load(const fs::path& file) 38 | { 39 | if (XAudio2Device::instance().getEngine() == nullptr) 40 | throw std::runtime_error("Can't create sound because XAudio2 Device is not created."); 41 | 42 | if (xaBuffer) // is there existing data? 43 | return false; 44 | 45 | if (!(alStream = createAudioStream(file.string().c_str()))) 46 | return false; // :( 47 | 48 | if (!alStream->OpenStream(file)) 49 | return false; 50 | 51 | // load the first buffer in the stream: 52 | xaBuffer = XABuffer::create(this, alStream->BytesPerSecond(), alStream, 0); 53 | 54 | return xaBuffer != nullptr; 55 | } 56 | 57 | bool SoundStream::Unload() 58 | { 59 | if (!xaBuffer) 60 | return true; // yes, its unloaded 61 | if (referance_count > 0) 62 | { 63 | //indebug(printf("SoundStream::Unload() Memory Leak: failed to delete xaBuffer, because it's still in use.\n")); 64 | return false; // can't do anything here while still referenced 65 | } 66 | XABuffer::destroy(xaBuffer); 67 | 68 | if (alStream) 69 | { 70 | delete alStream; 71 | alStream = nullptr; 72 | } 73 | return true; 74 | } 75 | 76 | bool SoundStream::BindSource(SoundObject* so) 77 | { 78 | if (!xaBuffer) 79 | return false; // no data loaded yet 80 | 81 | alSources.emplace_back(so); // default streamPos 82 | LoadStreamData(alSources.back(), 0); // load initial stream data (2 buffers) 83 | 84 | ++referance_count; 85 | return true; 86 | } 87 | 88 | bool SoundStream::UnbindSource(SoundObject* so) 89 | { 90 | if (!xaBuffer) 91 | return false; // no data loaded yet 92 | 93 | auto* e = GetSOEntry(so); 94 | if (!e) 95 | return false; // source doesn't exist 96 | 97 | ClearStreamData(*e); // unload all buffers 98 | 99 | alSources.erase(alSources.begin() + (e - alSources.data())); 100 | --referance_count; 101 | 102 | return true; 103 | } 104 | 105 | bool SoundStream::ResetBuffer(SoundObject* so) 106 | { 107 | return ResetStream(so); 108 | } 109 | 110 | bool SoundStream::StreamNext(SoundObject* so) 111 | { 112 | if (!xaBuffer) 113 | return false; // nothing to do here 114 | 115 | if (auto* e = GetSOEntry(so)) 116 | { 117 | if (e->busy) 118 | return false; // can't stream when stream is busy 119 | 120 | return StreamNext(*e); 121 | } 122 | 123 | return false; // nothing to stream 124 | } 125 | 126 | bool SoundStream::ResetStream(SoundObject* so) 127 | { 128 | // simply clear and load again, to avoid code maintenance hell 129 | if (auto* e = GetSOEntry(so)) 130 | { 131 | ClearStreamData(*e); 132 | return LoadStreamData(*e, 0); 133 | } 134 | 135 | return false; 136 | } 137 | 138 | bool SoundStream::IsEOS(const SoundObject* so) const 139 | { 140 | auto* e = GetSOEntry(so); 141 | return e ? true : (alStream ? (e->next >= alStream->Size()) : true); 142 | } 143 | 144 | SoundStream::SO_ENTRY* SoundStream::GetSOEntry(const SoundObject* so) const 145 | { 146 | for (const auto & e : alSources) 147 | if (e.obj == so) 148 | return (SO_ENTRY*)&e; 149 | 150 | return nullptr; // not found 151 | } 152 | 153 | void SoundStream::Seek(SoundObject* so, int samplepos) 154 | { 155 | if (SO_ENTRY* e = GetSOEntry(so)) 156 | { 157 | // if samplepos out of bounds THEN 0 ELSE convert samplepos to bytepos 158 | auto bytepos = (samplepos >= Size()) ? 0 : samplepos * xaBuffer->wf.nBlockAlign; 159 | 160 | ClearStreamData(*e); 161 | LoadStreamData(*e, bytepos); 162 | 163 | } 164 | 165 | } 166 | 167 | bool SoundStream::StreamNext(SO_ENTRY& e) 168 | { 169 | if (e.next >= alStream->Size()) // is EOF? 170 | return false; 171 | 172 | // front buffer was processed, swap buffers: 173 | std::swap(e.front, e.back); 174 | 175 | e.base = e.next; // shift the base pointer forward 176 | if (e.back == xaBuffer) // we can't refill xaBuffer 177 | { 178 | e.back = XABuffer::create(this, xaBuffer->wf.nAvgBytesPerSec, alStream, &e.next); 179 | if (!e.back) 180 | return false; // oh no... 181 | } 182 | else 183 | { 184 | if (!e.back) // no backbuffer. probably ClearStreamData() was called 185 | return false; 186 | 187 | XABuffer::stream(e.back, alStream, &e.next); 188 | } 189 | 190 | e.obj->getSource()->SubmitSourceBuffer(e.back); // submit the backbuffer to the queue 191 | return true; 192 | } 193 | 194 | bool SoundStream::LoadStreamData(SO_ENTRY& so, int streampos) 195 | { 196 | auto pos = streampos == -1 ? so.next : streampos; // -1: use next, else use streampos 197 | auto streamSize = alStream->Size() - pos; // lets calculate stream size from the SEEK position 198 | auto bytesPerSecond = alStream->BytesPerSecond(); 199 | auto numBuffers = streamSize > bytesPerSecond ? 2 : 1; 200 | auto* source = so.obj->getSource(); 201 | 202 | so.base = pos; 203 | if (pos == 0) // pos 0 means we load alBuffer 204 | { 205 | pos += xaBuffer->AudioBytes; // update pos 206 | source->SubmitSourceBuffer(so.front = xaBuffer); 207 | } 208 | else // load at arbitrary position 209 | { 210 | so.front = XABuffer::create(this, bytesPerSecond, alStream, &pos); 211 | source->SubmitSourceBuffer(so.front); 212 | } 213 | 214 | if (numBuffers == 2) // also load a backbuffer 215 | { 216 | so.back = XABuffer::create(this, bytesPerSecond, alStream, &pos); 217 | source->SubmitSourceBuffer(so.back); 218 | } 219 | so.next = pos; // pos variable was updated by CreateXABuffer 220 | 221 | return true; 222 | } 223 | 224 | void SoundStream::ClearStreamData(SO_ENTRY& so) 225 | { 226 | so.busy = true; 227 | auto* source = so.obj->getSource(); 228 | source->Stop(); 229 | 230 | if (XABuffer::getBuffersQueued(source)) // only flush if we have something to flush 231 | source->FlushSourceBuffers(); 232 | 233 | if (so.front) 234 | { 235 | if (so.front != xaBuffer) 236 | delete so.front, 237 | so.front = nullptr; 238 | } 239 | if (so.back) 240 | { 241 | delete so.back; 242 | so.back = nullptr; 243 | } 244 | 245 | so.busy = false; 246 | } 247 | } -------------------------------------------------------------------------------- /Source/StreamType/AudioStream.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * OneSound - Modern C++17 audio library for Windows OS with XAudio2 API 3 | * Copyright ⓒ 2018 Valentyn Bondarenko. All rights reserved. 4 | * License: https://github.com/weelhelmer/OneSound/master/LICENSE 5 | */ 6 | 7 | #include "OneSound\StreamType\AudioStream.h" 8 | 9 | #include "OneSound\StreamType\WAVStream.h" 10 | #include "OneSound\StreamType\MP3Stream.h" 11 | #include "OneSound\StreamType\OGGStream.h" 12 | 13 | namespace onesnd 14 | { 15 | enum AudioFileFormat 16 | { 17 | INVALID, WAV, MP3, OGG, 18 | }; 19 | 20 | // Checks the file extension 21 | static AudioFileFormat getAudioFileFormatByExtension(const fs::path& file) 22 | { 23 | if (!fs::exists(file)) 24 | throw std::runtime_error("Can't find file: "s + file.string()); 25 | 26 | if(!file.has_extension()) 27 | return AudioFileFormat::INVALID; 28 | 29 | if(file.extension() == ".wav") 30 | return AudioFileFormat::WAV; 31 | else if (file.extension() == ".mp3") 32 | return AudioFileFormat::MP3; 33 | else if (file.extension() == ".ogg") 34 | return AudioFileFormat::OGG; 35 | else 36 | { 37 | printf("OneSound Warning: Unsupported file format."); 38 | return AudioFileFormat::INVALID;; 39 | } 40 | } 41 | 42 | static bool checkMP3Tag(void* buffer) 43 | { 44 | #pragma pack(push) 45 | #pragma pack(1) 46 | struct MP3TAGV2 47 | { 48 | char id3[3]; 49 | unsigned char vermajor; 50 | unsigned char verminor; 51 | unsigned char flags; 52 | unsigned int size; 53 | }; 54 | #pragma pack(pop) 55 | 56 | auto tag = *(MP3TAGV2*)buffer; // agly, but works fine. 57 | if (tag.id3[0] == 'I' && tag.id3[1] == 'D' && tag.id3[2] == '3') 58 | return true; 59 | 60 | return false; // not an mp3 header 61 | } 62 | 63 | // Checks the file header 64 | static AudioFileFormat getAudioFileFormatByHeader(const char* file_name) 65 | { 66 | FILE** f = nullptr; 67 | fopen_s(f, file_name, "rb"); 68 | if (!f) 69 | throw std::runtime_error("Can't open file: "s + file_name); 70 | 71 | // MP3 has a header tag that needs 10 bytes 72 | // WAV has a large header with byte fields [file + 0]='RIFF' and [file + 8]='WAVE', so it needs 12 bytes 73 | // OGG has a 32-bit "capture pattern" sync field 'OggS', it needs 4 bytes 74 | int buffer[3]; // WAV requires most, so 12 bytes 75 | fread(buffer, sizeof(buffer), 1, *f); 76 | fclose(*f); 77 | f = nullptr; 78 | 79 | if (buffer[0] == 'FFIR' && buffer[2] == 'EVAW') 80 | return AudioFileFormat::WAV; 81 | else if (buffer[0] == 'SggO') 82 | return AudioFileFormat::OGG; 83 | else if (checkMP3Tag(buffer)) 84 | return AudioFileFormat::MP3; 85 | 86 | return AudioFileFormat::INVALID; 87 | } 88 | 89 | AudioStream* createAudioStream(const char* file) 90 | { 91 | auto fmt = getAudioFileFormatByExtension(file); 92 | if (fmt == AudioFileFormat::INVALID) 93 | fmt = getAudioFileFormatByHeader(file); 94 | 95 | if (fmt == AudioFileFormat::INVALID) 96 | throw std::runtime_error("Invalid file header."); 97 | 98 | switch (fmt) 99 | { 100 | case AudioFileFormat::WAV: return new WAVStream(); 101 | case AudioFileFormat::MP3: return new MP3Stream(); 102 | case AudioFileFormat::OGG: return new OGGStream(); 103 | 104 | default: 105 | return nullptr; 106 | } 107 | } 108 | 109 | bool createAudioStream(AudioStream* as, const char* file) 110 | { 111 | if (!as) 112 | return false; 113 | as->CloseStream(); // just in case 114 | 115 | auto fmt = getAudioFileFormatByExtension(file); 116 | if (!fmt) 117 | fmt = getAudioFileFormatByHeader(file); 118 | if (!fmt) 119 | return false; 120 | 121 | switch (fmt) 122 | { 123 | case AudioFileFormat::WAV: new (as) WAVStream(); break; 124 | case AudioFileFormat::MP3: new (as) MP3Stream(); break; 125 | case AudioFileFormat::OGG: new (as) OGGStream(); break; 126 | default: 127 | return false; 128 | } 129 | 130 | return true; 131 | } 132 | 133 | struct RIFFCHUNK 134 | { 135 | union 136 | { 137 | int ID; // chunk ID 138 | char IDStr[4]; // chunk ID as string 139 | }; 140 | 141 | int Size; // chunk SIZE 142 | }; 143 | 144 | struct WAVHEADER 145 | { 146 | RIFFCHUNK Header; // Contains the letters "RIFF" && (SizeOfFile - 8) in bytes 147 | union 148 | { 149 | int Format; // Contains the letters "WAVE" 150 | char FormatAsStr[4]; 151 | }; 152 | 153 | // The FMT sub-chunk 154 | RIFFCHUNK Subchunk1; // Contains the letters "fmt " && 16 bytes in size 155 | 156 | struct 157 | { 158 | short AudioFormat; // Should be 1, otherwise this file is compressed 159 | short NumChannels; // Mono = 1, Stereo = 2 160 | int SampleRate; // 8000, 22050, 44100, etc 161 | int ByteRate; // == SampleRate * NumChannels * BitsPerSample/8 162 | short BlockAlign; // == NumChannels * BitsPerSample/8 163 | short BitsPerSample; // 8 bits == 8, 16 bits == 16, etc. 164 | }; 165 | 166 | RIFFCHUNK NextChunk1; // Contains the letters "info" or "data" 167 | RIFFCHUNK NextChunk2; // maybe this one is data? 168 | int someData[4]; 169 | 170 | RIFFCHUNK* getDataChunk() 171 | { 172 | if (NextChunk1.ID == (int)'atad') 173 | return &NextChunk1; 174 | if (NextChunk2.ID == (int)'atad') 175 | return &NextChunk2; 176 | 177 | return nullptr; 178 | } 179 | }; 180 | 181 | 182 | AudioStream::AudioStream() : 183 | FileHandle(nullptr), 184 | stream_size(0), 185 | stream_position(0), 186 | sample_rate(0), 187 | NumChannels(0), 188 | SampleSize(0), 189 | SampleBlockSize(0) 190 | { } 191 | 192 | AudioStream::AudioStream(const fs::path& file) : 193 | FileHandle(nullptr), 194 | stream_size(0), 195 | stream_position(0), 196 | sample_rate(0), 197 | NumChannels(0), 198 | SampleSize(0), 199 | SampleBlockSize(0) 200 | { 201 | OpenStream(file); 202 | } 203 | 204 | AudioStream::~AudioStream() 205 | { 206 | CloseStream(); 207 | } 208 | 209 | bool AudioStream::OpenStream(const fs::path& file_name) 210 | { 211 | if (FileHandle) // do not allow reopen an existing stream 212 | return false; 213 | 214 | FileHandle = reinterpret_cast(file_open_ro(file_name.string().c_str())); 215 | if (!FileHandle) 216 | throw std::runtime_error("Can't open file: "s + file_name.string()); 217 | 218 | WAVHEADER wav; 219 | if (file_read(FileHandle, &wav, sizeof(wav)) <= 0) 220 | throw std::runtime_error("Failed to read WAV header from file: "s + file_name.string()); 221 | 222 | // != "RIFF" || != "WAVE" 223 | if (wav.Header.ID != (int)'FFIR' || wav.Format != (int)'EVAW') 224 | throw std::runtime_error("Invalid WAV header in file: "s + file_name.string()); 225 | 226 | auto* dataChunk = wav.getDataChunk(); 227 | if (!dataChunk) 228 | throw std::runtime_error("Failed to find WAV chunk in file: "s + file_name.string()); 229 | 230 | // initialize essential variables 231 | stream_size = dataChunk->Size; 232 | sample_rate = static_cast(wav.SampleRate); 233 | NumChannels = static_cast(wav.NumChannels); 234 | SampleSize = static_cast(wav.BitsPerSample >> 3); // BPS/8 => SampleSize 235 | SampleBlockSize = SampleSize * NumChannels; // [LL][RR] (1 to 4 bytes) 236 | 237 | return true; 238 | } 239 | 240 | void AudioStream::CloseStream() 241 | { 242 | if (FileHandle) 243 | { 244 | file_close(reinterpret_cast(FileHandle)); 245 | 246 | FileHandle = 0; 247 | stream_size = 0; 248 | stream_position = 0; 249 | sample_rate = 0; 250 | NumChannels = 0; 251 | SampleSize = 0; 252 | SampleBlockSize = 0; 253 | } 254 | } 255 | 256 | int AudioStream::ReadSome(void* dstBuffer, int dstSize) 257 | { 258 | if (!FileHandle) 259 | return 0; // so nothing to do here 260 | 261 | auto count = stream_size - stream_position; // calculate available data from stream 262 | if (count == 0) // if are stream available bytes are 0 263 | return 0; // EOS is reached 264 | 265 | if (count > dstSize) // if stream has more data than buffer 266 | count = dstSize; // set bytes to read bigger 267 | count -= count % SampleBlockSize; // make sure that count is aligned to blockSize 268 | 269 | if (file_read(FileHandle, dstBuffer, count) <= 0) 270 | { 271 | stream_position = stream_size; // set EOS 272 | return 0; // no bytes to read 273 | } 274 | stream_position += count; 275 | 276 | return count; 277 | 278 | } 279 | 280 | unsigned int AudioStream::Seek(unsigned int streampos) 281 | { 282 | if (int(streampos) >= stream_size) 283 | streampos = 0; 284 | 285 | streampos -= streampos % SampleBlockSize; // align to PCM blocksize 286 | file_seek(FileHandle, streampos + sizeof(WAVHEADER), SEEK_SET); 287 | stream_position = streampos; 288 | 289 | return streampos; 290 | } 291 | } 292 | -------------------------------------------------------------------------------- /Source/StreamType/MP3Stream.cpp: -------------------------------------------------------------------------------- 1 | // Copyright ⓒ 2018 Valentyn Bondarenko. All rights reserved. 2 | 3 | 4 | #include "OneSound\StreamType\MP3Stream.h" 5 | 6 | namespace onesnd 7 | { 8 | #pragma data_seg("SHARED") 9 | static HMODULE mpgDll = nullptr; 10 | static void(*mpg_exit)(); 11 | static int(*mpg_init)(); 12 | static int* (*mpg_new)(const char* decoder, int* error); 13 | static int(*mpg_close)(int* mh); 14 | static void(*mpg_delete)(int* mh); 15 | static int(*mpg_open_handle)(int* mh, void* iohandle); 16 | static int(*mpg_getformat)(int* mh, long* rate, int* channels, int* encoding); 17 | static size_t(*mpg_length)(int* mh); 18 | static size_t(*mpg_outblock)(int* mh); 19 | static int(*mpg_encsize)(int encoding); 20 | static int(*mpg_read)(int* mh, unsigned char* outmemory, size_t outmemsize, size_t* done); 21 | static const char* (*mpg_strerror)(int* mh); 22 | static int(*mpg_errcode)(int* mh); 23 | static const char** (*mpg_supported_decoders)(); 24 | static size_t(*mpg_seek)(int* mh, size_t sampleOffset, int whence); 25 | static const char* (*mpg_current_decoder)(int* mh); 26 | 27 | typedef int(*mpg_read_func)(void*, void*, size_t); 28 | typedef off_t(*mpg_seek_func)(void*, off_t, int); 29 | typedef int(*mpg_close_func)(void*); 30 | static int(*mpg_replace_reader_handle)(int* mh, mpg_read_func, mpg_seek_func, mpg_close_func); 31 | #pragma data_seg() 32 | 33 | template static inline void LoadMpgProc(Proc& outProcVar, const char* procName) 34 | { 35 | outProcVar = (Proc)GetProcAddress(mpgDll, procName); 36 | } 37 | static void _UninitMPG() 38 | { 39 | mpg_exit(); 40 | 41 | FreeLibrary(mpgDll); 42 | mpgDll = nullptr; 43 | } 44 | static void _InitMPG() 45 | { 46 | static const char* mpglib = "libmpg123"; 47 | mpgDll = LoadLibraryA(mpglib); 48 | if (!mpgDll) 49 | throw std::runtime_error("Can't found "s + mpglib + ".dll"s); 50 | 51 | LoadMpgProc(mpg_exit, "mpg123_exit"); 52 | LoadMpgProc(mpg_init, "mpg123_init"); 53 | LoadMpgProc(mpg_new, "mpg123_new"); 54 | LoadMpgProc(mpg_close, "mpg123_close"); 55 | LoadMpgProc(mpg_delete, "mpg123_delete"); 56 | LoadMpgProc(mpg_open_handle, "mpg123_open_handle"); 57 | LoadMpgProc(mpg_getformat, "mpg123_getformat"); 58 | LoadMpgProc(mpg_length, "mpg123_length"); 59 | LoadMpgProc(mpg_outblock, "mpg123_outblock"); 60 | LoadMpgProc(mpg_encsize, "mpg123_encsize"); 61 | LoadMpgProc(mpg_read, "mpg123_read"); 62 | LoadMpgProc(mpg_strerror, "mpg123_strerror"); 63 | LoadMpgProc(mpg_errcode, "mpg123_errcode"); 64 | LoadMpgProc(mpg_supported_decoders, "mpg123_supported_decoders"); 65 | LoadMpgProc(mpg_seek, "mpg123_seek"); 66 | LoadMpgProc(mpg_current_decoder, "mpg123_current_decoder"); 67 | LoadMpgProc(mpg_replace_reader_handle, "mpg123_replace_reader_handle"); 68 | 69 | mpg_init(); 70 | 71 | atexit(_UninitMPG); 72 | } 73 | 74 | MP3Stream::MP3Stream() : AudioStream() 75 | { 76 | if (!mpgDll) 77 | _InitMPG(); 78 | } 79 | 80 | MP3Stream::MP3Stream(const fs::path& file) : AudioStream() 81 | { 82 | if (!mpgDll) 83 | _InitMPG(); 84 | 85 | OpenStream(file); 86 | } 87 | 88 | MP3Stream::~MP3Stream() 89 | { 90 | CloseStream(); 91 | } 92 | 93 | bool MP3Stream::OpenStream(const fs::path& file_name) 94 | { 95 | if (!mpgDll || FileHandle) 96 | return 0; 97 | 98 | FileHandle = mpg_new(nullptr, nullptr); 99 | mpg_replace_reader_handle(FileHandle, file_read, file_seek, file_close); 100 | 101 | auto* iohandle = file_open_ro(file_name.string().c_str()); 102 | if (!iohandle) 103 | throw std::runtime_error("Can't open file: "s + file_name.string()); 104 | 105 | mpg_open_handle(FileHandle, iohandle); 106 | 107 | auto rate = 0; 108 | auto numChannels = decltype(rate)(); 109 | auto encoding = decltype(numChannels)(); 110 | 111 | if (mpg_getformat(FileHandle, reinterpret_cast(&rate), &numChannels, &encoding)) 112 | throw std::runtime_error("Failed to read MP3 header from file: "s + file_name.string()); 113 | 114 | auto sampleSize = mpg_encsize(encoding); 115 | 116 | // get the actual PCM data size: (NumSamples * NumChannels * SampleSize) 117 | SampleSize = sampleSize; 118 | SampleBlockSize = numChannels * sampleSize; 119 | stream_size = mpg_length(FileHandle) * SampleBlockSize; 120 | sample_rate = rate; 121 | NumChannels = numChannels; 122 | 123 | return true; 124 | } 125 | 126 | void MP3Stream::CloseStream() 127 | { 128 | if (!mpgDll) 129 | return; // mpg123 not present 130 | 131 | if (FileHandle) 132 | { 133 | mpg_close(FileHandle); 134 | mpg_delete(FileHandle); 135 | 136 | FileHandle = 0; 137 | stream_size = 0; 138 | stream_position = 0; 139 | sample_rate = 0; 140 | NumChannels = 0; 141 | SampleSize = 0; 142 | SampleBlockSize = 0; 143 | } 144 | } 145 | 146 | int MP3Stream::ReadSome(void* dstBuffer, int dstSize) 147 | { 148 | if (!mpgDll || !FileHandle) 149 | return 0; // mpg123 not present 150 | 151 | auto count = stream_size - stream_position; // calc available data from stream 152 | if (count == 0) // if stream available bytes 0? 153 | return 0; // EOS reached 154 | 155 | if (count > dstSize) // if stream has more data than buffer 156 | count = dstSize; // set bytes to read bigger 157 | count -= count % SampleBlockSize; // make sure count is aligned to blockSize 158 | 159 | auto bytesRead = size_t(); 160 | mpg_read(FileHandle, static_cast(dstBuffer), count, &bytesRead); 161 | 162 | stream_position += bytesRead; 163 | 164 | return bytesRead; 165 | } 166 | 167 | unsigned int MP3Stream::Seek(unsigned int streampos) 168 | { 169 | if (!mpgDll) 170 | return 0; 171 | 172 | if (int(streampos) >= stream_size) 173 | streampos = 0; 174 | int actual = streampos / SampleBlockSize; // mpg_seek works by sample blocks, so lets select the sample 175 | 176 | mpg_seek(FileHandle, actual, SEEK_SET); 177 | 178 | return streampos; 179 | } 180 | } -------------------------------------------------------------------------------- /Source/StreamType/OGGStream.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * OneSound - Modern C++17 audio library for Windows OS with XAudio2 API 3 | * Copyright ⓒ 2018 Valentyn Bondarenko. All rights reserved. 4 | * License: https://github.com/weelhelmer/OneSound/master/LICENSE 5 | */ 6 | 7 | #pragma once 8 | 9 | #include "OneSound\Export.h" 10 | 11 | #include "OneSound\StreamType\OGGStream.h" 12 | 13 | #include "..\ThirdParty\Include\Vorbis\vorbisfile.h" 14 | 15 | 16 | namespace onesnd 17 | { 18 | #pragma data_seg("SHARED") 19 | static HMODULE vfDll = nullptr; 20 | static int(*oggv_clear)(void* vf) = 0; 21 | static long(*oggv_read)(void* vf, char* buffer, int length, int bigendiannp, int word, int sgned, int* bitstream) = 0; 22 | static long(*oggv_pcm_seek)(void* vf, INT64 pos) = 0; 23 | static UINT64(*oggv_pcm_tell)(void* vf) = 0; 24 | static UINT64(*oggv_pcm_total)(void* vf, int i) = 0; 25 | static vorbis_info* (*oggv_info)(void* vf, int link) = 0; 26 | static vorbis_comment* (*oggv_comment)(void* vf, int link) = 0; 27 | static int(*oggv_open_callbacks)(void* datasource, int* vf, char* initial, long ibytes, ov_callbacks cb) = 0; 28 | #pragma data_seg() 29 | 30 | static size_t oggv_read_func(void* ptr, size_t size, size_t nmemb, void* handle) 31 | { 32 | return file_read(handle, ptr, size * nmemb); 33 | } 34 | static int oggv_seek_func(void* handle, INT64 offset, int whence) 35 | { 36 | return file_seek(handle, (long)offset, whence); 37 | } 38 | static int oggv_close_func(void* handle) 39 | { 40 | return file_close(handle); 41 | } 42 | static long oggv_tell_func(void* handle) 43 | { 44 | return file_tell(handle); 45 | } 46 | 47 | template static inline void LoadVorbisProc(Proc* outProcVar, const char* procName) 48 | { 49 | *outProcVar = (Proc)GetProcAddress(vfDll, procName); 50 | } 51 | static void finalizeOGGVorbis() 52 | { 53 | FreeLibrary(vfDll); 54 | vfDll = nullptr; 55 | } 56 | static void initializeOGGVorbis() 57 | { 58 | static const char* vorbislib = "vorbisfile"; 59 | 60 | // NOTE: ogg.dll and vorbis.dll is loaded by vorbisfile.dll 61 | vfDll = LoadLibraryA(vorbislib); 62 | if (!vfDll) 63 | throw std::runtime_error("Can't found "s + vorbislib + ".dll"s); 64 | 65 | LoadVorbisProc(&oggv_clear, "ov_clear"); 66 | LoadVorbisProc(&oggv_read, "ov_read"); 67 | LoadVorbisProc(&oggv_pcm_seek, "ov_pcm_seek"); 68 | LoadVorbisProc(&oggv_pcm_tell, "ov_pcm_tell"); 69 | LoadVorbisProc(&oggv_pcm_total, "ov_pcm_total"); 70 | LoadVorbisProc(&oggv_info, "ov_info"); 71 | LoadVorbisProc(&oggv_comment, "ov_comment"); 72 | LoadVorbisProc(&oggv_open_callbacks, "ov_open_callbacks"); 73 | 74 | atexit(finalizeOGGVorbis); 75 | } 76 | 77 | OGGStream::OGGStream() : AudioStream() 78 | { 79 | if (!vfDll) 80 | initializeOGGVorbis(); 81 | } 82 | 83 | OGGStream::OGGStream(const fs::path& file) : AudioStream() 84 | { 85 | if (!vfDll) 86 | initializeOGGVorbis(); 87 | 88 | OpenStream(file); 89 | } 90 | 91 | OGGStream::~OGGStream() 92 | { 93 | CloseStream(); 94 | } 95 | 96 | bool OGGStream::OpenStream(const fs::path& file_name) 97 | { 98 | if (!vfDll || FileHandle) 99 | return false; 100 | 101 | auto* iohandle = file_open_ro(file_name.string().c_str()); 102 | if (!iohandle) 103 | throw std::runtime_error("Can't open file: "s + file_name.string()); 104 | 105 | ov_callbacks cb = {oggv_read_func, oggv_seek_func, oggv_close_func, oggv_tell_func}; 106 | FileHandle = reinterpret_cast(malloc(sizeof(OggVorbis_File))); // filehandle is actually Vorbis handle 107 | 108 | auto err = oggv_open_callbacks(iohandle, FileHandle, nullptr, 0, cb); 109 | if (err) 110 | { 111 | const char* errmsg = nullptr; 112 | switch (err) 113 | { 114 | case OV_EREAD: errmsg = "Error reading OGG file!"; break; 115 | case OV_ENOTVORBIS: errmsg = "Not an OGG vorbis file!"; break; 116 | case OV_EVERSION: errmsg = "Vorbis version mismatch!"; break; 117 | case OV_EBADHEADER: errmsg = "Invalid vorbis bitstream header"; break; 118 | case OV_EFAULT: errmsg = "Internal logic fault"; break; 119 | } 120 | 121 | CloseStream(); 122 | throw std::runtime_error("Failed to open OGG file: "s + file_name.string()); 123 | } 124 | auto* info = oggv_info(FileHandle, -1); 125 | if (!info) 126 | { 127 | CloseStream(); 128 | throw std::runtime_error("Failed to acquire OGG stream format from file : "s + file_name.string()); 129 | } 130 | 131 | sample_rate = static_cast(info->rate); 132 | 133 | // FIXME: Some breaks are occured beatween every stream's block. 134 | if (sample_rate > 22050) 135 | // Let's warn the user. 136 | printf("ONESOUND: WARNING: The stream has some troubles when do its.\n\ 137 | Unknown breaks are occured beatween every stream's block\n\ 138 | if sample rate is more than 22050. Please convert your\n\ 139 | OGG File to the sund with 22050 sample rate until the\n\ 140 | author not found a solution.\n"); 141 | 142 | NumChannels = info->channels; 143 | SampleSize = 2; // OGG samples are always 16-bit 144 | SampleBlockSize = 2 * NumChannels; // OGG samples are always 16-bit 145 | stream_size = static_cast(oggv_pcm_total(FileHandle, -1) * SampleBlockSize); // streamsize in total bytes 146 | 147 | return true; 148 | } 149 | 150 | void OGGStream::CloseStream() 151 | { 152 | if (!vfDll) 153 | return; // vorbis not present 154 | 155 | if (FileHandle) 156 | { 157 | oggv_clear(FileHandle); 158 | free(FileHandle); 159 | 160 | FileHandle = 0; 161 | stream_size = 0; 162 | stream_position = 0; 163 | sample_rate = 0; 164 | NumChannels = 0; 165 | SampleSize = 0; 166 | SampleBlockSize = 0; 167 | } 168 | } 169 | 170 | int OGGStream::ReadSome(void* dstBuffer, int dstSize) 171 | { 172 | if (!vfDll || !FileHandle) 173 | return 0; 174 | 175 | auto count = stream_size - stream_position; // calc available data from stream 176 | if (count == 0) // if stream available bytes 0? 177 | return 0; // EOS reached 178 | 179 | if (count > dstSize) // if stream has more data than buffer 180 | count = dstSize; // set bytes to read bigger 181 | count -= count % SampleBlockSize; // make sure count is aligned to blockSize 182 | 183 | auto current_section = int(); 184 | auto bytesTotal = int(); // total bytes read 185 | do 186 | { 187 | // FIXME: Error when streaming one handle many times. 188 | // File handles are not shared, so creating two handles of the same stream can be chashed. 189 | // Find a way to share the stream or the data. 190 | int bytesRead = oggv_read(FileHandle, (char*)dstBuffer + bytesTotal, 191 | (count - bytesTotal), 0, 2, 1, ¤t_section); 192 | 193 | if (bytesRead == 0) 194 | break; // EOF! 195 | 196 | bytesTotal += bytesRead; 197 | } while (bytesTotal < count); 198 | 199 | stream_position += bytesTotal; 200 | return bytesTotal; 201 | } 202 | 203 | unsigned int OGGStream::Seek(unsigned int streampos) 204 | { 205 | if (!vfDll) 206 | return 0; // vorbis not present 207 | 208 | if (static_cast(streampos) >= stream_size) 209 | streampos = 0; // out of bounds, set to beginning 210 | oggv_pcm_seek(FileHandle, streampos / SampleBlockSize); // seek PCM samples 211 | 212 | return stream_position = streampos; // finally, update the stream position 213 | } 214 | } -------------------------------------------------------------------------------- /Source/XAudio2Device.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * OneSound - Modern C++17 audio library for Windows OS with XAudio2 API 3 | * Copyright ⓒ 2018 Valentyn Bondarenko. All rights reserved. 4 | * License: https://github.com/weelhelmer/OneSound/master/LICENSE 5 | */ 6 | 7 | #include "OneSound\XAudio2Device.h" 8 | 9 | #include "OneSound\StreamType\AudioStream.h" 10 | 11 | namespace onesnd 12 | { 13 | void XAudio2Device::initialize() 14 | { 15 | CoInitializeEx(nullptr, COINIT_MULTITHREADED); 16 | auto flags = long(); 17 | 18 | #if defined (_WIN32) && defined (_DEBUG) 19 | flags |= XAUDIO2_DEBUG_ENGINE; 20 | #else 21 | flags |= 0; 22 | #endif 23 | 24 | XAudio2Create(&xEngine, flags); 25 | xEngine->CreateMasteringVoice(&xMaster, XAUDIO2_DEFAULT_CHANNELS, XAUDIO2_DEFAULT_SAMPLERATE); 26 | X3DAudioInitialize(SPEAKER_STEREO, X3DAUDIO_SPEED_OF_SOUND, x3DAudioHandle); 27 | } 28 | 29 | void XAudio2Device::finalize() 30 | { 31 | xMaster->DestroyVoice(); 32 | xEngine->Release(); 33 | 34 | if (xMaster != nullptr) 35 | xMaster = nullptr; 36 | 37 | if (xEngine != nullptr) 38 | xEngine = nullptr; 39 | } 40 | 41 | XABuffer* XABuffer::create(SoundBuffer* ctx, int size, AudioStream* strm, int* pos) 42 | { 43 | if (pos) 44 | strm->Seek(*pos); // seek to specified pos, let the AudioStream handle error conditions 45 | if (strm->IsEOS()) 46 | return nullptr; // EOS(), failed! 47 | 48 | int bytesToRead = strm->Available(); 49 | if (size < bytesToRead) 50 | bytesToRead = size; 51 | 52 | auto* buffer = (XABuffer*)malloc(sizeof(XABuffer) + bytesToRead); 53 | if (!buffer) 54 | return nullptr; // out of memory 55 | 56 | auto* data = (BYTE*)buffer + sizeof(XABuffer); // sound data follows after the XABuffer header 57 | 58 | int bytesRead = strm->ReadSome(data, bytesToRead); 59 | if (pos) 60 | *pos += bytesRead; // update position 61 | 62 | buffer->Flags = strm->IsEOS() ? XAUDIO2_END_OF_STREAM : 0; 63 | buffer->AudioBytes = bytesRead; 64 | buffer->pAudioData = data; 65 | buffer->PlayBegin = 0; // first sample to play 66 | buffer->PlayLength = 0; // number of samples to play 67 | buffer->LoopBegin = 0; // first sample to loop 68 | buffer->LoopLength = 0; // number of samples to loop 69 | buffer->LoopCount = 0; // how many times to loop the region 70 | buffer->pContext = ctx; // context of the buffer 71 | 72 | auto sampleSize = strm->SingleSampleSize(); 73 | buffer->nBytesPerSample = sampleSize; 74 | 75 | auto& wf = buffer->wf; 76 | wf.wFormatTag = WAVE_FORMAT_PCM; 77 | wf.nChannels = strm->Channels(); 78 | buffer->nPCMSamples = bytesRead / (sampleSize * wf.nChannels); 79 | wf.nSamplesPerSec = strm->Frequency(); 80 | wf.wBitsPerSample = sampleSize * 8; 81 | wf.nBlockAlign = (wf.nChannels * sampleSize); 82 | wf.nAvgBytesPerSec = wf.nBlockAlign * wf.nSamplesPerSec; 83 | wf.cbSize = sizeof(WAVEFORMATEX); 84 | 85 | // this is enough to create an somewhat unique pseudo-hash: 86 | buffer->wfHash = wf.nSamplesPerSec + (wf.nChannels * 25) + (wf.wBitsPerSample * 7); 87 | return buffer; 88 | } 89 | 90 | void XABuffer::stream(XABuffer* buffer, AudioStream* strm, int* pos) 91 | { 92 | if (pos) 93 | strm->Seek(*pos); // seek to specified pos, let the AudioStream handle error conditions 94 | 95 | buffer->AudioBytes = strm->ReadSome((void*)buffer->pAudioData, buffer->AudioBytes); 96 | 97 | if (strm->IsEOS()) // end of stream was reached 98 | buffer->Flags = XAUDIO2_END_OF_STREAM; 99 | 100 | if (pos) 101 | *pos += buffer->AudioBytes; // update position 102 | } 103 | 104 | void XABuffer::destroy(XABuffer*& buffer) 105 | { 106 | free(reinterpret_cast(buffer)); 107 | buffer = nullptr; 108 | } 109 | 110 | int XABuffer::getBuffersQueued(IXAudio2SourceVoice* source) 111 | { 112 | XAUDIO2_VOICE_STATE state; 113 | source->GetState(&state); 114 | 115 | return state.BuffersQueued; 116 | } 117 | } -------------------------------------------------------------------------------- /ThirdParty/Include/Vorbis/codec.h: -------------------------------------------------------------------------------- 1 | /******************************************************************** 2 | * * 3 | * THIS FILE IS PART OF THE OggVorbis SOFTWARE CODEC SOURCE CODE. * 4 | * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS * 5 | * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE * 6 | * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. * 7 | * * 8 | * THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2001 * 9 | * by the XIPHOPHORUS Company http://www.xiph.org/ * 10 | 11 | ******************************************************************** 12 | 13 | function: libvorbis codec headers 14 | last mod: $Id: codec.h 7485 2004-08-05 14:54:23Z thomasvs $ 15 | 16 | ********************************************************************/ 17 | 18 | #ifndef _vorbis_codec_h_ 19 | #define _vorbis_codec_h_ 20 | 21 | #ifdef __cplusplus 22 | extern "C" 23 | { 24 | #endif /* __cplusplus */ 25 | 26 | #include "ogg.h" 27 | 28 | typedef struct vorbis_info{ 29 | int version; 30 | int channels; 31 | long rate; 32 | 33 | /* The below bitrate declarations are *hints*. 34 | Combinations of the three values carry the following implications: 35 | 36 | all three set to the same value: 37 | implies a fixed rate bitstream 38 | only nominal set: 39 | implies a VBR stream that averages the nominal bitrate. No hard 40 | upper/lower limit 41 | upper and or lower set: 42 | implies a VBR bitstream that obeys the bitrate limits. nominal 43 | may also be set to give a nominal rate. 44 | none set: 45 | the coder does not care to speculate. 46 | */ 47 | 48 | long bitrate_upper; 49 | long bitrate_nominal; 50 | long bitrate_lower; 51 | long bitrate_window; 52 | 53 | void *codec_setup; 54 | } vorbis_info; 55 | 56 | /* vorbis_dsp_state buffers the current vorbis audio 57 | analysis/synthesis state. The DSP state belongs to a specific 58 | logical bitstream ****************************************************/ 59 | typedef struct vorbis_dsp_state{ 60 | int analysisp; 61 | vorbis_info *vi; 62 | 63 | float **pcm; 64 | float **pcmret; 65 | int pcm_storage; 66 | int pcm_current; 67 | int pcm_returned; 68 | 69 | int preextrapolate; 70 | int eofflag; 71 | 72 | long lW; 73 | long W; 74 | long nW; 75 | long centerW; 76 | 77 | ogg_int64_t granulepos; 78 | ogg_int64_t sequence; 79 | 80 | ogg_int64_t glue_bits; 81 | ogg_int64_t time_bits; 82 | ogg_int64_t floor_bits; 83 | ogg_int64_t res_bits; 84 | 85 | void *backend_state; 86 | } vorbis_dsp_state; 87 | 88 | typedef struct vorbis_block{ 89 | /* necessary stream state for linking to the framing abstraction */ 90 | float **pcm; /* this is a pointer into local storage */ 91 | oggpack_buffer opb; 92 | 93 | long lW; 94 | long W; 95 | long nW; 96 | int pcmend; 97 | int mode; 98 | 99 | int eofflag; 100 | ogg_int64_t granulepos; 101 | ogg_int64_t sequence; 102 | vorbis_dsp_state *vd; /* For read-only access of configuration */ 103 | 104 | /* local storage to avoid remallocing; it's up to the mapping to 105 | structure it */ 106 | void *localstore; 107 | long localtop; 108 | long localalloc; 109 | long totaluse; 110 | struct alloc_chain *reap; 111 | 112 | /* bitmetrics for the frame */ 113 | long glue_bits; 114 | long time_bits; 115 | long floor_bits; 116 | long res_bits; 117 | 118 | void *internal; 119 | 120 | } vorbis_block; 121 | 122 | /* vorbis_block is a single block of data to be processed as part of 123 | the analysis/synthesis stream; it belongs to a specific logical 124 | bitstream, but is independant from other vorbis_blocks belonging to 125 | that logical bitstream. *************************************************/ 126 | 127 | struct alloc_chain{ 128 | void *ptr; 129 | struct alloc_chain *next; 130 | }; 131 | 132 | /* vorbis_info contains all the setup information specific to the 133 | specific compression/decompression mode in progress (eg, 134 | psychoacoustic settings, channel setup, options, codebook 135 | etc). vorbis_info and substructures are in backends.h. 136 | *********************************************************************/ 137 | 138 | /* the comments are not part of vorbis_info so that vorbis_info can be 139 | static storage */ 140 | typedef struct vorbis_comment{ 141 | /* unlimited user comment fields. libvorbis writes 'libvorbis' 142 | whatever vendor is set to in encode */ 143 | char **user_comments; 144 | int *comment_lengths; 145 | int comments; 146 | char *vendor; 147 | 148 | } vorbis_comment; 149 | 150 | 151 | /* libvorbis encodes in two abstraction layers; first we perform DSP 152 | and produce a packet (see docs/analysis.txt). The packet is then 153 | coded into a framed OggSquish bitstream by the second layer (see 154 | docs/framing.txt). Decode is the reverse process; we sync/frame 155 | the bitstream and extract individual packets, then decode the 156 | packet back into PCM audio. 157 | 158 | The extra framing/packetizing is used in streaming formats, such as 159 | files. Over the net (such as with UDP), the framing and 160 | packetization aren't necessary as they're provided by the transport 161 | and the streaming layer is not used */ 162 | 163 | /* Vorbis PRIMITIVES: general ***************************************/ 164 | 165 | extern void vorbis_info_init(vorbis_info *vi); 166 | extern void vorbis_info_clear(vorbis_info *vi); 167 | extern int vorbis_info_blocksize(vorbis_info *vi,int zo); 168 | extern void vorbis_comment_init(vorbis_comment *vc); 169 | extern void vorbis_comment_add(vorbis_comment *vc, char *comment); 170 | extern void vorbis_comment_add_tag(vorbis_comment *vc, 171 | char *tag, char *contents); 172 | extern char *vorbis_comment_query(vorbis_comment *vc, char *tag, int count); 173 | extern int vorbis_comment_query_count(vorbis_comment *vc, char *tag); 174 | extern void vorbis_comment_clear(vorbis_comment *vc); 175 | 176 | extern int vorbis_block_init(vorbis_dsp_state *v, vorbis_block *vb); 177 | extern int vorbis_block_clear(vorbis_block *vb); 178 | extern void vorbis_dsp_clear(vorbis_dsp_state *v); 179 | extern double vorbis_granule_time(vorbis_dsp_state *v, 180 | ogg_int64_t granulepos); 181 | 182 | /* Vorbis PRIMITIVES: analysis/DSP layer ****************************/ 183 | 184 | extern int vorbis_analysis_init(vorbis_dsp_state *v,vorbis_info *vi); 185 | extern int vorbis_commentheader_out(vorbis_comment *vc, ogg_packet *op); 186 | extern int vorbis_analysis_headerout(vorbis_dsp_state *v, 187 | vorbis_comment *vc, 188 | ogg_packet *op, 189 | ogg_packet *op_comm, 190 | ogg_packet *op_code); 191 | extern float **vorbis_analysis_buffer(vorbis_dsp_state *v,int vals); 192 | extern int vorbis_analysis_wrote(vorbis_dsp_state *v,int vals); 193 | extern int vorbis_analysis_blockout(vorbis_dsp_state *v,vorbis_block *vb); 194 | extern int vorbis_analysis(vorbis_block *vb,ogg_packet *op); 195 | 196 | extern int vorbis_bitrate_addblock(vorbis_block *vb); 197 | extern int vorbis_bitrate_flushpacket(vorbis_dsp_state *vd, 198 | ogg_packet *op); 199 | 200 | /* Vorbis PRIMITIVES: synthesis layer *******************************/ 201 | extern int vorbis_synthesis_headerin(vorbis_info *vi,vorbis_comment *vc, 202 | ogg_packet *op); 203 | 204 | extern int vorbis_synthesis_init(vorbis_dsp_state *v,vorbis_info *vi); 205 | extern int vorbis_synthesis_restart(vorbis_dsp_state *v); 206 | extern int vorbis_synthesis(vorbis_block *vb,ogg_packet *op); 207 | extern int vorbis_synthesis_trackonly(vorbis_block *vb,ogg_packet *op); 208 | extern int vorbis_synthesis_blockin(vorbis_dsp_state *v,vorbis_block *vb); 209 | extern int vorbis_synthesis_pcmout(vorbis_dsp_state *v,float ***pcm); 210 | extern int vorbis_synthesis_lapout(vorbis_dsp_state *v,float ***pcm); 211 | extern int vorbis_synthesis_read(vorbis_dsp_state *v,int samples); 212 | extern long vorbis_packet_blocksize(vorbis_info *vi,ogg_packet *op); 213 | 214 | extern int vorbis_synthesis_halfrate(vorbis_info *v,int flag); 215 | extern int vorbis_synthesis_halfrate_p(vorbis_info *v); 216 | 217 | /* Vorbis ERRORS and return codes ***********************************/ 218 | 219 | #define OV_FALSE -1 220 | #define OV_EOF -2 221 | #define OV_HOLE -3 222 | 223 | #define OV_EREAD -128 224 | #define OV_EFAULT -129 225 | #define OV_EIMPL -130 226 | #define OV_EINVAL -131 227 | #define OV_ENOTVORBIS -132 228 | #define OV_EBADHEADER -133 229 | #define OV_EVERSION -134 230 | #define OV_ENOTAUDIO -135 231 | #define OV_EBADPACKET -136 232 | #define OV_EBADLINK -137 233 | #define OV_ENOSEEK -138 234 | 235 | #ifdef __cplusplus 236 | } 237 | #endif /* __cplusplus */ 238 | 239 | #endif 240 | 241 | -------------------------------------------------------------------------------- /ThirdParty/Include/Vorbis/ogg.h: -------------------------------------------------------------------------------- 1 | /******************************************************************** 2 | * * 3 | * THIS FILE IS PART OF THE OggVorbis SOFTWARE CODEC SOURCE CODE. * 4 | * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS * 5 | * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE * 6 | * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. * 7 | * * 8 | * THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2002 * 9 | * by the Xiph.Org Foundation http://www.xiph.org/ * 10 | * * 11 | ******************************************************************** 12 | 13 | function: toplevel libogg include 14 | last mod: $Id: ogg.h 7188 2004-07-20 07:26:04Z xiphmont $ 15 | 16 | ********************************************************************/ 17 | #ifndef _OGG_H 18 | #define _OGG_H 19 | 20 | #ifdef __cplusplus 21 | extern "C" { 22 | #endif 23 | 24 | #include "os_types.h" 25 | 26 | typedef struct { 27 | long endbyte; 28 | int endbit; 29 | 30 | unsigned char *buffer; 31 | unsigned char *ptr; 32 | long storage; 33 | } oggpack_buffer; 34 | 35 | /* ogg_page is used to encapsulate the data in one Ogg bitstream page *****/ 36 | 37 | typedef struct { 38 | unsigned char *header; 39 | long header_len; 40 | unsigned char *body; 41 | long body_len; 42 | } ogg_page; 43 | 44 | /* ogg_stream_state contains the current encode/decode state of a logical 45 | Ogg bitstream **********************************************************/ 46 | 47 | typedef struct { 48 | unsigned char *body_data; /* bytes from packet bodies */ 49 | long body_storage; /* storage elements allocated */ 50 | long body_fill; /* elements stored; fill mark */ 51 | long body_returned; /* elements of fill returned */ 52 | 53 | 54 | int *lacing_vals; /* The values that will go to the segment table */ 55 | ogg_int64_t *granule_vals; /* granulepos values for headers. Not compact 56 | this way, but it is simple coupled to the 57 | lacing fifo */ 58 | long lacing_storage; 59 | long lacing_fill; 60 | long lacing_packet; 61 | long lacing_returned; 62 | 63 | unsigned char header[282]; /* working space for header encode */ 64 | int header_fill; 65 | 66 | int e_o_s; /* set when we have buffered the last packet in the 67 | logical bitstream */ 68 | int b_o_s; /* set after we've written the initial page 69 | of a logical bitstream */ 70 | long serialno; 71 | long pageno; 72 | ogg_int64_t packetno; /* sequence number for decode; the framing 73 | knows where there's a hole in the data, 74 | but we need coupling so that the codec 75 | (which is in a seperate abstraction 76 | layer) also knows about the gap */ 77 | ogg_int64_t granulepos; 78 | 79 | } ogg_stream_state; 80 | 81 | /* ogg_packet is used to encapsulate the data and metadata belonging 82 | to a single raw Ogg/Vorbis packet *************************************/ 83 | 84 | typedef struct { 85 | unsigned char *packet; 86 | long bytes; 87 | long b_o_s; 88 | long e_o_s; 89 | 90 | ogg_int64_t granulepos; 91 | 92 | ogg_int64_t packetno; /* sequence number for decode; the framing 93 | knows where there's a hole in the data, 94 | but we need coupling so that the codec 95 | (which is in a seperate abstraction 96 | layer) also knows about the gap */ 97 | } ogg_packet; 98 | 99 | typedef struct { 100 | unsigned char *data; 101 | int storage; 102 | int fill; 103 | int returned; 104 | 105 | int unsynced; 106 | int headerbytes; 107 | int bodybytes; 108 | } ogg_sync_state; 109 | 110 | /* Ogg BITSTREAM PRIMITIVES: bitstream ************************/ 111 | 112 | extern void oggpack_writeinit(oggpack_buffer *b); 113 | extern void oggpack_writetrunc(oggpack_buffer *b,long bits); 114 | extern void oggpack_writealign(oggpack_buffer *b); 115 | extern void oggpack_writecopy(oggpack_buffer *b,void *source,long bits); 116 | extern void oggpack_reset(oggpack_buffer *b); 117 | extern void oggpack_writeclear(oggpack_buffer *b); 118 | extern void oggpack_readinit(oggpack_buffer *b,unsigned char *buf,int bytes); 119 | extern void oggpack_write(oggpack_buffer *b,unsigned long value,int bits); 120 | extern long oggpack_look(oggpack_buffer *b,int bits); 121 | extern long oggpack_look1(oggpack_buffer *b); 122 | extern void oggpack_adv(oggpack_buffer *b,int bits); 123 | extern void oggpack_adv1(oggpack_buffer *b); 124 | extern long oggpack_read(oggpack_buffer *b,int bits); 125 | extern long oggpack_read1(oggpack_buffer *b); 126 | extern long oggpack_bytes(oggpack_buffer *b); 127 | extern long oggpack_bits(oggpack_buffer *b); 128 | extern unsigned char *oggpack_get_buffer(oggpack_buffer *b); 129 | 130 | extern void oggpackB_writeinit(oggpack_buffer *b); 131 | extern void oggpackB_writetrunc(oggpack_buffer *b,long bits); 132 | extern void oggpackB_writealign(oggpack_buffer *b); 133 | extern void oggpackB_writecopy(oggpack_buffer *b,void *source,long bits); 134 | extern void oggpackB_reset(oggpack_buffer *b); 135 | extern void oggpackB_writeclear(oggpack_buffer *b); 136 | extern void oggpackB_readinit(oggpack_buffer *b,unsigned char *buf,int bytes); 137 | extern void oggpackB_write(oggpack_buffer *b,unsigned long value,int bits); 138 | extern long oggpackB_look(oggpack_buffer *b,int bits); 139 | extern long oggpackB_look1(oggpack_buffer *b); 140 | extern void oggpackB_adv(oggpack_buffer *b,int bits); 141 | extern void oggpackB_adv1(oggpack_buffer *b); 142 | extern long oggpackB_read(oggpack_buffer *b,int bits); 143 | extern long oggpackB_read1(oggpack_buffer *b); 144 | extern long oggpackB_bytes(oggpack_buffer *b); 145 | extern long oggpackB_bits(oggpack_buffer *b); 146 | extern unsigned char *oggpackB_get_buffer(oggpack_buffer *b); 147 | 148 | /* Ogg BITSTREAM PRIMITIVES: encoding **************************/ 149 | 150 | extern int ogg_stream_packetin(ogg_stream_state *os, ogg_packet *op); 151 | extern int ogg_stream_pageout(ogg_stream_state *os, ogg_page *og); 152 | extern int ogg_stream_flush(ogg_stream_state *os, ogg_page *og); 153 | 154 | /* Ogg BITSTREAM PRIMITIVES: decoding **************************/ 155 | 156 | extern int ogg_sync_init(ogg_sync_state *oy); 157 | extern int ogg_sync_clear(ogg_sync_state *oy); 158 | extern int ogg_sync_reset(ogg_sync_state *oy); 159 | extern int ogg_sync_destroy(ogg_sync_state *oy); 160 | 161 | extern char *ogg_sync_buffer(ogg_sync_state *oy, long size); 162 | extern int ogg_sync_wrote(ogg_sync_state *oy, long bytes); 163 | extern long ogg_sync_pageseek(ogg_sync_state *oy,ogg_page *og); 164 | extern int ogg_sync_pageout(ogg_sync_state *oy, ogg_page *og); 165 | extern int ogg_stream_pagein(ogg_stream_state *os, ogg_page *og); 166 | extern int ogg_stream_packetout(ogg_stream_state *os,ogg_packet *op); 167 | extern int ogg_stream_packetpeek(ogg_stream_state *os,ogg_packet *op); 168 | 169 | /* Ogg BITSTREAM PRIMITIVES: general ***************************/ 170 | 171 | extern int ogg_stream_init(ogg_stream_state *os,int serialno); 172 | extern int ogg_stream_clear(ogg_stream_state *os); 173 | extern int ogg_stream_reset(ogg_stream_state *os); 174 | extern int ogg_stream_reset_serialno(ogg_stream_state *os,int serialno); 175 | extern int ogg_stream_destroy(ogg_stream_state *os); 176 | extern int ogg_stream_eos(ogg_stream_state *os); 177 | 178 | extern void ogg_page_checksum_set(ogg_page *og); 179 | 180 | extern int ogg_page_version(ogg_page *og); 181 | extern int ogg_page_continued(ogg_page *og); 182 | extern int ogg_page_bos(ogg_page *og); 183 | extern int ogg_page_eos(ogg_page *og); 184 | extern ogg_int64_t ogg_page_granulepos(ogg_page *og); 185 | extern int ogg_page_serialno(ogg_page *og); 186 | extern long ogg_page_pageno(ogg_page *og); 187 | extern int ogg_page_packets(ogg_page *og); 188 | 189 | extern void ogg_packet_clear(ogg_packet *op); 190 | 191 | 192 | #ifdef __cplusplus 193 | } 194 | #endif 195 | 196 | #endif /* _OGG_H */ 197 | 198 | 199 | 200 | 201 | 202 | 203 | -------------------------------------------------------------------------------- /ThirdParty/Include/Vorbis/os_types.h: -------------------------------------------------------------------------------- 1 | /******************************************************************** 2 | * * 3 | * THIS FILE IS PART OF THE OggVorbis SOFTWARE CODEC SOURCE CODE. * 4 | * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS * 5 | * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE * 6 | * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. * 7 | * * 8 | * THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2002 * 9 | * by the Xiph.Org Foundation http://www.xiph.org/ * 10 | * * 11 | ******************************************************************** 12 | 13 | function: #ifdef jail to whip a few platforms into the UNIX ideal. 14 | last mod: $Id: os_types.h 7524 2004-08-11 04:20:36Z conrad $ 15 | 16 | ********************************************************************/ 17 | #ifndef _OS_TYPES_H 18 | #define _OS_TYPES_H 19 | 20 | /* make it easy on the folks that want to compile the libs with a 21 | different malloc than stdlib */ 22 | #define _ogg_malloc malloc 23 | #define _ogg_calloc calloc 24 | #define _ogg_realloc realloc 25 | #define _ogg_free free 26 | 27 | #if defined(_WIN32) 28 | 29 | # if defined(__CYGWIN__) 30 | # include <_G_config.h> 31 | typedef _G_int64_t ogg_int64_t; 32 | typedef _G_int32_t ogg_int32_t; 33 | typedef _G_uint32_t ogg_uint32_t; 34 | typedef _G_int16_t ogg_int16_t; 35 | typedef _G_uint16_t ogg_uint16_t; 36 | # elif defined(__MINGW32__) 37 | typedef short ogg_int16_t; 38 | typedef unsigned short ogg_uint16_t; 39 | typedef int ogg_int32_t; 40 | typedef unsigned int ogg_uint32_t; 41 | typedef long long ogg_int64_t; 42 | typedef unsigned long long ogg_uint64_t; 43 | # elif defined(__MWERKS__) 44 | typedef long long ogg_int64_t; 45 | typedef int ogg_int32_t; 46 | typedef unsigned int ogg_uint32_t; 47 | typedef short ogg_int16_t; 48 | typedef unsigned short ogg_uint16_t; 49 | # else 50 | /* MSVC/Borland */ 51 | typedef __int64 ogg_int64_t; 52 | typedef __int32 ogg_int32_t; 53 | typedef unsigned __int32 ogg_uint32_t; 54 | typedef __int16 ogg_int16_t; 55 | typedef unsigned __int16 ogg_uint16_t; 56 | # endif 57 | 58 | #elif defined(__MACOS__) 59 | 60 | # include 61 | typedef SInt16 ogg_int16_t; 62 | typedef UInt16 ogg_uint16_t; 63 | typedef SInt32 ogg_int32_t; 64 | typedef UInt32 ogg_uint32_t; 65 | typedef SInt64 ogg_int64_t; 66 | 67 | #elif defined(__MACOSX__) /* MacOS X Framework build */ 68 | 69 | # include 70 | typedef int16_t ogg_int16_t; 71 | typedef u_int16_t ogg_uint16_t; 72 | typedef int32_t ogg_int32_t; 73 | typedef u_int32_t ogg_uint32_t; 74 | typedef int64_t ogg_int64_t; 75 | 76 | #elif defined(__BEOS__) 77 | 78 | /* Be */ 79 | # include 80 | typedef int16_t ogg_int16_t; 81 | typedef u_int16_t ogg_uint16_t; 82 | typedef int32_t ogg_int32_t; 83 | typedef u_int32_t ogg_uint32_t; 84 | typedef int64_t ogg_int64_t; 85 | 86 | #elif defined (__EMX__) 87 | 88 | /* OS/2 GCC */ 89 | typedef short ogg_int16_t; 90 | typedef unsigned short ogg_uint16_t; 91 | typedef int ogg_int32_t; 92 | typedef unsigned int ogg_uint32_t; 93 | typedef long long ogg_int64_t; 94 | 95 | #elif defined (DJGPP) 96 | 97 | /* DJGPP */ 98 | typedef short ogg_int16_t; 99 | typedef int ogg_int32_t; 100 | typedef unsigned int ogg_uint32_t; 101 | typedef long long ogg_int64_t; 102 | 103 | #elif defined(R5900) 104 | 105 | /* PS2 EE */ 106 | typedef long ogg_int64_t; 107 | typedef int ogg_int32_t; 108 | typedef unsigned ogg_uint32_t; 109 | typedef short ogg_int16_t; 110 | 111 | #elif defined(__SYMBIAN32__) 112 | 113 | /* Symbian GCC */ 114 | typedef signed short ogg_int16_t; 115 | typedef unsigned short ogg_uint16_t; 116 | typedef signed int ogg_int32_t; 117 | typedef unsigned int ogg_uint32_t; 118 | typedef long long int ogg_int64_t; 119 | 120 | #else 121 | 122 | # include 123 | # include 124 | 125 | #endif 126 | 127 | #endif /* _OS_TYPES_H */ 128 | -------------------------------------------------------------------------------- /ThirdParty/Include/Vorbis/vorbisfile.h: -------------------------------------------------------------------------------- 1 | /******************************************************************** 2 | * * 3 | * THIS FILE IS PART OF THE OggVorbis SOFTWARE CODEC SOURCE CODE. * 4 | * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS * 5 | * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE * 6 | * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. * 7 | * * 8 | * THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2001 * 9 | * by the XIPHOPHORUS Company http://www.xiph.org/ * 10 | * * 11 | ******************************************************************** 12 | 13 | function: stdio-based convenience library for opening/seeking/decoding 14 | last mod: $Id: vorbisfile.h 7485 2004-08-05 14:54:23Z thomasvs $ 15 | 16 | ********************************************************************/ 17 | 18 | #ifndef _OV_FILE_H_ 19 | #define _OV_FILE_H_ 20 | 21 | #ifdef __cplusplus 22 | extern "C" 23 | { 24 | #endif /* __cplusplus */ 25 | 26 | #include 27 | #include "codec.h" 28 | 29 | /* The function prototypes for the callbacks are basically the same as for 30 | * the stdio functions fread, fseek, fclose, ftell. 31 | * The one difference is that the FILE * arguments have been replaced with 32 | * a void * - this is to be used as a pointer to whatever internal data these 33 | * functions might need. In the stdio case, it's just a FILE * cast to a void * 34 | * 35 | * If you use other functions, check the docs for these functions and return 36 | * the right values. For seek_func(), you *MUST* return -1 if the stream is 37 | * unseekable 38 | */ 39 | typedef struct { 40 | size_t (*read_func) (void *ptr, size_t size, size_t nmemb, void *datasource); 41 | int (*seek_func) (void *datasource, ogg_int64_t offset, int whence); 42 | int (*close_func) (void *datasource); 43 | long (*tell_func) (void *datasource); 44 | } ov_callbacks; 45 | 46 | #define NOTOPEN 0 47 | #define PARTOPEN 1 48 | #define OPENED 2 49 | #define STREAMSET 3 50 | #define INITSET 4 51 | 52 | typedef struct OggVorbis_File { 53 | void *datasource; /* Pointer to a FILE *, etc. */ 54 | int seekable; 55 | ogg_int64_t offset; 56 | ogg_int64_t end; 57 | ogg_sync_state oy; 58 | 59 | /* If the FILE handle isn't seekable (eg, a pipe), only the current 60 | stream appears */ 61 | int links; 62 | ogg_int64_t *offsets; 63 | ogg_int64_t *dataoffsets; 64 | long *serialnos; 65 | ogg_int64_t *pcmlengths; /* overloaded to maintain binary 66 | compatability; x2 size, stores both 67 | beginning and end values */ 68 | vorbis_info *vi; 69 | vorbis_comment *vc; 70 | 71 | /* Decoding working state local storage */ 72 | ogg_int64_t pcm_offset; 73 | int ready_state; 74 | long current_serialno; 75 | int current_link; 76 | 77 | double bittrack; 78 | double samptrack; 79 | 80 | ogg_stream_state os; /* take physical pages, weld into a logical 81 | stream of packets */ 82 | vorbis_dsp_state vd; /* central working state for the packet->PCM decoder */ 83 | vorbis_block vb; /* local working space for packet->PCM decode */ 84 | 85 | ov_callbacks callbacks; 86 | 87 | } OggVorbis_File; 88 | 89 | extern int ov_clear(OggVorbis_File *vf); 90 | extern int ov_open(FILE *f,OggVorbis_File *vf,char *initial,long ibytes); 91 | extern int ov_open_callbacks(void *datasource, OggVorbis_File *vf, 92 | char *initial, long ibytes, ov_callbacks callbacks); 93 | 94 | extern int ov_test(FILE *f,OggVorbis_File *vf,char *initial,long ibytes); 95 | extern int ov_test_callbacks(void *datasource, OggVorbis_File *vf, 96 | char *initial, long ibytes, ov_callbacks callbacks); 97 | extern int ov_test_open(OggVorbis_File *vf); 98 | 99 | extern long ov_bitrate(OggVorbis_File *vf,int i); 100 | extern long ov_bitrate_instant(OggVorbis_File *vf); 101 | extern long ov_streams(OggVorbis_File *vf); 102 | extern long ov_seekable(OggVorbis_File *vf); 103 | extern long ov_serialnumber(OggVorbis_File *vf,int i); 104 | 105 | extern ogg_int64_t ov_raw_total(OggVorbis_File *vf,int i); 106 | extern ogg_int64_t ov_pcm_total(OggVorbis_File *vf,int i); 107 | extern double ov_time_total(OggVorbis_File *vf,int i); 108 | 109 | extern int ov_raw_seek(OggVorbis_File *vf,ogg_int64_t pos); 110 | extern int ov_pcm_seek(OggVorbis_File *vf,ogg_int64_t pos); 111 | extern int ov_pcm_seek_page(OggVorbis_File *vf,ogg_int64_t pos); 112 | extern int ov_time_seek(OggVorbis_File *vf,double pos); 113 | extern int ov_time_seek_page(OggVorbis_File *vf,double pos); 114 | 115 | extern int ov_raw_seek_lap(OggVorbis_File *vf,ogg_int64_t pos); 116 | extern int ov_pcm_seek_lap(OggVorbis_File *vf,ogg_int64_t pos); 117 | extern int ov_pcm_seek_page_lap(OggVorbis_File *vf,ogg_int64_t pos); 118 | extern int ov_time_seek_lap(OggVorbis_File *vf,double pos); 119 | extern int ov_time_seek_page_lap(OggVorbis_File *vf,double pos); 120 | 121 | extern ogg_int64_t ov_raw_tell(OggVorbis_File *vf); 122 | extern ogg_int64_t ov_pcm_tell(OggVorbis_File *vf); 123 | extern double ov_time_tell(OggVorbis_File *vf); 124 | 125 | extern vorbis_info *ov_info(OggVorbis_File *vf,int link); 126 | extern vorbis_comment *ov_comment(OggVorbis_File *vf,int link); 127 | 128 | extern long ov_read_float(OggVorbis_File *vf,float ***pcm_channels,int samples, 129 | int *bitstream); 130 | extern long ov_read(OggVorbis_File *vf,char *buffer,int length, 131 | int bigendianp,int word,int sgned,int *bitstream); 132 | extern int ov_crosslap(OggVorbis_File *vf1,OggVorbis_File *vf2); 133 | 134 | extern int ov_halfrate(OggVorbis_File *vf,int flag); 135 | extern int ov_halfrate_p(OggVorbis_File *vf); 136 | 137 | #ifdef __cplusplus 138 | } 139 | #endif /* __cplusplus */ 140 | 141 | #endif 142 | 143 | 144 | -------------------------------------------------------------------------------- /ThirdParty/Include/XAudio2_7/X3DAudio.h: -------------------------------------------------------------------------------- 1 | /*-========================================================================-_ 2 | | - X3DAUDIO - | 3 | | Copyright (c) Microsoft Corporation. All rights reserved. | 4 | |~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~| 5 | |PROJECT: X3DAudio MODEL: Unmanaged User-mode | 6 | |VERSION: 2.7 EXCEPT: No Exceptions | 7 | |CLASS: N / A MINREQ: WinXP, Xbox360 | 8 | |BASE: N / A DIALECT: MSC++ 14.00 | 9 | |>------------------------------------------------------------------------<| 10 | | DUTY: Cross-platform stand-alone 3D audio math library | 11 | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^ 12 | NOTES: 13 | 1. USE THE DEBUG DLL TO ENABLE PARAMETER VALIDATION VIA ASSERTS! 14 | Here's how: 15 | Copy X3DAudioDX_X.dll to where your application exists. 16 | The debug DLL can be found under %WINDIR%\system32. 17 | Rename X3DAudioDX_X.dll to X3DAudioX_X.dll to use the debug version. 18 | 19 | Only parameters required by DSP settings being calculated as 20 | stipulated by the calculation control flags are validated. 21 | 22 | 2. Definition of terms: 23 | LFE: Low Frequency Effect -- always omnidirectional. 24 | LPF: Low Pass Filter, divided into two classifications: 25 | Direct -- Applied to the direct signal path, 26 | used for obstruction/occlusion effects. 27 | Reverb -- Applied to the reverb signal path, 28 | used for occlusion effects only. 29 | 30 | 3. Volume level is expressed as a linear amplitude scaler: 31 | 1.0f represents no attenuation applied to the original signal, 32 | 0.5f denotes an attenuation of 6dB, and 0.0f results in silence. 33 | Amplification (volume > 1.0f) is also allowed, and is not clamped. 34 | 35 | LPF values range from 1.0f representing all frequencies pass through, 36 | to 0.0f which results in silence as all frequencies are filtered out. 37 | 38 | 4. X3DAudio uses a left-handed Cartesian coordinate system with values 39 | on the x-axis increasing from left to right, on the y-axis from 40 | bottom to top, and on the z-axis from near to far. 41 | Azimuths are measured clockwise from a given reference direction. 42 | 43 | Distance measurement is with respect to user-defined world units. 44 | Applications may provide coordinates using any system of measure 45 | as all non-normalized calculations are scale invariant, with such 46 | operations natively occurring in user-defined world unit space. 47 | Metric constants are supplied only as a convenience. 48 | Distance is calculated using the Euclidean norm formula. 49 | 50 | 5. Only real values are permissible with functions using 32-bit 51 | float parameters -- NAN and infinite values are not accepted. 52 | All computation occurs in 32-bit precision mode. */ 53 | 54 | #pragma once 55 | //---------------------------------------------------// 56 | #include // general windows types 57 | #if defined(_XBOX) 58 | #include 59 | #endif 60 | #include // for D3DVECTOR 61 | 62 | // speaker geometry configuration flags, specifies assignment of channels to speaker positions, defined as per WAVEFORMATEXTENSIBLE.dwChannelMask 63 | #if !defined(_SPEAKER_POSITIONS_) 64 | #define _SPEAKER_POSITIONS_ 65 | #define SPEAKER_FRONT_LEFT 0x00000001 66 | #define SPEAKER_FRONT_RIGHT 0x00000002 67 | #define SPEAKER_FRONT_CENTER 0x00000004 68 | #define SPEAKER_LOW_FREQUENCY 0x00000008 69 | #define SPEAKER_BACK_LEFT 0x00000010 70 | #define SPEAKER_BACK_RIGHT 0x00000020 71 | #define SPEAKER_FRONT_LEFT_OF_CENTER 0x00000040 72 | #define SPEAKER_FRONT_RIGHT_OF_CENTER 0x00000080 73 | #define SPEAKER_BACK_CENTER 0x00000100 74 | #define SPEAKER_SIDE_LEFT 0x00000200 75 | #define SPEAKER_SIDE_RIGHT 0x00000400 76 | #define SPEAKER_TOP_CENTER 0x00000800 77 | #define SPEAKER_TOP_FRONT_LEFT 0x00001000 78 | #define SPEAKER_TOP_FRONT_CENTER 0x00002000 79 | #define SPEAKER_TOP_FRONT_RIGHT 0x00004000 80 | #define SPEAKER_TOP_BACK_LEFT 0x00008000 81 | #define SPEAKER_TOP_BACK_CENTER 0x00010000 82 | #define SPEAKER_TOP_BACK_RIGHT 0x00020000 83 | #define SPEAKER_RESERVED 0x7FFC0000 // bit mask locations reserved for future use 84 | #define SPEAKER_ALL 0x80000000 // used to specify that any possible permutation of speaker configurations 85 | #endif 86 | 87 | // standard speaker geometry configurations, used with X3DAudioInitialize 88 | #if !defined(SPEAKER_MONO) 89 | #define SPEAKER_MONO SPEAKER_FRONT_CENTER 90 | #define SPEAKER_STEREO (SPEAKER_FRONT_LEFT | SPEAKER_FRONT_RIGHT) 91 | #define SPEAKER_2POINT1 (SPEAKER_FRONT_LEFT | SPEAKER_FRONT_RIGHT | SPEAKER_LOW_FREQUENCY) 92 | #define SPEAKER_SURROUND (SPEAKER_FRONT_LEFT | SPEAKER_FRONT_RIGHT | SPEAKER_FRONT_CENTER | SPEAKER_BACK_CENTER) 93 | #define SPEAKER_QUAD (SPEAKER_FRONT_LEFT | SPEAKER_FRONT_RIGHT | SPEAKER_BACK_LEFT | SPEAKER_BACK_RIGHT) 94 | #define SPEAKER_4POINT1 (SPEAKER_FRONT_LEFT | SPEAKER_FRONT_RIGHT | SPEAKER_LOW_FREQUENCY | SPEAKER_BACK_LEFT | SPEAKER_BACK_RIGHT) 95 | #define SPEAKER_5POINT1 (SPEAKER_FRONT_LEFT | SPEAKER_FRONT_RIGHT | SPEAKER_FRONT_CENTER | SPEAKER_LOW_FREQUENCY | SPEAKER_BACK_LEFT | SPEAKER_BACK_RIGHT) 96 | #define SPEAKER_7POINT1 (SPEAKER_FRONT_LEFT | SPEAKER_FRONT_RIGHT | SPEAKER_FRONT_CENTER | SPEAKER_LOW_FREQUENCY | SPEAKER_BACK_LEFT | SPEAKER_BACK_RIGHT | SPEAKER_FRONT_LEFT_OF_CENTER | SPEAKER_FRONT_RIGHT_OF_CENTER) 97 | #define SPEAKER_5POINT1_SURROUND (SPEAKER_FRONT_LEFT | SPEAKER_FRONT_RIGHT | SPEAKER_FRONT_CENTER | SPEAKER_LOW_FREQUENCY | SPEAKER_SIDE_LEFT | SPEAKER_SIDE_RIGHT) 98 | #define SPEAKER_7POINT1_SURROUND (SPEAKER_FRONT_LEFT | SPEAKER_FRONT_RIGHT | SPEAKER_FRONT_CENTER | SPEAKER_LOW_FREQUENCY | SPEAKER_BACK_LEFT | SPEAKER_BACK_RIGHT | SPEAKER_SIDE_LEFT | SPEAKER_SIDE_RIGHT) 99 | #endif 100 | 101 | // Xbox360 speaker geometry configuration, used with X3DAudioInitialize 102 | #if defined(_XBOX) 103 | #define SPEAKER_XBOX SPEAKER_5POINT1 104 | #endif 105 | 106 | 107 | // size of instance handle in bytes 108 | #define X3DAUDIO_HANDLE_BYTESIZE 20 109 | 110 | // float math constants 111 | #define X3DAUDIO_PI 3.141592654f 112 | #define X3DAUDIO_2PI 6.283185307f 113 | 114 | // speed of sound in meters per second for dry air at approximately 20C, used with X3DAudioInitialize 115 | #define X3DAUDIO_SPEED_OF_SOUND 343.5f 116 | 117 | // calculation control flags, used with X3DAudioCalculate 118 | #define X3DAUDIO_CALCULATE_MATRIX 0x00000001 // enable matrix coefficient table calculation 119 | #define X3DAUDIO_CALCULATE_DELAY 0x00000002 // enable delay time array calculation (stereo final mix only) 120 | #define X3DAUDIO_CALCULATE_LPF_DIRECT 0x00000004 // enable LPF direct-path coefficient calculation 121 | #define X3DAUDIO_CALCULATE_LPF_REVERB 0x00000008 // enable LPF reverb-path coefficient calculation 122 | #define X3DAUDIO_CALCULATE_REVERB 0x00000010 // enable reverb send level calculation 123 | #define X3DAUDIO_CALCULATE_DOPPLER 0x00000020 // enable doppler shift factor calculation 124 | #define X3DAUDIO_CALCULATE_EMITTER_ANGLE 0x00000040 // enable emitter-to-listener interior angle calculation 125 | 126 | #define X3DAUDIO_CALCULATE_ZEROCENTER 0x00010000 // do not position to front center speaker, signal positioned to remaining speakers instead, front center destination channel will be zero in returned matrix coefficient table, valid only for matrix calculations with final mix formats that have a front center channel 127 | #define X3DAUDIO_CALCULATE_REDIRECT_TO_LFE 0x00020000 // apply equal mix of all source channels to LFE destination channel, valid only for matrix calculations with sources that have no LFE channel and final mix formats that have an LFE channel 128 | 129 | 130 | //-----------------------------------------------------// 131 | #pragma pack(push, 1) // set packing alignment to ensure consistency across arbitrary build environments 132 | 133 | 134 | // primitive types 135 | typedef float FLOAT32; // 32-bit IEEE float 136 | typedef D3DVECTOR X3DAUDIO_VECTOR; // float 3D vector 137 | 138 | // instance handle of precalculated constants 139 | typedef BYTE X3DAUDIO_HANDLE[X3DAUDIO_HANDLE_BYTESIZE]; 140 | 141 | 142 | // Distance curve point: 143 | // Defines a DSP setting at a given normalized distance. 144 | typedef struct X3DAUDIO_DISTANCE_CURVE_POINT 145 | { 146 | FLOAT32 Distance; // normalized distance, must be within [0.0f, 1.0f] 147 | FLOAT32 DSPSetting; // DSP setting 148 | } X3DAUDIO_DISTANCE_CURVE_POINT, *LPX3DAUDIO_DISTANCE_CURVE_POINT; 149 | 150 | // Distance curve: 151 | // A piecewise curve made up of linear segments used to 152 | // define DSP behaviour with respect to normalized distance. 153 | // 154 | // Note that curve point distances are normalized within [0.0f, 1.0f]. 155 | // X3DAUDIO_EMITTER.CurveDistanceScaler must be used to scale the 156 | // normalized distances to user-defined world units. 157 | // For distances beyond CurveDistanceScaler * 1.0f, 158 | // pPoints[PointCount-1].DSPSetting is used as the DSP setting. 159 | // 160 | // All distance curve spans must be such that: 161 | // pPoints[k-1].DSPSetting + ((pPoints[k].DSPSetting-pPoints[k-1].DSPSetting) / (pPoints[k].Distance-pPoints[k-1].Distance)) * (pPoints[k].Distance-pPoints[k-1].Distance) != NAN or infinite values 162 | // For all points in the distance curve where 1 <= k < PointCount. 163 | typedef struct X3DAUDIO_DISTANCE_CURVE 164 | { 165 | X3DAUDIO_DISTANCE_CURVE_POINT* pPoints; // distance curve point array, must have at least PointCount elements with no duplicates and be sorted in ascending order with respect to Distance 166 | UINT32 PointCount; // number of distance curve points, must be >= 2 as all distance curves must have at least two endpoints, defining DSP settings at 0.0f and 1.0f normalized distance 167 | } X3DAUDIO_DISTANCE_CURVE, *LPX3DAUDIO_DISTANCE_CURVE; 168 | static const X3DAUDIO_DISTANCE_CURVE_POINT X3DAudioDefault_LinearCurvePoints[2] = { 0.0f, 1.0f, 1.0f, 0.0f }; 169 | static const X3DAUDIO_DISTANCE_CURVE X3DAudioDefault_LinearCurve = { (X3DAUDIO_DISTANCE_CURVE_POINT*)&X3DAudioDefault_LinearCurvePoints[0], 2 }; 170 | 171 | // Cone: 172 | // Specifies directionality for a listener or single-channel emitter by 173 | // modifying DSP behaviour with respect to its front orientation. 174 | // This is modeled using two sound cones: an inner cone and an outer cone. 175 | // On/within the inner cone, DSP settings are scaled by the inner values. 176 | // On/beyond the outer cone, DSP settings are scaled by the outer values. 177 | // If on both the cones, DSP settings are scaled by the inner values only. 178 | // Between the two cones, the scaler is linearly interpolated between the 179 | // inner and outer values. Set both cone angles to 0 or X3DAUDIO_2PI for 180 | // omnidirectionality using only the outer or inner values respectively. 181 | typedef struct X3DAUDIO_CONE 182 | { 183 | FLOAT32 InnerAngle; // inner cone angle in radians, must be within [0.0f, X3DAUDIO_2PI] 184 | FLOAT32 OuterAngle; // outer cone angle in radians, must be within [InnerAngle, X3DAUDIO_2PI] 185 | 186 | FLOAT32 InnerVolume; // volume level scaler on/within inner cone, used only for matrix calculations, must be within [0.0f, 2.0f] when used 187 | FLOAT32 OuterVolume; // volume level scaler on/beyond outer cone, used only for matrix calculations, must be within [0.0f, 2.0f] when used 188 | FLOAT32 InnerLPF; // LPF (both direct and reverb paths) coefficient subtrahend on/within inner cone, used only for LPF (both direct and reverb paths) calculations, must be within [0.0f, 1.0f] when used 189 | FLOAT32 OuterLPF; // LPF (both direct and reverb paths) coefficient subtrahend on/beyond outer cone, used only for LPF (both direct and reverb paths) calculations, must be within [0.0f, 1.0f] when used 190 | FLOAT32 InnerReverb; // reverb send level scaler on/within inner cone, used only for reverb calculations, must be within [0.0f, 2.0f] when used 191 | FLOAT32 OuterReverb; // reverb send level scaler on/beyond outer cone, used only for reverb calculations, must be within [0.0f, 2.0f] when used 192 | } X3DAUDIO_CONE, *LPX3DAUDIO_CONE; 193 | static const X3DAUDIO_CONE X3DAudioDefault_DirectionalCone = { X3DAUDIO_PI/2, X3DAUDIO_PI, 1.0f, 0.708f, 0.0f, 0.25f, 0.708f, 1.0f }; 194 | 195 | 196 | // Listener: 197 | // Defines a point of 3D audio reception. 198 | // 199 | // The cone is directed by the listener's front orientation. 200 | typedef struct X3DAUDIO_LISTENER 201 | { 202 | X3DAUDIO_VECTOR OrientFront; // orientation of front direction, used only for matrix and delay calculations or listeners with cones for matrix, LPF (both direct and reverb paths), and reverb calculations, must be normalized when used 203 | X3DAUDIO_VECTOR OrientTop; // orientation of top direction, used only for matrix and delay calculations, must be orthonormal with OrientFront when used 204 | 205 | X3DAUDIO_VECTOR Position; // position in user-defined world units, does not affect Velocity 206 | X3DAUDIO_VECTOR Velocity; // velocity vector in user-defined world units/second, used only for doppler calculations, does not affect Position 207 | 208 | X3DAUDIO_CONE* pCone; // sound cone, used only for matrix, LPF (both direct and reverb paths), and reverb calculations, NULL specifies omnidirectionality 209 | } X3DAUDIO_LISTENER, *LPX3DAUDIO_LISTENER; 210 | 211 | // Emitter: 212 | // Defines a 3D audio source, divided into two classifications: 213 | // 214 | // Single-point -- For use with single-channel sounds. 215 | // Positioned at the emitter base, i.e. the channel radius 216 | // and azimuth are ignored if the number of channels == 1. 217 | // 218 | // May be omnidirectional or directional using a cone. 219 | // The cone originates from the emitter base position, 220 | // and is directed by the emitter's front orientation. 221 | // 222 | // Multi-point -- For use with multi-channel sounds. 223 | // Each non-LFE channel is positioned using an 224 | // azimuth along the channel radius with respect to the 225 | // front orientation vector in the plane orthogonal to the 226 | // top orientation vector. An azimuth of X3DAUDIO_2PI 227 | // specifies a channel is an LFE. Such channels are 228 | // positioned at the emitter base and are calculated 229 | // with respect to pLFECurve only, never pVolumeCurve. 230 | // 231 | // Multi-point emitters are always omnidirectional, 232 | // i.e. the cone is ignored if the number of channels > 1. 233 | // 234 | // Note that many properties are shared among all channel points, 235 | // locking certain behaviour with respect to the emitter base position. 236 | // For example, doppler shift is always calculated with respect to the 237 | // emitter base position and so is constant for all its channel points. 238 | // Distance curve calculations are also with respect to the emitter base 239 | // position, with the curves being calculated independently of each other. 240 | // For instance, volume and LFE calculations do not affect one another. 241 | typedef struct X3DAUDIO_EMITTER 242 | { 243 | X3DAUDIO_CONE* pCone; // sound cone, used only with single-channel emitters for matrix, LPF (both direct and reverb paths), and reverb calculations, NULL specifies omnidirectionality 244 | X3DAUDIO_VECTOR OrientFront; // orientation of front direction, used only for emitter angle calculations or with multi-channel emitters for matrix calculations or single-channel emitters with cones for matrix, LPF (both direct and reverb paths), and reverb calculations, must be normalized when used 245 | X3DAUDIO_VECTOR OrientTop; // orientation of top direction, used only with multi-channel emitters for matrix calculations, must be orthonormal with OrientFront when used 246 | 247 | X3DAUDIO_VECTOR Position; // position in user-defined world units, does not affect Velocity 248 | X3DAUDIO_VECTOR Velocity; // velocity vector in user-defined world units/second, used only for doppler calculations, does not affect Position 249 | 250 | FLOAT32 InnerRadius; // inner radius, must be within [0.0f, FLT_MAX] 251 | FLOAT32 InnerRadiusAngle; // inner radius angle, must be within [0.0f, X3DAUDIO_PI/4.0) 252 | 253 | UINT32 ChannelCount; // number of sound channels, must be > 0 254 | FLOAT32 ChannelRadius; // channel radius, used only with multi-channel emitters for matrix calculations, must be >= 0.0f when used 255 | FLOAT32* pChannelAzimuths; // channel azimuth array, used only with multi-channel emitters for matrix calculations, contains positions of each channel expressed in radians along the channel radius with respect to the front orientation vector in the plane orthogonal to the top orientation vector, or X3DAUDIO_2PI to specify an LFE channel, must have at least ChannelCount elements, all within [0.0f, X3DAUDIO_2PI] when used 256 | 257 | X3DAUDIO_DISTANCE_CURVE* pVolumeCurve; // volume level distance curve, used only for matrix calculations, NULL specifies a default curve that conforms to the inverse square law, calculated in user-defined world units with distances <= CurveDistanceScaler clamped to no attenuation 258 | X3DAUDIO_DISTANCE_CURVE* pLFECurve; // LFE level distance curve, used only for matrix calculations, NULL specifies a default curve that conforms to the inverse square law, calculated in user-defined world units with distances <= CurveDistanceScaler clamped to no attenuation 259 | X3DAUDIO_DISTANCE_CURVE* pLPFDirectCurve; // LPF direct-path coefficient distance curve, used only for LPF direct-path calculations, NULL specifies the default curve: [0.0f,1.0f], [1.0f,0.75f] 260 | X3DAUDIO_DISTANCE_CURVE* pLPFReverbCurve; // LPF reverb-path coefficient distance curve, used only for LPF reverb-path calculations, NULL specifies the default curve: [0.0f,0.75f], [1.0f,0.75f] 261 | X3DAUDIO_DISTANCE_CURVE* pReverbCurve; // reverb send level distance curve, used only for reverb calculations, NULL specifies the default curve: [0.0f,1.0f], [1.0f,0.0f] 262 | 263 | FLOAT32 CurveDistanceScaler; // curve distance scaler, used to scale normalized distance curves to user-defined world units and/or exaggerate their effect, used only for matrix, LPF (both direct and reverb paths), and reverb calculations, must be within [FLT_MIN, FLT_MAX] when used 264 | FLOAT32 DopplerScaler; // doppler shift scaler, used to exaggerate doppler shift effect, used only for doppler calculations, must be within [0.0f, FLT_MAX] when used 265 | } X3DAUDIO_EMITTER, *LPX3DAUDIO_EMITTER; 266 | 267 | 268 | // DSP settings: 269 | // Receives results from a call to X3DAudioCalculate to be sent 270 | // to the low-level audio rendering API for 3D signal processing. 271 | // 272 | // The user is responsible for allocating the matrix coefficient table, 273 | // delay time array, and initializing the channel counts when used. 274 | typedef struct X3DAUDIO_DSP_SETTINGS 275 | { 276 | FLOAT32* pMatrixCoefficients; // [inout] matrix coefficient table, receives an array representing the volume level used to send from source channel S to destination channel D, stored as pMatrixCoefficients[SrcChannelCount * D + S], must have at least SrcChannelCount*DstChannelCount elements 277 | FLOAT32* pDelayTimes; // [inout] delay time array, receives delays for each destination channel in milliseconds, must have at least DstChannelCount elements (stereo final mix only) 278 | UINT32 SrcChannelCount; // [in] number of source channels, must equal number of channels in respective emitter 279 | UINT32 DstChannelCount; // [in] number of destination channels, must equal number of channels of the final mix 280 | 281 | FLOAT32 LPFDirectCoefficient; // [out] LPF direct-path coefficient 282 | FLOAT32 LPFReverbCoefficient; // [out] LPF reverb-path coefficient 283 | FLOAT32 ReverbLevel; // [out] reverb send level 284 | FLOAT32 DopplerFactor; // [out] doppler shift factor, scales resampler ratio for doppler shift effect, where the effective frequency = DopplerFactor * original frequency 285 | FLOAT32 EmitterToListenerAngle; // [out] emitter-to-listener interior angle, expressed in radians with respect to the emitter's front orientation 286 | 287 | FLOAT32 EmitterToListenerDistance; // [out] distance in user-defined world units from the emitter base to listener position, always calculated 288 | FLOAT32 EmitterVelocityComponent; // [out] component of emitter velocity vector projected onto emitter->listener vector in user-defined world units/second, calculated only for doppler 289 | FLOAT32 ListenerVelocityComponent; // [out] component of listener velocity vector projected onto emitter->listener vector in user-defined world units/second, calculated only for doppler 290 | } X3DAUDIO_DSP_SETTINGS, *LPX3DAUDIO_DSP_SETTINGS; 291 | 292 | 293 | //-------------------------------------------------------------// 294 | // function storage-class attribute and calltype 295 | #if defined(_XBOX) || defined(X3DAUDIOSTATIC) 296 | #define X3DAUDIO_API_(type) EXTERN_C type STDAPIVCALLTYPE 297 | #else 298 | #if defined(X3DEXPORT) 299 | #define X3DAUDIO_API_(type) EXTERN_C __declspec(dllexport) type STDAPIVCALLTYPE 300 | #else 301 | #define X3DAUDIO_API_(type) EXTERN_C __declspec(dllimport) type STDAPIVCALLTYPE 302 | #endif 303 | #endif 304 | #define X3DAUDIO_IMP_(type) type STDMETHODVCALLTYPE 305 | 306 | 307 | //-------------------------------------------------------// 308 | // initializes instance handle 309 | X3DAUDIO_API_(void) X3DAudioInitialize (UINT32 SpeakerChannelMask, FLOAT32 SpeedOfSound, __out X3DAUDIO_HANDLE Instance); 310 | 311 | // calculates DSP settings with respect to 3D parameters 312 | X3DAUDIO_API_(void) X3DAudioCalculate (__in const X3DAUDIO_HANDLE Instance, __in const X3DAUDIO_LISTENER* pListener, __in const X3DAUDIO_EMITTER* pEmitter, UINT32 Flags, __inout X3DAUDIO_DSP_SETTINGS* pDSPSettings); 313 | 314 | 315 | #pragma pack(pop) // revert packing alignment 316 | //---------------------------------<-EOF->----------------------------------// 317 | -------------------------------------------------------------------------------- /ThirdParty/Include/XAudio2_7/XAudio2fx.h: -------------------------------------------------------------------------------- 1 | /************************************************************************** 2 | * 3 | * Copyright (c) Microsoft Corporation. All rights reserved. 4 | * 5 | * File: xaudio2fx.h 6 | * Content: Declarations for the audio effects included with XAudio2. 7 | * 8 | **************************************************************************/ 9 | 10 | #ifndef __XAUDIO2FX_INCLUDED__ 11 | #define __XAUDIO2FX_INCLUDED__ 12 | 13 | 14 | /************************************************************************** 15 | * 16 | * XAudio2 effect class IDs. 17 | * 18 | **************************************************************************/ 19 | 20 | #include "comdecl.h" // For DEFINE_CLSID and DEFINE_IID 21 | 22 | // XAudio 2.0 (March 2008 SDK) 23 | //DEFINE_CLSID(AudioVolumeMeter, C0C56F46, 29B1, 44E9, 99, 39, A3, 2C, E8, 68, 67, E2); 24 | //DEFINE_CLSID(AudioVolumeMeter_Debug, C0C56F46, 29B1, 44E9, 99, 39, A3, 2C, E8, 68, 67, DB); 25 | //DEFINE_CLSID(AudioReverb, 6F6EA3A9, 2CF5, 41CF, 91, C1, 21, 70, B1, 54, 00, 63); 26 | //DEFINE_CLSID(AudioReverb_Debug, 6F6EA3A9, 2CF5, 41CF, 91, C1, 21, 70, B1, 54, 00, DB); 27 | 28 | // XAudio 2.1 (June 2008 SDK) 29 | //DEFINE_CLSID(AudioVolumeMeter, c1e3f122, a2ea, 442c, 85, 4f, 20, d9, 8f, 83, 57, a1); 30 | //DEFINE_CLSID(AudioVolumeMeter_Debug, 6d97a461, b02d, 48ae, b5, 43, 82, bc, 35, fd, fa, e2); 31 | //DEFINE_CLSID(AudioReverb, f4769300, b949, 4df9, b3, 33, 00, d3, 39, 32, e9, a6); 32 | //DEFINE_CLSID(AudioReverb_Debug, aea2cabc, 8c7c, 46aa, ba, 44, 0e, 6d, 75, 88, a1, f2); 33 | 34 | // XAudio 2.2 (August 2008 SDK) 35 | //DEFINE_CLSID(AudioVolumeMeter, f5ca7b34, 8055, 42c0, b8, 36, 21, 61, 29, eb, 7e, 30); 36 | //DEFINE_CLSID(AudioVolumeMeter_Debug, f796f5f7, 6059, 4a9f, 98, 2d, 61, ee, c2, ed, 67, ca); 37 | //DEFINE_CLSID(AudioReverb, 629cf0de, 3ecc, 41e7, 99, 26, f7, e4, 3e, eb, ec, 51); 38 | //DEFINE_CLSID(AudioReverb_Debug, 4aae4299, 3260, 46d4, 97, cc, 6c, c7, 60, c8, 53, 29); 39 | 40 | // XAudio 2.3 (November 2008 SDK) 41 | //DEFINE_CLSID(AudioVolumeMeter, e180344b, ac83, 4483, 95, 9e, 18, a5, c5, 6a, 5e, 19); 42 | //DEFINE_CLSID(AudioVolumeMeter_Debug, 922a0a56, 7d13, 40ae, a4, 81, 3c, 6c, 60, f1, 14, 01); 43 | //DEFINE_CLSID(AudioReverb, 9cab402c, 1d37, 44b4, 88, 6d, fa, 4f, 36, 17, 0a, 4c); 44 | //DEFINE_CLSID(AudioReverb_Debug, eadda998, 3be6, 4505, 84, be, ea, 06, 36, 5d, b9, 6b); 45 | 46 | // XAudio 2.4 (March 2009 SDK) 47 | //DEFINE_CLSID(AudioVolumeMeter, c7338b95, 52b8, 4542, aa, 79, 42, eb, 01, 6c, 8c, 1c); 48 | //DEFINE_CLSID(AudioVolumeMeter_Debug, 524bd872, 5c0b, 4217, bd, b8, 0a, 86, 81, 83, 0b, a5); 49 | //DEFINE_CLSID(AudioReverb, 8bb7778b, 645b, 4475, 9a, 73, 1d, e3, 17, 0b, d3, af); 50 | //DEFINE_CLSID(AudioReverb_Debug, da7738a2, cd0c, 4367, 9a, ac, d7, ea, d7, c6, 4f, 98); 51 | 52 | // XAudio 2.5 (March 2009 SDK) 53 | //DEFINE_CLSID(AudioVolumeMeter, 2139e6da, c341, 4774, 9a, c3, b4, e0, 26, 34, 7f, 64); 54 | //DEFINE_CLSID(AudioVolumeMeter_Debug, a5cc4e13, ca00, 416b, a6, ee, 49, fe, e7, b5, 43, d0); 55 | //DEFINE_CLSID(AudioReverb, d06df0d0, 8518, 441e, 82, 2f, 54, 51, d5, c5, 95, b8); 56 | //DEFINE_CLSID(AudioReverb_Debug, 613604ec, 304c, 45ec, a4, ed, 7a, 1c, 61, 2e, 9e, 72); 57 | 58 | // XAudio 2.6 (February 2010 SDK) 59 | //DEFINE_CLSID(AudioVolumeMeter, e48c5a3f, 93ef, 43bb, a0, 92, 2c, 7c, eb, 94, 6f, 27); 60 | //DEFINE_CLSID(AudioVolumeMeter_Debug, 9a9eaef7, a9e0, 4088, 9b, 1b, 9c, a0, 3a, 1a, ec, d4); 61 | //DEFINE_CLSID(AudioReverb, cecec95a, d894, 491a, be, e3, 5e, 10, 6f, b5, 9f, 2d); 62 | //DEFINE_CLSID(AudioReverb_Debug, 99a1c72e, 364c, 4c1b, 96, 23, fd, 5c, 8a, bd, 90, c7); 63 | 64 | // XAudio 2.7 (June 2010 SDK) 65 | DEFINE_CLSID(AudioVolumeMeter, cac1105f, 619b, 4d04, 83, 1a, 44, e1, cb, f1, 2d, 57); 66 | DEFINE_CLSID(AudioVolumeMeter_Debug, 2d9a0f9c, e67b, 4b24, ab, 44, 92, b3, e7, 70, c0, 20); 67 | DEFINE_CLSID(AudioReverb, 6a93130e, 1d53, 41d1, a9, cf, e7, 58, 80, 0b, b1, 79); 68 | DEFINE_CLSID(AudioReverb_Debug, c4f82dd4, cb4e, 4ce1, 8b, db, ee, 32, d4, 19, 82, 69); 69 | 70 | // Ignore the rest of this header if only the GUID definitions were requested 71 | #ifndef GUID_DEFS_ONLY 72 | 73 | #ifdef _XBOX 74 | #include // Xbox COM declarations (IUnknown, etc) 75 | #else 76 | #include // Windows COM declarations 77 | #endif 78 | #include // For log10() 79 | 80 | 81 | // All structures defined in this file should use tight packing 82 | #pragma pack(push, 1) 83 | 84 | 85 | /************************************************************************** 86 | * 87 | * Effect creation functions. On Windows, these are just inline functions 88 | * that call CoCreateInstance and Initialize; the XAUDIO2FX_DEBUG flag can 89 | * be used to select the debug version of the effects. On Xbox, these map 90 | * to real functions included in xaudio2.lib, and the XAUDIO2FX_DEBUG flag 91 | * is ignored; the application must link with the debug library to use the 92 | * debug functionality. 93 | * 94 | **************************************************************************/ 95 | 96 | // Use default values for some parameters if building C++ code 97 | #ifdef __cplusplus 98 | #define DEFAULT(x) =x 99 | #else 100 | #define DEFAULT(x) 101 | #endif 102 | 103 | #define XAUDIO2FX_DEBUG 1 // To select the debug version of an effect 104 | 105 | #ifdef _XBOX 106 | 107 | STDAPI CreateAudioVolumeMeter(__deref_out IUnknown** ppApo); 108 | STDAPI CreateAudioReverb(__deref_out IUnknown** ppApo); 109 | 110 | __inline HRESULT XAudio2CreateVolumeMeter(__deref_out IUnknown** ppApo, UINT32 /*Flags*/ DEFAULT(0)) 111 | { 112 | return CreateAudioVolumeMeter(ppApo); 113 | } 114 | 115 | __inline HRESULT XAudio2CreateReverb(__deref_out IUnknown** ppApo, UINT32 /*Flags*/ DEFAULT(0)) 116 | { 117 | return CreateAudioReverb(ppApo); 118 | } 119 | 120 | #else // Windows 121 | 122 | __inline HRESULT XAudio2CreateVolumeMeter(__deref_out IUnknown** ppApo, UINT32 Flags DEFAULT(0)) 123 | { 124 | #ifdef __cplusplus 125 | return CoCreateInstance((Flags & XAUDIO2FX_DEBUG) ? __uuidof(AudioVolumeMeter_Debug) 126 | : __uuidof(AudioVolumeMeter), 127 | NULL, CLSCTX_INPROC_SERVER, __uuidof(IUnknown), (void**)ppApo); 128 | #else 129 | return CoCreateInstance((Flags & XAUDIO2FX_DEBUG) ? &CLSID_AudioVolumeMeter_Debug 130 | : &CLSID_AudioVolumeMeter, 131 | NULL, CLSCTX_INPROC_SERVER, &IID_IUnknown, (void**)ppApo); 132 | #endif 133 | } 134 | 135 | __inline HRESULT XAudio2CreateReverb(__deref_out IUnknown** ppApo, UINT32 Flags DEFAULT(0)) 136 | { 137 | #ifdef __cplusplus 138 | return CoCreateInstance((Flags & XAUDIO2FX_DEBUG) ? __uuidof(AudioReverb_Debug) 139 | : __uuidof(AudioReverb), 140 | NULL, CLSCTX_INPROC_SERVER, __uuidof(IUnknown), (void**)ppApo); 141 | #else 142 | return CoCreateInstance((Flags & XAUDIO2FX_DEBUG) ? &CLSID_AudioReverb_Debug 143 | : &CLSID_AudioReverb, 144 | NULL, CLSCTX_INPROC_SERVER, &IID_IUnknown, (void**)ppApo); 145 | #endif 146 | } 147 | 148 | #endif // #ifdef _XBOX 149 | 150 | 151 | 152 | /************************************************************************** 153 | * 154 | * Volume meter parameters. 155 | * The volume meter supports FLOAT32 audio formats and must be used in-place. 156 | * 157 | **************************************************************************/ 158 | 159 | // XAUDIO2FX_VOLUMEMETER_LEVELS: Receives results from GetEffectParameters(). 160 | // The user is responsible for allocating pPeakLevels, pRMSLevels, and 161 | // initializing ChannelCount accordingly. 162 | // The volume meter does not support SetEffectParameters(). 163 | typedef struct XAUDIO2FX_VOLUMEMETER_LEVELS 164 | { 165 | float* pPeakLevels; // Peak levels table: receives maximum absolute level for each channel 166 | // over a processing pass; may be NULL if pRMSLevls != NULL, 167 | // otherwise must have at least ChannelCount elements. 168 | float* pRMSLevels; // Root mean square levels table: receives RMS level for each channel 169 | // over a processing pass; may be NULL if pPeakLevels != NULL, 170 | // otherwise must have at least ChannelCount elements. 171 | UINT32 ChannelCount; // Number of channels being processed by the volume meter APO 172 | } XAUDIO2FX_VOLUMEMETER_LEVELS; 173 | 174 | 175 | 176 | /************************************************************************** 177 | * 178 | * Reverb parameters. 179 | * The reverb supports only FLOAT32 audio with the following channel 180 | * configurations: 181 | * Input: Mono Output: Mono 182 | * Input: Mono Output: 5.1 183 | * Input: Stereo Output: Stereo 184 | * Input: Stereo Output: 5.1 185 | * The framerate must be within [20000, 48000] Hz. 186 | * 187 | * When using mono input, delay filters associated with the right channel 188 | * are not executed. In this case, parameters such as PositionRight and 189 | * PositionMatrixRight have no effect. This also means the reverb uses 190 | * less CPU when hosted in a mono submix. 191 | * 192 | **************************************************************************/ 193 | 194 | #define XAUDIO2FX_REVERB_MIN_FRAMERATE 20000 195 | #define XAUDIO2FX_REVERB_MAX_FRAMERATE 48000 196 | 197 | // XAUDIO2FX_REVERB_PARAMETERS: Native parameter set for the reverb effect 198 | 199 | typedef struct XAUDIO2FX_REVERB_PARAMETERS 200 | { 201 | // ratio of wet (processed) signal to dry (original) signal 202 | float WetDryMix; // [0, 100] (percentage) 203 | 204 | // Delay times 205 | UINT32 ReflectionsDelay; // [0, 300] in ms 206 | BYTE ReverbDelay; // [0, 85] in ms 207 | BYTE RearDelay; // [0, 5] in ms 208 | 209 | // Indexed parameters 210 | BYTE PositionLeft; // [0, 30] no units 211 | BYTE PositionRight; // [0, 30] no units, ignored when configured to mono 212 | BYTE PositionMatrixLeft; // [0, 30] no units 213 | BYTE PositionMatrixRight; // [0, 30] no units, ignored when configured to mono 214 | BYTE EarlyDiffusion; // [0, 15] no units 215 | BYTE LateDiffusion; // [0, 15] no units 216 | BYTE LowEQGain; // [0, 12] no units 217 | BYTE LowEQCutoff; // [0, 9] no units 218 | BYTE HighEQGain; // [0, 8] no units 219 | BYTE HighEQCutoff; // [0, 14] no units 220 | 221 | // Direct parameters 222 | float RoomFilterFreq; // [20, 20000] in Hz 223 | float RoomFilterMain; // [-100, 0] in dB 224 | float RoomFilterHF; // [-100, 0] in dB 225 | float ReflectionsGain; // [-100, 20] in dB 226 | float ReverbGain; // [-100, 20] in dB 227 | float DecayTime; // [0.1, inf] in seconds 228 | float Density; // [0, 100] (percentage) 229 | float RoomSize; // [1, 100] in feet 230 | } XAUDIO2FX_REVERB_PARAMETERS; 231 | 232 | 233 | // Maximum, minimum and default values for the parameters above 234 | #define XAUDIO2FX_REVERB_MIN_WET_DRY_MIX 0.0f 235 | #define XAUDIO2FX_REVERB_MIN_REFLECTIONS_DELAY 0 236 | #define XAUDIO2FX_REVERB_MIN_REVERB_DELAY 0 237 | #define XAUDIO2FX_REVERB_MIN_REAR_DELAY 0 238 | #define XAUDIO2FX_REVERB_MIN_POSITION 0 239 | #define XAUDIO2FX_REVERB_MIN_DIFFUSION 0 240 | #define XAUDIO2FX_REVERB_MIN_LOW_EQ_GAIN 0 241 | #define XAUDIO2FX_REVERB_MIN_LOW_EQ_CUTOFF 0 242 | #define XAUDIO2FX_REVERB_MIN_HIGH_EQ_GAIN 0 243 | #define XAUDIO2FX_REVERB_MIN_HIGH_EQ_CUTOFF 0 244 | #define XAUDIO2FX_REVERB_MIN_ROOM_FILTER_FREQ 20.0f 245 | #define XAUDIO2FX_REVERB_MIN_ROOM_FILTER_MAIN -100.0f 246 | #define XAUDIO2FX_REVERB_MIN_ROOM_FILTER_HF -100.0f 247 | #define XAUDIO2FX_REVERB_MIN_REFLECTIONS_GAIN -100.0f 248 | #define XAUDIO2FX_REVERB_MIN_REVERB_GAIN -100.0f 249 | #define XAUDIO2FX_REVERB_MIN_DECAY_TIME 0.1f 250 | #define XAUDIO2FX_REVERB_MIN_DENSITY 0.0f 251 | #define XAUDIO2FX_REVERB_MIN_ROOM_SIZE 0.0f 252 | 253 | #define XAUDIO2FX_REVERB_MAX_WET_DRY_MIX 100.0f 254 | #define XAUDIO2FX_REVERB_MAX_REFLECTIONS_DELAY 300 255 | #define XAUDIO2FX_REVERB_MAX_REVERB_DELAY 85 256 | #define XAUDIO2FX_REVERB_MAX_REAR_DELAY 5 257 | #define XAUDIO2FX_REVERB_MAX_POSITION 30 258 | #define XAUDIO2FX_REVERB_MAX_DIFFUSION 15 259 | #define XAUDIO2FX_REVERB_MAX_LOW_EQ_GAIN 12 260 | #define XAUDIO2FX_REVERB_MAX_LOW_EQ_CUTOFF 9 261 | #define XAUDIO2FX_REVERB_MAX_HIGH_EQ_GAIN 8 262 | #define XAUDIO2FX_REVERB_MAX_HIGH_EQ_CUTOFF 14 263 | #define XAUDIO2FX_REVERB_MAX_ROOM_FILTER_FREQ 20000.0f 264 | #define XAUDIO2FX_REVERB_MAX_ROOM_FILTER_MAIN 0.0f 265 | #define XAUDIO2FX_REVERB_MAX_ROOM_FILTER_HF 0.0f 266 | #define XAUDIO2FX_REVERB_MAX_REFLECTIONS_GAIN 20.0f 267 | #define XAUDIO2FX_REVERB_MAX_REVERB_GAIN 20.0f 268 | #define XAUDIO2FX_REVERB_MAX_DENSITY 100.0f 269 | #define XAUDIO2FX_REVERB_MAX_ROOM_SIZE 100.0f 270 | 271 | #define XAUDIO2FX_REVERB_DEFAULT_WET_DRY_MIX 100.0f 272 | #define XAUDIO2FX_REVERB_DEFAULT_REFLECTIONS_DELAY 5 273 | #define XAUDIO2FX_REVERB_DEFAULT_REVERB_DELAY 5 274 | #define XAUDIO2FX_REVERB_DEFAULT_REAR_DELAY 5 275 | #define XAUDIO2FX_REVERB_DEFAULT_POSITION 6 276 | #define XAUDIO2FX_REVERB_DEFAULT_POSITION_MATRIX 27 277 | #define XAUDIO2FX_REVERB_DEFAULT_EARLY_DIFFUSION 8 278 | #define XAUDIO2FX_REVERB_DEFAULT_LATE_DIFFUSION 8 279 | #define XAUDIO2FX_REVERB_DEFAULT_LOW_EQ_GAIN 8 280 | #define XAUDIO2FX_REVERB_DEFAULT_LOW_EQ_CUTOFF 4 281 | #define XAUDIO2FX_REVERB_DEFAULT_HIGH_EQ_GAIN 8 282 | #define XAUDIO2FX_REVERB_DEFAULT_HIGH_EQ_CUTOFF 4 283 | #define XAUDIO2FX_REVERB_DEFAULT_ROOM_FILTER_FREQ 5000.0f 284 | #define XAUDIO2FX_REVERB_DEFAULT_ROOM_FILTER_MAIN 0.0f 285 | #define XAUDIO2FX_REVERB_DEFAULT_ROOM_FILTER_HF 0.0f 286 | #define XAUDIO2FX_REVERB_DEFAULT_REFLECTIONS_GAIN 0.0f 287 | #define XAUDIO2FX_REVERB_DEFAULT_REVERB_GAIN 0.0f 288 | #define XAUDIO2FX_REVERB_DEFAULT_DECAY_TIME 1.0f 289 | #define XAUDIO2FX_REVERB_DEFAULT_DENSITY 100.0f 290 | #define XAUDIO2FX_REVERB_DEFAULT_ROOM_SIZE 100.0f 291 | 292 | 293 | // XAUDIO2FX_REVERB_I3DL2_PARAMETERS: Parameter set compliant with the I3DL2 standard 294 | 295 | typedef struct XAUDIO2FX_REVERB_I3DL2_PARAMETERS 296 | { 297 | // ratio of wet (processed) signal to dry (original) signal 298 | float WetDryMix; // [0, 100] (percentage) 299 | 300 | // Standard I3DL2 parameters 301 | INT32 Room; // [-10000, 0] in mB (hundredths of decibels) 302 | INT32 RoomHF; // [-10000, 0] in mB (hundredths of decibels) 303 | float RoomRolloffFactor; // [0.0, 10.0] 304 | float DecayTime; // [0.1, 20.0] in seconds 305 | float DecayHFRatio; // [0.1, 2.0] 306 | INT32 Reflections; // [-10000, 1000] in mB (hundredths of decibels) 307 | float ReflectionsDelay; // [0.0, 0.3] in seconds 308 | INT32 Reverb; // [-10000, 2000] in mB (hundredths of decibels) 309 | float ReverbDelay; // [0.0, 0.1] in seconds 310 | float Diffusion; // [0.0, 100.0] (percentage) 311 | float Density; // [0.0, 100.0] (percentage) 312 | float HFReference; // [20.0, 20000.0] in Hz 313 | } XAUDIO2FX_REVERB_I3DL2_PARAMETERS; 314 | 315 | 316 | // ReverbConvertI3DL2ToNative: Utility function to map from I3DL2 to native parameters 317 | 318 | __inline void ReverbConvertI3DL2ToNative 319 | ( 320 | __in const XAUDIO2FX_REVERB_I3DL2_PARAMETERS* pI3DL2, 321 | __out XAUDIO2FX_REVERB_PARAMETERS* pNative 322 | ) 323 | { 324 | float reflectionsDelay; 325 | float reverbDelay; 326 | 327 | // RoomRolloffFactor is ignored 328 | 329 | // These parameters have no equivalent in I3DL2 330 | pNative->RearDelay = XAUDIO2FX_REVERB_DEFAULT_REAR_DELAY; // 5 331 | pNative->PositionLeft = XAUDIO2FX_REVERB_DEFAULT_POSITION; // 6 332 | pNative->PositionRight = XAUDIO2FX_REVERB_DEFAULT_POSITION; // 6 333 | pNative->PositionMatrixLeft = XAUDIO2FX_REVERB_DEFAULT_POSITION_MATRIX; // 27 334 | pNative->PositionMatrixRight = XAUDIO2FX_REVERB_DEFAULT_POSITION_MATRIX; // 27 335 | pNative->RoomSize = XAUDIO2FX_REVERB_DEFAULT_ROOM_SIZE; // 100 336 | pNative->LowEQCutoff = 4; 337 | pNative->HighEQCutoff = 6; 338 | 339 | // The rest of the I3DL2 parameters map to the native property set 340 | pNative->RoomFilterMain = (float)pI3DL2->Room / 100.0f; 341 | pNative->RoomFilterHF = (float)pI3DL2->RoomHF / 100.0f; 342 | 343 | if (pI3DL2->DecayHFRatio >= 1.0f) 344 | { 345 | INT32 index = (INT32)(-4.0 * log10(pI3DL2->DecayHFRatio)); 346 | if (index < -8) index = -8; 347 | pNative->LowEQGain = (BYTE)((index < 0) ? index + 8 : 8); 348 | pNative->HighEQGain = 8; 349 | pNative->DecayTime = pI3DL2->DecayTime * pI3DL2->DecayHFRatio; 350 | } 351 | else 352 | { 353 | INT32 index = (INT32)(4.0 * log10(pI3DL2->DecayHFRatio)); 354 | if (index < -8) index = -8; 355 | pNative->LowEQGain = 8; 356 | pNative->HighEQGain = (BYTE)((index < 0) ? index + 8 : 8); 357 | pNative->DecayTime = pI3DL2->DecayTime; 358 | } 359 | 360 | reflectionsDelay = pI3DL2->ReflectionsDelay * 1000.0f; 361 | if (reflectionsDelay >= XAUDIO2FX_REVERB_MAX_REFLECTIONS_DELAY) // 300 362 | { 363 | reflectionsDelay = (float)(XAUDIO2FX_REVERB_MAX_REFLECTIONS_DELAY - 1); 364 | } 365 | else if (reflectionsDelay <= 1) 366 | { 367 | reflectionsDelay = 1; 368 | } 369 | pNative->ReflectionsDelay = (UINT32)reflectionsDelay; 370 | 371 | reverbDelay = pI3DL2->ReverbDelay * 1000.0f; 372 | if (reverbDelay >= XAUDIO2FX_REVERB_MAX_REVERB_DELAY) // 85 373 | { 374 | reverbDelay = (float)(XAUDIO2FX_REVERB_MAX_REVERB_DELAY - 1); 375 | } 376 | pNative->ReverbDelay = (BYTE)reverbDelay; 377 | 378 | pNative->ReflectionsGain = pI3DL2->Reflections / 100.0f; 379 | pNative->ReverbGain = pI3DL2->Reverb / 100.0f; 380 | pNative->EarlyDiffusion = (BYTE)(15.0f * pI3DL2->Diffusion / 100.0f); 381 | pNative->LateDiffusion = pNative->EarlyDiffusion; 382 | pNative->Density = pI3DL2->Density; 383 | pNative->RoomFilterFreq = pI3DL2->HFReference; 384 | 385 | pNative->WetDryMix = pI3DL2->WetDryMix; 386 | } 387 | 388 | 389 | /************************************************************************** 390 | * 391 | * Standard I3DL2 reverb presets (100% wet). 392 | * 393 | **************************************************************************/ 394 | 395 | #define XAUDIO2FX_I3DL2_PRESET_DEFAULT {100,-10000, 0,0.0f, 1.00f,0.50f,-10000,0.020f,-10000,0.040f,100.0f,100.0f,5000.0f} 396 | #define XAUDIO2FX_I3DL2_PRESET_GENERIC {100, -1000, -100,0.0f, 1.49f,0.83f, -2602,0.007f, 200,0.011f,100.0f,100.0f,5000.0f} 397 | #define XAUDIO2FX_I3DL2_PRESET_PADDEDCELL {100, -1000,-6000,0.0f, 0.17f,0.10f, -1204,0.001f, 207,0.002f,100.0f,100.0f,5000.0f} 398 | #define XAUDIO2FX_I3DL2_PRESET_ROOM {100, -1000, -454,0.0f, 0.40f,0.83f, -1646,0.002f, 53,0.003f,100.0f,100.0f,5000.0f} 399 | #define XAUDIO2FX_I3DL2_PRESET_BATHROOM {100, -1000,-1200,0.0f, 1.49f,0.54f, -370,0.007f, 1030,0.011f,100.0f, 60.0f,5000.0f} 400 | #define XAUDIO2FX_I3DL2_PRESET_LIVINGROOM {100, -1000,-6000,0.0f, 0.50f,0.10f, -1376,0.003f, -1104,0.004f,100.0f,100.0f,5000.0f} 401 | #define XAUDIO2FX_I3DL2_PRESET_STONEROOM {100, -1000, -300,0.0f, 2.31f,0.64f, -711,0.012f, 83,0.017f,100.0f,100.0f,5000.0f} 402 | #define XAUDIO2FX_I3DL2_PRESET_AUDITORIUM {100, -1000, -476,0.0f, 4.32f,0.59f, -789,0.020f, -289,0.030f,100.0f,100.0f,5000.0f} 403 | #define XAUDIO2FX_I3DL2_PRESET_CONCERTHALL {100, -1000, -500,0.0f, 3.92f,0.70f, -1230,0.020f, -2,0.029f,100.0f,100.0f,5000.0f} 404 | #define XAUDIO2FX_I3DL2_PRESET_CAVE {100, -1000, 0,0.0f, 2.91f,1.30f, -602,0.015f, -302,0.022f,100.0f,100.0f,5000.0f} 405 | #define XAUDIO2FX_I3DL2_PRESET_ARENA {100, -1000, -698,0.0f, 7.24f,0.33f, -1166,0.020f, 16,0.030f,100.0f,100.0f,5000.0f} 406 | #define XAUDIO2FX_I3DL2_PRESET_HANGAR {100, -1000,-1000,0.0f,10.05f,0.23f, -602,0.020f, 198,0.030f,100.0f,100.0f,5000.0f} 407 | #define XAUDIO2FX_I3DL2_PRESET_CARPETEDHALLWAY {100, -1000,-4000,0.0f, 0.30f,0.10f, -1831,0.002f, -1630,0.030f,100.0f,100.0f,5000.0f} 408 | #define XAUDIO2FX_I3DL2_PRESET_HALLWAY {100, -1000, -300,0.0f, 1.49f,0.59f, -1219,0.007f, 441,0.011f,100.0f,100.0f,5000.0f} 409 | #define XAUDIO2FX_I3DL2_PRESET_STONECORRIDOR {100, -1000, -237,0.0f, 2.70f,0.79f, -1214,0.013f, 395,0.020f,100.0f,100.0f,5000.0f} 410 | #define XAUDIO2FX_I3DL2_PRESET_ALLEY {100, -1000, -270,0.0f, 1.49f,0.86f, -1204,0.007f, -4,0.011f,100.0f,100.0f,5000.0f} 411 | #define XAUDIO2FX_I3DL2_PRESET_FOREST {100, -1000,-3300,0.0f, 1.49f,0.54f, -2560,0.162f, -613,0.088f, 79.0f,100.0f,5000.0f} 412 | #define XAUDIO2FX_I3DL2_PRESET_CITY {100, -1000, -800,0.0f, 1.49f,0.67f, -2273,0.007f, -2217,0.011f, 50.0f,100.0f,5000.0f} 413 | #define XAUDIO2FX_I3DL2_PRESET_MOUNTAINS {100, -1000,-2500,0.0f, 1.49f,0.21f, -2780,0.300f, -2014,0.100f, 27.0f,100.0f,5000.0f} 414 | #define XAUDIO2FX_I3DL2_PRESET_QUARRY {100, -1000,-1000,0.0f, 1.49f,0.83f,-10000,0.061f, 500,0.025f,100.0f,100.0f,5000.0f} 415 | #define XAUDIO2FX_I3DL2_PRESET_PLAIN {100, -1000,-2000,0.0f, 1.49f,0.50f, -2466,0.179f, -2514,0.100f, 21.0f,100.0f,5000.0f} 416 | #define XAUDIO2FX_I3DL2_PRESET_PARKINGLOT {100, -1000, 0,0.0f, 1.65f,1.50f, -1363,0.008f, -1153,0.012f,100.0f,100.0f,5000.0f} 417 | #define XAUDIO2FX_I3DL2_PRESET_SEWERPIPE {100, -1000,-1000,0.0f, 2.81f,0.14f, 429,0.014f, 648,0.021f, 80.0f, 60.0f,5000.0f} 418 | #define XAUDIO2FX_I3DL2_PRESET_UNDERWATER {100, -1000,-4000,0.0f, 1.49f,0.10f, -449,0.007f, 1700,0.011f,100.0f,100.0f,5000.0f} 419 | #define XAUDIO2FX_I3DL2_PRESET_SMALLROOM {100, -1000, -600,0.0f, 1.10f,0.83f, -400,0.005f, 500,0.010f,100.0f,100.0f,5000.0f} 420 | #define XAUDIO2FX_I3DL2_PRESET_MEDIUMROOM {100, -1000, -600,0.0f, 1.30f,0.83f, -1000,0.010f, -200,0.020f,100.0f,100.0f,5000.0f} 421 | #define XAUDIO2FX_I3DL2_PRESET_LARGEROOM {100, -1000, -600,0.0f, 1.50f,0.83f, -1600,0.020f, -1000,0.040f,100.0f,100.0f,5000.0f} 422 | #define XAUDIO2FX_I3DL2_PRESET_MEDIUMHALL {100, -1000, -600,0.0f, 1.80f,0.70f, -1300,0.015f, -800,0.030f,100.0f,100.0f,5000.0f} 423 | #define XAUDIO2FX_I3DL2_PRESET_LARGEHALL {100, -1000, -600,0.0f, 1.80f,0.70f, -2000,0.030f, -1400,0.060f,100.0f,100.0f,5000.0f} 424 | #define XAUDIO2FX_I3DL2_PRESET_PLATE {100, -1000, -200,0.0f, 1.30f,0.90f, 0,0.002f, 0,0.010f,100.0f, 75.0f,5000.0f} 425 | 426 | 427 | // Undo the #pragma pack(push, 1) at the top of this file 428 | #pragma pack(pop) 429 | 430 | #endif // #ifndef GUID_DEFS_ONLY 431 | #endif // #ifndef __XAUDIO2FX_INCLUDED__ 432 | -------------------------------------------------------------------------------- /ThirdParty/Include/XAudio2_7/audiodefs.h: -------------------------------------------------------------------------------- 1 | /*************************************************************************** 2 | * 3 | * Copyright (c) Microsoft Corporation. All rights reserved. 4 | * 5 | * File: audiodefs.h 6 | * Content: Basic constants and data types for audio work. 7 | * 8 | * Remarks: This header file defines all of the audio format constants and 9 | * structures required for XAudio2 and XACT work. Providing these 10 | * in a single location avoids certain dependency problems in the 11 | * legacy audio headers (mmreg.h, mmsystem.h, ksmedia.h). 12 | * 13 | * NOTE: Including the legacy headers after this one may cause a 14 | * compilation error, because they define some of the same types 15 | * defined here without preprocessor guards to avoid multiple 16 | * definitions. If a source file needs one of the old headers, 17 | * it must include it before including audiodefs.h. 18 | * 19 | ***************************************************************************/ 20 | 21 | #ifndef __AUDIODEFS_INCLUDED__ 22 | #define __AUDIODEFS_INCLUDED__ 23 | 24 | #include // For WORD, DWORD, etc. 25 | 26 | #pragma pack(push, 1) // Pack structures to 1-byte boundaries 27 | 28 | 29 | /************************************************************************** 30 | * 31 | * WAVEFORMATEX: Base structure for many audio formats. Format-specific 32 | * extensions can be defined for particular formats by using a non-zero 33 | * cbSize value and adding extra fields to the end of this structure. 34 | * 35 | ***************************************************************************/ 36 | 37 | #ifndef _WAVEFORMATEX_ 38 | 39 | #define _WAVEFORMATEX_ 40 | typedef struct tWAVEFORMATEX 41 | { 42 | WORD wFormatTag; // Integer identifier of the format 43 | WORD nChannels; // Number of audio channels 44 | DWORD nSamplesPerSec; // Audio sample rate 45 | DWORD nAvgBytesPerSec; // Bytes per second (possibly approximate) 46 | WORD nBlockAlign; // Size in bytes of a sample block (all channels) 47 | WORD wBitsPerSample; // Size in bits of a single per-channel sample 48 | WORD cbSize; // Bytes of extra data appended to this struct 49 | } WAVEFORMATEX; 50 | 51 | #endif 52 | 53 | // Defining pointer types outside of the #if block to make sure they are 54 | // defined even if mmreg.h or mmsystem.h is #included before this file 55 | 56 | typedef WAVEFORMATEX *PWAVEFORMATEX, *NPWAVEFORMATEX, *LPWAVEFORMATEX; 57 | typedef const WAVEFORMATEX *PCWAVEFORMATEX, *LPCWAVEFORMATEX; 58 | 59 | 60 | /************************************************************************** 61 | * 62 | * WAVEFORMATEXTENSIBLE: Extended version of WAVEFORMATEX that should be 63 | * used as a basis for all new audio formats. The format tag is replaced 64 | * with a GUID, allowing new formats to be defined without registering a 65 | * format tag with Microsoft. There are also new fields that can be used 66 | * to specify the spatial positions for each channel and the bit packing 67 | * used for wide samples (e.g. 24-bit PCM samples in 32-bit containers). 68 | * 69 | ***************************************************************************/ 70 | 71 | #ifndef _WAVEFORMATEXTENSIBLE_ 72 | 73 | #define _WAVEFORMATEXTENSIBLE_ 74 | typedef struct 75 | { 76 | WAVEFORMATEX Format; // Base WAVEFORMATEX data 77 | union 78 | { 79 | WORD wValidBitsPerSample; // Valid bits in each sample container 80 | WORD wSamplesPerBlock; // Samples per block of audio data; valid 81 | // if wBitsPerSample=0 (but rarely used). 82 | WORD wReserved; // Zero if neither case above applies. 83 | } Samples; 84 | DWORD dwChannelMask; // Positions of the audio channels 85 | GUID SubFormat; // Format identifier GUID 86 | } WAVEFORMATEXTENSIBLE; 87 | 88 | #endif 89 | 90 | typedef WAVEFORMATEXTENSIBLE *PWAVEFORMATEXTENSIBLE, *LPWAVEFORMATEXTENSIBLE; 91 | typedef const WAVEFORMATEXTENSIBLE *PCWAVEFORMATEXTENSIBLE, *LPCWAVEFORMATEXTENSIBLE; 92 | 93 | 94 | 95 | /************************************************************************** 96 | * 97 | * Define the most common wave format tags used in WAVEFORMATEX formats. 98 | * 99 | ***************************************************************************/ 100 | 101 | #ifndef WAVE_FORMAT_PCM // Pulse Code Modulation 102 | 103 | // If WAVE_FORMAT_PCM is not defined, we need to define some legacy types 104 | // for compatibility with the Windows mmreg.h / mmsystem.h header files. 105 | 106 | // Old general format structure (information common to all formats) 107 | typedef struct waveformat_tag 108 | { 109 | WORD wFormatTag; 110 | WORD nChannels; 111 | DWORD nSamplesPerSec; 112 | DWORD nAvgBytesPerSec; 113 | WORD nBlockAlign; 114 | } WAVEFORMAT, *PWAVEFORMAT, NEAR *NPWAVEFORMAT, FAR *LPWAVEFORMAT; 115 | 116 | // Specific format structure for PCM data 117 | typedef struct pcmwaveformat_tag 118 | { 119 | WAVEFORMAT wf; 120 | WORD wBitsPerSample; 121 | } PCMWAVEFORMAT, *PPCMWAVEFORMAT, NEAR *NPPCMWAVEFORMAT, FAR *LPPCMWAVEFORMAT; 122 | 123 | #define WAVE_FORMAT_PCM 0x0001 124 | 125 | #endif 126 | 127 | #ifndef WAVE_FORMAT_ADPCM // Microsoft Adaptive Differental PCM 128 | 129 | // Replicate the Microsoft ADPCM type definitions from mmreg.h. 130 | 131 | typedef struct adpcmcoef_tag 132 | { 133 | short iCoef1; 134 | short iCoef2; 135 | } ADPCMCOEFSET; 136 | 137 | #pragma warning(push) 138 | #pragma warning(disable:4200) // Disable zero-sized array warnings 139 | 140 | typedef struct adpcmwaveformat_tag { 141 | WAVEFORMATEX wfx; 142 | WORD wSamplesPerBlock; 143 | WORD wNumCoef; 144 | ADPCMCOEFSET aCoef[]; // Always 7 coefficient pairs for MS ADPCM 145 | } ADPCMWAVEFORMAT; 146 | 147 | #pragma warning(pop) 148 | 149 | #define WAVE_FORMAT_ADPCM 0x0002 150 | 151 | #endif 152 | 153 | // Other frequently used format tags 154 | 155 | #ifndef WAVE_FORMAT_UNKNOWN 156 | #define WAVE_FORMAT_UNKNOWN 0x0000 // Unknown or invalid format tag 157 | #endif 158 | 159 | #ifndef WAVE_FORMAT_IEEE_FLOAT 160 | #define WAVE_FORMAT_IEEE_FLOAT 0x0003 // 32-bit floating-point 161 | #endif 162 | 163 | #ifndef WAVE_FORMAT_MPEGLAYER3 164 | #define WAVE_FORMAT_MPEGLAYER3 0x0055 // ISO/MPEG Layer3 165 | #endif 166 | 167 | #ifndef WAVE_FORMAT_DOLBY_AC3_SPDIF 168 | #define WAVE_FORMAT_DOLBY_AC3_SPDIF 0x0092 // Dolby Audio Codec 3 over S/PDIF 169 | #endif 170 | 171 | #ifndef WAVE_FORMAT_WMAUDIO2 172 | #define WAVE_FORMAT_WMAUDIO2 0x0161 // Windows Media Audio 173 | #endif 174 | 175 | #ifndef WAVE_FORMAT_WMAUDIO3 176 | #define WAVE_FORMAT_WMAUDIO3 0x0162 // Windows Media Audio Pro 177 | #endif 178 | 179 | #ifndef WAVE_FORMAT_WMASPDIF 180 | #define WAVE_FORMAT_WMASPDIF 0x0164 // Windows Media Audio over S/PDIF 181 | #endif 182 | 183 | #ifndef WAVE_FORMAT_EXTENSIBLE 184 | #define WAVE_FORMAT_EXTENSIBLE 0xFFFE // All WAVEFORMATEXTENSIBLE formats 185 | #endif 186 | 187 | 188 | /************************************************************************** 189 | * 190 | * Define the most common wave format GUIDs used in WAVEFORMATEXTENSIBLE 191 | * formats. Note that including the Windows ksmedia.h header after this 192 | * one will cause build problems; this cannot be avoided, since ksmedia.h 193 | * defines these macros without preprocessor guards. 194 | * 195 | ***************************************************************************/ 196 | 197 | #ifdef __cplusplus // uuid() and __uuidof() are only available in C++ 198 | 199 | #ifndef KSDATAFORMAT_SUBTYPE_PCM 200 | struct __declspec(uuid("00000001-0000-0010-8000-00aa00389b71")) KSDATAFORMAT_SUBTYPE_PCM_STRUCT; 201 | #define KSDATAFORMAT_SUBTYPE_PCM __uuidof(KSDATAFORMAT_SUBTYPE_PCM_STRUCT) 202 | #endif 203 | 204 | #ifndef KSDATAFORMAT_SUBTYPE_ADPCM 205 | struct __declspec(uuid("00000002-0000-0010-8000-00aa00389b71")) KSDATAFORMAT_SUBTYPE_ADPCM_STRUCT; 206 | #define KSDATAFORMAT_SUBTYPE_ADPCM __uuidof(KSDATAFORMAT_SUBTYPE_ADPCM_STRUCT) 207 | #endif 208 | 209 | #ifndef KSDATAFORMAT_SUBTYPE_IEEE_FLOAT 210 | struct __declspec(uuid("00000003-0000-0010-8000-00aa00389b71")) KSDATAFORMAT_SUBTYPE_IEEE_FLOAT_STRUCT; 211 | #define KSDATAFORMAT_SUBTYPE_IEEE_FLOAT __uuidof(KSDATAFORMAT_SUBTYPE_IEEE_FLOAT_STRUCT) 212 | #endif 213 | 214 | #endif 215 | 216 | 217 | /************************************************************************** 218 | * 219 | * Speaker positions used in the WAVEFORMATEXTENSIBLE dwChannelMask field. 220 | * 221 | ***************************************************************************/ 222 | 223 | #ifndef SPEAKER_FRONT_LEFT 224 | #define SPEAKER_FRONT_LEFT 0x00000001 225 | #define SPEAKER_FRONT_RIGHT 0x00000002 226 | #define SPEAKER_FRONT_CENTER 0x00000004 227 | #define SPEAKER_LOW_FREQUENCY 0x00000008 228 | #define SPEAKER_BACK_LEFT 0x00000010 229 | #define SPEAKER_BACK_RIGHT 0x00000020 230 | #define SPEAKER_FRONT_LEFT_OF_CENTER 0x00000040 231 | #define SPEAKER_FRONT_RIGHT_OF_CENTER 0x00000080 232 | #define SPEAKER_BACK_CENTER 0x00000100 233 | #define SPEAKER_SIDE_LEFT 0x00000200 234 | #define SPEAKER_SIDE_RIGHT 0x00000400 235 | #define SPEAKER_TOP_CENTER 0x00000800 236 | #define SPEAKER_TOP_FRONT_LEFT 0x00001000 237 | #define SPEAKER_TOP_FRONT_CENTER 0x00002000 238 | #define SPEAKER_TOP_FRONT_RIGHT 0x00004000 239 | #define SPEAKER_TOP_BACK_LEFT 0x00008000 240 | #define SPEAKER_TOP_BACK_CENTER 0x00010000 241 | #define SPEAKER_TOP_BACK_RIGHT 0x00020000 242 | #define SPEAKER_RESERVED 0x7FFC0000 243 | #define SPEAKER_ALL 0x80000000 244 | #define _SPEAKER_POSITIONS_ 245 | #endif 246 | 247 | #ifndef SPEAKER_STEREO 248 | #define SPEAKER_MONO (SPEAKER_FRONT_CENTER) 249 | #define SPEAKER_STEREO (SPEAKER_FRONT_LEFT | SPEAKER_FRONT_RIGHT) 250 | #define SPEAKER_2POINT1 (SPEAKER_FRONT_LEFT | SPEAKER_FRONT_RIGHT | SPEAKER_LOW_FREQUENCY) 251 | #define SPEAKER_SURROUND (SPEAKER_FRONT_LEFT | SPEAKER_FRONT_RIGHT | SPEAKER_FRONT_CENTER | SPEAKER_BACK_CENTER) 252 | #define SPEAKER_QUAD (SPEAKER_FRONT_LEFT | SPEAKER_FRONT_RIGHT | SPEAKER_BACK_LEFT | SPEAKER_BACK_RIGHT) 253 | #define SPEAKER_4POINT1 (SPEAKER_FRONT_LEFT | SPEAKER_FRONT_RIGHT | SPEAKER_LOW_FREQUENCY | SPEAKER_BACK_LEFT | SPEAKER_BACK_RIGHT) 254 | #define SPEAKER_5POINT1 (SPEAKER_FRONT_LEFT | SPEAKER_FRONT_RIGHT | SPEAKER_FRONT_CENTER | SPEAKER_LOW_FREQUENCY | SPEAKER_BACK_LEFT | SPEAKER_BACK_RIGHT) 255 | #define SPEAKER_7POINT1 (SPEAKER_FRONT_LEFT | SPEAKER_FRONT_RIGHT | SPEAKER_FRONT_CENTER | SPEAKER_LOW_FREQUENCY | SPEAKER_BACK_LEFT | SPEAKER_BACK_RIGHT | SPEAKER_FRONT_LEFT_OF_CENTER | SPEAKER_FRONT_RIGHT_OF_CENTER) 256 | #define SPEAKER_5POINT1_SURROUND (SPEAKER_FRONT_LEFT | SPEAKER_FRONT_RIGHT | SPEAKER_FRONT_CENTER | SPEAKER_LOW_FREQUENCY | SPEAKER_SIDE_LEFT | SPEAKER_SIDE_RIGHT) 257 | #define SPEAKER_7POINT1_SURROUND (SPEAKER_FRONT_LEFT | SPEAKER_FRONT_RIGHT | SPEAKER_FRONT_CENTER | SPEAKER_LOW_FREQUENCY | SPEAKER_BACK_LEFT | SPEAKER_BACK_RIGHT | SPEAKER_SIDE_LEFT | SPEAKER_SIDE_RIGHT) 258 | #endif 259 | 260 | 261 | #pragma pack(pop) 262 | 263 | #endif // #ifndef __AUDIODEFS_INCLUDED__ 264 | -------------------------------------------------------------------------------- /ThirdParty/Include/XAudio2_7/comdecl.h: -------------------------------------------------------------------------------- 1 | // comdecl.h: Macros to facilitate COM interface and GUID declarations. 2 | // Copyright (c) Microsoft Corporation. All rights reserved. 3 | 4 | #ifndef _COMDECL_H_ 5 | #define _COMDECL_H_ 6 | 7 | #ifndef _XBOX 8 | #include // For standard COM interface macros 9 | #else 10 | #pragma warning(push) 11 | #pragma warning(disable:4061) 12 | #include // Required by xobjbase.h 13 | #include // Special definitions for Xbox build 14 | #pragma warning(pop) 15 | #endif 16 | 17 | // The DEFINE_CLSID() and DEFINE_IID() macros defined below allow COM GUIDs to 18 | // be declared and defined in such a way that clients can obtain the GUIDs using 19 | // either the __uuidof() extension or the old-style CLSID_Foo / IID_IFoo names. 20 | // If using the latter approach, the client can also choose whether to get the 21 | // GUID definitions by defining the INITGUID preprocessor constant or by linking 22 | // to a GUID library. This works in either C or C++. 23 | 24 | #ifdef __cplusplus 25 | 26 | #define DECLSPEC_UUID_WRAPPER(x) __declspec(uuid(#x)) 27 | #ifdef INITGUID 28 | 29 | #define DEFINE_CLSID(className, l, w1, w2, b1, b2, b3, b4, b5, b6, b7, b8) \ 30 | class DECLSPEC_UUID_WRAPPER(l##-##w1##-##w2##-##b1##b2##-##b3##b4##b5##b6##b7##b8) className; \ 31 | EXTERN_C const GUID DECLSPEC_SELECTANY CLSID_##className = __uuidof(className) 32 | 33 | #define DEFINE_IID(interfaceName, l, w1, w2, b1, b2, b3, b4, b5, b6, b7, b8) \ 34 | interface DECLSPEC_UUID_WRAPPER(l##-##w1##-##w2##-##b1##b2##-##b3##b4##b5##b6##b7##b8) interfaceName; \ 35 | EXTERN_C const GUID DECLSPEC_SELECTANY IID_##interfaceName = __uuidof(interfaceName) 36 | 37 | #else // INITGUID 38 | 39 | #define DEFINE_CLSID(className, l, w1, w2, b1, b2, b3, b4, b5, b6, b7, b8) \ 40 | class DECLSPEC_UUID_WRAPPER(l##-##w1##-##w2##-##b1##b2##-##b3##b4##b5##b6##b7##b8) className; \ 41 | EXTERN_C const GUID CLSID_##className 42 | 43 | #define DEFINE_IID(interfaceName, l, w1, w2, b1, b2, b3, b4, b5, b6, b7, b8) \ 44 | interface DECLSPEC_UUID_WRAPPER(l##-##w1##-##w2##-##b1##b2##-##b3##b4##b5##b6##b7##b8) interfaceName; \ 45 | EXTERN_C const GUID IID_##interfaceName 46 | 47 | #endif // INITGUID 48 | 49 | #else // __cplusplus 50 | 51 | #define DEFINE_CLSID(className, l, w1, w2, b1, b2, b3, b4, b5, b6, b7, b8) \ 52 | DEFINE_GUID(CLSID_##className, 0x##l, 0x##w1, 0x##w2, 0x##b1, 0x##b2, 0x##b3, 0x##b4, 0x##b5, 0x##b6, 0x##b7, 0x##b8) 53 | 54 | #define DEFINE_IID(interfaceName, l, w1, w2, b1, b2, b3, b4, b5, b6, b7, b8) \ 55 | DEFINE_GUID(IID_##interfaceName, 0x##l, 0x##w1, 0x##w2, 0x##b1, 0x##b2, 0x##b3, 0x##b4, 0x##b5, 0x##b6, 0x##b7, 0x##b8) 56 | 57 | #endif // __cplusplus 58 | 59 | #endif // #ifndef _COMDECL_H_ 60 | --------------------------------------------------------------------------------