commit 6655fd288624960ad41c08bce1f124a8fe35b418 Author: johnruina Date: Mon Jun 8 17:07:34 2026 -0400 added the readme diff --git a/Animator.h b/Animator.h new file mode 100644 index 0000000..86a1c40 --- /dev/null +++ b/Animator.h @@ -0,0 +1,216 @@ +#ifndef ANIMATOR_CLASS +#define ANIMATOR_CLASS + +#include +#include +#include +#include +#include +#include +#include "Rig.h" + +struct AssimpNodeData +{ + glm::mat4 transformation; + std::string name; + int childrenCount; + std::vector children; +}; + +// ============================================================================ +// Animation +// ============================================================================ +class Animation +{ +public: + Animation() = default; + + Animation(const std::string& animationPath, Rig* rig = nullptr) + { + Assimp::Importer importer; + const aiScene* scene = importer.ReadFile(animationPath, aiProcess_Triangulate); + assert(scene && scene->mRootNode); + + const aiAnimation* anim = scene->mAnimations[0]; + m_Duration = (float)anim->mDuration; + m_TicksPerSecond = (int)(anim->mTicksPerSecond != 0 ? anim->mTicksPerSecond : 24); + + ReadHierarchyData(m_RootNode, scene->mRootNode); + + for (unsigned int i = 0; i < anim->mNumChannels; i++) { + const aiNodeAnim* channel = anim->mChannels[i]; + m_Bones.emplace_back(channel->mNodeName.data, 0, channel); + m_BoneNames.push_back(channel->mNodeName.data); + } + + if (rig) RegisterBonesWithRig(*rig); + } + + void RegisterBonesWithRig(Rig& rig) + { + for (const std::string& name : m_BoneNames) { + if (rig.m_BoneInfoMap.find(name) == rig.m_BoneInfoMap.end()) { + BoneInfo info; + info.id = rig.m_BoneCounter++; + info.offset = glm::mat4(1.0f); + rig.m_BoneInfoMap[name] = info; + } + } + } + + Bone* FindBone(const std::string& name) + { + for (Bone& b : m_Bones) + if (b.GetBoneName() == name) return &b; + return nullptr; + } + + float GetTicksPerSecond() const { return (float)m_TicksPerSecond; } + float GetDuration() const { return m_Duration; } + const AssimpNodeData& GetRootNode() const { return m_RootNode; } + +public: + float m_Duration = 0.0f; + int m_TicksPerSecond = 24; + std::vector m_Bones; + std::vector m_BoneNames; + AssimpNodeData m_RootNode; + +private: + void ReadHierarchyData(AssimpNodeData& dest, const aiNode* src) + { + assert(src); + dest.name = src->mName.data; + dest.transformation = AssimpGLMHelpers::ConvertMatrixToGLMFormat(src->mTransformation); + dest.childrenCount = (int)src->mNumChildren; + for (unsigned int i = 0; i < src->mNumChildren; i++) { + AssimpNodeData child; + ReadHierarchyData(child, src->mChildren[i]); + dest.children.push_back(child); + } + } +}; + +// ============================================================================ +// Animator +// blendWeight ramps from 0?1 over blendDuration when PlayAnimation is called. +// CharacterBody::GetBlendedBoneMatrices() lerps all animators by blendWeight. +// ============================================================================ +class Animator +{ +public: + int weight = 0; // priority — higher wins + float blendDuration = 0.15f; // seconds to blend in + float blendWeight = 1.0f; // 0 = invisible, 1 = fully playing + bool loops = true; + bool isPlaying = true; + + Animator() + { + m_FinalBoneMatrices.assign(100, glm::mat4(1.0f)); + } + + void SetRig(Rig* rig) + { + m_Rig = rig; + if (m_CurrentAnimation) RebuildBoneInfoMap(); + } + + void SetAnimation(Animation* animation) + { + m_CurrentAnimation = animation; + m_CurrentTime = 0.0f; + if (m_Rig) RebuildBoneInfoMap(); + } + + void PlayAnimation() + { + m_CurrentTime = 0.0f; + isPlaying = true; + blendWeight = 0.0f; // start blending in from 0 + _blendTimer = 0.0f; + } + + void StopAnimation() { isPlaying = false; blendWeight = 0.0f; } + void ClearAnimation() { m_CurrentAnimation = nullptr; m_CurrentTime = 0.0f; isPlaying = false; blendWeight = 0.0f; } + + bool IsFinished() const + { + if (!m_CurrentAnimation || !isPlaying) return true; + return m_CurrentTime >= m_CurrentAnimation->GetDuration() - 1.0f; + } + + void Step(float dt) + { + if (!m_CurrentAnimation || dt <= 0.0f || !isPlaying || !m_Rig) return; + + // Ramp blend weight in + if (blendWeight < 1.0f) { + _blendTimer += dt; + blendWeight = glm::min(1.0f, blendDuration > 0.0f ? _blendTimer / blendDuration : 1.0f); + } + + m_CurrentTime += m_CurrentAnimation->GetTicksPerSecond() * dt; + + if (m_CurrentTime >= m_CurrentAnimation->GetDuration()) { + if (loops) { + m_CurrentTime = fmod(m_CurrentTime, m_CurrentAnimation->GetDuration()); + } else { + m_CurrentTime = m_CurrentAnimation->GetDuration(); + isPlaying = false; + blendWeight = 0.0f; + return; + } + } + + CalculateBoneTransform(&m_CurrentAnimation->GetRootNode(), glm::mat4(1.0f)); + } + + const std::vector& GetFinalBoneMatrices() const { return m_FinalBoneMatrices; } + +public: + std::vector m_FinalBoneMatrices; + Animation* m_CurrentAnimation = nullptr; + Rig* m_Rig = nullptr; + float m_CurrentTime = 0.0f; + float m_DeltaTime = 0.0f; + +private: + std::map m_BoneInfoMap; + float _blendTimer = 0.0f; + + void RebuildBoneInfoMap() + { + if (!m_CurrentAnimation || !m_Rig) return; + m_BoneInfoMap = m_Rig->m_BoneInfoMap; + m_CurrentAnimation->RegisterBonesWithRig(*m_Rig); + m_BoneInfoMap = m_Rig->m_BoneInfoMap; + } + + void CalculateBoneTransform(const AssimpNodeData* node, glm::mat4 parentTransform) + { + const std::string& nodeName = node->name; + glm::mat4 nodeTransform = node->transformation; + + Bone* bone = m_CurrentAnimation->FindBone(nodeName); + if (bone) { + bone->Update(m_CurrentTime); + nodeTransform = bone->GetLocalTransform(); + } + + glm::mat4 globalTransform = parentTransform * nodeTransform; + + auto it = m_BoneInfoMap.find(nodeName); + if (it != m_BoneInfoMap.end()) { + int index = it->second.id; + const glm::mat4 offset = it->second.offset; + if (index >= 0 && index < (int)m_FinalBoneMatrices.size()) + m_FinalBoneMatrices[index] = globalTransform * offset; + } + + for (int i = 0; i < node->childrenCount; i++) + CalculateBoneTransform(&node->children[i], globalTransform); + } +}; + +#endif \ No newline at end of file diff --git a/BodyComponentActions.h b/BodyComponentActions.h new file mode 100644 index 0000000..bd0615a --- /dev/null +++ b/BodyComponentActions.h @@ -0,0 +1,7 @@ +#pragma once + +#include "Character.h" + +void Footstep(CharacterBody* body, BodyComponent* bc) { + body->t.TranslateBy(body->t.GetFrontVector() * 0.1f); +} \ No newline at end of file diff --git a/Camera.h b/Camera.h new file mode 100644 index 0000000..3805b76 --- /dev/null +++ b/Camera.h @@ -0,0 +1,121 @@ +#ifndef CAMERA_CLASS_H +#define CAMERA_CLASS_H +#include +#include +#include +#include +#include +#include +#include +#include +#include "common.h" +#include "Window.h" +#include "t.h" +#include "tFunctions.h" +#include "shaderClass.h" + +const glm::vec3 worldUp = { 0.0f, 1.0f, 0.0f }; + +class Camera { +public: + bool lockedcursor = true; + t t; + float yaw = 0.0f; + float pitch = 0.0f; + const float originalspeed = 0.08f; + float speed = 0.08f; + float sensitivity = 0.001f; + float FOV = 90.0f; + float screenshake = 0.0f; + + Camera() {} + + void AddScreenshake(float amount) { + screenshake += amount; + float s = screenshake; + shakeTarget = glm::vec3( + ((float)(rand() % 2000 - 1000) / 1000.0f) * s, + ((float)(rand() % 2000 - 1000) / 1000.0f) * s, + ((float)(rand() % 2000 - 1000) / 1000.0f) * s * 0.5f + ); + shakeTimer = 0.05f; + } + + void Matrix(float nearPlane, float farPlane, Shader& shader) { + shader.SetMat4("proj", GetProjectionMatrix(nearPlane, farPlane)); + shader.SetMat4("view", GetViewMatrix()); + shader.Set3F("viewPos", t.GetTranslation()); + } + + glm::mat4 GetViewMatrix() { + glm::vec3 front = t.GetFrontVector(); + glm::vec3 up = t.GetUpVector(); + + if (screenshake > 0.0f) { + // Apply smooth shake offset stored in shakeOffset + glm::quat offsetRot = glm::quat(glm::vec3( + shakeOffset.x, + shakeOffset.y, + shakeOffset.z // roll + )); + front = glm::normalize(offsetRot * front); + up = glm::normalize(offsetRot * up); + } + + return glm::lookAt(t.GetTranslation(), t.GetTranslation() + front, up); + } + + glm::mat4 GetProjectionMatrix(float nearPlane, float farPlane) { + return glm::perspective(glm::radians(FOV), + (float)window->width / (float)window->height, nearPlane, farPlane); + } + + void Step(float dt) { + if (screenshake <= 0.0f) { + shakeOffset = glm::vec3(0.0f); + shakeTarget = glm::vec3(0.0f); + return; + } + + // Pick a new random target periodically, but fade target to zero as shake ends + shakeTimer -= dt; + if (shakeTimer <= 0.0f) { + float s = screenshake; + shakeTarget = glm::vec3( + ((float)(rand() % 2000 - 1000) / 1000.0f) * s, + ((float)(rand() % 2000 - 1000) / 1000.0f) * s, + ((float)(rand() % 2000 - 1000) / 1000.0f) * s * 0.5f + ); + shakeTimer = 0.05f; + } + + // As shake decays below threshold, pull target back to zero so we land clean + if (screenshake < 0.2f) + shakeTarget = glm::vec3(0.0f); + + // Smoothly interpolate current offset toward target + float smoothSpeed = 20.0f; + shakeOffset = glm::mix(shakeOffset, shakeTarget, glm::min(1.0f, smoothSpeed * dt)); + + // Decay + screenshake -= dt * 3.0f; + if (screenshake < 0.0f) screenshake = 0.0f; + } + + void ProcessMouseMovement(float xoffset, float yoffset) { + xoffset *= sensitivity; + yoffset *= sensitivity; + yaw += xoffset; + pitch += yoffset; + pitch = glm::clamp(pitch, -glm::radians(89.0f), glm::radians(89.0f)); + t.RotateToEulerAngles({ pitch, yaw, 0.0f }); + t.NormalizeRotation(); + } + +private: + glm::vec3 shakeOffset = glm::vec3(0.0f); // current smoothed offset (pitch, yaw, roll) + glm::vec3 shakeTarget = glm::vec3(0.0f); // target we're interpolating toward + float shakeTimer = 0.0f; // time until next target pick +}; + +#endif \ No newline at end of file diff --git a/Character.cpp b/Character.cpp new file mode 100644 index 0000000..71e0163 --- /dev/null +++ b/Character.cpp @@ -0,0 +1,62 @@ +#include "Character.h" +#include "Animator.h" + +// ------------------------------------------------------- +// BodyComponent +// ------------------------------------------------------- + +BodyComponent* CharacterBody::GetComponentOfName(std::string name) { + for (BodyComponent* C : components) { + if (C->name == name) + return C; + } + return nullptr; +} + +void CharacterBody::ExecuteAction(InputAction* action) { + for (BodyComponent* C : components) { + if (C->name == action->BodyComponentName) { + for (Action* a : C->Actions) { + if (a->Name == action->ActionName) { + a->FunctionPointer(this, C); + break; + } + } + break; + } + } +} + +// ------------------------------------------------------- +// CharacterMind +// ------------------------------------------------------- + +InputAction* CharacterMind::ProduceAction() { + // TODO: implement + return nullptr; +} + +// ------------------------------------------------------- +// Character +// ------------------------------------------------------- + +Character::Character() { + body = new CharacterBody(); + mind = nullptr; + shadertype = ShaderType::RigShader; +} + +void Character::Render(Shader& shader) { + if (!body || !body->rig || !body->animator) return; + if (body->animator->m_CurrentAnimation == nullptr) { + for (int i = 0; i < 100; i++) + shader.SetMat4(("finalBonesMatrices[" + std::to_string(i) + "]").c_str(), glm::mat4(1.0f)); + } + else { + std::vector transforms = body->GetBlendedBoneMatrices(); + + for (int i = 0; i < transforms.size(); i++) + shader.SetMat4(("finalBonesMatrices[" + std::to_string(i) + "]").c_str(), transforms[i]); + } + body->rig->Render(shader, body->t.GetTranslationMatrix() * body->t.GetRotationMatrix()); +} \ No newline at end of file diff --git a/Character.h b/Character.h new file mode 100644 index 0000000..f5ce6ff --- /dev/null +++ b/Character.h @@ -0,0 +1,128 @@ +#ifndef CHARACTER_CLASS +#define CHARACTER_CLASS +#include +#include +#include +#include +#include "t.h" +#include "Rig.h" +#include "Object.h" +#include "Animator.h" + +class CharacterBody; +class BodyComponent; + +class Action { +public: + std::string Name; + std::function FunctionPointer; +}; + +class InputAction { +public: + std::string BodyComponentName; + std::string ActionName; +}; + +class BodyComponent { +public: + std::string name; + BodyComponent* ParentComponent = nullptr; + std::vector Actions; +}; + +class CharacterBody : public t_package { +public: + int Health = 100; + Rig* rig = nullptr; + + std::vector animators; + Animator* animator = nullptr; // back-compat: base animator at weight 0 + + std::vector components; + BodyComponent* RootComponent = nullptr; + + CharacterBody() { + animator = AddAnimator(0); + animator->blendWeight = 1.0f; // base always fully visible + } + + Animator* AddAnimator(int weight) { + Animator* a = new Animator(); + a->weight = weight; + if (rig) a->SetRig(rig); + animators.push_back(a); + std::sort(animators.begin(), animators.end(), + [](Animator* a, Animator* b) { return a->weight < b->weight; }); + return a; + } + + // Returns weighted blend of all playing animators. + // Base (weight 0) is always the foundation; higher-weight animators + // blend in on top based on their blendWeight (0?1). + std::vector GetBlendedBoneMatrices() const { + // Start from the base animator + std::vector result = animator->GetFinalBoneMatrices(); + const int count = (int)result.size(); + + // Blend each higher-priority playing animator on top + for (int i = 1; i < (int)animators.size(); i++) { + Animator* a = animators[i]; + if (!a->isPlaying || !a->m_CurrentAnimation || a->blendWeight <= 0.0f) continue; + const auto& matrices = a->GetFinalBoneMatrices(); + for (int j = 0; j < count && j < (int)matrices.size(); j++) + result[j] = glm::mix(result[j], matrices[j], a->blendWeight); + } + return result; + } + + // Returns the highest-weight playing animator (for back-compat) + Animator* GetActiveAnimator() const { + for (int i = (int)animators.size() - 1; i >= 0; i--) + if (animators[i]->isPlaying && animators[i]->m_CurrentAnimation) + return animators[i]; + return animator; + } + + void SetRig(Rig* r) { + rig = r; + for (Animator* a : animators) + a->SetRig(r); + } + + void SetAnimation(Animation* anim) { + animator->SetAnimation(anim); + animator->PlayAnimation(); + animator->blendWeight = 1.0f; // base never blends — always instant + } + + void LoadAnimation(Animation* anim) { SetAnimation(anim); } + + void Step(float dt) { + for (Animator* a : animators) + a->Step(dt); + } + + BodyComponent* GetComponentOfName(std::string name); + void ExecuteAction(InputAction* action); +}; + +class CharacterMind { +public: + InputAction* ProduceAction(); +}; + +class Character : public Object, public Renderable { +public: + CharacterMind* mind = nullptr; + CharacterBody* body = nullptr; + + Character(); + void Render(Shader& shader) override; + + void Step(float dt) { + body->Step(dt); + } +}; + +#endif \ No newline at end of file diff --git a/Cubemap.h b/Cubemap.h new file mode 100644 index 0000000..b8d53d1 --- /dev/null +++ b/Cubemap.h @@ -0,0 +1,66 @@ +#ifndef CUBEMAP_CLASS +#define CUBEMAP_CLASS + +#include + +#include "stb_image.h" +#include + +#include "shaderClass.h" + +class Cubemap { +public: + GLuint ID; + + Cubemap() { + }; + + Cubemap(std::vector& faces) { + FillCubemap(faces); + }; + + void FillCubemap(std::vector& faces) { + + if (ID != 0) { + Delete(); + } + + glGenTextures(1, &ID); + glBindTexture(GL_TEXTURE_CUBE_MAP, ID); + + int width, height, nrChannels; + for (unsigned int i = 0; i < faces.size(); i++) + { + unsigned char* data = stbi_load(faces[i].c_str(), &width, &height, &nrChannels, 0); + if (data) + { + glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + i, + 0, GL_RGB, width, height, 0, GL_RGB, GL_UNSIGNED_BYTE, data + ); + stbi_image_free(data); + } + else + { + std::cout << "Cubemap tex failed to load at path: " << faces[i] << std::endl; + stbi_image_free(data); + } + } + glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); + glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); + glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE); + } + + void Bind() { + glBindTexture(GL_TEXTURE_CUBE_MAP, ID); + }; + void Unbind() { + glBindTexture(GL_TEXTURE_CUBE_MAP, 0); + }; + void Delete() { + glDeleteTextures(1, &ID); + }; +}; + +#endif \ No newline at end of file diff --git a/Debug.h b/Debug.h new file mode 100644 index 0000000..cded540 --- /dev/null +++ b/Debug.h @@ -0,0 +1,111 @@ + +#ifndef DEBUG_CLASS +#define DEBUG_CLASS + +#include +#include +#include + +#include +#include +#include +#include +#include + +#include "tFunctions.h" +#include "Mesh.h" +#include "Structures.h" + +const std::vector CUBEVERTICES = { +{{0.5f,0.5f,0.5f}, {1.0f,0.0f,0.0f},{ 0.0f,0.0f} }, +{{0.5f,0.5f,-0.5f}, {1.0f,0.0f,0.0f},{ 0.0f,1.0f}}, +{{0.5f,-0.5f,-0.5f}, {1.0f,0.0f,0.0f},{ 1.0f,1.0f}}, +{{0.5f,-0.5f,0.5f}, {1.0f,0.0f,0.0f}, {1.0f,0.0f}}, + +{{-0.5f,0.5f,0.5f}, {-1.0f,0.0f,0.0f}, {0.0f,0.0f}}, +{{-0.5f,0.5f,-0.5f}, {-1.0f,0.0f,0.0f}, {0.0f,1.0f}}, +{{-0.5f,-0.5f,-0.5f}, {-1.0f,0.0f,0.0f}, {1.0f,1.0f}}, +{{-0.5f,-0.5f,0.5f},{ -1.0f,0.0f,0.0f}, {1.0f,0.0f}}, + +{{0.5f,0.5f,0.5f}, {0.0f,1.0f,0.0f},{ 0.0f,0.0f} }, +{{0.5f,0.5f,-0.5f}, {0.0f,1.0f,0.0f},{ 0.0f,1.0f}}, +{{-0.5f,0.5f,-0.5f}, {0.0f,1.0f,0.0f},{ 1.0f,1.0f}}, +{{-0.5f,0.5f,0.5f}, {0.0f,1.0f,0.0f}, {1.0f,0.0f}}, + +{{0.5f,-0.5f,0.5f}, {0.0f,-1.0f,0.0f}, {0.0f,0.0f}}, +{{0.5f,-0.5f,-0.5f}, {0.0f,-1.0f,0.0f}, {0.0f,1.0f}}, +{{-0.5f,-0.5f,-0.5f}, {0.0f,-1.0f,0.0f}, {1.0f,1.0f}}, +{{-0.5f,-0.5f,0.5f},{ 0.0f,-1.0f,0.0f}, {1.0f,0.0f}}, + +{{0.5f,0.5f,0.5f}, {0.0f,0.0f,1.0f},{ 0.0f,0.0f} }, +{{-0.5f,0.5f,0.5f}, {0.0f,0.0f,1.0f},{ 0.0f,1.0f}}, +{{-0.5f,-0.5f,0.5f}, {0.0f,0.0f,1.0f},{ 1.0f,1.0f}}, +{{0.5f,-0.5f,0.5f}, {0.0f,0.0f,1.0f}, {1.0f,0.0f}}, + +{{0.5f,0.5f,-0.5f}, {0.0f,0.0f,-1.0f}, {0.0f,0.0f}}, +{{-0.5f,0.5f,-0.5f}, {0.0f,0.0f,-1.0f}, {0.0f,1.0f}}, +{{-0.5f,-0.5f,-0.5f}, {0.0f,0.0f,-1.0f}, {1.0f,1.0f}}, +{{0.5f,-0.5f,-0.5f},{ 0.0f,0.0f,-1.0f}, {1.0f,0.0f}} +}; + +const std::vector CUBEINDICES = { + 0, 3, 1, 3, 2, 1, + 4, 5, 7, 5, 6, 7, + + 8, 9, 11, 9, 10, 11, + 12, 15, 13, 15, 14, 13, + + 16, 17, 19, 17, 18, 19, + 20, 23, 21, 23, 22, 21 +}; + +const std::vector PLANEVERTICES = { +{{0.5f,0.0f,0.5f}, {0.0f,1.0f,0.0f},{ 0.0f,0.0f} }, +{{-0.5f,0.0f,0.5f}, {0.0f,1.0f,0.0f},{ 1.0f,0.0f}}, +{{-0.5f,0.0f,-0.5f}, {0.0f,1.0f,0.0f},{ 1.0f,1.0f}}, +{{0.5f,0.0f,-0.5f}, {0.0f,1.0f,0.0f}, {0.0f,1.0f}}, +}; + +const std::vector PLANEINDICES = { + 0,1,2, + 2,3,0, + + 2,1,0, + 0,3,2, +}; + +inline void Output(std::string& to) { + std::cout << to << '\n'; +} + +inline void Output(float& to) { + std::cout << to << '\n'; +} + +inline void Output(int& to) { + std::cout << to << '\n'; +} + +inline void Output(glm::vec3 tooutput) { + std::cout << tooutput.x << ' ' << tooutput.y << ' ' << tooutput.z << '\n'; +} + +inline void Output(BoundingBox tooutput) { + std::cout << tooutput.min.x << ' ' << tooutput.min.y << ' ' << tooutput.min.z << ' ' << tooutput.max.x << ' ' << tooutput.max.y << ' ' << tooutput.max.z << '\n'; +} + +inline void Output(glm::mat4 tooutput) { + std::cout << '[' << tooutput[0][0] << ',' << tooutput[0][1] << ',' << tooutput[0][2] << ',' << tooutput[0][3] << ',' << '\n' + << tooutput[1][0] << ',' << tooutput[1][1] << ',' << tooutput[1][2] << ',' << tooutput[1][3] << ',' << '\n' + << tooutput[2][0] << ',' << tooutput[2][1] << ',' << tooutput[2][2] << ',' << tooutput[2][3] << ',' << '\n' + << tooutput[3][0] << ',' << tooutput[3][1] << ',' << tooutput[3][2] << ',' << tooutput[3][3] << ',' << '\n' << ']' << '\n'; +} + +inline Mesh* CreateCubeMesh() { + return new Mesh(CUBEVERTICES, CUBEINDICES); +} +inline Mesh* CreatePlaneMesh() { + return new Mesh(PLANEVERTICES, PLANEINDICES); +} + +#endif \ No newline at end of file diff --git a/DefaultBodyComponents.h b/DefaultBodyComponents.h new file mode 100644 index 0000000..b117425 --- /dev/null +++ b/DefaultBodyComponents.h @@ -0,0 +1,36 @@ +#ifndef DEFAULT_BODY_COMPONENTS +#define DEFAULT_BODY_COMPONENTS + +#include + +#include "Character.h" +#include "BodyComponentActions.h" + +std::vector GenerateDefaultBody() { + std::vector TR; + BodyComponent* Head = new BodyComponent(); + BodyComponent* Torso = new BodyComponent(); + BodyComponent* RightArm = new BodyComponent(); + BodyComponent* LeftArm = new BodyComponent(); + BodyComponent* RightLeg = new BodyComponent(); + BodyComponent* LeftLeg = new BodyComponent(); + + Head->name = "Head"; + Torso->name = "Torso"; + RightArm->name = "RightArm"; + LeftArm->name = "LeftArm"; + RightLeg->name = "RightLeg"; + LeftLeg->name = "LeftLeg"; + + TR.push_back(Head); + TR.push_back(Torso); + TR.push_back(RightArm); + TR.push_back(LeftArm); + TR.push_back(RightLeg); + TR.push_back(LeftLeg); + + return TR; +} + + +#endif \ No newline at end of file diff --git a/DirLight.h b/DirLight.h new file mode 100644 index 0000000..94c2e28 --- /dev/null +++ b/DirLight.h @@ -0,0 +1,54 @@ + +#ifndef DIRLIGHT_CLASS +#define DIRLIGHT_CLASS + +#include +#include +#include + +#include "shaderClass.h" + +class DirLight { + +public: + DirLight() { + + } + DirLight(glm::vec3 ambient, glm::vec3 diffuse, glm::vec3 specular, glm::vec3 direction) + { + Initialize(ambient,diffuse,specular,direction); + } + + void Initialize(glm::vec3 newambient, glm::vec3 newdiffuse, glm::vec3 newspecular, glm::vec3 newdirection) { + ambient = glm::normalize(newambient); + diffuse = glm::normalize(newdiffuse); + specular = glm::normalize(newspecular); + direction = glm::normalize(newdirection); + } + + void Bind(Shader& shader) { + shader.Set3F("dirLight.ambient", ambient); + shader.Set3F("dirLight.diffuse", diffuse); + shader.Set3F("dirLight.specular", specular); + shader.Set3F("dirLight.direction", direction); + }; + + void Unbind(Shader shader) { + shader.Set3F("dirLight.ambient", glm::vec3(1.0f)); + shader.Set3F("dirLight.diffuse", glm::vec3(0.0f)); + shader.Set3F("dirLight.specular", glm::vec3(0.0f)); + shader.Set3F("dirLight.direction", glm::vec3(1.0f)); + //finish unbinding + }; + + glm::vec3 direction; + + glm::vec3 ambient; + glm::vec3 diffuse; + glm::vec3 specular; + +private: + +}; + +#endif \ No newline at end of file diff --git a/EBO.cpp b/EBO.cpp new file mode 100644 index 0000000..754c28b --- /dev/null +++ b/EBO.cpp @@ -0,0 +1,28 @@ + +#include "EBO.h" + +EBO::EBO() +{ +} + +void EBO::BufferData(GLuint* indices, GLsizeiptr size) { + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ID); + glBufferData(GL_ELEMENT_ARRAY_BUFFER, size, indices, GL_STATIC_DRAW); + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); +} + +void EBO::Bind() +{ + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ID); +} + +void EBO::Unbind() +{ + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); +} + +void EBO::Delete() +{ + glDeleteBuffers(1, &ID); + ID = 0; +} \ No newline at end of file diff --git a/EBO.h b/EBO.h new file mode 100644 index 0000000..26b3583 --- /dev/null +++ b/EBO.h @@ -0,0 +1,20 @@ + +#ifndef EBO_CLASS_H +#define EBO_CLASS_H + +#include + +class EBO { +public: + GLuint ID; + EBO(); + void GenerateID() { + glGenBuffers(1, &ID); + }; + void BufferData(GLuint* indices, GLsizeiptr size); + void Bind(); + void Unbind(); + void Delete(); +}; + +#endif \ No newline at end of file diff --git a/Engine.cpp b/Engine.cpp new file mode 100644 index 0000000..a51b871 --- /dev/null +++ b/Engine.cpp @@ -0,0 +1,526 @@ +#include "Engine.h" + +// ============================================================================ +// Standard library +// ============================================================================ +#include +#include +#include +#include +#include + +// ============================================================================ +// OpenGL +// ============================================================================ +#include +#include + +// ============================================================================ +// Math +// ============================================================================ +#include +#include +#include +#include + +// ============================================================================ +// Third party +// ============================================================================ +#include +#include FT_FREETYPE_H + +// ============================================================================ +// Engine — core +// ============================================================================ +#include "common.h" +#include "Window.h" +#include "Camera.h" +#include "Keyboard.h" +#include "Mouse.h" +#include "Physics.h" +#include "RenderSystem.h" +#include "SoundSystem.h" +#include "ResourceManager.h" +#include "tFunctions.h" +#include "Debug.h" + +// Rendering +#include "shaderClass.h" +#include "VBO.h" +#include "VAO.h" +#include "EBO.h" +#include "FBO.h" +#include "texture.h" +#include "Material.h" +#include "Mesh.h" +#include "Model.h" +#include "Cubemap.h" +#include "QuadVertices.h" +#include "Particle.h" +#include "Lighting.h" +#include "DirLight.h" + +// Scene +#include "Folder.h" +#include "Sound.h" +#include "Gui.h" +#include "font.h" + +// Character / animation +#include "Rig.h" +#include "Animator.h" +#include "Character.h" +#include "DefaultBodyComponents.h" +#include "BodyComponentActions.h" + +#define STB_IMAGE_IMPLEMENTATION +#include "stb_image.h" + +// ============================================================================ +// Constructor — window, callbacks, systems, shaders +// ============================================================================ +Engine::Engine() +{ + engine = this; + + glfwSetFramebufferSizeCallback(window->handle, framebuffer_size_callback); + glfwSetCursorPosCallback(window->handle, mouse_callback); + glfwSetScrollCallback(window->handle, scroll_callback); + glfwSetKeyCallback(window->handle, key_callback); + glfwSetMouseButtonCallback(window->handle, mouse_button_callback); + glfwSwapInterval(1); + + rendersystem = new RenderSystem(); + rendersystem->Initialize(); + physicsengine = new Physics(); + mainf = new Folder(); + camera = new Camera(); + camera->t.TranslateTo({ 0.0f, 5.0f, 0.0f }); + + rendersystem->RigShader = new Shader("shaders/rig.vert", "shaders/default.frag"); + rendersystem->MeshShader = new Shader("shaders/default.vert", "shaders/default.frag"); + rendersystem->MeshShadowShader = new Shader("shaders/meshshadow.vert", "shaders/shadow.frag"); + rendersystem->RigShadowShader = new Shader("shaders/rigshadow.vert", "shaders/shadow.frag"); + rendersystem->SkyboxShader = new Shader("shaders/skybox.vert", "shaders/skybox.frag"); + rendersystem->ScreenShader = new Shader("shaders/ScreenShader.vert", "shaders/ScreenShader.frag"); + rendersystem->ImageBoxShader = new Shader("shaders/ImageBox.vert", "shaders/ImageBox.frag"); + rendersystem->BoxShader = new Shader("shaders/Box.vert", "shaders/Box.frag"); + rendersystem->Text2DShader = new Shader("shaders/2DText.vert", "shaders/2DText.frag"); + rendersystem->ParticleShader = new Shader("shaders/Particle.vert", "shaders/Particle.frag"); +} + +// ============================================================================ +// Initiate — scene setup + game loop +// ============================================================================ +void Engine::Initiate() +{ + // ------------------------------------------------------------------------ + // Assets + // ------------------------------------------------------------------------ + Font* arial = new Font("assets/ft/arial.ttf"); + Texture* blanktex = new Texture("assets/blanktexture.png"); + Texture* magic = new Texture("assets/itsmagicbitch.jpg"); + Texture* snowflake = new Texture("assets/snowflake.png"); + Texture* leontex = new Texture("assets/revolvertex.png"); + + // ------------------------------------------------------------------------ + // Shared rig + animations + // ------------------------------------------------------------------------ + Rig* testrig = new Rig("assets/rig.glb"); + Animation* testanimation = new Animation("assets/walkanim.glb"); + Animation* punchanim = new Animation("assets/punchanim.glb"); + + // ------------------------------------------------------------------------ + // Player character + // ------------------------------------------------------------------------ + Character* testcharacter = new Character(); + testcharacter->name = "character"; + testcharacter->castshadow = true; + testcharacter->body->t.ScaleBy({ 0.5f, 1.8f, 0.5f }); + testcharacter->body->t.TranslateTo({ 0.0f, 0.9f, 0.0f }); + testcharacter->body->SetRig(testrig); + + // Base animator (weight 0) — walk, looped + testcharacter->body->SetAnimation(testanimation); + testcharacter->body->animator->loops = true; + + // Punch animator (weight 1) — one-shot, starts stopped + Animator* punchAnimator = testcharacter->body->AddAnimator(1); + punchAnimator->loops = false; + punchAnimator->SetAnimation(punchanim); + punchAnimator->StopAnimation(); + + testcharacter->BindToRenderSystem(); + + p* characterBody = new p(testcharacter->body); + characterBody->mass = 80.0f; + characterBody->lockRotation = true; + characterBody->friction = 0.0f; + physicsengine->AddObject(characterBody); + + // ------------------------------------------------------------------------ + // NPC + // ------------------------------------------------------------------------ + Character* npc = new Character(); + npc->name = "npc"; + npc->castshadow = true; + npc->body->t.ScaleBy({ 0.5f, 1.8f, 0.5f }); + npc->body->t.TranslateTo({ 3.0f, 0.9f, 3.0f }); + npc->body->SetRig(testrig); + npc->body->SetAnimation(testanimation); + npc->BindToRenderSystem(); + + p* npcBody = new p(npc->body); + npcBody->mass = 80.0f; + npcBody->lockRotation = true; + npcBody->friction = 0.0f; + physicsengine->AddObject(npcBody); + + // ------------------------------------------------------------------------ + // Rain particles + // ------------------------------------------------------------------------ + ParticleEmitter* rain = new ParticleEmitter(); + rain->name = "rain"; + rain->tex = snowflake; + rain->opaque = false; + rain->speed = 35.0f; + rain->lifespan = 0.6f; + rain->angularvelocity = { 0.0f, 0.0f, glm::radians(10.0f) }; + rain->size = { 0.04f, 0.4f, 0.0f }; + rain->emitangle = { glm::radians(60.0f), glm::radians(360.0f), glm::radians(60.0f) }; + rain->facecamera = false; + rain->color = { 1.0f, 1.0f, 1.0f, 1.0f }; + rain->emitdirection = ParticleEmitter::EmitDirection::Perpendicular; + rain->t.TranslateTo({ 0.0f, 10.0f, 0.0f }); + rain->t.RotateToQuaternion(glm::quat(glm::vec3(glm::radians(85.0f), 0.0f, 0.0f))); + rain->BindToRenderSystem(); + mainf->AddChild(rain); + + // ------------------------------------------------------------------------ + // 3D audio + // ------------------------------------------------------------------------ + Sound* music = new Sound(); + music->name = "music"; + music->LoadSound("assets/fs.wav", true); + music->Update3DPosition(0.0f, 0.0f, 0.0f); + music->PlayTrack(true); + mainf->AddChild(music); + + // ------------------------------------------------------------------------ + // GUI + // ------------------------------------------------------------------------ + Box* crosshair = new Box(); + crosshair->Color = { 0.0f, 0.0f, 0.0f }; + crosshair->t2d.center = { 0.5f, 0.5f }; + crosshair->t2d.position = { 0.5f, 0.5f, 0.0f, 0.0f }; + crosshair->t2d.size = { 0.0f, 0.0f, 4.0f, 4.0f }; + crosshair->BindToRenderSystem(); + + TextBox* tb = new TextBox(); + tb->font = arial; + tb->text = "ASDASD\nASDASD\nADSADSA"; + tb->fontsize = 0.5f; + tb->Color = { 0.0f, 0.0f, 0.0f }; + tb->t2d.position = { 0.5f, 0.5f, 0.0f, 0.0f }; + tb->t2d.center = { 0.0f, 0.0f }; + tb->textCenter = { 0.0f, 0.5f }; + tb->t2d.size = { 0.2f, 0.1f, 0.0f, 0.0f }; + tb->BindToRenderSystem(); + + TextBox* fpsCounter = new TextBox(); + fpsCounter->font = arial; + fpsCounter->text = "TEST1231231123"; + fpsCounter->fontsize = 0.5f; + fpsCounter->Color = { 0.0f, 0.0f, 0.0f }; + fpsCounter->t2d.position = { 1.0f, 0.0f, 0.0f, 0.0f }; + fpsCounter->t2d.center = { 1.0f, 0.0f }; + fpsCounter->textCenter = { 0.0f, 0.5f }; + fpsCounter->t2d.size = { 0.1f, 0.1f, 0.0f, 0.0f }; + fpsCounter->BindToRenderSystem(); + + ImageBox* testgui = new ImageBox(); + testgui->tex = magic; + testgui->Color = { 1.0f, 1.0f, 1.0f }; + testgui->Opacity = 0.8f; + testgui->rounding = 0.1f; + testgui->t2d.center = { 0.0f, 1.0f }; + testgui->t2d.position = { 0.0f, 1.0f, 10.0f, -10.0f }; + testgui->t2d.size = { 0.0f, 0.0f, 744.0f / 2.0f, 914.0f / 2.0f }; + testgui->BindToRenderSystem(); + + // ------------------------------------------------------------------------ + // World meshes + // ------------------------------------------------------------------------ + Model leonrevolver("assets/leonrevolver.obj"); + for (Mesh* mesh : leonrevolver.meshes) { + auto newmesh = mesh->Clone(); + newmesh->name = "revolver"; + newmesh->castshadow = true; + newmesh->meshTexture = leontex; + newmesh->t.TranslateBy({ 4.0f, 4.0f, 4.0f }); + newmesh->BindToRenderSystem(); + mainf->AddChild(newmesh); + } + + Mesh* debugcube = CreateCubeMesh(); + debugcube->name = "debugcube"; + debugcube->t.ScaleTo({ 0.8f, 0.8f, 0.8f }); + debugcube->BindToRenderSystem(); + mainf->AddChild(debugcube); + + Mesh* floor = CreateCubeMesh(); + floor->name = "floor"; + floor->meshTexture = blanktex; + floor->t.ScaleTo({ 100.0f, 2.0f, 100.0f }); + floor->t.TranslateTo({ 0.0f, -1.0f, 0.0f }); + floor->BindToRenderSystem(); + mainf->AddChild(floor); + p* floorBody = new p(floor); + floorBody->velocity = false; + physicsengine->AddObject(floorBody); + + Mesh* cube = CreateCubeMesh(); + cube->name = "cube"; + cube->meshTexture = blanktex; + cube->t.ScaleTo({ 1.0f, 1.0f, 1.0f }); + cube->t.TranslateTo({ 5.0f, 4.0f, 6.5f }); + cube->BindToRenderSystem(); + mainf->AddChild(cube); + + Mesh* cube2 = CreateCubeMesh(); + cube2->name = "cubee"; + cube2->meshTexture = blanktex; + cube2->t.ScaleTo({ 1.0f, 1.0f, 1.0f }); + cube2->t.TranslateTo({ 10.0f, 4.0f, 10.5f }); + cube2->BindToRenderSystem(); + mainf->AddChild(cube2); + + // Ground check + auto IsGrounded = [&]() -> bool { + Ray downRay; + downRay.origin = testcharacter->body->t.GetTranslation(); + downRay.direction = glm::vec3(0.0f, -1.0f, 0.0f); + const float halfHeight = testcharacter->body->t.GetScale().y * 0.5f; + for (p* obj : physicsengine->GetObjects()) { + if (obj->pointer == testcharacter->body) continue; + if (!obj->collision) continue; + auto hit = IsRayInT(downRay, obj->pointer->t); + if (hit.has_value()) { + if (glm::distance(downRay.origin, hit.value()) < halfHeight + 0.15f) + return true; + } + } + return false; + }; + + // ======================================================================== + // Game loop + // ======================================================================== + while (!glfwWindowShouldClose(window->handle)) + { + frame++; + const float deltatime = 1.0f / float(fps); + + const glm::vec3 camFront = camera->t.GetFrontVector(); + const glm::vec3 camRight = camera->t.GetRightVector(); + const float movespeed = 3.0f; + + // -------------------------------------------------------------------- + // Input — mouse + // -------------------------------------------------------------------- + while (Mouse::Event buffer = mouse->Read()) { + if (buffer.GetType() == Mouse::Event::Type::Move) { + float xoffset = mouse->GetX() - mouse->GetLastX(); + float yoffset = mouse->GetLastY() - mouse->GetY(); + camera->ProcessMouseMovement(xoffset, yoffset); + } + else if (buffer.GetType() == Mouse::Event::Type::RPress) { + camera->lockedcursor = !camera->lockedcursor; + } + } + + // -------------------------------------------------------------------- + // Input — held movement + // -------------------------------------------------------------------- + glm::vec3 inputVel = glm::vec3(0.0f); + if (keyboard->IsKeyDown('W')) inputVel += glm::normalize(glm::vec3(camFront.x, 0.0f, camFront.z)); + if (keyboard->IsKeyDown('S')) inputVel -= glm::normalize(glm::vec3(camFront.x, 0.0f, camFront.z)); + if (keyboard->IsKeyDown('A')) inputVel += glm::normalize(glm::vec3(camRight.x, 0.0f, camRight.z)); + if (keyboard->IsKeyDown('D')) inputVel -= glm::normalize(glm::vec3(camRight.x, 0.0f, camRight.z)); + if (glm::length(inputVel) > 0.0f) + inputVel = glm::normalize(inputVel) * movespeed; + + // -------------------------------------------------------------------- + // Input — keyboard events + // -------------------------------------------------------------------- + while (Keyboard::Event buffer = keyboard->ReadKey()) { + if (buffer.GetCode() == 'E' && buffer.IsPress()) { + Mesh* nc = CreateCubeMesh(); + nc->name = "cube!"; + nc->t.ScaleTo(1.0f); + nc->t.TranslateTo(camera->t.GetTranslation()); + nc->t.RotateByEulerAngles({ 0.0f, 0.0f, 0.0f }); + nc->BindToRenderSystem(); + mainf->AddChild(nc); + physicsengine->AddObject(new p(nc)); + } + if (buffer.GetCode() == 'F' && buffer.IsPress()) { + const glm::vec3 playerPos = testcharacter->body->t.GetTranslation(); + const glm::vec3 playerFront = glm::normalize(glm::vec3(camFront.x, 0.0f, camFront.z)); + + // Restart punch on high-priority animator + punchAnimator->m_CurrentTime = 0.0f; + punchAnimator->PlayAnimation(); + + debugcube->t.TranslateTo(playerPos + playerFront * 0.8f); + debugcube->t.ScaleTo({ 0.8f, 0.8f, 0.8f }); + debugcube->t.RotateToQuaternion(LookAt(-playerFront)); + + std::optional hit = TInT(debugcube->t, npc->body->t); + if (hit.has_value()) { + std::cout << "HIT NPC\n"; + npcBody->WakeUp(); + npcBody->linearvelocity += playerFront * 5.0f + glm::vec3(0.0f, 3.0f, 0.0f); + camera->AddScreenshake(0.15f); // landing a punch feels impactful + } + else { + std::cout << "MISSED\n"; + } + } + if (buffer.GetCode() == GLFW_KEY_LEFT_SHIFT && buffer.IsPress()) { + glm::vec3 dashDir = glm::length(inputVel) > 0.0f + ? glm::normalize(inputVel) + : glm::normalize(glm::vec3(camFront.x, 0.0f, camFront.z)); + characterBody->linearvelocity.x += dashDir.x * 18.0f; + characterBody->linearvelocity.z += dashDir.z * 18.0f; + camera->AddScreenshake(0.04f); + } + if (buffer.GetCode() == 'G' && buffer.IsPress()) { + camera->AddScreenshake(0.2f); + } + if (buffer.GetCode() == GLFW_KEY_SPACE && buffer.IsPress()) { + if (IsGrounded()) + characterBody->linearvelocity.y = 5.0f; + } + } + + // -------------------------------------------------------------------- + // Input — held keys + // -------------------------------------------------------------------- + if (keyboard->IsKeyDown(GLFW_KEY_ESCAPE)) + glfwSetWindowShouldClose(window->handle, 1); + + // Movement + damping + const float accel = 40.0f; + const float damp = 0.75f; + characterBody->linearvelocity.x *= damp; + characterBody->linearvelocity.z *= damp; + characterBody->linearvelocity.x += inputVel.x * accel * deltatime; + characterBody->linearvelocity.z += inputVel.z * accel * deltatime; + + // -------------------------------------------------------------------- + // Scene updates + // -------------------------------------------------------------------- + { + const glm::vec3 playerPos = testcharacter->body->t.GetTranslation(); + const glm::vec3 playerFront = glm::normalize(glm::vec3(camFront.x, 0.0f, camFront.z)); + debugcube->t.TranslateTo(playerPos + playerFront * 0.8f); + debugcube->t.ScaleTo({ 0.8f, 0.8f, 0.8f }); + debugcube->t.RotateToQuaternion(LookAt(-playerFront)); + } + + rain->t.TranslateTo(camera->t.GetTranslation() + glm::vec3(0.0f, 20.0f, 0.0f)); + for (int i = 0; i < 30; i++) rain->Emit(); + + testcharacter->body->t.RotateToQuaternion( + LookAt(-glm::normalize(glm::vec3(camFront.x, 0.0f, camFront.z))) + ); + camera->t.TranslateTo( + testcharacter->body->t.GetTranslation() - camera->t.GetFrontVector() * 3.0f + ); + + Sound* music = static_cast(mainf->GetFirstChildOfName("music")); + Mesh* cube = static_cast(mainf->GetFirstChildOfName("cube")); + music->Update3DPosition(cube->t.GetTranslation()); + + soundsystem->SetListenerPosition( + camera->t.GetTranslation(), + camera->t.GetFrontVector(), + camera->t.GetUpVector() + ); + + // -------------------------------------------------------------------- + // FPS counter + // -------------------------------------------------------------------- + { + static double lastTime = glfwGetTime(); + static int frameCount = 0; + static int measuredFps = 0; + static float accumulator = 0.0f; + double now = glfwGetTime(); + accumulator += (float)(now - lastTime); + lastTime = now; + frameCount++; + if (accumulator >= 0.25f) { + measuredFps = (int)(frameCount / accumulator); + frameCount = 0; + accumulator = 0.0f; + } + fpsCounter->text = std::to_string(measuredFps) + " FPS"; + } + + // -------------------------------------------------------------------- + // Step systems + // -------------------------------------------------------------------- + camera->Step(deltatime); + rain->Step(deltatime); + testcharacter->Step(deltatime); + npc->Step(deltatime); + soundsystem->Update(); + physicsengine->Step(deltatime); + + // -------------------------------------------------------------------- + // Render + // -------------------------------------------------------------------- + rendersystem->Render(*camera); + + glfwPollEvents(); + } +} + +// ============================================================================ +// GLFW callbacks +// ============================================================================ +void framebuffer_size_callback(GLFWwindow* window, int w, int h) +{ +} + +void key_callback(GLFWwindow* window, int key, int scancode, int action, int mods) +{ + if (action == GLFW_PRESS) keyboard->KeyDown(key); + else if (action == GLFW_RELEASE) keyboard->KeyUp(key); +} + +void scroll_callback(GLFWwindow* window, double xoffset, double yoffset) +{ +} + +void mouse_callback(GLFWwindow* window, double xposIn, double yposIn) +{ + mouse->OnMouseMove(static_cast(xposIn), static_cast(yposIn)); + glfwSetInputMode(window, GLFW_CURSOR, GLFW_CURSOR_DISABLED); + glfwSetCursorPos(window, ::window->width / 2, ::window->height / 2); + mouse->OnMouseMove(::window->width / 2.0f, ::window->height / 2.0f); +} + +void mouse_button_callback(GLFWwindow* window, int button, int action, int mods) +{ + if (button == GLFW_MOUSE_BUTTON_RIGHT) { + if (action == GLFW_PRESS) mouse->RightDown(); + else mouse->RightUp(); + } + else if (button == GLFW_MOUSE_BUTTON_LEFT) { + if (action == GLFW_PRESS) mouse->LeftDown(); + else mouse->LeftUp(); + } +} \ No newline at end of file diff --git a/Engine.h b/Engine.h new file mode 100644 index 0000000..0b9ba4e --- /dev/null +++ b/Engine.h @@ -0,0 +1,61 @@ + + +#ifndef ENGINE_CLASS +#define ENGINE_CLASS + +//OVERARCHING LIBRARIES +#include +#include + +//OPENGL LIBRARIES +#include +#include + +//MANMADE LIBRARIES +#include "common.h" + +inline int fps = 60; + +void framebuffer_size_callback(GLFWwindow* windowe, int w, int h); + +void key_callback(GLFWwindow* window, int key, int scancode, int action, int mods); + +void scroll_callback(GLFWwindow* window, double xoffset, double yoffset); + +void mouse_callback(GLFWwindow* windowe, double xposIn, double yposIn); + +void mouse_button_callback(GLFWwindow* window, int button, int action, int mods); + +class Physics; +class RenderSystem; +class SoundSystem; +class Folder; +class ParticleEmitter; +class Camera; +class Animator; + +class Engine { +public: + //SYSTEMS + Physics* physicsengine; + RenderSystem* rendersystem; +public: + //METADATA + int frame = 0; +public: + //DEBUG + bool renderwireframe = false; +public: + //RESOURCE MANAGEMENT + Folder* mainf; +public: + //CAMERA + Camera* camera; +public: + + Engine(); + + void Initiate(); +}; + +#endif diff --git a/FBO.h b/FBO.h new file mode 100644 index 0000000..8e643bd --- /dev/null +++ b/FBO.h @@ -0,0 +1,26 @@ + +#ifndef FBO_CLASS_H +#define FBO_CLASS_H + +#include + +// cube + +class FBO { +public: + GLuint ID; + FBO() { + glGenFramebuffers(1, &ID); + }; + void Bind() { + glBindFramebuffer(GL_FRAMEBUFFER, ID); + }; + void Unbind() { + glBindFramebuffer(GL_FRAMEBUFFER, 0); + }; + void Delete() { + glDeleteFramebuffers(1, &ID); + }; +}; + +#endif \ No newline at end of file diff --git a/FMOD/api/core/examples/3d.cpp b/FMOD/api/core/examples/3d.cpp new file mode 100644 index 0000000..24f1fa6 --- /dev/null +++ b/FMOD/api/core/examples/3d.cpp @@ -0,0 +1,215 @@ +/*============================================================================== +3D Example +Copyright (c), Firelight Technologies Pty, Ltd 2004-2026. + +This example shows how to basic 3D positioning of sounds. + +For information on using FMOD example code in your own programs, visit +https://www.fmod.com/legal +==============================================================================*/ +#include "fmod.hpp" +#include "common.h" + +const int INTERFACE_UPDATETIME = 50; // 50ms update for interface +const float DISTANCEFACTOR = 1.0f; // Units per meter. I.e feet would = 3.28. centimeters would = 100. + +int FMOD_Main() +{ + FMOD::System *system; + FMOD::Sound *sound1, *sound2, *sound3; + FMOD::Channel *channel1 = 0, *channel2 = 0, *channel3 = 0; + FMOD_RESULT result; + bool listenerflag = true; + FMOD_VECTOR listenerpos = { 0.0f, 0.0f, -1.0f * DISTANCEFACTOR }; + void *extradriverdata = 0; + + Common_Init(&extradriverdata); + + /* + Create a System object and initialize. + */ + result = FMOD::System_Create(&system); + ERRCHECK(result); + + result = system->init(100, FMOD_INIT_NORMAL, extradriverdata); + ERRCHECK(result); + + /* + Set the distance units. (meters/feet etc). + */ + result = system->set3DSettings(1.0, DISTANCEFACTOR, 1.0f); + ERRCHECK(result); + + /* + Load some sounds + */ + result = system->createSound(Common_MediaPath("drumloop.wav"), FMOD_3D, 0, &sound1); + ERRCHECK(result); + result = sound1->set3DMinMaxDistance(0.5f * DISTANCEFACTOR, 5000.0f * DISTANCEFACTOR); + ERRCHECK(result); + result = sound1->setMode(FMOD_LOOP_NORMAL); + ERRCHECK(result); + + result = system->createSound(Common_MediaPath("jaguar.wav"), FMOD_3D, 0, &sound2); + ERRCHECK(result); + result = sound2->set3DMinMaxDistance(0.5f * DISTANCEFACTOR, 5000.0f * DISTANCEFACTOR); + ERRCHECK(result); + result = sound2->setMode(FMOD_LOOP_NORMAL); + ERRCHECK(result); + + result = system->createSound(Common_MediaPath("swish.wav"), FMOD_2D, 0, &sound3); + ERRCHECK(result); + + /* + Play sounds at certain positions + */ + { + FMOD_VECTOR pos = { -10.0f * DISTANCEFACTOR, 0.0f, 0.0f }; + FMOD_VECTOR vel = { 0.0f, 0.0f, 0.0f }; + + result = system->playSound(sound1, 0, true, &channel1); + ERRCHECK(result); + result = channel1->set3DAttributes(&pos, &vel); + ERRCHECK(result); + result = channel1->setPaused(false); + ERRCHECK(result); + } + + { + FMOD_VECTOR pos = { 15.0f * DISTANCEFACTOR, 0.0f, 0.0f }; + FMOD_VECTOR vel = { 0.0f, 0.0f, 0.0f }; + + result = system->playSound(sound2, 0, true, &channel2); + ERRCHECK(result); + result = channel2->set3DAttributes(&pos, &vel); + ERRCHECK(result); + result = channel2->setPaused(false); + ERRCHECK(result); + } + + /* + Main loop + */ + do + { + Common_Update(); + + if (Common_BtnPress(BTN_ACTION1)) + { + bool paused; + channel1->getPaused(&paused); + channel1->setPaused(!paused); + } + + if (Common_BtnPress(BTN_ACTION2)) + { + bool paused; + channel2->getPaused(&paused); + channel2->setPaused(!paused); + } + + if (Common_BtnPress(BTN_ACTION3)) + { + result = system->playSound(sound3, 0, false, &channel3); + ERRCHECK(result); + } + + if (Common_BtnPress(BTN_MORE)) + { + listenerflag = !listenerflag; + } + + if (!listenerflag) + { + if (Common_BtnDown(BTN_LEFT)) + { + listenerpos.x -= 1.0f * DISTANCEFACTOR; + if (listenerpos.x < -24 * DISTANCEFACTOR) + { + listenerpos.x = -24 * DISTANCEFACTOR; + } + } + + if (Common_BtnDown(BTN_RIGHT)) + { + listenerpos.x += 1.0f * DISTANCEFACTOR; + if (listenerpos.x > 23 * DISTANCEFACTOR) + { + listenerpos.x = 23 * DISTANCEFACTOR; + } + } + } + + // ========================================================================================== + // UPDATE THE LISTENER + // ========================================================================================== + { + static float t = 0; + static FMOD_VECTOR lastpos = { 0.0f, 0.0f, 0.0f }; + FMOD_VECTOR forward = { 0.0f, 0.0f, 1.0f }; + FMOD_VECTOR up = { 0.0f, 1.0f, 0.0f }; + FMOD_VECTOR vel; + + if (listenerflag) + { + listenerpos.x = (float)sin(t * 0.05f) * 24.0f * DISTANCEFACTOR; // left right pingpong + } + + // ********* NOTE ******* READ NEXT COMMENT!!!!! + // vel = how far we moved last FRAME (m/f), then time compensate it to SECONDS (m/s). + vel.x = (listenerpos.x - lastpos.x) * (1000 / INTERFACE_UPDATETIME); + vel.y = (listenerpos.y - lastpos.y) * (1000 / INTERFACE_UPDATETIME); + vel.z = (listenerpos.z - lastpos.z) * (1000 / INTERFACE_UPDATETIME); + + // store pos for next time + lastpos = listenerpos; + + result = system->set3DListenerAttributes(0, &listenerpos, &vel, &forward, &up); + ERRCHECK(result); + + t += (30 * (1.0f / (float)INTERFACE_UPDATETIME)); // t is just a time value .. it increments in 30m/s steps in this example + } + + result = system->update(); + ERRCHECK(result); + + // Create small visual display. + char s[80] = "|.............<1>......................<2>.......|"; + s[(int)(listenerpos.x / DISTANCEFACTOR) + 25] = 'L'; + + Common_Draw("=================================================="); + Common_Draw("3D Example."); + Common_Draw("Copyright (c) Firelight Technologies 2004-2026."); + Common_Draw("=================================================="); + Common_Draw(""); + Common_Draw("Press %s to toggle sound 1 (16bit Mono 3D)", Common_BtnStr(BTN_ACTION1)); + Common_Draw("Press %s to toggle sound 2 (8bit Mono 3D)", Common_BtnStr(BTN_ACTION2)); + Common_Draw("Press %s to play a sound (16bit Stereo 2D)", Common_BtnStr(BTN_ACTION3)); + Common_Draw("Press %s or %s to move listener in still mode", Common_BtnStr(BTN_LEFT), Common_BtnStr(BTN_RIGHT)); + Common_Draw("Press %s to toggle listener auto movement", Common_BtnStr(BTN_MORE)); + Common_Draw("Press %s to quit", Common_BtnStr(BTN_QUIT)); + Common_Draw(""); + Common_Draw(s); + + Common_Sleep(INTERFACE_UPDATETIME - 1); + } while (!Common_BtnPress(BTN_QUIT)); + + /* + Shut down + */ + result = sound1->release(); + ERRCHECK(result); + result = sound2->release(); + ERRCHECK(result); + result = sound3->release(); + ERRCHECK(result); + + result = system->close(); + ERRCHECK(result); + result = system->release(); + ERRCHECK(result); + + Common_Close(); + + return 0; +} diff --git a/FMOD/api/core/examples/asyncio.cpp b/FMOD/api/core/examples/asyncio.cpp new file mode 100644 index 0000000..2afad89 --- /dev/null +++ b/FMOD/api/core/examples/asyncio.cpp @@ -0,0 +1,348 @@ +/*=============================================================================================== + Async IO Example + Copyright (c), Firelight Technologies Pty, Ltd 2004-2026. + + This example shows how to play a stream and use a custom file handler that defers reads for the + streaming part. FMOD will allow the user to return straight away from a file read request and + supply the data at a later time. +===============================================================================================*/ +#include "fmod.hpp" +#include "common.h" +#include + +struct AsyncData +{ + FMOD_ASYNCREADINFO *info; +}; + +struct ScopedMutex +{ + Common_Mutex *mMutex; + ScopedMutex(Common_Mutex *mutex) : mMutex(mutex) { Common_Mutex_Enter(mMutex); } + ~ScopedMutex() { Common_Mutex_Leave(mMutex); } +}; + +Common_Mutex gListCrit; +std::list gList; +bool gThreadQuit = false; +bool gThreadFinished = false; +bool gSleepBreak = false; + + +/* + A little text buffer to allow a scrolling window +*/ +const int DRAW_ROWS = NUM_ROWS - 8; +const int DRAW_COLS = NUM_COLUMNS; + +char gLineData[DRAW_ROWS][DRAW_COLS]; +Common_Mutex gLineCrit; + +void AddLine(const char *formatString...) +{ + ScopedMutex mutex(&gLineCrit); + + char s[DRAW_COLS]; + va_list args; + va_start(args, formatString); + Common_vsnprintf(s, DRAW_COLS, formatString, args); + va_end(args); + + for (int i = 1; i < DRAW_ROWS; i++) + { + memcpy(gLineData[i-1], gLineData[i], DRAW_COLS); + } + strncpy(gLineData[DRAW_ROWS-1], s, DRAW_COLS); +} + +void DrawLines() +{ + ScopedMutex mutex(&gLineCrit); + + for (int i = 0; i < DRAW_ROWS; i++) + { + Common_Draw(gLineData[i]); + } +} + + +/* + File callbacks +*/ +FMOD_RESULT F_CALL myopen(const char *name, unsigned int *filesize, void **handle, void * /*userdata*/) +{ + assert(name); + assert(filesize); + assert(handle); + + Common_File_Open(name, 0, filesize, handle); // mode 0 = 'read'. + + if (!handle) + { + return FMOD_ERR_FILE_NOTFOUND; + } + + return FMOD_OK; +} + +FMOD_RESULT F_CALL myclose(void *handle, void * /*userdata*/) +{ + assert(handle); + + Common_File_Close(handle); + + return FMOD_OK; +} + +FMOD_RESULT F_CALL myread(void *handle, void *buffer, unsigned int sizebytes, unsigned int *bytesread, void * /*userdata*/) +{ + assert(handle); + assert(buffer); + assert(bytesread); + + Common_File_Read(handle, buffer, sizebytes, bytesread); + + if (*bytesread < sizebytes) + { + return FMOD_ERR_FILE_EOF; + } + + return FMOD_OK; +} + +FMOD_RESULT F_CALL myseek(void *handle, unsigned int pos, void * /*userdata*/) +{ + assert(handle); + + Common_File_Seek(handle, pos); + + return FMOD_OK; +} + +FMOD_RESULT F_CALL myasyncread(FMOD_ASYNCREADINFO *info, void * /*userdata*/) +{ + assert(info); + + ScopedMutex mutex(&gListCrit); + + AsyncData *data = (AsyncData *)malloc(sizeof(AsyncData)); + if (!data) + { + /* Signal FMOD to wake up, this operation has has failed */ + info->done(info, FMOD_ERR_MEMORY); + return FMOD_ERR_MEMORY; + } + + AddLine("REQUEST %5d bytes, offset %5d PRIORITY = %d.", info->sizebytes, info->offset, info->priority); + data->info = info; + gList.push_back(data); + + /* Example only: Use your native filesystem scheduler / priority here */ + if (info->priority > 50) + { + gSleepBreak = true; + } + + return FMOD_OK; +} + +FMOD_RESULT F_CALL myasynccancel(FMOD_ASYNCREADINFO *info, void * /*userdata*/) +{ + assert(info); + + ScopedMutex mutex(&gListCrit); + + /* Find the pending IO request and remove it */ + for (std::list::iterator itr = gList.begin(); itr != gList.end(); itr++) + { + AsyncData *data = *itr; + if (data->info == info) + { + gList.remove(data); + free(data); + + /* Signal FMOD to wake up, this operation has been cancelled */ + info->done(info, FMOD_ERR_FILE_DISKEJECTED); + return FMOD_ERR_FILE_DISKEJECTED; + } + } + + /* IO request not found, it must have completed already */ + return FMOD_OK; +} + + +/* + Async file IO processing thread +*/ +void ProcessQueue(void * /*param*/) +{ + while (!gThreadQuit) + { + /* Grab the next IO task off the list */ + FMOD_ASYNCREADINFO *info = NULL; + Common_Mutex_Enter(&gListCrit); + if (!gList.empty()) + { + info = gList.front()->info; + gList.pop_front(); + } + Common_Mutex_Leave(&gListCrit); + + if (info) + { + /* Example only: Let's deprive the read of the whole block, only give 16kb at a time to make it re-ask for more later */ + unsigned int toread = info->sizebytes; + if (toread > 16384) + { + toread = 16384; + } + + /* Example only: Demonstration of priority influencing turnaround time */ + for (int i = 0; i < 50; i++) + { + Common_Sleep(10); + if (gSleepBreak) + { + AddLine("URGENT REQUEST - reading now!"); + gSleepBreak = false; + break; + } + } + + /* Process the seek and read request with EOF handling */ + Common_File_Seek(info->handle, info->offset); + + Common_File_Read(info->handle, info->buffer, toread, &info->bytesread); + + if (info->bytesread < toread) + { + AddLine("FED %5d bytes, offset %5d (* EOF)", info->bytesread, info->offset); + info->done(info, FMOD_ERR_FILE_EOF); + } + else + { + AddLine("FED %5d bytes, offset %5d", info->bytesread, info->offset); + info->done(info, FMOD_OK); + } + } + else + { + Common_Sleep(10); /* Example only: Use your native filesystem synchronisation to wait for more requests */ + } + } + + gThreadFinished = true; +} + + +int FMOD_Main() +{ + void *extradriverdata = NULL; + void *threadhandle = NULL; + + Common_Init(&extradriverdata); + + Common_Mutex_Create(&gLineCrit); + Common_Mutex_Create(&gListCrit); + + Common_Thread_Create(ProcessQueue, NULL, &threadhandle); + + /* + Create a System object and initialize. + */ + FMOD::System *system = NULL; + FMOD_RESULT result = FMOD::System_Create(&system); + ERRCHECK(result); + + result = system->init(1, FMOD_INIT_NORMAL, extradriverdata); + ERRCHECK(result); + + result = system->setStreamBufferSize(32768, FMOD_TIMEUNIT_RAWBYTES); + ERRCHECK(result); + + result = system->setFileSystem(myopen, myclose, myread, myseek, myasyncread, myasynccancel, 2048); + ERRCHECK(result); + + FMOD::Sound *sound = NULL; + result = system->createStream(Common_MediaPath("wave.mp3"), FMOD_LOOP_NORMAL | FMOD_2D | FMOD_IGNORETAGS, NULL, &sound); + ERRCHECK(result); + + FMOD::Channel *channel = NULL; + result = system->playSound(sound, 0, false, &channel); + ERRCHECK(result); + + /* + Main loop. + */ + do + { + Common_Update(); + + if (sound) + { + bool starving = false; + FMOD_OPENSTATE openstate = FMOD_OPENSTATE_READY; + result = sound->getOpenState(&openstate, NULL, &starving, NULL); + ERRCHECK(result); + + if (starving) + { + AddLine("Starving"); + } + + result = channel->setMute(starving); + ERRCHECK(result); + } + + if (Common_BtnPress(BTN_ACTION1)) + { + result = sound->release(); + if (result == FMOD_OK) + { + sound = NULL; + AddLine("Released sound"); + } + } + + result = system->update(); + ERRCHECK(result); + + Common_Draw("=================================================="); + Common_Draw("Async IO Example."); + Common_Draw("Copyright (c) Firelight Technologies 2004-2026."); + Common_Draw("=================================================="); + Common_Draw(""); + Common_Draw("Press %s to release playing stream", Common_BtnStr(BTN_ACTION1)); + Common_Draw("Press %s to quit", Common_BtnStr(BTN_QUIT)); + Common_Draw(""); + DrawLines(); + Common_Sleep(50); + } while (!Common_BtnPress(BTN_QUIT)); + + /* + Shut down + */ + if (sound) + { + result = sound->release(); + ERRCHECK(result); + } + result = system->close(); + ERRCHECK(result); + result = system->release(); + ERRCHECK(result); + + gThreadQuit = true; + while (!gThreadFinished) + { + Common_Sleep(10); + } + + Common_Mutex_Destroy(&gListCrit); + Common_Mutex_Destroy(&gLineCrit); + Common_Thread_Destroy(threadhandle); + Common_Close(); + + return 0; +} diff --git a/FMOD/api/core/examples/bin/3d.exe b/FMOD/api/core/examples/bin/3d.exe new file mode 100644 index 0000000..32b16df Binary files /dev/null and b/FMOD/api/core/examples/bin/3d.exe differ diff --git a/FMOD/api/core/examples/bin/asyncio.exe b/FMOD/api/core/examples/bin/asyncio.exe new file mode 100644 index 0000000..c99df07 Binary files /dev/null and b/FMOD/api/core/examples/bin/asyncio.exe differ diff --git a/FMOD/api/core/examples/bin/channel_groups.exe b/FMOD/api/core/examples/bin/channel_groups.exe new file mode 100644 index 0000000..a669101 Binary files /dev/null and b/FMOD/api/core/examples/bin/channel_groups.exe differ diff --git a/FMOD/api/core/examples/bin/convolution_reverb.exe b/FMOD/api/core/examples/bin/convolution_reverb.exe new file mode 100644 index 0000000..df42812 Binary files /dev/null and b/FMOD/api/core/examples/bin/convolution_reverb.exe differ diff --git a/FMOD/api/core/examples/bin/dsp_custom.exe b/FMOD/api/core/examples/bin/dsp_custom.exe new file mode 100644 index 0000000..3f6e7cc Binary files /dev/null and b/FMOD/api/core/examples/bin/dsp_custom.exe differ diff --git a/FMOD/api/core/examples/bin/dsp_effect_per_speaker.exe b/FMOD/api/core/examples/bin/dsp_effect_per_speaker.exe new file mode 100644 index 0000000..b268fc1 Binary files /dev/null and b/FMOD/api/core/examples/bin/dsp_effect_per_speaker.exe differ diff --git a/FMOD/api/core/examples/bin/dsp_inspector.exe b/FMOD/api/core/examples/bin/dsp_inspector.exe new file mode 100644 index 0000000..81a89bc Binary files /dev/null and b/FMOD/api/core/examples/bin/dsp_inspector.exe differ diff --git a/FMOD/api/core/examples/bin/effects.exe b/FMOD/api/core/examples/bin/effects.exe new file mode 100644 index 0000000..0adc89d Binary files /dev/null and b/FMOD/api/core/examples/bin/effects.exe differ diff --git a/FMOD/api/core/examples/bin/fmod.dll b/FMOD/api/core/examples/bin/fmod.dll new file mode 100644 index 0000000..2ed6c15 Binary files /dev/null and b/FMOD/api/core/examples/bin/fmod.dll differ diff --git a/FMOD/api/core/examples/bin/fmod_codec_raw.dll b/FMOD/api/core/examples/bin/fmod_codec_raw.dll new file mode 100644 index 0000000..1bac5e8 Binary files /dev/null and b/FMOD/api/core/examples/bin/fmod_codec_raw.dll differ diff --git a/FMOD/api/core/examples/bin/fmod_distance_filter.dll b/FMOD/api/core/examples/bin/fmod_distance_filter.dll new file mode 100644 index 0000000..97478cd Binary files /dev/null and b/FMOD/api/core/examples/bin/fmod_distance_filter.dll differ diff --git a/FMOD/api/core/examples/bin/fmod_gain.dll b/FMOD/api/core/examples/bin/fmod_gain.dll new file mode 100644 index 0000000..5b3427a Binary files /dev/null and b/FMOD/api/core/examples/bin/fmod_gain.dll differ diff --git a/FMOD/api/core/examples/bin/fmod_noise.dll b/FMOD/api/core/examples/bin/fmod_noise.dll new file mode 100644 index 0000000..087a283 Binary files /dev/null and b/FMOD/api/core/examples/bin/fmod_noise.dll differ diff --git a/FMOD/api/core/examples/bin/fmod_rnbo.dll b/FMOD/api/core/examples/bin/fmod_rnbo.dll new file mode 100644 index 0000000..8555a75 Binary files /dev/null and b/FMOD/api/core/examples/bin/fmod_rnbo.dll differ diff --git a/FMOD/api/core/examples/bin/gapless_playback.exe b/FMOD/api/core/examples/bin/gapless_playback.exe new file mode 100644 index 0000000..5822ee0 Binary files /dev/null and b/FMOD/api/core/examples/bin/gapless_playback.exe differ diff --git a/FMOD/api/core/examples/bin/generate_tone.exe b/FMOD/api/core/examples/bin/generate_tone.exe new file mode 100644 index 0000000..2a0a38d Binary files /dev/null and b/FMOD/api/core/examples/bin/generate_tone.exe differ diff --git a/FMOD/api/core/examples/bin/granular_synth.exe b/FMOD/api/core/examples/bin/granular_synth.exe new file mode 100644 index 0000000..84b5cec Binary files /dev/null and b/FMOD/api/core/examples/bin/granular_synth.exe differ diff --git a/FMOD/api/core/examples/bin/load_from_memory.exe b/FMOD/api/core/examples/bin/load_from_memory.exe new file mode 100644 index 0000000..af61a9a Binary files /dev/null and b/FMOD/api/core/examples/bin/load_from_memory.exe differ diff --git a/FMOD/api/core/examples/bin/multiple_speaker.exe b/FMOD/api/core/examples/bin/multiple_speaker.exe new file mode 100644 index 0000000..2c35aa0 Binary files /dev/null and b/FMOD/api/core/examples/bin/multiple_speaker.exe differ diff --git a/FMOD/api/core/examples/bin/multiple_system.exe b/FMOD/api/core/examples/bin/multiple_system.exe new file mode 100644 index 0000000..de1d62a Binary files /dev/null and b/FMOD/api/core/examples/bin/multiple_system.exe differ diff --git a/FMOD/api/core/examples/bin/net_stream.exe b/FMOD/api/core/examples/bin/net_stream.exe new file mode 100644 index 0000000..2dfb495 Binary files /dev/null and b/FMOD/api/core/examples/bin/net_stream.exe differ diff --git a/FMOD/api/core/examples/bin/output_mp3.dll b/FMOD/api/core/examples/bin/output_mp3.dll new file mode 100644 index 0000000..e52586d Binary files /dev/null and b/FMOD/api/core/examples/bin/output_mp3.dll differ diff --git a/FMOD/api/core/examples/bin/play_sound.exe b/FMOD/api/core/examples/bin/play_sound.exe new file mode 100644 index 0000000..fe71dd7 Binary files /dev/null and b/FMOD/api/core/examples/bin/play_sound.exe differ diff --git a/FMOD/api/core/examples/bin/play_stream.exe b/FMOD/api/core/examples/bin/play_stream.exe new file mode 100644 index 0000000..c83fc3f Binary files /dev/null and b/FMOD/api/core/examples/bin/play_stream.exe differ diff --git a/FMOD/api/core/examples/bin/record.exe b/FMOD/api/core/examples/bin/record.exe new file mode 100644 index 0000000..2c818c2 Binary files /dev/null and b/FMOD/api/core/examples/bin/record.exe differ diff --git a/FMOD/api/core/examples/bin/record_enumeration.exe b/FMOD/api/core/examples/bin/record_enumeration.exe new file mode 100644 index 0000000..d1548bb Binary files /dev/null and b/FMOD/api/core/examples/bin/record_enumeration.exe differ diff --git a/FMOD/api/core/examples/bin/user_created_sound.exe b/FMOD/api/core/examples/bin/user_created_sound.exe new file mode 100644 index 0000000..c4ede99 Binary files /dev/null and b/FMOD/api/core/examples/bin/user_created_sound.exe differ diff --git a/FMOD/api/core/examples/channel_groups.cpp b/FMOD/api/core/examples/channel_groups.cpp new file mode 100644 index 0000000..e67e5e5 --- /dev/null +++ b/FMOD/api/core/examples/channel_groups.cpp @@ -0,0 +1,189 @@ +/*============================================================================== +Channel Groups Example +Copyright (c), Firelight Technologies Pty, Ltd 2004-2026. + +This example shows how to put channels into channel groups, so that you can +affect a group of channels at a time instead of just one. + +For information on using FMOD example code in your own programs, visit +https://www.fmod.com/legal +==============================================================================*/ +#include "fmod.hpp" +#include "common.h" + +int FMOD_Main() +{ + FMOD::System *system; + FMOD::Sound *sound[6]; + FMOD::Channel *channel[6]; + FMOD::ChannelGroup *groupA, *groupB, *masterGroup; + FMOD_RESULT result; + int count; + void *extradriverdata = 0; + + Common_Init(&extradriverdata); + + /* + Create a System object and initialize. + */ + result = FMOD::System_Create(&system); + ERRCHECK(result); + + result = system->init(32, FMOD_INIT_NORMAL, extradriverdata); + ERRCHECK(result); + + result = system->createSound(Common_MediaPath("drumloop.wav"), FMOD_LOOP_NORMAL, 0, &sound[0]); + ERRCHECK(result); + result = system->createSound(Common_MediaPath("jaguar.wav"), FMOD_LOOP_NORMAL, 0, &sound[1]); + ERRCHECK(result); + result = system->createSound(Common_MediaPath("swish.wav"), FMOD_LOOP_NORMAL, 0, &sound[2]); + ERRCHECK(result); + result = system->createSound(Common_MediaPath("c.ogg"), FMOD_LOOP_NORMAL, 0, &sound[3]); + ERRCHECK(result); + result = system->createSound(Common_MediaPath("d.ogg"), FMOD_LOOP_NORMAL, 0, &sound[4]); + ERRCHECK(result); + result = system->createSound(Common_MediaPath("e.ogg"), FMOD_LOOP_NORMAL, 0, &sound[5]); + ERRCHECK(result); + + result = system->createChannelGroup("Group A", &groupA); + ERRCHECK(result); + result = system->createChannelGroup("Group B", &groupB); + ERRCHECK(result); + + result = system->getMasterChannelGroup(&masterGroup); + ERRCHECK(result); + + /* + Instead of being independent, set the group A and B to be children of the master group. + */ + result = masterGroup->addGroup(groupA); + ERRCHECK(result); + + result = masterGroup->addGroup(groupB); + ERRCHECK(result); + + /* + Start all the sounds. + */ + for (count = 0; count < 6; count++) + { + result = system->playSound(sound[count], 0, true, &channel[count]); + ERRCHECK(result); + + result = channel[count]->setChannelGroup((count < 3) ? groupA : groupB); + ERRCHECK(result); + + result = channel[count]->setPaused(false); + ERRCHECK(result); + } + + /* + Change the volume of each group, just because we can! (reduce overall noise). + */ + result = groupA->setVolume(0.5f); + ERRCHECK(result); + result = groupB->setVolume(0.5f); + ERRCHECK(result); + + /* + Main loop. + */ + do + { + Common_Update(); + + if (Common_BtnPress(BTN_ACTION1)) + { + bool mute = true; + groupA->getMute(&mute); + groupA->setMute(!mute); + } + + if (Common_BtnPress(BTN_ACTION2)) + { + bool mute = true; + groupB->getMute(&mute); + groupB->setMute(!mute); + } + + if (Common_BtnPress(BTN_ACTION3)) + { + bool mute = true; + masterGroup->getMute(&mute); + masterGroup->setMute(!mute); + } + + result = system->update(); + ERRCHECK(result); + + { + int channelsplaying = 0; + + result = system->getChannelsPlaying(&channelsplaying, NULL); + ERRCHECK(result); + + Common_Draw("=================================================="); + Common_Draw("Channel Groups Example."); + Common_Draw("Copyright (c) Firelight Technologies 2004-2026."); + Common_Draw("=================================================="); + Common_Draw(""); + Common_Draw("Group A : drumloop.wav, jaguar.wav, swish.wav"); + Common_Draw("Group B : c.ogg, d.ogg, e.ogg"); + Common_Draw(""); + Common_Draw("Press %s to mute/unmute group A", Common_BtnStr(BTN_ACTION1)); + Common_Draw("Press %s to mute/unmute group B", Common_BtnStr(BTN_ACTION2)); + Common_Draw("Press %s to mute/unmute master group", Common_BtnStr(BTN_ACTION3)); + Common_Draw("Press %s to quit", Common_BtnStr(BTN_QUIT)); + Common_Draw(""); + Common_Draw("Channels playing %d", channelsplaying); + } + + Common_Sleep(50); + } while (!Common_BtnPress(BTN_QUIT)); + + + /* + A little fade out over 2 seconds. + */ + { + float pitch = 1.0f; + float vol = 1.0f; + + for (count = 0; count < 200; count++) + { + masterGroup->setPitch(pitch); + masterGroup->setVolume(vol); + + vol -= (1.0f / 200.0f); + pitch -= (0.5f / 200.0f); + + result = system->update(); + ERRCHECK(result); + + Common_Sleep(10); + } + } + + /* + Shut down. + */ + for (count = 0; count < 6; count++) + { + result = sound[count]->release(); + ERRCHECK(result); + } + + result = groupA->release(); + ERRCHECK(result); + result = groupB->release(); + ERRCHECK(result); + + result = system->close(); + ERRCHECK(result); + result = system->release(); + ERRCHECK(result); + + Common_Close(); + + return 0; +} diff --git a/FMOD/api/core/examples/common.cpp b/FMOD/api/core/examples/common.cpp new file mode 100644 index 0000000..0b03ff1 --- /dev/null +++ b/FMOD/api/core/examples/common.cpp @@ -0,0 +1,234 @@ +/*============================================================================== +FMOD Example Framework +Copyright (c), Firelight Technologies Pty, Ltd 2012-2026. +==============================================================================*/ +#include "common.h" +#include "fmod_errors.h" + +/* Cross platform OS Functions internal to the FMOD library, exposed for the example framework. */ +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct FMOD_OS_FILE FMOD_OS_FILE; +typedef struct FMOD_OS_CRITICALSECTION FMOD_OS_CRITICALSECTION; + +FMOD_RESULT F_API FMOD_OS_Time_GetUs(unsigned int *us); +FMOD_RESULT F_API FMOD_OS_Debug_Output(const char *format, ...); +FMOD_RESULT F_API FMOD_OS_File_Open(const char *name, int mode, unsigned int *filesize, FMOD_OS_FILE **handle); +FMOD_RESULT F_API FMOD_OS_File_Close(FMOD_OS_FILE *handle); +FMOD_RESULT F_API FMOD_OS_File_Read(FMOD_OS_FILE *handle, void *buf, unsigned int count, unsigned int *read); +FMOD_RESULT F_API FMOD_OS_File_Write(FMOD_OS_FILE *handle, const void *buffer, unsigned int bytesToWrite, bool flush); +FMOD_RESULT F_API FMOD_OS_File_Seek(FMOD_OS_FILE *handle, unsigned int offset); +FMOD_RESULT F_API FMOD_OS_Time_Sleep(unsigned int ms); +FMOD_RESULT F_API FMOD_OS_CriticalSection_Create(FMOD_OS_CRITICALSECTION **crit, bool memorycrit); +FMOD_RESULT F_API FMOD_OS_CriticalSection_Free(FMOD_OS_CRITICALSECTION *crit, bool memorycrit); +FMOD_RESULT F_API FMOD_OS_CriticalSection_Enter(FMOD_OS_CRITICALSECTION *crit); +FMOD_RESULT F_API FMOD_OS_CriticalSection_Leave(FMOD_OS_CRITICALSECTION *crit); +FMOD_RESULT F_API FMOD_OS_CriticalSection_TryEnter(FMOD_OS_CRITICALSECTION *crit, bool *entered); +FMOD_RESULT F_API FMOD_OS_CriticalSection_IsLocked(FMOD_OS_CRITICALSECTION *crit, bool *locked); +FMOD_RESULT F_API FMOD_OS_Thread_Create(const char *name, void (*callback)(void *param), void *param, FMOD_THREAD_AFFINITY affinity, FMOD_THREAD_PRIORITY priority, FMOD_THREAD_STACK_SIZE stacksize, void **handle); +FMOD_RESULT F_API FMOD_OS_Thread_Destroy(void *handle); + +#ifdef __cplusplus +} +#endif + +void (*Common_Private_Error)(FMOD_RESULT, const char *, int); + +void ERRCHECK_fn(FMOD_RESULT result, const char *file, int line) +{ + if (result != FMOD_OK) + { + if (Common_Private_Error) + { + Common_Private_Error(result, file, line); + } + Common_Fatal("%s(%d): FMOD error %d - %s", file, line, result, FMOD_ErrorString(result)); + } +} + +void Common_Format(char *buffer, int bufferSize, const char *formatString...) +{ + va_list args; + va_start(args, formatString); + Common_vsnprintf(buffer, bufferSize, formatString, args); + va_end(args); + buffer[bufferSize-1] = '\0'; +} + +void Common_Fatal(const char *format, ...) +{ + char error[1024]; + + va_list args; + va_start(args, format); + Common_vsnprintf(error, 1024, format, args); + va_end(args); + error[1023] = '\0'; + + do + { + Common_Draw("A fatal error has occurred..."); + Common_Draw(""); + Common_Draw("%s", error); + Common_Draw(""); + Common_Draw("Press %s to quit", Common_BtnStr(BTN_QUIT)); + + Common_Update(); + Common_Sleep(50); + } while (!Common_BtnPress(BTN_QUIT)); + + Common_Exit(0); +} + +void Common_Draw(const char *format, ...) +{ + char string[1024]; + char *stringPtr = string; + + va_list args; + va_start(args, format); + Common_vsnprintf(string, 1024, format, args); + va_end(args); + string[1023] = '\0'; + + unsigned int length = (unsigned int)strlen(string); + + do + { + bool consumeNewLine = false; + unsigned int copyLength = length; + + // Search for new line characters + char *newLinePtr = strchr(stringPtr, '\n'); + if (newLinePtr) + { + consumeNewLine = true; + copyLength = (unsigned int)(newLinePtr - stringPtr); + } + + if (copyLength > NUM_COLUMNS) + { + // Hard wrap by default + copyLength = NUM_COLUMNS; + + // Loop for a soft wrap + for (int i = NUM_COLUMNS - 1; i >= 0; i--) + { + if (stringPtr[i] == ' ') + { + copyLength = i + 1; + break; + } + } + } + + // Null terminate the sub string temporarily by swapping out a char + char tempChar = stringPtr[copyLength]; + stringPtr[copyLength] = 0; + Common_DrawText(stringPtr); + stringPtr[copyLength] = tempChar; + + copyLength += (consumeNewLine ? 1 : 0); + length -= copyLength; + stringPtr += copyLength; + } while (length > 0); +} + +void Common_Time_GetUs(unsigned int *us) +{ + FMOD_OS_Time_GetUs(us); +} + +void Common_Log(const char *format, ...) +{ + char string[1024]; + + va_list args; + va_start(args, format); + Common_vsnprintf(string, 1024, format, args); + va_end(args); + string[1023] = '\0'; + + FMOD_OS_Debug_Output(string); +} + +void Common_LoadFileMemory(const char *name, void **buff, int *length) +{ + FMOD_OS_FILE *file = NULL; + unsigned int len, bytesread; + + FMOD_OS_File_Open(name, 0, &len, &file); + void *mem = malloc(len); + FMOD_OS_File_Read(file, mem, len, &bytesread); + FMOD_OS_File_Close(file); + + *buff = mem; + *length = bytesread; +} + +void Common_UnloadFileMemory(void *buff) +{ + free(buff); +} + +void Common_Sleep(unsigned int ms) +{ + FMOD_OS_Time_Sleep(ms); +} + +void Common_File_Open(const char *name, int mode, unsigned int *filesize, void **handle) +{ + FMOD_OS_File_Open(name, mode, filesize, (FMOD_OS_FILE **)handle); +} + +void Common_File_Close(void *handle) +{ + FMOD_OS_File_Close((FMOD_OS_FILE *)handle); +} + +void Common_File_Read(void *handle, void *buf, unsigned int length, unsigned int *read) +{ + FMOD_OS_File_Read((FMOD_OS_FILE *)handle, buf, length, read); +} + +void Common_File_Write(void *handle, void *buf, unsigned int length) +{ + FMOD_OS_File_Write((FMOD_OS_FILE *)handle, buf, length, true); +} + +void Common_File_Seek(void *handle, unsigned int offset) +{ + FMOD_OS_File_Seek((FMOD_OS_FILE *)handle, offset); +} + +void Common_Mutex_Create(Common_Mutex *mutex) +{ + FMOD_OS_CriticalSection_Create((FMOD_OS_CRITICALSECTION **)&mutex->crit, false); +} + +void Common_Mutex_Destroy(Common_Mutex *mutex) +{ + FMOD_OS_CriticalSection_Free((FMOD_OS_CRITICALSECTION *)mutex->crit, false); +} + +void Common_Mutex_Enter(Common_Mutex *mutex) +{ + FMOD_OS_CriticalSection_Enter((FMOD_OS_CRITICALSECTION *)mutex->crit); +} + +void Common_Mutex_Leave(Common_Mutex *mutex) +{ + FMOD_OS_CriticalSection_Leave((FMOD_OS_CRITICALSECTION *)mutex->crit); +} + +void Common_Thread_Create(void (*callback)(void *param), void *param, void **handle) +{ + FMOD_OS_Thread_Create("FMOD Example Thread", callback, param, FMOD_THREAD_AFFINITY_GROUP_A, FMOD_THREAD_PRIORITY_MEDIUM, (16 * 1024), handle); +} + +void Common_Thread_Destroy(void *handle) +{ + FMOD_OS_Thread_Destroy(handle); +} diff --git a/FMOD/api/core/examples/common.h b/FMOD/api/core/examples/common.h new file mode 100644 index 0000000..b3af2f3 --- /dev/null +++ b/FMOD/api/core/examples/common.h @@ -0,0 +1,93 @@ +/*============================================================================== +FMOD Example Framework +Copyright (c), Firelight Technologies Pty, Ltd 2012-2026. +==============================================================================*/ +#ifndef FMOD_EXAMPLES_COMMON_H +#define FMOD_EXAMPLES_COMMON_H + +#include "common_platform.h" +#include "fmod.h" + +#include +#include +#include +#include +#include +#include +#include + +#define NUM_COLUMNS 50 +#define NUM_ROWS 25 + +#ifndef Common_Sin + #define Common_Sin sin +#endif + +#ifndef Common_snprintf + #define Common_snprintf snprintf +#endif + +#ifndef Common_vsnprintf + #define Common_vsnprintf vsnprintf +#endif + +enum Common_Button +{ + BTN_ACTION1, + BTN_ACTION2, + BTN_ACTION3, + BTN_ACTION4, + BTN_LEFT, + BTN_RIGHT, + BTN_UP, + BTN_DOWN, + BTN_MORE, + BTN_QUIT +}; + +typedef struct +{ + void *crit; +} Common_Mutex; + +/* Cross platform functions (common) */ +void Common_Format(char *buffer, int bufferSize, const char *formatString...); +void Common_Fatal(const char *format, ...); +void Common_Draw(const char *format, ...); +void Common_Time_GetUs(unsigned int *us); +void Common_Log(const char *format, ...); +void Common_LoadFileMemory(const char *name, void **buff, int *length); +void Common_UnloadFileMemory(void *buff); +void Common_Sleep(unsigned int ms); +void Common_File_Open(const char *name, int mode, unsigned int *filesize, void **handle); // mode : 0 = read, 1 = write. +void Common_File_Close(void *handle); +void Common_File_Read(void *handle, void *buf, unsigned int length, unsigned int *read); +void Common_File_Write(void *handle, void *buf, unsigned int length); +void Common_File_Seek(void *handle, unsigned int offset); +void Common_Mutex_Create(Common_Mutex *mutex); +void Common_Mutex_Destroy(Common_Mutex *mutex); +void Common_Mutex_Enter(Common_Mutex *mutex); +void Common_Mutex_Leave(Common_Mutex *mutex); +void Common_Thread_Create(void (*callback)(void *param), void *param, void **handle); +void Common_Thread_Destroy(void *handle); + +void ERRCHECK_fn(FMOD_RESULT result, const char *file, int line); +#define ERRCHECK(_result) ERRCHECK_fn(_result, __FILE__, __LINE__) +#define Common_Max(_a, _b) ((_a) > (_b) ? (_a) : (_b)) +#define Common_Min(_a, _b) ((_a) < (_b) ? (_a) : (_b)) +#define Common_Clamp(_min, _val, _max) ((_val) < (_min) ? (_min) : ((_val) > (_max) ? (_max) : (_val))) + +/* Functions with platform specific implementation (common_platform) */ +void Common_Init(void **extraDriverData); +void Common_Close(); +void Common_Update(); +void Common_Exit(int returnCode); +void Common_DrawText(const char *text); +bool Common_BtnPress(Common_Button btn); +bool Common_BtnDown(Common_Button btn); +const char *Common_BtnStr(Common_Button btn); +const char *Common_MediaPath(const char *fileName); +const char *Common_WritePath(const char *fileName); + + +#endif diff --git a/FMOD/api/core/examples/common_platform.cpp b/FMOD/api/core/examples/common_platform.cpp new file mode 100644 index 0000000..29410d4 --- /dev/null +++ b/FMOD/api/core/examples/common_platform.cpp @@ -0,0 +1,306 @@ +/*============================================================================== +FMOD Example Framework +Copyright (c), Firelight Technologies Pty, Ltd 2012-2026. +==============================================================================*/ +#define WIN32_LEAN_AND_MEAN + +#include "common.h" +#include +#include +#include +#include +#include + +static HWND gWindow = nullptr; +static int gScreenWidth = 0; +static int gScreenHeight = 0; +static unsigned int gPressedButtons = 0; +static unsigned int gDownButtons = 0; +static unsigned int gLastDownButtons = 0; +static char gWriteBuffer[(NUM_COLUMNS+1) * NUM_ROWS] = {0}; +static char gDisplayBuffer[(NUM_COLUMNS+1) * NUM_ROWS] = {0}; +static unsigned int gYPos = 0; +static bool gQuit = false; +static std::vector gPathList; + +bool Common_Private_Test; +int Common_Private_Argc; +char** Common_Private_Argv; +void (*Common_Private_Update)(unsigned int*); +void (*Common_Private_Print)(const char*); +void (*Common_Private_Close)(); + +void Common_Init(void** /*extraDriverData*/) +{ + CoInitializeEx(nullptr, COINIT_APARTMENTTHREADED); +} + +void Common_Close() +{ + CoUninitialize(); + + for (std::vector::iterator item = gPathList.begin(); item != gPathList.end(); ++item) + { + free(*item); + } + if (Common_Private_Close) + { + Common_Private_Close(); + } +} + +static unsigned int translateButton(unsigned int button) +{ + switch (button) + { + case '1': return (1 << BTN_ACTION1); + case '2': return (1 << BTN_ACTION2); + case '3': return (1 << BTN_ACTION3); + case '4': return (1 << BTN_ACTION4); + case VK_LEFT: return (1 << BTN_LEFT); + case VK_RIGHT: return (1 << BTN_RIGHT); + case VK_UP: return (1 << BTN_UP); + case VK_DOWN: return (1 << BTN_DOWN); + case VK_SPACE: return (1 << BTN_MORE); + case VK_ESCAPE: return (1 << BTN_QUIT); + default: return 0; + } +} + +void Common_Update() +{ + MSG msg = { }; + while (PeekMessage(&msg, nullptr, 0, 0, PM_REMOVE)) + { + TranslateMessage(&msg); + DispatchMessage(&msg); + } + + gPressedButtons = (gLastDownButtons ^ gDownButtons) & gDownButtons; + gPressedButtons |= (gQuit ? (1 << BTN_QUIT) : 0); + gLastDownButtons = gDownButtons; + + memcpy(gDisplayBuffer, gWriteBuffer, sizeof(gWriteBuffer)); + InvalidateRect(gWindow, nullptr, FALSE); + + gYPos = 0; + memset(gWriteBuffer, ' ', sizeof(gWriteBuffer)); + for (int i = 0; i < NUM_ROWS; i++) + { + gWriteBuffer[(i * (NUM_COLUMNS + 1)) + NUM_COLUMNS] = '\n'; + } + + if (Common_Private_Update) + { + Common_Private_Update(&gPressedButtons); + } +} + +void Common_Exit(int returnCode) +{ + exit(returnCode); +} + +void Common_DrawText(const char *text) +{ + if (gYPos < NUM_ROWS) + { + char tempBuffer[NUM_COLUMNS + 1]; + Common_Format(tempBuffer, sizeof(tempBuffer), "%s", text); + memcpy(&gWriteBuffer[gYPos * (NUM_COLUMNS + 1)], tempBuffer, strlen(tempBuffer)); + gYPos++; + } +} + +bool Common_BtnPress(Common_Button btn) +{ + return ((gPressedButtons & (1 << btn)) != 0); +} + +bool Common_BtnDown(Common_Button btn) +{ + return ((gDownButtons & (1 << btn)) != 0); +} + +const char *Common_BtnStr(Common_Button btn) +{ + switch (btn) + { + case BTN_ACTION1: return "1"; + case BTN_ACTION2: return "2"; + case BTN_ACTION3: return "3"; + case BTN_ACTION4: return "4"; + case BTN_LEFT: return "Left"; + case BTN_RIGHT: return "Right"; + case BTN_UP: return "Up"; + case BTN_DOWN: return "Down"; + case BTN_MORE: return "Space"; + case BTN_QUIT: return "Escape"; + default: return "Unknown"; + } +} + +const char *Common_MediaPath(const char *fileName) +{ + char *filePath = (char *)calloc(256, sizeof(char)); + + static const char* pathPrefix = nullptr; + if (!pathPrefix) + { + const char *emptyPrefix = ""; + const char *mediaPrefix = "../media/"; + FILE *file = fopen(fileName, "r"); + if (file) + { + fclose(file); + pathPrefix = emptyPrefix; + } + else + { + pathPrefix = mediaPrefix; + } + } + + strcat(filePath, pathPrefix); + strcat(filePath, fileName); + + gPathList.push_back(filePath); + + return filePath; +} + +const char *Common_WritePath(const char *fileName) +{ + return Common_MediaPath(fileName); +} + +void Common_TTY(const char *format, ...) +{ + char string[1024] = {0}; + + va_list args; + va_start(args, format); + Common_vsnprintf(string, 1023, format, args); + va_end(args); + + if (Common_Private_Print) + { + (*Common_Private_Print)(string); + } + else + { + OutputDebugStringA(string); + } +} + +HFONT CreateDisplayFont() +{ + return CreateFontA(22, 0, 0, 0, FW_DONTCARE, FALSE, FALSE, FALSE, DEFAULT_CHARSET, OUT_OUTLINE_PRECIS, + CLIP_DEFAULT_PRECIS, DEFAULT_QUALITY, FIXED_PITCH, 0); +} + +LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) +{ + if (message == WM_PAINT) + { + PAINTSTRUCT ps; + HDC hdc = BeginPaint(hWnd, &ps); + HDC hdcBack = CreateCompatibleDC(hdc); + + HBITMAP hbmBack = CreateCompatibleBitmap(hdc, gScreenWidth, gScreenHeight); + HBITMAP hbmOld = (HBITMAP)SelectObject(hdcBack, hbmBack); + + HFONT hfnt = CreateDisplayFont(); + HFONT hfntOld = (HFONT)SelectObject(hdcBack, hfnt); + + SetBkColor(hdcBack, RGB(0x0, 0x0, 0x0)); + SetTextColor(hdcBack, RGB(0xFF, 0xFF, 0xFF)); + DrawTextA(hdcBack, gDisplayBuffer, -1, &ps.rcPaint, 0); + BitBlt(hdc, 0, 0, gScreenWidth, gScreenHeight, hdcBack, 0, 0, SRCCOPY); + + SelectObject(hdcBack, hfntOld); + DeleteObject(hfnt); + + SelectObject(hdcBack, hbmOld); + DeleteObject(hbmBack); + + DeleteDC(hdcBack); + EndPaint(hWnd, &ps); + } + else if (message == WM_DESTROY) + { + gQuit = true; + } + else if (message == WM_GETMINMAXINFO) + { + if (gScreenWidth == 0) + { + HDC hdc = GetDC(hWnd); + + HFONT hfnt = CreateDisplayFont(); + HFONT hfntOld = (HFONT)SelectObject(hdc, hfnt); + + TEXTMETRICA metrics = { }; + GetTextMetricsA(hdc, &metrics); + + SelectObject(hdc, hfntOld); + DeleteObject(hfnt); + + ReleaseDC(hWnd, hdc); + + RECT rec = { }; + rec.right = metrics.tmAveCharWidth * NUM_COLUMNS; + rec.bottom = metrics.tmHeight * NUM_ROWS; + + BOOL success = AdjustWindowRect(&rec, WS_CAPTION | WS_SYSMENU, FALSE); + assert(success); + + gScreenWidth = rec.right - rec.left; + gScreenHeight = rec.bottom - rec.top; + } + + LPMINMAXINFO lpMMI = (LPMINMAXINFO)lParam; + lpMMI->ptMinTrackSize.x = gScreenWidth; + lpMMI->ptMinTrackSize.y = gScreenHeight; + lpMMI->ptMaxTrackSize = lpMMI->ptMinTrackSize; + } + else if (message == WM_KEYDOWN) + { + gDownButtons |= translateButton((unsigned int)wParam); + } + else if (message == WM_KEYUP) + { + gDownButtons &= ~translateButton((unsigned int)wParam); + } + else + { + return DefWindowProc(hWnd, message, wParam, lParam); + } + + return 0; +} + +int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE /*hPrevInstance*/, PSTR /*pCmdLine*/, int nCmdShow) +{ + const char CLASS_NAME[] = "FMOD Example Window Class"; + + Common_Private_Argc = __argc; + Common_Private_Argv = __argv; + + WNDCLASSA wc = { }; + wc.style = CS_HREDRAW | CS_VREDRAW; + wc.lpfnWndProc = WndProc; + wc.hInstance = hInstance; + wc.hbrBackground = (HBRUSH)GetStockObject(BLACK_BRUSH); + wc.lpszClassName = CLASS_NAME; + + ATOM atom = RegisterClassA(&wc); + assert(atom); + + gWindow = CreateWindowA(CLASS_NAME, "FMOD Example", WS_CAPTION | WS_SYSMENU, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, nullptr, nullptr, hInstance, nullptr); + assert(gWindow); + + ShowWindow(gWindow, nCmdShow); + + return FMOD_Main(); +} diff --git a/FMOD/api/core/examples/common_platform.h b/FMOD/api/core/examples/common_platform.h new file mode 100644 index 0000000..2b46a6d --- /dev/null +++ b/FMOD/api/core/examples/common_platform.h @@ -0,0 +1,16 @@ +/*============================================================================== +FMOD Example Framework +Copyright (c), Firelight Technologies Pty, Ltd 2012-2026. +==============================================================================*/ +#include + +int FMOD_Main(); + +#define COMMON_PLATFORM_SUPPORTS_FOPEN + +#define Common_snprintf _snprintf +#define Common_vsnprintf _vsnprintf + +void Common_TTY(const char *format, ...); + + diff --git a/FMOD/api/core/examples/convolution_reverb.cpp b/FMOD/api/core/examples/convolution_reverb.cpp new file mode 100644 index 0000000..73d2834 --- /dev/null +++ b/FMOD/api/core/examples/convolution_reverb.cpp @@ -0,0 +1,239 @@ +/*============================================================================== +Convolution Reverb Example +Copyright (c), Firelight Technologies Pty, Ltd 2004-2026. + +This example shows how to set up a convolution reverb DSP as a global +DSP unit that can be routed into by multiple seperate channels. + +Convolution reverb uses data from a real world locations called an +"Impulse Response" to model the reflection of audio waves back +to a listener. + +Impulse Response is based on "St Andrew's Church" by + + www.openairlib.net + Audiolab, University of York + Damian T. Murphy + http://www.openairlib.net/auralizationdb/content/st-andrews-church + +licensed under Attribution Share Alike Creative Commons license +http://creativecommons.org/licenses/by-sa/3.0/ + + +Anechoic sample "Operatic Voice" by + + www.openairlib.net + http://www.openairlib.net/anechoicdb/content/operatic-voice + +licensed under Attribution Share Alike Creative Commons license +http://creativecommons.org/licenses/by-sa/3.0/ + + +### Features Demonstrated ### ++ FMOD_DSP_CONVOLUTION_REVERB ++ DSP::addInput + +For information on using FMOD example code in your own programs, visit +https://www.fmod.com/legal + +==============================================================================*/ +#include "fmod.hpp" +#include "common.h" + +int FMOD_Main() +{ + void *extradriverdata = 0; + Common_Init(&extradriverdata); + + /* + Create a System object and initialize + */ + FMOD_RESULT result; + FMOD::System* system; + result = FMOD::System_Create(&system); + ERRCHECK(result); + + result = system->init(32, FMOD_INIT_NORMAL, extradriverdata); + ERRCHECK(result); + + + /* + Create a new channel group to hold the convolution DSP unit + */ + FMOD::ChannelGroup* reverbGroup; + result = system->createChannelGroup("reverb", &reverbGroup); + ERRCHECK(result); + + + /* + Create a new channel group to hold all the channels and process the dry path + */ + FMOD::ChannelGroup* mainGroup; + result = system->createChannelGroup("main", &mainGroup); + ERRCHECK(result); + + /* + Create the convultion DSP unit and set it as the tail of the channel group + */ + FMOD::DSP* reverbUnit; + result = system->createDSPByType(FMOD_DSP_TYPE_CONVOLUTIONREVERB, &reverbUnit); + ERRCHECK(result); + result = reverbGroup->addDSP(FMOD_CHANNELCONTROL_DSP_TAIL, reverbUnit); + ERRCHECK(result); + + /* + Open the impulse response wav file, but use FMOD_OPENONLY as we want + to read the data into a seperate buffer + */ + FMOD::Sound* irSound; + result = system->createSound(Common_MediaPath("standrews.wav"), FMOD_DEFAULT | FMOD_OPENONLY, NULL, &irSound); + ERRCHECK(result); + + /* + Retrieve the sound information for the Impulse Response input file + */ + FMOD_SOUND_FORMAT irSoundFormat; + FMOD_SOUND_TYPE irSoundType; + int irSoundBits, irSoundChannels; + result = irSound->getFormat(&irSoundType, &irSoundFormat, &irSoundChannels, &irSoundBits); + ERRCHECK(result); + unsigned int irSoundLength; + result = irSound->getLength(&irSoundLength, FMOD_TIMEUNIT_PCM); + ERRCHECK(result); + + + if (irSoundFormat != FMOD_SOUND_FORMAT_PCM16) + { + /* + For simplicity of the example, if the impulse response is the wrong format just display an error + */ + Common_Fatal("Impulse Response file is the wrong audio format"); + } + + /* + The reverb unit expects a block of data containing a single 16 bit int containing + the number of channels in the impulse response, followed by PCM 16 data + */ + unsigned int irDataLength = sizeof(short) * (irSoundLength * irSoundChannels + 1); + short* irData = (short*)malloc(irDataLength); + irData[0] = (short)irSoundChannels; + unsigned int irDataRead; + result = irSound->readData(&irData[1], irDataLength - sizeof(short), &irDataRead); + ERRCHECK(result); + result = reverbUnit->setParameterData(FMOD_DSP_CONVOLUTION_REVERB_PARAM_IR, irData, irDataLength); + ERRCHECK(result); + + /* + Don't pass any dry signal from the reverb unit, instead take the dry part + of the mix from the main signal path + */ + result = reverbUnit->setParameterFloat(FMOD_DSP_CONVOLUTION_REVERB_PARAM_DRY, -80.0f); + ERRCHECK(result); + + /* + We can now free our copy of the IR data and release the sound object, the reverb unit + has created it's internal data + */ + free(irData); + result = irSound->release(); + ERRCHECK(result); + + /* + Load up and play a sample clip recorded in an anechoic chamber + */ + FMOD::Sound* sound; + system->createSound(Common_MediaPath("singing.wav"), FMOD_3D | FMOD_LOOP_NORMAL, NULL, &sound); + ERRCHECK(result); + + FMOD::Channel* channel; + system->playSound(sound, mainGroup, true, &channel); + ERRCHECK(result); + + /* + Create a send connection between the channel head and the reverb unit + */ + FMOD::DSP* channelHead; + channel->getDSP(FMOD_CHANNELCONTROL_DSP_HEAD, &channelHead); + ERRCHECK(result); + FMOD::DSPConnection* reverbConnection; + result = reverbUnit->addInput(channelHead, &reverbConnection, FMOD_DSPCONNECTION_TYPE_SEND); + ERRCHECK(result); + + result = channel->setPaused(false); + ERRCHECK(result); + + + float wetVolume = 1.0; + float dryVolume = 1.0; + + /* + Main loop + */ + do + { + Common_Update(); + + if (Common_BtnPress(BTN_LEFT)) + { + wetVolume = (wetVolume <= 0.0f) ? wetVolume : wetVolume - 0.05f; + } + if (Common_BtnPress(BTN_RIGHT)) + { + wetVolume = (wetVolume >= 1.0f) ? wetVolume : wetVolume + 0.05f; + } + if (Common_BtnPress(BTN_DOWN)) + { + dryVolume = (dryVolume <= 0.0f) ? dryVolume : dryVolume - 0.05f; + } + if (Common_BtnPress(BTN_UP)) + { + dryVolume = (dryVolume >= 1.0f) ? dryVolume : dryVolume + 0.05f; + } + + + result = system->update(); + ERRCHECK(result); + + result = reverbConnection->setMix(wetVolume); + ERRCHECK(result); + result = mainGroup->setVolume(dryVolume); + ERRCHECK(result); + + + Common_Draw("=================================================="); + Common_Draw("Convolution Example."); + Common_Draw("Copyright (c) Firelight Technologies 2004-2026."); + Common_Draw("=================================================="); + Common_Draw("Press %s and %s to change dry mix", Common_BtnStr(BTN_UP), Common_BtnStr(BTN_DOWN)); + Common_Draw("Press %s and %s to change wet mix", Common_BtnStr(BTN_LEFT), Common_BtnStr(BTN_RIGHT)); + Common_Draw("wet mix [%.2f] dry mix [%.2f]", wetVolume, dryVolume); + Common_Draw("Press %s to quit", Common_BtnStr(BTN_QUIT)); + Common_Draw(""); + + Common_Sleep(50); + } while (!Common_BtnPress(BTN_QUIT)); + + /* + Shut down + */ + result = sound->release(); + ERRCHECK(result); + result = mainGroup->release(); + ERRCHECK(result); + result = reverbGroup->removeDSP(reverbUnit); + ERRCHECK(result); + result = reverbUnit->disconnectAll(true, true); + ERRCHECK(result); + result = reverbUnit->release(); + ERRCHECK(result); + result = reverbGroup->release(); + ERRCHECK(result); + result = system->close(); + ERRCHECK(result); + result = system->release(); + ERRCHECK(result); + + Common_Close(); + + return 0; +} diff --git a/FMOD/api/core/examples/dsp_custom.cpp b/FMOD/api/core/examples/dsp_custom.cpp new file mode 100644 index 0000000..3a17bff --- /dev/null +++ b/FMOD/api/core/examples/dsp_custom.cpp @@ -0,0 +1,362 @@ +/*============================================================================== +Custom DSP Example +Copyright (c), Firelight Technologies Pty, Ltd 2004-2026. + +This example shows how to add a user created DSP callback to process audio +data. The read callback is executed at runtime, and can be added anywhere in +the DSP network. + +For information on using FMOD example code in your own programs, visit +https://www.fmod.com/legal +==============================================================================*/ +#include "fmod.hpp" +#include "common.h" + +typedef struct +{ + float *buffer; + float volume_linear; + int length_samples; + int channels; +} mydsp_data_t; + +FMOD_RESULT F_CALL myDSPCallback(FMOD_DSP_STATE *dsp_state, float *inbuffer, float *outbuffer, unsigned int length, int inchannels, int *outchannels) +{ + mydsp_data_t *data = (mydsp_data_t *)dsp_state->plugindata; + + /* + This loop assumes inchannels = outchannels, which it will be if the DSP is created with '0' + as the number of channels in FMOD_DSP_DESCRIPTION. + Specifying an actual channel count will mean you have to take care of any number of channels coming in, + but outputting the number of channels specified. Generally it is best to keep the channel + count at 0 for maximum compatibility. + */ + for (unsigned int samp = 0; samp < length; samp++) + { + /* + Feel free to unroll this. + */ + for (int chan = 0; chan < *outchannels; chan++) + { + /* + This DSP filter just halves the volume! + Input is modified, and sent to output. + */ + data->buffer[(samp * *outchannels) + chan] = outbuffer[(samp * inchannels) + chan] = inbuffer[(samp * inchannels) + chan] * data->volume_linear; + } + } + + data->channels = inchannels; + + return FMOD_OK; +} + +/* + Callback called when DSP is created. This implementation creates a structure which is attached to the dsp state's 'plugindata' member. +*/ +FMOD_RESULT F_CALL myDSPCreateCallback(FMOD_DSP_STATE *dsp_state) +{ + unsigned int blocksize; + FMOD_RESULT result; + + result = dsp_state->functions->getblocksize(dsp_state, &blocksize); + ERRCHECK(result); + + mydsp_data_t *data = (mydsp_data_t *)calloc(sizeof(mydsp_data_t), 1); + if (!data) + { + return FMOD_ERR_MEMORY; + } + dsp_state->plugindata = data; + data->volume_linear = 1.0f; + data->length_samples = blocksize; + + data->buffer = (float *)malloc(blocksize * 8 * sizeof(float)); // *8 = maximum size allowing room for 7.1. Could ask dsp_state->functions->getspeakermode for the right speakermode to get real speaker count. + if (!data->buffer) + { + return FMOD_ERR_MEMORY; + } + + return FMOD_OK; +} + +/* + Callback called when DSP is destroyed. The memory allocated in the create callback can be freed here. +*/ +FMOD_RESULT F_CALL myDSPReleaseCallback(FMOD_DSP_STATE *dsp_state) +{ + if (dsp_state->plugindata) + { + mydsp_data_t *data = (mydsp_data_t *)dsp_state->plugindata; + + if (data->buffer) + { + free(data->buffer); + } + + free(data); + } + + return FMOD_OK; +} + +/* + Callback called when DSP::getParameterData is called. This returns a pointer to the raw floating point PCM data. + We have set up 'parameter 0' to be the data parameter, so it checks to make sure the passed in index is 0, and nothing else. +*/ +FMOD_RESULT F_CALL myDSPGetParameterDataCallback(FMOD_DSP_STATE *dsp_state, int index, void **data, unsigned int *length, char *) +{ + if (index == 0) + { + unsigned int blocksize; + FMOD_RESULT result; + mydsp_data_t *mydata = (mydsp_data_t *)dsp_state->plugindata; + + result = dsp_state->functions->getblocksize(dsp_state, &blocksize); + ERRCHECK(result); + + *data = (void *)mydata; + *length = blocksize * 2 * sizeof(float); + + return FMOD_OK; + } + + return FMOD_ERR_INVALID_PARAM; +} + +/* + Callback called when DSP::setParameterFloat is called. This accepts a floating point 0 to 1 volume value, and stores it. + We have set up 'parameter 1' to be the volume parameter, so it checks to make sure the passed in index is 1, and nothing else. +*/ +FMOD_RESULT F_CALL myDSPSetParameterFloatCallback(FMOD_DSP_STATE *dsp_state, int index, float value) +{ + if (index == 1) + { + mydsp_data_t *mydata = (mydsp_data_t *)dsp_state->plugindata; + + mydata->volume_linear = value; + + return FMOD_OK; + } + + return FMOD_ERR_INVALID_PARAM; +} + +/* + Callback called when DSP::getParameterFloat is called. This returns a floating point 0 to 1 volume value. + We have set up 'parameter 1' to be the volume parameter, so it checks to make sure the passed in index is 1, and nothing else. + An alternate way of displaying the data is provided, as a string, so the main app can use it. +*/ +FMOD_RESULT F_CALL myDSPGetParameterFloatCallback(FMOD_DSP_STATE *dsp_state, int index, float *value, char *valstr) +{ + if (index == 1) + { + mydsp_data_t *mydata = (mydsp_data_t *)dsp_state->plugindata; + + *value = mydata->volume_linear; + if (valstr) + { + snprintf(valstr, FMOD_DSP_GETPARAM_VALUESTR_LENGTH, "%d", (int)((*value * 100.0f)+0.5f)); + } + + return FMOD_OK; + } + + return FMOD_ERR_INVALID_PARAM; +} + +int FMOD_Main() +{ + FMOD::System *system; + FMOD::Sound *sound; + FMOD::Channel *channel; + FMOD::DSP *mydsp; + FMOD::ChannelGroup *mastergroup; + FMOD_RESULT result; + void *extradriverdata = 0; + + Common_Init(&extradriverdata); + + /* + Create a System object and initialize. + */ + result = FMOD::System_Create(&system); + ERRCHECK(result); + + result = system->init(32, FMOD_INIT_NORMAL, extradriverdata); + ERRCHECK(result); + + result = system->createSound(Common_MediaPath("stereo.ogg"), FMOD_LOOP_NORMAL, 0, &sound); + ERRCHECK(result); + + result = system->playSound(sound, 0, false, &channel); + ERRCHECK(result); + + /* + Create the DSP effect. + */ + { + FMOD_DSP_DESCRIPTION dspdesc; + memset(&dspdesc, 0, sizeof(dspdesc)); + FMOD_DSP_PARAMETER_DESC wavedata_desc; + FMOD_DSP_PARAMETER_DESC volume_desc; + FMOD_DSP_PARAMETER_DESC *paramdesc[2] = + { + &wavedata_desc, + &volume_desc + }; + + FMOD_DSP_INIT_PARAMDESC_DATA(wavedata_desc, "wave data", "", "wave data", FMOD_DSP_PARAMETER_DATA_TYPE_USER); + FMOD_DSP_INIT_PARAMDESC_FLOAT(volume_desc, "volume", "%", "linear volume in percent", 0, 1, 1); + + strncpy(dspdesc.name, "My first DSP unit", sizeof(dspdesc.name)); + dspdesc.version = 0x00010000; + dspdesc.numinputbuffers = 1; + dspdesc.numoutputbuffers = 1; + dspdesc.read = myDSPCallback; + dspdesc.create = myDSPCreateCallback; + dspdesc.release = myDSPReleaseCallback; + dspdesc.getparameterdata = myDSPGetParameterDataCallback; + dspdesc.setparameterfloat = myDSPSetParameterFloatCallback; + dspdesc.getparameterfloat = myDSPGetParameterFloatCallback; + dspdesc.numparameters = 2; + dspdesc.paramdesc = paramdesc; + + result = system->createDSP(&dspdesc, &mydsp); + ERRCHECK(result); + } + + result = system->getMasterChannelGroup(&mastergroup); + ERRCHECK(result); + + result = mastergroup->addDSP(0, mydsp); + ERRCHECK(result); + + /* + Main loop. + */ + do + { + bool bypass; + + Common_Update(); + + result = mydsp->getBypass(&bypass); + ERRCHECK(result); + + if (Common_BtnPress(BTN_ACTION1)) + { + bypass = !bypass; + + result = mydsp->setBypass(bypass); + ERRCHECK(result); + } + if (Common_BtnPress(BTN_ACTION2)) + { + float vol; + + result = mydsp->getParameterFloat(1, &vol, 0, 0); + ERRCHECK(result); + + if (vol > 0.0f) + { + vol -= 0.1f; + } + + result = mydsp->setParameterFloat(1, vol); + ERRCHECK(result); + } + if (Common_BtnPress(BTN_ACTION3)) + { + float vol; + + result = mydsp->getParameterFloat(1, &vol, 0, 0); + ERRCHECK(result); + + if (vol < 1.0f) + { + vol += 0.1f; + } + + result = mydsp->setParameterFloat(1, vol); + ERRCHECK(result); + } + + result = system->update(); + ERRCHECK(result); + + { + char volstr[32] = { 0 }; + FMOD_DSP_PARAMETER_DESC *desc; + mydsp_data_t *data; + + result = mydsp->getParameterInfo(1, &desc); + ERRCHECK(result); + result = mydsp->getParameterFloat(1, 0, volstr, 32); + ERRCHECK(result); + result = mydsp->getParameterData(0, (void **)&data, 0, 0, 0); + ERRCHECK(result); + + Common_Draw("=================================================="); + Common_Draw("Custom DSP Example."); + Common_Draw("Copyright (c) Firelight Technologies 2004-2026."); + Common_Draw("=================================================="); + Common_Draw(""); + Common_Draw("Press %s to toggle filter bypass", Common_BtnStr(BTN_ACTION1)); + Common_Draw("Press %s to decrease volume 10%%", Common_BtnStr(BTN_ACTION2)); + Common_Draw("Press %s to increase volume 10%%", Common_BtnStr(BTN_ACTION3)); + Common_Draw("Press %s to quit", Common_BtnStr(BTN_QUIT)); + Common_Draw(""); + Common_Draw("Filter is %s", bypass ? "inactive" : "active"); + Common_Draw("Volume is %s%s", volstr, desc->label); + + if (data->channels) + { + char display[80] = { 0 }; + int channel; + + for (channel = 0; channel < data->channels; channel++) + { + int count,level; + float max = 0; + + for (count = 0; count < data->length_samples; count++) + { + if (fabsf(data->buffer[(count * data->channels) + channel]) > max) + { + max = fabsf(data->buffer[(count * data->channels) + channel]); + } + } + level = (int)(max * 40.0f); + + snprintf(display, sizeof(display), "%2d ", channel); + for (count = 0; count < level; count++) display[count + 3] = '='; + + Common_Draw(display); + } + } + } + + Common_Sleep(50); + } while (!Common_BtnPress(BTN_QUIT)); + + /* + Shut down + */ + result = sound->release(); + ERRCHECK(result); + + result = mastergroup->removeDSP(mydsp); + ERRCHECK(result); + result = mydsp->release(); + ERRCHECK(result); + + result = system->close(); + ERRCHECK(result); + result = system->release(); + ERRCHECK(result); + + Common_Close(); + + return 0; +} diff --git a/FMOD/api/core/examples/dsp_effect_per_speaker.cpp b/FMOD/api/core/examples/dsp_effect_per_speaker.cpp new file mode 100644 index 0000000..96e4d73 --- /dev/null +++ b/FMOD/api/core/examples/dsp_effect_per_speaker.cpp @@ -0,0 +1,276 @@ +/*============================================================================== +DSP Effect Per Speaker Example +Copyright (c), Firelight Technologies Pty, Ltd 2004-2026. + +This example shows how to manipulate a DSP network and as an example, creates 2 +DSP effects, splitting a single sound into 2 audio paths, which it then filters +seperately. + +To only have each audio path come out of one speaker each, +DSPConnection::setMixMatrix is used just before the 2 branches merge back together +again. + +For more speakers: + + * Use System::setSoftwareFormat + * Create more effects, currently 2 for stereo (lowpass and highpass), create one + per speaker. + * Under the 'Now connect the 2 effects to channeldsp head.' section, connect + the extra effects by duplicating the code more times. + * Filter each effect to each speaker by calling DSPConnection::setMixMatrix. + Expand the existing code by extending the matrices from 2 in and 2 out, to the + number of speakers you require. + +For information on using FMOD example code in your own programs, visit +https://www.fmod.com/legal +==============================================================================*/ +#include "fmod.hpp" +#include "common.h" + +int FMOD_Main() +{ + FMOD::System *system; + FMOD::Sound *sound; + FMOD::Channel *channel; + FMOD::ChannelGroup *mastergroup; + FMOD::DSP *dsplowpass, *dsphighpass, *dsphead, *dspchannelmixer; + FMOD::DSPConnection *dsplowpassconnection, *dsphighpassconnection; + FMOD_RESULT result; + float pan = 0.0f; + void *extradriverdata = 0; + + Common_Init(&extradriverdata); + + /* + Create a System object and initialize. + */ + result = FMOD::System_Create(&system); + ERRCHECK(result); + + /* + In this special case we want to use stereo output and not worry about varying matrix sizes depending on user speaker mode. + */ + system->setSoftwareFormat(48000, FMOD_SPEAKERMODE_STEREO, 0); + ERRCHECK(result); + + /* + Initialize FMOD + */ + result = system->init(32, FMOD_INIT_NORMAL, extradriverdata); + ERRCHECK(result); + + result = system->createSound(Common_MediaPath("drumloop.wav"), FMOD_LOOP_NORMAL, 0, &sound); + ERRCHECK(result); + + result = system->playSound(sound, 0, false, &channel); + ERRCHECK(result); + + /* + Create the DSP effects. + */ + result = system->createDSPByType(FMOD_DSP_TYPE_LOWPASS, &dsplowpass); + ERRCHECK(result); + + result = dsplowpass->setParameterFloat(FMOD_DSP_LOWPASS_CUTOFF, 1000.0f); + ERRCHECK(result); + result = dsplowpass->setParameterFloat(FMOD_DSP_LOWPASS_RESONANCE, 4.0f); + ERRCHECK(result); + + result = system->createDSPByType(FMOD_DSP_TYPE_HIGHPASS, &dsphighpass); + ERRCHECK(result); + + result = dsphighpass->setParameterFloat(FMOD_DSP_HIGHPASS_CUTOFF, 4000.0f); + ERRCHECK(result); + result = dsphighpass->setParameterFloat(FMOD_DSP_HIGHPASS_RESONANCE, 4.0f); + ERRCHECK(result); + + /* + Connect up the DSP network + */ + + /* + When a sound is played, a subnetwork is set up in the DSP network which looks like this. + Wavetable is the drumloop sound, and it feeds its data from right to left. + + [DSPHEAD]<------------[DSPCHANNELMIXER]<------------[CHANNEL HEAD]<------------[WAVETABLE - DRUMLOOP.WAV] + */ + result = system->getMasterChannelGroup(&mastergroup); + ERRCHECK(result); + + result = mastergroup->getDSP(FMOD_CHANNELCONTROL_DSP_HEAD, &dsphead); + ERRCHECK(result); + + result = dsphead->getInput(0, &dspchannelmixer, 0); + ERRCHECK(result); + + /* + Now disconnect channeldsp head from wavetable to look like this. + + [DSPHEAD] [DSPCHANNELMIXER]<------------[CHANNEL HEAD]<------------[WAVETABLE - DRUMLOOP.WAV] + */ + result = dsphead->disconnectFrom(dspchannelmixer); + ERRCHECK(result); + + /* + Now connect the 2 effects to channeldsp head. + Store the 2 connections this makes so we can set their matrix later. + + [DSPLOWPASS] + /x + [DSPHEAD] [DSPCHANNELMIXER]<------------[CHANNEL HEAD]<------------[WAVETABLE - DRUMLOOP.WAV] + \y + [DSPHIGHPASS] + */ + result = dsphead->addInput(dsplowpass, &dsplowpassconnection); /* x = dsplowpassconnection */ + ERRCHECK(result); + result = dsphead->addInput(dsphighpass, &dsphighpassconnection); /* y = dsphighpassconnection */ + ERRCHECK(result); + + /* + Now connect the channelmixer to the 2 effects + + [DSPLOWPASS] + /x \ + [DSPHEAD] [DSPCHANNELMIXER]<------------[CHANNEL HEAD]<------------[WAVETABLE - DRUMLOOP.WAV] + \y / + [DSPHIGHPASS] + */ + result = dsplowpass->addInput(dspchannelmixer); /* Ignore connection - we dont care about it. */ + ERRCHECK(result); + + result = dsphighpass->addInput(dspchannelmixer); /* Ignore connection - we dont care about it. */ + ERRCHECK(result); + + /* + Now the drumloop will be twice as loud, because it is being split into 2, then recombined at the end. + What we really want is to only feed the dsphead<-dsplowpass through the left speaker for that effect, and + dsphead<-dsphighpass to the right speaker for that effect. + We can do that simply by setting the pan, or speaker matrix of the connections. + + [DSPLOWPASS] + /x=1,0 \ + [DSPHEAD] [DSPCHANNELMIXER]<------------[CHANNEL HEAD]<------------[WAVETABLE - DRUMLOOP.WAV] + \y=0,1 / + [DSPHIGHPASS] + */ + { + float lowpassmatrix[2][2] = { + { 1.0f, 0.0f }, // <- output to front left. Take front left input signal at 1.0. + { 0.0f, 0.0f } // <- output to front right. Silence + }; + float highpassmatrix[2][2] = { + { 0.0f, 0.0f }, // <- output to front left. Silence + { 0.0f, 1.0f } // <- output to front right. Take front right input signal at 1.0 + }; + + /* + Upgrade the signal coming from the channel mixer from mono to stereo. Otherwise the lowpass and highpass will get mono signals + */ + result = dspchannelmixer->setChannelFormat(0, 0, FMOD_SPEAKERMODE_STEREO); + ERRCHECK(result); + + /* + Now set the above matrices. + */ + result = dsplowpassconnection->setMixMatrix(&lowpassmatrix[0][0], 2, 2); + ERRCHECK(result); + result = dsphighpassconnection->setMixMatrix(&highpassmatrix[0][0], 2, 2); + ERRCHECK(result); + } + + result = dsplowpass->setBypass(true); + ERRCHECK(result); + result = dsphighpass->setBypass(true); + ERRCHECK(result); + + result = dsplowpass->setActive(true); + ERRCHECK(result); + result = dsphighpass->setActive(true); + ERRCHECK(result); + + /* + Main loop. + */ + do + { + bool lowpassbypass, highpassbypass; + + Common_Update(); + + result = dsplowpass->getBypass(&lowpassbypass); + ERRCHECK(result); + result = dsphighpass->getBypass(&highpassbypass); + ERRCHECK(result); + + if (Common_BtnPress(BTN_ACTION1)) + { + lowpassbypass = !lowpassbypass; + + result = dsplowpass->setBypass(lowpassbypass); + ERRCHECK(result); + } + + if (Common_BtnPress(BTN_ACTION2)) + { + highpassbypass = !highpassbypass; + + result = dsphighpass->setBypass(highpassbypass); + ERRCHECK(result); + } + + if (Common_BtnDown(BTN_LEFT)) + { + pan = (pan <= -0.9f) ? -1.0f : pan - 0.1f; + + result = channel->setPan(pan); + ERRCHECK(result); + } + + if (Common_BtnDown(BTN_RIGHT)) + { + pan = (pan >= 0.9f) ? 1.0f : pan + 0.1f; + + result = channel->setPan(pan); + ERRCHECK(result); + } + + result = system->update(); + ERRCHECK(result); + + Common_Draw("=================================================="); + Common_Draw("DSP Effect Per Speaker Example."); + Common_Draw("Copyright (c) Firelight Technologies 2004-2026."); + Common_Draw("=================================================="); + Common_Draw(""); + Common_Draw("Press %s to toggle lowpass (left speaker)", Common_BtnStr(BTN_ACTION1)); + Common_Draw("Press %s to toggle highpass (right speaker)", Common_BtnStr(BTN_ACTION2)); + Common_Draw("Press %s or %s to pan sound", Common_BtnStr(BTN_LEFT), Common_BtnStr(BTN_RIGHT)); + Common_Draw("Press %s to quit", Common_BtnStr(BTN_QUIT)); + Common_Draw(""); + Common_Draw("Lowpass (left) is %s", lowpassbypass ? "inactive" : "active"); + Common_Draw("Highpass (right) is %s", highpassbypass ? "inactive" : "active"); + Common_Draw("Pan is %0.2f", pan); + + Common_Sleep(50); + } while (!Common_BtnPress(BTN_QUIT)); + + /* + Shut down + */ + result = sound->release(); + ERRCHECK(result); + + result = dsplowpass->release(); + ERRCHECK(result); + result = dsphighpass->release(); + ERRCHECK(result); + + result = system->close(); + ERRCHECK(result); + result = system->release(); + ERRCHECK(result); + + Common_Close(); + + return 0; +} diff --git a/FMOD/api/core/examples/dsp_inspector.cpp b/FMOD/api/core/examples/dsp_inspector.cpp new file mode 100644 index 0000000..6701438 --- /dev/null +++ b/FMOD/api/core/examples/dsp_inspector.cpp @@ -0,0 +1,331 @@ +/*============================================================================== +Plug-in Inspector Example +Copyright (c), Firelight Technologies Pty, Ltd 2004-2026. + +This example shows how to enumerate loaded plug-ins and their parameters. + +For information on using FMOD example code in your own programs, visit +https://www.fmod.com/legal +==============================================================================*/ +#include "fmod.hpp" +#include "common.h" + +const int INTERFACE_UPDATETIME = 50; // 50ms update for interface +const int MAX_PLUGINS_IN_VIEW = 5; +const int MAX_PARAMETERS_IN_VIEW = 14; + +enum InspectorState +{ + PLUGIN_SELECTOR, + PARAMETER_VIEWER +}; + +struct PluginSelectorState +{ + FMOD::System *system; + int numplugins; + int cursor; +}; + +struct ParameterViewerState +{ + FMOD::DSP *dsp; + int numparams; + int scroll; +}; + +void drawTitle() +{ + Common_Draw("=================================================="); + Common_Draw("Plug-in Inspector Example."); + Common_Draw("Copyright (c) Firelight Technologies 2004-2026."); + Common_Draw("=================================================="); + Common_Draw(""); +} + +bool hasDataParameter(const FMOD_DSP_DESCRIPTION *desc, FMOD_DSP_PARAMETER_DATA_TYPE type) +{ + for (int i = 0; i < desc->numparameters; i++) + { + if (desc->paramdesc[i]->type == FMOD_DSP_PARAMETER_TYPE_DATA && ((type >= 0 && desc->paramdesc[i]->datadesc.datatype >= 0) || desc->paramdesc[i]->datadesc.datatype == type)) + { + return true; + } + } + + return false; +} + +void drawDSPInfo(const FMOD_DSP_DESCRIPTION *desc) +{ + Common_Draw("Name (Version) : %s (%x)", desc->name, desc->version); + Common_Draw("SDK Version : %d", desc->pluginsdkversion); + Common_Draw("Type : %s", desc->numinputbuffers ? "Effect" : "Sound Generator"); + Common_Draw("Parameters : %d", desc->numparameters); + Common_Draw("Audio Callback : %s", desc->process ? "process()" : "read()"); + Common_Draw(""); + Common_Draw(" Reset | Side-Chain | 3D | Audibility | User Data"); + Common_Draw(" %s | %s | %s | %s | %s ", + desc->reset ? "Y " : "--", + hasDataParameter(desc, FMOD_DSP_PARAMETER_DATA_TYPE_SIDECHAIN) ? "Y " : "--", + hasDataParameter(desc, FMOD_DSP_PARAMETER_DATA_TYPE_3DATTRIBUTES) || hasDataParameter(desc, FMOD_DSP_PARAMETER_DATA_TYPE_3DATTRIBUTES_MULTI) ? "Y " : "--", + hasDataParameter(desc, FMOD_DSP_PARAMETER_DATA_TYPE_OVERALLGAIN) ? "Y " : "--", + hasDataParameter(desc, FMOD_DSP_PARAMETER_DATA_TYPE_USER) || desc->userdata ? "Y " : "--"); +} + +void drawDSPList(PluginSelectorState *state) +{ + unsigned int pluginhandle; + char pluginname[256]; + FMOD_RESULT result; + + Common_Draw("Press %s to select the next plug-in", Common_BtnStr(BTN_DOWN)); + Common_Draw("Press %s to select the previous plug-in", Common_BtnStr(BTN_UP)); + Common_Draw("Press %s to view the plug-in parameters", Common_BtnStr(BTN_RIGHT)); + Common_Draw(""); + + int start = Common_Clamp(0, state->cursor - (MAX_PLUGINS_IN_VIEW - 1) / 2, state->numplugins - MAX_PLUGINS_IN_VIEW); + for (int i = start; i < start + MAX_PLUGINS_IN_VIEW; i++) + { + result = state->system->getPluginHandle(FMOD_PLUGINTYPE_DSP, i, &pluginhandle); + ERRCHECK(result); + + result = state->system->getPluginInfo(pluginhandle, 0, pluginname, 256, 0); + ERRCHECK(result); + + Common_Draw("%s %s", i == state->cursor ? ">" : " ", pluginname); + } + + Common_Draw(""); + Common_Draw("=================================================="); + Common_Draw(""); + + result = state->system->getPluginHandle(FMOD_PLUGINTYPE_DSP, state->cursor, &pluginhandle); + ERRCHECK(result); + + const FMOD_DSP_DESCRIPTION *description; + result = state->system->getDSPInfoByPlugin(pluginhandle, &description); + ERRCHECK(result); + + drawDSPInfo(description); +} + +void drawDSPParameters(ParameterViewerState *state) +{ + FMOD_RESULT result; + FMOD_DSP_PARAMETER_DESC *paramdesc; + char pluginname[256]; + + Common_Draw("Press %s to scroll down", Common_BtnStr(BTN_DOWN)); + Common_Draw("Press %s to scroll up", Common_BtnStr(BTN_UP)); + Common_Draw("Press %s to return to the plug-in list", Common_BtnStr(BTN_LEFT)); + Common_Draw(""); + + result = state->dsp->getInfo(pluginname, 0, 0, 0, 0); + ERRCHECK(result); + + Common_Draw("%s Parameters:", pluginname); + Common_Draw("--------------------------------------------------"); + + for (int i = state->scroll; i < state->numparams; i++) + { + result = state->dsp->getParameterInfo(i, ¶mdesc); + ERRCHECK(result); + switch (paramdesc->type) + { + case FMOD_DSP_PARAMETER_TYPE_FLOAT: + { + char *units = paramdesc->label; + Common_Draw("%2d: %-15s [%g, %g] (%.2f%s)", i, paramdesc->name, paramdesc->floatdesc.min, paramdesc->floatdesc.max, paramdesc->floatdesc.defaultval, units); + break; + } + + case FMOD_DSP_PARAMETER_TYPE_INT: + { + if (paramdesc->intdesc.valuenames) + { + int lengthremaining = 1024; + char enums[1024]; + char *s = enums; + for (int j = 0; j < paramdesc->intdesc.max - paramdesc->intdesc.min; ++j) + { + int len = Common_snprintf(s, lengthremaining, "%s, ", paramdesc->intdesc.valuenames[j]); + if (!len) + { + break; + } + s += len; + lengthremaining -= len; + } + if (lengthremaining) + { + Common_snprintf(s, lengthremaining, "%s", paramdesc->intdesc.valuenames[paramdesc->intdesc.max - paramdesc->intdesc.min]); + } + Common_Draw("%2d: %-15s [%s] (%s)", i, paramdesc->name, enums, paramdesc->intdesc.valuenames[paramdesc->intdesc.defaultval - paramdesc->intdesc.min]); + } + else + { + char *units = paramdesc->label; + Common_Draw("%2d: %-15s [%d, %d] (%d%s)", i, paramdesc->name, paramdesc->intdesc.min, paramdesc->intdesc.max, paramdesc->intdesc.defaultval, units); + } + break; + } + + case FMOD_DSP_PARAMETER_TYPE_BOOL: + { + if (paramdesc->booldesc.valuenames) + { + Common_Draw("%2d: %-15s [%s, %s] (%s)", i, paramdesc->name, paramdesc->booldesc.valuenames[0], paramdesc->booldesc.valuenames[1], paramdesc->booldesc.valuenames[paramdesc->booldesc.defaultval ? 1 : 0]); + } + else + { + Common_Draw("%2d: %-15s [On, Off] (%s)", i, paramdesc->name, paramdesc->booldesc.defaultval ? "On" : "Off"); + } + break; + } + + case FMOD_DSP_PARAMETER_TYPE_DATA: + { + Common_Draw("%2d: %-15s (Data type: %d)", i, paramdesc->name, paramdesc->datadesc.datatype); + break; + } + + default: + break; + } + } +} + +InspectorState pluginSelectorDo(PluginSelectorState *state) +{ + if (Common_BtnPress(BTN_UP)) + { + state->cursor = (state->cursor - 1 + state->numplugins) % state->numplugins; + } + + if (Common_BtnPress(BTN_DOWN)) + { + state->cursor = (state->cursor + 1) % state->numplugins; + } + + if (Common_BtnPress(BTN_RIGHT)) + { + return PARAMETER_VIEWER; + } + + drawTitle(); + drawDSPList(state); + + return PLUGIN_SELECTOR; +} + +InspectorState parameterViewerDo(ParameterViewerState *state) +{ + if (state->numparams > MAX_PARAMETERS_IN_VIEW) + { + if (Common_BtnPress(BTN_UP)) + { + state->scroll--; + state->scroll = Common_Max(state->scroll, 0); + } + + if (Common_BtnPress(BTN_DOWN)) + { + state->scroll++; + state->scroll = Common_Min(state->scroll, state->numparams - MAX_PARAMETERS_IN_VIEW); + } + } + + if (Common_BtnPress(BTN_LEFT)) + { + return PLUGIN_SELECTOR; + } + + drawTitle(); + drawDSPParameters(state); + + return PARAMETER_VIEWER; +} + +int FMOD_Main() +{ + FMOD::System *system = 0; + FMOD_RESULT result; + void *extradriverdata = 0; + unsigned int pluginhandle; + InspectorState state = PLUGIN_SELECTOR; + PluginSelectorState pluginselector = { 0 }; + ParameterViewerState parameterviewer = { 0 }; + + Common_Init(&extradriverdata); + + /* + Create a System object and initialize + */ + result = FMOD::System_Create(&system); + ERRCHECK(result); + + result = system->init(32, FMOD_INIT_NORMAL, extradriverdata); + ERRCHECK(result); + + result = system->getNumPlugins(FMOD_PLUGINTYPE_DSP, &pluginselector.numplugins); + ERRCHECK(result); + + pluginselector.system = system; + + do + { + Common_Update(); + + if (state == PLUGIN_SELECTOR) + { + state = pluginSelectorDo(&pluginselector); + + if (state == PARAMETER_VIEWER) + { + result = pluginselector.system->getPluginHandle(FMOD_PLUGINTYPE_DSP, pluginselector.cursor, &pluginhandle); + ERRCHECK(result); + + result = pluginselector.system->createDSPByPlugin(pluginhandle, ¶meterviewer.dsp); + ERRCHECK(result); + + FMOD_RESULT result = parameterviewer.dsp->getNumParameters(¶meterviewer.numparams); + ERRCHECK(result); + + parameterviewer.scroll = 0; + } + } + else if (state == PARAMETER_VIEWER) + { + state = parameterViewerDo(¶meterviewer); + + if (state == PLUGIN_SELECTOR) + { + result = parameterviewer.dsp->release(); + ERRCHECK(result); + + parameterviewer.dsp = 0; + } + } + + result = system->update(); + ERRCHECK(result); + + Common_Sleep(INTERFACE_UPDATETIME - 1); + } while (!Common_BtnPress(BTN_QUIT)); + + if (parameterviewer.dsp) + { + result = parameterviewer.dsp->release(); + ERRCHECK(result); + } + + result = system->close(); + ERRCHECK(result); + result = system->release(); + ERRCHECK(result); + + Common_Close(); + + return 0; +} diff --git a/FMOD/api/core/examples/effects.cpp b/FMOD/api/core/examples/effects.cpp new file mode 100644 index 0000000..6bf3bb2 --- /dev/null +++ b/FMOD/api/core/examples/effects.cpp @@ -0,0 +1,237 @@ +/*============================================================================== +Effects Example +Copyright (c), Firelight Technologies Pty, Ltd 2004-2026. + +This example shows how to apply some of the built in software effects to sounds +by applying them to the master channel group. All software sounds played here +would be filtered in the same way. To filter per channel, and not have other +channels affected, simply apply the same functions to the FMOD::Channel instead +of the FMOD::ChannelGroup. + +For information on using FMOD example code in your own programs, visit +https://www.fmod.com/legal +==============================================================================*/ +#include "fmod.hpp" +#include "common.h" + +int FMOD_Main() +{ + FMOD::System *system = 0; + FMOD::Sound *sound = 0; + FMOD::Channel *channel = 0; + FMOD::ChannelGroup *mastergroup = 0; + FMOD::DSP *dsplowpass = 0; + FMOD::DSP *dsphighpass = 0; + FMOD::DSP *dspecho = 0; + FMOD::DSP *dspflange = 0; + FMOD_RESULT result; + void *extradriverdata = 0; + + Common_Init(&extradriverdata); + + /* + Create a System object and initialize + */ + result = FMOD::System_Create(&system); + ERRCHECK(result); + + result = system->init(32, FMOD_INIT_NORMAL, extradriverdata); + ERRCHECK(result); + + result = system->getMasterChannelGroup(&mastergroup); + ERRCHECK(result); + + result = system->createSound(Common_MediaPath("drumloop.wav"), FMOD_DEFAULT, 0, &sound); + ERRCHECK(result); + + result = system->playSound(sound, 0, false, &channel); + ERRCHECK(result); + + /* + Create some effects to play with + */ + result = system->createDSPByType(FMOD_DSP_TYPE_LOWPASS, &dsplowpass); + ERRCHECK(result); + result = system->createDSPByType(FMOD_DSP_TYPE_HIGHPASS, &dsphighpass); + ERRCHECK(result); + result = system->createDSPByType(FMOD_DSP_TYPE_ECHO, &dspecho); + ERRCHECK(result); + result = system->createDSPByType(FMOD_DSP_TYPE_FLANGE, &dspflange); + ERRCHECK(result); + + /* + Add them to the master channel group. Each time an effect is added (to position 0) it pushes the others down the list. + */ + result = mastergroup->addDSP(0, dsplowpass); + ERRCHECK(result); + result = mastergroup->addDSP(0, dsphighpass); + ERRCHECK(result); + result = mastergroup->addDSP(0, dspecho); + ERRCHECK(result); + result = mastergroup->addDSP(0, dspflange); + ERRCHECK(result); + + /* + By default, bypass all effects. This means let the original signal go through without processing. + It will sound 'dry' until effects are enabled by the user. + */ + result = dsplowpass->setBypass(true); + ERRCHECK(result); + result = dsphighpass->setBypass(true); + ERRCHECK(result); + result = dspecho->setBypass(true); + ERRCHECK(result); + result = dspflange->setBypass(true); + ERRCHECK(result); + + /* + Main loop + */ + do + { + Common_Update(); + + if (Common_BtnPress(BTN_MORE)) + { + bool paused; + + result = channel->getPaused(&paused); + ERRCHECK(result); + + paused = !paused; + + result = channel->setPaused(paused); + ERRCHECK(result); + } + + if (Common_BtnPress(BTN_ACTION1)) + { + bool bypass; + + result = dsplowpass->getBypass(&bypass); + ERRCHECK(result); + + bypass = !bypass; + + result = dsplowpass->setBypass(bypass); + ERRCHECK(result); + } + + if (Common_BtnPress(BTN_ACTION2)) + { + bool bypass; + + result = dsphighpass->getBypass(&bypass); + ERRCHECK(result); + + bypass = !bypass; + + result = dsphighpass->setBypass(bypass); + ERRCHECK(result); + } + + if (Common_BtnPress(BTN_ACTION3)) + { + bool bypass; + + result = dspecho->getBypass(&bypass); + ERRCHECK(result); + + bypass = !bypass; + + result = dspecho->setBypass(bypass); + ERRCHECK(result); + } + + if (Common_BtnPress(BTN_ACTION4)) + { + bool bypass; + + result = dspflange->getBypass(&bypass); + ERRCHECK(result); + + bypass = !bypass; + + result = dspflange->setBypass(bypass); + ERRCHECK(result); + } + + result = system->update(); + ERRCHECK(result); + + { + bool paused = 0; + bool dsplowpass_bypass; + bool dsphighpass_bypass; + bool dspecho_bypass; + bool dspflange_bypass; + + dsplowpass ->getBypass(&dsplowpass_bypass); + dsphighpass ->getBypass(&dsphighpass_bypass); + dspecho ->getBypass(&dspecho_bypass); + dspflange ->getBypass(&dspflange_bypass); + + if (channel) + { + result = channel->getPaused(&paused); + if ((result != FMOD_OK) && (result != FMOD_ERR_INVALID_HANDLE) && (result != FMOD_ERR_CHANNEL_STOLEN)) + { + ERRCHECK(result); + } + } + + Common_Draw("=================================================="); + Common_Draw("Effects Example."); + Common_Draw("Copyright (c) Firelight Technologies 2004-2026."); + Common_Draw("=================================================="); + Common_Draw(""); + Common_Draw("Press %s to pause/unpause sound", Common_BtnStr(BTN_MORE)); + Common_Draw("Press %s to toggle dsplowpass effect", Common_BtnStr(BTN_ACTION1)); + Common_Draw("Press %s to toggle dsphighpass effect", Common_BtnStr(BTN_ACTION2)); + Common_Draw("Press %s to toggle dspecho effect", Common_BtnStr(BTN_ACTION3)); + Common_Draw("Press %s to toggle dspflange effect", Common_BtnStr(BTN_ACTION4)); + Common_Draw("Press %s to quit", Common_BtnStr(BTN_QUIT)); + Common_Draw(""); + Common_Draw("%s : lowpass[%c] highpass[%c] echo[%c] flange[%c]", + paused ? "Paused " : "Playing", + dsplowpass_bypass ? ' ' : 'x', + dsphighpass_bypass ? ' ' : 'x', + dspecho_bypass ? ' ' : 'x', + dspflange_bypass ? ' ' : 'x'); + } + + Common_Sleep(50); + } while (!Common_BtnPress(BTN_QUIT)); + + /* + Shut down + */ + result = mastergroup->removeDSP(dsplowpass); + ERRCHECK(result); + result = mastergroup->removeDSP(dsphighpass); + ERRCHECK(result); + result = mastergroup->removeDSP(dspecho); + ERRCHECK(result); + result = mastergroup->removeDSP(dspflange); + ERRCHECK(result); + + result = dsplowpass->release(); + ERRCHECK(result); + result = dsphighpass->release(); + ERRCHECK(result); + result = dspecho->release(); + ERRCHECK(result); + result = dspflange->release(); + ERRCHECK(result); + + result = sound->release(); + ERRCHECK(result); + result = system->close(); + ERRCHECK(result); + result = system->release(); + ERRCHECK(result); + + Common_Close(); + + return 0; +} diff --git a/FMOD/api/core/examples/gapless_playback.cpp b/FMOD/api/core/examples/gapless_playback.cpp new file mode 100644 index 0000000..bfa098d --- /dev/null +++ b/FMOD/api/core/examples/gapless_playback.cpp @@ -0,0 +1,269 @@ +/*============================================================================== +Gapless Playback Example +Copyright (c), Firelight Technologies Pty, Ltd 2004-2026. + +This example shows how to schedule channel playback into the future with sample +accuracy. Use several scheduled channels to synchronize 2 or more sounds. + +For information on using FMOD example code in your own programs, visit +https://www.fmod.com/legal +==============================================================================*/ +#include "fmod.hpp" +#include "common.h" + +enum NOTE +{ + NOTE_C, + NOTE_D, + NOTE_E, +}; + +NOTE note[] = +{ + NOTE_E, /* Ma- */ + NOTE_D, /* ry */ + NOTE_C, /* had */ + NOTE_D, /* a */ + NOTE_E, /* lit- */ + NOTE_E, /* tle */ + NOTE_E, /* lamb, */ + NOTE_E, /* ..... */ + NOTE_D, /* lit- */ + NOTE_D, /* tle */ + NOTE_D, /* lamb, */ + NOTE_D, /* ..... */ + NOTE_E, /* lit- */ + NOTE_E, /* tle */ + NOTE_E, /* lamb, */ + NOTE_E, /* ..... */ + + NOTE_E, /* Ma- */ + NOTE_D, /* ry */ + NOTE_C, /* had */ + NOTE_D, /* a */ + NOTE_E, /* lit- */ + NOTE_E, /* tle */ + NOTE_E, /* lamb, */ + NOTE_E, /* its */ + NOTE_D, /* fleece */ + NOTE_D, /* was */ + NOTE_E, /* white */ + NOTE_D, /* as */ + NOTE_C, /* snow. */ + NOTE_C, /* ..... */ + NOTE_C, /* ..... */ + NOTE_C, /* ..... */ +}; + +int FMOD_Main() +{ + FMOD::System *system; + FMOD::Sound *sound[3]; + FMOD::Channel *channel = 0; + FMOD::ChannelGroup *channelgroup = 0; + FMOD_RESULT result; + unsigned int dsp_block_len, count; + int outputrate = 0; + void *extradriverdata = 0; + + Common_Init(&extradriverdata); + + /* + Create a System object and initialize. + */ + result = FMOD::System_Create(&system); + ERRCHECK(result); + + result = system->init(100, FMOD_INIT_NORMAL, extradriverdata); + ERRCHECK(result); + + /* + Get information needed later for scheduling. The mixer block size, and the output rate of the mixer. + */ + result = system->getDSPBufferSize(&dsp_block_len, 0); + ERRCHECK(result); + + result = system->getSoftwareFormat(&outputrate, 0, 0); + ERRCHECK(result); + + /* + Load 3 sounds - these are just sine wave tones at different frequencies. C, D and E on the musical scale. + */ + result = system->createSound(Common_MediaPath("c.ogg"), FMOD_DEFAULT, 0, &sound[NOTE_C]); + ERRCHECK(result); + result = system->createSound(Common_MediaPath("d.ogg"), FMOD_DEFAULT, 0, &sound[NOTE_D]); + ERRCHECK(result); + result = system->createSound(Common_MediaPath("e.ogg"), FMOD_DEFAULT, 0, &sound[NOTE_E]); + ERRCHECK(result); + + /* + Create a channelgroup that the channels will play on. We can use this channelgroup as our clock reference. + It also means we can pause and pitch bend the channelgroup, without affecting the offsets of the delays, because the channelgroup clock + which the channels feed off, will be pausing and speeding up/slowing down and still keeping the children in sync. + */ + result = system->createChannelGroup("Parent", &channelgroup); + ERRCHECK(result); + + unsigned int numsounds = sizeof(note) / sizeof(note[0]); + + /* + Play all the sounds at once! Space them apart with set delay though so that they sound like they play in order. + */ + for (count = 0; count < numsounds; count++) + { + static unsigned long long clock_start = 0; + unsigned int slen; + FMOD::Sound *s = sound[note[count]]; /* Pick a note from our tune. */ + + result = system->playSound(s, channelgroup, true, &channel); /* Play the sound on the channelgroup we want to use as the parent clock reference (for setDelay further down) */ + ERRCHECK(result); + + if (!clock_start) + { + result = channel->getDSPClock(0, &clock_start); + ERRCHECK(result); + + clock_start += (dsp_block_len * 2); /* Start the sound into the future, by 2 mixer blocks worth. */ + /* Should be enough to avoid the mixer catching up and hitting the clock value before we've finished setting up everything. */ + /* Alternatively the channelgroup we're basing the clock on could be paused to stop it ticking. */ + } + else + { + float freq; + + result = s->getLength(&slen, FMOD_TIMEUNIT_PCM); /* Get the length of the sound in samples. */ + ERRCHECK(result); + + result = s->getDefaults(&freq, 0); /* Get the default frequency that the sound was recorded at. */ + ERRCHECK(result); + + slen = (unsigned int)((float)slen / freq * outputrate); /* Convert the length of the sound to 'output samples' for the output timeline. */ + + clock_start += slen; /* Place the sound clock start time to this value after the last one. */ + } + + result = channel->setDelay(clock_start, 0, false); /* Schedule the channel to start in the future at the newly calculated channelgroup clock value. */ + ERRCHECK(result); + + result = channel->setPaused(false); /* Unpause the sound. Note that you won't hear the sounds, they are scheduled into the future. */ + ERRCHECK(result); + } + + /* + Main loop. + */ + do + { + Common_Update(); + + if (Common_BtnPress(BTN_ACTION1)) /* Pausing the channelgroup as the clock parent, will pause any scheduled sounds from continuing */ + { /* If you paused the channel, this would not stop the clock it is delayed against from ticking, */ + bool paused; /* and you'd have to recalculate the delay for the channel into the future again before it was unpaused. */ + result = channelgroup->getPaused(&paused); + ERRCHECK(result); + result = channelgroup->setPaused(!paused); + ERRCHECK(result); + } + if (Common_BtnPress(BTN_ACTION2)) + { + for (count = 0; count < 50; count++) + { + float pitch; + result = channelgroup->getPitch(&pitch); + ERRCHECK(result); + pitch += 0.01f; + result = channelgroup->setPitch(pitch); + ERRCHECK(result); + + result = system->update(); + ERRCHECK(result); + + Common_Sleep(10); + } + } + if (Common_BtnPress(BTN_ACTION3)) + { + for (count = 0; count < 50; count++) + { + float pitch; + result = channelgroup->getPitch(&pitch); + ERRCHECK(result); + + if (pitch > 0.1f) + { + pitch -= 0.01f; + } + result = channelgroup->setPitch(pitch); + ERRCHECK(result); + + result = system->update(); + ERRCHECK(result); + + Common_Sleep(10); + } + } + + result = system->update(); + ERRCHECK(result); + + /* + Print some information + */ + { + bool playing = false; + bool paused = false; + int chansplaying; + + if (channelgroup) + { + result = channelgroup->isPlaying(&playing); + if ((result != FMOD_OK) && (result != FMOD_ERR_INVALID_HANDLE)) + { + ERRCHECK(result); + } + + result = channelgroup->getPaused(&paused); + if ((result != FMOD_OK) && (result != FMOD_ERR_INVALID_HANDLE)) + { + ERRCHECK(result); + } + } + + result = system->getChannelsPlaying(&chansplaying, NULL); + ERRCHECK(result); + + Common_Draw("=================================================="); + Common_Draw("Gapless Playback example."); + Common_Draw("Copyright (c) Firelight Technologies 2004-2026."); + Common_Draw("=================================================="); + Common_Draw(""); + Common_Draw("Press %s to toggle pause", Common_BtnStr(BTN_ACTION1)); + Common_Draw("Press %s to increase pitch", Common_BtnStr(BTN_ACTION2)); + Common_Draw("Press %s to decrease pitch", Common_BtnStr(BTN_ACTION3)); + Common_Draw("Press %s to quit", Common_BtnStr(BTN_QUIT)); + Common_Draw(""); + Common_Draw("Channels Playing %d : %s", chansplaying, paused ? "Paused " : playing ? "Playing" : "Stopped"); + } + + Common_Sleep(50); + } while (!Common_BtnPress(BTN_QUIT)); + + /* + Shut down + */ + result = sound[NOTE_C]->release(); + ERRCHECK(result); + result = sound[NOTE_D]->release(); + ERRCHECK(result); + result = sound[NOTE_E]->release(); + ERRCHECK(result); + + result = system->close(); + ERRCHECK(result); + result = system->release(); + ERRCHECK(result); + + Common_Close(); + + return 0; +} diff --git a/FMOD/api/core/examples/generate_tone.cpp b/FMOD/api/core/examples/generate_tone.cpp new file mode 100644 index 0000000..6073684 --- /dev/null +++ b/FMOD/api/core/examples/generate_tone.cpp @@ -0,0 +1,213 @@ +/*============================================================================== +Generate Tone Example +Copyright (c), Firelight Technologies Pty, Ltd 2004-2026. + +This example shows how to play generated tones using System::playDSP +instead of manually connecting and disconnecting DSP units. + +For information on using FMOD example code in your own programs, visit +https://www.fmod.com/legal +==============================================================================*/ +#include "fmod.hpp" +#include "common.h" + +int FMOD_Main() +{ + FMOD::System *system; + FMOD::Channel *channel = 0; + FMOD::DSP *dsp; + FMOD_RESULT result; + void *extradriverdata = 0; + + Common_Init(&extradriverdata); + + /* + Create a System object and initialize. + */ + result = FMOD::System_Create(&system); + ERRCHECK(result); + + result = system->init(32, FMOD_INIT_NORMAL, extradriverdata); + ERRCHECK(result); + + /* + Create an oscillator DSP units for the tone. + */ + result = system->createDSPByType(FMOD_DSP_TYPE_OSCILLATOR, &dsp); + ERRCHECK(result); + result = dsp->setParameterFloat(FMOD_DSP_OSCILLATOR_RATE, 440.0f); /* Musical note 'A' */ + ERRCHECK(result); + + /* + Main loop + */ + do + { + Common_Update(); + + if (Common_BtnPress(BTN_ACTION1)) + { + if (channel) + { + result = channel->stop(); + ERRCHECK(result); + } + + result = system->playDSP(dsp, 0, true, &channel); + ERRCHECK(result); + result = channel->setVolume(0.5f); + ERRCHECK(result); + result = dsp->setParameterInt(FMOD_DSP_OSCILLATOR_TYPE, 0); + ERRCHECK(result); + result = channel->setPaused(false); + ERRCHECK(result); + } + + if (Common_BtnPress(BTN_ACTION2)) + { + if (channel) + { + result = channel->stop(); + ERRCHECK(result); + } + + result = system->playDSP(dsp, 0, true, &channel); + ERRCHECK(result); + result = channel->setVolume(0.125f); + ERRCHECK(result); + result = dsp->setParameterInt(FMOD_DSP_OSCILLATOR_TYPE, 1); + ERRCHECK(result); + result = channel->setPaused(false); + ERRCHECK(result); + } + + if (Common_BtnPress(BTN_ACTION3)) + { + if (channel) + { + result = channel->stop(); + ERRCHECK(result); + } + + result = system->playDSP(dsp, 0, true, &channel); + ERRCHECK(result); + result = channel->setVolume(0.125f); + ERRCHECK(result); + result = dsp->setParameterInt(FMOD_DSP_OSCILLATOR_TYPE, 2); + ERRCHECK(result); + result = channel->setPaused(false); + ERRCHECK(result); + } + + if (Common_BtnPress(BTN_ACTION4)) + { + if (channel) + { + result = channel->stop(); + ERRCHECK(result); + } + + result = system->playDSP(dsp, 0, true, &channel); + ERRCHECK(result); + result = channel->setVolume(0.5f); + ERRCHECK(result); + result = dsp->setParameterInt(FMOD_DSP_OSCILLATOR_TYPE, 4); + ERRCHECK(result); + result = channel->setPaused(false); + ERRCHECK(result); + } + + if (Common_BtnPress(BTN_MORE)) + { + if (channel) + { + result = channel->stop(); + ERRCHECK(result); + channel = 0; + } + } + + if (channel) + { + if (Common_BtnDown(BTN_UP) || Common_BtnDown(BTN_DOWN)) + { + float volume; + + result = channel->getVolume(&volume); + ERRCHECK(result); + + volume += (Common_BtnDown(BTN_UP) ? +0.1f : -0.1f); + volume = (volume > 1.0f) ? 1.0f : volume; + volume = (volume < 0.0f) ? 0.0f : volume; + + result = channel->setVolume(volume); + ERRCHECK(result); + } + + if (Common_BtnDown(BTN_LEFT) || Common_BtnDown(BTN_RIGHT)) + { + float frequency; + + result = channel->getFrequency(&frequency); + ERRCHECK(result); + + frequency += (Common_BtnDown(BTN_RIGHT) ? +500.0f : -500.0f); + + result = channel->setFrequency(frequency); + ERRCHECK(result); + } + } + + result = system->update(); + ERRCHECK(result); + + { + float frequency = 0.0f, volume = 0.0f; + bool playing = false; + + if (channel) + { + result = channel->getFrequency(&frequency); + ERRCHECK(result); + result = channel->getVolume(&volume); + ERRCHECK(result); + result = channel->isPlaying(&playing); + ERRCHECK(result); + } + + Common_Draw("=================================================="); + Common_Draw("Generate Tone Example."); + Common_Draw("Copyright (c) Firelight Technologies 2004-2026."); + Common_Draw("=================================================="); + Common_Draw(""); + Common_Draw("Press %s to play a sine wave", Common_BtnStr(BTN_ACTION1)); + Common_Draw("Press %s to play a square wave", Common_BtnStr(BTN_ACTION2)); + Common_Draw("Press %s to play a saw wave", Common_BtnStr(BTN_ACTION3)); + Common_Draw("Press %s to play a triangle wave", Common_BtnStr(BTN_ACTION4)); + Common_Draw("Press %s to stop the channel", Common_BtnStr(BTN_MORE)); + Common_Draw("Press %s and %s to change volume", Common_BtnStr(BTN_UP), Common_BtnStr(BTN_DOWN)); + Common_Draw("Press %s and %s to change frequency", Common_BtnStr(BTN_LEFT), Common_BtnStr(BTN_RIGHT)); + Common_Draw("Press %s to quit", Common_BtnStr(BTN_QUIT)); + Common_Draw(""); + Common_Draw("Channel is %s", playing ? "playing" : "stopped"); + Common_Draw("Volume %0.2f", volume); + Common_Draw("Frequency %0.2f", frequency); + } + + Common_Sleep(50); + } while (!Common_BtnPress(BTN_QUIT)); + + /* + Shut down + */ + result = dsp->release(); + ERRCHECK(result); + result = system->close(); + ERRCHECK(result); + result = system->release(); + ERRCHECK(result); + + Common_Close(); + + return 0; +} diff --git a/FMOD/api/core/examples/granular_synth.cpp b/FMOD/api/core/examples/granular_synth.cpp new file mode 100644 index 0000000..cc735aa --- /dev/null +++ b/FMOD/api/core/examples/granular_synth.cpp @@ -0,0 +1,278 @@ +/*============================================================================== +Granular Synthesis Example +Copyright (c), Firelight Technologies Pty, Ltd 2004-2026. + +This example shows how you can play a string of sounds together without gaps, +using the setDelay command, to produce a granular synthesis style truck engine +effect. + +The basic operation is: + + * Play 2 sounds initially at the same time, the first sound immediately, and + the 2nd sound with a delay calculated by the length of the first sound. + * Call setDelay to initiate the delayed playback. setDelay is sample accurate + and uses -output- samples as the time frame, not source samples. These + samples are a fixed amount per second regardless of the source sound format, + for example, 48000 samples per second if FMOD is initialized to 48khz output. + * Output samples are calculated from source samples with a simple + source->output sample rate conversion. i.e. + sound_length *= output_rate + sound_length /= sound_frequency + * When the first sound finishes, the second one should have automatically + started. This is a good oppurtunity to queue up the next sound. Repeat + step 2. + * Make sure the framerate is high enough to queue up a new sound before the + other one finishes otherwise you will get gaps. + +These sounds are not limited by format, channel count or bit depth like the +realtimestitching example is, and can also be modified to allow for overlap, +by reducing the delay from the first sound playing to the second by the overlap +amount. + + #define USE_STREAMS = Use 2 stream instances, created while they play. + #define USE_STREAMS = Use 6 static wavs, all loaded into memory. + +For information on using FMOD example code in your own programs, visit +https://www.fmod.com/legal +==============================================================================*/ +#include "fmod.hpp" +#include "common.h" + +//#define USE_STREAMS + +FMOD::System *gSystem; + +#ifdef USE_STREAMS +#define NUMSOUNDS 3 /* Use some longer sounds, free and load them on the fly. */ +FMOD::Sound *sound[2] = { 0, 0 }; /* 2 streams active, double buffer them. */ +const char *soundname[NUMSOUNDS] = { Common_MediaPath("c.ogg"), + Common_MediaPath("d.ogg"), + Common_MediaPath("e.ogg") }; +#else +#define NUMSOUNDS 6 /* These sounds will be loaded into memory statically. */ +FMOD::Sound *sound[NUMSOUNDS] = { 0, 0, 0, 0, 0, 0 }; /* 6 sounds active, one for each wav. */ +const char *soundname[NUMSOUNDS] = { Common_MediaPath("granular/truck_idle_off_01.wav"), + Common_MediaPath("granular/truck_idle_off_02.wav"), + Common_MediaPath("granular/truck_idle_off_03.wav"), + Common_MediaPath("granular/truck_idle_off_04.wav"), + Common_MediaPath("granular/truck_idle_off_05.wav"), + Common_MediaPath("granular/truck_idle_off_06.wav") }; +#endif + +FMOD::Channel *queue_next_sound(int outputrate, FMOD::Channel *playingchannel, int newindex, int slot) +{ + FMOD_RESULT result; + FMOD::Channel *newchannel; + FMOD::Sound *newsound; + +#ifdef USE_STREAMS /* Create a new stream */ + FMOD_CREATESOUNDEXINFO info; + memset(&info, 0, sizeof(FMOD_CREATESOUNDEXINFO)); + info.cbsize = sizeof(FMOD_CREATESOUNDEXINFO); + info.suggestedsoundtype = FMOD_SOUND_TYPE_OGGVORBIS; + result = gSystem->createStream(soundname[newindex], FMOD_IGNORETAGS | FMOD_LOWMEM, &info, &sound[slot]); + ERRCHECK(result); + newsound = sound[slot]; +#else /* Use an existing sound that was passed into us */ + (void)slot; + newsound = sound[newindex]; +#endif + + result = gSystem->playSound(newsound, 0, true, &newchannel); + ERRCHECK(result); + + if (playingchannel) + { + unsigned long long startdelay = 0; + unsigned int soundlength = 0; + float soundfrequency; + FMOD::Sound *playingsound; + + /* + Get the start time of the playing channel. + */ + result = playingchannel->getDelay(&startdelay, 0); + ERRCHECK(result); + + /* + Grab the length of the playing sound, and its frequency, so we can caluate where to place the new sound on the time line. + */ + result = playingchannel->getCurrentSound(&playingsound); + ERRCHECK(result); + result = playingsound->getLength(&soundlength, FMOD_TIMEUNIT_PCM); + ERRCHECK(result); + result = playingchannel->getFrequency(&soundfrequency); + ERRCHECK(result); + + /* + Now calculate the length of the sound in 'output samples'. + Ie if a 44khz sound is 22050 samples long, and the output rate is 48khz, then we want to delay by 24000 output samples. + */ + soundlength *= outputrate; + soundlength /= (int)soundfrequency; + + startdelay += soundlength; /* Add output rate adjusted sound length, to the clock value of the sound that is currently playing */ + + result = newchannel->setDelay(startdelay, 0); /* Set the delay of the new sound to the end of the old sound */ + ERRCHECK(result); + } + else + { + unsigned int bufferlength; + unsigned long long startdelay; + + result = gSystem->getDSPBufferSize(&bufferlength, 0); + ERRCHECK(result); + + result = newchannel->getDSPClock(0, &startdelay); + ERRCHECK(result); + + startdelay += (2 * bufferlength); + result = newchannel->setDelay(startdelay, 0); + ERRCHECK(result); + } + + { + float val, variation; + + /* + Randomize pitch/volume to make it sound more realistic / random. + */ + result = newchannel->getFrequency(&val); + ERRCHECK(result); + variation = (((float)(rand()%10000) / 5000.0f) - 1.0f); /* -1.0 to +1.0 */ + val *= (1.0f + (variation * 0.02f)); /* @22khz, range fluctuates from 21509 to 22491 */ + result = newchannel->setFrequency(val); + ERRCHECK(result); + + result = newchannel->getVolume(&val); + ERRCHECK(result); + variation = ((float)(rand()%10000) / 10000.0f); /* 0.0 to 1.0 */ + val *= (1.0f - (variation * 0.2f)); /* 0.8 to 1.0 */ + result = newchannel->setVolume(val); + ERRCHECK(result); + } + + result = newchannel->setPaused(false); + ERRCHECK(result); + + return newchannel; +} + +int FMOD_Main() +{ + FMOD::Channel *channel[2] = { 0,0 }; + FMOD_RESULT result; + int outputrate, slot = 0; + void *extradriverdata = 0; + bool paused = false; + + Common_Init(&extradriverdata); + + result = FMOD::System_Create(&gSystem); + ERRCHECK(result); + + result = gSystem->init(100, FMOD_INIT_NORMAL, extradriverdata); + ERRCHECK(result); + + result = gSystem->getSoftwareFormat(&outputrate, 0, 0); + ERRCHECK(result); + +#if !defined(USE_STREAMS) + for (unsigned int count = 0; count < NUMSOUNDS; count++) + { + result = gSystem->createSound(soundname[count], FMOD_IGNORETAGS, 0, &sound[count]); + ERRCHECK(result); + } +#endif + + /* + Kick off the first 2 sounds. First one is immediate, second one will be triggered to start after the first one. + */ + channel[slot] = queue_next_sound(outputrate, channel[1-slot], rand()%NUMSOUNDS, slot); + slot = 1-slot; /* flip */ + channel[slot] = queue_next_sound(outputrate, channel[1-slot], rand()%NUMSOUNDS, slot); + slot = 1-slot; /* flip */ + + do + { + bool isplaying = false; + + Common_Update(); + + if (Common_BtnPress(BTN_ACTION1)) + { + FMOD::ChannelGroup *mastergroup; + + paused = !paused; + + result = gSystem->getMasterChannelGroup(&mastergroup); + ERRCHECK(result); + result = mastergroup->setPaused(paused); + ERRCHECK(result); + } + + result = gSystem->update(); + ERRCHECK(result); + + /* + Replace the sound that just finished with a new sound, to create endless seamless stitching! + */ + result = channel[slot]->isPlaying(&isplaying); + if (result != FMOD_ERR_INVALID_HANDLE) + { + ERRCHECK(result); + } + + if (!isplaying && !paused) + { +#ifdef USE_STREAMS + /* + Release the sound that isn't playing any more. + */ + result = sound[slot]->release(); + ERRCHECK(result); + sound[slot] = 0; +#endif + + /* + Replace sound that just ended with a new sound, queued up to trigger exactly after the other sound ends. + */ + channel[slot] = queue_next_sound(outputrate, channel[1-slot], rand()%NUMSOUNDS, slot); + slot = 1-slot; /* flip */ + } + + Common_Draw("=================================================="); + Common_Draw("Granular Synthesis SetDelay Example."); + Common_Draw("Copyright (c) Firelight Technologies 2004-2026."); + Common_Draw("=================================================="); + Common_Draw(""); + Common_Draw("Toggle #define USE_STREAM on/off in code to switch between streams and static samples."); + Common_Draw(""); + Common_Draw("Press %s to pause", Common_BtnStr(BTN_ACTION1)); + Common_Draw("Press %s to quit", Common_BtnStr(BTN_QUIT)); + Common_Draw(""); + Common_Draw("Channels are %s", paused ? "paused" : "playing"); + + Common_Sleep(10); /* If you wait too long, ie longer than the length of the shortest sound, you will get gaps. */ + } while (!Common_BtnPress(BTN_QUIT)); + + /* + Shut down + */ + for (unsigned int count = 0; count < sizeof(sound) / sizeof(sound[0]); count++) + { + if (sound[count]) + { + result = sound[count]->release(); + ERRCHECK(result); + } + } + + result = gSystem->release(); + ERRCHECK(result); + + Common_Close(); + + return 0; +} diff --git a/FMOD/api/core/examples/load_from_memory.cpp b/FMOD/api/core/examples/load_from_memory.cpp new file mode 100644 index 0000000..3e1596e --- /dev/null +++ b/FMOD/api/core/examples/load_from_memory.cpp @@ -0,0 +1,168 @@ +/*============================================================================== +Load From Memory Example +Copyright (c), Firelight Technologies Pty, Ltd 2004-2026. + +This example is simply a variant of the [Play Sound Example](play_sound.html), +but it loads the data into memory then uses the 'load from memory' feature of +System::createSound. + +For information on using FMOD example code in your own programs, visit +https://www.fmod.com/legal +==============================================================================*/ +#include "fmod.hpp" +#include "common.h" + +int FMOD_Main() +{ + FMOD::System *system; + FMOD::Sound *sound1, *sound2, *sound3; + FMOD::Channel *channel = 0; + FMOD_RESULT result; + void *extradriverdata = 0; + void *buff = 0; + int length = 0; + FMOD_CREATESOUNDEXINFO exinfo; + + Common_Init(&extradriverdata); + + /* + Create a System object and initialize + */ + result = FMOD::System_Create(&system); + ERRCHECK(result); + + result = system->init(32, FMOD_INIT_NORMAL, extradriverdata); + ERRCHECK(result); + + Common_LoadFileMemory(Common_MediaPath("drumloop.wav"), &buff, &length); + memset(&exinfo, 0, sizeof(FMOD_CREATESOUNDEXINFO)); + exinfo.cbsize = sizeof(FMOD_CREATESOUNDEXINFO); + exinfo.length = length; + + result = system->createSound((const char *)buff, FMOD_OPENMEMORY | FMOD_LOOP_OFF, &exinfo, &sound1); + ERRCHECK(result); + Common_UnloadFileMemory(buff); // don't need the original memory any more. Note! If loading as a stream, the memory must stay active so do not free it! + + Common_LoadFileMemory(Common_MediaPath("jaguar.wav"), &buff, &length); + memset(&exinfo, 0, sizeof(FMOD_CREATESOUNDEXINFO)); + exinfo.cbsize = sizeof(FMOD_CREATESOUNDEXINFO); + exinfo.length = length; + + result = system->createSound((const char *)buff, FMOD_OPENMEMORY, &exinfo, &sound2); + ERRCHECK(result); + Common_UnloadFileMemory(buff); // don't need the original memory any more. Note! If loading as a stream, the memory must stay active so do not free it! + + Common_LoadFileMemory(Common_MediaPath("swish.wav"), &buff, &length); + memset(&exinfo, 0, sizeof(FMOD_CREATESOUNDEXINFO)); + exinfo.cbsize = sizeof(FMOD_CREATESOUNDEXINFO); + exinfo.length = length; + + result = system->createSound((const char *)buff, FMOD_OPENMEMORY, &exinfo, &sound3); + ERRCHECK(result); + Common_UnloadFileMemory(buff); // don't need the original memory any more. Note! If loading as a stream, the memory must stay active so do not free it! + + /* + Main loop + */ + do + { + Common_Update(); + + if (Common_BtnPress(BTN_ACTION1)) + { + result = system->playSound(sound1, 0, false, &channel); + ERRCHECK(result); + } + + if (Common_BtnPress(BTN_ACTION2)) + { + result = system->playSound(sound2, 0, false, &channel); + ERRCHECK(result); + } + + if (Common_BtnPress(BTN_ACTION3)) + { + result = system->playSound(sound3, 0, false, &channel); + ERRCHECK(result); + } + + result = system->update(); + ERRCHECK(result); + + { + unsigned int ms = 0; + unsigned int lenms = 0; + bool playing = 0; + bool paused = 0; + int channelsplaying = 0; + + if (channel) + { + FMOD::Sound *currentsound = 0; + + result = channel->isPlaying(&playing); + if ((result != FMOD_OK) && (result != FMOD_ERR_INVALID_HANDLE) && (result != FMOD_ERR_CHANNEL_STOLEN)) + { + ERRCHECK(result); + } + + result = channel->getPaused(&paused); + if ((result != FMOD_OK) && (result != FMOD_ERR_INVALID_HANDLE) && (result != FMOD_ERR_CHANNEL_STOLEN)) + { + ERRCHECK(result); + } + + result = channel->getPosition(&ms, FMOD_TIMEUNIT_MS); + if ((result != FMOD_OK) && (result != FMOD_ERR_INVALID_HANDLE) && (result != FMOD_ERR_CHANNEL_STOLEN)) + { + ERRCHECK(result); + } + + channel->getCurrentSound(¤tsound); + if (currentsound) + { + result = currentsound->getLength(&lenms, FMOD_TIMEUNIT_MS); + if ((result != FMOD_OK) && (result != FMOD_ERR_INVALID_HANDLE) && (result != FMOD_ERR_CHANNEL_STOLEN)) + { + ERRCHECK(result); + } + } + } + + system->getChannelsPlaying(&channelsplaying, NULL); + + Common_Draw("=================================================="); + Common_Draw("Load From Memory Example."); + Common_Draw("Copyright (c) Firelight Technologies 2004-2026."); + Common_Draw("=================================================="); + Common_Draw(""); + Common_Draw("Press %s to play a mono sound (drumloop)", Common_BtnStr(BTN_ACTION1)); + Common_Draw("Press %s to play a mono sound (jaguar)", Common_BtnStr(BTN_ACTION2)); + Common_Draw("Press %s to play a stereo sound (swish)", Common_BtnStr(BTN_ACTION3)); + Common_Draw("Press %s to quit", Common_BtnStr(BTN_QUIT)); + Common_Draw(""); + Common_Draw("Time %02d:%02d:%02d/%02d:%02d:%02d : %s", ms / 1000 / 60, ms / 1000 % 60, ms / 10 % 100, lenms / 1000 / 60, lenms / 1000 % 60, lenms / 10 % 100, paused ? "Paused " : playing ? "Playing" : "Stopped"); + Common_Draw("Channels Playing %2d", channelsplaying); + } + + Common_Sleep(50); + } while (!Common_BtnPress(BTN_QUIT)); + + /* + Shut down + */ + result = sound1->release(); + ERRCHECK(result); + result = sound2->release(); + ERRCHECK(result); + result = sound3->release(); + ERRCHECK(result); + result = system->close(); + ERRCHECK(result); + result = system->release(); + ERRCHECK(result); + + Common_Close(); + + return 0; +} diff --git a/FMOD/api/core/examples/media/c.ogg b/FMOD/api/core/examples/media/c.ogg new file mode 100644 index 0000000..4ce915d Binary files /dev/null and b/FMOD/api/core/examples/media/c.ogg differ diff --git a/FMOD/api/core/examples/media/d.ogg b/FMOD/api/core/examples/media/d.ogg new file mode 100644 index 0000000..0c8d037 Binary files /dev/null and b/FMOD/api/core/examples/media/d.ogg differ diff --git a/FMOD/api/core/examples/media/drumloop.wav b/FMOD/api/core/examples/media/drumloop.wav new file mode 100644 index 0000000..7188c33 Binary files /dev/null and b/FMOD/api/core/examples/media/drumloop.wav differ diff --git a/FMOD/api/core/examples/media/e.ogg b/FMOD/api/core/examples/media/e.ogg new file mode 100644 index 0000000..12a66bc Binary files /dev/null and b/FMOD/api/core/examples/media/e.ogg differ diff --git a/FMOD/api/core/examples/media/granular/truck_idle_off_01.wav b/FMOD/api/core/examples/media/granular/truck_idle_off_01.wav new file mode 100644 index 0000000..7762654 Binary files /dev/null and b/FMOD/api/core/examples/media/granular/truck_idle_off_01.wav differ diff --git a/FMOD/api/core/examples/media/granular/truck_idle_off_02.wav b/FMOD/api/core/examples/media/granular/truck_idle_off_02.wav new file mode 100644 index 0000000..43f4382 Binary files /dev/null and b/FMOD/api/core/examples/media/granular/truck_idle_off_02.wav differ diff --git a/FMOD/api/core/examples/media/granular/truck_idle_off_03.wav b/FMOD/api/core/examples/media/granular/truck_idle_off_03.wav new file mode 100644 index 0000000..1d0985d Binary files /dev/null and b/FMOD/api/core/examples/media/granular/truck_idle_off_03.wav differ diff --git a/FMOD/api/core/examples/media/granular/truck_idle_off_04.wav b/FMOD/api/core/examples/media/granular/truck_idle_off_04.wav new file mode 100644 index 0000000..3c1eab0 Binary files /dev/null and b/FMOD/api/core/examples/media/granular/truck_idle_off_04.wav differ diff --git a/FMOD/api/core/examples/media/granular/truck_idle_off_05.wav b/FMOD/api/core/examples/media/granular/truck_idle_off_05.wav new file mode 100644 index 0000000..a595c75 Binary files /dev/null and b/FMOD/api/core/examples/media/granular/truck_idle_off_05.wav differ diff --git a/FMOD/api/core/examples/media/granular/truck_idle_off_06.wav b/FMOD/api/core/examples/media/granular/truck_idle_off_06.wav new file mode 100644 index 0000000..6ded223 Binary files /dev/null and b/FMOD/api/core/examples/media/granular/truck_idle_off_06.wav differ diff --git a/FMOD/api/core/examples/media/jaguar.wav b/FMOD/api/core/examples/media/jaguar.wav new file mode 100644 index 0000000..0347714 Binary files /dev/null and b/FMOD/api/core/examples/media/jaguar.wav differ diff --git a/FMOD/api/core/examples/media/singing.wav b/FMOD/api/core/examples/media/singing.wav new file mode 100644 index 0000000..c5f3e99 Binary files /dev/null and b/FMOD/api/core/examples/media/singing.wav differ diff --git a/FMOD/api/core/examples/media/standrews.wav b/FMOD/api/core/examples/media/standrews.wav new file mode 100644 index 0000000..25bf89e Binary files /dev/null and b/FMOD/api/core/examples/media/standrews.wav differ diff --git a/FMOD/api/core/examples/media/stereo.ogg b/FMOD/api/core/examples/media/stereo.ogg new file mode 100644 index 0000000..1b26db5 Binary files /dev/null and b/FMOD/api/core/examples/media/stereo.ogg differ diff --git a/FMOD/api/core/examples/media/swish.wav b/FMOD/api/core/examples/media/swish.wav new file mode 100644 index 0000000..f84f6b5 Binary files /dev/null and b/FMOD/api/core/examples/media/swish.wav differ diff --git a/FMOD/api/core/examples/media/wave.mp3 b/FMOD/api/core/examples/media/wave.mp3 new file mode 100644 index 0000000..400b6a5 Binary files /dev/null and b/FMOD/api/core/examples/media/wave.mp3 differ diff --git a/FMOD/api/core/examples/media/wave_vorbis.fsb b/FMOD/api/core/examples/media/wave_vorbis.fsb new file mode 100644 index 0000000..64d11ea Binary files /dev/null and b/FMOD/api/core/examples/media/wave_vorbis.fsb differ diff --git a/FMOD/api/core/examples/multiple_speaker.cpp b/FMOD/api/core/examples/multiple_speaker.cpp new file mode 100644 index 0000000..d8e6f66 --- /dev/null +++ b/FMOD/api/core/examples/multiple_speaker.cpp @@ -0,0 +1,292 @@ +/*============================================================================== +Multiple Speaker Example +Copyright (c), Firelight Technologies Pty, Ltd 2004-2026. + +This example shows how to play sounds in multiple speakers, and also how to even +assign sound subchannels, such as those in a stereo sound to different +individual speakers. + +For information on using FMOD example code in your own programs, visit +https://www.fmod.com/legal +==============================================================================*/ +#include "fmod.hpp" +#include "common.h" + +const char *SPEAKERMODE_STRING[] = { "default", "raw", "mono", "stereo", "quad", "surround", "5.1", "7.1" }; +const char *SELECTION_STRING[] = { "Mono from front left speaker", + "Mono from front right speaker", + "Mono from center speaker", + "Mono from surround left speaker", + "Mono from surround right speaker", + "Mono from rear left speaker", + "Mono from rear right speaker", + "Stereo from front speakers", + "Stereo from front speakers (channel swapped)", + "Stereo (right only) from center speaker" }; +const unsigned int SELECTION_COUNT = sizeof(SELECTION_STRING) / sizeof(char *); + +bool isSelectionAvailable(FMOD_SPEAKERMODE mode, unsigned int selection) +{ + if (mode == FMOD_SPEAKERMODE_MONO || mode == FMOD_SPEAKERMODE_STEREO) + { + if (selection == 2 || selection == 3 || selection == 4 || selection == 5 || selection == 6 || selection == 9) return false; + } + else if (mode == FMOD_SPEAKERMODE_QUAD) + { + if (selection == 2 || selection == 5 || selection == 6 || selection == 9) return false; + } + else if (mode == FMOD_SPEAKERMODE_SURROUND || mode == FMOD_SPEAKERMODE_5POINT1) + { + if (selection == 5 || selection == 6) return false; + } + + return true; +} + +int FMOD_Main() +{ + FMOD::System *system; + FMOD::Sound *sound1, *sound2; + FMOD::Channel *channel = 0; + FMOD_RESULT result; + int selection = 0; + void *extradriverdata = 0; + FMOD_SPEAKERMODE speakermode = FMOD_SPEAKERMODE_STEREO; + + Common_Init(&extradriverdata); + + /* + Create a System object and initialize. + */ + result = FMOD::System_Create(&system); + ERRCHECK(result); + + result = system->init(32, FMOD_INIT_NORMAL, extradriverdata); + ERRCHECK(result); + + result = system->getSoftwareFormat(0, &speakermode, 0); + ERRCHECK(result); + + result = system->createSound(Common_MediaPath("drumloop.wav"), FMOD_2D | FMOD_LOOP_OFF, 0, &sound1); + ERRCHECK(result); + + result = system->createSound(Common_MediaPath("stereo.ogg"), FMOD_2D | FMOD_LOOP_OFF, 0, &sound2); + ERRCHECK(result); + + /* + Main loop. + */ + do + { + Common_Update(); + + if (Common_BtnPress(BTN_UP) && (selection != 0)) + { + selection--; + } + + if (Common_BtnPress(BTN_DOWN) && (selection != (SELECTION_COUNT - 1))) + { + selection++; + } + + if (Common_BtnPress(BTN_ACTION1) && isSelectionAvailable(speakermode, selection)) + { + if (selection == 0) /* Mono front left */ + { + result = system->playSound(sound1, 0, true, &channel); + ERRCHECK(result); + + result = channel->setMixLevelsOutput(1.0f, 0, 0, 0, 0, 0, 0, 0); + ERRCHECK(result); + + result = channel->setPaused(false); + ERRCHECK(result); + } + else if (selection == 1) /* Mono front right */ + { + result = system->playSound(sound1, 0, true, &channel); + ERRCHECK(result); + + result = channel->setMixLevelsOutput(0, 1.0f, 0, 0, 0, 0, 0, 0); + ERRCHECK(result); + + result = channel->setPaused(false); + ERRCHECK(result); + } + else if (selection == 2) /* Mono center */ + { + result = system->playSound(sound1, 0, true, &channel); + ERRCHECK(result); + + result = channel->setMixLevelsOutput(0, 0, 1.0f, 0, 0, 0, 0, 0); + ERRCHECK(result); + + result = channel->setPaused(false); + ERRCHECK(result); + } + else if (selection == 3) /* Mono surround left */ + { + result = system->playSound(sound1, 0, true, &channel); + ERRCHECK(result); + + result = channel->setMixLevelsOutput(0, 0, 0, 0, 1.0f, 0, 0, 0); + ERRCHECK(result); + + result = channel->setPaused(false); + ERRCHECK(result); + } + else if (selection == 4) /* Mono surround right */ + { + result = system->playSound(sound1, 0, true, &channel); + ERRCHECK(result); + + result = channel->setMixLevelsOutput(0, 0, 0, 0, 0, 1.0f, 0, 0); + ERRCHECK(result); + + result = channel->setPaused(false); + ERRCHECK(result); + } + else if (selection == 5) /* Mono rear left */ + { + result = system->playSound(sound1, 0, true, &channel); + ERRCHECK(result); + + result = channel->setMixLevelsOutput(0, 0, 0, 0, 0, 0, 1.0f, 0); + ERRCHECK(result); + + result = channel->setPaused(false); + ERRCHECK(result); + } + else if (selection == 6) /* Mono rear right */ + { + result = system->playSound(sound1, 0, true, &channel); + ERRCHECK(result); + + result = channel->setMixLevelsOutput(0, 0, 0, 0, 0, 0, 0, 1.0f); + ERRCHECK(result); + + result = channel->setPaused(false); + ERRCHECK(result); + } + else if (selection == 7) /* Stereo front */ + { + result = system->playSound(sound2, 0, false, &channel); + ERRCHECK(result); + } + else if (selection == 8) /* Stereo front channel swapped */ + { + float matrix[] = { 0.0f, 1.0f, + 1.0f, 0.0f }; + + result = system->playSound(sound2, 0, true, &channel); + ERRCHECK(result); + + result = channel->setMixMatrix(matrix, 2, 2); + ERRCHECK(result); + + result = channel->setPaused(false); + ERRCHECK(result); + } + else if (selection == 9) /* Stereo (right only) center */ + { + float matrix[] = { 0.0f, 0.0f, + 0.0f, 0.0f, + 0.0f, 1.0f }; + + result = system->playSound(sound2, 0, true, &channel); + ERRCHECK(result); + + result = channel->setMixMatrix(matrix, 3, 2); + ERRCHECK(result); + + result = channel->setPaused(false); + ERRCHECK(result); + } + } + + result = system->update(); + ERRCHECK(result); + + { + unsigned int ms = 0; + unsigned int lenms = 0; + bool playing = false; + bool paused = false; + int channelsplaying = 0; + + if (channel) + { + FMOD::Sound *currentsound = 0; + + result = channel->isPlaying(&playing); + if ((result != FMOD_OK) && (result != FMOD_ERR_INVALID_HANDLE) && (result != FMOD_ERR_CHANNEL_STOLEN)) + { + ERRCHECK(result); + } + + result = channel->getPaused(&paused); + if ((result != FMOD_OK) && (result != FMOD_ERR_INVALID_HANDLE) && (result != FMOD_ERR_CHANNEL_STOLEN)) + { + ERRCHECK(result); + } + + result = channel->getPosition(&ms, FMOD_TIMEUNIT_MS); + if ((result != FMOD_OK) && (result != FMOD_ERR_INVALID_HANDLE) && (result != FMOD_ERR_CHANNEL_STOLEN)) + { + ERRCHECK(result); + } + + channel->getCurrentSound(¤tsound); + if (currentsound) + { + result = currentsound->getLength(&lenms, FMOD_TIMEUNIT_MS); + if ((result != FMOD_OK) && (result != FMOD_ERR_INVALID_HANDLE) && (result != FMOD_ERR_CHANNEL_STOLEN)) + { + ERRCHECK(result); + } + } + } + + result = system->getChannelsPlaying(&channelsplaying, NULL); + ERRCHECK(result); + + Common_Draw("=================================================="); + Common_Draw("Multiple Speaker Example."); + Common_Draw("Copyright (c) Firelight Technologies 2004-2026."); + Common_Draw("=================================================="); + Common_Draw(""); + Common_Draw("Speaker mode is set to %s%s", SPEAKERMODE_STRING[speakermode], speakermode < FMOD_SPEAKERMODE_7POINT1 ? " causing some speaker options to be unavailable" : ""); + Common_Draw(""); + Common_Draw("Press %s or %s to select mode", Common_BtnStr(BTN_UP), Common_BtnStr(BTN_DOWN)); + Common_Draw("Press %s to play the sound", Common_BtnStr(BTN_ACTION1)); + for (int i = 0; i < SELECTION_COUNT; i++) + { + bool disabled = !isSelectionAvailable(speakermode, i); + Common_Draw("[%c] %s%s", (selection == i) ? (disabled ? '-' : 'X') : ' ', disabled ? "[N/A] " : "", SELECTION_STRING[i]); + } + Common_Draw("Press %s to quit", Common_BtnStr(BTN_QUIT)); + Common_Draw(""); + Common_Draw("Time %02d:%02d:%02d/%02d:%02d:%02d : %s", ms / 1000 / 60, ms / 1000 % 60, ms / 10 % 100, lenms / 1000 / 60, lenms / 1000 % 60, lenms / 10 % 100, paused ? "Paused " : playing ? "Playing" : "Stopped"); + Common_Draw("Channels playing: %d", channelsplaying); + } + + Common_Sleep(50); + } while (!Common_BtnPress(BTN_QUIT)); + + /* + Shut down + */ + result = sound1->release(); + ERRCHECK(result); + result = sound2->release(); + ERRCHECK(result); + result = system->close(); + ERRCHECK(result); + result = system->release(); + ERRCHECK(result); + + Common_Close(); + + return 0; +} diff --git a/FMOD/api/core/examples/multiple_system.cpp b/FMOD/api/core/examples/multiple_system.cpp new file mode 100644 index 0000000..3099288 --- /dev/null +++ b/FMOD/api/core/examples/multiple_system.cpp @@ -0,0 +1,193 @@ +/*============================================================================== +Multiple System Example +Copyright (c), Firelight Technologies Pty, Ltd 2004-2026. + +This example shows how to play sounds on two different output devices from the +same application. It creates two FMOD::System objects, selects a different sound +device for each, then allows the user to play one sound on each device. + +Note that sounds created on device A cannot be played on device B and vice +versa. + +For information on using FMOD example code in your own programs, visit +https://www.fmod.com/legal +==============================================================================*/ +#include "fmod.hpp" +#include "common.h" + +FMOD_RESULT fetchDriver(FMOD::System *system, int *driver) +{ + FMOD_RESULT result; + int numdrivers; + int selectedindex = 0; + + result = system->getNumDrivers(&numdrivers); + ERRCHECK(result); + + if (numdrivers == 0) + { + result = system->setOutput(FMOD_OUTPUTTYPE_NOSOUND); + ERRCHECK(result); + } + + do + { + Common_Update(); + + if (Common_BtnPress(BTN_UP) && (selectedindex != 0)) + { + selectedindex--; + } + if (Common_BtnPress(BTN_DOWN) && (selectedindex != (numdrivers - 1))) + { + selectedindex++; + } + + Common_Draw("=================================================="); + Common_Draw("Multiple System Example."); + Common_Draw("Copyright (c) Firelight Technologies 2004-2026."); + Common_Draw("=================================================="); + Common_Draw(""); + Common_Draw("Choose a device for system: 0x%p", system); + Common_Draw(""); + Common_Draw("Use %s and %s to select.", Common_BtnStr(BTN_UP), Common_BtnStr(BTN_DOWN)); + Common_Draw("Press %s to confirm.", Common_BtnStr(BTN_ACTION1)); + Common_Draw(""); + for (int i = 0; i < numdrivers; i++) + { + char name[256]; + + result = system->getDriverInfo(i, name, sizeof(name), 0, 0, 0, 0); + ERRCHECK(result); + + Common_Draw("[%c] - %d. %s", selectedindex == i ? 'X' : ' ', i, name); + } + + Common_Sleep(50); + } while (!Common_BtnPress(BTN_ACTION1) && !Common_BtnPress(BTN_QUIT)); + + *driver = selectedindex; + + return FMOD_OK; +} + +int FMOD_Main() +{ + FMOD::System *systemA, *systemB; + FMOD::Sound *soundA, *soundB; + FMOD::Channel *channelA = 0, *channelB = 0; + FMOD_RESULT result; + int driver; + void *extradriverdata = 0; + + Common_Init(&extradriverdata); + + /* + Create Sound Card A + */ + result = FMOD::System_Create(&systemA); + ERRCHECK(result); + + result = fetchDriver(systemA, &driver); + ERRCHECK(result); + + result = systemA->setDriver(driver); + ERRCHECK(result); + + result = systemA->init(32, FMOD_INIT_NORMAL, extradriverdata); + ERRCHECK(result); + + /* + Create Sound Card B + */ + result = FMOD::System_Create(&systemB); + ERRCHECK(result); + + result = fetchDriver(systemB, &driver); + ERRCHECK(result); + + result = systemB->setDriver(driver); + ERRCHECK(result); + + result = systemB->init(32, FMOD_INIT_NORMAL, extradriverdata); + ERRCHECK(result); + + /* + Load 1 sample into each soundcard. + */ + result = systemA->createSound(Common_MediaPath("drumloop.wav"), FMOD_LOOP_OFF, 0, &soundA); + ERRCHECK(result); + + result = systemB->createSound(Common_MediaPath("jaguar.wav"), FMOD_DEFAULT, 0, &soundB); + ERRCHECK(result); + + /* + Main loop + */ + do + { + Common_Update(); + + if (Common_BtnPress(BTN_ACTION1)) + { + result = systemA->playSound(soundA, 0, 0, &channelA); + ERRCHECK(result); + } + + if (Common_BtnPress(BTN_ACTION2)) + { + result = systemB->playSound(soundB, 0, 0, &channelB); + ERRCHECK(result); + } + + result = systemA->update(); + ERRCHECK(result); + result = systemB->update(); + ERRCHECK(result); + + { + int channelsplayingA = 0; + int channelsplayingB = 0; + + result = systemA->getChannelsPlaying(&channelsplayingA, NULL); + ERRCHECK(result); + result = systemB->getChannelsPlaying(&channelsplayingB, NULL); + ERRCHECK(result); + + Common_Draw("=================================================="); + Common_Draw("Multiple System Example."); + Common_Draw("Copyright (c) Firelight Technologies 2004-2026."); + Common_Draw("=================================================="); + Common_Draw(""); + Common_Draw("Press %s to play a sound on device A", Common_BtnStr(BTN_ACTION1)); + Common_Draw("Press %s to play a sound on device B", Common_BtnStr(BTN_ACTION2)); + Common_Draw("Press %s to quit", Common_BtnStr(BTN_QUIT)); + Common_Draw(""); + Common_Draw("Channels playing on A: %d", channelsplayingA); + Common_Draw("Channels playing on B: %d", channelsplayingB); + } + + Common_Sleep(50); + } while (!Common_BtnPress(BTN_QUIT)); + + /* + Shut down + */ + result = soundA->release(); + ERRCHECK(result); + result = systemA->close(); + ERRCHECK(result); + result = systemA->release(); + ERRCHECK(result); + + result = soundB->release(); + ERRCHECK(result); + result = systemB->close(); + ERRCHECK(result); + result = systemB->release(); + ERRCHECK(result); + + Common_Close(); + + return 0; +} diff --git a/FMOD/api/core/examples/net_stream.cpp b/FMOD/api/core/examples/net_stream.cpp new file mode 100644 index 0000000..5c9dff1 --- /dev/null +++ b/FMOD/api/core/examples/net_stream.cpp @@ -0,0 +1,219 @@ +/*============================================================================== +Net Stream Example +Copyright (c), Firelight Technologies Pty, Ltd 2004-2026. + +This example shows how to play streaming audio from an Internet source + +For information on using FMOD example code in your own programs, visit +https://www.fmod.com/legal +==============================================================================*/ +#define COMMON_REQUIRE_NETWORK +#include "fmod.hpp" +#include "common.h" + +int FMOD_Main() +{ + FMOD::System *system = 0; + FMOD::Sound *sound = 0; + FMOD::Channel *channel = 0; + FMOD_RESULT result = FMOD_OK; + FMOD_OPENSTATE openstate = FMOD_OPENSTATE_READY; + void *extradriverdata = 0; + const int tagcount = 4; + int tagindex = 0; + char tagstring[tagcount][128] = { }; + + Common_Init(&extradriverdata); + + /* + Create a System object and initialize. + */ + result = FMOD::System_Create(&system); + ERRCHECK(result); + + result = system->init(1, FMOD_INIT_NORMAL, extradriverdata); + ERRCHECK(result); + + /* Increase the file buffer size a little bit to account for Internet lag. */ + result = system->setStreamBufferSize(64*1024, FMOD_TIMEUNIT_RAWBYTES); + ERRCHECK(result); + + FMOD_CREATESOUNDEXINFO exinfo; + memset(&exinfo, 0, sizeof(FMOD_CREATESOUNDEXINFO)); + exinfo.cbsize = sizeof(FMOD_CREATESOUNDEXINFO); + exinfo.filebuffersize = 1024*16; /* Increase the default file chunk size to handle seeking inside large playlist files that may be over 2kb. */ + + result = system->createSound("https://stream.live.vc.bbcmedia.co.uk/bbc_world_service", FMOD_CREATESTREAM | FMOD_NONBLOCKING, &exinfo, &sound); + ERRCHECK(result); + + /* + Main loop + */ + do + { + unsigned int pos = 0; + unsigned int percent = 0; + bool playing = false; + bool paused = false; + bool starving = false; + const char *state = "Stopped"; + + Common_Update(); + + if (Common_BtnPress(BTN_ACTION1)) + { + if (channel) + { + bool paused = false; + + result = channel->getPaused(&paused); + ERRCHECK(result); + result = channel->setPaused(!paused); + ERRCHECK(result); + } + } + + result = system->update(); + ERRCHECK(result); + + result = sound->getOpenState(&openstate, &percent, &starving, 0); + ERRCHECK(result); + + { + FMOD_TAG tag; + + /* + Read any tags that have arrived, this could happen if a radio station switches + to a new song. + */ + while (sound->getTag(0, -1, &tag) == FMOD_OK) + { + if (tag.datatype == FMOD_TAGDATATYPE_STRING) + { + snprintf(tagstring[tagindex], 128, "%s = '%s' (%d bytes)", tag.name, (char *)tag.data, tag.datalen); + tagindex = (tagindex + 1) % tagcount; + + if (tag.type == FMOD_TAGTYPE_PLAYLIST && !strcmp(tag.name, "FILE")) + { + char url[256] = {}; + + strncpy(url, (const char *)tag.data, 255); /* data point to sound owned memory, copy it before the sound is released. */ + + result = sound->release(); + ERRCHECK(result); + + result = system->createSound(url, FMOD_CREATESTREAM | FMOD_NONBLOCKING, &exinfo, &sound); + ERRCHECK(result); + } + + } + else if (tag.type == FMOD_TAGTYPE_FMOD) + { + /* When a song changes, the sample rate may also change, so compensate here. */ + if (!strcmp(tag.name, "Sample Rate Change") && channel) + { + float frequency = *((float *)tag.data); + + result = channel->setFrequency(frequency); + ERRCHECK(result); + } + } + } + } + + if (channel) + { + result = channel->getPaused(&paused); + ERRCHECK(result); + + result = channel->isPlaying(&playing); + ERRCHECK(result); + + result = channel->getPosition(&pos, FMOD_TIMEUNIT_MS); + ERRCHECK(result); + + /* Silence the stream until we have sufficient data for smooth playback. */ + result = channel->setMute(starving); + ERRCHECK(result); + } + else + { + /* This may fail if the stream isn't ready yet, so don't check the error code. */ + system->playSound(sound, 0, false, &channel); + } + + if (openstate == FMOD_OPENSTATE_BUFFERING) + { + state = "Buffering..."; + } + else if (openstate == FMOD_OPENSTATE_CONNECTING) + { + state = "Connecting..."; + } + else if (paused) + { + state = "Paused"; + } + else if (playing) + { + state = "Playing"; + } + + Common_Draw("=================================================="); + Common_Draw("Net Stream Example."); + Common_Draw("Copyright (c) Firelight Technologies 2004-2026."); + Common_Draw("=================================================="); + Common_Draw(""); + Common_Draw("Press %s to toggle pause", Common_BtnStr(BTN_ACTION1)); + Common_Draw("Press %s to quit", Common_BtnStr(BTN_QUIT)); + Common_Draw(""); + Common_Draw("Time = %02d:%02d:%02d", pos / 1000 / 60, pos / 1000 % 60, pos / 10 % 100); + Common_Draw("State = %s %s", state, starving ? "(STARVING)" : ""); + Common_Draw("Buffer Percentage = %d", percent); + Common_Draw(""); + Common_Draw("Tags:"); + for (int i = tagindex; i < (tagindex + tagcount); i++) + { + Common_Draw("%s", tagstring[i % tagcount]); + Common_Draw(""); + } + + Common_Sleep(50); + } while (!Common_BtnPress(BTN_QUIT)); + + /* + Stop the channel, then wait for it to finish opening before we release it. + */ + if (channel) + { + result = channel->stop(); + ERRCHECK(result); + } + + do + { + Common_Update(); + Common_Draw("Waiting for sound to finish opening before trying to release it....", Common_BtnStr(BTN_ACTION1)); + Common_Sleep(50); + + result = system->update(); + ERRCHECK(result); + + result = sound->getOpenState(&openstate, 0, 0, 0); + ERRCHECK(result); + } while (openstate != FMOD_OPENSTATE_READY); + + /* + Shut down + */ + result = sound->release(); + ERRCHECK(result); + result = system->close(); + ERRCHECK(result); + result = system->release(); + ERRCHECK(result); + + Common_Close(); + + return 0; +} diff --git a/FMOD/api/core/examples/play_sound.cpp b/FMOD/api/core/examples/play_sound.cpp new file mode 100644 index 0000000..95ccc20 --- /dev/null +++ b/FMOD/api/core/examples/play_sound.cpp @@ -0,0 +1,152 @@ +/*============================================================================== +Play Sound Example +Copyright (c), Firelight Technologies Pty, Ltd 2004-2026. + +This example shows how to simply load and play multiple sounds, the simplest +usage of FMOD. By default FMOD will decode the entire file into memory when it +loads. If the sounds are big and possibly take up a lot of RAM it would be +better to use the FMOD_CREATESTREAM flag, this will stream the file in realtime +as it plays. + +For information on using FMOD example code in your own programs, visit +https://www.fmod.com/legal +==============================================================================*/ +#include "fmod.hpp" +#include "common.h" + +int FMOD_Main() +{ + FMOD::System *system; + FMOD::Sound *sound1, *sound2, *sound3; + FMOD::Channel *channel = 0; + FMOD_RESULT result; + void *extradriverdata = 0; + + Common_Init(&extradriverdata); + + /* + Create a System object and initialize + */ + result = FMOD::System_Create(&system); + ERRCHECK(result); + + result = system->init(32, FMOD_INIT_NORMAL, extradriverdata); + ERRCHECK(result); + + result = system->createSound(Common_MediaPath("drumloop.wav"), FMOD_DEFAULT, 0, &sound1); + ERRCHECK(result); + + result = sound1->setMode(FMOD_LOOP_OFF); /* drumloop.wav has embedded loop points which automatically makes looping turn on, */ + ERRCHECK(result); /* so turn it off here. We could have also just put FMOD_LOOP_OFF in the above CreateSound call. */ + + result = system->createSound(Common_MediaPath("jaguar.wav"), FMOD_DEFAULT, 0, &sound2); + ERRCHECK(result); + + result = system->createSound(Common_MediaPath("swish.wav"), FMOD_DEFAULT, 0, &sound3); + ERRCHECK(result); + + /* + Main loop + */ + do + { + Common_Update(); + + if (Common_BtnPress(BTN_ACTION1)) + { + result = system->playSound(sound1, 0, false, &channel); + ERRCHECK(result); + } + + if (Common_BtnPress(BTN_ACTION2)) + { + result = system->playSound(sound2, 0, false, &channel); + ERRCHECK(result); + } + + if (Common_BtnPress(BTN_ACTION3)) + { + result = system->playSound(sound3, 0, false, &channel); + ERRCHECK(result); + } + + result = system->update(); + ERRCHECK(result); + + { + unsigned int ms = 0; + unsigned int lenms = 0; + bool playing = 0; + bool paused = 0; + int channelsplaying = 0; + + if (channel) + { + FMOD::Sound *currentsound = 0; + + result = channel->isPlaying(&playing); + if ((result != FMOD_OK) && (result != FMOD_ERR_INVALID_HANDLE) && (result != FMOD_ERR_CHANNEL_STOLEN)) + { + ERRCHECK(result); + } + + result = channel->getPaused(&paused); + if ((result != FMOD_OK) && (result != FMOD_ERR_INVALID_HANDLE) && (result != FMOD_ERR_CHANNEL_STOLEN)) + { + ERRCHECK(result); + } + + result = channel->getPosition(&ms, FMOD_TIMEUNIT_MS); + if ((result != FMOD_OK) && (result != FMOD_ERR_INVALID_HANDLE) && (result != FMOD_ERR_CHANNEL_STOLEN)) + { + ERRCHECK(result); + } + + channel->getCurrentSound(¤tsound); + if (currentsound) + { + result = currentsound->getLength(&lenms, FMOD_TIMEUNIT_MS); + if ((result != FMOD_OK) && (result != FMOD_ERR_INVALID_HANDLE) && (result != FMOD_ERR_CHANNEL_STOLEN)) + { + ERRCHECK(result); + } + } + } + + system->getChannelsPlaying(&channelsplaying, NULL); + + Common_Draw("=================================================="); + Common_Draw("Play Sound Example."); + Common_Draw("Copyright (c) Firelight Technologies 2004-2026."); + Common_Draw("=================================================="); + Common_Draw(""); + Common_Draw("Press %s to play a mono sound (drumloop)", Common_BtnStr(BTN_ACTION1)); + Common_Draw("Press %s to play a mono sound (jaguar)", Common_BtnStr(BTN_ACTION2)); + Common_Draw("Press %s to play a stereo sound (swish)", Common_BtnStr(BTN_ACTION3)); + Common_Draw("Press %s to quit", Common_BtnStr(BTN_QUIT)); + Common_Draw(""); + Common_Draw("Time %02d:%02d:%02d/%02d:%02d:%02d : %s", ms / 1000 / 60, ms / 1000 % 60, ms / 10 % 100, lenms / 1000 / 60, lenms / 1000 % 60, lenms / 10 % 100, paused ? "Paused " : playing ? "Playing" : "Stopped"); + Common_Draw("Channels Playing %d", channelsplaying); + } + + Common_Sleep(50); + } while (!Common_BtnPress(BTN_QUIT)); + + /* + Shut down + */ + result = sound1->release(); + ERRCHECK(result); + result = sound2->release(); + ERRCHECK(result); + result = sound3->release(); + ERRCHECK(result); + result = system->close(); + ERRCHECK(result); + result = system->release(); + ERRCHECK(result); + + Common_Close(); + + return 0; +} diff --git a/FMOD/api/core/examples/play_stream.cpp b/FMOD/api/core/examples/play_stream.cpp new file mode 100644 index 0000000..464b1c6 --- /dev/null +++ b/FMOD/api/core/examples/play_stream.cpp @@ -0,0 +1,143 @@ +/*============================================================================== +Play Stream Example +Copyright (c), Firelight Technologies Pty, Ltd 2004-2026. + +This example shows how to simply play a stream such as an MP3 or WAV. The stream +behaviour is achieved by specifying FMOD_CREATESTREAM in the call to +System::createSound. This makes FMOD decode the file in realtime as it plays, +instead of loading it all at once which uses far less memory in exchange for a +small runtime CPU hit. + +For information on using FMOD example code in your own programs, visit +https://www.fmod.com/legal +==============================================================================*/ +#include "fmod.hpp" +#include "common.h" + +int FMOD_Main() +{ + FMOD::System *system; + FMOD::Sound *sound, *sound_to_play; + FMOD::Channel *channel = 0; + FMOD_RESULT result; + void *extradriverdata = 0; + int numsubsounds; + + Common_Init(&extradriverdata); + + /* + Create a System object and initialize. + */ + result = FMOD::System_Create(&system); + ERRCHECK(result); + + result = system->init(32, FMOD_INIT_NORMAL, extradriverdata); + ERRCHECK(result); + + /* + This example uses an FSB file, which is a preferred pack format for fmod containing multiple sounds. + This could just as easily be exchanged with a wav/mp3/ogg file for example, but in this case you wouldnt need to call getSubSound. + Because getNumSubSounds is called here the example would work with both types of sound file (packed vs single). + */ + result = system->createStream(Common_MediaPath("wave_vorbis.fsb"), FMOD_LOOP_NORMAL | FMOD_2D, 0, &sound); + ERRCHECK(result); + + result = sound->getNumSubSounds(&numsubsounds); + ERRCHECK(result); + + if (numsubsounds) + { + sound->getSubSound(0, &sound_to_play); + ERRCHECK(result); + } + else + { + sound_to_play = sound; + } + + /* + Play the sound. + */ + result = system->playSound(sound_to_play, 0, false, &channel); + ERRCHECK(result); + + /* + Main loop. + */ + do + { + Common_Update(); + + if (Common_BtnPress(BTN_ACTION1)) + { + bool paused; + result = channel->getPaused(&paused); + ERRCHECK(result); + result = channel->setPaused(!paused); + ERRCHECK(result); + } + + result = system->update(); + ERRCHECK(result); + + { + unsigned int ms = 0; + unsigned int lenms = 0; + bool playing = false; + bool paused = false; + + if (channel) + { + result = channel->isPlaying(&playing); + if ((result != FMOD_OK) && (result != FMOD_ERR_INVALID_HANDLE)) + { + ERRCHECK(result); + } + + result = channel->getPaused(&paused); + if ((result != FMOD_OK) && (result != FMOD_ERR_INVALID_HANDLE)) + { + ERRCHECK(result); + } + + result = channel->getPosition(&ms, FMOD_TIMEUNIT_MS); + if ((result != FMOD_OK) && (result != FMOD_ERR_INVALID_HANDLE)) + { + ERRCHECK(result); + } + + result = sound_to_play->getLength(&lenms, FMOD_TIMEUNIT_MS); + if ((result != FMOD_OK) && (result != FMOD_ERR_INVALID_HANDLE)) + { + ERRCHECK(result); + } + } + + Common_Draw("=================================================="); + Common_Draw("Play Stream Example."); + Common_Draw("Copyright (c) Firelight Technologies 2004-2026."); + Common_Draw("=================================================="); + Common_Draw(""); + Common_Draw("Press %s to toggle pause", Common_BtnStr(BTN_ACTION1)); + Common_Draw("Press %s to quit", Common_BtnStr(BTN_QUIT)); + Common_Draw(""); + Common_Draw("Time %02d:%02d:%02d/%02d:%02d:%02d : %s", ms / 1000 / 60, ms / 1000 % 60, ms / 10 % 100, lenms / 1000 / 60, lenms / 1000 % 60, lenms / 10 % 100, paused ? "Paused " : playing ? "Playing" : "Stopped"); + } + + Common_Sleep(50); + } while (!Common_BtnPress(BTN_QUIT)); + + /* + Shut down + */ + result = sound->release(); /* Release the parent, not the sound that was retrieved with getSubSound. */ + ERRCHECK(result); + result = system->close(); + ERRCHECK(result); + result = system->release(); + ERRCHECK(result); + + Common_Close(); + + return 0; +} diff --git a/FMOD/api/core/examples/plugins/BladeMP3EncDLL.h b/FMOD/api/core/examples/plugins/BladeMP3EncDLL.h new file mode 100644 index 0000000..c99f8b0 --- /dev/null +++ b/FMOD/api/core/examples/plugins/BladeMP3EncDLL.h @@ -0,0 +1,278 @@ +/* + * Blade Type of DLL Interface for Lame encoder + * + * Copyright (c) 1999-2002 A.L. Faber + * Based on bladedll.h version 1.0 written by Jukka Poikolainen + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#pragma once + +#ifdef __GNUC__ +#define ATTRIBUTE_PACKED __attribute__((packed)) +#else +#define ATTRIBUTE_PACKED +#pragma pack(push) +#pragma pack(1) +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +/* encoding formats */ + +#define BE_CONFIG_MP3 0 +#define BE_CONFIG_LAME 256 + +/* type definitions */ + +typedef void* HBE_STREAM; +typedef HBE_STREAM *PHBE_STREAM; +typedef unsigned long BE_ERR; + +/* error codes */ + +#define BE_ERR_SUCCESSFUL 0x00000000 +#define BE_ERR_INVALID_FORMAT 0x00000001 +#define BE_ERR_INVALID_FORMAT_PARAMETERS 0x00000002 +#define BE_ERR_NO_MORE_HANDLES 0x00000003 +#define BE_ERR_INVALID_HANDLE 0x00000004 +#define BE_ERR_BUFFER_TOO_SMALL 0x00000005 + +/* other constants */ + +#define BE_MAX_HOMEPAGE 128 + +/* format specific variables */ + +#define BE_MP3_MODE_STEREO 0 +#define BE_MP3_MODE_JSTEREO 1 +#define BE_MP3_MODE_DUALCHANNEL 2 +#define BE_MP3_MODE_MONO 3 + + + +#define MPEG1 1 +#define MPEG2 0 + +#ifdef _BLADEDLL +#undef FLOAT + #include +#endif + +#define CURRENT_STRUCT_VERSION 1 +#define CURRENT_STRUCT_SIZE sizeof(BE_CONFIG) // is currently 331 bytes + + +typedef enum +{ + VBR_METHOD_NONE = -1, + VBR_METHOD_DEFAULT = 0, + VBR_METHOD_OLD = 1, + VBR_METHOD_NEW = 2, + VBR_METHOD_MTRH = 3, + VBR_METHOD_ABR = 4 +} VBRMETHOD; + +typedef enum +{ + LQP_NOPRESET =-1, + + // QUALITY PRESETS + LQP_NORMAL_QUALITY = 0, + LQP_LOW_QUALITY = 1, + LQP_HIGH_QUALITY = 2, + LQP_VOICE_QUALITY = 3, + LQP_R3MIX = 4, + LQP_VERYHIGH_QUALITY = 5, + LQP_STANDARD = 6, + LQP_FAST_STANDARD = 7, + LQP_EXTREME = 8, + LQP_FAST_EXTREME = 9, + LQP_INSANE = 10, + LQP_ABR = 11, + LQP_CBR = 12, + LQP_MEDIUM = 13, + LQP_FAST_MEDIUM = 14, + + // NEW PRESET VALUES + LQP_PHONE =1000, + LQP_SW =2000, + LQP_AM =3000, + LQP_FM =4000, + LQP_VOICE =5000, + LQP_RADIO =6000, + LQP_TAPE =7000, + LQP_HIFI =8000, + LQP_CD =9000, + LQP_STUDIO =10000 + +} LAME_QUALITY_PRESET; + + + +typedef struct { + DWORD dwConfig; // BE_CONFIG_XXXXX + // Currently only BE_CONFIG_MP3 is supported + union { + + struct { + + DWORD dwSampleRate; // 48000, 44100 and 32000 allowed + BYTE byMode; // BE_MP3_MODE_STEREO, BE_MP3_MODE_DUALCHANNEL, BE_MP3_MODE_MONO + WORD wBitrate; // 32, 40, 48, 56, 64, 80, 96, 112, 128, 160, 192, 224, 256 and 320 allowed + BOOL bPrivate; + BOOL bCRC; + BOOL bCopyright; + BOOL bOriginal; + + } mp3; // BE_CONFIG_MP3 + + struct + { + // STRUCTURE INFORMATION + DWORD dwStructVersion; + DWORD dwStructSize; + + // BASIC ENCODER SETTINGS + DWORD dwSampleRate; // SAMPLERATE OF INPUT FILE + DWORD dwReSampleRate; // DOWNSAMPLERATE, 0=ENCODER DECIDES + LONG nMode; // BE_MP3_MODE_STEREO, BE_MP3_MODE_DUALCHANNEL, BE_MP3_MODE_MONO + DWORD dwBitrate; // CBR bitrate, VBR min bitrate + DWORD dwMaxBitrate; // CBR ignored, VBR Max bitrate + LONG nPreset; // Quality preset, use one of the settings of the LAME_QUALITY_PRESET enum + DWORD dwMpegVersion; // FUTURE USE, MPEG-1 OR MPEG-2 + DWORD dwPsyModel; // FUTURE USE, SET TO 0 + DWORD dwEmphasis; // FUTURE USE, SET TO 0 + + // BIT STREAM SETTINGS + BOOL bPrivate; // Set Private Bit (TRUE/FALSE) + BOOL bCRC; // Insert CRC (TRUE/FALSE) + BOOL bCopyright; // Set Copyright Bit (TRUE/FALSE) + BOOL bOriginal; // Set Original Bit (TRUE/FALSE) + + // VBR STUFF + BOOL bWriteVBRHeader; // WRITE XING VBR HEADER (TRUE/FALSE) + BOOL bEnableVBR; // USE VBR ENCODING (TRUE/FALSE) + INT nVBRQuality; // VBR QUALITY 0..9 + DWORD dwVbrAbr_bps; // Use ABR in stead of nVBRQuality + VBRMETHOD nVbrMethod; + BOOL bNoRes; // Disable Bit resorvoir (TRUE/FALSE) + + // MISC SETTINGS + BOOL bStrictIso; // Use strict ISO encoding rules (TRUE/FALSE) + WORD nQuality; // Quality Setting, HIGH BYTE should be NOT LOW byte, otherwhise quality=5 + + // FUTURE USE, SET TO 0, align strucutre to 331 bytes + BYTE btReserved[255-4*sizeof(DWORD) - sizeof( WORD )]; + + } LHV1; // LAME header version 1 + + struct { + + DWORD dwSampleRate; + BYTE byMode; + WORD wBitrate; + BYTE byEncodingMethod; + + } aac; + + } format; + +} BE_CONFIG, *PBE_CONFIG ATTRIBUTE_PACKED; + + +typedef struct { + + // BladeEnc DLL Version number + + BYTE byDLLMajorVersion; + BYTE byDLLMinorVersion; + + // BladeEnc Engine Version Number + + BYTE byMajorVersion; + BYTE byMinorVersion; + + // DLL Release date + + BYTE byDay; + BYTE byMonth; + WORD wYear; + + // BladeEnc Homepage URL + + CHAR zHomepage[BE_MAX_HOMEPAGE + 1]; + + BYTE byAlphaLevel; + BYTE byBetaLevel; + BYTE byMMXEnabled; + + BYTE btReserved[125]; + + +} BE_VERSION, *PBE_VERSION ATTRIBUTE_PACKED; + +#ifndef _BLADEDLL + +typedef BE_ERR (*BEINITSTREAM) (PBE_CONFIG, PDWORD, PDWORD, PHBE_STREAM); +typedef BE_ERR (*BEENCODECHUNK) (HBE_STREAM, DWORD, PSHORT, PBYTE, PDWORD); + +// added for floating point audio -- DSPguru, jd +typedef BE_ERR (*BEENCODECHUNKFLOATS16NI) (HBE_STREAM, DWORD, PFLOAT, PFLOAT, PBYTE, PDWORD); +typedef BE_ERR (*BEDEINITSTREAM) (HBE_STREAM, PBYTE, PDWORD); +typedef BE_ERR (*BECLOSESTREAM) (HBE_STREAM); +typedef VOID (*BEVERSION) (PBE_VERSION); +typedef BE_ERR (*BEWRITEVBRHEADER) (LPCSTR); +typedef BE_ERR (*BEWRITEINFOTAG) (HBE_STREAM, LPCSTR ); + +#define TEXT_BEINITSTREAM "beInitStream" +#define TEXT_BEENCODECHUNK "beEncodeChunk" +#define TEXT_BEENCODECHUNKFLOATS16NI "beEncodeChunkFloatS16NI" +#define TEXT_BEDEINITSTREAM "beDeinitStream" +#define TEXT_BECLOSESTREAM "beCloseStream" +#define TEXT_BEVERSION "beVersion" +#define TEXT_BEWRITEVBRHEADER "beWriteVBRHeader" +#define TEXT_BEFLUSHNOGAP "beFlushNoGap" +#define TEXT_BEWRITEINFOTAG "beWriteInfoTag" + + +#else + +__declspec(dllexport) BE_ERR beInitStream(PBE_CONFIG pbeConfig, PDWORD dwSamples, PDWORD dwBufferSize, PHBE_STREAM phbeStream); +__declspec(dllexport) BE_ERR beEncodeChunk(HBE_STREAM hbeStream, DWORD nSamples, PSHORT pSamples, PBYTE pOutput, PDWORD pdwOutput); + +// added for floating point audio -- DSPguru, jd +__declspec(dllexport) BE_ERR beEncodeChunkFloatS16NI(HBE_STREAM hbeStream, DWORD nSamples, PFLOAT buffer_l, PFLOAT buffer_r, PBYTE pOutput, PDWORD pdwOutput); +__declspec(dllexport) BE_ERR beDeinitStream(HBE_STREAM hbeStream, PBYTE pOutput, PDWORD pdwOutput); +__declspec(dllexport) BE_ERR beCloseStream(HBE_STREAM hbeStream); +__declspec(dllexport) VOID beVersion(PBE_VERSION pbeVersion); +__declspec(dllexport) BE_ERR beWriteVBRHeader(LPCSTR lpszFileName); +__declspec(dllexport) BE_ERR beFlushNoGap(HBE_STREAM hbeStream, PBYTE pOutput, PDWORD pdwOutput); +__declspec(dllexport) BE_ERR beWriteInfoTag( HBE_STREAM hbeStream, LPCSTR lpszFileName ); + +#endif + +#ifdef __cplusplus +} +#endif + +#ifndef __GNUC__ +#pragma pack(pop) +#endif + diff --git a/FMOD/api/core/examples/plugins/fmod_codec_raw.cpp b/FMOD/api/core/examples/plugins/fmod_codec_raw.cpp new file mode 100644 index 0000000..a7662af --- /dev/null +++ b/FMOD/api/core/examples/plugins/fmod_codec_raw.cpp @@ -0,0 +1,133 @@ +/*=============================================================================================== +Raw Codec Plugin Example +Copyright (c), Firelight Technologies Pty, Ltd 2004-2026. + +This example shows how to create a codec that reads raw PCM data. + +1. The codec can be compiled as a DLL, using the reserved function name 'FMODGetCodecDescription' + as the only export symbol, and at runtime, the dll can be loaded in with System::loadPlugin. + +2. Alternatively a codec of this type can be compiled directly into the program that uses it, and + you just register the codec into FMOD with System::registerCodec. This puts the codec into + the FMOD system, just the same way System::loadPlugin would if it was an external file. + +3. The 'open' callback is the first thing called, and FMOD already has a file handle open for it. + In the open callback you can use FMOD_CODEC_STATE::fileread / FMOD_CODEC_STATE::fileseek to parse + your own file format, and return FMOD_ERR_FORMAT if it is not the format you support. Return + FMOD_OK if it succeeds your format test. + +4. When an FMOD user calls System::createSound or System::createStream, the 'open' callback is called + once after FMOD tries to open it as many other types of file. If you want to override FMOD's + internal codecs then use the 'priority' parameter of System::loadPlugin or System::registerCodec. + +5. In the open callback, tell FMOD what sort of PCM format the sound will produce with the + FMOD_CODEC_STATE::waveformat member. + +6. The 'close' callback is called when Sound::release is called by the FMOD user. + +7. The 'read' callback is called when System::createSound or System::createStream wants to receive + PCM data, in the format that you specified with FMOD_CODEC_STATE::waveformat. Data is + interleaved as decribed in the terminology section of the FMOD API documentation. + When a stream is being used, the read callback will be called repeatedly, using a size value + determined by the decode buffer size of the stream. See FMOD_CREATESOUNDEXINFO or + FMOD_ADVANCEDSETTINGS. + +8. The 'seek' callback is called when Channel::setPosition is called, or when looping a sound + when it is a stream. + +===============================================================================================*/ + +#include + +#include "fmod.h" + +FMOD_RESULT F_CALL rawopen(FMOD_CODEC_STATE *codec, FMOD_MODE usermode, FMOD_CREATESOUNDEXINFO *userexinfo); +FMOD_RESULT F_CALL rawclose(FMOD_CODEC_STATE *codec); +FMOD_RESULT F_CALL rawread(FMOD_CODEC_STATE *codec, void *buffer, unsigned int size, unsigned int *read); +FMOD_RESULT F_CALL rawsetposition(FMOD_CODEC_STATE *codec, int subsound, unsigned int position, FMOD_TIMEUNIT postype); + +FMOD_CODEC_DESCRIPTION rawcodec = +{ + FMOD_CODEC_PLUGIN_VERSION, // Plugin version. + "FMOD Raw player plugin example", // Name. + 0x00010000, // Version 0xAAAABBBB A = major, B = minor. + 0, // Don't force everything using this codec to be a stream + FMOD_TIMEUNIT_PCMBYTES, // The time format we would like to accept into setposition/getposition. + &rawopen, // Open callback. + &rawclose, // Close callback. + &rawread, // Read callback. + 0, // Getlength callback. (If not specified FMOD return the length in FMOD_TIMEUNIT_PCM, FMOD_TIMEUNIT_MS or FMOD_TIMEUNIT_PCMBYTES units based on the lengthpcm member of the FMOD_CODEC structure). + &rawsetposition, // Setposition callback. + 0, // Getposition callback. (only used for timeunit types that are not FMOD_TIMEUNIT_PCM, FMOD_TIMEUNIT_MS and FMOD_TIMEUNIT_PCMBYTES). + 0 // Sound create callback (don't need it) +}; + + +/* + FMODGetCodecDescription is mandatory for every fmod plugin. This is the symbol the registerplugin function searches for. + Must be declared with F_CALL to make it export as stdcall. + MUST BE EXTERN'ED AS C! C++ functions will be mangled incorrectly and not load in fmod. +*/ +#ifdef __cplusplus +extern "C" { +#endif + +F_EXPORT FMOD_CODEC_DESCRIPTION * F_CALL FMODGetCodecDescription() +{ + return &rawcodec; +} + +#ifdef __cplusplus +} +#endif + + +static FMOD_CODEC_WAVEFORMAT rawwaveformat; + +/* + The actual codec code. + + Note that the callbacks uses FMOD's supplied file system callbacks. + + This is important as even though you might want to open the file yourself, you would lose the following benefits. + 1. Automatic support of memory files, CDDA based files, and HTTP/TCPIP based files. + 2. "fileoffset" / "length" support when user calls System::createSound with FMOD_CREATESOUNDEXINFO structure. + 3. Buffered file access. + FMOD files are high level abstracts that support all sorts of 'file', they are not just disk file handles. + If you want FMOD to use your own filesystem (and potentially lose the above benefits) use System::setFileSystem. +*/ + +FMOD_RESULT F_CALL rawopen(FMOD_CODEC_STATE *codec, FMOD_MODE /*usermode*/, FMOD_CREATESOUNDEXINFO * /*userexinfo*/) +{ + rawwaveformat.channels = 2; + rawwaveformat.format = FMOD_SOUND_FORMAT_PCM16; + rawwaveformat.frequency = 44100; + rawwaveformat.pcmblocksize = 0; + unsigned int size; + FMOD_CODEC_FILE_SIZE(codec, &size); + rawwaveformat.lengthpcm = size / (rawwaveformat.channels * sizeof(short)); /* bytes converted to PCM samples */; + + codec->numsubsounds = 0; /* number of 'subsounds' in this sound. For most codecs this is 0, only multi sound codecs such as FSB or CDDA have subsounds. */ + codec->waveformat = &rawwaveformat; + codec->plugindata = 0; /* user data value */ + + /* If your file format needs to read data to determine the format and load metadata, do so here with codec->fileread/fileseek function pointers. This will handle reading from disk/memory or internet. */ + + return FMOD_OK; +} + +FMOD_RESULT F_CALL rawclose(FMOD_CODEC_STATE * /*codec*/) +{ + return FMOD_OK; +} + +FMOD_RESULT F_CALL rawread(FMOD_CODEC_STATE *codec, void *buffer, unsigned int size, unsigned int *read) +{ + return FMOD_CODEC_FILE_READ(codec, buffer, size, read); +} + +FMOD_RESULT F_CALL rawsetposition(FMOD_CODEC_STATE *codec, int /*subsound*/, unsigned int position, FMOD_TIMEUNIT /*postype*/) +{ + return FMOD_CODEC_FILE_SEEK(codec, position, 0); +} + diff --git a/FMOD/api/core/examples/plugins/fmod_distance_filter.cpp b/FMOD/api/core/examples/plugins/fmod_distance_filter.cpp new file mode 100644 index 0000000..7c3c6e6 --- /dev/null +++ b/FMOD/api/core/examples/plugins/fmod_distance_filter.cpp @@ -0,0 +1,466 @@ +/*============================================================================== +Distance Filter DSP Plugin Example +Copyright (c), Firelight Technologies Pty, Ltd 2004-2026. + +This example shows how to create a distance filter DSP effect. +==============================================================================*/ + +#ifdef WIN32 + #define _CRT_SECURE_NO_WARNINGS +#endif + +#include +#include +#include + +#include "fmod.hpp" + +extern "C" +{ + F_EXPORT FMOD_DSP_DESCRIPTION* F_CALL FMODGetDSPDescription(); +} + +const float FMOD_DISTANCE_FILTER_PARAM_MAX_DISTANCE_MIN = 0.0f; +const float FMOD_DISTANCE_FILTER_PARAM_MAX_DISTANCE_MAX = 10000.0f; +const float FMOD_DISTANCE_FILTER_PARAM_MAX_DISTANCE_DEFAULT = 20.0f; +const float FMOD_DISTANCE_FILTER_PARAM_BANDPASS_FREQUENCY_MIN = 10.0f; +const float FMOD_DISTANCE_FILTER_PARAM_BANDPASS_FREQUENCY_MAX = 22000.0f; +const float FMOD_DISTANCE_FILTER_PARAM_BANDPASS_FREQUENCY_DEFAULT = 1500.0f; + +enum +{ + FMOD_DISTANCE_FILTER_MAX_DISTANCE, + FMOD_DISTANCE_FILTER_BANDPASS_FREQUENCY, + FMOD_DISTANCE_FILTER_3D_ATTRIBUTES, + FMOD_DISTANCE_FILTER_NUM_PARAMETERS +}; + +FMOD_RESULT F_CALL FMOD_DistanceFilter_dspcreate (FMOD_DSP_STATE *dsp_state); +FMOD_RESULT F_CALL FMOD_DistanceFilter_dsprelease (FMOD_DSP_STATE *dsp_state); +FMOD_RESULT F_CALL FMOD_DistanceFilter_dspreset (FMOD_DSP_STATE *dsp_state); +FMOD_RESULT F_CALL FMOD_DistanceFilter_dspread (FMOD_DSP_STATE *dsp_state, float *inbuffer, float *outbuffer, unsigned int length, int inchannels, int *outchannels); +FMOD_RESULT F_CALL FMOD_DistanceFilter_dspprocess (FMOD_DSP_STATE *dsp_state, unsigned int length, const FMOD_DSP_BUFFER_ARRAY *inbufferarray, FMOD_DSP_BUFFER_ARRAY *outbufferarray, FMOD_BOOL inputsidle, FMOD_DSP_PROCESS_OPERATION op); +FMOD_RESULT F_CALL FMOD_DistanceFilter_dspsetparamfloat(FMOD_DSP_STATE *dsp_state, int index, float value); +FMOD_RESULT F_CALL FMOD_DistanceFilter_dspsetparamint (FMOD_DSP_STATE *dsp_state, int index, int value); +FMOD_RESULT F_CALL FMOD_DistanceFilter_dspsetparambool (FMOD_DSP_STATE *dsp_state, int index, FMOD_BOOL value); +FMOD_RESULT F_CALL FMOD_DistanceFilter_dspsetparamdata (FMOD_DSP_STATE *dsp_state, int index, void *data, unsigned int length); +FMOD_RESULT F_CALL FMOD_DistanceFilter_dspgetparamfloat(FMOD_DSP_STATE *dsp_state, int index, float *value, char *valuestr); +FMOD_RESULT F_CALL FMOD_DistanceFilter_dspgetparamint (FMOD_DSP_STATE *dsp_state, int index, int *value, char *valuestr); +FMOD_RESULT F_CALL FMOD_DistanceFilter_dspgetparambool (FMOD_DSP_STATE *dsp_state, int index, FMOD_BOOL *value, char *valuestr); +FMOD_RESULT F_CALL FMOD_DistanceFilter_dspgetparamdata (FMOD_DSP_STATE *dsp_state, int index, void **value, unsigned int *length, char *valuestr); +FMOD_RESULT F_CALL FMOD_DistanceFilter_shouldiprocess (FMOD_DSP_STATE *dsp_state, FMOD_BOOL inputsidle, unsigned int length, FMOD_CHANNELMASK inmask, int inchannels, FMOD_SPEAKERMODE speakermode); + +static FMOD_DSP_PARAMETER_DESC p_max_distance; +static FMOD_DSP_PARAMETER_DESC p_bandpass_frequency; +static FMOD_DSP_PARAMETER_DESC p_3d_attributes; + +FMOD_DSP_PARAMETER_DESC *FMOD_DistanceFilter_dspparam[FMOD_DISTANCE_FILTER_NUM_PARAMETERS] = +{ + &p_max_distance, + &p_bandpass_frequency, + &p_3d_attributes +}; + +FMOD_DSP_DESCRIPTION FMOD_DistanceFilter_Desc = +{ + FMOD_PLUGIN_SDK_VERSION, + "FMOD Distance Filter", // name + 0x00010000, // plugin version + 1, // number of input buffers to process + 1, // number of output buffers to process + FMOD_DistanceFilter_dspcreate, + FMOD_DistanceFilter_dsprelease, + FMOD_DistanceFilter_dspreset, + FMOD_DistanceFilter_dspread, + 0, // FMOD_DistanceFilter_dspprocess, // *** declare this callback instead of FMOD_DistanceFilter_dspread if the plugin sets the output channel count *** + 0, + FMOD_DISTANCE_FILTER_NUM_PARAMETERS, + FMOD_DistanceFilter_dspparam, + FMOD_DistanceFilter_dspsetparamfloat, + 0, // FMOD_DistanceFilter_dspsetparamint, + 0, // FMOD_DistanceFilter_dspsetparambool, + FMOD_DistanceFilter_dspsetparamdata, + FMOD_DistanceFilter_dspgetparamfloat, + 0, // FMOD_DistanceFilter_dspgetparamint, + 0, // FMOD_DistanceFilter_dspgetparambool, + FMOD_DistanceFilter_dspgetparamdata, + FMOD_DistanceFilter_shouldiprocess, + 0, // userdata + 0, // sys_register + 0, // sys_deregister + 0 // sys_mix +}; + +extern "C" +{ + F_EXPORT FMOD_DSP_DESCRIPTION* F_CALL FMODGetDSPDescription() + { + static float distance_mapping_values[] = { 0, 1, 5, 20, 100, 500, 10000 }; + static float distance_mapping_scale[] = { 0, 1, 2, 3, 4, 4.5, 5 }; + + FMOD_DSP_INIT_PARAMDESC_FLOAT_WITH_MAPPING(p_max_distance, "Max Dist", "", "Distance at which bandpass stops narrowing. 0 to 1000000000. Default = 100", FMOD_DISTANCE_FILTER_PARAM_MAX_DISTANCE_DEFAULT, distance_mapping_values, distance_mapping_scale); + FMOD_DSP_INIT_PARAMDESC_FLOAT(p_bandpass_frequency, "Frequency", "Hz", "Bandpass target frequency. 100 to 10,000Hz. Default = 2000Hz", FMOD_DISTANCE_FILTER_PARAM_BANDPASS_FREQUENCY_MIN, FMOD_DISTANCE_FILTER_PARAM_BANDPASS_FREQUENCY_MAX, FMOD_DISTANCE_FILTER_PARAM_BANDPASS_FREQUENCY_DEFAULT); + FMOD_DSP_INIT_PARAMDESC_DATA(p_3d_attributes, "3D Attributes", "", "", FMOD_DSP_PARAMETER_DATA_TYPE_3DATTRIBUTES); + + return &FMOD_DistanceFilter_Desc; + } +} + +class FMODDistanceFilterState +{ + public: + FMODDistanceFilterState() { } + + void init (FMOD_DSP_STATE *dsp_state); + void release (FMOD_DSP_STATE *dsp_state); + FMOD_RESULT process (float *inbuffer, float *outbuffer, unsigned int length, int channels); + FMOD_RESULT process (unsigned int length, const FMOD_DSP_BUFFER_ARRAY *inbufferarray, FMOD_DSP_BUFFER_ARRAY *outbufferarray, FMOD_BOOL inputsidle, FMOD_DSP_PROCESS_OPERATION op); + void reset (); + void setMaxDistance (float); + void setBandpassFrequency(float); + void setDistance (float); + float maxDistance () const { return m_max_distance; } + float bandpassFrequency () const { return m_bandpass_frequency; } + + private: + void updateTimeConstants (); + + float m_max_distance; + float m_bandpass_frequency; + float m_distance; + float m_target_highpass_time_const; + float m_current_highpass_time_const; + float m_target_lowpass_time_const; + float m_current_lowpass_time_const; + int m_ramp_samples_left; + float *m_previous_lp1_out; + float *m_previous_lp2_out; + float *m_previous_hp_out; + int m_sample_rate; + int m_max_channels; +}; + +void FMODDistanceFilterState::init(FMOD_DSP_STATE *dsp_state) +{ + FMOD_DSP_GETSAMPLERATE(dsp_state, &m_sample_rate); + + m_max_channels = 8; + m_max_distance = FMOD_DISTANCE_FILTER_PARAM_MAX_DISTANCE_DEFAULT; + m_bandpass_frequency = FMOD_DISTANCE_FILTER_PARAM_BANDPASS_FREQUENCY_DEFAULT; + m_distance = 0; + + m_previous_lp1_out = (float*)FMOD_DSP_ALLOC(dsp_state, m_max_channels * sizeof(float)); + m_previous_lp2_out = (float*)FMOD_DSP_ALLOC(dsp_state, m_max_channels * sizeof(float)); + m_previous_hp_out = (float*)FMOD_DSP_ALLOC(dsp_state, m_max_channels * sizeof(float)); + + updateTimeConstants(); + reset(); +} + +void FMODDistanceFilterState::release(FMOD_DSP_STATE *dsp_state) +{ + FMOD_DSP_FREE(dsp_state, m_previous_lp1_out); + FMOD_DSP_FREE(dsp_state, m_previous_lp2_out); + FMOD_DSP_FREE(dsp_state, m_previous_hp_out); +} + +FMOD_RESULT FMODDistanceFilterState::process(float *inbuffer, float *outbuffer, unsigned int length, int channels) +{ + if(channels > m_max_channels) + { + return FMOD_ERR_INVALID_PARAM; + } + + // Note: buffers are interleaved + static float jitter = (float)1E-20; + float lp1_out, lp2_out; + int ch; + + float lp_tc = m_current_lowpass_time_const; + float hp_tc = m_current_highpass_time_const; + + if (m_ramp_samples_left) + { + float lp_delta = (m_target_lowpass_time_const - m_current_lowpass_time_const) / m_ramp_samples_left; + float hp_delta = (m_target_highpass_time_const - m_current_highpass_time_const) / m_ramp_samples_left; + while (length) + { + if (--m_ramp_samples_left) + { + lp_tc += lp_delta; + hp_tc += hp_delta; + for (ch = 0; ch < channels; ++ch) + { + lp1_out = m_previous_lp1_out[ch] + lp_tc * (*inbuffer++ + jitter - m_previous_lp1_out[ch]); + lp2_out = m_previous_lp2_out[ch] + lp_tc * (lp1_out - m_previous_lp2_out[ch]); + *outbuffer = hp_tc * (m_previous_hp_out[ch] + lp2_out - m_previous_lp2_out[ch]); + + m_previous_lp1_out[ch] = lp1_out; + m_previous_lp2_out[ch] = lp2_out; + m_previous_hp_out[ch] = *outbuffer++; + } + jitter = -jitter; + } + else + { + lp_tc = m_target_lowpass_time_const; + hp_tc = m_target_highpass_time_const; + break; + } + --length; + } + } + + while (length--) + { + for (ch = 0; ch < channels; ++ch) + { + lp1_out = m_previous_lp1_out[ch] + lp_tc * (*inbuffer++ + jitter - m_previous_lp1_out[ch]); + lp2_out = m_previous_lp2_out[ch] + lp_tc * (lp1_out - m_previous_lp2_out[ch]); + *outbuffer = hp_tc * (m_previous_hp_out[ch] + lp2_out - m_previous_lp2_out[ch]); + + m_previous_lp1_out[ch] = lp1_out; + m_previous_lp2_out[ch] = lp2_out; + m_previous_hp_out[ch] = *outbuffer++; + } + jitter = -jitter; + } + + m_current_lowpass_time_const = lp_tc; + m_current_highpass_time_const = hp_tc; + + return FMOD_OK; +} + +FMOD_RESULT FMODDistanceFilterState::process(unsigned int length, const FMOD_DSP_BUFFER_ARRAY *inbufferarray, FMOD_DSP_BUFFER_ARRAY *outbufferarray, FMOD_BOOL inputsidle, FMOD_DSP_PROCESS_OPERATION op) +{ + if (op == FMOD_DSP_PROCESS_QUERY) + { + FMOD_SPEAKERMODE outmode; + int outchannels; + + #if 1 // For stereo output + { + outmode = FMOD_SPEAKERMODE_STEREO; + outchannels = 2; + } + #else // For 5.1 output + { + outmode = FMOD_SPEAKERMODE_5POINT1; + outchannels = 6; + } + #endif + + if (outbufferarray) + { + outbufferarray->speakermode = outmode; + outbufferarray->buffernumchannels[0] = outchannels; + } + + if (inputsidle) + { + return FMOD_ERR_DSP_DONTPROCESS; + } + + return FMOD_OK; + } + + // Do processing here + float *inbuffer = inbufferarray->buffers[0]; + float *outbuffer = outbufferarray->buffers[0]; + int inchannels = inbufferarray->buffernumchannels[0]; + int outchannels = outbufferarray->buffernumchannels[0]; + + while(length--) + { + // MAIN DSP LOOP... + } + + return FMOD_OK; +} + +void FMODDistanceFilterState::reset() +{ + m_current_lowpass_time_const = m_target_lowpass_time_const; + m_current_highpass_time_const = m_target_highpass_time_const; + m_ramp_samples_left = 0; + + memset(m_previous_lp1_out, 0, m_max_channels * sizeof(float)); + memset(m_previous_lp2_out, 0, m_max_channels * sizeof(float)); + memset(m_previous_hp_out, 0, m_max_channels * sizeof(float)); +} + +void FMODDistanceFilterState::setMaxDistance(float distance) +{ + m_max_distance = distance; + updateTimeConstants(); +} + +void FMODDistanceFilterState::setBandpassFrequency(float frequency) +{ + m_bandpass_frequency = frequency; + updateTimeConstants(); +} + +void FMODDistanceFilterState::setDistance(float distance) +{ + m_distance = distance; + updateTimeConstants(); +} + +void FMODDistanceFilterState::updateTimeConstants() +{ + #define PI (3.14159265358979323846f) + #define MIN_CUTOFF (10.0f) + #define MAX_CUTOFF (22000.0f) + + float dist_factor = m_distance >= m_max_distance ? 1.0f : m_distance / m_max_distance; + float lp_cutoff = m_bandpass_frequency + (1.0f - dist_factor) * (1.0f - dist_factor) * (MAX_CUTOFF - m_bandpass_frequency); + float hp_cutoff = MIN_CUTOFF + dist_factor * dist_factor * (m_bandpass_frequency - MIN_CUTOFF); + + float dt = 1.0f / m_sample_rate; + float threshold = m_sample_rate / PI; + + if (lp_cutoff >= MAX_CUTOFF) + { + m_target_lowpass_time_const = 1.0f; + } + else if (lp_cutoff <= threshold) + { + float RC = 1.0f / (2.0f * PI * lp_cutoff); + m_target_lowpass_time_const = dt / (RC + dt); + } + else + { + m_target_lowpass_time_const = 0.666666667f + (lp_cutoff - threshold) / (3.0f * (MAX_CUTOFF - threshold)); + } + + if (hp_cutoff >= MAX_CUTOFF) + { + m_target_highpass_time_const = 0.0f; + } + else if (hp_cutoff <= threshold) + { + float RC = 1.0f / (2.0f * PI * hp_cutoff); + m_target_highpass_time_const = RC / (RC + dt); + } + else + { + m_target_highpass_time_const = (MAX_CUTOFF - hp_cutoff) / (3.0f * (MAX_CUTOFF - threshold)); + } + + m_ramp_samples_left = 256; +} + +FMOD_RESULT F_CALL FMOD_DistanceFilter_dspcreate(FMOD_DSP_STATE *dsp_state) +{ + FMODDistanceFilterState* state = (FMODDistanceFilterState *)FMOD_DSP_ALLOC(dsp_state, sizeof(FMODDistanceFilterState)); + state->init(dsp_state); + dsp_state->plugindata = state; + if (!state) + { + return FMOD_ERR_MEMORY; + } + return FMOD_OK; +} + +FMOD_RESULT F_CALL FMOD_DistanceFilter_dsprelease(FMOD_DSP_STATE *dsp_state) +{ + FMODDistanceFilterState *state = (FMODDistanceFilterState *)dsp_state->plugindata; + state->release(dsp_state); + FMOD_DSP_FREE(dsp_state, state); + return FMOD_OK; +} + +FMOD_RESULT F_CALL FMOD_DistanceFilter_dspread(FMOD_DSP_STATE *dsp_state, float *inbuffer, float *outbuffer, unsigned int length, int inchannels, int * /*outchannels*/) +{ + FMODDistanceFilterState *state = (FMODDistanceFilterState *)dsp_state->plugindata; + return state->process(inbuffer, outbuffer, length, inchannels); // input and output channels count match for this effect +} + +FMOD_RESULT F_CALL FMOD_DistanceFilter_dspprocess(FMOD_DSP_STATE *dsp_state, unsigned int length, const FMOD_DSP_BUFFER_ARRAY *inbufferarray, FMOD_DSP_BUFFER_ARRAY *outbufferarray, FMOD_BOOL inputsidle, FMOD_DSP_PROCESS_OPERATION op) +{ + FMODDistanceFilterState *state = (FMODDistanceFilterState *)dsp_state->plugindata; + return state->process(length, inbufferarray, outbufferarray, inputsidle, op); // as an example for plugins which set the output channel count +} + +FMOD_RESULT F_CALL FMOD_DistanceFilter_dspreset(FMOD_DSP_STATE *dsp_state) +{ + FMODDistanceFilterState *state = (FMODDistanceFilterState *)dsp_state->plugindata; + state->reset(); + return FMOD_OK; +} + +FMOD_RESULT F_CALL FMOD_DistanceFilter_dspsetparamfloat(FMOD_DSP_STATE *dsp_state, int index, float value) +{ + FMODDistanceFilterState *state = (FMODDistanceFilterState *)dsp_state->plugindata; + + switch (index) + { + case FMOD_DISTANCE_FILTER_MAX_DISTANCE: + state->setMaxDistance(value); + return FMOD_OK; + + case FMOD_DISTANCE_FILTER_BANDPASS_FREQUENCY: + state->setBandpassFrequency(value); + return FMOD_OK; + } + + return FMOD_ERR_INVALID_PARAM; +} + +FMOD_RESULT F_CALL FMOD_DistanceFilter_dspgetparamfloat(FMOD_DSP_STATE *dsp_state, int index, float *value, char *valuestr) +{ + FMODDistanceFilterState *state = (FMODDistanceFilterState *)dsp_state->plugindata; + + switch (index) + { + case FMOD_DISTANCE_FILTER_MAX_DISTANCE: + *value = state->maxDistance(); + if (valuestr) snprintf(valuestr, FMOD_DSP_GETPARAM_VALUESTR_LENGTH, "%.1f", state->maxDistance()); + return FMOD_OK; + + case FMOD_DISTANCE_FILTER_BANDPASS_FREQUENCY: + *value = state->bandpassFrequency(); + if (valuestr) snprintf(valuestr, FMOD_DSP_GETPARAM_VALUESTR_LENGTH, "%.1f Hz", state->bandpassFrequency()); + return FMOD_OK; + } + + return FMOD_ERR_INVALID_PARAM; +} + +FMOD_RESULT F_CALL FMOD_DistanceFilter_dspsetparamdata(FMOD_DSP_STATE *dsp_state, int index, void *data, unsigned int /*length*/) +{ + FMODDistanceFilterState *state = (FMODDistanceFilterState *)dsp_state->plugindata; + + switch (index) + { + case FMOD_DISTANCE_FILTER_3D_ATTRIBUTES: + FMOD_DSP_PARAMETER_3DATTRIBUTES* param = (FMOD_DSP_PARAMETER_3DATTRIBUTES*)data; + state->setDistance(sqrtf(param->relative.position.x * param->relative.position.x + param->relative.position.y * param->relative.position.y + param->relative.position.z * param->relative.position.z)); + return FMOD_OK; + } + + return FMOD_ERR_INVALID_PARAM; +} + +FMOD_RESULT F_CALL FMOD_DistanceFilter_dspgetparamdata(FMOD_DSP_STATE * /*dsp_state*/, int index, void ** /*value*/, unsigned int * /*length*/, char * /*valuestr*/) +{ + switch (index) + { + case FMOD_DISTANCE_FILTER_3D_ATTRIBUTES: + return FMOD_ERR_INVALID_PARAM; + } + + return FMOD_ERR_INVALID_PARAM; +} + +FMOD_RESULT F_CALL FMOD_DistanceFilter_shouldiprocess(FMOD_DSP_STATE * /*dsp_state*/, FMOD_BOOL inputsidle, unsigned int /*length*/, FMOD_CHANNELMASK /*inmask*/, int /*inchannels*/, FMOD_SPEAKERMODE /*speakermode*/) +{ + if (inputsidle) + { + return FMOD_ERR_DSP_DONTPROCESS; + } + + return FMOD_OK; +} diff --git a/FMOD/api/core/examples/plugins/fmod_gain.cpp b/FMOD/api/core/examples/plugins/fmod_gain.cpp new file mode 100644 index 0000000..1072122 --- /dev/null +++ b/FMOD/api/core/examples/plugins/fmod_gain.cpp @@ -0,0 +1,360 @@ +/*============================================================================== +Gain DSP Plugin Example +Copyright (c), Firelight Technologies Pty, Ltd 2004-2026. + +This example shows how to create a simple gain DSP effect. +==============================================================================*/ + +#ifdef WIN32 + #define _CRT_SECURE_NO_WARNINGS +#endif + +#include +#include +#include + +#include "fmod.hpp" + +#define FMOD_GAIN_USEPROCESSCALLBACK /* FMOD plugins have 2 methods of processing data. + 1. via a 'read' callback which is compatible with FMOD Ex but limited in functionality, or + 2. via a 'process' callback which exposes more functionality, like masks and query before process early out logic. */ + +extern "C" { + F_EXPORT FMOD_DSP_DESCRIPTION* F_CALL FMODGetDSPDescription(); +} + +const float FMOD_GAIN_PARAM_GAIN_MIN = -80.0f; +const float FMOD_GAIN_PARAM_GAIN_MAX = 10.0f; +const float FMOD_GAIN_PARAM_GAIN_DEFAULT = 0.0f; +#define FMOD_GAIN_RAMPCOUNT 256 + +enum +{ + FMOD_GAIN_PARAM_GAIN = 0, + FMOD_GAIN_PARAM_INVERT, + FMOD_GAIN_NUM_PARAMETERS +}; + +#define DECIBELS_TO_LINEAR(__dbval__) ((__dbval__ <= FMOD_GAIN_PARAM_GAIN_MIN) ? 0.0f : powf(10.0f, __dbval__ / 20.0f)) +#define LINEAR_TO_DECIBELS(__linval__) ((__linval__ <= 0.0f) ? FMOD_GAIN_PARAM_GAIN_MIN : 20.0f * log10f((float)__linval__)) + +FMOD_RESULT F_CALL FMOD_Gain_dspcreate (FMOD_DSP_STATE *dsp_state); +FMOD_RESULT F_CALL FMOD_Gain_dsprelease (FMOD_DSP_STATE *dsp_state); +FMOD_RESULT F_CALL FMOD_Gain_dspreset (FMOD_DSP_STATE *dsp_state); +#ifdef FMOD_GAIN_USEPROCESSCALLBACK +FMOD_RESULT F_CALL FMOD_Gain_dspprocess (FMOD_DSP_STATE *dsp_state, unsigned int length, const FMOD_DSP_BUFFER_ARRAY *inbufferarray, FMOD_DSP_BUFFER_ARRAY *outbufferarray, FMOD_BOOL inputsidle, FMOD_DSP_PROCESS_OPERATION op); +#else +FMOD_RESULT F_CALL FMOD_Gain_dspread (FMOD_DSP_STATE *dsp_state, float *inbuffer, float *outbuffer, unsigned int length, int inchannels, int *outchannels); +#endif +FMOD_RESULT F_CALL FMOD_Gain_dspsetparamfloat(FMOD_DSP_STATE *dsp_state, int index, float value); +FMOD_RESULT F_CALL FMOD_Gain_dspsetparamint (FMOD_DSP_STATE *dsp_state, int index, int value); +FMOD_RESULT F_CALL FMOD_Gain_dspsetparambool (FMOD_DSP_STATE *dsp_state, int index, FMOD_BOOL value); +FMOD_RESULT F_CALL FMOD_Gain_dspsetparamdata (FMOD_DSP_STATE *dsp_state, int index, void *data, unsigned int length); +FMOD_RESULT F_CALL FMOD_Gain_dspgetparamfloat(FMOD_DSP_STATE *dsp_state, int index, float *value, char *valuestr); +FMOD_RESULT F_CALL FMOD_Gain_dspgetparamint (FMOD_DSP_STATE *dsp_state, int index, int *value, char *valuestr); +FMOD_RESULT F_CALL FMOD_Gain_dspgetparambool (FMOD_DSP_STATE *dsp_state, int index, FMOD_BOOL *value, char *valuestr); +FMOD_RESULT F_CALL FMOD_Gain_dspgetparamdata (FMOD_DSP_STATE *dsp_state, int index, void **value, unsigned int *length, char *valuestr); +FMOD_RESULT F_CALL FMOD_Gain_shouldiprocess (FMOD_DSP_STATE *dsp_state, FMOD_BOOL inputsidle, unsigned int length, FMOD_CHANNELMASK inmask, int inchannels, FMOD_SPEAKERMODE speakermode); +FMOD_RESULT F_CALL FMOD_Gain_sys_register (FMOD_DSP_STATE *dsp_state); +FMOD_RESULT F_CALL FMOD_Gain_sys_deregister (FMOD_DSP_STATE *dsp_state); +FMOD_RESULT F_CALL FMOD_Gain_sys_mix (FMOD_DSP_STATE *dsp_state, int stage); + +static bool FMOD_Gain_Running = false; +static FMOD_DSP_PARAMETER_DESC p_gain; +static FMOD_DSP_PARAMETER_DESC p_invert; + +FMOD_DSP_PARAMETER_DESC *FMOD_Gain_dspparam[FMOD_GAIN_NUM_PARAMETERS] = +{ + &p_gain, + &p_invert +}; + +FMOD_DSP_DESCRIPTION FMOD_Gain_Desc = +{ + FMOD_PLUGIN_SDK_VERSION, + "FMOD Gain", // name + 0x00010000, // plug-in version + 1, // number of input buffers to process + 1, // number of output buffers to process + FMOD_Gain_dspcreate, + FMOD_Gain_dsprelease, + FMOD_Gain_dspreset, +#ifndef FMOD_GAIN_USEPROCESSCALLBACK + FMOD_Gain_dspread, +#else + 0, +#endif +#ifdef FMOD_GAIN_USEPROCESSCALLBACK + FMOD_Gain_dspprocess, +#else + 0, +#endif + 0, + FMOD_GAIN_NUM_PARAMETERS, + FMOD_Gain_dspparam, + FMOD_Gain_dspsetparamfloat, + 0, // FMOD_Gain_dspsetparamint, + FMOD_Gain_dspsetparambool, + 0, // FMOD_Gain_dspsetparamdata, + FMOD_Gain_dspgetparamfloat, + 0, // FMOD_Gain_dspgetparamint, + FMOD_Gain_dspgetparambool, + 0, // FMOD_Gain_dspgetparamdata, + FMOD_Gain_shouldiprocess, + 0, // userdata + FMOD_Gain_sys_register, + FMOD_Gain_sys_deregister, + FMOD_Gain_sys_mix +}; + +extern "C" +{ + +F_EXPORT FMOD_DSP_DESCRIPTION* F_CALL FMODGetDSPDescription() +{ + static float gain_mapping_values[] = { -80, -50, -30, -10, 10 }; + static float gain_mapping_scale[] = { 0, 2, 4, 7, 11 }; + + FMOD_DSP_INIT_PARAMDESC_FLOAT_WITH_MAPPING(p_gain, "Gain", "dB", "Gain in dB. -80 to 10. Default = 0", FMOD_GAIN_PARAM_GAIN_DEFAULT, gain_mapping_values, gain_mapping_scale); + FMOD_DSP_INIT_PARAMDESC_BOOL(p_invert, "Invert", "", "Invert signal. Default = off", false, 0); + return &FMOD_Gain_Desc; +} + +} + +class FMODGainState +{ +public: + FMODGainState(); + + void read(float *inbuffer, float *outbuffer, unsigned int length, int channels); + void reset(); + void setGain(float); + void setInvert(bool); + float gain() const { return LINEAR_TO_DECIBELS(m_invert ? -m_target_gain : m_target_gain); } + FMOD_BOOL invert() const { return m_invert; } + +private: + float m_target_gain; + float m_current_gain; + int m_ramp_samples_left; + bool m_invert; +}; + +FMODGainState::FMODGainState() +{ + m_target_gain = DECIBELS_TO_LINEAR(FMOD_GAIN_PARAM_GAIN_DEFAULT); + m_invert = 0; + reset(); +} + +void FMODGainState::read(float *inbuffer, float *outbuffer, unsigned int length, int channels) +{ + // Note: buffers are interleaved + float gain = m_current_gain; + + if (m_ramp_samples_left) + { + float target = m_target_gain; + float delta = (target - gain) / m_ramp_samples_left; + while (length) + { + if (--m_ramp_samples_left) + { + gain += delta; + for (int i = 0; i < channels; ++i) + { + *outbuffer++ = *inbuffer++ * gain; + } + } + else + { + gain = target; + break; + } + --length; + } + } + + unsigned int samples = length * channels; + while (samples--) + { + *outbuffer++ = *inbuffer++ * gain; + } + + m_current_gain = gain; +} + +void FMODGainState::reset() +{ + m_current_gain = m_target_gain; + m_ramp_samples_left = 0; +} + +void FMODGainState::setGain(float gain) +{ + m_target_gain = m_invert ? -DECIBELS_TO_LINEAR(gain) : DECIBELS_TO_LINEAR(gain); + m_ramp_samples_left = FMOD_GAIN_RAMPCOUNT; +} + +void FMODGainState::setInvert(bool invert) +{ + if (invert != m_invert) + { + m_target_gain = -m_target_gain; + m_ramp_samples_left = FMOD_GAIN_RAMPCOUNT; + } + m_invert = invert; +} + +FMOD_RESULT F_CALL FMOD_Gain_dspcreate(FMOD_DSP_STATE *dsp_state) +{ + dsp_state->plugindata = (FMODGainState *)FMOD_DSP_ALLOC(dsp_state, sizeof(FMODGainState)); + if (!dsp_state->plugindata) + { + return FMOD_ERR_MEMORY; + } + return FMOD_OK; +} + +FMOD_RESULT F_CALL FMOD_Gain_dsprelease(FMOD_DSP_STATE *dsp_state) +{ + FMODGainState *state = (FMODGainState *)dsp_state->plugindata; + FMOD_DSP_FREE(dsp_state, state); + return FMOD_OK; +} + +#ifdef FMOD_GAIN_USEPROCESSCALLBACK + +FMOD_RESULT F_CALL FMOD_Gain_dspprocess(FMOD_DSP_STATE *dsp_state, unsigned int length, const FMOD_DSP_BUFFER_ARRAY *inbufferarray, FMOD_DSP_BUFFER_ARRAY *outbufferarray, FMOD_BOOL inputsidle, FMOD_DSP_PROCESS_OPERATION op) +{ + FMODGainState *state = (FMODGainState *)dsp_state->plugindata; + + if (op == FMOD_DSP_PROCESS_QUERY) + { + if (outbufferarray && inbufferarray) + { + outbufferarray[0].buffernumchannels[0] = inbufferarray[0].buffernumchannels[0]; + outbufferarray[0].speakermode = inbufferarray[0].speakermode; + } + + if (inputsidle) + { + return FMOD_ERR_DSP_DONTPROCESS; + } + } + else + { + state->read(inbufferarray[0].buffers[0], outbufferarray[0].buffers[0], length, inbufferarray[0].buffernumchannels[0]); // input and output channels count match for this effect + } + + return FMOD_OK; +} + +#else + +FMOD_RESULT F_CALL FMOD_Gain_dspread(FMOD_DSP_STATE *dsp_state, float *inbuffer, float *outbuffer, unsigned int length, int inchannels, int * /*outchannels*/) +{ + FMODGainState *state = (FMODGainState *)dsp_state->plugindata; + state->read(inbuffer, outbuffer, length, inchannels); // input and output channels count match for this effect + return FMOD_OK; +} + +#endif + +FMOD_RESULT F_CALL FMOD_Gain_dspreset(FMOD_DSP_STATE *dsp_state) +{ + FMODGainState *state = (FMODGainState *)dsp_state->plugindata; + state->reset(); + return FMOD_OK; +} + +FMOD_RESULT F_CALL FMOD_Gain_dspsetparamfloat(FMOD_DSP_STATE *dsp_state, int index, float value) +{ + FMODGainState *state = (FMODGainState *)dsp_state->plugindata; + + switch (index) + { + case FMOD_GAIN_PARAM_GAIN: + state->setGain(value); + return FMOD_OK; + } + + return FMOD_ERR_INVALID_PARAM; +} + +FMOD_RESULT F_CALL FMOD_Gain_dspgetparamfloat(FMOD_DSP_STATE *dsp_state, int index, float *value, char *valuestr) +{ + FMODGainState *state = (FMODGainState *)dsp_state->plugindata; + + switch (index) + { + case FMOD_GAIN_PARAM_GAIN: + *value = state->gain(); + if (valuestr) snprintf(valuestr, FMOD_DSP_GETPARAM_VALUESTR_LENGTH, "%.1f dB", state->gain()); + return FMOD_OK; + } + + return FMOD_ERR_INVALID_PARAM; +} + +FMOD_RESULT F_CALL FMOD_Gain_dspsetparambool(FMOD_DSP_STATE *dsp_state, int index, FMOD_BOOL value) +{ + FMODGainState *state = (FMODGainState *)dsp_state->plugindata; + + switch (index) + { + case FMOD_GAIN_PARAM_INVERT: + state->setInvert(value ? true : false); + return FMOD_OK; + } + + return FMOD_ERR_INVALID_PARAM; +} + +FMOD_RESULT F_CALL FMOD_Gain_dspgetparambool(FMOD_DSP_STATE *dsp_state, int index, FMOD_BOOL *value, char *valuestr) +{ + FMODGainState *state = (FMODGainState *)dsp_state->plugindata; + + switch (index) + { + case FMOD_GAIN_PARAM_INVERT: + *value = state->invert(); + if (valuestr) snprintf(valuestr, FMOD_DSP_GETPARAM_VALUESTR_LENGTH, state->invert() ? "Inverted" : "Off" ); + return FMOD_OK; + } + + return FMOD_ERR_INVALID_PARAM; +} + +FMOD_RESULT F_CALL FMOD_Gain_shouldiprocess(FMOD_DSP_STATE * /*dsp_state*/, FMOD_BOOL inputsidle, unsigned int /*length*/, FMOD_CHANNELMASK /*inmask*/, int /*inchannels*/, FMOD_SPEAKERMODE /*speakermode*/) +{ + if (inputsidle) + { + return FMOD_ERR_DSP_DONTPROCESS; + } + + return FMOD_OK; +} + + +FMOD_RESULT F_CALL FMOD_Gain_sys_register(FMOD_DSP_STATE * /*dsp_state*/) +{ + FMOD_Gain_Running = true; + // called once for this type of dsp being loaded or registered (it is not per instance) + return FMOD_OK; +} + +FMOD_RESULT F_CALL FMOD_Gain_sys_deregister(FMOD_DSP_STATE * /*dsp_state*/) +{ + FMOD_Gain_Running = false; + // called once for this type of dsp being unloaded or de-registered (it is not per instance) + return FMOD_OK; +} + +FMOD_RESULT F_CALL FMOD_Gain_sys_mix(FMOD_DSP_STATE * /*dsp_state*/, int /*stage*/) +{ + // stage == 0 , before all dsps are processed/mixed, this callback is called once for this type. + // stage == 1 , after all dsps are processed/mixed, this callback is called once for this type. + return FMOD_OK; +} diff --git a/FMOD/api/core/examples/plugins/fmod_noise.cpp b/FMOD/api/core/examples/plugins/fmod_noise.cpp new file mode 100644 index 0000000..f88aa2b --- /dev/null +++ b/FMOD/api/core/examples/plugins/fmod_noise.cpp @@ -0,0 +1,302 @@ +/*============================================================================== +Plugin Example +Copyright (c), Firelight Technologies Pty, Ltd 2004-2026. + +This example shows how to created a plugin effect. +==============================================================================*/ + +#include +#include +#include +#include + +#include "fmod.hpp" + +extern "C" { + F_EXPORT FMOD_DSP_DESCRIPTION* F_CALL FMODGetDSPDescription(); +} + +const float FMOD_NOISE_PARAM_GAIN_MIN = -80.0f; +const float FMOD_NOISE_PARAM_GAIN_MAX = 10.0f; +const float FMOD_NOISE_PARAM_GAIN_DEFAULT = 0.0f; + +#define FMOD_NOISE_RAMPCOUNT 256 + +enum +{ + FMOD_NOISE_PARAM_LEVEL = 0, + FMOD_NOISE_PARAM_FORMAT, + FMOD_NOISE_NUM_PARAMETERS +}; + +enum FMOD_NOISE_FORMAT +{ + FMOD_NOISE_FORMAT_MONO = 0, + FMOD_NOISE_FORMAT_STEREO, + FMOD_NOISE_FORMAT_5POINT1 +}; + +#define DECIBELS_TO_LINEAR(__dbval__) ((__dbval__ <= FMOD_NOISE_PARAM_GAIN_MIN) ? 0.0f : powf(10.0f, __dbval__ / 20.0f)) +#define LINEAR_TO_DECIBELS(__linval__) ((__linval__ <= 0.0f) ? FMOD_NOISE_PARAM_GAIN_MIN : 20.0f * log10f((float)__linval__)) + +FMOD_RESULT F_CALL FMOD_Noise_dspcreate (FMOD_DSP_STATE *dsp); +FMOD_RESULT F_CALL FMOD_Noise_dsprelease (FMOD_DSP_STATE *dsp); +FMOD_RESULT F_CALL FMOD_Noise_dspreset (FMOD_DSP_STATE *dsp); +FMOD_RESULT F_CALL FMOD_Noise_dspprocess (FMOD_DSP_STATE *dsp, unsigned int length, const FMOD_DSP_BUFFER_ARRAY *inbufferarray, FMOD_DSP_BUFFER_ARRAY *outbufferarray, FMOD_BOOL inputsidle, FMOD_DSP_PROCESS_OPERATION op); +FMOD_RESULT F_CALL FMOD_Noise_dspsetparamfloat(FMOD_DSP_STATE *dsp, int index, float value); +FMOD_RESULT F_CALL FMOD_Noise_dspsetparamint (FMOD_DSP_STATE *dsp, int index, int value); +FMOD_RESULT F_CALL FMOD_Noise_dspsetparambool (FMOD_DSP_STATE *dsp, int index, bool value); +FMOD_RESULT F_CALL FMOD_Noise_dspsetparamdata (FMOD_DSP_STATE *dsp, int index, void *data, unsigned int length); +FMOD_RESULT F_CALL FMOD_Noise_dspgetparamfloat(FMOD_DSP_STATE *dsp, int index, float *value, char *valuestr); +FMOD_RESULT F_CALL FMOD_Noise_dspgetparamint (FMOD_DSP_STATE *dsp, int index, int *value, char *valuestr); +FMOD_RESULT F_CALL FMOD_Noise_dspgetparambool (FMOD_DSP_STATE *dsp, int index, bool *value, char *valuestr); +FMOD_RESULT F_CALL FMOD_Noise_dspgetparamdata (FMOD_DSP_STATE *dsp, int index, void **value, unsigned int *length, char *valuestr); + +static FMOD_DSP_PARAMETER_DESC p_level; +static FMOD_DSP_PARAMETER_DESC p_format; + +FMOD_DSP_PARAMETER_DESC *FMOD_Noise_dspparam[FMOD_NOISE_NUM_PARAMETERS] = +{ + &p_level, + &p_format +}; + +const char* FMOD_Noise_Format_Names[3] = {"Mono", "Stereo", "5.1"}; + +FMOD_DSP_DESCRIPTION FMOD_Noise_Desc = +{ + FMOD_PLUGIN_SDK_VERSION, + "FMOD Noise", // name + 0x00010000, // plug-in version + 0, // number of input buffers to process + 1, // number of output buffers to process + FMOD_Noise_dspcreate, + FMOD_Noise_dsprelease, + FMOD_Noise_dspreset, + 0, + FMOD_Noise_dspprocess, + 0, + FMOD_NOISE_NUM_PARAMETERS, + FMOD_Noise_dspparam, + FMOD_Noise_dspsetparamfloat, + FMOD_Noise_dspsetparamint, + 0, + 0, + FMOD_Noise_dspgetparamfloat, + FMOD_Noise_dspgetparamint, + 0, + 0, + 0, + 0, // userdata + 0, // Register + 0, // Deregister + 0 // Mix +}; + +extern "C" +{ + +F_EXPORT FMOD_DSP_DESCRIPTION* F_CALL FMODGetDSPDescription() +{ + FMOD_DSP_INIT_PARAMDESC_FLOAT(p_level, "Level", "dB", "Gain in dB. -80 to 10. Default = 0", FMOD_NOISE_PARAM_GAIN_MIN, FMOD_NOISE_PARAM_GAIN_MAX, FMOD_NOISE_PARAM_GAIN_DEFAULT); + FMOD_DSP_INIT_PARAMDESC_INT(p_format, "Format", "", "Mono, stereo or 5.1. Default = 0 (mono)", FMOD_NOISE_FORMAT_MONO, FMOD_NOISE_FORMAT_5POINT1, FMOD_NOISE_FORMAT_MONO, false, FMOD_Noise_Format_Names); + return &FMOD_Noise_Desc; +} + +} + +class FMODNoiseState +{ +public: + FMODNoiseState(); + + void generate(float *outbuffer, unsigned int length, int channels); + void reset(); + void setLevel(float); + void setFormat(FMOD_NOISE_FORMAT format) { m_format = format; } + float level() const { return LINEAR_TO_DECIBELS(m_target_level); } + FMOD_NOISE_FORMAT format() const { return m_format; } + +private: + float m_target_level; + float m_current_level; + int m_ramp_samples_left; + FMOD_NOISE_FORMAT m_format; +}; + +FMODNoiseState::FMODNoiseState() +{ + m_target_level = DECIBELS_TO_LINEAR(FMOD_NOISE_PARAM_GAIN_DEFAULT); + m_format = FMOD_NOISE_FORMAT_MONO; + reset(); +} + +void FMODNoiseState::generate(float *outbuffer, unsigned int length, int channels) +{ + // Note: buffers are interleaved + float gain = m_current_level; + + if (m_ramp_samples_left) + { + float target = m_target_level; + float delta = (target - gain) / m_ramp_samples_left; + while (length) + { + if (--m_ramp_samples_left) + { + gain += delta; + for (int i = 0; i < channels; ++i) + { + *outbuffer++ = (((float)(rand()%32768) / 16384.0f) - 1.0f) * gain; + } + } + else + { + gain = target; + break; + } + --length; + } + } + + unsigned int samples = length * channels; + while (samples--) + { + *outbuffer++ = (((float)(rand()%32768) / 16384.0f) - 1.0f) * gain; + } + + m_current_level = gain; +} + +void FMODNoiseState::reset() +{ + m_current_level = m_target_level; + m_ramp_samples_left = 0; +} + +void FMODNoiseState::setLevel(float level) +{ + m_target_level = DECIBELS_TO_LINEAR(level); + m_ramp_samples_left = FMOD_NOISE_RAMPCOUNT; +} + +FMOD_RESULT F_CALL FMOD_Noise_dspcreate(FMOD_DSP_STATE *dsp) +{ + dsp->plugindata = (FMODNoiseState *)FMOD_DSP_ALLOC(dsp, sizeof(FMODNoiseState)); + if (!dsp->plugindata) + { + return FMOD_ERR_MEMORY; + } + return FMOD_OK; +} + +FMOD_RESULT F_CALL FMOD_Noise_dsprelease(FMOD_DSP_STATE *dsp) +{ + FMODNoiseState *state = (FMODNoiseState *)dsp->plugindata; + FMOD_DSP_FREE(dsp, state); + return FMOD_OK; +} + +FMOD_RESULT F_CALL FMOD_Noise_dspprocess(FMOD_DSP_STATE *dsp, unsigned int length, const FMOD_DSP_BUFFER_ARRAY * /*inbufferarray*/, FMOD_DSP_BUFFER_ARRAY *outbufferarray, FMOD_BOOL /*inputsidle*/, FMOD_DSP_PROCESS_OPERATION op) +{ + FMODNoiseState *state = (FMODNoiseState *)dsp->plugindata; + + if (op == FMOD_DSP_PROCESS_QUERY) + { + FMOD_SPEAKERMODE outmode = FMOD_SPEAKERMODE_DEFAULT; + int outchannels = 0; + + switch(state->format()) + { + case FMOD_NOISE_FORMAT_MONO: + outmode = FMOD_SPEAKERMODE_MONO; + outchannels = 1; + break; + + case FMOD_NOISE_FORMAT_STEREO: + outmode = FMOD_SPEAKERMODE_STEREO; + outchannels = 2; + break; + + case FMOD_NOISE_FORMAT_5POINT1: + outmode = FMOD_SPEAKERMODE_5POINT1; + outchannels = 6; + } + + if (outbufferarray) + { + outbufferarray->speakermode = outmode; + outbufferarray->buffernumchannels[0] = outchannels; + } + + return FMOD_OK; + } + + state->generate(outbufferarray->buffers[0], length, outbufferarray->buffernumchannels[0]); + return FMOD_OK; +} + +FMOD_RESULT F_CALL FMOD_Noise_dspreset(FMOD_DSP_STATE *dsp) +{ + FMODNoiseState *state = (FMODNoiseState *)dsp->plugindata; + state->reset(); + return FMOD_OK; +} + +FMOD_RESULT F_CALL FMOD_Noise_dspsetparamfloat(FMOD_DSP_STATE *dsp, int index, float value) +{ + FMODNoiseState *state = (FMODNoiseState *)dsp->plugindata; + + switch (index) + { + case FMOD_NOISE_PARAM_LEVEL: + state->setLevel(value); + return FMOD_OK; + } + + return FMOD_ERR_INVALID_PARAM; +} + +FMOD_RESULT F_CALL FMOD_Noise_dspgetparamfloat(FMOD_DSP_STATE *dsp, int index, float *value, char *valuestr) +{ + FMODNoiseState *state = (FMODNoiseState *)dsp->plugindata; + + switch (index) + { + case FMOD_NOISE_PARAM_LEVEL: + *value = state->level(); + if (valuestr) snprintf(valuestr, FMOD_DSP_GETPARAM_VALUESTR_LENGTH, "%.1f dB", state->level()); + return FMOD_OK; + } + + return FMOD_ERR_INVALID_PARAM; +} + +FMOD_RESULT F_CALL FMOD_Noise_dspsetparamint(FMOD_DSP_STATE *dsp, int index, int value) +{ + FMODNoiseState *state = (FMODNoiseState *)dsp->plugindata; + + switch (index) + { + case FMOD_NOISE_PARAM_FORMAT: + state->setFormat((FMOD_NOISE_FORMAT)value); + return FMOD_OK; + } + + return FMOD_ERR_INVALID_PARAM; +} + +FMOD_RESULT F_CALL FMOD_Noise_dspgetparamint(FMOD_DSP_STATE *dsp, int index, int *value, char *valuestr) +{ + FMODNoiseState *state = (FMODNoiseState *)dsp->plugindata; + + switch (index) + { + case FMOD_NOISE_PARAM_FORMAT: + *value = state->format(); + if (valuestr) snprintf(valuestr, FMOD_DSP_GETPARAM_VALUESTR_LENGTH, "%s", FMOD_Noise_Format_Names[state->format()]); + return FMOD_OK; + } + + return FMOD_ERR_INVALID_PARAM; +} diff --git a/FMOD/api/core/examples/plugins/fmod_rnbo.cpp b/FMOD/api/core/examples/plugins/fmod_rnbo.cpp new file mode 100644 index 0000000..a8ed922 --- /dev/null +++ b/FMOD/api/core/examples/plugins/fmod_rnbo.cpp @@ -0,0 +1,189 @@ +/*============================================================================== +RNBO DSP Plugin Example +Copyright (c), Firelight Technologies Pty, Ltd 2004-2026. + +This example shows how to integrate RNBO C++ source code into an FMOD effect. +1. Add the rnbo and rnbo/common directories to your include paths. +2. Add the generated RNBO source .cpp file and rnbo/RNBO.cpp files to your list + of source files. +3. Build and copy the generated library into your FMOD Studio script directory: + https://fmod.com/docs/2.03/studio/plugin-reference.html#loading-plug-ins +Note: +FMOD parameters have a max length of 15 characters. RNBO parameters greater +than 15 chracters will be truncated. +==============================================================================*/ +#if __has_include("RNBO.h") +#include "RNBO.h" + +#include +#include +#include +#include + +#include "fmod.hpp" + +static FMOD_DSP_PARAMETER_DESC** params = nullptr; +static int numParams; +static int numInputs; +static int numOutputs; +static std::atomic gSysCount = 0; + +static FMOD_RESULT F_CALL FMOD_RNBO_Create(FMOD_DSP_STATE *dsp_state) +{ + dsp_state->plugindata = FMOD_DSP_ALLOC(dsp_state, sizeof(RNBO::CoreObject)); + if (!dsp_state->plugindata) + { + return FMOD_ERR_MEMORY; + } + + RNBO::CoreObject *rnboObject = (RNBO::CoreObject *)dsp_state->plugindata; + + int sampleRate; + unsigned int blockSize; + + FMOD_DSP_GETSAMPLERATE(dsp_state, &sampleRate); + FMOD_DSP_GETBLOCKSIZE(dsp_state, &blockSize); + + new (rnboObject) RNBO::CoreObject(); + + rnboObject->prepareToProcess(sampleRate, blockSize); + + return FMOD_OK; +} + +static FMOD_RESULT F_CALL FMOD_RNBO_Release(FMOD_DSP_STATE *dsp_state) +{ + RNBO::CoreObject *rnboObject = (RNBO::CoreObject *)dsp_state->plugindata; + rnboObject->~CoreObject(); + + FMOD_DSP_FREE(dsp_state, rnboObject); + + return FMOD_OK; +} + +static FMOD_RESULT F_CALL FMOD_RNBO_Process(FMOD_DSP_STATE *dsp_state, unsigned int length, const FMOD_DSP_BUFFER_ARRAY *inbufferarray, FMOD_DSP_BUFFER_ARRAY *outbufferarray, FMOD_BOOL inputsidle, FMOD_DSP_PROCESS_OPERATION op) +{ + RNBO::CoreObject *rnboObject = (RNBO::CoreObject *)dsp_state->plugindata; + + if (op == FMOD_DSP_PROCESS_QUERY) + { + if (numInputs > 0) + { + if (inputsidle) + { + return FMOD_ERR_DSP_SILENCE; + } + } + else + { + if (outbufferarray && outbufferarray[0].buffernumchannels) + { + outbufferarray[0].buffernumchannels[0] = numOutputs; + } + } + } + else + { + rnboObject->process(inbufferarray[0].buffers[0], inbufferarray[0].buffernumchannels[0], + outbufferarray[0].buffers[0], outbufferarray[0].buffernumchannels[0], length); + } + + return FMOD_OK; +} + +static FMOD_RESULT F_CALL FMOD_RNBO_SetParamFloat(FMOD_DSP_STATE *dsp_state, int index, float value) +{ + RNBO::CoreObject *rnboObject = (RNBO::CoreObject *)dsp_state->plugindata; + + rnboObject->setParameterValue(index, value); + return FMOD_OK; +} + +static FMOD_RESULT F_CALL FMOD_RNBO_GetParamFloat(FMOD_DSP_STATE *dsp_state, int index, float *value, char *valuestr) +{ + RNBO::CoreObject *rnboObject = (RNBO::CoreObject *)dsp_state->plugindata; + + *value = (float)rnboObject->getParameterValue(index); + if (valuestr) snprintf(valuestr, FMOD_DSP_GETPARAM_VALUESTR_LENGTH, "%s", rnboObject->getParameterName(index)); + + return FMOD_OK; +} + +static FMOD_RESULT F_CALL FMOD_RNBO_SysRegister(FMOD_DSP_STATE* dsp_state) +{ + RNBO::CoreObject* rnboObject = (RNBO::CoreObject*)dsp_state->plugindata; + + gSysCount++; + + return FMOD_OK; +} + +static FMOD_RESULT F_CALL FMOD_RNBO_SysDeregister(FMOD_DSP_STATE* dsp_state) +{ + RNBO::CoreObject* rnboObject = (RNBO::CoreObject*)dsp_state->plugindata; + + gSysCount--; + if (gSysCount == 0) + { + for (int i = 0; i < numParams; ++i) + { + free(params[i]); + } + free(params); + + params = nullptr; + } + + return FMOD_OK; +} + +extern "C" F_EXPORT FMOD_DSP_DESCRIPTION *F_CALL FMODGetDSPDescription() +{ + static FMOD_DSP_DESCRIPTION desc = { FMOD_PLUGIN_SDK_VERSION, "FMOD RNBO", 0x00010000 }; + desc.create = FMOD_RNBO_Create; + desc.release = FMOD_RNBO_Release; + desc.process = FMOD_RNBO_Process; + desc.setparameterfloat = FMOD_RNBO_SetParamFloat; + desc.getparameterfloat = FMOD_RNBO_GetParamFloat; + desc.sys_register = FMOD_RNBO_SysRegister; + desc.sys_deregister = FMOD_RNBO_SysDeregister; + + if (!params) + { + RNBO::CoreObject tmpRnboObject; + + numParams = tmpRnboObject.getNumParameters(); + numInputs = tmpRnboObject.getNumInputChannels(); + numOutputs = tmpRnboObject.getNumOutputChannels(); + + desc.numparameters = numParams; + desc.numinputbuffers = numInputs > 0; + desc.numoutputbuffers = numOutputs > 0; + + params = (FMOD_DSP_PARAMETER_DESC**)malloc(desc.numparameters * sizeof(FMOD_DSP_PARAMETER_DESC*)); + + for (int i = 0; i < numParams; ++i) + { + RNBO::ParameterInfo info = {}; + tmpRnboObject.getParameterInfo(i, &info); + + params[i] = (FMOD_DSP_PARAMETER_DESC *)malloc(sizeof(FMOD_DSP_PARAMETER_DESC)); + memset(params[i], 0, sizeof(FMOD_DSP_PARAMETER_DESC)); + + // FMOD_DSP_PARAMETER_DESC::name can only hold 15 characters (excluding \0 null terminator). + // RNBO parameters greater than 15 chracters will be truncated. + snprintf(params[i]->name, sizeof(params[i]->name), "%s", tmpRnboObject.getParameterId(i)); + snprintf(params[i]->label, sizeof(params[i]->label), "%s", info.unit); + + params[i]->type = FMOD_DSP_PARAMETER_TYPE_FLOAT; + params[i]->floatdesc.defaultval = info.initialValue; + params[i]->floatdesc.min = info.min; + params[i]->floatdesc.max = info.max; + } + + desc.paramdesc = params; + } + return &desc; +} + +#endif diff --git a/FMOD/api/core/examples/plugins/lame_enc.dll b/FMOD/api/core/examples/plugins/lame_enc.dll new file mode 100644 index 0000000..e416862 Binary files /dev/null and b/FMOD/api/core/examples/plugins/lame_enc.dll differ diff --git a/FMOD/api/core/examples/plugins/lame_enc64.dll b/FMOD/api/core/examples/plugins/lame_enc64.dll new file mode 100644 index 0000000..faa131b Binary files /dev/null and b/FMOD/api/core/examples/plugins/lame_enc64.dll differ diff --git a/FMOD/api/core/examples/plugins/output_mp3.cpp b/FMOD/api/core/examples/plugins/output_mp3.cpp new file mode 100644 index 0000000..b7ab203 --- /dev/null +++ b/FMOD/api/core/examples/plugins/output_mp3.cpp @@ -0,0 +1,429 @@ +/*=============================================================================================== + OUTPUT_MP3.DLL + Copyright (c), Firelight Technologies Pty, Ltd 2004-2026. + + Shows how to write an FMOD output plugin that writes the output to an mp3 file using + lame_enc.dll. + + Most of this source code that does the encoding is taken from the LAME encoder example. + An FMOD Studio output plugin is created by declaring the FMODGetOutputDescription function, + then filling out a FMOD_OUTPUT_DESCRIPTION and returning a pointer to it. + FMOD will then call those functions when appropriate. + + To get the output from FMOD so that you can write it to your sound device (or LAME encoder + function in this case), FMOD_OUTPUT_STATE::readfrommixer is called to run the mixer. + + We acknowledge that we are using LAME, which originates from www.mp3dev.org. + LAME is under the LGPL and as an external FMOD plugin with full source code for the interface + it is allowable under the LGPL to be distributed in this fashion. + +===============================================================================================*/ + +#include +#include +#include +#include + +#include "fmod.hpp" + +#include "BladeMP3EncDll.h" + +typedef struct +{ + FILE *mFP; + HINSTANCE mDLL; + HBE_STREAM hbeStream; + PBYTE pMP3Buffer; + PSHORT pWAVBuffer; + BE_VERSION Version; + DWORD dwMP3Buffer; + DWORD dwSamples; + + BEINITSTREAM beInitStream; + BEENCODECHUNK beEncodeChunk; + BEDEINITSTREAM beDeinitStream; + BECLOSESTREAM beCloseStream; + BEVERSION beVersion; + BEWRITEVBRHEADER beWriteVBRHeader; + + int dspbufferlength; + +} outputmp3_state; + +FMOD_OUTPUT_DESCRIPTION mp3output; + +FMOD_RESULT F_CALL OutputMP3_GetNumDriversCallback(FMOD_OUTPUT_STATE *output_state, int *numdrivers); +FMOD_RESULT F_CALL OutputMP3_GetDriverInfoCallback(FMOD_OUTPUT_STATE *output_state, int id, char *name, int namelen, FMOD_GUID *guid, int *systemrate, FMOD_SPEAKERMODE *speakermode, int *speakermodechannels); +FMOD_RESULT F_CALL OutputMP3_InitCallback(FMOD_OUTPUT_STATE *output_state, int selecteddriver, FMOD_INITFLAGS flags, int *outputrate, FMOD_SPEAKERMODE *speakermode, int *speakermodechannels, FMOD_SOUND_FORMAT *outputformat, int dspbufferlength, int *dspnumbuffers, int *dspnumadditionalbuffers, void *extradriverdata); +FMOD_RESULT F_CALL OutputMP3_CloseCallback(FMOD_OUTPUT_STATE *output_state); +FMOD_RESULT F_CALL OutputMP3_UpdateCallback(FMOD_OUTPUT_STATE *output_state); +FMOD_RESULT F_CALL OutputMP3_GetHandleCallback(FMOD_OUTPUT_STATE *output_state, void **handle); + + +#ifdef __cplusplus +extern "C" { +#endif + +/* + FMODGetOutputDescription is mandantory for every fmod plugin. This is the symbol the registerplugin function searches for. + Must be declared with F_CALL to make it export as stdcall. +*/ +F_EXPORT FMOD_OUTPUT_DESCRIPTION* F_CALL FMODGetOutputDescription() +{ + memset(&mp3output, 0, sizeof(FMOD_OUTPUT_DESCRIPTION)); + + mp3output.apiversion = FMOD_OUTPUT_PLUGIN_VERSION; + mp3output.name = "FMOD MP3 Output"; + mp3output.version = 0x00010000; + mp3output.method = FMOD_OUTPUT_METHOD_MIX_DIRECT; + mp3output.getnumdrivers = OutputMP3_GetNumDriversCallback; + mp3output.getdriverinfo = OutputMP3_GetDriverInfoCallback; + mp3output.init = OutputMP3_InitCallback; + mp3output.close = OutputMP3_CloseCallback; + mp3output.update = OutputMP3_UpdateCallback; + mp3output.gethandle = OutputMP3_GetHandleCallback; + + return &mp3output; +} + +#ifdef __cplusplus +} +#endif + + +/* +[ + [DESCRIPTION] + + [PARAMETERS] + + [REMARKS] + + [SEE_ALSO] +] +*/ +FMOD_RESULT F_CALL OutputMP3_GetNumDriversCallback(FMOD_OUTPUT_STATE * /*output*/, int *numdrivers) +{ + *numdrivers = 1; + + return FMOD_OK; +} + + +/* +[ + [DESCRIPTION] + + [PARAMETERS] + + [REMARKS] + + [SEE_ALSO] +] +*/ +FMOD_RESULT F_CALL OutputMP3_GetDriverInfoCallback(FMOD_OUTPUT_STATE * /*output*/, int /*id*/, char *name, int namelen, FMOD_GUID * /*guid*/, int * /*systemrate*/, FMOD_SPEAKERMODE *speakermode, int *speakermodechannels) +{ + strncpy(name, "fmodoutput.mp3", namelen); + + *speakermode = FMOD_SPEAKERMODE_STEREO; + *speakermodechannels = 2; + + return FMOD_OK; +} + + +/* +[ + [DESCRIPTION] + + [PARAMETERS] + + [REMARKS] + + [SEE_ALSO] +] +*/ +FMOD_RESULT F_CALL OutputMP3_InitCallback(FMOD_OUTPUT_STATE *output_state, int /*selecteddriver*/, FMOD_INITFLAGS /*flags*/, int *outputrate, FMOD_SPEAKERMODE *speakermode, int *speakermodechannels, FMOD_SOUND_FORMAT *outputformat, int dspbufferlength, int */*dspnumbuffers*/, int */*dspnumadditionalbuffers*/, void *extradriverdata) +{ + outputmp3_state *state; + BE_CONFIG beConfig = {0,}; + BE_ERR err = 0; + char filename[256]; + + /* + Create a structure that we can attach to the plugin instance. + */ + state = (outputmp3_state *)calloc(sizeof(outputmp3_state), 1); + if (!state) + { + return FMOD_ERR_MEMORY; + } + output_state->plugindata = state; + + *outputformat = FMOD_SOUND_FORMAT_PCM16; + *speakermode = FMOD_SPEAKERMODE_STEREO; + *speakermodechannels = 2; + +#ifdef _WIN64 + state->mDLL = LoadLibrary("lame_enc64.dll"); +#else + state->mDLL = LoadLibrary("lame_enc.dll"); +#endif + if (!state->mDLL) + { + return FMOD_ERR_PLUGIN_RESOURCE; + } + + state->dspbufferlength = dspbufferlength; + + /* + Get Interface functions from the DLL + */ + state->beInitStream = (BEINITSTREAM) GetProcAddress(state->mDLL, TEXT_BEINITSTREAM); + state->beEncodeChunk = (BEENCODECHUNK) GetProcAddress(state->mDLL, TEXT_BEENCODECHUNK); + state->beDeinitStream = (BEDEINITSTREAM) GetProcAddress(state->mDLL, TEXT_BEDEINITSTREAM); + state->beCloseStream = (BECLOSESTREAM) GetProcAddress(state->mDLL, TEXT_BECLOSESTREAM); + state->beVersion = (BEVERSION) GetProcAddress(state->mDLL, TEXT_BEVERSION); + state->beWriteVBRHeader = (BEWRITEVBRHEADER) GetProcAddress(state->mDLL, TEXT_BEWRITEVBRHEADER); + + // Check if all interfaces are present + if(!state->beInitStream || !state->beEncodeChunk || !state->beDeinitStream || !state->beCloseStream || !state->beVersion || !state->beWriteVBRHeader) + { + return FMOD_ERR_PLUGIN; + } + + // Get the version number + state->beVersion( &state->Version ); + + memset(&beConfig,0,sizeof(beConfig)); // clear all fields + + // use the LAME config structure + beConfig.dwConfig = BE_CONFIG_LAME; + + // this are the default settings for testcase.wav + + // FMOD NOTE : The 'extradriverdata' param could be used to pass in info about the bitrate and encoding settings. + + beConfig.format.LHV1.dwStructVersion = 1; + beConfig.format.LHV1.dwStructSize = sizeof(beConfig); + beConfig.format.LHV1.dwSampleRate = *outputrate; // INPUT FREQUENCY + beConfig.format.LHV1.dwReSampleRate = 0; // DON"T RESAMPLE + beConfig.format.LHV1.nMode = BE_MP3_MODE_JSTEREO; // OUTPUT IN STREO + beConfig.format.LHV1.dwBitrate = 128; // MINIMUM BIT RATE + beConfig.format.LHV1.nPreset = LQP_R3MIX; // QUALITY PRESET SETTING + beConfig.format.LHV1.dwMpegVersion = MPEG1; // MPEG VERSION (I or II) + beConfig.format.LHV1.dwPsyModel = 0; // USE DEFAULT PSYCHOACOUSTIC MODEL + beConfig.format.LHV1.dwEmphasis = 0; // NO EMPHASIS TURNED ON + beConfig.format.LHV1.bOriginal = TRUE; // SET ORIGINAL FLAG + beConfig.format.LHV1.bWriteVBRHeader = TRUE; // Write INFO tag + +// beConfig.format.LHV1.dwMaxBitrate = 320; // MAXIMUM BIT RATE +// beConfig.format.LHV1.bCRC = TRUE; // INSERT CRC +// beConfig.format.LHV1.bCopyright = TRUE; // SET COPYRIGHT FLAG +// beConfig.format.LHV1.bPrivate = TRUE; // SET PRIVATE FLAG +// beConfig.format.LHV1.bWriteVBRHeader = TRUE; // YES, WRITE THE XING VBR HEADER +// beConfig.format.LHV1.bEnableVBR = TRUE; // USE VBR +// beConfig.format.LHV1.nVBRQuality = 5; // SET VBR QUALITY + beConfig.format.LHV1.bNoRes = TRUE; // No Bit resorvoir + +// Preset Test +// beConfig.format.LHV1.nPreset = LQP_PHONE; + + // Init the MP3 Stream + err = state->beInitStream(&beConfig, &state->dwSamples, &state->dwMP3Buffer, &state->hbeStream); + + // Check result + if(err != BE_ERR_SUCCESSFUL) + { + return FMOD_ERR_PLUGIN; + } + + // Allocate MP3 buffer + state->pMP3Buffer = (PBYTE)malloc(state->dwMP3Buffer); + if(!state->pMP3Buffer) + { + return FMOD_ERR_MEMORY; + } + + // Allocate WAV buffer + state->pWAVBuffer = (PSHORT)malloc(state->dwSamples * sizeof(SHORT)); + if (!state->pWAVBuffer) + { + return FMOD_ERR_MEMORY; + } + + if (!extradriverdata) + { + strncpy(filename, "fmodoutput.mp3", 256); + } + else + { + strncpy(filename, (char *)extradriverdata, 256); + } + + state->mFP = fopen(filename, "wb"); + if (!state->mFP) + { + return FMOD_ERR_FILE_NOTFOUND; + } + + return FMOD_OK; +} + + +/* +[ + [DESCRIPTION] + + [PARAMETERS] + + [REMARKS] + + [SEE_ALSO] +] +*/ +FMOD_RESULT F_CALL OutputMP3_CloseCallback(FMOD_OUTPUT_STATE *output_state) +{ + outputmp3_state *state = (outputmp3_state *)output_state->plugindata; + DWORD dwWrite=0; + BE_ERR err; + + if (!state) + { + return FMOD_OK; + } + + // Deinit the stream + err = state->beDeinitStream(state->hbeStream, state->pMP3Buffer, &dwWrite); + + // Check result + if(err != BE_ERR_SUCCESSFUL) + { + state->beCloseStream(state->hbeStream); + + return FMOD_ERR_PLUGIN; + } + + // Are there any bytes returned from the DeInit call? + // If so, write them to disk + if( dwWrite ) + { + if( fwrite( state->pMP3Buffer, 1, dwWrite, state->mFP ) != dwWrite ) + { + return FMOD_ERR_FILE_BAD; + } + } + + // close the MP3 Stream + state->beCloseStream( state->hbeStream ); + + if (state->pWAVBuffer) + { + free(state->pWAVBuffer); + state->pWAVBuffer = 0; + } + + if (state->pMP3Buffer) + { + free(state->pMP3Buffer); + state->pMP3Buffer = 0; + } + + if (state->mFP) + { + fclose(state->mFP); + state->mFP = 0; + } + + if (state) + { + free(state); + output_state->plugindata = 0; + } + + return FMOD_OK; +} + + +/* +[ + [DESCRIPTION] + + [PARAMETERS] + + [REMARKS] + + [SEE_ALSO] +] +*/ +FMOD_RESULT F_CALL OutputMP3_UpdateCallback(FMOD_OUTPUT_STATE *output_state) +{ + FMOD_RESULT result; + outputmp3_state *state = (outputmp3_state *)output_state->plugindata; + DWORD dwRead=0; + DWORD dwWrite=0; + BE_ERR err; + + /* + Update the mixer to the interleaved buffer. + */ + PSHORT destptr = state->pWAVBuffer; + unsigned int len = state->dwSamples / 2; /* /2 = stereo */; + + while (len) + { + unsigned int l = len; // > state->dspbufferlength ? state->dspbufferlength : len; + + result = output_state->readfrommixer(output_state, destptr, l); + if (result != FMOD_OK) + { + return FMOD_OK; + } + + len -= l; + destptr += (l * 2); /* *2 = stereo. */ + } + + dwRead = state->dwSamples * sizeof(SHORT); + + // Encode samples + err = state->beEncodeChunk(state->hbeStream, dwRead / sizeof(SHORT), state->pWAVBuffer, state->pMP3Buffer, &dwWrite); + + // Check result + if(err != BE_ERR_SUCCESSFUL) + { + state->beCloseStream(state->hbeStream); + return FMOD_ERR_PLUGIN; + } + + // write dwWrite bytes that are returned in tehe pMP3Buffer to disk + if (fwrite(state->pMP3Buffer, 1, dwWrite, state->mFP) != dwWrite) + { + return FMOD_ERR_FILE_BAD; + } + + return FMOD_OK; +} + + +/* +[ + [DESCRIPTION] + + [PARAMETERS] + + [REMARKS] + + [SEE_ALSO] +] +*/ +FMOD_RESULT F_CALL OutputMP3_GetHandleCallback(FMOD_OUTPUT_STATE *output_state, void **handle) +{ + outputmp3_state *state = (outputmp3_state *)output_state->plugindata; + + *handle = state->mFP; + + return FMOD_OK; +} + + diff --git a/FMOD/api/core/examples/record.cpp b/FMOD/api/core/examples/record.cpp new file mode 100644 index 0000000..3a40646 --- /dev/null +++ b/FMOD/api/core/examples/record.cpp @@ -0,0 +1,222 @@ +/*============================================================================== +Record example +Copyright (c), Firelight Technologies Pty, Ltd 2004-2026. + +This example shows how to record continuously and play back the same data while +keeping a specified latency between the two. This is achieved by delaying the +start of playback until the specified number of milliseconds has been recorded. +At runtime the playback speed will be slightly altered to compensate for any +drift in either play or record drivers. + +For information on using FMOD example code in your own programs, visit +https://www.fmod.com/legal +==============================================================================*/ +#include "fmod.hpp" +#include "common.h" + +#define LATENCY_MS (50) /* Some devices will require higher latency to avoid glitches */ +#define DRIFT_MS (1) +#define DEVICE_INDEX (0) + +int FMOD_Main() +{ + FMOD::Channel *channel = NULL; + unsigned int samplesRecorded = 0; + unsigned int samplesPlayed = 0; + bool dspEnabled = false; + + void *extraDriverData = NULL; + Common_Init(&extraDriverData); + + /* + Create a System object and initialize. + */ + FMOD::System *system = NULL; + FMOD_RESULT result = FMOD::System_Create(&system); + ERRCHECK(result); + + result = system->init(100, FMOD_INIT_NORMAL, extraDriverData); + ERRCHECK(result); + + int numDrivers = 0; + result = system->getRecordNumDrivers(NULL, &numDrivers); + ERRCHECK(result); + + if (numDrivers == 0) + { + Common_Fatal("No recording devices found/plugged in! Aborting."); + } + + /* + Determine latency in samples. + */ + int nativeRate = 0; + int nativeChannels = 0; + result = system->getRecordDriverInfo(DEVICE_INDEX, NULL, 0, NULL, &nativeRate, NULL, &nativeChannels, NULL); + ERRCHECK(result); + + unsigned int driftThreshold = (nativeRate * DRIFT_MS) / 1000; /* The point where we start compensating for drift */ + unsigned int desiredLatency = (nativeRate * LATENCY_MS) / 1000; /* User specified latency */ + unsigned int adjustedLatency = desiredLatency; /* User specified latency adjusted for driver update granularity */ + int actualLatency = desiredLatency; /* Latency measured once playback begins (smoothened for jitter) */ + + /* + Create user sound to record into, then start recording. + */ + FMOD_CREATESOUNDEXINFO exinfo = {0}; + exinfo.cbsize = sizeof(FMOD_CREATESOUNDEXINFO); + exinfo.numchannels = nativeChannels; + exinfo.format = FMOD_SOUND_FORMAT_PCM16; + exinfo.defaultfrequency = nativeRate; + exinfo.length = nativeRate * sizeof(short) * nativeChannels; /* 1 second buffer, size here doesn't change latency */ + + FMOD::Sound *sound = NULL; + result = system->createSound(0, FMOD_LOOP_NORMAL | FMOD_OPENUSER, &exinfo, &sound); + ERRCHECK(result); + + result = system->recordStart(DEVICE_INDEX, sound, true); + ERRCHECK(result); + + unsigned int soundLength = 0; + result = sound->getLength(&soundLength, FMOD_TIMEUNIT_PCM); + ERRCHECK(result); + + /* + Main loop + */ + do + { + Common_Update(); + + /* + Add a DSP effect -- just for fun + */ + if (Common_BtnPress(BTN_ACTION1)) + { + FMOD_REVERB_PROPERTIES propOn = FMOD_PRESET_CONCERTHALL; + FMOD_REVERB_PROPERTIES propOff = FMOD_PRESET_OFF; + + dspEnabled = !dspEnabled; + + result = system->setReverbProperties(0, dspEnabled ? &propOn : &propOff); + ERRCHECK(result); + } + + result = system->update(); + ERRCHECK(result); + + /* + Determine how much has been recorded since we last checked + */ + unsigned int recordPos = 0; + result = system->getRecordPosition(DEVICE_INDEX, &recordPos); + if (result != FMOD_ERR_RECORD_DISCONNECTED) + { + ERRCHECK(result); + } + + static unsigned int lastRecordPos = 0; + unsigned int recordDelta = (recordPos >= lastRecordPos) ? (recordPos - lastRecordPos) : (recordPos + soundLength - lastRecordPos); + lastRecordPos = recordPos; + samplesRecorded += recordDelta; + + static unsigned int minRecordDelta = (unsigned int)-1; + if (recordDelta && (recordDelta < minRecordDelta)) + { + minRecordDelta = recordDelta; /* Smallest driver granularity seen so far */ + adjustedLatency = (recordDelta <= desiredLatency) ? desiredLatency : recordDelta; /* Adjust our latency if driver granularity is high */ + } + + /* + Delay playback until our desired latency is reached. + */ + if (!channel && samplesRecorded >= adjustedLatency) + { + result = system->playSound(sound, 0, false, &channel); + ERRCHECK(result); + } + + if (channel) + { + /* + Stop playback if recording stops. + */ + bool isRecording = false; + result = system->isRecording(DEVICE_INDEX, &isRecording); + if (result != FMOD_ERR_RECORD_DISCONNECTED) + { + ERRCHECK(result); + } + + if (!isRecording) + { + result = channel->setPaused(true); + ERRCHECK(result); + } + + /* + Determine how much has been played since we last checked. + */ + unsigned int playPos = 0; + result = channel->getPosition(&playPos, FMOD_TIMEUNIT_PCM); + ERRCHECK(result); + + static unsigned int lastPlayPos = 0; + unsigned int playDelta = (playPos >= lastPlayPos) ? (playPos - lastPlayPos) : (playPos + soundLength - lastPlayPos); + lastPlayPos = playPos; + samplesPlayed += playDelta; + + /* + Compensate for any drift. + */ + int latency = samplesRecorded - samplesPlayed; + actualLatency = (int)((0.97f * actualLatency) + (0.03f * latency)); + + int playbackRate = nativeRate; + if (actualLatency < (int)(adjustedLatency - driftThreshold)) + { + /* Play position is catching up to the record position, slow playback down by 2% */ + playbackRate = nativeRate - (nativeRate / 50); + } + else if (actualLatency > (int)(adjustedLatency + driftThreshold)) + { + /* Play position is falling behind the record position, speed playback up by 2% */ + playbackRate = nativeRate + (nativeRate / 50); + } + + channel->setFrequency((float)playbackRate); + ERRCHECK(result); + } + + Common_Draw("=================================================="); + Common_Draw("Record Example."); + Common_Draw("Copyright (c) Firelight Technologies 2004-2026."); + Common_Draw("=================================================="); + Common_Draw(""); + Common_Draw("Adjust LATENCY define to compensate for stuttering"); + Common_Draw("Current value is %dms", LATENCY_MS); + Common_Draw(""); + Common_Draw("Press %s to %s DSP effect", Common_BtnStr(BTN_ACTION1), dspEnabled ? "disable" : "enable"); + Common_Draw("Press %s to quit", Common_BtnStr(BTN_QUIT)); + Common_Draw(""); + Common_Draw("Adjusted latency: %4d (%dms)", adjustedLatency, adjustedLatency * 1000 / nativeRate); + Common_Draw("Actual latency: %4d (%dms)", actualLatency, actualLatency * 1000 / nativeRate); + Common_Draw(""); + Common_Draw("Recorded: %5d (%ds)", samplesRecorded, samplesRecorded / nativeRate); + Common_Draw("Played: %5d (%ds)", samplesPlayed, samplesPlayed / nativeRate); + + Common_Sleep(10); + } while (!Common_BtnPress(BTN_QUIT)); + + /* + Shut down + */ + result = sound->release(); + ERRCHECK(result); + result = system->release(); + ERRCHECK(result); + + Common_Close(); + + return 0; +} diff --git a/FMOD/api/core/examples/record_enumeration.cpp b/FMOD/api/core/examples/record_enumeration.cpp new file mode 100644 index 0000000..c15606d --- /dev/null +++ b/FMOD/api/core/examples/record_enumeration.cpp @@ -0,0 +1,212 @@ +/*============================================================================== +Record enumeration example +Copyright (c), Firelight Technologies Pty, Ltd 2004-2026. + +This example shows how to enumerate the available recording drivers on this +device. It demonstrates how the enumerated list changes as microphones are +attached and detached. It also shows that you can record from multi mics at +the same time. + +Please note to minimize latency care should be taken to control the number +of samples between the record position and the play position. Check the record +example for details on this process. + +For information on using FMOD example code in your own programs, visit +https://www.fmod.com/legal +==============================================================================*/ +#include "fmod.hpp" +#include "common.h" + +static const int MAX_DRIVERS = 16; +static const int MAX_DRIVERS_IN_VIEW = 3; + +struct RECORD_STATE +{ + FMOD::Sound *sound; + FMOD::Channel *channel; +}; + +FMOD_RESULT F_CALL SystemCallback(FMOD_SYSTEM* /*system*/, FMOD_SYSTEM_CALLBACK_TYPE /*type*/, void *, void *, void *userData) +{ + int *recordListChangedCount = (int *)userData; + *recordListChangedCount = *recordListChangedCount + 1; + + return FMOD_OK; +} + +int FMOD_Main() +{ + int scroll = 0; + int cursor = 0; + RECORD_STATE record[MAX_DRIVERS] = { }; + + void *extraDriverData = NULL; + Common_Init(&extraDriverData); + + /* + Create a System object and initialize. + */ + FMOD::System *system = NULL; + FMOD_RESULT result = FMOD::System_Create(&system); + ERRCHECK(result); + + result = system->init(100, FMOD_INIT_NORMAL, extraDriverData); + ERRCHECK(result); + + /* + Setup a callback so we can be notified if the record list has changed. + */ + int recordListChangedCount = 0; + result = system->setUserData(&recordListChangedCount); + ERRCHECK(result); + + result = system->setCallback(&SystemCallback, FMOD_SYSTEM_CALLBACK_RECORDLISTCHANGED); + ERRCHECK(result); + + /* + Main loop + */ + do + { + Common_Update(); + + int numDrivers = 0; + int numConnected = 0; + result = system->getRecordNumDrivers(&numDrivers, &numConnected); + ERRCHECK(result); + + numDrivers = Common_Min(numDrivers, MAX_DRIVERS); /* Clamp the reported number of drivers to simplify this example */ + + if (Common_BtnPress(BTN_ACTION1)) + { + bool isRecording = false; + system->isRecording(cursor, &isRecording); + + if (isRecording) + { + system->recordStop(cursor); + } + else + { + /* Clean up previous record sound */ + if (record[cursor].sound) + { + result = record[cursor].sound->release(); + ERRCHECK(result); + } + + /* Query device native settings and start a recording */ + int nativeRate = 0; + int nativeChannels = 0; + result = system->getRecordDriverInfo(cursor, NULL, 0, NULL, &nativeRate, NULL, &nativeChannels, NULL); + ERRCHECK(result); + + FMOD_CREATESOUNDEXINFO exinfo = {0}; + exinfo.cbsize = sizeof(FMOD_CREATESOUNDEXINFO); + exinfo.numchannels = nativeChannels; + exinfo.format = FMOD_SOUND_FORMAT_PCM16; + exinfo.defaultfrequency = nativeRate; + exinfo.length = nativeRate * sizeof(short) * nativeChannels; /* 1 second buffer, size here doesn't change latency */ + + result = system->createSound(0, FMOD_LOOP_NORMAL | FMOD_OPENUSER, &exinfo, &record[cursor].sound); + ERRCHECK(result); + + result = system->recordStart(cursor, record[cursor].sound, true); + if (result != FMOD_ERR_RECORD_DISCONNECTED) + { + ERRCHECK(result); + } + } + } + else if (Common_BtnPress(BTN_ACTION2)) + { + bool isPlaying = false; + record[cursor].channel->isPlaying(&isPlaying); + + if (isPlaying) + { + record[cursor].channel->stop(); + } + else if (record[cursor].sound) + { + result = system->playSound(record[cursor].sound, NULL, false, &record[cursor].channel); + ERRCHECK(result); + } + } + else if (Common_BtnPress(BTN_UP)) + { + cursor = Common_Max(cursor - 1, 0); + scroll = Common_Max(scroll - 1, 0); + } + else if (Common_BtnPress(BTN_DOWN)) + { + if (numDrivers) + { + cursor = Common_Min(cursor + 1, numDrivers - 1); + } + + if (numDrivers > MAX_DRIVERS_IN_VIEW) + { + scroll = Common_Min(scroll + 1, numDrivers - MAX_DRIVERS_IN_VIEW); + } + } + + result = system->update(); + ERRCHECK(result); + + Common_Draw("=================================================="); + Common_Draw("Record Enumeration Example."); + Common_Draw("Copyright (c) Firelight Technologies 2004-2026."); + Common_Draw("=================================================="); + Common_Draw(""); + Common_Draw("Record list has updated %d time(s).", recordListChangedCount); + Common_Draw("Currently %d device(s) plugged in.", numConnected); + Common_Draw(""); + Common_Draw("Press %s to quit", Common_BtnStr(BTN_QUIT)); + Common_Draw("Press %s and %s to scroll list", Common_BtnStr(BTN_UP), Common_BtnStr(BTN_DOWN)); + Common_Draw("Press %s start / stop recording", Common_BtnStr(BTN_ACTION1)); + Common_Draw("Press %s start / stop playback", Common_BtnStr(BTN_ACTION2)); + Common_Draw(""); + int numDisplay = Common_Min(numDrivers, MAX_DRIVERS_IN_VIEW); + for (int i = scroll; i < scroll + numDisplay; i++) + { + char name[256]; + int sampleRate; + int channels; + FMOD_GUID guid; + FMOD_DRIVER_STATE state; + + result = system->getRecordDriverInfo(i, name, sizeof(name), &guid, &sampleRate, NULL, &channels, &state); + ERRCHECK(result); + + bool isRecording = false; + system->isRecording(i, &isRecording); + + bool isPlaying = false; + record[i].channel->isPlaying(&isPlaying); + + Common_Draw("%c%2d. %s%.41s", (cursor == i) ? '>' : ' ', i, (state & FMOD_DRIVER_STATE_DEFAULT) ? "(*) " : "", name); + Common_Draw("%dKHz %dch {%08X-%04X-%04X-%04X-%02X%02X%02X%02X%02X%02X}", sampleRate / 1000, channels, guid.Data1, guid.Data2, guid.Data3, guid.Data4[0] << 8 | guid.Data4[1], guid.Data4[2], guid.Data4[3], guid.Data4[4], guid.Data4[5], guid.Data4[6], guid.Data4[7]); + Common_Draw("(%s) (%s) (%s)", (state & FMOD_DRIVER_STATE_CONNECTED) ? "Connected" : "Unplugged", isRecording ? "Recording" : "Not recording", isPlaying ? "Playing" : "Not playing"); + Common_Draw(""); + } + + Common_Sleep(50); + } while (!Common_BtnPress(BTN_QUIT)); + + for (int i = 0; i < MAX_DRIVERS; i++) + { + if (record[i].sound) + { + result = record[i].sound->release(); + ERRCHECK(result); + } + } + + result = system->release(); + ERRCHECK(result); + + Common_Close(); + + return 0; +} diff --git a/FMOD/api/core/examples/user_created_sound.cpp b/FMOD/api/core/examples/user_created_sound.cpp new file mode 100644 index 0000000..12eeba3 --- /dev/null +++ b/FMOD/api/core/examples/user_created_sound.cpp @@ -0,0 +1,190 @@ +/*============================================================================== +User Created Sound Example +Copyright (c), Firelight Technologies Pty, Ltd 2004-2026. + +This example shows how create a sound with data filled by the user. It shows a +user created static sample, followed by a user created stream. The former +allocates all memory needed for the sound and is played back as a static sample, +while the latter streams the data in chunks as it plays, using far less memory. + +For information on using FMOD example code in your own programs, visit +https://www.fmod.com/legal +==============================================================================*/ +#include "fmod.hpp" +#include "common.h" +#include + +FMOD_RESULT F_CALL pcmreadcallback(FMOD_SOUND* /*sound*/, void *data, unsigned int datalen) +{ + static float t1 = 0, t2 = 0; // time + static float v1 = 0, v2 = 0; // velocity + signed short *stereo16bitbuffer = (signed short *)data; + + for (unsigned int count = 0; count < (datalen >> 2); count++) // >>2 = 16bit stereo (4 bytes per sample) + { + *stereo16bitbuffer++ = (signed short)(Common_Sin(t1) * 32767.0f); // left channel + *stereo16bitbuffer++ = (signed short)(Common_Sin(t2) * 32767.0f); // right channel + + t1 += 0.01f + v1; + t2 += 0.0142f + v2; + v1 += (float)(Common_Sin(t1) * 0.002f); + v2 += (float)(Common_Sin(t2) * 0.002f); + } + + return FMOD_OK; +} + +FMOD_RESULT F_CALL pcmsetposcallback(FMOD_SOUND* /*sound*/, int /*subsound*/, unsigned int /*position*/, FMOD_TIMEUNIT /*postype*/) +{ + /* + This is useful if the user calls Channel::setPosition and you want to seek your data accordingly. + */ + return FMOD_OK; +} + +int FMOD_Main() +{ + FMOD::System *system; + FMOD::Sound *sound; + FMOD::Channel *channel = 0; + FMOD_RESULT result; + FMOD_MODE mode = FMOD_OPENUSER | FMOD_LOOP_NORMAL; + FMOD_CREATESOUNDEXINFO exinfo; + void *extradriverdata = 0; + + Common_Init(&extradriverdata); + + /* + Create a System object and initialize. + */ + result = FMOD::System_Create(&system); + ERRCHECK(result); + + result = system->init(32, FMOD_INIT_NORMAL, extradriverdata); + ERRCHECK(result); + + do + { + Common_Update(); + + if (Common_BtnPress(BTN_ACTION1)) + { + mode |= FMOD_CREATESTREAM; + } + + result = system->update(); + ERRCHECK(result); + + Common_Draw("=================================================="); + Common_Draw("User Created Sound Example."); + Common_Draw("Copyright (c) Firelight Technologies 2004-2026."); + Common_Draw("=================================================="); + Common_Draw(""); + Common_Draw("Sound played here is generated in realtime. It will either play as a stream which means it is continually filled as it is playing, or it will play as a static sample, which means it is filled once as the sound is created, then when played it will just play that short loop of data."); + Common_Draw(""); + Common_Draw("Press %s to play an infinite generated stream", Common_BtnStr(BTN_ACTION1)); + Common_Draw("Press %s to play a static looping sample", Common_BtnStr(BTN_ACTION2)); + Common_Draw(""); + + Common_Sleep(50); + } while (!Common_BtnPress(BTN_ACTION1) && !Common_BtnPress(BTN_ACTION2) && !Common_BtnPress(BTN_QUIT)); + + /* + Create and play the sound. + */ + memset(&exinfo, 0, sizeof(FMOD_CREATESOUNDEXINFO)); + exinfo.cbsize = sizeof(FMOD_CREATESOUNDEXINFO); /* Required. */ + exinfo.numchannels = 2; /* Number of channels in the sound. */ + exinfo.defaultfrequency = 44100; /* Default playback rate of sound. */ + exinfo.decodebuffersize = 44100; /* Chunk size of stream update in samples. This will be the amount of data passed to the user callback. */ + exinfo.length = exinfo.defaultfrequency * exinfo.numchannels * sizeof(signed short) * 5; /* Length of PCM data in bytes of whole song (for Sound::getLength) */ + exinfo.format = FMOD_SOUND_FORMAT_PCM16; /* Data format of sound. */ + exinfo.pcmreadcallback = pcmreadcallback; /* User callback for reading. */ + exinfo.pcmsetposcallback = pcmsetposcallback; /* User callback for seeking. */ + + result = system->createSound(0, mode, &exinfo, &sound); + ERRCHECK(result); + + result = system->playSound(sound, 0, 0, &channel); + ERRCHECK(result); + + /* + Main loop. + */ + do + { + Common_Update(); + + if (Common_BtnPress(BTN_ACTION1)) + { + bool paused; + result = channel->getPaused(&paused); + ERRCHECK(result); + result = channel->setPaused(!paused); + ERRCHECK(result); + } + + result = system->update(); + ERRCHECK(result); + + { + unsigned int ms = 0; + unsigned int lenms = 0; + bool playing = false; + bool paused = false; + + if (channel) + { + result = channel->isPlaying(&playing); + if ((result != FMOD_OK) && (result != FMOD_ERR_INVALID_HANDLE)) + { + ERRCHECK(result); + } + + result = channel->getPaused(&paused); + if ((result != FMOD_OK) && (result != FMOD_ERR_INVALID_HANDLE)) + { + ERRCHECK(result); + } + + result = channel->getPosition(&ms, FMOD_TIMEUNIT_MS); + if ((result != FMOD_OK) && (result != FMOD_ERR_INVALID_HANDLE)) + { + ERRCHECK(result); + } + + result = sound->getLength(&lenms, FMOD_TIMEUNIT_MS); + if ((result != FMOD_OK) && (result != FMOD_ERR_INVALID_HANDLE)) + { + ERRCHECK(result); + } + } + + Common_Draw("=================================================="); + Common_Draw("User Created Sound Example."); + Common_Draw("Copyright (c) Firelight Technologies 2004-2026."); + Common_Draw("=================================================="); + Common_Draw(""); + Common_Draw("Press %s to toggle pause", Common_BtnStr(BTN_ACTION1)); + Common_Draw("Press %s to quit", Common_BtnStr(BTN_QUIT)); + Common_Draw(""); + Common_Draw("Time %02d:%02d:%02d/%02d:%02d:%02d : %s", ms / 1000 / 60, ms / 1000 % 60, ms / 10 % 100, lenms / 1000 / 60, lenms / 1000 % 60, lenms / 10 % 100, paused ? "Paused " : playing ? "Playing" : "Stopped"); + } + + Common_Sleep(50); + } while (!Common_BtnPress(BTN_QUIT)); + + /* + Shut down + */ + result = sound->release(); + ERRCHECK(result); + result = system->close(); + ERRCHECK(result); + result = system->release(); + ERRCHECK(result); + + Common_Close(); + + return 0; +} diff --git a/FMOD/api/core/examples/vs2017/3d.vcxproj b/FMOD/api/core/examples/vs2017/3d.vcxproj new file mode 100644 index 0000000..f4ce163 --- /dev/null +++ b/FMOD/api/core/examples/vs2017/3d.vcxproj @@ -0,0 +1,83 @@ + + + + + Debug + Win32 + + + Debug + x64 + + + Debug + ARM64 + + + Release + Win32 + + + Release + x64 + + + Release + ARM64 + + + + x86 + x64 + ARM64 + L + + + {30AC8E0A-4195-49B0-952B-D5474CE6FE30} + + + + Application + v141 + false + true + + + + $(SolutionDir)_builds\$(ProjectName)\$(Configuration)\$(Platform)\ + $(SolutionDir)_builds\$(ProjectName)\$(Configuration)\$(Platform)\Intermediate\ + false + $(ProjectName)$(Suffix) + + + + Level3 + ..\..\inc + ProgramDatabase + _WIN32_WINNT=0x601;WINVER=0x601;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) + + + Windows + true + ..\..\lib\$(Arch) + fmod$(Suffix)_vc.lib;%(AdditionalDependencies) + + + if not exist ..\bin mkdir ..\bin +copy /Y "$(TargetPath)" ..\bin +copy /Y "..\..\lib\$(Arch)\fmod$(Suffix).dll" ..\bin +copy /Y "..\..\lib\$(Arch)\fmod$(Suffix).dll" "$(OutDir)" + + + + + + + + + + + + + + diff --git a/FMOD/api/core/examples/vs2017/3d.vcxproj.filters b/FMOD/api/core/examples/vs2017/3d.vcxproj.filters new file mode 100644 index 0000000..fc0f117 --- /dev/null +++ b/FMOD/api/core/examples/vs2017/3d.vcxproj.filters @@ -0,0 +1,24 @@ + + + + + common + + + common + + + + + {937abb1b-0123-4875-9828-07ed9f9813e3} + + + + + common + + + common + + + \ No newline at end of file diff --git a/FMOD/api/core/examples/vs2017/asyncio.vcxproj b/FMOD/api/core/examples/vs2017/asyncio.vcxproj new file mode 100644 index 0000000..ad42f43 --- /dev/null +++ b/FMOD/api/core/examples/vs2017/asyncio.vcxproj @@ -0,0 +1,83 @@ + + + + + Debug + Win32 + + + Debug + x64 + + + Debug + ARM64 + + + Release + Win32 + + + Release + x64 + + + Release + ARM64 + + + + x86 + x64 + ARM64 + L + + + {FC49B503-C66E-48BA-A0C4-48EC5A3566F5} + + + + Application + v141 + false + true + + + + $(SolutionDir)_builds\$(ProjectName)\$(Configuration)\$(Platform)\ + $(SolutionDir)_builds\$(ProjectName)\$(Configuration)\$(Platform)\Intermediate\ + false + $(ProjectName)$(Suffix) + + + + Level3 + ..\..\inc + ProgramDatabase + _WIN32_WINNT=0x601;WINVER=0x601;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) + + + Windows + true + ..\..\lib\$(Arch) + fmod$(Suffix)_vc.lib;%(AdditionalDependencies) + + + if not exist ..\bin mkdir ..\bin +copy /Y "$(TargetPath)" ..\bin +copy /Y "..\..\lib\$(Arch)\fmod$(Suffix).dll" ..\bin +copy /Y "..\..\lib\$(Arch)\fmod$(Suffix).dll" "$(OutDir)" + + + + + + + + + + + + + + diff --git a/FMOD/api/core/examples/vs2017/asyncio.vcxproj.filters b/FMOD/api/core/examples/vs2017/asyncio.vcxproj.filters new file mode 100644 index 0000000..fc0f117 --- /dev/null +++ b/FMOD/api/core/examples/vs2017/asyncio.vcxproj.filters @@ -0,0 +1,24 @@ + + + + + common + + + common + + + + + {937abb1b-0123-4875-9828-07ed9f9813e3} + + + + + common + + + common + + + \ No newline at end of file diff --git a/FMOD/api/core/examples/vs2017/channel_groups.vcxproj b/FMOD/api/core/examples/vs2017/channel_groups.vcxproj new file mode 100644 index 0000000..fa9c5d2 --- /dev/null +++ b/FMOD/api/core/examples/vs2017/channel_groups.vcxproj @@ -0,0 +1,83 @@ + + + + + Debug + Win32 + + + Debug + x64 + + + Debug + ARM64 + + + Release + Win32 + + + Release + x64 + + + Release + ARM64 + + + + x86 + x64 + ARM64 + L + + + {60C14B8A-9B03-4C7D-8897-21A1F7B30EBF} + + + + Application + v141 + false + true + + + + $(SolutionDir)_builds\$(ProjectName)\$(Configuration)\$(Platform)\ + $(SolutionDir)_builds\$(ProjectName)\$(Configuration)\$(Platform)\Intermediate\ + false + $(ProjectName)$(Suffix) + + + + Level3 + ..\..\inc + ProgramDatabase + _WIN32_WINNT=0x601;WINVER=0x601;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) + + + Windows + true + ..\..\lib\$(Arch) + fmod$(Suffix)_vc.lib;%(AdditionalDependencies) + + + if not exist ..\bin mkdir ..\bin +copy /Y "$(TargetPath)" ..\bin +copy /Y "..\..\lib\$(Arch)\fmod$(Suffix).dll" ..\bin +copy /Y "..\..\lib\$(Arch)\fmod$(Suffix).dll" "$(OutDir)" + + + + + + + + + + + + + + diff --git a/FMOD/api/core/examples/vs2017/channel_groups.vcxproj.filters b/FMOD/api/core/examples/vs2017/channel_groups.vcxproj.filters new file mode 100644 index 0000000..fc0f117 --- /dev/null +++ b/FMOD/api/core/examples/vs2017/channel_groups.vcxproj.filters @@ -0,0 +1,24 @@ + + + + + common + + + common + + + + + {937abb1b-0123-4875-9828-07ed9f9813e3} + + + + + common + + + common + + + \ No newline at end of file diff --git a/FMOD/api/core/examples/vs2017/convolution_reverb.vcxproj b/FMOD/api/core/examples/vs2017/convolution_reverb.vcxproj new file mode 100644 index 0000000..f31e237 --- /dev/null +++ b/FMOD/api/core/examples/vs2017/convolution_reverb.vcxproj @@ -0,0 +1,83 @@ + + + + + Debug + Win32 + + + Debug + x64 + + + Debug + ARM64 + + + Release + Win32 + + + Release + x64 + + + Release + ARM64 + + + + x86 + x64 + ARM64 + L + + + {6B8D7510-68F8-4563-B717-DC5564BDC838} + + + + Application + v141 + false + true + + + + $(SolutionDir)_builds\$(ProjectName)\$(Configuration)\$(Platform)\ + $(SolutionDir)_builds\$(ProjectName)\$(Configuration)\$(Platform)\Intermediate\ + false + $(ProjectName)$(Suffix) + + + + Level3 + ..\..\inc + ProgramDatabase + _WIN32_WINNT=0x601;WINVER=0x601;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) + + + Windows + true + ..\..\lib\$(Arch) + fmod$(Suffix)_vc.lib;%(AdditionalDependencies) + + + if not exist ..\bin mkdir ..\bin +copy /Y "$(TargetPath)" ..\bin +copy /Y "..\..\lib\$(Arch)\fmod$(Suffix).dll" ..\bin +copy /Y "..\..\lib\$(Arch)\fmod$(Suffix).dll" "$(OutDir)" + + + + + + + + + + + + + + diff --git a/FMOD/api/core/examples/vs2017/convolution_reverb.vcxproj.filters b/FMOD/api/core/examples/vs2017/convolution_reverb.vcxproj.filters new file mode 100644 index 0000000..fc0f117 --- /dev/null +++ b/FMOD/api/core/examples/vs2017/convolution_reverb.vcxproj.filters @@ -0,0 +1,24 @@ + + + + + common + + + common + + + + + {937abb1b-0123-4875-9828-07ed9f9813e3} + + + + + common + + + common + + + \ No newline at end of file diff --git a/FMOD/api/core/examples/vs2017/dsp_custom.vcxproj b/FMOD/api/core/examples/vs2017/dsp_custom.vcxproj new file mode 100644 index 0000000..e91cd95 --- /dev/null +++ b/FMOD/api/core/examples/vs2017/dsp_custom.vcxproj @@ -0,0 +1,83 @@ + + + + + Debug + Win32 + + + Debug + x64 + + + Debug + ARM64 + + + Release + Win32 + + + Release + x64 + + + Release + ARM64 + + + + x86 + x64 + ARM64 + L + + + {73621A08-B29F-4B69-82FD-30A60F97CF8C} + + + + Application + v141 + false + true + + + + $(SolutionDir)_builds\$(ProjectName)\$(Configuration)\$(Platform)\ + $(SolutionDir)_builds\$(ProjectName)\$(Configuration)\$(Platform)\Intermediate\ + false + $(ProjectName)$(Suffix) + + + + Level3 + ..\..\inc + ProgramDatabase + _WIN32_WINNT=0x601;WINVER=0x601;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) + + + Windows + true + ..\..\lib\$(Arch) + fmod$(Suffix)_vc.lib;%(AdditionalDependencies) + + + if not exist ..\bin mkdir ..\bin +copy /Y "$(TargetPath)" ..\bin +copy /Y "..\..\lib\$(Arch)\fmod$(Suffix).dll" ..\bin +copy /Y "..\..\lib\$(Arch)\fmod$(Suffix).dll" "$(OutDir)" + + + + + + + + + + + + + + diff --git a/FMOD/api/core/examples/vs2017/dsp_custom.vcxproj.filters b/FMOD/api/core/examples/vs2017/dsp_custom.vcxproj.filters new file mode 100644 index 0000000..fc0f117 --- /dev/null +++ b/FMOD/api/core/examples/vs2017/dsp_custom.vcxproj.filters @@ -0,0 +1,24 @@ + + + + + common + + + common + + + + + {937abb1b-0123-4875-9828-07ed9f9813e3} + + + + + common + + + common + + + \ No newline at end of file diff --git a/FMOD/api/core/examples/vs2017/dsp_effect_per_speaker.vcxproj b/FMOD/api/core/examples/vs2017/dsp_effect_per_speaker.vcxproj new file mode 100644 index 0000000..cf6f28e --- /dev/null +++ b/FMOD/api/core/examples/vs2017/dsp_effect_per_speaker.vcxproj @@ -0,0 +1,83 @@ + + + + + Debug + Win32 + + + Debug + x64 + + + Debug + ARM64 + + + Release + Win32 + + + Release + x64 + + + Release + ARM64 + + + + x86 + x64 + ARM64 + L + + + {8C2A2903-4326-4E80-B511-1F6D130D48A7} + + + + Application + v141 + false + true + + + + $(SolutionDir)_builds\$(ProjectName)\$(Configuration)\$(Platform)\ + $(SolutionDir)_builds\$(ProjectName)\$(Configuration)\$(Platform)\Intermediate\ + false + $(ProjectName)$(Suffix) + + + + Level3 + ..\..\inc + ProgramDatabase + _WIN32_WINNT=0x601;WINVER=0x601;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) + + + Windows + true + ..\..\lib\$(Arch) + fmod$(Suffix)_vc.lib;%(AdditionalDependencies) + + + if not exist ..\bin mkdir ..\bin +copy /Y "$(TargetPath)" ..\bin +copy /Y "..\..\lib\$(Arch)\fmod$(Suffix).dll" ..\bin +copy /Y "..\..\lib\$(Arch)\fmod$(Suffix).dll" "$(OutDir)" + + + + + + + + + + + + + + diff --git a/FMOD/api/core/examples/vs2017/dsp_effect_per_speaker.vcxproj.filters b/FMOD/api/core/examples/vs2017/dsp_effect_per_speaker.vcxproj.filters new file mode 100644 index 0000000..fc0f117 --- /dev/null +++ b/FMOD/api/core/examples/vs2017/dsp_effect_per_speaker.vcxproj.filters @@ -0,0 +1,24 @@ + + + + + common + + + common + + + + + {937abb1b-0123-4875-9828-07ed9f9813e3} + + + + + common + + + common + + + \ No newline at end of file diff --git a/FMOD/api/core/examples/vs2017/dsp_inspector.vcxproj b/FMOD/api/core/examples/vs2017/dsp_inspector.vcxproj new file mode 100644 index 0000000..946b23c --- /dev/null +++ b/FMOD/api/core/examples/vs2017/dsp_inspector.vcxproj @@ -0,0 +1,83 @@ + + + + + Debug + Win32 + + + Debug + x64 + + + Debug + ARM64 + + + Release + Win32 + + + Release + x64 + + + Release + ARM64 + + + + x86 + x64 + ARM64 + L + + + {BADDC3B7-41EE-489C-A539-63D604B65ABA} + + + + Application + v141 + false + true + + + + $(SolutionDir)_builds\$(ProjectName)\$(Configuration)\$(Platform)\ + $(SolutionDir)_builds\$(ProjectName)\$(Configuration)\$(Platform)\Intermediate\ + false + $(ProjectName)$(Suffix) + + + + Level3 + ..\..\inc + ProgramDatabase + _WIN32_WINNT=0x601;WINVER=0x601;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) + + + Windows + true + ..\..\lib\$(Arch) + fmod$(Suffix)_vc.lib;%(AdditionalDependencies) + + + if not exist ..\bin mkdir ..\bin +copy /Y "$(TargetPath)" ..\bin +copy /Y "..\..\lib\$(Arch)\fmod$(Suffix).dll" ..\bin +copy /Y "..\..\lib\$(Arch)\fmod$(Suffix).dll" "$(OutDir)" + + + + + + + + + + + + + + diff --git a/FMOD/api/core/examples/vs2017/dsp_inspector.vcxproj.filters b/FMOD/api/core/examples/vs2017/dsp_inspector.vcxproj.filters new file mode 100644 index 0000000..fc0f117 --- /dev/null +++ b/FMOD/api/core/examples/vs2017/dsp_inspector.vcxproj.filters @@ -0,0 +1,24 @@ + + + + + common + + + common + + + + + {937abb1b-0123-4875-9828-07ed9f9813e3} + + + + + common + + + common + + + \ No newline at end of file diff --git a/FMOD/api/core/examples/vs2017/effects.vcxproj b/FMOD/api/core/examples/vs2017/effects.vcxproj new file mode 100644 index 0000000..e3d76fa --- /dev/null +++ b/FMOD/api/core/examples/vs2017/effects.vcxproj @@ -0,0 +1,83 @@ + + + + + Debug + Win32 + + + Debug + x64 + + + Debug + ARM64 + + + Release + Win32 + + + Release + x64 + + + Release + ARM64 + + + + x86 + x64 + ARM64 + L + + + {7B9811CE-71EA-4D23-A568-DE5CE4CAB874} + + + + Application + v141 + false + true + + + + $(SolutionDir)_builds\$(ProjectName)\$(Configuration)\$(Platform)\ + $(SolutionDir)_builds\$(ProjectName)\$(Configuration)\$(Platform)\Intermediate\ + false + $(ProjectName)$(Suffix) + + + + Level3 + ..\..\inc + ProgramDatabase + _WIN32_WINNT=0x601;WINVER=0x601;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) + + + Windows + true + ..\..\lib\$(Arch) + fmod$(Suffix)_vc.lib;%(AdditionalDependencies) + + + if not exist ..\bin mkdir ..\bin +copy /Y "$(TargetPath)" ..\bin +copy /Y "..\..\lib\$(Arch)\fmod$(Suffix).dll" ..\bin +copy /Y "..\..\lib\$(Arch)\fmod$(Suffix).dll" "$(OutDir)" + + + + + + + + + + + + + + diff --git a/FMOD/api/core/examples/vs2017/effects.vcxproj.filters b/FMOD/api/core/examples/vs2017/effects.vcxproj.filters new file mode 100644 index 0000000..fc0f117 --- /dev/null +++ b/FMOD/api/core/examples/vs2017/effects.vcxproj.filters @@ -0,0 +1,24 @@ + + + + + common + + + common + + + + + {937abb1b-0123-4875-9828-07ed9f9813e3} + + + + + common + + + common + + + \ No newline at end of file diff --git a/FMOD/api/core/examples/vs2017/examples.sln b/FMOD/api/core/examples/vs2017/examples.sln new file mode 100644 index 0000000..c3e0dfb --- /dev/null +++ b/FMOD/api/core/examples/vs2017/examples.sln @@ -0,0 +1,538 @@ + +Microsoft Visual Studio Solution File, Format Version 11.00 +# Visual Studio 15 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "3d", "3d.vcxproj", "{30AC8E0A-4195-49B0-952B-D5474CE6FE30}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "asyncio", "asyncio.vcxproj", "{FC49B503-C66E-48BA-A0C4-48EC5A3566F5}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "channel_groups", "channel_groups.vcxproj", "{60C14B8A-9B03-4C7D-8897-21A1F7B30EBF}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "convolution_reverb", "convolution_reverb.vcxproj", "{6B8D7510-68F8-4563-B717-DC5564BDC838}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "dsp_custom", "dsp_custom.vcxproj", "{73621A08-B29F-4B69-82FD-30A60F97CF8C}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "dsp_effect_per_speaker", "dsp_effect_per_speaker.vcxproj", "{8C2A2903-4326-4E80-B511-1F6D130D48A7}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "dsp_inspector", "dsp_inspector.vcxproj", "{BADDC3B7-41EE-489C-A539-63D604B65ABA}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "effects", "effects.vcxproj", "{7B9811CE-71EA-4D23-A568-DE5CE4CAB874}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "gapless_playback", "gapless_playback.vcxproj", "{2A310F24-BF68-40A0-80DB-151A2C2DD19E}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "generate_tone", "generate_tone.vcxproj", "{2E9195B6-781C-4639-A89E-5518DBFF9B4B}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "granular_synth", "granular_synth.vcxproj", "{CD76FEC4-A143-425F-8C9C-148A4F8A75AB}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "load_from_memory", "load_from_memory.vcxproj", "{A4C690BA-86FE-4786-A373-B3DAADE8863A}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "multiple_speaker", "multiple_speaker.vcxproj", "{F12F3706-097B-48BB-B71C-92D7885543D9}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "multiple_system", "multiple_system.vcxproj", "{F55FABF2-4D21-4F66-A0DF-4A47CA5356FA}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "net_stream", "net_stream.vcxproj", "{B97E6091-EC38-4A34-964A-C903A1C6D254}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "play_sound", "play_sound.vcxproj", "{1823CB20-54DC-4F68-BDB4-0083B01D6326}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "play_stream", "play_stream.vcxproj", "{6BCA9E05-7327-4421-A5E6-82751ECA6380}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "record", "record.vcxproj", "{18D60FC0-7F72-45E0-9244-4A8F23DB4728}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "record_enumeration", "record_enumeration.vcxproj", "{37C4A65D-768C-46EF-8BDE-23A5DB762328}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "user_created_sound", "user_created_sound.vcxproj", "{85EBD7F6-DF34-4815-83BE-5B0516B7F098}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "fmod_codec_raw", "fmod_codec_raw.vcxproj", "{EFBD6DB6-3999-49A9-9397-FAD2FD863A87}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "fmod_distance_filter", "fmod_distance_filter.vcxproj", "{89CF5705-9092-4C80-BAAE-D645855D8E3C}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "fmod_gain", "fmod_gain.vcxproj", "{DA265C8D-292E-4622-8D66-AD911719607C}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "fmod_noise", "fmod_noise.vcxproj", "{E4525091-8E93-4075-9FB6-C2AEAD70AC63}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "fmod_rnbo", "fmod_rnbo.vcxproj", "{45445B97-5844-460E-8C8A-8C8A9BCA01BB}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "output_mp3", "output_mp3.vcxproj", "{546C5980-388B-4A05-ABE8-6DC366DBFA98}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Win32 = Debug|Win32 + Debug|x64 = Debug|x64 + Debug|ARM64 = Debug|ARM64 + Release|Win32 = Release|Win32 + Release|x64 = Release|x64 + Release|ARM64 = Release|ARM64 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {30AC8E0A-4195-49B0-952B-D5474CE6FE30}.Debug|Win32.ActiveCfg = Debug|Win32 + {30AC8E0A-4195-49B0-952B-D5474CE6FE30}.Debug|Win32.Build.0 = Debug|Win32 + {30AC8E0A-4195-49B0-952B-D5474CE6FE30}.Debug|Win32.Deploy.0 = Debug|Win32 + {30AC8E0A-4195-49B0-952B-D5474CE6FE30}.Debug|x64.ActiveCfg = Debug|x64 + {30AC8E0A-4195-49B0-952B-D5474CE6FE30}.Debug|x64.Build.0 = Debug|x64 + {30AC8E0A-4195-49B0-952B-D5474CE6FE30}.Debug|x64.Deploy.0 = Debug|x64 + {30AC8E0A-4195-49B0-952B-D5474CE6FE30}.Debug|ARM64.ActiveCfg = Debug|ARM64 + {30AC8E0A-4195-49B0-952B-D5474CE6FE30}.Debug|ARM64.Build.0 = Debug|ARM64 + {30AC8E0A-4195-49B0-952B-D5474CE6FE30}.Debug|ARM64.Deploy.0 = Debug|ARM64 + {30AC8E0A-4195-49B0-952B-D5474CE6FE30}.Release|Win32.ActiveCfg = Release|Win32 + {30AC8E0A-4195-49B0-952B-D5474CE6FE30}.Release|Win32.Build.0 = Release|Win32 + {30AC8E0A-4195-49B0-952B-D5474CE6FE30}.Release|Win32.Deploy.0 = Release|Win32 + {30AC8E0A-4195-49B0-952B-D5474CE6FE30}.Release|x64.ActiveCfg = Release|x64 + {30AC8E0A-4195-49B0-952B-D5474CE6FE30}.Release|x64.Build.0 = Release|x64 + {30AC8E0A-4195-49B0-952B-D5474CE6FE30}.Release|x64.Deploy.0 = Release|x64 + {30AC8E0A-4195-49B0-952B-D5474CE6FE30}.Release|ARM64.ActiveCfg = Release|ARM64 + {30AC8E0A-4195-49B0-952B-D5474CE6FE30}.Release|ARM64.Build.0 = Release|ARM64 + {30AC8E0A-4195-49B0-952B-D5474CE6FE30}.Release|ARM64.Deploy.0 = Release|ARM64 + {FC49B503-C66E-48BA-A0C4-48EC5A3566F5}.Debug|Win32.ActiveCfg = Debug|Win32 + {FC49B503-C66E-48BA-A0C4-48EC5A3566F5}.Debug|Win32.Build.0 = Debug|Win32 + {FC49B503-C66E-48BA-A0C4-48EC5A3566F5}.Debug|Win32.Deploy.0 = Debug|Win32 + {FC49B503-C66E-48BA-A0C4-48EC5A3566F5}.Debug|x64.ActiveCfg = Debug|x64 + {FC49B503-C66E-48BA-A0C4-48EC5A3566F5}.Debug|x64.Build.0 = Debug|x64 + {FC49B503-C66E-48BA-A0C4-48EC5A3566F5}.Debug|x64.Deploy.0 = Debug|x64 + {FC49B503-C66E-48BA-A0C4-48EC5A3566F5}.Debug|ARM64.ActiveCfg = Debug|ARM64 + {FC49B503-C66E-48BA-A0C4-48EC5A3566F5}.Debug|ARM64.Build.0 = Debug|ARM64 + {FC49B503-C66E-48BA-A0C4-48EC5A3566F5}.Debug|ARM64.Deploy.0 = Debug|ARM64 + {FC49B503-C66E-48BA-A0C4-48EC5A3566F5}.Release|Win32.ActiveCfg = Release|Win32 + {FC49B503-C66E-48BA-A0C4-48EC5A3566F5}.Release|Win32.Build.0 = Release|Win32 + {FC49B503-C66E-48BA-A0C4-48EC5A3566F5}.Release|Win32.Deploy.0 = Release|Win32 + {FC49B503-C66E-48BA-A0C4-48EC5A3566F5}.Release|x64.ActiveCfg = Release|x64 + {FC49B503-C66E-48BA-A0C4-48EC5A3566F5}.Release|x64.Build.0 = Release|x64 + {FC49B503-C66E-48BA-A0C4-48EC5A3566F5}.Release|x64.Deploy.0 = Release|x64 + {FC49B503-C66E-48BA-A0C4-48EC5A3566F5}.Release|ARM64.ActiveCfg = Release|ARM64 + {FC49B503-C66E-48BA-A0C4-48EC5A3566F5}.Release|ARM64.Build.0 = Release|ARM64 + {FC49B503-C66E-48BA-A0C4-48EC5A3566F5}.Release|ARM64.Deploy.0 = Release|ARM64 + {60C14B8A-9B03-4C7D-8897-21A1F7B30EBF}.Debug|Win32.ActiveCfg = Debug|Win32 + {60C14B8A-9B03-4C7D-8897-21A1F7B30EBF}.Debug|Win32.Build.0 = Debug|Win32 + {60C14B8A-9B03-4C7D-8897-21A1F7B30EBF}.Debug|Win32.Deploy.0 = Debug|Win32 + {60C14B8A-9B03-4C7D-8897-21A1F7B30EBF}.Debug|x64.ActiveCfg = Debug|x64 + {60C14B8A-9B03-4C7D-8897-21A1F7B30EBF}.Debug|x64.Build.0 = Debug|x64 + {60C14B8A-9B03-4C7D-8897-21A1F7B30EBF}.Debug|x64.Deploy.0 = Debug|x64 + {60C14B8A-9B03-4C7D-8897-21A1F7B30EBF}.Debug|ARM64.ActiveCfg = Debug|ARM64 + {60C14B8A-9B03-4C7D-8897-21A1F7B30EBF}.Debug|ARM64.Build.0 = Debug|ARM64 + {60C14B8A-9B03-4C7D-8897-21A1F7B30EBF}.Debug|ARM64.Deploy.0 = Debug|ARM64 + {60C14B8A-9B03-4C7D-8897-21A1F7B30EBF}.Release|Win32.ActiveCfg = Release|Win32 + {60C14B8A-9B03-4C7D-8897-21A1F7B30EBF}.Release|Win32.Build.0 = Release|Win32 + {60C14B8A-9B03-4C7D-8897-21A1F7B30EBF}.Release|Win32.Deploy.0 = Release|Win32 + {60C14B8A-9B03-4C7D-8897-21A1F7B30EBF}.Release|x64.ActiveCfg = Release|x64 + {60C14B8A-9B03-4C7D-8897-21A1F7B30EBF}.Release|x64.Build.0 = Release|x64 + {60C14B8A-9B03-4C7D-8897-21A1F7B30EBF}.Release|x64.Deploy.0 = Release|x64 + {60C14B8A-9B03-4C7D-8897-21A1F7B30EBF}.Release|ARM64.ActiveCfg = Release|ARM64 + {60C14B8A-9B03-4C7D-8897-21A1F7B30EBF}.Release|ARM64.Build.0 = Release|ARM64 + {60C14B8A-9B03-4C7D-8897-21A1F7B30EBF}.Release|ARM64.Deploy.0 = Release|ARM64 + {6B8D7510-68F8-4563-B717-DC5564BDC838}.Debug|Win32.ActiveCfg = Debug|Win32 + {6B8D7510-68F8-4563-B717-DC5564BDC838}.Debug|Win32.Build.0 = Debug|Win32 + {6B8D7510-68F8-4563-B717-DC5564BDC838}.Debug|Win32.Deploy.0 = Debug|Win32 + {6B8D7510-68F8-4563-B717-DC5564BDC838}.Debug|x64.ActiveCfg = Debug|x64 + {6B8D7510-68F8-4563-B717-DC5564BDC838}.Debug|x64.Build.0 = Debug|x64 + {6B8D7510-68F8-4563-B717-DC5564BDC838}.Debug|x64.Deploy.0 = Debug|x64 + {6B8D7510-68F8-4563-B717-DC5564BDC838}.Debug|ARM64.ActiveCfg = Debug|ARM64 + {6B8D7510-68F8-4563-B717-DC5564BDC838}.Debug|ARM64.Build.0 = Debug|ARM64 + {6B8D7510-68F8-4563-B717-DC5564BDC838}.Debug|ARM64.Deploy.0 = Debug|ARM64 + {6B8D7510-68F8-4563-B717-DC5564BDC838}.Release|Win32.ActiveCfg = Release|Win32 + {6B8D7510-68F8-4563-B717-DC5564BDC838}.Release|Win32.Build.0 = Release|Win32 + {6B8D7510-68F8-4563-B717-DC5564BDC838}.Release|Win32.Deploy.0 = Release|Win32 + {6B8D7510-68F8-4563-B717-DC5564BDC838}.Release|x64.ActiveCfg = Release|x64 + {6B8D7510-68F8-4563-B717-DC5564BDC838}.Release|x64.Build.0 = Release|x64 + {6B8D7510-68F8-4563-B717-DC5564BDC838}.Release|x64.Deploy.0 = Release|x64 + {6B8D7510-68F8-4563-B717-DC5564BDC838}.Release|ARM64.ActiveCfg = Release|ARM64 + {6B8D7510-68F8-4563-B717-DC5564BDC838}.Release|ARM64.Build.0 = Release|ARM64 + {6B8D7510-68F8-4563-B717-DC5564BDC838}.Release|ARM64.Deploy.0 = Release|ARM64 + {73621A08-B29F-4B69-82FD-30A60F97CF8C}.Debug|Win32.ActiveCfg = Debug|Win32 + {73621A08-B29F-4B69-82FD-30A60F97CF8C}.Debug|Win32.Build.0 = Debug|Win32 + {73621A08-B29F-4B69-82FD-30A60F97CF8C}.Debug|Win32.Deploy.0 = Debug|Win32 + {73621A08-B29F-4B69-82FD-30A60F97CF8C}.Debug|x64.ActiveCfg = Debug|x64 + {73621A08-B29F-4B69-82FD-30A60F97CF8C}.Debug|x64.Build.0 = Debug|x64 + {73621A08-B29F-4B69-82FD-30A60F97CF8C}.Debug|x64.Deploy.0 = Debug|x64 + {73621A08-B29F-4B69-82FD-30A60F97CF8C}.Debug|ARM64.ActiveCfg = Debug|ARM64 + {73621A08-B29F-4B69-82FD-30A60F97CF8C}.Debug|ARM64.Build.0 = Debug|ARM64 + {73621A08-B29F-4B69-82FD-30A60F97CF8C}.Debug|ARM64.Deploy.0 = Debug|ARM64 + {73621A08-B29F-4B69-82FD-30A60F97CF8C}.Release|Win32.ActiveCfg = Release|Win32 + {73621A08-B29F-4B69-82FD-30A60F97CF8C}.Release|Win32.Build.0 = Release|Win32 + {73621A08-B29F-4B69-82FD-30A60F97CF8C}.Release|Win32.Deploy.0 = Release|Win32 + {73621A08-B29F-4B69-82FD-30A60F97CF8C}.Release|x64.ActiveCfg = Release|x64 + {73621A08-B29F-4B69-82FD-30A60F97CF8C}.Release|x64.Build.0 = Release|x64 + {73621A08-B29F-4B69-82FD-30A60F97CF8C}.Release|x64.Deploy.0 = Release|x64 + {73621A08-B29F-4B69-82FD-30A60F97CF8C}.Release|ARM64.ActiveCfg = Release|ARM64 + {73621A08-B29F-4B69-82FD-30A60F97CF8C}.Release|ARM64.Build.0 = Release|ARM64 + {73621A08-B29F-4B69-82FD-30A60F97CF8C}.Release|ARM64.Deploy.0 = Release|ARM64 + {8C2A2903-4326-4E80-B511-1F6D130D48A7}.Debug|Win32.ActiveCfg = Debug|Win32 + {8C2A2903-4326-4E80-B511-1F6D130D48A7}.Debug|Win32.Build.0 = Debug|Win32 + {8C2A2903-4326-4E80-B511-1F6D130D48A7}.Debug|Win32.Deploy.0 = Debug|Win32 + {8C2A2903-4326-4E80-B511-1F6D130D48A7}.Debug|x64.ActiveCfg = Debug|x64 + {8C2A2903-4326-4E80-B511-1F6D130D48A7}.Debug|x64.Build.0 = Debug|x64 + {8C2A2903-4326-4E80-B511-1F6D130D48A7}.Debug|x64.Deploy.0 = Debug|x64 + {8C2A2903-4326-4E80-B511-1F6D130D48A7}.Debug|ARM64.ActiveCfg = Debug|ARM64 + {8C2A2903-4326-4E80-B511-1F6D130D48A7}.Debug|ARM64.Build.0 = Debug|ARM64 + {8C2A2903-4326-4E80-B511-1F6D130D48A7}.Debug|ARM64.Deploy.0 = Debug|ARM64 + {8C2A2903-4326-4E80-B511-1F6D130D48A7}.Release|Win32.ActiveCfg = Release|Win32 + {8C2A2903-4326-4E80-B511-1F6D130D48A7}.Release|Win32.Build.0 = Release|Win32 + {8C2A2903-4326-4E80-B511-1F6D130D48A7}.Release|Win32.Deploy.0 = Release|Win32 + {8C2A2903-4326-4E80-B511-1F6D130D48A7}.Release|x64.ActiveCfg = Release|x64 + {8C2A2903-4326-4E80-B511-1F6D130D48A7}.Release|x64.Build.0 = Release|x64 + {8C2A2903-4326-4E80-B511-1F6D130D48A7}.Release|x64.Deploy.0 = Release|x64 + {8C2A2903-4326-4E80-B511-1F6D130D48A7}.Release|ARM64.ActiveCfg = Release|ARM64 + {8C2A2903-4326-4E80-B511-1F6D130D48A7}.Release|ARM64.Build.0 = Release|ARM64 + {8C2A2903-4326-4E80-B511-1F6D130D48A7}.Release|ARM64.Deploy.0 = Release|ARM64 + {BADDC3B7-41EE-489C-A539-63D604B65ABA}.Debug|Win32.ActiveCfg = Debug|Win32 + {BADDC3B7-41EE-489C-A539-63D604B65ABA}.Debug|Win32.Build.0 = Debug|Win32 + {BADDC3B7-41EE-489C-A539-63D604B65ABA}.Debug|Win32.Deploy.0 = Debug|Win32 + {BADDC3B7-41EE-489C-A539-63D604B65ABA}.Debug|x64.ActiveCfg = Debug|x64 + {BADDC3B7-41EE-489C-A539-63D604B65ABA}.Debug|x64.Build.0 = Debug|x64 + {BADDC3B7-41EE-489C-A539-63D604B65ABA}.Debug|x64.Deploy.0 = Debug|x64 + {BADDC3B7-41EE-489C-A539-63D604B65ABA}.Debug|ARM64.ActiveCfg = Debug|ARM64 + {BADDC3B7-41EE-489C-A539-63D604B65ABA}.Debug|ARM64.Build.0 = Debug|ARM64 + {BADDC3B7-41EE-489C-A539-63D604B65ABA}.Debug|ARM64.Deploy.0 = Debug|ARM64 + {BADDC3B7-41EE-489C-A539-63D604B65ABA}.Release|Win32.ActiveCfg = Release|Win32 + {BADDC3B7-41EE-489C-A539-63D604B65ABA}.Release|Win32.Build.0 = Release|Win32 + {BADDC3B7-41EE-489C-A539-63D604B65ABA}.Release|Win32.Deploy.0 = Release|Win32 + {BADDC3B7-41EE-489C-A539-63D604B65ABA}.Release|x64.ActiveCfg = Release|x64 + {BADDC3B7-41EE-489C-A539-63D604B65ABA}.Release|x64.Build.0 = Release|x64 + {BADDC3B7-41EE-489C-A539-63D604B65ABA}.Release|x64.Deploy.0 = Release|x64 + {BADDC3B7-41EE-489C-A539-63D604B65ABA}.Release|ARM64.ActiveCfg = Release|ARM64 + {BADDC3B7-41EE-489C-A539-63D604B65ABA}.Release|ARM64.Build.0 = Release|ARM64 + {BADDC3B7-41EE-489C-A539-63D604B65ABA}.Release|ARM64.Deploy.0 = Release|ARM64 + {7B9811CE-71EA-4D23-A568-DE5CE4CAB874}.Debug|Win32.ActiveCfg = Debug|Win32 + {7B9811CE-71EA-4D23-A568-DE5CE4CAB874}.Debug|Win32.Build.0 = Debug|Win32 + {7B9811CE-71EA-4D23-A568-DE5CE4CAB874}.Debug|Win32.Deploy.0 = Debug|Win32 + {7B9811CE-71EA-4D23-A568-DE5CE4CAB874}.Debug|x64.ActiveCfg = Debug|x64 + {7B9811CE-71EA-4D23-A568-DE5CE4CAB874}.Debug|x64.Build.0 = Debug|x64 + {7B9811CE-71EA-4D23-A568-DE5CE4CAB874}.Debug|x64.Deploy.0 = Debug|x64 + {7B9811CE-71EA-4D23-A568-DE5CE4CAB874}.Debug|ARM64.ActiveCfg = Debug|ARM64 + {7B9811CE-71EA-4D23-A568-DE5CE4CAB874}.Debug|ARM64.Build.0 = Debug|ARM64 + {7B9811CE-71EA-4D23-A568-DE5CE4CAB874}.Debug|ARM64.Deploy.0 = Debug|ARM64 + {7B9811CE-71EA-4D23-A568-DE5CE4CAB874}.Release|Win32.ActiveCfg = Release|Win32 + {7B9811CE-71EA-4D23-A568-DE5CE4CAB874}.Release|Win32.Build.0 = Release|Win32 + {7B9811CE-71EA-4D23-A568-DE5CE4CAB874}.Release|Win32.Deploy.0 = Release|Win32 + {7B9811CE-71EA-4D23-A568-DE5CE4CAB874}.Release|x64.ActiveCfg = Release|x64 + {7B9811CE-71EA-4D23-A568-DE5CE4CAB874}.Release|x64.Build.0 = Release|x64 + {7B9811CE-71EA-4D23-A568-DE5CE4CAB874}.Release|x64.Deploy.0 = Release|x64 + {7B9811CE-71EA-4D23-A568-DE5CE4CAB874}.Release|ARM64.ActiveCfg = Release|ARM64 + {7B9811CE-71EA-4D23-A568-DE5CE4CAB874}.Release|ARM64.Build.0 = Release|ARM64 + {7B9811CE-71EA-4D23-A568-DE5CE4CAB874}.Release|ARM64.Deploy.0 = Release|ARM64 + {2A310F24-BF68-40A0-80DB-151A2C2DD19E}.Debug|Win32.ActiveCfg = Debug|Win32 + {2A310F24-BF68-40A0-80DB-151A2C2DD19E}.Debug|Win32.Build.0 = Debug|Win32 + {2A310F24-BF68-40A0-80DB-151A2C2DD19E}.Debug|Win32.Deploy.0 = Debug|Win32 + {2A310F24-BF68-40A0-80DB-151A2C2DD19E}.Debug|x64.ActiveCfg = Debug|x64 + {2A310F24-BF68-40A0-80DB-151A2C2DD19E}.Debug|x64.Build.0 = Debug|x64 + {2A310F24-BF68-40A0-80DB-151A2C2DD19E}.Debug|x64.Deploy.0 = Debug|x64 + {2A310F24-BF68-40A0-80DB-151A2C2DD19E}.Debug|ARM64.ActiveCfg = Debug|ARM64 + {2A310F24-BF68-40A0-80DB-151A2C2DD19E}.Debug|ARM64.Build.0 = Debug|ARM64 + {2A310F24-BF68-40A0-80DB-151A2C2DD19E}.Debug|ARM64.Deploy.0 = Debug|ARM64 + {2A310F24-BF68-40A0-80DB-151A2C2DD19E}.Release|Win32.ActiveCfg = Release|Win32 + {2A310F24-BF68-40A0-80DB-151A2C2DD19E}.Release|Win32.Build.0 = Release|Win32 + {2A310F24-BF68-40A0-80DB-151A2C2DD19E}.Release|Win32.Deploy.0 = Release|Win32 + {2A310F24-BF68-40A0-80DB-151A2C2DD19E}.Release|x64.ActiveCfg = Release|x64 + {2A310F24-BF68-40A0-80DB-151A2C2DD19E}.Release|x64.Build.0 = Release|x64 + {2A310F24-BF68-40A0-80DB-151A2C2DD19E}.Release|x64.Deploy.0 = Release|x64 + {2A310F24-BF68-40A0-80DB-151A2C2DD19E}.Release|ARM64.ActiveCfg = Release|ARM64 + {2A310F24-BF68-40A0-80DB-151A2C2DD19E}.Release|ARM64.Build.0 = Release|ARM64 + {2A310F24-BF68-40A0-80DB-151A2C2DD19E}.Release|ARM64.Deploy.0 = Release|ARM64 + {2E9195B6-781C-4639-A89E-5518DBFF9B4B}.Debug|Win32.ActiveCfg = Debug|Win32 + {2E9195B6-781C-4639-A89E-5518DBFF9B4B}.Debug|Win32.Build.0 = Debug|Win32 + {2E9195B6-781C-4639-A89E-5518DBFF9B4B}.Debug|Win32.Deploy.0 = Debug|Win32 + {2E9195B6-781C-4639-A89E-5518DBFF9B4B}.Debug|x64.ActiveCfg = Debug|x64 + {2E9195B6-781C-4639-A89E-5518DBFF9B4B}.Debug|x64.Build.0 = Debug|x64 + {2E9195B6-781C-4639-A89E-5518DBFF9B4B}.Debug|x64.Deploy.0 = Debug|x64 + {2E9195B6-781C-4639-A89E-5518DBFF9B4B}.Debug|ARM64.ActiveCfg = Debug|ARM64 + {2E9195B6-781C-4639-A89E-5518DBFF9B4B}.Debug|ARM64.Build.0 = Debug|ARM64 + {2E9195B6-781C-4639-A89E-5518DBFF9B4B}.Debug|ARM64.Deploy.0 = Debug|ARM64 + {2E9195B6-781C-4639-A89E-5518DBFF9B4B}.Release|Win32.ActiveCfg = Release|Win32 + {2E9195B6-781C-4639-A89E-5518DBFF9B4B}.Release|Win32.Build.0 = Release|Win32 + {2E9195B6-781C-4639-A89E-5518DBFF9B4B}.Release|Win32.Deploy.0 = Release|Win32 + {2E9195B6-781C-4639-A89E-5518DBFF9B4B}.Release|x64.ActiveCfg = Release|x64 + {2E9195B6-781C-4639-A89E-5518DBFF9B4B}.Release|x64.Build.0 = Release|x64 + {2E9195B6-781C-4639-A89E-5518DBFF9B4B}.Release|x64.Deploy.0 = Release|x64 + {2E9195B6-781C-4639-A89E-5518DBFF9B4B}.Release|ARM64.ActiveCfg = Release|ARM64 + {2E9195B6-781C-4639-A89E-5518DBFF9B4B}.Release|ARM64.Build.0 = Release|ARM64 + {2E9195B6-781C-4639-A89E-5518DBFF9B4B}.Release|ARM64.Deploy.0 = Release|ARM64 + {CD76FEC4-A143-425F-8C9C-148A4F8A75AB}.Debug|Win32.ActiveCfg = Debug|Win32 + {CD76FEC4-A143-425F-8C9C-148A4F8A75AB}.Debug|Win32.Build.0 = Debug|Win32 + {CD76FEC4-A143-425F-8C9C-148A4F8A75AB}.Debug|Win32.Deploy.0 = Debug|Win32 + {CD76FEC4-A143-425F-8C9C-148A4F8A75AB}.Debug|x64.ActiveCfg = Debug|x64 + {CD76FEC4-A143-425F-8C9C-148A4F8A75AB}.Debug|x64.Build.0 = Debug|x64 + {CD76FEC4-A143-425F-8C9C-148A4F8A75AB}.Debug|x64.Deploy.0 = Debug|x64 + {CD76FEC4-A143-425F-8C9C-148A4F8A75AB}.Debug|ARM64.ActiveCfg = Debug|ARM64 + {CD76FEC4-A143-425F-8C9C-148A4F8A75AB}.Debug|ARM64.Build.0 = Debug|ARM64 + {CD76FEC4-A143-425F-8C9C-148A4F8A75AB}.Debug|ARM64.Deploy.0 = Debug|ARM64 + {CD76FEC4-A143-425F-8C9C-148A4F8A75AB}.Release|Win32.ActiveCfg = Release|Win32 + {CD76FEC4-A143-425F-8C9C-148A4F8A75AB}.Release|Win32.Build.0 = Release|Win32 + {CD76FEC4-A143-425F-8C9C-148A4F8A75AB}.Release|Win32.Deploy.0 = Release|Win32 + {CD76FEC4-A143-425F-8C9C-148A4F8A75AB}.Release|x64.ActiveCfg = Release|x64 + {CD76FEC4-A143-425F-8C9C-148A4F8A75AB}.Release|x64.Build.0 = Release|x64 + {CD76FEC4-A143-425F-8C9C-148A4F8A75AB}.Release|x64.Deploy.0 = Release|x64 + {CD76FEC4-A143-425F-8C9C-148A4F8A75AB}.Release|ARM64.ActiveCfg = Release|ARM64 + {CD76FEC4-A143-425F-8C9C-148A4F8A75AB}.Release|ARM64.Build.0 = Release|ARM64 + {CD76FEC4-A143-425F-8C9C-148A4F8A75AB}.Release|ARM64.Deploy.0 = Release|ARM64 + {A4C690BA-86FE-4786-A373-B3DAADE8863A}.Debug|Win32.ActiveCfg = Debug|Win32 + {A4C690BA-86FE-4786-A373-B3DAADE8863A}.Debug|Win32.Build.0 = Debug|Win32 + {A4C690BA-86FE-4786-A373-B3DAADE8863A}.Debug|Win32.Deploy.0 = Debug|Win32 + {A4C690BA-86FE-4786-A373-B3DAADE8863A}.Debug|x64.ActiveCfg = Debug|x64 + {A4C690BA-86FE-4786-A373-B3DAADE8863A}.Debug|x64.Build.0 = Debug|x64 + {A4C690BA-86FE-4786-A373-B3DAADE8863A}.Debug|x64.Deploy.0 = Debug|x64 + {A4C690BA-86FE-4786-A373-B3DAADE8863A}.Debug|ARM64.ActiveCfg = Debug|ARM64 + {A4C690BA-86FE-4786-A373-B3DAADE8863A}.Debug|ARM64.Build.0 = Debug|ARM64 + {A4C690BA-86FE-4786-A373-B3DAADE8863A}.Debug|ARM64.Deploy.0 = Debug|ARM64 + {A4C690BA-86FE-4786-A373-B3DAADE8863A}.Release|Win32.ActiveCfg = Release|Win32 + {A4C690BA-86FE-4786-A373-B3DAADE8863A}.Release|Win32.Build.0 = Release|Win32 + {A4C690BA-86FE-4786-A373-B3DAADE8863A}.Release|Win32.Deploy.0 = Release|Win32 + {A4C690BA-86FE-4786-A373-B3DAADE8863A}.Release|x64.ActiveCfg = Release|x64 + {A4C690BA-86FE-4786-A373-B3DAADE8863A}.Release|x64.Build.0 = Release|x64 + {A4C690BA-86FE-4786-A373-B3DAADE8863A}.Release|x64.Deploy.0 = Release|x64 + {A4C690BA-86FE-4786-A373-B3DAADE8863A}.Release|ARM64.ActiveCfg = Release|ARM64 + {A4C690BA-86FE-4786-A373-B3DAADE8863A}.Release|ARM64.Build.0 = Release|ARM64 + {A4C690BA-86FE-4786-A373-B3DAADE8863A}.Release|ARM64.Deploy.0 = Release|ARM64 + {F12F3706-097B-48BB-B71C-92D7885543D9}.Debug|Win32.ActiveCfg = Debug|Win32 + {F12F3706-097B-48BB-B71C-92D7885543D9}.Debug|Win32.Build.0 = Debug|Win32 + {F12F3706-097B-48BB-B71C-92D7885543D9}.Debug|Win32.Deploy.0 = Debug|Win32 + {F12F3706-097B-48BB-B71C-92D7885543D9}.Debug|x64.ActiveCfg = Debug|x64 + {F12F3706-097B-48BB-B71C-92D7885543D9}.Debug|x64.Build.0 = Debug|x64 + {F12F3706-097B-48BB-B71C-92D7885543D9}.Debug|x64.Deploy.0 = Debug|x64 + {F12F3706-097B-48BB-B71C-92D7885543D9}.Debug|ARM64.ActiveCfg = Debug|ARM64 + {F12F3706-097B-48BB-B71C-92D7885543D9}.Debug|ARM64.Build.0 = Debug|ARM64 + {F12F3706-097B-48BB-B71C-92D7885543D9}.Debug|ARM64.Deploy.0 = Debug|ARM64 + {F12F3706-097B-48BB-B71C-92D7885543D9}.Release|Win32.ActiveCfg = Release|Win32 + {F12F3706-097B-48BB-B71C-92D7885543D9}.Release|Win32.Build.0 = Release|Win32 + {F12F3706-097B-48BB-B71C-92D7885543D9}.Release|Win32.Deploy.0 = Release|Win32 + {F12F3706-097B-48BB-B71C-92D7885543D9}.Release|x64.ActiveCfg = Release|x64 + {F12F3706-097B-48BB-B71C-92D7885543D9}.Release|x64.Build.0 = Release|x64 + {F12F3706-097B-48BB-B71C-92D7885543D9}.Release|x64.Deploy.0 = Release|x64 + {F12F3706-097B-48BB-B71C-92D7885543D9}.Release|ARM64.ActiveCfg = Release|ARM64 + {F12F3706-097B-48BB-B71C-92D7885543D9}.Release|ARM64.Build.0 = Release|ARM64 + {F12F3706-097B-48BB-B71C-92D7885543D9}.Release|ARM64.Deploy.0 = Release|ARM64 + {F55FABF2-4D21-4F66-A0DF-4A47CA5356FA}.Debug|Win32.ActiveCfg = Debug|Win32 + {F55FABF2-4D21-4F66-A0DF-4A47CA5356FA}.Debug|Win32.Build.0 = Debug|Win32 + {F55FABF2-4D21-4F66-A0DF-4A47CA5356FA}.Debug|Win32.Deploy.0 = Debug|Win32 + {F55FABF2-4D21-4F66-A0DF-4A47CA5356FA}.Debug|x64.ActiveCfg = Debug|x64 + {F55FABF2-4D21-4F66-A0DF-4A47CA5356FA}.Debug|x64.Build.0 = Debug|x64 + {F55FABF2-4D21-4F66-A0DF-4A47CA5356FA}.Debug|x64.Deploy.0 = Debug|x64 + {F55FABF2-4D21-4F66-A0DF-4A47CA5356FA}.Debug|ARM64.ActiveCfg = Debug|ARM64 + {F55FABF2-4D21-4F66-A0DF-4A47CA5356FA}.Debug|ARM64.Build.0 = Debug|ARM64 + {F55FABF2-4D21-4F66-A0DF-4A47CA5356FA}.Debug|ARM64.Deploy.0 = Debug|ARM64 + {F55FABF2-4D21-4F66-A0DF-4A47CA5356FA}.Release|Win32.ActiveCfg = Release|Win32 + {F55FABF2-4D21-4F66-A0DF-4A47CA5356FA}.Release|Win32.Build.0 = Release|Win32 + {F55FABF2-4D21-4F66-A0DF-4A47CA5356FA}.Release|Win32.Deploy.0 = Release|Win32 + {F55FABF2-4D21-4F66-A0DF-4A47CA5356FA}.Release|x64.ActiveCfg = Release|x64 + {F55FABF2-4D21-4F66-A0DF-4A47CA5356FA}.Release|x64.Build.0 = Release|x64 + {F55FABF2-4D21-4F66-A0DF-4A47CA5356FA}.Release|x64.Deploy.0 = Release|x64 + {F55FABF2-4D21-4F66-A0DF-4A47CA5356FA}.Release|ARM64.ActiveCfg = Release|ARM64 + {F55FABF2-4D21-4F66-A0DF-4A47CA5356FA}.Release|ARM64.Build.0 = Release|ARM64 + {F55FABF2-4D21-4F66-A0DF-4A47CA5356FA}.Release|ARM64.Deploy.0 = Release|ARM64 + {B97E6091-EC38-4A34-964A-C903A1C6D254}.Debug|Win32.ActiveCfg = Debug|Win32 + {B97E6091-EC38-4A34-964A-C903A1C6D254}.Debug|Win32.Build.0 = Debug|Win32 + {B97E6091-EC38-4A34-964A-C903A1C6D254}.Debug|Win32.Deploy.0 = Debug|Win32 + {B97E6091-EC38-4A34-964A-C903A1C6D254}.Debug|x64.ActiveCfg = Debug|x64 + {B97E6091-EC38-4A34-964A-C903A1C6D254}.Debug|x64.Build.0 = Debug|x64 + {B97E6091-EC38-4A34-964A-C903A1C6D254}.Debug|x64.Deploy.0 = Debug|x64 + {B97E6091-EC38-4A34-964A-C903A1C6D254}.Debug|ARM64.ActiveCfg = Debug|ARM64 + {B97E6091-EC38-4A34-964A-C903A1C6D254}.Debug|ARM64.Build.0 = Debug|ARM64 + {B97E6091-EC38-4A34-964A-C903A1C6D254}.Debug|ARM64.Deploy.0 = Debug|ARM64 + {B97E6091-EC38-4A34-964A-C903A1C6D254}.Release|Win32.ActiveCfg = Release|Win32 + {B97E6091-EC38-4A34-964A-C903A1C6D254}.Release|Win32.Build.0 = Release|Win32 + {B97E6091-EC38-4A34-964A-C903A1C6D254}.Release|Win32.Deploy.0 = Release|Win32 + {B97E6091-EC38-4A34-964A-C903A1C6D254}.Release|x64.ActiveCfg = Release|x64 + {B97E6091-EC38-4A34-964A-C903A1C6D254}.Release|x64.Build.0 = Release|x64 + {B97E6091-EC38-4A34-964A-C903A1C6D254}.Release|x64.Deploy.0 = Release|x64 + {B97E6091-EC38-4A34-964A-C903A1C6D254}.Release|ARM64.ActiveCfg = Release|ARM64 + {B97E6091-EC38-4A34-964A-C903A1C6D254}.Release|ARM64.Build.0 = Release|ARM64 + {B97E6091-EC38-4A34-964A-C903A1C6D254}.Release|ARM64.Deploy.0 = Release|ARM64 + {1823CB20-54DC-4F68-BDB4-0083B01D6326}.Debug|Win32.ActiveCfg = Debug|Win32 + {1823CB20-54DC-4F68-BDB4-0083B01D6326}.Debug|Win32.Build.0 = Debug|Win32 + {1823CB20-54DC-4F68-BDB4-0083B01D6326}.Debug|Win32.Deploy.0 = Debug|Win32 + {1823CB20-54DC-4F68-BDB4-0083B01D6326}.Debug|x64.ActiveCfg = Debug|x64 + {1823CB20-54DC-4F68-BDB4-0083B01D6326}.Debug|x64.Build.0 = Debug|x64 + {1823CB20-54DC-4F68-BDB4-0083B01D6326}.Debug|x64.Deploy.0 = Debug|x64 + {1823CB20-54DC-4F68-BDB4-0083B01D6326}.Debug|ARM64.ActiveCfg = Debug|ARM64 + {1823CB20-54DC-4F68-BDB4-0083B01D6326}.Debug|ARM64.Build.0 = Debug|ARM64 + {1823CB20-54DC-4F68-BDB4-0083B01D6326}.Debug|ARM64.Deploy.0 = Debug|ARM64 + {1823CB20-54DC-4F68-BDB4-0083B01D6326}.Release|Win32.ActiveCfg = Release|Win32 + {1823CB20-54DC-4F68-BDB4-0083B01D6326}.Release|Win32.Build.0 = Release|Win32 + {1823CB20-54DC-4F68-BDB4-0083B01D6326}.Release|Win32.Deploy.0 = Release|Win32 + {1823CB20-54DC-4F68-BDB4-0083B01D6326}.Release|x64.ActiveCfg = Release|x64 + {1823CB20-54DC-4F68-BDB4-0083B01D6326}.Release|x64.Build.0 = Release|x64 + {1823CB20-54DC-4F68-BDB4-0083B01D6326}.Release|x64.Deploy.0 = Release|x64 + {1823CB20-54DC-4F68-BDB4-0083B01D6326}.Release|ARM64.ActiveCfg = Release|ARM64 + {1823CB20-54DC-4F68-BDB4-0083B01D6326}.Release|ARM64.Build.0 = Release|ARM64 + {1823CB20-54DC-4F68-BDB4-0083B01D6326}.Release|ARM64.Deploy.0 = Release|ARM64 + {6BCA9E05-7327-4421-A5E6-82751ECA6380}.Debug|Win32.ActiveCfg = Debug|Win32 + {6BCA9E05-7327-4421-A5E6-82751ECA6380}.Debug|Win32.Build.0 = Debug|Win32 + {6BCA9E05-7327-4421-A5E6-82751ECA6380}.Debug|Win32.Deploy.0 = Debug|Win32 + {6BCA9E05-7327-4421-A5E6-82751ECA6380}.Debug|x64.ActiveCfg = Debug|x64 + {6BCA9E05-7327-4421-A5E6-82751ECA6380}.Debug|x64.Build.0 = Debug|x64 + {6BCA9E05-7327-4421-A5E6-82751ECA6380}.Debug|x64.Deploy.0 = Debug|x64 + {6BCA9E05-7327-4421-A5E6-82751ECA6380}.Debug|ARM64.ActiveCfg = Debug|ARM64 + {6BCA9E05-7327-4421-A5E6-82751ECA6380}.Debug|ARM64.Build.0 = Debug|ARM64 + {6BCA9E05-7327-4421-A5E6-82751ECA6380}.Debug|ARM64.Deploy.0 = Debug|ARM64 + {6BCA9E05-7327-4421-A5E6-82751ECA6380}.Release|Win32.ActiveCfg = Release|Win32 + {6BCA9E05-7327-4421-A5E6-82751ECA6380}.Release|Win32.Build.0 = Release|Win32 + {6BCA9E05-7327-4421-A5E6-82751ECA6380}.Release|Win32.Deploy.0 = Release|Win32 + {6BCA9E05-7327-4421-A5E6-82751ECA6380}.Release|x64.ActiveCfg = Release|x64 + {6BCA9E05-7327-4421-A5E6-82751ECA6380}.Release|x64.Build.0 = Release|x64 + {6BCA9E05-7327-4421-A5E6-82751ECA6380}.Release|x64.Deploy.0 = Release|x64 + {6BCA9E05-7327-4421-A5E6-82751ECA6380}.Release|ARM64.ActiveCfg = Release|ARM64 + {6BCA9E05-7327-4421-A5E6-82751ECA6380}.Release|ARM64.Build.0 = Release|ARM64 + {6BCA9E05-7327-4421-A5E6-82751ECA6380}.Release|ARM64.Deploy.0 = Release|ARM64 + {18D60FC0-7F72-45E0-9244-4A8F23DB4728}.Debug|Win32.ActiveCfg = Debug|Win32 + {18D60FC0-7F72-45E0-9244-4A8F23DB4728}.Debug|Win32.Build.0 = Debug|Win32 + {18D60FC0-7F72-45E0-9244-4A8F23DB4728}.Debug|Win32.Deploy.0 = Debug|Win32 + {18D60FC0-7F72-45E0-9244-4A8F23DB4728}.Debug|x64.ActiveCfg = Debug|x64 + {18D60FC0-7F72-45E0-9244-4A8F23DB4728}.Debug|x64.Build.0 = Debug|x64 + {18D60FC0-7F72-45E0-9244-4A8F23DB4728}.Debug|x64.Deploy.0 = Debug|x64 + {18D60FC0-7F72-45E0-9244-4A8F23DB4728}.Debug|ARM64.ActiveCfg = Debug|ARM64 + {18D60FC0-7F72-45E0-9244-4A8F23DB4728}.Debug|ARM64.Build.0 = Debug|ARM64 + {18D60FC0-7F72-45E0-9244-4A8F23DB4728}.Debug|ARM64.Deploy.0 = Debug|ARM64 + {18D60FC0-7F72-45E0-9244-4A8F23DB4728}.Release|Win32.ActiveCfg = Release|Win32 + {18D60FC0-7F72-45E0-9244-4A8F23DB4728}.Release|Win32.Build.0 = Release|Win32 + {18D60FC0-7F72-45E0-9244-4A8F23DB4728}.Release|Win32.Deploy.0 = Release|Win32 + {18D60FC0-7F72-45E0-9244-4A8F23DB4728}.Release|x64.ActiveCfg = Release|x64 + {18D60FC0-7F72-45E0-9244-4A8F23DB4728}.Release|x64.Build.0 = Release|x64 + {18D60FC0-7F72-45E0-9244-4A8F23DB4728}.Release|x64.Deploy.0 = Release|x64 + {18D60FC0-7F72-45E0-9244-4A8F23DB4728}.Release|ARM64.ActiveCfg = Release|ARM64 + {18D60FC0-7F72-45E0-9244-4A8F23DB4728}.Release|ARM64.Build.0 = Release|ARM64 + {18D60FC0-7F72-45E0-9244-4A8F23DB4728}.Release|ARM64.Deploy.0 = Release|ARM64 + {37C4A65D-768C-46EF-8BDE-23A5DB762328}.Debug|Win32.ActiveCfg = Debug|Win32 + {37C4A65D-768C-46EF-8BDE-23A5DB762328}.Debug|Win32.Build.0 = Debug|Win32 + {37C4A65D-768C-46EF-8BDE-23A5DB762328}.Debug|Win32.Deploy.0 = Debug|Win32 + {37C4A65D-768C-46EF-8BDE-23A5DB762328}.Debug|x64.ActiveCfg = Debug|x64 + {37C4A65D-768C-46EF-8BDE-23A5DB762328}.Debug|x64.Build.0 = Debug|x64 + {37C4A65D-768C-46EF-8BDE-23A5DB762328}.Debug|x64.Deploy.0 = Debug|x64 + {37C4A65D-768C-46EF-8BDE-23A5DB762328}.Debug|ARM64.ActiveCfg = Debug|ARM64 + {37C4A65D-768C-46EF-8BDE-23A5DB762328}.Debug|ARM64.Build.0 = Debug|ARM64 + {37C4A65D-768C-46EF-8BDE-23A5DB762328}.Debug|ARM64.Deploy.0 = Debug|ARM64 + {37C4A65D-768C-46EF-8BDE-23A5DB762328}.Release|Win32.ActiveCfg = Release|Win32 + {37C4A65D-768C-46EF-8BDE-23A5DB762328}.Release|Win32.Build.0 = Release|Win32 + {37C4A65D-768C-46EF-8BDE-23A5DB762328}.Release|Win32.Deploy.0 = Release|Win32 + {37C4A65D-768C-46EF-8BDE-23A5DB762328}.Release|x64.ActiveCfg = Release|x64 + {37C4A65D-768C-46EF-8BDE-23A5DB762328}.Release|x64.Build.0 = Release|x64 + {37C4A65D-768C-46EF-8BDE-23A5DB762328}.Release|x64.Deploy.0 = Release|x64 + {37C4A65D-768C-46EF-8BDE-23A5DB762328}.Release|ARM64.ActiveCfg = Release|ARM64 + {37C4A65D-768C-46EF-8BDE-23A5DB762328}.Release|ARM64.Build.0 = Release|ARM64 + {37C4A65D-768C-46EF-8BDE-23A5DB762328}.Release|ARM64.Deploy.0 = Release|ARM64 + {85EBD7F6-DF34-4815-83BE-5B0516B7F098}.Debug|Win32.ActiveCfg = Debug|Win32 + {85EBD7F6-DF34-4815-83BE-5B0516B7F098}.Debug|Win32.Build.0 = Debug|Win32 + {85EBD7F6-DF34-4815-83BE-5B0516B7F098}.Debug|Win32.Deploy.0 = Debug|Win32 + {85EBD7F6-DF34-4815-83BE-5B0516B7F098}.Debug|x64.ActiveCfg = Debug|x64 + {85EBD7F6-DF34-4815-83BE-5B0516B7F098}.Debug|x64.Build.0 = Debug|x64 + {85EBD7F6-DF34-4815-83BE-5B0516B7F098}.Debug|x64.Deploy.0 = Debug|x64 + {85EBD7F6-DF34-4815-83BE-5B0516B7F098}.Debug|ARM64.ActiveCfg = Debug|ARM64 + {85EBD7F6-DF34-4815-83BE-5B0516B7F098}.Debug|ARM64.Build.0 = Debug|ARM64 + {85EBD7F6-DF34-4815-83BE-5B0516B7F098}.Debug|ARM64.Deploy.0 = Debug|ARM64 + {85EBD7F6-DF34-4815-83BE-5B0516B7F098}.Release|Win32.ActiveCfg = Release|Win32 + {85EBD7F6-DF34-4815-83BE-5B0516B7F098}.Release|Win32.Build.0 = Release|Win32 + {85EBD7F6-DF34-4815-83BE-5B0516B7F098}.Release|Win32.Deploy.0 = Release|Win32 + {85EBD7F6-DF34-4815-83BE-5B0516B7F098}.Release|x64.ActiveCfg = Release|x64 + {85EBD7F6-DF34-4815-83BE-5B0516B7F098}.Release|x64.Build.0 = Release|x64 + {85EBD7F6-DF34-4815-83BE-5B0516B7F098}.Release|x64.Deploy.0 = Release|x64 + {85EBD7F6-DF34-4815-83BE-5B0516B7F098}.Release|ARM64.ActiveCfg = Release|ARM64 + {85EBD7F6-DF34-4815-83BE-5B0516B7F098}.Release|ARM64.Build.0 = Release|ARM64 + {85EBD7F6-DF34-4815-83BE-5B0516B7F098}.Release|ARM64.Deploy.0 = Release|ARM64 + {EFBD6DB6-3999-49A9-9397-FAD2FD863A87}.Debug|Win32.ActiveCfg = Debug|Win32 + {EFBD6DB6-3999-49A9-9397-FAD2FD863A87}.Debug|Win32.Build.0 = Debug|Win32 + {EFBD6DB6-3999-49A9-9397-FAD2FD863A87}.Debug|Win32.Deploy.0 = Debug|Win32 + {EFBD6DB6-3999-49A9-9397-FAD2FD863A87}.Debug|x64.ActiveCfg = Debug|x64 + {EFBD6DB6-3999-49A9-9397-FAD2FD863A87}.Debug|x64.Build.0 = Debug|x64 + {EFBD6DB6-3999-49A9-9397-FAD2FD863A87}.Debug|x64.Deploy.0 = Debug|x64 + {EFBD6DB6-3999-49A9-9397-FAD2FD863A87}.Debug|ARM64.ActiveCfg = Debug|ARM64 + {EFBD6DB6-3999-49A9-9397-FAD2FD863A87}.Debug|ARM64.Build.0 = Debug|ARM64 + {EFBD6DB6-3999-49A9-9397-FAD2FD863A87}.Debug|ARM64.Deploy.0 = Debug|ARM64 + {EFBD6DB6-3999-49A9-9397-FAD2FD863A87}.Release|Win32.ActiveCfg = Release|Win32 + {EFBD6DB6-3999-49A9-9397-FAD2FD863A87}.Release|Win32.Build.0 = Release|Win32 + {EFBD6DB6-3999-49A9-9397-FAD2FD863A87}.Release|Win32.Deploy.0 = Release|Win32 + {EFBD6DB6-3999-49A9-9397-FAD2FD863A87}.Release|x64.ActiveCfg = Release|x64 + {EFBD6DB6-3999-49A9-9397-FAD2FD863A87}.Release|x64.Build.0 = Release|x64 + {EFBD6DB6-3999-49A9-9397-FAD2FD863A87}.Release|x64.Deploy.0 = Release|x64 + {EFBD6DB6-3999-49A9-9397-FAD2FD863A87}.Release|ARM64.ActiveCfg = Release|ARM64 + {EFBD6DB6-3999-49A9-9397-FAD2FD863A87}.Release|ARM64.Build.0 = Release|ARM64 + {EFBD6DB6-3999-49A9-9397-FAD2FD863A87}.Release|ARM64.Deploy.0 = Release|ARM64 + {89CF5705-9092-4C80-BAAE-D645855D8E3C}.Debug|Win32.ActiveCfg = Debug|Win32 + {89CF5705-9092-4C80-BAAE-D645855D8E3C}.Debug|Win32.Build.0 = Debug|Win32 + {89CF5705-9092-4C80-BAAE-D645855D8E3C}.Debug|Win32.Deploy.0 = Debug|Win32 + {89CF5705-9092-4C80-BAAE-D645855D8E3C}.Debug|x64.ActiveCfg = Debug|x64 + {89CF5705-9092-4C80-BAAE-D645855D8E3C}.Debug|x64.Build.0 = Debug|x64 + {89CF5705-9092-4C80-BAAE-D645855D8E3C}.Debug|x64.Deploy.0 = Debug|x64 + {89CF5705-9092-4C80-BAAE-D645855D8E3C}.Debug|ARM64.ActiveCfg = Debug|ARM64 + {89CF5705-9092-4C80-BAAE-D645855D8E3C}.Debug|ARM64.Build.0 = Debug|ARM64 + {89CF5705-9092-4C80-BAAE-D645855D8E3C}.Debug|ARM64.Deploy.0 = Debug|ARM64 + {89CF5705-9092-4C80-BAAE-D645855D8E3C}.Release|Win32.ActiveCfg = Release|Win32 + {89CF5705-9092-4C80-BAAE-D645855D8E3C}.Release|Win32.Build.0 = Release|Win32 + {89CF5705-9092-4C80-BAAE-D645855D8E3C}.Release|Win32.Deploy.0 = Release|Win32 + {89CF5705-9092-4C80-BAAE-D645855D8E3C}.Release|x64.ActiveCfg = Release|x64 + {89CF5705-9092-4C80-BAAE-D645855D8E3C}.Release|x64.Build.0 = Release|x64 + {89CF5705-9092-4C80-BAAE-D645855D8E3C}.Release|x64.Deploy.0 = Release|x64 + {89CF5705-9092-4C80-BAAE-D645855D8E3C}.Release|ARM64.ActiveCfg = Release|ARM64 + {89CF5705-9092-4C80-BAAE-D645855D8E3C}.Release|ARM64.Build.0 = Release|ARM64 + {89CF5705-9092-4C80-BAAE-D645855D8E3C}.Release|ARM64.Deploy.0 = Release|ARM64 + {DA265C8D-292E-4622-8D66-AD911719607C}.Debug|Win32.ActiveCfg = Debug|Win32 + {DA265C8D-292E-4622-8D66-AD911719607C}.Debug|Win32.Build.0 = Debug|Win32 + {DA265C8D-292E-4622-8D66-AD911719607C}.Debug|Win32.Deploy.0 = Debug|Win32 + {DA265C8D-292E-4622-8D66-AD911719607C}.Debug|x64.ActiveCfg = Debug|x64 + {DA265C8D-292E-4622-8D66-AD911719607C}.Debug|x64.Build.0 = Debug|x64 + {DA265C8D-292E-4622-8D66-AD911719607C}.Debug|x64.Deploy.0 = Debug|x64 + {DA265C8D-292E-4622-8D66-AD911719607C}.Debug|ARM64.ActiveCfg = Debug|ARM64 + {DA265C8D-292E-4622-8D66-AD911719607C}.Debug|ARM64.Build.0 = Debug|ARM64 + {DA265C8D-292E-4622-8D66-AD911719607C}.Debug|ARM64.Deploy.0 = Debug|ARM64 + {DA265C8D-292E-4622-8D66-AD911719607C}.Release|Win32.ActiveCfg = Release|Win32 + {DA265C8D-292E-4622-8D66-AD911719607C}.Release|Win32.Build.0 = Release|Win32 + {DA265C8D-292E-4622-8D66-AD911719607C}.Release|Win32.Deploy.0 = Release|Win32 + {DA265C8D-292E-4622-8D66-AD911719607C}.Release|x64.ActiveCfg = Release|x64 + {DA265C8D-292E-4622-8D66-AD911719607C}.Release|x64.Build.0 = Release|x64 + {DA265C8D-292E-4622-8D66-AD911719607C}.Release|x64.Deploy.0 = Release|x64 + {DA265C8D-292E-4622-8D66-AD911719607C}.Release|ARM64.ActiveCfg = Release|ARM64 + {DA265C8D-292E-4622-8D66-AD911719607C}.Release|ARM64.Build.0 = Release|ARM64 + {DA265C8D-292E-4622-8D66-AD911719607C}.Release|ARM64.Deploy.0 = Release|ARM64 + {E4525091-8E93-4075-9FB6-C2AEAD70AC63}.Debug|Win32.ActiveCfg = Debug|Win32 + {E4525091-8E93-4075-9FB6-C2AEAD70AC63}.Debug|Win32.Build.0 = Debug|Win32 + {E4525091-8E93-4075-9FB6-C2AEAD70AC63}.Debug|Win32.Deploy.0 = Debug|Win32 + {E4525091-8E93-4075-9FB6-C2AEAD70AC63}.Debug|x64.ActiveCfg = Debug|x64 + {E4525091-8E93-4075-9FB6-C2AEAD70AC63}.Debug|x64.Build.0 = Debug|x64 + {E4525091-8E93-4075-9FB6-C2AEAD70AC63}.Debug|x64.Deploy.0 = Debug|x64 + {E4525091-8E93-4075-9FB6-C2AEAD70AC63}.Debug|ARM64.ActiveCfg = Debug|ARM64 + {E4525091-8E93-4075-9FB6-C2AEAD70AC63}.Debug|ARM64.Build.0 = Debug|ARM64 + {E4525091-8E93-4075-9FB6-C2AEAD70AC63}.Debug|ARM64.Deploy.0 = Debug|ARM64 + {E4525091-8E93-4075-9FB6-C2AEAD70AC63}.Release|Win32.ActiveCfg = Release|Win32 + {E4525091-8E93-4075-9FB6-C2AEAD70AC63}.Release|Win32.Build.0 = Release|Win32 + {E4525091-8E93-4075-9FB6-C2AEAD70AC63}.Release|Win32.Deploy.0 = Release|Win32 + {E4525091-8E93-4075-9FB6-C2AEAD70AC63}.Release|x64.ActiveCfg = Release|x64 + {E4525091-8E93-4075-9FB6-C2AEAD70AC63}.Release|x64.Build.0 = Release|x64 + {E4525091-8E93-4075-9FB6-C2AEAD70AC63}.Release|x64.Deploy.0 = Release|x64 + {E4525091-8E93-4075-9FB6-C2AEAD70AC63}.Release|ARM64.ActiveCfg = Release|ARM64 + {E4525091-8E93-4075-9FB6-C2AEAD70AC63}.Release|ARM64.Build.0 = Release|ARM64 + {E4525091-8E93-4075-9FB6-C2AEAD70AC63}.Release|ARM64.Deploy.0 = Release|ARM64 + {45445B97-5844-460E-8C8A-8C8A9BCA01BB}.Debug|Win32.ActiveCfg = Debug|Win32 + {45445B97-5844-460E-8C8A-8C8A9BCA01BB}.Debug|Win32.Build.0 = Debug|Win32 + {45445B97-5844-460E-8C8A-8C8A9BCA01BB}.Debug|Win32.Deploy.0 = Debug|Win32 + {45445B97-5844-460E-8C8A-8C8A9BCA01BB}.Debug|x64.ActiveCfg = Debug|x64 + {45445B97-5844-460E-8C8A-8C8A9BCA01BB}.Debug|x64.Build.0 = Debug|x64 + {45445B97-5844-460E-8C8A-8C8A9BCA01BB}.Debug|x64.Deploy.0 = Debug|x64 + {45445B97-5844-460E-8C8A-8C8A9BCA01BB}.Debug|ARM64.ActiveCfg = Debug|ARM64 + {45445B97-5844-460E-8C8A-8C8A9BCA01BB}.Debug|ARM64.Build.0 = Debug|ARM64 + {45445B97-5844-460E-8C8A-8C8A9BCA01BB}.Debug|ARM64.Deploy.0 = Debug|ARM64 + {45445B97-5844-460E-8C8A-8C8A9BCA01BB}.Release|Win32.ActiveCfg = Release|Win32 + {45445B97-5844-460E-8C8A-8C8A9BCA01BB}.Release|Win32.Build.0 = Release|Win32 + {45445B97-5844-460E-8C8A-8C8A9BCA01BB}.Release|Win32.Deploy.0 = Release|Win32 + {45445B97-5844-460E-8C8A-8C8A9BCA01BB}.Release|x64.ActiveCfg = Release|x64 + {45445B97-5844-460E-8C8A-8C8A9BCA01BB}.Release|x64.Build.0 = Release|x64 + {45445B97-5844-460E-8C8A-8C8A9BCA01BB}.Release|x64.Deploy.0 = Release|x64 + {45445B97-5844-460E-8C8A-8C8A9BCA01BB}.Release|ARM64.ActiveCfg = Release|ARM64 + {45445B97-5844-460E-8C8A-8C8A9BCA01BB}.Release|ARM64.Build.0 = Release|ARM64 + {45445B97-5844-460E-8C8A-8C8A9BCA01BB}.Release|ARM64.Deploy.0 = Release|ARM64 + {546C5980-388B-4A05-ABE8-6DC366DBFA98}.Debug|Win32.ActiveCfg = Debug|Win32 + {546C5980-388B-4A05-ABE8-6DC366DBFA98}.Debug|Win32.Build.0 = Debug|Win32 + {546C5980-388B-4A05-ABE8-6DC366DBFA98}.Debug|Win32.Deploy.0 = Debug|Win32 + {546C5980-388B-4A05-ABE8-6DC366DBFA98}.Debug|x64.ActiveCfg = Debug|x64 + {546C5980-388B-4A05-ABE8-6DC366DBFA98}.Debug|x64.Build.0 = Debug|x64 + {546C5980-388B-4A05-ABE8-6DC366DBFA98}.Debug|x64.Deploy.0 = Debug|x64 + {546C5980-388B-4A05-ABE8-6DC366DBFA98}.Debug|ARM64.ActiveCfg = Debug|ARM64 + {546C5980-388B-4A05-ABE8-6DC366DBFA98}.Debug|ARM64.Build.0 = Debug|ARM64 + {546C5980-388B-4A05-ABE8-6DC366DBFA98}.Debug|ARM64.Deploy.0 = Debug|ARM64 + {546C5980-388B-4A05-ABE8-6DC366DBFA98}.Release|Win32.ActiveCfg = Release|Win32 + {546C5980-388B-4A05-ABE8-6DC366DBFA98}.Release|Win32.Build.0 = Release|Win32 + {546C5980-388B-4A05-ABE8-6DC366DBFA98}.Release|Win32.Deploy.0 = Release|Win32 + {546C5980-388B-4A05-ABE8-6DC366DBFA98}.Release|x64.ActiveCfg = Release|x64 + {546C5980-388B-4A05-ABE8-6DC366DBFA98}.Release|x64.Build.0 = Release|x64 + {546C5980-388B-4A05-ABE8-6DC366DBFA98}.Release|x64.Deploy.0 = Release|x64 + {546C5980-388B-4A05-ABE8-6DC366DBFA98}.Release|ARM64.ActiveCfg = Release|ARM64 + {546C5980-388B-4A05-ABE8-6DC366DBFA98}.Release|ARM64.Build.0 = Release|ARM64 + {546C5980-388B-4A05-ABE8-6DC366DBFA98}.Release|ARM64.Deploy.0 = Release|ARM64 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal diff --git a/FMOD/api/core/examples/vs2017/fmod_codec_raw.vcxproj b/FMOD/api/core/examples/vs2017/fmod_codec_raw.vcxproj new file mode 100644 index 0000000..ca28c04 --- /dev/null +++ b/FMOD/api/core/examples/vs2017/fmod_codec_raw.vcxproj @@ -0,0 +1,69 @@ + + + + + Debug + Win32 + + + Debug + x64 + + + Debug + ARM64 + + + Release + Win32 + + + Release + x64 + + + Release + ARM64 + + + + L + $(Suffix)64 + + + {EFBD6DB6-3999-49A9-9397-FAD2FD863A87} + + + + DynamicLibrary + v141 + false + true + + + + $(SolutionDir)_builds\$(ProjectName)\$(Configuration)\$(Platform)\ + $(SolutionDir)_builds\$(ProjectName)\$(Configuration)\$(Platform)\Intermediate\ + false + $(ProjectName)$(Suffix) + + + + Level3 + ..\..\inc + ProgramDatabase + _WIN32_WINNT=0x601;WINVER=0x601;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) + MultiThreaded + MultiThreadedDebug + + + if not exist ..\bin mkdir ..\bin +copy /Y "$(TargetPath)" ..\bin + + + + + + + + diff --git a/FMOD/api/core/examples/vs2017/fmod_distance_filter.vcxproj b/FMOD/api/core/examples/vs2017/fmod_distance_filter.vcxproj new file mode 100644 index 0000000..be1ac09 --- /dev/null +++ b/FMOD/api/core/examples/vs2017/fmod_distance_filter.vcxproj @@ -0,0 +1,69 @@ + + + + + Debug + Win32 + + + Debug + x64 + + + Debug + ARM64 + + + Release + Win32 + + + Release + x64 + + + Release + ARM64 + + + + L + $(Suffix)64 + + + {89CF5705-9092-4C80-BAAE-D645855D8E3C} + + + + DynamicLibrary + v141 + false + true + + + + $(SolutionDir)_builds\$(ProjectName)\$(Configuration)\$(Platform)\ + $(SolutionDir)_builds\$(ProjectName)\$(Configuration)\$(Platform)\Intermediate\ + false + $(ProjectName)$(Suffix) + + + + Level3 + ..\..\inc + ProgramDatabase + _WIN32_WINNT=0x601;WINVER=0x601;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) + MultiThreaded + MultiThreadedDebug + + + if not exist ..\bin mkdir ..\bin +copy /Y "$(TargetPath)" ..\bin + + + + + + + + diff --git a/FMOD/api/core/examples/vs2017/fmod_gain.vcxproj b/FMOD/api/core/examples/vs2017/fmod_gain.vcxproj new file mode 100644 index 0000000..c762c3a --- /dev/null +++ b/FMOD/api/core/examples/vs2017/fmod_gain.vcxproj @@ -0,0 +1,69 @@ + + + + + Debug + Win32 + + + Debug + x64 + + + Debug + ARM64 + + + Release + Win32 + + + Release + x64 + + + Release + ARM64 + + + + L + $(Suffix)64 + + + {DA265C8D-292E-4622-8D66-AD911719607C} + + + + DynamicLibrary + v141 + false + true + + + + $(SolutionDir)_builds\$(ProjectName)\$(Configuration)\$(Platform)\ + $(SolutionDir)_builds\$(ProjectName)\$(Configuration)\$(Platform)\Intermediate\ + false + $(ProjectName)$(Suffix) + + + + Level3 + ..\..\inc + ProgramDatabase + _WIN32_WINNT=0x601;WINVER=0x601;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) + MultiThreaded + MultiThreadedDebug + + + if not exist ..\bin mkdir ..\bin +copy /Y "$(TargetPath)" ..\bin + + + + + + + + diff --git a/FMOD/api/core/examples/vs2017/fmod_noise.vcxproj b/FMOD/api/core/examples/vs2017/fmod_noise.vcxproj new file mode 100644 index 0000000..43e7ed8 --- /dev/null +++ b/FMOD/api/core/examples/vs2017/fmod_noise.vcxproj @@ -0,0 +1,69 @@ + + + + + Debug + Win32 + + + Debug + x64 + + + Debug + ARM64 + + + Release + Win32 + + + Release + x64 + + + Release + ARM64 + + + + L + $(Suffix)64 + + + {E4525091-8E93-4075-9FB6-C2AEAD70AC63} + + + + DynamicLibrary + v141 + false + true + + + + $(SolutionDir)_builds\$(ProjectName)\$(Configuration)\$(Platform)\ + $(SolutionDir)_builds\$(ProjectName)\$(Configuration)\$(Platform)\Intermediate\ + false + $(ProjectName)$(Suffix) + + + + Level3 + ..\..\inc + ProgramDatabase + _WIN32_WINNT=0x601;WINVER=0x601;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) + MultiThreaded + MultiThreadedDebug + + + if not exist ..\bin mkdir ..\bin +copy /Y "$(TargetPath)" ..\bin + + + + + + + + diff --git a/FMOD/api/core/examples/vs2017/fmod_rnbo.vcxproj b/FMOD/api/core/examples/vs2017/fmod_rnbo.vcxproj new file mode 100644 index 0000000..8b18d18 --- /dev/null +++ b/FMOD/api/core/examples/vs2017/fmod_rnbo.vcxproj @@ -0,0 +1,69 @@ + + + + + Debug + Win32 + + + Debug + x64 + + + Debug + ARM64 + + + Release + Win32 + + + Release + x64 + + + Release + ARM64 + + + + L + $(Suffix)64 + + + {45445B97-5844-460E-8C8A-8C8A9BCA01BB} + + + + DynamicLibrary + v141 + false + true + + + + $(SolutionDir)_builds\$(ProjectName)\$(Configuration)\$(Platform)\ + $(SolutionDir)_builds\$(ProjectName)\$(Configuration)\$(Platform)\Intermediate\ + false + $(ProjectName)$(Suffix) + + + + Level3 + ..\..\inc + ProgramDatabase + _WIN32_WINNT=0x601;WINVER=0x601;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) + MultiThreaded + MultiThreadedDebug + + + if not exist ..\bin mkdir ..\bin +copy /Y "$(TargetPath)" ..\bin + + + + + + + + diff --git a/FMOD/api/core/examples/vs2017/gapless_playback.vcxproj b/FMOD/api/core/examples/vs2017/gapless_playback.vcxproj new file mode 100644 index 0000000..fc633c9 --- /dev/null +++ b/FMOD/api/core/examples/vs2017/gapless_playback.vcxproj @@ -0,0 +1,83 @@ + + + + + Debug + Win32 + + + Debug + x64 + + + Debug + ARM64 + + + Release + Win32 + + + Release + x64 + + + Release + ARM64 + + + + x86 + x64 + ARM64 + L + + + {2A310F24-BF68-40A0-80DB-151A2C2DD19E} + + + + Application + v141 + false + true + + + + $(SolutionDir)_builds\$(ProjectName)\$(Configuration)\$(Platform)\ + $(SolutionDir)_builds\$(ProjectName)\$(Configuration)\$(Platform)\Intermediate\ + false + $(ProjectName)$(Suffix) + + + + Level3 + ..\..\inc + ProgramDatabase + _WIN32_WINNT=0x601;WINVER=0x601;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) + + + Windows + true + ..\..\lib\$(Arch) + fmod$(Suffix)_vc.lib;%(AdditionalDependencies) + + + if not exist ..\bin mkdir ..\bin +copy /Y "$(TargetPath)" ..\bin +copy /Y "..\..\lib\$(Arch)\fmod$(Suffix).dll" ..\bin +copy /Y "..\..\lib\$(Arch)\fmod$(Suffix).dll" "$(OutDir)" + + + + + + + + + + + + + + diff --git a/FMOD/api/core/examples/vs2017/gapless_playback.vcxproj.filters b/FMOD/api/core/examples/vs2017/gapless_playback.vcxproj.filters new file mode 100644 index 0000000..fc0f117 --- /dev/null +++ b/FMOD/api/core/examples/vs2017/gapless_playback.vcxproj.filters @@ -0,0 +1,24 @@ + + + + + common + + + common + + + + + {937abb1b-0123-4875-9828-07ed9f9813e3} + + + + + common + + + common + + + \ No newline at end of file diff --git a/FMOD/api/core/examples/vs2017/generate_tone.vcxproj b/FMOD/api/core/examples/vs2017/generate_tone.vcxproj new file mode 100644 index 0000000..465cc11 --- /dev/null +++ b/FMOD/api/core/examples/vs2017/generate_tone.vcxproj @@ -0,0 +1,83 @@ + + + + + Debug + Win32 + + + Debug + x64 + + + Debug + ARM64 + + + Release + Win32 + + + Release + x64 + + + Release + ARM64 + + + + x86 + x64 + ARM64 + L + + + {2E9195B6-781C-4639-A89E-5518DBFF9B4B} + + + + Application + v141 + false + true + + + + $(SolutionDir)_builds\$(ProjectName)\$(Configuration)\$(Platform)\ + $(SolutionDir)_builds\$(ProjectName)\$(Configuration)\$(Platform)\Intermediate\ + false + $(ProjectName)$(Suffix) + + + + Level3 + ..\..\inc + ProgramDatabase + _WIN32_WINNT=0x601;WINVER=0x601;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) + + + Windows + true + ..\..\lib\$(Arch) + fmod$(Suffix)_vc.lib;%(AdditionalDependencies) + + + if not exist ..\bin mkdir ..\bin +copy /Y "$(TargetPath)" ..\bin +copy /Y "..\..\lib\$(Arch)\fmod$(Suffix).dll" ..\bin +copy /Y "..\..\lib\$(Arch)\fmod$(Suffix).dll" "$(OutDir)" + + + + + + + + + + + + + + diff --git a/FMOD/api/core/examples/vs2017/generate_tone.vcxproj.filters b/FMOD/api/core/examples/vs2017/generate_tone.vcxproj.filters new file mode 100644 index 0000000..fc0f117 --- /dev/null +++ b/FMOD/api/core/examples/vs2017/generate_tone.vcxproj.filters @@ -0,0 +1,24 @@ + + + + + common + + + common + + + + + {937abb1b-0123-4875-9828-07ed9f9813e3} + + + + + common + + + common + + + \ No newline at end of file diff --git a/FMOD/api/core/examples/vs2017/granular_synth.vcxproj b/FMOD/api/core/examples/vs2017/granular_synth.vcxproj new file mode 100644 index 0000000..983c67c --- /dev/null +++ b/FMOD/api/core/examples/vs2017/granular_synth.vcxproj @@ -0,0 +1,83 @@ + + + + + Debug + Win32 + + + Debug + x64 + + + Debug + ARM64 + + + Release + Win32 + + + Release + x64 + + + Release + ARM64 + + + + x86 + x64 + ARM64 + L + + + {CD76FEC4-A143-425F-8C9C-148A4F8A75AB} + + + + Application + v141 + false + true + + + + $(SolutionDir)_builds\$(ProjectName)\$(Configuration)\$(Platform)\ + $(SolutionDir)_builds\$(ProjectName)\$(Configuration)\$(Platform)\Intermediate\ + false + $(ProjectName)$(Suffix) + + + + Level3 + ..\..\inc + ProgramDatabase + _WIN32_WINNT=0x601;WINVER=0x601;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) + + + Windows + true + ..\..\lib\$(Arch) + fmod$(Suffix)_vc.lib;%(AdditionalDependencies) + + + if not exist ..\bin mkdir ..\bin +copy /Y "$(TargetPath)" ..\bin +copy /Y "..\..\lib\$(Arch)\fmod$(Suffix).dll" ..\bin +copy /Y "..\..\lib\$(Arch)\fmod$(Suffix).dll" "$(OutDir)" + + + + + + + + + + + + + + diff --git a/FMOD/api/core/examples/vs2017/granular_synth.vcxproj.filters b/FMOD/api/core/examples/vs2017/granular_synth.vcxproj.filters new file mode 100644 index 0000000..fc0f117 --- /dev/null +++ b/FMOD/api/core/examples/vs2017/granular_synth.vcxproj.filters @@ -0,0 +1,24 @@ + + + + + common + + + common + + + + + {937abb1b-0123-4875-9828-07ed9f9813e3} + + + + + common + + + common + + + \ No newline at end of file diff --git a/FMOD/api/core/examples/vs2017/load_from_memory.vcxproj b/FMOD/api/core/examples/vs2017/load_from_memory.vcxproj new file mode 100644 index 0000000..c081509 --- /dev/null +++ b/FMOD/api/core/examples/vs2017/load_from_memory.vcxproj @@ -0,0 +1,83 @@ + + + + + Debug + Win32 + + + Debug + x64 + + + Debug + ARM64 + + + Release + Win32 + + + Release + x64 + + + Release + ARM64 + + + + x86 + x64 + ARM64 + L + + + {A4C690BA-86FE-4786-A373-B3DAADE8863A} + + + + Application + v141 + false + true + + + + $(SolutionDir)_builds\$(ProjectName)\$(Configuration)\$(Platform)\ + $(SolutionDir)_builds\$(ProjectName)\$(Configuration)\$(Platform)\Intermediate\ + false + $(ProjectName)$(Suffix) + + + + Level3 + ..\..\inc + ProgramDatabase + _WIN32_WINNT=0x601;WINVER=0x601;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) + + + Windows + true + ..\..\lib\$(Arch) + fmod$(Suffix)_vc.lib;%(AdditionalDependencies) + + + if not exist ..\bin mkdir ..\bin +copy /Y "$(TargetPath)" ..\bin +copy /Y "..\..\lib\$(Arch)\fmod$(Suffix).dll" ..\bin +copy /Y "..\..\lib\$(Arch)\fmod$(Suffix).dll" "$(OutDir)" + + + + + + + + + + + + + + diff --git a/FMOD/api/core/examples/vs2017/load_from_memory.vcxproj.filters b/FMOD/api/core/examples/vs2017/load_from_memory.vcxproj.filters new file mode 100644 index 0000000..fc0f117 --- /dev/null +++ b/FMOD/api/core/examples/vs2017/load_from_memory.vcxproj.filters @@ -0,0 +1,24 @@ + + + + + common + + + common + + + + + {937abb1b-0123-4875-9828-07ed9f9813e3} + + + + + common + + + common + + + \ No newline at end of file diff --git a/FMOD/api/core/examples/vs2017/multiple_speaker.vcxproj b/FMOD/api/core/examples/vs2017/multiple_speaker.vcxproj new file mode 100644 index 0000000..d0c84ac --- /dev/null +++ b/FMOD/api/core/examples/vs2017/multiple_speaker.vcxproj @@ -0,0 +1,83 @@ + + + + + Debug + Win32 + + + Debug + x64 + + + Debug + ARM64 + + + Release + Win32 + + + Release + x64 + + + Release + ARM64 + + + + x86 + x64 + ARM64 + L + + + {F12F3706-097B-48BB-B71C-92D7885543D9} + + + + Application + v141 + false + true + + + + $(SolutionDir)_builds\$(ProjectName)\$(Configuration)\$(Platform)\ + $(SolutionDir)_builds\$(ProjectName)\$(Configuration)\$(Platform)\Intermediate\ + false + $(ProjectName)$(Suffix) + + + + Level3 + ..\..\inc + ProgramDatabase + _WIN32_WINNT=0x601;WINVER=0x601;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) + + + Windows + true + ..\..\lib\$(Arch) + fmod$(Suffix)_vc.lib;%(AdditionalDependencies) + + + if not exist ..\bin mkdir ..\bin +copy /Y "$(TargetPath)" ..\bin +copy /Y "..\..\lib\$(Arch)\fmod$(Suffix).dll" ..\bin +copy /Y "..\..\lib\$(Arch)\fmod$(Suffix).dll" "$(OutDir)" + + + + + + + + + + + + + + diff --git a/FMOD/api/core/examples/vs2017/multiple_speaker.vcxproj.filters b/FMOD/api/core/examples/vs2017/multiple_speaker.vcxproj.filters new file mode 100644 index 0000000..fc0f117 --- /dev/null +++ b/FMOD/api/core/examples/vs2017/multiple_speaker.vcxproj.filters @@ -0,0 +1,24 @@ + + + + + common + + + common + + + + + {937abb1b-0123-4875-9828-07ed9f9813e3} + + + + + common + + + common + + + \ No newline at end of file diff --git a/FMOD/api/core/examples/vs2017/multiple_system.vcxproj b/FMOD/api/core/examples/vs2017/multiple_system.vcxproj new file mode 100644 index 0000000..c619fac --- /dev/null +++ b/FMOD/api/core/examples/vs2017/multiple_system.vcxproj @@ -0,0 +1,83 @@ + + + + + Debug + Win32 + + + Debug + x64 + + + Debug + ARM64 + + + Release + Win32 + + + Release + x64 + + + Release + ARM64 + + + + x86 + x64 + ARM64 + L + + + {F55FABF2-4D21-4F66-A0DF-4A47CA5356FA} + + + + Application + v141 + false + true + + + + $(SolutionDir)_builds\$(ProjectName)\$(Configuration)\$(Platform)\ + $(SolutionDir)_builds\$(ProjectName)\$(Configuration)\$(Platform)\Intermediate\ + false + $(ProjectName)$(Suffix) + + + + Level3 + ..\..\inc + ProgramDatabase + _WIN32_WINNT=0x601;WINVER=0x601;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) + + + Windows + true + ..\..\lib\$(Arch) + fmod$(Suffix)_vc.lib;%(AdditionalDependencies) + + + if not exist ..\bin mkdir ..\bin +copy /Y "$(TargetPath)" ..\bin +copy /Y "..\..\lib\$(Arch)\fmod$(Suffix).dll" ..\bin +copy /Y "..\..\lib\$(Arch)\fmod$(Suffix).dll" "$(OutDir)" + + + + + + + + + + + + + + diff --git a/FMOD/api/core/examples/vs2017/multiple_system.vcxproj.filters b/FMOD/api/core/examples/vs2017/multiple_system.vcxproj.filters new file mode 100644 index 0000000..fc0f117 --- /dev/null +++ b/FMOD/api/core/examples/vs2017/multiple_system.vcxproj.filters @@ -0,0 +1,24 @@ + + + + + common + + + common + + + + + {937abb1b-0123-4875-9828-07ed9f9813e3} + + + + + common + + + common + + + \ No newline at end of file diff --git a/FMOD/api/core/examples/vs2017/net_stream.vcxproj b/FMOD/api/core/examples/vs2017/net_stream.vcxproj new file mode 100644 index 0000000..42da378 --- /dev/null +++ b/FMOD/api/core/examples/vs2017/net_stream.vcxproj @@ -0,0 +1,83 @@ + + + + + Debug + Win32 + + + Debug + x64 + + + Debug + ARM64 + + + Release + Win32 + + + Release + x64 + + + Release + ARM64 + + + + x86 + x64 + ARM64 + L + + + {B97E6091-EC38-4A34-964A-C903A1C6D254} + + + + Application + v141 + false + true + + + + $(SolutionDir)_builds\$(ProjectName)\$(Configuration)\$(Platform)\ + $(SolutionDir)_builds\$(ProjectName)\$(Configuration)\$(Platform)\Intermediate\ + false + $(ProjectName)$(Suffix) + + + + Level3 + ..\..\inc + ProgramDatabase + _WIN32_WINNT=0x601;WINVER=0x601;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) + + + Windows + true + ..\..\lib\$(Arch) + fmod$(Suffix)_vc.lib;%(AdditionalDependencies) + + + if not exist ..\bin mkdir ..\bin +copy /Y "$(TargetPath)" ..\bin +copy /Y "..\..\lib\$(Arch)\fmod$(Suffix).dll" ..\bin +copy /Y "..\..\lib\$(Arch)\fmod$(Suffix).dll" "$(OutDir)" + + + + + + + + + + + + + + diff --git a/FMOD/api/core/examples/vs2017/net_stream.vcxproj.filters b/FMOD/api/core/examples/vs2017/net_stream.vcxproj.filters new file mode 100644 index 0000000..fc0f117 --- /dev/null +++ b/FMOD/api/core/examples/vs2017/net_stream.vcxproj.filters @@ -0,0 +1,24 @@ + + + + + common + + + common + + + + + {937abb1b-0123-4875-9828-07ed9f9813e3} + + + + + common + + + common + + + \ No newline at end of file diff --git a/FMOD/api/core/examples/vs2017/output_mp3.vcxproj b/FMOD/api/core/examples/vs2017/output_mp3.vcxproj new file mode 100644 index 0000000..9d7d475 --- /dev/null +++ b/FMOD/api/core/examples/vs2017/output_mp3.vcxproj @@ -0,0 +1,69 @@ + + + + + Debug + Win32 + + + Debug + x64 + + + Debug + ARM64 + + + Release + Win32 + + + Release + x64 + + + Release + ARM64 + + + + L + $(Suffix)64 + + + {546C5980-388B-4A05-ABE8-6DC366DBFA98} + + + + DynamicLibrary + v141 + false + true + + + + $(SolutionDir)_builds\$(ProjectName)\$(Configuration)\$(Platform)\ + $(SolutionDir)_builds\$(ProjectName)\$(Configuration)\$(Platform)\Intermediate\ + false + $(ProjectName)$(Suffix) + + + + Level3 + ..\..\inc + ProgramDatabase + _WIN32_WINNT=0x601;WINVER=0x601;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) + MultiThreaded + MultiThreadedDebug + + + if not exist ..\bin mkdir ..\bin +copy /Y "$(TargetPath)" ..\bin + + + + + + + + diff --git a/FMOD/api/core/examples/vs2017/play_sound.vcxproj b/FMOD/api/core/examples/vs2017/play_sound.vcxproj new file mode 100644 index 0000000..b95402e --- /dev/null +++ b/FMOD/api/core/examples/vs2017/play_sound.vcxproj @@ -0,0 +1,83 @@ + + + + + Debug + Win32 + + + Debug + x64 + + + Debug + ARM64 + + + Release + Win32 + + + Release + x64 + + + Release + ARM64 + + + + x86 + x64 + ARM64 + L + + + {1823CB20-54DC-4F68-BDB4-0083B01D6326} + + + + Application + v141 + false + true + + + + $(SolutionDir)_builds\$(ProjectName)\$(Configuration)\$(Platform)\ + $(SolutionDir)_builds\$(ProjectName)\$(Configuration)\$(Platform)\Intermediate\ + false + $(ProjectName)$(Suffix) + + + + Level3 + ..\..\inc + ProgramDatabase + _WIN32_WINNT=0x601;WINVER=0x601;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) + + + Windows + true + ..\..\lib\$(Arch) + fmod$(Suffix)_vc.lib;%(AdditionalDependencies) + + + if not exist ..\bin mkdir ..\bin +copy /Y "$(TargetPath)" ..\bin +copy /Y "..\..\lib\$(Arch)\fmod$(Suffix).dll" ..\bin +copy /Y "..\..\lib\$(Arch)\fmod$(Suffix).dll" "$(OutDir)" + + + + + + + + + + + + + + diff --git a/FMOD/api/core/examples/vs2017/play_sound.vcxproj.filters b/FMOD/api/core/examples/vs2017/play_sound.vcxproj.filters new file mode 100644 index 0000000..fc0f117 --- /dev/null +++ b/FMOD/api/core/examples/vs2017/play_sound.vcxproj.filters @@ -0,0 +1,24 @@ + + + + + common + + + common + + + + + {937abb1b-0123-4875-9828-07ed9f9813e3} + + + + + common + + + common + + + \ No newline at end of file diff --git a/FMOD/api/core/examples/vs2017/play_stream.vcxproj b/FMOD/api/core/examples/vs2017/play_stream.vcxproj new file mode 100644 index 0000000..9aca802 --- /dev/null +++ b/FMOD/api/core/examples/vs2017/play_stream.vcxproj @@ -0,0 +1,83 @@ + + + + + Debug + Win32 + + + Debug + x64 + + + Debug + ARM64 + + + Release + Win32 + + + Release + x64 + + + Release + ARM64 + + + + x86 + x64 + ARM64 + L + + + {6BCA9E05-7327-4421-A5E6-82751ECA6380} + + + + Application + v141 + false + true + + + + $(SolutionDir)_builds\$(ProjectName)\$(Configuration)\$(Platform)\ + $(SolutionDir)_builds\$(ProjectName)\$(Configuration)\$(Platform)\Intermediate\ + false + $(ProjectName)$(Suffix) + + + + Level3 + ..\..\inc + ProgramDatabase + _WIN32_WINNT=0x601;WINVER=0x601;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) + + + Windows + true + ..\..\lib\$(Arch) + fmod$(Suffix)_vc.lib;%(AdditionalDependencies) + + + if not exist ..\bin mkdir ..\bin +copy /Y "$(TargetPath)" ..\bin +copy /Y "..\..\lib\$(Arch)\fmod$(Suffix).dll" ..\bin +copy /Y "..\..\lib\$(Arch)\fmod$(Suffix).dll" "$(OutDir)" + + + + + + + + + + + + + + diff --git a/FMOD/api/core/examples/vs2017/play_stream.vcxproj.filters b/FMOD/api/core/examples/vs2017/play_stream.vcxproj.filters new file mode 100644 index 0000000..fc0f117 --- /dev/null +++ b/FMOD/api/core/examples/vs2017/play_stream.vcxproj.filters @@ -0,0 +1,24 @@ + + + + + common + + + common + + + + + {937abb1b-0123-4875-9828-07ed9f9813e3} + + + + + common + + + common + + + \ No newline at end of file diff --git a/FMOD/api/core/examples/vs2017/record.vcxproj b/FMOD/api/core/examples/vs2017/record.vcxproj new file mode 100644 index 0000000..190b11f --- /dev/null +++ b/FMOD/api/core/examples/vs2017/record.vcxproj @@ -0,0 +1,83 @@ + + + + + Debug + Win32 + + + Debug + x64 + + + Debug + ARM64 + + + Release + Win32 + + + Release + x64 + + + Release + ARM64 + + + + x86 + x64 + ARM64 + L + + + {18D60FC0-7F72-45E0-9244-4A8F23DB4728} + + + + Application + v141 + false + true + + + + $(SolutionDir)_builds\$(ProjectName)\$(Configuration)\$(Platform)\ + $(SolutionDir)_builds\$(ProjectName)\$(Configuration)\$(Platform)\Intermediate\ + false + $(ProjectName)$(Suffix) + + + + Level3 + ..\..\inc + ProgramDatabase + _WIN32_WINNT=0x601;WINVER=0x601;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) + + + Windows + true + ..\..\lib\$(Arch) + fmod$(Suffix)_vc.lib;%(AdditionalDependencies) + + + if not exist ..\bin mkdir ..\bin +copy /Y "$(TargetPath)" ..\bin +copy /Y "..\..\lib\$(Arch)\fmod$(Suffix).dll" ..\bin +copy /Y "..\..\lib\$(Arch)\fmod$(Suffix).dll" "$(OutDir)" + + + + + + + + + + + + + + diff --git a/FMOD/api/core/examples/vs2017/record.vcxproj.filters b/FMOD/api/core/examples/vs2017/record.vcxproj.filters new file mode 100644 index 0000000..fc0f117 --- /dev/null +++ b/FMOD/api/core/examples/vs2017/record.vcxproj.filters @@ -0,0 +1,24 @@ + + + + + common + + + common + + + + + {937abb1b-0123-4875-9828-07ed9f9813e3} + + + + + common + + + common + + + \ No newline at end of file diff --git a/FMOD/api/core/examples/vs2017/record_enumeration.vcxproj b/FMOD/api/core/examples/vs2017/record_enumeration.vcxproj new file mode 100644 index 0000000..95b27a2 --- /dev/null +++ b/FMOD/api/core/examples/vs2017/record_enumeration.vcxproj @@ -0,0 +1,83 @@ + + + + + Debug + Win32 + + + Debug + x64 + + + Debug + ARM64 + + + Release + Win32 + + + Release + x64 + + + Release + ARM64 + + + + x86 + x64 + ARM64 + L + + + {37C4A65D-768C-46EF-8BDE-23A5DB762328} + + + + Application + v141 + false + true + + + + $(SolutionDir)_builds\$(ProjectName)\$(Configuration)\$(Platform)\ + $(SolutionDir)_builds\$(ProjectName)\$(Configuration)\$(Platform)\Intermediate\ + false + $(ProjectName)$(Suffix) + + + + Level3 + ..\..\inc + ProgramDatabase + _WIN32_WINNT=0x601;WINVER=0x601;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) + + + Windows + true + ..\..\lib\$(Arch) + fmod$(Suffix)_vc.lib;%(AdditionalDependencies) + + + if not exist ..\bin mkdir ..\bin +copy /Y "$(TargetPath)" ..\bin +copy /Y "..\..\lib\$(Arch)\fmod$(Suffix).dll" ..\bin +copy /Y "..\..\lib\$(Arch)\fmod$(Suffix).dll" "$(OutDir)" + + + + + + + + + + + + + + diff --git a/FMOD/api/core/examples/vs2017/record_enumeration.vcxproj.filters b/FMOD/api/core/examples/vs2017/record_enumeration.vcxproj.filters new file mode 100644 index 0000000..fc0f117 --- /dev/null +++ b/FMOD/api/core/examples/vs2017/record_enumeration.vcxproj.filters @@ -0,0 +1,24 @@ + + + + + common + + + common + + + + + {937abb1b-0123-4875-9828-07ed9f9813e3} + + + + + common + + + common + + + \ No newline at end of file diff --git a/FMOD/api/core/examples/vs2017/user_created_sound.vcxproj b/FMOD/api/core/examples/vs2017/user_created_sound.vcxproj new file mode 100644 index 0000000..cb06443 --- /dev/null +++ b/FMOD/api/core/examples/vs2017/user_created_sound.vcxproj @@ -0,0 +1,83 @@ + + + + + Debug + Win32 + + + Debug + x64 + + + Debug + ARM64 + + + Release + Win32 + + + Release + x64 + + + Release + ARM64 + + + + x86 + x64 + ARM64 + L + + + {85EBD7F6-DF34-4815-83BE-5B0516B7F098} + + + + Application + v141 + false + true + + + + $(SolutionDir)_builds\$(ProjectName)\$(Configuration)\$(Platform)\ + $(SolutionDir)_builds\$(ProjectName)\$(Configuration)\$(Platform)\Intermediate\ + false + $(ProjectName)$(Suffix) + + + + Level3 + ..\..\inc + ProgramDatabase + _WIN32_WINNT=0x601;WINVER=0x601;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) + + + Windows + true + ..\..\lib\$(Arch) + fmod$(Suffix)_vc.lib;%(AdditionalDependencies) + + + if not exist ..\bin mkdir ..\bin +copy /Y "$(TargetPath)" ..\bin +copy /Y "..\..\lib\$(Arch)\fmod$(Suffix).dll" ..\bin +copy /Y "..\..\lib\$(Arch)\fmod$(Suffix).dll" "$(OutDir)" + + + + + + + + + + + + + + diff --git a/FMOD/api/core/examples/vs2017/user_created_sound.vcxproj.filters b/FMOD/api/core/examples/vs2017/user_created_sound.vcxproj.filters new file mode 100644 index 0000000..fc0f117 --- /dev/null +++ b/FMOD/api/core/examples/vs2017/user_created_sound.vcxproj.filters @@ -0,0 +1,24 @@ + + + + + common + + + common + + + + + {937abb1b-0123-4875-9828-07ed9f9813e3} + + + + + common + + + common + + + \ No newline at end of file diff --git a/FMOD/api/core/examples/vs2019/3d.vcxproj b/FMOD/api/core/examples/vs2019/3d.vcxproj new file mode 100644 index 0000000..4bf8d0a --- /dev/null +++ b/FMOD/api/core/examples/vs2019/3d.vcxproj @@ -0,0 +1,83 @@ + + + + + Debug + Win32 + + + Debug + x64 + + + Debug + ARM64 + + + Release + Win32 + + + Release + x64 + + + Release + ARM64 + + + + x86 + x64 + ARM64 + L + + + {ADD17242-D100-4B96-87C0-1B4F9E488CAA} + + + + Application + v142 + false + true + + + + $(SolutionDir)_builds\$(ProjectName)\$(Configuration)\$(Platform)\ + $(SolutionDir)_builds\$(ProjectName)\$(Configuration)\$(Platform)\Intermediate\ + false + $(ProjectName)$(Suffix) + + + + Level3 + ..\..\inc + ProgramDatabase + _WIN32_WINNT=0x601;WINVER=0x601;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) + + + Windows + true + ..\..\lib\$(Arch) + fmod$(Suffix)_vc.lib;%(AdditionalDependencies) + + + if not exist ..\bin mkdir ..\bin +copy /Y "$(TargetPath)" ..\bin +copy /Y "..\..\lib\$(Arch)\fmod$(Suffix).dll" ..\bin +copy /Y "..\..\lib\$(Arch)\fmod$(Suffix).dll" "$(OutDir)" + + + + + + + + + + + + + + diff --git a/FMOD/api/core/examples/vs2019/3d.vcxproj.filters b/FMOD/api/core/examples/vs2019/3d.vcxproj.filters new file mode 100644 index 0000000..fc0f117 --- /dev/null +++ b/FMOD/api/core/examples/vs2019/3d.vcxproj.filters @@ -0,0 +1,24 @@ + + + + + common + + + common + + + + + {937abb1b-0123-4875-9828-07ed9f9813e3} + + + + + common + + + common + + + \ No newline at end of file diff --git a/FMOD/api/core/examples/vs2019/asyncio.vcxproj b/FMOD/api/core/examples/vs2019/asyncio.vcxproj new file mode 100644 index 0000000..9401d22 --- /dev/null +++ b/FMOD/api/core/examples/vs2019/asyncio.vcxproj @@ -0,0 +1,83 @@ + + + + + Debug + Win32 + + + Debug + x64 + + + Debug + ARM64 + + + Release + Win32 + + + Release + x64 + + + Release + ARM64 + + + + x86 + x64 + ARM64 + L + + + {F110A4C9-EFE5-472B-9BA0-D7272C187C0E} + + + + Application + v142 + false + true + + + + $(SolutionDir)_builds\$(ProjectName)\$(Configuration)\$(Platform)\ + $(SolutionDir)_builds\$(ProjectName)\$(Configuration)\$(Platform)\Intermediate\ + false + $(ProjectName)$(Suffix) + + + + Level3 + ..\..\inc + ProgramDatabase + _WIN32_WINNT=0x601;WINVER=0x601;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) + + + Windows + true + ..\..\lib\$(Arch) + fmod$(Suffix)_vc.lib;%(AdditionalDependencies) + + + if not exist ..\bin mkdir ..\bin +copy /Y "$(TargetPath)" ..\bin +copy /Y "..\..\lib\$(Arch)\fmod$(Suffix).dll" ..\bin +copy /Y "..\..\lib\$(Arch)\fmod$(Suffix).dll" "$(OutDir)" + + + + + + + + + + + + + + diff --git a/FMOD/api/core/examples/vs2019/asyncio.vcxproj.filters b/FMOD/api/core/examples/vs2019/asyncio.vcxproj.filters new file mode 100644 index 0000000..fc0f117 --- /dev/null +++ b/FMOD/api/core/examples/vs2019/asyncio.vcxproj.filters @@ -0,0 +1,24 @@ + + + + + common + + + common + + + + + {937abb1b-0123-4875-9828-07ed9f9813e3} + + + + + common + + + common + + + \ No newline at end of file diff --git a/FMOD/api/core/examples/vs2019/channel_groups.vcxproj b/FMOD/api/core/examples/vs2019/channel_groups.vcxproj new file mode 100644 index 0000000..6c2c498 --- /dev/null +++ b/FMOD/api/core/examples/vs2019/channel_groups.vcxproj @@ -0,0 +1,83 @@ + + + + + Debug + Win32 + + + Debug + x64 + + + Debug + ARM64 + + + Release + Win32 + + + Release + x64 + + + Release + ARM64 + + + + x86 + x64 + ARM64 + L + + + {A7E69F23-1773-4D7A-9C16-A329639E66EA} + + + + Application + v142 + false + true + + + + $(SolutionDir)_builds\$(ProjectName)\$(Configuration)\$(Platform)\ + $(SolutionDir)_builds\$(ProjectName)\$(Configuration)\$(Platform)\Intermediate\ + false + $(ProjectName)$(Suffix) + + + + Level3 + ..\..\inc + ProgramDatabase + _WIN32_WINNT=0x601;WINVER=0x601;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) + + + Windows + true + ..\..\lib\$(Arch) + fmod$(Suffix)_vc.lib;%(AdditionalDependencies) + + + if not exist ..\bin mkdir ..\bin +copy /Y "$(TargetPath)" ..\bin +copy /Y "..\..\lib\$(Arch)\fmod$(Suffix).dll" ..\bin +copy /Y "..\..\lib\$(Arch)\fmod$(Suffix).dll" "$(OutDir)" + + + + + + + + + + + + + + diff --git a/FMOD/api/core/examples/vs2019/channel_groups.vcxproj.filters b/FMOD/api/core/examples/vs2019/channel_groups.vcxproj.filters new file mode 100644 index 0000000..fc0f117 --- /dev/null +++ b/FMOD/api/core/examples/vs2019/channel_groups.vcxproj.filters @@ -0,0 +1,24 @@ + + + + + common + + + common + + + + + {937abb1b-0123-4875-9828-07ed9f9813e3} + + + + + common + + + common + + + \ No newline at end of file diff --git a/FMOD/api/core/examples/vs2019/convolution_reverb.vcxproj b/FMOD/api/core/examples/vs2019/convolution_reverb.vcxproj new file mode 100644 index 0000000..8659cb9 --- /dev/null +++ b/FMOD/api/core/examples/vs2019/convolution_reverb.vcxproj @@ -0,0 +1,83 @@ + + + + + Debug + Win32 + + + Debug + x64 + + + Debug + ARM64 + + + Release + Win32 + + + Release + x64 + + + Release + ARM64 + + + + x86 + x64 + ARM64 + L + + + {87AD5FA6-C607-4DF0-8BA2-769BEB4BDBC0} + + + + Application + v142 + false + true + + + + $(SolutionDir)_builds\$(ProjectName)\$(Configuration)\$(Platform)\ + $(SolutionDir)_builds\$(ProjectName)\$(Configuration)\$(Platform)\Intermediate\ + false + $(ProjectName)$(Suffix) + + + + Level3 + ..\..\inc + ProgramDatabase + _WIN32_WINNT=0x601;WINVER=0x601;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) + + + Windows + true + ..\..\lib\$(Arch) + fmod$(Suffix)_vc.lib;%(AdditionalDependencies) + + + if not exist ..\bin mkdir ..\bin +copy /Y "$(TargetPath)" ..\bin +copy /Y "..\..\lib\$(Arch)\fmod$(Suffix).dll" ..\bin +copy /Y "..\..\lib\$(Arch)\fmod$(Suffix).dll" "$(OutDir)" + + + + + + + + + + + + + + diff --git a/FMOD/api/core/examples/vs2019/convolution_reverb.vcxproj.filters b/FMOD/api/core/examples/vs2019/convolution_reverb.vcxproj.filters new file mode 100644 index 0000000..fc0f117 --- /dev/null +++ b/FMOD/api/core/examples/vs2019/convolution_reverb.vcxproj.filters @@ -0,0 +1,24 @@ + + + + + common + + + common + + + + + {937abb1b-0123-4875-9828-07ed9f9813e3} + + + + + common + + + common + + + \ No newline at end of file diff --git a/FMOD/api/core/examples/vs2019/dsp_custom.vcxproj b/FMOD/api/core/examples/vs2019/dsp_custom.vcxproj new file mode 100644 index 0000000..042978d --- /dev/null +++ b/FMOD/api/core/examples/vs2019/dsp_custom.vcxproj @@ -0,0 +1,83 @@ + + + + + Debug + Win32 + + + Debug + x64 + + + Debug + ARM64 + + + Release + Win32 + + + Release + x64 + + + Release + ARM64 + + + + x86 + x64 + ARM64 + L + + + {08FFE91A-CC62-4357-856A-0379FA9CE526} + + + + Application + v142 + false + true + + + + $(SolutionDir)_builds\$(ProjectName)\$(Configuration)\$(Platform)\ + $(SolutionDir)_builds\$(ProjectName)\$(Configuration)\$(Platform)\Intermediate\ + false + $(ProjectName)$(Suffix) + + + + Level3 + ..\..\inc + ProgramDatabase + _WIN32_WINNT=0x601;WINVER=0x601;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) + + + Windows + true + ..\..\lib\$(Arch) + fmod$(Suffix)_vc.lib;%(AdditionalDependencies) + + + if not exist ..\bin mkdir ..\bin +copy /Y "$(TargetPath)" ..\bin +copy /Y "..\..\lib\$(Arch)\fmod$(Suffix).dll" ..\bin +copy /Y "..\..\lib\$(Arch)\fmod$(Suffix).dll" "$(OutDir)" + + + + + + + + + + + + + + diff --git a/FMOD/api/core/examples/vs2019/dsp_custom.vcxproj.filters b/FMOD/api/core/examples/vs2019/dsp_custom.vcxproj.filters new file mode 100644 index 0000000..fc0f117 --- /dev/null +++ b/FMOD/api/core/examples/vs2019/dsp_custom.vcxproj.filters @@ -0,0 +1,24 @@ + + + + + common + + + common + + + + + {937abb1b-0123-4875-9828-07ed9f9813e3} + + + + + common + + + common + + + \ No newline at end of file diff --git a/FMOD/api/core/examples/vs2019/dsp_effect_per_speaker.vcxproj b/FMOD/api/core/examples/vs2019/dsp_effect_per_speaker.vcxproj new file mode 100644 index 0000000..8b4e3a9 --- /dev/null +++ b/FMOD/api/core/examples/vs2019/dsp_effect_per_speaker.vcxproj @@ -0,0 +1,83 @@ + + + + + Debug + Win32 + + + Debug + x64 + + + Debug + ARM64 + + + Release + Win32 + + + Release + x64 + + + Release + ARM64 + + + + x86 + x64 + ARM64 + L + + + {55A6C6B3-EB1C-45D6-ABD3-F41B62EC8436} + + + + Application + v142 + false + true + + + + $(SolutionDir)_builds\$(ProjectName)\$(Configuration)\$(Platform)\ + $(SolutionDir)_builds\$(ProjectName)\$(Configuration)\$(Platform)\Intermediate\ + false + $(ProjectName)$(Suffix) + + + + Level3 + ..\..\inc + ProgramDatabase + _WIN32_WINNT=0x601;WINVER=0x601;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) + + + Windows + true + ..\..\lib\$(Arch) + fmod$(Suffix)_vc.lib;%(AdditionalDependencies) + + + if not exist ..\bin mkdir ..\bin +copy /Y "$(TargetPath)" ..\bin +copy /Y "..\..\lib\$(Arch)\fmod$(Suffix).dll" ..\bin +copy /Y "..\..\lib\$(Arch)\fmod$(Suffix).dll" "$(OutDir)" + + + + + + + + + + + + + + diff --git a/FMOD/api/core/examples/vs2019/dsp_effect_per_speaker.vcxproj.filters b/FMOD/api/core/examples/vs2019/dsp_effect_per_speaker.vcxproj.filters new file mode 100644 index 0000000..fc0f117 --- /dev/null +++ b/FMOD/api/core/examples/vs2019/dsp_effect_per_speaker.vcxproj.filters @@ -0,0 +1,24 @@ + + + + + common + + + common + + + + + {937abb1b-0123-4875-9828-07ed9f9813e3} + + + + + common + + + common + + + \ No newline at end of file diff --git a/FMOD/api/core/examples/vs2019/dsp_inspector.vcxproj b/FMOD/api/core/examples/vs2019/dsp_inspector.vcxproj new file mode 100644 index 0000000..ee12cc5 --- /dev/null +++ b/FMOD/api/core/examples/vs2019/dsp_inspector.vcxproj @@ -0,0 +1,83 @@ + + + + + Debug + Win32 + + + Debug + x64 + + + Debug + ARM64 + + + Release + Win32 + + + Release + x64 + + + Release + ARM64 + + + + x86 + x64 + ARM64 + L + + + {45B62C09-000B-49AB-A8DF-9F89F22FD4F8} + + + + Application + v142 + false + true + + + + $(SolutionDir)_builds\$(ProjectName)\$(Configuration)\$(Platform)\ + $(SolutionDir)_builds\$(ProjectName)\$(Configuration)\$(Platform)\Intermediate\ + false + $(ProjectName)$(Suffix) + + + + Level3 + ..\..\inc + ProgramDatabase + _WIN32_WINNT=0x601;WINVER=0x601;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) + + + Windows + true + ..\..\lib\$(Arch) + fmod$(Suffix)_vc.lib;%(AdditionalDependencies) + + + if not exist ..\bin mkdir ..\bin +copy /Y "$(TargetPath)" ..\bin +copy /Y "..\..\lib\$(Arch)\fmod$(Suffix).dll" ..\bin +copy /Y "..\..\lib\$(Arch)\fmod$(Suffix).dll" "$(OutDir)" + + + + + + + + + + + + + + diff --git a/FMOD/api/core/examples/vs2019/dsp_inspector.vcxproj.filters b/FMOD/api/core/examples/vs2019/dsp_inspector.vcxproj.filters new file mode 100644 index 0000000..fc0f117 --- /dev/null +++ b/FMOD/api/core/examples/vs2019/dsp_inspector.vcxproj.filters @@ -0,0 +1,24 @@ + + + + + common + + + common + + + + + {937abb1b-0123-4875-9828-07ed9f9813e3} + + + + + common + + + common + + + \ No newline at end of file diff --git a/FMOD/api/core/examples/vs2019/effects.vcxproj b/FMOD/api/core/examples/vs2019/effects.vcxproj new file mode 100644 index 0000000..a159c53 --- /dev/null +++ b/FMOD/api/core/examples/vs2019/effects.vcxproj @@ -0,0 +1,83 @@ + + + + + Debug + Win32 + + + Debug + x64 + + + Debug + ARM64 + + + Release + Win32 + + + Release + x64 + + + Release + ARM64 + + + + x86 + x64 + ARM64 + L + + + {147DC4C6-48E1-4018-A90C-C048452874B0} + + + + Application + v142 + false + true + + + + $(SolutionDir)_builds\$(ProjectName)\$(Configuration)\$(Platform)\ + $(SolutionDir)_builds\$(ProjectName)\$(Configuration)\$(Platform)\Intermediate\ + false + $(ProjectName)$(Suffix) + + + + Level3 + ..\..\inc + ProgramDatabase + _WIN32_WINNT=0x601;WINVER=0x601;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) + + + Windows + true + ..\..\lib\$(Arch) + fmod$(Suffix)_vc.lib;%(AdditionalDependencies) + + + if not exist ..\bin mkdir ..\bin +copy /Y "$(TargetPath)" ..\bin +copy /Y "..\..\lib\$(Arch)\fmod$(Suffix).dll" ..\bin +copy /Y "..\..\lib\$(Arch)\fmod$(Suffix).dll" "$(OutDir)" + + + + + + + + + + + + + + diff --git a/FMOD/api/core/examples/vs2019/effects.vcxproj.filters b/FMOD/api/core/examples/vs2019/effects.vcxproj.filters new file mode 100644 index 0000000..fc0f117 --- /dev/null +++ b/FMOD/api/core/examples/vs2019/effects.vcxproj.filters @@ -0,0 +1,24 @@ + + + + + common + + + common + + + + + {937abb1b-0123-4875-9828-07ed9f9813e3} + + + + + common + + + common + + + \ No newline at end of file diff --git a/FMOD/api/core/examples/vs2019/examples.sln b/FMOD/api/core/examples/vs2019/examples.sln new file mode 100644 index 0000000..e15c509 --- /dev/null +++ b/FMOD/api/core/examples/vs2019/examples.sln @@ -0,0 +1,538 @@ + +Microsoft Visual Studio Solution File, Format Version 11.00 +# Visual Studio Version 16 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "3d", "3d.vcxproj", "{ADD17242-D100-4B96-87C0-1B4F9E488CAA}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "asyncio", "asyncio.vcxproj", "{F110A4C9-EFE5-472B-9BA0-D7272C187C0E}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "channel_groups", "channel_groups.vcxproj", "{A7E69F23-1773-4D7A-9C16-A329639E66EA}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "convolution_reverb", "convolution_reverb.vcxproj", "{87AD5FA6-C607-4DF0-8BA2-769BEB4BDBC0}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "dsp_custom", "dsp_custom.vcxproj", "{08FFE91A-CC62-4357-856A-0379FA9CE526}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "dsp_effect_per_speaker", "dsp_effect_per_speaker.vcxproj", "{55A6C6B3-EB1C-45D6-ABD3-F41B62EC8436}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "dsp_inspector", "dsp_inspector.vcxproj", "{45B62C09-000B-49AB-A8DF-9F89F22FD4F8}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "effects", "effects.vcxproj", "{147DC4C6-48E1-4018-A90C-C048452874B0}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "gapless_playback", "gapless_playback.vcxproj", "{8F52BF20-643E-46AB-8807-6FB48DC52B35}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "generate_tone", "generate_tone.vcxproj", "{9E16C707-0F5E-4521-9A58-FA0A742259C7}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "granular_synth", "granular_synth.vcxproj", "{3F19F028-816A-47A7-BCEF-2A3989688534}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "load_from_memory", "load_from_memory.vcxproj", "{B11F9602-049A-4AAD-A1E7-447ACFFD48BB}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "multiple_speaker", "multiple_speaker.vcxproj", "{20C43E57-BD89-468D-AFA7-83583E85B332}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "multiple_system", "multiple_system.vcxproj", "{9110FF5A-0E6F-498A-8644-C4676E2512F7}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "net_stream", "net_stream.vcxproj", "{CF6AD8DE-783A-4D4C-A5C5-B15821005AA8}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "play_sound", "play_sound.vcxproj", "{012395B9-0619-4F92-A3A1-849E428FA9C5}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "play_stream", "play_stream.vcxproj", "{30AA49F0-403C-42A8-85D9-9368BD7D094F}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "record", "record.vcxproj", "{9F5AA538-A0B5-43BE-97BA-2699A8B3BCCC}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "record_enumeration", "record_enumeration.vcxproj", "{81A80C7F-07A9-47C2-BA06-0FDF6CEDD534}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "user_created_sound", "user_created_sound.vcxproj", "{967B4F9F-64AA-4D18-A70B-85679ECB2139}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "fmod_codec_raw", "fmod_codec_raw.vcxproj", "{9F630AA3-3E98-49FB-BAFF-46BB777E9347}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "fmod_distance_filter", "fmod_distance_filter.vcxproj", "{AE9C0F84-4920-4807-AD74-0AC87BF5DB85}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "fmod_gain", "fmod_gain.vcxproj", "{91FAFD26-BB00-47E6-9BF3-7518BE9A0FE6}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "fmod_noise", "fmod_noise.vcxproj", "{7824922D-742B-408C-AB19-B6C7854E8F69}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "fmod_rnbo", "fmod_rnbo.vcxproj", "{DD86B4DF-1EF1-4282-87BE-F8B01BF4CD11}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "output_mp3", "output_mp3.vcxproj", "{67A1AE60-71CB-4C53-8B2C-DF2C0E420115}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Win32 = Debug|Win32 + Debug|x64 = Debug|x64 + Debug|ARM64 = Debug|ARM64 + Release|Win32 = Release|Win32 + Release|x64 = Release|x64 + Release|ARM64 = Release|ARM64 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {ADD17242-D100-4B96-87C0-1B4F9E488CAA}.Debug|Win32.ActiveCfg = Debug|Win32 + {ADD17242-D100-4B96-87C0-1B4F9E488CAA}.Debug|Win32.Build.0 = Debug|Win32 + {ADD17242-D100-4B96-87C0-1B4F9E488CAA}.Debug|Win32.Deploy.0 = Debug|Win32 + {ADD17242-D100-4B96-87C0-1B4F9E488CAA}.Debug|x64.ActiveCfg = Debug|x64 + {ADD17242-D100-4B96-87C0-1B4F9E488CAA}.Debug|x64.Build.0 = Debug|x64 + {ADD17242-D100-4B96-87C0-1B4F9E488CAA}.Debug|x64.Deploy.0 = Debug|x64 + {ADD17242-D100-4B96-87C0-1B4F9E488CAA}.Debug|ARM64.ActiveCfg = Debug|ARM64 + {ADD17242-D100-4B96-87C0-1B4F9E488CAA}.Debug|ARM64.Build.0 = Debug|ARM64 + {ADD17242-D100-4B96-87C0-1B4F9E488CAA}.Debug|ARM64.Deploy.0 = Debug|ARM64 + {ADD17242-D100-4B96-87C0-1B4F9E488CAA}.Release|Win32.ActiveCfg = Release|Win32 + {ADD17242-D100-4B96-87C0-1B4F9E488CAA}.Release|Win32.Build.0 = Release|Win32 + {ADD17242-D100-4B96-87C0-1B4F9E488CAA}.Release|Win32.Deploy.0 = Release|Win32 + {ADD17242-D100-4B96-87C0-1B4F9E488CAA}.Release|x64.ActiveCfg = Release|x64 + {ADD17242-D100-4B96-87C0-1B4F9E488CAA}.Release|x64.Build.0 = Release|x64 + {ADD17242-D100-4B96-87C0-1B4F9E488CAA}.Release|x64.Deploy.0 = Release|x64 + {ADD17242-D100-4B96-87C0-1B4F9E488CAA}.Release|ARM64.ActiveCfg = Release|ARM64 + {ADD17242-D100-4B96-87C0-1B4F9E488CAA}.Release|ARM64.Build.0 = Release|ARM64 + {ADD17242-D100-4B96-87C0-1B4F9E488CAA}.Release|ARM64.Deploy.0 = Release|ARM64 + {F110A4C9-EFE5-472B-9BA0-D7272C187C0E}.Debug|Win32.ActiveCfg = Debug|Win32 + {F110A4C9-EFE5-472B-9BA0-D7272C187C0E}.Debug|Win32.Build.0 = Debug|Win32 + {F110A4C9-EFE5-472B-9BA0-D7272C187C0E}.Debug|Win32.Deploy.0 = Debug|Win32 + {F110A4C9-EFE5-472B-9BA0-D7272C187C0E}.Debug|x64.ActiveCfg = Debug|x64 + {F110A4C9-EFE5-472B-9BA0-D7272C187C0E}.Debug|x64.Build.0 = Debug|x64 + {F110A4C9-EFE5-472B-9BA0-D7272C187C0E}.Debug|x64.Deploy.0 = Debug|x64 + {F110A4C9-EFE5-472B-9BA0-D7272C187C0E}.Debug|ARM64.ActiveCfg = Debug|ARM64 + {F110A4C9-EFE5-472B-9BA0-D7272C187C0E}.Debug|ARM64.Build.0 = Debug|ARM64 + {F110A4C9-EFE5-472B-9BA0-D7272C187C0E}.Debug|ARM64.Deploy.0 = Debug|ARM64 + {F110A4C9-EFE5-472B-9BA0-D7272C187C0E}.Release|Win32.ActiveCfg = Release|Win32 + {F110A4C9-EFE5-472B-9BA0-D7272C187C0E}.Release|Win32.Build.0 = Release|Win32 + {F110A4C9-EFE5-472B-9BA0-D7272C187C0E}.Release|Win32.Deploy.0 = Release|Win32 + {F110A4C9-EFE5-472B-9BA0-D7272C187C0E}.Release|x64.ActiveCfg = Release|x64 + {F110A4C9-EFE5-472B-9BA0-D7272C187C0E}.Release|x64.Build.0 = Release|x64 + {F110A4C9-EFE5-472B-9BA0-D7272C187C0E}.Release|x64.Deploy.0 = Release|x64 + {F110A4C9-EFE5-472B-9BA0-D7272C187C0E}.Release|ARM64.ActiveCfg = Release|ARM64 + {F110A4C9-EFE5-472B-9BA0-D7272C187C0E}.Release|ARM64.Build.0 = Release|ARM64 + {F110A4C9-EFE5-472B-9BA0-D7272C187C0E}.Release|ARM64.Deploy.0 = Release|ARM64 + {A7E69F23-1773-4D7A-9C16-A329639E66EA}.Debug|Win32.ActiveCfg = Debug|Win32 + {A7E69F23-1773-4D7A-9C16-A329639E66EA}.Debug|Win32.Build.0 = Debug|Win32 + {A7E69F23-1773-4D7A-9C16-A329639E66EA}.Debug|Win32.Deploy.0 = Debug|Win32 + {A7E69F23-1773-4D7A-9C16-A329639E66EA}.Debug|x64.ActiveCfg = Debug|x64 + {A7E69F23-1773-4D7A-9C16-A329639E66EA}.Debug|x64.Build.0 = Debug|x64 + {A7E69F23-1773-4D7A-9C16-A329639E66EA}.Debug|x64.Deploy.0 = Debug|x64 + {A7E69F23-1773-4D7A-9C16-A329639E66EA}.Debug|ARM64.ActiveCfg = Debug|ARM64 + {A7E69F23-1773-4D7A-9C16-A329639E66EA}.Debug|ARM64.Build.0 = Debug|ARM64 + {A7E69F23-1773-4D7A-9C16-A329639E66EA}.Debug|ARM64.Deploy.0 = Debug|ARM64 + {A7E69F23-1773-4D7A-9C16-A329639E66EA}.Release|Win32.ActiveCfg = Release|Win32 + {A7E69F23-1773-4D7A-9C16-A329639E66EA}.Release|Win32.Build.0 = Release|Win32 + {A7E69F23-1773-4D7A-9C16-A329639E66EA}.Release|Win32.Deploy.0 = Release|Win32 + {A7E69F23-1773-4D7A-9C16-A329639E66EA}.Release|x64.ActiveCfg = Release|x64 + {A7E69F23-1773-4D7A-9C16-A329639E66EA}.Release|x64.Build.0 = Release|x64 + {A7E69F23-1773-4D7A-9C16-A329639E66EA}.Release|x64.Deploy.0 = Release|x64 + {A7E69F23-1773-4D7A-9C16-A329639E66EA}.Release|ARM64.ActiveCfg = Release|ARM64 + {A7E69F23-1773-4D7A-9C16-A329639E66EA}.Release|ARM64.Build.0 = Release|ARM64 + {A7E69F23-1773-4D7A-9C16-A329639E66EA}.Release|ARM64.Deploy.0 = Release|ARM64 + {87AD5FA6-C607-4DF0-8BA2-769BEB4BDBC0}.Debug|Win32.ActiveCfg = Debug|Win32 + {87AD5FA6-C607-4DF0-8BA2-769BEB4BDBC0}.Debug|Win32.Build.0 = Debug|Win32 + {87AD5FA6-C607-4DF0-8BA2-769BEB4BDBC0}.Debug|Win32.Deploy.0 = Debug|Win32 + {87AD5FA6-C607-4DF0-8BA2-769BEB4BDBC0}.Debug|x64.ActiveCfg = Debug|x64 + {87AD5FA6-C607-4DF0-8BA2-769BEB4BDBC0}.Debug|x64.Build.0 = Debug|x64 + {87AD5FA6-C607-4DF0-8BA2-769BEB4BDBC0}.Debug|x64.Deploy.0 = Debug|x64 + {87AD5FA6-C607-4DF0-8BA2-769BEB4BDBC0}.Debug|ARM64.ActiveCfg = Debug|ARM64 + {87AD5FA6-C607-4DF0-8BA2-769BEB4BDBC0}.Debug|ARM64.Build.0 = Debug|ARM64 + {87AD5FA6-C607-4DF0-8BA2-769BEB4BDBC0}.Debug|ARM64.Deploy.0 = Debug|ARM64 + {87AD5FA6-C607-4DF0-8BA2-769BEB4BDBC0}.Release|Win32.ActiveCfg = Release|Win32 + {87AD5FA6-C607-4DF0-8BA2-769BEB4BDBC0}.Release|Win32.Build.0 = Release|Win32 + {87AD5FA6-C607-4DF0-8BA2-769BEB4BDBC0}.Release|Win32.Deploy.0 = Release|Win32 + {87AD5FA6-C607-4DF0-8BA2-769BEB4BDBC0}.Release|x64.ActiveCfg = Release|x64 + {87AD5FA6-C607-4DF0-8BA2-769BEB4BDBC0}.Release|x64.Build.0 = Release|x64 + {87AD5FA6-C607-4DF0-8BA2-769BEB4BDBC0}.Release|x64.Deploy.0 = Release|x64 + {87AD5FA6-C607-4DF0-8BA2-769BEB4BDBC0}.Release|ARM64.ActiveCfg = Release|ARM64 + {87AD5FA6-C607-4DF0-8BA2-769BEB4BDBC0}.Release|ARM64.Build.0 = Release|ARM64 + {87AD5FA6-C607-4DF0-8BA2-769BEB4BDBC0}.Release|ARM64.Deploy.0 = Release|ARM64 + {08FFE91A-CC62-4357-856A-0379FA9CE526}.Debug|Win32.ActiveCfg = Debug|Win32 + {08FFE91A-CC62-4357-856A-0379FA9CE526}.Debug|Win32.Build.0 = Debug|Win32 + {08FFE91A-CC62-4357-856A-0379FA9CE526}.Debug|Win32.Deploy.0 = Debug|Win32 + {08FFE91A-CC62-4357-856A-0379FA9CE526}.Debug|x64.ActiveCfg = Debug|x64 + {08FFE91A-CC62-4357-856A-0379FA9CE526}.Debug|x64.Build.0 = Debug|x64 + {08FFE91A-CC62-4357-856A-0379FA9CE526}.Debug|x64.Deploy.0 = Debug|x64 + {08FFE91A-CC62-4357-856A-0379FA9CE526}.Debug|ARM64.ActiveCfg = Debug|ARM64 + {08FFE91A-CC62-4357-856A-0379FA9CE526}.Debug|ARM64.Build.0 = Debug|ARM64 + {08FFE91A-CC62-4357-856A-0379FA9CE526}.Debug|ARM64.Deploy.0 = Debug|ARM64 + {08FFE91A-CC62-4357-856A-0379FA9CE526}.Release|Win32.ActiveCfg = Release|Win32 + {08FFE91A-CC62-4357-856A-0379FA9CE526}.Release|Win32.Build.0 = Release|Win32 + {08FFE91A-CC62-4357-856A-0379FA9CE526}.Release|Win32.Deploy.0 = Release|Win32 + {08FFE91A-CC62-4357-856A-0379FA9CE526}.Release|x64.ActiveCfg = Release|x64 + {08FFE91A-CC62-4357-856A-0379FA9CE526}.Release|x64.Build.0 = Release|x64 + {08FFE91A-CC62-4357-856A-0379FA9CE526}.Release|x64.Deploy.0 = Release|x64 + {08FFE91A-CC62-4357-856A-0379FA9CE526}.Release|ARM64.ActiveCfg = Release|ARM64 + {08FFE91A-CC62-4357-856A-0379FA9CE526}.Release|ARM64.Build.0 = Release|ARM64 + {08FFE91A-CC62-4357-856A-0379FA9CE526}.Release|ARM64.Deploy.0 = Release|ARM64 + {55A6C6B3-EB1C-45D6-ABD3-F41B62EC8436}.Debug|Win32.ActiveCfg = Debug|Win32 + {55A6C6B3-EB1C-45D6-ABD3-F41B62EC8436}.Debug|Win32.Build.0 = Debug|Win32 + {55A6C6B3-EB1C-45D6-ABD3-F41B62EC8436}.Debug|Win32.Deploy.0 = Debug|Win32 + {55A6C6B3-EB1C-45D6-ABD3-F41B62EC8436}.Debug|x64.ActiveCfg = Debug|x64 + {55A6C6B3-EB1C-45D6-ABD3-F41B62EC8436}.Debug|x64.Build.0 = Debug|x64 + {55A6C6B3-EB1C-45D6-ABD3-F41B62EC8436}.Debug|x64.Deploy.0 = Debug|x64 + {55A6C6B3-EB1C-45D6-ABD3-F41B62EC8436}.Debug|ARM64.ActiveCfg = Debug|ARM64 + {55A6C6B3-EB1C-45D6-ABD3-F41B62EC8436}.Debug|ARM64.Build.0 = Debug|ARM64 + {55A6C6B3-EB1C-45D6-ABD3-F41B62EC8436}.Debug|ARM64.Deploy.0 = Debug|ARM64 + {55A6C6B3-EB1C-45D6-ABD3-F41B62EC8436}.Release|Win32.ActiveCfg = Release|Win32 + {55A6C6B3-EB1C-45D6-ABD3-F41B62EC8436}.Release|Win32.Build.0 = Release|Win32 + {55A6C6B3-EB1C-45D6-ABD3-F41B62EC8436}.Release|Win32.Deploy.0 = Release|Win32 + {55A6C6B3-EB1C-45D6-ABD3-F41B62EC8436}.Release|x64.ActiveCfg = Release|x64 + {55A6C6B3-EB1C-45D6-ABD3-F41B62EC8436}.Release|x64.Build.0 = Release|x64 + {55A6C6B3-EB1C-45D6-ABD3-F41B62EC8436}.Release|x64.Deploy.0 = Release|x64 + {55A6C6B3-EB1C-45D6-ABD3-F41B62EC8436}.Release|ARM64.ActiveCfg = Release|ARM64 + {55A6C6B3-EB1C-45D6-ABD3-F41B62EC8436}.Release|ARM64.Build.0 = Release|ARM64 + {55A6C6B3-EB1C-45D6-ABD3-F41B62EC8436}.Release|ARM64.Deploy.0 = Release|ARM64 + {45B62C09-000B-49AB-A8DF-9F89F22FD4F8}.Debug|Win32.ActiveCfg = Debug|Win32 + {45B62C09-000B-49AB-A8DF-9F89F22FD4F8}.Debug|Win32.Build.0 = Debug|Win32 + {45B62C09-000B-49AB-A8DF-9F89F22FD4F8}.Debug|Win32.Deploy.0 = Debug|Win32 + {45B62C09-000B-49AB-A8DF-9F89F22FD4F8}.Debug|x64.ActiveCfg = Debug|x64 + {45B62C09-000B-49AB-A8DF-9F89F22FD4F8}.Debug|x64.Build.0 = Debug|x64 + {45B62C09-000B-49AB-A8DF-9F89F22FD4F8}.Debug|x64.Deploy.0 = Debug|x64 + {45B62C09-000B-49AB-A8DF-9F89F22FD4F8}.Debug|ARM64.ActiveCfg = Debug|ARM64 + {45B62C09-000B-49AB-A8DF-9F89F22FD4F8}.Debug|ARM64.Build.0 = Debug|ARM64 + {45B62C09-000B-49AB-A8DF-9F89F22FD4F8}.Debug|ARM64.Deploy.0 = Debug|ARM64 + {45B62C09-000B-49AB-A8DF-9F89F22FD4F8}.Release|Win32.ActiveCfg = Release|Win32 + {45B62C09-000B-49AB-A8DF-9F89F22FD4F8}.Release|Win32.Build.0 = Release|Win32 + {45B62C09-000B-49AB-A8DF-9F89F22FD4F8}.Release|Win32.Deploy.0 = Release|Win32 + {45B62C09-000B-49AB-A8DF-9F89F22FD4F8}.Release|x64.ActiveCfg = Release|x64 + {45B62C09-000B-49AB-A8DF-9F89F22FD4F8}.Release|x64.Build.0 = Release|x64 + {45B62C09-000B-49AB-A8DF-9F89F22FD4F8}.Release|x64.Deploy.0 = Release|x64 + {45B62C09-000B-49AB-A8DF-9F89F22FD4F8}.Release|ARM64.ActiveCfg = Release|ARM64 + {45B62C09-000B-49AB-A8DF-9F89F22FD4F8}.Release|ARM64.Build.0 = Release|ARM64 + {45B62C09-000B-49AB-A8DF-9F89F22FD4F8}.Release|ARM64.Deploy.0 = Release|ARM64 + {147DC4C6-48E1-4018-A90C-C048452874B0}.Debug|Win32.ActiveCfg = Debug|Win32 + {147DC4C6-48E1-4018-A90C-C048452874B0}.Debug|Win32.Build.0 = Debug|Win32 + {147DC4C6-48E1-4018-A90C-C048452874B0}.Debug|Win32.Deploy.0 = Debug|Win32 + {147DC4C6-48E1-4018-A90C-C048452874B0}.Debug|x64.ActiveCfg = Debug|x64 + {147DC4C6-48E1-4018-A90C-C048452874B0}.Debug|x64.Build.0 = Debug|x64 + {147DC4C6-48E1-4018-A90C-C048452874B0}.Debug|x64.Deploy.0 = Debug|x64 + {147DC4C6-48E1-4018-A90C-C048452874B0}.Debug|ARM64.ActiveCfg = Debug|ARM64 + {147DC4C6-48E1-4018-A90C-C048452874B0}.Debug|ARM64.Build.0 = Debug|ARM64 + {147DC4C6-48E1-4018-A90C-C048452874B0}.Debug|ARM64.Deploy.0 = Debug|ARM64 + {147DC4C6-48E1-4018-A90C-C048452874B0}.Release|Win32.ActiveCfg = Release|Win32 + {147DC4C6-48E1-4018-A90C-C048452874B0}.Release|Win32.Build.0 = Release|Win32 + {147DC4C6-48E1-4018-A90C-C048452874B0}.Release|Win32.Deploy.0 = Release|Win32 + {147DC4C6-48E1-4018-A90C-C048452874B0}.Release|x64.ActiveCfg = Release|x64 + {147DC4C6-48E1-4018-A90C-C048452874B0}.Release|x64.Build.0 = Release|x64 + {147DC4C6-48E1-4018-A90C-C048452874B0}.Release|x64.Deploy.0 = Release|x64 + {147DC4C6-48E1-4018-A90C-C048452874B0}.Release|ARM64.ActiveCfg = Release|ARM64 + {147DC4C6-48E1-4018-A90C-C048452874B0}.Release|ARM64.Build.0 = Release|ARM64 + {147DC4C6-48E1-4018-A90C-C048452874B0}.Release|ARM64.Deploy.0 = Release|ARM64 + {8F52BF20-643E-46AB-8807-6FB48DC52B35}.Debug|Win32.ActiveCfg = Debug|Win32 + {8F52BF20-643E-46AB-8807-6FB48DC52B35}.Debug|Win32.Build.0 = Debug|Win32 + {8F52BF20-643E-46AB-8807-6FB48DC52B35}.Debug|Win32.Deploy.0 = Debug|Win32 + {8F52BF20-643E-46AB-8807-6FB48DC52B35}.Debug|x64.ActiveCfg = Debug|x64 + {8F52BF20-643E-46AB-8807-6FB48DC52B35}.Debug|x64.Build.0 = Debug|x64 + {8F52BF20-643E-46AB-8807-6FB48DC52B35}.Debug|x64.Deploy.0 = Debug|x64 + {8F52BF20-643E-46AB-8807-6FB48DC52B35}.Debug|ARM64.ActiveCfg = Debug|ARM64 + {8F52BF20-643E-46AB-8807-6FB48DC52B35}.Debug|ARM64.Build.0 = Debug|ARM64 + {8F52BF20-643E-46AB-8807-6FB48DC52B35}.Debug|ARM64.Deploy.0 = Debug|ARM64 + {8F52BF20-643E-46AB-8807-6FB48DC52B35}.Release|Win32.ActiveCfg = Release|Win32 + {8F52BF20-643E-46AB-8807-6FB48DC52B35}.Release|Win32.Build.0 = Release|Win32 + {8F52BF20-643E-46AB-8807-6FB48DC52B35}.Release|Win32.Deploy.0 = Release|Win32 + {8F52BF20-643E-46AB-8807-6FB48DC52B35}.Release|x64.ActiveCfg = Release|x64 + {8F52BF20-643E-46AB-8807-6FB48DC52B35}.Release|x64.Build.0 = Release|x64 + {8F52BF20-643E-46AB-8807-6FB48DC52B35}.Release|x64.Deploy.0 = Release|x64 + {8F52BF20-643E-46AB-8807-6FB48DC52B35}.Release|ARM64.ActiveCfg = Release|ARM64 + {8F52BF20-643E-46AB-8807-6FB48DC52B35}.Release|ARM64.Build.0 = Release|ARM64 + {8F52BF20-643E-46AB-8807-6FB48DC52B35}.Release|ARM64.Deploy.0 = Release|ARM64 + {9E16C707-0F5E-4521-9A58-FA0A742259C7}.Debug|Win32.ActiveCfg = Debug|Win32 + {9E16C707-0F5E-4521-9A58-FA0A742259C7}.Debug|Win32.Build.0 = Debug|Win32 + {9E16C707-0F5E-4521-9A58-FA0A742259C7}.Debug|Win32.Deploy.0 = Debug|Win32 + {9E16C707-0F5E-4521-9A58-FA0A742259C7}.Debug|x64.ActiveCfg = Debug|x64 + {9E16C707-0F5E-4521-9A58-FA0A742259C7}.Debug|x64.Build.0 = Debug|x64 + {9E16C707-0F5E-4521-9A58-FA0A742259C7}.Debug|x64.Deploy.0 = Debug|x64 + {9E16C707-0F5E-4521-9A58-FA0A742259C7}.Debug|ARM64.ActiveCfg = Debug|ARM64 + {9E16C707-0F5E-4521-9A58-FA0A742259C7}.Debug|ARM64.Build.0 = Debug|ARM64 + {9E16C707-0F5E-4521-9A58-FA0A742259C7}.Debug|ARM64.Deploy.0 = Debug|ARM64 + {9E16C707-0F5E-4521-9A58-FA0A742259C7}.Release|Win32.ActiveCfg = Release|Win32 + {9E16C707-0F5E-4521-9A58-FA0A742259C7}.Release|Win32.Build.0 = Release|Win32 + {9E16C707-0F5E-4521-9A58-FA0A742259C7}.Release|Win32.Deploy.0 = Release|Win32 + {9E16C707-0F5E-4521-9A58-FA0A742259C7}.Release|x64.ActiveCfg = Release|x64 + {9E16C707-0F5E-4521-9A58-FA0A742259C7}.Release|x64.Build.0 = Release|x64 + {9E16C707-0F5E-4521-9A58-FA0A742259C7}.Release|x64.Deploy.0 = Release|x64 + {9E16C707-0F5E-4521-9A58-FA0A742259C7}.Release|ARM64.ActiveCfg = Release|ARM64 + {9E16C707-0F5E-4521-9A58-FA0A742259C7}.Release|ARM64.Build.0 = Release|ARM64 + {9E16C707-0F5E-4521-9A58-FA0A742259C7}.Release|ARM64.Deploy.0 = Release|ARM64 + {3F19F028-816A-47A7-BCEF-2A3989688534}.Debug|Win32.ActiveCfg = Debug|Win32 + {3F19F028-816A-47A7-BCEF-2A3989688534}.Debug|Win32.Build.0 = Debug|Win32 + {3F19F028-816A-47A7-BCEF-2A3989688534}.Debug|Win32.Deploy.0 = Debug|Win32 + {3F19F028-816A-47A7-BCEF-2A3989688534}.Debug|x64.ActiveCfg = Debug|x64 + {3F19F028-816A-47A7-BCEF-2A3989688534}.Debug|x64.Build.0 = Debug|x64 + {3F19F028-816A-47A7-BCEF-2A3989688534}.Debug|x64.Deploy.0 = Debug|x64 + {3F19F028-816A-47A7-BCEF-2A3989688534}.Debug|ARM64.ActiveCfg = Debug|ARM64 + {3F19F028-816A-47A7-BCEF-2A3989688534}.Debug|ARM64.Build.0 = Debug|ARM64 + {3F19F028-816A-47A7-BCEF-2A3989688534}.Debug|ARM64.Deploy.0 = Debug|ARM64 + {3F19F028-816A-47A7-BCEF-2A3989688534}.Release|Win32.ActiveCfg = Release|Win32 + {3F19F028-816A-47A7-BCEF-2A3989688534}.Release|Win32.Build.0 = Release|Win32 + {3F19F028-816A-47A7-BCEF-2A3989688534}.Release|Win32.Deploy.0 = Release|Win32 + {3F19F028-816A-47A7-BCEF-2A3989688534}.Release|x64.ActiveCfg = Release|x64 + {3F19F028-816A-47A7-BCEF-2A3989688534}.Release|x64.Build.0 = Release|x64 + {3F19F028-816A-47A7-BCEF-2A3989688534}.Release|x64.Deploy.0 = Release|x64 + {3F19F028-816A-47A7-BCEF-2A3989688534}.Release|ARM64.ActiveCfg = Release|ARM64 + {3F19F028-816A-47A7-BCEF-2A3989688534}.Release|ARM64.Build.0 = Release|ARM64 + {3F19F028-816A-47A7-BCEF-2A3989688534}.Release|ARM64.Deploy.0 = Release|ARM64 + {B11F9602-049A-4AAD-A1E7-447ACFFD48BB}.Debug|Win32.ActiveCfg = Debug|Win32 + {B11F9602-049A-4AAD-A1E7-447ACFFD48BB}.Debug|Win32.Build.0 = Debug|Win32 + {B11F9602-049A-4AAD-A1E7-447ACFFD48BB}.Debug|Win32.Deploy.0 = Debug|Win32 + {B11F9602-049A-4AAD-A1E7-447ACFFD48BB}.Debug|x64.ActiveCfg = Debug|x64 + {B11F9602-049A-4AAD-A1E7-447ACFFD48BB}.Debug|x64.Build.0 = Debug|x64 + {B11F9602-049A-4AAD-A1E7-447ACFFD48BB}.Debug|x64.Deploy.0 = Debug|x64 + {B11F9602-049A-4AAD-A1E7-447ACFFD48BB}.Debug|ARM64.ActiveCfg = Debug|ARM64 + {B11F9602-049A-4AAD-A1E7-447ACFFD48BB}.Debug|ARM64.Build.0 = Debug|ARM64 + {B11F9602-049A-4AAD-A1E7-447ACFFD48BB}.Debug|ARM64.Deploy.0 = Debug|ARM64 + {B11F9602-049A-4AAD-A1E7-447ACFFD48BB}.Release|Win32.ActiveCfg = Release|Win32 + {B11F9602-049A-4AAD-A1E7-447ACFFD48BB}.Release|Win32.Build.0 = Release|Win32 + {B11F9602-049A-4AAD-A1E7-447ACFFD48BB}.Release|Win32.Deploy.0 = Release|Win32 + {B11F9602-049A-4AAD-A1E7-447ACFFD48BB}.Release|x64.ActiveCfg = Release|x64 + {B11F9602-049A-4AAD-A1E7-447ACFFD48BB}.Release|x64.Build.0 = Release|x64 + {B11F9602-049A-4AAD-A1E7-447ACFFD48BB}.Release|x64.Deploy.0 = Release|x64 + {B11F9602-049A-4AAD-A1E7-447ACFFD48BB}.Release|ARM64.ActiveCfg = Release|ARM64 + {B11F9602-049A-4AAD-A1E7-447ACFFD48BB}.Release|ARM64.Build.0 = Release|ARM64 + {B11F9602-049A-4AAD-A1E7-447ACFFD48BB}.Release|ARM64.Deploy.0 = Release|ARM64 + {20C43E57-BD89-468D-AFA7-83583E85B332}.Debug|Win32.ActiveCfg = Debug|Win32 + {20C43E57-BD89-468D-AFA7-83583E85B332}.Debug|Win32.Build.0 = Debug|Win32 + {20C43E57-BD89-468D-AFA7-83583E85B332}.Debug|Win32.Deploy.0 = Debug|Win32 + {20C43E57-BD89-468D-AFA7-83583E85B332}.Debug|x64.ActiveCfg = Debug|x64 + {20C43E57-BD89-468D-AFA7-83583E85B332}.Debug|x64.Build.0 = Debug|x64 + {20C43E57-BD89-468D-AFA7-83583E85B332}.Debug|x64.Deploy.0 = Debug|x64 + {20C43E57-BD89-468D-AFA7-83583E85B332}.Debug|ARM64.ActiveCfg = Debug|ARM64 + {20C43E57-BD89-468D-AFA7-83583E85B332}.Debug|ARM64.Build.0 = Debug|ARM64 + {20C43E57-BD89-468D-AFA7-83583E85B332}.Debug|ARM64.Deploy.0 = Debug|ARM64 + {20C43E57-BD89-468D-AFA7-83583E85B332}.Release|Win32.ActiveCfg = Release|Win32 + {20C43E57-BD89-468D-AFA7-83583E85B332}.Release|Win32.Build.0 = Release|Win32 + {20C43E57-BD89-468D-AFA7-83583E85B332}.Release|Win32.Deploy.0 = Release|Win32 + {20C43E57-BD89-468D-AFA7-83583E85B332}.Release|x64.ActiveCfg = Release|x64 + {20C43E57-BD89-468D-AFA7-83583E85B332}.Release|x64.Build.0 = Release|x64 + {20C43E57-BD89-468D-AFA7-83583E85B332}.Release|x64.Deploy.0 = Release|x64 + {20C43E57-BD89-468D-AFA7-83583E85B332}.Release|ARM64.ActiveCfg = Release|ARM64 + {20C43E57-BD89-468D-AFA7-83583E85B332}.Release|ARM64.Build.0 = Release|ARM64 + {20C43E57-BD89-468D-AFA7-83583E85B332}.Release|ARM64.Deploy.0 = Release|ARM64 + {9110FF5A-0E6F-498A-8644-C4676E2512F7}.Debug|Win32.ActiveCfg = Debug|Win32 + {9110FF5A-0E6F-498A-8644-C4676E2512F7}.Debug|Win32.Build.0 = Debug|Win32 + {9110FF5A-0E6F-498A-8644-C4676E2512F7}.Debug|Win32.Deploy.0 = Debug|Win32 + {9110FF5A-0E6F-498A-8644-C4676E2512F7}.Debug|x64.ActiveCfg = Debug|x64 + {9110FF5A-0E6F-498A-8644-C4676E2512F7}.Debug|x64.Build.0 = Debug|x64 + {9110FF5A-0E6F-498A-8644-C4676E2512F7}.Debug|x64.Deploy.0 = Debug|x64 + {9110FF5A-0E6F-498A-8644-C4676E2512F7}.Debug|ARM64.ActiveCfg = Debug|ARM64 + {9110FF5A-0E6F-498A-8644-C4676E2512F7}.Debug|ARM64.Build.0 = Debug|ARM64 + {9110FF5A-0E6F-498A-8644-C4676E2512F7}.Debug|ARM64.Deploy.0 = Debug|ARM64 + {9110FF5A-0E6F-498A-8644-C4676E2512F7}.Release|Win32.ActiveCfg = Release|Win32 + {9110FF5A-0E6F-498A-8644-C4676E2512F7}.Release|Win32.Build.0 = Release|Win32 + {9110FF5A-0E6F-498A-8644-C4676E2512F7}.Release|Win32.Deploy.0 = Release|Win32 + {9110FF5A-0E6F-498A-8644-C4676E2512F7}.Release|x64.ActiveCfg = Release|x64 + {9110FF5A-0E6F-498A-8644-C4676E2512F7}.Release|x64.Build.0 = Release|x64 + {9110FF5A-0E6F-498A-8644-C4676E2512F7}.Release|x64.Deploy.0 = Release|x64 + {9110FF5A-0E6F-498A-8644-C4676E2512F7}.Release|ARM64.ActiveCfg = Release|ARM64 + {9110FF5A-0E6F-498A-8644-C4676E2512F7}.Release|ARM64.Build.0 = Release|ARM64 + {9110FF5A-0E6F-498A-8644-C4676E2512F7}.Release|ARM64.Deploy.0 = Release|ARM64 + {CF6AD8DE-783A-4D4C-A5C5-B15821005AA8}.Debug|Win32.ActiveCfg = Debug|Win32 + {CF6AD8DE-783A-4D4C-A5C5-B15821005AA8}.Debug|Win32.Build.0 = Debug|Win32 + {CF6AD8DE-783A-4D4C-A5C5-B15821005AA8}.Debug|Win32.Deploy.0 = Debug|Win32 + {CF6AD8DE-783A-4D4C-A5C5-B15821005AA8}.Debug|x64.ActiveCfg = Debug|x64 + {CF6AD8DE-783A-4D4C-A5C5-B15821005AA8}.Debug|x64.Build.0 = Debug|x64 + {CF6AD8DE-783A-4D4C-A5C5-B15821005AA8}.Debug|x64.Deploy.0 = Debug|x64 + {CF6AD8DE-783A-4D4C-A5C5-B15821005AA8}.Debug|ARM64.ActiveCfg = Debug|ARM64 + {CF6AD8DE-783A-4D4C-A5C5-B15821005AA8}.Debug|ARM64.Build.0 = Debug|ARM64 + {CF6AD8DE-783A-4D4C-A5C5-B15821005AA8}.Debug|ARM64.Deploy.0 = Debug|ARM64 + {CF6AD8DE-783A-4D4C-A5C5-B15821005AA8}.Release|Win32.ActiveCfg = Release|Win32 + {CF6AD8DE-783A-4D4C-A5C5-B15821005AA8}.Release|Win32.Build.0 = Release|Win32 + {CF6AD8DE-783A-4D4C-A5C5-B15821005AA8}.Release|Win32.Deploy.0 = Release|Win32 + {CF6AD8DE-783A-4D4C-A5C5-B15821005AA8}.Release|x64.ActiveCfg = Release|x64 + {CF6AD8DE-783A-4D4C-A5C5-B15821005AA8}.Release|x64.Build.0 = Release|x64 + {CF6AD8DE-783A-4D4C-A5C5-B15821005AA8}.Release|x64.Deploy.0 = Release|x64 + {CF6AD8DE-783A-4D4C-A5C5-B15821005AA8}.Release|ARM64.ActiveCfg = Release|ARM64 + {CF6AD8DE-783A-4D4C-A5C5-B15821005AA8}.Release|ARM64.Build.0 = Release|ARM64 + {CF6AD8DE-783A-4D4C-A5C5-B15821005AA8}.Release|ARM64.Deploy.0 = Release|ARM64 + {012395B9-0619-4F92-A3A1-849E428FA9C5}.Debug|Win32.ActiveCfg = Debug|Win32 + {012395B9-0619-4F92-A3A1-849E428FA9C5}.Debug|Win32.Build.0 = Debug|Win32 + {012395B9-0619-4F92-A3A1-849E428FA9C5}.Debug|Win32.Deploy.0 = Debug|Win32 + {012395B9-0619-4F92-A3A1-849E428FA9C5}.Debug|x64.ActiveCfg = Debug|x64 + {012395B9-0619-4F92-A3A1-849E428FA9C5}.Debug|x64.Build.0 = Debug|x64 + {012395B9-0619-4F92-A3A1-849E428FA9C5}.Debug|x64.Deploy.0 = Debug|x64 + {012395B9-0619-4F92-A3A1-849E428FA9C5}.Debug|ARM64.ActiveCfg = Debug|ARM64 + {012395B9-0619-4F92-A3A1-849E428FA9C5}.Debug|ARM64.Build.0 = Debug|ARM64 + {012395B9-0619-4F92-A3A1-849E428FA9C5}.Debug|ARM64.Deploy.0 = Debug|ARM64 + {012395B9-0619-4F92-A3A1-849E428FA9C5}.Release|Win32.ActiveCfg = Release|Win32 + {012395B9-0619-4F92-A3A1-849E428FA9C5}.Release|Win32.Build.0 = Release|Win32 + {012395B9-0619-4F92-A3A1-849E428FA9C5}.Release|Win32.Deploy.0 = Release|Win32 + {012395B9-0619-4F92-A3A1-849E428FA9C5}.Release|x64.ActiveCfg = Release|x64 + {012395B9-0619-4F92-A3A1-849E428FA9C5}.Release|x64.Build.0 = Release|x64 + {012395B9-0619-4F92-A3A1-849E428FA9C5}.Release|x64.Deploy.0 = Release|x64 + {012395B9-0619-4F92-A3A1-849E428FA9C5}.Release|ARM64.ActiveCfg = Release|ARM64 + {012395B9-0619-4F92-A3A1-849E428FA9C5}.Release|ARM64.Build.0 = Release|ARM64 + {012395B9-0619-4F92-A3A1-849E428FA9C5}.Release|ARM64.Deploy.0 = Release|ARM64 + {30AA49F0-403C-42A8-85D9-9368BD7D094F}.Debug|Win32.ActiveCfg = Debug|Win32 + {30AA49F0-403C-42A8-85D9-9368BD7D094F}.Debug|Win32.Build.0 = Debug|Win32 + {30AA49F0-403C-42A8-85D9-9368BD7D094F}.Debug|Win32.Deploy.0 = Debug|Win32 + {30AA49F0-403C-42A8-85D9-9368BD7D094F}.Debug|x64.ActiveCfg = Debug|x64 + {30AA49F0-403C-42A8-85D9-9368BD7D094F}.Debug|x64.Build.0 = Debug|x64 + {30AA49F0-403C-42A8-85D9-9368BD7D094F}.Debug|x64.Deploy.0 = Debug|x64 + {30AA49F0-403C-42A8-85D9-9368BD7D094F}.Debug|ARM64.ActiveCfg = Debug|ARM64 + {30AA49F0-403C-42A8-85D9-9368BD7D094F}.Debug|ARM64.Build.0 = Debug|ARM64 + {30AA49F0-403C-42A8-85D9-9368BD7D094F}.Debug|ARM64.Deploy.0 = Debug|ARM64 + {30AA49F0-403C-42A8-85D9-9368BD7D094F}.Release|Win32.ActiveCfg = Release|Win32 + {30AA49F0-403C-42A8-85D9-9368BD7D094F}.Release|Win32.Build.0 = Release|Win32 + {30AA49F0-403C-42A8-85D9-9368BD7D094F}.Release|Win32.Deploy.0 = Release|Win32 + {30AA49F0-403C-42A8-85D9-9368BD7D094F}.Release|x64.ActiveCfg = Release|x64 + {30AA49F0-403C-42A8-85D9-9368BD7D094F}.Release|x64.Build.0 = Release|x64 + {30AA49F0-403C-42A8-85D9-9368BD7D094F}.Release|x64.Deploy.0 = Release|x64 + {30AA49F0-403C-42A8-85D9-9368BD7D094F}.Release|ARM64.ActiveCfg = Release|ARM64 + {30AA49F0-403C-42A8-85D9-9368BD7D094F}.Release|ARM64.Build.0 = Release|ARM64 + {30AA49F0-403C-42A8-85D9-9368BD7D094F}.Release|ARM64.Deploy.0 = Release|ARM64 + {9F5AA538-A0B5-43BE-97BA-2699A8B3BCCC}.Debug|Win32.ActiveCfg = Debug|Win32 + {9F5AA538-A0B5-43BE-97BA-2699A8B3BCCC}.Debug|Win32.Build.0 = Debug|Win32 + {9F5AA538-A0B5-43BE-97BA-2699A8B3BCCC}.Debug|Win32.Deploy.0 = Debug|Win32 + {9F5AA538-A0B5-43BE-97BA-2699A8B3BCCC}.Debug|x64.ActiveCfg = Debug|x64 + {9F5AA538-A0B5-43BE-97BA-2699A8B3BCCC}.Debug|x64.Build.0 = Debug|x64 + {9F5AA538-A0B5-43BE-97BA-2699A8B3BCCC}.Debug|x64.Deploy.0 = Debug|x64 + {9F5AA538-A0B5-43BE-97BA-2699A8B3BCCC}.Debug|ARM64.ActiveCfg = Debug|ARM64 + {9F5AA538-A0B5-43BE-97BA-2699A8B3BCCC}.Debug|ARM64.Build.0 = Debug|ARM64 + {9F5AA538-A0B5-43BE-97BA-2699A8B3BCCC}.Debug|ARM64.Deploy.0 = Debug|ARM64 + {9F5AA538-A0B5-43BE-97BA-2699A8B3BCCC}.Release|Win32.ActiveCfg = Release|Win32 + {9F5AA538-A0B5-43BE-97BA-2699A8B3BCCC}.Release|Win32.Build.0 = Release|Win32 + {9F5AA538-A0B5-43BE-97BA-2699A8B3BCCC}.Release|Win32.Deploy.0 = Release|Win32 + {9F5AA538-A0B5-43BE-97BA-2699A8B3BCCC}.Release|x64.ActiveCfg = Release|x64 + {9F5AA538-A0B5-43BE-97BA-2699A8B3BCCC}.Release|x64.Build.0 = Release|x64 + {9F5AA538-A0B5-43BE-97BA-2699A8B3BCCC}.Release|x64.Deploy.0 = Release|x64 + {9F5AA538-A0B5-43BE-97BA-2699A8B3BCCC}.Release|ARM64.ActiveCfg = Release|ARM64 + {9F5AA538-A0B5-43BE-97BA-2699A8B3BCCC}.Release|ARM64.Build.0 = Release|ARM64 + {9F5AA538-A0B5-43BE-97BA-2699A8B3BCCC}.Release|ARM64.Deploy.0 = Release|ARM64 + {81A80C7F-07A9-47C2-BA06-0FDF6CEDD534}.Debug|Win32.ActiveCfg = Debug|Win32 + {81A80C7F-07A9-47C2-BA06-0FDF6CEDD534}.Debug|Win32.Build.0 = Debug|Win32 + {81A80C7F-07A9-47C2-BA06-0FDF6CEDD534}.Debug|Win32.Deploy.0 = Debug|Win32 + {81A80C7F-07A9-47C2-BA06-0FDF6CEDD534}.Debug|x64.ActiveCfg = Debug|x64 + {81A80C7F-07A9-47C2-BA06-0FDF6CEDD534}.Debug|x64.Build.0 = Debug|x64 + {81A80C7F-07A9-47C2-BA06-0FDF6CEDD534}.Debug|x64.Deploy.0 = Debug|x64 + {81A80C7F-07A9-47C2-BA06-0FDF6CEDD534}.Debug|ARM64.ActiveCfg = Debug|ARM64 + {81A80C7F-07A9-47C2-BA06-0FDF6CEDD534}.Debug|ARM64.Build.0 = Debug|ARM64 + {81A80C7F-07A9-47C2-BA06-0FDF6CEDD534}.Debug|ARM64.Deploy.0 = Debug|ARM64 + {81A80C7F-07A9-47C2-BA06-0FDF6CEDD534}.Release|Win32.ActiveCfg = Release|Win32 + {81A80C7F-07A9-47C2-BA06-0FDF6CEDD534}.Release|Win32.Build.0 = Release|Win32 + {81A80C7F-07A9-47C2-BA06-0FDF6CEDD534}.Release|Win32.Deploy.0 = Release|Win32 + {81A80C7F-07A9-47C2-BA06-0FDF6CEDD534}.Release|x64.ActiveCfg = Release|x64 + {81A80C7F-07A9-47C2-BA06-0FDF6CEDD534}.Release|x64.Build.0 = Release|x64 + {81A80C7F-07A9-47C2-BA06-0FDF6CEDD534}.Release|x64.Deploy.0 = Release|x64 + {81A80C7F-07A9-47C2-BA06-0FDF6CEDD534}.Release|ARM64.ActiveCfg = Release|ARM64 + {81A80C7F-07A9-47C2-BA06-0FDF6CEDD534}.Release|ARM64.Build.0 = Release|ARM64 + {81A80C7F-07A9-47C2-BA06-0FDF6CEDD534}.Release|ARM64.Deploy.0 = Release|ARM64 + {967B4F9F-64AA-4D18-A70B-85679ECB2139}.Debug|Win32.ActiveCfg = Debug|Win32 + {967B4F9F-64AA-4D18-A70B-85679ECB2139}.Debug|Win32.Build.0 = Debug|Win32 + {967B4F9F-64AA-4D18-A70B-85679ECB2139}.Debug|Win32.Deploy.0 = Debug|Win32 + {967B4F9F-64AA-4D18-A70B-85679ECB2139}.Debug|x64.ActiveCfg = Debug|x64 + {967B4F9F-64AA-4D18-A70B-85679ECB2139}.Debug|x64.Build.0 = Debug|x64 + {967B4F9F-64AA-4D18-A70B-85679ECB2139}.Debug|x64.Deploy.0 = Debug|x64 + {967B4F9F-64AA-4D18-A70B-85679ECB2139}.Debug|ARM64.ActiveCfg = Debug|ARM64 + {967B4F9F-64AA-4D18-A70B-85679ECB2139}.Debug|ARM64.Build.0 = Debug|ARM64 + {967B4F9F-64AA-4D18-A70B-85679ECB2139}.Debug|ARM64.Deploy.0 = Debug|ARM64 + {967B4F9F-64AA-4D18-A70B-85679ECB2139}.Release|Win32.ActiveCfg = Release|Win32 + {967B4F9F-64AA-4D18-A70B-85679ECB2139}.Release|Win32.Build.0 = Release|Win32 + {967B4F9F-64AA-4D18-A70B-85679ECB2139}.Release|Win32.Deploy.0 = Release|Win32 + {967B4F9F-64AA-4D18-A70B-85679ECB2139}.Release|x64.ActiveCfg = Release|x64 + {967B4F9F-64AA-4D18-A70B-85679ECB2139}.Release|x64.Build.0 = Release|x64 + {967B4F9F-64AA-4D18-A70B-85679ECB2139}.Release|x64.Deploy.0 = Release|x64 + {967B4F9F-64AA-4D18-A70B-85679ECB2139}.Release|ARM64.ActiveCfg = Release|ARM64 + {967B4F9F-64AA-4D18-A70B-85679ECB2139}.Release|ARM64.Build.0 = Release|ARM64 + {967B4F9F-64AA-4D18-A70B-85679ECB2139}.Release|ARM64.Deploy.0 = Release|ARM64 + {9F630AA3-3E98-49FB-BAFF-46BB777E9347}.Debug|Win32.ActiveCfg = Debug|Win32 + {9F630AA3-3E98-49FB-BAFF-46BB777E9347}.Debug|Win32.Build.0 = Debug|Win32 + {9F630AA3-3E98-49FB-BAFF-46BB777E9347}.Debug|Win32.Deploy.0 = Debug|Win32 + {9F630AA3-3E98-49FB-BAFF-46BB777E9347}.Debug|x64.ActiveCfg = Debug|x64 + {9F630AA3-3E98-49FB-BAFF-46BB777E9347}.Debug|x64.Build.0 = Debug|x64 + {9F630AA3-3E98-49FB-BAFF-46BB777E9347}.Debug|x64.Deploy.0 = Debug|x64 + {9F630AA3-3E98-49FB-BAFF-46BB777E9347}.Debug|ARM64.ActiveCfg = Debug|ARM64 + {9F630AA3-3E98-49FB-BAFF-46BB777E9347}.Debug|ARM64.Build.0 = Debug|ARM64 + {9F630AA3-3E98-49FB-BAFF-46BB777E9347}.Debug|ARM64.Deploy.0 = Debug|ARM64 + {9F630AA3-3E98-49FB-BAFF-46BB777E9347}.Release|Win32.ActiveCfg = Release|Win32 + {9F630AA3-3E98-49FB-BAFF-46BB777E9347}.Release|Win32.Build.0 = Release|Win32 + {9F630AA3-3E98-49FB-BAFF-46BB777E9347}.Release|Win32.Deploy.0 = Release|Win32 + {9F630AA3-3E98-49FB-BAFF-46BB777E9347}.Release|x64.ActiveCfg = Release|x64 + {9F630AA3-3E98-49FB-BAFF-46BB777E9347}.Release|x64.Build.0 = Release|x64 + {9F630AA3-3E98-49FB-BAFF-46BB777E9347}.Release|x64.Deploy.0 = Release|x64 + {9F630AA3-3E98-49FB-BAFF-46BB777E9347}.Release|ARM64.ActiveCfg = Release|ARM64 + {9F630AA3-3E98-49FB-BAFF-46BB777E9347}.Release|ARM64.Build.0 = Release|ARM64 + {9F630AA3-3E98-49FB-BAFF-46BB777E9347}.Release|ARM64.Deploy.0 = Release|ARM64 + {AE9C0F84-4920-4807-AD74-0AC87BF5DB85}.Debug|Win32.ActiveCfg = Debug|Win32 + {AE9C0F84-4920-4807-AD74-0AC87BF5DB85}.Debug|Win32.Build.0 = Debug|Win32 + {AE9C0F84-4920-4807-AD74-0AC87BF5DB85}.Debug|Win32.Deploy.0 = Debug|Win32 + {AE9C0F84-4920-4807-AD74-0AC87BF5DB85}.Debug|x64.ActiveCfg = Debug|x64 + {AE9C0F84-4920-4807-AD74-0AC87BF5DB85}.Debug|x64.Build.0 = Debug|x64 + {AE9C0F84-4920-4807-AD74-0AC87BF5DB85}.Debug|x64.Deploy.0 = Debug|x64 + {AE9C0F84-4920-4807-AD74-0AC87BF5DB85}.Debug|ARM64.ActiveCfg = Debug|ARM64 + {AE9C0F84-4920-4807-AD74-0AC87BF5DB85}.Debug|ARM64.Build.0 = Debug|ARM64 + {AE9C0F84-4920-4807-AD74-0AC87BF5DB85}.Debug|ARM64.Deploy.0 = Debug|ARM64 + {AE9C0F84-4920-4807-AD74-0AC87BF5DB85}.Release|Win32.ActiveCfg = Release|Win32 + {AE9C0F84-4920-4807-AD74-0AC87BF5DB85}.Release|Win32.Build.0 = Release|Win32 + {AE9C0F84-4920-4807-AD74-0AC87BF5DB85}.Release|Win32.Deploy.0 = Release|Win32 + {AE9C0F84-4920-4807-AD74-0AC87BF5DB85}.Release|x64.ActiveCfg = Release|x64 + {AE9C0F84-4920-4807-AD74-0AC87BF5DB85}.Release|x64.Build.0 = Release|x64 + {AE9C0F84-4920-4807-AD74-0AC87BF5DB85}.Release|x64.Deploy.0 = Release|x64 + {AE9C0F84-4920-4807-AD74-0AC87BF5DB85}.Release|ARM64.ActiveCfg = Release|ARM64 + {AE9C0F84-4920-4807-AD74-0AC87BF5DB85}.Release|ARM64.Build.0 = Release|ARM64 + {AE9C0F84-4920-4807-AD74-0AC87BF5DB85}.Release|ARM64.Deploy.0 = Release|ARM64 + {91FAFD26-BB00-47E6-9BF3-7518BE9A0FE6}.Debug|Win32.ActiveCfg = Debug|Win32 + {91FAFD26-BB00-47E6-9BF3-7518BE9A0FE6}.Debug|Win32.Build.0 = Debug|Win32 + {91FAFD26-BB00-47E6-9BF3-7518BE9A0FE6}.Debug|Win32.Deploy.0 = Debug|Win32 + {91FAFD26-BB00-47E6-9BF3-7518BE9A0FE6}.Debug|x64.ActiveCfg = Debug|x64 + {91FAFD26-BB00-47E6-9BF3-7518BE9A0FE6}.Debug|x64.Build.0 = Debug|x64 + {91FAFD26-BB00-47E6-9BF3-7518BE9A0FE6}.Debug|x64.Deploy.0 = Debug|x64 + {91FAFD26-BB00-47E6-9BF3-7518BE9A0FE6}.Debug|ARM64.ActiveCfg = Debug|ARM64 + {91FAFD26-BB00-47E6-9BF3-7518BE9A0FE6}.Debug|ARM64.Build.0 = Debug|ARM64 + {91FAFD26-BB00-47E6-9BF3-7518BE9A0FE6}.Debug|ARM64.Deploy.0 = Debug|ARM64 + {91FAFD26-BB00-47E6-9BF3-7518BE9A0FE6}.Release|Win32.ActiveCfg = Release|Win32 + {91FAFD26-BB00-47E6-9BF3-7518BE9A0FE6}.Release|Win32.Build.0 = Release|Win32 + {91FAFD26-BB00-47E6-9BF3-7518BE9A0FE6}.Release|Win32.Deploy.0 = Release|Win32 + {91FAFD26-BB00-47E6-9BF3-7518BE9A0FE6}.Release|x64.ActiveCfg = Release|x64 + {91FAFD26-BB00-47E6-9BF3-7518BE9A0FE6}.Release|x64.Build.0 = Release|x64 + {91FAFD26-BB00-47E6-9BF3-7518BE9A0FE6}.Release|x64.Deploy.0 = Release|x64 + {91FAFD26-BB00-47E6-9BF3-7518BE9A0FE6}.Release|ARM64.ActiveCfg = Release|ARM64 + {91FAFD26-BB00-47E6-9BF3-7518BE9A0FE6}.Release|ARM64.Build.0 = Release|ARM64 + {91FAFD26-BB00-47E6-9BF3-7518BE9A0FE6}.Release|ARM64.Deploy.0 = Release|ARM64 + {7824922D-742B-408C-AB19-B6C7854E8F69}.Debug|Win32.ActiveCfg = Debug|Win32 + {7824922D-742B-408C-AB19-B6C7854E8F69}.Debug|Win32.Build.0 = Debug|Win32 + {7824922D-742B-408C-AB19-B6C7854E8F69}.Debug|Win32.Deploy.0 = Debug|Win32 + {7824922D-742B-408C-AB19-B6C7854E8F69}.Debug|x64.ActiveCfg = Debug|x64 + {7824922D-742B-408C-AB19-B6C7854E8F69}.Debug|x64.Build.0 = Debug|x64 + {7824922D-742B-408C-AB19-B6C7854E8F69}.Debug|x64.Deploy.0 = Debug|x64 + {7824922D-742B-408C-AB19-B6C7854E8F69}.Debug|ARM64.ActiveCfg = Debug|ARM64 + {7824922D-742B-408C-AB19-B6C7854E8F69}.Debug|ARM64.Build.0 = Debug|ARM64 + {7824922D-742B-408C-AB19-B6C7854E8F69}.Debug|ARM64.Deploy.0 = Debug|ARM64 + {7824922D-742B-408C-AB19-B6C7854E8F69}.Release|Win32.ActiveCfg = Release|Win32 + {7824922D-742B-408C-AB19-B6C7854E8F69}.Release|Win32.Build.0 = Release|Win32 + {7824922D-742B-408C-AB19-B6C7854E8F69}.Release|Win32.Deploy.0 = Release|Win32 + {7824922D-742B-408C-AB19-B6C7854E8F69}.Release|x64.ActiveCfg = Release|x64 + {7824922D-742B-408C-AB19-B6C7854E8F69}.Release|x64.Build.0 = Release|x64 + {7824922D-742B-408C-AB19-B6C7854E8F69}.Release|x64.Deploy.0 = Release|x64 + {7824922D-742B-408C-AB19-B6C7854E8F69}.Release|ARM64.ActiveCfg = Release|ARM64 + {7824922D-742B-408C-AB19-B6C7854E8F69}.Release|ARM64.Build.0 = Release|ARM64 + {7824922D-742B-408C-AB19-B6C7854E8F69}.Release|ARM64.Deploy.0 = Release|ARM64 + {DD86B4DF-1EF1-4282-87BE-F8B01BF4CD11}.Debug|Win32.ActiveCfg = Debug|Win32 + {DD86B4DF-1EF1-4282-87BE-F8B01BF4CD11}.Debug|Win32.Build.0 = Debug|Win32 + {DD86B4DF-1EF1-4282-87BE-F8B01BF4CD11}.Debug|Win32.Deploy.0 = Debug|Win32 + {DD86B4DF-1EF1-4282-87BE-F8B01BF4CD11}.Debug|x64.ActiveCfg = Debug|x64 + {DD86B4DF-1EF1-4282-87BE-F8B01BF4CD11}.Debug|x64.Build.0 = Debug|x64 + {DD86B4DF-1EF1-4282-87BE-F8B01BF4CD11}.Debug|x64.Deploy.0 = Debug|x64 + {DD86B4DF-1EF1-4282-87BE-F8B01BF4CD11}.Debug|ARM64.ActiveCfg = Debug|ARM64 + {DD86B4DF-1EF1-4282-87BE-F8B01BF4CD11}.Debug|ARM64.Build.0 = Debug|ARM64 + {DD86B4DF-1EF1-4282-87BE-F8B01BF4CD11}.Debug|ARM64.Deploy.0 = Debug|ARM64 + {DD86B4DF-1EF1-4282-87BE-F8B01BF4CD11}.Release|Win32.ActiveCfg = Release|Win32 + {DD86B4DF-1EF1-4282-87BE-F8B01BF4CD11}.Release|Win32.Build.0 = Release|Win32 + {DD86B4DF-1EF1-4282-87BE-F8B01BF4CD11}.Release|Win32.Deploy.0 = Release|Win32 + {DD86B4DF-1EF1-4282-87BE-F8B01BF4CD11}.Release|x64.ActiveCfg = Release|x64 + {DD86B4DF-1EF1-4282-87BE-F8B01BF4CD11}.Release|x64.Build.0 = Release|x64 + {DD86B4DF-1EF1-4282-87BE-F8B01BF4CD11}.Release|x64.Deploy.0 = Release|x64 + {DD86B4DF-1EF1-4282-87BE-F8B01BF4CD11}.Release|ARM64.ActiveCfg = Release|ARM64 + {DD86B4DF-1EF1-4282-87BE-F8B01BF4CD11}.Release|ARM64.Build.0 = Release|ARM64 + {DD86B4DF-1EF1-4282-87BE-F8B01BF4CD11}.Release|ARM64.Deploy.0 = Release|ARM64 + {67A1AE60-71CB-4C53-8B2C-DF2C0E420115}.Debug|Win32.ActiveCfg = Debug|Win32 + {67A1AE60-71CB-4C53-8B2C-DF2C0E420115}.Debug|Win32.Build.0 = Debug|Win32 + {67A1AE60-71CB-4C53-8B2C-DF2C0E420115}.Debug|Win32.Deploy.0 = Debug|Win32 + {67A1AE60-71CB-4C53-8B2C-DF2C0E420115}.Debug|x64.ActiveCfg = Debug|x64 + {67A1AE60-71CB-4C53-8B2C-DF2C0E420115}.Debug|x64.Build.0 = Debug|x64 + {67A1AE60-71CB-4C53-8B2C-DF2C0E420115}.Debug|x64.Deploy.0 = Debug|x64 + {67A1AE60-71CB-4C53-8B2C-DF2C0E420115}.Debug|ARM64.ActiveCfg = Debug|ARM64 + {67A1AE60-71CB-4C53-8B2C-DF2C0E420115}.Debug|ARM64.Build.0 = Debug|ARM64 + {67A1AE60-71CB-4C53-8B2C-DF2C0E420115}.Debug|ARM64.Deploy.0 = Debug|ARM64 + {67A1AE60-71CB-4C53-8B2C-DF2C0E420115}.Release|Win32.ActiveCfg = Release|Win32 + {67A1AE60-71CB-4C53-8B2C-DF2C0E420115}.Release|Win32.Build.0 = Release|Win32 + {67A1AE60-71CB-4C53-8B2C-DF2C0E420115}.Release|Win32.Deploy.0 = Release|Win32 + {67A1AE60-71CB-4C53-8B2C-DF2C0E420115}.Release|x64.ActiveCfg = Release|x64 + {67A1AE60-71CB-4C53-8B2C-DF2C0E420115}.Release|x64.Build.0 = Release|x64 + {67A1AE60-71CB-4C53-8B2C-DF2C0E420115}.Release|x64.Deploy.0 = Release|x64 + {67A1AE60-71CB-4C53-8B2C-DF2C0E420115}.Release|ARM64.ActiveCfg = Release|ARM64 + {67A1AE60-71CB-4C53-8B2C-DF2C0E420115}.Release|ARM64.Build.0 = Release|ARM64 + {67A1AE60-71CB-4C53-8B2C-DF2C0E420115}.Release|ARM64.Deploy.0 = Release|ARM64 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal diff --git a/FMOD/api/core/examples/vs2019/fmod_codec_raw.vcxproj b/FMOD/api/core/examples/vs2019/fmod_codec_raw.vcxproj new file mode 100644 index 0000000..320521b --- /dev/null +++ b/FMOD/api/core/examples/vs2019/fmod_codec_raw.vcxproj @@ -0,0 +1,69 @@ + + + + + Debug + Win32 + + + Debug + x64 + + + Debug + ARM64 + + + Release + Win32 + + + Release + x64 + + + Release + ARM64 + + + + L + $(Suffix)64 + + + {9F630AA3-3E98-49FB-BAFF-46BB777E9347} + + + + DynamicLibrary + v142 + false + true + + + + $(SolutionDir)_builds\$(ProjectName)\$(Configuration)\$(Platform)\ + $(SolutionDir)_builds\$(ProjectName)\$(Configuration)\$(Platform)\Intermediate\ + false + $(ProjectName)$(Suffix) + + + + Level3 + ..\..\inc + ProgramDatabase + _WIN32_WINNT=0x601;WINVER=0x601;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) + MultiThreaded + MultiThreadedDebug + + + if not exist ..\bin mkdir ..\bin +copy /Y "$(TargetPath)" ..\bin + + + + + + + + diff --git a/FMOD/api/core/examples/vs2019/fmod_distance_filter.vcxproj b/FMOD/api/core/examples/vs2019/fmod_distance_filter.vcxproj new file mode 100644 index 0000000..682b418 --- /dev/null +++ b/FMOD/api/core/examples/vs2019/fmod_distance_filter.vcxproj @@ -0,0 +1,69 @@ + + + + + Debug + Win32 + + + Debug + x64 + + + Debug + ARM64 + + + Release + Win32 + + + Release + x64 + + + Release + ARM64 + + + + L + $(Suffix)64 + + + {AE9C0F84-4920-4807-AD74-0AC87BF5DB85} + + + + DynamicLibrary + v142 + false + true + + + + $(SolutionDir)_builds\$(ProjectName)\$(Configuration)\$(Platform)\ + $(SolutionDir)_builds\$(ProjectName)\$(Configuration)\$(Platform)\Intermediate\ + false + $(ProjectName)$(Suffix) + + + + Level3 + ..\..\inc + ProgramDatabase + _WIN32_WINNT=0x601;WINVER=0x601;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) + MultiThreaded + MultiThreadedDebug + + + if not exist ..\bin mkdir ..\bin +copy /Y "$(TargetPath)" ..\bin + + + + + + + + diff --git a/FMOD/api/core/examples/vs2019/fmod_gain.vcxproj b/FMOD/api/core/examples/vs2019/fmod_gain.vcxproj new file mode 100644 index 0000000..c5bb0f4 --- /dev/null +++ b/FMOD/api/core/examples/vs2019/fmod_gain.vcxproj @@ -0,0 +1,69 @@ + + + + + Debug + Win32 + + + Debug + x64 + + + Debug + ARM64 + + + Release + Win32 + + + Release + x64 + + + Release + ARM64 + + + + L + $(Suffix)64 + + + {91FAFD26-BB00-47E6-9BF3-7518BE9A0FE6} + + + + DynamicLibrary + v142 + false + true + + + + $(SolutionDir)_builds\$(ProjectName)\$(Configuration)\$(Platform)\ + $(SolutionDir)_builds\$(ProjectName)\$(Configuration)\$(Platform)\Intermediate\ + false + $(ProjectName)$(Suffix) + + + + Level3 + ..\..\inc + ProgramDatabase + _WIN32_WINNT=0x601;WINVER=0x601;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) + MultiThreaded + MultiThreadedDebug + + + if not exist ..\bin mkdir ..\bin +copy /Y "$(TargetPath)" ..\bin + + + + + + + + diff --git a/FMOD/api/core/examples/vs2019/fmod_noise.vcxproj b/FMOD/api/core/examples/vs2019/fmod_noise.vcxproj new file mode 100644 index 0000000..0a56424 --- /dev/null +++ b/FMOD/api/core/examples/vs2019/fmod_noise.vcxproj @@ -0,0 +1,69 @@ + + + + + Debug + Win32 + + + Debug + x64 + + + Debug + ARM64 + + + Release + Win32 + + + Release + x64 + + + Release + ARM64 + + + + L + $(Suffix)64 + + + {7824922D-742B-408C-AB19-B6C7854E8F69} + + + + DynamicLibrary + v142 + false + true + + + + $(SolutionDir)_builds\$(ProjectName)\$(Configuration)\$(Platform)\ + $(SolutionDir)_builds\$(ProjectName)\$(Configuration)\$(Platform)\Intermediate\ + false + $(ProjectName)$(Suffix) + + + + Level3 + ..\..\inc + ProgramDatabase + _WIN32_WINNT=0x601;WINVER=0x601;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) + MultiThreaded + MultiThreadedDebug + + + if not exist ..\bin mkdir ..\bin +copy /Y "$(TargetPath)" ..\bin + + + + + + + + diff --git a/FMOD/api/core/examples/vs2019/fmod_rnbo.vcxproj b/FMOD/api/core/examples/vs2019/fmod_rnbo.vcxproj new file mode 100644 index 0000000..b888e38 --- /dev/null +++ b/FMOD/api/core/examples/vs2019/fmod_rnbo.vcxproj @@ -0,0 +1,69 @@ + + + + + Debug + Win32 + + + Debug + x64 + + + Debug + ARM64 + + + Release + Win32 + + + Release + x64 + + + Release + ARM64 + + + + L + $(Suffix)64 + + + {DD86B4DF-1EF1-4282-87BE-F8B01BF4CD11} + + + + DynamicLibrary + v142 + false + true + + + + $(SolutionDir)_builds\$(ProjectName)\$(Configuration)\$(Platform)\ + $(SolutionDir)_builds\$(ProjectName)\$(Configuration)\$(Platform)\Intermediate\ + false + $(ProjectName)$(Suffix) + + + + Level3 + ..\..\inc + ProgramDatabase + _WIN32_WINNT=0x601;WINVER=0x601;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) + MultiThreaded + MultiThreadedDebug + + + if not exist ..\bin mkdir ..\bin +copy /Y "$(TargetPath)" ..\bin + + + + + + + + diff --git a/FMOD/api/core/examples/vs2019/gapless_playback.vcxproj b/FMOD/api/core/examples/vs2019/gapless_playback.vcxproj new file mode 100644 index 0000000..1ccf709 --- /dev/null +++ b/FMOD/api/core/examples/vs2019/gapless_playback.vcxproj @@ -0,0 +1,83 @@ + + + + + Debug + Win32 + + + Debug + x64 + + + Debug + ARM64 + + + Release + Win32 + + + Release + x64 + + + Release + ARM64 + + + + x86 + x64 + ARM64 + L + + + {8F52BF20-643E-46AB-8807-6FB48DC52B35} + + + + Application + v142 + false + true + + + + $(SolutionDir)_builds\$(ProjectName)\$(Configuration)\$(Platform)\ + $(SolutionDir)_builds\$(ProjectName)\$(Configuration)\$(Platform)\Intermediate\ + false + $(ProjectName)$(Suffix) + + + + Level3 + ..\..\inc + ProgramDatabase + _WIN32_WINNT=0x601;WINVER=0x601;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) + + + Windows + true + ..\..\lib\$(Arch) + fmod$(Suffix)_vc.lib;%(AdditionalDependencies) + + + if not exist ..\bin mkdir ..\bin +copy /Y "$(TargetPath)" ..\bin +copy /Y "..\..\lib\$(Arch)\fmod$(Suffix).dll" ..\bin +copy /Y "..\..\lib\$(Arch)\fmod$(Suffix).dll" "$(OutDir)" + + + + + + + + + + + + + + diff --git a/FMOD/api/core/examples/vs2019/gapless_playback.vcxproj.filters b/FMOD/api/core/examples/vs2019/gapless_playback.vcxproj.filters new file mode 100644 index 0000000..fc0f117 --- /dev/null +++ b/FMOD/api/core/examples/vs2019/gapless_playback.vcxproj.filters @@ -0,0 +1,24 @@ + + + + + common + + + common + + + + + {937abb1b-0123-4875-9828-07ed9f9813e3} + + + + + common + + + common + + + \ No newline at end of file diff --git a/FMOD/api/core/examples/vs2019/generate_tone.vcxproj b/FMOD/api/core/examples/vs2019/generate_tone.vcxproj new file mode 100644 index 0000000..dcdec91 --- /dev/null +++ b/FMOD/api/core/examples/vs2019/generate_tone.vcxproj @@ -0,0 +1,83 @@ + + + + + Debug + Win32 + + + Debug + x64 + + + Debug + ARM64 + + + Release + Win32 + + + Release + x64 + + + Release + ARM64 + + + + x86 + x64 + ARM64 + L + + + {9E16C707-0F5E-4521-9A58-FA0A742259C7} + + + + Application + v142 + false + true + + + + $(SolutionDir)_builds\$(ProjectName)\$(Configuration)\$(Platform)\ + $(SolutionDir)_builds\$(ProjectName)\$(Configuration)\$(Platform)\Intermediate\ + false + $(ProjectName)$(Suffix) + + + + Level3 + ..\..\inc + ProgramDatabase + _WIN32_WINNT=0x601;WINVER=0x601;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) + + + Windows + true + ..\..\lib\$(Arch) + fmod$(Suffix)_vc.lib;%(AdditionalDependencies) + + + if not exist ..\bin mkdir ..\bin +copy /Y "$(TargetPath)" ..\bin +copy /Y "..\..\lib\$(Arch)\fmod$(Suffix).dll" ..\bin +copy /Y "..\..\lib\$(Arch)\fmod$(Suffix).dll" "$(OutDir)" + + + + + + + + + + + + + + diff --git a/FMOD/api/core/examples/vs2019/generate_tone.vcxproj.filters b/FMOD/api/core/examples/vs2019/generate_tone.vcxproj.filters new file mode 100644 index 0000000..fc0f117 --- /dev/null +++ b/FMOD/api/core/examples/vs2019/generate_tone.vcxproj.filters @@ -0,0 +1,24 @@ + + + + + common + + + common + + + + + {937abb1b-0123-4875-9828-07ed9f9813e3} + + + + + common + + + common + + + \ No newline at end of file diff --git a/FMOD/api/core/examples/vs2019/granular_synth.vcxproj b/FMOD/api/core/examples/vs2019/granular_synth.vcxproj new file mode 100644 index 0000000..e5fa904 --- /dev/null +++ b/FMOD/api/core/examples/vs2019/granular_synth.vcxproj @@ -0,0 +1,83 @@ + + + + + Debug + Win32 + + + Debug + x64 + + + Debug + ARM64 + + + Release + Win32 + + + Release + x64 + + + Release + ARM64 + + + + x86 + x64 + ARM64 + L + + + {3F19F028-816A-47A7-BCEF-2A3989688534} + + + + Application + v142 + false + true + + + + $(SolutionDir)_builds\$(ProjectName)\$(Configuration)\$(Platform)\ + $(SolutionDir)_builds\$(ProjectName)\$(Configuration)\$(Platform)\Intermediate\ + false + $(ProjectName)$(Suffix) + + + + Level3 + ..\..\inc + ProgramDatabase + _WIN32_WINNT=0x601;WINVER=0x601;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) + + + Windows + true + ..\..\lib\$(Arch) + fmod$(Suffix)_vc.lib;%(AdditionalDependencies) + + + if not exist ..\bin mkdir ..\bin +copy /Y "$(TargetPath)" ..\bin +copy /Y "..\..\lib\$(Arch)\fmod$(Suffix).dll" ..\bin +copy /Y "..\..\lib\$(Arch)\fmod$(Suffix).dll" "$(OutDir)" + + + + + + + + + + + + + + diff --git a/FMOD/api/core/examples/vs2019/granular_synth.vcxproj.filters b/FMOD/api/core/examples/vs2019/granular_synth.vcxproj.filters new file mode 100644 index 0000000..fc0f117 --- /dev/null +++ b/FMOD/api/core/examples/vs2019/granular_synth.vcxproj.filters @@ -0,0 +1,24 @@ + + + + + common + + + common + + + + + {937abb1b-0123-4875-9828-07ed9f9813e3} + + + + + common + + + common + + + \ No newline at end of file diff --git a/FMOD/api/core/examples/vs2019/load_from_memory.vcxproj b/FMOD/api/core/examples/vs2019/load_from_memory.vcxproj new file mode 100644 index 0000000..aff2531 --- /dev/null +++ b/FMOD/api/core/examples/vs2019/load_from_memory.vcxproj @@ -0,0 +1,83 @@ + + + + + Debug + Win32 + + + Debug + x64 + + + Debug + ARM64 + + + Release + Win32 + + + Release + x64 + + + Release + ARM64 + + + + x86 + x64 + ARM64 + L + + + {B11F9602-049A-4AAD-A1E7-447ACFFD48BB} + + + + Application + v142 + false + true + + + + $(SolutionDir)_builds\$(ProjectName)\$(Configuration)\$(Platform)\ + $(SolutionDir)_builds\$(ProjectName)\$(Configuration)\$(Platform)\Intermediate\ + false + $(ProjectName)$(Suffix) + + + + Level3 + ..\..\inc + ProgramDatabase + _WIN32_WINNT=0x601;WINVER=0x601;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) + + + Windows + true + ..\..\lib\$(Arch) + fmod$(Suffix)_vc.lib;%(AdditionalDependencies) + + + if not exist ..\bin mkdir ..\bin +copy /Y "$(TargetPath)" ..\bin +copy /Y "..\..\lib\$(Arch)\fmod$(Suffix).dll" ..\bin +copy /Y "..\..\lib\$(Arch)\fmod$(Suffix).dll" "$(OutDir)" + + + + + + + + + + + + + + diff --git a/FMOD/api/core/examples/vs2019/load_from_memory.vcxproj.filters b/FMOD/api/core/examples/vs2019/load_from_memory.vcxproj.filters new file mode 100644 index 0000000..fc0f117 --- /dev/null +++ b/FMOD/api/core/examples/vs2019/load_from_memory.vcxproj.filters @@ -0,0 +1,24 @@ + + + + + common + + + common + + + + + {937abb1b-0123-4875-9828-07ed9f9813e3} + + + + + common + + + common + + + \ No newline at end of file diff --git a/FMOD/api/core/examples/vs2019/multiple_speaker.vcxproj b/FMOD/api/core/examples/vs2019/multiple_speaker.vcxproj new file mode 100644 index 0000000..7c83542 --- /dev/null +++ b/FMOD/api/core/examples/vs2019/multiple_speaker.vcxproj @@ -0,0 +1,83 @@ + + + + + Debug + Win32 + + + Debug + x64 + + + Debug + ARM64 + + + Release + Win32 + + + Release + x64 + + + Release + ARM64 + + + + x86 + x64 + ARM64 + L + + + {20C43E57-BD89-468D-AFA7-83583E85B332} + + + + Application + v142 + false + true + + + + $(SolutionDir)_builds\$(ProjectName)\$(Configuration)\$(Platform)\ + $(SolutionDir)_builds\$(ProjectName)\$(Configuration)\$(Platform)\Intermediate\ + false + $(ProjectName)$(Suffix) + + + + Level3 + ..\..\inc + ProgramDatabase + _WIN32_WINNT=0x601;WINVER=0x601;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) + + + Windows + true + ..\..\lib\$(Arch) + fmod$(Suffix)_vc.lib;%(AdditionalDependencies) + + + if not exist ..\bin mkdir ..\bin +copy /Y "$(TargetPath)" ..\bin +copy /Y "..\..\lib\$(Arch)\fmod$(Suffix).dll" ..\bin +copy /Y "..\..\lib\$(Arch)\fmod$(Suffix).dll" "$(OutDir)" + + + + + + + + + + + + + + diff --git a/FMOD/api/core/examples/vs2019/multiple_speaker.vcxproj.filters b/FMOD/api/core/examples/vs2019/multiple_speaker.vcxproj.filters new file mode 100644 index 0000000..fc0f117 --- /dev/null +++ b/FMOD/api/core/examples/vs2019/multiple_speaker.vcxproj.filters @@ -0,0 +1,24 @@ + + + + + common + + + common + + + + + {937abb1b-0123-4875-9828-07ed9f9813e3} + + + + + common + + + common + + + \ No newline at end of file diff --git a/FMOD/api/core/examples/vs2019/multiple_system.vcxproj b/FMOD/api/core/examples/vs2019/multiple_system.vcxproj new file mode 100644 index 0000000..a78aaa3 --- /dev/null +++ b/FMOD/api/core/examples/vs2019/multiple_system.vcxproj @@ -0,0 +1,83 @@ + + + + + Debug + Win32 + + + Debug + x64 + + + Debug + ARM64 + + + Release + Win32 + + + Release + x64 + + + Release + ARM64 + + + + x86 + x64 + ARM64 + L + + + {9110FF5A-0E6F-498A-8644-C4676E2512F7} + + + + Application + v142 + false + true + + + + $(SolutionDir)_builds\$(ProjectName)\$(Configuration)\$(Platform)\ + $(SolutionDir)_builds\$(ProjectName)\$(Configuration)\$(Platform)\Intermediate\ + false + $(ProjectName)$(Suffix) + + + + Level3 + ..\..\inc + ProgramDatabase + _WIN32_WINNT=0x601;WINVER=0x601;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) + + + Windows + true + ..\..\lib\$(Arch) + fmod$(Suffix)_vc.lib;%(AdditionalDependencies) + + + if not exist ..\bin mkdir ..\bin +copy /Y "$(TargetPath)" ..\bin +copy /Y "..\..\lib\$(Arch)\fmod$(Suffix).dll" ..\bin +copy /Y "..\..\lib\$(Arch)\fmod$(Suffix).dll" "$(OutDir)" + + + + + + + + + + + + + + diff --git a/FMOD/api/core/examples/vs2019/multiple_system.vcxproj.filters b/FMOD/api/core/examples/vs2019/multiple_system.vcxproj.filters new file mode 100644 index 0000000..fc0f117 --- /dev/null +++ b/FMOD/api/core/examples/vs2019/multiple_system.vcxproj.filters @@ -0,0 +1,24 @@ + + + + + common + + + common + + + + + {937abb1b-0123-4875-9828-07ed9f9813e3} + + + + + common + + + common + + + \ No newline at end of file diff --git a/FMOD/api/core/examples/vs2019/net_stream.vcxproj b/FMOD/api/core/examples/vs2019/net_stream.vcxproj new file mode 100644 index 0000000..e1842c1 --- /dev/null +++ b/FMOD/api/core/examples/vs2019/net_stream.vcxproj @@ -0,0 +1,83 @@ + + + + + Debug + Win32 + + + Debug + x64 + + + Debug + ARM64 + + + Release + Win32 + + + Release + x64 + + + Release + ARM64 + + + + x86 + x64 + ARM64 + L + + + {CF6AD8DE-783A-4D4C-A5C5-B15821005AA8} + + + + Application + v142 + false + true + + + + $(SolutionDir)_builds\$(ProjectName)\$(Configuration)\$(Platform)\ + $(SolutionDir)_builds\$(ProjectName)\$(Configuration)\$(Platform)\Intermediate\ + false + $(ProjectName)$(Suffix) + + + + Level3 + ..\..\inc + ProgramDatabase + _WIN32_WINNT=0x601;WINVER=0x601;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) + + + Windows + true + ..\..\lib\$(Arch) + fmod$(Suffix)_vc.lib;%(AdditionalDependencies) + + + if not exist ..\bin mkdir ..\bin +copy /Y "$(TargetPath)" ..\bin +copy /Y "..\..\lib\$(Arch)\fmod$(Suffix).dll" ..\bin +copy /Y "..\..\lib\$(Arch)\fmod$(Suffix).dll" "$(OutDir)" + + + + + + + + + + + + + + diff --git a/FMOD/api/core/examples/vs2019/net_stream.vcxproj.filters b/FMOD/api/core/examples/vs2019/net_stream.vcxproj.filters new file mode 100644 index 0000000..fc0f117 --- /dev/null +++ b/FMOD/api/core/examples/vs2019/net_stream.vcxproj.filters @@ -0,0 +1,24 @@ + + + + + common + + + common + + + + + {937abb1b-0123-4875-9828-07ed9f9813e3} + + + + + common + + + common + + + \ No newline at end of file diff --git a/FMOD/api/core/examples/vs2019/output_mp3.vcxproj b/FMOD/api/core/examples/vs2019/output_mp3.vcxproj new file mode 100644 index 0000000..dbc392f --- /dev/null +++ b/FMOD/api/core/examples/vs2019/output_mp3.vcxproj @@ -0,0 +1,69 @@ + + + + + Debug + Win32 + + + Debug + x64 + + + Debug + ARM64 + + + Release + Win32 + + + Release + x64 + + + Release + ARM64 + + + + L + $(Suffix)64 + + + {67A1AE60-71CB-4C53-8B2C-DF2C0E420115} + + + + DynamicLibrary + v142 + false + true + + + + $(SolutionDir)_builds\$(ProjectName)\$(Configuration)\$(Platform)\ + $(SolutionDir)_builds\$(ProjectName)\$(Configuration)\$(Platform)\Intermediate\ + false + $(ProjectName)$(Suffix) + + + + Level3 + ..\..\inc + ProgramDatabase + _WIN32_WINNT=0x601;WINVER=0x601;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) + MultiThreaded + MultiThreadedDebug + + + if not exist ..\bin mkdir ..\bin +copy /Y "$(TargetPath)" ..\bin + + + + + + + + diff --git a/FMOD/api/core/examples/vs2019/play_sound.vcxproj b/FMOD/api/core/examples/vs2019/play_sound.vcxproj new file mode 100644 index 0000000..92e7968 --- /dev/null +++ b/FMOD/api/core/examples/vs2019/play_sound.vcxproj @@ -0,0 +1,83 @@ + + + + + Debug + Win32 + + + Debug + x64 + + + Debug + ARM64 + + + Release + Win32 + + + Release + x64 + + + Release + ARM64 + + + + x86 + x64 + ARM64 + L + + + {012395B9-0619-4F92-A3A1-849E428FA9C5} + + + + Application + v142 + false + true + + + + $(SolutionDir)_builds\$(ProjectName)\$(Configuration)\$(Platform)\ + $(SolutionDir)_builds\$(ProjectName)\$(Configuration)\$(Platform)\Intermediate\ + false + $(ProjectName)$(Suffix) + + + + Level3 + ..\..\inc + ProgramDatabase + _WIN32_WINNT=0x601;WINVER=0x601;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) + + + Windows + true + ..\..\lib\$(Arch) + fmod$(Suffix)_vc.lib;%(AdditionalDependencies) + + + if not exist ..\bin mkdir ..\bin +copy /Y "$(TargetPath)" ..\bin +copy /Y "..\..\lib\$(Arch)\fmod$(Suffix).dll" ..\bin +copy /Y "..\..\lib\$(Arch)\fmod$(Suffix).dll" "$(OutDir)" + + + + + + + + + + + + + + diff --git a/FMOD/api/core/examples/vs2019/play_sound.vcxproj.filters b/FMOD/api/core/examples/vs2019/play_sound.vcxproj.filters new file mode 100644 index 0000000..fc0f117 --- /dev/null +++ b/FMOD/api/core/examples/vs2019/play_sound.vcxproj.filters @@ -0,0 +1,24 @@ + + + + + common + + + common + + + + + {937abb1b-0123-4875-9828-07ed9f9813e3} + + + + + common + + + common + + + \ No newline at end of file diff --git a/FMOD/api/core/examples/vs2019/play_stream.vcxproj b/FMOD/api/core/examples/vs2019/play_stream.vcxproj new file mode 100644 index 0000000..dc5a6bd --- /dev/null +++ b/FMOD/api/core/examples/vs2019/play_stream.vcxproj @@ -0,0 +1,83 @@ + + + + + Debug + Win32 + + + Debug + x64 + + + Debug + ARM64 + + + Release + Win32 + + + Release + x64 + + + Release + ARM64 + + + + x86 + x64 + ARM64 + L + + + {30AA49F0-403C-42A8-85D9-9368BD7D094F} + + + + Application + v142 + false + true + + + + $(SolutionDir)_builds\$(ProjectName)\$(Configuration)\$(Platform)\ + $(SolutionDir)_builds\$(ProjectName)\$(Configuration)\$(Platform)\Intermediate\ + false + $(ProjectName)$(Suffix) + + + + Level3 + ..\..\inc + ProgramDatabase + _WIN32_WINNT=0x601;WINVER=0x601;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) + + + Windows + true + ..\..\lib\$(Arch) + fmod$(Suffix)_vc.lib;%(AdditionalDependencies) + + + if not exist ..\bin mkdir ..\bin +copy /Y "$(TargetPath)" ..\bin +copy /Y "..\..\lib\$(Arch)\fmod$(Suffix).dll" ..\bin +copy /Y "..\..\lib\$(Arch)\fmod$(Suffix).dll" "$(OutDir)" + + + + + + + + + + + + + + diff --git a/FMOD/api/core/examples/vs2019/play_stream.vcxproj.filters b/FMOD/api/core/examples/vs2019/play_stream.vcxproj.filters new file mode 100644 index 0000000..fc0f117 --- /dev/null +++ b/FMOD/api/core/examples/vs2019/play_stream.vcxproj.filters @@ -0,0 +1,24 @@ + + + + + common + + + common + + + + + {937abb1b-0123-4875-9828-07ed9f9813e3} + + + + + common + + + common + + + \ No newline at end of file diff --git a/FMOD/api/core/examples/vs2019/record.vcxproj b/FMOD/api/core/examples/vs2019/record.vcxproj new file mode 100644 index 0000000..3d5e8f8 --- /dev/null +++ b/FMOD/api/core/examples/vs2019/record.vcxproj @@ -0,0 +1,83 @@ + + + + + Debug + Win32 + + + Debug + x64 + + + Debug + ARM64 + + + Release + Win32 + + + Release + x64 + + + Release + ARM64 + + + + x86 + x64 + ARM64 + L + + + {9F5AA538-A0B5-43BE-97BA-2699A8B3BCCC} + + + + Application + v142 + false + true + + + + $(SolutionDir)_builds\$(ProjectName)\$(Configuration)\$(Platform)\ + $(SolutionDir)_builds\$(ProjectName)\$(Configuration)\$(Platform)\Intermediate\ + false + $(ProjectName)$(Suffix) + + + + Level3 + ..\..\inc + ProgramDatabase + _WIN32_WINNT=0x601;WINVER=0x601;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) + + + Windows + true + ..\..\lib\$(Arch) + fmod$(Suffix)_vc.lib;%(AdditionalDependencies) + + + if not exist ..\bin mkdir ..\bin +copy /Y "$(TargetPath)" ..\bin +copy /Y "..\..\lib\$(Arch)\fmod$(Suffix).dll" ..\bin +copy /Y "..\..\lib\$(Arch)\fmod$(Suffix).dll" "$(OutDir)" + + + + + + + + + + + + + + diff --git a/FMOD/api/core/examples/vs2019/record.vcxproj.filters b/FMOD/api/core/examples/vs2019/record.vcxproj.filters new file mode 100644 index 0000000..fc0f117 --- /dev/null +++ b/FMOD/api/core/examples/vs2019/record.vcxproj.filters @@ -0,0 +1,24 @@ + + + + + common + + + common + + + + + {937abb1b-0123-4875-9828-07ed9f9813e3} + + + + + common + + + common + + + \ No newline at end of file diff --git a/FMOD/api/core/examples/vs2019/record_enumeration.vcxproj b/FMOD/api/core/examples/vs2019/record_enumeration.vcxproj new file mode 100644 index 0000000..8edee32 --- /dev/null +++ b/FMOD/api/core/examples/vs2019/record_enumeration.vcxproj @@ -0,0 +1,83 @@ + + + + + Debug + Win32 + + + Debug + x64 + + + Debug + ARM64 + + + Release + Win32 + + + Release + x64 + + + Release + ARM64 + + + + x86 + x64 + ARM64 + L + + + {81A80C7F-07A9-47C2-BA06-0FDF6CEDD534} + + + + Application + v142 + false + true + + + + $(SolutionDir)_builds\$(ProjectName)\$(Configuration)\$(Platform)\ + $(SolutionDir)_builds\$(ProjectName)\$(Configuration)\$(Platform)\Intermediate\ + false + $(ProjectName)$(Suffix) + + + + Level3 + ..\..\inc + ProgramDatabase + _WIN32_WINNT=0x601;WINVER=0x601;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) + + + Windows + true + ..\..\lib\$(Arch) + fmod$(Suffix)_vc.lib;%(AdditionalDependencies) + + + if not exist ..\bin mkdir ..\bin +copy /Y "$(TargetPath)" ..\bin +copy /Y "..\..\lib\$(Arch)\fmod$(Suffix).dll" ..\bin +copy /Y "..\..\lib\$(Arch)\fmod$(Suffix).dll" "$(OutDir)" + + + + + + + + + + + + + + diff --git a/FMOD/api/core/examples/vs2019/record_enumeration.vcxproj.filters b/FMOD/api/core/examples/vs2019/record_enumeration.vcxproj.filters new file mode 100644 index 0000000..fc0f117 --- /dev/null +++ b/FMOD/api/core/examples/vs2019/record_enumeration.vcxproj.filters @@ -0,0 +1,24 @@ + + + + + common + + + common + + + + + {937abb1b-0123-4875-9828-07ed9f9813e3} + + + + + common + + + common + + + \ No newline at end of file diff --git a/FMOD/api/core/examples/vs2019/user_created_sound.vcxproj b/FMOD/api/core/examples/vs2019/user_created_sound.vcxproj new file mode 100644 index 0000000..bd9abbd --- /dev/null +++ b/FMOD/api/core/examples/vs2019/user_created_sound.vcxproj @@ -0,0 +1,83 @@ + + + + + Debug + Win32 + + + Debug + x64 + + + Debug + ARM64 + + + Release + Win32 + + + Release + x64 + + + Release + ARM64 + + + + x86 + x64 + ARM64 + L + + + {967B4F9F-64AA-4D18-A70B-85679ECB2139} + + + + Application + v142 + false + true + + + + $(SolutionDir)_builds\$(ProjectName)\$(Configuration)\$(Platform)\ + $(SolutionDir)_builds\$(ProjectName)\$(Configuration)\$(Platform)\Intermediate\ + false + $(ProjectName)$(Suffix) + + + + Level3 + ..\..\inc + ProgramDatabase + _WIN32_WINNT=0x601;WINVER=0x601;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) + + + Windows + true + ..\..\lib\$(Arch) + fmod$(Suffix)_vc.lib;%(AdditionalDependencies) + + + if not exist ..\bin mkdir ..\bin +copy /Y "$(TargetPath)" ..\bin +copy /Y "..\..\lib\$(Arch)\fmod$(Suffix).dll" ..\bin +copy /Y "..\..\lib\$(Arch)\fmod$(Suffix).dll" "$(OutDir)" + + + + + + + + + + + + + + diff --git a/FMOD/api/core/examples/vs2019/user_created_sound.vcxproj.filters b/FMOD/api/core/examples/vs2019/user_created_sound.vcxproj.filters new file mode 100644 index 0000000..fc0f117 --- /dev/null +++ b/FMOD/api/core/examples/vs2019/user_created_sound.vcxproj.filters @@ -0,0 +1,24 @@ + + + + + common + + + common + + + + + {937abb1b-0123-4875-9828-07ed9f9813e3} + + + + + common + + + common + + + \ No newline at end of file diff --git a/FMOD/api/core/inc/fmod.cs b/FMOD/api/core/inc/fmod.cs new file mode 100644 index 0000000..02bc513 --- /dev/null +++ b/FMOD/api/core/inc/fmod.cs @@ -0,0 +1,4090 @@ +/* ======================================================================================== */ +/* FMOD Core API - C# wrapper. */ +/* Copyright (c), Firelight Technologies Pty, Ltd. 2004-2026. */ +/* */ +/* For more detail visit: */ +/* https://fmod.com/docs/2.03/api/core-api.html */ +/* ======================================================================================== */ + +using System; +using System.Text; +using System.Runtime.InteropServices; +using System.Collections.Generic; + +namespace FMOD +{ + /* + FMOD version number. Check this against FMOD::System::getVersion / System_GetVersion + 0xaaaabbcc -> aaaa = major version number. bb = minor version number. cc = development version number. + */ + public partial class VERSION + { + public const int number = 0x00020313; + + /* + Define FMOD_DEBUG or FMOD_LOGGING to select appropriate libraries + */ +#if FMOD_DEBUG + public const string suffix = "D"; +#elif FMOD_LOGGING || DEVELOPMENT_BUILD + public const string suffix = "L"; +#else + public const string suffix = ""; +#endif + +#if !UNITY_2021_3_OR_NEWER + public const string dll = "fmod" + suffix; +#endif + } + + public class CONSTANTS + { + public const int MAX_CHANNEL_WIDTH = 32; + public const int MAX_LISTENERS = 8; + public const int REVERB_MAXINSTANCES = 4; + public const int MAX_SYSTEMS = 8; + } + + /* + FMOD core types + */ + public enum RESULT : int + { + OK, + ERR_BADCOMMAND, + ERR_CHANNEL_ALLOC, + ERR_CHANNEL_STOLEN, + ERR_DMA, + ERR_DSP_CONNECTION, + ERR_DSP_DONTPROCESS, + ERR_DSP_FORMAT, + ERR_DSP_INUSE, + ERR_DSP_NOTFOUND, + ERR_DSP_RESERVED, + ERR_DSP_SILENCE, + ERR_DSP_TYPE, + ERR_FILE_BAD, + ERR_FILE_COULDNOTSEEK, + ERR_FILE_DISKEJECTED, + ERR_FILE_EOF, + ERR_FILE_ENDOFDATA, + ERR_FILE_NOTFOUND, + ERR_FORMAT, + ERR_HEADER_MISMATCH, + ERR_HTTP, + ERR_HTTP_ACCESS, + ERR_HTTP_PROXY_AUTH, + ERR_HTTP_SERVER_ERROR, + ERR_HTTP_TIMEOUT, + ERR_INITIALIZATION, + ERR_INITIALIZED, + ERR_INTERNAL, + ERR_INVALID_FLOAT, + ERR_INVALID_HANDLE, + ERR_INVALID_PARAM, + ERR_INVALID_POSITION, + ERR_INVALID_SPEAKER, + ERR_INVALID_SYNCPOINT, + ERR_INVALID_THREAD, + ERR_INVALID_VECTOR, + ERR_MAXAUDIBLE, + ERR_MEMORY, + ERR_MEMORY_CANTPOINT, + ERR_NEEDS3D, + ERR_NEEDSHARDWARE, + ERR_NET_CONNECT, + ERR_NET_SOCKET_ERROR, + ERR_NET_URL, + ERR_NET_WOULD_BLOCK, + ERR_NOTREADY, + ERR_OUTPUT_ALLOCATED, + ERR_OUTPUT_CREATEBUFFER, + ERR_OUTPUT_DRIVERCALL, + ERR_OUTPUT_FORMAT, + ERR_OUTPUT_INIT, + ERR_OUTPUT_NODRIVERS, + ERR_PLUGIN, + ERR_PLUGIN_MISSING, + ERR_PLUGIN_RESOURCE, + ERR_PLUGIN_VERSION, + ERR_RECORD, + ERR_REVERB_CHANNELGROUP, + ERR_REVERB_INSTANCE, + ERR_SUBSOUNDS, + ERR_SUBSOUND_ALLOCATED, + ERR_SUBSOUND_CANTMOVE, + ERR_TAGNOTFOUND, + ERR_TOOMANYCHANNELS, + ERR_TRUNCATED, + ERR_UNIMPLEMENTED, + ERR_UNINITIALIZED, + ERR_UNSUPPORTED, + ERR_VERSION, + ERR_EVENT_ALREADY_LOADED, + ERR_EVENT_LIVEUPDATE_BUSY, + ERR_EVENT_LIVEUPDATE_MISMATCH, + ERR_EVENT_LIVEUPDATE_TIMEOUT, + ERR_EVENT_NOTFOUND, + ERR_STUDIO_UNINITIALIZED, + ERR_STUDIO_NOT_LOADED, + ERR_INVALID_STRING, + ERR_ALREADY_LOCKED, + ERR_NOT_LOCKED, + ERR_RECORD_DISCONNECTED, + ERR_TOOMANYSAMPLES, + } + + public enum CHANNELCONTROL_TYPE : int + { + CHANNEL, + CHANNELGROUP, + MAX + } + + [StructLayout(LayoutKind.Sequential)] + public struct VECTOR + { + public float x; + public float y; + public float z; + } + + [StructLayout(LayoutKind.Sequential)] + public struct ATTRIBUTES_3D + { + public VECTOR position; + public VECTOR velocity; + public VECTOR forward; + public VECTOR up; + } + + [StructLayout(LayoutKind.Sequential)] + public partial struct GUID + { + public int Data1; + public int Data2; + public int Data3; + public int Data4; + } + + [StructLayout(LayoutKind.Sequential)] + public struct ASYNCREADINFO + { + public IntPtr handle; + public uint offset; + public uint sizebytes; + public int priority; + + public IntPtr userdata; + public IntPtr buffer; + public uint bytesread; + public FILE_ASYNCDONE_FUNC done; + } + + public enum OUTPUTTYPE : int + { + AUTODETECT, + + UNKNOWN, + NOSOUND, + WAVWRITER, + NOSOUND_NRT, + WAVWRITER_NRT, + + WASAPI, + ASIO, + PULSEAUDIO, + ALSA, + COREAUDIO, + AUDIOTRACK, + OPENSL, + AUDIOOUT, + AUDIO3D, + WEBAUDIO, + NNAUDIO, + WINSONIC, + AAUDIO, + AUDIOWORKLET, + PHASE, + OHAUDIO, + + MAX, + } + + public enum PORT_TYPE : int + { + MUSIC, + COPYRIGHT_MUSIC, + VOICE, + CONTROLLER, + PERSONAL, + VIBRATION, + AUX, + PASSTHROUGH, + VR_VIBRATION, + + MAX + } + + public enum DEBUG_MODE : int + { + TTY, + FILE, + CALLBACK, + } + + [Flags] + public enum DEBUG_FLAGS : uint + { + NONE = 0x00000000, + ERROR = 0x00000001, + WARNING = 0x00000002, + LOG = 0x00000004, + + TYPE_MEMORY = 0x00000100, + TYPE_FILE = 0x00000200, + TYPE_CODEC = 0x00000400, + TYPE_TRACE = 0x00000800, + TYPE_VIRTUAL = 0x00001000, + + DISPLAY_TIMESTAMPS = 0x00010000, + DISPLAY_LINENUMBERS = 0x00020000, + DISPLAY_THREAD = 0x00040000, + } + + [Flags] + public enum MEMORY_TYPE : uint + { + NORMAL = 0x00000000, + STREAM_FILE = 0x00000001, + STREAM_DECODE = 0x00000002, + SAMPLEDATA = 0x00000004, + DSP_BUFFER = 0x00000008, + PLUGIN = 0x00000010, + PERSISTENT = 0x00200000, + ALL = 0xFFFFFFFF + } + + public enum SPEAKERMODE : int + { + DEFAULT, + RAW, + MONO, + STEREO, + QUAD, + SURROUND, + _5POINT1, + _7POINT1, + _7POINT1POINT4, + + MAX, + } + + public enum SPEAKER : int + { + NONE = -1, + FRONT_LEFT, + FRONT_RIGHT, + FRONT_CENTER, + LOW_FREQUENCY, + SURROUND_LEFT, + SURROUND_RIGHT, + BACK_LEFT, + BACK_RIGHT, + TOP_FRONT_LEFT, + TOP_FRONT_RIGHT, + TOP_BACK_LEFT, + TOP_BACK_RIGHT, + + MAX, + } + + [Flags] + public enum CHANNELMASK : uint + { + FRONT_LEFT = 0x00000001, + FRONT_RIGHT = 0x00000002, + FRONT_CENTER = 0x00000004, + LOW_FREQUENCY = 0x00000008, + SURROUND_LEFT = 0x00000010, + SURROUND_RIGHT = 0x00000020, + BACK_LEFT = 0x00000040, + BACK_RIGHT = 0x00000080, + BACK_CENTER = 0x00000100, + + MONO = (FRONT_LEFT), + STEREO = (FRONT_LEFT | FRONT_RIGHT), + LRC = (FRONT_LEFT | FRONT_RIGHT | FRONT_CENTER), + QUAD = (FRONT_LEFT | FRONT_RIGHT | SURROUND_LEFT | SURROUND_RIGHT), + SURROUND = (FRONT_LEFT | FRONT_RIGHT | FRONT_CENTER | SURROUND_LEFT | SURROUND_RIGHT), + _5POINT1 = (FRONT_LEFT | FRONT_RIGHT | FRONT_CENTER | LOW_FREQUENCY | SURROUND_LEFT | SURROUND_RIGHT), + _5POINT1_REARS = (FRONT_LEFT | FRONT_RIGHT | FRONT_CENTER | LOW_FREQUENCY | BACK_LEFT | BACK_RIGHT), + _7POINT0 = (FRONT_LEFT | FRONT_RIGHT | FRONT_CENTER | SURROUND_LEFT | SURROUND_RIGHT | BACK_LEFT | BACK_RIGHT), + _7POINT1 = (FRONT_LEFT | FRONT_RIGHT | FRONT_CENTER | LOW_FREQUENCY | SURROUND_LEFT | SURROUND_RIGHT | BACK_LEFT | BACK_RIGHT) + } + + public enum CHANNELORDER : int + { + DEFAULT, + WAVEFORMAT, + PROTOOLS, + ALLMONO, + ALLSTEREO, + ALSA, + + MAX, + } + + public enum PLUGINTYPE : int + { + OUTPUT, + CODEC, + DSP, + + MAX, + } + + [StructLayout(LayoutKind.Sequential)] + public struct PLUGINLIST + { + PLUGINTYPE type; + IntPtr description; + } + + [Flags] + public enum INITFLAGS : uint + { + NORMAL = 0x00000000, + STREAM_FROM_UPDATE = 0x00000001, + MIX_FROM_UPDATE = 0x00000002, + _3D_RIGHTHANDED = 0x00000004, + CLIP_OUTPUT = 0x00000008, + CHANNEL_LOWPASS = 0x00000100, + CHANNEL_DISTANCEFILTER = 0x00000200, + PROFILE_ENABLE = 0x00010000, + VOL0_BECOMES_VIRTUAL = 0x00020000, + GEOMETRY_USECLOSEST = 0x00040000, + PREFER_DOLBY_DOWNMIX = 0x00080000, + THREAD_UNSAFE = 0x00100000, + PROFILE_METER_ALL = 0x00200000, + MEMORY_TRACKING = 0x00400000, + } + + public enum SOUND_TYPE : int + { + UNKNOWN, + AIFF, + ASF, + DLS, + FLAC, + FSB, + IT, + MIDI, + MOD, + MPEG, + OGGVORBIS, + PLAYLIST, + RAW, + S3M, + USER, + WAV, + XM, + XMA, + AUDIOQUEUE, + AT9, + VORBIS, + MEDIA_FOUNDATION, + MEDIACODEC, + FADPCM, + OPUS, + + MAX, + } + + public enum SOUND_FORMAT : int + { + NONE, + PCM8, + PCM16, + PCM24, + PCM32, + PCMFLOAT, + BITSTREAM, + + MAX + } + + [Flags] + public enum MODE : uint + { + DEFAULT = 0x00000000, + LOOP_OFF = 0x00000001, + LOOP_NORMAL = 0x00000002, + LOOP_BIDI = 0x00000004, + _2D = 0x00000008, + _3D = 0x00000010, + CREATESTREAM = 0x00000080, + CREATESAMPLE = 0x00000100, + CREATECOMPRESSEDSAMPLE = 0x00000200, + OPENUSER = 0x00000400, + OPENMEMORY = 0x00000800, + OPENMEMORY_POINT = 0x10000000, + OPENRAW = 0x00001000, + OPENONLY = 0x00002000, + ACCURATETIME = 0x00004000, + MPEGSEARCH = 0x00008000, + NONBLOCKING = 0x00010000, + UNIQUE = 0x00020000, + _3D_HEADRELATIVE = 0x00040000, + _3D_WORLDRELATIVE = 0x00080000, + _3D_INVERSEROLLOFF = 0x00100000, + _3D_LINEARROLLOFF = 0x00200000, + _3D_LINEARSQUAREROLLOFF = 0x00400000, + _3D_INVERSETAPEREDROLLOFF = 0x00800000, + _3D_CUSTOMROLLOFF = 0x04000000, + _3D_IGNOREGEOMETRY = 0x40000000, + IGNORETAGS = 0x02000000, + LOWMEM = 0x08000000, + VIRTUAL_PLAYFROMSTART = 0x80000000 + } + + public enum OPENSTATE : int + { + READY, + LOADING, + ERROR, + CONNECTING, + BUFFERING, + SEEKING, + PLAYING, + SETPOSITION, + + MAX, + } + + public enum SOUNDGROUP_BEHAVIOR : int + { + BEHAVIOR_FAIL, + BEHAVIOR_MUTE, + BEHAVIOR_STEALLOWEST, + + MAX, + } + + public enum CHANNELCONTROL_CALLBACK_TYPE : int + { + END, + VIRTUALVOICE, + SYNCPOINT, + OCCLUSION, + + MAX, + } + + public struct CHANNELCONTROL_DSP_INDEX + { + public const int HEAD = -1; + public const int FADER = -2; + public const int TAIL = -3; + } + + public enum ERRORCALLBACK_INSTANCETYPE : int + { + NONE, + SYSTEM, + CHANNEL, + CHANNELGROUP, + CHANNELCONTROL, + SOUND, + SOUNDGROUP, + DSP, + DSPCONNECTION, + GEOMETRY, + REVERB3D, + STUDIO_SYSTEM, + STUDIO_EVENTDESCRIPTION, + STUDIO_EVENTINSTANCE, + STUDIO_PARAMETERINSTANCE, + STUDIO_BUS, + STUDIO_VCA, + STUDIO_BANK, + STUDIO_COMMANDREPLAY + } + + [StructLayout(LayoutKind.Sequential)] + public struct ERRORCALLBACK_INFO + { + public RESULT result; + public ERRORCALLBACK_INSTANCETYPE instancetype; + public IntPtr instance; + public StringWrapper functionname; + public StringWrapper functionparams; + } + + [StructLayout(LayoutKind.Sequential)] + public struct CPU_USAGE + { + public float dsp; /* DSP mixing CPU usage. */ + public float stream; /* Streaming engine CPU usage. */ + public float geometry; /* Geometry engine CPU usage. */ + public float update; /* System::update CPU usage. */ + public float convolution1; /* Convolution reverb processing thread #1 CPU usage */ + public float convolution2; /* Convolution reverb processing thread #2 CPU usage */ + } + + [StructLayout(LayoutKind.Sequential)] + public struct DSP_DATA_PARAMETER_INFO + { + public IntPtr data; + public uint length; + public int index; + } + + [Flags] + public enum SYSTEM_CALLBACK_TYPE : uint + { + DEVICELISTCHANGED = 0x00000001, + DEVICELOST = 0x00000002, + MEMORYALLOCATIONFAILED = 0x00000004, + THREADCREATED = 0x00000008, + BADDSPCONNECTION = 0x00000010, + PREMIX = 0x00000020, + POSTMIX = 0x00000040, + ERROR = 0x00000080, + THREADDESTROYED = 0x00000100, + PREUPDATE = 0x00000200, + POSTUPDATE = 0x00000400, + RECORDLISTCHANGED = 0x00000800, + BUFFEREDNOMIX = 0x00001000, + DEVICEREINITIALIZE = 0x00002000, + OUTPUTUNDERRUN = 0x00004000, + RECORDPOSITIONCHANGED = 0x00008000, + ALL = 0xFFFFFFFF, + } + + /* + FMOD Callbacks + */ + public delegate RESULT DEBUG_CALLBACK (DEBUG_FLAGS flags, IntPtr file, int line, IntPtr func, IntPtr message); + public delegate RESULT SYSTEM_CALLBACK (IntPtr system, SYSTEM_CALLBACK_TYPE type, IntPtr commanddata1, IntPtr commanddata2, IntPtr userdata); + public delegate RESULT CHANNELCONTROL_CALLBACK (IntPtr channelcontrol, CHANNELCONTROL_TYPE controltype, CHANNELCONTROL_CALLBACK_TYPE callbacktype, IntPtr commanddata1, IntPtr commanddata2); + public delegate RESULT DSP_CALLBACK (IntPtr dsp, DSP_CALLBACK_TYPE type, IntPtr data); + public delegate RESULT SOUND_NONBLOCK_CALLBACK (IntPtr sound, RESULT result); + public delegate RESULT SOUND_PCMREAD_CALLBACK (IntPtr sound, IntPtr data, uint datalen); + public delegate RESULT SOUND_PCMSETPOS_CALLBACK (IntPtr sound, int subsound, uint position, TIMEUNIT postype); + public delegate RESULT FILE_OPEN_CALLBACK (IntPtr name, ref uint filesize, ref IntPtr handle, IntPtr userdata); + public delegate RESULT FILE_CLOSE_CALLBACK (IntPtr handle, IntPtr userdata); + public delegate RESULT FILE_READ_CALLBACK (IntPtr handle, IntPtr buffer, uint sizebytes, ref uint bytesread, IntPtr userdata); + public delegate RESULT FILE_SEEK_CALLBACK (IntPtr handle, uint pos, IntPtr userdata); + public delegate RESULT FILE_ASYNCREAD_CALLBACK (IntPtr info, IntPtr userdata); + public delegate RESULT FILE_ASYNCCANCEL_CALLBACK(IntPtr info, IntPtr userdata); + public delegate void FILE_ASYNCDONE_FUNC (IntPtr info, RESULT result); + public delegate IntPtr MEMORY_ALLOC_CALLBACK (uint size, MEMORY_TYPE type, IntPtr sourcestr); + public delegate IntPtr MEMORY_REALLOC_CALLBACK (IntPtr ptr, uint size, MEMORY_TYPE type, IntPtr sourcestr); + public delegate void MEMORY_FREE_CALLBACK (IntPtr ptr, MEMORY_TYPE type, IntPtr sourcestr); + public delegate float CB_3D_ROLLOFF_CALLBACK (IntPtr channelcontrol, float distance); + + public enum DSP_RESAMPLER : int + { + DEFAULT, + NOINTERP, + LINEAR, + CUBIC, + SPLINE, + + MAX, + } + + public enum DSP_CALLBACK_TYPE : int + { + DATAPARAMETERRELEASE, + + MAX, + } + + public enum DSPCONNECTION_TYPE : int + { + STANDARD, + SIDECHAIN, + SEND, + SEND_SIDECHAIN, + PREALLOCATED, + + MAX, + } + + public enum TAGTYPE : int + { + UNKNOWN, + ID3V1, + ID3V2, + VORBISCOMMENT, + SHOUTCAST, + ICECAST, + ASF, + MIDI, + PLAYLIST, + FMOD, + USER, + + MAX + } + + public enum TAGDATATYPE : int + { + BINARY, + INT, + FLOAT, + STRING, + STRING_UTF16, + STRING_UTF16BE, + STRING_UTF8, + + MAX + } + + [StructLayout(LayoutKind.Sequential)] + public struct TAG + { + public TAGTYPE type; + public TAGDATATYPE datatype; + public StringWrapper name; + public IntPtr data; + public uint datalen; + public bool updated; + } + + [Flags] + public enum TIMEUNIT : uint + { + MS = 0x00000001, + PCM = 0x00000002, + PCMBYTES = 0x00000004, + RAWBYTES = 0x00000008, + PCMFRACTION = 0x00000010, + MODORDER = 0x00000100, + MODROW = 0x00000200, + MODPATTERN = 0x00000400, + } + + public struct PORT_INDEX + { + public const ulong NONE = 0xFFFFFFFFFFFFFFFF; + } + + [StructLayout(LayoutKind.Sequential)] + public struct CREATESOUNDEXINFO + { + public int cbsize; + public uint length; + public uint fileoffset; + public int numchannels; + public int defaultfrequency; + public SOUND_FORMAT format; + public uint decodebuffersize; + public int initialsubsound; + public int numsubsounds; + public IntPtr inclusionlist; + public int inclusionlistnum; + public IntPtr pcmreadcallback_internal; + public IntPtr pcmsetposcallback_internal; + public IntPtr nonblockcallback_internal; + public IntPtr dlsname; + public IntPtr encryptionkey; + public int maxpolyphony; + public IntPtr userdata; + public SOUND_TYPE suggestedsoundtype; + public IntPtr fileuseropen_internal; + public IntPtr fileuserclose_internal; + public IntPtr fileuserread_internal; + public IntPtr fileuserseek_internal; + public IntPtr fileuserasyncread_internal; + public IntPtr fileuserasynccancel_internal; + public IntPtr fileuserdata; + public int filebuffersize; + public CHANNELORDER channelorder; + public IntPtr initialsoundgroup; + public uint initialseekposition; + public TIMEUNIT initialseekpostype; + public int ignoresetfilesystem; + public uint audioqueuepolicy; + public uint minmidigranularity; + public int nonblockthreadid; + public IntPtr fsbguid; + + public SOUND_PCMREAD_CALLBACK pcmreadcallback + { + set { pcmreadcallback_internal = (value == null ? IntPtr.Zero : Marshal.GetFunctionPointerForDelegate(value)); } + get { return pcmreadcallback_internal == IntPtr.Zero ? null : Marshal.GetDelegateForFunctionPointer(pcmreadcallback_internal); } + } + public SOUND_PCMSETPOS_CALLBACK pcmsetposcallback + { + set { pcmsetposcallback_internal = (value == null ? IntPtr.Zero : Marshal.GetFunctionPointerForDelegate(value)); } + get { return pcmsetposcallback_internal == IntPtr.Zero ? null : Marshal.GetDelegateForFunctionPointer(pcmsetposcallback_internal); } + } + public SOUND_NONBLOCK_CALLBACK nonblockcallback + { + set { nonblockcallback_internal = (value == null ? IntPtr.Zero : Marshal.GetFunctionPointerForDelegate(value)); } + get { return nonblockcallback_internal == IntPtr.Zero ? null : Marshal.GetDelegateForFunctionPointer(nonblockcallback_internal); } + } + public FILE_OPEN_CALLBACK fileuseropen + { + set { fileuseropen_internal = (value == null ? IntPtr.Zero : Marshal.GetFunctionPointerForDelegate(value)); } + get { return fileuseropen_internal == IntPtr.Zero ? null : Marshal.GetDelegateForFunctionPointer(fileuseropen_internal); } + } + public FILE_CLOSE_CALLBACK fileuserclose + { + set { fileuserclose_internal = (value == null ? IntPtr.Zero : Marshal.GetFunctionPointerForDelegate(value)); } + get { return fileuserclose_internal == IntPtr.Zero ? null : Marshal.GetDelegateForFunctionPointer(fileuserclose_internal); } + } + public FILE_READ_CALLBACK fileuserread + { + set { fileuserread_internal = (value == null ? IntPtr.Zero : Marshal.GetFunctionPointerForDelegate(value)); } + get { return fileuserread_internal == IntPtr.Zero ? null : Marshal.GetDelegateForFunctionPointer(fileuserread_internal); } + } + public FILE_SEEK_CALLBACK fileuserseek + { + set { fileuserseek_internal = (value == null ? IntPtr.Zero : Marshal.GetFunctionPointerForDelegate(value)); } + get { return fileuserseek_internal == IntPtr.Zero ? null : Marshal.GetDelegateForFunctionPointer(fileuserseek_internal); } + } + public FILE_ASYNCREAD_CALLBACK fileuserasyncread + { + set { fileuserasyncread_internal = (value == null ? IntPtr.Zero : Marshal.GetFunctionPointerForDelegate(value)); } + get { return fileuserasyncread_internal == IntPtr.Zero ? null : Marshal.GetDelegateForFunctionPointer(fileuserasyncread_internal); } + } + public FILE_ASYNCCANCEL_CALLBACK fileuserasynccancel + { + set { fileuserasynccancel_internal = (value == null ? IntPtr.Zero : Marshal.GetFunctionPointerForDelegate(value)); } + get { return fileuserasynccancel_internal == IntPtr.Zero ? null : Marshal.GetDelegateForFunctionPointer(fileuserasynccancel_internal); } + } + + } + +#pragma warning disable 414 + [StructLayout(LayoutKind.Sequential)] + public struct REVERB_PROPERTIES + { + public float DecayTime; + public float EarlyDelay; + public float LateDelay; + public float HFReference; + public float HFDecayRatio; + public float Diffusion; + public float Density; + public float LowShelfFrequency; + public float LowShelfGain; + public float HighCut; + public float EarlyLateMix; + public float WetLevel; + + #region wrapperinternal + public REVERB_PROPERTIES(float decayTime, float earlyDelay, float lateDelay, float hfReference, + float hfDecayRatio, float diffusion, float density, float lowShelfFrequency, float lowShelfGain, + float highCut, float earlyLateMix, float wetLevel) + { + DecayTime = decayTime; + EarlyDelay = earlyDelay; + LateDelay = lateDelay; + HFReference = hfReference; + HFDecayRatio = hfDecayRatio; + Diffusion = diffusion; + Density = density; + LowShelfFrequency = lowShelfFrequency; + LowShelfGain = lowShelfGain; + HighCut = highCut; + EarlyLateMix = earlyLateMix; + WetLevel = wetLevel; + } + #endregion + } +#pragma warning restore 414 + + public class PRESET + { + public static REVERB_PROPERTIES OFF() { return new REVERB_PROPERTIES( 1000, 7, 11, 5000, 100, 100, 100, 250, 0, 20, 96, -80.0f );} + public static REVERB_PROPERTIES GENERIC() { return new REVERB_PROPERTIES( 1500, 7, 11, 5000, 83, 100, 100, 250, 0, 14500, 96, -8.0f );} + public static REVERB_PROPERTIES PADDEDCELL() { return new REVERB_PROPERTIES( 170, 1, 2, 5000, 10, 100, 100, 250, 0, 160, 84, -7.8f );} + public static REVERB_PROPERTIES ROOM() { return new REVERB_PROPERTIES( 400, 2, 3, 5000, 83, 100, 100, 250, 0, 6050, 88, -9.4f );} + public static REVERB_PROPERTIES BATHROOM() { return new REVERB_PROPERTIES( 1500, 7, 11, 5000, 54, 100, 60, 250, 0, 2900, 83, 0.5f );} + public static REVERB_PROPERTIES LIVINGROOM() { return new REVERB_PROPERTIES( 500, 3, 4, 5000, 10, 100, 100, 250, 0, 160, 58, -19.0f );} + public static REVERB_PROPERTIES STONEROOM() { return new REVERB_PROPERTIES( 2300, 12, 17, 5000, 64, 100, 100, 250, 0, 7800, 71, -8.5f );} + public static REVERB_PROPERTIES AUDITORIUM() { return new REVERB_PROPERTIES( 4300, 20, 30, 5000, 59, 100, 100, 250, 0, 5850, 64, -11.7f );} + public static REVERB_PROPERTIES CONCERTHALL() { return new REVERB_PROPERTIES( 3900, 20, 29, 5000, 70, 100, 100, 250, 0, 5650, 80, -9.8f );} + public static REVERB_PROPERTIES CAVE() { return new REVERB_PROPERTIES( 2900, 15, 22, 5000, 100, 100, 100, 250, 0, 20000, 59, -11.3f );} + public static REVERB_PROPERTIES ARENA() { return new REVERB_PROPERTIES( 7200, 20, 30, 5000, 33, 100, 100, 250, 0, 4500, 80, -9.6f );} + public static REVERB_PROPERTIES HANGAR() { return new REVERB_PROPERTIES( 10000, 20, 30, 5000, 23, 100, 100, 250, 0, 3400, 72, -7.4f );} + public static REVERB_PROPERTIES CARPETTEDHALLWAY() { return new REVERB_PROPERTIES( 300, 2, 30, 5000, 10, 100, 100, 250, 0, 500, 56, -24.0f );} + public static REVERB_PROPERTIES HALLWAY() { return new REVERB_PROPERTIES( 1500, 7, 11, 5000, 59, 100, 100, 250, 0, 7800, 87, -5.5f );} + public static REVERB_PROPERTIES STONECORRIDOR() { return new REVERB_PROPERTIES( 270, 13, 20, 5000, 79, 100, 100, 250, 0, 9000, 86, -6.0f );} + public static REVERB_PROPERTIES ALLEY() { return new REVERB_PROPERTIES( 1500, 7, 11, 5000, 86, 100, 100, 250, 0, 8300, 80, -9.8f );} + public static REVERB_PROPERTIES FOREST() { return new REVERB_PROPERTIES( 1500, 162, 88, 5000, 54, 79, 100, 250, 0, 760, 94, -12.3f );} + public static REVERB_PROPERTIES CITY() { return new REVERB_PROPERTIES( 1500, 7, 11, 5000, 67, 50, 100, 250, 0, 4050, 66, -26.0f );} + public static REVERB_PROPERTIES MOUNTAINS() { return new REVERB_PROPERTIES( 1500, 300, 100, 5000, 21, 27, 100, 250, 0, 1220, 82, -24.0f );} + public static REVERB_PROPERTIES QUARRY() { return new REVERB_PROPERTIES( 1500, 61, 25, 5000, 83, 100, 100, 250, 0, 3400, 100, -5.0f );} + public static REVERB_PROPERTIES PLAIN() { return new REVERB_PROPERTIES( 1500, 179, 100, 5000, 50, 21, 100, 250, 0, 1670, 65, -28.0f );} + public static REVERB_PROPERTIES PARKINGLOT() { return new REVERB_PROPERTIES( 1700, 8, 12, 5000, 100, 100, 100, 250, 0, 20000, 56, -19.5f );} + public static REVERB_PROPERTIES SEWERPIPE() { return new REVERB_PROPERTIES( 2800, 14, 21, 5000, 14, 80, 60, 250, 0, 3400, 66, 1.2f );} + public static REVERB_PROPERTIES UNDERWATER() { return new REVERB_PROPERTIES( 1500, 7, 11, 5000, 10, 100, 100, 250, 0, 500, 92, 7.0f );} + } + + [StructLayout(LayoutKind.Sequential)] + public struct ADVANCEDSETTINGS + { + public int cbSize; + public int maxMPEGCodecs; + public int maxADPCMCodecs; + public int maxXMACodecs; + public int maxVorbisCodecs; + public int maxAT9Codecs; + public int maxFADPCMCodecs; + public int maxOpusCodecs; + public int ASIONumChannels; + public IntPtr ASIOChannelList; + public IntPtr ASIOSpeakerList; + public float vol0virtualvol; + public uint defaultDecodeBufferSize; + public ushort profilePort; + public uint geometryMaxFadeTime; + public float distanceFilterCenterFreq; + public int reverb3Dinstance; + public int DSPBufferPoolSize; + public DSP_RESAMPLER resamplerMethod; + public uint randomSeed; + public int maxConvolutionThreads; + public int maxSpatialObjects; + } + + [Flags] + public enum DRIVER_STATE : uint + { + CONNECTED = 0x00000001, + DEFAULT = 0x00000002, + } + + public enum THREAD_PRIORITY : int + { + /* Platform specific priority range */ + PLATFORM_MIN = -32 * 1024, + PLATFORM_MAX = 32 * 1024, + + /* Platform agnostic priorities, maps internally to platform specific value */ + DEFAULT = PLATFORM_MIN - 1, + LOW = PLATFORM_MIN - 2, + MEDIUM = PLATFORM_MIN - 3, + HIGH = PLATFORM_MIN - 4, + VERY_HIGH = PLATFORM_MIN - 5, + EXTREME = PLATFORM_MIN - 6, + CRITICAL = PLATFORM_MIN - 7, + + /* Thread defaults */ + MIXER = EXTREME, + FEEDER = CRITICAL, + STREAM = VERY_HIGH, + FILE = HIGH, + NONBLOCKING = HIGH, + RECORD = HIGH, + GEOMETRY = LOW, + PROFILER = MEDIUM, + STUDIO_UPDATE = MEDIUM, + STUDIO_LOAD_BANK = MEDIUM, + STUDIO_LOAD_SAMPLE = MEDIUM, + CONVOLUTION1 = VERY_HIGH, + CONVOLUTION2 = VERY_HIGH + + } + + public enum THREAD_STACK_SIZE : uint + { + DEFAULT = 0, + MIXER = 80 * 1024, + FEEDER = 16 * 1024, + STREAM = 96 * 1024, + FILE = 64 * 1024, + NONBLOCKING = 112 * 1024, + RECORD = 16 * 1024, + GEOMETRY = 48 * 1024, + PROFILER = 128 * 1024, + STUDIO_UPDATE = 96 * 1024, + STUDIO_LOAD_BANK = 96 * 1024, + STUDIO_LOAD_SAMPLE = 96 * 1024, + CONVOLUTION1 = 16 * 1024, + CONVOLUTION2 = 16 * 1024 + } + + [Flags] + public enum THREAD_AFFINITY : long + { + /* Platform agnostic thread groupings */ + GROUP_DEFAULT = 0x4000000000000000, + GROUP_A = 0x4000000000000001, + GROUP_B = 0x4000000000000002, + GROUP_C = 0x4000000000000003, + + /* Thread defaults */ + MIXER = GROUP_A, + FEEDER = GROUP_C, + STREAM = GROUP_C, + FILE = GROUP_C, + NONBLOCKING = GROUP_C, + RECORD = GROUP_C, + GEOMETRY = GROUP_C, + PROFILER = GROUP_C, + STUDIO_UPDATE = GROUP_B, + STUDIO_LOAD_BANK = GROUP_C, + STUDIO_LOAD_SAMPLE = GROUP_C, + CONVOLUTION1 = GROUP_C, + CONVOLUTION2 = GROUP_C, + + /* Core mask, valid up to 1 << 61 */ + CORE_ALL = 0, + CORE_0 = 1 << 0, + CORE_1 = 1 << 1, + CORE_2 = 1 << 2, + CORE_3 = 1 << 3, + CORE_4 = 1 << 4, + CORE_5 = 1 << 5, + CORE_6 = 1 << 6, + CORE_7 = 1 << 7, + CORE_8 = 1 << 8, + CORE_9 = 1 << 9, + CORE_10 = 1 << 10, + CORE_11 = 1 << 11, + CORE_12 = 1 << 12, + CORE_13 = 1 << 13, + CORE_14 = 1 << 14, + CORE_15 = 1 << 15 + } + + public enum THREAD_TYPE : int + { + MIXER, + FEEDER, + STREAM, + FILE, + NONBLOCKING, + RECORD, + GEOMETRY, + PROFILER, + STUDIO_UPDATE, + STUDIO_LOAD_BANK, + STUDIO_LOAD_SAMPLE, + CONVOLUTION1, + CONVOLUTION2, + + MAX + } + + /* + FMOD System factory functions. Use this to create an FMOD System Instance. below you will see System init/close to get started. + */ + public struct Factory + { + public static RESULT System_Create(out System system) + { + return FMOD5_System_Create(out system.handle, VERSION.number); + } + + #region importfunctions + [DllImport(VERSION.dll)] + private static extern RESULT FMOD5_System_Create(out IntPtr system, uint headerversion); + + #endregion + } + + /* + FMOD global system functions (optional). + */ + public struct Memory + { + public static RESULT Initialize(IntPtr poolmem, int poollen, MEMORY_ALLOC_CALLBACK useralloc, MEMORY_REALLOC_CALLBACK userrealloc, MEMORY_FREE_CALLBACK userfree, MEMORY_TYPE memtypeflags = MEMORY_TYPE.ALL) + { + return FMOD5_Memory_Initialize(poolmem, poollen, useralloc, userrealloc, userfree, memtypeflags); + } + + public static RESULT GetStats(out int currentalloced, out int maxalloced, bool blocking = true) + { + return FMOD5_Memory_GetStats(out currentalloced, out maxalloced, blocking); + } + + #region importfunctions + [DllImport(VERSION.dll)] + private static extern RESULT FMOD5_Memory_Initialize(IntPtr poolmem, int poollen, MEMORY_ALLOC_CALLBACK useralloc, MEMORY_REALLOC_CALLBACK userrealloc, MEMORY_FREE_CALLBACK userfree, MEMORY_TYPE memtypeflags); + [DllImport(VERSION.dll)] + private static extern RESULT FMOD5_Memory_GetStats (out int currentalloced, out int maxalloced, bool blocking); + + #endregion + } + + public struct Debug + { + public static RESULT Initialize(DEBUG_FLAGS flags, DEBUG_MODE mode = DEBUG_MODE.TTY, DEBUG_CALLBACK callback = null, string filename = null) + { + using (StringHelper.ThreadSafeEncoding encoder = StringHelper.GetFreeHelper()) + { + return FMOD5_Debug_Initialize(flags, mode, callback, encoder.byteFromStringUTF8(filename)); + } + } + + #region importfunctions + [DllImport(VERSION.dll)] + private static extern RESULT FMOD5_Debug_Initialize(DEBUG_FLAGS flags, DEBUG_MODE mode, DEBUG_CALLBACK callback, byte[] filename); + + #endregion + } + + public struct Thread + { + public static RESULT SetAttributes(THREAD_TYPE type, THREAD_AFFINITY affinity = THREAD_AFFINITY.GROUP_DEFAULT, THREAD_PRIORITY priority = THREAD_PRIORITY.DEFAULT, THREAD_STACK_SIZE stacksize = THREAD_STACK_SIZE.DEFAULT) + { + return FMOD5_Thread_SetAttributes(type, affinity, priority, stacksize); + } + + #region importfunctions + [DllImport(VERSION.dll)] + private static extern RESULT FMOD5_Thread_SetAttributes(THREAD_TYPE type, THREAD_AFFINITY affinity, THREAD_PRIORITY priority, THREAD_STACK_SIZE stacksize); + #endregion + } + + /* + 'System' API. + */ + public struct System + { + public RESULT release() + { + return FMOD5_System_Release(this.handle); + } + + // Setup functions. + public RESULT setOutput(OUTPUTTYPE output) + { + return FMOD5_System_SetOutput(this.handle, output); + } + public RESULT getOutput(out OUTPUTTYPE output) + { + return FMOD5_System_GetOutput(this.handle, out output); + } + public RESULT getNumDrivers(out int numdrivers) + { + return FMOD5_System_GetNumDrivers(this.handle, out numdrivers); + } + public RESULT getDriverInfo(int id, out string name, int namelen, out Guid guid, out int systemrate, out SPEAKERMODE speakermode, out int speakermodechannels) + { + IntPtr stringMem = Marshal.AllocHGlobal(namelen); + + RESULT result = FMOD5_System_GetDriverInfo(this.handle, id, stringMem, namelen, out guid, out systemrate, out speakermode, out speakermodechannels); + using (StringHelper.ThreadSafeEncoding encoding = StringHelper.GetFreeHelper()) + { + name = encoding.stringFromNative(stringMem); + } + Marshal.FreeHGlobal(stringMem); + + return result; + } + public RESULT getDriverInfo(int id, out Guid guid, out int systemrate, out SPEAKERMODE speakermode, out int speakermodechannels) + { + return FMOD5_System_GetDriverInfo(this.handle, id, IntPtr.Zero, 0, out guid, out systemrate, out speakermode, out speakermodechannels); + } + public RESULT setDriver(int driver) + { + return FMOD5_System_SetDriver(this.handle, driver); + } + public RESULT getDriver(out int driver) + { + return FMOD5_System_GetDriver(this.handle, out driver); + } + public RESULT setSoftwareChannels(int numsoftwarechannels) + { + return FMOD5_System_SetSoftwareChannels(this.handle, numsoftwarechannels); + } + public RESULT getSoftwareChannels(out int numsoftwarechannels) + { + return FMOD5_System_GetSoftwareChannels(this.handle, out numsoftwarechannels); + } + public RESULT setSoftwareFormat(int samplerate, SPEAKERMODE speakermode, int numrawspeakers) + { + return FMOD5_System_SetSoftwareFormat(this.handle, samplerate, speakermode, numrawspeakers); + } + public RESULT getSoftwareFormat(out int samplerate, out SPEAKERMODE speakermode, out int numrawspeakers) + { + return FMOD5_System_GetSoftwareFormat(this.handle, out samplerate, out speakermode, out numrawspeakers); + } + public RESULT setDSPBufferSize(uint bufferlength, int numbuffers) + { + return FMOD5_System_SetDSPBufferSize(this.handle, bufferlength, numbuffers); + } + public RESULT getDSPBufferSize(out uint bufferlength, out int numbuffers) + { + return FMOD5_System_GetDSPBufferSize(this.handle, out bufferlength, out numbuffers); + } + public RESULT setFileSystem(FILE_OPEN_CALLBACK useropen, FILE_CLOSE_CALLBACK userclose, FILE_READ_CALLBACK userread, FILE_SEEK_CALLBACK userseek, FILE_ASYNCREAD_CALLBACK userasyncread, FILE_ASYNCCANCEL_CALLBACK userasynccancel, int blockalign) + { + return FMOD5_System_SetFileSystem(this.handle, useropen, userclose, userread, userseek, userasyncread, userasynccancel, blockalign); + } + public RESULT attachFileSystem(FILE_OPEN_CALLBACK useropen, FILE_CLOSE_CALLBACK userclose, FILE_READ_CALLBACK userread, FILE_SEEK_CALLBACK userseek) + { + return FMOD5_System_AttachFileSystem(this.handle, useropen, userclose, userread, userseek); + } + public RESULT setAdvancedSettings(ref ADVANCEDSETTINGS settings) + { + settings.cbSize = Marshal.SizeOf(); + return FMOD5_System_SetAdvancedSettings(this.handle, ref settings); + } + public RESULT getAdvancedSettings(ref ADVANCEDSETTINGS settings) + { + settings.cbSize = Marshal.SizeOf(); + return FMOD5_System_GetAdvancedSettings(this.handle, ref settings); + } + public RESULT setCallback(SYSTEM_CALLBACK callback, SYSTEM_CALLBACK_TYPE callbackmask = SYSTEM_CALLBACK_TYPE.ALL) + { + return FMOD5_System_SetCallback(this.handle, callback, callbackmask); + } + + // Plug-in support. + public RESULT setPluginPath(string path) + { + using (StringHelper.ThreadSafeEncoding encoder = StringHelper.GetFreeHelper()) + { + return FMOD5_System_SetPluginPath(this.handle, encoder.byteFromStringUTF8(path)); + } + } + public RESULT loadPlugin(string filename, out uint handle, uint priority = 0) + { + using (StringHelper.ThreadSafeEncoding encoder = StringHelper.GetFreeHelper()) + { + return FMOD5_System_LoadPlugin(this.handle, encoder.byteFromStringUTF8(filename), out handle, priority); + } + } + public RESULT unloadPlugin(uint handle) + { + return FMOD5_System_UnloadPlugin(this.handle, handle); + } + public RESULT getNumNestedPlugins(uint handle, out int count) + { + return FMOD5_System_GetNumNestedPlugins(this.handle, handle, out count); + } + public RESULT getNestedPlugin(uint handle, int index, out uint nestedhandle) + { + return FMOD5_System_GetNestedPlugin(this.handle, handle, index, out nestedhandle); + } + public RESULT getNumPlugins(PLUGINTYPE plugintype, out int numplugins) + { + return FMOD5_System_GetNumPlugins(this.handle, plugintype, out numplugins); + } + public RESULT getPluginHandle(PLUGINTYPE plugintype, int index, out uint handle) + { + return FMOD5_System_GetPluginHandle(this.handle, plugintype, index, out handle); + } + public RESULT getPluginInfo(uint handle, out PLUGINTYPE plugintype, out string name, int namelen, out uint version) + { + IntPtr stringMem = Marshal.AllocHGlobal(namelen); + + RESULT result = FMOD5_System_GetPluginInfo(this.handle, handle, out plugintype, stringMem, namelen, out version); + using (StringHelper.ThreadSafeEncoding encoder = StringHelper.GetFreeHelper()) + { + name = encoder.stringFromNative(stringMem); + } + Marshal.FreeHGlobal(stringMem); + + return result; + } + public RESULT getPluginInfo(uint handle, out PLUGINTYPE plugintype, out uint version) + { + return FMOD5_System_GetPluginInfo(this.handle, handle, out plugintype, IntPtr.Zero, 0, out version); + } + public RESULT setOutputByPlugin(uint handle) + { + return FMOD5_System_SetOutputByPlugin(this.handle, handle); + } + public RESULT getOutputByPlugin(out uint handle) + { + return FMOD5_System_GetOutputByPlugin(this.handle, out handle); + } + public RESULT createDSPByPlugin(uint handle, out DSP dsp) + { + return FMOD5_System_CreateDSPByPlugin(this.handle, handle, out dsp.handle); + } + public RESULT getDSPInfoByPlugin(uint handle, out IntPtr description) + { + return FMOD5_System_GetDSPInfoByPlugin(this.handle, handle, out description); + } + public RESULT registerDSP(ref DSP_DESCRIPTION description, out uint handle) + { + return FMOD5_System_RegisterDSP(this.handle, ref description, out handle); + } + + // Init/Close. + public RESULT init(int maxchannels, INITFLAGS flags, IntPtr extradriverdata) + { + return FMOD5_System_Init(this.handle, maxchannels, flags, extradriverdata); + } + public RESULT close() + { + return FMOD5_System_Close(this.handle); + } + + // General post-init system functions. + public RESULT update() + { + return FMOD5_System_Update(this.handle); + } + public RESULT setSpeakerPosition(SPEAKER speaker, float x, float y, bool active) + { + return FMOD5_System_SetSpeakerPosition(this.handle, speaker, x, y, active); + } + public RESULT getSpeakerPosition(SPEAKER speaker, out float x, out float y, out bool active) + { + return FMOD5_System_GetSpeakerPosition(this.handle, speaker, out x, out y, out active); + } + public RESULT setStreamBufferSize(uint filebuffersize, TIMEUNIT filebuffersizetype) + { + return FMOD5_System_SetStreamBufferSize(this.handle, filebuffersize, filebuffersizetype); + } + public RESULT getStreamBufferSize(out uint filebuffersize, out TIMEUNIT filebuffersizetype) + { + return FMOD5_System_GetStreamBufferSize(this.handle, out filebuffersize, out filebuffersizetype); + } + public RESULT set3DSettings(float dopplerscale, float distancefactor, float rolloffscale) + { + return FMOD5_System_Set3DSettings(this.handle, dopplerscale, distancefactor, rolloffscale); + } + public RESULT get3DSettings(out float dopplerscale, out float distancefactor, out float rolloffscale) + { + return FMOD5_System_Get3DSettings(this.handle, out dopplerscale, out distancefactor, out rolloffscale); + } + public RESULT set3DNumListeners(int numlisteners) + { + return FMOD5_System_Set3DNumListeners(this.handle, numlisteners); + } + public RESULT get3DNumListeners(out int numlisteners) + { + return FMOD5_System_Get3DNumListeners(this.handle, out numlisteners); + } + public RESULT set3DListenerAttributes(int listener, ref VECTOR pos, ref VECTOR vel, ref VECTOR forward, ref VECTOR up) + { + return FMOD5_System_Set3DListenerAttributes(this.handle, listener, ref pos, ref vel, ref forward, ref up); + } + public RESULT get3DListenerAttributes(int listener, out VECTOR pos, out VECTOR vel, out VECTOR forward, out VECTOR up) + { + return FMOD5_System_Get3DListenerAttributes(this.handle, listener, out pos, out vel, out forward, out up); + } + public RESULT set3DRolloffCallback(CB_3D_ROLLOFF_CALLBACK callback) + { + return FMOD5_System_Set3DRolloffCallback(this.handle, callback); + } + public RESULT mixerSuspend() + { + return FMOD5_System_MixerSuspend(this.handle); + } + public RESULT mixerResume() + { + return FMOD5_System_MixerResume(this.handle); + } + public RESULT getDefaultMixMatrix(SPEAKERMODE sourcespeakermode, SPEAKERMODE targetspeakermode, float[] matrix, int matrixhop) + { + return FMOD5_System_GetDefaultMixMatrix(this.handle, sourcespeakermode, targetspeakermode, matrix, matrixhop); + } + public RESULT getSpeakerModeChannels(SPEAKERMODE mode, out int channels) + { + return FMOD5_System_GetSpeakerModeChannels(this.handle, mode, out channels); + } + + // System information functions. + public RESULT getVersion(out uint version) + { + uint buildnumber; + return getVersion(out version, out buildnumber); + } + public RESULT getVersion(out uint version, out uint buildnumber) + { + return FMOD5_System_GetVersion(this.handle, out version, out buildnumber); + } + public RESULT getOutputHandle(out IntPtr handle) + { + return FMOD5_System_GetOutputHandle(this.handle, out handle); + } + public RESULT getChannelsPlaying(out int channels) + { + return FMOD5_System_GetChannelsPlaying(this.handle, out channels, IntPtr.Zero); + } + public RESULT getChannelsPlaying(out int channels, out int realchannels) + { + return FMOD5_System_GetChannelsPlaying(this.handle, out channels, out realchannels); + } + public RESULT getCPUUsage(out CPU_USAGE usage) + { + return FMOD5_System_GetCPUUsage(this.handle, out usage); + } + public RESULT getFileUsage(out Int64 sampleBytesRead, out Int64 streamBytesRead, out Int64 otherBytesRead) + { + return FMOD5_System_GetFileUsage(this.handle, out sampleBytesRead, out streamBytesRead, out otherBytesRead); + } + + // Sound/DSP/Channel/FX creation and retrieval. + public RESULT createSound(string name, MODE mode, ref CREATESOUNDEXINFO exinfo, out Sound sound) + { + using (StringHelper.ThreadSafeEncoding encoder = StringHelper.GetFreeHelper()) + { + return FMOD5_System_CreateSound(this.handle, encoder.byteFromStringUTF8(name), mode, ref exinfo, out sound.handle); + } + } + public RESULT createSound(byte[] data, MODE mode, ref CREATESOUNDEXINFO exinfo, out Sound sound) + { + return FMOD5_System_CreateSound(this.handle, data, mode, ref exinfo, out sound.handle); + } + public RESULT createSound(IntPtr name_or_data, MODE mode, ref CREATESOUNDEXINFO exinfo, out Sound sound) + { + return FMOD5_System_CreateSound(this.handle, name_or_data, mode, ref exinfo, out sound.handle); + } + public RESULT createSound(string name, MODE mode, out Sound sound) + { + CREATESOUNDEXINFO exinfo = new CREATESOUNDEXINFO(); + exinfo.cbsize = Marshal.SizeOf(); + + return createSound(name, mode, ref exinfo, out sound); + } + public RESULT createStream(string name, MODE mode, ref CREATESOUNDEXINFO exinfo, out Sound sound) + { + using (StringHelper.ThreadSafeEncoding encoder = StringHelper.GetFreeHelper()) + { + return FMOD5_System_CreateStream(this.handle, encoder.byteFromStringUTF8(name), mode, ref exinfo, out sound.handle); + } + } + public RESULT createStream(byte[] data, MODE mode, ref CREATESOUNDEXINFO exinfo, out Sound sound) + { + return FMOD5_System_CreateStream(this.handle, data, mode, ref exinfo, out sound.handle); + } + public RESULT createStream(IntPtr name_or_data, MODE mode, ref CREATESOUNDEXINFO exinfo, out Sound sound) + { + return FMOD5_System_CreateStream(this.handle, name_or_data, mode, ref exinfo, out sound.handle); + } + public RESULT createStream(string name, MODE mode, out Sound sound) + { + CREATESOUNDEXINFO exinfo = new CREATESOUNDEXINFO(); + exinfo.cbsize = Marshal.SizeOf(); + + return createStream(name, mode, ref exinfo, out sound); + } + public RESULT createDSP(ref DSP_DESCRIPTION description, out DSP dsp) + { + return FMOD5_System_CreateDSP(this.handle, ref description, out dsp.handle); + } + public RESULT createDSPByType(DSP_TYPE type, out DSP dsp) + { + return FMOD5_System_CreateDSPByType(this.handle, type, out dsp.handle); + } + public RESULT createDSPConnection(DSPCONNECTION_TYPE type, out DSPConnection connection) + { + return FMOD5_System_CreateDSPConnection(this.handle, type, out connection.handle); + } + public RESULT createChannelGroup(string name, out ChannelGroup channelgroup) + { + using (StringHelper.ThreadSafeEncoding encoder = StringHelper.GetFreeHelper()) + { + return FMOD5_System_CreateChannelGroup(this.handle, encoder.byteFromStringUTF8(name), out channelgroup.handle); + } + } + public RESULT createSoundGroup(string name, out SoundGroup soundgroup) + { + using (StringHelper.ThreadSafeEncoding encoder = StringHelper.GetFreeHelper()) + { + return FMOD5_System_CreateSoundGroup(this.handle, encoder.byteFromStringUTF8(name), out soundgroup.handle); + } + } + public RESULT createReverb3D(out Reverb3D reverb) + { + return FMOD5_System_CreateReverb3D(this.handle, out reverb.handle); + } + public RESULT playSound(Sound sound, ChannelGroup channelgroup, bool paused, out Channel channel) + { + return FMOD5_System_PlaySound(this.handle, sound.handle, channelgroup.handle, paused, out channel.handle); + } + public RESULT playDSP(DSP dsp, ChannelGroup channelgroup, bool paused, out Channel channel) + { + return FMOD5_System_PlayDSP(this.handle, dsp.handle, channelgroup.handle, paused, out channel.handle); + } + public RESULT getChannel(int channelid, out Channel channel) + { + return FMOD5_System_GetChannel(this.handle, channelid, out channel.handle); + } + public RESULT getDSPInfoByType(DSP_TYPE type, out IntPtr description) + { + return FMOD5_System_GetDSPInfoByType(this.handle, type, out description); + } + public RESULT getMasterChannelGroup(out ChannelGroup channelgroup) + { + return FMOD5_System_GetMasterChannelGroup(this.handle, out channelgroup.handle); + } + public RESULT getMasterSoundGroup(out SoundGroup soundgroup) + { + return FMOD5_System_GetMasterSoundGroup(this.handle, out soundgroup.handle); + } + + // Routing to ports. + public RESULT attachChannelGroupToPort(PORT_TYPE portType, ulong portIndex, ChannelGroup channelgroup, bool passThru = false) + { + return FMOD5_System_AttachChannelGroupToPort(this.handle, portType, portIndex, channelgroup.handle, passThru); + } + public RESULT detachChannelGroupFromPort(ChannelGroup channelgroup) + { + return FMOD5_System_DetachChannelGroupFromPort(this.handle, channelgroup.handle); + } + + // Reverb api. + public RESULT setReverbProperties(int instance, ref REVERB_PROPERTIES prop) + { + return FMOD5_System_SetReverbProperties(this.handle, instance, ref prop); + } + public RESULT getReverbProperties(int instance, out REVERB_PROPERTIES prop) + { + return FMOD5_System_GetReverbProperties(this.handle, instance, out prop); + } + + // System level DSP functionality. + public RESULT lockDSP() + { + return FMOD5_System_LockDSP(this.handle); + } + public RESULT unlockDSP() + { + return FMOD5_System_UnlockDSP(this.handle); + } + + // Recording api + public RESULT getRecordNumDrivers(out int numdrivers, out int numconnected) + { + return FMOD5_System_GetRecordNumDrivers(this.handle, out numdrivers, out numconnected); + } + public RESULT getRecordDriverInfo(int id, out string name, int namelen, out Guid guid, out int systemrate, out SPEAKERMODE speakermode, out int speakermodechannels, out DRIVER_STATE state) + { + IntPtr stringMem = Marshal.AllocHGlobal(namelen); + + RESULT result = FMOD5_System_GetRecordDriverInfo(this.handle, id, stringMem, namelen, out guid, out systemrate, out speakermode, out speakermodechannels, out state); + + using (StringHelper.ThreadSafeEncoding encoder = StringHelper.GetFreeHelper()) + { + name = encoder.stringFromNative(stringMem); + } + Marshal.FreeHGlobal(stringMem); + + return result; + } + public RESULT getRecordDriverInfo(int id, out Guid guid, out int systemrate, out SPEAKERMODE speakermode, out int speakermodechannels, out DRIVER_STATE state) + { + return FMOD5_System_GetRecordDriverInfo(this.handle, id, IntPtr.Zero, 0, out guid, out systemrate, out speakermode, out speakermodechannels, out state); + } + public RESULT getRecordPosition(int id, out uint position) + { + return FMOD5_System_GetRecordPosition(this.handle, id, out position); + } + public RESULT recordStart(int id, Sound sound, bool loop) + { + return FMOD5_System_RecordStart(this.handle, id, sound.handle, loop); + } + public RESULT recordStop(int id) + { + return FMOD5_System_RecordStop(this.handle, id); + } + public RESULT isRecording(int id, out bool recording) + { + return FMOD5_System_IsRecording(this.handle, id, out recording); + } + + // Geometry api + public RESULT createGeometry(int maxpolygons, int maxvertices, out Geometry geometry) + { + return FMOD5_System_CreateGeometry(this.handle, maxpolygons, maxvertices, out geometry.handle); + } + public RESULT setGeometrySettings(float maxworldsize) + { + return FMOD5_System_SetGeometrySettings(this.handle, maxworldsize); + } + public RESULT getGeometrySettings(out float maxworldsize) + { + return FMOD5_System_GetGeometrySettings(this.handle, out maxworldsize); + } + public RESULT loadGeometry(IntPtr data, int datasize, out Geometry geometry) + { + return FMOD5_System_LoadGeometry(this.handle, data, datasize, out geometry.handle); + } + public RESULT getGeometryOcclusion(ref VECTOR listener, ref VECTOR source, out float direct, out float reverb) + { + return FMOD5_System_GetGeometryOcclusion(this.handle, ref listener, ref source, out direct, out reverb); + } + + // Network functions + public RESULT setNetworkProxy(string proxy) + { + using (StringHelper.ThreadSafeEncoding encoder = StringHelper.GetFreeHelper()) + { + return FMOD5_System_SetNetworkProxy(this.handle, encoder.byteFromStringUTF8(proxy)); + } + } + public RESULT getNetworkProxy(out string proxy, int proxylen) + { + IntPtr stringMem = Marshal.AllocHGlobal(proxylen); + + RESULT result = FMOD5_System_GetNetworkProxy(this.handle, stringMem, proxylen); + using (StringHelper.ThreadSafeEncoding encoder = StringHelper.GetFreeHelper()) + { + proxy = encoder.stringFromNative(stringMem); + } + Marshal.FreeHGlobal(stringMem); + + return result; + } + public RESULT setNetworkTimeout(int timeout) + { + return FMOD5_System_SetNetworkTimeout(this.handle, timeout); + } + public RESULT getNetworkTimeout(out int timeout) + { + return FMOD5_System_GetNetworkTimeout(this.handle, out timeout); + } + + // Userdata set/get + public RESULT setUserData(IntPtr userdata) + { + return FMOD5_System_SetUserData(this.handle, userdata); + } + public RESULT getUserData(out IntPtr userdata) + { + return FMOD5_System_GetUserData(this.handle, out userdata); + } + + #region importfunctions + [DllImport(VERSION.dll)] + private static extern RESULT FMOD5_System_Release (IntPtr system); + [DllImport(VERSION.dll)] + private static extern RESULT FMOD5_System_SetOutput (IntPtr system, OUTPUTTYPE output); + [DllImport(VERSION.dll)] + private static extern RESULT FMOD5_System_GetOutput (IntPtr system, out OUTPUTTYPE output); + [DllImport(VERSION.dll)] + private static extern RESULT FMOD5_System_GetNumDrivers (IntPtr system, out int numdrivers); + [DllImport(VERSION.dll)] + private static extern RESULT FMOD5_System_GetDriverInfo (IntPtr system, int id, IntPtr name, int namelen, out Guid guid, out int systemrate, out SPEAKERMODE speakermode, out int speakermodechannels); + [DllImport(VERSION.dll)] + private static extern RESULT FMOD5_System_SetDriver (IntPtr system, int driver); + [DllImport(VERSION.dll)] + private static extern RESULT FMOD5_System_GetDriver (IntPtr system, out int driver); + [DllImport(VERSION.dll)] + private static extern RESULT FMOD5_System_SetSoftwareChannels (IntPtr system, int numsoftwarechannels); + [DllImport(VERSION.dll)] + private static extern RESULT FMOD5_System_GetSoftwareChannels (IntPtr system, out int numsoftwarechannels); + [DllImport(VERSION.dll)] + private static extern RESULT FMOD5_System_SetSoftwareFormat (IntPtr system, int samplerate, SPEAKERMODE speakermode, int numrawspeakers); + [DllImport(VERSION.dll)] + private static extern RESULT FMOD5_System_GetSoftwareFormat (IntPtr system, out int samplerate, out SPEAKERMODE speakermode, out int numrawspeakers); + [DllImport(VERSION.dll)] + private static extern RESULT FMOD5_System_SetDSPBufferSize (IntPtr system, uint bufferlength, int numbuffers); + [DllImport(VERSION.dll)] + private static extern RESULT FMOD5_System_GetDSPBufferSize (IntPtr system, out uint bufferlength, out int numbuffers); + [DllImport(VERSION.dll)] + private static extern RESULT FMOD5_System_SetFileSystem (IntPtr system, FILE_OPEN_CALLBACK useropen, FILE_CLOSE_CALLBACK userclose, FILE_READ_CALLBACK userread, FILE_SEEK_CALLBACK userseek, FILE_ASYNCREAD_CALLBACK userasyncread, FILE_ASYNCCANCEL_CALLBACK userasynccancel, int blockalign); + [DllImport(VERSION.dll)] + private static extern RESULT FMOD5_System_AttachFileSystem (IntPtr system, FILE_OPEN_CALLBACK useropen, FILE_CLOSE_CALLBACK userclose, FILE_READ_CALLBACK userread, FILE_SEEK_CALLBACK userseek); + [DllImport(VERSION.dll)] + private static extern RESULT FMOD5_System_SetAdvancedSettings (IntPtr system, ref ADVANCEDSETTINGS settings); + [DllImport(VERSION.dll)] + private static extern RESULT FMOD5_System_GetAdvancedSettings (IntPtr system, ref ADVANCEDSETTINGS settings); + [DllImport(VERSION.dll)] + private static extern RESULT FMOD5_System_SetCallback (IntPtr system, SYSTEM_CALLBACK callback, SYSTEM_CALLBACK_TYPE callbackmask); + [DllImport(VERSION.dll)] + private static extern RESULT FMOD5_System_SetPluginPath (IntPtr system, byte[] path); + [DllImport(VERSION.dll)] + private static extern RESULT FMOD5_System_LoadPlugin (IntPtr system, byte[] filename, out uint handle, uint priority); + [DllImport(VERSION.dll)] + private static extern RESULT FMOD5_System_UnloadPlugin (IntPtr system, uint handle); + [DllImport(VERSION.dll)] + private static extern RESULT FMOD5_System_GetNumNestedPlugins (IntPtr system, uint handle, out int count); + [DllImport(VERSION.dll)] + private static extern RESULT FMOD5_System_GetNestedPlugin (IntPtr system, uint handle, int index, out uint nestedhandle); + [DllImport(VERSION.dll)] + private static extern RESULT FMOD5_System_GetNumPlugins (IntPtr system, PLUGINTYPE plugintype, out int numplugins); + [DllImport(VERSION.dll)] + private static extern RESULT FMOD5_System_GetPluginHandle (IntPtr system, PLUGINTYPE plugintype, int index, out uint handle); + [DllImport(VERSION.dll)] + private static extern RESULT FMOD5_System_GetPluginInfo (IntPtr system, uint handle, out PLUGINTYPE plugintype, IntPtr name, int namelen, out uint version); + [DllImport(VERSION.dll)] + private static extern RESULT FMOD5_System_SetOutputByPlugin (IntPtr system, uint handle); + [DllImport(VERSION.dll)] + private static extern RESULT FMOD5_System_GetOutputByPlugin (IntPtr system, out uint handle); + [DllImport(VERSION.dll)] + private static extern RESULT FMOD5_System_CreateDSPByPlugin (IntPtr system, uint handle, out IntPtr dsp); + [DllImport(VERSION.dll)] + private static extern RESULT FMOD5_System_GetDSPInfoByPlugin (IntPtr system, uint handle, out IntPtr description); + [DllImport(VERSION.dll)] + private static extern RESULT FMOD5_System_RegisterDSP (IntPtr system, ref DSP_DESCRIPTION description, out uint handle); + [DllImport(VERSION.dll)] + private static extern RESULT FMOD5_System_Init (IntPtr system, int maxchannels, INITFLAGS flags, IntPtr extradriverdata); + [DllImport(VERSION.dll)] + private static extern RESULT FMOD5_System_Close (IntPtr system); + [DllImport(VERSION.dll)] + private static extern RESULT FMOD5_System_Update (IntPtr system); + [DllImport(VERSION.dll)] + private static extern RESULT FMOD5_System_SetSpeakerPosition (IntPtr system, SPEAKER speaker, float x, float y, bool active); + [DllImport(VERSION.dll)] + private static extern RESULT FMOD5_System_GetSpeakerPosition (IntPtr system, SPEAKER speaker, out float x, out float y, out bool active); + [DllImport(VERSION.dll)] + private static extern RESULT FMOD5_System_SetStreamBufferSize (IntPtr system, uint filebuffersize, TIMEUNIT filebuffersizetype); + [DllImport(VERSION.dll)] + private static extern RESULT FMOD5_System_GetStreamBufferSize (IntPtr system, out uint filebuffersize, out TIMEUNIT filebuffersizetype); + [DllImport(VERSION.dll)] + private static extern RESULT FMOD5_System_Set3DSettings (IntPtr system, float dopplerscale, float distancefactor, float rolloffscale); + [DllImport(VERSION.dll)] + private static extern RESULT FMOD5_System_Get3DSettings (IntPtr system, out float dopplerscale, out float distancefactor, out float rolloffscale); + [DllImport(VERSION.dll)] + private static extern RESULT FMOD5_System_Set3DNumListeners (IntPtr system, int numlisteners); + [DllImport(VERSION.dll)] + private static extern RESULT FMOD5_System_Get3DNumListeners (IntPtr system, out int numlisteners); + [DllImport(VERSION.dll)] + private static extern RESULT FMOD5_System_Set3DListenerAttributes (IntPtr system, int listener, ref VECTOR pos, ref VECTOR vel, ref VECTOR forward, ref VECTOR up); + [DllImport(VERSION.dll)] + private static extern RESULT FMOD5_System_Get3DListenerAttributes (IntPtr system, int listener, out VECTOR pos, out VECTOR vel, out VECTOR forward, out VECTOR up); + [DllImport(VERSION.dll)] + private static extern RESULT FMOD5_System_Set3DRolloffCallback (IntPtr system, CB_3D_ROLLOFF_CALLBACK callback); + [DllImport(VERSION.dll)] + private static extern RESULT FMOD5_System_MixerSuspend (IntPtr system); + [DllImport(VERSION.dll)] + private static extern RESULT FMOD5_System_MixerResume (IntPtr system); + [DllImport(VERSION.dll)] + private static extern RESULT FMOD5_System_GetDefaultMixMatrix (IntPtr system, SPEAKERMODE sourcespeakermode, SPEAKERMODE targetspeakermode, float[] matrix, int matrixhop); + [DllImport(VERSION.dll)] + private static extern RESULT FMOD5_System_GetSpeakerModeChannels (IntPtr system, SPEAKERMODE mode, out int channels); + [DllImport(VERSION.dll)] + private static extern RESULT FMOD5_System_GetVersion (IntPtr system, out uint version, out uint buildnumber); + [DllImport(VERSION.dll)] + private static extern RESULT FMOD5_System_GetOutputHandle (IntPtr system, out IntPtr handle); + [DllImport(VERSION.dll)] + private static extern RESULT FMOD5_System_GetChannelsPlaying (IntPtr system, out int channels, IntPtr zero); + [DllImport(VERSION.dll)] + private static extern RESULT FMOD5_System_GetChannelsPlaying (IntPtr system, out int channels, out int realchannels); + [DllImport(VERSION.dll)] + private static extern RESULT FMOD5_System_GetCPUUsage (IntPtr system, out CPU_USAGE usage); + [DllImport(VERSION.dll)] + private static extern RESULT FMOD5_System_GetFileUsage (IntPtr system, out Int64 sampleBytesRead, out Int64 streamBytesRead, out Int64 otherBytesRead); + [DllImport(VERSION.dll)] + private static extern RESULT FMOD5_System_CreateSound (IntPtr system, byte[] name_or_data, MODE mode, ref CREATESOUNDEXINFO exinfo, out IntPtr sound); + [DllImport(VERSION.dll)] + private static extern RESULT FMOD5_System_CreateSound (IntPtr system, IntPtr name_or_data, MODE mode, ref CREATESOUNDEXINFO exinfo, out IntPtr sound); + [DllImport(VERSION.dll)] + private static extern RESULT FMOD5_System_CreateStream (IntPtr system, byte[] name_or_data, MODE mode, ref CREATESOUNDEXINFO exinfo, out IntPtr sound); + [DllImport(VERSION.dll)] + private static extern RESULT FMOD5_System_CreateStream (IntPtr system, IntPtr name_or_data, MODE mode, ref CREATESOUNDEXINFO exinfo, out IntPtr sound); + [DllImport(VERSION.dll)] + private static extern RESULT FMOD5_System_CreateDSP (IntPtr system, ref DSP_DESCRIPTION description, out IntPtr dsp); + [DllImport(VERSION.dll)] + private static extern RESULT FMOD5_System_CreateDSPByType (IntPtr system, DSP_TYPE type, out IntPtr dsp); + [DllImport(VERSION.dll)] + private static extern RESULT FMOD5_System_CreateDSPConnection (IntPtr system, DSPCONNECTION_TYPE type, out IntPtr connection); + [DllImport(VERSION.dll)] + private static extern RESULT FMOD5_System_CreateChannelGroup (IntPtr system, byte[] name, out IntPtr channelgroup); + [DllImport(VERSION.dll)] + private static extern RESULT FMOD5_System_CreateSoundGroup (IntPtr system, byte[] name, out IntPtr soundgroup); + [DllImport(VERSION.dll)] + private static extern RESULT FMOD5_System_CreateReverb3D (IntPtr system, out IntPtr reverb); + [DllImport(VERSION.dll)] + private static extern RESULT FMOD5_System_PlaySound (IntPtr system, IntPtr sound, IntPtr channelgroup, bool paused, out IntPtr channel); + [DllImport(VERSION.dll)] + private static extern RESULT FMOD5_System_PlayDSP (IntPtr system, IntPtr dsp, IntPtr channelgroup, bool paused, out IntPtr channel); + [DllImport(VERSION.dll)] + private static extern RESULT FMOD5_System_GetChannel (IntPtr system, int channelid, out IntPtr channel); + [DllImport(VERSION.dll)] + private static extern RESULT FMOD5_System_GetDSPInfoByType (IntPtr system, DSP_TYPE type, out IntPtr description); + [DllImport(VERSION.dll)] + private static extern RESULT FMOD5_System_GetMasterChannelGroup (IntPtr system, out IntPtr channelgroup); + [DllImport(VERSION.dll)] + private static extern RESULT FMOD5_System_GetMasterSoundGroup (IntPtr system, out IntPtr soundgroup); + [DllImport(VERSION.dll)] + private static extern RESULT FMOD5_System_AttachChannelGroupToPort (IntPtr system, PORT_TYPE portType, ulong portIndex, IntPtr channelgroup, bool passThru); + [DllImport(VERSION.dll)] + private static extern RESULT FMOD5_System_DetachChannelGroupFromPort(IntPtr system, IntPtr channelgroup); + [DllImport(VERSION.dll)] + private static extern RESULT FMOD5_System_SetReverbProperties (IntPtr system, int instance, ref REVERB_PROPERTIES prop); + [DllImport(VERSION.dll)] + private static extern RESULT FMOD5_System_GetReverbProperties (IntPtr system, int instance, out REVERB_PROPERTIES prop); + [DllImport(VERSION.dll)] + private static extern RESULT FMOD5_System_LockDSP (IntPtr system); + [DllImport(VERSION.dll)] + private static extern RESULT FMOD5_System_UnlockDSP (IntPtr system); + [DllImport(VERSION.dll)] + private static extern RESULT FMOD5_System_GetRecordNumDrivers (IntPtr system, out int numdrivers, out int numconnected); + [DllImport(VERSION.dll)] + private static extern RESULT FMOD5_System_GetRecordDriverInfo (IntPtr system, int id, IntPtr name, int namelen, out Guid guid, out int systemrate, out SPEAKERMODE speakermode, out int speakermodechannels, out DRIVER_STATE state); + [DllImport(VERSION.dll)] + private static extern RESULT FMOD5_System_GetRecordPosition (IntPtr system, int id, out uint position); + [DllImport(VERSION.dll)] + private static extern RESULT FMOD5_System_RecordStart (IntPtr system, int id, IntPtr sound, bool loop); + [DllImport(VERSION.dll)] + private static extern RESULT FMOD5_System_RecordStop (IntPtr system, int id); + [DllImport(VERSION.dll)] + private static extern RESULT FMOD5_System_IsRecording (IntPtr system, int id, out bool recording); + [DllImport(VERSION.dll)] + private static extern RESULT FMOD5_System_CreateGeometry (IntPtr system, int maxpolygons, int maxvertices, out IntPtr geometry); + [DllImport(VERSION.dll)] + private static extern RESULT FMOD5_System_SetGeometrySettings (IntPtr system, float maxworldsize); + [DllImport(VERSION.dll)] + private static extern RESULT FMOD5_System_GetGeometrySettings (IntPtr system, out float maxworldsize); + [DllImport(VERSION.dll)] + private static extern RESULT FMOD5_System_LoadGeometry (IntPtr system, IntPtr data, int datasize, out IntPtr geometry); + [DllImport(VERSION.dll)] + private static extern RESULT FMOD5_System_GetGeometryOcclusion (IntPtr system, ref VECTOR listener, ref VECTOR source, out float direct, out float reverb); + [DllImport(VERSION.dll)] + private static extern RESULT FMOD5_System_SetNetworkProxy (IntPtr system, byte[] proxy); + [DllImport(VERSION.dll)] + private static extern RESULT FMOD5_System_GetNetworkProxy (IntPtr system, IntPtr proxy, int proxylen); + [DllImport(VERSION.dll)] + private static extern RESULT FMOD5_System_SetNetworkTimeout (IntPtr system, int timeout); + [DllImport(VERSION.dll)] + private static extern RESULT FMOD5_System_GetNetworkTimeout (IntPtr system, out int timeout); + [DllImport(VERSION.dll)] + private static extern RESULT FMOD5_System_SetUserData (IntPtr system, IntPtr userdata); + [DllImport(VERSION.dll)] + private static extern RESULT FMOD5_System_GetUserData (IntPtr system, out IntPtr userdata); + #endregion + + #region wrapperinternal + + public IntPtr handle; + + public System(IntPtr ptr) { this.handle = ptr; } + public bool hasHandle() { return this.handle != IntPtr.Zero; } + public void clearHandle() { this.handle = IntPtr.Zero; } + + #endregion + } + + + /* + 'Sound' API. + */ + public struct Sound + { + public RESULT release() + { + return FMOD5_Sound_Release(this.handle); + } + public RESULT getSystemObject(out System system) + { + return FMOD5_Sound_GetSystemObject(this.handle, out system.handle); + } + + // Standard sound manipulation functions. + public RESULT @lock(uint offset, uint length, out IntPtr ptr1, out IntPtr ptr2, out uint len1, out uint len2) + { + return FMOD5_Sound_Lock(this.handle, offset, length, out ptr1, out ptr2, out len1, out len2); + } + public RESULT unlock(IntPtr ptr1, IntPtr ptr2, uint len1, uint len2) + { + return FMOD5_Sound_Unlock(this.handle, ptr1, ptr2, len1, len2); + } + public RESULT setDefaults(float frequency, int priority) + { + return FMOD5_Sound_SetDefaults(this.handle, frequency, priority); + } + public RESULT getDefaults(out float frequency, out int priority) + { + return FMOD5_Sound_GetDefaults(this.handle, out frequency, out priority); + } + public RESULT set3DMinMaxDistance(float min, float max) + { + return FMOD5_Sound_Set3DMinMaxDistance(this.handle, min, max); + } + public RESULT get3DMinMaxDistance(out float min, out float max) + { + return FMOD5_Sound_Get3DMinMaxDistance(this.handle, out min, out max); + } + public RESULT set3DConeSettings(float insideconeangle, float outsideconeangle, float outsidevolume) + { + return FMOD5_Sound_Set3DConeSettings(this.handle, insideconeangle, outsideconeangle, outsidevolume); + } + public RESULT get3DConeSettings(out float insideconeangle, out float outsideconeangle, out float outsidevolume) + { + return FMOD5_Sound_Get3DConeSettings(this.handle, out insideconeangle, out outsideconeangle, out outsidevolume); + } + public RESULT set3DCustomRolloff(ref VECTOR points, int numpoints) + { + return FMOD5_Sound_Set3DCustomRolloff(this.handle, ref points, numpoints); + } + public RESULT get3DCustomRolloff(out IntPtr points, out int numpoints) + { + return FMOD5_Sound_Get3DCustomRolloff(this.handle, out points, out numpoints); + } + + public RESULT getSubSound(int index, out Sound subsound) + { + return FMOD5_Sound_GetSubSound(this.handle, index, out subsound.handle); + } + public RESULT getSubSoundParent(out Sound parentsound) + { + return FMOD5_Sound_GetSubSoundParent(this.handle, out parentsound.handle); + } + public RESULT getName(out string name, int namelen) + { + IntPtr stringMem = Marshal.AllocHGlobal(namelen); + + RESULT result = FMOD5_Sound_GetName(this.handle, stringMem, namelen); + using (StringHelper.ThreadSafeEncoding encoder = StringHelper.GetFreeHelper()) + { + name = encoder.stringFromNative(stringMem); + } + Marshal.FreeHGlobal(stringMem); + + return result; + } + public RESULT getLength(out uint length, TIMEUNIT lengthtype) + { + return FMOD5_Sound_GetLength(this.handle, out length, lengthtype); + } + public RESULT getFormat(out SOUND_TYPE type, out SOUND_FORMAT format, out int channels, out int bits) + { + return FMOD5_Sound_GetFormat(this.handle, out type, out format, out channels, out bits); + } + public RESULT getNumSubSounds(out int numsubsounds) + { + return FMOD5_Sound_GetNumSubSounds(this.handle, out numsubsounds); + } + public RESULT getNumTags(out int numtags, out int numtagsupdated) + { + return FMOD5_Sound_GetNumTags(this.handle, out numtags, out numtagsupdated); + } + public RESULT getTag(string name, int index, out TAG tag) + { + using (StringHelper.ThreadSafeEncoding encoder = StringHelper.GetFreeHelper()) + { + return FMOD5_Sound_GetTag(this.handle, encoder.byteFromStringUTF8(name), index, out tag); + } + } + public RESULT getOpenState(out OPENSTATE openstate, out uint percentbuffered, out bool starving, out bool diskbusy) + { + return FMOD5_Sound_GetOpenState(this.handle, out openstate, out percentbuffered, out starving, out diskbusy); + } + public RESULT readData(byte[] buffer) + { + return FMOD5_Sound_ReadData(this.handle, buffer, (uint)buffer.Length, IntPtr.Zero); + } + public RESULT readData(byte[] buffer, out uint read) + { + return FMOD5_Sound_ReadData(this.handle, buffer, (uint)buffer.Length, out read); + } + public RESULT seekData(uint pcm) + { + return FMOD5_Sound_SeekData(this.handle, pcm); + } + public RESULT setSoundGroup(SoundGroup soundgroup) + { + return FMOD5_Sound_SetSoundGroup(this.handle, soundgroup.handle); + } + public RESULT getSoundGroup(out SoundGroup soundgroup) + { + return FMOD5_Sound_GetSoundGroup(this.handle, out soundgroup.handle); + } + + // Synchronization point API. These points can come from markers embedded in wav files, and can also generate channel callbacks. + public RESULT getNumSyncPoints(out int numsyncpoints) + { + return FMOD5_Sound_GetNumSyncPoints(this.handle, out numsyncpoints); + } + public RESULT getSyncPoint(int index, out IntPtr point) + { + return FMOD5_Sound_GetSyncPoint(this.handle, index, out point); + } + public RESULT getSyncPointInfo(IntPtr point, out string name, int namelen, out uint offset, TIMEUNIT offsettype) + { + IntPtr stringMem = Marshal.AllocHGlobal(namelen); + + RESULT result = FMOD5_Sound_GetSyncPointInfo(this.handle, point, stringMem, namelen, out offset, offsettype); + using (StringHelper.ThreadSafeEncoding encoder = StringHelper.GetFreeHelper()) + { + name = encoder.stringFromNative(stringMem); + } + Marshal.FreeHGlobal(stringMem); + + return result; + } + public RESULT getSyncPointInfo(IntPtr point, out uint offset, TIMEUNIT offsettype) + { + return FMOD5_Sound_GetSyncPointInfo(this.handle, point, IntPtr.Zero, 0, out offset, offsettype); + } + public RESULT addSyncPoint(uint offset, TIMEUNIT offsettype, string name, out IntPtr point) + { + using (StringHelper.ThreadSafeEncoding encoder = StringHelper.GetFreeHelper()) + { + return FMOD5_Sound_AddSyncPoint(this.handle, offset, offsettype, encoder.byteFromStringUTF8(name), out point); + } + } + public RESULT deleteSyncPoint(IntPtr point) + { + return FMOD5_Sound_DeleteSyncPoint(this.handle, point); + } + + // Functions also in Channel class but here they are the 'default' to save having to change it in Channel all the time. + public RESULT setMode(MODE mode) + { + return FMOD5_Sound_SetMode(this.handle, mode); + } + public RESULT getMode(out MODE mode) + { + return FMOD5_Sound_GetMode(this.handle, out mode); + } + public RESULT setLoopCount(int loopcount) + { + return FMOD5_Sound_SetLoopCount(this.handle, loopcount); + } + public RESULT getLoopCount(out int loopcount) + { + return FMOD5_Sound_GetLoopCount(this.handle, out loopcount); + } + public RESULT setLoopPoints(uint loopstart, TIMEUNIT loopstarttype, uint loopend, TIMEUNIT loopendtype) + { + return FMOD5_Sound_SetLoopPoints(this.handle, loopstart, loopstarttype, loopend, loopendtype); + } + public RESULT getLoopPoints(out uint loopstart, TIMEUNIT loopstarttype, out uint loopend, TIMEUNIT loopendtype) + { + return FMOD5_Sound_GetLoopPoints(this.handle, out loopstart, loopstarttype, out loopend, loopendtype); + } + + // For MOD/S3M/XM/IT/MID sequenced formats only. + public RESULT getMusicNumChannels(out int numchannels) + { + return FMOD5_Sound_GetMusicNumChannels(this.handle, out numchannels); + } + public RESULT setMusicChannelVolume(int channel, float volume) + { + return FMOD5_Sound_SetMusicChannelVolume(this.handle, channel, volume); + } + public RESULT getMusicChannelVolume(int channel, out float volume) + { + return FMOD5_Sound_GetMusicChannelVolume(this.handle, channel, out volume); + } + public RESULT setMusicSpeed(float speed) + { + return FMOD5_Sound_SetMusicSpeed(this.handle, speed); + } + public RESULT getMusicSpeed(out float speed) + { + return FMOD5_Sound_GetMusicSpeed(this.handle, out speed); + } + + // Userdata set/get. + public RESULT setUserData(IntPtr userdata) + { + return FMOD5_Sound_SetUserData(this.handle, userdata); + } + public RESULT getUserData(out IntPtr userdata) + { + return FMOD5_Sound_GetUserData(this.handle, out userdata); + } + + #region importfunctions + [DllImport(VERSION.dll)] + private static extern RESULT FMOD5_Sound_Release (IntPtr sound); + [DllImport(VERSION.dll)] + private static extern RESULT FMOD5_Sound_GetSystemObject (IntPtr sound, out IntPtr system); + [DllImport(VERSION.dll)] + private static extern RESULT FMOD5_Sound_Lock (IntPtr sound, uint offset, uint length, out IntPtr ptr1, out IntPtr ptr2, out uint len1, out uint len2); + [DllImport(VERSION.dll)] + private static extern RESULT FMOD5_Sound_Unlock (IntPtr sound, IntPtr ptr1, IntPtr ptr2, uint len1, uint len2); + [DllImport(VERSION.dll)] + private static extern RESULT FMOD5_Sound_SetDefaults (IntPtr sound, float frequency, int priority); + [DllImport(VERSION.dll)] + private static extern RESULT FMOD5_Sound_GetDefaults (IntPtr sound, out float frequency, out int priority); + [DllImport(VERSION.dll)] + private static extern RESULT FMOD5_Sound_Set3DMinMaxDistance (IntPtr sound, float min, float max); + [DllImport(VERSION.dll)] + private static extern RESULT FMOD5_Sound_Get3DMinMaxDistance (IntPtr sound, out float min, out float max); + [DllImport(VERSION.dll)] + private static extern RESULT FMOD5_Sound_Set3DConeSettings (IntPtr sound, float insideconeangle, float outsideconeangle, float outsidevolume); + [DllImport(VERSION.dll)] + private static extern RESULT FMOD5_Sound_Get3DConeSettings (IntPtr sound, out float insideconeangle, out float outsideconeangle, out float outsidevolume); + [DllImport(VERSION.dll)] + private static extern RESULT FMOD5_Sound_Set3DCustomRolloff (IntPtr sound, ref VECTOR points, int numpoints); + [DllImport(VERSION.dll)] + private static extern RESULT FMOD5_Sound_Get3DCustomRolloff (IntPtr sound, out IntPtr points, out int numpoints); + [DllImport(VERSION.dll)] + private static extern RESULT FMOD5_Sound_GetSubSound (IntPtr sound, int index, out IntPtr subsound); + [DllImport(VERSION.dll)] + private static extern RESULT FMOD5_Sound_GetSubSoundParent (IntPtr sound, out IntPtr parentsound); + [DllImport(VERSION.dll)] + private static extern RESULT FMOD5_Sound_GetName (IntPtr sound, IntPtr name, int namelen); + [DllImport(VERSION.dll)] + private static extern RESULT FMOD5_Sound_GetLength (IntPtr sound, out uint length, TIMEUNIT lengthtype); + [DllImport(VERSION.dll)] + private static extern RESULT FMOD5_Sound_GetFormat (IntPtr sound, out SOUND_TYPE type, out SOUND_FORMAT format, out int channels, out int bits); + [DllImport(VERSION.dll)] + private static extern RESULT FMOD5_Sound_GetNumSubSounds (IntPtr sound, out int numsubsounds); + [DllImport(VERSION.dll)] + private static extern RESULT FMOD5_Sound_GetNumTags (IntPtr sound, out int numtags, out int numtagsupdated); + [DllImport(VERSION.dll)] + private static extern RESULT FMOD5_Sound_GetTag (IntPtr sound, byte[] name, int index, out TAG tag); + [DllImport(VERSION.dll)] + private static extern RESULT FMOD5_Sound_GetOpenState (IntPtr sound, out OPENSTATE openstate, out uint percentbuffered, out bool starving, out bool diskbusy); + [DllImport(VERSION.dll)] + private static extern RESULT FMOD5_Sound_ReadData (IntPtr sound, byte[] buffer, uint length, IntPtr zero); + [DllImport(VERSION.dll)] + private static extern RESULT FMOD5_Sound_ReadData (IntPtr sound, byte[] buffer, uint length, out uint read); + [DllImport(VERSION.dll)] + private static extern RESULT FMOD5_Sound_SeekData (IntPtr sound, uint pcm); + [DllImport(VERSION.dll)] + private static extern RESULT FMOD5_Sound_SetSoundGroup (IntPtr sound, IntPtr soundgroup); + [DllImport(VERSION.dll)] + private static extern RESULT FMOD5_Sound_GetSoundGroup (IntPtr sound, out IntPtr soundgroup); + [DllImport(VERSION.dll)] + private static extern RESULT FMOD5_Sound_GetNumSyncPoints (IntPtr sound, out int numsyncpoints); + [DllImport(VERSION.dll)] + private static extern RESULT FMOD5_Sound_GetSyncPoint (IntPtr sound, int index, out IntPtr point); + [DllImport(VERSION.dll)] + private static extern RESULT FMOD5_Sound_GetSyncPointInfo (IntPtr sound, IntPtr point, IntPtr name, int namelen, out uint offset, TIMEUNIT offsettype); + [DllImport(VERSION.dll)] + private static extern RESULT FMOD5_Sound_AddSyncPoint (IntPtr sound, uint offset, TIMEUNIT offsettype, byte[] name, out IntPtr point); + [DllImport(VERSION.dll)] + private static extern RESULT FMOD5_Sound_DeleteSyncPoint (IntPtr sound, IntPtr point); + [DllImport(VERSION.dll)] + private static extern RESULT FMOD5_Sound_SetMode (IntPtr sound, MODE mode); + [DllImport(VERSION.dll)] + private static extern RESULT FMOD5_Sound_GetMode (IntPtr sound, out MODE mode); + [DllImport(VERSION.dll)] + private static extern RESULT FMOD5_Sound_SetLoopCount (IntPtr sound, int loopcount); + [DllImport(VERSION.dll)] + private static extern RESULT FMOD5_Sound_GetLoopCount (IntPtr sound, out int loopcount); + [DllImport(VERSION.dll)] + private static extern RESULT FMOD5_Sound_SetLoopPoints (IntPtr sound, uint loopstart, TIMEUNIT loopstarttype, uint loopend, TIMEUNIT loopendtype); + [DllImport(VERSION.dll)] + private static extern RESULT FMOD5_Sound_GetLoopPoints (IntPtr sound, out uint loopstart, TIMEUNIT loopstarttype, out uint loopend, TIMEUNIT loopendtype); + [DllImport(VERSION.dll)] + private static extern RESULT FMOD5_Sound_GetMusicNumChannels (IntPtr sound, out int numchannels); + [DllImport(VERSION.dll)] + private static extern RESULT FMOD5_Sound_SetMusicChannelVolume (IntPtr sound, int channel, float volume); + [DllImport(VERSION.dll)] + private static extern RESULT FMOD5_Sound_GetMusicChannelVolume (IntPtr sound, int channel, out float volume); + [DllImport(VERSION.dll)] + private static extern RESULT FMOD5_Sound_SetMusicSpeed (IntPtr sound, float speed); + [DllImport(VERSION.dll)] + private static extern RESULT FMOD5_Sound_GetMusicSpeed (IntPtr sound, out float speed); + [DllImport(VERSION.dll)] + private static extern RESULT FMOD5_Sound_SetUserData (IntPtr sound, IntPtr userdata); + [DllImport(VERSION.dll)] + private static extern RESULT FMOD5_Sound_GetUserData (IntPtr sound, out IntPtr userdata); + #endregion + + #region wrapperinternal + + public IntPtr handle; + + public Sound(IntPtr ptr) { this.handle = ptr; } + public bool hasHandle() { return this.handle != IntPtr.Zero; } + public void clearHandle() { this.handle = IntPtr.Zero; } + + #endregion + } + + /* + 'ChannelControl' API + */ + interface IChannelControl + { + RESULT getSystemObject (out System system); + + // General control functionality for Channels and ChannelGroups. + RESULT stop (); + RESULT setPaused (bool paused); + RESULT getPaused (out bool paused); + RESULT setVolume (float volume); + RESULT getVolume (out float volume); + RESULT setVolumeRamp (bool ramp); + RESULT getVolumeRamp (out bool ramp); + RESULT getAudibility (out float audibility); + RESULT setPitch (float pitch); + RESULT getPitch (out float pitch); + RESULT setMute (bool mute); + RESULT getMute (out bool mute); + RESULT setReverbProperties (int instance, float wet); + RESULT getReverbProperties (int instance, out float wet); + RESULT setLowPassGain (float gain); + RESULT getLowPassGain (out float gain); + RESULT setMode (MODE mode); + RESULT getMode (out MODE mode); + RESULT setCallback (CHANNELCONTROL_CALLBACK callback); + RESULT isPlaying (out bool isplaying); + + // Note all 'set' functions alter a final matrix, this is why the only get function is getMixMatrix, to avoid other get functions returning incorrect/obsolete values. + RESULT setPan (float pan); + RESULT setMixLevelsOutput (float frontleft, float frontright, float center, float lfe, float surroundleft, float surroundright, float backleft, float backright); + RESULT setMixLevelsInput (float[] levels, int numlevels); + RESULT setMixMatrix (float[] matrix, int outchannels, int inchannels, int inchannel_hop); + RESULT getMixMatrix (float[] matrix, out int outchannels, out int inchannels, int inchannel_hop); + + // Clock based functionality. + RESULT getDSPClock (out ulong dspclock, out ulong parentclock); + RESULT setDelay (ulong dspclock_start, ulong dspclock_end, bool stopchannels); + RESULT getDelay (out ulong dspclock_start, out ulong dspclock_end); + RESULT getDelay (out ulong dspclock_start, out ulong dspclock_end, out bool stopchannels); + RESULT addFadePoint (ulong dspclock, float volume); + RESULT setFadePointRamp (ulong dspclock, float volume); + RESULT removeFadePoints (ulong dspclock_start, ulong dspclock_end); + RESULT getFadePoints (ref uint numpoints, ulong[] point_dspclock, float[] point_volume); + + // DSP effects. + RESULT getDSP (int index, out DSP dsp); + RESULT addDSP (int index, DSP dsp); + RESULT removeDSP (DSP dsp); + RESULT getNumDSPs (out int numdsps); + RESULT setDSPIndex (DSP dsp, int index); + RESULT getDSPIndex (DSP dsp, out int index); + + // 3D functionality. + RESULT set3DAttributes (ref VECTOR pos, ref VECTOR vel); + RESULT get3DAttributes (out VECTOR pos, out VECTOR vel); + RESULT set3DMinMaxDistance (float mindistance, float maxdistance); + RESULT get3DMinMaxDistance (out float mindistance, out float maxdistance); + RESULT set3DConeSettings (float insideconeangle, float outsideconeangle, float outsidevolume); + RESULT get3DConeSettings (out float insideconeangle, out float outsideconeangle, out float outsidevolume); + RESULT set3DConeOrientation (ref VECTOR orientation); + RESULT get3DConeOrientation (out VECTOR orientation); + RESULT set3DCustomRolloff (ref VECTOR points, int numpoints); + RESULT get3DCustomRolloff (out IntPtr points, out int numpoints); + RESULT set3DOcclusion (float directocclusion, float reverbocclusion); + RESULT get3DOcclusion (out float directocclusion, out float reverbocclusion); + RESULT set3DSpread (float angle); + RESULT get3DSpread (out float angle); + RESULT set3DLevel (float level); + RESULT get3DLevel (out float level); + RESULT set3DDopplerLevel (float level); + RESULT get3DDopplerLevel (out float level); + RESULT set3DDistanceFilter (bool custom, float customLevel, float centerFreq); + RESULT get3DDistanceFilter (out bool custom, out float customLevel, out float centerFreq); + + // Userdata set/get. + RESULT setUserData (IntPtr userdata); + RESULT getUserData (out IntPtr userdata); + } + + /* + 'Channel' API + */ + public struct Channel : IChannelControl + { + // Channel specific control functionality. + public RESULT setFrequency(float frequency) + { + return FMOD5_Channel_SetFrequency(this.handle, frequency); + } + public RESULT getFrequency(out float frequency) + { + return FMOD5_Channel_GetFrequency(this.handle, out frequency); + } + public RESULT setPriority(int priority) + { + return FMOD5_Channel_SetPriority(this.handle, priority); + } + public RESULT getPriority(out int priority) + { + return FMOD5_Channel_GetPriority(this.handle, out priority); + } + public RESULT setPosition(uint position, TIMEUNIT postype) + { + return FMOD5_Channel_SetPosition(this.handle, position, postype); + } + public RESULT getPosition(out uint position, TIMEUNIT postype) + { + return FMOD5_Channel_GetPosition(this.handle, out position, postype); + } + public RESULT setChannelGroup(ChannelGroup channelgroup) + { + return FMOD5_Channel_SetChannelGroup(this.handle, channelgroup.handle); + } + public RESULT getChannelGroup(out ChannelGroup channelgroup) + { + return FMOD5_Channel_GetChannelGroup(this.handle, out channelgroup.handle); + } + public RESULT setLoopCount(int loopcount) + { + return FMOD5_Channel_SetLoopCount(this.handle, loopcount); + } + public RESULT getLoopCount(out int loopcount) + { + return FMOD5_Channel_GetLoopCount(this.handle, out loopcount); + } + public RESULT setLoopPoints(uint loopstart, TIMEUNIT loopstarttype, uint loopend, TIMEUNIT loopendtype) + { + return FMOD5_Channel_SetLoopPoints(this.handle, loopstart, loopstarttype, loopend, loopendtype); + } + public RESULT getLoopPoints(out uint loopstart, TIMEUNIT loopstarttype, out uint loopend, TIMEUNIT loopendtype) + { + return FMOD5_Channel_GetLoopPoints(this.handle, out loopstart, loopstarttype, out loopend, loopendtype); + } + + // Information only functions. + public RESULT isVirtual(out bool isvirtual) + { + return FMOD5_Channel_IsVirtual(this.handle, out isvirtual); + } + public RESULT getCurrentSound(out Sound sound) + { + return FMOD5_Channel_GetCurrentSound(this.handle, out sound.handle); + } + public RESULT getIndex(out int index) + { + return FMOD5_Channel_GetIndex(this.handle, out index); + } + + public RESULT getSystemObject(out System system) + { + return FMOD5_Channel_GetSystemObject(this.handle, out system.handle); + } + + // General control functionality for Channels and ChannelGroups. + public RESULT stop() + { + return FMOD5_Channel_Stop(this.handle); + } + public RESULT setPaused(bool paused) + { + return FMOD5_Channel_SetPaused(this.handle, paused); + } + public RESULT getPaused(out bool paused) + { + return FMOD5_Channel_GetPaused(this.handle, out paused); + } + public RESULT setVolume(float volume) + { + return FMOD5_Channel_SetVolume(this.handle, volume); + } + public RESULT getVolume(out float volume) + { + return FMOD5_Channel_GetVolume(this.handle, out volume); + } + public RESULT setVolumeRamp(bool ramp) + { + return FMOD5_Channel_SetVolumeRamp(this.handle, ramp); + } + public RESULT getVolumeRamp(out bool ramp) + { + return FMOD5_Channel_GetVolumeRamp(this.handle, out ramp); + } + public RESULT getAudibility(out float audibility) + { + return FMOD5_Channel_GetAudibility(this.handle, out audibility); + } + public RESULT setPitch(float pitch) + { + return FMOD5_Channel_SetPitch(this.handle, pitch); + } + public RESULT getPitch(out float pitch) + { + return FMOD5_Channel_GetPitch(this.handle, out pitch); + } + public RESULT setMute(bool mute) + { + return FMOD5_Channel_SetMute(this.handle, mute); + } + public RESULT getMute(out bool mute) + { + return FMOD5_Channel_GetMute(this.handle, out mute); + } + public RESULT setReverbProperties(int instance, float wet) + { + return FMOD5_Channel_SetReverbProperties(this.handle, instance, wet); + } + public RESULT getReverbProperties(int instance, out float wet) + { + return FMOD5_Channel_GetReverbProperties(this.handle, instance, out wet); + } + public RESULT setLowPassGain(float gain) + { + return FMOD5_Channel_SetLowPassGain(this.handle, gain); + } + public RESULT getLowPassGain(out float gain) + { + return FMOD5_Channel_GetLowPassGain(this.handle, out gain); + } + public RESULT setMode(MODE mode) + { + return FMOD5_Channel_SetMode(this.handle, mode); + } + public RESULT getMode(out MODE mode) + { + return FMOD5_Channel_GetMode(this.handle, out mode); + } + public RESULT setCallback(CHANNELCONTROL_CALLBACK callback) + { + return FMOD5_Channel_SetCallback(this.handle, callback); + } + public RESULT isPlaying(out bool isplaying) + { + return FMOD5_Channel_IsPlaying(this.handle, out isplaying); + } + + // Note all 'set' functions alter a final matrix, this is why the only get function is getMixMatrix, to avoid other get functions returning incorrect/obsolete values. + public RESULT setPan(float pan) + { + return FMOD5_Channel_SetPan(this.handle, pan); + } + public RESULT setMixLevelsOutput(float frontleft, float frontright, float center, float lfe, float surroundleft, float surroundright, float backleft, float backright) + { + return FMOD5_Channel_SetMixLevelsOutput(this.handle, frontleft, frontright, center, lfe, surroundleft, surroundright, backleft, backright); + } + public RESULT setMixLevelsInput(float[] levels, int numlevels) + { + return FMOD5_Channel_SetMixLevelsInput(this.handle, levels, numlevels); + } + public RESULT setMixMatrix(float[] matrix, int outchannels, int inchannels, int inchannel_hop = 0) + { + return FMOD5_Channel_SetMixMatrix(this.handle, matrix, outchannels, inchannels, inchannel_hop); + } + public RESULT getMixMatrix(float[] matrix, out int outchannels, out int inchannels, int inchannel_hop = 0) + { + return FMOD5_Channel_GetMixMatrix(this.handle, matrix, out outchannels, out inchannels, inchannel_hop); + } + + // Clock based functionality. + public RESULT getDSPClock(out ulong dspclock, out ulong parentclock) + { + return FMOD5_Channel_GetDSPClock(this.handle, out dspclock, out parentclock); + } + public RESULT setDelay(ulong dspclock_start, ulong dspclock_end, bool stopchannels = true) + { + return FMOD5_Channel_SetDelay(this.handle, dspclock_start, dspclock_end, stopchannels); + } + public RESULT getDelay(out ulong dspclock_start, out ulong dspclock_end) + { + return FMOD5_Channel_GetDelay(this.handle, out dspclock_start, out dspclock_end, IntPtr.Zero); + } + public RESULT getDelay(out ulong dspclock_start, out ulong dspclock_end, out bool stopchannels) + { + return FMOD5_Channel_GetDelay(this.handle, out dspclock_start, out dspclock_end, out stopchannels); + } + public RESULT addFadePoint(ulong dspclock, float volume) + { + return FMOD5_Channel_AddFadePoint(this.handle, dspclock, volume); + } + public RESULT setFadePointRamp(ulong dspclock, float volume) + { + return FMOD5_Channel_SetFadePointRamp(this.handle, dspclock, volume); + } + public RESULT removeFadePoints(ulong dspclock_start, ulong dspclock_end) + { + return FMOD5_Channel_RemoveFadePoints(this.handle, dspclock_start, dspclock_end); + } + public RESULT getFadePoints(ref uint numpoints, ulong[] point_dspclock, float[] point_volume) + { + return FMOD5_Channel_GetFadePoints(this.handle, ref numpoints, point_dspclock, point_volume); + } + + // DSP effects. + public RESULT getDSP(int index, out DSP dsp) + { + return FMOD5_Channel_GetDSP(this.handle, index, out dsp.handle); + } + public RESULT addDSP(int index, DSP dsp) + { + return FMOD5_Channel_AddDSP(this.handle, index, dsp.handle); + } + public RESULT removeDSP(DSP dsp) + { + return FMOD5_Channel_RemoveDSP(this.handle, dsp.handle); + } + public RESULT getNumDSPs(out int numdsps) + { + return FMOD5_Channel_GetNumDSPs(this.handle, out numdsps); + } + public RESULT setDSPIndex(DSP dsp, int index) + { + return FMOD5_Channel_SetDSPIndex(this.handle, dsp.handle, index); + } + public RESULT getDSPIndex(DSP dsp, out int index) + { + return FMOD5_Channel_GetDSPIndex(this.handle, dsp.handle, out index); + } + + // 3D functionality. + public RESULT set3DAttributes(ref VECTOR pos, ref VECTOR vel) + { + return FMOD5_Channel_Set3DAttributes(this.handle, ref pos, ref vel); + } + public RESULT get3DAttributes(out VECTOR pos, out VECTOR vel) + { + return FMOD5_Channel_Get3DAttributes(this.handle, out pos, out vel); + } + public RESULT set3DMinMaxDistance(float mindistance, float maxdistance) + { + return FMOD5_Channel_Set3DMinMaxDistance(this.handle, mindistance, maxdistance); + } + public RESULT get3DMinMaxDistance(out float mindistance, out float maxdistance) + { + return FMOD5_Channel_Get3DMinMaxDistance(this.handle, out mindistance, out maxdistance); + } + public RESULT set3DConeSettings(float insideconeangle, float outsideconeangle, float outsidevolume) + { + return FMOD5_Channel_Set3DConeSettings(this.handle, insideconeangle, outsideconeangle, outsidevolume); + } + public RESULT get3DConeSettings(out float insideconeangle, out float outsideconeangle, out float outsidevolume) + { + return FMOD5_Channel_Get3DConeSettings(this.handle, out insideconeangle, out outsideconeangle, out outsidevolume); + } + public RESULT set3DConeOrientation(ref VECTOR orientation) + { + return FMOD5_Channel_Set3DConeOrientation(this.handle, ref orientation); + } + public RESULT get3DConeOrientation(out VECTOR orientation) + { + return FMOD5_Channel_Get3DConeOrientation(this.handle, out orientation); + } + public RESULT set3DCustomRolloff(ref VECTOR points, int numpoints) + { + return FMOD5_Channel_Set3DCustomRolloff(this.handle, ref points, numpoints); + } + public RESULT get3DCustomRolloff(out IntPtr points, out int numpoints) + { + return FMOD5_Channel_Get3DCustomRolloff(this.handle, out points, out numpoints); + } + public RESULT set3DOcclusion(float directocclusion, float reverbocclusion) + { + return FMOD5_Channel_Set3DOcclusion(this.handle, directocclusion, reverbocclusion); + } + public RESULT get3DOcclusion(out float directocclusion, out float reverbocclusion) + { + return FMOD5_Channel_Get3DOcclusion(this.handle, out directocclusion, out reverbocclusion); + } + public RESULT set3DSpread(float angle) + { + return FMOD5_Channel_Set3DSpread(this.handle, angle); + } + public RESULT get3DSpread(out float angle) + { + return FMOD5_Channel_Get3DSpread(this.handle, out angle); + } + public RESULT set3DLevel(float level) + { + return FMOD5_Channel_Set3DLevel(this.handle, level); + } + public RESULT get3DLevel(out float level) + { + return FMOD5_Channel_Get3DLevel(this.handle, out level); + } + public RESULT set3DDopplerLevel(float level) + { + return FMOD5_Channel_Set3DDopplerLevel(this.handle, level); + } + public RESULT get3DDopplerLevel(out float level) + { + return FMOD5_Channel_Get3DDopplerLevel(this.handle, out level); + } + public RESULT set3DDistanceFilter(bool custom, float customLevel, float centerFreq) + { + return FMOD5_Channel_Set3DDistanceFilter(this.handle, custom, customLevel, centerFreq); + } + public RESULT get3DDistanceFilter(out bool custom, out float customLevel, out float centerFreq) + { + return FMOD5_Channel_Get3DDistanceFilter(this.handle, out custom, out customLevel, out centerFreq); + } + + // Userdata set/get. + public RESULT setUserData(IntPtr userdata) + { + return FMOD5_Channel_SetUserData(this.handle, userdata); + } + public RESULT getUserData(out IntPtr userdata) + { + return FMOD5_Channel_GetUserData(this.handle, out userdata); + } + + #region importfunctions + [DllImport(VERSION.dll)] + private static extern RESULT FMOD5_Channel_SetFrequency (IntPtr channel, float frequency); + [DllImport(VERSION.dll)] + private static extern RESULT FMOD5_Channel_GetFrequency (IntPtr channel, out float frequency); + [DllImport(VERSION.dll)] + private static extern RESULT FMOD5_Channel_SetPriority (IntPtr channel, int priority); + [DllImport(VERSION.dll)] + private static extern RESULT FMOD5_Channel_GetPriority (IntPtr channel, out int priority); + [DllImport(VERSION.dll)] + private static extern RESULT FMOD5_Channel_SetPosition (IntPtr channel, uint position, TIMEUNIT postype); + [DllImport(VERSION.dll)] + private static extern RESULT FMOD5_Channel_GetPosition (IntPtr channel, out uint position, TIMEUNIT postype); + [DllImport(VERSION.dll)] + private static extern RESULT FMOD5_Channel_SetChannelGroup (IntPtr channel, IntPtr channelgroup); + [DllImport(VERSION.dll)] + private static extern RESULT FMOD5_Channel_GetChannelGroup (IntPtr channel, out IntPtr channelgroup); + [DllImport(VERSION.dll)] + private static extern RESULT FMOD5_Channel_SetLoopCount (IntPtr channel, int loopcount); + [DllImport(VERSION.dll)] + private static extern RESULT FMOD5_Channel_GetLoopCount (IntPtr channel, out int loopcount); + [DllImport(VERSION.dll)] + private static extern RESULT FMOD5_Channel_SetLoopPoints (IntPtr channel, uint loopstart, TIMEUNIT loopstarttype, uint loopend, TIMEUNIT loopendtype); + [DllImport(VERSION.dll)] + private static extern RESULT FMOD5_Channel_GetLoopPoints (IntPtr channel, out uint loopstart, TIMEUNIT loopstarttype, out uint loopend, TIMEUNIT loopendtype); + [DllImport(VERSION.dll)] + private static extern RESULT FMOD5_Channel_IsVirtual (IntPtr channel, out bool isvirtual); + [DllImport(VERSION.dll)] + private static extern RESULT FMOD5_Channel_GetCurrentSound (IntPtr channel, out IntPtr sound); + [DllImport(VERSION.dll)] + private static extern RESULT FMOD5_Channel_GetIndex (IntPtr channel, out int index); + [DllImport(VERSION.dll)] + private static extern RESULT FMOD5_Channel_GetSystemObject (IntPtr channel, out IntPtr system); + [DllImport(VERSION.dll)] + private static extern RESULT FMOD5_Channel_Stop (IntPtr channel); + [DllImport(VERSION.dll)] + private static extern RESULT FMOD5_Channel_SetPaused (IntPtr channel, bool paused); + [DllImport(VERSION.dll)] + private static extern RESULT FMOD5_Channel_GetPaused (IntPtr channel, out bool paused); + [DllImport(VERSION.dll)] + private static extern RESULT FMOD5_Channel_SetVolume (IntPtr channel, float volume); + [DllImport(VERSION.dll)] + private static extern RESULT FMOD5_Channel_GetVolume (IntPtr channel, out float volume); + [DllImport(VERSION.dll)] + private static extern RESULT FMOD5_Channel_SetVolumeRamp (IntPtr channel, bool ramp); + [DllImport(VERSION.dll)] + private static extern RESULT FMOD5_Channel_GetVolumeRamp (IntPtr channel, out bool ramp); + [DllImport(VERSION.dll)] + private static extern RESULT FMOD5_Channel_GetAudibility (IntPtr channel, out float audibility); + [DllImport(VERSION.dll)] + private static extern RESULT FMOD5_Channel_SetPitch (IntPtr channel, float pitch); + [DllImport(VERSION.dll)] + private static extern RESULT FMOD5_Channel_GetPitch (IntPtr channel, out float pitch); + [DllImport(VERSION.dll)] + private static extern RESULT FMOD5_Channel_SetMute (IntPtr channel, bool mute); + [DllImport(VERSION.dll)] + private static extern RESULT FMOD5_Channel_GetMute (IntPtr channel, out bool mute); + [DllImport(VERSION.dll)] + private static extern RESULT FMOD5_Channel_SetReverbProperties (IntPtr channel, int instance, float wet); + [DllImport(VERSION.dll)] + private static extern RESULT FMOD5_Channel_GetReverbProperties (IntPtr channel, int instance, out float wet); + [DllImport(VERSION.dll)] + private static extern RESULT FMOD5_Channel_SetLowPassGain (IntPtr channel, float gain); + [DllImport(VERSION.dll)] + private static extern RESULT FMOD5_Channel_GetLowPassGain (IntPtr channel, out float gain); + [DllImport(VERSION.dll)] + private static extern RESULT FMOD5_Channel_SetMode (IntPtr channel, MODE mode); + [DllImport(VERSION.dll)] + private static extern RESULT FMOD5_Channel_GetMode (IntPtr channel, out MODE mode); + [DllImport(VERSION.dll)] + private static extern RESULT FMOD5_Channel_SetCallback (IntPtr channel, CHANNELCONTROL_CALLBACK callback); + [DllImport(VERSION.dll)] + private static extern RESULT FMOD5_Channel_IsPlaying (IntPtr channel, out bool isplaying); + [DllImport(VERSION.dll)] + private static extern RESULT FMOD5_Channel_SetPan (IntPtr channel, float pan); + [DllImport(VERSION.dll)] + private static extern RESULT FMOD5_Channel_SetMixLevelsOutput (IntPtr channel, float frontleft, float frontright, float center, float lfe, float surroundleft, float surroundright, float backleft, float backright); + [DllImport(VERSION.dll)] + private static extern RESULT FMOD5_Channel_SetMixLevelsInput (IntPtr channel, float[] levels, int numlevels); + [DllImport(VERSION.dll)] + private static extern RESULT FMOD5_Channel_SetMixMatrix (IntPtr channel, float[] matrix, int outchannels, int inchannels, int inchannel_hop); + [DllImport(VERSION.dll)] + private static extern RESULT FMOD5_Channel_GetMixMatrix (IntPtr channel, float[] matrix, out int outchannels, out int inchannels, int inchannel_hop); + [DllImport(VERSION.dll)] + private static extern RESULT FMOD5_Channel_GetDSPClock (IntPtr channel, out ulong dspclock, out ulong parentclock); + [DllImport(VERSION.dll)] + private static extern RESULT FMOD5_Channel_SetDelay (IntPtr channel, ulong dspclock_start, ulong dspclock_end, bool stopchannels); + [DllImport(VERSION.dll)] + private static extern RESULT FMOD5_Channel_GetDelay (IntPtr channel, out ulong dspclock_start, out ulong dspclock_end, IntPtr zero); + [DllImport(VERSION.dll)] + private static extern RESULT FMOD5_Channel_GetDelay (IntPtr channel, out ulong dspclock_start, out ulong dspclock_end, out bool stopchannels); + [DllImport(VERSION.dll)] + private static extern RESULT FMOD5_Channel_AddFadePoint (IntPtr channel, ulong dspclock, float volume); + [DllImport(VERSION.dll)] + private static extern RESULT FMOD5_Channel_SetFadePointRamp (IntPtr channel, ulong dspclock, float volume); + [DllImport(VERSION.dll)] + private static extern RESULT FMOD5_Channel_RemoveFadePoints (IntPtr channel, ulong dspclock_start, ulong dspclock_end); + [DllImport(VERSION.dll)] + private static extern RESULT FMOD5_Channel_GetFadePoints (IntPtr channel, ref uint numpoints, ulong[] point_dspclock, float[] point_volume); + [DllImport(VERSION.dll)] + private static extern RESULT FMOD5_Channel_GetDSP (IntPtr channel, int index, out IntPtr dsp); + [DllImport(VERSION.dll)] + private static extern RESULT FMOD5_Channel_AddDSP (IntPtr channel, int index, IntPtr dsp); + [DllImport(VERSION.dll)] + private static extern RESULT FMOD5_Channel_RemoveDSP (IntPtr channel, IntPtr dsp); + [DllImport(VERSION.dll)] + private static extern RESULT FMOD5_Channel_GetNumDSPs (IntPtr channel, out int numdsps); + [DllImport(VERSION.dll)] + private static extern RESULT FMOD5_Channel_SetDSPIndex (IntPtr channel, IntPtr dsp, int index); + [DllImport(VERSION.dll)] + private static extern RESULT FMOD5_Channel_GetDSPIndex (IntPtr channel, IntPtr dsp, out int index); + [DllImport(VERSION.dll)] + private static extern RESULT FMOD5_Channel_Set3DAttributes (IntPtr channel, ref VECTOR pos, ref VECTOR vel); + [DllImport(VERSION.dll)] + private static extern RESULT FMOD5_Channel_Get3DAttributes (IntPtr channel, out VECTOR pos, out VECTOR vel); + [DllImport(VERSION.dll)] + private static extern RESULT FMOD5_Channel_Set3DMinMaxDistance (IntPtr channel, float mindistance, float maxdistance); + [DllImport(VERSION.dll)] + private static extern RESULT FMOD5_Channel_Get3DMinMaxDistance (IntPtr channel, out float mindistance, out float maxdistance); + [DllImport(VERSION.dll)] + private static extern RESULT FMOD5_Channel_Set3DConeSettings (IntPtr channel, float insideconeangle, float outsideconeangle, float outsidevolume); + [DllImport(VERSION.dll)] + private static extern RESULT FMOD5_Channel_Get3DConeSettings (IntPtr channel, out float insideconeangle, out float outsideconeangle, out float outsidevolume); + [DllImport(VERSION.dll)] + private static extern RESULT FMOD5_Channel_Set3DConeOrientation (IntPtr channel, ref VECTOR orientation); + [DllImport(VERSION.dll)] + private static extern RESULT FMOD5_Channel_Get3DConeOrientation (IntPtr channel, out VECTOR orientation); + [DllImport(VERSION.dll)] + private static extern RESULT FMOD5_Channel_Set3DCustomRolloff (IntPtr channel, ref VECTOR points, int numpoints); + [DllImport(VERSION.dll)] + private static extern RESULT FMOD5_Channel_Get3DCustomRolloff (IntPtr channel, out IntPtr points, out int numpoints); + [DllImport(VERSION.dll)] + private static extern RESULT FMOD5_Channel_Set3DOcclusion (IntPtr channel, float directocclusion, float reverbocclusion); + [DllImport(VERSION.dll)] + private static extern RESULT FMOD5_Channel_Get3DOcclusion (IntPtr channel, out float directocclusion, out float reverbocclusion); + [DllImport(VERSION.dll)] + private static extern RESULT FMOD5_Channel_Set3DSpread (IntPtr channel, float angle); + [DllImport(VERSION.dll)] + private static extern RESULT FMOD5_Channel_Get3DSpread (IntPtr channel, out float angle); + [DllImport(VERSION.dll)] + private static extern RESULT FMOD5_Channel_Set3DLevel (IntPtr channel, float level); + [DllImport(VERSION.dll)] + private static extern RESULT FMOD5_Channel_Get3DLevel (IntPtr channel, out float level); + [DllImport(VERSION.dll)] + private static extern RESULT FMOD5_Channel_Set3DDopplerLevel (IntPtr channel, float level); + [DllImport(VERSION.dll)] + private static extern RESULT FMOD5_Channel_Get3DDopplerLevel (IntPtr channel, out float level); + [DllImport(VERSION.dll)] + private static extern RESULT FMOD5_Channel_Set3DDistanceFilter (IntPtr channel, bool custom, float customLevel, float centerFreq); + [DllImport(VERSION.dll)] + private static extern RESULT FMOD5_Channel_Get3DDistanceFilter (IntPtr channel, out bool custom, out float customLevel, out float centerFreq); + [DllImport(VERSION.dll)] + private static extern RESULT FMOD5_Channel_SetUserData (IntPtr channel, IntPtr userdata); + [DllImport(VERSION.dll)] + private static extern RESULT FMOD5_Channel_GetUserData (IntPtr channel, out IntPtr userdata); + #endregion + + #region wrapperinternal + + public IntPtr handle; + + public Channel(IntPtr ptr) { this.handle = ptr; } + public bool hasHandle() { return this.handle != IntPtr.Zero; } + public void clearHandle() { this.handle = IntPtr.Zero; } + + #endregion + } + + /* + 'ChannelGroup' API + */ + public struct ChannelGroup : IChannelControl + { + public RESULT release() + { + return FMOD5_ChannelGroup_Release(this.handle); + } + + // Nested channel groups. + public RESULT addGroup(ChannelGroup group, bool propagatedspclock = true) + { + return FMOD5_ChannelGroup_AddGroup(this.handle, group.handle, propagatedspclock, IntPtr.Zero); + } + public RESULT addGroup(ChannelGroup group, bool propagatedspclock, out DSPConnection connection) + { + return FMOD5_ChannelGroup_AddGroup(this.handle, group.handle, propagatedspclock, out connection.handle); + } + public RESULT getNumGroups(out int numgroups) + { + return FMOD5_ChannelGroup_GetNumGroups(this.handle, out numgroups); + } + public RESULT getGroup(int index, out ChannelGroup group) + { + return FMOD5_ChannelGroup_GetGroup(this.handle, index, out group.handle); + } + public RESULT getParentGroup(out ChannelGroup group) + { + return FMOD5_ChannelGroup_GetParentGroup(this.handle, out group.handle); + } + + // Information only functions. + public RESULT getName(out string name, int namelen) + { + IntPtr stringMem = Marshal.AllocHGlobal(namelen); + + RESULT result = FMOD5_ChannelGroup_GetName(this.handle, stringMem, namelen); + using (StringHelper.ThreadSafeEncoding encoder = StringHelper.GetFreeHelper()) + { + name = encoder.stringFromNative(stringMem); + } + Marshal.FreeHGlobal(stringMem); + + return result; + } + public RESULT getNumChannels(out int numchannels) + { + return FMOD5_ChannelGroup_GetNumChannels(this.handle, out numchannels); + } + public RESULT getChannel(int index, out Channel channel) + { + return FMOD5_ChannelGroup_GetChannel(this.handle, index, out channel.handle); + } + + public RESULT getSystemObject(out System system) + { + return FMOD5_ChannelGroup_GetSystemObject(this.handle, out system.handle); + } + + // General control functionality for Channels and ChannelGroups. + public RESULT stop() + { + return FMOD5_ChannelGroup_Stop(this.handle); + } + public RESULT setPaused(bool paused) + { + return FMOD5_ChannelGroup_SetPaused(this.handle, paused); + } + public RESULT getPaused(out bool paused) + { + return FMOD5_ChannelGroup_GetPaused(this.handle, out paused); + } + public RESULT setVolume(float volume) + { + return FMOD5_ChannelGroup_SetVolume(this.handle, volume); + } + public RESULT getVolume(out float volume) + { + return FMOD5_ChannelGroup_GetVolume(this.handle, out volume); + } + public RESULT setVolumeRamp(bool ramp) + { + return FMOD5_ChannelGroup_SetVolumeRamp(this.handle, ramp); + } + public RESULT getVolumeRamp(out bool ramp) + { + return FMOD5_ChannelGroup_GetVolumeRamp(this.handle, out ramp); + } + public RESULT getAudibility(out float audibility) + { + return FMOD5_ChannelGroup_GetAudibility(this.handle, out audibility); + } + public RESULT setPitch(float pitch) + { + return FMOD5_ChannelGroup_SetPitch(this.handle, pitch); + } + public RESULT getPitch(out float pitch) + { + return FMOD5_ChannelGroup_GetPitch(this.handle, out pitch); + } + public RESULT setMute(bool mute) + { + return FMOD5_ChannelGroup_SetMute(this.handle, mute); + } + public RESULT getMute(out bool mute) + { + return FMOD5_ChannelGroup_GetMute(this.handle, out mute); + } + public RESULT setReverbProperties(int instance, float wet) + { + return FMOD5_ChannelGroup_SetReverbProperties(this.handle, instance, wet); + } + public RESULT getReverbProperties(int instance, out float wet) + { + return FMOD5_ChannelGroup_GetReverbProperties(this.handle, instance, out wet); + } + public RESULT setLowPassGain(float gain) + { + return FMOD5_ChannelGroup_SetLowPassGain(this.handle, gain); + } + public RESULT getLowPassGain(out float gain) + { + return FMOD5_ChannelGroup_GetLowPassGain(this.handle, out gain); + } + public RESULT setMode(MODE mode) + { + return FMOD5_ChannelGroup_SetMode(this.handle, mode); + } + public RESULT getMode(out MODE mode) + { + return FMOD5_ChannelGroup_GetMode(this.handle, out mode); + } + public RESULT setCallback(CHANNELCONTROL_CALLBACK callback) + { + return FMOD5_ChannelGroup_SetCallback(this.handle, callback); + } + public RESULT isPlaying(out bool isplaying) + { + return FMOD5_ChannelGroup_IsPlaying(this.handle, out isplaying); + } + + // Note all 'set' functions alter a final matrix, this is why the only get function is getMixMatrix, to avoid other get functions returning incorrect/obsolete values. + public RESULT setPan(float pan) + { + return FMOD5_ChannelGroup_SetPan(this.handle, pan); + } + public RESULT setMixLevelsOutput(float frontleft, float frontright, float center, float lfe, float surroundleft, float surroundright, float backleft, float backright) + { + return FMOD5_ChannelGroup_SetMixLevelsOutput(this.handle, frontleft, frontright, center, lfe, surroundleft, surroundright, backleft, backright); + } + public RESULT setMixLevelsInput(float[] levels, int numlevels) + { + return FMOD5_ChannelGroup_SetMixLevelsInput(this.handle, levels, numlevels); + } + public RESULT setMixMatrix(float[] matrix, int outchannels, int inchannels, int inchannel_hop) + { + return FMOD5_ChannelGroup_SetMixMatrix(this.handle, matrix, outchannels, inchannels, inchannel_hop); + } + public RESULT getMixMatrix(float[] matrix, out int outchannels, out int inchannels, int inchannel_hop) + { + return FMOD5_ChannelGroup_GetMixMatrix(this.handle, matrix, out outchannels, out inchannels, inchannel_hop); + } + + // Clock based functionality. + public RESULT getDSPClock(out ulong dspclock, out ulong parentclock) + { + return FMOD5_ChannelGroup_GetDSPClock(this.handle, out dspclock, out parentclock); + } + public RESULT setDelay(ulong dspclock_start, ulong dspclock_end, bool stopchannels) + { + return FMOD5_ChannelGroup_SetDelay(this.handle, dspclock_start, dspclock_end, stopchannels); + } + public RESULT getDelay(out ulong dspclock_start, out ulong dspclock_end) + { + return FMOD5_ChannelGroup_GetDelay(this.handle, out dspclock_start, out dspclock_end, IntPtr.Zero); + } + public RESULT getDelay(out ulong dspclock_start, out ulong dspclock_end, out bool stopchannels) + { + return FMOD5_ChannelGroup_GetDelay(this.handle, out dspclock_start, out dspclock_end, out stopchannels); + } + public RESULT addFadePoint(ulong dspclock, float volume) + { + return FMOD5_ChannelGroup_AddFadePoint(this.handle, dspclock, volume); + } + public RESULT setFadePointRamp(ulong dspclock, float volume) + { + return FMOD5_ChannelGroup_SetFadePointRamp(this.handle, dspclock, volume); + } + public RESULT removeFadePoints(ulong dspclock_start, ulong dspclock_end) + { + return FMOD5_ChannelGroup_RemoveFadePoints(this.handle, dspclock_start, dspclock_end); + } + public RESULT getFadePoints(ref uint numpoints, ulong[] point_dspclock, float[] point_volume) + { + return FMOD5_ChannelGroup_GetFadePoints(this.handle, ref numpoints, point_dspclock, point_volume); + } + + // DSP effects. + public RESULT getDSP(int index, out DSP dsp) + { + return FMOD5_ChannelGroup_GetDSP(this.handle, index, out dsp.handle); + } + public RESULT addDSP(int index, DSP dsp) + { + return FMOD5_ChannelGroup_AddDSP(this.handle, index, dsp.handle); + } + public RESULT removeDSP(DSP dsp) + { + return FMOD5_ChannelGroup_RemoveDSP(this.handle, dsp.handle); + } + public RESULT getNumDSPs(out int numdsps) + { + return FMOD5_ChannelGroup_GetNumDSPs(this.handle, out numdsps); + } + public RESULT setDSPIndex(DSP dsp, int index) + { + return FMOD5_ChannelGroup_SetDSPIndex(this.handle, dsp.handle, index); + } + public RESULT getDSPIndex(DSP dsp, out int index) + { + return FMOD5_ChannelGroup_GetDSPIndex(this.handle, dsp.handle, out index); + } + + // 3D functionality. + public RESULT set3DAttributes(ref VECTOR pos, ref VECTOR vel) + { + return FMOD5_ChannelGroup_Set3DAttributes(this.handle, ref pos, ref vel); + } + public RESULT get3DAttributes(out VECTOR pos, out VECTOR vel) + { + return FMOD5_ChannelGroup_Get3DAttributes(this.handle, out pos, out vel); + } + public RESULT set3DMinMaxDistance(float mindistance, float maxdistance) + { + return FMOD5_ChannelGroup_Set3DMinMaxDistance(this.handle, mindistance, maxdistance); + } + public RESULT get3DMinMaxDistance(out float mindistance, out float maxdistance) + { + return FMOD5_ChannelGroup_Get3DMinMaxDistance(this.handle, out mindistance, out maxdistance); + } + public RESULT set3DConeSettings(float insideconeangle, float outsideconeangle, float outsidevolume) + { + return FMOD5_ChannelGroup_Set3DConeSettings(this.handle, insideconeangle, outsideconeangle, outsidevolume); + } + public RESULT get3DConeSettings(out float insideconeangle, out float outsideconeangle, out float outsidevolume) + { + return FMOD5_ChannelGroup_Get3DConeSettings(this.handle, out insideconeangle, out outsideconeangle, out outsidevolume); + } + public RESULT set3DConeOrientation(ref VECTOR orientation) + { + return FMOD5_ChannelGroup_Set3DConeOrientation(this.handle, ref orientation); + } + public RESULT get3DConeOrientation(out VECTOR orientation) + { + return FMOD5_ChannelGroup_Get3DConeOrientation(this.handle, out orientation); + } + public RESULT set3DCustomRolloff(ref VECTOR points, int numpoints) + { + return FMOD5_ChannelGroup_Set3DCustomRolloff(this.handle, ref points, numpoints); + } + public RESULT get3DCustomRolloff(out IntPtr points, out int numpoints) + { + return FMOD5_ChannelGroup_Get3DCustomRolloff(this.handle, out points, out numpoints); + } + public RESULT set3DOcclusion(float directocclusion, float reverbocclusion) + { + return FMOD5_ChannelGroup_Set3DOcclusion(this.handle, directocclusion, reverbocclusion); + } + public RESULT get3DOcclusion(out float directocclusion, out float reverbocclusion) + { + return FMOD5_ChannelGroup_Get3DOcclusion(this.handle, out directocclusion, out reverbocclusion); + } + public RESULT set3DSpread(float angle) + { + return FMOD5_ChannelGroup_Set3DSpread(this.handle, angle); + } + public RESULT get3DSpread(out float angle) + { + return FMOD5_ChannelGroup_Get3DSpread(this.handle, out angle); + } + public RESULT set3DLevel(float level) + { + return FMOD5_ChannelGroup_Set3DLevel(this.handle, level); + } + public RESULT get3DLevel(out float level) + { + return FMOD5_ChannelGroup_Get3DLevel(this.handle, out level); + } + public RESULT set3DDopplerLevel(float level) + { + return FMOD5_ChannelGroup_Set3DDopplerLevel(this.handle, level); + } + public RESULT get3DDopplerLevel(out float level) + { + return FMOD5_ChannelGroup_Get3DDopplerLevel(this.handle, out level); + } + public RESULT set3DDistanceFilter(bool custom, float customLevel, float centerFreq) + { + return FMOD5_ChannelGroup_Set3DDistanceFilter(this.handle, custom, customLevel, centerFreq); + } + public RESULT get3DDistanceFilter(out bool custom, out float customLevel, out float centerFreq) + { + return FMOD5_ChannelGroup_Get3DDistanceFilter(this.handle, out custom, out customLevel, out centerFreq); + } + + // Userdata set/get. + public RESULT setUserData(IntPtr userdata) + { + return FMOD5_ChannelGroup_SetUserData(this.handle, userdata); + } + public RESULT getUserData(out IntPtr userdata) + { + return FMOD5_ChannelGroup_GetUserData(this.handle, out userdata); + } + + #region importfunctions + [DllImport(VERSION.dll)] + private static extern RESULT FMOD5_ChannelGroup_Release (IntPtr channelgroup); + [DllImport(VERSION.dll)] + private static extern RESULT FMOD5_ChannelGroup_AddGroup (IntPtr channelgroup, IntPtr group, bool propagatedspclock, IntPtr zero); + [DllImport(VERSION.dll)] + private static extern RESULT FMOD5_ChannelGroup_AddGroup (IntPtr channelgroup, IntPtr group, bool propagatedspclock, out IntPtr connection); + [DllImport(VERSION.dll)] + private static extern RESULT FMOD5_ChannelGroup_GetNumGroups (IntPtr channelgroup, out int numgroups); + [DllImport(VERSION.dll)] + private static extern RESULT FMOD5_ChannelGroup_GetGroup (IntPtr channelgroup, int index, out IntPtr group); + [DllImport(VERSION.dll)] + private static extern RESULT FMOD5_ChannelGroup_GetParentGroup (IntPtr channelgroup, out IntPtr group); + [DllImport(VERSION.dll)] + private static extern RESULT FMOD5_ChannelGroup_GetName (IntPtr channelgroup, IntPtr name, int namelen); + [DllImport(VERSION.dll)] + private static extern RESULT FMOD5_ChannelGroup_GetNumChannels (IntPtr channelgroup, out int numchannels); + [DllImport(VERSION.dll)] + private static extern RESULT FMOD5_ChannelGroup_GetChannel (IntPtr channelgroup, int index, out IntPtr channel); + [DllImport(VERSION.dll)] + private static extern RESULT FMOD5_ChannelGroup_GetSystemObject (IntPtr channelgroup, out IntPtr system); + [DllImport(VERSION.dll)] + private static extern RESULT FMOD5_ChannelGroup_Stop (IntPtr channelgroup); + [DllImport(VERSION.dll)] + private static extern RESULT FMOD5_ChannelGroup_SetPaused (IntPtr channelgroup, bool paused); + [DllImport(VERSION.dll)] + private static extern RESULT FMOD5_ChannelGroup_GetPaused (IntPtr channelgroup, out bool paused); + [DllImport(VERSION.dll)] + private static extern RESULT FMOD5_ChannelGroup_SetVolume (IntPtr channelgroup, float volume); + [DllImport(VERSION.dll)] + private static extern RESULT FMOD5_ChannelGroup_GetVolume (IntPtr channelgroup, out float volume); + [DllImport(VERSION.dll)] + private static extern RESULT FMOD5_ChannelGroup_SetVolumeRamp (IntPtr channelgroup, bool ramp); + [DllImport(VERSION.dll)] + private static extern RESULT FMOD5_ChannelGroup_GetVolumeRamp (IntPtr channelgroup, out bool ramp); + [DllImport(VERSION.dll)] + private static extern RESULT FMOD5_ChannelGroup_GetAudibility (IntPtr channelgroup, out float audibility); + [DllImport(VERSION.dll)] + private static extern RESULT FMOD5_ChannelGroup_SetPitch (IntPtr channelgroup, float pitch); + [DllImport(VERSION.dll)] + private static extern RESULT FMOD5_ChannelGroup_GetPitch (IntPtr channelgroup, out float pitch); + [DllImport(VERSION.dll)] + private static extern RESULT FMOD5_ChannelGroup_SetMute (IntPtr channelgroup, bool mute); + [DllImport(VERSION.dll)] + private static extern RESULT FMOD5_ChannelGroup_GetMute (IntPtr channelgroup, out bool mute); + [DllImport(VERSION.dll)] + private static extern RESULT FMOD5_ChannelGroup_SetReverbProperties (IntPtr channelgroup, int instance, float wet); + [DllImport(VERSION.dll)] + private static extern RESULT FMOD5_ChannelGroup_GetReverbProperties (IntPtr channelgroup, int instance, out float wet); + [DllImport(VERSION.dll)] + private static extern RESULT FMOD5_ChannelGroup_SetLowPassGain (IntPtr channelgroup, float gain); + [DllImport(VERSION.dll)] + private static extern RESULT FMOD5_ChannelGroup_GetLowPassGain (IntPtr channelgroup, out float gain); + [DllImport(VERSION.dll)] + private static extern RESULT FMOD5_ChannelGroup_SetMode (IntPtr channelgroup, MODE mode); + [DllImport(VERSION.dll)] + private static extern RESULT FMOD5_ChannelGroup_GetMode (IntPtr channelgroup, out MODE mode); + [DllImport(VERSION.dll)] + private static extern RESULT FMOD5_ChannelGroup_SetCallback (IntPtr channelgroup, CHANNELCONTROL_CALLBACK callback); + [DllImport(VERSION.dll)] + private static extern RESULT FMOD5_ChannelGroup_IsPlaying (IntPtr channelgroup, out bool isplaying); + [DllImport(VERSION.dll)] + private static extern RESULT FMOD5_ChannelGroup_SetPan (IntPtr channelgroup, float pan); + [DllImport(VERSION.dll)] + private static extern RESULT FMOD5_ChannelGroup_SetMixLevelsOutput (IntPtr channelgroup, float frontleft, float frontright, float center, float lfe, float surroundleft, float surroundright, float backleft, float backright); + [DllImport(VERSION.dll)] + private static extern RESULT FMOD5_ChannelGroup_SetMixLevelsInput (IntPtr channelgroup, float[] levels, int numlevels); + [DllImport(VERSION.dll)] + private static extern RESULT FMOD5_ChannelGroup_SetMixMatrix (IntPtr channelgroup, float[] matrix, int outchannels, int inchannels, int inchannel_hop); + [DllImport(VERSION.dll)] + private static extern RESULT FMOD5_ChannelGroup_GetMixMatrix (IntPtr channelgroup, float[] matrix, out int outchannels, out int inchannels, int inchannel_hop); + [DllImport(VERSION.dll)] + private static extern RESULT FMOD5_ChannelGroup_GetDSPClock (IntPtr channelgroup, out ulong dspclock, out ulong parentclock); + [DllImport(VERSION.dll)] + private static extern RESULT FMOD5_ChannelGroup_SetDelay (IntPtr channelgroup, ulong dspclock_start, ulong dspclock_end, bool stopchannels); + [DllImport(VERSION.dll)] + private static extern RESULT FMOD5_ChannelGroup_GetDelay (IntPtr channelgroup, out ulong dspclock_start, out ulong dspclock_end, IntPtr zero); + [DllImport(VERSION.dll)] + private static extern RESULT FMOD5_ChannelGroup_GetDelay (IntPtr channelgroup, out ulong dspclock_start, out ulong dspclock_end, out bool stopchannels); + [DllImport(VERSION.dll)] + private static extern RESULT FMOD5_ChannelGroup_AddFadePoint (IntPtr channelgroup, ulong dspclock, float volume); + [DllImport(VERSION.dll)] + private static extern RESULT FMOD5_ChannelGroup_SetFadePointRamp (IntPtr channelgroup, ulong dspclock, float volume); + [DllImport(VERSION.dll)] + private static extern RESULT FMOD5_ChannelGroup_RemoveFadePoints (IntPtr channelgroup, ulong dspclock_start, ulong dspclock_end); + [DllImport(VERSION.dll)] + private static extern RESULT FMOD5_ChannelGroup_GetFadePoints (IntPtr channelgroup, ref uint numpoints, ulong[] point_dspclock, float[] point_volume); + [DllImport(VERSION.dll)] + private static extern RESULT FMOD5_ChannelGroup_GetDSP (IntPtr channelgroup, int index, out IntPtr dsp); + [DllImport(VERSION.dll)] + private static extern RESULT FMOD5_ChannelGroup_AddDSP (IntPtr channelgroup, int index, IntPtr dsp); + [DllImport(VERSION.dll)] + private static extern RESULT FMOD5_ChannelGroup_RemoveDSP (IntPtr channelgroup, IntPtr dsp); + [DllImport(VERSION.dll)] + private static extern RESULT FMOD5_ChannelGroup_GetNumDSPs (IntPtr channelgroup, out int numdsps); + [DllImport(VERSION.dll)] + private static extern RESULT FMOD5_ChannelGroup_SetDSPIndex (IntPtr channelgroup, IntPtr dsp, int index); + [DllImport(VERSION.dll)] + private static extern RESULT FMOD5_ChannelGroup_GetDSPIndex (IntPtr channelgroup, IntPtr dsp, out int index); + [DllImport(VERSION.dll)] + private static extern RESULT FMOD5_ChannelGroup_Set3DAttributes (IntPtr channelgroup, ref VECTOR pos, ref VECTOR vel); + [DllImport(VERSION.dll)] + private static extern RESULT FMOD5_ChannelGroup_Get3DAttributes (IntPtr channelgroup, out VECTOR pos, out VECTOR vel); + [DllImport(VERSION.dll)] + private static extern RESULT FMOD5_ChannelGroup_Set3DMinMaxDistance (IntPtr channelgroup, float mindistance, float maxdistance); + [DllImport(VERSION.dll)] + private static extern RESULT FMOD5_ChannelGroup_Get3DMinMaxDistance (IntPtr channelgroup, out float mindistance, out float maxdistance); + [DllImport(VERSION.dll)] + private static extern RESULT FMOD5_ChannelGroup_Set3DConeSettings (IntPtr channelgroup, float insideconeangle, float outsideconeangle, float outsidevolume); + [DllImport(VERSION.dll)] + private static extern RESULT FMOD5_ChannelGroup_Get3DConeSettings (IntPtr channelgroup, out float insideconeangle, out float outsideconeangle, out float outsidevolume); + [DllImport(VERSION.dll)] + private static extern RESULT FMOD5_ChannelGroup_Set3DConeOrientation(IntPtr channelgroup, ref VECTOR orientation); + [DllImport(VERSION.dll)] + private static extern RESULT FMOD5_ChannelGroup_Get3DConeOrientation(IntPtr channelgroup, out VECTOR orientation); + [DllImport(VERSION.dll)] + private static extern RESULT FMOD5_ChannelGroup_Set3DCustomRolloff (IntPtr channelgroup, ref VECTOR points, int numpoints); + [DllImport(VERSION.dll)] + private static extern RESULT FMOD5_ChannelGroup_Get3DCustomRolloff (IntPtr channelgroup, out IntPtr points, out int numpoints); + [DllImport(VERSION.dll)] + private static extern RESULT FMOD5_ChannelGroup_Set3DOcclusion (IntPtr channelgroup, float directocclusion, float reverbocclusion); + [DllImport(VERSION.dll)] + private static extern RESULT FMOD5_ChannelGroup_Get3DOcclusion (IntPtr channelgroup, out float directocclusion, out float reverbocclusion); + [DllImport(VERSION.dll)] + private static extern RESULT FMOD5_ChannelGroup_Set3DSpread (IntPtr channelgroup, float angle); + [DllImport(VERSION.dll)] + private static extern RESULT FMOD5_ChannelGroup_Get3DSpread (IntPtr channelgroup, out float angle); + [DllImport(VERSION.dll)] + private static extern RESULT FMOD5_ChannelGroup_Set3DLevel (IntPtr channelgroup, float level); + [DllImport(VERSION.dll)] + private static extern RESULT FMOD5_ChannelGroup_Get3DLevel (IntPtr channelgroup, out float level); + [DllImport(VERSION.dll)] + private static extern RESULT FMOD5_ChannelGroup_Set3DDopplerLevel (IntPtr channelgroup, float level); + [DllImport(VERSION.dll)] + private static extern RESULT FMOD5_ChannelGroup_Get3DDopplerLevel (IntPtr channelgroup, out float level); + [DllImport(VERSION.dll)] + private static extern RESULT FMOD5_ChannelGroup_Set3DDistanceFilter (IntPtr channelgroup, bool custom, float customLevel, float centerFreq); + [DllImport(VERSION.dll)] + private static extern RESULT FMOD5_ChannelGroup_Get3DDistanceFilter (IntPtr channelgroup, out bool custom, out float customLevel, out float centerFreq); + [DllImport(VERSION.dll)] + private static extern RESULT FMOD5_ChannelGroup_SetUserData (IntPtr channelgroup, IntPtr userdata); + [DllImport(VERSION.dll)] + private static extern RESULT FMOD5_ChannelGroup_GetUserData (IntPtr channelgroup, out IntPtr userdata); + #endregion + + #region wrapperinternal + + public IntPtr handle; + + public ChannelGroup(IntPtr ptr) { this.handle = ptr; } + public bool hasHandle() { return this.handle != IntPtr.Zero; } + public void clearHandle() { this.handle = IntPtr.Zero; } + + #endregion + } + + /* + 'SoundGroup' API + */ + public struct SoundGroup + { + public RESULT release() + { + return FMOD5_SoundGroup_Release(this.handle); + } + + public RESULT getSystemObject(out System system) + { + return FMOD5_SoundGroup_GetSystemObject(this.handle, out system.handle); + } + + // SoundGroup control functions. + public RESULT setMaxAudible(int maxaudible) + { + return FMOD5_SoundGroup_SetMaxAudible(this.handle, maxaudible); + } + public RESULT getMaxAudible(out int maxaudible) + { + return FMOD5_SoundGroup_GetMaxAudible(this.handle, out maxaudible); + } + public RESULT setMaxAudibleBehavior(SOUNDGROUP_BEHAVIOR behavior) + { + return FMOD5_SoundGroup_SetMaxAudibleBehavior(this.handle, behavior); + } + public RESULT getMaxAudibleBehavior(out SOUNDGROUP_BEHAVIOR behavior) + { + return FMOD5_SoundGroup_GetMaxAudibleBehavior(this.handle, out behavior); + } + public RESULT setMuteFadeSpeed(float speed) + { + return FMOD5_SoundGroup_SetMuteFadeSpeed(this.handle, speed); + } + public RESULT getMuteFadeSpeed(out float speed) + { + return FMOD5_SoundGroup_GetMuteFadeSpeed(this.handle, out speed); + } + public RESULT setVolume(float volume) + { + return FMOD5_SoundGroup_SetVolume(this.handle, volume); + } + public RESULT getVolume(out float volume) + { + return FMOD5_SoundGroup_GetVolume(this.handle, out volume); + } + public RESULT stop() + { + return FMOD5_SoundGroup_Stop(this.handle); + } + + // Information only functions. + public RESULT getName(out string name, int namelen) + { + IntPtr stringMem = Marshal.AllocHGlobal(namelen); + + RESULT result = FMOD5_SoundGroup_GetName(this.handle, stringMem, namelen); + using (StringHelper.ThreadSafeEncoding encoder = StringHelper.GetFreeHelper()) + { + name = encoder.stringFromNative(stringMem); + } + Marshal.FreeHGlobal(stringMem); + + return result; + } + public RESULT getNumSounds(out int numsounds) + { + return FMOD5_SoundGroup_GetNumSounds(this.handle, out numsounds); + } + public RESULT getSound(int index, out Sound sound) + { + return FMOD5_SoundGroup_GetSound(this.handle, index, out sound.handle); + } + public RESULT getNumPlaying(out int numplaying) + { + return FMOD5_SoundGroup_GetNumPlaying(this.handle, out numplaying); + } + + // Userdata set/get. + public RESULT setUserData(IntPtr userdata) + { + return FMOD5_SoundGroup_SetUserData(this.handle, userdata); + } + public RESULT getUserData(out IntPtr userdata) + { + return FMOD5_SoundGroup_GetUserData(this.handle, out userdata); + } + + #region importfunctions + [DllImport(VERSION.dll)] + private static extern RESULT FMOD5_SoundGroup_Release (IntPtr soundgroup); + [DllImport(VERSION.dll)] + private static extern RESULT FMOD5_SoundGroup_GetSystemObject (IntPtr soundgroup, out IntPtr system); + [DllImport(VERSION.dll)] + private static extern RESULT FMOD5_SoundGroup_SetMaxAudible (IntPtr soundgroup, int maxaudible); + [DllImport(VERSION.dll)] + private static extern RESULT FMOD5_SoundGroup_GetMaxAudible (IntPtr soundgroup, out int maxaudible); + [DllImport(VERSION.dll)] + private static extern RESULT FMOD5_SoundGroup_SetMaxAudibleBehavior (IntPtr soundgroup, SOUNDGROUP_BEHAVIOR behavior); + [DllImport(VERSION.dll)] + private static extern RESULT FMOD5_SoundGroup_GetMaxAudibleBehavior (IntPtr soundgroup, out SOUNDGROUP_BEHAVIOR behavior); + [DllImport(VERSION.dll)] + private static extern RESULT FMOD5_SoundGroup_SetMuteFadeSpeed (IntPtr soundgroup, float speed); + [DllImport(VERSION.dll)] + private static extern RESULT FMOD5_SoundGroup_GetMuteFadeSpeed (IntPtr soundgroup, out float speed); + [DllImport(VERSION.dll)] + private static extern RESULT FMOD5_SoundGroup_SetVolume (IntPtr soundgroup, float volume); + [DllImport(VERSION.dll)] + private static extern RESULT FMOD5_SoundGroup_GetVolume (IntPtr soundgroup, out float volume); + [DllImport(VERSION.dll)] + private static extern RESULT FMOD5_SoundGroup_Stop (IntPtr soundgroup); + [DllImport(VERSION.dll)] + private static extern RESULT FMOD5_SoundGroup_GetName (IntPtr soundgroup, IntPtr name, int namelen); + [DllImport(VERSION.dll)] + private static extern RESULT FMOD5_SoundGroup_GetNumSounds (IntPtr soundgroup, out int numsounds); + [DllImport(VERSION.dll)] + private static extern RESULT FMOD5_SoundGroup_GetSound (IntPtr soundgroup, int index, out IntPtr sound); + [DllImport(VERSION.dll)] + private static extern RESULT FMOD5_SoundGroup_GetNumPlaying (IntPtr soundgroup, out int numplaying); + [DllImport(VERSION.dll)] + private static extern RESULT FMOD5_SoundGroup_SetUserData (IntPtr soundgroup, IntPtr userdata); + [DllImport(VERSION.dll)] + private static extern RESULT FMOD5_SoundGroup_GetUserData (IntPtr soundgroup, out IntPtr userdata); + #endregion + + #region wrapperinternal + + public IntPtr handle; + + public SoundGroup(IntPtr ptr) { this.handle = ptr; } + public bool hasHandle() { return this.handle != IntPtr.Zero; } + public void clearHandle() { this.handle = IntPtr.Zero; } + + #endregion + } + + /* + 'DSP' API + */ + public struct DSP + { + public RESULT release() + { + return FMOD5_DSP_Release(this.handle); + } + public RESULT getSystemObject(out System system) + { + return FMOD5_DSP_GetSystemObject(this.handle, out system.handle); + } + + // Connection / disconnection / input and output enumeration. + public RESULT addInput(DSP input) + { + return FMOD5_DSP_AddInput(this.handle, input.handle, IntPtr.Zero, DSPCONNECTION_TYPE.STANDARD); + } + public RESULT addInput(DSP input, out DSPConnection connection, DSPCONNECTION_TYPE type = DSPCONNECTION_TYPE.STANDARD) + { + return FMOD5_DSP_AddInput(this.handle, input.handle, out connection.handle, type); + } + public RESULT addInputPreallocated(DSP input, DSPConnection connection) + { + return FMOD5_DSP_AddInput(this.handle, input.handle, out connection.handle, DSPCONNECTION_TYPE.PREALLOCATED); + } + public RESULT disconnectFrom(DSP target, DSPConnection connection) + { + return FMOD5_DSP_DisconnectFrom(this.handle, target.handle, connection.handle); + } + public RESULT disconnectAll(bool inputs, bool outputs) + { + return FMOD5_DSP_DisconnectAll(this.handle, inputs, outputs); + } + public RESULT getNumInputs(out int numinputs) + { + return FMOD5_DSP_GetNumInputs(this.handle, out numinputs); + } + public RESULT getNumOutputs(out int numoutputs) + { + return FMOD5_DSP_GetNumOutputs(this.handle, out numoutputs); + } + public RESULT getInput(int index, out DSP input, out DSPConnection inputconnection) + { + return FMOD5_DSP_GetInput(this.handle, index, out input.handle, out inputconnection.handle); + } + public RESULT getOutput(int index, out DSP output, out DSPConnection outputconnection) + { + return FMOD5_DSP_GetOutput(this.handle, index, out output.handle, out outputconnection.handle); + } + + // DSP unit control. + public RESULT setActive(bool active) + { + return FMOD5_DSP_SetActive(this.handle, active); + } + public RESULT getActive(out bool active) + { + return FMOD5_DSP_GetActive(this.handle, out active); + } + public RESULT setBypass(bool bypass) + { + return FMOD5_DSP_SetBypass(this.handle, bypass); + } + public RESULT getBypass(out bool bypass) + { + return FMOD5_DSP_GetBypass(this.handle, out bypass); + } + public RESULT setWetDryMix(float prewet, float postwet, float dry) + { + return FMOD5_DSP_SetWetDryMix(this.handle, prewet, postwet, dry); + } + public RESULT getWetDryMix(out float prewet, out float postwet, out float dry) + { + return FMOD5_DSP_GetWetDryMix(this.handle, out prewet, out postwet, out dry); + } + public RESULT setChannelFormat(CHANNELMASK channelmask, int numchannels, SPEAKERMODE source_speakermode) + { + return FMOD5_DSP_SetChannelFormat(this.handle, channelmask, numchannels, source_speakermode); + } + public RESULT getChannelFormat(out CHANNELMASK channelmask, out int numchannels, out SPEAKERMODE source_speakermode) + { + return FMOD5_DSP_GetChannelFormat(this.handle, out channelmask, out numchannels, out source_speakermode); + } + public RESULT getOutputChannelFormat(CHANNELMASK inmask, int inchannels, SPEAKERMODE inspeakermode, out CHANNELMASK outmask, out int outchannels, out SPEAKERMODE outspeakermode) + { + return FMOD5_DSP_GetOutputChannelFormat(this.handle, inmask, inchannels, inspeakermode, out outmask, out outchannels, out outspeakermode); + } + public RESULT reset() + { + return FMOD5_DSP_Reset(this.handle); + } + public RESULT setCallback(DSP_CALLBACK callback) + { + return FMOD5_DSP_SetCallback(this.handle, callback); + } + + // DSP parameter control. + public RESULT setParameterFloat(int index, float value) + { + return FMOD5_DSP_SetParameterFloat(this.handle, index, value); + } + public RESULT setParameterInt(int index, int value) + { + return FMOD5_DSP_SetParameterInt(this.handle, index, value); + } + public RESULT setParameterBool(int index, bool value) + { + return FMOD5_DSP_SetParameterBool(this.handle, index, value); + } + public RESULT setParameterData(int index, byte[] data) + { + return FMOD5_DSP_SetParameterData(this.handle, index, data, data == null ? 0 : (uint)data.Length); + } + public RESULT getParameterFloat(int index, out float value) + { + return FMOD5_DSP_GetParameterFloat(this.handle, index, out value, IntPtr.Zero, 0); + } + public RESULT getParameterInt(int index, out int value) + { + return FMOD5_DSP_GetParameterInt(this.handle, index, out value, IntPtr.Zero, 0); + } + public RESULT getParameterBool(int index, out bool value) + { + return FMOD5_DSP_GetParameterBool(this.handle, index, out value, IntPtr.Zero, 0); + } + public RESULT getParameterData(int index, out IntPtr data, out uint length) + { + return FMOD5_DSP_GetParameterData(this.handle, index, out data, out length, IntPtr.Zero, 0); + } + public RESULT getNumParameters(out int numparams) + { + return FMOD5_DSP_GetNumParameters(this.handle, out numparams); + } + public RESULT getParameterInfo(int index, out DSP_PARAMETER_DESC desc) + { + IntPtr descPtr; + RESULT result = FMOD5_DSP_GetParameterInfo(this.handle, index, out descPtr); + desc = (DSP_PARAMETER_DESC)Marshal.PtrToStructure(descPtr); + return result; + } + public RESULT getDataParameterIndex(int datatype, out int index) + { + return FMOD5_DSP_GetDataParameterIndex(this.handle, datatype, out index); + } + public RESULT showConfigDialog(IntPtr hwnd, bool show) + { + return FMOD5_DSP_ShowConfigDialog(this.handle, hwnd, show); + } + + // DSP attributes. + public RESULT getInfo(out string name, out uint version, out int channels, out int configwidth, out int configheight) + { + IntPtr nameMem = Marshal.AllocHGlobal(32); + + RESULT result = FMOD5_DSP_GetInfo(this.handle, nameMem, out version, out channels, out configwidth, out configheight); + using (StringHelper.ThreadSafeEncoding encoder = StringHelper.GetFreeHelper()) + { + name = encoder.stringFromNative(nameMem); + } + Marshal.FreeHGlobal(nameMem); + return result; + } + public RESULT getInfo(out uint version, out int channels, out int configwidth, out int configheight) + { + return FMOD5_DSP_GetInfo(this.handle, IntPtr.Zero, out version, out channels, out configwidth, out configheight); ; + } + public RESULT getType(out DSP_TYPE type) + { + return FMOD5_DSP_GetType(this.handle, out type); + } + public RESULT getIdle(out bool idle) + { + return FMOD5_DSP_GetIdle(this.handle, out idle); + } + + // Userdata set/get. + public RESULT setUserData(IntPtr userdata) + { + return FMOD5_DSP_SetUserData(this.handle, userdata); + } + public RESULT getUserData(out IntPtr userdata) + { + return FMOD5_DSP_GetUserData(this.handle, out userdata); + } + + // Metering. + public RESULT setMeteringEnabled(bool inputEnabled, bool outputEnabled) + { + return FMOD5_DSP_SetMeteringEnabled(this.handle, inputEnabled, outputEnabled); + } + public RESULT getMeteringEnabled(out bool inputEnabled, out bool outputEnabled) + { + return FMOD5_DSP_GetMeteringEnabled(this.handle, out inputEnabled, out outputEnabled); + } + + public RESULT getMeteringInfo(IntPtr zero, out DSP_METERING_INFO outputInfo) + { + return FMOD5_DSP_GetMeteringInfo(this.handle, zero, out outputInfo); + } + public RESULT getMeteringInfo(out DSP_METERING_INFO inputInfo, IntPtr zero) + { + return FMOD5_DSP_GetMeteringInfo(this.handle, out inputInfo, zero); + } + public RESULT getMeteringInfo(out DSP_METERING_INFO inputInfo, out DSP_METERING_INFO outputInfo) + { + return FMOD5_DSP_GetMeteringInfo(this.handle, out inputInfo, out outputInfo); + } + + public RESULT getCPUUsage(out uint exclusive, out uint inclusive) + { + return FMOD5_DSP_GetCPUUsage(this.handle, out exclusive, out inclusive); + } + + #region importfunctions + [DllImport(VERSION.dll)] + private static extern RESULT FMOD5_DSP_Release (IntPtr dsp); + [DllImport(VERSION.dll)] + private static extern RESULT FMOD5_DSP_GetSystemObject (IntPtr dsp, out IntPtr system); + [DllImport(VERSION.dll)] + private static extern RESULT FMOD5_DSP_AddInput (IntPtr dsp, IntPtr input, IntPtr zero, DSPCONNECTION_TYPE type); + [DllImport(VERSION.dll)] + private static extern RESULT FMOD5_DSP_AddInput (IntPtr dsp, IntPtr input, out IntPtr connection, DSPCONNECTION_TYPE type); + [DllImport(VERSION.dll)] + private static extern RESULT FMOD5_DSP_AddInputPreallocated (IntPtr dsp, IntPtr input, out IntPtr connection); + [DllImport(VERSION.dll)] + private static extern RESULT FMOD5_DSP_DisconnectFrom (IntPtr dsp, IntPtr target, IntPtr connection); + [DllImport(VERSION.dll)] + private static extern RESULT FMOD5_DSP_DisconnectAll (IntPtr dsp, bool inputs, bool outputs); + [DllImport(VERSION.dll)] + private static extern RESULT FMOD5_DSP_GetNumInputs (IntPtr dsp, out int numinputs); + [DllImport(VERSION.dll)] + private static extern RESULT FMOD5_DSP_GetNumOutputs (IntPtr dsp, out int numoutputs); + [DllImport(VERSION.dll)] + private static extern RESULT FMOD5_DSP_GetInput (IntPtr dsp, int index, out IntPtr input, out IntPtr inputconnection); + [DllImport(VERSION.dll)] + private static extern RESULT FMOD5_DSP_GetOutput (IntPtr dsp, int index, out IntPtr output, out IntPtr outputconnection); + [DllImport(VERSION.dll)] + private static extern RESULT FMOD5_DSP_SetActive (IntPtr dsp, bool active); + [DllImport(VERSION.dll)] + private static extern RESULT FMOD5_DSP_GetActive (IntPtr dsp, out bool active); + [DllImport(VERSION.dll)] + private static extern RESULT FMOD5_DSP_SetBypass (IntPtr dsp, bool bypass); + [DllImport(VERSION.dll)] + private static extern RESULT FMOD5_DSP_GetBypass (IntPtr dsp, out bool bypass); + [DllImport(VERSION.dll)] + private static extern RESULT FMOD5_DSP_SetWetDryMix (IntPtr dsp, float prewet, float postwet, float dry); + [DllImport(VERSION.dll)] + private static extern RESULT FMOD5_DSP_GetWetDryMix (IntPtr dsp, out float prewet, out float postwet, out float dry); + [DllImport(VERSION.dll)] + private static extern RESULT FMOD5_DSP_SetChannelFormat (IntPtr dsp, CHANNELMASK channelmask, int numchannels, SPEAKERMODE source_speakermode); + [DllImport(VERSION.dll)] + private static extern RESULT FMOD5_DSP_GetChannelFormat (IntPtr dsp, out CHANNELMASK channelmask, out int numchannels, out SPEAKERMODE source_speakermode); + [DllImport(VERSION.dll)] + private static extern RESULT FMOD5_DSP_GetOutputChannelFormat (IntPtr dsp, CHANNELMASK inmask, int inchannels, SPEAKERMODE inspeakermode, out CHANNELMASK outmask, out int outchannels, out SPEAKERMODE outspeakermode); + [DllImport(VERSION.dll)] + private static extern RESULT FMOD5_DSP_Reset (IntPtr dsp); + [DllImport(VERSION.dll)] + private static extern RESULT FMOD5_DSP_SetCallback (IntPtr dsp, DSP_CALLBACK callback); + [DllImport(VERSION.dll)] + private static extern RESULT FMOD5_DSP_SetParameterFloat (IntPtr dsp, int index, float value); + [DllImport(VERSION.dll)] + private static extern RESULT FMOD5_DSP_SetParameterInt (IntPtr dsp, int index, int value); + [DllImport(VERSION.dll)] + private static extern RESULT FMOD5_DSP_SetParameterBool (IntPtr dsp, int index, bool value); + [DllImport(VERSION.dll)] + private static extern RESULT FMOD5_DSP_SetParameterData (IntPtr dsp, int index, byte[] data, uint length); + [DllImport(VERSION.dll)] + private static extern RESULT FMOD5_DSP_GetParameterFloat (IntPtr dsp, int index, out float value, IntPtr valuestr, int valuestrlen); + [DllImport(VERSION.dll)] + private static extern RESULT FMOD5_DSP_GetParameterInt (IntPtr dsp, int index, out int value, IntPtr valuestr, int valuestrlen); + [DllImport(VERSION.dll)] + private static extern RESULT FMOD5_DSP_GetParameterBool (IntPtr dsp, int index, out bool value, IntPtr valuestr, int valuestrlen); + [DllImport(VERSION.dll)] + private static extern RESULT FMOD5_DSP_GetParameterData (IntPtr dsp, int index, out IntPtr data, out uint length, IntPtr valuestr, int valuestrlen); + [DllImport(VERSION.dll)] + private static extern RESULT FMOD5_DSP_GetNumParameters (IntPtr dsp, out int numparams); + [DllImport(VERSION.dll)] + private static extern RESULT FMOD5_DSP_GetParameterInfo (IntPtr dsp, int index, out IntPtr desc); + [DllImport(VERSION.dll)] + private static extern RESULT FMOD5_DSP_GetDataParameterIndex (IntPtr dsp, int datatype, out int index); + [DllImport(VERSION.dll)] + private static extern RESULT FMOD5_DSP_ShowConfigDialog (IntPtr dsp, IntPtr hwnd, bool show); + [DllImport(VERSION.dll)] + private static extern RESULT FMOD5_DSP_GetInfo (IntPtr dsp, IntPtr name, out uint version, out int channels, out int configwidth, out int configheight); + [DllImport(VERSION.dll)] + private static extern RESULT FMOD5_DSP_GetType (IntPtr dsp, out DSP_TYPE type); + [DllImport(VERSION.dll)] + private static extern RESULT FMOD5_DSP_GetIdle (IntPtr dsp, out bool idle); + [DllImport(VERSION.dll)] + private static extern RESULT FMOD5_DSP_SetUserData (IntPtr dsp, IntPtr userdata); + [DllImport(VERSION.dll)] + private static extern RESULT FMOD5_DSP_GetUserData (IntPtr dsp, out IntPtr userdata); + [DllImport(VERSION.dll)] + public static extern RESULT FMOD5_DSP_SetMeteringEnabled (IntPtr dsp, bool inputEnabled, bool outputEnabled); + [DllImport(VERSION.dll)] + public static extern RESULT FMOD5_DSP_GetMeteringEnabled (IntPtr dsp, out bool inputEnabled, out bool outputEnabled); + [DllImport(VERSION.dll)] + public static extern RESULT FMOD5_DSP_GetMeteringInfo (IntPtr dsp, IntPtr zero, out DSP_METERING_INFO outputInfo); + [DllImport(VERSION.dll)] + public static extern RESULT FMOD5_DSP_GetMeteringInfo (IntPtr dsp, out DSP_METERING_INFO inputInfo, IntPtr zero); + [DllImport(VERSION.dll)] + public static extern RESULT FMOD5_DSP_GetMeteringInfo (IntPtr dsp, out DSP_METERING_INFO inputInfo, out DSP_METERING_INFO outputInfo); + [DllImport(VERSION.dll)] + public static extern RESULT FMOD5_DSP_GetCPUUsage (IntPtr dsp, out uint exclusive, out uint inclusive); + #endregion + + #region wrapperinternal + + public IntPtr handle; + + public DSP(IntPtr ptr) { this.handle = ptr; } + public bool hasHandle() { return this.handle != IntPtr.Zero; } + public void clearHandle() { this.handle = IntPtr.Zero; } + + #endregion + } + + /* + 'DSPConnection' API + */ + public struct DSPConnection + { + public RESULT getInput(out DSP input) + { + return FMOD5_DSPConnection_GetInput(this.handle, out input.handle); + } + public RESULT getOutput(out DSP output) + { + return FMOD5_DSPConnection_GetOutput(this.handle, out output.handle); + } + public RESULT setMix(float volume) + { + return FMOD5_DSPConnection_SetMix(this.handle, volume); + } + public RESULT getMix(out float volume) + { + return FMOD5_DSPConnection_GetMix(this.handle, out volume); + } + public RESULT setMixMatrix(float[] matrix, int outchannels, int inchannels, int inchannel_hop = 0) + { + return FMOD5_DSPConnection_SetMixMatrix(this.handle, matrix, outchannels, inchannels, inchannel_hop); + } + public RESULT getMixMatrix(float[] matrix, out int outchannels, out int inchannels, int inchannel_hop = 0) + { + return FMOD5_DSPConnection_GetMixMatrix(this.handle, matrix, out outchannels, out inchannels, inchannel_hop); + } + public RESULT getType(out DSPCONNECTION_TYPE type) + { + return FMOD5_DSPConnection_GetType(this.handle, out type); + } + + // Userdata set/get. + public RESULT setUserData(IntPtr userdata) + { + return FMOD5_DSPConnection_SetUserData(this.handle, userdata); + } + public RESULT getUserData(out IntPtr userdata) + { + return FMOD5_DSPConnection_GetUserData(this.handle, out userdata); + } + + #region importfunctions + [DllImport(VERSION.dll)] + private static extern RESULT FMOD5_DSPConnection_GetInput (IntPtr dspconnection, out IntPtr input); + [DllImport(VERSION.dll)] + private static extern RESULT FMOD5_DSPConnection_GetOutput (IntPtr dspconnection, out IntPtr output); + [DllImport(VERSION.dll)] + private static extern RESULT FMOD5_DSPConnection_SetMix (IntPtr dspconnection, float volume); + [DllImport(VERSION.dll)] + private static extern RESULT FMOD5_DSPConnection_GetMix (IntPtr dspconnection, out float volume); + [DllImport(VERSION.dll)] + private static extern RESULT FMOD5_DSPConnection_SetMixMatrix (IntPtr dspconnection, float[] matrix, int outchannels, int inchannels, int inchannel_hop); + [DllImport(VERSION.dll)] + private static extern RESULT FMOD5_DSPConnection_GetMixMatrix (IntPtr dspconnection, float[] matrix, out int outchannels, out int inchannels, int inchannel_hop); + [DllImport(VERSION.dll)] + private static extern RESULT FMOD5_DSPConnection_GetType (IntPtr dspconnection, out DSPCONNECTION_TYPE type); + [DllImport(VERSION.dll)] + private static extern RESULT FMOD5_DSPConnection_SetUserData (IntPtr dspconnection, IntPtr userdata); + [DllImport(VERSION.dll)] + private static extern RESULT FMOD5_DSPConnection_GetUserData (IntPtr dspconnection, out IntPtr userdata); + #endregion + + #region wrapperinternal + + public IntPtr handle; + + public DSPConnection(IntPtr ptr) { this.handle = ptr; } + public bool hasHandle() { return this.handle != IntPtr.Zero; } + public void clearHandle() { this.handle = IntPtr.Zero; } + + #endregion + } + + /* + 'Geometry' API + */ + public struct Geometry + { + public RESULT release() + { + return FMOD5_Geometry_Release(this.handle); + } + + // Polygon manipulation. + public RESULT addPolygon(float directocclusion, float reverbocclusion, bool doublesided, int numvertices, VECTOR[] vertices, out int polygonindex) + { + return FMOD5_Geometry_AddPolygon(this.handle, directocclusion, reverbocclusion, doublesided, numvertices, vertices, out polygonindex); + } + public RESULT getNumPolygons(out int numpolygons) + { + return FMOD5_Geometry_GetNumPolygons(this.handle, out numpolygons); + } + public RESULT getMaxPolygons(out int maxpolygons, out int maxvertices) + { + return FMOD5_Geometry_GetMaxPolygons(this.handle, out maxpolygons, out maxvertices); + } + public RESULT getPolygonNumVertices(int index, out int numvertices) + { + return FMOD5_Geometry_GetPolygonNumVertices(this.handle, index, out numvertices); + } + public RESULT setPolygonVertex(int index, int vertexindex, ref VECTOR vertex) + { + return FMOD5_Geometry_SetPolygonVertex(this.handle, index, vertexindex, ref vertex); + } + public RESULT getPolygonVertex(int index, int vertexindex, out VECTOR vertex) + { + return FMOD5_Geometry_GetPolygonVertex(this.handle, index, vertexindex, out vertex); + } + public RESULT setPolygonAttributes(int index, float directocclusion, float reverbocclusion, bool doublesided) + { + return FMOD5_Geometry_SetPolygonAttributes(this.handle, index, directocclusion, reverbocclusion, doublesided); + } + public RESULT getPolygonAttributes(int index, out float directocclusion, out float reverbocclusion, out bool doublesided) + { + return FMOD5_Geometry_GetPolygonAttributes(this.handle, index, out directocclusion, out reverbocclusion, out doublesided); + } + + // Object manipulation. + public RESULT setActive(bool active) + { + return FMOD5_Geometry_SetActive(this.handle, active); + } + public RESULT getActive(out bool active) + { + return FMOD5_Geometry_GetActive(this.handle, out active); + } + public RESULT setRotation(ref VECTOR forward, ref VECTOR up) + { + return FMOD5_Geometry_SetRotation(this.handle, ref forward, ref up); + } + public RESULT getRotation(out VECTOR forward, out VECTOR up) + { + return FMOD5_Geometry_GetRotation(this.handle, out forward, out up); + } + public RESULT setPosition(ref VECTOR position) + { + return FMOD5_Geometry_SetPosition(this.handle, ref position); + } + public RESULT getPosition(out VECTOR position) + { + return FMOD5_Geometry_GetPosition(this.handle, out position); + } + public RESULT setScale(ref VECTOR scale) + { + return FMOD5_Geometry_SetScale(this.handle, ref scale); + } + public RESULT getScale(out VECTOR scale) + { + return FMOD5_Geometry_GetScale(this.handle, out scale); + } + public RESULT save(IntPtr data, out int datasize) + { + return FMOD5_Geometry_Save(this.handle, data, out datasize); + } + + // Userdata set/get. + public RESULT setUserData(IntPtr userdata) + { + return FMOD5_Geometry_SetUserData(this.handle, userdata); + } + public RESULT getUserData(out IntPtr userdata) + { + return FMOD5_Geometry_GetUserData(this.handle, out userdata); + } + + #region importfunctions + [DllImport(VERSION.dll)] + private static extern RESULT FMOD5_Geometry_Release (IntPtr geometry); + [DllImport(VERSION.dll)] + private static extern RESULT FMOD5_Geometry_AddPolygon (IntPtr geometry, float directocclusion, float reverbocclusion, bool doublesided, int numvertices, VECTOR[] vertices, out int polygonindex); + [DllImport(VERSION.dll)] + private static extern RESULT FMOD5_Geometry_GetNumPolygons (IntPtr geometry, out int numpolygons); + [DllImport(VERSION.dll)] + private static extern RESULT FMOD5_Geometry_GetMaxPolygons (IntPtr geometry, out int maxpolygons, out int maxvertices); + [DllImport(VERSION.dll)] + private static extern RESULT FMOD5_Geometry_GetPolygonNumVertices(IntPtr geometry, int index, out int numvertices); + [DllImport(VERSION.dll)] + private static extern RESULT FMOD5_Geometry_SetPolygonVertex (IntPtr geometry, int index, int vertexindex, ref VECTOR vertex); + [DllImport(VERSION.dll)] + private static extern RESULT FMOD5_Geometry_GetPolygonVertex (IntPtr geometry, int index, int vertexindex, out VECTOR vertex); + [DllImport(VERSION.dll)] + private static extern RESULT FMOD5_Geometry_SetPolygonAttributes (IntPtr geometry, int index, float directocclusion, float reverbocclusion, bool doublesided); + [DllImport(VERSION.dll)] + private static extern RESULT FMOD5_Geometry_GetPolygonAttributes (IntPtr geometry, int index, out float directocclusion, out float reverbocclusion, out bool doublesided); + [DllImport(VERSION.dll)] + private static extern RESULT FMOD5_Geometry_SetActive (IntPtr geometry, bool active); + [DllImport(VERSION.dll)] + private static extern RESULT FMOD5_Geometry_GetActive (IntPtr geometry, out bool active); + [DllImport(VERSION.dll)] + private static extern RESULT FMOD5_Geometry_SetRotation (IntPtr geometry, ref VECTOR forward, ref VECTOR up); + [DllImport(VERSION.dll)] + private static extern RESULT FMOD5_Geometry_GetRotation (IntPtr geometry, out VECTOR forward, out VECTOR up); + [DllImport(VERSION.dll)] + private static extern RESULT FMOD5_Geometry_SetPosition (IntPtr geometry, ref VECTOR position); + [DllImport(VERSION.dll)] + private static extern RESULT FMOD5_Geometry_GetPosition (IntPtr geometry, out VECTOR position); + [DllImport(VERSION.dll)] + private static extern RESULT FMOD5_Geometry_SetScale (IntPtr geometry, ref VECTOR scale); + [DllImport(VERSION.dll)] + private static extern RESULT FMOD5_Geometry_GetScale (IntPtr geometry, out VECTOR scale); + [DllImport(VERSION.dll)] + private static extern RESULT FMOD5_Geometry_Save (IntPtr geometry, IntPtr data, out int datasize); + [DllImport(VERSION.dll)] + private static extern RESULT FMOD5_Geometry_SetUserData (IntPtr geometry, IntPtr userdata); + [DllImport(VERSION.dll)] + private static extern RESULT FMOD5_Geometry_GetUserData (IntPtr geometry, out IntPtr userdata); + #endregion + + #region wrapperinternal + + public IntPtr handle; + + public Geometry(IntPtr ptr) { this.handle = ptr; } + public bool hasHandle() { return this.handle != IntPtr.Zero; } + public void clearHandle() { this.handle = IntPtr.Zero; } + + #endregion + } + + /* + 'Reverb3D' API + */ + public struct Reverb3D + { + public RESULT release() + { + return FMOD5_Reverb3D_Release(this.handle); + } + + // Reverb manipulation. + public RESULT set3DAttributes(ref VECTOR position, float mindistance, float maxdistance) + { + return FMOD5_Reverb3D_Set3DAttributes(this.handle, ref position, mindistance, maxdistance); + } + public RESULT get3DAttributes(ref VECTOR position, ref float mindistance, ref float maxdistance) + { + return FMOD5_Reverb3D_Get3DAttributes(this.handle, ref position, ref mindistance, ref maxdistance); + } + public RESULT setProperties(ref REVERB_PROPERTIES properties) + { + return FMOD5_Reverb3D_SetProperties(this.handle, ref properties); + } + public RESULT getProperties(ref REVERB_PROPERTIES properties) + { + return FMOD5_Reverb3D_GetProperties(this.handle, ref properties); + } + public RESULT setActive(bool active) + { + return FMOD5_Reverb3D_SetActive(this.handle, active); + } + public RESULT getActive(out bool active) + { + return FMOD5_Reverb3D_GetActive(this.handle, out active); + } + + // Userdata set/get. + public RESULT setUserData(IntPtr userdata) + { + return FMOD5_Reverb3D_SetUserData(this.handle, userdata); + } + public RESULT getUserData(out IntPtr userdata) + { + return FMOD5_Reverb3D_GetUserData(this.handle, out userdata); + } + + #region importfunctions + [DllImport(VERSION.dll)] + private static extern RESULT FMOD5_Reverb3D_Release (IntPtr reverb3d); + [DllImport(VERSION.dll)] + private static extern RESULT FMOD5_Reverb3D_Set3DAttributes (IntPtr reverb3d, ref VECTOR position, float mindistance, float maxdistance); + [DllImport(VERSION.dll)] + private static extern RESULT FMOD5_Reverb3D_Get3DAttributes (IntPtr reverb3d, ref VECTOR position, ref float mindistance, ref float maxdistance); + [DllImport(VERSION.dll)] + private static extern RESULT FMOD5_Reverb3D_SetProperties (IntPtr reverb3d, ref REVERB_PROPERTIES properties); + [DllImport(VERSION.dll)] + private static extern RESULT FMOD5_Reverb3D_GetProperties (IntPtr reverb3d, ref REVERB_PROPERTIES properties); + [DllImport(VERSION.dll)] + private static extern RESULT FMOD5_Reverb3D_SetActive (IntPtr reverb3d, bool active); + [DllImport(VERSION.dll)] + private static extern RESULT FMOD5_Reverb3D_GetActive (IntPtr reverb3d, out bool active); + [DllImport(VERSION.dll)] + private static extern RESULT FMOD5_Reverb3D_SetUserData (IntPtr reverb3d, IntPtr userdata); + [DllImport(VERSION.dll)] + private static extern RESULT FMOD5_Reverb3D_GetUserData (IntPtr reverb3d, out IntPtr userdata); + #endregion + + #region wrapperinternal + + public IntPtr handle; + + public Reverb3D(IntPtr ptr) { this.handle = ptr; } + public bool hasHandle() { return this.handle != IntPtr.Zero; } + public void clearHandle() { this.handle = IntPtr.Zero; } + + #endregion + } + + #region Helper Functions + [StructLayout(LayoutKind.Sequential)] + public struct StringWrapper + { + IntPtr nativeUtf8Ptr; + + public StringWrapper(IntPtr ptr) + { + nativeUtf8Ptr = ptr; + } + + public static implicit operator string(StringWrapper fstring) + { + using (StringHelper.ThreadSafeEncoding encoder = StringHelper.GetFreeHelper()) + { + return encoder.stringFromNative(fstring.nativeUtf8Ptr); + } + } + + public bool StartsWith(byte[] prefix) + { + if (nativeUtf8Ptr == IntPtr.Zero) + { + return false; + } + + for (int i = 0; i < prefix.Length; i++) + { + if (Marshal.ReadByte(nativeUtf8Ptr, i) != prefix[i]) + { + return false; + } + } + + return true; + } + + public bool Equals(byte[] comparison) + { + if (nativeUtf8Ptr == IntPtr.Zero) + { + return false; + } + + for (int i = 0; i < comparison.Length; i++) + { + if (Marshal.ReadByte(nativeUtf8Ptr, i) != comparison[i]) + { + return false; + } + } + + if (Marshal.ReadByte(nativeUtf8Ptr, comparison.Length) != 0) + { + return false; + } + + return true; + } + } + + static class StringHelper + { + public class ThreadSafeEncoding : IDisposable + { + UTF8Encoding encoding = new UTF8Encoding(); + byte[] encodedBuffer = new byte[128]; + char[] decodedBuffer = new char[128]; + bool inUse; + GCHandle gcHandle; + + public bool InUse() { return inUse; } + public void SetInUse() { inUse = true; } + + private int roundUpPowerTwo(int number) + { + int newNumber = 1; + while (newNumber <= number) + { + newNumber *= 2; + } + + return newNumber; + } + + public byte[] byteFromStringUTF8(string s) + { + if (s == null) + { + return null; + } + + int maximumLength = encoding.GetMaxByteCount(s.Length) + 1; // +1 for null terminator + if (maximumLength > encodedBuffer.Length) + { + int encodedLength = encoding.GetByteCount(s) + 1; // +1 for null terminator + if (encodedLength > encodedBuffer.Length) + { + encodedBuffer = new byte[roundUpPowerTwo(encodedLength)]; + } + } + + int byteCount = encoding.GetBytes(s, 0, s.Length, encodedBuffer, 0); + encodedBuffer[byteCount] = 0; // Apply null terminator + + return encodedBuffer; + } + + public IntPtr intptrFromStringUTF8(string s) + { + if (s == null) + { + return IntPtr.Zero; + } + + gcHandle = GCHandle.Alloc(byteFromStringUTF8(s), GCHandleType.Pinned); + return gcHandle.AddrOfPinnedObject(); + } + + public string stringFromNative(IntPtr nativePtr) + { + if (nativePtr == IntPtr.Zero) + { + return ""; + } + + int nativeLen = 0; + while (Marshal.ReadByte(nativePtr, nativeLen) != 0) + { + nativeLen++; + } + + if (nativeLen == 0) + { + return ""; + } + + if (nativeLen > encodedBuffer.Length) + { + encodedBuffer = new byte[roundUpPowerTwo(nativeLen)]; + } + + Marshal.Copy(nativePtr, encodedBuffer, 0, nativeLen); + + int maximumLength = encoding.GetMaxCharCount(nativeLen); + if (maximumLength > decodedBuffer.Length) + { + int decodedLength = encoding.GetCharCount(encodedBuffer, 0, nativeLen); + if (decodedLength > decodedBuffer.Length) + { + decodedBuffer = new char[roundUpPowerTwo(decodedLength)]; + } + } + + int charCount = encoding.GetChars(encodedBuffer, 0, nativeLen, decodedBuffer, 0); + + return new String(decodedBuffer, 0, charCount); + } + + public void Dispose() + { + if (gcHandle.IsAllocated) + { + gcHandle.Free(); + } + lock (encoders) + { + inUse = false; + } + } + } + + static List encoders = new List(1); + + public static ThreadSafeEncoding GetFreeHelper() + { + lock (encoders) + { + ThreadSafeEncoding helper = null; + // Search for not in use helper + for (int i = 0; i < encoders.Count; i++) + { + if (!encoders[i].InUse()) + { + helper = encoders[i]; + break; + } + } + // Otherwise create another helper + if (helper == null) + { + helper = new ThreadSafeEncoding(); + encoders.Add(helper); + } + helper.SetInUse(); + return helper; + } + } + } + + #endregion +} diff --git a/FMOD/api/core/inc/fmod.h b/FMOD/api/core/inc/fmod.h new file mode 100644 index 0000000..89eaac7 --- /dev/null +++ b/FMOD/api/core/inc/fmod.h @@ -0,0 +1,670 @@ +/* ======================================================================================== */ +/* FMOD Core API - C header file. */ +/* Copyright (c), Firelight Technologies Pty, Ltd. 2004-2026. */ +/* */ +/* Use this header in conjunction with fmod_common.h (which contains all the constants / */ +/* callbacks) to develop using the C interface */ +/* */ +/* For more detail visit: */ +/* https://fmod.com/docs/2.03/api/core-api.html */ +/* ======================================================================================== */ + +#ifndef _FMOD_H +#define _FMOD_H + +#include "fmod_common.h" + +#ifdef __cplusplus +extern "C" +{ +#endif + +/* + FMOD global system functions (optional). +*/ +FMOD_RESULT F_API FMOD_Memory_Initialize (void *poolmem, int poollen, FMOD_MEMORY_ALLOC_CALLBACK useralloc, FMOD_MEMORY_REALLOC_CALLBACK userrealloc, FMOD_MEMORY_FREE_CALLBACK userfree, FMOD_MEMORY_TYPE memtypeflags); +FMOD_RESULT F_API FMOD_Memory_GetStats (int *currentalloced, int *maxalloced, FMOD_BOOL blocking); +FMOD_RESULT F_API FMOD_Debug_Initialize (FMOD_DEBUG_FLAGS flags, FMOD_DEBUG_MODE mode, FMOD_DEBUG_CALLBACK callback, const char *filename); +FMOD_RESULT F_API FMOD_File_SetDiskBusy (int busy); +FMOD_RESULT F_API FMOD_File_GetDiskBusy (int *busy); +FMOD_RESULT F_API FMOD_Thread_SetAttributes (FMOD_THREAD_TYPE type, FMOD_THREAD_AFFINITY affinity, FMOD_THREAD_PRIORITY priority, FMOD_THREAD_STACK_SIZE stacksize); + +/* + FMOD System factory functions. Use this to create an FMOD System Instance. below you will see FMOD_System_Init/Close to get started. +*/ +FMOD_RESULT F_API FMOD_System_Create (FMOD_SYSTEM **system, unsigned int headerversion); +FMOD_RESULT F_API FMOD_System_Release (FMOD_SYSTEM *system); + +/* + 'System' API +*/ + +/* Setup functions. */ +FMOD_RESULT F_API FMOD_System_SetOutput (FMOD_SYSTEM *system, FMOD_OUTPUTTYPE output); +FMOD_RESULT F_API FMOD_System_GetOutput (FMOD_SYSTEM *system, FMOD_OUTPUTTYPE *output); +FMOD_RESULT F_API FMOD_System_GetNumDrivers (FMOD_SYSTEM *system, int *numdrivers); +FMOD_RESULT F_API FMOD_System_GetDriverInfo (FMOD_SYSTEM *system, int id, char *name, int namelen, FMOD_GUID *guid, int *systemrate, FMOD_SPEAKERMODE *speakermode, int *speakermodechannels); +FMOD_RESULT F_API FMOD_System_SetDriver (FMOD_SYSTEM *system, int driver); +FMOD_RESULT F_API FMOD_System_GetDriver (FMOD_SYSTEM *system, int *driver); +FMOD_RESULT F_API FMOD_System_SetSoftwareChannels (FMOD_SYSTEM *system, int numsoftwarechannels); +FMOD_RESULT F_API FMOD_System_GetSoftwareChannels (FMOD_SYSTEM *system, int *numsoftwarechannels); +FMOD_RESULT F_API FMOD_System_SetSoftwareFormat (FMOD_SYSTEM *system, int samplerate, FMOD_SPEAKERMODE speakermode, int numrawspeakers); +FMOD_RESULT F_API FMOD_System_GetSoftwareFormat (FMOD_SYSTEM *system, int *samplerate, FMOD_SPEAKERMODE *speakermode, int *numrawspeakers); +FMOD_RESULT F_API FMOD_System_SetDSPBufferSize (FMOD_SYSTEM *system, unsigned int bufferlength, int numbuffers); +FMOD_RESULT F_API FMOD_System_GetDSPBufferSize (FMOD_SYSTEM *system, unsigned int *bufferlength, int *numbuffers); +FMOD_RESULT F_API FMOD_System_SetFileSystem (FMOD_SYSTEM *system, FMOD_FILE_OPEN_CALLBACK useropen, FMOD_FILE_CLOSE_CALLBACK userclose, FMOD_FILE_READ_CALLBACK userread, FMOD_FILE_SEEK_CALLBACK userseek, FMOD_FILE_ASYNCREAD_CALLBACK userasyncread, FMOD_FILE_ASYNCCANCEL_CALLBACK userasynccancel, int blockalign); +FMOD_RESULT F_API FMOD_System_AttachFileSystem (FMOD_SYSTEM *system, FMOD_FILE_OPEN_CALLBACK useropen, FMOD_FILE_CLOSE_CALLBACK userclose, FMOD_FILE_READ_CALLBACK userread, FMOD_FILE_SEEK_CALLBACK userseek); +FMOD_RESULT F_API FMOD_System_SetAdvancedSettings (FMOD_SYSTEM *system, FMOD_ADVANCEDSETTINGS *settings); +FMOD_RESULT F_API FMOD_System_GetAdvancedSettings (FMOD_SYSTEM *system, FMOD_ADVANCEDSETTINGS *settings); +FMOD_RESULT F_API FMOD_System_SetCallback (FMOD_SYSTEM *system, FMOD_SYSTEM_CALLBACK callback, FMOD_SYSTEM_CALLBACK_TYPE callbackmask); + +/* Plug-in support. */ +FMOD_RESULT F_API FMOD_System_SetPluginPath (FMOD_SYSTEM *system, const char *path); +FMOD_RESULT F_API FMOD_System_LoadPlugin (FMOD_SYSTEM *system, const char *filename, unsigned int *handle, unsigned int priority); +FMOD_RESULT F_API FMOD_System_UnloadPlugin (FMOD_SYSTEM *system, unsigned int handle); +FMOD_RESULT F_API FMOD_System_GetNumNestedPlugins (FMOD_SYSTEM *system, unsigned int handle, int *count); +FMOD_RESULT F_API FMOD_System_GetNestedPlugin (FMOD_SYSTEM *system, unsigned int handle, int index, unsigned int *nestedhandle); +FMOD_RESULT F_API FMOD_System_GetNumPlugins (FMOD_SYSTEM *system, FMOD_PLUGINTYPE plugintype, int *numplugins); +FMOD_RESULT F_API FMOD_System_GetPluginHandle (FMOD_SYSTEM *system, FMOD_PLUGINTYPE plugintype, int index, unsigned int *handle); +FMOD_RESULT F_API FMOD_System_GetPluginInfo (FMOD_SYSTEM *system, unsigned int handle, FMOD_PLUGINTYPE *plugintype, char *name, int namelen, unsigned int *version); +FMOD_RESULT F_API FMOD_System_SetOutputByPlugin (FMOD_SYSTEM *system, unsigned int handle); +FMOD_RESULT F_API FMOD_System_GetOutputByPlugin (FMOD_SYSTEM *system, unsigned int *handle); +FMOD_RESULT F_API FMOD_System_CreateDSPByPlugin (FMOD_SYSTEM *system, unsigned int handle, FMOD_DSP **dsp); +FMOD_RESULT F_API FMOD_System_GetDSPInfoByPlugin (FMOD_SYSTEM *system, unsigned int handle, const FMOD_DSP_DESCRIPTION **description); +FMOD_RESULT F_API FMOD_System_RegisterCodec (FMOD_SYSTEM *system, FMOD_CODEC_DESCRIPTION *description, unsigned int *handle, unsigned int priority); +FMOD_RESULT F_API FMOD_System_RegisterDSP (FMOD_SYSTEM *system, const FMOD_DSP_DESCRIPTION *description, unsigned int *handle); +FMOD_RESULT F_API FMOD_System_RegisterOutput (FMOD_SYSTEM *system, const FMOD_OUTPUT_DESCRIPTION *description, unsigned int *handle); + +/* Init/Close. */ +FMOD_RESULT F_API FMOD_System_Init (FMOD_SYSTEM *system, int maxchannels, FMOD_INITFLAGS flags, void *extradriverdata); +FMOD_RESULT F_API FMOD_System_Close (FMOD_SYSTEM *system); + +/* General post-init system functions. */ +FMOD_RESULT F_API FMOD_System_Update (FMOD_SYSTEM *system); +FMOD_RESULT F_API FMOD_System_SetSpeakerPosition (FMOD_SYSTEM *system, FMOD_SPEAKER speaker, float x, float y, FMOD_BOOL active); +FMOD_RESULT F_API FMOD_System_GetSpeakerPosition (FMOD_SYSTEM *system, FMOD_SPEAKER speaker, float *x, float *y, FMOD_BOOL *active); +FMOD_RESULT F_API FMOD_System_SetStreamBufferSize (FMOD_SYSTEM *system, unsigned int filebuffersize, FMOD_TIMEUNIT filebuffersizetype); +FMOD_RESULT F_API FMOD_System_GetStreamBufferSize (FMOD_SYSTEM *system, unsigned int *filebuffersize, FMOD_TIMEUNIT *filebuffersizetype); +FMOD_RESULT F_API FMOD_System_Set3DSettings (FMOD_SYSTEM *system, float dopplerscale, float distancefactor, float rolloffscale); +FMOD_RESULT F_API FMOD_System_Get3DSettings (FMOD_SYSTEM *system, float *dopplerscale, float *distancefactor, float *rolloffscale); +FMOD_RESULT F_API FMOD_System_Set3DNumListeners (FMOD_SYSTEM *system, int numlisteners); +FMOD_RESULT F_API FMOD_System_Get3DNumListeners (FMOD_SYSTEM *system, int *numlisteners); +FMOD_RESULT F_API FMOD_System_Set3DListenerAttributes (FMOD_SYSTEM *system, int listener, const FMOD_VECTOR *pos, const FMOD_VECTOR *vel, const FMOD_VECTOR *forward, const FMOD_VECTOR *up); +FMOD_RESULT F_API FMOD_System_Get3DListenerAttributes (FMOD_SYSTEM *system, int listener, FMOD_VECTOR *pos, FMOD_VECTOR *vel, FMOD_VECTOR *forward, FMOD_VECTOR *up); +FMOD_RESULT F_API FMOD_System_Set3DRolloffCallback (FMOD_SYSTEM *system, FMOD_3D_ROLLOFF_CALLBACK callback); +FMOD_RESULT F_API FMOD_System_MixerSuspend (FMOD_SYSTEM *system); +FMOD_RESULT F_API FMOD_System_MixerResume (FMOD_SYSTEM *system); +FMOD_RESULT F_API FMOD_System_GetDefaultMixMatrix (FMOD_SYSTEM *system, FMOD_SPEAKERMODE sourcespeakermode, FMOD_SPEAKERMODE targetspeakermode, float *matrix, int matrixhop); +FMOD_RESULT F_API FMOD_System_GetSpeakerModeChannels (FMOD_SYSTEM *system, FMOD_SPEAKERMODE mode, int *channels); + +/* System information functions. */ +FMOD_RESULT F_API FMOD_System_GetVersion (FMOD_SYSTEM *system, unsigned int *version, unsigned int *buildnumber); +FMOD_RESULT F_API FMOD_System_GetOutputHandle (FMOD_SYSTEM *system, void **handle); +FMOD_RESULT F_API FMOD_System_GetChannelsPlaying (FMOD_SYSTEM *system, int *channels, int *realchannels); +FMOD_RESULT F_API FMOD_System_GetCPUUsage (FMOD_SYSTEM *system, FMOD_CPU_USAGE *usage); +FMOD_RESULT F_API FMOD_System_GetFileUsage (FMOD_SYSTEM *system, long long *sampleBytesRead, long long *streamBytesRead, long long *otherBytesRead); + +/* Sound/DSP/Channel/FX creation and retrieval. */ +FMOD_RESULT F_API FMOD_System_CreateSound (FMOD_SYSTEM *system, const char *name_or_data, FMOD_MODE mode, FMOD_CREATESOUNDEXINFO *exinfo, FMOD_SOUND **sound); +FMOD_RESULT F_API FMOD_System_CreateStream (FMOD_SYSTEM *system, const char *name_or_data, FMOD_MODE mode, FMOD_CREATESOUNDEXINFO *exinfo, FMOD_SOUND **sound); +FMOD_RESULT F_API FMOD_System_CreateDSP (FMOD_SYSTEM *system, const FMOD_DSP_DESCRIPTION *description, FMOD_DSP **dsp); +FMOD_RESULT F_API FMOD_System_CreateDSPByType (FMOD_SYSTEM *system, FMOD_DSP_TYPE type, FMOD_DSP **dsp); +FMOD_RESULT F_API FMOD_System_CreateDSPConnection (FMOD_SYSTEM *system, FMOD_DSPCONNECTION_TYPE type, FMOD_DSPCONNECTION **connection); +FMOD_RESULT F_API FMOD_System_CreateChannelGroup (FMOD_SYSTEM *system, const char *name, FMOD_CHANNELGROUP **channelgroup); +FMOD_RESULT F_API FMOD_System_CreateSoundGroup (FMOD_SYSTEM *system, const char *name, FMOD_SOUNDGROUP **soundgroup); +FMOD_RESULT F_API FMOD_System_CreateReverb3D (FMOD_SYSTEM *system, FMOD_REVERB3D **reverb); +FMOD_RESULT F_API FMOD_System_PlaySound (FMOD_SYSTEM *system, FMOD_SOUND *sound, FMOD_CHANNELGROUP *channelgroup, FMOD_BOOL paused, FMOD_CHANNEL **channel); +FMOD_RESULT F_API FMOD_System_PlayDSP (FMOD_SYSTEM *system, FMOD_DSP *dsp, FMOD_CHANNELGROUP *channelgroup, FMOD_BOOL paused, FMOD_CHANNEL **channel); +FMOD_RESULT F_API FMOD_System_GetChannel (FMOD_SYSTEM *system, int channelid, FMOD_CHANNEL **channel); +FMOD_RESULT F_API FMOD_System_GetDSPInfoByType (FMOD_SYSTEM *system, FMOD_DSP_TYPE type, const FMOD_DSP_DESCRIPTION **description); +FMOD_RESULT F_API FMOD_System_GetMasterChannelGroup (FMOD_SYSTEM *system, FMOD_CHANNELGROUP **channelgroup); +FMOD_RESULT F_API FMOD_System_GetMasterSoundGroup (FMOD_SYSTEM *system, FMOD_SOUNDGROUP **soundgroup); + +/* Routing to ports. */ +FMOD_RESULT F_API FMOD_System_AttachChannelGroupToPort (FMOD_SYSTEM *system, FMOD_PORT_TYPE portType, FMOD_PORT_INDEX portIndex, FMOD_CHANNELGROUP *channelgroup, FMOD_BOOL passThru); +FMOD_RESULT F_API FMOD_System_DetachChannelGroupFromPort(FMOD_SYSTEM *system, FMOD_CHANNELGROUP *channelgroup); + +/* Reverb API. */ +FMOD_RESULT F_API FMOD_System_SetReverbProperties (FMOD_SYSTEM *system, int instance, const FMOD_REVERB_PROPERTIES *prop); +FMOD_RESULT F_API FMOD_System_GetReverbProperties (FMOD_SYSTEM *system, int instance, FMOD_REVERB_PROPERTIES *prop); + +/* System level DSP functionality. */ +FMOD_RESULT F_API FMOD_System_LockDSP (FMOD_SYSTEM *system); +FMOD_RESULT F_API FMOD_System_UnlockDSP (FMOD_SYSTEM *system); + +/* Recording API. */ +FMOD_RESULT F_API FMOD_System_GetRecordNumDrivers (FMOD_SYSTEM *system, int *numdrivers, int *numconnected); +FMOD_RESULT F_API FMOD_System_GetRecordDriverInfo (FMOD_SYSTEM *system, int id, char *name, int namelen, FMOD_GUID *guid, int *systemrate, FMOD_SPEAKERMODE *speakermode, int *speakermodechannels, FMOD_DRIVER_STATE *state); +FMOD_RESULT F_API FMOD_System_GetRecordPosition (FMOD_SYSTEM *system, int id, unsigned int *position); +FMOD_RESULT F_API FMOD_System_RecordStart (FMOD_SYSTEM *system, int id, FMOD_SOUND *sound, FMOD_BOOL loop); +FMOD_RESULT F_API FMOD_System_RecordStop (FMOD_SYSTEM *system, int id); +FMOD_RESULT F_API FMOD_System_IsRecording (FMOD_SYSTEM *system, int id, FMOD_BOOL *recording); + +/* Geometry API. */ +FMOD_RESULT F_API FMOD_System_CreateGeometry (FMOD_SYSTEM *system, int maxpolygons, int maxvertices, FMOD_GEOMETRY **geometry); +FMOD_RESULT F_API FMOD_System_SetGeometrySettings (FMOD_SYSTEM *system, float maxworldsize); +FMOD_RESULT F_API FMOD_System_GetGeometrySettings (FMOD_SYSTEM *system, float *maxworldsize); +FMOD_RESULT F_API FMOD_System_LoadGeometry (FMOD_SYSTEM *system, const void *data, int datasize, FMOD_GEOMETRY **geometry); +FMOD_RESULT F_API FMOD_System_GetGeometryOcclusion (FMOD_SYSTEM *system, const FMOD_VECTOR *listener, const FMOD_VECTOR *source, float *direct, float *reverb); + +/* Network functions. */ +FMOD_RESULT F_API FMOD_System_SetNetworkProxy (FMOD_SYSTEM *system, const char *proxy); +FMOD_RESULT F_API FMOD_System_GetNetworkProxy (FMOD_SYSTEM *system, char *proxy, int proxylen); +FMOD_RESULT F_API FMOD_System_SetNetworkTimeout (FMOD_SYSTEM *system, int timeout); +FMOD_RESULT F_API FMOD_System_GetNetworkTimeout (FMOD_SYSTEM *system, int *timeout); + +/* Userdata set/get. */ +FMOD_RESULT F_API FMOD_System_SetUserData (FMOD_SYSTEM *system, void *userdata); +FMOD_RESULT F_API FMOD_System_GetUserData (FMOD_SYSTEM *system, void **userdata); + +/* Sound API +*/ + +FMOD_RESULT F_API FMOD_Sound_Release (FMOD_SOUND *sound); +FMOD_RESULT F_API FMOD_Sound_GetSystemObject (FMOD_SOUND *sound, FMOD_SYSTEM **system); + +/* + Standard sound manipulation functions. +*/ + +FMOD_RESULT F_API FMOD_Sound_Lock (FMOD_SOUND *sound, unsigned int offset, unsigned int length, void **ptr1, void **ptr2, unsigned int *len1, unsigned int *len2); +FMOD_RESULT F_API FMOD_Sound_Unlock (FMOD_SOUND *sound, void *ptr1, void *ptr2, unsigned int len1, unsigned int len2); +FMOD_RESULT F_API FMOD_Sound_SetDefaults (FMOD_SOUND *sound, float frequency, int priority); +FMOD_RESULT F_API FMOD_Sound_GetDefaults (FMOD_SOUND *sound, float *frequency, int *priority); +FMOD_RESULT F_API FMOD_Sound_Set3DMinMaxDistance (FMOD_SOUND *sound, float min, float max); +FMOD_RESULT F_API FMOD_Sound_Get3DMinMaxDistance (FMOD_SOUND *sound, float *min, float *max); +FMOD_RESULT F_API FMOD_Sound_Set3DConeSettings (FMOD_SOUND *sound, float insideconeangle, float outsideconeangle, float outsidevolume); +FMOD_RESULT F_API FMOD_Sound_Get3DConeSettings (FMOD_SOUND *sound, float *insideconeangle, float *outsideconeangle, float *outsidevolume); +FMOD_RESULT F_API FMOD_Sound_Set3DCustomRolloff (FMOD_SOUND *sound, FMOD_VECTOR *points, int numpoints); +FMOD_RESULT F_API FMOD_Sound_Get3DCustomRolloff (FMOD_SOUND *sound, FMOD_VECTOR **points, int *numpoints); +FMOD_RESULT F_API FMOD_Sound_GetSubSound (FMOD_SOUND *sound, int index, FMOD_SOUND **subsound); +FMOD_RESULT F_API FMOD_Sound_GetSubSoundParent (FMOD_SOUND *sound, FMOD_SOUND **parentsound); +FMOD_RESULT F_API FMOD_Sound_GetName (FMOD_SOUND *sound, char *name, int namelen); +FMOD_RESULT F_API FMOD_Sound_GetLength (FMOD_SOUND *sound, unsigned int *length, FMOD_TIMEUNIT lengthtype); +FMOD_RESULT F_API FMOD_Sound_GetFormat (FMOD_SOUND *sound, FMOD_SOUND_TYPE *type, FMOD_SOUND_FORMAT *format, int *channels, int *bits); +FMOD_RESULT F_API FMOD_Sound_GetNumSubSounds (FMOD_SOUND *sound, int *numsubsounds); +FMOD_RESULT F_API FMOD_Sound_GetNumTags (FMOD_SOUND *sound, int *numtags, int *numtagsupdated); +FMOD_RESULT F_API FMOD_Sound_GetTag (FMOD_SOUND *sound, const char *name, int index, FMOD_TAG *tag); +FMOD_RESULT F_API FMOD_Sound_GetOpenState (FMOD_SOUND *sound, FMOD_OPENSTATE *openstate, unsigned int *percentbuffered, FMOD_BOOL *starving, FMOD_BOOL *diskbusy); +FMOD_RESULT F_API FMOD_Sound_ReadData (FMOD_SOUND *sound, void *buffer, unsigned int length, unsigned int *read); +FMOD_RESULT F_API FMOD_Sound_SeekData (FMOD_SOUND *sound, unsigned int pcm); + +FMOD_RESULT F_API FMOD_Sound_SetSoundGroup (FMOD_SOUND *sound, FMOD_SOUNDGROUP *soundgroup); +FMOD_RESULT F_API FMOD_Sound_GetSoundGroup (FMOD_SOUND *sound, FMOD_SOUNDGROUP **soundgroup); + +/* + Synchronization point API. These points can come from markers embedded in wav files, and can also generate channel callbacks. +*/ + +FMOD_RESULT F_API FMOD_Sound_GetNumSyncPoints (FMOD_SOUND *sound, int *numsyncpoints); +FMOD_RESULT F_API FMOD_Sound_GetSyncPoint (FMOD_SOUND *sound, int index, FMOD_SYNCPOINT **point); +FMOD_RESULT F_API FMOD_Sound_GetSyncPointInfo (FMOD_SOUND *sound, FMOD_SYNCPOINT *point, char *name, int namelen, unsigned int *offset, FMOD_TIMEUNIT offsettype); +FMOD_RESULT F_API FMOD_Sound_AddSyncPoint (FMOD_SOUND *sound, unsigned int offset, FMOD_TIMEUNIT offsettype, const char *name, FMOD_SYNCPOINT **point); +FMOD_RESULT F_API FMOD_Sound_DeleteSyncPoint (FMOD_SOUND *sound, FMOD_SYNCPOINT *point); + +/* + Functions also in Channel class but here they are the 'default' to save having to change it in Channel all the time. +*/ + +FMOD_RESULT F_API FMOD_Sound_SetMode (FMOD_SOUND *sound, FMOD_MODE mode); +FMOD_RESULT F_API FMOD_Sound_GetMode (FMOD_SOUND *sound, FMOD_MODE *mode); +FMOD_RESULT F_API FMOD_Sound_SetLoopCount (FMOD_SOUND *sound, int loopcount); +FMOD_RESULT F_API FMOD_Sound_GetLoopCount (FMOD_SOUND *sound, int *loopcount); +FMOD_RESULT F_API FMOD_Sound_SetLoopPoints (FMOD_SOUND *sound, unsigned int loopstart, FMOD_TIMEUNIT loopstarttype, unsigned int loopend, FMOD_TIMEUNIT loopendtype); +FMOD_RESULT F_API FMOD_Sound_GetLoopPoints (FMOD_SOUND *sound, unsigned int *loopstart, FMOD_TIMEUNIT loopstarttype, unsigned int *loopend, FMOD_TIMEUNIT loopendtype); + +/* + For MOD/S3M/XM/IT/MID sequenced formats only. +*/ + +FMOD_RESULT F_API FMOD_Sound_GetMusicNumChannels (FMOD_SOUND *sound, int *numchannels); +FMOD_RESULT F_API FMOD_Sound_SetMusicChannelVolume (FMOD_SOUND *sound, int channel, float volume); +FMOD_RESULT F_API FMOD_Sound_GetMusicChannelVolume (FMOD_SOUND *sound, int channel, float *volume); +FMOD_RESULT F_API FMOD_Sound_SetMusicSpeed (FMOD_SOUND *sound, float speed); +FMOD_RESULT F_API FMOD_Sound_GetMusicSpeed (FMOD_SOUND *sound, float *speed); + +/* + Userdata set/get. +*/ + +FMOD_RESULT F_API FMOD_Sound_SetUserData (FMOD_SOUND *sound, void *userdata); +FMOD_RESULT F_API FMOD_Sound_GetUserData (FMOD_SOUND *sound, void **userdata); + +/* + 'Channel' API +*/ + +FMOD_RESULT F_API FMOD_Channel_GetSystemObject (FMOD_CHANNEL *channel, FMOD_SYSTEM **system); + +/* + General control functionality for Channels and ChannelGroups. +*/ + +FMOD_RESULT F_API FMOD_Channel_Stop (FMOD_CHANNEL *channel); +FMOD_RESULT F_API FMOD_Channel_SetPaused (FMOD_CHANNEL *channel, FMOD_BOOL paused); +FMOD_RESULT F_API FMOD_Channel_GetPaused (FMOD_CHANNEL *channel, FMOD_BOOL *paused); +FMOD_RESULT F_API FMOD_Channel_SetVolume (FMOD_CHANNEL *channel, float volume); +FMOD_RESULT F_API FMOD_Channel_GetVolume (FMOD_CHANNEL *channel, float *volume); +FMOD_RESULT F_API FMOD_Channel_SetVolumeRamp (FMOD_CHANNEL *channel, FMOD_BOOL ramp); +FMOD_RESULT F_API FMOD_Channel_GetVolumeRamp (FMOD_CHANNEL *channel, FMOD_BOOL *ramp); +FMOD_RESULT F_API FMOD_Channel_GetAudibility (FMOD_CHANNEL *channel, float *audibility); +FMOD_RESULT F_API FMOD_Channel_SetPitch (FMOD_CHANNEL *channel, float pitch); +FMOD_RESULT F_API FMOD_Channel_GetPitch (FMOD_CHANNEL *channel, float *pitch); +FMOD_RESULT F_API FMOD_Channel_SetMute (FMOD_CHANNEL *channel, FMOD_BOOL mute); +FMOD_RESULT F_API FMOD_Channel_GetMute (FMOD_CHANNEL *channel, FMOD_BOOL *mute); +FMOD_RESULT F_API FMOD_Channel_SetReverbProperties (FMOD_CHANNEL *channel, int instance, float wet); +FMOD_RESULT F_API FMOD_Channel_GetReverbProperties (FMOD_CHANNEL *channel, int instance, float *wet); +FMOD_RESULT F_API FMOD_Channel_SetLowPassGain (FMOD_CHANNEL *channel, float gain); +FMOD_RESULT F_API FMOD_Channel_GetLowPassGain (FMOD_CHANNEL *channel, float *gain); +FMOD_RESULT F_API FMOD_Channel_SetMode (FMOD_CHANNEL *channel, FMOD_MODE mode); +FMOD_RESULT F_API FMOD_Channel_GetMode (FMOD_CHANNEL *channel, FMOD_MODE *mode); +FMOD_RESULT F_API FMOD_Channel_SetCallback (FMOD_CHANNEL *channel, FMOD_CHANNELCONTROL_CALLBACK callback); +FMOD_RESULT F_API FMOD_Channel_IsPlaying (FMOD_CHANNEL *channel, FMOD_BOOL *isplaying); + +/* + Note all 'set' functions alter a final matrix, this is why the only get function is getMixMatrix, to avoid other get functions returning incorrect/obsolete values. +*/ + +FMOD_RESULT F_API FMOD_Channel_SetPan (FMOD_CHANNEL *channel, float pan); +FMOD_RESULT F_API FMOD_Channel_SetMixLevelsOutput (FMOD_CHANNEL *channel, float frontleft, float frontright, float center, float lfe, float surroundleft, float surroundright, float backleft, float backright); +FMOD_RESULT F_API FMOD_Channel_SetMixLevelsInput (FMOD_CHANNEL *channel, float *levels, int numlevels); +FMOD_RESULT F_API FMOD_Channel_SetMixMatrix (FMOD_CHANNEL *channel, float *matrix, int outchannels, int inchannels, int inchannel_hop); +FMOD_RESULT F_API FMOD_Channel_GetMixMatrix (FMOD_CHANNEL *channel, float *matrix, int *outchannels, int *inchannels, int inchannel_hop); + +/* + Clock based functionality. +*/ + +FMOD_RESULT F_API FMOD_Channel_GetDSPClock (FMOD_CHANNEL *channel, unsigned long long *dspclock, unsigned long long *parentclock); +FMOD_RESULT F_API FMOD_Channel_SetDelay (FMOD_CHANNEL *channel, unsigned long long dspclock_start, unsigned long long dspclock_end, FMOD_BOOL stopchannels); +FMOD_RESULT F_API FMOD_Channel_GetDelay (FMOD_CHANNEL *channel, unsigned long long *dspclock_start, unsigned long long *dspclock_end, FMOD_BOOL *stopchannels); +FMOD_RESULT F_API FMOD_Channel_AddFadePoint (FMOD_CHANNEL *channel, unsigned long long dspclock, float volume); +FMOD_RESULT F_API FMOD_Channel_SetFadePointRamp (FMOD_CHANNEL *channel, unsigned long long dspclock, float volume); +FMOD_RESULT F_API FMOD_Channel_RemoveFadePoints (FMOD_CHANNEL *channel, unsigned long long dspclock_start, unsigned long long dspclock_end); +FMOD_RESULT F_API FMOD_Channel_GetFadePoints (FMOD_CHANNEL *channel, unsigned int *numpoints, unsigned long long *point_dspclock, float *point_volume); + +/* + DSP effects. +*/ + +FMOD_RESULT F_API FMOD_Channel_GetDSP (FMOD_CHANNEL *channel, int index, FMOD_DSP **dsp); +FMOD_RESULT F_API FMOD_Channel_AddDSP (FMOD_CHANNEL *channel, int index, FMOD_DSP *dsp); +FMOD_RESULT F_API FMOD_Channel_RemoveDSP (FMOD_CHANNEL *channel, FMOD_DSP *dsp); +FMOD_RESULT F_API FMOD_Channel_GetNumDSPs (FMOD_CHANNEL *channel, int *numdsps); +FMOD_RESULT F_API FMOD_Channel_SetDSPIndex (FMOD_CHANNEL *channel, FMOD_DSP *dsp, int index); +FMOD_RESULT F_API FMOD_Channel_GetDSPIndex (FMOD_CHANNEL *channel, FMOD_DSP *dsp, int *index); + +/* + 3D functionality. +*/ + +FMOD_RESULT F_API FMOD_Channel_Set3DAttributes (FMOD_CHANNEL *channel, const FMOD_VECTOR *pos, const FMOD_VECTOR *vel); +FMOD_RESULT F_API FMOD_Channel_Get3DAttributes (FMOD_CHANNEL *channel, FMOD_VECTOR *pos, FMOD_VECTOR *vel); +FMOD_RESULT F_API FMOD_Channel_Set3DMinMaxDistance (FMOD_CHANNEL *channel, float mindistance, float maxdistance); +FMOD_RESULT F_API FMOD_Channel_Get3DMinMaxDistance (FMOD_CHANNEL *channel, float *mindistance, float *maxdistance); +FMOD_RESULT F_API FMOD_Channel_Set3DConeSettings (FMOD_CHANNEL *channel, float insideconeangle, float outsideconeangle, float outsidevolume); +FMOD_RESULT F_API FMOD_Channel_Get3DConeSettings (FMOD_CHANNEL *channel, float *insideconeangle, float *outsideconeangle, float *outsidevolume); +FMOD_RESULT F_API FMOD_Channel_Set3DConeOrientation (FMOD_CHANNEL *channel, FMOD_VECTOR *orientation); +FMOD_RESULT F_API FMOD_Channel_Get3DConeOrientation (FMOD_CHANNEL *channel, FMOD_VECTOR *orientation); +FMOD_RESULT F_API FMOD_Channel_Set3DCustomRolloff (FMOD_CHANNEL *channel, FMOD_VECTOR *points, int numpoints); +FMOD_RESULT F_API FMOD_Channel_Get3DCustomRolloff (FMOD_CHANNEL *channel, FMOD_VECTOR **points, int *numpoints); +FMOD_RESULT F_API FMOD_Channel_Set3DOcclusion (FMOD_CHANNEL *channel, float directocclusion, float reverbocclusion); +FMOD_RESULT F_API FMOD_Channel_Get3DOcclusion (FMOD_CHANNEL *channel, float *directocclusion, float *reverbocclusion); +FMOD_RESULT F_API FMOD_Channel_Set3DSpread (FMOD_CHANNEL *channel, float angle); +FMOD_RESULT F_API FMOD_Channel_Get3DSpread (FMOD_CHANNEL *channel, float *angle); +FMOD_RESULT F_API FMOD_Channel_Set3DLevel (FMOD_CHANNEL *channel, float level); +FMOD_RESULT F_API FMOD_Channel_Get3DLevel (FMOD_CHANNEL *channel, float *level); +FMOD_RESULT F_API FMOD_Channel_Set3DDopplerLevel (FMOD_CHANNEL *channel, float level); +FMOD_RESULT F_API FMOD_Channel_Get3DDopplerLevel (FMOD_CHANNEL *channel, float *level); +FMOD_RESULT F_API FMOD_Channel_Set3DDistanceFilter (FMOD_CHANNEL *channel, FMOD_BOOL custom, float customLevel, float centerFreq); +FMOD_RESULT F_API FMOD_Channel_Get3DDistanceFilter (FMOD_CHANNEL *channel, FMOD_BOOL *custom, float *customLevel, float *centerFreq); + +/* + Userdata set/get. +*/ + +FMOD_RESULT F_API FMOD_Channel_SetUserData (FMOD_CHANNEL *channel, void *userdata); +FMOD_RESULT F_API FMOD_Channel_GetUserData (FMOD_CHANNEL *channel, void **userdata); + +/* + Channel specific control functionality. +*/ + +FMOD_RESULT F_API FMOD_Channel_SetFrequency (FMOD_CHANNEL *channel, float frequency); +FMOD_RESULT F_API FMOD_Channel_GetFrequency (FMOD_CHANNEL *channel, float *frequency); +FMOD_RESULT F_API FMOD_Channel_SetPriority (FMOD_CHANNEL *channel, int priority); +FMOD_RESULT F_API FMOD_Channel_GetPriority (FMOD_CHANNEL *channel, int *priority); +FMOD_RESULT F_API FMOD_Channel_SetPosition (FMOD_CHANNEL *channel, unsigned int position, FMOD_TIMEUNIT postype); +FMOD_RESULT F_API FMOD_Channel_GetPosition (FMOD_CHANNEL *channel, unsigned int *position, FMOD_TIMEUNIT postype); +FMOD_RESULT F_API FMOD_Channel_SetChannelGroup (FMOD_CHANNEL *channel, FMOD_CHANNELGROUP *channelgroup); +FMOD_RESULT F_API FMOD_Channel_GetChannelGroup (FMOD_CHANNEL *channel, FMOD_CHANNELGROUP **channelgroup); +FMOD_RESULT F_API FMOD_Channel_SetLoopCount (FMOD_CHANNEL *channel, int loopcount); +FMOD_RESULT F_API FMOD_Channel_GetLoopCount (FMOD_CHANNEL *channel, int *loopcount); +FMOD_RESULT F_API FMOD_Channel_SetLoopPoints (FMOD_CHANNEL *channel, unsigned int loopstart, FMOD_TIMEUNIT loopstarttype, unsigned int loopend, FMOD_TIMEUNIT loopendtype); +FMOD_RESULT F_API FMOD_Channel_GetLoopPoints (FMOD_CHANNEL *channel, unsigned int *loopstart, FMOD_TIMEUNIT loopstarttype, unsigned int *loopend, FMOD_TIMEUNIT loopendtype); + +/* + Information only functions. +*/ + +FMOD_RESULT F_API FMOD_Channel_IsVirtual (FMOD_CHANNEL *channel, FMOD_BOOL *isvirtual); +FMOD_RESULT F_API FMOD_Channel_GetCurrentSound (FMOD_CHANNEL *channel, FMOD_SOUND **sound); +FMOD_RESULT F_API FMOD_Channel_GetIndex (FMOD_CHANNEL *channel, int *index); + +/* + 'ChannelGroup' API +*/ + +FMOD_RESULT F_API FMOD_ChannelGroup_GetSystemObject (FMOD_CHANNELGROUP *channelgroup, FMOD_SYSTEM **system); + +/* + General control functionality for Channels and ChannelGroups. +*/ + +FMOD_RESULT F_API FMOD_ChannelGroup_Stop (FMOD_CHANNELGROUP *channelgroup); +FMOD_RESULT F_API FMOD_ChannelGroup_SetPaused (FMOD_CHANNELGROUP *channelgroup, FMOD_BOOL paused); +FMOD_RESULT F_API FMOD_ChannelGroup_GetPaused (FMOD_CHANNELGROUP *channelgroup, FMOD_BOOL *paused); +FMOD_RESULT F_API FMOD_ChannelGroup_SetVolume (FMOD_CHANNELGROUP *channelgroup, float volume); +FMOD_RESULT F_API FMOD_ChannelGroup_GetVolume (FMOD_CHANNELGROUP *channelgroup, float *volume); +FMOD_RESULT F_API FMOD_ChannelGroup_SetVolumeRamp (FMOD_CHANNELGROUP *channelgroup, FMOD_BOOL ramp); +FMOD_RESULT F_API FMOD_ChannelGroup_GetVolumeRamp (FMOD_CHANNELGROUP *channelgroup, FMOD_BOOL *ramp); +FMOD_RESULT F_API FMOD_ChannelGroup_GetAudibility (FMOD_CHANNELGROUP *channelgroup, float *audibility); +FMOD_RESULT F_API FMOD_ChannelGroup_SetPitch (FMOD_CHANNELGROUP *channelgroup, float pitch); +FMOD_RESULT F_API FMOD_ChannelGroup_GetPitch (FMOD_CHANNELGROUP *channelgroup, float *pitch); +FMOD_RESULT F_API FMOD_ChannelGroup_SetMute (FMOD_CHANNELGROUP *channelgroup, FMOD_BOOL mute); +FMOD_RESULT F_API FMOD_ChannelGroup_GetMute (FMOD_CHANNELGROUP *channelgroup, FMOD_BOOL *mute); +FMOD_RESULT F_API FMOD_ChannelGroup_SetReverbProperties (FMOD_CHANNELGROUP *channelgroup, int instance, float wet); +FMOD_RESULT F_API FMOD_ChannelGroup_GetReverbProperties (FMOD_CHANNELGROUP *channelgroup, int instance, float *wet); +FMOD_RESULT F_API FMOD_ChannelGroup_SetLowPassGain (FMOD_CHANNELGROUP *channelgroup, float gain); +FMOD_RESULT F_API FMOD_ChannelGroup_GetLowPassGain (FMOD_CHANNELGROUP *channelgroup, float *gain); +FMOD_RESULT F_API FMOD_ChannelGroup_SetMode (FMOD_CHANNELGROUP *channelgroup, FMOD_MODE mode); +FMOD_RESULT F_API FMOD_ChannelGroup_GetMode (FMOD_CHANNELGROUP *channelgroup, FMOD_MODE *mode); +FMOD_RESULT F_API FMOD_ChannelGroup_SetCallback (FMOD_CHANNELGROUP *channelgroup, FMOD_CHANNELCONTROL_CALLBACK callback); +FMOD_RESULT F_API FMOD_ChannelGroup_IsPlaying (FMOD_CHANNELGROUP *channelgroup, FMOD_BOOL *isplaying); + +/* + Note all 'set' functions alter a final matrix, this is why the only get function is getMixMatrix, to avoid other get functions returning incorrect/obsolete values. +*/ + +FMOD_RESULT F_API FMOD_ChannelGroup_SetPan (FMOD_CHANNELGROUP *channelgroup, float pan); +FMOD_RESULT F_API FMOD_ChannelGroup_SetMixLevelsOutput (FMOD_CHANNELGROUP *channelgroup, float frontleft, float frontright, float center, float lfe, float surroundleft, float surroundright, float backleft, float backright); +FMOD_RESULT F_API FMOD_ChannelGroup_SetMixLevelsInput (FMOD_CHANNELGROUP *channelgroup, float *levels, int numlevels); +FMOD_RESULT F_API FMOD_ChannelGroup_SetMixMatrix (FMOD_CHANNELGROUP *channelgroup, float *matrix, int outchannels, int inchannels, int inchannel_hop); +FMOD_RESULT F_API FMOD_ChannelGroup_GetMixMatrix (FMOD_CHANNELGROUP *channelgroup, float *matrix, int *outchannels, int *inchannels, int inchannel_hop); + +/* + Clock based functionality. +*/ + +FMOD_RESULT F_API FMOD_ChannelGroup_GetDSPClock (FMOD_CHANNELGROUP *channelgroup, unsigned long long *dspclock, unsigned long long *parentclock); +FMOD_RESULT F_API FMOD_ChannelGroup_SetDelay (FMOD_CHANNELGROUP *channelgroup, unsigned long long dspclock_start, unsigned long long dspclock_end, FMOD_BOOL stopchannels); +FMOD_RESULT F_API FMOD_ChannelGroup_GetDelay (FMOD_CHANNELGROUP *channelgroup, unsigned long long *dspclock_start, unsigned long long *dspclock_end, FMOD_BOOL *stopchannels); +FMOD_RESULT F_API FMOD_ChannelGroup_AddFadePoint (FMOD_CHANNELGROUP *channelgroup, unsigned long long dspclock, float volume); +FMOD_RESULT F_API FMOD_ChannelGroup_SetFadePointRamp (FMOD_CHANNELGROUP *channelgroup, unsigned long long dspclock, float volume); +FMOD_RESULT F_API FMOD_ChannelGroup_RemoveFadePoints (FMOD_CHANNELGROUP *channelgroup, unsigned long long dspclock_start, unsigned long long dspclock_end); +FMOD_RESULT F_API FMOD_ChannelGroup_GetFadePoints (FMOD_CHANNELGROUP *channelgroup, unsigned int *numpoints, unsigned long long *point_dspclock, float *point_volume); + +/* + DSP effects. +*/ + +FMOD_RESULT F_API FMOD_ChannelGroup_GetDSP (FMOD_CHANNELGROUP *channelgroup, int index, FMOD_DSP **dsp); +FMOD_RESULT F_API FMOD_ChannelGroup_AddDSP (FMOD_CHANNELGROUP *channelgroup, int index, FMOD_DSP *dsp); +FMOD_RESULT F_API FMOD_ChannelGroup_RemoveDSP (FMOD_CHANNELGROUP *channelgroup, FMOD_DSP *dsp); +FMOD_RESULT F_API FMOD_ChannelGroup_GetNumDSPs (FMOD_CHANNELGROUP *channelgroup, int *numdsps); +FMOD_RESULT F_API FMOD_ChannelGroup_SetDSPIndex (FMOD_CHANNELGROUP *channelgroup, FMOD_DSP *dsp, int index); +FMOD_RESULT F_API FMOD_ChannelGroup_GetDSPIndex (FMOD_CHANNELGROUP *channelgroup, FMOD_DSP *dsp, int *index); + +/* + 3D functionality. +*/ + +FMOD_RESULT F_API FMOD_ChannelGroup_Set3DAttributes (FMOD_CHANNELGROUP *channelgroup, const FMOD_VECTOR *pos, const FMOD_VECTOR *vel); +FMOD_RESULT F_API FMOD_ChannelGroup_Get3DAttributes (FMOD_CHANNELGROUP *channelgroup, FMOD_VECTOR *pos, FMOD_VECTOR *vel); +FMOD_RESULT F_API FMOD_ChannelGroup_Set3DMinMaxDistance (FMOD_CHANNELGROUP *channelgroup, float mindistance, float maxdistance); +FMOD_RESULT F_API FMOD_ChannelGroup_Get3DMinMaxDistance (FMOD_CHANNELGROUP *channelgroup, float *mindistance, float *maxdistance); +FMOD_RESULT F_API FMOD_ChannelGroup_Set3DConeSettings (FMOD_CHANNELGROUP *channelgroup, float insideconeangle, float outsideconeangle, float outsidevolume); +FMOD_RESULT F_API FMOD_ChannelGroup_Get3DConeSettings (FMOD_CHANNELGROUP *channelgroup, float *insideconeangle, float *outsideconeangle, float *outsidevolume); +FMOD_RESULT F_API FMOD_ChannelGroup_Set3DConeOrientation(FMOD_CHANNELGROUP *channelgroup, FMOD_VECTOR *orientation); +FMOD_RESULT F_API FMOD_ChannelGroup_Get3DConeOrientation(FMOD_CHANNELGROUP *channelgroup, FMOD_VECTOR *orientation); +FMOD_RESULT F_API FMOD_ChannelGroup_Set3DCustomRolloff (FMOD_CHANNELGROUP *channelgroup, FMOD_VECTOR *points, int numpoints); +FMOD_RESULT F_API FMOD_ChannelGroup_Get3DCustomRolloff (FMOD_CHANNELGROUP *channelgroup, FMOD_VECTOR **points, int *numpoints); +FMOD_RESULT F_API FMOD_ChannelGroup_Set3DOcclusion (FMOD_CHANNELGROUP *channelgroup, float directocclusion, float reverbocclusion); +FMOD_RESULT F_API FMOD_ChannelGroup_Get3DOcclusion (FMOD_CHANNELGROUP *channelgroup, float *directocclusion, float *reverbocclusion); +FMOD_RESULT F_API FMOD_ChannelGroup_Set3DSpread (FMOD_CHANNELGROUP *channelgroup, float angle); +FMOD_RESULT F_API FMOD_ChannelGroup_Get3DSpread (FMOD_CHANNELGROUP *channelgroup, float *angle); +FMOD_RESULT F_API FMOD_ChannelGroup_Set3DLevel (FMOD_CHANNELGROUP *channelgroup, float level); +FMOD_RESULT F_API FMOD_ChannelGroup_Get3DLevel (FMOD_CHANNELGROUP *channelgroup, float *level); +FMOD_RESULT F_API FMOD_ChannelGroup_Set3DDopplerLevel (FMOD_CHANNELGROUP *channelgroup, float level); +FMOD_RESULT F_API FMOD_ChannelGroup_Get3DDopplerLevel (FMOD_CHANNELGROUP *channelgroup, float *level); +FMOD_RESULT F_API FMOD_ChannelGroup_Set3DDistanceFilter (FMOD_CHANNELGROUP *channelgroup, FMOD_BOOL custom, float customLevel, float centerFreq); +FMOD_RESULT F_API FMOD_ChannelGroup_Get3DDistanceFilter (FMOD_CHANNELGROUP *channelgroup, FMOD_BOOL *custom, float *customLevel, float *centerFreq); + +/* + Userdata set/get. +*/ + +FMOD_RESULT F_API FMOD_ChannelGroup_SetUserData (FMOD_CHANNELGROUP *channelgroup, void *userdata); +FMOD_RESULT F_API FMOD_ChannelGroup_GetUserData (FMOD_CHANNELGROUP *channelgroup, void **userdata); + +FMOD_RESULT F_API FMOD_ChannelGroup_Release (FMOD_CHANNELGROUP *channelgroup); + +/* + Nested channel groups. +*/ + +FMOD_RESULT F_API FMOD_ChannelGroup_AddGroup (FMOD_CHANNELGROUP *channelgroup, FMOD_CHANNELGROUP *group, FMOD_BOOL propagatedspclock, FMOD_DSPCONNECTION **connection); +FMOD_RESULT F_API FMOD_ChannelGroup_GetNumGroups (FMOD_CHANNELGROUP *channelgroup, int *numgroups); +FMOD_RESULT F_API FMOD_ChannelGroup_GetGroup (FMOD_CHANNELGROUP *channelgroup, int index, FMOD_CHANNELGROUP **group); +FMOD_RESULT F_API FMOD_ChannelGroup_GetParentGroup (FMOD_CHANNELGROUP *channelgroup, FMOD_CHANNELGROUP **group); + +/* + Information only functions. +*/ + +FMOD_RESULT F_API FMOD_ChannelGroup_GetName (FMOD_CHANNELGROUP *channelgroup, char *name, int namelen); +FMOD_RESULT F_API FMOD_ChannelGroup_GetNumChannels (FMOD_CHANNELGROUP *channelgroup, int *numchannels); +FMOD_RESULT F_API FMOD_ChannelGroup_GetChannel (FMOD_CHANNELGROUP *channelgroup, int index, FMOD_CHANNEL **channel); + +/* + 'SoundGroup' API +*/ + +FMOD_RESULT F_API FMOD_SoundGroup_Release (FMOD_SOUNDGROUP *soundgroup); +FMOD_RESULT F_API FMOD_SoundGroup_GetSystemObject (FMOD_SOUNDGROUP *soundgroup, FMOD_SYSTEM **system); + +/* + SoundGroup control functions. +*/ + +FMOD_RESULT F_API FMOD_SoundGroup_SetMaxAudible (FMOD_SOUNDGROUP *soundgroup, int maxaudible); +FMOD_RESULT F_API FMOD_SoundGroup_GetMaxAudible (FMOD_SOUNDGROUP *soundgroup, int *maxaudible); +FMOD_RESULT F_API FMOD_SoundGroup_SetMaxAudibleBehavior (FMOD_SOUNDGROUP *soundgroup, FMOD_SOUNDGROUP_BEHAVIOR behavior); +FMOD_RESULT F_API FMOD_SoundGroup_GetMaxAudibleBehavior (FMOD_SOUNDGROUP *soundgroup, FMOD_SOUNDGROUP_BEHAVIOR *behavior); +FMOD_RESULT F_API FMOD_SoundGroup_SetMuteFadeSpeed (FMOD_SOUNDGROUP *soundgroup, float speed); +FMOD_RESULT F_API FMOD_SoundGroup_GetMuteFadeSpeed (FMOD_SOUNDGROUP *soundgroup, float *speed); +FMOD_RESULT F_API FMOD_SoundGroup_SetVolume (FMOD_SOUNDGROUP *soundgroup, float volume); +FMOD_RESULT F_API FMOD_SoundGroup_GetVolume (FMOD_SOUNDGROUP *soundgroup, float *volume); +FMOD_RESULT F_API FMOD_SoundGroup_Stop (FMOD_SOUNDGROUP *soundgroup); + +/* + Information only functions. +*/ + +FMOD_RESULT F_API FMOD_SoundGroup_GetName (FMOD_SOUNDGROUP *soundgroup, char *name, int namelen); +FMOD_RESULT F_API FMOD_SoundGroup_GetNumSounds (FMOD_SOUNDGROUP *soundgroup, int *numsounds); +FMOD_RESULT F_API FMOD_SoundGroup_GetSound (FMOD_SOUNDGROUP *soundgroup, int index, FMOD_SOUND **sound); +FMOD_RESULT F_API FMOD_SoundGroup_GetNumPlaying (FMOD_SOUNDGROUP *soundgroup, int *numplaying); + +/* + Userdata set/get. +*/ + +FMOD_RESULT F_API FMOD_SoundGroup_SetUserData (FMOD_SOUNDGROUP *soundgroup, void *userdata); +FMOD_RESULT F_API FMOD_SoundGroup_GetUserData (FMOD_SOUNDGROUP *soundgroup, void **userdata); + +/* + 'DSP' API +*/ + +FMOD_RESULT F_API FMOD_DSP_Release (FMOD_DSP *dsp); +FMOD_RESULT F_API FMOD_DSP_GetSystemObject (FMOD_DSP *dsp, FMOD_SYSTEM **system); + +/* + Connection / disconnection / input and output enumeration. +*/ + +FMOD_RESULT F_API FMOD_DSP_AddInput (FMOD_DSP *dsp, FMOD_DSP *input, FMOD_DSPCONNECTION **connection, FMOD_DSPCONNECTION_TYPE type); +FMOD_RESULT F_API FMOD_DSP_AddInputPreallocated (FMOD_DSP *dsp, FMOD_DSP *input, FMOD_DSPCONNECTION **connection); +FMOD_RESULT F_API FMOD_DSP_DisconnectFrom (FMOD_DSP *dsp, FMOD_DSP *target, FMOD_DSPCONNECTION *connection); +FMOD_RESULT F_API FMOD_DSP_DisconnectAll (FMOD_DSP *dsp, FMOD_BOOL inputs, FMOD_BOOL outputs); +FMOD_RESULT F_API FMOD_DSP_GetNumInputs (FMOD_DSP *dsp, int *numinputs); +FMOD_RESULT F_API FMOD_DSP_GetNumOutputs (FMOD_DSP *dsp, int *numoutputs); +FMOD_RESULT F_API FMOD_DSP_GetInput (FMOD_DSP *dsp, int index, FMOD_DSP **input, FMOD_DSPCONNECTION **inputconnection); +FMOD_RESULT F_API FMOD_DSP_GetOutput (FMOD_DSP *dsp, int index, FMOD_DSP **output, FMOD_DSPCONNECTION **outputconnection); + +/* + DSP unit control. +*/ + +FMOD_RESULT F_API FMOD_DSP_SetActive (FMOD_DSP *dsp, FMOD_BOOL active); +FMOD_RESULT F_API FMOD_DSP_GetActive (FMOD_DSP *dsp, FMOD_BOOL *active); +FMOD_RESULT F_API FMOD_DSP_SetBypass (FMOD_DSP *dsp, FMOD_BOOL bypass); +FMOD_RESULT F_API FMOD_DSP_GetBypass (FMOD_DSP *dsp, FMOD_BOOL *bypass); +FMOD_RESULT F_API FMOD_DSP_SetWetDryMix (FMOD_DSP *dsp, float prewet, float postwet, float dry); +FMOD_RESULT F_API FMOD_DSP_GetWetDryMix (FMOD_DSP *dsp, float *prewet, float *postwet, float *dry); +FMOD_RESULT F_API FMOD_DSP_SetChannelFormat (FMOD_DSP *dsp, FMOD_CHANNELMASK channelmask, int numchannels, FMOD_SPEAKERMODE source_speakermode); +FMOD_RESULT F_API FMOD_DSP_GetChannelFormat (FMOD_DSP *dsp, FMOD_CHANNELMASK *channelmask, int *numchannels, FMOD_SPEAKERMODE *source_speakermode); +FMOD_RESULT F_API FMOD_DSP_GetOutputChannelFormat (FMOD_DSP *dsp, FMOD_CHANNELMASK inmask, int inchannels, FMOD_SPEAKERMODE inspeakermode, FMOD_CHANNELMASK *outmask, int *outchannels, FMOD_SPEAKERMODE *outspeakermode); +FMOD_RESULT F_API FMOD_DSP_Reset (FMOD_DSP *dsp); +FMOD_RESULT F_API FMOD_DSP_SetCallback (FMOD_DSP *dsp, FMOD_DSP_CALLBACK callback); + +/* + DSP parameter control. +*/ + +FMOD_RESULT F_API FMOD_DSP_SetParameterFloat (FMOD_DSP *dsp, int index, float value); +FMOD_RESULT F_API FMOD_DSP_SetParameterInt (FMOD_DSP *dsp, int index, int value); +FMOD_RESULT F_API FMOD_DSP_SetParameterBool (FMOD_DSP *dsp, int index, FMOD_BOOL value); +FMOD_RESULT F_API FMOD_DSP_SetParameterData (FMOD_DSP *dsp, int index, void *data, unsigned int length); +FMOD_RESULT F_API FMOD_DSP_GetParameterFloat (FMOD_DSP *dsp, int index, float *value, char *valuestr, int valuestrlen); +FMOD_RESULT F_API FMOD_DSP_GetParameterInt (FMOD_DSP *dsp, int index, int *value, char *valuestr, int valuestrlen); +FMOD_RESULT F_API FMOD_DSP_GetParameterBool (FMOD_DSP *dsp, int index, FMOD_BOOL *value, char *valuestr, int valuestrlen); +FMOD_RESULT F_API FMOD_DSP_GetParameterData (FMOD_DSP *dsp, int index, void **data, unsigned int *length, char *valuestr, int valuestrlen); +FMOD_RESULT F_API FMOD_DSP_GetNumParameters (FMOD_DSP *dsp, int *numparams); +FMOD_RESULT F_API FMOD_DSP_GetParameterInfo (FMOD_DSP *dsp, int index, FMOD_DSP_PARAMETER_DESC **desc); +FMOD_RESULT F_API FMOD_DSP_GetDataParameterIndex (FMOD_DSP *dsp, int datatype, int *index); +FMOD_RESULT F_API FMOD_DSP_ShowConfigDialog (FMOD_DSP *dsp, void *hwnd, FMOD_BOOL show); + +/* + DSP attributes. +*/ + +FMOD_RESULT F_API FMOD_DSP_GetInfo (FMOD_DSP *dsp, char *name, unsigned int *version, int *channels, int *configwidth, int *configheight); +FMOD_RESULT F_API FMOD_DSP_GetType (FMOD_DSP *dsp, FMOD_DSP_TYPE *type); +FMOD_RESULT F_API FMOD_DSP_GetIdle (FMOD_DSP *dsp, FMOD_BOOL *idle); + +/* + Userdata set/get. +*/ + +FMOD_RESULT F_API FMOD_DSP_SetUserData (FMOD_DSP *dsp, void *userdata); +FMOD_RESULT F_API FMOD_DSP_GetUserData (FMOD_DSP *dsp, void **userdata); + +/* + Metering. +*/ + +FMOD_RESULT F_API FMOD_DSP_SetMeteringEnabled (FMOD_DSP *dsp, FMOD_BOOL inputEnabled, FMOD_BOOL outputEnabled); +FMOD_RESULT F_API FMOD_DSP_GetMeteringEnabled (FMOD_DSP *dsp, FMOD_BOOL *inputEnabled, FMOD_BOOL *outputEnabled); +FMOD_RESULT F_API FMOD_DSP_GetMeteringInfo (FMOD_DSP *dsp, FMOD_DSP_METERING_INFO *inputInfo, FMOD_DSP_METERING_INFO *outputInfo); +FMOD_RESULT F_API FMOD_DSP_GetCPUUsage (FMOD_DSP *dsp, unsigned int *exclusive, unsigned int *inclusive); + +/* + 'DSPConnection' API +*/ + +FMOD_RESULT F_API FMOD_DSPConnection_GetInput (FMOD_DSPCONNECTION *dspconnection, FMOD_DSP **input); +FMOD_RESULT F_API FMOD_DSPConnection_GetOutput (FMOD_DSPCONNECTION *dspconnection, FMOD_DSP **output); +FMOD_RESULT F_API FMOD_DSPConnection_SetMix (FMOD_DSPCONNECTION *dspconnection, float volume); +FMOD_RESULT F_API FMOD_DSPConnection_GetMix (FMOD_DSPCONNECTION *dspconnection, float *volume); +FMOD_RESULT F_API FMOD_DSPConnection_SetMixMatrix (FMOD_DSPCONNECTION *dspconnection, float *matrix, int outchannels, int inchannels, int inchannel_hop); +FMOD_RESULT F_API FMOD_DSPConnection_GetMixMatrix (FMOD_DSPCONNECTION *dspconnection, float *matrix, int *outchannels, int *inchannels, int inchannel_hop); +FMOD_RESULT F_API FMOD_DSPConnection_GetType (FMOD_DSPCONNECTION *dspconnection, FMOD_DSPCONNECTION_TYPE *type); + +/* + Userdata set/get. +*/ + +FMOD_RESULT F_API FMOD_DSPConnection_SetUserData (FMOD_DSPCONNECTION *dspconnection, void *userdata); +FMOD_RESULT F_API FMOD_DSPConnection_GetUserData (FMOD_DSPCONNECTION *dspconnection, void **userdata); + +/* + 'Geometry' API +*/ + +FMOD_RESULT F_API FMOD_Geometry_Release (FMOD_GEOMETRY *geometry); + +/* + Polygon manipulation. +*/ + +FMOD_RESULT F_API FMOD_Geometry_AddPolygon (FMOD_GEOMETRY *geometry, float directocclusion, float reverbocclusion, FMOD_BOOL doublesided, int numvertices, const FMOD_VECTOR *vertices, int *polygonindex); +FMOD_RESULT F_API FMOD_Geometry_GetNumPolygons (FMOD_GEOMETRY *geometry, int *numpolygons); +FMOD_RESULT F_API FMOD_Geometry_GetMaxPolygons (FMOD_GEOMETRY *geometry, int *maxpolygons, int *maxvertices); +FMOD_RESULT F_API FMOD_Geometry_GetPolygonNumVertices (FMOD_GEOMETRY *geometry, int index, int *numvertices); +FMOD_RESULT F_API FMOD_Geometry_SetPolygonVertex (FMOD_GEOMETRY *geometry, int index, int vertexindex, const FMOD_VECTOR *vertex); +FMOD_RESULT F_API FMOD_Geometry_GetPolygonVertex (FMOD_GEOMETRY *geometry, int index, int vertexindex, FMOD_VECTOR *vertex); +FMOD_RESULT F_API FMOD_Geometry_SetPolygonAttributes (FMOD_GEOMETRY *geometry, int index, float directocclusion, float reverbocclusion, FMOD_BOOL doublesided); +FMOD_RESULT F_API FMOD_Geometry_GetPolygonAttributes (FMOD_GEOMETRY *geometry, int index, float *directocclusion, float *reverbocclusion, FMOD_BOOL *doublesided); + +/* + Object manipulation. +*/ + +FMOD_RESULT F_API FMOD_Geometry_SetActive (FMOD_GEOMETRY *geometry, FMOD_BOOL active); +FMOD_RESULT F_API FMOD_Geometry_GetActive (FMOD_GEOMETRY *geometry, FMOD_BOOL *active); +FMOD_RESULT F_API FMOD_Geometry_SetRotation (FMOD_GEOMETRY *geometry, const FMOD_VECTOR *forward, const FMOD_VECTOR *up); +FMOD_RESULT F_API FMOD_Geometry_GetRotation (FMOD_GEOMETRY *geometry, FMOD_VECTOR *forward, FMOD_VECTOR *up); +FMOD_RESULT F_API FMOD_Geometry_SetPosition (FMOD_GEOMETRY *geometry, const FMOD_VECTOR *position); +FMOD_RESULT F_API FMOD_Geometry_GetPosition (FMOD_GEOMETRY *geometry, FMOD_VECTOR *position); +FMOD_RESULT F_API FMOD_Geometry_SetScale (FMOD_GEOMETRY *geometry, const FMOD_VECTOR *scale); +FMOD_RESULT F_API FMOD_Geometry_GetScale (FMOD_GEOMETRY *geometry, FMOD_VECTOR *scale); +FMOD_RESULT F_API FMOD_Geometry_Save (FMOD_GEOMETRY *geometry, void *data, int *datasize); + +/* + Userdata set/get. +*/ + +FMOD_RESULT F_API FMOD_Geometry_SetUserData (FMOD_GEOMETRY *geometry, void *userdata); +FMOD_RESULT F_API FMOD_Geometry_GetUserData (FMOD_GEOMETRY *geometry, void **userdata); + +/* + 'Reverb3D' API +*/ + +FMOD_RESULT F_API FMOD_Reverb3D_Release (FMOD_REVERB3D *reverb3d); + +/* + Reverb manipulation. +*/ + +FMOD_RESULT F_API FMOD_Reverb3D_Set3DAttributes (FMOD_REVERB3D *reverb3d, const FMOD_VECTOR *position, float mindistance, float maxdistance); +FMOD_RESULT F_API FMOD_Reverb3D_Get3DAttributes (FMOD_REVERB3D *reverb3d, FMOD_VECTOR *position, float *mindistance, float *maxdistance); +FMOD_RESULT F_API FMOD_Reverb3D_SetProperties (FMOD_REVERB3D *reverb3d, const FMOD_REVERB_PROPERTIES *properties); +FMOD_RESULT F_API FMOD_Reverb3D_GetProperties (FMOD_REVERB3D *reverb3d, FMOD_REVERB_PROPERTIES *properties); +FMOD_RESULT F_API FMOD_Reverb3D_SetActive (FMOD_REVERB3D *reverb3d, FMOD_BOOL active); +FMOD_RESULT F_API FMOD_Reverb3D_GetActive (FMOD_REVERB3D *reverb3d, FMOD_BOOL *active); + +/* + Userdata set/get. +*/ + +FMOD_RESULT F_API FMOD_Reverb3D_SetUserData (FMOD_REVERB3D *reverb3d, void *userdata); +FMOD_RESULT F_API FMOD_Reverb3D_GetUserData (FMOD_REVERB3D *reverb3d, void **userdata); + +#ifdef __cplusplus +} +#endif + +#endif /* _FMOD_H */ diff --git a/FMOD/api/core/inc/fmod.hpp b/FMOD/api/core/inc/fmod.hpp new file mode 100644 index 0000000..a315918 --- /dev/null +++ b/FMOD/api/core/inc/fmod.hpp @@ -0,0 +1,609 @@ +/* ======================================================================================== */ +/* FMOD Core API - C++ header file. */ +/* Copyright (c), Firelight Technologies Pty, Ltd. 2004-2026. */ +/* */ +/* Use this header in conjunction with fmod_common.h (which contains all the constants / */ +/* callbacks) to develop using the C++ language. */ +/* */ +/* For more detail visit: */ +/* https://fmod.com/docs/2.03/api/core-api.html */ +/* ======================================================================================== */ +#ifndef _FMOD_HPP +#define _FMOD_HPP + +#include "fmod_common.h" +#include "fmod.h" + +/* + FMOD Namespace +*/ +namespace FMOD +{ + class System; + class Sound; + class ChannelControl; + class Channel; + class ChannelGroup; + class SoundGroup; + class DSP; + class DSPConnection; + class Geometry; + class Reverb3D; + + /* + FMOD global system functions (optional). + */ + inline FMOD_RESULT Memory_Initialize (void *poolmem, int poollen, FMOD_MEMORY_ALLOC_CALLBACK useralloc, FMOD_MEMORY_REALLOC_CALLBACK userrealloc, FMOD_MEMORY_FREE_CALLBACK userfree, FMOD_MEMORY_TYPE memtypeflags = FMOD_MEMORY_ALL) { return FMOD_Memory_Initialize(poolmem, poollen, useralloc, userrealloc, userfree, memtypeflags); } + inline FMOD_RESULT Memory_GetStats (int *currentalloced, int *maxalloced, bool blocking = true) { return FMOD_Memory_GetStats(currentalloced, maxalloced, blocking); } + inline FMOD_RESULT Debug_Initialize (FMOD_DEBUG_FLAGS flags, FMOD_DEBUG_MODE mode = FMOD_DEBUG_MODE_TTY, FMOD_DEBUG_CALLBACK callback = 0, const char *filename = 0) { return FMOD_Debug_Initialize(flags, mode, callback, filename); } + inline FMOD_RESULT File_SetDiskBusy (int busy) { return FMOD_File_SetDiskBusy(busy); } + inline FMOD_RESULT File_GetDiskBusy (int *busy) { return FMOD_File_GetDiskBusy(busy); } + inline FMOD_RESULT Thread_SetAttributes (FMOD_THREAD_TYPE type, FMOD_THREAD_AFFINITY affinity = FMOD_THREAD_AFFINITY_GROUP_DEFAULT, FMOD_THREAD_PRIORITY priority = FMOD_THREAD_PRIORITY_DEFAULT, FMOD_THREAD_STACK_SIZE stacksize = FMOD_THREAD_STACK_SIZE_DEFAULT) { return FMOD_Thread_SetAttributes(type, affinity, priority, stacksize); } + + /* + FMOD System factory functions. + */ + inline FMOD_RESULT System_Create (System **system, unsigned int headerversion = FMOD_VERSION) { return FMOD_System_Create((FMOD_SYSTEM **)system, headerversion); } + + /* + 'System' API + */ + class System + { + private: + + // Constructor made private so user cannot statically instance a System class. System_Create must be used. + System(); + System(const System &); + + public: + + FMOD_RESULT F_API release (); + + // Setup functions. + FMOD_RESULT F_API setOutput (FMOD_OUTPUTTYPE output); + FMOD_RESULT F_API getOutput (FMOD_OUTPUTTYPE *output); + FMOD_RESULT F_API getNumDrivers (int *numdrivers); + FMOD_RESULT F_API getDriverInfo (int id, char *name, int namelen, FMOD_GUID *guid, int *systemrate, FMOD_SPEAKERMODE *speakermode, int *speakermodechannels); + FMOD_RESULT F_API setDriver (int driver); + FMOD_RESULT F_API getDriver (int *driver); + FMOD_RESULT F_API setSoftwareChannels (int numsoftwarechannels); + FMOD_RESULT F_API getSoftwareChannels (int *numsoftwarechannels); + FMOD_RESULT F_API setSoftwareFormat (int samplerate, FMOD_SPEAKERMODE speakermode, int numrawspeakers); + FMOD_RESULT F_API getSoftwareFormat (int *samplerate, FMOD_SPEAKERMODE *speakermode, int *numrawspeakers); + FMOD_RESULT F_API setDSPBufferSize (unsigned int bufferlength, int numbuffers); + FMOD_RESULT F_API getDSPBufferSize (unsigned int *bufferlength, int *numbuffers); + FMOD_RESULT F_API setFileSystem (FMOD_FILE_OPEN_CALLBACK useropen, FMOD_FILE_CLOSE_CALLBACK userclose, FMOD_FILE_READ_CALLBACK userread, FMOD_FILE_SEEK_CALLBACK userseek, FMOD_FILE_ASYNCREAD_CALLBACK userasyncread, FMOD_FILE_ASYNCCANCEL_CALLBACK userasynccancel, int blockalign); + FMOD_RESULT F_API attachFileSystem (FMOD_FILE_OPEN_CALLBACK useropen, FMOD_FILE_CLOSE_CALLBACK userclose, FMOD_FILE_READ_CALLBACK userread, FMOD_FILE_SEEK_CALLBACK userseek); + FMOD_RESULT F_API setAdvancedSettings (FMOD_ADVANCEDSETTINGS *settings); + FMOD_RESULT F_API getAdvancedSettings (FMOD_ADVANCEDSETTINGS *settings); + FMOD_RESULT F_API setCallback (FMOD_SYSTEM_CALLBACK callback, FMOD_SYSTEM_CALLBACK_TYPE callbackmask = FMOD_SYSTEM_CALLBACK_ALL); + + // Plug-in support. + FMOD_RESULT F_API setPluginPath (const char *path); + FMOD_RESULT F_API loadPlugin (const char *filename, unsigned int *handle, unsigned int priority = 0); + FMOD_RESULT F_API unloadPlugin (unsigned int handle); + FMOD_RESULT F_API getNumNestedPlugins (unsigned int handle, int *count); + FMOD_RESULT F_API getNestedPlugin (unsigned int handle, int index, unsigned int *nestedhandle); + FMOD_RESULT F_API getNumPlugins (FMOD_PLUGINTYPE plugintype, int *numplugins); + FMOD_RESULT F_API getPluginHandle (FMOD_PLUGINTYPE plugintype, int index, unsigned int *handle); + FMOD_RESULT F_API getPluginInfo (unsigned int handle, FMOD_PLUGINTYPE *plugintype, char *name, int namelen, unsigned int *version); + FMOD_RESULT F_API setOutputByPlugin (unsigned int handle); + FMOD_RESULT F_API getOutputByPlugin (unsigned int *handle); + FMOD_RESULT F_API createDSPByPlugin (unsigned int handle, DSP **dsp); + FMOD_RESULT F_API getDSPInfoByPlugin (unsigned int handle, const FMOD_DSP_DESCRIPTION **description); + FMOD_RESULT F_API registerCodec (FMOD_CODEC_DESCRIPTION *description, unsigned int *handle, unsigned int priority = 0); + FMOD_RESULT F_API registerDSP (const FMOD_DSP_DESCRIPTION *description, unsigned int *handle); + FMOD_RESULT F_API registerOutput (const FMOD_OUTPUT_DESCRIPTION *description, unsigned int *handle); + + // Init/Close. + FMOD_RESULT F_API init (int maxchannels, FMOD_INITFLAGS flags, void *extradriverdata); + FMOD_RESULT F_API close (); + + // General post-init system functions. + FMOD_RESULT F_API update (); /* IMPORTANT! CALL THIS ONCE PER FRAME! */ + + FMOD_RESULT F_API setSpeakerPosition (FMOD_SPEAKER speaker, float x, float y, bool active); + FMOD_RESULT F_API getSpeakerPosition (FMOD_SPEAKER speaker, float *x, float *y, bool *active); + FMOD_RESULT F_API setStreamBufferSize (unsigned int filebuffersize, FMOD_TIMEUNIT filebuffersizetype); + FMOD_RESULT F_API getStreamBufferSize (unsigned int *filebuffersize, FMOD_TIMEUNIT *filebuffersizetype); + FMOD_RESULT F_API set3DSettings (float dopplerscale, float distancefactor, float rolloffscale); + FMOD_RESULT F_API get3DSettings (float *dopplerscale, float *distancefactor, float *rolloffscale); + FMOD_RESULT F_API set3DNumListeners (int numlisteners); + FMOD_RESULT F_API get3DNumListeners (int *numlisteners); + FMOD_RESULT F_API set3DListenerAttributes (int listener, const FMOD_VECTOR *pos, const FMOD_VECTOR *vel, const FMOD_VECTOR *forward, const FMOD_VECTOR *up); + FMOD_RESULT F_API get3DListenerAttributes (int listener, FMOD_VECTOR *pos, FMOD_VECTOR *vel, FMOD_VECTOR *forward, FMOD_VECTOR *up); + FMOD_RESULT F_API set3DRolloffCallback (FMOD_3D_ROLLOFF_CALLBACK callback); + FMOD_RESULT F_API mixerSuspend (); + FMOD_RESULT F_API mixerResume (); + FMOD_RESULT F_API getDefaultMixMatrix (FMOD_SPEAKERMODE sourcespeakermode, FMOD_SPEAKERMODE targetspeakermode, float *matrix, int matrixhop); + FMOD_RESULT F_API getSpeakerModeChannels (FMOD_SPEAKERMODE mode, int *channels); + + // System information functions. + FMOD_RESULT F_API getVersion (unsigned int *version, unsigned int *buildnumber = 0); + FMOD_RESULT F_API getOutputHandle (void **handle); + FMOD_RESULT F_API getChannelsPlaying (int *channels, int *realchannels = 0); + FMOD_RESULT F_API getCPUUsage (FMOD_CPU_USAGE *usage); + FMOD_RESULT F_API getFileUsage (long long *sampleBytesRead, long long *streamBytesRead, long long *otherBytesRead); + + // Sound/DSP/Channel/FX creation and retrieval. + FMOD_RESULT F_API createSound (const char *name_or_data, FMOD_MODE mode, FMOD_CREATESOUNDEXINFO *exinfo, Sound **sound); + FMOD_RESULT F_API createStream (const char *name_or_data, FMOD_MODE mode, FMOD_CREATESOUNDEXINFO *exinfo, Sound **sound); + FMOD_RESULT F_API createDSP (const FMOD_DSP_DESCRIPTION *description, DSP **dsp); + FMOD_RESULT F_API createDSPByType (FMOD_DSP_TYPE type, DSP **dsp); + FMOD_RESULT F_API createDSPConnection (FMOD_DSPCONNECTION_TYPE type, DSPConnection **connection); + FMOD_RESULT F_API createChannelGroup (const char *name, ChannelGroup **channelgroup); + FMOD_RESULT F_API createSoundGroup (const char *name, SoundGroup **soundgroup); + FMOD_RESULT F_API createReverb3D (Reverb3D **reverb); + + FMOD_RESULT F_API playSound (Sound *sound, ChannelGroup *channelgroup, bool paused, Channel **channel); + FMOD_RESULT F_API playDSP (DSP *dsp, ChannelGroup *channelgroup, bool paused, Channel **channel); + FMOD_RESULT F_API getChannel (int channelid, Channel **channel); + FMOD_RESULT F_API getDSPInfoByType (FMOD_DSP_TYPE type, const FMOD_DSP_DESCRIPTION **description); + FMOD_RESULT F_API getMasterChannelGroup (ChannelGroup **channelgroup); + FMOD_RESULT F_API getMasterSoundGroup (SoundGroup **soundgroup); + + // Routing to ports. + FMOD_RESULT F_API attachChannelGroupToPort (FMOD_PORT_TYPE portType, FMOD_PORT_INDEX portIndex, ChannelGroup *channelgroup, bool passThru = false); + FMOD_RESULT F_API detachChannelGroupFromPort (ChannelGroup *channelgroup); + + // Reverb API. + FMOD_RESULT F_API setReverbProperties (int instance, const FMOD_REVERB_PROPERTIES *prop); + FMOD_RESULT F_API getReverbProperties (int instance, FMOD_REVERB_PROPERTIES *prop); + + // System level DSP functionality. + FMOD_RESULT F_API lockDSP (); + FMOD_RESULT F_API unlockDSP (); + + // Recording API. + FMOD_RESULT F_API getRecordNumDrivers (int *numdrivers, int *numconnected); + FMOD_RESULT F_API getRecordDriverInfo (int id, char *name, int namelen, FMOD_GUID *guid, int *systemrate, FMOD_SPEAKERMODE *speakermode, int *speakermodechannels, FMOD_DRIVER_STATE *state); + FMOD_RESULT F_API getRecordPosition (int id, unsigned int *position); + FMOD_RESULT F_API recordStart (int id, Sound *sound, bool loop); + FMOD_RESULT F_API recordStop (int id); + FMOD_RESULT F_API isRecording (int id, bool *recording); + + // Geometry API. + FMOD_RESULT F_API createGeometry (int maxpolygons, int maxvertices, Geometry **geometry); + FMOD_RESULT F_API setGeometrySettings (float maxworldsize); + FMOD_RESULT F_API getGeometrySettings (float *maxworldsize); + FMOD_RESULT F_API loadGeometry (const void *data, int datasize, Geometry **geometry); + FMOD_RESULT F_API getGeometryOcclusion (const FMOD_VECTOR *listener, const FMOD_VECTOR *source, float *direct, float *reverb); + + // Network functions. + FMOD_RESULT F_API setNetworkProxy (const char *proxy); + FMOD_RESULT F_API getNetworkProxy (char *proxy, int proxylen); + FMOD_RESULT F_API setNetworkTimeout (int timeout); + FMOD_RESULT F_API getNetworkTimeout (int *timeout); + + // Userdata set/get. + FMOD_RESULT F_API setUserData (void *userdata); + FMOD_RESULT F_API getUserData (void **userdata); + }; + + /* + 'Sound' API + */ + class Sound + { + private: + + // Constructor made private so user cannot statically instance a Sound class. Appropriate Sound creation or retrieval function must be used. + Sound(); + Sound(const Sound &); + + public: + + FMOD_RESULT F_API release (); + FMOD_RESULT F_API getSystemObject (System **system); + + // Standard sound manipulation functions. + FMOD_RESULT F_API lock (unsigned int offset, unsigned int length, void **ptr1, void **ptr2, unsigned int *len1, unsigned int *len2); + FMOD_RESULT F_API unlock (void *ptr1, void *ptr2, unsigned int len1, unsigned int len2); + FMOD_RESULT F_API setDefaults (float frequency, int priority); + FMOD_RESULT F_API getDefaults (float *frequency, int *priority); + FMOD_RESULT F_API set3DMinMaxDistance (float min, float max); + FMOD_RESULT F_API get3DMinMaxDistance (float *min, float *max); + FMOD_RESULT F_API set3DConeSettings (float insideconeangle, float outsideconeangle, float outsidevolume); + FMOD_RESULT F_API get3DConeSettings (float *insideconeangle, float *outsideconeangle, float *outsidevolume); + FMOD_RESULT F_API set3DCustomRolloff (FMOD_VECTOR *points, int numpoints); + FMOD_RESULT F_API get3DCustomRolloff (FMOD_VECTOR **points, int *numpoints); + FMOD_RESULT F_API getSubSound (int index, Sound **subsound); + FMOD_RESULT F_API getSubSoundParent (Sound **parentsound); + FMOD_RESULT F_API getName (char *name, int namelen); + FMOD_RESULT F_API getLength (unsigned int *length, FMOD_TIMEUNIT lengthtype); + FMOD_RESULT F_API getFormat (FMOD_SOUND_TYPE *type, FMOD_SOUND_FORMAT *format, int *channels, int *bits); + FMOD_RESULT F_API getNumSubSounds (int *numsubsounds); + FMOD_RESULT F_API getNumTags (int *numtags, int *numtagsupdated); + FMOD_RESULT F_API getTag (const char *name, int index, FMOD_TAG *tag); + FMOD_RESULT F_API getOpenState (FMOD_OPENSTATE *openstate, unsigned int *percentbuffered, bool *starving, bool *diskbusy); + FMOD_RESULT F_API readData (void *buffer, unsigned int length, unsigned int *read); + FMOD_RESULT F_API seekData (unsigned int pcm); + + FMOD_RESULT F_API setSoundGroup (SoundGroup *soundgroup); + FMOD_RESULT F_API getSoundGroup (SoundGroup **soundgroup); + + // Synchronization point API. These points can come from markers embedded in wav files, and can also generate channel callbacks. + FMOD_RESULT F_API getNumSyncPoints (int *numsyncpoints); + FMOD_RESULT F_API getSyncPoint (int index, FMOD_SYNCPOINT **point); + FMOD_RESULT F_API getSyncPointInfo (FMOD_SYNCPOINT *point, char *name, int namelen, unsigned int *offset, FMOD_TIMEUNIT offsettype); + FMOD_RESULT F_API addSyncPoint (unsigned int offset, FMOD_TIMEUNIT offsettype, const char *name, FMOD_SYNCPOINT **point); + FMOD_RESULT F_API deleteSyncPoint (FMOD_SYNCPOINT *point); + + // Functions also in Channel class but here they are the 'default' to save having to change it in Channel all the time. + FMOD_RESULT F_API setMode (FMOD_MODE mode); + FMOD_RESULT F_API getMode (FMOD_MODE *mode); + FMOD_RESULT F_API setLoopCount (int loopcount); + FMOD_RESULT F_API getLoopCount (int *loopcount); + FMOD_RESULT F_API setLoopPoints (unsigned int loopstart, FMOD_TIMEUNIT loopstarttype, unsigned int loopend, FMOD_TIMEUNIT loopendtype); + FMOD_RESULT F_API getLoopPoints (unsigned int *loopstart, FMOD_TIMEUNIT loopstarttype, unsigned int *loopend, FMOD_TIMEUNIT loopendtype); + + // For MOD/S3M/XM/IT/MID sequenced formats only. + FMOD_RESULT F_API getMusicNumChannels (int *numchannels); + FMOD_RESULT F_API setMusicChannelVolume (int channel, float volume); + FMOD_RESULT F_API getMusicChannelVolume (int channel, float *volume); + FMOD_RESULT F_API setMusicSpeed (float speed); + FMOD_RESULT F_API getMusicSpeed (float *speed); + + // Userdata set/get. + FMOD_RESULT F_API setUserData (void *userdata); + FMOD_RESULT F_API getUserData (void **userdata); + }; + + + /* + 'ChannelControl API'. This is a base class for Channel and ChannelGroup so they can share the same functionality. This cannot be used or instansiated explicitly. + */ + class ChannelControl + { + private: + + // Constructor made private so user cannot statically instance a Control class. + ChannelControl(); + ChannelControl(const ChannelControl &); + + public: + + FMOD_RESULT F_API getSystemObject (System **system); + + // General control functionality for Channels and ChannelGroups. + FMOD_RESULT F_API stop (); + FMOD_RESULT F_API setPaused (bool paused); + FMOD_RESULT F_API getPaused (bool *paused); + FMOD_RESULT F_API setVolume (float volume); + FMOD_RESULT F_API getVolume (float *volume); + FMOD_RESULT F_API setVolumeRamp (bool ramp); + FMOD_RESULT F_API getVolumeRamp (bool *ramp); + FMOD_RESULT F_API getAudibility (float *audibility); + FMOD_RESULT F_API setPitch (float pitch); + FMOD_RESULT F_API getPitch (float *pitch); + FMOD_RESULT F_API setMute (bool mute); + FMOD_RESULT F_API getMute (bool *mute); + FMOD_RESULT F_API setReverbProperties (int instance, float wet); + FMOD_RESULT F_API getReverbProperties (int instance, float *wet); + FMOD_RESULT F_API setLowPassGain (float gain); + FMOD_RESULT F_API getLowPassGain (float *gain); + FMOD_RESULT F_API setMode (FMOD_MODE mode); + FMOD_RESULT F_API getMode (FMOD_MODE *mode); + FMOD_RESULT F_API setCallback (FMOD_CHANNELCONTROL_CALLBACK callback); + FMOD_RESULT F_API isPlaying (bool *isplaying); + + // Panning and level adjustment. + // Note all 'set' functions alter a final matrix, this is why the only get function is getMixMatrix, to avoid other get functions returning incorrect/obsolete values. + FMOD_RESULT F_API setPan (float pan); + FMOD_RESULT F_API setMixLevelsOutput (float frontleft, float frontright, float center, float lfe, float surroundleft, float surroundright, float backleft, float backright); + FMOD_RESULT F_API setMixLevelsInput (float *levels, int numlevels); + FMOD_RESULT F_API setMixMatrix (float *matrix, int outchannels, int inchannels, int inchannel_hop = 0); + FMOD_RESULT F_API getMixMatrix (float *matrix, int *outchannels, int *inchannels, int inchannel_hop = 0); + + // Clock based functionality. + FMOD_RESULT F_API getDSPClock (unsigned long long *dspclock, unsigned long long *parentclock); + FMOD_RESULT F_API setDelay (unsigned long long dspclock_start, unsigned long long dspclock_end, bool stopchannels = true); + FMOD_RESULT F_API getDelay (unsigned long long *dspclock_start, unsigned long long *dspclock_end, bool *stopchannels = 0); + FMOD_RESULT F_API addFadePoint (unsigned long long dspclock, float volume); + FMOD_RESULT F_API setFadePointRamp (unsigned long long dspclock, float volume); + FMOD_RESULT F_API removeFadePoints (unsigned long long dspclock_start, unsigned long long dspclock_end); + FMOD_RESULT F_API getFadePoints (unsigned int *numpoints, unsigned long long *point_dspclock, float *point_volume); + + // DSP effects. + FMOD_RESULT F_API getDSP (int index, DSP **dsp); + FMOD_RESULT F_API addDSP (int index, DSP *dsp); + FMOD_RESULT F_API removeDSP (DSP *dsp); + FMOD_RESULT F_API getNumDSPs (int *numdsps); + FMOD_RESULT F_API setDSPIndex (DSP *dsp, int index); + FMOD_RESULT F_API getDSPIndex (DSP *dsp, int *index); + + // 3D functionality. + FMOD_RESULT F_API set3DAttributes (const FMOD_VECTOR *pos, const FMOD_VECTOR *vel); + FMOD_RESULT F_API get3DAttributes (FMOD_VECTOR *pos, FMOD_VECTOR *vel); + FMOD_RESULT F_API set3DMinMaxDistance (float mindistance, float maxdistance); + FMOD_RESULT F_API get3DMinMaxDistance (float *mindistance, float *maxdistance); + FMOD_RESULT F_API set3DConeSettings (float insideconeangle, float outsideconeangle, float outsidevolume); + FMOD_RESULT F_API get3DConeSettings (float *insideconeangle, float *outsideconeangle, float *outsidevolume); + FMOD_RESULT F_API set3DConeOrientation (FMOD_VECTOR *orientation); + FMOD_RESULT F_API get3DConeOrientation (FMOD_VECTOR *orientation); + FMOD_RESULT F_API set3DCustomRolloff (FMOD_VECTOR *points, int numpoints); + FMOD_RESULT F_API get3DCustomRolloff (FMOD_VECTOR **points, int *numpoints); + FMOD_RESULT F_API set3DOcclusion (float directocclusion, float reverbocclusion); + FMOD_RESULT F_API get3DOcclusion (float *directocclusion, float *reverbocclusion); + FMOD_RESULT F_API set3DSpread (float angle); + FMOD_RESULT F_API get3DSpread (float *angle); + FMOD_RESULT F_API set3DLevel (float level); + FMOD_RESULT F_API get3DLevel (float *level); + FMOD_RESULT F_API set3DDopplerLevel (float level); + FMOD_RESULT F_API get3DDopplerLevel (float *level); + FMOD_RESULT F_API set3DDistanceFilter (bool custom, float customLevel, float centerFreq); + FMOD_RESULT F_API get3DDistanceFilter (bool *custom, float *customLevel, float *centerFreq); + + // Userdata set/get. + FMOD_RESULT F_API setUserData (void *userdata); + FMOD_RESULT F_API getUserData (void **userdata); + }; + + /* + 'Channel' API. + */ + class Channel : public ChannelControl + { + private: + + // Constructor made private so user cannot statically instance a Channel class. Appropriate Channel creation or retrieval function must be used. + Channel(); + Channel(const Channel &); + + public: + + // Channel specific control functionality. + FMOD_RESULT F_API setFrequency (float frequency); + FMOD_RESULT F_API getFrequency (float *frequency); + FMOD_RESULT F_API setPriority (int priority); + FMOD_RESULT F_API getPriority (int *priority); + FMOD_RESULT F_API setPosition (unsigned int position, FMOD_TIMEUNIT postype); + FMOD_RESULT F_API getPosition (unsigned int *position, FMOD_TIMEUNIT postype); + FMOD_RESULT F_API setChannelGroup (ChannelGroup *channelgroup); + FMOD_RESULT F_API getChannelGroup (ChannelGroup **channelgroup); + FMOD_RESULT F_API setLoopCount (int loopcount); + FMOD_RESULT F_API getLoopCount (int *loopcount); + FMOD_RESULT F_API setLoopPoints (unsigned int loopstart, FMOD_TIMEUNIT loopstarttype, unsigned int loopend, FMOD_TIMEUNIT loopendtype); + FMOD_RESULT F_API getLoopPoints (unsigned int *loopstart, FMOD_TIMEUNIT loopstarttype, unsigned int *loopend, FMOD_TIMEUNIT loopendtype); + + // Information only functions. + FMOD_RESULT F_API isVirtual (bool *isvirtual); + FMOD_RESULT F_API getCurrentSound (Sound **sound); + FMOD_RESULT F_API getIndex (int *index); + }; + + /* + 'ChannelGroup' API + */ + class ChannelGroup : public ChannelControl + { + private: + + // Constructor made private so user cannot statically instance a ChannelGroup class. Appropriate ChannelGroup creation or retrieval function must be used. + ChannelGroup(); + ChannelGroup(const ChannelGroup &); + + public: + + FMOD_RESULT F_API release (); + + // Nested channel groups. + FMOD_RESULT F_API addGroup (ChannelGroup *group, bool propagatedspclock = true, DSPConnection **connection = 0); + FMOD_RESULT F_API getNumGroups (int *numgroups); + FMOD_RESULT F_API getGroup (int index, ChannelGroup **group); + FMOD_RESULT F_API getParentGroup (ChannelGroup **group); + + // Information only functions. + FMOD_RESULT F_API getName (char *name, int namelen); + FMOD_RESULT F_API getNumChannels (int *numchannels); + FMOD_RESULT F_API getChannel (int index, Channel **channel); + }; + + /* + 'SoundGroup' API + */ + class SoundGroup + { + private: + + // Constructor made private so user cannot statically instance a SoundGroup class. Appropriate SoundGroup creation or retrieval function must be used. + SoundGroup(); + SoundGroup(const SoundGroup &); + + public: + + FMOD_RESULT F_API release (); + FMOD_RESULT F_API getSystemObject (System **system); + + // SoundGroup control functions. + FMOD_RESULT F_API setMaxAudible (int maxaudible); + FMOD_RESULT F_API getMaxAudible (int *maxaudible); + FMOD_RESULT F_API setMaxAudibleBehavior (FMOD_SOUNDGROUP_BEHAVIOR behavior); + FMOD_RESULT F_API getMaxAudibleBehavior (FMOD_SOUNDGROUP_BEHAVIOR *behavior); + FMOD_RESULT F_API setMuteFadeSpeed (float speed); + FMOD_RESULT F_API getMuteFadeSpeed (float *speed); + FMOD_RESULT F_API setVolume (float volume); + FMOD_RESULT F_API getVolume (float *volume); + FMOD_RESULT F_API stop (); + + // Information only functions. + FMOD_RESULT F_API getName (char *name, int namelen); + FMOD_RESULT F_API getNumSounds (int *numsounds); + FMOD_RESULT F_API getSound (int index, Sound **sound); + FMOD_RESULT F_API getNumPlaying (int *numplaying); + + // Userdata set/get. + FMOD_RESULT F_API setUserData (void *userdata); + FMOD_RESULT F_API getUserData (void **userdata); + }; + + /* + 'DSP' API + */ + class DSP + { + private: + + // Constructor made private so user cannot statically instance a DSP class. Appropriate DSP creation or retrieval function must be used. + DSP(); + DSP(const DSP &); + + public: + + FMOD_RESULT F_API release (); + FMOD_RESULT F_API getSystemObject (System **system); + + // Connection / disconnection / input and output enumeration. + FMOD_RESULT F_API addInput (DSP *input, DSPConnection **connection = 0, FMOD_DSPCONNECTION_TYPE type = FMOD_DSPCONNECTION_TYPE_STANDARD); + FMOD_RESULT F_API addInputPreallocated (DSP *input, DSPConnection **connection = 0); + FMOD_RESULT F_API disconnectFrom (DSP *target, DSPConnection *connection = 0); + FMOD_RESULT F_API disconnectAll (bool inputs, bool outputs); + FMOD_RESULT F_API getNumInputs (int *numinputs); + FMOD_RESULT F_API getNumOutputs (int *numoutputs); + FMOD_RESULT F_API getInput (int index, DSP **input, DSPConnection **inputconnection); + FMOD_RESULT F_API getOutput (int index, DSP **output, DSPConnection **outputconnection); + + // DSP unit control. + FMOD_RESULT F_API setActive (bool active); + FMOD_RESULT F_API getActive (bool *active); + FMOD_RESULT F_API setBypass (bool bypass); + FMOD_RESULT F_API getBypass (bool *bypass); + FMOD_RESULT F_API setWetDryMix (float prewet, float postwet, float dry); + FMOD_RESULT F_API getWetDryMix (float *prewet, float *postwet, float *dry); + FMOD_RESULT F_API setChannelFormat (FMOD_CHANNELMASK channelmask, int numchannels, FMOD_SPEAKERMODE source_speakermode); + FMOD_RESULT F_API getChannelFormat (FMOD_CHANNELMASK *channelmask, int *numchannels, FMOD_SPEAKERMODE *source_speakermode); + FMOD_RESULT F_API getOutputChannelFormat (FMOD_CHANNELMASK inmask, int inchannels, FMOD_SPEAKERMODE inspeakermode, FMOD_CHANNELMASK *outmask, int *outchannels, FMOD_SPEAKERMODE *outspeakermode); + FMOD_RESULT F_API reset (); + FMOD_RESULT F_API setCallback (FMOD_DSP_CALLBACK callback); + + // DSP parameter control. + FMOD_RESULT F_API setParameterFloat (int index, float value); + FMOD_RESULT F_API setParameterInt (int index, int value); + FMOD_RESULT F_API setParameterBool (int index, bool value); + FMOD_RESULT F_API setParameterData (int index, void *data, unsigned int length); + FMOD_RESULT F_API getParameterFloat (int index, float *value, char *valuestr, int valuestrlen); + FMOD_RESULT F_API getParameterInt (int index, int *value, char *valuestr, int valuestrlen); + FMOD_RESULT F_API getParameterBool (int index, bool *value, char *valuestr, int valuestrlen); + FMOD_RESULT F_API getParameterData (int index, void **data, unsigned int *length, char *valuestr, int valuestrlen); + FMOD_RESULT F_API getNumParameters (int *numparams); + FMOD_RESULT F_API getParameterInfo (int index, FMOD_DSP_PARAMETER_DESC **desc); + FMOD_RESULT F_API getDataParameterIndex (int datatype, int *index); + FMOD_RESULT F_API showConfigDialog (void *hwnd, bool show); + + // DSP attributes. + FMOD_RESULT F_API getInfo (char *name, unsigned int *version, int *channels, int *configwidth, int *configheight); + FMOD_RESULT F_API getType (FMOD_DSP_TYPE *type); + FMOD_RESULT F_API getIdle (bool *idle); + + // Userdata set/get. + FMOD_RESULT F_API setUserData (void *userdata); + FMOD_RESULT F_API getUserData (void **userdata); + + // Metering. + FMOD_RESULT F_API setMeteringEnabled (bool inputEnabled, bool outputEnabled); + FMOD_RESULT F_API getMeteringEnabled (bool *inputEnabled, bool *outputEnabled); + FMOD_RESULT F_API getMeteringInfo (FMOD_DSP_METERING_INFO *inputInfo, FMOD_DSP_METERING_INFO *outputInfo); + FMOD_RESULT F_API getCPUUsage (unsigned int *exclusive, unsigned int *inclusive); + }; + + + /* + 'DSPConnection' API + */ + class DSPConnection + { + private: + + // Constructor made private so user cannot statically instance a DSPConnection class. Appropriate DSPConnection creation or retrieval function must be used. + DSPConnection(); + DSPConnection(const DSPConnection &); + + public: + + FMOD_RESULT F_API getInput (DSP **input); + FMOD_RESULT F_API getOutput (DSP **output); + FMOD_RESULT F_API setMix (float volume); + FMOD_RESULT F_API getMix (float *volume); + FMOD_RESULT F_API setMixMatrix (float *matrix, int outchannels, int inchannels, int inchannel_hop = 0); + FMOD_RESULT F_API getMixMatrix (float *matrix, int *outchannels, int *inchannels, int inchannel_hop = 0); + FMOD_RESULT F_API getType (FMOD_DSPCONNECTION_TYPE *type); + + // Userdata set/get. + FMOD_RESULT F_API setUserData (void *userdata); + FMOD_RESULT F_API getUserData (void **userdata); + }; + + + /* + 'Geometry' API + */ + class Geometry + { + private: + + // Constructor made private so user cannot statically instance a Geometry class. Appropriate Geometry creation or retrieval function must be used. + Geometry(); + Geometry(const Geometry &); + + public: + + FMOD_RESULT F_API release (); + + // Polygon manipulation. + FMOD_RESULT F_API addPolygon (float directocclusion, float reverbocclusion, bool doublesided, int numvertices, const FMOD_VECTOR *vertices, int *polygonindex); + FMOD_RESULT F_API getNumPolygons (int *numpolygons); + FMOD_RESULT F_API getMaxPolygons (int *maxpolygons, int *maxvertices); + FMOD_RESULT F_API getPolygonNumVertices (int index, int *numvertices); + FMOD_RESULT F_API setPolygonVertex (int index, int vertexindex, const FMOD_VECTOR *vertex); + FMOD_RESULT F_API getPolygonVertex (int index, int vertexindex, FMOD_VECTOR *vertex); + FMOD_RESULT F_API setPolygonAttributes (int index, float directocclusion, float reverbocclusion, bool doublesided); + FMOD_RESULT F_API getPolygonAttributes (int index, float *directocclusion, float *reverbocclusion, bool *doublesided); + + // Object manipulation. + FMOD_RESULT F_API setActive (bool active); + FMOD_RESULT F_API getActive (bool *active); + FMOD_RESULT F_API setRotation (const FMOD_VECTOR *forward, const FMOD_VECTOR *up); + FMOD_RESULT F_API getRotation (FMOD_VECTOR *forward, FMOD_VECTOR *up); + FMOD_RESULT F_API setPosition (const FMOD_VECTOR *position); + FMOD_RESULT F_API getPosition (FMOD_VECTOR *position); + FMOD_RESULT F_API setScale (const FMOD_VECTOR *scale); + FMOD_RESULT F_API getScale (FMOD_VECTOR *scale); + FMOD_RESULT F_API save (void *data, int *datasize); + + // Userdata set/get. + FMOD_RESULT F_API setUserData (void *userdata); + FMOD_RESULT F_API getUserData (void **userdata); + }; + + + /* + 'Reverb' API + */ + class Reverb3D + { + private: + + // Constructor made private so user cannot statically instance a Reverb3D class. Appropriate Reverb creation or retrieval function must be used. + Reverb3D(); + Reverb3D(const Reverb3D &); + + public: + + FMOD_RESULT F_API release (); + + // Reverb manipulation. + FMOD_RESULT F_API set3DAttributes (const FMOD_VECTOR *position, float mindistance, float maxdistance); + FMOD_RESULT F_API get3DAttributes (FMOD_VECTOR *position, float *mindistance,float *maxdistance); + FMOD_RESULT F_API setProperties (const FMOD_REVERB_PROPERTIES *properties); + FMOD_RESULT F_API getProperties (FMOD_REVERB_PROPERTIES *properties); + FMOD_RESULT F_API setActive (bool active); + FMOD_RESULT F_API getActive (bool *active); + + // Userdata set/get. + FMOD_RESULT F_API setUserData (void *userdata); + FMOD_RESULT F_API getUserData (void **userdata); + }; +} + +#endif diff --git a/FMOD/api/core/inc/fmod_codec.h b/FMOD/api/core/inc/fmod_codec.h new file mode 100644 index 0000000..a8266d4 --- /dev/null +++ b/FMOD/api/core/inc/fmod_codec.h @@ -0,0 +1,136 @@ +/* ======================================================================================== */ +/* FMOD Core API - Codec development header file. */ +/* Copyright (c), Firelight Technologies Pty, Ltd. 2004-2026. */ +/* */ +/* Use this header if you are wanting to develop your own file format plugin to use with */ +/* FMOD's codec system. With this header you can make your own fileformat plugin that FMOD */ +/* can register and use. See the documentation and examples on how to make a working */ +/* plugin. */ +/* */ +/* For more detail visit: */ +/* https://fmod.com/docs/2.03/api/core-api.html */ +/* ======================================================================================== */ +#ifndef _FMOD_CODEC_H +#define _FMOD_CODEC_H + +/* + Codec types +*/ +typedef struct FMOD_CODEC_STATE FMOD_CODEC_STATE; +typedef struct FMOD_CODEC_WAVEFORMAT FMOD_CODEC_WAVEFORMAT; + +/* + Codec constants +*/ +#define FMOD_CODEC_PLUGIN_VERSION 1 + +typedef int FMOD_CODEC_SEEK_METHOD; +#define FMOD_CODEC_SEEK_METHOD_SET 0 +#define FMOD_CODEC_SEEK_METHOD_CURRENT 1 +#define FMOD_CODEC_SEEK_METHOD_END 2 + +/* + Codec callbacks +*/ +typedef FMOD_RESULT (F_CALL *FMOD_CODEC_OPEN_CALLBACK) (FMOD_CODEC_STATE *codec_state, FMOD_MODE usermode, FMOD_CREATESOUNDEXINFO *userexinfo); +typedef FMOD_RESULT (F_CALL *FMOD_CODEC_CLOSE_CALLBACK) (FMOD_CODEC_STATE *codec_state); +typedef FMOD_RESULT (F_CALL *FMOD_CODEC_READ_CALLBACK) (FMOD_CODEC_STATE *codec_state, void *buffer, unsigned int samples_in, unsigned int *samples_out); +typedef FMOD_RESULT (F_CALL *FMOD_CODEC_GETLENGTH_CALLBACK) (FMOD_CODEC_STATE *codec_state, unsigned int *length, FMOD_TIMEUNIT lengthtype); +typedef FMOD_RESULT (F_CALL *FMOD_CODEC_SETPOSITION_CALLBACK) (FMOD_CODEC_STATE *codec_state, int subsound, unsigned int position, FMOD_TIMEUNIT postype); +typedef FMOD_RESULT (F_CALL *FMOD_CODEC_GETPOSITION_CALLBACK) (FMOD_CODEC_STATE *codec_state, unsigned int *position, FMOD_TIMEUNIT postype); +typedef FMOD_RESULT (F_CALL *FMOD_CODEC_SOUNDCREATE_CALLBACK) (FMOD_CODEC_STATE *codec_state, int subsound, FMOD_SOUND *sound); +typedef FMOD_RESULT (F_CALL *FMOD_CODEC_GETWAVEFORMAT_CALLBACK)(FMOD_CODEC_STATE *codec_state, int index, FMOD_CODEC_WAVEFORMAT *waveformat); + +/* + Codec functions +*/ +typedef FMOD_RESULT (F_CALL *FMOD_CODEC_METADATA_FUNC) (FMOD_CODEC_STATE *codec_state, FMOD_TAGTYPE tagtype, char *name, void *data, unsigned int datalen, FMOD_TAGDATATYPE datatype, int unique); +typedef void * (F_CALL *FMOD_CODEC_ALLOC_FUNC) (unsigned int size, unsigned int align, const char *file, int line); +typedef void (F_CALL *FMOD_CODEC_FREE_FUNC) (void *ptr, const char *file, int line); +typedef void (F_CALL *FMOD_CODEC_LOG_FUNC) (FMOD_DEBUG_FLAGS level, const char *file, int line, const char *function, const char *string, ...); + +typedef FMOD_RESULT (F_CALL *FMOD_CODEC_FILE_READ_FUNC) (FMOD_CODEC_STATE *codec_state, void *buffer, unsigned int sizebytes, unsigned int *bytesread); +typedef FMOD_RESULT (F_CALL *FMOD_CODEC_FILE_SEEK_FUNC) (FMOD_CODEC_STATE *codec_state, unsigned int pos, FMOD_CODEC_SEEK_METHOD method); +typedef FMOD_RESULT (F_CALL *FMOD_CODEC_FILE_TELL_FUNC) (FMOD_CODEC_STATE *codec_state, unsigned int *pos); +typedef FMOD_RESULT (F_CALL *FMOD_CODEC_FILE_SIZE_FUNC) (FMOD_CODEC_STATE *codec_state, unsigned int *size); + +/* + Codec structures +*/ +typedef struct FMOD_CODEC_DESCRIPTION +{ + unsigned int apiversion; + const char *name; + unsigned int version; + int defaultasstream; + FMOD_TIMEUNIT timeunits; + FMOD_CODEC_OPEN_CALLBACK open; + FMOD_CODEC_CLOSE_CALLBACK close; + FMOD_CODEC_READ_CALLBACK read; + FMOD_CODEC_GETLENGTH_CALLBACK getlength; + FMOD_CODEC_SETPOSITION_CALLBACK setposition; + FMOD_CODEC_GETPOSITION_CALLBACK getposition; + FMOD_CODEC_SOUNDCREATE_CALLBACK soundcreate; + FMOD_CODEC_GETWAVEFORMAT_CALLBACK getwaveformat; +} FMOD_CODEC_DESCRIPTION; + +struct FMOD_CODEC_WAVEFORMAT +{ + const char* name; + FMOD_SOUND_FORMAT format; + int channels; + int frequency; + unsigned int lengthbytes; + unsigned int lengthpcm; + unsigned int pcmblocksize; + int loopstart; + int loopend; + FMOD_MODE mode; + FMOD_CHANNELMASK channelmask; + FMOD_CHANNELORDER channelorder; + float peakvolume; +}; + +typedef struct FMOD_CODEC_STATE_FUNCTIONS +{ + FMOD_CODEC_METADATA_FUNC metadata; + FMOD_CODEC_ALLOC_FUNC alloc; + FMOD_CODEC_FREE_FUNC free; + FMOD_CODEC_LOG_FUNC log; + FMOD_CODEC_FILE_READ_FUNC read; + FMOD_CODEC_FILE_SEEK_FUNC seek; + FMOD_CODEC_FILE_TELL_FUNC tell; + FMOD_CODEC_FILE_SIZE_FUNC size; +} FMOD_CODEC_STATE_FUNCTIONS; + +struct FMOD_CODEC_STATE +{ + void *plugindata; + FMOD_CODEC_WAVEFORMAT *waveformat; + FMOD_CODEC_STATE_FUNCTIONS *functions; + int numsubsounds; +}; + +/* + Codec macros +*/ +#define FMOD_CODEC_METADATA(_state, _tagtype, _name, _data, _datalen, _datatype, _unique) \ + (_state)->functions->metadata(_state, _tagtype, _name, _data, _datalen, _datatype, _unique) +#define FMOD_CODEC_ALLOC(_state, _size, _align) \ + (_state)->functions->alloc(_size, _align, __FILE__, __LINE__) +#define FMOD_CODEC_FREE(_state, _ptr) \ + (_state)->functions->free(_ptr, __FILE__, __LINE__) +#define FMOD_CODEC_LOG(_state, _level, _location, _format, ...) \ + (_state)->functions->log(_level, __FILE__, __LINE__, _location, _format, ##__VA_ARGS__) +#define FMOD_CODEC_FILE_READ(_state, _buffer, _sizebytes, _bytesread) \ + (_state)->functions->read(_state, _buffer, _sizebytes, _bytesread) +#define FMOD_CODEC_FILE_SEEK(_state, _pos, _method) \ + (_state)->functions->seek(_state, _pos, _method) +#define FMOD_CODEC_FILE_TELL(_state, _pos) \ + (_state)->functions->tell(_state, _pos) +#define FMOD_CODEC_FILE_SIZE(_state, _size) \ + (_state)->functions->size(_state, _size) + +#endif + + diff --git a/FMOD/api/core/inc/fmod_common.h b/FMOD/api/core/inc/fmod_common.h new file mode 100644 index 0000000..0db5d15 --- /dev/null +++ b/FMOD/api/core/inc/fmod_common.h @@ -0,0 +1,901 @@ +/* ======================================================================================== */ +/* FMOD Core API - Common C/C++ header file. */ +/* Copyright (c), Firelight Technologies Pty, Ltd. 2004-2026. */ +/* */ +/* This header is included by fmod.hpp (C++ interface) and fmod.h (C interface) */ +/* */ +/* For more detail visit: */ +/* https://fmod.com/docs/2.03/api/core-api-common.html */ +/* ======================================================================================== */ +#ifndef _FMOD_COMMON_H +#define _FMOD_COMMON_H + +/* + Library import helpers +*/ +#if defined(_WIN32) || defined(__CYGWIN__) + #define F_CALL __stdcall +#else + #define F_CALL +#endif + +#if defined(_WIN32) || defined(__CYGWIN__) || defined(__ORBIS__) || defined(F_USE_DECLSPEC) + #define F_EXPORT __declspec(dllexport) +#elif defined(__APPLE__) || defined(__ANDROID__) || defined(__linux__) || defined(F_USE_ATTRIBUTE) + #define F_EXPORT __attribute__((visibility("default"))) +#else + #define F_EXPORT +#endif + +#ifdef DLL_EXPORTS + #define F_API F_EXPORT F_CALL +#else + #define F_API F_CALL +#endif + +/* + FMOD core types +*/ +typedef int FMOD_BOOL; +typedef struct FMOD_SYSTEM FMOD_SYSTEM; +typedef struct FMOD_SOUND FMOD_SOUND; +typedef struct FMOD_CHANNELCONTROL FMOD_CHANNELCONTROL; +typedef struct FMOD_CHANNEL FMOD_CHANNEL; +typedef struct FMOD_CHANNELGROUP FMOD_CHANNELGROUP; +typedef struct FMOD_SOUNDGROUP FMOD_SOUNDGROUP; +typedef struct FMOD_REVERB3D FMOD_REVERB3D; +typedef struct FMOD_DSP FMOD_DSP; +typedef struct FMOD_DSPCONNECTION FMOD_DSPCONNECTION; +typedef struct FMOD_POLYGON FMOD_POLYGON; +typedef struct FMOD_GEOMETRY FMOD_GEOMETRY; +typedef struct FMOD_SYNCPOINT FMOD_SYNCPOINT; +typedef struct FMOD_ASYNCREADINFO FMOD_ASYNCREADINFO; + +/* + FMOD constants +*/ +#define FMOD_VERSION 0x00020313 /* 0xaaaabbcc -> aaaa = product version, bb = major version, cc = minor version.*/ +#define FMOD_BUILDNUMBER 162576 + +typedef unsigned int FMOD_DEBUG_FLAGS; +#define FMOD_DEBUG_LEVEL_NONE 0x00000000 +#define FMOD_DEBUG_LEVEL_ERROR 0x00000001 +#define FMOD_DEBUG_LEVEL_WARNING 0x00000002 +#define FMOD_DEBUG_LEVEL_LOG 0x00000004 +#define FMOD_DEBUG_TYPE_MEMORY 0x00000100 +#define FMOD_DEBUG_TYPE_FILE 0x00000200 +#define FMOD_DEBUG_TYPE_CODEC 0x00000400 +#define FMOD_DEBUG_TYPE_TRACE 0x00000800 +#define FMOD_DEBUG_TYPE_VIRTUAL 0x00001000 +#define FMOD_DEBUG_DISPLAY_TIMESTAMPS 0x00010000 +#define FMOD_DEBUG_DISPLAY_LINENUMBERS 0x00020000 +#define FMOD_DEBUG_DISPLAY_THREAD 0x00040000 + +typedef unsigned int FMOD_MEMORY_TYPE; +#define FMOD_MEMORY_NORMAL 0x00000000 +#define FMOD_MEMORY_STREAM_FILE 0x00000001 +#define FMOD_MEMORY_STREAM_DECODE 0x00000002 +#define FMOD_MEMORY_SAMPLEDATA 0x00000004 +#define FMOD_MEMORY_DSP_BUFFER 0x00000008 +#define FMOD_MEMORY_PLUGIN 0x00000010 +#define FMOD_MEMORY_PERSISTENT 0x00200000 +#define FMOD_MEMORY_ALL 0xFFFFFFFF + +typedef unsigned int FMOD_INITFLAGS; +#define FMOD_INIT_NORMAL 0x00000000 +#define FMOD_INIT_STREAM_FROM_UPDATE 0x00000001 +#define FMOD_INIT_MIX_FROM_UPDATE 0x00000002 +#define FMOD_INIT_3D_RIGHTHANDED 0x00000004 +#define FMOD_INIT_CLIP_OUTPUT 0x00000008 +#define FMOD_INIT_CHANNEL_LOWPASS 0x00000100 +#define FMOD_INIT_CHANNEL_DISTANCEFILTER 0x00000200 +#define FMOD_INIT_PROFILE_ENABLE 0x00010000 +#define FMOD_INIT_VOL0_BECOMES_VIRTUAL 0x00020000 +#define FMOD_INIT_GEOMETRY_USECLOSEST 0x00040000 +#define FMOD_INIT_PREFER_DOLBY_DOWNMIX 0x00080000 +#define FMOD_INIT_THREAD_UNSAFE 0x00100000 +#define FMOD_INIT_PROFILE_METER_ALL 0x00200000 +#define FMOD_INIT_MEMORY_TRACKING 0x00400000 + +typedef unsigned int FMOD_DRIVER_STATE; +#define FMOD_DRIVER_STATE_CONNECTED 0x00000001 +#define FMOD_DRIVER_STATE_DEFAULT 0x00000002 + +typedef unsigned int FMOD_TIMEUNIT; +#define FMOD_TIMEUNIT_MS 0x00000001 +#define FMOD_TIMEUNIT_PCM 0x00000002 +#define FMOD_TIMEUNIT_PCMBYTES 0x00000004 +#define FMOD_TIMEUNIT_RAWBYTES 0x00000008 +#define FMOD_TIMEUNIT_PCMFRACTION 0x00000010 +#define FMOD_TIMEUNIT_MODORDER 0x00000100 +#define FMOD_TIMEUNIT_MODROW 0x00000200 +#define FMOD_TIMEUNIT_MODPATTERN 0x00000400 + +typedef unsigned int FMOD_SYSTEM_CALLBACK_TYPE; +#define FMOD_SYSTEM_CALLBACK_DEVICELISTCHANGED 0x00000001 +#define FMOD_SYSTEM_CALLBACK_DEVICELOST 0x00000002 +#define FMOD_SYSTEM_CALLBACK_MEMORYALLOCATIONFAILED 0x00000004 +#define FMOD_SYSTEM_CALLBACK_THREADCREATED 0x00000008 +#define FMOD_SYSTEM_CALLBACK_BADDSPCONNECTION 0x00000010 +#define FMOD_SYSTEM_CALLBACK_PREMIX 0x00000020 +#define FMOD_SYSTEM_CALLBACK_POSTMIX 0x00000040 +#define FMOD_SYSTEM_CALLBACK_ERROR 0x00000080 +#define FMOD_SYSTEM_CALLBACK_THREADDESTROYED 0x00000100 +#define FMOD_SYSTEM_CALLBACK_PREUPDATE 0x00000200 +#define FMOD_SYSTEM_CALLBACK_POSTUPDATE 0x00000400 +#define FMOD_SYSTEM_CALLBACK_RECORDLISTCHANGED 0x00000800 +#define FMOD_SYSTEM_CALLBACK_BUFFEREDNOMIX 0x00001000 +#define FMOD_SYSTEM_CALLBACK_DEVICEREINITIALIZE 0x00002000 +#define FMOD_SYSTEM_CALLBACK_OUTPUTUNDERRUN 0x00004000 +#define FMOD_SYSTEM_CALLBACK_RECORDPOSITIONCHANGED 0x00008000 +#define FMOD_SYSTEM_CALLBACK_ALL 0xFFFFFFFF + +typedef unsigned int FMOD_MODE; +#define FMOD_DEFAULT 0x00000000 +#define FMOD_LOOP_OFF 0x00000001 +#define FMOD_LOOP_NORMAL 0x00000002 +#define FMOD_LOOP_BIDI 0x00000004 +#define FMOD_2D 0x00000008 +#define FMOD_3D 0x00000010 +#define FMOD_CREATESTREAM 0x00000080 +#define FMOD_CREATESAMPLE 0x00000100 +#define FMOD_CREATECOMPRESSEDSAMPLE 0x00000200 +#define FMOD_OPENUSER 0x00000400 +#define FMOD_OPENMEMORY 0x00000800 +#define FMOD_OPENMEMORY_POINT 0x10000000 +#define FMOD_OPENRAW 0x00001000 +#define FMOD_OPENONLY 0x00002000 +#define FMOD_ACCURATETIME 0x00004000 +#define FMOD_MPEGSEARCH 0x00008000 +#define FMOD_NONBLOCKING 0x00010000 +#define FMOD_UNIQUE 0x00020000 +#define FMOD_3D_HEADRELATIVE 0x00040000 +#define FMOD_3D_WORLDRELATIVE 0x00080000 +#define FMOD_3D_INVERSEROLLOFF 0x00100000 +#define FMOD_3D_LINEARROLLOFF 0x00200000 +#define FMOD_3D_LINEARSQUAREROLLOFF 0x00400000 +#define FMOD_3D_INVERSETAPEREDROLLOFF 0x00800000 +#define FMOD_3D_CUSTOMROLLOFF 0x04000000 +#define FMOD_3D_IGNOREGEOMETRY 0x40000000 +#define FMOD_IGNORETAGS 0x02000000 +#define FMOD_LOWMEM 0x08000000 +#define FMOD_VIRTUAL_PLAYFROMSTART 0x80000000 + +typedef unsigned int FMOD_CHANNELMASK; +#define FMOD_CHANNELMASK_FRONT_LEFT 0x00000001 +#define FMOD_CHANNELMASK_FRONT_RIGHT 0x00000002 +#define FMOD_CHANNELMASK_FRONT_CENTER 0x00000004 +#define FMOD_CHANNELMASK_LOW_FREQUENCY 0x00000008 +#define FMOD_CHANNELMASK_SURROUND_LEFT 0x00000010 +#define FMOD_CHANNELMASK_SURROUND_RIGHT 0x00000020 +#define FMOD_CHANNELMASK_BACK_LEFT 0x00000040 +#define FMOD_CHANNELMASK_BACK_RIGHT 0x00000080 +#define FMOD_CHANNELMASK_BACK_CENTER 0x00000100 +#define FMOD_CHANNELMASK_MONO (FMOD_CHANNELMASK_FRONT_LEFT) +#define FMOD_CHANNELMASK_STEREO (FMOD_CHANNELMASK_FRONT_LEFT | FMOD_CHANNELMASK_FRONT_RIGHT) +#define FMOD_CHANNELMASK_LRC (FMOD_CHANNELMASK_FRONT_LEFT | FMOD_CHANNELMASK_FRONT_RIGHT | FMOD_CHANNELMASK_FRONT_CENTER) +#define FMOD_CHANNELMASK_QUAD (FMOD_CHANNELMASK_FRONT_LEFT | FMOD_CHANNELMASK_FRONT_RIGHT | FMOD_CHANNELMASK_SURROUND_LEFT | FMOD_CHANNELMASK_SURROUND_RIGHT) +#define FMOD_CHANNELMASK_SURROUND (FMOD_CHANNELMASK_FRONT_LEFT | FMOD_CHANNELMASK_FRONT_RIGHT | FMOD_CHANNELMASK_FRONT_CENTER | FMOD_CHANNELMASK_SURROUND_LEFT | FMOD_CHANNELMASK_SURROUND_RIGHT) +#define FMOD_CHANNELMASK_5POINT1 (FMOD_CHANNELMASK_FRONT_LEFT | FMOD_CHANNELMASK_FRONT_RIGHT | FMOD_CHANNELMASK_FRONT_CENTER | FMOD_CHANNELMASK_LOW_FREQUENCY | FMOD_CHANNELMASK_SURROUND_LEFT | FMOD_CHANNELMASK_SURROUND_RIGHT) +#define FMOD_CHANNELMASK_5POINT1_REARS (FMOD_CHANNELMASK_FRONT_LEFT | FMOD_CHANNELMASK_FRONT_RIGHT | FMOD_CHANNELMASK_FRONT_CENTER | FMOD_CHANNELMASK_LOW_FREQUENCY | FMOD_CHANNELMASK_BACK_LEFT | FMOD_CHANNELMASK_BACK_RIGHT) +#define FMOD_CHANNELMASK_7POINT0 (FMOD_CHANNELMASK_FRONT_LEFT | FMOD_CHANNELMASK_FRONT_RIGHT | FMOD_CHANNELMASK_FRONT_CENTER | FMOD_CHANNELMASK_SURROUND_LEFT | FMOD_CHANNELMASK_SURROUND_RIGHT | FMOD_CHANNELMASK_BACK_LEFT | FMOD_CHANNELMASK_BACK_RIGHT) +#define FMOD_CHANNELMASK_7POINT1 (FMOD_CHANNELMASK_FRONT_LEFT | FMOD_CHANNELMASK_FRONT_RIGHT | FMOD_CHANNELMASK_FRONT_CENTER | FMOD_CHANNELMASK_LOW_FREQUENCY | FMOD_CHANNELMASK_SURROUND_LEFT | FMOD_CHANNELMASK_SURROUND_RIGHT | FMOD_CHANNELMASK_BACK_LEFT | FMOD_CHANNELMASK_BACK_RIGHT) + +typedef unsigned long long FMOD_PORT_INDEX; +#define FMOD_PORT_INDEX_NONE 0xFFFFFFFFFFFFFFFF + +typedef int FMOD_THREAD_PRIORITY; +/* Platform specific priority range */ +#define FMOD_THREAD_PRIORITY_PLATFORM_MIN (-32 * 1024) +#define FMOD_THREAD_PRIORITY_PLATFORM_MAX ( 32 * 1024) +/* Platform agnostic priorities, maps internally to platform specific value */ +#define FMOD_THREAD_PRIORITY_DEFAULT (FMOD_THREAD_PRIORITY_PLATFORM_MIN - 1) +#define FMOD_THREAD_PRIORITY_LOW (FMOD_THREAD_PRIORITY_PLATFORM_MIN - 2) +#define FMOD_THREAD_PRIORITY_MEDIUM (FMOD_THREAD_PRIORITY_PLATFORM_MIN - 3) +#define FMOD_THREAD_PRIORITY_HIGH (FMOD_THREAD_PRIORITY_PLATFORM_MIN - 4) +#define FMOD_THREAD_PRIORITY_VERY_HIGH (FMOD_THREAD_PRIORITY_PLATFORM_MIN - 5) +#define FMOD_THREAD_PRIORITY_EXTREME (FMOD_THREAD_PRIORITY_PLATFORM_MIN - 6) +#define FMOD_THREAD_PRIORITY_CRITICAL (FMOD_THREAD_PRIORITY_PLATFORM_MIN - 7) +/* Thread defaults */ +#define FMOD_THREAD_PRIORITY_MIXER FMOD_THREAD_PRIORITY_EXTREME +#define FMOD_THREAD_PRIORITY_FEEDER FMOD_THREAD_PRIORITY_CRITICAL +#define FMOD_THREAD_PRIORITY_STREAM FMOD_THREAD_PRIORITY_VERY_HIGH +#define FMOD_THREAD_PRIORITY_FILE FMOD_THREAD_PRIORITY_HIGH +#define FMOD_THREAD_PRIORITY_NONBLOCKING FMOD_THREAD_PRIORITY_HIGH +#define FMOD_THREAD_PRIORITY_RECORD FMOD_THREAD_PRIORITY_HIGH +#define FMOD_THREAD_PRIORITY_GEOMETRY FMOD_THREAD_PRIORITY_LOW +#define FMOD_THREAD_PRIORITY_PROFILER FMOD_THREAD_PRIORITY_MEDIUM +#define FMOD_THREAD_PRIORITY_STUDIO_UPDATE FMOD_THREAD_PRIORITY_MEDIUM +#define FMOD_THREAD_PRIORITY_STUDIO_LOAD_BANK FMOD_THREAD_PRIORITY_MEDIUM +#define FMOD_THREAD_PRIORITY_STUDIO_LOAD_SAMPLE FMOD_THREAD_PRIORITY_MEDIUM +#define FMOD_THREAD_PRIORITY_CONVOLUTION1 FMOD_THREAD_PRIORITY_VERY_HIGH +#define FMOD_THREAD_PRIORITY_CONVOLUTION2 FMOD_THREAD_PRIORITY_VERY_HIGH + +typedef unsigned int FMOD_THREAD_STACK_SIZE; +#define FMOD_THREAD_STACK_SIZE_DEFAULT 0 +#define FMOD_THREAD_STACK_SIZE_MIXER (80 * 1024) +#define FMOD_THREAD_STACK_SIZE_FEEDER (16 * 1024) +#define FMOD_THREAD_STACK_SIZE_STREAM (96 * 1024) +#define FMOD_THREAD_STACK_SIZE_FILE (64 * 1024) +#define FMOD_THREAD_STACK_SIZE_NONBLOCKING (112 * 1024) +#define FMOD_THREAD_STACK_SIZE_RECORD (16 * 1024) +#define FMOD_THREAD_STACK_SIZE_GEOMETRY (48 * 1024) +#define FMOD_THREAD_STACK_SIZE_PROFILER (128 * 1024) +#define FMOD_THREAD_STACK_SIZE_STUDIO_UPDATE (96 * 1024) +#define FMOD_THREAD_STACK_SIZE_STUDIO_LOAD_BANK (96 * 1024) +#define FMOD_THREAD_STACK_SIZE_STUDIO_LOAD_SAMPLE (96 * 1024) +#define FMOD_THREAD_STACK_SIZE_CONVOLUTION1 (16 * 1024) +#define FMOD_THREAD_STACK_SIZE_CONVOLUTION2 (16 * 1024) + +typedef long long FMOD_THREAD_AFFINITY; +/* Platform agnostic thread groupings */ +#define FMOD_THREAD_AFFINITY_GROUP_DEFAULT 0x4000000000000000 +#define FMOD_THREAD_AFFINITY_GROUP_A 0x4000000000000001 +#define FMOD_THREAD_AFFINITY_GROUP_B 0x4000000000000002 +#define FMOD_THREAD_AFFINITY_GROUP_C 0x4000000000000003 +/* Thread defaults */ +#define FMOD_THREAD_AFFINITY_MIXER FMOD_THREAD_AFFINITY_GROUP_A +#define FMOD_THREAD_AFFINITY_FEEDER FMOD_THREAD_AFFINITY_GROUP_C +#define FMOD_THREAD_AFFINITY_STREAM FMOD_THREAD_AFFINITY_GROUP_C +#define FMOD_THREAD_AFFINITY_FILE FMOD_THREAD_AFFINITY_GROUP_C +#define FMOD_THREAD_AFFINITY_NONBLOCKING FMOD_THREAD_AFFINITY_GROUP_C +#define FMOD_THREAD_AFFINITY_RECORD FMOD_THREAD_AFFINITY_GROUP_C +#define FMOD_THREAD_AFFINITY_GEOMETRY FMOD_THREAD_AFFINITY_GROUP_C +#define FMOD_THREAD_AFFINITY_PROFILER FMOD_THREAD_AFFINITY_GROUP_C +#define FMOD_THREAD_AFFINITY_STUDIO_UPDATE FMOD_THREAD_AFFINITY_GROUP_B +#define FMOD_THREAD_AFFINITY_STUDIO_LOAD_BANK FMOD_THREAD_AFFINITY_GROUP_C +#define FMOD_THREAD_AFFINITY_STUDIO_LOAD_SAMPLE FMOD_THREAD_AFFINITY_GROUP_C +#define FMOD_THREAD_AFFINITY_CONVOLUTION1 FMOD_THREAD_AFFINITY_GROUP_C +#define FMOD_THREAD_AFFINITY_CONVOLUTION2 FMOD_THREAD_AFFINITY_GROUP_C +/* Core mask, valid up to 1 << 62 */ +#define FMOD_THREAD_AFFINITY_CORE_ALL 0 +#define FMOD_THREAD_AFFINITY_CORE_0 (1 << 0) +#define FMOD_THREAD_AFFINITY_CORE_1 (1 << 1) +#define FMOD_THREAD_AFFINITY_CORE_2 (1 << 2) +#define FMOD_THREAD_AFFINITY_CORE_3 (1 << 3) +#define FMOD_THREAD_AFFINITY_CORE_4 (1 << 4) +#define FMOD_THREAD_AFFINITY_CORE_5 (1 << 5) +#define FMOD_THREAD_AFFINITY_CORE_6 (1 << 6) +#define FMOD_THREAD_AFFINITY_CORE_7 (1 << 7) +#define FMOD_THREAD_AFFINITY_CORE_8 (1 << 8) +#define FMOD_THREAD_AFFINITY_CORE_9 (1 << 9) +#define FMOD_THREAD_AFFINITY_CORE_10 (1 << 10) +#define FMOD_THREAD_AFFINITY_CORE_11 (1 << 11) +#define FMOD_THREAD_AFFINITY_CORE_12 (1 << 12) +#define FMOD_THREAD_AFFINITY_CORE_13 (1 << 13) +#define FMOD_THREAD_AFFINITY_CORE_14 (1 << 14) +#define FMOD_THREAD_AFFINITY_CORE_15 (1 << 15) + +/* Preset for FMOD_REVERB_PROPERTIES */ +#define FMOD_PRESET_OFF { 1000, 7, 11, 5000, 100, 100, 100, 250, 0, 20, 96, -80.0f } +#define FMOD_PRESET_GENERIC { 1500, 7, 11, 5000, 83, 100, 100, 250, 0, 14500, 96, -8.0f } +#define FMOD_PRESET_PADDEDCELL { 170, 1, 2, 5000, 10, 100, 100, 250, 0, 160, 84, -7.8f } +#define FMOD_PRESET_ROOM { 400, 2, 3, 5000, 83, 100, 100, 250, 0, 6050, 88, -9.4f } +#define FMOD_PRESET_BATHROOM { 1500, 7, 11, 5000, 54, 100, 60, 250, 0, 2900, 83, 0.5f } +#define FMOD_PRESET_LIVINGROOM { 500, 3, 4, 5000, 10, 100, 100, 250, 0, 160, 58, -19.0f } +#define FMOD_PRESET_STONEROOM { 2300, 12, 17, 5000, 64, 100, 100, 250, 0, 7800, 71, -8.5f } +#define FMOD_PRESET_AUDITORIUM { 4300, 20, 30, 5000, 59, 100, 100, 250, 0, 5850, 64, -11.7f } +#define FMOD_PRESET_CONCERTHALL { 3900, 20, 29, 5000, 70, 100, 100, 250, 0, 5650, 80, -9.8f } +#define FMOD_PRESET_CAVE { 2900, 15, 22, 5000, 100, 100, 100, 250, 0, 20000, 59, -11.3f } +#define FMOD_PRESET_ARENA { 7200, 20, 30, 5000, 33, 100, 100, 250, 0, 4500, 80, -9.6f } +#define FMOD_PRESET_HANGAR { 10000, 20, 30, 5000, 23, 100, 100, 250, 0, 3400, 72, -7.4f } +#define FMOD_PRESET_CARPETTEDHALLWAY { 300, 2, 30, 5000, 10, 100, 100, 250, 0, 500, 56, -24.0f } +#define FMOD_PRESET_HALLWAY { 1500, 7, 11, 5000, 59, 100, 100, 250, 0, 7800, 87, -5.5f } +#define FMOD_PRESET_STONECORRIDOR { 270, 13, 20, 5000, 79, 100, 100, 250, 0, 9000, 86, -6.0f } +#define FMOD_PRESET_ALLEY { 1500, 7, 11, 5000, 86, 100, 100, 250, 0, 8300, 80, -9.8f } +#define FMOD_PRESET_FOREST { 1500, 162, 88, 5000, 54, 79, 100, 250, 0, 760, 94, -12.3f } +#define FMOD_PRESET_CITY { 1500, 7, 11, 5000, 67, 50, 100, 250, 0, 4050, 66, -26.0f } +#define FMOD_PRESET_MOUNTAINS { 1500, 300, 100, 5000, 21, 27, 100, 250, 0, 1220, 82, -24.0f } +#define FMOD_PRESET_QUARRY { 1500, 61, 25, 5000, 83, 100, 100, 250, 0, 3400, 100, -5.0f } +#define FMOD_PRESET_PLAIN { 1500, 179, 100, 5000, 50, 21, 100, 250, 0, 1670, 65, -28.0f } +#define FMOD_PRESET_PARKINGLOT { 1700, 8, 12, 5000, 100, 100, 100, 250, 0, 20000, 56, -19.5f } +#define FMOD_PRESET_SEWERPIPE { 2800, 14, 21, 5000, 14, 80, 60, 250, 0, 3400, 66, 1.2f } +#define FMOD_PRESET_UNDERWATER { 1500, 7, 11, 5000, 10, 100, 100, 250, 0, 500, 92, 7.0f } + +#define FMOD_MAX_CHANNEL_WIDTH 32 +#define FMOD_MAX_SYSTEMS 8 +#define FMOD_MAX_LISTENERS 8 +#define FMOD_REVERB_MAXINSTANCES 4 + +typedef enum FMOD_THREAD_TYPE +{ + FMOD_THREAD_TYPE_MIXER, + FMOD_THREAD_TYPE_FEEDER, + FMOD_THREAD_TYPE_STREAM, + FMOD_THREAD_TYPE_FILE, + FMOD_THREAD_TYPE_NONBLOCKING, + FMOD_THREAD_TYPE_RECORD, + FMOD_THREAD_TYPE_GEOMETRY, + FMOD_THREAD_TYPE_PROFILER, + FMOD_THREAD_TYPE_STUDIO_UPDATE, + FMOD_THREAD_TYPE_STUDIO_LOAD_BANK, + FMOD_THREAD_TYPE_STUDIO_LOAD_SAMPLE, + FMOD_THREAD_TYPE_CONVOLUTION1, + FMOD_THREAD_TYPE_CONVOLUTION2, + + FMOD_THREAD_TYPE_MAX, + FMOD_THREAD_TYPE_FORCEINT = 65536 +} FMOD_THREAD_TYPE; + +typedef enum FMOD_RESULT +{ + FMOD_OK, + FMOD_ERR_BADCOMMAND, + FMOD_ERR_CHANNEL_ALLOC, + FMOD_ERR_CHANNEL_STOLEN, + FMOD_ERR_DMA, + FMOD_ERR_DSP_CONNECTION, + FMOD_ERR_DSP_DONTPROCESS, + FMOD_ERR_DSP_FORMAT, + FMOD_ERR_DSP_INUSE, + FMOD_ERR_DSP_NOTFOUND, + FMOD_ERR_DSP_RESERVED, + FMOD_ERR_DSP_SILENCE, + FMOD_ERR_DSP_TYPE, + FMOD_ERR_FILE_BAD, + FMOD_ERR_FILE_COULDNOTSEEK, + FMOD_ERR_FILE_DISKEJECTED, + FMOD_ERR_FILE_EOF, + FMOD_ERR_FILE_ENDOFDATA, + FMOD_ERR_FILE_NOTFOUND, + FMOD_ERR_FORMAT, + FMOD_ERR_HEADER_MISMATCH, + FMOD_ERR_HTTP, + FMOD_ERR_HTTP_ACCESS, + FMOD_ERR_HTTP_PROXY_AUTH, + FMOD_ERR_HTTP_SERVER_ERROR, + FMOD_ERR_HTTP_TIMEOUT, + FMOD_ERR_INITIALIZATION, + FMOD_ERR_INITIALIZED, + FMOD_ERR_INTERNAL, + FMOD_ERR_INVALID_FLOAT, + FMOD_ERR_INVALID_HANDLE, + FMOD_ERR_INVALID_PARAM, + FMOD_ERR_INVALID_POSITION, + FMOD_ERR_INVALID_SPEAKER, + FMOD_ERR_INVALID_SYNCPOINT, + FMOD_ERR_INVALID_THREAD, + FMOD_ERR_INVALID_VECTOR, + FMOD_ERR_MAXAUDIBLE, + FMOD_ERR_MEMORY, + FMOD_ERR_MEMORY_CANTPOINT, + FMOD_ERR_NEEDS3D, + FMOD_ERR_NEEDSHARDWARE, + FMOD_ERR_NET_CONNECT, + FMOD_ERR_NET_SOCKET_ERROR, + FMOD_ERR_NET_URL, + FMOD_ERR_NET_WOULD_BLOCK, + FMOD_ERR_NOTREADY, + FMOD_ERR_OUTPUT_ALLOCATED, + FMOD_ERR_OUTPUT_CREATEBUFFER, + FMOD_ERR_OUTPUT_DRIVERCALL, + FMOD_ERR_OUTPUT_FORMAT, + FMOD_ERR_OUTPUT_INIT, + FMOD_ERR_OUTPUT_NODRIVERS, + FMOD_ERR_PLUGIN, + FMOD_ERR_PLUGIN_MISSING, + FMOD_ERR_PLUGIN_RESOURCE, + FMOD_ERR_PLUGIN_VERSION, + FMOD_ERR_RECORD, + FMOD_ERR_REVERB_CHANNELGROUP, + FMOD_ERR_REVERB_INSTANCE, + FMOD_ERR_SUBSOUNDS, + FMOD_ERR_SUBSOUND_ALLOCATED, + FMOD_ERR_SUBSOUND_CANTMOVE, + FMOD_ERR_TAGNOTFOUND, + FMOD_ERR_TOOMANYCHANNELS, + FMOD_ERR_TRUNCATED, + FMOD_ERR_UNIMPLEMENTED, + FMOD_ERR_UNINITIALIZED, + FMOD_ERR_UNSUPPORTED, + FMOD_ERR_VERSION, + FMOD_ERR_EVENT_ALREADY_LOADED, + FMOD_ERR_EVENT_LIVEUPDATE_BUSY, + FMOD_ERR_EVENT_LIVEUPDATE_MISMATCH, + FMOD_ERR_EVENT_LIVEUPDATE_TIMEOUT, + FMOD_ERR_EVENT_NOTFOUND, + FMOD_ERR_STUDIO_UNINITIALIZED, + FMOD_ERR_STUDIO_NOT_LOADED, + FMOD_ERR_INVALID_STRING, + FMOD_ERR_ALREADY_LOCKED, + FMOD_ERR_NOT_LOCKED, + FMOD_ERR_RECORD_DISCONNECTED, + FMOD_ERR_TOOMANYSAMPLES, + + FMOD_RESULT_FORCEINT = 65536 +} FMOD_RESULT; + +typedef enum FMOD_CHANNELCONTROL_TYPE +{ + FMOD_CHANNELCONTROL_CHANNEL, + FMOD_CHANNELCONTROL_CHANNELGROUP, + + FMOD_CHANNELCONTROL_MAX, + FMOD_CHANNELCONTROL_FORCEINT = 65536 +} FMOD_CHANNELCONTROL_TYPE; + +typedef enum FMOD_OUTPUTTYPE +{ + FMOD_OUTPUTTYPE_AUTODETECT, + FMOD_OUTPUTTYPE_UNKNOWN, + FMOD_OUTPUTTYPE_NOSOUND, + FMOD_OUTPUTTYPE_WAVWRITER, + FMOD_OUTPUTTYPE_NOSOUND_NRT, + FMOD_OUTPUTTYPE_WAVWRITER_NRT, + FMOD_OUTPUTTYPE_WASAPI, + FMOD_OUTPUTTYPE_ASIO, + FMOD_OUTPUTTYPE_PULSEAUDIO, + FMOD_OUTPUTTYPE_ALSA, + FMOD_OUTPUTTYPE_COREAUDIO, + FMOD_OUTPUTTYPE_AUDIOTRACK, + FMOD_OUTPUTTYPE_OPENSL, + FMOD_OUTPUTTYPE_AUDIOOUT, + FMOD_OUTPUTTYPE_AUDIO3D, + FMOD_OUTPUTTYPE_WEBAUDIO, + FMOD_OUTPUTTYPE_NNAUDIO, + FMOD_OUTPUTTYPE_WINSONIC, + FMOD_OUTPUTTYPE_AAUDIO, + FMOD_OUTPUTTYPE_AUDIOWORKLET, + FMOD_OUTPUTTYPE_PHASE, + FMOD_OUTPUTTYPE_OHAUDIO, + + FMOD_OUTPUTTYPE_MAX, + FMOD_OUTPUTTYPE_FORCEINT = 65536 +} FMOD_OUTPUTTYPE; + +typedef enum FMOD_DEBUG_MODE +{ + FMOD_DEBUG_MODE_TTY, + FMOD_DEBUG_MODE_FILE, + FMOD_DEBUG_MODE_CALLBACK, + + FMOD_DEBUG_MODE_FORCEINT = 65536 +} FMOD_DEBUG_MODE; + +typedef enum FMOD_SPEAKERMODE +{ + FMOD_SPEAKERMODE_DEFAULT, + FMOD_SPEAKERMODE_RAW, + FMOD_SPEAKERMODE_MONO, + FMOD_SPEAKERMODE_STEREO, + FMOD_SPEAKERMODE_QUAD, + FMOD_SPEAKERMODE_SURROUND, + FMOD_SPEAKERMODE_5POINT1, + FMOD_SPEAKERMODE_7POINT1, + FMOD_SPEAKERMODE_7POINT1POINT4, + + FMOD_SPEAKERMODE_MAX, + FMOD_SPEAKERMODE_FORCEINT = 65536 +} FMOD_SPEAKERMODE; + +typedef enum FMOD_SPEAKER +{ + FMOD_SPEAKER_NONE = -1, + FMOD_SPEAKER_FRONT_LEFT, + FMOD_SPEAKER_FRONT_RIGHT, + FMOD_SPEAKER_FRONT_CENTER, + FMOD_SPEAKER_LOW_FREQUENCY, + FMOD_SPEAKER_SURROUND_LEFT, + FMOD_SPEAKER_SURROUND_RIGHT, + FMOD_SPEAKER_BACK_LEFT, + FMOD_SPEAKER_BACK_RIGHT, + FMOD_SPEAKER_TOP_FRONT_LEFT, + FMOD_SPEAKER_TOP_FRONT_RIGHT, + FMOD_SPEAKER_TOP_BACK_LEFT, + FMOD_SPEAKER_TOP_BACK_RIGHT, + + FMOD_SPEAKER_MAX, + FMOD_SPEAKER_FORCEINT = 65536 +} FMOD_SPEAKER; + +typedef enum FMOD_CHANNELORDER +{ + FMOD_CHANNELORDER_DEFAULT, + FMOD_CHANNELORDER_WAVEFORMAT, + FMOD_CHANNELORDER_PROTOOLS, + FMOD_CHANNELORDER_ALLMONO, + FMOD_CHANNELORDER_ALLSTEREO, + FMOD_CHANNELORDER_ALSA, + + FMOD_CHANNELORDER_MAX, + FMOD_CHANNELORDER_FORCEINT = 65536 +} FMOD_CHANNELORDER; + +typedef enum FMOD_PLUGINTYPE +{ + FMOD_PLUGINTYPE_OUTPUT, + FMOD_PLUGINTYPE_CODEC, + FMOD_PLUGINTYPE_DSP, + + FMOD_PLUGINTYPE_MAX, + FMOD_PLUGINTYPE_FORCEINT = 65536 +} FMOD_PLUGINTYPE; + +typedef enum FMOD_SOUND_TYPE +{ + FMOD_SOUND_TYPE_UNKNOWN, + FMOD_SOUND_TYPE_AIFF, + FMOD_SOUND_TYPE_ASF, + FMOD_SOUND_TYPE_DLS, + FMOD_SOUND_TYPE_FLAC, + FMOD_SOUND_TYPE_FSB, + FMOD_SOUND_TYPE_IT, + FMOD_SOUND_TYPE_MIDI, + FMOD_SOUND_TYPE_MOD, + FMOD_SOUND_TYPE_MPEG, + FMOD_SOUND_TYPE_OGGVORBIS, + FMOD_SOUND_TYPE_PLAYLIST, + FMOD_SOUND_TYPE_RAW, + FMOD_SOUND_TYPE_S3M, + FMOD_SOUND_TYPE_USER, + FMOD_SOUND_TYPE_WAV, + FMOD_SOUND_TYPE_XM, + FMOD_SOUND_TYPE_XMA, + FMOD_SOUND_TYPE_AUDIOQUEUE, + FMOD_SOUND_TYPE_AT9, + FMOD_SOUND_TYPE_VORBIS, + FMOD_SOUND_TYPE_MEDIA_FOUNDATION, + FMOD_SOUND_TYPE_MEDIACODEC, + FMOD_SOUND_TYPE_FADPCM, + FMOD_SOUND_TYPE_OPUS, + + FMOD_SOUND_TYPE_MAX, + FMOD_SOUND_TYPE_FORCEINT = 65536 +} FMOD_SOUND_TYPE; + +typedef enum FMOD_SOUND_FORMAT +{ + FMOD_SOUND_FORMAT_NONE, + FMOD_SOUND_FORMAT_PCM8, + FMOD_SOUND_FORMAT_PCM16, + FMOD_SOUND_FORMAT_PCM24, + FMOD_SOUND_FORMAT_PCM32, + FMOD_SOUND_FORMAT_PCMFLOAT, + FMOD_SOUND_FORMAT_BITSTREAM, + + FMOD_SOUND_FORMAT_MAX, + FMOD_SOUND_FORMAT_FORCEINT = 65536 +} FMOD_SOUND_FORMAT; + +typedef enum FMOD_OPENSTATE +{ + FMOD_OPENSTATE_READY, + FMOD_OPENSTATE_LOADING, + FMOD_OPENSTATE_ERROR, + FMOD_OPENSTATE_CONNECTING, + FMOD_OPENSTATE_BUFFERING, + FMOD_OPENSTATE_SEEKING, + FMOD_OPENSTATE_PLAYING, + FMOD_OPENSTATE_SETPOSITION, + + FMOD_OPENSTATE_MAX, + FMOD_OPENSTATE_FORCEINT = 65536 +} FMOD_OPENSTATE; + +typedef enum FMOD_SOUNDGROUP_BEHAVIOR +{ + FMOD_SOUNDGROUP_BEHAVIOR_FAIL, + FMOD_SOUNDGROUP_BEHAVIOR_MUTE, + FMOD_SOUNDGROUP_BEHAVIOR_STEALLOWEST, + + FMOD_SOUNDGROUP_BEHAVIOR_MAX, + FMOD_SOUNDGROUP_BEHAVIOR_FORCEINT = 65536 +} FMOD_SOUNDGROUP_BEHAVIOR; + +typedef enum FMOD_CHANNELCONTROL_CALLBACK_TYPE +{ + FMOD_CHANNELCONTROL_CALLBACK_END, + FMOD_CHANNELCONTROL_CALLBACK_VIRTUALVOICE, + FMOD_CHANNELCONTROL_CALLBACK_SYNCPOINT, + FMOD_CHANNELCONTROL_CALLBACK_OCCLUSION, + + FMOD_CHANNELCONTROL_CALLBACK_MAX, + FMOD_CHANNELCONTROL_CALLBACK_FORCEINT = 65536 +} FMOD_CHANNELCONTROL_CALLBACK_TYPE; + +typedef enum FMOD_CHANNELCONTROL_DSP_INDEX +{ + FMOD_CHANNELCONTROL_DSP_HEAD = -1, + FMOD_CHANNELCONTROL_DSP_FADER = -2, + FMOD_CHANNELCONTROL_DSP_TAIL = -3, + + FMOD_CHANNELCONTROL_DSP_FORCEINT = 65536 +} FMOD_CHANNELCONTROL_DSP_INDEX; + +typedef enum FMOD_ERRORCALLBACK_INSTANCETYPE +{ + FMOD_ERRORCALLBACK_INSTANCETYPE_NONE, + FMOD_ERRORCALLBACK_INSTANCETYPE_SYSTEM, + FMOD_ERRORCALLBACK_INSTANCETYPE_CHANNEL, + FMOD_ERRORCALLBACK_INSTANCETYPE_CHANNELGROUP, + FMOD_ERRORCALLBACK_INSTANCETYPE_CHANNELCONTROL, + FMOD_ERRORCALLBACK_INSTANCETYPE_SOUND, + FMOD_ERRORCALLBACK_INSTANCETYPE_SOUNDGROUP, + FMOD_ERRORCALLBACK_INSTANCETYPE_DSP, + FMOD_ERRORCALLBACK_INSTANCETYPE_DSPCONNECTION, + FMOD_ERRORCALLBACK_INSTANCETYPE_GEOMETRY, + FMOD_ERRORCALLBACK_INSTANCETYPE_REVERB3D, + FMOD_ERRORCALLBACK_INSTANCETYPE_STUDIO_SYSTEM, + FMOD_ERRORCALLBACK_INSTANCETYPE_STUDIO_EVENTDESCRIPTION, + FMOD_ERRORCALLBACK_INSTANCETYPE_STUDIO_EVENTINSTANCE, + FMOD_ERRORCALLBACK_INSTANCETYPE_STUDIO_PARAMETERINSTANCE, + FMOD_ERRORCALLBACK_INSTANCETYPE_STUDIO_BUS, + FMOD_ERRORCALLBACK_INSTANCETYPE_STUDIO_VCA, + FMOD_ERRORCALLBACK_INSTANCETYPE_STUDIO_BANK, + FMOD_ERRORCALLBACK_INSTANCETYPE_STUDIO_COMMANDREPLAY, + + FMOD_ERRORCALLBACK_INSTANCETYPE_FORCEINT = 65536 +} FMOD_ERRORCALLBACK_INSTANCETYPE; + +typedef enum FMOD_DSP_RESAMPLER +{ + FMOD_DSP_RESAMPLER_DEFAULT, + FMOD_DSP_RESAMPLER_NOINTERP, + FMOD_DSP_RESAMPLER_LINEAR, + FMOD_DSP_RESAMPLER_CUBIC, + FMOD_DSP_RESAMPLER_SPLINE, + + FMOD_DSP_RESAMPLER_MAX, + FMOD_DSP_RESAMPLER_FORCEINT = 65536 +} FMOD_DSP_RESAMPLER; + +typedef enum FMOD_DSP_CALLBACK_TYPE +{ + FMOD_DSP_CALLBACK_DATAPARAMETERRELEASE, + + FMOD_DSP_CALLBACK_MAX, + FMOD_DSP_CALLBACK_FORCEINT = 65536 +} FMOD_DSP_CALLBACK_TYPE; + +typedef enum FMOD_DSPCONNECTION_TYPE +{ + FMOD_DSPCONNECTION_TYPE_STANDARD, + FMOD_DSPCONNECTION_TYPE_SIDECHAIN, + FMOD_DSPCONNECTION_TYPE_SEND, + FMOD_DSPCONNECTION_TYPE_SEND_SIDECHAIN, + FMOD_DSPCONNECTION_TYPE_PREALLOCATED, + + FMOD_DSPCONNECTION_TYPE_MAX, + FMOD_DSPCONNECTION_TYPE_FORCEINT = 65536 +} FMOD_DSPCONNECTION_TYPE; + +typedef enum FMOD_TAGTYPE +{ + FMOD_TAGTYPE_UNKNOWN, + FMOD_TAGTYPE_ID3V1, + FMOD_TAGTYPE_ID3V2, + FMOD_TAGTYPE_VORBISCOMMENT, + FMOD_TAGTYPE_SHOUTCAST, + FMOD_TAGTYPE_ICECAST, + FMOD_TAGTYPE_ASF, + FMOD_TAGTYPE_MIDI, + FMOD_TAGTYPE_PLAYLIST, + FMOD_TAGTYPE_FMOD, + FMOD_TAGTYPE_USER, + + FMOD_TAGTYPE_MAX, + FMOD_TAGTYPE_FORCEINT = 65536 +} FMOD_TAGTYPE; + +typedef enum FMOD_TAGDATATYPE +{ + FMOD_TAGDATATYPE_BINARY, + FMOD_TAGDATATYPE_INT, + FMOD_TAGDATATYPE_FLOAT, + FMOD_TAGDATATYPE_STRING, + FMOD_TAGDATATYPE_STRING_UTF16, + FMOD_TAGDATATYPE_STRING_UTF16BE, + FMOD_TAGDATATYPE_STRING_UTF8, + + FMOD_TAGDATATYPE_MAX, + FMOD_TAGDATATYPE_FORCEINT = 65536 +} FMOD_TAGDATATYPE; + +typedef enum FMOD_PORT_TYPE +{ + FMOD_PORT_TYPE_MUSIC, + FMOD_PORT_TYPE_COPYRIGHT_MUSIC, + FMOD_PORT_TYPE_VOICE, + FMOD_PORT_TYPE_CONTROLLER, + FMOD_PORT_TYPE_PERSONAL, + FMOD_PORT_TYPE_VIBRATION, + FMOD_PORT_TYPE_AUX, + FMOD_PORT_TYPE_PASSTHROUGH, + FMOD_PORT_TYPE_VR_VIBRATION, + + FMOD_PORT_TYPE_MAX, + FMOD_PORT_TYPE_FORCEINT = 65536 +} FMOD_PORT_TYPE; + +/* + FMOD callbacks +*/ +typedef FMOD_RESULT (F_CALL *FMOD_DEBUG_CALLBACK) (FMOD_DEBUG_FLAGS flags, const char *file, int line, const char* func, const char* message); +typedef FMOD_RESULT (F_CALL *FMOD_SYSTEM_CALLBACK) (FMOD_SYSTEM *system, FMOD_SYSTEM_CALLBACK_TYPE type, void *commanddata1, void* commanddata2, void *userdata); +typedef FMOD_RESULT (F_CALL *FMOD_CHANNELCONTROL_CALLBACK) (FMOD_CHANNELCONTROL *channelcontrol, FMOD_CHANNELCONTROL_TYPE controltype, FMOD_CHANNELCONTROL_CALLBACK_TYPE callbacktype, void *commanddata1, void *commanddata2); +typedef FMOD_RESULT (F_CALL *FMOD_DSP_CALLBACK) (FMOD_DSP *dsp, FMOD_DSP_CALLBACK_TYPE type, void *data); +typedef FMOD_RESULT (F_CALL *FMOD_SOUND_NONBLOCK_CALLBACK) (FMOD_SOUND *sound, FMOD_RESULT result); +typedef FMOD_RESULT (F_CALL *FMOD_SOUND_PCMREAD_CALLBACK) (FMOD_SOUND *sound, void *data, unsigned int datalen); +typedef FMOD_RESULT (F_CALL *FMOD_SOUND_PCMSETPOS_CALLBACK) (FMOD_SOUND *sound, int subsound, unsigned int position, FMOD_TIMEUNIT postype); +typedef FMOD_RESULT (F_CALL *FMOD_FILE_OPEN_CALLBACK) (const char *name, unsigned int *filesize, void **handle, void *userdata); +typedef FMOD_RESULT (F_CALL *FMOD_FILE_CLOSE_CALLBACK) (void *handle, void *userdata); +typedef FMOD_RESULT (F_CALL *FMOD_FILE_READ_CALLBACK) (void *handle, void *buffer, unsigned int sizebytes, unsigned int *bytesread, void *userdata); +typedef FMOD_RESULT (F_CALL *FMOD_FILE_SEEK_CALLBACK) (void *handle, unsigned int pos, void *userdata); +typedef FMOD_RESULT (F_CALL *FMOD_FILE_ASYNCREAD_CALLBACK) (FMOD_ASYNCREADINFO *info, void *userdata); +typedef FMOD_RESULT (F_CALL *FMOD_FILE_ASYNCCANCEL_CALLBACK)(FMOD_ASYNCREADINFO *info, void *userdata); +typedef void (F_CALL *FMOD_FILE_ASYNCDONE_FUNC) (FMOD_ASYNCREADINFO *info, FMOD_RESULT result); +typedef void* (F_CALL *FMOD_MEMORY_ALLOC_CALLBACK) (unsigned int size, FMOD_MEMORY_TYPE type, const char *sourcestr); +typedef void* (F_CALL *FMOD_MEMORY_REALLOC_CALLBACK) (void *ptr, unsigned int size, FMOD_MEMORY_TYPE type, const char *sourcestr); +typedef void (F_CALL *FMOD_MEMORY_FREE_CALLBACK) (void *ptr, FMOD_MEMORY_TYPE type, const char *sourcestr); +typedef float (F_CALL *FMOD_3D_ROLLOFF_CALLBACK) (FMOD_CHANNELCONTROL *channelcontrol, float distance); + +/* + FMOD structs +*/ +struct FMOD_ASYNCREADINFO +{ + void *handle; + unsigned int offset; + unsigned int sizebytes; + int priority; + void *userdata; + void *buffer; + unsigned int bytesread; + FMOD_FILE_ASYNCDONE_FUNC done; +}; + +typedef struct FMOD_VECTOR +{ + float x; + float y; + float z; +} FMOD_VECTOR; + +typedef struct FMOD_3D_ATTRIBUTES +{ + FMOD_VECTOR position; + FMOD_VECTOR velocity; + FMOD_VECTOR forward; + FMOD_VECTOR up; +} FMOD_3D_ATTRIBUTES; + +typedef struct FMOD_GUID +{ + unsigned int Data1; + unsigned short Data2; + unsigned short Data3; + unsigned char Data4[8]; +} FMOD_GUID; + +typedef struct FMOD_PLUGINLIST +{ + FMOD_PLUGINTYPE type; + void *description; +} FMOD_PLUGINLIST; + +typedef struct FMOD_ADVANCEDSETTINGS +{ + int cbSize; + int maxMPEGCodecs; + int maxADPCMCodecs; + int maxXMACodecs; + int maxVorbisCodecs; + int maxAT9Codecs; + int maxFADPCMCodecs; + int maxOpusCodecs; + int ASIONumChannels; + char **ASIOChannelList; + FMOD_SPEAKER *ASIOSpeakerList; + float vol0virtualvol; + unsigned int defaultDecodeBufferSize; + unsigned short profilePort; + unsigned int geometryMaxFadeTime; + float distanceFilterCenterFreq; + int reverb3Dinstance; + int DSPBufferPoolSize; + FMOD_DSP_RESAMPLER resamplerMethod; + unsigned int randomSeed; + int maxConvolutionThreads; + int maxSpatialObjects; +} FMOD_ADVANCEDSETTINGS; + +typedef struct FMOD_TAG +{ + FMOD_TAGTYPE type; + FMOD_TAGDATATYPE datatype; + char *name; + void *data; + unsigned int datalen; + FMOD_BOOL updated; +} FMOD_TAG; + +typedef struct FMOD_CREATESOUNDEXINFO +{ + int cbsize; + unsigned int length; + unsigned int fileoffset; + int numchannels; + int defaultfrequency; + FMOD_SOUND_FORMAT format; + unsigned int decodebuffersize; + int initialsubsound; + int numsubsounds; + int *inclusionlist; + int inclusionlistnum; + FMOD_SOUND_PCMREAD_CALLBACK pcmreadcallback; + FMOD_SOUND_PCMSETPOS_CALLBACK pcmsetposcallback; + FMOD_SOUND_NONBLOCK_CALLBACK nonblockcallback; + const char *dlsname; + const char *encryptionkey; + int maxpolyphony; + void *userdata; + FMOD_SOUND_TYPE suggestedsoundtype; + FMOD_FILE_OPEN_CALLBACK fileuseropen; + FMOD_FILE_CLOSE_CALLBACK fileuserclose; + FMOD_FILE_READ_CALLBACK fileuserread; + FMOD_FILE_SEEK_CALLBACK fileuserseek; + FMOD_FILE_ASYNCREAD_CALLBACK fileuserasyncread; + FMOD_FILE_ASYNCCANCEL_CALLBACK fileuserasynccancel; + void *fileuserdata; + int filebuffersize; + FMOD_CHANNELORDER channelorder; + FMOD_SOUNDGROUP *initialsoundgroup; + unsigned int initialseekposition; + FMOD_TIMEUNIT initialseekpostype; + int ignoresetfilesystem; + unsigned int audioqueuepolicy; + unsigned int minmidigranularity; + int nonblockthreadid; + FMOD_GUID *fsbguid; +} FMOD_CREATESOUNDEXINFO; + +typedef struct FMOD_REVERB_PROPERTIES +{ + float DecayTime; + float EarlyDelay; + float LateDelay; + float HFReference; + float HFDecayRatio; + float Diffusion; + float Density; + float LowShelfFrequency; + float LowShelfGain; + float HighCut; + float EarlyLateMix; + float WetLevel; +} FMOD_REVERB_PROPERTIES; + +typedef struct FMOD_ERRORCALLBACK_INFO +{ + FMOD_RESULT result; + FMOD_ERRORCALLBACK_INSTANCETYPE instancetype; + void *instance; + const char *functionname; + const char *functionparams; +} FMOD_ERRORCALLBACK_INFO; + +typedef struct FMOD_CPU_USAGE +{ + float dsp; + float stream; + float geometry; + float update; + float convolution1; + float convolution2; +} FMOD_CPU_USAGE; + +typedef struct FMOD_DSP_DATA_PARAMETER_INFO +{ + void *data; + unsigned int length; + int index; +} FMOD_DSP_DATA_PARAMETER_INFO; + +/* + FMOD optional headers for plugin development +*/ +#include "fmod_codec.h" +#include "fmod_dsp.h" +#include "fmod_output.h" + +#endif diff --git a/FMOD/api/core/inc/fmod_dsp.cs b/FMOD/api/core/inc/fmod_dsp.cs new file mode 100644 index 0000000..a5828a0 --- /dev/null +++ b/FMOD/api/core/inc/fmod_dsp.cs @@ -0,0 +1,1093 @@ +/* ======================================================================================== */ +/* FMOD Core API - DSP header file. */ +/* Copyright (c), Firelight Technologies Pty, Ltd. 2004-2026. */ +/* */ +/* Use this header if you are wanting to develop your own DSP plugin to use with FMODs */ +/* dsp system. With this header you can make your own DSP plugin that FMOD can */ +/* register and use. See the documentation and examples on how to make a working plugin. */ +/* */ +/* For more detail visit: */ +/* https://fmod.com/docs/2.03/api/plugin-api-dsp.html */ +/* =========================================================================================*/ + +using System; +using System.Text; +using System.Runtime.InteropServices; + +namespace FMOD +{ + [StructLayout(LayoutKind.Sequential)] + public struct DSP_BUFFER_ARRAY + { + public int numbuffers; + public IntPtr buffernumchannels; + public IntPtr bufferchannelmask; + public IntPtr buffers; + public SPEAKERMODE speakermode; + + /* + These properties take advantage of the fact that numbuffers is always zero or one + */ + + public int numchannels + { + get + { + if (buffernumchannels != IntPtr.Zero && numbuffers != 0) + return Marshal.ReadInt32(buffernumchannels); + + return 0; + } + set + { + if (buffernumchannels != IntPtr.Zero && numbuffers != 0) + Marshal.WriteInt32(buffernumchannels, value); + } + } + + public IntPtr buffer + { + get + { + if (buffers != IntPtr.Zero && numbuffers != 0) + return Marshal.ReadIntPtr(buffers); + + return IntPtr.Zero; + } + set + { + if (buffers != IntPtr.Zero && numbuffers != 0) + Marshal.WriteIntPtr(buffers, value); + } + } + } + + public enum DSP_PROCESS_OPERATION + { + PROCESS_PERFORM, + PROCESS_QUERY + } + + [StructLayout(LayoutKind.Sequential)] + public struct COMPLEX + { + public float real; + public float imag; + } + + public enum DSP_PAN_SURROUND_FLAGS + { + DEFAULT = 0, + ROTATION_NOT_BIASED = 1, + } + + + /* + DSP callbacks + */ + public delegate RESULT DSP_CREATE_CALLBACK (ref DSP_STATE dsp_state); + public delegate RESULT DSP_RELEASE_CALLBACK (ref DSP_STATE dsp_state); + public delegate RESULT DSP_RESET_CALLBACK (ref DSP_STATE dsp_state); + public delegate RESULT DSP_SETPOSITION_CALLBACK (ref DSP_STATE dsp_state, uint pos); + public delegate RESULT DSP_READ_CALLBACK (ref DSP_STATE dsp_state, IntPtr inbuffer, IntPtr outbuffer, uint length, int inchannels, ref int outchannels); + public delegate RESULT DSP_SHOULDIPROCESS_CALLBACK (ref DSP_STATE dsp_state, bool inputsidle, uint length, CHANNELMASK inmask, int inchannels, SPEAKERMODE speakermode); + public delegate RESULT DSP_PROCESS_CALLBACK (ref DSP_STATE dsp_state, uint length, ref DSP_BUFFER_ARRAY inbufferarray, ref DSP_BUFFER_ARRAY outbufferarray, bool inputsidle, DSP_PROCESS_OPERATION op); + public delegate RESULT DSP_SETPARAM_FLOAT_CALLBACK (ref DSP_STATE dsp_state, int index, float value); + public delegate RESULT DSP_SETPARAM_INT_CALLBACK (ref DSP_STATE dsp_state, int index, int value); + public delegate RESULT DSP_SETPARAM_BOOL_CALLBACK (ref DSP_STATE dsp_state, int index, bool value); + public delegate RESULT DSP_SETPARAM_DATA_CALLBACK (ref DSP_STATE dsp_state, int index, IntPtr data, uint length); + public delegate RESULT DSP_GETPARAM_FLOAT_CALLBACK (ref DSP_STATE dsp_state, int index, ref float value, IntPtr valuestr); + public delegate RESULT DSP_GETPARAM_INT_CALLBACK (ref DSP_STATE dsp_state, int index, ref int value, IntPtr valuestr); + public delegate RESULT DSP_GETPARAM_BOOL_CALLBACK (ref DSP_STATE dsp_state, int index, ref bool value, IntPtr valuestr); + public delegate RESULT DSP_GETPARAM_DATA_CALLBACK (ref DSP_STATE dsp_state, int index, ref IntPtr data, ref uint length, IntPtr valuestr); + public delegate RESULT DSP_SYSTEM_REGISTER_CALLBACK (ref DSP_STATE dsp_state); + public delegate RESULT DSP_SYSTEM_DEREGISTER_CALLBACK (ref DSP_STATE dsp_state); + public delegate RESULT DSP_SYSTEM_MIX_CALLBACK (ref DSP_STATE dsp_state, int stage); + + + /* + DSP functions + */ + public delegate IntPtr DSP_ALLOC_FUNC (uint size, MEMORY_TYPE type, IntPtr sourcestr); + public delegate IntPtr DSP_REALLOC_FUNC (IntPtr ptr, uint size, MEMORY_TYPE type, IntPtr sourcestr); + public delegate void DSP_FREE_FUNC (IntPtr ptr, MEMORY_TYPE type, IntPtr sourcestr); + public delegate void DSP_LOG_FUNC (DEBUG_FLAGS level, IntPtr file, int line, IntPtr function, IntPtr str); + public delegate RESULT DSP_GETSAMPLERATE_FUNC (ref DSP_STATE dsp_state, ref int rate); + public delegate RESULT DSP_GETBLOCKSIZE_FUNC (ref DSP_STATE dsp_state, ref uint blocksize); + public delegate RESULT DSP_GETSPEAKERMODE_FUNC (ref DSP_STATE dsp_state, ref int speakermode_mixer, ref int speakermode_output); + public delegate RESULT DSP_GETCLOCK_FUNC (ref DSP_STATE dsp_state, out ulong clock, out uint offset, out uint length); + public delegate RESULT DSP_GETLISTENERATTRIBUTES_FUNC (ref DSP_STATE dsp_state, ref int numlisteners, IntPtr attributes); + public delegate RESULT DSP_GETUSERDATA_FUNC (ref DSP_STATE dsp_state, out IntPtr userdata); + public delegate RESULT DSP_DFT_FFTREAL_FUNC (ref DSP_STATE dsp_state, int size, IntPtr signal, IntPtr dft, IntPtr window, int signalhop); + public delegate RESULT DSP_DFT_IFFTREAL_FUNC (ref DSP_STATE dsp_state, int size, IntPtr dft, IntPtr signal, IntPtr window, int signalhop); + public delegate RESULT DSP_PAN_SUMMONOMATRIX_FUNC (ref DSP_STATE dsp_state, int sourceSpeakerMode, float lowFrequencyGain, float overallGain, IntPtr matrix); + public delegate RESULT DSP_PAN_SUMSTEREOMATRIX_FUNC (ref DSP_STATE dsp_state, int sourceSpeakerMode, float pan, float lowFrequencyGain, float overallGain, int matrixHop, IntPtr matrix); + public delegate RESULT DSP_PAN_SUMSURROUNDMATRIX_FUNC (ref DSP_STATE dsp_state, int sourceSpeakerMode, int targetSpeakerMode, float direction, float extent, float rotation, float lowFrequencyGain, float overallGain, int matrixHop, IntPtr matrix, DSP_PAN_SURROUND_FLAGS flags); + public delegate RESULT DSP_PAN_SUMMONOTOSURROUNDMATRIX_FUNC (ref DSP_STATE dsp_state, int targetSpeakerMode, float direction, float extent, float lowFrequencyGain, float overallGain, int matrixHop, IntPtr matrix); + public delegate RESULT DSP_PAN_SUMSTEREOTOSURROUNDMATRIX_FUNC (ref DSP_STATE dsp_state, int targetSpeakerMode, float direction, float extent, float rotation, float lowFrequencyGain, float overallGain, int matrixHop, IntPtr matrix); + public delegate RESULT DSP_PAN_GETROLLOFFGAIN_FUNC (ref DSP_STATE dsp_state, DSP_PAN_3D_ROLLOFF_TYPE rolloff, float distance, float mindistance, float maxdistance, out float gain); + + + public enum DSP_TYPE : int + { + UNKNOWN, + MIXER, + OSCILLATOR, + LOWPASS, + ITLOWPASS, + HIGHPASS, + ECHO, + FADER, + FLANGE, + DISTORTION, + NORMALIZE, + LIMITER, + PARAMEQ, + PITCHSHIFT, + CHORUS, + ITECHO, + COMPRESSOR, + SFXREVERB, + LOWPASS_SIMPLE, + DELAY, + TREMOLO, + SEND, + RETURN, + HIGHPASS_SIMPLE, + PAN, + THREE_EQ, + FFT, + LOUDNESS_METER, + CONVOLUTIONREVERB, + CHANNELMIX, + TRANSCEIVER, + OBJECTPAN, + MULTIBAND_EQ, + MULTIBAND_DYNAMICS, + MAX + } + + public enum DSP_PARAMETER_TYPE + { + FLOAT, + INT, + BOOL, + DATA, + MAX + } + + public enum DSP_PARAMETER_FLOAT_MAPPING_TYPE + { + DSP_PARAMETER_FLOAT_MAPPING_TYPE_LINEAR, + DSP_PARAMETER_FLOAT_MAPPING_TYPE_AUTO, + DSP_PARAMETER_FLOAT_MAPPING_TYPE_PIECEWISE_LINEAR, + } + + [StructLayout(LayoutKind.Sequential)] + public struct DSP_PARAMETER_FLOAT_MAPPING_PIECEWISE_LINEAR + { + public int numpoints; + public IntPtr pointparamvalues; + public IntPtr pointpositions; + } + + [StructLayout(LayoutKind.Sequential)] + public struct DSP_PARAMETER_FLOAT_MAPPING + { + public DSP_PARAMETER_FLOAT_MAPPING_TYPE type; + public DSP_PARAMETER_FLOAT_MAPPING_PIECEWISE_LINEAR piecewiselinearmapping; + } + + + [StructLayout(LayoutKind.Sequential)] + public struct DSP_PARAMETER_DESC_FLOAT + { + public float min; + public float max; + public float defaultval; + public DSP_PARAMETER_FLOAT_MAPPING mapping; + } + + [StructLayout(LayoutKind.Sequential)] + public struct DSP_PARAMETER_DESC_INT + { + public int min; + public int max; + public int defaultval; + public bool goestoinf; + public IntPtr valuenames; + } + + [StructLayout(LayoutKind.Sequential)] + public struct DSP_PARAMETER_DESC_BOOL + { + public bool defaultval; + public IntPtr valuenames; + } + + [StructLayout(LayoutKind.Sequential)] + public struct DSP_PARAMETER_DESC_DATA + { + public int datatype; + } + + [StructLayout(LayoutKind.Explicit)] + public struct DSP_PARAMETER_DESC_UNION + { + [FieldOffset(0)] + public DSP_PARAMETER_DESC_FLOAT floatdesc; + [FieldOffset(0)] + public DSP_PARAMETER_DESC_INT intdesc; + [FieldOffset(0)] + public DSP_PARAMETER_DESC_BOOL booldesc; + [FieldOffset(0)] + public DSP_PARAMETER_DESC_DATA datadesc; + } + + [StructLayout(LayoutKind.Sequential)] + public struct DSP_PARAMETER_DESC + { + public DSP_PARAMETER_TYPE type; + [MarshalAs(UnmanagedType.ByValArray, SizeConst = 16)] + public byte[] name; + [MarshalAs(UnmanagedType.ByValArray, SizeConst = 16)] + public byte[] label; + public string description; + + public DSP_PARAMETER_DESC_UNION desc; + } + + public enum DSP_PARAMETER_DATA_TYPE + { + DSP_PARAMETER_DATA_TYPE_USER = 0, + DSP_PARAMETER_DATA_TYPE_OVERALLGAIN = -1, + DSP_PARAMETER_DATA_TYPE_3DATTRIBUTES = -2, + DSP_PARAMETER_DATA_TYPE_SIDECHAIN = -3, + DSP_PARAMETER_DATA_TYPE_FFT = -4, + DSP_PARAMETER_DATA_TYPE_3DATTRIBUTES_MULTI = -5, + DSP_PARAMETER_DATA_TYPE_ATTENUATION_RANGE = -6, + DSP_PARAMETER_DATA_TYPE_DYNAMIC_RESPONSE = -7, + DSP_PARAMETER_DATA_TYPE_FINITE_LENGTH = -8 + } + + [StructLayout(LayoutKind.Sequential)] + public struct DSP_PARAMETER_OVERALLGAIN + { + public float linear_gain; + public float linear_gain_additive; + } + + [StructLayout(LayoutKind.Sequential)] + public struct DSP_PARAMETER_3DATTRIBUTES + { + public ATTRIBUTES_3D relative; + public ATTRIBUTES_3D absolute; + } + + [StructLayout(LayoutKind.Sequential)] + public struct DSP_PARAMETER_3DATTRIBUTES_MULTI + { + public int numlisteners; + [MarshalAs(UnmanagedType.ByValArray, SizeConst = 8)] + public ATTRIBUTES_3D[] relative; + [MarshalAs(UnmanagedType.ByValArray, SizeConst = 8)] + public float[] weight; + public ATTRIBUTES_3D absolute; + } + + [StructLayout(LayoutKind.Sequential)] + public struct DSP_PARAMETER_SIDECHAIN + { + public int sidechainenable; + } + + [StructLayout(LayoutKind.Sequential)] + public struct DSP_PARAMETER_FFT + { + public int length; + public int numchannels; + + [MarshalAs(UnmanagedType.ByValArray,SizeConst=32)] + private IntPtr[] spectrum_internal; + + public float[][] spectrum + { + get + { + var buffer = new float[numchannels][]; + + for (int i = 0; i < numchannels; ++i) + { + buffer[i] = new float[length]; + Marshal.Copy(spectrum_internal[i], buffer[i], 0, length); + } + + return buffer; + } + } + + public void getSpectrum(ref float[][] buffer) + { + int bufferLength = Math.Min(buffer.Length, numchannels); + for (int i = 0; i < bufferLength; ++i) + { + getSpectrum(i, ref buffer[i]); + } + } + + public void getSpectrum(int channel, ref float[] buffer) + { + int bufferLength = Math.Min(buffer.Length, length); + Marshal.Copy(spectrum_internal[channel], buffer, 0, bufferLength); + } + } + + [StructLayout(LayoutKind.Sequential)] + public struct DSP_PARAMETER_DYNAMIC_RESPONSE + { + public int numchannels; + [MarshalAs(UnmanagedType.ByValArray, SizeConst = 32)] + public float[] rms; + } + + [StructLayout(LayoutKind.Sequential)] + public struct DSP_PARAMETER_FINITE_LENGTH + { + public int finite; + } + + [StructLayout(LayoutKind.Sequential)] + public struct DSP_LOUDNESS_METER_INFO_TYPE + { + public float momentaryloudness; + public float shorttermloudness; + public float integratedloudness; + public float loudness10thpercentile; + public float loudness95thpercentile; + [MarshalAs(UnmanagedType.ByValArray, SizeConst = 66)] + public float[] loudnesshistogram; + public float maxtruepeak; + public float maxmomentaryloudness; + } + + [StructLayout(LayoutKind.Sequential)] + public struct DSP_LOUDNESS_METER_WEIGHTING_TYPE + { + [MarshalAs(UnmanagedType.ByValArray, SizeConst = 32)] + public float[] channelweight; + } + + [StructLayout(LayoutKind.Sequential)] + public struct DSP_PARAMETER_ATTENUATION_RANGE + { + public float min; + public float max; + } + + [StructLayout(LayoutKind.Sequential)] + public struct DSP_DESCRIPTION + { + public uint pluginsdkversion; + [MarshalAs(UnmanagedType.ByValArray, SizeConst = 32)] + public byte[] name; + public uint version; + public int numinputbuffers; + public int numoutputbuffers; + public DSP_CREATE_CALLBACK create; + public DSP_RELEASE_CALLBACK release; + public DSP_RESET_CALLBACK reset; + public DSP_READ_CALLBACK read; + public DSP_PROCESS_CALLBACK process; + public DSP_SETPOSITION_CALLBACK setposition; + + public int numparameters; + public IntPtr paramdesc; + public DSP_SETPARAM_FLOAT_CALLBACK setparameterfloat; + public DSP_SETPARAM_INT_CALLBACK setparameterint; + public DSP_SETPARAM_BOOL_CALLBACK setparameterbool; + public DSP_SETPARAM_DATA_CALLBACK setparameterdata; + public DSP_GETPARAM_FLOAT_CALLBACK getparameterfloat; + public DSP_GETPARAM_INT_CALLBACK getparameterint; + public DSP_GETPARAM_BOOL_CALLBACK getparameterbool; + public DSP_GETPARAM_DATA_CALLBACK getparameterdata; + public DSP_SHOULDIPROCESS_CALLBACK shouldiprocess; + public IntPtr userdata; + + public DSP_SYSTEM_REGISTER_CALLBACK sys_register; + public DSP_SYSTEM_DEREGISTER_CALLBACK sys_deregister; + public DSP_SYSTEM_MIX_CALLBACK sys_mix; + } + + [StructLayout(LayoutKind.Sequential)] + public struct DSP_STATE_DFT_FUNCTIONS + { + public DSP_DFT_FFTREAL_FUNC fftreal; + public DSP_DFT_IFFTREAL_FUNC inversefftreal; + } + + [StructLayout(LayoutKind.Sequential)] + public struct DSP_STATE_PAN_FUNCTIONS + { + public DSP_PAN_SUMMONOMATRIX_FUNC summonomatrix; + public DSP_PAN_SUMSTEREOMATRIX_FUNC sumstereomatrix; + public DSP_PAN_SUMSURROUNDMATRIX_FUNC sumsurroundmatrix; + public DSP_PAN_SUMMONOTOSURROUNDMATRIX_FUNC summonotosurroundmatrix; + public DSP_PAN_SUMSTEREOTOSURROUNDMATRIX_FUNC sumstereotosurroundmatrix; + public DSP_PAN_GETROLLOFFGAIN_FUNC getrolloffgain; + } + + [StructLayout(LayoutKind.Sequential)] + public struct DSP_STATE_FUNCTIONS + { + public DSP_ALLOC_FUNC alloc; + public DSP_REALLOC_FUNC realloc; + public DSP_FREE_FUNC free; + public DSP_GETSAMPLERATE_FUNC getsamplerate; + public DSP_GETBLOCKSIZE_FUNC getblocksize; + public IntPtr dft_internal; + public IntPtr pan_internal; + public DSP_GETSPEAKERMODE_FUNC getspeakermode; + public DSP_GETCLOCK_FUNC getclock; + public DSP_GETLISTENERATTRIBUTES_FUNC getlistenerattributes; + public DSP_LOG_FUNC log; + public DSP_GETUSERDATA_FUNC getuserdata; + public DSP_STATE_DFT_FUNCTIONS dft + { + get { return Marshal.PtrToStructure(dft_internal); } + } + public DSP_STATE_PAN_FUNCTIONS pan + { + get { return Marshal.PtrToStructure(pan_internal); } + } + } + + [StructLayout(LayoutKind.Sequential)] + public struct DSP_STATE + { + public IntPtr instance; + public IntPtr plugindata; + public uint channelmask; + public int source_speakermode; + public IntPtr sidechaindata; + public int sidechainchannels; + private IntPtr functions_internal; + public int systemobject; + + public DSP_STATE_FUNCTIONS functions + { + get { return Marshal.PtrToStructure(functions_internal); } + } + } + + [StructLayout(LayoutKind.Sequential)] + public struct DSP_METERING_INFO + { + public int numsamples; + public LEVEL_ARRAY peaklevel; + public LEVEL_ARRAY rmslevel; + public short numchannels; + + #region wrapperinternal + + [StructLayout(LayoutKind.Sequential)] + public struct LEVEL_ARRAY + { + // Explicitly define level array elements to avoid allocation + private float ch0, ch1, ch2, ch3, ch4, ch5, ch6, ch7; + private float ch8, ch9, ch10, ch11, ch12, ch13, ch14, ch15; + private float ch16, ch17, ch18, ch19, ch20, ch21, ch22, ch23; + private float ch24, ch25, ch26, ch27, ch28, ch29, ch30, ch31; + + // Indexer for access to elements + public float this[int index] + { + get + { + switch (index) + { + case 0: return ch0; + case 1: return ch1; + case 2: return ch2; + case 3: return ch3; + case 4: return ch4; + case 5: return ch5; + case 6: return ch6; + case 7: return ch7; + case 8: return ch8; + case 9: return ch9; + case 10: return ch10; + case 11: return ch11; + case 12: return ch12; + case 13: return ch13; + case 14: return ch14; + case 15: return ch15; + case 16: return ch16; + case 17: return ch17; + case 18: return ch18; + case 19: return ch19; + case 20: return ch20; + case 21: return ch21; + case 22: return ch22; + case 23: return ch23; + case 24: return ch24; + case 25: return ch25; + case 26: return ch26; + case 27: return ch27; + case 28: return ch28; + case 29: return ch29; + case 30: return ch30; + case 31: return ch31; + default: throw new IndexOutOfRangeException(); + } + } + } + + public readonly int Length => 32; + + // Implicit conversion for unchanged access to entire array + public static implicit operator float[](LEVEL_ARRAY levels) + { + float[] buffer = new float[levels.Length]; + for (int i = 0; i < levels.Length; i++) + { + buffer[i] = levels[i]; + } + return buffer; + } + + // Zero allocation copy-to + public void CopyTo(float[] buffer) + { + int len = buffer.Length >= this.Length ? this.Length : buffer.Length; + for (int i = 0; i < len; i++) + { + buffer[i] = this[i]; + } + } + } + + #endregion + } + + /* + ============================================================================================================== + + FMOD built in effect parameters. + Use DSP::setParameter with these enums for the 'index' parameter. + + ============================================================================================================== + */ + + public enum DSP_OSCILLATOR : int + { + TYPE, + RATE + } + + public enum DSP_LOWPASS : int + { + CUTOFF, + RESONANCE + } + + public enum DSP_ITLOWPASS : int + { + CUTOFF, + RESONANCE + } + + public enum DSP_HIGHPASS : int + { + CUTOFF, + RESONANCE + } + + public enum DSP_ECHO : int + { + DELAY, + FEEDBACK, + DRYLEVEL, + WETLEVEL, + DELAYCHANGEMODE + } + + public enum DSP_ECHO_DELAYCHANGEMODE_TYPE : int + { + FADE, + LERP, + NONE + } + + public enum DSP_FADER : int + { + GAIN, + OVERALL_GAIN, + } + + public enum DSP_DELAY : int + { + CH0, + CH1, + CH2, + CH3, + CH4, + CH5, + CH6, + CH7, + CH8, + CH9, + CH10, + CH11, + CH12, + CH13, + CH14, + CH15, + MAXDELAY, + } + + public enum DSP_FLANGE : int + { + MIX, + DEPTH, + RATE + } + + public enum DSP_TREMOLO : int + { + FREQUENCY, + DEPTH, + SHAPE, + SKEW, + DUTY, + SQUARE, + PHASE, + SPREAD + } + + public enum DSP_DISTORTION : int + { + LEVEL + } + + public enum DSP_NORMALIZE : int + { + FADETIME, + THRESHOLD, + MAXAMP + } + + public enum DSP_LIMITER : int + { + RELEASETIME, + CEILING, + MAXIMIZERGAIN, + MODE, + } + + public enum DSP_PARAMEQ : int + { + CENTER, + BANDWIDTH, + GAIN + } + + public enum DSP_MULTIBAND_EQ : int + { + A_FILTER, + A_FREQUENCY, + A_Q, + A_GAIN, + B_FILTER, + B_FREQUENCY, + B_Q, + B_GAIN, + C_FILTER, + C_FREQUENCY, + C_Q, + C_GAIN, + D_FILTER, + D_FREQUENCY, + D_Q, + D_GAIN, + E_FILTER, + E_FREQUENCY, + E_Q, + E_GAIN, + } + + public enum DSP_MULTIBAND_EQ_FILTER_TYPE : int + { + DISABLED, + LOWPASS_12DB, + LOWPASS_24DB, + LOWPASS_48DB, + HIGHPASS_12DB, + HIGHPASS_24DB, + HIGHPASS_48DB, + LOWSHELF, + HIGHSHELF, + PEAKING, + BANDPASS, + NOTCH, + ALLPASS, + LOWPASS_6DB, + HIGHPASS_6DB, + } + + public enum DSP_MULTIBAND_DYNAMICS : int + { + LOWER_FREQUENCY, + UPPER_FREQUENCY, + LINKED, + USE_SIDECHAIN, + A_MODE, + A_GAIN, + A_THRESHOLD, + A_RATIO, + A_ATTACK, + A_RELEASE, + A_GAIN_MAKEUP, + A_RESPONSE_DATA, + B_MODE, + B_GAIN, + B_THRESHOLD, + B_RATIO, + B_ATTACK, + B_RELEASE, + B_GAIN_MAKEUP, + B_RESPONSE_DATA, + C_MODE, + C_GAIN, + C_THRESHOLD, + C_RATIO, + C_ATTACK, + C_RELEASE, + C_GAIN_MAKEUP, + C_RESPONSE_DATA, + } + + public enum DSP_MULTIBAND_DYNAMICS_MODE_TYPE : int + { + DISABLED, + COMPRESS_UP, + COMPRESS_DOWN, + EXPAND_UP, + EXPAND_DOWN + } + + public enum DSP_PITCHSHIFT : int + { + PITCH, + FFTSIZE, + OVERLAP, + MAXCHANNELS + } + + public enum DSP_CHORUS : int + { + MIX, + RATE, + DEPTH, + } + + public enum DSP_ITECHO : int + { + WETDRYMIX, + FEEDBACK, + LEFTDELAY, + RIGHTDELAY, + PANDELAY + } + + public enum DSP_COMPRESSOR : int + { + THRESHOLD, + RATIO, + ATTACK, + RELEASE, + GAINMAKEUP, + USESIDECHAIN, + LINKED + } + + public enum DSP_SFXREVERB : int + { + DECAYTIME, + EARLYDELAY, + LATEDELAY, + HFREFERENCE, + HFDECAYRATIO, + DIFFUSION, + DENSITY, + LOWSHELFFREQUENCY, + LOWSHELFGAIN, + HIGHCUT, + EARLYLATEMIX, + WETLEVEL, + DRYLEVEL + } + + public enum DSP_LOWPASS_SIMPLE : int + { + CUTOFF + } + + public enum DSP_SEND : int + { + RETURNID, + LEVEL, + } + + public enum DSP_RETURN : int + { + ID, + INPUT_SPEAKER_MODE + } + + public enum DSP_HIGHPASS_SIMPLE : int + { + CUTOFF + } + + public enum DSP_PAN_2D_STEREO_MODE_TYPE : int + { + DISTRIBUTED, + DISCRETE + } + + public enum DSP_PAN_MODE_TYPE : int + { + MONO, + STEREO, + SURROUND + } + + public enum DSP_PAN_3D_ROLLOFF_TYPE : int + { + LINEARSQUARED, + LINEAR, + INVERSE, + INVERSETAPERED, + CUSTOM + } + + public enum DSP_PAN_3D_EXTENT_MODE_TYPE : int + { + AUTO, + USER, + OFF + } + + public enum DSP_PAN : int + { + MODE, + _2D_STEREO_POSITION, + _2D_DIRECTION, + _2D_EXTENT, + _2D_ROTATION, + _2D_LFE_LEVEL, + _2D_STEREO_MODE, + _2D_STEREO_SEPARATION, + _2D_STEREO_AXIS, + ENABLED_SPEAKERS, + _3D_POSITION, + _3D_ROLLOFF, + _3D_MIN_DISTANCE, + _3D_MAX_DISTANCE, + _3D_EXTENT_MODE, + _3D_SOUND_SIZE, + _3D_MIN_EXTENT, + _3D_PAN_BLEND, + LFE_UPMIX_ENABLED, + OVERALL_GAIN, + SURROUND_SPEAKER_MODE, + _2D_HEIGHT_BLEND, + ATTENUATION_RANGE, + OVERRIDE_RANGE + } + + public enum DSP_THREE_EQ_CROSSOVERSLOPE_TYPE : int + { + _12DB, + _24DB, + _48DB + } + + public enum DSP_THREE_EQ : int + { + LOWGAIN, + MIDGAIN, + HIGHGAIN, + LOWCROSSOVER, + HIGHCROSSOVER, + CROSSOVERSLOPE + } + + public enum DSP_FFT_WINDOW_TYPE : int + { + RECT, + TRIANGLE, + HAMMING, + HANNING, + BLACKMAN, + BLACKMANHARRIS + } + + public enum DSP_FFT_DOWNMIX_TYPE : int + { + NONE, + MONO + } + + public enum DSP_FFT : int + { + WINDOWSIZE, + WINDOW, + BAND_START_FREQ, + BAND_STOP_FREQ, + SPECTRUMDATA, + RMS, + SPECTRAL_CENTROID, + IMMEDIATE_MODE, + DOWNMIX, + CHANNEL + } + + + public enum DSP_LOUDNESS_METER : int + { + STATE, + WEIGHTING, + INFO + } + + + public enum DSP_LOUDNESS_METER_STATE_TYPE : int + { + RESET_INTEGRATED = -3, + RESET_MAXPEAK = -2, + RESET_ALL = -1, + PAUSED = 0, + ANALYZING = 1 + } + + public enum DSP_CONVOLUTION_REVERB : int + { + IR, + WET, + DRY, + LINKED + } + + public enum DSP_CHANNELMIX_OUTPUT : int + { + DEFAULT, + ALLMONO, + ALLSTEREO, + ALLQUAD, + ALL5POINT1, + ALL7POINT1, + ALLLFE, + ALL7POINT1POINT4 + } + + public enum DSP_CHANNELMIX : int + { + OUTPUTGROUPING, + GAIN_CH0, + GAIN_CH1, + GAIN_CH2, + GAIN_CH3, + GAIN_CH4, + GAIN_CH5, + GAIN_CH6, + GAIN_CH7, + GAIN_CH8, + GAIN_CH9, + GAIN_CH10, + GAIN_CH11, + GAIN_CH12, + GAIN_CH13, + GAIN_CH14, + GAIN_CH15, + GAIN_CH16, + GAIN_CH17, + GAIN_CH18, + GAIN_CH19, + GAIN_CH20, + GAIN_CH21, + GAIN_CH22, + GAIN_CH23, + GAIN_CH24, + GAIN_CH25, + GAIN_CH26, + GAIN_CH27, + GAIN_CH28, + GAIN_CH29, + GAIN_CH30, + GAIN_CH31, + OUTPUT_CH0, + OUTPUT_CH1, + OUTPUT_CH2, + OUTPUT_CH3, + OUTPUT_CH4, + OUTPUT_CH5, + OUTPUT_CH6, + OUTPUT_CH7, + OUTPUT_CH8, + OUTPUT_CH9, + OUTPUT_CH10, + OUTPUT_CH11, + OUTPUT_CH12, + OUTPUT_CH13, + OUTPUT_CH14, + OUTPUT_CH15, + OUTPUT_CH16, + OUTPUT_CH17, + OUTPUT_CH18, + OUTPUT_CH19, + OUTPUT_CH20, + OUTPUT_CH21, + OUTPUT_CH22, + OUTPUT_CH23, + OUTPUT_CH24, + OUTPUT_CH25, + OUTPUT_CH26, + OUTPUT_CH27, + OUTPUT_CH28, + OUTPUT_CH29, + OUTPUT_CH30, + OUTPUT_CH31, + } + + public enum DSP_TRANSCEIVER_SPEAKERMODE : int + { + AUTO = -1, + MONO = 0, + STEREO, + SURROUND, + } + + public enum DSP_TRANSCEIVER : int + { + TRANSMIT, + GAIN, + CHANNEL, + TRANSMITSPEAKERMODE + } + + public enum DSP_OBJECTPAN : int + { + _3D_POSITION, + _3D_ROLLOFF, + _3D_MIN_DISTANCE, + _3D_MAX_DISTANCE, + _3D_EXTENT_MODE, + _3D_SOUND_SIZE, + _3D_MIN_EXTENT, + OVERALL_GAIN, + OUTPUTGAIN, + ATTENUATION_RANGE, + OVERRIDE_RANGE + } +} diff --git a/FMOD/api/core/inc/fmod_dsp.h b/FMOD/api/core/inc/fmod_dsp.h new file mode 100644 index 0000000..fa9494b --- /dev/null +++ b/FMOD/api/core/inc/fmod_dsp.h @@ -0,0 +1,463 @@ +/* ======================================================================================== */ +/* FMOD Core API - DSP header file. */ +/* Copyright (c), Firelight Technologies Pty, Ltd. 2004-2026. */ +/* */ +/* Use this header if you are wanting to develop your own DSP plugin to use with FMODs */ +/* dsp system. With this header you can make your own DSP plugin that FMOD can */ +/* register and use. See the documentation and examples on how to make a working plugin. */ +/* */ +/* For more detail visit: */ +/* https://fmod.com/docs/2.03/api/plugin-api-dsp.html */ +/* =========================================================================================*/ +#ifndef _FMOD_DSP_H +#define _FMOD_DSP_H + +#include "fmod_dsp_effects.h" + +typedef struct FMOD_DSP_STATE FMOD_DSP_STATE; +typedef struct FMOD_DSP_BUFFER_ARRAY FMOD_DSP_BUFFER_ARRAY; +typedef struct FMOD_COMPLEX FMOD_COMPLEX; + +/* + DSP Constants +*/ +#define FMOD_PLUGIN_SDK_VERSION 110 +#define FMOD_DSP_GETPARAM_VALUESTR_LENGTH 32 + +typedef enum +{ + FMOD_DSP_PROCESS_PERFORM, + FMOD_DSP_PROCESS_QUERY +} FMOD_DSP_PROCESS_OPERATION; + +typedef enum FMOD_DSP_PAN_SURROUND_FLAGS +{ + FMOD_DSP_PAN_SURROUND_DEFAULT = 0, + FMOD_DSP_PAN_SURROUND_ROTATION_NOT_BIASED = 1, + + FMOD_DSP_PAN_SURROUND_FLAGS_FORCEINT = 65536 +} FMOD_DSP_PAN_SURROUND_FLAGS; + +typedef enum +{ + FMOD_DSP_PARAMETER_TYPE_FLOAT, + FMOD_DSP_PARAMETER_TYPE_INT, + FMOD_DSP_PARAMETER_TYPE_BOOL, + FMOD_DSP_PARAMETER_TYPE_DATA, + + FMOD_DSP_PARAMETER_TYPE_MAX, + FMOD_DSP_PARAMETER_TYPE_FORCEINT = 65536 +} FMOD_DSP_PARAMETER_TYPE; + +typedef enum +{ + FMOD_DSP_PARAMETER_FLOAT_MAPPING_TYPE_LINEAR, + FMOD_DSP_PARAMETER_FLOAT_MAPPING_TYPE_AUTO, + FMOD_DSP_PARAMETER_FLOAT_MAPPING_TYPE_PIECEWISE_LINEAR, + + FMOD_DSP_PARAMETER_FLOAT_MAPPING_TYPE_FORCEINT = 65536 +} FMOD_DSP_PARAMETER_FLOAT_MAPPING_TYPE; + +typedef enum +{ + FMOD_DSP_PARAMETER_DATA_TYPE_USER = 0, + FMOD_DSP_PARAMETER_DATA_TYPE_OVERALLGAIN = -1, + FMOD_DSP_PARAMETER_DATA_TYPE_3DATTRIBUTES = -2, + FMOD_DSP_PARAMETER_DATA_TYPE_SIDECHAIN = -3, + FMOD_DSP_PARAMETER_DATA_TYPE_FFT = -4, + FMOD_DSP_PARAMETER_DATA_TYPE_3DATTRIBUTES_MULTI = -5, + FMOD_DSP_PARAMETER_DATA_TYPE_ATTENUATION_RANGE = -6, + FMOD_DSP_PARAMETER_DATA_TYPE_DYNAMIC_RESPONSE = -7, + FMOD_DSP_PARAMETER_DATA_TYPE_FINITE_LENGTH = -8, +} FMOD_DSP_PARAMETER_DATA_TYPE; + +/* + DSP Callbacks +*/ +typedef FMOD_RESULT (F_CALL *FMOD_DSP_CREATE_CALLBACK) (FMOD_DSP_STATE *dsp_state); +typedef FMOD_RESULT (F_CALL *FMOD_DSP_RELEASE_CALLBACK) (FMOD_DSP_STATE *dsp_state); +typedef FMOD_RESULT (F_CALL *FMOD_DSP_RESET_CALLBACK) (FMOD_DSP_STATE *dsp_state); +typedef FMOD_RESULT (F_CALL *FMOD_DSP_READ_CALLBACK) (FMOD_DSP_STATE *dsp_state, float *inbuffer, float *outbuffer, unsigned int length, int inchannels, int *outchannels); +typedef FMOD_RESULT (F_CALL *FMOD_DSP_PROCESS_CALLBACK) (FMOD_DSP_STATE *dsp_state, unsigned int length, const FMOD_DSP_BUFFER_ARRAY *inbufferarray, FMOD_DSP_BUFFER_ARRAY *outbufferarray, FMOD_BOOL inputsidle, FMOD_DSP_PROCESS_OPERATION op); +typedef FMOD_RESULT (F_CALL *FMOD_DSP_SETPOSITION_CALLBACK) (FMOD_DSP_STATE *dsp_state, unsigned int pos); +typedef FMOD_RESULT (F_CALL *FMOD_DSP_SHOULDIPROCESS_CALLBACK) (FMOD_DSP_STATE *dsp_state, FMOD_BOOL inputsidle, unsigned int length, FMOD_CHANNELMASK inmask, int inchannels, FMOD_SPEAKERMODE speakermode); +typedef FMOD_RESULT (F_CALL *FMOD_DSP_SETPARAM_FLOAT_CALLBACK) (FMOD_DSP_STATE *dsp_state, int index, float value); +typedef FMOD_RESULT (F_CALL *FMOD_DSP_SETPARAM_INT_CALLBACK) (FMOD_DSP_STATE *dsp_state, int index, int value); +typedef FMOD_RESULT (F_CALL *FMOD_DSP_SETPARAM_BOOL_CALLBACK) (FMOD_DSP_STATE *dsp_state, int index, FMOD_BOOL value); +typedef FMOD_RESULT (F_CALL *FMOD_DSP_SETPARAM_DATA_CALLBACK) (FMOD_DSP_STATE *dsp_state, int index, void *data, unsigned int length); +typedef FMOD_RESULT (F_CALL *FMOD_DSP_GETPARAM_FLOAT_CALLBACK) (FMOD_DSP_STATE *dsp_state, int index, float *value, char *valuestr); +typedef FMOD_RESULT (F_CALL *FMOD_DSP_GETPARAM_INT_CALLBACK) (FMOD_DSP_STATE *dsp_state, int index, int *value, char *valuestr); +typedef FMOD_RESULT (F_CALL *FMOD_DSP_GETPARAM_BOOL_CALLBACK) (FMOD_DSP_STATE *dsp_state, int index, FMOD_BOOL *value, char *valuestr); +typedef FMOD_RESULT (F_CALL *FMOD_DSP_GETPARAM_DATA_CALLBACK) (FMOD_DSP_STATE *dsp_state, int index, void **data, unsigned int *length, char *valuestr); +typedef FMOD_RESULT (F_CALL *FMOD_DSP_SYSTEM_REGISTER_CALLBACK) (FMOD_DSP_STATE *dsp_state); +typedef FMOD_RESULT (F_CALL *FMOD_DSP_SYSTEM_DEREGISTER_CALLBACK) (FMOD_DSP_STATE *dsp_state); +typedef FMOD_RESULT (F_CALL *FMOD_DSP_SYSTEM_MIX_CALLBACK) (FMOD_DSP_STATE *dsp_state, int stage); + +/* + DSP Functions +*/ +typedef void * (F_CALL *FMOD_DSP_ALLOC_FUNC) (unsigned int size, FMOD_MEMORY_TYPE type, const char *sourcestr); +typedef void * (F_CALL *FMOD_DSP_REALLOC_FUNC) (void *ptr, unsigned int size, FMOD_MEMORY_TYPE type, const char *sourcestr); +typedef void (F_CALL *FMOD_DSP_FREE_FUNC) (void *ptr, FMOD_MEMORY_TYPE type, const char *sourcestr); +typedef void (F_CALL *FMOD_DSP_LOG_FUNC) (FMOD_DEBUG_FLAGS level, const char *file, int line, const char *function, const char *str, ...); +typedef FMOD_RESULT (F_CALL *FMOD_DSP_GETSAMPLERATE_FUNC) (FMOD_DSP_STATE *dsp_state, int *rate); +typedef FMOD_RESULT (F_CALL *FMOD_DSP_GETBLOCKSIZE_FUNC) (FMOD_DSP_STATE *dsp_state, unsigned int *blocksize); +typedef FMOD_RESULT (F_CALL *FMOD_DSP_GETSPEAKERMODE_FUNC) (FMOD_DSP_STATE *dsp_state, FMOD_SPEAKERMODE *speakermode_mixer, FMOD_SPEAKERMODE *speakermode_output); +typedef FMOD_RESULT (F_CALL *FMOD_DSP_GETCLOCK_FUNC) (FMOD_DSP_STATE *dsp_state, unsigned long long *clock, unsigned int *offset, unsigned int *length); +typedef FMOD_RESULT (F_CALL *FMOD_DSP_GETLISTENERATTRIBUTES_FUNC) (FMOD_DSP_STATE *dsp_state, int *numlisteners, FMOD_3D_ATTRIBUTES *attributes); +typedef FMOD_RESULT (F_CALL *FMOD_DSP_GETUSERDATA_FUNC) (FMOD_DSP_STATE *dsp_state, void **userdata); +typedef FMOD_RESULT (F_CALL *FMOD_DSP_DFT_FFTREAL_FUNC) (FMOD_DSP_STATE *dsp_state, int size, const float *signal, FMOD_COMPLEX* dft, const float *window, int signalhop); +typedef FMOD_RESULT (F_CALL *FMOD_DSP_DFT_IFFTREAL_FUNC) (FMOD_DSP_STATE *dsp_state, int size, const FMOD_COMPLEX *dft, float* signal, const float *window, int signalhop); +typedef FMOD_RESULT (F_CALL *FMOD_DSP_PAN_SUMMONOMATRIX_FUNC) (FMOD_DSP_STATE *dsp_state, FMOD_SPEAKERMODE sourceSpeakerMode, float lowFrequencyGain, float overallGain, float *matrix); +typedef FMOD_RESULT (F_CALL *FMOD_DSP_PAN_SUMSTEREOMATRIX_FUNC) (FMOD_DSP_STATE *dsp_state, FMOD_SPEAKERMODE sourceSpeakerMode, float pan, float lowFrequencyGain, float overallGain, int matrixHop, float *matrix); +typedef FMOD_RESULT (F_CALL *FMOD_DSP_PAN_SUMSURROUNDMATRIX_FUNC) (FMOD_DSP_STATE *dsp_state, FMOD_SPEAKERMODE sourceSpeakerMode, FMOD_SPEAKERMODE targetSpeakerMode, float direction, float extent, float rotation, float lowFrequencyGain, float overallGain, int matrixHop, float *matrix, FMOD_DSP_PAN_SURROUND_FLAGS flags); +typedef FMOD_RESULT (F_CALL *FMOD_DSP_PAN_SUMMONOTOSURROUNDMATRIX_FUNC) (FMOD_DSP_STATE *dsp_state, FMOD_SPEAKERMODE targetSpeakerMode, float direction, float extent, float lowFrequencyGain, float overallGain, int matrixHop, float *matrix); +typedef FMOD_RESULT (F_CALL *FMOD_DSP_PAN_SUMSTEREOTOSURROUNDMATRIX_FUNC) (FMOD_DSP_STATE *dsp_state, FMOD_SPEAKERMODE targetSpeakerMode, float direction, float extent, float rotation, float lowFrequencyGain, float overallGain, int matrixHop, float *matrix); +typedef FMOD_RESULT (F_CALL *FMOD_DSP_PAN_GETROLLOFFGAIN_FUNC) (FMOD_DSP_STATE *dsp_state, FMOD_DSP_PAN_3D_ROLLOFF_TYPE rolloff, float distance, float mindistance, float maxdistance, float *gain); + +/* + DSP Structures +*/ +struct FMOD_DSP_BUFFER_ARRAY +{ + int numbuffers; + int *buffernumchannels; + FMOD_CHANNELMASK *bufferchannelmask; + float **buffers; + FMOD_SPEAKERMODE speakermode; +}; + +struct FMOD_COMPLEX +{ + float real; + float imag; +}; + +typedef struct FMOD_DSP_PARAMETER_FLOAT_MAPPING_PIECEWISE_LINEAR +{ + int numpoints; + float *pointparamvalues; + float *pointpositions; +} FMOD_DSP_PARAMETER_FLOAT_MAPPING_PIECEWISE_LINEAR; + +typedef struct FMOD_DSP_PARAMETER_FLOAT_MAPPING +{ + FMOD_DSP_PARAMETER_FLOAT_MAPPING_TYPE type; + FMOD_DSP_PARAMETER_FLOAT_MAPPING_PIECEWISE_LINEAR piecewiselinearmapping; +} FMOD_DSP_PARAMETER_FLOAT_MAPPING; + +typedef struct FMOD_DSP_PARAMETER_DESC_FLOAT +{ + float min; + float max; + float defaultval; + FMOD_DSP_PARAMETER_FLOAT_MAPPING mapping; +} FMOD_DSP_PARAMETER_DESC_FLOAT; + +typedef struct FMOD_DSP_PARAMETER_DESC_INT +{ + int min; + int max; + int defaultval; + FMOD_BOOL goestoinf; + const char* const* valuenames; +} FMOD_DSP_PARAMETER_DESC_INT; + +typedef struct FMOD_DSP_PARAMETER_DESC_BOOL +{ + FMOD_BOOL defaultval; + const char* const* valuenames; +} FMOD_DSP_PARAMETER_DESC_BOOL; + +typedef struct FMOD_DSP_PARAMETER_DESC_DATA +{ + int datatype; +} FMOD_DSP_PARAMETER_DESC_DATA; + +typedef struct FMOD_DSP_PARAMETER_DESC +{ + FMOD_DSP_PARAMETER_TYPE type; + char name[16]; + char label[16]; + const char *description; + + union + { + FMOD_DSP_PARAMETER_DESC_FLOAT floatdesc; + FMOD_DSP_PARAMETER_DESC_INT intdesc; + FMOD_DSP_PARAMETER_DESC_BOOL booldesc; + FMOD_DSP_PARAMETER_DESC_DATA datadesc; + }; +} FMOD_DSP_PARAMETER_DESC; + +typedef struct FMOD_DSP_PARAMETER_OVERALLGAIN +{ + float linear_gain; + float linear_gain_additive; +} FMOD_DSP_PARAMETER_OVERALLGAIN; + +typedef struct FMOD_DSP_PARAMETER_3DATTRIBUTES +{ + FMOD_3D_ATTRIBUTES relative; + FMOD_3D_ATTRIBUTES absolute; +} FMOD_DSP_PARAMETER_3DATTRIBUTES; + +typedef struct FMOD_DSP_PARAMETER_3DATTRIBUTES_MULTI +{ + int numlisteners; + FMOD_3D_ATTRIBUTES relative[FMOD_MAX_LISTENERS]; + float weight[FMOD_MAX_LISTENERS]; + FMOD_3D_ATTRIBUTES absolute; +} FMOD_DSP_PARAMETER_3DATTRIBUTES_MULTI; + +typedef struct FMOD_DSP_PARAMETER_ATTENUATION_RANGE +{ + float min; + float max; +} FMOD_DSP_PARAMETER_ATTENUATION_RANGE; + +typedef struct FMOD_DSP_PARAMETER_SIDECHAIN +{ + FMOD_BOOL sidechainenable; +} FMOD_DSP_PARAMETER_SIDECHAIN; + +typedef struct FMOD_DSP_PARAMETER_FFT +{ + int length; + int numchannels; + float *spectrum[32]; +} FMOD_DSP_PARAMETER_FFT; + +typedef struct FMOD_DSP_PARAMETER_DYNAMIC_RESPONSE +{ + int numchannels; + float rms[32]; +} FMOD_DSP_PARAMETER_DYNAMIC_RESPONSE; + +typedef struct FMOD_DSP_PARAMETER_FINITE_LENGTH +{ + FMOD_BOOL finite; +} FMOD_DSP_PARAMETER_FINITE_LENGTH; + +typedef struct FMOD_DSP_DESCRIPTION +{ + unsigned int pluginsdkversion; + char name[32]; + unsigned int version; + int numinputbuffers; + int numoutputbuffers; + FMOD_DSP_CREATE_CALLBACK create; + FMOD_DSP_RELEASE_CALLBACK release; + FMOD_DSP_RESET_CALLBACK reset; + FMOD_DSP_READ_CALLBACK read; + FMOD_DSP_PROCESS_CALLBACK process; + FMOD_DSP_SETPOSITION_CALLBACK setposition; + + int numparameters; + FMOD_DSP_PARAMETER_DESC **paramdesc; + FMOD_DSP_SETPARAM_FLOAT_CALLBACK setparameterfloat; + FMOD_DSP_SETPARAM_INT_CALLBACK setparameterint; + FMOD_DSP_SETPARAM_BOOL_CALLBACK setparameterbool; + FMOD_DSP_SETPARAM_DATA_CALLBACK setparameterdata; + FMOD_DSP_GETPARAM_FLOAT_CALLBACK getparameterfloat; + FMOD_DSP_GETPARAM_INT_CALLBACK getparameterint; + FMOD_DSP_GETPARAM_BOOL_CALLBACK getparameterbool; + FMOD_DSP_GETPARAM_DATA_CALLBACK getparameterdata; + FMOD_DSP_SHOULDIPROCESS_CALLBACK shouldiprocess; + void *userdata; + + FMOD_DSP_SYSTEM_REGISTER_CALLBACK sys_register; + FMOD_DSP_SYSTEM_DEREGISTER_CALLBACK sys_deregister; + FMOD_DSP_SYSTEM_MIX_CALLBACK sys_mix; + +} FMOD_DSP_DESCRIPTION; + +typedef struct FMOD_DSP_STATE_DFT_FUNCTIONS +{ + FMOD_DSP_DFT_FFTREAL_FUNC fftreal; + FMOD_DSP_DFT_IFFTREAL_FUNC inversefftreal; +} FMOD_DSP_STATE_DFT_FUNCTIONS; + +typedef struct FMOD_DSP_STATE_PAN_FUNCTIONS +{ + FMOD_DSP_PAN_SUMMONOMATRIX_FUNC summonomatrix; + FMOD_DSP_PAN_SUMSTEREOMATRIX_FUNC sumstereomatrix; + FMOD_DSP_PAN_SUMSURROUNDMATRIX_FUNC sumsurroundmatrix; + FMOD_DSP_PAN_SUMMONOTOSURROUNDMATRIX_FUNC summonotosurroundmatrix; + FMOD_DSP_PAN_SUMSTEREOTOSURROUNDMATRIX_FUNC sumstereotosurroundmatrix; + FMOD_DSP_PAN_GETROLLOFFGAIN_FUNC getrolloffgain; +} FMOD_DSP_STATE_PAN_FUNCTIONS; + +typedef struct FMOD_DSP_STATE_FUNCTIONS +{ + FMOD_DSP_ALLOC_FUNC alloc; + FMOD_DSP_REALLOC_FUNC realloc; + FMOD_DSP_FREE_FUNC free; + FMOD_DSP_GETSAMPLERATE_FUNC getsamplerate; + FMOD_DSP_GETBLOCKSIZE_FUNC getblocksize; + FMOD_DSP_STATE_DFT_FUNCTIONS *dft; + FMOD_DSP_STATE_PAN_FUNCTIONS *pan; + FMOD_DSP_GETSPEAKERMODE_FUNC getspeakermode; + FMOD_DSP_GETCLOCK_FUNC getclock; + FMOD_DSP_GETLISTENERATTRIBUTES_FUNC getlistenerattributes; + FMOD_DSP_LOG_FUNC log; + FMOD_DSP_GETUSERDATA_FUNC getuserdata; +} FMOD_DSP_STATE_FUNCTIONS; + +struct FMOD_DSP_STATE +{ + void *instance; + void *plugindata; + FMOD_CHANNELMASK channelmask; + FMOD_SPEAKERMODE source_speakermode; + float *sidechaindata; + int sidechainchannels; + FMOD_DSP_STATE_FUNCTIONS *functions; + int systemobject; +}; + +typedef struct FMOD_DSP_METERING_INFO +{ + int numsamples; + float peaklevel[32]; + float rmslevel[32]; + short numchannels; +} FMOD_DSP_METERING_INFO; + +/* + DSP Macros +*/ +#define FMOD_DSP_INIT_PARAMDESC_FLOAT(_paramstruct, _name, _label, _description, _min, _max, _defaultval) \ + memset(&(_paramstruct), 0, sizeof(_paramstruct)); \ + (_paramstruct).type = FMOD_DSP_PARAMETER_TYPE_FLOAT; \ + strncpy((_paramstruct).name, _name, 15); \ + strncpy((_paramstruct).label, _label, 15); \ + (_paramstruct).description = _description; \ + (_paramstruct).floatdesc.min = _min; \ + (_paramstruct).floatdesc.max = _max; \ + (_paramstruct).floatdesc.defaultval = _defaultval; \ + (_paramstruct).floatdesc.mapping.type = FMOD_DSP_PARAMETER_FLOAT_MAPPING_TYPE_AUTO; + +#define FMOD_DSP_INIT_PARAMDESC_FLOAT_WITH_MAPPING(_paramstruct, _name, _label, _description, _defaultval, _values, _positions); \ + memset(&(_paramstruct), 0, sizeof(_paramstruct)); \ + (_paramstruct).type = FMOD_DSP_PARAMETER_TYPE_FLOAT; \ + strncpy((_paramstruct).name, _name , 15); \ + strncpy((_paramstruct).label, _label, 15); \ + (_paramstruct).description = _description; \ + (_paramstruct).floatdesc.min = _values[0]; \ + (_paramstruct).floatdesc.max = _values[sizeof(_values) / sizeof(float) - 1]; \ + (_paramstruct).floatdesc.defaultval = _defaultval; \ + (_paramstruct).floatdesc.mapping.type = FMOD_DSP_PARAMETER_FLOAT_MAPPING_TYPE_PIECEWISE_LINEAR; \ + (_paramstruct).floatdesc.mapping.piecewiselinearmapping.numpoints = sizeof(_values) / sizeof(float); \ + (_paramstruct).floatdesc.mapping.piecewiselinearmapping.pointparamvalues = _values; \ + (_paramstruct).floatdesc.mapping.piecewiselinearmapping.pointpositions = _positions; + +#define FMOD_DSP_INIT_PARAMDESC_INT(_paramstruct, _name, _label, _description, _min, _max, _defaultval, _goestoinf, _valuenames) \ + memset(&(_paramstruct), 0, sizeof(_paramstruct)); \ + (_paramstruct).type = FMOD_DSP_PARAMETER_TYPE_INT; \ + strncpy((_paramstruct).name, _name , 15); \ + strncpy((_paramstruct).label, _label, 15); \ + (_paramstruct).description = _description; \ + (_paramstruct).intdesc.min = _min; \ + (_paramstruct).intdesc.max = _max; \ + (_paramstruct).intdesc.defaultval = _defaultval; \ + (_paramstruct).intdesc.goestoinf = _goestoinf; \ + (_paramstruct).intdesc.valuenames = _valuenames; + +#define FMOD_DSP_INIT_PARAMDESC_INT_ENUMERATED(_paramstruct, _name, _label, _description, _defaultval, _valuenames) \ + memset(&(_paramstruct), 0, sizeof(_paramstruct)); \ + (_paramstruct).type = FMOD_DSP_PARAMETER_TYPE_INT; \ + strncpy((_paramstruct).name, _name , 15); \ + strncpy((_paramstruct).label, _label, 15); \ + (_paramstruct).description = _description; \ + (_paramstruct).intdesc.min = 0; \ + (_paramstruct).intdesc.max = sizeof(_valuenames) / sizeof(char*) - 1; \ + (_paramstruct).intdesc.defaultval = _defaultval; \ + (_paramstruct).intdesc.goestoinf = false; \ + (_paramstruct).intdesc.valuenames = _valuenames; + +#define FMOD_DSP_INIT_PARAMDESC_BOOL(_paramstruct, _name, _label, _description, _defaultval, _valuenames) \ + memset(&(_paramstruct), 0, sizeof(_paramstruct)); \ + (_paramstruct).type = FMOD_DSP_PARAMETER_TYPE_BOOL; \ + strncpy((_paramstruct).name, _name , 15); \ + strncpy((_paramstruct).label, _label, 15); \ + (_paramstruct).description = _description; \ + (_paramstruct).booldesc.defaultval = _defaultval; \ + (_paramstruct).booldesc.valuenames = _valuenames; + +#define FMOD_DSP_INIT_PARAMDESC_DATA(_paramstruct, _name, _label, _description, _datatype) \ + memset(&(_paramstruct), 0, sizeof(_paramstruct)); \ + (_paramstruct).type = FMOD_DSP_PARAMETER_TYPE_DATA; \ + strncpy((_paramstruct).name, _name , 15); \ + strncpy((_paramstruct).label, _label, 15); \ + (_paramstruct).description = _description; \ + (_paramstruct).datadesc.datatype = _datatype; + +#define FMOD_DSP_DECLARE_PARAMDESC_FLOAT(_param, _name, _desc, _label, _min, _max, _default) \ + static FMOD_DSP_PARAMETER_DESC _param = {FMOD_DSP_PARAMETER_TYPE_FLOAT, _name, _label, _desc}; \ + _param.floatdesc.min = _min; \ + _param.floatdesc.max = _max; \ + _param.floatdesc.defaultval = _default; \ + _param.floatdesc.mapping.type = FMOD_DSP_PARAMETER_FLOAT_MAPPING_TYPE_AUTO; + +#define FMOD_DSP_DECLARE_PARAMDESC_INT(_param, _name, _desc, _label, _min, _max, _default, _goestoinf) \ + static FMOD_DSP_PARAMETER_DESC _param = {FMOD_DSP_PARAMETER_TYPE_INT, _name, _label, _desc}; \ + _param.intdesc.min = _min; \ + _param.intdesc.max = _max; \ + _param.intdesc.defaultval = _default; \ + _param.intdesc.goestoinf = _goestoinf; + +#define FMOD_DSP_DECLARE_PARAMDESC_ENUM(_param, _name, _desc, _valuenames, _default) \ + static FMOD_DSP_PARAMETER_DESC _param = {FMOD_DSP_PARAMETER_TYPE_INT, _name, "", _desc}; \ + _param.intdesc.valuenames = _valuenames; \ + _param.intdesc.max = sizeof(_valuenames) / sizeof(_valuenames[0]) - 1; \ + _param.intdesc.defaultval = _default; + +#define FMOD_DSP_DECLARE_PARAMDESC_BOOL(_param, _name, _desc, _valuenames, _default) \ + static FMOD_DSP_PARAMETER_DESC _param = {FMOD_DSP_PARAMETER_TYPE_BOOL, _name, "", _desc}; \ + _param.booldesc.valuenames = _valuenames; \ + _param.booldesc.defaultval = _default; + +#define FMOD_DSP_DECLARE_PARAMDESC_DATA(_param, _name, _desc, _datatype) \ + static FMOD_DSP_PARAMETER_DESC _param = {FMOD_DSP_PARAMETER_TYPE_DATA, _name, "", _desc}; \ + _param.datadesc.datatype = _datatype; + +#define FMOD_DSP_ALLOC(_state, _size) \ + (_state)->functions->alloc(_size, FMOD_MEMORY_NORMAL, __FILE__) +#define FMOD_DSP_REALLOC(_state, _ptr, _size) \ + (_state)->functions->realloc(_ptr, _size, FMOD_MEMORY_NORMAL, __FILE__) +#define FMOD_DSP_FREE(_state, _ptr) \ + (_state)->functions->free(_ptr, FMOD_MEMORY_NORMAL, __FILE__) +#define FMOD_DSP_LOG(_state, _level, _location, _format, ...) \ + (_state)->functions->log(_level, __FILE__, __LINE__, _location, _format, ##__VA_ARGS__) +#define FMOD_DSP_GETSAMPLERATE(_state, _rate) \ + (_state)->functions->getsamplerate(_state, _rate) +#define FMOD_DSP_GETBLOCKSIZE(_state, _blocksize) \ + (_state)->functions->getblocksize(_state, _blocksize) +#define FMOD_DSP_GETSPEAKERMODE(_state, _speakermodemix, _speakermodeout) \ + (_state)->functions->getspeakermode(_state, _speakermodemix, _speakermodeout) +#define FMOD_DSP_GETCLOCK(_state, _clock, _offset, _length) \ + (_state)->functions->getclock(_state, _clock, _offset, _length) +#define FMOD_DSP_GETLISTENERATTRIBUTES(_state, _numlisteners, _attributes) \ + (_state)->functions->getlistenerattributes(_state, _numlisteners, _attributes) +#define FMOD_DSP_GETUSERDATA(_state, _userdata) \ + (_state)->functions->getuserdata(_state, _userdata) +#define FMOD_DSP_DFT_FFTREAL(_state, _size, _signal, _dft, _window, _signalhop) \ + (_state)->functions->dft->fftreal(_state, _size, _signal, _dft, _window, _signalhop) +#define FMOD_DSP_DFT_IFFTREAL(_state, _size, _dft, _signal, _window, _signalhop) \ + (_state)->functions->dft->inversefftreal(_state, _size, _dft, _signal, _window, _signalhop) +#define FMOD_DSP_PAN_SUMMONOMATRIX(_state, _sourcespeakermode, _lowfrequencygain, _overallgain, _matrix) \ + (_state)->functions->pan->summonomatrix(_state, _sourcespeakermode, _lowfrequencygain, _overallgain, _matrix) +#define FMOD_DSP_PAN_SUMSTEREOMATRIX(_state, _sourcespeakermode, _pan, _lowfrequencygain, _overallgain, _matrixhop, _matrix) \ + (_state)->functions->pan->sumstereomatrix(_state, _sourcespeakermode, _pan, _lowfrequencygain, _overallgain, _matrixhop, _matrix) +#define FMOD_DSP_PAN_SUMSURROUNDMATRIX(_state, _sourcespeakermode, _targetspeakermode, _direction, _extent, _rotation, _lowfrequencygain, _overallgain, _matrixhop, _matrix, _flags) \ + (_state)->functions->pan->sumsurroundmatrix(_state, _sourcespeakermode, _targetspeakermode, _direction, _extent, _rotation, _lowfrequencygain, _overallgain, _matrixhop, _matrix, _flags) +#define FMOD_DSP_PAN_SUMMONOTOSURROUNDMATRIX(_state, _targetspeakermode, _direction, _extent, _lowfrequencygain, _overallgain, _matrixhop, _matrix) \ + (_state)->functions->pan->summonotosurroundmatrix(_state, _targetspeakermode, _direction, _extent, _lowfrequencygain, _overallgain, _matrixhop, _matrix) +#define FMOD_DSP_PAN_SUMSTEREOTOSURROUNDMATRIX(_state, _targetspeakermode, _direction, _extent, _rotation, _lowfrequencygain, _overallgain, matrixhop, _matrix) \ + (_state)->functions->pan->sumstereotosurroundmatrix(_state, _targetspeakermode, _direction, _extent, _rotation, _lowfrequencygain, _overallgain, matrixhop, _matrix) +#define FMOD_DSP_PAN_GETROLLOFFGAIN(_state, _rolloff, _distance, _mindistance, _maxdistance, _gain) \ + (_state)->functions->pan->getrolloffgain(_state, _rolloff, _distance, _mindistance, _maxdistance, _gain) + +#endif + diff --git a/FMOD/api/core/inc/fmod_dsp_effects.h b/FMOD/api/core/inc/fmod_dsp_effects.h new file mode 100644 index 0000000..5adf9cb --- /dev/null +++ b/FMOD/api/core/inc/fmod_dsp_effects.h @@ -0,0 +1,632 @@ +/* ============================================================================================================= */ +/* FMOD Core API - Built-in effects header file. */ +/* Copyright (c), Firelight Technologies Pty, Ltd. 2004-2026. */ +/* */ +/* In this header you can find parameter structures for FMOD system registered DSP effects */ +/* and generators. */ +/* */ +/* For more detail visit: */ +/* https://fmod.com/docs/2.03/api/core-api-common-dsp-effects.html#fmod_dsp_type */ +/* ============================================================================================================= */ + +#ifndef _FMOD_DSP_EFFECTS_H +#define _FMOD_DSP_EFFECTS_H + +typedef enum +{ + FMOD_DSP_TYPE_UNKNOWN, + FMOD_DSP_TYPE_MIXER, + FMOD_DSP_TYPE_OSCILLATOR, + FMOD_DSP_TYPE_LOWPASS, + FMOD_DSP_TYPE_ITLOWPASS, + FMOD_DSP_TYPE_HIGHPASS, + FMOD_DSP_TYPE_ECHO, + FMOD_DSP_TYPE_FADER, + FMOD_DSP_TYPE_FLANGE, + FMOD_DSP_TYPE_DISTORTION, + FMOD_DSP_TYPE_NORMALIZE, + FMOD_DSP_TYPE_LIMITER, + FMOD_DSP_TYPE_PARAMEQ, + FMOD_DSP_TYPE_PITCHSHIFT, + FMOD_DSP_TYPE_CHORUS, + FMOD_DSP_TYPE_ITECHO, + FMOD_DSP_TYPE_COMPRESSOR, + FMOD_DSP_TYPE_SFXREVERB, + FMOD_DSP_TYPE_LOWPASS_SIMPLE, + FMOD_DSP_TYPE_DELAY, + FMOD_DSP_TYPE_TREMOLO, + FMOD_DSP_TYPE_SEND, + FMOD_DSP_TYPE_RETURN, + FMOD_DSP_TYPE_HIGHPASS_SIMPLE, + FMOD_DSP_TYPE_PAN, + FMOD_DSP_TYPE_THREE_EQ, + FMOD_DSP_TYPE_FFT, + FMOD_DSP_TYPE_LOUDNESS_METER, + FMOD_DSP_TYPE_CONVOLUTIONREVERB, + FMOD_DSP_TYPE_CHANNELMIX, + FMOD_DSP_TYPE_TRANSCEIVER, + FMOD_DSP_TYPE_OBJECTPAN, + FMOD_DSP_TYPE_MULTIBAND_EQ, + FMOD_DSP_TYPE_MULTIBAND_DYNAMICS, + + FMOD_DSP_TYPE_MAX, + FMOD_DSP_TYPE_FORCEINT = 65536 /* Makes sure this enum is signed 32bit. */ +} FMOD_DSP_TYPE; + +/* + =================================================================================================== + + FMOD built in effect parameters. + Use DSP::setParameter with these enums for the 'index' parameter. + + =================================================================================================== +*/ + +typedef enum +{ + FMOD_DSP_OSCILLATOR_TYPE, + FMOD_DSP_OSCILLATOR_RATE +} FMOD_DSP_OSCILLATOR; + + +typedef enum +{ + FMOD_DSP_LOWPASS_CUTOFF, + FMOD_DSP_LOWPASS_RESONANCE +} FMOD_DSP_LOWPASS; + + +typedef enum +{ + FMOD_DSP_ITLOWPASS_CUTOFF, + FMOD_DSP_ITLOWPASS_RESONANCE +} FMOD_DSP_ITLOWPASS; + + +typedef enum +{ + FMOD_DSP_HIGHPASS_CUTOFF, + FMOD_DSP_HIGHPASS_RESONANCE +} FMOD_DSP_HIGHPASS; + + +typedef enum +{ + FMOD_DSP_ECHO_DELAY, + FMOD_DSP_ECHO_FEEDBACK, + FMOD_DSP_ECHO_DRYLEVEL, + FMOD_DSP_ECHO_WETLEVEL, + FMOD_DSP_ECHO_DELAYCHANGEMODE +} FMOD_DSP_ECHO; + + +typedef enum +{ + FMOD_DSP_ECHO_DELAYCHANGEMODE_FADE, + FMOD_DSP_ECHO_DELAYCHANGEMODE_LERP, + FMOD_DSP_ECHO_DELAYCHANGEMODE_NONE +} FMOD_DSP_ECHO_DELAYCHANGEMODE_TYPE; + + +typedef enum FMOD_DSP_FADER +{ + FMOD_DSP_FADER_GAIN, + FMOD_DSP_FADER_OVERALL_GAIN, +} FMOD_DSP_FADER; + + +typedef enum +{ + FMOD_DSP_FLANGE_MIX, + FMOD_DSP_FLANGE_DEPTH, + FMOD_DSP_FLANGE_RATE +} FMOD_DSP_FLANGE; + + +typedef enum +{ + FMOD_DSP_DISTORTION_LEVEL +} FMOD_DSP_DISTORTION; + + +typedef enum +{ + FMOD_DSP_NORMALIZE_FADETIME, + FMOD_DSP_NORMALIZE_THRESHOLD, + FMOD_DSP_NORMALIZE_MAXAMP +} FMOD_DSP_NORMALIZE; + + +typedef enum +{ + FMOD_DSP_LIMITER_RELEASETIME, + FMOD_DSP_LIMITER_CEILING, + FMOD_DSP_LIMITER_MAXIMIZERGAIN, + FMOD_DSP_LIMITER_MODE, +} FMOD_DSP_LIMITER; + + +typedef enum +{ + FMOD_DSP_PARAMEQ_CENTER, + FMOD_DSP_PARAMEQ_BANDWIDTH, + FMOD_DSP_PARAMEQ_GAIN +} FMOD_DSP_PARAMEQ; + + +typedef enum FMOD_DSP_MULTIBAND_EQ +{ + FMOD_DSP_MULTIBAND_EQ_A_FILTER, + FMOD_DSP_MULTIBAND_EQ_A_FREQUENCY, + FMOD_DSP_MULTIBAND_EQ_A_Q, + FMOD_DSP_MULTIBAND_EQ_A_GAIN, + FMOD_DSP_MULTIBAND_EQ_B_FILTER, + FMOD_DSP_MULTIBAND_EQ_B_FREQUENCY, + FMOD_DSP_MULTIBAND_EQ_B_Q, + FMOD_DSP_MULTIBAND_EQ_B_GAIN, + FMOD_DSP_MULTIBAND_EQ_C_FILTER, + FMOD_DSP_MULTIBAND_EQ_C_FREQUENCY, + FMOD_DSP_MULTIBAND_EQ_C_Q, + FMOD_DSP_MULTIBAND_EQ_C_GAIN, + FMOD_DSP_MULTIBAND_EQ_D_FILTER, + FMOD_DSP_MULTIBAND_EQ_D_FREQUENCY, + FMOD_DSP_MULTIBAND_EQ_D_Q, + FMOD_DSP_MULTIBAND_EQ_D_GAIN, + FMOD_DSP_MULTIBAND_EQ_E_FILTER, + FMOD_DSP_MULTIBAND_EQ_E_FREQUENCY, + FMOD_DSP_MULTIBAND_EQ_E_Q, + FMOD_DSP_MULTIBAND_EQ_E_GAIN, +} FMOD_DSP_MULTIBAND_EQ; + + +typedef enum FMOD_DSP_MULTIBAND_EQ_FILTER_TYPE +{ + FMOD_DSP_MULTIBAND_EQ_FILTER_DISABLED, + FMOD_DSP_MULTIBAND_EQ_FILTER_LOWPASS_12DB, + FMOD_DSP_MULTIBAND_EQ_FILTER_LOWPASS_24DB, + FMOD_DSP_MULTIBAND_EQ_FILTER_LOWPASS_48DB, + FMOD_DSP_MULTIBAND_EQ_FILTER_HIGHPASS_12DB, + FMOD_DSP_MULTIBAND_EQ_FILTER_HIGHPASS_24DB, + FMOD_DSP_MULTIBAND_EQ_FILTER_HIGHPASS_48DB, + FMOD_DSP_MULTIBAND_EQ_FILTER_LOWSHELF, + FMOD_DSP_MULTIBAND_EQ_FILTER_HIGHSHELF, + FMOD_DSP_MULTIBAND_EQ_FILTER_PEAKING, + FMOD_DSP_MULTIBAND_EQ_FILTER_BANDPASS, + FMOD_DSP_MULTIBAND_EQ_FILTER_NOTCH, + FMOD_DSP_MULTIBAND_EQ_FILTER_ALLPASS, + FMOD_DSP_MULTIBAND_EQ_FILTER_LOWPASS_6DB, + FMOD_DSP_MULTIBAND_EQ_FILTER_HIGHPASS_6DB, +} FMOD_DSP_MULTIBAND_EQ_FILTER_TYPE; + + +typedef enum FMOD_DSP_MULTIBAND_DYNAMICS +{ + FMOD_DSP_MULTIBAND_DYNAMICS_LOWER_FREQUENCY, + FMOD_DSP_MULTIBAND_DYNAMICS_UPPER_FREQUENCY, + FMOD_DSP_MULTIBAND_DYNAMICS_LINKED, + FMOD_DSP_MULTIBAND_DYNAMICS_USE_SIDECHAIN, + FMOD_DSP_MULTIBAND_DYNAMICS_A_MODE, + FMOD_DSP_MULTIBAND_DYNAMICS_A_GAIN, + FMOD_DSP_MULTIBAND_DYNAMICS_A_THRESHOLD, + FMOD_DSP_MULTIBAND_DYNAMICS_A_RATIO, + FMOD_DSP_MULTIBAND_DYNAMICS_A_ATTACK, + FMOD_DSP_MULTIBAND_DYNAMICS_A_RELEASE, + FMOD_DSP_MULTIBAND_DYNAMICS_A_GAIN_MAKEUP, + FMOD_DSP_MULTIBAND_DYNAMICS_A_RESPONSE_DATA, + FMOD_DSP_MULTIBAND_DYNAMICS_B_MODE, + FMOD_DSP_MULTIBAND_DYNAMICS_B_GAIN, + FMOD_DSP_MULTIBAND_DYNAMICS_B_THRESHOLD, + FMOD_DSP_MULTIBAND_DYNAMICS_B_RATIO, + FMOD_DSP_MULTIBAND_DYNAMICS_B_ATTACK, + FMOD_DSP_MULTIBAND_DYNAMICS_B_RELEASE, + FMOD_DSP_MULTIBAND_DYNAMICS_B_GAIN_MAKEUP, + FMOD_DSP_MULTIBAND_DYNAMICS_B_RESPONSE_DATA, + FMOD_DSP_MULTIBAND_DYNAMICS_C_MODE, + FMOD_DSP_MULTIBAND_DYNAMICS_C_GAIN, + FMOD_DSP_MULTIBAND_DYNAMICS_C_THRESHOLD, + FMOD_DSP_MULTIBAND_DYNAMICS_C_RATIO, + FMOD_DSP_MULTIBAND_DYNAMICS_C_ATTACK, + FMOD_DSP_MULTIBAND_DYNAMICS_C_RELEASE, + FMOD_DSP_MULTIBAND_DYNAMICS_C_GAIN_MAKEUP, + FMOD_DSP_MULTIBAND_DYNAMICS_C_RESPONSE_DATA, +} FMOD_DSP_MULTIBAND_DYNAMICS; + + +typedef enum FMOD_DSP_MULTIBAND_DYNAMICS_MODE_TYPE +{ + FMOD_DSP_MULTIBAND_DYNAMICS_MODE_DISABLED, + FMOD_DSP_MULTIBAND_DYNAMICS_MODE_COMPRESS_UP, + FMOD_DSP_MULTIBAND_DYNAMICS_MODE_COMPRESS_DOWN, + FMOD_DSP_MULTIBAND_DYNAMICS_MODE_EXPAND_UP, + FMOD_DSP_MULTIBAND_DYNAMICS_MODE_EXPAND_DOWN +} FMOD_DSP_MULTIBAND_DYNAMICS_MODE_TYPE; + + +typedef enum +{ + FMOD_DSP_PITCHSHIFT_PITCH, + FMOD_DSP_PITCHSHIFT_FFTSIZE, + FMOD_DSP_PITCHSHIFT_OVERLAP, + FMOD_DSP_PITCHSHIFT_MAXCHANNELS +} FMOD_DSP_PITCHSHIFT; + + +typedef enum +{ + FMOD_DSP_CHORUS_MIX, + FMOD_DSP_CHORUS_RATE, + FMOD_DSP_CHORUS_DEPTH, +} FMOD_DSP_CHORUS; + + +typedef enum +{ + FMOD_DSP_ITECHO_WETDRYMIX, + FMOD_DSP_ITECHO_FEEDBACK, + FMOD_DSP_ITECHO_LEFTDELAY, + FMOD_DSP_ITECHO_RIGHTDELAY, + FMOD_DSP_ITECHO_PANDELAY +} FMOD_DSP_ITECHO; + +typedef enum +{ + FMOD_DSP_COMPRESSOR_THRESHOLD, + FMOD_DSP_COMPRESSOR_RATIO, + FMOD_DSP_COMPRESSOR_ATTACK, + FMOD_DSP_COMPRESSOR_RELEASE, + FMOD_DSP_COMPRESSOR_GAINMAKEUP, + FMOD_DSP_COMPRESSOR_USESIDECHAIN, + FMOD_DSP_COMPRESSOR_LINKED +} FMOD_DSP_COMPRESSOR; + +typedef enum +{ + FMOD_DSP_SFXREVERB_DECAYTIME, + FMOD_DSP_SFXREVERB_EARLYDELAY, + FMOD_DSP_SFXREVERB_LATEDELAY, + FMOD_DSP_SFXREVERB_HFREFERENCE, + FMOD_DSP_SFXREVERB_HFDECAYRATIO, + FMOD_DSP_SFXREVERB_DIFFUSION, + FMOD_DSP_SFXREVERB_DENSITY, + FMOD_DSP_SFXREVERB_LOWSHELFFREQUENCY, + FMOD_DSP_SFXREVERB_LOWSHELFGAIN, + FMOD_DSP_SFXREVERB_HIGHCUT, + FMOD_DSP_SFXREVERB_EARLYLATEMIX, + FMOD_DSP_SFXREVERB_WETLEVEL, + FMOD_DSP_SFXREVERB_DRYLEVEL +} FMOD_DSP_SFXREVERB; + +typedef enum +{ + FMOD_DSP_LOWPASS_SIMPLE_CUTOFF +} FMOD_DSP_LOWPASS_SIMPLE; + + +typedef enum +{ + FMOD_DSP_DELAY_CH0, + FMOD_DSP_DELAY_CH1, + FMOD_DSP_DELAY_CH2, + FMOD_DSP_DELAY_CH3, + FMOD_DSP_DELAY_CH4, + FMOD_DSP_DELAY_CH5, + FMOD_DSP_DELAY_CH6, + FMOD_DSP_DELAY_CH7, + FMOD_DSP_DELAY_CH8, + FMOD_DSP_DELAY_CH9, + FMOD_DSP_DELAY_CH10, + FMOD_DSP_DELAY_CH11, + FMOD_DSP_DELAY_CH12, + FMOD_DSP_DELAY_CH13, + FMOD_DSP_DELAY_CH14, + FMOD_DSP_DELAY_CH15, + FMOD_DSP_DELAY_MAXDELAY +} FMOD_DSP_DELAY; + + +typedef enum +{ + FMOD_DSP_TREMOLO_FREQUENCY, + FMOD_DSP_TREMOLO_DEPTH, + FMOD_DSP_TREMOLO_SHAPE, + FMOD_DSP_TREMOLO_SKEW, + FMOD_DSP_TREMOLO_DUTY, + FMOD_DSP_TREMOLO_SQUARE, + FMOD_DSP_TREMOLO_PHASE, + FMOD_DSP_TREMOLO_SPREAD +} FMOD_DSP_TREMOLO; + + +typedef enum +{ + FMOD_DSP_SEND_RETURNID, + FMOD_DSP_SEND_LEVEL, +} FMOD_DSP_SEND; + + +typedef enum +{ + FMOD_DSP_RETURN_ID, + FMOD_DSP_RETURN_INPUT_SPEAKER_MODE +} FMOD_DSP_RETURN; + + +typedef enum +{ + FMOD_DSP_HIGHPASS_SIMPLE_CUTOFF +} FMOD_DSP_HIGHPASS_SIMPLE; + + +typedef enum +{ + FMOD_DSP_PAN_2D_STEREO_MODE_DISTRIBUTED, + FMOD_DSP_PAN_2D_STEREO_MODE_DISCRETE +} FMOD_DSP_PAN_2D_STEREO_MODE_TYPE; + + +typedef enum +{ + FMOD_DSP_PAN_MODE_MONO, + FMOD_DSP_PAN_MODE_STEREO, + FMOD_DSP_PAN_MODE_SURROUND +} FMOD_DSP_PAN_MODE_TYPE; + + +typedef enum +{ + FMOD_DSP_PAN_3D_ROLLOFF_LINEARSQUARED, + FMOD_DSP_PAN_3D_ROLLOFF_LINEAR, + FMOD_DSP_PAN_3D_ROLLOFF_INVERSE, + FMOD_DSP_PAN_3D_ROLLOFF_INVERSETAPERED, + FMOD_DSP_PAN_3D_ROLLOFF_CUSTOM +} FMOD_DSP_PAN_3D_ROLLOFF_TYPE; + + +typedef enum +{ + FMOD_DSP_PAN_3D_EXTENT_MODE_AUTO, + FMOD_DSP_PAN_3D_EXTENT_MODE_USER, + FMOD_DSP_PAN_3D_EXTENT_MODE_OFF +} FMOD_DSP_PAN_3D_EXTENT_MODE_TYPE; + + +typedef enum +{ + FMOD_DSP_PAN_MODE, + FMOD_DSP_PAN_2D_STEREO_POSITION, + FMOD_DSP_PAN_2D_DIRECTION, + FMOD_DSP_PAN_2D_EXTENT, + FMOD_DSP_PAN_2D_ROTATION, + FMOD_DSP_PAN_2D_LFE_LEVEL, + FMOD_DSP_PAN_2D_STEREO_MODE, + FMOD_DSP_PAN_2D_STEREO_SEPARATION, + FMOD_DSP_PAN_2D_STEREO_AXIS, + FMOD_DSP_PAN_ENABLED_SPEAKERS, + FMOD_DSP_PAN_3D_POSITION, + FMOD_DSP_PAN_3D_ROLLOFF, + FMOD_DSP_PAN_3D_MIN_DISTANCE, + FMOD_DSP_PAN_3D_MAX_DISTANCE, + FMOD_DSP_PAN_3D_EXTENT_MODE, + FMOD_DSP_PAN_3D_SOUND_SIZE, + FMOD_DSP_PAN_3D_MIN_EXTENT, + FMOD_DSP_PAN_3D_PAN_BLEND, + FMOD_DSP_PAN_LFE_UPMIX_ENABLED, + FMOD_DSP_PAN_OVERALL_GAIN, + FMOD_DSP_PAN_SURROUND_SPEAKER_MODE, + FMOD_DSP_PAN_2D_HEIGHT_BLEND, + FMOD_DSP_PAN_ATTENUATION_RANGE, + FMOD_DSP_PAN_OVERRIDE_RANGE +} FMOD_DSP_PAN; + + +typedef enum +{ + FMOD_DSP_THREE_EQ_CROSSOVERSLOPE_12DB, + FMOD_DSP_THREE_EQ_CROSSOVERSLOPE_24DB, + FMOD_DSP_THREE_EQ_CROSSOVERSLOPE_48DB +} FMOD_DSP_THREE_EQ_CROSSOVERSLOPE_TYPE; + + +typedef enum +{ + FMOD_DSP_THREE_EQ_LOWGAIN, + FMOD_DSP_THREE_EQ_MIDGAIN, + FMOD_DSP_THREE_EQ_HIGHGAIN, + FMOD_DSP_THREE_EQ_LOWCROSSOVER, + FMOD_DSP_THREE_EQ_HIGHCROSSOVER, + FMOD_DSP_THREE_EQ_CROSSOVERSLOPE +} FMOD_DSP_THREE_EQ; + + +typedef enum +{ + FMOD_DSP_FFT_WINDOW_RECT, + FMOD_DSP_FFT_WINDOW_TRIANGLE, + FMOD_DSP_FFT_WINDOW_HAMMING, + FMOD_DSP_FFT_WINDOW_HANNING, + FMOD_DSP_FFT_WINDOW_BLACKMAN, + FMOD_DSP_FFT_WINDOW_BLACKMANHARRIS +} FMOD_DSP_FFT_WINDOW_TYPE; + + +typedef enum +{ + FMOD_DSP_FFT_DOWNMIX_NONE, + FMOD_DSP_FFT_DOWNMIX_MONO, +} FMOD_DSP_FFT_DOWNMIX_TYPE; + + +typedef enum +{ + FMOD_DSP_FFT_WINDOWSIZE, + FMOD_DSP_FFT_WINDOW, + FMOD_DSP_FFT_BAND_START_FREQ, + FMOD_DSP_FFT_BAND_STOP_FREQ, + FMOD_DSP_FFT_SPECTRUMDATA, + FMOD_DSP_FFT_RMS, + FMOD_DSP_FFT_SPECTRAL_CENTROID, + FMOD_DSP_FFT_IMMEDIATE_MODE, + FMOD_DSP_FFT_DOWNMIX, + FMOD_DSP_FFT_CHANNEL, +} FMOD_DSP_FFT; + +#define FMOD_DSP_LOUDNESS_METER_HISTOGRAM_SAMPLES 66 + +typedef enum +{ + FMOD_DSP_LOUDNESS_METER_STATE, + FMOD_DSP_LOUDNESS_METER_WEIGHTING, + FMOD_DSP_LOUDNESS_METER_INFO +} FMOD_DSP_LOUDNESS_METER; + + +typedef enum +{ + FMOD_DSP_LOUDNESS_METER_STATE_RESET_INTEGRATED = -3, + FMOD_DSP_LOUDNESS_METER_STATE_RESET_MAXPEAK = -2, + FMOD_DSP_LOUDNESS_METER_STATE_RESET_ALL = -1, + FMOD_DSP_LOUDNESS_METER_STATE_PAUSED = 0, + FMOD_DSP_LOUDNESS_METER_STATE_ANALYZING = 1 +} FMOD_DSP_LOUDNESS_METER_STATE_TYPE; + +typedef struct FMOD_DSP_LOUDNESS_METER_INFO_TYPE +{ + float momentaryloudness; + float shorttermloudness; + float integratedloudness; + float loudness10thpercentile; + float loudness95thpercentile; + float loudnesshistogram[FMOD_DSP_LOUDNESS_METER_HISTOGRAM_SAMPLES]; + float maxtruepeak; + float maxmomentaryloudness; +} FMOD_DSP_LOUDNESS_METER_INFO_TYPE; + +typedef struct FMOD_DSP_LOUDNESS_METER_WEIGHTING_TYPE +{ + float channelweight[32]; +} FMOD_DSP_LOUDNESS_METER_WEIGHTING_TYPE; + +typedef enum +{ + FMOD_DSP_CONVOLUTION_REVERB_PARAM_IR, + FMOD_DSP_CONVOLUTION_REVERB_PARAM_WET, + FMOD_DSP_CONVOLUTION_REVERB_PARAM_DRY, + FMOD_DSP_CONVOLUTION_REVERB_PARAM_LINKED +} FMOD_DSP_CONVOLUTION_REVERB; + +typedef enum +{ + FMOD_DSP_CHANNELMIX_OUTPUT_DEFAULT, + FMOD_DSP_CHANNELMIX_OUTPUT_ALLMONO, + FMOD_DSP_CHANNELMIX_OUTPUT_ALLSTEREO, + FMOD_DSP_CHANNELMIX_OUTPUT_ALLQUAD, + FMOD_DSP_CHANNELMIX_OUTPUT_ALL5POINT1, + FMOD_DSP_CHANNELMIX_OUTPUT_ALL7POINT1, + FMOD_DSP_CHANNELMIX_OUTPUT_ALLLFE, + FMOD_DSP_CHANNELMIX_OUTPUT_ALL7POINT1POINT4 +} FMOD_DSP_CHANNELMIX_OUTPUT; + +typedef enum +{ + FMOD_DSP_CHANNELMIX_OUTPUTGROUPING, + FMOD_DSP_CHANNELMIX_GAIN_CH0, + FMOD_DSP_CHANNELMIX_GAIN_CH1, + FMOD_DSP_CHANNELMIX_GAIN_CH2, + FMOD_DSP_CHANNELMIX_GAIN_CH3, + FMOD_DSP_CHANNELMIX_GAIN_CH4, + FMOD_DSP_CHANNELMIX_GAIN_CH5, + FMOD_DSP_CHANNELMIX_GAIN_CH6, + FMOD_DSP_CHANNELMIX_GAIN_CH7, + FMOD_DSP_CHANNELMIX_GAIN_CH8, + FMOD_DSP_CHANNELMIX_GAIN_CH9, + FMOD_DSP_CHANNELMIX_GAIN_CH10, + FMOD_DSP_CHANNELMIX_GAIN_CH11, + FMOD_DSP_CHANNELMIX_GAIN_CH12, + FMOD_DSP_CHANNELMIX_GAIN_CH13, + FMOD_DSP_CHANNELMIX_GAIN_CH14, + FMOD_DSP_CHANNELMIX_GAIN_CH15, + FMOD_DSP_CHANNELMIX_GAIN_CH16, + FMOD_DSP_CHANNELMIX_GAIN_CH17, + FMOD_DSP_CHANNELMIX_GAIN_CH18, + FMOD_DSP_CHANNELMIX_GAIN_CH19, + FMOD_DSP_CHANNELMIX_GAIN_CH20, + FMOD_DSP_CHANNELMIX_GAIN_CH21, + FMOD_DSP_CHANNELMIX_GAIN_CH22, + FMOD_DSP_CHANNELMIX_GAIN_CH23, + FMOD_DSP_CHANNELMIX_GAIN_CH24, + FMOD_DSP_CHANNELMIX_GAIN_CH25, + FMOD_DSP_CHANNELMIX_GAIN_CH26, + FMOD_DSP_CHANNELMIX_GAIN_CH27, + FMOD_DSP_CHANNELMIX_GAIN_CH28, + FMOD_DSP_CHANNELMIX_GAIN_CH29, + FMOD_DSP_CHANNELMIX_GAIN_CH30, + FMOD_DSP_CHANNELMIX_GAIN_CH31, + FMOD_DSP_CHANNELMIX_OUTPUT_CH0, + FMOD_DSP_CHANNELMIX_OUTPUT_CH1, + FMOD_DSP_CHANNELMIX_OUTPUT_CH2, + FMOD_DSP_CHANNELMIX_OUTPUT_CH3, + FMOD_DSP_CHANNELMIX_OUTPUT_CH4, + FMOD_DSP_CHANNELMIX_OUTPUT_CH5, + FMOD_DSP_CHANNELMIX_OUTPUT_CH6, + FMOD_DSP_CHANNELMIX_OUTPUT_CH7, + FMOD_DSP_CHANNELMIX_OUTPUT_CH8, + FMOD_DSP_CHANNELMIX_OUTPUT_CH9, + FMOD_DSP_CHANNELMIX_OUTPUT_CH10, + FMOD_DSP_CHANNELMIX_OUTPUT_CH11, + FMOD_DSP_CHANNELMIX_OUTPUT_CH12, + FMOD_DSP_CHANNELMIX_OUTPUT_CH13, + FMOD_DSP_CHANNELMIX_OUTPUT_CH14, + FMOD_DSP_CHANNELMIX_OUTPUT_CH15, + FMOD_DSP_CHANNELMIX_OUTPUT_CH16, + FMOD_DSP_CHANNELMIX_OUTPUT_CH17, + FMOD_DSP_CHANNELMIX_OUTPUT_CH18, + FMOD_DSP_CHANNELMIX_OUTPUT_CH19, + FMOD_DSP_CHANNELMIX_OUTPUT_CH20, + FMOD_DSP_CHANNELMIX_OUTPUT_CH21, + FMOD_DSP_CHANNELMIX_OUTPUT_CH22, + FMOD_DSP_CHANNELMIX_OUTPUT_CH23, + FMOD_DSP_CHANNELMIX_OUTPUT_CH24, + FMOD_DSP_CHANNELMIX_OUTPUT_CH25, + FMOD_DSP_CHANNELMIX_OUTPUT_CH26, + FMOD_DSP_CHANNELMIX_OUTPUT_CH27, + FMOD_DSP_CHANNELMIX_OUTPUT_CH28, + FMOD_DSP_CHANNELMIX_OUTPUT_CH29, + FMOD_DSP_CHANNELMIX_OUTPUT_CH30, + FMOD_DSP_CHANNELMIX_OUTPUT_CH31 +} FMOD_DSP_CHANNELMIX; + +typedef enum +{ + FMOD_DSP_TRANSCEIVER_SPEAKERMODE_AUTO = -1, + FMOD_DSP_TRANSCEIVER_SPEAKERMODE_MONO = 0, + FMOD_DSP_TRANSCEIVER_SPEAKERMODE_STEREO, + FMOD_DSP_TRANSCEIVER_SPEAKERMODE_SURROUND, +} FMOD_DSP_TRANSCEIVER_SPEAKERMODE; + + +typedef enum +{ + FMOD_DSP_TRANSCEIVER_TRANSMIT, + FMOD_DSP_TRANSCEIVER_GAIN, + FMOD_DSP_TRANSCEIVER_CHANNEL, + FMOD_DSP_TRANSCEIVER_TRANSMITSPEAKERMODE +} FMOD_DSP_TRANSCEIVER; + + +typedef enum +{ + FMOD_DSP_OBJECTPAN_3D_POSITION, + FMOD_DSP_OBJECTPAN_3D_ROLLOFF, + FMOD_DSP_OBJECTPAN_3D_MIN_DISTANCE, + FMOD_DSP_OBJECTPAN_3D_MAX_DISTANCE, + FMOD_DSP_OBJECTPAN_3D_EXTENT_MODE, + FMOD_DSP_OBJECTPAN_3D_SOUND_SIZE, + FMOD_DSP_OBJECTPAN_3D_MIN_EXTENT, + FMOD_DSP_OBJECTPAN_OVERALL_GAIN, + FMOD_DSP_OBJECTPAN_OUTPUTGAIN, + FMOD_DSP_OBJECTPAN_ATTENUATION_RANGE, + FMOD_DSP_OBJECTPAN_OVERRIDE_RANGE +} FMOD_DSP_OBJECTPAN; + +#endif + diff --git a/FMOD/api/core/inc/fmod_errors.cs b/FMOD/api/core/inc/fmod_errors.cs new file mode 100644 index 0000000..fe27784 --- /dev/null +++ b/FMOD/api/core/inc/fmod_errors.cs @@ -0,0 +1,106 @@ +/* ============================================================================================== */ +/* FMOD Core / Studio API - Error string header file. */ +/* Copyright (c), Firelight Technologies Pty, Ltd. 2004-2026. */ +/* */ +/* Use this header if you want to store or display a string version / english explanation */ +/* of the FMOD error codes. */ +/* */ +/* For more detail visit: */ +/* https://fmod.com/docs/2.03/api/core-api-common.html#fmod_result */ +/* =============================================================================================== */ + +namespace FMOD +{ + public class Error + { + public static string String(FMOD.RESULT errcode) + { + switch (errcode) + { + case FMOD.RESULT.OK: return "No errors."; + case FMOD.RESULT.ERR_BADCOMMAND: return "Tried to call a function on a data type that does not allow this type of functionality (ie calling Sound::lock on a streaming sound)."; + case FMOD.RESULT.ERR_CHANNEL_ALLOC: return "Error trying to allocate a channel."; + case FMOD.RESULT.ERR_CHANNEL_STOLEN: return "The specified channel has been reused to play another sound."; + case FMOD.RESULT.ERR_DMA: return "DMA Failure. See debug output for more information."; + case FMOD.RESULT.ERR_DSP_CONNECTION: return "DSP connection error. Connection possibly caused a cyclic dependency or connected dsps with incompatible buffer counts."; + case FMOD.RESULT.ERR_DSP_DONTPROCESS: return "DSP return code from a DSP process query callback. Tells mixer not to call the process callback and therefore not consume CPU. Use this to optimize the DSP graph."; + case FMOD.RESULT.ERR_DSP_FORMAT: return "DSP Format error. A DSP unit may have attempted to connect to this network with the wrong format, or a matrix may have been set with the wrong size if the target unit has a specified channel map."; + case FMOD.RESULT.ERR_DSP_INUSE: return "DSP is already in the mixer's DSP network. It must be removed before being reinserted or released."; + case FMOD.RESULT.ERR_DSP_NOTFOUND: return "DSP connection error. Couldn't find the DSP unit specified."; + case FMOD.RESULT.ERR_DSP_RESERVED: return "DSP operation error. Cannot perform operation on this DSP as it is reserved by the system."; + case FMOD.RESULT.ERR_DSP_SILENCE: return "DSP return code from a DSP process query callback. Tells mixer silence would be produced from read, so go idle and not consume CPU. Use this to optimize the DSP graph."; + case FMOD.RESULT.ERR_DSP_TYPE: return "DSP operation cannot be performed on a DSP of this type."; + case FMOD.RESULT.ERR_FILE_BAD: return "Error loading file."; + case FMOD.RESULT.ERR_FILE_COULDNOTSEEK: return "Couldn't perform seek operation. This is a limitation of the medium (ie netstreams) or the file format."; + case FMOD.RESULT.ERR_FILE_DISKEJECTED: return "Media was ejected while reading."; + case FMOD.RESULT.ERR_FILE_EOF: return "End of file unexpectedly reached while trying to read essential data (truncated?)."; + case FMOD.RESULT.ERR_FILE_ENDOFDATA: return "End of current chunk reached while trying to read data."; + case FMOD.RESULT.ERR_FILE_NOTFOUND: return "File not found."; + case FMOD.RESULT.ERR_FORMAT: return "Unsupported file or audio format."; + case FMOD.RESULT.ERR_HEADER_MISMATCH: return "There is a version mismatch between the FMOD header and either the FMOD Studio library or the FMOD Low Level library."; + case FMOD.RESULT.ERR_HTTP: return "A HTTP error occurred. This is a catch-all for HTTP errors not listed elsewhere."; + case FMOD.RESULT.ERR_HTTP_ACCESS: return "The specified resource requires authentication or is forbidden."; + case FMOD.RESULT.ERR_HTTP_PROXY_AUTH: return "Proxy authentication is required to access the specified resource."; + case FMOD.RESULT.ERR_HTTP_SERVER_ERROR: return "A HTTP server error occurred."; + case FMOD.RESULT.ERR_HTTP_TIMEOUT: return "The HTTP request timed out."; + case FMOD.RESULT.ERR_INITIALIZATION: return "FMOD was not initialized correctly to support this function."; + case FMOD.RESULT.ERR_INITIALIZED: return "Cannot call this command after System::init."; + case FMOD.RESULT.ERR_INTERNAL: return "An error occured in the FMOD system. Use the logging version of FMOD for more information."; + case FMOD.RESULT.ERR_INVALID_FLOAT: return "Value passed in was a NaN, Inf or denormalized float."; + case FMOD.RESULT.ERR_INVALID_HANDLE: return "An invalid object handle was used."; + case FMOD.RESULT.ERR_INVALID_PARAM: return "An invalid parameter was passed to this function."; + case FMOD.RESULT.ERR_INVALID_POSITION: return "An invalid seek position was passed to this function."; + case FMOD.RESULT.ERR_INVALID_SPEAKER: return "An invalid speaker was passed to this function based on the current speaker mode."; + case FMOD.RESULT.ERR_INVALID_SYNCPOINT: return "The syncpoint did not come from this sound handle."; + case FMOD.RESULT.ERR_INVALID_THREAD: return "Tried to call a function on a thread that is not supported."; + case FMOD.RESULT.ERR_INVALID_VECTOR: return "The vectors passed in are not unit length, or perpendicular."; + case FMOD.RESULT.ERR_MAXAUDIBLE: return "Reached maximum audible playback count for this sound's soundgroup."; + case FMOD.RESULT.ERR_MEMORY: return "Not enough memory or resources."; + case FMOD.RESULT.ERR_MEMORY_CANTPOINT: return "Can't use FMOD_OPENMEMORY_POINT on non PCM source data, or non mp3/xma/adpcm data if FMOD_CREATECOMPRESSEDSAMPLE was used."; + case FMOD.RESULT.ERR_NEEDS3D: return "Tried to call a command on a 2d sound when the command was meant for 3d sound."; + case FMOD.RESULT.ERR_NEEDSHARDWARE: return "Tried to use a feature that requires hardware support."; + case FMOD.RESULT.ERR_NET_CONNECT: return "Couldn't connect to the specified host."; + case FMOD.RESULT.ERR_NET_SOCKET_ERROR: return "A socket error occurred. This is a catch-all for socket-related errors not listed elsewhere."; + case FMOD.RESULT.ERR_NET_URL: return "The specified URL couldn't be resolved."; + case FMOD.RESULT.ERR_NET_WOULD_BLOCK: return "Operation on a non-blocking socket could not complete immediately."; + case FMOD.RESULT.ERR_NOTREADY: return "Operation could not be performed because specified sound/DSP connection is not ready."; + case FMOD.RESULT.ERR_OUTPUT_ALLOCATED: return "Error initializing output device, but more specifically, the output device is already in use and cannot be reused."; + case FMOD.RESULT.ERR_OUTPUT_CREATEBUFFER: return "Error creating hardware sound buffer."; + case FMOD.RESULT.ERR_OUTPUT_DRIVERCALL: return "A call to a standard soundcard driver failed, which could possibly mean a bug in the driver or resources were missing or exhausted."; + case FMOD.RESULT.ERR_OUTPUT_FORMAT: return "Soundcard does not support the specified format."; + case FMOD.RESULT.ERR_OUTPUT_INIT: return "Error initializing output device."; + case FMOD.RESULT.ERR_OUTPUT_NODRIVERS: return "The output device has no drivers installed. If pre-init, FMOD_OUTPUT_NOSOUND is selected as the output mode. If post-init, the function just fails."; + case FMOD.RESULT.ERR_PLUGIN: return "An unspecified error has been returned from a plugin."; + case FMOD.RESULT.ERR_PLUGIN_MISSING: return "A requested output, dsp unit type or codec was not available."; + case FMOD.RESULT.ERR_PLUGIN_RESOURCE: return "A resource that the plugin requires cannot be allocated or found. (ie the DLS file for MIDI playback)"; + case FMOD.RESULT.ERR_PLUGIN_VERSION: return "A plugin was built with an unsupported SDK version."; + case FMOD.RESULT.ERR_RECORD: return "An error occurred trying to initialize the recording device."; + case FMOD.RESULT.ERR_REVERB_CHANNELGROUP: return "Reverb properties cannot be set on this channel because a parent channelgroup owns the reverb connection."; + case FMOD.RESULT.ERR_REVERB_INSTANCE: return "Specified instance in FMOD_REVERB_PROPERTIES couldn't be set. Most likely because it is an invalid instance number or the reverb doesn't exist."; + case FMOD.RESULT.ERR_SUBSOUNDS: return "The error occurred because the sound referenced contains subsounds when it shouldn't have, or it doesn't contain subsounds when it should have. The operation may also not be able to be performed on a parent sound."; + case FMOD.RESULT.ERR_SUBSOUND_ALLOCATED: return "This subsound is already being used by another sound, you cannot have more than one parent to a sound. Null out the other parent's entry first."; + case FMOD.RESULT.ERR_SUBSOUND_CANTMOVE: return "Shared subsounds cannot be replaced or moved from their parent stream, such as when the parent stream is an FSB file."; + case FMOD.RESULT.ERR_TAGNOTFOUND: return "The specified tag could not be found or there are no tags."; + case FMOD.RESULT.ERR_TOOMANYCHANNELS: return "The sound created exceeds the allowable input channel count. This can be increased using the 'maxinputchannels' parameter in System::setSoftwareFormat."; + case FMOD.RESULT.ERR_TRUNCATED: return "The retrieved string is too long to fit in the supplied buffer and has been truncated."; + case FMOD.RESULT.ERR_UNIMPLEMENTED: return "Something in FMOD hasn't been implemented when it should be. Contact support."; + case FMOD.RESULT.ERR_UNINITIALIZED: return "This command failed because System::init or System::setDriver was not called."; + case FMOD.RESULT.ERR_UNSUPPORTED: return "A command issued was not supported by this object. Possibly a plugin without certain callbacks specified."; + case FMOD.RESULT.ERR_VERSION: return "The version number of this file format is not supported."; + case FMOD.RESULT.ERR_EVENT_ALREADY_LOADED: return "The specified bank has already been loaded."; + case FMOD.RESULT.ERR_EVENT_LIVEUPDATE_BUSY: return "The live update connection failed due to the game already being connected."; + case FMOD.RESULT.ERR_EVENT_LIVEUPDATE_MISMATCH: return "The live update connection failed due to the game data being out of sync with the tool."; + case FMOD.RESULT.ERR_EVENT_LIVEUPDATE_TIMEOUT: return "The live update connection timed out."; + case FMOD.RESULT.ERR_EVENT_NOTFOUND: return "The requested event, bus or vca could not be found."; + case FMOD.RESULT.ERR_STUDIO_UNINITIALIZED: return "The Studio::System object is not yet initialized."; + case FMOD.RESULT.ERR_STUDIO_NOT_LOADED: return "The specified resource is not loaded, so it can't be unloaded."; + case FMOD.RESULT.ERR_INVALID_STRING: return "An invalid string was passed to this function."; + case FMOD.RESULT.ERR_ALREADY_LOCKED: return "The specified resource is already locked."; + case FMOD.RESULT.ERR_NOT_LOCKED: return "The specified resource is not locked, so it can't be unlocked."; + case FMOD.RESULT.ERR_RECORD_DISCONNECTED: return "The specified recording driver has been disconnected."; + case FMOD.RESULT.ERR_TOOMANYSAMPLES: return "The length provided exceed the allowable limit."; + default: return "Unknown error."; + } + } + } +} diff --git a/FMOD/api/core/inc/fmod_errors.h b/FMOD/api/core/inc/fmod_errors.h new file mode 100644 index 0000000..c745729 --- /dev/null +++ b/FMOD/api/core/inc/fmod_errors.h @@ -0,0 +1,110 @@ +/* ============================================================================================== */ +/* FMOD Core / Studio API - Error string header file. */ +/* Copyright (c), Firelight Technologies Pty, Ltd. 2004-2026. */ +/* */ +/* Use this header if you want to store or display a string version / english explanation */ +/* of the FMOD error codes. */ +/* */ +/* For more detail visit: */ +/* https://fmod.com/docs/2.03/api/core-api-common.html#fmod_result */ +/* =============================================================================================== */ +#ifndef _FMOD_ERRORS_H +#define _FMOD_ERRORS_H + +#include "fmod.h" + +#ifdef __GNUC__ +static const char *FMOD_ErrorString(FMOD_RESULT errcode) __attribute__((unused)); +#endif + +static const char *FMOD_ErrorString(FMOD_RESULT errcode) +{ + switch (errcode) + { + case FMOD_OK: return "No errors."; + case FMOD_ERR_BADCOMMAND: return "Tried to call a function on a data type that does not allow this type of functionality (ie calling Sound::lock on a streaming sound)."; + case FMOD_ERR_CHANNEL_ALLOC: return "Error trying to allocate a channel."; + case FMOD_ERR_CHANNEL_STOLEN: return "The specified channel has been reused to play another sound."; + case FMOD_ERR_DMA: return "DMA Failure. See debug output for more information."; + case FMOD_ERR_DSP_CONNECTION: return "DSP connection error. Connection possibly caused a cyclic dependency or connected dsps with incompatible buffer counts."; + case FMOD_ERR_DSP_DONTPROCESS: return "DSP return code from a DSP process query callback. Tells mixer not to call the process callback and therefore not consume CPU. Use this to optimize the DSP graph."; + case FMOD_ERR_DSP_FORMAT: return "DSP Format error. A DSP unit may have attempted to connect to this network with the wrong format, or a matrix may have been set with the wrong size if the target unit has a specified channel map."; + case FMOD_ERR_DSP_INUSE: return "DSP is already in the mixer's DSP network. It must be removed before being reinserted or released."; + case FMOD_ERR_DSP_NOTFOUND: return "DSP connection error. Couldn't find the DSP unit specified."; + case FMOD_ERR_DSP_RESERVED: return "DSP operation error. Cannot perform operation on this DSP as it is reserved by the system."; + case FMOD_ERR_DSP_SILENCE: return "DSP return code from a DSP process query callback. Tells mixer silence would be produced from read, so go idle and not consume CPU. Use this to optimize the DSP graph."; + case FMOD_ERR_DSP_TYPE: return "DSP operation cannot be performed on a DSP of this type."; + case FMOD_ERR_FILE_BAD: return "Error loading file."; + case FMOD_ERR_FILE_COULDNOTSEEK: return "Couldn't perform seek operation. This is a limitation of the medium (ie netstreams) or the file format."; + case FMOD_ERR_FILE_DISKEJECTED: return "Media was ejected while reading."; + case FMOD_ERR_FILE_EOF: return "End of file unexpectedly reached while trying to read essential data (truncated?)."; + case FMOD_ERR_FILE_ENDOFDATA: return "End of current chunk reached while trying to read data."; + case FMOD_ERR_FILE_NOTFOUND: return "File not found."; + case FMOD_ERR_FORMAT: return "Unsupported file or audio format."; + case FMOD_ERR_HEADER_MISMATCH: return "There is a version mismatch between the FMOD header and either the FMOD Studio library or the FMOD Low Level library."; + case FMOD_ERR_HTTP: return "A HTTP error occurred. This is a catch-all for HTTP errors not listed elsewhere."; + case FMOD_ERR_HTTP_ACCESS: return "The specified resource requires authentication or is forbidden."; + case FMOD_ERR_HTTP_PROXY_AUTH: return "Proxy authentication is required to access the specified resource."; + case FMOD_ERR_HTTP_SERVER_ERROR: return "A HTTP server error occurred."; + case FMOD_ERR_HTTP_TIMEOUT: return "The HTTP request timed out."; + case FMOD_ERR_INITIALIZATION: return "FMOD was not initialized correctly to support this function."; + case FMOD_ERR_INITIALIZED: return "Cannot call this command after System::init."; + case FMOD_ERR_INTERNAL: return "An error occured in the FMOD system. Use the logging version of FMOD for more information."; + case FMOD_ERR_INVALID_FLOAT: return "Value passed in was a NaN, Inf or denormalized float."; + case FMOD_ERR_INVALID_HANDLE: return "An invalid object handle was used."; + case FMOD_ERR_INVALID_PARAM: return "An invalid parameter was passed to this function."; + case FMOD_ERR_INVALID_POSITION: return "An invalid seek position was passed to this function."; + case FMOD_ERR_INVALID_SPEAKER: return "An invalid speaker was passed to this function based on the current speaker mode."; + case FMOD_ERR_INVALID_SYNCPOINT: return "The syncpoint did not come from this sound handle."; + case FMOD_ERR_INVALID_THREAD: return "Tried to call a function on a thread that is not supported."; + case FMOD_ERR_INVALID_VECTOR: return "The vectors passed in are not unit length, or perpendicular."; + case FMOD_ERR_MAXAUDIBLE: return "Reached maximum audible playback count for this sound's soundgroup."; + case FMOD_ERR_MEMORY: return "Not enough memory or resources."; + case FMOD_ERR_MEMORY_CANTPOINT: return "Can't use FMOD_OPENMEMORY_POINT on non PCM source data, or non mp3/xma/adpcm data if FMOD_CREATECOMPRESSEDSAMPLE was used."; + case FMOD_ERR_NEEDS3D: return "Tried to call a command on a 2d sound when the command was meant for 3d sound."; + case FMOD_ERR_NEEDSHARDWARE: return "Tried to use a feature that requires hardware support."; + case FMOD_ERR_NET_CONNECT: return "Couldn't connect to the specified host."; + case FMOD_ERR_NET_SOCKET_ERROR: return "A socket error occurred. This is a catch-all for socket-related errors not listed elsewhere."; + case FMOD_ERR_NET_URL: return "The specified URL couldn't be resolved."; + case FMOD_ERR_NET_WOULD_BLOCK: return "Operation on a non-blocking socket could not complete immediately."; + case FMOD_ERR_NOTREADY: return "Operation could not be performed because specified sound/DSP connection is not ready."; + case FMOD_ERR_OUTPUT_ALLOCATED: return "Error initializing output device, but more specifically, the output device is already in use and cannot be reused."; + case FMOD_ERR_OUTPUT_CREATEBUFFER: return "Error creating hardware sound buffer."; + case FMOD_ERR_OUTPUT_DRIVERCALL: return "A call to a standard soundcard driver failed, which could possibly mean a bug in the driver or resources were missing or exhausted."; + case FMOD_ERR_OUTPUT_FORMAT: return "Soundcard does not support the specified format."; + case FMOD_ERR_OUTPUT_INIT: return "Error initializing output device."; + case FMOD_ERR_OUTPUT_NODRIVERS: return "The output device has no drivers installed. If pre-init, FMOD_OUTPUT_NOSOUND is selected as the output mode. If post-init, the function just fails."; + case FMOD_ERR_PLUGIN: return "An unspecified error has been returned from a plugin."; + case FMOD_ERR_PLUGIN_MISSING: return "A requested output, dsp unit type or codec was not available."; + case FMOD_ERR_PLUGIN_RESOURCE: return "A resource that the plugin requires cannot be allocated or found. (ie the DLS file for MIDI playback)"; + case FMOD_ERR_PLUGIN_VERSION: return "A plugin was built with an unsupported SDK version."; + case FMOD_ERR_RECORD: return "An error occurred trying to initialize the recording device."; + case FMOD_ERR_REVERB_CHANNELGROUP: return "Reverb properties cannot be set on this channel because a parent channelgroup owns the reverb connection."; + case FMOD_ERR_REVERB_INSTANCE: return "Specified instance in FMOD_REVERB_PROPERTIES couldn't be set. Most likely because it is an invalid instance number or the reverb doesn't exist."; + case FMOD_ERR_SUBSOUNDS: return "The error occurred because the sound referenced contains subsounds when it shouldn't have, or it doesn't contain subsounds when it should have. The operation may also not be able to be performed on a parent sound."; + case FMOD_ERR_SUBSOUND_ALLOCATED: return "This subsound is already being used by another sound, you cannot have more than one parent to a sound. Null out the other parent's entry first."; + case FMOD_ERR_SUBSOUND_CANTMOVE: return "Shared subsounds cannot be replaced or moved from their parent stream, such as when the parent stream is an FSB file."; + case FMOD_ERR_TAGNOTFOUND: return "The specified tag could not be found or there are no tags."; + case FMOD_ERR_TOOMANYCHANNELS: return "The sound created exceeds the allowable input channel count. This can be increased using the 'maxinputchannels' parameter in System::setSoftwareFormat."; + case FMOD_ERR_TRUNCATED: return "The retrieved string is too long to fit in the supplied buffer and has been truncated."; + case FMOD_ERR_UNIMPLEMENTED: return "Something in FMOD hasn't been implemented when it should be. Contact support."; + case FMOD_ERR_UNINITIALIZED: return "This command failed because System::init or System::setDriver was not called."; + case FMOD_ERR_UNSUPPORTED: return "A command issued was not supported by this object. Possibly a plugin without certain callbacks specified."; + case FMOD_ERR_VERSION: return "The version number of this file format is not supported."; + case FMOD_ERR_EVENT_ALREADY_LOADED: return "The specified bank has already been loaded."; + case FMOD_ERR_EVENT_LIVEUPDATE_BUSY: return "The live update connection failed due to the game already being connected."; + case FMOD_ERR_EVENT_LIVEUPDATE_MISMATCH: return "The live update connection failed due to the game data being out of sync with the tool."; + case FMOD_ERR_EVENT_LIVEUPDATE_TIMEOUT: return "The live update connection timed out."; + case FMOD_ERR_EVENT_NOTFOUND: return "The requested event, parameter, bus or vca could not be found."; + case FMOD_ERR_STUDIO_UNINITIALIZED: return "The Studio::System object is not yet initialized."; + case FMOD_ERR_STUDIO_NOT_LOADED: return "The specified resource is not loaded, so it can't be unloaded."; + case FMOD_ERR_INVALID_STRING: return "An invalid string was passed to this function."; + case FMOD_ERR_ALREADY_LOCKED: return "The specified resource is already locked."; + case FMOD_ERR_NOT_LOCKED: return "The specified resource is not locked, so it can't be unlocked."; + case FMOD_ERR_RECORD_DISCONNECTED: return "The specified recording driver has been disconnected."; + case FMOD_ERR_TOOMANYSAMPLES: return "The length provided exceeds the allowable limit."; + default : return "Unknown error."; + }; +} + +#endif diff --git a/FMOD/api/core/inc/fmod_output.h b/FMOD/api/core/inc/fmod_output.h new file mode 100644 index 0000000..6c8e91d --- /dev/null +++ b/FMOD/api/core/inc/fmod_output.h @@ -0,0 +1,122 @@ +/* ======================================================================================== */ +/* FMOD Core API - output development header file. */ +/* Copyright (c), Firelight Technologies Pty, Ltd. 2004-2026. */ +/* */ +/* Use this header if you are wanting to develop your own output plugin to use with */ +/* FMOD's output system. With this header you can make your own output plugin that FMOD */ +/* can register and use. See the documentation and examples on how to make a working */ +/* plugin. */ +/* */ +/* For more detail visit: */ +/* https://fmod.com/docs/2.03/api/plugin-api-output.html */ +/* ======================================================================================== */ +#ifndef _FMOD_OUTPUT_H +#define _FMOD_OUTPUT_H + +typedef struct FMOD_OUTPUT_STATE FMOD_OUTPUT_STATE; +typedef struct FMOD_OUTPUT_OBJECT3DINFO FMOD_OUTPUT_OBJECT3DINFO; + +/* + Output constants +*/ +#define FMOD_OUTPUT_PLUGIN_VERSION 5 + +typedef unsigned int FMOD_OUTPUT_METHOD; +#define FMOD_OUTPUT_METHOD_MIX_DIRECT 0 +#define FMOD_OUTPUT_METHOD_MIX_BUFFERED 1 + +/* + Output callbacks +*/ +typedef FMOD_RESULT (F_CALL *FMOD_OUTPUT_GETNUMDRIVERS_CALLBACK) (FMOD_OUTPUT_STATE *output_state, int *numdrivers); +typedef FMOD_RESULT (F_CALL *FMOD_OUTPUT_GETDRIVERINFO_CALLBACK) (FMOD_OUTPUT_STATE *output_state, int id, char *name, int namelen, FMOD_GUID *guid, int *systemrate, FMOD_SPEAKERMODE *speakermode, int *speakermodechannels); +typedef FMOD_RESULT (F_CALL *FMOD_OUTPUT_INIT_CALLBACK) (FMOD_OUTPUT_STATE *output_state, int selecteddriver, FMOD_INITFLAGS flags, int *outputrate, FMOD_SPEAKERMODE *speakermode, int *speakermodechannels, FMOD_SOUND_FORMAT *outputformat, int dspbufferlength, int *dspnumbuffers, int *dspnumadditionalbuffers, void *extradriverdata); +typedef FMOD_RESULT (F_CALL *FMOD_OUTPUT_START_CALLBACK) (FMOD_OUTPUT_STATE *output_state); +typedef FMOD_RESULT (F_CALL *FMOD_OUTPUT_STOP_CALLBACK) (FMOD_OUTPUT_STATE *output_state); +typedef FMOD_RESULT (F_CALL *FMOD_OUTPUT_CLOSE_CALLBACK) (FMOD_OUTPUT_STATE *output_state); +typedef FMOD_RESULT (F_CALL *FMOD_OUTPUT_UPDATE_CALLBACK) (FMOD_OUTPUT_STATE *output_state); +typedef FMOD_RESULT (F_CALL *FMOD_OUTPUT_GETHANDLE_CALLBACK) (FMOD_OUTPUT_STATE *output_state, void **handle); +typedef FMOD_RESULT (F_CALL *FMOD_OUTPUT_MIXER_CALLBACK) (FMOD_OUTPUT_STATE *output_state); +typedef FMOD_RESULT (F_CALL *FMOD_OUTPUT_OBJECT3DGETINFO_CALLBACK) (FMOD_OUTPUT_STATE *output_state, int *maxhardwareobjects); +typedef FMOD_RESULT (F_CALL *FMOD_OUTPUT_OBJECT3DALLOC_CALLBACK) (FMOD_OUTPUT_STATE *output_state, void **object3d); +typedef FMOD_RESULT (F_CALL *FMOD_OUTPUT_OBJECT3DFREE_CALLBACK) (FMOD_OUTPUT_STATE *output_state, void *object3d); +typedef FMOD_RESULT (F_CALL *FMOD_OUTPUT_OBJECT3DUPDATE_CALLBACK) (FMOD_OUTPUT_STATE *output_state, void *object3d, const FMOD_OUTPUT_OBJECT3DINFO *info); +typedef FMOD_RESULT (F_CALL *FMOD_OUTPUT_OPENPORT_CALLBACK) (FMOD_OUTPUT_STATE *output_state, FMOD_PORT_TYPE portType, FMOD_PORT_INDEX portIndex, int *portId, int *portRate, int *portChannels, FMOD_SOUND_FORMAT *portFormat); +typedef FMOD_RESULT (F_CALL *FMOD_OUTPUT_CLOSEPORT_CALLBACK) (FMOD_OUTPUT_STATE *output_state, int portId); +typedef FMOD_RESULT (F_CALL *FMOD_OUTPUT_DEVICELISTCHANGED_CALLBACK)(FMOD_OUTPUT_STATE *output_state); + +/* + Output functions +*/ +typedef FMOD_RESULT (F_CALL *FMOD_OUTPUT_READFROMMIXER_FUNC) (FMOD_OUTPUT_STATE *output_state, void *buffer, unsigned int length); +typedef FMOD_RESULT (F_CALL *FMOD_OUTPUT_COPYPORT_FUNC) (FMOD_OUTPUT_STATE *output_state, int portId, void *buffer, unsigned int length); +typedef FMOD_RESULT (F_CALL *FMOD_OUTPUT_REQUESTRESET_FUNC) (FMOD_OUTPUT_STATE *output_state); +typedef void * (F_CALL *FMOD_OUTPUT_ALLOC_FUNC) (unsigned int size, unsigned int align, const char *file, int line); +typedef void (F_CALL *FMOD_OUTPUT_FREE_FUNC) (void *ptr, const char *file, int line); +typedef void (F_CALL *FMOD_OUTPUT_LOG_FUNC) (FMOD_DEBUG_FLAGS level, const char *file, int line, const char *function, const char *string, ...); + +/* + Output structures +*/ +typedef struct FMOD_OUTPUT_DESCRIPTION +{ + unsigned int apiversion; + const char *name; + unsigned int version; + FMOD_OUTPUT_METHOD method; + FMOD_OUTPUT_GETNUMDRIVERS_CALLBACK getnumdrivers; + FMOD_OUTPUT_GETDRIVERINFO_CALLBACK getdriverinfo; + FMOD_OUTPUT_INIT_CALLBACK init; + FMOD_OUTPUT_START_CALLBACK start; + FMOD_OUTPUT_STOP_CALLBACK stop; + FMOD_OUTPUT_CLOSE_CALLBACK close; + FMOD_OUTPUT_UPDATE_CALLBACK update; + FMOD_OUTPUT_GETHANDLE_CALLBACK gethandle; + FMOD_OUTPUT_MIXER_CALLBACK mixer; + FMOD_OUTPUT_OBJECT3DGETINFO_CALLBACK object3dgetinfo; + FMOD_OUTPUT_OBJECT3DALLOC_CALLBACK object3dalloc; + FMOD_OUTPUT_OBJECT3DFREE_CALLBACK object3dfree; + FMOD_OUTPUT_OBJECT3DUPDATE_CALLBACK object3dupdate; + FMOD_OUTPUT_OPENPORT_CALLBACK openport; + FMOD_OUTPUT_CLOSEPORT_CALLBACK closeport; + FMOD_OUTPUT_DEVICELISTCHANGED_CALLBACK devicelistchanged; +} FMOD_OUTPUT_DESCRIPTION; + +struct FMOD_OUTPUT_STATE +{ + void *plugindata; + FMOD_OUTPUT_READFROMMIXER_FUNC readfrommixer; + FMOD_OUTPUT_ALLOC_FUNC alloc; + FMOD_OUTPUT_FREE_FUNC free; + FMOD_OUTPUT_LOG_FUNC log; + FMOD_OUTPUT_COPYPORT_FUNC copyport; + FMOD_OUTPUT_REQUESTRESET_FUNC requestreset; +}; + +struct FMOD_OUTPUT_OBJECT3DINFO +{ + float *buffer; + unsigned int bufferlength; + FMOD_VECTOR position; + float gain; + float spread; + float priority; +}; + +/* + Output macros +*/ +#define FMOD_OUTPUT_READFROMMIXER(_state, _buffer, _length) \ + (_state)->readfrommixer(_state, _buffer, _length) +#define FMOD_OUTPUT_ALLOC(_state, _size, _align) \ + (_state)->alloc(_size, _align, __FILE__, __LINE__) +#define FMOD_OUTPUT_FREE(_state, _ptr) \ + (_state)->free(_ptr, __FILE__, __LINE__) +#define FMOD_OUTPUT_LOG(_state, _level, _location, _format, ...) \ + (_state)->log(_level, __FILE__, __LINE__, _location, _format, ##__VA_ARGS__) +#define FMOD_OUTPUT_COPYPORT(_state, _id, _buffer, _length) \ + (_state)->copyport(_state, _id, _buffer, _length) +#define FMOD_OUTPUT_REQUESTRESET(_state) \ + (_state)->requestreset(_state) + +#endif /* _FMOD_OUTPUT_H */ diff --git a/FMOD/api/core/lib/arm64/fmod.dll b/FMOD/api/core/lib/arm64/fmod.dll new file mode 100644 index 0000000..af9fc20 Binary files /dev/null and b/FMOD/api/core/lib/arm64/fmod.dll differ diff --git a/FMOD/api/core/lib/arm64/fmodL.dll b/FMOD/api/core/lib/arm64/fmodL.dll new file mode 100644 index 0000000..e794340 Binary files /dev/null and b/FMOD/api/core/lib/arm64/fmodL.dll differ diff --git a/FMOD/api/core/lib/arm64/fmodL_vc.lib b/FMOD/api/core/lib/arm64/fmodL_vc.lib new file mode 100644 index 0000000..15f9413 Binary files /dev/null and b/FMOD/api/core/lib/arm64/fmodL_vc.lib differ diff --git a/FMOD/api/core/lib/arm64/fmod_vc.lib b/FMOD/api/core/lib/arm64/fmod_vc.lib new file mode 100644 index 0000000..d1a42b8 Binary files /dev/null and b/FMOD/api/core/lib/arm64/fmod_vc.lib differ diff --git a/FMOD/api/core/lib/x64/fmod.dll b/FMOD/api/core/lib/x64/fmod.dll new file mode 100644 index 0000000..3612a9a Binary files /dev/null and b/FMOD/api/core/lib/x64/fmod.dll differ diff --git a/FMOD/api/core/lib/x64/fmodL.dll b/FMOD/api/core/lib/x64/fmodL.dll new file mode 100644 index 0000000..b70bfab Binary files /dev/null and b/FMOD/api/core/lib/x64/fmodL.dll differ diff --git a/FMOD/api/core/lib/x64/fmodL_vc.lib b/FMOD/api/core/lib/x64/fmodL_vc.lib new file mode 100644 index 0000000..01b367d Binary files /dev/null and b/FMOD/api/core/lib/x64/fmodL_vc.lib differ diff --git a/FMOD/api/core/lib/x64/fmod_vc.lib b/FMOD/api/core/lib/x64/fmod_vc.lib new file mode 100644 index 0000000..7f57d53 Binary files /dev/null and b/FMOD/api/core/lib/x64/fmod_vc.lib differ diff --git a/FMOD/api/core/lib/x86/fmod.dll b/FMOD/api/core/lib/x86/fmod.dll new file mode 100644 index 0000000..2ed6c15 Binary files /dev/null and b/FMOD/api/core/lib/x86/fmod.dll differ diff --git a/FMOD/api/core/lib/x86/fmodL.dll b/FMOD/api/core/lib/x86/fmodL.dll new file mode 100644 index 0000000..a1a2ef3 Binary files /dev/null and b/FMOD/api/core/lib/x86/fmodL.dll differ diff --git a/FMOD/api/core/lib/x86/fmodL_vc.lib b/FMOD/api/core/lib/x86/fmodL_vc.lib new file mode 100644 index 0000000..302319b Binary files /dev/null and b/FMOD/api/core/lib/x86/fmodL_vc.lib differ diff --git a/FMOD/api/core/lib/x86/fmod_vc.lib b/FMOD/api/core/lib/x86/fmod_vc.lib new file mode 100644 index 0000000..0d074ad Binary files /dev/null and b/FMOD/api/core/lib/x86/fmod_vc.lib differ diff --git a/FMOD/api/core/lib/x86/libfmod.a b/FMOD/api/core/lib/x86/libfmod.a new file mode 100644 index 0000000..aeddb47 Binary files /dev/null and b/FMOD/api/core/lib/x86/libfmod.a differ diff --git a/FMOD/api/core/lib/x86/libfmodL.a b/FMOD/api/core/lib/x86/libfmodL.a new file mode 100644 index 0000000..f82b071 Binary files /dev/null and b/FMOD/api/core/lib/x86/libfmodL.a differ diff --git a/FMOD/api/fsbank/inc/fsbank.h b/FMOD/api/fsbank/inc/fsbank.h new file mode 100644 index 0000000..6340365 --- /dev/null +++ b/FMOD/api/fsbank/inc/fsbank.h @@ -0,0 +1,158 @@ +#ifndef _FSBANK_H +#define _FSBANK_H + +#if defined(_WIN32) + #define FB_EXPORT __declspec(dllexport) + #define FB_CALL __stdcall +#else + #define FB_EXPORT __attribute__((visibility("default"))) + #define FB_CALL +#endif + +#if defined(DLL_EXPORTS) + #define FB_API FB_EXPORT FB_CALL +#else + #define FB_API FB_CALL +#endif + +/* + FSBank types +*/ +typedef unsigned int FSBANK_INITFLAGS; +typedef unsigned int FSBANK_BUILDFLAGS; + +#define FSBANK_INIT_NORMAL 0x00000000 +#define FSBANK_INIT_IGNOREERRORS 0x00000001 +#define FSBANK_INIT_WARNINGSASERRORS 0x00000002 +#define FSBANK_INIT_CREATEINCLUDEHEADER 0x00000004 +#define FSBANK_INIT_DONTLOADCACHEFILES 0x00000008 +#define FSBANK_INIT_GENERATEPROGRESSITEMS 0x00000010 + +#define FSBANK_BUILD_DEFAULT 0x00000000 +#define FSBANK_BUILD_DISABLESYNCPOINTS 0x00000001 +#define FSBANK_BUILD_DONTLOOP 0x00000002 +#define FSBANK_BUILD_FILTERHIGHFREQ 0x00000004 +#define FSBANK_BUILD_DISABLESEEKING 0x00000008 +#define FSBANK_BUILD_OPTIMIZESAMPLERATE 0x00000010 +#define FSBANK_BUILD_FSB5_DONTWRITENAMES 0x00000080 +#define FSBANK_BUILD_NOGUID 0x00000100 +#define FSBANK_BUILD_WRITEPEAKVOLUME 0x00000200 +#define FSBANK_BUILD_ALIGN4K 0x00000400 + +#define FSBANK_BUILD_OVERRIDE_MASK (FSBANK_BUILD_DISABLESYNCPOINTS | FSBANK_BUILD_DONTLOOP | FSBANK_BUILD_FILTERHIGHFREQ | FSBANK_BUILD_DISABLESEEKING | FSBANK_BUILD_OPTIMIZESAMPLERATE | FSBANK_BUILD_WRITEPEAKVOLUME) +#define FSBANK_BUILD_CACHE_VALIDATION_MASK (FSBANK_BUILD_DONTLOOP | FSBANK_BUILD_FILTERHIGHFREQ | FSBANK_BUILD_OPTIMIZESAMPLERATE) + +typedef enum FSBANK_RESULT +{ + FSBANK_OK, + FSBANK_ERR_CACHE_CHUNKNOTFOUND, + FSBANK_ERR_CANCELLED, + FSBANK_ERR_CANNOT_CONTINUE, + FSBANK_ERR_ENCODER, + FSBANK_ERR_ENCODER_INIT, + FSBANK_ERR_ENCODER_NOTSUPPORTED, + FSBANK_ERR_FILE_OS, + FSBANK_ERR_FILE_NOTFOUND, + FSBANK_ERR_FMOD, + FSBANK_ERR_INITIALIZED, + FSBANK_ERR_INVALID_FORMAT, + FSBANK_ERR_INVALID_PARAM, + FSBANK_ERR_MEMORY, + FSBANK_ERR_UNINITIALIZED, + FSBANK_ERR_WRITER_FORMAT, + FSBANK_WARN_CANNOTLOOP, + FSBANK_WARN_IGNORED_FILTERHIGHFREQ, + FSBANK_WARN_IGNORED_DISABLESEEKING, + FSBANK_WARN_FORCED_DONTWRITENAMES, + FSBANK_ERR_ENCODER_FILE_NOTFOUND, + FSBANK_ERR_ENCODER_FILE_BAD, + FSBANK_WARN_IGNORED_ALIGN4K, +} FSBANK_RESULT; + +typedef enum FSBANK_FORMAT +{ + FSBANK_FORMAT_PCM, + FSBANK_FORMAT_XMA, + FSBANK_FORMAT_AT9, + FSBANK_FORMAT_VORBIS, + FSBANK_FORMAT_FADPCM, + FSBANK_FORMAT_OPUS, + + FSBANK_FORMAT_MAX +} FSBANK_FORMAT; + +typedef enum FSBANK_FSBVERSION +{ + FSBANK_FSBVERSION_FSB5, + + FSBANK_FSBVERSION_MAX +} FSBANK_FSBVERSION; + +typedef enum FSBANK_STATE +{ + FSBANK_STATE_DECODING, + FSBANK_STATE_ANALYSING, + FSBANK_STATE_PREPROCESSING, + FSBANK_STATE_ENCODING, + FSBANK_STATE_WRITING, + FSBANK_STATE_FINISHED, + FSBANK_STATE_FAILED, + FSBANK_STATE_WARNING, +} FSBANK_STATE; + +typedef struct FSBANK_SUBSOUND +{ + const char* const *fileNames; + const void* const *fileData; + const unsigned int *fileDataLengths; + unsigned int numFiles; + FSBANK_BUILDFLAGS overrideFlags; + unsigned int overrideQuality; + float desiredSampleRate; + float percentOptimizedRate; +} FSBANK_SUBSOUND; + +typedef struct FSBANK_PROGRESSITEM +{ + int subSoundIndex; + int threadIndex; + FSBANK_STATE state; + const void *stateData; +} FSBANK_PROGRESSITEM; + +typedef struct FSBANK_STATEDATA_FAILED +{ + FSBANK_RESULT errorCode; + char errorString[256]; +} FSBANK_STATEDATA_FAILED; + +typedef struct FSBANK_STATEDATA_WARNING +{ + FSBANK_RESULT warnCode; + char warningString[256]; +} FSBANK_STATEDATA_WARNING; + + +#ifdef __cplusplus +extern "C" { +#endif + +typedef void* (FB_CALL *FSBANK_MEMORY_ALLOC_CALLBACK)(unsigned int size, unsigned int type, const char *sourceStr); +typedef void* (FB_CALL *FSBANK_MEMORY_REALLOC_CALLBACK)(void *ptr, unsigned int size, unsigned int type, const char *sourceStr); +typedef void (FB_CALL *FSBANK_MEMORY_FREE_CALLBACK)(void *ptr, unsigned int type, const char *sourceStr); + +FSBANK_RESULT FB_API FSBank_MemoryInit(FSBANK_MEMORY_ALLOC_CALLBACK userAlloc, FSBANK_MEMORY_REALLOC_CALLBACK userRealloc, FSBANK_MEMORY_FREE_CALLBACK userFree); +FSBANK_RESULT FB_API FSBank_Init(FSBANK_FSBVERSION version, FSBANK_INITFLAGS flags, unsigned int numSimultaneousJobs, const char *cacheDirectory); +FSBANK_RESULT FB_API FSBank_Release(); +FSBANK_RESULT FB_API FSBank_Build(const FSBANK_SUBSOUND *subSounds, unsigned int numSubSounds, FSBANK_FORMAT encodeFormat, FSBANK_BUILDFLAGS buildFlags, unsigned int quality, const char *encryptKey, const char *outputFileName); +FSBANK_RESULT FB_API FSBank_FetchFSBMemory(const void **data, unsigned int *length); +FSBANK_RESULT FB_API FSBank_BuildCancel(); +FSBANK_RESULT FB_API FSBank_FetchNextProgressItem(const FSBANK_PROGRESSITEM **progressItem); +FSBANK_RESULT FB_API FSBank_ReleaseProgressItem(const FSBANK_PROGRESSITEM *progressItem); +FSBANK_RESULT FB_API FSBank_MemoryGetStats(unsigned int *currentAllocated, unsigned int *maximumAllocated); + +#ifdef __cplusplus +} +#endif + +#endif // _FSBANK_H diff --git a/FMOD/api/fsbank/inc/fsbank_errors.h b/FMOD/api/fsbank/inc/fsbank_errors.h new file mode 100644 index 0000000..d9ec5c3 --- /dev/null +++ b/FMOD/api/fsbank/inc/fsbank_errors.h @@ -0,0 +1,35 @@ +#pragma once + +#include "fsbank.h" + +static const char *FSBank_ErrorString(FSBANK_RESULT result) +{ + switch (result) + { + case FSBANK_OK: return "No errors."; + case FSBANK_ERR_CACHE_CHUNKNOTFOUND: return "An expected chunk is missing from the cache, perhaps try deleting cache files."; + case FSBANK_ERR_CANCELLED: return "The build process was cancelled during compilation by the user."; + case FSBANK_ERR_CANNOT_CONTINUE: return "The build process cannot continue due to previously ignored errors."; + case FSBANK_ERR_ENCODER: return "Encoder for chosen format has encountered an unexpected error."; + case FSBANK_ERR_ENCODER_INIT: return "Encoder initialization failed."; + case FSBANK_ERR_ENCODER_NOTSUPPORTED: return "Encoder for chosen format is not supported on this platform."; + case FSBANK_ERR_FILE_OS: return "An operating system based file error was encountered."; + case FSBANK_ERR_FILE_NOTFOUND: return "A specified file could not be found."; + case FSBANK_ERR_FMOD: return "Internal error from FMOD sub-system."; + case FSBANK_ERR_INITIALIZED: return "Already initialized."; + case FSBANK_ERR_INVALID_FORMAT: return "The format of the source file is invalid."; + case FSBANK_ERR_INVALID_PARAM: return "An invalid parameter has been passed to this function."; + case FSBANK_ERR_MEMORY: return "Run out of memory."; + case FSBANK_ERR_UNINITIALIZED: return "Not initialized yet."; + case FSBANK_ERR_WRITER_FORMAT: return "Chosen encode format is not supported by this FSB version."; + case FSBANK_WARN_CANNOTLOOP: return "Source file is too short for seamless looping. Looping disabled."; + case FSBANK_WARN_IGNORED_FILTERHIGHFREQ: return "FSBANK_BUILD_FILTERHIGHFREQ flag ignored: feature only supported by XMA format."; + case FSBANK_WARN_IGNORED_DISABLESEEKING: return "FSBANK_BUILD_DISABLESEEKING flag ignored: feature only supported by XMA format."; + case FSBANK_WARN_FORCED_DONTWRITENAMES: return "FSBANK_BUILD_FSB5_DONTWRITENAMES flag forced: cannot write names when source is from memory."; + case FSBANK_ERR_ENCODER_FILE_NOTFOUND: return "External encoder dynamic library not found."; + case FSBANK_ERR_ENCODER_FILE_BAD: return "External encoder dynamic library could not be loaded, possibly incorrect binary format, incorrect architecture, or file corruption."; + case FSBANK_WARN_IGNORED_ALIGN4K: return "FSBANK_BUILD_ALIGN4K flag ignored: feature only supported by Opus, Vorbis, and FADPCM formats."; + default: return "Unknown error."; + } +} + diff --git a/FMOD/api/fsbank/lib/x64/fsbank.dll b/FMOD/api/fsbank/lib/x64/fsbank.dll new file mode 100644 index 0000000..612b155 Binary files /dev/null and b/FMOD/api/fsbank/lib/x64/fsbank.dll differ diff --git a/FMOD/api/fsbank/lib/x64/fsbank_vc.lib b/FMOD/api/fsbank/lib/x64/fsbank_vc.lib new file mode 100644 index 0000000..70e2668 Binary files /dev/null and b/FMOD/api/fsbank/lib/x64/fsbank_vc.lib differ diff --git a/FMOD/api/fsbank/lib/x64/libfsbvorbis64.dll b/FMOD/api/fsbank/lib/x64/libfsbvorbis64.dll new file mode 100644 index 0000000..d42acbb Binary files /dev/null and b/FMOD/api/fsbank/lib/x64/libfsbvorbis64.dll differ diff --git a/FMOD/api/fsbank/lib/x64/opus.dll b/FMOD/api/fsbank/lib/x64/opus.dll new file mode 100644 index 0000000..f23c981 Binary files /dev/null and b/FMOD/api/fsbank/lib/x64/opus.dll differ diff --git a/FMOD/api/fsbank/lib/x86/fsbank.dll b/FMOD/api/fsbank/lib/x86/fsbank.dll new file mode 100644 index 0000000..16fa6bb Binary files /dev/null and b/FMOD/api/fsbank/lib/x86/fsbank.dll differ diff --git a/FMOD/api/fsbank/lib/x86/fsbank_vc.lib b/FMOD/api/fsbank/lib/x86/fsbank_vc.lib new file mode 100644 index 0000000..f951a20 Binary files /dev/null and b/FMOD/api/fsbank/lib/x86/fsbank_vc.lib differ diff --git a/FMOD/api/fsbank/lib/x86/libfsbvorbis.dll b/FMOD/api/fsbank/lib/x86/libfsbvorbis.dll new file mode 100644 index 0000000..5e8ba8f Binary files /dev/null and b/FMOD/api/fsbank/lib/x86/libfsbvorbis.dll differ diff --git a/FMOD/api/fsbank/lib/x86/opus.dll b/FMOD/api/fsbank/lib/x86/opus.dll new file mode 100644 index 0000000..a8a9a25 Binary files /dev/null and b/FMOD/api/fsbank/lib/x86/opus.dll differ diff --git a/FMOD/api/studio/examples/3d.cpp b/FMOD/api/studio/examples/3d.cpp new file mode 100644 index 0000000..5439368 --- /dev/null +++ b/FMOD/api/studio/examples/3d.cpp @@ -0,0 +1,163 @@ +/*============================================================================== +Event 3D Example +Copyright (c), Firelight Technologies Pty, Ltd 2012-2026. + +This example demonstrates how to position events in 3D for spatialization. + +For information on using FMOD example code in your own programs, visit +https://www.fmod.com/legal +==============================================================================*/ +#include "fmod_studio.hpp" +#include "fmod.hpp" +#include "common.h" + +const int SCREEN_WIDTH = NUM_COLUMNS; +const int SCREEN_HEIGHT = 16; + +int currentScreenPosition = -1; +char screenBuffer[(SCREEN_WIDTH + 1) * SCREEN_HEIGHT + 1] = {0}; + +void initializeScreenBuffer(); +void updateScreenPosition(const FMOD_VECTOR& worldPosition); + +int FMOD_Main() +{ + void *extraDriverData = NULL; + Common_Init(&extraDriverData); + + FMOD::Studio::System* system = NULL; + ERRCHECK( FMOD::Studio::System::create(&system) ); + + // The example Studio project is authored for 5.1 sound, so set up the system output mode to match + FMOD::System* coreSystem = NULL; + ERRCHECK( system->getCoreSystem(&coreSystem) ); + ERRCHECK( coreSystem->setSoftwareFormat(0, FMOD_SPEAKERMODE_5POINT1, 0) ); + + ERRCHECK( system->initialize(1024, FMOD_STUDIO_INIT_NORMAL, FMOD_INIT_NORMAL, extraDriverData) ); + + FMOD::Studio::Bank* masterBank = NULL; + ERRCHECK( system->loadBankFile(Common_MediaPath("Master.bank"), FMOD_STUDIO_LOAD_BANK_NORMAL, &masterBank) ); + + FMOD::Studio::Bank* stringsBank = NULL; + ERRCHECK( system->loadBankFile(Common_MediaPath("Master.strings.bank"), FMOD_STUDIO_LOAD_BANK_NORMAL, &stringsBank) ); + + FMOD::Studio::Bank* vehiclesBank = NULL; + ERRCHECK( system->loadBankFile(Common_MediaPath("Vehicles.bank"), FMOD_STUDIO_LOAD_BANK_NORMAL, &vehiclesBank) ); + + FMOD::Studio::EventDescription* eventDescription = NULL; + ERRCHECK( system->getEvent("event:/Vehicles/Ride-on Mower", &eventDescription) ); + + FMOD::Studio::EventInstance* eventInstance = NULL; + ERRCHECK( eventDescription->createInstance(&eventInstance) ); + + ERRCHECK( eventInstance->setParameterByName("RPM", 650.0f) ); + ERRCHECK( eventInstance->start() ); + + // Position the listener at the origin + FMOD_3D_ATTRIBUTES attributes = { { 0 } }; + attributes.forward.z = 1.0f; + attributes.up.y = 1.0f; + ERRCHECK( system->setListenerAttributes(0, &attributes) ); + + // Position the event 2 units in front of the listener + attributes.position.z = 2.0f; + ERRCHECK( eventInstance->set3DAttributes(&attributes) ); + + initializeScreenBuffer(); + + do + { + Common_Update(); + + if (Common_BtnDown(BTN_LEFT)) + { + attributes.position.x -= 1.0f; + ERRCHECK( eventInstance->set3DAttributes(&attributes) ); + } + + if (Common_BtnDown(BTN_RIGHT)) + { + attributes.position.x += 1.0f; + ERRCHECK( eventInstance->set3DAttributes(&attributes) ); + } + + if (Common_BtnDown(BTN_UP)) + { + attributes.position.z += 1.0f; + ERRCHECK( eventInstance->set3DAttributes(&attributes) ); + } + + if (Common_BtnDown(BTN_DOWN)) + { + attributes.position.z -= 1.0f; + ERRCHECK( eventInstance->set3DAttributes(&attributes) ); + } + + ERRCHECK( system->update() ); + + updateScreenPosition(attributes.position); + Common_Draw("=================================================="); + Common_Draw("Event 3D Example."); + Common_Draw("Copyright (c) Firelight Technologies 2012-2026."); + Common_Draw("=================================================="); + Common_Draw(screenBuffer); + Common_Draw("Use the arrow keys (%s, %s, %s, %s) to control the event position", + Common_BtnStr(BTN_LEFT), Common_BtnStr(BTN_RIGHT), Common_BtnStr(BTN_UP), Common_BtnStr(BTN_DOWN)); + Common_Draw("Press %s to quit", Common_BtnStr(BTN_QUIT)); + + Common_Sleep(50); + } while (!Common_BtnPress(BTN_QUIT)); + + ERRCHECK( system->release() ); + + Common_Close(); + + return 0; +} + +void initializeScreenBuffer() +{ + memset(screenBuffer, ' ', sizeof(screenBuffer)); + + int idx = SCREEN_WIDTH; + for (int i = 0; i < SCREEN_HEIGHT; ++i) + { + screenBuffer[idx] = '\n'; + idx += SCREEN_WIDTH + 1; + } + + screenBuffer[(SCREEN_WIDTH + 1) * SCREEN_HEIGHT] = '\0'; +} + +int getCharacterIndex(const FMOD_VECTOR& position) +{ + int row = static_cast(-position.z + (SCREEN_HEIGHT / 2)); + int col = static_cast(position.x + (SCREEN_WIDTH / 2)); + + if (0 < row && row < SCREEN_HEIGHT && 0 < col && col < SCREEN_WIDTH) + { + return (row * (SCREEN_WIDTH + 1)) + col; + } + + return -1; +} + +void updateScreenPosition(const FMOD_VECTOR& eventPosition) +{ + if (currentScreenPosition != -1) + { + screenBuffer[currentScreenPosition] = ' '; + currentScreenPosition = -1; + } + + FMOD_VECTOR origin = {0}; + int idx = getCharacterIndex(origin); + screenBuffer[idx] = '^'; + + idx = getCharacterIndex(eventPosition); + if (idx != -1) + { + screenBuffer[idx] = 'o'; + currentScreenPosition = idx; + } +} diff --git a/FMOD/api/studio/examples/3d_multi.cpp b/FMOD/api/studio/examples/3d_multi.cpp new file mode 100644 index 0000000..3297b0f --- /dev/null +++ b/FMOD/api/studio/examples/3d_multi.cpp @@ -0,0 +1,241 @@ +/*============================================================================== +Event 3D Multi-Listener Example +Copyright (c), Firelight Technologies Pty, Ltd 2012-2026. + +This example demonstrates how use listener weighting to crossfade listeners +in and out. + +For information on using FMOD example code in your own programs, visit +https://www.fmod.com/legal +==============================================================================*/ +#include "fmod_studio.hpp" +#include "fmod.hpp" +#include "common.h" + +const int SCREEN_WIDTH = NUM_COLUMNS; +const int SCREEN_HEIGHT = 10; + +char backBuffer[(SCREEN_WIDTH + 1) * SCREEN_HEIGHT + 1] = {0}; +char screenBuffer[(SCREEN_WIDTH + 1) * SCREEN_HEIGHT + 1] = {0}; + +void initializeScreenBuffer(); +void updateScreenPosition(const FMOD_VECTOR& worldPosition, float listenerDist, float weight1, float weight2); + +int FMOD_Main() +{ + void *extraDriverData = NULL; + Common_Init(&extraDriverData); + + FMOD::Studio::System* system = NULL; + ERRCHECK( FMOD::Studio::System::create(&system) ); + + // The example Studio project is authored for 5.1 sound, so set up the system output mode to match + FMOD::System* coreSystem = NULL; + ERRCHECK( system->getCoreSystem(&coreSystem) ); + ERRCHECK( coreSystem->setSoftwareFormat(0, FMOD_SPEAKERMODE_5POINT1, 0) ); + + ERRCHECK( system->initialize(1024, FMOD_STUDIO_INIT_NORMAL, FMOD_INIT_NORMAL, extraDriverData) ); + + FMOD::Studio::Bank* masterBank = NULL; + ERRCHECK( system->loadBankFile(Common_MediaPath("Master.bank"), FMOD_STUDIO_LOAD_BANK_NORMAL, &masterBank) ); + + FMOD::Studio::Bank* stringsBank = NULL; + ERRCHECK( system->loadBankFile(Common_MediaPath("Master.strings.bank"), FMOD_STUDIO_LOAD_BANK_NORMAL, &stringsBank) ); + + FMOD::Studio::Bank* vehiclesBank = NULL; + ERRCHECK( system->loadBankFile(Common_MediaPath("Vehicles.bank"), FMOD_STUDIO_LOAD_BANK_NORMAL, &vehiclesBank) ); + + FMOD::Studio::EventDescription* eventDescription = NULL; + ERRCHECK( system->getEvent("event:/Vehicles/Ride-on Mower", &eventDescription) ); + + FMOD::Studio::EventInstance* eventInstance = NULL; + ERRCHECK( eventDescription->createInstance(&eventInstance) ); + + ERRCHECK( eventInstance->setParameterByName("RPM", 650.0f) ); + ERRCHECK( eventInstance->start() ); + + // Position two listeners + ERRCHECK( system->setNumListeners(2) ); + int activeListener = 0; + float listenerDist = 8.0f; + float listenerWeight[2] = { 1.0f, 0.0f }; + FMOD_3D_ATTRIBUTES listenerAttributes[2] = {}; + listenerAttributes[0].forward.z = 1.0f; + listenerAttributes[0].up.y = 1.0f; + listenerAttributes[0].position.x = -listenerDist; + listenerAttributes[1].forward.z = 1.0f; + listenerAttributes[1].up.y = 1.0f; + listenerAttributes[1].position.x = listenerDist; + + ERRCHECK( system->setListenerAttributes(0, &listenerAttributes[0]) ); + ERRCHECK( system->setListenerWeight(0, listenerWeight[0]) ); + ERRCHECK( system->setListenerAttributes(1, &listenerAttributes[1]) ); + ERRCHECK( system->setListenerWeight(1, listenerWeight[1]) ); + + // Position the event 2 units in front of the listener + FMOD_3D_ATTRIBUTES carAttributes = {}; + carAttributes.forward.z = 1.0f; + carAttributes.up.y = 1.0f; + carAttributes.position.x = 0.0f; + carAttributes.position.z = 2.0f; + ERRCHECK( eventInstance->set3DAttributes(&carAttributes) ); + + initializeScreenBuffer(); + + do + { + Common_Update(); + + if (Common_BtnPress(BTN_LEFT)) + { + carAttributes.position.x -= 1.0f; + ERRCHECK( eventInstance->set3DAttributes(&carAttributes) ); + } + + if (Common_BtnPress(BTN_RIGHT)) + { + carAttributes.position.x += 1.0f; + ERRCHECK( eventInstance->set3DAttributes(&carAttributes) ); + } + + if (Common_BtnPress(BTN_UP)) + { + carAttributes.position.z += 1.0f; + ERRCHECK( eventInstance->set3DAttributes(&carAttributes) ); + } + + if (Common_BtnPress(BTN_DOWN)) + { + carAttributes.position.z -= 1.0f; + ERRCHECK( eventInstance->set3DAttributes(&carAttributes) ); + } + + if (Common_BtnPress(BTN_ACTION1)) + { + activeListener++; + if (activeListener > 2) + activeListener = 0; + } + + if (Common_BtnPress(BTN_ACTION2)) + { + activeListener--; + if (activeListener < 0) + activeListener = 2; + } + + if (Common_BtnPress(BTN_ACTION3)) + { + listenerDist -= 1.0f; + if (listenerDist < 0.0f) + listenerDist = 0.0f; + } + + if (Common_BtnPress(BTN_ACTION4)) + { + listenerDist += 1.0f; + if (listenerDist < 0.0f) + listenerDist = 0.0f; + } + + for (int i=0; i<2; ++i) + { + float target = (activeListener == i || activeListener == 2); // 0 = left, 1 = right, 2 = both + + float dist = (target - listenerWeight[i]); + float step = 50.0f / 1000.0f; // very rough estimate of 50ms per update, not properly timed + + if (dist >= -step && dist <= step) + listenerWeight[i] = target; + else if (dist > 0.0f) + listenerWeight[i] += step; + else + listenerWeight[i] += -step; + } + + listenerAttributes[0].position.x = -listenerDist; + listenerAttributes[1].position.x = listenerDist; + ERRCHECK( system->setListenerAttributes(0, &listenerAttributes[0]) ); + ERRCHECK( system->setListenerAttributes(1, &listenerAttributes[1]) ); + ERRCHECK( system->setListenerWeight(0, listenerWeight[0]) ); + ERRCHECK( system->setListenerWeight(1, listenerWeight[1]) ); + + ERRCHECK( system->update() ); + + updateScreenPosition(carAttributes.position, listenerDist, listenerWeight[0], listenerWeight[1]); + + Common_Draw("=================================================="); + Common_Draw("Event 3D Multi-Listener Example."); + Common_Draw("Copyright (c) Firelight Technologies 2012-2026."); + Common_Draw("=================================================="); + Common_Draw(screenBuffer); + + Common_Draw("Left listener: %d%%", (int)(listenerWeight[0] * 100)); + Common_Draw("Right listener: %d%%", (int)(listenerWeight[1] * 100)); + Common_Draw("Use the arrow keys (%s, %s, %s, %s) to control the event position", + Common_BtnStr(BTN_LEFT), Common_BtnStr(BTN_RIGHT), Common_BtnStr(BTN_UP), Common_BtnStr(BTN_DOWN)); + Common_Draw("Use %s and %s to toggle left/right/both listeners", Common_BtnStr(BTN_ACTION1), Common_BtnStr(BTN_ACTION2)); + Common_Draw("Use %s and %s to move listeners closer or further apart", Common_BtnStr(BTN_ACTION3), Common_BtnStr(BTN_ACTION4)); + Common_Draw("Press %s to quit", Common_BtnStr(BTN_QUIT)); + + Common_Sleep(50); + } while (!Common_BtnPress(BTN_QUIT)); + + ERRCHECK( system->release() ); + + Common_Close(); + + return 0; +} + +void initializeScreenBuffer() +{ + memset(backBuffer, ' ', sizeof(backBuffer)); + + int idx = SCREEN_WIDTH; + for (int i = 0; i < SCREEN_HEIGHT; ++i) + { + backBuffer[idx] = '\n'; + idx += SCREEN_WIDTH + 1; + } + + backBuffer[(SCREEN_WIDTH + 1) * SCREEN_HEIGHT] = '\0'; + memcpy(screenBuffer, backBuffer, sizeof(screenBuffer)); +} + +void setCharacterIndex(const FMOD_VECTOR& position, char ch) +{ + int row = static_cast(-position.z + (SCREEN_HEIGHT / 2)); + int col = static_cast(position.x + (SCREEN_WIDTH / 2)); + + if (0 < row && row < SCREEN_HEIGHT && 0 < col && col < SCREEN_WIDTH) + { + screenBuffer[row * (SCREEN_WIDTH + 1) + col] = ch; + } +} + +char symbolForWeight(float weight) +{ + if (weight >= 0.95f) + return 'X'; + else if (weight >= 0.05f) + return 'x'; + else + return '.'; +} + +void updateScreenPosition(const FMOD_VECTOR& worldPosition, float listenerDist, float weight1, float weight2) +{ + memcpy(screenBuffer, backBuffer, sizeof(screenBuffer)); + + FMOD_VECTOR pos = {0}; + setCharacterIndex(pos, '^'); + + pos.x = -listenerDist; + setCharacterIndex(pos, symbolForWeight(weight1)); + + pos.x = listenerDist; + setCharacterIndex(pos, symbolForWeight(weight2)); + + setCharacterIndex(worldPosition, 'o'); +} diff --git a/FMOD/api/studio/examples/bin/3d.exe b/FMOD/api/studio/examples/bin/3d.exe new file mode 100644 index 0000000..a6a2349 Binary files /dev/null and b/FMOD/api/studio/examples/bin/3d.exe differ diff --git a/FMOD/api/studio/examples/bin/3d_multi.exe b/FMOD/api/studio/examples/bin/3d_multi.exe new file mode 100644 index 0000000..99229ab Binary files /dev/null and b/FMOD/api/studio/examples/bin/3d_multi.exe differ diff --git a/FMOD/api/studio/examples/bin/event_parameter.exe b/FMOD/api/studio/examples/bin/event_parameter.exe new file mode 100644 index 0000000..cda07db Binary files /dev/null and b/FMOD/api/studio/examples/bin/event_parameter.exe differ diff --git a/FMOD/api/studio/examples/bin/fmod.dll b/FMOD/api/studio/examples/bin/fmod.dll new file mode 100644 index 0000000..2ed6c15 Binary files /dev/null and b/FMOD/api/studio/examples/bin/fmod.dll differ diff --git a/FMOD/api/studio/examples/bin/fmodstudio.dll b/FMOD/api/studio/examples/bin/fmodstudio.dll new file mode 100644 index 0000000..22619e3 Binary files /dev/null and b/FMOD/api/studio/examples/bin/fmodstudio.dll differ diff --git a/FMOD/api/studio/examples/bin/load_banks.exe b/FMOD/api/studio/examples/bin/load_banks.exe new file mode 100644 index 0000000..9093178 Binary files /dev/null and b/FMOD/api/studio/examples/bin/load_banks.exe differ diff --git a/FMOD/api/studio/examples/bin/music_callbacks.exe b/FMOD/api/studio/examples/bin/music_callbacks.exe new file mode 100644 index 0000000..9811e64 Binary files /dev/null and b/FMOD/api/studio/examples/bin/music_callbacks.exe differ diff --git a/FMOD/api/studio/examples/bin/objectpan.exe b/FMOD/api/studio/examples/bin/objectpan.exe new file mode 100644 index 0000000..0adb3b1 Binary files /dev/null and b/FMOD/api/studio/examples/bin/objectpan.exe differ diff --git a/FMOD/api/studio/examples/bin/programmer_sound.exe b/FMOD/api/studio/examples/bin/programmer_sound.exe new file mode 100644 index 0000000..9c337b4 Binary files /dev/null and b/FMOD/api/studio/examples/bin/programmer_sound.exe differ diff --git a/FMOD/api/studio/examples/bin/recording_playback.exe b/FMOD/api/studio/examples/bin/recording_playback.exe new file mode 100644 index 0000000..c8e1f52 Binary files /dev/null and b/FMOD/api/studio/examples/bin/recording_playback.exe differ diff --git a/FMOD/api/studio/examples/bin/simple_event.exe b/FMOD/api/studio/examples/bin/simple_event.exe new file mode 100644 index 0000000..da7a1ef Binary files /dev/null and b/FMOD/api/studio/examples/bin/simple_event.exe differ diff --git a/FMOD/api/studio/examples/common.cpp b/FMOD/api/studio/examples/common.cpp new file mode 100644 index 0000000..0b03ff1 --- /dev/null +++ b/FMOD/api/studio/examples/common.cpp @@ -0,0 +1,234 @@ +/*============================================================================== +FMOD Example Framework +Copyright (c), Firelight Technologies Pty, Ltd 2012-2026. +==============================================================================*/ +#include "common.h" +#include "fmod_errors.h" + +/* Cross platform OS Functions internal to the FMOD library, exposed for the example framework. */ +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct FMOD_OS_FILE FMOD_OS_FILE; +typedef struct FMOD_OS_CRITICALSECTION FMOD_OS_CRITICALSECTION; + +FMOD_RESULT F_API FMOD_OS_Time_GetUs(unsigned int *us); +FMOD_RESULT F_API FMOD_OS_Debug_Output(const char *format, ...); +FMOD_RESULT F_API FMOD_OS_File_Open(const char *name, int mode, unsigned int *filesize, FMOD_OS_FILE **handle); +FMOD_RESULT F_API FMOD_OS_File_Close(FMOD_OS_FILE *handle); +FMOD_RESULT F_API FMOD_OS_File_Read(FMOD_OS_FILE *handle, void *buf, unsigned int count, unsigned int *read); +FMOD_RESULT F_API FMOD_OS_File_Write(FMOD_OS_FILE *handle, const void *buffer, unsigned int bytesToWrite, bool flush); +FMOD_RESULT F_API FMOD_OS_File_Seek(FMOD_OS_FILE *handle, unsigned int offset); +FMOD_RESULT F_API FMOD_OS_Time_Sleep(unsigned int ms); +FMOD_RESULT F_API FMOD_OS_CriticalSection_Create(FMOD_OS_CRITICALSECTION **crit, bool memorycrit); +FMOD_RESULT F_API FMOD_OS_CriticalSection_Free(FMOD_OS_CRITICALSECTION *crit, bool memorycrit); +FMOD_RESULT F_API FMOD_OS_CriticalSection_Enter(FMOD_OS_CRITICALSECTION *crit); +FMOD_RESULT F_API FMOD_OS_CriticalSection_Leave(FMOD_OS_CRITICALSECTION *crit); +FMOD_RESULT F_API FMOD_OS_CriticalSection_TryEnter(FMOD_OS_CRITICALSECTION *crit, bool *entered); +FMOD_RESULT F_API FMOD_OS_CriticalSection_IsLocked(FMOD_OS_CRITICALSECTION *crit, bool *locked); +FMOD_RESULT F_API FMOD_OS_Thread_Create(const char *name, void (*callback)(void *param), void *param, FMOD_THREAD_AFFINITY affinity, FMOD_THREAD_PRIORITY priority, FMOD_THREAD_STACK_SIZE stacksize, void **handle); +FMOD_RESULT F_API FMOD_OS_Thread_Destroy(void *handle); + +#ifdef __cplusplus +} +#endif + +void (*Common_Private_Error)(FMOD_RESULT, const char *, int); + +void ERRCHECK_fn(FMOD_RESULT result, const char *file, int line) +{ + if (result != FMOD_OK) + { + if (Common_Private_Error) + { + Common_Private_Error(result, file, line); + } + Common_Fatal("%s(%d): FMOD error %d - %s", file, line, result, FMOD_ErrorString(result)); + } +} + +void Common_Format(char *buffer, int bufferSize, const char *formatString...) +{ + va_list args; + va_start(args, formatString); + Common_vsnprintf(buffer, bufferSize, formatString, args); + va_end(args); + buffer[bufferSize-1] = '\0'; +} + +void Common_Fatal(const char *format, ...) +{ + char error[1024]; + + va_list args; + va_start(args, format); + Common_vsnprintf(error, 1024, format, args); + va_end(args); + error[1023] = '\0'; + + do + { + Common_Draw("A fatal error has occurred..."); + Common_Draw(""); + Common_Draw("%s", error); + Common_Draw(""); + Common_Draw("Press %s to quit", Common_BtnStr(BTN_QUIT)); + + Common_Update(); + Common_Sleep(50); + } while (!Common_BtnPress(BTN_QUIT)); + + Common_Exit(0); +} + +void Common_Draw(const char *format, ...) +{ + char string[1024]; + char *stringPtr = string; + + va_list args; + va_start(args, format); + Common_vsnprintf(string, 1024, format, args); + va_end(args); + string[1023] = '\0'; + + unsigned int length = (unsigned int)strlen(string); + + do + { + bool consumeNewLine = false; + unsigned int copyLength = length; + + // Search for new line characters + char *newLinePtr = strchr(stringPtr, '\n'); + if (newLinePtr) + { + consumeNewLine = true; + copyLength = (unsigned int)(newLinePtr - stringPtr); + } + + if (copyLength > NUM_COLUMNS) + { + // Hard wrap by default + copyLength = NUM_COLUMNS; + + // Loop for a soft wrap + for (int i = NUM_COLUMNS - 1; i >= 0; i--) + { + if (stringPtr[i] == ' ') + { + copyLength = i + 1; + break; + } + } + } + + // Null terminate the sub string temporarily by swapping out a char + char tempChar = stringPtr[copyLength]; + stringPtr[copyLength] = 0; + Common_DrawText(stringPtr); + stringPtr[copyLength] = tempChar; + + copyLength += (consumeNewLine ? 1 : 0); + length -= copyLength; + stringPtr += copyLength; + } while (length > 0); +} + +void Common_Time_GetUs(unsigned int *us) +{ + FMOD_OS_Time_GetUs(us); +} + +void Common_Log(const char *format, ...) +{ + char string[1024]; + + va_list args; + va_start(args, format); + Common_vsnprintf(string, 1024, format, args); + va_end(args); + string[1023] = '\0'; + + FMOD_OS_Debug_Output(string); +} + +void Common_LoadFileMemory(const char *name, void **buff, int *length) +{ + FMOD_OS_FILE *file = NULL; + unsigned int len, bytesread; + + FMOD_OS_File_Open(name, 0, &len, &file); + void *mem = malloc(len); + FMOD_OS_File_Read(file, mem, len, &bytesread); + FMOD_OS_File_Close(file); + + *buff = mem; + *length = bytesread; +} + +void Common_UnloadFileMemory(void *buff) +{ + free(buff); +} + +void Common_Sleep(unsigned int ms) +{ + FMOD_OS_Time_Sleep(ms); +} + +void Common_File_Open(const char *name, int mode, unsigned int *filesize, void **handle) +{ + FMOD_OS_File_Open(name, mode, filesize, (FMOD_OS_FILE **)handle); +} + +void Common_File_Close(void *handle) +{ + FMOD_OS_File_Close((FMOD_OS_FILE *)handle); +} + +void Common_File_Read(void *handle, void *buf, unsigned int length, unsigned int *read) +{ + FMOD_OS_File_Read((FMOD_OS_FILE *)handle, buf, length, read); +} + +void Common_File_Write(void *handle, void *buf, unsigned int length) +{ + FMOD_OS_File_Write((FMOD_OS_FILE *)handle, buf, length, true); +} + +void Common_File_Seek(void *handle, unsigned int offset) +{ + FMOD_OS_File_Seek((FMOD_OS_FILE *)handle, offset); +} + +void Common_Mutex_Create(Common_Mutex *mutex) +{ + FMOD_OS_CriticalSection_Create((FMOD_OS_CRITICALSECTION **)&mutex->crit, false); +} + +void Common_Mutex_Destroy(Common_Mutex *mutex) +{ + FMOD_OS_CriticalSection_Free((FMOD_OS_CRITICALSECTION *)mutex->crit, false); +} + +void Common_Mutex_Enter(Common_Mutex *mutex) +{ + FMOD_OS_CriticalSection_Enter((FMOD_OS_CRITICALSECTION *)mutex->crit); +} + +void Common_Mutex_Leave(Common_Mutex *mutex) +{ + FMOD_OS_CriticalSection_Leave((FMOD_OS_CRITICALSECTION *)mutex->crit); +} + +void Common_Thread_Create(void (*callback)(void *param), void *param, void **handle) +{ + FMOD_OS_Thread_Create("FMOD Example Thread", callback, param, FMOD_THREAD_AFFINITY_GROUP_A, FMOD_THREAD_PRIORITY_MEDIUM, (16 * 1024), handle); +} + +void Common_Thread_Destroy(void *handle) +{ + FMOD_OS_Thread_Destroy(handle); +} diff --git a/FMOD/api/studio/examples/common.h b/FMOD/api/studio/examples/common.h new file mode 100644 index 0000000..b3af2f3 --- /dev/null +++ b/FMOD/api/studio/examples/common.h @@ -0,0 +1,93 @@ +/*============================================================================== +FMOD Example Framework +Copyright (c), Firelight Technologies Pty, Ltd 2012-2026. +==============================================================================*/ +#ifndef FMOD_EXAMPLES_COMMON_H +#define FMOD_EXAMPLES_COMMON_H + +#include "common_platform.h" +#include "fmod.h" + +#include +#include +#include +#include +#include +#include +#include + +#define NUM_COLUMNS 50 +#define NUM_ROWS 25 + +#ifndef Common_Sin + #define Common_Sin sin +#endif + +#ifndef Common_snprintf + #define Common_snprintf snprintf +#endif + +#ifndef Common_vsnprintf + #define Common_vsnprintf vsnprintf +#endif + +enum Common_Button +{ + BTN_ACTION1, + BTN_ACTION2, + BTN_ACTION3, + BTN_ACTION4, + BTN_LEFT, + BTN_RIGHT, + BTN_UP, + BTN_DOWN, + BTN_MORE, + BTN_QUIT +}; + +typedef struct +{ + void *crit; +} Common_Mutex; + +/* Cross platform functions (common) */ +void Common_Format(char *buffer, int bufferSize, const char *formatString...); +void Common_Fatal(const char *format, ...); +void Common_Draw(const char *format, ...); +void Common_Time_GetUs(unsigned int *us); +void Common_Log(const char *format, ...); +void Common_LoadFileMemory(const char *name, void **buff, int *length); +void Common_UnloadFileMemory(void *buff); +void Common_Sleep(unsigned int ms); +void Common_File_Open(const char *name, int mode, unsigned int *filesize, void **handle); // mode : 0 = read, 1 = write. +void Common_File_Close(void *handle); +void Common_File_Read(void *handle, void *buf, unsigned int length, unsigned int *read); +void Common_File_Write(void *handle, void *buf, unsigned int length); +void Common_File_Seek(void *handle, unsigned int offset); +void Common_Mutex_Create(Common_Mutex *mutex); +void Common_Mutex_Destroy(Common_Mutex *mutex); +void Common_Mutex_Enter(Common_Mutex *mutex); +void Common_Mutex_Leave(Common_Mutex *mutex); +void Common_Thread_Create(void (*callback)(void *param), void *param, void **handle); +void Common_Thread_Destroy(void *handle); + +void ERRCHECK_fn(FMOD_RESULT result, const char *file, int line); +#define ERRCHECK(_result) ERRCHECK_fn(_result, __FILE__, __LINE__) +#define Common_Max(_a, _b) ((_a) > (_b) ? (_a) : (_b)) +#define Common_Min(_a, _b) ((_a) < (_b) ? (_a) : (_b)) +#define Common_Clamp(_min, _val, _max) ((_val) < (_min) ? (_min) : ((_val) > (_max) ? (_max) : (_val))) + +/* Functions with platform specific implementation (common_platform) */ +void Common_Init(void **extraDriverData); +void Common_Close(); +void Common_Update(); +void Common_Exit(int returnCode); +void Common_DrawText(const char *text); +bool Common_BtnPress(Common_Button btn); +bool Common_BtnDown(Common_Button btn); +const char *Common_BtnStr(Common_Button btn); +const char *Common_MediaPath(const char *fileName); +const char *Common_WritePath(const char *fileName); + + +#endif diff --git a/FMOD/api/studio/examples/common_platform.cpp b/FMOD/api/studio/examples/common_platform.cpp new file mode 100644 index 0000000..29410d4 --- /dev/null +++ b/FMOD/api/studio/examples/common_platform.cpp @@ -0,0 +1,306 @@ +/*============================================================================== +FMOD Example Framework +Copyright (c), Firelight Technologies Pty, Ltd 2012-2026. +==============================================================================*/ +#define WIN32_LEAN_AND_MEAN + +#include "common.h" +#include +#include +#include +#include +#include + +static HWND gWindow = nullptr; +static int gScreenWidth = 0; +static int gScreenHeight = 0; +static unsigned int gPressedButtons = 0; +static unsigned int gDownButtons = 0; +static unsigned int gLastDownButtons = 0; +static char gWriteBuffer[(NUM_COLUMNS+1) * NUM_ROWS] = {0}; +static char gDisplayBuffer[(NUM_COLUMNS+1) * NUM_ROWS] = {0}; +static unsigned int gYPos = 0; +static bool gQuit = false; +static std::vector gPathList; + +bool Common_Private_Test; +int Common_Private_Argc; +char** Common_Private_Argv; +void (*Common_Private_Update)(unsigned int*); +void (*Common_Private_Print)(const char*); +void (*Common_Private_Close)(); + +void Common_Init(void** /*extraDriverData*/) +{ + CoInitializeEx(nullptr, COINIT_APARTMENTTHREADED); +} + +void Common_Close() +{ + CoUninitialize(); + + for (std::vector::iterator item = gPathList.begin(); item != gPathList.end(); ++item) + { + free(*item); + } + if (Common_Private_Close) + { + Common_Private_Close(); + } +} + +static unsigned int translateButton(unsigned int button) +{ + switch (button) + { + case '1': return (1 << BTN_ACTION1); + case '2': return (1 << BTN_ACTION2); + case '3': return (1 << BTN_ACTION3); + case '4': return (1 << BTN_ACTION4); + case VK_LEFT: return (1 << BTN_LEFT); + case VK_RIGHT: return (1 << BTN_RIGHT); + case VK_UP: return (1 << BTN_UP); + case VK_DOWN: return (1 << BTN_DOWN); + case VK_SPACE: return (1 << BTN_MORE); + case VK_ESCAPE: return (1 << BTN_QUIT); + default: return 0; + } +} + +void Common_Update() +{ + MSG msg = { }; + while (PeekMessage(&msg, nullptr, 0, 0, PM_REMOVE)) + { + TranslateMessage(&msg); + DispatchMessage(&msg); + } + + gPressedButtons = (gLastDownButtons ^ gDownButtons) & gDownButtons; + gPressedButtons |= (gQuit ? (1 << BTN_QUIT) : 0); + gLastDownButtons = gDownButtons; + + memcpy(gDisplayBuffer, gWriteBuffer, sizeof(gWriteBuffer)); + InvalidateRect(gWindow, nullptr, FALSE); + + gYPos = 0; + memset(gWriteBuffer, ' ', sizeof(gWriteBuffer)); + for (int i = 0; i < NUM_ROWS; i++) + { + gWriteBuffer[(i * (NUM_COLUMNS + 1)) + NUM_COLUMNS] = '\n'; + } + + if (Common_Private_Update) + { + Common_Private_Update(&gPressedButtons); + } +} + +void Common_Exit(int returnCode) +{ + exit(returnCode); +} + +void Common_DrawText(const char *text) +{ + if (gYPos < NUM_ROWS) + { + char tempBuffer[NUM_COLUMNS + 1]; + Common_Format(tempBuffer, sizeof(tempBuffer), "%s", text); + memcpy(&gWriteBuffer[gYPos * (NUM_COLUMNS + 1)], tempBuffer, strlen(tempBuffer)); + gYPos++; + } +} + +bool Common_BtnPress(Common_Button btn) +{ + return ((gPressedButtons & (1 << btn)) != 0); +} + +bool Common_BtnDown(Common_Button btn) +{ + return ((gDownButtons & (1 << btn)) != 0); +} + +const char *Common_BtnStr(Common_Button btn) +{ + switch (btn) + { + case BTN_ACTION1: return "1"; + case BTN_ACTION2: return "2"; + case BTN_ACTION3: return "3"; + case BTN_ACTION4: return "4"; + case BTN_LEFT: return "Left"; + case BTN_RIGHT: return "Right"; + case BTN_UP: return "Up"; + case BTN_DOWN: return "Down"; + case BTN_MORE: return "Space"; + case BTN_QUIT: return "Escape"; + default: return "Unknown"; + } +} + +const char *Common_MediaPath(const char *fileName) +{ + char *filePath = (char *)calloc(256, sizeof(char)); + + static const char* pathPrefix = nullptr; + if (!pathPrefix) + { + const char *emptyPrefix = ""; + const char *mediaPrefix = "../media/"; + FILE *file = fopen(fileName, "r"); + if (file) + { + fclose(file); + pathPrefix = emptyPrefix; + } + else + { + pathPrefix = mediaPrefix; + } + } + + strcat(filePath, pathPrefix); + strcat(filePath, fileName); + + gPathList.push_back(filePath); + + return filePath; +} + +const char *Common_WritePath(const char *fileName) +{ + return Common_MediaPath(fileName); +} + +void Common_TTY(const char *format, ...) +{ + char string[1024] = {0}; + + va_list args; + va_start(args, format); + Common_vsnprintf(string, 1023, format, args); + va_end(args); + + if (Common_Private_Print) + { + (*Common_Private_Print)(string); + } + else + { + OutputDebugStringA(string); + } +} + +HFONT CreateDisplayFont() +{ + return CreateFontA(22, 0, 0, 0, FW_DONTCARE, FALSE, FALSE, FALSE, DEFAULT_CHARSET, OUT_OUTLINE_PRECIS, + CLIP_DEFAULT_PRECIS, DEFAULT_QUALITY, FIXED_PITCH, 0); +} + +LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) +{ + if (message == WM_PAINT) + { + PAINTSTRUCT ps; + HDC hdc = BeginPaint(hWnd, &ps); + HDC hdcBack = CreateCompatibleDC(hdc); + + HBITMAP hbmBack = CreateCompatibleBitmap(hdc, gScreenWidth, gScreenHeight); + HBITMAP hbmOld = (HBITMAP)SelectObject(hdcBack, hbmBack); + + HFONT hfnt = CreateDisplayFont(); + HFONT hfntOld = (HFONT)SelectObject(hdcBack, hfnt); + + SetBkColor(hdcBack, RGB(0x0, 0x0, 0x0)); + SetTextColor(hdcBack, RGB(0xFF, 0xFF, 0xFF)); + DrawTextA(hdcBack, gDisplayBuffer, -1, &ps.rcPaint, 0); + BitBlt(hdc, 0, 0, gScreenWidth, gScreenHeight, hdcBack, 0, 0, SRCCOPY); + + SelectObject(hdcBack, hfntOld); + DeleteObject(hfnt); + + SelectObject(hdcBack, hbmOld); + DeleteObject(hbmBack); + + DeleteDC(hdcBack); + EndPaint(hWnd, &ps); + } + else if (message == WM_DESTROY) + { + gQuit = true; + } + else if (message == WM_GETMINMAXINFO) + { + if (gScreenWidth == 0) + { + HDC hdc = GetDC(hWnd); + + HFONT hfnt = CreateDisplayFont(); + HFONT hfntOld = (HFONT)SelectObject(hdc, hfnt); + + TEXTMETRICA metrics = { }; + GetTextMetricsA(hdc, &metrics); + + SelectObject(hdc, hfntOld); + DeleteObject(hfnt); + + ReleaseDC(hWnd, hdc); + + RECT rec = { }; + rec.right = metrics.tmAveCharWidth * NUM_COLUMNS; + rec.bottom = metrics.tmHeight * NUM_ROWS; + + BOOL success = AdjustWindowRect(&rec, WS_CAPTION | WS_SYSMENU, FALSE); + assert(success); + + gScreenWidth = rec.right - rec.left; + gScreenHeight = rec.bottom - rec.top; + } + + LPMINMAXINFO lpMMI = (LPMINMAXINFO)lParam; + lpMMI->ptMinTrackSize.x = gScreenWidth; + lpMMI->ptMinTrackSize.y = gScreenHeight; + lpMMI->ptMaxTrackSize = lpMMI->ptMinTrackSize; + } + else if (message == WM_KEYDOWN) + { + gDownButtons |= translateButton((unsigned int)wParam); + } + else if (message == WM_KEYUP) + { + gDownButtons &= ~translateButton((unsigned int)wParam); + } + else + { + return DefWindowProc(hWnd, message, wParam, lParam); + } + + return 0; +} + +int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE /*hPrevInstance*/, PSTR /*pCmdLine*/, int nCmdShow) +{ + const char CLASS_NAME[] = "FMOD Example Window Class"; + + Common_Private_Argc = __argc; + Common_Private_Argv = __argv; + + WNDCLASSA wc = { }; + wc.style = CS_HREDRAW | CS_VREDRAW; + wc.lpfnWndProc = WndProc; + wc.hInstance = hInstance; + wc.hbrBackground = (HBRUSH)GetStockObject(BLACK_BRUSH); + wc.lpszClassName = CLASS_NAME; + + ATOM atom = RegisterClassA(&wc); + assert(atom); + + gWindow = CreateWindowA(CLASS_NAME, "FMOD Example", WS_CAPTION | WS_SYSMENU, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, nullptr, nullptr, hInstance, nullptr); + assert(gWindow); + + ShowWindow(gWindow, nCmdShow); + + return FMOD_Main(); +} diff --git a/FMOD/api/studio/examples/common_platform.h b/FMOD/api/studio/examples/common_platform.h new file mode 100644 index 0000000..2b46a6d --- /dev/null +++ b/FMOD/api/studio/examples/common_platform.h @@ -0,0 +1,16 @@ +/*============================================================================== +FMOD Example Framework +Copyright (c), Firelight Technologies Pty, Ltd 2012-2026. +==============================================================================*/ +#include + +int FMOD_Main(); + +#define COMMON_PLATFORM_SUPPORTS_FOPEN + +#define Common_snprintf _snprintf +#define Common_vsnprintf _vsnprintf + +void Common_TTY(const char *format, ...); + + diff --git a/FMOD/api/studio/examples/event_parameter.cpp b/FMOD/api/studio/examples/event_parameter.cpp new file mode 100644 index 0000000..d594454 --- /dev/null +++ b/FMOD/api/studio/examples/event_parameter.cpp @@ -0,0 +1,97 @@ +/*============================================================================== +Event Parameter Example +Copyright (c), Firelight Technologies Pty, Ltd 2012-2026. + +This example demonstrates how to control event playback using game parameters. + +For information on using FMOD example code in your own programs, visit +https://www.fmod.com/legal +==============================================================================*/ +#include "fmod_studio.hpp" +#include "fmod.hpp" +#include "common.h" + +int FMOD_Main() +{ + void *extraDriverData = NULL; + Common_Init(&extraDriverData); + + FMOD::Studio::System* system = NULL; + ERRCHECK( FMOD::Studio::System::create(&system) ); + ERRCHECK( system->initialize(1024, FMOD_STUDIO_INIT_NORMAL, FMOD_INIT_NORMAL, extraDriverData) ); + + FMOD::Studio::Bank* masterBank = NULL; + ERRCHECK( system->loadBankFile(Common_MediaPath("Master.bank"), FMOD_STUDIO_LOAD_BANK_NORMAL, &masterBank) ); + + FMOD::Studio::Bank* stringsBank = NULL; + ERRCHECK( system->loadBankFile(Common_MediaPath("Master.strings.bank"), FMOD_STUDIO_LOAD_BANK_NORMAL, &stringsBank) ); + + FMOD::Studio::Bank* sfxBank = NULL; + ERRCHECK( system->loadBankFile(Common_MediaPath("SFX.bank"), FMOD_STUDIO_LOAD_BANK_NORMAL, &sfxBank) ); + + FMOD::Studio::EventDescription* eventDescription = NULL; + ERRCHECK( system->getEvent("event:/Character/Player Footsteps", &eventDescription) ); + + // Find the parameter once and then set by handle + // Or we can just find by name every time but by handle is more efficient if we are setting lots of parameters + FMOD_STUDIO_PARAMETER_DESCRIPTION paramDesc; + ERRCHECK( eventDescription->getParameterDescriptionByName("Surface", ¶mDesc) ); + FMOD_STUDIO_PARAMETER_ID surfaceID = paramDesc.id; + + FMOD::Studio::EventInstance* eventInstance = NULL; + ERRCHECK( eventDescription->createInstance(&eventInstance) ); + + // Make the event audible to start with + float surfaceParameterValue = 1.0f; + ERRCHECK( eventInstance->setParameterByID(surfaceID, surfaceParameterValue) ); + + do + { + Common_Update(); + + if (Common_BtnPress(BTN_MORE)) + { + ERRCHECK( eventInstance->start() ); + } + + if (Common_BtnPress(BTN_ACTION1)) + { + surfaceParameterValue = Common_Max(paramDesc.minimum, surfaceParameterValue - 1.0f); + ERRCHECK( eventInstance->setParameterByID(surfaceID, surfaceParameterValue) ); + } + + if (Common_BtnPress(BTN_ACTION2)) + { + surfaceParameterValue = Common_Min(surfaceParameterValue + 1.0f, paramDesc.maximum); + ERRCHECK( eventInstance->setParameterByID(surfaceID, surfaceParameterValue) ); + } + + ERRCHECK( system->update() ); + + float userValue = 0.0f; + float finalValue = 0.0f; + ERRCHECK( eventInstance->getParameterByID(surfaceID, &userValue, &finalValue) ); + + Common_Draw("=================================================="); + Common_Draw("Event Parameter Example."); + Common_Draw("Copyright (c) Firelight Technologies 2012-2026."); + Common_Draw("=================================================="); + Common_Draw(""); + Common_Draw("Surface Parameter = (user: %1.1f, final: %1.1f)", userValue, finalValue); + Common_Draw(""); + Common_Draw("Surface Parameter:"); + Common_Draw("Press %s to play event", Common_BtnStr(BTN_MORE)); + Common_Draw("Press %s to decrease value", Common_BtnStr(BTN_ACTION1)); + Common_Draw("Press %s to increase value", Common_BtnStr(BTN_ACTION2)); + Common_Draw(""); + Common_Draw("Press %s to quit", Common_BtnStr(BTN_QUIT)); + + Common_Sleep(50); + } while (!Common_BtnPress(BTN_QUIT)); + + ERRCHECK( system->release() ); + + Common_Close(); + + return 0; +} diff --git a/FMOD/api/studio/examples/load_banks.cpp b/FMOD/api/studio/examples/load_banks.cpp new file mode 100644 index 0000000..aaafc61 --- /dev/null +++ b/FMOD/api/studio/examples/load_banks.cpp @@ -0,0 +1,427 @@ +/*============================================================================== +Load Banks Example +Copyright (c), Firelight Technologies Pty, Ltd 2012-2026. + +This example demonstrates loading banks via file, memory, and user callbacks. + +The banks that are loaded are: + +* SFX.bank (file) +* Music.bank (memory) +* Vehicles.bank (memory-point) +* VO.bank (custom) + +The loading and unloading is asynchronous, and we displays the current +state of each bank as loading is occuring. + +### See Also ### +* Studio::System::loadBankFile +* Studio::System::loadBankMemory +* Studio::System::loadBankCustom +* Studio::Bank::loadSampleData +* Studio::Bank::getLoadingState +* Studio::Bank::getSampleLoadingState +* Studio::Bank::getUserData +* Studio::Bank::setUserData + +For information on using FMOD example code in your own programs, visit +https://www.fmod.com/legal +==============================================================================*/ +#include "fmod_studio.hpp" +#include "fmod.hpp" +#include "common.h" +#include + +// +// Some platforms don't support cross platform fopen. Or you can disable this +// to see how the sample deals with bank load failures. +// +#ifdef COMMON_PLATFORM_SUPPORTS_FOPEN + #define ENABLE_FILE_OPEN +#endif + +// +// Load method as enum for our sample code +// +enum LoadBankMethod +{ + LoadBank_File, + LoadBank_Memory, + LoadBank_MemoryPoint, + LoadBank_Custom +}; +static const char* BANK_LOAD_METHOD_NAMES[] = +{ + "File", + "Memory", + "Memory-Point", + "Custom" +}; + +// +// Sanity check for loading files +// +#ifdef ENABLE_FILE_OPEN + static const size_t MAX_FILE_LENGTH = 2*1024*1024*1024ULL; +#endif + +// +// Custom callbacks that just wrap fopen +// +FMOD_RESULT F_CALL customFileOpen(const char *name, unsigned int *filesize, void **handle, void *userdata) +{ +#ifdef ENABLE_FILE_OPEN + // We pass the filename into our callbacks via userdata in the custom info struct + const char* filename = (const char*)userdata; + FILE* file = fopen(filename, "rb"); + if (!file) + { + return FMOD_ERR_FILE_NOTFOUND; + } + fseek(file, 0, SEEK_END); + size_t length = ftell(file); + fseek(file, 0, SEEK_SET); + if (length >= MAX_FILE_LENGTH) + { + fclose(file); + return FMOD_ERR_FILE_BAD; + } + *filesize = (unsigned int)length; + *handle = file; + return FMOD_OK; +#else + return FMOD_ERR_FILE_NOTFOUND; +#endif +} + +FMOD_RESULT F_CALL customFileClose(void *handle, void *userdata) +{ +#ifdef ENABLE_FILE_OPEN + FILE* file = (FILE*)handle; + fclose(file); +#endif + return FMOD_OK; +} + +FMOD_RESULT F_CALL customFileRead(void *handle, void *buffer, unsigned int sizebytes, unsigned int *bytesread, void *userdata) +{ + *bytesread = 0; +#ifdef ENABLE_FILE_OPEN + FILE* file = (FILE*)handle; + size_t read = fread(buffer, 1, sizebytes, file); + *bytesread = (unsigned int)read; + // If the request is larger than the bytes left in the file, then we must return EOF + if (read < sizebytes) + { + return FMOD_ERR_FILE_EOF; + } +#endif + return FMOD_OK; +} + +FMOD_RESULT F_CALL customFileSeek(void *handle, unsigned int pos, void *userdata) +{ +#ifdef ENABLE_FILE_OPEN + FILE* file = (FILE*)handle; + fseek(file, pos, SEEK_SET); +#endif + return FMOD_OK; +} + +// +// Helper function that loads a file into aligned memory buffer +// +FMOD_RESULT loadFile(const char* filename, char** memoryBase, char** memoryPtr, int* memoryLength) +{ + // If we don't support fopen then just return a single invalid byte for our file + size_t length = 1; + +#ifdef ENABLE_FILE_OPEN + FILE* file = fopen(filename, "rb"); + if (!file) + { + return FMOD_ERR_FILE_NOTFOUND; + } + fseek(file, 0, SEEK_END); + length = ftell(file); + fseek(file, 0, SEEK_SET); + if (length >= MAX_FILE_LENGTH) + { + fclose(file); + return FMOD_ERR_FILE_BAD; + } +#endif + + // Load into a pointer aligned to FMOD_STUDIO_LOAD_MEMORY_ALIGNMENT + char* membase = reinterpret_cast(malloc(length + FMOD_STUDIO_LOAD_MEMORY_ALIGNMENT)); + char* memptr = (char*)(((size_t)membase + (FMOD_STUDIO_LOAD_MEMORY_ALIGNMENT-1)) & ~(FMOD_STUDIO_LOAD_MEMORY_ALIGNMENT-1)); + +#ifdef ENABLE_FILE_OPEN + size_t bytesRead = fread(memptr, 1, length, file); + fclose(file); + if (bytesRead != length) + { + free(membase); + return FMOD_ERR_FILE_BAD; + } +#endif + + *memoryBase = membase; + *memoryPtr = memptr; + *memoryLength = (int)length; + return FMOD_OK; +} + +// +// Helper function that loads a bank in using the given method +// +FMOD_RESULT loadBank(FMOD::Studio::System* system, LoadBankMethod method, const char* filename, FMOD::Studio::Bank** bank) +{ + if (method == LoadBank_File) + { + return system->loadBankFile(filename, FMOD_STUDIO_LOAD_BANK_NONBLOCKING, bank); + } + else if (method == LoadBank_Memory || method == LoadBank_MemoryPoint) + { + char* memoryBase; + char* memoryPtr; + int memoryLength; + FMOD_RESULT result = loadFile(filename, &memoryBase, &memoryPtr, &memoryLength); + if (result != FMOD_OK) + { + return result; + } + + FMOD_STUDIO_LOAD_MEMORY_MODE memoryMode = (method == LoadBank_MemoryPoint ? FMOD_STUDIO_LOAD_MEMORY_POINT : FMOD_STUDIO_LOAD_MEMORY); + result = system->loadBankMemory(memoryPtr, memoryLength, memoryMode, FMOD_STUDIO_LOAD_BANK_NONBLOCKING, bank); + if (result != FMOD_OK) + { + free(memoryBase); + return result; + } + + if (method == LoadBank_MemoryPoint) + { + // Keep memory around until bank unload completes + result = (*bank)->setUserData(memoryBase); + } + else + { + // Don't need memory any more + free(memoryBase); + } + return result; + } + else + { + // Set up custom callback + FMOD_STUDIO_BANK_INFO info; + memset(&info, 0, sizeof(info)); + info.size = sizeof(info); + info.opencallback = customFileOpen; + info.closecallback = customFileClose; + info.readcallback = customFileRead; + info.seekcallback = customFileSeek; + info.userdata = (void*)filename; + + return system->loadBankCustom(&info, FMOD_STUDIO_LOAD_BANK_NONBLOCKING, bank); + } +} + +// +// Helper function to return state as a string +// +const char* getLoadingStateString(FMOD_STUDIO_LOADING_STATE state, FMOD_RESULT loadResult) +{ + switch (state) + { + case FMOD_STUDIO_LOADING_STATE_UNLOADING: + return "unloading "; + case FMOD_STUDIO_LOADING_STATE_UNLOADED: + return "unloaded "; + case FMOD_STUDIO_LOADING_STATE_LOADING: + return "loading "; + case FMOD_STUDIO_LOADING_STATE_LOADED: + return "loaded "; + case FMOD_STUDIO_LOADING_STATE_ERROR: + // Show some common errors + if (loadResult == FMOD_ERR_NOTREADY) + { + return "error (rdy)"; + } + else if (loadResult == FMOD_ERR_FILE_BAD) + { + return "error (bad)"; + } + else if (loadResult == FMOD_ERR_FILE_NOTFOUND) + { + return "error (mis)"; + } + else + { + return "error "; + } + default: + return "???"; + }; +} + +// +// Helper function to return handle validity as a string. +// Just because the bank handle is valid doesn't mean the bank load +// has completed successfully! +// +const char* getHandleStateString(FMOD::Studio::Bank* bank) +{ + if (bank == NULL) + { + return "null "; + } + else if (!bank->isValid()) + { + return "invalid"; + } + else + { + return "valid "; + } +} + +// +// Callback to free memory-point allocation when it is safe to do so +// +FMOD_RESULT F_CALL studioCallback(FMOD_STUDIO_SYSTEM *system, FMOD_STUDIO_SYSTEM_CALLBACK_TYPE type, void *commanddata, void *userdata) +{ + if (type == FMOD_STUDIO_SYSTEM_CALLBACK_BANK_UNLOAD) + { + // For memory-point, it is now safe to free our memory + FMOD::Studio::Bank* bank = (FMOD::Studio::Bank*)commanddata; + void* memory; + ERRCHECK(bank->getUserData(&memory)); + if (memory) + { + free(memory); + } + } + return FMOD_OK; +} + +// +// Main example code +// +int FMOD_Main() +{ + void *extraDriverData = 0; + Common_Init(&extraDriverData); + + FMOD::Studio::System* system; + ERRCHECK( FMOD::Studio::System::create(&system) ); + ERRCHECK( system->initialize(1024, FMOD_STUDIO_INIT_NORMAL, FMOD_INIT_NORMAL, extraDriverData) ); + ERRCHECK( system->setCallback(studioCallback, FMOD_STUDIO_SYSTEM_CALLBACK_BANK_UNLOAD) ); + + static const int BANK_COUNT = 4; + static const char* BANK_NAMES[] = + { + "SFX.bank", + "Music.bank", + "Vehicles.bank", + "VO.bank", + }; + + FMOD::Studio::Bank* banks[BANK_COUNT] = {0}; + bool wantBankLoaded[BANK_COUNT] = {0}; + bool wantSampleLoad = true; + + do + { + Common_Update(); + + for (int i=0; iunload()); + wantBankLoaded[i] = false; + } + } + } + if (Common_BtnPress(BTN_MORE)) + { + wantSampleLoad = !wantSampleLoad; + } + + // Load bank sample data automatically if that mode is enabled + // Also query current status for text display + FMOD_RESULT loadStateResult[BANK_COUNT] = { FMOD_OK, FMOD_OK, FMOD_OK, FMOD_OK, }; + FMOD_RESULT sampleStateResult[BANK_COUNT] = { FMOD_OK, FMOD_OK, FMOD_OK, FMOD_OK, }; + FMOD_STUDIO_LOADING_STATE bankLoadState[BANK_COUNT] = { FMOD_STUDIO_LOADING_STATE_UNLOADED, FMOD_STUDIO_LOADING_STATE_UNLOADED, FMOD_STUDIO_LOADING_STATE_UNLOADED, FMOD_STUDIO_LOADING_STATE_UNLOADED }; + FMOD_STUDIO_LOADING_STATE sampleLoadState[BANK_COUNT] = { FMOD_STUDIO_LOADING_STATE_UNLOADED, FMOD_STUDIO_LOADING_STATE_UNLOADED, FMOD_STUDIO_LOADING_STATE_UNLOADED, FMOD_STUDIO_LOADING_STATE_UNLOADED }; + for (int i=0; iisValid()) + { + loadStateResult[i] = banks[i]->getLoadingState(&bankLoadState[i]); + } + if (bankLoadState[i] == FMOD_STUDIO_LOADING_STATE_LOADED) + { + sampleStateResult[i] = banks[i]->getSampleLoadingState(&sampleLoadState[i]); + if (wantSampleLoad && sampleLoadState[i] == FMOD_STUDIO_LOADING_STATE_UNLOADED) + { + ERRCHECK(banks[i]->loadSampleData()); + } + else if (!wantSampleLoad && (sampleLoadState[i] == FMOD_STUDIO_LOADING_STATE_LOADING || sampleLoadState[i] == FMOD_STUDIO_LOADING_STATE_LOADED)) + { + ERRCHECK(banks[i]->unloadSampleData()); + } + } + } + + ERRCHECK( system->update() ); + + Common_Draw("=================================================="); + Common_Draw("Bank Load Example."); + Common_Draw("Copyright (c) Firelight Technologies 2012-2026."); + Common_Draw("=================================================="); + Common_Draw("Name Handle Bank-State Sample-State"); + + for (int i=0; iunloadAll() ); + ERRCHECK( system->flushCommands() ); + ERRCHECK( system->release() ); + + Common_Close(); + + return 0; +} diff --git a/FMOD/api/studio/examples/media/640148main_APU Shutdown.ogg b/FMOD/api/studio/examples/media/640148main_APU Shutdown.ogg new file mode 100644 index 0000000..7c8c88b Binary files /dev/null and b/FMOD/api/studio/examples/media/640148main_APU Shutdown.ogg differ diff --git a/FMOD/api/studio/examples/media/640165main_Lookin At It.ogg b/FMOD/api/studio/examples/media/640165main_Lookin At It.ogg new file mode 100644 index 0000000..b0e4008 Binary files /dev/null and b/FMOD/api/studio/examples/media/640165main_Lookin At It.ogg differ diff --git a/FMOD/api/studio/examples/media/640166main_MECO.ogg b/FMOD/api/studio/examples/media/640166main_MECO.ogg new file mode 100644 index 0000000..c775fb1 Binary files /dev/null and b/FMOD/api/studio/examples/media/640166main_MECO.ogg differ diff --git a/FMOD/api/studio/examples/media/640169main_Press to ATO.ogg b/FMOD/api/studio/examples/media/640169main_Press to ATO.ogg new file mode 100644 index 0000000..644ed1f Binary files /dev/null and b/FMOD/api/studio/examples/media/640169main_Press to ATO.ogg differ diff --git a/FMOD/api/studio/examples/media/Dialogue_CN.bank b/FMOD/api/studio/examples/media/Dialogue_CN.bank new file mode 100644 index 0000000..18e0561 Binary files /dev/null and b/FMOD/api/studio/examples/media/Dialogue_CN.bank differ diff --git a/FMOD/api/studio/examples/media/Dialogue_EN.bank b/FMOD/api/studio/examples/media/Dialogue_EN.bank new file mode 100644 index 0000000..34ff7eb Binary files /dev/null and b/FMOD/api/studio/examples/media/Dialogue_EN.bank differ diff --git a/FMOD/api/studio/examples/media/Dialogue_JP.bank b/FMOD/api/studio/examples/media/Dialogue_JP.bank new file mode 100644 index 0000000..1f48d59 Binary files /dev/null and b/FMOD/api/studio/examples/media/Dialogue_JP.bank differ diff --git a/FMOD/api/studio/examples/media/Master.bank b/FMOD/api/studio/examples/media/Master.bank new file mode 100644 index 0000000..98366d0 Binary files /dev/null and b/FMOD/api/studio/examples/media/Master.bank differ diff --git a/FMOD/api/studio/examples/media/Master.strings.bank b/FMOD/api/studio/examples/media/Master.strings.bank new file mode 100644 index 0000000..d479933 Binary files /dev/null and b/FMOD/api/studio/examples/media/Master.strings.bank differ diff --git a/FMOD/api/studio/examples/media/Music.bank b/FMOD/api/studio/examples/media/Music.bank new file mode 100644 index 0000000..56dcc1b Binary files /dev/null and b/FMOD/api/studio/examples/media/Music.bank differ diff --git a/FMOD/api/studio/examples/media/SFX.bank b/FMOD/api/studio/examples/media/SFX.bank new file mode 100644 index 0000000..6ad07ce Binary files /dev/null and b/FMOD/api/studio/examples/media/SFX.bank differ diff --git a/FMOD/api/studio/examples/media/VO.bank b/FMOD/api/studio/examples/media/VO.bank new file mode 100644 index 0000000..90511d3 Binary files /dev/null and b/FMOD/api/studio/examples/media/VO.bank differ diff --git a/FMOD/api/studio/examples/media/Vehicles.bank b/FMOD/api/studio/examples/media/Vehicles.bank new file mode 100644 index 0000000..9792c52 Binary files /dev/null and b/FMOD/api/studio/examples/media/Vehicles.bank differ diff --git a/FMOD/api/studio/examples/media/programmer_sound.fsb b/FMOD/api/studio/examples/media/programmer_sound.fsb new file mode 100644 index 0000000..936a7bf Binary files /dev/null and b/FMOD/api/studio/examples/media/programmer_sound.fsb differ diff --git a/FMOD/api/studio/examples/music_callbacks.cpp b/FMOD/api/studio/examples/music_callbacks.cpp new file mode 100644 index 0000000..08de0a6 --- /dev/null +++ b/FMOD/api/studio/examples/music_callbacks.cpp @@ -0,0 +1,175 @@ +/*============================================================================== +Music Callback Example +Copyright (c), Firelight Technologies Pty, Ltd 2012-2026. + +This example demonstrates beat and named marker callbacks when playing music. + +### See Also ### +* Studio::EventInstance::setCallback +* FMOD_STUDIO_EVENT_CALLBACK_TIMELINE_MARKER +* FMOD_STUDIO_EVENT_CALLBACK_TIMELINE_BEAT + +For information on using FMOD example code in your own programs, visit +https://www.fmod.com/legal +==============================================================================*/ +#include "fmod_studio.hpp" +#include "fmod.hpp" +#include "common.h" +#include +#include + +static const int MAX_ENTRIES = 6; + +struct CallbackInfo +{ + Common_Mutex mMutex; + std::vector mEntries; +}; + +FMOD_RESULT F_CALL markerCallback(FMOD_STUDIO_EVENT_CALLBACK_TYPE type, FMOD_STUDIO_EVENTINSTANCE* event, void *parameters); + +int FMOD_Main() +{ + void *extraDriverData = NULL; + Common_Init(&extraDriverData); + + FMOD::Studio::System* system = NULL; + ERRCHECK( FMOD::Studio::System::create(&system) ); + + // The example Studio project is authored for 5.1 sound, so set up the system output mode to match + FMOD::System* coreSystem = NULL; + ERRCHECK( system->getCoreSystem(&coreSystem) ); + ERRCHECK( coreSystem->setSoftwareFormat(0, FMOD_SPEAKERMODE_5POINT1, 0) ); + + ERRCHECK( system->initialize(1024, FMOD_STUDIO_INIT_NORMAL, FMOD_INIT_NORMAL, extraDriverData) ); + + FMOD::Studio::Bank* masterBank = NULL; + ERRCHECK( system->loadBankFile(Common_MediaPath("Master.bank"), FMOD_STUDIO_LOAD_BANK_NORMAL, &masterBank) ); + + FMOD::Studio::Bank* stringsBank = NULL; + ERRCHECK( system->loadBankFile(Common_MediaPath("Master.strings.bank"), FMOD_STUDIO_LOAD_BANK_NORMAL, &stringsBank) ); + + FMOD::Studio::Bank* musicBank = NULL; + FMOD_RESULT result = system->loadBankFile(Common_MediaPath("Music.bank"), FMOD_STUDIO_LOAD_BANK_NORMAL, &musicBank); + if (result != FMOD_OK) + { + // Music bank is not exported by default, you will have to export from the tool first + Common_Fatal("Please export music.bank from the Studio tool to run this example"); + } + + FMOD::Studio::EventDescription* eventDescription = NULL; + ERRCHECK( system->getEvent("event:/Music/Level 01", &eventDescription) ); + + FMOD::Studio::EventInstance* eventInstance = NULL; + ERRCHECK( eventDescription->createInstance(&eventInstance) ); + + CallbackInfo info; + Common_Mutex_Create(&info.mMutex); + + ERRCHECK( eventInstance->setUserData(&info) ); + ERRCHECK( eventInstance->setCallback(markerCallback, + FMOD_STUDIO_EVENT_CALLBACK_TIMELINE_MARKER | FMOD_STUDIO_EVENT_CALLBACK_TIMELINE_BEAT | + FMOD_STUDIO_EVENT_CALLBACK_SOUND_PLAYED | FMOD_STUDIO_EVENT_CALLBACK_SOUND_STOPPED) ); + ERRCHECK( eventInstance->start() ); + + FMOD_STUDIO_PARAMETER_DESCRIPTION parameterDescription; + ERRCHECK( eventDescription->getParameterDescriptionByName("Progression", ¶meterDescription) ); + + FMOD_STUDIO_PARAMETER_ID progressionID = parameterDescription.id; + + float progression = 0.0f; + ERRCHECK(eventInstance->setParameterByID(progressionID, progression)); + + do + { + Common_Update(); + + if (Common_BtnPress(BTN_MORE)) + { + progression = (progression == 0.0f ? 1.0f : 0.0f); + ERRCHECK(eventInstance->setParameterByID(progressionID, progression)); + } + + ERRCHECK( system->update() ); + + int position; + ERRCHECK( eventInstance->getTimelinePosition(&position) ); + + Common_Draw("=================================================="); + Common_Draw("Music Callback Example."); + Common_Draw("Copyright (c) Firelight Technologies 2012-2026."); + Common_Draw("=================================================="); + Common_Draw(""); + Common_Draw("Timeline = %d", position); + Common_Draw(""); + // Obtain lock and look at our strings + Common_Mutex_Enter(&info.mMutex); + for (size_t i=0; irelease() ); + + Common_Mutex_Destroy(&info.mMutex); + Common_Close(); + + return 0; +} + +// Obtain a lock and add a string entry to our list +void markerAddString(CallbackInfo* info, const char* format, ...) +{ + char buf[256]; + va_list args; + va_start(args, format); + Common_vsnprintf(buf, 256, format, args); + va_end(args); + buf[255] = '\0'; + Common_Mutex_Enter(&info->mMutex); + if (info->mEntries.size() >= MAX_ENTRIES) + { + info->mEntries.erase(info->mEntries.begin()); + } + info->mEntries.push_back(std::string(buf)); + Common_Mutex_Leave(&info->mMutex); +} + +// Callback from Studio - Remember these callbacks will occur in the Studio update thread, NOT the game thread. +FMOD_RESULT F_CALL markerCallback(FMOD_STUDIO_EVENT_CALLBACK_TYPE type, FMOD_STUDIO_EVENTINSTANCE* event, void *parameters) +{ + CallbackInfo* callbackInfo; + ERRCHECK(((FMOD::Studio::EventInstance*)event)->getUserData((void**)&callbackInfo)); + + if (type == FMOD_STUDIO_EVENT_CALLBACK_TIMELINE_MARKER) + { + FMOD_STUDIO_TIMELINE_MARKER_PROPERTIES* props = (FMOD_STUDIO_TIMELINE_MARKER_PROPERTIES*)parameters; + markerAddString(callbackInfo, "Named marker '%s'", props->name); + } + else if (type == FMOD_STUDIO_EVENT_CALLBACK_TIMELINE_BEAT) + { + FMOD_STUDIO_TIMELINE_BEAT_PROPERTIES* props = (FMOD_STUDIO_TIMELINE_BEAT_PROPERTIES*)parameters; + markerAddString(callbackInfo, "beat %d, bar %d (tempo %.1f %d:%d)", props->beat, props->bar, props->tempo, props->timesignatureupper, props->timesignaturelower); + } + if (type == FMOD_STUDIO_EVENT_CALLBACK_SOUND_PLAYED || type == FMOD_STUDIO_EVENT_CALLBACK_SOUND_STOPPED) + { + FMOD::Sound* sound = (FMOD::Sound*)parameters; + char name[256]; + ERRCHECK(sound->getName(name, 256)); + unsigned int len; + ERRCHECK(sound->getLength(&len, FMOD_TIMEUNIT_MS)); + + markerAddString(callbackInfo, "Sound '%s' (length %.3f) %s", + name, (float)len/1000.0f, + type == FMOD_STUDIO_EVENT_CALLBACK_SOUND_PLAYED ? "Started" : "Stopped"); + } + + return FMOD_OK; +} diff --git a/FMOD/api/studio/examples/objectpan.cpp b/FMOD/api/studio/examples/objectpan.cpp new file mode 100644 index 0000000..8d70318 --- /dev/null +++ b/FMOD/api/studio/examples/objectpan.cpp @@ -0,0 +1,189 @@ +/*============================================================================== +Object Panning Example +Copyright (c), Firelight Technologies Pty, Ltd 2015-2026. + +This example demonstrates the FMOD object panner. The usage is completely +transparent to the API, the only difference is how the event is authored in the +FMOD Studio tool. + +To hear the difference between object panning and normal panning this example +has two events (one configured with the normal panner, and one with the object +panner). As they move around the listener you may toggle between panning method +and two different sounds. + +Object panning requires compatible hardware such as a Dolby Atmos amplifier or +a Playstation VR headset. For cases when the necessary hardware is not available +FMOD will fallback to standard 3D panning. + +For information on using FMOD example code in your own programs, visit +https://www.fmod.com/legal +==============================================================================*/ +#include "fmod_studio.hpp" +#include "fmod.hpp" +#include "common.h" +#include + +int FMOD_Main() +{ + bool isOnGround = false; + bool useListenerAttenuationPosition = false; + + void *extraDriverData = NULL; + Common_Init(&extraDriverData); + + FMOD::Studio::System *system = NULL; + ERRCHECK( FMOD::Studio::System::create(&system) ); + + // The example Studio project is authored for 5.1 sound, so set up the system output mode to match + FMOD::System* coreSystem = NULL; + ERRCHECK( system->getCoreSystem(&coreSystem) ); + ERRCHECK( coreSystem->setSoftwareFormat(0, FMOD_SPEAKERMODE_5POINT1, 0) ); + + // Attempt to initialize with a compatible object panning output + FMOD_RESULT result = coreSystem->setOutput(FMOD_OUTPUTTYPE_AUDIO3D); + if (result != FMOD_OK) + { + result = coreSystem->setOutput(FMOD_OUTPUTTYPE_WINSONIC); + if (result == FMOD_OK) + { + ERRCHECK( coreSystem->setSoftwareFormat(0, FMOD_SPEAKERMODE_7POINT1POINT4, 0) ); + } + else + { + result = coreSystem->setOutput(FMOD_OUTPUTTYPE_PHASE); + if (result == FMOD_OK) + { + ERRCHECK( coreSystem->setSoftwareFormat(0, FMOD_SPEAKERMODE_7POINT1POINT4, 0) ); + } + } + } + + int numDrivers = 0; + ERRCHECK( coreSystem->getNumDrivers(&numDrivers) ); + + if (numDrivers == 0) + { + ERRCHECK( coreSystem->setDSPBufferSize(512, 4) ); + ERRCHECK( coreSystem->setOutput(FMOD_OUTPUTTYPE_AUTODETECT) ); + } + + // Due to a bug in WinSonic on Windows, FMOD initialization may fail on some machines. + // If you get the error "FMOD error 51 - Error initializing output device", try using + // a different output type such as FMOD_OUTPUTTYPE_AUTODETECT + ERRCHECK( system->initialize(1024, FMOD_STUDIO_INIT_NORMAL, FMOD_INIT_NORMAL, extraDriverData) ); + + // Load everything needed for playback + FMOD::Studio::Bank *masterBank = NULL; + FMOD::Studio::Bank *musicBank = NULL; + FMOD::Studio::Bank *stringsBank = NULL; + FMOD::Studio::EventDescription *spatializerDescription = NULL; + FMOD::Studio::EventInstance *spatializerInstance = NULL; + float spatializer; + float radioFrequency; + + ERRCHECK( system->loadBankFile(Common_MediaPath("Master.bank"), FMOD_STUDIO_LOAD_BANK_NORMAL, &masterBank) ); + ERRCHECK( system->loadBankFile(Common_MediaPath("Music.bank"), FMOD_STUDIO_LOAD_BANK_NORMAL, &musicBank) ); + ERRCHECK( system->loadBankFile(Common_MediaPath("Master.strings.bank"), FMOD_STUDIO_LOAD_BANK_NORMAL, &stringsBank) ); + ERRCHECK( system->getEvent("event:/Music/Radio Station", &spatializerDescription) ); + ERRCHECK( spatializerDescription->createInstance(&spatializerInstance) ); + ERRCHECK( spatializerInstance->start() ); + + do + { + Common_Update(); + + ERRCHECK(spatializerInstance->getParameterByName("Freq", NULL, &radioFrequency)); + ERRCHECK(spatializerInstance->getParameterByName("Spatializer", NULL, &spatializer)); + + if (Common_BtnPress(BTN_ACTION1)) + { + if (radioFrequency == 3.00f) + { + ERRCHECK(spatializerInstance->setParameterByName("Freq", 0.00f)); + } + else + { + ERRCHECK(spatializerInstance->setParameterByName("Freq", (radioFrequency + 1.50f))); + } + } + + if (Common_BtnPress(BTN_ACTION2)) + { + if (spatializer == 1.00) + { + ERRCHECK(spatializerInstance->setParameterByName("Spatializer", 0.00f)); + } + else + { + ERRCHECK(spatializerInstance->setParameterByName("Spatializer", 1.00f)); + } + } + + if (Common_BtnPress(BTN_ACTION3)) + { + isOnGround = !isOnGround; + } + + if (Common_BtnPress(BTN_ACTION4)) + { + useListenerAttenuationPosition = !useListenerAttenuationPosition; + } + + FMOD_3D_ATTRIBUTES vec = { }; + vec.forward.z = 1.0f; + vec.up.y = 1.0f; + static float t = 0; + vec.position.x = sinf(t) * 3.0f; /* Rotate sound in a circle */ + vec.position.z = cosf(t) * 3.0f; /* Rotate sound in a circle */ + t += 0.03f; + + if (isOnGround) + { + vec.position.y = 0; /* At ground level */ + } + else + { + vec.position.y = 5.0f; /* Up high */ + } + + ERRCHECK( spatializerInstance->set3DAttributes(&vec) ); + + FMOD_3D_ATTRIBUTES listener_vec = { }; + listener_vec.forward.z = 1.0f; + listener_vec.up.y = 1.0f; + + FMOD_VECTOR listener_attenuationPos = vec.position; + listener_attenuationPos.z -= -10.0f; + + ERRCHECK( system->setListenerAttributes(0, &listener_vec, useListenerAttenuationPosition ? &listener_attenuationPos : nullptr) ); + ERRCHECK( system->update() ); + + const char *radioString = (radioFrequency == 0.00f) ? "Rock" : (radioFrequency == 1.50f) ? "Lo-fi" : "Hip hop"; + const char *spatialString = (spatializer == 0.00f) ? "Standard 3D Spatializer" : "Object Spatializer"; + + Common_Draw("=================================================="); + Common_Draw("Object Panning Example."); + Common_Draw("Copyright (c) Firelight Technologies 2015-2026."); + Common_Draw("=================================================="); + Common_Draw(""); + Common_Draw("Playing %s with the %s.", radioString, spatialString); + Common_Draw("Radio is %s.", isOnGround ? "on the ground" : "up in the air"); + Common_Draw(""); + Common_Draw("Press %s to switch stations.", Common_BtnStr(BTN_ACTION1)); + Common_Draw("Press %s to switch spatializer.", Common_BtnStr(BTN_ACTION2)); + Common_Draw("Press %s to elevate the event instance.", Common_BtnStr(BTN_ACTION3)); + Common_Draw("Press %s to %s use of attenuation position.", Common_BtnStr(BTN_ACTION4), useListenerAttenuationPosition ? "disable" : "enable"); + Common_Draw(""); + Common_Draw("Press %s to quit", Common_BtnStr(BTN_QUIT)); + + Common_Sleep(50); + } while (!Common_BtnPress(BTN_QUIT)); + + ERRCHECK( stringsBank->unload() ); + ERRCHECK( musicBank->unload() ); + ERRCHECK( system->release() ); + + Common_Close(); + + return 0; +} diff --git a/FMOD/api/studio/examples/programmer_sound.cpp b/FMOD/api/studio/examples/programmer_sound.cpp new file mode 100644 index 0000000..7ecbef8 --- /dev/null +++ b/FMOD/api/studio/examples/programmer_sound.cpp @@ -0,0 +1,177 @@ +/*============================================================================== +Programmer Sound Example +Copyright (c), Firelight Technologies Pty, Ltd 2012-2026. + +This example demonstrates how to implement the programmer sound callback to +play an event that has a programmer specified sound. + +### See Also ### +Studio::EventInstance::setCallback + +For information on using FMOD example code in your own programs, visit +https://www.fmod.com/legal +==============================================================================*/ +#include "fmod_studio.hpp" +#include "fmod.hpp" +#include "common.h" + +struct ProgrammerSoundContext +{ + const char* dialogueString; +}; + +FMOD_RESULT F_CALL programmerSoundCallback(FMOD_STUDIO_EVENT_CALLBACK_TYPE type, FMOD_STUDIO_EVENTINSTANCE* event, void *parameters); + +int FMOD_Main() +{ + void *extraDriverData = NULL; + Common_Init(&extraDriverData); + + FMOD::Studio::System* system = NULL; + ERRCHECK( FMOD::Studio::System::create(&system) ); + + // The example Studio project is authored for 5.1 sound, so set up the system output mode to match + FMOD::System* coreSystem = NULL; + ERRCHECK( system->getCoreSystem(&coreSystem) ); + ERRCHECK( coreSystem->setSoftwareFormat(0, FMOD_SPEAKERMODE_5POINT1, 0) ); + + ERRCHECK( system->initialize(1024, FMOD_STUDIO_INIT_NORMAL, FMOD_INIT_NORMAL, extraDriverData) ); + + FMOD::Studio::Bank* masterBank = NULL; + ERRCHECK( system->loadBankFile(Common_MediaPath("Master.bank"), FMOD_STUDIO_LOAD_BANK_NORMAL, &masterBank) ); + + FMOD::Studio::Bank* stringsBank = NULL; + ERRCHECK( system->loadBankFile(Common_MediaPath("Master.strings.bank"), FMOD_STUDIO_LOAD_BANK_NORMAL, &stringsBank) ); + + FMOD::Studio::Bank* sfxBank = NULL; + ERRCHECK( system->loadBankFile(Common_MediaPath("SFX.bank"), FMOD_STUDIO_LOAD_BANK_NORMAL, &sfxBank) ); + + // Available banks + unsigned int bankIndex = 0; + static const char* const banks[] = { "Dialogue_EN.bank", "Dialogue_JP.bank", "Dialogue_CN.bank" }; + + FMOD::Studio::Bank* localizedBank = NULL; + ERRCHECK( system->loadBankFile(Common_MediaPath(banks[bankIndex]), FMOD_STUDIO_LOAD_BANK_NORMAL, &localizedBank) ); + + FMOD::Studio::EventDescription* eventDescription = NULL; + ERRCHECK( system->getEvent("event:/Character/Dialogue", &eventDescription) ); + + FMOD::Studio::EventInstance* eventInstance = NULL; + ERRCHECK( eventDescription->createInstance(&eventInstance) ); + + // Dialogue keys available + // These keys are shared amongst all audio tables + unsigned int dialogueIndex = 0; + static const char* const dialogue[] = {"welcome", "main menu", "goodbye"}; + + ProgrammerSoundContext programmerSoundContext; + programmerSoundContext.dialogueString = dialogue[dialogueIndex]; + + ERRCHECK( eventInstance->setUserData(&programmerSoundContext) ); + ERRCHECK( eventInstance->setCallback(programmerSoundCallback, FMOD_STUDIO_EVENT_CALLBACK_CREATE_PROGRAMMER_SOUND | FMOD_STUDIO_EVENT_CALLBACK_DESTROY_PROGRAMMER_SOUND) ); + + do + { + Common_Update(); + + if (Common_BtnPress(BTN_ACTION1)) + { + ERRCHECK( localizedBank->unload() ); + + bankIndex = (bankIndex < 2) ? bankIndex + 1 : 0; + ERRCHECK( system->loadBankFile(Common_MediaPath(banks[bankIndex]), FMOD_STUDIO_LOAD_BANK_NORMAL, &localizedBank) ); + } + + if (Common_BtnPress(BTN_ACTION2)) + { + dialogueIndex = (dialogueIndex < 2) ? dialogueIndex + 1 : 0; + programmerSoundContext.dialogueString = dialogue[dialogueIndex]; + } + + if (Common_BtnPress(BTN_MORE)) + { + ERRCHECK( eventInstance->start() ); + } + + ERRCHECK( system->update() ); + + Common_Draw("=================================================="); + Common_Draw("Programmer Sound Example."); + Common_Draw("Copyright (c) Firelight Technologies 2012-2026."); + Common_Draw("=================================================="); + Common_Draw(""); + Common_Draw("Press %s to change language", Common_BtnStr(BTN_ACTION1)); + Common_Draw("Press %s to change dialogue", Common_BtnStr(BTN_ACTION2)); + Common_Draw("Press %s to play the event", Common_BtnStr(BTN_MORE)); + Common_Draw(""); + Common_Draw("Language:"); + Common_Draw(" %s English", bankIndex == 0 ? ">" : " "); + Common_Draw(" %s Japanese", bankIndex == 1 ? ">" : " "); + Common_Draw(" %s Chinese", bankIndex == 2 ? ">" : " "); + Common_Draw(""); + Common_Draw("Dialogue:"); + Common_Draw(" %s Welcome to the FMOD Studio tutorial", dialogueIndex == 0 ? ">" : " "); + Common_Draw(" %s This is the main menu", dialogueIndex == 1 ? ">" : " "); + Common_Draw(" %s Goodbye", dialogueIndex == 2 ? ">" : " "); + Common_Draw(""); + Common_Draw("Press %s to quit", Common_BtnStr(BTN_QUIT)); + + Common_Sleep(50); + } while (!Common_BtnPress(BTN_QUIT)); + + ERRCHECK( system->release() ); + + Common_Close(); + + return 0; +} + +#define CHECK_RESULT(op) \ + { \ + FMOD_RESULT res = (op); \ + if (res != FMOD_OK) \ + { \ + return res; \ + } \ + } + +FMOD_RESULT F_CALL programmerSoundCallback(FMOD_STUDIO_EVENT_CALLBACK_TYPE type, FMOD_STUDIO_EVENTINSTANCE* event, void *parameters) +{ + FMOD::Studio::EventInstance* eventInstance = (FMOD::Studio::EventInstance*)event; + + if (type == FMOD_STUDIO_EVENT_CALLBACK_CREATE_PROGRAMMER_SOUND) + { + FMOD_STUDIO_PROGRAMMER_SOUND_PROPERTIES* props = (FMOD_STUDIO_PROGRAMMER_SOUND_PROPERTIES*)parameters; + + // Get our context from the event instance user data + ProgrammerSoundContext* context = NULL; + CHECK_RESULT( eventInstance->getUserData((void**)&context) ); + + FMOD::Studio::System* studioSystem = NULL; + CHECK_RESULT( eventInstance->getSystem(&studioSystem) ); + // Find the audio file in the audio table with the key + FMOD_STUDIO_SOUND_INFO info; + CHECK_RESULT( studioSystem->getSoundInfo(context->dialogueString, &info) ); + + FMOD::System* coreSystem = NULL; + CHECK_RESULT( studioSystem->getCoreSystem(&coreSystem) ); + FMOD::Sound* sound = NULL; + CHECK_RESULT( coreSystem->createSound(info.name_or_data, FMOD_LOOP_NORMAL | FMOD_CREATECOMPRESSEDSAMPLE | FMOD_NONBLOCKING | info.mode, &info.exinfo, &sound) ); + + // Pass the sound to FMOD + props->sound = (FMOD_SOUND*)sound; + props->subsoundIndex = info.subsoundindex; + } + else if (type == FMOD_STUDIO_EVENT_CALLBACK_DESTROY_PROGRAMMER_SOUND) + { + FMOD_STUDIO_PROGRAMMER_SOUND_PROPERTIES* props = (FMOD_STUDIO_PROGRAMMER_SOUND_PROPERTIES*)parameters; + + // Obtain the sound + FMOD::Sound* sound = (FMOD::Sound*)props->sound; + + // Release the sound + CHECK_RESULT( sound->release() ); + } + + return FMOD_OK; +} \ No newline at end of file diff --git a/FMOD/api/studio/examples/recording_playback.cpp b/FMOD/api/studio/examples/recording_playback.cpp new file mode 100644 index 0000000..4b34931 --- /dev/null +++ b/FMOD/api/studio/examples/recording_playback.cpp @@ -0,0 +1,373 @@ +/*============================================================================== +API Recording Example +Copyright (c), Firelight Technologies Pty, Ltd 2012-2026. + +This example shows recording and playback functionality, allowing the user to +trigger some sounds and then play back what they have recorded. The provided +functionality is intended to assist in debugging. + +For information on using FMOD example code in your own programs, visit +https://www.fmod.com/legal +==============================================================================*/ +#include "fmod_studio.hpp" +#include "fmod.hpp" +#include "common.h" + +const int SCREEN_WIDTH = NUM_COLUMNS; +const int SCREEN_HEIGHT = 10; + +int currentScreenPosition = -1; +char screenBuffer[(SCREEN_WIDTH + 1) * SCREEN_HEIGHT + 1] = {0}; + +void initializeScreenBuffer(); +void updateScreenPosition(const FMOD_VECTOR& worldPosition); + +static const char* RECORD_FILENAME = "playback.cmd.txt"; + +enum State +{ + State_Selection, + State_Record, + State_Playback, + State_Quit +}; + +State executeSelection(FMOD::Studio::System* system); +State executeRecord(FMOD::Studio::System* system); +State executePlayback(FMOD::Studio::System* system); + +int FMOD_Main() +{ + void *extraDriverData = 0; + Common_Init(&extraDriverData); + + FMOD::Studio::System* system = NULL; + ERRCHECK( FMOD::Studio::System::create(&system) ); + + // The example Studio project is authored for 5.1 sound, so set up the system output mode to match + FMOD::System* coreSystem = NULL; + ERRCHECK( system->getCoreSystem(&coreSystem) ); + ERRCHECK( coreSystem->setSoftwareFormat(0, FMOD_SPEAKERMODE_5POINT1, 0) ); + + ERRCHECK( system->initialize(1024, FMOD_STUDIO_INIT_NORMAL, FMOD_INIT_NORMAL, extraDriverData) ); + + State state = State_Selection; + while (state != State_Quit) + { + switch (state) + { + case State_Selection: + state = executeSelection(system); + break; + case State_Record: + state = executeRecord(system); + break; + case State_Playback: + state = executePlayback(system); + break; + case State_Quit: + break; + }; + }; + + ERRCHECK( system->release() ); + + Common_Close(); + + return 0; +} + +// Show the main selection menu +State executeSelection(FMOD::Studio::System* system) +{ + for (;;) + { + Common_Update(); + + if (Common_BtnPress(BTN_ACTION1)) + { + return State_Record; + } + if (Common_BtnPress(BTN_ACTION2)) + { + return State_Playback; + } + if (Common_BtnPress(BTN_QUIT)) + { + return State_Quit; + } + + ERRCHECK( system->update() ); + + Common_Draw("=================================================="); + Common_Draw("Recording and playback example."); + Common_Draw("Copyright (c) Firelight Technologies 2012-2026."); + Common_Draw("=================================================="); + Common_Draw(""); + Common_Draw("Waiting to start recording"); + Common_Draw(""); + Common_Draw("Press %s to start recording", Common_BtnStr(BTN_ACTION1)); + Common_Draw("Press %s to play back recording", Common_BtnStr(BTN_ACTION2)); + Common_Draw("Press %s to quit", Common_BtnStr(BTN_QUIT)); + Common_Draw(""); + Common_Sleep(50); + } +} + +// Start recording, load banks and then let the user trigger some sounds +State executeRecord(FMOD::Studio::System* system) +{ + FMOD::Studio::Bank* masterBank = NULL; + ERRCHECK( system->loadBankFile(Common_MediaPath("Master.bank"), FMOD_STUDIO_LOAD_BANK_NONBLOCKING, &masterBank) ); + + FMOD::Studio::Bank* stringsBank = NULL; + ERRCHECK( system->loadBankFile(Common_MediaPath("Master.strings.bank"), FMOD_STUDIO_LOAD_BANK_NONBLOCKING, &stringsBank) ); + + FMOD::Studio::Bank* vehiclesBank = NULL; + ERRCHECK( system->loadBankFile(Common_MediaPath("Vehicles.bank"), FMOD_STUDIO_LOAD_BANK_NONBLOCKING, &vehiclesBank) ); + + FMOD::Studio::Bank* sfxBank = NULL; + ERRCHECK( system->loadBankFile(Common_MediaPath("SFX.bank"), FMOD_STUDIO_LOAD_BANK_NONBLOCKING, &sfxBank) ); + + // Wait for banks to load + ERRCHECK( system->flushCommands() ); + + // Start recording commands - it will also record which banks we have already loaded by now + ERRCHECK( system->startCommandCapture(Common_WritePath(RECORD_FILENAME), FMOD_STUDIO_COMMANDCAPTURE_NORMAL) ); + + FMOD_GUID explosionID = {0}; + ERRCHECK( system->lookupID("event:/Weapons/Explosion", &explosionID) ); + + FMOD::Studio::EventDescription* engineDescription = NULL; + ERRCHECK( system->getEvent("event:/Vehicles/Ride-on Mower", &engineDescription) ); + + FMOD::Studio::EventInstance* engineInstance = NULL; + ERRCHECK( engineDescription->createInstance(&engineInstance) ); + + ERRCHECK( engineInstance->setParameterByName("RPM", 650.0f) ); + ERRCHECK( engineInstance->start() ); + + // Position the listener at the origin + FMOD_3D_ATTRIBUTES attributes = { { 0 } }; + attributes.forward.z = 1.0f; + attributes.up.y = 1.0f; + ERRCHECK( system->setListenerAttributes(0, &attributes) ); + + // Position the event 2 units in front of the listener + attributes.position.z = 2.0f; + ERRCHECK( engineInstance->set3DAttributes(&attributes) ); + + initializeScreenBuffer(); + + bool wantQuit = false; + + for (;;) + { + Common_Update(); + + if (Common_BtnPress(BTN_MORE)) + { + break; + } + + if (Common_BtnPress(BTN_QUIT)) + { + wantQuit = true; + break; + } + + if (Common_BtnPress(BTN_ACTION1)) + { + // One-shot event + FMOD::Studio::EventDescription* eventDescription = NULL; + ERRCHECK( system->getEventByID(&explosionID, &eventDescription) ); + + FMOD::Studio::EventInstance* eventInstance = NULL; + ERRCHECK( eventDescription->createInstance(&eventInstance) ); + for (int i=0; i<10; ++i) + { + ERRCHECK( eventInstance->setVolume(i / 10.0f) ); + } + + ERRCHECK( eventInstance->start() ); + + // Release will clean up the instance when it completes + ERRCHECK( eventInstance->release() ); + } + + if (Common_BtnPress(BTN_LEFT)) + { + attributes.position.x -= 1.0f; + ERRCHECK( engineInstance->set3DAttributes(&attributes) ); + } + + if (Common_BtnPress(BTN_RIGHT)) + { + attributes.position.x += 1.0f; + ERRCHECK( engineInstance->set3DAttributes(&attributes) ); + } + + if (Common_BtnPress(BTN_UP)) + { + attributes.position.z += 1.0f; + ERRCHECK( engineInstance->set3DAttributes(&attributes) ); + } + + if (Common_BtnPress(BTN_DOWN)) + { + attributes.position.z -= 1.0f; + ERRCHECK( engineInstance->set3DAttributes(&attributes) ); + } + + if (Common_BtnPress(BTN_MORE)) + { + break; + } + if (Common_BtnPress(BTN_QUIT)) + { + wantQuit = true; + break; + } + + ERRCHECK(system->update()); + + updateScreenPosition(attributes.position); + Common_Draw("=================================================="); + Common_Draw("Recording and playback example."); + Common_Draw("Copyright (c) Firelight Technologies 2012-2026."); + Common_Draw("=================================================="); + Common_Draw(""); + Common_Draw("Recording!"); + Common_Draw(""); + Common_Draw(screenBuffer); + Common_Draw(""); + Common_Draw("Press %s to finish recording", Common_BtnStr(BTN_MORE)); + Common_Draw("Press %s to play a one-shot", Common_BtnStr(BTN_ACTION1)); + Common_Draw("Use the arrow keys (%s, %s, %s, %s) to control the engine position", + Common_BtnStr(BTN_LEFT), Common_BtnStr(BTN_RIGHT), Common_BtnStr(BTN_UP), Common_BtnStr(BTN_DOWN)); + Common_Draw("Press %s to quit", Common_BtnStr(BTN_QUIT)); + + Common_Sleep(50); + } + + // Unload all the banks + ERRCHECK( masterBank->unload() ); + ERRCHECK( stringsBank->unload() ); + ERRCHECK( vehiclesBank->unload() ); + ERRCHECK( sfxBank->unload() ); + + // Finish recording + ERRCHECK( system->flushCommands() ); + ERRCHECK( system->stopCommandCapture() ); + + return (wantQuit ? State_Quit : State_Selection); +} + +// Play back a previously recorded file +State executePlayback(FMOD::Studio::System* system) +{ + FMOD::Studio::CommandReplay* replay; + ERRCHECK( system->loadCommandReplay(Common_WritePath(RECORD_FILENAME), FMOD_STUDIO_COMMANDREPLAY_NORMAL, &replay)); + int commandCount; + ERRCHECK(replay->getCommandCount(&commandCount)); + float totalTime; + ERRCHECK(replay->getLength(&totalTime)); + ERRCHECK(replay->start()); + ERRCHECK(system->update()); + + for (;;) + { + Common_Update(); + + if (Common_BtnPress(BTN_QUIT)) + { + break; + } + + if (Common_BtnPress(BTN_MORE)) + { + bool paused; + ERRCHECK(replay->getPaused(&paused)); + ERRCHECK(replay->setPaused(!paused)); + } + + FMOD_STUDIO_PLAYBACK_STATE state; + ERRCHECK(replay->getPlaybackState(&state)); + if (state == FMOD_STUDIO_PLAYBACK_STOPPED) + { + break; + } + + int currentIndex; + float currentTime; + ERRCHECK(replay->getCurrentCommand(¤tIndex, ¤tTime)); + + ERRCHECK(system->update()); + + Common_Draw("=================================================="); + Common_Draw("Recording and playback example."); + Common_Draw("Copyright (c) Firelight Technologies 2012-2026."); + Common_Draw("=================================================="); + Common_Draw(""); + Common_Draw("Playing back commands:"); + Common_Draw("Command = %d / %d\n", currentIndex, commandCount); + Common_Draw("Time = %.3f / %.3f\n", currentTime, totalTime); + Common_Draw(""); + Common_Draw("Press %s to pause/unpause recording", Common_BtnStr(BTN_MORE)); + Common_Draw("Press %s to quit", Common_BtnStr(BTN_QUIT)); + + Common_Sleep(50); + } + + + ERRCHECK( replay->release() ); + ERRCHECK( system->unloadAll() ); + return State_Selection; +} + +void initializeScreenBuffer() +{ + memset(screenBuffer, ' ', sizeof(screenBuffer)); + + int idx = SCREEN_WIDTH; + for (int i = 0; i < SCREEN_HEIGHT; ++i) + { + screenBuffer[idx] = '\n'; + idx += SCREEN_WIDTH + 1; + } + + screenBuffer[(SCREEN_WIDTH + 1) * SCREEN_HEIGHT] = '\0'; +} + +int getCharacterIndex(const FMOD_VECTOR& position) +{ + int row = static_cast(-position.z + (SCREEN_HEIGHT / 2)); + int col = static_cast(position.x + (SCREEN_WIDTH / 2)); + + if (0 < row && row < SCREEN_HEIGHT && 0 < col && col < SCREEN_WIDTH) + { + return (row * (SCREEN_WIDTH + 1)) + col; + } + + return -1; +} + +void updateScreenPosition(const FMOD_VECTOR& eventPosition) +{ + if (currentScreenPosition != -1) + { + screenBuffer[currentScreenPosition] = ' '; + currentScreenPosition = -1; + } + + FMOD_VECTOR origin = {0}; + int idx = getCharacterIndex(origin); + screenBuffer[idx] = '^'; + + idx = getCharacterIndex(eventPosition); + if (idx != -1) + { + screenBuffer[idx] = 'o'; + currentScreenPosition = idx; + } +} diff --git a/FMOD/api/studio/examples/simple_event.cpp b/FMOD/api/studio/examples/simple_event.cpp new file mode 100644 index 0000000..b92aa9e --- /dev/null +++ b/FMOD/api/studio/examples/simple_event.cpp @@ -0,0 +1,126 @@ +/*============================================================================== +Simple Event Example +Copyright (c), Firelight Technologies Pty, Ltd 2012-2026. + +This example demonstrates the various ways of playing an event. + +#### Explosion Event #### +This event is played as a one-shot and released immediately after it has been +created. + +#### Looping Ambience Event #### +A single instance is started or stopped based on user input. + +#### Cancel Event #### +This instance is started and if already playing, restarted. + +For information on using FMOD example code in your own programs, visit +https://www.fmod.com/legal +==============================================================================*/ +#include "fmod_studio.hpp" +#include "fmod.hpp" +#include "common.h" + +int FMOD_Main() +{ + void *extraDriverData = NULL; + Common_Init(&extraDriverData); + + FMOD::Studio::System* system = NULL; + ERRCHECK( FMOD::Studio::System::create(&system) ); + + // The example Studio project is authored for 5.1 sound, so set up the system output mode to match + FMOD::System* coreSystem = NULL; + ERRCHECK( system->getCoreSystem(&coreSystem) ); + ERRCHECK( coreSystem->setSoftwareFormat(0, FMOD_SPEAKERMODE_5POINT1, 0) ); + + ERRCHECK( system->initialize(1024, FMOD_STUDIO_INIT_NORMAL, FMOD_INIT_NORMAL, extraDriverData) ); + + FMOD::Studio::Bank* masterBank = NULL; + ERRCHECK( system->loadBankFile(Common_MediaPath("Master.bank"), FMOD_STUDIO_LOAD_BANK_NORMAL, &masterBank) ); + + FMOD::Studio::Bank* stringsBank = NULL; + ERRCHECK( system->loadBankFile(Common_MediaPath("Master.strings.bank"), FMOD_STUDIO_LOAD_BANK_NORMAL, &stringsBank) ); + + FMOD::Studio::Bank* sfxBank = NULL; + ERRCHECK( system->loadBankFile(Common_MediaPath("SFX.bank"), FMOD_STUDIO_LOAD_BANK_NORMAL, &sfxBank) ); + + // Get the Looping Ambience event + FMOD::Studio::EventDescription* loopingAmbienceDescription = NULL; + ERRCHECK( system->getEvent("event:/Ambience/Country", &loopingAmbienceDescription) ); + + FMOD::Studio::EventInstance* loopingAmbienceInstance = NULL; + ERRCHECK( loopingAmbienceDescription->createInstance(&loopingAmbienceInstance) ); + + // Get the 4 Second Surge event + FMOD::Studio::EventDescription* cancelDescription = NULL; + ERRCHECK( system->getEvent("event:/UI/Cancel", &cancelDescription) ); + + FMOD::Studio::EventInstance* cancelInstance = NULL; + ERRCHECK( cancelDescription->createInstance(&cancelInstance) ); + + // Get the Single Explosion event + FMOD::Studio::EventDescription* explosionDescription = NULL; + ERRCHECK( system->getEvent("event:/Weapons/Explosion", &explosionDescription) ); + + // Start loading explosion sample data and keep it in memory + ERRCHECK( explosionDescription->loadSampleData() ); + + do + { + Common_Update(); + + if (Common_BtnPress(BTN_ACTION1)) + { + // One-shot event + FMOD::Studio::EventInstance* eventInstance = NULL; + ERRCHECK( explosionDescription->createInstance(&eventInstance) ); + + ERRCHECK( eventInstance->start() ); + + // Release will clean up the instance when it completes + ERRCHECK( eventInstance->release() ); + } + + if (Common_BtnPress(BTN_ACTION2)) + { + ERRCHECK( loopingAmbienceInstance->start() ); + } + + if (Common_BtnPress(BTN_ACTION3)) + { + ERRCHECK( loopingAmbienceInstance->stop(FMOD_STUDIO_STOP_IMMEDIATE) ); + } + + if (Common_BtnPress(BTN_ACTION4)) + { + // Calling start on an instance will cause it to restart if it's already playing + ERRCHECK( cancelInstance->start() ); + } + + ERRCHECK( system->update() ); + + Common_Draw("=================================================="); + Common_Draw("Simple Event Example."); + Common_Draw("Copyright (c) Firelight Technologies 2012-2026."); + Common_Draw("=================================================="); + Common_Draw(""); + Common_Draw("Press %s to fire and forget the explosion", Common_BtnStr(BTN_ACTION1)); + Common_Draw("Press %s to start the looping ambience", Common_BtnStr(BTN_ACTION2)); + Common_Draw("Press %s to stop the looping ambience", Common_BtnStr(BTN_ACTION3)); + Common_Draw("Press %s to start/restart the cancel sound", Common_BtnStr(BTN_ACTION4)); + Common_Draw("Press %s to quit", Common_BtnStr(BTN_QUIT)); + + Common_Sleep(50); + } while (!Common_BtnPress(BTN_QUIT)); + + ERRCHECK( sfxBank->unload() ); + ERRCHECK( stringsBank->unload() ); + ERRCHECK( masterBank->unload() ); + + ERRCHECK( system->release() ); + + Common_Close(); + + return 0; +} diff --git a/FMOD/api/studio/examples/vs2017/3d.vcxproj b/FMOD/api/studio/examples/vs2017/3d.vcxproj new file mode 100644 index 0000000..d0bb6ba --- /dev/null +++ b/FMOD/api/studio/examples/vs2017/3d.vcxproj @@ -0,0 +1,85 @@ + + + + + Debug + Win32 + + + Debug + x64 + + + Debug + ARM64 + + + Release + Win32 + + + Release + x64 + + + Release + ARM64 + + + + x86 + x64 + ARM64 + L + + + {6A2B9ADB-9D37-4AD0-8D5E-704016494DD2} + + + + Application + v141 + false + true + + + + $(SolutionDir)_builds\$(ProjectName)\$(Configuration)\$(Platform)\ + $(SolutionDir)_builds\$(ProjectName)\$(Configuration)\$(Platform)\Intermediate\ + false + $(ProjectName)$(Suffix) + + + + Level3 + ..\..\..\core\inc;..\..\..\studio\inc + ProgramDatabase + _WIN32_WINNT=0x601;WINVER=0x601;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) + + + Windows + true + ..\..\..\core\lib\$(Arch);..\..\..\studio\lib\$(Arch) + fmod$(Suffix)_vc.lib;fmodstudio$(Suffix)_vc.lib;%(AdditionalDependencies) + + + if not exist ..\bin mkdir ..\bin +copy /Y "$(TargetPath)" ..\bin +copy /Y "..\..\..\core\lib\$(Arch)\fmod$(Suffix).dll" ..\bin +copy /Y "..\..\..\studio\lib\$(Arch)\fmodstudio$(Suffix).dll" ..\bin +copy /Y "..\..\..\core\lib\$(Arch)\fmod$(Suffix).dll" "$(OutDir)" +copy /Y "..\..\..\studio\lib\$(Arch)\fmodstudio$(Suffix).dll" "$(OutDir)" + + + + + + + + + + + + + + diff --git a/FMOD/api/studio/examples/vs2017/3d.vcxproj.filters b/FMOD/api/studio/examples/vs2017/3d.vcxproj.filters new file mode 100644 index 0000000..fc0f117 --- /dev/null +++ b/FMOD/api/studio/examples/vs2017/3d.vcxproj.filters @@ -0,0 +1,24 @@ + + + + + common + + + common + + + + + {937abb1b-0123-4875-9828-07ed9f9813e3} + + + + + common + + + common + + + \ No newline at end of file diff --git a/FMOD/api/studio/examples/vs2017/3d_multi.vcxproj b/FMOD/api/studio/examples/vs2017/3d_multi.vcxproj new file mode 100644 index 0000000..d9def27 --- /dev/null +++ b/FMOD/api/studio/examples/vs2017/3d_multi.vcxproj @@ -0,0 +1,85 @@ + + + + + Debug + Win32 + + + Debug + x64 + + + Debug + ARM64 + + + Release + Win32 + + + Release + x64 + + + Release + ARM64 + + + + x86 + x64 + ARM64 + L + + + {313A5F70-D199-4E1B-B2C3-22D5BCEE7058} + + + + Application + v141 + false + true + + + + $(SolutionDir)_builds\$(ProjectName)\$(Configuration)\$(Platform)\ + $(SolutionDir)_builds\$(ProjectName)\$(Configuration)\$(Platform)\Intermediate\ + false + $(ProjectName)$(Suffix) + + + + Level3 + ..\..\..\core\inc;..\..\..\studio\inc + ProgramDatabase + _WIN32_WINNT=0x601;WINVER=0x601;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) + + + Windows + true + ..\..\..\core\lib\$(Arch);..\..\..\studio\lib\$(Arch) + fmod$(Suffix)_vc.lib;fmodstudio$(Suffix)_vc.lib;%(AdditionalDependencies) + + + if not exist ..\bin mkdir ..\bin +copy /Y "$(TargetPath)" ..\bin +copy /Y "..\..\..\core\lib\$(Arch)\fmod$(Suffix).dll" ..\bin +copy /Y "..\..\..\studio\lib\$(Arch)\fmodstudio$(Suffix).dll" ..\bin +copy /Y "..\..\..\core\lib\$(Arch)\fmod$(Suffix).dll" "$(OutDir)" +copy /Y "..\..\..\studio\lib\$(Arch)\fmodstudio$(Suffix).dll" "$(OutDir)" + + + + + + + + + + + + + + diff --git a/FMOD/api/studio/examples/vs2017/3d_multi.vcxproj.filters b/FMOD/api/studio/examples/vs2017/3d_multi.vcxproj.filters new file mode 100644 index 0000000..fc0f117 --- /dev/null +++ b/FMOD/api/studio/examples/vs2017/3d_multi.vcxproj.filters @@ -0,0 +1,24 @@ + + + + + common + + + common + + + + + {937abb1b-0123-4875-9828-07ed9f9813e3} + + + + + common + + + common + + + \ No newline at end of file diff --git a/FMOD/api/studio/examples/vs2017/event_parameter.vcxproj b/FMOD/api/studio/examples/vs2017/event_parameter.vcxproj new file mode 100644 index 0000000..8a72089 --- /dev/null +++ b/FMOD/api/studio/examples/vs2017/event_parameter.vcxproj @@ -0,0 +1,85 @@ + + + + + Debug + Win32 + + + Debug + x64 + + + Debug + ARM64 + + + Release + Win32 + + + Release + x64 + + + Release + ARM64 + + + + x86 + x64 + ARM64 + L + + + {5AF356EC-E627-4696-88FA-393F2567C89E} + + + + Application + v141 + false + true + + + + $(SolutionDir)_builds\$(ProjectName)\$(Configuration)\$(Platform)\ + $(SolutionDir)_builds\$(ProjectName)\$(Configuration)\$(Platform)\Intermediate\ + false + $(ProjectName)$(Suffix) + + + + Level3 + ..\..\..\core\inc;..\..\..\studio\inc + ProgramDatabase + _WIN32_WINNT=0x601;WINVER=0x601;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) + + + Windows + true + ..\..\..\core\lib\$(Arch);..\..\..\studio\lib\$(Arch) + fmod$(Suffix)_vc.lib;fmodstudio$(Suffix)_vc.lib;%(AdditionalDependencies) + + + if not exist ..\bin mkdir ..\bin +copy /Y "$(TargetPath)" ..\bin +copy /Y "..\..\..\core\lib\$(Arch)\fmod$(Suffix).dll" ..\bin +copy /Y "..\..\..\studio\lib\$(Arch)\fmodstudio$(Suffix).dll" ..\bin +copy /Y "..\..\..\core\lib\$(Arch)\fmod$(Suffix).dll" "$(OutDir)" +copy /Y "..\..\..\studio\lib\$(Arch)\fmodstudio$(Suffix).dll" "$(OutDir)" + + + + + + + + + + + + + + diff --git a/FMOD/api/studio/examples/vs2017/event_parameter.vcxproj.filters b/FMOD/api/studio/examples/vs2017/event_parameter.vcxproj.filters new file mode 100644 index 0000000..fc0f117 --- /dev/null +++ b/FMOD/api/studio/examples/vs2017/event_parameter.vcxproj.filters @@ -0,0 +1,24 @@ + + + + + common + + + common + + + + + {937abb1b-0123-4875-9828-07ed9f9813e3} + + + + + common + + + common + + + \ No newline at end of file diff --git a/FMOD/api/studio/examples/vs2017/examples.sln b/FMOD/api/studio/examples/vs2017/examples.sln new file mode 100644 index 0000000..a9c9055 --- /dev/null +++ b/FMOD/api/studio/examples/vs2017/examples.sln @@ -0,0 +1,198 @@ + +Microsoft Visual Studio Solution File, Format Version 11.00 +# Visual Studio 15 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "3d", "3d.vcxproj", "{6A2B9ADB-9D37-4AD0-8D5E-704016494DD2}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "3d_multi", "3d_multi.vcxproj", "{313A5F70-D199-4E1B-B2C3-22D5BCEE7058}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "event_parameter", "event_parameter.vcxproj", "{5AF356EC-E627-4696-88FA-393F2567C89E}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "load_banks", "load_banks.vcxproj", "{BC9F4EC6-EA53-4E28-A195-326CBB9672EE}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "music_callbacks", "music_callbacks.vcxproj", "{6F2DB886-37AF-4C24-B2B2-BDF78EBD463C}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "objectpan", "objectpan.vcxproj", "{E990E075-513A-4593-9DF2-0388ACE51AAC}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "programmer_sound", "programmer_sound.vcxproj", "{44396AA9-7D10-42AE-989E-744F4984DA05}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "recording_playback", "recording_playback.vcxproj", "{F5E9BC59-CD65-461F-BC26-6D48A738C168}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "simple_event", "simple_event.vcxproj", "{679C8463-8AF3-4320-866D-60C952C123F3}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Win32 = Debug|Win32 + Debug|x64 = Debug|x64 + Debug|ARM64 = Debug|ARM64 + Release|Win32 = Release|Win32 + Release|x64 = Release|x64 + Release|ARM64 = Release|ARM64 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {6A2B9ADB-9D37-4AD0-8D5E-704016494DD2}.Debug|Win32.ActiveCfg = Debug|Win32 + {6A2B9ADB-9D37-4AD0-8D5E-704016494DD2}.Debug|Win32.Build.0 = Debug|Win32 + {6A2B9ADB-9D37-4AD0-8D5E-704016494DD2}.Debug|Win32.Deploy.0 = Debug|Win32 + {6A2B9ADB-9D37-4AD0-8D5E-704016494DD2}.Debug|x64.ActiveCfg = Debug|x64 + {6A2B9ADB-9D37-4AD0-8D5E-704016494DD2}.Debug|x64.Build.0 = Debug|x64 + {6A2B9ADB-9D37-4AD0-8D5E-704016494DD2}.Debug|x64.Deploy.0 = Debug|x64 + {6A2B9ADB-9D37-4AD0-8D5E-704016494DD2}.Debug|ARM64.ActiveCfg = Debug|ARM64 + {6A2B9ADB-9D37-4AD0-8D5E-704016494DD2}.Debug|ARM64.Build.0 = Debug|ARM64 + {6A2B9ADB-9D37-4AD0-8D5E-704016494DD2}.Debug|ARM64.Deploy.0 = Debug|ARM64 + {6A2B9ADB-9D37-4AD0-8D5E-704016494DD2}.Release|Win32.ActiveCfg = Release|Win32 + {6A2B9ADB-9D37-4AD0-8D5E-704016494DD2}.Release|Win32.Build.0 = Release|Win32 + {6A2B9ADB-9D37-4AD0-8D5E-704016494DD2}.Release|Win32.Deploy.0 = Release|Win32 + {6A2B9ADB-9D37-4AD0-8D5E-704016494DD2}.Release|x64.ActiveCfg = Release|x64 + {6A2B9ADB-9D37-4AD0-8D5E-704016494DD2}.Release|x64.Build.0 = Release|x64 + {6A2B9ADB-9D37-4AD0-8D5E-704016494DD2}.Release|x64.Deploy.0 = Release|x64 + {6A2B9ADB-9D37-4AD0-8D5E-704016494DD2}.Release|ARM64.ActiveCfg = Release|ARM64 + {6A2B9ADB-9D37-4AD0-8D5E-704016494DD2}.Release|ARM64.Build.0 = Release|ARM64 + {6A2B9ADB-9D37-4AD0-8D5E-704016494DD2}.Release|ARM64.Deploy.0 = Release|ARM64 + {313A5F70-D199-4E1B-B2C3-22D5BCEE7058}.Debug|Win32.ActiveCfg = Debug|Win32 + {313A5F70-D199-4E1B-B2C3-22D5BCEE7058}.Debug|Win32.Build.0 = Debug|Win32 + {313A5F70-D199-4E1B-B2C3-22D5BCEE7058}.Debug|Win32.Deploy.0 = Debug|Win32 + {313A5F70-D199-4E1B-B2C3-22D5BCEE7058}.Debug|x64.ActiveCfg = Debug|x64 + {313A5F70-D199-4E1B-B2C3-22D5BCEE7058}.Debug|x64.Build.0 = Debug|x64 + {313A5F70-D199-4E1B-B2C3-22D5BCEE7058}.Debug|x64.Deploy.0 = Debug|x64 + {313A5F70-D199-4E1B-B2C3-22D5BCEE7058}.Debug|ARM64.ActiveCfg = Debug|ARM64 + {313A5F70-D199-4E1B-B2C3-22D5BCEE7058}.Debug|ARM64.Build.0 = Debug|ARM64 + {313A5F70-D199-4E1B-B2C3-22D5BCEE7058}.Debug|ARM64.Deploy.0 = Debug|ARM64 + {313A5F70-D199-4E1B-B2C3-22D5BCEE7058}.Release|Win32.ActiveCfg = Release|Win32 + {313A5F70-D199-4E1B-B2C3-22D5BCEE7058}.Release|Win32.Build.0 = Release|Win32 + {313A5F70-D199-4E1B-B2C3-22D5BCEE7058}.Release|Win32.Deploy.0 = Release|Win32 + {313A5F70-D199-4E1B-B2C3-22D5BCEE7058}.Release|x64.ActiveCfg = Release|x64 + {313A5F70-D199-4E1B-B2C3-22D5BCEE7058}.Release|x64.Build.0 = Release|x64 + {313A5F70-D199-4E1B-B2C3-22D5BCEE7058}.Release|x64.Deploy.0 = Release|x64 + {313A5F70-D199-4E1B-B2C3-22D5BCEE7058}.Release|ARM64.ActiveCfg = Release|ARM64 + {313A5F70-D199-4E1B-B2C3-22D5BCEE7058}.Release|ARM64.Build.0 = Release|ARM64 + {313A5F70-D199-4E1B-B2C3-22D5BCEE7058}.Release|ARM64.Deploy.0 = Release|ARM64 + {5AF356EC-E627-4696-88FA-393F2567C89E}.Debug|Win32.ActiveCfg = Debug|Win32 + {5AF356EC-E627-4696-88FA-393F2567C89E}.Debug|Win32.Build.0 = Debug|Win32 + {5AF356EC-E627-4696-88FA-393F2567C89E}.Debug|Win32.Deploy.0 = Debug|Win32 + {5AF356EC-E627-4696-88FA-393F2567C89E}.Debug|x64.ActiveCfg = Debug|x64 + {5AF356EC-E627-4696-88FA-393F2567C89E}.Debug|x64.Build.0 = Debug|x64 + {5AF356EC-E627-4696-88FA-393F2567C89E}.Debug|x64.Deploy.0 = Debug|x64 + {5AF356EC-E627-4696-88FA-393F2567C89E}.Debug|ARM64.ActiveCfg = Debug|ARM64 + {5AF356EC-E627-4696-88FA-393F2567C89E}.Debug|ARM64.Build.0 = Debug|ARM64 + {5AF356EC-E627-4696-88FA-393F2567C89E}.Debug|ARM64.Deploy.0 = Debug|ARM64 + {5AF356EC-E627-4696-88FA-393F2567C89E}.Release|Win32.ActiveCfg = Release|Win32 + {5AF356EC-E627-4696-88FA-393F2567C89E}.Release|Win32.Build.0 = Release|Win32 + {5AF356EC-E627-4696-88FA-393F2567C89E}.Release|Win32.Deploy.0 = Release|Win32 + {5AF356EC-E627-4696-88FA-393F2567C89E}.Release|x64.ActiveCfg = Release|x64 + {5AF356EC-E627-4696-88FA-393F2567C89E}.Release|x64.Build.0 = Release|x64 + {5AF356EC-E627-4696-88FA-393F2567C89E}.Release|x64.Deploy.0 = Release|x64 + {5AF356EC-E627-4696-88FA-393F2567C89E}.Release|ARM64.ActiveCfg = Release|ARM64 + {5AF356EC-E627-4696-88FA-393F2567C89E}.Release|ARM64.Build.0 = Release|ARM64 + {5AF356EC-E627-4696-88FA-393F2567C89E}.Release|ARM64.Deploy.0 = Release|ARM64 + {BC9F4EC6-EA53-4E28-A195-326CBB9672EE}.Debug|Win32.ActiveCfg = Debug|Win32 + {BC9F4EC6-EA53-4E28-A195-326CBB9672EE}.Debug|Win32.Build.0 = Debug|Win32 + {BC9F4EC6-EA53-4E28-A195-326CBB9672EE}.Debug|Win32.Deploy.0 = Debug|Win32 + {BC9F4EC6-EA53-4E28-A195-326CBB9672EE}.Debug|x64.ActiveCfg = Debug|x64 + {BC9F4EC6-EA53-4E28-A195-326CBB9672EE}.Debug|x64.Build.0 = Debug|x64 + {BC9F4EC6-EA53-4E28-A195-326CBB9672EE}.Debug|x64.Deploy.0 = Debug|x64 + {BC9F4EC6-EA53-4E28-A195-326CBB9672EE}.Debug|ARM64.ActiveCfg = Debug|ARM64 + {BC9F4EC6-EA53-4E28-A195-326CBB9672EE}.Debug|ARM64.Build.0 = Debug|ARM64 + {BC9F4EC6-EA53-4E28-A195-326CBB9672EE}.Debug|ARM64.Deploy.0 = Debug|ARM64 + {BC9F4EC6-EA53-4E28-A195-326CBB9672EE}.Release|Win32.ActiveCfg = Release|Win32 + {BC9F4EC6-EA53-4E28-A195-326CBB9672EE}.Release|Win32.Build.0 = Release|Win32 + {BC9F4EC6-EA53-4E28-A195-326CBB9672EE}.Release|Win32.Deploy.0 = Release|Win32 + {BC9F4EC6-EA53-4E28-A195-326CBB9672EE}.Release|x64.ActiveCfg = Release|x64 + {BC9F4EC6-EA53-4E28-A195-326CBB9672EE}.Release|x64.Build.0 = Release|x64 + {BC9F4EC6-EA53-4E28-A195-326CBB9672EE}.Release|x64.Deploy.0 = Release|x64 + {BC9F4EC6-EA53-4E28-A195-326CBB9672EE}.Release|ARM64.ActiveCfg = Release|ARM64 + {BC9F4EC6-EA53-4E28-A195-326CBB9672EE}.Release|ARM64.Build.0 = Release|ARM64 + {BC9F4EC6-EA53-4E28-A195-326CBB9672EE}.Release|ARM64.Deploy.0 = Release|ARM64 + {6F2DB886-37AF-4C24-B2B2-BDF78EBD463C}.Debug|Win32.ActiveCfg = Debug|Win32 + {6F2DB886-37AF-4C24-B2B2-BDF78EBD463C}.Debug|Win32.Build.0 = Debug|Win32 + {6F2DB886-37AF-4C24-B2B2-BDF78EBD463C}.Debug|Win32.Deploy.0 = Debug|Win32 + {6F2DB886-37AF-4C24-B2B2-BDF78EBD463C}.Debug|x64.ActiveCfg = Debug|x64 + {6F2DB886-37AF-4C24-B2B2-BDF78EBD463C}.Debug|x64.Build.0 = Debug|x64 + {6F2DB886-37AF-4C24-B2B2-BDF78EBD463C}.Debug|x64.Deploy.0 = Debug|x64 + {6F2DB886-37AF-4C24-B2B2-BDF78EBD463C}.Debug|ARM64.ActiveCfg = Debug|ARM64 + {6F2DB886-37AF-4C24-B2B2-BDF78EBD463C}.Debug|ARM64.Build.0 = Debug|ARM64 + {6F2DB886-37AF-4C24-B2B2-BDF78EBD463C}.Debug|ARM64.Deploy.0 = Debug|ARM64 + {6F2DB886-37AF-4C24-B2B2-BDF78EBD463C}.Release|Win32.ActiveCfg = Release|Win32 + {6F2DB886-37AF-4C24-B2B2-BDF78EBD463C}.Release|Win32.Build.0 = Release|Win32 + {6F2DB886-37AF-4C24-B2B2-BDF78EBD463C}.Release|Win32.Deploy.0 = Release|Win32 + {6F2DB886-37AF-4C24-B2B2-BDF78EBD463C}.Release|x64.ActiveCfg = Release|x64 + {6F2DB886-37AF-4C24-B2B2-BDF78EBD463C}.Release|x64.Build.0 = Release|x64 + {6F2DB886-37AF-4C24-B2B2-BDF78EBD463C}.Release|x64.Deploy.0 = Release|x64 + {6F2DB886-37AF-4C24-B2B2-BDF78EBD463C}.Release|ARM64.ActiveCfg = Release|ARM64 + {6F2DB886-37AF-4C24-B2B2-BDF78EBD463C}.Release|ARM64.Build.0 = Release|ARM64 + {6F2DB886-37AF-4C24-B2B2-BDF78EBD463C}.Release|ARM64.Deploy.0 = Release|ARM64 + {E990E075-513A-4593-9DF2-0388ACE51AAC}.Debug|Win32.ActiveCfg = Debug|Win32 + {E990E075-513A-4593-9DF2-0388ACE51AAC}.Debug|Win32.Build.0 = Debug|Win32 + {E990E075-513A-4593-9DF2-0388ACE51AAC}.Debug|Win32.Deploy.0 = Debug|Win32 + {E990E075-513A-4593-9DF2-0388ACE51AAC}.Debug|x64.ActiveCfg = Debug|x64 + {E990E075-513A-4593-9DF2-0388ACE51AAC}.Debug|x64.Build.0 = Debug|x64 + {E990E075-513A-4593-9DF2-0388ACE51AAC}.Debug|x64.Deploy.0 = Debug|x64 + {E990E075-513A-4593-9DF2-0388ACE51AAC}.Debug|ARM64.ActiveCfg = Debug|ARM64 + {E990E075-513A-4593-9DF2-0388ACE51AAC}.Debug|ARM64.Build.0 = Debug|ARM64 + {E990E075-513A-4593-9DF2-0388ACE51AAC}.Debug|ARM64.Deploy.0 = Debug|ARM64 + {E990E075-513A-4593-9DF2-0388ACE51AAC}.Release|Win32.ActiveCfg = Release|Win32 + {E990E075-513A-4593-9DF2-0388ACE51AAC}.Release|Win32.Build.0 = Release|Win32 + {E990E075-513A-4593-9DF2-0388ACE51AAC}.Release|Win32.Deploy.0 = Release|Win32 + {E990E075-513A-4593-9DF2-0388ACE51AAC}.Release|x64.ActiveCfg = Release|x64 + {E990E075-513A-4593-9DF2-0388ACE51AAC}.Release|x64.Build.0 = Release|x64 + {E990E075-513A-4593-9DF2-0388ACE51AAC}.Release|x64.Deploy.0 = Release|x64 + {E990E075-513A-4593-9DF2-0388ACE51AAC}.Release|ARM64.ActiveCfg = Release|ARM64 + {E990E075-513A-4593-9DF2-0388ACE51AAC}.Release|ARM64.Build.0 = Release|ARM64 + {E990E075-513A-4593-9DF2-0388ACE51AAC}.Release|ARM64.Deploy.0 = Release|ARM64 + {44396AA9-7D10-42AE-989E-744F4984DA05}.Debug|Win32.ActiveCfg = Debug|Win32 + {44396AA9-7D10-42AE-989E-744F4984DA05}.Debug|Win32.Build.0 = Debug|Win32 + {44396AA9-7D10-42AE-989E-744F4984DA05}.Debug|Win32.Deploy.0 = Debug|Win32 + {44396AA9-7D10-42AE-989E-744F4984DA05}.Debug|x64.ActiveCfg = Debug|x64 + {44396AA9-7D10-42AE-989E-744F4984DA05}.Debug|x64.Build.0 = Debug|x64 + {44396AA9-7D10-42AE-989E-744F4984DA05}.Debug|x64.Deploy.0 = Debug|x64 + {44396AA9-7D10-42AE-989E-744F4984DA05}.Debug|ARM64.ActiveCfg = Debug|ARM64 + {44396AA9-7D10-42AE-989E-744F4984DA05}.Debug|ARM64.Build.0 = Debug|ARM64 + {44396AA9-7D10-42AE-989E-744F4984DA05}.Debug|ARM64.Deploy.0 = Debug|ARM64 + {44396AA9-7D10-42AE-989E-744F4984DA05}.Release|Win32.ActiveCfg = Release|Win32 + {44396AA9-7D10-42AE-989E-744F4984DA05}.Release|Win32.Build.0 = Release|Win32 + {44396AA9-7D10-42AE-989E-744F4984DA05}.Release|Win32.Deploy.0 = Release|Win32 + {44396AA9-7D10-42AE-989E-744F4984DA05}.Release|x64.ActiveCfg = Release|x64 + {44396AA9-7D10-42AE-989E-744F4984DA05}.Release|x64.Build.0 = Release|x64 + {44396AA9-7D10-42AE-989E-744F4984DA05}.Release|x64.Deploy.0 = Release|x64 + {44396AA9-7D10-42AE-989E-744F4984DA05}.Release|ARM64.ActiveCfg = Release|ARM64 + {44396AA9-7D10-42AE-989E-744F4984DA05}.Release|ARM64.Build.0 = Release|ARM64 + {44396AA9-7D10-42AE-989E-744F4984DA05}.Release|ARM64.Deploy.0 = Release|ARM64 + {F5E9BC59-CD65-461F-BC26-6D48A738C168}.Debug|Win32.ActiveCfg = Debug|Win32 + {F5E9BC59-CD65-461F-BC26-6D48A738C168}.Debug|Win32.Build.0 = Debug|Win32 + {F5E9BC59-CD65-461F-BC26-6D48A738C168}.Debug|Win32.Deploy.0 = Debug|Win32 + {F5E9BC59-CD65-461F-BC26-6D48A738C168}.Debug|x64.ActiveCfg = Debug|x64 + {F5E9BC59-CD65-461F-BC26-6D48A738C168}.Debug|x64.Build.0 = Debug|x64 + {F5E9BC59-CD65-461F-BC26-6D48A738C168}.Debug|x64.Deploy.0 = Debug|x64 + {F5E9BC59-CD65-461F-BC26-6D48A738C168}.Debug|ARM64.ActiveCfg = Debug|ARM64 + {F5E9BC59-CD65-461F-BC26-6D48A738C168}.Debug|ARM64.Build.0 = Debug|ARM64 + {F5E9BC59-CD65-461F-BC26-6D48A738C168}.Debug|ARM64.Deploy.0 = Debug|ARM64 + {F5E9BC59-CD65-461F-BC26-6D48A738C168}.Release|Win32.ActiveCfg = Release|Win32 + {F5E9BC59-CD65-461F-BC26-6D48A738C168}.Release|Win32.Build.0 = Release|Win32 + {F5E9BC59-CD65-461F-BC26-6D48A738C168}.Release|Win32.Deploy.0 = Release|Win32 + {F5E9BC59-CD65-461F-BC26-6D48A738C168}.Release|x64.ActiveCfg = Release|x64 + {F5E9BC59-CD65-461F-BC26-6D48A738C168}.Release|x64.Build.0 = Release|x64 + {F5E9BC59-CD65-461F-BC26-6D48A738C168}.Release|x64.Deploy.0 = Release|x64 + {F5E9BC59-CD65-461F-BC26-6D48A738C168}.Release|ARM64.ActiveCfg = Release|ARM64 + {F5E9BC59-CD65-461F-BC26-6D48A738C168}.Release|ARM64.Build.0 = Release|ARM64 + {F5E9BC59-CD65-461F-BC26-6D48A738C168}.Release|ARM64.Deploy.0 = Release|ARM64 + {679C8463-8AF3-4320-866D-60C952C123F3}.Debug|Win32.ActiveCfg = Debug|Win32 + {679C8463-8AF3-4320-866D-60C952C123F3}.Debug|Win32.Build.0 = Debug|Win32 + {679C8463-8AF3-4320-866D-60C952C123F3}.Debug|Win32.Deploy.0 = Debug|Win32 + {679C8463-8AF3-4320-866D-60C952C123F3}.Debug|x64.ActiveCfg = Debug|x64 + {679C8463-8AF3-4320-866D-60C952C123F3}.Debug|x64.Build.0 = Debug|x64 + {679C8463-8AF3-4320-866D-60C952C123F3}.Debug|x64.Deploy.0 = Debug|x64 + {679C8463-8AF3-4320-866D-60C952C123F3}.Debug|ARM64.ActiveCfg = Debug|ARM64 + {679C8463-8AF3-4320-866D-60C952C123F3}.Debug|ARM64.Build.0 = Debug|ARM64 + {679C8463-8AF3-4320-866D-60C952C123F3}.Debug|ARM64.Deploy.0 = Debug|ARM64 + {679C8463-8AF3-4320-866D-60C952C123F3}.Release|Win32.ActiveCfg = Release|Win32 + {679C8463-8AF3-4320-866D-60C952C123F3}.Release|Win32.Build.0 = Release|Win32 + {679C8463-8AF3-4320-866D-60C952C123F3}.Release|Win32.Deploy.0 = Release|Win32 + {679C8463-8AF3-4320-866D-60C952C123F3}.Release|x64.ActiveCfg = Release|x64 + {679C8463-8AF3-4320-866D-60C952C123F3}.Release|x64.Build.0 = Release|x64 + {679C8463-8AF3-4320-866D-60C952C123F3}.Release|x64.Deploy.0 = Release|x64 + {679C8463-8AF3-4320-866D-60C952C123F3}.Release|ARM64.ActiveCfg = Release|ARM64 + {679C8463-8AF3-4320-866D-60C952C123F3}.Release|ARM64.Build.0 = Release|ARM64 + {679C8463-8AF3-4320-866D-60C952C123F3}.Release|ARM64.Deploy.0 = Release|ARM64 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal diff --git a/FMOD/api/studio/examples/vs2017/load_banks.vcxproj b/FMOD/api/studio/examples/vs2017/load_banks.vcxproj new file mode 100644 index 0000000..1cad419 --- /dev/null +++ b/FMOD/api/studio/examples/vs2017/load_banks.vcxproj @@ -0,0 +1,85 @@ + + + + + Debug + Win32 + + + Debug + x64 + + + Debug + ARM64 + + + Release + Win32 + + + Release + x64 + + + Release + ARM64 + + + + x86 + x64 + ARM64 + L + + + {BC9F4EC6-EA53-4E28-A195-326CBB9672EE} + + + + Application + v141 + false + true + + + + $(SolutionDir)_builds\$(ProjectName)\$(Configuration)\$(Platform)\ + $(SolutionDir)_builds\$(ProjectName)\$(Configuration)\$(Platform)\Intermediate\ + false + $(ProjectName)$(Suffix) + + + + Level3 + ..\..\..\core\inc;..\..\..\studio\inc + ProgramDatabase + _WIN32_WINNT=0x601;WINVER=0x601;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) + + + Windows + true + ..\..\..\core\lib\$(Arch);..\..\..\studio\lib\$(Arch) + fmod$(Suffix)_vc.lib;fmodstudio$(Suffix)_vc.lib;%(AdditionalDependencies) + + + if not exist ..\bin mkdir ..\bin +copy /Y "$(TargetPath)" ..\bin +copy /Y "..\..\..\core\lib\$(Arch)\fmod$(Suffix).dll" ..\bin +copy /Y "..\..\..\studio\lib\$(Arch)\fmodstudio$(Suffix).dll" ..\bin +copy /Y "..\..\..\core\lib\$(Arch)\fmod$(Suffix).dll" "$(OutDir)" +copy /Y "..\..\..\studio\lib\$(Arch)\fmodstudio$(Suffix).dll" "$(OutDir)" + + + + + + + + + + + + + + diff --git a/FMOD/api/studio/examples/vs2017/load_banks.vcxproj.filters b/FMOD/api/studio/examples/vs2017/load_banks.vcxproj.filters new file mode 100644 index 0000000..fc0f117 --- /dev/null +++ b/FMOD/api/studio/examples/vs2017/load_banks.vcxproj.filters @@ -0,0 +1,24 @@ + + + + + common + + + common + + + + + {937abb1b-0123-4875-9828-07ed9f9813e3} + + + + + common + + + common + + + \ No newline at end of file diff --git a/FMOD/api/studio/examples/vs2017/music_callbacks.vcxproj b/FMOD/api/studio/examples/vs2017/music_callbacks.vcxproj new file mode 100644 index 0000000..9f5508d --- /dev/null +++ b/FMOD/api/studio/examples/vs2017/music_callbacks.vcxproj @@ -0,0 +1,85 @@ + + + + + Debug + Win32 + + + Debug + x64 + + + Debug + ARM64 + + + Release + Win32 + + + Release + x64 + + + Release + ARM64 + + + + x86 + x64 + ARM64 + L + + + {6F2DB886-37AF-4C24-B2B2-BDF78EBD463C} + + + + Application + v141 + false + true + + + + $(SolutionDir)_builds\$(ProjectName)\$(Configuration)\$(Platform)\ + $(SolutionDir)_builds\$(ProjectName)\$(Configuration)\$(Platform)\Intermediate\ + false + $(ProjectName)$(Suffix) + + + + Level3 + ..\..\..\core\inc;..\..\..\studio\inc + ProgramDatabase + _WIN32_WINNT=0x601;WINVER=0x601;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) + + + Windows + true + ..\..\..\core\lib\$(Arch);..\..\..\studio\lib\$(Arch) + fmod$(Suffix)_vc.lib;fmodstudio$(Suffix)_vc.lib;%(AdditionalDependencies) + + + if not exist ..\bin mkdir ..\bin +copy /Y "$(TargetPath)" ..\bin +copy /Y "..\..\..\core\lib\$(Arch)\fmod$(Suffix).dll" ..\bin +copy /Y "..\..\..\studio\lib\$(Arch)\fmodstudio$(Suffix).dll" ..\bin +copy /Y "..\..\..\core\lib\$(Arch)\fmod$(Suffix).dll" "$(OutDir)" +copy /Y "..\..\..\studio\lib\$(Arch)\fmodstudio$(Suffix).dll" "$(OutDir)" + + + + + + + + + + + + + + diff --git a/FMOD/api/studio/examples/vs2017/music_callbacks.vcxproj.filters b/FMOD/api/studio/examples/vs2017/music_callbacks.vcxproj.filters new file mode 100644 index 0000000..fc0f117 --- /dev/null +++ b/FMOD/api/studio/examples/vs2017/music_callbacks.vcxproj.filters @@ -0,0 +1,24 @@ + + + + + common + + + common + + + + + {937abb1b-0123-4875-9828-07ed9f9813e3} + + + + + common + + + common + + + \ No newline at end of file diff --git a/FMOD/api/studio/examples/vs2017/objectpan.vcxproj b/FMOD/api/studio/examples/vs2017/objectpan.vcxproj new file mode 100644 index 0000000..e379f1a --- /dev/null +++ b/FMOD/api/studio/examples/vs2017/objectpan.vcxproj @@ -0,0 +1,85 @@ + + + + + Debug + Win32 + + + Debug + x64 + + + Debug + ARM64 + + + Release + Win32 + + + Release + x64 + + + Release + ARM64 + + + + x86 + x64 + ARM64 + L + + + {E990E075-513A-4593-9DF2-0388ACE51AAC} + + + + Application + v141 + false + true + + + + $(SolutionDir)_builds\$(ProjectName)\$(Configuration)\$(Platform)\ + $(SolutionDir)_builds\$(ProjectName)\$(Configuration)\$(Platform)\Intermediate\ + false + $(ProjectName)$(Suffix) + + + + Level3 + ..\..\..\core\inc;..\..\..\studio\inc + ProgramDatabase + _WIN32_WINNT=0x601;WINVER=0x601;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) + + + Windows + true + ..\..\..\core\lib\$(Arch);..\..\..\studio\lib\$(Arch) + fmod$(Suffix)_vc.lib;fmodstudio$(Suffix)_vc.lib;%(AdditionalDependencies) + + + if not exist ..\bin mkdir ..\bin +copy /Y "$(TargetPath)" ..\bin +copy /Y "..\..\..\core\lib\$(Arch)\fmod$(Suffix).dll" ..\bin +copy /Y "..\..\..\studio\lib\$(Arch)\fmodstudio$(Suffix).dll" ..\bin +copy /Y "..\..\..\core\lib\$(Arch)\fmod$(Suffix).dll" "$(OutDir)" +copy /Y "..\..\..\studio\lib\$(Arch)\fmodstudio$(Suffix).dll" "$(OutDir)" + + + + + + + + + + + + + + diff --git a/FMOD/api/studio/examples/vs2017/objectpan.vcxproj.filters b/FMOD/api/studio/examples/vs2017/objectpan.vcxproj.filters new file mode 100644 index 0000000..fc0f117 --- /dev/null +++ b/FMOD/api/studio/examples/vs2017/objectpan.vcxproj.filters @@ -0,0 +1,24 @@ + + + + + common + + + common + + + + + {937abb1b-0123-4875-9828-07ed9f9813e3} + + + + + common + + + common + + + \ No newline at end of file diff --git a/FMOD/api/studio/examples/vs2017/programmer_sound.vcxproj b/FMOD/api/studio/examples/vs2017/programmer_sound.vcxproj new file mode 100644 index 0000000..9d14db7 --- /dev/null +++ b/FMOD/api/studio/examples/vs2017/programmer_sound.vcxproj @@ -0,0 +1,85 @@ + + + + + Debug + Win32 + + + Debug + x64 + + + Debug + ARM64 + + + Release + Win32 + + + Release + x64 + + + Release + ARM64 + + + + x86 + x64 + ARM64 + L + + + {44396AA9-7D10-42AE-989E-744F4984DA05} + + + + Application + v141 + false + true + + + + $(SolutionDir)_builds\$(ProjectName)\$(Configuration)\$(Platform)\ + $(SolutionDir)_builds\$(ProjectName)\$(Configuration)\$(Platform)\Intermediate\ + false + $(ProjectName)$(Suffix) + + + + Level3 + ..\..\..\core\inc;..\..\..\studio\inc + ProgramDatabase + _WIN32_WINNT=0x601;WINVER=0x601;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) + + + Windows + true + ..\..\..\core\lib\$(Arch);..\..\..\studio\lib\$(Arch) + fmod$(Suffix)_vc.lib;fmodstudio$(Suffix)_vc.lib;%(AdditionalDependencies) + + + if not exist ..\bin mkdir ..\bin +copy /Y "$(TargetPath)" ..\bin +copy /Y "..\..\..\core\lib\$(Arch)\fmod$(Suffix).dll" ..\bin +copy /Y "..\..\..\studio\lib\$(Arch)\fmodstudio$(Suffix).dll" ..\bin +copy /Y "..\..\..\core\lib\$(Arch)\fmod$(Suffix).dll" "$(OutDir)" +copy /Y "..\..\..\studio\lib\$(Arch)\fmodstudio$(Suffix).dll" "$(OutDir)" + + + + + + + + + + + + + + diff --git a/FMOD/api/studio/examples/vs2017/programmer_sound.vcxproj.filters b/FMOD/api/studio/examples/vs2017/programmer_sound.vcxproj.filters new file mode 100644 index 0000000..fc0f117 --- /dev/null +++ b/FMOD/api/studio/examples/vs2017/programmer_sound.vcxproj.filters @@ -0,0 +1,24 @@ + + + + + common + + + common + + + + + {937abb1b-0123-4875-9828-07ed9f9813e3} + + + + + common + + + common + + + \ No newline at end of file diff --git a/FMOD/api/studio/examples/vs2017/recording_playback.vcxproj b/FMOD/api/studio/examples/vs2017/recording_playback.vcxproj new file mode 100644 index 0000000..db19c00 --- /dev/null +++ b/FMOD/api/studio/examples/vs2017/recording_playback.vcxproj @@ -0,0 +1,85 @@ + + + + + Debug + Win32 + + + Debug + x64 + + + Debug + ARM64 + + + Release + Win32 + + + Release + x64 + + + Release + ARM64 + + + + x86 + x64 + ARM64 + L + + + {F5E9BC59-CD65-461F-BC26-6D48A738C168} + + + + Application + v141 + false + true + + + + $(SolutionDir)_builds\$(ProjectName)\$(Configuration)\$(Platform)\ + $(SolutionDir)_builds\$(ProjectName)\$(Configuration)\$(Platform)\Intermediate\ + false + $(ProjectName)$(Suffix) + + + + Level3 + ..\..\..\core\inc;..\..\..\studio\inc + ProgramDatabase + _WIN32_WINNT=0x601;WINVER=0x601;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) + + + Windows + true + ..\..\..\core\lib\$(Arch);..\..\..\studio\lib\$(Arch) + fmod$(Suffix)_vc.lib;fmodstudio$(Suffix)_vc.lib;%(AdditionalDependencies) + + + if not exist ..\bin mkdir ..\bin +copy /Y "$(TargetPath)" ..\bin +copy /Y "..\..\..\core\lib\$(Arch)\fmod$(Suffix).dll" ..\bin +copy /Y "..\..\..\studio\lib\$(Arch)\fmodstudio$(Suffix).dll" ..\bin +copy /Y "..\..\..\core\lib\$(Arch)\fmod$(Suffix).dll" "$(OutDir)" +copy /Y "..\..\..\studio\lib\$(Arch)\fmodstudio$(Suffix).dll" "$(OutDir)" + + + + + + + + + + + + + + diff --git a/FMOD/api/studio/examples/vs2017/recording_playback.vcxproj.filters b/FMOD/api/studio/examples/vs2017/recording_playback.vcxproj.filters new file mode 100644 index 0000000..fc0f117 --- /dev/null +++ b/FMOD/api/studio/examples/vs2017/recording_playback.vcxproj.filters @@ -0,0 +1,24 @@ + + + + + common + + + common + + + + + {937abb1b-0123-4875-9828-07ed9f9813e3} + + + + + common + + + common + + + \ No newline at end of file diff --git a/FMOD/api/studio/examples/vs2017/simple_event.vcxproj b/FMOD/api/studio/examples/vs2017/simple_event.vcxproj new file mode 100644 index 0000000..184486e --- /dev/null +++ b/FMOD/api/studio/examples/vs2017/simple_event.vcxproj @@ -0,0 +1,85 @@ + + + + + Debug + Win32 + + + Debug + x64 + + + Debug + ARM64 + + + Release + Win32 + + + Release + x64 + + + Release + ARM64 + + + + x86 + x64 + ARM64 + L + + + {679C8463-8AF3-4320-866D-60C952C123F3} + + + + Application + v141 + false + true + + + + $(SolutionDir)_builds\$(ProjectName)\$(Configuration)\$(Platform)\ + $(SolutionDir)_builds\$(ProjectName)\$(Configuration)\$(Platform)\Intermediate\ + false + $(ProjectName)$(Suffix) + + + + Level3 + ..\..\..\core\inc;..\..\..\studio\inc + ProgramDatabase + _WIN32_WINNT=0x601;WINVER=0x601;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) + + + Windows + true + ..\..\..\core\lib\$(Arch);..\..\..\studio\lib\$(Arch) + fmod$(Suffix)_vc.lib;fmodstudio$(Suffix)_vc.lib;%(AdditionalDependencies) + + + if not exist ..\bin mkdir ..\bin +copy /Y "$(TargetPath)" ..\bin +copy /Y "..\..\..\core\lib\$(Arch)\fmod$(Suffix).dll" ..\bin +copy /Y "..\..\..\studio\lib\$(Arch)\fmodstudio$(Suffix).dll" ..\bin +copy /Y "..\..\..\core\lib\$(Arch)\fmod$(Suffix).dll" "$(OutDir)" +copy /Y "..\..\..\studio\lib\$(Arch)\fmodstudio$(Suffix).dll" "$(OutDir)" + + + + + + + + + + + + + + diff --git a/FMOD/api/studio/examples/vs2017/simple_event.vcxproj.filters b/FMOD/api/studio/examples/vs2017/simple_event.vcxproj.filters new file mode 100644 index 0000000..fc0f117 --- /dev/null +++ b/FMOD/api/studio/examples/vs2017/simple_event.vcxproj.filters @@ -0,0 +1,24 @@ + + + + + common + + + common + + + + + {937abb1b-0123-4875-9828-07ed9f9813e3} + + + + + common + + + common + + + \ No newline at end of file diff --git a/FMOD/api/studio/examples/vs2019/3d.vcxproj b/FMOD/api/studio/examples/vs2019/3d.vcxproj new file mode 100644 index 0000000..a6a67a0 --- /dev/null +++ b/FMOD/api/studio/examples/vs2019/3d.vcxproj @@ -0,0 +1,85 @@ + + + + + Debug + Win32 + + + Debug + x64 + + + Debug + ARM64 + + + Release + Win32 + + + Release + x64 + + + Release + ARM64 + + + + x86 + x64 + ARM64 + L + + + {25FB3D24-744A-4481-905C-A152193E4F40} + + + + Application + v142 + false + true + + + + $(SolutionDir)_builds\$(ProjectName)\$(Configuration)\$(Platform)\ + $(SolutionDir)_builds\$(ProjectName)\$(Configuration)\$(Platform)\Intermediate\ + false + $(ProjectName)$(Suffix) + + + + Level3 + ..\..\..\core\inc;..\..\..\studio\inc + ProgramDatabase + _WIN32_WINNT=0x601;WINVER=0x601;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) + + + Windows + true + ..\..\..\core\lib\$(Arch);..\..\..\studio\lib\$(Arch) + fmod$(Suffix)_vc.lib;fmodstudio$(Suffix)_vc.lib;%(AdditionalDependencies) + + + if not exist ..\bin mkdir ..\bin +copy /Y "$(TargetPath)" ..\bin +copy /Y "..\..\..\core\lib\$(Arch)\fmod$(Suffix).dll" ..\bin +copy /Y "..\..\..\studio\lib\$(Arch)\fmodstudio$(Suffix).dll" ..\bin +copy /Y "..\..\..\core\lib\$(Arch)\fmod$(Suffix).dll" "$(OutDir)" +copy /Y "..\..\..\studio\lib\$(Arch)\fmodstudio$(Suffix).dll" "$(OutDir)" + + + + + + + + + + + + + + diff --git a/FMOD/api/studio/examples/vs2019/3d.vcxproj.filters b/FMOD/api/studio/examples/vs2019/3d.vcxproj.filters new file mode 100644 index 0000000..fc0f117 --- /dev/null +++ b/FMOD/api/studio/examples/vs2019/3d.vcxproj.filters @@ -0,0 +1,24 @@ + + + + + common + + + common + + + + + {937abb1b-0123-4875-9828-07ed9f9813e3} + + + + + common + + + common + + + \ No newline at end of file diff --git a/FMOD/api/studio/examples/vs2019/3d_multi.vcxproj b/FMOD/api/studio/examples/vs2019/3d_multi.vcxproj new file mode 100644 index 0000000..b6f3553 --- /dev/null +++ b/FMOD/api/studio/examples/vs2019/3d_multi.vcxproj @@ -0,0 +1,85 @@ + + + + + Debug + Win32 + + + Debug + x64 + + + Debug + ARM64 + + + Release + Win32 + + + Release + x64 + + + Release + ARM64 + + + + x86 + x64 + ARM64 + L + + + {7B45A0E8-BDB1-49BA-B8F1-0AC447DFB7A3} + + + + Application + v142 + false + true + + + + $(SolutionDir)_builds\$(ProjectName)\$(Configuration)\$(Platform)\ + $(SolutionDir)_builds\$(ProjectName)\$(Configuration)\$(Platform)\Intermediate\ + false + $(ProjectName)$(Suffix) + + + + Level3 + ..\..\..\core\inc;..\..\..\studio\inc + ProgramDatabase + _WIN32_WINNT=0x601;WINVER=0x601;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) + + + Windows + true + ..\..\..\core\lib\$(Arch);..\..\..\studio\lib\$(Arch) + fmod$(Suffix)_vc.lib;fmodstudio$(Suffix)_vc.lib;%(AdditionalDependencies) + + + if not exist ..\bin mkdir ..\bin +copy /Y "$(TargetPath)" ..\bin +copy /Y "..\..\..\core\lib\$(Arch)\fmod$(Suffix).dll" ..\bin +copy /Y "..\..\..\studio\lib\$(Arch)\fmodstudio$(Suffix).dll" ..\bin +copy /Y "..\..\..\core\lib\$(Arch)\fmod$(Suffix).dll" "$(OutDir)" +copy /Y "..\..\..\studio\lib\$(Arch)\fmodstudio$(Suffix).dll" "$(OutDir)" + + + + + + + + + + + + + + diff --git a/FMOD/api/studio/examples/vs2019/3d_multi.vcxproj.filters b/FMOD/api/studio/examples/vs2019/3d_multi.vcxproj.filters new file mode 100644 index 0000000..fc0f117 --- /dev/null +++ b/FMOD/api/studio/examples/vs2019/3d_multi.vcxproj.filters @@ -0,0 +1,24 @@ + + + + + common + + + common + + + + + {937abb1b-0123-4875-9828-07ed9f9813e3} + + + + + common + + + common + + + \ No newline at end of file diff --git a/FMOD/api/studio/examples/vs2019/event_parameter.vcxproj b/FMOD/api/studio/examples/vs2019/event_parameter.vcxproj new file mode 100644 index 0000000..23f27fd --- /dev/null +++ b/FMOD/api/studio/examples/vs2019/event_parameter.vcxproj @@ -0,0 +1,85 @@ + + + + + Debug + Win32 + + + Debug + x64 + + + Debug + ARM64 + + + Release + Win32 + + + Release + x64 + + + Release + ARM64 + + + + x86 + x64 + ARM64 + L + + + {8625CEF7-34E2-4C61-99B1-1F1BDB9AE9FA} + + + + Application + v142 + false + true + + + + $(SolutionDir)_builds\$(ProjectName)\$(Configuration)\$(Platform)\ + $(SolutionDir)_builds\$(ProjectName)\$(Configuration)\$(Platform)\Intermediate\ + false + $(ProjectName)$(Suffix) + + + + Level3 + ..\..\..\core\inc;..\..\..\studio\inc + ProgramDatabase + _WIN32_WINNT=0x601;WINVER=0x601;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) + + + Windows + true + ..\..\..\core\lib\$(Arch);..\..\..\studio\lib\$(Arch) + fmod$(Suffix)_vc.lib;fmodstudio$(Suffix)_vc.lib;%(AdditionalDependencies) + + + if not exist ..\bin mkdir ..\bin +copy /Y "$(TargetPath)" ..\bin +copy /Y "..\..\..\core\lib\$(Arch)\fmod$(Suffix).dll" ..\bin +copy /Y "..\..\..\studio\lib\$(Arch)\fmodstudio$(Suffix).dll" ..\bin +copy /Y "..\..\..\core\lib\$(Arch)\fmod$(Suffix).dll" "$(OutDir)" +copy /Y "..\..\..\studio\lib\$(Arch)\fmodstudio$(Suffix).dll" "$(OutDir)" + + + + + + + + + + + + + + diff --git a/FMOD/api/studio/examples/vs2019/event_parameter.vcxproj.filters b/FMOD/api/studio/examples/vs2019/event_parameter.vcxproj.filters new file mode 100644 index 0000000..fc0f117 --- /dev/null +++ b/FMOD/api/studio/examples/vs2019/event_parameter.vcxproj.filters @@ -0,0 +1,24 @@ + + + + + common + + + common + + + + + {937abb1b-0123-4875-9828-07ed9f9813e3} + + + + + common + + + common + + + \ No newline at end of file diff --git a/FMOD/api/studio/examples/vs2019/examples.sln b/FMOD/api/studio/examples/vs2019/examples.sln new file mode 100644 index 0000000..16a31f1 --- /dev/null +++ b/FMOD/api/studio/examples/vs2019/examples.sln @@ -0,0 +1,198 @@ + +Microsoft Visual Studio Solution File, Format Version 11.00 +# Visual Studio Version 16 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "3d", "3d.vcxproj", "{25FB3D24-744A-4481-905C-A152193E4F40}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "3d_multi", "3d_multi.vcxproj", "{7B45A0E8-BDB1-49BA-B8F1-0AC447DFB7A3}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "event_parameter", "event_parameter.vcxproj", "{8625CEF7-34E2-4C61-99B1-1F1BDB9AE9FA}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "load_banks", "load_banks.vcxproj", "{61E57184-67FE-4B58-99DC-1997E30A436C}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "music_callbacks", "music_callbacks.vcxproj", "{B4FD73EE-7F06-4061-A0C7-8BE8EB0F3C19}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "objectpan", "objectpan.vcxproj", "{0643EB75-38AD-4FFF-9A99-876E19BD5463}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "programmer_sound", "programmer_sound.vcxproj", "{EE034D50-BF51-4644-BAED-C6359830F316}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "recording_playback", "recording_playback.vcxproj", "{F48A8DBC-32FF-4923-8F30-A7A64C4C2475}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "simple_event", "simple_event.vcxproj", "{9A55EFC8-588B-43ED-8193-C1ABC6D54A71}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Win32 = Debug|Win32 + Debug|x64 = Debug|x64 + Debug|ARM64 = Debug|ARM64 + Release|Win32 = Release|Win32 + Release|x64 = Release|x64 + Release|ARM64 = Release|ARM64 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {25FB3D24-744A-4481-905C-A152193E4F40}.Debug|Win32.ActiveCfg = Debug|Win32 + {25FB3D24-744A-4481-905C-A152193E4F40}.Debug|Win32.Build.0 = Debug|Win32 + {25FB3D24-744A-4481-905C-A152193E4F40}.Debug|Win32.Deploy.0 = Debug|Win32 + {25FB3D24-744A-4481-905C-A152193E4F40}.Debug|x64.ActiveCfg = Debug|x64 + {25FB3D24-744A-4481-905C-A152193E4F40}.Debug|x64.Build.0 = Debug|x64 + {25FB3D24-744A-4481-905C-A152193E4F40}.Debug|x64.Deploy.0 = Debug|x64 + {25FB3D24-744A-4481-905C-A152193E4F40}.Debug|ARM64.ActiveCfg = Debug|ARM64 + {25FB3D24-744A-4481-905C-A152193E4F40}.Debug|ARM64.Build.0 = Debug|ARM64 + {25FB3D24-744A-4481-905C-A152193E4F40}.Debug|ARM64.Deploy.0 = Debug|ARM64 + {25FB3D24-744A-4481-905C-A152193E4F40}.Release|Win32.ActiveCfg = Release|Win32 + {25FB3D24-744A-4481-905C-A152193E4F40}.Release|Win32.Build.0 = Release|Win32 + {25FB3D24-744A-4481-905C-A152193E4F40}.Release|Win32.Deploy.0 = Release|Win32 + {25FB3D24-744A-4481-905C-A152193E4F40}.Release|x64.ActiveCfg = Release|x64 + {25FB3D24-744A-4481-905C-A152193E4F40}.Release|x64.Build.0 = Release|x64 + {25FB3D24-744A-4481-905C-A152193E4F40}.Release|x64.Deploy.0 = Release|x64 + {25FB3D24-744A-4481-905C-A152193E4F40}.Release|ARM64.ActiveCfg = Release|ARM64 + {25FB3D24-744A-4481-905C-A152193E4F40}.Release|ARM64.Build.0 = Release|ARM64 + {25FB3D24-744A-4481-905C-A152193E4F40}.Release|ARM64.Deploy.0 = Release|ARM64 + {7B45A0E8-BDB1-49BA-B8F1-0AC447DFB7A3}.Debug|Win32.ActiveCfg = Debug|Win32 + {7B45A0E8-BDB1-49BA-B8F1-0AC447DFB7A3}.Debug|Win32.Build.0 = Debug|Win32 + {7B45A0E8-BDB1-49BA-B8F1-0AC447DFB7A3}.Debug|Win32.Deploy.0 = Debug|Win32 + {7B45A0E8-BDB1-49BA-B8F1-0AC447DFB7A3}.Debug|x64.ActiveCfg = Debug|x64 + {7B45A0E8-BDB1-49BA-B8F1-0AC447DFB7A3}.Debug|x64.Build.0 = Debug|x64 + {7B45A0E8-BDB1-49BA-B8F1-0AC447DFB7A3}.Debug|x64.Deploy.0 = Debug|x64 + {7B45A0E8-BDB1-49BA-B8F1-0AC447DFB7A3}.Debug|ARM64.ActiveCfg = Debug|ARM64 + {7B45A0E8-BDB1-49BA-B8F1-0AC447DFB7A3}.Debug|ARM64.Build.0 = Debug|ARM64 + {7B45A0E8-BDB1-49BA-B8F1-0AC447DFB7A3}.Debug|ARM64.Deploy.0 = Debug|ARM64 + {7B45A0E8-BDB1-49BA-B8F1-0AC447DFB7A3}.Release|Win32.ActiveCfg = Release|Win32 + {7B45A0E8-BDB1-49BA-B8F1-0AC447DFB7A3}.Release|Win32.Build.0 = Release|Win32 + {7B45A0E8-BDB1-49BA-B8F1-0AC447DFB7A3}.Release|Win32.Deploy.0 = Release|Win32 + {7B45A0E8-BDB1-49BA-B8F1-0AC447DFB7A3}.Release|x64.ActiveCfg = Release|x64 + {7B45A0E8-BDB1-49BA-B8F1-0AC447DFB7A3}.Release|x64.Build.0 = Release|x64 + {7B45A0E8-BDB1-49BA-B8F1-0AC447DFB7A3}.Release|x64.Deploy.0 = Release|x64 + {7B45A0E8-BDB1-49BA-B8F1-0AC447DFB7A3}.Release|ARM64.ActiveCfg = Release|ARM64 + {7B45A0E8-BDB1-49BA-B8F1-0AC447DFB7A3}.Release|ARM64.Build.0 = Release|ARM64 + {7B45A0E8-BDB1-49BA-B8F1-0AC447DFB7A3}.Release|ARM64.Deploy.0 = Release|ARM64 + {8625CEF7-34E2-4C61-99B1-1F1BDB9AE9FA}.Debug|Win32.ActiveCfg = Debug|Win32 + {8625CEF7-34E2-4C61-99B1-1F1BDB9AE9FA}.Debug|Win32.Build.0 = Debug|Win32 + {8625CEF7-34E2-4C61-99B1-1F1BDB9AE9FA}.Debug|Win32.Deploy.0 = Debug|Win32 + {8625CEF7-34E2-4C61-99B1-1F1BDB9AE9FA}.Debug|x64.ActiveCfg = Debug|x64 + {8625CEF7-34E2-4C61-99B1-1F1BDB9AE9FA}.Debug|x64.Build.0 = Debug|x64 + {8625CEF7-34E2-4C61-99B1-1F1BDB9AE9FA}.Debug|x64.Deploy.0 = Debug|x64 + {8625CEF7-34E2-4C61-99B1-1F1BDB9AE9FA}.Debug|ARM64.ActiveCfg = Debug|ARM64 + {8625CEF7-34E2-4C61-99B1-1F1BDB9AE9FA}.Debug|ARM64.Build.0 = Debug|ARM64 + {8625CEF7-34E2-4C61-99B1-1F1BDB9AE9FA}.Debug|ARM64.Deploy.0 = Debug|ARM64 + {8625CEF7-34E2-4C61-99B1-1F1BDB9AE9FA}.Release|Win32.ActiveCfg = Release|Win32 + {8625CEF7-34E2-4C61-99B1-1F1BDB9AE9FA}.Release|Win32.Build.0 = Release|Win32 + {8625CEF7-34E2-4C61-99B1-1F1BDB9AE9FA}.Release|Win32.Deploy.0 = Release|Win32 + {8625CEF7-34E2-4C61-99B1-1F1BDB9AE9FA}.Release|x64.ActiveCfg = Release|x64 + {8625CEF7-34E2-4C61-99B1-1F1BDB9AE9FA}.Release|x64.Build.0 = Release|x64 + {8625CEF7-34E2-4C61-99B1-1F1BDB9AE9FA}.Release|x64.Deploy.0 = Release|x64 + {8625CEF7-34E2-4C61-99B1-1F1BDB9AE9FA}.Release|ARM64.ActiveCfg = Release|ARM64 + {8625CEF7-34E2-4C61-99B1-1F1BDB9AE9FA}.Release|ARM64.Build.0 = Release|ARM64 + {8625CEF7-34E2-4C61-99B1-1F1BDB9AE9FA}.Release|ARM64.Deploy.0 = Release|ARM64 + {61E57184-67FE-4B58-99DC-1997E30A436C}.Debug|Win32.ActiveCfg = Debug|Win32 + {61E57184-67FE-4B58-99DC-1997E30A436C}.Debug|Win32.Build.0 = Debug|Win32 + {61E57184-67FE-4B58-99DC-1997E30A436C}.Debug|Win32.Deploy.0 = Debug|Win32 + {61E57184-67FE-4B58-99DC-1997E30A436C}.Debug|x64.ActiveCfg = Debug|x64 + {61E57184-67FE-4B58-99DC-1997E30A436C}.Debug|x64.Build.0 = Debug|x64 + {61E57184-67FE-4B58-99DC-1997E30A436C}.Debug|x64.Deploy.0 = Debug|x64 + {61E57184-67FE-4B58-99DC-1997E30A436C}.Debug|ARM64.ActiveCfg = Debug|ARM64 + {61E57184-67FE-4B58-99DC-1997E30A436C}.Debug|ARM64.Build.0 = Debug|ARM64 + {61E57184-67FE-4B58-99DC-1997E30A436C}.Debug|ARM64.Deploy.0 = Debug|ARM64 + {61E57184-67FE-4B58-99DC-1997E30A436C}.Release|Win32.ActiveCfg = Release|Win32 + {61E57184-67FE-4B58-99DC-1997E30A436C}.Release|Win32.Build.0 = Release|Win32 + {61E57184-67FE-4B58-99DC-1997E30A436C}.Release|Win32.Deploy.0 = Release|Win32 + {61E57184-67FE-4B58-99DC-1997E30A436C}.Release|x64.ActiveCfg = Release|x64 + {61E57184-67FE-4B58-99DC-1997E30A436C}.Release|x64.Build.0 = Release|x64 + {61E57184-67FE-4B58-99DC-1997E30A436C}.Release|x64.Deploy.0 = Release|x64 + {61E57184-67FE-4B58-99DC-1997E30A436C}.Release|ARM64.ActiveCfg = Release|ARM64 + {61E57184-67FE-4B58-99DC-1997E30A436C}.Release|ARM64.Build.0 = Release|ARM64 + {61E57184-67FE-4B58-99DC-1997E30A436C}.Release|ARM64.Deploy.0 = Release|ARM64 + {B4FD73EE-7F06-4061-A0C7-8BE8EB0F3C19}.Debug|Win32.ActiveCfg = Debug|Win32 + {B4FD73EE-7F06-4061-A0C7-8BE8EB0F3C19}.Debug|Win32.Build.0 = Debug|Win32 + {B4FD73EE-7F06-4061-A0C7-8BE8EB0F3C19}.Debug|Win32.Deploy.0 = Debug|Win32 + {B4FD73EE-7F06-4061-A0C7-8BE8EB0F3C19}.Debug|x64.ActiveCfg = Debug|x64 + {B4FD73EE-7F06-4061-A0C7-8BE8EB0F3C19}.Debug|x64.Build.0 = Debug|x64 + {B4FD73EE-7F06-4061-A0C7-8BE8EB0F3C19}.Debug|x64.Deploy.0 = Debug|x64 + {B4FD73EE-7F06-4061-A0C7-8BE8EB0F3C19}.Debug|ARM64.ActiveCfg = Debug|ARM64 + {B4FD73EE-7F06-4061-A0C7-8BE8EB0F3C19}.Debug|ARM64.Build.0 = Debug|ARM64 + {B4FD73EE-7F06-4061-A0C7-8BE8EB0F3C19}.Debug|ARM64.Deploy.0 = Debug|ARM64 + {B4FD73EE-7F06-4061-A0C7-8BE8EB0F3C19}.Release|Win32.ActiveCfg = Release|Win32 + {B4FD73EE-7F06-4061-A0C7-8BE8EB0F3C19}.Release|Win32.Build.0 = Release|Win32 + {B4FD73EE-7F06-4061-A0C7-8BE8EB0F3C19}.Release|Win32.Deploy.0 = Release|Win32 + {B4FD73EE-7F06-4061-A0C7-8BE8EB0F3C19}.Release|x64.ActiveCfg = Release|x64 + {B4FD73EE-7F06-4061-A0C7-8BE8EB0F3C19}.Release|x64.Build.0 = Release|x64 + {B4FD73EE-7F06-4061-A0C7-8BE8EB0F3C19}.Release|x64.Deploy.0 = Release|x64 + {B4FD73EE-7F06-4061-A0C7-8BE8EB0F3C19}.Release|ARM64.ActiveCfg = Release|ARM64 + {B4FD73EE-7F06-4061-A0C7-8BE8EB0F3C19}.Release|ARM64.Build.0 = Release|ARM64 + {B4FD73EE-7F06-4061-A0C7-8BE8EB0F3C19}.Release|ARM64.Deploy.0 = Release|ARM64 + {0643EB75-38AD-4FFF-9A99-876E19BD5463}.Debug|Win32.ActiveCfg = Debug|Win32 + {0643EB75-38AD-4FFF-9A99-876E19BD5463}.Debug|Win32.Build.0 = Debug|Win32 + {0643EB75-38AD-4FFF-9A99-876E19BD5463}.Debug|Win32.Deploy.0 = Debug|Win32 + {0643EB75-38AD-4FFF-9A99-876E19BD5463}.Debug|x64.ActiveCfg = Debug|x64 + {0643EB75-38AD-4FFF-9A99-876E19BD5463}.Debug|x64.Build.0 = Debug|x64 + {0643EB75-38AD-4FFF-9A99-876E19BD5463}.Debug|x64.Deploy.0 = Debug|x64 + {0643EB75-38AD-4FFF-9A99-876E19BD5463}.Debug|ARM64.ActiveCfg = Debug|ARM64 + {0643EB75-38AD-4FFF-9A99-876E19BD5463}.Debug|ARM64.Build.0 = Debug|ARM64 + {0643EB75-38AD-4FFF-9A99-876E19BD5463}.Debug|ARM64.Deploy.0 = Debug|ARM64 + {0643EB75-38AD-4FFF-9A99-876E19BD5463}.Release|Win32.ActiveCfg = Release|Win32 + {0643EB75-38AD-4FFF-9A99-876E19BD5463}.Release|Win32.Build.0 = Release|Win32 + {0643EB75-38AD-4FFF-9A99-876E19BD5463}.Release|Win32.Deploy.0 = Release|Win32 + {0643EB75-38AD-4FFF-9A99-876E19BD5463}.Release|x64.ActiveCfg = Release|x64 + {0643EB75-38AD-4FFF-9A99-876E19BD5463}.Release|x64.Build.0 = Release|x64 + {0643EB75-38AD-4FFF-9A99-876E19BD5463}.Release|x64.Deploy.0 = Release|x64 + {0643EB75-38AD-4FFF-9A99-876E19BD5463}.Release|ARM64.ActiveCfg = Release|ARM64 + {0643EB75-38AD-4FFF-9A99-876E19BD5463}.Release|ARM64.Build.0 = Release|ARM64 + {0643EB75-38AD-4FFF-9A99-876E19BD5463}.Release|ARM64.Deploy.0 = Release|ARM64 + {EE034D50-BF51-4644-BAED-C6359830F316}.Debug|Win32.ActiveCfg = Debug|Win32 + {EE034D50-BF51-4644-BAED-C6359830F316}.Debug|Win32.Build.0 = Debug|Win32 + {EE034D50-BF51-4644-BAED-C6359830F316}.Debug|Win32.Deploy.0 = Debug|Win32 + {EE034D50-BF51-4644-BAED-C6359830F316}.Debug|x64.ActiveCfg = Debug|x64 + {EE034D50-BF51-4644-BAED-C6359830F316}.Debug|x64.Build.0 = Debug|x64 + {EE034D50-BF51-4644-BAED-C6359830F316}.Debug|x64.Deploy.0 = Debug|x64 + {EE034D50-BF51-4644-BAED-C6359830F316}.Debug|ARM64.ActiveCfg = Debug|ARM64 + {EE034D50-BF51-4644-BAED-C6359830F316}.Debug|ARM64.Build.0 = Debug|ARM64 + {EE034D50-BF51-4644-BAED-C6359830F316}.Debug|ARM64.Deploy.0 = Debug|ARM64 + {EE034D50-BF51-4644-BAED-C6359830F316}.Release|Win32.ActiveCfg = Release|Win32 + {EE034D50-BF51-4644-BAED-C6359830F316}.Release|Win32.Build.0 = Release|Win32 + {EE034D50-BF51-4644-BAED-C6359830F316}.Release|Win32.Deploy.0 = Release|Win32 + {EE034D50-BF51-4644-BAED-C6359830F316}.Release|x64.ActiveCfg = Release|x64 + {EE034D50-BF51-4644-BAED-C6359830F316}.Release|x64.Build.0 = Release|x64 + {EE034D50-BF51-4644-BAED-C6359830F316}.Release|x64.Deploy.0 = Release|x64 + {EE034D50-BF51-4644-BAED-C6359830F316}.Release|ARM64.ActiveCfg = Release|ARM64 + {EE034D50-BF51-4644-BAED-C6359830F316}.Release|ARM64.Build.0 = Release|ARM64 + {EE034D50-BF51-4644-BAED-C6359830F316}.Release|ARM64.Deploy.0 = Release|ARM64 + {F48A8DBC-32FF-4923-8F30-A7A64C4C2475}.Debug|Win32.ActiveCfg = Debug|Win32 + {F48A8DBC-32FF-4923-8F30-A7A64C4C2475}.Debug|Win32.Build.0 = Debug|Win32 + {F48A8DBC-32FF-4923-8F30-A7A64C4C2475}.Debug|Win32.Deploy.0 = Debug|Win32 + {F48A8DBC-32FF-4923-8F30-A7A64C4C2475}.Debug|x64.ActiveCfg = Debug|x64 + {F48A8DBC-32FF-4923-8F30-A7A64C4C2475}.Debug|x64.Build.0 = Debug|x64 + {F48A8DBC-32FF-4923-8F30-A7A64C4C2475}.Debug|x64.Deploy.0 = Debug|x64 + {F48A8DBC-32FF-4923-8F30-A7A64C4C2475}.Debug|ARM64.ActiveCfg = Debug|ARM64 + {F48A8DBC-32FF-4923-8F30-A7A64C4C2475}.Debug|ARM64.Build.0 = Debug|ARM64 + {F48A8DBC-32FF-4923-8F30-A7A64C4C2475}.Debug|ARM64.Deploy.0 = Debug|ARM64 + {F48A8DBC-32FF-4923-8F30-A7A64C4C2475}.Release|Win32.ActiveCfg = Release|Win32 + {F48A8DBC-32FF-4923-8F30-A7A64C4C2475}.Release|Win32.Build.0 = Release|Win32 + {F48A8DBC-32FF-4923-8F30-A7A64C4C2475}.Release|Win32.Deploy.0 = Release|Win32 + {F48A8DBC-32FF-4923-8F30-A7A64C4C2475}.Release|x64.ActiveCfg = Release|x64 + {F48A8DBC-32FF-4923-8F30-A7A64C4C2475}.Release|x64.Build.0 = Release|x64 + {F48A8DBC-32FF-4923-8F30-A7A64C4C2475}.Release|x64.Deploy.0 = Release|x64 + {F48A8DBC-32FF-4923-8F30-A7A64C4C2475}.Release|ARM64.ActiveCfg = Release|ARM64 + {F48A8DBC-32FF-4923-8F30-A7A64C4C2475}.Release|ARM64.Build.0 = Release|ARM64 + {F48A8DBC-32FF-4923-8F30-A7A64C4C2475}.Release|ARM64.Deploy.0 = Release|ARM64 + {9A55EFC8-588B-43ED-8193-C1ABC6D54A71}.Debug|Win32.ActiveCfg = Debug|Win32 + {9A55EFC8-588B-43ED-8193-C1ABC6D54A71}.Debug|Win32.Build.0 = Debug|Win32 + {9A55EFC8-588B-43ED-8193-C1ABC6D54A71}.Debug|Win32.Deploy.0 = Debug|Win32 + {9A55EFC8-588B-43ED-8193-C1ABC6D54A71}.Debug|x64.ActiveCfg = Debug|x64 + {9A55EFC8-588B-43ED-8193-C1ABC6D54A71}.Debug|x64.Build.0 = Debug|x64 + {9A55EFC8-588B-43ED-8193-C1ABC6D54A71}.Debug|x64.Deploy.0 = Debug|x64 + {9A55EFC8-588B-43ED-8193-C1ABC6D54A71}.Debug|ARM64.ActiveCfg = Debug|ARM64 + {9A55EFC8-588B-43ED-8193-C1ABC6D54A71}.Debug|ARM64.Build.0 = Debug|ARM64 + {9A55EFC8-588B-43ED-8193-C1ABC6D54A71}.Debug|ARM64.Deploy.0 = Debug|ARM64 + {9A55EFC8-588B-43ED-8193-C1ABC6D54A71}.Release|Win32.ActiveCfg = Release|Win32 + {9A55EFC8-588B-43ED-8193-C1ABC6D54A71}.Release|Win32.Build.0 = Release|Win32 + {9A55EFC8-588B-43ED-8193-C1ABC6D54A71}.Release|Win32.Deploy.0 = Release|Win32 + {9A55EFC8-588B-43ED-8193-C1ABC6D54A71}.Release|x64.ActiveCfg = Release|x64 + {9A55EFC8-588B-43ED-8193-C1ABC6D54A71}.Release|x64.Build.0 = Release|x64 + {9A55EFC8-588B-43ED-8193-C1ABC6D54A71}.Release|x64.Deploy.0 = Release|x64 + {9A55EFC8-588B-43ED-8193-C1ABC6D54A71}.Release|ARM64.ActiveCfg = Release|ARM64 + {9A55EFC8-588B-43ED-8193-C1ABC6D54A71}.Release|ARM64.Build.0 = Release|ARM64 + {9A55EFC8-588B-43ED-8193-C1ABC6D54A71}.Release|ARM64.Deploy.0 = Release|ARM64 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal diff --git a/FMOD/api/studio/examples/vs2019/load_banks.vcxproj b/FMOD/api/studio/examples/vs2019/load_banks.vcxproj new file mode 100644 index 0000000..6d369f7 --- /dev/null +++ b/FMOD/api/studio/examples/vs2019/load_banks.vcxproj @@ -0,0 +1,85 @@ + + + + + Debug + Win32 + + + Debug + x64 + + + Debug + ARM64 + + + Release + Win32 + + + Release + x64 + + + Release + ARM64 + + + + x86 + x64 + ARM64 + L + + + {61E57184-67FE-4B58-99DC-1997E30A436C} + + + + Application + v142 + false + true + + + + $(SolutionDir)_builds\$(ProjectName)\$(Configuration)\$(Platform)\ + $(SolutionDir)_builds\$(ProjectName)\$(Configuration)\$(Platform)\Intermediate\ + false + $(ProjectName)$(Suffix) + + + + Level3 + ..\..\..\core\inc;..\..\..\studio\inc + ProgramDatabase + _WIN32_WINNT=0x601;WINVER=0x601;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) + + + Windows + true + ..\..\..\core\lib\$(Arch);..\..\..\studio\lib\$(Arch) + fmod$(Suffix)_vc.lib;fmodstudio$(Suffix)_vc.lib;%(AdditionalDependencies) + + + if not exist ..\bin mkdir ..\bin +copy /Y "$(TargetPath)" ..\bin +copy /Y "..\..\..\core\lib\$(Arch)\fmod$(Suffix).dll" ..\bin +copy /Y "..\..\..\studio\lib\$(Arch)\fmodstudio$(Suffix).dll" ..\bin +copy /Y "..\..\..\core\lib\$(Arch)\fmod$(Suffix).dll" "$(OutDir)" +copy /Y "..\..\..\studio\lib\$(Arch)\fmodstudio$(Suffix).dll" "$(OutDir)" + + + + + + + + + + + + + + diff --git a/FMOD/api/studio/examples/vs2019/load_banks.vcxproj.filters b/FMOD/api/studio/examples/vs2019/load_banks.vcxproj.filters new file mode 100644 index 0000000..fc0f117 --- /dev/null +++ b/FMOD/api/studio/examples/vs2019/load_banks.vcxproj.filters @@ -0,0 +1,24 @@ + + + + + common + + + common + + + + + {937abb1b-0123-4875-9828-07ed9f9813e3} + + + + + common + + + common + + + \ No newline at end of file diff --git a/FMOD/api/studio/examples/vs2019/music_callbacks.vcxproj b/FMOD/api/studio/examples/vs2019/music_callbacks.vcxproj new file mode 100644 index 0000000..c08f7ca --- /dev/null +++ b/FMOD/api/studio/examples/vs2019/music_callbacks.vcxproj @@ -0,0 +1,85 @@ + + + + + Debug + Win32 + + + Debug + x64 + + + Debug + ARM64 + + + Release + Win32 + + + Release + x64 + + + Release + ARM64 + + + + x86 + x64 + ARM64 + L + + + {B4FD73EE-7F06-4061-A0C7-8BE8EB0F3C19} + + + + Application + v142 + false + true + + + + $(SolutionDir)_builds\$(ProjectName)\$(Configuration)\$(Platform)\ + $(SolutionDir)_builds\$(ProjectName)\$(Configuration)\$(Platform)\Intermediate\ + false + $(ProjectName)$(Suffix) + + + + Level3 + ..\..\..\core\inc;..\..\..\studio\inc + ProgramDatabase + _WIN32_WINNT=0x601;WINVER=0x601;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) + + + Windows + true + ..\..\..\core\lib\$(Arch);..\..\..\studio\lib\$(Arch) + fmod$(Suffix)_vc.lib;fmodstudio$(Suffix)_vc.lib;%(AdditionalDependencies) + + + if not exist ..\bin mkdir ..\bin +copy /Y "$(TargetPath)" ..\bin +copy /Y "..\..\..\core\lib\$(Arch)\fmod$(Suffix).dll" ..\bin +copy /Y "..\..\..\studio\lib\$(Arch)\fmodstudio$(Suffix).dll" ..\bin +copy /Y "..\..\..\core\lib\$(Arch)\fmod$(Suffix).dll" "$(OutDir)" +copy /Y "..\..\..\studio\lib\$(Arch)\fmodstudio$(Suffix).dll" "$(OutDir)" + + + + + + + + + + + + + + diff --git a/FMOD/api/studio/examples/vs2019/music_callbacks.vcxproj.filters b/FMOD/api/studio/examples/vs2019/music_callbacks.vcxproj.filters new file mode 100644 index 0000000..fc0f117 --- /dev/null +++ b/FMOD/api/studio/examples/vs2019/music_callbacks.vcxproj.filters @@ -0,0 +1,24 @@ + + + + + common + + + common + + + + + {937abb1b-0123-4875-9828-07ed9f9813e3} + + + + + common + + + common + + + \ No newline at end of file diff --git a/FMOD/api/studio/examples/vs2019/objectpan.vcxproj b/FMOD/api/studio/examples/vs2019/objectpan.vcxproj new file mode 100644 index 0000000..15f0931 --- /dev/null +++ b/FMOD/api/studio/examples/vs2019/objectpan.vcxproj @@ -0,0 +1,85 @@ + + + + + Debug + Win32 + + + Debug + x64 + + + Debug + ARM64 + + + Release + Win32 + + + Release + x64 + + + Release + ARM64 + + + + x86 + x64 + ARM64 + L + + + {0643EB75-38AD-4FFF-9A99-876E19BD5463} + + + + Application + v142 + false + true + + + + $(SolutionDir)_builds\$(ProjectName)\$(Configuration)\$(Platform)\ + $(SolutionDir)_builds\$(ProjectName)\$(Configuration)\$(Platform)\Intermediate\ + false + $(ProjectName)$(Suffix) + + + + Level3 + ..\..\..\core\inc;..\..\..\studio\inc + ProgramDatabase + _WIN32_WINNT=0x601;WINVER=0x601;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) + + + Windows + true + ..\..\..\core\lib\$(Arch);..\..\..\studio\lib\$(Arch) + fmod$(Suffix)_vc.lib;fmodstudio$(Suffix)_vc.lib;%(AdditionalDependencies) + + + if not exist ..\bin mkdir ..\bin +copy /Y "$(TargetPath)" ..\bin +copy /Y "..\..\..\core\lib\$(Arch)\fmod$(Suffix).dll" ..\bin +copy /Y "..\..\..\studio\lib\$(Arch)\fmodstudio$(Suffix).dll" ..\bin +copy /Y "..\..\..\core\lib\$(Arch)\fmod$(Suffix).dll" "$(OutDir)" +copy /Y "..\..\..\studio\lib\$(Arch)\fmodstudio$(Suffix).dll" "$(OutDir)" + + + + + + + + + + + + + + diff --git a/FMOD/api/studio/examples/vs2019/objectpan.vcxproj.filters b/FMOD/api/studio/examples/vs2019/objectpan.vcxproj.filters new file mode 100644 index 0000000..fc0f117 --- /dev/null +++ b/FMOD/api/studio/examples/vs2019/objectpan.vcxproj.filters @@ -0,0 +1,24 @@ + + + + + common + + + common + + + + + {937abb1b-0123-4875-9828-07ed9f9813e3} + + + + + common + + + common + + + \ No newline at end of file diff --git a/FMOD/api/studio/examples/vs2019/programmer_sound.vcxproj b/FMOD/api/studio/examples/vs2019/programmer_sound.vcxproj new file mode 100644 index 0000000..48ba750 --- /dev/null +++ b/FMOD/api/studio/examples/vs2019/programmer_sound.vcxproj @@ -0,0 +1,85 @@ + + + + + Debug + Win32 + + + Debug + x64 + + + Debug + ARM64 + + + Release + Win32 + + + Release + x64 + + + Release + ARM64 + + + + x86 + x64 + ARM64 + L + + + {EE034D50-BF51-4644-BAED-C6359830F316} + + + + Application + v142 + false + true + + + + $(SolutionDir)_builds\$(ProjectName)\$(Configuration)\$(Platform)\ + $(SolutionDir)_builds\$(ProjectName)\$(Configuration)\$(Platform)\Intermediate\ + false + $(ProjectName)$(Suffix) + + + + Level3 + ..\..\..\core\inc;..\..\..\studio\inc + ProgramDatabase + _WIN32_WINNT=0x601;WINVER=0x601;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) + + + Windows + true + ..\..\..\core\lib\$(Arch);..\..\..\studio\lib\$(Arch) + fmod$(Suffix)_vc.lib;fmodstudio$(Suffix)_vc.lib;%(AdditionalDependencies) + + + if not exist ..\bin mkdir ..\bin +copy /Y "$(TargetPath)" ..\bin +copy /Y "..\..\..\core\lib\$(Arch)\fmod$(Suffix).dll" ..\bin +copy /Y "..\..\..\studio\lib\$(Arch)\fmodstudio$(Suffix).dll" ..\bin +copy /Y "..\..\..\core\lib\$(Arch)\fmod$(Suffix).dll" "$(OutDir)" +copy /Y "..\..\..\studio\lib\$(Arch)\fmodstudio$(Suffix).dll" "$(OutDir)" + + + + + + + + + + + + + + diff --git a/FMOD/api/studio/examples/vs2019/programmer_sound.vcxproj.filters b/FMOD/api/studio/examples/vs2019/programmer_sound.vcxproj.filters new file mode 100644 index 0000000..fc0f117 --- /dev/null +++ b/FMOD/api/studio/examples/vs2019/programmer_sound.vcxproj.filters @@ -0,0 +1,24 @@ + + + + + common + + + common + + + + + {937abb1b-0123-4875-9828-07ed9f9813e3} + + + + + common + + + common + + + \ No newline at end of file diff --git a/FMOD/api/studio/examples/vs2019/recording_playback.vcxproj b/FMOD/api/studio/examples/vs2019/recording_playback.vcxproj new file mode 100644 index 0000000..c146896 --- /dev/null +++ b/FMOD/api/studio/examples/vs2019/recording_playback.vcxproj @@ -0,0 +1,85 @@ + + + + + Debug + Win32 + + + Debug + x64 + + + Debug + ARM64 + + + Release + Win32 + + + Release + x64 + + + Release + ARM64 + + + + x86 + x64 + ARM64 + L + + + {F48A8DBC-32FF-4923-8F30-A7A64C4C2475} + + + + Application + v142 + false + true + + + + $(SolutionDir)_builds\$(ProjectName)\$(Configuration)\$(Platform)\ + $(SolutionDir)_builds\$(ProjectName)\$(Configuration)\$(Platform)\Intermediate\ + false + $(ProjectName)$(Suffix) + + + + Level3 + ..\..\..\core\inc;..\..\..\studio\inc + ProgramDatabase + _WIN32_WINNT=0x601;WINVER=0x601;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) + + + Windows + true + ..\..\..\core\lib\$(Arch);..\..\..\studio\lib\$(Arch) + fmod$(Suffix)_vc.lib;fmodstudio$(Suffix)_vc.lib;%(AdditionalDependencies) + + + if not exist ..\bin mkdir ..\bin +copy /Y "$(TargetPath)" ..\bin +copy /Y "..\..\..\core\lib\$(Arch)\fmod$(Suffix).dll" ..\bin +copy /Y "..\..\..\studio\lib\$(Arch)\fmodstudio$(Suffix).dll" ..\bin +copy /Y "..\..\..\core\lib\$(Arch)\fmod$(Suffix).dll" "$(OutDir)" +copy /Y "..\..\..\studio\lib\$(Arch)\fmodstudio$(Suffix).dll" "$(OutDir)" + + + + + + + + + + + + + + diff --git a/FMOD/api/studio/examples/vs2019/recording_playback.vcxproj.filters b/FMOD/api/studio/examples/vs2019/recording_playback.vcxproj.filters new file mode 100644 index 0000000..fc0f117 --- /dev/null +++ b/FMOD/api/studio/examples/vs2019/recording_playback.vcxproj.filters @@ -0,0 +1,24 @@ + + + + + common + + + common + + + + + {937abb1b-0123-4875-9828-07ed9f9813e3} + + + + + common + + + common + + + \ No newline at end of file diff --git a/FMOD/api/studio/examples/vs2019/simple_event.vcxproj b/FMOD/api/studio/examples/vs2019/simple_event.vcxproj new file mode 100644 index 0000000..16291db --- /dev/null +++ b/FMOD/api/studio/examples/vs2019/simple_event.vcxproj @@ -0,0 +1,85 @@ + + + + + Debug + Win32 + + + Debug + x64 + + + Debug + ARM64 + + + Release + Win32 + + + Release + x64 + + + Release + ARM64 + + + + x86 + x64 + ARM64 + L + + + {9A55EFC8-588B-43ED-8193-C1ABC6D54A71} + + + + Application + v142 + false + true + + + + $(SolutionDir)_builds\$(ProjectName)\$(Configuration)\$(Platform)\ + $(SolutionDir)_builds\$(ProjectName)\$(Configuration)\$(Platform)\Intermediate\ + false + $(ProjectName)$(Suffix) + + + + Level3 + ..\..\..\core\inc;..\..\..\studio\inc + ProgramDatabase + _WIN32_WINNT=0x601;WINVER=0x601;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) + + + Windows + true + ..\..\..\core\lib\$(Arch);..\..\..\studio\lib\$(Arch) + fmod$(Suffix)_vc.lib;fmodstudio$(Suffix)_vc.lib;%(AdditionalDependencies) + + + if not exist ..\bin mkdir ..\bin +copy /Y "$(TargetPath)" ..\bin +copy /Y "..\..\..\core\lib\$(Arch)\fmod$(Suffix).dll" ..\bin +copy /Y "..\..\..\studio\lib\$(Arch)\fmodstudio$(Suffix).dll" ..\bin +copy /Y "..\..\..\core\lib\$(Arch)\fmod$(Suffix).dll" "$(OutDir)" +copy /Y "..\..\..\studio\lib\$(Arch)\fmodstudio$(Suffix).dll" "$(OutDir)" + + + + + + + + + + + + + + diff --git a/FMOD/api/studio/examples/vs2019/simple_event.vcxproj.filters b/FMOD/api/studio/examples/vs2019/simple_event.vcxproj.filters new file mode 100644 index 0000000..fc0f117 --- /dev/null +++ b/FMOD/api/studio/examples/vs2019/simple_event.vcxproj.filters @@ -0,0 +1,24 @@ + + + + + common + + + common + + + + + {937abb1b-0123-4875-9828-07ed9f9813e3} + + + + + common + + + common + + + \ No newline at end of file diff --git a/FMOD/api/studio/inc/fmod_studio.cs b/FMOD/api/studio/inc/fmod_studio.cs new file mode 100644 index 0000000..8424348 --- /dev/null +++ b/FMOD/api/studio/inc/fmod_studio.cs @@ -0,0 +1,2260 @@ +/* ======================================================================================== */ +/* FMOD Studio API - C# wrapper. */ +/* Copyright (c), Firelight Technologies Pty, Ltd. 2004-2026. */ +/* */ +/* For more detail visit: */ +/* https://fmod.com/docs/2.03/api/studio-api.html */ +/* ======================================================================================== */ + +using System; +using System.Text; +using System.Runtime.InteropServices; +using System.Collections; + +namespace FMOD.Studio +{ + public partial class STUDIO_VERSION + { +#if !UNITY_2021_3_OR_NEWER + public const string dll = "fmodstudio" + VERSION.suffix; +#endif + } + + public enum STOP_MODE : int + { + ALLOWFADEOUT, + IMMEDIATE, + } + + public enum LOADING_STATE : int + { + UNLOADING, + UNLOADED, + LOADING, + LOADED, + ERROR, + } + + [StructLayout(LayoutKind.Sequential)] + public struct PROGRAMMER_SOUND_PROPERTIES + { + public StringWrapper name; + public IntPtr sound; + public int subsoundIndex; + } + + [StructLayout(LayoutKind.Sequential)] + public struct TIMELINE_MARKER_PROPERTIES + { + public StringWrapper name; + public int position; + } + + [StructLayout(LayoutKind.Sequential)] + public struct TIMELINE_BEAT_PROPERTIES + { + public int bar; + public int beat; + public int position; + public float tempo; + public int timesignatureupper; + public int timesignaturelower; + } + + [StructLayout(LayoutKind.Sequential)] + public struct TIMELINE_NESTED_BEAT_PROPERTIES + { + public GUID eventid; + public TIMELINE_BEAT_PROPERTIES properties; + } + + [StructLayout(LayoutKind.Sequential)] + public struct ADVANCEDSETTINGS + { + public int cbsize; + public int commandqueuesize; + public int handleinitialsize; + public int studioupdateperiod; + public int idlesampledatapoolsize; + public int streamingscheduledelay; + public IntPtr encryptionkey; + } + + [StructLayout(LayoutKind.Sequential)] + public struct CPU_USAGE + { + public float update; + } + + [StructLayout(LayoutKind.Sequential)] + public struct BUFFER_INFO + { + public int currentusage; + public int peakusage; + public int capacity; + public int stallcount; + public float stalltime; + } + + [StructLayout(LayoutKind.Sequential)] + public struct BUFFER_USAGE + { + public BUFFER_INFO studiocommandqueue; + public BUFFER_INFO studiohandle; + } + + [StructLayout(LayoutKind.Sequential)] + public struct BANK_INFO + { + public int size; + public IntPtr userdata; + public int userdatalength; + public FILE_OPEN_CALLBACK opencallback; + public FILE_CLOSE_CALLBACK closecallback; + public FILE_READ_CALLBACK readcallback; + public FILE_SEEK_CALLBACK seekcallback; + } + + [Flags] + public enum SYSTEM_CALLBACK_TYPE : uint + { + PREUPDATE = 0x00000001, + POSTUPDATE = 0x00000002, + BANK_UNLOAD = 0x00000004, + LIVEUPDATE_CONNECTED = 0x00000008, + LIVEUPDATE_DISCONNECTED = 0x00000010, + ALL = 0xFFFFFFFF, + } + + public delegate RESULT SYSTEM_CALLBACK(IntPtr system, SYSTEM_CALLBACK_TYPE type, IntPtr commanddata, IntPtr userdata); + + public enum PARAMETER_TYPE : int + { + GAME_CONTROLLED, + AUTOMATIC_DISTANCE, + AUTOMATIC_EVENT_CONE_ANGLE, + AUTOMATIC_EVENT_ORIENTATION, + AUTOMATIC_DIRECTION, + AUTOMATIC_ELEVATION, + AUTOMATIC_LISTENER_ORIENTATION, + AUTOMATIC_SPEED, + AUTOMATIC_SPEED_ABSOLUTE, + AUTOMATIC_DISTANCE_NORMALIZED, + MAX + } + + [Flags] + public enum PARAMETER_FLAGS : uint + { + READONLY = 0x00000001, + AUTOMATIC = 0x00000002, + GLOBAL = 0x00000004, + DISCRETE = 0x00000008, + LABELED = 0x00000010, + } + + [StructLayout(LayoutKind.Sequential)] + public struct PARAMETER_ID + { + public uint data1; + public uint data2; + } + + [StructLayout(LayoutKind.Sequential)] + public struct PARAMETER_DESCRIPTION + { + public StringWrapper name; + public PARAMETER_ID id; + public float minimum; + public float maximum; + public float defaultvalue; + public PARAMETER_TYPE type; + public PARAMETER_FLAGS flags; + public GUID guid; + } + + // This is only need for loading memory and given our C# wrapper LOAD_MEMORY_POINT isn't feasible anyway + enum LOAD_MEMORY_MODE : int + { + LOAD_MEMORY, + LOAD_MEMORY_POINT, + } + + enum LOAD_MEMORY_ALIGNMENT : int + { + VALUE = 32 + } + + [StructLayout(LayoutKind.Sequential)] + public struct SOUND_INFO + { + public IntPtr name_or_data; + public MODE mode; + public CREATESOUNDEXINFO exinfo; + public int subsoundindex; + + public string name + { + get + { + using (StringHelper.ThreadSafeEncoding encoding = StringHelper.GetFreeHelper()) + { + return ((mode & (MODE.OPENMEMORY | MODE.OPENMEMORY_POINT)) == 0) ? encoding.stringFromNative(name_or_data) : String.Empty; + } + } + } + } + + public enum USER_PROPERTY_TYPE : int + { + INTEGER, + BOOLEAN, + FLOAT, + STRING, + } + + [StructLayout(LayoutKind.Sequential)] + public struct USER_PROPERTY + { + public StringWrapper name; + public USER_PROPERTY_TYPE type; + private Union_IntBoolFloatString value; + + public int intValue() { return (type == USER_PROPERTY_TYPE.INTEGER) ? value.intvalue : -1; } + public bool boolValue() { return (type == USER_PROPERTY_TYPE.BOOLEAN) ? value.boolvalue : false; } + public float floatValue() { return (type == USER_PROPERTY_TYPE.FLOAT) ? value.floatvalue : -1; } + public string stringValue() { return (type == USER_PROPERTY_TYPE.STRING) ? value.stringvalue : ""; } + }; + + [StructLayout(LayoutKind.Explicit)] + struct Union_IntBoolFloatString + { + [FieldOffset(0)] + public int intvalue; + [FieldOffset(0)] + public bool boolvalue; + [FieldOffset(0)] + public float floatvalue; + [FieldOffset(0)] + public StringWrapper stringvalue; + } + + [Flags] + public enum INITFLAGS : uint + { + NORMAL = 0x00000000, + LIVEUPDATE = 0x00000001, + ALLOW_MISSING_PLUGINS = 0x00000002, + SYNCHRONOUS_UPDATE = 0x00000004, + DEFERRED_CALLBACKS = 0x00000008, + LOAD_FROM_UPDATE = 0x00000010, + MEMORY_TRACKING = 0x00000020, + } + + [Flags] + public enum LOAD_BANK_FLAGS : uint + { + NORMAL = 0x00000000, + NONBLOCKING = 0x00000001, + DECOMPRESS_SAMPLES = 0x00000002, + UNENCRYPTED = 0x00000004, + } + + [Flags] + public enum COMMANDCAPTURE_FLAGS : uint + { + NORMAL = 0x00000000, + FILEFLUSH = 0x00000001, + SKIP_INITIAL_STATE = 0x00000002, + } + + [Flags] + public enum COMMANDREPLAY_FLAGS : uint + { + NORMAL = 0x00000000, + SKIP_CLEANUP = 0x00000001, + FAST_FORWARD = 0x00000002, + SKIP_BANK_LOAD = 0x00000004, + } + + public enum PLAYBACK_STATE : int + { + PLAYING, + SUSTAINING, + STOPPED, + STARTING, + STOPPING, + } + + public enum EVENT_PROPERTY : int + { + CHANNELPRIORITY, + SCHEDULE_DELAY, + SCHEDULE_LOOKAHEAD, + MINIMUM_DISTANCE, + MAXIMUM_DISTANCE, + COOLDOWN, + MAX + }; + + [StructLayout(LayoutKind.Sequential)] + public struct PLUGIN_INSTANCE_PROPERTIES + { + public IntPtr name; + public IntPtr dsp; + } + + [Flags] + public enum EVENT_CALLBACK_TYPE : uint + { + CREATED = 0x00000001, + DESTROYED = 0x00000002, + STARTING = 0x00000004, + STARTED = 0x00000008, + RESTARTED = 0x00000010, + STOPPED = 0x00000020, + START_FAILED = 0x00000040, + CREATE_PROGRAMMER_SOUND = 0x00000080, + DESTROY_PROGRAMMER_SOUND = 0x00000100, + PLUGIN_CREATED = 0x00000200, + PLUGIN_DESTROYED = 0x00000400, + TIMELINE_MARKER = 0x00000800, + TIMELINE_BEAT = 0x00001000, + SOUND_PLAYED = 0x00002000, + SOUND_STOPPED = 0x00004000, + REAL_TO_VIRTUAL = 0x00008000, + VIRTUAL_TO_REAL = 0x00010000, + START_EVENT_COMMAND = 0x00020000, + NESTED_TIMELINE_BEAT = 0x00040000, + + ALL = 0xFFFFFFFF, + } + + public delegate RESULT EVENT_CALLBACK(EVENT_CALLBACK_TYPE type, IntPtr _event, IntPtr parameters); + + public delegate RESULT COMMANDREPLAY_FRAME_CALLBACK(IntPtr replay, int commandindex, float currenttime, IntPtr userdata); + public delegate RESULT COMMANDREPLAY_LOAD_BANK_CALLBACK(IntPtr replay, int commandindex, GUID bankguid, IntPtr bankfilename, LOAD_BANK_FLAGS flags, out IntPtr bank, IntPtr userdata); + public delegate RESULT COMMANDREPLAY_CREATE_INSTANCE_CALLBACK(IntPtr replay, int commandindex, IntPtr eventdescription, out IntPtr instance, IntPtr userdata); + + public enum INSTANCETYPE : int + { + NONE, + SYSTEM, + EVENTDESCRIPTION, + EVENTINSTANCE, + PARAMETERINSTANCE, + BUS, + VCA, + BANK, + COMMANDREPLAY, + } + + [StructLayout(LayoutKind.Sequential)] + public struct COMMAND_INFO + { + public StringWrapper commandname; + public int parentcommandindex; + public int framenumber; + public float frametime; + public INSTANCETYPE instancetype; + public INSTANCETYPE outputtype; + public UInt32 instancehandle; + public UInt32 outputhandle; + } + + [StructLayout(LayoutKind.Sequential)] + public struct MEMORY_USAGE + { + public int exclusive; + public int inclusive; + public int sampledata; + } + + public struct Util + { + public static RESULT parseID(string idString, out GUID id) + { + using (StringHelper.ThreadSafeEncoding encoder = StringHelper.GetFreeHelper()) + { + return FMOD_Studio_ParseID(encoder.byteFromStringUTF8(idString), out id); + } + } + + #region importfunctions + [DllImport(STUDIO_VERSION.dll)] + private static extern RESULT FMOD_Studio_ParseID(byte[] idString, out GUID id); + #endregion + } + + public struct System + { + // Initialization / system functions. + public static RESULT create(out System system) + { + return FMOD_Studio_System_Create(out system.handle, VERSION.number); + } + public RESULT setAdvancedSettings(ADVANCEDSETTINGS settings) + { + settings.cbsize = Marshal.SizeOf(); + return FMOD_Studio_System_SetAdvancedSettings(this.handle, ref settings); + } + public RESULT setAdvancedSettings(ADVANCEDSETTINGS settings, string encryptionKey) + { + using (StringHelper.ThreadSafeEncoding encoder = StringHelper.GetFreeHelper()) + { + IntPtr userKey = settings.encryptionkey; + settings.encryptionkey = encoder.intptrFromStringUTF8(encryptionKey); + FMOD.RESULT result = setAdvancedSettings(settings); + settings.encryptionkey = userKey; + return result; + } + } + public RESULT getAdvancedSettings(out ADVANCEDSETTINGS settings) + { + settings.cbsize = Marshal.SizeOf(); + return FMOD_Studio_System_GetAdvancedSettings(this.handle, out settings); + } + public RESULT initialize(int maxchannels, INITFLAGS studioflags, FMOD.INITFLAGS flags, IntPtr extradriverdata) + { + return FMOD_Studio_System_Initialize(this.handle, maxchannels, studioflags, flags, extradriverdata); + } + public RESULT release() + { + return FMOD_Studio_System_Release(this.handle); + } + public RESULT update() + { + return FMOD_Studio_System_Update(this.handle); + } + public RESULT getCoreSystem(out FMOD.System coresystem) + { + return FMOD_Studio_System_GetCoreSystem(this.handle, out coresystem.handle); + } + public RESULT getEvent(string path, out EventDescription _event) + { + using (StringHelper.ThreadSafeEncoding encoder = StringHelper.GetFreeHelper()) + { + return FMOD_Studio_System_GetEvent(this.handle, encoder.byteFromStringUTF8(path), out _event.handle); + } + } + public RESULT getBus(string path, out Bus bus) + { + using (StringHelper.ThreadSafeEncoding encoder = StringHelper.GetFreeHelper()) + { + return FMOD_Studio_System_GetBus(this.handle, encoder.byteFromStringUTF8(path), out bus.handle); + } + } + public RESULT getVCA(string path, out VCA vca) + { + using (StringHelper.ThreadSafeEncoding encoder = StringHelper.GetFreeHelper()) + { + return FMOD_Studio_System_GetVCA(this.handle, encoder.byteFromStringUTF8(path), out vca.handle); + } + } + public RESULT getBank(string path, out Bank bank) + { + using (StringHelper.ThreadSafeEncoding encoder = StringHelper.GetFreeHelper()) + { + return FMOD_Studio_System_GetBank(this.handle, encoder.byteFromStringUTF8(path), out bank.handle); + } + } + + public RESULT getEventByID(GUID id, out EventDescription _event) + { + return FMOD_Studio_System_GetEventByID(this.handle, ref id, out _event.handle); + } + public RESULT getBusByID(GUID id, out Bus bus) + { + return FMOD_Studio_System_GetBusByID(this.handle, ref id, out bus.handle); + } + public RESULT getVCAByID(GUID id, out VCA vca) + { + return FMOD_Studio_System_GetVCAByID(this.handle, ref id, out vca.handle); + } + public RESULT getBankByID(GUID id, out Bank bank) + { + return FMOD_Studio_System_GetBankByID(this.handle, ref id, out bank.handle); + } + public RESULT getSoundInfo(string key, out SOUND_INFO info) + { + using (StringHelper.ThreadSafeEncoding encoder = StringHelper.GetFreeHelper()) + { + return FMOD_Studio_System_GetSoundInfo(this.handle, encoder.byteFromStringUTF8(key), out info); + } + } + public RESULT getParameterDescriptionByName(string name, out PARAMETER_DESCRIPTION parameter) + { + using (StringHelper.ThreadSafeEncoding encoder = StringHelper.GetFreeHelper()) + { + return FMOD_Studio_System_GetParameterDescriptionByName(this.handle, encoder.byteFromStringUTF8(name), out parameter); + } + } + public RESULT getParameterDescriptionByID(PARAMETER_ID id, out PARAMETER_DESCRIPTION parameter) + { + return FMOD_Studio_System_GetParameterDescriptionByID(this.handle, id, out parameter); + } + public RESULT getParameterLabelByName(string name, int labelindex, out string label) + { + label = null; + + using (StringHelper.ThreadSafeEncoding encoder = StringHelper.GetFreeHelper()) + { + IntPtr stringMem = Marshal.AllocHGlobal(256); + int retrieved = 0; + byte[] nameBytes = encoder.byteFromStringUTF8(name); + RESULT result = FMOD_Studio_System_GetParameterLabelByName(this.handle, nameBytes, labelindex, stringMem, 256, out retrieved); + + if (result == RESULT.ERR_TRUNCATED) + { + Marshal.FreeHGlobal(stringMem); + result = FMOD_Studio_System_GetParameterLabelByName(this.handle, nameBytes, labelindex, IntPtr.Zero, 0, out retrieved); + stringMem = Marshal.AllocHGlobal(retrieved); + result = FMOD_Studio_System_GetParameterLabelByName(this.handle, nameBytes, labelindex, stringMem, retrieved, out retrieved); + } + + if (result == RESULT.OK) + { + label = encoder.stringFromNative(stringMem); + } + Marshal.FreeHGlobal(stringMem); + return result; + } + } + public RESULT getParameterLabelByID(PARAMETER_ID id, int labelindex, out string label) + { + label = null; + + using (StringHelper.ThreadSafeEncoding encoder = StringHelper.GetFreeHelper()) + { + IntPtr stringMem = Marshal.AllocHGlobal(256); + int retrieved = 0; + RESULT result = FMOD_Studio_System_GetParameterLabelByID(this.handle, id, labelindex, stringMem, 256, out retrieved); + + if (result == RESULT.ERR_TRUNCATED) + { + Marshal.FreeHGlobal(stringMem); + result = FMOD_Studio_System_GetParameterLabelByID(this.handle, id, labelindex, IntPtr.Zero, 0, out retrieved); + stringMem = Marshal.AllocHGlobal(retrieved); + result = FMOD_Studio_System_GetParameterLabelByID(this.handle, id, labelindex, stringMem, retrieved, out retrieved); + } + + if (result == RESULT.OK) + { + label = encoder.stringFromNative(stringMem); + } + Marshal.FreeHGlobal(stringMem); + return result; + } + } + public RESULT getParameterByID(PARAMETER_ID id, out float value) + { + float finalValue; + return getParameterByID(id, out value, out finalValue); + } + public RESULT getParameterByID(PARAMETER_ID id, out float value, out float finalvalue) + { + return FMOD_Studio_System_GetParameterByID(this.handle, id, out value, out finalvalue); + } + public RESULT setParameterByID(PARAMETER_ID id, float value, bool ignoreseekspeed = false) + { + return FMOD_Studio_System_SetParameterByID(this.handle, id, value, ignoreseekspeed); + } + public RESULT setParameterByIDWithLabel(PARAMETER_ID id, string label, bool ignoreseekspeed = false) + { + using (StringHelper.ThreadSafeEncoding encoder = StringHelper.GetFreeHelper()) + { + return FMOD_Studio_System_SetParameterByIDWithLabel(this.handle, id, encoder.byteFromStringUTF8(label), ignoreseekspeed); + } + } + public RESULT setParametersByIDs(PARAMETER_ID[] ids, float[] values, int count, bool ignoreseekspeed = false) + { + return FMOD_Studio_System_SetParametersByIDs(this.handle, ids, values, count, ignoreseekspeed); + } + public RESULT getParameterByName(string name, out float value) + { + float finalValue; + return getParameterByName(name, out value, out finalValue); + } + public RESULT getParameterByName(string name, out float value, out float finalvalue) + { + using (StringHelper.ThreadSafeEncoding encoder = StringHelper.GetFreeHelper()) + { + return FMOD_Studio_System_GetParameterByName(this.handle, encoder.byteFromStringUTF8(name), out value, out finalvalue); + } + } + public RESULT setParameterByName(string name, float value, bool ignoreseekspeed = false) + { + using (StringHelper.ThreadSafeEncoding encoder = StringHelper.GetFreeHelper()) + { + return FMOD_Studio_System_SetParameterByName(this.handle, encoder.byteFromStringUTF8(name), value, ignoreseekspeed); + } + } + public RESULT setParameterByNameWithLabel(string name, string label, bool ignoreseekspeed = false) + { + using (StringHelper.ThreadSafeEncoding encoder = StringHelper.GetFreeHelper(), + labelEncoder = StringHelper.GetFreeHelper()) + { + return FMOD_Studio_System_SetParameterByNameWithLabel(this.handle, encoder.byteFromStringUTF8(name), labelEncoder.byteFromStringUTF8(label), ignoreseekspeed); + } + } + public RESULT lookupID(string path, out GUID id) + { + using (StringHelper.ThreadSafeEncoding encoder = StringHelper.GetFreeHelper()) + { + return FMOD_Studio_System_LookupID(this.handle, encoder.byteFromStringUTF8(path), out id); + } + } + public RESULT lookupPath(GUID id, out string path) + { + path = null; + + using (StringHelper.ThreadSafeEncoding encoder = StringHelper.GetFreeHelper()) + { + IntPtr stringMem = Marshal.AllocHGlobal(256); + int retrieved = 0; + RESULT result = FMOD_Studio_System_LookupPath(this.handle, ref id, stringMem, 256, out retrieved); + + if (result == RESULT.ERR_TRUNCATED) + { + Marshal.FreeHGlobal(stringMem); + stringMem = Marshal.AllocHGlobal(retrieved); + result = FMOD_Studio_System_LookupPath(this.handle, ref id, stringMem, retrieved, out retrieved); + } + + if (result == RESULT.OK) + { + path = encoder.stringFromNative(stringMem); + } + Marshal.FreeHGlobal(stringMem); + return result; + } + } + public RESULT getNumListeners(out int numlisteners) + { + return FMOD_Studio_System_GetNumListeners(this.handle, out numlisteners); + } + public RESULT setNumListeners(int numlisteners) + { + return FMOD_Studio_System_SetNumListeners(this.handle, numlisteners); + } + public RESULT getListenerAttributes(int listener, out ATTRIBUTES_3D attributes) + { + return FMOD_Studio_System_GetListenerAttributes(this.handle, listener, out attributes, IntPtr.Zero); + } + public RESULT getListenerAttributes(int listener, out ATTRIBUTES_3D attributes, out VECTOR attenuationposition) + { + return FMOD_Studio_System_GetListenerAttributes(this.handle, listener, out attributes, out attenuationposition); + } + public RESULT setListenerAttributes(int listener, ATTRIBUTES_3D attributes) + { + return FMOD_Studio_System_SetListenerAttributes(this.handle, listener, ref attributes, IntPtr.Zero); + } + public RESULT setListenerAttributes(int listener, ATTRIBUTES_3D attributes, VECTOR attenuationposition) + { + return FMOD_Studio_System_SetListenerAttributes(this.handle, listener, ref attributes, ref attenuationposition); + } + public RESULT getListenerWeight(int listener, out float weight) + { + return FMOD_Studio_System_GetListenerWeight(this.handle, listener, out weight); + } + public RESULT setListenerWeight(int listener, float weight) + { + return FMOD_Studio_System_SetListenerWeight(this.handle, listener, weight); + } + public RESULT loadBankFile(string filename, LOAD_BANK_FLAGS flags, out Bank bank) + { + using (StringHelper.ThreadSafeEncoding encoder = StringHelper.GetFreeHelper()) + { + return FMOD_Studio_System_LoadBankFile(this.handle, encoder.byteFromStringUTF8(filename), flags, out bank.handle); + } + } + public RESULT loadBankMemory(byte[] buffer, LOAD_BANK_FLAGS flags, out Bank bank) + { + // Manually pin the byte array. It's what the marshaller should do anyway but don't leave it to chance. + GCHandle pinnedArray = GCHandle.Alloc(buffer, GCHandleType.Pinned); + IntPtr pointer = pinnedArray.AddrOfPinnedObject(); + RESULT result = FMOD_Studio_System_LoadBankMemory(this.handle, pointer, buffer.Length, LOAD_MEMORY_MODE.LOAD_MEMORY, flags, out bank.handle); + pinnedArray.Free(); + return result; + } + public RESULT loadBankMemory(IntPtr buffer, int length, LOAD_BANK_FLAGS flags, out Bank bank) + { + return FMOD_Studio_System_LoadBankMemory(this.handle, buffer, length, LOAD_MEMORY_MODE.LOAD_MEMORY, flags, out bank.handle); + } + public RESULT loadBankCustom(BANK_INFO info, LOAD_BANK_FLAGS flags, out Bank bank) + { + info.size = Marshal.SizeOf(); + return FMOD_Studio_System_LoadBankCustom(this.handle, ref info, flags, out bank.handle); + } + public RESULT unloadAll() + { + return FMOD_Studio_System_UnloadAll(this.handle); + } + public RESULT flushCommands() + { + return FMOD_Studio_System_FlushCommands(this.handle); + } + public RESULT flushSampleLoading() + { + return FMOD_Studio_System_FlushSampleLoading(this.handle); + } + public RESULT startCommandCapture(string filename, COMMANDCAPTURE_FLAGS flags) + { + using (StringHelper.ThreadSafeEncoding encoder = StringHelper.GetFreeHelper()) + { + return FMOD_Studio_System_StartCommandCapture(this.handle, encoder.byteFromStringUTF8(filename), flags); + } + } + public RESULT stopCommandCapture() + { + return FMOD_Studio_System_StopCommandCapture(this.handle); + } + public RESULT loadCommandReplay(string filename, COMMANDREPLAY_FLAGS flags, out CommandReplay replay) + { + using (StringHelper.ThreadSafeEncoding encoder = StringHelper.GetFreeHelper()) + { + return FMOD_Studio_System_LoadCommandReplay(this.handle, encoder.byteFromStringUTF8(filename), flags, out replay.handle); + } + } + public RESULT getBankCount(out int count) + { + return FMOD_Studio_System_GetBankCount(this.handle, out count); + } + public RESULT getBankList(out Bank[] array) + { + array = null; + + RESULT result; + int capacity; + result = FMOD_Studio_System_GetBankCount(this.handle, out capacity); + if (result != RESULT.OK) + { + return result; + } + if (capacity == 0) + { + array = new Bank[0]; + return result; + } + + IntPtr[] rawArray = new IntPtr[capacity]; + int actualCount; + result = FMOD_Studio_System_GetBankList(this.handle, rawArray, capacity, out actualCount); + if (result != RESULT.OK) + { + return result; + } + if (actualCount > capacity) // More items added since we queried just now? + { + actualCount = capacity; + } + array = new Bank[actualCount]; + for (int i = 0; i < actualCount; ++i) + { + array[i].handle = rawArray[i]; + } + return RESULT.OK; + } + public RESULT getParameterDescriptionCount(out int count) + { + return FMOD_Studio_System_GetParameterDescriptionCount(this.handle, out count); + } + public RESULT getParameterDescriptionList(out PARAMETER_DESCRIPTION[] array) + { + array = null; + + int capacity; + RESULT result = FMOD_Studio_System_GetParameterDescriptionCount(this.handle, out capacity); + if (result != RESULT.OK) + { + return result; + } + if (capacity == 0) + { + array = new PARAMETER_DESCRIPTION[0]; + return RESULT.OK; + } + + PARAMETER_DESCRIPTION[] tempArray = new PARAMETER_DESCRIPTION[capacity]; + int actualCount; + result = FMOD_Studio_System_GetParameterDescriptionList(this.handle, tempArray, capacity, out actualCount); + if (result != RESULT.OK) + { + return result; + } + + if (actualCount != capacity) + { + Array.Resize(ref tempArray, actualCount); + } + + array = tempArray; + + return RESULT.OK; + } + public RESULT getCPUUsage(out CPU_USAGE usage, out FMOD.CPU_USAGE usage_core) + { + return FMOD_Studio_System_GetCPUUsage(this.handle, out usage, out usage_core); + } + public RESULT getBufferUsage(out BUFFER_USAGE usage) + { + return FMOD_Studio_System_GetBufferUsage(this.handle, out usage); + } + public RESULT resetBufferUsage() + { + return FMOD_Studio_System_ResetBufferUsage(this.handle); + } + + public RESULT setCallback(SYSTEM_CALLBACK callback, SYSTEM_CALLBACK_TYPE callbackmask = SYSTEM_CALLBACK_TYPE.ALL) + { + return FMOD_Studio_System_SetCallback(this.handle, callback, callbackmask); + } + + public RESULT getUserData(out IntPtr userdata) + { + return FMOD_Studio_System_GetUserData(this.handle, out userdata); + } + + public RESULT setUserData(IntPtr userdata) + { + return FMOD_Studio_System_SetUserData(this.handle, userdata); + } + + public RESULT getMemoryUsage(out MEMORY_USAGE memoryusage) + { + return FMOD_Studio_System_GetMemoryUsage(this.handle, out memoryusage); + } + + #region importfunctions + [DllImport(STUDIO_VERSION.dll)] + private static extern RESULT FMOD_Studio_System_Create (out IntPtr system, uint headerversion); + [DllImport(STUDIO_VERSION.dll)] + private static extern bool FMOD_Studio_System_IsValid (IntPtr system); + [DllImport(STUDIO_VERSION.dll)] + private static extern RESULT FMOD_Studio_System_SetAdvancedSettings (IntPtr system, ref ADVANCEDSETTINGS settings); + [DllImport(STUDIO_VERSION.dll)] + private static extern RESULT FMOD_Studio_System_GetAdvancedSettings (IntPtr system, out ADVANCEDSETTINGS settings); + [DllImport(STUDIO_VERSION.dll)] + private static extern RESULT FMOD_Studio_System_Initialize (IntPtr system, int maxchannels, INITFLAGS studioflags, FMOD.INITFLAGS flags, IntPtr extradriverdata); + [DllImport(STUDIO_VERSION.dll)] + private static extern RESULT FMOD_Studio_System_Release (IntPtr system); + [DllImport(STUDIO_VERSION.dll)] + private static extern RESULT FMOD_Studio_System_Update (IntPtr system); + [DllImport(STUDIO_VERSION.dll)] + private static extern RESULT FMOD_Studio_System_GetCoreSystem (IntPtr system, out IntPtr coresystem); + [DllImport(STUDIO_VERSION.dll)] + private static extern RESULT FMOD_Studio_System_GetEvent (IntPtr system, byte[] path, out IntPtr _event); + [DllImport(STUDIO_VERSION.dll)] + private static extern RESULT FMOD_Studio_System_GetBus (IntPtr system, byte[] path, out IntPtr bus); + [DllImport(STUDIO_VERSION.dll)] + private static extern RESULT FMOD_Studio_System_GetVCA (IntPtr system, byte[] path, out IntPtr vca); + [DllImport(STUDIO_VERSION.dll)] + private static extern RESULT FMOD_Studio_System_GetBank (IntPtr system, byte[] path, out IntPtr bank); + [DllImport(STUDIO_VERSION.dll)] + private static extern RESULT FMOD_Studio_System_GetEventByID (IntPtr system, ref GUID id, out IntPtr _event); + [DllImport(STUDIO_VERSION.dll)] + private static extern RESULT FMOD_Studio_System_GetBusByID (IntPtr system, ref GUID id, out IntPtr bus); + [DllImport(STUDIO_VERSION.dll)] + private static extern RESULT FMOD_Studio_System_GetVCAByID (IntPtr system, ref GUID id, out IntPtr vca); + [DllImport(STUDIO_VERSION.dll)] + private static extern RESULT FMOD_Studio_System_GetBankByID (IntPtr system, ref GUID id, out IntPtr bank); + [DllImport(STUDIO_VERSION.dll)] + private static extern RESULT FMOD_Studio_System_GetSoundInfo (IntPtr system, byte[] key, out SOUND_INFO info); + [DllImport(STUDIO_VERSION.dll)] + private static extern RESULT FMOD_Studio_System_GetParameterDescriptionByName(IntPtr system, byte[] name, out PARAMETER_DESCRIPTION parameter); + [DllImport(STUDIO_VERSION.dll)] + private static extern RESULT FMOD_Studio_System_GetParameterDescriptionByID(IntPtr system, PARAMETER_ID id, out PARAMETER_DESCRIPTION parameter); + [DllImport(STUDIO_VERSION.dll)] + private static extern RESULT FMOD_Studio_System_GetParameterLabelByName (IntPtr system, byte[] name, int labelindex, IntPtr label, int size, out int retrieved); + [DllImport(STUDIO_VERSION.dll)] + private static extern RESULT FMOD_Studio_System_GetParameterLabelByID (IntPtr system, PARAMETER_ID id, int labelindex, IntPtr label, int size, out int retrieved); + [DllImport(STUDIO_VERSION.dll)] + private static extern RESULT FMOD_Studio_System_GetParameterByID (IntPtr system, PARAMETER_ID id, out float value, out float finalvalue); + [DllImport(STUDIO_VERSION.dll)] + private static extern RESULT FMOD_Studio_System_SetParameterByID (IntPtr system, PARAMETER_ID id, float value, bool ignoreseekspeed); + [DllImport(STUDIO_VERSION.dll)] + private static extern RESULT FMOD_Studio_System_SetParameterByIDWithLabel (IntPtr system, PARAMETER_ID id, byte[] label, bool ignoreseekspeed); + [DllImport(STUDIO_VERSION.dll)] + private static extern RESULT FMOD_Studio_System_SetParametersByIDs (IntPtr system, PARAMETER_ID[] ids, float[] values, int count, bool ignoreseekspeed); + [DllImport(STUDIO_VERSION.dll)] + private static extern RESULT FMOD_Studio_System_GetParameterByName (IntPtr system, byte[] name, out float value, out float finalvalue); + [DllImport(STUDIO_VERSION.dll)] + private static extern RESULT FMOD_Studio_System_SetParameterByName (IntPtr system, byte[] name, float value, bool ignoreseekspeed); + [DllImport(STUDIO_VERSION.dll)] + private static extern RESULT FMOD_Studio_System_SetParameterByNameWithLabel (IntPtr system, byte[] name, byte[] label, bool ignoreseekspeed); + [DllImport(STUDIO_VERSION.dll)] + private static extern RESULT FMOD_Studio_System_LookupID (IntPtr system, byte[] path, out GUID id); + [DllImport(STUDIO_VERSION.dll)] + private static extern RESULT FMOD_Studio_System_LookupPath (IntPtr system, ref GUID id, IntPtr path, int size, out int retrieved); + [DllImport(STUDIO_VERSION.dll)] + private static extern RESULT FMOD_Studio_System_GetNumListeners (IntPtr system, out int numlisteners); + [DllImport(STUDIO_VERSION.dll)] + private static extern RESULT FMOD_Studio_System_SetNumListeners (IntPtr system, int numlisteners); + [DllImport(STUDIO_VERSION.dll)] + private static extern RESULT FMOD_Studio_System_GetListenerAttributes (IntPtr system, int listener, out ATTRIBUTES_3D attributes, IntPtr zero); + [DllImport(STUDIO_VERSION.dll)] + private static extern RESULT FMOD_Studio_System_GetListenerAttributes (IntPtr system, int listener, out ATTRIBUTES_3D attributes, out VECTOR attenuationposition); + [DllImport(STUDIO_VERSION.dll)] + private static extern RESULT FMOD_Studio_System_SetListenerAttributes (IntPtr system, int listener, ref ATTRIBUTES_3D attributes, IntPtr zero); + [DllImport(STUDIO_VERSION.dll)] + private static extern RESULT FMOD_Studio_System_SetListenerAttributes (IntPtr system, int listener, ref ATTRIBUTES_3D attributes, ref VECTOR attenuationposition); + [DllImport(STUDIO_VERSION.dll)] + private static extern RESULT FMOD_Studio_System_GetListenerWeight (IntPtr system, int listener, out float weight); + [DllImport(STUDIO_VERSION.dll)] + private static extern RESULT FMOD_Studio_System_SetListenerWeight (IntPtr system, int listener, float weight); + [DllImport(STUDIO_VERSION.dll)] + private static extern RESULT FMOD_Studio_System_LoadBankFile (IntPtr system, byte[] filename, LOAD_BANK_FLAGS flags, out IntPtr bank); + [DllImport(STUDIO_VERSION.dll)] + private static extern RESULT FMOD_Studio_System_LoadBankMemory (IntPtr system, IntPtr buffer, int length, LOAD_MEMORY_MODE mode, LOAD_BANK_FLAGS flags, out IntPtr bank); + [DllImport(STUDIO_VERSION.dll)] + private static extern RESULT FMOD_Studio_System_LoadBankCustom (IntPtr system, ref BANK_INFO info, LOAD_BANK_FLAGS flags, out IntPtr bank); + [DllImport(STUDIO_VERSION.dll)] + private static extern RESULT FMOD_Studio_System_UnloadAll (IntPtr system); + [DllImport(STUDIO_VERSION.dll)] + private static extern RESULT FMOD_Studio_System_FlushCommands (IntPtr system); + [DllImport(STUDIO_VERSION.dll)] + private static extern RESULT FMOD_Studio_System_FlushSampleLoading (IntPtr system); + [DllImport(STUDIO_VERSION.dll)] + private static extern RESULT FMOD_Studio_System_StartCommandCapture (IntPtr system, byte[] filename, COMMANDCAPTURE_FLAGS flags); + [DllImport(STUDIO_VERSION.dll)] + private static extern RESULT FMOD_Studio_System_StopCommandCapture (IntPtr system); + [DllImport(STUDIO_VERSION.dll)] + private static extern RESULT FMOD_Studio_System_LoadCommandReplay (IntPtr system, byte[] filename, COMMANDREPLAY_FLAGS flags, out IntPtr replay); + [DllImport(STUDIO_VERSION.dll)] + private static extern RESULT FMOD_Studio_System_GetBankCount (IntPtr system, out int count); + [DllImport(STUDIO_VERSION.dll)] + private static extern RESULT FMOD_Studio_System_GetBankList (IntPtr system, IntPtr[] array, int capacity, out int count); + [DllImport(STUDIO_VERSION.dll)] + private static extern RESULT FMOD_Studio_System_GetParameterDescriptionCount(IntPtr system, out int count); + [DllImport(STUDIO_VERSION.dll)] + private static extern RESULT FMOD_Studio_System_GetParameterDescriptionList(IntPtr system, [Out] PARAMETER_DESCRIPTION[] array, int capacity, out int count); + [DllImport(STUDIO_VERSION.dll)] + private static extern RESULT FMOD_Studio_System_GetCPUUsage (IntPtr system, out CPU_USAGE usage, out FMOD.CPU_USAGE usage_core); + [DllImport(STUDIO_VERSION.dll)] + private static extern RESULT FMOD_Studio_System_GetBufferUsage (IntPtr system, out BUFFER_USAGE usage); + [DllImport(STUDIO_VERSION.dll)] + private static extern RESULT FMOD_Studio_System_ResetBufferUsage (IntPtr system); + [DllImport(STUDIO_VERSION.dll)] + private static extern RESULT FMOD_Studio_System_SetCallback (IntPtr system, SYSTEM_CALLBACK callback, SYSTEM_CALLBACK_TYPE callbackmask); + [DllImport(STUDIO_VERSION.dll)] + private static extern RESULT FMOD_Studio_System_GetUserData (IntPtr system, out IntPtr userdata); + [DllImport(STUDIO_VERSION.dll)] + private static extern RESULT FMOD_Studio_System_SetUserData (IntPtr system, IntPtr userdata); + [DllImport(STUDIO_VERSION.dll)] + private static extern RESULT FMOD_Studio_System_GetMemoryUsage (IntPtr system, out MEMORY_USAGE memoryusage); + #endregion + + #region wrapperinternal + + public IntPtr handle; + + public System(IntPtr ptr) { this.handle = ptr; } + public bool hasHandle() { return this.handle != IntPtr.Zero; } + public void clearHandle() { this.handle = IntPtr.Zero; } + + public bool isValid() + { + return hasHandle() && FMOD_Studio_System_IsValid(this.handle); + } + + #endregion + } + + public struct EventDescription + { + public RESULT getID(out GUID id) + { + return FMOD_Studio_EventDescription_GetID(this.handle, out id); + } + public RESULT getPath(out string path) + { + path = null; + + using (StringHelper.ThreadSafeEncoding encoder = StringHelper.GetFreeHelper()) + { + IntPtr stringMem = Marshal.AllocHGlobal(256); + int retrieved = 0; + RESULT result = FMOD_Studio_EventDescription_GetPath(this.handle, stringMem, 256, out retrieved); + + if (result == RESULT.ERR_TRUNCATED) + { + Marshal.FreeHGlobal(stringMem); + stringMem = Marshal.AllocHGlobal(retrieved); + result = FMOD_Studio_EventDescription_GetPath(this.handle, stringMem, retrieved, out retrieved); + } + + if (result == RESULT.OK) + { + path = encoder.stringFromNative(stringMem); + } + Marshal.FreeHGlobal(stringMem); + return result; + } + } + public RESULT getParameterDescriptionCount(out int count) + { + return FMOD_Studio_EventDescription_GetParameterDescriptionCount(this.handle, out count); + } + public RESULT getParameterDescriptionByIndex(int index, out PARAMETER_DESCRIPTION parameter) + { + return FMOD_Studio_EventDescription_GetParameterDescriptionByIndex(this.handle, index, out parameter); + } + public RESULT getParameterDescriptionByName(string name, out PARAMETER_DESCRIPTION parameter) + { + using (StringHelper.ThreadSafeEncoding encoder = StringHelper.GetFreeHelper()) + { + return FMOD_Studio_EventDescription_GetParameterDescriptionByName(this.handle, encoder.byteFromStringUTF8(name), out parameter); + } + } + public RESULT getParameterDescriptionByID(PARAMETER_ID id, out PARAMETER_DESCRIPTION parameter) + { + return FMOD_Studio_EventDescription_GetParameterDescriptionByID(this.handle, id, out parameter); + } + public RESULT getParameterLabelByIndex(int index, int labelindex, out string label) + { + label = null; + + using (StringHelper.ThreadSafeEncoding encoder = StringHelper.GetFreeHelper()) + { + IntPtr stringMem = Marshal.AllocHGlobal(256); + int retrieved = 0; + RESULT result = FMOD_Studio_EventDescription_GetParameterLabelByIndex(this.handle, index, labelindex, stringMem, 256, out retrieved); + + if (result == RESULT.ERR_TRUNCATED) + { + Marshal.FreeHGlobal(stringMem); + result = FMOD_Studio_EventDescription_GetParameterLabelByIndex(this.handle, index, labelindex, IntPtr.Zero, 0, out retrieved); + stringMem = Marshal.AllocHGlobal(retrieved); + result = FMOD_Studio_EventDescription_GetParameterLabelByIndex(this.handle, index, labelindex, stringMem, retrieved, out retrieved); + } + + if (result == RESULT.OK) + { + label = encoder.stringFromNative(stringMem); + } + Marshal.FreeHGlobal(stringMem); + return result; + } + } + public RESULT getParameterLabelByName(string name, int labelindex, out string label) + { + label = null; + + using (StringHelper.ThreadSafeEncoding encoder = StringHelper.GetFreeHelper()) + { + IntPtr stringMem = Marshal.AllocHGlobal(256); + int retrieved = 0; + byte[] nameBytes = encoder.byteFromStringUTF8(name); + RESULT result = FMOD_Studio_EventDescription_GetParameterLabelByName(this.handle, nameBytes, labelindex, stringMem, 256, out retrieved); + + if (result == RESULT.ERR_TRUNCATED) + { + Marshal.FreeHGlobal(stringMem); + result = FMOD_Studio_EventDescription_GetParameterLabelByName(this.handle, nameBytes, labelindex, IntPtr.Zero, 0, out retrieved); + stringMem = Marshal.AllocHGlobal(retrieved); + result = FMOD_Studio_EventDescription_GetParameterLabelByName(this.handle, nameBytes, labelindex, stringMem, retrieved, out retrieved); + } + + if (result == RESULT.OK) + { + label = encoder.stringFromNative(stringMem); + } + Marshal.FreeHGlobal(stringMem); + return result; + } + } + public RESULT getParameterLabelByID(PARAMETER_ID id, int labelindex, out string label) + { + label = null; + + using (StringHelper.ThreadSafeEncoding encoder = StringHelper.GetFreeHelper()) + { + IntPtr stringMem = Marshal.AllocHGlobal(256); + int retrieved = 0; + RESULT result = FMOD_Studio_EventDescription_GetParameterLabelByID(this.handle, id, labelindex, stringMem, 256, out retrieved); + + if (result == RESULT.ERR_TRUNCATED) + { + Marshal.FreeHGlobal(stringMem); + result = FMOD_Studio_EventDescription_GetParameterLabelByID(this.handle, id, labelindex, IntPtr.Zero, 0, out retrieved); + stringMem = Marshal.AllocHGlobal(retrieved); + result = FMOD_Studio_EventDescription_GetParameterLabelByID(this.handle, id, labelindex, stringMem, retrieved, out retrieved); + } + + if (result == RESULT.OK) + { + label = encoder.stringFromNative(stringMem); + } + Marshal.FreeHGlobal(stringMem); + return result; + } + } + public RESULT getUserPropertyCount(out int count) + { + return FMOD_Studio_EventDescription_GetUserPropertyCount(this.handle, out count); + } + public RESULT getUserPropertyByIndex(int index, out USER_PROPERTY property) + { + return FMOD_Studio_EventDescription_GetUserPropertyByIndex(this.handle, index, out property); + } + public RESULT getUserProperty(string name, out USER_PROPERTY property) + { + using (StringHelper.ThreadSafeEncoding encoder = StringHelper.GetFreeHelper()) + { + return FMOD_Studio_EventDescription_GetUserProperty(this.handle, encoder.byteFromStringUTF8(name), out property); + } + } + public RESULT getLength(out int length) + { + return FMOD_Studio_EventDescription_GetLength(this.handle, out length); + } + public RESULT getMinMaxDistance(out float min, out float max) + { + return FMOD_Studio_EventDescription_GetMinMaxDistance(this.handle, out min, out max); + } + public RESULT getSoundSize(out float size) + { + return FMOD_Studio_EventDescription_GetSoundSize(this.handle, out size); + } + public RESULT isSnapshot(out bool snapshot) + { + return FMOD_Studio_EventDescription_IsSnapshot(this.handle, out snapshot); + } + public RESULT isOneshot(out bool oneshot) + { + return FMOD_Studio_EventDescription_IsOneshot(this.handle, out oneshot); + } + public RESULT isStream(out bool isStream) + { + return FMOD_Studio_EventDescription_IsStream(this.handle, out isStream); + } + public RESULT is3D(out bool is3D) + { + return FMOD_Studio_EventDescription_Is3D(this.handle, out is3D); + } + public RESULT isDopplerEnabled(out bool doppler) + { + return FMOD_Studio_EventDescription_IsDopplerEnabled(this.handle, out doppler); + } + public RESULT hasSustainPoint(out bool sustainPoint) + { + return FMOD_Studio_EventDescription_HasSustainPoint(this.handle, out sustainPoint); + } + + public RESULT createInstance(out EventInstance instance) + { + return FMOD_Studio_EventDescription_CreateInstance(this.handle, out instance.handle); + } + + public RESULT getInstanceCount(out int count) + { + return FMOD_Studio_EventDescription_GetInstanceCount(this.handle, out count); + } + public RESULT getInstanceList(out EventInstance[] array) + { + array = null; + + RESULT result; + int capacity; + result = FMOD_Studio_EventDescription_GetInstanceCount(this.handle, out capacity); + if (result != RESULT.OK) + { + return result; + } + if (capacity == 0) + { + array = new EventInstance[0]; + return result; + } + + IntPtr[] rawArray = new IntPtr[capacity]; + int actualCount; + result = FMOD_Studio_EventDescription_GetInstanceList(this.handle, rawArray, capacity, out actualCount); + if (result != RESULT.OK) + { + return result; + } + if (actualCount > capacity) // More items added since we queried just now? + { + actualCount = capacity; + } + array = new EventInstance[actualCount]; + for (int i = 0; i < actualCount; ++i) + { + array[i].handle = rawArray[i]; + } + return RESULT.OK; + } + + public RESULT loadSampleData() + { + return FMOD_Studio_EventDescription_LoadSampleData(this.handle); + } + + public RESULT unloadSampleData() + { + return FMOD_Studio_EventDescription_UnloadSampleData(this.handle); + } + + public RESULT getSampleLoadingState(out LOADING_STATE state) + { + return FMOD_Studio_EventDescription_GetSampleLoadingState(this.handle, out state); + } + + public RESULT releaseAllInstances() + { + return FMOD_Studio_EventDescription_ReleaseAllInstances(this.handle); + } + public RESULT setCallback(EVENT_CALLBACK callback, EVENT_CALLBACK_TYPE callbackmask = EVENT_CALLBACK_TYPE.ALL) + { + return FMOD_Studio_EventDescription_SetCallback(this.handle, callback, callbackmask); + } + + public RESULT getUserData(out IntPtr userdata) + { + return FMOD_Studio_EventDescription_GetUserData(this.handle, out userdata); + } + + public RESULT setUserData(IntPtr userdata) + { + return FMOD_Studio_EventDescription_SetUserData(this.handle, userdata); + } + + #region importfunctions + [DllImport(STUDIO_VERSION.dll)] + private static extern bool FMOD_Studio_EventDescription_IsValid (IntPtr eventdescription); + [DllImport(STUDIO_VERSION.dll)] + private static extern RESULT FMOD_Studio_EventDescription_GetID (IntPtr eventdescription, out GUID id); + [DllImport(STUDIO_VERSION.dll)] + private static extern RESULT FMOD_Studio_EventDescription_GetPath (IntPtr eventdescription, IntPtr path, int size, out int retrieved); + [DllImport(STUDIO_VERSION.dll)] + private static extern RESULT FMOD_Studio_EventDescription_GetParameterDescriptionCount(IntPtr eventdescription, out int count); + [DllImport(STUDIO_VERSION.dll)] + private static extern RESULT FMOD_Studio_EventDescription_GetParameterDescriptionByIndex(IntPtr eventdescription, int index, out PARAMETER_DESCRIPTION parameter); + [DllImport(STUDIO_VERSION.dll)] + private static extern RESULT FMOD_Studio_EventDescription_GetParameterDescriptionByName(IntPtr eventdescription, byte[] name, out PARAMETER_DESCRIPTION parameter); + [DllImport(STUDIO_VERSION.dll)] + private static extern RESULT FMOD_Studio_EventDescription_GetParameterDescriptionByID(IntPtr eventdescription, PARAMETER_ID id, out PARAMETER_DESCRIPTION parameter); + [DllImport(STUDIO_VERSION.dll)] + private static extern RESULT FMOD_Studio_EventDescription_GetParameterLabelByIndex(IntPtr eventdescription, int index, int labelindex, IntPtr label, int size, out int retrieved); + [DllImport(STUDIO_VERSION.dll)] + private static extern RESULT FMOD_Studio_EventDescription_GetParameterLabelByName(IntPtr eventdescription, byte[] name, int labelindex, IntPtr label, int size, out int retrieved); + [DllImport(STUDIO_VERSION.dll)] + private static extern RESULT FMOD_Studio_EventDescription_GetParameterLabelByID (IntPtr eventdescription, PARAMETER_ID id, int labelindex, IntPtr label, int size, out int retrieved); + [DllImport(STUDIO_VERSION.dll)] + private static extern RESULT FMOD_Studio_EventDescription_GetUserPropertyCount (IntPtr eventdescription, out int count); + [DllImport(STUDIO_VERSION.dll)] + private static extern RESULT FMOD_Studio_EventDescription_GetUserPropertyByIndex(IntPtr eventdescription, int index, out USER_PROPERTY property); + [DllImport(STUDIO_VERSION.dll)] + private static extern RESULT FMOD_Studio_EventDescription_GetUserProperty (IntPtr eventdescription, byte[] name, out USER_PROPERTY property); + [DllImport(STUDIO_VERSION.dll)] + private static extern RESULT FMOD_Studio_EventDescription_GetLength (IntPtr eventdescription, out int length); + [DllImport(STUDIO_VERSION.dll)] + private static extern RESULT FMOD_Studio_EventDescription_GetMinMaxDistance (IntPtr eventdescription, out float min, out float max); + [DllImport(STUDIO_VERSION.dll)] + private static extern RESULT FMOD_Studio_EventDescription_GetSoundSize (IntPtr eventdescription, out float size); + [DllImport(STUDIO_VERSION.dll)] + private static extern RESULT FMOD_Studio_EventDescription_IsSnapshot (IntPtr eventdescription, out bool snapshot); + [DllImport(STUDIO_VERSION.dll)] + private static extern RESULT FMOD_Studio_EventDescription_IsOneshot (IntPtr eventdescription, out bool oneshot); + [DllImport(STUDIO_VERSION.dll)] + private static extern RESULT FMOD_Studio_EventDescription_IsStream (IntPtr eventdescription, out bool isStream); + [DllImport(STUDIO_VERSION.dll)] + private static extern RESULT FMOD_Studio_EventDescription_Is3D (IntPtr eventdescription, out bool is3D); + [DllImport(STUDIO_VERSION.dll)] + private static extern RESULT FMOD_Studio_EventDescription_IsDopplerEnabled (IntPtr eventdescription, out bool doppler); + [DllImport(STUDIO_VERSION.dll)] + private static extern RESULT FMOD_Studio_EventDescription_HasSustainPoint (IntPtr eventdescription, out bool sustainPoint); + [DllImport(STUDIO_VERSION.dll)] + private static extern RESULT FMOD_Studio_EventDescription_CreateInstance (IntPtr eventdescription, out IntPtr instance); + [DllImport(STUDIO_VERSION.dll)] + private static extern RESULT FMOD_Studio_EventDescription_GetInstanceCount (IntPtr eventdescription, out int count); + [DllImport(STUDIO_VERSION.dll)] + private static extern RESULT FMOD_Studio_EventDescription_GetInstanceList (IntPtr eventdescription, IntPtr[] array, int capacity, out int count); + [DllImport(STUDIO_VERSION.dll)] + private static extern RESULT FMOD_Studio_EventDescription_LoadSampleData (IntPtr eventdescription); + [DllImport(STUDIO_VERSION.dll)] + private static extern RESULT FMOD_Studio_EventDescription_UnloadSampleData (IntPtr eventdescription); + [DllImport(STUDIO_VERSION.dll)] + private static extern RESULT FMOD_Studio_EventDescription_GetSampleLoadingState (IntPtr eventdescription, out LOADING_STATE state); + [DllImport(STUDIO_VERSION.dll)] + private static extern RESULT FMOD_Studio_EventDescription_ReleaseAllInstances (IntPtr eventdescription); + [DllImport(STUDIO_VERSION.dll)] + private static extern RESULT FMOD_Studio_EventDescription_SetCallback (IntPtr eventdescription, EVENT_CALLBACK callback, EVENT_CALLBACK_TYPE callbackmask); + [DllImport(STUDIO_VERSION.dll)] + private static extern RESULT FMOD_Studio_EventDescription_GetUserData (IntPtr eventdescription, out IntPtr userdata); + [DllImport(STUDIO_VERSION.dll)] + private static extern RESULT FMOD_Studio_EventDescription_SetUserData (IntPtr eventdescription, IntPtr userdata); + #endregion + #region wrapperinternal + + public IntPtr handle; + + public EventDescription(IntPtr ptr) { this.handle = ptr; } + public bool hasHandle() { return this.handle != IntPtr.Zero; } + public void clearHandle() { this.handle = IntPtr.Zero; } + + public bool isValid() + { + return hasHandle() && FMOD_Studio_EventDescription_IsValid(this.handle); + } + + #endregion + } + + public struct EventInstance + { + public RESULT getDescription(out EventDescription description) + { + return FMOD_Studio_EventInstance_GetDescription(this.handle, out description.handle); + } + public RESULT getSystem(out System system) + { + return FMOD_Studio_EventInstance_GetSystem(this.handle, out system.handle); + } + public RESULT getVolume(out float volume) + { + return FMOD_Studio_EventInstance_GetVolume(this.handle, out volume, IntPtr.Zero); + } + public RESULT getVolume(out float volume, out float finalvolume) + { + return FMOD_Studio_EventInstance_GetVolume(this.handle, out volume, out finalvolume); + } + public RESULT setVolume(float volume) + { + return FMOD_Studio_EventInstance_SetVolume(this.handle, volume); + } + public RESULT getPitch(out float pitch) + { + return FMOD_Studio_EventInstance_GetPitch(this.handle, out pitch, IntPtr.Zero); + } + public RESULT getPitch(out float pitch, out float finalpitch) + { + return FMOD_Studio_EventInstance_GetPitch(this.handle, out pitch, out finalpitch); + } + public RESULT setPitch(float pitch) + { + return FMOD_Studio_EventInstance_SetPitch(this.handle, pitch); + } + public RESULT get3DAttributes(out ATTRIBUTES_3D attributes) + { + return FMOD_Studio_EventInstance_Get3DAttributes(this.handle, out attributes); + } + public RESULT set3DAttributes(ATTRIBUTES_3D attributes) + { + return FMOD_Studio_EventInstance_Set3DAttributes(this.handle, ref attributes); + } + public RESULT getListenerMask(out uint mask) + { + return FMOD_Studio_EventInstance_GetListenerMask(this.handle, out mask); + } + public RESULT setListenerMask(uint mask) + { + return FMOD_Studio_EventInstance_SetListenerMask(this.handle, mask); + } + public RESULT getProperty(EVENT_PROPERTY index, out float value) + { + return FMOD_Studio_EventInstance_GetProperty(this.handle, index, out value); + } + public RESULT setProperty(EVENT_PROPERTY index, float value) + { + return FMOD_Studio_EventInstance_SetProperty(this.handle, index, value); + } + public RESULT getReverbLevel(int index, out float level) + { + return FMOD_Studio_EventInstance_GetReverbLevel(this.handle, index, out level); + } + public RESULT setReverbLevel(int index, float level) + { + return FMOD_Studio_EventInstance_SetReverbLevel(this.handle, index, level); + } + public RESULT getPaused(out bool paused) + { + return FMOD_Studio_EventInstance_GetPaused(this.handle, out paused); + } + public RESULT setPaused(bool paused) + { + return FMOD_Studio_EventInstance_SetPaused(this.handle, paused); + } + public RESULT start() + { + return FMOD_Studio_EventInstance_Start(this.handle); + } + public RESULT stop(STOP_MODE mode) + { + return FMOD_Studio_EventInstance_Stop(this.handle, mode); + } + public RESULT getTimelinePosition(out int position) + { + return FMOD_Studio_EventInstance_GetTimelinePosition(this.handle, out position); + } + public RESULT setTimelinePosition(int position) + { + return FMOD_Studio_EventInstance_SetTimelinePosition(this.handle, position); + } + public RESULT getPlaybackState(out PLAYBACK_STATE state) + { + return FMOD_Studio_EventInstance_GetPlaybackState(this.handle, out state); + } + public RESULT getChannelGroup(out FMOD.ChannelGroup group) + { + return FMOD_Studio_EventInstance_GetChannelGroup(this.handle, out group.handle); + } + public RESULT getMinMaxDistance(out float min, out float max) + { + return FMOD_Studio_EventInstance_GetMinMaxDistance(this.handle, out min, out max); + } + public RESULT release() + { + return FMOD_Studio_EventInstance_Release(this.handle); + } + public RESULT isVirtual(out bool virtualstate) + { + return FMOD_Studio_EventInstance_IsVirtual(this.handle, out virtualstate); + } + public RESULT getParameterByID(PARAMETER_ID id, out float value) + { + float finalvalue; + return getParameterByID(id, out value, out finalvalue); + } + public RESULT getParameterByID(PARAMETER_ID id, out float value, out float finalvalue) + { + return FMOD_Studio_EventInstance_GetParameterByID(this.handle, id, out value, out finalvalue); + } + public RESULT setParameterByID(PARAMETER_ID id, float value, bool ignoreseekspeed = false) + { + return FMOD_Studio_EventInstance_SetParameterByID(this.handle, id, value, ignoreseekspeed); + } + public RESULT setParameterByIDWithLabel(PARAMETER_ID id, string label, bool ignoreseekspeed = false) + { + using (StringHelper.ThreadSafeEncoding encoder = StringHelper.GetFreeHelper()) + { + return FMOD_Studio_EventInstance_SetParameterByIDWithLabel(this.handle, id, encoder.byteFromStringUTF8(label), ignoreseekspeed); + } + } + public RESULT setParametersByIDs(PARAMETER_ID[] ids, float[] values, int count, bool ignoreseekspeed = false) + { + return FMOD_Studio_EventInstance_SetParametersByIDs(this.handle, ids, values, count, ignoreseekspeed); + } + public RESULT getParameterByName(string name, out float value) + { + float finalValue; + return getParameterByName(name, out value, out finalValue); + } + public RESULT getParameterByName(string name, out float value, out float finalvalue) + { + using (StringHelper.ThreadSafeEncoding encoder = StringHelper.GetFreeHelper()) + { + return FMOD_Studio_EventInstance_GetParameterByName(this.handle, encoder.byteFromStringUTF8(name), out value, out finalvalue); + } + } + public RESULT setParameterByName(string name, float value, bool ignoreseekspeed = false) + { + using (StringHelper.ThreadSafeEncoding encoder = StringHelper.GetFreeHelper()) + { + return FMOD_Studio_EventInstance_SetParameterByName(this.handle, encoder.byteFromStringUTF8(name), value, ignoreseekspeed); + } + } + public RESULT setParameterByNameWithLabel(string name, string label, bool ignoreseekspeed = false) + { + using (StringHelper.ThreadSafeEncoding encoder = StringHelper.GetFreeHelper(), + labelEncoder = StringHelper.GetFreeHelper()) + { + return FMOD_Studio_EventInstance_SetParameterByNameWithLabel(this.handle, encoder.byteFromStringUTF8(name), labelEncoder.byteFromStringUTF8(label), ignoreseekspeed); + } + } + public RESULT keyOff() + { + return FMOD_Studio_EventInstance_KeyOff(this.handle); + } + public RESULT setCallback(EVENT_CALLBACK callback, EVENT_CALLBACK_TYPE callbackmask = EVENT_CALLBACK_TYPE.ALL) + { + return FMOD_Studio_EventInstance_SetCallback(this.handle, callback, callbackmask); + } + public RESULT getUserData(out IntPtr userdata) + { + return FMOD_Studio_EventInstance_GetUserData(this.handle, out userdata); + } + public RESULT setUserData(IntPtr userdata) + { + return FMOD_Studio_EventInstance_SetUserData(this.handle, userdata); + } + public RESULT getCPUUsage(out uint exclusive, out uint inclusive) + { + return FMOD_Studio_EventInstance_GetCPUUsage(this.handle, out exclusive, out inclusive); + } + public RESULT getMemoryUsage(out MEMORY_USAGE memoryusage) + { + return FMOD_Studio_EventInstance_GetMemoryUsage(this.handle, out memoryusage); + } + #region importfunctions + [DllImport(STUDIO_VERSION.dll)] + private static extern bool FMOD_Studio_EventInstance_IsValid (IntPtr _event); + [DllImport(STUDIO_VERSION.dll)] + private static extern RESULT FMOD_Studio_EventInstance_GetDescription (IntPtr _event, out IntPtr description); + [DllImport(STUDIO_VERSION.dll)] + private static extern RESULT FMOD_Studio_EventInstance_GetSystem (IntPtr _event, out IntPtr system); + [DllImport(STUDIO_VERSION.dll)] + private static extern RESULT FMOD_Studio_EventInstance_GetVolume (IntPtr _event, out float volume, IntPtr zero); + [DllImport(STUDIO_VERSION.dll)] + private static extern RESULT FMOD_Studio_EventInstance_GetVolume (IntPtr _event, out float volume, out float finalvolume); + [DllImport(STUDIO_VERSION.dll)] + private static extern RESULT FMOD_Studio_EventInstance_SetVolume (IntPtr _event, float volume); + [DllImport(STUDIO_VERSION.dll)] + private static extern RESULT FMOD_Studio_EventInstance_GetPitch (IntPtr _event, out float pitch, IntPtr zero); + [DllImport(STUDIO_VERSION.dll)] + private static extern RESULT FMOD_Studio_EventInstance_GetPitch (IntPtr _event, out float pitch, out float finalpitch); + [DllImport(STUDIO_VERSION.dll)] + private static extern RESULT FMOD_Studio_EventInstance_SetPitch (IntPtr _event, float pitch); + [DllImport(STUDIO_VERSION.dll)] + private static extern RESULT FMOD_Studio_EventInstance_Get3DAttributes (IntPtr _event, out ATTRIBUTES_3D attributes); + [DllImport(STUDIO_VERSION.dll)] + private static extern RESULT FMOD_Studio_EventInstance_Set3DAttributes (IntPtr _event, ref ATTRIBUTES_3D attributes); + [DllImport(STUDIO_VERSION.dll)] + private static extern RESULT FMOD_Studio_EventInstance_GetListenerMask (IntPtr _event, out uint mask); + [DllImport(STUDIO_VERSION.dll)] + private static extern RESULT FMOD_Studio_EventInstance_SetListenerMask (IntPtr _event, uint mask); + [DllImport(STUDIO_VERSION.dll)] + private static extern RESULT FMOD_Studio_EventInstance_GetProperty (IntPtr _event, EVENT_PROPERTY index, out float value); + [DllImport(STUDIO_VERSION.dll)] + private static extern RESULT FMOD_Studio_EventInstance_SetProperty (IntPtr _event, EVENT_PROPERTY index, float value); + [DllImport(STUDIO_VERSION.dll)] + private static extern RESULT FMOD_Studio_EventInstance_GetReverbLevel (IntPtr _event, int index, out float level); + [DllImport(STUDIO_VERSION.dll)] + private static extern RESULT FMOD_Studio_EventInstance_SetReverbLevel (IntPtr _event, int index, float level); + [DllImport(STUDIO_VERSION.dll)] + private static extern RESULT FMOD_Studio_EventInstance_GetPaused (IntPtr _event, out bool paused); + [DllImport(STUDIO_VERSION.dll)] + private static extern RESULT FMOD_Studio_EventInstance_SetPaused (IntPtr _event, bool paused); + [DllImport(STUDIO_VERSION.dll)] + private static extern RESULT FMOD_Studio_EventInstance_Start (IntPtr _event); + [DllImport(STUDIO_VERSION.dll)] + private static extern RESULT FMOD_Studio_EventInstance_Stop (IntPtr _event, STOP_MODE mode); + [DllImport(STUDIO_VERSION.dll)] + private static extern RESULT FMOD_Studio_EventInstance_GetTimelinePosition (IntPtr _event, out int position); + [DllImport(STUDIO_VERSION.dll)] + private static extern RESULT FMOD_Studio_EventInstance_SetTimelinePosition (IntPtr _event, int position); + [DllImport(STUDIO_VERSION.dll)] + private static extern RESULT FMOD_Studio_EventInstance_GetPlaybackState (IntPtr _event, out PLAYBACK_STATE state); + [DllImport(STUDIO_VERSION.dll)] + private static extern RESULT FMOD_Studio_EventInstance_GetChannelGroup (IntPtr _event, out IntPtr group); + [DllImport(STUDIO_VERSION.dll)] + private static extern RESULT FMOD_Studio_EventInstance_GetMinMaxDistance (IntPtr _event, out float min, out float max); + [DllImport(STUDIO_VERSION.dll)] + private static extern RESULT FMOD_Studio_EventInstance_Release (IntPtr _event); + [DllImport(STUDIO_VERSION.dll)] + private static extern RESULT FMOD_Studio_EventInstance_IsVirtual (IntPtr _event, out bool virtualstate); + [DllImport(STUDIO_VERSION.dll)] + private static extern RESULT FMOD_Studio_EventInstance_GetParameterByName (IntPtr _event, byte[] name, out float value, out float finalvalue); + [DllImport(STUDIO_VERSION.dll)] + private static extern RESULT FMOD_Studio_EventInstance_SetParameterByName (IntPtr _event, byte[] name, float value, bool ignoreseekspeed); + [DllImport(STUDIO_VERSION.dll)] + private static extern RESULT FMOD_Studio_EventInstance_SetParameterByNameWithLabel (IntPtr _event, byte[] name, byte[] label, bool ignoreseekspeed); + [DllImport(STUDIO_VERSION.dll)] + private static extern RESULT FMOD_Studio_EventInstance_GetParameterByID (IntPtr _event, PARAMETER_ID id, out float value, out float finalvalue); + [DllImport(STUDIO_VERSION.dll)] + private static extern RESULT FMOD_Studio_EventInstance_SetParameterByID (IntPtr _event, PARAMETER_ID id, float value, bool ignoreseekspeed); + [DllImport(STUDIO_VERSION.dll)] + private static extern RESULT FMOD_Studio_EventInstance_SetParameterByIDWithLabel (IntPtr _event, PARAMETER_ID id, byte[] label, bool ignoreseekspeed); + [DllImport(STUDIO_VERSION.dll)] + private static extern RESULT FMOD_Studio_EventInstance_SetParametersByIDs (IntPtr _event, PARAMETER_ID[] ids, float[] values, int count, bool ignoreseekspeed); + [DllImport(STUDIO_VERSION.dll)] + private static extern RESULT FMOD_Studio_EventInstance_KeyOff (IntPtr _event); + [DllImport(STUDIO_VERSION.dll)] + private static extern RESULT FMOD_Studio_EventInstance_SetCallback (IntPtr _event, EVENT_CALLBACK callback, EVENT_CALLBACK_TYPE callbackmask); + [DllImport (STUDIO_VERSION.dll)] + private static extern RESULT FMOD_Studio_EventInstance_GetUserData (IntPtr _event, out IntPtr userdata); + [DllImport (STUDIO_VERSION.dll)] + private static extern RESULT FMOD_Studio_EventInstance_SetUserData (IntPtr _event, IntPtr userdata); + [DllImport (STUDIO_VERSION.dll)] + private static extern RESULT FMOD_Studio_EventInstance_GetCPUUsage (IntPtr _event, out uint exclusive, out uint inclusive); + [DllImport(STUDIO_VERSION.dll)] + private static extern RESULT FMOD_Studio_EventInstance_GetMemoryUsage (IntPtr _event, out MEMORY_USAGE memoryusage); + #endregion + + #region wrapperinternal + + public IntPtr handle; + + public EventInstance(IntPtr ptr) { this.handle = ptr; } + public bool hasHandle() { return this.handle != IntPtr.Zero; } + public void clearHandle() { this.handle = IntPtr.Zero; } + + public bool isValid() + { + return hasHandle() && FMOD_Studio_EventInstance_IsValid(this.handle); + } + + #endregion + } + + public struct Bus + { + public RESULT getID(out GUID id) + { + return FMOD_Studio_Bus_GetID(this.handle, out id); + } + public RESULT getPath(out string path) + { + path = null; + + using (StringHelper.ThreadSafeEncoding encoder = StringHelper.GetFreeHelper()) + { + IntPtr stringMem = Marshal.AllocHGlobal(256); + int retrieved = 0; + RESULT result = FMOD_Studio_Bus_GetPath(this.handle, stringMem, 256, out retrieved); + + if (result == RESULT.ERR_TRUNCATED) + { + Marshal.FreeHGlobal(stringMem); + stringMem = Marshal.AllocHGlobal(retrieved); + result = FMOD_Studio_Bus_GetPath(this.handle, stringMem, retrieved, out retrieved); + } + + if (result == RESULT.OK) + { + path = encoder.stringFromNative(stringMem); + } + Marshal.FreeHGlobal(stringMem); + return result; + } + + } + public RESULT getVolume(out float volume) + { + float finalVolume; + return getVolume(out volume, out finalVolume); + } + public RESULT getVolume(out float volume, out float finalvolume) + { + return FMOD_Studio_Bus_GetVolume(this.handle, out volume, out finalvolume); + } + public RESULT setVolume(float volume) + { + return FMOD_Studio_Bus_SetVolume(this.handle, volume); + } + public RESULT getPaused(out bool paused) + { + return FMOD_Studio_Bus_GetPaused(this.handle, out paused); + } + public RESULT setPaused(bool paused) + { + return FMOD_Studio_Bus_SetPaused(this.handle, paused); + } + public RESULT getMute(out bool mute) + { + return FMOD_Studio_Bus_GetMute(this.handle, out mute); + } + public RESULT setMute(bool mute) + { + return FMOD_Studio_Bus_SetMute(this.handle, mute); + } + public RESULT stopAllEvents(STOP_MODE mode) + { + return FMOD_Studio_Bus_StopAllEvents(this.handle, mode); + } + public RESULT lockChannelGroup() + { + return FMOD_Studio_Bus_LockChannelGroup(this.handle); + } + public RESULT unlockChannelGroup() + { + return FMOD_Studio_Bus_UnlockChannelGroup(this.handle); + } + public RESULT getChannelGroup(out FMOD.ChannelGroup group) + { + return FMOD_Studio_Bus_GetChannelGroup(this.handle, out group.handle); + } + public RESULT getCPUUsage(out uint exclusive, out uint inclusive) + { + return FMOD_Studio_Bus_GetCPUUsage(this.handle, out exclusive, out inclusive); + } + public RESULT getMemoryUsage(out MEMORY_USAGE memoryusage) + { + return FMOD_Studio_Bus_GetMemoryUsage(this.handle, out memoryusage); + } + public RESULT getPortIndex(out ulong index) + { + return FMOD_Studio_Bus_GetPortIndex(this.handle, out index); + } + public RESULT setPortIndex(ulong index) + { + return FMOD_Studio_Bus_SetPortIndex(this.handle, index); + } + + #region importfunctions + [DllImport(STUDIO_VERSION.dll)] + private static extern bool FMOD_Studio_Bus_IsValid (IntPtr bus); + [DllImport(STUDIO_VERSION.dll)] + private static extern RESULT FMOD_Studio_Bus_GetID (IntPtr bus, out GUID id); + [DllImport(STUDIO_VERSION.dll)] + private static extern RESULT FMOD_Studio_Bus_GetPath (IntPtr bus, IntPtr path, int size, out int retrieved); + [DllImport(STUDIO_VERSION.dll)] + private static extern RESULT FMOD_Studio_Bus_GetVolume (IntPtr bus, out float volume, out float finalvolume); + [DllImport(STUDIO_VERSION.dll)] + private static extern RESULT FMOD_Studio_Bus_SetVolume (IntPtr bus, float volume); + [DllImport(STUDIO_VERSION.dll)] + private static extern RESULT FMOD_Studio_Bus_GetPaused (IntPtr bus, out bool paused); + [DllImport(STUDIO_VERSION.dll)] + private static extern RESULT FMOD_Studio_Bus_SetPaused (IntPtr bus, bool paused); + [DllImport(STUDIO_VERSION.dll)] + private static extern RESULT FMOD_Studio_Bus_GetMute (IntPtr bus, out bool mute); + [DllImport(STUDIO_VERSION.dll)] + private static extern RESULT FMOD_Studio_Bus_SetMute (IntPtr bus, bool mute); + [DllImport(STUDIO_VERSION.dll)] + private static extern RESULT FMOD_Studio_Bus_StopAllEvents (IntPtr bus, STOP_MODE mode); + [DllImport(STUDIO_VERSION.dll)] + private static extern RESULT FMOD_Studio_Bus_LockChannelGroup (IntPtr bus); + [DllImport(STUDIO_VERSION.dll)] + private static extern RESULT FMOD_Studio_Bus_UnlockChannelGroup (IntPtr bus); + [DllImport(STUDIO_VERSION.dll)] + private static extern RESULT FMOD_Studio_Bus_GetChannelGroup (IntPtr bus, out IntPtr group); + [DllImport(STUDIO_VERSION.dll)] + private static extern RESULT FMOD_Studio_Bus_GetCPUUsage (IntPtr bus, out uint exclusive, out uint inclusive); + [DllImport(STUDIO_VERSION.dll)] + private static extern RESULT FMOD_Studio_Bus_GetMemoryUsage (IntPtr bus, out MEMORY_USAGE memoryusage); + [DllImport(STUDIO_VERSION.dll)] + private static extern RESULT FMOD_Studio_Bus_GetPortIndex (IntPtr bus, out ulong index); + [DllImport(STUDIO_VERSION.dll)] + private static extern RESULT FMOD_Studio_Bus_SetPortIndex (IntPtr bus, ulong index); + #endregion + + #region wrapperinternal + + public IntPtr handle; + + public Bus(IntPtr ptr) { this.handle = ptr; } + public bool hasHandle() { return this.handle != IntPtr.Zero; } + public void clearHandle() { this.handle = IntPtr.Zero; } + + public bool isValid() + { + return hasHandle() && FMOD_Studio_Bus_IsValid(this.handle); + } + + #endregion + } + + public struct VCA + { + public RESULT getID(out GUID id) + { + return FMOD_Studio_VCA_GetID(this.handle, out id); + } + public RESULT getPath(out string path) + { + path = null; + + using (StringHelper.ThreadSafeEncoding encoder = StringHelper.GetFreeHelper()) + { + IntPtr stringMem = Marshal.AllocHGlobal(256); + int retrieved = 0; + RESULT result = FMOD_Studio_VCA_GetPath(this.handle, stringMem, 256, out retrieved); + + if (result == RESULT.ERR_TRUNCATED) + { + Marshal.FreeHGlobal(stringMem); + stringMem = Marshal.AllocHGlobal(retrieved); + result = FMOD_Studio_VCA_GetPath(this.handle, stringMem, retrieved, out retrieved); + } + + if (result == RESULT.OK) + { + path = encoder.stringFromNative(stringMem); + } + Marshal.FreeHGlobal(stringMem); + return result; + } + } + public RESULT getVolume(out float volume) + { + float finalVolume; + return getVolume(out volume, out finalVolume); + } + public RESULT getVolume(out float volume, out float finalvolume) + { + return FMOD_Studio_VCA_GetVolume(this.handle, out volume, out finalvolume); + } + public RESULT setVolume(float volume) + { + return FMOD_Studio_VCA_SetVolume(this.handle, volume); + } + + #region importfunctions + [DllImport(STUDIO_VERSION.dll)] + private static extern bool FMOD_Studio_VCA_IsValid (IntPtr vca); + [DllImport(STUDIO_VERSION.dll)] + private static extern RESULT FMOD_Studio_VCA_GetID (IntPtr vca, out GUID id); + [DllImport(STUDIO_VERSION.dll)] + private static extern RESULT FMOD_Studio_VCA_GetPath (IntPtr vca, IntPtr path, int size, out int retrieved); + [DllImport(STUDIO_VERSION.dll)] + private static extern RESULT FMOD_Studio_VCA_GetVolume (IntPtr vca, out float volume, out float finalvolume); + [DllImport(STUDIO_VERSION.dll)] + private static extern RESULT FMOD_Studio_VCA_SetVolume (IntPtr vca, float volume); + #endregion + + #region wrapperinternal + + public IntPtr handle; + + public VCA(IntPtr ptr) { this.handle = ptr; } + public bool hasHandle() { return this.handle != IntPtr.Zero; } + public void clearHandle() { this.handle = IntPtr.Zero; } + + public bool isValid() + { + return hasHandle() && FMOD_Studio_VCA_IsValid(this.handle); + } + + #endregion + } + + public struct Bank + { + // Property access + + public RESULT getID(out GUID id) + { + return FMOD_Studio_Bank_GetID(this.handle, out id); + } + public RESULT getPath(out string path) + { + path = null; + + using (StringHelper.ThreadSafeEncoding encoder = StringHelper.GetFreeHelper()) + { + IntPtr stringMem = Marshal.AllocHGlobal(256); + int retrieved = 0; + RESULT result = FMOD_Studio_Bank_GetPath(this.handle, stringMem, 256, out retrieved); + + if (result == RESULT.ERR_TRUNCATED) + { + Marshal.FreeHGlobal(stringMem); + stringMem = Marshal.AllocHGlobal(retrieved); + result = FMOD_Studio_Bank_GetPath(this.handle, stringMem, retrieved, out retrieved); + } + + if (result == RESULT.OK) + { + path = encoder.stringFromNative(stringMem); + } + Marshal.FreeHGlobal(stringMem); + return result; + } + } + public RESULT unload() + { + return FMOD_Studio_Bank_Unload(this.handle); + } + public RESULT loadSampleData() + { + return FMOD_Studio_Bank_LoadSampleData(this.handle); + } + public RESULT unloadSampleData() + { + return FMOD_Studio_Bank_UnloadSampleData(this.handle); + } + public RESULT getLoadingState(out LOADING_STATE state) + { + return FMOD_Studio_Bank_GetLoadingState(this.handle, out state); + } + public RESULT getSampleLoadingState(out LOADING_STATE state) + { + return FMOD_Studio_Bank_GetSampleLoadingState(this.handle, out state); + } + + // Enumeration + public RESULT getStringCount(out int count) + { + return FMOD_Studio_Bank_GetStringCount(this.handle, out count); + } + public RESULT getStringInfo(int index, out GUID id, out string path) + { + path = null; + id = new GUID(); + + using (StringHelper.ThreadSafeEncoding encoder = StringHelper.GetFreeHelper()) + { + IntPtr stringMem = Marshal.AllocHGlobal(256); + int retrieved = 0; + RESULT result = FMOD_Studio_Bank_GetStringInfo(this.handle, index, out id, stringMem, 256, out retrieved); + + if (result == RESULT.ERR_TRUNCATED) + { + Marshal.FreeHGlobal(stringMem); + stringMem = Marshal.AllocHGlobal(retrieved); + result = FMOD_Studio_Bank_GetStringInfo(this.handle, index, out id, stringMem, retrieved, out retrieved); + } + + if (result == RESULT.OK) + { + path = encoder.stringFromNative(stringMem); + } + Marshal.FreeHGlobal(stringMem); + return result; + } + } + + public RESULT getEventCount(out int count) + { + return FMOD_Studio_Bank_GetEventCount(this.handle, out count); + } + public RESULT getEventList(out EventDescription[] array) + { + array = null; + + RESULT result; + int capacity; + result = FMOD_Studio_Bank_GetEventCount(this.handle, out capacity); + if (result != RESULT.OK) + { + return result; + } + if (capacity == 0) + { + array = new EventDescription[0]; + return result; + } + + IntPtr[] rawArray = new IntPtr[capacity]; + int actualCount; + result = FMOD_Studio_Bank_GetEventList(this.handle, rawArray, capacity, out actualCount); + if (result != RESULT.OK) + { + return result; + } + if (actualCount > capacity) // More items added since we queried just now? + { + actualCount = capacity; + } + array = new EventDescription[actualCount]; + for (int i = 0; i < actualCount; ++i) + { + array[i].handle = rawArray[i]; + } + return RESULT.OK; + } + public RESULT getBusCount(out int count) + { + return FMOD_Studio_Bank_GetBusCount(this.handle, out count); + } + public RESULT getBusList(out Bus[] array) + { + array = null; + + RESULT result; + int capacity; + result = FMOD_Studio_Bank_GetBusCount(this.handle, out capacity); + if (result != RESULT.OK) + { + return result; + } + if (capacity == 0) + { + array = new Bus[0]; + return result; + } + + IntPtr[] rawArray = new IntPtr[capacity]; + int actualCount; + result = FMOD_Studio_Bank_GetBusList(this.handle, rawArray, capacity, out actualCount); + if (result != RESULT.OK) + { + return result; + } + if (actualCount > capacity) // More items added since we queried just now? + { + actualCount = capacity; + } + array = new Bus[actualCount]; + for (int i = 0; i < actualCount; ++i) + { + array[i].handle = rawArray[i]; + } + return RESULT.OK; + } + public RESULT getVCACount(out int count) + { + return FMOD_Studio_Bank_GetVCACount(this.handle, out count); + } + public RESULT getVCAList(out VCA[] array) + { + array = null; + + RESULT result; + int capacity; + result = FMOD_Studio_Bank_GetVCACount(this.handle, out capacity); + if (result != RESULT.OK) + { + return result; + } + if (capacity == 0) + { + array = new VCA[0]; + return result; + } + + IntPtr[] rawArray = new IntPtr[capacity]; + int actualCount; + result = FMOD_Studio_Bank_GetVCAList(this.handle, rawArray, capacity, out actualCount); + if (result != RESULT.OK) + { + return result; + } + if (actualCount > capacity) // More items added since we queried just now? + { + actualCount = capacity; + } + array = new VCA[actualCount]; + for (int i = 0; i < actualCount; ++i) + { + array[i].handle = rawArray[i]; + } + return RESULT.OK; + } + + public RESULT getUserData(out IntPtr userdata) + { + return FMOD_Studio_Bank_GetUserData(this.handle, out userdata); + } + + public RESULT setUserData(IntPtr userdata) + { + return FMOD_Studio_Bank_SetUserData(this.handle, userdata); + } + + #region importfunctions + [DllImport(STUDIO_VERSION.dll)] + private static extern bool FMOD_Studio_Bank_IsValid (IntPtr bank); + [DllImport(STUDIO_VERSION.dll)] + private static extern RESULT FMOD_Studio_Bank_GetID (IntPtr bank, out GUID id); + [DllImport(STUDIO_VERSION.dll)] + private static extern RESULT FMOD_Studio_Bank_GetPath (IntPtr bank, IntPtr path, int size, out int retrieved); + [DllImport(STUDIO_VERSION.dll)] + private static extern RESULT FMOD_Studio_Bank_Unload (IntPtr bank); + [DllImport(STUDIO_VERSION.dll)] + private static extern RESULT FMOD_Studio_Bank_LoadSampleData (IntPtr bank); + [DllImport(STUDIO_VERSION.dll)] + private static extern RESULT FMOD_Studio_Bank_UnloadSampleData (IntPtr bank); + [DllImport(STUDIO_VERSION.dll)] + private static extern RESULT FMOD_Studio_Bank_GetLoadingState (IntPtr bank, out LOADING_STATE state); + [DllImport(STUDIO_VERSION.dll)] + private static extern RESULT FMOD_Studio_Bank_GetSampleLoadingState (IntPtr bank, out LOADING_STATE state); + [DllImport(STUDIO_VERSION.dll)] + private static extern RESULT FMOD_Studio_Bank_GetStringCount (IntPtr bank, out int count); + [DllImport(STUDIO_VERSION.dll)] + private static extern RESULT FMOD_Studio_Bank_GetStringInfo (IntPtr bank, int index, out GUID id, IntPtr path, int size, out int retrieved); + [DllImport(STUDIO_VERSION.dll)] + private static extern RESULT FMOD_Studio_Bank_GetEventCount (IntPtr bank, out int count); + [DllImport(STUDIO_VERSION.dll)] + private static extern RESULT FMOD_Studio_Bank_GetEventList (IntPtr bank, IntPtr[] array, int capacity, out int count); + [DllImport(STUDIO_VERSION.dll)] + private static extern RESULT FMOD_Studio_Bank_GetBusCount (IntPtr bank, out int count); + [DllImport(STUDIO_VERSION.dll)] + private static extern RESULT FMOD_Studio_Bank_GetBusList (IntPtr bank, IntPtr[] array, int capacity, out int count); + [DllImport(STUDIO_VERSION.dll)] + private static extern RESULT FMOD_Studio_Bank_GetVCACount (IntPtr bank, out int count); + [DllImport(STUDIO_VERSION.dll)] + private static extern RESULT FMOD_Studio_Bank_GetVCAList (IntPtr bank, IntPtr[] array, int capacity, out int count); + [DllImport(STUDIO_VERSION.dll)] + private static extern RESULT FMOD_Studio_Bank_GetUserData (IntPtr bank, out IntPtr userdata); + [DllImport(STUDIO_VERSION.dll)] + private static extern RESULT FMOD_Studio_Bank_SetUserData (IntPtr bank, IntPtr userdata); + #endregion + + #region wrapperinternal + + public IntPtr handle; + + public Bank(IntPtr ptr) { this.handle = ptr; } + public bool hasHandle() { return this.handle != IntPtr.Zero; } + public void clearHandle() { this.handle = IntPtr.Zero; } + + public bool isValid() + { + return hasHandle() && FMOD_Studio_Bank_IsValid(this.handle); + } + + #endregion + } + + public struct CommandReplay + { + // Information query + public RESULT getSystem(out System system) + { + return FMOD_Studio_CommandReplay_GetSystem(this.handle, out system.handle); + } + + public RESULT getLength(out float length) + { + return FMOD_Studio_CommandReplay_GetLength(this.handle, out length); + } + public RESULT getCommandCount(out int count) + { + return FMOD_Studio_CommandReplay_GetCommandCount(this.handle, out count); + } + public RESULT getCommandInfo(int commandIndex, out COMMAND_INFO info) + { + return FMOD_Studio_CommandReplay_GetCommandInfo(this.handle, commandIndex, out info); + } + + public RESULT getCommandString(int commandIndex, out string buffer) + { + buffer = null; + using (StringHelper.ThreadSafeEncoding encoder = StringHelper.GetFreeHelper()) + { + int stringLength = 256; + IntPtr stringMem = Marshal.AllocHGlobal(256); + RESULT result = FMOD_Studio_CommandReplay_GetCommandString(this.handle, commandIndex, stringMem, stringLength); + + while (result == RESULT.ERR_TRUNCATED) + { + Marshal.FreeHGlobal(stringMem); + stringLength *= 2; + stringMem = Marshal.AllocHGlobal(stringLength); + result = FMOD_Studio_CommandReplay_GetCommandString(this.handle, commandIndex, stringMem, stringLength); + } + + if (result == RESULT.OK) + { + buffer = encoder.stringFromNative(stringMem); + } + Marshal.FreeHGlobal(stringMem); + return result; + } + } + public RESULT getCommandAtTime(float time, out int commandIndex) + { + return FMOD_Studio_CommandReplay_GetCommandAtTime(this.handle, time, out commandIndex); + } + // Playback + public RESULT setBankPath(string bankPath) + { + using (StringHelper.ThreadSafeEncoding encoder = StringHelper.GetFreeHelper()) + { + return FMOD_Studio_CommandReplay_SetBankPath(this.handle, encoder.byteFromStringUTF8(bankPath)); + } + } + public RESULT start() + { + return FMOD_Studio_CommandReplay_Start(this.handle); + } + public RESULT stop() + { + return FMOD_Studio_CommandReplay_Stop(this.handle); + } + public RESULT seekToTime(float time) + { + return FMOD_Studio_CommandReplay_SeekToTime(this.handle, time); + } + public RESULT seekToCommand(int commandIndex) + { + return FMOD_Studio_CommandReplay_SeekToCommand(this.handle, commandIndex); + } + public RESULT getPaused(out bool paused) + { + return FMOD_Studio_CommandReplay_GetPaused(this.handle, out paused); + } + public RESULT setPaused(bool paused) + { + return FMOD_Studio_CommandReplay_SetPaused(this.handle, paused); + } + public RESULT getPlaybackState(out PLAYBACK_STATE state) + { + return FMOD_Studio_CommandReplay_GetPlaybackState(this.handle, out state); + } + public RESULT getCurrentCommand(out int commandIndex, out float currentTime) + { + return FMOD_Studio_CommandReplay_GetCurrentCommand(this.handle, out commandIndex, out currentTime); + } + // Release + public RESULT release() + { + return FMOD_Studio_CommandReplay_Release(this.handle); + } + // Callbacks + public RESULT setFrameCallback(COMMANDREPLAY_FRAME_CALLBACK callback) + { + return FMOD_Studio_CommandReplay_SetFrameCallback(this.handle, callback); + } + public RESULT setLoadBankCallback(COMMANDREPLAY_LOAD_BANK_CALLBACK callback) + { + return FMOD_Studio_CommandReplay_SetLoadBankCallback(this.handle, callback); + } + public RESULT setCreateInstanceCallback(COMMANDREPLAY_CREATE_INSTANCE_CALLBACK callback) + { + return FMOD_Studio_CommandReplay_SetCreateInstanceCallback(this.handle, callback); + } + public RESULT getUserData(out IntPtr userdata) + { + return FMOD_Studio_CommandReplay_GetUserData(this.handle, out userdata); + } + public RESULT setUserData(IntPtr userdata) + { + return FMOD_Studio_CommandReplay_SetUserData(this.handle, userdata); + } + + #region importfunctions + [DllImport(STUDIO_VERSION.dll)] + private static extern bool FMOD_Studio_CommandReplay_IsValid (IntPtr replay); + [DllImport(STUDIO_VERSION.dll)] + private static extern RESULT FMOD_Studio_CommandReplay_GetSystem (IntPtr replay, out IntPtr system); + [DllImport(STUDIO_VERSION.dll)] + private static extern RESULT FMOD_Studio_CommandReplay_GetLength (IntPtr replay, out float length); + [DllImport(STUDIO_VERSION.dll)] + private static extern RESULT FMOD_Studio_CommandReplay_GetCommandCount (IntPtr replay, out int count); + [DllImport(STUDIO_VERSION.dll)] + private static extern RESULT FMOD_Studio_CommandReplay_GetCommandInfo (IntPtr replay, int commandindex, out COMMAND_INFO info); + [DllImport(STUDIO_VERSION.dll)] + private static extern RESULT FMOD_Studio_CommandReplay_GetCommandString (IntPtr replay, int commandIndex, IntPtr buffer, int length); + [DllImport(STUDIO_VERSION.dll)] + private static extern RESULT FMOD_Studio_CommandReplay_GetCommandAtTime (IntPtr replay, float time, out int commandIndex); + [DllImport(STUDIO_VERSION.dll)] + private static extern RESULT FMOD_Studio_CommandReplay_SetBankPath (IntPtr replay, byte[] bankPath); + [DllImport(STUDIO_VERSION.dll)] + private static extern RESULT FMOD_Studio_CommandReplay_Start (IntPtr replay); + [DllImport(STUDIO_VERSION.dll)] + private static extern RESULT FMOD_Studio_CommandReplay_Stop (IntPtr replay); + [DllImport(STUDIO_VERSION.dll)] + private static extern RESULT FMOD_Studio_CommandReplay_SeekToTime (IntPtr replay, float time); + [DllImport(STUDIO_VERSION.dll)] + private static extern RESULT FMOD_Studio_CommandReplay_SeekToCommand (IntPtr replay, int commandIndex); + [DllImport(STUDIO_VERSION.dll)] + private static extern RESULT FMOD_Studio_CommandReplay_GetPaused (IntPtr replay, out bool paused); + [DllImport(STUDIO_VERSION.dll)] + private static extern RESULT FMOD_Studio_CommandReplay_SetPaused (IntPtr replay, bool paused); + [DllImport(STUDIO_VERSION.dll)] + private static extern RESULT FMOD_Studio_CommandReplay_GetPlaybackState (IntPtr replay, out PLAYBACK_STATE state); + [DllImport(STUDIO_VERSION.dll)] + private static extern RESULT FMOD_Studio_CommandReplay_GetCurrentCommand (IntPtr replay, out int commandIndex, out float currentTime); + [DllImport(STUDIO_VERSION.dll)] + private static extern RESULT FMOD_Studio_CommandReplay_Release (IntPtr replay); + [DllImport(STUDIO_VERSION.dll)] + private static extern RESULT FMOD_Studio_CommandReplay_SetFrameCallback (IntPtr replay, COMMANDREPLAY_FRAME_CALLBACK callback); + [DllImport(STUDIO_VERSION.dll)] + private static extern RESULT FMOD_Studio_CommandReplay_SetLoadBankCallback (IntPtr replay, COMMANDREPLAY_LOAD_BANK_CALLBACK callback); + [DllImport(STUDIO_VERSION.dll)] + private static extern RESULT FMOD_Studio_CommandReplay_SetCreateInstanceCallback(IntPtr replay, COMMANDREPLAY_CREATE_INSTANCE_CALLBACK callback); + [DllImport(STUDIO_VERSION.dll)] + private static extern RESULT FMOD_Studio_CommandReplay_GetUserData (IntPtr replay, out IntPtr userdata); + [DllImport(STUDIO_VERSION.dll)] + private static extern RESULT FMOD_Studio_CommandReplay_SetUserData (IntPtr replay, IntPtr userdata); + #endregion + + #region wrapperinternal + + public IntPtr handle; + + public CommandReplay(IntPtr ptr) { this.handle = ptr; } + public bool hasHandle() { return this.handle != IntPtr.Zero; } + public void clearHandle() { this.handle = IntPtr.Zero; } + + public bool isValid() + { + return hasHandle() && FMOD_Studio_CommandReplay_IsValid(this.handle); + } + + #endregion + } +} // FMOD diff --git a/FMOD/api/studio/inc/fmod_studio.h b/FMOD/api/studio/inc/fmod_studio.h new file mode 100644 index 0000000..ea39267 --- /dev/null +++ b/FMOD/api/studio/inc/fmod_studio.h @@ -0,0 +1,249 @@ +/* ======================================================================================== */ +/* FMOD Studio API - C header file. */ +/* Copyright (c), Firelight Technologies Pty, Ltd. 2004-2026. */ +/* */ +/* Use this header in conjunction with fmod_studio_common.h (which contains all the */ +/* constants / callbacks) to develop using the C language. */ +/* */ +/* For more detail visit: */ +/* https://fmod.com/docs/2.03/api/studio-api.html */ +/* ======================================================================================== */ +#ifndef FMOD_STUDIO_H +#define FMOD_STUDIO_H + +#include "fmod_studio_common.h" + +#ifdef __cplusplus +extern "C" +{ +#endif + +/* + Global +*/ +FMOD_RESULT F_API FMOD_Studio_ParseID(const char *idstring, FMOD_GUID *id); +FMOD_RESULT F_API FMOD_Studio_System_Create(FMOD_STUDIO_SYSTEM **system, unsigned int headerversion); + +/* + System +*/ +FMOD_BOOL F_API FMOD_Studio_System_IsValid(FMOD_STUDIO_SYSTEM *system); +FMOD_RESULT F_API FMOD_Studio_System_SetAdvancedSettings(FMOD_STUDIO_SYSTEM *system, FMOD_STUDIO_ADVANCEDSETTINGS *settings); +FMOD_RESULT F_API FMOD_Studio_System_GetAdvancedSettings(FMOD_STUDIO_SYSTEM *system, FMOD_STUDIO_ADVANCEDSETTINGS *settings); +FMOD_RESULT F_API FMOD_Studio_System_Initialize(FMOD_STUDIO_SYSTEM *system, int maxchannels, FMOD_STUDIO_INITFLAGS studioflags, FMOD_INITFLAGS flags, void *extradriverdata); +FMOD_RESULT F_API FMOD_Studio_System_Release(FMOD_STUDIO_SYSTEM *system); +FMOD_RESULT F_API FMOD_Studio_System_Update(FMOD_STUDIO_SYSTEM *system); +FMOD_RESULT F_API FMOD_Studio_System_GetCoreSystem(FMOD_STUDIO_SYSTEM *system, FMOD_SYSTEM **coresystem); +FMOD_RESULT F_API FMOD_Studio_System_GetEvent(FMOD_STUDIO_SYSTEM *system, const char *pathOrID, FMOD_STUDIO_EVENTDESCRIPTION **event); +FMOD_RESULT F_API FMOD_Studio_System_GetBus(FMOD_STUDIO_SYSTEM *system, const char *pathOrID, FMOD_STUDIO_BUS **bus); +FMOD_RESULT F_API FMOD_Studio_System_GetVCA(FMOD_STUDIO_SYSTEM *system, const char *pathOrID, FMOD_STUDIO_VCA **vca); +FMOD_RESULT F_API FMOD_Studio_System_GetBank(FMOD_STUDIO_SYSTEM *system, const char *pathOrID, FMOD_STUDIO_BANK **bank); +FMOD_RESULT F_API FMOD_Studio_System_GetEventByID(FMOD_STUDIO_SYSTEM *system, const FMOD_GUID *id, FMOD_STUDIO_EVENTDESCRIPTION **event); +FMOD_RESULT F_API FMOD_Studio_System_GetBusByID(FMOD_STUDIO_SYSTEM *system, const FMOD_GUID *id, FMOD_STUDIO_BUS **bus); +FMOD_RESULT F_API FMOD_Studio_System_GetVCAByID(FMOD_STUDIO_SYSTEM *system, const FMOD_GUID *id, FMOD_STUDIO_VCA **vca); +FMOD_RESULT F_API FMOD_Studio_System_GetBankByID(FMOD_STUDIO_SYSTEM *system, const FMOD_GUID *id, FMOD_STUDIO_BANK **bank); +FMOD_RESULT F_API FMOD_Studio_System_GetSoundInfo(FMOD_STUDIO_SYSTEM *system, const char *key, FMOD_STUDIO_SOUND_INFO *info); +FMOD_RESULT F_API FMOD_Studio_System_GetParameterDescriptionByName(FMOD_STUDIO_SYSTEM *system, const char *name, FMOD_STUDIO_PARAMETER_DESCRIPTION *parameter); +FMOD_RESULT F_API FMOD_Studio_System_GetParameterDescriptionByID(FMOD_STUDIO_SYSTEM *system, FMOD_STUDIO_PARAMETER_ID id, FMOD_STUDIO_PARAMETER_DESCRIPTION *parameter); +FMOD_RESULT F_API FMOD_Studio_System_GetParameterLabelByName(FMOD_STUDIO_SYSTEM *system, const char *name, int labelindex, char *label, int size, int *retrieved); +FMOD_RESULT F_API FMOD_Studio_System_GetParameterLabelByID(FMOD_STUDIO_SYSTEM *system, FMOD_STUDIO_PARAMETER_ID id, int labelindex, char *label, int size, int *retrieved); +FMOD_RESULT F_API FMOD_Studio_System_GetParameterByID(FMOD_STUDIO_SYSTEM *system, FMOD_STUDIO_PARAMETER_ID id, float *value, float *finalvalue); +FMOD_RESULT F_API FMOD_Studio_System_SetParameterByID(FMOD_STUDIO_SYSTEM *system, FMOD_STUDIO_PARAMETER_ID id, float value, FMOD_BOOL ignoreseekspeed); +FMOD_RESULT F_API FMOD_Studio_System_SetParameterByIDWithLabel(FMOD_STUDIO_SYSTEM *system, FMOD_STUDIO_PARAMETER_ID id, const char *label, FMOD_BOOL ignoreseekspeed); +FMOD_RESULT F_API FMOD_Studio_System_SetParametersByIDs(FMOD_STUDIO_SYSTEM *system, const FMOD_STUDIO_PARAMETER_ID *ids, float *values, int count, FMOD_BOOL ignoreseekspeed); +FMOD_RESULT F_API FMOD_Studio_System_GetParameterByName(FMOD_STUDIO_SYSTEM *system, const char *name, float *value, float *finalvalue); +FMOD_RESULT F_API FMOD_Studio_System_SetParameterByName(FMOD_STUDIO_SYSTEM *system, const char *name, float value, FMOD_BOOL ignoreseekspeed); +FMOD_RESULT F_API FMOD_Studio_System_SetParameterByNameWithLabel(FMOD_STUDIO_SYSTEM *system, const char *name, const char *label, FMOD_BOOL ignoreseekspeed); +FMOD_RESULT F_API FMOD_Studio_System_LookupID(FMOD_STUDIO_SYSTEM *system, const char *path, FMOD_GUID *id); +FMOD_RESULT F_API FMOD_Studio_System_LookupPath(FMOD_STUDIO_SYSTEM *system, const FMOD_GUID *id, char *path, int size, int *retrieved); +FMOD_RESULT F_API FMOD_Studio_System_GetNumListeners(FMOD_STUDIO_SYSTEM *system, int *numlisteners); +FMOD_RESULT F_API FMOD_Studio_System_SetNumListeners(FMOD_STUDIO_SYSTEM *system, int numlisteners); +FMOD_RESULT F_API FMOD_Studio_System_GetListenerAttributes(FMOD_STUDIO_SYSTEM *system, int index, FMOD_3D_ATTRIBUTES *attributes, FMOD_VECTOR *attenuationposition); +FMOD_RESULT F_API FMOD_Studio_System_SetListenerAttributes(FMOD_STUDIO_SYSTEM *system, int index, const FMOD_3D_ATTRIBUTES *attributes, const FMOD_VECTOR *attenuationposition); +FMOD_RESULT F_API FMOD_Studio_System_GetListenerWeight(FMOD_STUDIO_SYSTEM *system, int index, float *weight); +FMOD_RESULT F_API FMOD_Studio_System_SetListenerWeight(FMOD_STUDIO_SYSTEM *system, int index, float weight); +FMOD_RESULT F_API FMOD_Studio_System_LoadBankFile(FMOD_STUDIO_SYSTEM *system, const char *filename, FMOD_STUDIO_LOAD_BANK_FLAGS flags, FMOD_STUDIO_BANK **bank); +FMOD_RESULT F_API FMOD_Studio_System_LoadBankMemory(FMOD_STUDIO_SYSTEM *system, const char *buffer, int length, FMOD_STUDIO_LOAD_MEMORY_MODE mode, FMOD_STUDIO_LOAD_BANK_FLAGS flags, FMOD_STUDIO_BANK **bank); +FMOD_RESULT F_API FMOD_Studio_System_LoadBankCustom(FMOD_STUDIO_SYSTEM *system, const FMOD_STUDIO_BANK_INFO *info, FMOD_STUDIO_LOAD_BANK_FLAGS flags, FMOD_STUDIO_BANK **bank); +FMOD_RESULT F_API FMOD_Studio_System_RegisterPlugin(FMOD_STUDIO_SYSTEM *system, const FMOD_DSP_DESCRIPTION *description); +FMOD_RESULT F_API FMOD_Studio_System_UnregisterPlugin(FMOD_STUDIO_SYSTEM *system, const char *name); +FMOD_RESULT F_API FMOD_Studio_System_UnloadAll(FMOD_STUDIO_SYSTEM *system); +FMOD_RESULT F_API FMOD_Studio_System_FlushCommands(FMOD_STUDIO_SYSTEM *system); +FMOD_RESULT F_API FMOD_Studio_System_FlushSampleLoading(FMOD_STUDIO_SYSTEM *system); +FMOD_RESULT F_API FMOD_Studio_System_StartCommandCapture(FMOD_STUDIO_SYSTEM *system, const char *filename, FMOD_STUDIO_COMMANDCAPTURE_FLAGS flags); +FMOD_RESULT F_API FMOD_Studio_System_StopCommandCapture(FMOD_STUDIO_SYSTEM *system); +FMOD_RESULT F_API FMOD_Studio_System_LoadCommandReplay(FMOD_STUDIO_SYSTEM *system, const char *filename, FMOD_STUDIO_COMMANDREPLAY_FLAGS flags, FMOD_STUDIO_COMMANDREPLAY **replay); +FMOD_RESULT F_API FMOD_Studio_System_GetBankCount(FMOD_STUDIO_SYSTEM *system, int *count); +FMOD_RESULT F_API FMOD_Studio_System_GetBankList(FMOD_STUDIO_SYSTEM *system, FMOD_STUDIO_BANK **array, int capacity, int *count); +FMOD_RESULT F_API FMOD_Studio_System_GetParameterDescriptionCount(FMOD_STUDIO_SYSTEM *system, int *count); +FMOD_RESULT F_API FMOD_Studio_System_GetParameterDescriptionList(FMOD_STUDIO_SYSTEM *system, FMOD_STUDIO_PARAMETER_DESCRIPTION *array, int capacity, int *count); +FMOD_RESULT F_API FMOD_Studio_System_GetCPUUsage(FMOD_STUDIO_SYSTEM *system, FMOD_STUDIO_CPU_USAGE *usage, FMOD_CPU_USAGE *usage_core); +FMOD_RESULT F_API FMOD_Studio_System_GetBufferUsage(FMOD_STUDIO_SYSTEM *system, FMOD_STUDIO_BUFFER_USAGE *usage); +FMOD_RESULT F_API FMOD_Studio_System_ResetBufferUsage(FMOD_STUDIO_SYSTEM *system); +FMOD_RESULT F_API FMOD_Studio_System_SetCallback(FMOD_STUDIO_SYSTEM *system, FMOD_STUDIO_SYSTEM_CALLBACK callback, FMOD_STUDIO_SYSTEM_CALLBACK_TYPE callbackmask); +FMOD_RESULT F_API FMOD_Studio_System_SetUserData(FMOD_STUDIO_SYSTEM *system, void *userdata); +FMOD_RESULT F_API FMOD_Studio_System_GetUserData(FMOD_STUDIO_SYSTEM *system, void **userdata); +FMOD_RESULT F_API FMOD_Studio_System_GetMemoryUsage(FMOD_STUDIO_SYSTEM *system, FMOD_STUDIO_MEMORY_USAGE *memoryusage); + +/* + EventDescription +*/ +FMOD_BOOL F_API FMOD_Studio_EventDescription_IsValid(FMOD_STUDIO_EVENTDESCRIPTION *eventdescription); +FMOD_RESULT F_API FMOD_Studio_EventDescription_GetID(FMOD_STUDIO_EVENTDESCRIPTION *eventdescription, FMOD_GUID *id); +FMOD_RESULT F_API FMOD_Studio_EventDescription_GetPath(FMOD_STUDIO_EVENTDESCRIPTION *eventdescription, char *path, int size, int *retrieved); +FMOD_RESULT F_API FMOD_Studio_EventDescription_GetParameterDescriptionCount(FMOD_STUDIO_EVENTDESCRIPTION *eventdescription, int *count); +FMOD_RESULT F_API FMOD_Studio_EventDescription_GetParameterDescriptionByIndex(FMOD_STUDIO_EVENTDESCRIPTION *eventdescription, int index, FMOD_STUDIO_PARAMETER_DESCRIPTION *parameter); +FMOD_RESULT F_API FMOD_Studio_EventDescription_GetParameterDescriptionByName(FMOD_STUDIO_EVENTDESCRIPTION *eventdescription, const char *name, FMOD_STUDIO_PARAMETER_DESCRIPTION *parameter); +FMOD_RESULT F_API FMOD_Studio_EventDescription_GetParameterDescriptionByID(FMOD_STUDIO_EVENTDESCRIPTION *eventdescription, FMOD_STUDIO_PARAMETER_ID id, FMOD_STUDIO_PARAMETER_DESCRIPTION *parameter); +FMOD_RESULT F_API FMOD_Studio_EventDescription_GetParameterLabelByIndex(FMOD_STUDIO_EVENTDESCRIPTION *eventdescription, int index, int labelindex, char *label, int size, int *retrieved); +FMOD_RESULT F_API FMOD_Studio_EventDescription_GetParameterLabelByName(FMOD_STUDIO_EVENTDESCRIPTION *eventdescription, const char *name, int labelindex, char *label, int size, int *retrieved); +FMOD_RESULT F_API FMOD_Studio_EventDescription_GetParameterLabelByID(FMOD_STUDIO_EVENTDESCRIPTION *eventdescription, FMOD_STUDIO_PARAMETER_ID id, int labelindex, char *label, int size, int *retrieved); +FMOD_RESULT F_API FMOD_Studio_EventDescription_GetUserPropertyCount(FMOD_STUDIO_EVENTDESCRIPTION *eventdescription, int *count); +FMOD_RESULT F_API FMOD_Studio_EventDescription_GetUserPropertyByIndex(FMOD_STUDIO_EVENTDESCRIPTION *eventdescription, int index, FMOD_STUDIO_USER_PROPERTY *property); +FMOD_RESULT F_API FMOD_Studio_EventDescription_GetUserProperty(FMOD_STUDIO_EVENTDESCRIPTION *eventdescription, const char *name, FMOD_STUDIO_USER_PROPERTY *property); +FMOD_RESULT F_API FMOD_Studio_EventDescription_GetLength(FMOD_STUDIO_EVENTDESCRIPTION *eventdescription, int *length); +FMOD_RESULT F_API FMOD_Studio_EventDescription_GetMinMaxDistance(FMOD_STUDIO_EVENTDESCRIPTION *eventdescription, float *min, float *max); +FMOD_RESULT F_API FMOD_Studio_EventDescription_GetSoundSize(FMOD_STUDIO_EVENTDESCRIPTION *eventdescription, float *size); +FMOD_RESULT F_API FMOD_Studio_EventDescription_IsSnapshot(FMOD_STUDIO_EVENTDESCRIPTION *eventdescription, FMOD_BOOL *snapshot); +FMOD_RESULT F_API FMOD_Studio_EventDescription_IsOneshot(FMOD_STUDIO_EVENTDESCRIPTION *eventdescription, FMOD_BOOL *oneshot); +FMOD_RESULT F_API FMOD_Studio_EventDescription_IsStream(FMOD_STUDIO_EVENTDESCRIPTION *eventdescription, FMOD_BOOL *isStream); +FMOD_RESULT F_API FMOD_Studio_EventDescription_Is3D(FMOD_STUDIO_EVENTDESCRIPTION *eventdescription, FMOD_BOOL *is3D); +FMOD_RESULT F_API FMOD_Studio_EventDescription_IsDopplerEnabled(FMOD_STUDIO_EVENTDESCRIPTION *eventdescription, FMOD_BOOL *doppler); +FMOD_RESULT F_API FMOD_Studio_EventDescription_HasSustainPoint(FMOD_STUDIO_EVENTDESCRIPTION *eventdescription, FMOD_BOOL *sustainPoint); +FMOD_RESULT F_API FMOD_Studio_EventDescription_CreateInstance(FMOD_STUDIO_EVENTDESCRIPTION *eventdescription, FMOD_STUDIO_EVENTINSTANCE **instance); +FMOD_RESULT F_API FMOD_Studio_EventDescription_GetInstanceCount(FMOD_STUDIO_EVENTDESCRIPTION *eventdescription, int *count); +FMOD_RESULT F_API FMOD_Studio_EventDescription_GetInstanceList(FMOD_STUDIO_EVENTDESCRIPTION *eventdescription, FMOD_STUDIO_EVENTINSTANCE **array, int capacity, int *count); +FMOD_RESULT F_API FMOD_Studio_EventDescription_LoadSampleData(FMOD_STUDIO_EVENTDESCRIPTION *eventdescription); +FMOD_RESULT F_API FMOD_Studio_EventDescription_UnloadSampleData(FMOD_STUDIO_EVENTDESCRIPTION *eventdescription); +FMOD_RESULT F_API FMOD_Studio_EventDescription_GetSampleLoadingState(FMOD_STUDIO_EVENTDESCRIPTION *eventdescription, FMOD_STUDIO_LOADING_STATE *state); +FMOD_RESULT F_API FMOD_Studio_EventDescription_ReleaseAllInstances(FMOD_STUDIO_EVENTDESCRIPTION *eventdescription); +FMOD_RESULT F_API FMOD_Studio_EventDescription_SetCallback(FMOD_STUDIO_EVENTDESCRIPTION *eventdescription, FMOD_STUDIO_EVENT_CALLBACK callback, FMOD_STUDIO_EVENT_CALLBACK_TYPE callbackmask); +FMOD_RESULT F_API FMOD_Studio_EventDescription_GetUserData(FMOD_STUDIO_EVENTDESCRIPTION *eventdescription, void **userdata); +FMOD_RESULT F_API FMOD_Studio_EventDescription_SetUserData(FMOD_STUDIO_EVENTDESCRIPTION *eventdescription, void *userdata); + +/* + EventInstance +*/ +FMOD_BOOL F_API FMOD_Studio_EventInstance_IsValid(FMOD_STUDIO_EVENTINSTANCE *eventinstance); +FMOD_RESULT F_API FMOD_Studio_EventInstance_GetDescription(FMOD_STUDIO_EVENTINSTANCE *eventinstance, FMOD_STUDIO_EVENTDESCRIPTION **description); +FMOD_RESULT F_API FMOD_Studio_EventInstance_GetSystem(FMOD_STUDIO_EVENTINSTANCE *eventinstance, FMOD_STUDIO_SYSTEM **system); +FMOD_RESULT F_API FMOD_Studio_EventInstance_GetVolume(FMOD_STUDIO_EVENTINSTANCE *eventinstance, float *volume, float *finalvolume); +FMOD_RESULT F_API FMOD_Studio_EventInstance_SetVolume(FMOD_STUDIO_EVENTINSTANCE *eventinstance, float volume); +FMOD_RESULT F_API FMOD_Studio_EventInstance_GetPitch(FMOD_STUDIO_EVENTINSTANCE *eventinstance, float *pitch, float *finalpitch); +FMOD_RESULT F_API FMOD_Studio_EventInstance_SetPitch(FMOD_STUDIO_EVENTINSTANCE *eventinstance, float pitch); +FMOD_RESULT F_API FMOD_Studio_EventInstance_Get3DAttributes(FMOD_STUDIO_EVENTINSTANCE *eventinstance, FMOD_3D_ATTRIBUTES *attributes); +FMOD_RESULT F_API FMOD_Studio_EventInstance_Set3DAttributes(FMOD_STUDIO_EVENTINSTANCE *eventinstance, FMOD_3D_ATTRIBUTES *attributes); +FMOD_RESULT F_API FMOD_Studio_EventInstance_GetListenerMask(FMOD_STUDIO_EVENTINSTANCE *eventinstance, unsigned int *mask); +FMOD_RESULT F_API FMOD_Studio_EventInstance_SetListenerMask(FMOD_STUDIO_EVENTINSTANCE *eventinstance, unsigned int mask); +FMOD_RESULT F_API FMOD_Studio_EventInstance_GetProperty(FMOD_STUDIO_EVENTINSTANCE *eventinstance, FMOD_STUDIO_EVENT_PROPERTY index, float *value); +FMOD_RESULT F_API FMOD_Studio_EventInstance_SetProperty(FMOD_STUDIO_EVENTINSTANCE *eventinstance, FMOD_STUDIO_EVENT_PROPERTY index, float value); +FMOD_RESULT F_API FMOD_Studio_EventInstance_GetReverbLevel(FMOD_STUDIO_EVENTINSTANCE *eventinstance, int index, float *level); +FMOD_RESULT F_API FMOD_Studio_EventInstance_SetReverbLevel(FMOD_STUDIO_EVENTINSTANCE *eventinstance, int index, float level); +FMOD_RESULT F_API FMOD_Studio_EventInstance_GetPaused(FMOD_STUDIO_EVENTINSTANCE *eventinstance, FMOD_BOOL *paused); +FMOD_RESULT F_API FMOD_Studio_EventInstance_SetPaused(FMOD_STUDIO_EVENTINSTANCE *eventinstance, FMOD_BOOL paused); +FMOD_RESULT F_API FMOD_Studio_EventInstance_Start(FMOD_STUDIO_EVENTINSTANCE *eventinstance); +FMOD_RESULT F_API FMOD_Studio_EventInstance_Stop(FMOD_STUDIO_EVENTINSTANCE *eventinstance, FMOD_STUDIO_STOP_MODE mode); +FMOD_RESULT F_API FMOD_Studio_EventInstance_GetTimelinePosition(FMOD_STUDIO_EVENTINSTANCE *eventinstance, int *position); +FMOD_RESULT F_API FMOD_Studio_EventInstance_SetTimelinePosition(FMOD_STUDIO_EVENTINSTANCE *eventinstance, int position); +FMOD_RESULT F_API FMOD_Studio_EventInstance_GetPlaybackState(FMOD_STUDIO_EVENTINSTANCE *eventinstance, FMOD_STUDIO_PLAYBACK_STATE *state); +FMOD_RESULT F_API FMOD_Studio_EventInstance_GetChannelGroup(FMOD_STUDIO_EVENTINSTANCE *eventinstance, FMOD_CHANNELGROUP **group); +FMOD_RESULT F_API FMOD_Studio_EventInstance_GetMinMaxDistance(FMOD_STUDIO_EVENTINSTANCE *eventinstance, float *min, float *max); +FMOD_RESULT F_API FMOD_Studio_EventInstance_Release(FMOD_STUDIO_EVENTINSTANCE *eventinstance); +FMOD_RESULT F_API FMOD_Studio_EventInstance_IsVirtual(FMOD_STUDIO_EVENTINSTANCE *eventinstance, FMOD_BOOL *virtualstate); +FMOD_RESULT F_API FMOD_Studio_EventInstance_GetParameterByName(FMOD_STUDIO_EVENTINSTANCE *eventinstance, const char *name, float *value, float *finalvalue); +FMOD_RESULT F_API FMOD_Studio_EventInstance_SetParameterByName(FMOD_STUDIO_EVENTINSTANCE *eventinstance, const char *name, float value, FMOD_BOOL ignoreseekspeed); +FMOD_RESULT F_API FMOD_Studio_EventInstance_SetParameterByNameWithLabel(FMOD_STUDIO_EVENTINSTANCE *eventinstance, const char *name, const char *label, FMOD_BOOL ignoreseekspeed); +FMOD_RESULT F_API FMOD_Studio_EventInstance_GetParameterByID(FMOD_STUDIO_EVENTINSTANCE *eventinstance, FMOD_STUDIO_PARAMETER_ID id, float *value, float *finalvalue); +FMOD_RESULT F_API FMOD_Studio_EventInstance_SetParameterByID(FMOD_STUDIO_EVENTINSTANCE *eventinstance, FMOD_STUDIO_PARAMETER_ID id, float value, FMOD_BOOL ignoreseekspeed); +FMOD_RESULT F_API FMOD_Studio_EventInstance_SetParameterByIDWithLabel(FMOD_STUDIO_EVENTINSTANCE *eventinstance, FMOD_STUDIO_PARAMETER_ID id, const char *label, FMOD_BOOL ignoreseekspeed); +FMOD_RESULT F_API FMOD_Studio_EventInstance_SetParametersByIDs(FMOD_STUDIO_EVENTINSTANCE *eventinstance, const FMOD_STUDIO_PARAMETER_ID *ids, float *values, int count, FMOD_BOOL ignoreseekspeed); +FMOD_RESULT F_API FMOD_Studio_EventInstance_KeyOff(FMOD_STUDIO_EVENTINSTANCE *eventinstance); +FMOD_RESULT F_API FMOD_Studio_EventInstance_SetCallback(FMOD_STUDIO_EVENTINSTANCE *eventinstance, FMOD_STUDIO_EVENT_CALLBACK callback, FMOD_STUDIO_EVENT_CALLBACK_TYPE callbackmask); +FMOD_RESULT F_API FMOD_Studio_EventInstance_GetUserData(FMOD_STUDIO_EVENTINSTANCE *eventinstance, void **userdata); +FMOD_RESULT F_API FMOD_Studio_EventInstance_SetUserData(FMOD_STUDIO_EVENTINSTANCE *eventinstance, void *userdata); +FMOD_RESULT F_API FMOD_Studio_EventInstance_GetCPUUsage(FMOD_STUDIO_EVENTINSTANCE *eventinstance, unsigned int *exclusive, unsigned int *inclusive); +FMOD_RESULT F_API FMOD_Studio_EventInstance_GetMemoryUsage(FMOD_STUDIO_EVENTINSTANCE *eventinstance, FMOD_STUDIO_MEMORY_USAGE *memoryusage); + +/* + Bus +*/ +FMOD_BOOL F_API FMOD_Studio_Bus_IsValid(FMOD_STUDIO_BUS *bus); +FMOD_RESULT F_API FMOD_Studio_Bus_GetID(FMOD_STUDIO_BUS *bus, FMOD_GUID *id); +FMOD_RESULT F_API FMOD_Studio_Bus_GetPath(FMOD_STUDIO_BUS *bus, char *path, int size, int *retrieved); +FMOD_RESULT F_API FMOD_Studio_Bus_GetVolume(FMOD_STUDIO_BUS *bus, float *volume, float *finalvolume); +FMOD_RESULT F_API FMOD_Studio_Bus_SetVolume(FMOD_STUDIO_BUS *bus, float volume); +FMOD_RESULT F_API FMOD_Studio_Bus_GetPaused(FMOD_STUDIO_BUS *bus, FMOD_BOOL *paused); +FMOD_RESULT F_API FMOD_Studio_Bus_SetPaused(FMOD_STUDIO_BUS *bus, FMOD_BOOL paused); +FMOD_RESULT F_API FMOD_Studio_Bus_GetMute(FMOD_STUDIO_BUS *bus, FMOD_BOOL *mute); +FMOD_RESULT F_API FMOD_Studio_Bus_SetMute(FMOD_STUDIO_BUS *bus, FMOD_BOOL mute); +FMOD_RESULT F_API FMOD_Studio_Bus_StopAllEvents(FMOD_STUDIO_BUS *bus, FMOD_STUDIO_STOP_MODE mode); +FMOD_RESULT F_API FMOD_Studio_Bus_GetPortIndex(FMOD_STUDIO_BUS *bus, FMOD_PORT_INDEX *index); +FMOD_RESULT F_API FMOD_Studio_Bus_SetPortIndex(FMOD_STUDIO_BUS *bus, FMOD_PORT_INDEX index); +FMOD_RESULT F_API FMOD_Studio_Bus_LockChannelGroup(FMOD_STUDIO_BUS *bus); +FMOD_RESULT F_API FMOD_Studio_Bus_UnlockChannelGroup(FMOD_STUDIO_BUS *bus); +FMOD_RESULT F_API FMOD_Studio_Bus_GetChannelGroup(FMOD_STUDIO_BUS *bus, FMOD_CHANNELGROUP **group); +FMOD_RESULT F_API FMOD_Studio_Bus_GetCPUUsage(FMOD_STUDIO_BUS *bus, unsigned int *exclusive, unsigned int *inclusive); +FMOD_RESULT F_API FMOD_Studio_Bus_GetMemoryUsage(FMOD_STUDIO_BUS *bus, FMOD_STUDIO_MEMORY_USAGE *memoryusage); + +/* + VCA +*/ +FMOD_BOOL F_API FMOD_Studio_VCA_IsValid(FMOD_STUDIO_VCA *vca); +FMOD_RESULT F_API FMOD_Studio_VCA_GetID(FMOD_STUDIO_VCA *vca, FMOD_GUID *id); +FMOD_RESULT F_API FMOD_Studio_VCA_GetPath(FMOD_STUDIO_VCA *vca, char *path, int size, int *retrieved); +FMOD_RESULT F_API FMOD_Studio_VCA_GetVolume(FMOD_STUDIO_VCA *vca, float *volume, float *finalvolume); +FMOD_RESULT F_API FMOD_Studio_VCA_SetVolume(FMOD_STUDIO_VCA *vca, float volume); + +/* + Bank +*/ +FMOD_BOOL F_API FMOD_Studio_Bank_IsValid(FMOD_STUDIO_BANK *bank); +FMOD_RESULT F_API FMOD_Studio_Bank_GetID(FMOD_STUDIO_BANK *bank, FMOD_GUID *id); +FMOD_RESULT F_API FMOD_Studio_Bank_GetPath(FMOD_STUDIO_BANK *bank, char *path, int size, int *retrieved); +FMOD_RESULT F_API FMOD_Studio_Bank_Unload(FMOD_STUDIO_BANK *bank); +FMOD_RESULT F_API FMOD_Studio_Bank_LoadSampleData(FMOD_STUDIO_BANK *bank); +FMOD_RESULT F_API FMOD_Studio_Bank_UnloadSampleData(FMOD_STUDIO_BANK *bank); +FMOD_RESULT F_API FMOD_Studio_Bank_GetLoadingState(FMOD_STUDIO_BANK *bank, FMOD_STUDIO_LOADING_STATE *state); +FMOD_RESULT F_API FMOD_Studio_Bank_GetSampleLoadingState(FMOD_STUDIO_BANK *bank, FMOD_STUDIO_LOADING_STATE *state); +FMOD_RESULT F_API FMOD_Studio_Bank_GetStringCount(FMOD_STUDIO_BANK *bank, int *count); +FMOD_RESULT F_API FMOD_Studio_Bank_GetStringInfo(FMOD_STUDIO_BANK *bank, int index, FMOD_GUID *id, char *path, int size, int *retrieved); +FMOD_RESULT F_API FMOD_Studio_Bank_GetEventCount(FMOD_STUDIO_BANK *bank, int *count); +FMOD_RESULT F_API FMOD_Studio_Bank_GetEventList(FMOD_STUDIO_BANK *bank, FMOD_STUDIO_EVENTDESCRIPTION **array, int capacity, int *count); +FMOD_RESULT F_API FMOD_Studio_Bank_GetBusCount(FMOD_STUDIO_BANK *bank, int *count); +FMOD_RESULT F_API FMOD_Studio_Bank_GetBusList(FMOD_STUDIO_BANK *bank, FMOD_STUDIO_BUS **array, int capacity, int *count); +FMOD_RESULT F_API FMOD_Studio_Bank_GetVCACount(FMOD_STUDIO_BANK *bank, int *count); +FMOD_RESULT F_API FMOD_Studio_Bank_GetVCAList(FMOD_STUDIO_BANK *bank, FMOD_STUDIO_VCA **array, int capacity, int *count); +FMOD_RESULT F_API FMOD_Studio_Bank_GetUserData(FMOD_STUDIO_BANK *bank, void **userdata); +FMOD_RESULT F_API FMOD_Studio_Bank_SetUserData(FMOD_STUDIO_BANK *bank, void *userdata); + +/* + Command playback information +*/ +FMOD_BOOL F_API FMOD_Studio_CommandReplay_IsValid(FMOD_STUDIO_COMMANDREPLAY *replay); +FMOD_RESULT F_API FMOD_Studio_CommandReplay_GetSystem(FMOD_STUDIO_COMMANDREPLAY *replay, FMOD_STUDIO_SYSTEM **system); +FMOD_RESULT F_API FMOD_Studio_CommandReplay_GetLength(FMOD_STUDIO_COMMANDREPLAY *replay, float *length); +FMOD_RESULT F_API FMOD_Studio_CommandReplay_GetCommandCount(FMOD_STUDIO_COMMANDREPLAY *replay, int *count); +FMOD_RESULT F_API FMOD_Studio_CommandReplay_GetCommandInfo(FMOD_STUDIO_COMMANDREPLAY *replay, int commandindex, FMOD_STUDIO_COMMAND_INFO *info); +FMOD_RESULT F_API FMOD_Studio_CommandReplay_GetCommandString(FMOD_STUDIO_COMMANDREPLAY *replay, int commandindex, char *buffer, int length); +FMOD_RESULT F_API FMOD_Studio_CommandReplay_GetCommandAtTime(FMOD_STUDIO_COMMANDREPLAY *replay, float time, int *commandindex); +FMOD_RESULT F_API FMOD_Studio_CommandReplay_SetBankPath(FMOD_STUDIO_COMMANDREPLAY *replay, const char *bankPath); +FMOD_RESULT F_API FMOD_Studio_CommandReplay_Start(FMOD_STUDIO_COMMANDREPLAY *replay); +FMOD_RESULT F_API FMOD_Studio_CommandReplay_Stop(FMOD_STUDIO_COMMANDREPLAY *replay); +FMOD_RESULT F_API FMOD_Studio_CommandReplay_SeekToTime(FMOD_STUDIO_COMMANDREPLAY *replay, float time); +FMOD_RESULT F_API FMOD_Studio_CommandReplay_SeekToCommand(FMOD_STUDIO_COMMANDREPLAY *replay, int commandindex); +FMOD_RESULT F_API FMOD_Studio_CommandReplay_GetPaused(FMOD_STUDIO_COMMANDREPLAY *replay, FMOD_BOOL *paused); +FMOD_RESULT F_API FMOD_Studio_CommandReplay_SetPaused(FMOD_STUDIO_COMMANDREPLAY *replay, FMOD_BOOL paused); +FMOD_RESULT F_API FMOD_Studio_CommandReplay_GetPlaybackState(FMOD_STUDIO_COMMANDREPLAY *replay, FMOD_STUDIO_PLAYBACK_STATE *state); +FMOD_RESULT F_API FMOD_Studio_CommandReplay_GetCurrentCommand(FMOD_STUDIO_COMMANDREPLAY *replay, int *commandindex, float *currenttime); +FMOD_RESULT F_API FMOD_Studio_CommandReplay_Release(FMOD_STUDIO_COMMANDREPLAY *replay); +FMOD_RESULT F_API FMOD_Studio_CommandReplay_SetFrameCallback(FMOD_STUDIO_COMMANDREPLAY *replay, FMOD_STUDIO_COMMANDREPLAY_FRAME_CALLBACK callback); +FMOD_RESULT F_API FMOD_Studio_CommandReplay_SetLoadBankCallback(FMOD_STUDIO_COMMANDREPLAY *replay, FMOD_STUDIO_COMMANDREPLAY_LOAD_BANK_CALLBACK callback); +FMOD_RESULT F_API FMOD_Studio_CommandReplay_SetCreateInstanceCallback(FMOD_STUDIO_COMMANDREPLAY *replay, FMOD_STUDIO_COMMANDREPLAY_CREATE_INSTANCE_CALLBACK callback); +FMOD_RESULT F_API FMOD_Studio_CommandReplay_GetUserData(FMOD_STUDIO_COMMANDREPLAY *replay, void **userdata); +FMOD_RESULT F_API FMOD_Studio_CommandReplay_SetUserData(FMOD_STUDIO_COMMANDREPLAY *replay, void *userdata); + +#ifdef __cplusplus +} +#endif + +#endif /* FMOD_STUDIO_H */ diff --git a/FMOD/api/studio/inc/fmod_studio.hpp b/FMOD/api/studio/inc/fmod_studio.hpp new file mode 100644 index 0000000..44d3481 --- /dev/null +++ b/FMOD/api/studio/inc/fmod_studio.hpp @@ -0,0 +1,403 @@ +/* ======================================================================================== */ +/* FMOD Studio API - C++ header file. */ +/* Copyright (c), Firelight Technologies Pty, Ltd. 2004-2026. */ +/* */ +/* Use this header in conjunction with fmod_studio_common.h (which contains all the */ +/* constants / callbacks) to develop using the C++ language. */ +/* */ +/* For more detail visit: */ +/* https://fmod.com/docs/2.03/api/studio-api.html */ +/* ======================================================================================== */ +#ifndef FMOD_STUDIO_HPP +#define FMOD_STUDIO_HPP + +#include "fmod_studio_common.h" +#include "fmod_studio.h" + +#include "fmod.hpp" + +namespace FMOD +{ + +namespace Studio +{ + typedef FMOD_GUID ID; // Deprecated. Please use FMOD_GUID type. + + class System; + class EventDescription; + class EventInstance; + class Bus; + class VCA; + class Bank; + class CommandReplay; + + inline FMOD_RESULT parseID(const char *idstring, FMOD_GUID *id) { return FMOD_Studio_ParseID(idstring, id); } + + class System + { + private: + // Constructor made private so user cannot statically instance a System class. System::create must be used. + System(); + System(const System &); + + public: + static FMOD_RESULT F_API create(System **system, unsigned int headerversion = FMOD_VERSION); + FMOD_RESULT F_API setAdvancedSettings(FMOD_STUDIO_ADVANCEDSETTINGS *settings); + FMOD_RESULT F_API getAdvancedSettings(FMOD_STUDIO_ADVANCEDSETTINGS *settings); + FMOD_RESULT F_API initialize(int maxchannels, FMOD_STUDIO_INITFLAGS studioflags, FMOD_INITFLAGS flags, void *extradriverdata); + FMOD_RESULT F_API release(); + + // Handle validity + bool F_API isValid() const; + + // Update processing + FMOD_RESULT F_API update(); + FMOD_RESULT F_API flushCommands(); + FMOD_RESULT F_API flushSampleLoading(); + + // Low-level API access + FMOD_RESULT F_API getCoreSystem(FMOD::System **system) const; + + // Asset retrieval + FMOD_RESULT F_API getEvent(const char *path, EventDescription **event) const; + FMOD_RESULT F_API getBus(const char *path, Bus **bus) const; + FMOD_RESULT F_API getVCA(const char *path, VCA **vca) const; + FMOD_RESULT F_API getBank(const char *path, Bank **bank) const; + FMOD_RESULT F_API getEventByID(const FMOD_GUID *id, EventDescription **event) const; + FMOD_RESULT F_API getBusByID(const FMOD_GUID *id, Bus **bus) const; + FMOD_RESULT F_API getVCAByID(const FMOD_GUID *id, VCA **vca) const; + FMOD_RESULT F_API getBankByID(const FMOD_GUID *id, Bank **bank) const; + FMOD_RESULT F_API getSoundInfo(const char *key, FMOD_STUDIO_SOUND_INFO *info) const; + FMOD_RESULT F_API getParameterDescriptionByName(const char *name, FMOD_STUDIO_PARAMETER_DESCRIPTION *parameter) const; + FMOD_RESULT F_API getParameterDescriptionByID(FMOD_STUDIO_PARAMETER_ID id, FMOD_STUDIO_PARAMETER_DESCRIPTION *parameter) const; + FMOD_RESULT F_API getParameterLabelByName(const char *name, int labelindex, char *label, int size, int *retrieved) const; + FMOD_RESULT F_API getParameterLabelByID(FMOD_STUDIO_PARAMETER_ID id, int labelindex, char *label, int size, int *retrieved) const; + + // Global parameter control + FMOD_RESULT F_API getParameterByID(FMOD_STUDIO_PARAMETER_ID id, float *value, float *finalvalue = 0) const; + FMOD_RESULT F_API setParameterByID(FMOD_STUDIO_PARAMETER_ID id, float value, bool ignoreseekspeed = false); + FMOD_RESULT F_API setParameterByIDWithLabel(FMOD_STUDIO_PARAMETER_ID id, const char *label, bool ignoreseekspeed = false); + FMOD_RESULT F_API setParametersByIDs(const FMOD_STUDIO_PARAMETER_ID *ids, float *values, int count, bool ignoreseekspeed = false); + FMOD_RESULT F_API getParameterByName(const char *name, float *value, float *finalvalue = 0) const; + FMOD_RESULT F_API setParameterByName(const char *name, float value, bool ignoreseekspeed = false); + FMOD_RESULT F_API setParameterByNameWithLabel(const char *name, const char *label, bool ignoreseekspeed = false); + + // Path lookup + FMOD_RESULT F_API lookupID(const char *path, FMOD_GUID *id) const; + FMOD_RESULT F_API lookupPath(const FMOD_GUID *id, char *path, int size, int *retrieved) const; + + // Listener control + FMOD_RESULT F_API getNumListeners(int *numlisteners); + FMOD_RESULT F_API setNumListeners(int numlisteners); + FMOD_RESULT F_API getListenerAttributes(int listener, FMOD_3D_ATTRIBUTES *attributes, FMOD_VECTOR *attenuationposition = 0) const; + FMOD_RESULT F_API setListenerAttributes(int listener, const FMOD_3D_ATTRIBUTES *attributes, const FMOD_VECTOR *attenuationposition = 0); + FMOD_RESULT F_API getListenerWeight(int listener, float *weight); + FMOD_RESULT F_API setListenerWeight(int listener, float weight); + + // Bank control + FMOD_RESULT F_API loadBankFile(const char *filename, FMOD_STUDIO_LOAD_BANK_FLAGS flags, Bank **bank); + FMOD_RESULT F_API loadBankMemory(const char *buffer, int length, FMOD_STUDIO_LOAD_MEMORY_MODE mode, FMOD_STUDIO_LOAD_BANK_FLAGS flags, Bank **bank); + FMOD_RESULT F_API loadBankCustom(const FMOD_STUDIO_BANK_INFO *info, FMOD_STUDIO_LOAD_BANK_FLAGS flags, Bank **bank); + FMOD_RESULT F_API unloadAll(); + + // General functionality + FMOD_RESULT F_API getBufferUsage(FMOD_STUDIO_BUFFER_USAGE *usage) const; + FMOD_RESULT F_API resetBufferUsage(); + FMOD_RESULT F_API registerPlugin(const FMOD_DSP_DESCRIPTION *description); + FMOD_RESULT F_API unregisterPlugin(const char *name); + + // Enumeration + FMOD_RESULT F_API getBankCount(int *count) const; + FMOD_RESULT F_API getBankList(Bank **array, int capacity, int *count) const; + FMOD_RESULT F_API getParameterDescriptionCount(int *count) const; + FMOD_RESULT F_API getParameterDescriptionList(FMOD_STUDIO_PARAMETER_DESCRIPTION *array, int capacity, int *count) const; + + // Command capture and replay + FMOD_RESULT F_API startCommandCapture(const char *filename, FMOD_STUDIO_COMMANDCAPTURE_FLAGS flags); + FMOD_RESULT F_API stopCommandCapture(); + FMOD_RESULT F_API loadCommandReplay(const char *filename, FMOD_STUDIO_COMMANDREPLAY_FLAGS flags, CommandReplay **replay); + + // Callbacks + FMOD_RESULT F_API setCallback(FMOD_STUDIO_SYSTEM_CALLBACK callback, FMOD_STUDIO_SYSTEM_CALLBACK_TYPE callbackmask = FMOD_STUDIO_SYSTEM_CALLBACK_ALL); + FMOD_RESULT F_API getUserData(void **userdata) const; + FMOD_RESULT F_API setUserData(void *userdata); + + // Monitoring + FMOD_RESULT F_API getCPUUsage(FMOD_STUDIO_CPU_USAGE *usage, FMOD_CPU_USAGE *usage_core) const; + FMOD_RESULT F_API getMemoryUsage(FMOD_STUDIO_MEMORY_USAGE *memoryusage) const; + }; + + class EventDescription + { + private: + // Constructor made private so user cannot statically instance the class. + EventDescription(); + EventDescription(const EventDescription &); + + public: + // Handle validity + bool F_API isValid() const; + + // Property access + FMOD_RESULT F_API getID(FMOD_GUID *id) const; + FMOD_RESULT F_API getPath(char *path, int size, int *retrieved) const; + FMOD_RESULT F_API getParameterDescriptionCount(int *count) const; + FMOD_RESULT F_API getParameterDescriptionByIndex(int index, FMOD_STUDIO_PARAMETER_DESCRIPTION *parameter) const; + FMOD_RESULT F_API getParameterDescriptionByName(const char *name, FMOD_STUDIO_PARAMETER_DESCRIPTION *parameter) const; + FMOD_RESULT F_API getParameterDescriptionByID(FMOD_STUDIO_PARAMETER_ID id, FMOD_STUDIO_PARAMETER_DESCRIPTION *parameter) const; + FMOD_RESULT F_API getParameterLabelByIndex(int index, int labelindex, char *label, int size, int *retrieved) const; + FMOD_RESULT F_API getParameterLabelByName(const char *name, int labelindex, char *label, int size, int *retrieved) const; + FMOD_RESULT F_API getParameterLabelByID(FMOD_STUDIO_PARAMETER_ID id, int labelindex, char *label, int size, int *retrieved) const; + FMOD_RESULT F_API getUserPropertyCount(int *count) const; + FMOD_RESULT F_API getUserPropertyByIndex(int index, FMOD_STUDIO_USER_PROPERTY *property) const; + FMOD_RESULT F_API getUserProperty(const char *name, FMOD_STUDIO_USER_PROPERTY *property) const; + FMOD_RESULT F_API getLength(int *length) const; + FMOD_RESULT F_API getMinMaxDistance(float *min, float *max) const; + FMOD_RESULT F_API getSoundSize(float *size) const; + + FMOD_RESULT F_API isSnapshot(bool *snapshot) const; + FMOD_RESULT F_API isOneshot(bool *oneshot) const; + FMOD_RESULT F_API isStream(bool *isStream) const; + FMOD_RESULT F_API is3D(bool *is3d) const; + FMOD_RESULT F_API isDopplerEnabled(bool *doppler) const; + FMOD_RESULT F_API hasSustainPoint(bool *sustainPoint) const; + + // Playback control + FMOD_RESULT F_API createInstance(EventInstance **instance) const; + FMOD_RESULT F_API getInstanceCount(int *count) const; + FMOD_RESULT F_API getInstanceList(EventInstance **array, int capacity, int *count) const; + + // Sample data loading control + FMOD_RESULT F_API loadSampleData(); + FMOD_RESULT F_API unloadSampleData(); + FMOD_RESULT F_API getSampleLoadingState(FMOD_STUDIO_LOADING_STATE *state) const; + + // Convenience functions + FMOD_RESULT F_API releaseAllInstances(); + + // Callbacks + FMOD_RESULT F_API setCallback(FMOD_STUDIO_EVENT_CALLBACK callback, FMOD_STUDIO_EVENT_CALLBACK_TYPE callbackmask = FMOD_STUDIO_EVENT_CALLBACK_ALL); + FMOD_RESULT F_API getUserData(void **userdata) const; + FMOD_RESULT F_API setUserData(void *userdata); + }; + + class EventInstance + { + private: + // Constructor made private so user cannot statically instance the class. + EventInstance(); + EventInstance(const EventInstance &); + + public: + // Handle validity + bool F_API isValid() const; + + // Property access + FMOD_RESULT F_API getDescription(EventDescription **description) const; + FMOD_RESULT F_API getSystem(System **system) const; + + // Playback control + FMOD_RESULT F_API getVolume(float *volume, float *finalvolume = 0) const; + FMOD_RESULT F_API setVolume(float volume); + + FMOD_RESULT F_API getPitch(float *pitch, float *finalpitch = 0) const; + FMOD_RESULT F_API setPitch(float pitch); + + FMOD_RESULT F_API get3DAttributes(FMOD_3D_ATTRIBUTES *attributes) const; + FMOD_RESULT F_API set3DAttributes(const FMOD_3D_ATTRIBUTES *attributes); + + FMOD_RESULT F_API getListenerMask(unsigned int *mask) const; + FMOD_RESULT F_API setListenerMask(unsigned int mask); + + FMOD_RESULT F_API getProperty(FMOD_STUDIO_EVENT_PROPERTY index, float *value) const; + FMOD_RESULT F_API setProperty(FMOD_STUDIO_EVENT_PROPERTY index, float value); + + FMOD_RESULT F_API getReverbLevel(int index, float *level) const; + FMOD_RESULT F_API setReverbLevel(int index, float level); + + FMOD_RESULT F_API getPaused(bool *paused) const; + FMOD_RESULT F_API setPaused(bool paused); + + FMOD_RESULT F_API start(); + FMOD_RESULT F_API stop(FMOD_STUDIO_STOP_MODE mode); + + FMOD_RESULT F_API getTimelinePosition(int *position) const; + FMOD_RESULT F_API setTimelinePosition(int position); + + FMOD_RESULT F_API getPlaybackState(FMOD_STUDIO_PLAYBACK_STATE *state) const; + + FMOD_RESULT F_API getChannelGroup(ChannelGroup **group) const; + + FMOD_RESULT F_API getMinMaxDistance(float *min, float *max) const; + + FMOD_RESULT F_API release(); + + FMOD_RESULT F_API isVirtual(bool *virtualstate) const; + + FMOD_RESULT F_API getParameterByID(FMOD_STUDIO_PARAMETER_ID id, float *value, float *finalvalue = 0) const; + FMOD_RESULT F_API setParameterByID(FMOD_STUDIO_PARAMETER_ID id, float value, bool ignoreseekspeed = false); + FMOD_RESULT F_API setParameterByIDWithLabel(FMOD_STUDIO_PARAMETER_ID id, const char* label, bool ignoreseekspeed = false); + FMOD_RESULT F_API setParametersByIDs(const FMOD_STUDIO_PARAMETER_ID *ids, float *values, int count, bool ignoreseekspeed = false); + + FMOD_RESULT F_API getParameterByName(const char *name, float *value, float *finalvalue = 0) const; + FMOD_RESULT F_API setParameterByName(const char *name, float value, bool ignoreseekspeed = false); + FMOD_RESULT F_API setParameterByNameWithLabel(const char *name, const char* label, bool ignoreseekspeed = false); + + FMOD_RESULT F_API keyOff(); + + // Monitoring + FMOD_RESULT F_API getCPUUsage(unsigned int *exclusive, unsigned int *inclusive) const; + FMOD_RESULT F_API getMemoryUsage(FMOD_STUDIO_MEMORY_USAGE *memoryusage) const; + + // Callbacks + FMOD_RESULT F_API setCallback(FMOD_STUDIO_EVENT_CALLBACK callback, FMOD_STUDIO_EVENT_CALLBACK_TYPE callbackmask = FMOD_STUDIO_EVENT_CALLBACK_ALL); + FMOD_RESULT F_API getUserData(void **userdata) const; + FMOD_RESULT F_API setUserData(void *userdata); + }; + + class Bus + { + private: + // Constructor made private so user cannot statically instance the class. + Bus(); + Bus(const Bus &); + + public: + // Handle validity + bool F_API isValid() const; + + // Property access + FMOD_RESULT F_API getID(FMOD_GUID *id) const; + FMOD_RESULT F_API getPath(char *path, int size, int *retrieved) const; + + // Playback control + FMOD_RESULT F_API getVolume(float *volume, float *finalvolume = 0) const; + FMOD_RESULT F_API setVolume(float volume); + + FMOD_RESULT F_API getPaused(bool *paused) const; + FMOD_RESULT F_API setPaused(bool paused); + + FMOD_RESULT F_API getMute(bool *mute) const; + FMOD_RESULT F_API setMute(bool mute); + + FMOD_RESULT F_API stopAllEvents(FMOD_STUDIO_STOP_MODE mode); + + // Output port + FMOD_RESULT F_API getPortIndex(FMOD_PORT_INDEX *index) const; + FMOD_RESULT F_API setPortIndex(FMOD_PORT_INDEX index); + + // Low-level API access + FMOD_RESULT F_API lockChannelGroup(); + FMOD_RESULT F_API unlockChannelGroup(); + FMOD_RESULT F_API getChannelGroup(FMOD::ChannelGroup **group) const; + + // Monitoring + FMOD_RESULT F_API getCPUUsage(unsigned int *exclusive, unsigned int *inclusive) const; + FMOD_RESULT F_API getMemoryUsage(FMOD_STUDIO_MEMORY_USAGE *memoryusage) const; + }; + + class VCA + { + private: + // Constructor made private so user cannot statically instance the class. + VCA(); + VCA(const VCA &); + + public: + // Handle validity + bool F_API isValid() const; + + // Property access + FMOD_RESULT F_API getID(FMOD_GUID *id) const; + FMOD_RESULT F_API getPath(char *path, int size, int *retrieved) const; + + // Playback control + FMOD_RESULT F_API getVolume(float *volume, float *finalvolume = 0) const; + FMOD_RESULT F_API setVolume(float volume); + }; + + class Bank + { + private: + // Constructor made private so user cannot statically instance the class. + Bank(); + Bank(const Bank &); + + public: + // Handle validity + bool F_API isValid() const; + + // Property access + FMOD_RESULT F_API getID(FMOD_GUID *id) const; + FMOD_RESULT F_API getPath(char *path, int size, int *retrieved) const; + + // Loading control + FMOD_RESULT F_API unload(); + FMOD_RESULT F_API loadSampleData(); + FMOD_RESULT F_API unloadSampleData(); + + FMOD_RESULT F_API getLoadingState(FMOD_STUDIO_LOADING_STATE *state) const; + FMOD_RESULT F_API getSampleLoadingState(FMOD_STUDIO_LOADING_STATE *state) const; + + // Enumeration + FMOD_RESULT F_API getStringCount(int *count) const; + FMOD_RESULT F_API getStringInfo(int index, FMOD_GUID *id, char *path, int size, int *retrieved) const; + FMOD_RESULT F_API getEventCount(int *count) const; + FMOD_RESULT F_API getEventList(EventDescription **array, int capacity, int *count) const; + FMOD_RESULT F_API getBusCount(int *count) const; + FMOD_RESULT F_API getBusList(Bus **array, int capacity, int *count) const; + FMOD_RESULT F_API getVCACount(int *count) const; + FMOD_RESULT F_API getVCAList(VCA **array, int capacity, int *count) const; + + FMOD_RESULT F_API getUserData(void **userdata) const; + FMOD_RESULT F_API setUserData(void *userdata); + }; + + class CommandReplay + { + private: + // Constructor made private so user cannot statically instance the class. + CommandReplay(); + CommandReplay(const CommandReplay &); + + public: + // Handle validity + bool F_API isValid() const; + + // Information query + FMOD_RESULT F_API getSystem(System **system) const; + FMOD_RESULT F_API getLength(float *length) const; + + FMOD_RESULT F_API getCommandCount(int *count) const; + FMOD_RESULT F_API getCommandInfo(int commandindex, FMOD_STUDIO_COMMAND_INFO *info) const; + FMOD_RESULT F_API getCommandString(int commandindex, char *buffer, int length) const; + FMOD_RESULT F_API getCommandAtTime(float time, int *commandindex) const; + + // Playback + FMOD_RESULT F_API setBankPath(const char *bankPath); + FMOD_RESULT F_API start(); + FMOD_RESULT F_API stop(); + FMOD_RESULT F_API seekToTime(float time); + FMOD_RESULT F_API seekToCommand(int commandindex); + FMOD_RESULT F_API getPaused(bool *paused) const; + FMOD_RESULT F_API setPaused(bool paused); + FMOD_RESULT F_API getPlaybackState(FMOD_STUDIO_PLAYBACK_STATE *state) const; + FMOD_RESULT F_API getCurrentCommand(int *commandindex, float *currenttime) const; + + // Release + FMOD_RESULT F_API release(); + + // Callbacks + FMOD_RESULT F_API setFrameCallback(FMOD_STUDIO_COMMANDREPLAY_FRAME_CALLBACK callback); + FMOD_RESULT F_API setLoadBankCallback(FMOD_STUDIO_COMMANDREPLAY_LOAD_BANK_CALLBACK callback); + FMOD_RESULT F_API setCreateInstanceCallback(FMOD_STUDIO_COMMANDREPLAY_CREATE_INSTANCE_CALLBACK callback); + + FMOD_RESULT F_API getUserData(void **userdata) const; + FMOD_RESULT F_API setUserData(void *userdata); + }; + +} // namespace Studio + +} // namespace FMOD + +#endif //FMOD_STUDIO_HPP diff --git a/FMOD/api/studio/inc/fmod_studio_common.h b/FMOD/api/studio/inc/fmod_studio_common.h new file mode 100644 index 0000000..5490a06 --- /dev/null +++ b/FMOD/api/studio/inc/fmod_studio_common.h @@ -0,0 +1,336 @@ +/* ======================================================================================== */ +/* FMOD Studio API - Common C/C++ header file. */ +/* Copyright (c), Firelight Technologies Pty, Ltd. 2004-2026. */ +/* */ +/* This header defines common enumerations, structs and callbacks that are shared between */ +/* the C and C++ interfaces. */ +/* */ +/* For more detail visit: */ +/* https://fmod.com/docs/2.03/api/studio-api.html */ +/* ======================================================================================== */ +#ifndef FMOD_STUDIO_COMMON_H +#define FMOD_STUDIO_COMMON_H + +#include "fmod.h" + +/* + FMOD Studio types. +*/ +typedef struct FMOD_STUDIO_SYSTEM FMOD_STUDIO_SYSTEM; +typedef struct FMOD_STUDIO_EVENTDESCRIPTION FMOD_STUDIO_EVENTDESCRIPTION; +typedef struct FMOD_STUDIO_EVENTINSTANCE FMOD_STUDIO_EVENTINSTANCE; +typedef struct FMOD_STUDIO_BUS FMOD_STUDIO_BUS; +typedef struct FMOD_STUDIO_VCA FMOD_STUDIO_VCA; +typedef struct FMOD_STUDIO_BANK FMOD_STUDIO_BANK; +typedef struct FMOD_STUDIO_COMMANDREPLAY FMOD_STUDIO_COMMANDREPLAY; + +/* + FMOD Studio constants +*/ +#define FMOD_STUDIO_LOAD_MEMORY_ALIGNMENT 32 + +typedef unsigned int FMOD_STUDIO_INITFLAGS; +#define FMOD_STUDIO_INIT_NORMAL 0x00000000 +#define FMOD_STUDIO_INIT_LIVEUPDATE 0x00000001 +#define FMOD_STUDIO_INIT_ALLOW_MISSING_PLUGINS 0x00000002 +#define FMOD_STUDIO_INIT_SYNCHRONOUS_UPDATE 0x00000004 +#define FMOD_STUDIO_INIT_DEFERRED_CALLBACKS 0x00000008 +#define FMOD_STUDIO_INIT_LOAD_FROM_UPDATE 0x00000010 +#define FMOD_STUDIO_INIT_MEMORY_TRACKING 0x00000020 + +typedef unsigned int FMOD_STUDIO_PARAMETER_FLAGS; +#define FMOD_STUDIO_PARAMETER_READONLY 0x00000001 +#define FMOD_STUDIO_PARAMETER_AUTOMATIC 0x00000002 +#define FMOD_STUDIO_PARAMETER_GLOBAL 0x00000004 +#define FMOD_STUDIO_PARAMETER_DISCRETE 0x00000008 +#define FMOD_STUDIO_PARAMETER_LABELED 0x00000010 + +typedef unsigned int FMOD_STUDIO_SYSTEM_CALLBACK_TYPE; +#define FMOD_STUDIO_SYSTEM_CALLBACK_PREUPDATE 0x00000001 +#define FMOD_STUDIO_SYSTEM_CALLBACK_POSTUPDATE 0x00000002 +#define FMOD_STUDIO_SYSTEM_CALLBACK_BANK_UNLOAD 0x00000004 +#define FMOD_STUDIO_SYSTEM_CALLBACK_LIVEUPDATE_CONNECTED 0x00000008 +#define FMOD_STUDIO_SYSTEM_CALLBACK_LIVEUPDATE_DISCONNECTED 0x00000010 +#define FMOD_STUDIO_SYSTEM_CALLBACK_ALL 0xFFFFFFFF + +typedef unsigned int FMOD_STUDIO_EVENT_CALLBACK_TYPE; +#define FMOD_STUDIO_EVENT_CALLBACK_CREATED 0x00000001 +#define FMOD_STUDIO_EVENT_CALLBACK_DESTROYED 0x00000002 +#define FMOD_STUDIO_EVENT_CALLBACK_STARTING 0x00000004 +#define FMOD_STUDIO_EVENT_CALLBACK_STARTED 0x00000008 +#define FMOD_STUDIO_EVENT_CALLBACK_RESTARTED 0x00000010 +#define FMOD_STUDIO_EVENT_CALLBACK_STOPPED 0x00000020 +#define FMOD_STUDIO_EVENT_CALLBACK_START_FAILED 0x00000040 +#define FMOD_STUDIO_EVENT_CALLBACK_CREATE_PROGRAMMER_SOUND 0x00000080 +#define FMOD_STUDIO_EVENT_CALLBACK_DESTROY_PROGRAMMER_SOUND 0x00000100 +#define FMOD_STUDIO_EVENT_CALLBACK_PLUGIN_CREATED 0x00000200 +#define FMOD_STUDIO_EVENT_CALLBACK_PLUGIN_DESTROYED 0x00000400 +#define FMOD_STUDIO_EVENT_CALLBACK_TIMELINE_MARKER 0x00000800 +#define FMOD_STUDIO_EVENT_CALLBACK_TIMELINE_BEAT 0x00001000 +#define FMOD_STUDIO_EVENT_CALLBACK_SOUND_PLAYED 0x00002000 +#define FMOD_STUDIO_EVENT_CALLBACK_SOUND_STOPPED 0x00004000 +#define FMOD_STUDIO_EVENT_CALLBACK_REAL_TO_VIRTUAL 0x00008000 +#define FMOD_STUDIO_EVENT_CALLBACK_VIRTUAL_TO_REAL 0x00010000 +#define FMOD_STUDIO_EVENT_CALLBACK_START_EVENT_COMMAND 0x00020000 +#define FMOD_STUDIO_EVENT_CALLBACK_NESTED_TIMELINE_BEAT 0x00040000 +#define FMOD_STUDIO_EVENT_CALLBACK_ALL 0xFFFFFFFF + +typedef unsigned int FMOD_STUDIO_LOAD_BANK_FLAGS; +#define FMOD_STUDIO_LOAD_BANK_NORMAL 0x00000000 +#define FMOD_STUDIO_LOAD_BANK_NONBLOCKING 0x00000001 +#define FMOD_STUDIO_LOAD_BANK_DECOMPRESS_SAMPLES 0x00000002 +#define FMOD_STUDIO_LOAD_BANK_UNENCRYPTED 0x00000004 + +typedef unsigned int FMOD_STUDIO_COMMANDCAPTURE_FLAGS; +#define FMOD_STUDIO_COMMANDCAPTURE_NORMAL 0x00000000 +#define FMOD_STUDIO_COMMANDCAPTURE_FILEFLUSH 0x00000001 +#define FMOD_STUDIO_COMMANDCAPTURE_SKIP_INITIAL_STATE 0x00000002 + +typedef unsigned int FMOD_STUDIO_COMMANDREPLAY_FLAGS; +#define FMOD_STUDIO_COMMANDREPLAY_NORMAL 0x00000000 +#define FMOD_STUDIO_COMMANDREPLAY_SKIP_CLEANUP 0x00000001 +#define FMOD_STUDIO_COMMANDREPLAY_FAST_FORWARD 0x00000002 +#define FMOD_STUDIO_COMMANDREPLAY_SKIP_BANK_LOAD 0x00000004 + +typedef enum FMOD_STUDIO_LOADING_STATE +{ + FMOD_STUDIO_LOADING_STATE_UNLOADING, + FMOD_STUDIO_LOADING_STATE_UNLOADED, + FMOD_STUDIO_LOADING_STATE_LOADING, + FMOD_STUDIO_LOADING_STATE_LOADED, + FMOD_STUDIO_LOADING_STATE_ERROR, + + FMOD_STUDIO_LOADING_STATE_FORCEINT = 65536 /* Makes sure this enum is signed 32bit. */ +} FMOD_STUDIO_LOADING_STATE; + +typedef enum FMOD_STUDIO_LOAD_MEMORY_MODE +{ + FMOD_STUDIO_LOAD_MEMORY, + FMOD_STUDIO_LOAD_MEMORY_POINT, + + FMOD_STUDIO_LOAD_MEMORY_FORCEINT = 65536 /* Makes sure this enum is signed 32bit. */ +} FMOD_STUDIO_LOAD_MEMORY_MODE; + +typedef enum FMOD_STUDIO_PARAMETER_TYPE +{ + FMOD_STUDIO_PARAMETER_GAME_CONTROLLED, + FMOD_STUDIO_PARAMETER_AUTOMATIC_DISTANCE, + FMOD_STUDIO_PARAMETER_AUTOMATIC_EVENT_CONE_ANGLE, + FMOD_STUDIO_PARAMETER_AUTOMATIC_EVENT_ORIENTATION, + FMOD_STUDIO_PARAMETER_AUTOMATIC_DIRECTION, + FMOD_STUDIO_PARAMETER_AUTOMATIC_ELEVATION, + FMOD_STUDIO_PARAMETER_AUTOMATIC_LISTENER_ORIENTATION, + FMOD_STUDIO_PARAMETER_AUTOMATIC_SPEED, + FMOD_STUDIO_PARAMETER_AUTOMATIC_SPEED_ABSOLUTE, + FMOD_STUDIO_PARAMETER_AUTOMATIC_DISTANCE_NORMALIZED, + + FMOD_STUDIO_PARAMETER_MAX, + FMOD_STUDIO_PARAMETER_FORCEINT = 65536 /* Makes sure this enum is signed 32bit. */ +} FMOD_STUDIO_PARAMETER_TYPE; + +typedef enum FMOD_STUDIO_USER_PROPERTY_TYPE +{ + FMOD_STUDIO_USER_PROPERTY_TYPE_INTEGER, + FMOD_STUDIO_USER_PROPERTY_TYPE_BOOLEAN, + FMOD_STUDIO_USER_PROPERTY_TYPE_FLOAT, + FMOD_STUDIO_USER_PROPERTY_TYPE_STRING, + + FMOD_STUDIO_USER_PROPERTY_TYPE_FORCEINT = 65536 /* Makes sure this enum is signed 32bit. */ +} FMOD_STUDIO_USER_PROPERTY_TYPE; + +typedef enum FMOD_STUDIO_EVENT_PROPERTY +{ + FMOD_STUDIO_EVENT_PROPERTY_CHANNELPRIORITY, + FMOD_STUDIO_EVENT_PROPERTY_SCHEDULE_DELAY, + FMOD_STUDIO_EVENT_PROPERTY_SCHEDULE_LOOKAHEAD, + FMOD_STUDIO_EVENT_PROPERTY_MINIMUM_DISTANCE, + FMOD_STUDIO_EVENT_PROPERTY_MAXIMUM_DISTANCE, + FMOD_STUDIO_EVENT_PROPERTY_COOLDOWN, + FMOD_STUDIO_EVENT_PROPERTY_MAX, + + FMOD_STUDIO_EVENT_PROPERTY_FORCEINT = 65536 /* Makes sure this enum is signed 32bit. */ +} FMOD_STUDIO_EVENT_PROPERTY; + +typedef enum FMOD_STUDIO_PLAYBACK_STATE +{ + FMOD_STUDIO_PLAYBACK_PLAYING, + FMOD_STUDIO_PLAYBACK_SUSTAINING, + FMOD_STUDIO_PLAYBACK_STOPPED, + FMOD_STUDIO_PLAYBACK_STARTING, + FMOD_STUDIO_PLAYBACK_STOPPING, + + FMOD_STUDIO_PLAYBACK_FORCEINT = 65536 +} FMOD_STUDIO_PLAYBACK_STATE; + +typedef enum FMOD_STUDIO_STOP_MODE +{ + FMOD_STUDIO_STOP_ALLOWFADEOUT, + FMOD_STUDIO_STOP_IMMEDIATE, + + FMOD_STUDIO_STOP_FORCEINT = 65536 /* Makes sure this enum is signed 32bit. */ +} FMOD_STUDIO_STOP_MODE; + +typedef enum FMOD_STUDIO_INSTANCETYPE +{ + FMOD_STUDIO_INSTANCETYPE_NONE, + FMOD_STUDIO_INSTANCETYPE_SYSTEM, + FMOD_STUDIO_INSTANCETYPE_EVENTDESCRIPTION, + FMOD_STUDIO_INSTANCETYPE_EVENTINSTANCE, + FMOD_STUDIO_INSTANCETYPE_PARAMETERINSTANCE, + FMOD_STUDIO_INSTANCETYPE_BUS, + FMOD_STUDIO_INSTANCETYPE_VCA, + FMOD_STUDIO_INSTANCETYPE_BANK, + FMOD_STUDIO_INSTANCETYPE_COMMANDREPLAY, + + FMOD_STUDIO_INSTANCETYPE_FORCEINT = 65536 /* Makes sure this enum is signed 32bit. */ +} FMOD_STUDIO_INSTANCETYPE; + +/* + FMOD Studio structures +*/ +typedef struct FMOD_STUDIO_BANK_INFO +{ + int size; + void *userdata; + int userdatalength; + FMOD_FILE_OPEN_CALLBACK opencallback; + FMOD_FILE_CLOSE_CALLBACK closecallback; + FMOD_FILE_READ_CALLBACK readcallback; + FMOD_FILE_SEEK_CALLBACK seekcallback; +} FMOD_STUDIO_BANK_INFO; + +typedef struct FMOD_STUDIO_PARAMETER_ID +{ + unsigned int data1; + unsigned int data2; +} FMOD_STUDIO_PARAMETER_ID; + +typedef struct FMOD_STUDIO_PARAMETER_DESCRIPTION +{ + const char *name; + FMOD_STUDIO_PARAMETER_ID id; + float minimum; + float maximum; + float defaultvalue; + FMOD_STUDIO_PARAMETER_TYPE type; + FMOD_STUDIO_PARAMETER_FLAGS flags; + FMOD_GUID guid; +} FMOD_STUDIO_PARAMETER_DESCRIPTION; + +typedef struct FMOD_STUDIO_USER_PROPERTY +{ + const char *name; + FMOD_STUDIO_USER_PROPERTY_TYPE type; + + union + { + int intvalue; + FMOD_BOOL boolvalue; + float floatvalue; + const char *stringvalue; + }; +} FMOD_STUDIO_USER_PROPERTY; + +typedef struct FMOD_STUDIO_PROGRAMMER_SOUND_PROPERTIES +{ + const char *name; + FMOD_SOUND *sound; + int subsoundIndex; +} FMOD_STUDIO_PROGRAMMER_SOUND_PROPERTIES; + +typedef struct FMOD_STUDIO_PLUGIN_INSTANCE_PROPERTIES +{ + const char *name; + FMOD_DSP *dsp; +} FMOD_STUDIO_PLUGIN_INSTANCE_PROPERTIES; + +typedef struct FMOD_STUDIO_TIMELINE_MARKER_PROPERTIES +{ + const char *name; + int position; +} FMOD_STUDIO_TIMELINE_MARKER_PROPERTIES; + +typedef struct FMOD_STUDIO_TIMELINE_BEAT_PROPERTIES +{ + int bar; + int beat; + int position; + float tempo; + int timesignatureupper; + int timesignaturelower; +} FMOD_STUDIO_TIMELINE_BEAT_PROPERTIES; + +typedef struct FMOD_STUDIO_TIMELINE_NESTED_BEAT_PROPERTIES +{ + FMOD_GUID eventid; + FMOD_STUDIO_TIMELINE_BEAT_PROPERTIES properties; +} FMOD_STUDIO_TIMELINE_NESTED_BEAT_PROPERTIES; + +typedef struct FMOD_STUDIO_ADVANCEDSETTINGS +{ + int cbsize; + unsigned int commandqueuesize; + unsigned int handleinitialsize; + int studioupdateperiod; + int idlesampledatapoolsize; + unsigned int streamingscheduledelay; + const char* encryptionkey; +} FMOD_STUDIO_ADVANCEDSETTINGS; + +typedef struct FMOD_STUDIO_CPU_USAGE +{ + float update; +} FMOD_STUDIO_CPU_USAGE; + +typedef struct FMOD_STUDIO_BUFFER_INFO +{ + int currentusage; + int peakusage; + int capacity; + int stallcount; + float stalltime; +} FMOD_STUDIO_BUFFER_INFO; + +typedef struct FMOD_STUDIO_BUFFER_USAGE +{ + FMOD_STUDIO_BUFFER_INFO studiocommandqueue; + FMOD_STUDIO_BUFFER_INFO studiohandle; +} FMOD_STUDIO_BUFFER_USAGE; + +typedef struct FMOD_STUDIO_SOUND_INFO +{ + const char *name_or_data; + FMOD_MODE mode; + FMOD_CREATESOUNDEXINFO exinfo; + int subsoundindex; +} FMOD_STUDIO_SOUND_INFO; + +typedef struct FMOD_STUDIO_COMMAND_INFO +{ + const char *commandname; + int parentcommandindex; + int framenumber; + float frametime; + FMOD_STUDIO_INSTANCETYPE instancetype; + FMOD_STUDIO_INSTANCETYPE outputtype; + unsigned int instancehandle; + unsigned int outputhandle; +} FMOD_STUDIO_COMMAND_INFO; + +typedef struct FMOD_STUDIO_MEMORY_USAGE +{ + int exclusive; + int inclusive; + int sampledata; +} FMOD_STUDIO_MEMORY_USAGE; + +/* + FMOD Studio callbacks. +*/ +typedef FMOD_RESULT (F_CALL *FMOD_STUDIO_SYSTEM_CALLBACK) (FMOD_STUDIO_SYSTEM *system, FMOD_STUDIO_SYSTEM_CALLBACK_TYPE type, void *commanddata, void *userdata); +typedef FMOD_RESULT (F_CALL *FMOD_STUDIO_EVENT_CALLBACK) (FMOD_STUDIO_EVENT_CALLBACK_TYPE type, FMOD_STUDIO_EVENTINSTANCE *event, void *parameters); +typedef FMOD_RESULT (F_CALL *FMOD_STUDIO_COMMANDREPLAY_FRAME_CALLBACK) (FMOD_STUDIO_COMMANDREPLAY *replay, int commandindex, float currenttime, void *userdata); +typedef FMOD_RESULT (F_CALL *FMOD_STUDIO_COMMANDREPLAY_LOAD_BANK_CALLBACK) (FMOD_STUDIO_COMMANDREPLAY *replay, int commandindex, const FMOD_GUID *bankguid, const char *bankfilename, FMOD_STUDIO_LOAD_BANK_FLAGS flags, FMOD_STUDIO_BANK **bank, void *userdata); +typedef FMOD_RESULT (F_CALL *FMOD_STUDIO_COMMANDREPLAY_CREATE_INSTANCE_CALLBACK) (FMOD_STUDIO_COMMANDREPLAY *replay, int commandindex, FMOD_STUDIO_EVENTDESCRIPTION *eventdescription, FMOD_STUDIO_EVENTINSTANCE **instance, void *userdata); + +#endif // FMOD_STUDIO_COMMON_H diff --git a/FMOD/api/studio/lib/arm64/fmodstudio.dll b/FMOD/api/studio/lib/arm64/fmodstudio.dll new file mode 100644 index 0000000..e13b6f4 Binary files /dev/null and b/FMOD/api/studio/lib/arm64/fmodstudio.dll differ diff --git a/FMOD/api/studio/lib/arm64/fmodstudioL.dll b/FMOD/api/studio/lib/arm64/fmodstudioL.dll new file mode 100644 index 0000000..5d5c277 Binary files /dev/null and b/FMOD/api/studio/lib/arm64/fmodstudioL.dll differ diff --git a/FMOD/api/studio/lib/arm64/fmodstudioL_vc.lib b/FMOD/api/studio/lib/arm64/fmodstudioL_vc.lib new file mode 100644 index 0000000..374c9cb Binary files /dev/null and b/FMOD/api/studio/lib/arm64/fmodstudioL_vc.lib differ diff --git a/FMOD/api/studio/lib/arm64/fmodstudio_vc.lib b/FMOD/api/studio/lib/arm64/fmodstudio_vc.lib new file mode 100644 index 0000000..e3e8d09 Binary files /dev/null and b/FMOD/api/studio/lib/arm64/fmodstudio_vc.lib differ diff --git a/FMOD/api/studio/lib/x64/fmodstudio.dll b/FMOD/api/studio/lib/x64/fmodstudio.dll new file mode 100644 index 0000000..e701fe8 Binary files /dev/null and b/FMOD/api/studio/lib/x64/fmodstudio.dll differ diff --git a/FMOD/api/studio/lib/x64/fmodstudioL.dll b/FMOD/api/studio/lib/x64/fmodstudioL.dll new file mode 100644 index 0000000..8f8e167 Binary files /dev/null and b/FMOD/api/studio/lib/x64/fmodstudioL.dll differ diff --git a/FMOD/api/studio/lib/x64/fmodstudioL_vc.lib b/FMOD/api/studio/lib/x64/fmodstudioL_vc.lib new file mode 100644 index 0000000..8ce692e Binary files /dev/null and b/FMOD/api/studio/lib/x64/fmodstudioL_vc.lib differ diff --git a/FMOD/api/studio/lib/x64/fmodstudio_vc.lib b/FMOD/api/studio/lib/x64/fmodstudio_vc.lib new file mode 100644 index 0000000..62ea3ec Binary files /dev/null and b/FMOD/api/studio/lib/x64/fmodstudio_vc.lib differ diff --git a/FMOD/api/studio/lib/x86/fmodstudio.dll b/FMOD/api/studio/lib/x86/fmodstudio.dll new file mode 100644 index 0000000..22619e3 Binary files /dev/null and b/FMOD/api/studio/lib/x86/fmodstudio.dll differ diff --git a/FMOD/api/studio/lib/x86/fmodstudioL.dll b/FMOD/api/studio/lib/x86/fmodstudioL.dll new file mode 100644 index 0000000..a87a234 Binary files /dev/null and b/FMOD/api/studio/lib/x86/fmodstudioL.dll differ diff --git a/FMOD/api/studio/lib/x86/fmodstudioL_vc.lib b/FMOD/api/studio/lib/x86/fmodstudioL_vc.lib new file mode 100644 index 0000000..eddb980 Binary files /dev/null and b/FMOD/api/studio/lib/x86/fmodstudioL_vc.lib differ diff --git a/FMOD/api/studio/lib/x86/fmodstudio_vc.lib b/FMOD/api/studio/lib/x86/fmodstudio_vc.lib new file mode 100644 index 0000000..a9322e5 Binary files /dev/null and b/FMOD/api/studio/lib/x86/fmodstudio_vc.lib differ diff --git a/FMOD/api/studio/lib/x86/libfmodstudio.a b/FMOD/api/studio/lib/x86/libfmodstudio.a new file mode 100644 index 0000000..b590353 Binary files /dev/null and b/FMOD/api/studio/lib/x86/libfmodstudio.a differ diff --git a/FMOD/api/studio/lib/x86/libfmodstudioL.a b/FMOD/api/studio/lib/x86/libfmodstudioL.a new file mode 100644 index 0000000..e1882d1 Binary files /dev/null and b/FMOD/api/studio/lib/x86/libfmodstudioL.a differ diff --git a/FMOD/bin/FMOD Profiler.exe b/FMOD/bin/FMOD Profiler.exe new file mode 100644 index 0000000..471e461 Binary files /dev/null and b/FMOD/bin/FMOD Profiler.exe differ diff --git a/FMOD/bin/Qt6Core.dll b/FMOD/bin/Qt6Core.dll new file mode 100644 index 0000000..adbcb96 Binary files /dev/null and b/FMOD/bin/Qt6Core.dll differ diff --git a/FMOD/bin/Qt6Gui.dll b/FMOD/bin/Qt6Gui.dll new file mode 100644 index 0000000..0874b2d Binary files /dev/null and b/FMOD/bin/Qt6Gui.dll differ diff --git a/FMOD/bin/Qt6Network.dll b/FMOD/bin/Qt6Network.dll new file mode 100644 index 0000000..31357d2 Binary files /dev/null and b/FMOD/bin/Qt6Network.dll differ diff --git a/FMOD/bin/Qt6Widgets.dll b/FMOD/bin/Qt6Widgets.dll new file mode 100644 index 0000000..ca4da04 Binary files /dev/null and b/FMOD/bin/Qt6Widgets.dll differ diff --git a/FMOD/bin/fsbank.exe b/FMOD/bin/fsbank.exe new file mode 100644 index 0000000..1536c2d Binary files /dev/null and b/FMOD/bin/fsbank.exe differ diff --git a/FMOD/bin/fsbankcl.exe b/FMOD/bin/fsbankcl.exe new file mode 100644 index 0000000..761d532 Binary files /dev/null and b/FMOD/bin/fsbankcl.exe differ diff --git a/FMOD/bin/libfsbvorbis64.dll b/FMOD/bin/libfsbvorbis64.dll new file mode 100644 index 0000000..d42acbb Binary files /dev/null and b/FMOD/bin/libfsbvorbis64.dll differ diff --git a/FMOD/bin/opus.dll b/FMOD/bin/opus.dll new file mode 100644 index 0000000..f23c981 Binary files /dev/null and b/FMOD/bin/opus.dll differ diff --git a/FMOD/bin/platforms/qwindows.dll b/FMOD/bin/platforms/qwindows.dll new file mode 100644 index 0000000..4bdf1a1 Binary files /dev/null and b/FMOD/bin/platforms/qwindows.dll differ diff --git a/FMOD/doc/FMOD API User Manual/advanced-core-api-topics.html b/FMOD/doc/FMOD API User Manual/advanced-core-api-topics.html new file mode 100644 index 0000000..044c96c --- /dev/null +++ b/FMOD/doc/FMOD API User Manual/advanced-core-api-topics.html @@ -0,0 +1,772 @@ + + +Core API Advanced Topics + + + + +
+
+

FMOD Engine User Manual 2.03

+ +
+
+

10. Core API Advanced Topics

+

10.1 Detecting Audio Devices

+

The Core API has automatic sound card detection and recovery during playback. If a new device is inserted after initialization, the FMOD Engine will seamlessly jump to it, assuming it is the higher priority device. An example of this would be a USB headset being plugged in.

+

If the device that is being played on is removed, the FMOD Engine automatically jumps to the device considered next most important (e.g.: On Windows, it would be the new 'default' device). If a new device is inserted, then removed, the FMOD Engine ends up on the device it was originally playing on before the new device was inserted.

+

You can override the sound card detection behavior with a custom callback. This is the FMOD_SYSTEM_CALLBACK_DEVICELISTCHANGED callback.

+

10.2 Extracting PCM Data from a Sound

+

The following demonstrates how to extract PCM data from a Sound and place it into a buffer using Sound::readData. This technique is sometimes used to draw a vizualisation of a waveform, to send the data to another piece of software on the same machine, or to send the data over a network.

+

FMOD_OPENONLY must be used for the mode argument of System::createSound to ensure that file handle remains open for reading, as other modes will automatically read the entire file's data and close the file handle. Additionally, Sound::seekData can be used to seek within the Sound's data before reading into a buffer.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
FMOD::Sound *sound;
+unsigned int length;
+char *buffer;
+
+system->createSound("drumloop.wav", FMOD_OPENONLY, nullptr, &sound);
+sound->getLength(&length, FMOD_TIMEUNIT_RAWBYTES);
+
+buffer = new char[length];
+sound->readData(buffer, length, nullptr);
+
+delete[] buffer;
+
+ +
FMOD_SOUND *sound;
+unsigned int length;
+char *buffer;
+
+FMOD_System_CreateSound(system, "drumloop.wav", FMOD_OPENONLY, 0, &sound);
+FMOD_Sound_GetLength(sound, &length, FMOD_TIMEUNIT_RAWBYTES);
+
+buffer = (char *)malloc(length);
+FMOD_Sound_ReadData(sound, (void *)buffer, length, 0);
+
+free(buffer);
+
+ +
FMOD.Sound sound;
+uint length;
+byte[] buffer;
+
+system.createSound("drumloop.wav", FMOD.MODE.OPENONLY, out sound);
+sound.getLength(out length, FMOD.TIMEUNIT.RAWBYTES);
+
+buffer = new byte[(int)length];
+sound.readData(buffer);
+
+ +
var sound = {};
+var length = {};
+var buffer = {};
+
+system.createSound("drumloop.wav", FMOD.OPENONLY, null, sound);
+sound = sound.val;
+
+sound.getLength(length, FMOD.TIMEUNIT_RAWBYTES);
+length = length.val;
+
+sound.readData(buffer, length, null);
+buffer = buffer.val;
+
+ +

See Also: FMOD_TIMEUNIT, FMOD_MODE, Sound::getLength, System::createSound. Sound::seekData

+

10.3 Linking Plug-ins

+

You can extend the functionality of the FMOD Engine through the use of plug-ins. Each plug-in type (codec, DSP and output) has its own API you can use. Whether you have developed the plug-in yourself or you are using one from a third party, there are two ways to integrate it into FMOD.

+

10.3.1 Static

+

When the plug-in is available to you as source code, you can hook it up to FMOD by including the source file and using one of the plug-in registration APIs System::registerCodec, System::registerDSP or System::registerOutput. Each of these functions accepts the relevant description structure that provides the functionality of the plug-in. By convention, plug-in developers create a function that returns this description structure for you. For example, FMOD_AudioGaming_AudioMotors_GetDSPDescription is the name used by one of our partner plug-ins (it follows the form of "FMOD_[CompanyName]_[ProductName]_Get[PluginType]Description").

+

Alternatively, if you don't have source code, but you do have a static library (such as .lib or .a) it's almost the same process. Link the static library with your project, then call the description function passing the value into the registration function.

+

Codec Example

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
FMOD_RESULT result;
+unsigned int handle;
+FMOD::Sound* sound;
+
+result = system->registerCodec(FMOD_Example_GetCodecDescription(), &handle);
+
+// example.xyz is a file encoded with the codec's corresponding encoder
+result = system->createSound("example.xyz", FMOD_DEFAULT, 0, &sound);
+
+ +
FMOD_RESULT result;
+unsigned int handle;
+FMOD_SOUND* sound;
+
+result = FMOD_System_RegisterCodec(system, FMOD_Example_GetCodecDescription(), &handle, 0);
+
+// example.xyz is a file encoded with the codec's corresponding encoder
+result = FMOD_System_CreateSound(system, "example.xyz", FMOD_DEFAULT, 0, &sound);
+
+ +
var result = {};
+var handle = {};
+var sound = {};
+var outval = {};
+
+result = system.registerCodec(FMOD_Example_GetCodecDescription(), outval, 0);
+handle = outval.val;
+
+// example.xyz is a file encoded with the codec's corresponding encoder
+result = system.createSound("example.xyz", FMOD.DEFAULT, 0, outval);
+sound = outval.val;
+
+ +
+

Currently not supported for C#.

+
+

Output Example

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
FMOD_RESULT result;
+unsigned int handle;
+
+result = system->registerOutput(FMOD_Example_GetOutputDescription(), &handle);
+result = system->setOutputByPlugin(handle);
+
+ +
FMOD_RESULT result;
+unsigned int handle;
+
+result = FMOD_System_RegisterOutput(system, FMOD_Example_GetCodecDescription(), &handle);
+result = FMOD_System_SetOutputByPlugin(system, handle);
+
+ +
var result = {};
+var handle = {};
+var outval = {};
+
+result = system.registerOutput(FMOD_Example_GetOutputDescription(), outval, 0);
+handle = outval.val;
+result = system.setOutputByPlugin(handle);
+
+ +
+

Currently not supported for C#.

+
+

DSP Example

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
FMOD::Channel* channel;
+FMOD::DSP* dsp;
+FMOD_RESULT result;
+unsigned int handle;
+
+result = system->registerDSP(FMOD_Example_GetDSPDescription(), &handle);
+result = system->playSound(sound, 0, false, &channel);
+result = system->createDSPByPlugin(handle, &dsp);
+result = channel->addDSP(0, dsp);
+
+ +
FMOD_CHANNEL* channel;
+FMOD_DSP* dsp;
+FMOD_RESULT result;
+unsigned int handle;
+
+result = FMOD_System_RegisterDSP(system, FMOD_Example_GetDSPDescription(), &handle);
+result = FMOD_System_PlaySound(system, sound, 0, false, &channel);
+result = FMOD_System_CreateDSPByPlugin(system, handle, &dsp);
+result = FMOD_Channel_AddDSP(channel, 0, dsp);
+
+ +
var result = {};
+var handle = {};
+var dsp = {};
+var channel = {};
+var outval = {};
+
+result = system.registerDSP(FMOD_Example_GetDSPDescription(), outval);
+handle = outval.val;
+result = system.playSound(sound, 0, false, outval);
+channel = outval.val;
+result = system.createDSPByPlugin(handle, outval);
+dsp = outval.val;
+result = channel.addDSP(0, dsp);
+
+ +
+

Currently not supported for C#.

+
+

10.3.2 Dynamic

+

Another way plug-in code is distributed is via a prebuilt dynamic library (such as .so, .dll or .dylib). These are even easier to integrate with FMOD than static libraries.

+

First, ensure the plug-in file is in the working directory of your application. This is often the same location as the application executable. Then, in your code call System::loadPlugin, passing in the name of the library.

+

That's all there is to it. Under the hood, the FMOD Engine will open the library and search for well known functions similar to the description functions mentioned above. Once found, the plug-in is registered and ready for use.

+

Codec Example

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
FMOD_RESULT result;
+unsigned int handle;
+FMOD::Sound* sound;
+
+result = system->loadPlugin("example_codec.dll", &handle);
+
+// example.xyz is a file encoded with the codec's corresponding encoder
+result = system->createSound("example.xyz", FMOD_DEFAULT, 0, &sound);
+
+ +
FMOD_RESULT result;
+unsigned int handle;
+FMOD_SOUND* sound;
+
+result = FMOD_System_LoadPlugin(system, "example_codec.dll", &handle, 0);
+
+// example.xyz is a file encoded with the codec's corresponding encoder
+result = FMOD_System_CreateSound(system, "example.xyz", FMOD_DEFAULT, 0, &sound);
+
+ +
FMOD.Result result;
+uint handle;
+FMOD.Sound sound;
+
+result = system.loadPlugin("example_codec.dll", out handle);
+
+// example.xyz is a file encoded with the codec's corresponding encoder
+result = system.createSound("example.xyz", FMOD.MODE.DEFAULT, 0, out sound);
+
+ +
+

Currently not supported for JavaScript.

+
+

Output Example

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
FMOD_RESULT result;
+unsigned int handle;
+
+result = system->loadPlugin("example_output.dll", &handle);
+result = system->setOutputByPlugin(handle);
+
+ +
FMOD_RESULT result;
+unsigned int handle;
+
+result = FMOD_System_LoadPlugin(system, "example_output.dll", &handle, 0);
+result = FMOD_System_SetOutputByPlugin(system, handle);
+
+ +
FMOD.Result result;
+uint handle;
+
+result = system.loadPlugin("example_output.dll", out handle);
+result = system.setOutputByPlugin(handle);
+
+ +
+

Currently not supported for JavaScript.

+
+

DSP Example

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
FMOD::Channel* channel;
+FMOD::DSP* dsp;
+FMOD_RESULT result;
+unsigned int handle;
+
+result = system->loadPlugin("example_dsp.dll", &handle);
+result = system->playSound(sound, 0, false, &channel);
+result = system->createDSPByPlugin(handle, &dsp);
+result = channel->addDSP(0, dsp);
+
+ +
FMOD_CHANNEL* channel;
+FMOD_DSP* dsp;
+FMOD_RESULT result;
+unsigned int handle;
+
+result = FMOD_System_LoadPlugin(system, "example_dsp.dll", &handle, 0);
+result = FMOD_System_PlaySound(system, sound, 0, false, &channel);
+result = FMOD_System_CreateDSPByPlugin(system, handle, &dsp);
+result = FMOD_Channel_AddDSP(channel, 0, dsp);
+
+ +
FMOD.Channel channel;
+FMOD.DSP dsp;
+FMOD_RESULT result;
+uint handle;
+
+result = system.loadPlugin("example_dsp.dll", out handle);
+result = system.playSound(sound, 0, false, out channel);
+result = system.createDSPByPlugin(handle, out dsp);
+result = channel.addDSP(0, dsp);
+
+ +
+

Currently not supported for JavaScript.

+
+

10.4 Recording

+

The Core API has the ability to record directly from an input into a Sound object. This Sound can then be played back after it has been recorded, or the raw data can be retrieved with Sound::lock and Sound::unlock functions.

+

The Sound can also be played while it is recording, to allow realtime effects. A simple technique to achieve this is to start recording, then wait a small amount of time (for example, 50 ms), then play the Sound. This keeps the play cursor just behind the record cursor. For information on how to do this and an example of source code, see the "record" example in the /api/core/examples/bin folder of the FMOD Engine distribution.

+

10.5 Using Output Plug-ins

+

The Core API has support for user-created output plug-ins. A developer can create a plug-in to take FMOD audio output to a custom target. This could be a hardware device, or a non standard file/memory/network based system.

+

An output mode can run in real-time, or non real-time which allows the developer to run FMOD's mixer/streamer/system at faster or slower than real-time rates.

+

Plug-ins can be created inline with the application, or compiled as a stand-alone dynamic library (ie .dll or .so)

+

Unlike DSP and instrument plug-ins, output plug-ins cannot be used in conjunction with FMOD Studio.

+

See System::registerOutput documentation for more.

+

10.6 3D Polygon-based Geometry Occlusion

+

The Core API supports the supply of polygon mesh data that can be processed in real time to create the effect of occlusion in a 3D world. In real world terms, you can stop sounds from traveling through walls, or even confine reverb inside a geometric volume so that it doesn't leak out into other areas.

+

To use the FMOD Geometry Engine, create a mesh object with System::createGeometry. Then, add polygons to each mesh with Geometry::addPolygon. Each object can be translated, rotated and scaled to fit your environment.

+

10.7 Virtual 3D Reverb System

+

It is common for environments to exhibit different reverberation characteristics in different locations. Ideally as the listener moves throughout the virtual environment, the sound of the reverberation should change accordingly. This change in reverberation properties can be modeled in FMOD Studio by using the built in Reverb3D API.

+

10.7.1 3D Reverbs

+

The 3D reverb system works by using the main built-in system I3DL2 reverb, and allows you to place multiple virtual reverb spheres within the 3D world. Each reverb sphere defines:

+
    +
  • Its position within the 3D world
  • +
  • The area, or sphere of influence affected by the reverb (with minimum and maximum distances)
  • +
  • The reverberation properties of the area
  • +
+

At runtime, the FMOD Engine interpolates (or morphs) between the characteristics of 3D reverbs according to the listener's proximity and the position and overlap of the reverbs. This method allows the FMOD Engine to use a single reverb DSP unit to provide a dynamic reverberation within the 3D world. This process is illustrated in the image below.

+

3D Reverb

+

When the listener is within the sphere of effect of one or more 3D reverbs, the listener hears a weighted combination of the affecting reverbs. When the listener is outside the coverage of all 3D reverbs, the reverb is not applied.

+

Because this method requires only one reverb DSP unit regardless of how many virtual reverb spheres are created, there is no additional CPU cost for creating additional reverb spheres.

+

By default, 2D sounds share this same reverb DSP instance. To avoid 2D sounds having reverb, use ChannelControl::setReverbProperties and set wet = 0, or shift the 2D Sounds to a different reverb DSP instance, using the same function. Adding a second reverb DSP unit for this purpose will incur a small CPU and memory hit.

+

The following is an example of using the call System::createReverb3D, then setting the characteristics of the reverb using Reverb3D::setProperties.

+
FMOD::Reverb *reverb;
+result = system->createReverb3D(&reverb);
+FMOD_REVERB_PROPERTIES prop2 = FMOD_PRESET_CONCERTHALL;
+reverb->setProperties(&prop2);
+
+ +

In order for a reverb to exhibit 3D properties, it is necessary to set its 3D attributes. The method Reverb3D::set3DAttributes allows you to set a reverb's origin position, as well as the area of coverage using the minimum distance and maximum distance.

+
FMOD_VECTOR pos = { -10.0f, 0.0f, 0.0f };
+float mindist = 10.0f; 
+float maxdist = 20.0f;
+reverb->set3DAttributes(&pos, mindist, maxdist);
+
+ +

As the 3D reverb uses the position of the listener in its weighting calculation, you also need to ensure that the location of the listener is set using System::set3dListenerAttributes.

+
FMOD_VECTOR  listenerpos  = { 0.0f, 0.0f, -1.0f };
+system->set3DListenerAttributes(0, &listenerpos, 0, 0, 0);
+
+ +

This is all that is needed to get virtual 3d reverb zones to work. From this point onwards, based on the listener position, reverb presets should morph into each other if they overlap, and attenuate based on the listener's distance from the 3D reverb sphere's center.

+

10.7.2 Using Multiple Reverbs

+

The interpolation of 3D reverbs is only an estimation of how the multiple reverberations within the environment may sound. In some situations, greater realism is required, and so multiple styles of reverberations within a single environment must be modeled. For example, imagine a large church hall with a tunnel down into the catacombs. The reverb applied to the player's footsteps within the church hall (such as FMOD_PRESET_STONEROOM) could be quite different to that of the monster sounds emitting from the tunnel (which may be applied with both FMOD_PRESET_SEWERPIPE and FMOD_PRESET_STONEROOM). To handle this situation, multiple instances of the reverb DSP are required. As many as four instances of the reverb DSP can be added to the FMOD DSP graph, though each instance incurs a cost of more CPU time and memory usage.

+

FMOD Studio allows a sound designer to design their own reverbs, add them to group buses, and use sends and mixer snapshots to control the reverb mix. This section, however, describes how to use the Core API to add reverbs, query an instance's reverb properties, and control the wet/dry mix of each reverb instance on a per-channel basis.

+

Should you want to model multiple reverbs types within an environment without the extra resource expense of multiple reverb effects, use the method described in the 3D Reverbs section of this chapter instead, as it covers using automated 3D reverb zones to simulate reverb for different environments using only a single reverb instance.

+

Below is an example of using System::setReverbProperties to set up four different reverb effects. You do not need to explicitly create the extra reverb instance DSP objects, as the FMOD Engine creates them and connects them to the DSP graph when you reference them.

+
FMOD_REVERB_PROPERTIES prop1 = FMOD_PRESET_HALLWAY;
+FMOD_REVERB_PROPERTIES prop2 = FMOD_PRESET_SEWERPIPE;
+FMOD_REVERB_PROPERTIES prop3 = FMOD_PRESET_PARKINGLOT;
+FMOD_REVERB_PROPERTIES prop4 = FMOD_PRESET_CONCERTHALL;
+
+ +

The example defines four different FMOD_REVERB_PROPERTIES structures using presets. You can define your own reverb settings, but presets make it easier to get some common reverbs working. For more information about reverb presets, see the FMOD_REVERB_PRESETS section of the Core API Reference chapter.

+

Once the reverb effects are set up, the 'instance' parameter may be used to set which reverb DSP unit should be used for each preset, while calling the System::setReverbProperties function.

+
result = system->setReverbProperties(0, &prop1);
+result = system->setReverbProperties(1, &prop2);
+result = system->setReverbProperties(2, &prop3);
+result = system->setReverbProperties(3, &prop4);
+
+ +

Should you wish to get the current System reverb properties, you must specify the instance number in the 'instance' parameter when calling System::getReverbProperties, as shown in the below example of getting instance 3's properties.

+
FMOD_REVERB_PROPERTIES prop = { 0 };
+result = system->getReverbProperties(3, &prop);
+
+ +

You can set the wet/dry mix for each reverb on a channel of the FMOD Engine's mixer with ChannelControl::setReverbProperties. By default, a channel sends to all instances. The example below sets instance 1's send value to linear 0.0 (-80 db) (off).

+
result = channel->setReverbProperties(1, 0.0f);
+
+ +

To get the reverb mix level to be full volume again, set it to 1 (0db).

+
result = channel->setReverbProperties(1, 1.0f);
+
+ +

10.8 Transitioning from FMOD Ex

+

This section describes the differences between FMOD Ex and FMOD Studio.

+

10.8.1 Studio API Versus FMOD Designer API

+

The Studio API is conceptually similar to the old FMOD Designer API, but most classes have been renamed, and some have been removed or split up.

+

EventSystem and EventSystem_Create

+

The Studio::System class is analogous to the old EventSystem class. The static Studio::System::create function is analogous to the old EventSystem_Create function.

+

EventProject

+

The Studio::Bank class is analogous to the old EventProject class.

+

FEV and FSB Files

+

Each FMOD Designer project produced a single .fev file and multiple .fsb files. In contrast, an FMOD Studio project produces multiple .bank files, which contain event metadata as well as sample data. See the Studio::System::loadBankFile, Studio::Bank::loadSampleData, and Studio::EventDescription::loadSampleData functions. The Core API still supports loading .fsb files directly.

+

EventGroup

+

FMOD Studio doesn't have the concept of EventGroups. Events can be placed in folders, but this has no significance at runtime. To achieve the loading control formerly provided by EventGroups, events can be placed in different banks.

+

Event

+

The old Event class has been split into two classes: Studio::EventDescription and Studio::EventInstance. Studio::EventDescription holds the static data that describes an event, while Studio::EventInstance is a playable instance of an event. These two classes correspond to old Event objects retrieved by calling getEvent with or without the FMOD_EVENT_INFOONLY flag.

+

The FMOD Designer API used to create a fixed number of event instances when you first called getEvent without FMOD_EVENT_INFOONLY, whereas the Studio API creates a single instance each time you call Studio::EventDescription::createInstance. This gives you more control over the memory usage for each event.

+

Retrieving Events

+

Events can be retrieved by ID (using Studio::System::getEventByID) or by path (using Studio::System::getEvent).

+

Event IDs are GUIDs (globally unique identifiers), and stay the same even if the event is renamed or moved around in the project. IDs can be parsed from a string using Studio::parseID, or looked up from a path using Studio::System::lookupID if the "Master Bank.strings.bank" file is loaded.

+

Event paths consist of the string "event:/", followed by the the path to the event within the project's folder structure. To retrieve events by path, the "Master Bank.strings.bank" file must be loaded.

+

EventParameter

+

There is no class analogous to the old EventParameter class. Instead use the parameter getting and setting functions in Studio::EventInstance: Studio::EventInstance::getParameterByID, Studio::EventInstance::getParameterByName, Studio::EventInstance::setParameterByID, Studio::EventInstance::setParameterByName, Studio::EventInstance::setParametersByIDs.

+

Sustain Points and Key Off

+

The old EventParameter class had a keyOff function to move past the next sustain point. In FMOD Studio and the Studio API, this behavior is implemented via a built-in KeyOff that can be triggered via Studio::EventInstance::keyOff.

+

EventCategory

+

Event categories have been replaced in FMOD Studio by buses and VCAs, which provide much more functionality to the sound designer. In the Studio API, buses and VCAs are accessed via the Studio::Bus and Studio::VCA classes.

+

EventReverb

+

The EventReverb class has been removed. Similar functionality can be implemented using events with automatic distance parameters controlling reverb snapshots.

+

EventQueue and EventQueueEntry

+

FMOD Studio doesn't have the concept of event queues.

+

MusicSystem and MusicPrompt

+

Interactive music in FMOD Studio is implemented inside the event editor, so the MusicSystem and MusicPrompt classes have been removed.

+

NetEventSystem

+

Whereas the old network tweaking API was implemented as a separate fmod_event_net library, the FMOD Studio live update system is built into the main API library, and can be enabled by passing FMOD_STUDIO_INIT_LIVEUPDATE to Studio::System::initialize.

+

10.8.2 FMOD Studio's Core API Versus FMOD Ex's Core API

+ +

The FMOD Engine now handles the speaker mode automatically. Starting the Core API is as simple as calling System::init, and does not require querying caps or speaker modes to make the FMOD Engine's software mixer match that of the operating system. If you want the software mixer to be forced into a certain speaker mode, disregarding the operating system, use System::setSoftwareFormat. The FMOD Engine will automatically downmix or upmix this mode if the user's system is not the same speaker mode as the one selected for the software engine. Where possible, Dolby or internal downmixing will be used to achieve better surround effect.

+

Added new DSP effects

+

The following new DSP effects are added. (From fmod_dsp_effects.h)

+
FMOD_DSP_TYPE_SEND,               /* This unit sends a copy of the signal to a return DSP anywhere in the DSP tree. */
+FMOD_DSP_TYPE_RETURN,             /* This unit receives signals from a number of send DSPs. */
+FMOD_DSP_TYPE_HIGHPASS_SIMPLE,    /* This unit filters sound using a simple highpass with no resonance, but has flexible cutoff and is fast. Deprecated and will be removed in a future release (see FMOD_DSP_HIGHPASS_SIMPLE remarks for alternatives). */
+FMOD_DSP_TYPE_PAN,                /* This unit pans the signal, possibly upmixing or downmixing as well. */
+FMOD_DSP_TYPE_THREE_EQ,           /* This unit is a three-band equalizer. */
+FMOD_DSP_TYPE_FFT,                /* This unit simply analyzes the signal and provides spectrum information back through getParameter. */
+FMOD_DSP_TYPE_LOUDNESS_METER,     /* This unit analyzes the loudness and true peak of the signal. */
+FMOD_DSP_TYPE_ENVELOPEFOLLOWER,   /* This unit tracks the envelope of the input/sidechain signal. Format to be publicly disclosed soon. */
+FMOD_DSP_TYPE_CONVOLUTIONREVERB,  /* This unit implements convolution reverb. */
+FMOD_DSP_TYPE_CHANNELMIX,         /* This unit provides per signal channel gain, and output channel mapping to allow 1 multi-channel signal made up of many groups of signals to map to a single output signal. */
+FMOD_DSP_TYPE_TRANSCEIVER,        /* This unit 'sends' and 'receives' from a selection of up to 32 different slots.  It is like a send/return but it uses global slots rather than returns as the destination.  It also has other features.  Multiple transceivers can receive from a single channel, or multiple transceivers can send to a single channel, or a combination of both. */
+FMOD_DSP_TYPE_OBJECTPAN,          /* This unit sends the signal to a 3d object encoder like Dolby Atmos.   Supports a subset of the FMOD_DSP_TYPE_PAN parameters. */
+FMOD_DSP_TYPE_MULTIBAND_EQ,       /* This unit is a flexible five band parametric equalizer. */
+
+ +

FMOD's convolution reverb also has the option to be GPU accelerated for big performance wins.

+

New file format support

+

FMOD_SOUND_TYPE_FADPCM is a new highly optimized, branchless ADPCM variant which has higher quality than IMA ADPCM, and better performance. Great for mobiles.

+

Dolby Atmos support

+

Through the FMOD object panner, sounds can be positioned spherically in 3d space to support Dolby Atmos. This includes height speakers.

+

New DSP mixing engine

+

The FMOD Engine's software mixing engine is more flexible than that of FMOD Ex, with support for changing channel formats and speaker modes as the signal flows through the mix. The FMOD Engine's software mixing engine also has better custom DSP support, with branch idling, silence detection, sends and returns, side-chaining, circular connections and more.

+

Added plug-in info helper function

+

System::getDSPInfoByPlugin has been added to plug the gap between loading a plug-in, and getting its FMOD_DSP_DESCRIPTION structure so that it can be passed to System::createDSP.

+

Added background suspension support

+

For mobile devices, System::mixerSuspend and System::mixerResume allows you to halt FMOD's cpu mixer and thread before sleeping or answering a call or any other interruption event.

+

ChannelGroups volume and panning are now DSP based, rather than reaching down to the Channels of the child ChannelGroups.

+

ChannelGroups in FMOD Ex were a way to scale and modify the pan and volume of the Channels in the ChannelGroups below. The FMOD Engine now modifies pan and volume on a DSP basis using the fader DSP unit. A fader unit can be repositioned in a channel group's effect list, allowing effects to be either post- or pre-fader effects.

+

Added additional output streams

+

System::attachChannelGroupToPort and System::detachChannelGroupFromPort allows signals to be sent to alternate sound outputs like headsets, controllers with speakers, and console based multi speaker arrays that are not the standard surround sound speaker output.

+

Added Sound helper function

+

Added the ability for a child sound (subsound) to query for its parent via Sound::getSubSoundParent.

+

Added sample volume control

+

ChannelControl::addFadePoint, ChannelControl::removeFadePoints and ChannelControl::getFadePoints give the ability to set up a volume fade or ramp between any 2 clock points is possible. Link up multiple fade points to create envelopes. All fading is clock accurate and compensated for when pitch is changed. ChannelControl::setVolumeRamp / ChannelControl::getVolumeRamp can be used when queuing sounds up and for other reasons, it can be desirable to turn off ramping of volume changes, so the ability has been added to turn volume ramping (declicking) off or on per Channel/ChannelGroup.

+

Added UTF8 support

+

Functions such as System::getDriverInfoW have been removed in favour of UTF8 support.

+

Added concept of a 'fader' DSP per Channel and ChannelGroup

+

Each Channel and ChannelGroup has a built in 'fader' (FMOD_DSP_TYPE_FADER). This also acts as the DSP 'head' of the Channel or ChannelGroup by default.
+This can of course be changed later. If you add an effect, you can position it to be the head, and the fader will be before that in the signal chain.
+A fader DSP simply adjusts volume of the signal for a mix, and also supports sample accurate volume fade points, for envelopes and fade ins / fade outs.
+A panner is a separate entity which can pan a sound in mono, stereo and surround using a variety of parameters including position/direction/extent/rotation/axis control and 3d position control.
+The order of processing of a fader and panner can be controlled using ChannelControl::setDSPIndex, and it can be positioned into an effect chain so that panning comes before an effect or after, with fading coming at a different position in the effect chain.

+

New DSPConnection types supported

+

DSP::addInput now has a new optional parameter to describe the connection's behavior between two DSP units. FMOD_DSPCONNECTION_TYPE has been added to tell an input DSP that it should mix to a 'sidechain' buffer, which is a special buffer for DSP units that want to process a sidechain (for example a compressor) through a DSP unit's FMOD_DSP_STATE structure. This signal is not audible but is used to affect behavior within the DSP. FMOD_DSPCONNECTION_TYPE_SIDECHAIN would be used here.
+It should only consume existing data, not execute the input to generate that data. FMOD_DSPCONNECTION_TYPE_SEND would be used here. This can be useful for graph dependency reasons, so that an input is not executed before it should be.

+

New DSP parameter types

+

In FMOD Ex, only float parameters were supported. Now Int, Bool and Data parameters are supported.
+Use:

+ +

FMOD_HARDWARE support

+

The FMOD Engine's software mixing is sufficiently advanced that it can do things that would be impossible with the limited features of hardware voices. Today, when multicore processors are common even on mobile platforms, hardware voice support provides no real advantage; not when the FMOD Engine can be faster, better quality, and more flexible. As such, all sounds and voices handled by the FMOD Engine are software mixed.

+

API changes:

+
    +
  • System::setHardwareChannels is removed
  • +
  • System::getDriverCaps is removed. systemrate, speakermode, speakermodechannels parameters have been added to System::getDriverInfo to provide the information which may be important to the developer. Similarly, System::getRecordDriverCaps has been removed, in favour of System::getRecordDriverInfo.
  • +
  • System::setSpeakerMode and System::getSpeakerMode are removed, and instead are now moved into System::setSoftwareFormat because 'speakermode' now only affects the internal mixer, and the operating system speaker mode is matched at runtime through matrix upmixing or downmixing (automatically).
  • +
+

Channels and ChannelGroups have been merged into 'ChannelControl'

+

Channels and ChannelGroups had some similar functionality in FMOD Ex (ie setVolume, setPaused), but the FMOD Engine takes it even further. The FMOD Engine is designed so that ChannelGroups can have a lot more control, including allowing pausing and muting at the DSP node level, adding effects, and positioning in 3D.

+

Converting FMOD Reverb parameters

+

The FMOD Engine handles reverb parameters differently to FMOD Ex. Use this table to convert from FMOD Ex parameters to FMOD Engine parameters.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
FMOD Engine propertyRangeFMOD Ex property / conversion formula to create FMOD Engine value
DecayTime (ms)100 to 20000DecayTime * 1000
EarlyDelay (ms)0 to 300ReflectionsDelay * 1000
LateDelay (ms)0 to 100ReverbDelay * 1000
HFReference (Hz)20 to 20000HFReference
HFDecayRatio (%)0 to 100DecayHFRatio * 100
Diffusion (%)0 to 100Diffusion
Density (%)0 to 100Density
LowShelfFrequency (Hz)20 to 1000LFReference
LowShelfGain (dB)-48 to 12RoomLF / 100
HighCut (Hz)20 to 20000IF RoomHF < 0 THEN HFReference / sqrt((1-HFGain) / HFGain) ELSE 20000
EarlyLateMix (%)0 to 100IF Reflections > -10000 THEN LateEarlyRatio/(LateEarlyRatio + 1) * 100 ELSE 100
WetLevel (dB)-80 to 2010 * log10(EarlyAndLatePower) + Room / 100
+

Note: Clamp all values to maximum (after conversion) as some conversions may exceed the new parameter range.

+ + + + + + + + + + + + + + + + + + + + + +
Intermediate variables used in conversionFormulas
LateEarlyRatiopow(10, (Reverb - Reflections) / 2000)
EarlyAndLatePowerpow(10, Reflections / 1000) + pow(10, Reverb / 1000)
HFGainpow(10, RoomHF / 2000)
+

System::set3DSpeakerPosition renamed

+

System::setSpeakerPosition is a minor name change to denote that 3d and 2d positioning is affected by speaker location.

+

FMOD_CHANNEL_FREE / FMOD_CHANNEL_REUSE removed. Default ChannelGroup now passed to playSound if needed

+

System::playSound and System::playDSP now do not take a 'channel' parameter. All channels behave the same way as FMOD_CHANNEL_FREE would have in FMOD Ex.
+Seeing as a parameter was removed from playSound/playDSP, a new one was added to remove the overhead of disconnecting and reconnecting DSP graph nodes after playSound was called, so that they could be hooked up to a new ChannelGroup other than the master ChannelGroup. Consider this addition a performance optimization, and a simplification in API calls.

+

CDROM / CDDA support removed

+

Legacy support for CDROM redbook audio playback has been removed due to lack of interest and issues with maintaining said code.

+

System::getSpectrum and System::getWaveData removed

+

Add a custom DSP unit to capture DSP wavedata from the output stage. Use the master ChannelGroup's DSP head with System::getMasterChannelGroup and ChannelControl::getDSP.
+Add a built in FFT DSP unit type to capture spectrum data from the output stage. Create a built in FFT unit with System::createDSPByType and FMOD_DSP_TYPE_FFT, then add the effect to the master ChannelGroup with ChannelControl::addDSP. Use DSP::getParameterData to get the raw spectrum data or use DSP::getParameterFloat to get the dominant frequency from the signal.

+

'W' function wide char support removed

+

Functions such as System::getDriverInfoW have been removed in favour of UTF8 support.

+

System::setReverbAmbientProperties removed

+

The 'background' ambient reverb for a 3d reverb system is now just the standard reverb set with System::setReverbProperties.

+

System::getDSPClock removed

+

Use the DSP clock of the master ChannelGroup instead with System::getMasterChannelGroup and ChannelControl::getDSPClock.

+

getMemoryInfo functions have been removed from all classes

+

Due to the unreliability of the function in FMOD Ex due to caching, threads, and shared memory throwing results out, the function has been removed. Alternate memory tracking methods will be added later. FMOD::Memory_GetStats and logging is the best way to track memory at the moment.

+

Sound::setVariations and Sound::getVariations have been removed

+

Due to this being a 'helper' function that can easily be achieved in user code, this was deemed not necessary and removed.

+

Sound::setSubSoundSentence has been removed

+

This function has been removed in favour of the extremely precise and more reliable ChannelControl::setDelay functionality. 2 or more sounds can be queued up to play end to end using this function, with the added benefit of cross fades and overlaps.

+

setDelay and clock functions now use 64bit 'long long' type rather than than 32bit hi and 32bit low part parameters.

+

Due to the complexity of working in fixed point, and seeing as there is a consistent 64bit type for all compilers in long long that FMOD supports, we have switched to this type.
+1 32bit value would wrap around in 24 hours at 48khz, so 64bit values will last for 12 million years which should be enough to avoid in game clock wrap around.

+

Channel::setSpeakerMix, Channel::setSpeakerLevels, Channel::setInputChannelMix, Channel::getPan, Channel::getSpeakerMix and Channel::getSpeakerLevels removed

+

A cleaner replacement has been made for these functions,

+ +

Note that because setPan, setMixLevelsOutput and setMixLevelsInput all affect a final pan matrix, only getMixMatrix is available as the 'getter'. There is no more exclusive mode for the panning technique like there was in FMOD Ex. All 3 functions can now affect the final matrix. The setMixMatrix function now allows instant setting of a full matrix for performance reasons, rather than calling setSpeakerLevels each time for each speaker.

+

DSPConnection::setLevels/getLevels have been removed.

+

As above, new functionality is available to produce the same result. Rather than setting output levels row by row, a full 2 dimensional matrix is supplied with DSPConnection::setMixMatrix.

+

Channel::set3DPanLevel misnomer renamed

+

The FMOD Ex function did not actually only affect pan, it also affected doppler and distance attenuation so to call it 'pan' level was not really correct. THe FMOD Engine corrects this with ChannelControl::set3DLevel.

+

'override' functions removed from ChannelGroup class

+

Because volume/pitch/muting/reverb properties and pausing has been added as a ChannelGroup concept at the DSP level, ChannelGroups no longer rely on their 'channels' to do pausing and muting type logic. The ChannelGroup's DSP itself will directly mute/pause etc, thanks to the removal of FMOD_HARDWARE support.

+

System::addDSP removed from the System API

+

Rather than using the 'system' to add a DSP to, the user must use System::getMasterChannelGroup which gets the top level ChannelGroup, then use ChannelControl::addDSP to add the DSP to it, which effectively puts at the end of the signal chain.

+

DSP::remove removed from the DSP API

+

Effects that are added with ChannelControl::addDSP are owned by the ChannelControl that added it, and therefore must be removed with ChannelControl::removeDSP, instead of having the DSP removing itself. This helps the ChannelGroup or Channel manage resources.

+ + +
+ + + diff --git a/FMOD/doc/FMOD API User Manual/core-api-channel.html b/FMOD/doc/FMOD API User Manual/core-api-channel.html new file mode 100644 index 0000000..831fbfe --- /dev/null +++ b/FMOD/doc/FMOD API User Manual/core-api-channel.html @@ -0,0 +1,814 @@ + + +Core API Reference | Channel + + + + +
+ +
+

11. Core API Reference | Channel

+

A source of audio signal that connects to the ChannelGroup mixing hierarchy.

+

Create with System::playSound or System::playDSP.

+

Playback control:

+ +

Information:

+ +

The following APIs are inherited from ChannelControl:

+

Playback:

+ +

Volume levels:

+ +

Spatialization:

+ +

Panning and level adjustment:

+ +

Filtering:

+ +

DSP chain configuration:

+ +

Sample accurate scheduling:

+ +

General:

+ +

Channel::getChannelGroup

+

Retrieves the ChannelGroup this object outputs to.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
FMOD_RESULT Channel::getChannelGroup(
+  ChannelGroup **channelgroup
+);
+
+ +
FMOD_RESULT FMOD_Channel_GetChannelGroup(
+  FMOD_CHANNEL *channel,
+  FMOD_CHANNELGROUP **channelgroup
+);
+
+ +
RESULT Channel.getChannelGroup(
+  out ChannelGroup channelgroup
+);
+
+ +
Channel.getChannelGroup(
+  channelgroup
+);
+
+ +
+
channelgroup Out
+
Output group. (ChannelGroup)
+
+

See Also: Channel::setChannelGroup

+

Channel::getCurrentSound

+

Retrieves the currently playing Sound.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
FMOD_RESULT Channel::getCurrentSound(
+  Sound **sound
+);
+
+ +
FMOD_RESULT FMOD_Channel_GetCurrentSound(
+  FMOD_CHANNEL *channel,
+  FMOD_SOUND **sound
+);
+
+ +
RESULT Channel.getCurrentSound(
+  out Sound sound
+);
+
+ +
Channel.getCurrentSound(
+  sound
+);
+
+ +
+
sound Out
+
Currently playing sound. (Sound)
+
+

May return NULL or equivalent if no Sound is playing.

+

See Also: System::playSound

+

Channel::getFrequency

+

Retrieves the playback frequency or playback rate.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
FMOD_RESULT Channel::getFrequency(
+  float *frequency
+);
+
+ +
FMOD_RESULT FMOD_Channel_GetFrequency(
+  FMOD_CHANNEL *channel,
+  float *frequency
+);
+
+ +
RESULT Channel.getFrequency(
+  out float frequency
+);
+
+ +
Channel.getFrequency(
+  frequency
+);
+
+ +
+
frequency Out
+
+

Playback frequency.

+
    +
  • Units: Hertz
  • +
+
+
+

See Also: Channel::setFrequency

+

Channel::getIndex

+

Retrieves the index of this object in the System Channel pool.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
FMOD_RESULT Channel::getIndex(
+  int *index
+);
+
+ +
FMOD_RESULT FMOD_Channel_GetIndex(
+  FMOD_CHANNEL *channel,
+  int *index
+);
+
+ +
RESULT Channel.getIndex(
+  out int index
+);
+
+ +
Channel.getIndex(
+  index
+);
+
+ +
+
index Out
+
+

Index within the System Channel pool.

+ +
+
+

See Also: System::getChannel

+

Channel::getLoopCount

+

Retrieves the number of times to loop before stopping.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
FMOD_RESULT Channel::getLoopCount(
+  int *loopcount
+);
+
+ +
FMOD_RESULT FMOD_Channel_GetLoopCount(
+  FMOD_CHANNEL *channel,
+  int *loopcount
+);
+
+ +
RESULT Channel.getLoopCount(
+  out int loopcount
+);
+
+ +
Channel.getLoopCount(
+  loopcount
+);
+
+ +
+
loopcount Out
+
Times to loop before stopping where 0 represents "oneshot", 1 represents "loop once then stop" and -1 represents "loop forever".
+
+

This is the current loop countdown value that will decrement as it plays until reaching 0. Reset with Channel::setLoopCount.

+

Channel::getLoopPoints

+

Retrieves the loop start and end points.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
FMOD_RESULT Channel::getLoopPoints(
+  unsigned int *loopstart,
+  FMOD_TIMEUNIT loopstarttype,
+  unsigned int *loopend,
+  FMOD_TIMEUNIT loopendtype
+);
+
+ +
FMOD_RESULT FMOD_Channel_GetLoopPoints(
+  FMOD_CHANNEL *channel,
+  unsigned int *loopstart,
+  FMOD_TIMEUNIT loopstarttype,
+  unsigned int *loopend,
+  FMOD_TIMEUNIT loopendtype
+);
+
+ +
RESULT Channel.getLoopPoints(
+  out uint loopstart,
+  TIMEUNIT loopstarttype,
+  out uint loopend,
+  TIMEUNIT loopendtype
+);
+
+ +
Channel.getLoopPoints(
+  loopstart,
+  loopstarttype,
+  loopend,
+  loopendtype
+);
+
+ +
+
loopstart OutOpt
+
+

Loop start point.

+ +
+
loopstarttype
+
Time units for loopstart. (FMOD_TIMEUNIT)
+
loopend OutOpt
+
+

Loop end point.

+ +
+
loopendtype
+
Time units for loopend. (FMOD_TIMEUNIT)
+
+

Valid FMOD_TIMEUNIT types are FMOD_TIMEUNIT_PCM, FMOD_TIMEUNIT_MS, FMOD_TIMEUNIT_PCMBYTES. Any other time units return FMOD_ERR_FORMAT.
+If FMOD_TIMEUNIT_MS or FMOD_TIMEUNIT_PCMBYTES are used, the value is internally converted from FMOD_TIMEUNIT_PCM, so the retrieved value may not exactly match the set value.

+

See Also: Channel::setLoopPoints

+

Channel::getPosition

+

Retrieves the current playback position.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
FMOD_RESULT Channel::getPosition(
+  unsigned int *position,
+  FMOD_TIMEUNIT postype
+);
+
+ +
FMOD_RESULT FMOD_Channel_GetPosition(
+  FMOD_CHANNEL *channel,
+  unsigned int *position,
+  FMOD_TIMEUNIT postype
+);
+
+ +
RESULT Channel.getPosition(
+  out uint position,
+  TIMEUNIT postype
+);
+
+ +
Channel.getPosition(
+  position,
+  postype
+);
+
+ +
+
position Out
+
Playback position.
+
postype
+
Time units for position. (FMOD_TIMEUNIT)
+
+

Certain FMOD_TIMEUNIT types are always available: FMOD_TIMEUNIT_PCM, FMOD_TIMEUNIT_PCMBYTES and FMOD_TIMEUNIT_MS. The others are format specific such as FMOD_TIMEUNIT_MODORDER / FMOD_TIMEUNIT_MODROW / FMOD_TIMEUNIT_MODPATTERN which is specific to files of type MOD / S3M / XM / IT.

+

If FMOD_TIMEUNIT_MS or FMOD_TIMEUNIT_PCMBYTES are used, the value is internally converted from FMOD_TIMEUNIT_PCM, so the retrieved value may not exactly match the set value.

+

See Also: Channel::setPosition

+

Channel::getPriority

+

Retrieves the priority used for virtual voice ordering.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
FMOD_RESULT Channel::getPriority(
+  int *priority
+);
+
+ +
FMOD_RESULT FMOD_Channel_GetPriority(
+  FMOD_CHANNEL *channel,
+  int *priority
+);
+
+ +
RESULT Channel.getPriority(
+  out int priority
+);
+
+ +
Channel.getPriority(
+  priority
+);
+
+ +
+
priority Out
+
+

Priority where 0 represents most important and 256 represents least important.

+
    +
  • Range: [0, 256]
  • +
  • Default: 128
  • +
+
+
+

Priority is used as a coarse grain control for the virtual voice system, lower priority Channels will always be stolen before higher ones. For Channels of equal priority, those with the quietest ChannelControl::getAudibility value will be stolen first.

+

For more information, see the Virtual Voice System section of the Managing Resources in the Core API chapter.

+

See Also: Channel::setPriority

+

Channel::isVirtual

+

Retrieves whether the Channel is being emulated by the virtual voice system.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
FMOD_RESULT Channel::isVirtual(
+  bool *isvirtual
+);
+
+ +
FMOD_RESULT FMOD_Channel_IsVirtual(
+  FMOD_CHANNEL *channel,
+  FMOD_BOOL *isvirtual
+);
+
+ +
RESULT Channel.isVirtual(
+  out bool isvirtual
+);
+
+ +
Channel.isVirtual(
+  isvirtual
+);
+
+ +
+
isvirtual Out
+
+

Virtual state. True = silent / emulated. False = audible / real.

+
    +
  • Units: Boolean
  • +
+
+
+

See the Virtual Voice System section of the Managing Resources in the Core API chapter for more information.

+

See Also: ChannelControl::getAudibility

+

Channel::setChannelGroup

+

Sets the ChannelGroup this object outputs to.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
FMOD_RESULT Channel::setChannelGroup(
+  ChannelGroup *channelgroup
+);
+
+ +
FMOD_RESULT FMOD_Channel_SetChannelGroup(
+  FMOD_CHANNEL *channel,
+  FMOD_CHANNELGROUP *channelgroup
+);
+
+ +
RESULT Channel.setChannelGroup(
+  ChannelGroup channelgroup
+);
+
+ +
Channel.setChannelGroup(
+  channelgroup
+);
+
+ +
+
channelgroup
+
Output group. (ChannelGroup)
+
+

A ChannelGroup may contain many Channels.

+

Channels may only output to a single ChannelGroup. This operation will remove it from the previous group first.

+

See Also: Channel::getChannelGroup

+

Channel::setFrequency

+

Sets the frequency or playback rate.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
FMOD_RESULT Channel::setFrequency(
+  float frequency
+);
+
+ +
FMOD_RESULT FMOD_Channel_SetFrequency(
+  FMOD_CHANNEL *channel,
+  float frequency
+);
+
+ +
RESULT Channel.setFrequency(
+  float frequency
+);
+
+ +
Channel.setFrequency(
+  frequency
+);
+
+ +
+
frequency
+
+

Playback rate.

+
    +
  • Units: Hertz
  • +
+
+
+

Default frequency is determined by the audio format of the Sound or DSP.

+

Sounds opened as FMOD_CREATESAMPLE (not FMOD_CREATESTREAM or FMOD_CREATECOMPRESSEDSAMPLE) can be played backwards by giving a negative frequency.

+

See Also: Channel::getFrequency, Sound::setDefaults

+

Channel::setLoopCount

+

Sets the number of times to loop before stopping.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
FMOD_RESULT Channel::setLoopCount(
+  int loopcount
+);
+
+ +
FMOD_RESULT FMOD_Channel_SetLoopCount(
+  FMOD_CHANNEL *channel,
+  int loopcount
+);
+
+ +
RESULT Channel.setLoopCount(
+  int loopcount
+);
+
+ +
Channel.setLoopCount(
+  loopcount
+);
+
+ +
+
loopcount
+
Times to loop before stopping where 0 represents "oneshot", 1 represents "loop once then stop" and -1 represents "loop forever".
+
+

The 'mode' of the Sound or Channel must be FMOD_LOOP_NORMAL or FMOD_LOOP_BIDI for this function to work.

+

See Also: Streaming Issues, Channel::getLoopCount, ChannelControl::setMode, Sound::setMode, System::createSound

+

Channel::setLoopPoints

+

Sets the loop start and end points.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
FMOD_RESULT Channel::setLoopPoints(
+  unsigned int loopstart,
+  FMOD_TIMEUNIT loopstarttype,
+  unsigned int loopend,
+  FMOD_TIMEUNIT loopendtype
+);
+
+ +
FMOD_RESULT FMOD_Channel_SetLoopPoints(
+  FMOD_CHANNEL *channel,
+  unsigned int loopstart,
+  FMOD_TIMEUNIT loopstarttype,
+  unsigned int loopend,
+  FMOD_TIMEUNIT loopendtype
+);
+
+ +
RESULT Channel.setLoopPoints(
+  uint loopstart,
+  TIMEUNIT loopstarttype,
+  uint loopend,
+  TIMEUNIT loopendtype
+);
+
+ +
Channel.setLoopPoints(
+  loopstart,
+  loopstarttype,
+  loopend,
+  loopendtype
+);
+
+ +
+
loopstart
+
+

Loop start point.

+ +
+
loopstarttype
+
Time units for loopstart. (FMOD_TIMEUNIT)
+
loopend
+
+

Loop end point.

+ +
+
loopendtype
+
Time units for loopend. (FMOD_TIMEUNIT)
+
+

Loop points may only be set on a Channel playing a Sound, not a Channel playing a DSP (See System::playDSP).

+

Valid FMOD_TIMEUNIT types are FMOD_TIMEUNIT_PCM, FMOD_TIMEUNIT_MS, FMOD_TIMEUNIT_PCMBYTES. Any other time units return FMOD_ERR_FORMAT.
+If FMOD_TIMEUNIT_MS or FMOD_TIMEUNIT_PCMBYTES, the value is internally converted to FMOD_TIMEUNIT_PCM.

+

The Channel's mode must be set to FMOD_LOOP_NORMAL or FMOD_LOOP_BIDI for loop points to affect playback.

+

See Also: Streaming Issues, Channel::getLoopPoints, ChannelControl::setMode

+

Channel::setPosition

+

Sets the current playback position.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
FMOD_RESULT Channel::setPosition(
+  unsigned int position,
+  FMOD_TIMEUNIT postype
+);
+
+ +
FMOD_RESULT FMOD_Channel_SetPosition(
+  FMOD_CHANNEL *channel,
+  unsigned int position,
+  FMOD_TIMEUNIT postype
+);
+
+ +
RESULT Channel.setPosition(
+  uint position,
+  TIMEUNIT postype
+);
+
+ +
Channel.setPosition(
+  position,
+  postype
+);
+
+ +
+
position
+
Playback position.
+
postype
+
Time units for position. (FMOD_TIMEUNIT)
+
+

Certain FMOD_TIMEUNIT types are always available: FMOD_TIMEUNIT_PCM, FMOD_TIMEUNIT_PCMBYTES and FMOD_TIMEUNIT_MS. The others are format specific such as FMOD_TIMEUNIT_MODORDER / FMOD_TIMEUNIT_MODROW / FMOD_TIMEUNIT_MODPATTERN which is specific to files of type MOD / S3M / XM / IT.

+

If playing a Sound created with System::createStream or FMOD_CREATESTREAM changing the position may cause a slow reflush operation while the file seek and decode occurs. You can avoid this by creating the stream with FMOD_NONBLOCKING. This will cause the stream to go into FMOD_OPENSTATE_SETPOSITION state (see Sound::getOpenState) and Sound commands will return FMOD_ERR_NOTREADY. Channel::getPosition will also not update until this non-blocking set position operation has completed.

+

Using a VBR source that does not have an associated seek table or seek information (such as MP3 or MOD/S3M/XM/IT) may cause inaccurate seeking if you specify FMOD_TIMEUNIT_MS or FMOD_TIMEUNIT_PCM. If you want FMOD to create a PCM vs bytes seek table so that seeking is accurate, you will have to specify FMOD_ACCURATETIME when loading or opening the sound. This means there is a slight delay as FMOD scans the whole file when loading the sound to create this table.

+

See Also: Channel::getPosition

+

Channel::setPriority

+

Sets the priority used for virtual voice ordering.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
FMOD_RESULT Channel::setPriority(
+  int priority
+);
+
+ +
FMOD_RESULT FMOD_Channel_SetPriority(
+  FMOD_CHANNEL *channel,
+  int priority
+);
+
+ +
RESULT Channel.setPriority(
+  int priority
+);
+
+ +
Channel.setPriority(
+  priority
+);
+
+ +
+
priority
+
+

Priority where 0 represents most important and 256 represents least important.

+
    +
  • Range: [0, 256]
  • +
  • Default: 128
  • +
+
+
+

Priority is used as a coarse grain control for the virtual voice system, lower priority Channels will always be stolen before higher ones. For Channels of equal priority, those with the quietest ChannelControl::getAudibility value will be stolen first.

+

See the Virtual Voice System section of the Managing Resources in the Core API chapter for more information.

+

See Also: Channel::getPriority

+ + +
+ + + diff --git a/FMOD/doc/FMOD API User Manual/core-api-channelcontrol.html b/FMOD/doc/FMOD API User Manual/core-api-channelcontrol.html new file mode 100644 index 0000000..fd28ed5 --- /dev/null +++ b/FMOD/doc/FMOD API User Manual/core-api-channelcontrol.html @@ -0,0 +1,4019 @@ + + +Core API Reference | ChannelControl + + + + +
+ +
+

11. Core API Reference | ChannelControl

+

An interface that represents the shared APIs between Channel and ChannelGroup.

+

Playback:

+ +

Volume levels:

+ +

Spatialization:

+ +

Panning and level adjustment:

+ +

Filtering:

+ +

DSP chain configuration:

+ +
+ +

Sample accurate scheduling:

+ +

General:

+ +
+ +
+ +

ChannelControl::addDSP

+

Adds a DSP unit to the specified index in the DSP chain.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
FMOD_RESULT ChannelControl::addDSP(
+  int index,
+  DSP *dsp
+);
+
+ +
FMOD_RESULT FMOD_Channel_AddDSP(
+  FMOD_CHANNEL *channel,
+  int index,
+  FMOD_DSP *dsp
+);
+FMOD_RESULT FMOD_ChannelGroup_AddDSP(
+  FMOD_CHANNELGROUP *channelgroup,
+  int index,
+  FMOD_DSP *dsp
+);
+
+ +
RESULT ChannelControl.addDSP(
+  int index,
+  DSP dsp
+);
+
+ +
Channel.addDSP(
+  index,
+  dsp
+);
+ChannelGroup.addDSP(
+  index,
+  dsp
+);
+
+ +
+
index
+
+

Offset into the DSP chain, see FMOD_CHANNELCONTROL_DSP_INDEX for special named offsets for 'head' and 'tail' and 'fader' units.

+ +
+
dsp
+
DSP unit to be added. (DSP)
+
+

If dsp is already added to an existing object it will be removed and then added to this object.

+

For detailed information on FMOD's DSP graph, see the DSP Architecture and Usage section of the Using DSP Effects in the Core API chapter.

+

See Also: ChannelControl::removeDSP, System::createDSP, System::createDSPByType, System::createDSPByPlugin

+

ChannelControl::addFadePoint

+

Adds a sample accurate fade point at a time relative to the parent ChannelGroup DSP clock.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
FMOD_RESULT ChannelControl::addFadePoint(
+  unsigned long long dspclock,
+  float volume
+);
+
+ +
FMOD_RESULT FMOD_Channel_AddFadePoint(
+  FMOD_CHANNEL *channel,
+  unsigned long long dspclock,
+  float volume
+);
+FMOD_RESULT FMOD_ChannelGroup_AddFadePoint(
+  FMOD_CHANNELGROUP *channelgroup,
+  unsigned long long dspclock,
+  float volume
+);
+
+ +
RESULT ChannelControl.addFadePoint(
+  ulong dspclock,
+  float volume
+);
+
+ +
Channel.addFadePoint(
+  dspclock,
+  volume
+);
+ChannelGroup.addFadePoint(
+  dspclock,
+  volume
+);
+
+ +
+
dspclock
+
+

DSP clock of the parent ChannelGroup to set the fade point volume.

+
    +
  • Units: Samples
  • +
+
+
volume
+
+

Volume level at the given dspclock. Values above 1.0 amplify the signal.

+
    +
  • Units: Linear
  • +
  • Range: [0, inf)
  • +
+
+
+

Fade points are scaled against other volume settings and in-between each fade point the volume will be linearly ramped.

+

To perform sample accurate fading use ChannelControl::getDSPClock to query the parent clock value. If a parent ChannelGroup changes its pitch, the fade points will still be correct as the parent clock rate is adjusted by that pitch.

+
/* Example. Ramp from full volume to half volume over the next 4096 samples */
+unsigned long long parentclock;
+FMOD_ChannelControl_GetDSPClock(target, NULL, &parentclock);
+FMOD_ChannelControl_AddFadePoint(target, parentclock,        1.0f);
+FMOD_ChannelControl_AddFadePoint(target, parentclock + 4096, 0.5f);
+
+ +
// Example. Ramp from full volume to half volume over the next 4096 samples
+unsigned long long parentclock;
+target->getDSPClock(nullptr, &parentclock);
+target->addFadePoint(parentclock,        1.0f);
+target->addFadePoint(parentclock + 4096, 0.5f);
+
+ +

See Also: ChannelControl::removeFadePoints, ChannelControl::setFadePointRamp, ChannelControl::getFadePoints

+

FMOD_CHANNELCONTROL_CALLBACK

+

Callback for Channel or ChannelGroup notifications.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
FMOD_RESULT F_CALL FMOD_CHANNELCONTROL_CALLBACK(
+  FMOD_CHANNELCONTROL *channelcontrol,
+  FMOD_CHANNELCONTROL_TYPE controltype,
+  FMOD_CHANNELCONTROL_CALLBACK_TYPE callbacktype,
+  void *commanddata1,
+  void *commanddata2
+);
+
+ +
delegate RESULT CHANNELCONTROL_CALLBACK(
+  IntPtr channelcontrol,
+  CHANNELCONTROL_TYPE controltype,
+  CHANNELCONTROL_CALLBACK_TYPE callbacktype,
+  IntPtr commanddata1,
+  IntPtr commanddata2
+);
+
+ +
function FMOD_CHANNELCONTROL_CALLBACK(
+  channelcontrol,
+  controltype,
+  callbacktype,
+  commanddata1,
+  commanddata2
+)
+
+ +
+
channelcontrol
+
Base Channel or ChannelGroup handle. (ChannelControl)
+
controltype
+
Identifier to distinguish between Channel and ChannelGroup. (FMOD_CHANNELCONTROL_TYPE)
+
callbacktype
+
Type of callback. (FMOD_CHANNELCONTROL_CALLBACK_TYPE)
+
commanddata1 Opt
+
First callback parameter, see FMOD_CHANNELCONTROL_CALLBACK_TYPE for details.
+
commanddata2 Opt
+
Second callback parameter, see FMOD_CHANNELCONTROL_CALLBACK_TYPE for details.
+
+
+

The 'channelcontrol' argument can be cast to FMOD::Channel * or FMOD::ChannelGroup * given controltype.

+
+
+

The 'channelcontrol' argument can be cast to FMOD_CHANNEL * or FMOD_CHANNELGROUP * given controltype.

+
+
+

The 'channelcontrol' argument can be used via Channel or ChannelGroup by using FMOD.Channel channel = new FMOD.Channel(channelcontrol);

+
+

See Also: Callback Behavior, ChannelControl::setCallback

+

FMOD_CHANNELCONTROL_CALLBACK_TYPE

+

Types of callbacks called by Channels and ChannelGroups.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
typedef enum FMOD_CHANNELCONTROL_CALLBACK_TYPE {
+  FMOD_CHANNELCONTROL_CALLBACK_END,
+  FMOD_CHANNELCONTROL_CALLBACK_VIRTUALVOICE,
+  FMOD_CHANNELCONTROL_CALLBACK_SYNCPOINT,
+  FMOD_CHANNELCONTROL_CALLBACK_OCCLUSION,
+  FMOD_CHANNELCONTROL_CALLBACK_MAX
+} FMOD_CHANNELCONTROL_CALLBACK_TYPE;
+
+ +
enum CHANNELCONTROL_CALLBACK_TYPE : int
+{
+  END,
+  VIRTUALVOICE,
+  SYNCPOINT,
+  OCCLUSION,
+  MAX,
+}
+
+ +
CHANNELCONTROL_CALLBACK_END
+CHANNELCONTROL_CALLBACK_VIRTUALVOICE
+CHANNELCONTROL_CALLBACK_SYNCPOINT
+CHANNELCONTROL_CALLBACK_OCCLUSION
+CHANNELCONTROL_CALLBACK_MAX
+
+ +
+
FMOD_CHANNELCONTROL_CALLBACK_END
+
Called when a sound ends. Supported by Channel only.
+commanddata1: Unused.
+commanddata2: Unused.
+
FMOD_CHANNELCONTROL_CALLBACK_VIRTUALVOICE
+
Called when a Channel is made virtual or real. Supported by Channel objects only.
+commanddata1: (int) 0 represents 'virtual to real' and 1 represents 'real to virtual'.
+commanddata2: Unused.
+
FMOD_CHANNELCONTROL_CALLBACK_SYNCPOINT
+
Called when a syncpoint is encountered. Can be from wav file markers or user added. Supported by Channel only.
+commanddata1: (int) representing the index of the sync point for use with Sound::getSyncPointInfo.
+commanddata2: Unused.
+
FMOD_CHANNELCONTROL_CALLBACK_OCCLUSION
+
Called when geometry occlusion values are calculated. Can be used to clamp or change the value. Supported by Channel and ChannelGroup.
+commanddata1: (float *) representing the calculated direct occlusion value, can be modified.
+commanddata2: (float *) representing the calculated reverb occlusion value, can be modified.
+
FMOD_CHANNELCONTROL_CALLBACK_MAX
+
Maximum number of callback types supported.
+
+

commanddata1 and commanddata2 are parameters passed into the callback and each callback may interpret them differently as specified above. See FMOD_CHANNELCONTROL_CALLBACK.

+

Callbacks are called from the game thread when set from the Core API or Studio API in synchronous mode, and from the Studio Update Thread when in default / async mode.

+

See Also: Callback Behavior, ChannelControl::setCallback

+

FMOD_CHANNELCONTROL_DSP_INDEX

+

References to built-in DSP positions that reside in a Channel or ChannelGroup's DSP chain.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
typedef enum FMOD_CHANNELCONTROL_DSP_INDEX {
+  FMOD_CHANNELCONTROL_DSP_HEAD  = -1,
+  FMOD_CHANNELCONTROL_DSP_FADER = -2,
+  FMOD_CHANNELCONTROL_DSP_TAIL  = -3
+} FMOD_CHANNELCONTROL_DSP_INDEX;
+
+ +
struct CHANNELCONTROL_DSP_INDEX
+{
+  const int HEAD  = -1;
+  const int FADER = -2;
+  const int TAIL  = -3;
+}
+
+ +
CHANNELCONTROL_DSP_HEAD     = -1
+CHANNELCONTROL_DSP_FADER    = -2
+CHANNELCONTROL_DSP_TAIL     = -3
+
+ +
+
FMOD_CHANNELCONTROL_DSP_HEAD
+
Head of the DSP chain, closest to the output, equivalent of index 0.
+
FMOD_CHANNELCONTROL_DSP_FADER
+
Built-in fader DSP.
+
FMOD_CHANNELCONTROL_DSP_TAIL
+
Tail of the DSP chain, closest to the input, equivalent of the number of DSPs minus 1.
+
+

Before any DSPs have been added by the user, there is only one DSP available for a Channel or ChannelGroup. This is of type FMOD_DSP_TYPE_FADER. This handles volume and panning for a Channel or ChannelGroup.
+As only 1 DSP exists by default, initially CHANNELCONTROL_DSP_HEAD, CHANNELCONTROL_DSP_TAIL and CHANNELCONTROL_DSP_FADER all reference the same DSP.

+

See Also: ChannelControl::getDSP, ChannelControl::getNumDSPs, ChannelControl::setDSPIndex

+

ChannelControl::get3DAttributes

+

Retrieves the 3D position and velocity used to apply panning, attenuation and doppler.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
FMOD_RESULT ChannelControl::get3DAttributes(
+  FMOD_VECTOR *pos,
+  FMOD_VECTOR *vel
+);
+
+ +
FMOD_RESULT FMOD_Channel_Get3DAttributes(
+  FMOD_CHANNEL *channel,
+  FMOD_VECTOR *pos,
+  FMOD_VECTOR *vel
+);
+FMOD_RESULT FMOD_ChannelGroup_Get3DAttributes(
+  FMOD_CHANNELGROUP *channelgroup,
+  FMOD_VECTOR *pos,
+  FMOD_VECTOR *vel
+);
+
+ +
RESULT ChannelControl.get3DAttributes(
+  out VECTOR pos,
+  out VECTOR vel
+);
+
+ +
Channel.get3DAttributes(
+  pos,
+  vel
+);
+ChannelGroup.get3DAttributes(
+  pos,
+  vel
+);
+
+ +
+
pos OutOpt
+
+

Position in 3D space used for panning and attenuation. (FMOD_VECTOR)

+ +
+
vel OutOpt
+
+

Velocity in 3D space used for doppler. (FMOD_VECTOR)

+ +
+
+

See Also: ChannelControl::set3DAttributes

+

ChannelControl::get3DConeOrientation

+

Retrieves the orientation of a 3D cone shape, used for simulated occlusion.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
FMOD_RESULT ChannelControl::get3DConeOrientation(
+  FMOD_VECTOR *orientation
+);
+
+ +
FMOD_RESULT FMOD_Channel_Get3DConeOrientation(
+  FMOD_CHANNEL *channel,
+  FMOD_VECTOR *orientation
+);
+FMOD_RESULT FMOD_ChannelGroup_Get3DConeOrientation(
+  FMOD_CHANNELGROUP *channelgroup,
+  FMOD_VECTOR *orientation
+);
+
+ +
RESULT ChannelControl.get3DConeOrientation(
+  out VECTOR orientation
+);
+
+ +
Channel.get3DConeOrientation(
+  orientation
+);
+ChannelGroup.get3DConeOrientation(
+  orientation
+);
+
+ +
+
orientation Out
+
+

Normalized orientation vector, which represents the direction of the sound cone. (FMOD_VECTOR)

+
    +
  • Default: (0, 0, 1)
  • +
+
+
+

See Also: ChannelControl::set3DConeOrientation

+

ChannelControl::get3DConeSettings

+

Retrieves the angles and attenuation levels of a 3D cone shape, for simulated occlusion which is based on direction.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
FMOD_RESULT ChannelControl::get3DConeSettings(
+  float *insideconeangle,
+  float *outsideconeangle,
+  float *outsidevolume
+);
+
+ +
FMOD_RESULT FMOD_Channel_Get3DConeSettings(
+  FMOD_CHANNEL *channel,
+  float *insideconeangle,
+  float *outsideconeangle,
+  float *outsidevolume
+);
+FMOD_RESULT FMOD_ChannelGroup_Get3DConeSettings(
+  FMOD_CHANNELGROUP *channelgroup,
+  float *insideconeangle,
+  float *outsideconeangle,
+  float *outsidevolume
+);
+
+ +
RESULT ChannelControl.get3DConeSettings(
+  out float insideconeangle,
+  out float outsideconeangle,
+  out float outsidevolume
+);
+
+ +
Channel.get3DConeSettings(
+  insideconeangle,
+  outsideconeangle,
+  outsidevolume
+);
+ChannelGroup.get3DConeSettings(
+  insideconeangle,
+  outsideconeangle,
+  outsidevolume
+);
+
+ +
+
insideconeangle OutOpt
+
+

Inside cone angle. This is the angle spread within which the sound is unattenuated.

+
    +
  • Units: Degrees
  • +
  • Range: [0, 360]
  • +
  • Default: 360
  • +
+
+
outsideconeangle OutOpt
+
+

Outside cone angle. This is the angle spread outside of which the sound is attenuated to its outsidevolume.

+
    +
  • Units: Degrees
  • +
  • Range: [0, 360]
  • +
  • Default: 360
  • +
+
+
outsidevolume OutOpt
+
+

Cone outside volume.

+
    +
  • Units: Linear
  • +
  • Range: [0, 1]
  • +
  • Default: 1
  • +
+
+
+

When ChannelControl::set3DConeOrientation is used and a 3D 'cone' is set up, attenuation will automatically occur for a sound based on the relative angle of the direction the cone is facing, vs the angle between the sound and the listener.

+
    +
  • If the relative angle is within the insideconeangle, the sound will not have any attenuation applied.
  • +
  • If the relative angle is between the insideconeangle and outsideconeangle, linear volume attenuation (between 1 and outsidevolume) is applied between the two angles until it reaches the outsideconeangle.
  • +
  • If the relative angle is outside of the outsideconeangle the volume does not attenuate any further.
  • +
+

See Also: ChannelControl::set3DConeSettings

+

ChannelControl::get3DCustomRolloff

+

Retrieves the current custom roll-off shape for 3D distance attenuation.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
FMOD_RESULT ChannelControl::get3DCustomRolloff(
+  FMOD_VECTOR **points,
+  int *numpoints
+);
+
+ +
FMOD_RESULT FMOD_Channel_Get3DCustomRolloff(
+  FMOD_CHANNEL *channel,
+  FMOD_VECTOR **points,
+  int *numpoints
+);
+FMOD_RESULT FMOD_ChannelGroup_Get3DCustomRolloff(
+  FMOD_CHANNELGROUP *channelgroup,
+  FMOD_VECTOR **points,
+  int *numpoints
+);
+
+ +
RESULT ChannelControl.get3DCustomRolloff(
+  out IntPtr points,
+  out int numpoints
+);
+
+ +
Channel.get3DCustomRolloff(
+  points,
+  numpoints
+);
+ChannelGroup.get3DCustomRolloff(
+  points,
+  numpoints
+);
+
+ +
+
points OutOpt
+
+

Array of vectors sorted by distance, where x = distance and y = volume from 0 to 1. z is unused. (FMOD_VECTOR)

+ +
+
numpoints OutOpt
+
Number of entries in the points array.
+
+

See Also: ChannelControl::set3DCustomRolloff

+

ChannelControl::get3DDistanceFilter

+

Retrieves the override values for the 3D distance filter.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
FMOD_RESULT ChannelControl::get3DDistanceFilter(
+  bool *custom,
+  float *customLevel,
+  float *centerFreq
+);
+
+ +
FMOD_RESULT FMOD_Channel_Get3DDistanceFilter(
+  FMOD_CHANNEL *channel,
+  FMOD_BOOL *custom,
+  float *customLevel,
+  float *centerFreq
+);
+FMOD_RESULT FMOD_ChannelGroup_Get3DDistanceFilter(
+  FMOD_CHANNELGROUP *channelgroup,
+  FMOD_BOOL *custom,
+  float *customLevel,
+  float *centerFreq
+);
+
+ +
RESULT ChannelControl.get3DDistanceFilter(
+  out bool custom,
+  out float customLevel,
+  out float centerFreq
+);
+
+ +
Channel.get3DDistanceFilter(
+  custom,
+  customLevel,
+  centerFreq
+);
+ChannelGroup.get3DDistanceFilter(
+  custom,
+  customLevel,
+  centerFreq
+);
+
+ +
+
custom OutOpt
+
+

Override automatic distance filtering and use customLevel instead.

+
    +
  • Units: Boolean
  • +
  • Default: False
  • +
+
+
customLevel OutOpt
+
+

Attenuation factor where 1 represents no attenuation and 0 represents complete attenuation.

+
    +
  • Range: [0, 1]
  • +
  • Default: 1
  • +
+
+
centerFreq OutOpt
+
+

Center frequency of the band-pass filter used to simulate distance attenuation, 0 for default of FMOD_ADVANCEDSETTINGS::distanceFilterCenterFreq.

+ +
+
+

See Also: ChannelControl::set3DDistanceFilter

+

ChannelControl::get3DDopplerLevel

+

Retrieves the amount by which doppler is scaled.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
FMOD_RESULT ChannelControl::get3DDopplerLevel(
+  float *level
+);
+
+ +
FMOD_RESULT FMOD_Channel_Get3DDopplerLevel(
+  FMOD_CHANNEL *channel,
+  float *level
+);
+FMOD_RESULT FMOD_ChannelGroup_Get3DDopplerLevel(
+  FMOD_CHANNELGROUP *channelgroup,
+  float *level
+);
+
+ +
RESULT ChannelControl.get3DDopplerLevel(
+  out float level
+);
+
+ +
Channel.get3DDopplerLevel(
+  level
+);
+ChannelGroup.get3DDopplerLevel(
+  level
+);
+
+ +
+
level Out
+
+

Doppler scale where 0 represents no doppler, 1 represents natural doppler and 5 represents exaggerated doppler.

+
    +
  • Range: [0, 5]
  • +
  • Default: 1
  • +
+
+
+

See Also: ChannelControl::set3DDopplerLevel

+

ChannelControl::get3DLevel

+

Retrieves the blend between 3D panning and 2D panning.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
FMOD_RESULT ChannelControl::get3DLevel(
+  float *level
+);
+
+ +
FMOD_RESULT FMOD_Channel_Get3DLevel(
+  FMOD_CHANNEL *channel,
+  float *level
+);
+FMOD_RESULT FMOD_ChannelGroup_Get3DLevel(
+  FMOD_CHANNELGROUP *channelgroup,
+  float *level
+);
+
+ +
RESULT ChannelControl.get3DLevel(
+  out float level
+);
+
+ +
Channel.get3DLevel(
+  level
+);
+ChannelGroup.get3DLevel(
+  level
+);
+
+ +
+
level Out
+
+

3D pan level where 0 represents panning/attenuating solely with 2D panning functions and 1 represents solely 3D.

+
    +
  • Units: Linear
  • +
  • Range: [0, 1]
  • +
  • Default: 1
  • +
+
+
+

The FMOD_3D flag must be set on this object otherwise FMOD_ERR_NEEDS3D is returned.

+

2D functions include:

+ +

3D functions include:

+ +

See Also: ChannelControl::set3DLevel

+

ChannelControl::get3DMinMaxDistance

+

Retrieves the minimum and maximum distances used to calculate the 3D roll-off attenuation.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
FMOD_RESULT ChannelControl::get3DMinMaxDistance(
+  float *mindistance,
+  float *maxdistance
+);
+
+ +
FMOD_RESULT FMOD_Channel_Get3DMinMaxDistance(
+  FMOD_CHANNEL *channel,
+  float *mindistance,
+  float *maxdistance
+);
+FMOD_RESULT FMOD_ChannelGroup_Get3DMinMaxDistance(
+  FMOD_CHANNELGROUP *channelgroup,
+  float *mindistance,
+  float *maxdistance
+);
+
+ +
RESULT ChannelControl.get3DMinMaxDistance(
+  out float mindistance,
+  out float maxdistance
+);
+
+ +
Channel.get3DMinMaxDistance(
+  mindistance,
+  maxdistance
+);
+ChannelGroup.get3DMinMaxDistance(
+  mindistance,
+  maxdistance
+);
+
+ +
+
mindistance OutOpt
+
+

Distance from the source where attenuation begins.

+ +
+
maxdistance OutOpt
+
+

Distance from the source where attenuation ends.

+ +
+
+

See Also: ChannelControl::set3DMinMaxDistance, System::set3DSettings

+

ChannelControl::get3DOcclusion

+

Retrieves the 3D attenuation factors for the direct and reverb paths.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
FMOD_RESULT ChannelControl::get3DOcclusion(
+  float *directocclusion,
+  float *reverbocclusion
+);
+
+ +
FMOD_RESULT FMOD_Channel_Get3DOcclusion(
+  FMOD_CHANNEL *channel,
+  float *directocclusion,
+  float *reverbocclusion
+);
+FMOD_RESULT FMOD_ChannelGroup_Get3DOcclusion(
+  FMOD_CHANNELGROUP *channelgroup,
+  float *directocclusion,
+  float *reverbocclusion
+);
+
+ +
RESULT ChannelControl.get3DOcclusion(
+  out float directocclusion,
+  out float reverbocclusion
+);
+
+ +
Channel.get3DOcclusion(
+  directocclusion,
+  reverbocclusion
+);
+ChannelGroup.get3DOcclusion(
+  directocclusion,
+  reverbocclusion
+);
+
+ +
+
directocclusion OutOpt
+
+

Occlusion factor for the direct path where 0 represents no occlusion and 1 represents full occlusion.

+
    +
  • Range: [0, 1]
  • +
  • Default: 0
  • +
+
+
reverbocclusion OutOpt
+
+

Occlusion factor for the reverb path where 0 represents no occlusion and 1 represents full occlusion.

+
    +
  • Range: [0, 1]
  • +
  • Default: 0
  • +
+
+
+

See Also: ChannelControl::set3DOcclusion

+

ChannelControl::get3DSpread

+

Retrieves the spread of a 3D sound in speaker space.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
FMOD_RESULT ChannelControl::get3DSpread(
+  float *angle
+);
+
+ +
FMOD_RESULT FMOD_Channel_Get3DSpread(
+  FMOD_CHANNEL *channel,
+  float *angle
+);
+FMOD_RESULT FMOD_ChannelGroup_Get3DSpread(
+  FMOD_CHANNELGROUP *channelgroup,
+  float *angle
+);
+
+ +
RESULT ChannelControl.get3DSpread(
+  out float angle
+);
+
+ +
Channel.get3DSpread(
+  angle
+);
+ChannelGroup.get3DSpread(
+  angle
+);
+
+ +
+
angle Out
+
+

Angle over which the sound is spread.

+
    +
  • Units: Degrees
  • +
  • Range: [0, 360]
  • +
  • Default: 0
  • +
+
+
+

See Also: ChannelControl::set3DSpread

+

ChannelControl::getAudibility

+

Gets the calculated audibility based on all attenuation factors which contribute to the final output volume.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
FMOD_RESULT ChannelControl::getAudibility(
+  float *audibility
+);
+
+ +
FMOD_RESULT FMOD_Channel_GetAudibility(
+  FMOD_CHANNEL *channel,
+  float *audibility
+);
+FMOD_RESULT FMOD_ChannelGroup_GetAudibility(
+  FMOD_CHANNELGROUP *channelgroup,
+  float *audibility
+);
+
+ +
RESULT ChannelControl.getAudibility(
+  out float audibility
+);
+
+ +
Channel.getAudibility(
+  audibility
+);
+ChannelGroup.getAudibility(
+  audibility
+);
+
+ +
+
audibility Out
+
Estimated audibility.
+
+

The estimated volume is calculated using a number of factors detailed in the Audibility Calculation section of the Core API Managing Resources chapter.

+

While this does not represent the actual waveform, Channels playing FSB files will take into consideration the overall peak level of the file (if available).

+

This value is used to determine which Channels should be audible and which Channels to virtualize when resources are limited.

+

See the Virtual Voice System section of the Managing Resources in the Core API chapter for more details about how audibility is calculated.

+

See Also: Channel::isVirtual, ChannelControl::getVolume, ChannelControl::get3DOcclusion, ChannelControl::get3DAttributes, FMOD_DSP_PARAMETER_OVERALLGAIN

+

ChannelControl::getDelay

+

Retrieves a sample accurate start (and/or stop) time relative to the parent ChannelGroup DSP clock.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
FMOD_RESULT ChannelControl::getDelay(
+  unsigned long long *dspclock_start,
+  unsigned long long *dspclock_end,
+  bool *stopchannels = nullptr
+);
+
+ +
FMOD_RESULT FMOD_Channel_GetDelay(
+  FMOD_CHANNEL *channel,
+  unsigned long long *dspclock_start,
+  unsigned long long *dspclock_end,
+  FMOD_BOOL *stopchannels
+);
+FMOD_RESULT FMOD_ChannelGroup_GetDelay(
+  FMOD_CHANNELGROUP *channelgroup,
+  unsigned long long *dspclock_start,
+  unsigned long long *dspclock_end,
+  FMOD_BOOL *stopchannels
+);
+
+ +
RESULT ChannelControl.getDelay(
+  out ulong dspclock_start,
+  out ulong dspclock_end
+);
+RESULT ChannelControl.getDelay(
+  out ulong dspclock_start,
+  out ulong dspclock_end,
+  out bool stopchannels
+);
+
+ +
Channel.getDelay(
+  dspclock_start,
+  dspclock_end,
+  stopchannels
+);
+ChannelGroup.getDelay(
+  dspclock_start,
+  dspclock_end,
+  stopchannels
+);
+
+ +
+
dspclock_start OutOpt
+
+

DSP clock of the parent ChannelGroup to audibly start playing sound at.

+
    +
  • Units: Samples
  • +
  • Default: 0
  • +
+
+
dspclock_end OutOpt
+
+

DSP clock of the parent ChannelGroup to audibly stop playing sound at.

+
    +
  • Units: Samples
  • +
  • Default: 0
  • +
+
+
stopchannels OutOpt
+
+

True: When dspclock_end is reached, behaves like ChannelControl::stop has been called.
+False: When dspclock_end is reached, behaves like ChannelControl::setPaused has been called, a subsequent dspclock_start allows it to resume.

+
    +
  • Units: Boolean
  • +
+
+
+

See Also: ChannelControl::setDelay,ChannelControl::getDSPClock

+

ChannelControl::getDSP

+

Retrieves the DSP unit at the specified index in the DSP chain.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
FMOD_RESULT ChannelControl::getDSP(
+  int index,
+  DSP **dsp
+);
+
+ +
FMOD_RESULT FMOD_Channel_GetDSP(
+  FMOD_CHANNEL *channel,
+  int index,
+  FMOD_DSP **dsp
+);
+FMOD_RESULT FMOD_ChannelGroup_GetDSP(
+  FMOD_CHANNELGROUP *channelgroup,
+  int index,
+  FMOD_DSP **dsp
+);
+
+ +
RESULT ChannelControl.getDSP(
+  int index,
+  out DSP dsp
+);
+
+ +
Channel.getDSP(
+  index,
+  dsp
+);
+ChannelGroup.getDSP(
+  index,
+  dsp
+);
+
+ +
+
index
+
+

Offset into the DSP chain, see FMOD_CHANNELCONTROL_DSP_INDEX for special named offsets for 'head' and 'tail' and 'fader' units.

+ +
+
dsp Out
+
DSP unit at the specified index. (DSP)
+
+

ChannelControl::getDSPClock

+

Retrieves the DSP clock values at this point in time.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
FMOD_RESULT ChannelControl::getDSPClock(
+  unsigned long long *dspclock,
+  unsigned long long *parentclock
+);
+
+ +
FMOD_RESULT FMOD_Channel_GetDSPClock(
+  FMOD_CHANNEL *channel,
+  unsigned long long *dspclock,
+  unsigned long long *parentclock
+);
+FMOD_RESULT FMOD_ChannelGroup_GetDSPClock(
+  FMOD_CHANNELGROUP *channelgroup,
+  unsigned long long *dspclock,
+  unsigned long long *parentclock
+);
+
+ +
RESULT ChannelControl.getDSPClock(
+  out ulong dspclock,
+  out ulong parentclock
+);
+
+ +
Channel.getDSPClock(
+  dspclock,
+  parentclock
+);
+ChannelGroup.getDSPClock(
+  dspclock,
+  parentclock
+);
+
+ +
+
dspclock OutOpt
+
+

DSP clock value for the tail DSP (FMOD_CHANNELCONTROL_DSP_TAIL) node.

+
    +
  • Units: Samples
  • +
+
+
parentclock OutOpt
+
+

DSP clock value for the tail DSP (FMOD_CHANNELCONTROL_DSP_TAIL) node of the parent ChannelGroup.

+
    +
  • Units: Samples
  • +
+
+
+

To perform sample accurate scheduling in conjunction with ChannelControl::setDelay and ChannelControl::addFadePoint query the parentclock value.

+

See Also: ChannelControl::getDelay

+

ChannelControl::getDSPIndex

+

Retrieves the index of a DSP inside the Channel or ChannelGroup's DSP chain.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
FMOD_RESULT ChannelControl::getDSPIndex(
+  DSP *dsp,
+  int *index
+);
+
+ +
FMOD_RESULT FMOD_Channel_GetDSPIndex(
+  FMOD_CHANNEL *channel,
+  FMOD_DSP *dsp,
+  int *index
+);
+FMOD_RESULT FMOD_ChannelGroup_GetDSPIndex(
+  FMOD_CHANNELGROUP *channelgroup,
+  FMOD_DSP *dsp,
+  int *index
+);
+
+ +
RESULT ChannelControl.getDSPIndex(
+  DSP dsp,
+  out int index
+);
+
+ +
Channel.getDSPIndex(
+  dsp,
+  index
+);
+ChannelGroup.getDSPIndex(
+  dsp,
+  index
+);
+
+ +
+
dsp
+
DSP unit that exists in the DSP chain. (DSP)
+
index Out
+
Offset into the DSP chain.
+
+

See Also: ChannelControl::setDSPIndex

+

ChannelControl::getFadePoints

+

Retrieves information about stored fade points.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
FMOD_RESULT ChannelControl::getFadePoints(
+  unsigned int *numpoints,
+  unsigned long long *point_dspclock,
+  float *point_volume
+);
+
+ +
FMOD_RESULT FMOD_Channel_GetFadePoints(
+  FMOD_CHANNEL *channel,
+  unsigned int *numpoints,
+  unsigned long long *point_dspclock,
+  float *point_volume
+);
+FMOD_RESULT FMOD_ChannelGroup_GetFadePoints(
+  FMOD_CHANNELGROUP *channelgroup,
+  unsigned int *numpoints,
+  unsigned long long *point_dspclock,
+  float *point_volume
+);
+
+ +
RESULT ChannelControl.getFadePoints(
+  ref uint numpoints,
+  ulong[] point_dspclock,
+  float[] point_volume
+);
+
+ +
Channel.getFadePoints(
+  numpoints,
+  point_dspclock,
+  point_volume
+);
+ChannelGroup.getFadePoints(
+  numpoints,
+  point_dspclock,
+  point_volume
+);
+
+ +
+
numpoints Out
+
Number of fade points.
+
point_dspclock OutOpt
+
+

Array of DSP clock values that represent the fade point times.

+
    +
  • Units: Samples
  • +
+
+
point_volume OutOpt
+
+

Array of volume levels that represent the fade point values.

+
    +
  • Units: Linear
  • +
  • Range: [0, inf)
  • +
+
+
+

Passing NULL for point_dspclock and point_volume will allow you to query the number of fade points stored, with result stored in numpoints.
+If numpoints is specified by the user, the value will be used as an input for the maximum number of fade points to output. It will then output as the number of fadepoints retrieved.

+

See Also: ChannelControl::addFadePoint, ChannelControl::setFadePointRamp, ChannelControl::removeFadePoints

+

ChannelControl::getLowPassGain

+

Retrieves the gain of the dry signal when built in lowpass / distance filtering is applied.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
FMOD_RESULT ChannelControl::getLowPassGain(
+  float *gain
+);
+
+ +
FMOD_RESULT FMOD_Channel_GetLowPassGain(
+  FMOD_CHANNEL *channel,
+  float *gain
+);
+FMOD_RESULT FMOD_ChannelGroup_GetLowPassGain(
+  FMOD_CHANNELGROUP *channelgroup,
+  float *gain
+);
+
+ +
RESULT ChannelControl.getLowPassGain(
+  out float gain
+);
+
+ +
Channel.getLowPassGain(
+  gain
+);
+ChannelGroup.getLowPassGain(
+  gain
+);
+
+ +
+
gain Out
+
+

gain level where 0 represents silent (full filtering) and 1 represents full volume (no filtering).

+
    +
  • Units: Linear
  • +
  • Range: [0, 1]
  • +
  • Default: 1
  • +
+
+
+

Requires the built in lowpass to be created with FMOD_INIT_CHANNEL_LOWPASS or FMOD_INIT_CHANNEL_DISTANCEFILTER.

+
+

Currently only supported for Channel, not ChannelGroup.

+
+

See Also: ChannelControl::setLowPassGain

+

ChannelControl::getMixMatrix

+

Retrieves a 2 dimensional pan matrix that maps the signal from input channels (columns) to output speakers (rows).

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
FMOD_RESULT ChannelControl::getMixMatrix(
+  float *matrix,
+  int *outchannels,
+  int *inchannels,
+  int inchannel_hop = 0
+);
+
+ +
FMOD_RESULT FMOD_Channel_GetMixMatrix(
+  FMOD_CHANNEL *channel,
+  float *matrix,
+  int *outchannels,
+  int *inchannels,
+  int inchannel_hop
+);
+FMOD_RESULT FMOD_ChannelGroup_GetMixMatrix(
+  FMOD_CHANNELGROUP *channelgroup,
+  float *matrix,
+  int *outchannels,
+  int *inchannels,
+  int inchannel_hop
+);
+
+ +
RESULT ChannelControl.getMixMatrix(
+  float[] matrix,
+  out int outchannels,
+  out int inchannels,
+  int inchannel_hop = 0
+);
+
+ +
Channel.getMixMatrix(
+  matrix,
+  outchannels,
+  inchannels,
+  inchannel_hop
+);
+ChannelGroup.getMixMatrix(
+  matrix,
+  outchannels,
+  inchannels,
+  inchannel_hop
+);
+
+ +
+
matrix OutOpt
+
+

Two dimensional array of volume levels in row-major order. Each row represents an output speaker, each column represents an input channel.

+
    +
  • Units: Linear
  • +
  • Range: (-inf, inf)
  • +
+
+
outchannels OutOpt
+
Number of valid output channels (rows) in matrix.
+
+ +
+
inchannels OutOpt
+
Number of valid input channels (columns) in matrix.
+
+ +
+
inchannel_hop OutOpt
+
Width (total number of columns) in destination matrix. A matrix element is referenced as 'outchannel * inchannel_hop + inchannel'.
+
+

Passing NULL for matrix will allow you to query outchannels and inchannels otherwise they are not optional.

+

Matrix element values can be below 0 to invert a signal and above 1 to amplify the signal. Note that increasing the signal level too far may cause audible distortion.

+

See Also: ChannelControl::setMixMatrix

+

ChannelControl::getMode

+

Retrieves the playback mode bits that control how this object behaves.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
FMOD_RESULT ChannelControl::getMode(
+  FMOD_MODE *mode
+);
+
+ +
FMOD_RESULT FMOD_Channel_GetMode(
+  FMOD_CHANNEL *channel,
+  FMOD_MODE *mode
+);
+FMOD_RESULT FMOD_ChannelGroup_GetMode(
+  FMOD_CHANNELGROUP *channelgroup,
+  FMOD_MODE *mode
+);
+
+ +
RESULT ChannelControl.getMode(
+  out MODE mode
+);
+
+ +
Channel.getMode(
+  mode
+);
+ChannelGroup.getMode(
+  mode
+);
+
+ +
+
mode Out
+
Playback mode bitfield. Test against a specific mode with the AND operator. (FMOD_MODE)
+
+

See Also: ChannelControl::setMode

+

ChannelControl::getMute

+

Retrieves the mute state.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
FMOD_RESULT ChannelControl::getMute(
+  bool *mute
+);
+
+ +
FMOD_RESULT FMOD_Channel_GetMute(
+  FMOD_CHANNEL *channel,
+  FMOD_BOOL *mute
+);
+FMOD_RESULT FMOD_ChannelGroup_GetMute(
+  FMOD_CHANNELGROUP *channelgroup,
+  FMOD_BOOL *mute
+);
+
+ +
RESULT ChannelControl.getMute(
+  out bool mute
+);
+
+ +
Channel.getMute(
+  mute
+);
+ChannelGroup.getMute(
+  mute
+);
+
+ +
+
mute Out
+
+

Mute state. True = silent. False = audible.

+
    +
  • Units: Boolean
  • +
+
+
+

An individual mute state is kept for each object, a parent ChannelGroup being muted will effectively mute this object however when queried the individual mute state is returned. ChannelControl::getAudibility can be used to calculate overall audibility for a Channel or ChannelGroup.

+

See Also: ChannelControl::setMute

+

ChannelControl::getNumDSPs

+

Retrieves the number of DSP units in the DSP chain.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
FMOD_RESULT ChannelControl::getNumDSPs(
+  int *numdsps
+);
+
+ +
FMOD_RESULT FMOD_Channel_GetNumDSPs(
+  FMOD_CHANNEL *channel,
+  int *numdsps
+);
+FMOD_RESULT FMOD_ChannelGroup_GetNumDSPs(
+  FMOD_CHANNELGROUP *channelgroup,
+  int *numdsps
+);
+
+ +
RESULT ChannelControl.getNumDSPs(
+  out int numdsps
+);
+
+ +
Channel.getNumDSPs(
+  numdsps
+);
+ChannelGroup.getNumDSPs(
+  numdsps
+);
+
+ +
+
numdsps Out
+
Number of DSP units in the DSP chain.
+
+

See Also: ChannelControl::addDSP, ChannelControl::removeDSP, ChannelControl::getDSP

+

ChannelControl::getPaused

+

Retrieves the paused state.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
FMOD_RESULT ChannelControl::getPaused(
+  bool *paused
+);
+
+ +
FMOD_RESULT FMOD_Channel_GetPaused(
+  FMOD_CHANNEL *channel,
+  FMOD_BOOL *paused
+);
+FMOD_RESULT FMOD_ChannelGroup_GetPaused(
+  FMOD_CHANNELGROUP *channelgroup,
+  FMOD_BOOL *paused
+);
+
+ +
RESULT ChannelControl.getPaused(
+  out bool paused
+);
+
+ +
Channel.getPaused(
+  paused
+);
+ChannelGroup.getPaused(
+  paused
+);
+
+ +
+
paused Out
+
+

Paused state. True = playback halted. False = playback active.

+
    +
  • Units: Boolean
  • +
+
+
+

An individual pause state is kept for each object, a parent ChannelGroup being paused will effectively pause this object however when queried the individual pause state is returned.

+

See Also: ChannelControl::setPaused

+

ChannelControl::getPitch

+

Retrieves the relative pitch / playback rate.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
FMOD_RESULT ChannelControl::getPitch(
+  float *pitch
+);
+
+ +
FMOD_RESULT FMOD_Channel_GetPitch(
+  FMOD_CHANNEL *channel,
+  float *pitch
+);
+FMOD_RESULT FMOD_ChannelGroup_GetPitch(
+  FMOD_CHANNELGROUP *channelgroup,
+  float *pitch
+);
+
+ +
RESULT ChannelControl.getPitch(
+  out float pitch
+);
+
+ +
Channel.getPitch(
+  pitch
+);
+ChannelGroup.getPitch(
+  pitch
+);
+
+ +
+
pitch Out
+
Pitch value where 0.5 represents half pitch (one octave down), 1 represents unmodified pitch and 2 represents double pitch (one octave up).
+
+

An individual pitch value is kept for each object, a parent ChannelGroup pitch will effectively scale the pitch of this object however when queried the individual pitch value is returned.

+

See Also: ChannelControl::setPitch

+

ChannelControl::getReverbProperties

+

Retrieves the wet / send level for a particular reverb instance.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
FMOD_RESULT ChannelControl::getReverbProperties(
+  int instance,
+  float *wet
+);
+
+ +
FMOD_RESULT FMOD_Channel_GetReverbProperties(
+  FMOD_CHANNEL *channel,
+  int instance,
+  float *wet
+);
+FMOD_RESULT FMOD_ChannelGroup_GetReverbProperties(
+  FMOD_CHANNELGROUP *channelgroup,
+  int instance,
+  float *wet
+);
+
+ +
RESULT ChannelControl.getReverbProperties(
+  int instance,
+  out float wet
+);
+
+ +
Channel.getReverbProperties(
+  instance,
+  wet
+);
+ChannelGroup.getReverbProperties(
+  instance,
+  wet
+);
+
+ +
+
instance
+
+

Reverb instance index.

+ +
+
wet Out
+
+

Send level for the signal to the reverb. 0 = none, 1 = full.

+ +
+
+

See Also: ChannelControl::setReverbProperties

+

ChannelControl::getSystemObject

+

Retrieves the System that created this object.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
FMOD_RESULT ChannelControl::getSystemObject(
+  System **system
+);
+
+ +
FMOD_RESULT FMOD_Channel_GetSystemObject(
+  FMOD_CHANNEL *channel,
+  FMOD_SYSTEM **system
+);
+FMOD_RESULT FMOD_ChannelGroup_GetSystemObject(
+  FMOD_CHANNELGROUP *channelgroup,
+  FMOD_SYSTEM **system
+);
+
+ +
RESULT ChannelControl.getSystemObject(
+  out System system
+);
+
+ +
Channel.getSystemObject(
+  system
+);
+ChannelGroup.getSystemObject(
+  system
+);
+
+ +
+
system Out
+
System object. (System)
+
+

See Also: System::createChannelGroup, System::getMasterChannelGroup, System::playSound

+

ChannelControl::getUserData

+

Retrieves a user value associated with this object.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
FMOD_RESULT ChannelControl::getUserData(
+  void **userdata
+);
+
+ +
FMOD_RESULT FMOD_Channel_GetUserData(
+  FMOD_CHANNEL *channel,
+  void **userdata
+);
+FMOD_RESULT FMOD_ChannelGroup_GetUserData(
+  FMOD_CHANNELGROUP *channelgroup,
+  void **userdata
+);
+
+ +
RESULT ChannelControl.getUserData(
+  out IntPtr userdata
+);
+
+ +
Channel.getUserData(
+  userdata
+);
+ChannelGroup.getUserData(
+  userdata
+);
+
+ +
+
userdata Out
+
User data set by calling ChannelControl::setUserData.
+
+

This function allows arbitrary user data to be retrieved from this object. See the User Data section of the glossary for an example of how to get and set user data.

+

ChannelControl::getVolume

+

Retrieves the volume level.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
FMOD_RESULT ChannelControl::getVolume(
+  float *volume
+);
+
+ +
FMOD_RESULT FMOD_Channel_GetVolume(
+  FMOD_CHANNEL *channel,
+  float *volume
+);
+FMOD_RESULT FMOD_ChannelGroup_GetVolume(
+  FMOD_CHANNELGROUP *channelgroup,
+  float *volume
+);
+
+ +
RESULT ChannelControl.getVolume(
+  out float volume
+);
+
+ +
Channel.getVolume(
+  volume
+);
+ChannelGroup.getVolume(
+  volume
+);
+
+ +
+
volume Out
+
+

Volume level.

+
    +
  • Units: Linear
  • +
  • Range: (-inf, inf)
  • +
  • Default: 1
  • +
+
+
+

See Also: ChannelControl::setVolume

+

ChannelControl::getVolumeRamp

+

Retrieves whether volume changes are ramped or instantaneous.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
FMOD_RESULT ChannelControl::getVolumeRamp(
+  bool *ramp
+);
+
+ +
FMOD_RESULT FMOD_Channel_GetVolumeRamp(
+  FMOD_CHANNEL *channel,
+  FMOD_BOOL *ramp
+);
+FMOD_RESULT FMOD_ChannelGroup_GetVolumeRamp(
+  FMOD_CHANNELGROUP *channelgroup,
+  FMOD_BOOL *ramp
+);
+
+ +
RESULT ChannelControl.getVolumeRamp(
+  out bool ramp
+);
+
+ +
Channel.getVolumeRamp(
+  ramp
+);
+ChannelGroup.getVolumeRamp(
+  ramp
+);
+
+ +
+
ramp Out
+
+

Ramp state. True = volume change is ramped. False = volume change is instantaeous.

+
    +
  • Units: Boolean
  • +
  • Default: True
  • +
+
+
+

See Also: ChannelControl::setVolumeRamp

+

ChannelControl::isPlaying

+

Retrieves the playing state.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
FMOD_RESULT ChannelControl::isPlaying(
+  bool *isplaying
+);
+
+ +
FMOD_RESULT FMOD_Channel_IsPlaying(
+  FMOD_CHANNEL *channel,
+  FMOD_BOOL *isplaying
+);
+FMOD_RESULT FMOD_ChannelGroup_IsPlaying(
+  FMOD_CHANNELGROUP *channelgroup,
+  FMOD_BOOL *isplaying
+);
+
+ +
RESULT ChannelControl.isPlaying(
+  out bool isplaying
+);
+
+ +
Channel.isPlaying(
+  isplaying
+);
+ChannelGroup.isPlaying(
+  isplaying
+);
+
+ +
+
isplaying Out
+
+

Playing state.

+
    +
  • Units: Boolean
  • +
+
+
+

A Channel is considered playing after System::playSound or System::playDSP, even if it is paused.

+

A ChannelGroup is considered playing if it has any playing Channels.

+

ChannelControl::removeDSP

+

Removes the specified DSP unit from the DSP chain.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
FMOD_RESULT ChannelControl::removeDSP(
+  DSP *dsp
+);
+
+ +
FMOD_RESULT FMOD_Channel_RemoveDSP(
+  FMOD_CHANNEL *channel,
+  FMOD_DSP *dsp
+);
+FMOD_RESULT FMOD_ChannelGroup_RemoveDSP(
+  FMOD_CHANNELGROUP *channelgroup,
+  FMOD_DSP *dsp
+);
+
+ +
RESULT ChannelControl.removeDSP(
+  DSP dsp
+);
+
+ +
Channel.removeDSP(
+  dsp
+);
+ChannelGroup.removeDSP(
+  dsp
+);
+
+ +
+
dsp
+
DSP unit to be removed. (DSP)
+
+

See Also: ChannelControl::addDSP, ChannelControl::getDSP, ChannelControl::getNumDSPs

+

ChannelControl::removeFadePoints

+

Removes all fade points between the two specified clock values (inclusive).

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
FMOD_RESULT ChannelControl::removeFadePoints(
+  unsigned long long dspclock_start,
+  unsigned long long dspclock_end
+);
+
+ +
FMOD_RESULT FMOD_Channel_RemoveFadePoints(
+  FMOD_CHANNEL *channel,
+  unsigned long long dspclock_start,
+  unsigned long long dspclock_end
+);
+FMOD_RESULT FMOD_ChannelGroup_RemoveFadePoints(
+  FMOD_CHANNELGROUP *channelgroup,
+  unsigned long long dspclock_start,
+  unsigned long long dspclock_end
+);
+
+ +
RESULT ChannelControl.removeFadePoints(
+  ulong dspclock_start,
+  ulong dspclock_end
+);
+
+ +
Channel.removeFadePoints(
+  dspclock_start,
+  dspclock_end
+);
+ChannelGroup.removeFadePoints(
+  dspclock_start,
+  dspclock_end
+);
+
+ +
+
dspclock_start
+
+

DSP clock of the parent ChannelGroup at which to begin removing fade points.

+
    +
  • Units: Samples
  • +
+
+
dspclock_end
+
+

DSP clock of the parent ChannelGroup at which to stop removing fade points.

+
    +
  • Units: Samples
  • +
+
+
+

See Also: ChannelControl::addFadePoint, ChannelControl::setFadePointRamp, ChannelControl::getFadePoints

+

ChannelControl::set3DAttributes

+

Sets the 3D position and velocity used to apply panning, attenuation and doppler.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
FMOD_RESULT ChannelControl::set3DAttributes(
+  const FMOD_VECTOR *pos,
+  const FMOD_VECTOR *vel
+);
+
+ +
FMOD_RESULT FMOD_Channel_Set3DAttributes(
+  FMOD_CHANNEL *channel,
+  const FMOD_VECTOR *pos,
+  const FMOD_VECTOR *vel
+);
+FMOD_RESULT FMOD_ChannelGroup_Set3DAttributes(
+  FMOD_CHANNELGROUP *channelgroup,
+  const FMOD_VECTOR *pos,
+  const FMOD_VECTOR *vel
+);
+
+ +
RESULT ChannelControl.set3DAttributes(
+  ref VECTOR pos,
+  ref VECTOR vel
+);
+RESULT ChannelControl.set3DAttributes(
+  ref VECTOR pos,
+  ref VECTOR vel
+);
+
+ +
Channel.set3DAttributes(
+  pos,
+  vel
+);
+ChannelGroup.set3DAttributes(
+  pos,
+  vel
+);
+
+ +
+
pos Opt
+
+

Position in 3D space used for panning and attenuation. (FMOD_VECTOR)

+ +
+
vel Opt
+
+

Velocity in 3D space used for doppler. (FMOD_VECTOR)

+ +
+
+

The FMOD_3D flag must be set on this object otherwise FMOD_ERR_NEEDS3D is returned.

+

Vectors must be provided in the correct handedness.

+

For a stereo 3D sound, you can set the spread of the left/right parts in speaker space by using ChannelControl::set3DSpread.

+

See Also: ChannelControl::get3DAttributes

+

ChannelControl::set3DConeOrientation

+

Sets the orientation of a 3D cone shape, used for simulated occlusion.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
FMOD_RESULT ChannelControl::set3DConeOrientation(
+  FMOD_VECTOR *orientation
+);
+
+ +
FMOD_RESULT FMOD_Channel_Set3DConeOrientation(
+  FMOD_CHANNEL *channel,
+  FMOD_VECTOR *orientation
+);
+FMOD_RESULT FMOD_ChannelGroup_Set3DConeOrientation(
+  FMOD_CHANNELGROUP *channelgroup,
+  FMOD_VECTOR *orientation
+);
+
+ +
RESULT ChannelControl.set3DConeOrientation(
+  ref VECTOR orientation
+);
+
+ +
Channel.set3DConeOrientation(
+  orientation
+);
+ChannelGroup.set3DConeOrientation(
+  orientation
+);
+
+ +
+
orientation
+
+

Normalized orientation vector, which represents the direction of the sound cone. (FMOD_VECTOR)

+
    +
  • Default: (0, 0, 1)
  • +
+
+
+

The FMOD_3D flag must be set on this object otherwise FMOD_ERR_NEEDS3D is returned.

+

This function has no effect unless ChannelControl::set3DConeSettings has been used to change the cone inside/outside angles from the default.

+

Vectors must be provided in the correct handedness.

+

See Also: ChannelControl::get3DConeOrientation

+

ChannelControl::set3DConeSettings

+

Sets the angles and attenuation levels of a 3D cone shape, for simulated occlusion which is based on direction.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
FMOD_RESULT ChannelControl::set3DConeSettings(
+  float insideconeangle,
+  float outsideconeangle,
+  float outsidevolume
+);
+
+ +
FMOD_RESULT FMOD_Channel_Set3DConeSettings(
+  FMOD_CHANNEL *channel,
+  float insideconeangle,
+  float outsideconeangle,
+  float outsidevolume
+);
+FMOD_RESULT FMOD_ChannelGroup_Set3DConeSettings(
+  FMOD_CHANNELGROUP *channelgroup,
+  float insideconeangle,
+  float outsideconeangle,
+  float outsidevolume
+);
+
+ +
RESULT ChannelControl.set3DConeSettings(
+  float insideconeangle,
+  float outsideconeangle,
+  float outsidevolume
+);
+
+ +
Channel.set3DConeSettings(
+  insideconeangle,
+  outsideconeangle,
+  outsidevolume
+);
+ChannelGroup.set3DConeSettings(
+  insideconeangle,
+  outsideconeangle,
+  outsidevolume
+);
+
+ +
+
insideconeangle
+
+

Inside cone angle. This is the angle spread within which the sound is unattenuated.

+
    +
  • Units: Degrees
  • +
  • Range: [0, outsideconeangle]
  • +
  • Default: 360
  • +
+
+
outsideconeangle
+
+

Outside cone angle. This is the angle spread outside of which the sound is attenuated to its outsidevolume.

+
    +
  • Units: Degrees
  • +
  • Range: [insideconeangle, 360]
  • +
  • Default: 360
  • +
+
+
outsidevolume
+
+

Cone outside volume.

+
    +
  • Units: Linear
  • +
  • Range: [0, 1]
  • +
  • Default: 1
  • +
+
+
+

The FMOD_3D flag must be set on this object otherwise FMOD_ERR_NEEDS3D is returned.

+

When ChannelControl::set3DConeOrientation is used and a 3D 'cone' is set up, attenuation will automatically occur for a sound based on the relative angle of the direction the cone is facing, vs the angle between the sound and the listener.

+
    +
  • If the relative angle is within the insideconeangle, the sound will not have any attenuation applied.
  • +
  • If the relative angle is between the insideconeangle and outsideconeangle, linear volume attenuation (between 1 and outsidevolume) is applied between the two angles until it reaches the outsideconeangle.
  • +
  • If the relative angle is outside of the outsideconeangle the volume does not attenuate any further.
  • +
+

See Also: ChannelControl::get3DConeSettings, Sound::set3DConeSettings

+

ChannelControl::set3DCustomRolloff

+

Sets a custom roll-off shape for 3D distance attenuation.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
FMOD_RESULT ChannelControl::set3DCustomRolloff(
+  FMOD_VECTOR *points,
+  int numpoints
+);
+
+ +
FMOD_RESULT FMOD_Channel_Set3DCustomRolloff(
+  FMOD_CHANNEL *channel,
+  FMOD_VECTOR *points,
+  int numpoints
+);
+FMOD_RESULT FMOD_ChannelGroup_Set3DCustomRolloff(
+  FMOD_CHANNELGROUP *channelgroup,
+  FMOD_VECTOR *points,
+  int numpoints
+);
+
+ +
RESULT ChannelControl.set3DCustomRolloff(
+  ref VECTOR points,
+  int numpoints
+);
+
+ +
Channel.set3DCustomRolloff(
+  points,
+  numpoints
+);
+ChannelGroup.set3DCustomRolloff(
+  points,
+  numpoints
+);
+
+ +
+
points
+
+

Array of vectors sorted by distance, where x = distance and y = volume from 0 to 1. z should be set to 0. Pass null or equivalen to disable custom rolloff. (FMOD_VECTOR)

+ +
+
numpoints
+
Number of points.
+
+

Must be used in conjunction with FMOD_3D_CUSTOMROLLOFF flag to be activated.

+

This function does not duplicate the memory for the points internally. The memory you pass to FMOD must remain valid while in use.

+

If FMOD_3D_CUSTOMROLLOFF is set and the roll-off shape is not set, FMOD will revert to FMOD_3D_INVERSEROLLOFF roll-off mode.

+

When a custom roll-off is specified a Channel or ChannelGroup's 3D 'minimum' and 'maximum' distances are ignored.

+

The distance in-between point values is linearly interpolated until the final point where the last value is held.

+

If the points are not sorted by distance, an error will result.

+
// Defining a custom array of points
+FMOD_VECTOR curve[3] =
+{
+    { 0.0f,  1.0f, 0.0f },
+    { 2.0f,  0.2f, 0.0f },
+    { 20.0f, 0.0f, 0.0f }
+};
+
+ +

See Also: Sound::set3DCustomRolloff, ChannelControl::get3DCustomRolloff

+

ChannelControl::set3DDistanceFilter

+

Sets an override value for the 3D distance filter.

+

If distance filtering is enabled, by default the 3D engine will automatically attenuate frequencies using a lowpass and a highpass filter, based on 3D distance.
+This function allows the distance filter effect to be set manually, or to be set back to 'automatic' mode.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
FMOD_RESULT ChannelControl::set3DDistanceFilter(
+  bool custom,
+  float customLevel,
+  float centerFreq
+);
+
+ +
FMOD_RESULT FMOD_Channel_Set3DDistanceFilter(
+  FMOD_CHANNEL *channel,
+  FMOD_BOOL custom,
+  float customLevel,
+  float centerFreq
+);
+FMOD_RESULT FMOD_ChannelGroup_Set3DDistanceFilter(
+  FMOD_CHANNELGROUP *channelgroup,
+  FMOD_BOOL custom,
+  float customLevel,
+  float centerFreq
+);
+
+ +
RESULT ChannelControl.set3DDistanceFilter(
+  bool custom,
+  float customLevel,
+  float centerFreq
+);
+
+ +
Channel.set3DDistanceFilter(
+  custom,
+  customLevel,
+  centerFreq
+);
+ChannelGroup.set3DDistanceFilter(
+  custom,
+  customLevel,
+  centerFreq
+);
+
+ +
+
custom
+
+

Override automatic distance filtering and use customLevel instead.

+
    +
  • Units: Boolean
  • +
  • Default: False
  • +
+
+
customLevel
+
+

Attenuation factor where 1 represents no attenuation and 0 represents complete attenuation.

+
    +
  • Range: [0, 1]
  • +
  • Default: 1
  • +
+
+
centerFreq Opt
+
+

Center frequency of the band-pass filter used to simulate distance attenuation, 0 for default.

+ +
+
+

The FMOD_3D flag must be set on this object otherwise FMOD_ERR_NEEDS3D is returned.

+

The System must be initialized with FMOD_INIT_CHANNEL_DISTANCEFILTER for this feature to work.

+
+

Currently only supported for Channel, not ChannelGroup.

+
+

See Also: ChannelControl::get3DDistanceFilter

+

ChannelControl::set3DDopplerLevel

+

Sets the amount by which doppler is scaled.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
FMOD_RESULT ChannelControl::set3DDopplerLevel(
+  float level
+);
+
+ +
FMOD_RESULT FMOD_Channel_Set3DDopplerLevel(
+  FMOD_CHANNEL *channel,
+  float level
+);
+FMOD_RESULT FMOD_ChannelGroup_Set3DDopplerLevel(
+  FMOD_CHANNELGROUP *channelgroup,
+  float level
+);
+
+ +
RESULT ChannelControl.set3DDopplerLevel(
+  float level
+);
+
+ +
Channel.set3DDopplerLevel(
+  level
+);
+ChannelGroup.set3DDopplerLevel(
+  level
+);
+
+ +
+
level
+
+

Doppler scale where 0 represents no doppler, 1 represents natural doppler and 5 represents exaggerated doppler.

+
    +
  • Range: [0, 5]
  • +
  • Default: 1
  • +
+
+
+

The FMOD_3D flag must be set on this object otherwise FMOD_ERR_NEEDS3D is returned.

+

The doppler effect will disabled if System::set3DNumListeners is given a value greater than 1.

+
+

Currently only supported for Channel, not ChannelGroup.

+
+

See Also: ChannelControl::get3DDopplerLevel, System::set3DSettings

+

ChannelControl::set3DLevel

+

Sets the blend between 3D panning and 2D panning.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
FMOD_RESULT ChannelControl::set3DLevel(
+  float level
+);
+
+ +
FMOD_RESULT FMOD_Channel_Set3DLevel(
+  FMOD_CHANNEL *channel,
+  float level
+);
+FMOD_RESULT FMOD_ChannelGroup_Set3DLevel(
+  FMOD_CHANNELGROUP *channelgroup,
+  float level
+);
+
+ +
RESULT ChannelControl.set3DLevel(
+  float level
+);
+
+ +
Channel.set3DLevel(
+  level
+);
+ChannelGroup.set3DLevel(
+  level
+);
+
+ +
+
level
+
+

3D pan level where 0 represents panning/attenuating solely with 2D panning functions and 1 represents solely 3D.

+
    +
  • Units: Linear
  • +
  • Range: [0, 1]
  • +
  • Default: 1
  • +
+
+
+

The FMOD_3D flag must be set on this object otherwise FMOD_ERR_NEEDS3D is returned.

+

2D functions include:

+ +

3D functions include:

+ +

See Also: ChannelControl::get3DLevel

+

ChannelControl::set3DMinMaxDistance

+

Sets the minimum and maximum distances used to calculate the 3D roll-off attenuation.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
FMOD_RESULT ChannelControl::set3DMinMaxDistance(
+  float mindistance,
+  float maxdistance
+);
+
+ +
FMOD_RESULT FMOD_Channel_Set3DMinMaxDistance(
+  FMOD_CHANNEL *channel,
+  float mindistance,
+  float maxdistance
+);
+FMOD_RESULT FMOD_ChannelGroup_Set3DMinMaxDistance(
+  FMOD_CHANNELGROUP *channelgroup,
+  float mindistance,
+  float maxdistance
+);
+
+ +
RESULT ChannelControl.set3DMinMaxDistance(
+  float mindistance,
+  float maxdistance
+);
+
+ +
Channel.set3DMinMaxDistance(
+  mindistance,
+  maxdistance
+);
+ChannelGroup.set3DMinMaxDistance(
+  mindistance,
+  maxdistance
+);
+
+ +
+
mindistance
+
+

Distance from the source where attenuation begins.

+ +
+
maxdistance
+
+

Distance from the source where attenuation ends.

+ +
+
+

When the listener is within the minimum distance of the sound source the 3D volume will be at its maximum. As the listener moves from the minimum distance to the maximum distance the sound will attenuate following the roll-off curve set. When outside the maximum distance the sound will no longer attenuate.

+

Attenuation in 3D space is controlled by the roll-off mode, these are FMOD_3D_INVERSEROLLOFF, FMOD_3D_LINEARROLLOFF, FMOD_3D_LINEARSQUAREROLLOFF, FMOD_3D_INVERSETAPEREDROLLOFF, FMOD_3D_CUSTOMROLLOFF.

+

Minimum distance is useful to give the impression that the sound is loud or soft in 3D space.
+A sound with a small 3D minimum distance in a typical (non custom) roll-off mode will make the sound appear small, and the sound will attenuate quickly.
+A sound with a large minimum distance will make the sound appear larger.

+

The FMOD_3D flag must be set on this object otherwise FMOD_ERR_NEEDS3D is returned.

+

To define the min and max distance per Sound instead of Channel or ChannelGroup use Sound::set3DMinMaxDistance.

+

If FMOD_3D_CUSTOMROLLOFF has been set on this object these values are stored, but ignored in 3D processing.

+

See Also: ChannelControl::get3DMinMaxDistance

+

ChannelControl::set3DOcclusion

+

Sets the 3D attenuation factors for the direct and reverb paths.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
FMOD_RESULT ChannelControl::set3DOcclusion(
+  float directocclusion,
+  float reverbocclusion
+);
+
+ +
FMOD_RESULT FMOD_Channel_Set3DOcclusion(
+  FMOD_CHANNEL *channel,
+  float directocclusion,
+  float reverbocclusion
+);
+FMOD_RESULT FMOD_ChannelGroup_Set3DOcclusion(
+  FMOD_CHANNELGROUP *channelgroup,
+  float directocclusion,
+  float reverbocclusion
+);
+
+ +
RESULT ChannelControl.set3DOcclusion(
+  float directocclusion,
+  float reverbocclusion
+);
+
+ +
Channel.set3DOcclusion(
+  directocclusion,
+  reverbocclusion
+);
+ChannelGroup.set3DOcclusion(
+  directocclusion,
+  reverbocclusion
+);
+
+ +
+
directocclusion
+
+

Occlusion factor for the direct path where 0 represents no occlusion and 1 represents full occlusion.

+
    +
  • Range: [0, 1]
  • +
  • Default: 0
  • +
+
+
reverbocclusion
+
+

Occlusion factor for the reverb path where 0 represents no occlusion and 1 represents full occlusion.

+
    +
  • Range: [0, 1]
  • +
  • Default: 0
  • +
+
+
+

There is a reverb path/send when ChannelControl::setReverbProperties has been used, reverbocclusion controls its attenuation.

+

If the System has been initialized with FMOD_INIT_CHANNEL_DISTANCEFILTER or FMOD_INIT_CHANNEL_LOWPASS the directocclusion is applied as frequency filtering rather than volume attenuation.

+

See Also: ChannelControl::get3DOcclusion

+

ChannelControl::set3DSpread

+

Sets the spread of a 3D sound in speaker space.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
FMOD_RESULT ChannelControl::set3DSpread(
+  float angle
+);
+
+ +
FMOD_RESULT FMOD_Channel_Set3DSpread(
+  FMOD_CHANNEL *channel,
+  float angle
+);
+FMOD_RESULT FMOD_ChannelGroup_Set3DSpread(
+  FMOD_CHANNELGROUP *channelgroup,
+  float angle
+);
+
+ +
RESULT ChannelControl.set3DSpread(
+  float angle
+);
+
+ +
Channel.set3DSpread(
+  angle
+);
+ChannelGroup.set3DSpread(
+  angle
+);
+
+ +
+
angle
+
+

Angle over which the sound is spread.

+
    +
  • Units: Degrees
  • +
  • Range: [0, 360]
  • +
  • Default: 0
  • +
+
+
+

When the spread angle is 0 (default) a multi-channel signal will collapse to mono and be spatialized to a single point based on ChannelControl::set3DAttributes calculations. As the angle is increased, each channel within a multi-channel signal will be rotated away from that point. For 2, 4, 6, 8, and 12 channel signals, the spread is arranged from leftmost speaker to rightmost speaker intelligently, for example in 5.1 the leftmost speaker is rear left, followed by front left, center, front right then finally rear right as the rightmost speaker (LFE is not spread). For other channel counts the individual channels are spread evenly in the order of the signal. As the signal is spread the power will be preserved.

+

For a stereo signal given different spread angles:

+
    +
  • 0: Sound is collapsed to mono and spatialized to a single point.
  • +
  • 90: Left channel is rotated 45 degrees to the left compared with angle=0 and the right channel 45 degrees to the right.
  • +
  • 180: Left channel is rotated 90 degrees to the left compared with angle=0 and the right channel 90 degrees to the right.
  • +
  • 360: Left channel is rotated 180 degrees to the left and the right channel 180 degrees to the right. This means the sound is collapsed to mono and spatialized to a single point in the opposite direction compared with (angle=0).
  • +
+

See Also: ChannelControl::get3DSpread

+

ChannelControl::setCallback

+

Sets the callback for ChannelControl level notifications.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
FMOD_RESULT ChannelControl::setCallback(
+  FMOD_CHANNELCONTROL_CALLBACK callback
+);
+
+ +
FMOD_RESULT FMOD_Channel_SetCallback(
+  FMOD_CHANNEL *channel,
+  FMOD_CHANNELCONTROL_CALLBACK callback
+);
+FMOD_RESULT FMOD_ChannelGroup_SetCallback(
+  FMOD_CHANNELGROUP *channelgroup,
+  FMOD_CHANNELCONTROL_CALLBACK callback
+);
+
+ +
RESULT ChannelControl.setCallback(
+  CHANNEL_CALLBACK callback
+);
+
+ +
Channel.setCallback(
+  callback
+);
+ChannelGroup.setCallback(
+  callback
+);
+
+ +
+
callback
+
Callback to invoke. (FMOD_CHANNELCONTROL_CALLBACK)
+
+

See Also: Callback Behavior, FMOD_CHANNELCONTROL_CALLBACK_TYPE

+

ChannelControl::setDelay

+

Sets a sample accurate start (and/or stop) time relative to the parent ChannelGroup DSP clock.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
FMOD_RESULT ChannelControl::setDelay(
+  unsigned long long dspclock_start,
+  unsigned long long dspclock_end,
+  bool stopchannels = true
+);
+
+ +
FMOD_RESULT FMOD_Channel_SetDelay(
+  FMOD_CHANNEL *channel,
+  unsigned long long dspclock_start,
+  unsigned long long dspclock_end,
+  FMOD_BOOL stopchannels
+);
+FMOD_RESULT FMOD_ChannelGroup_SetDelay(
+  FMOD_CHANNELGROUP *channelgroup,
+  unsigned long long dspclock_start,
+  unsigned long long dspclock_end,
+  FMOD_BOOL stopchannels
+);
+
+ +
RESULT ChannelControl.setDelay(
+  ulong dspclock_start,
+  ulong dspclock_end,
+  bool stopchannels = true
+);
+
+ +
Channel.setDelay(
+  dspclock_start,
+  dspclock_end,
+  stopchannels
+);
+ChannelGroup.setDelay(
+  dspclock_start,
+  dspclock_end,
+  stopchannels
+);
+
+ +
+
dspclock_start Opt
+
+

DSP clock of the parent ChannelGroup to audibly start playing sound at.

+
    +
  • Units: Samples
  • +
  • Default: 0
  • +
+
+
dspclock_end Opt
+
+

DSP clock of the parent ChannelGroup to audibly stop playing sound at.

+
    +
  • Units: Samples
  • +
  • Default: 0
  • +
+
+
stopchannels
+
+

True: When dspclock_end is reached, behaves like ChannelControl::stop has been called.
+False: When dspclock_end is reached, behaves like ChannelControl::setPaused has been called, a subsequent dspclock_start allows it to resume.

+
    +
  • Units: Boolean
  • +
+
+
+

To perform sample accurate scheduling use ChannelControl::getDSPClock to query the parent clock value. If a parent ChannelGroup changes its pitch, the start and stop times will still be correct as the parent clock rate is adjusted by that pitch.

+

See Also: ChannelControl::getDelay

+

ChannelControl::setDSPIndex

+

Sets the index in the DSP chain of the specified DSP.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
FMOD_RESULT ChannelControl::setDSPIndex(
+  DSP *dsp,
+  int index
+);
+
+ +
FMOD_RESULT FMOD_Channel_SetDSPIndex(
+  FMOD_CHANNEL *channel,
+  FMOD_DSP *dsp,
+  int index
+);
+FMOD_RESULT FMOD_ChannelGroup_SetDSPIndex(
+  FMOD_CHANNELGROUP *channelgroup,
+  FMOD_DSP *dsp,
+  int index
+);
+
+ +
RESULT ChannelControl.setDSPIndex(
+  DSP dsp,
+  int index
+);
+
+ +
Channel.setDSPIndex(
+  dsp,
+  index
+);
+ChannelGroup.setDSPIndex(
+  dsp,
+  index
+);
+
+ +
+
dsp
+
A DSP unit that exists in the DSP chain. (DSP)
+
index
+
Offset into the DSP chain to move the DSP to, see FMOD_CHANNELCONTROL_DSP_INDEX for special named offsets.
+
+

This will move a DSP already in the DSP chain to a new offset.

+

See Also: ChannelControl::getDSPIndex

+

ChannelControl::setFadePointRamp

+

Adds a volume ramp at the specified time in the future using fade points.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
FMOD_RESULT ChannelControl::setFadePointRamp(
+  unsigned long long dspclock,
+  float volume
+);
+
+ +
FMOD_RESULT FMOD_Channel_SetFadePointRamp(
+  FMOD_CHANNEL *channel,
+  unsigned long long dspclock,
+  float volume
+);
+FMOD_RESULT FMOD_ChannelGroup_SetFadePointRamp(
+  FMOD_CHANNELGROUP *channelgroup,
+  unsigned long long dspclock,
+  float volume
+);
+
+ +
RESULT ChannelControl.setFadePointRamp(
+  ulong dspclock,
+  float volume
+);
+
+ +
Channel.setFadePointRamp(
+  dspclock,
+  volume
+);
+ChannelGroup.setFadePointRamp(
+  dspclock,
+  volume
+);
+
+ +
+
dspclock
+
+

Time at which the ramp will end, as measured by the DSP clock of the parent ChannelGroup.

+
    +
  • Units: Samples
  • +
+
+
volume
+
+

Volume level at the given dspclock. 0 = silent, 1 = full.

+
    +
  • Units: Linear
  • +
  • Range: [0, inf)
  • +
+
+
+

This is a convenience function that creates a scheduled 64 sample fade point ramp from the current volume level to volume arriving at dspclock time.

+

Can be use in conjunction with ChannelControl::SetDelay.

+

All fade points after dspclock will be removed.

+

See Also: ChannelControl::removeFadePoints, ChannelControl::addFadePoint, ChannelControl::getFadePoints

+

ChannelControl::setLowPassGain

+

Sets the gain of the dry signal when built in lowpass / distance filtering is applied.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
FMOD_RESULT ChannelControl::setLowPassGain(
+  float gain
+);
+
+ +
FMOD_RESULT FMOD_Channel_SetLowPassGain(
+  FMOD_CHANNEL *channel,
+  float gain
+);
+FMOD_RESULT FMOD_ChannelGroup_SetLowPassGain(
+  FMOD_CHANNELGROUP *channelgroup,
+  float gain
+);
+
+ +
RESULT ChannelControl.setLowPassGain(
+  float gain
+);
+
+ +
Channel.setLowPassGain(
+  gain
+);
+ChannelGroup.setLowPassGain(
+  gain
+);
+
+ +
+
gain
+
+

gain level where 0 represents silent (full filtering) and 1 represents full volume (no filtering).

+
    +
  • Units: Linear
  • +
  • Range: [0, 1]
  • +
  • Default: 1
  • +
+
+
+

Requires the built in lowpass to be created with FMOD_INIT_CHANNEL_LOWPASS or FMOD_INIT_CHANNEL_DISTANCEFILTER.

+
+

Currently only supported for Channel, not ChannelGroup.

+
+

See Also: ChannelControl::getLowPassGain

+

ChannelControl::setMixLevelsInput

+

Sets the incoming volume level for each channel of a multi-channel signal.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
FMOD_RESULT ChannelControl::setMixLevelsInput(
+  float *levels,
+  int numlevels
+);
+
+ +
FMOD_RESULT FMOD_Channel_SetMixLevelsInput(
+  FMOD_CHANNEL *channel,
+  float *levels,
+  int numlevels
+);
+FMOD_RESULT FMOD_ChannelGroup_SetMixLevelsInput(
+  FMOD_CHANNELGROUP *channelgroup,
+  float *levels,
+  int numlevels
+);
+
+ +
RESULT ChannelControl.setMixLevelsInput(
+  float[] levels,
+  int numlevels
+);
+
+ +
Channel.setMixLevelsInput(
+  levels,
+  numlevels
+);
+ChannelGroup.setMixLevelsInput(
+  levels,
+  numlevels
+);
+
+ +
+
levels
+
+

Array of volume levels for each incoming channel. Volume level. 0 = silent, 1 = full. Negative level inverts the signal. Values larger than 1 amplify the signal.

+
    +
  • Units: Linear
  • +
  • Range: (-inf, inf)
  • +
+
+
numlevels
+
+

Number of levels in the array.

+ +
+
+

This is a convenience function to avoid passing a matrix, it will overwrite values set via ChannelControl::setPan, ChannelControl::setMixLevelsOutput and ChannelControl::setMixMatrix.

+
+

Currently only supported for Channel, not ChannelGroup.

+
+

See Also: ChannelControl::getMixMatrix

+

ChannelControl::setMixLevelsOutput

+

Sets the outgoing volume levels for each speaker.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
FMOD_RESULT ChannelControl::setMixLevelsOutput(
+  float frontleft,
+  float frontright,
+  float center,
+  float lfe,
+  float surroundleft,
+  float surroundright,
+  float backleft,
+  float backright
+);
+
+ +
FMOD_RESULT FMOD_Channel_SetMixLevelsOutput(
+  FMOD_CHANNEL *channel,
+  float frontleft,
+  float frontright,
+  float center,
+  float lfe,
+  float surroundleft,
+  float surroundright,
+  float backleft,
+  float backright
+);
+FMOD_RESULT FMOD_ChannelGroup_SetMixLevelsOutput(
+  FMOD_CHANNELGROUP *channelgroup,
+  float frontleft,
+  float frontright,
+  float center,
+  float lfe,
+  float surroundleft,
+  float surroundright,
+  float backleft,
+  float backright
+);
+
+ +
RESULT ChannelControl.setMixLevelsOutput(
+  float frontleft,
+  float frontright,
+  float center,
+  float lfe,
+  float surroundleft,
+  float surroundright,
+  float backleft,
+  float backright
+);
+
+ +
Channel.setMixLevelsOutput(
+  frontleft,
+  frontright,
+  center,
+  lfe,
+  surroundleft,
+  surroundright,
+  backleft,
+  backright
+);
+ChannelGroup.setMixLevelsOutput(
+  frontleft,
+  frontright,
+  center,
+  lfe,
+  surroundleft,
+  surroundright,
+  backleft,
+  backright
+);
+
+ +
+
frontleft
+
+

Volume level for FMOD_SPEAKER_FRONT_LEFT. Volume level. 0 = silent, 1 = full. Negative level inverts the signal. Values larger than 1 amplify the signal.

+
    +
  • Units: Linear
  • +
  • Range: (-inf, inf)
  • +
+
+
frontright
+
+

Volume level for FMOD_SPEAKER_FRONT_RIGHT. Volume level. 0 = silent, 1 = full. Negative level inverts the signal. Values larger than 1 amplify the signal.

+
    +
  • Units: Linear
  • +
  • Range: (-inf, inf)
  • +
+
+
center
+
+

Volume level for FMOD_SPEAKER_FRONT_CENTER. Volume level. 0 = silent, 1 = full. Negative level inverts the signal. Values larger than 1 amplify the signal.

+
    +
  • Units: Linear
  • +
  • Range: (-inf, inf)
  • +
+
+
lfe
+
+

Volume level for FMOD_SPEAKER_LOW_FREQUENCY. Volume level. 0 = silent, 1 = full. Negative level inverts the signal. Values larger than 1 amplify the signal.

+
    +
  • Units: Linear
  • +
  • Range: (-inf, inf)
  • +
+
+
surroundleft
+
+

Volume level for FMOD_SPEAKER_SURROUND_LEFT. Volume level. 0 = silent, 1 = full. Negative level inverts the signal. Values larger than 1 amplify the signal.

+
    +
  • Units: Linear
  • +
  • Range: (-inf, inf)
  • +
+
+
surroundright
+
+

Volume level for FMOD_SPEAKER_SURROUND_RIGHT. Volume level. 0 = silent, 1 = full. Negative level inverts the signal. Values larger than 1 amplify the signal.

+
    +
  • Units: Linear
  • +
  • Range: (-inf, inf)
  • +
+
+
backleft
+
+

Volume level for FMOD_SPEAKER_BACK_LEFT. Volume level. 0 = silent, 1 = full. Negative level inverts the signal. Values larger than 1 amplify the signal.

+
    +
  • Units: Linear
  • +
  • Range: (-inf, inf)
  • +
+
+
backright
+
+

Volume level for FMOD_SPEAKER_BACK_RIGHT. Volume level. 0 = silent, 1 = full. Negative level inverts the signal. Values larger than 1 amplify the signal.

+
    +
  • Units: Linear
  • +
  • Range: (-inf, inf)
  • +
+
+
+

Specify the level for a given output speaker, if the channel count of the input and output do not match, channels will be up/down mixed as appropriate to approximate the given speaker values. For example stereo input with 5.1 output will use the center parameter to distribute signal to the center speaker from front left and front right channels.

+

This is a convenience function to avoid passing a matrix, it will overwrite values set via ChannelControl::setPan, ChannelControl::setMixLevelsInput and ChannelControl::setMixMatrix.

+

The output channel count will always match the System speaker mode set via System::setSoftwareFormat.

+

If the System is initialized with FMOD_SPEAKERMODE_RAW calling this function will produce silence.

+

See Also: ChannelControl::getMixMatrix

+

ChannelControl::setMixMatrix

+

Sets a two-dimensional pan matrix that maps the signal from input channels (columns) to output speakers (rows).

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
FMOD_RESULT ChannelControl::setMixMatrix(
+  float *matrix,
+  int outchannels,
+  int inchannels,
+  int inchannel_hop = 0
+);
+
+ +
FMOD_RESULT FMOD_Channel_SetMixMatrix(
+  FMOD_CHANNEL *channel,
+  float *matrix,
+  int outchannels,
+  int inchannels,
+  int inchannel_hop
+);
+FMOD_RESULT FMOD_ChannelGroup_SetMixMatrix(
+  FMOD_CHANNELGROUP *channelgroup,
+  float *matrix,
+  int outchannels,
+  int inchannels,
+  int inchannel_hop
+);
+
+ +
RESULT ChannelControl.setMixMatrix(
+  float[] matrix,
+  int outchannels,
+  int inchannels,
+  int inchannel_hop = 0
+);
+
+ +
Channel.setMixMatrix(
+  matrix,
+  outchannels,
+  inchannels,
+  inchannel_hop
+);
+ChannelGroup.setMixMatrix(
+  matrix,
+  outchannels,
+  inchannels,
+  inchannel_hop
+);
+
+ +
+
matrix Opt
+
+

Two dimensional array of volume levels in row-major order. Each row represents an output speaker, each column represents an input channel.

+
    +
  • Units: Linear
  • +
  • Range: (-inf, inf)
  • +
+
+
outchannels
+
+

Number of output channels (rows) in matrix.

+ +
+
inchannels
+
+

Number of input channels (columns) in matrix.

+ +
+
inchannel_hop Opt
+
Width (total number of columns) in source matrix. A matrix element is referenced as 'outchannel * inchannel_hop + inchannel'.
+
+ +

This will overwrite values set via ChannelControl::setPan, ChannelControl::setMixLevelsInput and ChannelControl::setMixLevelsOutput.

+

If no matrix is passed in via matrix a default upmix, downmix, or unit matrix will take its place. A unit matrix allows a signal to pass through unchanged.

+

Example 5.1 unit matrix:

+
1 0 0 0 0 0 
+0 1 0 0 0 0 
+0 0 1 0 0 0 
+0 0 0 1 0 0 
+0 0 0 0 1 0 
+0 0 0 0 0 1
+
+

Matrix element values can be below 0 to invert a signal and above 1 to amplify the signal. Note that increasing the signal level too far may cause audible distortion.

+

See Also: ChannelControl::getMixMatrix

+

ChannelControl::setMode

+

Sets the playback mode that controls how this object behaves.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
FMOD_RESULT ChannelControl::setMode(
+  FMOD_MODE mode
+);
+
+ +
FMOD_RESULT FMOD_Channel_SetMode(
+  FMOD_CHANNEL *channel,
+  FMOD_MODE mode
+);
+FMOD_RESULT FMOD_ChannelGroup_SetMode(
+  FMOD_CHANNELGROUP *channelgroup,
+  FMOD_MODE mode
+);
+
+ +
RESULT ChannelControl.setMode(
+  MODE mode
+);
+
+ +
Channel.setMode(
+  mode
+);
+ChannelGroup.setMode(
+  mode
+);
+
+ +
+
mode
+
+

Playback mode. More than one mode can be set at once by combining them with the OR operator. (FMOD_MODE)

+ +
+
+

Modes supported:

+ +

When changing the loop mode, sounds created with System::createStream or FMOD_CREATESTREAM may have already been pre-buffered and executed their loop logic ahead of time before this call was even made. This is dependent on the size of the sound versus the size of the stream decode buffer (see FMOD_CREATESOUNDEXINFO). If this happens, you may need to reflush the stream buffer by calling Channel::setPosition. Note this will usually only happen if you have sounds or loop points that are smaller than the stream decode buffer size.

+

When changing the loop mode of sounds created with with System::createSound or FMOD_CREATESAMPLE, if the sound was set up as FMOD_LOOP_OFF, then set to FMOD_LOOP_NORMAL with this function, the sound may click when playing the end of the sound. This is because the sound needs to be prepared for looping using Sound::setMode, by modifying the content of the PCM data (i.e. data past the end of the actual sample data) to allow the interpolators to read ahead without clicking. If you use ChannelControl::setMode it will not do this (because different Channels may have different loop modes for the same sound) and may click if you try to set it to looping on an unprepared sound. If you want to change the loop mode at runtime it may be better to load the sound as looping first (or use Sound::setMode), to let it prepare the data as if it was looping so that it does not click whenever ChannelControl::setMode is used to turn looping on.

+

If FMOD_3D_IGNOREGEOMETRY or FMOD_VIRTUAL_PLAYFROMSTART is not specified, the flag will be cleared if it was specified previously.

+

See Also: ChannelControl::getMode

+

ChannelControl::setMute

+

Sets the mute state.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
FMOD_RESULT ChannelControl::setMute(
+  bool mute
+);
+
+ +
FMOD_RESULT FMOD_Channel_SetMute(
+  FMOD_CHANNEL *channel,
+  FMOD_BOOL mute
+);
+FMOD_RESULT FMOD_ChannelGroup_SetMute(
+  FMOD_CHANNELGROUP *channelgroup,
+  FMOD_BOOL mute
+);
+
+ +
RESULT ChannelControl.setMute(
+  bool mute
+);
+
+ +
Channel.setMute(
+  mute
+);
+ChannelGroup.setMute(
+  mute
+);
+
+ +
+
mute
+
+

Mute state. True = silent. False = audible.

+
    +
  • Units: Boolean
  • +
+
+
+

Mute is an additional control for volume, the effect of which is equivalent to setting the volume to zero.

+

An individual mute state is kept for each object, muting a parent ChannelGroup will effectively mute this object however when queried the individual mute state is returned. ChannelControl::getAudibility can be used to calculate overall audibility for a Channel or ChannelGroup.

+

See Also: ChannelControl::getMute

+

ChannelControl::setPan

+

Sets the left/right pan level.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
FMOD_RESULT ChannelControl::setPan(
+  float pan
+);
+
+ +
FMOD_RESULT FMOD_Channel_SetPan(
+  FMOD_CHANNEL *channel,
+  float pan
+);
+FMOD_RESULT FMOD_ChannelGroup_SetPan(
+  FMOD_CHANNELGROUP *channelgroup,
+  float pan
+);
+
+ +
RESULT ChannelControl.setPan(
+  float pan
+);
+
+ +
Channel.setPan(
+  pan
+);
+ChannelGroup.setPan(
+  pan
+);
+
+ +
+
pan
+
+

Pan level where -1 represents full left, 0 represents center and 1 represents full right.

+
    +
  • Range: [-1, 1]
  • +
  • Default: 0
  • +
+
+
+

This is a convenience function to avoid passing a matrix, it will overwrite values set via ChannelControl::setMixLevelsInput, ChannelControl::setMixLevelsOutput and ChannelControl::setMixMatrix.

+

Mono inputs are panned from left to right using constant power panning (non linear fade). Stereo and greater inputs will isolate the front left and right input channels and fade them up and down based on the pan value (silencing other channels). The output channel count will always match the System speaker mode set via System::setSoftwareFormat.

+

If the System is initialized with FMOD_SPEAKERMODE_RAW calling this function will produce silence.

+

See Also: ChannelControl::getMixMatrix

+

ChannelControl::setPaused

+

Sets the paused state.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
FMOD_RESULT ChannelControl::setPaused(
+  bool paused
+);
+
+ +
FMOD_RESULT FMOD_Channel_SetPaused(
+  FMOD_CHANNEL *channel,
+  FMOD_BOOL paused
+);
+FMOD_RESULT FMOD_ChannelGroup_SetPaused(
+  FMOD_CHANNELGROUP *channelgroup,
+  FMOD_BOOL paused
+);
+
+ +
RESULT ChannelControl.setPaused(
+  bool paused
+);
+
+ +
Channel.setPaused(
+  paused
+);
+ChannelGroup.setPaused(
+  paused
+);
+
+ +
+
paused
+
+

Paused state. True = playback halted. False = playback active.

+
    +
  • Units: Boolean
  • +
+
+
+

Pause halts playback which effectively freezes Channel::getPosition and ChannelControl::getDSPClock values.

+

An individual pause state is kept for each object, pausing a parent ChannelGroup will effectively pause this object however when queried the individual pause state is returned.

+

See Also: ChannelControl::getPaused

+

ChannelControl::setPitch

+

Sets the relative pitch / playback rate.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
FMOD_RESULT ChannelControl::setPitch(
+  float pitch
+);
+
+ +
FMOD_RESULT FMOD_Channel_SetPitch(
+  FMOD_CHANNEL *channel,
+  float pitch
+);
+FMOD_RESULT FMOD_ChannelGroup_SetPitch(
+  FMOD_CHANNELGROUP *channelgroup,
+  float pitch
+);
+
+ +
RESULT ChannelControl.setPitch(
+  float pitch
+);
+
+ +
Channel.setPitch(
+  pitch
+);
+ChannelGroup.setPitch(
+  pitch
+);
+
+ +
+
pitch
+
Pitch value where 0.5 represents half pitch (one octave down), 1.0 represents unmodified pitch and 2.0 represents double pitch (one octave up).
+
+

Scales playback frequency of Channel object or if issued on a ChannelGroup it scales the frequencies of all Channels contained in the ChannelGroup.

+

An individual pitch value is kept for each object, changing the pitch of a parent ChannelGroup will effectively alter the pitch of this object however when queried the individual pitch value is returned.

+

See Also: ChannelControl::getPitch, Channel::setFrequency, Channel::getFrequency

+

ChannelControl::setReverbProperties

+

Sets the wet / send level for a particular reverb instance.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
FMOD_RESULT ChannelControl::setReverbProperties(
+  int instance,
+  float wet
+);
+
+ +
FMOD_RESULT FMOD_Channel_SetReverbProperties(
+  FMOD_CHANNEL *channel,
+  int instance,
+  float wet
+);
+FMOD_RESULT FMOD_ChannelGroup_SetReverbProperties(
+  FMOD_CHANNELGROUP *channelgroup,
+  int instance,
+  float wet
+);
+
+ +
RESULT ChannelControl.setReverbProperties(
+  int instance,
+  float wet
+);
+
+ +
Channel.setReverbProperties(
+  instance,
+  wet
+);
+ChannelGroup.setReverbProperties(
+  instance,
+  wet
+);
+
+ +
+
instance
+
+

Reverb instance index.

+ +
+
wet
+
+

Send level for the signal to the reverb. 0 = none, 1 = full. Negative level inverts the signal.

+ +
+
+

Channels are automatically connected to all existing reverb instances due to the default wet level of 1. ChannelGroups however will not send to any reverb by default requiring an explicit call to this function.

+

ChannelGroup reverb is optimal for the case where you want to send 1 mixed signal to the reverb, rather than a lot of individual Channel reverb sends. It is advisable to do this to reduce CPU if you have many Channels inside a ChannelGroup.

+

When setting a wet level for a ChannelGroup, any Channels under that ChannelGroup will still have their existing sends to the reverb. To avoid this doubling up you should explicitly set the Channel wet levels to 0.

+

See Also: ChannelControl::getReverbProperties

+

ChannelControl::setUserData

+

Sets a user value associated with this object.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
FMOD_RESULT ChannelControl::setUserData(
+  void *userdata
+);
+
+ +
FMOD_RESULT FMOD_Channel_SetUserData(
+  FMOD_CHANNEL *channel,
+  void *userdata
+);
+FMOD_RESULT FMOD_ChannelGroup_SetUserData(
+  FMOD_CHANNELGROUP *channelgroup,
+  void *userdata
+);
+
+ +
RESULT ChannelControl.setUserData(
+  IntPtr userdata
+);
+
+ +
Channel.setUserData(
+  userdata
+);
+ChannelGroup.setUserData(
+  userdata
+);
+
+ +
+
userdata
+
Value stored on this object.
+
+

This function allows arbitrary user data to be attached to this object. See the User Data section of the glossary for an example of how to get and set user data.

+

See Also: ChannelControl::getUserData, ChannelControl::setCallback

+

ChannelControl::setVolume

+

Sets the volume level.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
FMOD_RESULT ChannelControl::setVolume(
+  float volume
+);
+
+ +
FMOD_RESULT FMOD_Channel_SetVolume(
+  FMOD_CHANNEL *channel,
+  float volume
+);
+FMOD_RESULT FMOD_ChannelGroup_SetVolume(
+  FMOD_CHANNELGROUP *channelgroup,
+  float volume
+);
+
+ +
RESULT ChannelControl.setVolume(
+  float volume
+);
+
+ +
Channel.setVolume(
+  volume
+);
+ChannelGroup.setVolume(
+  volume
+);
+
+ +
+
volume
+
+

Volume level. 0 = silent, 1 = full. Negative level inverts the signal. Values larger than 1 amplify the signal.

+
    +
  • Units: Linear
  • +
  • Range: (-inf, inf)
  • +
  • Default: 1
  • +
+
+
+

To define the volume per Sound use Sound::setDefaults.

+

Setting volume at a level higher than 1 can lead to distortion/clipping.

+

See Also: ChannelControl::getVolume

+

ChannelControl::setVolumeRamp

+

Sets whether volume changes are ramped or instantaneous.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
FMOD_RESULT ChannelControl::setVolumeRamp(
+  bool ramp
+);
+
+ +
FMOD_RESULT FMOD_Channel_SetVolumeRamp(
+  FMOD_CHANNEL *channel,
+  FMOD_BOOL ramp
+);
+FMOD_RESULT FMOD_ChannelGroup_SetVolumeRamp(
+  FMOD_CHANNELGROUP *channelgroup,
+  FMOD_BOOL ramp
+);
+
+ +
RESULT ChannelControl.setVolumeRamp(
+  bool ramp
+);
+
+ +
Channel.setVolumeRamp(
+  ramp
+);
+ChannelGroup.setVolumeRamp(
+  ramp
+);
+
+ +
+
ramp
+
+

Ramp state. True = volume change is ramped. False = volume change is instantaeous.

+
    +
  • Units: Boolean
  • +
  • Default: True
  • +
+
+
+

Volume changes when not paused will be ramped to the target value to avoid a pop sound, this function allows that setting to be overridden and volume changes to be applied immediately.

+

See Also: ChannelControl::getVolumeRamp

+

ChannelControl::stop

+

Stops the Channel (or all Channels in nested ChannelGroups) from playing.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
FMOD_RESULT ChannelControl::stop();
+
+ +
FMOD_RESULT FMOD_Channel_Stop(FMOD_CHANNEL *channel);
+FMOD_RESULT FMOD_ChannelGroup_Stop(FMOD_CHANNELGROUP *channelgroup);
+
+ +
RESULT ChannelControl.stop();
+
+ +
Channel.stop();
+ChannelGroup.stop();
+
+ +

This will free up internal resources for reuse by the virtual voice system.

+

Channels are stopped automatically when their playback position reaches the length of the Sound being played. This is not the case however if the Channel is playing a DSP or the Sound is looping, in which case the Channel will continue playing until stop is called. Once stopped, the Channel handle will become invalid and can be discarded and any API calls made with it will return FMOD_ERR_INVALID_HANDLE.

+

See Also: System::playSound, Channel::getPosition, Sound::getLength, System::playDSP

+

FMOD_CHANNELCONTROL_TYPE

+

Identifier used to distinguish between Channel and ChannelGroup in the ChannelControl callback.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
typedef enum FMOD_CHANNELCONTROL_TYPE {
+  FMOD_CHANNELCONTROL_CHANNEL,
+  FMOD_CHANNELCONTROL_CHANNELGROUP,
+  FMOD_CHANNELCONTROL_MAX,
+} FMOD_CHANNELCONTROL_TYPE;
+
+ +
enum CHANNELCONTROL_TYPE : int
+{
+    CHANNEL,
+    CHANNELGROUP,
+    MAX
+}
+
+ +
CHANNELCONTROL_CHANNEL
+CHANNELCONTROL_CHANNELGROUP
+CHANNELCONTROL_MAX
+
+ +
+
FMOD_CHANNELCONTROL_CHANNEL
+
Type representing Channel
+
FMOD_CHANNELCONTROL_CHANNELGROUP
+
Type representing ChannelGroup
+
FMOD_CHANNELCONTROL_MAX
+
Maximum number of ChannelControl types.
+
+

See Also: ChannelControl::setCallback

+ + +
+ + + diff --git a/FMOD/doc/FMOD API User Manual/core-api-channelgroup.html b/FMOD/doc/FMOD API User Manual/core-api-channelgroup.html new file mode 100644 index 0000000..f8837dc --- /dev/null +++ b/FMOD/doc/FMOD API User Manual/core-api-channelgroup.html @@ -0,0 +1,476 @@ + + +Core API Reference | ChannelGroup + + + + +
+ +
+

11. Core API Reference | ChannelGroup

+

A submix in the mixing hierarchy akin to a bus that can contain both Channel and ChannelGroup objects.

+

Create with System::createChannelGroup.

+

Channel management:

+ +

ChannelGroup management:

+ +

General:

+ +

The following APIs are inherited from ChannelControl:

+

Playback:

+ +

Volume levels:

+ +

Spatialization:

+ +

Panning and level adjustment:

+ +

Filtering:

+ +

DSP chain configuration:

+ +

Sample accurate scheduling:

+ +

General:

+ +

ChannelGroup::addGroup

+

Adds a ChannelGroup as an input to this group.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
FMOD_RESULT ChannelGroup::addGroup(
+  ChannelGroup *group,
+  bool propagatedspclock = true,
+  DSPConnection **connection = nullptr
+);
+
+ +
FMOD_RESULT FMOD_ChannelGroup_AddGroup(
+  FMOD_CHANNELGROUP *channelgroup,
+  FMOD_CHANNELGROUP *group,
+  FMOD_BOOL propagatedspclock,
+  FMOD_DSPCONNECTION **connection
+);
+
+ +
RESULT ChannelGroup.addGroup(
+  ChannelGroup group,
+  bool propagatedspclock = true
+);
+RESULT ChannelGroup.addGroup(
+  ChannelGroup group,
+  bool propagatedspclock,
+  out DSPConnection connection
+);
+
+ +
ChannelGroup.addGroup(
+  group,
+  propagatedspclock,
+  connection
+);
+
+ +
+
group
+
Group to add. (ChannelGroup)
+
propagatedspclock
+
+

Recursively propagate this object's clock values to group.

+
    +
  • Units: Boolean
  • +
+
+
connection OutOpt
+
Connection between the head DSP of group and the tail DSP of this object. (DSPConnection)
+
+

See Also: ChannelGroup::getNumGroups, ChannelGroup::getGroup, ChannelGroup::getParentGroup

+

ChannelGroup::getChannel

+

Retrieves the Channel at the specified index in the list of Channel inputs.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
FMOD_RESULT ChannelGroup::getChannel(
+  int index,
+  Channel **channel
+);
+
+ +
FMOD_RESULT FMOD_ChannelGroup_GetChannel(
+  FMOD_CHANNELGROUP *channelgroup,
+  int index,
+  FMOD_CHANNEL **channel
+);
+
+ +
RESULT ChannelGroup.getChannel(
+  int index,
+  out Channel channel
+);
+
+ +
ChannelGroup.getChannel(
+  index,
+  channel
+);
+
+ +
+
index
+
+

Offset into the list of Channel inputs.

+ +
+
channel Out
+
Channel at the specified index. (Channel)
+
+

ChannelGroup::getGroup

+

Retrieves the ChannelGroup at the specified index in the list of group inputs.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
FMOD_RESULT ChannelGroup::getGroup(
+  int index,
+  ChannelGroup **group
+);
+
+ +
FMOD_RESULT FMOD_ChannelGroup_GetGroup(
+  FMOD_CHANNELGROUP *channelgroup,
+  int index,
+  FMOD_CHANNELGROUP **group
+);
+
+ +
RESULT ChannelGroup.getGroup(
+  int index,
+  out ChannelGroup group
+);
+
+ +
ChannelGroup.getGroup(
+  index,
+  group
+);
+
+ +
+
index
+
+

Offset into the list of group inputs.

+ +
+
group Out
+
Group at the specified index. (ChannelGroup)
+
+

See Also: ChannelGroup::addGroup, ChannelGroup::getParentGroup

+

ChannelGroup::getName

+

Retrieves the name set when the group was created.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
FMOD_RESULT ChannelGroup::getName(
+  char *name,
+  int namelen
+);
+
+ +
FMOD_RESULT FMOD_ChannelGroup_GetName(
+  FMOD_CHANNELGROUP *channelgroup,
+  char *name,
+  int namelen
+);
+
+ +
RESULT ChannelGroup.getName(
+  out string name,
+  int namelen
+);
+
+ +
ChannelGroup.getName(
+  name
+);
+
+ +
+
name Out
+
Name of the group. (UTF-8 string)
+
namelen
+
+

Length of name.

+
    +
  • Units: Bytes
  • +
+
+
+

See Also: System::getMasterChannelGroup, System::createChannelGroup

+

ChannelGroup::getNumChannels

+

Retrieves the number of Channels that feed into to this group.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
FMOD_RESULT ChannelGroup::getNumChannels(
+  int *numchannels
+);
+
+ +
FMOD_RESULT FMOD_ChannelGroup_GetNumChannels(
+  FMOD_CHANNELGROUP *channelgroup,
+  int *numchannels
+);
+
+ +
RESULT ChannelGroup.getNumChannels(
+  out int numchannels
+);
+
+ +
ChannelGroup.getNumChannels(
+  numchannels
+);
+
+ +
+
numchannels Out
+
Number of Channels.
+
+

See Also: ChannelGroup::getChannel

+

ChannelGroup::getNumGroups

+

Retrieves the number of ChannelGroups that feed into to this group.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
FMOD_RESULT ChannelGroup::getNumGroups(
+  int *numgroups
+);
+
+ +
FMOD_RESULT FMOD_ChannelGroup_GetNumGroups(
+  FMOD_CHANNELGROUP *channelgroup,
+  int *numgroups
+);
+
+ +
RESULT ChannelGroup.getNumGroups(
+  out int numgroups
+);
+
+ +
ChannelGroup.getNumGroups(
+  numgroups
+);
+
+ +
+
numgroups Out
+
Number of ChannelGroups.
+
+

See Also: ChannelGroup::addGroup, ChannelGroup::getGroup, ChannelGroup::getParentGroup

+

ChannelGroup::getParentGroup

+

Retrieves the ChannelGroup this object outputs to.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
FMOD_RESULT ChannelGroup::getParentGroup(
+  ChannelGroup **group
+);
+
+ +
FMOD_RESULT FMOD_ChannelGroup_GetParentGroup(
+  FMOD_CHANNELGROUP *channelgroup,
+  FMOD_CHANNELGROUP **group
+);
+
+ +
RESULT ChannelGroup.getParentGroup(
+  out ChannelGroup group
+);
+
+ +
ChannelGroup.getParentGroup(
+  group
+);
+
+ +
+
group Out
+
Output group. (ChannelGroup)
+
+

See Also: ChannelGroup::addGroup, ChannelGroup::getNumGroups, ChannelGroup::getGroup

+

ChannelGroup::release

+

Frees the memory for the group.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
FMOD_RESULT ChannelGroup::release();
+
+ +
FMOD_RESULT FMOD_ChannelGroup_Release(FMOD_CHANNELGROUP *channelgroup);
+
+ +
RESULT ChannelGroup.release();
+
+ +
ChannelGroup.release();
+
+ +

Any Channels or ChannelGroups feeding into this group are moved to the master ChannelGroup.

+

See Also: System::createChannelGroup, System::getMasterChannelGroup

+ + +
+ + + diff --git a/FMOD/doc/FMOD API User Manual/core-api-common-dsp-effects.html b/FMOD/doc/FMOD API User Manual/core-api-common-dsp-effects.html new file mode 100644 index 0000000..68531e2 --- /dev/null +++ b/FMOD/doc/FMOD API User Manual/core-api-common-dsp-effects.html @@ -0,0 +1,5009 @@ + + +Core API Reference | Effect Parameters + + + + +
+ +
+

11. Core API Reference | Effect Parameters

+

These are the parameters for controlling digital signal processors.

+

DSP Types:

+ +

DSP Parameters:

+ +

DSP Parameter Types:

+ +

FMOD_DSP_CHANNELMIX

+

Channel Mix DSP parameter types.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
typedef enum FMOD_DSP_CHANNELMIX {
+  FMOD_DSP_CHANNELMIX_OUTPUTGROUPING,
+  FMOD_DSP_CHANNELMIX_GAIN_CH0,
+  FMOD_DSP_CHANNELMIX_GAIN_CH1,
+  FMOD_DSP_CHANNELMIX_GAIN_CH2,
+  FMOD_DSP_CHANNELMIX_GAIN_CH3,
+  FMOD_DSP_CHANNELMIX_GAIN_CH4,
+  FMOD_DSP_CHANNELMIX_GAIN_CH5,
+  FMOD_DSP_CHANNELMIX_GAIN_CH6,
+  FMOD_DSP_CHANNELMIX_GAIN_CH7,
+  FMOD_DSP_CHANNELMIX_GAIN_CH8,
+  FMOD_DSP_CHANNELMIX_GAIN_CH9,
+  FMOD_DSP_CHANNELMIX_GAIN_CH10,
+  FMOD_DSP_CHANNELMIX_GAIN_CH11,
+  FMOD_DSP_CHANNELMIX_GAIN_CH12,
+  FMOD_DSP_CHANNELMIX_GAIN_CH13,
+  FMOD_DSP_CHANNELMIX_GAIN_CH14,
+  FMOD_DSP_CHANNELMIX_GAIN_CH15,
+  FMOD_DSP_CHANNELMIX_GAIN_CH16,
+  FMOD_DSP_CHANNELMIX_GAIN_CH17,
+  FMOD_DSP_CHANNELMIX_GAIN_CH18,
+  FMOD_DSP_CHANNELMIX_GAIN_CH19,
+  FMOD_DSP_CHANNELMIX_GAIN_CH20,
+  FMOD_DSP_CHANNELMIX_GAIN_CH21,
+  FMOD_DSP_CHANNELMIX_GAIN_CH22,
+  FMOD_DSP_CHANNELMIX_GAIN_CH23,
+  FMOD_DSP_CHANNELMIX_GAIN_CH24,
+  FMOD_DSP_CHANNELMIX_GAIN_CH25,
+  FMOD_DSP_CHANNELMIX_GAIN_CH26,
+  FMOD_DSP_CHANNELMIX_GAIN_CH27,
+  FMOD_DSP_CHANNELMIX_GAIN_CH28,
+  FMOD_DSP_CHANNELMIX_GAIN_CH29,
+  FMOD_DSP_CHANNELMIX_GAIN_CH30,
+  FMOD_DSP_CHANNELMIX_GAIN_CH31,
+  FMOD_DSP_CHANNELMIX_OUTPUT_CH0,
+  FMOD_DSP_CHANNELMIX_OUTPUT_CH1,
+  FMOD_DSP_CHANNELMIX_OUTPUT_CH2,
+  FMOD_DSP_CHANNELMIX_OUTPUT_CH3,
+  FMOD_DSP_CHANNELMIX_OUTPUT_CH4,
+  FMOD_DSP_CHANNELMIX_OUTPUT_CH5,
+  FMOD_DSP_CHANNELMIX_OUTPUT_CH6,
+  FMOD_DSP_CHANNELMIX_OUTPUT_CH7,
+  FMOD_DSP_CHANNELMIX_OUTPUT_CH8,
+  FMOD_DSP_CHANNELMIX_OUTPUT_CH9,
+  FMOD_DSP_CHANNELMIX_OUTPUT_CH10,
+  FMOD_DSP_CHANNELMIX_OUTPUT_CH11,
+  FMOD_DSP_CHANNELMIX_OUTPUT_CH12,
+  FMOD_DSP_CHANNELMIX_OUTPUT_CH13,
+  FMOD_DSP_CHANNELMIX_OUTPUT_CH14,
+  FMOD_DSP_CHANNELMIX_OUTPUT_CH15,
+  FMOD_DSP_CHANNELMIX_OUTPUT_CH16,
+  FMOD_DSP_CHANNELMIX_OUTPUT_CH17,
+  FMOD_DSP_CHANNELMIX_OUTPUT_CH18,
+  FMOD_DSP_CHANNELMIX_OUTPUT_CH19,
+  FMOD_DSP_CHANNELMIX_OUTPUT_CH20,
+  FMOD_DSP_CHANNELMIX_OUTPUT_CH21,
+  FMOD_DSP_CHANNELMIX_OUTPUT_CH22,
+  FMOD_DSP_CHANNELMIX_OUTPUT_CH23,
+  FMOD_DSP_CHANNELMIX_OUTPUT_CH24,
+  FMOD_DSP_CHANNELMIX_OUTPUT_CH25,
+  FMOD_DSP_CHANNELMIX_OUTPUT_CH26,
+  FMOD_DSP_CHANNELMIX_OUTPUT_CH27,
+  FMOD_DSP_CHANNELMIX_OUTPUT_CH28,
+  FMOD_DSP_CHANNELMIX_OUTPUT_CH29,
+  FMOD_DSP_CHANNELMIX_OUTPUT_CH30,
+  FMOD_DSP_CHANNELMIX_OUTPUT_CH31
+} FMOD_DSP_CHANNELMIX;
+
+ +
enum DSP_CHANNELMIX
+{
+  OUTPUTGROUPING,
+  GAIN_CH0,
+  GAIN_CH1,
+  GAIN_CH2,
+  GAIN_CH3,
+  GAIN_CH4,
+  GAIN_CH5,
+  GAIN_CH6,
+  GAIN_CH7,
+  GAIN_CH8,
+  GAIN_CH9,
+  GAIN_CH10,
+  GAIN_CH11,
+  GAIN_CH12,
+  GAIN_CH13,
+  GAIN_CH14,
+  GAIN_CH15,
+  GAIN_CH16,
+  GAIN_CH17,
+  GAIN_CH18,
+  GAIN_CH19,
+  GAIN_CH20,
+  GAIN_CH21,
+  GAIN_CH22,
+  GAIN_CH23,
+  GAIN_CH24,
+  GAIN_CH25,
+  GAIN_CH26,
+  GAIN_CH27,
+  GAIN_CH28,
+  GAIN_CH29,
+  GAIN_CH30,
+  GAIN_CH31,
+  OUTPUT_CH0,
+  OUTPUT_CH1,
+  OUTPUT_CH2,
+  OUTPUT_CH3,
+  OUTPUT_CH4,
+  OUTPUT_CH5,
+  OUTPUT_CH6,
+  OUTPUT_CH7,
+  OUTPUT_CH8,
+  OUTPUT_CH9,
+  OUTPUT_CH10,
+  OUTPUT_CH11,
+  OUTPUT_CH12,
+  OUTPUT_CH13,
+  OUTPUT_CH14,
+  OUTPUT_CH15,
+  OUTPUT_CH16,
+  OUTPUT_CH17,
+  OUTPUT_CH18,
+  OUTPUT_CH19,
+  OUTPUT_CH20,
+  OUTPUT_CH21,
+  OUTPUT_CH22,
+  OUTPUT_CH23,
+  OUTPUT_CH24,
+  OUTPUT_CH25,
+  OUTPUT_CH26,
+  OUTPUT_CH27,
+  OUTPUT_CH28,
+  OUTPUT_CH29,
+  OUTPUT_CH30,
+  OUTPUT_CH31
+}
+
+ +
FMOD.DSP_CHANNELMIX_OUTPUTGROUPING
+FMOD.DSP_CHANNELMIX_GAIN_CH0
+FMOD.DSP_CHANNELMIX_GAIN_CH1
+FMOD.DSP_CHANNELMIX_GAIN_CH2
+FMOD.DSP_CHANNELMIX_GAIN_CH3
+FMOD.DSP_CHANNELMIX_GAIN_CH4
+FMOD.DSP_CHANNELMIX_GAIN_CH5
+FMOD.DSP_CHANNELMIX_GAIN_CH6
+FMOD.DSP_CHANNELMIX_GAIN_CH7
+FMOD.DSP_CHANNELMIX_GAIN_CH8
+FMOD.DSP_CHANNELMIX_GAIN_CH9
+FMOD.DSP_CHANNELMIX_GAIN_CH10
+FMOD.DSP_CHANNELMIX_GAIN_CH11
+FMOD.DSP_CHANNELMIX_GAIN_CH12
+FMOD.DSP_CHANNELMIX_GAIN_CH13
+FMOD.DSP_CHANNELMIX_GAIN_CH14
+FMOD.DSP_CHANNELMIX_GAIN_CH15
+FMOD.DSP_CHANNELMIX_GAIN_CH16
+FMOD.DSP_CHANNELMIX_GAIN_CH17
+FMOD.DSP_CHANNELMIX_GAIN_CH18
+FMOD.DSP_CHANNELMIX_GAIN_CH19
+FMOD.DSP_CHANNELMIX_GAIN_CH20
+FMOD.DSP_CHANNELMIX_GAIN_CH21
+FMOD.DSP_CHANNELMIX_GAIN_CH22
+FMOD.DSP_CHANNELMIX_GAIN_CH23
+FMOD.DSP_CHANNELMIX_GAIN_CH24
+FMOD.DSP_CHANNELMIX_GAIN_CH25
+FMOD.DSP_CHANNELMIX_GAIN_CH26
+FMOD.DSP_CHANNELMIX_GAIN_CH27
+FMOD.DSP_CHANNELMIX_GAIN_CH28
+FMOD.DSP_CHANNELMIX_GAIN_CH29
+FMOD.DSP_CHANNELMIX_GAIN_CH30
+FMOD.DSP_CHANNELMIX_GAIN_CH31
+FMOD.DSP_CHANNELMIX_OUTPUT_CH0,
+FMOD.DSP_CHANNELMIX_OUTPUT_CH1,
+FMOD.DSP_CHANNELMIX_OUTPUT_CH2,
+FMOD.DSP_CHANNELMIX_OUTPUT_CH3,
+FMOD.DSP_CHANNELMIX_OUTPUT_CH4,
+FMOD.DSP_CHANNELMIX_OUTPUT_CH5,
+FMOD.DSP_CHANNELMIX_OUTPUT_CH6,
+FMOD.DSP_CHANNELMIX_OUTPUT_CH7,
+FMOD.DSP_CHANNELMIX_OUTPUT_CH8,
+FMOD.DSP_CHANNELMIX_OUTPUT_CH9,
+FMOD.DSP_CHANNELMIX_OUTPUT_CH10,
+FMOD.DSP_CHANNELMIX_OUTPUT_CH11,
+FMOD.DSP_CHANNELMIX_OUTPUT_CH12,
+FMOD.DSP_CHANNELMIX_OUTPUT_CH13,
+FMOD.DSP_CHANNELMIX_OUTPUT_CH14,
+FMOD.DSP_CHANNELMIX_OUTPUT_CH15,
+FMOD.DSP_CHANNELMIX_OUTPUT_CH16,
+FMOD.DSP_CHANNELMIX_OUTPUT_CH17,
+FMOD.DSP_CHANNELMIX_OUTPUT_CH18,
+FMOD.DSP_CHANNELMIX_OUTPUT_CH19,
+FMOD.DSP_CHANNELMIX_OUTPUT_CH20,
+FMOD.DSP_CHANNELMIX_OUTPUT_CH21,
+FMOD.DSP_CHANNELMIX_OUTPUT_CH22,
+FMOD.DSP_CHANNELMIX_OUTPUT_CH23,
+FMOD.DSP_CHANNELMIX_OUTPUT_CH24,
+FMOD.DSP_CHANNELMIX_OUTPUT_CH25,
+FMOD.DSP_CHANNELMIX_OUTPUT_CH26,
+FMOD.DSP_CHANNELMIX_OUTPUT_CH27,
+FMOD.DSP_CHANNELMIX_OUTPUT_CH28,
+FMOD.DSP_CHANNELMIX_OUTPUT_CH29,
+FMOD.DSP_CHANNELMIX_OUTPUT_CH30,
+FMOD.DSP_CHANNELMIX_OUTPUT_CH31
+
+ +
+
FMOD_DSP_CHANNELMIX_OUTPUTGROUPING
+
+

Channel mix output grouping. (FMOD_DSP_CHANNELMIX_OUTPUT)

+ +
+
FMOD_DSP_CHANNELMIX_GAIN_CH0
+
+

Channel #0 gain.

+
    +
  • Type: float
  • +
  • Units: Decibels
  • +
  • Range: [-80, 10]
  • +
  • Default: 0
  • +
+
+
FMOD_DSP_CHANNELMIX_GAIN_CH1
+
+

Channel #1 gain.

+
    +
  • Type: float
  • +
  • Units: Decibels
  • +
  • Range: [-80, 10]
  • +
  • Default: 0
  • +
+
+
FMOD_DSP_CHANNELMIX_GAIN_CH2
+
+

Channel #2 gain.

+
    +
  • Type: float
  • +
  • Units: Decibels
  • +
  • Range: [-80, 10]
  • +
  • Default: 0
  • +
+
+
FMOD_DSP_CHANNELMIX_GAIN_CH3
+
+

Channel #3 gain.

+
    +
  • Type: float
  • +
  • Units: Decibels
  • +
  • Range: [-80, 10]
  • +
  • Default: 0
  • +
+
+
FMOD_DSP_CHANNELMIX_GAIN_CH4
+
+

Channel #4 gain.

+
    +
  • Type: float
  • +
  • Units: Decibels
  • +
  • Range: [-80, 10]
  • +
  • Default: 0
  • +
+
+
FMOD_DSP_CHANNELMIX_GAIN_CH5
+
+

Channel #5 gain.

+
    +
  • Type: float
  • +
  • Units: Decibels
  • +
  • Range: [-80, 10]
  • +
  • Default: 0
  • +
+
+
FMOD_DSP_CHANNELMIX_GAIN_CH6
+
+

Channel #6 gain.

+
    +
  • Type: float
  • +
  • Units: Decibels
  • +
  • Range: [-80, 10]
  • +
  • Default: 0
  • +
+
+
FMOD_DSP_CHANNELMIX_GAIN_CH7
+
+

Channel #7 gain.

+
    +
  • Type: float
  • +
  • Units: Decibels
  • +
  • Range: [-80, 10]
  • +
  • Default: 0
  • +
+
+
FMOD_DSP_CHANNELMIX_GAIN_CH8
+
+

Channel #8 gain.

+
    +
  • Type: float
  • +
  • Units: Decibels
  • +
  • Range: [-80, 10]
  • +
  • Default: 0
  • +
+
+
FMOD_DSP_CHANNELMIX_GAIN_CH9
+
+

Channel #9 gain.

+
    +
  • Type: float
  • +
  • Units: Decibels
  • +
  • Range: [-80, 10]
  • +
  • Default: 0
  • +
+
+
FMOD_DSP_CHANNELMIX_GAIN_CH10
+
+

Channel #10 gain.

+
    +
  • Type: float
  • +
  • Units: Decibels
  • +
  • Range: [-80, 10]
  • +
  • Default: 0
  • +
+
+
FMOD_DSP_CHANNELMIX_GAIN_CH11
+
+

Channel #11 gain.

+
    +
  • Type: float
  • +
  • Units: Decibels
  • +
  • Range: [-80, 10]
  • +
  • Default: 0
  • +
+
+
FMOD_DSP_CHANNELMIX_GAIN_CH12
+
+

Channel #12 gain.

+
    +
  • Type: float
  • +
  • Units: Decibels
  • +
  • Range: [-80, 10]
  • +
  • Default: 0
  • +
+
+
FMOD_DSP_CHANNELMIX_GAIN_CH13
+
+

Channel #13 gain.

+
    +
  • Type: float
  • +
  • Units: Decibels
  • +
  • Range: [-80, 10]
  • +
  • Default: 0
  • +
+
+
FMOD_DSP_CHANNELMIX_GAIN_CH14
+
+

Channel #14 gain.

+
    +
  • Type: float
  • +
  • Units: Decibels
  • +
  • Range: [-80, 10]
  • +
  • Default: 0
  • +
+
+
FMOD_DSP_CHANNELMIX_GAIN_CH15
+
+

Channel #15 gain.

+
    +
  • Type: float
  • +
  • Units: Decibels
  • +
  • Range: [-80, 10]
  • +
  • Default: 0
  • +
+
+
FMOD_DSP_CHANNELMIX_GAIN_CH16
+
+

Channel #16 gain.

+
    +
  • Type: float
  • +
  • Units: Decibels
  • +
  • Range: [-80, 10]
  • +
  • Default: 0
  • +
+
+
FMOD_DSP_CHANNELMIX_GAIN_CH17
+
+

Channel #17 gain.

+
    +
  • Type: float
  • +
  • Units: Decibels
  • +
  • Range: [-80, 10]
  • +
  • Default: 0
  • +
+
+
FMOD_DSP_CHANNELMIX_GAIN_CH18
+
+

Channel #18 gain.

+
    +
  • Type: float
  • +
  • Units: Decibels
  • +
  • Range: [-80, 10]
  • +
  • Default: 0
  • +
+
+
FMOD_DSP_CHANNELMIX_GAIN_CH19
+
+

Channel #19 gain.

+
    +
  • Type: float
  • +
  • Units: Decibels
  • +
  • Range: [-80, 10]
  • +
  • Default: 0
  • +
+
+
FMOD_DSP_CHANNELMIX_GAIN_CH20
+
+

Channel #20 gain.

+
    +
  • Type: float
  • +
  • Units: Decibels
  • +
  • Range: [-80, 10]
  • +
  • Default: 0
  • +
+
+
FMOD_DSP_CHANNELMIX_GAIN_CH21
+
+

Channel #21 gain.

+
    +
  • Type: float
  • +
  • Units: Decibels
  • +
  • Range: [-80, 10]
  • +
  • Default: 0
  • +
+
+
FMOD_DSP_CHANNELMIX_GAIN_CH22
+
+

Channel #22 gain.

+
    +
  • Type: float
  • +
  • Units: Decibels
  • +
  • Range: [-80, 10]
  • +
  • Default: 0
  • +
+
+
FMOD_DSP_CHANNELMIX_GAIN_CH23
+
+

Channel #23 gain.

+
    +
  • Type: float
  • +
  • Units: Decibels
  • +
  • Range: [-80, 10]
  • +
  • Default: 0
  • +
+
+
FMOD_DSP_CHANNELMIX_GAIN_CH24
+
+

Channel #24 gain.

+
    +
  • Type: float
  • +
  • Units: Decibels
  • +
  • Range: [-80, 10]
  • +
  • Default: 0
  • +
+
+
FMOD_DSP_CHANNELMIX_GAIN_CH25
+
+

Channel #25 gain.

+
    +
  • Type: float
  • +
  • Units: Decibels
  • +
  • Range: [-80, 10]
  • +
  • Default: 0
  • +
+
+
FMOD_DSP_CHANNELMIX_GAIN_CH26
+
+

Channel #26 gain.

+
    +
  • Type: float
  • +
  • Units: Decibels
  • +
  • Range: [-80, 10]
  • +
  • Default: 0
  • +
+
+
FMOD_DSP_CHANNELMIX_GAIN_CH27
+
+

Channel #27 gain.

+
    +
  • Type: float
  • +
  • Units: Decibels
  • +
  • Range: [-80, 10]
  • +
  • Default: 0
  • +
+
+
FMOD_DSP_CHANNELMIX_GAIN_CH28
+
+

Channel #28 gain.

+
    +
  • Type: float
  • +
  • Units: Decibels
  • +
  • Range: [-80, 10]
  • +
  • Default: 0
  • +
+
+
FMOD_DSP_CHANNELMIX_GAIN_CH29
+
+

Channel #29 gain.

+
    +
  • Type: float
  • +
  • Units: Decibels
  • +
  • Range: [-80, 10]
  • +
  • Default: 0
  • +
+
+
FMOD_DSP_CHANNELMIX_GAIN_CH30
+
+

Channel #30 gain.

+
    +
  • Type: float
  • +
  • Units: Decibels
  • +
  • Range: [-80, 10]
  • +
  • Default: 0
  • +
+
+
FMOD_DSP_CHANNELMIX_GAIN_CH31
+
+

Channel #31 gain.

+
    +
  • Type: float
  • +
  • Units: Decibels
  • +
  • Range: [-80, 10]
  • +
  • Default: 0
  • +
+
+
FMOD_DSP_CHANNELMIX_OUTPUT_CH0
+
+

Output channel for Input channel #0

+
    +
  • Type: int
  • +
  • Default: 0
  • +
+
+
FMOD_DSP_CHANNELMIX_OUTPUT_CH1
+
+

Output channel for Input channel #1

+
    +
  • Type: int
  • +
  • Default: 1
  • +
+
+
FMOD_DSP_CHANNELMIX_OUTPUT_CH2
+
+

Output channel for Input channel #2

+
    +
  • Type: int
  • +
  • Default: 2
  • +
+
+
FMOD_DSP_CHANNELMIX_OUTPUT_CH3
+
+

Output channel for Input channel #3

+
    +
  • Type: int
  • +
  • Default: 3
  • +
+
+
FMOD_DSP_CHANNELMIX_OUTPUT_CH4
+
+

Output channel for Input channel #4

+
    +
  • Type: int
  • +
  • Default: 4
  • +
+
+
FMOD_DSP_CHANNELMIX_OUTPUT_CH5
+
+

Output channel for Input channel #5

+
    +
  • Type: int
  • +
  • Default: 5
  • +
+
+
FMOD_DSP_CHANNELMIX_OUTPUT_CH6
+
+

Output channel for Input channel #6

+
    +
  • Type: int
  • +
  • Default: 6
  • +
+
+
FMOD_DSP_CHANNELMIX_OUTPUT_CH7
+
+

Output channel for Input channel #7

+
    +
  • Type: int
  • +
  • Default: 7
  • +
+
+
FMOD_DSP_CHANNELMIX_OUTPUT_CH8
+
+

Output channel for Input channel #8

+
    +
  • Type: int
  • +
  • Default: 8
  • +
+
+
FMOD_DSP_CHANNELMIX_OUTPUT_CH9
+
+

Output channel for Input channel #9

+
    +
  • Type: int
  • +
  • Default: 9
  • +
+
+
FMOD_DSP_CHANNELMIX_OUTPUT_CH10
+
+

Output channel for Input channel #10

+
    +
  • Type: int
  • +
  • Default: 10
  • +
+
+
FMOD_DSP_CHANNELMIX_OUTPUT_CH11
+
+

Output channel for Input channel #11

+
    +
  • Type: int
  • +
  • Default: 11
  • +
+
+
FMOD_DSP_CHANNELMIX_OUTPUT_CH12
+
+

Output channel for Input channel #12

+
    +
  • Type: int
  • +
  • Default: 12
  • +
+
+
FMOD_DSP_CHANNELMIX_OUTPUT_CH13
+
+

Output channel for Input channel #13

+
    +
  • Type: int
  • +
  • Default: 13
  • +
+
+
FMOD_DSP_CHANNELMIX_OUTPUT_CH14
+
+

Output channel for Input channel #14

+
    +
  • Type: int
  • +
  • Default: 14
  • +
+
+
FMOD_DSP_CHANNELMIX_OUTPUT_CH15
+
+

Output channel for Input channel #15

+
    +
  • Type: int
  • +
  • Default: 15
  • +
+
+
FMOD_DSP_CHANNELMIX_OUTPUT_CH16
+
+

Output channel for Input channel #16

+
    +
  • Type: int
  • +
  • Default: 16
  • +
+
+
FMOD_DSP_CHANNELMIX_OUTPUT_CH17
+
+

Output channel for Input channel #17

+
    +
  • Type: int
  • +
  • Default: 17
  • +
+
+
FMOD_DSP_CHANNELMIX_OUTPUT_CH18
+
+

Output channel for Input channel #18

+
    +
  • Type: int
  • +
  • Default: 18
  • +
+
+
FMOD_DSP_CHANNELMIX_OUTPUT_CH19
+
+

Output channel for Input channel #19

+
    +
  • Type: int
  • +
  • Default: 19
  • +
+
+
FMOD_DSP_CHANNELMIX_OUTPUT_CH20
+
+

Output channel for Input channel #20

+
    +
  • Type: int
  • +
  • Default: 20
  • +
+
+
FMOD_DSP_CHANNELMIX_OUTPUT_CH21
+
+

Output channel for Input channel #21

+
    +
  • Type: int
  • +
  • Default: 21
  • +
+
+
FMOD_DSP_CHANNELMIX_OUTPUT_CH22
+
+

Output channel for Input channel #22

+
    +
  • Type: int
  • +
  • Default: 22
  • +
+
+
FMOD_DSP_CHANNELMIX_OUTPUT_CH23
+
+

Output channel for Input channel #23

+
    +
  • Type: int
  • +
  • Default: 23
  • +
+
+
FMOD_DSP_CHANNELMIX_OUTPUT_CH24
+
+

Output channel for Input channel #24

+
    +
  • Type: int
  • +
  • Default: 24
  • +
+
+
FMOD_DSP_CHANNELMIX_OUTPUT_CH25
+
+

Output channel for Input channel #25

+
    +
  • Type: int
  • +
  • Default: 25
  • +
+
+
FMOD_DSP_CHANNELMIX_OUTPUT_CH26
+
+

Output channel for Input channel #26

+
    +
  • Type: int
  • +
  • Default: 26
  • +
+
+
FMOD_DSP_CHANNELMIX_OUTPUT_CH27
+
+

Output channel for Input channel #27

+
    +
  • Type: int
  • +
  • Default: 27
  • +
+
+
FMOD_DSP_CHANNELMIX_OUTPUT_CH28
+
+

Output channel for Input channel #28

+
    +
  • Type: int
  • +
  • Default: 28
  • +
+
+
FMOD_DSP_CHANNELMIX_OUTPUT_CH29
+
+

Output channel for Input channel #29

+
    +
  • Type: int
  • +
  • Default: 29
  • +
+
+
FMOD_DSP_CHANNELMIX_OUTPUT_CH30
+
+

Output channel for Input channel #30

+
    +
  • Type: int
  • +
  • Default: 30
  • +
+
+
FMOD_DSP_CHANNELMIX_OUTPUT_CH31
+
+

Output channel for Input channel #31

+
    +
  • Type: int
  • +
  • Default: 31
  • +
+
+
+

For FMOD_DSP_CHANNELMIX_OUTPUTGROUPING, this value will set the output speaker format for the DSP. This determines the number of output channels.

+

If an input channel is mapped to an output channel in excess of the number of output channels, the input channel is instead mapped to the modulo of that channel's index. E.g.: If there are 4 output channels, an input channel mapped to output channel index 5 is mapped to index 1.

+

See Also: FMOD_DSP_TYPE_CHANNELMIX, DSP::setParameterInt, DSP::setParameterFloat, FMOD_DSP_TYPE

+

FMOD_DSP_CHANNELMIX_OUTPUT

+

Channel mix DSP output grouping types for the FMOD_DSP_CHANNELMIX_OUTPUTGROUPING parameter. Output grouping sets the output speaker format for the Channel Mix DSP. This determines the number of output channels.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
typedef enum FMOD_DSP_CHANNELMIX_OUTPUT {
+  FMOD_DSP_CHANNELMIX_OUTPUT_DEFAULT,
+  FMOD_DSP_CHANNELMIX_OUTPUT_ALLMONO,
+  FMOD_DSP_CHANNELMIX_OUTPUT_ALLSTEREO,
+  FMOD_DSP_CHANNELMIX_OUTPUT_ALLQUAD,
+  FMOD_DSP_CHANNELMIX_OUTPUT_ALL5POINT1,
+  FMOD_DSP_CHANNELMIX_OUTPUT_ALL7POINT1,
+  FMOD_DSP_CHANNELMIX_OUTPUT_ALLLFE,
+  FMOD_DSP_CHANNELMIX_OUTPUT_ALL7POINT1POINT4
+} FMOD_DSP_CHANNELMIX_OUTPUT;
+
+ +
enum DSP_CHANNELMIX_OUTPUT
+{
+  DEFAULT,
+  ALLMONO,
+  ALLSTEREO,
+  ALLQUAD,
+  ALL5POINT1,
+  ALL7POINT1,
+  ALLLFE,
+  ALL7POINT1POINT4
+}
+
+ +
FMOD.DSP_CHANNELMIX_OUTPUT_DEFAULT
+FMOD.DSP_CHANNELMIX_OUTPUT_ALLMONO
+FMOD.DSP_CHANNELMIX_OUTPUT_ALLSTEREO
+FMOD.DSP_CHANNELMIX_OUTPUT_ALLQUAD
+FMOD.DSP_CHANNELMIX_OUTPUT_ALL5POINT1
+FMOD.DSP_CHANNELMIX_OUTPUT_ALL7POINT1
+FMOD.DSP_CHANNELMIX_OUTPUT_ALLLFE
+FMOD.DSP_CHANNELMIX_OUTPUT_ALL7POINT1POINT4
+
+ +
+
FMOD_DSP_CHANNELMIX_OUTPUT_DEFAULT
+
Output channel count = input channel count. Mapping: See FMOD_SPEAKER enumeration.
+
FMOD_DSP_CHANNELMIX_OUTPUT_ALLMONO
+
Output channel count = 1. Mapping: Mono, Mono, Mono, Mono, Mono, Mono, ... (each channel all the way up to FMOD_MAX_CHANNEL_WIDTH channels are treated as if they were mono)
+
FMOD_DSP_CHANNELMIX_OUTPUT_ALLSTEREO
+
Output channel count = 2. Mapping: Left, Right, Left, Right, Left, Right, ... (each pair of channels is treated as stereo all the way up to FMOD_MAX_CHANNEL_WIDTH channels)
+
FMOD_DSP_CHANNELMIX_OUTPUT_ALLQUAD
+
Output channel count = 4. Mapping: Repeating pattern of Front Left, Front Right, Surround Left, Surround Right.
+
FMOD_DSP_CHANNELMIX_OUTPUT_ALL5POINT1
+
Output channel count = 6. Mapping: Repeating pattern of Front Left, Front Right, Center, LFE, Surround Left, Surround Right.
+
FMOD_DSP_CHANNELMIX_OUTPUT_ALL7POINT1
+
Output channel count = 8. Mapping: Repeating pattern of Front Left, Front Right, Center, LFE, Surround Left, Surround Right, Back Left, Back Right.
+
FMOD_DSP_CHANNELMIX_OUTPUT_ALLLFE
+
Output channel count = 6. Mapping: Repeating pattern of LFE in a 5.1 output signal.
+
FMOD_DSP_CHANNELMIX_OUTPUT_ALL7POINT1POINT4
+
Output channel count = 12. Mapping: Repeating pattern of Front Left, Front Right, Center, LFE, Surround Left, Surround Right, Back Left, Back Right, Top Front Left, Top Front Right, Top Back Left, Top Back Right.
+
+

See Also: FMOD_DSP_CHANNELMIX_OUTPUTGROUPING, FMOD_DSP_TYPE_CHANNELMIX, DSP::setParameterInt, DSP::getParameterInt, FMOD_DSP_TYPE

+

FMOD_DSP_CHORUS

+

Chorus DSP parameter types.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
typedef enum FMOD_DSP_CHORUS {
+  FMOD_DSP_CHORUS_MIX,
+  FMOD_DSP_CHORUS_RATE,
+  FMOD_DSP_CHORUS_DEPTH
+} FMOD_DSP_CHORUS;
+
+ +
enum DSP_CHORUS
+{
+  MIX,
+  RATE,
+  DEPTH,
+}
+
+ +
FMOD.DSP_CHORUS_MIX
+FMOD.DSP_CHORUS_RATE
+FMOD.DSP_CHORUS_DEPTH
+
+ +
+
FMOD_DSP_CHORUS_MIX
+
+

Percentage of wet signal in mix.

+
    +
  • Type: float
  • +
  • Units: Percentage
  • +
  • Range: [0, 100]
  • +
  • Default: 50
  • +
+
+
FMOD_DSP_CHORUS_RATE
+
+

Chorus modulation rate.

+
    +
  • Type: float
  • +
  • Units: Hertz
  • +
  • Range: [0, 20]
  • +
  • Default: 0.8
  • +
+
+
FMOD_DSP_CHORUS_DEPTH
+
+

Chorus modulation depth.

+
    +
  • Type: float
  • +
  • Units: Milliseconds
  • +
  • Range: [0, 100]
  • +
  • Default: 3
  • +
+
+
+

Chorus is an effect where the sound is more 'spacious' due a copy of the signal being played along side the original, but with the delay of each copy modulating on a sine wave. As there are 2 versions of the same signal (dry vs wet), by default each signal is given 50% mix, so that the total is not louder than the original unaffected signal.

+

See Also: FMOD_DSP_TYPE_CHORUS, DSP::setParameterFloat, DSP::getParameterFloat, FMOD_DSP_TYPE

+

FMOD_DSP_COMPRESSOR

+

Compressor DSP parameter types.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
typedef enum FMOD_DSP_COMPRESSOR {
+  FMOD_DSP_COMPRESSOR_THRESHOLD,
+  FMOD_DSP_COMPRESSOR_RATIO,
+  FMOD_DSP_COMPRESSOR_ATTACK,
+  FMOD_DSP_COMPRESSOR_RELEASE,
+  FMOD_DSP_COMPRESSOR_GAINMAKEUP,
+  FMOD_DSP_COMPRESSOR_USESIDECHAIN,
+  FMOD_DSP_COMPRESSOR_LINKED
+} FMOD_DSP_COMPRESSOR;
+
+ +
enum DSP_COMPRESSOR
+{
+  THRESHOLD,
+  RATIO,
+  ATTACK,
+  RELEASE,
+  GAINMAKEUP,
+  USESIDECHAIN,
+  LINKED
+}
+
+ +
FMOD.DSP_COMPRESSOR_THRESHOLD
+FMOD.DSP_COMPRESSOR_RATIO
+FMOD.DSP_COMPRESSOR_ATTACK
+FMOD.DSP_COMPRESSOR_RELEASE
+FMOD.DSP_COMPRESSOR_GAINMAKEUP
+FMOD.DSP_COMPRESSOR_USESIDECHAIN
+FMOD.DSP_COMPRESSOR_LINKED
+
+ +
+
FMOD_DSP_COMPRESSOR_THRESHOLD
+
+

Threshold level.

+
    +
  • Type: float
  • +
  • Units: Decibels
  • +
  • Range: [-60, 0]
  • +
  • Default: 0
  • +
+
+
FMOD_DSP_COMPRESSOR_RATIO
+
+

Compression Ratio.

+
    +
  • Type: float
  • +
  • Units: Linear
  • +
  • Range: [1, 50]
  • +
  • Default: 2.5
  • +
+
+
FMOD_DSP_COMPRESSOR_ATTACK
+
+

Attack time.

+
    +
  • Type: float
  • +
  • Units: Milliseconds
  • +
  • Range: [0.1, 500]
  • +
  • Default: 20
  • +
+
+
FMOD_DSP_COMPRESSOR_RELEASE
+
+

Release time.

+
    +
  • Type: float
  • +
  • Units: Milliseconds
  • +
  • Range: [10, 5000]
  • +
  • Default: 100
  • +
+
+
FMOD_DSP_COMPRESSOR_GAINMAKEUP
+
+

Make-up gain applied after limiting.

+
    +
  • Type: float
  • +
  • Units: Decibels
  • +
  • Range: [-30, 30]
  • +
  • Default: 0
  • +
+
+
FMOD_DSP_COMPRESSOR_USESIDECHAIN
+
Data of type FMOD_DSP_PARAMETER_SIDECHAIN. Whether to analyse the sidechain signal instead of the input signal. The FMOD_DSP_PARAMETER_SIDECHAIN::sidechainenable default is false.
+
FMOD_DSP_COMPRESSOR_LINKED
+
+

false = Independent (compressor per channel), true = Linked. If the channel count of the sidechain signal is different to the input signal, it will be forced into linked mode.

+
    +
  • Type: bool
  • +
  • Default: true
  • +
+
+
+

This is a multi-channel software limiter that is uniform across the whole spectrum.
+The limiter is not guaranteed to catch every peak above the threshold level, because it cannot apply gain reduction instantaneously - the time delay is determined by the attack time. However setting the attack time too short will distort the sound, so it is a compromise. High level peaks can be avoided by using a short attack time - but not too short, and setting the threshold a few decibels below the critical level.

+

See Also: FMOD_DSP_TYPE_COMPRESSOR, DSP::setParameterFloat, DSP::setParameterBool

+

FMOD_DSP_CONVOLUTION_REVERB

+

Convolution reverb DSP parameter types.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
typedef enum FMOD_DSP_CONVOLUTION_REVERB {
+  FMOD_DSP_CONVOLUTION_REVERB_PARAM_IR,
+  FMOD_DSP_CONVOLUTION_REVERB_PARAM_WET,
+  FMOD_DSP_CONVOLUTION_REVERB_PARAM_DRY,
+  FMOD_DSP_CONVOLUTION_REVERB_PARAM_LINKED
+} FMOD_DSP_CONVOLUTION_REVERB;
+
+ +
enum DSP_CONVOLUTION_REVERB
+{
+  IR,
+  WET,
+  DRY,
+  LINKED
+}
+
+ +
FMOD.DSP_CONVOLUTION_REVERB_PARAM_IR
+FMOD.DSP_CONVOLUTION_REVERB_PARAM_WET
+FMOD.DSP_CONVOLUTION_REVERB_PARAM_DRY
+FMOD.DSP_CONVOLUTION_REVERB_PARAM_LINKED
+
+ +
+
FMOD_DSP_CONVOLUTION_REVERB_PARAM_IR
+
Array of signed 16-bit (short) PCM data to be used as reverb impulse response. First member of the array should be a 16 bit value (short) which specifies the number of channels. Array looks like [index 0=numchannels][index 1+ = raw 16 bit PCM data]. Data is copied internally so source can be freed.
+
FMOD_DSP_CONVOLUTION_REVERB_PARAM_WET
+
+

Volume of echo signal to pass to output.

+
    +
  • Type: float
  • +
  • Units: Decibels
  • +
  • Range: [-80, 10]
  • +
  • Default: 0
  • +
+
+
FMOD_DSP_CONVOLUTION_REVERB_PARAM_DRY
+
+

Original sound volume.

+
    +
  • Type: float
  • +
  • Units: Decibels
  • +
  • Range: [-80, 10]
  • +
  • Default: 0
  • +
+
+
FMOD_DSP_CONVOLUTION_REVERB_PARAM_LINKED
+
+

Linked - channels are mixed together before processing through the reverb.

+
    +
  • Type: bool
  • +
  • Default: true
  • +
+
+
+

Convolution reverb is a reverberation effect that uses a recording of a physical space known as an Impulse Response file (or IR file) to generate frequency specific reverberation.

+

See Also: FMOD_DSP_TYPE_CONVOLUTIONREVERB, DSP::setParameterFloat, DSP::setParameterData

+

FMOD_DSP_DELAY

+

Delay DSP parameter types.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
typedef enum FMOD_DSP_DELAY {
+  FMOD_DSP_DELAY_CH0,
+  FMOD_DSP_DELAY_CH1,
+  FMOD_DSP_DELAY_CH2,
+  FMOD_DSP_DELAY_CH3,
+  FMOD_DSP_DELAY_CH4,
+  FMOD_DSP_DELAY_CH5,
+  FMOD_DSP_DELAY_CH6,
+  FMOD_DSP_DELAY_CH7,
+  FMOD_DSP_DELAY_CH8,
+  FMOD_DSP_DELAY_CH9,
+  FMOD_DSP_DELAY_CH10,
+  FMOD_DSP_DELAY_CH11,
+  FMOD_DSP_DELAY_CH12,
+  FMOD_DSP_DELAY_CH13,
+  FMOD_DSP_DELAY_CH14,
+  FMOD_DSP_DELAY_CH15,
+  FMOD_DSP_DELAY_MAXDELAY
+} FMOD_DSP_DELAY;
+
+ +
enum DSP_DELAY
+{
+  CH0,
+  CH1,
+  CH2,
+  CH3,
+  CH4,
+  CH5,
+  CH6,
+  CH7,
+  CH8,
+  CH9,
+  CH10,
+  CH11,
+  CH12,
+  CH13,
+  CH14,
+  CH15,
+  MAXDELAY,
+}
+
+ +
FMOD.DSP_DELAY_CH0
+FMOD.DSP_DELAY_CH1
+FMOD.DSP_DELAY_CH2
+FMOD.DSP_DELAY_CH3
+FMOD.DSP_DELAY_CH4
+FMOD.DSP_DELAY_CH5
+FMOD.DSP_DELAY_CH6
+FMOD.DSP_DELAY_CH7
+FMOD.DSP_DELAY_CH8
+FMOD.DSP_DELAY_CH9
+FMOD.DSP_DELAY_CH10
+FMOD.DSP_DELAY_CH11
+FMOD.DSP_DELAY_CH12
+FMOD.DSP_DELAY_CH13
+FMOD.DSP_DELAY_CH14
+FMOD.DSP_DELAY_CH15
+FMOD.DSP_DELAY_MAXDELAY
+
+ +
+
FMOD_DSP_DELAY_CH0
+
+

Channel #0 Delay.

+
    +
  • Type: float
  • +
  • Units: Milliseconds
  • +
  • Range: [0, 10000]
  • +
  • Default: 0
  • +
+
+
FMOD_DSP_DELAY_CH1
+
+

Channel #1 Delay.

+
    +
  • Type: float
  • +
  • Units: Milliseconds
  • +
  • Range: [0, 10000]
  • +
  • Default: 0
  • +
+
+
FMOD_DSP_DELAY_CH2
+
+

Channel #2 Delay.

+
    +
  • Type: float
  • +
  • Units: Milliseconds
  • +
  • Range: [0, 10000]
  • +
  • Default: 0
  • +
+
+
FMOD_DSP_DELAY_CH3
+
+

Channel #3 Delay.

+
    +
  • Type: float
  • +
  • Units: Milliseconds
  • +
  • Range: [0, 10000]
  • +
  • Default: 0
  • +
+
+
FMOD_DSP_DELAY_CH4
+
+

Channel #4 Delay.

+
    +
  • Type: float
  • +
  • Units: Milliseconds
  • +
  • Range: [0, 10000]
  • +
  • Default: 0
  • +
+
+
FMOD_DSP_DELAY_CH5
+
+

Channel #5 Delay.

+
    +
  • Type: float
  • +
  • Units: Milliseconds
  • +
  • Range: [0, 10000]
  • +
  • Default: 0
  • +
+
+
FMOD_DSP_DELAY_CH6
+
+

Channel #6 Delay.

+
    +
  • Type: float
  • +
  • Units: Milliseconds
  • +
  • Range: [0, 10000]
  • +
  • Default: 0
  • +
+
+
FMOD_DSP_DELAY_CH7
+
+

Channel #7 Delay.

+
    +
  • Type: float
  • +
  • Units: Milliseconds
  • +
  • Range: [0, 10000]
  • +
  • Default: 0
  • +
+
+
FMOD_DSP_DELAY_CH8
+
+

Channel #8 Delay.

+
    +
  • Type: float
  • +
  • Units: Milliseconds
  • +
  • Range: [0, 10000]
  • +
  • Default: 0
  • +
+
+
FMOD_DSP_DELAY_CH9
+
+

Channel #9 Delay.

+
    +
  • Type: float
  • +
  • Units: Milliseconds
  • +
  • Range: [0, 10000]
  • +
  • Default: 0
  • +
+
+
FMOD_DSP_DELAY_CH10
+
+

Channel #10 Delay.

+
    +
  • Type: float
  • +
  • Units: Milliseconds
  • +
  • Range: [0, 10000]
  • +
  • Default: 0
  • +
+
+
FMOD_DSP_DELAY_CH11
+
+

Channel #11 Delay.

+
    +
  • Type: float
  • +
  • Units: Milliseconds
  • +
  • Range: [0, 10000]
  • +
  • Default: 0
  • +
+
+
FMOD_DSP_DELAY_CH12
+
+

Channel #12 Delay.

+
    +
  • Type: float
  • +
  • Units: Milliseconds
  • +
  • Range: [0, 10000]
  • +
  • Default: 0
  • +
+
+
FMOD_DSP_DELAY_CH13
+
+

Channel #13 Delay.

+
    +
  • Type: float
  • +
  • Units: Milliseconds
  • +
  • Range: [0, 10000]
  • +
  • Default: 0
  • +
+
+
FMOD_DSP_DELAY_CH14
+
+

Channel #14 Delay.

+
    +
  • Type: float
  • +
  • Units: Milliseconds
  • +
  • Range: [0, 10000]
  • +
  • Default: 0
  • +
+
+
FMOD_DSP_DELAY_CH15
+
+

Channel #15 Delay.

+
    +
  • Type: float
  • +
  • Units: Milliseconds
  • +
  • Range: [0, 10000]
  • +
  • Default: 0
  • +
+
+
FMOD_DSP_DELAY_MAXDELAY
+
+

Maximum delay, for memory allocation purposes.

+
    +
  • Type: float
  • +
  • Units: Milliseconds
  • +
  • Range: [0, 10000]
  • +
  • Default: 10
  • +
+
+
+

Every time MaxDelay is changed, the plug-in re-allocates the delay buffer. This means the delay disappears at that time while it refills its new buffer. A larger MaxDelay results in larger amounts of memory allocated.

+

Channel delays above MaxDelay will be clipped to MaxDelay and the delay buffer will not be resized.

+

See Also: FMOD_DSP_TYPE_DELAY, DSP::setParameterFloat

+

FMOD_DSP_DISTORTION

+

Distortion DSP parameter types.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
typedef enum FMOD_DSP_DISTORTION {
+  FMOD_DSP_DISTORTION_LEVEL
+} FMOD_DSP_DISTORTION;
+
+ +
enum DSP_DISTORTION
+{
+  LEVEL
+}
+
+ +
FMOD.DSP_DISTORTION_LEVEL
+
+ +
+
FMOD_DSP_DISTORTION_LEVEL
+
+

Distortion value.

+
    +
  • Type: float
  • +
  • Units: Linear
  • +
  • Range: [0, 1]
  • +
  • Default: 0.5
  • +
+
+
+

See Also: FMOD_DSP_TYPE_DISTORTION, DSP::setParameterFloat

+

FMOD_DSP_ECHO

+

Echo DSP parameter types.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
typedef enum FMOD_DSP_ECHO {
+  FMOD_DSP_ECHO_DELAY,
+  FMOD_DSP_ECHO_FEEDBACK,
+  FMOD_DSP_ECHO_DRYLEVEL,
+  FMOD_DSP_ECHO_WETLEVEL,
+  FMOD_DSP_ECHO_DELAYCHANGEMODE
+} FMOD_DSP_ECHO;
+
+ +
enum DSP_ECHO
+{
+  DELAY,
+  FEEDBACK,
+  DRYLEVEL,
+  WETLEVEL,
+  DELAYCHANGEMODE
+}
+
+ +
FMOD.DSP_ECHO_DELAY
+FMOD.DSP_ECHO_FEEDBACK
+FMOD.DSP_ECHO_DRYLEVEL
+FMOD.DSP_ECHO_WETLEVEL
+FMOD.DSP_ECHO_DELAYCHANGEMODE
+
+ +
+
FMOD_DSP_ECHO_DELAY
+
+

Echo delay.

+
    +
  • Type: float
  • +
  • Units: Milliseconds
  • +
  • Range: [1, 5000]
  • +
  • Default: 500
  • +
+
+
FMOD_DSP_ECHO_FEEDBACK
+
+

Echo decay per delay. 100.0 = No decay, 0.0 = total decay.

+
    +
  • Type: float
  • +
  • Units: Percentage
  • +
  • Range: [0, 100]
  • +
  • Default: 50
  • +
+
+
FMOD_DSP_ECHO_DRYLEVEL
+
+

Original sound volume.

+
    +
  • Type: float
  • +
  • Units: Decibels
  • +
  • Range: [-80, 10]
  • +
  • Default: 0
  • +
+
+
FMOD_DSP_ECHO_WETLEVEL
+
+

Volume of echo signal to pass to output.

+
    +
  • Type: float
  • +
  • Units: Decibels
  • +
  • Range: [-80, 10]
  • +
  • Default: 0
  • +
+
+
FMOD_DSP_ECHO_DELAYCHANGEMODE
+
+

The method used to smooth delay changes.

+ +
+
+

Every time the delay is changed, the plug-in reallocates the echo buffer. This means the echo disappears at that time while it refills its new buffer. Larger echo delays result in larger amounts of memory allocated.

+

See Also: FMOD_DSP_TYPE_ECHO, DSP::setParameterFloat

+

FMOD_DSP_ECHO_DELAYCHANGEMODE_TYPE

+

Options for smoothing delay changes in the echo effect.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
typedef enum FMOD_DSP_ECHO_DELAYCHANGEMODE_TYPE {
+    FMOD_DSP_ECHO_DELAYCHANGEMODE_FADE,
+    FMOD_DSP_ECHO_DELAYCHANGEMODE_LERP,
+    FMOD_DSP_ECHO_DELAYCHANGEMODE_NONE
+} FMOD_DSP_ECHO_DELAYCHANGEMODE_TYPE;
+
+ +
enum DSP_ECHO_DELAYCHANGEMODE_TYPE
+{
+    FADE,
+    LERP,
+    NONE
+}
+
+ +
    FMOD.DSP_ECHO_DELAYCHANGEMODE_FADE,
+    FMOD.DSP_ECHO_DELAYCHANGEMODE_LERP,
+    FMOD.DSP_ECHO_DELAYCHANGEMODE_NONE
+
+ +
+
FMOD_DSP_ECHO_DELAYCHANGEMODE_FADE
+
The ramp delay change mode will fade-in the new delay value and fade-out the old delay value. This is best suited for large, fast parameter changes.
+
FMOD_DSP_ECHO_DELAYCHANGEMODE_LERP
+
The lerp delay change mode will use linear interpolation to approach the new delay target. This is best suited for small, slow parameter changes, and for emulating the doppler effect.
+
FMOD_DSP_ECHO_DELAYCHANGEMODE_NONE
+
The none delay change mode will disable value smoothing between delay changes.
+
+

See Also: FMOD_DSP_ECHO_DELAYCHANGEMODE

+

FMOD_DSP_FADER

+

Fader DSP parameter types.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
typedef enum FMOD_DSP_FADER {
+  FMOD_DSP_FADER_GAIN,
+  FMOD_DSP_FADER_OVERALL_GAIN
+} FMOD_DSP_FADER;
+
+ +
enum DSP_FADER
+{
+  GAIN,
+  OVERALL_GAIN,
+}
+
+ +
+

Not supported for JavaScript.

+
+
+
FMOD_DSP_FADER_GAIN
+
+

Signal gain.

+
    +
  • Type: float
  • +
  • Units: Decibels
  • +
  • Range: [-80, 10]
  • +
  • Default: 0
  • +
+
+
FMOD_DSP_FADER_OVERALL_GAIN
+
+

Overall gain to allow FMOD to know the DSP is scaling the signal for visualization purposes.

+ +
+
+

See Also: FMOD_DSP_TYPE_FADER, DSP::setParameterFloat

+

FMOD_DSP_FFT

+

FFT DSP parameter types.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
typedef enum FMOD_DSP_FFT {
+  FMOD_DSP_FFT_WINDOWSIZE,
+  FMOD_DSP_FFT_WINDOW,
+  FMOD_DSP_FFT_BAND_START_FREQ,
+  FMOD_DSP_FFT_BAND_STOP_FREQ,
+  FMOD_DSP_FFT_SPECTRUMDATA,
+  FMOD_DSP_FFT_RMS,
+  FMOD_DSP_FFT_SPECTRAL_CENTROID,
+  FMOD_DSP_FFT_IMMEDIATE_MODE,
+  FMOD_DSP_FFT_DOWNMIX,
+  FMOD_DSP_FFT_CHANNEL
+} FMOD_DSP_FFT;
+
+ +
enum DSP_FFT
+{
+    WINDOWSIZE,
+    WINDOW,
+    BAND_START_FREQ,
+    BAND_STOP_FREQ,
+    SPECTRUMDATA,
+    RMS,
+    SPECTRAL_CENTROID,
+    IMMEDIATE_MODE,
+    DOWNMIX,
+    CHANNEL
+}
+
+ +
FMOD.DSP_FFT_WINDOWSIZE
+FMOD.DSP_FFT_WINDOW
+FMOD.DSP_FFT_BAND_START_FREQ
+FMOD.DSP_FFT_BAND_STOP_FREQ
+FMOD.DSP_FFT_SPECTRUMDATA
+FMOD.DSP_FFT_RMS
+FMOD.DSP_FFT_SPECTRAL_CENTROID
+FMOD.DSP_FFT_IMMEDIATE_MODE
+FMOD.DSP_FFT_DOWNMIX
+FMOD.DSP_FFT_CHANNEL
+
+ +
+
FMOD_DSP_FFT_WINDOWSIZE
+
+

Window size. Must be a power of 2 between 128 and 16384.

+
    +
  • Type: int
  • +
  • Default: 2048
  • +
+
+
FMOD_DSP_FFT_WINDOW
+
+

FFT Window Type.

+ +
+
FMOD_DSP_FFT_BAND_START_FREQ
+
+

The start frequency of the analysis band.

+
    +
  • Type: float
  • +
  • Default: 0
  • +
+
+
FMOD_DSP_FFT_BAND_STOP_FREQ
+
+

The stop frequency of the analysis band.

+
    +
  • Type: float
  • +
  • Default: 22000
  • +
+
+
FMOD_DSP_FFT_SPECTRUMDATA R/O
+
+

Returns the current spectrum values between 0 and 1 for each 'fft bin'. Divide the Nyquist frequency by the window size to get the hz value per entry.

+ +
+
FMOD_DSP_FFT_RMS R/O
+
+

The total RMS value of the spectral components within the analysis band.

+
    +
  • Type: float
  • +
+
+
FMOD_DSP_FFT_SPECTRAL_CENTROID R/O
+
+

Returns the centroid of the spectral components within the analysis band for the first channel.

+
    +
  • Type: float
  • +
+
+
FMOD_DSP_FFT_IMMEDIATE_MODE
+
+

Immediate Mode. False = data requests will have a delay on first time use and hardware acceleration, if available, will be used. True = data requests will have no delay on first time use, and no hardware acceleration will be used.

+
    +
  • Type: bool
  • +
  • Default: false
  • +
+
+
FMOD_DSP_FFT_DOWNMIX
+
+

Downmix mode. If set to FMOD_DSP_FFT_DOWNMIX_MONO, the DSP will downmix the input signal to mono before analysis, producing a single spectrum. Note that this only affects the analysis - the DSP will pass the unmodified signal through to its output regardless of the downmix setting.

+ +
+
FMOD_DSP_FFT_CHANNEL
+
+

The channel to analyze. If set to -1, all channels will be analyzed, producing multiple spectra. Otherwise only the specified channel will be analyzed, producing a single spectrum.

+
    +
  • Type: int
  • +
  • Default: -1
  • +
+
+
+

Set the attributes for the spectrum analysis with FMOD_DSP_FFT_WINDOWSIZE, FMOD_DSP_FFT_WINDOW, FMOD_DSP_FFT_BAND_START_FREQ, FMOD_DSP_FFT_BAND_STOP_FREQ, FMOD_DSP_FFT_DOWNMIX, and FMOD_DSP_FFT_CHANNEL.
+Retrieve the results with FMOD_DSP_FFT_SPECTRUMDATA, FMOD_DSP_FFT_RMS and FMOD_DSP_FFT_SPECTRAL_CENTROID.
+FMOD_DSP_FFT_SPECTRUMDATA stores its data in the FMOD_DSP_PARAMETER_DATA_TYPE_FFT. You will need to cast to this structure to get the right data.

+

See Also: FMOD_DSP_TYPE_FFT, DSP::setParameterFloat, DSP::setParameterInt, DSP::setParameterData, FMOD_DSP_FFT_WINDOW_TYPE

+

FMOD_DSP_FFT_DOWNMIX_TYPE

+

List of downmix modes for the FFT DSP.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
typedef enum FMOD_DSP_FFT_DOWNMIX_TYPE {
+  FMOD_DSP_FFT_DOWNMIX_NONE,
+  FMOD_DSP_FFT_DOWNMIX_MONO
+} FMOD_DSP_FFT_DOWNMIX_TYPE;
+
+ +
enum DSP_FFT_DOWNMIX_TYPE
+{
+  NONE,
+  MONO
+}
+
+ +
FMOD.DSP_FFT_DOWNMIX_NONE
+FMOD.DSP_FFT_DOWNMIX_MONO
+
+ +
+
FMOD_DSP_FFT_DOWNMIX_NONE
+
No downmix.
+
FMOD_DSP_FFT_DOWNMIX_MONO
+
Downmix to mono.
+
+

Used to specify the downmix applied by the FFT DSP before spectrum analysis.

+

See Also: FMOD_DSP_FFT, FMOD_DSP_TYPE_FFT

+

FMOD_DSP_FFT_WINDOW_TYPE

+

List of windowing methods for the FFT DSP.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
typedef enum FMOD_DSP_FFT_WINDOW_TYPE {
+  FMOD_DSP_FFT_WINDOW_RECT,
+  FMOD_DSP_FFT_WINDOW_TRIANGLE,
+  FMOD_DSP_FFT_WINDOW_HAMMING,
+  FMOD_DSP_FFT_WINDOW_HANNING,
+  FMOD_DSP_FFT_WINDOW_BLACKMAN,
+  FMOD_DSP_FFT_WINDOW_BLACKMANHARRIS
+} FMOD_DSP_FFT_WINDOW_TYPE;
+
+ +
enum DSP_FFT_WINDOW_TYPE
+{
+  RECT,
+  TRIANGLE,
+  HAMMING,
+  HANNING,
+  BLACKMAN,
+  BLACKMANHARRIS
+}
+
+ +
FMOD.DSP_FFT_WINDOW_RECT
+FMOD.DSP_FFT_WINDOW_TRIANGLE
+FMOD.DSP_FFT_WINDOW_HAMMING
+FMOD.DSP_FFT_WINDOW_HANNING
+FMOD.DSP_FFT_WINDOW_BLACKMAN
+FMOD.DSP_FFT_WINDOW_BLACKMANHARRIS
+
+ +
+
FMOD_DSP_FFT_WINDOW_RECT
+
w[n] = 1.0
+
FMOD_DSP_FFT_WINDOW_TRIANGLE
+
w[n] = TRI(2n/N)
+
FMOD_DSP_FFT_WINDOW_HAMMING
+
w[n] = 0.54 - (0.46 * COS(n/N) )
+
FMOD_DSP_FFT_WINDOW_HANNING
+
w[n] = 0.5 * (1.0 - COS(n/N) )
+
FMOD_DSP_FFT_WINDOW_BLACKMAN
+
w[n] = 0.42 - (0.5 * COS(n/N) ) + (0.08 * COS(2.0 * n/N) )
+
FMOD_DSP_FFT_WINDOW_BLACKMANHARRIS
+
w[n] = 0.35875 - (0.48829 * COS(1.0 * n/N)) + (0.14128 * COS(2.0 * n/N)) - (0.01168 * COS(3.0 * n/N))
+
+

Used in spectrum analysis to reduce leakage / transient signals interfering with the analysis. This is a problem with analysis of continuous signals that only have a small portion of the signal sample (the fft window size). Windowing the signal with a curve or triangle tapers the sides of the fft window to help alleviate this problem.

+

Cyclic signals such as a sine wave that repeat their cycle in a multiple of the window size do not need windowing. I.e. If the sine wave repeats every 1024, 512, 256 etc samples and the FMOD fft window is 1024, then the signal would not need windowing.

+

Not windowing is represented by FMOD_DSP_FFT_WINDOW_RECT. If the cycle of the signal (ie the sine wave) is not a multiple of the window size, it will cause frequency abnormalities, so a different windowing method is needed.

+

FMOD_DSP_FFT_WINDOW_RECT

+

FFT Window Rectangle

+

FMOD_DSP_FFT_WINDOW_TRIANGLE

+

FFT Window Triangle

+

FMOD_DSP_FFT_WINDOW_HAMMING

+

FFT Window Hamming

+

FMOD_DSP_FFT_WINDOW_HANNING

+

FFT Window Hanning

+

FMOD_DSP_FFT_WINDOW_BLACKMAN

+

FFT Window Blackman

+

FMOD_DSP_FFT_WINDOW_BLACKMANHARRIS

+

FFT Window Blackman Harris

+

See Also: FMOD_DSP_FFT, FMOD_DSP_TYPE_FFT

+

FMOD_DSP_FLANGE

+

Flange DSP parameter types.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
typedef enum FMOD_DSP_FLANGE {
+  FMOD_DSP_FLANGE_MIX,
+  FMOD_DSP_FLANGE_DEPTH,
+  FMOD_DSP_FLANGE_RATE
+} FMOD_DSP_FLANGE;
+
+ +
enum DSP_FLANGE
+{
+  MIX,
+  DEPTH,
+  RATE
+}
+
+ +
FMOD.DSP_FLANGE_MIX
+FMOD.DSP_FLANGE_DEPTH
+FMOD.DSP_FLANGE_RATE
+
+ +
+
FMOD_DSP_FLANGE_MIX
+
+

Percentage of wet signal in the mix.

+
    +
  • Type: float
  • +
  • Units: Percentage
  • +
  • Range: [0, 100]
  • +
  • Default: 50
  • +
+
+
FMOD_DSP_FLANGE_DEPTH
+
+

Flange depth.

+
    +
  • Type: float
  • +
  • Units: Linear
  • +
  • Range: [0.01, 1]
  • +
  • Default: 1
  • +
+
+
FMOD_DSP_FLANGE_RATE
+
+

Flange speed.

+
    +
  • Type: float
  • +
  • Units: Hertz
  • +
  • Range: [0, 20]
  • +
  • Default: .1
  • +
+
+
+

Flange is an effect where the signal is played twice at the same time, and one copy slides back and forth creating a whooshing or flanging effect. As there are 2 versions of the same signal (dry vs wet), by default each signal is given 50% mix, so that the total is not louder than the original unaffected signal.

+

Flange depth is a percentage of a 10ms shift from the original signal. Anything above 10ms is not considered flange because to the ear it begins to 'echo' so 10ms is the highest value possible.

+

See Also: FMOD_DSP_TYPE_FLANGE, DSP::setParameterFloat

+

FMOD_DSP_HIGHPASS

+

Highpass DSP parameter types.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
typedef enum FMOD_DSP_HIGHPASS {
+  FMOD_DSP_HIGHPASS_CUTOFF,
+  FMOD_DSP_HIGHPASS_RESONANCE
+} FMOD_DSP_HIGHPASS;
+
+ +
enum DSP_HIGHPASS
+{
+  CUTOFF,
+  RESONANCE
+}
+
+ +
FMOD.DSP_HIGHPASS_CUTOFF
+FMOD.DSP_HIGHPASS_RESONANCE
+
+ +
+
FMOD_DSP_HIGHPASS_CUTOFF
+
+

Highpass cutoff frequency.

+
    +
  • Type: float
  • +
  • Units: Hertz
  • +
  • Range: [1, 22000]
  • +
  • Default: 5000
  • +
+
+
FMOD_DSP_HIGHPASS_RESONANCE
+
+

Highpass resonance Q value.

+
    +
  • Type: float
  • +
  • Range: [1, 10]
  • +
  • Default: 1
  • +
+
+
+

Deprecated and will be removed in a future release, to emulate with FMOD_DSP_TYPE_MULTIBAND_EQ:

+
// Configure a single band (band A) as a highpass (all other bands default to off).
+// 12dB roll-off to approximate the old effect curve.
+// Cutoff frequency can be used the same as with the old effect.
+// Resonance can be applied by setting the 'Q' value of the new effect.
+FMOD_DSP_SetParameterInt(multiband, FMOD_DSP_MULTIBAND_EQ_A_FILTER, FMOD_DSP_MULTIBAND_EQ_FILTER_HIGHPASS_12DB);
+FMOD_DSP_SetParameterFloat(multiband, FMOD_DSP_MULTIBAND_EQ_A_FREQUENCY, frequency);
+FMOD_DSP_SetParameterFloat(multiband, FMOD_DSP_MULTIBAND_EQ_A_Q, resonance);
+
+ +

See Also: FMOD_DSP_TYPE_HIGHPASS, DSP::setParameterFloat

+

FMOD_DSP_HIGHPASS_SIMPLE

+

High pass simple DSP parameter types.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
typedef enum FMOD_DSP_HIGHPASS_SIMPLE {
+  FMOD_DSP_HIGHPASS_SIMPLE_CUTOFF
+} FMOD_DSP_HIGHPASS_SIMPLE;
+
+ +
enum DSP_HIGHPASS_SIMPLE
+{
+  CUTOFF
+}
+
+ +
FMOD.DSP_HIGHPASS_SIMPLE_CUTOFF
+
+ +
+
FMOD_DSP_HIGHPASS_SIMPLE_CUTOFF
+
+

Highpass cutoff frequency.

+
    +
  • Type: float
  • +
  • Units: Hertz
  • +
  • Range: [1, 22000]
  • +
  • Default: 5000
  • +
+
+
+

Deprecated and will be removed in a future release, to emulate with FMOD_DSP_TYPE_MULTIBAND_EQ:

+
// Configure a single band (band A) as a highpass (all other bands default to off).
+// 12dB roll-off to approximate the old effect curve.
+// Cutoff frequency can be used the same as with the old effect.
+// Resonance / 'Q' should remain at default 0.707.
+FMOD_DSP_SetParameterInt(multiband, FMOD_DSP_MULTIBAND_EQ_A_FILTER, FMOD_DSP_MULTIBAND_EQ_FILTER_HIGHPASS_12DB);
+FMOD_DSP_SetParameterFloat(multiband, FMOD_DSP_MULTIBAND_EQ_A_FREQUENCY, frequency);
+
+ +

This is a very simple single-order high pass filter. The emphasis is on speed rather than accuracy, so this should not be used for task requiring critical filtering.

+

See Also: FMOD_DSP_TYPE_HIGHPASS_SIMPLE, DSP::setParameterFloat

+

FMOD_DSP_ITECHO

+

IT echo DSP parameter types.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
typedef enum FMOD_DSP_ITECHO {
+  FMOD_DSP_ITECHO_WETDRYMIX,
+  FMOD_DSP_ITECHO_FEEDBACK,
+  FMOD_DSP_ITECHO_LEFTDELAY,
+  FMOD_DSP_ITECHO_RIGHTDELAY,
+  FMOD_DSP_ITECHO_PANDELAY
+} FMOD_DSP_ITECHO;
+
+ +
enum DSP_ITECHO
+{
+  WETDRYMIX,
+  FEEDBACK,
+  LEFTDELAY,
+  RIGHTDELAY,
+  PANDELAY
+}
+
+ +
FMOD.DSP_ITECHO_WETDRYMIX
+FMOD.DSP_ITECHO_FEEDBACK
+FMOD.DSP_ITECHO_LEFTDELAY
+FMOD.DSP_ITECHO_RIGHTDELAY
+FMOD.DSP_ITECHO_PANDELAY
+
+ +
+
FMOD_DSP_ITECHO_WETDRYMIX
+
+

Ratio of wet (processed) signal to dry (unprocessed) signal. Higher is wetter.

+
    +
  • Type: float
  • +
  • Units: Percentage
  • +
  • Range: [0, 100]
  • +
  • Default: 50
  • +
+
+
FMOD_DSP_ITECHO_FEEDBACK
+
+

Percentage of output fed back into input.

+
    +
  • Type: float
  • +
  • Units: Percentage
  • +
  • Range: [0, 100]
  • +
  • Default: 50
  • +
+
+
FMOD_DSP_ITECHO_LEFTDELAY
+
+

Delay for left channel.

+
    +
  • Type: float
  • +
  • Units: Milliseconds
  • +
  • Range: [1, 2000]
  • +
  • Default: 500
  • +
+
+
FMOD_DSP_ITECHO_RIGHTDELAY
+
+

Delay for right channel.

+
    +
  • Type: float
  • +
  • Units: Milliseconds
  • +
  • Range: [1, 2000]
  • +
  • Default: 500
  • +
+
+
FMOD_DSP_ITECHO_PANDELAY
+
+

Value that specifies whether to swap left and right delays with each successive echo. CURRENTLY NOT SUPPORTED.

+
    +
  • Type: float
  • +
  • Range: 0, 1
  • +
  • Default: 0
  • +
+
+
+

This is effectively a software based echo filter that emulates the DirectX DMO echo effect. Impulse tracker files can support this, and FMOD will produce the effect on ANY platform, not just those that support DirectX effects!

+

Every time the delay is changed, the plug-in reallocates the echo buffer. This means the echo disappears at that time while it refills its new buffer. Larger echo delays result in larger amounts of memory allocated.

+

As this is a stereo filter made mainly for IT playback, it is targeted for stereo signals. With mono signals only the FMOD_DSP_ITECHO_LEFTDELAY is used. For multi-channel signals (>2) there will be no echo on those channels.

+

See Also: FMOD_DSP_TYPE_ITECHO, DSP::setParameterFloat

+

FMOD_DSP_ITLOWPASS

+

Lowpass DSP parameter types.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
typedef enum FMOD_DSP_ITLOWPASS {
+  FMOD_DSP_ITLOWPASS_CUTOFF,
+  FMOD_DSP_ITLOWPASS_RESONANCE
+} FMOD_DSP_ITLOWPASS;
+
+ +
enum DSP_ITLOWPASS
+{
+  CUTOFF,
+  RESONANCE
+}
+
+ +
FMOD.DSP_ITLOWPASS_CUTOFF
+FMOD.DSP_ITLOWPASS_RESONANCE
+
+ +
+
FMOD_DSP_ITLOWPASS_CUTOFF
+
+

Lowpass cutoff frequency.

+
    +
  • Type: float
  • +
  • Units: Hertz
  • +
  • Range: [1, 22000]
  • +
  • Default: 5000
  • +
+
+
FMOD_DSP_ITLOWPASS_RESONANCE
+
+

Lowpass resonance Q value.

+
    +
  • Type: float
  • +
  • Range: [0, 127]
  • +
  • Default: 1
  • +
+
+
+

The FMOD Engine's .IT playback (FMOD_SOUND_TYPE_IT) uses this filter.

+

This is different to the default FMOD_DSP_TYPE_ITLOWPASS filter in that it uses a different quality algorithm and is the filter used to produce the correct sounding playback in .IT files.

+

Note! This filter actually has a limited cutoff frequency below the specified maximum, due to its limited design. For a more open range filter, use FMOD_DSP_LOWPASS, or if you don't mind not having resonance, FMOD_DSP_LOWPASS_SIMPLE.

+

The effective maximum cutoff is about 8060hz.

+

See Also: FMOD_DSP_TYPE_ITLOWPASS, DSP::setParameterFloat

+

FMOD_DSP_LIMITER

+

Limiter DSP parameter types.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
typedef enum FMOD_DSP_LIMITER {
+  FMOD_DSP_LIMITER_RELEASETIME,
+  FMOD_DSP_LIMITER_CEILING,
+  FMOD_DSP_LIMITER_MAXIMIZERGAIN,
+  FMOD_DSP_LIMITER_MODE
+} FMOD_DSP_LIMITER;
+
+ +
enum DSP_LIMITER
+{
+  RELEASETIME,
+  CEILING,
+  MAXIMIZERGAIN,
+  MODE,
+}
+
+ +
FMOD.DSP_LIMITER_RELEASETIME
+FMOD.DSP_LIMITER_CEILING
+FMOD.DSP_LIMITER_MAXIMIZERGAIN
+FMOD.DSP_LIMITER_MODE
+
+ +
+
FMOD_DSP_LIMITER_RELEASETIME
+
+

Time to return the gain reduction to full in ms.

+
    +
  • Type: float
  • +
  • Units: Milliseconds
  • +
  • Range: [1, 1000]
  • +
  • Default: 10
  • +
+
+
FMOD_DSP_LIMITER_CEILING
+
+

Maximum level of the output signal.

+
    +
  • Type: float
  • +
  • Units: Decibels
  • +
  • Range: [-12, 0]
  • +
  • Default: 0
  • +
+
+
FMOD_DSP_LIMITER_MAXIMIZERGAIN
+
+

Maximum amplification allowed.

+
    +
  • Type: float
  • +
  • Units: Decibels
  • +
  • Range: [0, 12]
  • +
  • Default: 0
  • +
+
+
FMOD_DSP_LIMITER_MODE
+
+

Channel processing mode where false is independent (limiter per channel) and true is linked (all channels are summed together before processing).

+
    +
  • Type: bool
  • +
  • Default: false
  • +
+
+
+

See Also: FMOD_DSP_TYPE_LIMITER, DSP::setParameterFloat

+

FMOD_DSP_LOUDNESS_METER

+

Loudness meter DSP parameter types.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
typedef enum FMOD_DSP_LOUDNESS_METER {
+  FMOD_DSP_LOUDNESS_METER_STATE,
+  FMOD_DSP_LOUDNESS_METER_WEIGHTING,
+  FMOD_DSP_LOUDNESS_METER_INFO
+} FMOD_DSP_LOUDNESS_METER;
+
+ +
enum DSP_LOUDNESS_METER
+{
+  STATE,
+  WEIGHTING,
+  INFO
+}
+
+ +
FMOD.DSP_LOUDNESS_METER_STATE,
+FMOD.DSP_LOUDNESS_METER_WEIGHTING,
+FMOD.DSP_LOUDNESS_METER_INFO
+
+ +
+
FMOD_DSP_LOUDNESS_METER_STATE
+
+

Update state.

+ +
+
FMOD_DSP_LOUDNESS_METER_WEIGHTING
+
+

Channel weighting.

+ +
+
FMOD_DSP_LOUDNESS_METER_INFO R/O
+
+

Metering information.

+ +
+
+

See Also: FMOD_DSP_TYPE_LOUDNESS_METER, DSP::setParameterInt, DSP::setParameterData

+

FMOD_DSP_LOUDNESS_METER_INFO_TYPE

+

Loudness meter information data structure.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
typedef struct FMOD_DSP_LOUDNESS_METER_INFO_TYPE
+{
+  float momentaryloudness;
+  float shorttermloudness;
+  float integratedloudness;
+  float loudness10thpercentile;
+  float loudness95thpercentile;
+  float loudnesshistogram[66];
+  float maxtruepeak;
+  float maxmomentaryloudness;
+} FMOD_DSP_LOUDNESS_METER_INFO_TYPE;
+
+ +
struct DSP_LOUDNESS_METER_INFO_TYPE
+{
+  float momentaryloudness;
+  float shorttermloudness;
+  float integratedloudness;
+  float loudness10thpercentile;
+  float loudness95thpercentile;
+  float loudnesshistogram[66];
+  float maxtruepeak;
+  float maxmomentaryloudness;
+}
+
+ +
FMOD_DSP_LOUDNESS_METER_INFO_TYPE
+{
+  momentaryloudness;
+  shorttermloudness;
+  integratedloudness;
+  loudness10thpercentile;
+  loudness95thpercentile;
+  loudnesshistogram;
+  maxtruepeak;
+  maxmomentaryloudness;
+}
+
+ +
+
momentaryloudness
+
Loudness value indicating current loudness. Calculated using a 400ms window.
+
+
    +
  • Units: Decibels
  • +
  • Range: [-80, inf)
  • +
+
+
shorttermloudness
+
Loudness value indicating loudness averaged over a short time duration. Calculated using a 3 second window.
+
+
    +
  • Units: Decibels
  • +
  • Range: [-80, inf)
  • +
+
+
integratedloudness
+
Loudness value indicating loudness over the entire duration of the recording period.
+
+
    +
  • Units: Decibels
  • +
  • Range: [-80, inf)
  • +
+
+
loudness10thpercentile
+
10th percentile loudness (towards lowest loudness). Uses short term loudness values (3 second averages).
+
+
    +
  • Units: Decibels
  • +
  • Range: [-80, inf)
  • +
+
+
loudness95thpercentile
+
95th percentile loudness (towards highest loudness). Uses short term loudness values (3 second averages).
+
+
    +
  • Units: Decibels
  • +
  • Range: [-80, inf)
  • +
+
+
loudnesshistogram
+
Array containing distribution of loudness values. Each array entry is a count of the momentary loudness values (400ms averages) evenly distributed along the range [-60, 6] excluding loudness values outside that range.
+
maxtruepeak
+
Highest peak.
+
+
    +
  • Units: Decibels
  • +
  • Range: [-80, inf)
  • +
+
+
maxmomentaryloudness
+
Highest momentary loudness value (400ms averages).
+
+
    +
  • Units: Decibels
  • +
  • Range: [-80, inf)
  • +
+

See Also: FMOD_DSP_PARAMETER_DATA_TYPE, FMOD_DSP_PARAMETER_DESC

+

FMOD_DSP_LOUDNESS_METER_STATE_TYPE

+

Loudness meter state indicating update behavior.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
typedef enum FMOD_DSP_LOUDNESS_METER_STATE_TYPE {
+  FMOD_DSP_LOUDNESS_METER_STATE_RESET_INTEGRATED = -3,
+  FMOD_DSP_LOUDNESS_METER_STATE_RESET_MAXPEAK = -2,
+  FMOD_DSP_LOUDNESS_METER_STATE_RESET_ALL = -1,
+  FMOD_DSP_LOUDNESS_METER_STATE_PAUSED = 0,
+  FMOD_DSP_LOUDNESS_METER_STATE_ANALYZING = 1
+} FMOD_DSP_LOUDNESS_METER_STATE_TYPE;
+
+ +
enum DSP_LOUDNESS_METER_STATE_TYPE
+{
+  RESET_INTEGRATED = -3,
+  RESET_MAXPEAK = -2,
+  ESET_ALL = -1,
+  PAUSED,
+  ANALYZING
+}
+
+ +
FMOD.DSP_LOUDNESS_METER_STATE_RESET_INTEGRATED = -3,
+FMOD.DSP_LOUDNESS_METER_STATE_RESET_MAXPEAK = -2,
+FMOD.DSP_LOUDNESS_METER_STATE_RESET_ALL = -1,
+FMOD.DSP_LOUDNESS_METER_STATE_PAUSED = 0,
+FMOD.DSP_LOUDNESS_METER_STATE_ANALYZING = 1
+
+ +
+
FMOD_DSP_LOUDNESS_METER_STATE_RESET_INTEGRATED
+
Reset loudness meter information except max peak.
+
FMOD_DSP_LOUDNESS_METER_STATE_RESET_MAXPEAK
+
Reset loudness meter max peak.
+
FMOD_DSP_LOUDNESS_METER_STATE_RESET_ALL
+
Reset all loudness meter information.
+
FMOD_DSP_LOUDNESS_METER_STATE_PAUSED
+
Pause loudness meter.
+
FMOD_DSP_LOUDNESS_METER_STATE_ANALYZING
+
Enable loudness meter recording and analyzing.
+
+

See Also: FMOD_DSP_TYPE_LOUDNESS_METER

+

FMOD_DSP_LOUDNESS_METER_WEIGHTING_TYPE

+

Loudness meter channel weighting.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
typedef struct FMOD_DSP_LOUDNESS_METER_WEIGHTING_TYPE
+{
+  float channelweight[32];
+} FMOD_DSP_LOUDNESS_METER_WEIGHTING_TYPE;
+
+ +
struct DSP_LOUDNESS_METER_WEIGHTING_TYPE
+{
+  float channelweight[32];
+}
+
+ +
FMOD_DSP_LOUDNESS_METER_WEIGHTING_TYPE
+{
+  channelweight;
+}
+
+ +
+
channelweight
+
+

The weighting of each channel used in calculating loudness.

+
    +
  • Default: { 1, 1, 1, 0, 1.4, 1.4, 1.4, 1.4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }
  • +
+
+
+

See Also: FMOD_DSP_PARAMETER_DATA_TYPE, FMOD_DSP_PARAMETER_DESC

+

FMOD_DSP_LOWPASS

+

Low pass DSP parameter types.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
typedef enum FMOD_DSP_LOWPASS {
+  FMOD_DSP_LOWPASS_CUTOFF,
+  FMOD_DSP_LOWPASS_RESONANCE
+} FMOD_DSP_LOWPASS;
+
+ +
enum DSP_LOWPASS
+{
+  CUTOFF,
+  RESONANCE
+}
+
+ +
FMOD.DSP_LOWPASS_CUTOFF
+FMOD.DSP_LOWPASS_RESONANCE
+
+ +
+
FMOD_DSP_LOWPASS_CUTOFF
+
+

Lowpass cutoff frequency.

+
    +
  • Type: float
  • +
  • Units: Hertz
  • +
  • Range: [1, 22000]
  • +
  • Default: 5000
  • +
+
+
FMOD_DSP_LOWPASS_RESONANCE
+
+

Lowpass resonance Q value.

+
    +
  • Type: float
  • +
  • Range: [0, 10]
  • +
  • Default: 1
  • +
+
+
+

Deprecated and will be removed in a future release, to emulate with FMOD_DSP_TYPE_MULTIBAND_EQ:

+
// Configure a single band (band A) as a lowpass (all other bands default to off).
+// 24dB roll-off to approximate the old effect curve.
+// Cutoff frequency can be used the same as with the old effect.
+// Resonance can be applied by setting the 'Q' value of the new effect.
+FMOD_DSP_SetParameterInt(multiband, FMOD_DSP_MULTIBAND_EQ_A_FILTER, FMOD_DSP_MULTIBAND_EQ_FILTER_LOWPASS_24DB);
+FMOD_DSP_SetParameterFloat(multiband, FMOD_DSP_MULTIBAND_EQ_A_FREQUENCY, frequency);
+FMOD_DSP_SetParameterFloat(multiband, FMOD_DSP_MULTIBAND_EQ_A_Q, resonance);
+
+ +

See Also: FMOD_DSP_TYPE_LOWPASS, DSP::setParameterFloat

+

FMOD_DSP_LOWPASS_SIMPLE

+

Low pass simple DSP parameter types.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
typedef enum FMOD_DSP_LOWPASS_SIMPLE {
+  FMOD_DSP_LOWPASS_SIMPLE_CUTOFF
+} FMOD_DSP_LOWPASS_SIMPLE;
+
+ +
enum DSP_LOWPASS_SIMPLE
+{
+  CUTOFF
+}
+
+ +
FMOD.DSP_LOWPASS_SIMPLE_CUTOFF
+
+ +
+
FMOD_DSP_LOWPASS_SIMPLE_CUTOFF
+
+

Lowpass cutoff frequency.

+
    +
  • Type: float
  • +
  • Units: Hertz
  • +
  • Range: [1, 22000]
  • +
  • Default: 5000
  • +
+
+
+

Deprecated and will be removed in a future release, to emulate with FMOD_DSP_TYPE_MULTIBAND_EQ:

+
//  Configure a single band (band A) as a lowpass (all other bands default to off).
+//  12dB roll-off to approximate the old effect curve.
+//  Cutoff frequency can be used the same as with the old effect.
+//  Resonance / 'Q' should remain at default 0.707.
+FMOD_DSP_SetParameterInt(multiband, FMOD_DSP_MULTIBAND_EQ_A_FILTER, FMOD_DSP_MULTIBAND_EQ_FILTER_LOWPASS_12DB);
+FMOD_DSP_SetParameterFloat(multiband, FMOD_DSP_MULTIBAND_EQ_A_FREQUENCY, frequency);
+
+ +

This is a very simple low pass filter, based on two single-pole RC time-constant modules.

+

The emphasis is on speed rather than accuracy, so this should not be used for task requiring critical filtering.

+

See Also: FMOD_DSP_TYPE_LOWPASS_SIMPLE, DSP::setParameterFloat, DSP::getParameterFloat, FMOD_DSP_TYPE

+

FMOD_DSP_MULTIBAND_DYNAMICS

+

Three-band compressor/expander effect.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
typedef enum FMOD_DSP_MULTIBAND_DYNAMICS
+{
+  FMOD_DSP_MULTIBAND_DYNAMICS_LOWER_FREQUENCY,
+  FMOD_DSP_MULTIBAND_DYNAMICS_UPPER_FREQUENCY,
+  FMOD_DSP_MULTIBAND_DYNAMICS_LINKED,
+  FMOD_DSP_MULTIBAND_DYNAMICS_USE_SIDECHAIN,
+  FMOD_DSP_MULTIBAND_DYNAMICS_A_MODE,
+  FMOD_DSP_MULTIBAND_DYNAMICS_A_GAIN,
+  FMOD_DSP_MULTIBAND_DYNAMICS_A_THRESHOLD,
+  FMOD_DSP_MULTIBAND_DYNAMICS_A_RATIO,
+  FMOD_DSP_MULTIBAND_DYNAMICS_A_ATTACK,
+  FMOD_DSP_MULTIBAND_DYNAMICS_A_RELEASE,
+  FMOD_DSP_MULTIBAND_DYNAMICS_A_GAIN_MAKEUP,
+  FMOD_DSP_MULTIBAND_DYNAMICS_A_RESPONSE_DATA,
+  FMOD_DSP_MULTIBAND_DYNAMICS_B_MODE,
+  FMOD_DSP_MULTIBAND_DYNAMICS_B_GAIN,
+  FMOD_DSP_MULTIBAND_DYNAMICS_B_THRESHOLD,
+  FMOD_DSP_MULTIBAND_DYNAMICS_B_RATIO,
+  FMOD_DSP_MULTIBAND_DYNAMICS_B_ATTACK,
+  FMOD_DSP_MULTIBAND_DYNAMICS_B_RELEASE,
+  FMOD_DSP_MULTIBAND_DYNAMICS_B_GAIN_MAKEUP,
+  FMOD_DSP_MULTIBAND_DYNAMICS_B_RESPONSE_DATA,
+  FMOD_DSP_MULTIBAND_DYNAMICS_C_MODE,
+  FMOD_DSP_MULTIBAND_DYNAMICS_C_GAIN,
+  FMOD_DSP_MULTIBAND_DYNAMICS_C_THRESHOLD,
+  FMOD_DSP_MULTIBAND_DYNAMICS_C_RATIO,
+  FMOD_DSP_MULTIBAND_DYNAMICS_C_ATTACK,
+  FMOD_DSP_MULTIBAND_DYNAMICS_C_RELEASE,
+  FMOD_DSP_MULTIBAND_DYNAMICS_C_GAIN_MAKEUP,
+  FMOD_DSP_MULTIBAND_DYNAMICS_C_RESPONSE_DATA
+};
+
+ +
enum DSP_MULTIBAND_DYNAMICS
+{
+  LOWER_FREQUENCY,
+  UPPER_FREQUENCY,
+  LINKED,
+  USE_SIDECHAIN,
+  A_MODE,
+  A_GAIN,
+  A_THRESHOLD,
+  A_RATIO,
+  A_ATTACK,
+  A_RELEASE,
+  A_GAIN_MAKEUP,
+  A_RESPONSE_DATA,
+  B_MODE,
+  B_GAIN,
+  B_THRESHOLD,
+  B_RATIO,
+  B_ATTACK,
+  B_RELEASE,
+  B_GAIN_MAKEUP,
+  B_RESPONSE_DATA,
+  C_MODE,
+  C_GAIN,
+  C_THRESHOLD,
+  C_RATIO,
+  C_ATTACK,
+  C_RELEASE,
+  C_GAIN_MAKEUP,
+  C_RESPONSE_DATA
+}
+
+ +
FMOD.DSP_MULTIBAND_DYNAMICS_LOWER_FREQUENCY,
+FMOD.DSP_MULTIBAND_DYNAMICS_UPPER_FREQUENCY,
+FMOD.DSP_MULTIBAND_DYNAMICS_LINKED,
+FMOD.DSP_MULTIBAND_DYNAMICS_USE_SIDECHAIN,
+FMOD.DSP_MULTIBAND_DYNAMICS_A_MODE,
+FMOD.DSP_MULTIBAND_DYNAMICS_A_GAIN,
+FMOD.DSP_MULTIBAND_DYNAMICS_A_THRESHOLD,
+FMOD.DSP_MULTIBAND_DYNAMICS_A_RATIO,
+FMOD.DSP_MULTIBAND_DYNAMICS_A_ATTACK,
+FMOD.DSP_MULTIBAND_DYNAMICS_A_RELEASE,
+FMOD.DSP_MULTIBAND_DYNAMICS_A_GAIN_MAKEUP,
+FMOD.DSP_MULTIBAND_DYNAMICS_A_RESPONSE_DATA,
+FMOD.DSP_MULTIBAND_DYNAMICS_B_MODE,
+FMOD.DSP_MULTIBAND_DYNAMICS_B_GAIN,
+FMOD.DSP_MULTIBAND_DYNAMICS_B_THRESHOLD,
+FMOD.DSP_MULTIBAND_DYNAMICS_B_RATIO,
+FMOD.DSP_MULTIBAND_DYNAMICS_B_ATTACK,
+FMOD.DSP_MULTIBAND_DYNAMICS_B_RELEASE,
+FMOD.DSP_MULTIBAND_DYNAMICS_B_GAIN_MAKEUP,
+FMOD.DSP_MULTIBAND_DYNAMICS_B_RESPONSE_DATA,
+FMOD.DSP_MULTIBAND_DYNAMICS_C_MODE,
+FMOD.DSP_MULTIBAND_DYNAMICS_C_GAIN,
+FMOD.DSP_MULTIBAND_DYNAMICS_C_THRESHOLD,
+FMOD.DSP_MULTIBAND_DYNAMICS_C_RATIO,
+FMOD.DSP_MULTIBAND_DYNAMICS_C_ATTACK,
+FMOD.DSP_MULTIBAND_DYNAMICS_C_RELEASE,
+FMOD.DSP_MULTIBAND_DYNAMICS_C_GAIN_MAKEUP,
+FMOD.DSP_MULTIBAND_DYNAMICS_C_RESPONSE_DATA
+
+ +
+
FMOD_DSP_MULTIBAND_DYNAMICS_LOWER_FREQUENCY
+
+

Lower crossover frequency. Band A will process the dynamic content ranging from 20Hz to this value, and Band B will process the dynamic content ranging from this value to the value of FMOD_DSP_MULTIBAND_DYNAMICS_UPPER_FREQUENCY.

+
    +
  • Type: float
  • +
  • Units: Hertz
  • +
  • Range: [20, 22000]
  • +
  • Default: 400
  • +
+
+
FMOD_DSP_MULTIBAND_DYNAMICS_UPPER_FREQUENCY
+
+

Upper crossover frequency. Band B will process the dynamic content ranging from the value of FMOD_DSP_MULTIBAND_DYNAMICS_LOWER_FREQUENCY to this value, and Band C will process the dynamic content ranging from this value to 20kHz.

+
    +
  • Type: float
  • +
  • Units: Hertz
  • +
  • Range: [20, 22000]
  • +
  • Default: 4000
  • +
+
+
FMOD_DSP_MULTIBAND_DYNAMICS_LINKED
+
+

Enables optimized processing mode. When set to true, the input signal is mixed down to mono before passing through the dynamic processor bands. If the channel count of the sidechain signal is different to the input signal, it will be forced into linked mode.

+
    +
  • Type: Boolean
  • +
  • Default: True
  • +
+
+
FMOD_DSP_MULTIBAND_DYNAMICS_USE_SIDECHAIN
+
+

Whether to analyse the sidechain signal instead of the input signal. When sidechaining is enabled the sidechain channel will be split into separate bands and analyzed for their dynamic content, but the resulting dynamic response will still be applied to the host channel.

+ +
+
FMOD_DSP_MULTIBAND_DYNAMICS_A_MODE
+
+

Band A: Dynamic response mode. Use this to configure how the band will respond to the envelope of the signal. The "Upward" modes will amplify the signal, and the "Downward" modes will attenuate the signal.

+ +
+
FMOD_DSP_MULTIBAND_DYNAMICS_A_GAIN
+
+

Band A: Gain applied before dynamic processing. This amplifies or attenuates the signal before it is split into separate bands and dynamic processors.

+
    +
  • Type: float
  • +
  • Units: dB
  • +
  • Range: [-30, 30]
  • +
  • Default: 0
  • +
+
+
FMOD_DSP_MULTIBAND_DYNAMICS_A_THRESHOLD
+
+

Band A: Dynamic response threshold. This changes the threshold at which this band will start attenuating or amplifying the signal.

+
    +
  • Type: float
  • +
  • Units: dB
  • +
  • Range: [-80, 0]
  • +
  • Default: -5
  • +
+
+
FMOD_DSP_MULTIBAND_DYNAMICS_A_RATIO
+
+

Band A: Dynamic response ratio. This changes the amount of amplification or attenuation that will be applied to the signal. The result of dynamic processing will be more subtle at lower ratio values, and will intensify as the ratio increases.

+
    +
  • Type: float
  • +
  • Units: Linear
  • +
  • Range: [1, 50]
  • +
  • Default: 2.5
  • +
+
+
FMOD_DSP_MULTIBAND_DYNAMICS_A_ATTACK
+
+

Band A: Dynamic attack time. This is the duration it will take the dynamic processor to apply the full ratio of amplification or attenuation. Lower values will mean the full ratio is applied quickly, and will approach the ratio value more smoothly as the attack value increases.

+
    +
  • Type: float
  • +
  • Units: ms
  • +
  • Range: [0.1, 1000]
  • +
  • Default: 20
  • +
+
+
FMOD_DSP_MULTIBAND_DYNAMICS_A_RELEASE
+
+

Band A: Dynamic release time. This is the duration it will take the dynamic processor to return to stop applying amplification or attenuation. Lower values will mean the ratio stops being applied quickly, and will back off the ratio value more smoothly as the release value increases.

+
    +
  • Type: float
  • +
  • Units: ms
  • +
  • Range: [10, 5000]
  • +
  • Default: 100
  • +
+
+
FMOD_DSP_MULTIBAND_DYNAMICS_A_GAIN_MAKEUP
+
+

Band A: Gain applied after dynamic processing. This amplifies or attenuates the signal after it passes through the dynamic processors and before the split signal is mixed back together.

+
    +
  • Type: float
  • +
  • Units: dB
  • +
  • Range: [-30, 30]
  • +
  • Default: 0
  • +
+
+
FMOD_DSP_MULTIBAND_DYNAMICS_A_RESPONSE_DATA
+
+

Band A: Dynamic response metering information. This structure contains data on the average attenuation or amplification applied per channel in the last mix block.

+ +
+
FMOD_DSP_MULTIBAND_DYNAMICS_B_MODE
+
Band B: See Band A.
+
FMOD_DSP_MULTIBAND_DYNAMICS_B_GAIN
+
Band B: See Band A.
+
FMOD_DSP_MULTIBAND_DYNAMICS_B_THRESHOLD
+
Band B: See Band A.
+
FMOD_DSP_MULTIBAND_DYNAMICS_B_RATIO
+
Band B: See Band A.
+
FMOD_DSP_MULTIBAND_DYNAMICS_B_ATTACK
+
Band B: See Band A.
+
FMOD_DSP_MULTIBAND_DYNAMICS_B_RELEASE
+
Band B: See Band A.
+
FMOD_DSP_MULTIBAND_DYNAMICS_B_GAIN_MAKEUP
+
Band B: See Band A.
+
FMOD_DSP_MULTIBAND_DYNAMICS_B_RESPONSE_DATA
+
Band B: See Band A.
+
FMOD_DSP_MULTIBAND_DYNAMICS_C_MODE
+
Band C: See Band A.
+
FMOD_DSP_MULTIBAND_DYNAMICS_C_GAIN
+
Band C: See Band A.
+
FMOD_DSP_MULTIBAND_DYNAMICS_C_THRESHOLD
+
Band C: See Band A.
+
FMOD_DSP_MULTIBAND_DYNAMICS_C_RATIO
+
Band C: See Band A.
+
FMOD_DSP_MULTIBAND_DYNAMICS_C_ATTACK
+
Band C: See Band A.
+
FMOD_DSP_MULTIBAND_DYNAMICS_C_RELEASE
+
Band C: See Band A.
+
FMOD_DSP_MULTIBAND_DYNAMICS_C_GAIN_MAKEUP
+
Band C: See Band A.
+
FMOD_DSP_MULTIBAND_DYNAMICS_C_RESPONSE_DATA
+
Band C: See Band A.
+
+

FMOD_DSP_MULTIBAND_DYNAMICS_MODE_TYPE

+

Multiband Dynamics dynamic response types.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
typedef enum FMOD_DSP_MULTIBAND_DYNAMICS_MODE_TYPE {
+  FMOD_DSP_MULTIBAND_DYNAMICS_MODE_DISABLED,
+  FMOD_DSP_MULTIBAND_DYNAMICS_MODE_COMPRESS_UP,
+  FMOD_DSP_MULTIBAND_DYNAMICS_MODE_COMPRESS_DOWN,
+  FMOD_DSP_MULTIBAND_DYNAMICS_MODE_EXPAND_UP,
+  FMOD_DSP_MULTIBAND_DYNAMICS_MODE_EXPAND_DOWN
+};
+
+ +
enum DSP_MULTIBAND_DYNAMICS_MODE_TYPE
+{
+  DISABLED,
+  COMPRESS_UP,
+  COMPRESS_DOWN,
+  EXPAND_UP,
+  EXPAND_DOWN
+}
+
+ +
FMOD.DSP_MULTIBAND_DYNAMICS_MODE_DISABLED,
+FMOD.DSP_MULTIBAND_DYNAMICS_MODE_COMPRESS_UP,
+FMOD.DSP_MULTIBAND_DYNAMICS_MODE_COMPRESS_DOWN,
+FMOD.DSP_MULTIBAND_DYNAMICS_MODE_EXPAND_UP,
+FMOD.DSP_MULTIBAND_DYNAMICS_MODE_EXPAND_DOWN
+
+ +
+
FMOD_DSP_MULTIBAND_DYNAMICS_MODE_DISABLED
+
Response disabled, no processing.
+
FMOD_DSP_MULTIBAND_DYNAMICS_MODE_COMPRESS_UP
+
Dynamic upward compression. Amplifies the signal below a defined threshold.
+
FMOD_DSP_MULTIBAND_DYNAMICS_MODE_COMPRESS_DOWN
+
Dynamic downward compression. Attenuates the signal above a defined threshold.
+
FMOD_DSP_MULTIBAND_DYNAMICS_MODE_EXPAND_UP
+
Dynamic upward expansion. Amplifies the signal above a defined threshold.
+
FMOD_DSP_MULTIBAND_DYNAMICS_MODE_EXPAND_DOWN
+
Dynamic downward expansion. Attenuates the signal below a defined threshold.
+
+

See Also: FMOD_DSP_MULTIBAND_DYNAMICS

+

FMOD_DSP_MULTIBAND_EQ

+

Multiband equalizer DSP parameter types.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
typedef enum FMOD_DSP_MULTIBAND_EQ {
+  FMOD_DSP_MULTIBAND_EQ_A_FILTER,
+  FMOD_DSP_MULTIBAND_EQ_A_FREQUENCY,
+  FMOD_DSP_MULTIBAND_EQ_A_Q,
+  FMOD_DSP_MULTIBAND_EQ_A_GAIN,
+  FMOD_DSP_MULTIBAND_EQ_B_FILTER,
+  FMOD_DSP_MULTIBAND_EQ_B_FREQUENCY,
+  FMOD_DSP_MULTIBAND_EQ_B_Q,
+  FMOD_DSP_MULTIBAND_EQ_B_GAIN,
+  FMOD_DSP_MULTIBAND_EQ_C_FILTER,
+  FMOD_DSP_MULTIBAND_EQ_C_FREQUENCY,
+  FMOD_DSP_MULTIBAND_EQ_C_Q,
+  FMOD_DSP_MULTIBAND_EQ_C_GAIN,
+  FMOD_DSP_MULTIBAND_EQ_D_FILTER,
+  FMOD_DSP_MULTIBAND_EQ_D_FREQUENCY,
+  FMOD_DSP_MULTIBAND_EQ_D_Q,
+  FMOD_DSP_MULTIBAND_EQ_D_GAIN,
+  FMOD_DSP_MULTIBAND_EQ_E_FILTER,
+  FMOD_DSP_MULTIBAND_EQ_E_FREQUENCY,
+  FMOD_DSP_MULTIBAND_EQ_E_Q,
+  FMOD_DSP_MULTIBAND_EQ_E_GAIN
+} FMOD_DSP_MULTIBAND_EQ;
+
+ +
enum DSP_MULTIBAND_EQ
+{
+  A_FILTER,
+  A_FREQUENCY,
+  A_Q,
+  A_GAIN,
+  B_FILTER,
+  B_FREQUENCY,
+  B_Q,
+  B_GAIN,
+  C_FILTER,
+  C_FREQUENCY,
+  C_Q,
+  C_GAIN,
+  D_FILTER,
+  D_FREQUENCY,
+  D_Q,
+  D_GAIN,
+  E_FILTER,
+  E_FREQUENCY,
+  E_Q,
+  E_GAIN,
+}
+
+ +
FMOD.DSP_MULTIBAND_EQ_A_FILTER
+FMOD.DSP_MULTIBAND_EQ_A_FREQUENCY
+FMOD.DSP_MULTIBAND_EQ_A_Q
+FMOD.DSP_MULTIBAND_EQ_A_GAIN
+FMOD.DSP_MULTIBAND_EQ_B_FILTER
+FMOD.DSP_MULTIBAND_EQ_B_FREQUENCY
+FMOD.DSP_MULTIBAND_EQ_B_Q
+FMOD.DSP_MULTIBAND_EQ_B_GAIN
+FMOD.DSP_MULTIBAND_EQ_C_FILTER
+FMOD.DSP_MULTIBAND_EQ_C_FREQUENCY
+FMOD.DSP_MULTIBAND_EQ_C_Q
+FMOD.DSP_MULTIBAND_EQ_C_GAIN
+FMOD.DSP_MULTIBAND_EQ_D_FILTER
+FMOD.DSP_MULTIBAND_EQ_D_FREQUENCY
+FMOD.DSP_MULTIBAND_EQ_D_Q
+FMOD.DSP_MULTIBAND_EQ_D_GAIN
+FMOD.DSP_MULTIBAND_EQ_E_FILTER
+FMOD.DSP_MULTIBAND_EQ_E_FREQUENCY
+FMOD.DSP_MULTIBAND_EQ_E_Q
+FMOD.DSP_MULTIBAND_EQ_E_GAIN
+
+ +
+
FMOD_DSP_MULTIBAND_EQ_A_FILTER
+
+

Band A: used to interpret the behavior of the remaining parameters.

+ +
+
FMOD_DSP_MULTIBAND_EQ_A_FREQUENCY
+
+

Band A: Significant frequency, cutoff [low/high pass, low/high shelf], center [notch, peaking, band-pass], phase transition point [all-pass].

+
    +
  • Type: float
  • +
  • Units: Hertz
  • +
  • Range: [20, 22000]
  • +
  • Default: 8000
  • +
+
+
FMOD_DSP_MULTIBAND_EQ_A_Q
+
+

Band A: Quality factor, resonance [low/high pass], bandwidth [notch, peaking, band-pass], phase transition sharpness [all-pass], unused [low/high shelf].

+
    +
  • Type: float
  • +
  • Range: [0.1, 10]
  • +
  • Default: 0.707
  • +
+
+
FMOD_DSP_MULTIBAND_EQ_A_GAIN
+
+

Band A: Boost or attenuation in dB [peaking, high/low shelf only]. -30 to 30. Default = 0.

+
    +
  • Type: float
  • +
  • Units: Decibels
  • +
  • Range: [-30, 30]
  • +
  • Default: 8000
  • +
+
+
FMOD_DSP_MULTIBAND_EQ_B_FILTER
+
+

Band B: See Band A.

+ +
+
FMOD_DSP_MULTIBAND_EQ_B_FREQUENCY
+
Band B: See Band A
+
FMOD_DSP_MULTIBAND_EQ_B_Q
+
Band B: See Band A
+
FMOD_DSP_MULTIBAND_EQ_B_GAIN
+
Band B: See Band A
+
FMOD_DSP_MULTIBAND_EQ_C_FILTER
+
+

Band C: See Band A.

+ +
+
FMOD_DSP_MULTIBAND_EQ_C_FREQUENCY
+
Band C: See Band A.
+
FMOD_DSP_MULTIBAND_EQ_C_Q
+
Band C: See Band A.
+
FMOD_DSP_MULTIBAND_EQ_C_GAIN
+
Band C: See Band A.
+
FMOD_DSP_MULTIBAND_EQ_D_FILTER
+
+

Band D: See Band A.

+ +
+
FMOD_DSP_MULTIBAND_EQ_D_FREQUENCY
+
Band D: See Band A.
+
FMOD_DSP_MULTIBAND_EQ_D_Q
+
Band D: See Band A.
+
FMOD_DSP_MULTIBAND_EQ_D_GAIN
+
Band D: See Band A.
+
FMOD_DSP_MULTIBAND_EQ_E_FILTER
+
+

Band E: See Band A.

+ +
+
FMOD_DSP_MULTIBAND_EQ_E_FREQUENCY
+
Band E: See Band A.
+
FMOD_DSP_MULTIBAND_EQ_E_Q
+
Band E: See Band A.
+
FMOD_DSP_MULTIBAND_EQ_E_GAIN
+
Band E: See Band A.
+
+

Flexible five band parametric equalizer.

+

See Also: FMOD_DSP_TYPE_MULTIBAND_EQ, DSP::setParameterInt, DSP::setParameterFloat

+

FMOD_DSP_MULTIBAND_EQ_FILTER_TYPE

+

Multiband equalizer filter types.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
typedef enum FMOD_DSP_MULTIBAND_EQ_FILTER_TYPE {
+  FMOD_DSP_MULTIBAND_EQ_FILTER_DISABLED,
+  FMOD_DSP_MULTIBAND_EQ_FILTER_LOWPASS_12DB,
+  FMOD_DSP_MULTIBAND_EQ_FILTER_LOWPASS_24DB,
+  FMOD_DSP_MULTIBAND_EQ_FILTER_LOWPASS_48DB,
+  FMOD_DSP_MULTIBAND_EQ_FILTER_HIGHPASS_12DB,
+  FMOD_DSP_MULTIBAND_EQ_FILTER_HIGHPASS_24DB,
+  FMOD_DSP_MULTIBAND_EQ_FILTER_HIGHPASS_48DB,
+  FMOD_DSP_MULTIBAND_EQ_FILTER_LOWSHELF,
+  FMOD_DSP_MULTIBAND_EQ_FILTER_HIGHSHELF,
+  FMOD_DSP_MULTIBAND_EQ_FILTER_PEAKING,
+  FMOD_DSP_MULTIBAND_EQ_FILTER_BANDPASS,
+  FMOD_DSP_MULTIBAND_EQ_FILTER_NOTCH,
+  FMOD_DSP_MULTIBAND_EQ_FILTER_ALLPASS,
+  FMOD_DSP_MULTIBAND_EQ_FILTER_LOWPASS_6DB,
+  FMOD_DSP_MULTIBAND_EQ_FILTER_HIGHPASS_6DB
+} FMOD_DSP_MULTIBAND_EQ_FILTER_TYPE;
+
+ +
enum DSP_MULTIBAND_EQ_FILTER_TYPE
+{
+  DISABLED,
+  LOWPASS_12DB,
+  LOWPASS_24DB,
+  LOWPASS_48DB,
+  HIGHPASS_12DB,
+  HIGHPASS_24DB,
+  HIGHPASS_48DB,
+  LOWSHELF,
+  HIGHSHELF,
+  PEAKING,
+  BANDPASS,
+  NOTCH,
+  ALLPASS,
+  LOWPASS_6DB,
+  HIGHPASS_6DB
+}
+
+ +
FMOD.DSP_MULTIBAND_EQ_FILTER_DISABLED
+FMOD.DSP_MULTIBAND_EQ_FILTER_LOWPASS_12DB
+FMOD.DSP_MULTIBAND_EQ_FILTER_LOWPASS_24DB
+FMOD.DSP_MULTIBAND_EQ_FILTER_LOWPASS_48DB
+FMOD.DSP_MULTIBAND_EQ_FILTER_HIGHPASS_12DB
+FMOD.DSP_MULTIBAND_EQ_FILTER_HIGHPASS_24DB
+FMOD.DSP_MULTIBAND_EQ_FILTER_HIGHPASS_48DB
+FMOD.DSP_MULTIBAND_EQ_FILTER_LOWSHELF
+FMOD.DSP_MULTIBAND_EQ_FILTER_HIGHSHELF
+FMOD.DSP_MULTIBAND_EQ_FILTER_PEAKING
+FMOD.DSP_MULTIBAND_EQ_FILTER_BANDPASS
+FMOD.DSP_MULTIBAND_EQ_FILTER_NOTCH
+FMOD.DSP_MULTIBAND_EQ_FILTER_ALLPASS
+FMOD.DSP_MULTIBAND_EQ_FILTER_LOWPASS_6DB
+FMOD.DSP_MULTIBAND_EQ_FILTER_HIGHPASS_6DB
+
+ +
+
FMOD_DSP_MULTIBAND_EQ_FILTER_DISABLED
+
Disabled filter, no processing.
+
FMOD_DSP_MULTIBAND_EQ_FILTER_LOWPASS_12DB
+
Resonant low-pass filter, attenuates frequencies (12dB per octave) above a given point (with specificed resonance) while allowing the rest to pass.
+
FMOD_DSP_MULTIBAND_EQ_FILTER_LOWPASS_24DB
+
Resonant low-pass filter, attenuates frequencies (24dB per octave) above a given point (with specificed resonance) while allowing the rest to pass.
+
FMOD_DSP_MULTIBAND_EQ_FILTER_LOWPASS_48DB
+
Resonant low-pass filter, attenuates frequencies (48dB per octave) above a given point (with specificed resonance) while allowing the rest to pass.
+
FMOD_DSP_MULTIBAND_EQ_FILTER_HIGHPASS_12DB
+
Resonant high-pass filter, attenuates frequencies (12dB per octave) below a given point (with specificed resonance) while allowing the rest to pass.
+
FMOD_DSP_MULTIBAND_EQ_FILTER_HIGHPASS_24DB
+
Resonant high-pass filter, attenuates frequencies (24dB per octave) below a given point (with specificed resonance) while allowing the rest to pass.
+
FMOD_DSP_MULTIBAND_EQ_FILTER_HIGHPASS_48DB
+
Resonant high-pass filter, attenuates frequencies (48dB per octave) below a given point (with specificed resonance) while allowing the rest to pass.
+
FMOD_DSP_MULTIBAND_EQ_FILTER_LOWSHELF
+
Low-shelf filter, boosts or attenuates frequencies (with specified gain) below a given point while allowing the rest to pass.
+
FMOD_DSP_MULTIBAND_EQ_FILTER_HIGHSHELF
+
High-shelf filter, boosts or attenuates frequencies (with specified gain) above a given point while allowing the rest to pass.
+
FMOD_DSP_MULTIBAND_EQ_FILTER_PEAKING
+
Peaking filter, boosts or attenuates frequencies (with specified gain) at a given point (with specificed bandwidth) while allowing the rest to pass.
+
FMOD_DSP_MULTIBAND_EQ_FILTER_BANDPASS
+
Band-pass filter, allows frequencies at a given point (with specificed bandwidth) to pass while attenuating frequencies outside this range.
+
FMOD_DSP_MULTIBAND_EQ_FILTER_NOTCH
+
Notch or band-reject filter, attenuates frequencies at a given point (with specificed bandwidth) while allowing frequencies outside this range to pass.
+
FMOD_DSP_MULTIBAND_EQ_FILTER_ALLPASS
+
All-pass filter, allows all frequencies to pass, but changes the phase response at a given point (with specified sharpness).
+
FMOD_DSP_MULTIBAND_EQ_FILTER_LOWPASS_6DB
+
Non-resonant low-pass filter, attenuates frequencies (6dB per octave) above a given point while allowing the rest to pass.
+
FMOD_DSP_MULTIBAND_EQ_FILTER_HIGHPASS_6DB
+
Non-resonant high-pass filter, attenuates frequencies (6dB per octave) below a given point while allowing the rest to pass.
+
+

See Also: FMOD_DSP_MULTIBAND_EQ

+

FMOD_DSP_NORMALIZE

+

Normalize DSP parameter types.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
typedef enum FMOD_DSP_NORMALIZE {
+  FMOD_DSP_NORMALIZE_FADETIME,
+  FMOD_DSP_NORMALIZE_THRESHOLD,
+  FMOD_DSP_NORMALIZE_MAXAMP
+} FMOD_DSP_NORMALIZE;
+
+ +
enum DSP_NORMALIZE
+{
+  FADETIME,
+  THRESHOLD,
+  MAXAMP
+}
+
+ +
FMOD.DSP_NORMALIZE_FADETIME
+FMOD.DSP_NORMALIZE_THRESHOLD
+FMOD.DSP_NORMALIZE_MAXAMP
+
+ +
+
FMOD_DSP_NORMALIZE_FADETIME
+
+

Time to ramp the silence to full.

+
    +
  • Type: float
  • +
  • Units: Milliseconds
  • +
  • Range: [0, 20000]
  • +
  • Default: 5000
  • +
+
+
FMOD_DSP_NORMALIZE_THRESHOLD
+
+

Lower volume range threshold to ignore.

+
    +
  • Type: float
  • +
  • Units: Linear
  • +
  • Range: [0, 1]
  • +
  • Default: 0.1
  • +
+
+
FMOD_DSP_NORMALIZE_MAXAMP
+
+

Maximum amplification allowed.

+
    +
  • Type: float
  • +
  • Units: Linear
  • +
  • Range: [1, 100000]
  • +
  • Default: 20
  • +
+
+
+

Normalize amplifies the sound based on the maximum peaks within the signal. For example if the maximum peaks in the signal were 50% of the bandwidth, it would scale the whole sound by 2.

+

The lower threshold value makes the normalizer ignore peaks below a certain point, to avoid over-amplification if a loud signal suddenly came in, and also to avoid amplifying to maximum things like background hiss.

+

Because FMOD is a realtime audio processor, it doesn't have the luxury of knowing the peak for the whole sound (ie it can't see into the future), so it has to process data as it comes in.

+

To avoid very sudden changes in volume level based on small samples of new data, FMOD fades towards the desired amplification which makes for smooth gain control. The fadetime parameter can control this.

+

See Also: FMOD_DSP_TYPE_NORMALIZE, DSP::setParameterFloat

+

FMOD_DSP_OBJECTPAN

+

Object based spatializer parameters.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
typedef enum FMOD_DSP_OBJECTPAN {
+  FMOD_DSP_OBJECTPAN_3D_POSITION,
+  FMOD_DSP_OBJECTPAN_3D_ROLLOFF,
+  FMOD_DSP_OBJECTPAN_3D_MIN_DISTANCE,
+  FMOD_DSP_OBJECTPAN_3D_MAX_DISTANCE,
+  FMOD_DSP_OBJECTPAN_3D_EXTENT_MODE,
+  FMOD_DSP_OBJECTPAN_3D_SOUND_SIZE,
+  FMOD_DSP_OBJECTPAN_3D_MIN_EXTENT,
+  FMOD_DSP_OBJECTPAN_OVERALL_GAIN,
+  FMOD_DSP_OBJECTPAN_OUTPUTGAIN,
+  FMOD_DSP_OBJECTPAN_ATTENUATION_RANGE,
+  FMOD_DSP_OBJECTPAN_OVERRIDE_RANGE
+} FMOD_DSP_OBJECTPAN;
+
+ +
enum DSP_OBJECTPAN
+{
+  _3D_POSITION,
+  _3D_ROLLOFF,
+  _3D_MIN_DISTANCE,
+  _3D_MAX_DISTANCE,
+  _3D_EXTENT_MODE,
+  _3D_SOUND_SIZE,
+  _3D_MIN_EXTENT,
+  OVERALL_GAIN,
+  OUTPUTGAIN,
+  ATTENUATION_RANGE,
+  OVERRIDE_RANGE
+}
+
+ +
FMOD.DSP_OBJECTPAN_3D_POSITION
+FMOD.DSP_OBJECTPAN_3D_ROLLOFF
+FMOD.DSP_OBJECTPAN_3D_MIN_DISTANCE
+FMOD.DSP_OBJECTPAN_3D_MAX_DISTANCE
+FMOD.DSP_OBJECTPAN_3D_EXTENT_MODE
+FMOD.DSP_OBJECTPAN_3D_SOUND_SIZE
+FMOD.DSP_OBJECTPAN_3D_MIN_EXTENT
+FMOD.DSP_OBJECTPAN_OVERALL_GAIN
+FMOD.DSP_OBJECTPAN_OUTPUTGAIN
+FMOD.DSP_OBJECTPAN_ATTENUATION_RANGE
+FMOD.DSP_OBJECTPAN_OVERRIDE_RANGE
+
+ +
+
FMOD_DSP_OBJECTPAN_3D_POSITION
+
+

3D Position.

+ +
+
FMOD_DSP_OBJECTPAN_3D_ROLLOFF
+
+

3D Roll-off Type.

+ +
+
FMOD_DSP_OBJECTPAN_3D_MIN_DISTANCE
+
+

3D Min Distance when FMOD_DSP_OBJECTPAN_OVERRIDE_RANGE is true.

+ +
+
FMOD_DSP_OBJECTPAN_3D_MAX_DISTANCE
+
+

3D Max Distance when FMOD_DSP_OBJECTPAN_OVERRIDE_RANGE is true.

+ +
+
FMOD_DSP_OBJECTPAN_3D_EXTENT_MODE
+
+

3D Extent Mode.

+ +
+
FMOD_DSP_OBJECTPAN_3D_SOUND_SIZE
+
+

3D Sound Size.

+ +
+
FMOD_DSP_OBJECTPAN_3D_MIN_EXTENT
+
+

3D Min Extent.

+
    +
  • Type: float
  • +
  • Units: Degrees
  • +
  • Range: [0, 360]
  • +
  • Default: 0
  • +
+
+
FMOD_DSP_OBJECTPAN_OVERALL_GAIN R/O
+
+

Overall gain to allow FMOD to know the DSP is scaling the signal for virtualization purposes.

+ +
+
FMOD_DSP_OBJECTPAN_OUTPUTGAIN
+
+

Output gain level.

+
    +
  • Type: float
  • +
  • Units: Linear
  • +
  • Range: [0, 1]
  • +
  • Default: 0
  • +
+
+
FMOD_DSP_OBJECTPAN_ATTENUATION_RANGE
+
+

Attenuation Range when FMOD_DSP_OBJECTPAN_OVERRIDE_RANGE is false.

+ +
+
FMOD_DSP_OBJECTPAN_OVERRIDE_RANGE
+
+

Override Attenuation Range with FMOD_DSP_OBJECTPAN_3D_MIN_DISTANCE and FMOD_DSP_OBJECTPAN_3D_MAX_DISTANCE.

+
    +
  • Type: bool
  • +
  • Default: true
  • +
+
+
+

Signal processed by this DSP will be sent to the global object mixer (effectively a send), any DSP connected after this will receive silence.

+

For best results this DSP should be used with FMOD_OUTPUTTYPE_WINSONIC or FMOD_OUTPUTTYPE_AUDIO3D to get height spatialization. Playback with any other output will result in fallback spatialization provided by FMOD_DSP_TYPE_PAN.

+

FMOD_DSP_OBJECTPAN_OVERRIDE_RANGE defaults to true for backwards compatability.

+

See Also: FMOD_DSP_TYPE_OBJECTPAN, DSP::setParameterFloat, DSP::setParameterInt, DSP::setParameterData, Controlling a Spatializer DSP.

+

FMOD_DSP_OSCILLATOR

+

Oscillator DSP parameter types.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
typedef enum FMOD_DSP_OSCILLATOR {
+  FMOD_DSP_OSCILLATOR_TYPE,
+  FMOD_DSP_OSCILLATOR_RATE
+} FMOD_DSP_OSCILLATOR;
+
+ +
enum DSP_OSCILLATOR
+{
+  TYPE,
+  RATE
+}
+
+ +
FMOD.DSP_OSCILLATOR_TYPE
+FMOD.DSP_OSCILLATOR_RATE
+
+ +
+
FMOD_DSP_OSCILLATOR_TYPE
+
+

Waveform type. 0 = sine. 1 = square. 2 = sawup. 3 = sawdown. 4 = triangle. 5 = noise.

+
    +
  • Type: int
  • +
  • Default: 0
  • +
+
+
FMOD_DSP_OSCILLATOR_RATE
+
+

Frequency of the tone. Does not affect the noise generator.

+
    +
  • Type: float
  • +
  • Units: Hertz
  • +
  • Range: [0, 22000]
  • +
  • Default: 220
  • +
+
+
+

See Also: FMOD_DSP_TYPE_OSCILLATOR, DSP::setParameterFloat, DSP::setParameterInt

+

FMOD_DSP_PAN

+

Pan DSP parameter types.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
typedef enum FMOD_DSP_PAN {
+  FMOD_DSP_PAN_MODE,
+  FMOD_DSP_PAN_2D_STEREO_POSITION,
+  FMOD_DSP_PAN_2D_DIRECTION,
+  FMOD_DSP_PAN_2D_EXTENT,
+  FMOD_DSP_PAN_2D_ROTATION,
+  FMOD_DSP_PAN_2D_LFE_LEVEL,
+  FMOD_DSP_PAN_2D_STEREO_MODE,
+  FMOD_DSP_PAN_2D_STEREO_SEPARATION,
+  FMOD_DSP_PAN_2D_STEREO_AXIS,
+  FMOD_DSP_PAN_ENABLED_SPEAKERS,
+  FMOD_DSP_PAN_3D_POSITION,
+  FMOD_DSP_PAN_3D_ROLLOFF,
+  FMOD_DSP_PAN_3D_MIN_DISTANCE,
+  FMOD_DSP_PAN_3D_MAX_DISTANCE,
+  FMOD_DSP_PAN_3D_EXTENT_MODE,
+  FMOD_DSP_PAN_3D_SOUND_SIZE,
+  FMOD_DSP_PAN_3D_MIN_EXTENT,
+  FMOD_DSP_PAN_3D_PAN_BLEND,
+  FMOD_DSP_PAN_LFE_UPMIX_ENABLED,
+  FMOD_DSP_PAN_OVERALL_GAIN,
+  FMOD_DSP_PAN_SURROUND_SPEAKER_MODE,
+  FMOD_DSP_PAN_2D_HEIGHT_BLEND,
+  FMOD_DSP_PAN_ATTENUATION_RANGE,
+  FMOD_DSP_PAN_OVERRIDE_RANGE
+} FMOD_DSP_PAN;
+
+ +
enum DSP_PAN
+{
+  MODE,
+  _2D_STEREO_POSITION,
+  _2D_DIRECTION,
+  _2D_EXTENT,
+  _2D_ROTATION,
+  _2D_LFE_LEVEL,
+  _2D_STEREO_MODE,
+  _2D_STEREO_SEPARATION,
+  _2D_STEREO_AXIS,
+  ENABLED_SPEAKERS,
+  _3D_POSITION,
+  _3D_ROLLOFF,
+  _3D_MIN_DISTANCE,
+  _3D_MAX_DISTANCE,
+  _3D_EXTENT_MODE,
+  _3D_SOUND_SIZE,
+  _3D_MIN_EXTENT,
+  _3D_PAN_BLEND,
+  LFE_UPMIX_ENABLED,
+  OVERALL_GAIN,
+  SURROUND_SPEAKER_MODE,
+  _2D_HEIGHT_BLEND,
+  ATTENUATION_RANGE,
+  OVERRIDE_RANGE
+}
+
+ +
FMOD.DSP_PAN_MODE
+FMOD.DSP_PAN_2D_STEREO_POSITION
+FMOD.DSP_PAN_2D_DIRECTION
+FMOD.DSP_PAN_2D_EXTENT
+FMOD.DSP_PAN_2D_ROTATION
+FMOD.DSP_PAN_2D_LFE_LEVEL
+FMOD.DSP_PAN_2D_STEREO_MODE
+FMOD.DSP_PAN_2D_STEREO_SEPARATION
+FMOD.DSP_PAN_2D_STEREO_AXIS
+FMOD.DSP_PAN_ENABLED_SPEAKERS
+FMOD.DSP_PAN_3D_POSITION
+FMOD.DSP_PAN_3D_ROLLOFF
+FMOD.DSP_PAN_3D_MIN_DISTANCE
+FMOD.DSP_PAN_3D_MAX_DISTANCE
+FMOD.DSP_PAN_3D_EXTENT_MODE
+FMOD.DSP_PAN_3D_SOUND_SIZE
+FMOD.DSP_PAN_3D_MIN_EXTENT
+FMOD.DSP_PAN_3D_PAN_BLEND
+FMOD.DSP_PAN_LFE_UPMIX_ENABLED
+FMOD.DSP_PAN_OVERALL_GAIN
+FMOD.DSP_PAN_SURROUND_SPEAKER_MODE
+FMOD.DSP_PAN_2D_HEIGHT_BLEND
+FMOD.DSP_PAN_ATTENUATION_RANGE
+FMOD.DSP_PAN_OVERRIDE_RANGE
+
+ +
+
FMOD_DSP_PAN_MODE
+
+

Panner mode.

+ +
+
FMOD_DSP_PAN_2D_STEREO_POSITION
+
+

2D Stereo pan position.

+
    +
  • Type: float
  • +
  • Units: Linear
  • +
  • Range: [-100, 100]
  • +
  • Default: 0
  • +
+
+
FMOD_DSP_PAN_2D_DIRECTION
+
+

2D Surround pan direction. Direction from center point of panning circle where 0 is front center and -180 or +180 is rear speakers center point.

+
    +
  • Type: float
  • +
  • Units: Degrees
  • +
  • Range: [-180, 180]
  • +
  • Default: 0
  • +
+
+
FMOD_DSP_PAN_2D_EXTENT
+
+

2D Surround pan extent.

+
    +
  • Type: float
  • +
  • Units: Degrees
  • +
  • Range: [0, 360]
  • +
  • Default: 360
  • +
+
+
FMOD_DSP_PAN_2D_ROTATION
+
+

2D Surround pan rotation.

+
    +
  • Type: float
  • +
  • Units: Degrees
  • +
  • Range: [-180, 180]
  • +
  • Default: 0
  • +
+
+
FMOD_DSP_PAN_2D_LFE_LEVEL
+
+

2D Surround pan LFE level.

+
    +
  • Type: float
  • +
  • Units: Decibels
  • +
  • Range: [-80, 20]
  • +
  • Default: 0
  • +
+
+
FMOD_DSP_PAN_2D_STEREO_MODE
+
+

Stereo-To-Surround Mode.

+ +
+
FMOD_DSP_PAN_2D_STEREO_SEPARATION
+
+

Stereo-To-Surround Stereo For FMOD_DSP_PAN_2D_STEREO_MODE_DISCRETE mode. Separation/width of L/R parts of stereo sound.

+
    +
  • Type: float
  • +
  • Units: Degrees
  • +
  • Range: [-180, 180]
  • +
  • Default: 60
  • +
+
+
FMOD_DSP_PAN_2D_STEREO_AXIS
+
+

Stereo-To-Surround Stereo For FMOD_DSP_PAN_2D_STEREO_MODE_DISCRETE mode. Axis/rotation of L/R parts of stereo sound.

+
    +
  • Type: float
  • +
  • Units: Degrees
  • +
  • Range: [-180, 180]
  • +
  • Default: 0
  • +
+
+
FMOD_DSP_PAN_ENABLED_SPEAKERS
+
+

Speakers Enabled Bitmask for each speaker from 0 to 32 to be considered by panner. Use to disable speakers from being panned to. 0 to 0xFFF. Default = 0xFFF (All on).

+
    +
  • Type: int
  • +
  • Range: [0, 0xFFF]
  • +
  • Default: 0xFFF
  • +
+
+
FMOD_DSP_PAN_3D_POSITION
+
+

3D Position of panner and listener(s).

+ +
+
FMOD_DSP_PAN_3D_ROLLOFF
+
+

3D volume attenuation curve shape.

+ +
+
FMOD_DSP_PAN_3D_MIN_DISTANCE
+
+

3D volume attenuation minimum distance when FMOD_DSP_OBJECTPAN_OVERRIDE_RANGE is true.

+ +
+
FMOD_DSP_PAN_3D_MAX_DISTANCE
+
+

3D volume attenuation maximum distance when FMOD_DSP_OBJECTPAN_OVERRIDE_RANGE is true.

+ +
+
FMOD_DSP_PAN_3D_EXTENT_MODE
+
+

3D Extent Mode.

+ +
+
FMOD_DSP_PAN_3D_SOUND_SIZE
+
+

3D Sound Size.

+ +
+
FMOD_DSP_PAN_3D_MIN_EXTENT
+
+

3D Min Extent.

+
    +
  • Type: float
  • +
  • Units: Degrees
  • +
  • Range: [0, 360]
  • +
  • Default: 0
  • +
+
+
FMOD_DSP_PAN_3D_PAN_BLEND
+
+

3D Pan Blend.

+
    +
  • Type: float
  • +
  • Units: Linear
  • +
  • Range: [0, 1]
  • +
  • Default: 0
  • +
+
+
FMOD_DSP_PAN_LFE_UPMIX_ENABLED
+
+

LFE Upmix Enabled. Determines whether non-LFE source channels should mix to the LFE or leave it alone. 0 (off) to 1 (on). Default = 0 (off).

+
    +
  • Type: int
  • +
  • Units: Linear
  • +
  • Range: [0, 1]
  • +
  • Default: 0
  • +
+
+
FMOD_DSP_PAN_OVERALL_GAIN
+
+

Overall gain to allow FMOD to know the DSP is scaling the signal for visualization purposes.

+ +
+
FMOD_DSP_PAN_SURROUND_SPEAKER_MODE
+
+

Surround speaker mode. (FMOD_SPEAKERMODE)

+ +
+
FMOD_DSP_PAN_2D_HEIGHT_BLEND
+
+

2D Height blend. When the input or FMOD_DSP_PAN_SURROUND_SPEAKER_MODE has height speakers, control the blend between ground and height. -1.0 (push top speakers to ground), 0.0 (preserve top / ground separation), 1.0 (push ground speakers to top).

+
    +
  • Type: float
  • +
  • Units: Linear
  • +
  • Range: [-1, 1]
  • +
  • Default: 0
  • +
+
+
FMOD_DSP_PAN_ATTENUATION_RANGE
+
+

Attenuation Range when FMOD_DSP_OBJECTPAN_OVERRIDE_RANGE is false.

+ +
+
FMOD_DSP_PAN_OVERRIDE_RANGE
+
+

Override Attenuation Range with FMOD_DSP_PAN_3D_MIN_DISTANCE and FMOD_DSP_PAN_3D_MAX_DISTANCE.

+
    +
  • Type: bool
  • +
  • Default: true
  • +
+
+
+

FMOD_DSP_PAN_3D_PAN_BLEND controls the percentage of the effect supplied by FMOD_DSP_PAN_2D_DIRECTION and FMOD_DSP_PAN_2D_EXTENT.

+

For FMOD_DSP_PAN_3D_POSITION, the following members in the FMOD_DSP_PARAMETER_3DATTRIBUTES_MULTI struct should be non zero.
+- numlisteners - This is typically 1, can be up to 8. Typically more than 1 is only used for split screen purposes. The FMOD Panner will average angles and produce the best compromise for panning and attenuation.
+- relative[listenernum].position - This is the delta between the listener position and the sound position. Typically the listener position is subtracted from the sound position.
+- relative[listenernum].forward - This is the sound's forward vector. Optional, set to 0,0,1 if not needed. This is only relevant for more than mono sounds in 3D, that are spread amongst the destination speakers at the time of panning.

+
    If the sound rotates then the L/R part of a stereo sound will rotate amongst its destination speakers.
+    If the sound has moved and pinpointed into a single speaker, rotation of the sound will have no effect as at that point the channels are collapsed into a single point.
+
+ +

For FMOD_DSP_PAN_2D_STEREO_MODE, when it is set to FMOD_DSP_PAN_2D_STEREO_MODE_DISCRETE, only FMOD_DSP_PAN_2D_STEREO_SEPARATION and FMOD_DSP_PAN_2D_STEREO_AXIS are used.
+When it is set to FMOD_DSP_PAN_2D_STEREO_MODE_DISTRIBUTED, then standard FMOD_DSP_PAN_2D_DIRECTION/FMOD_DSP_PAN_2D_EXTENT parameters are used.

+

FMOD_DSP_OBJECTPAN_OVERRIDE_RANGE defaults to true for backwards compatability.

+

See Also: FMOD_DSP_TYPE_PAN, DSP::setParameterFloat, DSP::setParameterInt, DSP::setParameterData, Controlling a Spatializer DSP.

+

FMOD_DSP_PAN_2D_STEREO_MODE_TYPE

+

2D stereo mode values for pan DSP.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
typedef enum FMOD_DSP_PAN_2D_STEREO_MODE_TYPE {
+  FMOD_DSP_PAN_2D_STEREO_MODE_DISTRIBUTED,
+  FMOD_DSP_PAN_2D_STEREO_MODE_DISCRETE
+} FMOD_DSP_PAN_2D_STEREO_MODE_TYPE;
+
+ +
enum DSP_PAN_2D_STEREO_MODE_TYPE
+{
+  DISTRIBUTED,
+  DISCRETE
+}
+
+ +
FMOD.DSP_PAN_2D_STEREO_MODE_DISTRIBUTED
+FMOD.DSP_PAN_2D_STEREO_MODE_DISCRETE
+
+ +
+
FMOD_DSP_PAN_2D_STEREO_MODE_DISTRIBUTED
+
The parts of a stereo sound are spread around destination speakers based on FMOD_DSP_PAN_2D_EXTENT / FMOD_DSP_PAN_2D_DIRECTION
+
FMOD_DSP_PAN_2D_STEREO_MODE_DISCRETE
+
The L/R parts of a stereo sound are rotated around a circle based on FMOD_DSP_PAN_2D_STEREO_AXIS / FMOD_DSP_PAN_2D_STEREO_SEPARATION.
+
+

See Also: FMOD_DSP_PAN_2D_STEREO_MODE, FMOD_DSP_TYPE_PAN, FMOD_DSP_PAN

+

FMOD_DSP_PAN_3D_EXTENT_MODE_TYPE

+

3D extent mode values for pan DSP.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
typedef enum FMOD_DSP_PAN_3D_EXTENT_MODE_TYPE {
+  FMOD_DSP_PAN_3D_EXTENT_MODE_AUTO,
+  FMOD_DSP_PAN_3D_EXTENT_MODE_USER,
+  FMOD_DSP_PAN_3D_EXTENT_MODE_OFF
+} FMOD_DSP_PAN_3D_EXTENT_MODE_TYPE;
+
+ +
enum DSP_PAN_3D_EXTENT_MODE_TYPE
+{
+  AUTO,
+  USER,
+  OFF
+}
+
+ +
FMOD.DSP_PAN_3D_EXTENT_MODE_AUTO
+FMOD.DSP_PAN_3D_EXTENT_MODE_USER
+FMOD.DSP_PAN_3D_EXTENT_MODE_OFF
+
+ +
+
FMOD_DSP_PAN_3D_EXTENT_MODE_AUTO
+
+
FMOD_DSP_PAN_3D_EXTENT_MODE_USER
+
+
FMOD_DSP_PAN_3D_EXTENT_MODE_OFF
+
+
+

See Also: FMOD_DSP_PAN_3D_EXTENT_MODE, FMOD_DSP_TYPE_PAN, FMOD_DSP_PAN

+

FMOD_DSP_PAN_3D_ROLLOFF_TYPE

+

3D roll-off values for pan DSP.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
typedef enum FMOD_DSP_PAN_3D_ROLLOFF_TYPE {
+  FMOD_DSP_PAN_3D_ROLLOFF_LINEARSQUARED,
+  FMOD_DSP_PAN_3D_ROLLOFF_LINEAR,
+  FMOD_DSP_PAN_3D_ROLLOFF_INVERSE,
+  FMOD_DSP_PAN_3D_ROLLOFF_INVERSETAPERED,
+  FMOD_DSP_PAN_3D_ROLLOFF_CUSTOM
+} FMOD_DSP_PAN_3D_ROLLOFF_TYPE;
+
+ +
enum DSP_PAN_3D_ROLLOFF_TYPE
+{
+  LINEARSQUARED,
+  LINEAR,
+  INVERSE,
+  INVERSETAPERED,
+  CUSTOM
+}
+
+ +
FMOD.DSP_PAN_3D_ROLLOFF_LINEARSQUARED
+FMOD.DSP_PAN_3D_ROLLOFF_LINEAR
+FMOD.DSP_PAN_3D_ROLLOFF_INVERSE
+FMOD.DSP_PAN_3D_ROLLOFF_INVERSETAPERED
+FMOD.DSP_PAN_3D_ROLLOFF_CUSTOM
+
+ +
+
FMOD_DSP_PAN_3D_ROLLOFF_LINEARSQUARED
+
This is a linear-square roll-off model. Below mindistance, the volume is unattenuated; as distance increases from mindistance to maxdistance, the volume attenuates to silence according to a linear squared gradient. For this roll-off mode, distance values greater than mindistance are scaled according to the rolloffscale. This roll-off mode provides steeper volume ramping close to the mindistance, and more gradual ramping close to the maxdistance, than linear roll-off mode.
+
Linear Square Roll-off Graph
+
FMOD_DSP_PAN_3D_ROLLOFF_LINEAR
+
This is a linear roll-off model. Below mindistance, the volume is unattenuated; as distance increases from mindistance to maxdistance, the volume attenuates to silence using a linear gradient. For this roll-off mode, distance values greater than mindistance are scaled according to the rolloffscale. While this roll-off mode is not as realistic as inverse roll-off mode, it is easier to comprehend.
+
Linear Roll-off Graph
+
FMOD_DSP_PAN_3D_ROLLOFF_INVERSE
+
This is an inverse roll-off model. Below mindistance, the volume is unattenuated; as distance increases above mindistance, the volume attenuates using mindistance/distance as the gradient until it reaches maxdistance, where it stops attenuating. For this roll-off mode, distance values greater than mindistance are scaled according to the rolloffscale. This roll-off mode accurately models the way sounds attenuate over distance in the real world. (DEFAULT)
+
Inverse Roll-off Graph
+
FMOD_DSP_PAN_3D_ROLLOFF_INVERSETAPERED
+
This is a combination of the inverse and linear-square roll-off models. At short distances where inverse roll-off would provide greater attenuation, it functions as inverse roll-off mode; then at greater distances where linear-square roll-off mode would provide greater attenuation, it uses that roll-off mode instead. For this roll-off mode, distance values greater than mindistance are scaled according to the rolloffscale. Inverse tapered roll-off mode approximates realistic behavior while still guaranteeing the sound attenuates to silence at maxdistance.
+
Inverse Tapered Roll-off Graph
+
FMOD_DSP_PAN_3D_ROLLOFF_CUSTOM
+
Custom roll-off can be defined by the programmer setting volume manually. Attenuation in the Pan DSP is turned off in this mode.
+
+

Minimum and Maximum distance settings are controlled with FMOD_DSP_PAN_3D_MIN_DISTANCE and FMOD_DSP_PAN_3D_MAX_DISTANCE.

+

See Also: FMOD_DSP_PAN_3D_ROLLOFF, FMOD_DSP_TYPE_PAN, FMOD_DSP_PAN

+

FMOD_DSP_PAN_MODE_TYPE

+

Pan mode values for the pan DSP.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
typedef enum FMOD_DSP_PAN_MODE_TYPE {
+  FMOD_DSP_PAN_MODE_MONO,
+  FMOD_DSP_PAN_MODE_STEREO,
+  FMOD_DSP_PAN_MODE_SURROUND
+} FMOD_DSP_PAN_MODE_TYPE;
+
+ +
enum DSP_PAN_MODE_TYPE
+{
+  MONO,
+  STEREO,
+  SURROUND
+}
+
+ +
FMOD.DSP_PAN_MODE_MONO
+FMOD.DSP_PAN_MODE_STEREO
+FMOD.DSP_PAN_MODE_SURROUND
+
+ +
+
FMOD_DSP_PAN_MODE_MONO
+
Single channel output.
+
FMOD_DSP_PAN_MODE_STEREO
+
Two channel output
+
FMOD_DSP_PAN_MODE_SURROUND
+
Three or more channel output. Includes common modes like quad, 5.1 or 7.1.
+
+

See Also: FMOD_DSP_PAN_MODE, FMOD_DSP_TYPE_PAN, FMOD_DSP_PAN

+

FMOD_DSP_PARAMEQ

+

Parametric EQ DSP parameter types.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
typedef enum FMOD_DSP_PARAMEQ {
+  FMOD_DSP_PARAMEQ_CENTER,
+  FMOD_DSP_PARAMEQ_BANDWIDTH,
+  FMOD_DSP_PARAMEQ_GAIN
+} FMOD_DSP_PARAMEQ;
+
+ +
enum DSP_PARAMEQ
+{
+  CENTER,
+  BANDWIDTH,
+  GAIN
+}
+
+ +
FMOD.DSP_PARAMEQ_CENTER
+FMOD.DSP_PARAMEQ_BANDWIDTH
+FMOD.DSP_PARAMEQ_GAIN
+
+ +
+
FMOD_DSP_PARAMEQ_CENTER
+
+

Frequency center.

+
    +
  • Type: float
  • +
  • Units: Hertz
  • +
  • Range: [20, 22000]
  • +
  • Default: 8000
  • +
+
+
FMOD_DSP_PARAMEQ_BANDWIDTH
+
+

Octave range around the center frequency to filter.

+
    +
  • Type: float
  • +
  • Range: [0.2, 5]
  • +
  • Default: 1
  • +
+
+
FMOD_DSP_PARAMEQ_GAIN
+
+

Frequency Gain in dB.

+
    +
  • Type: float
  • +
  • Units: Decibels
  • +
  • Range: [-30, 30]
  • +
  • Default: 0
  • +
+
+
+

Deprecated and will be removed in a future release, to emulate with FMOD_DSP_TYPE_MULTIBAND_EQ:

+
// Configure a single band (band A) as a peaking EQ (all other bands default to off).
+// Center frequency can be used as with the old effect.
+// Bandwidth can be applied by setting the 'Q' value of the new effect.
+// Gain at the center frequency can be used the same as with the old effect.
+FMOD_DSP_SetParameterInt(multiband, FMOD_DSP_MULTIBAND_EQ_A_FILTER, FMOD_DSP_MULTIBAND_EQ_FILTER_PEAKING);
+FMOD_DSP_SetParameterFloat(multiband, FMOD_DSP_MULTIBAND_EQ_A_FREQUENCY, center);
+FMOD_DSP_SetParameterFloat(multiband, FMOD_DSP_MULTIBAND_EQ_A_Q, bandwidth);
+FMOD_DSP_SetParameterFloat(multiband, FMOD_DSP_MULTIBAND_EQ_A_GAIN, gain);
+
+ +

Parametric EQ is a single band peaking EQ filter that attenuates or amplifies a selected frequency and its neighboring frequencies.

+

When the gain is set to zero decibels the sound will be unaffected and represents the original signal exactly.

+

See Also: FMOD_DSP_TYPE_PARAMEQ, DSP::setParameterFloat, DSP::getParameterFloat, FMOD_DSP_TYPE

+

FMOD_DSP_PITCHSHIFT

+

Pitch shifter DSP parameter types.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
typedef enum FMOD_DSP_PITCHSHIFT {
+  FMOD_DSP_PITCHSHIFT_PITCH,
+  FMOD_DSP_PITCHSHIFT_FFTSIZE,
+  FMOD_DSP_PITCHSHIFT_OVERLAP,
+  FMOD_DSP_PITCHSHIFT_MAXCHANNELS
+} FMOD_DSP_PITCHSHIFT;
+
+ +
enum DSP_PITCHSHIFT
+{
+  PITCH,
+  FFTSIZE,
+  OVERLAP,
+  MAXCHANNELS
+}
+
+ +
FMOD.DSP_PITCHSHIFT_PITCH
+FMOD.DSP_PITCHSHIFT_FFTSIZE
+FMOD.DSP_PITCHSHIFT_OVERLAP
+FMOD.DSP_PITCHSHIFT_MAXCHANNELS
+
+ +
+
FMOD_DSP_PITCHSHIFT_PITCH
+
+

Pitch value. 0.5 = one octave down, 2.0 = one octave up. 1.0 does not change the pitch.

+
    +
  • Type: float
  • +
  • Range: [0.5, 2]
  • +
  • Default: 1
  • +
+
+
FMOD_DSP_PITCHSHIFT_FFTSIZE
+
+

FFT window size - 256, 512, 1024, 2048, 4096. Increase this to reduce 'smearing'. This effect creates a warbling sound similar to when an mp3 is encoded at very low bitrates.

+
    +
  • Type: float
  • +
  • Default: 1024
  • +
+
+
FMOD_DSP_PITCHSHIFT_OVERLAP
+
Removed. Do not use. FMOD now uses 4 overlaps and cannot be changed.
+
FMOD_DSP_PITCHSHIFT_MAXCHANNELS
+
+

Maximum channels supported. 0 = same as FMOD's default output polyphony, 1 = mono, 2 = stereo etc. See remarks for more. It is recommended to leave it at 0.

+
    +
  • Type: float
  • +
  • Range: [0, 16]
  • +
+
+
+

FMOD_DSP_PITCHSHIFT_MAXCHANNELS dictates the amount of memory allocated. If this parameter is set to stereo, the pitch shift unit will allocate enough memory for 2 channels. If it is 5.1, it will allocate enough memory for a 6 channel pitch shift, etc. By default, the maxchannels value is 0, meaning that it allocates enough memory for the default speaker channel format as the system. You can get the system's default speaker channel format by calling System::getSoftwareFormat to see speakermode and numrawspeakers.

+

If the pitch shift effect is only ever applied to the global mix (i.e. with ChannelControl::addDSP on a ChannelGroup object), then 0 is the value to set as it will be enough to handle all speaker modes.

+

When the pitch shift is added to a Channel (i.e. with ChannelControl::addDSP on a Channel object) then the channel count of the signal that comes in could potentially be anything from 1 to 8. It is only in this case that you might want to increase the channel count above the output's channel count.

+

If a Channel pitch shift is set to a lower number than the signal's channel count that is coming in, it will not pitch shift the sound.

+

See Also: FMOD_DSP_TYPE_PITCHSHIFT, DSP::setParameterFloat

+

FMOD_DSP_RETURN

+

Return DSP parameter types.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
typedef enum FMOD_DSP_RETURN {
+  FMOD_DSP_RETURN_ID,
+  FMOD_DSP_RETURN_INPUT_SPEAKER_MODE
+} FMOD_DSP_RETURN;
+
+ +
enum DSP_RETURN
+{
+  ID,
+  INPUT_SPEAKER_MODE
+}
+
+ +
FMOD.DSP_RETURN_ID
+FMOD.DSP_RETURN_INPUT_SPEAKER_MODE
+
+ +
+
FMOD_DSP_RETURN_ID R/O
+
+

ID of this Return DSP.

+
    +
  • Type: int
  • +
  • Default: -1
  • +
+
+
FMOD_DSP_RETURN_INPUT_SPEAKER_MODE
+
+

Input speaker mode of this return.

+ +
+
+

See Also: FMOD_DSP_TYPE_RETURN, DSP::setParameterInt

+

FMOD_DSP_SEND

+

Send DSP parameter types.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
typedef enum FMOD_DSP_SEND {
+  FMOD_DSP_SEND_RETURNID,
+  FMOD_DSP_SEND_LEVEL
+} FMOD_DSP_SEND;
+
+ +
enum DSP_SEND
+{
+  RETURNID,
+  LEVEL,
+}
+
+ +
FMOD.DSP_SEND_RETURNID
+FMOD.DSP_SEND_LEVEL
+
+ +
+
FMOD_DSP_SEND_RETURNID
+
+

ID of the Return DSP this send is connected to where -1 indicates no connected return DSP.

+
    +
  • Type: int
  • +
  • Default = -1
  • +
+
+
FMOD_DSP_SEND_LEVEL
+
+

Send level.

+
    +
  • Type: float
  • +
  • Units: Linear
  • +
  • Range: [0, 1]
  • +
  • Default: 1
  • +
+
+
+

See Also: FMOD_DSP_TYPE_SEND, DSP::setParameterInt, DSP::setParameterFloat

+

FMOD_DSP_SFXREVERB

+

SFX reverb DSP parameter types.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
typedef enum FMOD_DSP_SFXREVERB {
+  FMOD_DSP_SFXREVERB_DECAYTIME,
+  FMOD_DSP_SFXREVERB_EARLYDELAY,
+  FMOD_DSP_SFXREVERB_LATEDELAY,
+  FMOD_DSP_SFXREVERB_HFREFERENCE,
+  FMOD_DSP_SFXREVERB_HFDECAYRATIO,
+  FMOD_DSP_SFXREVERB_DIFFUSION,
+  FMOD_DSP_SFXREVERB_DENSITY,
+  FMOD_DSP_SFXREVERB_LOWSHELFFREQUENCY,
+  FMOD_DSP_SFXREVERB_LOWSHELFGAIN,
+  FMOD_DSP_SFXREVERB_HIGHCUT,
+  FMOD_DSP_SFXREVERB_EARLYLATEMIX,
+  FMOD_DSP_SFXREVERB_WETLEVEL,
+  FMOD_DSP_SFXREVERB_DRYLEVEL
+} FMOD_DSP_SFXREVERB;
+
+ +
enum DSP_SFXREVERB
+{
+  DECAYTIME,
+  EARLYDELAY,
+  LATEDELAY,
+  HFREFERENCE,
+  HFDECAYRATIO,
+  DIFFUSION,
+  DENSITY,
+  LOWSHELFFREQUENCY,
+  LOWSHELFGAIN,
+  HIGHCUT,
+  EARLYLATEMIX,
+  WETLEVEL,
+  DRYLEVEL
+}
+
+ +
FMOD.DSP_SFXREVERB_DECAYTIME
+FMOD.DSP_SFXREVERB_EARLYDELAY
+FMOD.DSP_SFXREVERB_LATEDELAY
+FMOD.DSP_SFXREVERB_HFREFERENCE
+FMOD.DSP_SFXREVERB_HFDECAYRATIO
+FMOD.DSP_SFXREVERB_DIFFUSION
+FMOD.DSP_SFXREVERB_DENSITY
+FMOD.DSP_SFXREVERB_LOWSHELFFREQUENCY
+FMOD.DSP_SFXREVERB_LOWSHELFGAIN
+FMOD.DSP_SFXREVERB_HIGHCUT
+FMOD.DSP_SFXREVERB_EARLYLATEMIX
+FMOD.DSP_SFXREVERB_WETLEVEL
+FMOD.DSP_SFXREVERB_DRYLEVEL
+
+ +
+
FMOD_DSP_SFXREVERB_DECAYTIME
+
+

Reverberation decay time at low-frequencies.

+
    +
  • Type: float
  • +
  • Units: Milliseconds
  • +
  • Range: [100, 20000]
  • +
  • Default: 1500
  • +
+
+
FMOD_DSP_SFXREVERB_EARLYDELAY
+
+

Delay time of first reflection.

+
    +
  • Type: float
  • +
  • Units: Milliseconds
  • +
  • Range: [0, 300]
  • +
  • Default: 20
  • +
+
+
FMOD_DSP_SFXREVERB_LATEDELAY
+
+

Late reverberation delay time relative to first reflection in milliseconds.

+
    +
  • Type: float
  • +
  • Units: Milliseconds
  • +
  • Range: [0, 100]
  • +
  • Default: 40
  • +
+
+
FMOD_DSP_SFXREVERB_HFREFERENCE
+
+

Reference frequency for high-frequency decay.

+
    +
  • Type: float
  • +
  • Units: Hertz
  • +
  • Range: [20, 20000]
  • +
  • Default: 5000
  • +
+
+
FMOD_DSP_SFXREVERB_HFDECAYRATIO
+
+

High-frequency decay time relative to decay time.

+
    +
  • Type: float
  • +
  • Units: Percent
  • +
  • Range: [10, 100]
  • +
  • Default: 50
  • +
+
+
FMOD_DSP_SFXREVERB_DIFFUSION
+
+

Reverberation diffusion (echo density).

+
    +
  • Type: float
  • +
  • Units: Percent
  • +
  • Range: [10, 100]
  • +
  • Default: 50
  • +
+
+
FMOD_DSP_SFXREVERB_DENSITY
+
+

Reverberation density (modal density).

+
    +
  • Type: float
  • +
  • Units: Percent
  • +
  • Range: [10, 100]
  • +
  • Default: 50
  • +
+
+
FMOD_DSP_SFXREVERB_LOWSHELFFREQUENCY
+
+

Transition frequency of low-shelf filter.

+
    +
  • Type: float
  • +
  • Units: Hertz
  • +
  • Range: [20, 1000]
  • +
  • Default: 250
  • +
+
+
FMOD_DSP_SFXREVERB_LOWSHELFGAIN
+
+

Gain of low-shelf filter.

+
    +
  • Type: float
  • +
  • Units: Decibels
  • +
  • Range: [-36, 12]
  • +
  • Default: 0
  • +
+
+
FMOD_DSP_SFXREVERB_HIGHCUT
+
+

Cutoff frequency of low-pass filter.

+
    +
  • Type: float
  • +
  • Units: Hertz
  • +
  • Range: [20, 20000]
  • +
  • Default: 20000
  • +
+
+
FMOD_DSP_SFXREVERB_EARLYLATEMIX
+
+

Blend ratio of late reverb to early reflections.

+
    +
  • Type: float
  • +
  • Units: Percent
  • +
  • Range: [0, 100]
  • +
  • Default: 50
  • +
+
+
FMOD_DSP_SFXREVERB_WETLEVEL
+
+

Reverb signal level.

+
    +
  • Type: float
  • +
  • Units: Decibels
  • +
  • Range: [-80, 20]
  • +
  • Default: -6
  • +
+
+
FMOD_DSP_SFXREVERB_DRYLEVEL
+
+

Dry signal level.

+
    +
  • Type: float
  • +
  • Units: Decibels
  • +
  • Range: [-80, 20]
  • +
  • Default: 0
  • +
+
+
+

This is a high quality I3DL2 based reverb. On top of the I3DL2 property set, "Dry Level" is also included to allow the dry mix to be changed. These properties can be set with presets in FMOD_REVERB_PRESETS.

+

See Also: FMOD_DSP_TYPE_SFXREVERB, DSP::setParameterFloat, FMOD_REVERB_PRESETS

+

FMOD_DSP_THREE_EQ

+

Three EQ DSP parameter types.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
typedef enum FMOD_DSP_THREE_EQ {
+  FMOD_DSP_THREE_EQ_LOWGAIN,
+  FMOD_DSP_THREE_EQ_MIDGAIN,
+  FMOD_DSP_THREE_EQ_HIGHGAIN,
+  FMOD_DSP_THREE_EQ_LOWCROSSOVER,
+  FMOD_DSP_THREE_EQ_HIGHCROSSOVER,
+  FMOD_DSP_THREE_EQ_CROSSOVERSLOPE
+} FMOD_DSP_THREE_EQ;
+
+ +
enum DSP_THREE_EQ
+{
+  LOWGAIN,
+  MIDGAIN,
+  HIGHGAIN,
+  LOWCROSSOVER,
+  HIGHCROSSOVER,
+  CROSSOVERSLOPE
+}
+
+ +
FMOD.DSP_THREE_EQ_LOWGAIN
+FMOD.DSP_THREE_EQ_MIDGAIN
+FMOD.DSP_THREE_EQ_HIGHGAIN
+FMOD.DSP_THREE_EQ_LOWCROSSOVER
+FMOD.DSP_THREE_EQ_HIGHCROSSOVER
+FMOD.DSP_THREE_EQ_CROSSOVERSLOPE
+
+ +
+
FMOD_DSP_THREE_EQ_LOWGAIN
+
+

Low frequency gain.

+
    +
  • Type: float
  • +
  • Units: Decibels
  • +
  • Range: [-80, 10]
  • +
  • Default: 0
  • +
+
+
FMOD_DSP_THREE_EQ_MIDGAIN
+
+

Mid frequency gain.

+
    +
  • Type: float
  • +
  • Units: Decibels
  • +
  • Range: [-80, 10]
  • +
  • Default: 0
  • +
+
+
FMOD_DSP_THREE_EQ_HIGHGAIN
+
+

High frequency gain.

+
    +
  • Type: float
  • +
  • Units: Decibels
  • +
  • Range: [-80, 10]
  • +
  • Default: 0
  • +
+
+
FMOD_DSP_THREE_EQ_LOWCROSSOVER
+
+

Low-to-mid crossover frequency.

+
    +
  • Type: float
  • +
  • Units: Hertz
  • +
  • Range: [10, 22000]
  • +
  • Default: 400
  • +
+
+
FMOD_DSP_THREE_EQ_HIGHCROSSOVER
+
+

Mid-to-high crossover frequency.

+
    +
  • Type: float
  • +
  • Units: Hertz
  • +
  • Range: [10, 22000]
  • +
  • Default: 4000
  • +
+
+
FMOD_DSP_THREE_EQ_CROSSOVERSLOPE
+
+

Crossover Slope type.

+ +
+
+

See Also: FMOD_DSP_TYPE_THREE_EQ, DSP::setParameterFloat, DSP::setParameterInt

+

FMOD_DSP_THREE_EQ_CROSSOVERSLOPE_TYPE

+

Crossover values for the three EQ DSP.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
typedef enum FMOD_DSP_THREE_EQ_CROSSOVERSLOPE_TYPE {
+  FMOD_DSP_THREE_EQ_CROSSOVERSLOPE_12DB,
+  FMOD_DSP_THREE_EQ_CROSSOVERSLOPE_24DB,
+  FMOD_DSP_THREE_EQ_CROSSOVERSLOPE_48DB
+} FMOD_DSP_THREE_EQ_CROSSOVERSLOPE_TYPE;
+
+ +
enum DSP_THREE_EQ_CROSSOVERSLOPE_TYPE
+{
+  _12DB,
+  _24DB,
+  _48DB
+}
+
+ +
FMOD.DSP_THREE_EQ_CROSSOVERSLOPE_12DB
+FMOD.DSP_THREE_EQ_CROSSOVERSLOPE_24DB
+FMOD.DSP_THREE_EQ_CROSSOVERSLOPE_48DB
+
+ +
+
FMOD_DSP_THREE_EQ_CROSSOVERSLOPE_12DB
+
12dB/Octave crossover slope.
+
FMOD_DSP_THREE_EQ_CROSSOVERSLOPE_24DB
+
24dB/Octave crossover slope.
+
FMOD_DSP_THREE_EQ_CROSSOVERSLOPE_48DB
+
48dB/Octave crossover slope.
+
+

See Also: FMOD_DSP_THREE_EQ_CROSSOVERSLOPE, FMOD_DSP_TYPE_THREE_EQ, FMOD_DSP_THREE_EQ

+

FMOD_DSP_TRANSCEIVER

+

Transceiver DSP parameter types.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
typedef enum FMOD_DSP_TRANSCEIVER {
+  FMOD_DSP_TRANSCEIVER_TRANSMIT,
+  FMOD_DSP_TRANSCEIVER_GAIN,
+  FMOD_DSP_TRANSCEIVER_CHANNEL,
+  FMOD_DSP_TRANSCEIVER_TRANSMITSPEAKERMODE
+} FMOD_DSP_TRANSCEIVER;
+
+ +
enum DSP_TRANSCEIVER
+{
+  TRANSMIT,
+  GAIN,
+  CHANNEL,
+  TRANSMITSPEAKERMODE
+}
+
+ +
FMOD.DSP_TRANSCEIVER_TRANSMIT
+FMOD.DSP_TRANSCEIVER_GAIN
+FMOD.DSP_TRANSCEIVER_CHANNEL
+FMOD.DSP_TRANSCEIVER_TRANSMITSPEAKERMODE
+
+ +
+
FMOD_DSP_TRANSCEIVER_TRANSMIT
+
+

FALSE = Transceiver is a 'receiver' (like a return) and accepts data from a channel. TRUE = Transceiver is a 'transmitter' (like a send).

+
    +
  • Type: bool
  • +
  • Default: false
  • +
+
+
FMOD_DSP_TRANSCEIVER_GAIN
+
+

Gain to receive or transmit.

+
    +
  • Type: float
  • +
  • Units: Decibels
  • +
  • Range: [-80, 10]
  • +
  • Default: 0
  • +
+
+
FMOD_DSP_TRANSCEIVER_CHANNEL
+
+

Global slot that can be transmitted to or received from.

+
    +
  • Type: int
  • +
  • Range: [0, 31]
  • +
  • Default: 0
  • +
+
+
FMOD_DSP_TRANSCEIVER_TRANSMITSPEAKERMODE
+
+

Speaker mode (transmitter mode only). (FMOD_DSP_TRANSCEIVER_SPEAKERMODE)

+ +
+
+

The transceiver only transmits and receives to a global array of 32 channels. The transceiver can be set to receiver mode (like a return) and can receive the signal at a variable gain. The transceiver can also be set to transmit to a channel (like a send) and can transmit the signal with a variable gain.

+

The FMOD_DSP_TRANSCEIVER_TRANSMITSPEAKERMODE is only applicable to the transmission format, not the receive format. This means this parameter is ignored in 'receive mode'. This allows receivers to receive at the speaker mode of the user's choice. Receiving from a mono channel, is cheaper than receiving from a surround channel for example. The 3 speaker modes FMOD_DSP_TRANSCEIVER_SPEAKERMODE_MONO, FMOD_DSP_TRANSCEIVER_SPEAKERMODE_STEREO, FMOD_DSP_TRANSCEIVER_SPEAKERMODE_SURROUND are stored as separate buffers in memory for a transmitter channel. To save memory, use 1 common speaker mode for a transmitter.

+

The transceiver is double buffered to avoid desyncing of transmitters and receivers. This means there will be a 1 block delay on a receiver, compared to the data sent from a transmitter. Multiple transmitters sending to the same channel will be mixed together.

+

See Also: FMOD_DSP_TYPE_TRANSCEIVER, FMOD_DSP_TRANSCEIVER_GAIN, DSP::setParameterFloat, DSP::setParameterInt, DSP::setParameterBool

+

FMOD_DSP_TRANSCEIVER_SPEAKERMODE

+

Speaker mode values for the transceiver DSP.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
typedef enum FMOD_DSP_TRANSCEIVER_SPEAKERMODE {
+  FMOD_DSP_TRANSCEIVER_SPEAKERMODE_AUTO = -1,
+  FMOD_DSP_TRANSCEIVER_SPEAKERMODE_MONO = 0,
+  FMOD_DSP_TRANSCEIVER_SPEAKERMODE_STEREO,
+  FMOD_DSP_TRANSCEIVER_SPEAKERMODE_SURROUND
+} FMOD_DSP_TRANSCEIVER_SPEAKERMODE;
+
+ +
enum DSP_TRANSCEIVER_SPEAKERMODE
+{
+  AUTO = -1,
+  MONO = 0,
+  STEREO,
+  SURROUND,
+}
+
+ +
FMOD.DSP_TRANSCEIVER_SPEAKERMODE_AUTO = -1
+FMOD.DSP_TRANSCEIVER_SPEAKERMODE_MONO = 0
+FMOD.DSP_TRANSCEIVER_SPEAKERMODE_STEREO
+FMOD.DSP_TRANSCEIVER_SPEAKERMODE_SURROUND
+
+ +
+
FMOD_DSP_TRANSCEIVER_SPEAKERMODE_AUTO
+
The transmitter uses the channel count of its input signal as the channel count of its channel buffer.
+
FMOD_DSP_TRANSCEIVER_SPEAKERMODE_MONO
+
The transmitter downmixes its input signal to a mono channel buffer.
+
FMOD_DSP_TRANSCEIVER_SPEAKERMODE_STEREO
+
The transmitter upmixes or downmixes its input signal to a stereo channel buffer.
+
FMOD_DSP_TRANSCEIVER_SPEAKERMODE_SURROUND
+
The transmitter upmixes or downmixes its input signal to a surround channel buffer. Surround could mean any speaker mode above stereo, so this could mean quad/surround/5.1/7.1.
+
+

The speaker mode of a transceiver buffer (of which there are up to 32) is determined automatically depending on the signal flowing through the transceiver effect, or it can be forced to a specific mode. Smaller fixed speaker mode buffers can save memory. This is only relevant for transmitter DSPs, as only transmitters control the format of the transceiver channel's buffer.

+

If multiple transceivers transmit to a single buffer in different speaker modes, the buffer allocates memory for each of those speaker modes. This uses more memory than a single speaker mode. If there are multiple receivers reading from a channel with multiple speaker modes in its buffer, each receiver reads them all and mixes them together.

+

If the system's speaker mode is stereo or mono, it will not create a 3rd buffer, it will just use the mono/stereo speaker mode buffer.

+

See Also: FMOD_DSP_TYPE_TRANSCEIVER, FMOD_DSP_TRANSCEIVER_SPEAKERMODE, DSP::setParameterInt

+

FMOD_DSP_TREMOLO

+

Tremolo DSP parameter types.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
typedef enum FMOD_DSP_TREMOLO {
+  FMOD_DSP_TREMOLO_FREQUENCY,
+  FMOD_DSP_TREMOLO_DEPTH,
+  FMOD_DSP_TREMOLO_SHAPE,
+  FMOD_DSP_TREMOLO_SKEW,
+  FMOD_DSP_TREMOLO_DUTY,
+  FMOD_DSP_TREMOLO_SQUARE,
+  FMOD_DSP_TREMOLO_PHASE,
+  FMOD_DSP_TREMOLO_SPREAD
+} FMOD_DSP_TREMOLO;
+
+ +
enum DSP_TREMOLO
+{
+  FREQUENCY,
+  DEPTH,
+  SHAPE,
+  SKEW,
+  DUTY,
+  SQUARE,
+  PHASE,
+  SPREAD
+}
+
+ +
FMOD.DSP_TREMOLO_FREQUENCY
+FMOD.DSP_TREMOLO_DEPTH
+FMOD.DSP_TREMOLO_SHAPE
+FMOD.DSP_TREMOLO_SKEW
+FMOD.DSP_TREMOLO_DUTY
+FMOD.DSP_TREMOLO_SQUARE
+FMOD.DSP_TREMOLO_PHASE
+FMOD.DSP_TREMOLO_SPREAD
+
+ +
+
FMOD_DSP_TREMOLO_FREQUENCY
+
+

LFO frequency.

+
    +
  • Type: float
  • +
  • Units: Hertz
  • +
  • Range: [0.1, 20]
  • +
  • Default: 5
  • +
+
+
FMOD_DSP_TREMOLO_DEPTH
+
+

Tremolo depth.

+
    +
  • Type: float
  • +
  • Units: Linear
  • +
  • Range: [0, 1]
  • +
  • Default: 1
  • +
+
+
FMOD_DSP_TREMOLO_SHAPE
+
+

LFO shape morph between triangle and sine.

+
    +
  • Type: float
  • +
  • Units: Linear
  • +
  • Range: [0, 1]
  • +
  • Default: 1
  • +
+
+
FMOD_DSP_TREMOLO_SKEW
+
+

Time-skewing of LFO cycle.

+
    +
  • Type: float
  • +
  • Units: Linear
  • +
  • Range: [-1, 1]
  • +
  • Default: 0
  • +
+
+
FMOD_DSP_TREMOLO_DUTY
+
+

LFO on-time.

+
    +
  • Type: float
  • +
  • Units: Linear
  • +
  • Range: [0, 1]
  • +
  • Default: 0.5
  • +
+
+
FMOD_DSP_TREMOLO_SQUARE
+
+

Flatness of the LFO shape.

+
    +
  • Type: float
  • +
  • Units: Linear
  • +
  • Range: [0, 1]
  • +
  • Default: 1
  • +
+
+
FMOD_DSP_TREMOLO_PHASE
+
+

Instantaneous LFO phase.

+
    +
  • Type: float
  • +
  • Units: Linear
  • +
  • Range: [0, 1]
  • +
  • Default: 0
  • +
+
+
FMOD_DSP_TREMOLO_SPREAD
+
+

Rotation / auto-pan effect.

+
    +
  • Type: float
  • +
  • Units: Linear
  • +
  • Range: [-1, 1]
  • +
  • Default: 0
  • +
+
+
+

The tremolo effect varies the amplitude of a sound. Depending on the settings, this unit can produce a tremolo, chopper or auto-pan effect.

+

The shape of the LFO (low freq. oscillator) can morphed between sine, triangle and sawtooth waves using the FMOD_DSP_TREMOLO_SHAPE and FMOD_DSP_TREMOLO_SKEW parameters.

+

FMOD_DSP_TREMOLO_DUTY and FMOD_DSP_TREMOLO_SQUARE are useful for a chopper-type effect where the first controls the on-time duration and second controls the flatness of the envelope.

+

FMOD_DSP_TREMOLO_SPREAD varies the LFO phase between channels to get an auto-pan effect. This works best with a sine shape LFO.

+

The LFO can be synchronized using the FMOD_DSP_TREMOLO_PHASE parameter which sets its instantaneous phase.

+

See Also: FMOD_DSP_TYPE_TREMOLO, DSP::setParameterFloat

+

FMOD_DSP_TYPE

+

DSP types.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
typedef enum FMOD_DSP_TYPE {
+  FMOD_DSP_TYPE_UNKNOWN,
+  FMOD_DSP_TYPE_MIXER,
+  FMOD_DSP_TYPE_OSCILLATOR,
+  FMOD_DSP_TYPE_LOWPASS,
+  FMOD_DSP_TYPE_ITLOWPASS,
+  FMOD_DSP_TYPE_HIGHPASS,
+  FMOD_DSP_TYPE_ECHO,
+  FMOD_DSP_TYPE_FADER,
+  FMOD_DSP_TYPE_FLANGE,
+  FMOD_DSP_TYPE_DISTORTION,
+  FMOD_DSP_TYPE_NORMALIZE,
+  FMOD_DSP_TYPE_LIMITER,
+  FMOD_DSP_TYPE_PARAMEQ,
+  FMOD_DSP_TYPE_PITCHSHIFT,
+  FMOD_DSP_TYPE_CHORUS,
+  FMOD_DSP_TYPE_ITECHO,
+  FMOD_DSP_TYPE_COMPRESSOR,
+  FMOD_DSP_TYPE_SFXREVERB,
+  FMOD_DSP_TYPE_LOWPASS_SIMPLE,
+  FMOD_DSP_TYPE_DELAY,
+  FMOD_DSP_TYPE_TREMOLO,
+  FMOD_DSP_TYPE_SEND,
+  FMOD_DSP_TYPE_RETURN,
+  FMOD_DSP_TYPE_HIGHPASS_SIMPLE,
+  FMOD_DSP_TYPE_PAN,
+  FMOD_DSP_TYPE_THREE_EQ,
+  FMOD_DSP_TYPE_FFT,
+  FMOD_DSP_TYPE_LOUDNESS_METER,
+  FMOD_DSP_TYPE_CONVOLUTIONREVERB,
+  FMOD_DSP_TYPE_CHANNELMIX,
+  FMOD_DSP_TYPE_TRANSCEIVER,
+  FMOD_DSP_TYPE_OBJECTPAN,
+  FMOD_DSP_TYPE_MULTIBAND_EQ,
+  FMOD_DSP_TYPE_MULTIBAND_DYNAMICS,
+  FMOD_DSP_TYPE_MAX
+} FMOD_DSP_TYPE;
+
+ +
enum DSP_TYPE : int
+{
+  UNKNOWN,
+  MIXER,
+  OSCILLATOR,
+  LOWPASS,
+  ITLOWPASS,
+  HIGHPASS,
+  ECHO,
+  FADER,
+  FLANGE,
+  DISTORTION,
+  NORMALIZE,
+  LIMITER,
+  PARAMEQ,
+  PITCHSHIFT,
+  CHORUS,
+  ITECHO,
+  COMPRESSOR,
+  SFXREVERB,
+  LOWPASS_SIMPLE,
+  DELAY,
+  TREMOLO,
+  SEND,
+  RETURN,
+  HIGHPASS_SIMPLE,
+  PAN,
+  THREE_EQ,
+  FFT,
+  LOUDNESS_METER,
+  CONVOLUTIONREVERB,
+  CHANNELMIX,
+  TRANSCEIVER,
+  OBJECTPAN,
+  MULTIBAND_EQ,
+  MULTIBAND_DYNAMICS,
+  MAX
+}
+
+ +
FMOD.DSP_TYPE_UNKNOWN
+FMOD.DSP_TYPE_MIXER
+FMOD.DSP_TYPE_OSCILLATOR
+FMOD.DSP_TYPE_LOWPASS
+FMOD.DSP_TYPE_ITLOWPASS
+FMOD.DSP_TYPE_HIGHPASS
+FMOD.DSP_TYPE_ECHO
+FMOD.DSP_TYPE_FADER
+FMOD.DSP_TYPE_FLANGE
+FMOD.DSP_TYPE_DISTORTION
+FMOD.DSP_TYPE_NORMALIZE
+FMOD.DSP_TYPE_LIMITER
+FMOD.DSP_TYPE_PARAMEQ
+FMOD.DSP_TYPE_PITCHSHIFT
+FMOD.DSP_TYPE_CHORUS
+FMOD.DSP_TYPE_ITECHO
+FMOD.DSP_TYPE_COMPRESSOR
+FMOD.DSP_TYPE_SFXREVERB
+FMOD.DSP_TYPE_LOWPASS_SIMPLE
+FMOD.DSP_TYPE_DELAY
+FMOD.DSP_TYPE_TREMOLO
+FMOD.DSP_TYPE_SEND
+FMOD.DSP_TYPE_RETURN
+FMOD.DSP_TYPE_HIGHPASS_SIMPLE
+FMOD.DSP_TYPE_PAN
+FMOD.DSP_TYPE_THREE_EQ
+FMOD.DSP_TYPE_FFT
+FMOD.DSP_TYPE_LOUDNESS_METER
+FMOD.DSP_TYPE_CONVOLUTIONREVERB
+FMOD.DSP_TYPE_CHANNELMIX
+FMOD.DSP_TYPE_TRANSCEIVER
+FMOD.DSP_TYPE_OBJECTPAN
+FMOD.DSP_TYPE_MULTIBAND_EQ
+FMOD.DSP_TYPE_MULTIBAND_DYNAMICS
+FMOD.DSP_TYPE_MAX
+
+ +
+
FMOD_DSP_TYPE_UNKNOWN
+
Was created via a non-FMOD plug-in and has an unknown purpose.
+
FMOD_DSP_TYPE_MIXER
+
Does not process the signal. Acts as a unit purely for mixing inputs.
+
FMOD_DSP_TYPE_OSCILLATOR
+
Generates sine/square/saw/triangle or noise tones. See FMOD_DSP_OSCILLATOR for parameter information, Effect reference - Oscillator for overview.
+
FMOD_DSP_TYPE_LOWPASS
+
Filters sound using a high quality, resonant lowpass filter algorithm but consumes more CPU time. Deprecated and will be removed in a future release. See FMOD_DSP_LOWPASS remarks for parameter information, Effect reference - Low Pass for overview.
+
FMOD_DSP_TYPE_ITLOWPASS
+
Filters sound using a resonant lowpass filter algorithm that is used in Impulse Tracker, but with limited cutoff range (0 to 8060hz). See FMOD_DSP_ITLOWPASS for parameter information, Effect reference - IT Low Pass for overview.
+
FMOD_DSP_TYPE_HIGHPASS
+
Filters sound using a resonant highpass filter algorithm. Deprecated and will be removed in a future release. See FMOD_DSP_HIGHPASS remarks for parameter information, Effect reference - High Pass for overview.
+
FMOD_DSP_TYPE_ECHO
+
Produces an echo on the sound and fades out at the desired rate. See FMOD_DSP_ECHO for parameter information, Effect reference - Echo for overview.
+
FMOD_DSP_TYPE_FADER
+
Pans and scales the volume of a unit. See FMOD_DSP_FADER for parameter information, Effect reference - Fader for overview.
+
FMOD_DSP_TYPE_FLANGE
+
Produces a flange effect on the sound. See FMOD_DSP_FLANGE for parameter information, Effect reference - Flange for overview.
+
FMOD_DSP_TYPE_DISTORTION
+
Distorts the sound. See FMOD_DSP_DISTORTION for parameter information, Effect reference - Distortion for overview.
+
FMOD_DSP_TYPE_NORMALIZE
+
Normalizes or amplifies the sound to a certain level. See FMOD_DSP_NORMALIZE for parameter information, Effect reference - Normalize for overview.
+
FMOD_DSP_TYPE_LIMITER
+
Limits the sound to a certain level. See FMOD_DSP_LIMITER for parameter information, Effect reference - Limiter for overview.
+
FMOD_DSP_TYPE_PARAMEQ
+
Attenuates or amplifies a selected frequency range. Deprecated and will be removed in a future release. See FMOD_DSP_PARAMEQ for parameter information, Effect reference - Parametric EQ for overview.
+
FMOD_DSP_TYPE_PITCHSHIFT
+
Bends the pitch of a sound without changing the speed of playback. See FMOD_DSP_PITCHSHIFT for parameter information, Effect reference - Pitch Shifter for overview.
+
FMOD_DSP_TYPE_CHORUS
+
Produces a chorus effect on the sound. See FMOD_DSP_CHORUS for parameter information, Effect reference - Chorus for overview.
+
FMOD_DSP_TYPE_ITECHO
+
Produces an echo on the sound and fades out at the desired rate as is used in Impulse Tracker. See FMOD_DSP_ITECHO for parameter information, Effect reference - IT Echo for overview.
+
FMOD_DSP_TYPE_COMPRESSOR
+
Dynamic compression (linked/unlinked multi-channel, wideband). See FMOD_DSP_COMPRESSOR for parameter information, Effect reference - Compressor for overview.
+
FMOD_DSP_TYPE_SFXREVERB
+
I3DL2 reverb effect. See FMOD_DSP_SFXREVERB for parameter information, Effect reference - SFX Reverb for overview.
+
FMOD_DSP_TYPE_LOWPASS_SIMPLE
+
Filters sound using a simple lowpass with no resonance, but has flexible cutoff and is fast. Deprecated and will be removed in a future release. See FMOD_DSP_LOWPASS_SIMPLE remarks for parameter information, Effect reference - Low Pass Simple for overview.
+
FMOD_DSP_TYPE_DELAY
+
Produces different delays on individual channels of the sound. See FMOD_DSP_DELAY for parameter information, Effect reference - Delay for overview.
+
FMOD_DSP_TYPE_TREMOLO
+
Produces a tremolo / chopper effect on the sound. See FMOD_DSP_TREMOLO for parameter information, Effect reference - Tremolo for overview.
+
FMOD_DSP_TYPE_SEND
+
Sends a copy of the signal to a return DSP anywhere in the DSP tree. See FMOD_DSP_SEND for parameter information, Effect reference - Send for overview.
+
FMOD_DSP_TYPE_RETURN
+
Receives signals from a number of send DSPs. See FMOD_DSP_RETURN for parameter information, Effect reference - Return for overview.
+
FMOD_DSP_TYPE_HIGHPASS_SIMPLE
+
Filters sound using a simple highpass with no resonance, but has flexible cutoff and is fast. Deprecated and will be removed in a future release. See FMOD_DSP_HIGHPASS_SIMPLE remarks for parameter information, Effect reference - High Pass Simple for overview.
+
FMOD_DSP_TYPE_PAN
+
Pans the signal in 2D or 3D, possibly upmixing or downmixing as well. See FMOD_DSP_PAN for parameter information, Effect reference - Pan for overview.
+
FMOD_DSP_TYPE_THREE_EQ
+
Three-band equalizer. See FMOD_DSP_THREE_EQ for parameter information, Effect reference - Three EQ for overview.
+
FMOD_DSP_TYPE_FFT
+
Analyzes the signal and provides spectrum information back through getParameter. See FMOD_DSP_FFT for parameter information, Effect reference - FFT for overview.
+
FMOD_DSP_TYPE_LOUDNESS_METER
+
Analyzes the loudness and true peak of the signal.
+
FMOD_DSP_TYPE_CONVOLUTIONREVERB
+
Convolution reverb. See FMOD_DSP_CONVOLUTION_REVERB for parameter information, Effect reference - Convolution Reverb for overview.
+
FMOD_DSP_TYPE_CHANNELMIX
+
Provides per channel gain, channel grouping of the input signal which also sets the speaker format for the output signal, and customizable input to output channel routing. See FMOD_DSP_CHANNELMIX for parameter information, Effect reference - Channel Mix for overview.
+
FMOD_DSP_TYPE_TRANSCEIVER
+
'sends' and 'receives' from a selection of up to 32 different slots. It is like a send/return but it uses global slots rather than returns as the destination. It also has other features. Multiple transceivers can receive from a single channel, or multiple transceivers can send to a single channel, or a combination of both. See FMOD_DSP_TRANSCEIVER for parameter information, Effect reference - Transceiver for overview.
+
FMOD_DSP_TYPE_OBJECTPAN
+
Spatializes input signal by passing it to an external object mixer. See FMOD_DSP_OBJECTPAN for parameter information, Effect reference - Object Panner for overview.
+
FMOD_DSP_TYPE_MULTIBAND_EQ
+
Five band parametric equalizer. See FMOD_DSP_MULTIBAND_EQ for parameter information, Effect reference - Multiband Equalizer for overview.
+
FMOD_DSP_TYPE_MULTIBAND_DYNAMICS
+
Three-band compressor/expander. See FMOD_DSP_MULTIBAND_DYNAMICS for parameter information, Effect reference - Multiband Dynamics for overview.
+
FMOD_DSP_TYPE_MAX
+
Maximum number of pre-defined DSP types.
+
+

See Also: System::createDSPByType

+ + +
+ + + diff --git a/FMOD/doc/FMOD API User Manual/core-api-common.html b/FMOD/doc/FMOD API User Manual/core-api-common.html new file mode 100644 index 0000000..2b49581 --- /dev/null +++ b/FMOD/doc/FMOD API User Manual/core-api-common.html @@ -0,0 +1,2639 @@ + + +Core API Reference | Common + + + + +
+ +
+

11. Core API Reference | Common

+

File:

+
    +
  • File_GetDiskBusy Information function to retrieve the state of FMOD disk access.
  • +
  • File_SetDiskBusy Sets the busy state for disk access ensuring mutual exclusion of file operations.
  • +
+

Memory:

+
    +
  • Memory_GetStats Returns information on the memory usage of FMOD.
  • +
  • Memory_Initialize Specifies a method for FMOD to allocate and free memory, either through user supplied callbacks or through a user supplied memory buffer with a fixed size.
  • +
+
+ +
+
    +
  • FMOD_MEMORY_TYPE Bitfields for memory allocation type being passed into FMOD memory callbacks.
  • +
+

Debugging:

+
    +
  • Debug_Initialize Specify the level and delivery method of log messages when using the logging version of FMOD.
  • +
+
+ +
+
    +
  • FMOD_DEBUG_MODE Specify the destination of log output when using the logging version of FMOD.
  • +
  • FMOD_DEBUG_FLAGS Specify the requested information to be output when using the logging version of FMOD.
  • +
+

Threading:

+
    +
  • Thread_SetAttributes Specify the affinity, priority and stack size for all FMOD created threads.
  • +
+
+ +

General:

+ +
+ +

FMOD_3D_ATTRIBUTES

+

Structure describing a position, velocity and orientation.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
typedef struct FMOD_3D_ATTRIBUTES {
+  FMOD_VECTOR position;
+  FMOD_VECTOR velocity;
+  FMOD_VECTOR forward;
+  FMOD_VECTOR up;
+} FMOD_3D_ATTRIBUTES;
+
+ +
struct ATTRIBUTES_3D
+{
+  VECTOR position;
+  VECTOR velocity;
+  VECTOR forward;
+  VECTOR up;
+}
+
+ +
_3D_ATTRIBUTES
+{
+  position,
+  velocity,
+  forward,
+  up,
+};
+
+ +
+
position
+
+

Position in world space used for panning and attenuation. (FMOD_VECTOR)

+ +
+
velocity
+
+

Velocity in world space used for doppler. (FMOD_VECTOR)

+ +
+
forward
+
Forwards orientation, must be of unit length (1.0) and perpendicular to up. (FMOD_VECTOR)
+
up
+
Upwards orientation, must be of unit length (1.0) and perpendicular to forward. (FMOD_VECTOR)
+
+

Vectors must be provided in the correct handedness.

+

See Also: FMOD_DSP_PARAMETER_3DATTRIBUTES

+

FMOD_CHANNELMASK

+

Flags that describe the speakers present in a given signal.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
#define FMOD_CHANNELMASK_FRONT_LEFT       0x00000001
+#define FMOD_CHANNELMASK_FRONT_RIGHT      0x00000002
+#define FMOD_CHANNELMASK_FRONT_CENTER     0x00000004
+#define FMOD_CHANNELMASK_LOW_FREQUENCY    0x00000008
+#define FMOD_CHANNELMASK_SURROUND_LEFT    0x00000010
+#define FMOD_CHANNELMASK_SURROUND_RIGHT   0x00000020
+#define FMOD_CHANNELMASK_BACK_LEFT        0x00000040
+#define FMOD_CHANNELMASK_BACK_RIGHT       0x00000080
+#define FMOD_CHANNELMASK_BACK_CENTER      0x00000100
+#define FMOD_CHANNELMASK_MONO             (FMOD_CHANNELMASK_FRONT_LEFT)
+#define FMOD_CHANNELMASK_STEREO           (FMOD_CHANNELMASK_FRONT_LEFT | FMOD_CHANNELMASK_FRONT_RIGHT)
+#define FMOD_CHANNELMASK_LRC              (FMOD_CHANNELMASK_FRONT_LEFT | FMOD_CHANNELMASK_FRONT_RIGHT | FMOD_CHANNELMASK_FRONT_CENTER)
+#define FMOD_CHANNELMASK_QUAD             (FMOD_CHANNELMASK_FRONT_LEFT | FMOD_CHANNELMASK_FRONT_RIGHT | FMOD_CHANNELMASK_SURROUND_LEFT | FMOD_CHANNELMASK_SURROUND_RIGHT)
+#define FMOD_CHANNELMASK_SURROUND         (FMOD_CHANNELMASK_FRONT_LEFT | FMOD_CHANNELMASK_FRONT_RIGHT | FMOD_CHANNELMASK_FRONT_CENTER | FMOD_CHANNELMASK_SURROUND_LEFT | FMOD_CHANNELMASK_SURROUND_RIGHT)
+#define FMOD_CHANNELMASK_5POINT1          (FMOD_CHANNELMASK_FRONT_LEFT | FMOD_CHANNELMASK_FRONT_RIGHT | FMOD_CHANNELMASK_FRONT_CENTER | FMOD_CHANNELMASK_LOW_FREQUENCY | FMOD_CHANNELMASK_SURROUND_LEFT | FMOD_CHANNELMASK_SURROUND_RIGHT)
+#define FMOD_CHANNELMASK_5POINT1_REARS    (FMOD_CHANNELMASK_FRONT_LEFT | FMOD_CHANNELMASK_FRONT_RIGHT | FMOD_CHANNELMASK_FRONT_CENTER | FMOD_CHANNELMASK_LOW_FREQUENCY | FMOD_CHANNELMASK_BACK_LEFT | FMOD_CHANNELMASK_BACK_RIGHT)
+#define FMOD_CHANNELMASK_7POINT0          (FMOD_CHANNELMASK_FRONT_LEFT | FMOD_CHANNELMASK_FRONT_RIGHT | FMOD_CHANNELMASK_FRONT_CENTER | FMOD_CHANNELMASK_SURROUND_LEFT | FMOD_CHANNELMASK_SURROUND_RIGHT | FMOD_CHANNELMASK_BACK_LEFT | FMOD_CHANNELMASK_BACK_RIGHT)
+#define FMOD_CHANNELMASK_7POINT1          (FMOD_CHANNELMASK_FRONT_LEFT | FMOD_CHANNELMASK_FRONT_RIGHT | FMOD_CHANNELMASK_FRONT_CENTER | FMOD_CHANNELMASK_LOW_FREQUENCY | FMOD_CHANNELMASK_SURROUND_LEFT | FMOD_CHANNELMASK_SURROUND_RIGHT | FMOD_CHANNELMASK_BACK_LEFT | FMOD_CHANNELMASK_BACK_RIGHT)
+
+ +
[Flags]
+enum CHANNELMASK : uint
+{
+  FRONT_LEFT        = 0x00000001,
+  FRONT_RIGHT       = 0x00000002,
+  FRONT_CENTER      = 0x00000004,
+  LOW_FREQUENCY     = 0x00000008,
+  SURROUND_LEFT     = 0x00000010,
+  SURROUND_RIGHT    = 0x00000020,
+  BACK_LEFT         = 0x00000040,
+  BACK_RIGHT        = 0x00000080,
+  BACK_CENTER       = 0x00000100,
+  MONO              = (FRONT_LEFT),
+  STEREO            = (FRONT_LEFT | FRONT_RIGHT),
+  LRC               = (FRONT_LEFT | FRONT_RIGHT | FRONT_CENTER),
+  QUAD              = (FRONT_LEFT | FRONT_RIGHT | SURROUND_LEFT | SURROUND_RIGHT),
+  SURROUND          = (FRONT_LEFT | FRONT_RIGHT | FRONT_CENTER | SURROUND_LEFT | SURROUND_RIGHT),
+  _5POINT1          = (FRONT_LEFT | FRONT_RIGHT | FRONT_CENTER | LOW_FREQUENCY | SURROUND_LEFT | SURROUND_RIGHT),
+  _5POINT1_REARS    = (FRONT_LEFT | FRONT_RIGHT | FRONT_CENTER | LOW_FREQUENCY | BACK_LEFT | BACK_RIGHT),
+  _7POINT0          = (FRONT_LEFT | FRONT_RIGHT | FRONT_CENTER | SURROUND_LEFT | SURROUND_RIGHT | BACK_LEFT | BACK_RIGHT),
+  _7POINT1          = (FRONT_LEFT | FRONT_RIGHT | FRONT_CENTER | LOW_FREQUENCY | SURROUND_LEFT | SURROUND_RIGHT | BACK_LEFT | BACK_RIGHT)
+}
+
+ +
CHANNELMASK_FRONT_LEFT      = 0x00000001
+CHANNELMASK_FRONT_RIGHT     = 0x00000002
+CHANNELMASK_FRONT_CENTER    = 0x00000004
+CHANNELMASK_LOW_FREQUENCY   = 0x00000008
+CHANNELMASK_SURROUND_LEFT   = 0x00000010
+CHANNELMASK_SURROUND_RIGHT  = 0x00000020
+CHANNELMASK_BACK_LEFT       = 0x00000040
+CHANNELMASK_BACK_RIGHT      = 0x00000080
+CHANNELMASK_BACK_CENTER     = 0x00000100
+CHANNELMASK_MONO            = (CHANNELMASK_FRONT_LEFT))
+CHANNELMASK_STEREO          = (CHANNELMASK_FRONT_LEFT | CHANNELMASK_FRONT_RIGHT))
+CHANNELMASK_LRC             = (CHANNELMASK_FRONT_LEFT | CHANNELMASK_FRONT_RIGHT | CHANNELMASK_FRONT_CENTER))
+CHANNELMASK_QUAD            = (CHANNELMASK_FRONT_LEFT | CHANNELMASK_FRONT_RIGHT | CHANNELMASK_SURROUND_LEFT | CHANNELMASK_SURROUND_RIGHT))
+CHANNELMASK_SURROUND        = (CHANNELMASK_FRONT_LEFT | CHANNELMASK_FRONT_RIGHT | CHANNELMASK_FRONT_CENTER | CHANNELMASK_SURROUND_LEFT | CHANNELMASK_SURROUND_RIGHT))
+CHANNELMASK_5POINT1         = (CHANNELMASK_FRONT_LEFT | CHANNELMASK_FRONT_RIGHT | CHANNELMASK_FRONT_CENTER | CHANNELMASK_LOW_FREQUENCY | CHANNELMASK_SURROUND_LEFT | CHANNELMASK_SURROUND_RIGHT))
+CHANNELMASK_5POINT1_REARS   = (CHANNELMASK_FRONT_LEFT | CHANNELMASK_FRONT_RIGHT | CHANNELMASK_FRONT_CENTER | CHANNELMASK_LOW_FREQUENCY | CHANNELMASK_BACK_LEFT | CHANNELMASK_BACK_RIGHT))
+CHANNELMASK_7POINT0         = (CHANNELMASK_FRONT_LEFT | CHANNELMASK_FRONT_RIGHT | CHANNELMASK_FRONT_CENTER | CHANNELMASK_SURROUND_LEFT | CHANNELMASK_SURROUND_RIGHT | CHANNELMASK_BACK_LEFT | CHANNELMASK_BACK_RIGHT))
+CHANNELMASK_7POINT1         = (CHANNELMASK_FRONT_LEFT | CHANNELMASK_FRONT_RIGHT | CHANNELMASK_FRONT_CENTER | CHANNELMASK_LOW_FREQUENCY | CHANNELMASK_SURROUND_LEFT | CHANNELMASK_SURROUND_RIGHT | CHANNELMASK_BACK_LEFT | CHANNELMASK_BACK_RIGHT))
+
+ +
+
FMOD_CHANNELMASK_FRONT_LEFT
+
Front left channel.
+
FMOD_CHANNELMASK_FRONT_RIGHT
+
Front right channel.
+
FMOD_CHANNELMASK_FRONT_CENTER
+
Front center channel.
+
FMOD_CHANNELMASK_LOW_FREQUENCY
+
Low frequency channel.
+
FMOD_CHANNELMASK_SURROUND_LEFT
+
Surround left channel.
+
FMOD_CHANNELMASK_SURROUND_RIGHT
+
Surround right channel.
+
FMOD_CHANNELMASK_BACK_LEFT
+
Back left channel.
+
FMOD_CHANNELMASK_BACK_RIGHT
+
Back right channel.
+
FMOD_CHANNELMASK_BACK_CENTER
+
Back center channel, not represented in any FMOD_SPEAKERMODE.
+
FMOD_CHANNELMASK_MONO
+
Mono channel mask.
+
FMOD_CHANNELMASK_STEREO
+
Stereo channel mask.
+
FMOD_CHANNELMASK_LRC
+
Left / right / center channel mask.
+
FMOD_CHANNELMASK_QUAD
+
Quadphonic channel mask.
+
FMOD_CHANNELMASK_SURROUND
+
5.0 surround channel mask.
+
FMOD_CHANNELMASK_5POINT1
+
5.1 surround channel mask.
+
FMOD_CHANNELMASK_5POINT1_REARS
+
5.1 surround channel mask, using rears instead of surrounds.
+
FMOD_CHANNELMASK_7POINT0
+
7.0 surround channel mask.
+
FMOD_CHANNELMASK_7POINT1
+
7.1 surround channel mask.
+
+

See Also: DSP::setChannelFormat, DSP::getChannelFormat

+

FMOD_CHANNELORDER

+

Speaker ordering for multi-channel signals.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
typedef enum FMOD_CHANNELORDER {
+  FMOD_CHANNELORDER_DEFAULT,
+  FMOD_CHANNELORDER_WAVEFORMAT,
+  FMOD_CHANNELORDER_PROTOOLS,
+  FMOD_CHANNELORDER_ALLMONO,
+  FMOD_CHANNELORDER_ALLSTEREO,
+  FMOD_CHANNELORDER_ALSA,
+  FMOD_CHANNELORDER_MAX
+} FMOD_CHANNELORDER;
+
+ +
enum CHANNELORDER : int
+{
+  DEFAULT,
+  WAVEFORMAT,
+  PROTOOLS,
+  ALLMONO,
+  ALLSTEREO,
+  ALSA,
+  MAX,
+}
+
+ +
CHANNELORDER_DEFAULT
+CHANNELORDER_WAVEFORMAT
+CHANNELORDER_PROTOOLS
+CHANNELORDER_ALLMONO
+CHANNELORDER_ALLSTEREO
+CHANNELORDER_ALSA
+CHANNELORDER_MAX
+
+ +
+
FMOD_CHANNELORDER_DEFAULT
+
Left, Right, Center, LFE, Surround Left, Surround Right, Back Left, Back Right (see FMOD_SPEAKER enumeration)
+
FMOD_CHANNELORDER_WAVEFORMAT
+
Left, Right, Center, LFE, Back Left, Back Right, Surround Left, Surround Right (as per Microsoft .wav WAVEFORMAT structure master order)
+
FMOD_CHANNELORDER_PROTOOLS
+
Left, Center, Right, Surround Left, Surround Right, LFE
+
FMOD_CHANNELORDER_ALLMONO
+
Mono, Mono, Mono, Mono, Mono, Mono, ... (each channel up to FMOD_MAX_CHANNEL_WIDTH treated as mono)
+
FMOD_CHANNELORDER_ALLSTEREO
+
Left, Right, Left, Right, Left, Right, ... (each pair of channels up to FMOD_MAX_CHANNEL_WIDTH treated as stereo)
+
FMOD_CHANNELORDER_ALSA
+
Left, Right, Surround Left, Surround Right, Center, LFE (as per Linux ALSA channel order)
+
FMOD_CHANNELORDER_MAX
+
Maximum number of channel orderings supported.
+
+

See Also: FMOD_CREATESOUNDEXINFO

+

FMOD_CPU_USAGE

+

Performance information for Core API functionality.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
typedef struct FMOD_CPU_USAGE {
+    float           dsp;
+    float           stream;
+    float           geometry;
+    float           update;
+    float           convolution1;
+    float           convolution2;
+} FMOD_CPU_USAGE;
+
+ +
struct CPU_USAGE
+{
+    float           dsp;
+    float           stream;
+    float           geometry;
+    float           update;
+    float           convolution1;
+    float           convolution2;
+}
+
+ +
CPU_USAGE
+{
+    dsp,
+    stream,
+    geometry,
+    update,
+    convolution1,
+    convolution2
+};
+
+ +
+
dsp
+
+

DSP mixing engine CPU usage. Percentage of FMOD_THREAD_TYPE_MIXER, or main thread if FMOD_INIT_MIX_FROM_UPDATE flag is used with System::init.

+
    +
  • Units: Percent
  • +
  • Range: [0, 100]
  • +
+
+
stream
+
+

Streaming engine CPU usage. Percentage of FMOD_THREAD_TYPE_STREAM, or main thread if FMOD_INIT_STREAM_FROM_UPDATE flag is used with System::init.

+
    +
  • Units: Percent
  • +
  • Range: [0, 100]
  • +
+
+
geometry
+
+

Geometry engine CPU usage. Percentage of FMOD_THREAD_TYPE_GEOMETRY.

+
    +
  • Units: Percent
  • +
  • Range: [0, 100]
  • +
+
+
update
+
+

System::update CPU usage. Percentage of main thread.

+
    +
  • Units: Percent
  • +
  • Range: [0, 100]
  • +
+
+
convolution1
+
+

Convolution reverb processing thread #1 CPU usage. Percentage of FMOD_THREAD_TYPE_CONVOLUTION1.

+
    +
  • Units: Percent
  • +
  • Range: [0, 100]
  • +
+
+
convolution2
+
+

Convolution reverb processing thread #2 CPU usage. Percentage of FMOD_THREAD_TYPE_CONVOLUTION2.

+
    +
  • Units: Percent
  • +
  • Range: [0, 100]
  • +
+
+
+

This structure is filled in with System::getCPUUsage.

+

For readability, the percentage values are smoothed to provide a more stable output.

+

'Percentage of main thread' in the descriptions above refers to the thread that the function is called from by the user.

+

The use of FMOD_THREAD_TYPE_CONVOLUTION1 or FMOD_THREAD_TYPE_CONVOLUTION2 can be controlled with FMOD_ADVANCEDSETTINGS::maxConvolutionThreads.

+

See Also: Studio::System::getCPUUsage, FMOD_STUDIO_CPU_USAGE

+

FMOD_DEBUG_CALLBACK

+

Callback for debug messages when using the logging version of FMOD.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
FMOD_RESULT F_CALL FMOD_DEBUG_CALLBACK(
+  FMOD_DEBUG_FLAGS flags,
+  const char *file,
+  int line,
+  const char *func,
+  const char *message
+);
+
+ +
delegate RESULT DEBUG_CALLBACK(
+  DEBUG_FLAGS flags,
+  IntPtr file,
+  int line,
+  IntPtr func,
+  IntPtr message
+);
+
+ +
+

Not supported for JavaScript.

+
+
+
flags
+
Flags which detail the level and type of this log. (FMOD_DEBUG_FLAGS)
+
file
+
Source code file name where the message originated. (UTF-8 string)
+
line
+
Source code line number where the message originated.
+
func
+
Class and function name where the message originated. (UTF-8 string)
+
message
+
Actual debug message associated with the callback. (UTF-8 string)
+
+
+

The 'file', 'func', and 'message' arguments can be used via StringWrapper by using FMOD.StringWrapper string = new FMOD.StringWrapper(ptrToString);

+
+

This callback will fire directly from the log line, as such it can be from any thread.

+

See Also: Debug_Initialize

+

FMOD_DEBUG_FLAGS

+

Specify the requested information to be output when using the logging version of FMOD.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
#define FMOD_DEBUG_LEVEL_NONE            0x00000000
+#define FMOD_DEBUG_LEVEL_ERROR           0x00000001
+#define FMOD_DEBUG_LEVEL_WARNING         0x00000002
+#define FMOD_DEBUG_LEVEL_LOG             0x00000004
+#define FMOD_DEBUG_TYPE_MEMORY           0x00000100
+#define FMOD_DEBUG_TYPE_FILE             0x00000200
+#define FMOD_DEBUG_TYPE_CODEC            0x00000400
+#define FMOD_DEBUG_TYPE_TRACE            0x00000800
+#define FMOD_DEBUG_TYPE_VIRTUAL          0x00001000
+#define FMOD_DEBUG_DISPLAY_TIMESTAMPS    0x00010000
+#define FMOD_DEBUG_DISPLAY_LINENUMBERS   0x00020000
+#define FMOD_DEBUG_DISPLAY_THREAD        0x00040000
+
+ +
[Flags]
+enum DEBUG_FLAGS : uint
+{
+  NONE                  = 0x00000000,
+  ERROR                 = 0x00000001,
+  WARNING               = 0x00000002,
+  LOG                   = 0x00000004,
+  TYPE_MEMORY           = 0x00000100,
+  TYPE_FILE             = 0x00000200,
+  TYPE_CODEC            = 0x00000400,
+  TYPE_TRACE            = 0x00000800,
+  TYPE_VIRTUAL          = 0x00001000,
+  DISPLAY_TIMESTAMPS    = 0x00010000,
+  DISPLAY_LINENUMBERS   = 0x00020000,
+  DISPLAY_THREAD        = 0x00040000,
+}
+
+ +
DEBUG_LEVEL_NONE            = 0x00000000
+DEBUG_LEVEL_ERROR           = 0x00000001
+DEBUG_LEVEL_WARNING         = 0x00000002
+DEBUG_LEVEL_LOG             = 0x00000004
+DEBUG_TYPE_MEMORY           = 0x00000100
+DEBUG_TYPE_FILE             = 0x00000200
+DEBUG_TYPE_CODEC            = 0x00000400
+DEBUG_TYPE_TRACE            = 0x00000800
+DEBUG_TYPE_VIRTUAL          = 0x00001000
+DEBUG_DISPLAY_TIMESTAMPS    = 0x00010000
+DEBUG_DISPLAY_LINENUMBERS   = 0x00020000
+DEBUG_DISPLAY_THREAD        = 0x00040000
+
+ +
+
FMOD_DEBUG_LEVEL_NONE
+
Disable all messages.
+
FMOD_DEBUG_LEVEL_ERROR
+
Enable only error messages.
+
FMOD_DEBUG_LEVEL_WARNING
+
Enable warning and error messages.
+
FMOD_DEBUG_LEVEL_LOG
+
Enable informational, warning and error messages (default).
+
FMOD_DEBUG_TYPE_MEMORY
+
Verbose logging for memory operations, only use this if you are debugging a memory related issue.
+
FMOD_DEBUG_TYPE_FILE
+
Verbose logging for file access, only use this if you are debugging a file related issue.
+
FMOD_DEBUG_TYPE_CODEC
+
Verbose logging for codec initialization, only use this if you are debugging a codec related issue.
+
FMOD_DEBUG_TYPE_TRACE
+
Verbose logging for internal errors, use this for tracking the origin of error codes.
+
FMOD_DEBUG_TYPE_VIRTUAL
+
Verbose logging for whenever a Channel changes its virtual state.
+
FMOD_DEBUG_DISPLAY_TIMESTAMPS
+
Display the time stamp of the log message in milliseconds.
+
FMOD_DEBUG_DISPLAY_LINENUMBERS
+
Display the source code file and line number for where the message originated.
+
FMOD_DEBUG_DISPLAY_THREAD
+
Display the thread ID of the calling function that generated the message.
+
+

See Also: Debug_Initialize

+

Debug_Initialize

+

Specify the level and delivery method of log messages when using the logging version of FMOD.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
FMOD_RESULT Debug_Initialize(
+  FMOD_DEBUG_FLAGS flags,
+  FMOD_DEBUG_MODE mode = FMOD_DEBUG_MODE_TTY,
+  FMOD_DEBUG_CALLBACK callback = 0,
+  const char *filename = nullptr
+);
+
+ +
FMOD_RESULT FMOD_Debug_Initialize(
+  FMOD_DEBUG_FLAGS flags,
+  FMOD_DEBUG_MODE mode,
+  FMOD_DEBUG_CALLBACK callback,
+  const char *filename
+);
+
+ +
static RESULT Debug.Initialize(
+  DEBUG_FLAGS flags,
+  DEBUG_MODE mode = DEBUG_MODE.TTY,
+  DEBUG_CALLBACK callback = null,
+  string filename = null
+);
+
+ +
Debug_Initialize(
+  flags
+);
+
+ +
+
flags
+
Debug level, type and display control flags. More than one mode can be set at once by combining them with the OR operator. (FMOD_DEBUG_FLAGS)
+
mode Opt
+
Destination for log messages. (FMOD_DEBUG_MODE)
+
callback Opt
+
Callback to use when mode is set to callback, only required when using that mode. (FMOD_DEBUG_CALLBACK)
+
filename Opt
+
Filename to use when mode is set to file, only required when using that mode. (UTF-8 string)
+
+

This function will return FMOD_ERR_UNSUPPORTED when using the non-logging (release) versions of FMOD.

+

The logging version of FMOD can be recognized by the 'L' suffix in the library name, fmodL.dll or libfmodL.so for instance.

+

Note that:

+ +

See Also: Callback Behavior

+

FMOD_DEBUG_MODE

+

Specify the destination of log output when using the logging version of FMOD.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
typedef enum FMOD_DEBUG_MODE {
+  FMOD_DEBUG_MODE_TTY,
+  FMOD_DEBUG_MODE_FILE,
+  FMOD_DEBUG_MODE_CALLBACK
+} FMOD_DEBUG_MODE;
+
+ +
enum DEBUG_MODE : int
+{
+  TTY,
+  FILE,
+  CALLBACK,
+}
+
+ +
+

Not supported for JavaScript.

+
+
+
FMOD_DEBUG_MODE_TTY
+
Default log location per platform, i.e. Visual Studio output window, stderr, LogCat, etc.
+
FMOD_DEBUG_MODE_FILE
+
Write log to specified file path.
+
FMOD_DEBUG_MODE_CALLBACK
+
Call specified callback with log information.
+
+

TTY destination can vary depending on platform, common examples include the Visual Studio / Xcode output window, stderr and LogCat.

+

See Also: Debug_Initialize

+

File_GetDiskBusy

+

Information function to retrieve the state of FMOD disk access.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
FMOD_RESULT File_GetDiskBusy(
+  int *busy
+);
+
+ +
FMOD_RESULT FMOD_File_GetDiskBusy(
+  int *busy
+);
+
+ +
+

Not supported for C#.

+
+
+

Not supported for JavaScript.

+
+
+
busy Out
+
Busy state of the disk at the current time.
+
+

Do not use this function to synchronize your own reads with, as due to timing, you might call this function and it says false = it is not busy, but the split second after calling this function, internally FMOD might set it to busy. Use File_SetDiskBusy for proper mutual exclusion as it uses semaphores.

+

See Also: File_SetDiskBusy

+

File_SetDiskBusy

+

Sets the busy state for disk access ensuring mutual exclusion of file operations.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
FMOD_RESULT File_SetDiskBusy(
+  int busy
+);
+
+ +
FMOD_RESULT FMOD_File_SetDiskBusy(
+  int busy
+);
+
+ +
+

Not supported for C#.

+
+
+

Not supported for JavaScript.

+
+
+
busy
+
Busy state where 1 represent the begining of disk access and 0 represents the end of disk access.
+
+

If file IO is currently being performed by FMOD this function will block until it has completed.

+

This function should be called in pairs once to set the state, then again to clear it once complete.

+

See Also: File_GetDiskBusy

+

FMOD_GUID

+

Structure describing a globally unique identifier.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
typedef struct FMOD_GUID {
+  unsigned int     Data1;
+  unsigned short   Data2;
+  unsigned short   Data3;
+  unsigned char    Data4[8];
+} FMOD_GUID;
+
+ +
struct System.Guid
+
+ +
FMOD_GUID
+{
+  Data1,
+  Data2,
+  Data3,
+  Data4,
+};
+
+ +
+
Data1
+
Specifies the first 8 hexadecimal digits of the GUID.
+
Data2
+
Specifies the first group of 4 hexadecimal digits.
+
Data3
+
Specifies the second group of 4 hexadecimal digits.
+
Data4
+
Array of 8 bytes. The first 2 bytes contain the third group of 4 hexadecimal digits. The remaining 6 bytes contain the final 12 hexadecimal digits.
+
+

See Also: System::getDriverInfo

+

FMOD_MAX_CHANNEL_WIDTH

+

Maximum number of channels per sample of audio supported by audio files, buffers, connections and DSPs.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
#define FMOD_MAX_CHANNEL_WIDTH 32
+
+ +
class CONSTANTS
+{
+  const int MAX_CHANNEL_WIDTH = 32;
+}
+
+ +
MAX_CHANNEL_WIDTH = 32
+
+ +
+
FMOD_MAX_CHANNEL_WIDTH
+
Maximum number of channels.
+
+

See Also: System::setSoftwareFormat, ChannelControl::setMixMatrix, DSP::setChannelFormat

+

FMOD_MAX_LISTENERS

+

Maximum number of listeners supported.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
#define FMOD_MAX_LISTENERS 8
+
+ +
class CONSTANTS
+{
+  const int MAX_LISTENERS = 8;
+}
+
+ +
MAX_LISTENERS = 8
+
+ +
+
FMOD_MAX_LISTENERS
+
Maximum listeners.
+
+

See Also: System::set3DNumListeners, System::set3DListenerAttributes

+

FMOD_MAX_SYSTEMS

+

Maximum number of System objects allowed.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
#define FMOD_MAX_SYSTEMS 8
+
+ +
class CONSTANTS
+{
+  const int MAX_SYSTEMS = 8;
+}
+
+ +
+

Not supported for JavaScript.

+
+
+
FMOD_MAX_SYSTEMS
+
Maximum System objects.
+
+

See Also: System_Create

+

FMOD_MEMORY_ALLOC_CALLBACK

+

Callback to allocate a block of memory.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
void * F_CALL FMOD_MEMORY_ALLOC_CALLBACK(
+  unsigned int size,
+  FMOD_MEMORY_TYPE type,
+  const char *sourcestr
+);
+
+ +
delegate IntPtr MEMORY_ALLOC_CALLBACK(
+  uint size,
+  MEMORY_TYPE type,
+  IntPtr sourcestr
+);
+
+ +
+

Not supported for JavaScript.

+
+
+
size
+
+

Size of the memory block to be allocated and returned.

+
    +
  • Units: Bytes
  • +
+
+
type
+
Type of memory allocation. (FMOD_MEMORY_TYPE)
+
sourcestr Opt
+
String with the FMOD source code filename and line number in it. Only valid in logging versions of FMOD. (UTF-8 string)
+
+

Returning an aligned pointer, of 16 byte alignment is recommended for performance reasons.

+
+

The 'sourcestr' argument can be used via StringWrapper by using FMOD.StringWrapper sourceStr = new FMOD.StringWrapper(sourcestr);

+
+

See Also: Memory_Initialize, Memory_GetStats, FMOD_MEMORY_REALLOC_CALLBACK, FMOD_MEMORY_FREE_CALLBACK

+

FMOD_MEMORY_FREE_CALLBACK

+

Callback to free a block of memory.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
void F_CALL FMOD_MEMORY_FREE_CALLBACK(
+  void *ptr,
+  FMOD_MEMORY_TYPE type,
+  const char *sourcestr
+);
+
+ +
delegate void MEMORY_FREE_CALLBACK(
+  IntPtr ptr,
+  MEMORY_TYPE type,
+  IntPtr sourcestr
+);
+
+ +
+

Not supported for JavaScript.

+
+
+
ptr
+
Pre-existing block of memory to be freed.
+
type
+
Type of memory to be freed. (FMOD_MEMORY_TYPE)
+
sourcestr
+
String with the FMOD source code filename and line number in it. Only valid in logging versions of FMOD. (UTF-8 string)
+
+
+

The 'sourcestr' argument can be used via StringWrapper by using FMOD.StringWrapper sourceStr = new FMOD.StringWrapper(sourcestr);

+
+

See Also: Memory_Initialize, FMOD_MEMORY_ALLOC_CALLBACK, FMOD_MEMORY_REALLOC_CALLBACK

+

Memory_GetStats

+

Returns information on the memory usage of FMOD.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
FMOD_RESULT Memory_GetStats(
+  int *currentalloced,
+  int *maxalloced,
+  bool blocking = true
+);
+
+ +
FMOD_RESULT FMOD_Memory_GetStats(
+  int *currentalloced,
+  int *maxalloced,
+  FMOD_BOOL blocking
+);
+
+ +
static RESULT Memory.GetStats(
+  out int currentalloced,
+  out int maxalloced,
+  bool blocking = true
+);
+
+ +
Memory_GetStats(
+  currentalloced,
+  maxalloced,
+  blocking
+);
+
+ +
+
currentalloced OutOpt
+
Currently allocated memory at time of call.
+
maxalloced OutOpt
+
Maximum allocated memory since System::init or Memory_Initialize.
+
blocking
+
+

Flag to indicate whether to favour speed or accuracy. Specifying true for this parameter will flush the DSP graph to make sure all queued allocations happen immediately, which can be costly.

+
    +
  • Units: Boolean
  • +
+
+
+

This information is byte accurate and counts all allocs and frees internally. This is useful for determining a fixed memory size to make FMOD work within for fixed memory machines such as consoles.

+

Note that if using Memory_Initialize, the memory usage will be slightly higher than without it, as FMOD has to have a small amount of memory overhead to manage the available memory.

+

Memory_Initialize

+

Specifies a method for FMOD to allocate and free memory, either through user supplied callbacks or through a user supplied memory buffer with a fixed size.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
FMOD_RESULT Memory_Initialize(
+  void *poolmem,
+  int poollen,
+  FMOD_MEMORY_ALLOC_CALLBACK useralloc,
+  FMOD_MEMORY_REALLOC_CALLBACK userrealloc,
+  FMOD_MEMORY_FREE_CALLBACK userfree,
+  FMOD_MEMORY_TYPE memtypeflags = FMOD_MEMORY_ALL
+);
+
+ +
FMOD_RESULT FMOD_Memory_Initialize(
+  void *poolmem,
+  int poollen,
+  FMOD_MEMORY_ALLOC_CALLBACK useralloc,
+  FMOD_MEMORY_REALLOC_CALLBACK userrealloc,
+  FMOD_MEMORY_FREE_CALLBACK userfree,
+  FMOD_MEMORY_TYPE memtypeflags
+);
+
+ +
static RESULT Memory.Initialize(
+  IntPtr poolmem,
+  int poollen,
+  MEMORY_ALLOC_CALLBACK useralloc,
+  MEMORY_REALLOC_CALLBACK userrealloc,
+  MEMORY_FREE_CALLBACK userfree,
+  MEMORY_TYPE memtypeflags = MEMORY_TYPE.ALL
+);
+
+ +
+

Not supported for JavaScript.

+
+
+
poolmem Opt
+
Block of memory of size poollen bytes for FMOD to manage, mutually exclusive with useralloc / userrealloc / userfree.
+
poollen Opt
+
+

Size of poolmem, must be a multiple of 512.

+
    +
  • Units: Bytes
  • +
+
+
useralloc Opt
+
Memory allocation callback compatible with ANSI malloc, mutually exclusive with poolmem. (FMOD_MEMORY_ALLOC_CALLBACK)
+
userrealloc Opt
+
Memory reallocation callback compatible with ANSI realloc, mutually exclusive with poolmem. (FMOD_MEMORY_REALLOC_CALLBACK)
+
userfree Opt
+
Memory free callback compatible with ANSI free, mutually exclusive with poolmem. (FMOD_MEMORY_FREE_CALLBACK)
+
memtypeflags Opt
+
Types of memory callbacks you wish to handle. OR these together to handle multiple types. (FMOD_MEMORY_TYPE)
+
+

This function must be called before any FMOD System object is created.

+

Valid usage of this function requires either poolmem and poollen or useralloc, userrealloc and userfree being set.
+If 'useralloc' and 'userfree' are provided without 'userrealloc' the reallocation is implemented via an allocation of the new size, copy from old address to new, then a free of the old address.

+

To find out the required fixed size call Memory_Initialize with an overly large pool size (or no pool) and find out the maximum RAM usage at any one time with Memory_GetStats.

+

Callback implementations must be thread safe.

+

If you specify a fixed size pool that is too small, FMOD will return FMOD_ERR_MEMORY when the limit of the fixed size pool is exceeded. At this point, it's possible that FMOD may become unstable. To maintain stability, do not allow FMOD to run out of memory.

+

See Also: Callback Behavior

+

FMOD_MEMORY_REALLOC_CALLBACK

+

Callback to re-allocate a block of memory to a different size.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
void * F_CALL FMOD_MEMORY_REALLOC_CALLBACK(
+  void *ptr,
+  unsigned int size,
+  FMOD_MEMORY_TYPE type,
+  const char *sourcestr
+);
+
+ +
delegate IntPtr MEMORY_REALLOC_CALLBACK(
+  IntPtr ptr,
+  uint size,
+  MEMORY_TYPE type,
+  IntPtr sourcestr
+);
+
+ +
+

Not supported for JavaScript.

+
+
+
ptr
+
Block of memory to be resized. If this is null, then a new block of memory is allocated and no memory is freed.
+
size
+
+

Size of the memory to be reallocated.

+
    +
  • Units: Bytes
  • +
+
+
type
+
Memory allocation type. (FMOD_MEMORY_TYPE)
+
sourcestr
+
String with the FMOD source code filename and line number in it. Only valid in logging versions of FMOD. (UTF-8 string)
+
+

When allocating new memory, the contents of the old memory block must be preserved.

+

Returning an aligned pointer, of 16 byte alignment is recommended for performance reasons.

+
+

The 'sourcestr' argument can be used via StringWrapper by using FMOD.StringWrapper sourceStr = new FMOD.StringWrapper(sourcestr);

+
+

See Also: Memory_Initialize, Memory_GetStats, FMOD_MEMORY_ALLOC_CALLBACK, FMOD_MEMORY_FREE_CALLBACK

+

FMOD_MEMORY_TYPE

+

Bitfields for memory allocation type being passed into FMOD memory callbacks.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
#define FMOD_MEMORY_NORMAL             0x00000000
+#define FMOD_MEMORY_STREAM_FILE        0x00000001
+#define FMOD_MEMORY_STREAM_DECODE      0x00000002
+#define FMOD_MEMORY_SAMPLEDATA         0x00000004
+#define FMOD_MEMORY_DSP_BUFFER         0x00000008
+#define FMOD_MEMORY_PLUGIN             0x00000010
+#define FMOD_MEMORY_PERSISTENT         0x00200000
+#define FMOD_MEMORY_ALL                0xFFFFFFFF
+
+ +
[Flags]
+enum MEMORY_TYPE : uint
+{
+  NORMAL            = 0x00000000,
+  STREAM_FILE       = 0x00000001,
+  STREAM_DECODE     = 0x00000002,
+  SAMPLEDATA        = 0x00000004,
+  DSP_BUFFER        = 0x00000008,
+  PLUGIN            = 0x00000010,
+  PERSISTENT        = 0x00200000,
+  ALL               = 0xFFFFFFFF
+}
+
+ +
+

Not supported for JavaScript.

+
+
+
FMOD_MEMORY_NORMAL
+
Standard memory.
+
FMOD_MEMORY_STREAM_FILE
+
Stream file buffer, size controllable with System::setStreamBufferSize.
+
FMOD_MEMORY_STREAM_DECODE
+
Stream decode buffer, size controllable with FMOD_CREATESOUNDEXINFO::decodebuffersize.
+
FMOD_MEMORY_SAMPLEDATA
+
Sample data buffer. Raw audio data, usually PCM/MPEG/ADPCM/XMA data.
+
FMOD_MEMORY_DSP_BUFFER
+
Deprecated.
+
FMOD_MEMORY_PLUGIN
+
Memory allocated by a third party plugin.
+
FMOD_MEMORY_PERSISTENT
+
Persistent memory. Memory will be freed when System::release is called.
+
FMOD_MEMORY_ALL
+
Mask specifying all memory types.
+
+

See Also: FMOD_MEMORY_ALLOC_CALLBACK, FMOD_MEMORY_REALLOC_CALLBACK, FMOD_MEMORY_FREE_CALLBACK, Memory_Initialize

+

FMOD_MODE

+

Sound description bitfields, bitwise OR them together for loading and describing Sounds.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
#define FMOD_DEFAULT                    0x00000000
+#define FMOD_LOOP_OFF                   0x00000001
+#define FMOD_LOOP_NORMAL                0x00000002
+#define FMOD_LOOP_BIDI                  0x00000004
+#define FMOD_2D                         0x00000008
+#define FMOD_3D                         0x00000010
+#define FMOD_CREATESTREAM               0x00000080
+#define FMOD_CREATESAMPLE               0x00000100
+#define FMOD_CREATECOMPRESSEDSAMPLE     0x00000200
+#define FMOD_OPENUSER                   0x00000400
+#define FMOD_OPENMEMORY                 0x00000800
+#define FMOD_OPENMEMORY_POINT           0x10000000
+#define FMOD_OPENRAW                    0x00001000
+#define FMOD_OPENONLY                   0x00002000
+#define FMOD_ACCURATETIME               0x00004000
+#define FMOD_MPEGSEARCH                 0x00008000
+#define FMOD_NONBLOCKING                0x00010000
+#define FMOD_UNIQUE                     0x00020000
+#define FMOD_3D_HEADRELATIVE            0x00040000
+#define FMOD_3D_WORLDRELATIVE           0x00080000
+#define FMOD_3D_INVERSEROLLOFF          0x00100000
+#define FMOD_3D_LINEARROLLOFF           0x00200000
+#define FMOD_3D_LINEARSQUAREROLLOFF     0x00400000
+#define FMOD_3D_INVERSETAPEREDROLLOFF   0x00800000
+#define FMOD_3D_CUSTOMROLLOFF           0x04000000
+#define FMOD_3D_IGNOREGEOMETRY          0x40000000
+#define FMOD_IGNORETAGS                 0x02000000
+#define FMOD_LOWMEM                     0x08000000
+#define FMOD_VIRTUAL_PLAYFROMSTART      0x80000000
+
+ +
[Flags]
+enum MODE : uint
+{
+  DEFAULT                   = 0x00000000,
+  LOOP_OFF                  = 0x00000001,
+  LOOP_NORMAL               = 0x00000002,
+  LOOP_BIDI                 = 0x00000004,
+  _2D                       = 0x00000008,
+  _3D                       = 0x00000010,
+  CREATESTREAM              = 0x00000080,
+  CREATESAMPLE              = 0x00000100,
+  CREATECOMPRESSEDSAMPLE    = 0x00000200,
+  OPENUSER                  = 0x00000400,
+  OPENMEMORY                = 0x00000800,
+  OPENMEMORY_POINT          = 0x10000000,
+  OPENRAW                   = 0x00001000,
+  OPENONLY                  = 0x00002000,
+  ACCURATETIME              = 0x00004000,
+  MPEGSEARCH                = 0x00008000,
+  NONBLOCKING               = 0x00010000,
+  UNIQUE                    = 0x00020000,
+  _3D_HEADRELATIVE          = 0x00040000,
+  _3D_WORLDRELATIVE         = 0x00080000,
+  _3D_INVERSEROLLOFF        = 0x00100000,
+  _3D_LINEARROLLOFF         = 0x00200000,
+  _3D_LINEARSQUAREROLLOFF   = 0x00400000,
+  _3D_INVERSETAPEREDROLLOFF = 0x00800000,
+  _3D_CUSTOMROLLOFF         = 0x04000000,
+  _3D_IGNOREGEOMETRY        = 0x40000000,
+  IGNORETAGS                = 0x02000000,
+  LOWMEM                    = 0x08000000,
+  VIRTUAL_PLAYFROMSTART     = 0x80000000
+}
+
+ +
DEFAULT                     = 0x00000000
+LOOP_OFF                    = 0x00000001
+LOOP_NORMAL                 = 0x00000002
+LOOP_BIDI                   = 0x00000004
+_2D                         = 0x00000008
+_3D                         = 0x00000010
+CREATESTREAM                = 0x00000080
+CREATESAMPLE                = 0x00000100
+CREATECOMPRESSEDSAMPLE      = 0x00000200
+OPENUSER                    = 0x00000400
+OPENMEMORY                  = 0x00000800
+OPENMEMORY_POINT            = 0x10000000
+OPENRAW                     = 0x00001000
+OPENONLY                    = 0x00002000
+ACCURATETIME                = 0x00004000
+MPEGSEARCH                  = 0x00008000
+NONBLOCKING                 = 0x00010000
+UNIQUE                      = 0x00020000
+_3D_HEADRELATIVE            = 0x00040000
+_3D_WORLDRELATIVE           = 0x00080000
+_3D_INVERSEROLLOFF          = 0x00100000
+_3D_LINEARROLLOFF           = 0x00200000
+_3D_LINEARSQUAREROLLOFF     = 0x00400000
+_3D_INVERSETAPEREDROLLOFF   = 0x00800000
+_3D_CUSTOMROLLOFF           = 0x04000000
+_3D_IGNOREGEOMETRY          = 0x40000000
+IGNORETAGS                  = 0x02000000
+LOWMEM                      = 0x08000000
+VIRTUAL_PLAYFROMSTART       = 0x80000000
+
+ +
+
FMOD_DEFAULT
+
Default for all modes listed below. FMOD_LOOP_OFF, FMOD_2D, FMOD_3D_WORLDRELATIVE, FMOD_3D_INVERSEROLLOFF
+
FMOD_LOOP_OFF
+
For non looping Sounds. (DEFAULT). Overrides FMOD_LOOP_NORMAL / FMOD_LOOP_BIDI.
+
FMOD_LOOP_NORMAL
+
For forward looping Sounds.
+
FMOD_LOOP_BIDI
+
For bidirectional looping Sounds. (only works on non-streaming, real voices).
+
FMOD_2D
+
Ignores any 3d processing. (DEFAULT).
+
FMOD_3D
+
Makes the Sound, Channel or ChannelGroup positionable in 3D. Overrides FMOD_2D.
+
FMOD_CREATESTREAM
+
Decompress at runtime, streaming from the source provided (ie from disk). Overrides FMOD_CREATESAMPLE and FMOD_CREATECOMPRESSEDSAMPLE. Note a stream can only be played once at a time due to a stream only having 1 stream buffer and file handle. Open multiple streams to have them play concurrently.
+
FMOD_CREATESAMPLE
+
Decompress at loadtime, decompressing or decoding whole file into memory as the target sample format (ie PCM). Fastest for playback and most flexible.
+
FMOD_CREATECOMPRESSEDSAMPLE
+
Load MP2/MP3/FADPCM/IMAADPCM/Vorbis/AT9 or XMA into memory and leave it compressed. Vorbis/AT9/FADPCM encoding only supported in the .FSB container format. During playback the FMOD software mixer will decode it in realtime as a 'compressed sample'. Overrides FMOD_CREATESAMPLE. If the sound data is not one of the supported formats, it will behave as if it was created with FMOD_CREATESAMPLE and decode the sound into PCM.
+
FMOD_OPENUSER
+
Opens a user-created static sample or stream. When used, the first argument of System::createSound and System::createStream, name_or_data, is ignored, so recommended practice is to pass null or equivalent. The following data must be provided using FMOD_CREATESOUNDEXINFO: cbsize, length, numchannels, defaultfrequency, format, and optionally readcallback. If a user-created 'sample' is created with no read callback, the sample will be empty. If this is the case, use Sound::lock and Sound::unlock to place sound data into the Sound.
+
FMOD_OPENMEMORY
+
When used, the first argument of System::createSound and System::createStream, name_or_data, is interpreted as a pointer to memory instead of filename for creating sounds. The following data must be provided using FMOD_CREATESOUNDEXINFO: cbsize, and length. If used with FMOD_CREATESAMPLE or FMOD_CREATECOMPRESSEDSAMPLE, FMOD duplicates the memory into its own buffers. Your own buffer can be freed after open, unless you are using FMOD_NONBLOCKING then wait until the Sound is in the FMOD_OPENSTATE_READY state. If used with FMOD_CREATESTREAM, FMOD will stream out of the buffer whose pointer you passed in. In this case, your own buffer should not be freed until you have finished with and released the stream.
+
FMOD_OPENMEMORY_POINT
+
When used, the first argument of System::createSound and System::createStream, name_or_data, is interpreted as a pointer to memory instead of filename for creating sounds. The following data must be provided using FMOD_CREATESOUNDEXINFO: cbsize, and length. This differs to FMOD_OPENMEMORY in that it uses the memory as is, without duplicating the memory into its own buffers. Cannot be freed after open, only after Sound::release. Will not work if the data is compressed and FMOD_CREATECOMPRESSEDSAMPLE is not used. Cannot be used in conjunction with FMOD_CREATESOUNDEXINFO::encryptionkey.
+
FMOD_OPENRAW
+
Will ignore file format and treat as raw PCM. The following data must be provided using FMOD_CREATESOUNDEXINFO: cbsize, numchannels, defaultfrequency, and format. Must be little endian data, and integer data must also be signed.
+
FMOD_OPENONLY
+
Just open the file, don't prebuffer or read. Good for fast opens for info, or when Sound::readData is to be used.
+
FMOD_ACCURATETIME
+
For System::createSound - for accurate Sound::getLength / Channel::setPosition on VBR MP3, and MOD/S3M/XM/IT/MIDI files. Scans file first, so takes longer to open. FMOD_OPENONLY does not affect this.
+
FMOD_MPEGSEARCH
+
For corrupted / bad MP3 files. This will search all the way through the file until it hits a valid MPEG header. Normally only searches for 4k.
+
FMOD_NONBLOCKING
+
For opening Sounds and getting streamed subsounds (seeking) asynchronously. Use Sound::getOpenState to poll the state of the Sound as it opens or retrieves the subsound in the background.
+
FMOD_UNIQUE
+
Unique Sound, can only be played one at a time.
+
FMOD_3D_HEADRELATIVE
+
Make the Sound's position, velocity and orientation relative to the listener.
+
FMOD_3D_WORLDRELATIVE
+
Make the Sound's position, velocity and orientation absolute (relative to the world). (DEFAULT)
+
FMOD_3D_INVERSEROLLOFF
+
This sound follows an inverse roll-off model. Below mindistance, the volume is unattenuated; as distance increases above mindistance, the volume attenuates using mindistance/distance as the gradient until it reaches maxdistance, where it stops attenuating. For this roll-off mode, distance values greater than mindistance are scaled according to the rolloffscale. This roll-off mode accurately models the way sounds attenuate over distance in the real world. (DEFAULT)
+
Inverse Roll-off Graph
+
FMOD_3D_LINEARROLLOFF
+
This sound follows a linear roll-off model. Below mindistance, the volume is unattenuated; as distance increases from mindistance to maxdistance, the volume attenuates to silence using a linear gradient. For this roll-off mode, distance values greater than mindistance are scaled according to the rolloffscale. While this roll-off mode is not as realistic as inverse roll-off mode, it is easier to comprehend.
+
Linear Roll-off Graph
+
FMOD_3D_LINEARSQUAREROLLOFF
+
This sound follows a linear-square roll-off model. Below mindistance, the volume is unattenuated; as distance increases from mindistance to maxdistance, the volume attenuates to silence according to a linear squared gradient. For this roll-off mode, distance values greater than mindistance are scaled according to the rolloffscale. This roll-off mode provides steeper volume ramping close to the mindistance, and more gradual ramping close to the maxdistance, than linear roll-off mode.
+
Linear Square Roll-off Graph
+
FMOD_3D_INVERSETAPEREDROLLOFF
+
This sound follows a combination of the inverse and linear-square roll-off models. At short distances where inverse roll-off would provide greater attenuation, it functions as inverse roll-off mode; then at greater distances where linear-square roll-off mode would provide greater attenuation, it uses that roll-off mode instead. For this roll-off mode, distance values greater than mindistance are scaled according to the rolloffscale. Inverse tapered roll-off mode approximates realistic behavior while still guaranteeing the sound attenuates to silence at maxdistance.
+
Inverse Tapered Roll-off Graph
+
FMOD_3D_CUSTOMROLLOFF
+
This sound follow a roll-off model defined by Sound::set3DCustomRolloff / ChannelControl::set3DCustomRolloff. This roll-off mode provides greater freedom and flexibility than any other, but must be defined manually.
+
FMOD_3D_IGNOREGEOMETRY
+
Is not affected by geometry occlusion. If not specified in Sound::setMode, or ChannelControl::setMode, the flag is cleared and it is affected by geometry again.
+
FMOD_IGNORETAGS
+
Skips id3v2/asf/etc tag checks when opening a Sound, to reduce seek/read overhead when opening files.
+
FMOD_LOWMEM
+
Removes some features from samples to give a lower memory overhead, like Sound::getName.
+
FMOD_VIRTUAL_PLAYFROMSTART
+
For Channels that start virtual (due to being quiet or low importance), instead of swapping back to audible, and playing at the correct offset according to time, this flag makes the Channel play from the start.
+
+

By default a Sound will open as a static sound that is decompressed fully into memory to PCM. (ie equivalent of FMOD_CREATESAMPLE) To have a stream instead, use FMOD_CREATESTREAM, or use the wrapper function System::createStream.

+

Some opening modes (ie FMOD_OPENUSER, FMOD_OPENMEMORY, FMOD_OPENMEMORY_POINT, FMOD_OPENRAW) will need extra information. This can be provided using the FMOD_CREATESOUNDEXINFO structure.

+

Specifying FMOD_OPENMEMORY_POINT will POINT to your memory rather allocating its own sound buffers and duplicating it internally. This means you cannot free the memory while FMOD is using it, until after Sound::release is called.

+

With FMOD_OPENMEMORY_POINT, for PCM formats, only WAV, FSB, and RAW are supported. For compressed formats, only those formats supported by FMOD_CREATECOMPRESSEDSAMPLE are supported.

+

With FMOD_OPENMEMORY_POINT and FMOD_OPENRAW or PCM, if using them together, note that you must pad the data on each side by 16 bytes. This is so fmod can modify the ends of the data for looping / interpolation / mixing purposes. If a wav file, you will need to insert silence, and then reset loop points to stop the playback from playing that silence.

+

See Also: System::createSound, System::createStream, Sound::setMode, ChannelControl::setMode

+

FMOD_RESULT

+

Error codes returned from every function.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
typedef enum FMOD_RESULT {
+  FMOD_OK,
+  FMOD_ERR_BADCOMMAND,
+  FMOD_ERR_CHANNEL_ALLOC,
+  FMOD_ERR_CHANNEL_STOLEN,
+  FMOD_ERR_DMA,
+  FMOD_ERR_DSP_CONNECTION,
+  FMOD_ERR_DSP_DONTPROCESS,
+  FMOD_ERR_DSP_FORMAT,
+  FMOD_ERR_DSP_INUSE,
+  FMOD_ERR_DSP_NOTFOUND,
+  FMOD_ERR_DSP_RESERVED,
+  FMOD_ERR_DSP_SILENCE,
+  FMOD_ERR_DSP_TYPE,
+  FMOD_ERR_FILE_BAD,
+  FMOD_ERR_FILE_COULDNOTSEEK,
+  FMOD_ERR_FILE_DISKEJECTED,
+  FMOD_ERR_FILE_EOF,
+  FMOD_ERR_FILE_ENDOFDATA,
+  FMOD_ERR_FILE_NOTFOUND,
+  FMOD_ERR_FORMAT,
+  FMOD_ERR_HEADER_MISMATCH,
+  FMOD_ERR_HTTP,
+  FMOD_ERR_HTTP_ACCESS,
+  FMOD_ERR_HTTP_PROXY_AUTH,
+  FMOD_ERR_HTTP_SERVER_ERROR,
+  FMOD_ERR_HTTP_TIMEOUT,
+  FMOD_ERR_INITIALIZATION,
+  FMOD_ERR_INITIALIZED,
+  FMOD_ERR_INTERNAL,
+  FMOD_ERR_INVALID_FLOAT,
+  FMOD_ERR_INVALID_HANDLE,
+  FMOD_ERR_INVALID_PARAM,
+  FMOD_ERR_INVALID_POSITION,
+  FMOD_ERR_INVALID_SPEAKER,
+  FMOD_ERR_INVALID_SYNCPOINT,
+  FMOD_ERR_INVALID_THREAD,
+  FMOD_ERR_INVALID_VECTOR,
+  FMOD_ERR_MAXAUDIBLE,
+  FMOD_ERR_MEMORY,
+  FMOD_ERR_MEMORY_CANTPOINT,
+  FMOD_ERR_NEEDS3D,
+  FMOD_ERR_NEEDSHARDWARE,
+  FMOD_ERR_NET_CONNECT,
+  FMOD_ERR_NET_SOCKET_ERROR,
+  FMOD_ERR_NET_URL,
+  FMOD_ERR_NET_WOULD_BLOCK,
+  FMOD_ERR_NOTREADY,
+  FMOD_ERR_OUTPUT_ALLOCATED,
+  FMOD_ERR_OUTPUT_CREATEBUFFER,
+  FMOD_ERR_OUTPUT_DRIVERCALL,
+  FMOD_ERR_OUTPUT_FORMAT,
+  FMOD_ERR_OUTPUT_INIT,
+  FMOD_ERR_OUTPUT_NODRIVERS,
+  FMOD_ERR_PLUGIN,
+  FMOD_ERR_PLUGIN_MISSING,
+  FMOD_ERR_PLUGIN_RESOURCE,
+  FMOD_ERR_PLUGIN_VERSION,
+  FMOD_ERR_RECORD,
+  FMOD_ERR_REVERB_CHANNELGROUP,
+  FMOD_ERR_REVERB_INSTANCE,
+  FMOD_ERR_SUBSOUNDS,
+  FMOD_ERR_SUBSOUND_ALLOCATED,
+  FMOD_ERR_SUBSOUND_CANTMOVE,
+  FMOD_ERR_TAGNOTFOUND,
+  FMOD_ERR_TOOMANYCHANNELS,
+  FMOD_ERR_TRUNCATED,
+  FMOD_ERR_UNIMPLEMENTED,
+  FMOD_ERR_UNINITIALIZED,
+  FMOD_ERR_UNSUPPORTED,
+  FMOD_ERR_VERSION,
+  FMOD_ERR_EVENT_ALREADY_LOADED,
+  FMOD_ERR_EVENT_LIVEUPDATE_BUSY,
+  FMOD_ERR_EVENT_LIVEUPDATE_MISMATCH,
+  FMOD_ERR_EVENT_LIVEUPDATE_TIMEOUT,
+  FMOD_ERR_EVENT_NOTFOUND,
+  FMOD_ERR_STUDIO_UNINITIALIZED,
+  FMOD_ERR_STUDIO_NOT_LOADED,
+  FMOD_ERR_INVALID_STRING,
+  FMOD_ERR_ALREADY_LOCKED,
+  FMOD_ERR_NOT_LOCKED,
+  FMOD_ERR_RECORD_DISCONNECTED,
+  FMOD_ERR_TOOMANYSAMPLES
+} FMOD_RESULT;
+
+ +
enum RESULT : int
+{
+  OK,
+  ERR_BADCOMMAND,
+  ERR_CHANNEL_ALLOC,
+  ERR_CHANNEL_STOLEN,
+  ERR_DMA,
+  ERR_DSP_CONNECTION,
+  ERR_DSP_DONTPROCESS,
+  ERR_DSP_FORMAT,
+  ERR_DSP_INUSE,
+  ERR_DSP_NOTFOUND,
+  ERR_DSP_RESERVED,
+  ERR_DSP_SILENCE,
+  ERR_DSP_TYPE,
+  ERR_FILE_BAD,
+  ERR_FILE_COULDNOTSEEK,
+  ERR_FILE_DISKEJECTED,
+  ERR_FILE_EOF,
+  ERR_FILE_ENDOFDATA,
+  ERR_FILE_NOTFOUND,
+  ERR_FORMAT,
+  ERR_HEADER_MISMATCH,
+  ERR_HTTP,
+  ERR_HTTP_ACCESS,
+  ERR_HTTP_PROXY_AUTH,
+  ERR_HTTP_SERVER_ERROR,
+  ERR_HTTP_TIMEOUT,
+  ERR_INITIALIZATION,
+  ERR_INITIALIZED,
+  ERR_INTERNAL,
+  ERR_INVALID_FLOAT,
+  ERR_INVALID_HANDLE,
+  ERR_INVALID_PARAM,
+  ERR_INVALID_POSITION,
+  ERR_INVALID_SPEAKER,
+  ERR_INVALID_SYNCPOINT,
+  ERR_INVALID_THREAD,
+  ERR_INVALID_VECTOR,
+  ERR_MAXAUDIBLE,
+  ERR_MEMORY,
+  ERR_MEMORY_CANTPOINT,
+  ERR_NEEDS3D,
+  ERR_NEEDSHARDWARE,
+  ERR_NET_CONNECT,
+  ERR_NET_SOCKET_ERROR,
+  ERR_NET_URL,
+  ERR_NET_WOULD_BLOCK,
+  ERR_NOTREADY,
+  ERR_OUTPUT_ALLOCATED,
+  ERR_OUTPUT_CREATEBUFFER,
+  ERR_OUTPUT_DRIVERCALL,
+  ERR_OUTPUT_FORMAT,
+  ERR_OUTPUT_INIT,
+  ERR_OUTPUT_NODRIVERS,
+  ERR_PLUGIN,
+  ERR_PLUGIN_MISSING,
+  ERR_PLUGIN_RESOURCE,
+  ERR_PLUGIN_VERSION,
+  ERR_RECORD,
+  ERR_REVERB_CHANNELGROUP,
+  ERR_REVERB_INSTANCE,
+  ERR_SUBSOUNDS,
+  ERR_SUBSOUND_ALLOCATED,
+  ERR_SUBSOUND_CANTMOVE,
+  ERR_TAGNOTFOUND,
+  ERR_TOOMANYCHANNELS,
+  ERR_TRUNCATED,
+  ERR_UNIMPLEMENTED,
+  ERR_UNINITIALIZED,
+  ERR_UNSUPPORTED,
+  ERR_VERSION,
+  ERR_EVENT_ALREADY_LOADED,
+  ERR_EVENT_LIVEUPDATE_BUSY,
+  ERR_EVENT_LIVEUPDATE_MISMATCH,
+  ERR_EVENT_LIVEUPDATE_TIMEOUT,
+  ERR_EVENT_NOTFOUND,
+  ERR_STUDIO_UNINITIALIZED,
+  ERR_STUDIO_NOT_LOADED,
+  ERR_INVALID_STRING,
+  ERR_ALREADY_LOCKED,
+  ERR_NOT_LOCKED,
+  ERR_RECORD_DISCONNECTED,
+  ERR_TOOMANYSAMPLES,
+}
+
+ +
OK
+ERR_BADCOMMAND
+ERR_CHANNEL_ALLOC
+ERR_CHANNEL_STOLEN
+ERR_DMA
+ERR_DSP_CONNECTION
+ERR_DSP_DONTPROCESS
+ERR_DSP_FORMAT
+ERR_DSP_INUSE
+ERR_DSP_NOTFOUND
+ERR_DSP_RESERVED
+ERR_DSP_SILENCE
+ERR_DSP_TYPE
+ERR_FILE_BAD
+ERR_FILE_COULDNOTSEEK
+ERR_FILE_DISKEJECTED
+ERR_FILE_EOF
+ERR_FILE_ENDOFDATA
+ERR_FILE_NOTFOUND
+ERR_FORMAT
+ERR_HEADER_MISMATCH
+ERR_HTTP
+ERR_HTTP_ACCESS
+ERR_HTTP_PROXY_AUTH
+ERR_HTTP_SERVER_ERROR
+ERR_HTTP_TIMEOUT
+ERR_INITIALIZATION
+ERR_INITIALIZED
+ERR_INTERNAL
+ERR_INVALID_FLOAT
+ERR_INVALID_HANDLE
+ERR_INVALID_PARAM
+ERR_INVALID_POSITION
+ERR_INVALID_SPEAKER
+ERR_INVALID_SYNCPOINT
+ERR_INVALID_THREAD
+ERR_INVALID_VECTOR
+ERR_MAXAUDIBLE
+ERR_MEMORY
+ERR_MEMORY_CANTPOINT
+ERR_NEEDS3D
+ERR_NEEDSHARDWARE
+ERR_NET_CONNECT
+ERR_NET_SOCKET_ERROR
+ERR_NET_URL
+ERR_NET_WOULD_BLOCK
+ERR_NOTREADY
+ERR_OUTPUT_ALLOCATED
+ERR_OUTPUT_CREATEBUFFER
+ERR_OUTPUT_DRIVERCALL
+ERR_OUTPUT_FORMAT
+ERR_OUTPUT_INIT
+ERR_OUTPUT_NODRIVERS
+ERR_PLUGIN
+ERR_PLUGIN_MISSING
+ERR_PLUGIN_RESOURCE
+ERR_PLUGIN_VERSION
+ERR_RECORD
+ERR_REVERB_CHANNELGROUP
+ERR_REVERB_INSTANCE
+ERR_SUBSOUNDS
+ERR_SUBSOUND_ALLOCATED
+ERR_SUBSOUND_CANTMOVE
+ERR_TAGNOTFOUND
+ERR_TOOMANYCHANNELS
+ERR_TRUNCATED
+ERR_UNIMPLEMENTED
+ERR_UNINITIALIZED
+ERR_UNSUPPORTED
+ERR_VERSION
+ERR_EVENT_ALREADY_LOADED
+ERR_EVENT_LIVEUPDATE_BUSY
+ERR_EVENT_LIVEUPDATE_MISMATCH
+ERR_EVENT_LIVEUPDATE_TIMEOUT
+ERR_EVENT_NOTFOUND
+ERR_STUDIO_UNINITIALIZED
+ERR_STUDIO_NOT_LOADED
+ERR_INVALID_STRING
+ERR_ALREADY_LOCKED
+ERR_NOT_LOCKED
+ERR_RECORD_DISCONNECTED
+ERR_TOOMANYSAMPLES
+
+ +
+
FMOD_OK
+
No errors.
+
FMOD_ERR_BADCOMMAND
+
Tried to call a function on a data type that does not allow this type of functionality (ie calling Sound::lock on a streaming Sound).
+
FMOD_ERR_CHANNEL_ALLOC
+
Error trying to allocate a Channel.
+
FMOD_ERR_CHANNEL_STOLEN
+
The specified Channel has been reused to play another Sound.
+
FMOD_ERR_DMA
+
DMA Failure. See debug output for more information.
+
FMOD_ERR_DSP_CONNECTION
+
DSP connection error. Connection possibly caused a cyclic dependency or connected DSPs with incompatible buffer counts.
+
FMOD_ERR_DSP_DONTPROCESS
+
DSP return code from a DSP process query callback. Tells mixer not to call the process callback and therefore not consume CPU. Use this to optimize the DSP graph.
+
FMOD_ERR_DSP_FORMAT
+
DSP format error. A DSP unit may have attempted to connect to this graph with the wrong format, or a matrix may have been set with the wrong size if the target unit has a specified channel map.
+
FMOD_ERR_DSP_INUSE
+
DSP is already in the mixer's DSP graph. It must be removed before being reinserted or released.
+
FMOD_ERR_DSP_NOTFOUND
+
DSP connection error. Couldn't find the DSP unit specified.
+
FMOD_ERR_DSP_RESERVED
+
DSP operation error. Cannot perform operation on this DSP as it is reserved by the system.
+
FMOD_ERR_DSP_SILENCE
+
DSP return code from a DSP process query callback. Tells the mixer silence would be produced from read, so go idle and not consume CPU. Use this to optimize the DSP graph.
+
FMOD_ERR_DSP_TYPE
+
DSP operation cannot be performed on a DSP of this type.
+
FMOD_ERR_FILE_BAD
+
Error loading file.
+
FMOD_ERR_FILE_COULDNOTSEEK
+
Couldn't perform seek operation. This is a limitation of the medium (ie netstreams) or the file format.
+
FMOD_ERR_FILE_DISKEJECTED
+
Media was ejected while reading.
+
FMOD_ERR_FILE_EOF
+
End of file unexpectedly reached while trying to read essential data (truncated?).
+
FMOD_ERR_FILE_ENDOFDATA
+
End of current chunk reached while trying to read data.
+
FMOD_ERR_FILE_NOTFOUND
+
File not found.
+
FMOD_ERR_FORMAT
+
Unsupported file or audio format.
+
FMOD_ERR_HEADER_MISMATCH
+
There is a version mismatch between the FMOD header and either the FMOD API library or the Core API library.
+
FMOD_ERR_HTTP
+
A HTTP error occurred. This is a catch-all for HTTP errors not listed elsewhere.
+
FMOD_ERR_HTTP_ACCESS
+
The specified resource requires authentication or is forbidden.
+
FMOD_ERR_HTTP_PROXY_AUTH
+
Proxy authentication is required to access the specified resource.
+
FMOD_ERR_HTTP_SERVER_ERROR
+
A HTTP server error occurred.
+
FMOD_ERR_HTTP_TIMEOUT
+
The HTTP request timed out.
+
FMOD_ERR_INITIALIZATION
+
FMOD was not initialized correctly to support this function.
+
FMOD_ERR_INITIALIZED
+
Cannot call this command after System::init.
+
FMOD_ERR_INTERNAL
+
An error occured in the FMOD system. Use the logging version of FMOD for more information.
+
FMOD_ERR_INVALID_FLOAT
+
Value passed in was a NaN, Inf or denormalized float.
+
FMOD_ERR_INVALID_HANDLE
+
An invalid object handle was used.
+
FMOD_ERR_INVALID_PARAM
+
An invalid parameter was passed to this function.
+
FMOD_ERR_INVALID_POSITION
+
An invalid seek position was passed to this function.
+
FMOD_ERR_INVALID_SPEAKER
+
An invalid speaker was passed to this function based on the current speaker mode.
+
FMOD_ERR_INVALID_SYNCPOINT
+
The syncpoint did not come from this Sound handle.
+
FMOD_ERR_INVALID_THREAD
+
Tried to call a function on a thread that is not supported.
+
FMOD_ERR_INVALID_VECTOR
+
The vectors passed in are not unit length, or perpendicular.
+
FMOD_ERR_MAXAUDIBLE
+
Reached maximum audible playback count for this Sound's SoundGroup.
+
FMOD_ERR_MEMORY
+
Not enough memory or resources.
+
FMOD_ERR_MEMORY_CANTPOINT
+
Can't use FMOD_OPENMEMORY_POINT on non PCM source data, or non mp3/xma/adpcm data if FMOD_CREATECOMPRESSEDSAMPLE was used.
+
FMOD_ERR_NEEDS3D
+
Tried to call a command on a 2D Sound when the command was meant for 3D Sound.
+
FMOD_ERR_NEEDSHARDWARE
+
Tried to use a feature that requires hardware support.
+
FMOD_ERR_NET_CONNECT
+
Couldn't connect to the specified host.
+
FMOD_ERR_NET_SOCKET_ERROR
+
A socket error occurred. This is a catch-all for socket-related errors not listed elsewhere.
+
FMOD_ERR_NET_URL
+
The specified URL couldn't be resolved.
+
FMOD_ERR_NET_WOULD_BLOCK
+
Operation on a non-blocking socket could not complete immediately.
+
FMOD_ERR_NOTREADY
+
Operation could not be performed because specified Sound/DSP connection is not ready.
+
FMOD_ERR_OUTPUT_ALLOCATED
+
Error initializing output device, but more specifically, the output device is already in use and cannot be reused.
+
FMOD_ERR_OUTPUT_CREATEBUFFER
+
Error creating hardware sound buffer.
+
FMOD_ERR_OUTPUT_DRIVERCALL
+
A call to a standard soundcard driver failed, which could possibly mean a bug in the driver or resources were missing or exhausted.
+
FMOD_ERR_OUTPUT_FORMAT
+
Soundcard does not support the specified format.
+
FMOD_ERR_OUTPUT_INIT
+
Error initializing output device.
+
FMOD_ERR_OUTPUT_NODRIVERS
+
The output device has no drivers installed. If pre-init, FMOD_OUTPUT_NOSOUND is selected as the output mode. If post-init, the function just fails.
+
FMOD_ERR_PLUGIN
+
An unspecified error has been returned from a plug-in.
+
FMOD_ERR_PLUGIN_MISSING
+
A requested output, dsp unit type or codec was not available.
+
FMOD_ERR_PLUGIN_RESOURCE
+
A resource that the plug-in requires (e.g.: The DLS file for MIDI playback) cannot be allocated or found.
+
FMOD_ERR_PLUGIN_VERSION
+
A plug-in was built with an unsupported SDK version.
+
FMOD_ERR_RECORD
+
An error occurred trying to initialize the recording device.
+
FMOD_ERR_REVERB_CHANNELGROUP
+
Reverb properties cannot be set on this Channel because a parent ChannelGroup owns the reverb connection.
+
FMOD_ERR_REVERB_INSTANCE
+
Specified instance in FMOD_REVERB_PROPERTIES couldn't be set. Most likely because it is an invalid instance number or the reverb doesn't exist.
+
FMOD_ERR_SUBSOUNDS
+
The error occurred because the Sound referenced contains subsounds when it shouldn't have, or it doesn't contain subsounds when it should have. The operation may also not be able to be performed on a parent Sound.
+
FMOD_ERR_SUBSOUND_ALLOCATED
+
This subsound is already being used by another Sound, you cannot have more than one parent to a Sound. Null out the other parent's entry first.
+
FMOD_ERR_SUBSOUND_CANTMOVE
+
Shared subsounds cannot be replaced or moved from their parent stream, such as when the parent stream is an FSB file.
+
FMOD_ERR_TAGNOTFOUND
+
The specified tag could not be found or there are no tags.
+
FMOD_ERR_TOOMANYCHANNELS
+
The Sound created exceeds the allowable input speaker channel count. This result occurs only when a signal's speaker channel format requires more than 32 channels.
+
FMOD_ERR_TRUNCATED
+
The retrieved string is too long to fit in the supplied buffer and has been truncated.
+
FMOD_ERR_UNIMPLEMENTED
+
Something in FMOD hasn't been implemented when it should be. Contact support.
+
FMOD_ERR_UNINITIALIZED
+
This command failed because System::init or System::setDriver was not called.
+
FMOD_ERR_UNSUPPORTED
+
A command issued was not supported by this object. Possibly a plug-in without certain callbacks specified.
+
FMOD_ERR_VERSION
+
The version number of this file format is not supported.
+
FMOD_ERR_EVENT_ALREADY_LOADED
+
The specified bank has already been loaded.
+
FMOD_ERR_EVENT_LIVEUPDATE_BUSY
+
The live update connection failed due to the game already being connected.
+
FMOD_ERR_EVENT_LIVEUPDATE_MISMATCH
+
The live update connection failed due to the game data being out of sync with the tool.
+
FMOD_ERR_EVENT_LIVEUPDATE_TIMEOUT
+
The live update connection timed out.
+
FMOD_ERR_EVENT_NOTFOUND
+
The requested event, parameter, bus or vca could not be found.
+
FMOD_ERR_STUDIO_UNINITIALIZED
+
The Studio::System object is not yet initialized.
+
FMOD_ERR_STUDIO_NOT_LOADED
+
The specified resource is not loaded, so it can't be unloaded.
+
FMOD_ERR_INVALID_STRING
+
An invalid string was passed to this function.
+
FMOD_ERR_ALREADY_LOCKED
+
The specified resource is already locked.
+
FMOD_ERR_NOT_LOCKED
+
The specified resource is not locked, so it can't be unlocked.
+
FMOD_ERR_RECORD_DISCONNECTED
+
The specified recording driver has been disconnected.
+
FMOD_ERR_TOOMANYSAMPLES
+
The length provided exceeds the allowable limit.
+
+

FMOD_SPEAKER

+

Assigns an enumeration for a speaker index.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
typedef enum FMOD_SPEAKER {
+  FMOD_SPEAKER_NONE = -1,
+  FMOD_SPEAKER_FRONT_LEFT,
+  FMOD_SPEAKER_FRONT_RIGHT,
+  FMOD_SPEAKER_FRONT_CENTER,
+  FMOD_SPEAKER_LOW_FREQUENCY,
+  FMOD_SPEAKER_SURROUND_LEFT,
+  FMOD_SPEAKER_SURROUND_RIGHT,
+  FMOD_SPEAKER_BACK_LEFT,
+  FMOD_SPEAKER_BACK_RIGHT,
+  FMOD_SPEAKER_TOP_FRONT_LEFT,
+  FMOD_SPEAKER_TOP_FRONT_RIGHT,
+  FMOD_SPEAKER_TOP_BACK_LEFT,
+  FMOD_SPEAKER_TOP_BACK_RIGHT,
+  FMOD_SPEAKER_MAX
+} FMOD_SPEAKER;
+
+ +
enum SPEAKER : int
+{
+  NONE = -1,
+  FRONT_LEFT,
+  FRONT_RIGHT,
+  FRONT_CENTER,
+  LOW_FREQUENCY,
+  SURROUND_LEFT,
+  SURROUND_RIGHT,
+  BACK_LEFT,
+  BACK_RIGHT,
+  TOP_FRONT_LEFT,
+  TOP_FRONT_RIGHT,
+  TOP_BACK_LEFT,
+  TOP_BACK_RIGHT,
+  MAX,
+}
+
+ +
SPEAKER_NONE = -1
+SPEAKER_FRONT_LEFT
+SPEAKER_FRONT_RIGHT
+SPEAKER_FRONT_CENTER
+SPEAKER_LOW_FREQUENCY
+SPEAKER_SURROUND_LEFT
+SPEAKER_SURROUND_RIGHT
+SPEAKER_BACK_LEFT
+SPEAKER_BACK_RIGHT
+SPEAKER_TOP_FRONT_LEFT
+SPEAKER_TOP_FRONT_RIGHT
+SPEAKER_TOP_BACK_LEFT
+SPEAKER_TOP_BACK_RIGHT
+SPEAKER_MAX
+
+ +
+
FMOD_SPEAKER_NONE
+
No speaker
+
FMOD_SPEAKER_FRONT_LEFT
+
The front left speaker
+
FMOD_SPEAKER_FRONT_RIGHT
+
The front right speaker
+
FMOD_SPEAKER_FRONT_CENTER
+
The front center speaker
+
FMOD_SPEAKER_LOW_FREQUENCY
+
The LFE or 'subwoofer' speaker
+
FMOD_SPEAKER_SURROUND_LEFT
+
The surround left (usually to the side) speaker
+
FMOD_SPEAKER_SURROUND_RIGHT
+
The surround right (usually to the side) speaker
+
FMOD_SPEAKER_BACK_LEFT
+
The back left speaker
+
FMOD_SPEAKER_BACK_RIGHT
+
The back right speaker
+
FMOD_SPEAKER_TOP_FRONT_LEFT
+
The top front left speaker
+
FMOD_SPEAKER_TOP_FRONT_RIGHT
+
The top front right speaker
+
FMOD_SPEAKER_TOP_BACK_LEFT
+
The top back left speaker
+
FMOD_SPEAKER_TOP_BACK_RIGHT
+
The top back right speaker
+
FMOD_SPEAKER_MAX
+
Maximum number of speaker types supported.
+
+

See Also: System::setSpeakerPosition, System::getSpeakerPosition

+

FMOD_SPEAKERMODE

+

Speaker mode types.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
typedef enum FMOD_SPEAKERMODE {
+  FMOD_SPEAKERMODE_DEFAULT,
+  FMOD_SPEAKERMODE_RAW,
+  FMOD_SPEAKERMODE_MONO,
+  FMOD_SPEAKERMODE_STEREO,
+  FMOD_SPEAKERMODE_QUAD,
+  FMOD_SPEAKERMODE_SURROUND,
+  FMOD_SPEAKERMODE_5POINT1,
+  FMOD_SPEAKERMODE_7POINT1,
+  FMOD_SPEAKERMODE_7POINT1POINT4,
+  FMOD_SPEAKERMODE_MAX
+} FMOD_SPEAKERMODE;
+
+ +
enum SPEAKERMODE : int
+{
+  DEFAULT,
+  RAW,
+  MONO,
+  STEREO,
+  QUAD,
+  SURROUND,
+  _5POINT1,
+  _7POINT1,
+  _7POINT1POINT4,
+  MAX,
+}
+
+ +
SPEAKERMODE_DEFAULT
+SPEAKERMODE_RAW
+SPEAKERMODE_MONO
+SPEAKERMODE_STEREO
+SPEAKERMODE_QUAD
+SPEAKERMODE_SURROUND
+SPEAKERMODE_5POINT1
+SPEAKERMODE_7POINT1
+SPEAKERMODE_7POINT1POINT4
+SPEAKERMODE_MAX
+
+ +
+
FMOD_SPEAKERMODE_DEFAULT
+
Default speaker mode for the chosen output mode which will resolve after System::init.
+
FMOD_SPEAKERMODE_RAW
+
Assume there is no special mapping from a given channel to a speaker, channels map 1:1 in order. Use System::setSoftwareFormat to specify the speaker count.
+
FMOD_SPEAKERMODE_MONO
+
1 speaker setup (monaural).
+
FMOD_SPEAKERMODE_STEREO
+
2 speaker setup (stereo) front left, front right.
+
FMOD_SPEAKERMODE_QUAD
+
4 speaker setup (4.0) front left, front right, surround left, surround right.
+
FMOD_SPEAKERMODE_SURROUND
+
5 speaker setup (5.0) front left, front right, center, surround left, surround right.
+
FMOD_SPEAKERMODE_5POINT1
+
6 speaker setup (5.1) front left, front right, center, low frequency, surround left, surround right.
+
FMOD_SPEAKERMODE_7POINT1
+
8 speaker setup (7.1) front left, front right, center, low frequency, surround left, surround right, back left, back right.
+
FMOD_SPEAKERMODE_7POINT1POINT4
+
12 speaker setup (7.1.4) front left, front right, center, low frequency, surround left, surround right, back left, back right, top front left, top front right, top back left, top back right.
+
FMOD_SPEAKERMODE_MAX
+
Maximum number of speaker modes supported.
+
+

Note below the phrase 'sound channels' is used. These are the subchannels inside a sound, they are not related and have nothing to do with the FMOD class "Channel".

+

For example a mono sound has 1 sound channel, a stereo sound has 2 sound channels, and an AC3 or 6 channel wav file have 6 "sound channels".

+

FMOD_SPEAKERMODE_RAW
+This mode is for output devices that are not specifically mono/stereo/quad/surround/5.1 or 7.1, but are multi-channel.

+ +

FMOD_SPEAKERMODE_MONO
+This mode is for a 1 speaker arrangement.

+
    +
  • Panning does not work in this speaker mode.
  • +
  • Mono, stereo and multi-channel sounds have each sound channel played on the one speaker at unity.
  • +
  • Mix behavior for multi-channel sounds can be set with ChannelControl::setMixMatrix.
  • +
+

FMOD_SPEAKERMODE_STEREO
+This mode is for 2 speaker arrangements that have a left and right speaker.

+
    +
  • Mono sounds default to an even distribution between left and right. They can be panned with ChannelControl::setPan.
  • +
  • Stereo sounds default to the middle, or full left in the left speaker and full right in the right speaker. They can be cross faded with ChannelControl::setPan.
  • +
  • Multi-channel sounds have each sound channel played on each speaker at unity.
  • +
  • Mix behavior for multi-channel sounds can be set with ChannelControl::setMixMatrix.
  • +
+

FMOD_SPEAKERMODE_QUAD
+This mode is for 4 speaker arrangements that have a front left, front right, surround left and a surround right speaker.

+
    +
  • Mono sounds default to an even distribution between front left and front right. They can be panned with ChannelControl::setPan.
  • +
  • Stereo sounds default to the left sound channel played on the front left, and the right sound channel played on the front right. They can be cross faded with ChannelControl::setPan.
  • +
  • Multi-channel sounds default to all of their sound channels being played on each speaker in order of input.
  • +
  • Mix behavior for multi-channel sounds can be set with ChannelControl::setMixMatrix.
  • +
+

FMOD_SPEAKERMODE_SURROUND
+This mode is for 5 speaker arrangements that have a left/right/center/surround left/surround right.

+
    +
  • Mono sounds default to the center speaker. They can be panned with ChannelControl::setPan.
  • +
  • Stereo sounds default to the left sound channel played on the front left, and the right sound channel played on the front right. They can be cross faded with ChannelControl::setPan.
  • +
  • Multi-channel sounds default to all of their sound channels being played on each speaker in order of input.
  • +
  • Mix behavior for multi-channel sounds can be set with ChannelControl::setMixMatrix.
  • +
+

FMOD_SPEAKERMODE_5POINT1
+This mode is for 5.1 speaker arrangements that have a left/right/center/surround left/surround right and a subwoofer speaker.

+
    +
  • Mono sounds default to the center speaker. They can be panned with ChannelControl::setPan.
  • +
  • Stereo sounds default to the left sound channel played on the front left, and the right sound channel played on the front right. They can be cross faded with ChannelControl::setPan.
  • +
  • Multi-channel sounds default to all of their sound channels being played on each speaker in order of input.
  • +
  • Mix behavior for multi-channel sounds can be set with ChannelControl::setMixMatrix.
  • +
+

FMOD_SPEAKERMODE_7POINT1
+This mode is for 7.1 speaker arrangements that have a left/right/center/surround left/surround right/rear left/rear right and a subwoofer speaker.

+
    +
  • Mono sounds default to the center speaker. They can be panned with ChannelControl::setPan.
  • +
  • Stereo sounds default to the left sound channel played on the front left, and the right sound channel played on the front right. They can be cross faded with ChannelControl::setPan.
  • +
  • Multi-channel sounds default to all of their sound channels being played on each speaker in order of input.
  • +
  • Mix behavior for multi-channel sounds can be set with ChannelControl::setMixMatrix.
  • +
+

See the FMOD Studio Mixing Guide for graphical depictions of each speaker mode.

+

See Also: System::getSoftwareFormat, DSP::setChannelFormat

+

FMOD_SYNCPOINT

+

Named marker for a given point in time.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
typedef struct FMOD_SYNCPOINT FMOD_SYNCPOINT;
+
+ +
IntPtr
+
+ +
+

Not supported for JavaScript.

+
+

This is an opaque type that you fetch with Sound::getSyncPoint then query with Sound::getSyncPointInfo.

+

See Also: Sound::addSyncPoint, Sound::deleteSyncPoint

+

FMOD_THREAD_AFFINITY

+

Bitfield for specifying the CPU core a given thread runs on.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
#define FMOD_THREAD_AFFINITY_GROUP_DEFAULT          0x4000000000000000
+#define FMOD_THREAD_AFFINITY_GROUP_A                0x4000000000000001
+#define FMOD_THREAD_AFFINITY_GROUP_B                0x4000000000000002
+#define FMOD_THREAD_AFFINITY_GROUP_C                0x4000000000000003
+#define FMOD_THREAD_AFFINITY_MIXER                  FMOD_THREAD_AFFINITY_GROUP_A
+#define FMOD_THREAD_AFFINITY_FEEDER                 FMOD_THREAD_AFFINITY_GROUP_C
+#define FMOD_THREAD_AFFINITY_STREAM                 FMOD_THREAD_AFFINITY_GROUP_C
+#define FMOD_THREAD_AFFINITY_FILE                   FMOD_THREAD_AFFINITY_GROUP_C
+#define FMOD_THREAD_AFFINITY_NONBLOCKING            FMOD_THREAD_AFFINITY_GROUP_C
+#define FMOD_THREAD_AFFINITY_RECORD                 FMOD_THREAD_AFFINITY_GROUP_C
+#define FMOD_THREAD_AFFINITY_GEOMETRY               FMOD_THREAD_AFFINITY_GROUP_C
+#define FMOD_THREAD_AFFINITY_PROFILER               FMOD_THREAD_AFFINITY_GROUP_C
+#define FMOD_THREAD_AFFINITY_STUDIO_UPDATE          FMOD_THREAD_AFFINITY_GROUP_B
+#define FMOD_THREAD_AFFINITY_STUDIO_LOAD_BANK       FMOD_THREAD_AFFINITY_GROUP_C
+#define FMOD_THREAD_AFFINITY_STUDIO_LOAD_SAMPLE     FMOD_THREAD_AFFINITY_GROUP_C
+#define FMOD_THREAD_AFFINITY_CORE_ALL               0
+#define FMOD_THREAD_AFFINITY_CORE_0                 (1 << 0)
+#define FMOD_THREAD_AFFINITY_CORE_1                 (1 << 1)
+#define FMOD_THREAD_AFFINITY_CORE_2                 (1 << 2)
+#define FMOD_THREAD_AFFINITY_CORE_3                 (1 << 3)
+#define FMOD_THREAD_AFFINITY_CORE_4                 (1 << 4)
+#define FMOD_THREAD_AFFINITY_CORE_5                 (1 << 5)
+#define FMOD_THREAD_AFFINITY_CORE_6                 (1 << 6)
+#define FMOD_THREAD_AFFINITY_CORE_7                 (1 << 7)
+#define FMOD_THREAD_AFFINITY_CORE_8                 (1 << 8)
+#define FMOD_THREAD_AFFINITY_CORE_9                 (1 << 9)
+#define FMOD_THREAD_AFFINITY_CORE_10                (1 << 10)
+#define FMOD_THREAD_AFFINITY_CORE_11                (1 << 11)
+#define FMOD_THREAD_AFFINITY_CORE_12                (1 << 12)
+#define FMOD_THREAD_AFFINITY_CORE_13                (1 << 13)
+#define FMOD_THREAD_AFFINITY_CORE_14                (1 << 14)
+#define FMOD_THREAD_AFFINITY_CORE_15                (1 << 15)
+
+ +
[Flags]
+enum THREAD_AFFINITY : long
+{
+  GROUP_DEFAULT       = 0x4000000000000000,
+  GROUP_A             = 0x4000000000000001,
+  GROUP_B             = 0x4000000000000002,
+  GROUP_C             = 0x4000000000000003,
+  MIXER               = GROUP_A,
+  FEEDER              = GROUP_C,
+  STREAM              = GROUP_C,
+  FILE                = GROUP_C,
+  NONBLOCKING         = GROUP_C,
+  RECORD              = GROUP_C,
+  GEOMETRY            = GROUP_C,
+  PROFILER            = GROUP_C,
+  STUDIO_UPDATE       = GROUP_B,
+  STUDIO_LOAD_BANK    = GROUP_C,
+  STUDIO_LOAD_SAMPLE  = GROUP_C,
+  CORE_ALL            = 0,
+  CORE_0              = 1 << 0,
+  CORE_1              = 1 << 1,
+  CORE_2              = 1 << 2,
+  CORE_3              = 1 << 3,
+  CORE_4              = 1 << 4,
+  CORE_5              = 1 << 5,
+  CORE_6              = 1 << 6,
+  CORE_7              = 1 << 7,
+  CORE_8              = 1 << 8,
+  CORE_9              = 1 << 9,
+  CORE_10             = 1 << 10,
+  CORE_11             = 1 << 11,
+  CORE_12             = 1 << 12,
+  CORE_13             = 1 << 13,
+  CORE_14             = 1 << 14,
+  CORE_15             = 1 << 15
+}
+
+ +
+

Not supported for JavaScript.

+
+
+
FMOD_THREAD_AFFINITY_GROUP_DEFAULT
+
For a given thread use the default listed below, i.e. FMOD_THREAD_TYPE_MIXER uses FMOD_THREAD_AFFINITY_MIXER.
+
FMOD_THREAD_AFFINITY_GROUP_A
+
Grouping A is recommended to isolate the mixer thread FMOD_THREAD_TYPE_MIXER.
+
FMOD_THREAD_AFFINITY_GROUP_B
+
Grouping B is recommended to isolate the Studio update thread FMOD_THREAD_TYPE_STUDIO_UPDATE.
+
FMOD_THREAD_AFFINITY_GROUP_C
+
Grouping C is recommended for all remaining threads.
+
FMOD_THREAD_AFFINITY_MIXER
+
Default affinity for FMOD_THREAD_TYPE_MIXER.
+
FMOD_THREAD_AFFINITY_FEEDER
+
Default affinity for FMOD_THREAD_TYPE_FEEDER.
+
FMOD_THREAD_AFFINITY_STREAM
+
Default affinity for FMOD_THREAD_TYPE_STREAM.
+
FMOD_THREAD_AFFINITY_FILE
+
Default affinity for FMOD_THREAD_TYPE_FILE.
+
FMOD_THREAD_AFFINITY_NONBLOCKING
+
Default affinity for FMOD_THREAD_TYPE_NONBLOCKING.
+
FMOD_THREAD_AFFINITY_RECORD
+
Default affinity for FMOD_THREAD_TYPE_RECORD.
+
FMOD_THREAD_AFFINITY_GEOMETRY
+
Default affinity for FMOD_THREAD_TYPE_GEOMETRY.
+
FMOD_THREAD_AFFINITY_PROFILER
+
Default affinity for FMOD_THREAD_TYPE_PROFILER.
+
FMOD_THREAD_AFFINITY_STUDIO_UPDATE
+
Default affinity for FMOD_THREAD_TYPE_STUDIO_UPDATE.
+
FMOD_THREAD_AFFINITY_STUDIO_LOAD_BANK
+
Default affinity for FMOD_THREAD_TYPE_STUDIO_LOAD_BANK.
+
FMOD_THREAD_AFFINITY_STUDIO_LOAD_SAMPLE
+
Default affinity for FMOD_THREAD_TYPE_STUDIO_LOAD_SAMPLE.
+
FMOD_THREAD_AFFINITY_CONVOLUTION1
+
Default affinity for FMOD_THREAD_TYPE_CONVOLUTION1.
+
FMOD_THREAD_AFFINITY_CONVOLUTION2
+
Default affinity for FMOD_THREAD_TYPE_CONVOLUTION2.
+
FMOD_THREAD_AFFINITY_CORE_ALL
+
Assign to all cores.
+
FMOD_THREAD_AFFINITY_CORE_0
+
Assign to core 0.
+
FMOD_THREAD_AFFINITY_CORE_1
+
Assign to core 1.
+
FMOD_THREAD_AFFINITY_CORE_2
+
Assign to core 2.
+
FMOD_THREAD_AFFINITY_CORE_3
+
Assign to core 3.
+
FMOD_THREAD_AFFINITY_CORE_4
+
Assign to core 4.
+
FMOD_THREAD_AFFINITY_CORE_5
+
Assign to core 5.
+
FMOD_THREAD_AFFINITY_CORE_6
+
Assign to core 6.
+
FMOD_THREAD_AFFINITY_CORE_7
+
Assign to core 7.
+
FMOD_THREAD_AFFINITY_CORE_8
+
Assign to core 8.
+
FMOD_THREAD_AFFINITY_CORE_9
+
Assign to core 9.
+
FMOD_THREAD_AFFINITY_CORE_10
+
Assign to core 10.
+
FMOD_THREAD_AFFINITY_CORE_11
+
Assign to core 11.
+
FMOD_THREAD_AFFINITY_CORE_12
+
Assign to core 12.
+
FMOD_THREAD_AFFINITY_CORE_13
+
Assign to core 13.
+
FMOD_THREAD_AFFINITY_CORE_14
+
Assign to core 14.
+
FMOD_THREAD_AFFINITY_CORE_15
+
Assign to core 15.
+
+

The platform agnostic thread groups, A, B and C give recommendations about FMOD threads that should be separated from one another.
+Platforms with fixed CPU core counts will try to honor this request, those that don't will leave affinity to the operating system.
+See the FMOD platform specific docs for each platform to see how the groups map to cores.

+

If an explicit core affinity is given, i.e. FMOD_THREAD_AFFINITY_CORE_11 and that core is unavailable a fatal error will be produced.

+

Explicit core assignment up to (1 << 61) is supported for platforms with that many cores.

+

See Also: Thread_SetAttributes

+

FMOD_THREAD_PRIORITY

+

Scheduling priority to assign a given thread to.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
#define FMOD_THREAD_PRIORITY_PLATFORM_MIN           (-32 * 1024)
+#define FMOD_THREAD_PRIORITY_PLATFORM_MAX           ( 32 * 1024)
+#define FMOD_THREAD_PRIORITY_DEFAULT                (FMOD_THREAD_PRIORITY_PLATFORM_MIN - 1)
+#define FMOD_THREAD_PRIORITY_LOW                    (FMOD_THREAD_PRIORITY_PLATFORM_MIN - 2)
+#define FMOD_THREAD_PRIORITY_MEDIUM                 (FMOD_THREAD_PRIORITY_PLATFORM_MIN - 3)
+#define FMOD_THREAD_PRIORITY_HIGH                   (FMOD_THREAD_PRIORITY_PLATFORM_MIN - 4)
+#define FMOD_THREAD_PRIORITY_VERY_HIGH              (FMOD_THREAD_PRIORITY_PLATFORM_MIN - 5)
+#define FMOD_THREAD_PRIORITY_EXTREME                (FMOD_THREAD_PRIORITY_PLATFORM_MIN - 6)
+#define FMOD_THREAD_PRIORITY_CRITICAL               (FMOD_THREAD_PRIORITY_PLATFORM_MIN - 7)
+#define FMOD_THREAD_PRIORITY_MIXER                  FMOD_THREAD_PRIORITY_EXTREME
+#define FMOD_THREAD_PRIORITY_FEEDER                 FMOD_THREAD_PRIORITY_CRITICAL
+#define FMOD_THREAD_PRIORITY_STREAM                 FMOD_THREAD_PRIORITY_VERY_HIGH
+#define FMOD_THREAD_PRIORITY_FILE                   FMOD_THREAD_PRIORITY_HIGH
+#define FMOD_THREAD_PRIORITY_NONBLOCKING            FMOD_THREAD_PRIORITY_HIGH
+#define FMOD_THREAD_PRIORITY_RECORD                 FMOD_THREAD_PRIORITY_HIGH
+#define FMOD_THREAD_PRIORITY_GEOMETRY               FMOD_THREAD_PRIORITY_LOW
+#define FMOD_THREAD_PRIORITY_PROFILER               FMOD_THREAD_PRIORITY_MEDIUM
+#define FMOD_THREAD_PRIORITY_STUDIO_UPDATE          FMOD_THREAD_PRIORITY_MEDIUM
+#define FMOD_THREAD_PRIORITY_STUDIO_LOAD_BANK       FMOD_THREAD_PRIORITY_MEDIUM
+#define FMOD_THREAD_PRIORITY_STUDIO_LOAD_SAMPLE     FMOD_THREAD_PRIORITY_MEDIUM
+
+ +
enum THREAD_PRIORITY : int
+{
+  PLATFORM_MIN        = -32 * 1024,
+  PLATFORM_MAX        =  32 * 1024,
+  DEFAULT             = PLATFORM_MIN - 1,
+  LOW                 = PLATFORM_MIN - 2,
+  MEDIUM              = PLATFORM_MIN - 3,
+  HIGH                = PLATFORM_MIN - 4,
+  VERY_HIGH           = PLATFORM_MIN - 5,
+  EXTREME             = PLATFORM_MIN - 6,
+  CRITICAL            = PLATFORM_MIN - 7,
+  MIXER               = EXTREME,
+  FEEDER              = CRITICAL,
+  STREAM              = VERY_HIGH,
+  FILE                = HIGH,
+  NONBLOCKING         = HIGH,
+  RECORD              = HIGH,
+  GEOMETRY            = LOW,
+  PROFILER            = MEDIUM,
+  STUDIO_UPDATE       = MEDIUM,
+  STUDIO_LOAD_BANK    = MEDIUM,
+  STUDIO_LOAD_SAMPLE  = MEDIUM
+}
+
+ +
+

Not supported for JavaScript.

+
+
+
FMOD_THREAD_PRIORITY_PLATFORM_MIN
+
Lower bound of platform specific priority range.
+
FMOD_THREAD_PRIORITY_PLATFORM_MAX
+
Upper bound of platform specific priority range.
+
FMOD_THREAD_PRIORITY_DEFAULT
+
For a given thread use the default listed below, i.e. FMOD_THREAD_TYPE_MIXER uses FMOD_THREAD_PRIORITY_MIXER.
+
FMOD_THREAD_PRIORITY_LOW
+
Low platform agnostic priority.
+
FMOD_THREAD_PRIORITY_MEDIUM
+
Medium platform agnostic priority.
+
FMOD_THREAD_PRIORITY_HIGH
+
High platform agnostic priority.
+
FMOD_THREAD_PRIORITY_VERY_HIGH
+
Very high platform agnostic priority.
+
FMOD_THREAD_PRIORITY_EXTREME
+
Extreme platform agnostic priority.
+
FMOD_THREAD_PRIORITY_CRITICAL
+
Critical platform agnostic priority.
+
FMOD_THREAD_PRIORITY_MIXER
+
Default priority for FMOD_THREAD_TYPE_MIXER.
+
FMOD_THREAD_PRIORITY_FEEDER
+
Default priority for FMOD_THREAD_TYPE_FEEDER.
+
FMOD_THREAD_PRIORITY_STREAM
+
Default priority for FMOD_THREAD_TYPE_STREAM.
+
FMOD_THREAD_PRIORITY_FILE
+
Default priority for FMOD_THREAD_TYPE_FILE.
+
FMOD_THREAD_PRIORITY_NONBLOCKING
+
Default priority for FMOD_THREAD_TYPE_NONBLOCKING.
+
FMOD_THREAD_PRIORITY_RECORD
+
Default priority for FMOD_THREAD_TYPE_RECORD.
+
FMOD_THREAD_PRIORITY_GEOMETRY
+
Default priority for FMOD_THREAD_TYPE_GEOMETRY.
+
FMOD_THREAD_PRIORITY_PROFILER
+
Default priority for FMOD_THREAD_TYPE_PROFILER.
+
FMOD_THREAD_PRIORITY_STUDIO_UPDATE
+
Default priority for FMOD_THREAD_TYPE_STUDIO_UPDATE.
+
FMOD_THREAD_PRIORITY_STUDIO_LOAD_BANK
+
Default priority for FMOD_THREAD_TYPE_STUDIO_LOAD_BANK.
+
FMOD_THREAD_PRIORITY_STUDIO_LOAD_SAMPLE
+
Default priority for FMOD_THREAD_TYPE_STUDIO_LOAD_SAMPLE.
+
FMOD_THREAD_PRIORITY_CONVOLUTION1
+
Default priority for FMOD_THREAD_TYPE_CONVOLUTION1.
+
FMOD_THREAD_PRIORITY_CONVOLUTION2
+
Default priority for FMOD_THREAD_TYPE_CONVOLUTION2.
+
+

The platform agnostic priorities are used to rank FMOD threads against one another for best runtime scheduling.
+Platforms will translate these values in to platform specific priorities.
+See the FMOD platform specific docs for each platform to see how the agnostic priorities map to specific values.

+

Explicit platform specific priorities can be given within the range of FMOD_THREAD_PRIORITY_PLATFORM_MIN to FMOD_THREAD_PRIORITY_PLATFORM_MAX.
+See platform documentation for details on the available priority values for a given operating system.

+

See Also: Thread_SetAttributes

+

Thread_SetAttributes

+

Specify the affinity, priority and stack size for all FMOD created threads.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
FMOD_RESULT Thread_SetAttributes(
+  FMOD_THREAD_TYPE type,
+  FMOD_THREAD_AFFINITY affinity = FMOD_THREAD_AFFINITY_GROUP_DEFAULT,
+  FMOD_THREAD_PRIORITY priority = FMOD_THREAD_PRIORITY_DEFAULT,
+  FMOD_THREAD_STACK_SIZE stacksize = FMOD_THREAD_STACK_SIZE_DEFAULT
+);
+
+ +
FMOD_RESULT FMOD_Thread_SetAttributes(
+  FMOD_THREAD_TYPE type,
+  FMOD_THREAD_AFFINITY affinity,
+  FMOD_THREAD_PRIORITY priority,
+  FMOD_THREAD_STACK_SIZE stacksize
+);
+
+ +
static RESULT Thread.SetAttributes(
+  THREAD_TYPE type,
+  THREAD_AFFINITY affinity = THREAD_AFFINITY.GROUP_DEFAULT,
+  THREAD_PRIORITY priority = THREAD_PRIORITY.DEFAULT,
+  THREAD_STACK_SIZE stacksize = THREAD_STACK_SIZE.DEFAULT
+);
+
+ +
+

Not supported for JavaScript.

+
+
+
type
+
Identifier for an FMOD thread. (FMOD_THREAD_TYPE)
+
affinity Opt
+
Bitfield of desired CPU cores to assign the given thread to. (FMOD_THREAD_AFFINITY)
+
priority Opt
+
Scheduling priority to assign the given thread to. (FMOD_THREAD_PRIORITY)
+
stacksize Opt
+
Amount of stack space available to the given thread. (FMOD_THREAD_STACK_SIZE)
+
+

You must call this function for the chosen thread before that thread is created for the settings to take effect.

+

Affinity can be specified using one (or more) of the FMOD_THREAD_AFFINITY constants or by providing the bits explicitly, i.e. (1<<3) for logical core three (core affinity is zero based).
+See platform documentation for details on the available cores for a given device.

+

Priority can be specified using one of the FMOD_THREAD_PRIORITY constants or by providing the value explicitly, i.e. (-2) for the lowest thread priority on Windows.
+See platform documentation for details on the available priority values for a given operating system.

+

Stack size can be specified explicitly, however for each thread you should provide a size equal to or larger than the expected default or risk causing a stack overflow at runtime.

+

FMOD_THREAD_STACK_SIZE

+

Stack space available to the given thread.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
#define FMOD_THREAD_STACK_SIZE_DEFAULT              0
+#define FMOD_THREAD_STACK_SIZE_MIXER                (80  * 1024)
+#define FMOD_THREAD_STACK_SIZE_FEEDER               (16  * 1024)
+#define FMOD_THREAD_STACK_SIZE_STREAM               (96  * 1024)
+#define FMOD_THREAD_STACK_SIZE_FILE                 (64  * 1024)
+#define FMOD_THREAD_STACK_SIZE_NONBLOCKING          (112 * 1024)
+#define FMOD_THREAD_STACK_SIZE_RECORD               (16  * 1024)
+#define FMOD_THREAD_STACK_SIZE_GEOMETRY             (48  * 1024)
+#define FMOD_THREAD_STACK_SIZE_PROFILER             (128 * 1024)
+#define FMOD_THREAD_STACK_SIZE_STUDIO_UPDATE        (96  * 1024)
+#define FMOD_THREAD_STACK_SIZE_STUDIO_LOAD_BANK     (96  * 1024)
+#define FMOD_THREAD_STACK_SIZE_STUDIO_LOAD_SAMPLE   (96  * 1024)
+
+ +
enum THREAD_STACK_SIZE : uint
+{
+  DEFAULT             = 0,
+  MIXER               = 80  * 1024,
+  FEEDER              = 16  * 1024,
+  STREAM              = 96  * 1024,
+  FILE                = 64  * 1024,
+  NONBLOCKING         = 112 * 1024,
+  RECORD              = 16  * 1024,
+  GEOMETRY            = 48  * 1024,
+  PROFILER            = 128 * 1024,
+  STUDIO_UPDATE       = 96  * 1024,
+  STUDIO_LOAD_BANK    = 96  * 1024,
+  STUDIO_LOAD_SAMPLE  = 96  * 1024
+}
+
+ +
+

Not supported for JavaScript.

+
+
+
FMOD_THREAD_STACK_SIZE_DEFAULT
+
For a given thread use the default listed below, i.e. FMOD_THREAD_TYPE_MIXER uses FMOD_THREAD_STACK_SIZE_MIXER.
+
FMOD_THREAD_STACK_SIZE_MIXER
+
Default stack size for FMOD_THREAD_TYPE_MIXER.
+
FMOD_THREAD_STACK_SIZE_FEEDER
+
Default stack size for FMOD_THREAD_TYPE_FEEDER.
+
FMOD_THREAD_STACK_SIZE_STREAM
+
Default stack size for FMOD_THREAD_TYPE_STREAM.
+
FMOD_THREAD_STACK_SIZE_FILE
+
Default stack size for FMOD_THREAD_TYPE_FILE.
+
FMOD_THREAD_STACK_SIZE_NONBLOCKING
+
Default stack size for FMOD_THREAD_TYPE_NONBLOCKING.
+
FMOD_THREAD_STACK_SIZE_RECORD
+
Default stack size for FMOD_THREAD_TYPE_RECORD.
+
FMOD_THREAD_STACK_SIZE_GEOMETRY
+
Default stack size for FMOD_THREAD_TYPE_GEOMETRY.
+
FMOD_THREAD_STACK_SIZE_PROFILER
+
Default stack size for FMOD_THREAD_TYPE_PROFILER.
+
FMOD_THREAD_STACK_SIZE_STUDIO_UPDATE
+
Default stack size for FMOD_THREAD_TYPE_STUDIO_UPDATE.
+
FMOD_THREAD_STACK_SIZE_STUDIO_LOAD_BANK
+
Default stack size for FMOD_THREAD_TYPE_STUDIO_LOAD_BANK.
+
FMOD_THREAD_STACK_SIZE_STUDIO_LOAD_SAMPLE
+
Default stack size for FMOD_THREAD_TYPE_STUDIO_LOAD_SAMPLE.
+
FMOD_THREAD_STACK_SIZE_CONVOLUTION1
+
Default stack size for FMOD_THREAD_TYPE_CONVOLUTION1.
+
FMOD_THREAD_STACK_SIZE_CONVOLUTION2
+
Default stack size for FMOD_THREAD_TYPE_CONVOLUTION2.
+
+

Stack size can be specified explicitly, however for each thread you should provide a size equal to or larger than the expected default or risk causing a stack overflow at runtime.

+

See Also: Thread_SetAttributes

+

FMOD_THREAD_TYPE

+

Named constants for threads created at runtime.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
typedef enum FMOD_THREAD_TYPE {
+  FMOD_THREAD_TYPE_MIXER,
+  FMOD_THREAD_TYPE_FEEDER,
+  FMOD_THREAD_TYPE_STREAM,
+  FMOD_THREAD_TYPE_FILE,
+  FMOD_THREAD_TYPE_NONBLOCKING,
+  FMOD_THREAD_TYPE_RECORD,
+  FMOD_THREAD_TYPE_GEOMETRY,
+  FMOD_THREAD_TYPE_PROFILER,
+  FMOD_THREAD_TYPE_STUDIO_UPDATE,
+  FMOD_THREAD_TYPE_STUDIO_LOAD_BANK,
+  FMOD_THREAD_TYPE_STUDIO_LOAD_SAMPLE,
+  FMOD_THREAD_TYPE_CONVOLUTION1,
+  FMOD_THREAD_TYPE_CONVOLUTION2,
+  FMOD_THREAD_TYPE_MAX
+} FMOD_THREAD_TYPE;
+
+ +
enum THREAD_TYPE : int
+{
+  MIXER,
+  FEEDER,
+  STREAM,
+  FILE,
+  NONBLOCKING,
+  RECORD,
+  GEOMETRY,
+  PROFILER,
+  STUDIO_UPDATE,
+  STUDIO_LOAD_BANK,
+  STUDIO_LOAD_SAMPLE,
+  CONVOLUTION1,
+  CONVOLUTION2,
+  MAX
+}
+
+ +
+

Not supported for JavaScript.

+
+
+
FMOD_THREAD_TYPE_MIXER
+
Thread responsible for mixing and processing blocks of audio.
+
FMOD_THREAD_TYPE_FEEDER
+
Thread used by some output plug-ins for transferring buffered audio from FMOD_THREAD_TYPE_MIXER to the sound output device.
+
FMOD_THREAD_TYPE_STREAM
+
Thread that decodes compressed audio to PCM for Sounds created as FMOD_CREATESTREAM.
+
FMOD_THREAD_TYPE_FILE
+
Thread that reads compressed audio from disk to be consumed by FMOD_THREAD_TYPE_STREAM.
+
FMOD_THREAD_TYPE_NONBLOCKING
+
Thread that processes the creation of Sounds asynchronously when opened with FMOD_NONBLOCKING.
+
FMOD_THREAD_TYPE_RECORD
+
Thread used by some output plug-ins for transferring audio from a microphone to FMOD_THREAD_TYPE_MIXER.
+
FMOD_THREAD_TYPE_GEOMETRY
+
Thread used by the Geometry system for performing background calculations.
+
FMOD_THREAD_TYPE_PROFILER
+
Thread for network communication when using FMOD_INIT_PROFILE_ENABLE.
+
FMOD_THREAD_TYPE_STUDIO_UPDATE
+
Thread for processing Studio API commands and scheduling sound playback.
+
FMOD_THREAD_TYPE_STUDIO_LOAD_BANK
+
Thread for asynchronously loading Studio::Bank metadata.
+
FMOD_THREAD_TYPE_STUDIO_LOAD_SAMPLE
+
Thread for asynchronously loading Studio::Bank sample data.
+
FMOD_THREAD_TYPE_CONVOLUTION1
+
Thread for processing medium size delay lines for FMOD_DSP_TYPE_CONVOLUTIONREVERB.
+
FMOD_THREAD_TYPE_CONVOLUTION2
+
Thread for processing larger size delay lines for FMOD_DSP_TYPE_CONVOLUTIONREVERB.
+
FMOD_THREAD_TYPE_MAX
+
Maximum number of thread types supported.
+
+

See Also: Thread_SetAttributes

+

FMOD_TIMEUNIT

+

Time types used for position or length.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
#define FMOD_TIMEUNIT_MS            0x00000001
+#define FMOD_TIMEUNIT_PCM           0x00000002
+#define FMOD_TIMEUNIT_PCMBYTES      0x00000004
+#define FMOD_TIMEUNIT_RAWBYTES      0x00000008
+#define FMOD_TIMEUNIT_PCMFRACTION   0x00000010
+#define FMOD_TIMEUNIT_MODORDER      0x00000100
+#define FMOD_TIMEUNIT_MODROW        0x00000200
+#define FMOD_TIMEUNIT_MODPATTERN    0x00000400
+
+ +
[Flags]
+enum TIMEUNIT : uint
+{
+  MS          = 0x00000001,
+  PCM         = 0x00000002,
+  PCMBYTES    = 0x00000004,
+  RAWBYTES    = 0x00000008,
+  PCMFRACTION = 0x00000010,
+  MODORDER    = 0x00000100,
+  MODROW      = 0x00000200,
+  MODPATTERN  = 0x00000400,
+}
+
+ +
TIMEUNIT_MS            = 0x00000001
+TIMEUNIT_PCM           = 0x00000002
+TIMEUNIT_PCMBYTES      = 0x00000004
+TIMEUNIT_RAWBYTES      = 0x00000008
+TIMEUNIT_PCMFRACTION   = 0x00000010
+TIMEUNIT_MODORDER      = 0x00000100
+TIMEUNIT_MODROW        = 0x00000200
+TIMEUNIT_MODPATTERN    = 0x00000400
+
+ +
+
FMOD_TIMEUNIT_MS
+
Milliseconds.
+
FMOD_TIMEUNIT_PCM
+
PCM samples, related to milliseconds * samplerate / 1000.
+
FMOD_TIMEUNIT_PCMBYTES
+
Bytes, related to PCM samples * channels * datawidth (ie 16bit = 2 bytes).
+
FMOD_TIMEUNIT_RAWBYTES
+
Raw file bytes of (compressed) sound data (does not include headers). Only used by Sound::getLength and Channel::getPosition.
+
FMOD_TIMEUNIT_PCMFRACTION
+
Fractions of 1 PCM sample. Unsigned int range 0 to 0xFFFFFFFF. Used for sub-sample granularity for DSP purposes.
+
FMOD_TIMEUNIT_MODORDER
+
MOD/S3M/XM/IT. Order in a sequenced module format. Use Sound::getFormat to determine the PCM format being decoded to.
+
FMOD_TIMEUNIT_MODROW
+
MOD/S3M/XM/IT. Current row in a sequenced module format. Cannot use with Channel::setPosition. Sound::getLength will return the number of rows in the currently playing or seeked to pattern.
+
FMOD_TIMEUNIT_MODPATTERN
+
MOD/S3M/XM/IT. Current pattern in a sequenced module format. Cannot use with Channel::setPosition. Sound::getLength will return the number of patterns in the song and Channel::getPosition will return the currently playing pattern.
+
+

See Also: Sound::getLength, Channel::setPosition, Channel::getPosition

+

FMOD_VECTOR

+

Structure describing a point in 3D space.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
typedef struct FMOD_VECTOR {
+  float   x;
+  float   y;
+  float   z;
+} FMOD_VECTOR;
+
+ +
struct VECTOR
+{
+  float x;
+  float y;
+  float z;
+}
+
+ +
FMOD_VECTOR
+{
+  x,
+  y,
+  z,
+};
+
+ +
+
x
+
X coordinate in 3D space.
+
y
+
Y coordinate in 3D space.
+
z
+
Z coordinate in 3D space.
+
+

FMOD uses a left handed coordinate system by default.

+

To use a right handed coordinate system specify FMOD_INIT_3D_RIGHTHANDED from FMOD_INITFLAGS in System::init.

+

See Also: System::set3DListenerAttributes, ChannelControl::set3DAttributes

+

FMOD_VERSION

+

Current FMOD version number.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
#define FMOD_VERSION ...
+
+ +
class VERSION
+{
+  const int number = ...;
+}
+
+ +
+

Not supported for JavaScript.

+
+
+
FMOD_VERSION
+
Current FMOD version number.
+
+

The version is a 32 bit hexadecimal value formatted as 16:8:8, with the upper 16 bits being the product version, the middle 8 bits being the major version and the bottom 8 bits being the minor version. For example a value of 0x00010203 is equal to 1.02.03.

+

See Also: Studio::System::create, System::getVersion

+ + +
+ + + diff --git a/FMOD/doc/FMOD API User Manual/core-api-concepts.html b/FMOD/doc/FMOD API User Manual/core-api-concepts.html new file mode 100644 index 0000000..0f1fb20 --- /dev/null +++ b/FMOD/doc/FMOD API User Manual/core-api-concepts.html @@ -0,0 +1,116 @@ + + +Core API Key Concepts + + + + +
+ +
+

2. Core API Key Concepts

+

The Core API is a programmer API that allows the manipulation of low-level audio primitives, and is the backbone of the FMOD Engine.

+

While the Studio API is easy to use and well-suited to most game projects, the Core API is both more powerful and more flexible. This makes it useful for games with unusual and strict audio requirements that do not perfectly fit into the Studio API's paradigm of events and buses. In addition, even games made using the Studio API can benefit from a solid knowledge of the Core API, as the Core API is the foundation upon which the Studio API is built.

+

This chapter introduces several essential FMOD Core API concepts. Understanding these concepts and how they interact is key to understanding how best to use the Core API to develop adaptive game audio.

+

This chapter is designed to be read before proceeding on to the rest of this manual, as the concepts introduced here come up frequently in later chapters.

+

2.1 The Core API and the FMOD Engine

+

The FMOD Engine is a runtime library for playing adaptive audio in games. It consists of two APIs: FMOD Studio API, and the FMOD Core API.

+

The FMOD Core API allows audio programmers to create audio content without using FMOD Studio, and to interact with the FMOD Engine's underlying mechanisms. This makes it more powerful and flexible than the FMOD Studio API.

+

The FMOD Studio API can load and play .bank files created in FMOD Studio, an application that allows sound designers and composers to create adaptive audio content for games. This makes it less flexible than the FMOD Core API, but easier to use, especially for sound designers with limited audio programming experience and audio programmers with limited experience of sound design.

+

FMOD for Unity and FMOD for Unreal Engine are packaged software integrations of the FMOD Engine for use in Unity and Unreal Engine games. Each package includes a copy of the FMOD Engine that is automatically installed along with the integration.

+

FMOD version numbers are split into three parts, in the format: productVersion.majorVersion.minorVersion.

+

2.2 The System Object

+

The FMOD system object is the heart of the FMOD Engine, the key mechanism that all other Core API features depend on to work. This means that before your game can do anything else with the Core API, the system object needs to be created. Outside of exceptional circumstances, you only ever need one FMOD system object to handle all the audio in your game. Most games therefore create a system object when the game is launched, and then only destroy that system object when the player quits the game.

+

For information about getting your game ready to play audio with the FMOD Core API, see the Running the Core API chapter. For more information about the system object, see System subchapter of the Core API Reference chapter.

+

2.3 Sounds

+

A sound is a piece of sample data that's loaded or buffered into memory, ready to be played. Sounds are created using System::createStream or System::createSound, which also lets you choose the loading mode to be used for that sound.

+

Once a sound is loaded, you can play it with System::playSound. This creates a channel that plays the sound's sample data.

+

For more information about loading and playing sounds, see the Loading and Playing Sounds in the Core API chapter. For reference information about sounds, see the Sound subchapter of the Core API Reference chapter.

+

2.4 Channels

+

A channel can be thought of as a single "voice" in your game's mix. Each channel is the source of an audio signal, which it routes into the DSP graph to be mixed.

+

Provided the sound isn't a stream, you can play multiple channels based on the same sound contemporaneously, without needing to create multiple instances of that sound. Calling System::playSound again while one or more channels based on that sound is already playing creates and plays a new channel based on that sound, without stopping the already-playing channels. This allows you to save resources by only keeping one copy of a sound in memory, no matter how many instances of that sound you need to play.

+

If a sound is a stream (which is to say, if it was created by with System::createStream or by calling System::createSound with FMOD_CREATESTREAM), calling System::playSound while a channel based on that sound is already playing instead causes it to restart. If you want to play multiple instances of a streaming sound's sample data, you can do so by creating multiple sounds based on the same sample data, and playing each one separately.

+

For more information about channels, see the Channel subchapter of the Core API Reference chapter.

+

2.4.1 Channel Virtualization

+

Channels don't necessarily consume resources while they're playing. If a channel falls silent, or if it's the quietest channel when there are too many channels playing, it can be "virtualized." Virtualized channels are abstracted away so that they don't consume resources; if they subsequently become loud enough that they should be audible, or if the number of playing channels drops back down below the limit, they stop being virtual and resume playing as if they had never stopped. Because channels are only virtualized if they're silent or quieter than all other non-virtual channels, this normally has no apparent effect on how the game sounds, but helps save a lot of resources.

+

For more information about virtualization, see the Virtual Voice System section of the Managing Resources in the Core API chapter.

+

2.5 Channel Groups

+

A channel group functions as a container for channels and other channel groups. Each channel group creates a submix of the signals output by the channels and channel groups it contains. This means that you can treat channel groups like buses, routing other channels and channel groups into them in order to better control your mix, and putting DSPs on them to process and modify their submixes.

+

While it is possible to put DSPs onto channels, it's usually more resource-efficient to put them onto channel groups, as doing so allows a single DSP unit to process the submixed output of multiple channels.

+

For more information about channel groups, see the ChannelGroup section of the Core API Reference chapter.

+

2.6 DSP Units

+

A DSP (or Digital Signal Processor) unit takes PCM audio input and transforms it to create PCM audio output. DSPs are sometimes called effects.

+

Commonly-used DSPs include the panner, which is used to spatialize and pan signals, and the fader, which is used to adjust volume.

+

DSPs are usually applied to channel groups in order to modify their submixes in various ways, though they can also be applied to channels. Multiple DSPs can be applied to the same channel group or channel.

+

For more information about using DSPs, see the Using DSP Effects in the Core API chapter. For more information about specific DSPs, see the Effects Reference chapter.

+

2.7 FMOD Sound Banks

+

While the FMOD Core API can play loose audio files in a variety of formats, it can also load and play .fsb files. .fsb files, also known as FMOD sound banks, are a container format optimized for loading and playing sounds in games. You can create FSB files for your game by using the fsbank.exe and fsbankcl.exe applications that comes included with the FMOD Engine.

+

.fsb files provide a number of benefits over other audio file formats, including:

+
    +
  • No-seek loading. FSB loading supports three continuous file reads: A main header read, a sub-sound metadata read, and a raw audio data read.
  • +
  • Memory points. An FSB can be loaded into memory and simply 'pointed to' so that FMOD uses the memory where it is, and does not allocate any extra memory. See FMOD_OPENMEMORY_POINT.
  • +
  • Low memory overhead. A lot of file formats contain fluff such as tags and metadata. FSB stores information in compressed, bit packed formats with minimal overhead for optimum efficiency.
  • +
  • Multiple sounds in one file. Thousands of sounds can be stored inside one .fsb file, and selected by the API function Sound::getSubSound. Because a single .fsb file can include the sample data used by multiple different sounds, .fsb files can also function as loading units for your game's sample data. As loading an .fsb file that contains the sample data for multiple different sounds requires involves less overhead than loading the sample data for all of those sounds individually, this saves resources in any situation where multiple different sounds' sample data would need to be loaded at the same time.
  • +
  • Efficient Ogg Vorbis. FSB strips out the 'Ogg' and keeps the 'Vorbis'. This means that one codebook can be shared between all sounds, saving megabytes of memory compared to loading .ogg files individually.
  • +
  • FADPCM codec support. The FMOD Engine supports a very efficient ADPCM variant called FADPCM. This variant is many times faster than a standard ADPCM decoder as it does not require branching, and is therefore very efficient on mobile devices. The quality is also far superior than most ADPCM variants, and lacks the 'hiss' notable in those formats.
  • +
+

For more information about FMOD sound banks, see the Supported File Formats section of the Loading and Playing Sounds in the Core API chapter.

+

2.8 3D Sounds and Channels

+

A 3D channel or 3D channel group is created with the FMOD_3D flag. This flag allows a channel or channel group to have a defined position, orientation, and velocity in 3D space, set by ChannelControl::set3DAttributes. These 3D attributes can be used by DSPs on that channel or channel group, allowing them to process the signal of that channel or channel group in different ways depending on the 3D attributes' values. The most common reason for making a channel or channel group 3D is to spatialize it with a panner effect, panning and attenuating the signal to make it seem to come from a specific direction and distance.

+

Sounds can be set to 2D or 3D as well, by specifying the FMOD_3D flag when creating them with System::createSound. In most cases, this isn't strictly necessary - you can make any channel 2D or 3D, regardless of which of those the sound is - but setting a sound to be 2D or 3D makes that the default for all channels based on that sound.

+

2.9 Streams

+

Streaming is a way of playing sound without having to load the entire audio asset to be played into memory first. Instead, the sample data is loaded piecemeal into a ring buffer. Each piece of the sample data is loaded into the buffer shortly before it is played and overwritten again as soon as it has finished playing, ensuring that only a tiny amount of the stream's sample data is stored in memory at any given time.

+

The FMOD Engine supports streaming from file, memory, user callbacks, and http/shoutcast/icecast sources.

+

Streaming sounds are created using System::createStream or by adding the FMOD_CREATESTREAM flag to System::createSound. Each streaming sound plays exactly one instance of its associated sample data. To play multiple instances of the same piece of sample data as streams, you must open and play a stream multiple times. Each such opened stream is its own sound.

+

Streaming sounds are mostly used for music and dialogue, though they may be used for other sounds as well.

+

2.10 Audio Devices

+

An audio device is any piece of hardware that accepts an audio signal and behaves differently according to the signal it receives.

+

Most audio devices are designed to produce sound: Speakers, headphones, controller speakers, VoIP headsets, and so on. Some audio devices instead use the audio signals they receive for other purposes. For example, the vibrators in some controllers accept audio data and modulate the intensity and frequency of their vibration based on the data they receive.

+

The Core API is capable of outputting audio signals to audio devices.

+ + +
+ + + diff --git a/FMOD/doc/FMOD API User Manual/core-api-dsp.html b/FMOD/doc/FMOD API User Manual/core-api-dsp.html new file mode 100644 index 0000000..76e39c5 --- /dev/null +++ b/FMOD/doc/FMOD API User Manual/core-api-dsp.html @@ -0,0 +1,2285 @@ + + +Core API Reference | DSP + + + + +
+ +
+

11. Core API Reference | DSP

+

A digital signal processor is one node within a graph that transforms input audio signals into an output stream.

+

Create with System::createDSP, System::createDSPByType or System::createDSPByPlugin.

+

Connections:

+ +

Parameters:

+ +

Channel format:

+ +

Metering:

+ +

Processing:

+ +

General:

+ +
+ +

DSP::addInput

+

Adds a DSP unit as an input to this object.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
FMOD_RESULT DSP::addInput(
+  DSP *input,
+  DSPConnection **connection = nullptr,
+  FMOD_DSPCONNECTION_TYPE type = FMOD_DSPCONNECTION_TYPE_STANDARD
+);
+
+ +
FMOD_RESULT FMOD_DSP_AddInput(
+  FMOD_DSP *dsp,
+  FMOD_DSP *input,
+  FMOD_DSPCONNECTION **connection,
+  FMOD_DSPCONNECTION_TYPE type
+);
+
+ +
RESULT DSP.addInput(
+  DSP input
+);
+RESULT DSP.addInput(
+  DSP input,
+  out DSPConnection connection,
+  DSPCONNECTION_TYPE type = DSPCONNECTION_TYPE.STANDARD
+);
+
+ +
DSP.addInput(
+  input,
+  connection,
+  type
+);
+
+ +
+
input
+
DSP unit to be added. (DSP)
+
connection OutOpt
+
Connection between the two units. (DSPConnection)
+
type
+
+

Type of connection between the two units. (FMOD_DSPCONNECTION_TYPE)

+ +
+
+

When a DSP has multiple inputs the signals are automatically mixed together, sent to the unit's output(s).

+

The returned connection will remain valid until the units are disconnected.

+

When type is FMOD_DSPCONNECTION_TYPE_PREALLOCATED (or when calling DSP::addInputPreallocated in C#), you should use the connection parameter to provide a valid DSPConnection handle that was created by System::createDSPConnection. In this case, the input will be connected using the provided connection rather than a newly allocated one.

+

See Also: DSP::getInput, DSP::getNumInputs, DSP::getOutput, DSP::getNumOutputs

+

DSP::addInputPreallocated

+

Adds a preallocated DSP unit as an input to this object.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
FMOD_RESULT DSP::addInputPreallocated(
+  DSP *input,
+  DSPConnection **connection = nullptr
+);
+
+ +
FMOD_RESULT FMOD_DSP_AddInputPreallocated(
+  FMOD_DSP *dsp,
+  FMOD_DSP *input,
+  FMOD_DSPCONNECTION **connection
+);
+
+ +
RESULT DSP.addInputPreallocated(
+  DSP input,
+  DSPConnection connection = null
+);
+
+ +
+

Currently not supported for javascript.

+
+
+
input
+
DSP unit to be added. (DSP)
+
connection OutOpt
+
Connection between the two units. (DSPConnection)
+
+

When a DSP has multiple inputs the signals are automatically mixed together, sent to the unit's output(s).

+

The returned connection will remain valid until the units are disconnected.

+

You should use the connection parameter to provide a valid DSPConnection handle that was created by System::createDSPConnection. In this case, the input will be connected using the provided connection rather than a newly allocated one.

+

See Also: DSP::getInput, DSP::getNumInputs, DSP::getOutput, DSP::getNumOutputs, DSP::addInput

+

FMOD_DSP_CALLBACK

+

Callback for DSP notifications.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
FMOD_RESULT F_CALL FMOD_DSP_CALLBACK(
+  FMOD_DSP *dsp,
+  FMOD_DSP_CALLBACK_TYPE type,
+  void *data
+);
+
+ +
delegate RESULT DSP_CALLBACK(
+  IntPtr dsp,
+  DSP_CALLBACK_TYPE type,
+  IntPtr data
+);
+
+ +
function FMOD_DSP_CALLBACK(
+  dsp,
+  type,
+  data
+)
+
+ +
+
dsp
+
DSP handle. (DSP)
+
type
+
Type of callback. (FMOD_DSP_CALLBACK_TYPE)
+
data Opt
+
Callback data; see FMOD_DSP_CALLBACK_TYPE for details.
+
+
+

The 'dsp' argument can be cast to FMOD::DSP *.

+
+
+

You can convert the 'dsp' argument to an FMOD.DSP object by using FMOD.DSP dspobject = new FMOD.DSP(dsp);

+
+

See Also: Callback Behavior, DSP::setCallback

+

FMOD_DSP_CALLBACK_TYPE

+

Types of callback called by a DSP.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
typedef enum FMOD_DSP_CALLBACK_TYPE {
+  FMOD_DSP_CALLBACK_DATAPARAMETERRELEASE,
+  FMOD_DSP_CALLBACK_MAX
+} FMOD_DSP_CALLBACK_TYPE;
+
+ +
enum DSP_CALLBACK_TYPE : int
+{
+  DATAPARAMETERRELEASE,
+  MAX,
+}
+
+ +
DSP_CALLBACK_DATAPARAMETERRELEASE
+DSP_CALLBACK_MAX
+
+ +
+
FMOD_DSP_CALLBACK_DATAPARAMETERRELEASE
+
Called when a DSP's data parameter can be released.
+data: FMOD_DSP_DATA_PARAMETER_INFO.
+
+

Callbacks are called from the game thread when set from the Core API or Studio API in synchronous mode, and from the Studio Update Thread when in default / async mode.

+

See Also: Callback Behavior, DSP::setCallback

+

FMOD_DSP_DATA_PARAMETER_INFO

+

Describes the value of a DSP's data parameter.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
typedef struct FMOD_DSP_DATA_PARAMETER_INFO {
+  void          *data;
+  unsigned int  length;
+  int           index;
+} FMOD_DSP_DATA_PARAMETER_INFO;
+
+ +
struct DSP_DATA_PARAMETER_INFO
+{
+    IntPtr          data;
+    uint            length;
+    int             index;
+}
+
+ +
FMOD_DSP_DATA_PARAMETER_INFO
+{
+  data,
+  length,
+  index,
+};
+
+ +
+
data
+
Pointer to the data buffer.
+
length
+
Length of the data buffer in bytes. (unsigned int)
+
index
+
Index of the DSP parameter. (int)
+
+

This data is passed to the DSP callback function when type is FMOD_DSP_CALLBACK_DATAPARAMETERRELEASE. The callback should free the data pointer if it is no longer required.

+

See Also: FMOD_DSP_CALLBACK

+

DSP::disconnectAll

+

Disconnects all inputs and/or outputs.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
FMOD_RESULT DSP::disconnectAll(
+  bool inputs,
+  bool outputs
+);
+
+ +
FMOD_RESULT FMOD_DSP_DisconnectAll(
+  FMOD_DSP *dsp,
+  FMOD_BOOL inputs,
+  FMOD_BOOL outputs
+);
+
+ +
RESULT DSP.disconnectAll(
+  bool inputs,
+  bool outputs
+);
+
+ +
DSP.disconnectAll(
+  inputs,
+  outputs
+);
+
+ +
+
inputs
+
+

Whether all inputs should be disconnected.

+
    +
  • Units: Boolean
  • +
+
+
outputs
+
+

Whether all outputs should be disconnected.

+
    +
  • Units: Boolean
  • +
+
+
+

This is a convenience function that is faster than disconnecting all inputs and outputs individually.

+

See Also: DSP::disconnectFrom

+

DSP::disconnectFrom

+

Disconnect the specified input DSP.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
FMOD_RESULT DSP::disconnectFrom(
+  DSP *target,
+  DSPConnection *connection = nullptr
+);
+
+ +
FMOD_RESULT FMOD_DSP_DisconnectFrom(
+  FMOD_DSP *dsp,
+  FMOD_DSP *target,
+  FMOD_DSPCONNECTION *connection
+);
+
+ +
RESULT DSP.disconnectFrom(
+  DSP target,
+  DSPConnection connection = null
+);
+
+ +
DSP.disconnectFrom(
+  target,
+  connection
+);
+
+ +
+
target Opt
+
Input DSP unit to disconnect. If an input DSP unit is not specified, all inputs and outputs are disconnected from this unit. (DSP)
+
connection Opt
+
When there is more than one connection between two units this can be used to define which of the connections should be disconnected. (DSPConnection)
+
+

If target had only one output, after this operation that entire sub graph will no longer be connected to the DSP graph.

+

After this operation connection is no longer valid.

+

See Also: DSP::addInput, DSP::disconnectAll

+

DSP::getActive

+

Retrieves the processing active state.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
FMOD_RESULT DSP::getActive(
+  bool *active
+);
+
+ +
FMOD_RESULT FMOD_DSP_GetActive(
+  FMOD_DSP *dsp,
+  FMOD_BOOL *active
+);
+
+ +
RESULT DSP.getActive(
+  out bool active
+);
+
+ +
DSP.getActive(
+  active
+);
+
+ +
+
active Out
+
+

Active state.

+
    +
  • Units: Boolean
  • +
  • Default: False
  • +
+
+
+

If active is False, processing of this unit and its inputs are stopped.

+

A DSP is inactive when first created. It is automatically activated when ChannelControl::addDSP is used; otherwise, it must be set to active manually.

+

See Also: DSP::setActive, DSP::setBypass

+

DSP::getBypass

+

Retrieves the processing bypass state.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
FMOD_RESULT DSP::getBypass(
+  bool *bypass
+);
+
+ +
FMOD_RESULT FMOD_DSP_GetBypass(
+  FMOD_DSP *dsp,
+  FMOD_BOOL *bypass
+);
+
+ +
RESULT DSP.getBypass(
+  out bool bypass
+);
+
+ +
DSP.getBypass(
+  bypass
+);
+
+ +
+
bypass Out
+
+

Bypass state.

+
    +
  • Units: Boolean
  • +
  • Default: False
  • +
+
+
+

If bypass is true, processing of this unit is skipped but it continues to process its inputs.

+

See Also: DSP::setBypass, DSP::setActive

+

DSP::getChannelFormat

+

Retrieves the PCM input format this DSP will receive when processing.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
FMOD_RESULT DSP::getChannelFormat(
+  FMOD_CHANNELMASK *channelmask,
+  int *numchannels,
+  FMOD_SPEAKERMODE *source_speakermode
+);
+
+ +
FMOD_RESULT FMOD_DSP_GetChannelFormat(
+  FMOD_DSP *dsp,
+  FMOD_CHANNELMASK *channelmask,
+  int *numchannels,
+  FMOD_SPEAKERMODE *source_speakermode
+);
+
+ +
RESULT DSP.getChannelFormat(
+  out CHANNELMASK channelmask,
+  out int numchannels,
+  out SPEAKERMODE source_speakermode
+);
+
+ +
DSP.getChannelFormat(
+  channelmask,
+  numchannels,
+  source_speakermode
+);
+
+ +
+
channelmask OutOpt
+
Deprecated. (FMOD_CHANNELMASK)
+
numchannels OutOpt
+
Number of channels to be processed.
+
source_speakermode OutOpt
+
Speaker mode to describe the channel mapping. (FMOD_SPEAKERMODE)
+
+

See Also: DSP::setChannelFormat

+

DSP::getCPUUsage

+

Retrieves statistics on the mixer thread CPU usage for this unit.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
FMOD_RESULT DSP::getCPUUsage(
+  unsigned int *exclusive,
+  unsigned int *inclusive
+);
+
+ +
FMOD_RESULT FMOD_DSP_GetCPUUsage(
+  FMOD_DSP *dsp,
+  unsigned int *exclusive,
+  unsigned int *inclusive
+);
+
+ +
RESULT DSP.getCPUUsage(
+  out uint exclusive,
+  out uint inclusive
+);
+
+ +
DSP.getCPUUsage(
+  exclusive,
+  inclusive
+);
+
+ +
+
exclusive OutOpt
+
+

CPU time spent processing just this unit during the last mixer update.

+
    +
  • Units: Microseconds
  • +
+
+
inclusive OutOpt
+
+

CPU time spent processing this unit and all of its input during the last mixer update.

+
    +
  • Units: Microseconds
  • +
+
+
+

FMOD_INIT_PROFILE_ENABLE with System::init is required to call this function.

+

DSP::getDataParameterIndex

+

Retrieve the index of the first data parameter of a particular data type.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
FMOD_RESULT DSP::getDataParameterIndex(
+  int datatype,
+  int *index
+);
+
+ +
FMOD_RESULT FMOD_DSP_GetDataParameterIndex(
+  FMOD_DSP *dsp,
+  int datatype,
+  int *index
+);
+
+ +
RESULT DSP.getDataParameterIndex(
+  int datatype,
+  out int index
+);
+
+ +
DSP.getDataParameterIndex(
+  datatype,
+  index
+);
+
+ +
+
datatype
+
The type of data to find. Typically of type FMOD_DSP_PARAMETER_DATA_TYPE.
+
index OutOpt
+
Contains the index of the first data parameter of type datatype after the function is called. Will be -1 if no matches were found.
+
+

This function returns FMOD_OK if a parameter of matching type is found and FMOD_ERR_INVALID_PARAM if no matches were found.

+

The return code can be used to check whether the DSP supports specific functionality through data parameters of certain types without the need to provide index.

+

DSP::getIdle

+

Retrieves the idle state.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
FMOD_RESULT DSP::getIdle(
+  bool *idle
+);
+
+ +
FMOD_RESULT FMOD_DSP_GetIdle(
+  FMOD_DSP *dsp,
+  FMOD_BOOL *idle
+);
+
+ +
RESULT DSP.getIdle(
+  out bool idle
+);
+
+ +
DSP.getIdle(
+  idle
+);
+
+ +
+
idle Out
+
+

Idle state.

+
    +
  • Units: Boolean
  • +
+
+
+

A DSP is considered idle when it stops receiving input signals and all internal processing of stored input has been exhausted.

+

Different DSP types can have different idle behavior. A reverb or echo DSP may take longer to go idle after it stops receiving a valid signal than a DSP with a shorter tail length, such as an EQ filter.

+

DSP::getInfo

+

Retrieves information about this DSP unit.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
FMOD_RESULT DSP::getInfo(
+  char *name,
+  unsigned int *version,
+  int *channels,
+  int *configwidth,
+  int *configheight
+);
+
+ +
FMOD_RESULT FMOD_DSP_GetInfo(
+  FMOD_DSP *dsp,
+  char *name,
+  unsigned int *version,
+  int *channels,
+  int *configwidth,
+  int *configheight
+);
+
+ +
RESULT DSP.getInfo(
+  out string name,
+  out uint version,
+  out int channels,
+  out int configwidth,
+  out int configheight
+);
+
+ +
DSP.getInfo(
+  name,
+  version,
+  channels,
+  configwidth,
+  configheight
+);
+
+ +
+
name OutOpt
+
The name of this unit will be written (null terminated) to the provided 32 byte buffer. (UTF-8 string)
+
version OutOpt
+
Version number of this unit, usually formatted as hex AAAABBBB where the AAAA is the major version number and the BBBB is the minor version number.
+
channels OutOpt
+
Number of channels this unit processes where 0 represents "any".
+
configwidth OutOpt
+
Configuration dialog box width where 0 represents "no dialog box".
+
configheight OutOpt
+
Configuration dialog box height where 0 represents "no dialog box".
+
+

See Also: DSP::showConfigDialog

+

DSP::getInput

+

Retrieves the DSP unit at the specified index in the input list.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
FMOD_RESULT DSP::getInput(
+  int index,
+  DSP **input,
+  DSPConnection **inputconnection
+);
+
+ +
FMOD_RESULT FMOD_DSP_GetInput(
+  FMOD_DSP *dsp,
+  int index,
+  FMOD_DSP **input,
+  FMOD_DSPCONNECTION **inputconnection
+);
+
+ +
RESULT DSP.getInput(
+  int index,
+  out DSP input,
+  out DSPConnection inputconnection
+);
+
+ +
DSP.getInput(
+  index,
+  input,
+  inputconnection
+);
+
+ +
+
index
+
+

Offset into this DSP's input list.

+ +
+
input OutOpt
+
DSP unit at the specified index. (DSP)
+
inputconnection OutOpt
+
Connection between this unit and input. (DSPConnection)
+
+

This will flush the DSP queue (which blocks against the mixer) to ensure the input list is correct, avoid this during time sensitive operations.

+

The returned connection will remain valid until the units are disconnected.

+

See Also: DSP::addInput, DSP::getOutput

+

DSP::getMeteringEnabled

+

Retrieves the input and output signal metering enabled states.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
FMOD_RESULT DSP::getMeteringEnabled(
+  bool *inputEnabled,
+  bool *outputEnabled
+);
+
+ +
FMOD_RESULT FMOD_DSP_GetMeteringEnabled(
+  FMOD_DSP *dsp,
+  FMOD_BOOL *inputEnabled,
+  FMOD_BOOL *outputEnabled
+);
+
+ +
RESULT DSP.getMeteringEnabled(
+  out bool inputEnabled,
+  out bool outputEnabled
+);
+
+ +
DSP.getMeteringEnabled(
+  inputEnabled,
+  outputEnabled
+);
+
+ +
+
inputEnabled OutOpt
+
+

Metering enabled state for the input signal.

+
    +
  • Units: Boolean
  • +
  • Default: False
  • +
+
+
outputEnabled OutOpt
+
+

Metering enabled state for the output signal.

+
    +
  • Units: Boolean
  • +
  • Default: False
  • +
+
+
+

Input metering is pre processing, while output metering is post processing.

+

Enabled metering allows DSP::getMeteringInfo to return metering information and allows FMOD profiling tools to visualize the levels.

+

FMOD_INIT_PROFILE_METER_ALL with System::init will automatically turn on metering for all DSP units inside the dsp graph.

+

See Also: DSP::setMeteringEnabled

+

DSP::getMeteringInfo

+

Retrieve the signal metering enabled metering information.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
FMOD_RESULT DSP::getMeteringInfo(
+  FMOD_DSP_METERING_INFO *inputInfo,
+  FMOD_DSP_METERING_INFO *outputInfo
+);
+
+ +
FMOD_RESULT FMOD_DSP_GetMeteringInfo(
+  FMOD_DSP *dsp,
+  FMOD_DSP_METERING_INFO *inputInfo,
+  FMOD_DSP_METERING_INFO *outputInfo
+);
+
+ +
RESULT DSP.getMeteringInfo(
+  IntPtr zero,
+  DSP_METERING_INFO outputInfo
+);
+RESULT DSP.getMeteringInfo(
+  DSP_METERING_INFO inputInfo,
+  IntPtr zero
+);
+RESULT DSP.getMeteringInfo(
+  DSP_METERING_INFO inputInfo,
+  DSP_METERING_INFO outputInfo
+);
+
+ +
DSP.getMeteringInfo(
+  inputInfo,
+  outputInfo
+);
+
+ +
+
inputInfo OutOpt
+
Input metering information before the DSP has processed. (FMOD_DSP_METERING_INFO)
+
outputInfo OutOpt
+
Output metering information after the DSP has processed. (FMOD_DSP_METERING_INFO)
+
+

Requesting metering information when it hasn't been enabled will result in FMOD_ERR_BADCOMMAND.

+

FMOD_INIT_PROFILE_METER_ALL with System::init will automatically enable metering for all DSP units.

+

See Also: DSP::setMeteringEnabled, DSP::getMeteringEnabled

+

DSP::getNumInputs

+

Retrieves the number of DSP units in the input list.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
FMOD_RESULT DSP::getNumInputs(
+  int *numinputs
+);
+
+ +
FMOD_RESULT FMOD_DSP_GetNumInputs(
+  FMOD_DSP *dsp,
+  int *numinputs
+);
+
+ +
RESULT DSP.getNumInputs(
+  out int numinputs
+);
+
+ +
DSP.getNumInputs(
+  numinputs
+);
+
+ +
+
numinputs Out
+
Number of input DSPs.
+
+

This flushes the DSP queue (which blocks against the mixer) to ensure the input list is correct. You should avoid doing this during time-sensitive operations.

+

See Also: DSP::getNumOutputs, DSP::getInput

+

DSP::getNumOutputs

+

Retrieves the number of DSP units in the output list.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
FMOD_RESULT DSP::getNumOutputs(
+  int *numoutputs
+);
+
+ +
FMOD_RESULT FMOD_DSP_GetNumOutputs(
+  FMOD_DSP *dsp,
+  int *numoutputs
+);
+
+ +
RESULT DSP.getNumOutputs(
+  out int numoutputs
+);
+
+ +
DSP.getNumOutputs(
+  numoutputs
+);
+
+ +
+
numoutputs Out
+
Number of output DSPs.
+
+

This flushes the DSP queue (which blocks against the mixer) to ensure the output list is correct. You should avoid doing this during time-sensitive operations.

+

See Also: DSP::getNumInputs, DSP::getOutput

+

DSP::getNumParameters

+

Retrieves the number of parameters exposed by this unit.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
FMOD_RESULT DSP::getNumParameters(
+  int *numparams
+);
+
+ +
FMOD_RESULT FMOD_DSP_GetNumParameters(
+  FMOD_DSP *dsp,
+  int *numparams
+);
+
+ +
RESULT DSP.getNumParameters(
+  out int numparams
+);
+
+ +
DSP.getNumParameters(
+  numparams
+);
+
+ +
+
numparams Out
+
Number of parameters.
+
+

Use this to enumerate all parameters of a DSP unit with DSP::getParameterInfo.

+

See Also: DSP::setParameterFloat, DSP::setParameterInt, DSP::setParameterBool, DSP::setParameterData

+

DSP::getOutput

+

Retrieves the DSP unit at the specified index in the output list.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
FMOD_RESULT DSP::getOutput(
+  int index,
+  DSP **output,
+  DSPConnection **outputconnection
+);
+
+ +
FMOD_RESULT FMOD_DSP_GetOutput(
+  FMOD_DSP *dsp,
+  int index,
+  FMOD_DSP **output,
+  FMOD_DSPCONNECTION **outputconnection
+);
+
+ +
RESULT DSP.getOutput(
+  int index,
+  out DSP output,
+  out DSPConnection outputconnection
+);
+
+ +
DSP.getOutput(
+  index,
+  output,
+  outputconnection
+);
+
+ +
+
index
+
+

Offset into this DSP's output list.

+ +
+
output OutOpt
+
DSP unit at the specified index. (DSP)
+
outputconnection OutOpt
+
Connection between this unit and output. (DSPConnection)
+
+

This flushes the DSP queue (which blocks against the mixer) to ensure the output list is correct. You should avoid doing this during time-sensitive operations.

+

The returned connection will remain valid until the units are disconnected.

+

See Also: DSP::addInput, DSP::getInput

+

DSP::getOutputChannelFormat

+

Retrieves the output format this DSP produces when processing based on the input specified.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
FMOD_RESULT DSP::getOutputChannelFormat(
+  FMOD_CHANNELMASK inmask,
+  int inchannels,
+  FMOD_SPEAKERMODE inspeakermode,
+  FMOD_CHANNELMASK *outmask,
+  int *outchannels,
+  FMOD_SPEAKERMODE *outspeakermode
+);
+
+ +
FMOD_RESULT FMOD_DSP_GetOutputChannelFormat(
+  FMOD_DSP *dsp,
+  FMOD_CHANNELMASK inmask,
+  int inchannels,
+  FMOD_SPEAKERMODE inspeakermode,
+  FMOD_CHANNELMASK *outmask,
+  int *outchannels,
+  FMOD_SPEAKERMODE *outspeakermode
+);
+
+ +
RESULT DSP.getOutputChannelFormat(
+  CHANNELMASK inmask,
+  int inchannels,
+  SPEAKERMODE inspeakermode,
+  out CHANNELMASK outmask,
+  out int outchannels,
+  out SPEAKERMODE outspeakermode
+);
+
+ +
DSP.getOutputChannelFormat(
+  inmask,
+  inchannels,
+  inspeakermode,
+  outmask,
+  outchannels,
+  outspeakermode
+);
+
+ +
+
inmask
+
Deprecated. (FMOD_CHANNELMASK)
+
inchannels
+
Number of channels for the input signal.
+
inspeakermode
+
Speaker mode for the input signal. (FMOD_SPEAKERMODE)
+
outmask OutOpt
+
Deprecated. (FMOD_CHANNELMASK)
+
outchannels OutOpt
+
Number of channels for the output signal.
+
outspeakermode OutOpt
+
Speaker mode for the output signal. (FMOD_SPEAKERMODE)
+
+

See Also: DSP::setChannelFormat, DSP::getChannelFormat

+

DSP::getParameterBool

+

Retrieves a boolean parameter by index.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
FMOD_RESULT DSP::getParameterBool(
+  int index,
+  bool *value,
+  char *valuestr,
+  int valuestrlen
+);
+
+ +
FMOD_RESULT FMOD_DSP_GetParameterBool(
+  FMOD_DSP *dsp,
+  int index,
+  FMOD_BOOL *value,
+  char *valuestr,
+  int valuestrlen
+);
+
+ +
RESULT DSP.getParameterBool(
+  int index,
+  out bool value
+);
+
+ +
DSP.getParameterBool(
+  index,
+  value,
+  valuestr
+);
+
+ +
+
index
+
+

Parameter index.

+ +
+
value OutOpt
+
+

Parameter boolean data.

+
    +
  • Units: Boolean
  • +
+
+
valuestr OutOpt
+
String representation value. (UTF-8 string)
+
valuestrlen
+
+

Length of valuestr.

+ +
+
+

See Also: DSP::setParameterBool, DSP::getParameterInfo

+

DSP::getParameterData

+

Retrieves a binary data parameter by index.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
FMOD_RESULT DSP::getParameterData(
+  int index,
+  void **data,
+  unsigned int *length,
+  char *valuestr,
+  int valuestrlen
+);
+
+ +
FMOD_RESULT FMOD_DSP_GetParameterData(
+  FMOD_DSP *dsp,
+  int index,
+  void **data,
+  unsigned int *length,
+  char *valuestr,
+  int valuestrlen
+);
+
+ +
RESULT DSP.getParameterData(
+  int index,
+  out IntPtr data,
+  out uint length
+);
+
+ +
DSP.getParameterData(
+  index,
+  data,
+  length,
+  valuestr
+);
+
+ +
+
index
+
+

Parameter index.

+ +
+
data OutOpt
+
Parameter binary data.
+
length OutOpt
+
+

Length of data.

+
    +
  • Units: Bytes
  • +
+
+
valuestr OutOpt
+
String representation data. (UTF-8 string)
+
valuestrlen
+
+

Length of valuestr.

+ +
+
+

See Also: DSP::setParameterData, DSP::getParameterInfo

+

DSP::getParameterFloat

+

Retrieves a floating point parameter by index.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
FMOD_RESULT DSP::getParameterFloat(
+  int index,
+  float *value,
+  char *valuestr,
+  int valuestrlen
+);
+
+ +
FMOD_RESULT FMOD_DSP_GetParameterFloat(
+  FMOD_DSP *dsp,
+  int index,
+  float *value,
+  char *valuestr,
+  int valuestrlen
+);
+
+ +
RESULT DSP.getParameterFloat(
+  int index,
+  out float value
+);
+
+ +
DSP.getParameterFloat(
+  index,
+  value,
+  valuestr
+);
+
+ +
+
index
+
+

Parameter index.

+ +
+
value OutOpt
+
Parameter floating point data.
+
valuestr OutOpt
+
String representation value. (UTF-8 string)
+
valuestrlen
+
+

Length of valuestr.

+ +
+
+

See Also: DSP::setParameterFloat, DSP::getParameterInfo

+

DSP::getParameterInfo

+

Retrieve information about a specified parameter.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
FMOD_RESULT DSP::getParameterInfo(
+  int index,
+  FMOD_DSP_PARAMETER_DESC **desc
+);
+
+ +
FMOD_RESULT FMOD_DSP_GetParameterInfo(
+  FMOD_DSP *dsp,
+  int index,
+  FMOD_DSP_PARAMETER_DESC **desc
+);
+
+ +
RESULT DSP.getParameterInfo(
+  int index,
+  out DSP_PARAMETER_DESC desc
+);
+
+ +
DSP.getParameterInfo(
+  index,
+  desc
+);
+
+ +
+
index
+
+

Parameter index.

+ +
+
desc Out
+
Parameter description at the specified index. (FMOD_DSP_PARAMETER_DESC)
+
+

See Also: DSP::setParameterFloat, DSP::setParameterInt, DSP::setParameterBool, DSP::setParameterData

+

DSP::getParameterInt

+

Retrieves an integer parameter by index.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
FMOD_RESULT DSP::getParameterInt(
+  int index,
+  int *value,
+  char *valuestr,
+  int valuestrlen
+);
+
+ +
FMOD_RESULT FMOD_DSP_GetParameterInt(
+  FMOD_DSP *dsp,
+  int index,
+  int *value,
+  char *valuestr,
+  int valuestrlen
+);
+
+ +
RESULT DSP.getParameterInt(
+  int index,
+  out int value
+);
+
+ +
DSP.getParameterInt(
+  index,
+  value,
+  valuestr
+);
+
+ +
+
index
+
+

Parameter index.

+ +
+
value OutOpt
+
Parameter integer data.
+
valuestr OutOpt
+
String representation value. (UTF-8 string)
+
valuestrlen
+
+

Length of valuestr.

+ +
+
+

See Also: DSP::setParameterInt, DSP::getParameterInfo

+

DSP::getSystemObject

+

Retrieves the parent System object.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
FMOD_RESULT DSP::getSystemObject(
+  System **system
+);
+
+ +
FMOD_RESULT FMOD_DSP_GetSystemObject(
+  FMOD_DSP *dsp,
+  FMOD_SYSTEM **system
+);
+
+ +
RESULT DSP.getSystemObject(
+  out System system
+);
+
+ +
DSP.getSystemObject(
+  system
+);
+
+ +
+
system Out
+
System object. (System)
+
+

See Also: System::createDSP, System::createDSPByType

+

DSP::getType

+

Retrieves the pre-defined type of a FMOD registered DSP unit.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
FMOD_RESULT DSP::getType(
+  FMOD_DSP_TYPE *type
+);
+
+ +
FMOD_RESULT FMOD_DSP_GetType(
+  FMOD_DSP *dsp,
+  FMOD_DSP_TYPE *type
+);
+
+ +
RESULT DSP.getType(
+  out DSP_TYPE type
+);
+
+ +
DSP.getType(
+  type
+);
+
+ +
+
type Out
+
DSP type. (FMOD_DSP_TYPE)
+
+

This is only valid for the DSP types built in to the FMOD Engine. For user-created plug-in DSPs, it instead returns FMOD_DSP_TYPE_UNKNOWN.

+

DSP::getUserData

+

Retrieves a user value associated with this object.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
FMOD_RESULT DSP::getUserData(
+  void **userdata
+);
+
+ +
FMOD_RESULT FMOD_DSP_GetUserData(
+  FMOD_DSP *dsp,
+  void **userdata
+);
+
+ +
RESULT DSP.getUserData(
+  out IntPtr userdata
+);
+
+ +
DSP.getUserData(
+  userdata
+);
+
+ +
+
userdata Out
+
User data set by calling DSP::setUserData.
+
+

This function allows arbitrary user data to be retrieved from this object. See the User Data section of the glossary for an example of how to get and set user data.

+

DSP::getWetDryMix

+

Retrieves the scale of the wet and dry signal components.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
FMOD_RESULT DSP::getWetDryMix(
+  float *prewet,
+  float *postwet,
+  float *dry
+);
+
+ +
FMOD_RESULT FMOD_DSP_GetWetDryMix(
+  FMOD_DSP *dsp,
+  float *prewet,
+  float *postwet,
+  float *dry
+);
+
+ +
RESULT DSP.getWetDryMix(
+  out float prewet,
+  out float postwet,
+  out float dry
+);
+
+ +
DSP.getWetDryMix(
+  prewet,
+  postwet,
+  dry
+);
+
+ +
+
prewet OutOpt
+
+

Level of the 'Dry' (pre-processed signal) mix that is processed by the DSP. 0 = silent, 1 = full. Negative level inverts the signal. Values larger than 1 amplify the signal.

+
    +
  • Units: Linear
  • +
  • Range: (-inf, inf)
  • +
  • Default: 1
  • +
+
+
postwet OutOpt
+
+

Level of the 'Wet' (post-processed signal) mix that is output. 0 = silent, 1 = full. Negative level inverts the signal. Values larger than 1 amplify the signal.

+
    +
  • Units: Linear
  • +
  • Range: (-inf, inf)
  • +
  • Default: 1
  • +
+
+
dry OutOpt
+
+

Level of the 'Dry' (pre-processed signal) mix that is output. 0 = silent, 1 = full. Negative level inverts the signal. Values larger than 1 amplify the signal.

+
    +
  • Units: Linear
  • +
  • Range: (-inf, inf)
  • +
  • Default: 1
  • +
+
+
+

See Also: DSP::setWetDryMix

+

DSP::release

+

Releases a DSP unit, freeing the memory used by that object.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
FMOD_RESULT DSP::release();
+
+ +
FMOD_RESULT FMOD_DSP_Release(FMOD_DSP *dsp);
+
+ +
RESULT DSP.release();
+
+ +
DSP.release();
+
+ +

If DSP is not removed from the graph with ChannelControl::removeDSP after being added with ChannelControl::addDSP, it will not release and will instead return FMOD_ERR_DSP_INUSE.

+

See Also: System::createDSP

+

DSP::reset

+

Reset a DSP's internal state, making it ready for a new input signal.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
FMOD_RESULT DSP::reset();
+
+ +
FMOD_RESULT FMOD_DSP_Reset(FMOD_DSP *dsp);
+
+ +
RESULT DSP.reset();
+
+ +
DSP.reset();
+
+ +

This will clear all internal state derived from input signal while retaining any set parameter values. The intended use of the function is to avoid audible artifacts if moving the DSP from one part of the DSP graph to another.

+

DSP::setActive

+

Sets the processing active state.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
FMOD_RESULT DSP::setActive(
+  bool active
+);
+
+ +
FMOD_RESULT FMOD_DSP_SetActive(
+  FMOD_DSP *dsp,
+  FMOD_BOOL active
+);
+
+ +
RESULT DSP.setActive(
+  bool active
+);
+
+ +
DSP.setActive(
+  active
+);
+
+ +
+
active
+
+

Active state.

+
    +
  • Units: Boolean
  • +
  • Default: False
  • +
+
+
+

If active is false, processing of this unit and its inputs are stopped.

+

When created, a DSP is inactive. It is automatically activated when ChannelControl::addDSP is used; otherwise, it must be set to active manually.

+

See Also: DSP::getActive, DSP::setBypass, DSP::getBypass

+

DSP::setBypass

+

Sets the processing bypass state.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
FMOD_RESULT DSP::setBypass(
+  bool bypass
+);
+
+ +
FMOD_RESULT FMOD_DSP_SetBypass(
+  FMOD_DSP *dsp,
+  FMOD_BOOL bypass
+);
+
+ +
RESULT DSP.setBypass(
+  bool bypass
+);
+
+ +
DSP.setBypass(
+  bypass
+);
+
+ +
+
bypass
+
+

Bypass state.

+
    +
  • Units: Boolean
  • +
  • Default: False
  • +
+
+
+

If bypass is true, processing of this unit is skipped but it continues to process its inputs.

+

See Also: DSP::getBypass, DSP::setActive, DSP::getActive

+

DSP::setCallback

+

Sets the callback for DSP notifications.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
FMOD_RESULT DSP::setCallback(
+  FMOD_DSP_CALLBACK callback
+);
+
+ +
FMOD_RESULT FMOD_DSP_SetCallback(
+  FMOD_DSP *dsp,
+  FMOD_DSP_CALLBACK callback
+);
+
+ +
RESULT DSP.setCallback(
+  DSP_CALLBACK callback
+);
+
+ +
DSP.setCallback(
+  callback
+);
+
+ +
+
callback
+
Callback to invoke. (FMOD_DSP_CALLBACK)
+
+

See Also: Callback Behavior, FMOD_DSP_CALLBACK_TYPE

+

DSP::setChannelFormat

+

Sets the PCM input format this DSP is to receive when processing.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
FMOD_RESULT DSP::setChannelFormat(
+  FMOD_CHANNELMASK channelmask,
+  int numchannels,
+  FMOD_SPEAKERMODE source_speakermode
+);
+
+ +
FMOD_RESULT FMOD_DSP_SetChannelFormat(
+  FMOD_DSP *dsp,
+  FMOD_CHANNELMASK channelmask,
+  int numchannels,
+  FMOD_SPEAKERMODE source_speakermode
+);
+
+ +
RESULT DSP.setChannelFormat(
+  CHANNELMASK channelmask,
+  int numchannels,
+  SPEAKERMODE source_speakermode
+);
+
+ +
DSP.setChannelFormat(
+  channelmask,
+  numchannels,
+  source_speakermode
+);
+
+ +
+
channelmask
+
Deprecated. (FMOD_CHANNELMASK)
+
numchannels
+
+

Number of channels to be processed.

+ +
+
source_speakermode
+
Speaker mode to describe the channel mapping. (FMOD_SPEAKERMODE)
+
+

Setting the number of channels on a unit forces either a down or up mix to that channel count before processing the DSP read/process callback.

+

See Also: DSP::getChannelFormat

+

DSP::setMeteringEnabled

+

Sets the input and output signal metering enabled states.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
FMOD_RESULT DSP::setMeteringEnabled(
+  bool inputEnabled,
+  bool outputEnabled
+);
+
+ +
FMOD_RESULT FMOD_DSP_SetMeteringEnabled(
+  FMOD_DSP *dsp,
+  FMOD_BOOL inputEnabled,
+  FMOD_BOOL outputEnabled
+);
+
+ +
RESULT DSP.setMeteringEnabled(
+  bool inputEnabled,
+  bool outputEnabled
+);
+
+ +
DSP.setMeteringEnabled(
+  inputEnabled,
+  outputEnabled
+);
+
+ +
+
inputEnabled
+
+

Metering enabled state for the input signal.

+
    +
  • Units: Boolean
  • +
  • Default: False
  • +
+
+
outputEnabled
+
+

Metering enabled state for the output signal.

+
    +
  • Units: Boolean
  • +
  • Default: False
  • +
+
+
+

Input metering is pre processing, while output metering is post processing.

+

Enabled metering allows DSP::getMeteringInfo to return metering information and allows FMOD profiling tools to visualize the levels.

+

FMOD_INIT_PROFILE_METER_ALL with System::init will automatically turn on metering for all DSP units inside the DSP graph.

+

This function must have inputEnabled and outputEnabled set to true if being used by the Studio API, such as in the Unity or Unreal Engine integrations, in order to avoid conflict with FMOD Studio's live update feature.

+

See Also: DSP::getMeteringEnabled

+

DSP::setParameterBool

+

Sets a boolean parameter by index.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
FMOD_RESULT DSP::setParameterBool(
+  int index,
+  bool value
+);
+
+ +
FMOD_RESULT FMOD_DSP_SetParameterBool(
+  FMOD_DSP *dsp,
+  int index,
+  FMOD_BOOL value
+);
+
+ +
RESULT DSP.setParameterBool(
+  int index,
+  bool value
+);
+
+ +
DSP.setParameterBool(
+  index,
+  value
+);
+
+ +
+
index
+
+

Parameter index.

+ +
+
value
+
+

Parameter value.

+
    +
  • Units: Boolean
  • +
+
+
+

See Also: DSP::getParameterInfo, DSP::getParameterBool

+

DSP::setParameterData

+

Sets a binary data parameter by index.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
FMOD_RESULT DSP::setParameterData(
+  int index,
+  void *data,
+  unsigned int length
+);
+
+ +
FMOD_RESULT FMOD_DSP_SetParameterData(
+  FMOD_DSP *dsp,
+  int index,
+  void *data,
+  unsigned int length
+);
+
+ +
RESULT DSP.setParameterData(
+  int index,
+  byte[] data
+);
+
+ +
DSP.setParameterData(
+  index,
+  data,
+  length
+);
+
+ +
+
index
+
+

Parameter index.

+ +
+
data
+
Parameter binary data.
+
length
+
+

Length of data.

+
    +
  • Units: Bytes
  • +
+
+
+

Certain data types are predefined by the system and can be specified via the FMOD_DSP_PARAMETER_DESC_DATA, see FMOD_DSP_PARAMETER_DATA_TYPE

+

See Also: DSP::getParameterInfo, DSP::getParameterData

+

DSP::setParameterFloat

+

Sets a floating point parameter by index.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
FMOD_RESULT DSP::setParameterFloat(
+  int index,
+  float value
+);
+
+ +
FMOD_RESULT FMOD_DSP_SetParameterFloat(
+  FMOD_DSP *dsp,
+  int index,
+  float value
+);
+
+ +
RESULT DSP.setParameterFloat(
+  int index,
+  float value
+);
+
+ +
DSP.setParameterFloat(
+  index,
+  value
+);
+
+ +
+
index
+
+

Parameter index.

+ +
+
value
+
Parameter floating point data.
+
+

See Also: DSP::getParameterInfo, DSP::getParameterFloat

+

DSP::setParameterInt

+

Sets an integer parameter by index.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
FMOD_RESULT DSP::setParameterInt(
+  int index,
+  int value
+);
+
+ +
FMOD_RESULT FMOD_DSP_SetParameterInt(
+  FMOD_DSP *dsp,
+  int index,
+  int value
+);
+
+ +
RESULT DSP.setParameterInt(
+  int index,
+  int value
+);
+
+ +
DSP.setParameterInt(
+  index,
+  value
+);
+
+ +
+
index
+
+

Parameter index.

+ +
+
value
+
Parameter integer data.
+
+

See Also: DSP::getParameterInfo, DSP::getParameterInt

+

DSP::setUserData

+

Sets a user value associated with this object.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
FMOD_RESULT DSP::setUserData(
+  void *userdata
+);
+
+ +
FMOD_RESULT FMOD_DSP_SetUserData(
+  FMOD_DSP *dsp,
+  void *userdata
+);
+
+ +
RESULT DSP.setUserData(
+  IntPtr userdata
+);
+
+ +
DSP.setUserData(
+  userdata
+);
+
+ +
+
userdata
+
Value stored on this object.
+
+

This function allows arbitrary user data to be attached to this object. See the User Data section of the glossary for an example of how to get and set user data.

+

See Also: DSP::getUserData

+

DSP::setWetDryMix

+

Sets the scale of the wet and dry signal components.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
FMOD_RESULT DSP::setWetDryMix(
+  float prewet,
+  float postwet,
+  float dry
+);
+
+ +
FMOD_RESULT FMOD_DSP_SetWetDryMix(
+  FMOD_DSP *dsp,
+  float prewet,
+  float postwet,
+  float dry
+);
+
+ +
RESULT DSP.setWetDryMix(
+  float prewet,
+  float postwet,
+  float dry
+);
+
+ +
DSP.setWetDryMix(
+  prewet,
+  postwet,
+  dry
+);
+
+ +
+
prewet
+
+

Level of the 'Dry' (pre-processed signal) mix that is processed by the DSP. 0 = silent, 1 = full. Negative level inverts the signal. Values larger than 1 amplify the signal.

+
    +
  • Units: Linear
  • +
  • Range: (-inf, inf)
  • +
  • Default: 1
  • +
+
+
postwet
+
+

Level of the 'Wet' (post-processed signal) mix that is output. 0 = silent, 1 = full. Negative level inverts the signal. Values larger than 1 amplify the signal.

+
    +
  • Units: Linear
  • +
  • Range: (-inf, inf)
  • +
  • Default: 1
  • +
+
+
dry
+
+

Level of the 'Dry' (pre-processed signal) mix that is output. 0 = silent, 1 = full. Negative level inverts the signal. Values larger than 1 amplify the signal.

+
    +
  • Units: Linear
  • +
  • Range: (-inf, inf)
  • +
  • Default: 0
  • +
+
+
+

The dry signal path is silent by default, because DSP effects transform the input and pass the newly processed result to the output.

+

See Also: DSP::getWetDryMix

+

DSP::showConfigDialog

+

Display or hide a DSP unit configuration dialog box inside the target window.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
FMOD_RESULT DSP::showConfigDialog(
+  void *hwnd,
+  bool show
+);
+
+ +
FMOD_RESULT FMOD_DSP_ShowConfigDialog(
+  FMOD_DSP *dsp,
+  void *hwnd,
+  FMOD_BOOL show
+);
+
+ +
RESULT DSP.showConfigDialog(
+  IntPtr hwnd,
+  bool show
+);
+
+ +
DSP.showConfigDialog(
+  hwnd,
+  show
+);
+
+ +
+
hwnd
+
Target HWND in windows to display configuration dialog.
+
show
+
+

Whether to show or hide the dialog box inside target hwnd.

+
    +
  • Units: Boolean
  • +
+
+
+

Some DSP plug-ins (especially VST plug-ins) use dialog boxes to display graphical user interfaces for modifying their parameters, rather than using the other method of enumerating their parameters and setting them with DSP::setParameterFloat, DSP::setParameterInt, DSP::setParameterBool, or DSP::setParameterData.

+

To find out what size window to create to store the configuration screen, use DSP::getInfo where you can get the width and height.

+ + +
+ + + diff --git a/FMOD/doc/FMOD API User Manual/core-api-dspconnection.html b/FMOD/doc/FMOD API User Manual/core-api-dspconnection.html new file mode 100644 index 0000000..976c76e --- /dev/null +++ b/FMOD/doc/FMOD API User Manual/core-api-dspconnection.html @@ -0,0 +1,553 @@ + + +Core API Reference | DSPConnection + + + + +
+ +
+

11. Core API Reference | DSPConnection

+

An interface that manages Digital Signal Processor (DSP) connections

+

Mix Properties:

+ +

General:

+ +
+ +

DSPConnection::getInput

+

Retrieves the connection's input DSP unit.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
FMOD_RESULT DSPConnection::getInput(
+  DSP **input
+);
+
+ +
FMOD_RESULT FMOD_DSPConnection_GetInput(
+  FMOD_DSPCONNECTION *dspconnection,
+  FMOD_DSP **input
+);
+
+ +
RESULT DSPConnection.getInput(
+  out DSP input
+);
+
+ +
DSPConnection.getInput(
+  input
+);
+
+ +
+
input Out
+
Input DSP unit. (DSP)
+
+

If this function is called very soon after DSP::addInput, the connection might not be ready because the DSP system is still queued to be connected and may need to wait several milliseconds for the next mix to occur. When this occurs, the function returns FMOD_ERR_NOTREADY and input is null.

+

See Also: DSPConnection::getOutput, DSP::addInput

+

DSPConnection::getMix

+

Retrieves the connection's volume scale.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
FMOD_RESULT DSPConnection::getMix(
+  float *volume
+);
+
+ +
FMOD_RESULT FMOD_DSPConnection_GetMix(
+  FMOD_DSPCONNECTION *dspconnection,
+  float *volume
+);
+
+ +
RESULT DSPConnection.getMix(
+  out float volume
+);
+
+ +
DSPConnection.getMix(
+  volume
+);
+
+ +
+
volume Out
+
+

Volume scale applied to the input before being passed to the output. 0 = silent, 1 = full. Negative level inverts the signal. Values larger than 1 amplify the signal.

+
    +
  • Units: Linear
  • +
  • Range: (-inf, inf)
  • +
  • Default: 1
  • +
+
+
+

See Also: DSPConnection::setMix

+

DSPConnection::getMixMatrix

+

Retrieves a 2 dimensional pan matrix that maps the signal from input channels (columns) to output speakers (rows).

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
FMOD_RESULT DSPConnection::getMixMatrix(
+  float *matrix,
+  int *outchannels,
+  int *inchannels,
+  int inchannel_hop = 0
+);
+
+ +
FMOD_RESULT FMOD_DSPConnection_GetMixMatrix(
+  FMOD_DSPCONNECTION *dspconnection,
+  float *matrix,
+  int *outchannels,
+  int *inchannels,
+  int inchannel_hop
+);
+
+ +
RESULT DSPConnection.getMixMatrix(
+  float[] matrix,
+  out int outchannels,
+  out int inchannels,
+  int inchannel_hop = 0
+);
+
+ +
DSPConnection.getMixMatrix(
+  matrix,
+  outchannels,
+  inchannels,
+  inchannel_hop
+);
+
+ +
+
matrix OutOpt
+
+

Two dimensional array of volume levels in row-major order. Each row represents an output speaker, each column represents an input channel. Passing null or equivalent as the matrix allows querying of outchannels and inchannels.

+
    +
  • Units: Linear
  • +
  • Range: (-inf, inf)
  • +
+
+
outchannels OutOpt
+
Number of valid output channels (rows) in matrix. Optional only when matrix is null or equivalent.
+
inchannels OutOpt
+
Number of valid input channels (columns) in matrix. Optional only when matrix is null or equivalent.
+
inchannel_hop Opt
+
Width (total number of columns) in destination matrix. Can be larger than inchannels to represent a smaller valid region inside a larger matrix.
+
+

A matrix element is referenced from the incoming matrix data as outchannel * inchannel_hop + inchannel.

+

See Also: DSPConnection::setMixMatrix

+

DSPConnection::getOutput

+

Retrieves the connection's output DSP unit.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
FMOD_RESULT DSPConnection::getOutput(
+  DSP **output
+);
+
+ +
FMOD_RESULT FMOD_DSPConnection_GetOutput(
+  FMOD_DSPCONNECTION *dspconnection,
+  FMOD_DSP **output
+);
+
+ +
RESULT DSPConnection.getOutput(
+  out DSP output
+);
+
+ +
DSPConnection.getOutput(
+  output
+);
+
+ +
+
output Out
+
Output DSP unit. (DSP)
+
+

If this function is called very soon after DSP::addInput, the connection might not be ready because the DSP system is still queued to be connected and may need to wait several milliseconds for the next mix to occur. When this occurs, the function returns FMOD_ERR_NOTREADY and output is null.

+

See Also: DSPConnection::getInput, DSP::addInput

+

DSPConnection::getType

+

Retrieves the type of the connection between two DSP units.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
FMOD_RESULT DSPConnection::getType(
+  FMOD_DSPCONNECTION_TYPE *type
+);
+
+ +
FMOD_RESULT FMOD_DSPConnection_GetType(
+  FMOD_DSPCONNECTION *dspconnection,
+  FMOD_DSPCONNECTION_TYPE *type
+);
+
+ +
RESULT DSPConnection.getType(
+  out DSPCONNECTION_TYPE type
+);
+
+ +
DSPConnection.getType(
+  type
+);
+
+ +
+
type Out
+
Type of connection. (FMOD_DSPCONNECTION_TYPE)
+
+

DSPConnection::getUserData

+

Retrieves a user value associated with this object.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
FMOD_RESULT DSPConnection::getUserData(
+  void **userdata
+);
+
+ +
FMOD_RESULT FMOD_DSPConnection_GetUserData(
+  FMOD_DSPCONNECTION *dspconnection,
+  void **userdata
+);
+
+ +
RESULT DSPConnection.getUserData(
+  out IntPtr userdata
+);
+
+ +
DSPConnection.getUserData(
+  userdata
+);
+
+ +
+
userdata Out
+
User data set by calling DSPConnection::setUserData.
+
+

This function allows arbitrary user data to be retrieved from this object. See the User Data section of the glossary for an example of how to get and set user data.

+

DSPConnection::setMix

+

Sets the connection's volume scale.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
FMOD_RESULT DSPConnection::setMix(
+  float volume
+);
+
+ +
FMOD_RESULT FMOD_DSPConnection_SetMix(
+  FMOD_DSPCONNECTION *dspconnection,
+  float volume
+);
+
+ +
RESULT DSPConnection.setMix(
+  float volume
+);
+
+ +
DSPConnection.setMix(
+  volume
+);
+
+ +
+
volume
+
+

Volume scale applied to the input before being passed to the output. 0 = silent, 1 = full. Negative level inverts the signal. Values larger than 1 amplify the signal.

+
    +
  • Units: Linear
  • +
  • Range: (-inf, inf)
  • +
  • Default: 1
  • +
+
+
+

See Also: DSPConnection::getMix, DSPConnection::setMixMatrix, DSPConnection::getMixMatrix

+

DSPConnection::setMixMatrix

+

Sets a 2 dimensional pan matrix that maps the signal from input channels (columns) to output speakers (rows).

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
FMOD_RESULT DSPConnection::setMixMatrix(
+  float *matrix,
+  int outchannels,
+  int inchannels,
+  int inchannel_hop = 0
+);
+
+ +
FMOD_RESULT FMOD_DSPConnection_SetMixMatrix(
+  FMOD_DSPCONNECTION *dspconnection,
+  float *matrix,
+  int outchannels,
+  int inchannels,
+  int inchannel_hop
+);
+
+ +
RESULT DSPConnection.setMixMatrix(
+  float[] matrix,
+  int outchannels,
+  int inchannels,
+  int inchannel_hop = 0
+);
+
+ +
DSPConnection.setMixMatrix(
+  matrix,
+  outchannels,
+  inchannels,
+  inchannel_hop
+);
+
+ +
+
matrix Opt
+
+

Two dimensional array of volume levels in row-major order. Each row represents an output speaker, each column represents an input channel. Null or equivalent sets a 'default' matrix.

+
    +
  • Units: Linear
  • +
  • Range: (-inf, inf)
  • +
+
+
outchannels
+
+

Number of output channels (rows) in matrix.

+ +
+
inchannels
+
+

Number of input channels (columns) in matrix.

+ +
+
inchannel_hop Opt
+
Width (total number of columns) in source matrix. Can be larger than inchannels to represent a smaller valid region inside a larger matrix.
+
+ +

A matrix element is referenced from the incoming matrix data as outchannel * inchannel_hop + inchannel.

+

If null or equivalent is passed in via matrix a default upmix, downmix, or unit matrix will take its place. A unit matrix allows a signal to pass through unchanged.

+

Example 5.1 unit matrix:

+
1 0 0 0 0 0 
+0 1 0 0 0 0 
+0 0 1 0 0 0 
+0 0 0 1 0 0 
+0 0 0 0 1 0 
+0 0 0 0 0 1
+
+

Matrix element values can be below 0 to invert a signal and above 1 to amplify the signal. Note that increasing the signal level too far may cause audible distortion.

+

See Also: DSPConnection::getMixMatrix

+

DSPConnection::setUserData

+

Sets a user value associated with this object.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
FMOD_RESULT DSPConnection::setUserData(
+  void *userdata
+);
+
+ +
FMOD_RESULT FMOD_DSPConnection_SetUserData(
+  FMOD_DSPCONNECTION *dspconnection,
+  void *userdata
+);
+
+ +
RESULT DSPConnection.setUserData(
+  IntPtr userdata
+);
+
+ +
DSPConnection.setUserData(
+  userdata
+);
+
+ +
+
userdata
+
Value stored on this object.
+
+

This function allows arbitrary user data to be attached to this object. See the User Data section of the glossary for an example of how to get and set user data.

+

See Also: DSPConnection::getUserData

+

FMOD_DSPCONNECTION_TYPE

+

List of connection types between two DSP units.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
typedef enum FMOD_DSPCONNECTION_TYPE {
+  FMOD_DSPCONNECTION_TYPE_STANDARD,
+  FMOD_DSPCONNECTION_TYPE_SIDECHAIN,
+  FMOD_DSPCONNECTION_TYPE_SEND,
+  FMOD_DSPCONNECTION_TYPE_SEND_SIDECHAIN,
+  FMOD_DSPCONNECTION_TYPE_PREALLOCATED,
+  FMOD_DSPCONNECTION_TYPE_MAX
+} FMOD_DSPCONNECTION_TYPE;
+
+ +
enum DSPCONNECTION_TYPE
+{
+    STANDARD,
+    SIDECHAIN,
+    SEND,
+    SEND_SIDECHAIN,
+    PREALLOCATED,
+    MAX,
+}
+
+ +
FMOD.DSPCONNECTION_TYPE_STANDARD
+FMOD.DSPCONNECTION_TYPE_SIDECHAIN
+FMOD.DSPCONNECTION_TYPE_SEND
+FMOD.DSPCONNECTION_TYPE_SEND_SIDECHAIN
+FMOD.DSPCONNECTION_TYPE_PREALLOCATED
+FMOD.DSPCONNECTION_TYPE_MAX
+
+ +
+
FMOD_DSPCONNECTION_TYPE_STANDARD
+
Default connection type. Audio is mixed from the input to the output DSP's audible buffer.
+
FMOD_DSPCONNECTION_TYPE_SIDECHAIN
+
Sidechain connection type. Audio is mixed from the input to the output DSP's sidechain buffer.
+
FMOD_DSPCONNECTION_TYPE_SEND
+
Send connection type. Audio is mixed from the input to the output DSP's audible buffer, but the input is not executed, only copied from. A standard connection or sidechain needs to make an input execute to generate data.
+
FMOD_DSPCONNECTION_TYPE_SEND_SIDECHAIN
+
Send sidechain connection type. Audio is mixed from the input to the output DSP's sidechain buffer, but the input is not executed, only copied from. A standard connection or sidechain needs to make an input execute to generate data.
+
FMOD_DSPCONNECTION_TYPE_PREALLOCATED
+
Pre-allocated connection allocated with System::createDSPConnection. Only used with DSP::addInput.
+
FMOD_DSPCONNECTION_TYPE_MAX
+
Maximum number of DSP connection types supported.
+
+

FMOD_DSP_CONNECTION_TYPE_STANDARD

+
+

Default DSPConnection type. Audio is mixed from the input to the output DSP's audible buffer, meaning it will be part of the audible signal. A standard connection executes its input DSP if it has not been executed before.

+

FMOD_DSP_CONNECTION_TYPE_SIDECHAIN

+
+

Sidechain DSPConnection type. Audio is mixed from the input to the output DSP's sidechain buffer, meaning it will not be part of the audible signal. A sidechain connection executes its input DSP if it has not been executed before.

+

This separate sidechain buffer exists so that the DSP can privately access it for analysis purposes. For example, a compressor DSP could analyze the signal and use the result of that analysis to control its own compression level and gain parameters.

+

When a sidechain is connected to a DSP, the sidechain buffer is a member of the FMOD_DSP_STATE struct, which is itself passed in as a parameter of the read callback. This data simplifies the development of effects that make use of sidechaining.

+

FMOD_DSP_STATE::sidechaindata and FMOD_DSP_STATE::sidechainchannels will hold the mixed result of any sidechain data flowing into it.

+

FMOD_DSP_CONNECTION_TYPE_SEND

+
+

Send DSPConnection type. Audio is mixed from the input to the output DSP's audible buffer, meaning it becomes part of the audible signal. A send connection will not execute its input DSP if it has not been executed before.

+

A send connection only reads what exists at the input's buffer at the time of executing the output DSP unit (which can be considered the 'return').

+

FMOD_DSP_CONNECTION_TYPE_SEND_SIDECHAIN

+
+

Send sidechain DSPConnection type. Audio is mixed from the input to the output DSP's sidechain buffer, meaning it does not become part of the audible signal. A send sidechain connection does not execute its input DSP if it has not been executed before.

+

A send sidechain connection only reads what exists at the input's buffer at the time of executing the output DSP unit (which can be considered the 'sidechain return').

+

When a sidechain is connected to a DSP, the sidechain data is stored in the FMOD_DSP_STATE struct that is a function parameter of the read callback. This data simplifies the development of effects that make use of sidechaining.

+

FMOD_DSP_STATE::sidechaindata and FMOD_DSP_STATE::sidechainchannels hold the mixed result of any sidechain data flowing into them.

+

FMOD_DSPCONNECTION_TYPE_PREALLOCATED

+
+

Pre-allocated DSPConnection type. Used with DSP::addInput when providing a pre-allocated connection (created by a call to System::createDSPConnection) via the connection parameter.

+

See Also: DSP::addInput, DSPConnection::getType

+ + +
+ + + diff --git a/FMOD/doc/FMOD API User Manual/core-api-geometry.html b/FMOD/doc/FMOD API User Manual/core-api-geometry.html new file mode 100644 index 0000000..484cece --- /dev/null +++ b/FMOD/doc/FMOD API User Manual/core-api-geometry.html @@ -0,0 +1,1057 @@ + + +Core API Reference | Geometry + + + + +
+ +
+

11. Core API Reference | Geometry

+

An interface that allows the setup and modification of geometry for occlusion

+

Polygons:

+ +

Object Spatialization:

+ +

Object General:

+ +

Geometry::addPolygon

+

Adds a polygon.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
FMOD_RESULT Geometry::addPolygon(
+  float directocclusion,
+  float reverbocclusion,
+  bool doublesided,
+  int numvertices,
+  const FMOD_VECTOR *vertices,
+  int *polygonindex
+);
+
+ +
FMOD_RESULT FMOD_Geometry_AddPolygon(
+  FMOD_GEOMETRY *geometry,
+  float directocclusion,
+  float reverbocclusion,
+  FMOD_BOOL doublesided,
+  int numvertices,
+  const FMOD_VECTOR *vertices,
+  int *polygonindex
+);
+
+ +
RESULT Geometry.addPolygon(
+  float directocclusion,
+  float reverbocclusion,
+  bool doublesided,
+  int numvertices,
+  VECTOR[] vertices,
+  out int polygonindex
+);
+
+ +
+

Currently not supported for JavaScript.

+
+
+
directocclusion
+
+

Occlusion factor of the polygon for the direct path where 0 represents no occlusion and 1 represents full occlusion.

+
    +
  • Range: [0, 1]
  • +
  • Default: 0
  • +
+
+
reverbocclusion
+
+

Occlusion factor of the polygon for the reverb path where 0 represents no occlusion and 1 represents full occlusion.

+
    +
  • Range: [0, 1]
  • +
  • Default: 0
  • +
+
+
doublesided
+
+

True: Polygon is double sided.
+False: Polygon is single sided, and the winding of the polygon (which determines the polygon's normal) determines which side of the polygon will cause occlusion.

+
    +
  • Units: Boolean
  • +
+
+
numvertices
+
Number of vertices in this polygon. This must be at least 3.
+
vertices
+
Array of vertices located in object space of length numvertices. (FMOD_VECTOR)
+
polygonindex OutOpt
+
Polygon index. Use this with other per polygon based functions as a handle.
+
+

All vertices must lay in the same plane otherwise behavior may be unpredictable. The polygon is assumed to be convex. A non convex polygon will produce unpredictable behavior. Polygons with zero area will be ignored.

+

Polygons cannot be added if already at the maximum number of polygons or if the addition of their verticies would result in exceeding the maximum number of vertices.

+

Vertices of an object are in object space, not world space, and so are relative to the position, or center of the object. See Geometry::setPosition.

+

See Also: Geometry::setPolygonAttributes, Geometry::getNumPolygons, Geometry::getMaxPolygons

+

Geometry::getActive

+

Retrieves whether an object is processed by the geometry engine.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
FMOD_RESULT Geometry::getActive(
+  bool *active
+);
+
+ +
FMOD_RESULT FMOD_Geometry_GetActive(
+  FMOD_GEOMETRY *geometry,
+  FMOD_BOOL *active
+);
+
+ +
RESULT Geometry.getActive(
+  out bool active
+);
+
+ +
Geometry.getActive(
+  active
+);
+
+ +
+
active Out
+
+

Object is allowed to be processed by the geometry engine.

+
    +
  • Units: Boolean
  • +
  • Default: True
  • +
+
+
+

See Also: Geometry::setActive

+

Geometry::getMaxPolygons

+

Retrieves the maximum number of polygons and vertices allocatable for this object.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
FMOD_RESULT Geometry::getMaxPolygons(
+  int *maxpolygons,
+  int *maxvertices
+);
+
+ +
FMOD_RESULT FMOD_Geometry_GetMaxPolygons(
+  FMOD_GEOMETRY *geometry,
+  int *maxpolygons,
+  int *maxvertices
+);
+
+ +
RESULT Geometry.getMaxPolygons(
+  out int maxpolygons,
+  out int maxvertices
+);
+
+ +
Geometry.getMaxPolygons(
+  maxpolygons,
+  maxvertices
+);
+
+ +
+
maxpolygons OutOpt
+
Maximum possible number of polygons in this object.
+
maxvertices OutOpt
+
Maximum possible number of vertices in this object.
+
+

The maximum number was set with System::createGeometry.

+

See Also: System::loadGeometry

+

Geometry::getNumPolygons

+

Retrieves the number of polygons in this object.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
FMOD_RESULT Geometry::getNumPolygons(
+  int *numpolygons
+);
+
+ +
FMOD_RESULT FMOD_Geometry_GetNumPolygons(
+  FMOD_GEOMETRY *geometry,
+  int *numpolygons
+);
+
+ +
RESULT Geometry.getNumPolygons(
+  out int numpolygons
+);
+
+ +
Geometry.getNumPolygons(
+  numpolygons
+);
+
+ +
+
numpolygons Out
+
Number of polygons.
+
+

See Also: Geometry::AddPolygon

+

Geometry::getPolygonAttributes

+

Retrieves the attributes for a polygon.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
FMOD_RESULT Geometry::getPolygonAttributes(
+  int index,
+  float *directocclusion,
+  float *reverbocclusion,
+  bool *doublesided
+);
+
+ +
FMOD_RESULT FMOD_Geometry_GetPolygonAttributes(
+  FMOD_GEOMETRY *geometry,
+  int index,
+  float *directocclusion,
+  float *reverbocclusion,
+  FMOD_BOOL *doublesided
+);
+
+ +
RESULT Geometry.getPolygonAttributes(
+  int index,
+  out float directocclusion,
+  out float reverbocclusion,
+  out bool doublesided
+);
+
+ +
Geometry.getPolygonAttributes(
+  index,
+  directocclusion,
+  reverbocclusion,
+  doublesided
+);
+
+ +
+
index
+
+

Polygon index.

+ +
+
directocclusion OutOpt
+
+

Occlusion factor for the direct path where 0 represents no occlusion and 1 represents full occlusion.

+
    +
  • Range: [0, 1]
  • +
  • Default: 0
  • +
  • Units: Linear
  • +
+
+
reverbocclusion OutOpt
+
+

Occlusion factor for the reverb path where 0 represents no occlusion and 1 represents full occlusion.

+
    +
  • Range: [0, 1]
  • +
  • Default: 0
  • +
  • Units: Linear
  • +
+
+
doublesided OutOpt
+
+

True: Polygon is double sided.
+False: Polygon is single sided, and the winding of the polygon (which determines the polygon's normal) determines which side of the polygon will cause occlusion.

+
    +
  • Units: Boolean
  • +
+
+
+

See Also: Geometry::setPolygonAttributes

+

Geometry::getPolygonNumVertices

+

Gets the number of vertices in a polygon.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
FMOD_RESULT Geometry::getPolygonNumVertices(
+  int index,
+  int *numvertices
+);
+
+ +
FMOD_RESULT FMOD_Geometry_GetPolygonNumVertices(
+  FMOD_GEOMETRY *geometry,
+  int index,
+  int *numvertices
+);
+
+ +
RESULT Geometry.getPolygonNumVertices(
+  int index,
+  out int numvertices
+);
+
+ +
Geometry.getPolygonNumVertices(
+  index,
+  numvertices
+);
+
+ +
+
index
+
+

Polygon index.

+ +
+
numvertices OutOpt
+
Number of vertices.
+
+

Geometry::getPolygonVertex

+

Retrieves the position of a vertex.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
FMOD_RESULT Geometry::getPolygonVertex(
+  int index,
+  int vertexindex,
+  FMOD_VECTOR *vertex
+);
+
+ +
FMOD_RESULT FMOD_Geometry_GetPolygonVertex(
+  FMOD_GEOMETRY *geometry,
+  int index,
+  int vertexindex,
+  FMOD_VECTOR *vertex
+);
+
+ +
RESULT Geometry.getPolygonVertex(
+  int index,
+  int vertexindex,
+  out VECTOR vertex
+);
+
+ +
Geometry.getPolygonVertex(
+  index,
+  vertexindex,
+  vertex
+);
+
+ +
+
index
+
+

Polygon index.

+ +
+
vertexindex
+
+

Polygon vertex index.

+ +
+
vertex Out
+
+

3D Position of the vertex. (FMOD_VECTOR)

+ +
+
+

Vertices are relative to the position of the object. See Geometry::setPosition.

+

See Also: Geometry::setPolygonVertex

+

Geometry::getPosition

+

Retrieves the 3D position of the object.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
FMOD_RESULT Geometry::getPosition(
+  FMOD_VECTOR *position
+);
+
+ +
FMOD_RESULT FMOD_Geometry_GetPosition(
+  FMOD_GEOMETRY *geometry,
+  FMOD_VECTOR *position
+);
+
+ +
RESULT Geometry.getPosition(
+  out VECTOR position
+);
+
+ +
Geometry.getPosition(
+  position
+);
+
+ +
+
position Out
+
+

3D position. (FMOD_VECTOR)

+ +
+
+

Position is in world space.

+

See Also: Geometry::setPosition

+

Geometry::getRotation

+

Retrieves the 3D orientation of the object.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
FMOD_RESULT Geometry::getRotation(
+  FMOD_VECTOR *forward,
+  FMOD_VECTOR *up
+);
+
+ +
FMOD_RESULT FMOD_Geometry_GetRotation(
+  FMOD_GEOMETRY *geometry,
+  FMOD_VECTOR *forward,
+  FMOD_VECTOR *up
+);
+
+ +
RESULT Geometry.getRotation(
+  out VECTOR forward,
+  out VECTOR up
+);
+
+ +
Geometry.getRotation(
+  forward,
+  up
+);
+
+ +
+
forward OutOpt
+
Forwards orientation. This vector must be of unit length and perpendicular to the up vector. (FMOD_VECTOR)
+
up OutOpt
+
Upwards orientation. This vector must be of unit length and perpendicular to the forwards vector. (FMOD_VECTOR)
+
+

See Also: Geometry::setRotation

+

Geometry::getScale

+

Retrieves the 3D scale of the object.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
FMOD_RESULT Geometry::getScale(
+  FMOD_VECTOR *scale
+);
+
+ +
FMOD_RESULT FMOD_Geometry_GetScale(
+  FMOD_GEOMETRY *geometry,
+  FMOD_VECTOR *scale
+);
+
+ +
RESULT Geometry.getScale(
+  out VECTOR scale
+);
+
+ +
Geometry.getScale(
+  scale
+);
+
+ +
+
scale Out
+
+

Scale value. (FMOD_VECTOR)

+
    +
  • Units: Linear
  • +
  • Default: (1, 1, 1)
  • +
+
+
+

See Also: Geometry::setScale

+

Geometry::getUserData

+

Retrieves a user value associated with this object.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
FMOD_RESULT Geometry::getUserData(
+  void **userdata
+);
+
+ +
FMOD_RESULT FMOD_Geometry_GetUserData(
+  FMOD_GEOMETRY *geometry,
+  void **userdata
+);
+
+ +
RESULT Geometry.getUserData(
+  out IntPtr userdata
+);
+
+ +
Geometry.getUserData(
+  userdata
+);
+
+ +
+
userdata Out
+
User data set by calling Geometry::setUserData.
+
+

This function allows arbitrary user data to be retrieved from this object. See the User Data section of the glossary for an example of how to get and set user data.

+

Geometry::release

+

Frees a geometry object and releases its memory.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
FMOD_RESULT Geometry::release();
+
+ +
FMOD_RESULT FMOD_Geometry_Release(FMOD_GEOMETRY *geometry);
+
+ +
RESULT Geometry.release();
+
+ +
Geometry.release();
+
+ +

Geometry::save

+

Saves the geometry object as a serialized binary block to a user memory buffer.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
FMOD_RESULT Geometry::save(
+  void *data,
+  int *datasize
+);
+
+ +
FMOD_RESULT FMOD_Geometry_Save(
+  FMOD_GEOMETRY *geometry,
+  void *data,
+  int *datasize
+);
+
+ +
RESULT Geometry.save(
+  IntPtr data,
+  out int datasize
+);
+
+ +
+

Currently not supported for JavaScript.

+
+
+
data OutOpt
+
Serialized geometry object. Specify null to have the datasize parameter return the size of the memory required for this saved object.
+
datasize Out
+
+

Size required to save this object when 'data' parameter is null. Otherwise ignored.

+
    +
  • Units: Bytes
  • +
+
+
+

Typical usage of this function is to call it twice - once to get the size of the data, then again to write the data to your pointer.

+

The data can be saved to a file if required and loaded later with System::loadGeometry.

+

See Also: System::createGeometry

+

Geometry::setActive

+

Sets whether an object is processed by the geometry engine.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
FMOD_RESULT Geometry::setActive(
+  bool active
+);
+
+ +
FMOD_RESULT FMOD_Geometry_SetActive(
+  FMOD_GEOMETRY *geometry,
+  FMOD_BOOL active
+);
+
+ +
RESULT Geometry.setActive(
+  bool active
+);
+
+ +
Geometry.setActive(
+  active
+);
+
+ +
+
active
+
+

Allow object to be processed by the geometry engine.

+
    +
  • Units: Boolean
  • +
  • Default: True
  • +
+
+
+

See Also: Geometry::getActive

+

Geometry::setPolygonAttributes

+

Sets individual attributes for a polygon inside a geometry object.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
FMOD_RESULT Geometry::setPolygonAttributes(
+  int index,
+  float directocclusion,
+  float reverbocclusion,
+  bool doublesided
+);
+
+ +
FMOD_RESULT FMOD_Geometry_SetPolygonAttributes(
+  FMOD_GEOMETRY *geometry,
+  int index,
+  float directocclusion,
+  float reverbocclusion,
+  FMOD_BOOL doublesided
+);
+
+ +
RESULT Geometry.setPolygonAttributes(
+  int index,
+  float directocclusion,
+  float reverbocclusion,
+  bool doublesided
+);
+
+ +
Geometry.setPolygonAttributes(
+  index,
+  directocclusion,
+  reverbocclusion,
+  doublesided
+);
+
+ +
+
index
+
+

Polygon index.

+ +
+
directocclusion
+
+

Occlusion factor of the polygon for the direct path where 0 represents no occlusion and 1 represents full occlusion.

+
    +
  • Range: [0, 1]
  • +
  • Default: 0
  • +
  • Units: Linear
  • +
+
+
reverbocclusion
+
+

Occlusion factor of the polygon for the reverb path where 0 represents no occlusion and 1 represents full occlusion.

+
    +
  • Range: [0, 1]
  • +
  • Default: 0
  • +
  • Units: Linear
  • +
+
+
doublesided
+
+

True: Polygon is double sided.
+False: Polygon is single sided, and the winding of the polygon (which determines the polygon's normal) determines which side of the polygon will cause occlusion.

+
    +
  • Units: Boolean
  • +
+
+
+

See Also: Geometry::getPolygonAttributes, Geometry::getNumPolygons

+

Geometry::setPolygonVertex

+

Alters the position of a polygon's vertex inside a geometry object.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
FMOD_RESULT Geometry::setPolygonVertex(
+  int index,
+  int vertexindex,
+  const FMOD_VECTOR *vertex
+);
+
+ +
FMOD_RESULT FMOD_Geometry_SetPolygonVertex(
+  FMOD_GEOMETRY *geometry,
+  int index,
+  int vertexindex,
+  const FMOD_VECTOR *vertex
+);
+
+ +
RESULT Geometry.setPolygonVertex(
+  int index,
+  int vertexindex,
+  ref VECTOR vertex
+);
+
+ +
Geometry.setPolygonVertex(
+  index,
+  vertexindex,
+  vertex
+);
+
+ +
+
index
+
+

Polygon index.

+ +
+
vertexindex
+
+

Polygon vertex index.

+ +
+
vertex
+
+

3D Position of the vertex. (FMOD_VECTOR)

+ +
+
+

Vertices are relative to the position of the object. See Geometry::setPosition.

+

There may be some significant overhead with this function as it may cause some reconfiguration of internal data structures used to speed up sound-ray testing.

+

You may get better results if you want to modify your object by using Geometry::setPosition, Geometry::setScale and Geometry::setRotation.

+

See Also: Geometry::getPolygonNumVertices, Geometry::getPolygonNumVertices, Geometry::getNumPolygons

+

Geometry::setPosition

+

Sets the 3D position of the object.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
FMOD_RESULT Geometry::setPosition(
+  const FMOD_VECTOR *position
+);
+
+ +
FMOD_RESULT FMOD_Geometry_SetPosition(
+  FMOD_GEOMETRY *geometry,
+  const FMOD_VECTOR *position
+);
+
+ +
RESULT Geometry.setPosition(
+  ref VECTOR position
+);
+
+ +
Geometry.setPosition(
+  position
+);
+
+ +
+
position
+
+

3D position. (FMOD_VECTOR)

+ +
+
+

Position is in world space.

+

See Also: Geometry::getPosition, Geometry::setRotation, Geometry::setScale

+

Geometry::setRotation

+

Sets the 3D orientation of the object.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
FMOD_RESULT Geometry::setRotation(
+  const FMOD_VECTOR *forward,
+  const FMOD_VECTOR *up
+);
+
+ +
FMOD_RESULT FMOD_Geometry_SetRotation(
+  FMOD_GEOMETRY *geometry,
+  const FMOD_VECTOR *forward,
+  const FMOD_VECTOR *up
+);
+
+ +
RESULT Geometry.setRotation(
+  ref VECTOR forward,
+  ref VECTOR up
+);
+
+ +
Geometry.setRotation(
+  forward,
+  up
+);
+
+ +
+
forward Opt
+
+

Forwards orientation. This vector must be of unit length and perpendicular to the up vector. (FMOD_VECTOR)

+
    +
  • Default: (0, 0, 1)
  • +
+
+
up Opt
+
+

Upwards orientation. This vector must be of unit length and perpendicular to the forwards vector. (FMOD_VECTOR)

+
    +
  • Default: (0, 1, 0)
  • +
+
+
+

See remarks in System::set3DListenerAttributes for more description on forward and up vectors.

+

See Also: Geometry::getRotation, Geometry::setPosition, Geometry::setScale

+

Geometry::setScale

+

Sets the 3D scale of the object.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
FMOD_RESULT Geometry::setScale(
+  const FMOD_VECTOR *scale
+);
+
+ +
FMOD_RESULT FMOD_Geometry_SetScale(
+  FMOD_GEOMETRY *geometry,
+  const FMOD_VECTOR *scale
+);
+
+ +
RESULT Geometry.setScale(
+  ref VECTOR scale
+);
+
+ +
Geometry.setScale(
+  scale
+);
+
+ +
+
scale
+
+

Scale value. (FMOD_VECTOR)

+
    +
  • Units: Linear
  • +
  • Default: (1, 1, 1)
  • +
+
+
+

An object can be scaled/warped in all 3 dimensions separately using this function without having to modify polygon data.

+

See Also: Geometry::getScale, Geometry::setPosition, Geometry::setRotation

+

Geometry::setUserData

+

Sets a user value associated with this object.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
FMOD_RESULT Geometry::setUserData(
+  void *userdata
+);
+
+ +
FMOD_RESULT FMOD_Geometry_SetUserData(
+  FMOD_GEOMETRY *geometry,
+  void *userdata
+);
+
+ +
RESULT Geometry.setUserData(
+  IntPtr userdata
+);
+
+ +
Geometry.setUserData(
+  userdata
+);
+
+ +
+
userdata
+
Value stored on this object.
+
+

This function allows arbitrary user data to be attached to this object. See the User Data section of the glossary for an example of how to get and set user data.

+

See Also: Geometry::getUserData

+ + +
+ + + diff --git a/FMOD/doc/FMOD API User Manual/core-api-platform-android.html b/FMOD/doc/FMOD API User Manual/core-api-platform-android.html new file mode 100644 index 0000000..a6b88ea --- /dev/null +++ b/FMOD/doc/FMOD API User Manual/core-api-platform-android.html @@ -0,0 +1,105 @@ + + +Core API Reference | Android Specific + + + + +
+ +
+

11. Core API Reference | Android Specific

+

APIs and types for Android platform, see fmod_android.h

+ +

FMOD_Android_JNI_Close

+

Call to uninitialize FMOD from a native activity.

+

+

+
C
+
C++
+
C#
+
+

+
FMOD_RESULT FMOD_Android_JNI_Close();
+
+ +
RESULT FMOD.Android.JNI_Close();
+
+ +
+

Not supported for JavaScript.

+
+

When using a native activity, you will need to call this function after calling System::release.

+

See Also: Java

+

FMOD_Android_JNI_Init

+

Call to initialize FMOD from a native activity.

+

+

+
C
+
C++
+
C#
+
+

+
FMOD_RESULT FMOD_Android_JNI_Init(
+    JavaVM *vm,
+    jobject javaActivity
+);
+
+ +
FMOD_RESULT FMOD.Android.JNI_Init(
+    IntPtr vm,
+    IntPtr javaActivity
+);
+
+ +
+

Not supported for JavaScript.

+
+
+
vm
+
Pointer to the ANativeActivity::vm JavaVM.
+
javaActivity
+
Pointer to your ANativeActivity::clazz jobject.
+
+

When using a native activity, you will need to call this function before making calls into the FMOD API.
+The vm must be attached to the current thread before being passed to this function. For example:

+
mApp->activity->vm->AttachCurrentThread(&mJniEnv, NULL);
+FMOD_Android_JNI_Init(mApp->activity->vm, mApp->activity->clazz);
+
+ +

See Also: Java

+ + +
+ + + diff --git a/FMOD/doc/FMOD API User Manual/core-api-platform-html5.html b/FMOD/doc/FMOD API User Manual/core-api-platform-html5.html new file mode 100644 index 0000000..585c3b6 --- /dev/null +++ b/FMOD/doc/FMOD API User Manual/core-api-platform-html5.html @@ -0,0 +1,302 @@ + + +Core API Reference | HTML5 Specific + + + + +
+ +
+

11. Core API Reference | HTML5 Specific

+

APIs and types for HTML5 platform.

+
    +
  • FS_createPreloadedFile Mounts a local file so that FMOD can recognize it when calling a function that uses a filename. Should be called in prerun.
  • +
  • ReadFile Read the entire contents of a file into a memory variable, as preloaded by FS_createPreloadedFile.
  • +
  • Memory_Free Free memory allocated by FMOD internally in ReadFile.
  • +
  • file_open Helper function to open a file that was preloaded by FS_createPreloadedFile.
  • +
  • file_close Helper function to close a file manually that was preloaded with FS_createPreloadedFile.
  • +
  • file_read Helper function to read from a file that was preloaded with FS_createPreloadedFile.
  • +
  • file_seek Helper function to seek a file manually that was preloaded with FS_createPreloadedFile.
  • +
  • getValue Retrieve a value from a specific FMOD memory address.
  • +
  • setValue Store a value at a specific FMOD memory address.
  • +
+

FS_createPreloadedFile

+

Mounts a local file so that FMOD can recognize it when calling a function that uses a filename. Should be called in prerun.

+

+

+
JS
+
+

+
FS_createPreloadedFile(ptr, value, type);
+
+ +
+
parent
+
Parent folder path. (UTF-8 string)
+
name
+
The name of the new file. (UTF-8 string)
+
url
+
Local (real) file system path the contents will be loaded from (UTF-8 string).
+
canRead
+
+

Whether the file should have read permissions set from the program’s point of view.

+
    +
  • Units: Boolean
  • +
+
+
canWrite
+
+

Whether the file should have write permissions set from the program’s point of view.

+
    +
  • Units: Boolean
  • +
+
+
+

Example usage.

+
function prerun()
+{
+    var fileUrl = "/public/js/";
+    var fileName = "Master.Bank";
+    var folderName = "/";
+
+    FMOD.FS_createPreloadedFile(folderName, fileName, fileUrl + fileName, true, false);
+}
+
+ +

Wrapper for the emscripten function.

+

See Also: ReadFile

+

ReadFile

+

Read the entire contents of a file into a memory variable, as preloaded by FS_createPreloadedFile.

+

+

+
JS
+
+

+
ReadFile(system, value, type);
+
+ +
+
system
+
System object handle.
+
filename
+
Filename of the file that is to be loaded, that has the path and filename that matches the preloaded path/filename if loaded in that fashion.
+
output Out
+
Output object containing 'val' and 'length'. Val contains memory that can be passed to FMOD functions like System::createSound (using FMOD_OPENMEMORY ) or Studio::System::loadBankMemory.
+
+

Example usage.

+
result = FMOD.ReadFile(gSystemCore, "/" + filename, outval);
+CHECK_RESULT(result);
+
+memoryPtr    = outval.val;      // Pointer to FMOD owned file data. See below where FMOD.Memory_Free is used to free it.
+memoryLength = outval.length;   // Length of FMOD owned file data
+
+result = gSystem.loadBankMemory(memoryPtr, memoryLength, FMOD.STUDIO_LOAD_MEMORY, FMOD.STUDIO_LOAD_BANK_NONBLOCKING, outval);
+CHECK_RESULT(result);
+
+ +

Call Memory_Free on the variable after using it.

+

Memory_Free

+

Free memory allocated by FMOD internally in ReadFile.

+

+

+
JS
+
+

+
Memory_Free(ptr);
+
+ +
+
ptr
+
Number representing the FMOD buffer address from the ReadFile function.
+
+

See Also: ReadFile

+

file_open

+

Helper function to open a file that was preloaded by FS_createPreloadedFile.

+

+

+
JS
+
+

+
file_open(system, filename, filesize, handle);
+
+ +
+
system
+
System object handle.
+
filename
+
path and filename which matches the path/filename set up in FMOD.FS_createPreloadedFile. (UTF-8 string)
+
filesize Out
+
An object with the calculated size of the file stored in filesize.val.
+
handle Out
+
An object with the file handle stored in handle.val.
+
+

See Also: file_close, file_read, file_seek

+

file_close

+

Helper function to close a file manually that was preloaded with FS_createPreloadedFile.

+

+

+
JS
+
+

+
file_close(handle);
+
+ +
+
handle
+
Handle returned by the file_open function.
+
+

See Also: file_read, file_seek

+

file_read

+

Helper function to read from a file that was preloaded with FS_createPreloadedFile.

+

+

+
JS
+
+

+
file_read(handle, buffer, sizebytes, bytesread);
+
+ +
+
handle
+
Handle returned by the file_open function.
+
buffer
+
A memory address that would come from FMOD, such as that from an FMOD callback or Sound::lock.
+
sizebytes
+
Integer value with the number of bytes requested to be read from the file handle.
+
bytesread Out
+
An object with the number of bytes actually read stored in bytesread.val.
+
+

See Also: file_open, file_close, file_seek

+

file_seek

+

Helper function to seek a file manually that was preloaded with FS_createPreloadedFile.

+

+

+
JS
+
+

+
file_seek(handle, pos);
+
+ +
+
handle
+
Handle returned by file_open function.
+
pos
+
offset in bytes to seek into the file, relative to the start.
+
+

See Also: file_close, file_read

+

setValue

+

Store a value at a specific FMOD memory address.

+

+

+
JS
+
+

+
setValue(ptr, value, type);
+
+ +
+
ptr
+
Number representing the FMOD buffer address.
+
value
+
The value to be stored.
+
type
+
value type specified as a string. ie 'i8', 'i16', 'i32', 'i64', 'float', 'double'. (UTF-8 string)
+
+

Example usage.

+
for (var samp = 0; samp < length; samp++)
+{
+    for (var chan = 0; chan < outchannels; chan++)
+    {
+        // This DSP filter just halves the volume! Input is modified, and sent to output.
+        let val = FMOD.getValue(inbuffer + (((samp * inchannels) + chan) * 4), 'float') * dsp_state.plugindata.volume_linear;
+
+        FMOD.setValue(outbuffer + (((samp * outchannels) + chan) * 4), val, 'float');
+    }
+}
+
+ +

Wrapper for the emscripten function.

+

See Also: getValue

+

getValue

+

Retrieve a value from a specific FMOD memory address.

+

+

+
JS
+
+

+
getValue(ptr, value);
+
+ +
+
ptr
+
Number representing the FMOD buffer address.
+
type
+
value type specified as a string. ie 'i8', 'i16', 'i32', 'i64', 'float', 'double'. (UTF-8 string)
+
+

Example usage.

+
for (var samp = 0; samp < length; samp++)
+{
+    for (var chan = 0; chan < outchannels; chan++)
+    {
+        // This DSP filter just halves the volume! Input is modified, and sent to output.
+        let val = FMOD.getValue(inbuffer + (((samp * inchannels) + chan) * 4), 'float') * dsp_state.plugindata.volume_linear;
+
+        FMOD.setValue(outbuffer + (((samp * outchannels) + chan) * 4), val, 'float');
+    }
+}
+
+ +

Wrapper for the emscripten function.

+

Return value

+

If this method succeeds, it returns an integer value stored at the specified memory address.

+

See Also: setValue

+

file_seek

+

Helper function to seek a file manually that was preloaded with FS_createPreloadedFile.

+

+

+
JS
+
+

+
file_seek(handle, pos);
+
+ +
+
handle
+
Handle returned by file_open function.
+
pos
+
offset in bytes to seek into the file, relative to the start.
+
+

See Also: file_close, file_read

+ + +
+ + + diff --git a/FMOD/doc/FMOD API User Manual/core-api-platform-ios.html b/FMOD/doc/FMOD API User Manual/core-api-platform-ios.html new file mode 100644 index 0000000..4df2e35 --- /dev/null +++ b/FMOD/doc/FMOD API User Manual/core-api-platform-ios.html @@ -0,0 +1,78 @@ + + +Core API Reference | iOS Specific + + + + +
+ +
+

11. Core API Reference | iOS Specific

+

APIs and types for iOS platform, see fmod_ios.h

+ +

FMOD_AUDIOQUEUE_CODECPOLICY

+

Control whether the sound will use a the dedicated hardware decoder or a software codec.

+

+

+
C
+
C++
+
+

+
typedef enum FMOD_AUDIOQUEUE_CODECPOLICY {
+  FMOD_AUDIOQUEUE_CODECPOLICY_DEFAULT,
+  FMOD_AUDIOQUEUE_CODECPOLICY_SOFTWAREONLY,
+  FMOD_AUDIOQUEUE_CODECPOLICY_HARDWAREONLY
+} FMOD_AUDIOQUEUE_CODECPOLICY;
+
+ +
+

Not supported for C#.

+
+
+

Not supported for JavaScript.

+
+
+
FMOD_AUDIOQUEUE_CODECPOLICY_DEFAULT
+
Try hardware first, if it's in use or prohibited by audio session, try software.
+
FMOD_AUDIOQUEUE_CODECPOLICY_SOFTWAREONLY
+
kAudioQueueHardwareCodecPolicy_UseSoftwareOnly ~ try software, if not available fail.
+
FMOD_AUDIOQUEUE_CODECPOLICY_HARDWAREONLY
+
kAudioQueueHardwareCodecPolicy_UseHardwareOnly ~ try hardware, if not available fail.
+
+

Every devices has a single hardware decoder and unlimited software decoders.

+

See Also: FMOD_CREATESOUNDEXINFO

+ + +
+ + + diff --git a/FMOD/doc/FMOD API User Manual/core-api-reverb3d.html b/FMOD/doc/FMOD API User Manual/core-api-reverb3d.html new file mode 100644 index 0000000..c0f6f6e --- /dev/null +++ b/FMOD/doc/FMOD API User Manual/core-api-reverb3d.html @@ -0,0 +1,432 @@ + + +Core API Reference | Reverb3D + + + + +
+ +
+

11. Core API Reference | Reverb3D

+

An interface that manages virtual 3D reverb spheres. For more information, see the 3D Reverbs section of the Advanced Core API Topics chapter.

+

General:

+ +

Reverb3D::get3DAttributes

+

Retrieves the 3D attributes of a reverb sphere.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
FMOD_RESULT Reverb3D::get3DAttributes(
+  FMOD_VECTOR *position,
+  float *mindistance,
+  float *maxdistance
+);
+
+ +
FMOD_RESULT FMOD_Reverb3D_Get3DAttributes(
+  FMOD_REVERB3D *reverb3d,
+  FMOD_VECTOR *position,
+  float *mindistance,
+  float *maxdistance
+);
+
+ +
RESULT Reverb3D.get3DAttributes(
+  ref VECTOR position,
+  ref float mindistance,
+  ref float maxdistance
+);
+
+ +
Reverb3D.get3DAttributes(
+  position,
+  mindistance,
+  maxdistance
+);
+
+ +
+
position OutOpt
+
Position in 3D space represnting the center of the reverb. (FMOD_VECTOR)
+
mindistance OutOpt
+
Distance from the centerpoint within which the reverb will have full effect.
+
maxdistance OutOpt
+
Distance from the centerpoint beyond which the reverb will have no effect.
+
+

For more information, see the 3D Reverbs section of the Advanced Core API Topics chapter.

+

See Also: Reverb3D::set3DAttributes

+

Reverb3D::getActive

+

Retrieves the active state.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
FMOD_RESULT Reverb3D::getActive(
+  bool *active
+);
+
+ +
FMOD_RESULT FMOD_Reverb3D_GetActive(
+  FMOD_REVERB3D *reverb3d,
+  FMOD_BOOL *active
+);
+
+ +
RESULT Reverb3D.getActive(
+  out bool active
+);
+
+ +
Reverb3D.getActive(
+  active
+);
+
+ +
+
active Out
+
+

Active state of the reverb sphere.

+
    +
  • Units: Boolean
  • +
  • Default: True
  • +
+
+
+

For more information, see the 3D Reverbs section of the Advanced Core API Topics chapter.

+

See Also: Reverb3D::setActive

+

Reverb3D::getProperties

+

Retrieves the environmental properties of a reverb sphere.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
FMOD_RESULT Reverb3D::getProperties(
+  FMOD_REVERB_PROPERTIES *properties
+);
+
+ +
FMOD_RESULT FMOD_Reverb3D_GetProperties(
+  FMOD_REVERB3D *reverb3d,
+  FMOD_REVERB_PROPERTIES *properties
+);
+
+ +
RESULT Reverb3D.getProperties(
+  ref REVERB_PROPERTIES properties
+);
+
+ +
Reverb3D.getProperties(
+  properties
+);
+
+ +
+
properties Out
+
Reverb properties. (FMOD_REVERB_PROPERTIES)
+
+

For more information, see the 3D Reverbs section of the Advanced Core API Topics chapter.

+

See Also: Reverb3D::setProperties

+

Reverb3D::getUserData

+

Retrieves a user value associated with this object.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
FMOD_RESULT Reverb3D::getUserData(
+  void **userdata
+);
+
+ +
FMOD_RESULT FMOD_Reverb3D_GetUserData(
+  FMOD_REVERB3D *reverb3d,
+  void **userdata
+);
+
+ +
RESULT Reverb3D.getUserData(
+  out IntPtr userdata
+);
+
+ +
Reverb3D.getUserData(
+  userdata
+);
+
+ +
+
userdata Out
+
User data set by calling Reverb3D::setUserData.
+
+

This function allows arbitrary user data to be retrieved from this object. See the User Data section of the glossary for an example of how to get and set user data.

+

See Also: 3D Reverbs.

+

Reverb3D::release

+

Releases the memory for a reverb object and makes it inactive.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
FMOD_RESULT Reverb3D::release();
+
+ +
FMOD_RESULT FMOD_Reverb3D_Release(FMOD_REVERB3D *reverb3d);
+
+ +
RESULT Reverb3D.release();
+
+ +
Reverb3D.release();
+
+ +

If you release all Reverb3D objects and have not added a new Reverb3D object, System::setReverbProperties should be called to reset the reverb properties.

+

See Also: System::createReverb3D

+

Reverb3D::set3DAttributes

+

Sets the 3D attributes of a reverb sphere.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
FMOD_RESULT Reverb3D::set3DAttributes(
+  const FMOD_VECTOR *position,
+  float mindistance,
+  float maxdistance
+);
+
+ +
FMOD_RESULT FMOD_Reverb3D_Set3DAttributes(
+  FMOD_REVERB3D *reverb3d,
+  const FMOD_VECTOR *position,
+  float mindistance,
+  float maxdistance
+);
+
+ +
RESULT Reverb3D.set3DAttributes(
+  ref VECTOR position,
+  float mindistance,
+  float maxdistance
+);
+
+ +
Reverb3D.set3DAttributes(
+  position,
+  mindistance,
+  maxdistance
+);
+
+ +
+
position Opt
+
+

Position in 3D space represnting the center of the reverb. (FMOD_VECTOR)

+ +
+
mindistance
+
+

Distance from the centerpoint within which the reverb will have full effect.

+ +
+
maxdistance
+
+

Distance from the centerpoint beyond which the reverb will have no effect.

+ +
+
+

For more information, see the 3D Reverbs section of the Advanced Core API Topics chapter.

+

When the position of the listener is less than maxdistance away from the position of one or more reverb objects, the listener's 3D reverb properties are a weighted combination of those reverb objects. Otherwise, the reverb DSP will use the global reverb settings.

+

See Also: Reverb3D::get3DAttributes

+

Reverb3D::setActive

+

Sets the active state.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
FMOD_RESULT Reverb3D::setActive(
+  bool active
+);
+
+ +
FMOD_RESULT FMOD_Reverb3D_SetActive(
+  FMOD_REVERB3D *reverb3d,
+  FMOD_BOOL active
+);
+
+ +
RESULT Reverb3D.setActive(
+  bool active
+);
+
+ +
Reverb3D.setActive(
+  active
+);
+
+ +
+
active
+
+

Active state of the reverb sphere.

+
    +
  • Units: Boolean
  • +
  • Default: True
  • +
+
+
+

For more information, see the 3D Reverbs section of the Advanced Core API Topics chapter.

+

See Also: Reverb3D::getActive

+

Reverb3D::setProperties

+

Sets the environmental properties of a reverb sphere.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
FMOD_RESULT Reverb3D::setProperties(
+  const FMOD_REVERB_PROPERTIES *properties
+);
+
+ +
FMOD_RESULT FMOD_Reverb3D_SetProperties(
+  FMOD_REVERB3D *reverb3d,
+  const FMOD_REVERB_PROPERTIES *properties
+);
+
+ +
RESULT Reverb3D.setProperties(
+  ref REVERB_PROPERTIES properties
+);
+
+ +
Reverb3D.setProperties(
+  properties
+);
+
+ +
+
properties
+
Reverb properties. (FMOD_REVERB_PROPERTIES)
+
+

Fore more information, see the 3D Reverbs section of the Advanced Core API Topics chapter.

+

Reverb presets are available, see FMOD_REVERB_PRESETS.

+

See Also: Reverb3D::getProperties

+

Reverb3D::setUserData

+

Sets a user value associated with this object.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
FMOD_RESULT Reverb3D::setUserData(
+  void *userdata
+);
+
+ +
FMOD_RESULT FMOD_Reverb3D_SetUserData(
+  FMOD_REVERB3D *reverb3d,
+  void *userdata
+);
+
+ +
RESULT Reverb3D.setUserData(
+  IntPtr userdata
+);
+
+ +
Reverb3D.setUserData(
+  userdata
+);
+
+ +
+
userdata
+
Value stored on this object.
+
+

This function allows arbitrary user data to be attached to this object. See the User Data section of the glossary for an example of how to get and set user data.

+

See Also: Reverb3D::getUserData

+ + +
+ + + diff --git a/FMOD/doc/FMOD API User Manual/core-api-sound.html b/FMOD/doc/FMOD API User Manual/core-api-sound.html new file mode 100644 index 0000000..576ff4f --- /dev/null +++ b/FMOD/doc/FMOD API User Manual/core-api-sound.html @@ -0,0 +1,3056 @@ + + +Core API Reference | Sound + + + + +
+ +
+

11. Core API Reference | Sound

+

Container for sample data that can be played on a Channel.

+

Create with System::createSound or System::createStream.

+

Format information:

+ +
+
    +
  • FMOD_TAG Tag data / metadata description.
  • +
+
+
    +
  • FMOD_SOUND_TYPE Recognized audio formats that can be loaded into a Sound.
  • +
  • FMOD_SOUND_FORMAT These definitions describe the native format of the hardware or software buffer that will be used.
  • +
  • FMOD_TAGTYPE List of tag data / metadata types that could be stored within a sound. These include id3 tags, metadata from netstreams and vorbis/asf data.
  • +
  • FMOD_TAGDATATYPE List of tag data / metadata types.
  • +
+

Defaults when played:

+ +

Relationship management:

+ +

Data reading:

+
    +
  • Sound::getOpenState Retrieves the state a sound is in after being opened with the non blocking flag, or the current state of the streaming buffer.
  • +
  • Sound::readData Reads data from an opened sound to a specified buffer, using FMOD's internal codecs.
  • +
  • Sound::seekData Seeks a sound for use with data reading, using FMOD's internal codecs.
  • +
  • Sound::lock Gives access to a portion or all the sample data of a sound for direct manipulation.
  • +
  • Sound::unlock Finalizes a previous sample data lock and submits it back to the Sound object.
  • +
+
+
    +
  • FMOD_OPENSTATE These values describe what state a sound is in after FMOD_NONBLOCKING has been used to open it.
  • +
+

Music:

+ +

Synchronization / markers:

+ +

General:

+ +
+ +

FMOD_OPENSTATE

+

These values describe what state a sound is in after FMOD_NONBLOCKING has been used to open it.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
typedef enum FMOD_OPENSTATE {
+  FMOD_OPENSTATE_READY,
+  FMOD_OPENSTATE_LOADING,
+  FMOD_OPENSTATE_ERROR,
+  FMOD_OPENSTATE_CONNECTING,
+  FMOD_OPENSTATE_BUFFERING,
+  FMOD_OPENSTATE_SEEKING,
+  FMOD_OPENSTATE_PLAYING,
+  FMOD_OPENSTATE_SETPOSITION,
+  FMOD_OPENSTATE_MAX
+} FMOD_OPENSTATE;
+
+ +
enum OPENSTATE : int
+{
+  READY,
+  LOADING,
+  ERROR,
+  CONNECTING,
+  BUFFERING,
+  SEEKING,
+  PLAYING,
+  SETPOSITION,
+  MAX
+}
+
+ +
FMOD.OPENSTATE_READY
+FMOD.OPENSTATE_LOADING
+FMOD.OPENSTATE_ERROR
+FMOD.OPENSTATE_CONNECTING
+FMOD.OPENSTATE_BUFFERING
+FMOD.OPENSTATE_SEEKING
+FMOD.OPENSTATE_PLAYING
+FMOD.OPENSTATE_SETPOSITION
+FMOD.OPENSTATE_MAX
+
+ +
+
FMOD_OPENSTATE_READY
+
Opened and ready to play.
+
FMOD_OPENSTATE_LOADING
+
Initial load in progress.
+
FMOD_OPENSTATE_ERROR
+
Failed to open - file not found, out of memory etc. See return value of Sound::getOpenState for what happened.
+
FMOD_OPENSTATE_CONNECTING
+
Connecting to remote host (internet sounds only).
+
FMOD_OPENSTATE_BUFFERING
+
Buffering data.
+
FMOD_OPENSTATE_SEEKING
+
Seeking to subsound and re-flushing stream buffer.
+
FMOD_OPENSTATE_PLAYING
+
Ready and playing, but not possible to release at this time without stalling the main thread.
+
FMOD_OPENSTATE_SETPOSITION
+
Seeking within a stream to a different position.
+
FMOD_OPENSTATE_MAX
+
Maximum number of open state types.
+
+

With streams, if you are using FMOD_NONBLOCKING, note that if the user calls Sound::getSubSound, a stream will go into FMOD_OPENSTATE_SEEKING state and sound related commands will return FMOD_ERR_NOTREADY.

+

With streams, if you are using FMOD_NONBLOCKING, note that if the user calls Channel::getPosition, a stream will go into FMOD_OPENSTATE_SETPOSITION state and sound related commands will return FMOD_ERR_NOTREADY.

+

See Also: Sound::getOpenState, FMOD_MODE

+

Sound::addSyncPoint

+

Adds a sync point at a specific time within the sound.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
FMOD_RESULT Sound::addSyncPoint(
+  unsigned int offset,
+  FMOD_TIMEUNIT offsettype,
+  const char *name,
+  FMOD_SYNCPOINT **point
+);
+
+ +
FMOD_RESULT FMOD_Sound_AddSyncPoint(
+  FMOD_SOUND *sound,
+  unsigned int offset,
+  FMOD_TIMEUNIT offsettype,
+  const char *name,
+  FMOD_SYNCPOINT **point
+);
+
+ +
RESULT Sound.addSyncPoint(
+  uint offset,
+  TIMEUNIT offsettype,
+  string name,
+  out IntPtr point
+);
+
+ +
Sound.addSyncPoint(
+  offset,
+  offsettype,
+  name,
+  point
+);
+
+ +
+
offset
+
Offset value.
+
offsettype
+
offset unit type. (FMOD_TIMEUNIT)
+
name Opt
+
Sync point name. (UTF-8 string)
+
point OutOpt
+
Sync point. (FMOD_SYNCPOINT)
+
+

For more information on sync points see Sync Points.

+

See Also: Sound::getNumSyncPoints, Sound::getSyncPoint, Sound::getSyncPointInfo, Sound::deleteSyncPoint

+

Sound::deleteSyncPoint

+

Deletes a sync point within the sound.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
FMOD_RESULT Sound::deleteSyncPoint(
+  FMOD_SYNCPOINT *point
+);
+
+ +
FMOD_RESULT FMOD_Sound_DeleteSyncPoint(
+  FMOD_SOUND *sound,
+  FMOD_SYNCPOINT *point
+);
+
+ +
RESULT Sound.deleteSyncPoint(
+  IntPtr point
+);
+
+ +
Sound.deleteSyncPoint(
+  point
+);
+
+ +
+
point
+
Sync point. (FMOD_SYNCPOINT)
+
+

For for more information on sync points see Sync Points.

+

See Also: Sound::addSyncPoint, Sound::getNumSyncPoints, Sound::getSyncPoint

+

FMOD_SOUND_FORMAT

+

These definitions describe the native format of the hardware or software buffer that will be used.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
typedef enum FMOD_SOUND_FORMAT {
+  FMOD_SOUND_FORMAT_NONE,
+  FMOD_SOUND_FORMAT_PCM8,
+  FMOD_SOUND_FORMAT_PCM16,
+  FMOD_SOUND_FORMAT_PCM24,
+  FMOD_SOUND_FORMAT_PCM32,
+  FMOD_SOUND_FORMAT_PCMFLOAT,
+  FMOD_SOUND_FORMAT_BITSTREAM,
+  FMOD_SOUND_FORMAT_MAX
+} FMOD_SOUND_FORMAT;
+
+ +
enum SOUND_FORMAT
+{
+  NONE,
+  PCM8,
+  PCM16,
+  PCM24,
+  PCM32,
+  PCMFLOAT,
+  BITSTREAM,
+  MAX
+}
+
+ +
FMOD.SOUND_FORMAT_NONE
+FMOD.SOUND_FORMAT_PCM8
+FMOD.SOUND_FORMAT_PCM16
+FMOD.SOUND_FORMAT_PCM24
+FMOD.SOUND_FORMAT_PCM32
+FMOD.SOUND_FORMAT_PCMFLOAT
+FMOD.SOUND_FORMAT_BITSTREAM
+FMOD.SOUND_FORMAT_MAX
+
+ +
+
FMOD_SOUND_FORMAT_NONE
+
Uninitalized / unknown.
+
FMOD_SOUND_FORMAT_PCM8
+
8bit integer PCM data.
+
FMOD_SOUND_FORMAT_PCM16
+
16bit integer PCM data.
+
FMOD_SOUND_FORMAT_PCM24
+
24bit integer PCM data.
+
FMOD_SOUND_FORMAT_PCM32
+
32bit integer PCM data.
+
FMOD_SOUND_FORMAT_PCMFLOAT
+
32bit floating point PCM data.
+
FMOD_SOUND_FORMAT_BITSTREAM
+
Sound data is in its native compressed format. See FMOD_CREATECOMPRESSEDSAMPLE
+
FMOD_SOUND_FORMAT_MAX
+
Maximum number of sound formats supported.
+
+

FMOD expects all PCM data referred to by FMOD_SOUND_FORMAT to be little endian, and integer PCM data to be signed.

+

See Also: System::createSound, Sound::getFormat

+

Sound::get3DConeSettings

+

Retrieves the inside and outside angles of the 3D projection cone and the outside volume.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
FMOD_RESULT Sound::get3DConeSettings(
+  float *insideconeangle,
+  float *outsideconeangle,
+  float *outsidevolume
+);
+
+ +
FMOD_RESULT FMOD_Sound_Get3DConeSettings(
+  FMOD_SOUND *sound,
+  float *insideconeangle,
+  float *outsideconeangle,
+  float *outsidevolume
+);
+
+ +
RESULT Sound.get3DConeSettings(
+  out float insideconeangle,
+  out float outsideconeangle,
+  out float outsidevolume
+);
+
+ +
Sound.get3DConeSettings(
+  insideconeangle,
+  outsideconeangle,
+  outsidevolume
+);
+
+ +
+
insideconeangle OutOpt
+
+

Inside cone angle. This is the angle within which the sound is unattenuated.

+
    +
  • Units: Degrees
  • +
  • Range: [0, outsideconeangle]
  • +
  • Default: 360
  • +
+
+
outsideconeangle OutOpt
+
+

Outside cone angle. This is the angle outside of which the sound is attenuated to its outside volume.

+
    +
  • Units: Degrees
  • +
  • Range: [insideconeangle, 360]
  • +
  • Default: 360
  • +
+
+
outsidevolume OutOpt
+
+

Cone outside volume.

+
    +
  • Units: Linear
  • +
  • Range: [0, 1]
  • +
  • Default: 1
  • +
+
+
+

See Also: Sound::set3DConeSettings

+

Sound::get3DCustomRolloff

+

Retrieves the current custom roll-off shape for 3D distance attenuation.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
FMOD_RESULT Sound::get3DCustomRolloff(
+  FMOD_VECTOR **points,
+  int *numpoints
+);
+
+ +
FMOD_RESULT FMOD_Sound_Get3DCustomRolloff(
+  FMOD_SOUND *sound,
+  FMOD_VECTOR **points,
+  int *numpoints
+);
+
+ +
RESULT Sound.get3DCustomRolloff(
+  out IntPtr points,
+  out int numpoints
+);
+
+ +
Sound.get3DCustomRolloff(
+  points,
+  numpoints
+);
+
+ +
+
points OutOpt
+
Array of points sorted by distance where x = distance and y = volume from 0 to 1. (FMOD_VECTOR)
+
numpoints OutOpt
+
Number of points.
+
+

See Also: Sound::set3DCustomRolloff

+

Sound::get3DMinMaxDistance

+

Retrieve the minimum and maximum audible distance for a 3D sound.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
FMOD_RESULT Sound::get3DMinMaxDistance(
+  float *min,
+  float *max
+);
+
+ +
FMOD_RESULT FMOD_Sound_Get3DMinMaxDistance(
+  FMOD_SOUND *sound,
+  float *min,
+  float *max
+);
+
+ +
RESULT Sound.get3DMinMaxDistance(
+  out float min,
+  out float max
+);
+
+ +
Sound.get3DMinMaxDistance(
+  min,
+  max
+);
+
+ +
+
min OutOpt
+
+

Minimum volume distance for the sound.

+ +
+
max OutOpt
+
+

Maximum volume distance for the sound.

+ +
+
+

See Also: Sound::set3DMinMaxDistance

+

Sound::getDefaults

+

Retrieves a sound's default playback attributes.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
FMOD_RESULT Sound::getDefaults(
+  float *frequency,
+  int *priority
+);
+
+ +
FMOD_RESULT FMOD_Sound_GetDefaults(
+  FMOD_SOUND *sound,
+  float *frequency,
+  int *priority
+);
+
+ +
RESULT Sound.getDefaults(
+  out float frequency,
+  out int priority
+);
+
+ +
Sound.getDefaults(
+  frequency,
+  priority
+);
+
+ +
+
frequency OutOpt
+
+

Default playback frequency.

+
    +
  • Units: Hertz
  • +
  • Default: 48000
  • +
+
+
priority OutOpt
+
+

Default priority where 0 is the highest priority.

+
    +
  • Range: [0, 256]
  • +
  • Default: 128
  • +
+
+
+

See Also: Sound::setDefaults

+

Sound::getFormat

+

Returns format information about the sound.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
FMOD_RESULT Sound::getFormat(
+  FMOD_SOUND_TYPE *type,
+  FMOD_SOUND_FORMAT *format,
+  int *channels,
+  int *bits
+);
+
+ +
FMOD_RESULT FMOD_Sound_GetFormat(
+  FMOD_SOUND *sound,
+  FMOD_SOUND_TYPE *type,
+  FMOD_SOUND_FORMAT *format,
+  int *channels,
+  int *bits
+);
+
+ +
RESULT Sound.getFormat(
+  out SOUND_TYPE type,
+  out SOUND_FORMAT format,
+  out int channels,
+  out int bits
+);
+
+ +
Sound.getFormat(
+  type,
+  format,
+  channels,
+  bits
+);
+
+ +
+
type OutOpt
+
Type of sound. (FMOD_SOUND_TYPE)
+
format OutOpt
+
Format of the sound. (FMOD_SOUND_FORMAT)
+
channels OutOpt
+
Number of channels.
+
bits OutOpt
+
Number of bits per sample, corresponding to format.
+
+

Sound::getLength

+

Retrieves the length using the specified time unit.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
FMOD_RESULT Sound::getLength(
+  unsigned int *length,
+  FMOD_TIMEUNIT lengthtype
+);
+
+ +
FMOD_RESULT FMOD_Sound_GetLength(
+  FMOD_SOUND *sound,
+  unsigned int *length,
+  FMOD_TIMEUNIT lengthtype
+);
+
+ +
RESULT Sound.getLength(
+  out uint length,
+  TIMEUNIT lengthtype
+);
+
+ +
Sound.getLength(
+  length,
+  lengthtype
+);
+
+ +
+
length Out
+
Sound length in units specified by lengthtype.
+
lengthtype
+
Time unit type to retrieve into length. (FMOD_TIMEUNIT)
+
+

lengthtype must be valid for the file format. For example, an MP3 file does not support FMOD_TIMEUNIT_MODORDER.

+

A length of 0xFFFFFFFF means it is of unlimited length, such as an internet radio stream or MOD/S3M/XM/IT file which may loop forever.

+

Note: Using a VBR (Variable Bit Rate) source that does not have metadata containing its accurate length (such as un-tagged MP3 or MOD/S3M/XM/IT) may return inaccurate length values.
+For these formats, use FMOD_ACCURATETIME when creating the sound. This will cause a slight delay and memory increase, as FMOD will scan the whole during creation to find the correct length. This flag also creates a seek table to enable sample accurate seeking.

+

See Also: System::createSound

+

Sound::getLoopCount

+

Retrieves the sound's loop count.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
FMOD_RESULT Sound::getLoopCount(
+  int *loopcount
+);
+
+ +
FMOD_RESULT FMOD_Sound_GetLoopCount(
+  FMOD_SOUND *sound,
+  int *loopcount
+);
+
+ +
RESULT Sound.getLoopCount(
+  out int loopcount
+);
+
+ +
Sound.getLoopCount(
+  loopcount
+);
+
+ +
+
loopcount Out
+
+

Number of times to loop before final playback where -1 is always loop. 0 means no loop.

+
    +
  • Range: [-1, inf)
  • +
  • Default: -1
  • +
+
+
+

Unlike the Channel loop count function, this function simply returns the value set with Sound::setLoopCount. It does not decrement as it plays (especially seeing as one sound can be played multiple times).

+

See Also: Sound::setLoopCount, Channel::setLoopCount

+

Sound::getLoopPoints

+

Retrieves the loop points for a sound.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
FMOD_RESULT Sound::getLoopPoints(
+  unsigned int *loopstart,
+  FMOD_TIMEUNIT loopstarttype,
+  unsigned int *loopend,
+  FMOD_TIMEUNIT loopendtype
+);
+
+ +
FMOD_RESULT FMOD_Sound_GetLoopPoints(
+  FMOD_SOUND *sound,
+  unsigned int *loopstart,
+  FMOD_TIMEUNIT loopstarttype,
+  unsigned int *loopend,
+  FMOD_TIMEUNIT loopendtype
+);
+
+ +
RESULT Sound.getLoopPoints(
+  out uint loopstart,
+  TIMEUNIT loopstarttype,
+  out uint loopend,
+  TIMEUNIT loopendtype
+);
+
+ +
Sound.getLoopPoints(
+  loopstart,
+  loopstarttype,
+  loopend,
+  loopendtype
+);
+
+ +
+
loopstart OutOpt
+
Loop start point.
+
loopstarttype
+
Time format of loopstart. (FMOD_TIMEUNIT)
+
loopend OutOpt
+
Loop end point.
+
loopendtype
+
Time format of loopend. (FMOD_TIMEUNIT)
+
+

The values from loopstart and loopend are inclusive, which means these positions will be played.

+

See Also: Sound::setLoopPoints

+

Sound::getMode

+

Retrieves the mode of a sound.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
FMOD_RESULT Sound::getMode(
+  FMOD_MODE *mode
+);
+
+ +
FMOD_RESULT FMOD_Sound_GetMode(
+  FMOD_SOUND *sound,
+  FMOD_MODE *mode
+);
+
+ +
RESULT Sound.getMode(
+  out MODE mode
+);
+
+ +
Sound.getMode(
+  mode
+);
+
+ +
+
mode Out
+
Current mode. (FMOD_MODE)
+
+

The mode will be dependent on the mode set by a call to System::createSound, System::createStream or Sound::setMode.

+

See Also: ChannelControl::setMode, ChannelControl::getMode

+

Sound::getMusicChannelVolume

+

Retrieves the volume of a MOD/S3M/XM/IT/MIDI music channel volume.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
FMOD_RESULT Sound::getMusicChannelVolume(
+  int channel,
+  float *volume
+);
+
+ +
FMOD_RESULT FMOD_Sound_GetMusicChannelVolume(
+  FMOD_SOUND *sound,
+  int channel,
+  float *volume
+);
+
+ +
RESULT Sound.getMusicChannelVolume(
+  int channel,
+  out float volume
+);
+
+ +
Sound.getMusicChannelVolume(
+  channel,
+  volume
+);
+
+ +
+
channel
+
MOD/S3M/XM/IT/MIDI music subchannel to retrieve the volume for.
+
volume Out
+
+

Volume of the channel.

+
    +
  • Units: Linear
  • +
  • Range: [0, 1]
  • +
  • Default: 1
  • +
+
+
+

See Also: Sound::setMusicChannelVolume

+

Sound::getMusicNumChannels

+

Gets the number of music channels inside a MOD/S3M/XM/IT/MIDI file.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
FMOD_RESULT Sound::getMusicNumChannels(
+  int *numchannels
+);
+
+ +
FMOD_RESULT FMOD_Sound_GetMusicNumChannels(
+  FMOD_SOUND *sound,
+  int *numchannels
+);
+
+ +
RESULT Sound.getMusicNumChannels(
+  out int numchannels
+);
+
+ +
Sound.getMusicNumChannels(
+  numchannels
+);
+
+ +
+
numchannels Out
+
Number of music channels used in the song.
+
+

See Also: Sound::setMusicChannelVolume, Sound::getMusicChannelVolume

+

Sound::getMusicSpeed

+

Gets the relative speed of MOD/S3M/XM/IT/MIDI music.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
FMOD_RESULT Sound::getMusicSpeed(
+  float *speed
+);
+
+ +
FMOD_RESULT FMOD_Sound_GetMusicSpeed(
+  FMOD_SOUND *sound,
+  float *speed
+);
+
+ +
RESULT Sound.getMusicSpeed(
+  out float speed
+);
+
+ +
Sound.getMusicSpeed(
+  speed
+);
+
+ +
+
speed Out
+
Speed of the song.
+
+

See Also: Sound::setMusicSpeed

+

Sound::getName

+

Retrieves the name of a sound.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
FMOD_RESULT Sound::getName(
+  char *name,
+  int namelen
+);
+
+ +
FMOD_RESULT FMOD_Sound_GetName(
+  FMOD_SOUND *sound,
+  char *name,
+  int namelen
+);
+
+ +
RESULT Sound.getName(
+  out string name,
+  int namelen
+);
+
+ +
Sound.getName(
+  name
+);
+
+ +
+
name Out
+
Name of the sound. (UTF-8 string)
+
namelen
+
+

Length of buffer to receive name.

+
    +
  • Units: Bytes
  • +
+
+
+

if FMOD_LOWMEM has been specified in System::createSound, this function will return "(null)".

+

Sound::getNumSubSounds

+

Retrieves the number of subsounds stored within a sound.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
FMOD_RESULT Sound::getNumSubSounds(
+  int *numsubsounds
+);
+
+ +
FMOD_RESULT FMOD_Sound_GetNumSubSounds(
+  FMOD_SOUND *sound,
+  int *numsubsounds
+);
+
+ +
RESULT Sound.getNumSubSounds(
+  out int numsubsounds
+);
+
+ +
Sound.getNumSubSounds(
+  numsubsounds
+);
+
+ +
+
numsubsounds Out
+
Number of subsounds.
+
+

A format that has subsounds is a container format, such as FSB, DLS, MOD, S3M, XM, IT.

+

See Also: Sound::getSubSound

+

Sound::getNumSyncPoints

+

Retrieves the number of sync points stored within a sound.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
FMOD_RESULT Sound::getNumSyncPoints(
+  int *numsyncpoints
+);
+
+ +
FMOD_RESULT FMOD_Sound_GetNumSyncPoints(
+  FMOD_SOUND *sound,
+  int *numsyncpoints
+);
+
+ +
RESULT Sound.getNumSyncPoints(
+  out int numsyncpoints
+);
+
+ +
Sound.getNumSyncPoints(
+  numsyncpoints
+);
+
+ +
+
numsyncpoints Out
+
Number of sync points.
+
+

For for more information on sync points see Sync Points.

+

See Also: Sound::getSyncPoint, Sound::getSyncPointInfo, Sound::addSyncPoint, Sound::deleteSyncPoint

+

Sound::getNumTags

+

Retrieves the number of metadata tags.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
FMOD_RESULT Sound::getNumTags(
+  int *numtags,
+  int *numtagsupdated
+);
+
+ +
FMOD_RESULT FMOD_Sound_GetNumTags(
+  FMOD_SOUND *sound,
+  int *numtags,
+  int *numtagsupdated
+);
+
+ +
RESULT Sound.getNumTags(
+  out int numtags,
+  out int numtagsupdated
+);
+
+ +
Sound.getNumTags(
+  numtags,
+  numtagsupdated
+);
+
+ +
+
numtags OutOpt
+
Number of tags.
+
numtagsupdated OutOpt
+
Number of tags updated since this function was last called.
+
+

'Tags' are metadata stored within a sound file. These can be things like a song's name, composer etc.

+

numtagsupdated could be periodically checked to see if new tags are available in certain circumstances. This might be the case with internet based streams (i.e. shoutcast or icecast) where the name of the song or other attributes might change.

+

See Also: Sound::getTag

+

Sound::getOpenState

+

Retrieves the state a sound is in after being opened with the non blocking flag, or the current state of the streaming buffer.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
FMOD_RESULT Sound::getOpenState(
+  FMOD_OPENSTATE *openstate,
+  unsigned int *percentbuffered,
+  bool *starving,
+  bool *diskbusy
+);
+
+ +
FMOD_RESULT FMOD_Sound_GetOpenState(
+  FMOD_SOUND *sound,
+  FMOD_OPENSTATE *openstate,
+  unsigned int *percentbuffered,
+  FMOD_BOOL *starving,
+  FMOD_BOOL *diskbusy
+);
+
+ +
RESULT Sound.getOpenState(
+  out OPENSTATE openstate,
+  out uint percentbuffered,
+  out bool starving,
+  out bool diskbusy
+);
+
+ +
Sound.getOpenState(
+  openstate,
+  percentbuffered,
+  starving,
+  diskbusy
+);
+
+ +
+
openstate OutOpt
+
Open state of a sound. (FMOD_OPENSTATE)
+
percentbuffered OutOpt
+
+

Filled percentage of a stream's file buffer.

+
    +
  • Units: Percent
  • +
  • Range: [0, 100]
  • +
+
+
starving OutOpt
+
+

Starving state. true if a stream has decoded more than the stream file buffer has ready.

+
    +
  • Units: Boolean
  • +
+
+
diskbusy OutOpt
+
+

Disk is currently being accessed for this sound.

+
    +
  • Units: Boolean
  • +
+
+
+

When a sound is opened with FMOD_NONBLOCKING, it is opened and prepared in the background, or asynchronously. This allows the main application to execute without stalling on audio loads.
+This function will describe the state of the asynchronous load routine i.e. whether it has succeeded, failed or is still in progress.

+

If 'starving' is true, then you will most likely hear a stuttering/repeating sound as the decode buffer loops on itself and replays old data.
+With the ability to detect stream starvation, muting the sound with ChannelControl::setMute will keep the stream quiet until it is not starving any more.

+

Note: Always check 'openstate' to determine the state of the sound. Do not assume that if this function returns FMOD_OK then the sound has finished loading.

+

See Also: FMOD_MODE

+

Sound::getSoundGroup

+

Retrieves the sound's current sound group.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
FMOD_RESULT Sound::getSoundGroup(
+  SoundGroup **soundgroup
+);
+
+ +
FMOD_RESULT FMOD_Sound_GetSoundGroup(
+  FMOD_SOUND *sound,
+  FMOD_SOUNDGROUP **soundgroup
+);
+
+ +
RESULT Sound.getSoundGroup(
+  out SoundGroup soundgroup
+);
+
+ +
Sound.getSoundGroup(
+  soundgroup
+);
+
+ +
+
soundgroup Out
+
Sound's current sound group. (SoundGroup)
+
+

See Also: Sound::setSoundGroup, System::getMasterSoundGroup

+

Sound::getSubSound

+

Retrieves a handle to a Sound object that is contained within the parent sound.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
FMOD_RESULT Sound::getSubSound(
+  int index,
+  Sound **subsound
+);
+
+ +
FMOD_RESULT FMOD_Sound_GetSubSound(
+  FMOD_SOUND *sound,
+  int index,
+  FMOD_SOUND **subsound
+);
+
+ +
RESULT Sound.getSubSound(
+  int index,
+  out Sound subsound
+);
+
+ +
Sound.getSubSound(
+  index,
+  subsound
+);
+
+ +
+
index
+
+

Index of the subsound.

+ +
+
subsound Out
+
Subsound object. (Sound)
+
+

If the sound is a stream and FMOD_NONBLOCKING was not used, then this call will perform a blocking seek/flush to the specified subsound.

+

If FMOD_NONBLOCKING was used to open this sound and the sound is a stream, FMOD will do a non blocking seek/flush and set the state of the subsound to FMOD_OPENSTATE_SEEKING.

+

The sound won't be ready to be used when FMOD_NONBLOCKING is used, until the state of the sound becomes FMOD_OPENSTATE_READY or FMOD_OPENSTATE_ERROR.

+

See Also: Sound::getSubSoundParent, System::createSound

+

Sound::getSubSoundParent

+

Retrieves the parent Sound object that contains this subsound.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
FMOD_RESULT Sound::getSubSoundParent(
+  Sound **parentsound
+);
+
+ +
FMOD_RESULT FMOD_Sound_GetSubSoundParent(
+  FMOD_SOUND *sound,
+  FMOD_SOUND **parentsound
+);
+
+ +
RESULT Sound.getSubSoundParent(
+  out Sound parentsound
+);
+
+ +
Sound.getSubSoundParent(
+  parentsound
+);
+
+ +
+
parentsound Out
+
Parent sound object. (Sound)
+
+

If the sound is not a subsound, the parentsound will be null.

+

See Also: Sound::getNumSubSounds, Sound::getSubSound

+

Sound::getSyncPoint

+

Retrieve a sync point.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
FMOD_RESULT Sound::getSyncPoint(
+  int index,
+  FMOD_SYNCPOINT **point
+);
+
+ +
FMOD_RESULT FMOD_Sound_GetSyncPoint(
+  FMOD_SOUND *sound,
+  int index,
+  FMOD_SYNCPOINT **point
+);
+
+ +
RESULT Sound.getSyncPoint(
+  int index,
+  out IntPtr point
+);
+
+ +
Sound.getSyncPoint(
+  index,
+  point
+);
+
+ +
+
index
+
+

Index of the sync point.

+ +
+
point Out
+
Sync point. (FMOD_SYNCPOINT)
+
+

For for more information on sync points see Sync Points.

+

See Also: Sound::getNumSyncPoints, Sound::getSyncPointInfo, Sound::addSyncPoint, Sound::deleteSyncPoint

+

Sound::getSyncPointInfo

+

Retrieves information on an embedded sync point.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
FMOD_RESULT Sound::getSyncPointInfo(
+  FMOD_SYNCPOINT *point,
+  char *name,
+  int namelen,
+  unsigned int *offset,
+  FMOD_TIMEUNIT offsettype
+);
+
+ +
FMOD_RESULT FMOD_Sound_GetSyncPointInfo(
+  FMOD_SOUND *sound,
+  FMOD_SYNCPOINT *point,
+  char *name,
+  int namelen,
+  unsigned int *offset,
+  FMOD_TIMEUNIT offsettype
+);
+
+ +
RESULT Sound.getSyncPointInfo(
+  IntPtr point,
+  out string name,
+  int namelen,
+  out uint offset,
+  TIMEUNIT offsettype
+);
+
+ +
Sound.getSyncPointInfo(
+  point,
+  name,
+  namelen,
+  offset,
+  offsettype
+);
+
+ +
+
point
+
Sync point. (FMOD_SYNCPOINT)
+
name OutOpt
+
Name of the syncpoint. (UTF-8 string)
+
namelen
+
+

Size of name.

+
    +
  • Units: Bytes
  • +
+
+
offset OutOpt
+
Offset of the syncpoint.
+
offsettype
+
Format of offset. (FMOD_TIMEUNIT)
+
+

For for more information on sync points see Sync Points.

+

See Also: Sound::getNumSyncPoints, Sound::getSyncPoint, Sound::addSyncPoint, Sound::deleteSyncPoint

+

Sound::getSystemObject

+

Retrieves the parent System object.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
FMOD_RESULT Sound::getSystemObject(
+  System **system
+);
+
+ +
FMOD_RESULT FMOD_Sound_GetSystemObject(
+  FMOD_SOUND *sound,
+  FMOD_SYSTEM **system
+);
+
+ +
RESULT Sound.getSystemObject(
+  out System system
+);
+
+ +
Sound.getSystemObject(
+  system
+);
+
+ +
+
system Out
+
System object. (System)
+
+

See Also: System::createSound

+

Sound::getTag

+

Retrieves a metadata tag.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
FMOD_RESULT Sound::getTag(
+  const char *name,
+  int index,
+  FMOD_TAG *tag
+);
+
+ +
FMOD_RESULT FMOD_Sound_GetTag(
+  FMOD_SOUND *sound,
+  const char *name,
+  int index,
+  FMOD_TAG *tag
+);
+
+ +
RESULT Sound.getTag(
+  string name,
+  int index,
+  out TAG tag
+);
+
+ +
Sound.getTag(
+  name,
+  index,
+  tag
+);
+
+ +
+
name
+
Name of a type of tag to retrieve. (UTF-8 string). Specify null to retrieve all types of tags.
+
index Opt
+
+

Index into the tag list as restricted by name.

+ +
+
tag Out
+
Tag info structure. (FMOD_TAG)
+
+

'Tags' are metadata stored within a sound file. These can be things like a song's name, composer etc.

+

The number of tags available can be found with Sound::getNumTags.

+

The way to display or retrieve tags can be done in 3 different ways:

+
    +
  • All tags can be continuously retrieved by looping from 0 to the numtags value in Sound::getNumTags - 1. Updated tags will refresh automatically, and the 'updated' member of the FMOD_TAG structure will be set to true if a tag has been updated, due to something like a netstream changing the song name for example.
  • +
  • Tags can be retrieved by specifying -1 as the index and only updating tags that are returned. If all tags are retrieved and this function is called the function will return an error of FMOD_ERR_TAGNOTFOUND.
  • +
  • Specific tags can be retrieved by specifying a name parameter. The index can be 0 based or -1 in the same fashion as described previously.
  • +
+

Note with netstreams an important consideration must be made between songs, a tag may occur that changes the playback rate of the song. It is up to the user to catch this and reset the playback rate with Channel::setFrequency.
+A sample rate change will be signalled with a tag of type FMOD_TAGTYPE_FMOD.

+
  FMOD_TAG tag;
+  while (FMOD_Sound_GetTag(sound, 0, -1, &tag) == FMOD_OK)
+  {
+    if (tag.type == FMOD_TAGTYPE_FMOD)
+    {
+        /* When a song changes, the sample rate may also change, so compensate here. */
+        if (!strcmp(tag.name, "Sample Rate Change") && channel)
+        {
+            float frequency = *((float *)tag.data);
+
+            result = FMOD_Channel_SetFrequency(channel, frequency);
+            ERRCHECK(result);
+        }
+    }
+  }
+
+ +
  FMOD_TAG tag;
+  while (sound->getTag(0, -1, &tag) == FMOD_OK)
+  {
+    if (tag.type == FMOD_TAGTYPE_FMOD)
+    {
+        /* When a song changes, the sample rate may also change, so compensate here. */
+        if (!strcmp(tag.name, "Sample Rate Change") && channel)
+        {
+            float frequency = *((float *)tag.data);
+
+            result = channel->setFrequency(frequency);
+            ERRCHECK(result);
+        }
+    }
+  }
+
+ +

Sound::getUserData

+

Retrieves a user value associated with this object.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
FMOD_RESULT Sound::getUserData(
+  void **userdata
+);
+
+ +
FMOD_RESULT FMOD_Sound_GetUserData(
+  FMOD_SOUND *sound,
+  void **userdata
+);
+
+ +
RESULT Sound.getUserData(
+  out IntPtr userdata
+);
+
+ +
Sound.getUserData(
+  userdata
+);
+
+ +
+
userdata Out
+
User data set by calling Sound::setUserData
+
+

This function allows arbitrary user data to be retrieved from this object. See the User Data section of the glossary for an example of how to get and set user data.

+

Sound::lock

+

Gives access to a portion or all the sample data of a sound for direct manipulation.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
FMOD_RESULT Sound::lock(
+  unsigned int offset,
+  unsigned int length,
+  void **ptr1,
+  void **ptr2,
+  unsigned int *len1,
+  unsigned int *len2
+);
+
+ +
FMOD_RESULT FMOD_Sound_Lock(
+  FMOD_SOUND *sound,
+  unsigned int offset,
+  unsigned int length,
+  void **ptr1,
+  void **ptr2,
+  unsigned int *len1,
+  unsigned int *len2
+);
+
+ +
RESULT Sound.lock(
+  uint offset,
+  uint length,
+  out IntPtr ptr1,
+  out IntPtr ptr2,
+  out uint len1,
+  out uint len2
+);
+
+ +
Sound.lock(
+  offset,
+  length,
+  ptr1,
+  ptr2,
+  len1,
+  len2
+);
+
+ +
+
offset
+
+

Offset into the sound's buffer to be retrieved.

+
    +
  • Units: Bytes
  • +
+
+
length
+
+

Length of the data required to be retrieved. If offset + length exceeds the length of the sample buffer, ptr2 and len2 will be valid.

+
    +
  • Units: Bytes
  • +
+
+
ptr1 Out
+
+

First part of the locked data.

+ +
+
ptr2 Out
+
+

Second part of the locked data if the offset + length has exceeded the length of the sample buffer.

+ +
+
len1 Out
+
+

Length of ptr1.

+
    +
  • Units: Bytes
  • +
+
+
len2 Out
+
+

Length of ptr2

+
    +
  • Units: Bytes
  • +
+
+
+

You must always unlock the data again after you have finished with it, using Sound::unlock.

+

With this function you get access to the raw audio data. If the data is 8, 16, 24 or 32bit PCM data, mono or stereo data, you must take this into consideration when processing the data. See Sample Data for more information.

+

If the sound is created with FMOD_CREATECOMPRESSEDSAMPLE the data retrieved will be the compressed bitstream.

+

It is not possible to lock the following:

+ +

The names 'lock'/'unlock' are a legacy reference to older Operating System APIs that used to cause a mutex lock on the data, so that it could not be written to while the 'lock' was in place. This is no longer the case with FMOD and data can be 'locked' multiple times from different places/threads at once.

+

See Also: System::createSound

+

FMOD_SOUND_NONBLOCK_CALLBACK

+

Callback to be called when a sound has finished loading, or a non blocking seek is occuring.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
FMOD_RESULT F_CALL FMOD_SOUND_NONBLOCK_CALLBACK(
+  FMOD_SOUND *sound,
+  FMOD_RESULT result
+);
+
+ +
delegate RESULT SOUND_NONBLOCKCALLBACK(
+  IntPtr sound,
+  RESULT result
+);
+
+ +
+

Not supported for JavaScript.

+
+
+
sound
+
Sound. (Sound)
+
result
+
Error code. (FMOD_RESULT)
+
+

Invoked by:

+ +

Return code currently ignored.

+

Note that for non blocking streams a seek could occur when restarting the sound after the first playthrough. This will result in a callback being triggered again.

+

Since this callback can occur from the async thread, there are restrictions about what functions can be called during the callback. All Sound functions are safe to call, except for Sound::setSoundGroup and Sound::release. It is also safe to call System::getUserData. The rest of the Core API and the Studio API is not allowed. Calling a non-allowed function will return FMOD_ERR_INVALID_THREAD.

+
+

sound can be cast to Sound *.

+
+

See Also: FMOD_CREATESOUNDEXINFO

+

FMOD_SOUND_PCMREAD_CALLBACK

+

Read callback used for user created sounds or to intercept FMOD's decoder during a normal sound open.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
FMOD_RESULT F_CALL FMOD_SOUND_PCMREAD_CALLBACK(
+  FMOD_SOUND *sound,
+  void *data,
+  unsigned int datalen
+);
+
+ +
delegate RESULT SOUND_PCMREADCALLBACK(
+  IntPtr sound,
+  IntPtr data,
+  uint datalen
+);
+
+ +
function FMOD_SOUND_PCMREAD_CALLBACK(
+  sound,
+  data,
+  datalen
+)
+
+ +
+
sound
+
Sound. (Sound)
+
data
+
PCM data that the user can either read or write to.
+
+ +
+
datalen
+
+

Length of the data.

+
    +
  • Units: Bytes
  • +
+
+
+

Invoked by:

+ +

Use cases:

+
    +
  • A FMOD_OPENUSER sound. The callback is used to write PCM data to a user created sound when requested.
  • +
  • During a normal System::createsound or System::createStream, the read callback will be issued with decoded pcm data, allowing it to be manipulated or copied somewhere else. The return value is ignored.
  • +
+

The format of the sound can be retrieved with Sound::getFormat from this callback. This will allow the user to determine what type of pointer to use if they are not sure what format the sound is.

+
+

sound can be cast to Sound *.

+
+

See Also: FMOD_SOUND_PCMSETPOS_CALLBACK, FMOD_CREATESOUNDEXINFO

+

FMOD_SOUND_PCMSETPOS_CALLBACK

+

Set position callback for user created sounds or to intercept FMOD's decoder during an API setPositon call.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
FMOD_RESULT F_CALL FMOD_SOUND_PCMSETPOS_CALLBACK(
+  FMOD_SOUND *sound,
+  int subsound,
+  unsigned int position,
+  FMOD_TIMEUNIT postype
+);
+
+ +
delegate RESULT SOUND_PCMSETPOSCALLBACK(
+  IntPtr sound,
+  int subsound,
+  uint position,
+  TIMEUNIT postype
+);
+
+ +
function FMOD_SOUND_PCMSETPOS_CALLBACK(
+  sound,
+  subsound,
+  position,
+  postype
+)
+
+ +
+
sound
+
Sound. (Sound)
+
subsound
+
In a multi subsound type sound (ie .FSB or .DLS), this will contain the index into the list of sounds.
+
position
+
Requested seek position.
+
postype
+
+

position type, or FMOD_ERR_FORMAT if the sound is a user created sound and the seek type is unsupported. (FMOD_TIMEUNIT)

+ +
+
+

Invoked by:

+ +

Use cases:

+ +
+

sound can be cast to Sound *.

+
+

See Also: FMOD_SOUND_PCMREAD_CALLBACK, FMOD_CREATESOUNDEXINFO

+

Sound::readData

+

Reads data from an opened sound to a specified buffer, using FMOD's internal codecs.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
FMOD_RESULT Sound::readData(
+  void *buffer,
+  unsigned int length,
+  unsigned int *read
+);
+
+ +
FMOD_RESULT FMOD_Sound_ReadData(
+  FMOD_SOUND *sound,
+  void *buffer,
+  unsigned int length,
+  unsigned int *read
+);
+
+ +
RESULT Sound.readData(
+  byte[] buffer
+);
+RESULT Sound.readData(
+  byte[] buffer,
+  out uint read
+);
+
+ +
Sound.readData(
+  buffer,
+  length,
+  read
+);
+
+ +
+
buffer
+
+

Buffer to read decoded data into.

+ +
+
length
+
+

Amount of data to read into buffer.

+
    +
  • Units: Bytes
  • +
+
+
read OutOpt
+
+

Actual amount of data read. May differ to length.

+
    +
  • Units: Bytes
  • +
+
+
+

This can be used for decoding data offline in small pieces (or big pieces), rather than playing and capturing it, or loading the whole file at once and having to Sound::lock / Sound::unlock the data.

+

If too much data is read, it is possible FMOD_ERR_FILE_EOF will be returned, meaning it is out of data. The 'read' parameter will reflect this by returning a smaller number of bytes read than was requested.

+

As a non streaming sound reads and decodes the whole file then closes it upon calling System::createSound, Sound::readData will then not work because the file handle is closed. Use FMOD_OPENONLY to stop FMOD reading/decoding the file.
+If FMOD_OPENONLY flag is used when opening a sound, it will leave the file handle open, and FMOD will not read/decode any data internally, so the read cursor will stay at position 0. This will allow the user to read the data from the start.

+

For streams, the streaming engine will decode a small chunk of data and this will advance the read cursor. You need to either use FMOD_OPENONLY to stop the stream pre-buffering or call Sound::seekData to reset the read cursor back to the start of the file, otherwise it will appear as if the start of the stream is missing.
+Channel::setPosition will have the same result. These functions will flush the stream buffer and read in a chunk of audio internally. This is why if you want to read from an absolute position you should use Sound::seekData and not the previously mentioned functions.

+

If you are calling Sound::readData and Sound::seekData on a stream, information functions such as Channel::getPosition may give misleading results. Calling Channel::setPosition will cause the streaming engine to reset and flush the stream, leading to the time values returning to their correct position.

+

NOTE! Thread safety. If you call this from another stream callback, or any other thread besides the main thread, make sure to mutex the callback with Sound::release in case the sound is still being read from while releasing.

+

This function is thread safe to call from a stream callback or different thread as long as it doesnt conflict with a call to Sound::release.

+

See Also: Extracting PCM Data from a Sound, Sound::lock, Sound::unlock

+

Sound::release

+

Frees a sound object.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
FMOD_RESULT Sound::release();
+
+ +
FMOD_RESULT FMOD_Sound_Release(FMOD_SOUND *sound);
+
+ +
RESULT Sound.release();
+
+ +
Sound.release();
+
+ +

This will stop any instances of this sound, and free the sound object and its children if it is a multi-sound object.

+

If the sound was opened with FMOD_NONBLOCKING and hasn't finished opening yet, it will block. Additionally, if the sound is still playing or has recently been stopped, the release may stall, as the mixer may still be using the sound. Using Sound::getOpenState and checking the open state for FMOD_OPENSTATE_READY and FMOD_OPENSTATE_ERROR is a good way to avoid stalls.

+

See Also: System::createSound, Sound::getSubSound

+

Sound::seekData

+

Seeks a sound for use with data reading, using FMOD's internal codecs.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
FMOD_RESULT Sound::seekData(
+  unsigned int pcm
+);
+
+ +
FMOD_RESULT FMOD_Sound_SeekData(
+  FMOD_SOUND *sound,
+  unsigned int pcm
+);
+
+ +
RESULT Sound.seekData(
+  uint pcm
+);
+
+ +
Sound.seekData(
+  pcm
+);
+
+ +
+
pcm
+
+

Seek Offset.

+
    +
  • Units: Samples
  • +
+
+
+

For use in conjunction with Sound::readData and FMOD_OPENONLY.

+

For streaming sounds, if this function is called, it will advance the internal file pointer but not update the streaming engine. This can lead to de-synchronization of position information for the stream and audible playback.

+

A stream can reset its stream buffer and position synchronization by calling Channel::setPosition. This causes reset and flush of the stream buffer.

+

Sound::set3DConeSettings

+

Sets the angles and attenuation levels of a 3D cone shape, for simulated occlusion which is based on direction.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
FMOD_RESULT Sound::set3DConeSettings(
+  float insideconeangle,
+  float outsideconeangle,
+  float outsidevolume
+);
+
+ +
FMOD_RESULT FMOD_Sound_Set3DConeSettings(
+  FMOD_SOUND *sound,
+  float insideconeangle,
+  float outsideconeangle,
+  float outsidevolume
+);
+
+ +
RESULT Sound.set3DConeSettings(
+  float insideconeangle,
+  float outsideconeangle,
+  float outsidevolume
+);
+
+ +
Sound.set3DConeSettings(
+  insideconeangle,
+  outsideconeangle,
+  outsidevolume
+);
+
+ +
+
insideconeangle
+
+

Inside cone angle. This is the angle spread within which the sound is unattenuated.

+
    +
  • Units: Degrees
  • +
  • Range: [0, outsideconeangle]
  • +
  • Default: 360
  • +
+
+
outsideconeangle
+
+

Outside cone angle. This is the angle spread outside of which the sound is attenuated to its outsidevolume.

+
    +
  • Units: Degrees
  • +
  • Range: [insideconeangle, 360]
  • +
  • Default: 360
  • +
+
+
outsidevolume
+
+

Cone outside volume.

+
    +
  • Units: Linear
  • +
  • Range: [0, 1]
  • +
  • Default: 1
  • +
+
+
+

When ChannelControl::set3DConeOrientation is used and a 3D 'cone' is set up, attenuation will automatically occur for a sound based on the relative angle of the direction the cone is facing, vs the angle between the sound and the listener.

+
    +
  • If the relative angle is within the insideconeangle, the sound will not have any attenuation applied.
  • +
  • If the relative angle is between the insideconeangle and outsideconeangle, linear volume attenuation (between 1 and outsidevolume) is applied between the two angles until it reaches the outsideconeangle.
  • +
  • If the relative angle is outside of the outsideconeangle the volume does not attenuate any further.
  • +
+

See Also: Sound::get3DConeSettings, ChannelControl::set3DConeSettings

+

Sound::set3DCustomRolloff

+

Sets a custom roll-off shape for 3D distance attenuation.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
FMOD_RESULT Sound::set3DCustomRolloff(
+  FMOD_VECTOR *points,
+  int numpoints
+);
+
+ +
FMOD_RESULT FMOD_Sound_Set3DCustomRolloff(
+  FMOD_SOUND *sound,
+  FMOD_VECTOR *points,
+  int numpoints
+);
+
+ +
RESULT Sound.set3DCustomRolloff(
+  ref VECTOR points,
+  int numpoints
+);
+
+ +
Sound.set3DCustomRolloff(
+  points,
+  numpoints
+);
+
+ +
+
points
+
Array of points sorted by distance, where x = distance and y = volume from 0 to 1. z should be set to 0. Pass null or equivalent to disable custom roll-off. (FMOD_VECTOR)
+
numpoints
+
Number of points.
+
+

Must be used in conjunction with FMOD_3D_CUSTOMROLLOFF flag to be activated.

+

This function does not duplicate the memory for the points internally. The memory you pass to FMOD must remain valid while in use.

+

If FMOD_3D_CUSTOMROLLOFF is set and the roll-off shape is not set, FMOD will revert to FMOD_3D_INVERSEROLLOFF roll-off mode.

+

When a custom roll-off is specified a sound's 3D 'minimum' and 'maximum' distances are ignored.

+

The distance in-between point values is linearly interpolated until the final point where the last value is held.

+

If the points are not sorted by distance, an error will result.

+
// Defining a custom array of points
+FMOD_VECTOR curve[3] =
+{
+    { 0.0f,  1.0f, 0.0f },
+    { 2.0f,  0.2f, 0.0f },
+    { 20.0f, 0.0f, 0.0f }
+};
+
+ +

See Also: Sound::get3DCustomRolloff, ChannelControl::set3DCustomRolloff

+

Sound::set3DMinMaxDistance

+

Sets the minimum and maximum audible distance for a 3D sound.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
FMOD_RESULT Sound::set3DMinMaxDistance(
+  float min,
+  float max
+);
+
+ +
FMOD_RESULT FMOD_Sound_Set3DMinMaxDistance(
+  FMOD_SOUND *sound,
+  float min,
+  float max
+);
+
+ +
RESULT Sound.set3DMinMaxDistance(
+  float min,
+  float max
+);
+
+ +
Sound.set3DMinMaxDistance(
+  min,
+  max
+);
+
+ +
+
min
+
+

The sound's minimum volume distance, or the distance that the sound has no attenuation due to 3d positioning.

+ +
+
max
+
+

The sound's maximum volume distance, or the distance that no additional attenuation will occur. See below for notes on different maxdistance behaviors.

+ +
+
+

The distances are meant to simulate the 'size' of a sound. Reducing the min distance will mean the sound appears smaller in the world, and in some modes makes the volume attenuate faster as the listener moves away from the sound.
+Increasing the min distance simulates a larger sound in the world, and in some modes makes the volume attenuate slower as the listener moves away from the sound.

+

max will affect attenuation differently based on roll-off mode set in the mode parameter of System::createSound, System::createStream, Sound::setMode or ChannelControl::setMode.

+

For these modes the volume will attenuate to 0 volume (silence), when the distance from the sound is equal to or further than the max distance:

+ +

For these modes the volume will stop attenuating at the point of the max distance, without affecting the rate of attenuation:

+ +

For this mode the max distance is ignored:

+ +

See Also: Sound::get3DMinMaxDistance, ChannelControl::set3DMinMaxDistance, ChannelControl::get3DMinMaxDistance, System::set3DSettings

+

Sound::setDefaults

+

Sets a sound's default playback attributes.

+

When the Sound is played it will use these values without having to specify them later on a per Channel basis.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
FMOD_RESULT Sound::setDefaults(
+  float frequency,
+  int priority
+);
+
+ +
FMOD_RESULT FMOD_Sound_SetDefaults(
+  FMOD_SOUND *sound,
+  float frequency,
+  int priority
+);
+
+ +
RESULT Sound.setDefaults(
+  float frequency,
+  int priority
+);
+
+ +
Sound.setDefaults(
+  frequency,
+  priority
+);
+
+ +
+
frequency
+
+

Default playback frequency. Default value is determined by the sound source's sample rate.

+
    +
  • Units: Hertz
  • +
  • Default: 44100
  • +
+
+
priority
+
+

Default priority where 0 is the highest priority.

+
    +
  • Range: [0, 256]
  • +
  • Default: 128
  • +
+
+
+

If you only want to change one of the default values, you will need to call Sound::getDefaults to get the other existing default value first. e.g.:

+
int priority;
+sound->getDefaults(nullptr, &priority);
+sound->setDefaults(48000, priority);
+
+ +
int priority;
+FMOD_Sound_GetDefaults(sound, NULL, &priority);
+FMOD_Sound_SetDefaults(48000, priority);
+
+ +
int priority;
+sound.getDefaults(out _, out priority);
+sound.setDefaults(48000, priority);
+
+ +
sound.getDefaults(null, outval);
+sound.setDefaults(48000, outval.val);
+
+ +

See Also: Sound::getDefaults, System::playSound, System::createSound

+

Sound::setLoopCount

+

Sets the sound to loop a specified number of times before stopping if the playback mode is set to looping.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
FMOD_RESULT Sound::setLoopCount(
+  int loopcount
+);
+
+ +
FMOD_RESULT FMOD_Sound_SetLoopCount(
+  FMOD_SOUND *sound,
+  int loopcount
+);
+
+ +
RESULT Sound.setLoopCount(
+  int loopcount
+);
+
+ +
Sound.setLoopCount(
+  loopcount
+);
+
+ +
+
loopcount
+
+

Number of times to loop before final playback where -1 is always loop. 0 means no loop.

+
    +
  • Range: [-1, inf)
  • +
  • Default: -1
  • +
+
+
+

Changing loop count on an already buffered stream may not produced desired output. See Streaming Issues.

+

See Also: Sound::setLoopPoints, Sound::getLoopCount

+

Sound::setLoopPoints

+

Sets the loop points within a sound.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
FMOD_RESULT Sound::setLoopPoints(
+  unsigned int loopstart,
+  FMOD_TIMEUNIT loopstarttype,
+  unsigned int loopend,
+  FMOD_TIMEUNIT loopendtype
+);
+
+ +
FMOD_RESULT FMOD_Sound_SetLoopPoints(
+  FMOD_SOUND *sound,
+  unsigned int loopstart,
+  FMOD_TIMEUNIT loopstarttype,
+  unsigned int loopend,
+  FMOD_TIMEUNIT loopendtype
+);
+
+ +
RESULT Sound.setLoopPoints(
+  uint loopstart,
+  TIMEUNIT loopstarttype,
+  uint loopend,
+  TIMEUNIT loopendtype
+);
+
+ +
Sound.setLoopPoints(
+  loopstart,
+  loopstarttype,
+  loopend,
+  loopendtype
+);
+
+ +
+
loopstart
+
+

Loop start point.

+
    +
  • Range: [0, loopend)
  • +
+
+
loopstarttype
+
Time format of loopstart. (FMOD_TIMEUNIT)
+
loopend
+
+

Loop end point.

+
    +
  • Range: [loopstart, Sound::getLength)
  • +
+
+
loopendtype
+
Time format of loopend. (FMOD_TIMEUNIT)
+
+

The values used for loopstart and loopend are inclusive, which means these positions will be played.

+

If a loopend is smaller or equal to loopstart an error will be returned. The same will happen for any values that are equal or greater than the length of the sound.

+

Changing loop points on an already buffered stream may not produced desired output. See Streaming Issues.

+

The Sound's mode must be set to FMOD_LOOP_NORMAL or FMOD_LOOP_BIDI for loop points to affect playback.

+

See Also: Sound::getLoopPoints, Sound::setLoopCount, Sound::setMode

+

Sound::setMode

+

Sets or alters the mode of a sound.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
FMOD_RESULT Sound::setMode(
+  FMOD_MODE mode
+);
+
+ +
FMOD_RESULT FMOD_Sound_SetMode(
+  FMOD_SOUND *sound,
+  FMOD_MODE mode
+);
+
+ +
RESULT Sound.setMode(
+  MODE mode
+);
+
+ +
Sound.setMode(
+  mode
+);
+
+ +
+
mode
+
+

Mode bits to set. (FMOD_MODE)

+ +
+
+

When calling this function, note that it will only take effect when the sound is played again with System::playSound.
+This is the default for when the sound next plays, not a mode that will suddenly change all currently playing instances of this sound.

+

Flags supported:

+ +

If FMOD_3D_IGNOREGEOMETRY is not specified, the flag will be cleared if it was specified previously.

+

Changing mode on an already buffered stream may not produced desired output. See Streaming Issues.

+

See Also: Streaming Issues, Sound::getMode, Sound::setLoopPoints, System::playSound

+

Sound::setMusicChannelVolume

+

Sets the volume of a MOD/S3M/XM/IT/MIDI music channel volume.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
FMOD_RESULT Sound::setMusicChannelVolume(
+  int channel,
+  float volume
+);
+
+ +
FMOD_RESULT FMOD_Sound_SetMusicChannelVolume(
+  FMOD_SOUND *sound,
+  int channel,
+  float volume
+);
+
+ +
RESULT Sound.setMusicChannelVolume(
+  int channel,
+  float volume
+);
+
+ +
Sound.setMusicChannelVolume(
+  channel,
+  volume
+);
+
+ +
+
channel
+
MOD/S3M/XM/IT/MIDI music subchannel to set a linear volume for.
+
volume
+
+

Volume of the channel.

+
    +
  • Units: Linear
  • +
  • Range: [0, 1]
  • +
  • Default: 1
  • +
+
+
+

See Also: Sound::getMusicNumChannels, Sound::getMusicChannelVolume

+

Sound::setMusicSpeed

+

Sets the relative speed of MOD/S3M/XM/IT/MIDI music.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
FMOD_RESULT Sound::setMusicSpeed(
+  float speed
+);
+
+ +
FMOD_RESULT FMOD_Sound_SetMusicSpeed(
+  FMOD_SOUND *sound,
+  float speed
+);
+
+ +
RESULT Sound.setMusicSpeed(
+  float speed
+);
+
+ +
Sound.setMusicSpeed(
+  speed
+);
+
+ +
+
speed
+
+

Speed of the song.

+
    +
  • Units: Linear
  • +
  • Range: [0.01, 100]
  • +
  • Default: 1
  • +
+
+
+

See Also: Sound::getMusicSpeed

+

Sound::setSoundGroup

+

Moves the sound from its existing SoundGroup to the specified sound group.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
FMOD_RESULT Sound::setSoundGroup(
+  SoundGroup *soundgroup
+);
+
+ +
FMOD_RESULT FMOD_Sound_SetSoundGroup(
+  FMOD_SOUND *sound,
+  FMOD_SOUNDGROUP *soundgroup
+);
+
+ +
RESULT Sound.setSoundGroup(
+  SoundGroup soundgroup
+);
+
+ +
Sound.setSoundGroup(
+  soundgroup
+);
+
+ +
+
soundgroup
+
Sound group to move the sound to. (SoundGroup)
+
+

By default, a sound is located in the 'master sound group'. This can be retrieved with System::getMasterSoundGroup.

+

See Also: Sound::getSoundGroup, System::createSoundGroup, SoundGroup::setMaxAudible

+

Sound::setUserData

+

Sets a user value associated with this object.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
FMOD_RESULT Sound::setUserData(
+  void *userdata
+);
+
+ +
FMOD_RESULT FMOD_Sound_SetUserData(
+  FMOD_SOUND *sound,
+  void *userdata
+);
+
+ +
RESULT Sound.setUserData(
+  IntPtr userdata
+);
+
+ +
Sound.setUserData(
+  userdata
+);
+
+ +
+
userdata
+
Value stored on this object.
+
+

This function allows arbitrary user data to be attached to this object. See the User Data section of the glossary for an example of how to get and set user data.

+

See Also: Sound::getUserData

+

FMOD_SOUND_TYPE

+

Recognized audio formats that can be loaded into a Sound.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
typedef enum FMOD_SOUND_TYPE {
+  FMOD_SOUND_TYPE_UNKNOWN,
+  FMOD_SOUND_TYPE_AIFF,
+  FMOD_SOUND_TYPE_ASF,
+  FMOD_SOUND_TYPE_DLS,
+  FMOD_SOUND_TYPE_FLAC,
+  FMOD_SOUND_TYPE_FSB,
+  FMOD_SOUND_TYPE_IT,
+  FMOD_SOUND_TYPE_MIDI,
+  FMOD_SOUND_TYPE_MOD,
+  FMOD_SOUND_TYPE_MPEG,
+  FMOD_SOUND_TYPE_OGGVORBIS,
+  FMOD_SOUND_TYPE_PLAYLIST,
+  FMOD_SOUND_TYPE_RAW,
+  FMOD_SOUND_TYPE_S3M,
+  FMOD_SOUND_TYPE_USER,
+  FMOD_SOUND_TYPE_WAV,
+  FMOD_SOUND_TYPE_XM,
+  FMOD_SOUND_TYPE_XMA,
+  FMOD_SOUND_TYPE_AUDIOQUEUE,
+  FMOD_SOUND_TYPE_AT9,
+  FMOD_SOUND_TYPE_VORBIS,
+  FMOD_SOUND_TYPE_MEDIA_FOUNDATION,
+  FMOD_SOUND_TYPE_MEDIACODEC,
+  FMOD_SOUND_TYPE_FADPCM,
+  FMOD_SOUND_TYPE_OPUS,
+  FMOD_SOUND_TYPE_MAX
+} FMOD_SOUND_TYPE;
+
+ +
enum SOUND_TYPE
+{
+  UNKNOWN,
+  AIFF,
+  ASF,
+  DLS,
+  FLAC,
+  FSB,
+  IT,
+  MIDI,
+  MOD,
+  MPEG,
+  OGGVORBIS,
+  PLAYLIST,
+  RAW,
+  S3M,
+  USER,
+  WAV,
+  XM,
+  XMA,
+  AUDIOQUEUE,
+  AT9,
+  VORBIS,
+  MEDIA_FOUNDATION,
+  MEDIACODEC,
+  FADPCM,
+  OPUS,
+  MAX,
+}
+
+ +
FMOD.SOUND_TYPE_UNKNOWN
+FMOD.SOUND_TYPE_AIFF
+FMOD.SOUND_TYPE_ASF
+FMOD.SOUND_TYPE_DLS
+FMOD.SOUND_TYPE_FLAC
+FMOD.SOUND_TYPE_FSB
+FMOD.SOUND_TYPE_IT
+FMOD.SOUND_TYPE_MIDI
+FMOD.SOUND_TYPE_MOD
+FMOD.SOUND_TYPE_MPEG
+FMOD.SOUND_TYPE_OGGVORBIS
+FMOD.SOUND_TYPE_PLAYLIST
+FMOD.SOUND_TYPE_RAW
+FMOD.SOUND_TYPE_S3M
+FMOD.SOUND_TYPE_USER
+FMOD.SOUND_TYPE_WAV
+FMOD.SOUND_TYPE_XM
+FMOD.SOUND_TYPE_XMA
+FMOD.SOUND_TYPE_AUDIOQUEUE
+FMOD.SOUND_TYPE_AT9
+FMOD.SOUND_TYPE_VORBIS
+FMOD.SOUND_TYPE_MEDIA_FOUNDATION
+FMOD.SOUND_TYPE_MEDIACODEC
+FMOD.SOUND_TYPE_FADPCM
+FMOD.SOUND_TYPE_OPUS
+FMOD.SOUND_TYPE_MAX
+
+ +
+
FMOD_SOUND_TYPE_UNKNOWN
+
Unknown or custom codec plug-in.
+
FMOD_SOUND_TYPE_AIFF
+
Audio Interchange File Format (.aif, .aiff). Uncompressed integer formats only.
+
FMOD_SOUND_TYPE_ASF
+
Microsoft Advanced Systems Format (.asf, .wma, .wmv). Platform provided decoder, available only on Windows.
+
FMOD_SOUND_TYPE_DLS
+
Downloadable Sound (.dls). Multi-sound bank format used by MIDI (.mid).
+
FMOD_SOUND_TYPE_FLAC
+
Free Lossless Audio Codec (.flac).
+
FMOD_SOUND_TYPE_FSB
+
FMOD Sample Bank (.fsb). Proprietary multi-sound bank format. Supported encodings: PCM16, FADPCM, Vorbis, AT9, XMA, Opus.
+
FMOD_SOUND_TYPE_IT
+
Impulse Tracker (.it).
+
FMOD_SOUND_TYPE_MIDI
+
Musical Instrument Digital Interface (.mid).
+
FMOD_SOUND_TYPE_MOD
+
Protracker / Fasttracker Module File (.mod).
+
FMOD_SOUND_TYPE_MPEG
+
Moving Picture Experts Group (.mp2, .mp3). Also supports .wav (RIFF) container format.
+
FMOD_SOUND_TYPE_OGGVORBIS
+
Ogg Vorbis (.ogg).
+
FMOD_SOUND_TYPE_PLAYLIST
+
Play list information container (.asx, .pls, .m3u, .wax). No audio, tags only.
+
FMOD_SOUND_TYPE_RAW
+
Raw uncompressed PCM data (.raw).
+
FMOD_SOUND_TYPE_S3M
+
ScreamTracker 3 Module (.s3m).
+
FMOD_SOUND_TYPE_USER
+
User created sound.
+
FMOD_SOUND_TYPE_WAV
+
Microsoft Waveform Audio File Format (.wav). Supported encodings: Uncompressed PCM, IMA ADPCM. Platform provided ACM decoder extensions, available only on Windows.
+
FMOD_SOUND_TYPE_XM
+
FastTracker 2 Extended Module (.xm).
+
FMOD_SOUND_TYPE_XMA
+
Microsoft XMA bit-stream supported by FSB (.fsb) container format. Platform provided decoder, available only on Xbox.
+
FMOD_SOUND_TYPE_AUDIOQUEUE
+
Apple Audio Queue decoder (.mp4, .m4a, .mp3). Supported encodings: AAC, ALAC, MP3. Platform provided decoder, available only on iOS / tvOS devices.
+
FMOD_SOUND_TYPE_AT9
+
Sony ATRAC9 bit-stream supported by FSB (.fsb) container format. Platform provided decoder, available only on PlayStation.
+
FMOD_SOUND_TYPE_VORBIS
+
Vorbis bit-stream supported by FSB (.fsb) container format.
+
FMOD_SOUND_TYPE_MEDIA_FOUNDATION
+
Microsoft Media Foundation decoder (.asf, .wma, .wmv, .mp4, .m4a). Platform provided decoder, available only on UWP.
+
FMOD_SOUND_TYPE_MEDIACODEC
+
Google Media Codec decoder (.m4a, .mp4). Platform provided decoder, available only on Android.
+
FMOD_SOUND_TYPE_FADPCM
+
FMOD Adaptive Differential Pulse Code Modulation bit-stream supported by FSB (.fsb) container format.
+
FMOD_SOUND_TYPE_OPUS
+
Opus bit-stream supported by FSB (.fsb) container format. Platform provided decoder, available only on Xbox Series X|S, PS5, and Switch.
+
FMOD_SOUND_TYPE_MAX
+
Maximum number of sound types supported.
+
+

See Also: Sound::getFormat

+

Sound::unlock

+

Finalizes a previous sample data lock and submits it back to the Sound object.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
FMOD_RESULT Sound::unlock(
+  void *ptr1,
+  void *ptr2,
+  unsigned int len1,
+  unsigned int len2
+);
+
+ +
FMOD_RESULT FMOD_Sound_Unlock(
+  FMOD_SOUND *sound,
+  void *ptr1,
+  void *ptr2,
+  unsigned int len1,
+  unsigned int len2
+);
+
+ +
RESULT Sound.unlock(
+  IntPtr ptr1,
+  IntPtr ptr2,
+  uint len1,
+  uint len2
+);
+
+ +
Sound.unlock(
+  ptr1,
+  ptr2,
+  len1,
+  len2
+);
+
+ +
+
ptr1
+
+

First part of the locked data.

+ +
+
ptr2
+
+

Second part of the locked data.

+ +
+
len1
+
+

Length of ptr1.

+
    +
  • Units: Bytes
  • +
+
+
len2
+
+

Length of ptr2

+
    +
  • Units: Bytes
  • +
+
+
+

The data being 'unlocked' must first have been locked with Sound::lock.

+

If an unlock is not performed on PCM data, then sample loops may produce audible clicks.

+

The names 'lock'/'unlock' are a legacy reference to older Operating System APIs that used to cause a mutex lock on the data, so that it could not be written to while the 'lock' was in place. This is no longer the case with FMOD and data can be 'locked' multiple times from different places/threads at once.

+

See Also: Sound::lock

+

FMOD_TAG

+

Tag data / metadata description.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
typedef struct FMOD_TAG {
+  FMOD_TAGTYPE       type;
+  FMOD_TAGDATATYPE   datatype;
+  char              *name;
+  void              *data;
+  unsigned int       datalen;
+  FMOD_BOOL          updated;
+} FMOD_TAG;
+
+ +
struct TAG
+{
+  TAGTYPE           type;
+  TAGDATATYPE       datatype;
+  StringWrapper     name;
+  IntPtr            data;
+  uint              datalen;
+  bool              updated;
+}
+
+ +
FMOD_TAG
+{
+  type,
+  datatype,
+  data,
+  datalen,
+  updated,
+};
+
+ +
+
type R/O
+
Tag type. (FMOD_TAGTYPE)
+
datatype R/O
+
Tag data type. (FMOD_TAGDATATYPE)
+
name R/O
+
Name.
+
data R/O
+
Tag data.
+
datalen R/O
+
Size of data. +* Units: Bytes
+
updated R/O
+
+

True if this tag has been updated since last being accessed with Sound::getTag

+
    +
  • Units: Boolean
  • +
+
+
+

See Also: Sound::getTag

+

FMOD_TAGDATATYPE

+

List of tag data / metadata types.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
typedef enum FMOD_TAGDATATYPE {
+  FMOD_TAGDATATYPE_BINARY,
+  FMOD_TAGDATATYPE_INT,
+  FMOD_TAGDATATYPE_FLOAT,
+  FMOD_TAGDATATYPE_STRING,
+  FMOD_TAGDATATYPE_STRING_UTF16,
+  FMOD_TAGDATATYPE_STRING_UTF16BE,
+  FMOD_TAGDATATYPE_STRING_UTF8,
+  FMOD_TAGDATATYPE_MAX
+} FMOD_TAGDATATYPE;
+
+ +
enum TAGDATATYPE : int
+{
+  BINARY,
+  INT,
+  FLOAT,
+  STRING,
+  STRING_UTF16,
+  STRING_UTF16BE,
+  STRING_UTF8,
+  MAX
+}
+
+ +
FMOD.TAGDATATYPE_BINARY
+FMOD.TAGDATATYPE_INT
+FMOD.TAGDATATYPE_FLOAT
+FMOD.TAGDATATYPE_STRING
+FMOD.TAGDATATYPE_STRING_UTF16
+FMOD.TAGDATATYPE_STRING_UTF16BE
+FMOD.TAGDATATYPE_STRING_UTF8
+FMOD.TAGDATATYPE_MAX
+
+ +
+
FMOD_TAGDATATYPE_BINARY
+
Raw binary data. see FMOD_TAG structure for length of data in bytes.
+
FMOD_TAGDATATYPE_INT
+
Integer - Note this integer could be 8bit / 16bit / 32bit / 64bit. See FMOD_TAG structure for integer size (1 vs 2 vs 4 vs 8 bytes).
+
FMOD_TAGDATATYPE_FLOAT
+
IEEE floating point number. See FMOD_TAG structure to confirm if the float data is 32bit or 64bit (4 vs 8 bytes).
+
FMOD_TAGDATATYPE_STRING
+
8bit ASCII char string. See FMOD_TAG structure for string length in bytes.
+
FMOD_TAGDATATYPE_STRING_UTF16
+
16bit UTF string. Assume little endian byte order. See FMOD_TAG structure for string length in bytes.
+
FMOD_TAGDATATYPE_STRING_UTF16BE
+
16bit UTF string Big endian byte order. See FMOD_TAG structure for string length in bytes.
+
FMOD_TAGDATATYPE_STRING_UTF8
+
8 bit UTF string. See FMOD_TAG structure for string length in bytes.
+
FMOD_TAGDATATYPE_MAX
+
Maximum number of tag datatypes supported.
+
+

See FMOD_TAG structure for tag length in bytes.

+

See Also: Sound::getTag, FMOD_TAGTYPE, FMOD_TAG

+

FMOD_TAGTYPE

+

List of tag data / metadata types that could be stored within a sound. These include id3 tags, metadata from netstreams and vorbis/asf data.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
typedef enum FMOD_TAGTYPE {
+  FMOD_TAGTYPE_UNKNOWN,
+  FMOD_TAGTYPE_ID3V1,
+  FMOD_TAGTYPE_ID3V2,
+  FMOD_TAGTYPE_VORBISCOMMENT,
+  FMOD_TAGTYPE_SHOUTCAST,
+  FMOD_TAGTYPE_ICECAST,
+  FMOD_TAGTYPE_ASF,
+  FMOD_TAGTYPE_MIDI,
+  FMOD_TAGTYPE_PLAYLIST,
+  FMOD_TAGTYPE_FMOD,
+  FMOD_TAGTYPE_USER,
+  FMOD_TAGTYPE_MAX
+} FMOD_TAGTYPE;
+
+ +
enum TAGTYPE
+{
+  UNKNOWN,
+  ID3V1,
+  ID3V2,
+  VORBISCOMMENT,
+  SHOUTCAST,
+  ICECAST,
+  ASF,
+  MIDI,
+  PLAYLIST,
+  FMOD,
+  USER,
+  MAX
+}
+
+ +
FMOD.TAGTYPE_UNKNOWN
+FMOD.TAGTYPE_ID3V1
+FMOD.TAGTYPE_ID3V2
+FMOD.TAGTYPE_VORBISCOMMENT
+FMOD.TAGTYPE_SHOUTCAST
+FMOD.TAGTYPE_ICECAST
+FMOD.TAGTYPE_ASF
+FMOD.TAGTYPE_MIDI
+FMOD.TAGTYPE_PLAYLIST
+FMOD.TAGTYPE_FMOD
+FMOD.TAGTYPE_USER
+FMOD.TAGTYPE_MAX
+
+ +
+
FMOD_TAGTYPE_UNKNOWN
+
Tag type that is not recognized by FMOD
+
FMOD_TAGTYPE_ID3V1
+
MP3 ID3 Tag 1.0. Typically 1 tag stored 128 bytes from end of an MP3 file.
+
FMOD_TAGTYPE_ID3V2
+
MP3 ID3 Tag 2.0. Variable length tags with more than 1 possible.
+
FMOD_TAGTYPE_VORBISCOMMENT
+
Metadata container used in Vorbis, FLAC, Theora, Speex and Opus file formats.
+
FMOD_TAGTYPE_SHOUTCAST
+
SHOUTcast internet stream metadata which can be issued during playback.
+
FMOD_TAGTYPE_ICECAST
+
Icecast internet stream metadata which can be issued during playback.
+
FMOD_TAGTYPE_ASF
+
Advanced Systems Format metadata typically associated with Windows Media formats such as WMA.
+
FMOD_TAGTYPE_MIDI
+
Metadata stored inside a MIDI file.
+
FMOD_TAGTYPE_PLAYLIST
+
Playlist files such as PLS,M3U,ASX and WAX will populate playlist information through this tag type.
+
FMOD_TAGTYPE_FMOD
+
Tag type used by FMOD's MIDI, MOD, S3M, XM, IT format support, and netstreams to notify of internet stream events like a sample rate change.
+
FMOD_TAGTYPE_USER
+
For codec developers, this tag type can be used with FMOD_CODEC_METADATA_FUNC to generate custom metadata.
+
FMOD_TAGTYPE_MAX
+
Maximum number of tag types supported.
+
+

FMOD_TAGTYPE_MIDI remarks. A midi file contains 16 channels. Not all of them are used, or in order. Use the tag 'Channel mask' and 'Number of channels' to find the channels used, to use with Sound::setMusicChannelVolume / Sound::getMusicChannelVolume. For example if the mask is 1001b, there are 2 channels, and channel 0 and channel 3 are the 2 channels used with the above functions.

+

See Also: Sound::getTag, FMOD_TAGDATATYPE, FMOD_TAG

+ + +
+ + + diff --git a/FMOD/doc/FMOD API User Manual/core-api-soundgroup.html b/FMOD/doc/FMOD API User Manual/core-api-soundgroup.html new file mode 100644 index 0000000..df47231 --- /dev/null +++ b/FMOD/doc/FMOD API User Manual/core-api-soundgroup.html @@ -0,0 +1,784 @@ + + +Core API Reference | SoundGroup + + + + +
+ +
+

11. Core API Reference | SoundGroup

+

An interface that manages Sound Groups

+

Group Functions:

+ +
+ +

Sound Functions:

+ +

General:

+ +

FMOD_SOUNDGROUP_BEHAVIOR

+

Values specifying behavior when a sound group's max audible value is exceeded.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
typedef enum FMOD_SOUNDGROUP_BEHAVIOR {
+  FMOD_SOUNDGROUP_BEHAVIOR_FAIL,
+  FMOD_SOUNDGROUP_BEHAVIOR_MUTE,
+  FMOD_SOUNDGROUP_BEHAVIOR_STEALLOWEST,
+  FMOD_SOUNDGROUP_BEHAVIOR_MAX
+} FMOD_SOUNDGROUP_BEHAVIOR;
+
+ +
enum SOUNDGROUP_BEHAVIOR
+{
+    BEHAVIOR_FAIL,
+    BEHAVIOR_MUTE,
+    BEHAVIOR_STEALLOWEST,
+    MAX,
+}
+
+ +
FMOD.SOUNDGROUP_BEHAVIOR_FAIL
+FMOD.SOUNDGROUP_BEHAVIOR_MUTE
+FMOD.SOUNDGROUP_BEHAVIOR_STEALLOWEST
+FMOD.SOUNDGROUP_BEHAVIOR_MAX
+
+ +
+
FMOD_SOUNDGROUP_BEHAVIOR_FAIL
+
Excess sounds will fail when calling System::playSound.
+
FMOD_SOUNDGROUP_BEHAVIOR_MUTE
+
Excess sounds will begin mute and will become audible when sufficient sounds are stopped.
+
FMOD_SOUNDGROUP_BEHAVIOR_STEALLOWEST
+
Excess sounds will steal from the quietest Sound playing in the group.
+
FMOD_SOUNDGROUP_BEHAVIOR_MAX
+
Maximum number of SoundGroup behaviors.
+
+

When using FMOD_SOUNDGROUP_BEHAVIOR_MUTE, SoundGroup::setMuteFadeSpeed can be used to stop a sudden transition.
+Instead, the time specified will be used to cross fade between the sounds that go silent and the ones that become audible.

+

See Also: SoundGroup::setMaxAudibleBehavior, SoundGroup::getMaxAudibleBehavior, SoundGroup::setMaxAudible, SoundGroup::getMaxAudible, SoundGroup::setMuteFadeSpeed, SoundGroup::getMuteFadeSpeed

+

SoundGroup::getMaxAudible

+

Retrieves the maximum number of playbacks to be audible at once in a sound group.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
FMOD_RESULT SoundGroup::getMaxAudible(
+  int *maxaudible
+);
+
+ +
FMOD_RESULT FMOD_SoundGroup_GetMaxAudible(
+  FMOD_SOUNDGROUP *soundgroup,
+  int *maxaudible
+);
+
+ +
RESULT SoundGroup.getMaxAudible(
+  out int maxaudible
+);
+
+ +
SoundGroup.getMaxAudible(
+  maxaudible
+);
+
+ +
+
maxaudible Out
+
+

Maximum number of playbacks to be audible at once.

+
    +
  • Range: [-1, inf)
  • +
  • Default: -1
  • +
+
+
+

See Also: SoundGroup::setMaxAudible

+

SoundGroup::getMaxAudibleBehavior

+

Retrieves the current max audible behavior.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
FMOD_RESULT SoundGroup::getMaxAudibleBehavior(
+  FMOD_SOUNDGROUP_BEHAVIOR *behavior
+);
+
+ +
FMOD_RESULT FMOD_SoundGroup_GetMaxAudibleBehavior(
+  FMOD_SOUNDGROUP *soundgroup,
+  FMOD_SOUNDGROUP_BEHAVIOR *behavior
+);
+
+ +
RESULT SoundGroup.getMaxAudibleBehavior(
+  out SOUNDGROUP_BEHAVIOR behavior
+);
+
+ +
SoundGroup.getMaxAudibleBehavior(
+  behavior
+);
+
+ +
+
behavior Out
+
+

SoundGroup max playbacks behavior. (FMOD_SOUNDGROUP_BEHAVIOR)

+ +
+
+

See Also: SoundGroup::setMaxAudibleBehavior

+

SoundGroup::getMuteFadeSpeed

+

Retrieves the current mute fade time.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
FMOD_RESULT SoundGroup::getMuteFadeSpeed(
+  float *speed
+);
+
+ +
FMOD_RESULT FMOD_SoundGroup_GetMuteFadeSpeed(
+  FMOD_SOUNDGROUP *soundgroup,
+  float *speed
+);
+
+ +
RESULT SoundGroup.getMuteFadeSpeed(
+  out float speed
+);
+
+ +
SoundGroup.getMuteFadeSpeed(
+  speed
+);
+
+ +
+
speed Out
+
+

Fade time. 0 = no fading.

+
    +
  • Units: Seconds
  • +
  • Range: [0, inf)
  • +
  • Default: 0
  • +
+
+
+

See Also: SoundGroup::setMuteFadeSpeed

+

SoundGroup::getName

+

Retrieves the name of the sound group.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
FMOD_RESULT SoundGroup::getName(
+  char *name,
+  int namelen
+);
+
+ +
FMOD_RESULT FMOD_SoundGroup_GetName(
+  FMOD_SOUNDGROUP *soundgroup,
+  char *name,
+  int namelen
+);
+
+ +
RESULT SoundGroup.getName(
+  out string name,
+  int namelen
+);
+
+ +
SoundGroup.getName(
+  name
+);
+
+ +
+
name Out
+
Name of the SoundGroup. (UTF-8 string)
+
namelen
+
+

Length of name.

+
    +
  • Units: Bytes
  • +
+
+
+

See Also: System::createSoundGroup

+

SoundGroup::getNumPlaying

+

Retrieves the number of currently playing Channels for the SoundGroup.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
FMOD_RESULT SoundGroup::getNumPlaying(
+  int *numplaying
+);
+
+ +
FMOD_RESULT FMOD_SoundGroup_GetNumPlaying(
+  FMOD_SOUNDGROUP *soundgroup,
+  int *numplaying
+);
+
+ +
RESULT SoundGroup.getNumPlaying(
+  out int numplaying
+);
+
+ +
SoundGroup.getNumPlaying(
+  numplaying
+);
+
+ +
+
numplaying Out
+
Number of actively playing Channels from sounds in this SoundGroup.
+
+

This routine returns the number of Channels playing. If the SoundGroup only has one Sound, and that Sound is playing twice, the figure returned will be two.

+

See Also: System::createSoundGroup, System::getMasterSoundGroup

+

SoundGroup::getNumSounds

+

Retrieves the current number of sounds in this sound group.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
FMOD_RESULT SoundGroup::getNumSounds(
+  int *numsounds
+);
+
+ +
FMOD_RESULT FMOD_SoundGroup_GetNumSounds(
+  FMOD_SOUNDGROUP *soundgroup,
+  int *numsounds
+);
+
+ +
RESULT SoundGroup.getNumSounds(
+  out int numsounds
+);
+
+ +
SoundGroup.getNumSounds(
+  numsounds
+);
+
+ +
+
numsounds Out
+
Number of Sounds in this SoundGroup.
+
+

See Also: SoundGroup::getSound

+

SoundGroup::getSound

+

Retrieves a sound.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
FMOD_RESULT SoundGroup::getSound(
+  int index,
+  Sound **sound
+);
+
+ +
FMOD_RESULT FMOD_SoundGroup_GetSound(
+  FMOD_SOUNDGROUP *soundgroup,
+  int index,
+  FMOD_SOUND **sound
+);
+
+ +
RESULT SoundGroup.getSound(
+  int index,
+  out Sound sound
+);
+
+ +
SoundGroup.getSound(
+  index,
+  sound
+);
+
+ +
+
index
+
Index of the sound.
+
sound Out
+
Sound object. (Sound)
+
+

Use SoundGroup::getNumSounds in conjunction with this function to enumerate all sounds in a SoundGroup.

+

See Also: System::createSound

+

SoundGroup::getSystemObject

+

Retrieves the parent System object.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
FMOD_RESULT SoundGroup::getSystemObject(
+  System **system
+);
+
+ +
FMOD_RESULT FMOD_SoundGroup_GetSystemObject(
+  FMOD_SOUNDGROUP *soundgroup,
+  FMOD_SYSTEM **system
+);
+
+ +
RESULT SoundGroup.getSystemObject(
+  out System system
+);
+
+ +
SoundGroup.getSystemObject(
+  system
+);
+
+ +
+
system Out
+
System object. (System)
+
+

See Also: System::createSoundGroup, System::getMasterSoundGroup

+

SoundGroup::getUserData

+

Retrieves a user value associated with this object.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
FMOD_RESULT SoundGroup::getUserData(
+  void **userdata
+);
+
+ +
FMOD_RESULT FMOD_SoundGroup_GetUserData(
+  FMOD_SOUNDGROUP *soundgroup,
+  void **userdata
+);
+
+ +
RESULT SoundGroup.getUserData(
+  out IntPtr userdata
+);
+
+ +
SoundGroup.getUserData(
+  userdata
+);
+
+ +
+
userdata Out
+
User data set by calling SoundGroup::setUserData.
+
+

This function allows arbitrary user data to be retrieved from this object. See the User Data section of the glossary for an example of how to get and set user data.

+

SoundGroup::getVolume

+

Retrieves the volume of the sound group.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
FMOD_RESULT SoundGroup::getVolume(
+  float *volume
+);
+
+ +
FMOD_RESULT FMOD_SoundGroup_GetVolume(
+  FMOD_SOUNDGROUP *soundgroup,
+  float *volume
+);
+
+ +
RESULT SoundGroup.getVolume(
+  out float volume
+);
+
+ +
SoundGroup.getVolume(
+  volume
+);
+
+ +
+
volume Out
+
+

Volume level.

+
    +
  • Units: Linear
  • +
  • Range: [0, 1]
  • +
  • Default: 1
  • +
+
+
+

See Also: SoundGroup::setVolume

+

SoundGroup::release

+

Releases a soundgroup object and returns all sounds back to the master sound group.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
FMOD_RESULT SoundGroup::release();
+
+ +
FMOD_RESULT FMOD_SoundGroup_Release(FMOD_SOUNDGROUP *soundgroup);
+
+ +
RESULT SoundGroup.release();
+
+ +
SoundGroup.release();
+
+ +

You cannot release the master SoundGroup.

+

See Also: System::createSoundGroup, System::getMasterSoundGroup

+

SoundGroup::setMaxAudible

+

Sets the maximum number of playbacks to be audible at once in a sound group.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
FMOD_RESULT SoundGroup::setMaxAudible(
+  int maxaudible
+);
+
+ +
FMOD_RESULT FMOD_SoundGroup_SetMaxAudible(
+  FMOD_SOUNDGROUP *soundgroup,
+  int maxaudible
+);
+
+ +
RESULT SoundGroup.setMaxAudible(
+  int maxaudible
+);
+
+ +
SoundGroup.setMaxAudible(
+  maxaudible
+);
+
+ +
+
maxaudible
+
+

Maximum number of playbacks to be audible at once. -1 denotes unlimited.

+
    +
  • Range: [-1, inf)
  • +
  • Default: -1
  • +
+
+
+

If playing instances of sounds in this group equal or exceed number specified here, attepts to play more of the sounds with be met with FMOD_ERR_MAXAUDIBLE by default.
+Use SoundGroup::setMaxAudibleBehavior to change the way the sound playback behaves when too many sounds are playing. Muting, failing and stealing behaviors can be specified. See FMOD_SOUNDGROUP_BEHAVIOR.

+

SoundGroup::getNumPlaying can be used to determine how many instances of the sounds in the SoundGroup are currently playing.

+

See Also: SoundGroup::getMaxAudible, SoundGroup::setMaxAudibleBehavior, SoundGroup::getMaxAudibleBehavior

+

SoundGroup::setMaxAudibleBehavior

+

This function changes the way the sound playback behaves when too many sounds are playing in a soundgroup.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
FMOD_RESULT SoundGroup::setMaxAudibleBehavior(
+  FMOD_SOUNDGROUP_BEHAVIOR behavior
+);
+
+ +
FMOD_RESULT FMOD_SoundGroup_SetMaxAudibleBehavior(
+  FMOD_SOUNDGROUP *soundgroup,
+  FMOD_SOUNDGROUP_BEHAVIOR behavior
+);
+
+ +
RESULT SoundGroup.setMaxAudibleBehavior(
+  SOUNDGROUP_BEHAVIOR behavior
+);
+
+ +
SoundGroup.setMaxAudibleBehavior(
+  behavior
+);
+
+ +
+
behavior
+
+

SoundGroup max playbacks behavior. (FMOD_SOUNDGROUP_BEHAVIOR)

+ +
+
+

See Also: SoundGroup::getMaxAudibleBehavior, SoundGroup::setMaxAudible, SoundGroup::getMaxAudible

+

SoundGroup::setMuteFadeSpeed

+

Sets a mute fade time.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
FMOD_RESULT SoundGroup::setMuteFadeSpeed(
+  float speed
+);
+
+ +
FMOD_RESULT FMOD_SoundGroup_SetMuteFadeSpeed(
+  FMOD_SOUNDGROUP *soundgroup,
+  float speed
+);
+
+ +
RESULT SoundGroup.setMuteFadeSpeed(
+  float speed
+);
+
+ +
SoundGroup.setMuteFadeSpeed(
+  speed
+);
+
+ +
+
speed
+
+

Fade time. 0 = no fading.

+
    +
  • Units: Seconds
  • +
  • Range: [0, inf)
  • +
  • Default: 0
  • +
+
+
+

If a mode besides FMOD_SOUNDGROUP_BEHAVIOR_MUTE is used, the fade speed is ignored.

+

When more sounds are playing in a SoundGroup than are specified with SoundGroup::setMaxAudible, the least important Sound (ie lowest priority / lowest audible volume due to 3D position, volume etc) will fade to silence if FMOD_SOUNDGROUP_BEHAVIOR_MUTE is used, and any previous sounds that were silent because of this rule will fade in if they are more important.

+

See Also: SoundGroup::getMuteFadeSpeed

+

SoundGroup::setUserData

+

Sets a user value associated with this object.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
FMOD_RESULT SoundGroup::setUserData(
+  void *userdata
+);
+
+ +
FMOD_RESULT FMOD_SoundGroup_SetUserData(
+  FMOD_SOUNDGROUP *soundgroup,
+  void *userdata
+);
+
+ +
RESULT SoundGroup.setUserData(
+  IntPtr userdata
+);
+
+ +
SoundGroup.setUserData(
+  userdata
+);
+
+ +
+
userdata
+
Value stored on this object.
+
+

This function allows arbitrary user data to be attached to this object. See the User Data section of the glossary for an example of how to get and set user data.

+

See Also: SoundGroup::getUserData

+

SoundGroup::setVolume

+

Sets the volume of the sound group.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
FMOD_RESULT SoundGroup::setVolume(
+  float volume
+);
+
+ +
FMOD_RESULT FMOD_SoundGroup_SetVolume(
+  FMOD_SOUNDGROUP *soundgroup,
+  float volume
+);
+
+ +
RESULT SoundGroup.setVolume(
+  float volume
+);
+
+ +
SoundGroup.setVolume(
+  volume
+);
+
+ +
+
volume
+
+

Volume level.

+
    +
  • Units: Linear
  • +
  • Range: [0, 1]
  • +
  • Default: 1
  • +
+
+
+

Scales the volume of all Channels playing Sounds in this SoundGroup.

+

See Also: SoundGroup::getVolume

+

SoundGroup::stop

+

Stops all sounds within this soundgroup.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
FMOD_RESULT SoundGroup::stop();
+
+ +
FMOD_RESULT FMOD_SoundGroup_Stop(FMOD_SOUNDGROUP *soundgroup);
+
+ +
RESULT SoundGroup.stop();
+
+ +
SoundGroup.stop();
+
+ +

See Also: System::playSound

+ + +
+ + + diff --git a/FMOD/doc/FMOD API User Manual/core-api-system.html b/FMOD/doc/FMOD API User Manual/core-api-system.html new file mode 100644 index 0000000..6c2471a --- /dev/null +++ b/FMOD/doc/FMOD API User Manual/core-api-system.html @@ -0,0 +1,7073 @@ + + +Core API Reference | System + + + + +
+ +
+

11. Core API Reference | System

+

Management object from which all resources are created and played.

+

Create with System_Create.

+

Lifetime management:

+ +
+
    +
  • FMOD_INITFLAGS Configuration flags used when initializing the System object.
  • +
+

Device selection:

+
    +
  • System::setOutput Sets the type of output interface used to run the mixer.
  • +
  • System::getOutput Retrieves the type of output interface used to run the mixer.
  • +
  • System::getNumDrivers Retrieves the number of output drivers available for the selected output type.
  • +
  • System::getDriverInfo Retrieves identification information about a sound device specified by its index, and specific to the selected output mode.
  • +
  • System::setDriver Sets the output driver for the selected output type.
  • +
  • System::getDriver Retrieves the output driver for the selected output type.
  • +
+
+
    +
  • FMOD_OUTPUTTYPE Built-in output types that can be used to run the mixer.
  • +
+

Setup:

+ +
+ +
+ +

File system setup:

+ +
+ +

Plug-in support:

+ +
+
    +
  • FMOD_PLUGINLIST Used to support lists of plug-ins within the one dynamic library.
  • +
+
+ +

Network configuration:

+ +

Information:

+ +

Creation and retrieval:

+ +
+ +

Runtime control:

+ +
+ +
+
    +
  • FMOD_PORT_INDEX Output type specific index for when there are multiple instances or destinations for a port type.
  • +
  • FMOD_PORT_TYPE Port types available for routing audio.
  • +
  • FMOD_REVERB_MAXINSTANCES The maximum number of global reverb instances.
  • +
  • FMOD_REVERB_PRESETS Predefined reverb configurations. To simplify usage, and avoid manually selecting reverb parameters, a table of common presets is supplied for ease of use.
  • +
+

Recording:

+
    +
  • System::getRecordNumDrivers Retrieves the number of recording devices available for this output mode. Use this to enumerate all recording devices possible so that the user can select one.
  • +
  • System::getRecordDriverInfo Retrieves identification information about an audio device specified by its index, and specific to the output mode.
  • +
  • System::getRecordPosition Retrieves the current recording position of the record buffer in PCM samples.
  • +
  • System::recordStart Starts the recording engine recording to a pre-created Sound object.
  • +
  • System::recordStop Stops the recording engine from recording to a pre-created Sound object.
  • +
  • System::isRecording Retrieves the state of the FMOD recording API, ie if it is currently recording or not.
  • +
+
+
    +
  • FMOD_DRIVER_STATE Flags that provide additional information about a particular driver.
  • +
+

Geometry management:

+ +

General:

+ +
+ +
+ +

FMOD_3D_ROLLOFF_CALLBACK

+

Callback to allow custom calculation of distance attenuation.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
float F_CALL FMOD_3D_ROLLOFF_CALLBACK(
+  FMOD_CHANNELCONTROL *channelcontrol,
+  float distance
+);
+
+ +
delegate float CB_3D_ROLLOFFCALLBACK(
+  IntPtr channelcontrol,
+  float distance
+);
+
+ +
+

Not supported for JavaScript.

+
+
+
channelcontrol
+
Channel being evaluated. (ChannelControl)
+
distance
+
+

Distance from the listener.

+ +
+
+
+

channelcontrol can be cast to Channel *.

+
+

See Also: System::set3DRolloffCallback, System::set3DListenerAttributes, System::get3DListenerAttributes

+

FMOD_ADVANCEDSETTINGS

+

Advanced configuration settings.

+

Structure to allow configuration of lesser used system level settings. These tweaks generally allow the user to set resource limits and customize settings to better fit their application.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
typedef struct FMOD_ADVANCEDSETTINGS {
+  int                  cbSize;
+  int                  maxMPEGCodecs;
+  int                  maxADPCMCodecs;
+  int                  maxXMACodecs;
+  int                  maxVorbisCodecs;
+  int                  maxAT9Codecs;
+  int                  maxFADPCMCodecs;
+  int                  maxOpusCodecs;
+  int                  ASIONumChannels;
+  char               **ASIOChannelList;
+  FMOD_SPEAKER        *ASIOSpeakerList;
+  float                vol0virtualvol;
+  unsigned int         defaultDecodeBufferSize;
+  unsigned short       profilePort;
+  unsigned int         geometryMaxFadeTime;
+  float                distanceFilterCenterFreq;
+  int                  reverb3Dinstance;
+  int                  DSPBufferPoolSize;
+  FMOD_DSP_RESAMPLER   resamplerMethod;
+  unsigned int         randomSeed;
+  int                  maxConvolutionThreads;
+  int                  maxSpatialObjects;
+} FMOD_ADVANCEDSETTINGS;
+
+ +
struct ADVANCEDSETTINGS
+{
+  int           cbSize;
+  int           maxMPEGCodecs;
+  int           maxADPCMCodecs;
+  int           maxXMACodecs;
+  int           maxVorbisCodecs;
+  int           maxAT9Codecs;
+  int           maxFADPCMCodecs;
+  int           maxOpusCodecs;
+  int           ASIONumChannels;
+  IntPtr        ASIOChannelList;
+  IntPtr        ASIOSpeakerList;
+  float         vol0virtualvol;
+  uint          defaultDecodeBufferSize;
+  ushort        profilePort;
+  uint          geometryMaxFadeTime;
+  float         distanceFilterCenterFreq;
+  int           reverb3Dinstance;
+  int           DSPBufferPoolSize;
+  DSP_RESAMPLER resamplerMethod;
+  uint          randomSeed;
+  int           maxConvolutionThreads;
+  int           maxSpatialObjects;
+}
+
+ +
ADVANCEDSETTINGS
+{
+  maxMPEGCodecs,
+  maxADPCMCodecs,
+  maxXMACodecs,
+  maxVorbisCodecs,
+  maxAT9Codecs,
+  maxFADPCMCodecs,
+  maxOpusCodecs,
+  ASIONumChannels,
+  vol0virtualvol,
+  defaultDecodeBufferSize,
+  profilePort,
+  geometryMaxFadeTime,
+  distanceFilterCenterFreq,
+  reverb3Dinstance,
+  DSPBufferPoolSize,
+  resamplerMethod,
+  randomSeed,
+  maxConvolutionThreads,
+  maxSpatialObjects,
+};
+
+ +
+
cbSize
+
Size of this structure. Must be set to sizeof(FMOD_ADVANCEDSETTINGS) before calling System::setAdvancedSettings or System::getAdvancedSettings.
+
maxMPEGCodecs Opt
+
+

Maximum MPEG Sounds created as FMOD_CREATECOMPRESSEDSAMPLE.

+
    +
  • Default: 32
  • +
  • Range: [0, 256]
  • +
+
+
maxADPCMCodecs Opt
+
+

Maximum IMA-ADPCM Sounds created as FMOD_CREATECOMPRESSEDSAMPLE.

+
    +
  • Default: 32
  • +
  • Range: [0, 256]
  • +
+
+
maxXMACodecs Opt
+
+

Maximum XMA Sounds created as FMOD_CREATECOMPRESSEDSAMPLE.

+
    +
  • Default: 32
  • +
  • Range: [0, 256]
  • +
+
+
maxVorbisCodecs Opt
+
+

Maximum Vorbis Sounds created as FMOD_CREATECOMPRESSEDSAMPLE.

+
    +
  • Default: 32
  • +
  • Range: [0, 256]
  • +
+
+
maxAT9Codecs Opt
+
+

Maximum AT9 Sounds created as FMOD_CREATECOMPRESSEDSAMPLE.

+
    +
  • Default: 32
  • +
  • Range: [0, 256]
  • +
+
+
maxFADPCMCodecs Opt
+
+

Maximum FADPCM Sounds created as FMOD_CREATECOMPRESSEDSAMPLE.

+
    +
  • Default: 32
  • +
  • Range: [0, 256]
  • +
+
+
maxOpusCodecs Opt
+
+

Maximum Opus Sounds created as FMOD_CREATECOMPRESSEDSAMPLE.

+
    +
  • Default: 32
  • +
  • Range: [0, 256]
  • +
+
+
ASIONumChannels Opt
+
+

Number of elements in ASIOSpeakerList on input, number of elements in ASIOChannelList on output.

+ +
+
ASIOChannelList R/O
+
Read only list of strings representing ASIO channel names (UTF-8 string), count is defined by ASIONumChannels. Only valid after System::init.
+
ASIOSpeakerList Opt
+
List of speakers that represent each ASIO channel used for remapping, count is defined by ASIONumChannels. Use FMOD_SPEAKER_NONE to indicate no output for a given speaker. (FMOD_SPEAKER)
+
vol0virtualvol Opt
+
+

For use with FMOD_INIT_VOL0_BECOMES_VIRTUAL, Channels with audibility below this will become virtual. See the Virtual Voice System section of the Managing Resources in the Core API chapter for more information.

+
    +
  • Units: Linear
  • +
  • Default: 0
  • +
+
+
defaultDecodeBufferSize Opt
+
+

For use with Streams, the default size of the double buffer.

+
    +
  • Units: Milliseconds
  • +
  • Default: 400
  • +
  • Range: [0, 30000]
  • +
+
+
profilePort Opt
+
+

For use with FMOD_INIT_PROFILE_ENABLE, specify the port to listen on for connections by FMOD Studio or FMOD Profiler.

+
    +
  • Default: 9264
  • +
+
+
geometryMaxFadeTime Opt
+
+

For use with Geometry, the maximum time it takes for a Channel to fade to the new volume level when its occlusion changes.

+
    +
  • Units: Milliseconds
  • +
  • Default: 500
  • +
+
+
distanceFilterCenterFreq Opt
+
+

For use with FMOD_INIT_CHANNEL_DISTANCEFILTER, the default center frequency for the distance filter.

+
    +
  • Units: Hertz
  • +
  • Default: 1500
  • +
  • Range: [10, 22050]
  • +
+
+
reverb3Dinstance Opt
+
+

For use with Reverb3D, selects which global reverb instance to use.

+
    +
  • Range: [0, FMOD_REVERB_MAXINSTANCES)
  • +
+
+
DSPBufferPoolSize Opt
+
+

Number of intermediate mixing buffers in the DSP buffer pool. Each buffer in bytes is bufferlength (See System::getDSPBufferSize) * sizeof(float) * output mode speaker count (See FMOD_SPEAKERMODE). ie 7.1 @ 1024 DSP block size = 1024 * 4 * 8 = 32KB.

+
    +
  • Default: 8
  • +
+
+
resamplerMethod Opt
+
Resampling method used by Channels. (FMOD_DSP_RESAMPLER)
+
randomSeed Opt
+
Seed value to initialize the internal random number generator.
+
maxConvolutionThreads Opt
+
+

Maximum number of CPU threads to use for FMOD_DSP_TYPE_CONVOLUTIONREVERB effect. 1 = effect is entirely processed inside the FMOD_THREAD_TYPE_MIXER thread. 2 and 3 offloads different parts of the convolution processing into different threads (FMOD_THREAD_TYPE_CONVOLUTION1 and FMOD_THREAD_TYPE_CONVOLUTION2 to increase throughput.

+
    +
  • Default: 3
  • +
  • Range: [0, 3]
  • +
+
+
maxSpatialObjects Opt
+
+

Maximum Spatial Objects that can be reserved per FMOD system. FMOD_OUTPUTTYPE_AUDIO3D is a special case where multiple FMOD systems are not allowed. See the Object based approach section of the Core API Spatializing Sounds chapter. A value of -1 means no Spatial Objects will be reserved. A value of 0 means all available Spatial Objects will be reserved. Any other value means it will reserve that many Spatial Objects.

+
    +
  • Default: 0
  • +
  • Range: [-1, 65535]
  • +
+
+
+

All members have a default of 0 except for cbSize, so clearing the whole structure to zeroes first then setting cbSize is a common use pattern.

+

Specifying one of the codec maximums will help determine the maximum CPU usage of playing FMOD_CREATECOMPRESSEDSAMPLE Sounds of that type as well as the memory requirements. Memory will be allocated for 'up front' (during System::init) if these values are specified as non zero. If any are zero, it allocates memory for the codec whenever a file of the type in question is loaded. So if maxMPEGCodecs is 0 for example, it will allocate memory for the MPEG codecs the first time an MP3 is loaded or an MP3 based .FSB file is loaded.

+

Setting DSPBufferPoolSize pre-allocates memory for the FMOD DSP graph. See the DSP Architecture and Usage section of the Using DSP Effects in the Core API chapter. By default, eight buffers are created up front. A large graph might require more if the aim is to avoid real-time allocations from the FMOD mixer thread.

+

See Also: System::setAdvancedSettings, System::getAdvancedSettings

+

FMOD_ASYNCREADINFO

+

Information about a single asynchronous file operation.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
typedef struct FMOD_ASYNCREADINFO {
+  void                      *handle;
+  unsigned int               offset;
+  unsigned int               sizebytes;
+  int                        priority;
+  void                      *userdata;
+  void                      *buffer;
+  unsigned int               bytesread;
+  FMOD_FILE_ASYNCDONE_FUNC   done;
+} FMOD_ASYNCREADINFO;
+
+ +
struct ASYNCREADINFO
+{
+  IntPtr                      handle;
+  uint                        offset;
+  uint                        sizebytes;
+  int                         priority;
+  IntPtr                      userdata;
+  IntPtr                      buffer;
+  uint                        bytesread;
+  FILE_ASYNCDONE_FUNC         done;
+}
+
+ +
+

Not supported for JavaScript.

+
+
+
handle R/O
+
File handle that was returned in FMOD_FILE_OPEN_CALLBACK.
+
offset R/O
+
Offset within the file where the read operation should occur.
+
+
    +
  • Units: Bytes
  • +
+
+
sizebytes R/O
+
Number of bytes to read.
+
+
    +
  • Units: Bytes
  • +
+
+
priority R/O
+
Priority hint for how quickly this operation should be serviced where 0 represents low importance and 100 represents extreme importance. This could be used to prioritize the read order of a file job queue for example. FMOD decides the importance of the read based on if it could degrade audio or not.
+
userdata Opt
+
User value associated with this async operation, passed to FMOD_FILE_ASYNCCANCEL_CALLBACK.
+
buffer
+
Buffer to read data into.
+
bytesread
+
Number of bytes read into buffer.
+
+
    +
  • Units: Bytes
  • +
+
+
done R/O
+
Completion function to signal the async read is done. (FMOD_FILE_ASYNCDONE_FUNC)
+
+

When servicing the async read operation, read from handle at the given offset for sizebytes into buffer. Write the number of bytes read into bytesread then call done with the FMOD_RESULT that matches the success of the operation.

+

See Also: FMOD_FILE_ASYNCREAD_CALLBACK

+

FMOD_CREATESOUNDEXINFO

+

Additional options for creating a Sound.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
typedef struct FMOD_CREATESOUNDEXINFO {
+  int                              cbsize;
+  unsigned int                     length;
+  unsigned int                     fileoffset;
+  int                              numchannels;
+  int                              defaultfrequency;
+  FMOD_SOUND_FORMAT                format;
+  unsigned int                     decodebuffersize;
+  int                              initialsubsound;
+  int                              numsubsounds;
+  int                             *inclusionlist;
+  int                              inclusionlistnum;
+  FMOD_SOUND_PCMREAD_CALLBACK      pcmreadcallback;
+  FMOD_SOUND_PCMSETPOS_CALLBACK    pcmsetposcallback;
+  FMOD_SOUND_NONBLOCK_CALLBACK     nonblockcallback;
+  const char                      *dlsname;
+  const char                      *encryptionkey;
+  int                              maxpolyphony;
+  void                            *userdata;
+  FMOD_SOUND_TYPE                  suggestedsoundtype;
+  FMOD_FILE_OPEN_CALLBACK          fileuseropen;
+  FMOD_FILE_CLOSE_CALLBACK         fileuserclose;
+  FMOD_FILE_READ_CALLBACK          fileuserread;
+  FMOD_FILE_SEEK_CALLBACK          fileuserseek;
+  FMOD_FILE_ASYNCREAD_CALLBACK     fileuserasyncread;
+  FMOD_FILE_ASYNCCANCEL_CALLBACK   fileuserasynccancel;
+  void                            *fileuserdata;
+  int                              filebuffersize;
+  FMOD_CHANNELORDER                channelorder;
+  FMOD_SOUNDGROUP                 *initialsoundgroup;
+  unsigned int                     initialseekposition;
+  FMOD_TIMEUNIT                    initialseekpostype;
+  int                              ignoresetfilesystem;
+  unsigned int                     audioqueuepolicy;
+  unsigned int                     minmidigranularity;
+  int                              nonblockthreadid;
+  FMOD_GUID                       *fsbguid;
+} FMOD_CREATESOUNDEXINFO;
+
+ +
struct CREATESOUNDEXINFO
+{
+  int                      cbsize;
+  uint                     length;
+  uint                     fileoffset;
+  int                      numchannels;
+  int                      defaultfrequency;
+  SOUND_FORMAT             format;
+  uint                     decodebuffersize;
+  int                      initialsubsound;
+  int                      numsubsounds;
+  IntPtr                   inclusionlist;
+  int                      inclusionlistnum;
+  SOUND_PCMREADCALLBACK    pcmreadcallback;
+  SOUND_PCMSETPOSCALLBACK  pcmsetposcallback;
+  SOUND_NONBLOCKCALLBACK   nonblockcallback;
+  IntPtr                   dlsname;
+  IntPtr                   encryptionkey;
+  int                      maxpolyphony;
+  IntPtr                   userdata;
+  SOUND_TYPE               suggestedsoundtype;
+  FILE_OPENCALLBACK        fileuseropen;
+  FILE_CLOSECALLBACK       fileuserclose;
+  FILE_READCALLBACK        fileuserread;
+  FILE_SEEKCALLBACK        fileuserseek;
+  FILE_ASYNCREADCALLBACK   fileuserasyncread;
+  FILE_ASYNCCANCELCALLBACK fileuserasynccancel;
+  IntPtr                   fileuserdata;
+  int                      filebuffersize;
+  CHANNELORDER             channelorder;
+  IntPtr                   initialsoundgroup;
+  uint                     initialseekposition;
+  TIMEUNIT                 initialseekpostype;
+  int                      ignoresetfilesystem;
+  uint                     audioqueuepolicy;
+  uint                     minmidigranularity;
+  int                      nonblockthreadid;
+  IntPtr                   fsbguid;
+}
+
+ +
CREATESOUNDEXINFO
+{
+  length,
+  fileoffset,
+  numchannels,
+  defaultfrequency,
+  format,
+  decodebuffersize,
+  initialsubsound,
+  numsubsounds,
+  inclusionlist,
+  inclusionlistnum,
+  pcmreadcallback,
+  pcmsetposcallback,
+  nonblockcallback,
+  dlsname,
+  encryptionkey,
+  maxpolyphony,
+  userdata,
+  suggestedsoundtype,
+  fileuseropen,
+  fileuserclose,
+  fileuserread,
+  fileuserseek,
+  fileuserasyncread,
+  fileuserasynccancel,
+  fileuserdata,
+  filebuffersize,
+  channelorder,
+  initialsoundgroup,
+  initialseekposition,
+  initialseekpostype,
+  ignoresetfilesystem,
+  audioqueuepolicy,
+  minmidigranularity,
+  nonblockthreadid,
+};
+
+ +
+
cbsize
+
Size of this structure. Must be set to sizeof(FMOD_CREATESOUNDEXINFO) before calling System::createSound or System::createStream.
+
length Opt
+
+

Bytes to read starting at fileoffset, or length of Sound to create for FMOD_OPENUSER, or length of name_or_data for FMOD_OPENMEMORY / FMOD_OPENMEMORY_POINT.

+
    +
  • Units: Bytes
  • +
+
+
fileoffset Opt
+
+

File offset to start reading from.

+
    +
  • Units: Bytes
  • +
+
+
numchannels Opt
+
+

Number of channels in sound data for FMOD_OPENUSER / FMOD_OPENRAW.

+ +
+
defaultfrequency Opt
+
+

Default frequency of sound data for FMOD_OPENUSER / FMOD_OPENRAW.

+
    +
  • Units: Hertz
  • +
+
+
format Opt
+
Format of sound data for FMOD_OPENUSER / FMOD_OPENRAW. (FMOD_SOUND_FORMAT)
+
decodebuffersize Opt
+
+

Size of the decoded buffer for FMOD_CREATESTREAM, or the block size used with pcmreadcallback for FMOD_OPENUSER.

+ +
+
initialsubsound Opt
+
Initial subsound to seek to for FMOD_CREATESTREAM.
+
numsubsounds Opt
+
Number of subsounds available for FMOD_OPENUSER, or maximum subsounds to load from file.
+
inclusionlist Opt
+
List of subsound indices to load from file.
+
inclusionlistnum Opt
+
Number of items in inclusionlist.
+
pcmreadcallback Opt
+
Callback to provide audio for FMOD_OPENUSER, or capture audio as it is decoded. (FMOD_SOUND_PCMREAD_CALLBACK)
+
pcmsetposcallback Opt
+
Callback to perform seeking for FMOD_OPENUSER, or capture seek requests. (FMOD_SOUND_PCMSETPOS_CALLBACK)
+
nonblockcallback Opt
+
Callback to notify completion for FMOD_NONBLOCKING, occurs during creation and seeking / restarting streams. (FMOD_SOUND_NONBLOCK_CALLBACK)
+
dlsname Opt
+
File path for a FMOD_SOUND_TYPE_DLS sample set to use when loading a FMOD_SOUND_TYPE_MIDI file, see below for defaults.
+
encryptionkey Opt
+
Key for encrypted FMOD_SOUND_TYPE_FSB file, cannot be used in conjunction with FMOD_OPENMEMORY_POINT.
+
maxpolyphony Opt
+
+

Maximum voice count for FMOD_SOUND_TYPE_MIDI / FMOD_SOUND_TYPE_IT.

+
    +
  • Default: 64
  • +
+
+
userdata Opt
+
User data to be attached to the Sound during creation, access via Sound::getUserData.
+
suggestedsoundtype Opt
+
Attempt to load using the specified type first instead of loading in codec priority order. (FMOD_SOUND_TYPE)
+
fileuseropen Opt
+
Callback for opening this file. (FMOD_FILE_OPEN_CALLBACK)
+
fileuserclose Opt
+
Callback for closing this file. (FMOD_FILE_CLOSE_CALLBACK)
+
fileuserread Opt
+
Callback for reading from this file. (FMOD_FILE_READ_CALLBACK)
+
fileuserseek Opt
+
Callback for seeking within this file. (FMOD_FILE_SEEK_CALLBACK)
+
fileuserasyncread Opt
+
Callback for seeking within this file. (FMOD_FILE_ASYNCREAD_CALLBACK)
+
fileuserasynccancel Opt
+
Callback for seeking within this file. (FMOD_FILE_ASYNCCANCEL_CALLBACK)
+
fileuserdata Opt
+
User data to be passed into the file callbacks.
+
filebuffersize Opt
+
Buffer size for reading the file, -1 to disable buffering.
+
channelorder Opt
+
Custom ordering of speakers for this sound data. (FMOD_CHANNELORDER)
+
initialsoundgroup Opt
+
SoundGroup to place this Sound in once created. (SoundGroup)
+
initialseekposition Opt
+
Initial position to seek to for FMOD_CREATESTREAM.
+
initialseekpostype Opt
+
Time units for initialseekposition. (FMOD_TIMEUNIT)
+
ignoresetfilesystem Opt
+
Ignore System::setFileSystem and FMOD_CREATESOUNDEXINFO file callbacks.
+
audioqueuepolicy Opt
+
Hardware / software decoding policy for FMOD_SOUND_TYPE_AUDIOQUEUE, see FMOD_AUDIOQUEUE_CODECPOLICY.
+
minmidigranularity Opt
+
+

Mixer granularity for FMOD_SOUND_TYPE_MIDI sounds, smaller numbers give a more accurate reproduction at the cost of higher CPU usage.

+
    +
  • Units: Samples
  • +
  • Default: 512
  • +
+
+
nonblockthreadid Opt
+
+

Thread index to execute FMOD_NONBLOCKING loads on for parallel Sound loading. Not supported on HTML5.

+
    +
  • Range: [0, 4]
  • +
+
+
fsbguid Opt
+
On input, GUID of already loaded FMOD_SOUND_TYPE_FSB file to reduce disk access, on output, GUID of loaded FSB. (FMOD_GUID)
+
+

Loading a file from memory:

+
    +
  • Create the sound using the FMOD_OPENMEMORY flag.
  • +
  • Specify length for the size of the memory block in bytes.
  • +
+

Loading a file from within another larger (possibly wad/pak) file, by giving the loader an offset and length:

+
    +
  • Specify fileoffset and length.
  • +
+

Create a user created / non-file based sound:

+
    +
  • Create the sound using the FMOD_OPENUSER flag.
  • +
  • Specify defaultfrequency, numchannels and format.
  • +
+

Load an FSB stream seeking to a specific subsound in one file operation:

+ +

Load a subset of the Sounds in an FSB saving memory:

+
    +
  • Specify inclusionlist and inclusionlistnum.
  • +
  • Optionally set numsubsounds to match 'inclusionlistnum', saves memory and causes Sound::getSubSound to index into inclusionlist.
  • +
+

Capture sound data as it is decoded:

+
    +
  • Specify pcmreadcallback and pcmseekcallback.
  • +
+

Provide a custom DLS for MIDI playback:

+
    +
  • Specify dlsname.
  • +
+

Setting the decodebuffersize is for CPU intensive codecs that may be causing stuttering, not file intensive codecs (i.e. those from CD or net streams) which are normally altered with System::setStreamBufferSize. As an example of CPU intensive codecs, an MP3 file will take more CPU to decode than a PCM wav file.

+

If you hear stuttering, then the codec is using more CPU than the decode buffer playback rate can keep up with. Increasing the decodebuffersize is likely to solve this problem.

+

FSB codec. If inclusionlist and numsubsounds are used together, this will trigger a special mode where subsounds are shuffled down to save memory (useful for large FSB files where you only want to load 1 sound). There will be no gaps, ie no null subsounds. As an example, if there are 10,000 subsounds and there is an inclusionlist with only 1 entry, and numsubsounds = 1, then subsound 0 will be that entry, and there will only be the memory allocated for 1 subsound. Previously there would still be 10,000 subsound pointers and other associated codec entries allocated along with it multiplied by 10,000.

+

See Also: Callback Behavior, System::createSound

+

FMOD_DRIVER_STATE

+

Flags that provide additional information about a particular driver.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
#define FMOD_DRIVER_STATE_CONNECTED   0x00000001
+#define FMOD_DRIVER_STATE_DEFAULT     0x00000002
+
+ +
[Flags]
+enum DRIVER_STATE : uint
+{
+  CONNECTED = 0x00000001,
+  DEFAULT   = 0x00000002,
+}
+
+ +
DRIVER_STATE_CONNECTED = 0x00000001
+DRIVER_STATE_DEFAULT   = 0x00000002
+
+ +
+
FMOD_DRIVER_STATE_CONNECTED
+
Device is currently plugged in.
+
FMOD_DRIVER_STATE_DEFAULT
+
Device is the users preferred choice.
+
+

See Also: System::getRecordDriverInfo

+

FMOD_DSP_RESAMPLER

+

List of interpolation types used for resampling.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
typedef enum FMOD_DSP_RESAMPLER {
+  FMOD_DSP_RESAMPLER_DEFAULT,
+  FMOD_DSP_RESAMPLER_NOINTERP,
+  FMOD_DSP_RESAMPLER_LINEAR,
+  FMOD_DSP_RESAMPLER_CUBIC,
+  FMOD_DSP_RESAMPLER_SPLINE,
+  FMOD_DSP_RESAMPLER_MAX
+} FMOD_DSP_RESAMPLER;
+
+ +
enum DSP_RESAMPLER : int
+{
+  DEFAULT,
+  NOINTERP,
+  LINEAR,
+  CUBIC,
+  SPLINE,
+  MAX
+}
+
+ +
DSP_RESAMPLER_DEFAULT
+DSP_RESAMPLER_NOINTERP
+DSP_RESAMPLER_LINEAR
+DSP_RESAMPLER_CUBIC
+DSP_RESAMPLER_SPLINE
+DSP_RESAMPLER_MAX
+
+ +
+
FMOD_DSP_RESAMPLER_DEFAULT
+
Default interpolation method, same as FMOD_DSP_RESAMPLER_LINEAR.
+
FMOD_DSP_RESAMPLER_NOINTERP
+
No interpolation. High frequency aliasing hiss will be audible depending on the sample rate of the sound.
+
FMOD_DSP_RESAMPLER_LINEAR
+
Linear interpolation (default method). Fast and good quality, causes very slight lowpass effect on low frequency sounds.
+
FMOD_DSP_RESAMPLER_CUBIC
+
Cubic interpolation. Slower than linear interpolation but better quality.
+
FMOD_DSP_RESAMPLER_SPLINE
+
5 point spline interpolation. Slowest resampling method but best quality.
+
FMOD_DSP_RESAMPLER_MAX
+
Maximum number of resample methods supported.
+
+

Use System::setAdvancedSettings and FMOD_ADVANCEDSETTINGS::resamplerMethod to configure the resampling quality you require for sample rate conversion during sound playback.

+

FMOD_ERRORCALLBACK_INFO

+

Information describing an error that has occurred.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
typedef struct FMOD_ERRORCALLBACK_INFO {
+  FMOD_RESULT                       result;
+  FMOD_ERRORCALLBACK_INSTANCETYPE   instancetype;
+  void                             *instance;
+  const char                       *functionname;
+  const char                       *functionparams;
+} FMOD_ERRORCALLBACK_INFO;
+
+ +
struct ERRORCALLBACK_INFO
+{
+  RESULT                      result;
+  ERRORCALLBACK_INSTANCETYPE  instancetype;
+  IntPtr                      instance;
+  StringWrapper               functionname;
+  StringWrapper               functionparams;
+}
+
+ +
ERRORCALLBACK_INFO
+{
+  result,
+  instancetype,
+  instance,
+  functionname,
+  functionparams,
+};
+
+ +
+
result
+
Error code result. (FMOD_RESULT)
+
instancetype
+
Type of instance the error occurred on. (FMOD_ERRORCALLBACK_INSTANCETYPE)
+
instance
+
Instance pointer.
+
functionname
+
Function that the error occurred on. (UTF-8 string)
+
functionparams
+
Function parameters that the error ocurred on. (UTF-8 string)
+
+

The instance pointer will be a type corresponding to the instanceType enum.

+

See Also: FMOD_SYSTEM_CALLBACK, FMOD_SYSTEM_CALLBACK_ERROR

+

FMOD_ERRORCALLBACK_INSTANCETYPE

+

Identifier used to represent the different types of instance in the error callback.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
typedef enum FMOD_ERRORCALLBACK_INSTANCETYPE {
+  FMOD_ERRORCALLBACK_INSTANCETYPE_NONE,
+  FMOD_ERRORCALLBACK_INSTANCETYPE_SYSTEM,
+  FMOD_ERRORCALLBACK_INSTANCETYPE_CHANNEL,
+  FMOD_ERRORCALLBACK_INSTANCETYPE_CHANNELGROUP,
+  FMOD_ERRORCALLBACK_INSTANCETYPE_CHANNELCONTROL,
+  FMOD_ERRORCALLBACK_INSTANCETYPE_SOUND,
+  FMOD_ERRORCALLBACK_INSTANCETYPE_SOUNDGROUP,
+  FMOD_ERRORCALLBACK_INSTANCETYPE_DSP,
+  FMOD_ERRORCALLBACK_INSTANCETYPE_DSPCONNECTION,
+  FMOD_ERRORCALLBACK_INSTANCETYPE_GEOMETRY,
+  FMOD_ERRORCALLBACK_INSTANCETYPE_REVERB3D,
+  FMOD_ERRORCALLBACK_INSTANCETYPE_STUDIO_SYSTEM,
+  FMOD_ERRORCALLBACK_INSTANCETYPE_STUDIO_EVENTDESCRIPTION,
+  FMOD_ERRORCALLBACK_INSTANCETYPE_STUDIO_EVENTINSTANCE,
+  FMOD_ERRORCALLBACK_INSTANCETYPE_STUDIO_PARAMETERINSTANCE,
+  FMOD_ERRORCALLBACK_INSTANCETYPE_STUDIO_BUS,
+  FMOD_ERRORCALLBACK_INSTANCETYPE_STUDIO_VCA,
+  FMOD_ERRORCALLBACK_INSTANCETYPE_STUDIO_BANK,
+  FMOD_ERRORCALLBACK_INSTANCETYPE_STUDIO_COMMANDREPLAY
+} FMOD_ERRORCALLBACK_INSTANCETYPE;
+
+ +
enum ERRORCALLBACK_INSTANCETYPE
+{
+  NONE,
+  SYSTEM,
+  CHANNEL,
+  CHANNELGROUP,
+  CHANNELCONTROL,
+  SOUND,
+  SOUNDGROUP,
+  DSP,
+  DSPCONNECTION,
+  GEOMETRY,
+  REVERB3D,
+  STUDIO_SYSTEM,
+  STUDIO_EVENTDESCRIPTION,
+  STUDIO_EVENTINSTANCE,
+  STUDIO_PARAMETERINSTANCE,
+  STUDIO_BUS,
+  STUDIO_VCA,
+  STUDIO_BANK,
+  STUDIO_COMMANDREPLAY
+}
+
+ +
ERRORCALLBACK_INSTANCETYPE_NONE
+ERRORCALLBACK_INSTANCETYPE_SYSTEM
+ERRORCALLBACK_INSTANCETYPE_CHANNEL
+ERRORCALLBACK_INSTANCETYPE_CHANNELGROUP
+ERRORCALLBACK_INSTANCETYPE_CHANNELCONTROL
+ERRORCALLBACK_INSTANCETYPE_SOUND
+ERRORCALLBACK_INSTANCETYPE_SOUNDGROUP
+ERRORCALLBACK_INSTANCETYPE_DSP
+ERRORCALLBACK_INSTANCETYPE_DSPCONNECTION
+ERRORCALLBACK_INSTANCETYPE_GEOMETRY
+ERRORCALLBACK_INSTANCETYPE_REVERB3D
+ERRORCALLBACK_INSTANCETYPE_STUDIO_SYSTEM
+ERRORCALLBACK_INSTANCETYPE_STUDIO_EVENTDESCRIPTION
+ERRORCALLBACK_INSTANCETYPE_STUDIO_EVENTINSTANCE
+ERRORCALLBACK_INSTANCETYPE_STUDIO_PARAMETERINSTANCE
+ERRORCALLBACK_INSTANCETYPE_STUDIO_BUS
+ERRORCALLBACK_INSTANCETYPE_STUDIO_VCA
+ERRORCALLBACK_INSTANCETYPE_STUDIO_BANK
+ERRORCALLBACK_INSTANCETYPE_STUDIO_COMMANDREPLAY
+
+ +
+
FMOD_ERRORCALLBACK_INSTANCETYPE_NONE
+
Type representing no known instance type.
+
FMOD_ERRORCALLBACK_INSTANCETYPE_SYSTEM
+
Type representing System.
+
FMOD_ERRORCALLBACK_INSTANCETYPE_CHANNEL
+
Type representing Channel.
+
FMOD_ERRORCALLBACK_INSTANCETYPE_CHANNELGROUP
+
Type representing ChannelGroup.
+
FMOD_ERRORCALLBACK_INSTANCETYPE_CHANNELCONTROL
+
Type representing ChannelControl.
+
FMOD_ERRORCALLBACK_INSTANCETYPE_SOUND
+
Type representing Sound.
+
FMOD_ERRORCALLBACK_INSTANCETYPE_SOUNDGROUP
+
Type representing SoundGroup.
+
FMOD_ERRORCALLBACK_INSTANCETYPE_DSP
+
Type representing DSP.
+
FMOD_ERRORCALLBACK_INSTANCETYPE_DSPCONNECTION
+
Type representing DSPConnection.
+
FMOD_ERRORCALLBACK_INSTANCETYPE_GEOMETRY
+
Type representing Geometry.
+
FMOD_ERRORCALLBACK_INSTANCETYPE_REVERB3D
+
Type representing Reverb3D.
+
FMOD_ERRORCALLBACK_INSTANCETYPE_STUDIO_SYSTEM
+
Type representing Studio::System.
+
FMOD_ERRORCALLBACK_INSTANCETYPE_STUDIO_EVENTDESCRIPTION
+
Type representing Studio::EventDescription.
+
FMOD_ERRORCALLBACK_INSTANCETYPE_STUDIO_EVENTINSTANCE
+
Type representing Studio::EventInstance.
+
FMOD_ERRORCALLBACK_INSTANCETYPE_STUDIO_PARAMETERINSTANCE
+
Deprecated.
+
FMOD_ERRORCALLBACK_INSTANCETYPE_STUDIO_BUS
+
Type representing Studio::Bus.
+
FMOD_ERRORCALLBACK_INSTANCETYPE_STUDIO_VCA
+
Type representing Studio::VCA.
+
FMOD_ERRORCALLBACK_INSTANCETYPE_STUDIO_BANK
+
Type representing Studio::Bank.
+
FMOD_ERRORCALLBACK_INSTANCETYPE_STUDIO_COMMANDREPLAY
+
Type representing Studio::CommandReplay.
+
+

See Also: FMOD_ERRORCALLBACK_INFO, FMOD_SYSTEM_CALLBACK, FMOD_SYSTEM_CALLBACK_ERROR

+

FMOD_FILE_ASYNCCANCEL_CALLBACK

+

Callback for cancelling a pending asynchronous read.

+

This callback is called to stop/release or shut down the resource that is holding the file, for example: releasing a Sound stream.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
FMOD_RESULT F_CALL FMOD_FILE_ASYNCCANCEL_CALLBACK(
+  FMOD_ASYNCREADINFO *info,
+  void *userdata
+);
+
+ +
delegate RESULT FILE_ASYNCCANCELCALLBACK(
+  IntPtr info,
+  IntPtr userdata
+);
+
+ +
+

Not supported for JavaScript.

+
+
+
info
+
Information describing the asynchronous read operation to cancel. (FMOD_ASYNCREADINFO)
+
userdata Opt
+
User value set by FMOD_CREATESOUNDEXINFO::fileuserdata or FMOD_STUDIO_BANK_INFO::userData.
+
+

Before returning from this callback the implementation must ensure that all references to info are relinquished.

+

See Also: System::setFileSystem, FMOD_FILE_OPEN_CALLBACK, FMOD_FILE_CLOSE_CALLBACK, FMOD_FILE_READ_CALLBACK, FMOD_FILE_SEEK_CALLBACK, FMOD_FILE_ASYNCREAD_CALLBACK

+

FMOD_FILE_ASYNCDONE_FUNC

+

Function to be called when asynchronous reading is finished.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
void F_CALL FMOD_FILE_ASYNCDONE_FUNC(
+  FMOD_ASYNCREADINFO *info,
+  FMOD_RESULT result
+);
+
+ +
delegate void FILE_ASYNCDONE_FUNC(
+  IntPtr info,
+  RESULT result
+);
+
+ +
+

Not supported for JavaScript.

+
+
+
info
+
Async info for the completed operation. (FMOD_ASYNCREADINFO)
+
result
+
The result of the read operation. (FMOD_RESULT)
+
+

Relevant result codes to use with this function include:

+ +

FMOD_FILE_ASYNCREAD_CALLBACK

+

Callback for reading from a file asynchronously.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
FMOD_RESULT F_CALL FMOD_FILE_ASYNCREAD_CALLBACK(
+  FMOD_ASYNCREADINFO *info,
+  void *userdata
+);
+
+ +
delegate RESULT FILE_ASYNCREADCALLBACK(
+  IntPtr info,
+  IntPtr userdata
+);
+
+ +
+

Not supported for JavaScript.

+
+
+
info
+
Information describing the requested asynchronous read operation. (FMOD_ASYNCREADINFO)
+
userdata Opt
+
User value set by FMOD_CREATESOUNDEXINFO::fileuserdata or FMOD_STUDIO_BANK_INFO::userData.
+
+

This callback allows you to accept a file I/O request without servicing it immediately. The callback can queue or store the FMOD_ASYNCREADINFO structure pointer, so that a 'servicing routine' can read the data and mark the job as done.

+

Marking an asynchronous job as 'done' outside of this callback can be done by calling the FMOD_ASYNCREADINFO::done function pointer with the file read result as a parameter.

+

If the servicing routine is processed in the same thread as the thread that invokes this callback (for example the thread that calls System::createSound or System::createStream), a deadlock will occur because while System::createSound or System::createStream waits for the file data, the servicing routine in the main thread won't be able to execute.

+

This typically means an outside servicing routine should typically be run in a separate thread.

+

The read request can be queued or stored and this callback can return immediately with FMOD_OK. Returning an error at this point will cause FMOD to stop what it was doing and return back to the caller. If it is from FMOD's stream thread, the stream will typically stop.

+

See Also: System::setFileSystem, FMOD_FILE_OPEN_CALLBACK, FMOD_FILE_CLOSE_CALLBACK, FMOD_FILE_READ_CALLBACK, FMOD_FILE_SEEK_CALLBACK, FMOD_FILE_ASYNCCANCEL_CALLBACK

+

FMOD_FILE_CLOSE_CALLBACK

+

Calback for closing a file.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
FMOD_RESULT F_CALL FMOD_FILE_CLOSE_CALLBACK(
+  void *handle,
+  void *userdata
+);
+
+ +
delegate RESULT FILE_CLOSECALLBACK(
+  IntPtr handle,
+  IntPtr userdata
+);
+
+ +
function FMOD_FILE_CLOSE_CALLBACK(
+  handle,
+  userdata
+)
+
+ +
+
handle
+
File handle that was returned in FMOD_FILE_OPEN_CALLBACK.
+
userdata
+
User value set by FMOD_CREATESOUNDEXINFO::fileuserdata or FMOD_STUDIO_BANK_INFO::userData.
+
+

Close any user created file handle and perform any cleanup necessary for the file here. If the callback is from System::attachFileSystem, then the return value is ignored.

+

See Also: System::setFileSystem, FMOD_FILE_OPEN_CALLBACK, FMOD_FILE_READ_CALLBACK, FMOD_FILE_SEEK_CALLBACK, FMOD_FILE_ASYNCREAD_CALLBACK, FMOD_FILE_ASYNCCANCEL_CALLBACK

+

FMOD_FILE_OPEN_CALLBACK

+

Callback for opening a file.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
FMOD_RESULT F_CALL FMOD_FILE_OPEN_CALLBACK(
+  const char *name,
+  unsigned int *filesize,
+  void **handle,
+  void *userdata
+);
+
+ +
delegate RESULT FILE_OPENCALLBACK(
+  IntPtr name,
+  ref uint filesize,
+  ref IntPtr handle,
+  IntPtr userdata
+);
+
+ +
function FMOD_FILE_OPEN_CALLBACK(
+  name,
+  filesize,
+  handle,
+  userdata
+)
+
+ +
+
name
+
File name or identifier. (UTF-8 string)
+
filesize Out
+
+

Size of the file.

+
    +
  • Units: Bytes
  • +
+
+
handle Out
+
Handle to identify this file in future file callbacks.
+
userdata
+
User value set by FMOD_CREATESOUNDEXINFO::fileuserdata or FMOD_STUDIO_BANK_INFO::userData.
+
+

Return the appropriate error code such as FMOD_ERR_FILE_NOTFOUND if the file fails to open. If the callback is from System::attachFileSystem, then the return value is ignored.

+
+

The 'name' argument can be used via StringWrapper by using FMOD.StringWrapper nameStr = new FMOD.StringWrapper(name);

+
+

See Also: System::setFileSystem, FMOD_FILE_CLOSE_CALLBACK, FMOD_FILE_READ_CALLBACK, FMOD_FILE_SEEK_CALLBACK, FMOD_FILE_ASYNCREAD_CALLBACK, FMOD_FILE_ASYNCCANCEL_CALLBACK

+

FMOD_FILE_READ_CALLBACK

+

Callback for reading from a file.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
FMOD_RESULT F_CALL FMOD_FILE_READ_CALLBACK(
+  void *handle,
+  void *buffer,
+  unsigned int sizebytes,
+  unsigned int *bytesread,
+  void *userdata
+);
+
+ +
delegate RESULT FILE_READCALLBACK(
+  IntPtr handle,
+  IntPtr buffer,
+  uint sizebytes,
+  ref uint bytesread,
+  IntPtr userdata
+);
+
+ +
function FMOD_FILE_READ_CALLBACK(
+  handle,
+  buffer,
+  sizebytes,
+  bytesread,
+  userdata
+)
+
+ +
+
handle
+
File handle that was returned in FMOD_FILE_OPEN_CALLBACK.
+
buffer Out
+
Buffer to read data into.
+
sizebytes
+
+

Number of bytes to read into buffer.

+
    +
  • Units: Bytes
  • +
+
+
bytesread Out
+
+

Number of bytes read into buffer.

+
    +
  • Units: Bytes
  • +
+
+
userdata
+
User value set by FMOD_CREATESOUNDEXINFO::fileuserdata or FMOD_STUDIO_BANK_INFO::userData.
+
+

If the callback is from System::attachFileSystem, then the return value is ignored.

+

If there is not enough data to read the requested number of bytes, return fewer bytes in the bytesread parameter and and return FMOD_ERR_FILE_EOF.

+

See Also: System::setFileSystem, FMOD_FILE_OPEN_CALLBACK, FMOD_FILE_CLOSE_CALLBACK, FMOD_FILE_SEEK_CALLBACK, FMOD_FILE_ASYNCREAD_CALLBACK, FMOD_FILE_ASYNCCANCEL_CALLBACK

+

FMOD_FILE_SEEK_CALLBACK

+

Callback for seeking within a file.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
FMOD_RESULT F_CALL FMOD_FILE_SEEK_CALLBACK(
+  void *handle,
+  unsigned int pos,
+  void *userdata
+);
+
+ +
delegate RESULT FILE_SEEKCALLBACK(
+  IntPtr handle,
+  uint pos,
+  IntPtr userdata
+);
+
+ +
function FMOD_FILE_SEEK_CALLBACK(
+  handle,
+  pos,
+  userdata
+)
+
+ +
+
handle
+
File handle that returned in FMOD_FILE_OPEN_CALLBACK.
+
pos
+
+

Absolute position to seek to in file.

+
    +
  • Units: Bytes
  • +
+
+
userdata
+
User value set by FMOD_CREATESOUNDEXINFO::fileuserdata or FMOD_STUDIO_BANK_INFO::userData.
+
+

If the callback is from System::attachFileSystem, then the return value is ignored.

+

See Also: System::setFileSystem, FMOD_FILE_OPEN_CALLBACK, FMOD_FILE_CLOSE_CALLBACK, FMOD_FILE_READ_CALLBACK, FMOD_FILE_ASYNCREAD_CALLBACK, FMOD_FILE_ASYNCCANCEL_CALLBACK

+

FMOD_INITFLAGS

+

Configuration flags used when initializing the System object.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
#define FMOD_INIT_NORMAL                     0x00000000
+#define FMOD_INIT_STREAM_FROM_UPDATE         0x00000001
+#define FMOD_INIT_MIX_FROM_UPDATE            0x00000002
+#define FMOD_INIT_3D_RIGHTHANDED             0x00000004
+#define FMOD_INIT_CLIP_OUTPUT                0x00000008
+#define FMOD_INIT_CHANNEL_LOWPASS            0x00000100
+#define FMOD_INIT_CHANNEL_DISTANCEFILTER     0x00000200
+#define FMOD_INIT_PROFILE_ENABLE             0x00010000
+#define FMOD_INIT_VOL0_BECOMES_VIRTUAL       0x00020000
+#define FMOD_INIT_GEOMETRY_USECLOSEST        0x00040000
+#define FMOD_INIT_PREFER_DOLBY_DOWNMIX       0x00080000
+#define FMOD_INIT_THREAD_UNSAFE              0x00100000
+#define FMOD_INIT_PROFILE_METER_ALL          0x00200000
+#define FMOD_INIT_MEMORY_TRACKING            0x00400000
+
+ +
[Flags]
+enum INITFLAGS : uint
+{
+  NORMAL                     = 0x00000000,
+  STREAM_FROM_UPDATE         = 0x00000001,
+  MIX_FROM_UPDATE            = 0x00000002,
+  _3D_RIGHTHANDED            = 0x00000004,
+  CLIP_OUTPUT                = 0x00000008,
+  CHANNEL_LOWPASS            = 0x00000100,
+  CHANNEL_DISTANCEFILTER     = 0x00000200,
+  PROFILE_ENABLE             = 0x00010000,
+  VOL0_BECOMES_VIRTUAL       = 0x00020000,
+  GEOMETRY_USECLOSEST        = 0x00040000,
+  PREFER_DOLBY_DOWNMIX       = 0x00080000,
+  THREAD_UNSAFE              = 0x00100000,
+  PROFILE_METER_ALL          = 0x00200000,
+  MEMORY_TRACKING            = 0x00400000,
+}
+
+ +
INIT_NORMAL                 = 0x00000000
+INIT_STREAM_FROM_UPDATE     = 0x00000001
+INIT_MIX_FROM_UPDATE        = 0x00000002
+INIT_3D_RIGHTHANDED         = 0x00000004
+INIT_CLIP_OUTPUT            = 0x00000008
+INIT_CHANNEL_LOWPASS        = 0x00000100
+INIT_CHANNEL_DISTANCEFILTER = 0x00000200
+INIT_PROFILE_ENABLE         = 0x00010000
+INIT_VOL0_BECOMES_VIRTUAL   = 0x00020000
+INIT_GEOMETRY_USECLOSEST    = 0x00040000
+INIT_PREFER_DOLBY_DOWNMIX   = 0x00080000
+INIT_THREAD_UNSAFE          = 0x00100000
+INIT_PROFILE_METER_ALL      = 0x00200000
+INIT_MEMORY_TRACKING        = 0x00400000
+
+ +
+
FMOD_INIT_NORMAL
+
Initialize normally
+
FMOD_INIT_STREAM_FROM_UPDATE
+
No stream thread is created internally. Streams are driven from System::update. Mainly used with non-realtime outputs.
+
FMOD_INIT_MIX_FROM_UPDATE
+
No mixer thread is created internally. Mixing is driven from System::update. Only applies to polling based output modes such as FMOD_OUTPUTTYPE_NOSOUND, FMOD_OUTPUTTYPE_WAVWRITER.
+
FMOD_INIT_3D_RIGHTHANDED
+
3D calculations will be performed in right-handed coordinates, instead of the default of left-handed coordinates. See the Handedness section of the Glossary for more information.
+
FMOD_INIT_CLIP_OUTPUT
+
Enables hard clipping of output values greater than 1.0f or less than -1.0f.
+
FMOD_INIT_CHANNEL_LOWPASS
+
Enables usage of ChannelControl::setLowPassGain, ChannelControl::set3DOcclusion, or automatic usage by the Geometry API. All voices will add a software lowpass filter effect into the DSP chain which is idle unless one of the previous functions/features are used.
+
FMOD_INIT_CHANNEL_DISTANCEFILTER
+
All FMOD_3D based voices add a software low pass and highpass filter effect into the DSP chain, which acts as a distance-automated bandpass filter. Use System::setAdvancedSettings to adjust the center frequency.
+
FMOD_INIT_PROFILE_ENABLE
+
Enable TCP/IP based host which allows FMOD Studio or FMOD Profiler to connect to it, and view memory, CPU and the DSP graph in real-time.
+
FMOD_INIT_VOL0_BECOMES_VIRTUAL
+
Any sounds that are 0 volume will go virtual and not be processed except for having their positions updated virtually. Use System::setAdvancedSettings to adjust what volume besides zero to switch to virtual at.
+
FMOD_INIT_GEOMETRY_USECLOSEST
+
With the geometry engine, only process the closest polygon rather than accumulating all polygons the sound to listener line intersects.
+
FMOD_INIT_PREFER_DOLBY_DOWNMIX
+
When using FMOD_SPEAKERMODE_5POINT1 with a stereo output device, use the Dolby Pro Logic II downmix algorithm instead of the default stereo downmix algorithm.
+
FMOD_INIT_THREAD_UNSAFE
+
Disables thread safety for API calls. Only use this if FMOD is being called from a single thread, and if Studio API is not being used!
+
FMOD_INIT_PROFILE_METER_ALL
+
Slower, but adds level metering for every single DSP unit in the graph. Use DSP::setMeteringEnabled to turn meters off individually. Setting this flag implies FMOD_INIT_PROFILE_ENABLE.
+
FMOD_INIT_MEMORY_TRACKING
+
Enables memory allocation tracking. Currently this is only useful when using the Studio API. Increases memory footprint and reduces performance. This flag is implied by FMOD_STUDIO_INIT_MEMORY_TRACKING.
+
+

See Also: System::init

+

FMOD_OUTPUTTYPE

+

Built-in output types that can be used to run the mixer.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
typedef enum FMOD_OUTPUTTYPE {
+  FMOD_OUTPUTTYPE_AUTODETECT,
+  FMOD_OUTPUTTYPE_UNKNOWN,
+  FMOD_OUTPUTTYPE_NOSOUND,
+  FMOD_OUTPUTTYPE_WAVWRITER,
+  FMOD_OUTPUTTYPE_NOSOUND_NRT,
+  FMOD_OUTPUTTYPE_WAVWRITER_NRT,
+  FMOD_OUTPUTTYPE_WASAPI,
+  FMOD_OUTPUTTYPE_ASIO,
+  FMOD_OUTPUTTYPE_PULSEAUDIO,
+  FMOD_OUTPUTTYPE_ALSA,
+  FMOD_OUTPUTTYPE_COREAUDIO,
+  FMOD_OUTPUTTYPE_AUDIOTRACK,
+  FMOD_OUTPUTTYPE_OPENSL,
+  FMOD_OUTPUTTYPE_AUDIOOUT,
+  FMOD_OUTPUTTYPE_AUDIO3D,
+  FMOD_OUTPUTTYPE_WEBAUDIO,
+  FMOD_OUTPUTTYPE_NNAUDIO,
+  FMOD_OUTPUTTYPE_WINSONIC,
+  FMOD_OUTPUTTYPE_AAUDIO,
+  FMOD_OUTPUTTYPE_AUDIOWORKLET,
+  FMOD_OUTPUTTYPE_PHASE,
+  FMOD_OUTPUTTYPE_OHAUDIO,
+  FMOD_OUTPUTTYPE_MAX
+} FMOD_OUTPUTTYPE;
+
+ +
enum OUTPUTTYPE : int
+{
+  AUTODETECT,
+  UNKNOWN,
+  NOSOUND,
+  WAVWRITER,
+  NOSOUND_NRT,
+  WAVWRITER_NRT,
+  WASAPI,
+  ASIO,
+  PULSEAUDIO,
+  ALSA,
+  COREAUDIO,
+  AUDIOTRACK,
+  OPENSL,
+  AUDIOOUT,
+  AUDIO3D,
+  WEBAUDIO,
+  NNAUDIO,
+  WINSONIC,
+  AAUDIO,
+  AUDIOWORKLET,
+  PHASE,
+  OHAUDIO,
+  MAX,
+}
+
+ +
OUTPUTTYPE_AUTODETECT
+OUTPUTTYPE_UNKNOWN
+OUTPUTTYPE_NOSOUND
+OUTPUTTYPE_WAVWRITER
+OUTPUTTYPE_NOSOUND_NRT
+OUTPUTTYPE_WAVWRITER_NRT
+OUTPUTTYPE_WASAPI
+OUTPUTTYPE_ASIO
+OUTPUTTYPE_PULSEAUDIO
+OUTPUTTYPE_ALSA
+OUTPUTTYPE_COREAUDIO
+OUTPUTTYPE_AUDIOTRACK
+OUTPUTTYPE_OPENSL
+OUTPUTTYPE_AUDIOOUT
+OUTPUTTYPE_AUDIO3D
+OUTPUTTYPE_WEBAUDIO
+OUTPUTTYPE_NNAUDIO
+OUTPUTTYPE_WINSONIC
+OUTPUTTYPE_AAUDIO
+OUTPUTTYPE_AUDIOWORKLET
+OUTPUTTYPE_PHASE
+OUTPUTTYPE_OHAUDIO
+OUTPUTTYPE_MAX
+
+ +
+
FMOD_OUTPUTTYPE_AUTODETECT
+
Picks the best output mode for the platform. This is the default.
+
FMOD_OUTPUTTYPE_UNKNOWN
+
All - 3rd party plug-in, unknown. This is for use with System::getOutput only.
+
FMOD_OUTPUTTYPE_NOSOUND
+
All - Perform all mixing but discard the final output.
+
FMOD_OUTPUTTYPE_WAVWRITER
+
All - Writes output to a .wav file.
+
FMOD_OUTPUTTYPE_NOSOUND_NRT
+
All - Non-realtime version of FMOD_OUTPUTTYPE_NOSOUND, one mix per System::update.
+
FMOD_OUTPUTTYPE_WAVWRITER_NRT
+
All - Non-realtime version of FMOD_OUTPUTTYPE_WAVWRITER, one mix per System::update.
+
FMOD_OUTPUTTYPE_WASAPI
+
Win / UWP / Xbox One / Game Core - Windows Audio Session API. (Default on Windows, Xbox One, Game Core and UWP)
+
FMOD_OUTPUTTYPE_ASIO
+
Win - Low latency ASIO 2.0.
+
FMOD_OUTPUTTYPE_PULSEAUDIO
+
Linux - Pulse Audio. (Default on Linux if available)
+
FMOD_OUTPUTTYPE_ALSA
+
Linux - Advanced Linux Sound Architecture. (Default on Linux if PulseAudio isn't available)
+
FMOD_OUTPUTTYPE_COREAUDIO
+
Mac / iOS - Core Audio. (Default on Mac and iOS)
+
FMOD_OUTPUTTYPE_AUDIOTRACK
+
Android - Java Audio Track. (Default on Android 2.2 and below)
+
FMOD_OUTPUTTYPE_OPENSL
+
Android - OpenSL ES. (Default on Android 2.3 up to 7.1)
+
FMOD_OUTPUTTYPE_AUDIOOUT
+
PS4 / PS5 - Audio Out. (Default on PS4, PS5)
+
FMOD_OUTPUTTYPE_AUDIO3D
+
PS4 - Audio3D.
+
FMOD_OUTPUTTYPE_WEBAUDIO
+
HTML5 - Web Audio ScriptProcessorNode output. (Default on HTML5 if AudioWorkletNode isn't available)
+
FMOD_OUTPUTTYPE_NNAUDIO
+
Switch - nn::audio. (Default on Switch)
+
FMOD_OUTPUTTYPE_WINSONIC
+
Win10 / Xbox One / Game Core - Windows Sonic.
+
FMOD_OUTPUTTYPE_AAUDIO
+
Android - AAudio. (Default on Android 8.1 and above)
+
FMOD_OUTPUTTYPE_AUDIOWORKLET
+
HTML5 - Web Audio AudioWorkletNode output. (Default on HTML5 if available)
+
FMOD_OUTPUTTYPE_PHASE
+
iOS - PHASE framework. (Disabled)
+
FMOD_OUTPUTTYPE_OHAUDIO
+
OpenHarmony - OHAudio.
+
FMOD_OUTPUTTYPE_MAX
+
Maximum number of output types supported.
+
+

To pass information to the driver when initializing use the extradriverdata parameter in System::init for the following reasons:

+ +

Currently these are the only FMOD drivers that take extra information. Other unknown plug-ins may have different requirements.

+

If FMOD_OUTPUTTYPE_WAVWRITER_NRT or FMOD_OUTPUTTYPE_NOSOUND_NRT are used, and if the System::update function is being called very quickly (ie for a non realtime decode) it may be being called too quickly for the FMOD streamer thread to respond to. The result will be a skipping/stuttering output in the captured audio. To remedy this, disable the FMOD streamer thread, and use FMOD_INIT_STREAM_FROM_UPDATE to avoid skipping in the output stream, as it will lock the mixer and the streamer together in the same thread.

+

See Also: System::setOutput, System::getOutput

+

FMOD_PLUGINLIST

+

Used to support lists of plug-ins within the one dynamic library.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
typedef struct FMOD_PLUGINLIST {
+  FMOD_PLUGINTYPE  type;
+  void            *description;
+} FMOD_PLUGINLIST;
+
+ +
+

Not supported for C#.

+
+
+

Not supported for JavaScript.

+
+
+
type R/O
+
Plug-in type. (FMOD_PLUGINTYPE)
+
description R/O
+
One of the plug-in description structures. (FMOD_DSP_DESCRIPTION) (FMOD_OUTPUT_DESCRIPTION) (FMOD_CODEC_DESCRIPTION).
+
+

This structure is returned from a plugin as a pointer to a list where the last entry has FMOD_PLUGINTYPE_MAX and a NULL description.

+

See Also: System::getNumNestedPlugins, System::getNestedPlugin

+

FMOD_PLUGINTYPE

+

Types of plug-in used to extend functionality.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
typedef enum FMOD_PLUGINTYPE {
+  FMOD_PLUGINTYPE_OUTPUT,
+  FMOD_PLUGINTYPE_CODEC,
+  FMOD_PLUGINTYPE_DSP,
+  FMOD_PLUGINTYPE_MAX
+} FMOD_PLUGINTYPE;
+
+ +
enum PLUGINTYPE : int
+{
+  OUTPUT,
+  CODEC,
+  DSP,
+  MAX
+}
+
+ +
PLUGINTYPE_OUTPUT
+PLUGINTYPE_CODEC
+PLUGINTYPE_DSP
+PLUGINTYPE_MAX
+
+ +
+
FMOD_PLUGINTYPE_OUTPUT
+
Audio output interface plug-in represented with FMOD_OUTPUT_DESCRIPTION.
+
FMOD_PLUGINTYPE_CODEC
+
File format codec plug-in represented with FMOD_CODEC_DESCRIPTION.
+
FMOD_PLUGINTYPE_DSP
+
DSP unit plug-in represented with FMOD_DSP_DESCRIPTION.
+
FMOD_PLUGINTYPE_MAX
+
Maximum number of plug-in types supported.
+
+

See Also: System::getNumPlugins, System::getPluginInfo, System::unloadPlugin

+

FMOD_PORT_INDEX

+

Output type specific index for when there are multiple instances or destinations for a port type.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
#define FMOD_PORT_INDEX_NONE 0xFFFFFFFFFFFFFFFF
+
+ +
struct PORT_INDEX
+{
+  const ulong NONE = 0xFFFFFFFFFFFFFFFF;
+}
+
+ +
PORT_INDEX_NONE = 0xFFFFFFFFFFFFFFFF
+
+ +
+
FMOD_PORT_INDEX_NONE
+
Use when a port index is not required
+
+

See Also: System::attachChannelGroupToPort, FMOD_PORT_TYPE

+

FMOD_PORT_TYPE

+

Port types available for routing audio.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
typedef enum FMOD_PORT_TYPE
+{
+    FMOD_PORT_TYPE_MUSIC,
+    FMOD_PORT_TYPE_COPYRIGHT_MUSIC,
+    FMOD_PORT_TYPE_VOICE,
+    FMOD_PORT_TYPE_CONTROLLER,
+    FMOD_PORT_TYPE_PERSONAL,
+    FMOD_PORT_TYPE_VIBRATION,
+    FMOD_PORT_TYPE_AUX,
+    FMOD_PORT_TYPE_PASSTHROUGH,
+    FMOD_PORT_TYPE_VR_VIBRATION,
+    FMOD_PORT_TYPE_MAX
+} FMOD_PORT_TYPE;
+
+ +
enum PORT_TYPE : int
+{
+    MUSIC,
+    COPYRIGHT_MUSIC,
+    VOICE,
+    CONTROLLER,
+    PERSONAL,
+    VIBRATION,
+    AUX,
+    PASSTHROUGH,
+    VR_VIBRATION,
+    MAX
+}
+
+ +
PORT_TYPE_MUSIC
+PORT_TYPE_COPYRIGHT_MUSIC
+PORT_TYPE_VOICE
+PORT_TYPE_CONTROLLER
+PORT_TYPE_PERSONAL
+PORT_TYPE_VIBRATION
+PORT_TYPE_AUX
+PORT_TYPE_PASSTHROUGH
+PORT_TYPE_VR_VIBRATION
+PORT_TYPE_MAX
+
+ +
+
FMOD_PORT_TYPE_MUSIC
+
Background music, pass FMOD_PORT_INDEX_NONE as port index.
+ +
Copyright background music, pass FMOD_PORT_INDEX_NONE as port index.
+
FMOD_PORT_TYPE_VOICE
+
Voice chat, pass platform specific user ID of desired user as port index.
+
FMOD_PORT_TYPE_CONTROLLER
+
Controller speaker, pass platform specific user ID of desired user as port index.
+
FMOD_PORT_TYPE_PERSONAL
+
Personal audio device, pass platform specific user ID of desired user as port index.
+
FMOD_PORT_TYPE_VIBRATION
+
Controller vibration, pass platform specific user ID of desired user as port index.
+
FMOD_PORT_TYPE_AUX
+
Auxiliary output port, pass FMOD_PORT_INDEX_NONE as port index.
+
FMOD_PORT_TYPE_PASSTHROUGH
+
Passthrough output port, pass FMOD_PORT_INDEX_NONE as port index.
+
FMOD_PORT_TYPE_VR_VIBRATION
+
VR Controller vibration, pass platform specific user ID of desired user as port index.
+
FMOD_PORT_TYPE_MAX
+
Maximum number of port types supported.
+
+

Not all platforms support all port types. See platform specific guides for a list of supported port types on each platform.

+

See Also: System::attachChannelGroupToPort

+

FMOD_REVERB_MAXINSTANCES

+

The maximum number of global reverb instances.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
#define FMOD_REVERB_MAXINSTANCES 4
+
+ +
class CONSTANTS
+{
+  const int REVERB_MAXINSTANCES = 4;
+}
+
+ +
REVERB_MAXINSTANCES = 4
+
+ +
+
FMOD_REVERB_MAXINSTANCES
+
Maximum instances available.
+
+

Each instance of a reverb is an instance of an FMOD_DSP_SFXREVERB DSP in the DSP graph. This is unrelated to the number of possible Reverb3D objects, which is unlimited.

+

See Also: ChannelControl::setReverbProperties, ChannelControl::setReverbProperties, System::setReverbProperties, System::getReverbProperties

+

FMOD_REVERB_PRESETS

+

Predefined reverb configurations. To simplify usage, and avoid manually selecting reverb parameters, a table of common presets is supplied for ease of use.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
#define FMOD_PRESET_OFF                {  1000,    7,  11, 5000, 100, 100, 100, 250, 0,    20,  96, -80.0f }
+#define FMOD_PRESET_GENERIC            {  1500,    7,  11, 5000,  83, 100, 100, 250, 0, 14500,  96,  -8.0f }
+#define FMOD_PRESET_PADDEDCELL         {   170,    1,   2, 5000,  10, 100, 100, 250, 0,   160,  84,  -7.8f }
+#define FMOD_PRESET_ROOM               {   400,    2,   3, 5000,  83, 100, 100, 250, 0,  6050,  88,  -9.4f }
+#define FMOD_PRESET_BATHROOM           {  1500,    7,  11, 5000,  54, 100,  60, 250, 0,  2900,  83,   0.5f }
+#define FMOD_PRESET_LIVINGROOM         {   500,    3,   4, 5000,  10, 100, 100, 250, 0,   160,  58, -19.0f }
+#define FMOD_PRESET_STONEROOM          {  2300,   12,  17, 5000,  64, 100, 100, 250, 0,  7800,  71,  -8.5f }
+#define FMOD_PRESET_AUDITORIUM         {  4300,   20,  30, 5000,  59, 100, 100, 250, 0,  5850,  64, -11.7f }
+#define FMOD_PRESET_CONCERTHALL        {  3900,   20,  29, 5000,  70, 100, 100, 250, 0,  5650,  80,  -9.8f }
+#define FMOD_PRESET_CAVE               {  2900,   15,  22, 5000, 100, 100, 100, 250, 0, 20000,  59, -11.3f }
+#define FMOD_PRESET_ARENA              {  7200,   20,  30, 5000,  33, 100, 100, 250, 0,  4500,  80,  -9.6f }
+#define FMOD_PRESET_HANGAR             { 10000,   20,  30, 5000,  23, 100, 100, 250, 0,  3400,  72,  -7.4f }
+#define FMOD_PRESET_CARPETTEDHALLWAY   {   300,    2,  30, 5000,  10, 100, 100, 250, 0,   500,  56, -24.0f }
+#define FMOD_PRESET_HALLWAY            {  1500,    7,  11, 5000,  59, 100, 100, 250, 0,  7800,  87,  -5.5f }
+#define FMOD_PRESET_STONECORRIDOR      {   270,   13,  20, 5000,  79, 100, 100, 250, 0,  9000,  86,  -6.0f }
+#define FMOD_PRESET_ALLEY              {  1500,    7,  11, 5000,  86, 100, 100, 250, 0,  8300,  80,  -9.8f }
+#define FMOD_PRESET_FOREST             {  1500,  162,  88, 5000,  54,  79, 100, 250, 0,   760,  94, -12.3f }
+#define FMOD_PRESET_CITY               {  1500,    7,  11, 5000,  67,  50, 100, 250, 0,  4050,  66, -26.0f }
+#define FMOD_PRESET_MOUNTAINS          {  1500,  300, 100, 5000,  21,  27, 100, 250, 0,  1220,  82, -24.0f }
+#define FMOD_PRESET_QUARRY             {  1500,   61,  25, 5000,  83, 100, 100, 250, 0,  3400, 100,  -5.0f }
+#define FMOD_PRESET_PLAIN              {  1500,  179, 100, 5000,  50,  21, 100, 250, 0,  1670,  65, -28.0f }
+#define FMOD_PRESET_PARKINGLOT         {  1700,    8,  12, 5000, 100, 100, 100, 250, 0, 20000,  56, -19.5f }
+#define FMOD_PRESET_SEWERPIPE          {  2800,   14,  21, 5000,  14,  80,  60, 250, 0,  3400,  66,   1.2f }
+#define FMOD_PRESET_UNDERWATER         {  1500,    7,  11, 5000,  10, 100, 100, 250, 0,   500,  92,   7.0f }
+
+ +
class PRESET
+{
+  REVERB_PROPERTIES OFF
+  REVERB_PROPERTIES GENERIC
+  REVERB_PROPERTIES PADDEDCELL
+  REVERB_PROPERTIES ROOM
+  REVERB_PROPERTIES BATHROOM
+  REVERB_PROPERTIES LIVINGROOM
+  REVERB_PROPERTIES STONEROOM
+  REVERB_PROPERTIES AUDITORIUM
+  REVERB_PROPERTIES CONCERTHALL
+  REVERB_PROPERTIES CAVE
+  REVERB_PROPERTIES ARENA
+  REVERB_PROPERTIES HANGAR
+  REVERB_PROPERTIES CARPETTEDHALLWAY
+  REVERB_PROPERTIES HALLWAY
+  REVERB_PROPERTIES STONECORRIDOR
+  REVERB_PROPERTIES ALLEY
+  REVERB_PROPERTIES FOREST
+  REVERB_PROPERTIES CITY
+  REVERB_PROPERTIES MOUNTAINS
+  REVERB_PROPERTIES QUARRY
+  REVERB_PROPERTIES PLAIN
+  REVERB_PROPERTIES PARKINGLOT
+  REVERB_PROPERTIES SEWERPIPE
+  REVERB_PROPERTIES UNDERWATER
+}
+
+ +
+

Not supported for JavaScript.

+
+
+
FMOD_PRESET_OFF
+
Off / disabled
+
FMOD_PRESET_GENERIC
+
Generic / default
+
FMOD_PRESET_PADDEDCELL
+
Padded cell
+
FMOD_PRESET_ROOM
+
Room
+
FMOD_PRESET_BATHROOM
+
Bathroom
+
FMOD_PRESET_LIVINGROOM
+
Living room
+
FMOD_PRESET_STONEROOM
+
Stone room
+
FMOD_PRESET_AUDITORIUM
+
Auditorium
+
FMOD_PRESET_CONCERTHALL
+
Convert hall
+
FMOD_PRESET_CAVE
+
Cave
+
FMOD_PRESET_ARENA
+
Arena
+
FMOD_PRESET_HANGAR
+
Hangar
+
FMOD_PRESET_CARPETTEDHALLWAY
+
Carpeted hallway
+
FMOD_PRESET_HALLWAY
+
Hallway
+
FMOD_PRESET_STONECORRIDOR
+
Stone corridor
+
FMOD_PRESET_ALLEY
+
Alley
+
FMOD_PRESET_FOREST
+
Forest
+
FMOD_PRESET_CITY
+
City
+
FMOD_PRESET_MOUNTAINS
+
Mountains
+
FMOD_PRESET_QUARRY
+
Quarry
+
FMOD_PRESET_PLAIN
+
Plain
+
FMOD_PRESET_PARKINGLOT
+
Parking lot
+
FMOD_PRESET_SEWERPIPE
+
Sewer pipe
+
FMOD_PRESET_UNDERWATER
+
Underwater
+
+

Sets of predefined reverb properties used to initialize an FMOD_REVERB_PROPERTIES structure statically.
+For example:

+
FMOD_REVERB_PROPERTIES prop = FMOD_PRESET_GENERIC;
+
+

See Also: System::setReverbProperties, System::getReverbProperties

+

FMOD_REVERB_PROPERTIES

+

Structure defining a reverb environment.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
typedef struct FMOD_REVERB_PROPERTIES {
+  float   DecayTime;
+  float   EarlyDelay;
+  float   LateDelay;
+  float   HFReference;
+  float   HFDecayRatio;
+  float   Diffusion;
+  float   Density;
+  float   LowShelfFrequency;
+  float   LowShelfGain;
+  float   HighCut;
+  float   EarlyLateMix;
+  float   WetLevel;
+} FMOD_REVERB_PROPERTIES;
+
+ +
struct REVERB_PROPERTIES
+{
+    float DecayTime;
+    float EarlyDelay;
+    float LateDelay;
+    float HFReference;
+    float HFDecayRatio;
+    float Diffusion;
+    float Density;
+    float LowShelfFrequency;
+    float LowShelfGain;
+    float HighCut;
+    float EarlyLateMix;
+    float WetLevel;
+}
+
+ +
REVERB_PROPERTIES
+{
+  DecayTime,
+  EarlyDelay,
+  LateDelay,
+  HFReference,
+  HFDecayRatio,
+  Diffusion,
+  Density,
+  LowShelfFrequency,
+  LowShelfGain,
+  HighCut,
+  EarlyLateMix,
+  WetLevel,
+};
+
+ +
+
DecayTime
+
+

Reverberation decay time.

+
    +
  • Units: Milliseconds
  • +
  • Default: 1500
  • +
  • Range: [0, 20000]
  • +
+
+
EarlyDelay
+
+

Initial reflection delay time.

+
    +
  • Units: Milliseconds
  • +
  • Default: 7
  • +
  • Range: [0, 300]
  • +
+
+
LateDelay
+
+

Late reverberation delay time relative to initial reflection.

+
    +
  • Units: Milliseconds
  • +
  • Default: 11
  • +
  • Range: [0, 100]
  • +
+
+
HFReference
+
+

Reference high frequency.

+
    +
  • Units: Hertz
  • +
  • Default: 5000
  • +
  • Range: [20, 20000]
  • +
+
+
HFDecayRatio
+
+

High-frequency to mid-frequency decay time ratio.

+
    +
  • Units: Percent
  • +
  • Default: 50
  • +
  • Range: [10, 100]
  • +
+
+
Diffusion
+
+

Value that controls the echo density in the late reverberation decay.

+
    +
  • Units: Percent
  • +
  • Default: 50
  • +
  • Range: [10, 100]
  • +
+
+
Density
+
+

Value that controls the modal density in the late reverberation decay.

+
    +
  • Units: Percent
  • +
  • Default: 100
  • +
  • Range: [0, 100]
  • +
+
+
LowShelfFrequency
+
+

Reference low frequency

+
    +
  • Units: Hertz
  • +
  • Default: 250
  • +
  • Range: [20, 1000]
  • +
+
+
LowShelfGain
+
+

Relative room effect level at low frequencies.

+
    +
  • Units: Decibels
  • +
  • Default: 0
  • +
  • Range: [-36, 12]
  • +
+
+
HighCut
+
+

Relative room effect level at high frequencies.

+
    +
  • Units: Hertz
  • +
  • Default: 200000
  • +
  • Range: [0, 20000]
  • +
+
+
EarlyLateMix
+
+

Early reflections level relative to room effect.

+
    +
  • Units: Percent
  • +
  • Default: 50
  • +
  • Range: [0, 100]
  • +
+
+
WetLevel
+
+

Room effect level at mid frequencies.

+
    +
  • Units: Decibels
  • +
  • Default: -6
  • +
  • Range: [-80, 20]
  • +
+
+
+

Note the default reverb properties are the same as the FMOD_PRESET_GENERIC preset.

+

See Also: System::setReverbProperties, System::getReverbProperties, FMOD_REVERB_PRESETS

+

System::attachChannelGroupToPort

+

Connect the output of the specified ChannelGroup to an audio port on the output driver.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
FMOD_RESULT System::attachChannelGroupToPort(
+  FMOD_PORT_TYPE portType,
+  FMOD_PORT_INDEX portIndex,
+  ChannelGroup *channelgroup,
+  bool passThru = false
+);
+
+ +
FMOD_RESULT FMOD_System_AttachChannelGroupToPort(
+  FMOD_SYSTEM *system,
+  FMOD_PORT_TYPE portType,
+  FMOD_PORT_INDEX portIndex,
+  FMOD_CHANNELGROUP *channelgroup,
+  FMOD_BOOL passThru
+);
+
+ +
RESULT System.attachChannelGroupToPort(
+  uint portType,
+  ulong portIndex,
+  ChannelGroup channelgroup,
+  bool passThru = false
+);
+
+ +
System.attachChannelGroupToPort(
+  portType,
+  portIndex,
+  channelgroup,
+  passThru
+);
+
+ +
+
portType
+
Port type (output mode specific). (FMOD_PORT_TYPE)
+
portIndex
+
Index to specify which instance of the specified portType to use (output mode specific) (FMOD_PORT_INDEX)
+
channelgroup
+
Group to attach the port to. (ChannelGroup)
+
passThru
+
+

Whether the signal should additionally route to the existing ChannelGroup output.

+
    +
  • Units: Boolean
  • +
+
+
+

Ports are additional outputs supported by some FMOD_OUTPUTTYPE plug-ins and can include things like controller headsets or dedicated background music streams. See the Port Support section (where applicable) of each platform's getting started guide found in the platform details chapter.

+

See Also: System::detachChannelGroupFromPort

+

System::attachFileSystem

+

'Piggyback' on FMOD file reading routines to capture data as it's read.

+

This allows users to capture data as FMOD reads it, which may be useful for extracting the raw data that FMOD reads for hard to support sources (for example internet streams).

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
FMOD_RESULT System::attachFileSystem(
+  FMOD_FILE_OPEN_CALLBACK useropen,
+  FMOD_FILE_CLOSE_CALLBACK userclose,
+  FMOD_FILE_READ_CALLBACK userread,
+  FMOD_FILE_SEEK_CALLBACK userseek
+);
+
+ +
FMOD_RESULT FMOD_System_AttachFileSystem(
+  FMOD_SYSTEM *system,
+  FMOD_FILE_OPEN_CALLBACK useropen,
+  FMOD_FILE_CLOSE_CALLBACK userclose,
+  FMOD_FILE_READ_CALLBACK userread,
+  FMOD_FILE_SEEK_CALLBACK userseek
+);
+
+ +
RESULT System.attachFileSystem(
+  FILE_OPENCALLBACK useropen,
+  FILE_CLOSECALLBACK userclose,
+  FILE_READCALLBACK userread,
+  FILE_SEEKCALLBACK userseek
+);
+
+ +
System.attachFileSystem(
+  useropen,
+  userclose,
+  userread,
+  userseek
+);
+
+ +
+
useropen Opt
+
Callback for after a file is opened. (FMOD_FILE_OPEN_CALLBACK)
+
userclose Opt
+
Callback for after a file is closed. (FMOD_FILE_CLOSE_CALLBACK)
+
userread Opt
+
Callback for after a read operation. (FMOD_FILE_READ_CALLBACK)
+
userseek Opt
+
Callback for after a seek operation. (FMOD_FILE_SEEK_CALLBACK)
+
+

To detach, pass null or equivalent as the callback parameters.

+

Note: This function is not to replace FMOD's file system. For this functionality, see System::setFileSystem.

+

See Also: Callback Behavior

+

FMOD_SYSTEM_CALLBACK

+

Callback for System notifications.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
FMOD_RESULT F_CALL FMOD_SYSTEM_CALLBACK(
+  FMOD_SYSTEM *system,
+  FMOD_SYSTEM_CALLBACK_TYPE type,
+  void *commanddata1,
+  void *commanddata2,
+  void *userdata
+);
+
+ +
delegate RESULT SYSTEM_CALLBACK(
+  IntPtr system,
+  SYSTEM_CALLBACK_TYPE type,
+  IntPtr commanddata1,
+  IntPtr commanddata2,
+  IntPtr userdata
+);
+
+ +
function FMOD_SYSTEM_CALLBACK(
+  system,
+  type,
+  commanddata1,
+  commanddata2,
+  userdata
+)
+
+ +
+
system Opt
+
System handle. (System)
+
type
+
Type of callback. (FMOD_SYSTEM_CALLBACK_TYPE)
+
commanddata1 Opt
+
First callback parameter, see FMOD_SYSTEM_CALLBACK_TYPE for details.
+
commanddata2 Opt
+
Second callback parameter, see FMOD_SYSTEM_CALLBACK_TYPE for details.
+
userdata Opt
+
User data associated with system or the last value set with any call to System::setUserData for global callbacks.
+
+
+

The 'system' argument can be cast to FMOD::System *.

+
+
+

The 'system' argument can be used via System by using FMOD.System coreSystem = new FMOD.System(system);

+
+

See Also: Callback Behavior, User Data, System::setCallback

+

FMOD_SYSTEM_CALLBACK_TYPE

+

Types of callbacks called by the System.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
#define FMOD_SYSTEM_CALLBACK_DEVICELISTCHANGED        0x00000001
+#define FMOD_SYSTEM_CALLBACK_DEVICELOST               0x00000002
+#define FMOD_SYSTEM_CALLBACK_MEMORYALLOCATIONFAILED   0x00000004
+#define FMOD_SYSTEM_CALLBACK_THREADCREATED            0x00000008
+#define FMOD_SYSTEM_CALLBACK_BADDSPCONNECTION         0x00000010
+#define FMOD_SYSTEM_CALLBACK_PREMIX                   0x00000020
+#define FMOD_SYSTEM_CALLBACK_POSTMIX                  0x00000040
+#define FMOD_SYSTEM_CALLBACK_ERROR                    0x00000080
+#define FMOD_SYSTEM_CALLBACK_THREADDESTROYED          0x00000100
+#define FMOD_SYSTEM_CALLBACK_PREUPDATE                0x00000200
+#define FMOD_SYSTEM_CALLBACK_POSTUPDATE               0x00000400
+#define FMOD_SYSTEM_CALLBACK_RECORDLISTCHANGED        0x00000800
+#define FMOD_SYSTEM_CALLBACK_BUFFEREDNOMIX            0x00001000
+#define FMOD_SYSTEM_CALLBACK_DEVICEREINITIALIZE       0x00002000
+#define FMOD_SYSTEM_CALLBACK_OUTPUTUNDERRUN           0x00004000
+#define FMOD_SYSTEM_CALLBACK_RECORDPOSITIONCHANGED    0x00008000
+#define FMOD_SYSTEM_CALLBACK_ALL                      0xFFFFFFFF
+
+ +
[Flags]
+enum SYSTEM_CALLBACK_TYPE : uint
+{
+  DEVICELISTCHANGED      = 0x00000001,
+  DEVICELOST             = 0x00000002,
+  MEMORYALLOCATIONFAILED = 0x00000004,
+  THREADCREATED          = 0x00000008,
+  BADDSPCONNECTION       = 0x00000010,
+  PREMIX                 = 0x00000020,
+  POSTMIX                = 0x00000040,
+  ERROR                  = 0x00000080,
+  THREADDESTROYED        = 0x00000100,
+  PREUPDATE              = 0x00000200,
+  POSTUPDATE             = 0x00000400,
+  RECORDLISTCHANGED      = 0x00000800,
+  BUFFEREDNOMIX          = 0x00001000,
+  DEVICEREINITIALIZE     = 0x00002000,
+  OUTPUTUNDERRUN         = 0x00004000,
+  RECORDPOSITIONCHANGED  = 0x00008000,
+  ALL                    = 0xFFFFFFFF,
+}
+
+ +
SYSTEM_CALLBACK_DEVICELISTCHANGED      = 0x00000001
+SYSTEM_CALLBACK_DEVICELOST             = 0x00000002
+SYSTEM_CALLBACK_MEMORYALLOCATIONFAILED = 0x00000004
+SYSTEM_CALLBACK_THREADCREATED          = 0x00000008
+SYSTEM_CALLBACK_BADDSPCONNECTION       = 0x00000010
+SYSTEM_CALLBACK_PREMIX                 = 0x00000020
+SYSTEM_CALLBACK_POSTMIX                = 0x00000040
+SYSTEM_CALLBACK_ERROR                  = 0x00000080
+SYSTEM_CALLBACK_THREADDESTROYED        = 0x00000100
+SYSTEM_CALLBACK_PREUPDATE              = 0x00000200
+SYSTEM_CALLBACK_POSTUPDATE             = 0x00000400
+SYSTEM_CALLBACK_RECORDLISTCHANGED      = 0x00000800
+SYSTEM_CALLBACK_BUFFEREDNOMIX          = 0x00001000
+SYSTEM_CALLBACK_DEVICEREINITIALIZE     = 0x00002000
+SYSTEM_CALLBACK_OUTPUTUNDERRUN         = 0x00004000
+SYSTEM_CALLBACK_RECORDPOSITIONCHANGED  = 0x00008000
+SYSTEM_CALLBACK_ALL                    = 0xFFFFFFFF
+
+ +
+
FMOD_SYSTEM_CALLBACK_DEVICELISTCHANGED
+
Called from System::update when the enumerated list of devices has changed. Called from the main (calling) thread when set from the Core API or Studio API in synchronous mode, and from the Studio Update Thread when in default / async mode.
+
FMOD_SYSTEM_CALLBACK_DEVICELOST
+
Deprecated.
+
FMOD_SYSTEM_CALLBACK_MEMORYALLOCATIONFAILED
+
Called directly when a memory allocation fails.
+
FMOD_SYSTEM_CALLBACK_THREADCREATED
+
Called from the game thread when a thread is created.
+
FMOD_SYSTEM_CALLBACK_BADDSPCONNECTION
+
Deprecated.
+
FMOD_SYSTEM_CALLBACK_PREMIX
+
Called from the mixer thread before it starts the next block.
+
FMOD_SYSTEM_CALLBACK_POSTMIX
+
Called from the mixer thread after it finishes a block.
+
FMOD_SYSTEM_CALLBACK_ERROR
+
Called directly when an API function returns an error, including delayed async functions.
+
FMOD_SYSTEM_CALLBACK_THREADDESTROYED
+
Called from the game thread when a thread is destroyed.
+
FMOD_SYSTEM_CALLBACK_PREUPDATE
+
Called at start of System::update from the main (calling) thread when set from the Core API or Studio API in synchronous mode, and from the Studio Update Thread when in default / async mode.
+
FMOD_SYSTEM_CALLBACK_POSTUPDATE
+
Called at end of System::update from the main (calling) thread when set from the Core API or Studio API in synchronous mode, and from the Studio Update Thread when in default / async mode.
+
FMOD_SYSTEM_CALLBACK_RECORDLISTCHANGED
+
Called from System::update when the enumerated list of recording devices has changed. Called from the main (calling) thread when set from the Core API or Studio API in synchronous mode, and from the Studio Update Thread when in default / async mode.
+
FMOD_SYSTEM_CALLBACK_BUFFEREDNOMIX
+
Called from the feeder thread after audio was consumed from the ring buffer, but not enough to allow another mix to run.
+
FMOD_SYSTEM_CALLBACK_DEVICEREINITIALIZE
+
Called from System::update when an output device is re-initialized. Called from the main (calling) thread when set from the Core API or Studio API in synchronous mode, and from the Studio Update Thread when in default / async mode.
+
FMOD_SYSTEM_CALLBACK_OUTPUTUNDERRUN
+
Called from the mixer thread when the device output attempts to read more samples than are available in the output buffer.
+
FMOD_SYSTEM_CALLBACK_RECORDPOSITIONCHANGED
+
Called from the mixer thread when the System record position changed.
+
FMOD_SYSTEM_CALLBACK_ALL
+
Mask representing all callback types.
+
+

For each callback type unless specified below it is assumed commanddata1 and commanddata2 are unused and userdata matches the value set with System::setUserData.

+

FMOD_SYSTEM_CALLBACK_MEMORYALLOCATIONFAILED
+commanddata1: (const char *) representing the file and line of the failure.
+commanddata2: (int) representing the size of the requested allocation

+

FMOD_SYSTEM_CALLBACK_ERROR
+commanddata1: (FMOD_ERRORCALLBACK_INFO *) with extra information about the error.
+commanddata2: Unused.

+

FMOD_SYSTEM_CALLBACK_THREADCREATED / FMOD_SYSTEM_CALLBACK_THREADDESTROYED
+commanddata1: Handle of the thread, see notes below for thread handle types.
+commanddata2: (const char *) representing the name of the thread.

+

FMOD_SYSTEM_CALLBACK_DEVICEREINITIALIZE
+commanddata1: (FMOD_OUTPUTTYPE) of the output device.
+commanddata2: (int) selected driver index.

+

FMOD_SYSTEM_CALLBACK_RECORDPOSITIONCHANGED
+commanddata1: (Sound) that is being recorded to.
+commanddata2: (int) The new record position.

+

Thread handle types per platform:

+
    +
  • Mac, Linux, iOS, Android: pthread_t
  • +
  • PS4, PS5: ScePthread
  • +
  • Win, GameCore: HANDLE
  • +
+

Using FMOD_SYSTEM_CALLBACK_ALL or FMOD_SYSTEM_CALLBACK_DEVICELISTCHANGED will disable any automated device ejection/insertion handling. Use this callback to control the behavior yourself.
+Using FMOD_SYSTEM_CALLBACK_DEVICELISTCHANGED (Mac only) requires the application to be running an event loop which will allow external changes to device list to be detected.

+

See Also: Callback Behavior, System::setCallback, FMOD_SYSTEM_CALLBACK

+

System::close

+

Close the connection to the output and return to an uninitialized state without releasing the object.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
FMOD_RESULT System::close();
+
+ +
FMOD_RESULT FMOD_System_Close(FMOD_SYSTEM *system);
+
+ +
RESULT System.close();
+
+ +
System.close();
+
+ +

Closing renders objects created with this System invalid. Make sure any Sound, ChannelGroup, Geometry and DSP objects are released before calling this.

+

All pre-initialize configuration settings will remain and the System can be reinitialized as needed.

+

See Also: System::init, System::release

+

System_Create

+

Creates an instance of the FMOD system.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
FMOD_RESULT System_Create(
+  System **system,
+  unsigned int headerversion = FMOD_VERSION
+);
+
+ +
FMOD_RESULT FMOD_System_Create(
+  FMOD_SYSTEM **system,
+  unsigned int headerversion
+);
+
+ +
static RESULT Factory.System_Create(
+  out System system
+);
+
+ +
System_Create(
+  system
+);
+
+ +
+
system Out
+
Newly created object. (System)
+
headerversion
+
Expected FMOD Engine version.
+
+

Pass FMOD_VERSION in headerversion to ensure the library and header versions being used match.

+

This must be called first to create an FMOD System object before any other API calls (except for Memory_Initialize and Debug_Initialize). Use this function to create 1 or multiple instances of FMOD System objects.

+

Use System::release to free a system object.

+
+

Calls to System_Create and System::release are not thread-safe. Do not call these functions simultaneously from multiple threads at once.

+
+

See Also: System::init

+

System::createChannelGroup

+

Create a ChannelGroup object.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
FMOD_RESULT System::createChannelGroup(
+  const char *name,
+  ChannelGroup **channelgroup
+);
+
+ +
FMOD_RESULT FMOD_System_CreateChannelGroup(
+  FMOD_SYSTEM *system,
+  const char *name,
+  FMOD_CHANNELGROUP **channelgroup
+);
+
+ +
RESULT System.createChannelGroup(
+  string name,
+  out ChannelGroup channelgroup
+);
+
+ +
System.createChannelGroup(
+  name,
+  channelgroup
+);
+
+ +
+
name Opt
+
Label for identification purposes. (UTF-8 string)
+
channelgroup Out
+
Newly created group. (ChannelGroup)
+
+

ChannelGroups can be used to assign / group Channels, for things such as volume scaling. ChannelGroups are also used for sub-mixing. Any Channels that are assigned to a ChannelGroup get submixed into that ChannelGroup's 'tail' DSP. See FMOD_CHANNELCONTROL_DSP_TAIL.

+

If a ChannelGroup has an effect added to it, the effect is processed post-mix from the Channels and ChannelGroups below it in the mix hierarchy. For more information, see the DSP Architecture and Usage section of the Using DSP Effects in the Core API chapter.

+

All ChannelGroups will initially output directly to the master ChannelGroup (See System::getMasterChannelGroup). ChannelGroups can be re-parented this with ChannelGroup::addGroup.

+

See Also: ChannelGroup::release

+

System::createDSP

+

Create a DSP unit given a plug-in description structure.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
FMOD_RESULT System::createDSP(
+  const FMOD_DSP_DESCRIPTION *description,
+  DSP **dsp
+);
+
+ +
FMOD_RESULT FMOD_System_CreateDSP(
+  FMOD_SYSTEM *system,
+  const FMOD_DSP_DESCRIPTION *description,
+  FMOD_DSP **dsp
+);
+
+ +
RESULT System.createDSP(
+  ref DSP_DESCRIPTION description,
+  out DSP dsp
+);
+
+ +
System.createDSP(
+  description,
+  dsp
+);
+
+ +
+
description
+
Structure describing the DSP to create. (FMOD_DSP_DESCRIPTION)
+
dsp Out
+
Newly created unit. (DSP)
+
+

A DSP unit is a module that can be inserted into the DSP graph to allow sound filtering or sound generation. For more information, see the DSP Architecture and Usage section of the Using DSP Effects in the Core API chapter.

+

DSPs must be attached to the DSP graph before they become active, either via ChannelControl::addDSP or DSP::addInput.

+

See Also: System::createDSPByType, System::createDSPByPlugin

+

System::createDSPByPlugin

+

Create a DSP unit with a specified plug-in handle.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
FMOD_RESULT System::createDSPByPlugin(
+  unsigned int handle,
+  DSP **dsp
+);
+
+ +
FMOD_RESULT FMOD_System_CreateDSPByPlugin(
+  FMOD_SYSTEM *system,
+  unsigned int handle,
+  FMOD_DSP **dsp
+);
+
+ +
RESULT System.createDSPByPlugin(
+  uint handle,
+  out DSP dsp
+);
+
+ +
System.createDSPByPlugin(
+  handle,
+  dsp
+);
+
+ +
+
handle
+
Handle to an already loaded DSP plug-in.
+
dsp Out
+
Newly created unit. (DSP)
+
+

A DSP object is a module that can be inserted into the DSP graph to allow sound filtering or sound generation. For more information, see the DSP Architecture and Usage section of the Using DSP Effects in the Core API chapter.

+

A handle can come from a newly loaded plug-in with System::loadPlugin or an existing plug-in with System::getPluginHandle.

+

DSPs must be attached to the DSP graph before they become active, either via ChannelControl::addDSP or DSP::addInput.

+

See Also: System::createDSP, System::createDSPByType

+

System::createDSPByType

+

Create a DSP unit with a specified built-in type index.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
FMOD_RESULT System::createDSPByType(
+  FMOD_DSP_TYPE type,
+  DSP **dsp
+);
+
+ +
FMOD_RESULT FMOD_System_CreateDSPByType(
+  FMOD_SYSTEM *system,
+  FMOD_DSP_TYPE type,
+  FMOD_DSP **dsp
+);
+
+ +
RESULT System.createDSPByType(
+  DSP_TYPE type,
+  out DSP dsp
+);
+
+ +
System.createDSPByType(
+  type,
+  dsp
+);
+
+ +
+
type
+
Type of built in unit. (FMOD_DSP_TYPE)
+
dsp Out
+
Newly created unit. (DSP)
+
+

A DSP unit (or "DSP") is a module that can be inserted into the DSP graph to allow sound filtering or sound generation. For more information, see the DSP Architecture and Usage section of the Using DSP Effects in the Core API chapter.

+

DSPs must be attached to the DSP graph before they become active, either via ChannelControl::addDSP or DSP::addInput.

+

See Also: System::createDSP

+

System::createDSPConnection

+

Create a DSPConnection object.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
FMOD_RESULT System::createDSPConnection(
+  FMOD_DSPCONNECTION_TYPE type,
+  DSPConnection **connection
+);
+
+ +
FMOD_RESULT FMOD_System_CreateDSPConnection(
+  FMOD_SYSTEM *system,
+  FMOD_DSPCONNECTION_TYPE type,
+  FMOD_DSP **connection
+);
+
+ +
RESULT System.createDSPConnection(
+  DSPCONNECTION_TYPE type,
+  out DSPConnection connection
+);
+
+ +
System.createDSPConnection(
+  type,
+  connection
+);
+
+ +
+
type
+
Type of connection. (FMOD_DSPCONNECTION_TYPE)
+
connection Out
+
Newly created connection. (DSPConnection)
+
+

Creating a DSP connection with this function allows you to configure its initial state before using it to connect two DSPs via DSP::addInput.

+

System::createGeometry

+

Geometry creation function. This function will create a base geometry object which can then have polygons added to it.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
FMOD_RESULT System::createGeometry(
+  int maxpolygons,
+  int maxvertices,
+  Geometry **geometry
+);
+
+ +
FMOD_RESULT FMOD_System_CreateGeometry(
+  FMOD_SYSTEM *system,
+  int maxpolygons,
+  int maxvertices,
+  FMOD_GEOMETRY **geometry
+);
+
+ +
RESULT System.createGeometry(
+  int maxpolygons,
+  int maxvertices,
+  out Geometry geometry
+);
+
+ +
System.createGeometry(
+  maxpolygons,
+  maxvertices,
+  geometry
+);
+
+ +
+
maxpolygons
+
Maximum number of polygons within this object.
+
maxvertices
+
Maximum number of vertices within this object.
+
geometry Out
+
Newly created geometry object. (Geometry)
+
+

Polygons can be added to a geometry object using Geometry::addPolygon. For best efficiency, avoid overlapping of polygons and long thin polygons.

+

A geometry object stores its polygons in a group to allow optimization for line testing, insertion and updating of geometry in real-time.
+Geometry objects also allow for efficient rotation, scaling and translation of groups of polygons.

+

It is important to set the value of maxworldsize to an appropriate value using System::setGeometrySettings.

+

See Also: System::setGeometrySettings, System::loadGeometry, Geometry::addPolygon, Geometry::setPosition, Geometry::setRotation, Geometry::setScale

+

System::createReverb3D

+

Creates a 'virtual reverb' object. This object reacts to 3D location and morphs the reverb environment based on how close it is to the reverb object's center.

+

Multiple reverb objects can be created to achieve a multi-reverb environment. 1 reverb object is used for all 3D reverb objects (slot 0 by default).

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
FMOD_RESULT System::createReverb3D(
+  Reverb3D **reverb
+);
+
+ +
FMOD_RESULT FMOD_System_CreateReverb3D(
+  FMOD_SYSTEM *system,
+  FMOD_REVERB3D **reverb
+);
+
+ +
RESULT System.createReverb3D(
+  out Reverb3D reverb
+);
+
+ +
System.createReverb3D(
+  reverb
+);
+
+ +
+
reverb Out
+
Newly created virtual reverb object. (Reverb3D)
+
+

The 3D reverb object is a sphere having 3D attributes (position, minimum distance, maximum distance) and reverb properties.

+

The properties and 3D attributes of all reverb objects collectively determine, along with the listener's position, the settings of and input gains into a single 3D reverb DSP.

+

When the listener is within the sphere of effect of one or more 3D reverbs, the listener's 3D reverb properties are a weighted combination of such 3D reverbs.

+

When the listener is outside all of the reverbs, no reverb is applied.

+

System::setReverbProperties can be used to create an alternative reverb that can be used for 2D and background global reverb.

+

To avoid this reverb interfering with the reverb slot used by the 3D reverb, 2D reverb should use a different slot id with System::setReverbProperties, otherwise FMOD_ADVANCEDSETTINGS::reverb3Dinstance can also be used to place 3D reverb on a different reverb slot.

+

Use ChannelControl::setReverbProperties to turn off reverb for 2D sounds (ie set wet = 0).

+

Creating multiple reverb objects does not impact performance. This is because these reverb objects are 'virtual reverbs': There is only one reverb DSP unit running at a time, and its parameter values are morphed to those of each virtual reverb as needed.

+

To remove the reverb DSP unit and the associated CPU cost, first make sure all 3D reverb objects are released. Then, call System::setReverbProperties with the 3D reverb's slot ID (0 by default) with a property point of 0 or NULL, to signal that the reverb instance should be deleted.

+

If a 3D reverb is still present, and System::setReverbProperties function is called to free the reverb, the 3D reverb system recreates it upon the next System::update call.

+

The 3D reverb system does not affect Studio events unless it is explicitly enabled by calling Studio::EventInstance::setReverbLevel on each event instance.

+

See Also: Reverb3D::release

+

System::createSound

+

Loads a sound into memory, opens it for streaming or sets it up for callback based sounds.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
FMOD_RESULT System::createSound(
+  const char *name_or_data,
+  FMOD_MODE mode,
+  FMOD_CREATESOUNDEXINFO *exinfo,
+  Sound **sound
+);
+
+ +
FMOD_RESULT FMOD_System_CreateSound(
+  FMOD_SYSTEM *system,
+  const char *name_or_data,
+  FMOD_MODE mode,
+  FMOD_CREATESOUNDEXINFO *exinfo,
+  FMOD_SOUND **sound
+);
+
+ +
RESULT System.createSound(
+  string name,
+  MODE mode,
+  out Sound sound
+);
+RESULT System.createSound(
+  byte[] data,
+  MODE mode,
+  out Sound sound
+);
+RESULT System.createSound(
+  string name,
+  MODE mode,
+  ref CREATESOUNDEXINFO exinfo,
+  out Sound sound
+);
+RESULT System.createSound(
+  IntPtr name_or_data,
+  MODE mode,
+  ref CREATESOUNDEXINFO exinfo,
+  out Sound sound
+);
+
+ +
System.createSound(
+  name_or_data,
+  mode,
+  exinfo,
+  sound
+);
+
+ +
+
name_or_data
+
Name of the file or URL to open (UTF-8 string) or a pointer to a preloaded sound memory block if FMOD_OPENMEMORY / FMOD_OPENMEMORY_POINT is used.
+
mode
+
+

Behavior modifier for opening the sound. (FMOD_MODE)

+ +
+
exinfo Opt
+
Extended information for creating the sound. (FMOD_CREATESOUNDEXINFO)
+
sound Out
+
Newly created Sound object. (Sound)
+
+

FMOD_CREATESAMPLE will try to load and decompress the whole sound into memory, use FMOD_CREATESTREAM to open it as a stream and have it play back in realtime from disk or another medium. FMOD_CREATECOMPRESSEDSAMPLE can also be used for certain formats to play the sound directly in its compressed format from the mixer.

+
    +
  • To open a file or URL as a stream, so that it decompresses / reads at runtime, instead of loading / decompressing into memory all at the time of this call, use the FMOD_CREATESTREAM flag.
  • +
  • To open a file or URL as a compressed sound effect that is not streamed and is not decompressed into memory at load time, use FMOD_CREATECOMPRESSEDSAMPLE. This is supported with MPEG (mp2/mp3), ADPCM/FADPCM, XMA, AT9 and FSB Vorbis files only. This is useful for those who want realtime compressed soundeffects, but not the overhead of disk access.
  • +
  • To open a sound as 2D, so that it is not affected by 3D processing, use the FMOD_2D flag. 3D sound commands will be ignored on these types of sounds.
  • +
  • To open a sound as 3D, so that it is treated as a 3D sound, use the FMOD_3D flag.
  • +
+

Note that FMOD_OPENRAW, FMOD_OPENMEMORY, FMOD_OPENMEMORY_POINT and FMOD_OPENUSER will not work here without the exinfo structure present, as more information is needed.

+

Use FMOD_NONBLOCKING to have the sound open or load in the background. You can use Sound::getOpenState to determine if it has finished loading / opening or not. While it is loading (not ready), sound functions are not accessible for that sound. Do not free memory provided with FMOD_OPENMEMORY if the sound is not in a ready state, as it will most likely lead to a crash.

+

To account for slow media that might cause buffer underrun (skipping / stuttering / repeating blocks of audio) with sounds created with FMOD_CREATESTREAM, use System::setStreamBufferSize to increase read ahead.

+

As using FMOD_OPENUSER causes FMOD to ignore whatever is passed as the first argument name_or_data, recommended practice is to pass null or equivalent.

+

Specifying FMOD_OPENMEMORY_POINT will POINT to your memory rather allocating its own sound buffers and duplicating it internally, this means you cannot free the memory while FMOD is using it, until after Sound::release is called.

+

With FMOD_OPENMEMORY_POINT, only PCM formats and compressed formats using FMOD_CREATECOMPRESSEDSAMPLE are supported.

+
+

Use of FMOD.NON_BLOCKING is currently not supported for JavaScript.

+
+

System::createSoundGroup

+

Creates a SoundGroup object.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
FMOD_RESULT System::createSoundGroup(
+  const char *name,
+  SoundGroup **soundgroup
+);
+
+ +
FMOD_RESULT FMOD_System_CreateSoundGroup(
+  FMOD_SYSTEM *system,
+  const char *name,
+  FMOD_SOUNDGROUP **soundgroup
+);
+
+ +
RESULT System.createSoundGroup(
+  string name,
+  out SoundGroup soundgroup
+);
+
+ +
System.createSoundGroup(
+  name,
+  soundgroup
+);
+
+ +
+
name
+
Name of SoundGroup. (UTF-8 string)
+
soundgroup Out
+
Newly created group. (SoundGroup)
+
+

A SoundGroup is a way to address multiple Sounds at once with group level commands, such as:

+ +

Once a SoundGroup is created, Sound::setSoundGroup is used to put a Sound in a SoundGroup.

+

See Also: SoundGroup::release, Sound::setSoundGroup

+

System::createStream

+

Opens a sound for streaming.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
FMOD_RESULT System::createStream(
+  const char *name_or_data,
+  FMOD_MODE mode,
+  FMOD_CREATESOUNDEXINFO *exinfo,
+  Sound **sound
+);
+
+ +
FMOD_RESULT FMOD_System_CreateStream(
+  FMOD_SYSTEM *system,
+  const char *name_or_data,
+  FMOD_MODE mode,
+  FMOD_CREATESOUNDEXINFO *exinfo,
+  FMOD_SOUND **sound
+);
+
+ +
RESULT System.createStream(
+  string name,
+  MODE mode,
+  out Sound sound
+);
+RESULT System.createStream(
+  string name,
+  MODE mode,
+  ref CREATESOUNDEXINFO exinfo,
+  out Sound sound
+);
+RESULT System.createStream(
+  byte[] data,
+  MODE mode,
+  ref CREATESOUNDEXINFO exinfo,
+  out Sound sound
+);
+RESULT System.createStream(
+  IntPtr name_or_data,
+  MODE mode,
+  ref CREATESOUNDEXINFO exinfo,
+  out Sound sound
+);
+
+ +
System.createStream(
+  name_or_data,
+  mode,
+  exinfo,
+  sound
+);
+
+ +
+
name_or_data
+
Name of the file or URL to open (UTF-8 string) or a pointer to a preloaded sound memory block if FMOD_OPENMEMORY / FMOD_OPENMEMORY_POINT is used.
+
mode
+
+

Behavior modifier for opening the sound. (FMOD_MODE)

+ +
+
exinfo Opt
+
Extended information while playing the sound. (FMOD_CREATESOUNDEXINFO)
+
sound Out
+
Newly created Sound object. (Sound)
+
+

This is a convenience function for System::createSound with the FMOD_CREATESTREAM flag added.

+

A stream only has one decode buffer and file handle, and therefore can only be played once. It cannot play multiple times at once because it cannot share a stream buffer if the stream is playing at different positions. Open multiple streams to have them play concurrently.

+

System::detachChannelGroupFromPort

+

Disconnect the output of the specified ChannelGroup from an audio port on the output driver.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
FMOD_RESULT System::detachChannelGroupFromPort(
+  ChannelGroup *channelgroup
+);
+
+ +
FMOD_RESULT FMOD_System_DetachChannelGroupFromPort(
+  FMOD_SYSTEM *system,
+  FMOD_CHANNELGROUP *channelgroup
+);
+
+ +
RESULT System.detachChannelGroupFromPort(
+  ChannelGroup channelgroup
+);
+
+ +
System.detachChannelGroupFromPort(
+  channelgroup
+);
+
+ +
+
channelgroup
+
Group to detach the port from. (ChannelGroup)
+
+

Removing a ChannelGroup from a port will reroute the audio back to the main mix.

+

See Also: System::attachChannelGroupToPort

+

System::get3DListenerAttributes

+

Retrieves the position, velocity and orientation of the specified 3D sound listener.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
FMOD_RESULT System::get3DListenerAttributes(
+  int listener,
+  FMOD_VECTOR *pos,
+  FMOD_VECTOR *vel,
+  FMOD_VECTOR *forward,
+  FMOD_VECTOR *up
+);
+
+ +
FMOD_RESULT FMOD_System_Get3DListenerAttributes(
+  FMOD_SYSTEM *system,
+  int listener,
+  FMOD_VECTOR *pos,
+  FMOD_VECTOR *vel,
+  FMOD_VECTOR *forward,
+  FMOD_VECTOR *up
+);
+
+ +
RESULT System.get3DListenerAttributes(
+  int listener,
+  out VECTOR pos,
+  out VECTOR vel,
+  out VECTOR forward,
+  out VECTOR up
+);
+
+ +
System.get3DListenerAttributes(
+  listener,
+  pos,
+  vel,
+  forward,
+  up
+);
+
+ +
+
listener
+
+

Index of listener to get 3D attributes for. Listeners are indexed from 0, to FMOD_MAX_LISTENERS - 1, in a multi-listener environment.

+ +
+
pos OutOpt
+
+

Position in 3D space used for panning and attenuation. (FMOD_VECTOR)

+ +
+
vel OutOpt
+
+

Velocity in 3D space used for doppler. (FMOD_VECTOR)

+ +
+
forward OutOpt
+
Forwards orientation. (FMOD_VECTOR)
+
up OutOpt
+
Upwards orientation. (FMOD_VECTOR)
+
+

Users of the Studio API should call Studio::System::getListenerAttributes instead of this function.

+

See Also: System::set3DListenerAttributes

+

System::get3DNumListeners

+

Retrieves the number of 3D listeners.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
FMOD_RESULT System::get3DNumListeners(
+  int *numlisteners
+);
+
+ +
FMOD_RESULT FMOD_System_Get3DNumListeners(
+  FMOD_SYSTEM *system,
+  int *numlisteners
+);
+
+ +
RESULT System.get3DNumListeners(
+  out int numlisteners
+);
+
+ +
System.get3DNumListeners(
+  numlisteners
+);
+
+ +
+
numlisteners Out
+
Number of 3D listeners in the 3D scene.
+
+

Users of the Studio API should call Studio::System::getNumListeners instead of this function.

+

See Also: System::set3DNumListeners

+

System::get3DSettings

+

Retrieves the global doppler scale, distance factor and roll-off scale for all 3D sounds.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
FMOD_RESULT System::get3DSettings(
+  float *dopplerscale,
+  float *distancefactor,
+  float *rolloffscale
+);
+
+ +
FMOD_RESULT FMOD_System_Get3DSettings(
+  FMOD_SYSTEM *system,
+  float *dopplerscale,
+  float *distancefactor,
+  float *rolloffscale
+);
+
+ +
RESULT System.get3DSettings(
+  out float dopplerscale,
+  out float distancefactor,
+  out float rolloffscale
+);
+
+ +
System.get3DSettings(
+  dopplerscale,
+  distancefactor,
+  rolloffscale
+);
+
+ +
+
dopplerscale OutOpt
+
A scaling factor for doppler shift.
+
distancefactor OutOpt
+
A factor for converting game distance units to FMOD distance units.
+
rolloffscale OutOpt
+
A scaling factor for distance attenuation. When a sound uses a roll-off mode other than FMOD_3D_CUSTOMROLLOFF and the distance is greater than the sound's minimum distance, the distance is scaled by the roll-off scale.
+
+

See Also: System::set3DSettings

+

System::getAdvancedSettings

+

Retrieves the advanced settings for the system object.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
FMOD_RESULT System::getAdvancedSettings(
+  FMOD_ADVANCEDSETTINGS *settings
+);
+
+ +
FMOD_RESULT FMOD_System_GetAdvancedSettings(
+  FMOD_SYSTEM *system,
+  FMOD_ADVANCEDSETTINGS *settings
+);
+
+ +
RESULT System.getAdvancedSettings(
+  ref ADVANCEDSETTINGS settings
+);
+
+ +
System.getAdvancedSettings(
+  settings
+);
+
+ +
+
settings Out
+
Advanced settings (FMOD_ADVANCEDSETTINGS)
+
+

See Also: System::setAdvancedSettings

+

System::getChannel

+

Retrieves a handle to a Channel by ID.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
FMOD_RESULT System::getChannel(
+  int channelid,
+  Channel **channel
+);
+
+ +
FMOD_RESULT FMOD_System_GetChannel(
+  FMOD_SYSTEM *system,
+  int channelid,
+  FMOD_CHANNEL **channel
+);
+
+ +
RESULT System.getChannel(
+  int channelid,
+  out Channel channel
+);
+
+ +
System.getChannel(
+  channelid,
+  channel
+);
+
+ +
+
channelid
+
Index in the FMOD Channel pool. Specify a Channel number from 0 to the 'maxchannels' value specified in System::init minus 1.
+
channel Out
+
Requested Channel. (Channel)
+
+

This function is mainly for getting handles to existing (playing) Channels and setting their attributes. The only way to 'create' an instance of a Channel for playback is to use System::playSound or [System::playDSP].

+

See Also: System::init

+

System::getChannelsPlaying

+

Retrieves the number of currently playing Channels.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
FMOD_RESULT System::getChannelsPlaying(
+  int *channels,
+  int *realchannels = nullptr
+);
+
+ +
FMOD_RESULT FMOD_System_GetChannelsPlaying(
+  FMOD_SYSTEM *system,
+  int *channels,
+  int *realchannels
+);
+
+ +
RESULT System.getChannelsPlaying(
+  out int channels
+);
+RESULT System.getChannelsPlaying(
+  out int channels,
+  out int realchannels
+);
+
+ +
System.getChannelsPlaying(
+  channels,
+  realchannels
+);
+
+ +
+
channels OptOut
+
Number of playing Channels (both real and virtual).
+
realchannels OptOut
+
Number of playing real (non-virtual) Channels.
+
+

For differences between real and virtual voices see the Virtual Voice System section of the Managing Resources in the Core API chapter for more information.

+

See Also: ChannelControl::isPlaying, Channel::isVirtual

+

System::getCPUUsage

+

Retrieves the amount of CPU used for different parts of the Core API.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
FMOD_RESULT System::getCPUUsage(
+  FMOD_CPU_USAGE *usage
+);
+
+ +
FMOD_RESULT FMOD_System_GetCPUUsage(
+  FMOD_SYSTEM *system,
+  FMOD_CPU_USAGE *usage
+);
+
+ +
RESULT System.getCPUUsage(
+  out CPU_USAGE usage
+);
+
+ +
System.getCPUUsage(
+  usage
+);
+
+ +
+
usage Out
+
CPU usage values. (FMOD_CPU_USAGE)
+
+

For readability, the percentage values are smoothed to provide a more stable output.

+

See Also: Studio::System::getCPUUsage, FMOD_STUDIO_CPU_USAGE

+

System::getDefaultMixMatrix

+

Retrieves the default matrix used to convert from one speaker mode to another.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
FMOD_RESULT System::getDefaultMixMatrix(
+  FMOD_SPEAKERMODE sourcespeakermode,
+  FMOD_SPEAKERMODE targetspeakermode,
+  float *matrix,
+  int matrixhop
+);
+
+ +
FMOD_RESULT FMOD_System_GetDefaultMixMatrix(
+  FMOD_SYSTEM *system,
+  FMOD_SPEAKERMODE sourcespeakermode,
+  FMOD_SPEAKERMODE targetspeakermode,
+  float *matrix,
+  int matrixhop
+);
+
+ +
RESULT System.getDefaultMixMatrix(
+  SPEAKERMODE sourcespeakermode,
+  SPEAKERMODE targetspeakermode,
+  float[] matrix,
+  int matrixhop
+);
+
+ +
System.getDefaultMixMatrix(
+  sourcespeakermode,
+  targetspeakermode,
+  matrix,
+  matrixhop
+);
+
+ +
+
sourcespeakermode
+
The speaker mode being converted from. (FMOD_SPEAKERMODE)
+
targetspeakermode
+
The speaker mode being converted to. (FMOD_SPEAKERMODE)
+
matrix Out
+
The output matrix. Its minimum size in number of floats must be the number of source channels multiplied by the number of target channels. Source and target channels cannot exceed FMOD_MAX_CHANNEL_WIDTH.
+
matrixhop Opt
+
The number of source channels in the matrix. If this is 0, the number of source channels will be derived from sourcespeakermode. Maximum of FMOD_MAX_CHANNEL_WIDTH.
+
+

The gain for source channel 's' to target channel 't' is matrix[t * matrixhop + s].

+

If 'sourcespeakermode' or 'targetspeakermode' is FMOD_SPEAKERMODE_RAW, this function will return FMOD_ERR_INVALID_PARAM.

+

See Also: System::getSpeakerModeChannels

+

System::getDriver

+

Retrieves the output driver for the selected output type.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
FMOD_RESULT System::getDriver(
+  int *driver
+);
+
+ +
FMOD_RESULT FMOD_System_GetDriver(
+  FMOD_SYSTEM *system,
+  int *driver
+);
+
+ +
RESULT System.getDriver(
+  out int driver
+);
+
+ +
System.getDriver(
+  driver
+);
+
+ +
+
driver Out
+
Driver index where 0 represents the default for the output type.
+
+

See Also: System::setDriver

+

System::getDriverInfo

+

Retrieves identification information about a sound device specified by its index, and specific to the selected output mode.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
FMOD_RESULT System::getDriverInfo(
+  int id,
+  char *name,
+  int namelen,
+  FMOD_GUID *guid,
+  int *systemrate,
+  FMOD_SPEAKERMODE *speakermode,
+  int *speakermodechannels
+);
+
+ +
FMOD_RESULT FMOD_System_GetDriverInfo(
+  FMOD_SYSTEM *system,
+  int id,
+  char *name,
+  int namelen,
+  FMOD_GUID *guid,
+  int *systemrate,
+  FMOD_SPEAKERMODE *speakermode,
+  int *speakermodechannels
+);
+
+ +
RESULT System.getDriverInfo(
+  int id,
+  out string name,
+  int namelen,
+  out Guid guid,
+  out int systemrate,
+  out SPEAKERMODE speakermode,
+  out int speakermodechannels
+);
+
+ +
System.getDriverInfo(
+  id,
+  name,
+  guid,
+  systemrate,
+  speakermode,
+  speakermodechannels
+);
+
+ +
+
id
+
+

Index of the sound driver device.

+ +
+
name OptOut
+
Name of the device. (UTF-8 string)
+
namelen
+
+

Length of name. 256 is sufficient to contain the vast majority of driver names.

+
    +
  • Units: Bytes
  • +
+
+
guid OptOut
+
A GUID that uniquely identifies the device. (FMOD_GUID)
+
systemrate OptOut
+
Sample rate this device operates at.
+
speakermode OptOut
+
Speaker setup this device is currently using. (FMOD_SPEAKERMODE)
+
speakermodechannels OptOut
+
Number of channels in the current speaker setup.
+
+

See Also: System::setOutput

+

System::getDSPBufferSize

+

Retrieves the buffer size settings for the FMOD software mixing engine.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
FMOD_RESULT System::getDSPBufferSize(
+  unsigned int *bufferlength,
+  int *numbuffers
+);
+
+ +
FMOD_RESULT FMOD_System_GetDSPBufferSize(
+  FMOD_SYSTEM *system,
+  unsigned int *bufferlength,
+  int *numbuffers
+);
+
+ +
RESULT System.getDSPBufferSize(
+  out uint bufferlength,
+  out int numbuffers
+);
+
+ +
System.getDSPBufferSize(
+  bufferlength,
+  numbuffers
+);
+
+ +
+
bufferlength OptOut
+
+

Mixer engine block size.

+
    +
  • Units: Samples
  • +
  • Default: 1024
  • +
+
+
numbuffers OptOut
+
+

Mixer engine number of buffers used.

+
    +
  • Default: 4
  • +
+
+
+

To get the bufferlength in milliseconds, divide it by the output rate and multiply the result by 1000. For a bufferlength of 1024 and an output rate of 48khz (see System::SetSoftwareFormat), milliseconds = 1024 / 48000 * 1000 = 21.33ms. This means the mixer updates every 21.33ms.

+

To get the total buffer size multiply the bufferlength by the numbuffers value. By default this would be 4 * 1024 = 4096 samples, or 4 * 21.33ms = 85.33ms. This would generally be the total latency of the software mixer, but in reality due to one of the buffers being written to constantly, and the cursor position of the buffer that is audible, the latency is typically more like the (number of buffers - 1.5) multiplied by the buffer length.

+

To convert from milliseconds back to 'samples', simply multiply the value in milliseconds by the sample rate of the output (ie 48000 if that is what it is set to), then divide by 1000.

+

See Also: System::setDSPBufferSize

+

System::getDSPInfoByPlugin

+

Retrieve the description structure for a pre-existing DSP plug-in.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
FMOD_RESULT System::getDSPInfoByPlugin(
+  unsigned int handle,
+  const FMOD_DSP_DESCRIPTION **description
+);
+
+ +
FMOD_RESULT FMOD_System_GetDSPInfoByPlugin(
+  FMOD_SYSTEM *system,
+  unsigned int handle,
+  const FMOD_DSP_DESCRIPTION **description
+);
+
+ +
RESULT System.getDSPInfoByPlugin(
+  uint handle,
+  out IntPtr description
+);
+
+ +
System.getDSPInfoByPlugin(
+  handle,
+  description
+);
+
+ +
+
handle
+
Handle to a pre-existing DSP plug-in, loaded by System::loadPlugin.
+
description Out
+
Description structure for the DSP. (FMOD_DSP_DESCRIPTION)
+
+

See Also: System::loadPlugin

+

System::getDSPInfoByType

+

Retrieve the description structure for a built-in DSP plug-in.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
FMOD_RESULT System::getDSPInfoByType(
+  FMOD_DSP_TYPE type,
+  const FMOD_DSP_DESCRIPTION **description
+);
+
+ +
FMOD_RESULT FMOD_System_GetDSPInfoByType(
+  FMOD_SYSTEM *system,
+  FMOD_DSP_TYPE type,
+  const FMOD_DSP_DESCRIPTION **description
+);
+
+ +
RESULT System.getDSPInfoByType(
+  DSP_TYPE type,
+  out IntPtr description
+);
+
+ +
System.getDSPInfoByType(
+  type,
+  description
+);
+
+ +
+
type
+
Type of built in unit. (FMOD_DSP_TYPE)
+
description Out
+
Description structure for the DSP. (FMOD_DSP_DESCRIPTION)
+
+

FMOD_DSP_TYPE_MIXER not supported.

+

See Also: System::getDSPInfoByPlugin

+

System::getFileUsage

+

Retrieves information about file reads.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
FMOD_RESULT System::getFileUsage(
+  long long *sampleBytesRead,
+  long long *streamBytesRead,
+  long long *otherBytesRead
+);
+
+ +
FMOD_RESULT FMOD_System_GetFileUsage(
+  FMOD_SYSTEM *system,
+  long long *sampleBytesRead,
+  long long *streamBytesRead,
+  long long *otherBytesRead
+);
+
+ +
RESULT System.getFileUsage(
+  out Int64 sampleBytesRead,
+  out Int64 streamBytesRead,
+  out Int64 otherBytesRead
+);
+
+ +
System.getFileUsage(
+  sampleBytesRead,
+  streamBytesRead,
+  otherBytesRead
+);
+
+ +
+
sampleBytesRead OptOut
+
+

Total bytes read from file for loading sample data.

+
    +
  • Units: Bytes
  • +
+
+
streamBytesRead OptOut
+
+

Total bytes read from file for streaming sounds.

+
    +
  • Units: Bytes
  • +
+
+
otherBytesRead OptOut
+
+

Total bytes read for non-audio data such as bank files created in FMOD Studio.

+
    +
  • Units: Bytes
  • +
+
+
+

The values returned are running totals that never reset.

+

System::getGeometryOcclusion

+

Calculates geometry occlusion between a listener and a sound source.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
FMOD_RESULT System::getGeometryOcclusion(
+  const FMOD_VECTOR *listener,
+  const FMOD_VECTOR *source,
+  float *direct,
+  float *reverb
+);
+
+ +
FMOD_RESULT FMOD_System_GetGeometryOcclusion(
+  FMOD_SYSTEM *system,
+  const FMOD_VECTOR *listener,
+  const FMOD_VECTOR *source,
+  float *direct,
+  float *reverb
+);
+
+ +
RESULT System.getGeometryOcclusion(
+  ref VECTOR listener,
+  ref VECTOR source,
+  out float direct,
+  out float reverb
+);
+
+ +
System.getGeometryOcclusion(
+  listener,
+  source,
+  direct,
+  reverb
+);
+
+ +
+
listener
+
The listener position. (FMOD_VECTOR)
+
source
+
The source position. (FMOD_VECTOR)
+
direct OptOut
+
Direct occlusion value. 0 = not occluded at all / full volume, 1 = fully occluded / silent.
+
reverb OptOut
+
Reverb occlusion value. 0 = not occluded at all / wet, 1 = fully occluded / dry.
+
+

If single sided polygons have been created, it is important to get the source and listener positions around the right way,
+as the occlusion from point A to point B may not be the same as the occlusion from point B to point A.

+

See Also: System::createGeometry

+

System::getGeometrySettings

+

Retrieves the maximum world size for the geometry engine.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
FMOD_RESULT System::getGeometrySettings(
+  float *maxworldsize
+);
+
+ +
FMOD_RESULT FMOD_System_GetGeometrySettings(
+  FMOD_SYSTEM *system,
+  float *maxworldsize
+);
+
+ +
RESULT System.getGeometrySettings(
+  out float maxworldsize
+);
+
+ +
System.getGeometrySettings(
+  maxworldsize
+);
+
+ +
+
maxworldsize Out
+
Maximum world size.
+
+

FMOD uses an efficient spatial partitioning system to store polygons for ray casting purposes.
+The maximum size of the world should be set to allow processing within a known range.
+Outside of this range, objects and polygons will not be processed as efficiently.
+Excessive world size settings can also cause loss of precision and efficiency.

+

See Also: System::setGeometrySettings

+

System::getMasterChannelGroup

+

Retrieves the master ChannelGroup that all sounds ultimately route to.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
FMOD_RESULT System::getMasterChannelGroup(
+  ChannelGroup **channelgroup
+);
+
+ +
FMOD_RESULT FMOD_System_GetMasterChannelGroup(
+  FMOD_SYSTEM *system,
+  FMOD_CHANNELGROUP **channelgroup
+);
+
+ +
RESULT System.getMasterChannelGroup(
+  out ChannelGroup channelgroup
+);
+
+ +
System.getMasterChannelGroup(
+  channelgroup
+);
+
+ +
+
channelgroup Out
+
Master group. (ChannelGroup)
+
+

This is the default ChannelGroup that Channels play on, unless a different ChannelGroup is specified with System::playSound, System::playDSP or Channel::setChannelGroup.
+A master ChannelGroup can be used to do things like set the 'master volume' for all playing Channels. See ChannelControl::setVolume.

+

See Also: System::createChannelGroup

+

System::getMasterSoundGroup

+

Retrieves the default SoundGroup, where all sounds are placed when they are created.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
FMOD_RESULT System::getMasterSoundGroup(
+  SoundGroup **soundgroup
+);
+
+ +
FMOD_RESULT FMOD_System_GetMasterSoundGroup(
+  FMOD_SYSTEM *system,
+  FMOD_SOUNDGROUP **soundgroup
+);
+
+ +
RESULT System.getMasterSoundGroup(
+  out SoundGroup soundgroup
+);
+
+ +
System.getMasterSoundGroup(
+  soundgroup
+);
+
+ +
+
soundgroup Out
+
Master sound group. (SoundGroup)
+
+

If SoundGroup is released, the Sounds will be put back into this SoundGroup.

+

See Also: SoundGroup::release, Sound::setSoundGroup

+

System::getNestedPlugin

+

Retrieves the handle of a nested plug-in.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
FMOD_RESULT System::getNestedPlugin(
+  unsigned int handle,
+  int index,
+  unsigned int *nestedhandle
+);
+
+ +
FMOD_RESULT FMOD_System_GetNestedPlugin(
+  FMOD_SYSTEM *system,
+  unsigned int handle,
+  int index,
+  unsigned int *nestedhandle
+);
+
+ +
RESULT System.getNestedPlugin(
+  uint handle,
+  int index,
+  out uint nestedhandle
+);
+
+ +
System.getNestedPlugin(
+  handle,
+  index,
+  nestedhandle
+);
+
+ +
+
handle
+
Handle obtained from System::loadPlugin.
+
index
+
+

Index into the list of plug-in definitions.

+ +
+
nestedhandle Out
+
Handle used to represent the nested plug-in.
+
+

This function is used to iterate handles for plug-ins that have a list of definitions.

+

Most plug-ins contain a single definition. If this is the case, only index 0 is valid, and the returned handle is the same as the handle passed in.

+

See the DSP Plug-in API guide for more information.

+

System::getNetworkProxy

+

Retrieves the URL of the proxy server used in internet streaming.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
FMOD_RESULT System::getNetworkProxy(
+  char *proxy,
+  int proxylen
+);
+
+ +
FMOD_RESULT FMOD_System_GetNetworkProxy(
+  FMOD_SYSTEM *system,
+  char *proxy,
+  int proxylen
+);
+
+ +
RESULT System.getNetworkProxy(
+  out string proxy,
+  int proxylen
+);
+
+ +
System.getNetworkProxy(
+  proxy
+);
+
+ +
+
proxy Out
+
Proxy server URL. (UTF-8 string)
+
proxylen
+
Length of proxy.
+
+

See Also: System::setNetworkProxy

+

System::getNetworkTimeout

+

Retrieve the timeout value for network streams.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
FMOD_RESULT System::getNetworkTimeout(
+  int *timeout
+);
+
+ +
FMOD_RESULT FMOD_System_GetNetworkTimeout(
+  FMOD_SYSTEM *system,
+  int *timeout
+);
+
+ +
RESULT System.getNetworkTimeout(
+  out int timeout
+);
+
+ +
System.getNetworkTimeout(
+  timeout
+);
+
+ +
+
timeout Out
+
+

Timeout value.

+

Units: Milliseconds

+
+
+

System::getNumDrivers

+

Retrieves the number of output drivers available for the selected output type.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
FMOD_RESULT System::getNumDrivers(
+  int *numdrivers
+);
+
+ +
FMOD_RESULT FMOD_System_GetNumDrivers(
+  FMOD_SYSTEM *system,
+  int *numdrivers
+);
+
+ +
RESULT System.getNumDrivers(
+  out int numdrivers
+);
+
+ +
System.getNumDrivers(
+  numdrivers
+);
+
+ +
+
numdrivers Out
+
Number of output drivers.
+
+

If System::setOutput has not been called, this function will return the number of drivers available for the default output type.
+A possible use for this function is to iterate through available sound devices for the current output type, and use System::getDriverInfo to get the device's name and other attributes.

+

See Also: System::getDriver

+

System::getNumNestedPlugins

+

Retrieves the number of nested plug-ins from the selected plug-in.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
FMOD_RESULT System::getNumNestedPlugins(
+  unsigned int handle,
+  int *count
+);
+
+ +
FMOD_RESULT FMOD_System_GetNumNestedPlugins(
+  FMOD_SYSTEM *system,
+  unsigned int handle,
+  int *count
+);
+
+ +
RESULT System.getNumNestedPlugins(
+  uint handle,
+  out int count
+);
+
+ +
System.getNumNestedPlugins(
+  handle,
+  count
+);
+
+ +
+
handle
+
Handle obtained from System::loadPlugin.
+
count
+
Returned number of plug-ins.
+
+

Most plug-ins contain a single definition, in which case the count is 1, however some have a list of definitions. This function returns the number of plug-ins that have been defined.

+

See the DSP Plug-in API guide for more information.

+

See Also: System::getNestedPlugin

+

System::getNumPlugins

+

Retrieves the number of loaded plug-ins.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
FMOD_RESULT System::getNumPlugins(
+  FMOD_PLUGINTYPE plugintype,
+  int *numplugins
+);
+
+ +
FMOD_RESULT FMOD_System_GetNumPlugins(
+  FMOD_SYSTEM *system,
+  FMOD_PLUGINTYPE plugintype,
+  int *numplugins
+);
+
+ +
RESULT System.getNumPlugins(
+  PLUGINTYPE plugintype,
+  out int numplugins
+);
+
+ +
System.getNumPlugins(
+  plugintype,
+  numplugins
+);
+
+ +
+
plugintype
+
Plugin type. (FMOD_PLUGINTYPE)
+
numplugins Out
+
Number of loaded plug-ins for the selected plugintype.
+
+

See Also: System::loadPlugin, System::getPluginHandle

+

System::getOutput

+

Retrieves the type of output interface used to run the mixer.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
FMOD_RESULT System::getOutput(
+  FMOD_OUTPUTTYPE *output
+);
+
+ +
FMOD_RESULT FMOD_System_GetOutput(
+  FMOD_SYSTEM *system,
+  FMOD_OUTPUTTYPE *output
+);
+
+ +
RESULT System.getOutput(
+  out OUTPUTTYPE output
+);
+
+ +
System.getOutput(
+  output
+);
+
+ +
+
output Out
+
Output type. (FMOD_OUTPUTTYPE)
+
+

See Also: System::setOutput

+

System::getOutputByPlugin

+

Retrieves the plug-in handle for the currently selected output type.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
FMOD_RESULT System::getOutputByPlugin(
+  unsigned int *handle
+);
+
+ +
FMOD_RESULT FMOD_System_GetOutputByPlugin(
+  FMOD_SYSTEM *system,
+  unsigned int *handle
+);
+
+ +
RESULT System.getOutputByPlugin(
+  out uint handle
+);
+
+ +
System.getOutputByPlugin(
+  handle
+);
+
+ +
+
handle Out
+
Handle to a pre-existing output plug-in.
+
+

See Also: System::getNumPlugins, System::setOutputByPlugin, System::setOutput

+

System::getOutputHandle

+

Retrieves an output type specific internal native interface.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
FMOD_RESULT System::getOutputHandle(
+  void **handle
+);
+
+ +
FMOD_RESULT FMOD_System_GetOutputHandle(
+  FMOD_SYSTEM *system,
+  void **handle
+);
+
+ +
RESULT System.getOutputHandle(
+  out IntPtr handle
+);
+
+ +
System.getOutputHandle(
+  handle
+);
+
+ +
+
handle Out
+
Internal native handle.
+
+

Reinterpret the returned handle based on the selected output type, not all types return something.

+ +

See Also: FMOD_OUTPUTTYPE, System::setOutput, System::init

+

System::getPluginHandle

+

Retrieves the handle of a plug-in based on its type and relative index.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
FMOD_RESULT System::getPluginHandle(
+  FMOD_PLUGINTYPE plugintype,
+  int index,
+  unsigned int *handle
+);
+
+ +
FMOD_RESULT FMOD_System_GetPluginHandle(
+  FMOD_SYSTEM *system,
+  FMOD_PLUGINTYPE plugintype,
+  int index,
+  unsigned int *handle
+);
+
+ +
RESULT System.getPluginHandle(
+  PLUGINTYPE plugintype,
+  int index,
+  out uint handle
+);
+
+ +
System.getPluginHandle(
+  plugintype,
+  index,
+  handle
+);
+
+ +
+
plugintype
+
Plug-in type. (FMOD_PLUGINTYPE)
+
index
+
Index in the list of plug-ins for the given plugintype.
+
handle Out
+
Handle used to represent the plugin.
+
+

All plug-ins, whether built-in or loaded, can be enumerated using this and System::getNumPlugins.

+

See Also: System::loadPlugin

+

System::getPluginInfo

+

Retrieves information for the selected plug-in.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
FMOD_RESULT System::getPluginInfo(
+  unsigned int handle,
+  FMOD_PLUGINTYPE *plugintype,
+  char *name,
+  int namelen,
+  unsigned int *version
+);
+
+ +
FMOD_RESULT FMOD_System_GetPluginInfo(
+  FMOD_SYSTEM *system,
+  unsigned int handle,
+  FMOD_PLUGINTYPE *plugintype,
+  char *name,
+  int namelen,
+  unsigned int *version
+);
+
+ +
RESULT System.getPluginInfo(
+  uint handle,
+  out PLUGINTYPE plugintype,
+  out string name,
+  int namelen,
+  out uint version
+);
+
+ +
System.getPluginInfo(
+  handle,
+  plugintype,
+  name,
+  version
+);
+
+ +
+
handle
+
Handle to an already loaded plug-in.
+
plugintype OptOut
+
Plug-in type. (FMOD_PLUGINTYPE)
+
name OptOut
+
Name of the plug-in. (UTF-8 string)
+
namelen
+
+

Length of name.

+
    +
  • Units: Bytes
  • +
+
+
version OptOut
+
Version number of the plug-in.
+
+

See Also: System::getNumPlugins, System::getPluginHandle

+

System::getRecordDriverInfo

+

Retrieves identification information about an audio device specified by its index, and specific to the output mode.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
FMOD_RESULT System::getRecordDriverInfo(
+  int id,
+  char *name,
+  int namelen,
+  FMOD_GUID *guid,
+  int *systemrate,
+  FMOD_SPEAKERMODE *speakermode,
+  int *speakermodechannels,
+  FMOD_DRIVER_STATE *state
+);
+
+ +
FMOD_RESULT FMOD_System_GetRecordDriverInfo(
+  FMOD_SYSTEM *system,
+  int id,
+  char *name,
+  int namelen,
+  FMOD_GUID *guid,
+  int *systemrate,
+  FMOD_SPEAKERMODE *speakermode,
+  int *speakermodechannels,
+  FMOD_DRIVER_STATE *state
+);
+
+ +
RESULT System.getRecordDriverInfo(
+  int id,
+  out string name,
+  int namelen,
+  out Guid guid,
+  out int systemrate,
+  out SPEAKERMODE speakermode,
+  out int speakermodechannels,
+  out DRIVER_STATE state
+);
+
+ +
System.getRecordDriverInfo(
+  id,
+  name,
+  guid,
+  systemrate,
+  speakermode,
+  speakermodechannels,
+  state
+);
+
+ +
+
id
+
+

Index of the recording device.

+ +
+
name OptOut
+
The name of the device. (UTF-8 string)
+
namelen
+
The length of the target buffer receiving the name string.
+
+
    +
  • Units: Bytes
  • +
+
+
guid OptOut
+
A GUID that uniquely identifies the device. (FMOD_GUID)
+
systemrate OptOut
+
The sample rate the device operates at.
+
speakermode OptOut
+
The speaker configuration the device is currently using. (FMOD_SPEAKERMODE)
+
speakermodechannels OptOut
+
The number of channels in the current speaker setup.
+
state OptOut
+
Flags that provide additional information about the driver. (FMOD_DRIVER_STATE)
+
+

See Also: System::setOutput

+

System::getRecordNumDrivers

+

Retrieves the number of recording devices available for this output mode. Use this to enumerate all recording devices possible so that the user can select one.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
FMOD_RESULT System::getRecordNumDrivers(
+  int *numdrivers,
+  int *numconnected
+);
+
+ +
FMOD_RESULT FMOD_System_GetRecordNumDrivers(
+  FMOD_SYSTEM *system,
+  int *numdrivers,
+  int *numconnected
+);
+
+ +
RESULT System.getRecordNumDrivers(
+  out int numdrivers,
+  out int numconnected
+);
+
+ +
System.getRecordNumDrivers(
+  numdrivers,
+  numconnected
+);
+
+ +
+
numdrivers OptOut
+
Number of recording drivers available for this output mode.
+
numconnected OptOut
+
Number of recording driver currently plugged in.
+
+

See Also: System::getRecordDriverInfo

+

System::getRecordPosition

+

Retrieves the current recording position of the record buffer in PCM samples.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
FMOD_RESULT System::getRecordPosition(
+  int id,
+  unsigned int *position
+);
+
+ +
FMOD_RESULT FMOD_System_GetRecordPosition(
+  FMOD_SYSTEM *system,
+  int id,
+  unsigned int *position
+);
+
+ +
RESULT System.getRecordPosition(
+  int id,
+  out uint position
+);
+
+ +
System.getRecordPosition(
+  id,
+  position
+);
+
+ +
+
id
+
+

Index of the recording device.

+ +
+
position Out
+
+

Current recording position.

+

Units: Samples

+
+
+

Will return FMOD_ERR_RECORD_DISCONNECTED if the driver is unplugged.

+

The position will return to 0 when System::recordStop is called or when a non-looping recording reaches the end.

+

PS4 specific note: Record devices are virtual so 'position' will continue to update if the device is unplugged (the OS is generating silence). This function will still report FMOD_ERR_RECORD_DISCONNECTED for your information though.

+

See Also: System::recordStart, System::recordStop

+

System::getReverbProperties

+

Retrieves the current reverb environment for the specified reverb instance.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
FMOD_RESULT System::getReverbProperties(
+  int instance,
+  FMOD_REVERB_PROPERTIES *prop
+);
+
+ +
FMOD_RESULT FMOD_System_GetReverbProperties(
+  FMOD_SYSTEM *system,
+  int instance,
+  FMOD_REVERB_PROPERTIES *prop
+);
+
+ +
RESULT System.getReverbProperties(
+  int instance,
+  out REVERB_PROPERTIES prop
+);
+
+ +
System.getReverbProperties(
+  instance,
+  prop
+);
+
+ +
+
instance
+
Index of the particular reverb instance to target.
+
prop Out
+
Current reverb environment description. (FMOD_REVERB_PROPERTIES)
+
+

See Also: System::setReverbProperties

+

System::getSoftwareChannels

+

Retrieves the maximum number of software mixed Channels possible.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
FMOD_RESULT System::getSoftwareChannels(
+  int *numsoftwarechannels
+);
+
+ +
FMOD_RESULT FMOD_System_GetSoftwareChannels(
+  FMOD_SYSTEM *system,
+  int *numsoftwarechannels
+);
+
+ +
RESULT System.getSoftwareChannels(
+  out int numsoftwarechannels
+);
+
+ +
System.getSoftwareChannels(
+  numsoftwarechannels
+);
+
+ +
+
numsoftwarechannels Out
+
Current maximum number of real voices (Channels) available.
+
+

Software Channels refers to real voices that will play, with numsoftwarechannels refering to the maximum number of voices before successive voices start becoming virtual. For differences between real and virtual voices, see the Virtual Voice System section of the Managing Resources in the Core API chapter.

+

See Also: System::setSoftwareChannels

+

System::getSoftwareFormat

+

Retrieves the output format for the software mixer.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
FMOD_RESULT System::getSoftwareFormat(
+  int *samplerate,
+  FMOD_SPEAKERMODE *speakermode,
+  int *numrawspeakers
+);
+
+ +
FMOD_RESULT FMOD_System_GetSoftwareFormat(
+  FMOD_SYSTEM *system,
+  int *samplerate,
+  FMOD_SPEAKERMODE *speakermode,
+  int *numrawspeakers
+);
+
+ +
RESULT System.getSoftwareFormat(
+  out int samplerate,
+  out SPEAKERMODE speakermode,
+  out int numrawspeakers
+);
+
+ +
System.getSoftwareFormat(
+  samplerate,
+  speakermode,
+  numrawspeakers
+);
+
+ +
+
samplerate OptOut
+
Sample rate of the mixer.
+
speakermode OptOut
+
Speaker setup of the mixer. (FMOD_SPEAKERMODE)
+
numrawspeakers OptOut
+
Number of speakers for FMOD_SPEAKERMODE_RAW mode.
+
+

See Also: System::setSoftwareFormat

+

System::getSpeakerModeChannels

+

Retrieves the channel count for a given speaker mode.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
FMOD_RESULT System::getSpeakerModeChannels(
+  FMOD_SPEAKERMODE mode,
+  int *channels
+);
+
+ +
FMOD_RESULT FMOD_System_GetSpeakerModeChannels(
+  FMOD_SYSTEM *system,
+  FMOD_SPEAKERMODE mode,
+  int *channels
+);
+
+ +
RESULT System.getSpeakerModeChannels(
+  SPEAKERMODE mode,
+  out int channels
+);
+
+ +
System.getSpeakerModeChannels(
+  mode,
+  channels
+);
+
+ +
+
mode
+
Speaker mode to query. (FMOD_SPEAKERMODE)
+
channels Out
+
Number of channels.
+
+

System::getSpeakerPosition

+

Retrieves the position of the specified speaker for the current speaker mode.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
FMOD_RESULT System::getSpeakerPosition(
+  FMOD_SPEAKER speaker,
+  float *x,
+  float *y,
+  bool *active
+);
+
+ +
FMOD_RESULT FMOD_System_GetSpeakerPosition(
+  FMOD_SYSTEM *system,
+  FMOD_SPEAKER speaker,
+  float *x,
+  float *y,
+  FMOD_BOOL *active
+);
+
+ +
RESULT System.getSpeakerPosition(
+  SPEAKER speaker,
+  out float x,
+  out float y,
+  out bool active
+);
+
+ +
System.getSpeakerPosition(
+  speaker,
+  x,
+  y,
+  active
+);
+
+ +
+
speaker
+
Speaker. (FMOD_SPEAKER)
+
x OptOut
+
+

2D X position relative to the listener. -1 = left, 0 = middle, +1 = right.

+
    +
  • Range: [-1, 1]
  • +
+
+
y OptOut
+
+

2D Y position relative to the listener. -1 = back, 0 = middle, +1 = front.

+
    +
  • Range: [-1, 1]
  • +
+
+
active OptOut
+
+

Active state of a speaker. True = included in 3D calculations, False = ignored.

+
    +
  • Units: Boolean
  • +
+
+
+

See Also: System::setSpeakerPosition

+

System::getStreamBufferSize

+

Retrieves the default file buffer size for newly opened streams.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
FMOD_RESULT System::getStreamBufferSize(
+  unsigned int *filebuffersize,
+  FMOD_TIMEUNIT *filebuffersizetype
+);
+
+ +
FMOD_RESULT FMOD_System_GetStreamBufferSize(
+  FMOD_SYSTEM *system,
+  unsigned int *filebuffersize,
+  FMOD_TIMEUNIT *filebuffersizetype
+);
+
+ +
RESULT System.getStreamBufferSize(
+  out uint filebuffersize,
+  out TIMEUNIT filebuffersizetype
+);
+
+ +
System.getStreamBufferSize(
+  filebuffersize,
+  filebuffersizetype
+);
+
+ +
+
filebuffersize OptOut
+
+

Buffer size.

+
    +
  • Default: 16384
  • +
+
+
filebuffersizetype OptOut
+
+

Type of units for filebuffersize. (FMOD_TIMEUNIT)

+ +
+
+

Valid units for filebuffersizetype are:

+ +

See Also: System::setStreamBufferSize

+

System::getUserData

+

Retrieves a user value associated with a System object.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
FMOD_RESULT System::getUserData(
+  void **userdata
+);
+
+ +
FMOD_RESULT FMOD_System_GetUserData(
+  FMOD_SYSTEM *system,
+  void **userdata
+);
+
+ +
RESULT System.getUserData(
+  out IntPtr userdata
+);
+
+ +
System.getUserData(
+  userdata
+);
+
+ +
+
userdata Out
+
User data set by calling System::setUserData.
+
+

This function allows arbitrary user data to be retrieved from this object. See the User Data section of the glossary for an example of how to get and set user data.

+

System::getVersion

+

Retrieves the FMOD version and build number.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
FMOD_RESULT System::getVersion(
+  unsigned int *version,
+  unsigned int *buildnumber = 0
+);
+
+ +
FMOD_RESULT FMOD_System_GetVersion(
+  FMOD_SYSTEM *system,
+  unsigned int *version,
+  unsigned int *buildnumber
+);
+
+ +
RESULT System.getVersion(
+  out uint version
+);
+RESULT System.getVersion(
+  out uint version,
+  out uint buildnumber
+);
+
+ +
System.getVersion(
+  version,
+  buildnumber
+);
+
+ +
+
version OutOpt
+
Version number.
+
buildnumber OutOpt
+
Build number.
+
+

The version is a 32 bit hexadecimal value formatted as 16:8:8, with the upper 16 bits being the product version, the middle 8 bits being the major version and the bottom 8 bits being the minor version. For example a value of 0x00010203 is equal to 1.02.03.

+

Compare against FMOD_VERSION to make sure header and runtime library versions match.

+

See Also: System_Create

+

System::init

+

Initialize the system object and prepare FMOD for playback.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
FMOD_RESULT System::init(
+  int maxchannels,
+  FMOD_INITFLAGS flags,
+  void *extradriverdata
+);
+
+ +
FMOD_RESULT FMOD_System_Init(
+  FMOD_SYSTEM *system,
+  int maxchannels,
+  FMOD_INITFLAGS flags,
+  void *extradriverdata
+);
+
+ +
RESULT System.init(
+  int maxchannels,
+  INITFLAGS flags,
+  IntPtr extradriverdata
+);
+
+ +
System.init(
+  maxchannels,
+  flags,
+  extradriverdata
+);
+
+ +
+
maxchannels
+
+

Maximum number of Channel objects available for playback, also known as virtual voices. Virtual voices will play with minimal overhead, with a subset of 'real' voices that are mixed, and selected based on priority and audibility. See the Virtual Voice System section of the Managing Resources in the Core API chapter for more information.

+
    +
  • Range: [0, 4095]
  • +
+
+
flags
+
Initialization flags. More than one mode can be set at once by combining them with the OR operator. (FMOD_INITFLAGS)
+
extradriverdata Opt
+
Additional output specific initialization data. This will be passed to the output plug-in. See FMOD_OUTPUTTYPE for descriptions of data that can be passed in, based on the selected output mode.
+
+

A system object must be created with System_create

+

Most API functions require an initialized System object before they will succeed, otherwise they will return FMOD_ERR_UNINITIALIZED. Some can only be called before initialization. These are:

+ +

System::setOutput / System::setOutputByPlugin can be called before or after System::init on Android, GameCore, UWP, Windows and Mac. Other platforms can only call this before System::init.

+

See Also: System::close, System::release

+

System::isRecording

+

Retrieves the state of the FMOD recording API, ie if it is currently recording or not.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
FMOD_RESULT System::isRecording(
+  int id,
+  bool *recording
+);
+
+ +
FMOD_RESULT FMOD_System_IsRecording(
+  FMOD_SYSTEM *system,
+  int id,
+  FMOD_BOOL *recording
+);
+
+ +
RESULT System.isRecording(
+  int id,
+  out bool recording
+);
+
+ +
System.isRecording(
+  id,
+  recording
+);
+
+ +
+
id
+
+

Index of the recording device.

+ +
+
recording OptOut
+
+

Recording state. True = system is recording, False = system is not recording.

+
    +
  • Units: Boolean
  • +
+
+
+

Recording can be started with System::recordStart and stopped with System::recordStop.

+

Will return FMOD_ERR_RECORD_DISCONNECTED if the driver is unplugged.

+

PS4 specific note: Record devices are virtual so 'recording' will continue to report true if the device is unplugged (the OS is generating silence). This function will still report FMOD_ERR_RECORD_DISCONNECTED for your information though.

+

See Also: System::getRecordPosition

+

System::loadGeometry

+

Creates a geometry object from a block of memory which contains pre-saved geometry data.

+

This function avoids the need to manually create and add geometry for faster start time.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
FMOD_RESULT System::loadGeometry(
+  const void *data,
+  int datasize,
+  Geometry **geometry
+);
+
+ +
FMOD_RESULT FMOD_System_LoadGeometry(
+  FMOD_SYSTEM *system,
+  const void *data,
+  int datasize,
+  FMOD_GEOMETRY **geometry
+);
+
+ +
RESULT System.loadGeometry(
+  IntPtr data,
+  int datasize,
+  out Geometry geometry
+);
+
+ +
System.loadGeometry(
+  data,
+  datasize,
+  geometry
+);
+
+ +
+
data
+
Pre-saved geometry data from Geometry::save.
+
datasize
+
Size of data.
+
+
    +
  • Units: Bytes
  • +
+
+
geometry Out
+
Newly created geometry object. (Geometry)
+
+

See Also: System::createGeometry

+

System::loadPlugin

+

Loads an FMOD plug-in (DSP, output or codec) from a file.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
FMOD_RESULT System::loadPlugin(
+  const char *filename,
+  unsigned int *handle,
+  unsigned int priority = 0
+);
+
+ +
FMOD_RESULT FMOD_System_LoadPlugin(
+  FMOD_SYSTEM *system,
+  const char *filename,
+  unsigned int *handle,
+  unsigned int priority
+);
+
+ +
RESULT System.loadPlugin(
+  string filename,
+  out uint handle,
+  uint priority = 0
+);
+
+ +
+

Currently not supported for JavaScript.

+
+
+
filename
+
Path to the plug-in file. (UTF-8 string)
+
handle Out
+
Handle used to represent the plug-in.
+
priority Opt
+
Codec load priority where 0 represents most important and higher numbers represent less importance. FMOD_PLUGINTYPE_CODEC only.
+
+

Once loaded, DSP plug-ins can be used via System::createDSPByPlugin, output plug-ins can be used via System::setOutputByPlugin, and codec plug-ins are used automatically.

+

When opening a file each codec tests whether it can support the file format in priority order.

+

The format of the plug-in is dependent on the operating system:

+
    +
  • Windows / UWP / Xbox One: .dll
  • +
  • Linux / Android: .so
  • +
  • Macintosh: .dylib
  • +
  • PS4: .prx
  • +
+

See Also: System::unloadPlugin, System::setPluginPath, System::getNumPlugins, System::getPluginHandle, System::getPluginInfo

+

System::lockDSP

+

Mutual exclusion function to lock the DSP engine (which runs asynchronously in another thread), so that it will not execute.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
FMOD_RESULT System::lockDSP();
+
+ +
FMOD_RESULT FMOD_System_LockDSP(FMOD_SYSTEM *system);
+
+ +
RESULT System.lockDSP();
+
+ +
System.lockDSP();
+
+ +

If the DSP engine is already executing, this function is blocked until it has completed.

+

The function may be used to synchronize DSP graph operations carried out by your code. For example, you could use this to construct a DSP sub-graph without the DSP engine executing in the background while the sub-graph is still under construction.

+

Once you no longer need the DSP engine to be locked, it can be unlocked with System::unlockDSP.

+

Note that if the DSP engine is locked for a significant amount of time, it may result in audible skipping or stuttering.

+

System::mixerResume

+

Resume mixer thread and reacquire access to audio hardware.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
FMOD_RESULT System::mixerResume();
+
+ +
FMOD_RESULT FMOD_System_MixerResume(FMOD_SYSTEM *system);
+
+ +
RESULT System.mixerResume();
+
+ +
System.mixerResume();
+
+ +

Used on mobile platforms when entering the foreground after being suspended.

+

All internal state will resume, i.e. created Sound and Channels are still valid and playback will continue.

+

Android specific: Must be called on the same thread as System::mixerSuspend.

+

HTML5 specific: Used to start audio from a user interaction event, like a mouse click or screen touch event. Without this call audio may not start on some browsers.

+

See Also: System::mixerSuspend

+

System::mixerSuspend

+

Suspend mixer thread and relinquish usage of audio hardware while maintaining internal state.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
FMOD_RESULT System::mixerSuspend();
+
+ +
FMOD_RESULT FMOD_System_MixerSuspend(FMOD_SYSTEM *system);
+
+ +
RESULT System.mixerSuspend();
+
+ +
System.mixerSuspend();
+
+ +

Used on mobile platforms when entering a backgrounded state to reduce CPU to 0%.

+

All internal state will be maintained, i.e. created Sound and Channels will stay available in memory.

+

See Also: System::mixerResume

+

System::playDSP

+

Plays a DSP along with any of its inputs on a Channel.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
FMOD_RESULT System::playDSP(
+  DSP *dsp,
+  ChannelGroup *channelgroup,
+  bool paused,
+  Channel **channel
+);
+
+ +
FMOD_RESULT FMOD_System_PlayDSP(
+  FMOD_SYSTEM *system,
+  FMOD_DSP *dsp,
+  FMOD_CHANNELGROUP *channelgroup,
+  FMOD_BOOL paused,
+  FMOD_CHANNEL **channel
+);
+
+ +
RESULT System.playDSP(
+  DSP dsp,
+  ChannelGroup channelgroup,
+  bool paused,
+  out Channel channel
+);
+
+ +
System.playDSP(
+  dsp,
+  channelgroup,
+  paused,
+  channel
+);
+
+ +
+
dsp
+
Unit to play. (DSP)
+
channelgroup Opt
+
Group to output to instead of the master. (ChannelGroup)
+
paused
+
+

Whether to start in the paused state. Start a Channel paused to allow altering attributes without it being audible, then follow it up with a call to ChannelControl::setPaused with paused = False.

+
    +
  • Units: Boolean
  • +
+
+
channel OptOut
+
Newly playing Channel. (Channel)
+
+

Specifying a channelgroup as part of playDSP is more efficient than using Channel::setChannelGroup after playDSP, and could avoid audible glitches if the playDSP is not in a paused state.

+

If dsp returns FMOD_ERR_FILE_EOF from its process or read callback, the channel will stop.

+

Channels are reference counted to handle dead or stolen Channel handles. See the Channel and Channel Group Handles section of the Mixing and Routing in the Core API chapter for more information.

+

Playing more Sounds or DSPs than physical Channels allow is handled with virtual voices. See the Virtual Voice System section of the Managing Resources in the Core API chapter for more information.

+

See Also: System::createDSP, System::createDSPByType, System::createDSPByPlugin

+

System::playSound

+

Plays a Sound on a Channel.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
FMOD_RESULT System::playSound(
+  Sound *sound,
+  ChannelGroup *channelgroup,
+  bool paused,
+  Channel **channel
+);
+
+ +
FMOD_RESULT FMOD_System_PlaySound(
+  FMOD_SYSTEM *system,
+  FMOD_SOUND *sound,
+  FMOD_CHANNELGROUP *channelgroup,
+  FMOD_BOOL paused,
+  FMOD_CHANNEL **channel
+);
+
+ +
RESULT System.playSound(
+  Sound sound,
+  ChannelGroup channelgroup,
+  bool paused,
+  out Channel channel
+);
+
+ +
System.playSound(
+  sound,
+  channelgroup,
+  paused,
+  channel
+);
+
+ +
+
sound
+
Sound to play. (Sound)
+
channelgroup Opt
+
Group to output to instead of the master. (ChannelGroup)
+
paused
+
+

Whether to start in the paused state. Start a Channel paused to allow altering attributes without it being audible, then follow it up with a call to ChannelControl::setPaused with paused = False.

+
    +
  • Units: Boolean
  • +
+
+
channel OptOut
+
Newly playing Channel. (Channel)
+
+

When a sound is played, it will use the sound's default frequency and priority. See Sound::setDefaults.

+

A sound defined as FMOD_3D will by default play at the 3D position of the listener. To set the 3D position of the Channel before the sound is audible, start the Channel paused by setting the paused parameter to true, and call ChannelControl::set3DAttributes.

+

Specifying a channelgroup as part of playSound is more efficient than using Channel::setChannelGroup after playSound, and could avoid audible glitches if the playSound is not in a paused state.

+

Channels are reference counted to handle dead or stolen Channel handles. For more information, see the Channel and Channel Group Handles section of the Mixing and Routing in the Core API chapter.

+

Playing more Sounds than physical Channels allow is handled with virtual voices. See the Virtual Voice System section of the Managing Resources in the Core API chapter for more information.

+

See Also: System::createSound, System::createStream

+

System::recordStart

+

Starts the recording engine recording to a pre-created Sound object.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
FMOD_RESULT System::recordStart(
+  int id,
+  Sound *sound,
+  bool loop
+);
+
+ +
FMOD_RESULT FMOD_System_RecordStart(
+  FMOD_SYSTEM *system,
+  int id,
+  FMOD_SOUND *sound,
+  FMOD_BOOL loop
+);
+
+ +
RESULT System.recordStart(
+  int id,
+  Sound sound,
+  bool loop
+);
+
+ +
System.recordStart(
+  id,
+  sound,
+  loop
+);
+
+ +
+
id
+
+

Index of the recording device.

+ +
+
sound
+
User created sound for the user to record to. (Sound)
+
loop
+
+

Flag to tell the recording engine whether to continue recording to the provided sound from the start again, after it has reached the end. If this is set to true the data will be continually be overwritten once every loop.

+
    +
  • Units: Boolean
  • +
+
+
+

Will return FMOD_ERR_RECORD_DISCONNECTED if the driver is unplugged.

+

Sound must be created as FMOD_CREATESAMPLE. Raw PCM data can be accessed with Sound::lock, Sound::unlock and System::getRecordPosition.

+

Recording from the same driver a second time will stop the first recording.

+

For lowest latency set the FMOD::Sound sample rate to the rate returned by System::getRecordDriverInfo, otherwise a resampler will be allocated to handle the difference in frequencies, which adds latency.

+

See Also: System::recordStop

+

System::recordStop

+

Stops the recording engine from recording to a pre-created Sound object.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
FMOD_RESULT System::recordStop(
+  int id
+);
+
+ +
FMOD_RESULT FMOD_System_RecordStop(
+  FMOD_SYSTEM *system,
+  int id
+);
+
+ +
RESULT System.recordStop(
+  int id
+);
+
+ +
System.recordStop(
+  id
+);
+
+ +
+
id
+
+

Index of the recording device.

+ +
+
+

Returns no error if unplugged or already stopped.

+

See Also: System::recordStart

+

System::registerCodec

+

Register a Codec plug-in description structure for later use.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
FMOD_RESULT System::registerCodec(
+  FMOD_CODEC_DESCRIPTION *description,
+  unsigned int *handle,
+  unsigned int priority = 0
+);
+
+ +
FMOD_RESULT FMOD_System_RegisterCodec(
+  FMOD_SYSTEM *system,
+  FMOD_CODEC_DESCRIPTION *description,
+  unsigned int *handle,
+  unsigned int priority
+);
+
+ +
System.registerCodec(
+  description,
+  handle,
+  priority
+);
+
+ +
+

Currently not supported for C#.

+
+
+
description
+
Structure describing the Codec to register. (FMOD_CODEC_DESCRIPTION)
+
handle Out
+
Handle used to represent the plug-in.
+
priority Opt
+
Codec load priority where 0 represents most important and higher numbers represent less importance.
+
+

To create an instances of this plug-in use System::createSound and System::createStream.

+

When opening a file each Codec tests whether it can support the file format in priority order. The priority for each FMOD_SOUND_TYPE are as follows:

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
FMOD_SOUND_TYPEPriority
FMOD_SOUND_TYPE_FSB250
FMOD_SOUND_TYPE_XMA250
FMOD_SOUND_TYPE_AT9250
FMOD_SOUND_TYPE_VORBIS250
FMOD_SOUND_TYPE_OPUS250
FMOD_SOUND_TYPE_FADPCM250
FMOD_SOUND_TYPE_WAV600
FMOD_SOUND_TYPE_OGGVORBIS800
FMOD_SOUND_TYPE_AIFF1000
FMOD_SOUND_TYPE_FLAC1100
FMOD_SOUND_TYPE_MOD1200
FMOD_SOUND_TYPE_S3M1300
FMOD_SOUND_TYPE_XM1400
FMOD_SOUND_TYPE_IT1500
FMOD_SOUND_TYPE_MIDI1600
FMOD_SOUND_TYPE_DLS1700
FMOD_SOUND_TYPE_ASF1900
FMOD_SOUND_TYPE_AUDIOQUEUE2200
FMOD_SOUND_TYPE_MEDIACODEC2250
FMOD_SOUND_TYPE_MPEG2400
FMOD_SOUND_TYPE_PLAYLIST2450
FMOD_SOUND_TYPE_RAW2500
FMOD_SOUND_TYPE_USER2600
FMOD_SOUND_TYPE_MEDIA_FOUNDATION2600
+

XMA, AT9, Vorbis, Opus and FADPCM are supported through the FSB format, and therefore have the same priority as FSB.

+

Media Foundation is supported through the User codec, and therefore has the same priority as User.

+

Raw and User are only accesible if FMOD_OPENRAW or FMOD_OPENUSER is specified as the mode in System::createSound.

+

System::registerDSP

+

Register a DSP plug-in description structure for later use.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
FMOD_RESULT System::registerDSP(
+  const FMOD_DSP_DESCRIPTION *description,
+  unsigned int *handle
+);
+
+ +
FMOD_RESULT FMOD_System_RegisterDSP(
+  FMOD_SYSTEM *system,
+  const FMOD_DSP_DESCRIPTION *description,
+  unsigned int *handle
+);
+
+ +
RESULT System.registerDSP(
+  ref DSP_DESCRIPTION description,
+  out uint handle
+);
+
+ +
System.registerDSP(
+  description,
+  handle
+);
+
+ +
+
description
+
Structure describing the DSP to register. (FMOD_DSP_DESCRIPTION)
+
handle Out
+
Handle used to represent the plug-in.
+
+

To create an instance of this plug-in, use System::createDSPByPlugin.

+

System::registerOutput

+

Register an Output plug-in description structure for later use.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
FMOD_RESULT System::registerOutput(
+  const FMOD_OUTPUT_DESCRIPTION *description,
+  unsigned int *handle
+);
+
+ +
FMOD_RESULT FMOD_System_RegisterOutput(
+  FMOD_SYSTEM *system,
+  const FMOD_OUTPUT_DESCRIPTION *description,
+  unsigned int *handle
+);
+
+ +
System.registerOutput(
+  description,
+  handle
+);
+
+ +
+

Not supported for C#.

+
+
+
description
+
Structure describing the Output to register. (FMOD_OUTPUT_DESCRIPTION)
+
handle Out
+
Handle used to represent the plug-in.
+
+

To select this plug-in for output use, use System::setOutputByPlugin.

+

System::release

+

Closes and frees this object and its resources.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
FMOD_RESULT System::release();
+
+ +
FMOD_RESULT FMOD_System_Release(FMOD_SYSTEM *system);
+
+ +
RESULT System.release();
+
+ +
System.release();
+
+ +

This will internally call System::close, so calling System::close before this function is not necessary.

+
+

Calls to System_Create and System::release are not thread-safe. Do not call these functions simultaneously from multiple threads at once.

+
+

See Also: System::init

+

System::set3DListenerAttributes

+

Sets the position, velocity and orientation of the specified 3D sound listener.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
FMOD_RESULT System::set3DListenerAttributes(
+  int listener,
+  const FMOD_VECTOR *pos,
+  const FMOD_VECTOR *vel,
+  const FMOD_VECTOR *forward,
+  const FMOD_VECTOR *up
+);
+
+ +
FMOD_RESULT FMOD_System_Set3DListenerAttributes(
+  FMOD_SYSTEM *system,
+  int listener,
+  const FMOD_VECTOR *pos,
+  const FMOD_VECTOR *vel,
+  const FMOD_VECTOR *forward,
+  const FMOD_VECTOR *up
+);
+
+ +
RESULT System.set3DListenerAttributes(
+  int listener,
+  ref VECTOR pos,
+  ref VECTOR vel,
+  ref VECTOR forward,
+  ref VECTOR up
+);
+
+ +
System.set3DListenerAttributes(
+  listener,
+  pos,
+  vel,
+  forward,
+  up
+);
+
+ +
+
listener
+
+

Index of listener to set 3D attributes on. Listeners are indexed from 0, to FMOD_MAX_LISTENERS - 1, in a multi-listener environment.

+ +
+
pos Opt
+
+

Position in 3D world space used for panning and attenuation. (FMOD_VECTOR)

+ +
+
vel Opt
+
+

Velocity in 3D space used for doppler. (FMOD_VECTOR)

+ +
+
forward Opt
+
Forwards orientation. (FMOD_VECTOR)
+
up Opt
+
Upwards orientation. (FMOD_VECTOR)
+
+

The forward and up vectors must be perpendicular and be of unit length (magnitude of each vector should be 1).

+

Vectors must be provided in the correct handedness.

+

For velocity, remember to use units per second, and not units per frame. This is a common mistake and will make the doppler effect sound wrong if velocity is based on movement per frame rather than a fixed time period.
+If velocity per frame is calculated, it can be converted to velocity per second by dividing it by the time taken between frames as a fraction of a second.
+i.e.

+
velocity_units_per_second = (position_currentframe - position_lastframe) / time_taken_since_last_frame_in_seconds.
+
+

At 60fps the formula would look like velocity_units_per_second = (position_currentframe - position_lastframe) / 0.0166667.

+

Users of the Studio API should call Studio::System::setListenerAttributes instead of this function.

+

See Also: System::get3DListenerAttributes, System::set3DSettings, System::get3DSettings

+

System::set3DNumListeners

+

Sets the number of 3D 'listeners' in the 3D sound scene.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
FMOD_RESULT System::set3DNumListeners(
+  int numlisteners
+);
+
+ +
FMOD_RESULT FMOD_System_Set3DNumListeners(
+  FMOD_SYSTEM *system,
+  int numlisteners
+);
+
+ +
RESULT System.set3DNumListeners(
+  int numlisteners
+);
+
+ +
System.set3DNumListeners(
+  numlisteners
+);
+
+ +
+
numlisteners Out
+
+

Number of listeners in the scene.

+ +
+
+

This function is useful mainly for split-screen game purposes.

+

If the number of listeners is set to more than 1, then panning and doppler are turned off. All sound effects will be mono. FMOD uses a 'closest sound to the listener' method to determine what should be heard in this case.

+

Users of the Studio API should call Studio::System::setNumListeners instead of this function.

+

See Also: System::get3DNumListeners, System::set3DListenerAttributes

+

System::set3DRolloffCallback

+

Sets a callback to allow custom calculation of distance attenuation.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
FMOD_RESULT System::set3DRolloffCallback(
+  FMOD_3D_ROLLOFF_CALLBACK callback
+);
+
+ +
FMOD_RESULT FMOD_System_Set3DRolloffCallback(
+  FMOD_SYSTEM *system,
+  FMOD_3D_ROLLOFF_CALLBACK callback
+);
+
+ +
RESULT System.set3DRolloffCallback(
+  CB_3D_ROLLOFFCALLBACK callback
+);
+
+ +
+

Not supported for JavaScript.

+
+
+
callback
+
Custom callback. Set to 0 or null to return control of distance attenuation to FMOD. (FMOD_3D_ROLLOFF_CALLBACK)
+
+

This function overrides FMOD_3D_INVERSEROLLOFF, FMOD_3D_LINEARROLLOFF, FMOD_3D_LINEARSQUAREROLLOFF, FMOD_3D_INVERSETAPEREDROLLOFF and FMOD_3D_CUSTOMROLLOFF.

+

See Also: Callback Behavior

+

System::set3DSettings

+

Sets the global doppler scale, distance factor and log roll-off scale for all 3D sound in FMOD.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
FMOD_RESULT System::set3DSettings(
+  float dopplerscale,
+  float distancefactor,
+  float rolloffscale
+);
+
+ +
FMOD_RESULT FMOD_System_Set3DSettings(
+  FMOD_SYSTEM *system,
+  float dopplerscale,
+  float distancefactor,
+  float rolloffscale
+);
+
+ +
RESULT System.set3DSettings(
+  float dopplerscale,
+  float distancefactor,
+  float rolloffscale
+);
+
+ +
System.set3DSettings(
+  dopplerscale,
+  distancefactor,
+  rolloffscale
+);
+
+ +
+
dopplerscale
+
+

A scaling factor for doppler shift.

+
    +
  • Default: 1
  • +
+
+
distancefactor
+
+

A factor for converting game distance units to FMOD distance units.

+
    +
  • Default: 1
  • +
+
+
rolloffscale
+
+

A scaling factor for distance attenuation. When a sound uses a roll-off mode other than FMOD_3D_CUSTOMROLLOFF and the distance is greater than the sound's minimum distance, the distance is scaled by the roll-off scale.

+
    +
  • Default: 1
  • +
+
+
+

The dopplerscale is a general scaling factor for how much the pitch varies due to doppler shifting in 3D sound. Doppler is the pitch bending effect when a sound comes towards the listener or moves away from it, much like the effect you hear when a train goes past you with its horn sounding. With "dopplerscale" you can exaggerate or diminish the effect. FMOD's effective speed of sound at a doppler factor of 1.0 is 340 m/s.

+

The distancefactor is the FMOD 3D engine relative distance factor, compared to 1.0 meters. Another way to put it is that it equates to "how many units per meter does your engine have". For example, if you are using feet then "scale" would equal 3.28.
+This only affects doppler. If you keep your min/max distance, custom roll-off curves, and positions in scale relative to each other, the volume roll-off will not change. If you set this, the mindistance of a sound will automatically set itself to this value when it is created in case the user forgets to set the mindistance to match the new distancefactor.

+

The rolloffscale is a global factor applied to the roll-off of sounds using roll-off modes other than FMOD_3D_CUSTOMROLLOFF. When a sound uses a roll-off mode other than FMOD_3D_CUSTOMROLLOFF and the distance is greater than the sound's minimum distance, the distance for the purposes of distance attenuation is calculated according to the formula distance = (distance - minDistance) * rolloffscale + minDistance.

+

See Also: System::get3DSettings, Sound::set3DMinMaxDistance, Sound::get3DMinMaxDistance, ChannelControl::set3DAttributes

+

System::setAdvancedSettings

+

Sets advanced settings for the system object, typically to allow adjusting of settings related to resource usage or audio quality.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
FMOD_RESULT System::setAdvancedSettings(
+  FMOD_ADVANCEDSETTINGS *settings
+);
+
+ +
FMOD_RESULT FMOD_System_SetAdvancedSettings(
+  FMOD_SYSTEM *system,
+  FMOD_ADVANCEDSETTINGS *settings
+);
+
+ +
RESULT System.setAdvancedSettings(
+  ref ADVANCEDSETTINGS settings
+);
+
+ +
System.setAdvancedSettings(
+  settings
+);
+
+ +
+
settings
+
Advanced settings (FMOD_ADVANCEDSETTINGS)
+
+

To use, clear the FMOD_ADVANCEDSETTINGS structure to zeroes first, then set the cbSize member to the size in bytes of the FMOD_ADVANCEDSETTINGS structure. From here settings can be set one at a time, as all defaults are null or 0 for all members.

+

See Also: System::getAdvancedSettings

+

System::setCallback

+

Sets the callback for System level notifications.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
FMOD_RESULT System::setCallback(
+  FMOD_SYSTEM_CALLBACK callback,
+  FMOD_SYSTEM_CALLBACK_TYPE callbackmask = FMOD_SYSTEM_CALLBACK_ALL
+);
+
+ +
FMOD_RESULT FMOD_System_SetCallback(
+  FMOD_SYSTEM *system,
+  FMOD_SYSTEM_CALLBACK callback,
+  FMOD_SYSTEM_CALLBACK_TYPE callbackmask
+);
+
+ +
RESULT System.setCallback(
+  SYSTEM_CALLBACK callback,
+  SYSTEM_CALLBACK_TYPE callbackmask = SYSTEM_CALLBACK_TYPE.ALL
+);
+
+ +
System.setCallback(
+  callback,
+  callbackmask
+);
+
+ +
+
callback
+
Callback to invoke when system notification happens. (FMOD_SYSTEM_CALLBACK)
+
callbackmask
+
Bitfield specifying which callback types are required, to filter out unwanted callbacks. (FMOD_SYSTEM_CALLBACK_TYPE)
+
+

System callbacks can be called by a variety of FMOD threads, so make sure any code executed inside the callback is thread safe.

+

See Also: Callback Behavior

+

System::setDriver

+

Sets the output driver for the selected output type.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
FMOD_RESULT System::setDriver(
+  int driver
+);
+
+ +
FMOD_RESULT FMOD_System_SetDriver(
+  FMOD_SYSTEM *system,
+  int driver
+);
+
+ +
RESULT System.setDriver(
+  int driver
+);
+
+ +
System.setDriver(
+  driver
+);
+
+ +
+
driver
+
+

Driver index where 0 represents the default for the output type.

+ +
+
+

When an output type has more than one driver available, this function can be used to select between them.

+

If this function is called after System::init, the current driver will be shutdown and the newly selected driver will be initialized / started.

+

See Also: System::getDriver, System::getDriverInfo, System::setOutput

+

System::setDSPBufferSize

+

Sets the buffer size for the FMOD software mixing engine.

+

This function is used if you need to control mixer latency or granularity. Smaller buffersizes lead to smaller latency, but can lead to stuttering/skipping/unstable sound on slower machines or soundcards with bad drivers.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
FMOD_RESULT System::setDSPBufferSize(
+  unsigned int bufferlength,
+  int numbuffers
+);
+
+ +
FMOD_RESULT FMOD_System_SetDSPBufferSize(
+  FMOD_SYSTEM *system,
+  unsigned int bufferlength,
+  int numbuffers
+);
+
+ +
RESULT System.setDSPBufferSize(
+  uint bufferlength,
+  int numbuffers
+);
+
+ +
System.setDSPBufferSize(
+  bufferlength,
+  numbuffers
+);
+
+ +
+
bufferlength
+
+

The mixer engine block size. Use this to adjust mixer update granularity. See below for more information on buffer length vs latency.

+
    +
  • Units: Samples
  • +
  • Default: 1024
  • +
+
+
numbuffers
+
+

The mixer engine number of buffers used. Use this to adjust mixer latency. See below for more information on number of buffers vs latency.

+
    +
  • Default: 4
  • +
+
+
+

To get the bufferlength in milliseconds, divide it by the output rate and multiply the result by 1000. For a bufferlength of 1024 and an output rate of 48khz (see System::SetSoftwareFormat), milliseconds = 1024 / 48000 * 1000 = 21.33ms. This means the mixer updates every 21.33ms.

+

To get the total buffer size multiply the bufferlength by the numbuffers value. By default this would be 4 * 1024 = 4096 samples, or 4 * 21.33ms = 85.33ms. This would generally be the total latency of the software mixer, but in reality due to one of the buffers being written to constantly, and the cursor position of the buffer that is audible, the latency is typically more like the (number of buffers - 1.5) multiplied by the buffer length.

+

To convert from milliseconds back to 'samples', simply multiply the value in milliseconds by the sample rate of the output (ie 48000 if that is what it is set to), then divide by 1000.

+

The FMOD software mixer mixes to a ring buffer. The size of this ring buffer is determined here. It mixes a block of sound data every 'bufferlength' number of samples, and there are 'numbuffers' number of these blocks that make up the entire ring buffer. Adjusting these values can lead to extremely low latency performance (smaller values), or greater stability in sound output (larger values).

+

Warning! The 'buffersize' is generally best left alone. Making the granularity smaller will just increase CPU usage (cache misses and DSP graph overhead). Making it larger affects how often you hear commands update such as volume/pitch/pan changes. Anything above 20ms will be noticeable and sound parameter changes will be obvious instead of smooth.

+

FMOD chooses the most optimal size by default for best stability, depending on the output type. It is not recommended changing this value unless you really need to. You may get worse performance than the default settings chosen by FMOD. If you do set the size manually, the bufferlength argument must be a multiple of four, typically 256, 480, 512, 1024 or 2048 depending on your latency requirements.

+

The values in milliseconds and average latency expected from the settings can be calculated using the following code:

+
FMOD_RESULT result;
+unsigned int blocksize;
+int numblocks;
+float ms;
+
+result = system->getDSPBufferSize(&blocksize, &numblocks);
+result = system->getSoftwareFormat(&frequency, 0, 0);
+
+ms = (float)blocksize * 1000.0f / (float)frequency;
+
+printf("Mixer blocksize        = %.02f ms\n", ms);
+printf("Mixer Total buffersize = %.02f ms\n", ms * numblocks);
+printf("Mixer Average Latency  = %.02f ms\n", ms * ((float)numblocks - 1.5f));
+
+ + +

See Also: System::getDSPBufferSize, System::getSoftwareFormat, System::init, System::close

+

System::setFileSystem

+

Set callbacks to implement all file I/O instead of using the platform native method.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
FMOD_RESULT System::setFileSystem(
+  FMOD_FILE_OPEN_CALLBACK useropen,
+  FMOD_FILE_CLOSE_CALLBACK userclose,
+  FMOD_FILE_READ_CALLBACK userread,
+  FMOD_FILE_SEEK_CALLBACK userseek,
+  FMOD_FILE_ASYNCREAD_CALLBACK userasyncread,
+  FMOD_FILE_ASYNCCANCEL_CALLBACK userasynccancel,
+  int blockalign
+);
+
+ +
FMOD_RESULT FMOD_System_SetFileSystem(
+  FMOD_SYSTEM *system,
+  FMOD_FILE_OPEN_CALLBACK useropen,
+  FMOD_FILE_CLOSE_CALLBACK userclose,
+  FMOD_FILE_READ_CALLBACK userread,
+  FMOD_FILE_SEEK_CALLBACK userseek,
+  FMOD_FILE_ASYNCREAD_CALLBACK userasyncread,
+  FMOD_FILE_ASYNCCANCEL_CALLBACK userasynccancel,
+  int blockalign
+);
+
+ +
RESULT System.setFileSystem(
+  FILE_OPENCALLBACK useropen,
+  FILE_CLOSECALLBACK userclose,
+  FILE_READCALLBACK userread,
+  FILE_SEEKCALLBACK userseek,
+  FILE_ASYNCREADCALLBACK userasyncread,
+  FILE_ASYNCCANCELCALLBACK userasynccancel,
+  int blockalign
+);
+
+ +
System.setFileSystem(
+  useropen,
+  userclose,
+  userread,
+  userseek,
+  userasyncread,
+  userasynccancel,
+  blockalign
+);
+
+ +
+
useropen Opt
+
Callback for opening a file. (FMOD_FILE_OPEN_CALLBACK)
+
userclose Opt
+
Callback for closing a file. (FMOD_FILE_CLOSE_CALLBACK)
+
userread Opt
+
Callback for reading from a file, instead of userasyncread and userasynccancel. (FMOD_FILE_READ_CALLBACK)
+
userseek Opt
+
Callback for seeking within a file, instead of userasyncread and userasynccancel. (FMOD_FILE_SEEK_CALLBACK)
+
userasyncread Opt
+
Callback for reading and seeking asynchronously, instead of userread and userseek. (FMOD_FILE_ASYNCREAD_CALLBACK)
+
userasynccancel Opt
+
Callback for cancelling a previous userasyncread call. (FMOD_FILE_ASYNCCANCEL_CALLBACK)
+
blockalign Opt
+
+

File buffering chunk size, specify -1 to keep system default or previously set value. 0 = disable buffering, see notes below for more on this.

+
    +
  • Default: 2048
  • +
  • Units: Bytes
  • +
+
+
+

Setting these callbacks have no effect on sounds loaded with FMOD_OPENMEMORY or FMOD_OPENUSER.

+

There are three valid configurations for this function:

+
    +
  1. Set useropen, userclose, userread, userseek and optionally blockalign for blocking file I/O.
  2. +
  3. Set useropen, userclose, userasyncread, userasynccancel and optionally blockalign for asynchronous file I/O.
  4. +
  5. Set blockalign by itself with everything else null, to change platform native file I/O buffering.
  6. +
+

Setting blockalign to 0 will disable file buffering and cause every read to invoke the relevant callback (not recommended), current default is tuned for memory usage vs performance. Be mindful of the I/O capabilities of the platform before increasing this default.

+

Asynchronous file access via userasyncread / userasynccanel.

+
    +
  • We recommended consulting the 'asyncio' example for reference implementation. For more information, see the Asynchronous I/O and Deferred Fire Reading section of the Loading and Playing Sounds in the Core API chapter.
  • +
  • userasyncread allows the user to return immediately before the data is ready. FMOD will either wait internally (see note below about thread safety), or continuously check in the streamer until data arrives. It is the user's responsibility to provide data in time in the stream case, or the stream may stutter. Data starvation can be detected with Sound::getOpenState.
  • +
  • Important: If userasyncread is processed in the main thread, then it will hang the application, because FMOD will wait internally until data is ready, and the main thread will not be able to supply the data. For this reason the user's file access should normally be from a separate thread.
  • +
  • A userasynccancel must either service or prevent an async read issued previously via userasyncread before returning.
  • +
+

Implementation tips to avoid hangs / crashes.

+
    +
  • All Callbacks must be thread safe.
  • +
  • FMOD_ERR_FILE_EOF must be returned if the number of bytes read is smaller than requested.
  • +
+
+

userasyncread and userasynccancel are not supported for JavaScript.

+
+

See Also: Callback Behavior, System::attachFileSystem

+

System::setGeometrySettings

+

Sets the maximum world size for the geometry engine for performance / precision reasons.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
FMOD_RESULT System::setGeometrySettings(
+  float maxworldsize
+);
+
+ +
FMOD_RESULT FMOD_System_SetGeometrySettings(
+  FMOD_SYSTEM *system,
+  float maxworldsize
+);
+
+ +
RESULT System.setGeometrySettings(
+  float maxworldsize
+);
+
+ +
System.setGeometrySettings(
+  maxworldsize
+);
+
+ +
+
maxworldsize
+
Maximum size of the world from the centerpoint to the edge using the same units used in other 3D functions.
+
+

FMOD uses an efficient spatial partitioning system to store polygons for ray casting purposes.
+The maximum size of the world should (maxworldsize) be set to allow processing within a known range.
+Outside of this range, objects and polygons will not be processed as efficiently.
+Excessive world size settings can also cause loss of precision and efficiency.

+

Setting maxworldsize should be done first before creating any geometry. It can be done any time afterwards but may be slow in this case.

+

See Also: System::createGeometry, System::getGeometrySettings, System::set3DSettings

+

System::setNetworkProxy

+

Set a proxy server to use for all subsequent internet connections.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
FMOD_RESULT System::setNetworkProxy(
+  const char *proxy
+);
+
+ +
FMOD_RESULT FMOD_System_SetNetworkProxy(
+  FMOD_SYSTEM *system,
+  const char *proxy
+);
+
+ +
RESULT System.setNetworkProxy(
+  string proxy
+);
+
+ +
System.setNetworkProxy(
+  proxy
+);
+
+ +
+
proxy
+
Proxy server URL. (UTF-8 string)
+
+

Specify the proxy in host:port format e.g. www.fmod.com:8888 (defaults to port 80 if no port is specified).

+

Basic authentication is supported using user:password@host:port format e.g. bob:sekrit123@www.fmod.com:8888

+

See Also: System::getNetworkProxy

+

System::setNetworkTimeout

+

Set the timeout for network streams.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
FMOD_RESULT System::setNetworkTimeout(
+  int timeout
+);
+
+ +
FMOD_RESULT FMOD_System_SetNetworkTimeout(
+  FMOD_SYSTEM *system,
+  int timeout
+);
+
+ +
RESULT System.setNetworkTimeout(
+  int timeout
+);
+
+ +
System.setNetworkTimeout(
+  timeout
+);
+
+ +
+
timeout
+
+

Timeout value.

+
    +
  • Units: Milliseconds
  • +
  • Default: 5000
  • +
+
+
+

See Also: System::getNetworkTimeout

+

System::setOutput

+

Sets the type of output interface used to run the mixer.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
FMOD_RESULT System::setOutput(
+  FMOD_OUTPUTTYPE output
+);
+
+ +
FMOD_RESULT FMOD_System_SetOutput(
+  FMOD_SYSTEM *system,
+  FMOD_OUTPUTTYPE output
+);
+
+ +
RESULT System.setOutput(
+  OUTPUTTYPE output
+);
+
+ +
System.setOutput(
+  output
+);
+
+ +
+
output
+
Output type. (FMOD_OUTPUTTYPE)
+
+

This function is typically used to select between different OS specific audio APIs which may have different features.

+

It is only necessary to call this function if you want to specifically switch away from the default output mode for the operating system. The most optimal mode is selected by default for the operating system.

+

(Windows, UWP, GameCore, Android, MacOS, iOS, Linux Only) This function can be called after System::init to perform special handling of driver disconnections, see FMOD_SYSTEM_CALLBACK_DEVICELISTCHANGED.

+

When using the Studio API, switching to an NRT (non-realtime) output type after FMOD is already initialized will not behave correctly unless the Studio API was initialized with FMOD_STUDIO_INIT_SYNCHRONOUS_UPDATE.

+

See Also: System::getOutput

+

System::setOutputByPlugin

+

Selects an output type given a plug-in handle.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
FMOD_RESULT System::setOutputByPlugin(
+  unsigned int handle
+);
+
+ +
FMOD_RESULT FMOD_System_SetOutputByPlugin(
+  FMOD_SYSTEM *system,
+  unsigned int handle
+);
+
+ +
RESULT System.setOutputByPlugin(
+  uint handle
+);
+
+ +
System.setOutputByPlugin(
+  handle
+);
+
+ +
+
handle
+
Handle to an already loaded output plug-in.
+
+

(Windows Only) This function can be called after FMOD is already initialized. You can use it to change the output mode at runtime. If FMOD_SYSTEM_CALLBACK_DEVICELISTCHANGED is specified use the setOutput call to change to FMOD_OUTPUTTYPE_NOSOUND if no more sound card drivers exist.

+

See Also: System::getNumPlugins, System::getOutputByPlugin, System::setOutput

+

System::setPluginPath

+

Specify a base search path for plug-ins so they can be placed somewhere else than the directory of the main executable.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
FMOD_RESULT System::setPluginPath(
+  const char *path
+);
+
+ +
FMOD_RESULT FMOD_System_SetPluginPath(
+  FMOD_SYSTEM *system,
+  const char *path
+);
+
+ +
RESULT System.setPluginPath(
+  string path
+);
+
+ +
System.setPluginPath(
+  path
+);
+
+ +
+
path
+
A character string containing a correctly formatted path to load plug-ins from. (UTF-8 string)
+
+

See Also: System::loadPlugin

+

System::setReverbProperties

+

Sets parameters for the global reverb environment.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
FMOD_RESULT System::setReverbProperties(
+  int instance,
+  const FMOD_REVERB_PROPERTIES *prop
+);
+
+ +
FMOD_RESULT FMOD_System_SetReverbProperties(
+  FMOD_SYSTEM *system,
+  int instance,
+  const FMOD_REVERB_PROPERTIES *prop
+);
+
+ +
RESULT System.setReverbProperties(
+  int instance,
+  ref REVERB_PROPERTIES prop
+);
+
+ +
System.setReverbProperties(
+  instance,
+  prop
+);
+
+ +
+
instance
+
+

Index of the particular reverb instance to target.

+ +
+
prop
+
Reverb environment description. Passing 0 or NULL to this function will delete the reverb. (FMOD_REVERB_PROPERTIES)
+
+

To assist in defining reverb properties there are several presets available, see FMOD_REVERB_PRESETS

+

When using each instance for the first time, FMOD will create an SFX reverb DSP unit that takes up several hundred kilobytes of memory and some CPU.

+

See Also: System::getReverbProperties, ChannelControl::setReverbProperties, ChannelControl::getReverbProperties, Effects Reference: SFX Reverb

+

System::setSoftwareChannels

+

Sets the maximum number of software mixed Channels possible.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
FMOD_RESULT System::setSoftwareChannels(
+  int numsoftwarechannels
+);
+
+ +
FMOD_RESULT FMOD_System_SetSoftwareChannels(
+  FMOD_SYSTEM *system,
+  int numsoftwarechannels
+);
+
+ +
RESULT System.setSoftwareChannels(
+  int numsoftwarechannels
+);
+
+ +
System.setSoftwareChannels(
+  numsoftwarechannels
+);
+
+ +
+
numsoftwarechannels
+
+

The maximum number of real Channels to be allocated by FMOD.

+
    +
  • Default: 64
  • +
+
+
+

This function cannot be called after FMOD is already activated, it must be called before System::init, or after System::close.
+'Software Channels' refers to real Channels that will play, with numsoftwarechannels refering to the maximum number of Channels before successive Channels start becoming virtual. For differences between real and virtual Channels see the Virtual Voice System section of the Managing Resources in the Core API chapter.

+

See Also: System::getSoftwareChannels, System::init, System::close

+

System::setSoftwareFormat

+

Sets the output format for the software mixer.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
FMOD_RESULT System::setSoftwareFormat(
+  int samplerate,
+  FMOD_SPEAKERMODE speakermode,
+  int numrawspeakers
+);
+
+ +
FMOD_RESULT FMOD_System_SetSoftwareFormat(
+  FMOD_SYSTEM *system,
+  int samplerate,
+  FMOD_SPEAKERMODE speakermode,
+  int numrawspeakers
+);
+
+ +
RESULT System.setSoftwareFormat(
+  int samplerate,
+  SPEAKERMODE speakermode,
+  int numrawspeakers
+);
+
+ +
System.setSoftwareFormat(
+  samplerate,
+  speakermode,
+  numrawspeakers
+);
+
+ +
+
samplerate Opt
+
+

Sample rate of the mixer.

+
    +
  • Range: [8000, 192000]
  • +
  • Units: Hertz
  • +
  • Default: 48000
  • +
+
+
speakermode Opt
+
Speaker setup of the mixer. (FMOD_SPEAKERMODE)
+
numrawspeakers Opt
+
+

Number of speakers for FMOD_SPEAKERMODE_RAW mode.

+ +
+
+

If loading banks made in FMOD Studio, this must be called with speakermode corresponding to the project output format if there is a possibility of the output audio device not matching the project format. Any differences between the project format and speakermode will cause the mix to sound wrong.

+

By default speakermode will assume the setup the OS / output prefers.

+

Altering the samplerate from the OS / output preferred rate may incur extra latency. Altering the speakermode from the OS / output preferred mode may cause an upmix/downmix which can alter the sound.

+

On lower power platforms such as mobile samplerate will default to 24 kHz to reduce CPU cost.

+

This function must be called before System::init, or after System::close.

+

See Also: System::getSoftwareFormat

+

System::setSpeakerPosition

+

Sets the position of the specified speaker for the current speaker mode.

+

This function allows the user to specify the position of their speaker to account for non standard setups.
+It also allows the user to disable speakers from 3D consideration in a game.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
FMOD_RESULT System::setSpeakerPosition(
+  FMOD_SPEAKER speaker,
+  float x,
+  float y,
+  bool active
+);
+
+ +
FMOD_RESULT FMOD_System_SetSpeakerPosition(
+  FMOD_SYSTEM *system,
+  FMOD_SPEAKER speaker,
+  float x,
+  float y,
+  FMOD_BOOL active
+);
+
+ +
RESULT System.setSpeakerPosition(
+  SPEAKER speaker,
+  float x,
+  float y,
+  bool active
+);
+
+ +
System.setSpeakerPosition(
+  speaker,
+  x,
+  y,
+  active
+);
+
+ +
+
speaker
+
Speaker. (FMOD_SPEAKER)
+
x
+
+

2D X position relative to the listener. -1 = left, 0 = middle, +1 = right.

+
    +
  • Range: [-1, 1]
  • +
+
+
y
+
+

2D Y position relative to the listener. -1 = back, 0 = middle, +1 = front.

+
    +
  • Range: [-1, 1]
  • +
+
+
active
+
+

Active state of a speaker. True = included in 3D calculations, False = ignored.

+
    +
  • Units: Boolean
  • +
+
+
+

This allows you to customize the position of the speakers for the current FMOD_SPEAKERMODE by giving X (left to right) and Y (front to back) coordinates.
+When disabling a speaker, 3D spatialization is redistributed around the missing speaker so that signal isn't lost.

+

Stereo setup would look like this:

+
FMOD_System_SetSpeakerPosition(system, FMOD_SPEAKER_FRONT_LEFT, -1.0f,  0.0f, 1);
+FMOD_System_SetSpeakerPosition(system, FMOD_SPEAKER_FRONT_RIGHT, 1.0f,  0.0f, 1);
+
+ +
system->setSpeakerPosition(FMOD_SPEAKER_FRONT_LEFT, -1.0f,  0.0f, true);
+system->setSpeakerPosition(FMOD_SPEAKER_FRONT_RIGHT, 1.0f,  0.0f, true);
+
+ +

7.1 setup would look like this:

+
FMOD_System_SetSpeakerPosition(system, FMOD_SPEAKER_FRONT_LEFT,     sin(degtorad( -30)), cos(degtorad( -30)), 1);
+FMOD_System_SetSpeakerPosition(system, FMOD_SPEAKER_FRONT_RIGHT,    sin(degtorad(  30)), cos(degtorad(  30)), 1);
+FMOD_System_SetSpeakerPosition(system, FMOD_SPEAKER_FRONT_CENTER,   sin(degtorad(   0)), cos(degtorad(   0)), 1);
+FMOD_System_SetSpeakerPosition(system, FMOD_SPEAKER_LOW_FREQUENCY,  sin(degtorad(   0)), cos(degtorad(   0)), 1);
+FMOD_System_SetSpeakerPosition(system, FMOD_SPEAKER_SURROUND_LEFT,  sin(degtorad( -90)), cos(degtorad( -90)), 1);
+FMOD_System_SetSpeakerPosition(system, FMOD_SPEAKER_SURROUND_RIGHT, sin(degtorad(  90)), cos(degtorad(  90)), 1);
+FMOD_System_SetSpeakerPosition(system, FMOD_SPEAKER_BACK_LEFT,      sin(degtorad(-150)), cos(degtorad(-150)), 1);
+FMOD_System_SetSpeakerPosition(system, FMOD_SPEAKER_BACK_RIGHT,     sin(degtorad( 150)), cos(degtorad( 150)), 1);
+
+ +
system->setSpeakerPosition(FMOD_SPEAKER_FRONT_LEFT,     sin(degtorad( -30)), cos(degtorad( -30)), true);
+system->setSpeakerPosition(FMOD_SPEAKER_FRONT_RIGHT,    sin(degtorad(  30)), cos(degtorad(  30)), true);
+system->setSpeakerPosition(FMOD_SPEAKER_FRONT_CENTER,   sin(degtorad(   0)), cos(degtorad(   0)), true);
+system->setSpeakerPosition(FMOD_SPEAKER_LOW_FREQUENCY,  sin(degtorad(   0)), cos(degtorad(   0)), true);
+system->setSpeakerPosition(FMOD_SPEAKER_SURROUND_LEFT,  sin(degtorad( -90)), cos(degtorad( -90)), true);
+system->setSpeakerPosition(FMOD_SPEAKER_SURROUND_RIGHT, sin(degtorad(  90)), cos(degtorad(  90)), true);
+system->setSpeakerPosition(FMOD_SPEAKER_BACK_LEFT,      sin(degtorad(-150)), cos(degtorad(-150)), true);
+system->setSpeakerPosition(FMOD_SPEAKER_BACK_RIGHT,     sin(degtorad( 150)), cos(degtorad( 150)), true);
+
+ +

Calling System::setSoftwareFormat will override any customization made with this function.

+

Users of the Studio API should be aware this function does not affect the speaker positions used by the spatializer DSPs such as the pan and object panner DSPs. It is purely for Core API spatialization via ChannelControl::set3DAttributes.

+

See Also: System::getSpeakerPosition

+

System::setStreamBufferSize

+

Sets the default file buffer size for newly opened streams.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
FMOD_RESULT System::setStreamBufferSize(
+  unsigned int filebuffersize,
+  FMOD_TIMEUNIT filebuffersizetype
+);
+
+ +
FMOD_RESULT FMOD_System_SetStreamBufferSize(
+  FMOD_SYSTEM *system,
+  unsigned int filebuffersize,
+  FMOD_TIMEUNIT filebuffersizetype
+);
+
+ +
RESULT System.setStreamBufferSize(
+  uint filebuffersize,
+  TIMEUNIT filebuffersizetype
+);
+
+ +
System.setStreamBufferSize(
+  filebuffersize,
+  filebuffersizetype
+);
+
+ +
+
filebuffersize
+
+

Buffer size.

+
    +
  • Default: 16384
  • +
+
+
filebuffersizetype
+
+

Type of units for filebuffersize. (FMOD_TIMEUNIT)

+ +
+
+

Valid units for filebuffersizetype are:

+ +

Larger values will consume more memory, whereas smaller values may cause buffer under-run / starvation / stuttering caused by large delays in disk access (ie netstream), or CPU usage in slow machines, or by trying to play too many streams at once.

+

Does not affect streams created with FMOD_OPENUSER, as the buffer size is specified in System::createSound.

+

Does not affect latency of playback. All streams are pre-buffered (unless opened with FMOD_OPENONLY), so they will always start immediately.

+

Seek and Play operations can sometimes cause a reflush of this buffer.

+

If FMOD_TIMEUNIT_RAWBYTES is used, the memory allocated is two times the size passed in, because fmod allocates a double buffer.

+

If FMOD_TIMEUNIT_MS, FMOD_TIMEUNIT_PCM or FMOD_TIMEUNIT_PCMBYTES is used, and the stream is infinite (such as a shoutcast netstream), or VBR, then FMOD cannot calculate an accurate compression ratio to work with when the file is opened. This means it will then base the buffersize on FMOD_TIMEUNIT_PCMBYTES, or in other words the number of PCM bytes, but this will be incorrect for some compressed formats. Use FMOD_TIMEUNIT_RAWBYTES for these type (infinite / undetermined length) of streams for more accurate read sizes.

+

To determine the actual memory usage of a stream, including sound buffer and other overhead, use Memory_GetStats before and after creating a sound.

+

Stream may still stutter if the codec uses a large amount of cpu time, which impacts the smaller, internal 'decode' buffer. The decode buffer size is changeable via FMOD_CREATESOUNDEXINFO.

+

See Also: System::getStreamBufferSize, Sound::getOpenState

+

System::setUserData

+

Sets a user value associated with a System object.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
FMOD_RESULT System::setUserData(
+  void *userdata
+);
+
+ +
FMOD_RESULT FMOD_System_SetUserData(
+  FMOD_SYSTEM *system,
+  void *userdata
+);
+
+ +
RESULT System.setUserData(
+  IntPtr userdata
+);
+
+ +
System.setUserData(
+  userdata
+);
+
+ +
+
userdata
+
User specified data to be stored within the System object.
+
+

This function allows arbitrary user data to be attached to this object, which wll be passed through the userdata parameter in any FMOD_SYSTEM_CALLBACKs. See the User Data section of the glossary for an example of how to get and set user data.

+

See Also: System::getUserData, System::setCallback

+

System::unloadPlugin

+

Unloads an FMOD (DSP, Output or Codec) plug-in.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
FMOD_RESULT System::unloadPlugin(
+  unsigned int handle
+);
+
+ +
FMOD_RESULT FMOD_System_UnloadPlugin(
+  FMOD_SYSTEM *system,
+  unsigned int handle
+);
+
+ +
RESULT System.unloadPlugin(
+  uint handle
+);
+
+ +
System.unloadPlugin(
+  handle
+);
+
+ +
+
handle
+
Handle to an already loaded plug-in.
+
+

See Also: System::loadPlugin

+

System::unlockDSP

+

Mutual exclusion function to unlock the DSP engine (which runs asynchronously in another thread) and let it continue executing.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
FMOD_RESULT System::unlockDSP();
+
+ +
FMOD_RESULT FMOD_System_UnlockDSP(FMOD_SYSTEM *system);
+
+ +
RESULT System.unlockDSP();
+
+ +
System.unlockDSP();
+
+ +

The DSP engine must be locked with System::lockDSP before this function is called.

+

System::update

+

Updates the FMOD system.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
FMOD_RESULT System::update();
+
+ +
FMOD_RESULT FMOD_System_Update(FMOD_SYSTEM *system);
+
+ +
RESULT System.update();
+
+ +
System.update();
+
+ +

Should be called once per 'game' tick, or once per frame in your application to perform actions such as:

+
    +
  • Panning and reverb from 3D attributes changes.
  • +
  • Virtualization of Channels based on their audibility.
  • +
  • Mixing for non-realtime output types. See comment below.
  • +
  • Streaming if using FMOD_INIT_STREAM_FROM_UPDATE.
  • +
  • Mixing if using FMOD_INIT_MIX_FROM_UPDATE
  • +
  • Firing callbacks that are deferred until Update.
  • +
  • DSP cleanup.
  • +
+

If FMOD_OUTPUTTYPE_NOSOUND_NRT or FMOD_OUTPUTTYPE_WAVWRITER_NRT output modes are used, this function also drives the software / DSP engine, instead of it running asynchronously in a thread as is the default behavior.
+This can be used for faster than realtime updates to the decoding or DSP engine which might be useful if the output is the wav writer for example.

+

If FMOD_INIT_STREAM_FROM_UPDATE is used, this function will update the stream engine. Combining this with the non realtime output will mean smoother captured output.

+

See Also: System::init, FMOD_INITFLAGS, FMOD_OUTPUTTYPE, FMOD_MODE

+ + +
+ + + diff --git a/FMOD/doc/FMOD API User Manual/core-api.html b/FMOD/doc/FMOD API User Manual/core-api.html new file mode 100644 index 0000000..60cd0df --- /dev/null +++ b/FMOD/doc/FMOD API User Manual/core-api.html @@ -0,0 +1,59 @@ + + +Core API Reference + + + + + + + + diff --git a/FMOD/doc/FMOD API User Manual/dsp-plugin-api-guide.html b/FMOD/doc/FMOD API User Manual/dsp-plugin-api-guide.html new file mode 100644 index 0000000..d8beda1 --- /dev/null +++ b/FMOD/doc/FMOD API User Manual/dsp-plugin-api-guide.html @@ -0,0 +1,254 @@ + + +Plug-in DSP API Guide + + + + +
+ +
+

18. Plug-in DSP API Guide

+

Game studios and third-party developers can augment FMOD Studio's built-in suite of effects and sound modules by creating their own plug-ins. By placing plug-ins in FMOD Studio's plug-ins folder, these can be added to tracks or buses, modulated and automated by game parameters just like built-in effect and sound modules.

+

This chapter describes how to create plug-ins and make them available to FMOD Studio and your game. We also recommended you follow along with the example plug-ins found in api/core/examples/plugins, as they are fully implemented working effects you can use or base your code on.

+

18.1 Accessing Plug-ins in FMOD Studio

+

A plug-in must be built as a dynamic linked library and placed in the plug-ins folder specified in FMOD Studio's Preferences dialog under the Plug-ins tab. FMOD Studio scans the folder and all sub-folders both on start-up and when the folder is changed by the user. Studio tries to load any libraries it finds (.dll on Windows or .dylib on Mac) and ignores libraries which don't support the API.

+

Detected plug-in instruments will be available via the track context menu in the Event Editor, whereas detected plug-in effects will show up in the effect deck's Add Effect and Insert Effect context menus. When a plug-in module is added to a track or bus, its panel will be displayed in the effect deck. The panel will be automatically populated with dials, buttons and data drop-zones for each parameter.

+

18.2 Basics

+

Two versions of the plug-in will usually be required - one for FMOD Studio and one for the game.

+

Studio will require a dll or dylib file if running in Windows or Mac respectively. These will be loaded dynamically in Studio as described in the previous section.

+

Another version of the plug-in must be compiled for the game's target platform. This may also be a dynamic library but, in most cases, can (or must) be a static library or simply compiled along with the game code. Each target platform requires its own version of the plugin to ensure compatibility and performance. In each case, game code is required to load the plug-in prior to loading the project or object referencing the plug-in.

+

18.2.1 Building a Plug-in

+

The fmod_dsp.h header file includes all the necessary type definitions and constants for creating plug-ins including the struct FMOD_DSP_DESCRIPTION which defines the plug-in's capabilities and callbacks.

+

If creating a dynamic library, the library must export FMODGetDSPDescription, e.g.:

+
extern "C" {
+F_EXPORT FMOD_DSP_DESCRIPTION* F_CALL FMODGetDSPDescription();
+}
+
+ +

The F_EXPORT macro provides the relevant storage class for exporting FMODGetDSPDescription. Some platforms however, such as PS5, cannot automatically provide a definition for this macro. In such cases you will need to manually add a preprocessor definition for F_USE_DECLSPEC, or F_USE_ATTRIBUTE for Linux based platforms, otherwise the built plugin may fail to load.

+

Dynamic libraries must be compiled for the same architecture as the host (whether FMOD Studio or the game), so if the host is 64-bit, the plug-in must be 64-bit.

+

A third-party tool, such as the free Dependencies, can be used to verify that the library is able to be loaded and the proper symbol is exported. In Windows, the symbol will look like _FMODGetDSPDescription@0.

+

If creating a static library, the library should export a symbol with a unique name such as FMOD_YourCompany_YourProduct_GetDSPDescription, e.g.:

+
extern "C" {
+F_EXPORT FMOD_DSP_DESCRIPTION* F_CALL FMOD_YourCompany_YourProduct_GetDSPDescription();
+}
+
+ +

You should then share this extern'd symbol name in a header so developers can register it at runtime with System::registerDSP.

+

18.2.2 Loading the Plug-in in the Game

+

The plug-in must be registered using the FMOD Studio or Core API before the object referencing the plug-in is loaded in the game.

+

The following functions can be used to register a plug-in if it is statically linked or compiled with the game code:

+
FMOD_RESULT FMOD::Studio::System::registerPlugin(const FMOD_DSP_DESCRIPTION* description);
+FMOD_RESULT FMOD::System::registerDSP(const FMOD_DSP_DESCRIPTION *description, unsigned int *handle);
+
+ +

If the plug-in library is to be dynamically loaded, it can be registered using:

+
FMOD_RESULT FMOD::System::loadPlugin(const char *filename, unsigned int *handle, unsigned int priority = 0)
+
+ +

A base plug-in path can be specified using the function:

+
FMOD_RESULT FMOD::System::setPluginPath(const char *path)
+
+ +

If this is set, the filename parameter of System::loadPlugin is assumed to be relative to this path.

+

Plug-ins do not normally need to be unregistered, but it is possible with either of the following functions:

+
FMOD_RESULT FMOD::Studio::System::unregisterPlugin(const char* name)
+FMOD_RESULT FMOD::System::unloadPlugin(unsigned int handle)
+
+ +

In these functions, name refers to the name of the plug-in defined in the plug-ins descriptor and handle refers to handle returned by System::loadPlugin.

+

18.2.3 Plug-in Types

+

There are two main plug-in types:

+
    +
  • Effect Modules
  • +
  • Sound Modules
  • +
+

Both module types are created in the same way - the difference lies in whether the plug-in processes an audio input.

+

Effect modules apply effects to an audio signal. Each effect module has an input and an output. Effect modules can be inserted anywhere in FMOD Studio's signal routing, whether it be on an event's track or a mixer bus. Examples of different types of plug-in effects include:

+
    +
  • Effects which have the same input and output channel counts such as EQ, compression, distortion, etc...
  • +
  • Effects which perform up- or down-mixing as part of the processing algorithm such as panning or reverb
  • +
  • Spatialization and any distance/direction effects which respond to a sound's 3D location in the game such as 3D panning, distance filtering, early reflections or binaural audio
  • +
  • Side-chaining effects such as compression or audio modulation (e.g. ring modulators)
  • +
+

Sound Modules produce their own audio output - they do not have an audio input. Sound modules can be placed on tracks inside Events and can be made to trigger from the timeline, game parameter or within another sound module.

+

18.3 Plug-in UI

+

A default user interface will be automatically created by FMOD Studio, assigning a control for each FMOD_DSP_PARAMETER_DESC exported from your plug-in. The type of UI control assigned to the parameter depends on its FMOD_DSP_PARAMETER_TYPE:

+ + + + + + + + + + + + + + + + + + + + + + + + + +
TypeControl
FMOD_DSP_PARAMETER_TYPE_BOOLButton
FMOD_DSP_PARAMETER_TYPE_FLOATDial
FMOD_DSP_PARAMETER_TYPE_INTDropdown
FMOD_DSP_PARAMETER_TYPE_DATAData Drop
+

The UI presented in FMOD Studio can be customized inside a .plugin.js using the Plug-In Scripting API. Example .plugin.js files can be found in the "plugins" folder within the FMOD Studio installation directory.

+

18.4 The Plug-in Descriptor

+

The plug-in descriptor is a struct, FMOD_DSP_DESCRIPTION defined in fmod_dsp.h, which describes the capabilities of the plug-in and contains function pointers for all callbacks needed to communicate with FMOD. Data in the descriptor cannot change once the plug-in is loaded. The original struct and its data must stay around until the plug-in is unloaded as data inside this struct is referenced directly within FMOD throughout the lifetime of the plug-in.

+

The first member, FMOD_DSP_DESCRIPTION::pluginsdkversion, must always hold the version number of the plug-in SDK it was complied with. This version is defined as FMOD_PLUGIN_SDK_VERSION. The SDK version is incremented whenever changes to the API occur.

+

The following two members, FMOD_DSP_DESCRIPTION::name and FMOD_DSP_DESCRIPTION::version, identify the plug-in. Each plug-in must have a unique name, usually the company name followed by the product name. Version numbers should not be included in the name in order to allow for future migration of saved data across different versions. Names should not change across versions for the same reason. The version number should be incremented whenever any changes to the plug-in have been made.

+

Here is a code snippet from the FMOD Gain example which shows how to initialize the first five members of FMOD_DSP_DESCRIPTION:

+
FMOD_DSP_DESCRIPTION FMOD_Gain_Desc =
+{
+    FMOD_PLUGIN_SDK_VERSION,
+    "FMOD Gain",    // name
+    0x00010000,     // plug-in version
+    1,              // number of input buffers to process
+    1,              // number of output buffers to process
+    ...
+};
+
+ +

The other descriptor members will be discussed in the following sections.

+

18.5 Thread Safety

+

Audio callbacks FMOD_DSP_DESCRIPTION::read, FMOD_DSP_DESCRIPTION::process and FMOD_DSP_DESCRIPTION::shouldiprocess are executed in FMOD's mixer thread whereas all other callbacks are executed in the host's thread (game or Studio UI). It is therefore important to ensure thread safety across parameters and states which are shared between those two types of callbacks.

+

In the FMOD Gain example, two gains are stored: target gain and current gain. target gain stores the parameter value which is set and queried from the host thread. This value is then assigned to current gain at the start of the audio processing callback and it is current gain that is then applied to the signal. FMOD Gain shows how this method can be used to perform parameter ramping by not directly assigning current gain but interpolating between current gain and target gain over a fixed number of samples so as to minimize audio artefacts during parameter changes.

+

18.6 Plug-in Parameters

+

Plug-in effect and sound modules can have any number of parameters. Once defined, the number of parameters and each of their properties cannot change. Parameters can be one of four types:

+
    +
  • floating-point
  • +
  • integer
  • +
  • boolean (two-state)
  • +
  • data
  • +
+

Parameters are defined in FMOD_DSP_DESCRIPTION as a list of pointers to parameter descriptors, FMOD_DSP_DESCRIPTION::paramdesc. The FMOD_DSP_DESCRIPTION::numparameters specifies the number of parameters. Each parameter descriptor is of type FMOD_DSP_PARAMETER_DESC. As with the plug-in descriptor, parameter descriptors must stay around until the plug-in is unloaded as the data within these descriptors are directly accessed throughout the lifetime of the plug-in.

+

Common to each parameter type are the members FMOD_DSP_PARAMETER_DESC::name and units, as well as FMOD_DSP_PARAMETER_DESC::description which should describe the parameter in a sentence or two. The type member will need to be set to one of the four types and either of the FMOD_DSP_PARAMETER_DESC::floatdesc, FMOD_DSP_PARAMETER_DESC::intdesc, FMOD_DSP_PARAMETER_DESC::booldesc or FMOD_DSP_PARAMETER_DESC::datadesc members will need to specified. The different parameter types and their properties are described in more detail in the sections below.

+

18.6.1 Floating-point Parameters

+

Floating-point parameters have type set to FMOD_DSP_PARAMETER_TYPE_FLOAT. They are continuous, singled-valued parameters and their minimum, maximum and default values are defined by the floatdesc members min, max and defaultval.

+

The following units should be used where appropriate:

+
    +
  • "Hz" for frequency or cut-off
  • +
  • "ms" for duration, time offset or delay
  • +
  • "st" (semitones) for pitch
  • +
  • "dB" for gain, threshold or feedback
  • +
  • "%" for mix, depth, feedback, quality, probability, multiplier or generic 'amount'.
  • +
  • "Deg" for angle or angular spread
  • +
+

These are preferred over other denominations (such as kHz for cut-off) as they are recognised by Studio therefore allowing values to be displayed in a more readable and consistent manner. Unitless 0-to-1 parameters should be avoided in favour of dB if the parameter describes a gain, % if it describes a multiplier, or a unitless 0-to-10 range is preferred if describing a generic amount.

+

The FMOD_DSP_DESCRIPTION members FMOD_DSP_DESCRIPTION::setparameterfloat and FMOD_DSP_DESCRIPTION::getparameterfloat will need to point to static functions of type FMOD_DSP_SETPARAM_FLOAT_CALLBACK and FMOD_DSP_GETPARAM_FLOAT_CALLBACK, respectively, if any floating-point parameters are declared.

+

These will be displayed as dials in FMOD Studio's effect deck.

+

18.6.2 Integer Parameters

+

Integer parameters have type set to FMOD_DSP_PARAMETER_TYPE_INT. They are discrete, singled-valued parameters and their minimum, maximum and default values are defined by the intdesc members min, max and defaultval. The member goestoinf describes whether the maximum value represents infinity as maybe used for parameters representing polyphony, count or ratio.

+

The FMOD_DSP_DESCRIPTION members FMOD_DSP_DESCRIPTION::setparameterint and FMOD_DSP_DESCRIPTION::getparameterint will need to point to static functions of type FMOD_DSP_SETPARAM_INT_CALLBACK and FMOD_DSP_GETPARAM_INT_CALLBACK, respectively, if any integer parameters are declared.

+

These will be displayed as dials in FMOD Studio's effect deck.

+

18.6.3 Boolean Parameters

+

Boolean parameters have type set to FMOD_DSP_PARAMETER_TYPE_BOOL. They are discrete, singled-valued parameters and their default value is defined by the booldesc member defaultval.

+

The FMOD_DSP_DESCRIPTION members FMOD_DSP_DESCRIPTION::setparameterbool and FMOD_DSP_DESCRIPTION::getparameterbool will need to point to static functions of type FMOD_DSP_SETPARAM_BOOL_CALLBACK and FMOD_DSP_GETPARAM_BOOL_CALLBACK, respectively, if any boolean parameters are declared.

+

These will be displayed as buttons in FMOD Studio's effect deck.

+

18.6.4 Data Parameters

+

Data parameters have type set to FMOD_DSP_PARAMETER_TYPE_DATA. These parameters can represent any type of data including built-in types which serve a special purpose in FMOD. The datadesc member datatype specifies the type of data stored in the parameter. Values 0 and above may be used to describe user types whereas negative values are reserved for special types described in the following sections.

+

The FMOD_DSP_DESCRIPTION members FMOD_DSP_DESCRIPTION::setparameterdata and FMOD_DSP_DESCRIPTION::getparameterdata will need to point to static functions of type FMOD_DSP_SETPARAM_DATA_CALLBACK and FMOD_DSP_GETPARAM_DATA_CALLBACK, respectively, if any data parameters with datatype 0 and above are declared.

+

Data parameters with datatype 0 and above will be displayed as drop-zones in FMOD Studio's effect deck. You can drag any file containing the data onto the drop-zone to set the parameter's value. Data is stored with the project just like other parameter types.

+

18.7 Multiple Plug-ins Within One File

+

Typically each plug-in only has a single definition. If you want to have multiple definitions from within the one plugin file, you can use a plugin list. An example is shown below.

+
FMOD_DSP_DESCRIPTION My_Gain_Desc = { .. };
+FMOD_DSP_DESCRIPTION My_Panner_Desc = { .. };
+FMOD_OUTPUT_DESCRIPTION My_Output_Desc = { .. };
+
+static FMOD_PLUGINLIST My_Plugin_List[] =
+{
+    { FMOD_PLUGINTYPE_DSP, &My_Gain_Desc },
+    { FMOD_PLUGINTYPE_DSP, &My_Panner_Desc },
+    { FMOD_PLUGINTYPE_OUTPUT, &My_Output_Desc },
+    { FMOD_PLUGINTYPE_MAX, NULL }
+};
+
+extern "C"
+{
+
+F_EXPORT FMOD_PLUGINLIST* F_CALL FMODGetPluginDescriptionList()
+{
+    return &My_Plugin_List;
+}
+
+} // end extern "C"
+
+ +

Support for multiple plug-ins via FMODGetPluginDescriptionList was added in 1.08. If the plug-in also implements FMODGetDSPDescription, then older versions of the FMOD Engine load a single DSP effect, whereas newer versions load all effects.

+

To load plug-ins at runtime, call System::loadPlugin as normal. The handle returned is for the first definition. System::getNumNestedPlugins and System::getNestedPlugin can be used to iterate all plug-ins in the one file.

+
unsigned int baseHandle;
+ERRCHECK(system->loadPlugin("plugin_name.dll", &baseHandle));
+int count;
+ERRCHECK(system->getNumNestedPlugins(baseHandle, &count));
+for (int index=0; index<count; ++index)
+{
+    unsigned int handle;
+    ERRCHECK(system->getNestedPlugin(baseHandle, index, &handle));        
+    FMOD_PLUGINTYPE type;
+    ERRCHECK(system->getPluginInfo(handle, &type, 0, 0, 0));
+    // We have an output plug-in, a DSP plug-in, or a codec plug-in here.
+}
+
+ +

The above code also works for plug-ins with a single definition. In that case, the count is always 1 and System::getNestedPlugin returns the same handle as passed in.

+ + +
+ + + diff --git a/FMOD/doc/FMOD API User Manual/effects-reference.html b/FMOD/doc/FMOD API User Manual/effects-reference.html new file mode 100644 index 0000000..4ace5f1 --- /dev/null +++ b/FMOD/doc/FMOD API User Manual/effects-reference.html @@ -0,0 +1,1102 @@ + + +Core API Effect Reference + + + + +
+
+

FMOD Engine User Manual 2.03

+ +
+
+

8. Core API Effect Reference

+

This chapter describes the suite of DSP effects built in to the FMOD Engine, as well as their purposes, performance characteristics, and implementation details.

+

8.1 Current Effects

+

This section contains high level descriptions of currently supported built in effects.

+

Effects are categorized in each description for performance as:

+
    +
  • low overhead - Can be used freely without much CPU impact.
  • +
  • medium overhead - Use carefully with a medium CPU impact.
  • +
  • high overhead - Use sparingly with a higher CPU impact.
  • +
+

These categories are only broad guidelines, however, and cannot account for every project's unique requirements and resource budget. For a more accurate measurement of the performance impact of the effects in your project, use the FMOD Studio profiler or Core API profiler tool.

+

8.1.1 Channel Mix

+

The channel mix effect allows you to group, manipulate and route the individual channels of the signal.

+

Larger channel count multi-channel audio formats benefit the most from this effect, as mono and stereo signals are usually easily manipulated with a simple pan or volume setting. With larger multi-channel audio formats, the channels in the signal can be routed to any speaker that is required, and each volume level of each channel can be individually set.

+

Example: 8 stereo streams being interleaved into a single 16 channel stream. Normally FMOD would not know how to pan this type of signal. The grouping feature would let you describe it as 'all stereo' to allow the signal to pan correctly as 8 pairs of stereo signals. There are a variety of grouping modes to choose from.

+

The channel mix effect provides the following features:

+
    +
  • Per Channel Gain (up to 32 channels). For each channel in a signal, each input gain level can be individually.
    +Per channel gain
    +In this example, gain levels have been set on a 5.1 signal. Setting gain for a channel applies to all samples in the signal.
  • +
  • Output Channel Grouping. A multi-channel input signal can be described to play as a group of lower channel count speaker formats. By default, the channel mix effect passes the input channel format to the output without changing it.
    +Per channel gain
    +In this example, a multi-channel input signal is being described as multiple stereo signals out using the 'All Stereo' setting.
  • +
  • Input to output channel routing. The output speaker for each input channel of a signal can be set individually. By default, the routing for each input channels maps directly to the output equivalent.
    +Input to output channel routing
    +In this example, a multi-channel input signal has its 6 channels of audio routed to custom speakers on the output.
  • +
+

The channel mix effect is controllable by the parameters:

+
    +
  • Per channel gain - This has a range of -80 dB to +10 dB with a default of 0 dB. This can be set using the FMOD_DSP_CHANNELMIX_GAIN_CH0 through to FMOD_DSP_CHANNELMIX_GAIN_CH31 parameters.
  • +
  • Output channel grouping - This is configurable via group modes such as 'all lfe', 'all mono', 'all stereo', and in-between speaker modes up to 'all 7.4.1', with a default of speaker mode in = speaker mode out. This can be set using the FMOD_DSP_CHANNELMIX_OUTPUT parameter.
  • +
  • Per channel speaker mapping - This allows for each input channel to specify an output speaker number for complex routing flexibility. Channel mapping for each channel can be set using the FMOD_DSP_CHANNELMIX_OUTPUT_CH0 through to FMOD_DSP_CHANNELMIX_OUTPUT_CH31 parameters.
  • +
+

See Also: FMOD_DSP_TYPE_CHANNELMIX

+

Performance

+

Channel mix is a low overhead effect.

+

To avoid the bandwidth overhead of many streams playing at once, many streams can be interleaved into one using an external tool. The resulting file can then be streamed as a single sound, and the grouping feature can describe the sound as many lower channel count sounds.

+
+

8.1.2 Chorus

+

The chorus effect is often used in music, generated by interference of the source signal with delayed copies of the original that modulate their delay offsets over time. The effect works best on sounds which are sustaining in nature, and has a full / shimmering characteristic.

+

The chorus effect is characterized by a single delay line per channel of the signal, where each delay line oscillates its time offset in a sinusoidal manner, at a rate and range specified by the user.

+

Input to output channel routing
+A signal (black) having a copy (grey) added to itself, at a delay that oscillates back and forth in time with a speed of chorus rate, to a maximum delay of chorus depth. The original and copy of itself are gain balanced so that the signal does not get louder.

+

In multi-channel signals each subsequent channel has its delay incremented by 90 degrees in the sinusoidal cycle, and wrapping around back to a 90 degree offset each time. i.e.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Speaker Configuration
StereoL = 90degR = 180deg
Surround 5.1FL = 90degFR = 180degC = 270degLFE = 90degSL = 180degSR = 270deg
+

The chorus effect is controllable by the parameters:

+
    +
  • Depth - Delay used to achieve the effect. Has a range of 0 to 100ms with a default of 3 ms. Set with the FMOD_DSP_CHORUS_DEPTH parameter.
  • +
  • Rate - Speed of oscillation. Has a range of 0 to 20 Hz with a default of 0.8 Hz. Set with the FMOD_DSP_CHORUS_RATE parameter.
  • +
  • Mix - Percentage of effect applied to the input signal. The mix is a scale between the wet and the dry signal per channel, so that the loudness of the output stays consistent. Has a range of 0 to 100% with a default of 50%. Set with the FMOD_DSP_CHORUS_MIX parameter.
  • +
+

See Also: FMOD_DSP_TYPE_CHORUS

+

Performance

+

Chorus is a medium overhead effect.

+

Chorus is a comb filter which means it uses extra memory to buffer audio.

+
+

8.1.3 Compressor

+

The compressor effect reduces the volume of loud sounds above a certain threshold, reducing or compressing an audio signal's dynamic range.

+

The compressor reacts to the signal exceeding the 'threshold', which is a dB setting set by the user. If the signal exceeds this threshold a gain envelope is applied to the signal to reduce the signal by an amount specified as the 'ratio'.

+

The ratio is the fraction of the input level that is above the threshold, that the signal is reduced to in dB. If a ratio is set to 2, for every 2 dB above the threshold, the compressor only allows 1 dB above the threshold through. If a ratio is set to 4, for every 4 dB above the threshold, the compressor only allows 1 dB above the threshold through. The higher the ratio, the more audible and agressive it will be while a low ratio will provide gentler compression.

+

The reduction is controlled by a timed envelope which modifies the gain. The envelope has an attack and release period. The start of the attack happens when the threshold is exceeded. This can be set in milliseconds. Once the input signal level is below the threshold, the release stage starts will return the gain back to the starting value.

+

Compressor
+A signal suddenly exceeding the threshold is aggressively gain reduced with a high ratio. Attack and release states of an envelope control the timing of the reduction and the return to the original level after the signal drops back below the threshold.*

+

Characteristics of the compressor effect:

+
    +
  • Uniform across the whole spectrum, so all frequencies are affected equally.
  • +
  • Analysis of the input signal to compare against threshold is 'peak sensing' and not 'RMS sensing'.
  • +
  • Envelope transitions are 'hard knee' which is the shape of the envelope when the attack and release phase start and stop.
  • +
  • Linked and unlinked multi-channel side chain input is supported. If the channel count of the side chain is different to the input signal, it will be forced into linked mode.
  • +
+

The compressor effect is controllable by the parameters:

+
    +
  • Threshold - The threshold level has a range of -80 dB to 0 dB and has a default of 0 dB. Set with FMOD_DSP_COMPRESSOR_THRESHOLD.
  • +
  • Ratio - The ratio has a range of 1 to 50 and has a default of 2.5. The higher the ratio the more aggressive the compression. Set with FMOD_DSP_COMPRESSOR_RATIO.
  • +
  • Linked mode - Multi-channel, so each individual channel reacts independently of each other. Linked Mode is also available which mixes all channels into a mono signal before processing. Set with FMOD_DSP_COMPRESSOR_LINKED.
  • +
  • Side chain - Side chaining is available to allow an outside signal to control the level rather than the incoming signal. Set with FMOD_DSP_COMPRESSOR_USESIDECHAIN. To connect a side chain to the compressor, the DSP API is used to add another DSP using DSP::addInput and FMOD_DSPCONNECTION_TYPE_SIDECHAIN.
  • +
  • Attack speed - Attack speed of the gain envelope is available, having a range of 0.1 ms to 1000 ms with a default of 20 ms. Set with FMOD_DSP_COMPRESSOR_ATTACK.
  • +
  • Release speed - Release speed of the gain envelope is available, having a range of 10 ms to 5000 ms with a default of 100 ms. Set with FMOD_DSP_COMPRESSOR_RELEASE.
  • +
  • Gain make-up - Gain make-up allows a constant gain to be applied at the output having a range of 0 dB to 30dB, with a default of 0 dB. Set with FMOD_DSP_COMPRESSOR_GAINMAKEUP.
  • +
+
+

In a real-time audio engine, the compressor is not guaranteed to catch every peak above the threshold level, because it cannot apply gain reduction instantaneously. The time delay is determined by the attack time. However setting the attack time too short will distort the sound, so it is a compromise. High level peaks can be avoided by using a short attack time - but not too short, and setting the threshold a few decibels below the critical level.

+
+

See Also: FMOD_DSP_TYPE_COMPRESSOR

+

Performance

+

Compressor is a medium overhead effect.

+
+

8.1.4 Convolution Reverb

+

The convolution reverb effect is used to simulate an environment by processing audio with a recording of a real world location (the 'impulse response'), in order to reproduce the reverberation characteristics of that environment.

+

Convolution reverb differs to FMOD's SFX Reverb, in that it is not controlled by a set of parameters, but instead is set by an impulse response file, which has been previously recorded and supplied to the effect.

+

This has the advantage of reproducing a space's reverberation characteristics very faithfully, but has the disadvantage of not being flexible. The convolution reverb environment cannot be easily morphed into a different environment, compared to the SFX Reverb effect which can set different tuning parameters to get the desired result in real time. A workaround for this might be to have more than one convolution reverb running and cross fade between them, but it will use more CPU power to do so.

+

Convolution reverb is a relatively expensive effect, due to it being processed in the frequency domain which includes costly spectral to time domain conversions and vice versa, as well as the process of convolving the input signal with the impulse response in real-time.

+

The convolution effect is controllable by the parameters:

+ +

The output channel count of the DSP is the channel count of the impulse response source.

+

For Impulse response data, you can purchase/download professionally recorded space data and feed it straight into the FMOD convolution reverb effect, or you can make your own.

+

Creating Impulse Response Data

+

Impulse response
+A typical impulse starts with an exciter, such as a burst of noise, and then the resulting sound contains the reverberation of the exciter from the surrounding environment.

+

To make your own requires recording an 'impulse' (a burst of white noise or a longer sine wave sweep sound) in the space. The idea is to record the resulting reverberation from the surroundings. An impulse needs both power and full spectrum to capture the room’s full response. An ideal impulse cannot exist in reality, so an approximation is used, for example the popping of a balloon or a shot from a starter pistol.

+

The next step after recording is to deconvolve the recording to produce an impulse response. Third-party tools exist for this. When saving a response for a 3D real-time environment, it is best to use a monophonic (1 channel) impulse, as you do not want directionality baked into the impulse itself. FMOD's 3D engine positions sounds in 3D and pans them in any speakers, and because of the nature of reverb any directionality is generally lost in the real world.

+

See Also: FMOD_DSP_TYPE_CONVOLUTIONREVERB

+

Performance

+

Convolution reverb is a high overhead effect.

+

Although it is a high overhead effect in nature, FMOD's convolution engine has been highly optimized to use platform specific vector processing, as well as multiple CPU threads to reduce impact on the main DSP mixing thread.

+

To save CPU time and memory, the shorter an impulse response is, the faster it will be. Longer impulses use larger amounts of CPU time.

+
+

8.1.5 Delay

+

The delay effect is used to delay individual channels of a signal. It is simpler than an echo, and is used to manipulate the timing of multi-channel signals with greater control.

+

The delay effect is achieved by storing the signal for each channel then playing it back after periods of time specified by the user.

+

Delay
+A stereo signal having its left and right channel delayed into the mix with different delay lengths.

+

The delay effect is controllable by the parameters:

+
    +
  • Per channel delay. Each channel can have its own delay, up to 16 channels, with a range of 0 to 10 seconds and a default of 0. Set with the FMOD_DSP_DELAY_CH0 to FMOD_DSP_DELAY_CH15 parameters.
  • +
  • Maximum delay. Because delay requires buffering of audio signals, a maximum delay can be set to control memory usage. Per channel delay must be smaller or equal to this value. Set with FMOD_DSP_DELAY_MAXDELAY parameter.
  • +
+

See Also: FMOD_DSP_TYPE_DELAY

+

Performance

+

Delay is a low overhead effect.

+

Delay is a stores a history which means it uses more memory due to the buffering of audio signals. Control maximum delay lengths with FMOD_DSP_DELAY_MAXDELAY.

+
+

8.1.6 Distortion

+

The distortion effect is used to alter the shape of a signal to make it 'noisier'. Among other things, distortion may be used to simulate low quality equipment or a low quality communications channel.

+

The effect is achieved by amplifying then clipping the signal at levels controlled by the user. The loudness characteristic of the distortion is not levelled, and may need an additional fader to compensate for the increased loudness.

+

Distortion
+A signal being distorted with some compensation afterwards to bring the loudness of the output into line with the input.

+

The distortion effect is controllable by the parameters:

+
    +
  • Distortion level - The amount of distortion is controlled by with one parameter with a range between 0 (none) and 1 (full) and a default of 0.5. Set with FMOD_DSP_DISTORTION_LEVEL.
  • +
+

See Also: FMOD_DSP_TYPE_DISTORTION

+

Performance

+

Distortion is a low overhead effect.

+
+

8.1.7 Echo

+

The echo effect simulates the reflection of a sound that arrives with a delay after the initial sound is heard. With feedback, it can then continue to be heard at a diminished volume level until the sound fully attenuates. This effect is a cheaper, simple way to simulate an environment and its early / harsher reflections than a full reverb effect.

+

Echo is achieved by mixing the incoming signal into an echo buffer at an offset determined by the delay time, and then mixing that buffer back into the original input signal with a volume level determined by the feedback.

+

Distortion
+A short sound playing (black) and its delayed copy playing back, then continuing to feed itself back in with the same delay each time, but with diminished power.

+

The echo effect is controllable by the parameters:

+
    +
  • Delay - The time taken to hear an echo of the original signal is specified with the 'delay' parameter, which ranges between 10ms and 5000ms and has a default of 500ms. Set with FMOD_DSP_ECHO_DELAY.
  • +
  • Feedback - The amount of the signal fed back into the echo buffer after the initial delay is specified with the 'feedback' parameter, which is defined as a percentage between 0% and 100%, with a default of 50%. Set with FMOD_DSP_ECHO_FEEDBACK.
  • +
  • Wet Mix and Dry Mix - Wet and dry mix of the echo effect can be set separately, which both have a range of -80 dB to +10 dB and a default of 0 dB. Set with FMOD_DSP_ECHO_DRYLEVEL and FMOD_DSP_ECHO_WETLEVEL.
  • +
  • Delay Change Mode - The method used to smooth delay changes. Ramp will fade-in the new delay value and fade-out the old delay value. Lerp will use linear interpolation to approach the new delay target. None will disable value smoothing between delay changes. Set with FMOD_DSP_ECHO_DELAYCHANGEMODE.
  • +
+

The outgoing channel count of the echo effect is always be the same as the number coming in.
+Due to the initial delay tap having no attenuation, simulating attenuation from the first tap onwards can be done by scaling the whole effect with the FMOD_DSP_ECHO_WETLEVEL parameter.

+

See Also: FMOD_DSP_TYPE_ECHO

+

Performance

+

Echo is a medium overhead effect.

+

Echo is a comb filter which means it uses extra memory to buffer audio.

+
+

8.1.8 Fader

+

The fader effect is used to scale the volume of a signal. Its DSP is used commonly, both by Channels and ChannelGroups as their main source of volume control and by FMOD Studio's gain effect.

+

The fader effect is controllable by the parameters:

+
    +
  • Gain - The fader can attenuate the signal, potentially even to silence, or amplify it. This gain value has a range of -80 dB to +10 dB with a default of 0 dB. Set with FMOD_DSP_FADER_GAIN.
  • +
  • Overall gain - The fader can be used as a source of information to query the overall attenuation of the signal. Get with FMOD_DSP_FADER_OVERALL_GAIN.
  • +
+

See Also: FMOD_DSP_TYPE_FADER

+

Performance

+

Fader is a low overhead effect.

+
+

8.1.9 FFT

+

The FFT (Fast Fourier Transform) effect analyzes the signal and provides information about its frequency spectrum. This can be used to provide information about the dominant pitch of a sound (for pitch detection), or for display or measurement of the power of different parts of the spectrum at the same time.

+

The FFT DSP is a process that converts a time domain signal to a frequency domain representation in real time.

+

FFT
+A sine wave playing at 20hz in the time domain (top) and a spectrum representation (bottom) of the same wave after an FFT has processed it.

+

The FFT effect is controllable by the parameters:

+
    +
  • Block Size - The FFT analyzes the signal in blocks of samples. The block size is a power of 2 between 128 and 16384, with a default setting of 2048. The size has a trade-off of accuracy vs cpu expense and latency. Smaller blocks are more efficient and have lower latency, but have less results, so are coarser in their accuracy. Larger blocks are less efficient and have higher latency, but have more data and are better in their accuracy. Set with FMOD_DSP_FFT_WINDOWSIZE.
  • +
  • Windowing - Each time a block is processed, the FFT must taper the start and end to avoid unwanted spectral leakage or transient signals interfering with the analysis. This is done by applying a window to the data before processing it. The default window type is the 'Hamming' type. Set with FMOD_DSP_FFT_WINDOW.
  • +
  • Analysis band - The effect calculates RMS and spectral centroid values for frequencies within the analysis band. Set with FMOD_DSP_FFT_BAND_START_FREQ and FMOD_DSP_FFT_BAND_STOP_FREQ.
  • +
  • Multichannel signals - The effect can analyze all channels of the signal independently, just analyze a single channel, or downmix to a single channel before analysis. Set with FMOD_DSP_FFT_DOWNMIX and FMOD_DSP_FFT_CHANNEL.
  • +
  • Spectrum data - The spectrum data can be retrieved as an array of signal power values, one for each frequency interval. Get with FMOD_DSP_FFT_SPECTRUMDATA.
  • +
  • RMS - This is a single representative value, calculated as the sum of the signal power values within the analysis band. Get with FMOD_DSP_FFT_RMS.
  • +
  • Spectral centroid - This is a single representative value, calculated as a weighted average of the frequency components within the analysis band. Useful for simple pitch detection. Get with FMOD_DSP_FFT_SPECTRAL_CENTROID.
  • +
  • Immediate mode - Use this to control how the data is processed. When set to true, data requests will have no delay on first time use, and no hardware acceleration will be used. When set to false, data requests will have a delay on first time use and hardware acceleration, if available, will be used. Set with FMOD_DSP_FFT_IMMEDIATE_MODE.
  • +
+

Cyclic signals such as a sine wave that repeat their cycle in a multiple of the window size do not need windowing. I.e. If the sine wave repeats every 1024, 512, 256 etc samples and the FMOD FFT window is 1024, then the signal would not need windowing. Not windowing is represented by FMOD_DSP_FFT_WINDOW_RECT.

+

For more natural sounds, and more complex sounds, different window shapes can be used which are supported by this effect. See FMOD_DSP_FFT_WINDOW_TYPE for a list of window types and examples of their shapes.

+

See Also: FMOD_DSP_TYPE_FFT

+

Performance

+

FFT is a high overhead effect.

+
+

8.1.10 Flange

+

The flange effect is generated by interference of the signal with a single delayed copy of that signal that slowly modulates its delay offset over time. This produces a wooshing, sweeping effect. Typically used in music, it can also be used to create an otherworldly repetitive effect for atmosphere.

+

In this effect a copy of the incoming signal is delayed and mixed back in at a varying offset that cycles on a sinusoidal shape. The delay has a maximum depth of 10ms. As there are 2 versions of the same signal, by default each signal is given 50% mix, so that the total loudness is generally not louder than the original signal.

+

Flange
+A sound being fed in (black) and the gain reduced version (grey) being added to a copy (grey) at a delay that changes over time, according to a sinusoidal shape. The delay has an adjustable rate and depth.

+

The flange effect is controllable by the parameters:

+
    +
  • Depth - This can be set between 0.01 and 1, with a default of 1. A value of 1 represents around 10 ms shift from the original signal. Anything above 10ms is not considered flange because to the ear it begins to 'echo' so 10ms is the highest value possible. Set with FMOD_DSP_FLANGE_DEPTH.
  • +
  • Rate - Flange rate is measured in Hz and has a range of 0 to 20 Hz, with a default of 0.1 Hz. Set with FMOD_DSP_FLANGE_RATE.
  • +
  • Mix - Flange balance is the mix between the original signal and the delayed copy, with a range of 0% to 100%, with a default to 50%. Set with FMOD_DSP_FLANGE_MIX.
  • +
+

See Also: FMOD_DSP_TYPE_FLANGE

+

Performance

+

Flange is a medium overhead effect.

+

Flange is a comb filter which means it uses extra memory to buffer audio.

+
+

8.1.11 Haptics

+

Haptics is an instrument for synthesizing device vibrations from a haptic file created in Meta Haptics Studio.

+

The Haptics effect is controllable by the parameters:

+
    +
  • Clip - A haptic clip created in Meta Haptics Studio. Set with FMOD_HAPTICS_CLIP.
  • +
  • Intensity left - The output strength of the synthesized vibration on the left device or motor. Set with FMOD_HAPTICS_INTENSITY_LEFT.
  • +
  • Intensity right - The output strength of the synthesized vibration on the right device or motor. Set with FMOD_HAPTICS_INTENSITY_RIGHT.
  • +
+

Haptics support is available in simple vs advanced varieties. Simple haptics provide basic vibration by changing only the strength (amplitude) of a motor, resulting in a general “rumble†sensation that is not very detailed. Advanced haptics use both amplitude and frequency to drive more precise actuators, allowing vibrations to feel sharper, smoother, or more textured. This enables more expressive and localized feedback, such as simulating surfaces, impacts, or subtle motion.

+

Controllers with advanced support:

+
    +
  • PS5
  • +
  • Quest 3
  • +
+

Controllers with simple support:

+
    +
  • PS4
  • +
  • Xbox Series X/S
  • +
  • Xbox One
  • +
  • Switch 1/2
  • +
+

Performance

+

Haptics is a low overhead effect.

+
+

8.1.12 IT Echo

+

The IT echo effect is a variation of the original echo effect, which simulates the reflection of a sound that arrives with a delay after the initial sound is heard. With feedback it can then continue to be heard at a diminished volume level until the sound fully attenuates.

+

This version of echo is stereo only, but has a variable delay per channel, and allows bouncing the echo from left to right speakers and vice versa. It was originally introduced to support the type of echo used in .IT music files.

+

This echo variation originated to support .IT music files. The effect emulates in software, the Microsoft Direct X echo which is the employed by the Mod Plug Tracker program.

+

The IT echo effect is controllable by the parameters:

+
    +
  • Left / right delay - As this is a stereo filter made intended for .IT playback, it is targeted for stereo signals. With mono signals only the left delay is used. For multi-channel signals (>2) there is no echo on the extra channels. Set with FMOD_DSP_ITECHO_LEFTDELAY and FMOD_DSP_ITECHO_RIGHTDELAY.
  • +
  • Pan Delay - Panning of the stereo delays can be set to ping-pong left and right with each successive echo. Set with FMOD_DSP_ITECHO_PANDELAY.
  • +
  • Feedback level - Amount of output signal that is passed back in as an input signal in successive updates. Set with FMOD_DSP_ITECHO_FEEDBACK
  • +
  • Wet / Dry mix - Percentage of input signal vs processed signal that is sent to output. By default the percentage is set to 50 for an even mix, with 0 being no effect passed to output, with 100 being no original dry signal passed to the output. Set with FMOD_DSP_ITECHO_WETDRYMIX
  • +
+

See Also: FMOD_DSP_TYPE_ITECHO

+
+

This echo does not have interpolation between changes in delay, which means every time the delay is changed the echo buffer is cleared and a period of silence will occur.

+
+

Performance

+

IT Echo is a medium overhead effect.

+

Echo is a comb filter which means it uses extra memory to buffer audio.

+
+

8.1.13 IT Low Pass

+

The IT low pass effect is used to attenuate or remove high frequencies in a signal, controlled with a cutoff frequency that is specified by the user. The resonance attribute or 'Q' value of the filter can also be specified, to affect the gain of the signal at the cutoff frequency, to further alter the characteristics of the sound.

+

This low pass variation originated to support .IT music files. The effect emulates low pass filter effect employed by the Impulse Tracker program.

+

Characteristics of the IT low pass effect:

+
    +
  • This is different to the default Low Pass, Multi Band Equalizer or Low Pass Simple effects in that it uses a different quality algorithm and is the filter used to produce the correct sounding playback in .IT files.
  • +
  • This filter actually has a limited cutoff frequency below the specified maximum, due to its limited design (8060hz), so for a more open range filter use Low Pass, Multi Band Equalizer or for a filter with no resonance control, Low Pass Simple.
  • +
+

The IT low pass effect is controllable by the parameters:

+
    +
  • Cutoff frequency - The frequency for the low pass filter ranges between 1 Hz and 22 kHz with a default of 5 kHz. Set with FMOD_DSP_ITLOWPASS_CUTOFF.
  • +
  • Resonance - The low pass resonance or Q value is a linear value that ranges between 0 and 127 with a default of 1. Set with FMOD_DSP_ITLOWPASS_RESONANCE.
  • +
+

See Also: FMOD_DSP_TYPE_ITLOWPASS

+

Performance

+

IT low pass is a low overhead effect.

+
+

8.1.14 Limiter

+

The limiter effect prevents the signal from exceeding a certain amplitude. Originally limiters were used to quickly avoid audio from overworking electronics and damaging them. Now they are used to control dynamics and avoid noisy clipping.

+

Limiter in action
+When the input signal exceeds a threshold (the ceiling), it immediately reduces the gain to avoid clipping or excessive loudness. When the input signal returns to a level underneath the ceiling, the gain is not immediately returned to normal, it is ramped back with a release envelope.

+

The Limiter effect is controllable by the parameters:

+
    +
  • Ceiling - The FMOD limiter is a hard limiter, which detects peaks and immediately limits them by scaling the whole signal to stay within the ceiling. The ceiling has a range of -12 dB to 0 dB and has a default of 0 dB. Set with FMOD_DSP_LIMITER_CEILING.
  • +
  • When peaks drop below the desired ceiling setting, the scale applied downwards to the signal is gradually reduced or released over the time specified in the release. The release time has a range of 1 ms to 1000 ms with a default of 10ms. Set with FMOD_DSP_LIMITER_RELEASETIME.
  • +
  • Linked mode - The processing mode for the effect can be 'linked' which means all channels in a signal are summed together and treated as mono first (no per channel processing), or 'unlinked' which is the default and is individual processing per channel. The default setting is unlinked. Set with FMOD_DSP_LIMITER_MODE.
  • +
  • Maximizer gain - The input signal can have a gain applied to it which is overridden by the ceiling, making the signal louder but reducing dynamic range. The maximizer gain has a range of 0 dB to +12 dB with a default of 0 dB. Set with FMOD_DSP_LIMITER_MAXIMIZERGAIN.
  • +
+

See Also: FMOD_DSP_TYPE_LIMITER

+

Performance

+

Limiter is a low overhead effect.

+
+

8.1.15 Loudness Meter

+

The Loudness Meter effect analyzes the loudness and true peak of the signal.

+

The Loudness Meter effect is controllable by the parameters:

+ +

See Also: FMOD_DSP_TYPE_LOUDNESS_METER

+

Performance

+

Loudness Meter is a low overhead effect.

+
+

8.1.16 Multiband Dynamics

+

Three band dynamic processor. This effect is used to dynamically attenuate and amplify frequencies within each band based on the envelope of the signal.

+

The multiband dynamics effect processes each channel of the incoming signal by splitting it into one of three frequency bands, applying dynamic processing to each band individually, and combining the resulting bands back together.

+

The available dynamic processing operations are:

+
    +
  • Downward Compression: Attenuates the signal when it is above a defined threshold, by a factor determined by the ratio.
    +Downward Compression
    +Dynamic response shown in red, depicting the output signal decreasing in response to input values above the threshold.
    + This is the mode that the existing FMOD Compressor uses, and is useful for bringing down harsh percussive sounds, such as plosives and sibilance in the upper frequency range.
    + Select with FMOD_DSP_MULTIBAND_DYNAMICS_MODE_COMPRESS_DOWN.
  • +
  • Upward Compression: Amplifies the signal when it is below a defined threshold, by a factor determined by the ratio.
    +Upward Compression
    +Dynamic response shown in red, depicting the output signal increasing in response to input values below the threshold.
    + Upward Compression can be useful for bringing out quieter details in sounds, such as breath in the middle frequency range of vocals, or fret noise in the upper frequency range of a guitar.
    + Select with FMOD_DSP_MULTIBAND_DYNAMICS_MODE_COMPRESS_UP.
  • +
  • Downward Expansion: Attenuates the signal when it is below a defined threshold, by a factor determined by the ratio.
    +Downward Expansion
    +Dynamic response shown in red, depicting the output signal decreasing in response to input values below the threshold.
    + Downward Epansion be useful for removing noise in the signal, such as bird chirps in the upper frequency range, or room tone in the lower frequency range.
    + Select with FMOD_DSP_MULTIBAND_DYNAMICS_MODE_EXPAND_DOWN.
  • +
  • Upward Expansion: Amplifies the signal when it is above a defined threshold, by a factor determined by the ratio.
    +Upward Expansion
    +Dynamic response shown in red, depicting the output signal increasing in response to input values above the threshold.
    + Upward Expansion can easily cause clipping, so use with caution, but can be useful for bringing percussive sounds forward, such as snares in the upper frequency range or explosions in the lower frequency range.
    + Select with FMOD_DSP_MULTIBAND_DYNAMICS_MODE_EXPAND_UP.
  • +
+

Linked and unlinked side chaining is supported. If the channel count of the side chain is different to the input signal, it will be forced into linked mode.

+

See Also: FMOD_DSP_TYPE_MULTIBAND_DYNAMICS

+

Performance

+

Multiband Dynamics is a medium overhead effect. When a band is collpased it will not be processed, reducing CPU overhead of the effect.

+
+

8.1.17 Multiband Equalizer

+

A flexible five band parametric equalizer. This effect is used to attenuate and accentuate frequencies for greater control over frequency shaping within a signal.

+

The multiband equalizer effect processes each channel of the incoming signal by passing it through up to 5 selectable filter types in series (one after another) from A to E.

+

Multiband EQ curves
+Frequency response curve shown in red (phase response in gray) with three enabled filter types. (A) 12dB high-pass filter set at 70Hz. (B) Peaking filter set at 1kHz. (C) 24dB low-pass filter set at 10kHz.

+

The different filter types selectable are:

+ + +

See Also: FMOD_DSP_TYPE_MULTIBAND_EQ

+

Performance

+

Multiband EQ is a low overhead to medium overhead effect.

+

Each band of the effect is a separate filter that carries the same CPU cost regardless of fundamental type (except 24dB / 48dB variations - see below). Performance scales linearly as each band is enabled, i.e. running the effect with two enabled filters costs twice the CPU performance of running with a single filter enabled. If the signal has multiple channels performance scales approximately linearly with the channel count with some reductions due to multi-channel optimizations.

+

Some filter types have 12, 24 or 48 dB (decibel) variations, these variations indicate the filter is run once (12dB), twice (24dB) or four times (48dB) to achieve steeper roll off curves. As with all the provided filter types, performance scales linearly with the number of times the filter is run, therefore a 48dB filter (which runs four times) has approximately four times the CPU cost as a single 12dB filter with some reduction due to optimizations. The 6dB variation runs once like the 12dB version, but is slightly faster.

+
+

8.1.18 Normalize

+

Normalize amplifies the sound based on the maximum peaks within the signal. This is used to increase the loudness of a signal to a uniform maximum level.

+

The normalize filter analyzes the signal in realtime and scales the output based on maximum peaks detected. The lower limit of peak detection, and upper scale multiplier can be controlled by the user.

+

The normalize effect is controllable by the parameters:

+
    +
  • Fade time - To avoid reacting too quickly to sudden changes, the process occurs over a longer time to avoid pops and sudden bursts of noise. The duration is controlled with the normalize 'fade time' parameter which has a range of 0 to 20,000 ms, with a default of 5000 ms. Set with FMOD_DSP_NORMALIZE_FADETIME.
  • +
  • Threshold - Below certain signal levels, normalization is not desired. A low level signal that is normalized by its small peaks may cause excessive amplification of things like background hiss so a threshold setting can be used. The Threshold setting ranges from 0 to 1 as a linear value, with a default of 0.1. Set with FMOD_DSP_NORMALIZE_THRESHOLD.
  • +
  • Maximum Amplification - To avoid excessive amplification, a limit can be set on the maximum amplification factor. Maximum amplification has a range of 1 to 100,000 with a default of 20. Set with FMOD_DSP_NORMALIZE_MAXAMP.
  • +
+

By default the normalizer takes the highest peak value and scale it to 0 dB, scaling the rest of the signal by the same scale factor.

+

Normalize in action
+A signal with low gain having its gain slowly increased until it reaches a ceiling level.

+

See Also: FMOD_DSP_TYPE_NORMALIZE

+

Performance

+

Normalize is a low overhead effect.

+
+

8.1.19 Object Panner

+

The object panner effect is specifically designed to work with 3D platform-specific technologies such as Windows Sonic, PlayStation VR, and Dolby Atmos. It functions by routing the signal and the event's 3D positional information directly to a hardware device, instead of through the ChannelGroups and DSPs into which the signal is nominally routed.

+
+

FMOD Studio and the FMOD Studio User Manual refer to this effect as an 'Object Spatializer'.

+
+

As a result of the signal bypassing the mixer, the signal does not encounter any effects or sends "downstream" of the object panner. Unlike the Pan effect or built in Core API panning, the object panner does not automatically up-mix the signal to your project's surround speaker mode.

+

Signals processed by this effect are sent to the global object mixer (effectively a send), any DSP connected after this will receive silence.

+

Object panner bypassing mixer
+The signal flow above shows that the object panner sends the signal to the final output, bypassing the mixing engine.

+

For best results this effect should be used with Win Sonic or Audio 3D to get height panning. Playback with any other output results in fallback panning.

+
+

For a description of the parameters for an Object Panner, see the Panner effect reference as it shares a subset of the same parameters.

+
+

See Also: FMOD_DSP_TYPE_OBJECTPAN

+

Performance

+

Object Panner is a low overhead effect.

+
+

8.1.20 Oscillator

+

The Oscillator effect is a pure tone generator. It can be used to generate a variety of wave form shapes such as sine, saw, square and noise. Using a tone generator is an efficient way to create sound without using any memory.

+

The oscillator is a generator effect. This means it ignores incoming signals and writes out audio as a mono output signal. There are 5 different types of oscillator shape.

+

Oscillator wave shapes
+The different wave shapes that the oscillator effect supports.

+

The oscillator effect is controllable by the parameters:

+

Wave Shape - wave shape such as sine, square, triangle, saw, noise. Set with FMOD_DSP_OSCILLATOR_TYPE.
+Rate - The rate in Hz at which the audio is generated for different pitched tones. Set with FMOD_DSP_OSCILLATOR_RATE.

+

See Also: FMOD_DSP_TYPE_OSCILLATOR

+

Performance

+

Oscillator is a low overhead effect.

+
+

8.1.21 Pan

+

The pan effect is a multi channel, multi speaker signal distribution effect with 2D and 3D panning controls. Pan control allows you to specify which speakers the signal should be audible in, and can be used to convey a sense of movement by changing the panning of a sound in real time.

+
+

FMOD Studio and the FMOD Studio User Manual refers to this effect as a 'spatializer' when using its 3D functionality.

+
+

The pan effect can pan a signal based on a 3D emitter/listener position, or on a 2D basis where the speakers are panned to directly as if they were laid out on a stereo X axis or on a surround sound circle, where in both cases the listener is situated in the middle.
+There are several options for panning, so the guide below lists the different cases and features and how they are implemented.

+

The panner can be used in a purely 2D mode, or 3D mode, or a mixture of the two by utilizing the pan blend parameter.

+

The parameters for the pan effect are listed as topics below to elaborate on their functionality:

+

2D Stereo Output Mode

+

When the FMOD_DSP_PAN_MODE_TYPE is FMOD_DSP_PAN_MODE_STEREO, a simple position control can be used to pan a sound between left and right speakers, where a value of -100 is full left, 0 is in the middle and +100 is full right.

+

2D Stereo Output Mode
+The audible position of a sound in between stereo speakers can be set with a single stereo position value.

+
+

API reference. Positioning sound between left and right in a stereo speaker mode can be done with the FMOD_DSP_PAN_2D_STEREO_POSITION parameter.

+
+

The channels of a source signal are interpreted in different ways when panned to a stereo output:

+
    +
  • A mono signal is distributed with a constant power level with different left/right contributions based on the position value.
  • +
  • Stereo and above channel counts have their channels faded in and out in their matching left or right speaker, rather than moved between speakers as a mono signal would.
  • +
+

2D Surround Output Mode

+

When the FMOD_DSP_PAN_MODE_TYPE is FMOD_DSP_PAN_MODE_SURROUND (more than stereo, for example quad / 4.1 or 7.1), the source signal is distributed through the output speaker mode using a relevant up mix or down mix algorithm.

+

When panning any type of signal in a surround output mode, the distribution is described as a proportion of a set of speakers laid out on a circle. This is described by:

+
    +
  • Direction. Relative angle to the front facing position from the center point (or listener position) of a circle.
  • +
  • Extent. Amount of distribution on a circle relative to the direction.
  • +
+

2D Surround Output Mode
+A default direction of 0 (front center) and an extent of 360 (black circle), in a 7.1 speaker mode. The source signal's channels are distributed between all speakers in their default positions. The dot is a virtual representation of an equivalent x,y position of a signal in the circle.

+

2D Surround Output Mode: Extent

+

The extent is the size of the arc in the output speaker circle that has sound distributed to it. An extent of 360 means the source signal channels are distributed as they natively do to the whole speaker circle. An extent of 0 means the source signal channels are scaled within a single point on the circle.

+

2D Surround Output Mode: Extent 360
+A pan with a 30 degree direction, and an extent (the black arc), that changes from 360 degrees with distribution in all speakers, down to a 10 degree extent that makes the audio focus on front right speaker only. The dot is a virtual representation of an equivalent x,y position of a signal in the circle.

+

The channel mapping of a source signal is scaled into the extent angle.

+

2D Surround Output Mode: Extent 5ch
+A pan with a 30 degree direction, a 60 degree extent, and the channels of a 5 channel source signal being scaled within the extent.

+
+

API reference. Setting the extent value can be done with the FMOD_DSP_PAN_2D_EXTENT parameter.

+
+

2D Surround Output Mode: Direction

+

The direction is the orientation of the arc (extent) in the output speaker circle that has sound distributed to it. A direction of 0 means audio is distributed towards the front of the listener. A direction of -90 is to the left, +90 is to the right, with -180 and +180 being behind the listener.

+

2D Surround Output Mode: Direction
+A pan with a 60 degree extent (the black arc) with a direction that starts at 30 degrees then does a full rotation around the speaker circle to end up where it started.

+

The channel mapping of a source signal maintains its original orientation regardless of the direction setting. As an example a 5.1 signal that has a direction of 90 degrees does not rotate this signal's channels, but concentrates the signal towards the direction depending on now narrow the extent is.

+
+

API reference. Setting the direction value can be done with the FMOD_DSP_PAN_2D_DIRECTION parameter.

+
+

2D Surround Output Mode: Rotation

+

For a multi-channel source signal, the channels inside the signal can be rotated from their original mapping, contained within the extent.

+

2D Surround Output Mode: Rotation
+A pan with a fixed 30 degree direction and 60 degree extent, with a 5 channel source signal having its channels rotated over time inside the extent.

+
+

API reference. Setting the rotation value can be done with the FMOD_DSP_PAN_2D_ROTATION parameter.

+
+

2D Surround Output Mode: LFE Level

+

The LFE (Low Frequency Effects) channel of a signal is not positionable, but its level can be set independently. This is only available for surround output speaker modes.

+

The LFE level can be set to -80 dB for full attenuation up to +20 dB for amplification.

+
+

API reference. Setting the LFE value can be done with the FMOD_DSP_PAN_2D_LFE_LEVEL parameter.

+
+

2D Surround Output Mode: Stereo Source Discrete Panning

+

A stereo source signal is by default treated the same as other multi-channel source signals, with the left and right channels scaled within the extent (half of the extent dedicated to the left channel, half to the right).

+

Stereo source signals have an extra mode for discrete left/right panning in a circle, to give more focused distribution. The pan behavior for stereo source signals can be altered by setting the pan effect's 2D stereo mode parameter from 'Distributed' to 'Discrete'.

+
+

API reference. Switching stereo signal pan behavior from distributed to discrete can be set with the FMOD_DSP_PAN_2D_STEREO_MODE parameter.

+
+

In discrete mode, the left and right channels are not evenly distributed over an extent range, they are rather audibly located to the extreme left and right of that range, with no distribution of the signal to speakers in-between.

+

Distributed mode continues to use extent and direction parameters to control distribution, whereas 'Discrete' mode uses 2 different parameters called 'Separation' and 'Axis'.

+

2D Surround Output Mode: Stereo Axis

+

For a stereo sound in discrete mode, the orientation is denoted by an angle inside the circle pointing to the outside of the circle, called 'Axis' parameter. This can be set between -180 for behind in the left direction, and +180 degrees for behind in the right direction.

+

2D Surround Output Mode: Discrete Axis
+A pan of a stereo signal with a rotating axis and 60 degree separation.

+

As compared to distributed mode, in discrete mode the stereo axis setting rotates the mapping of the source signal channels around the circle, so that at +/- 180 degrees position the L and R source channels are reversed in the output speakers.

+
+

API reference. Setting the Stereo axis value can be done with the FMOD_DSP_PAN_2D_STEREO_AXIS parameter.

+
+

2D Surround Output Mode: Stereo Separation

+

For a stereo sound in discrete mode, The width of the pan distribution is known as 'Separation' and is represented by an angle with a range of -180 to +180 degrees, and a default of 60 degrees.

+

A default of 60 degrees with an axis of 0 degrees puts left in the front left speaker, and right in the front right speaker. Setting it to 0 puts the left and right in the same position and when it is negative the left and right source signal positions are swapped around.

+

2D Surround Output Mode: Stereo Separation
+A discrete mode pan of a stereo signal with a 0 degree axis and a separation that starts at 60 degrees then shrinks to 10 degrees, then flips the left and right by moving to a -60 degree separation value.

+
+

API reference. Setting the Stereo Separation value can be done with the FMOD_DSP_PAN_2D_STEREO_SEPARATION parameter.

+
+

2D Surround Output Mode: Height

+

In a speaker setup with height speakers, the pan can be blended between the standard ground level speaker circle and its pan distribution, with the

+

When the input or FMOD_DSP_PAN_SURROUND_SPEAKER_MODE has height speakers, control the blend between ground and height. -1.0 (push top speakers to ground), 0.0 (preserve top / ground separation), 1.0 (push ground speakers to top).

+

2D Surround Output Mode: Height Top
+A 7.1.4 speaker layout, viewed from the top. The 'T' (Top) based speakers are located in the ceiling of the listener's room.

+

2D Surround Output Mode: Height Side Mono
+A side view of a 7.1.4 speaker layout, with a mono signal (dot) adjusting its height from the ground level (0) to the ceiling level (1).

+

With a signal containing no height speakers of its own (ie all standard ground based speaker layouts of mono to 7.1), any height value below 0 is capped to 0. Negative height values are reserved for signals with height speakers.

+

The height value behaves differently for 7.1.4 source signals.

+ + + + + + + + + + + + + + + + + + + + + +
Height value7.1.4 signal behavior
0Default position, leaving ground and ceiling level signal channels in their relative ground and ceiling level output speaker locations.
0 to 1Affects height of ground level signal channels. Leaves the ceiling signal channels alone. Has the effect of raising up the source signal's ground channels the higher the number is.
0 to -1Affects height of ceiling level signal channels. Leaves the ground signal channels alone. Has the effect of lowering the ceiling channels the lower the number is.
+

2D Surround Output Mode: Height Side 7.1.4 Up
+A side view of a 7.1.4 speaker layout, with a 7.1.4 signal (multiple dots) adjusting its ground level channels from the ground level (0) to the ceiling level (1).

+

2D Surround Output Mode: Height Side 7.1.4 Down
+A side view of a 7.1.4 speaker layout, with a 7.1.4 signal (multiple dots) adjusting its ceiling level channels from the ceiling level (0) to the ground level (-1).

+
+

API reference. Setting the Stereo Separation value can be done with the FMOD_DSP_PAN_2D_HEIGHT_BLEND parameter.

+
+

3D Surround Output Mode: 3D Pan Blend

+

As the pan effect can simultaneously utilise 2D commands and 3D commands to achieve the desired signal distribution among the output speakers, to hear the result of 2D commands only or 3D commands only or a mixture of both, the Pan Blend setting can be used.

+

The setting has a linear range of 0 to 1 and a default of 0, which is the equivalent of all 2D output only. The opposite value is 1, and the equivalent of 3D output only. Values in-between allow for a mixture of the two, which allows for 2D to 3D pan morphing or vice versa.

+
+

API reference. Setting the 3D Pan Blend can be done with the FMOD_DSP_PAN_3D_PAN_BLEND parameter.

+
+

See Also: 2D vs 3D

+

3D Surround Output Mode: Position

+

For positioning of audio in speakers, setting the 3D position of objects is the key step to correct panning. Panning is based in 3D mode based on the position and orientation of a virtual 'listener' (ie the player / the camera position) vs the sound (or in this case the pan DSP).

+

The pan effect allows more than 1 listener, which is most useful for split screen type scenarios.

+

3D Surround Output Mode: Position
+2 sounds playing in a 3D space (X/Z plane only) with 2 listeners active. The output takes both listeners into account to produce the current gain and pan for a sound.

+
+

API reference. Setting the 3D Position can be done with the FMOD_DSP_PAN_3D_POSITION parameter.

+
+

3D Surround Output Mode: Roll-off

+

Roll-off is the simulation of distance between the listener and the sound source, which translates to gain or in some cases gain of certain frequencies. The further a sound source is from a listener, the quieter it will be. The Roll-off is based on an attenuation curve which is configurable, depending on requirements.

+

Below is a list of the various roll-off modes supported, with a description of its features below. A common control for each roll-off mode is the Minimum Distance and Maximum Distance. These controls help simulate the size of the sound and the space that it is in.

+

Linear Roll-off:
+3D Surround Output Mode: Roll Off Linear
+Linear roll-off keeps the volume unattenuated below the min distance, then attenuates to silence using a linear gradient to silence at the max distance.

+

Linear Squared Roll-off (Default setting):
+3D Surround Output Mode: Roll Off Linear Squared
+Linear Squared roll-off keeps the volume unattenuated below the min distance, then attenuates to silence using a linear squared gradient to silence at the max distance. This gives it a faster roll-off near the min distance, and a slower roll-off nearer to the max distance than linear mode.

+

Inverse Roll-off:
+3D Surround Output Mode: Roll Off Inverse
+Inverse roll-off keeps the volume unattenuated below the min distance, then attenuates at a rate using min distance / distance as the gradient until it reaches max distance where it stops attenuating.

+

Inverse Tapered Roll-off:
+3D Surround Output Mode: Roll Off Inverse Tapered
+Inverse tapered is a combination of Inverse Roll-off and Linear Squared Roll-off. From min distance onwards Inverse is used, then if the gain is lower with Linear Squared, it will switch to that to ensure the gain hits silence at the max distance.

+

Custom Roll-off:
+3D Surround Output Mode: Custom Roll-off
+Custom roll-off can be defined by the programmer setting volume manually. Attenuation in the pan DSP is turned off in this mode.

+
+

API reference. Setting the 3D Roll-off can be done with the FMOD_DSP_PAN_3D_ROLLOFF parameter.

+
+

3D Surround Output Mode: Min Distance

+

The minimum distance, in all roll-off modes is the distance from the listener that the gain starts attenuating.

+

In Custom roll-off mode the Min Distance is ignored.

+
+

API reference. Setting the 3D Min Distance can be done with the FMOD_DSP_PAN_3D_MIN_DISTANCE parameter.

+
+

3D Surround Output Mode: Max Distance

+

The maximum distance, is the distance from the listener that the gain stops attenuating (Inverse roll-off mode), or attenuates to silence (Linear, Linear Squared and Inverse Tapered roll-off modes).

+

In Custom roll-off mode the Max Distance is ignored.

+
+

API reference. Setting the 3D Max Distance can be done with the FMOD_DSP_PAN_3D_MAX_DISTANCE parameter.

+
+

3D Surround Output Mode: Extent Mode

+

In 3D, the speaker distribution method as described in 2D Extent is controlled via a combination of 3D Minimum Extent and and 3D Sound Size.
+Both are controlled manually, automatically, or they can be disabled. In 3D the direction is determined automatically based on 3D positioning.

+

Automatic Mode:
+In Automatic Mode the 3D Sound Size is automatically controlled based on sound source distance from listener (closer = bigger) and works off a base of 2 times the Minimum Distance. 3D Minimum Extent is set to 0.
+3D Surround Output Mode: Extent Auto
+In automatic mode, the signal distribution arc gets smaller as the sound source gets further away from the listener. As it approaches the listener, it gets bigger to distribute the signal throughout more speakers. This alleviates the source signal instantly flipping from one speaker to another if it crosses through the position of the listener.

+

Off Mode:
+In Off Mode the 3D Sound Size is set to 0, and 3D Minimum Extent is set to 0.
+3D Surround Output Mode: Extent Off
+In off mode, the signal distribution arc becomes a point which pinpoints the distribution of the signal into one location, regardless of the sound source distance from the listener.

+

User Mode:
+In User Mode, the 3D Minimum Extent and 3D Sound Size are set by the user using the parameters provided.

+
+

API reference. Setting the 3D Extent Mode can be done with the FMOD_DSP_PAN_3D_EXTENT_MODE parameter.

+
+

3D Surround Output Mode: Sound Size

+

The sound size parameter has an affect on the panner's extent, based on how 'large' the sound is. A very small sound is be concentrated more into a point source (a small extent) and a large sound is spread around the speakers more to convey a sense of envelopment (a large extent).

+

3D Surround Output Mode: Sound Size
+A source signal that is located near a speaker and does not move, but the apparent 'size' of the source changes from small to large, affecting the extent of the pan distribution around the circle.

+

This parameter is only available to be set in 'User' Extent Mode. In 'Automatic' and 'Off' mode, the sound size parameter is set automatically.

+

The sound size's affect on the extent can be clamped to a minimum angle, set with Min Extent.

+
+

API reference. Setting the 3D Sound Size can be done with the FMOD_DSP_PAN_3D_SOUND_SIZE parameter.

+
+

3D Surround Output Mode: Min Extent

+

The min extent parameter has an affect on the panner's extent, by acting as a clamp against the sound size's affect on it. If a sound size becomes small which can reduce the distribution of pan to a point source, the min extent parameter can set an angle to guarantee that the panner does not distribute the signal below this value.

+

3D Surround Output Mode: Min Extent
+A source signal that is located near a speaker and does not move, with the sound size changing from largest to smallest size, but the extent being clamped by at the minimum extent angle, which in this case is set to 180 degrees.

+

This parameter is only available to be set in 'User' Extent Mode. In 'Automatic' and 'Off' mode, the min extent parameter is set to 0.

+
+

API reference. Setting the 3D Min Extent can be done with the FMOD_DSP_PAN_3D_MIN_EXTENT parameter.

+
+

General settings: Enabled Speakers

+

Speakers for target distribution of a source signal can be turned on or off to mute sound in a speaker and have the distribution shifted to other speakers.

+

General settings: Enabled Speakers
+Speakers arbitrarily being turned off and on which alters the distribution of the source signal to the other speakers.

+

Note that signal does not disappear if its location was intended for a particular speaker, it just gets reassigned to other speakers. In a 7.1 speaker layout, if all speakers except for front left / front right were disabled, then sounds that are supposed to play in the back speakers would be mixed down to the front speakers like they would be in a typical stereo speaker output mode.

+
+

API reference. Setting the Enabled Speakers can be done with the FMOD_DSP_PAN_ENABLED_SPEAKERS parameter.

+
+

General settings: LFE Up-mix Enabled

+

LFE Up-mix Enabled determines whether non-LFE source channels should mix to the LFE or not. Default is off, so only an LFE source channel is audible in an LFE output speaker.

+
+

API reference. Setting the LFE Up-mix enabled can be done with the FMOD_DSP_PAN_LFE_UPMIX_ENABLED parameter.

+
+

General settings: Overall Gain

+

A read only parameter that allows the user to query the gain of the Panner based on all of the attenuation calculations.

+

Two values are returned, a linear gain value that represents the volume of the default audible output path of the DSP, and an additive linear gain value that represents the volume of the signal that is sent to other DSPs but not audible from the output of the DSP. This could be a send path to another DSP (See Send) or a send path to a hardware device (See Object Panner).

+
+

API reference. Getting the Overall Gain can be done with the FMOD_DSP_PAN_OVERALL_GAIN parameter.

+
+

General settings: Surround Speaker Mode

+

The surround speaker mode is the output speaker format for the panner. By default it is the same as the speaker mode selected for the user or by the user after the System's initialization.

+
+

API reference. Setting the Surround Speaker Mode can be done with the FMOD_DSP_PAN_SURROUND_SPEAKER_MODE parameter.

+
+

See Also: FMOD_DSP_TYPE_PAN

+

Performance

+

Pan is a low overhead effect.

+
+

8.1.22 Pitch Shifter

+

A pitch shifter can be used to change the pitch of a sound without affecting the duration of playback.

+

The pitch shifter uses a transform algorithm (FFT) to convert the signal from the time domain to the frequency domain. The signal is manipulated to shift sinusoidal bands by the specified amount, then the signal is re-synthesized back into the time domain into a standard PCM signal.

+

This effect can also be used for time stretching or scaling, by shifting the pitch then altering the playback frequency in the other direction proportionally. As an example if the pitch was doubled, and the frequency of the sound was halved, the pitch of the sound would sound correct but it would be twice as slow.

+

This pitch shifter is based on the pitch shifter code at http://www.dspdimension.com, written by Stephan M. Bernsee. The original code is COPYRIGHT 1999-2003 Stephan M. Bernsee - smb@dspdimension.com under the Wide Open License (WOL).

+

The pitch shifter effect is controllable by the parameters:

+
    +
  • Pitch - The pitch can be set with a single linear value, which ranges from 0.5 octaves to 2.0 octaves, with a default of 1 which equals no pitch change. Set with FMOD_DSP_PITCHSHIFT_PITCH.
  • +
  • FFT size - Quality can be altered with the FFT window size which ranges from 256 to 4096 with a default of 1024. Set with FMOD_DSP_PITCHSHIFT_FFTSIZE.
  • +
  • Max channels - The maximum number of incoming speaker channels that can be handled by the pitch shifter effect. The amount of memory allocated to the pitch shifter effect is proportional to the number specified. If set to a lower number than the signal's channel count, no pitch shifting is applied. It is therefore best to set this parameter to the number of channels the pitch shifter effect receives as input. If this parameter is set to 0, it acts as if it were set to the system's default speaker channel format, as reported by System::getSoftwareFormat. Set with FMOD_DSP_PITCHSHIFT_MAXCHANNELS.
  • +
+

See Also: FMOD_DSP_TYPE_PITCHSHIFT

+

Performance

+

Pitch Shifter is a high overhead effect.

+

This filter is computationally expensive. Reducing the signal from stereo to mono halves the cpu usage. FFT Window size also improves performance at smaller sizes. Reducing window size lowers audio quality, but which settings to use are largely dependant on the sound being played. A noisy polyphonic signal needs a larger fft size compared to a speaking voice for example.

+
+

8.1.23 Return

+

The use of a return effect is to receive a routed audio signal from a different location than its standard input inside the DSP graph.

+

A return effect receives routed audio from its partner DSP, the Send effect.

+

Return
+A DSP graph showing a send and return deviating the signal from its normal signal flow, sending a copy of the signal (visible as gray dashed arrow) from the send, and receiving it on the return.

+

The return effect is controllable by the parameters:

+
    +
  • Speaker mode - The speaker mode of the receiving buffer can be set to a known speaker mode, or it can be left to automatically select, which is the default. Set with FMOD_DSP_RETURN_INPUT_SPEAKER_MODE.
  • +
+

The return effect can query the parameters:

+
    +
  • Return ID - The index that the Send effect will use for the 'Return ID' destination parameter. Get with FMOD_DSP_RETURN_ID.
  • +
+

Note that upon receiving the signal, it is buffered and therefore will incur one mix block of latency.

+

See Also: FMOD_DSP_TYPE_RETURN

+

Performance

+

Return is a low overhead effect.

+
+

8.1.24 Send

+

The use of a send effect is to route an audio signal to a different location than its standard output inside the DSP graph.

+

A send effect routes its audio to a partner DSP, the return effect.
+Return
+A DSP graph showing a send and return deviating the signal from its normal signal flow, sending the signal (visible as grey dashed arrow) from the send, and receiving it on the return.

+

The send effect is controllable by the parameters:

+ +

Note that upon receiving the signal on the return side, it is buffered and therefore will incur one mix block of latency.

+

See Also: FMOD_DSP_TYPE_SEND

+

Performance

+

Send is a low overhead effect.

+
+

8.1.25 SFX Reverb

+

The SFX reverb effect is a high quality I3DL2 based reverb to simulate an acoustic space. It is highly configurable so the many parameters can be altered to simulate small and wide open spaces.

+

SFX Reverb is a time domain low CPU cost with high quality and flexibility. Because it is parametric, there is great control over the characteristics of the reverb, and it also means that reverb can change or morph over time from one preset to another.

+

SFX Reverb
+A diagram of the layout of time domain reverb. There is the original signal (direct) followed by some early reflected copies of the original signal (early reflections) then a diffused version of the original which decays over time (late reflections/reverb) to silence.

+

The SFX reverb effect is controllable by the parameters:

+ +

The reverb can be controlled with simple to understand presets. The current preset list is:

+
    +
  • Off
  • +
  • Generic
  • +
  • Padded Cell
  • +
  • Room
  • +
  • Bath room
  • +
  • Living room
  • +
  • Stone room
  • +
  • Auditorium
  • +
  • Concert Hall
  • +
  • Cave
  • +
  • Arena
  • +
  • Hangar
  • +
  • Stone Corridor
  • +
  • Alley
  • +
  • Forest
  • +
  • City
  • +
  • Mountains
  • +
  • Quarry
  • +
  • Plain
  • +
  • Parking Lot
  • +
  • Sewer Pipe
  • +
  • Under Water
  • +
+
+

API reference. Reverb presets can be set with FMOD_REVERB_PRESETS.

+
+

See Also: FMOD_DSP_TYPE_SFXREVERB

+

Performance

+

SFX Reverb is a medium overhead effect.

+
+

8.1.26 Three EQ

+

The three EQ effect is a three band equalizer. It splits the signal into lows, mids and highs, and allows each band to be attenuated (potentially all the way down to silence) or boosted.

+

For each band, the frequencies can be modified with the low/mid crossover frequency and the mid/high crossover frequency controls. The shape of the cross-over slow can also be changed for the bands, with 12 dB, 24 dB and 48 dB options available.

+

Three EQ curves
+The Three EQ and the (L)ow / (M)id / (H)igh frequency bands each at 0 dB attenuation, with their cross over points displayed as the dotted lines and slope set to 12 dB. Alternate crossover slopes are shown in a lighter tone for 24 and 48 dB.

+

The three EQ effect is controllable by the parameters:

+ +

See Also: FMOD_DSP_TYPE_THREE_EQ

+

Performance

+

Three EQ is a low overhead effect.

+

With the 12, 24 or 48 dB variations, this indicates whether the filter is run once (12dB), twice (24dB) or four times (48dB) to achieve steeper roll off curves. Performance scales linearly with the number of times the filter is run, therefore a 48dB filter (which runs four times) has approximately four times the CPU cost as a single 12dB filter with some reduction due to optimizations.

+
+

8.1.27 Transceiver

+

Like the Send and Return effects, the transceiver effect allows signals to be routed from one place in the DSP graph to another.

+

There are 32 separate channels to which a transceiver can route an audio signal or receive audio from. A transceiver can be set to receiver mode, which makes it receive the signal from the selected channel at a variable gain, similar to a return. A transceiver can alternatively be set to transmit mode, which makes it function similarly to a send in that it sends a duplicate of the signal at its position in the DSP graph, with a variable gain, to the selected channel.

+

This allows transceivers to be used in a variety of different ways. A common application is for one transmitting transceiver's signal to be received by an unlimited number of receiving transceivers, making that signal audible in multiple different parts of the DSP graph. In a 3D world, this could allow one expensive emitter (i.e.: a stream) to be broadcast to different 3D locations around the world simultaneously, at low CPU cost.

+

Transceiver
+Sounds being transmitted by 2 transceivers in transmit mode, one sound transmitting to channel 0, and the other to channel 1. There is then a 3D scene with 5 transceivers tuned to either channel 0 or 1, which lets then broadcast the transmitted signal from different locations simultaneously.

+

Characteristics of the transceiver effect:

+
    +
  • Upon receiving the signal on the receive side, it is buffered and therefore incurs one mix block of latency.
  • +
  • When multiple transmitters are set to the same channel, their signals are mixed together.
  • +
+

The transceiver effect is controllable by the parameters:

+
    +
  • Transmit mode - The transceiver can be set to 'transmitter' mode, or 'receiver' mode. Set with FMOD_DSP_TRANSCEIVER_TRANSMIT parameter.
  • +
  • Transmit or receive gain - Set with a range of -80 dB to +10 dB and a default of 0dB. Set with FMOD_DSP_TRANSCEIVER_GAIN parameter.
  • +
  • Transmit speaker mode - This can be set to either mono, stereo or surround. Surround is the speaker mode of the System. If in receive mode, transmit speaker mode has no effect. Set with the FMOD_DSP_TRANSCEIVER_TRANSMITSPEAKERMODE.
  • +
+

Each transmitter can transmit in its preferred speaker mode of mono, stereo or surround. Each receiving transceiver receives all of these signals, mixes them, and in the process up-mixes or down-mixes to the speaker channel format used at its position in the DSP graph.

+

See Also: FMOD_DSP_TYPE_TRANSCEIVER

+

Performance

+

To reduce memory overhead, ensure that when multiple transmitting transceivers are set to the same channel, they are also set to the same transmit speaker mode.

+

Transceiver is a low overhead effect.

+
+

8.1.28 Tremolo

+

The tremolo effect varies the amplitude of a sound with a low frequency oscillator, which results in periodic volume changes. Depending on the settings, this unit can produce a tremolo, chopper, or auto-pan effect.

+

The tremolo effect is controllable by the parameters:

+
    +
  • Shape - The shape of the LFO (Low Frequency Oscillator) can set to sine, triangle and sawtooth waves by adjusting the this parameter. Set with FMOD_DSP_TREMOLO_SHAPE.
  • +
  • Skew - The time skewing of the LFO (Low Frequency Oscillator) cycle can be set with a linear value between 0 and 1, with a default of 0.5. Set with FMOD_DSP_TREMOLO_SHAPE and FMOD_DSP_TREMOLO_SKEW parameters.
  • +
  • Frequency - The speed of the LFO can be set in Hz, with a range of 0.1 Hz to 20 Hz and a default of 5 Hz. Set with FMOD_DSP_TREMOLO_FREQUENCY.
  • +
  • Depth - The depth of the LFO can be set with a linear value from 0 to 1 where 0 is no tremolo and 1 is full. Default is 1. Set with FMOD_DSP_TREMOLO_DEPTH.
  • +
  • Duty / Square - Duty and Square attributes are useful for a chopper-type effect where the first controls the on-time duration and second controls the flatness of the envelope. Set with FMOD_DSP_TREMOLO_DUTY and FMOD_DSP_TREMOLO_SQUARE parameters.
  • +
  • Spread - The Spread attribute varies the LFO phase between channels to get an auto-pan effect. This works best with a sine shape LFO. Set with FMOD_DSP_TREMOLO_SPREAD.
  • +
  • Phase - The LFO can be synchronized using the phase parameter which sets its instantaneous phase. Set with FMOD_DSP_TREMOLO_PHASE.
  • +
+

See Also: FMOD_DSP_TYPE_TREMOLO

+

Performance

+

Tremolo is a low overhead effect.

+
+

8.2 Legacy Effects

+

High-level descriptions of built effects that are superseded by newer improved effects.

+

8.2.1 High Pass

+

Resonant high pass filter effect.

+
+

Development Status. Deprecated and will be removed in a future release

+
+

Use Multiband Equalizer as a replacement.

+

See Also: FMOD_DSP_TYPE_HIGHPASS

+

Performance

+

High Pass is a low overhead effect.

+
+

8.2.2 High Pass Simple

+

This is a very simple single-order high pass filter. The emphasis is on speed rather than accuracy, so this should not be used for task requiring critical filtering.

+
+

Development Status. Deprecated and will be removed in a future release

+
+

Use Multiband Equalizer as a replacement.

+

See Also: FMOD_DSP_TYPE_HIGHPASS_SIMPLE

+

Performance

+

High Pass Simple is a low overhead effect.

+
+

8.2.3 Low Pass

+

A resonant low pass filter effect.

+
+

Development Status. Deprecated and will be removed in a future release

+
+

Use Multiband Equalizer as a replacement.

+

See Also: FMOD_DSP_TYPE_LOWPASS

+

Performance

+

Low Pass is a medium overhead effect.

+
+

8.2.4 Low Pass Simple

+

This is a very simple low pass filter effect, based on two single-pole RC time-constant modules.

+

The emphasis is on speed rather than accuracy, so this should not be used for task requiring critical filtering.

+
+

Development Status. Deprecated and will be removed in a future release

+
+

Use Multiband Equalizer as a replacement.

+

See Also: FMOD_DSP_TYPE_LOWPASS_SIMPLE

+

Performance

+

Low Pass Simple is a low overhead effect.

+
+

8.2.5 Parametric EQ

+

Parametric EQ is a single band peaking EQ filter effect that attenuates or amplifies a selected frequency and its neighboring frequencies.

+

When a frequency has its gain set to 1.0, the sound is unaffected and represents the original signal exactly.

+
+

Development Status. Deprecated and will be removed in a future release

+
+

Use Multiband Equalizer as a replacement.

+

See Also: FMOD_DSP_TYPE_PARAMEQ

+

Performance

+

Parametric EQ is a medium overhead effect.

+
+ + +
+ + + diff --git a/FMOD/doc/FMOD API User Manual/fsbank-api.html b/FMOD/doc/FMOD API User Manual/fsbank-api.html new file mode 100644 index 0000000..35dbb38 --- /dev/null +++ b/FMOD/doc/FMOD API User Manual/fsbank-api.html @@ -0,0 +1,720 @@ + + +FSBank API Reference + + + + +
+ +
+

20. FSBank API Reference

+ +

20.1 FSBank_Init

+

Initialize the FSBank system.

+

+

+
C
+
+

+
FSBANK_RESULT FSBank_Init(
+  FSBANK_FSBVERSION version,
+  FSBANK_INITFLAGS flags,
+  unsigned int numSimultaneousJobs,
+  const char *cacheDirectory
+);
+
+ +
+
version
+
FSB version, currently only FSBANK_FSBVERSION_FSB5 is supported. (FSBANK_FSBVERSION)
+
flags
+
Initialization flags which control how the system behaves. (FSBANK_INITFLAGS)
+
numSimultaneousJobs
+
The maximum number of threads to create for parallel encoding. Set this to your number of CPU 'cores' for best performance.
+
cacheDirectory Opt
+
Location to store the temporary cache files, default is a directory off the current working directory.
+
+

See Also: FSBank_Release

+

20.2 FSBank_Build

+

Begin the building process for the provided subsound descriptions.

+

+

+
C
+
+

+
FSBANK_RESULT FSBank_Build(
+  const FSBANK_SUBSOUND *subSounds,
+  unsigned int numSubSounds,
+  FSBANK_FORMAT encodeFormat,
+  FSBANK_BUILDFLAGS buildFlags,
+  unsigned int quality,
+  const char *encryptKey,
+  const char *outputFileName
+);
+
+ +
+
subSounds
+
Array of subsound descriptions each defining one subsound for the FSB. (FSBANK_SUBSOUND)
+
numSubSounds
+
Number of elements in subSounds.
+
encodeFormat
+
FSB encoding format. (FSBANK_FORMAT)
+
buildFlags
+
Building flags which control how the sample data is encoded. (FSBANK_BUILDFLAGS)
+
quality
+
Controls the post compression quality level. From 1 (high compression / low quality) to 100 (high quality / low compression), use 0 for default quality. See remarks for format specific usage.
+
encryptKey Opt
+
Key used to encrypt the FSB. Same key is required at runtime for decryption.
+
outputFileName Out
+
Path of the FSB to produce.
+
+

Format specific quality interpretation:

+
    +
  • AT9 - Bitrate (Kbps) depends on channel count, quality [1 to 100] maps linearly to the available options
  • +
  • 1ch = [36, 48, 60, 72, 84, 96]
  • +
  • 2ch = [72, 96, 120, 144, 168, 192]
  • +
  • MPEG - Bitrate (Kbps) = FMOD quality * 3.2
  • +
  • Vorbis - Vorbis quality [-0.1 to 1.0] maps linearly to FMOD quality [1 to 100] based on: Vorbis_Quality = ((FMOD_Quality - 1) / 90.0f) - 0.1f
  • +
  • XMA - XMA quality = FMOD quality
  • +
  • Opus - Opus per-channel bitrate (Kbps) [0.8 to 64] maps linearly to FMOD quality [1 to 80], then bitrate [67.2 to 128] to quality [81 to 100]
  • +
+

Build function will block until complete.

+

20.3 FSBank_BuildCancel

+

Halt the build in progress.

+

+

+
C
+
+

+
FSBANK_RESULT FSBank_BuildCancel();
+
+ +

Must be called from a different thread to FSBank_Build

+

See Also: FSBank_Build

+

20.4 FSBank_Release

+

Release the FSBank system, clean up used resources.

+

+

+
C
+
+

+
FSBANK_RESULT FSBank_Release();
+
+ +

All progress items retrieved with FSBank_FetchNextProgressItem will be released by this function.

+

See Also: FSBank_Init, FSBank_FetchNextProgressItem

+

20.5 FSBank_ReleaseProgressItem

+

Release memory associated with a progress item.

+

+

+
C
+
+

+
FSBANK_RESULT FSBank_ReleaseProgressItem(
+  const FSBANK_PROGRESSITEM *progressItem
+);
+
+ +
+
progressItem
+
One status update about the progress of a particular subsound. (FSBANK_PROGRESSITEM)
+
+

See Also: FSBank_FetchNextProgressItem

+

20.6 FSBank_MemoryGetStats

+

Query the current and maximum memory usage of the FSBank system.

+

+

+
C
+
+

+
FSBANK_RESULT FSBank_MemoryGetStats(
+  unsigned int *currentAllocated,
+  unsigned int *maximumAllocated
+);
+
+ +
+
currentAllocated
+
Address of a variable that receives the currently allocated memory at time of call. Optional. Specify 0 or NULL to ignore.
+
maximumAllocated
+
Address of a variable that receives the maximum allocated memory since FSBank_Init. Optional. Specify 0 or NULL to ignore.
+
+

20.7 FSBank_MemoryInit

+

Specifies a method for FSBank to allocate memory through callbacks.

+

+

+
C
+
+

+
FSBANK_RESULT FSBank_MemoryInit(
+  FSBANK_MEMORY_ALLOC_CALLBACK userAlloc,
+  FSBANK_MEMORY_REALLOC_CALLBACK userRealloc,
+  FSBANK_MEMORY_FREE_CALLBACK userFree
+);
+
+ +
+
userAlloc
+
Overrides the internal calls to alloc. Compatible with ANSI malloc(). (FSBANK_MEMORY_ALLOC_CALLBACK)
+
userRealloc
+
Overrides the internal calls to realloc. Compatible with ANSI realloc(). (FSBANK_MEMORY_REALLOC_CALLBACK)
+
userFree
+
Overrides the internal calls to free. Compatible with ANSI free(). (FSBANK_MEMORY_FREE_CALLBACK)
+
+

20.8 FSBank_FetchFSBMemory

+

Fetch the built FSB data from memory.

+

+

+
C
+
+

+
FSBANK_RESULT FSBank_FetchFSBMemory(
+  const void **data,
+  unsigned int *length
+);
+
+ +
+
data
+
Built FSB data.
+
length
+
+

Length of 'data'.

+
    +
  • Units: Bytes
  • +
+
+
+

Requires FSBank_Build to be called with outputFileName is set to NULL.

+

The memory allocated as part of FSBank_Build will be freed automatically by the next FSBank_Build or FSBank_Release.

+

See Also: FSBank_Build, FSBank_Release

+

20.9 FSBank_FetchNextProgressItem

+

Fetch build progress items that describe the current state of the build.

+

+

+
C
+
+

+
FSBANK_RESULT FSBank_FetchNextProgressItem(
+  const FSBANK_PROGRESSITEM **progressItem
+);
+
+ +
+
progressItem
+
One status update about the progress of a particular subsound. (FSBANK_PROGRESSITEM)
+
+

Can be called while the build is in progress to get realtime updates or after the build for a report. Call FSBank_ReleaseProgressItem to free allocated memory.

+

20.10 FSBANK_MEMORY_ALLOC_CALLBACK

+

Callback to allocate a block of memory.

+

+

+
C
+
+

+
void * FSBANK_CALLBACK FSBANK_MEMORY_ALLOC_CALLBACK(
+  unsigned int size,
+  unsigned int type,
+  const char *sourceStr
+);
+
+ +
+
size
+
Size in bytes of the memory block to be allocated and returned.
+
type
+
Type of memory allocation.
+
sourceStr
+
Only valid (not null) in logging versions of FMOD. Gives a string with the fmod source code filename and line number in it, for better resource tracking.
+
+

Returning an aligned pointer, of 16 byte alignment is recommended for speed purposes.

+

See Also: FSBank_MemoryInit, FSBANK_MEMORY_REALLOC_CALLBACK, FSBANK_MEMORY_FREE_CALLBACK

+

20.11 FSBANK_MEMORY_FREE_CALLBACK

+

Callback to free a block of memory.

+

+

+
C
+
+

+
void FSBANK_CALLBACK FSBANK_MEMORY_FREE_CALLBACK(
+  void *ptr,
+  unsigned int type,
+  const char *sourceStr
+);
+
+ +
+
ptr
+
Pointer to a pre-existing block of memory to be freed.
+
type
+
Type of memory to be freed.
+
sourceStr
+
Only valid (not null) in logging versions of FMOD. Gives a string with the fmod source code filename and line number in it, for better resource tracking.
+
+

See Also: FSBank_MemoryInit, FSBANK_MEMORY_ALLOC_CALLBACK, FSBANK_MEMORY_REALLOC_CALLBACK

+

20.12 FSBANK_MEMORY_REALLOC_CALLBACK

+

Callback to re-allocate a block of memory to a different size.

+

+

+
C
+
+

+
void * FSBANK_CALLBACK FSBANK_MEMORY_REALLOC_CALLBACK(
+  void *ptr,
+  unsigned int size,
+  unsigned int type,
+  const char *sourceStr
+);
+
+ +
+
ptr
+
Pointer to a block of memory to be resized. If this is NULL then a new block of memory is simply allocated.
+
size
+
Size of the memory to be reallocated. The original memory must be preserved.
+
type
+
Type of memory allocation.
+
sourceStr
+
Only valid (not null) in logging versions of FMOD. Gives a string with the fmod source code filename and line number in it, for better resource tracking.
+
+

Returning an aligned pointer, of 16 byte alignment is recommended for speed purposes.

+

See Also: FSBank_MemoryInit, FSBANK_MEMORY_ALLOC_CALLBACK, FSBANK_MEMORY_FREE_CALLBACK

+

20.13 FSBANK_INITFLAGS

+

Bit fields to control the general operation of the library.

+

+

+
C
+
+

+
#define FSBANK_INIT_NORMAL                  0x00000000
+#define FSBANK_INIT_IGNOREERRORS            0x00000001
+#define FSBANK_INIT_WARNINGSASERRORS        0x00000002
+#define FSBANK_INIT_CREATEINCLUDEHEADER     0x00000004
+#define FSBANK_INIT_DONTLOADCACHEFILES      0x00000008
+#define FSBANK_INIT_GENERATEPROGRESSITEMS   0x00000010
+
+ +
+
FSBANK_INIT_NORMAL
+
Initialize normally.
+
FSBANK_INIT_IGNOREERRORS
+
Ignore individual subsound build errors, continue building for as long as possible.
+
FSBANK_INIT_WARNINGSASERRORS
+
Treat any warnings issued as errors.
+
FSBANK_INIT_CREATEINCLUDEHEADER
+
Create C header files with #defines defining indices for each member of the FSB.
+
FSBANK_INIT_DONTLOADCACHEFILES
+
Ignore existing cache files.
+
FSBANK_INIT_GENERATEPROGRESSITEMS
+
Generate status items that can be queried by another thread to monitor the build progress and give detailed error messages.
+
+

See Also: FSBank_Init

+

20.14 FSBANK_BUILDFLAGS

+

Bit fields to control how subsounds are encoded.

+

+

+
C
+
+

+
#define FSBANK_BUILD_DEFAULT                 0x00000000
+#define FSBANK_BUILD_DISABLESYNCPOINTS       0x00000001
+#define FSBANK_BUILD_DONTLOOP                0x00000002
+#define FSBANK_BUILD_FILTERHIGHFREQ          0x00000004
+#define FSBANK_BUILD_DISABLESEEKING          0x00000008
+#define FSBANK_BUILD_OPTIMIZESAMPLERATE      0x00000010
+#define FSBANK_BUILD_FSB5_DONTWRITENAMES     0x00000080
+#define FSBANK_BUILD_NOGUID                  0x00000100
+#define FSBANK_BUILD_WRITEPEAKVOLUME         0x00000200
+#define FSBANK_BUILD_ALIGN4K                 0x00000400
+#define FSBANK_BUILD_OVERRIDE_MASK           (FSBANK_BUILD_DISABLESYNCPOINTS | FSBANK_BUILD_DONTLOOP | FSBANK_BUILD_FILTERHIGHFREQ | FSBANK_BUILD_DISABLESEEKING | FSBANK_BUILD_OPTIMIZESAMPLERATE | FSBANK_BUILD_WRITEPEAKVOLUME)
+#define FSBANK_BUILD_CACHE_VALIDATION_MASK   (FSBANK_BUILD_DONTLOOP | FSBANK_BUILD_FILTERHIGHFREQ | FSBANK_BUILD_OPTIMIZESAMPLERATE)
+
+ +
+
FSBANK_BUILD_DEFAULT
+
Build with default settings.
+
FSBANK_BUILD_DISABLESYNCPOINTS
+
Disable the storing of syncpoints in the output
+
FSBANK_BUILD_DONTLOOP
+
Disable perfect loop encoding and sound stretching. Removes chirps from the start of oneshot MP2, MP3 and IMAADPCM sounds.
+
FSBANK_BUILD_FILTERHIGHFREQ
+
XMA only. Enable high frequency filtering.
+
FSBANK_BUILD_DISABLESEEKING
+
XMA only. Disable seek tables to save memory.
+
FSBANK_BUILD_OPTIMIZESAMPLERATE
+
Attempt to optimize the sample rate down. Ignored if format is MP2, MP3 or if FSB4 basic headers flag is used.
+
FSBANK_BUILD_FSB5_DONTWRITENAMES
+
Do not write out a names chunk to the FSB to reduce file size.
+
FSBANK_BUILD_NOGUID
+
Write out a null GUID for the FSB header. The engine will not use header caching for these FSB files.
+
FSBANK_BUILD_WRITEPEAKVOLUME
+
Write peak volume for all subsounds.
+
FSBANK_BUILD_ALIGN4K
+
Opus, Vorbis and FADPCM only. Align large sample data to a 4KB boundary to improve binary patching in distribution systems that operate in 4KB blocks (Microsoft).
+
FSBANK_BUILD_OVERRIDE_MASK
+
Build flag mask that specifies which settings can be overridden per subsound.
+
FSBANK_BUILD_CACHE_VALIDATION_MASK
+
Build flag mask that specifies which settings (when changed) invalidate a cache file.
+
+

See Also: FSBank_Init, FSBANK_SUBSOUND

+

20.15 FSBANK_FORMAT

+

Compression formats available for encoding

+

+

+
C
+
+

+
typedef enum FSBANK_FORMAT {
+  FSBANK_FORMAT_PCM,
+  FSBANK_FORMAT_XMA,
+  FSBANK_FORMAT_AT9,
+  FSBANK_FORMAT_VORBIS,
+  FSBANK_FORMAT_FADPCM,
+  FSBANK_FORMAT_OPUS,
+  FSBANK_FORMAT_MAX
+} FSBANK_FORMAT;
+
+ +
+
FSBANK_FORMAT_PCM
+
PCM (1:1) All platforms.
+
FSBANK_FORMAT_XMA
+
XMA (VBR) XboxOne and Xbox Series X|S only (hardware). Depends on xmaencoder.
+
FSBANK_FORMAT_AT9
+
ATRAC9 (CBR) PS4 and PS5 only (hardware). Depends on libatrac9.
+
FSBANK_FORMAT_VORBIS
+
Vorbis (VBR) All platforms. Depends on libvorbis.
+
FSBANK_FORMAT_FADPCM
+
FMOD ADPCM (3.5:1) All platforms.
+
FSBANK_FORMAT_OPUS
+
Opus (VBR) Xbox Series X|S, PS5, and Switch. Depends on opus.
+
FSBANK_FORMAT_MAX
+
Upper bound for this enumeration, for use with validation.
+
+

See Also: FSBank_Build

+

20.16 FSBANK_FSBVERSION

+

Version of FSB to write out.

+

+

+
C
+
+

+
typedef enum FSBANK_FSBVERSION {
+  FSBANK_FSBVERSION_FSB5,
+  FSBANK_FSBVERSION_MAX
+} FSBANK_FSBVERSION;
+
+ +
+
FSBANK_FSBVERSION_FSB5
+
Produce FSB version 5 files.
+
FSBANK_FSBVERSION_MAX
+
Upper bound for this enumeration, for use with validation.
+
+

See Also: FSBank_Init

+

20.17 FSBANK_PROGRESSITEM

+

Status information describing the progress of a build.

+

+

+
C
+
+

+
typedef struct FSBANK_PROGRESSITEM {
+  int            subSoundIndex;
+  int            threadIndex;
+  FSBANK_STATE   state;
+  const void    *stateData;
+} FSBANK_PROGRESSITEM;
+
+ +
+
subSoundIndex
+
Index into the subsound list passed to FSBank_Build that this update relates to (-1 indicates no specific subsound).
+
threadIndex
+
Which thread index is serving this update (-1 indicates FSBank_Build / main thread).
+
state
+
Progress through the encoding process. (FSBANK_STATE)
+
stateData
+
Cast to state specific data structure for extra information.
+
+

See Also: FSBank_Build, FSBank_FetchNextProgressItem, FSBank_ReleaseProgressItem, FSBANK_STATE

+

20.18 FSBANK_RESULT

+

Error codes returned from every function.

+

+

+
C
+
+

+
typedef enum FSBANK_RESULT {
+  FSBANK_OK,
+  FSBANK_ERR_CACHE_CHUNKNOTFOUND,
+  FSBANK_ERR_CANCELLED,
+  FSBANK_ERR_CANNOT_CONTINUE,
+  FSBANK_ERR_ENCODER,
+  FSBANK_ERR_ENCODER_INIT,
+  FSBANK_ERR_ENCODER_NOTSUPPORTED,
+  FSBANK_ERR_FILE_OS,
+  FSBANK_ERR_FILE_NOTFOUND,
+  FSBANK_ERR_FMOD,
+  FSBANK_ERR_INITIALIZED,
+  FSBANK_ERR_INVALID_FORMAT,
+  FSBANK_ERR_INVALID_PARAM,
+  FSBANK_ERR_MEMORY,
+  FSBANK_ERR_UNINITIALIZED,
+  FSBANK_ERR_WRITER_FORMAT,
+  FSBANK_WARN_CANNOTLOOP,
+  FSBANK_WARN_IGNORED_FILTERHIGHFREQ,
+  FSBANK_WARN_IGNORED_DISABLESEEKING,
+  FSBANK_WARN_FORCED_DONTWRITENAMES,
+  FSBANK_ERR_ENCODER_FILE_NOTFOUND,
+  FSBANK_ERR_ENCODER_FILE_BAD,
+  FSBANK_WARN_IGNORED_ALIGN4K,
+} FSBANK_RESULT;
+
+ +
+
FSBANK_OK
+
No errors.
+
FSBANK_ERR_CACHE_CHUNKNOTFOUND
+
An expected chunk is missing from the cache, perhaps try deleting cache files.
+
FSBANK_ERR_CANCELLED
+
The build process was cancelled during compilation by the user.
+
FSBANK_ERR_CANNOT_CONTINUE
+
The build process cannot continue due to previously ignored errors.
+
FSBANK_ERR_ENCODER
+
Encoder for chosen format has encountered an unexpected error.
+
FSBANK_ERR_ENCODER_INIT
+
Encoder initialization failed.
+
FSBANK_ERR_ENCODER_NOTSUPPORTED
+
Encoder for chosen format is not supported on this platform.
+
FSBANK_ERR_FILE_OS
+
An operating system based file error was encountered.
+
FSBANK_ERR_FILE_NOTFOUND
+
A specified file could not be found.
+
FSBANK_ERR_FMOD
+
Internal error from FMOD sub-system.
+
FSBANK_ERR_INITIALIZED
+
Already initialized.
+
FSBANK_ERR_INVALID_FORMAT
+
The format of the source file is invalid.
+
FSBANK_ERR_INVALID_PARAM
+
An invalid parameter has been passed to this function.
+
FSBANK_ERR_MEMORY
+
Ran out of memory.
+
FSBANK_ERR_UNINITIALIZED
+
Not initialized yet.
+
FSBANK_ERR_WRITER_FORMAT
+
Chosen encode format is not supported by this FSB version.
+
FSBANK_WARN_CANNOTLOOP
+
Source file is too short for seamless looping. Looping disabled.
+
FSBANK_WARN_IGNORED_FILTERHIGHFREQ
+
FSBANK_BUILD_FILTERHIGHFREQ flag ignored: feature only supported by XMA format.
+
FSBANK_WARN_IGNORED_DISABLESEEKING
+
FSBANK_BUILD_DISABLESEEKING flag ignored: feature only supported by XMA format.
+
FSBANK_WARN_FORCED_DONTWRITENAMES
+
FSBANK_BUILD_FSB5_DONTWRITENAMES flag forced: cannot write names when source is from memory.
+
FSBANK_ERR_ENCODER_FILE_NOTFOUND
+
External encoder dynamic library not found
+
FSBANK_ERR_ENCODER_FILE_BAD
+
External encoder dynamic library could not be loaded, possibly incorrect binary format, incorrect architecture, file corruption
+
FSBANK_WARN_IGNORED_ALIGN4K
+
FSBANK_BUILD_ALIGN4K flag ignored: feature only supported by Opus, Vorbis, and FADPCM formats.
+
+

20.19 FSBANK_STATE

+

Current state during the build process.

+

+

+
C
+
+

+
typedef enum FSBANK_STATE {
+  FSBANK_STATE_DECODING,
+  FSBANK_STATE_ANALYSING,
+  FSBANK_STATE_PREPROCESSING,
+  FSBANK_STATE_ENCODING,
+  FSBANK_STATE_WRITING,
+  FSBANK_STATE_FINISHED,
+  FSBANK_STATE_FAILED,
+  FSBANK_STATE_WARNING
+} FSBANK_STATE;
+
+ +
+
FSBANK_STATE_DECODING
+
Decode a file to usable raw sample data.
+
FSBANK_STATE_ANALYSING
+
Scan sound data for details (such as optimized sample rate).
+
FSBANK_STATE_PREPROCESSING
+
Prepares sound data for encoder.
+
FSBANK_STATE_ENCODING
+
Pass the sample data to the chosen encoder.
+
FSBANK_STATE_WRITING
+
Write encoded data into an FSB.
+
FSBANK_STATE_FINISHED
+
Process complete.
+
FSBANK_STATE_FAILED
+
An error has occurred, check data (as FSBANK_STATEDATA_FAILED) for details.
+
FSBANK_STATE_WARNING
+
A warning has been issued, check data (as FSBANK_STATEDATA_WARNING) for details.
+
+

See Also: FSBANK_PROGRESSITEM

+

20.20 FSBANK_STATEDATA_FAILED

+

Extra failed state data.

+

+

+
C
+
+

+
typedef struct FSBANK_STATEDATA_FAILED {
+  FSBANK_RESULT   errorCode;
+  char            errorString[256];
+} FSBANK_STATEDATA_FAILED;
+
+ +
+
errorCode
+
Error result code. (FSBANK_RESULT)
+
errorString
+
Description for error code.
+
+

Cast stateData in FSBANK_PROGRESSITEM to this struct if the state is FSBANK_STATE_FAILED

+

20.21 FSBANK_STATEDATA_WARNING

+

Extra warning state data.

+

+

+
C
+
+

+
typedef struct FSBANK_STATEDATA_WARNING {
+  FSBANK_RESULT   warnCode;
+  char            warningString[256];
+} FSBANK_STATEDATA_WARNING;
+
+ +
+
warnCode
+
Warning result code. (FSBANK_RESULT)
+
warningString
+
Description for warning code.
+
+

Cast stateData in FSBANK_PROGRESSITEM to this struct if the state is FSBANK_STATE_WARNING

+

20.22 FSBANK_SUBSOUND

+

Representation of how to encode a single subsound in the final FSB.

+

+

+
C
+
+

+
typedef struct FSBANK_SUBSOUND {
+  const char* const   *fileNames;
+  const void* const   *fileData;
+  const unsigned int   *fileDataLengths;
+  unsigned int         numFiles;
+  FSBANK_BUILDFLAGS    overrideFlags;
+  unsigned int         overrideQuality;
+  float                desiredSampleRate;
+  float                percentOptimizedRate;
+} FSBANK_SUBSOUND;
+
+ +
+
fileNames
+
List of file names (instead of FSBANK_SUBSOUND::fileData) used to produce an interleaved sound. (UTF-8 string)
+
fileData
+
List of file data pointers (instead of FSBANK_SUBSOUND::fileNames) used to produce an interleaved sound.
+
fileDataLengths
+
List of file data lengths corresponding to the items in the FSBANK_SUBSOUND::fileData list.
+
numFiles
+
Number of items in either FSBANK_SUBSOUND::fileData / FSBANK_SUBSOUND::fileDataLengths or FSBANK_SUBSOUND::fileNames.
+
overrideFlags
+
Flags that will reverse the equivalent flags passed to FSBank_Build. (FSBANK_BUILDFLAGS)
+
overrideQuality
+
Override the quality setting passed to FSBank_Build.
+
desiredSampleRate
+
Resample to this sample rate (ignores optimize sample rate setting), up to 192000Hz.
+
percentOptimizedRate
+
If using FSBANK_BUILD_OPTIMIZESAMPLERATE, this is the percentage of that rate to be used, up to 100.0%.
+
+

Subsounds are generally used to encode a single audio file each. However, it is also possible to encode multiple audio files with a single subsound, in which case the audio data from each file will be interleaved when the subsound is encoded in the final FSB. The source files provided in this manner must have the same format and sample rate.

+

See Also: FSBank_Build, FSBANK_BUILD_OPTIMIZESAMPLERATE, FSBANK_BUILDFLAGS

+ + +
+ + + diff --git a/FMOD/doc/FMOD API User Manual/glossary.html b/FMOD/doc/FMOD API User Manual/glossary.html new file mode 100644 index 0000000..9acfc09 --- /dev/null +++ b/FMOD/doc/FMOD API User Manual/glossary.html @@ -0,0 +1,726 @@ + + +Glossary + + + + +
+ +
+

22. Glossary

+

22.1 2D vs 3D

+

A 3D sound source is a Channel that has a position and a velocity in space. When a 3D Channel is playing, its volume, speaker placement and pitch will be affected automatically based on the relation to the listener.

+

A listener is typically the location of the player or the game camera. It has a position and velocity like a sound source, but it also has an orientation.

+

3D Sound behaviour:

+
    +
  • Volume is affected by the relative distance of the listener and the source.
  • +
  • Pitch is affected by the relative velocity of the listener and the source (This causes the doppler effect).
  • +
  • Pan is affected by the relative orientation of the listener to the position of the source.
  • +
+

2D Sound behaviour:

+ +

Note: You can blend between a 3D mix and a 2D mix with ChannelControl::set3DLevel.

+

For a more detailed description of 3D sound behaviour, see the Spatializing Sounds in the Core API chapter.

+

22.2 Asset

+

An audio asset is a prerecorded sound that could potentially be used in a game. Assets can be loose audio files, or can be built into bank files or FSBs.

+

22.3 Audio channel

+

An audio channel is a monoaural signal generally associated with a particular speaker. For example, a stereo signal contains two channels, left and right. This is unrelated to the FMOD Channel class.

+

22.4 Automatic Parameter

+

An automatic parameter (also known in FMOD Studio as a built-in parameter) is any parameter whose value is automatically set based on the event instance's 3D attributes whenever the Studio system is updated.

+

Types of automatic parameter include:

+
    +
  • FMOD_STUDIO_PARAMETER_AUTOMATIC_DISTANCE
  • +
  • FMOD_STUDIO_PARAMETER_AUTOMATIC_EVENT_CONE_ANGLE
  • +
  • FMOD_STUDIO_PARAMETER_AUTOMATIC_EVENT_ORIENTATION
  • +
  • FMOD_STUDIO_PARAMETER_AUTOMATIC_DIRECTION
  • +
  • FMOD_STUDIO_PARAMETER_AUTOMATIC_ELEVATION
  • +
  • FMOD_STUDIO_PARAMETER_AUTOMATIC_LISTENER_ORIENTATION
  • +
  • FMOD_STUDIO_PARAMETER_AUTOMATIC_SPEED
  • +
  • FMOD_STUDIO_PARAMETER_AUTOMATIC_SPEED_ABSOLUTE
  • +
+

For more information about these parameter types, see the FMOD_STUDIO_PARAMETER_TYPE section of the Studio API Reference chapter.

+

22.5 Bank File

+

A bank file, or "bank," is a collection of content created in an FMOD Studio project, formatted and compressed for use with the version of the FMOD Engine integrated into in your game.

+

Bank files usually contain both metadata and sample data. However, it is also possible to create split banks whose sample data and metadata are in separate bank files. Splitting banks in this fashion slightly increases overhead at run time, but can help keep patch size low if it is ever necessary to release a patched version of your game that includes changes to the audio metadata but not the sample data.

+

Bank files are compatible with any version of the FMOD Engine with the same major and product version numbers as the version of FMOD Studio used to create them. For example, a bank built in FMOD Studio version 2.00.03 is compatible with FMOD Engine versions 2.00.03, 2.00.00, and 2.00.10, but not with versions 1.10.14, 1.00.03, and 2.01.03.

+

At least one bank in any FMOD Studio project is a master bank. A master bank contains data relevant to your entire FMOD Studio project, and so at least one master bank must be loaded into memory before any event in any bank may be used by your game. Most games have a single master bank that is kept loaded into memory at all times.

+

Bank files (.bank) should not be confused with FMOD Sample Bank files (.fsb). They are two different formats.

+

For more information about using bank files in the FMOD Engine, see the Bank Layout, Bank Loading, and Bank Unload sections of the Studio API Guide chapter, as well as the Studio::Bank subchapter of the Studio API Reference chapter.

+

22.6 Callback Behavior

+

Only one callback is stored for each System/Studio::System/Studio::EventInstance/ChannelControl/DSP. Therefore, any registered callback should handle all required callback types and indicate those types via the callback type mask.

+

All calls to callbacks are issued per type. This means that if, for example, you use System::setCallback with FMOD_SYSTEM_CALLBACK_ALL, when the callback is called, only one type will be passed for the type argument. Multiple types will not be combined for a single call.

+

C/C++ behavior. Casting your own function type to an FMOD callback could cause a crash or corruption. For callback declaration always use F_CALL between the return type and the function name, and use the correct C types for all callback parameters.

+

22.7 Channel Group

+

A channel group allows attributes to be set on a group of channels collectively. A channel group also allows you to operate on a the final mixed signal of the output of its channels and child channel groups. This is known as a 'sub mix'.

+

A channel group can be created with System::createChannelGroup, which returns a ChannelGroup object.

+

The sub mix buffer can be processed with effects (see ChannelControl::addDSP), saving CPU time compared to applying the same effect to multiple channels individually.

+

The signal processing of a channel group persists even when a channel has stopped.

+

A channel group can contain many children channel groups, but can only have one parent channel group. See ChannelGroup::addGroup and ChannelGroup::getParentGroup.

+

22.8 Channel

+

A Channel is a playing instance of a Sound. This is unrelated to an audio channel.

+

After loading or creating a Sound, it is playable via the System::playSound command which returns a Channel object for run-time manipulation of its properties.

+

FMOD automatically selects a Channel for the sound to play on, you do not have to manage your own Channels.

+

Set the maximum number of Channels playable with System::init. For more information on Channels and how they can be real or virtual, see the Virtual Voice System section of the Managing Resources in the Core API chapter.

+

22.9 Compressed Sample

+

Parent topic : Sound

+

Compressed Samples are suited for small sounds that need to be played more than once at a time, for example sound effects.

+

Only certain file formats are supported with this type of sound. File formats such as .MP2, .MP3, and .FSB (using FADPCM, Vorbis, AT9 and XMA codecs).
+This type of sound is stored in memory in its native compressed format, and decodes in real-time while playing.

+

Use FMOD_CREATECOMPRESSEDSAMPLE to create a Sound object in this mode.

+ + + + + + + + + + + + + + + + + + + + + + + + + +
Compressed Sample attributesComparison
Keeps sound compressed into memory.Can use less memory than a sample, large sounds can use more than a stream.
Higher CPU overhead during playback.Uses more CPU than a sample, slightly less than a stream.
Fast to load.Faster than a sample, possibly slower than a stream with very large sounds.
Can play more than 1 at a time.Better polyphony than a stream.
+

Note: Compressed samples have a context allocated for each instance of playback. This requires a fixed start up memory overhead. See FMOD_ADVANCEDSETTINGS to control codec maximums.

+

22.10 Documentation Conventions

+

22.10.1 Parameter Tokens

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
TokenMeaning
OutThe API function will fill in information in this parameter.
OptThis parameter is optional, specify null or zero to ignore.
R/OThis token applies to members of various structures which FMOD passes to user callbacks. User callbacks must not modify the values of these members. Modifying the values of these members will cause undefined behavior.
C#This is only available in C#.
JSThis is only available in Javascript.
+

22.11 Core API Profiler Tool

+

The core API profiler tool, also known as the FMOD Profiler or FMOD Profiler.exe, is a tool for profiling your game's DSP graph and performance. It can be found in the /bin directory of the FMOD Engine distribution.

+

To profile your game with the core API profiler tool, you must specify FMOD_INIT_PROFILE_ENABLE when initializing the Core API. For more information about initialization flags, see the FMOD_INITFLAGS section of the Core API Reference chapter.

+

22.12 Core API

+

The Core API is a programmer API that allows the manipulation of low-level audio primitives, and is the backbone of the FMOD Engine.

+

Unlike the Studio API, the Core API is a standalone solution that allows you to implement every part of your game's audio using only code, and does not require the use of FMOD Studio to design audio content. However, while it is more powerful than the Studio API, it includes fewer convenience functions, and so is best used in games that require more flexibility than the Studio API can provide.

+

The Core API and Studio API together comprise the FMOD Engine.

+

For more information about the Core API, see the Core API Concepts and Core API Reference chapters.

+

22.13 Distance Units

+

The unit of measurement for distances for 3D calculations. By default 1 disance unit is equivalent to 1 meter. To use your game's distance units specify the scale of your game's distance units to meters using System::set3DSettings.

+

22.14 Down Mixing

+

When the source signal channel count is higher than the destination, it will distribute its higher channel information into the lower speaker mode's channels.
+This example is a table of the speakers in a stereo output with the input speakers of a 7.1 signal. Values in table represent attenuation. 0dB = full volume, - = silence.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Output speakerFront left inFront right inCenter inLFE inSurround left inSurround right inBack left inBack right in
Left0dB--3dB--3dB--6dB-
Right-0dB-3dB---3dB--6dB
+

Example of a higher 7.1 speaker mode signal being down mixed to a stereo output. When more than one input channel contributes to the output speaker, the inputs are summed/mixed together.

+

22.15 DSP Chain

+

A DSP chain is a type of DSP sub-graph in which multiple DSP units are connected together in a linear fashion. Each Channel and ChannelGroup contains a DSP chain.

+

A DSP is capable of multiple inputs, but in a DSP chain each DSP is connected to the next with one input, all the way from the tail to the head. See FMOD_CHANNELCONTROL_DSP_INDEX for special named offsets for 'head' and 'tail' and 'fader' units.

+

DSP Chain

+

A typical Channel is represented above, with a node at the 'head' (of type FMOD_DSP_TYPE_FADER to allow volume control and panning), which is fed by an echo effect (of type FMOD_DSP_TYPE_ECHO) which is in turn fed by a PCM wavetable unit (of type that is internal to FMOD) at the 'tail'. The signal feeds from right to left to the DSP chain's head, before continuing to the next connected DSP (not pictured).

+

22.16 DSP Clock

+

Each DSP unit has an associated DSP clock. The speed of this clock affects any time-based behavior the DSP has, such that a DSP with a faster DSP clock will change the way it processes the signal more rapidly than one with a slower clock.

+

By default, all DSP clocks run at the same speed, helping ensure that different channels and channel groups remain synchronized. However, if a channel or channel group is subject to pitch adjustment, the DSP clocks associated with that channel or channel group may run at a faster or slower rate in order to account for the time stretching inherent to pitch changes.

+

DSP clocks are used for scheduling various time-based behaviors, including those of ChannelControl::setDelay in the Core API and modulators in FMOD Studio.

+

22.17 DSP Effect

+

A DSP effect is an effect that makes use of a DSP unit.

+

22.18 DSP Engine

+

The DSP engine is the portion of the FMOD Engine that traverses, executes, and mixes the DSP graph.

+

For more information about the DSP engine, see the DSP Architecture and Usage section of the Using DSP Effects in the Core API chapter.

+

22.19 DSP Graph

+

The DSP graph is made of DSP units linked together into a network by DSPConnections. Audio signals originate and flow through the DSP graph, being processed by the DSP units they pass through and combined into a submix whenever multiple DSPConnections target the same DSP unit, until they arrive at an output. The DSP graph allows audio to be dynamically processed and mixed, and so is the foundation of all dynamic game audio in FMOD.

+

Normally, an FMOD project has one DSP graph. Sections of a DSP graph may be referred to as sub-graphs for the purpose of easy discussion.

+

An FMOD project's DSP graph may be viewed by using the FMOD Profiler, as long as you specify FMOD_INIT_PROFILE_ENABLE when initializing the Core API.

+

For more information about DSP graphs, see the DSP Architecture and Usage section of the Using DSP Effects in the Core API chapter.

+

22.20 DSP Sub-graph

+

A DSP sub-graph is an arbitrary subset of the DSP units and DSPConnections in a DSP graph. They are not represented in code; rather, they are a useful abstraction when discussing a project's DSP interactions, as they are easier to conceptualize of than the entire DSP graph.

+

22.21 DSP

+

DSP stands for "Digital Signal Processing", and usually relates to processing raw PCM samples to alter the sound. A DSP unit (or just "a DSP") is a modular node in the DSP graph that's capable of a specific kind of digital signal processing. Many DSPs are used in effects, or to process audio in other situations.

+

DSPs can be added to an FMOD Channel, or ChannelGroup with the ChannelControl::addDSP function.

+

FMOD provides a suite of DSPs that can alter sounds in interesting ways, such as better simulating real-world sound behavior or exaggerating sounds. Examples of such DSPs include the echo, SFX reverb, IT low pass, flange, and chorus DSPs.

+

You can also write your own DSPs by using System::createDSP. For more information about writing DSPs, see the DSP subchapter of the Plug-in API Reference chapter.

+

22.22 Effect

+

In the FMOD Engine, an effect is a modular unit that manipulates a signal in some way. Most effects are DSP effects, which is to say, they use digital signal processing units to alter the signal.

+

The effects included in the FMOD Engine are detailed in the Effects Reference chapter.
+Many FMOD Engine effects also exist as FMOD Studio effects, though not all.

+

22.23 FMOD Engine

+

The FMOD Engine is a runtime library for playing adaptive audio in games. It consists of two APIs: The Studio API, and the Core API. Content created in FMOD Studio can be built as .bank files, which can then be loaded and played in the FMOD Engine using the Studio API. The Core API allows audio programmers to create audio content without using FMOD Studio, and to interact with the FMOD Engine's underlying mechanisms.

+

For more information about the FMOD Engine, see the FMOD Engine User Manual. You're reading it right now.

+

22.24 FMOD for Unity

+

FMOD for Unity is a packaged software integration of the FMOD Engine for use with the Unity game engine. This integration makes it possible use dynamic audio content created in FMOD Studio in your Unity game.

+

FMOD for Unity includes a full copy of the FMOD Engine, so it is not necessary to install the FMOD Engine separately.

+

For detailed guidance on FMOD for Unity, see our Unity Integration documentation.

+

22.25 FMOD for Unreal Engine

+

FMOD for Unreal Engine is a packaged software integration of the FMOD Engine for use with the Unreal Engine game engine. This integration makes it possible use dynamic audio content created in FMOD Studio in your Unreal Engine game.

+

FMOD for Unreal Engine includes a full copy of the FMOD Engine, so it is not necessary to install the FMOD Engine separately.

+

For detailed guidance on FMOD for Unreal Engine, see our Unreal Engine Integration documentation.

+

22.26 FMOD Studio

+

FMOD Studio is an application that allows sound designers and composers to create adaptive audio content for games. Content created in FMOD Studio can be built as .bank files, which can then be loaded and played in the FMOD Engine using the Studio API.

+

For more information about FMOD Studio, see the FMOD Studio User Manual.

+

22.27 FSB

+

.fsb files (also known as "FMOD Soundbanks" or "FSBs") are a proprietary file format that acts as a container for encoded and compressed sample data. They are built using FSBank API or the FMOD Soundbank Generator tool that comes packaged with the FMOD Engine, and their content can be loaded and played using the Core API.

+

.fsb files should not be confused with the .bank files built in FMOD Studio. Unlike FMOD Studio's .bank files, .fsb files cannot contain event or mixer metadata, but their sampledata can be loaded and played using the Core API without needing the Studio API. In most cases, if your game uses the Studio API, you should use .bank files; whereas if your game uses only the Core API, you should use .fsb files.

+

The FMOD Engine is compatible with all .fsb files built using the FSBank API and the FMOD Soundbank Generator tool that comes packaged with the FMOD Engine. .fsb files that were instead built using older tools (such as FMOD Designer, FMOD Ex, or versions of the FMOD Soundbank Generator tool distributed with FMOD Ex) use older, deprecated codecs, and so are not compatible with the FMOD Engine.

+

22.28 GUID

+

A GUID is a unique string used to identify a digital object, and stands for Globally Unique Identifier. In the FMOD Engine, GUIDs are commonly used to invoke and define relationships between the various elements of a project. For example, every event, asset, bus, parameter, snapshot, effect, bank, and instrument in an FMOD Studio project has a GUID, and each such object's metadata includes the GUIDs of other objects that it references or is referenced by.

+

Certain APIs allow you to specify which object to affect by GUID. For example, Studio::System::getEventByID gets the eventDescription of an event with a specified GUID.

+

GUIDs are a form of metadata. The GUID structure used by the FMOD Engine is defined by FMOD_GUID.

+

22.29 Handedness

+

Handedness is an innate property of 3D cartesian coordinate systems. The handedness of the coordinate system specifies the relative direction of the Z axis along the line perpendicular to the X and Y axes, and the direction of positive rotations when an axis is directed towards the point of view.

+

When the X axis is directed to the right, and the Y axis is directed upwards:

+
    +
  • A left-handed coordinate system's Z is directed away from the point of view, and rotations in the positive direction are clockwise.
  • +
  • A right-handed coordinate system's Z axis is directed towards the point of view, and rotations in the positive direction are counter-clockwise.
  • +
+

For 3D spatialization to behave intuitively, it is important that FMOD is configured to use the same orientation as your game's coordinate system. By default FMOD uses a left-handed coordinate system, but FMOD may also be configured to use a right-handed coordinate system by passing FMOD_INIT_3D_RIGHTHANDED to System::init.

+

22.30 Loading Mode

+

The loading mode of an asset is the way in which that asset's sample data is loaded into memory so that it can be played. There are three possible loading modes:

+
    +
  • Compressed. In this mode, the asset's sample data is loaded into memory in a compressed format in advance of its being played. This sample data is then decompressed in real time whenever an instance of the asset is played. This mode requires less memory than decompressed loading mode, but requires more CPU to play the loaded asset.
  • +
  • Decompressed. In this mode, the asset's sample data is loaded into memory in a decompressed format in advance of being played. This mode requires more memory than compressed loading mode, but does not require as much CPU to play the loaded asset.
  • +
  • Streaming. In this mode, each playing instance of the asset requires a separate stream. Each stream is a ring buffer; the asset associated with a stream is loaded piecemeal from disk into the buffer, and each piece is played as soon as it is loaded then immediately overwritten by the next piece. Because only a small part of the asset is loaded into memory at any given time, streaming assets require only a small amount of memory compared to the other loading modes. However, because each instance of a streaming asset requires a separate buffer that loads the asset independently, each contemporaneously playing instance of an asset with this loading mode requires constant file I/O.
  • +
+

For more information about loading assets in the FMOD Engine, see the Sample Data Loading section of the Studio API Guide chapter. For more information about the streaming loading mode specifically, see the Streams section of the Loading and Playing Sounds in the Core API chapter.

+

22.31 Metadata

+

Metadata is data that describes other data. In FMOD Studio and the FMOD Engine, "metadata" usually means the data that describes how sample data is to be used in a game, i.e.: the data that defines an FMOD Studio project's events, mixer, and other non-sample data content. This kind of metadata is packaged into bank files whenever a project is built in FMOD Studio.

+

22.32 Mixer

+

See DSP graph.

+

22.33 Reading Sound Data

+

The following shows how to read sound data to a buffer using Sound::readData.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
FMOD::Sound *sound;
+unsigned int length;
+char *buffer;
+
+system->createSound("drumloop.wav", FMOD_DEFAULT | FMOD_OPENONLY, nullptr, &sound);
+sound->getLength(&length, FMOD_TIMEUNIT_RAWBYTES);
+
+buffer = new char[length];
+sound->readData(buffer, length, nullptr);
+
+delete[] buffer;
+
+ +
FMOD_SOUND *sound;
+unsigned int length;
+char *buffer;
+
+FMOD_System_CreateSound(system, "drumloop.wav", FMOD_DEFAULT | FMOD_OPENONLY, 0, &sound);
+FMOD_Sound_GetLength(sound, &length, FMOD_TIMEUNIT_RAWBYTES);
+
+buffer = (char *)malloc(length);
+FMOD_Sound_ReadData(sound, (void *)buffer, length, 0);
+
+free(buffer);
+
+ +
FMOD.Sound sound;
+uint length;
+byte[] buffer;
+
+system.createSound("drumloop.wav", FMOD.MODE.DEFAULT | FMOD.MODE.OPENONLY, out sound);
+sound.getLength(out length, FMOD.TIMEUNIT.RAWBYTES);
+
+buffer = new byte[(int)length];
+sound.readData(buffer);
+
+ +
var sound = {};
+var length = {};
+var buffer = {};
+
+system.createSound("drumloop.wav", FMOD.DEFAULT | FMOD.OPENONLY, null, sound);
+sound = sound.val;
+
+sound.getLength(length, FMOD.TIMEUNIT_RAWBYTES);
+length = length.val;
+
+sound.readData(buffer, length, null);
+buffer = buffer.val;
+
+ +

See Also: FMOD_TIMEUNIT, FMOD_MODE, Sound::getLength, System::createSound

+

22.34 Sample Data

+

Sample data is raw (PCM) or a compressed audio signal, stored as a sound. Multi-channel PCM sample data (stereo and above) is interleaved, so a 5.1 signal for example has 6 values stored together per sample.

+

22.34.1 Endianness

+

When accessing raw data in a sound, it will be in the native endianness of the platform. See Sound::lock, Sound::unlock.
+When a sound file is loaded, FMOD will convert the endian to match the native endian of the platform.

+

22.34.2 Sample Formats

+

Sample data can come in a variety of PCM bit depths (8,16,24,32) and types (integer, float), or as a compressed bitstream. See FMOD_SOUND_FORMAT.

+

22.34.3 Samples vs Bytes vs Milliseconds

+

Within FMOD functions you will see references to PCM samples, bytes and milliseconds.

+

To understand what the difference is a diagram has been provided to show how raw PCM sample data is stored in FMOD buffers.

+

Samples vs Bytes vs Milliseconds

+

In this diagram you will see that a stereo sound has its left/right data interleaved one after the other.
+A left/right pair (a sound with 2 channels) is called a sample.
+Because this is made up of 16bit data, 1 sample = 4 bytes.
+If the sample rate, or playback rate is 44.1khz, or 44100 samples per second, then 1 sample is 1/44100th of a second, or 1/44th of a millisecond. Therefore 44100 samples = 1 second or 1000ms worth of data.
+To convert between the different terminologies, the following formulas can be used:

+
    +
  • ms = samples * 1000 / samplerate.
  • +
  • samples = ms * samplerate / 1000.
  • +
  • samplerate = samples * 1000 / ms.
  • +
  • bytes = samples * bits * channels / 8.
  • +
  • samples = bytes * 8 / bits / channels.
  • +
+

Some functions like Sound::getLength provide the length in milliseconds, bytes and samples to avoid needing to do these calculations.

+

22.35 Sample

+

Parent topic : Sound

+

Samples (also referred to as 'decompress into memory' type sounds), are suited for small sounds that need to be played more than once at a time, for example sound effects.

+

Use FMOD_CREATESAMPLE to create a Sound object in this mode.

+ + + + + + + + + + + + + + + + + + + + + + + + + +
Sample attributesComparison
Decompresses whole sound into memory.Can use more memory than a compressed sample or stream.
Low CPU overhead during playback.Uses less CPU than a compressed sample or stream.
Slower to load.Can take longer to load on large sounds than a compressed sample or stream.
Can play more than 1 at a time.Better polyphony than a stream.
+

Mobile Developers: A common use for this format is to store files compressed on disk (for faster download speed), then decompress into memory at load time, for lower cpu overhead at run-time.

+

22.36 Signal

+

The signal is an abstraction of the audio sample data flowing through an FMOD project. Understanding how signals flow through a project is necessary to understand how the DSP graph and mixing work.

+

In most cases, signals originate from channels, which route their output signals into channel groups. Each channel group creates a submix of all the signals flowing into it. Channels and channel groups may feature DSPs that process the signal before passing it to the next DSP in the graph associated with that channel group; when there are no DSPs left in the channel group, the signal is routed from that channel group to that channel group's routing destination. All signals should eventually flow to the master channel group or an audio port supplied by an FMOD_OUTPUTTYPE plug-in.

+

22.37 Sound

+

A sound is an instance of sample data which can be loaded from media, or created from memory.

+

When a sound is loaded, it is either decompressed as a static sample into memory as PCM (sample), loaded into memory in its native format and decompressed at runtime (compressed sample), or streamed and decoded in realtime (in chunks) from an external media such as a disk or internet (stream).

+

For more detail see:

+ +

A sound can be created with System::createSound or System::createStream which returns a Sound object. A Sound object can be played with System::playSound.

+

22.38 Streaming Sample Data

+

Streaming sample data is sample data formatted for the streaming loading mode. The distinction between streaming sample data and non-streaming sample data is only extant when using the Studio API to play content from bank files, as the loading mode of assets in a bank file is encoded into that bank file along with those assets. When using the Core API, the loading mode of a sound is specified at run time.

+

When using the Core API, the loading mode of a sound is specified at run time.

+

For more information about streaming, see the Streams section of the Loading and Playing Sounds in the Core API chapter.

+

22.39 Stream

+

Parent topic : Sound

+

A stream is good for a sound that is too large to fit into memory. A stream reads from disk or other media like the internet as it plays.

+

Typically suited to larger sounds like music, long ambiences, or voice.

+

Use FMOD_CREATESTREAM to create a Sound object in this mode.

+ + + + + + + + + + + + + + + + + + + + + + + + + +
'Stream' attributesComparison
Uses a small buffer in memory.Uses less memory than a sample or compressed sample on large sounds.
Higher CPU overhead during playback.Uses more CPU than sample, slightly more than a compressed sample due to simultaneous reading from medium.
Fast to load.Faster than a sample on large sounds, possibly faster than a compressed sample with very large sounds.
Can only be played once at a time.Worse polyphony than a sample or compressed sample.
+

Note: A very small sound may use more memory than a sample or compressed sample when created as a stream, due to the stream file/decode buffer overhead being bigger than the size of the sound.

+

22.39.1 Streaming Issues

+

Bandwidth

+

Streaming audio from a medium should be kept to a limited number of instances, to avoid starvation of data leading to skipping / stuttering audio.

+

Increasing stream memory buffer sizes can help to mitigate this problem. See System::setStreamBufferSize and FMOD_ADVANCEDSETTINGS::defaultDecodeBufferSize.

+

Speed of commands using streams

+

System::createStream, Channel::setPosition and Sound::getSubSound when using a stream can take longer than an in memory sample, as they have to initialize internal buffers and flush them from disk.

+

Use FMOD_NONBLOCKING command to remove the cost from the main thread and put the overhead into a background thread.

+

Setting loop counts or points of a playing stream

+

Issues with looping streaming sounds may arise when changing the loop count or loop points of a playing stream.

+

Sounds created with System::createStream or FMOD_CREATESTREAM may have executed loop logic and buffered sample data before API calls to change their looping properties. If issues occur after changing loop properties you may need to call Channel::setPosition to force a flush of the stream buffer.

+

Note this will usually only happen if you have sounds or loop regions which are smaller than the stream decode buffer. See FMOD_CREATESOUNDEXINFO.

+

22.40 String Format

+

All FMOD Public APIs and structures use UTF-8 strings.

+

As C# uses UTF-16 strings by default, the FMOD C# api function parameters will automatically convert between UTF-16 and UTF-8 strings in any api using the C# "string" type or FMOD's "StringWrapper" type. However, any API that uses strings via an IntPtr will not automatically convert from UTF-16, and will instead expect a UTF-8 string to be used.

+

22.41 Studio API

+

The Studio API is a programmer API that allows your game to interact with data-driven projects created in FMOD Studio at run time. The Studio API and Core API together comprise the FMOD Engine.

+

The Studio API is built on top of the Core API, and extends its functionality. FMOD Studio and the Studio API are flexible and powerful enough to suit the audio needs of the vast majority of games. However, if a specific game requires more flexibility than the Studio API provides, we recommend using the Core API instead.

+

For more information about the Studio API, see the Studio API Guide and Studio API Reference chapters.

+

22.42 Studio GUIDs and Paths

+

Many functions in the Studio API allow you to identify an object within an FMOD Studio project by the object's globally unique identifier, or GUID. These API functions will accept the GUID in binary format (mostly useful when an object's GUID has been looked up programmatically by name), or as a string formatted as 32 digits separated by hyphens and enclosed in braces: {00000000-0000-0000-0000-000000000000}.

+

Many functions in the Studio API allow you to identify an object within an FMOD Studio project by the object's path. Objects can only be identified by path if the project's strings bank is loaded.

+

See the FMOD Studio User Manual for more information.

+

22.43 Studio Strings Bank

+

When building a master bank, FMOD Studio also writes out a strings bank for the project. The strings bank contains a string table which the Studio API can use to resolve GUIDs from paths. Studio API functions which accept paths require the project's strings bank to be loaded in order to function correctly.

+

22.44 Studio Update Thread

+

A thread created by the Studio System to perform asynchronous processing of API commands and manage scheduling and playback logic for events. This thread is triggered from the core mixer thread at the period specified in the FMOD_STUDIO_ADVANCEDSETTINGS. If the studio system is initialized with FMOD_STUDIO_INIT_SYNCHRONOUS_UPDATE then no studio update thread is created.

+

22.45 Subsound

+

A subsound is a one of several distinct, independently playable audio assets that together comprise a loaded or streaming sound.

+

To have subsounds, a sound must be in a container format such as FSB, DLS, MOD, S3M, XM, or IT. Sounds in other formats are composed of a single asset, and do not have subsounds.

+

Because the loading unit for audio assets is the sound, subsounds cannot be loaded independently of their associated sound, and loading a sound loads all of the subsounds of that sound.

+

Because a stream can only play one asset at a time, a streaming sound with subsounds can only play one of those subsounds at a time. If you want to stream multiple subsounds of a sound at once, you must create a separate streaming sound for each of them.

+

22.46 Sync Points

+

A sync point can be used to trigger a callback during playback. See FMOD_CHANNELCONTROL_CALLBACK_SYNCPOINT.
+These points can be user generated via the API or can come from a .wav file with embedded markers.

+

Markers can be added to a wave file in a sound editor usually by clicking on a waveform or timeline and inserting a 'marker' or 'region'.

+

Any RIFF based format will support sync points.

+

Sync points can be manipulated with:

+ +

22.47 System

+

This can refer to either the Core API's System class, the Studio API's Studio::System class, or an object derived from one of those classes.

+

The System class is the heart of the FMOD Engine. Nearly all Core API features depend on a System object existing, and will not work if it has not yet been created.

+

The Studio::System class is built on top of the System class. Nearly all Studio API features depend on a Studio::System object existing, and will not work if it has not yet been created.

+

Your game should create a Studio::System object if it uses the Studio API. If your game uses only the Core API, it should create a System object instead.

+

For information about using the Core API's System class, see the Core API Getting Started chapter. For more information about using the Studio API's Studio::System class, see the Studio API Getting Started chapter.

+

22.48 Up Mixing

+

When the source signal channel count is lower than the destination, it will distribute its lower channel information into the higher speaker mode's channels.
+This example is a table of the different source signal speaker modes, mapping to a 7.1 output. Values in table represent attenuation. 0dB = full volume, - = silence.

+
Key: M = Mono, L = Left, R = Right, FL = Front Left, FR = Front Right, C = Center, LFE = Low Frequency Emitter, SL = Surround Left, SR = Surround Right, BL = Back Left, BR = Back Right
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Output SpeakerMono sourceStereo sourceQuad source5.0 source5.1 source7.1 source
Front leftM = -3dBL = 0dBFL = 0dBFL = 0dBFL = 0dBFL = 0dB
Front rightM = -3dBR = 0dBFR = 0dBFR = 0dBFR = 0dBFR = 0dB
Center---C = 0dBC = 0dBC = 0dB
LFE----LFE = 0dBLFE = 0dB
Surround left--SL = 0dBSL = 0dBSL = 0dBSL = 0dB
Surround right--SR = 0dBSR = 0dBSR = 0dBSR = 0dB
Back left-----BL = 0dB
Back right-----BR = 0dB
+

Example of lower and equal speaker modes up mixing to a target speaker mode = 7.1

+

22.49 User Data

+

User data is arbitrary data that can be attached to various FMOD objects. User data is stored without a type, in the form of a void * in C/C++, IntPtr in C# or an object in javascript. User data can then be retrieved and cast back to the original type. The following shows how to set and get user data on a Sound, but can be likewise applied to any object with a getUserData or setUserData method.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
{
+    const char *userData = "Hello User Data!";
+    void *pointer = (void *)userData;
+    sound->setUserData(pointer);
+}
+{
+    void *pointer;
+    sound->getUserData(&pointer);
+    const char *userData = (const char *)pointer;
+}
+
+ +
{
+    const char *userData = "Hello User Data!";
+    void *pointer = (void *)userData;
+    FMOD_Sound_SetUserData(object, pointer);
+}
+{
+    void *pointer;
+    FMOD_Sound_GetUserData(object, &pointer);
+    const char *userData = (const char *)pointer;
+}
+
+ +
{
+    string userData = "Hello User Data!";
+    GCHandle handle = GCHandle.Alloc(userData);
+    IntPtr pointer = GCHandle.ToIntPtr(handle);
+    sound.setUserData(pointer);
+}
+{
+    IntPtr pointer;
+    sound.getUserData(out pointer);
+    GCHandle handle = GCHandle.FromIntPtr(pointer);
+    string userData = handle.Target as string;
+}
+
+ +
{
+    var userData = "Hello User Data!";
+    sound.setUserData(userData);
+}
+{
+    var outval = {};
+    sound.getUserData(outval);
+    var userData = outval.val;
+}
+
+ +

22.50 Version

+

The version number of an FMOD product. Version numbers are split into three parts, in the format: productVersion.majorVersion.minorVersion. For example, the version 1.23.45 would indicate product version 1, major version 23, and minor version 45 of that major version.

+

Major versions contain significant changes, add new features, and may affect bank compatibility. Updating to a new major version usually requires project migration. New major versions may change playback behavior in some cases.

+

Minor versions, also known as patch versions, contain bug fixes and smaller workflow improvements.

+

Built bank files are compatible with any version of the FMOD Engine with the same major and product version numbers as the version of FMOD Studio used to create them. For example, a bank built in FMOD Studio version 2.00.03 is fully compatible with FMOD Engine versions 2.00.03, 2.00.00, and 2.00.10, but not with versions 1.10.14, 1.00.03, and 2.01.03.

+

In addition, a bank built by a given major version of FMOD Studio can be loaded by any later major version of the FMOD Engine. However, because new major engine versions frequently include minor changes to behavior, banks loaded in later major versions may behave exhibit small changes in bahvior in some circumstances. For example, banks created in FMOD Studio version 1.10.xx can be loaded in FMOD Engine versions 2.00.xx or 2.01.xx, but might sound slightly different in those versions than in 1.10.xx.

+ + +
+ + + diff --git a/FMOD/doc/FMOD API User Manual/images/3d-reverb.png b/FMOD/doc/FMOD API User Manual/images/3d-reverb.png new file mode 100644 index 0000000..821b21e Binary files /dev/null and b/FMOD/doc/FMOD API User Manual/images/3d-reverb.png differ diff --git a/FMOD/doc/FMOD API User Manual/images/3d-studio-1.png b/FMOD/doc/FMOD API User Manual/images/3d-studio-1.png new file mode 100644 index 0000000..3bb173e Binary files /dev/null and b/FMOD/doc/FMOD API User Manual/images/3d-studio-1.png differ diff --git a/FMOD/doc/FMOD API User Manual/images/3d-studio-2.png b/FMOD/doc/FMOD API User Manual/images/3d-studio-2.png new file mode 100644 index 0000000..bb2e517 Binary files /dev/null and b/FMOD/doc/FMOD API User Manual/images/3d-studio-2.png differ diff --git a/FMOD/doc/FMOD API User Manual/images/3d-studio-3.png b/FMOD/doc/FMOD API User Manual/images/3d-studio-3.png new file mode 100644 index 0000000..6d5f201 Binary files /dev/null and b/FMOD/doc/FMOD API User Manual/images/3d-studio-3.png differ diff --git a/FMOD/doc/FMOD API User Manual/images/dsp-chain.png b/FMOD/doc/FMOD API User Manual/images/dsp-chain.png new file mode 100644 index 0000000..7a302c3 Binary files /dev/null and b/FMOD/doc/FMOD API User Manual/images/dsp-chain.png differ diff --git a/FMOD/doc/FMOD API User Manual/images/dsp-channelmix-grouping.svg b/FMOD/doc/FMOD API User Manual/images/dsp-channelmix-grouping.svg new file mode 100644 index 0000000..e58c354 --- /dev/null +++ b/FMOD/doc/FMOD API User Manual/images/dsp-channelmix-grouping.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/FMOD/doc/FMOD API User Manual/images/dsp-channelmix-levels.svg b/FMOD/doc/FMOD API User Manual/images/dsp-channelmix-levels.svg new file mode 100644 index 0000000..a94b774 --- /dev/null +++ b/FMOD/doc/FMOD API User Manual/images/dsp-channelmix-levels.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/FMOD/doc/FMOD API User Manual/images/dsp-channelmix-routing.svg b/FMOD/doc/FMOD API User Manual/images/dsp-channelmix-routing.svg new file mode 100644 index 0000000..b57f3f1 --- /dev/null +++ b/FMOD/doc/FMOD API User Manual/images/dsp-channelmix-routing.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/FMOD/doc/FMOD API User Manual/images/dsp-chorus-wave.svg b/FMOD/doc/FMOD API User Manual/images/dsp-chorus-wave.svg new file mode 100644 index 0000000..c88e35d --- /dev/null +++ b/FMOD/doc/FMOD API User Manual/images/dsp-chorus-wave.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/FMOD/doc/FMOD API User Manual/images/dsp-compressor.svg b/FMOD/doc/FMOD API User Manual/images/dsp-compressor.svg new file mode 100644 index 0000000..4cfd95c --- /dev/null +++ b/FMOD/doc/FMOD API User Manual/images/dsp-compressor.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/FMOD/doc/FMOD API User Manual/images/dsp-convolution-impulse.svg b/FMOD/doc/FMOD API User Manual/images/dsp-convolution-impulse.svg new file mode 100644 index 0000000..66c12aa --- /dev/null +++ b/FMOD/doc/FMOD API User Manual/images/dsp-convolution-impulse.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/FMOD/doc/FMOD API User Manual/images/dsp-delay-wave.svg b/FMOD/doc/FMOD API User Manual/images/dsp-delay-wave.svg new file mode 100644 index 0000000..9c14744 --- /dev/null +++ b/FMOD/doc/FMOD API User Manual/images/dsp-delay-wave.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/FMOD/doc/FMOD API User Manual/images/dsp-distortion-wave.svg b/FMOD/doc/FMOD API User Manual/images/dsp-distortion-wave.svg new file mode 100644 index 0000000..8c6c4ed --- /dev/null +++ b/FMOD/doc/FMOD API User Manual/images/dsp-distortion-wave.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/FMOD/doc/FMOD API User Manual/images/dsp-echo-wave.svg b/FMOD/doc/FMOD API User Manual/images/dsp-echo-wave.svg new file mode 100644 index 0000000..d676c7e --- /dev/null +++ b/FMOD/doc/FMOD API User Manual/images/dsp-echo-wave.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/FMOD/doc/FMOD API User Manual/images/dsp-fft-blackman.png b/FMOD/doc/FMOD API User Manual/images/dsp-fft-blackman.png new file mode 100644 index 0000000..4264896 Binary files /dev/null and b/FMOD/doc/FMOD API User Manual/images/dsp-fft-blackman.png differ diff --git a/FMOD/doc/FMOD API User Manual/images/dsp-fft-blackmanharris.png b/FMOD/doc/FMOD API User Manual/images/dsp-fft-blackmanharris.png new file mode 100644 index 0000000..a40b36b Binary files /dev/null and b/FMOD/doc/FMOD API User Manual/images/dsp-fft-blackmanharris.png differ diff --git a/FMOD/doc/FMOD API User Manual/images/dsp-fft-hamming.png b/FMOD/doc/FMOD API User Manual/images/dsp-fft-hamming.png new file mode 100644 index 0000000..7c658ce Binary files /dev/null and b/FMOD/doc/FMOD API User Manual/images/dsp-fft-hamming.png differ diff --git a/FMOD/doc/FMOD API User Manual/images/dsp-fft-hanning.png b/FMOD/doc/FMOD API User Manual/images/dsp-fft-hanning.png new file mode 100644 index 0000000..c89691e Binary files /dev/null and b/FMOD/doc/FMOD API User Manual/images/dsp-fft-hanning.png differ diff --git a/FMOD/doc/FMOD API User Manual/images/dsp-fft-process.png b/FMOD/doc/FMOD API User Manual/images/dsp-fft-process.png new file mode 100644 index 0000000..46216b2 Binary files /dev/null and b/FMOD/doc/FMOD API User Manual/images/dsp-fft-process.png differ diff --git a/FMOD/doc/FMOD API User Manual/images/dsp-fft-process.svg b/FMOD/doc/FMOD API User Manual/images/dsp-fft-process.svg new file mode 100644 index 0000000..a88db07 --- /dev/null +++ b/FMOD/doc/FMOD API User Manual/images/dsp-fft-process.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/FMOD/doc/FMOD API User Manual/images/dsp-fft-rectangle.png b/FMOD/doc/FMOD API User Manual/images/dsp-fft-rectangle.png new file mode 100644 index 0000000..88f2c6c Binary files /dev/null and b/FMOD/doc/FMOD API User Manual/images/dsp-fft-rectangle.png differ diff --git a/FMOD/doc/FMOD API User Manual/images/dsp-fft-triangle.png b/FMOD/doc/FMOD API User Manual/images/dsp-fft-triangle.png new file mode 100644 index 0000000..4264896 Binary files /dev/null and b/FMOD/doc/FMOD API User Manual/images/dsp-fft-triangle.png differ diff --git a/FMOD/doc/FMOD API User Manual/images/dsp-flange-wave.svg b/FMOD/doc/FMOD API User Manual/images/dsp-flange-wave.svg new file mode 100644 index 0000000..a09adf9 --- /dev/null +++ b/FMOD/doc/FMOD API User Manual/images/dsp-flange-wave.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/FMOD/doc/FMOD API User Manual/images/dsp-limiter-signals.svg b/FMOD/doc/FMOD API User Manual/images/dsp-limiter-signals.svg new file mode 100644 index 0000000..0f9bd42 --- /dev/null +++ b/FMOD/doc/FMOD API User Manual/images/dsp-limiter-signals.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/FMOD/doc/FMOD API User Manual/images/dsp-multibandeq-bands.svg b/FMOD/doc/FMOD API User Manual/images/dsp-multibandeq-bands.svg new file mode 100644 index 0000000..a80f3fa --- /dev/null +++ b/FMOD/doc/FMOD API User Manual/images/dsp-multibandeq-bands.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/FMOD/doc/FMOD API User Manual/images/dsp-normalize-signals.svg b/FMOD/doc/FMOD API User Manual/images/dsp-normalize-signals.svg new file mode 100644 index 0000000..e246995 --- /dev/null +++ b/FMOD/doc/FMOD API User Manual/images/dsp-normalize-signals.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/FMOD/doc/FMOD API User Manual/images/dsp-objectpanner-diagram.svg b/FMOD/doc/FMOD API User Manual/images/dsp-objectpanner-diagram.svg new file mode 100644 index 0000000..01624d9 --- /dev/null +++ b/FMOD/doc/FMOD API User Manual/images/dsp-objectpanner-diagram.svg @@ -0,0 +1,4 @@ + + + +
TRACK SIGNAL CHAIN
TRACK SIGNAL CHAIN
OBJECT PANNER



Sends signal to object mixer
OBJECT PANNER...
PANNER AND OTHER BUSES
PANNER AND OTHER...
MASTER BUS
MASTER BUS
Signal
Signal
Signal
Signal
Signal
Signal
OBJECT MIXER
OBJECT MIXER
Signal
Signal
SIGNAL ROUTED DIRECTLY TO OBJECT MIXER
SIGNAL ROUTED DIRECTLY TO OBJECT MIXER
AUDIO OUTPUT
AUDIO OUTPUT
Signal
Signal
Text is not SVG - cannot display
\ No newline at end of file diff --git a/FMOD/doc/FMOD API User Manual/images/dsp-oscillator-waves.svg b/FMOD/doc/FMOD API User Manual/images/dsp-oscillator-waves.svg new file mode 100644 index 0000000..6aa45b2 --- /dev/null +++ b/FMOD/doc/FMOD API User Manual/images/dsp-oscillator-waves.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/FMOD/doc/FMOD API User Manual/images/dsp-pan-2d-height-side.svg b/FMOD/doc/FMOD API User Manual/images/dsp-pan-2d-height-side.svg new file mode 100644 index 0000000..8e3f3b9 --- /dev/null +++ b/FMOD/doc/FMOD API User Manual/images/dsp-pan-2d-height-side.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/FMOD/doc/FMOD API User Manual/images/dsp-pan-2d-height.svg b/FMOD/doc/FMOD API User Manual/images/dsp-pan-2d-height.svg new file mode 100644 index 0000000..79317c4 --- /dev/null +++ b/FMOD/doc/FMOD API User Manual/images/dsp-pan-2d-height.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/FMOD/doc/FMOD API User Manual/images/dsp-pan-2d-stereo-anim.gif b/FMOD/doc/FMOD API User Manual/images/dsp-pan-2d-stereo-anim.gif new file mode 100644 index 0000000..58f82c2 Binary files /dev/null and b/FMOD/doc/FMOD API User Manual/images/dsp-pan-2d-stereo-anim.gif differ diff --git a/FMOD/doc/FMOD API User Manual/images/dsp-pan-2d-stereo.svg b/FMOD/doc/FMOD API User Manual/images/dsp-pan-2d-stereo.svg new file mode 100644 index 0000000..daa86a3 --- /dev/null +++ b/FMOD/doc/FMOD API User Manual/images/dsp-pan-2d-stereo.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/FMOD/doc/FMOD API User Manual/images/dsp-pan-2d-surround-anim.gif b/FMOD/doc/FMOD API User Manual/images/dsp-pan-2d-surround-anim.gif new file mode 100644 index 0000000..9eae1cf Binary files /dev/null and b/FMOD/doc/FMOD API User Manual/images/dsp-pan-2d-surround-anim.gif differ diff --git a/FMOD/doc/FMOD API User Manual/images/dsp-pan-2d-surround-direction-anim.gif b/FMOD/doc/FMOD API User Manual/images/dsp-pan-2d-surround-direction-anim.gif new file mode 100644 index 0000000..078fc41 Binary files /dev/null and b/FMOD/doc/FMOD API User Manual/images/dsp-pan-2d-surround-direction-anim.gif differ diff --git a/FMOD/doc/FMOD API User Manual/images/dsp-pan-2d-surround-discrete-anim.gif b/FMOD/doc/FMOD API User Manual/images/dsp-pan-2d-surround-discrete-anim.gif new file mode 100644 index 0000000..901ef42 Binary files /dev/null and b/FMOD/doc/FMOD API User Manual/images/dsp-pan-2d-surround-discrete-anim.gif differ diff --git a/FMOD/doc/FMOD API User Manual/images/dsp-pan-2d-surround-discretesep-anim.gif b/FMOD/doc/FMOD API User Manual/images/dsp-pan-2d-surround-discretesep-anim.gif new file mode 100644 index 0000000..f8e7863 Binary files /dev/null and b/FMOD/doc/FMOD API User Manual/images/dsp-pan-2d-surround-discretesep-anim.gif differ diff --git a/FMOD/doc/FMOD API User Manual/images/dsp-pan-2d-surround-extent-5ch.png b/FMOD/doc/FMOD API User Manual/images/dsp-pan-2d-surround-extent-5ch.png new file mode 100644 index 0000000..83e9714 Binary files /dev/null and b/FMOD/doc/FMOD API User Manual/images/dsp-pan-2d-surround-extent-5ch.png differ diff --git a/FMOD/doc/FMOD API User Manual/images/dsp-pan-2d-surround-height-714down.gif b/FMOD/doc/FMOD API User Manual/images/dsp-pan-2d-surround-height-714down.gif new file mode 100644 index 0000000..6933538 Binary files /dev/null and b/FMOD/doc/FMOD API User Manual/images/dsp-pan-2d-surround-height-714down.gif differ diff --git a/FMOD/doc/FMOD API User Manual/images/dsp-pan-2d-surround-height-714up.gif b/FMOD/doc/FMOD API User Manual/images/dsp-pan-2d-surround-height-714up.gif new file mode 100644 index 0000000..9837ede Binary files /dev/null and b/FMOD/doc/FMOD API User Manual/images/dsp-pan-2d-surround-height-714up.gif differ diff --git a/FMOD/doc/FMOD API User Manual/images/dsp-pan-2d-surround-height.gif b/FMOD/doc/FMOD API User Manual/images/dsp-pan-2d-surround-height.gif new file mode 100644 index 0000000..e74aacb Binary files /dev/null and b/FMOD/doc/FMOD API User Manual/images/dsp-pan-2d-surround-height.gif differ diff --git a/FMOD/doc/FMOD API User Manual/images/dsp-pan-2d-surround-rotate-anim.gif b/FMOD/doc/FMOD API User Manual/images/dsp-pan-2d-surround-rotate-anim.gif new file mode 100644 index 0000000..1fc00f4 Binary files /dev/null and b/FMOD/doc/FMOD API User Manual/images/dsp-pan-2d-surround-rotate-anim.gif differ diff --git a/FMOD/doc/FMOD API User Manual/images/dsp-pan-2d.png b/FMOD/doc/FMOD API User Manual/images/dsp-pan-2d.png new file mode 100644 index 0000000..f4e6d38 Binary files /dev/null and b/FMOD/doc/FMOD API User Manual/images/dsp-pan-2d.png differ diff --git a/FMOD/doc/FMOD API User Manual/images/dsp-pan-2d.svg b/FMOD/doc/FMOD API User Manual/images/dsp-pan-2d.svg new file mode 100644 index 0000000..27be22f --- /dev/null +++ b/FMOD/doc/FMOD API User Manual/images/dsp-pan-2d.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/FMOD/doc/FMOD API User Manual/images/dsp-pan-3d-extent-off.gif b/FMOD/doc/FMOD API User Manual/images/dsp-pan-3d-extent-off.gif new file mode 100644 index 0000000..52706d9 Binary files /dev/null and b/FMOD/doc/FMOD API User Manual/images/dsp-pan-3d-extent-off.gif differ diff --git a/FMOD/doc/FMOD API User Manual/images/dsp-pan-3d-position.svg b/FMOD/doc/FMOD API User Manual/images/dsp-pan-3d-position.svg new file mode 100644 index 0000000..fb4dd11 --- /dev/null +++ b/FMOD/doc/FMOD API User Manual/images/dsp-pan-3d-position.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/FMOD/doc/FMOD API User Manual/images/dsp-pan-3d-rolloff-custom.svg b/FMOD/doc/FMOD API User Manual/images/dsp-pan-3d-rolloff-custom.svg new file mode 100644 index 0000000..adea834 --- /dev/null +++ b/FMOD/doc/FMOD API User Manual/images/dsp-pan-3d-rolloff-custom.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/FMOD/doc/FMOD API User Manual/images/dsp-pan-3d-rolloff-inverse.svg b/FMOD/doc/FMOD API User Manual/images/dsp-pan-3d-rolloff-inverse.svg new file mode 100644 index 0000000..1781280 --- /dev/null +++ b/FMOD/doc/FMOD API User Manual/images/dsp-pan-3d-rolloff-inverse.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/FMOD/doc/FMOD API User Manual/images/dsp-pan-3d-rolloff-invtaper.svg b/FMOD/doc/FMOD API User Manual/images/dsp-pan-3d-rolloff-invtaper.svg new file mode 100644 index 0000000..5122c51 --- /dev/null +++ b/FMOD/doc/FMOD API User Manual/images/dsp-pan-3d-rolloff-invtaper.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/FMOD/doc/FMOD API User Manual/images/dsp-pan-3d-rolloff-linear.svg b/FMOD/doc/FMOD API User Manual/images/dsp-pan-3d-rolloff-linear.svg new file mode 100644 index 0000000..09c3e9e --- /dev/null +++ b/FMOD/doc/FMOD API User Manual/images/dsp-pan-3d-rolloff-linear.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/FMOD/doc/FMOD API User Manual/images/dsp-pan-3d-rolloff-linsquared.svg b/FMOD/doc/FMOD API User Manual/images/dsp-pan-3d-rolloff-linsquared.svg new file mode 100644 index 0000000..68b68b4 --- /dev/null +++ b/FMOD/doc/FMOD API User Manual/images/dsp-pan-3d-rolloff-linsquared.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/FMOD/doc/FMOD API User Manual/images/dsp-pan-3d-surround-minextent.gif b/FMOD/doc/FMOD API User Manual/images/dsp-pan-3d-surround-minextent.gif new file mode 100644 index 0000000..b58c056 Binary files /dev/null and b/FMOD/doc/FMOD API User Manual/images/dsp-pan-3d-surround-minextent.gif differ diff --git a/FMOD/doc/FMOD API User Manual/images/dsp-pan-3d-surround-soundsize.gif b/FMOD/doc/FMOD API User Manual/images/dsp-pan-3d-surround-soundsize.gif new file mode 100644 index 0000000..24fa164 Binary files /dev/null and b/FMOD/doc/FMOD API User Manual/images/dsp-pan-3d-surround-soundsize.gif differ diff --git a/FMOD/doc/FMOD API User Manual/images/dsp-pan-general-enabledspeakers.gif b/FMOD/doc/FMOD API User Manual/images/dsp-pan-general-enabledspeakers.gif new file mode 100644 index 0000000..5e11ed1 Binary files /dev/null and b/FMOD/doc/FMOD API User Manual/images/dsp-pan-general-enabledspeakers.gif differ diff --git a/FMOD/doc/FMOD API User Manual/images/dsp-send-return.svg b/FMOD/doc/FMOD API User Manual/images/dsp-send-return.svg new file mode 100644 index 0000000..ec4d856 --- /dev/null +++ b/FMOD/doc/FMOD API User Manual/images/dsp-send-return.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/FMOD/doc/FMOD API User Manual/images/dsp-sfxreverb.svg b/FMOD/doc/FMOD API User Manual/images/dsp-sfxreverb.svg new file mode 100644 index 0000000..dfb728d --- /dev/null +++ b/FMOD/doc/FMOD API User Manual/images/dsp-sfxreverb.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/FMOD/doc/FMOD API User Manual/images/dsp-threeeq.svg b/FMOD/doc/FMOD API User Manual/images/dsp-threeeq.svg new file mode 100644 index 0000000..048f157 --- /dev/null +++ b/FMOD/doc/FMOD API User Manual/images/dsp-threeeq.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/FMOD/doc/FMOD API User Manual/images/dsp-transceiver.svg b/FMOD/doc/FMOD API User Manual/images/dsp-transceiver.svg new file mode 100644 index 0000000..68e5371 --- /dev/null +++ b/FMOD/doc/FMOD API User Manual/images/dsp-transceiver.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/FMOD/doc/FMOD API User Manual/images/dspnet-img001.png b/FMOD/doc/FMOD API User Manual/images/dspnet-img001.png new file mode 100644 index 0000000..f0a0be0 Binary files /dev/null and b/FMOD/doc/FMOD API User Manual/images/dspnet-img001.png differ diff --git a/FMOD/doc/FMOD API User Manual/images/dspnet-img002.png b/FMOD/doc/FMOD API User Manual/images/dspnet-img002.png new file mode 100644 index 0000000..a8d3754 Binary files /dev/null and b/FMOD/doc/FMOD API User Manual/images/dspnet-img002.png differ diff --git a/FMOD/doc/FMOD API User Manual/images/dspnet-img003.png b/FMOD/doc/FMOD API User Manual/images/dspnet-img003.png new file mode 100644 index 0000000..3f4b1fa Binary files /dev/null and b/FMOD/doc/FMOD API User Manual/images/dspnet-img003.png differ diff --git a/FMOD/doc/FMOD API User Manual/images/dspnet-img004.png b/FMOD/doc/FMOD API User Manual/images/dspnet-img004.png new file mode 100644 index 0000000..e9a5eca Binary files /dev/null and b/FMOD/doc/FMOD API User Manual/images/dspnet-img004.png differ diff --git a/FMOD/doc/FMOD API User Manual/images/dspnet-img005.png b/FMOD/doc/FMOD API User Manual/images/dspnet-img005.png new file mode 100644 index 0000000..d48fcc9 Binary files /dev/null and b/FMOD/doc/FMOD API User Manual/images/dspnet-img005.png differ diff --git a/FMOD/doc/FMOD API User Manual/images/dspnet-img006.png b/FMOD/doc/FMOD API User Manual/images/dspnet-img006.png new file mode 100644 index 0000000..30a70f0 Binary files /dev/null and b/FMOD/doc/FMOD API User Manual/images/dspnet-img006.png differ diff --git a/FMOD/doc/FMOD API User Manual/images/dspnet-img007.png b/FMOD/doc/FMOD API User Manual/images/dspnet-img007.png new file mode 100644 index 0000000..efea4c8 Binary files /dev/null and b/FMOD/doc/FMOD API User Manual/images/dspnet-img007.png differ diff --git a/FMOD/doc/FMOD API User Manual/images/dspnet-img008.png b/FMOD/doc/FMOD API User Manual/images/dspnet-img008.png new file mode 100644 index 0000000..df67a60 Binary files /dev/null and b/FMOD/doc/FMOD API User Manual/images/dspnet-img008.png differ diff --git a/FMOD/doc/FMOD API User Manual/images/dspnet-img009.png b/FMOD/doc/FMOD API User Manual/images/dspnet-img009.png new file mode 100644 index 0000000..0961029 Binary files /dev/null and b/FMOD/doc/FMOD API User Manual/images/dspnet-img009.png differ diff --git a/FMOD/doc/FMOD API User Manual/images/dspnet-img010.png b/FMOD/doc/FMOD API User Manual/images/dspnet-img010.png new file mode 100644 index 0000000..86e6d74 Binary files /dev/null and b/FMOD/doc/FMOD API User Manual/images/dspnet-img010.png differ diff --git a/FMOD/doc/FMOD API User Manual/images/dspnet-img011.png b/FMOD/doc/FMOD API User Manual/images/dspnet-img011.png new file mode 100644 index 0000000..597a743 Binary files /dev/null and b/FMOD/doc/FMOD API User Manual/images/dspnet-img011.png differ diff --git a/FMOD/doc/FMOD API User Manual/images/dspnet-img012.png b/FMOD/doc/FMOD API User Manual/images/dspnet-img012.png new file mode 100644 index 0000000..414dad9 Binary files /dev/null and b/FMOD/doc/FMOD API User Manual/images/dspnet-img012.png differ diff --git a/FMOD/doc/FMOD API User Manual/images/dspnet-img013.png b/FMOD/doc/FMOD API User Manual/images/dspnet-img013.png new file mode 100644 index 0000000..ab47847 Binary files /dev/null and b/FMOD/doc/FMOD API User Manual/images/dspnet-img013.png differ diff --git a/FMOD/doc/FMOD API User Manual/images/dspnet-img014.png b/FMOD/doc/FMOD API User Manual/images/dspnet-img014.png new file mode 100644 index 0000000..a951e21 Binary files /dev/null and b/FMOD/doc/FMOD API User Manual/images/dspnet-img014.png differ diff --git a/FMOD/doc/FMOD API User Manual/images/dspnet-img015.png b/FMOD/doc/FMOD API User Manual/images/dspnet-img015.png new file mode 100644 index 0000000..05a9ee9 Binary files /dev/null and b/FMOD/doc/FMOD API User Manual/images/dspnet-img015.png differ diff --git a/FMOD/doc/FMOD API User Manual/images/dynamic-response-compress-down.svg b/FMOD/doc/FMOD API User Manual/images/dynamic-response-compress-down.svg new file mode 100644 index 0000000..157f2a9 --- /dev/null +++ b/FMOD/doc/FMOD API User Manual/images/dynamic-response-compress-down.svg @@ -0,0 +1 @@ +InputOutputThresholdRatio \ No newline at end of file diff --git a/FMOD/doc/FMOD API User Manual/images/dynamic-response-compress-up.svg b/FMOD/doc/FMOD API User Manual/images/dynamic-response-compress-up.svg new file mode 100644 index 0000000..1744892 --- /dev/null +++ b/FMOD/doc/FMOD API User Manual/images/dynamic-response-compress-up.svg @@ -0,0 +1 @@ +InputOutputThresholdRatio \ No newline at end of file diff --git a/FMOD/doc/FMOD API User Manual/images/dynamic-response-expand-down.svg b/FMOD/doc/FMOD API User Manual/images/dynamic-response-expand-down.svg new file mode 100644 index 0000000..ec8b5b0 --- /dev/null +++ b/FMOD/doc/FMOD API User Manual/images/dynamic-response-expand-down.svg @@ -0,0 +1 @@ +InputOutputThresholdRatio \ No newline at end of file diff --git a/FMOD/doc/FMOD API User Manual/images/dynamic-response-expand-up.svg b/FMOD/doc/FMOD API User Manual/images/dynamic-response-expand-up.svg new file mode 100644 index 0000000..28a5db4 --- /dev/null +++ b/FMOD/doc/FMOD API User Manual/images/dynamic-response-expand-up.svg @@ -0,0 +1 @@ +InputOutputThresholdRatio \ No newline at end of file diff --git a/FMOD/doc/FMOD API User Manual/images/mpeg-frames.png b/FMOD/doc/FMOD API User Manual/images/mpeg-frames.png new file mode 100644 index 0000000..cee5965 Binary files /dev/null and b/FMOD/doc/FMOD API User Manual/images/mpeg-frames.png differ diff --git a/FMOD/doc/FMOD API User Manual/images/multi-channel-mpeg.png b/FMOD/doc/FMOD API User Manual/images/multi-channel-mpeg.png new file mode 100644 index 0000000..048ade4 Binary files /dev/null and b/FMOD/doc/FMOD API User Manual/images/multi-channel-mpeg.png differ diff --git a/FMOD/doc/FMOD API User Manual/images/object_spatializer_effect_diagram.png b/FMOD/doc/FMOD API User Manual/images/object_spatializer_effect_diagram.png new file mode 100644 index 0000000..c7ed554 Binary files /dev/null and b/FMOD/doc/FMOD API User Manual/images/object_spatializer_effect_diagram.png differ diff --git a/FMOD/doc/FMOD API User Manual/images/samples-bytes-milliseconds.png b/FMOD/doc/FMOD API User Manual/images/samples-bytes-milliseconds.png new file mode 100644 index 0000000..d656d3e Binary files /dev/null and b/FMOD/doc/FMOD API User Manual/images/samples-bytes-milliseconds.png differ diff --git a/FMOD/doc/FMOD API User Manual/images/studio-bank-layout.png b/FMOD/doc/FMOD API User Manual/images/studio-bank-layout.png new file mode 100644 index 0000000..609bed9 Binary files /dev/null and b/FMOD/doc/FMOD API User Manual/images/studio-bank-layout.png differ diff --git a/FMOD/doc/FMOD API User Manual/images/studio-thread-async.png b/FMOD/doc/FMOD API User Manual/images/studio-thread-async.png new file mode 100644 index 0000000..3ab9412 Binary files /dev/null and b/FMOD/doc/FMOD API User Manual/images/studio-thread-async.png differ diff --git a/FMOD/doc/FMOD API User Manual/images/studio-thread-sync.png b/FMOD/doc/FMOD API User Manual/images/studio-thread-sync.png new file mode 100644 index 0000000..15a7651 Binary files /dev/null and b/FMOD/doc/FMOD API User Manual/images/studio-thread-sync.png differ diff --git a/FMOD/doc/FMOD API User Manual/images/virtual-dspgraph.png b/FMOD/doc/FMOD API User Manual/images/virtual-dspgraph.png new file mode 100644 index 0000000..f3c7e21 Binary files /dev/null and b/FMOD/doc/FMOD API User Manual/images/virtual-dspgraph.png differ diff --git a/FMOD/doc/FMOD API User Manual/loading-and-playing-sounds-in-the-core-api.html b/FMOD/doc/FMOD API User Manual/loading-and-playing-sounds-in-the-core-api.html new file mode 100644 index 0000000..7b8b9be --- /dev/null +++ b/FMOD/doc/FMOD API User Manual/loading-and-playing-sounds-in-the-core-api.html @@ -0,0 +1,663 @@ + + +Core API Loading and Playing Sounds + + + + +
+ +
+

4. Core API Loading and Playing Sounds

+

This chapter describes how to load and play sounds using the Core API.

+

4.1 Loading Samples for Playback

+

Before an asset may be played, its sample data must be loaded or buffered into memory. The process of loading or buffering the sampledata into memory is referred to as "creating the sound." Sounds are created using System::createStream or System::createSound, which also lets you choose the loading mode to be used for that sound.

+

4.1.1 Non-blocking Sound Creation

+

Loading a sound is one of the slowest operations the FMOD Engine can perform. You may optionally place a sound load into the background so that it doesn't affect processing in the main application thread by using the FMOD_NONBLOCKING flag in System::createSound.

+
FMOD::Sound *sound;
+result = system->createStream("../media/wave.mp3", FMOD_NONBLOCKING, 0, &sound); // Creates a handle to a stream then commands the FMOD Async loader to open the stream in the background.
+ERRCHECK(result);
+
+ +

This immediately returns a sound handle, which you can use to check the status of the sound being loaded with Sound::getOpenState. When the sound is ready to play, its state is FMOD_OPENSTATE_READY. Wait until the sound is ready before playing it. If a function other than getOpenState is called on a sound that is still loading, it typically returns FMOD_ERR_NOTREADY.

+

To avoid a stall on a streaming sound when trying to free/release it, check that the state is FMOD_OPENSTATE_READY before calling Sound::release.

+

You can specify a callback using the nonblockcallback member of the FMOD_CREATESOUNDEXINFO structure, to be called when the sound finished loading or the stream finishes opening. The following are examples of the callback definition and the createSound call.

+
FMOD_RESULT F_CALLBACK nonblockcallback(FMOD_SOUND *sound, FMOD_RESULT result)
+{
+    FMOD::Sound *snd = (FMOD::Sound *)sound;
+
+    printf("Sound loaded! (%d) %s\n", result, FMOD_ErrorString(result)); 
+
+    return FMOD_OK;
+}
+
+ +
FMOD_RESULT result;
+FMOD::Sound *sound;
+FMOD_CREATESOUNDEXINFO exinfo;
+
+memset(&exinfo, 0, sizeof(FMOD_CREATESOUNDEXINFO));
+exinfo.cbsize = sizeof(FMOD_CREATESOUNDEXINFO);
+exinfo.nonblockcallback = nonblockcallback;
+
+result = system->createStream("../media/wave.mp3", FMOD_NONBLOCKING, &exinfo, &sound);
+ERRCHECK(result);
+
+ +

4.1.2 Loading modes

+

There are three different ways in which sample data may be loaded for playback.

+

Decompressed Sounds

+

The default mode for createSound is FMOD_CREATESAMPLE, which decompresses the sample data into memory in PCM format for playback. (PCM data is raw uncompressed audio data. For more information, see Sample Data.) Decompressed sounds uses little to no CPU time to process, as PCM data is the same format that the FMOD mixing engine uses, as well as the format used by the audio device itself. However, uncompressed PCM data requires a lot more memory than compressed sample data.

+

Decompressed sounds are desirable on platforms with limited CPU cycles, especially mobile devices.

+

Compressed Sounds

+

For shorter sounds, rather than decompressing the audio file into memory, you may wish to load the audio file into memory in its compressed form. Compressed sounds require less loading time and memory than decompressed sounds, as the sample data does not need to be decompressed when it is loaded. However, because compressed samples are more complicated to play, they have larger contexts to deal with (for example vorbis decode information), so there is a constant per voice overhead (up to a fixed limit) for each playing compressed sound.

+

Codec allocation is incurred at System::init time if you call System::setAdvancedSettings and set a maxCodecs value, or it could happen the first time a sound is loaded with the FMOD_CREATECOMPRESSEDSAMPLE flag. If not configured with System::setAdvancedSettings, this uses the default of 32 codecs for the allocation.

+

For example, the vorbis codec has an overhead of 16kb per voice, so the default of 32 vorbis codecs would consume 512kb of memory. If you used System::setAdvancedSettings to set the maxVorbisCodecs value to 16 instead, the vorbis codecs would instead consume 256kb of memory, but you could only play 16 compressed sounds encoded in Vorbis format.

+

Generally, the best cross platform codec to used as a compressed sample is Vorbis (from an FSB file). However, if Vorbis uses too much CPU for your platform (i.e.: mobile), the FADPCM codec is a good second option. It is less compressed, and uses far fewer CPU cycles to decode, while giving good quality and 4:1 compression. For PS4 or Xbox One, it is better to use the AT9 and XMA codec formats respectively, as the decoding of these formats are handled by separate media chips, taking the load off the CPU. See the relevant Platform Details section for details on platform specific audio formats.

+

To play a sound as compressed, add the FMOD_CREATECOMPRESSEDSAMPLE flag to the System::createSound function.

+

Streams

+

Streaming is the ability to take a large audio asset, and read/play it in real time in small chunks at a time, avoiding the need to load the entire asset into memory.

+

Whether an asset should be streamed is a question of resource availability and allocation. Each currently-playing streaming asset requires constant file I/O (which is to say, access to the disk) and a very small amount of memory for the stream's ring buffer; whereas assets using other loading modes require much more memory but only require file I/O when they’re first loaded, and only require these resources once, no matter how many instances of the asset are playing.

+

File I/O is a very limited resource on many platforms, and is needed for many things other than audio. Fortunately, most games load much of their content into memory up-front at the start of new levels and areas, and many users do not run applications that constantly access the disk in the background. This means that there are usually periods when the player’s device is not otherwise loading content from disk, meaning that streaming assets that play in those periods can enjoy uncontested and uninterrupted file I/O. By contrast, a streaming asset that plays while the disk is being accessed regularly by anything else may not be able to access to disk frequently enough to refresh its ring buffer, and so may suffer from buffer starvation. Buffer starvation of a streaming asset manifests as the sound stuttering or stopping entirely.

+

The streaming loading mode is therefore best used for assets that meet the following conditions:

+
    +
  • The asset would take up an inconveniently large amount of memory if fully loaded.
  • +
  • Few instances of the asset ever need to be playing at the same time.
  • +
  • Few or no other streaming assets ever need to be playing at the same time as the asset.
  • +
  • The asset only plays at times when the game does not need to read or write much to the drive on which the asset or its bank file is stored.
  • +
+

Accordingly, streaming is typically reserved for:

+
    +
  • Music
  • +
  • Voice overs and dialogue
  • +
  • Long ambiance tracks
  • +
+

To play a Sound as a stream, add the FMOD_CREATESTREAM flag to the System::createSound function, or use the System::createStream function. These options both equate to the same end behavior.

+

Streaming behavior can be adjusted in several ways, as streaming a file takes two threads, one for file reading, and one for codec decoding/decompression. File buffer sizes can be adjusted with System::setStreamBufferSize and codec decoding buffer size can be adjusted with FMOD_CREATESOUNDEXINFO decodeBufferSize member, or FMOD_ADVANCEDSETTINGS::defaultDecodeBufferSize.

+
Internet Streaming
+

FMOD streaming supports internet addresses. Supplying http or https in the filename will switch FMOD to streaming using native http, shoutcast or icecast.

+

Playlist files (such as ASX/PLS/M3U/WAX formats) are supported, including redirection.

+

Proxy specification and authentication are supported, as well as real-time shoutcast stream switching, metadata retrieval and packet loss notification.

+

4.2 Playing a sound

+

To execute a simple playSound

+
    +
  1. Load a sound with System::createSound, using the system object handle as described above. This will return a Sound handle. This is your handle to your loaded sound.
  2. +
  3. Play the sound with System::playSound, using the Sound handle returned from Step 1. This will return a Channel handle.
  4. +
  5. Let it play in the background, or monitor its status with ChannelControl::isPlaying, using the Channel handle returned from Step 2. A channel handle will also go immediately invalid when a sound ends, when calling any relevant Channel based function, so that is another way to know a sound has ended. The error code returned will be FMOD_ERR_INVALID_HANDLE.
  6. +
+

All functions execute immediately, so you can either fire and forget a sound during main loop execution or poll for a sound to finish. Playing a sound does not block the application.

+

The following example shows playing a sound loaded with createSound and then playing it.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
FMOD_RESULT result;
+FMOD_SOUND *sound;
+FMOD_CHANNEL *channel;
+
+result = FMOD_System_CreateSound(system, "../media/wave.mp3", FMOD_DEFAULT, 0, &sound);
+ERRCHECK(result);
+
+result = FMOD_System_PlaySound(system, sound, 0, 0, &channel);
+ERRCHECK(result);
+
+ +
FMOD_RESULT result;
+FMOD::Sound *sound;
+FMOD::Channel *channel;
+
+result = system->createSound("../media/wave.mp3", FMOD_DEFAULT, nullptr, &sound);
+ERRCHECK(result);
+
+result = system->playSound(sound, nullptr, false, &channel);
+ERRCHECK(result);
+
+ +
FMOD.RESULT result;
+FMOD.Sound sound;
+FMOD.Channel channel;
+
+result = system.createSound("../media/wave.mp3", FMOD.MODE.DEFAULT, out sound);
+ERRCHECK(result);
+
+result = system.playSound(sound, null, false, out channel);
+ERRCHECK(result);
+
+ +
var result;
+var sound = {};
+var outval = {};
+var channel = null;
+
+result = system.createSound("../media/wave.mp3", FMOD.MODE_DEFAULT, 0, outval);
+ERRCHECK(result);
+
+sound = outval.val;
+
+result = system.playSound(sound, null, false, channel);
+ERRCHECK(result);
+
+ +

4.2.1 Getting a Subsound

+

When a sound contains multiple subsounds, you can get get the number of subsounds by using Sound::getNumSubSounds, and get a pointer to a specific subsound by calling Sound::getSubSound and specifying the index of the subsound you want.

+

Under most circumstances, getSubSound is a free function call, whether it be called on a sample or a stream, as all it does is return a pointer. However, if getSubSound is called on a blocking stream, it may cause System::playSound to stall for several milliseconds or more while it seeks and reflushes the stream buffer. Time taken can depend on the file format and media.

+

If the parent sound was opened using FMOD_NONBLOCKING, its current FMOD_OPENSTATE will have to be polled with Sound::getOpenState until it returns FMOD_OPENSTATE_READY. When the stream is ready and System::playSound is called, then the playsound will not stall and will execute immediately because the stream has been flushed.

+

4.3 Advanced Sound Creation

+

FMOD has a number of FMOD_MODE modes for Sound creation that require the use of FMOD_CREATESOUNDEXINFO to specify various properties of the sound, such as the data format, frequency, length, callbacks, and so on. The following details how to use these modes, and provides basic examples of creating a sound using each mode.

+

4.3.1 Creating a Sound from memory

+

FMOD_OPENMEMORY causes FMOD to interpret the first argument of System::createSound or System::createStream as a pointer to memory instead of a filename. FMOD_CREATESOUNDEXINFO::length is used to specify the length of the sound, specifically the amount of memory in bytes the sound's data occupies. This data is copied into FMOD's buffers and can be freed after the sound is created. If using FMOD_CREATESTREAM, the data is instead streamed from the buffer pointed to by the pointer you passed in, so you should ensure that the memory isn't freed until you have finished with and released the stream.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
FMOD::Sound *sound;
+FMOD_CREATESOUNDEXINFO exinfo;
+void *buffer = 0;
+int length = 0;
+
+//
+// Load your audio data to the "buffer" pointer here
+//
+
+// Create extended sound info struct
+memset(&exinfo, 0, sizeof(FMOD_CREATESOUNDEXINFO));
+exinfo.cbsize = sizeof(FMOD_CREATESOUNDEXINFO);     // Size of the struct.
+exinfo.length = length;                             // Length of sound - PCM data in bytes
+
+system->createSound((const char *)buffer, FMOD_OPENMEMORY, &exinfo, &sound);
+// The audio data pointed to by "buffer" has been duplicated into FMOD's buffers, and can now be freed
+// However, if loading as a stream with FMOD_CREATESTREAM or System::createStream, the memory must stay active, so do not free it!
+
+ +
FMOD_Sound *sound;
+FMOD_CREATESOUNDEXINFO exinfo;
+void *buffer = 0;
+int length = 0;
+
+//
+// Load your audio data to the "buffer" pointer here
+//
+
+// Create extended sound info struct
+memset(&exinfo, 0, sizeof(FMOD_CREATESOUNDEXINFO));
+exinfo.cbsize = sizeof(FMOD_CREATESOUNDEXINFO);     // Size of the struct.
+exinfo.length = length;                             // Length of sound - PCM data in bytes
+
+FMOD_System_CreateSound(system, (const char *)buffer, FMOD_OPENMEMORY, &exinfo, &sound);
+// The audio data pointed to by "buffer" has been duplicated into FMOD's buffers, and can now be freed
+// However, if loading as a stream with FMOD_CREATESTREAM or System::createStream, the memory must stay active, so do not free it!
+
+ +
FMOD.Sound sound;
+FMOD.CREATESOUNDEXINFO exinfo;
+byte[] buffer;
+
+//
+// Load your audio data to the "buffer" array here
+//
+
+// Create extended sound info struct
+exinfo = new FMOD.CREATESOUNDEXINFO();
+exinfo.cbsize = Marshal.SizeOf(typeof(FMOD.CREATESOUNDEXINFO));
+exinfo.length = (uint)bytes.Length;
+
+system.createSound(buffer, FMOD.MODE.OPENMEMORY, ref exinfo, out sound);
+// The audio data stored by the "buffer" array has been duplicated into FMOD's buffers, and can now be freed
+// However, if loading as a stream with FMOD_CREATESTREAM or System::createStream, you must pin "buffer" with GCHandle so that it stays active
+
+ +
var sound = {};
+var outval = {};
+var buffer;
+
+//
+// Load your audio data to a Uint8Array and assign it to "buffer" var here 
+//
+
+// Create extended sound info struct
+// No need to define cbsize, the struct already knows its own size in JS
+var exinfo = FMOD.CREATESOUNDEXINFO();
+exinfo.length = buffer.length;            // Length of sound - PCM data in bytes
+
+system.createSound(buffer.buffer, FMOD.OPENMEMORY, exinfo, outval);
+sound = outval.val;
+// The audio data stored in the "buffer" var has been duplicated into FMOD's buffers, and can now be freed
+// However, if loading as a stream with FMOD_CREATESTREAM or System::createStream, the memory must stay active, so do not free it!
+
+ +

FMOD_OPENMEMORY_POINT also causes FMOD to interpret the first argument of System::createSound or System::createStream as a pointer to memory instead of a filename. However, unlike FMOD_OPENMEMORY, FMOD will use the memory as is instead of copying it to its own buffers. As a result, you may only free the memory after Sound::release is called. FMOD_CREATESOUNDEXINFO::length is used to specify the length of the sound, specifically the amount of memory in bytes the sound's data occupies.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
FMOD::Sound *sound;
+FMOD_CREATESOUNDEXINFO exinfo;
+void *buffer = 0;
+int length = 0;
+
+//
+// Load your audio data to the "buffer" pointer here
+//
+
+// Create extended sound info struct
+memset(&exinfo, 0, sizeof(FMOD_CREATESOUNDEXINFO));
+exinfo.cbsize = sizeof(FMOD_CREATESOUNDEXINFO);     // Size of the struct
+exinfo.length = length;                             // Length of sound - PCM data in bytes
+
+system->createSound((const char *)buffer, FMOD_OPENMEMORY_POINT, &exinfo, &sound);
+// As FMOD is using the data stored at the buffer pointer as is, without copying it into its own buffers, the memory cannot be freed until after Sound::release is called
+
+ +
FMOD_Sound *sound;
+FMOD_CREATESOUNDEXINFO exinfo;
+void *buffer = 0;
+int length = 0;
+
+//
+// Load your audio data to the "buffer" pointer here
+//
+
+// Create extended sound info struct
+memset(&exinfo, 0, sizeof(FMOD_CREATESOUNDEXINFO));
+exinfo.cbsize = sizeof(FMOD_CREATESOUNDEXINFO);     // Size of the struct
+exinfo.length = length;                             // Length of sound - PCM data in bytes
+
+FMOD_System_CreateSound(system, (const char *)buffer, FMOD_OPENMEMORY_POINT, &exinfo, &sound);
+// As FMOD is using the data stored at the buffer pointer as is, without copying it into its own buffers, the memory cannot be freed until after Sound::release is called
+
+ +
FMOD.Sound sound
+FMOD.CREATESOUNDEXINFO exinfo;
+byte[] buffer;
+GCHandle gch;
+
+//
+// Load your audio data to the "buffer" array here
+//
+
+// Pin data in memory so a pointer to it can be passed to FMOD's unmanaged code
+gch = GCHandle.Alloc(buffer, GCHandleType.Pinned);
+
+// Create extended sound info struct
+exinfo = new FMOD.CREATESOUNDEXINFO();
+exinfo.cbsize = Marshal.SizeOf(typeof(FMOD.CREATESOUNDEXINFO)); // Size of the struct
+exinfo.length = (uint)bytes.Length;                             // Length of sound - PCM data in bytes
+
+system.createSound(gch.AddrOfPinnedObject(), FMOD.MODE.OPENMEMORY_POINT, ref exinfo, out sound);
+// As FMOD is using the data stored at the buffer pointer as is, without copying it into its own buffers, the memory must stay active and pinned
+// Unpin memory with gch.Free() after Sound::release has been called
+
+ +
+

Not supported for JavaScript.

+
+

4.3.2 Creating a Sound from PCM data

+

FMOD_OPENRAW causes FMOD to ignore the format of the provided audio file, and instead treat it as raw PCM data. Use FMOD_CREATESOUNDEXINFO to specify the frequency, number of channels, and data format of the file. FMOD expects all raw PCM data to be little endian, and integer PCM data to be signed, in order to play correctly.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
FMOD::Sound *sound;
+FMOD_CREATESOUNDEXINFO exinfo;
+
+// Create extended sound info struct
+memset(&exinfo, 0, sizeof(FMOD_CREATESOUNDEXINFO));
+exinfo.cbsize           = sizeof(FMOD_CREATESOUNDEXINFO);   // Size of the struct
+exinfo.numchannels      = 2;                                // Number of channels in the sound
+exinfo.defaultfrequency = 44100;                            // Playback rate of sound
+exinfo.format           = FMOD_SOUND_FORMAT_PCM16;          // Data format of sound
+
+system->createSound("./Your/File/Path/Here.raw", FMOD_OPENRAW, &exinfo, &sound);
+
+ +
FMOD_Sound *sound;
+FMOD_CREATESOUNDEXINFO exinfo;
+
+// Create extended sound info struct
+memset(&exinfo, 0, sizeof(FMOD_CREATESOUNDEXINFO));
+exinfo.cbsize           = sizeof(FMOD_CREATESOUNDEXINFO);   // Size of the struct
+exinfo.numchannels      = 2;                                // Number of channels in the sound
+exinfo.defaultfrequency = 44100;                            // Default playback rate of sound
+exinfo.format           = FMOD_SOUND_FORMAT_PCM16;          // Data format of sound
+
+FMOD_System_CreateSound(system, "./Your/File/Path/Here.raw", FMOD_OPENRAW, &exinfo, &sound);
+
+ +
FMOD.Sound sound
+FMOD.CREATESOUNDEXINFO exinfo;
+
+// Create extended sound info struct
+exinfo = new FMOD.CREATESOUNDEXINFO();
+exinfo.cbsize           = Marshal.SizeOf(typeof(FMOD.CREATESOUNDEXINFO));  // Size of the struct
+exinfo.numchannels      = 2;                                // Number of channels in the sound
+exinfo.defaultfrequency = 44100;                            // Default playback rate of sound
+exinfo.format           = FMOD.SOUND_FORMAT.PCM16;          // Data format of sound
+
+system.createSound("./Your/File/Path/Here.raw", FMOD.MODE.OPENRAW, ref exinfo, out sound);
+
+ +
var sound = {};
+var outval = {};
+var exinfo = FMOD.CREATESOUNDEXINFO();
+
+// Create extended sound info struct
+// No need to define cbsize, the struct already knows its own size in JS
+exinfo.numchannels      = 2;                                // Number of channels in the sound
+exinfo.defaultfrequency = 44100;                            // Default playback rate of sound
+exinfo.format           = FMOD.SOUND_FORMAT.PCM16;          // Data format of sound
+
+system.createSound("./Your/File/Path/Here.raw", FMOD.OPENRAW, exinfo, outval);
+sound = outval.val;
+
+ +

4.3.3 Creating a Sound by manually providing sample data

+

FMOD_OPENUSER causes FMOD to ignore the first argument of System::createSound or System::createStream, and instead create a static sample or stream to which you must manually provide audio data. Use FMOD_CREATESOUNDEXINFO to specify the frequency, number of channels, and data format. You can optionally provide a read callback, which is used to place your own audio data into FMOD's buffers. If no read callback is provided, the sample will be empty, so Sound::lock and Sound::unlock must be used to provide audio data instead.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
FMOD::Sound *sound;
+FMOD_CREATESOUNDEXINFO exinfo;
+
+// Create extended sound info struct
+memset(&exinfo, 0, sizeof(FMOD_CREATESOUNDEXINFO));
+exinfo.cbsize           = sizeof(FMOD_CREATESOUNDEXINFO);   // Size of the struct
+exinfo.numchannels      = 2;                                // Number of channels in the sound
+exinfo.defaultfrequency = 44100;                            // Default playback rate of sound
+exinfo.length           = exinfo.defaultfrequency * exinfo.numchannels * sizeof(signed short) * 5;   // Length of sound - PCM data in bytes. 5 = seconds
+exinfo.format           = FMOD_SOUND_FORMAT_PCM16;          // Data format of sound
+exinfo.pcmreadcallback  = MyReadCallbackFunction;           // To read sound data, you must specify a read callback using the pcmreadcallback field
+// Alternatively, use Sound::lock and Sound::unlock to submit sample data to the sound when playing it back
+
+// As sample data is being loaded via callback or Sound::lock and Sound::unlock, pass null or equivalent as first argument
+system->createSound(0, FMOD_OPENUSER, &exinfo, &sound);
+
+ +
FMOD_Sound *sound;
+FMOD_CREATESOUNDEXINFO exinfo;
+
+// Create extended sound info struct
+memset(&exinfo, 0, sizeof(FMOD_CREATESOUNDEXINFO));
+exinfo.cbsize           = sizeof(FMOD_CREATESOUNDEXINFO);   // Size of the struct
+exinfo.numchannels      = 2;                                // Number of channels in the sound
+exinfo.defaultfrequency = 44100;                            // Default playback rate of sound
+exinfo.length           = exinfo.defaultfrequency * exinfo.numchannels * sizeof(signed short) * 5;   // Length of sound - PCM data in bytes. 5 = seconds
+exinfo.format           = FMOD_SOUND_FORMAT_PCM16;          // Data format of sound
+exinfo.pcmreadcallback  = MyReadCallbackFunction;           // To read sound data, you must specify a read callback using the pcmreadcallback field
+// Alternatively, use Sound::lock and Sound::unlock to submit sample data to the sound when playing it back
+
+// As sample data is being loaded via callback or Sound::lock and Sound::unlock, pass null or equivalent as second argument
+FMOD_System_CreateSound(system, NULL, FMOD_OPENUSER, &exinfo, &sound);
+
+ +
FMOD.Sound sound
+FMOD.CREATESOUNDEXINFO exinfo;
+
+// Create extended sound info struct
+exinfo = new FMOD.CREATESOUNDEXINFO();
+exinfo.cbsize           = Marshal.SizeOf(typeof(FMOD.CREATESOUNDEXINFO));  // Size of the struct
+exinfo.numchannels      = 2;                                // Number of channels in the sound
+exinfo.defaultfrequency = 44100;                            // Default playback rate of sound
+exinfo.length           = exinfo.defaultfrequency * exinfo.numchannels * sizeof(short) * 5;   // Length of sound - PCM data in bytes. 5 = seconds
+exinfo.format           = FMOD.SOUND_FORMAT.PCM16;          // Data format of sound
+exinfo.pcmreadcallback  = MyReadCallbackFunction;           // To read sound data, you must specify a read callback using the pcmreadcallback field
+// Alternatively, use Sound::lock and Sound::unlock to submit sample data to the sound when playing it back
+
+// As sample data is being loaded via callback or Sound::lock and Sound::unlock, pass null or equivalent as first argument
+system.createSound("", FMOD.MODE.OPENUSER, ref exinfo, out sound);
+
+ +
var sound = {};
+var outval = {};
+var exinfo = FMOD.CREATESOUNDEXINFO();
+
+// Create extended sound info struct
+// No need to define cbsize, the struct already knows its own size in JS
+exinfo.numchannels      = 2;                                // Number of channels in the sound
+exinfo.defaultfrequency = 44100;                            // Default playback rate of sound
+exinfo.length           = exinfo.defaultfrequency * exinfo.numchannels * 2 * 5;      // Length of sound - PCM data in bytes. 2 = sizeof(short) and 5 = seconds
+exinfo.format           = FMOD.SOUND_FORMAT.PCM16;          // Data format of sound
+exinfo.pcmreadcallback  = MyReadCallbackFunction;           // To read sound data, you must specify a read callback using the pcmreadcallback field
+// Alternatively, use Sound::lock and Sound::unlock to submit sample data to the sound when playing it back
+
+// As sample data is being loaded via callback or Sound::lock and Sound::unlock, pass null or equivalent as first argument
+system.createSound("", FMOD.OPENUSER, exinfo, outval);
+sound = outval.val;
+
+ +

4.3.4 Creating the Sound as a Streamed FSB File

+

An FSB file contains subsounds, so if you open it as a stream, you may not want FMOD seeking to the first subsound and wasting time. You can use the initialsubsound member of the FMOD_CREATESOUNDEXINFO structure to make the non-blocking open seek to the subsound of your choice.

+
FMOD_RESULT result;
+FMOD::Sound *sound;
+FMOD_CREATESOUNDEXINFO exinfo;
+
+memset(&exinfo, 0, sizeof(FMOD_CREATESOUNDEXINFO));
+exinfo.cbsize = sizeof(FMOD_CREATESOUNDEXINFO);
+exinfo.initialsubsound = 1;
+
+result = system->createStream("../media/sounds.fsb", FMOD_NONBLOCKING, &exinfo, &sound);
+ERRCHECK(result);
+
+ +

Then get the subsound you wanted with Sound::getSubSound.

+

4.4 Avoiding Stalls While Loading or Releasing a Sound

+

One of the slowest operations is loading a sound. To place a sound load into the background so that it doesn't affect processing in the main application thread, the user can use the FMOD_NONBLOCKING flag in System::createSound or System::createStream.

+

Immediately a sound handle is returned to the user. The status of the sound being loaded can then be checked with Sound::getOpenState. If a function is called on a sound that is still loading (besides getOpenState), it will typically return FMOD_ERR_NOTREADY. Wait until the sound is ready to play it. The state would be FMOD_OPENSTATE_READY.

+

To avoid a stall on a streaming sound when trying to free/release it, check that the state is FMOD_OPENSTATE_READY before calling Sound::release.

+

4.5 Asynchronous I/O and Deferred File Reading

+

This tutorial describes how to defer file reading in FMOD so that you don't have to immediately satisfy FMOD's requests for data. This sort of behavior is highly desirable in game streaming engines that do not have access to the data yet, or for when accessing data out of order or in a non sequential fashion would greatly degrade performance. FMOD's asynchronous I/O callbacks will allow you to receive an FMOD read request and defer it to a later time when the game is ready. FMOD uses priorities to notify the game engine how urgent each read request is, as sometimes deferring a music stream read (for example) can result in stuttering audio.

+

4.5.1 Setup : Override FMOD's file system with callbacks

+

The idea is that you are wanting to override the file I/O that FMOD normally performs internally. You may have done this before with the System::setFileSystem by overriding the following callbacks:

+
FMOD_FILE_OPENCALLBACK  useropen
+FMOD_FILE_CLOSECALLBACK  userclose
+FMOD_FILE_READCALLBACK  userread
+FMOD_FILE_SEEKCALLBACK  userseek
+
+ +

The normal behavior here is that you would need to satisfy FMOD's read and seek requests immediately in a blocking fashion.
+In the open callback, you open your internal file handle and return it to FMOD, along with the file size.
+You would have to set all callbacks or file system override would not work. Any callback that is null in the above callback list will cause FMOD to use the default internal system and ignore your callbacks. All callbacks must be set.

+

With async I/O, there are 2 new callbacks which you can use to replace the 'userread' and 'userseek' callbacks:

+
FMOD_FILE_ASYNCREADCALLBACK  userasyncread
+FMOD_FILE_ASYNCCANCELCALLBACK  userasynccancel
+
+ +

If these callbacks are set, the 'userread' and 'userseek' callbacks are made redundant. You can of course keep 'userread' and 'userseek' defined if you want to switch between the 2 systems for some reason, but when 'userasyncread' is defined, the normal read/seek callbacks will never be called.

+

4.5.2 Defining the basics - opening and closing the file handle.

+

Before we start, we'll just define the open and close callback. A very simple implementation using stdio is provided below:

+
FMOD_RESULT F_CALLBACK myopen(const char *name, unsigned int *filesize, void **handle, void **userdata)
+{
+    if (name)
+    {
+        FILE *fp;
+
+        fp = fopen(name, "rb");
+        if (!fp)
+        {
+            return FMOD_ERR_FILE_NOTFOUND;
+        }
+
+        fseek(fp, 0, SEEK_END);
+        *filesize = ftell(fp);
+        fseek(fp, 0, SEEK_SET);
+
+        *userdata = (void *)0x12345678;
+        *handle = fp;
+    }
+
+    return FMOD_OK;
+}
+
+FMOD_RESULT F_CALLBACK myclose(void *handle, void *userdata)
+{
+    if (!handle)
+    {
+        return FMOD_ERR_INVALID_PARAM;
+    }
+
+    fclose((FILE *)handle);
+
+    return FMOD_OK;
+}
+
+ +

4.5.3 Defining 'userasyncread'

+

The idea for asynchronous reading, is that FMOD will request data (note, possibly from any thread - so be wary of thread safety in your code!), but you don't have to give the data to FMOD immediately. You can return from the callback without giving FMOD any data. This is deferred I/O.

+

For example, here is a definition of an async read callback:

+
FMOD_RESULT F_CALLBACK myasyncread(FMOD_ASYNCREADINFO *info, void *userdata)
+{
+    return PutReadRequestOntoQueue(info);
+}
+
+ +

Note that we didnt actually do any read here. You can return immediately and FMOD will internally wait until the read request is satisfied. Note that if FMOD decides to wait from the main thread (which it will do often), then you cannot satisfy the queue from the main thread, you will get a deadlock. Just put the request onto a queue. We'll discuss how to let FMOD know that the data is ready in the next section.

+

There are a few things to consider here:

+
    +
  • The callback could come from any thread inside FMOD's system. Usually this means FMOD's streaming thread, FMOD's file I/O thread, the main thread, or the FMOD_NONBLOCKING thread. Be thread safe! Use criticalsections around linked list/queue operations to avoid corruption of data.
  • +
  • Return code. This is usually a fatal, non disk related error such as not being able to add to the queue. This could be an out of memory error for example. Use FMOD_ERR_MEMORY as the return value if this is the case. Return FMOD_OK in normal cases. It normally won't be a return code related to a disk error. You have to set the 'result' code in the FMOD_ASYNCREADINFO structure to let FMOD know about a file based error.
  • +
  • Be wary that your queued command may need to be cancelled if the user decides to release the FMOD resource that is using that file, such as a sound. See the next section about myasynccancel in that case.
  • +
  • The FMOD_ASYNCREADINFO structure is where you fill in the data requested by FMOD. See below for a more detailed description of this structure and what is required to complete the read.
  • +
+

4.5.4 Defining 'userasynccancel'

+

If you have queued up a lot of read requests, and have not satisfied them yet, then it is possible that the user may want to release a sound before the request has been fulfilled (ie Sound::release is called).
+In that case FMOD will call the async cancel callback to let you cancel any operations you may have pending, that are related to this file.

+
FMOD_RESULT F_CALLBACK myasynccancel(void *handle, void *userdata)
+{
+    return SearchQueueForFileHandleAndRemove(info);
+}
+
+ +

Note that the above callback implementation will search through our internal linked list (in a thread safe fashion), removing any requests from the queue so that they don't get processed after the Sound is released. If it is in the middle of reading, then the callback will wait until the read is finished and then return.
+Do not return while a read is happening, or before a read happens, as the memory for the read destination will be freed and the deferred read will read into an invalid pointer.

+

4.5.5 Filling out the FMOD_ASYNCREADINFO structure when performing a deferred read

+

The FMOD_ASYNCREADINFO is the structure you will pass to your deferred I/O system, and will be the structure that you read and fill out when fulfilling the requests.

+

The structure exposes the features of the async read system. These are:

+
    +
  • Priority is supported. FMOD will let the user know if the read is not important, mildly important, or extremely important. This will allow the user to reshuffle the queue to make important reads happen before non important reads.
  • +
  • Read completion is signalled by simply setting the 'result' code of FMOD_ASYNCREADINFO.
  • +
  • Memory does not need to be copied anywhere, you can read directly into FMOD's pointers which point directly to the internal file buffers.
  • +
  • You do not have to give FMOD all of the data, you can give a partial read result to the callback and FMOD will most likely just issue another read request later with a smaller byte value.
  • +
+
typedef struct {
+  void *  handle;
+  unsigned int  offset;
+  unsigned int  sizebytes;
+  int  priority;
+  void *  buffer;
+  unsigned int  bytesread;
+  FMOD_RESULT  result;
+  void *  userdata;
+} FMOD_ASYNCREADINFO;
+
+ +

The first 4 members (handle, offset, sizebytes, priority) are read only values, which tell you about the file handle in question, where in the file it wants to read from (so no seek callbacks required!) and how many bytes it wants. The priority value tells you how important the read is as discussed previously.

+

The next 3 members (buffer, bytesread and result) are values you will fill in, and to let FMOD know that you have read the data.
+Read your file data into buffer. sizebytes is how much you should be reading. bytesread is how much you actually read (this could be less than sizebytes).
+If you hit the 'end of file' condition and need to return less bytes than were requested - set bytesread to less than sizebytes, and then set the result to FMOD_ERR_FILE_EOF.

+
+

Set the result last! Do not set the result before setting the bytesread value and reading the data into buffer. This is because the initial value for result is going to be FMOD_ERR_NOTREADY. When you set the value to FMOD_OK (or an appropriate error code) FMOD immediately sees this as an indication to continue, so if the bytesread or buffer contents are not ready you will get corruption, errors, or unexpected behavior. To prevent this, make setting result the last thing you do before finishing your queue process, after setting bytesread and filling in buffer.

+
+

4.5.6 Threading issues & read priorities

+

As mentioned earlier in this tutorial, FMOD can call the read callback from various different threads, so it is common sense to protect your I/O system from operations happening simultaneously from different threads.

+

A system that would use FMOD's async I/O feature would most likely be running in its own thread. This is so the blocking wait loops in FMOD's loading calls are not forever waiting for data because the user can't provide it to FMOD.
+If the system runs in another thread, it can detect the queue insert, and process the data while FMOD is waiting.

+

It is actually possible to complete the read as if it wasn't deferred, and do a direct file read into the buffer and set sizebytes/result values from the FMOD async read callback. This is a possible way to reduce delays for extremely urgent FMOD reads.

+

Currently there are 3 different categories of read priority.

+
    +
  • 0 = low priority. These reads are usually blocking style reads that come from a user load command, and there are no real negative side effects of delaying the read except that the load function takes longer. These reads are going to be issued from a System::createSound call for example.
  • +
  • 50 = medium priority. These reads are important, and usually come from the FMOD stream system. They can be delayed, but not for too long. If the delay is too long, then audio streams will starve, and possibly stutter. If you need to delay the read longer, the FMOD file buffer size can be increased with System::setStreamBufferSize
  • +
  • 100 = high priority. Currently the highest priority read issued by FMOD is when an audio stream loops. It must internally flush the stream buffer after a seek to loop start, and do so before the stream 'decode buffer' (the PCM double-buffer that the stream decoder decodes into) loops around and starts stuttering (this is a different buffer to the previously mentioned stream buffer. That one contains compressed file data. The decode buffer contains decompressed PCM data). The decode buffer is usually small so it is important to get the read done fast, but the user can also increase these buffers with FMOD_CREATESOUNDEXINFO::decodebuffersize. FMOD_ADVANCEDSETTINGS::defaultDecodeBufferSize can also be used to set all future decode buffer sizes for all streams without having to set it every time, and is going to be used for the Event System because decode buffer size is not something you can set for events individually.
  • +
+

4.6 Supported File Formats

+

We recommend using the .fsb file format for most purposes.

+

The Core API also has native/built in code to support many file formats out of the box. WAV, MP3 and Ogg Vorbis are supported by default, but many more obscure formats like AIFF, FLAC and others. Sequenced formats that are played back in realtime with a real time sequencer, are included. MIDI/MOD/S3M/XM/IT are examples of these. A more comprehensive list can be found in the FMOD_SOUND_TYPE list.

+

In addition, the Core API also has support for user-created file format plug-ins. You can create callbacks for FMOD to call when System::createSound or System::createStream is executed, or when the decoding engine is asking for data. Plug-ins can be created inline with the application, or compiled as a stand-alone dynamic library (ie .dll or .so). See the System::registerCodec documentation for more.

+ + +
+ + + diff --git a/FMOD/doc/FMOD API User Manual/managing-resources-in-the-core-api.html b/FMOD/doc/FMOD API User Manual/managing-resources-in-the-core-api.html new file mode 100644 index 0000000..254a555 --- /dev/null +++ b/FMOD/doc/FMOD API User Manual/managing-resources-in-the-core-api.html @@ -0,0 +1,256 @@ + + +Core API Managing Resources + + + + +
+ +
+

9. Core API Managing Resources

+

Measuring and tweaking performance is an important part of developing any application, and being able to scale FMOD from low power portable devices to the very latest in next gen consoles is key to our design. This chapter should give you a solid understanding of how to configure FMOD to fit within your audio budget, no matter which platforms you're targeting.

+

9.1 Virtual Voice System

+

The Core API includes a 'virtual voice system.' This system allows you to play hundreds or even thousands of Channels at once, but to only have a small number of them actually producing sound and consuming resources. The others are 'virtual,' emulated with a simple position and audibility update, and so are not heard and don't consume CPU time. For example: A dungeon may have 200 torches burning on the walls in various places, but at any given time only the loudest of these torches are really audible.

+

FMOD dynamically makes Channels 'virtual' or 'real' depending on real time audibility calculations (based on distance/volume/priority/occlusion). A Channel which is playing far away or with a low volume becomes virtual, and may change back into a real Channel when it comes closer or louder due to Channel or ChannelGroup API calls.

+

There are three situations in which a channel may become virtual:

+
    +
  • The channel's audibility falling below the Vol0 Virtual threshold. This threshold represents the loudness below which a channel is not audible, and thus the threshold below which it may be automatically virtualized without audibly affecting the mix. For information about Vol0 Virtual, see the VOL0 Virtual section of this chapter.
  • +
  • The maximum number of software (i.e.: non-virtual) channels channels being exceeded. When this occurs, the software channel with the lowest priority is automatically virtualized. If multiple software channels share the lowest priority, the least audible of those channels is virtualized. For more information about exceeding the maximum number of software channels, see the Software Channels vs Virtual Channels section of this chapter.
  • +
  • If using the Studio API, the channel's event instance being stolen and that event instance's stealing behavior being "virtualize." For more information about Studio API voice control, see the Studio API Voice Control section of this chapter.
  • +
+

9.1.1 Audibility Calculation

+

The virtual voice system automatically takes into account the following when calculating audibility:

+ +

A Channel can be queried for whether it is virtual with the Channel::isVirtual function. When going virtual, the sound's time will still be ticked and any fade points will still continue to interpolate. Any additional DSPs attached to the Channel will be preserved. When the Channel becomes real again, it will resume as if it had been playing properly.

+

9.1.2 Peak Volume

+

Peak volume is available for sounds that are exported via FSBank as long as the "Write peak volume" option is enabled. FMOD Studio tool always enables this flag when exporting banks, so FMOD Studio sounds will always have a peak volume. If the peak volume is not present (such as a loose wav file), then the sound is treated as if it had full volume.

+

9.1.3 VOL0 Virtual

+

An important part of the virtual voice system is the FMOD_INIT_VOL0_BECOMES_VIRTUAL flag. When this flag is enabled, Channels will automatically go virtual when their audibility drops below the limit specified in the FMOD_ADVANCEDSETTINGS vol0virtualvol field. This is useful to remove sounds which are effectively silent, which is both a performance and quality improvement. Since it is only removing silent sounds, there should be no perceived difference in sound output when enabling this flag.

+

It is strongly recommended that FMOD_INIT_VOL0_BECOMES_VIRTUAL is specified in System::init, and that the FMOD_ADVANCEDSETTINGS::vol0virtualvol field is set to a small non-zero amount, such as 0.001. If you're using the Studio API, FMOD_INIT_VOL0_BECOMES_VIRTUAL is automatically set when calling Studio::System::initialize, and vol0virtualvol can be set in System::setAdvancedSettings by getting the Studio::System::getCoreSystem after Studio::System::create but before Studio::System::initialize.

+

9.1.4 Channel Priority

+

FMOD provides a simple and powerful way of controlling which Channels go virtual, by using a Channel priority. Channel priority set with Channel::setPriority or Sound::setDefaults, where a smaller integer value corresponds to a higher (more important) priority. If a Channel is a higher priority than another, then it will always take precedence regardless of its volume, distance, or gain calculation. Channels with a high priority will never be stolen by those with a lower priority, ever. The only time a Channel with a high priority will go virtual is if other Channels with an equal or even higher priority are playing, or if FMOD_INIT_VOL0_BECOMES_VIRTUAL has been specified and the sound is effectively silent.

+

It is up to you to decide if some sounds should be more important than others. An example of an important sound might be a 2D menu or GUI sound or beep that needs to be heard above all other sounds.

+

We recommend not using too many priority levels in a single game. The benefit of audibility-based virtualization is that it ensures only the quietest and least-noticeable channels are virtualized, making the effect of channel virtualization as subtle and unnoticeable as possible. Having a larger number of channel priorities increases the liklihood of channels being stolen even when they are loud and noticeable, and thus undermines that benefit.

+

9.1.5 Software Channels vs Virtual Channels

+

To set the number of virtual Channels FMOD will use, call System::init with the number of virtual Channels specified in the maxchannels parameter. To set the number of software mixed Channels available, use System::setSoftwareChannels. A further limit is available per codec by using FMOD_ADVANCEDSETTINGS.

+

If the virtual Channel limit is hit then Channels will be stolen and start returning FMOD_ERR_INVALID_HANDLE. Channels which have had their handle stolen in this way are permanently stopped and will never return.

+

Assuming the number of playing Channels is below the maximum virtual Channel limit, then the Channel handle will remain valid, but the Channel may be virtual or real depending on audibility. The maximum number of real playing Channels will be the limit set by System::setSoftwareChannels, or the limits of the codecs set with FMOD_ADVANCEDSETTINGS.

+

For typical games, it is reasonable to set the maxchannels value of System::init to some high value, from a few hundred up to a thousand or more. The number of real software Channels is often set lower, at anywhere from 32 to 128. This allows the game to create and keep track of a large number of Channels, but still limit the CPU cost by having a small number actually playing at once.

+

9.1.6 Virtual to Real Transition

+

When channels stop being virtual, they resume from their proper place, part-way through the sound. To change this behavior, you can either use Sound or Channel priorities to stop it going virtual in the first place, or you have the option to have a Channel start from the beginning instead of half way through by using the FMOD_VIRTUAL_PLAYFROMSTART flag with System::createSound, System::createStream, Sound::setMode or ChannelControl::setMode.

+

As described above, only the quietest, least important sounds should be swapping in and out, so you shouldn't notice sounds 'swapping in', but if you have a low number of real Channels, and they are all loud, then this behavior could become more noticeable and may sound bad.

+

Another option is to simply call Channel::isVirtual and stop the sound, but don't do this until after a System::update! After System::playSound, the virtual Channel sorting needs to be done in System::update to process what is really virtual and what isn't.

+

9.1.7 Studio API Voice Control

+

In addition to the system provided by the Core API, the Studio API also allows you to limit playing Channels by using event polyphony: The sound designer can specify a limit to the number of simultaneously playing instances of an event. There are two modes for event polyphony: Channel stealing on, and channel stealing off.

+

Event Polyphony with Channel Stealing On

+

In this mode, once more instances are playing than the limit, some become virtual. Whether an event has become virtual can be queried with Studio::EventInstance::isVirtual. A virtual event mutes its master channel group; this causes any playing Channels to go virtual, as FMOD_INIT_VOL0_BECOMES_VIRTUAL is always set when using the Studio API.

+

Event virtualization is determined by an event's audibility, which is calculated based on the accumulated gain applied to the event's master track, as well any alterations applied to gain by fades, automation, and modulation. This includes:

+ +

Audibility is only calculated using the event's master channel group; the calculation does not include any gain applied to any child channels or channel groups.

+

An event which is virtual may become real at a later time if the audibility increases compared to the other playing instances.

+

Event Polyphony with Channel Stealing Off

+

In this mode, once the instance limit has been met, further instances will not play. Instances can still be created, and Studio::EventInstance::start can be called, but they will not actually play. Querying Studio::EventInstance::getPlaybackState will show that the extra instances are not in the playing state. Once instances fail to play then they will not start at a later time, regardless of what happens to the other instances. In this mode, event audibility has no affect on which instances play, it is simply based on which had Studio::EventInstance::start called first.

+

Interaction with the Core API Virtual Voice System

+

FMOD Studio events ultimately create one or more core Channel objects to play sound. These Channels can go real or virtual based on the max software Channels set at initialization time. Therefore, it is possible to have events where Studio::EventInstance::isVirtual is false, but some or all of the underlying Channels are virtual due to the software Channel limit. The Core API voice system takes into account the bus set-up, distance attenuation, volume settings, and other DSP effects on Studio buses.

+

Studio Events can influence and override the Core API's virtual voice selection system with the priority value controlled per-event in FMOD Studio. Any Channels created by an event have the priority value set for their event in the FMOD Studio Tool - and a higher priority Channel can never be stolen by a lower priority Channel, even if it is very quiet. Unlike priorities set in the Core API, FMOD Studio only exposes five potential priority values. This is done deliberately, since priority should not be used in a fine-grained way.

+

Event Priority is not inherited for nested events. It is therefore possible for a high priority event to have low priority nested events. In such a case, the Channels of the nested events may be virtualized, regardless of the parent event's high priority.

+

9.1.8 Core API Profiler

+

The Core API profiler tool displays the DSP graph, and can be used to quickly see which Channels have gone virtual. Consider the Channel Groups Example. If we add FMOD_INIT_PROFILE_ENABLE and add a call to System::setSoftwareChannels with 5, then we see one of the 6 Channels has gone virtual:

+

Virtual DSP Graph

+

9.2 Non blocking loads, threads and thread safety

+

Core API commands are thread safe and queued. They get processed either immediately, or in background threads, depending on the command.

+

By default, things like initialization and loading a Sound are processed on the main thread.

+

Mixing, streaming, geometry processing, file reading and file loading are or can be done in the background, in background threads. Every effort is made to avoid blocking the main application's loop unexpectedly.

+

One of the slowest operations is loading a Sound. To place a Sound load into the background so that it doesn't affect processing in the main application thread, the user can use the FMOD_NONBLOCKING flag in System::createSound or System::createStream.

+

FMOD thread types:

+ +

9.2.1 Thread Affinity

+

On some platforms, FMOD thread affinity can be customized. See the platform specific Platform Details page for more information.

+

9.2.2 FMOD Callback Types

+

FMOD File and memory callbacks can possibly be called from an FMOD thread. Remember that if you specify file or memory callbacks with FMOD, to make sure that they are thread safe. FMOD may call these callbacks from other threads.

+

9.2.3 Core API Thread Safety

+

By default, the Core API is initialized to be thread safe, which means the API can be called from any game thread at any time. Core API thread safety can be disabled with the FMOD_INIT_THREAD_UNSAFE flag in System::init or Studio::System::initialize. The overhead of thread safety is that there is a mutex lock around the public API functions and (where possible) some commands are enqueued to be executed the next system update. The cases where it is safe to disable thread safety are:

+
    +
  • The game is using Studio API exclusively, and never issues Core API calls itself.
  • +
  • The game is using the Core API exclusively, and always from a single thread at once.
  • +
  • The game is using Studio API and Core API at the same time, but FMOD Studio is created with FMOD_STUDIO_INIT_SYNCHRONOUS_UPDATE and the Core API calls are done in the same thread as the Studio API calls.
  • +
+

9.2.4 Studio API Thread Safety

+

By default, the Studio API is completely thread safe, and all commands execute on the Studio API update thread. In the case of a function that returns a handle, that handle is valid as soon as the function returns it, and all functions using that handle are immediately available. As such, if a command is delayed, the delay is not immediately obvious, and does not delay subsequent commands on the thread.

+

If Studio::System::initialize is called with FMOD_STUDIO_INIT_SYNCHRONOUS_UPDATE, then Studio will not be thread-safe as it assumes all calls will be issued from a single thread. Commands in this mode will be queued up to be processed in the next Studio::System::update call. This mode is not recommended except for testing or for users who have set up their own asynchronous command queue already and wish to process all calls on a single thread. See the Studio Thread Overview for further information.

+

9.3 CPU Performance

+

Before we jump into the details, let's first consider how performance is measured in the FMOD Engine. The primary metric we use, when discussing how expensive something is, is CPU percentage. We can calculate this by measuring the time spent performing an action and comparing it against a known time window; the most common example of this is DSP or mixer performance.

+

When we talk about mixer performance we are actually talking about the production of audio samples being sent to the output (usually your speakers). At regular intervals, our mixer produces a buffer of samples which represents a fixed amount of time for playback. We call this a DSP block. DSP block size often defaults to 512 samples, which when played back at 48 kHz represents ~10ms of audio.

+

With a fixed amount of samples being produced regularly, we can now measure how long it takes to produce those samples and receive a percentage. For example, if it took us 5ms of CPU time to produce 10ms of audio, our mixer performance would be 50%. As the CPU time approaches 10ms we risk not delivering the audio in time which results in an audio discontinuity known as stuttering.

+

Another key performance area is update(). This operation is called regularly to do runtime housekeeping. Our recommendation is you call update() once per render frame, which is often 30 or 60 times per second. Using the 30 or 60 FPS (frames per second) known time frame, we can measure CPU time spent performing this action to get percentages.

+

Armed with the ability to measure performance, we need to identify the things that cost the bulk of the CPU time. The most commonly quoted contributor is Channel count, following the logic that playing more Channels takes up more CPU time. Following is a list of the main contributors to the cost of sound playback:

+
    +
  • Decoding compressed audio to PCM.
  • +
  • Resampling the PCM to the appropriate pitch.
  • +
  • Applying DSP effects to the Channel.
  • +
  • Mixing the audio with other sounds to produce the final output you hear.
  • +
+

9.3.1 Compression Format

+

Choosing the correct compression format for the kind of audio you want to play and the platform you want to play it on is a big part of controlling the CPU cost. For recommendations on format choice, see the Platform Details chapter.

+

9.3.2 Voice Limiting

+

Once you've settled on a compression format, you need to decide how many Channels of that format you want to be audible at the same time. There are three ways you can use to control the number of Channels playable:

+ +

For a deep dive into how the virtual voice system works and ways to further control Channel count, see the Virtual Voice System.

+

9.3.3 Tips and Tricks

+

With a correctly configured compression format and appropriate Channel count, you are well on your way to an efficiently configured set up. Next up is a series of CPU-saving tips to consider for your project. Not all are applicable to every project, but they should be considered if you want to get the best performance from the FMOD Engine.

+

Adjust Sample Rates

+

There are two sample rates you need to think about when optimizing, the system sample rate and the source audio sample rate.

+

You can control the system sample rate by using System::setSoftwareFormat (sampleRate, ...), which by default is 48 kHz. Reducing this can give some big wins in performance because less data is being produced. This setting is a trade off between performance and quality.

+

To control the source audio rate, you can resample using your favorite audio editor or use the sample rate settings when compressing using the FSBank tool or the FSBankLib API. All audio is sent to a resampler when it is played at runtime. If the source sample rate and the System rate match and there are no pitch / frequency settings applied to the Channel, the resampler is skipped, saving CPU time. This trick is often good for music and other sounds that rarely require real-time pitch adjustment.

+

Increase DSP Block Size

+

As mentioned earlier, the DSP block size represents a fixed amount of samples that are produced regularly to be sent to the speakers. When producing each block of samples, there is a fixed amount of overhead, so making the block size larger reduces the overall CPU cost. You can control this setting with System::setDSPBufferSize (blockLength, ...), which often defaults to 512 or 1024 samples, depending on the platform.

+

The trade off with this setting is CPU against mixer granularity. For more information about the implications of changing this setting, see the System::setDSPBufferSize section of the Core API Reference chapter.

+

Reduce Speaker Channel Count

+

This section refers to channel count in the context of speaker channels as they exist in audio files.

+

Controlling how many channels of audio are being played can have a big impact on performance. Consider the simple math that a 7.1 surround signal has eight channels, and thus four times as much data to process as a stereo signal. There are a few different places where speaker channel count can be controlled to improve performance.

+

The source audio channel count should be carefully chosen. Often mono sources are best, especially for sounds that are positioned in 3D. Reducing the channel count at the source is an easy win, and also decreases the decoding time for that sound.

+

Setting the system channel count controls how 3D sounds are panned when they are given a position in the world. You set this channel count by specifying a speaker mode that represents a well known speaker configuration, such as 7.1 surround or stereo. To do this, use System::setSoftwareFormat (..., speakerMode, ...). The default value of this parameter matches your output device settings.

+

As a more advanced setting, you can limit the number of speaker channels produced by a sub-mix, or the number of channels entering a particular DSP effect. This can be especially useful for limiting the channels into an expensive effect. The API to control this is DSP::setChannelFormat(..., speakerMode). By default, this parameter is the output of the previous DSP unit.

+

Choose Inexpensive DSPs

+

Not all DSPs are created equal. Some are computationally simple and use very little CPU, others can be quite expensive. When deciding to use a particular effect, it is important to profile on the target platforms' hardware to fully understand the CPU implications.

+

The positioning of an effect in the DSP graph can make a big difference on a game's resource cost. Placing an effect on every channel routed into a channel group means it can affect each of those channels differently, but costs a lot more CPU time than placing that effect only on the channel group. There are no strict rules for where each effect should be positioned, but to give an example, multiband equalizer DSP effects are cheap enough that they can often be applied to every channel without straining a game's resource budget, while the SFX reverb DSP effect is expensive enough that it's more common to add a single instance of it to a channel group so that it's applied to the sub-mix.

+

Take Advantage of Hardware Decoding

+

Some platforms have access to hardware assisted decoders, which offload the processing from the CPU to dedicated decoding hardware. These can be utilized by building banks with the corresponding platform's format, such as AT9, XMA, or Opus.

+

When using hardware assisted decoders with streams, each Channel reserves a hardware decoder for the lifetime of the Channel. This means that the Virtual Voice System is not able to steal any hardware decoders that are in use. As a result, if all hardware decoders are in use, new streamed Channels cannot play until an existing streamed Channel stops and yields its decoder. Therefore, you should not rely on the Virtual Voice System to cull streamed Channels when using hardware decoders. Treat hardware decoders as you would any other limited resource, only using what you need and freeing Channels when they are no longer required.

+

9.4 Custom File Systems and Memory Management

+

The Core API caters to the needs of applications and their memory and file systems. A file system can be 'plugged in' so that FMOD uses it, and not its own system, as well as memory allocation.

+

To set up a custom file system is a simple process of calling System::setFileSystem.

+

The file system handles the normal cases of open, read, seek, close, but adds an extra feature which is useful for prioritized/delayed file systems, FMOD supports the FMOD_FILE_ASYNCREAD_CALLBACK callback, for deferred, prioritized loading and reading, which is a common feature in advanced game streaming engines.

+

An async read callback can immediately return without supplying data, then when the application supplies data at a later time, even in a different thread, it can set the 'done' flag in the FMOD_ASYNCREADINFO structure to get FMOD to consume it. Consideration has to be made to not wait too long or increase stream buffer sizes, so that streams don't audibly stutter/skip.

+

To set up a custom memory allocator is done by calling Memory_Initialize. This is not an FMOD class member function because it needs to be called before any FMOD objects are created, including the System object.

+

To read more about setting up memory pools or memory environments, see the Memory Management section of the Managing Resources in the Core API chapter.

+

9.5 Memory Management

+

The following are some pointers on ways of saving memory in the FMOD Engine.

+

9.5.1 Use a Fixed-size Memory Pool.

+

To make the FMOD Engine stay inside a fixed size memory pool, and not do any external allocs, you can use the Memory_Initialize function. i.e.:

+
result = FMOD::Memory_Initialize(malloc(4*1024*1024), 4*1024*1024, 0,0,0);  // allocate 4mb and pass it to the FMOD Engine to use.
+ERRCHECK(result);
+
+ +

Alternatively, you can use this function to specify your own callbacks for alloc and free. If you do, the memory pool pointer and length must be NULL.

+

9.5.2 Lower Sound Instance Overhead.

+

The FMOD_LOWMEM flag can be used to shave some memory off of the sound class. This flag removes memory allocation for certain features which aren't used often in games. For example, it removes the 'name' field, so if Sound::getName is called when this flag is set, it returns "(null)".

+

9.5.3 Use Compressed Samples

+

The FMOD Engine can play ADPCM, AT9, MP2/MP3, Opus, and XMA data compressed, without needing to decompress them to PCM first. This can save a large amount of memory, at the cost of requiring more CPU time when the sound is played.

+

To enable this, use the FMOD_CREATECOMPRESSEDSAMPLE flag when calling System::createSound. When using formats other than the ones specified above or platforms that do not support those formats, this flag is ignored.

+

On platforms that support hardware decoding, using this flag results in the platform hardware decoder decompressing the data without affecting the main CPU. For information about what platforms support hardware decoding and which encoding formats they support, see the Platform Details chapter.

+

Using FMOD_CREATECOMPRESSEDSAMPLE incurs a 'one off' memory overhead cost, as it allocates the pool of codecs required to play the encoding format of the sample data. For information on how to control this pool, see the following section.

+

9.5.4 Control Memory Usage with Settings

+

For sounds created with FMOD_CREATECOMPRESSEDSAMPLE, System::setAdvancedSettings allows you to reduce the number of simultaneous XMA/ADPCM or MPEG sounds played at once, to save memory. The defaults are specified in the documentation for this function. Lowering them reduces memory consumption. The pool of codecs for each codec type is only allocated when the first sound of that type is loaded, so reducing XMA (for example) to 0 when XMA is never used does not save any memory.

+

For streams, setting System::setStreamBufferSize controls the memory usage for the stream buffer used for each stream. Lowering the size in this function reduces memory consumption, but may also lead to stuttering streams. This is purely based on the type of media the FMOD streamer is reading from (e.g.: a CD-ROM is slower than a hard disk), so you should experiment with your target platforms' hardware to determine whether changing the stream buffer size will cause problems.

+

Reducing the number of Channels used reduces memory consumption. System::init's maxchannels parameter sets the maximum number of concurrent voices, and System::setSoftwareChannels sets the maximum number of concurrent real voices. You should specify enough voices though to avoid Channel stealing.

+

9.5.5 Tracking FMOD memory usage.

+

Using Memory_GetStats is a good way to track FMOD memory usage, and also find the highest amount of memory allocated at any time. This information is useful when attempting to trim or adjust your project's memory consumption; for example, when adjusting the fixed memory pool size.

+ + +
+ + + diff --git a/FMOD/doc/FMOD API User Manual/mixing-and-routing-in-the-core-api.html b/FMOD/doc/FMOD API User Manual/mixing-and-routing-in-the-core-api.html new file mode 100644 index 0000000..4c51622 --- /dev/null +++ b/FMOD/doc/FMOD API User Manual/mixing-and-routing-in-the-core-api.html @@ -0,0 +1,660 @@ + + +Core API Mixing and Routing + + + + +
+ +
+

6. Core API Mixing and Routing

+

This chapter covers the many ways in which channel groups and the dsp graph can be used to manipulate and process your game's sounds.

+

6.1 Channel Groups and Routing

+

While it is possible to add the same effect to multiple channels, creating a submix of those channels and adding the effect to that submix requires only a single instance of the effect, and thus consumes fewer resources. This reduces CPU usage greatly.

+

The primary tool for achieving this in FMOD Studio and the Studio API is the "bus"; in the Core API, it is the "channel group." If multiple channels are routed into the same bus or channel group, the it creates a sub-mix of those signals. If an effect is added to that bus or ChannelGroup, the effect only processes that sub-mix, rather than processing every individual Channel that contributed to it.

+

The volume of a ChannelGroup can be altered, which allows for master volume groups. The volume is scaled based on a fader DSP inside a ChannelGroup. All Channels and ChannelGroups have a fader DSP by default.

+

ChannelGroups are hierarchical. ChannelGroups can contain ChannelGroups, which can contain other ChannelGroups and Channels.

+

Many attributes can be applied to a ChannelGroup, including things like speaker mix, and 3D position. A whole group of Channels, and the ChannelGroups below them, can be positioned in 3D with 1 call, rather than trying to position all of them individually.

+

'Master Volume', 'SFX Volume' and 'Music Volume' are typical settings in a game. Setting up an 'SFX' ChannelGroup, and a 'Music' ChannelGroup, and having them children of the master ChannelGroup (see System::getMasterChannelGroup)

+

6.1.1 Channel and Channel Group Handles

+

All FMOD types, whether they are represented internally via pointer or handle, look like a pointer type. No matter the type, a null pointer will never be returned as a valid result, but it is not safe to assume anything else about the pointer value. Do not assume that the pointer value falls in any particular address range, or that it has any zero bits in the bottom of the pointer value address.

+

All FMOD types are equivalent for both the C and C++ API. It is possible to cast between the appropriate types by re-interpreting the pointer type directly.

+

FMOD Channels are returned to you as a pointer, but actually consist of 32 bits of packed integer handle data. This allows Channels to be re-used safely.

+

If a Channel is stopped with ChannelControl::stop or ends naturally, the Channel handle will become invalid and return FMOD_ERR_INVALID_HANDLE.

+

If not enough Channels are specified at System::init and an existing virtual Channel is stolen by the FMOD priority system, then the handle to the stolen Channel becomes 'invalid'. Subsequent Channel commands to a stolen handle will return FMOD_ERR_CHANNEL_STOLEN.

+

FMOD ChannelGroups are returned to you directly as a pointer. Once you destroy a ChannelGroup, it is no longer safe to call FMOD functions with that pointer.

+

6.2 Upmix/Downmix Behavior

+

FMOD handles downmixing using mix matrices. Below you can find the various mix matrix layouts, with each table representing a separate output format. In each table, speakers in the "Output" column are assigned levels from the incoming speaker formulas in the relevant row, according to the incoming speaker layout. Different mix matrix layouts can be set using ChannelControl::setMixMatrix. See FMOD_SPEAKER and FMOD_SPEAKERMODE for more details on existing speaker layouts.
+For an improved result when using 5.1 on a stereo output device,the Dolby Pro Logic II downmix algorithm can be chosen by specifying FMOD_INIT_PREFER_DOLBY_DOWNMIX as an init flag when calling System::init.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
KeyValue
MMono
LLeft
RRight
FLFront Left
FRFront Right
CCenter
LFELow Frequency Effects
SLSurround Left
SRSurround Right
BLBack Left
BRBack Right
TFLTop Front Left
TFRTop Front Right
TBLTop Back Left
TBRTop Back Right
+

6.2.1 Mono

+
+ + + + + + + + + + + + + + + + + + + + + + + + + +
OutputMonoStereoQuad5.05.17.17.1.4
MML x 0.707 + R x 0.707FL x 0.500 + FR x 0.500 + SL x 0.500 + SR x 0.500FL x 0.447 + FR x 0.447 + C x 0.447 + BL x 0.447 + BR x 0.447FL x 0.447 + FR x 0.447 + C x 0.447 + BL x 0.447 + BR x 0.447FL x 0.378 + FR x 0.378 + C x 0.378 + SL x 0.378 + SR x 0.378 + BL x 0.378 + BR x 0.378FL x 0.378 + FR x 0.378 + C x 0.378 + SL x 0.378 + SR x 0.378 + BL x 0.378 + BR x 0.378
+
+

6.2.2 Stereo

+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
OutputMonoStereoQuad5.05.17.17.1.4
LM x 0.707LFL + SL x 0.707FL + C x 0.707 + BL x 0.707FL + C x 0.707 + BL x 0.707FL + C x 0.707 + SL x 0.707 + BL x 0.596FL + C x 0.707 + SL x 0.707 + BL x 0.596
RM x 0.707RFR + SR x 0.707FR + C x 0.707 + BR x 0.707FR + C x 0.707 + BR x 0.707FR + C x 0.707 + SR x 0.707 + BR x 0.596FR + C x 0.707 + SR x 0.707 + BR x 0.596
+
+

6.2.3 Quad

+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
OutputMonoStereoQuad5.05.17.17.1.4
FLM x 0.707LFLFL + C x 0.707FL + C x 0.707FL x 0.965 + FR x 0.258 + C x 0.707 + SL x 0.707FL x 0.965 + FR x 0.258 + C x 0.707 + SL x 0.707
FRM x 0.707RFRFR + C x 0.707FR + C x 0.707FL x 0.258 + FR x 0.965 + C x 0.707 + SR x 0.707FL x 0.258 + FR x 0.965 + C x 0.707 + SR x 0.707
SLSLBLBLSL x 0.707 + BL x 0.965 + BR x 0.258SL x 0.707 + BL x 0.965 + BR x 0.258
SRSRBRBRSR x 0.707 + BL x 0.258 + BR x 0.965SR x 0.707 + BL x 0.258 + BR x 0.965
+
+

6.2.4 Surround

+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
OutputMonoStereoQuad5.05.17.17.1.4
FLM x 0.707LFL x 0.961FLFLFL + SL x 0.367FL + SL x 0.367
FRM x 0.707RFR x 0.961FRFRFR + SR x 0.367FR + SR x 0.367
CCCCC
BLFL x 0.274 + SL x 0.960 + SR x 0.422BLBLSL x 0.930 + BL x 0.700 + BR x 0.460SL x 0.930 + BL x 0.700 + BR x 0.460
BRFR x 0.274 + SL x 0.422 + SR x 0.960BRBRSR x 0.930 + BL x 0.460 + BR x 0.700SR x 0.930 + BL x 0.460 + BR x 0.700
+
+

6.2.5 5.1

+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
OutputMonoStereoQuad5.05.17.17.1.4
FLM x 0.707LFL x 0.961FLFLFL + SL x 0.367FL + SL x 0.367
FRM x 0.707RFR x 0.961FRFRFR + SR x 0.367FR + SR x 0.367
CCCCC
LFELFELFELFE
BLFL x 0.274 + SL x 0.960 + SR x 0.422BLBLSL x 0.930 + BL x 0.700 + BR x 0.460SL x 0.930 + BL x 0.700 + BR x 0.460
BRFR x 0.274 + SL x 0.422 + SR x 0.960BRBRSR x 0.930 + BL x 0.460 + BR x 0.700SR x 0.930 + BL x 0.460 + BR x 0.700
+
+

6.2.6 7.1

+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
OutputMonoStereoQuad5.05.17.17.1.4
FLM x 0.707LFL x 0.939FLFLFLFL
FRM x 0.707RFR x 0.939FRFRFRFR
CCCCC
LFELFELFELFE
SLFL x 0.344 + SL x 0.344BL x 0.883BL x 0.883SLSL
SRFR x 0.344 + SR x 0.344BR x 0.883BR x 0.883SRSR
BLSL x 0.939BL x 0.470BL x 0.470BLBL
BRSR x 0.939BR x 0.470BR x 0.470BRBR
+
+

6.2.7 7.1.4

+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
OutputMonoStereoQuad5.05.17.17.1.4
FLM x 0.707LFL x 0.939FLFLFLFL
FRM x 0.707RFR x 0.939FRFRFRFR
CCCCC
LFELFELFELFE
SLFL x 0.344 + SL x 0.344BL x 0.883BL x 0.883SLSL
SRFR x 0.344 + SR x 0.344BR x 0.883BR x 0.883SRSR
BLSL x 0.939BL x 0.470BL x 0.470BLBL
BRSR x 0.939BR x 0.470BR x 0.470BRBR
TFLTFL
TFRTFR
TBLTBL
TBRTBR
+
+ + +
+ + + diff --git a/FMOD/doc/FMOD API User Manual/platforms-android.html b/FMOD/doc/FMOD API User Manual/platforms-android.html new file mode 100644 index 0000000..312fa20 --- /dev/null +++ b/FMOD/doc/FMOD API User Manual/platforms-android.html @@ -0,0 +1,287 @@ + + +Platform Details | Android + + + + +
+ +
+

17. Platform Details | Android

+ +

Android Specific Starter Guide

+

SDK Version

+

FMOD is compiled using the following tools.

+
    +
  • NDK - version r26b targeting android-21 (32bit and 64bit).
  • +
  • SDK - platform version 34.
  • +
+

Compatibility

+

FMOD supports devices of the below ABIs back to API level 21 (Android 5.0, Lollipop).

+
    +
  • armeabi-v7a - supported and optimized with VFPv2 (and NEON if detected at runtime).
  • +
  • arm64-v8a - supported and optimized with NEON.
  • +
  • x86 - supported and optimized with SSE3.
  • +
  • x86_64 - supported and optimized with SSE3.
  • +
  • mips - unsupported due to limited demand.
  • +
  • mips64 - unsupported due to limited demand.
  • +
  • armeabi - unsupported from FMOD 2.2 due to NDK deprecation.
  • +
+

Libraries

+

Substitute $ABI with your desired ABI from the 'Compatibility' list above.

+

Core API library

+
    +
  • /api/core/lib/$ABI/libfmod.so - Release binary for production code.
  • +
  • /api/core/lib/$ABI/libfmodL.so - Release binary with logging enabled for development.
  • +
+

Studio API library (used in conjunction with the core API library)

+
    +
  • /api/studio/lib/$ABI/libfmodstudio.so - Release binary for production code.
  • +
  • /api/studio/lib/$ABI/libfmodstudioL.so - Release binary with logging enabled for development.
  • +
+

Java

+

FMOD is primarily a native C/C++ library implementation but does have a Java component that is invoked from native code. To ensure the Java component is properly operating please make sure you reference the fmod.jar in your project. This means telling the IDE or build system where to find the fmod.jar file so it's included in the application.

+

It is also highly recommended that you initialize the FMOD Java component, this will allow loading assets from the APK and automatic configuration for lowest latency. This should be done before System_Create or Studio::System::create, and should be closed after System::release or Studio::System::release.

+

A basic example is listed below, for more details please check the provided examples.

+
public class MainActivity extends Activity
+{
+    @Override
+    protected void onCreate(Bundle savedInstanceState)
+    {
+        org.fmod.FMOD.init(this);
+    }
+
+    @Override
+    protected void onDestroy()
+    {
+        org.fmod.FMOD.close();
+    }
+}
+
+static
+{
+    System.loadLibrary("fmod");
+}
+
+ +

If you do not have a Java activity class, you can use FMOD_Android_JNI_Init to perform the org.fmod.FMOD.init and System.loadLibrary initialization actions natively. You can likewise use FMOD_Android_JNI_Close to perform the org.fmod.FMOD.close cleanup. For example:

+
void android_main(struct android_app* app)
+{
+    jniEnv = NULL;
+    app->activity->vm->AttachCurrentThread(&jniEnv, NULL);
+    FMOD_Android_JNI_Init(app->activity->vm, app->activity->clazz);
+
+    // ... game loop
+
+    FMOD_Android_JNI_Close();
+    app->activity->vm->DetachCurrentThread();
+}
+
+ +

Examples

+

FMOD examples are shipped as Android Studio projects using the Gradle build system with the Android Gradle plug-in. Examples are provided for using both CMake and ndk-build to perform the external native build:

+
    +
  • /api/(core|studio)/examples/androidstudio/cmake - Examples using CMake to perform the external native build.
  • +
  • /api/(core|studio)/examples/androidstudio/ndkbuild - Examples using ndk-build to perform the external native build.
  • +
+

Linking FMOD to your code

+

To link FMOD into your native code refer to the Android documentation relevant to the build tools you are using. You may also find it helpful to refer to the Android.mk files or the CMakeLists.txt files from the FMOD examples.

+

Audio Latency

+

Reducing the amount of audio latency between calling an API function and hearing its effect is generally controlled via System::setDSPBufferSize. However it should be noted that on this platform there is significantly more OS latency (which is out of the control of developers). It is currently not mandatory for device manufactures to adhere to audio latency guidelines (section 5.3 Audio Latency of the Android CDD). Devices which report FEATURE_AUDIO_LOW_LATENCY will be able to achieve lower latency playback. This is handled internally by FMOD and requires no additional configuration. Latency test results for specific devices can be found on the Superpowered Latency Table.

+

Pairing with a BlueTooth speaker or headset will incur significant extra latency, 120ms in some tests. This is currently unavoidable due to the OS taking extra buffering beyond developer control.

+

Asset Manager

+

To load files from the APK using the Asset Manager (for files stored in the asset directory at build time) you need to use a special syntax. FMOD will recognize any path that is prefixed with file:///android_asset/ as an asset, so passing a path of file:///android_asset/drumloop.wav will load the file drumloop.wav which was stored in the asset directory at build time. For this functionality to work your device must be running Gingerbread or newer and have called org.fmod.FMOD.init from Java.

+

Native Threads

+

If you call FMOD from a native thread (not Java) you will need to ensure the thread is attached to the Java runtime environment JavaVM::AttachCurrentThread. It's recommended you remain attached for the life of the thread but you may call JavaVM::DetachCurrentThread after the invocation of FMOD if you prefer.

+

FMOD often makes calls to Java code contained within fmod.jar and therefore requires the thread to be attached. All internal FMOD threads are attached when they are created so this only concerns user threads.

+

Suspend in Background

+

FMOD native threads continue running when your application transitions to the background, and so continue to use resources. To completely stop the FMOD Engine without losing your current setup you can call System::mixerSuspend as part of your backgrounding process. When you return to the foreground, use System::mixerResume to reactivate the FMOD Engine. It is extremely important to ensure no FMOD APIs are called between suspend and resume, as they would run the risk of causing a deadlock. You must also call suspend and resume pairs on the same thread.

+

Suspending Recording on Exit

+

Input streams are not guaranteed to be released when closing the application. If you are using audio input features such as System::recordStart and System::recordStop, calling System::mixerSuspend during backrounding is recommended to avoid leaking stream resources.

+

AAudio Device Selection

+

If you are targeting API 23 and above, you can access all valid input and output devices when using FMOD_OUTPUTTYPE_AAUDIO. Some of these devices may require special permissions, feature sets, or API handling that are not available on all Android devices, and it is your responsibility to meet these prerequisites if you want to target that device type.
+The device id can be retrieved from the Data1 value stored in the FMOD_GUID returned from System::getDriverInfo or System::getRecordDriverInfo, and the device type will be stored in the Data3 value. The device type can be compared to the corresponding Android AudioDeviceInfo type constants, and any special handling for that device type will need to be implemented before calling System::setDriver or System::recordStart with that device.

+

If you are targeting API 28 and above, each AAudio input device has a corresponding device containing a "(Voice)" suffix in its name, and a Data2 value of true stored in the FMOD_GUID returned from System::getRecordDriverInfo. These input devices use the same physical device as their non-"(Voice)" counterpart, but have hardware echo cancellation enabled as well.

+

Permissions

+

Some functionality inside of FMOD will require you set relevant permissions in your AndroidManifest.xml file.

+ +

Thread Affinity

+

All threads will default to FMOD_THREAD_AFFINITY_CORE_ALL, this is recommended due to the wide variety of devices available but can be customized with Thread_SetAttributes.

+

Thread Priority

+

The relationship between FMOD platform agnostic thread priority and the platform specific values is as follows:

+ +

Known Issues

+
    +
  • The Audio Track output mode currently does not support recording, please use the OpenSL output mode for this.
  • +
  • The Snapdragon Profiler created by Qualcomm has a bug when displaying system trace information. The trace will indicate that the "AudioTrack" thread executes for several milliseconds when in fact it does not. The "AudioTrack" thread is created by the OpenSL output plug-in and is responsible for calling into FMOD to fetch audio. FMOD services this request efficiently with lock free data structures and returns in microseconds to avoid any audio glitches. To verify the behavior of this thread use the Android System Trace viewer instead of the Snapdragon Profiler.
  • +
+

Application Lifecycle Management

+

FMOD will happily continue to operate when your device is in the background, for media playback applications this may be desirable. For the vast majority of use cases though, you want FMOD to be quiet and use no CPU. You can achieve this goal by using System::mixerSuspend and System::mixerResume, often it is convenient to implement these in the activity onStart and onStop overrides. To avoid issues when shutting down ensure you resume the mixer before releasing, it is recommended you perform this in the onDestroy override.

+

Example Java code

+
@Override
+protected void onStart()
+{
+    super.onStart();
+    setStateStart();
+}
+
+@Override
+protected void onStop()
+{
+    setStateStop();
+    super.onStop();
+}
+
+@Override
+protected void onDestroy()
+{
+    setStateDestroy();
+    super.onDestroy();
+}
+
+private native void setStateStart();
+private native void setStateStop();
+private native void setStateDestroy();
+
+ +

Example C++ code

+
void Java_org_fmod_example_MainActivity_setStateStart(JNIEnv *env, jobject thiz)
+{
+    gSystem->mixerResume();
+}
+
+void Java_org_fmod_example_MainActivity_setStateStop(JNIEnv *env, jobject thiz)
+{
+    gSystem->mixerSuspend();
+}
+
+void Java_org_fmod_example_MainActivity_setStateDestroy(JNIEnv *env, jobject thiz)
+{
+    gSystem->mixerResume();
+}
+
+ +

The result of using this API will be the halt of the audio hardware and a complete lock of all FMOD threads. It is important that you do not call any FMOD API functions after System::mixerSuspend other than System::mixerResume, even if you intend to shutdown FMOD as you may cause a deadlock.

+

Performance Reference

+

This section is a companion for the CPU Performance section of the Managing Resources in the Core API chapter and serves as a quick reference of facts targeting this platform.

+

Format Choice

+

Each compression format provided in FMOD has a reason for being included, the below list will detail our recommendations for this platform. Formats listed as primary are considering the best choice, secondary formats should only be considered if the primary doesn't satisfy your requirements.

+
    +
  • FADPCM: Primary format for all sounds.
  • +
  • Vorbis: Secondary format for long streams if FADPCM compression is too low.
  • +
  • PCM: Secondary format for short sounds if FADPCM cost is too high.
  • +
  • XMA: Unavailable.
  • +
  • AT9: Unavailable.
  • +
+

Channel Count

+

To give developers an idea about the costs of a particular format we provide synthetic benchmark results. These results are based on simple usage of the Studio API using recommended configuration settings.

+

Due to the CPU governor that controls the power saving features of the device, getting accurate CPU numbers requires rooting the device and setting the CPU frequency to maximum.

+

Settings

+
    +
  • Real channel count: 32
  • +
  • Sample rate: 24 kHz
  • +
  • Speaker mode: Stereo
  • +
  • DSP block size: 512 samples
  • +
+

Test Device: A

+
    +
  • CPU: SHIELD Android TV
  • +
  • OS: Android 9
  • +
+

Results: A

+
    +
  • DSP with Vorbis: 8.66% (+/- 1.28%)
  • +
  • DSP with FADPCM: 2.64% (+/- 0.21%)
  • +
  • DSP with PCM: 1.98% (+/- 0.22%)
  • +
  • Update at 60 FPS: 1.48% (+/- 6.86%)
  • +
+

Test Device: B

+
    +
  • CPU: Redmi 5A
  • +
  • OS: Android 8.1.0
  • +
+

Results: B

+
    +
  • DSP with Vorbis: 21.29% (+/- 5.11%)
  • +
  • DSP with FADPCM: 5.45% (+/- 0.72%)
  • +
  • DSP with PCM: 4.63% (+/- 0.69%)
  • +
  • Update at 60 FPS: 3.72% (+/- 2.93%)
  • +
+ + +
+ + + diff --git a/FMOD/doc/FMOD API User Manual/platforms-html5.html b/FMOD/doc/FMOD API User Manual/platforms-html5.html new file mode 100644 index 0000000..694d2dc --- /dev/null +++ b/FMOD/doc/FMOD API User Manual/platforms-html5.html @@ -0,0 +1,602 @@ + + +Platform Details | HTML5 + + + + +
+ +
+

17. Platform Details | HTML5

+ +

HTML5 Specific Starter Guide

+

Running FMOD as HTML5 on the web is made possible by having a web server host and deliver the JavaScript content to the client web browser. In a local development environment this would be hosted using a web server such as Apache (required for HTTPS / SharedArrayBuffer testing) or something like Simple Web Server.

+

SDK version

+

FMOD is compiled using Emscripten 3.1.67.

+

Browser Support

+

Minimum specifications

+

FMOD supports the following minimum browser versions:

+
    +
  • Firefox: 79
  • +
  • Safari: 14.1.0
  • +
  • Chrome: 85
  • +
+

Compatibility

+
    +
  • FMOD requires a browser to support web-audio at a minimum to be compatible, this is supported by modern browsers. See compatibility details here.
  • +
  • FMOD will not be audible until a user interaction (like a click, touch, or key press) happens to initiate audio. This is a security measure to prevent unwanted audio from playing unexpectedly.
  • +
  • For using the WASM version of FMOD there are additional restrictions, however most mainstream browsers have support. See compatibility details here.
  • +
  • Browser support for 5.1 / surround sound is supported but may be limited to certain browsers, and was adopted early by Mozilla Firefox verified in version 50.1.0.
  • +
  • Browsers that support AudioWorkletNode will automatically use FMOD_OUTPUTTYPE_AUDIOWORKLET for this functionality. This mode allows non blocking/background audio mixing. See compatibility details here.
  • +
  • If FMOD_OUTPUTTYPE_AUDIOWORKLET is not supported, FMOD_OUTPUTTYPE_WEBAUDIO is used. At the code level this uses ScriptProcessorNode which is now deprecated.
  • +
  • Browsers that support SharedArrayBuffer will get access to pthread support, but this has to be enabled by the developer by using the special 'P' versions of the FMOD libraries. See compatibility details here.
  • +
  • To develop with SharedArrayBuffer mode, cross origin isolation / CORS is required. Please follow this guide for further information.
  • +
+

Threads

+

The standard (non SharedArrayBuffer/pthread) WASM build does not support threads for compatibility with older browsers. The developer must call System::update regularly to keep the audio running without skipping/stuttering.

+

If FMOD_OUTPUTTYPE_AUDIOWORKLET is being used then the FMOD software mixer will run asynchronously without the help of System::update. System::update would be important for streaming audio (i.e. files opened with System::createStream / FMOD_CREATESTREAM) only.

+

The SharedArrayBuffer/pthread WASM build supports background streaming, non blocking file loading and other non blocking behavior.

+

Libraries

+

FMOD provides different binaries covering different runtime formats and compatibility.

+

If you are developing in HTML / Javascript your choices are:

+
    +
  • WASM - More modern/faster code for modern browsers.
  • +
  • JS - Legacy code for older browsers.
  • +
+

If you are developing in C / C++ your choices are:

+
    +
  • W32 - Native libraries to link with other emscripten based source.
  • +
+

To include FMOD using JavaScript in a html file, refer to the following example in your HTML. Filename will vary based on what HTML technology or logging/reduced variant you might be using.

+

Core API Only:

+
<script type="text/javascript" src="fmod.js"></script>
+
+ +

Studio API:

+
<script type="text/javascript" src="fmodstudio.js"></script>
+
+ +

Technology choice

+

Select from below for your technology choice, and refer to the table for the folder the FMOD libraries are located in, and any accompanying files that must be copied in with them to your project folder.

+
+

WASM

+

Faster (approximately 30%) and uses half the memory of Javascript, but requires the web browser to support the WASM technology, and also a web server that understands the .wasm 'application/wasm' mime type.

+

Core API libraries - Located in /api/core/lib/wasm/.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Core API fileCompanion file (put in same folder)Description
fmod.jsfmod.wasmRelease library for production code
fmodL.jsfmodL.wasmRelease library with logging output, use for debugging
fmod_reduced.jsfmod_reduced.wasmSmaller release library for production code, with reduced features
fmodP.jsfmodP.wasmSharedArrayBuffer / pthread version. Release library for production code
fmodPL.jsfmodPL.wasmSharedArrayBuffer / pthread version. Release library with logging output, use for debugging
fmodP_reduced.jsfmodP_reduced.wasmSharedArrayBuffer / pthread version. Smaller release library for production code, with reduced features
+

Studio API libraries - Located in /api/studio/lib/wasm/. The Studio API files already contain the Core API, so you do not need to include the Core API files as well.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Studio API fileCompanion file (put in same folder)Description
fmodstudio.jsfmodstudio.wasmRelease library for production code. Includes fmod_reduced.js
fmodstudioL.jsfmodstudioL.wasmRelease library with logging output, use for debugging
fmodstudioP.jsfmodstudioP.wasmSharedArrayBuffer / pthread version. Release library for production code. Includes fmodP_reduced.js
fmodstudioPL.jsfmodstudioPL.wasmSharedArrayBuffer / pthread version. Release library with logging output, use for debugging
+
+

W32

+

For using Emscripten with your own C/C++ code to convert to JavaScript. W32 is an intermediate format.
+See Using FMOD with C/C++ for instructions on which compiler / linker flags to use.

+

Core API libraries - Located in /api/core/lib/w32/

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Core API fileDescription
fmod.aRelease binary for production code
fmodL.aRelease binary with logging enabled for development
fmod_reduced.aSmaller release binary with reduced features, for production code.
fmodP.aSharedArrayBuffer / pthread version. Release binary for production code
fmodPL.aSharedArrayBuffer / pthread version. Release binary with logging enabled for development
fmodP_reduced.aSharedArrayBuffer / pthread version. Smaller release binary with reduced features, for production code.
+

Studio API libraries - Located in /api/studio/lib/w32/. The Studio API files already contain the Core API, so you do not need to include the Core API files as well.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Studio API fileDescription
fmodstudio.aRelease binary for production code. Contains fmod_reduced.a
fmodstudioL.aRelease binary with logging enabled for development. Contains fmodL.a
fmodstudioP.aSharedArrayBuffer / pthread version. Release binary for production code. Contains fmodP_reduced.a
fmodstudioPL.aSharedArrayBuffer / pthread version. Release binary with logging enabled for development. Contains fmodPL.a
+

Note: The fmodstudio versions of the library include the fmod_reduced version of the core, so accessing things like .ogg/.mp3 (see reduced ) through Studio::System::getCoreSystem are not supported. Use the fmodstudioL version to get full access to all features.

+
+

JS (Legacy)

+

Older Javascript compiled. Slower and uses more memory, but best for compatibility.

+

Core API libraries - Located in /api/core/lib/js/

+ + + + + + + + + + + + + + + + + + + + + + + + + +
Core API fileCompanion file (put in same folder)Description
fmod.jsfmod.js.memRelease library for production code
fmodL.jsfmodL.js.memRelease library with logging output, use for debugging
fmod_reduced.jsfmod_reduced.js.memSmaller release library for production code, with reduced features
+

Studio API libraries - Located in /api/studio/lib/js/. The Studio API files already contain the Core API, so you do not need to include the Core API files as well.

+ + + + + + + + + + + + + + + + + + + + +
Studio API fileCompanion file (put in same folder)Description
fmodstudio.jsfmodstudio.js.memRelease library for production code. Contains fmod_reduced.js
fmodstudioL.jsfmodstudioL.js.memRelease library with logging output, use for debugging. Contains fmodL.js
+

Using FMOD with C/C++

+

If you have a C/C++ program that uses FMOD and are converting it to JavaScript using Emscripten, you will need to link the relevant FMOD binaries as per the Emscripten Documentation, and ensure the following flags are added in your Emscripten compilation arguments:

+
-s WASM=1 -s ALLOW_MEMORY_GROWTH=1 -s EXPORTED_RUNTIME_METHODS=ccall,cwrap,setValue,getValue
+
+ +

Flags using WASM pthread build

+

Add these flags on top of the standard flags above:

+
-pthread -s PTHREAD_POOL_SIZE=5
+
+ +

Overriding FMOD's 'window' handle.

+

Before any FMOD API calls, emit some Javascript that sets Module.window with your own window handle.

+
EM_ASM({
+    console.log("Setting FMOD module window handle");
+    Module.window = window;
+});
+
+ +

Using FMOD with JavaScript

+

Application setup

+

To set up a JavaScript application and the 'FMOD object', declare some members of the object that can be used internally by FMOD.

+
var FMOD = {};                          // FMOD global object which must be declared to enable 'main' and 'preRun' and then call the constructor function.
+FMOD.window = window;                   // Optional. Specify main window handle from a different context if needed.
+FMOD.preRun = prerun;                   // Optional. Will be called before FMOD runs, but after the Emscripten runtime has initialized
+FMOD.onRuntimeInitialized = main;       // Called when the Emscripten runtime has initialized
+FMOD.INITIAL_MEMORY = 64*1024*1024;     // FMOD Heap defaults to 16mb which is enough for this demo, but set it differently here for demonstration (64mb)
+FMODModule(FMOD);                       // Requires being called to initialize the 'FMOD' object via the FMOD constructor.
+
+function prerun()
+{
+    // Call FMOD file preloading functions here to mount local files. Otherwise load custom data from memory or use own file system. 
+}
+
+ +

FMOD defaults to 16mb of memory to load sounds with and create FMOD objects with. Use the following global before calling the main FMOD constructor object, to control how much memory to use.
+For WASM support, FMOD uses ALLOW_MEMORY_GROWTH, which will allow memory to grow dynamically from INITIAL_MEMORY up to a maximum of 2GB.

+

To use some of the mounting functionality provided for file access, specify 'preRun' to ensure it is executed before main().

+

Setting and getting

+

Javascript parameters are passed by value, therefore when you pass one to a function, it makes the concept of a 'getter' function difficult.
+The variable's value cannot be changed by the function from the caller's perspective, but it can add a new member to the variable, which is the mechanism FMOD always uses when 'getting' data from a function.

+

In C the variable can be altered as it would be passed by reference (using pointers).
+In FMOD for JavaScript, the variable you pass in gets a new member called val which contains the new data.
+i.e.

+
var outval = {}; // generic variable to reuse and be passed to FMOD functions.
+var name;        // to store name of sound.
+
+sound.getName(outval);
+name = outval.val;  // 'val' contains the data. Pass it to the variable we want to keep.
+
+console.log(name);
+
+ +

All FMOD functions that produce data in a variable after calling a function return data this way.

+

Using structures

+

When using a structure to pass information to FMOD, a helper/constuctor function must be called to create the structure before using it/filling in its members, so that FMOD can understand what is being passed to it.
+If these constructor functions are not used, the function it is being passed to will probably result in a 'binding' error (in the browser debug/log console/window).

+
var guid = FMOD.GUID();
+var info = FMOD.STUDIO_BANK_INFO();
+
+ +

File Access

+

FMOD lets you load data from the host in a few different ways, depending on your setup.

+
Direct from host, via FMOD's filesystem
+

FMOD exposes an emscripten mechanism to mount/pre-load files in the 'prerun()' function, that is described above in the Application Setup section of this document.
+Call FS_createPreloadedFile to register your files so that FMOD can use filenames in file related functions. See Emscripten docs for more on this function.
+For example the playsound example

+
// Will be called before FMOD runs, but after the Emscripten runtime has initialized
+// Call FMOD file preloading functions here to mount local files. Otherwise load custom data from memory or use own file system.
+function prerun()
+{
+    var fileUrl = "/public/js/";
+    var fileName;
+    var folderName = "/";
+    var canRead = true;
+    var canWrite = false;
+
+    fileName = [
+        "dog.wav",
+        "lion.wav",
+        "wave.mp3"
+    ];
+
+    for (var count = 0; count < fileName.length; count++)
+    {
+        FMOD.FS_createPreloadedFile(folderName, fileName[count], fileUrl + fileName[count], canRead, canWrite);
+    }
+}
+
+ +

Then later in your app you can simply reference a file by path/filename.

+
result = gSystem.createSound("/lion.wav", FMOD.LOOP_OFF, null, outval);
+CHECK_RESULT(result);
+
+ +
Via memory
+

If you have raw data in memory that you want to pass to FMOD , you can. Warning though, javascript passes data by value, so the memory usage will temporarily double for the sound data when it is passed to fmod.
+The load_from_memory has an example of this

+
var chars  = new Uint8Array(e.target.result);
+var outval = {};
+var result;
+var exinfo = FMOD.CREATESOUNDEXINFO();
+exinfo.length = chars.length;
+
+result = gSystem.createStream(chars.buffer, FMOD.LOOP_OFF | FMOD.OPENMEMORY, exinfo, outval);
+CHECK_RESULT(result);
+
+ +
Via callbacks
+

If you have a file system you can use file callbacks to load data into FMOD. See System::setFileSystem, or Studio::System::loadBankCustom
+In load_bank example, there is a demonstration of this

+
var info = new FMOD.STUDIO_BANK_INFO();
+
+info.opencallback = customFileOpen;
+info.closecallback = customFileClose;
+info.readcallback = customFileRead;
+info.seekcallback = customFileSeek;
+info.userdata = filename;
+
+result = gSystem.loadBankCustom(info, FMOD.STUDIO_LOAD_BANK_NONBLOCKING, outval);
+CHECK_RESULT(result);
+
+ +

In this case the filename is passed as userdata to let the callback get information for what file to load.
+Here is the customFileOpen callback getting the filename and opening a file handle.
+The file is opened in this case with a special FMOD provided file API. Replace this with your own API.

+
function customFileOpen(name, filesize, handle, userdata)
+{
+    var filesize_outval = {};
+    var handle_outval = {}
+
+    // We pass the filename into our callbacks via userdata in the custom info struct
+    var filename = userdata;
+
+    var result = FMOD.file_open(gSystemLowLevel, filename, filesize_outval, handle_outval)
+    if (result == FMOD.OK)
+    {
+        filesize.val = filesize_outval.val;
+        handle.val = handle_outval.val;
+    }
+
+    return result;
+}
+
+ +

To read data in the callback, into the buffer that FMOD has provided, FMOD has used a special technique where it passes the memory address, instead of a javascript buffer.
+This means to write data to FMOD's buffer you must use FMOD.setValue using the buffer address, writing the data in a loop, a byte at a time. This could be optimized somewhat by using i32 to write 4 bytes at a time.

+
function customFileRead(handle, buffer, sizebytes, bytesread, userdata)
+{
+    var bytesread_outval = {};
+    var buffer_outval = {};
+
+    // Read from the file into a new buffer. This part can be swapped for your own file system.
+    var result = FMOD.file_read(handle, buffer_outval, sizebytes, bytesread_outval)   // read produces a new array with data.
+    if (result == FMOD.OK)
+    {
+        bytesread.val = bytesread_outval.val;
+    }
+
+    // Copy the new buffer contents into the buffer that is passed into the callback. 'buffer' is a memory address, so we can only write to it with FMOD.setValue
+    for (count = 0; count < bytesread.val; count++)
+    {
+        FMOD.setValue(buffer + count, buffer_outval.val[count], 'i8');      // See https://kripken.github.io/emscripten-site/docs/api_reference/preamble.js.html#accessing-memory for docs on setValue.
+    }
+
+    return result;
+}
+
+ +

Helper functions

+

FMOD comes with some functions to aid with reading file data and writing to memory buffers.
+Here is the list of functions that are provided.

+ +

Performance tuning

+

CPU Overhead

+

By default FMOD mixes at 48000hz. If the browser is not running at that rate, it will introduce a resampler to convert the rate, which consumes CPU time and adds a DSP block worth of latency.
+This can be solved by querying the hardware's rate before System::init, and calling System::setSoftwareFormat to the same rate as the output. Here is an example (from the PlaySound example):

+
var outval = {};
+result = gSystem.getDriverInfo(0, null, null, outval, null, null);
+CHECK_RESULT(result);
+result = gSystem.setSoftwareFormat(outval.val, FMOD.SPEAKERMODE_DEFAULT, 0)
+CHECK_RESULT(result);
+
+ +

Audio Stability (Stuttering)

+

Some devices cannot handle the default buffer size of 4 blocks of 1024 samples (4096 samples) without stuttering, so to avoid this set the buffer size in your application to 2 blocks of 2048.
+Here is an example

+
result = gSystem.setDSPBufferSize(2048, 2);
+CHECK_RESULT(result);
+
+ +

If a non pthread FMOD library is being used and FMOD_OUTPUTTYPE_WEBAUDIO is being used (see Compatibility section of documentation), make sure System::update is being called frequently enough for mixing / streaming to be processed from the main thread.

+

Reduced Feature build

+

The Core API libraries provide _reduced library file variations which can be used optionally.
+The _reduced library is a smaller subset of features. This provides a smaller file size footprint for distribution purposes.

+

fmodstudio.js/fmodstudio.a/fmodstudio.wasm and their 'P' (SharedArrayBuffer/pthread) versions include the reduced library by default. To get the full feature set use the logging version of each file instead. This enables logging but you can turn it off with Debug_Initialize.

+

Codec Support

+

The following file formats are removed in favour of the .FSB file format only. .FSB support includes vorbis, FADPCM and pcm audio formats:

+
    +
  • AIFF file format support
  • +
  • DLS file format support
  • +
  • FLAC file format support
  • +
  • WAV file format support
  • +
  • MOD file format support
  • +
  • S3M file format support
  • +
  • XM file format support
  • +
  • IT file format support
  • +
  • MID/MIDI file format support
  • +
  • MP2/MP3 file format support
  • +
  • OGG file format support
  • +
  • PLS/M3U file format support
  • +
+

DSP Effect support

+

The following effects / mixer code is removed:

+
    +
  • Envelope follower DSP support
  • +
  • Cubic / Spline and 'none' interpolation support. Linear interpolation only.
  • +
+

Known Issues

+

The following items are not supported:

+ +

The following callbacks remain unimplemented at this point, so they will not work:

+
+ + +
+ + + diff --git a/FMOD/doc/FMOD API User Manual/platforms-ios.html b/FMOD/doc/FMOD API User Manual/platforms-ios.html new file mode 100644 index 0000000..185e776 --- /dev/null +++ b/FMOD/doc/FMOD API User Manual/platforms-ios.html @@ -0,0 +1,379 @@ + + +Platform Details | iOS + + + + +
+ +
+

17. Platform Details | iOS

+ +

iOS Specific Starter Guide

+

SDK Version

+

FMOD is compiled using the following tools.

+
    +
  • Xcode - version 15.2 targeting SDK 17.2 for iOS/tvOS and SDK 1.0 for visionOS.
  • +
+

Compatibility

+

FMOD supports devices of the below architectures back to iOS/tvOS 12.0. Please note that armv6, armv7, armv7s and x86 are no longer supported by Xcode and thus are no longer supported by FMOD.

+
    +
  • iOS: arm64, arm64e
  • +
  • tvOS: arm64, arm64e
  • +
  • visionOS: arm64, arm64e
  • +
  • iOS simulator: x86_64, arm64
  • +
  • tvOS simulator: x86_64, arm64
  • +
  • visionOS simulator: x86_64, arm64
  • +
+

Libraries

+

Each lib is a universal binary containing the relevant architectures from the 'Compatibility' list above.

+

Core API library

+
    +
  • /api/core/lib/libfmod_iphoneos.a - Release iOS device binary for production code.
  • +
  • /api/core/lib/libfmodL_iphoneos.a - Release iOS device binary with logging enabled for development.
  • +
  • /api/core/lib/libfmod_iphonesimulator.a - Release iOS simulator binary for production code.
  • +
  • /api/core/lib/libfmodL_iphonesimulator.a - Release iOS simulator binary with logging enabled for development.
  • +
  • /api/core/lib/libfmod_appletvos.a - Release tvOS device binary for production code.
  • +
  • /api/core/lib/libfmodL_appletvos.a - Release tvOS device binary with logging enabled for development.
  • +
  • /api/core/lib/libfmod_appletvsimulator.a - Release tvOS simulator binary for production code.
  • +
  • /api/core/lib/libfmodL_appletvsimulator.a - Release tvOS simulator binary with logging enabled for development.
  • +
  • /api/core/lib/libfmod_xros.a - Release visionOS device binary for production code.
  • +
  • /api/core/lib/libfmodL_xros.a - Release visionOS device binary with logging enabled for development.
  • +
  • /api/core/lib/libfmod_xrsimulator.a - Release visionOS simulator binary for production code.
  • +
  • /api/core/lib/libfmodL_xrsimulator.a - Release visionOS simulator binary with logging enabled for development.
  • +
+

Studio API library (used in conjunction with Core API library)

+
    +
  • /api/studio/lib/libfmodstudio_iphoneos.a - Release iOS device binary for production code.
  • +
  • /api/studio/lib/libfmodstudioL_iphoneos.a - Release iOS device binary with logging enabled for development.
  • +
  • /api/studio/lib/libfmodstudio_iphonesimulator.a - Release iOS simulator binary for production code.
  • +
  • /api/studio/lib/libfmodstudioL_iphonesimulator.a - Release iOS simulator binary with logging enabled for development.
  • +
  • /api/studio/lib/libfmodstudio_appletvos.a - Release tvOS device binary for production code.
  • +
  • /api/studio/lib/libfmodstudioL_appletvos.a - Release tvOS device binary with logging enabled for development.
  • +
  • /api/studio/lib/libfmodstudio_appletvsimulator.a - Release tvOS simulator binary for production code.
  • +
  • /api/studio/lib/libfmodstudioL_appletvsimulator.a - Release tvOS simulator binary with logging enabled for development.
  • +
  • /api/studio/lib/libfmodstudio_xros.a - Release visionOS device binary for production code.
  • +
  • /api/studio/lib/libfmodstudioL_xros.a - Release visionOS device binary with logging enabled for development.
  • +
  • /api/studio/lib/libfmodstudio_xrsimulator.a - Release visionOS simulator binary for production code.
  • +
  • /api/studio/lib/libfmodstudioL_xrsimulator.a - Release visionOS simulator binary with logging enabled for development.
  • +
+

Apple libraries (required for the Core API and Studio API libraries)

+
    +
  • AudioToolbox.framework - Audio output.
  • +
  • AVFoundation.framework - Audio Session query.
  • +
+

Hardware Decoding

+

Via the AudioQueue codec FMOD supports decoding AAC, ALAC and MP3. At present iOS devices only have support for decoding one sound with hardware at a time (which may be consumed by playing the iPod). At the cost of extra CPU, all iOS devices have access to software codecs to support more than one sound of these formats. By default FMOD will try to use hardware, if it is in use a software codec will be used. If you want explicit control over whether hardware or software is chosen you can use the FMOD_AUDIOQUEUE_CODECPOLICY enumeration provided in fmod_ios.h. This is set with FMOD_CREATESOUNDEXINFO::audioqueuepolicy via System::createSound.

+

When playing MP3s using the AudioQueue codec, seeking is generally slow for the first time each position is visited. If you need fast random access to a file you can create the sound using the FMOD_ACCURATETIME flag. This will scan the file at load time to determine its accurate length, which has the benefit of creating a seek table to aid in seeking. This is a one-time upfront cost for fast seeking vs paying the cost at runtime for each unique position.

+

All decoding performed by the AudioQueue codec is done on standalone files such as .mp3, .m4a, etc. There is no support for using AudioQueue with FSB or bank compressed audio. Any MP3 decoding for FSB files is performed by the standard cross-platform FMOD decoder.

+

Handling Interruptions

+

Unlike in previous versions of FMOD, it is now the responsibility of the developer to interact with the AudioSession APIs native to this platform. To assist in this matter we provide two functions you can use when you need to handle interruptions, System::mixerSuspend and System::mixerResume. There are three interruptions that need to be addressed:

+ +

We provide example code in the Core API examples that demonstrates how to set up observers for these interruptions that suspend and resume the FMOD system as needed:

+
void Common_DefaultSuspendCallback(bool suspend)
+
+void (*gSuspendCallback)(bool suspend) = &Common_DefaultSuspendCallback;
+bool gIsSuspended = false;
+bool gNeedsReset = false;
+
+void Common_DefaultSuspendCallback(bool suspend)
+{
+    NSLog(@"Common_DefaultSuspendCallback(%s)\n", suspend ? "true" : "false");
+}
+
+/*
+    Pass a function pointer to a function handling suspend/resume from your own code to Common_RegisterSuspendCallback
+*/
+void Common_RegisterSuspendCallback(void (*callback)(bool))
+{
+    gSuspendCallback = callback ? callback : &Common_DefaultSuspendCallback;
+}
+
+/*
+    Set up some observers for various notifications
+*/
+[[NSNotificationCenter defaultCenter] addObserverForName:AVAudioSessionInterruptionNotification object:nil queue:nil usingBlock:^(NSNotification *notification)
+{
+    AVAudioSessionInterruptionType type = (AVAudioSessionInterruptionType)[[notification.userInfo valueForKey:AVAudioSessionInterruptionTypeKey] unsignedIntegerValue];
+    if (type == AVAudioSessionInterruptionTypeBegan)
+    {
+        NSLog(@"Interruption Began");
+        // Ignore deprecated warnings regarding AVAudioSessionInterruptionReasonAppWasSuspended and
+        // AVAudioSessionInterruptionWasSuspendedKey, we protect usage for the versions where they are available
+        #pragma clang diagnostic push
+        #pragma clang diagnostic ignored "-Wdeprecated-declarations"
+
+        // If the audio session was deactivated while the app was in the background, the app receives the
+        // notification when relaunched. Identify this reason for interruption and ignore it.
+        if (@available(iOS 16.0, tvOS 14.5, *))
+        {
+            // Delayed suspend-in-background notifications no longer exist, this must be a real interruption
+        }
+        #if !TARGET_OS_TV // tvOS never supported "AVAudioSessionInterruptionReasonAppWasSuspended"
+        else if (@available(iOS 14.5, *))
+        {
+            if ([[notification.userInfo valueForKey:AVAudioSessionInterruptionReasonKey] intValue] == AVAudioSessionInterruptionReasonAppWasSuspended)
+            {
+                NSLog(@"Ignoring delayed AVAudioSessionInterruptionNotification");
+                return; // Ignore delayed suspend-in-background notification
+            }
+        }
+        #endif
+        else
+        {
+            if ([[notification.userInfo valueForKey:AVAudioSessionInterruptionWasSuspendedKey] boolValue])
+            {
+                NSLog(@"Ignoring delayed AVAudioSessionInterruptionNotification");
+                return; // Ignore delayed suspend-in-background notification
+            }
+        }
+
+        gSuspendCallback(true);
+        gIsSuspended = true;
+
+        #pragma clang diagnostic pop
+    }
+    else if (type == AVAudioSessionInterruptionTypeEnded)
+    {
+        NSLog(@"Interruption Ended");
+        NSError *errorMessage = nullptr;
+        if (![[AVAudioSession sharedInstance] setActive:TRUE error:&errorMessage])
+        {
+            // Interruption like Siri can prevent session activation, wait for did-become-active notification
+            NSLog(@"AVAudioSessionInterruptionNotification: AVAudioSession.setActive() failed: %@", errorMessage);
+            return;
+        }
+
+        gSuspendCallback(false);
+        gIsSuspended = false;
+    }
+}];
+
+[[NSNotificationCenter defaultCenter] addObserverForName:UIApplicationDidBecomeActiveNotification object:nil queue:nil usingBlock:^(NSNotification *notification)
+{
+    NSLog(@"Application did become active");
+
+    if (gNeedsReset)
+    {
+        gSuspendCallback(true);
+        gIsSuspended = true;
+    }
+
+    NSError *errorMessage = nullptr;
+    if (![[AVAudioSession sharedInstance] setActive:TRUE error:&errorMessage])
+    {
+        if ([errorMessage code] == AVAudioSessionErrorCodeCannotStartPlaying)
+        {
+            // Interruption like Screen Time can prevent session activation, but will not trigger an interruption-ended notification.
+            // There is no other callback or trigger to hook into after this point, we are not in the background and there is no other audio playing.
+            // Our only option is to have a sleep loop until the Audio Session can be activated again.
+            while (![[AVAudioSession sharedInstance] setActive:TRUE error:nil])
+            {
+                usleep(20000);
+            }
+        }
+        else
+        {
+            // Interruption like Siri can prevent session activation, wait for interruption-ended notification.
+            NSLog(@"UIApplicationDidBecomeActiveNotification: AVAudioSession.setActive() failed: %@", errorMessage);
+            return;
+        }
+    }
+
+    // It's possible the system missed sending us an interruption end, so recover here
+    if (gIsSuspended)
+    {
+        gSuspendCallback(false);
+        gNeedsReset = false;
+        gIsSuspended = false;
+    }
+}];
+
+[[NSNotificationCenter defaultCenter] addObserverForName:AVAudioSessionMediaServicesWereResetNotification object:nil queue:nil usingBlock:^(NSNotification *notification)
+{
+    NSLog(@"Media services were reset");
+    if ([UIApplication sharedApplication].applicationState == UIApplicationStateBackground || gIsSuspended)
+    {
+        // Received the reset notification while in the background, need to reset the AudioUnit when we come back to foreground.
+        gNeedsReset = true;
+    }
+    else
+    {
+        // In the foregound but something chopped the media services, need to do a reset.
+        gSuspendCallback(true);
+        gSuspendCallback(false);
+    }
+}];
+
+ +

A more complete example can be found in the "suspend_resume" Core API example, which demonstrates one potential way of handling the integration of System::mixerSuspend and System::mixerResume with the observers. This is done by creating a callback that, when fired from an observer, sets a global boolean that the main thread checks to suspend/resume the mixer.

+

For more information about interruptions please check the Apple documentation.

+

Lock Screen & Background Audio

+

There is no special configuration inside FMOD required to enable the playback of audio from the lock screen or the background, there are two things you must configure outside of FMOD to do this though.

+
    +
  1. Choose an AudioSession category that supports background / lock screen audio, see audio session basics for more details.
  2. +
  3. Enable background audio functionality in your info.plist with the UIBackgroundModes key, see the iOS key reference for more details.
  4. +
+

When playing audio on the lock screen (or during the fade out transition to silence when locking) it is important to ensure your buffering is configured correctly to allow low power audio playback. Please consult the latency section of this doc for further details.

+

Recording

+

Much like lock screen and background audio, recording requires a particular AudioSession category to be active at the time of System::recordStart (and must remain active until the recording finishes). The required category is called 'play and record' and can be read about in the audio session basics documentation. Note that FMOD is always 'playing' audio (even silence) so it is not sufficient to simply use the 'recording' category unless you are running the 'No Sound' or 'Wav Writer' output mode.

+

Some devices may take some time to switch AudioSession category so it is recommended to set this category at application start time to avoid any hiccups in audio playback.

+

You will also need to add a "Privacy - Microphone Usage Description" (NSMicrophoneUsageDescription) key to the built project's Info.plist file, with a string value explaining to the user how your application will use their recorded data.

+

Latency

+

The default latency introduced by FMOD for this platform is 4 blocks of 512 samples at a sample rate of 24 kHz, which equates to approximately 85 ms. You are free to change this using two APIs, System::setDSPBufferSize and System::setSoftwareFormat but there are some important considerations.

+

If you have configured background or lock screen audio when locking the device the OS will conserve power by requesting audio from FMOD less frequently. If you desire this functionality please ensure your DSP buffer size is sufficiently large to cover the request. The iOS operating system will expect 4096 samples to be available, so configure FMOD as 8 blocks of 512 samples or 4 blocks of 1024 samples to satisfy the request (otherwise silence will be produced and a warning issued on the TTY).

+

If you are worried about latency and do not want automatic low power mode you can configure the Audio Session buffer and sample rate to match FMOD for best results. Assuming an FMOD block size of 512 samples and 24 kHz sample rate you should configure the OS with the following:

+
AVAudioSession *session = [AVAudioSession sharedInstance];
+double rate = 24000.0; // This should match System::setSoftwareFormat 'samplerate' which defaults to 24000
+int blockSize = 512; // This should match System::setDSPBufferSize 'bufferlength' which defaults to 512
+
+BOOL success = [session setPreferredSampleRate:rate error:nil];
+assert(success);
+
+success = [session setPreferredIOBufferDuration:blockSize / rate error:nil];
+assert(success);
+
+success = [session setActive:TRUE error:nil];
+assert(success);
+
+ +

Multi-channel Output

+

For hardware that supports greater than stereo output you can configure the device to operate with that channel count using the AudioSession API.

+

Here is a code snippet that demonstrates using as many channels as available:

+
AVAudioSession *session = [AVAudioSession sharedInstance];
+long maxChannels = [session maximumOutputNumberOfChannels];
+
+BOOL success = [session setPreferredOutputNumberOfChannels:maxChannels error:nil];
+assert(success);
+
+success = [session setActive:TRUE error:nil];
+assert(success);
+
+ +

Suspend in Background

+

FMOD native threads will continue running when your application transitions to the background, this will continue to use resources. To completely stop FMOD without losing your current setup you can call System::mixerSuspend as part of your backgrounding process. When you return to the foreground, use System::mixerResume to reactivate FMOD. It is extremely important to ensure no FMOD APIs are called in-between suspend and resume as they run the risk of causing a deadlock. You must also call suspend and resume pairs on the same thread.

+

Thread Affinity

+

All threads will default to FMOD_THREAD_AFFINITY_CORE_ALL, it is not currently possible to override this with Thread_SetAttributes.

+

Thread Priority

+

The relationship between FMOD platform agnostic thread priority and the platform specific values is as follows:

+ +

For FMOD to detect the channel count you must use setPreferredOutputNumberOfChannels and activate your AudioSession before calling System::init.

+

Performance Reference

+

This section is a companion for the CPU Performance section of the Managing Resources in the Core API chapter and serves as a quick reference of facts targeting this platform.

+

Format Choice

+

Each compression format provided in FMOD has a reason for being included, the below list will detail our recommendations for this platform. Formats listed as primary are considering the best choice, secondary formats should only be considered if the primary doesn't satisfy your requirements.

+
    +
  • FADPCM: Primary format for all sounds.
  • +
  • Vorbis: Secondary format for long streams if FADPCM compression is too low.
  • +
  • PCM: Secondary format for short sounds if FADPCM cost is too high.
  • +
  • AAC: Special format for long streams, single hardware assisted codec available for .MP4 / .M4A files.
  • +
  • XMA: Unavailable.
  • +
  • AT9: Unavailable.
  • +
+

Channel Count

+

To give developers an idea about the costs of a particular format we provide synthetic benchmark results. These results are based on simple usage of the Studio API using recommended configuration settings.

+

Settings

+
    +
  • Real channel count: 32
  • +
  • Sample rate: 24 kHz
  • +
  • Speaker mode: Stereo
  • +
  • DSP block size: 1024 samples
  • +
+

Test Device: A

+
    +
  • CPU: Apple A7 @ 1.3 GHz (iPhone 5S)
  • +
  • OS: 12.5.1
  • +
+

Results: A

+
    +
  • DSP with Vorbis: 5.27% (+/- 0.76%)
  • +
  • DSP with FADPCM: 2.21% (+/- 0.30%)
  • +
  • DSP with PCM: 1.36% (+/- 0.23%)
  • +
  • Update at 60 FPS: 0.89% (+/- 0.52%)
  • +
+

Test Device: B

+
    +
  • CPU: Apple A8 @ 1.5 GHz (iPad mini 4)
  • +
  • OS: 14.4.1
  • +
+

Results: B

+
    +
  • DSP with Vorbis: 4.16% (+/- 0.76%)
  • +
  • DSP with FADPCM: 1.68% (+/- 0.50%)
  • +
  • DSP with PCM: 0.97% (+/- 0.42%)
  • +
  • Update at 60 FPS: 0.82% (+/- 1.01%)
  • +
+ + +
+ + + diff --git a/FMOD/doc/FMOD API User Manual/platforms-linux.html b/FMOD/doc/FMOD API User Manual/platforms-linux.html new file mode 100644 index 0000000..fcde415 --- /dev/null +++ b/FMOD/doc/FMOD API User Manual/platforms-linux.html @@ -0,0 +1,143 @@ + + +Platform Details | Linux + + + + +
+ +
+

17. Platform Details | Linux

+ +

Linux Specific Starter Guide

+

SDK Version

+

FMOD is compiled using the following tools.

+
    +
  • LLVM/Clang - version 10.
  • +
+

Compatibility

+

FMOD supports systems that provide ALSA v0.9.0rc4 or newer for the following architectures:

+
    +
  • x86 - requires SSE2, optimized with SSE3 if detected at runtime, minimum GNU C library GLIBC_2.2, minimum GNU C++ library CXXABI_1_3, GLIBCXX_3.4.
  • +
  • x86_64 - requires SSE2 (implied by x86_64), optimized with SSE3 or AVX if detected at runtime, minimum GNU C library GLIBC_2.2.5, minimum GNU C++ library CXXABI_1_3, GLIBCXX_3.4.
  • +
  • arm - requires armv7 or newer with NEON, hard float ABI (gnueabihf), minimum GCC library GCC_3.5, minimum GNU C library GLIBC_2.4, minimum GNU C++ library CXXABI_1_3, GLIBCXX_3.4.
  • +
  • arm64 - requires armv8, minimum GCC library GCC_3.5, minimum GNU C library GLIBC_2.17, minimum GNU C++ library CXXABI_1_3, GLIBCXX_3.4.
  • +
+

Libraries

+

Substitute $ARCH with your desired architecture from the 'Compatibility' list above.

+

Core API library

+
    +
  • /api/core/lib/$ARCH/libfmod.so - Release binary for production code.
  • +
  • /api/core/lib/$ARCH/libfmodL.so - Release binary with logging enabled for development.
  • +
+

Studio API library (used in conjunction with the Core API library)

+
    +
  • /api/studio/lib/$ARCH/libfmodstudio.so - Release binary for production code.
  • +
  • /api/studio/lib/$ARCH/libfmodstudioL.so - Release binary with logging enabled for development.
  • +
+

Device Selection

+

FMOD defaults to using PulseAudio if available if no device is specified via System::setOutput. The environment variable FMOD_ALSA_DEVICE can be used to override this behavior, causing FMOD to use ALSA by default. It will also select the device specified by the variable value, if found, by default. Device names are as specified by the output of aplay -L.

+

Depending on the configuration of ALSA, a device that otherwise functions correctly may not be listed in the output of aplay -L, and as a result won't be available to FMOD. If this is the case, you may need to either add a namehint to the device's .asoundrc configuration file, or set defaults.namehint.showall to on in your ALSA configuration file /usr/share/alsa/alsa.conf.

+

Thread Affinity

+

All threads will default to FMOD_THREAD_AFFINITY_CORE_ALL, it is not currently possible to override this with Thread_SetAttributes.

+

Thread Priority

+

The relationship between FMOD platform agnostic thread priority and the platform specific values is as follows:

+ +

Troubleshooting

+

System::init returns FMOD_ERR_PLUGIN_MISSING:
+This can happen if your machine is missing the ALSA library libasound.so.2 for the desired architecture, almost any version of it will be sufficient. Please note that if you are on an x86_64 platform running an x86 application using FMOD you will need the x86 version of ALSA installed also.

+

Performance Reference

+

This section is a companion for the CPU Performance section of the Managing Resources in the Core API chapter and serves as a quick reference of facts targeting this platform.

+

Format Choice

+

Each compression format provided in FMOD has a reason for being included, the below list will detail our recommendations for this platform. Formats listed as primary are considering the best choice, secondary formats should only be considered if the primary doesn't satisfy your requirements.

+
    +
  • Vorbis: Primary format for all sounds.
  • +
  • FADPCM: Secondary format if Vorbis CPU usage is too high for low spec machines.
  • +
  • PCM: Not recommended.
  • +
  • XMA: Unavailable.
  • +
  • AT9: Unavailable.
  • +
+

Channel Count

+

To give developers an idea about the costs of a particular format we provide synthetic benchmark results. These results are based on simple usage of the Studio API using recommended configuration settings.

+

Settings

+
    +
  • Real channel count: 64
  • +
  • Sample rate: 48 kHz
  • +
  • Speaker mode: Stereo
  • +
  • DSP block size: 1024 samples
  • +
+

Test Device

+
    +
  • CPU: Intel(R) Core(TM) i7-10510U CPU @ 1.80GHz
  • +
  • OS: Ubuntu 20.10
  • +
+

Results

+
    +
  • DSP with Vorbis: 15.41% (+/- 3.01%)
  • +
  • DSP with FADPCM: 6.31% (+/- 0.25%)
  • +
  • DSP with PCM: 2.65% (+/- 0.17%)
  • +
  • Update at 60 FPS: 1.61% (+/- 0.16%)
  • +
+ + +
+ + + diff --git a/FMOD/doc/FMOD API User Manual/platforms-mac.html b/FMOD/doc/FMOD API User Manual/platforms-mac.html new file mode 100644 index 0000000..ad5d3f4 --- /dev/null +++ b/FMOD/doc/FMOD API User Manual/platforms-mac.html @@ -0,0 +1,146 @@ + + +Platform Details | Mac + + + + +
+ +
+

17. Platform Details | Mac

+ +

macOS Specific Starter Guide

+

SDK Version

+

FMOD is compiled using the following tools.

+
    +
  • Xcode - version 15.0.1 targeting macOS 14.0.
  • +
+

Compatibility

+

FMOD supports x86_64 and arm64 back to macOS 10.13. Please note that both x86 and PPC are not accepted for submission to the Mac App Store and thus are no longer supported by FMOD.

+

Libraries

+

Core API library

+
    +
  • /api/core/lib/libfmod.dylib - Release binary for production code.
  • +
  • /api/core/lib/libfmodL.dylib - Release binary with logging enabled for development.
  • +
+

Studio API library (used in conjunction with the Core API library)

+
    +
  • /api/studio/lib/libfmodstudio.dylib - Release binary for production code.
  • +
  • /api/studio/lib/libfmodstudioL.dylib - Release binary with logging enabled for development.
  • +
+

Latency

+

The default latency introduced by FMOD for this platform is 4 blocks of 512 samples at a sample rate of 48 kHz, which equates to approximately 43 ms. You are free to change this using two APIs, System::setDSPBufferSize and System::setSoftwareFormat but there are some important considerations.

+

All audio devices have a number of samples they prefer to operate in, on Mac this is almost always 512, which makes our default a natural fit. If you use System::setDSPBufferSize to reduce FMODs granularity (to 256 samples for instance), be aware the audio device will still operate at its native block of 512 samples. If you would like to reduce the block size of the audio device (to 256 samples), after you have set the FMOD granularity and initialized the System object use the following code:

+
AudioUnit audioUnit;
+gSystem->getOutputHandle((void **)&audioUnit);
+
+AudioDeviceID audioDeviceID;
+UInt32 audioDeviceIDSize = sizeof(audioDeviceID);
+AudioUnitGetProperty(audioUnit, kAudioOutputUnitProperty_CurrentDevice, kAudioUnitScope_Global, 0, &audioDeviceID, &audioDeviceIDSize);
+
+UInt32 bufferFrameSize = 256;
+AudioDeviceSetProperty(audioDeviceID, NULL, 0, FALSE, kAudioDevicePropertyBufferFrameSize, sizeof(bufferFrameSize), &bufferFrameSize);
+
+ +

Suspend in Background

+

FMOD native threads will continue running when your application transitions to the background, this will continue to use resources. To completely stop FMOD without losing your current setup you can call System::mixerSuspend as part of your backgrounding process. When you return to the foreground, use System::mixerResume to reactivate FMOD. It is extremely important to ensure no FMOD APIs are called in-between suspend and resume as they run the risk of causing a deadlock. You must also call suspend and resume pairs on the same thread.

+

Thread Affinity

+

All threads will default to FMOD_THREAD_AFFINITY_CORE_ALL, it is not currently possible to override this with Thread_SetAttributes.

+

Thread Priority

+

The relationship between FMOD platform agnostic thread priority and the platform specific values is as follows:

+ +

Performance Reference

+

This section is a companion for the CPU Performance section of the Managing Resources in the Core API chapter and serves as a quick reference of facts targeting this platform.

+

Format Choice

+

Each compression format provided in FMOD has a reason for being included, the below list will detail our recommendations for this platform. Formats listed as primary are considering the best choice, secondary formats should only be considered if the primary doesn't satisfy your requirements.

+
    +
  • Vorbis: Primary format for all sounds.
  • +
  • FADPCM: Secondary format if Vorbis CPU usage is too high for low spec machines.
  • +
  • PCM: Not recommended.
  • +
  • XMA: Unavailable.
  • +
  • AT9: Unavailable.
  • +
+

Channel Count

+

To give developers an idea about the costs of a particular format we provide synthetic benchmark results. These results are based on simple usage of the Studio API using recommended configuration settings.

+

Settings

+
    +
  • Real channel count: 64
  • +
  • Sample rate: 48 kHz
  • +
  • Speaker mode: Stereo
  • +
  • DSP block size: 512 samples
  • +
+

Test Device

+
    +
  • CPU: Intel(R) Core(TM) i5-4278U CPU @ 2.60GHz
  • +
  • OS: macOS 10.15.7 (19H2)
  • +
+

Results

+
    +
  • DSP with Vorbis: 7.78% (+/- 0.95%)
  • +
  • DSP with FADPCM: 4.90% (+/- 0.61%)
  • +
  • DSP with PCM: 2.93% (+/- 0.58%)
  • +
  • Update at 60 FPS: 1.81% (+/- 0.35%)
  • +
+ + +
+ + + diff --git a/FMOD/doc/FMOD API User Manual/platforms-openharmony.html b/FMOD/doc/FMOD API User Manual/platforms-openharmony.html new file mode 100644 index 0000000..c519ad0 --- /dev/null +++ b/FMOD/doc/FMOD API User Manual/platforms-openharmony.html @@ -0,0 +1,147 @@ + + +Platform Details | Open Harmony + + + + +
+ +
+

17. Platform Details | Open Harmony

+ +

Open Harmony Specific Starter Guide

+

SDK Version

+

FMOD is compiled using the following tools.

+
    +
  • SDK - version 4.0.10.13 targeting API 10.
  • +
+

Compatibility

+

FMOD supports devices of the below ABIs back to API 10.

+
    +
  • armeabi-v7a - supported and optimized with NEON.
  • +
  • arm64-v8a - supported and optimized with NEON.
  • +
  • x86_64 - supported and optimized with SSE3.
  • +
+

Libraries

+

Substitute $ABI with your desired ABI from the 'Compatibility' list above.

+

Core API library

+
    +
  • /api/core/lib/$ABI/libfmod.so - Release binary for production code.
  • +
  • /api/core/lib/$ABI/libfmodL.so - Release binary with logging enabled for development.
  • +
+

Studio API library (used in conjunction with the Core API library)

+
    +
  • /api/studio/lib/$ABI/libfmodstudio.so - Release binary for production code.
  • +
  • /api/studio/lib/$ABI/libfmodstudioL.so - Release binary with logging enabled for development.
  • +
+

JavaScript

+

FMOD is primarily a native C/C++ library implementation but does provide a limited JavaScript interface to provide necessary data to the engine.

+

It is also highly recommended that you initialize the FMOD JavaScript interface, as this will allow loading assets from the App package. This should be done before System_Create or Studio::System::create, and should be closed after System::release or Studio::System::release.

+

To access the JavaScript interface you must create index.d.ts in src\main\cpp\types\libfmod with the following:

+
export const init: (ability: UIAbility) => void;
+export const close: () => void; 
+
+ +

Create an oh-package.json5 in src\main\cpp\types\libfmod with the following:

+
{
+  "name": "libfmod.so",
+  "types": "./index.d.ts",
+  "version": "",
+  "description": "FMOD Core Library."
+}
+
+ +

Reference the .d.ts in oh-package.json5 for the target (not application), which goes in devDependencies:

+
"devDependencies": {
+  "@types/libfmod.so": "file:./src/main/cpp/types/libfmod"
+},
+
+ +

To call FMOD JavaScript functions you need to edit your Ability.ts and add the following import:

+
import fmod from 'libfmod.so';
+
+ +

In your Ability onCreate function add:

+
fmod.init(this);
+
+ +

In your Ability onDestroy function add:

+
fmod.close();
+
+ +

It is expected that the API for FMOD is called from your existing native code in C++. It is important when initializing FMOD to not call the init function too early otherwise the audio device will fail. Make sure you call FMOD after the WindowStage ACTIVE event occurs, for example, you can edit your Ability.ts, and edit onWindowStageCreate to include the following:

+
windowStage.on('windowStageEvent', (data) => {
+  if (data == window.WindowStageEventType.ACTIVE) {
+    // Call you JS entry point for FMOD creation here
+  }
+  else if (data == window.WindowStageEventType.INACTIVE) {
+    // Call you JS entry point for FMOD destruction here
+  }
+});
+
+ +

Thread Affinity

+

All threads will default to FMOD_THREAD_AFFINITY_CORE_ALL, this is recommended due to the wide variety of devices available but can be customized with Thread_SetAttributes.

+

Thread Priority

+

The relationship between FMOD platform agnostic thread priority and the platform specific values is as follows:

+ +

Resume Audio on Return From Background

+

The system will pause FMOD when your app goes into the background, however it will not resume it when returning to the foreground. To handle this, call System::mixerSuspend from your UIAbility onBackground callback and call System::mixerResume from your UIAbility onForeground callback.

+

Latency

+

For SDK 10 devices, the hardware latency is fixed at ~90ms, for FMOD to operate in this high latency environment you must increase the FMOD buffer size to handle the latency. We recommend calling System::setDSPBufferSize with 2048 as the buffer length and 4 as the number of buffers.

+

For SDK 11 and newer devices, the hardware latency is internally configured to match the FMOD buffer length. If you do not call System::setDSPBufferSize, the default of 1024 buffer length and 4 buffers will be used, which the hardware can use without stuttering. If you want to set the buffer length lower than the default 1024, we recommend using FAST mode.

+

FAST mode is available on all devices and can be selected by calling System::setDriver with 1 before System::init (the default of 0 represents normal mode). With FAST mode activated you should be able to set the FMOD buffer length down to 512, with 4 buffers and achieve glitch free playback. However, please note some development boards cannot handle FAST mode and will result in a crash, thankfully we have seen no such crash in any consumer devices.

+ + +
+ + + diff --git a/FMOD/doc/FMOD API User Manual/platforms-uwp.html b/FMOD/doc/FMOD API User Manual/platforms-uwp.html new file mode 100644 index 0000000..2103916 --- /dev/null +++ b/FMOD/doc/FMOD API User Manual/platforms-uwp.html @@ -0,0 +1,193 @@ + + +Platform Details | Universal Windows Platform + + + + +
+ +
+

17. Platform Details | Universal Windows Platform

+ +

UWP Specific Starter Guide

+

SDK Version

+

FMOD is compiled using the following tools.

+
    +
  • Visual Studio - version 2017 targeting platform toolset v141
  • +
+

Compatibility

+

FMOD supports devices of the below architectures running Windows 10.

+
    +
  • x86 - optimized with SSE3.
  • +
  • x64 - optimized with SSE3 (and AVX if detected at runtime).
  • +
  • arm - optimized with VFPv2 (and NEON if detected at runtime).
  • +
+

Libraries

+

The provided libs are import libraries which require the corresponding DLL to be present at runtime. Substitute $ARCH your desired architecture from the 'Compatibility' list above.

+

Core API library

+
    +
  • /api/core/lib/$ARCH/fmod.lib - Release binary for production code (requires fmod.dll at runtime).
  • +
  • /api/core/lib/$ARCH/fmodL.lib - Release binary with logging enabled for development (requires fmodL.dll at runtime).
  • +
+

Studio API library (used in conjunction with the Core API library)

+
    +
  • /api/studio/lib/$ARCH/fmodstudio.lib - Release binary for production code (requires fmodstudio.dll at runtime).
  • +
  • /api/studio/lib/$ARCH/fmodstudioL.lib - Release binary with logging enabled for development (requires fmodstudioL.dll at runtime).
  • +
+

Plug-ins

+

FMOD includes a media foundation plug-in codec that can optionally be included in your game.

+
    +
  • /api/plugins/media_foundation/lib/$ARCH/media_foundation.dll
  • +
+

This has been separated in order to support Windows N by default - the media foundation plug-in is NOT compatible with Windows N unless the user installs the appropriate Media Feature Pack for Windows.

+

If included, FMOD can use the codec to support WMA, ASF, WMV, M4A and MP4 files.

+

Permissions

+

Some functionality inside of FMOD will require you set relevant capabilities in your manifest file.

+
    +
  • Microphone - to make use of the System::recordStart API, see Known Issues for further notes about recording.
  • +
  • Internet (Client) - to stream audio from the internet.
  • +
  • Private Networks (Client & Server) - to use FMOD profiler or FMOD Studio live update. See Known Issue for further notes about connecting.
  • +
+

Thread Affinity

+

All threads will default to FMOD_THREAD_AFFINITY_CORE_ALL, this is recommended due to the wide variety of PC hardware but can be customized with Thread_SetAttributes.

+

Thread Priority

+

The relationship between FMOD platform agnostic thread priority and the platform specific values is as follows:

+ +

Port Support

+

UWP supports the following port types when using FMOD_OUTPUTTYPE_WINSONIC:

+ +

Background Music

+

The background music will bypass the operating system's virtual speaker processing.

+

Below is a usage demonstration with error checking omitted for brevity:

+
FMOD::ChannelGroup *bgm;
+system->createChannelGroup("BGM", &bgm);
+system->attachChannelGroupToPort(FMOD_PORT_TYPE_MUSIC, FMOD_PORT_INDEX_NONE, bgm);
+
+FMOD::Channel* channel;
+system->playSound(music, bgm, false, &channel);
+
+ +

Pass Through

+

Use this port to bypass the operating system's virtual speaker processing for non-diegetic sounds.

+

Below is a usage demonstration with error checking omitted for brevity:

+
FMOD::ChannelGroup *passthrough;
+system->createChannelGroup("PASSTHROUGH", &passthrough);
+system->attachChannelGroupToPort(FMOD_PORT_TYPE_PASSTHROUGH, FMOD_PORT_INDEX_NONE, passthrough);
+
+FMOD::Channel *channel;
+system->playSound(your_non_diegetic_sound, passthrough, false, &channel);
+
+ +

Known Issues

+
    +
  • +

    Even after adding support for audio recording to your application manifest, you must still make sure to call System::recordStart in the UI thread so the system can display a warning to the user. Calling from any other thread will return FMOD_ERR_OUTPUT_INIT.

    +
  • +
  • +

    FMOD Studio will not be able to connect to the engine if they are both running on the same machine. This is a restriction imposed by the Windows Universal Application environment.

    +
  • +
+

Performance Reference

+

This section is a companion for the CPU Performance section of the Managing Resources in the Core API chapter and serves as a quick reference of facts targeting this platform.

+

Format Choice

+

Each compression format provided in FMOD has a reason for being included, the below list will detail our recommendations for this platform. Formats listed as primary are considering the best choice, secondary formats should only be considered if the primary doesn't satisfy your requirements.

+
    +
  • Vorbis: Primary format for all sounds.
  • +
  • FADPCM: Secondary format if Vorbis CPU usage is too high for low spec machines.
  • +
  • PCM: Not recommended.
  • +
  • XMA: Unavailable.
  • +
  • AT9: Unavailable.
  • +
+

Channel Count

+

To give developers an idea about the costs of a particular format we provide synthetic benchmark results. These results are based on simple usage of the Studio API using recommended configuration settings.

+

Settings

+
    +
  • Real channel count: 64
  • +
  • Sample rate: 48 kHz
  • +
  • Speaker mode: Stereo
  • +
  • DSP block size: 1024 samples
  • +
+

Test Device

+
    +
  • CPU: Intel(R) Core(TM) i5-6400T CPU @ 2.20GHz
  • +
  • OS: Microsoft Windows [Version 10.0.19042.867]
  • +
+

Results

+
    +
  • DSP with Vorbis: 6.45% (+/- 0.66%)
  • +
  • DSP with FADPCM: 3.00% (+/- 0.34%)
  • +
  • DSP with PCM: 1.33% (+/- 0.22%)
  • +
  • Update at 60 FPS: 0.77% (+/- 0.19%)
  • +
+ + +
+ + + diff --git a/FMOD/doc/FMOD API User Manual/platforms-win.html b/FMOD/doc/FMOD API User Manual/platforms-win.html new file mode 100644 index 0000000..d41d3d2 --- /dev/null +++ b/FMOD/doc/FMOD API User Manual/platforms-win.html @@ -0,0 +1,227 @@ + + +Platform Details | Windows + + + + +
+ +
+

17. Platform Details | Windows

+ +

Windows Specific Starter Guide

+

SDK Version

+

FMOD is compiled using the following tools.

+
    +
  • Visual Studio 2019 - version 16.11.0 targeting platform toolset v142.
  • +
+

Compatibility

+

FMOD supports the below architectures back to Windows 7.

+
    +
  • x86 - optimized with SSE3.
  • +
  • x64 - optimized with SSE3 (and AVX if detected at runtime).
  • +
  • ARM64 - optimized with NEON.
  • +
+

Libraries

+

The provided libs are import libraries which require the corresponding DLL to be present at runtime. Substitute $ARCH your desired architecture from the 'Compatibility' list above.

+

The C API of the supplied libraries are compatible with MinGW (C++ ABI not supported). The 64 bit dll can be linked directly. You will need to use the import library libfmod.a and libfmodstudio.a in order to link the 32 bit dlls.

+

If you encounter issues linking fmod with MinGW, ensure that you are following the GCC linker ordering requirements and the MinGW library search order.

+

Core API library

+
    +
  • /api/core/lib/$ARCH/fmod_vc.lib - Release binary for production code (requires fmod.dll at runtime).
  • +
  • /api/core/lib/$ARCH/fmodL_vc.lib - Release binary with logging enabled for development (requires fmodL.dll at runtime).
  • +
+

Studio API library (used in conjunction with the Core API library)

+
    +
  • /api/studio/lib/$ARCH/fmodstudio_vc.lib - Release binary for production code (requires fmodstudio.dll at runtime).
  • +
  • /api/studio/lib/$ARCH/fmodstudioL_vc.lib - Release binary with logging enabled for development (requires fmodstudioL.dll at runtime).
  • +
+

COM

+

Before calling any FMOD functions it is important to ensure COM is initialized. You can achieve this by calling CoInitializeEx(nullptr, COINIT_APARTMENTTHREADED) on each thread that will interact with the FMOD Engine. This is balanced with a call to CoUninitialize() when you are completely finished with all calls to FMOD.

+

If you fail to initialize COM, FMOD will perform this on-demand for you issuing a warning. FMOD will not uninitialize COM in this case so it will be considered a memory leak.

+

To ensure correct behavior FMOD assumes when using the WASAPI output mode (default for Windows Vista and newer) that you call System::getNumDrivers, System::getDriverInfo and System::init from your UI thread. This ensures that any platform specific dialogs that need to be presented can do so. This recommendation comes from the IAudioClient interface docs on MSDN which state:

+
+

In Windows 8, the first use of IAudioClient to access the audio device should be on the STA thread. Calls from an MTA thread may result in undefined behavior.

+
+

ASIO and C#

+

If using FMOD_OUTPUTTYPE_ASIO with the C# wrapper, FMOD will need to be running on the STA thread to ensure COM is intialized correctly. This can be achieved by adding the STAThreadAttribute to the main method:

+
[STAThread]
+static void Main(string[] args)
+{
+    Factory.System_Create(out FMOD.System system);
+    system.setOutput(OUTPUTTYPE.ASIO);
+    system.init(32, INITFLAGS.NORMAL, IntPtr.Zero);
+}
+
+ +

ARM64

+

Building for ARM64 requires Visual Studio 2019 with toolset v142 and supports NEON.

+

Codec Support

+

The following are not supported:

+
    +
  • WMA file format support
  • +
+

DSP Effect Support

+

The following are not supported:

+
    +
  • VST format plug-ins
  • +
+

Output Mode Support

+

The following are not supported:

+
    +
  • ASIO output mode
  • +
+

Thread Affinity

+

All threads will default to FMOD_THREAD_AFFINITY_CORE_ALL, this is recommended due to the wide variety of PC hardware but can be customized with Thread_SetAttributes.

+

Thread Priority

+

The relationship between FMOD platform agnostic thread priority and the platform specific values is as follows:

+ +

Port Support

+

Windows supports the following port types when using FMOD_OUTPUTTYPE_WINSONIC:

+ +

Background Music

+

The background music will bypass the operating system's virtual speaker processing.

+

Below is a usage demonstration with error checking omitted for brevity:

+
FMOD::ChannelGroup *bgm;
+system->createChannelGroup("BGM", &bgm);
+system->attachChannelGroupToPort(FMOD_PORT_TYPE_MUSIC, FMOD_PORT_INDEX_NONE, bgm);
+
+FMOD::Channel* channel;
+system->playSound(music, bgm, false, &channel);
+
+ +

Pass Through

+

Use this port to bypass the operating system's virtual speaker processing for non-diegetic sounds.

+

Below is a usage demonstration with error checking omitted for brevity:

+
FMOD::ChannelGroup *passthrough;
+system->createChannelGroup("PASSTHROUGH", &passthrough);
+system->attachChannelGroupToPort(FMOD_PORT_TYPE_PASSTHROUGH, FMOD_PORT_INDEX_NONE, passthrough);
+
+FMOD::Channel *channel;
+system->playSound(your_non_diegetic_sound, passthrough, false, &channel);
+
+ +

Object Spatialization for 3D Audio (Windows Sonic)

+

Platform-specific object spatialization technologies can potentially offer more accurate spatialization than the FMOD spatializer effect. To take advantage of Windows Sonic to spatialize your events, you can use an FMOD object spatializer effect instead of an FMOD spatializer. Doing so bypasses any subsequent effects or sends, instead routing the event's audio from the FMOD object spatializer directly to Windows Sonic for object spatialization.

+

Most platforms can only handle a limited number of object-spatialized sounds, so the FMOD object spatializer effect is best reserved for use with important events.

+

Your machine must be configured to enable Windows Sonic. To enable Windows Sonic on Windows:

+
    +
  • Ensure that you are running Windows 10 Creators Update or later.
  • +
  • Open the control panel, and click on the sound icon. (If the sound icon does not appear, click on the hardware and sound category.)
  • +
  • In the playback tab of the sound window, right-click on your default audio device to open the context menu, then select "properties."
  • +
  • In the spatial sound tab of the properties window for your default audio device, open the spatial sound format dropdown menu and select "Windows Sonic" or "Windows Sonic for Headphones."
  • +
  • Click the OK button or the apply button to confirm the change.
  • +
+

For more information about object spatialization, see the Spatialization Options and Auditioning Object Spatialization and Height Panning sections of the FMOD Studio User Manual and the Spatial Audio section of the Core API Spatializing Sounds.

+

Performance Reference

+

This section is a companion for the CPU Performance section of the Managing Resources in the Core API chapter and serves as a quick reference of facts targeting this platform.

+

Format Choice

+

Each compression format provided in FMOD has a reason for being included, the below list will detail our recommendations for this platform. Formats listed as primary are considering the best choice, secondary formats should only be considered if the primary doesn't satisfy your requirements.

+
    +
  • Vorbis: Primary format for all sounds.
  • +
  • FADPCM: Secondary format if Vorbis CPU usage is too high for low spec machines.
  • +
  • PCM: Not recommended.
  • +
  • XMA: Unavailable.
  • +
  • AT9: Unavailable.
  • +
+

Channel Count

+

To give developers an idea about the costs of a particular format we provide synthetic benchmark results. These results are based on simple usage of the Studio API using recommended configuration settings.

+

Settings

+
    +
  • Real channel count: 64
  • +
  • Sample rate: 48 kHz
  • +
  • Speaker mode: Stereo
  • +
  • DSP block size: 1024 samples
  • +
+

Test Device

+
    +
  • CPU: Intel(R) Core(TM) i7 CPU 860 @ 2.80GHz
  • +
  • OS: Microsoft Windows [Version 6.1.7601]
  • +
+

Results

+
    +
  • DSP with Vorbis: 6.88% (+/- 0.52%)
  • +
  • DSP with FADPCM: 3.10% (+/- 0.20%)
  • +
  • DSP with PCM: 1.59% (+/- 0.24%)
  • +
  • Update at 60 FPS: 0.82% (+/- 0.05%)
  • +
+ + +
+ + + diff --git a/FMOD/doc/FMOD API User Manual/platforms.html b/FMOD/doc/FMOD API User Manual/platforms.html new file mode 100644 index 0000000..8b66544 --- /dev/null +++ b/FMOD/doc/FMOD API User Manual/platforms.html @@ -0,0 +1,52 @@ + + +Platform Details + + + + + + + + diff --git a/FMOD/doc/FMOD API User Manual/plugin-api-codec.html b/FMOD/doc/FMOD API User Manual/plugin-api-codec.html new file mode 100644 index 0000000..0abb595 --- /dev/null +++ b/FMOD/doc/FMOD API User Manual/plugin-api-codec.html @@ -0,0 +1,1050 @@ + + +Plug-in API Reference | Codec + + + + +
+ +
+

19. Plug-in API Reference | Codec

+

An interface that manages codec plug-ins.

+

General:

+ +
+ +
+ +
+ +

FMOD_CODEC_ALLOC_FUNC

+

Codec allocate memory function.

+

+

+
C
+
C++
+
JS
+
+

+
void * F_CALL FMOD_CODEC_ALLOC_FUNC(
+  unsigned int size,
+  unsigned int align,
+  const char *file,
+  int line
+);
+
+ +
+

Not supported for C#.

+
+
+

Not supported for JavaScript.

+
+
+
size
+
+

Allocation size.

+
    +
  • Units: Bytes
  • +
+
+
align
+
+

Memory alignment.

+
    +
  • Units: Bytes
  • +
+
+
file
+
Source code file name where the allocation was requested.
+
line
+
Line of allocation in file.
+
+

See Also: FMOD_CODEC_STATE

+

FMOD_CODEC_CLOSE_CALLBACK

+

Codec close callback.

+

This callback is called to shut down and release memory for the codec instance.

+

+

+
C
+
C++
+
JS
+
+

+
FMOD_RESULT F_CALL FMOD_CODEC_CLOSE_CALLBACK(
+  FMOD_CODEC_STATE *codec_state
+);
+
+ +
+

Not supported for C#.

+
+
+

Not supported for JavaScript.

+
+
+
codec_state
+
Codec state. (FMOD_CODEC_STATE)
+
+

Invoked by:

+ +

See Also: FMOD_CODEC_DESCRIPTION, FMOD_CODEC_OPEN_CALLBACK, FMOD_CODEC_SOUNDCREATE_CALLBACK

+

FMOD_CODEC_DESCRIPTION

+

Codec description.

+

This description structure allows the plug-in writer to define all functionality required for a user-defined codec.

+

+

+
C
+
C++
+
JS
+
+

+
typedef struct FMOD_CODEC_DESCRIPTION {
+  unsigned int                        apiversion;
+  const char                         *name;
+  unsigned int                        version;
+  int                                 defaultasstream;
+  FMOD_TIMEUNIT                       timeunits;
+  FMOD_CODEC_OPEN_CALLBACK            open;
+  FMOD_CODEC_CLOSE_CALLBACK           close;
+  FMOD_CODEC_READ_CALLBACK            read;
+  FMOD_CODEC_GETLENGTH_CALLBACK       getlength;
+  FMOD_CODEC_SETPOSITION_CALLBACK     setposition;
+  FMOD_CODEC_GETPOSITION_CALLBACK     getposition;
+  FMOD_CODEC_SOUNDCREATE_CALLBACK     soundcreate;
+  FMOD_CODEC_GETWAVEFORMAT_CALLBACK   getwaveformat;
+} FMOD_CODEC_DESCRIPTION;
+
+ +
FMOD_CODEC_DESCRIPTION
+{
+  apiversion,
+  name,
+  version,
+  defaultasstream,
+  timeunits,
+  open,
+  close,
+  read,
+  getlength,
+  setposition,
+  getposition,
+  soundcreate,
+  getwaveformat,
+};
+
+ +
+

Currently not supported for C#.

+
+
+
apiversion
+
The codec plug-in API version this plug-in is built for. Set to this to FMOD_CODEC_PLUGIN_VERSION.
+
name
+
Name of the codec.
+
version
+
Plug-in's version number.
+
defaultasstream
+
Defaults as stream.
+
timeunits
+
Time units used with setposition codec. (FMOD_TIMEUNIT)
+
open
+
Open callback. (FMOD_CODEC_OPEN_CALLBACK)
+
close
+
Close callback. (FMOD_CODEC_CLOSE_CALLBACK)
+
read
+
Read callback. (FMOD_CODEC_READ_CALLBACK)
+
getlength
+
Get length callback. (FMOD_CODEC_GETLENGTH_CALLBACK)
+
setposition
+
Seek callback. (FMOD_CODEC_SETPOSITION_CALLBACK)
+
getposition
+
Get position callback. (FMOD_CODEC_GETPOSITION_CALLBACK)
+
soundcreate
+
Sound creation callback. (FMOD_CODEC_SOUNDCREATE_CALLBACK)
+
getwaveformat
+
Get wave format callback. (FMOD_CODEC_GETWAVEFORMAT_CALLBACK)
+
+

See Also: FMOD_CODEC_STATE, FMOD_CODEC_WAVEFORMAT

+

FMOD_CODEC_FILE_READ_FUNC

+

Codec file read function.

+

+

+
C
+
C++
+
JS
+
+

+
FMOD_RESULT F_CALL FMOD_CODEC_FILE_READ_FUNC(
+  FMOD_CODEC_STATE *codec_state,
+  void *buffer,
+  unsigned int sizebytes,
+  unsigned int *bytesread
+);
+
+ +
+

Not supported for C#.

+
+
+

Not supported for JavaScript.

+
+
+
codec_state
+
Codec state. (FMOD_CODEC_STATE)
+
buffer Out
+
Buffer to read data into.
+
sizebytes
+
+

Number of bytes to read into buffer.

+
    +
  • Units: Bytes
  • +
+
+
bytesread Out
+
+

Number of bytes read into buffer.

+
    +
  • Units: Bytes
  • +
+
+
+

If there is not enough data to read the requested number of bytes, return fewer bytes in the bytesread parameter and and return FMOD_ERR_FILE_EOF.

+

See Also: FMOD_CODEC_FILE_SEEK_FUNC, FMOD_CODEC_FILE_TELL_FUNC, FMOD_CODEC_FILE_SIZE_FUNC

+

FMOD_CODEC_FILE_SEEK_FUNC

+

Codec file seek function.

+

+

+
C
+
C++
+
JS
+
+

+
FMOD_RESULT F_CALL FMOD_CODEC_FILE_SEEK_FUNC(
+  FMOD_CODEC_STATE *codec_state,
+  unsigned int pos,
+  FMOD_CODEC_SEEK_METHOD method
+);
+
+ +
+

Not supported for C#.

+
+
+

Not supported for JavaScript.

+
+
+
codec_state
+
Codec state. (FMOD_CODEC_STATE)
+
pos
+
+

Absolute position to seek to in file with respect to the seek method.

+
    +
  • Units: Bytes
  • +
+
+
method
+
Method of seeking. (FMOD_CODEC_SEEK_METHOD)
+
+

See Also: FMOD_CODEC_FILE_READ_FUNC, FMOD_CODEC_FILE_TELL_FUNC, FMOD_CODEC_FILE_SIZE_FUNC

+

FMOD_CODEC_FILE_SIZE_FUNC

+

Codec file size function.

+

+

+
C
+
C++
+
JS
+
+

+
FMOD_RESULT F_CALL FMOD_CODEC_FILE_SIZE_FUNC(
+  FMOD_CODEC_STATE *codec_state,
+  unsigned int *size
+);
+
+ +
+

Not supported for C#.

+
+
+

Not supported for JavaScript.

+
+
+
codec_state
+
Codec state. (FMOD_CODEC_STATE)
+
size Out
+
+

Size of the file.

+
    +
  • Units: Bytes
  • +
+
+
+

See Also: FMOD_CODEC_FILE_READ_FUNC, FMOD_CODEC_FILE_SEEK_FUNC, FMOD_CODEC_FILE_TELL_FUNC

+

FMOD_CODEC_FILE_TELL_FUNC

+

Codec file function to retrieve the current file position.

+

+

+
C
+
C++
+
JS
+
+

+
FMOD_RESULT F_CALL FMOD_CODEC_FILE_TELL_FUNC(
+  FMOD_CODEC_STATE *codec_state,
+  unsigned int *pos
+);
+
+ +
+

Not supported for C#.

+
+
+

Not supported for JavaScript.

+
+
+
codec_state
+
Codec state. (FMOD_CODEC_STATE)
+
pos Out
+
+

Current absolute position in file.

+
    +
  • Units: Bytes
  • +
+
+
+

See Also: FMOD_CODEC_FILE_READ_FUNC, FMOD_CODEC_FILE_SEEK_FUNC, FMOD_CODEC_FILE_SIZE_FUNC

+

FMOD_CODEC_FREE_FUNC

+

Codec free memory function.

+

+

+
C
+
C++
+
JS
+
+

+
void F_CALL FMOD_CODEC_FREE_FUNC(
+  void *ptr,
+  const char *file,
+  int line
+);
+
+ +
+

Not supported for C#.

+
+
+

Not supported for JavaScript.

+
+
+
ptr
+
Allocation pointer.
+
file
+
Source code file name where the allocation is freed.
+
line
+
Line of free call in file.
+
+

See Also: FMOD_CODEC_STATE

+

FMOD_CODEC_GETLENGTH_CALLBACK

+

Codec get length callback.

+

This callback is called to retrieve the length of the audio file of this codec type.

+

+

+
C
+
C++
+
JS
+
+

+
FMOD_RESULT F_CALL FMOD_CODEC_GETLENGTH_CALLBACK(
+  FMOD_CODEC_STATE *codec_state,
+  unsigned int *length,
+  FMOD_TIMEUNIT lengthtype
+);
+
+ +
+

Not supported for C#.

+
+
+

Not supported for JavaScript.

+
+
+
codec_state
+
Codec state. (FMOD_CODEC_STATE)
+
length Out
+
Length of the sound in units determined by lengthtype.
+
lengthtype
+
Timeunit type of length. (FMOD_TIMEUNIT)
+
+

Invoked by:

+ +

See Also: FMOD_CODEC_DESCRIPTION

+

FMOD_CODEC_GETPOSITION_CALLBACK

+

Codec get position callback.

+

This callback is called to retrieve the current read position of the audio file of this codec type.

+

+

+
C
+
C++
+
JS
+
+

+
FMOD_RESULT F_CALL FMOD_CODEC_GETPOSITION_CALLBACK(
+  FMOD_CODEC_STATE *codec_state,
+  unsigned int *position,
+  FMOD_TIMEUNIT postype
+);
+
+ +
+

Not supported for C#.

+
+
+

Not supported for JavaScript.

+
+
+
codec_state
+
Codec state. (FMOD_CODEC_STATE)
+
position Out
+
Codec position in units determined by postype.
+
postype
+
Time units for position. This will be one of the timeunits supplied by the codec author in the FMOD_CODEC_DESCRIPTION structure. (FMOD_TIMEUNIT)
+
+

Invoked by:

+ +

See Also: FMOD_CODEC_DESCRIPTION

+

FMOD_CODEC_GETWAVEFORMAT_CALLBACK

+

Codec get wave format callback.

+

This callback is called to allow FMOD to retrieve the format of the file the codec instance represents.

+

+

+
C
+
C++
+
JS
+
+

+
FMOD_RESULT F_CALL FMOD_CODEC_GETWAVEFORMAT_CALLBACK(
+  FMOD_CODEC_STATE *codec_state,
+  int index,
+  FMOD_CODEC_WAVEFORMAT *waveformat
+);
+
+ +
+

Not supported for C#.

+
+
+

Not supported for JavaScript.

+
+
+
codec_state
+
Codec state. (FMOD_CODEC_STATE)
+
index
+
Subsound index. This is only used in file formats which can store multiple sounds within them, otherwise it will be 0.
+
waveformat Out
+
Wave format of the sound object. (FMOD_CODEC_WAVEFORMAT)
+
+

Useful to reduce memory usage by limiting the number of FMOD_CODEC_WAVEFORMAT structures.

+

FMOD_CODEC_LOG_FUNC

+

Codec log function.

+

Call this function in an codec plug-in context to utilize FMOD's debugging system.

+

+

+
C
+
C++
+
JS
+
+

+
void F_CALL FMOD_CODEC_LOG_FUNC(
+  FMOD_DEBUG_FLAGS level,
+  const char *file,
+  int line,
+  const char *function,
+  const char *string,
+  ...
+);
+
+ +
+

Not supported for C#.

+
+
+

Not supported for JavaScript.

+
+
+
level
+
Log type or level. (FMOD_DEBUG_FLAGS)
+
file
+
Source code file name from where the log is called. (UTF-8 string)
+
line
+
Line of log call in file.
+
function
+
Name of the logging function. (UTF-8 string)
+
string
+
Log codec string. (UTF-8 string)
+
+

See Also: FMOD_CODEC_STATE

+

FMOD_CODEC_METADATA_FUNC

+

Codec metadata function.

+

This function is to be called when a codec's metadata is updated.

+

+

+
C
+
C++
+
JS
+
+

+
FMOD_RESULT F_CALL FMOD_CODEC_METADATA_FUNC(
+  FMOD_CODEC_STATE *codec_state,
+  FMOD_TAGTYPE tagtype,
+  char *name,
+  void *data,
+  unsigned int datalen,
+  FMOD_TAGDATATYPE datatype,
+  int unique
+);
+
+ +
+

Not supported for C#.

+
+
+

Not supported for JavaScript.

+
+
+
codec_state
+
Codec state. (FMOD_CODEC_STATE)
+
tagtype
+
Source type of tag being updated. (FMOD_TAGTYPE)
+
name
+
Name of the tag being updated.
+
data
+
Contents of tag.
+
datalen
+
+

Data length of the tag data in bytes.

+
    +
  • Units: Bytes
  • +
+
+
datatype
+
Data type of tag. (FMOD_TAGDATATYPE)
+
unique
+
Unique state. If this is true / non zero, then the tag (determined by the name) being updated is the only one of its type. If it is zero then there are multiple versions of this tag with the same name.
+
+

Codec metadata can be retrieved by the user with Sound::getTag

+

Codec metadata can be added during creation, or during playback. A common case for play time metadata is internet based streams.

+

See Also: FMOD_CODEC_DESCRIPTION

+

FMOD_CODEC_OPEN_CALLBACK

+

Codec open callback.

+

This callback is called to initialize a codec instance using the codec's file handle to verify if the file is of the type of the codec, and to do any file reading required for initialization of the codec.

+

+

+
C
+
C++
+
JS
+
+

+
FMOD_RESULT F_CALL FMOD_CODEC_OPEN_CALLBACK(
+  FMOD_CODEC_STATE *codec_state,
+  FMOD_MODE usermode,
+  FMOD_CREATESOUNDEXINFO *userexinfo
+);
+
+ +
+

Not supported for C#.

+
+
+

Not supported for JavaScript.

+
+
+
codec_state
+
Codec state. Use this to access codec specific variables, the FMOD file system for reading/seeking, and codec user data. (FMOD_CODEC_STATE)
+
usermode Opt
+
+

Mode that the user supplied via System::createSound or System::createStream. (FMOD_MODE)

+ +
+
userexinfo Opt
+
Extra info structure that the user supplied via System::createSound or System::createStream. (FMOD_CREATESOUNDEXINFO)
+
+

Invoked by:

+ +

Implementation detail:

+

This callback is where the file format check is done, memory is allocated, and the codec is initialized.

+

The usermode and userexinfo parameters tell the codec what was passed in by the user. Generally these can be ignored, as the file format usually determines the format and frequency of the sound. If you have a flexible format codec (ie you don't mind what output format your codec writes to), you might want to use the parameter that was passed in by the user to specify the output sound format / frequency.

+

Read and seek within the file using the fileread and fileseek members of the FMOD_CODEC_STATE structure that is passed in.

+

Note!: Do not use your own filesystem.

+

The reasons for this are:

+
    +
  • The user may have set their own file system via user filesystem callbacks.
  • +
  • FMOD allows file reading via disk, memory and TCP/IP. If you use your own file routines you will lose this ability.
  • +
+

Important! FMOD will ping all codecs trying to find the right one for the file the user has passed in. Make sure the first line of your codec open is a FAST format check. Ie it reads an identifying string, checks it and returns an error FMOD_ERR_FORMAT if it is not found.

+

See Also: FMOD_CODEC_DESCRIPTION, FMOD_CODEC_CLOSE_CALLBACK, FMOD_CODEC_SOUNDCREATE_CALLBACK

+

FMOD_CODEC_PLUGIN_VERSION

+

The codec plug-in API version the plug-in was built with.

+

+

+
C
+
C++
+
JS
+
+

+
#define FMOD_CODEC_PLUGIN_VERSION   1
+
+ +
FMOD.CODEC_PLUGIN_VERSION
+
+ +
+

Currently not supported for C#.

+
+

See Also: FMOD_CODEC_DESCRIPTION

+

FMOD_CODEC_READ_CALLBACK

+

Codec read callback.

+

This callback is called to read PCM data from the codec instance.

+

+

+
C
+
C++
+
JS
+
+

+
FMOD_RESULT F_CALL FMOD_CODEC_READ_CALLBACK(
+  FMOD_CODEC_STATE *codec_state,
+  void *buffer,
+  unsigned int samples_in,
+  unsigned int *samples_out
+);
+
+ +
+

Not supported for C#.

+
+
+

Not supported for JavaScript.

+
+
+
codec_state
+
Codec state. (FMOD_CODEC_STATE)
+
buffer
+
+

Target PCM data buffer. Note that the format of this data is the format described in FMOD_CODEC_WAVEFORMAT.

+ +
+
samples_in
+
+

Number of PCM samples to decode

+
    +
  • Units: Samples
  • +
+
+
samples_out
+
+

Number of PCM samples decoded

+
    +
  • Units: Samples
  • +
+
+
+

This callback is issued when FMOD tries to read some data from the file to the destination format (the format specified in the FMOD_CODEC_OPEN_CALLBACK).

+

Implementation detail:

+

If you cannot read number of samples requested, simply return FMOD_OK and give samples_out the number of samples you decoded.

+

Read and seek within the file using the fileread and fileseek members of the FMOD_CODEC_STATE structure that is passed in.

+

Note!: Do not use your own filesystem.

+

The reasons for this are:

+
    +
  • The user may have set their own file system via user filesystem callbacks.
  • +
  • FMOD allows file reading via disk, memory and TCP/IP. If you use your own file routines you will lose this ability.
  • +
+

See Also: FMOD_CODEC_DESCRIPTION

+

FMOD_CODEC_SEEK_METHOD

+

File seek methods.

+

+

+
C
+
C++
+
JS
+
+

+
#define FMOD_CODEC_SEEK_METHOD_SET     0
+#define FMOD_CODEC_SEEK_METHOD_CURRENT 1
+#define FMOD_CODEC_SEEK_METHOD_END     2
+
+ +
+

Not supported for C#.

+
+
+

Not supported for JavaScript.

+
+
+
FMOD_CODEC_SEEK_METHOD_SET
+
Seeks from the beginning.
+
FMOD_CODEC_SEEK_METHOD_CURRENT
+
Seeks from the current position.
+
FMOD_CODEC_SEEK_METHOD_END
+
Seeks from the end.
+
+

See Also: FMOD_CODEC_FILE_SEEK_FUNC

+

FMOD_CODEC_SETPOSITION_CALLBACK

+

Codec set position callback.

+

This callback is called to set the audible position of a codec instance.

+

+

+
C
+
C++
+
JS
+
+

+
FMOD_RESULT F_CALL FMOD_CODEC_SETPOSITION_CALLBACK(
+  FMOD_CODEC_STATE *codec_state,
+  int subsound,
+  unsigned int position,
+  FMOD_TIMEUNIT postype
+);
+
+ +
+

Not supported for C#.

+
+
+

Not supported for JavaScript.

+
+
+
codec_state
+
Codec state. (FMOD_CODEC_STATE)
+
subsound
+
Subsound within which to seek. This is only used in file formats which can store multiple sounds within them, otherwise it will be 0.
+
position
+
Seek position in units determined by postype.
+
postype
+
Time units for position. This will be one of the timeunits supplied by the codec author in the FMOD_CODEC_DESCRIPTION structure. (FMOD_TIMEUNIT)
+
+

Invoked by:

+ +

Implementation detail:

+

Read and seek within the file using the fileread and fileseek members of the FMOD_CODEC_STATE structure that is passed in.

+

Note!: Do not use your own filesystem.

+

The reasons for this are:

+
    +
  • The user may have set their own file system via user filesystem callbacks.
  • +
  • FMOD allows file reading via disk, memory and TCP/IP. If you use your own file routines you will lose this ability.
  • +
+

See Also: Channel::getPosition, FMOD_CODEC_READ_CALLBACK, FMOD_CODEC_GETLENGTH_CALLBACK, FMOD_CODEC_GETPOSITION_CALLBACK

+

FMOD_CODEC_SOUNDCREATE_CALLBACK

+

Codec sound create callback.

+

This callback is called after a Sound is created.

+

+

+
C
+
C++
+
JS
+
+

+
FMOD_RESULT F_CALL FMOD_CODEC_SOUNDCREATE_CALLBACK(
+  FMOD_CODEC_STATE *codec_state,
+  int subsound,
+  FMOD_SOUND *sound
+);
+
+ +
+

Not supported for C#.

+
+
+

Not supported for JavaScript.

+
+
+
codec_state
+
Codec state. (FMOD_CODEC_STATE)
+
subsound
+
Subsound index being created. This is only used in file formats which can store multiple sounds within them, otherwise it will be 0.
+
sound Out
+
Newly created Sound object. (Sound)
+
+

Invoked by:

+ +

Useful so the codec can set more parameters for the related created sound.

+

See Also: System::createSound, System::createStream

+

FMOD_CODEC_STATE

+

Codec state structure that is passed into each callback.

+

+

+
C
+
C++
+
JS
+
+

+
typedef struct FMOD_CODEC_STATE {
+  void                          *plugindata;
+  FMOD_CODEC_WAVEFORMAT         *waveformat;
+  FMOD_CODEC_STATE_FUNCTIONS    *functions;
+  int                            numsubsounds;
+} FMOD_CODEC_STATE;
+
+ +
FMOD_CODEC_STATE
+{
+  plugindata;
+  waveformat;
+  functions;
+  numsubsounds,
+};
+
+ +
+

Not supported for C#.

+
+
+
plugindata
+
Data that the plugin writer wants to attach to this object.
+
waveformat Opt
+
Array of format structures containing information about each sound. (FMOD_CODEC_WAVEFORMAT)
+
functions R/O
+
Struct containing functions to give plug-in developers the ability to query system state, access system level functionality and helpers. (FMOD_CODEC_STATE_FUNCTIONS)
+
numsubsounds
+
Number of 'subsounds' in this sound. Anything other than 0 makes it a 'container' format.
+
+

'numsubsounds' should be 1+ if the file is a container format, and does not contain wav data itself. Examples of these types would be FSB (contains multiple sounds), DLS (contain instruments).

+

The waveformat value should point to an array of information based on how many subsounds are in the format. If the number of subsounds is 0 then it should point to 1 waveformat, the same as if the number of subsounds was 1. If subsounds was 100 for example, there should be a pointer to an array of 100 waveformat structures.

+

When a sound has 1 or more subsounds, the caller must play the individual sounds specified by first obtaining the subsound with Sound::getSubSound.

+

FMOD_CODEC_STATE_FUNCTIONS

+

Struct containing functions to give plug-in developers the ability to query system state and access system level functionality and helpers.

+

+

+
C
+
C++
+
JS
+
+

+
typedef struct FMOD_CODEC_STATE_FUNCTIONS {
+    FMOD_CODEC_METADATA_FUNC     metadata;
+    FMOD_CODEC_ALLOC_FUNC        alloc;
+    FMOD_CODEC_FREE_FUNC         free;
+    FMOD_CODEC_LOG_FUNC          log;
+    FMOD_CODEC_FILE_READ_FUNC    read;
+    FMOD_CODEC_FILE_SEEK_FUNC    seek;
+    FMOD_CODEC_FILE_TELL_FUNC    tell;
+    FMOD_CODEC_FILE_SIZE_FUNC    size;
+} FMOD_CODEC_STATE_FUNCTIONS;
+
+ +
+

Not supported for C#.

+
+
+

Not supported for JavaScript.

+
+
+
metadata R/O
+
This will return a callable FMOD metadata function to use from codec. (FMOD_CODEC_METADATA_FUNC)
+
alloc R/O
+
Function to allocate memory using the FMOD memory system. (FMOD_CODEC_ALLOC_FUNC)
+
free R/O
+
Function to free memory allocated with FMOD_CODEC_ALLOC_FUNC. (FMOD_CODEC_FREE_FUNC)
+
log R/O
+
Function to write to the FMOD logging system. (FMOD_CODEC_LOG_FUNC)
+
read R/O
+
Function to read using a file handle. (FMOD_CODEC_FILE_READ_FUNC)
+
seek R/O
+
Function to seek using a file handle. (FMOD_CODEC_FILE_SEEK_FUNC)
+
tell R/O
+
Function to get the current read cursor position of a file handle. (FMOD_CODEC_FILE_TELL_FUNC)
+
size R/O
+
Function to get the size using a file handle. (FMOD_CODEC_FILE_SIZE_FUNC)
+
+

See Also: FMOD_CODEC_STATE

+

FMOD_CODEC_WAVEFORMAT

+

Codec wave format.

+

This structure defines the attributes of a sound, and determines the format of the Sound object when it is created with System::createSound or System::createStream

+

+

+
C
+
C++
+
JS
+
+

+
typedef struct FMOD_CODEC_WAVEFORMAT {
+  const char*         name;
+  FMOD_SOUND_FORMAT   format;
+  int                 channels;
+  int                 frequency;
+  unsigned int        lengthbytes;
+  unsigned int        lengthpcm;
+  unsigned int        pcmblocksize;
+  int                 loopstart;
+  int                 loopend;
+  FMOD_MODE           mode;
+  FMOD_CHANNELMASK    channelmask;
+  FMOD_CHANNELORDER   channelorder;
+  float               peakvolume;
+} FMOD_CODEC_WAVEFORMAT;
+
+ +
FMOD_CODEC_WAVEFORMAT
+{
+  name,
+  format,
+  channels,
+  frequency,
+  lengthbytes,
+  lengthpcm,
+  pcmblocksize,
+  loopstart,
+  loopend,
+  mode,
+  channelmask,
+  channelorder,
+  peakvolume,
+};
+
+ +
+

Currently not supported for C#.

+
+
+
name Opt
+
Name of sound. The codec must own the lifetime of the string memory until the codec is destroyed. (UTF-8 string)
+
format
+
Format for codec output. (FMOD_SOUND_FORMAT)
+
channels
+
Number of channels.
+
frequency
+
+

Default frequency of the codec.

+
    +
  • Units: Hertz
  • +
+
+
lengthbytes Opt
+
+

Length of the source data. Used for FMOD_TIMEUNIT_RAWBYTES.

+
    +
  • Units: Bytes
  • +
+
+
lengthpcm
+
+

Length of the file. Used for Sound::getLength and for memory allocation of static decompressed sample data.

+
    +
  • Units: Samples
  • +
+
+
pcmblocksize Opt
+
Minimum, optimal number of decompressed PCM samples codec can handle.
+
loopstart Opt
+
+

Loop start position.

+
    +
  • Units: Samples
  • +
+
+
loopend Opt
+
+

Loop end position.

+
    +
  • Units: Samples
  • +
+
+
mode Opt
+
+

Default sound loading mode. (FMOD_MODE)

+ +
+
channelmask Opt
+
Channel bitmask to describe which speakers the channels in the codec map to, in order of channel count. (FMOD_CHANNELMASK)
+
channelorder Opt
+
Channel order type that describes where each audio channel should pan for the number of channels specified. (FMOD_CHANNELORDER)
+
peakvolume Opt
+
Peak volume of sound.
+
+

The format, channels, frequency and lengthpcm tell FMOD what sort of sound buffer to create when you initialize your code.

+

If you wrote an MP3 codec that decoded to stereo 16bit integer PCM for a 44khz sound, you would specify FMOD_SOUND_FORMAT_PCM16, and channels would be equal to 2, and frequency would be 44100.

+

1.07 Note. 'blockalign' member which was in bytes has been removed. 'pcmblocksize' is now the replacement, and is measured in PCM samples only, not bytes. This is purely to support buffering
+internal to FMOD for codecs that are not sample accurate.

+

Note: When registering a codec, format, channels, frequency and lengthpcm must be supplied, otherwise there will be an error.

+

This structure is optional if FMOD_CODEC_GETWAVEFORMAT_CALLBACK is specified.

+

An array of these structures may be needed if FMOD_CODEC_STATE::numsubsounds is larger than 1.

+

See Also: FMOD_CODEC_STATE, FMOD_CODEC_DESCRIPTION

+ + +
+ + + diff --git a/FMOD/doc/FMOD API User Manual/plugin-api-dsp.html b/FMOD/doc/FMOD API User Manual/plugin-api-dsp.html new file mode 100644 index 0000000..c11e62f --- /dev/null +++ b/FMOD/doc/FMOD API User Manual/plugin-api-dsp.html @@ -0,0 +1,3951 @@ + + +Plug-in API Reference | DSP + + + + +
+ +
+

19. Plug-in API Reference | DSP

+

An interface that manages DSP plug-ins.

+

For more information on creating and using DSP plug-ins, please refer to the Plug-in DSP API Guide.

+

System:

+ +

Parameter API:

+ +
+ +
+ +
+ +

General:

+ +
+ +
+ +
+
    +
  • FMOD_DSP_STATE_DFT_FUNCTIONS Struct containing DFT functions to enable a plug-in to perform optimized time-frequency domain conversion.
  • +
  • FMOD_DSP_STATE_FUNCTIONS Struct containing functions to give plug-in developers the ability to query system state and access system level functionality and helpers.
  • +
  • FMOD_DSP_STATE_PAN_FUNCTIONS Struct containing panning helper functions for spatialization plug-ins.
  • +
+
+ +
+

Functions:

+ +
+ +
+ +
+ +
+ +

FMOD_COMPLEX

+

Complex number structure.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
typedef struct FMOD_COMPLEX {
+  float   real;
+  float   imag;
+} FMOD_COMPLEX;
+
+ +
struct COMPLEX
+{
+  float real;
+  float imag;
+}
+
+ +
FMOD_COMPLEX
+{
+  real,
+  imag,
+};
+
+ +
+
real
+
Real component
+
imag
+
Imaginary component
+
+

See Also: FMOD_DSP_STATE_FUNCTIONS, FMOD_DSP_STATE_DFT_FUNCTIONS

+

FMOD_DSP_ALLOC_FUNC

+

Function to allocate memory using the FMOD memory system.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
void * F_CALL FMOD_DSP_ALLOC_FUNC(
+    unsigned int size,
+    FMOD_MEMORY_TYPE type,
+    const char *sourcestr
+);
+
+ +
delegate IntPtr DSP_ALLOC_FUNC(
+    uint size,
+    MEMORY_TYPE type,
+    IntPtr sourcestr
+);
+
+ +
+

Not supported for JavaScript.

+
+
+
size
+
+

Allocation size.

+
    +
  • Units: Bytes
  • +
+
+
type
+
Memory allocation type. (FMOD_MEMORY_TYPE)
+
sourcestr
+
String with the FMOD source code filename and line number in it. Only valid in logging versions of FMOD. (UTF-8 string)
+
+
+

The 'sourcestr' argument can be used via StringWrapper by using FMOD.StringWrapper sourceStr = new FMOD.StringWrapper(sourcestr);

+
+

Implementation Detail:

+

This function is a wrapper used by the system level allocator and can be called from any DSP instance. Returns a pointer to a region of memory with the requested size, or 0 on a failure.

+

See Also: FMOD_DSP_STATE, FMOD_DSP_REALLOC_FUNC, FMOD_DSP_FREE_FUNC

+

FMOD_DSP_BUFFER_ARRAY

+

Structure for input and output buffers.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
typedef struct FMOD_DSP_BUFFER_ARRAY {
+  int                numbuffers;
+  int               *buffernumchannels;
+  FMOD_CHANNELMASK   *bufferchannelmask;
+  float            **buffers;
+  FMOD_SPEAKERMODE   speakermode;
+} FMOD_DSP_BUFFER_ARRAY;
+
+ +
struct DSP_BUFFER_ARRAY
+{
+  int           numbuffers;
+  int[]         buffernumchannels;
+  CHANNELMASK[] bufferchannelmask;
+  IntPtr[]      buffers;
+  SPEAKERMODE   speakermode;
+  int           numchannels;
+  IntPtr        buffer;
+}
+
+ +
+

Not supported for JavaScript.

+
+
+
numbuffers
+
Array size of buffers.
+
buffernumchannels
+
Array of number of channels for each buffer.
+
bufferchannelmask
+
Deprecated. (FMOD_CHANNELMASK)
+
buffers
+
Array of buffers.
+
speakermode
+
Speaker mode for all buffers in the array. (FMOD_SPEAKERMODE)
+
numchannels C#
+
C# helper property to get number of channels in the buffer.
+
buffer C#
+
C# helper property to retrieve memory from the buffers property.
+
+

This structure is used for reading and writing sample data in the FMOD_DSP_PROCESS_CALLBACK.

+

Example:

+

The following example demonstrates how to traverse a buffer array to generate a square wave:

+
int numchannels = outbufferarray[0].buffernumchannels[0];
+float *output = outbufferarray[0].buffers[0];
+
+bool pos = false;
+int step = 0;
+for (unsigned int sample = 0; sample < length; sample++)
+{
+    for (int channel = 0; channel < numchannels; channel++)
+    {
+        output[sample * numchannels + channel] = pos ? 1.0f : -1.0f;
+    }
+    if (step++ % 32 == 0)
+    {
+        pos = !pos;
+    }
+}
+
+ +
int numchannels = outbufferarray.numchannels;
+float[] output = new float[length * numchannels];
+
+bool pos = false;
+int step = 0;
+for (int sample = 0; sample < length; sample++)
+{
+    for (int channel = 0; channel < numchannels; channel++)
+    {
+        output[sample * numchannels + channel] = pos ? 1.0f : -1.0f;
+    }
+    if (step++ % 32 == 0)
+    {
+        pos = !pos;
+    }
+}
+
+Marshal.Copy(output, 0, outbufferarray.buffer, (int)length * numchannels);
+
+ +
+

Not supported for JavaScript.

+
+

See Also: FMOD_DSP_DESCRIPTION

+

FMOD_DSP_CREATE_CALLBACK

+

DSP create callback.

+

This callback is called when you create a DSP unit instance of this type.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
FMOD_RESULT F_CALL FMOD_DSP_CREATE_CALLBACK(
+  FMOD_DSP_STATE *dsp_state
+);
+
+ +
delegate RESULT DSP_CREATE_CALLBACK(
+    ref DSP_STATE dsp_state
+);
+
+ +
function FMOD_DSP_CREATE_CALLBACK(
+    dsp_state
+)
+
+ +
+
dsp_state
+
DSP plug-in state. (FMOD_DSP_STATE)
+
+

Invoked by:

+ +

Implementation Detail:

+

This callback is typically where memory is allocated and DSP specific variables are initialized.

+

If a user re-uses a DSP unit instead of releasing it and creating a new one, it may be useful to implement FMOD_DSP_RESET_CALLBACK to reset any variables or buffers when the user calls DSP::reset.

+

See Also: FMOD_DSP_DESCRIPTION, System::createDSP, System::createDSPByType, System::createDSPByPlugin, FMOD_DSP_RESET_CALLBACK, FMOD_DSP_RELEASE_CALLBACK

+

FMOD_DSP_DESCRIPTION

+

DSP description.

+

This description structure allows you to define all functionality required for a DSP unit when writing a DSP plug-in.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
typedef struct FMOD_DSP_DESCRIPTION {
+  unsigned int                          pluginsdkversion;
+  char                                  name[32];
+  unsigned int                          version;
+  int                                   numinputbuffers;
+  int                                   numoutputbuffers;
+  FMOD_DSP_CREATE_CALLBACK              create;
+  FMOD_DSP_RELEASE_CALLBACK             release;
+  FMOD_DSP_RESET_CALLBACK               reset;
+  FMOD_DSP_READ_CALLBACK                read;
+  FMOD_DSP_PROCESS_CALLBACK             process;
+  FMOD_DSP_SETPOSITION_CALLBACK         setposition;
+  int                                   numparameters;
+  FMOD_DSP_PARAMETER_DESC             **paramdesc;
+  FMOD_DSP_SETPARAM_FLOAT_CALLBACK      setparameterfloat;
+  FMOD_DSP_SETPARAM_INT_CALLBACK        setparameterint;
+  FMOD_DSP_SETPARAM_BOOL_CALLBACK       setparameterbool;
+  FMOD_DSP_SETPARAM_DATA_CALLBACK       setparameterdata;
+  FMOD_DSP_GETPARAM_FLOAT_CALLBACK      getparameterfloat;
+  FMOD_DSP_GETPARAM_INT_CALLBACK        getparameterint;
+  FMOD_DSP_GETPARAM_BOOL_CALLBACK       getparameterbool;
+  FMOD_DSP_GETPARAM_DATA_CALLBACK       getparameterdata;
+  FMOD_DSP_SHOULDIPROCESS_CALLBACK      shouldiprocess;
+  void                                 *userdata;
+  FMOD_DSP_SYSTEM_REGISTER_CALLBACK     sys_register;
+  FMOD_DSP_SYSTEM_DEREGISTER_CALLBACK   sys_deregister;
+  FMOD_DSP_SYSTEM_MIX_CALLBACK          sys_mix;
+} FMOD_DSP_DESCRIPTION;
+
+ +
struct DSP_DESCRIPTION
+{
+  uint                           pluginsdkversion;
+  char[]                         name;
+  uint                           version;
+  int                            numinputbuffers;
+  int                            numoutputbuffers;
+  DSP_CREATE_CALLBACK            create;
+  DSP_RELEASE_CALLBACK           release;
+  DSP_RESET_CALLBACK             reset;
+  DSP_READ_CALLBACK              read;
+  DSP_PROCESS_CALLBACK           process;
+  DSP_SETPOSITION_CALLBACK       setposition;
+  int                            numparameters;
+  IntPtr                         paramdesc;
+  DSP_SETPARAM_FLOAT_CALLBACK    setparameterfloat;
+  DSP_SETPARAM_INT_CALLBACK      setparameterint;
+  DSP_SETPARAM_BOOL_CALLBACK     setparameterbool;
+  DSP_SETPARAM_DATA_CALLBACK     setparameterdata;
+  DSP_GETPARAM_FLOAT_CALLBACK    getparameterfloat;
+  DSP_GETPARAM_INT_CALLBACK      getparameterint;
+  DSP_GETPARAM_BOOL_CALLBACK     getparameterbool;
+  DSP_GETPARAM_DATA_CALLBACK     getparameterdata;
+  DSP_SHOULDIPROCESS_CALLBACK    shouldiprocess;
+  IntPtr                         userdata;
+  DSP_SYSTEM_REGISTER_CALLBACK   sys_register;
+  DSP_SYSTEM_DEREGISTER_CALLBACK sys_deregister;
+  DSP_SYSTEM_MIX_CALLBACK        sys_mix;
+}
+
+ +
FMOD_DSP_DESCRIPTION
+{
+  pluginsdkversion,
+  name,
+  version,
+  numinputbuffers,
+  numoutputbuffers,
+  create,
+  release,
+  reset,
+  read,
+  process,
+  setposition,
+  numparameters,
+  paramdesc,
+  setparameterfloat,
+  setparameterint,
+  setparameterbool,
+  setparameterdata,
+  getparameterfloat,
+  getparameterint,
+  getparameterbool,
+  getparameterdata,
+  shouldiprocess,
+  userdata,
+  sys_register,
+  sys_deregister,
+  sys_mix,
+};
+
+ +
+
pluginsdkversion
+
The plug-in SDK version this plug-in is built for. Set this to FMOD_PLUGIN_SDK_VERSION.
+
name Opt
+
DSP name. (UTF-8 string)
+
version Opt
+
Plug-in's version number.
+
numinputbuffers
+
Number of input FMOD_DSP_BUFFER_ARRAYs to process. Use 0 for DSPs that only generate sound and 1 for effects that process incoming sound.
+
numoutputbuffers
+
Number of audio output FMOD_DSP_BUFFER_ARRAYs. Only one output buffer is currently supported.
+
create Opt
+
Callback to initialize any required resources when the unit is created. (FMOD_DSP_CREATE_CALLBACK)
+
release Opt
+
Callback to perform any required cleanup just before the unit is freed. (FMOD_DSP_RELEASE_CALLBACK)
+
reset Opt
+
Callback to perform any required state resetting on the unit, such as history buffers for a filter to avoid clicks or artifacts. (FMOD_DSP_RESET_CALLBACK)
+
read Opt
+
Callback to retrieve audio data from the unit. An alternative to the process callback. Use in conjunction with shouldiprocess to determine whether read should continue to be called. (FMOD_DSP_READ_CALLBACK)
+
process Opt
+
Callback to retrieve audio data from the unit. Can be specified instead of the read callback if any channel format changes occur between input and output. This also replaces shouldiprocess and should return an error if the effect is to be bypassed. (FMOD_DSP_PROCESS_CALLBACK)
+
setposition Opt
+
Callback to change the unit's internal position info without processing data, or to reset a cursor position internally if reading data from a certain source. This is called when Channel::setPosition is called on a Channel created with System::playDSP. (FMOD_DSP_SETPOSITION_CALLBACK)
+
numparameters Opt
+
Number of parameters in the paramdesc array. The user finds this with DSP::getNumParameters
+
paramdesc Opt
+
Pointer to an array of FMOD_DSP_PARAMETER_DESC defining the parameters used by this filter. (FMOD_DSP_PARAMETER_DESC)
+
setparameterfloat Opt
+
Callback to update a floating point parameter value on the unit. (FMOD_DSP_SETPARAM_FLOAT_CALLBACK)
+
setparameterint Opt
+
Callback to update an integer parameter value on the unit. (FMOD_DSP_SETPARAM_INT_CALLBACK)
+
setparameterbool Opt
+
Callback to update a boolean parameter value on the unit. (FMOD_DSP_SETPARAM_BOOL_CALLBACK)
+
setparameterdata Opt
+
Callback to update a data parameter value on the unit. (FMOD_DSP_SETPARAM_DATA_CALLBACK)
+
getparameterfloat Opt
+
Callback to retrieve a floating point parameter value from the unit. (FMOD_DSP_GETPARAM_FLOAT_CALLBACK)
+
getparameterint Opt
+
Callback to retrieve an integer parameter value from the unit. (FMOD_DSP_GETPARAM_INT_CALLBACK)
+
getparameterbool Opt
+
Callback to retrieve a boolean parameter value from the unit. (FMOD_DSP_GETPARAM_BOOL_CALLBACK)
+
getparameterdata Opt
+
Callback to retrieve a data parameter value from the unit. (FMOD_DSP_GETPARAM_DATA_CALLBACK)
+
shouldiprocess Opt
+
Callback to determine whether read should continue to be called. You can detect if inputs are idle and return FMOD_OK to process or any other error code to avoid processing the effect. Use a countdown timer to allow effect tails to process before idling. If process is used instead, then read and shouldiprocess are not necessary. (FMOD_DSP_SHOULDIPROCESS_CALLBACK)
+
userdata Opt
+
User data stored by assignment to this property is shared by all newly created DSP instances constructed from this DSP description and can be accessed using FMOD_DSP_GETUSERDATA_FUNC.
+
sys_register Opt
+
Callback to perform any 'global'/per System object initialization for the plug-in. This is called when a DSP plug-in is registered with System::registerDSP. (FMOD_DSP_SYSTEM_REGISTER_CALLBACK)
+
sys_deregister Opt
+
Callback to perform any 'global'/per System object shutdown for the plug-in. This is called when a DSP plug-in is unloaded with System::unloadPlugin or during system shutdown with System::close. (FMOD_DSP_SYSTEM_DEREGISTER_CALLBACK)
+
sys_mix Opt
+
Callback to perform any 'global'/per System object update calls each mix for the plug-in. This is called when the mixer starts to execute or is just finishing executing. (FMOD_DSP_SYSTEM_MIX_CALLBACK)
+
+

There are 2 different ways to change a parameter in this architecture.

+

One is to use DSP::setParameterFloat / DSP::setParameterInt / DSP::setParameterBool / DSP::setParameterData. This is platform independent and is dynamic, so new unknown plug-ins can have their parameters enumerated and used.

+

The other is to use DSP::showConfigDialog. This is platform specific and requires a GUI, and will display a dialog box to configure the plug-in.

+

Implementation Detail:

+

All function pointers assigned to callbacks must remain valid until the plug-in is unloaded with System::unloadPlugin.

+

The name is stored as a UTF8 string. You can assign the plug-in's name in like so:

+
FMOD_DSP_DESCRIPTION desc = {};
+strncpy(desc.name, "My DSP", sizeof(desc.name));
+
+ +
FMOD.DSP_DESCRIPTION desc = new FMOD.DSP_DESCRIPTION();
+desc.name = System.Text.Encoding.UTF8.GetBytes("My DSP");
+
+ +
var desc = FMOD.DSP_DESCRIPTION();
+desc.name = "My DSP";
+
+ +

See Also: System::createDSP, DSP::setParameterFloat, DSP::setParameterInt, DSP::setParameterBool, DSP::setParameterData, FMOD_DSP_STATE, FMOD_DSP_CREATE_CALLBACK, FMOD_DSP_RELEASE_CALLBACK, FMOD_DSP_RESET_CALLBACK, FMOD_DSP_READ_CALLBACK, FMOD_DSP_PROCESS_CALLBACK, FMOD_DSP_SETPOSITION_CALLBACK, FMOD_DSP_PARAMETER_DESC, FMOD_DSP_SETPARAM_FLOAT_CALLBACK, FMOD_DSP_SETPARAM_INT_CALLBACK, FMOD_DSP_SETPARAM_BOOL_CALLBACK, FMOD_DSP_SETPARAM_DATA_CALLBACK, FMOD_DSP_GETPARAM_FLOAT_CALLBACK, FMOD_DSP_GETPARAM_INT_CALLBACK, FMOD_DSP_GETPARAM_BOOL_CALLBACK, FMOD_DSP_GETPARAM_DATA_CALLBACK, FMOD_DSP_SHOULDIPROCESS_CALLBACK, FMOD_DSP_SYSTEM_REGISTER_CALLBACK, FMOD_DSP_SYSTEM_DEREGISTER_CALLBACK, FMOD_DSP_SYSTEM_MIX_CALLBACK

+

FMOD_DSP_DFT_FFTREAL_FUNC

+

Function for performing an FFT on a real signal.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
FMOD_RESULT F_CALL FMOD_DSP_DFT_FFTREAL_FUNC(
+    FMOD_DSP_STATE *dsp_state,
+    int size,
+    const float *signal,
+    FMOD_COMPLEX* dft,
+    const float *window,
+    int signalhop
+);
+
+ +
delegate RESULT DSP_DFT_FFTREAL_FUNC(
+    ref DSP_STATE dsp_state,
+    int size,
+    IntPtr signal,
+    IntPtr dft,
+    IntPtr window,
+    int signalhop
+);
+
+ +
+

Not supported for JavaScript.

+
+
+
dsp_state
+
DSP plug-in state. (FMOD_DSP_STATE)
+
size
+
+

The length of the signal frame.

+
    +
  • Units: Samples
  • +
+
+
signal
+
+

Input signal frame to perform DFT on.

+
    +
  • Units: PCM
  • +
  • Range: [-1.0, +1.0]
  • +
+
+
dft Out
+
+

The output DFT result. (FMOD_COMPLEX)

+ +
+
window Opt
+
+

Window buffer for smoothing input signal prior to analysis. Must be the same length as the input signal. Example window types can be found in FMOD_DSP_FFT_WINDOW.

+
    +
  • Range: [0.0, 1.0]
  • +
+
+
signalhop Opt
+
+

The number of samples between signal frames.

+
    +
  • Units: Samples
  • +
+
+
+

Implementation Detail:

+

Calling this function will append an FMOD_DSP_FFT effect to the DSP's output if there isn't one already.

+

See Also: FMOD_DSP_STATE, FMOD_DSP_DFT_IFFTREAL_FUNC, FFT

+

FMOD_DSP_DFT_IFFTREAL_FUNC

+

Function for performing an inverse FFT to get a real signal.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
FMOD_RESULT F_CALL FMOD_DSP_DFT_IFFTREAL_FUNC(
+    FMOD_DSP_STATE *dsp_state,
+    int size,
+    const FMOD_COMPLEX *dft,
+    float* signal,
+    const float *window,
+    int signalhop
+);
+
+ +
delegate RESULT DSP_DFT_IFFTREAL_FUNC(
+    ref DSP_STATE dsp_state,
+    int size,
+    IntPtr dft,
+    IntPtr signal,
+    IntPtr window,
+    int signalhop
+);
+
+ +
+

Not supported for JavaScript.

+
+
+
dsp_state
+
DSP plug-in state. (FMOD_DSP_STATE)
+
size
+
+

The length of the signal frame.

+
    +
  • Units: Samples
  • +
+
+
dft
+
+

The previous input DFT result calculated from FMOD_DSP_DFT_FFTREAL_FUNC. (FMOD_COMPLEX)

+ +
+
signal Out
+
+

Output signal to perform IFFT on.

+
    +
  • Units: PCM
  • +
  • Range: [-1.0, +1.0]
  • +
+
+
window Opt
+
+

Window buffer for smoothing input signal prior to analysis. Must be the same length as the input signal. Example window types can be found in FMOD_DSP_FFT_WINDOW.

+
    +
  • Range: [0.0, 1.0]
  • +
+
+
signalhop Opt
+
+

The number of samples between signal frames.

+
    +
  • Units: Samples
  • +
+
+
+

Implementation Detail:

+

Calling this function will append an FMOD_DSP_FFT effect to the DSP's output if there isn't one already.

+

See Also: FMOD_DSP_STATE, FMOD_DSP_DFT_FFTREAL_FUNC

+

FMOD_DSP_FREE_FUNC

+

Function to free memory allocated with FMOD_DSP_ALLOC_FUNC.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
void F_CALL FMOD_DSP_FREE_FUNC(
+    void *ptr,
+    FMOD_MEMORY_TYPE type,
+    const char *sourcestr
+);
+
+ +
delegate IntPtr DSP_FREE_FUNC(
+    IntPtr ptr,
+    MEMORY_TYPE type,
+    IntPtr sourcestr
+);
+
+ +
+

Not supported for JavaScript.

+
+
+
ptr
+
Pointer to memory location to free.
+
type
+
Memory allocation type. (FMOD_MEMORY_TYPE)
+
sourcestr
+
String with the FMOD source code filename and line number in it. Only valid in logging versions of FMOD. (UTF-8 string)
+
+
+

The 'sourcestr' argument can be used via StringWrapper by using FMOD.StringWrapper sourceStr = new FMOD.StringWrapper(sourcestr);

+
+

Implementation Detail:

+

This function is a wrapper used by the system level allocator and can be called from any DSP instance.

+

See Also: FMOD_DSP_STATE, FMOD_DSP_ALLOC_FUNC, FMOD_DSP_REALLOC_FUNC

+

FMOD_DSP_GETBLOCKSIZE_FUNC

+

Function to query the number of samples the mixer will process each mix.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
FMOD_RESULT F_CALL FMOD_DSP_GETBLOCKSIZE_FUNC(
+    FMOD_DSP_STATE *dsp_state,
+    unsigned int *blocksize
+);
+
+ +
delegate RESULT DSP_GETBLOCKSIZE_FUNC(
+    ref DSP_STATE dsp_state,
+    ref uint blocksize
+);
+
+ +
FMOD_DSP_GETBLOCKSIZE_FUNC(
+    dsp_state,
+    blocksize
+)
+
+ +
+
dsp_state
+
DSP plug-in state. (FMOD_DSP_STATE)
+
blocksize Out
+
+

Maximum number of decompressed PCM samples the DSP unit can handle.

+
    +
  • Units: Samples
  • +
+
+
+

Implementation Detail:

+

DSPs are requested to process blocks of varying length up to this size.

+

See Also: FMOD_DSP_STATE, System::getDSPBufferSize

+

FMOD_DSP_GETCLOCK_FUNC

+

Function to get the clock of the current DSP, as well as the subset of the input buffer that contains the signal.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
FMOD_RESULT F_CALL FMOD_DSP_GETCLOCK_FUNC(
+    FMOD_DSP_STATE *dsp_state,
+    unsigned long long *clock,
+    unsigned int *offset,
+    unsigned int *length
+);
+
+ +
delegate RESULT DSP_GETCLOCK_FUNC(
+    ref DSP_STATE dsp_state,
+    out ulong clock,
+    out uint offset,
+    out uint length
+);
+
+ +
+

Not supported for JavaScript.

+
+
+
dsp_state
+
DSP plug-in state. (FMOD_DSP_STATE)
+
clock OutOpt
+
+

DSP clock value for the DSP node.

+
    +
  • Units: Samples
  • +
+
+
offset OutOpt
+
+

The start offset of the audio data inside the input buffer.

+
    +
  • Units: Samples
  • +
+
+
length OutOpt
+
+

The length of the audio data inside the input buffer.

+
    +
  • Units: Samples
  • +
+
+
+

Implementation Detail:

+

FMOD mix blocks are block aligned, so when a delay such as ChannelControl::setDelay is used the audio may start and end part way through the buffer. The offset is where the audio starts inside the buffer, and the length is how long after the offset the audio continues for.

+

See Also: FMOD_DSP_STATE

+

FMOD_DSP_GETLISTENERATTRIBUTES_FUNC

+

Callback for getting the absolute listener attributes set via the API.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
FMOD_RESULT F_CALL FMOD_DSP_GETLISTENERATTRIBUTES_FUNC(
+    FMOD_DSP_STATE *dsp_state,
+    int *numlisteners,
+    FMOD_3D_ATTRIBUTES *attributes
+);
+
+ +
delegate RESULT DSP_GETLISTENERATTRIBUTES_FUNC(
+    ref DSP_STATE dsp_state,
+    ref int numlisteners,
+    IntPtr attributes
+);
+
+ +
+

Not supported for JavaScript.

+
+
+
dsp_state
+
DSP plug-in state. (FMOD_DSP_STATE)
+
numlisteners OutOpt
+
The number of listeners.
+
attributes OutOpt
+
An array of 3D attributes corresponding to each listener. (FMOD_3D_ATTRIBUTES)
+
+

Implementation Detail:

+

Returned as left-handed coordinates.

+

See Also: FMOD_DSP_STATE

+

FMOD_DSP_GETPARAM_BOOL_CALLBACK

+

Get boolean parameter callback.

+

This callback is called when the user wants to get a boolean parameter value from a DSP unit.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
FMOD_RESULT F_CALL FMOD_DSP_GETPARAM_BOOL_CALLBACK(
+  FMOD_DSP_STATE *dsp_state,
+  int index,
+  FMOD_BOOL *value,
+  char *valuestr
+);
+
+ +
delegate RESULT DSP_GETPARAM_BOOL_CALLBACK
+(
+  ref DSP_STATE dsp_state,
+  int index,
+  ref bool value,
+  IntPtr valuestr
+);
+
+ +
function FMOD_DSP_GETPARAM_BOOL_CALLBACK(
+    dsp_state,
+    index,
+    value,
+    valuestr
+)
+
+ +
+
dsp_state
+
DSP Plug-in state. (FMOD_DSP_STATE)
+
index
+
Parameter index.
+
value Out
+
+

Parameter value.

+
    +
  • Units: Boolean
  • +
+
+
valuestr OutOpt
+
String value of the parameter. Can be used to display an alternate representation of the number. For example "ON" or "OFF" instead of 1.0 and 0.0. The length of the buffer being passed in is always a maximum of FMOD_DSP_GETPARAM_VALUESTR_LENGTH bytes. (UTF-8 string)
+
+

Invoked by:

+
    +
  • User Thread. Triggered by user calling DSP::getParameterBool. Parameter getters are not thread safe and you will need to handle synchronization between parameter getters and any other callbacks that access those parameters, i.e FMOD_DSP_PROCESS_CALLBACK.
  • +
+
+

The 'valuestr' argument can be used via StringWrapper by using FMOD.StringWrapper valueStr = new FMOD.StringWrapper(valuestr);

+
+

See Also: FMOD_DSP_DESCRIPTION, FMOD_DSP_SETPARAM_BOOL_CALLBACK

+

FMOD_DSP_GETPARAM_DATA_CALLBACK

+

Get data parameter callback.

+

This callback is called when the user wants to get a data parameter value from a DSP unit.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
FMOD_RESULT F_CALL FMOD_DSP_GETPARAM_DATA_CALLBACK(
+  FMOD_DSP_STATE *dsp_state,
+  int index,
+  void **data,
+  unsigned int *length,
+  char *valuestr
+);
+
+ +
delegate RESULT DSP_GETPARAM_DATA_CALLBACK
+(
+  ref DSP_STATE dsp_state,
+  int index,
+  IntPtr data,
+  ref uint length,
+  IntPtr valuestr
+);
+
+ +
function FMOD_DSP_GETPARAM_DATA_CALLBACK(
+    dsp_state,
+    index,
+    data,
+    length,
+    valuestr
+)
+
+ +
+
dsp_state
+
DSP plug-in state. (FMOD_DSP_STATE)
+
index
+
Parameter index.
+
data Out
+
Parameter data.
+
length Out
+
Length of data.
+
valuestr OutOpt
+
String value of the parameter. Can be used to display an alternate representation of the number. For example "ON" or "OFF" instead of values values inside the binary data. The length of the buffer being passed in is always a maximum of FMOD_DSP_GETPARAM_VALUESTR_LENGTH bytes. (UTF-8 string)
+
+

Invoked by:

+ +
+

The 'valuestr' argument can be used via StringWrapper by using FMOD.StringWrapper valueStr = new FMOD.StringWrapper(valuestr);

+
+

See Also: DSP::setParameterData, FMOD_DSP_DESCRIPTION, FMOD_DSP_SETPARAM_DATA_CALLBACK

+

FMOD_DSP_GETPARAM_FLOAT_CALLBACK

+

Get float parameter callback.

+

This callback is called when the user wants to get a floating point parameter value from a DSP unit.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
FMOD_RESULT F_CALL FMOD_DSP_GETPARAM_FLOAT_CALLBACK(
+  FMOD_DSP_STATE *dsp_state,
+  int index,
+  float *value,
+  char *valuestr
+);
+
+ +
delegate RESULT DSP_GETPARAM_FLOAT_CALLBACK
+(
+  ref DSP_STATE dsp_state,
+  int index,
+  ref float value,
+  IntPtr valuestr
+);
+
+ +
function FMOD_DSP_GETPARAM_FLOAT_CALLBACK(
+    dsp_state,
+    index,
+    value,
+    valuestr
+)
+
+ +
+
dsp_state
+
DSP plug-in state. (FMOD_DSP_STATE)
+
index
+
Parameter index.
+
value Out
+
Parameter value.
+
valuestr OutOpt
+
String value of the parameter. Can be used to display an alternate representation of the number. For example "ON" or "OFF" instead of 1.0 and 0.0. The length of the buffer being passed in is always a maximum of FMOD_DSP_GETPARAM_VALUESTR_LENGTH bytes. (UTF-8 string)
+
+

Invoked by:

+
    +
  • User Thread. Triggered by user calling DSP::getParameterFloat. Parameter getters are not thread safe and you will need to handle synchronization between parameter getters and any other callbacks that access those parameters, i.e FMOD_DSP_PROCESS_CALLBACK.
  • +
+
+

The 'valuestr' argument can be used via StringWrapper by using FMOD.StringWrapper valueStr = new FMOD.StringWrapper(valuestr);

+
+

See Also: FMOD_DSP_DESCRIPTION, FMOD_DSP_SETPARAM_FLOAT_CALLBACK

+

FMOD_DSP_GETPARAM_INT_CALLBACK

+

Get integer parameter callback.

+

This callback is called when the user wants to get an integer parameter value from a DSP unit.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
FMOD_RESULT F_CALL FMOD_DSP_GETPARAM_INT_CALLBACK(
+  FMOD_DSP_STATE *dsp_state,
+  int index,
+  int *value,
+  char *valuestr
+);
+
+ +
delegate RESULT DSP_GETPARAM_INT_CALLBACK
+(
+  ref DSP_STATE dsp_state,
+  int index,
+  ref int value,
+  IntPtr valuestr
+);
+
+ +
function FMOD_DSP_GETPARAM_INT_CALLBACK(
+    dsp_state,
+    index,
+    value,
+    valuestr
+)
+
+ +
+
dsp_state
+
DSP plug-in state. (FMOD_DSP_STATE)
+
index
+
Parameter index.
+
value Out
+
Parameter value.
+
valuestr OutOpt
+
String value of the parameter. Can be used to display an alternate representation of the number. For example "ON" or "OFF" instead of 1 and 0. The length of the buffer being passed in is always a maximum of FMOD_DSP_GETPARAM_VALUESTR_LENGTH bytes.
+
+

Invoked by:

+
    +
  • User Thread. Triggered by user calling DSP::getParameterInt. Parameter getters are not thread safe and you will need to handle synchronization between parameter getters and any other callbacks that access those parameters, i.e FMOD_DSP_PROCESS_CALLBACK.
  • +
+
+

The 'valuestr' argument can be used via StringWrapper by using FMOD.StringWrapper valueStr = new FMOD.StringWrapper(valuestr);

+
+

See Also: DSP::setParameterInt, FMOD_DSP_DESCRIPTION, FMOD_DSP_SETPARAM_INT_CALLBACK

+

FMOD_DSP_GETPARAM_VALUESTR_LENGTH

+

Length in bytes of the buffer pointed to by the valuestr argument of FMOD_DSP_GETPARAM_XXXX_CALLBACK functions.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
#define FMOD_DSP_GETPARAM_VALUESTR_LENGTH   32
+
+ +
FMOD.DSP_GETPARAM_VALUESTR_LENGTH = 32
+
+ +
+

Currently not supported for C#.

+
+

See Also: FMOD_DSP_GETPARAM_FLOAT_CALLBACK, FMOD_DSP_GETPARAM_INT_CALLBACK, FMOD_DSP_GETPARAM_BOOL_CALLBACK, FMOD_DSP_GETPARAM_DATA_CALLBACK

+

FMOD_DSP_GETSAMPLERATE_FUNC

+

Function to query the system sample rate.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
FMOD_RESULT F_CALL FMOD_DSP_GETSAMPLERATE_FUNC(
+    FMOD_DSP_STATE *dsp_state,
+    int *rate
+);
+
+ +
delegate RESULT DSP_GETSAMPLERATE_FUNC(
+    ref DSP_STATE dsp_state,
+    ref int rate
+);
+
+ +
FMOD_DSP_GETSAMPLERATE_FUNC(
+    dsp_state,
+    rate
+)
+
+ +
+
dsp_state
+
DSP plug-in state. (FMOD_DSP_STATE)
+
rate OutOpt
+
+

The system sample rate.

+
    +
  • Units: Hertz
  • +
+
+
+

See Also: FMOD_DSP_STATE

+

FMOD_DSP_GETSPEAKERMODE_FUNC

+

Function to query the system speaker modes.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
FMOD_RESULT F_CALL FMOD_DSP_GETSPEAKERMODE_FUNC(
+    FMOD_DSP_STATE *dsp_state,
+    FMOD_SPEAKERMODE *speakermode_mixer,
+    FMOD_SPEAKERMODE *speakermode_output
+);
+
+ +
delegate RESULT DSP_GETSPEAKERMODE_FUNC(
+    ref DSP_STATE dsp_state,
+    ref int speakermode_mixer,
+    ref int speakermode_output
+);
+
+ +
FMOD_DSP_GETSPEAKERMODE_FUNC(
+    dsp_state,
+    speakermode_mixer,
+    speakermode_output
+)
+
+ +
+
dsp_state
+
DSP plug-in state. (FMOD_DSP_STATE)
+
speakermode_mixer OutOpt
+
The default speaker mode of the System. (FMOD_SPEAKERMODE)
+
speakermode_output OutOpt
+
The output device speaker mode. (FMOD_SPEAKERMODE)
+
+

Implementation detail:

+

If speakermode_mixer and speakermode_output are different then the System is downmixing or upmixing to the speakermode_output format.

+

See Also: FMOD_DSP_STATE, Upmix/Downmix Behavior

+

FMOD_DSP_GETUSERDATA_FUNC

+

Function to get the user data attached to this DSP.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
FMOD_RESULT F_CALL FMOD_DSP_GETUSERDATA_FUNC(
+    FMOD_DSP_STATE *dsp_state,
+    void **userdata
+);
+
+ +
delegate RESULT DSP_GETUSERDATA_FUNC(
+    ref DSP_STATE dsp_state,
+    out IntPtr userdata
+);
+
+ +
+

Not supported for JavaScript.

+
+
+
dsp_state
+
DSP plug-in state. (FMOD_DSP_STATE)
+
userdata Out
+
User data set by calling DSP::setUserData or assignment via FMOD_DSP_DESCRIPTION::userdata.
+
+

See Also: FMOD_DSP_STATE

+

FMOD_DSP_LOG_FUNC

+

Function to write to the FMOD logging system.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
void F_CALL FMOD_DSP_LOG_FUNC(
+    FMOD_DEBUG_FLAGS level,
+    const char *file,
+    int line,
+    const char *function,
+    const char *str,
+    ...
+);
+
+ +
delegate void DSP_LOG_FUNC(
+    DEBUG_FLAGS level,
+    IntPtr file,
+    int line,
+    IntPtr function,
+    IntPtr str
+);
+
+ +
+

Not supported for JavaScript.

+
+
+
level
+
Log type or level. (FMOD_DEBUG_FLAGS)
+
file
+
Source code file name from where the log is called. (UTF-8 string)
+
line
+
Line number in the source code file the function is being called from.
+
function
+
Name of the logging function. (UTF-8 string)
+
str
+
String to log. (UTF-8 string)
+
+

See Also: FMOD_DSP_STATE

+

FMOD_DSP_METERING_INFO

+

DSP metering info.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
typedef struct FMOD_DSP_METERING_INFO {
+  int     numsamples;
+  float   peaklevel[32];
+  float   rmslevel[32];
+  short   numchannels;
+} FMOD_DSP_METERING_INFO;
+
+ +
struct DSP_METERING_INFO
+{
+  int     numsamples;
+  float[] peaklevel;
+  float[] rmslevel;
+  short   numchannels;
+}
+
+ +
FMOD_DSP_METERING_INFO
+{
+  numsamples,
+  peaklevel,
+  rmslevel,
+  numchannels,
+};
+
+ +
+
numsamples R/O
+
Number of samples considered for this metering info.
+
peaklevel R/O
+
+

Peak level per channel.

+
    +
  • Units: Linear
  • +
+
+
rmslevel R/O
+
+

Rms level per channel.

+
    +
  • Units: Linear
  • +
+
+
numchannels R/O
+
Number of channels.
+
+

See Also: FMOD_SPEAKER, DSP::getMeteringInfo

+

FMOD_DSP_PAN_GETROLLOFFGAIN_FUNC

+

Function to calculate distance attenuation.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
FMOD_RESULT F_CALL FMOD_DSP_PAN_GETROLLOFFGAIN_FUNC(
+    FMOD_DSP_STATE *dsp_state,
+    FMOD_DSP_PAN_3D_ROLLOFF_TYPE rolloff,
+    float distance,
+    float mindistance,
+    float maxdistance,
+    float *gain
+);
+
+ +
delegate RESULT DSP_PAN_GETROLLOFFGAIN_FUNC(
+    ref DSP_STATE dsp_state,
+    DSP_PAN_3D_ROLLOFF_TYPE rolloff,
+    float distance,
+    float mindistance,
+    float maxdistance,
+    out float gain
+);
+
+ +
+

Not supported for JavaScript.

+
+
+
dsp_state
+
DSP plug-in state. (FMOD_DSP_STATE)
+
rolloff
+
Rolloff type to apply to distance attenuation calculation. (FMOD_DSP_PAN_3D_ROLLOFF_TYPE)
+
distance
+
+

The distance from the DSP's position.

+ +
+
mindistance
+
+

Distance from the source where attenuation begins.

+ +
+
maxdistance
+
+

Distance from the source where attenuation ends.

+ +
+
gain Out
+
+

Gain modifier applied to signal at provided distance.

+
    +
  • Units: Linear
  • +
+
+
+

See Also: FMOD_DSP_STATE

+

FMOD_DSP_PAN_SUMMONOMATRIX_FUNC

+

Function to calculate a mix matrix that downmixes the source speaker mode to mono.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
FMOD_RESULT F_CALL FMOD_DSP_PAN_SUMMONOMATRIX_FUNC(
+    FMOD_DSP_STATE *dsp_state,
+    FMOD_SPEAKERMODE sourceSpeakerMode,
+    float lowFrequencyGain,
+    float overallGain,
+    float *matrix
+);
+
+ +
delegate RESULT DSP_PAN_SUMMONOMATRIX_FUNC(
+    ref DSP_STATE dsp_state,
+    int sourceSpeakerMode,
+    float lowFrequencyGain,
+    float overallGain,
+    IntPtr matrix
+);
+
+ +
+

Not supported for JavaScript.

+
+
+
dsp_state
+
DSP plug-in state. (FMOD_DSP_STATE)
+
sourceSpeakerMode
+
The input speaker mode of to create a mono mix matrix for. (FMOD_SPEAKERMODE)
+
lowFrequencyGain
+
+

Gain modifier to apply just to the LFE channel.

+
    +
  • Units: Linear
  • +
+
+
overallGain
+
+

Gain modifier to apply to each channel, including the LFE channel.

+
    +
  • Units: Linear
  • +
+
+
matrix Out
+
Calculated mono mix matrix based on the given parameters.
+
+

See Also: FMOD_DSP_STATE, System::getSpeakerModeChannels, ChannelControl::setMixMatrix, Upmix/Downmix Behavior

+

FMOD_DSP_PAN_SUMMONOTOSURROUNDMATRIX_FUNC

+

Function to calculate a mix matrix that upmixes from mono to the target speaker mode.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
FMOD_RESULT F_CALL FMOD_DSP_PAN_SUMMONOTOSURROUNDMATRIX_FUNC(
+    FMOD_DSP_STATE *dsp_state,
+    FMOD_SPEAKERMODE targetSpeakerMode,
+    float direction,
+    float extent,
+    float lowFrequencyGain,
+    float overallGain,
+    int matrixHop,
+    float *matrix
+);
+
+ +
delegate RESULT DSP_PAN_SUMMONOTOSURROUNDMATRIX_FUNC(
+    ref DSP_STATE dsp_state,
+    int targetSpeakerMode,
+    float direction,
+    float extent,
+    float lowFrequencyGain,
+    float overallGain,
+    int matrixHop,
+    IntPtr matrix
+);
+
+ +
+

Not supported for JavaScript.

+
+
+
dsp_state
+
DSP plug-in state. (FMOD_DSP_STATE)
+
targetSpeakerMode
+
The output speaker mode to create a mix matrix for. (FMOD_SPEAKERMODE)
+
direction
+
+

Angle from center point of panning circle where 0 is front center and -180 or +180 is rear speakers center point.

+
    +
  • Units: Degrees
  • +
  • Range: [-180, 180]
  • +
+
+
extent
+
+

The amount the signal will be spread across the panning circle relative to direction, where 0 is not at all and 360 is spread between all speakers.

+
    +
  • Units: Degrees
  • +
  • Range: [0, 360]
  • +
+
+
lowFrequencyGain
+
+

Gain modifier to apply just to the LFE channel.

+
    +
  • Units: Linear
  • +
+
+
overallGain
+
+

Gain modifier to apply to each channel, including the LFE channel.

+
    +
  • Units: Linear
  • +
+
+
matrixHop
+
+

The number of source channels in the matrix.

+ +
+
matrix Out
+
Calculated surround mix matrix based on the given parameters.
+
+

See Also: FMOD_DSP_STATE, ChannelControl::setMixMatrix, Upmix/Downmix Behavior

+

FMOD_DSP_PAN_SUMSTEREOMATRIX_FUNC

+

Function to calculate a mix matrix that downmixes from the source speaker mode to stereo.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
FMOD_RESULT F_CALL FMOD_DSP_PAN_SUMSTEREOMATRIX_FUNC(
+    FMOD_DSP_STATE *dsp_state,
+    FMOD_SPEAKERMODE sourceSpeakerMode,
+    float pan,
+    float lowFrequencyGain,
+    float overallGain,
+    int matrixHop,
+    float *matrix
+);
+
+ +
delegate RESULT DSP_PAN_SUMSTEREOMATRIX_FUNC(
+    ref DSP_STATE dsp_state,
+    int sourceSpeakerMode,
+    float pan,
+    float lowFrequencyGain,
+    float overallGain,
+    int matrixHop,
+    IntPtr matrix
+);
+
+ +
+

Not supported for JavaScript.

+
+
+
dsp_state
+
DSP plug-in state. (FMOD_DSP_STATE)
+
sourceSpeakerMode
+
The input speaker mode to create a stereo mix matrix for. (FMOD_SPEAKERMODE)
+
pan
+
+

The amount the signal will be spread across the left and right channels, where -100 is 100% left, and 100 is 100% right.

+
    +
  • Units: Percentage
  • +
  • Range: [-100, 100]
  • +
+
+
lowFrequencyGain
+
+

Gain modifier to apply just to the LFE channel.

+
    +
  • Units: Linear
  • +
+
+
overallGain
+
+

Gain modifier to apply to each channel, including the LFE channel.

+
    +
  • Units: Linear
  • +
+
+
matrixHop
+
+

The number of source channels in the matrix.

+ +
+
matrix Out
+
Calculated stereo mix matrix based on the given parameters.
+
+

See Also: FMOD_DSP_STATE, ChannelControl::setMixMatrix, Upmix/Downmix Behavior

+

FMOD_DSP_PAN_SUMSTEREOTOSURROUNDMATRIX_FUNC

+

Function to calculate a mix matrix that upmixes from stereo to the target speaker mode.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
FMOD_RESULT F_CALL FMOD_DSP_PAN_SUMSTEREOTOSURROUNDMATRIX_FUNC(
+    FMOD_DSP_STATE *dsp_state,
+     FMOD_SPEAKERMODE targetSpeakerMode,
+     float direction,
+     float extent,
+     float rotation,
+     float lowFrequencyGain,
+     float overallGain,
+     int matrixHop,
+     float *matrix
+);
+
+ +
delegate RESULT DSP_PAN_SUMSTEREOTOSURROUNDMATRIX_FUNC(
+    ref DSP_STATE dsp_state,
+    int targetSpeakerMode,
+    float direction,
+    float extent,
+    float rotation,
+    float lowFrequencyGain,
+    float overallGain,
+    int matrixHop,
+    IntPtr matrix
+);
+
+ +
+

Not supported for JavaScript.

+
+
+
dsp_state
+
DSP plug-in state. (FMOD_DSP_STATE)
+
targetSpeakerMode
+
The target speaker mode to create a mix matrix for. (FMOD_SPEAKERMODE)
+
direction
+
+

Angle from center point of panning circle where 0 is front center and -180 or +180 is rear speakers center point.

+
    +
  • Units: Degrees
  • +
  • Range: [-180, 180]
  • +
+
+
extent
+
+

The amount the signal will be spread across the panning circle relative to direction, where 0 is not at all and 360 is spread between all speakers.

+
    +
  • Units: Degrees
  • +
  • Range: [0, 360]
  • +
+
+
rotation
+
+

The rotation of the channels from their original mapping, contained within the extent.

+
    +
  • Units: Degrees
  • +
  • Range: [-180, 180]
  • +
+
+
lowFrequencyGain
+
+

Gain modifier to apply just to the LFE channel.

+
    +
  • Units: Linear
  • +
+
+
overallGain
+
+

Gain modifier to apply to each channel, including the LFE channel.

+
    +
  • Units: Linear
  • +
+
+
matrixHop
+
+

The number of source channels in the matrix.

+ +
+
matrix Out
+
Calculated surround mix matrix based on the given parameters.
+
+

See Also: FMOD_DSP_STATE, ChannelControl::setMixMatrix

+

FMOD_DSP_PAN_SUMSURROUNDMATRIX_FUNC

+

Function to calculate a mix matrix that upmixes or downmixes from the source speaker mode to the target speaker mode.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
FMOD_RESULT F_CALL FMOD_DSP_PAN_SUMSURROUNDMATRIX_FUNC(
+    FMOD_DSP_STATE *dsp_state,
+    FMOD_SPEAKERMODE sourceSpeakerMode,
+    FMOD_SPEAKERMODE targetSpeakerMode,
+    float direction,
+    float extent,
+    float rotation,
+    float lowFrequencyGain,
+    float overallGain,
+    int matrixHop,
+    float *matrix,
+    FMOD_DSP_PAN_SURROUND_FLAGS flags
+);
+
+ +
delegate RESULT DSP_PAN_SUMSURROUNDMATRIX_FUNC(
+    ref DSP_STATE dsp_state,
+    int sourceSpeakerMode,
+    int targetSpeakerMode,
+    float direction,
+    float extent,
+    float rotation,
+    float lowFrequencyGain,
+    float overallGain,
+    int matrixHop,
+    IntPtr matrix,
+    DSP_PAN_SURROUND_FLAGS flags
+);
+
+ +
+

Not supported for JavaScript.

+
+
+
dsp_state
+
DSP plug-in state. (FMOD_DSP_STATE)
+
sourceSpeakerMode
+
The input speaker mode of the mix matrix to calculate. (FMOD_SPEAKERMODE)
+
targetSpeakerMode
+
The output speaker mode of the mix matrix to calculate. (FMOD_SPEAKERMODE)
+
direction
+
+

Angle from center point of panning circle where 0 is front center and -180 or +180 is rear speakers center point.

+
    +
  • Units: Degrees
  • +
  • Range: [-180, 180]
  • +
+
+
extent
+
+

The amount the signal will be spread across the panning circle relative to direction, where 0 is not at all and 360 is spread between all speakers.

+
    +
  • Units: Degrees
  • +
  • Range: [0, 360]
  • +
+
+
rotation
+
+

The rotation of the channels from their original mapping, contained within the extent.

+
    +
  • Units: Degrees
  • +
  • Range: [-180, 180]
  • +
+
+
lowFrequencyGain
+
+

Gain modifier to apply just to the LFE channel.

+
    +
  • Units: Linear
  • +
+
+
overallGain
+
+

Gain modifier to apply to each channel, including the LFE channel.

+
    +
  • Units: Linear
  • +
+
+
matrixHop
+
+

The number of source channels in the matrix.

+ +
+
matrix Out
+
Calculated surround mix matrix based on the given parameters.
+
+

See Also: FMOD_DSP_STATE, ChannelControl::setMixMatrix

+

FMOD_DSP_PAN_SURROUND_FLAGS

+

Flags for the FMOD_DSP_PAN_SUMSURROUNDMATRIX_FUNC function.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
typedef enum FMOD_DSP_PAN_SURROUND_FLAGS {
+  FMOD_DSP_PAN_SURROUND_DEFAULT,
+  FMOD_DSP_PAN_SURROUND_ROTATION_NOT_BIASED
+} FMOD_DSP_PAN_SURROUND_FLAGS;
+
+ +
enum DSP_PAN_SURROUND_FLAGS
+{
+  DEFAULT,
+  ROTATION_NOT_BIASED,
+}
+
+ +
DSP_PAN_SURROUND_DEFAULT
+DSP_PAN_SURROUND_ROTATION_NOT_BIASED
+
+ +
+
FMOD_DSP_PAN_SURROUND_DEFAULT
+
Output channel rotations are spread across the panning circle based on speaker positions.
+
FMOD_DSP_PAN_SURROUND_ROTATION_NOT_BIASED
+
Output channel rotations are spread evenly across the panning circle.
+
+

See Also: FMOD_DSP_STATE_PAN_FUNCTIONS

+

FMOD_DSP_PARAMETER_3DATTRIBUTES

+

3D attributes data structure.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
typedef struct FMOD_DSP_PARAMETER_3DATTRIBUTES {
+  FMOD_3D_ATTRIBUTES   relative;
+  FMOD_3D_ATTRIBUTES   absolute;
+} FMOD_DSP_PARAMETER_3DATTRIBUTES;
+
+ +
struct DSP_PARAMETER_3DATTRIBUTES
+{
+  _3D_ATTRIBUTES relative;
+  _3D_ATTRIBUTES absolute;
+}
+
+ +
FMOD_DSP_PARAMETER_3DATTRIBUTES
+{
+  relative,
+  absolute,
+}
+
+ +
+
relative
+
Position of the sound relative to the listener. (FMOD_3D_ATTRIBUTES)
+
absolute
+
Position of the sound in world coordinates. (FMOD_3D_ATTRIBUTES)
+
+

The FMOD::Studio::System sets this parameter automatically when an FMOD::Studio::EventInstance position changes. However, if you are using the core FMOD::System and not the FMOD::Studio::System, you must set this DSP parameter explicitly.

+

Attributes must use a coordinate system with the positive Y axis being up and the positive X axis being right. The FMOD Engine converts passed-in coordinates to left-handed for the plug-in if the system was initialized with the FMOD_INIT_3D_RIGHTHANDED flag.

+

When using a listener attenuation position, the direction of the relative attributes will be relative to the listener position and the length will be the distance to the attenuation position.

+

See Also: FMOD_DSP_PARAMETER_DATA_TYPE, FMOD_DSP_PARAMETER_DESC, Studio::System::setListenerAttributes, Controlling a Spatializer DSP.

+

FMOD_DSP_PARAMETER_3DATTRIBUTES_MULTI

+

3D attributes data structure for multiple listeners.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
typedef struct FMOD_DSP_PARAMETER_3DATTRIBUTES_MULTI {
+  int                  numlisteners;
+  FMOD_3D_ATTRIBUTES   relative[FMOD_MAX_LISTENERS];
+  float                weight[FMOD_MAX_LISTENERS];
+  FMOD_3D_ATTRIBUTES   absolute;
+} FMOD_DSP_PARAMETER_3DATTRIBUTES_MULTI;
+
+ +
struct DSP_PARAMETER_3DATTRIBUTES_MULTI
+{
+  int               numlisteners;
+  _3D_ATTRIBUTES[]  relative;
+  float[]           weight;
+  _3D_ATTRIBUTES    absolute;
+}
+
+ +
FMOD_DSP_PARAMETER_3DATTRIBUTES_MULTI
+{
+  numlisteners,
+};
+
+ +
+
numlisteners
+
Number of listeners.
+
relative
+
Position of the sound relative to the listeners. (FMOD_3D_ATTRIBUTES)
+
weight
+
Weighting of the listeners where 0 means listener has no contribution and 1 means full contribution.
+
absolute
+
Position of the sound in world coordinates. (FMOD_3D_ATTRIBUTES)
+
+

The FMOD::Studio::System sets this parameter automatically when an FMOD::Studio::EventInstance position changes. However, if you are using the core API's FMOD::System and not the FMOD::Studio::System, you must set this DSP parameter explicitly.

+

Attributes must use a coordinate system with the positive Y axis being up and the positive X axis being right. The FMOD Engine converts passed in coordinates to left-handed for the plug-in if the System was initialized with the FMOD_INIT_3D_RIGHTHANDED flag.

+

When using a listener attenuation position, the direction of the relative attributes will be relative to the listener position and the length will be the distance to the attenuation position.

+

See Also: FMOD_DSP_PARAMETER_DATA_TYPE, FMOD_DSP_PARAMETER_DESC, Studio::System::setListenerAttributes, Controlling a Spatializer DSP.

+

FMOD_DSP_PARAMETER_ATTENUATION_RANGE

+

Attenuation range parameter data structure.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
typedef struct FMOD_DSP_PARAMETER_ATTENUATION_RANGE {
+  float   min;
+  float   max;
+} FMOD_DSP_PARAMETER_ATTENUATION_RANGE;
+
+ +
struct DSP_PARAMETER_ATTENUATION_RANGE
+{
+  float min;
+  float max;
+}
+
+ +
FMOD_DSP_PARAMETER_ATTENUATION_RANGE
+{
+  min,
+  max,
+};
+
+ +
+
min R/O
+
Minimum distance for attenuation.
+
max R/O
+
Maximum distance for attenuation.
+
+

The FMOD::Studio::System will set this parameter automatically if an FMOD::Studio::EventInstance min or max distance changes.

+

See Also: FMOD_DSP_PARAMETER_DATA_TYPE, FMOD_DSP_PARAMETER_DESC

+

FMOD_DSP_PARAMETER_DATA_TYPE

+

Data parameter types.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
typedef enum FMOD_DSP_PARAMETER_DATA_TYPE {
+  FMOD_DSP_PARAMETER_DATA_TYPE_USER = 0,
+  FMOD_DSP_PARAMETER_DATA_TYPE_OVERALLGAIN = -1,
+  FMOD_DSP_PARAMETER_DATA_TYPE_3DATTRIBUTES = -2,
+  FMOD_DSP_PARAMETER_DATA_TYPE_SIDECHAIN = -3,
+  FMOD_DSP_PARAMETER_DATA_TYPE_FFT = -4,
+  FMOD_DSP_PARAMETER_DATA_TYPE_3DATTRIBUTES_MULTI = -5,
+  FMOD_DSP_PARAMETER_DATA_TYPE_ATTENUATION_RANGE = -6,
+  FMOD_DSP_PARAMETER_DATA_TYPE_DYNAMIC_RESPONSE = -7,
+  FMOD_DSP_PARAMETER_DATA_TYPE_FINITE_LENGTH = -8
+} FMOD_DSP_PARAMETER_DATA_TYPE;
+
+ +
enum DSP_PARAMETER_DATA_TYPE
+{
+  DSP_PARAMETER_DATA_TYPE_USER = 0,
+  DSP_PARAMETER_DATA_TYPE_OVERALLGAIN = -1,
+  DSP_PARAMETER_DATA_TYPE_3DATTRIBUTES = -2,
+  DSP_PARAMETER_DATA_TYPE_SIDECHAIN = -3,
+  DSP_PARAMETER_DATA_TYPE_FFT = -4,
+  DSP_PARAMETER_DATA_TYPE_3DATTRIBUTES_MULTI = -5,
+  DSP_PARAMETER_DATA_TYPE_ATTENUATION_RANGE = -6,
+  DSP_PARAMETER_DATA_TYPE_DYNAMIC_RESPONSE = -7,
+  DSP_PARAMETER_DATA_TYPE_FINITE_LENGTH = -8
+}
+
+ +
FMOD.DSP_PARAMETER_DATA_TYPE_USER = 0
+FMOD.DSP_PARAMETER_DATA_TYPE_OVERALLGAIN = -1
+FMOD.DSP_PARAMETER_DATA_TYPE_3DATTRIBUTES = -2
+FMOD.DSP_PARAMETER_DATA_TYPE_SIDECHAIN = -3
+FMOD.DSP_PARAMETER_DATA_TYPE_FFT = -4
+FMOD.DSP_PARAMETER_DATA_TYPE_3DATTRIBUTES_MULTI = -5
+FMOD.DSP_PARAMETER_DATA_TYPE_ATTENUATION_RANGE = -6,
+FMOD.DSP_PARAMETER_DATA_TYPE_DYNAMIC_RESPONSE = -7
+FMOD.DSP_PARAMETER_DATA_TYPE_FINITE_LENGTH = -8
+
+ +
+
FMOD_DSP_PARAMETER_DATA_TYPE_USER
+
Default data type. All user data types should be 0 or above.
+
FMOD_DSP_PARAMETER_DATA_TYPE_OVERALLGAIN
+
Data type for FMOD_DSP_PARAMETER_OVERALLGAIN parameters. There should be a maximum of one per DSP.
+
FMOD_DSP_PARAMETER_DATA_TYPE_3DATTRIBUTES
+
Data type for FMOD_DSP_PARAMETER_3DATTRIBUTES parameters. There should be a maximum of one per DSP.
+
FMOD_DSP_PARAMETER_DATA_TYPE_SIDECHAIN
+
Data type for FMOD_DSP_PARAMETER_SIDECHAIN parameters. There should be a maximum of one per DSP.
+
FMOD_DSP_PARAMETER_DATA_TYPE_FFT
+
Data type for FMOD_DSP_PARAMETER_FFT parameters. There should be a maximum of one per DSP.
+
FMOD_DSP_PARAMETER_DATA_TYPE_3DATTRIBUTES_MULTI
+
Data type for FMOD_DSP_PARAMETER_3DATTRIBUTES_MULTI parameters. There should be a maximum of one per DSP.
+
FMOD_DSP_PARAMETER_DATA_TYPE_ATTENUATION_RANGE
+
Data type for FMOD_DSP_PARAMETER_ATTENUATION_RANGE parameters. There should be a maximum of one per DSP.
+
FMOD_DSP_PARAMETER_DATA_TYPE_DYNAMIC_RESPONSE
+
Data type for FMOD_DSP_PARAMETER_DYNAMIC_RESPONSE parameters. There should be a maximum of one per DSP.
+
FMOD_DSP_PARAMETER_DATA_TYPE_FINITE_LENGTH
+
Data type for FMOD_DSP_PARAMETER_FINITE_LENGTH parameters. There should be a maximum of one per DSP.
+
+

See Also: FMOD_DSP_PARAMETER_DESC_DATA, DSP::getParameterData, DSP::setParameterData

+

FMOD_DSP_PARAMETER_DESC

+

Base structure for DSP parameter descriptions.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
typedef struct FMOD_DSP_PARAMETER_DESC {
+  FMOD_DSP_PARAMETER_TYPE         type;
+  char                            name[16];
+  char                            label[16];
+  const char                     *description;
+  union
+  {
+      FMOD_DSP_PARAMETER_DESC_FLOAT   floatdesc;
+      FMOD_DSP_PARAMETER_DESC_INT     intdesc;
+      FMOD_DSP_PARAMETER_DESC_BOOL    booldesc;
+      FMOD_DSP_PARAMETER_DESC_DATA    datadesc;
+  }
+} FMOD_DSP_PARAMETER_DESC;
+
+ +
struct DSP_PARAMETER_DESC
+{
+  DSP_PARAMETER_TYPE         type;
+  char[]                     name;
+  char[]                     label;
+  string                     description;
+  DSP_PARAMETER_DESC_UNION   desc;
+}
+
+ +
FMOD_DSP_PARAMETER_DESC
+{
+  type,
+  name,
+  label,
+  description,
+};
+
+ +
+
type
+
Parameter type. (FMOD_DSP_PARAMETER_TYPE)
+
name
+
Parameter Name.
+
label
+
Unit type label.
+
description
+
Description of the parameter.
+
floatdesc
+
Floating point format description used when type is FMOD_DSP_PARAMETER_TYPE_FLOAT. (FMOD_DSP_PARAMETER_DESC_FLOAT)
+
intdesc
+
Integer format description used when type is FMOD_DSP_PARAMETER_TYPE_INT. (FMOD_DSP_PARAMETER_DESC_INT)
+
booldesc
+
Boolean format description used when type is FMOD_DSP_PARAMETER_TYPE_BOOL. (FMOD_DSP_PARAMETER_DESC_BOOL)
+
datadesc
+
Data format description used when type is FMOD_DSP_PARAMETER_TYPE_DATA. (FMOD_DSP_PARAMETER_DESC_DATA)
+
+

See Also: System::createDSP, DSP::setParameterFloat, DSP::getParameterFloat, DSP::setParameterInt, DSP::getParameterInt, DSP::setParameterBool, DSP::getParameterBool, DSP::setParameterData, DSP::getParameterData, FMOD_DSP_PARAMETER_DESC_FLOAT, FMOD_DSP_PARAMETER_DESC_INT, FMOD_DSP_PARAMETER_DESC_BOOL, FMOD_DSP_PARAMETER_DESC_DATA, FMOD_DSP_PARAMETER_DATA_TYPE

+

FMOD_DSP_PARAMETER_DESC_BOOL

+

Boolean parameter description.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
typedef struct FMOD_DSP_PARAMETER_DESC_BOOL {
+  FMOD_BOOL            defaultval;
+  const char* const*   valuenames;
+} FMOD_DSP_PARAMETER_DESC_BOOL;
+
+ +
struct DSP_PARAMETER_DESC_BOOL
+{
+  bool      defaultval;
+  IntPtr    valuenames;
+}
+
+ +
FMOD_DSP_PARAMETER_DESC_BOOL
+{
+  defaultval,
+};
+
+ +
+
defaultval
+
+

Default parameter value.

+
    +
  • Units: Boolean
  • +
+
+
valuenames Opt
+
Names for false and true, respectively (UTF-8 string). There should be two strings.
+
+

See Also: System::createDSP, DSP::setParameterBool, DSP::getParameterBool, FMOD_DSP_PARAMETER_DESC

+

FMOD_DSP_PARAMETER_DESC_DATA

+

Data parameter description.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
typedef struct FMOD_DSP_PARAMETER_DESC_DATA {
+  int   datatype;
+} FMOD_DSP_PARAMETER_DESC_DATA;
+
+ +
struct DSP_PARAMETER_DESC_DATA
+{
+  int   datatype;
+}
+
+ +
FMOD_DSP_PARAMETER_DESC_DATA
+{
+  datatype,
+};
+
+ +
+
datatype
+
Type of data.
+
+

See Also: System::createDSP, DSP::setParameterData, DSP::getParameterData, FMOD_DSP_PARAMETER_DATA_TYPE, FMOD_DSP_PARAMETER_DESC

+

FMOD_DSP_PARAMETER_DESC_FLOAT

+

Float parameter description.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
typedef struct FMOD_DSP_PARAMETER_DESC_FLOAT {
+  float                              min;
+  float                              max;
+  float                              defaultval;
+  FMOD_DSP_PARAMETER_FLOAT_MAPPING   mapping;
+} FMOD_DSP_PARAMETER_DESC_FLOAT;
+
+ +
struct DSP_PARAMETER_DESC_FLOAT
+{
+  float                       min;
+  float                       max;
+  float                       defaultval;
+  DSP_PARAMETER_FLOAT_MAPPING mapping;
+}
+
+ +
FMOD_DSP_PARAMETER_DESC_FLOAT
+{
+  min,
+  max,
+  defaultval,
+};
+
+ +
+
min
+
Minimum value.
+
max
+
Maximum value.
+
defaultval
+
Default value.
+
mapping
+
How the values are distributed across dials and automation curves. (FMOD_DSP_PARAMETER_FLOAT_MAPPING)
+
+

See Also: System::createDSP, DSP::setParameterFloat, DSP::getParameterFloat, FMOD_DSP_PARAMETER_DESC

+

FMOD_DSP_PARAMETER_DESC_INT

+

Integer parameter description.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
typedef struct FMOD_DSP_PARAMETER_DESC_INT {
+  int                  min;
+  int                  max;
+  int                  defaultval;
+  FMOD_BOOL            goestoinf;
+  const char* const*   valuenames;
+} FMOD_DSP_PARAMETER_DESC_INT;
+
+ +
struct DSP_PARAMETER_DESC_INT
+{
+  int    min;
+  int    max;
+  int    defaultval;
+  bool   goestoinf;
+  IntPtr valuenames;
+}
+
+ +
FMOD_DSP_PARAMETER_DESC_INT
+{
+  min,
+  max,
+  defaultval,
+  goestoinf,
+};
+
+ +
+
min
+
Minimum value.
+
max
+
Maximum value.
+
defaultval
+
Default value.
+
goestoinf
+
+

Whether the last value represents infinity.

+
    +
  • Units: Boolean
  • +
+
+
valuenames Opt
+
Names for each value (UTF-8 string). There should be as many strings as there are possible values (max - min + 1).
+
+

See Also: System::createDSP, DSP::setParameterInt, DSP::getParameterInt, FMOD_DSP_PARAMETER_DESC

+

FMOD_DSP_PARAMETER_DYNAMIC_RESPONSE

+

Dynamic response data structure.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
typedef struct FMOD_DSP_PARAMETER_DYNAMIC_RESPONSE {
+  int     numchannels;
+  float   rms[32];
+} FMOD_DSP_PARAMETER_DYNAMIC_RESPONSE;
+
+ +
struct DSP_PARAMETER_DYNAMIC_RESPONSE
+{
+  int numchannels;
+  float[] rms;
+}
+
+ +
DSP_PARAMETER_DYNAMIC_RESPONSE
+{
+  numchannels,
+  rms,
+}
+
+ +
+
numchannels R/O
+
The number of channels recorded in the rms array.
+
rms R/O
+
+

The RMS (Root Mean Square) averaged gain factor applied per channel for the last processed block of audio.

+
    +
  • Units: Linear
  • +
+
+
+

See Also: FMOD_DSP_PARAMETER_DATA_TYPE, FMOD_DSP_PARAMETER_DESC, FMOD_DSP_PARAMETER_DATA_TYPE_DYNAMIC_RESPONSE

+

FMOD_DSP_PARAMETER_FFT

+

FFT parameter data structure.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
typedef struct FMOD_DSP_PARAMETER_FFT {
+  int     length;
+  int     numchannels;
+  float   *spectrum[32];
+} FMOD_DSP_PARAMETER_FFT;
+
+ +
struct DSP_PARAMETER_FFT
+{
+  int       length;
+  int       numchannels;
+  float[][] spectrum;
+  void getSpectrum(ref float[][] buffer);
+  void getSpectrum(int channel, ref float[] buffer);
+}
+
+ +
FMOD_DSP_PARAMETER_FFT
+{
+  length,
+  numchannels,
+  spectrum
+};
+
+ +
+
length R/O
+
Number of entries in this spectrum window. Divide this by the output rate to get the hz per entry.
+
numchannels R/O
+
Number of channels in spectrum.
+
spectrum R/O
+
Per channel spectrum arrays. See remarks for more.
+
getSpectrum C#
+
Fill the provided buffer with the spectrum data to avoid garbage collection.
+
getSpectrum C#
+
Fill the provided buffer with the spectrum data for the specified channel to avoid garbage collection.
+
+

Notes on the spectrum data member. Values inside the float buffer are typically between 0 and 1.0.

+

Each top level array represents one PCM channel of data.

+

Address data as spectrum[channel][bin]. A bin is 1 fft window entry.

+

Only read/display half of the buffer typically for analysis as the 2nd half is usually the same data reversed due to the nature of the way FFT works.

+

See Also: FMOD_DSP_PARAMETER_DATA_TYPE, FMOD_DSP_PARAMETER_DESC, FMOD_DSP_PARAMETER_DATA_TYPE_FFT, FMOD_DSP_TYPE, FMOD_DSP_FFT

+

FMOD_DSP_PARAMETER_FINITE_LENGTH

+

Length data structure.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
typedef struct FMOD_DSP_PARAMETER_FINITE_LENGTH
+{
+  FMOD_BOOL finite;
+} FMOD_DSP_PARAMETER_FINITE_LENGTH;
+
+ +
struct DSP_PARAMETER_FINITE_LENGTH
+{
+  int finite;
+}
+
+ +
DSP_PARAMETER_FINITE_LENGTH
+{
+  finite,
+}
+
+ +
+
finite R/O
+
+

Whether the DSP's playback length is finite.

+
    +
  • Units: Boolean
  • +
+
+
+

This data structure is used by the Studio API to detect whether the DSP will stop by itself or continue playing forever.

+

See Also: FMOD_DSP_PARAMETER_DATA_TYPE, FMOD_DSP_PARAMETER_DESC, FMOD_DSP_PARAMETER_DATA_TYPE_FINITE_LENGTH

+

FMOD_DSP_PARAMETER_FLOAT_MAPPING

+

Structure to define a mapping for a DSP unit's float parameter.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
typedef struct FMOD_DSP_PARAMETER_FLOAT_MAPPING {
+  FMOD_DSP_PARAMETER_FLOAT_MAPPING_TYPE               type;
+  FMOD_DSP_PARAMETER_FLOAT_MAPPING_PIECEWISE_LINEAR   piecewiselinearmapping;
+} FMOD_DSP_PARAMETER_FLOAT_MAPPING;
+
+ +
struct DSP_PARAMETER_FLOAT_MAPPING
+{
+  DSP_PARAMETER_FLOAT_MAPPING_TYPE type;
+  DSP_PARAMETER_FLOAT_MAPPING_PIECEWISE_LINEAR piecewiselinearmapping;
+}
+
+ +
FMOD_DSP_PARAMETER_FLOAT_MAPPING
+{
+  type,
+  piecewiselinearmapping
+};
+
+ +
+
type
+
Mapping type (FMOD_DSP_PARAMETER_FLOAT_MAPPING_TYPE)
+
piecewiselinearmapping
+
Piecewise linear mapping type. (FMOD_DSP_PARAMETER_FLOAT_MAPPING_PIECEWISE_LINEAR)
+
+

See Also: FMOD_DSP_PARAMETER_FLOAT_MAPPING_TYPE, FMOD_DSP_PARAMETER_FLOAT_MAPPING_PIECEWISE_LINEAR, FMOD_DSP_PARAMETER_DESC_FLOAT

+

FMOD_DSP_PARAMETER_FLOAT_MAPPING_PIECEWISE_LINEAR

+

Structure to define a piecewise linear mapping.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
typedef struct FMOD_DSP_PARAMETER_FLOAT_MAPPING_PIECEWISE_LINEAR {
+  int     numpoints;
+  float   *pointparamvalues;
+  float   *pointpositions;
+} FMOD_DSP_PARAMETER_FLOAT_MAPPING_PIECEWISE_LINEAR;
+
+ +
struct DSP_PARAMETER_FLOAT_MAPPING_PIECEWISE_LINEAR
+{
+  int numpoints;
+  IntPtr pointparamvalues;
+  IntPtr pointpositions;
+}
+
+ +
FMOD_DSP_PARAMETER_FLOAT_MAPPING_PIECEWISE_LINEAR
+{
+  numpoints,
+};
+
+ +
+
numpoints
+
Number of pairs in the piecewise mapping (at least 2).
+
pointparamvalues
+
Values in the parameter's units for each point
+
pointpositions
+
Positions along the control's scale (e.g. dial angle) corresponding to each parameter value. The range of this scale is arbitrary and all positions will be relative to the minimum and maximum values (e.g. [0,1,3] is equivalent to [1,2,4] and [2,4,8]). If this array is zero, pointparamvalues will be distributed with equal spacing.
+
+

See Also: FMOD_DSP_PARAMETER_FLOAT_MAPPING_TYPE, FMOD_DSP_PARAMETER_FLOAT_MAPPING

+

FMOD_DSP_PARAMETER_FLOAT_MAPPING_TYPE

+

DSP float parameter mappings. These determine how values are mapped across dials and automation curves.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
typedef enum FMOD_DSP_PARAMETER_FLOAT_MAPPING_TYPE {
+  FMOD_DSP_PARAMETER_FLOAT_MAPPING_TYPE_LINEAR,
+  FMOD_DSP_PARAMETER_FLOAT_MAPPING_TYPE_AUTO,
+  FMOD_DSP_PARAMETER_FLOAT_MAPPING_TYPE_PIECEWISE_LINEAR
+} FMOD_DSP_PARAMETER_FLOAT_MAPPING_TYPE;
+
+ +
enum DSP_PARAMETER_FLOAT_MAPPING_TYPE
+{
+  DSP_PARAMETER_FLOAT_MAPPING_TYPE_LINEAR = 0,
+  DSP_PARAMETER_FLOAT_MAPPING_TYPE_AUTO,
+  DSP_PARAMETER_FLOAT_MAPPING_TYPE_PIECEWISE_LINEAR,
+}
+
+ +
FMOD.DSP_PARAMETER_FLOAT_MAPPING_TYPE_LINEAR
+FMOD.DSP_PARAMETER_FLOAT_MAPPING_TYPE_AUTO
+FMOD.DSP_PARAMETER_FLOAT_MAPPING_TYPE_PIECEWISE_LINEAR
+
+ +
+
FMOD_DSP_PARAMETER_FLOAT_MAPPING_TYPE_LINEAR
+
Values mapped linearly across range.
+
FMOD_DSP_PARAMETER_FLOAT_MAPPING_TYPE_AUTO
+
A mapping is automatically chosen based on range and units. See remarks.
+
FMOD_DSP_PARAMETER_FLOAT_MAPPING_TYPE_PIECEWISE_LINEAR
+
Values mapped in a piecewise linear fashion defined by FMOD_DSP_PARAMETER_FLOAT_MAPPING_PIECEWISE_LINEAR.
+
+

FMOD_DSP_PARAMETER_FLOAT_MAPPING_TYPE_AUTO generates a mapping based on range and units. For example, if the units are in Hertz and the range is with-in the audio spectrum, a Bark scale will be chosen. Logarithmic scales may also be generated for ranges above zero spanning several orders of magnitude.

+

See Also: FMOD_DSP_PARAMETER_FLOAT_MAPPING

+

FMOD_DSP_PARAMETER_OVERALLGAIN

+

Overall gain parameter data structure.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
typedef struct FMOD_DSP_PARAMETER_OVERALLGAIN {
+  float   linear_gain;
+  float   linear_gain_additive;
+} FMOD_DSP_PARAMETER_OVERALLGAIN;
+
+ +
struct DSP_PARAMETER_OVERALLGAIN
+{
+  float linear_gain;
+  float linear_gain_additive;
+}
+
+ +
FMOD_DSP_PARAMETER_OVERALLGAIN
+{
+  linear_gain,
+  linear_gain_additive,
+};
+
+ +
+
linear_gain R/O
+
Overall linear gain of the effect on the direct signal path.
+
linear_gain_additive R/O
+
Additive gain for parallel signal paths.
+
+

This parameter is read by the system to determine the effect's gain for voice virtualization.

+

See Also: FMOD_DSP_PARAMETER_DATA_TYPE, FMOD_DSP_PARAMETER_DESC, Virtual Voice System.

+

FMOD_DSP_PARAMETER_SIDECHAIN

+

Side chain parameter data structure.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
typedef struct FMOD_DSP_PARAMETER_SIDECHAIN {
+  FMOD_BOOL   sidechainenable;
+} FMOD_DSP_PARAMETER_SIDECHAIN;
+
+ +
struct DSP_PARAMETER_SIDECHAIN
+{
+  int sidechainenable;
+}
+
+ +
FMOD_DSP_PARAMETER_SIDECHAIN
+{
+  sidechainenable,
+};
+
+ +
+
sidechainenable
+
+

Whether sidechains are enabled.

+
    +
  • Units: Boolean
  • +
+
+
+

See Also: FMOD_DSP_PARAMETER_DATA_TYPE, FMOD_DSP_PARAMETER_DESC

+

FMOD_DSP_PARAMETER_TYPE

+

DSP parameter types.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
typedef enum FMOD_DSP_PARAMETER_TYPE {
+  FMOD_DSP_PARAMETER_TYPE_FLOAT,
+  FMOD_DSP_PARAMETER_TYPE_INT,
+  FMOD_DSP_PARAMETER_TYPE_BOOL,
+  FMOD_DSP_PARAMETER_TYPE_DATA,
+  FMOD_DSP_PARAMETER_TYPE_MAX
+} FMOD_DSP_PARAMETER_TYPE;
+
+ +
enum DSP_PARAMETER_TYPE
+{
+  FLOAT = 0,
+  INT,
+  BOOL,
+  DATA,
+  MAX
+}
+
+ +
FMOD.DSP_PARAMETER_TYPE_FLOAT
+FMOD.DSP_PARAMETER_TYPE_INT
+FMOD.DSP_PARAMETER_TYPE_BOOL
+FMOD.DSP_PARAMETER_TYPE_DATA
+FMOD.DSP_PARAMETER_TYPE_MAX
+
+ +
+
FMOD_DSP_PARAMETER_TYPE_FLOAT
+
FMOD_DSP_PARAMETER_DESC will use the FMOD_DSP_PARAMETER_DESC_FLOAT.
+
FMOD_DSP_PARAMETER_TYPE_INT
+
FMOD_DSP_PARAMETER_DESC will use the FMOD_DSP_PARAMETER_DESC_INT.
+
FMOD_DSP_PARAMETER_TYPE_BOOL
+
FMOD_DSP_PARAMETER_DESC will use the FMOD_DSP_PARAMETER_DESC_BOOL.
+
FMOD_DSP_PARAMETER_TYPE_DATA
+
FMOD_DSP_PARAMETER_DESC will use the FMOD_DSP_PARAMETER_DESC_DATA.
+
FMOD_DSP_PARAMETER_TYPE_MAX
+
Maximum number of DSP parameter types.
+
+

See Also: FMOD_DSP_PARAMETER_DESC

+

FMOD_DSP_PROCESS_CALLBACK

+

Process callback.

+

This callback receives an input signal, and allows the user to filter or process the data and write it to the output. This is an alternative to the FMOD_DSP_READ_CALLBACK and FMOD_DSP_SHOULDIPROCESS_CALLBACK.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
FMOD_RESULT F_CALL FMOD_DSP_PROCESS_CALLBACK(
+  FMOD_DSP_STATE *dsp_state,
+  unsigned int length,
+  const FMOD_DSP_BUFFER_ARRAY *inbufferarray,
+  FMOD_DSP_BUFFER_ARRAY *outbufferarray,
+  FMOD_BOOL inputsidle,
+  FMOD_DSP_PROCESS_OPERATION op
+);
+
+ +
delegate RESULT DSP_PROCESS_CALLBACK
+(
+  ref DSP_STATE dsp_state,
+  uint length,
+  ref DSP_BUFFER_ARRAY inbufferarray,
+  ref DSP_BUFFER_ARRAY outbufferarray,
+  bool inputsidle,
+  DSP_PROCESS_OPERATION op
+);
+
+ +
+

Not supported for JavaScript.

+
+
+
dsp_state
+
DSP plug-in state. (FMOD_DSP_STATE)
+
length
+
+

Length of the incoming and outgoing buffer.

+
    +
  • Units: Samples
  • +
+
+
inbufferarray
+
Description of the incoming signal. (FMOD_DSP_BUFFER_ARRAY)
+
outbufferarray
+
Description of the outgoing signal. (FMOD_DSP_BUFFER_ARRAY)
+
inputsidle
+
+

This is true if no audio is being fed to this unit.

+
    +
  • Units: Boolean
  • +
+
+
op
+
Operation type. (FMOD_DSP_PROCESS_OPERATION)
+
+

Invoked by:

+
    +
  • FMOD Mixer Thread. The callback is called automatically and periodically when the DSP engine updates. This callback is called back regularly after the unit has been created, inserted to the DSP graph, and set to active by the user.
  • +
+

For a process update to be called it would have to be enabled, and this is done with DSP::setActive. If ChannelControl::addDSP is used the unit is automatically set to active.

+

Implementation Detail:

+

This callback can be used to specify the output channel format at runtime rather than create time, and also supports multiple input/output buffers.

+

This callback will be called twice per mix as it has a dual purpose. Once will be with op = FMOD_DSP_PROCESS_QUERY, and then depending on the return value of the query, if it is FMOD_OK it will call it again with FMOD_DSP_PROCESS_PERFORM.

+

Return FMOD_ERR_DSP_SILENCE if the effect is generating silence, so FMOD's mixer can optimize the signal path and not process it any more.

+

Example:

+

The following example demonstrates how to copy the input buffer to the output buffer at half volume inside a DSP process callback:

+
FMOD_RESULT F_CALL Process(FMOD_DSP_STATE *dsp_state, unsigned int length, const FMOD_DSP_BUFFER_ARRAY *inbufferarray, FMOD_DSP_BUFFER_ARRAY *outbufferarray, FMOD_BOOL inputsidle, FMOD_DSP_PROCESS_OPERATION op)
+{
+    if (op == FMOD_DSP_PROCESS_QUERY)
+    {
+        if (outbufferarray && inbufferarray)
+        {
+            if (outbufferarray[0].buffernumchannels[0] != inbufferarray[0].buffernumchannels[0])
+            {
+                FMOD_ERR_DSP_SILENCE;
+            }
+        }
+        if (inputsidle)
+        {
+            return FMOD_ERR_DSP_DONTPROCESS;
+        }
+    }
+    else
+    {
+        int numchannels = outbufferarray[0].buffernumchannels[0];
+        float *input = inbufferarray[0].buffers[0];
+        float *output = outbufferarray[0].buffers[0];
+
+        for (unsigned int sample = 0; sample < length; sample++)
+        {
+            for (int channel = 0; channel < numchannels; channel++)
+            {
+                output[sample * numchannels + channel] = input[sample * numchannels + channel] * 0.5f;
+            }
+        }
+    }
+
+    return FMOD_OK;
+}
+
+ +
[AOT.MonoPInvokeCallback(typeof(FMOD.DSP_PROCESS_CALLBACK))]
+static RESULT Process(ref DSP_STATE dsp_state, uint length, ref DSP_BUFFER_ARRAY inbufferarray, ref DSP_BUFFER_ARRAY outbufferarray, bool inputsidle, DSP_PROCESS_OPERATION op)
+{
+    if (op == DSP_PROCESS_OPERATION.PROCESS_QUERY)
+    {
+        if (inbufferarray.numchannels != outbufferarray.numchannels)
+        {
+            return RESULT.ERR_DSP_SILENCE;
+        }
+        if (inputsidle)
+        {
+            return RESULT.ERR_DSP_DONTPROCESS;
+        }
+    }
+    else if (op == DSP_PROCESS_OPERATION.PROCESS_PERFORM)
+    {
+        int numchannels = outbufferarray.numchannels;
+        float[] input = new float[length * numchannels];
+        float[] output = new float[length * numchannels];
+
+        Marshal.Copy(inbufferarray.buffer, input, 0, (int)length * numchannels);
+
+        for (int sample = 0; sample < length; sample++)
+        {
+            for (int channel = 0; channel < numchannels; channel++)
+            {
+                output[sample * numchannels + channel] = input[sample * numchannels + channel] * 0.5f;
+            }
+        }
+
+        Marshal.Copy(output, 0, outbufferarray.buffer, (int)length * numchannels);
+    }
+
+    return RESULT.OK;
+}
+
+ +
+

Not supported for JavaScript.

+
+

See Also: FMOD_DSP_READ_CALLBACK, FMOD_DSP_SHOULDIPROCESS_CALLBACK, FMOD_DSP_DESCRIPTION

+

FMOD_DSP_PROCESS_OPERATION

+

Process operation type.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
typedef enum FMOD_DSP_PROCESS_OPERATION {
+  FMOD_DSP_PROCESS_PERFORM,
+  FMOD_DSP_PROCESS_QUERY
+} FMOD_DSP_PROCESS_OPERATION;
+
+ +
enum DSP_PROCESS_OPERATION
+{
+  PROCESS_PERFORM = 0,
+  PROCESS_QUERY
+}
+
+ +
+

Not supported for JavaScript.

+
+
+
FMOD_DSP_PROCESS_PERFORM
+
Process the incoming audio in inbufferarray and output to outbufferarray.
+
FMOD_DSP_PROCESS_QUERY
+
The DSP is being queried for the expected output format and whether it needs to process audio or should be bypassed. The function should return FMOD_OK, or FMOD_ERR_DSP_DONTPROCESS or FMOD_ERR_DSP_SILENCE if audio can pass through unprocessed. See remarks for more. If audio is to be processed, outbufferarray must be filled with the expected output format, channel count and mask.
+
+

A process callback will be called twice per mix for a DSP unit. Once with the FMOD_DSP_PROCESS_QUERY command, then conditionally, FMOD_DSP_PROCESS_PERFORM.

+

FMOD_DSP_PROCESS_QUERY is to be handled only by filling out the outbufferarray information, and returning a relevant return code.

+

It should not really do any logic besides checking and returning one of the following codes:

+ +

If audio is to be processed, outbufferarray must be filled with the expected output format, channel count and mask. Mask can be 0.

+

FMOD_DSP_PROCESS_PERFORM is to be handled by reading the data from the input, processing it, and writing it to the output. Always write to the output buffer and fill it fully to avoid unpredictable audio output.

+

Always return FMOD_OK, the return value is ignored from the process stage.

+

See Also: FMOD_DSP_PROCESS_CALLBACK, FMOD_DSP_DESCRIPTION

+

FMOD_DSP_READ_CALLBACK

+

DSP read callback.

+

This callback receives an input signal and allows the user of the plug-in to filter or process the data and write it to the output.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
FMOD_RESULT F_CALL FMOD_DSP_READ_CALLBACK(
+  FMOD_DSP_STATE *dsp_state,
+  float *inbuffer,
+  float *outbuffer,
+  unsigned int length,
+  int inchannels,
+  int *outchannels
+);
+
+ +
delegate RESULT DSP_READ_CALLBACK
+(
+  ref DSP_STATE dsp_state,
+  IntPtr inbuffer,
+  IntPtr outbuffer,
+  uint length,
+  int inchannels,
+  ref int outchannels
+);
+
+ +
function FMOD_DSP_READ_CALLBACK(
+    dsp_state,
+    inbuffer,
+    outbuffer,
+    length,
+    inchannels,
+    outchannels
+)
+
+ +
+
dsp_state
+
DSP plug-in state. (FMOD_DSP_STATE)
+
inbuffer
+
Incoming floating point -1.0 to +1.0 ranged data. Data will be interleaved if inchannels is greater than 1.
+
outbuffer
+
Outgoing floating point -1.0 to +1.0 ranged data. The DSP writer must write to this pointer else there will be silence. Data must be interleaved if outchannels is greater than 1.
+
length
+
+

Length of the incoming and outgoing buffers.

+
    +
  • Units: Samples
  • +
+
+
inchannels
+
Number of channels of interleaved PCM data in the inbuffer parameter. Example: 1 = mono, 2 = stereo, 6 = 5.1.
+
outchannels
+
Number of channels of interleaved PCM data in the outbuffer parameter. Example: 1 = mono, 2 = stereo, 6 = 5.1.
+
+

Invoked by:

+
    +
  • FMOD Mixer Thread. The callback is called automatically and periodically when the DSP engine updates. This callback is called regularly after the unit has been created, inserted into the DSP graph, and set to active by the user.
  • +
+

For a read update to be called it would have to be enabled, and this is done with DSP::setActive. If ChannelControl::addDSP is used the unit is automatically set to active.

+

Implementation Detail:

+

The range of -1 to 1 is a soft limit. In the case of the inbuffer it is not guaranteed to be in that range, and in the case of the outbuffer FMOD will accept values outside that range. However all values will be clamped to the range of -1 to 1 in the final mix.

+

This callback will not be called if the preceding FMOD_DSP_SHOULDIPROCESS_CALLBACK is returning FMOD_ERR_DSP_DONTPROCESS. Return FMOD_ERR_DSP_SILENCE if the effect is generating silence, so FMOD's mixer can optimize the signal path and not process it any more.

+

NOTE: Effects that do not stop processing via FMOD_DSP_SHOULDIPROCESS_CALLBACK may keep the signal chain alive when it is not desirable to do so. FMOD Studio events may return that they are still playing when they should be stopped.

+

Example:

+

The following example demonstrates how to copy the input buffer to the output buffer at half volume inside a DSP read callback:

+
FMOD_RESULT F_CALL Read(FMOD_DSP_STATE *dsp_state, float *inbuffer, float *outbuffer, unsigned int length, int inchannels, int *outchannels)
+{
+    for (unsigned int sample = 0; sample < length; sample++)
+    {
+        for (int channel = 0; channel < inchannels; channel++)
+        {
+            outbuffer[sample * *outchannels + channel] = inbuffer[sample * inchannels + channel] * 0.5f;
+        }
+    }
+
+    return FMOD_OK;
+}
+
+ +
[AOT.MonoPInvokeCallback(typeof(FMOD.DSP_READ_CALLBACK))]
+static RESULT Read(ref DSP_STATE dsp_state, IntPtr inbuffer, IntPtr outbuffer, uint length, int inchannels, ref int outchannels)
+{
+    float[] input = new float[length * inchannels];
+    float[] output = new float[length * outchannels];
+
+    Marshal.Copy(inbuffer, input, 0, (int)length * inchannels);
+
+    for (int sample = 0; sample < length; sample++)
+    {
+        for (int channel = 0; channel < outchannels; channel++)
+        {
+            output[sample * outchannels + channel] = input[sample * outchannels + channel] * 0.5f;
+        }
+    }
+
+    Marshal.Copy(output, 0, outbuffer, (int)length * outchannels);
+
+    return RESULT.OK;
+}
+
+ +
function Read(dsp_state, inbuffer, outbuffer, length, inchannels, outchannels)
+{
+    for (var sample = 0; sample < length; sample++)
+    {
+        for (var channel = 0; channel < outchannels; channel++)
+        {
+            let val = FMOD.getValue(inbuffer + (((sample * inchannels) + channel) * 4), 'float') * 0.5;
+
+            FMOD.setValue(outbuffer + (((sample * outchannels) + channel) * 4), val, 'float');
+            dsp_state.plugindata.buffer[(sample * outchannels) + channel] = val;
+        }
+    }
+
+    return FMOD.OK;
+}
+
+ +

See Also: FMOD_DSP_SHOULDIPROCESS_CALLBACK, FMOD_DSP_DESCRIPTION, DSP::setActive, FMOD_RESULT

+

FMOD_DSP_REALLOC_FUNC

+

Function to reallocate memory using the FMOD memory system.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
void * F_CALL FMOD_DSP_REALLOC_FUNC(
+    void *ptr,
+    unsigned int size,
+    FMOD_MEMORY_TYPE type,
+    const char *sourcestr
+);
+
+ +
delegate IntPtr DSP_REALLOC_FUNC(
+    IntPtr ptr,
+    uint size,
+    MEMORY_TYPE type,
+    IntPtr sourcestr
+);
+
+ +
+

Not supported for JavaScript.

+
+
+
ptr
+
Memory location to reallocate.
+
size
+
+

Allocation size.

+
    +
  • Units: Bytes
  • +
+
+
type
+
Memory allocation type. (FMOD_MEMORY_TYPE)
+
sourcestr
+
String with the FMOD source code filename and line number in it. Only valid in logging versions of FMOD. (UTF-8 string)
+
+
+

The 'sourcestr' argument can be used via StringWrapper by using FMOD.StringWrapper sourceStr = new FMOD.StringWrapper(sourcestr);

+
+

Implementation Detail:

+

This function is a wrapper used by the system level allocator and can be called from any DSP instance. Returns a pointer to a region of reallocated memory, or 0 on a failure.

+

See Also: FMOD_DSP_STATE, FMOD_DSP_ALLOC_FUNC, FMOD_DSP_FREE_FUNC

+

FMOD_DSP_RELEASE_CALLBACK

+

DSP release callback.

+

This callback is called when the user of the plug-in releases a DSP unit instance.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
FMOD_RESULT F_CALL FMOD_DSP_RELEASE_CALLBACK(
+  FMOD_DSP_STATE *dsp_state
+);
+
+ +
delegate RESULT DSP_RELEASE_CALLBACK
+(
+  ref DSP_STATE dsp_state
+);
+
+ +
function FMOD_DSP_RELEASE_CALLBACK(
+    dsp_state,
+)
+
+ +
+
dsp_state
+
DSP plug-in state. (FMOD_DSP_STATE)
+
+

Invoked by:

+
    +
  • User Thread / FMOD Mixer Thread. Triggered by user calling DSP::release or internal FMOD functions.
  • +
+

Implementation Detail:

+

This callback is typically used to free any resources allocated during the course of the lifetime of the DSP instance or perform any shut down code needed to clean up the DSP unit.

+

See Also: FMOD_DSP_DESCRIPTION, FMOD_DSP_CREATE_CALLBACK

+

FMOD_DSP_RESET_CALLBACK

+

DSP reset callback.

+

This callback function is called to allow a DSP effect to reset its internal state.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
FMOD_RESULT F_CALL FMOD_DSP_RESET_CALLBACK(
+  FMOD_DSP_STATE *dsp_state
+);
+
+ +
delegate RESULT DSP_RESET_CALLBACK
+(
+  ref DSP_STATE dsp_state
+)
+
+ +
function FMOD_DSP_RESET_CALLBACK(
+    dsp_state,
+)
+
+ +
+
dsp_state
+
DSP plug-in state. (FMOD_DSP_STATE)
+
+

Invoked by:

+
    +
  • User Thread / FMOD Mixer Thread. Triggered by user calling DSP::reset or internal FMOD functions.
  • +
+

This callback is called on all plug-ins inside an event whenever the event is started (for example by Studio::EventInstance::start).

+

It is also useful if (for example) an effect is still holding audio data for a sound that has stopped, and is being relocated to a new sound. Resetting the unit would clear any buffers and get it ready for new sound data.

+

Note that this callback should not change any public parameters that are exposed via FMOD_DSP_DESCRIPTION::paramdesc, but should instead reset the internal state to match the public parameter values.

+

See Also: FMOD_DSP_DESCRIPTION

+

FMOD_DSP_SETPARAM_BOOL_CALLBACK

+

Set boolean parameter callback.

+

This callback is called when the user of the plug-in wants to set a boolean parameter for a DSP unit.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
FMOD_RESULT F_CALL FMOD_DSP_SETPARAM_BOOL_CALLBACK(
+  FMOD_DSP_STATE *dsp_state,
+  int index,
+  FMOD_BOOL value
+);
+
+ +
delegate RESULT DSP_SETPARAM_BOOL_CALLBACK
+(
+  ref DSP_STATE dsp_state,
+  int index,
+  bool value
+);
+
+ +
function FMOD_DSP_SETPARAM_BOOL_CALLBACK(
+    dsp_state,
+    index,
+    value
+)
+
+ +
+
dsp_state
+
DSP plug-in state. (FMOD_DSP_STATE)
+
index
+
Parameter index.
+
value
+
+

Parameter value.

+
    +
  • Units: Boolean
  • +
+
+
+

Invoked by:

+
    +
  • User Thread. Triggered by user calling DSP::setParameterBool. Parameter setters are not thread safe and you will need to handle synchronization between parameter setters and any other callbacks that access those parameters, i.e FMOD_DSP_PROCESS_CALLBACK.
  • +
+

See Also: DSP::getParameterBool, FMOD_DSP_DESCRIPTION, FMOD_DSP_GETPARAM_BOOL_CALLBACK

+

FMOD_DSP_SETPARAM_DATA_CALLBACK

+

Set data parameter callback.

+

This callback is called when the user of the plug-in wants to set a binary data parameter for a DSP unit.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
FMOD_RESULT F_CALL FMOD_DSP_SETPARAM_DATA_CALLBACK(
+  FMOD_DSP_STATE *dsp_state,
+  int index,
+  void *data,
+  unsigned int length
+);
+
+ +
delegate RESULT DSP_SETPARAM_DATA_CALLBACK
+(
+  ref DSP_STATE dsp_state,
+  int index,
+  IntPtr data,
+  uint length
+);
+
+ +
function FMOD_DSP_SETPARAM_DATA_CALLBACK(
+    dsp_state,
+    index,
+    data,
+    length
+)
+
+ +
+
dsp_state
+
DSP plug-in state. (FMOD_DSP_STATE)
+
index
+
Parameter index.
+
data
+
Parameter data. Binary data the size of length parameter.
+
length Opt
+
+

Size of the binary data parameter.

+
    +
  • Units: Bytes
  • +
+
+
+

Certain data types are predefined by the system and can be specified via the FMOD_DSP_PARAMETER_DESC_DATA, see FMOD_DSP_PARAMETER_DATA_TYPE

+

Invoked by:

+
    +
  • User Thread. Triggered by user calling DSP::setParameterData. Parameter setters are not thread safe and you will need to handle synchronization between parameter setters and any other callbacks that access those parameters, i.e FMOD_DSP_PROCESS_CALLBACK.
  • +
+

See Also: DSP::getParameterData, FMOD_DSP_DESCRIPTION, FMOD_DSP_GETPARAM_DATA_CALLBACK

+

FMOD_DSP_SETPARAM_FLOAT_CALLBACK

+

Set float parameter callback.

+

This callback is called when the user wants to set a float parameter for a DSP unit.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
FMOD_RESULT F_CALL FMOD_DSP_SETPARAM_FLOAT_CALLBACK(
+  FMOD_DSP_STATE *dsp_state,
+  int index,
+  float value
+);
+
+ +
delegate RESULT DSP_SETPARAM_FLOAT_CALLBACK
+(
+  ref DSP_STATE dsp_state,
+  int index,
+  ref float value
+);
+
+ +
function FMOD_DSP_SETPARAM_FLOAT_CALLBACK(
+    dsp_state,
+    index,
+    value
+)
+
+ +
+
dsp_state
+
DSP plug-in state. (FMOD_DSP_STATE)
+
index
+
Parameter index.
+
value
+
Parameter value.
+
+

Invoked by:

+
    +
  • User Thread. Triggered by user calling DSP::setParameterFloat. Parameter setters are not thread safe and you will need to handle synchronization between parameter setters and any other callbacks that access those parameters, i.e FMOD_DSP_PROCESS_CALLBACK.
  • +
+

Range checking is not needed. FMOD will clamp the incoming value to the specified min/max.

+

See Also: DSP::getParameterFloat, FMOD_DSP_DESCRIPTION, FMOD_DSP_GETPARAM_FLOAT_CALLBACK

+

FMOD_DSP_SETPARAM_INT_CALLBACK

+

Set integer parameter callback.

+

This callback is called when the user of the plug-in wants to set an integer parameter for a DSP unit.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
FMOD_RESULT F_CALL FMOD_DSP_SETPARAM_INT_CALLBACK(
+  FMOD_DSP_STATE *dsp_state,
+  int index,
+  int value
+);
+
+ +
delegate RESULT DSP_SETPARAM_INT_CALLBACK
+(
+  ref DSP_STATE dsp_state,
+  int index,
+  int value
+);
+
+ +
function FMOD_DSP_SETPARAM_INT_CALLBACK(
+    dsp_state,
+    index,
+    value
+)
+
+ +
+
dsp_state
+
DSP plug-in state. (FMOD_DSP_STATE)
+
index
+
Parameter index.
+
value
+
Parameter value.
+
+

Invoked by:

+
    +
  • User Thread. Triggered by user calling DSP::setParameterInt. Parameter setters are not thread safe and you will need to handle synchronization between parameter setters and any other callbacks that access those parameters, i.e FMOD_DSP_PROCESS_CALLBACK.
  • +
+

Range checking is not needed. FMOD will clamp the incoming value to the specified min/max.

+

See Also: DSP::setParameterInt, FMOD_DSP_DESCRIPTION, FMOD_DSP_GETPARAM_INT_CALLBACK

+

FMOD_DSP_SETPOSITION_CALLBACK

+

DSP set position callback.

+

This callback is called when the user of the plug-in wants to set a PCM position for a DSP.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
FMOD_RESULT F_CALL FMOD_DSP_SETPOSITION_CALLBACK(
+  FMOD_DSP_STATE *dsp_state,
+  unsigned int pos
+);
+
+ +
delegate RESULT DSP_SETPOSITION_CALLBACK
+(
+  ref DSP_STATE dsp_state,
+  uint pos
+);
+
+ +
function FMOD_DSP_SETPOSITION_CALLBACK(
+    dsp_state,
+    pos
+)
+
+ +
+
dsp_state
+
DSP plug-in state. (FMOD_DSP_STATE)
+
pos
+
+

Target position in the audio signal. (FMOD_TIMEUNIT_PCM).

+
    +
  • Units: Samples
  • +
+
+
+

Invoked by:

+ +

This callback is typically used for DSP units that behave as an audio signal with a relative position. This type of callback is only called if the DSP has been played with System::playDSP.

+

See Also: FMOD_DSP_DESCRIPTION

+

FMOD_DSP_SHOULDIPROCESS_CALLBACK

+

DSP 'should I process?' callback.

+

This callback is called to allow you to tell the FMOD mixer whether the FMOD_DSP_READ_CALLBACK callback should be called or not. This can be used as an optimization to reduce CPU overhead.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
FMOD_RESULT F_CALL FMOD_DSP_SHOULDIPROCESS_CALLBACK(
+  FMOD_DSP_STATE *dsp_state,
+  FMOD_BOOL inputsidle,
+  unsigned int length,
+  FMOD_CHANNELMASK inmask,
+  int inchannels,
+  FMOD_SPEAKERMODE speakermode
+);
+
+ +
delegate RESULT DSP_SHOULDIPROCESS_CALLBACK
+(
+  ref DSP_STATE dsp_state,
+  bool inputsidle,
+  uint length,
+  CHANNELMASK inmask,
+  int inchannels,
+  SPEAKERMODE speakermode
+);
+
+ +
function FMOD_DSP_SHOULDIPROCESS_CALLBACK(
+    dsp_state,
+    inputsidle,
+    length,
+    inmask,
+    inchannels,
+    speakermode
+)
+
+ +
+
dsp_state
+
DSP plug-in state. (FMOD_DSP_STATE)
+
inputsidle
+
+

This is true if no audio is being fed to this unit.

+
    +
  • Units: Boolean
  • +
+
+
length
+
+

Length of the incoming and outgoing buffer.

+
    +
  • Units: Samples
  • +
+
+
inmask
+
Deprecated. (FMOD_CHANNELMASK)
+
inchannels
+
Number of input channels.
+
speakermode
+
Speakermode that corresponds to the channel count and channel mask. (FMOD_SPEAKERMODE)
+
+

Invoked by:

+
    +
  • FMOD Mixer Thread. The callback is called automatically and periodically when the DSP engine updates.
  • +
+

Implementation Detail:

+

An example of an effect that would continue processing silence would be an echo or reverb effect that needs to play a tail sound until it fades out to silence. At that point it could return FMOD_ERR_DSP_SILENCE as well.

+

Typically inmask and speakermode parameters are not important to a plug-in unless it cares about speaker positioning. If it processes any data regardless of channel format coming in, it can safely ignore these two parameters.

+

If the effect produces silence such as when it is receiving no signal, then FMOD_ERR_DSP_SILENCE can be returned in the FMOD_DSP_SHOULDIPROCESS_CALLBACK callback. If the effect does not modify the sound in any way with the current effect parameter settings, then FMOD_ERR_DSP_DONTPROCESS can be returned.
+Either of these return values will cause FMOD's mixer to skip the FMOD_DSP_READ_CALLBACK callback.

+

NOTE: Effects that do not stop processing may keep the signal chain alive when it is not desirable. In the case of FMOD Studio, it may result in events that keep playing indefinitely.

+

The following code can be used for DSP effects that have no tail:

+
static FMOD_RESULT F_CALL shouldIProcess(FMOD_DSP_STATE *dsp_state, bool inputsidle, unsigned int length, FMOD_CHANNELMASK inmask, int inchannels, FMOD_SPEAKERMODE speakermode)
+{
+    if (inputsidle)
+    {
+        return FMOD_ERR_DSP_SILENCE;
+    }
+    return FMOD_OK;
+}
+
+ +

See Also: FMOD_DSP_READ_CALLBACK, FMOD_DSP_DESCRIPTION, FMOD_RESULT

+

FMOD_DSP_STATE

+

DSP plug-in structure that is passed into each callback.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
typedef struct FMOD_DSP_STATE {
+  void                      *instance;
+  void                      *plugindata;
+  FMOD_CHANNELMASK           channelmask;
+  FMOD_SPEAKERMODE           source_speakermode;
+  float                     *sidechaindata;
+  int                        sidechainchannels;
+  FMOD_DSP_STATE_FUNCTIONS   *functions;
+  int                        systemobject;
+} FMOD_DSP_STATE;
+
+ +
struct DSP_STATE
+{
+  IntPtr     instance;
+  IntPtr     plugindata;
+  uint       channelmask;
+  int        source_speakermode;
+  IntPtr     sidechaindata;
+  int        sidechainchannels;
+  IntPtr     functions;
+  int        systemobject;
+}
+
+ +
FMOD_DSP_STATE
+{
+  instance,
+  plugindata,
+  channelmask,
+  source_speakermode,
+  sidechaindata,
+  sidechainchannels,
+  functions,
+  systemobject,
+};
+
+ +
+
instance R/O
+
Internal instance pointer.
+
plugindata
+
Data that the plug-in writer wants to attach to this object.
+
channelmask R/O
+
Specifies which speakers the DSP effect is active on. (FMOD_CHANNELMASK)
+
source_speakermode R/O
+
Specifies which speaker mode the signal originated. (FMOD_SPEAKERMODE)
+
sidechaindata R/O
+
Sidechain mix result.
+
sidechainchannels R/O
+
Number of channels in the sidechain buffer.
+
functions R/O
+
Struct containing functions to give plug-in developers the ability to query system state and access system level functionality and helpers. (FMOD_DSP_STATE_FUNCTIONS)
+
systemobject R/O
+
FMOD::System object index, relating to the System object that created this DSP.
+
+

'systemobject' is an integer associated with the system object that created the DSP or registered the DSP plug-in. If there is only one system object, this integer is always 0. If the DSP was created or registered by a second system object, the integer would be 1, and so on.
+FMOD_DSP_STATE_FUNCTIONS::getsamplerate/getblocksize/getspeakermode could return different results, so it could be relevant to plug-in developers who want to monitor which object is being used.

+

Implementation Detail:

+

Unlike FMOD_DSP_DESCRIPTION::userdata, plugindata cannot be written to by the user, and is an ideal place to store the plug-in's state. The recommended pattern is to create the plugindata inside the FMOD_DSP_CREATE_CALLBACK, free it inside the FMOD_DSP_RELEASE_CALLBACK.

+

Here is an example of a simple oscillator that uses the plugindata to store the state required to generate a sine wave.

+
#define TWO_PI (2.0f * 3.14159265358979323846f)
+
+typedef struct
+{
+    unsigned int step[16];
+} dsp_data;
+
+FMOD_RESULT F_CALL Read(FMOD_DSP_STATE *dsp_state, float *inbuffer, float *outbuffer, unsigned int length, int inchannels, int *outchannels)
+{
+    dsp_data *data = (dsp_data *)dsp_state->plugindata;
+    int samplerate;
+    dsp_state->functions->getsamplerate(dsp_state, &samplerate);
+
+    for (unsigned int sample = 0; sample < length; sample++)
+    {
+        for (int channel = 0; channel < inchannels; channel++)
+        {
+            outbuffer[sample * *outchannels + channel] = sinf((440.0f * TWO_PI * data->step[channel]++) / (float)samplerate);
+        }
+    }
+
+    return FMOD_OK;
+}
+
+FMOD_RESULT F_CALL Create(FMOD_DSP_STATE *dsp_state)
+{
+    dsp_data *data = (dsp_data *)calloc(sizeof(dsp_data), 1);
+    if (!data)
+    {
+        return FMOD_ERR_MEMORY;
+    }
+    memset(data, 0, sizeof(data));
+    dsp_state->plugindata = data;
+
+    return FMOD_OK;
+}
+
+FMOD_RESULT F_CALL Release(FMOD_DSP_STATE *dsp_state)
+{
+    if (dsp_state->plugindata)
+    {
+        dsp_data *data = (dsp_data *)dsp_state->plugindata;
+        free(data);
+    }
+
+    return FMOD_OK;
+}
+
+ +
class dsp_data
+{
+    public uint[] step;
+}
+
+[AOT.MonoPInvokeCallback(typeof(FMOD.DSP_READ_CALLBACK))]
+static RESULT CaptureDSPReadCallback(ref FMOD.DSP_STATE dsp_state, IntPtr inbuffer, IntPtr outbuffer, uint length, int inchannels, ref int outchannels)
+{
+    float[] input = new float[length * inchannels];
+    float[] output = new float[length * outchannels];
+
+    GCHandle dataHandle = GCHandle.FromIntPtr(dsp_state.plugindata);
+    dsp_data data = dataHandle.Target as dsp_data;
+
+    int samplerate = 0;
+    dsp_state.functions.getsamplerate(ref dsp_state, ref samplerate);
+
+    for (int sample = 0; sample < length; sample++)
+    {
+        for (int channel = 0; channel < outchannels; channel++)
+        {
+            output[sample * outchannels + channel] = MathF.Sin((440.0f * MathF.PI * 2 * data.step[channel]++) / (float)samplerate);
+        }
+    }
+
+    Marshal.Copy(output, 0, outbuffer, (int)length * outchannels);
+
+    return RESULT.OK;
+}
+
+[AOT.MonoPInvokeCallback(typeof(FMOD.DSP_CREATE_CALLBACK))]
+static RESULT CaptureDSPCreateCallback(ref FMOD.DSP_STATE dsp_state)
+{
+    dsp_data data = new dsp_data();
+    data.step = new uint[16];
+    dsp_state.plugindata = GCHandle.ToIntPtr(GCHandle.Alloc(data));
+
+    return RESULT.OK;
+}
+
+[AOT.MonoPInvokeCallback(typeof(FMOD.DSP_RELEASE_CALLBACK))]
+static RESULT CaptureDSPReleaseCallback(ref FMOD.DSP_STATE dsp_state)
+{
+    GCHandle.FromIntPtr(dsp_state.plugindata).Free();
+
+    return RESULT.OK;
+}
+
+ +
function Read(dsp_state, inbuffer, outbuffer, length, inchannels, outchannels)
+{
+    let outval = {};
+    result = dsp_state.functions.getsamplerate(dsp_state, outval);
+    CHECK_RESULT(result);
+
+    for (var sample = 0; sample < length; sample++)
+    {
+        for (var channel = 0; channel < outchannels; channel++)
+        {
+            let val = Math.sin((440.0 * 2 * Math.PI * dsp_state.plugindata.step[channel]++) / outval.val);
+            FMOD.setValue(outbuffer + (((sample * outchannels) + channel) * 4), val, 'float');
+        }
+    }
+
+    return FMOD.OK;
+}
+
+function Create(dsp_state)
+{
+    dsp_state.plugindata =
+    {
+        step: []
+    };
+    for(let i = 0; i < 16; i++)
+    {
+        dsp_state.plugindata.step[i] = 0;
+    }
+
+    return FMOD.OK;
+}
+
+function Release(dsp_state)
+{
+    // No need to clean up memory in js
+    return FMOD.OK;
+}
+
+ +

See Also: FMOD_DSP_DESCRIPTION, FMOD_DSP_STATE_FUNCTIONS

+

FMOD_DSP_STATE_DFT_FUNCTIONS

+

Struct containing DFT functions to enable a plug-in to perform optimized time-frequency domain conversion.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
typedef struct FMOD_DSP_STATE_DFT_FUNCTIONS {
+  FMOD_DSP_DFT_FFTREAL_FUNC    fftreal;
+  FMOD_DSP_DFT_IFFTREAL_FUNC   inversefftreal;
+} FMOD_DSP_STATE_DFT_FUNCTIONS;
+
+ +
struct DSP_STATE_DFT_FUNCTIONS
+{
+  DSP_DFT_FFTREAL_FUNC  fftreal;
+  DSP_DFT_IFFTREAL_FUNC inversefftreal;
+}
+
+ +
+

Not supported for JavaScript.

+
+
+
fftreal R/O
+
Function for performing an FFT on a real signal. (FMOD_DSP_DFT_FFTREAL_FUNC)
+
inversefftreal R/O
+
Function for performing an inverse FFT to get a real signal. (FMOD_DSP_DFT_IFFTREAL_FUNC)
+
+

Implementation Detail:

+

All function pointers will remain valid for the lifetime of the system.

+

See Also: FMOD_DSP_STATE_FUNCTIONS, FFT

+

FMOD_DSP_STATE_FUNCTIONS

+

Struct containing functions to give plug-in developers the ability to query system state and access system level functionality and helpers.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
typedef struct FMOD_DSP_STATE_FUNCTIONS {
+  FMOD_DSP_ALLOC_FUNC                   alloc;
+  FMOD_DSP_REALLOC_FUNC                 realloc;
+  FMOD_DSP_FREE_FUNC                    free;
+  FMOD_DSP_GETSAMPLERATE_FUNC           getsamplerate;
+  FMOD_DSP_GETBLOCKSIZE_FUNC            getblocksize;
+  FMOD_DSP_STATE_DFT_FUNCTIONS         *dft;
+  FMOD_DSP_STATE_PAN_FUNCTIONS         *pan;
+  FMOD_DSP_GETSPEAKERMODE_FUNC          getspeakermode;
+  FMOD_DSP_GETCLOCK_FUNC                getclock;
+  FMOD_DSP_GETLISTENERATTRIBUTES_FUNC   getlistenerattributes;
+  FMOD_DSP_LOG_FUNC                     log;
+  FMOD_DSP_GETUSERDATA_FUNC             getuserdata;
+} FMOD_DSP_STATE_FUNCTIONS;
+
+ +
struct DSP_STATE_FUNCTIONS
+{
+  DSP_ALLOC_FUNC                  alloc;
+  DSP_REALLOC_FUNC                realloc;
+  DSP_FREE_FUNC                   free;
+  DSP_GETSAMPLERATE_FUNC          getsamplerate;
+  DSP_GETBLOCKSIZE_FUNC           getblocksize;
+  IntPtr                          dft;
+  IntPtr                          pan;
+  DSP_GETSPEAKERMODE_FUNC         getspeakermode;
+  DSP_GETCLOCK_FUNC               getclock;
+  DSP_GETLISTENERATTRIBUTES_FUNC  getlistenerattributes;
+  DSP_LOG_FUNC                    log;
+  DSP_GETUSERDATA_FUNC            getuserdata;
+}
+
+ +
DSP_STATE_FUNCTIONS
+{
+  getsamplerate,
+  getblocksize,
+  getspeakermode
+}
+
+ +
+
alloc R/O
+
Function to allocate memory using the FMOD memory system. (FMOD_DSP_ALLOC_FUNC)
+
realloc R/O
+
Function to reallocate memory using the FMOD memory system. (FMOD_DSP_REALLOC_FUNC)
+
free R/O
+
Function to free memory allocated with FMOD_DSP_ALLOC_FUNC. (FMOD_DSP_FREE_FUNC)
+
getsamplerate R/O
+
Function to query the system sample rate. (FMOD_DSP_GETSAMPLERATE_FUNC)
+
getblocksize R/O
+
Function to query the system block size. DSPs are requested to process blocks of varying length up to this size. (FMOD_DSP_GETBLOCKSIZE_FUNC)
+
dft R/O
+
Struct containing DFT functions to enable a plug-in to perform optimized time-frequency domain conversion. (FMOD_DSP_STATE_DFT_FUNCTIONS)
+
pan R/O
+
Struct containing panning helper functions for spatialization plug-ins. (FMOD_DSP_STATE_PAN_FUNCTIONS)
+
getspeakermode R/O
+
Function to query the system speaker modes. One is the mixer's default speaker mode, the other is the output mode the system is downmixing or upmixing to. (FMOD_DSP_GETSPEAKERMODE_FUNC)
+
getclock R/O
+
Function to get the clock of the current DSP, as well as the subset of the input buffer that contains the signal. (FMOD_DSP_GETCLOCK_FUNC)
+
getlistenerattributes R/O
+
Callback for getting the absolute listener attributes set via the API (returned as left-handed coordinates). (FMOD_DSP_GETLISTENERATTRIBUTES_FUNC)
+
log R/O
+
Function to write to the FMOD logging system. (FMOD_DSP_LOG_FUNC)
+
getuserdata R/O
+
Function to get the user data attached to this DSP. See FMOD_DSP_DESCRIPTION::userdata. (FMOD_DSP_GETUSERDATA_FUNC)
+
+

Implementation Detail:

+

All function pointers will remain valid for the lifetime of the system.

+

See Also: FMOD_DSP_STATE, FMOD_DSP_STATE_DFT_FUNCTIONS, FMOD_DSP_STATE_PAN_FUNCTIONS

+

FMOD_DSP_STATE_PAN_FUNCTIONS

+

Struct containing panning helper functions for spatialization plug-ins.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
typedef struct FMOD_DSP_STATE_PAN_FUNCTIONS {
+  FMOD_DSP_PAN_SUMMONOMATRIX_FUNC               summonomatrix;
+  FMOD_DSP_PAN_SUMSTEREOMATRIX_FUNC             sumstereomatrix;
+  FMOD_DSP_PAN_SUMSURROUNDMATRIX_FUNC           sumsurroundmatrix;
+  FMOD_DSP_PAN_SUMMONOTOSURROUNDMATRIX_FUNC     summonotosurroundmatrix;
+  FMOD_DSP_PAN_SUMSTEREOTOSURROUNDMATRIX_FUNC   sumstereotosurroundmatrix;
+  FMOD_DSP_PAN_GETROLLOFFGAIN_FUNC              getrolloffgain;
+} FMOD_DSP_STATE_PAN_FUNCTIONS;
+
+ +
struct DSP_STATE_PAN_FUNCTIONS
+{
+  DSP_PAN_SUMMONOMATRIX_FUNC             summonomatrix;
+  DSP_PAN_SUMSTEREOMATRIX_FUNC           sumstereomatrix;
+  DSP_PAN_SUMSURROUNDMATRIX_FUNC         sumsurroundmatrix;
+  DSP_PAN_SUMMONOTOSURROUNDMATRIX_FUNC   summonotosurroundmatrix;
+  DSP_PAN_SUMSTEREOTOSURROUNDMATRIX_FUNC sumstereotosurroundmatrix;
+  DSP_PAN_GETROLLOFFGAIN_FUNC            getrolloffgain;
+}
+
+ +
+

Not supported for JavaScript.

+
+
+
summonomatrix R/O
+
Function to calculate a mono mix matrix scaled by the gain value. (FMOD_DSP_PAN_SUMMONOMATRIX_FUNC)
+
sumstereomatrix R/O
+
Function to calculate a stereo mix matrix with given pan and gain values. (FMOD_DSP_PAN_SUMSTEREOMATRIX_FUNC)
+
sumsurroundmatrix R/O
+
Function to calculate a surround mix matrix with the given positional information. (FMOD_DSP_PAN_SUMSURROUNDMATRIX_FUNC)
+
summonotosurroundmatrix R/O
+
Function to calculate a surround mix matrix for mono input signals. (FMOD_DSP_PAN_SUMMONOTOSURROUNDMATRIX_FUNC)
+
sumstereotosurroundmatrix R/O
+
Function to calculate a surround mix matrix for stereo input signals. (FMOD_DSP_PAN_SUMSTEREOTOSURROUNDMATRIX_FUNC)
+
getrolloffgain R/O
+
Function to calculate distance attenuation. (FMOD_DSP_PAN_GETROLLOFFGAIN_FUNC)
+
+

Implementation Detail:

+

All function pointers will remain valid for the lifetime of the system.

+

See Also: FMOD_DSP_STATE_FUNCTIONS, FMOD_DSP_PAN_SURROUND_FLAGS, ChannelControl::setMixMatrix

+

FMOD_DSP_SYSTEM_DEREGISTER_CALLBACK

+

System level DSP type deregister callback.

+

The callback is called as a one time deregistration of a DSP plug-in type, rather than of an individual DSP instance.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
FMOD_RESULT F_CALL FMOD_DSP_SYSTEM_DEREGISTER_CALLBACK(
+  FMOD_DSP_STATE *dsp_state
+);
+
+ +
delegate RESULT DSP_SYSTEM_DEREGISTER_CALLBACK
+(
+  ref DSP_STATE dsp_state
+);
+
+ +
function FMOD_DSP_SYSTEM_DEREGISTER_CALLBACK(
+    dsp_state
+)
+
+ +
+
dsp_state
+
A partially-valid DSP plug-in state object with a null instance pointer. (FMOD_DSP_STATE)
+
+

Invoked by:

+ +

This callback is called after all instances of the plug-in type have been released.

+

The callback is not associated with any DSP instance, so the instance member of FMOD_DSP_STATE will be 0 / NULL. Only 'systemobject' and 'callbacks' are valid for use.

+

See Also: FMOD_DSP_DESCRIPTION

+

FMOD_DSP_SYSTEM_MIX_CALLBACK

+

System level DSP type mix callback.

+

The function can be used as a global pre/mid/post mix function for this type of DSP, rather than of an individual DSP instance.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
FMOD_RESULT F_CALL FMOD_DSP_SYSTEM_MIX_CALLBACK(
+  FMOD_DSP_STATE *dsp_state,
+  int stage
+);
+
+ +
delegate RESULT DSP_SYSTEM_MIX_CALLBACK
+(
+  ref DSP_STATE dsp_state,
+  int stage
+);
+
+ +
function FMOD_DSP_SYSTEM_MIX_CALLBACK(
+    dsp_state,
+    stage
+)
+
+ +
+
dsp_state
+
A partially-valid DSP plug-in state object with a null instance pointer. (FMOD_DSP_STATE)
+
stage
+
0 = premix, or before the mixer has executed. 1 = postmix, or after the mix has been executed. 2 = midmix, after clocks calculation before the main mix has occurred.
+
+

Invoked by:

+
    +
  • FMOD Mixer Thread. The callback is called automatically and periodically when the DSP engine updates.
  • +
+

The callback is not associated with any DSP instance, so the instance member of FMOD_DSP_STATE will be 0 / NULL. Only 'systemobject' and 'callbacks' are valid for use.
+The callback is triggered automatically by the mixer and is not triggered by any API function.

+

See Also: FMOD_DSP_DESCRIPTION

+

FMOD_DSP_SYSTEM_REGISTER_CALLBACK

+

System level DSP type registration callback.

+

The callback is called as a one time initialization to set up the DSP plug-in type, rather than of an individual DSP instance.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
FMOD_RESULT F_CALL FMOD_DSP_SYSTEM_REGISTER_CALLBACK(
+  FMOD_DSP_STATE *dsp_state
+);
+
+ +
delegate RESULT DSP_SYSTEM_REGISTER_CALLBACK
+(
+  ref DSP_STATE dsp_state
+);
+
+ +
function FMOD_DSP_SYSTEM_REGISTER_CALLBACK(
+    dsp_state
+)
+
+ +
+
dsp_state
+
A partially-valid DSP plug-in state object with a null instance pointer. (FMOD_DSP_STATE)
+
+

Invoked by:

+ +

This callback is called before any instances of the plug-in type have been created.

+

The callback is not associated with any DSP instance, so the instance member of FMOD_DSP_STATE will be 0 / NULL. Only 'systemobject' and 'callbacks' are valid for use.

+

See Also: FMOD_DSP_DESCRIPTION

+

FMOD_PLUGIN_SDK_VERSION

+

The plug-in SDK version.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
#define FMOD_PLUGIN_SDK_VERSION   110
+
+ +
FMOD.PLUGIN_SDK_VERSION = 110
+
+ +
+

Currently not supported for C#.

+
+

See Also: FMOD_DSP_DESCRIPTION

+ + +
+ + + diff --git a/FMOD/doc/FMOD API User Manual/plugin-api-output.html b/FMOD/doc/FMOD API User Manual/plugin-api-output.html new file mode 100644 index 0000000..06fec7e --- /dev/null +++ b/FMOD/doc/FMOD API User Manual/plugin-api-output.html @@ -0,0 +1,1174 @@ + + +Plug-in API Reference | Output + + + + +
+ +
+

19. Plug-in API Reference | Output

+

An interface that manages output plug-ins.

+

Object 3D:

+ +
+ +

General:

+ +
+ +
+ +
+ +

FMOD_OUTPUT_ALLOC_FUNC

+

Output allocate memory function.

+

+

+
C
+
C++
+
JS
+
+

+
void * F_CALL FMOD_OUTPUT_ALLOC_FUNC(
+  unsigned int size,
+  unsigned int align,
+  const char *file,
+  int line
+);
+
+ +
+

Not supported for C#.

+
+
+

Not supported for JavaScript.

+
+
+
size
+
+

Allocation size.

+
    +
  • Units: Bytes
  • +
+
+
align
+
+

Memory alignment.

+
    +
  • Units: Bytes
  • +
+
+
file
+
Source code file name where the allocation was requested.
+
line
+
Line of allocation in file.
+
+

See Also: FMOD_OUTPUT_STATE

+

FMOD_OUTPUT_CLOSEPORT_CALLBACK

+

Output close port callback.

+

+

+
C
+
C++
+
JS
+
+

+
FMOD_RESULT F_CALL FMOD_OUTPUT_CLOSEPORT_CALLBACK(
+  FMOD_OUTPUT_STATE *output_state,
+  int portId
+);
+
+ +
+

Not supported for C#.

+
+
+

Not supported for JavaScript.

+
+
+
output_state
+
Plug-in state. (FMOD_OUTPUT_STATE)
+
portId
+
Port ID.
+
+

Main thread callback to close an auxiliary output port on the device.

+

See Also: FMOD_OUTPUT_DESCRIPTION

+

FMOD_OUTPUT_CLOSE_CALLBACK

+

Output close callback.

+

This callback is called to shut down and release the output driver's audio interface.

+

+

+
C
+
C++
+
JS
+
+

+
FMOD_RESULT F_CALL FMOD_OUTPUT_CLOSE_CALLBACK(
+  FMOD_OUTPUT_STATE *output_state
+);
+
+ +
+

Not supported for C#.

+
+
+

Not supported for JavaScript.

+
+
+
output_state
+
Plug-in state. (FMOD_OUTPUT_STATE)
+
+

Invoked by:

+ +

To stop the output stream, rather than closing and shutting it down, FMOD_OUTPUT_STOP_CALLBACK would be used.

+

See Also: FMOD_OUTPUT_DESCRIPTION

+

FMOD_OUTPUT_COPYPORT_FUNC

+

Output copy port function.

+

Function to copy the output from the mixer for the given auxiliary port.

+

+

+
C
+
C++
+
JS
+
+

+
FMOD_RESULT F_CALL FMOD_OUTPUT_COPYPORT_FUNC(
+  FMOD_OUTPUT_STATE *output_state,
+  int portId,
+  void *buffer,
+  unsigned int length
+);
+
+ +
+

Not supported for C#.

+
+
+

Not supported for JavaScript.

+
+
+
output_state
+
Plug-in state. (FMOD_OUTPUT_STATE)
+
portId
+
Auxiliary port.
+
buffer
+
Output buffer.
+
length
+
Length of buffer
+
+

See Also: FMOD_OUTPUT_STATE

+

FMOD_OUTPUT_DESCRIPTION

+

Output description.

+

This description structure allows the plug-in writer to define all functionality required for a user-defined output device.

+

+

+
C
+
C++
+
JS
+
+

+
typedef struct FMOD_OUTPUT_DESCRIPTION {
+  unsigned int                           apiversion;
+  const char                            *name;
+  unsigned int                           version;
+  FMOD_OUTPUT_METHOD                     method;
+  FMOD_OUTPUT_GETNUMDRIVERS_CALLBACK     getnumdrivers;
+  FMOD_OUTPUT_GETDRIVERINFO_CALLBACK     getdriverinfo;
+  FMOD_OUTPUT_INIT_CALLBACK              init;
+  FMOD_OUTPUT_START_CALLBACK             start;
+  FMOD_OUTPUT_STOP_CALLBACK              stop;
+  FMOD_OUTPUT_CLOSE_CALLBACK             close;
+  FMOD_OUTPUT_UPDATE_CALLBACK            update;
+  FMOD_OUTPUT_GETHANDLE_CALLBACK         gethandle;
+  FMOD_OUTPUT_MIXER_CALLBACK             mixer;
+  FMOD_OUTPUT_OBJECT3DGETINFO_CALLBACK   object3dgetinfo;
+  FMOD_OUTPUT_OBJECT3DALLOC_CALLBACK     object3dalloc;
+  FMOD_OUTPUT_OBJECT3DFREE_CALLBACK      object3dfree;
+  FMOD_OUTPUT_OBJECT3DUPDATE_CALLBACK    object3dupdate;
+  FMOD_OUTPUT_OPENPORT_CALLBACK          openport;
+  FMOD_OUTPUT_CLOSEPORT_CALLBACK         closeport;
+  FMOD_OUTPUT_DEVICELISTCHANGED_CALLBACK devicelistchanged;
+} FMOD_OUTPUT_DESCRIPTION;
+
+ +
FMOD_OUTPUT_DESCRIPTION
+{
+  apiversion,
+  name,
+  version,
+  method,
+  getnumdrivers,
+  getdriverinfo,
+  init,
+  start,
+  stop,
+  close,
+  update,
+  gethandle,
+  mixer,
+  object3dgetinfo,
+  object3dalloc,
+  object3dfree,
+  object3dupdate,
+  openport,
+  closeport,
+  devicelistchanged
+};
+
+ +
+

Not supported for C#.

+
+
+
apiversion
+
The output plug-in API version this plug-in is built for. Set to this to FMOD_OUTPUT_PLUGIN_VERSION.
+
name
+
The name of the output plug-in, encoded as a UTF-8 string.
+
version
+
The version of the output plug-in.
+
method
+
The method by which the mixer is executed and buffered. (FMOD_OUTPUT_METHOD)
+
getnumdrivers
+
A user thread callback to provide the number of attached sound devices. Called from System::getNumDrivers. (FMOD_OUTPUT_GETNUMDRIVERS_CALLBACK)
+
getdriverinfo
+
A user thread callback to provide information about a particular sound device. Called from System::getDriverInfo. (FMOD_OUTPUT_GETDRIVERINFO_CALLBACK)
+
init
+
A user thread callback to allocate resources and provide information about hardware capabilities. Called from System::init. (FMOD_OUTPUT_INIT_CALLBACK)
+
start Opt
+
A user thread callback just before mixing should begin, calls to FMOD_OUTPUT_MIXER_CALLBACK will start, you may call FMOD_OUTPUT_READFROMMIXER_FUNC after this point. Called from System::init. (FMOD_OUTPUT_START_CALLBACK)
+
stop Opt
+
A user thread callback just after mixing has finished, calls to FMOD_OUTPUT_MIXER_CALLBACK have stopped, you may not call FMOD_OUTPUT_READFROMMIXER_FUNC after this point. Called from System::close. (FMOD_OUTPUT_STOP_CALLBACK)
+
close Opt
+
A user thread callback to clean up resources allocated during FMOD_OUTPUT_INIT_CALLBACK. Called from System::init and System::close. (FMOD_OUTPUT_CLOSE_CALLBACK)
+
update Opt
+
A user thread callback once per frame to update internal state. Called from System::update. (FMOD_OUTPUT_UPDATE_CALLBACK)
+
gethandle Opt
+
A user thread callback to provide a pointer to the internal device object used to share with other audio systems. Called from System::getOutputHandle. (FMOD_OUTPUT_GETHANDLE_CALLBACK)
+
mixer Opt
+
A mixer thread callback called repeatedly to give a thread for waiting on an audio hardware synchronization primitive (see remarks for details). Ensure you have a reasonable timeout (~200ms) on your synchronization primitive and allow this callback to return once per wakeup to avoid deadlocks. (FMOD_OUTPUT_MIXER_CALLBACK)
+
object3dgetinfo Opt
+
A mixer thread callback to provide information about the capabilities of 3D object hardware. Called during a mix. (FMOD_OUTPUT_OBJECT3DGETINFO_CALLBACK)
+
object3dalloc Opt
+
A mixer thread callback to reserve a hardware resources for a single 3D object. Called during a mix. (FMOD_OUTPUT_OBJECT3DALLOC_CALLBACK)
+
object3dfree Opt
+
A mixer thread callback to release a hardware resource previously acquired with FMOD_OUTPUT_OBJECT3DALLOC_CALLBACK. Called during a mix. (FMOD_OUTPUT_OBJECT3DFREE_CALLBACK)
+
object3dupdate Opt
+
A mixer thread callback once for every acquired 3D object every mix to provide 3D information and buffered audio. Called during a mix. (FMOD_OUTPUT_OBJECT3DUPDATE_CALLBACK)
+
openport Opt
+
A main thread callback to open an auxiliary output port on the device. (FMOD_OUTPUT_OPENPORT_CALLBACK)
+
closeport Opt
+
A main thread callback to close an auxiliary output port on the device. (FMOD_OUTPUT_CLOSEPORT_CALLBACK)
+
devicelistchanged Opt
+
A main thread callback to notify that a change to the device list may have occurred. (FMOD_OUTPUT_DEVICELISTCHANGED_CALLBACK)
+
+

Pass this structure to System::registerOutput to create a new output type, or if defining a dynamically loadable plug-in, return it in a function called FMODGetOutputDescription. FMOD's plug-in loader will look for this function in a dynamic library.

+
/*
+    Plug-in setup example
+*/
+extern "C" FMOD_OUTPUT_DESCRIPTION* F_CALL FMODGetOutputDescription()
+{
+    static FMOD_OUTPUT_DESCRIPTION desc;
+
+    /*
+        Fill members of structure
+    */
+
+    return &desc;
+}
+
+ +

There are several methods for driving the FMOD mixer to service the audio hardware.

+ +

Callbacks marked with 'user thread' will be called in response to the user of the Core API. In the case of the Studio API, the user is the Studio update thread.

+

See Also: FMOD_OUTPUT_STATE

+

FMOD_OUTPUT_DEVICELISTCHANGED_CALLBACK

+

Output device list change callback.

+

+

+
C
+
C++
+
JS
+
+

+
FMOD_RESULT F_CALL FMOD_OUTPUT_DEVICELISTCHANGED_CALLBACK(
+  FMOD_OUTPUT_STATE *output_state
+);
+
+ +
+

Not supported for C#.

+
+
+

Not supported for JavaScript.

+
+
+
output_state
+
Plug-in state. (FMOD_OUTPUT_STATE)
+
+

See Also: FMOD_OUTPUT_DESCRIPTION

+

FMOD_OUTPUT_FREE_FUNC

+

Output free memory function.

+

+

+
C
+
C++
+
JS
+
+

+
void F_CALL FMOD_OUTPUT_FREE_FUNC(
+  void *ptr,
+  const char *file,
+  int line
+);
+
+ +
+

Not supported for C#.

+
+
+

Not supported for JavaScript.

+
+
+
ptr
+
Allocation pointer.
+
file
+
Source code file name where the allocation is freed.
+
line
+
Line of free call in file.
+
+

See Also: FMOD_OUTPUT_STATE

+

FMOD_OUTPUT_GETDRIVERINFO_CALLBACK

+

Output get driver info callback.

+

This callback is called to provide the user with information about the selected audio driver.

+

+

+
C
+
C++
+
JS
+
+

+
FMOD_RESULT F_CALL FMOD_OUTPUT_GETDRIVERINFO_CALLBACK(
+  FMOD_OUTPUT_STATE *output_state,
+  int id,
+  char *name,
+  int namelen,
+  FMOD_GUID *guid,
+  int *systemrate,
+  FMOD_SPEAKERMODE *speakermode,
+  int *speakermodechannels
+);
+
+ +
+

Not supported for C#.

+
+
+

Not supported for JavaScript.

+
+
+
output_state
+
Plug-in state. (FMOD_OUTPUT_STATE)
+
id
+
The index into the total number of outputs possible, provided by the FMOD_OUTPUT_GETNUMDRIVERS_CALLBACK callback.
+
name
+
The driver name relevant to the index passed in. Fill this in. (UTF-8 string)
+
namelen
+
+

The length of name buffer being passed in by the user.

+
    +
  • Units: Bytes
  • +
+
+
guid
+
The GUID structure. (FMOD_GUID)
+
systemrate Opt
+
+

The rate the output device prefers. Leave 0 to remain flexible.

+
    +
  • Units: Hertz
  • +
+
+
speakermode Opt
+
The speaker mode the output device prefers. Leave FMOD_SPEAKERMODE_DEFAULT to remain flexible. (FMOD_SPEAKERMODE)
+
speakermodechannels Opt
+
The speaker mode associated channels the output device prefers. Leave at 0 to remain flexible. Only used for FMOD_SPEAKERMODE_RAW.
+
+

Invoked by:

+ +

See Also: System::getNumDrivers, FMOD_OUTPUT_DESCRIPTION, System::getNumDrivers, FMOD_OUTPUT_GETNUMDRIVERS_CALLBACK

+

FMOD_OUTPUT_GETHANDLE_CALLBACK

+

Output get output handle callback.

+

This callback is called to provide the user with a low level audio interface handle that may be used to pass to other middleware.

+

+

+
C
+
C++
+
JS
+
+

+
FMOD_RESULT F_CALL FMOD_OUTPUT_GETHANDLE_CALLBACK(
+  FMOD_OUTPUT_STATE *output_state,
+  void **handle
+);
+
+ +
+

Not supported for C#.

+
+
+

Not supported for JavaScript.

+
+
+
output_state
+
Plug-in state. (FMOD_OUTPUT_STATE)
+
handle Out
+
Plug-in's output 'handle'.
+
+

Invoked by:

+ +

This callback is only needed if the plug-in writer wants to allow the user access to the main handle behind the plug-in (for example the file handle in a file writer plug-in). The plug-in writer needs to document and publish the type of the handle, as is done in the documentation for System::getOutputHandle.

+

See Also: FMOD_OUTPUT_DESCRIPTION

+

FMOD_OUTPUT_GETNUMDRIVERS_CALLBACK

+

Output get number of drivers callback.

+

This callback is called to provide the user with the number of devices usable for the output mode.

+

+

+
C
+
C++
+
JS
+
+

+
FMOD_RESULT F_CALL FMOD_OUTPUT_GETNUMDRIVERS_CALLBACK(
+  FMOD_OUTPUT_STATE *output_state,
+  int *numdrivers
+);
+
+ +
+

Not supported for C#.

+
+
+

Not supported for JavaScript.

+
+
+
output_state
+
Plug-in state. (FMOD_OUTPUT_STATE)
+
numdrivers
+
Number of output drivers in your plug-in.
+
+

Invoked by:

+ +

Optional. FMOD will assume 0 if this is not specified.

+

See Also: FMOD_OUTPUT_DESCRIPTION, System::getDriverInfo, FMOD_OUTPUT_GETDRIVERINFO_CALLBACK

+

FMOD_OUTPUT_INIT_CALLBACK

+

Output initialization callback.

+

This callback is called to allow initialization of the output stream for mixing.

+

+

+
C
+
C++
+
JS
+
+

+
FMOD_RESULT F_CALL FMOD_OUTPUT_INIT_CALLBACK(
+  FMOD_OUTPUT_STATE *output_state,
+  int selecteddriver,
+  FMOD_INITFLAGS flags,
+  int *outputrate,
+  FMOD_SPEAKERMODE *speakermode,
+  int *speakermodechannels,
+  FMOD_SOUND_FORMAT *outputformat,
+  int dspbufferlength,
+  int *dspnumbuffers,
+  int *dspnumadditionalbuffers,
+  void *extradriverdata
+);
+
+ +
+

Not supported for C#.

+
+
+

Not supported for JavaScript.

+
+
+
output_state
+
Plug-in state. (FMOD_OUTPUT_STATE)
+
selecteddriver
+
Selected driver id that the user chose from calling System::setDriver.
+
flags
+
Initialization flags passed in by the user. (FMOD_INITFLAGS)
+
outputrate
+
+

Output rate selected by the user. If not possible, change the rate to the closest match. FMOD will resample from the rate requested to your rate if they do not match.

+
    +
  • Units: Hertz
  • +
+
+
speakermode
+
Speaker mode selected by the user. If not possible, change the speaker mode to the closest match. FMOD will upmix or downmix to the requested speaker mode if they do not match. (FMOD_SPEAKERMODE)
+
speakermodechannels
+
Speaker mode channel count selected by the user. For example 1 = mono output. 2 = stereo output. Needed if supporting FMOD_SPEAKERMODE_RAW, otherwise it is informational.
+
outputformat
+
Sound format supported by output mode. For example, FMOD_SOUND_FORMAT_PCM16 would be normal. FMOD will convert from FMOD_SOUND_FORMAT_PCMFLOAT (the mixer buffer format) to whatever you specify. (FMOD_SOUND_FORMAT)
+
dspbufferlength
+
+

Size of the buffer fmod will mix to in one mix update.

+
    +
  • Units: Samples
  • +
+
+
dspnumbuffers
+
The number of buffers the FMOD Engine mixes the signal to in a circular fashion. Multiply this by dspbufferlength to get the total size of the output sound buffer to allocate. This can be set by the plug-in when FMOD_OUTPUT_DESCRIPTION::method is set to FMOD_OUTPUT_METHOD_MIX_BUFFERED.
+
dspnumadditionalbuffers Out
+
Number of additional buffers that a plug-in with FMOD_OUTPUT_DESCRIPTION::method set to FMOD_OUTPUT_METHOD_MIX_BUFFERED requires. These will be allocated up front to allow the number of used buffers to grow when an internal buffer starvation is detected.
+
extradriverdata
+
Data passed in by the user specific to this driver.
+
+

Invoked by:

+ +

See Also: FMOD_OUTPUT_DESCRIPTION, System::setDriver

+

FMOD_OUTPUT_LOG_FUNC

+

Output log function.

+

Call this function in an output plug-in context to utilize the FMOD Engine's debugging system.

+

+

+
C
+
C++
+
JS
+
+

+
void F_CALL FMOD_OUTPUT_LOG_FUNC(
+  FMOD_DEBUG_FLAGS level,
+  const char *file,
+  int line,
+  const char *function,
+  const char *string,
+  ...
+);
+
+ +
+

Not supported for C#.

+
+
+

Not supported for JavaScript.

+
+
+
level
+
Log type or level. (FMOD_DEBUG_FLAGS)
+
file
+
Source code file name from where the log is called. (UTF-8 string)
+
line
+
Line of log call in file.
+
function
+
Name of the logging function. (UTF-8 string)
+
string
+
Log output string. (UTF-8 string)
+
+

See Also: FMOD_OUTPUT_STATE

+

FMOD_OUTPUT_METHOD

+

Output method used to interact with the mixer.

+

+

+
C
+
C++
+
JS
+
+

+
#define FMOD_OUTPUT_METHOD_MIX_DIRECT    0
+#define FMOD_OUTPUT_METHOD_MIX_BUFFERED  2
+
+ +
OUTPUT_METHOD_MIX_DIRECT    = 0
+OUTPUT_METHOD_MIX_BUFFERED  = 1
+
+ +
+

Not supported for C#.

+
+
+
FMOD_OUTPUT_METHOD_MIX_DIRECT
+
When calling FMOD_OUTPUT_READFROMMIXER_FUNC, the mixer executes directly. Buffering must be performed by plug-in code.
+
FMOD_OUTPUT_METHOD_MIX_BUFFERED
+
Mixer will execute and buffer automatically (on a separate thread) and can be read from with FMOD_OUTPUT_READFROMMIXER_FUNC.
+
+

For hardware that presents a callback that must be filled immediately FMOD_OUTPUT_METHOD_MIX_BUFFERED is recommended as buffering occurs in a separate thread, reading from the mixer is simply a memcpy. Using FMOD_OUTPUT_METHOD_MIX_DIRECT is recommended if you want to take direct control of how and when the mixer runs.

+

See Also: FMOD_OUTPUT_DESCRIPTION

+

FMOD_OUTPUT_MIXER_CALLBACK

+

Output mixer callback.

+

This callback can be used to stall the FMOD mixer thread until it is ready to call the FMOD mixer directly.

+

+

+
C
+
C++
+
JS
+
+

+
FMOD_RESULT F_CALL FMOD_OUTPUT_MIXER_CALLBACK(
+  FMOD_OUTPUT_STATE *output_state
+);
+
+ +
+

Not supported for C#.

+
+
+

Not supported for JavaScript.

+
+
+
output_state
+
Plug-in state. (FMOD_OUTPUT_STATE)
+
+

Invoked by:

+ +

This callback must use the FMOD_OUTPUT_READFROMMIXER_FUNC function to produce the audio stream needed by the output.

+

This callback is optional in FMOD_OUTPUT_METHOD_MIX_DIRECT or FMOD_OUTPUT_METHOD_MIX_BUFFERED mode. An output mode may avoid this callback, and instead use its own timing system to call the FMOD mixer with FMOD_OUTPUT_READFROMMIXER_FUNC.

+

If this callback is used, it will be triggered immediately from the FMOD mixer thread. The callback can then stall with its own synchronization primitive (ie a wait on a semaphore), until something else signals the primitive to execute a mix with FMOD_OUTPUT_READFROMMIXER_FUNC.

+

Ensure you have a reasonable timeout (~200ms) on your synchronization primitive and allow this callback to return regularly, to avoid deadlocks.

+

See Also: FMOD_OUTPUT_DESCRIPTION, FMOD_OUTPUT_STATE

+

FMOD_OUTPUT_OBJECT3DALLOC_CALLBACK

+

Output 3D Object alloc callback.

+

This callback is called to reserve hardware resources for a single 3D object.

+

+

+
C
+
C++
+
JS
+
+

+
FMOD_RESULT F_CALL FMOD_OUTPUT_OBJECT3DALLOC_CALLBACK(
+  FMOD_OUTPUT_STATE *output_state,
+  void **object3d
+);
+
+ +
+

Not supported for C#.

+
+
+

Not supported for JavaScript.

+
+
+
output_state
+
Plug-in state. (FMOD_OUTPUT_STATE)
+
object3d
+
3D audio object.
+
+

Invoked by:

+
    +
  • FMOD mixer thread.
  • +
+

This callback is used for 'Object based audio' where sound hardware can receive individual audio streams and position them in 3D space natively, separate from the FMOD mixer. A typical implementation would be something like Dolby Atmos or Playstation VR.

+

See Also: FMOD_OUTPUT_DESCRIPTION, FMOD_OUTPUT_OBJECT3DGETINFO_CALLBACK, FMOD_OUTPUT_OBJECT3DFREE_CALLBACK, FMOD_OUTPUT_OBJECT3DUPDATE_CALLBACK

+

FMOD_OUTPUT_OBJECT3DFREE_CALLBACK

+

Output 3D Object free callback.

+

This callback is called to release a hardware resource previously acquired with FMOD_OUTPUT_OBJECT3DALLOC_CALLBACK.

+

+

+
C
+
C++
+
JS
+
+

+
FMOD_RESULT F_CALL FMOD_OUTPUT_OBJECT3DFREE_CALLBACK(
+  FMOD_OUTPUT_STATE *output_state,
+  void *object3d
+);
+
+ +
+

Not supported for C#.

+
+
+

Not supported for JavaScript.

+
+
+
output_state
+
Plug-in state. (FMOD_OUTPUT_STATE)
+
object3d
+
3D audio object.
+
+

Invoked by:

+
    +
  • FMOD mixer thread.
  • +
+

This callback is used for 'Object based audio' where sound hardware can receive individual audio streams and position them in 3D space natively, separate from the FMOD mixer. A typical implementation would be something like Dolby Atmos or Atmos or Playstation VR.

+

See Also: FMOD_OUTPUT_DESCRIPTION, FMOD_OUTPUT_OBJECT3DGETINFO_CALLBACK, FMOD_OUTPUT_OBJECT3DALLOC_CALLBACK, FMOD_OUTPUT_OBJECT3DUPDATE_CALLBACK

+

FMOD_OUTPUT_OBJECT3DGETINFO_CALLBACK

+

Output 3D Object get info callback.

+

Called from the mixer thread to provide information about the capabilities of 3D object hardware.

+

+

+
C
+
C++
+
JS
+
+

+
FMOD_RESULT F_CALL FMOD_OUTPUT_OBJECT3DGETINFO_CALLBACK(
+  FMOD_OUTPUT_STATE *output_state,
+  int *maxhardwareobjects
+);
+
+ +
+

Not supported for C#.

+
+
+

Not supported for JavaScript.

+
+
+
output_state
+
Plug-in state. (FMOD_OUTPUT_STATE)
+
maxhardwareobjects
+
Maximum number of 3D objects supported.
+
+

Invoked by:

+
    +
  • FMOD mixer thread.
  • +
+

This callback is used for 'Object based audio' where sound hardware can receive individual audio streams and position them in 3D space natively, separate from the FMOD mixer. A typical implementation would be something like Dolby Atmos or Atmos or Playstation VR.

+

See Also: FMOD_OUTPUT_DESCRIPTION, FMOD_OUTPUT_OBJECT3DALLOC_CALLBACK, FMOD_OUTPUT_OBJECT3DFREE_CALLBACK, FMOD_OUTPUT_OBJECT3DUPDATE_CALLBACK

+

FMOD_OUTPUT_OBJECT3DINFO

+

Output 3D Object Info.

+

+

+
C
+
C++
+
JS
+
+

+
typedef struct FMOD_OUTPUT_OBJECT3DINFO {
+  float         *buffer;
+  unsigned int   bufferlength;
+  FMOD_VECTOR    position;
+  float          gain;
+  float          spread;
+  float          priority;
+} FMOD_OUTPUT_OBJECT3DINFO;
+
+ +
FMOD_OUTPUT_OBJECT3DINFO
+{
+  buffer,
+  bufferlength,
+  position,
+  gain,
+  spread,
+  priority,
+};
+
+ +
+

Not supported for C#.

+
+
+
buffer R/O
+
Mono PCM floating point buffer. This buffer needs to be scaled by the gain value to get distance attenuation.
+
bufferlength R/O
+
Length in PCM samples of buffer.
+
position R/O
+
Vector relative between object and listener. (FMOD_VECTOR)
+
gain R/O
+
0.0 to 1.0 - 1 = 'buffer' is not attenuated, 0 = 'buffer' is fully attenuated.
+
spread R/O
+
0 - 360 degrees. 0 = point source, 360 = sound is spread around all speakers
+
priority R/O
+
0.0 to 1.0 - 0 = most important, 1 = least important. Based on height and distance (height is more important).
+
+

This callback is used for 'Object mixing' where sound hardware can receive individual audio streams and position them in 3D space natively, separate from the FMOD mixer. A typical implementation would be something like Dolby Atmos or Atmos or Playstation VR.

+

This structure is passed to the plug-in via FMOD_OUTPUT_OBJECT3DUPDATE_CALLBACK, so that any object-based panning solution available can position it in the speakers correctly.
+Object based panning is a 3D panning solution that sends a mono-only signal to a hardware device, such as Dolby Atmos or other similar panning solutions.

+

FMOD does not attenuate the buffer, but provides a 'gain' parameter that the user must use to scale the buffer by. Rather than pre-attenuating the buffer, the plug-in developer can access untouched data for other purposes, like reverb sending for example.
+The 'gain' parameter is based on the user's 3D custom roll-off model.

+

See Also: FMOD_OUTPUT_OBJECT3DUPDATE_CALLBACK

+

FMOD_OUTPUT_OBJECT3DUPDATE_CALLBACK

+

Output 3D Object update callback.

+

Called from the mixer thread once for every acquired 3D object every mix to provide 3D information and buffered audio.

+

+

+
C
+
C++
+
JS
+
+

+
FMOD_RESULT F_CALL FMOD_OUTPUT_OBJECT3DUPDATE_CALLBACK(
+  FMOD_OUTPUT_STATE *output_state,
+  void *object3d,
+  const FMOD_OUTPUT_OBJECT3DINFO *info
+);
+
+ +
+

Not supported for C#.

+
+
+

Not supported for JavaScript.

+
+
+
output_state
+
Plug-in state. (FMOD_OUTPUT_STATE)
+
object3d
+
3D audio object.
+
info
+
3D object characteristics. (FMOD_OUTPUT_OBJECT3DINFO)
+
+

Invoked by:

+
    +
  • FMOD mixer
  • +
+

This callback is used for 'Object based audio' where sound hardware can receive individual audio streams and position them in 3D space natively, separate from the FMOD mixer. A typical implementation would be something like Dolby Atmos or Atmos or Playstation VR.

+

See Also: FMOD_OUTPUT_DESCRIPTION, FMOD_OUTPUT_OBJECT3DGETINFO_CALLBACK, FMOD_OUTPUT_OBJECT3DALLOC_CALLBACK, FMOD_OUTPUT_OBJECT3DFREE_CALLBACK

+

FMOD_OUTPUT_OPENPORT_CALLBACK

+

Output open port callback.

+

+

+
C
+
C++
+
JS
+
+

+
FMOD_RESULT F_CALL FMOD_OUTPUT_OPENPORT_CALLBACK(
+  FMOD_OUTPUT_STATE *output_state,
+  FMOD_PORT_TYPE portType,
+  FMOD_PORT_INDEX portIndex,
+  int *portId,
+  int *portRate,
+  int *portChannels,
+  FMOD_SOUND_FORMAT *portFormat
+);
+
+ +
+

Not supported for C#.

+
+
+

Not supported for JavaScript.

+
+
+
output_state
+
Plug-in state. (FMOD_OUTPUT_STATE)
+
portType
+
Port type. (FMOD_PORT_TYPE)
+
portIndex
+
Port index. (FMOD_PORT_INDEX)
+
portId Out
+
Port ID.
+
portRate Out
+
+

Port rate.

+
    +
  • Units: Hertz
  • +
+
+
portChannels Out
+
Number of channels.
+
portFormat
+
Port sound format. (FMOD_SOUND_FORMAT)
+
+

Main thread callback to open an auxiliary output port on the device.

+

See Also: FMOD_OUTPUT_DESCRIPTION

+

FMOD_OUTPUT_PLUGIN_VERSION

+

The output plug-in API version the plug-in was created with.

+

+

+
C
+
C++
+
JS
+
+

+
#define FMOD_OUTPUT_PLUGIN_VERSION   5
+
+ +
FMOD.OUTPUT_PLUGIN_VERSION
+
+ +
+

Currently not supported for C#.

+
+

See Also: FMOD_OUTPUT_DESCRIPTION

+

FMOD_OUTPUT_READFROMMIXER_FUNC

+

Output read from mixer function.

+

+

+
C
+
C++
+
JS
+
+

+
FMOD_RESULT F_CALL FMOD_OUTPUT_READFROMMIXER_FUNC(
+  FMOD_OUTPUT_STATE *output_state,
+  void *buffer,
+  unsigned int length
+);
+
+ +
+

Not supported for C#.

+
+
+

Not supported for JavaScript.

+
+
+
output_state
+
Plug-in state. (FMOD_OUTPUT_STATE)
+
buffer
+
Memory for the Studio API mixer to write to, provided by the plug-in writer.
+
length
+
Length of the buffer in samples.
+
+

Called by the plug-in. Use this function from your own driver irq/timer to read some data from FMOD's DSP engine. All of the resulting output caused by playing sounds and specifying effects by the user of the plug-in is mixed here and written to the memory provided by you.

+

FMOD_OUTPUT_REQUESTRESET_FUNC

+

Output request reset function.

+

Request the output to shut down and restart.

+

+

+
C
+
C++
+
JS
+
+

+
FMOD_RESULT F_CALL FMOD_OUTPUT_REQUESTRESET_FUNC(
+  FMOD_OUTPUT_STATE *output_state
+);
+
+ +
+

Not supported for C#.

+
+
+

Not supported for JavaScript.

+
+
+
output_state
+
Plug-in state. (FMOD_OUTPUT_STATE)
+
+

If this is issued, the output will not reset immediately, but on the next udpate the output will first shut down with a call to the FMOD_OUTPUT_STOP_CALLBACK then FMOD_OUTPUT_CLOSE_CALLBACK, followed by a restart with FMOD_OUTPUT_INIT_CALLBACK and FMOD_OUTPUT_START_CALLBACK

+

FMOD_OUTPUT_START_CALLBACK

+

Output start callback.

+

Called just before mixing should begin. This callback is called to start the output driver's audio stream.

+

+

+
C
+
C++
+
JS
+
+

+
FMOD_RESULT F_CALL FMOD_OUTPUT_START_CALLBACK(
+  FMOD_OUTPUT_STATE *output_state
+);
+
+ +
+

Not supported for C#.

+
+
+

Not supported for JavaScript.

+
+
+
output_state
+
Plug-in state. (FMOD_OUTPUT_STATE)
+
+

Invoked by:

+ +

This function is meant for starting the output audio rather than allocating memory and initializing interfaces like FMOD_OUTPUT_INIT_CALLBACK would.

+

See Also: FMOD_OUTPUT_DESCRIPTION, FMOD_OUTPUT_STOP_CALLBACK

+

FMOD_OUTPUT_STATE

+

Output object state passed into every callback provides access to plug-in developers data and system functionality.

+

+

+
C
+
C++
+
JS
+
+

+
typedef struct FMOD_OUTPUT_STATE {
+  void                            *plugindata;
+  FMOD_OUTPUT_READFROMMIXER_FUNC   readfrommixer;
+  FMOD_OUTPUT_ALLOC_FUNC           alloc;
+  FMOD_OUTPUT_FREE_FUNC            free;
+  FMOD_OUTPUT_LOG_FUNC             log;
+  FMOD_OUTPUT_COPYPORT_FUNC        copyport;
+  FMOD_OUTPUT_REQUESTRESET_FUNC    requestreset;
+} FMOD_OUTPUT_STATE;
+
+ +
FMOD_OUTPUT_STATE
+{
+  plugindata,
+};
+
+ +
+

Not supported for C#.

+
+
+
plugindata
+
Plug-in state data.
+
readfrommixer R/O
+
Function to read a buffer of audio from the mixer. Used to control when the mix occurs manually when FMOD_OUTPUT_DESCRIPTION::method set to FMOD_OUTPUT_METHOD_MIX_DIRECT. (FMOD_OUTPUT_READFROMMIXER_FUNC)
+
alloc R/O
+
Function to allocate memory using the FMOD memory system. (FMOD_OUTPUT_ALLOC_FUNC)
+
free R/O
+
Function to free memory allocated with FMOD_OUTPUT_ALLOC. (FMOD_OUTPUT_FREE_FUNC)
+
log R/O
+
Function to write to the FMOD logging system. (FMOD_OUTPUT_LOG_FUNC)
+
copyport R/O
+
Function to copy the output from the mixer for the given auxiliary port. (FMOD_OUTPUT_COPYPORT_FUNC)
+
requestreset R/O
+
Function to request the output plug-in be shutdown then restarted during the next System::update. (FMOD_OUTPUT_REQUESTRESET_FUNC)
+
+

See Also: FMOD_OUTPUT_DESCRIPTION

+

FMOD_OUTPUT_STOP_CALLBACK

+

Output stop callback.

+

Called just after mixing has ended. This callback is called to stop the output driver's audio stream.

+

+

+
C
+
C++
+
JS
+
+

+
FMOD_RESULT F_CALL FMOD_OUTPUT_STOP_CALLBACK(
+  FMOD_OUTPUT_STATE *output_state
+);
+
+ +
+

Not supported for C#.

+
+
+

Not supported for JavaScript.

+
+
+
output_state
+
Plug-in state. (FMOD_OUTPUT_STATE)
+
+

Invoked by:

+ +

This function is meant for stopping the output audio rather than freeing memory and shutting down audio interfaces like FMOD_OUTPUT_CLOSE_CALLBACK would.

+

See Also: FMOD_OUTPUT_DESCRIPTION, FMOD_OUTPUT_START_CALLBACK

+

FMOD_OUTPUT_UPDATE_CALLBACK

+

Output update callback.

+

+

+
C
+
C++
+
JS
+
+

+
FMOD_RESULT F_CALL FMOD_OUTPUT_UPDATE_CALLBACK(
+  FMOD_OUTPUT_STATE *output_state
+);
+
+ +
+

Not supported for C#.

+
+
+

Not supported for JavaScript.

+
+
+
output_state
+
Plug-in state. (FMOD_OUTPUT_STATE)
+
+

Invoked by:

+ +

This callback is invoked from the main application update which allows the output to process data in sync with the application, rather than the mixer thread.

+

See Also: FMOD_OUTPUT_DESCRIPTION, System::update

+ + +
+ + + diff --git a/FMOD/doc/FMOD API User Manual/plugin-api.html b/FMOD/doc/FMOD API User Manual/plugin-api.html new file mode 100644 index 0000000..f44d170 --- /dev/null +++ b/FMOD/doc/FMOD API User Manual/plugin-api.html @@ -0,0 +1,47 @@ + + +Plug-in API Reference + + + + + + + + diff --git a/FMOD/doc/FMOD API User Manual/running-the-core-api.html b/FMOD/doc/FMOD API User Manual/running-the-core-api.html new file mode 100644 index 0000000..f075b34 --- /dev/null +++ b/FMOD/doc/FMOD API User Manual/running-the-core-api.html @@ -0,0 +1,79 @@ + + +Core API Getting Started + + + + +
+ +
+

3. Core API Getting Started

+

This chapter describes how to start up, configure, run, and shut down the FMOD Engine using only the Core API. It frequently references concepts explained in the Core API: Key Concepts chapter.

+

At the most basic level, all that is needed to configure the Core API is creating the System object and calling System::init on it. The sound card can be manually selected using the System::setDriver function. More settings can be configured, such as the mixing rate of the FMOD system, the resampling method, or the speaker mode with System::setSoftwareFormat. Modifying the mixer settings only adjusts the internal mixing format; at the end, the audio stream is always converted to the settings that are set by the player (e.g.: the settings in the control panel in Windows, or the standard 7.1/48khz output mode on Xbox One or PS4).

+

3.1 Initializing the Core API

+

The Core API can be used without needing to use the Studio API at all. Using the Core API gives access to the fundamental abilities of loading and playing sounds, creating DSP effects, setting up ChannelGroups, and setting sample-accurate fade points and start/stop times. However, when just using the Core API, it is not possible to load FMOD Studio banks or load and play events that sound artists have designed in FMOD Studio. To initialize the Core API directly:

+
FMOD_RESULT result;
+FMOD::System *system = NULL;
+
+result = FMOD::System_Create(&system);      // Create the main system object.
+if (result != FMOD_OK)
+{
+    printf("FMOD error! (%d) %s\n", result, FMOD_ErrorString(result));
+    exit(-1);
+}
+
+result = system->init(512, FMOD_INIT_NORMAL, 0);    // Initialize FMOD.
+if (result != FMOD_OK)
+{
+    printf("FMOD error! (%d) %s\n", result, FMOD_ErrorString(result));
+    exit(-1);
+}
+
+ +

FMOD System object is returned to you directly as a pointer. Once you destroy the Core API System, it is no longer safe to call FMOD functions with that pointer.

+

The Core API can be customized with advanced settings by calling System::setAdvancedSettings before initialization.

+

3.2 Configuring the Core API

+

The output hardware, FMOD's resource usage, and other types of configuration options can be set if you desire behavior differing from the default. These are generally called before System::init. For more information about these, see System::setAdvancedSettings, Studio::System::setAdvancedSettings.

+

3.3 Updating the FMOD Engine

+

The FMOD Engine should be ticked once per game update. To tick it when using the Core API, call System::update. (If you're using the Studio API, you should instead call Studio::System::update.)

+

3.4 Shutting Down the FMOD Engine

+

To shut down the Core API, call System::release.

+ + +
+ + + diff --git a/FMOD/doc/FMOD API User Manual/scripts/language-selector.js b/FMOD/doc/FMOD API User Manual/scripts/language-selector.js new file mode 100644 index 0000000..71e752a --- /dev/null +++ b/FMOD/doc/FMOD API User Manual/scripts/language-selector.js @@ -0,0 +1,98 @@ +var languageTabs = null; +var languageSpecificElements = null; +var availableLanguages = null; + +// Helper function to iterate over an HTMLCollection or NodeList (https://stackoverflow.com/questions/3871547/js-iterating-over-result-of-getelementsbyclassname-using-array-foreach) +function forEachElement(collection, func) { + Array.prototype.forEach.call(collection, func); +} + +function matchLanguage(el, lang) { + if (lang == "language-all" || el.classList.contains("language-all")) { + return true; + } else if ((lang === "language-c" || lang === "language-cpp") && el.classList.contains("language-c-cpp")) { + return true; + } else { + return el.classList.contains(lang); + } +} + +function setLanguage(lang) { + if (languageSpecificElements == null) { + return; + } + + window.localStorage.setItem("FMOD.Documents.selected-language", lang); + + if (availableLanguages.length > 0 && !availableLanguages.includes(lang)) { + lang = availableLanguages[0]; + } + + forEachElement(languageTabs, function(el) { + var ellang = el.attributes['data-language'].value; + + if (ellang === lang) { + el.classList.add("selected"); + } else { + el.classList.remove("selected"); + } + }); + + forEachElement(languageSpecificElements, function(el) { + if (matchLanguage(el, lang)) { + el.style.display = 'block'; + } else { + el.style.display = 'none'; + } + }); + + window.localStorage.setItem("FMOD.Documents.selected-language", lang); +} + +function init() { + var docsBody = document.querySelector("div.manual-content.api"); + + if (docsBody) { + // API docs + + // Setup language tabs + languageTabs = docsBody.getElementsByClassName("language-tab"); + + forEachElement(languageTabs, function(el) { + el.onclick = function() { setLanguage(this.attributes['data-language'].value); } + }); + + // Cache language specific elements on the page + languageSpecificElements = docsBody.querySelectorAll(".language-c, .language-cpp, .language-c-cpp, .language-csharp, .language-javascript"); + + // Determine languages used on the page + availableLanguages = []; + ["language-c", "language-cpp", "language-c-cpp", "language-csharp", "language-javascript"].forEach(function(lang) { + if (docsBody.querySelector("." + lang) != null) { + availableLanguages.push(lang); + } + }); + + if (availableLanguages.indexOf("language-c-cpp") >=0) { + if (availableLanguages.indexOf("language-c") < 0) availableLanguages.push("language-c"); + if (availableLanguages.indexOf("language-cpp") < 0) availableLanguages.push("language-cpp"); + } + // Set initial language + var lang = window.localStorage.getItem("FMOD.Documents.selected-language"); + + if (lang == null) { + lang = "language-cpp"; + } + + setLanguage(lang); + } +} + +if (typeof module !== 'undefined') { + module.exports = { initLanguageSelector: init }; +} else { + // Call our init function when the document is loaded. (https://plainjs.com/javascript/events/running-code-when-the-document-is-ready-15/) + if (document.readyState != 'loading') init(); + else if (document.addEventListener) document.addEventListener('DOMContentLoaded', init); + else document.attachEvent('onreadystatechange', function() { if (document.readyState == 'complete') init(); }); +} diff --git a/FMOD/doc/FMOD API User Manual/spatializing-sounds-in-the-core-api.html b/FMOD/doc/FMOD API User Manual/spatializing-sounds-in-the-core-api.html new file mode 100644 index 0000000..a81b4b5 --- /dev/null +++ b/FMOD/doc/FMOD API User Manual/spatializing-sounds-in-the-core-api.html @@ -0,0 +1,299 @@ + + +Core API Spatializing Sounds + + + + +
+ +
+

5. Core API Spatializing Sounds

+

This chapter will introduce you to using 3D sound with the Core API. With it, you can easily implement interactive 3D audio and have access to features such as 5.1 or 7.1 speaker output, automatic attenuation, doppler, and more advanced psychoacoustic 3D audio techniques.

+

For information specific to the Studio API and FMOD Studio events, see the Studio API 3D Events chapter.

+

5.0.1 Speaker and Output Modes

+

You do not need to set the speaker mode for FMOD. Any sound using FMOD_3D is automatically positioned in a surround speaker system. As long as the player's sound card supports it, and their operating system speaker settings are correct, their audio device will be able to output the sound in 5.1 or 7.1.

+

5.0.2 Loading Sounds as 3D

+

When loading a sound or sound bank, the sound must be created with System::createSound or System::createStream using the FMOD_3D flag. ie.

+
result = system->createSound("../media/drumloop.wav", FMOD_3D, 0, &sound);
+if (result != FMOD_OK)
+{
+    HandleError(result);
+}
+
+ +

It is generally best not to try and switch between 3D and 2D at all, if you want though, you can change the Sound or Channel's mode to FMOD_3D_HEADRELATIVE at runtime which places the sound always relative to the listener, effectively sounding 2D as it will always follow the listener as the listener moves around.

+

5.0.3 Distance Models

+

A major part of spatialization is attenuating the volume of a channel based on its distance from the listener. The FMOD Engine supports multiple different models for how this should occur.

+

Inverse

+

This is the default FMOD 3D distance model. All sounds naturally attenuate (fade out) in the real world using an inverse distance attenuation. The flag to set to this mode is FMOD_3D_INVERSEROLLOFF but if you're loading a sound you don't need to set this because it is the default. It is more for the purpose or resetting the mode back to the original if you set it to FMOD_3D_LINEARROLLOFF at some later stage.

+

When FMOD uses this model, 'mindistance' of a Sound / Channel, is the distance that the sound starts to attenuate from. This can simulate the sound being smaller or larger. By default, for every doubling of this mindistance, the sound volume will halve. This roll-off rate can be changed with System::set3DSettings.

+

As an example of relative sound sizes, we can compare a bee and a jumbo jet. At only a meter or 2 away from a bee we will probably not hear it any more. In contrast, a jet will be heard from hundreds of meters away. In this case we might set the bee's mindistance to 0.1 meters. After a few meters it should fall silent. The jumbo jet's mindistance could be set to 50 meters. This could take many hundreds of meters of distance between listener and sound before it falls silent. In this case we now have a more realistic representation of the loudness of the sound, even though each wave file has a fully normalized 16bit waveform within. (ie if you played them in 2D they would both be the same volume).

+

The 'maxdistance' does not affect the rate of roll-off, it simply means the distance where the sound stops attenuating. Don't set the maxdistance to a low number unless you want it to artificially stop attenuating. This is usually not wanted. Leave it at its default of 10000.0.

+

Inverse Tapered

+

This is a combination of the inverse and linear-square roll-off models. At shorter distances where inverse roll-off would provide greater attenuation, it functions as inverse roll-off mode; then at greater distances where linear-square roll-off mode would provide greater attenuation, it uses that roll-off mode instead. For this roll-off mode, distance values greater than mindistance are scaled according to the rolloffscale. Inverse tapered roll-off mode approximates realistic behavior while still guaranteeing the sound attenuates to silence at maxdistance.

+

Linear and Linear Squared

+

These are alternative distance models, also available in the FMOD Engine. To use them, add the FMOD_3D_LINEARROLLOFF or FMOD_3D_LINEARSQUAREROLLOFF flag to System::createSound or Sound::setMode / ChannelControl::setMode. While less realistic, these models are more game programmer-friendly, as they result in the attenuation fading linearly between 'mindistance' and 'maxdistance'. In these modes, the mindistance is the same as it is in the inverse model (i.e.: the minimum distance before the sound starts to attenuate), but the maxdistance is the point where the volume = 0 due to 3D distance. The attenuation in-between those two points is linear or linear squared, depending on which model is selected.

+

Custom

+

Custom roll-off allows a FMOD_3D_ROLLOFF_CALLBACK to be set that allows you to calculate how the volume roll-off happens. If a callback is not convenient, the Core API also allows an array of points that are linearly interpolated between, to denote a 'curve', using ChannelControl::set3DCustomRolloff.

+

5.0.4 Speaker Channel Formats

+

If the player's sound card supports it, any sound using FMOD_3D is automatically positioned in a surround speaker system, so you do not need to set the speaker mode for FMOD. Provided the player has correctly set their operating system's speaker settings, their audio device will be able to output the audio in 5.1 or 7.1.

+

5.0.5 Advanced Global 3D Settings

+

There are three configurable settings in the FMOD Engine that affect all 3D sounds. These are:

+
    +
  • Doppler factor. This is used to exaggerate or minimize the doppler effect.
  • +
  • Distance factor. This multiplies the langth of the distance units used by the FMOD Engine, allowing you to use distance units that match those used in your game (e.g.: centimeters, feet, meters, yards).
  • +
  • Roll-off scale. This affects 3D sounds that use roll-off modes other than FMOD_3D_CUSTOMROLLOFF, and controls how quickly such sounds attenuate as distance increases.
  • +
+

All three settings can be set with System::set3DSettings. In most games, there is no need to set them.

+

5.0.6 Advanced 3D Techniques

+

While spatialization is often enough on its own, some games benefit from more complex 3D behavior. Here's a few ideas.

+
    +
  • Occlusion. A Sound's underlying Channels or ChannelGroups can have lowpass filtering applied to them to simulate sound going through walls or being muffled by large objects.
  • +
  • 3D Reverb Zones for reverb panning. For more information, see the 3D Reverbs section of the Advanced Core API Topics chapter. Reverb can also be occluded to not go through walls or objects.
  • +
  • Polygon based geometry occlusion. Add polygon data to FMOD's geometry engine, and FMOD will automatically occlude sound in realtime using raycasting. See more about this in the 3D Polygon based geometry occlusion section of the Advanced Core API Topics chapter.
  • +
  • Morphing between 2D and 3D with multi-channel audio formats. Channels can be a point source, or be morphed by the user into 2D audio, which is great for distance based envelopment. The closer a Channel is, the more it can spread into the other speakers, rather than flipping from one side to the other as it pans from one side to the other. See ChannelControl::set3DLevel for the function that lets the user change this mix.
  • +
  • Stereo and multi-channel audio formats can be used for 3D audio. Typically, a mono audio format is used for 3D audio, but multi-channel audio formats can be used to give extra impact. By default, multi-channel sample data is collapsed into a mono point source. To 'spread' the multiple channels use ChannelControl::set3DSpread. This can give a more spatial effect for a sound that is coming from a certain direction. A subtle spread of sound in the distance may give the impression of being more effectively spatialized as if it were reflecting off nearby surfaces, or being 'big' and emitting different parts of the sound in different directions.
  • +
  • Spatialization plug-in support. 3rd party VR audio plug-ins can be used to give more realistic panning over headphones.
  • +
+

5.1 Controlling a Spatializer DSP

+

Controlling a spatializer DSP using the Core API requires setting the data parameter associated with 3D attributes for the Channel. This is a data parameter of type FMOD_DSP_PARAMETER_DATA_TYPE_3DATTRIBUTES or FMOD_DSP_PARAMETER_DATA_TYPE_3DATTRIBUTES_MULTI. When using the Core API System, you must set this DSP parameter explicitly. To do this, use ChannelControl::set3DAttributes with the handle that was returned from System::playSound for the channel. If 3D positioning of a ChannelGroup instead, set the ChannelGroup to be 3D once with ChannelControl::setMode, then call ChannelControl::set3DAttributes for that channel group.

+

Because the effect of a spatializer DSP depends on the position of the channel or channel group relative to the listener, it is also necessary to update the 3D attributes of the listener once per frame with System::set3DListenerAttributes.

+

Call System::update once per frame so the 3D calculations can update based on the positions and other attributes.

+

This method works with our pan DSP, the object panner DSP, the Resonance Source and Soundfield spatializers, and any other third party plug-ins that make use of the FMOD spatializers.

+

Attributes must use a coordinate system with the positive Y axis being up and the positive X axis being right (left-handed coordinate system). FMOD converts passed in coordinates from right-handed to left-handed for the plug-in if the System is initialized with the FMOD_INIT_3D_RIGHTHANDED flag.

+

The absolute data for the FMOD_DSP_PARAMETER_3DATTRIBUTES is straightforward, however the relative part requires some work to calculate.

+
/*
+    This code supposes the availability of a maths library with basic support for 3D and 4D vectors and 4x4 matrices:
+
+    // 3D vector
+    class Vec3f
+    {
+    public:
+        float x, y, z;
+
+        // Initialize x, y & z from the corresponding elements of FMOD_VECTOR
+        Vec3f(const FMOD_VECTOR &v);
+    };
+
+    // 4D vector
+    class Vec4f
+    {
+    public:
+        float x, y, z, w;
+
+        Vec4f(const Vec3f &v, float w);
+
+        // Initialize x, y & z from the corresponding elements of FMOD_VECTOR
+        Vec4f(const FMOD_VECTOR &v, float w);
+
+        // Copy x, y & z to the corresponding elements of FMOD_VECTOR
+        void toFMOD(FMOD_VECTOR &v);
+    };
+
+    // 4x4 matrix
+    class Matrix44f
+    {
+    public:
+        Vec4f X, Y, Z, W;
+    };
+
+    // 3D Vector cross product
+    Vec3f crossProduct(const Vec3f &a, const Vec3f &b);
+
+    // 4D Vector addition
+    Vec4f operator+(const Vec4f &a, const Vec4f &b);
+
+    // 4D Vector subtraction
+    Vec4f operator-(const Vec4f& a, const Vec4f& b);
+
+    // Matrix multiplication m * v
+    Vec4f operator*(const Matrix44f &m, const Vec4f &v);
+
+    // 4x4 Matrix inverse
+    Matrix44f inverse(const Matrix44f &m);
+*/
+
+void calculatePannerAttributes(const FMOD_3D_ATTRIBUTES &listenerAttributes, const FMOD_3D_ATTRIBUTES &emitterAttributes, FMOD_DSP_PARAMETER_3DATTRIBUTES &pannerAttributes)
+{
+    // pannerAttributes.relative is the emitter position and orientation transformed into the listener's space:
+
+    // First we need the 3D transformation for the listener.
+    Vec3f right = crossProduct(listenerAttributes.up, listenerAttributes.forward);
+
+    Matrix44f listenerTransform;
+    listenerTransform.X = Vec4f(right, 0.0f);
+    listenerTransform.Y = Vec4f(listenerAttributes.up, 0.0f);
+    listenerTransform.Z = Vec4f(listenerAttributes.forward, 0.0f);
+    listenerTransform.W = Vec4f(listenerAttributes.position, 1.0f);
+
+    // Now we use the inverse of the listener's 3D transformation to transform the emitter attributes into the listener's space:
+    Matrix44f invListenerTransform = inverse(listenerTransform);
+
+    Vec4f position = invListenerTransform * Vec4f(emitterAttributes.position, 1.0f);
+
+    // Setting the w component of the 4D vector to zero means the matrix multiplication will only rotate the vector.
+    Vec4f forward = invListenerTransform * Vec4f(emitterAttributes.forward, 0.0f);
+    Vec4f up = invListenerTransform * Vec4f(emitterAttributes.up, 0.0f);
+    Vec4f velocity = invListenerTransform * (Vec4f(emitterAttributes.velocity, 0.0f) - Vec4f(listenerAttributes.velocity, 0.0f));
+
+    // We are now done computing the relative attributes.
+    position.toFMOD(pannerAttributes.relative.position);
+    forward.toFMOD(pannerAttributes.relative.forward);
+    up.toFMOD(pannerAttributes.relative.up);
+    velocity.toFMOD(pannerAttributes.relative.velocity);
+
+    // pannerAttributes.absolute is simply the emitter position and orientation:
+    pannerAttributes.absolute = emitterAttributes;
+}
+
+ +

When using FMOD_DSP_PARAMETER_3DATTRIBUTES_MULTI, you must call calculatePannerAttributes for each listener, filling in the appropriate listener attributes.

+

Set this on the DSP by using DSP::setParameterData with the index of the FMOD_DSP_PARAMETER_DATA_TYPE_3DATTRIBUTES. You will need to check with the author of the DSP for the structure index. Pass the data into the DSP using DSP::setParameterData with the index of the 3D Attributes, FMOD_DSP_PARAMETER_DATA_TYPE_3DATTRIBUTES or FMOD_DSP_PARAMETER_DATA_TYPE_3DATTRIBUTES_MULTI.

+

The following is an example of a typical game's audio loop that uses System::update to update the 3D attributes of channels and listeners, as well as the FMOD channel management system, once per frame.

+
do
+{
+    UpdateGame();       // here the game is updated and the sources would be moved with channel->set3DAttibutes.
+
+    system->set3DListenerAttributes(0, &listener_pos, &listener_vel, &listener_forward, &listener_up);     // update 'ears'
+
+    system->update();   // needed to update 3d engine, once per frame.
+
+} while (gamerunning);
+
+ +

Most games usually take the position, velocity and orientation from the camera's vectors and matrix.

+

5.1.1 Velocity

+

Velocity is only required if you want doppler effects. If you do not, you can pass 0 or NULL to both System::set3DListenerAttributes and ChannelControl::set3DAttributes for the velocity parameter, and no doppler effect will be heard.

+

It is important that the velocity passed to the FMOD Engine is in meters per second and not meters per frame. To get the correct velocity vector, use a method such as calculating it using vectors from your game's physics code. Don't just subtract the last frame's position from the current position, as this is affected by framerate, meaning that the higher the framerate the smaller the position deltas and thus the smaller the doppler effect, which is incorrect.

+

If the only way you can get the velocity is to subtract this and last frame's position vectors, then remember to time adjust them from meters per frame back up to meters per second. This is done simply by scaling the difference vector obtained by subtracting the two position vectors, by one over the frame time delta.

+

Here is an example.

+
velx = (posx-lastposx) * 1000 / timedelta;
+velz = (posy-lastposy) * 1000 / timedelta;
+velz = (posz-lastposz) * 1000 / timedelta;
+
+ +

timedelta is the time since the last frame in milliseconds. This can be obtained with functions such as timeGetTime(). So at 60fps, the timedelta would be 16.67ms. if the source moved 0.1 meters in this time, the actual velocity in meters per second would be:

+
vel = 0.1 * 1000 / 16.67 = 6 meters per second.
+
+ +

Similarly, if we only have half the framerate of 30fps, then subtracting position deltas will gives us twice the distance that it would at 60fps (so it would have moved 0.2 meters this time).

+
vel = 0.2 * 1000 / 33.33 = 6 meters per second.
+
+ +

5.1.2 Orientation and left-handed vs right-handed coordinate systems

+

Getting the correct orientation set up is essential if you want the source to move around you in 3D space.

+

By default, FMOD uses a left-handed coordinate system. If you are using a right-handed coordinate system then FMOD must be initialized by passing FMOD_INIT_3D_RIGHTHANDED to System::init. In either case FMOD requires that the positive Y axis is up and the positive X axis is right, if your coordinate system uses a different convention then you must rotate your vectors into FMOD's space before passing them to FMOD.

+

Note for plug-in writers: FMOD always uses a left-handed coordinate system when passing 3D data to plug-ins. This coordinate system is fixed to use +X = right, +Y = up, +Z = forward. When the system is initialised to use right-handed coordinates FMOD will flip the Z component of vectors before passing them to plug-ins.

+

5.1.3 Split Screen / Multiple Listeners

+

Some games have a split screen mode, where different sections of the screen represent cameras in different locations. As the listener is almost always positioned in the same location as the camera, this means that the FMOD Engine has to be able to handle more than one listener at once. This is handled by using System::set3DNumListeners and System::set3DListenerAttributes.

+

For example, if you have two player split screen, System::set3DNumListeners would be set to two. When updating the positions of the listener, for each 'camera' or 'listener' call System::set3DListenerAttributes with 0 as the listener number of the first camera, and 1 for the listener number of the second camera.

+

When using multiple listeners in the Core API, 3D Channels have the following behavior:

+
    +
  • All doppler is disabled. This is because one listener might be going towards the sound, and another listener might be going away from the sound. To avoid confusion, the doppler is simply turned off.
  • +
  • All audio is mono. If to one listener the sound should be coming out of the left speaker, and to another listener it should be coming out of the right speaker, there will be a conflict, and more confusion, so all sounds are simply panned to the middle. This removes confusion.
  • +
  • Each sound is played only once as it would with a single player game, instead of a different instance of the sound being played for each listener. This saves voice and CPU resources. The sound's effective audibility is determined by the closest listener to the sound, which makes sense, as the sound should be the loudest to the nearest listener, and more distant listeners would not have any impact on the volume.
  • +
+

5.1.4 Stereo and Multi-channel Audio

+

A stereo sound, when played as 3d, is split into two mono voices internally which are separately 3D positionable. Multi-channel audio formats are also supported, so an eight channel sound (for example) allocates 8 mono voices internally in FMOD. To rotate the left and right part of a stereo 3D sound in 3D space, use the ChannelControl::set3DSpread function. By default, the subchannels position themselves in the same place, therefore sounding 'mono'.

+

5.2 Spatial Audio

+

Historically, audio spatialization (the process of taking an audio file and making it sound "in the world") has been all about positioning sound in speakers arranged on a horizontal plane. This arrangement is often seen in the form of 5.1 or 7.1 surround. With the advancement of VR technology, however, more emphasis has been put on making sound as immersive as the visuals. This is achieved by more advanced processing of the audio signals for the traditional horizontal plane as well as the introduction of height spatialization. This has given the rise of the term "spatial audio" which focuses on this more realistic approach to spatialization.

+

Within FMOD there are several ways you can achieve a more immersive spatialization experience, depending on your target platform some may or may not apply. The following sections outline a few general approaches with specific implementation details contained within.

+

5.2.1 Channel based approach

+

The most traditional way to approach spatialization is by panning signal into virtual speakers, so with the introduction of 7.1.4 (7 horizontal plane speakers, 1 sub-woofer, 4 roof speakers) you can do just this.

+
    +
  • Set your FMOD::System to the appropriate speaker mode by calling System::setSoftwareFormat(0, FMOD_SPEAKERMODE_7POINT1POINT4, 0).
  • +
  • Select an output mode capable of rendering 7.1.4 content System::setOutput(FMOD_OUTPUTTYPE_WINSONIC).
  • +
+

You can now System::createSound and System::playSound content authored as 7.1.4. If you have the necessary sound system setup (i.e. Dolby Atmos) you will hear the sound play back including the ceiling speakers. If you have a headphone based setup (i.e. Windows Sonic for Headphones or Dolby Atmos for Headphones) you will hear an approximation of ceiling speakers.

+

To take an existing horizontal plane signal and push it into the ceiling plane you can create an FMOD spatializer and adjust the height controls.

+ +

Not only will this let you blend to the 0.0.4 ceiling speakers by setting the value between 0.0 and 1.0, it will also let you blend from the 0.0.4 ceiling speakers to the ground plane 7.1.0 by setting the value between 0.0 and -1.0.

+

The FMOD_OUTPUTTYPE_WINSONIC plug-in supports 7.1.4 output available on Windows, UWP, Xbox One and Xbox Series X|S. Also, the FMOD_OUTPUTTYPE_PHASE plug-in supports 7.1.4 output for iOS devices. Other platforms will fold 7.1.4 down to 7.1.

+

5.2.2 Object based approach

+

To get more discrete spatialization of an audio signal you can use the FMOD object spatializer, so named because the audio signal is packaged with the spatialization information (position, orientation, etc) and sent to an object mixer. Often used to highlight important sounds with strong localization to add interest to a scene, usually used in-conjunction with the channel based approach, be that 7.1.4 or even simply 5.1 / 7.1.

+
    +
  • Set your FMOD::System to an object ready output plug-in by calling System::setOutput(FMOD_OUTPUTTYPE_WINSONIC) or System::setOutput(FMOD_OUTPUTTYPE_AUDIO3D) or System::setOutput(FMOD_OUTPUTTYPE_AUDIOOUT) or System::setOutput(FMOD_OUTPUTTYPE_PHASE).
  • +
  • Create an object spatializer with System::createDSPByType(FMOD_DSP_TYPE_OBJECTPAN).
  • +
  • Provide 3D position information with FMOD_DSP_OBJECTPAN_3D_POSITION via DSP::setParameterData.
  • +
+

There is no limit to how many FMOD_DSP_TYPE_OBJECTPAN DSPs you can create, however there is a limit to how many can be processed at a time. This limit is flexible, and varies from platform to platform. When there are more object spatializers in use than there are available resources for, FMOD virtualizes the least significant sounds by processing with a traditional channel based mix.

+

An important consideration, when using object spatializers, is signal flow. Unlike most DSPs, after the signal enters an object spatializer DSP it is sent out to the object mixer. Regardless of whether the object mixer is a software library or a physical piece of hardware, the result is that you no longer have access to that signal. Any processing you would like to perform on that signal must therefore be accomplished before it enters the object spatializer DSP. Despite this, to assist mixing, the object spatializer automatically applies any "downstream" ChannelGroup volume settings.

+

Object spatialization is available via the following output plug-ins:

+ +

Other output plug-ins will emulate object spatialization using traditional channel based panning.

+

5.2.3 Third Party Plug-ins

+

In addition to the built-in channel and object based approaches there are third party plug-ins available that can assist too. The FMOD DSP plug-in API (see FMOD_DSP_DESCRIPTION) allows any developer to produce an interface for their spatial audio technology and provide it across all FMOD platforms. Additionally the FMOD output plug-in API (see FMOD_OUTPUT_DESCRIPTION) allows developers to implement a renderer for the FMOD object spatializer extending the functionality to more platforms and more technologies.

+

Some examples of publicly-available third-party plug-ins:

+
    +
  • Resonance Audio Spatializer. The Resonance Audio cross-platform suite of plug-ins comes bundled with FMOD. Resonance Audio offers a "Source" plug-in which behaves much like the FMOD object spatializer, in that audio is sent out to an object mixer, however the final signal returns as binaural output at the "Listener" plug-in. Resonance Audio also offers a "Soundfield" plug-in for playing back first order Ambisonic sound fields. For more details about the usage of Resonance Audio please check out the user guide.
  • +
  • Oculus Spatializer. Another cross-platform suite of spatial audio plug-ins is that offered by Oculus as part of their Audio SDK. You can find instructions and downloads for these available on their website.
  • +
  • Steam Audio. Valve Software offers another cross-platform suite of spatial audio plug-ins as part of their Steam Audio SDK. You can find getting started information available on their website with downloads on GitHub.
  • +
+ + +
+ + + diff --git a/FMOD/doc/FMOD API User Manual/studio-api-3d-events.html b/FMOD/doc/FMOD API User Manual/studio-api-3d-events.html new file mode 100644 index 0000000..68eedff --- /dev/null +++ b/FMOD/doc/FMOD API User Manual/studio-api-3d-events.html @@ -0,0 +1,94 @@ + + +Studio API 3D Events + + + + +
+ +
+

14. Studio API 3D Events

+

This chapter will introduce you to using 3D sound with FMOD Studio events.

+

14.1 Coordinate Systems and Handedness

+

FMOD Studio shares the same coordinate system as the core API. For more information, see the Spatializing Sounds in the Core API chapter.

+

14.2 Updating orientations

+

The programmer needs to call Studio::System::setListenerAttributes once per frame for the listener, and to update 3D events with Studio::EventInstance::set3DAttributes. It is important to update all orientations before calling Studio::System::update. If some orientations are set before Studio::System::update and some are set afterwards, then some frames may end up having old positions relative to others. This is particularly important when both the listener and the events are moving fast and together - if there are frames where the listener moves but the event does not it becomes very noticeable.

+

14.3 FMOD Spatializer

+

FMOD Studio supports spatializing events by placing an FMOD spatializer effect on the event master track. It is possible to use other sorts of spatializers by replacing the FMOD spatializer with a different type of effect, for example a third party spatializer.

+

14.4 FMOD Object Spatializer

+

The object spatializer is a special type of spatializer that interfaces with object-based output modes such as Dolby Atmos. These output modes accept mono signals with a 3D position and do their own spatialization and mixing to the final speaker configuration. To use object spatializers, the programmer has to specify an output mode that supports object based spatialization, otherwise the signal will be mixed down at the final stage by FMOD.

+

The benefit of the object spatializer is that it allows the sound designer to leverage object-based technologies. It does come at a cost, however, as the signal leaves the mix at the object spatializer and does not receive the benefit of DSP effects on parent buses like signals run though normal spatializers do. The object spatializer automatically bases its volume on the combined volumes of parent buses for basic mixing, but no complex effects can be used. For this reason, the mix has to be set up very carefully with knowledge of the limitations of the object spatialization.

+

It is possible for the sound designer to use a mixture of normal 3D spatialized events and object-spatialized 3D events. Normal events will have signal going through the mixer hierarchy, and object-based events will have signal that leaves the mix at the master track. As far as the programming API goes, both kinds of events are treated exactly the same.

+

14.5 Automatic Parameters

+

FMOD Studio supports setting automations based on parameters that automatically update based on position. For example, the sound designer could add a volume automation based on Distance, with a 2D panning that is automated on the Direction parameter. The event is still considered 3D in that case, even if it has no spatializer on the master track.

+

An event may have both a spatializer on the master track, as well as an automation based on a Distance parameter. As the event and listener moves, both the spatializer and the automation will be updated.

+

14.6 Multiple Listeners

+

FMOD Studio supports multiple listeners. Call Studio::System::setNumListeners to set the number of listeners, and use Studio::System::setListenerAttributes to set the orientations for listeners, with an index for the listener.

+

14.6.1 Studio Spatialization for Multiple Listeners

+

Consider the case of an event with three nearby listeners. In this case, listener A is slightly closer to the event than B, and C is the furthest away, outside the max distance of the event.

+

The Studio spatializer will take listener A and B into account. The gain will be based off the closest listener distance (in this case, the distance to listener A). Listener B will have an effect on the spatialization. However, both A and B agree that the event is to the front, so the final pan matrix will be towards the front speakers. Listener C has no effect on the calculation since it is out of range.

+

Multiple listeners

+

Consider this case where listener A and B have moved and now the event is to the right of A and to the left of B. In this case, the gain will be based of the closest listener distance (which is B), but the pan matrix will have signal out of both the left and the right since both listeners have an effect on the mix. If A moved further away then the contribution of A would diminish and to the signal would start to come more out of the left speakers. If A moved further enough away, the signal would smoothly interpolate to just B having an influence on the spatialization.

+

Multiple listeners

+

14.6.2 Studio Spatialization for Listener Weights

+

Listener weights can be set using Studio::System::setListenerWeight. This allows listeners to fade in and out of existence, as well as to allow cross-fading of listeners to a new position. In the following picture, we have 4 listeners. Listener C is out of range so it has no influence, and listener D has 0% weighting so it has no influence either. The remaining two listeners have a weight of 40% and 60%. In this example, perhaps the camera is teleporting to a new position and the game is smoothly interpolating to a new orientation.

+

The gain is a weighted average between A and B, so it is equivalent to having a distance somewhere between the two listeners. The spatialization of the signal is a mixture of A and B. A is further away and has a lower weight, so the biggest contribution is due to B, meaning the signal sounds mostly in the front speakers. If you imagine blending from A to B, the signal will smoothly interpolate from the back speakers to the front and get louder when the weights scale from A to B.

+

Multiple listener weights

+

14.7 Listener Mask

+

Events can have a mask that specifies which listeners are active for that event. By default all listeners apply to all events. By calling Studio::EventInstance::setListenerMask, some listeners can be disabled for that event so that they have no influence on the panning. This could be used to group some events and listeners together and have that set only affected by that one listener. When performing the calculation above, any listener not included in the mask is ignored and is as if it does not exist for that event. It is an error to set a combination of mask and weight such that no listener is active for an event.

+

14.8 Doppler

+

FMOD events support doppler. The sound designer specifies doppler on a per event basis with a scale, so some events may be affected less than others. Doppler is calculated using listener and event velocities; it is up to the programmer to correctly specify velocity values using Studio::EventInstance::set3DAttributes and Studio::System::setListenerAttributes. The scale of doppler can be specified at initialization time using System::set3DSettings.

+

For the case of multiple listeners, the doppler is based on the closest listener. If listener has a weight then it is a combination of the closest listeners up to 100%. For example if there were three listeners at increasing distance with weight of 60%, 60% and 60%, then the doppler would be calculated from 60% of the first listener, 40% of the second, and 0% of the third.

+

14.9 Automatic Parameters and Multiple Listeners

+

If there are multiple listeners, an FMOD Studio event's automatic parameters are based on the closest listener. If the closest listener has a weight, then the event's automatic parameters instead use a combination of the closest listeners, up to a total weight of 100%. For example, if there are three listeners at increasing distance with weights of 60%, 60% and 60%, then the automatic parameters would be calculated from 60% of the first listener, 40% of the second, and 0% of the third.

+

14.10 Interface with Core API

+

When calling Studio::System::setNumListeners and Studio::System::setListenerAttributes, there is no need to call the equivalent Core API functions System::set3DNumListeners and System::set3DListenerAttributes, as FMOD Studio passes the information into the Core API automatically. This means it is possible to have a mixture of FMOD Studio 3D events and Core API 3D Channels playing at the same time.

+ + +
+ + + diff --git a/FMOD/doc/FMOD API User Manual/studio-api-bank.html b/FMOD/doc/FMOD API User Manual/studio-api-bank.html new file mode 100644 index 0000000..a194bdf --- /dev/null +++ b/FMOD/doc/FMOD API User Manual/studio-api-bank.html @@ -0,0 +1,766 @@ + + +Studio API Reference | Studio::Bank + + + + +
+ +
+

16. Studio API Reference | Studio::Bank

+

Banks made in FMOD Studio contain the metadata and audio sample data required for runtime mixing and playback. Audio sample data may be packed into the same bank as the event metadata which references it, or it may be packed into separate banks.

+

Loading:

+ +

Buses:

+
    +
  • Studio::Bank::getBusCount Retrieves the number of buses in the bank. This is only relevant for master banks, as other banks do not contain buses.
  • +
  • Studio::Bank::getBusList Retrieves a list of the buses in the bank. This is only relevant for master banks, as other banks do not contain buses.
  • +
+

Events:

+ +

String Table:

+ +

VCAs:

+ +

General:

+ +

See Also:

+ +

Studio::Bank::getBusCount

+

Retrieves the number of buses in the bank. This is only relevant for master banks, as other banks do not contain buses.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
FMOD_RESULT Studio::Bank::getBusCount(
+  int *count
+);
+
+ +
FMOD_RESULT FMOD_Studio_Bank_GetBusCount(
+  FMOD_STUDIO_BANK *bank,
+  int *count
+);
+
+ +
RESULT Studio.Bank.getBusCount(
+  out int count
+);
+
+ +
Bank.getBusCount(
+  count
+);
+
+ +
+
count Out
+
Bus count.
+
+

May be used in conjunction with Studio::Bank::getBusList to enumerate the buses in the bank.

+

Studio::Bank::getBusList

+

Retrieves a list of the buses in the bank. This is only relevant for master banks, as other banks do not contain buses.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
FMOD_RESULT Studio::Bank::getBusList(
+  Studio::Bus **array,
+  int capacity,
+  int *count
+);
+
+ +
FMOD_RESULT FMOD_Studio_Bank_GetBusList(
+  FMOD_STUDIO_BANK *bank,
+  FMOD_STUDIO_BUS **array,
+  int capacity,
+  int *count
+);
+
+ +
RESULT Studio.Bank.getBusList(
+  out Bus[] array
+);
+
+ +
Bank.getBusList(
+  array,
+  capacity,
+  count
+);
+
+ +
+
array Out
+
Array to receive the list. (Studio::Bus)
+
capacity
+
Capacity of array.
+
count OutOpt
+
Number of buses written to array.
+
+

May be used in conjunction with Studio::Bank::getBusCount to enumerate the buses in the bank.

+

This function returns a maximum of capacity buses from the bank. If the bank contains more than capacity buses additional buses will be silently ignored.

+

Studio::Bank::getEventCount

+

Retrieves the number of event descriptions in the bank.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
FMOD_RESULT Studio::Bank::getEventCount(
+  int *count
+);
+
+ +
FMOD_RESULT FMOD_Studio_Bank_GetEventCount(
+  FMOD_STUDIO_BANK *bank,
+  int *count
+);
+
+ +
RESULT Studio.Bank.getEventCount(
+  out int count
+);
+
+ +
Bank.getEventCount(
+  count
+);
+
+ +
+
count Out
+
Event description count.
+
+

May be used in conjunction with Studio::Bank::getEventList to enumerate the events in the bank.

+

This function counts the events which were added to the bank by the sound designer. The bank may contain additional events which are referenced by event instruments but were not added to the bank, and those referenced events are not counted.

+

Studio::Bank::getEventList

+

Retrieves a list of the event descriptions in the bank.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
FMOD_RESULT Studio::Bank::getEventList(
+  Studio::EventDescription **array,
+  int capacity,
+  int *count
+);
+
+ +
FMOD_RESULT FMOD_Studio_Bank_GetEventList(
+  FMOD_STUDIO_BANK *bank,
+  FMOD_STUDIO_EVENTDESCRIPTION **array,
+  int capacity,
+  int *count
+);
+
+ +
RESULT Studio.Bank.getEventList(
+  out EventDescription[] array
+);
+
+ +
Bank.getEventList(
+  array,
+  capacity,
+  count
+);
+
+ +
+
array Out
+
Array to receive the list. (Studio::EventDescription)
+
capacity
+
Capacity of array.
+
count OutOpt
+
Number of event descriptions written to array.
+
+

This function returns a maximum of capacity events from the bank. If the bank contains more than capacity events then additional events will be silently ignored.

+

May be used in conjunction with Studio::Bank::getEventCount to enumerate the events in the bank.

+

This function retrieves the events which were added to the bank by the sound designer. The bank may contain additional events which are referenced by event instruments but were not added to the bank, and those referenced events are not retrieved.

+

Studio::Bank::getID

+

Retrieves the bank's GUID.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
FMOD_RESULT Studio::Bank::getID(
+  FMOD_GUID *id
+);
+
+ +
FMOD_RESULT FMOD_Studio_Bank_GetID(
+  FMOD_STUDIO_BANK *bank,
+  FMOD_GUID *id
+);
+
+ +
RESULT Studio.Bank.getID(
+  out Guid id
+);
+
+ +
Bank.getID(
+  id
+);
+
+ +
+
id Out
+
Bank GUID. (FMOD_GUID)
+
+

Studio::Bank::getLoadingState

+

Retrieves the loading state.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
FMOD_RESULT Studio::Bank::getLoadingState(
+  FMOD_STUDIO_LOADING_STATE *state
+);
+
+ +
FMOD_RESULT FMOD_Studio_Bank_GetLoadingState(
+  FMOD_STUDIO_BANK *bank,
+  FMOD_STUDIO_LOADING_STATE *state
+);
+
+ +
RESULT Studio.Bank.getLoadingState(
+  out LOADING_STATE state
+);
+
+ +
Bank.getLoadingState(
+  state
+);
+
+ +
+
state Out
+
Loading state. (FMOD_STUDIO_LOADING_STATE)
+
+

This function may be used to check the loading state of a bank which has been loaded asynchronously using the FMOD_STUDIO_LOAD_BANK_NONBLOCKING flag, or is pending unload following a call to Studio::Bank::unload.

+

If an asynchronous load failed due to a file error state will contain FMOD_STUDIO_LOADING_STATE_ERROR and the return code from this function will be the error code of the bank load function.

+

See Also: Studio::System::loadBankFile, Studio::System::loadBankMemory, Studio::System::loadBankCustom

+

Studio::Bank::getPath

+

Retrieves the path.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
FMOD_RESULT Studio::Bank::getPath(
+  char *path,
+  int size,
+  int *retrieved
+);
+
+ +
FMOD_RESULT FMOD_Studio_Bank_GetPath(
+  FMOD_STUDIO_BANK *bank,
+  char *path,
+  int size,
+  int *retrieved
+);
+
+ +
RESULT Studio.Bank.getPath(
+  out string path
+);
+
+ +
Bank.getPath(
+  path,
+  size,
+  retrieved
+);
+
+ +
+
path OutOpt
+
Buffer to receive the path. (UTF-8 string)
+
size
+
Size of the path buffer in bytes. Must be 0 if path is null.
+
retrieved OutOpt
+
Length of the path in bytes, including the terminating null character.
+
+

The strings bank must be loaded prior to calling this function, otherwise FMOD_ERR_EVENT_NOTFOUND is returned.

+

If the path is longer than size then it is truncated and this function returns FMOD_ERR_TRUNCATED.

+

The retrieved parameter can be used to get the buffer size required to hold the full path

+

Studio::Bank::getSampleLoadingState

+

Retrieves the loading state of the samples in the bank.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
FMOD_RESULT Studio::Bank::getSampleLoadingState(
+  FMOD_STUDIO_LOADING_STATE *state
+);
+
+ +
FMOD_RESULT FMOD_Studio_Bank_GetSampleLoadingState(
+  FMOD_STUDIO_BANK *bank,
+  FMOD_STUDIO_LOADING_STATE *state
+);
+
+ +
RESULT Studio.Bank.getSampleLoadingState(
+  out LOADING_STATE state
+);
+
+ +
Bank.getSampleLoadingState(
+  state
+);
+
+ +
+
state Out
+
Loading state. (FMOD_STUDIO_LOADING_STATE)
+
+

May be used for tracking the status of the Studio::Bank::loadSampleData operation.

+

If Studio::Bank::loadSampleData has not been called for the bank then this function will return FMOD_STUDIO_LOADING_STATE_UNLOADED even though sample data may have been loaded by other API calls.

+

See also: Studio::Bank::unloadSampleData, Sample Data Loading

+

Studio::Bank::getStringCount

+

Retrieves the number of string table entries in the bank. This is only relevant for studio string banks, as other banks do not contain string tables.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
FMOD_RESULT Studio::Bank::getStringCount(
+  int *count
+);
+
+ +
FMOD_RESULT FMOD_Studio_Bank_GetStringCount(
+  FMOD_STUDIO_BANK *bank,
+  int *count
+);
+
+ +
RESULT Studio.Bank.getStringCount(
+  out int count
+);
+
+ +
Bank.getStringCount(
+  count
+);
+
+ +
+
count Out
+
String table entry count.
+
+

May be used in conjunction with Studio::Bank::getStringInfo to enumerate the string table in a bank.

+

See Also: strings bank

+

Studio::Bank::getStringInfo

+

Retrieves a string table entry. This is only relevant for studio string banks, as other banks do not contain string tables.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
FMOD_RESULT Studio::Bank::getStringInfo(
+  int index,
+  FMOD_GUID *id,
+  char *path,
+  int size,
+  int *retrieved
+);
+
+ +
FMOD_RESULT FMOD_Studio_Bank_GetStringInfo(
+  FMOD_STUDIO_BANK *bank,
+  int index,
+  FMOD_GUID *id,
+  char *path,
+  int size,
+  int *retrieved
+);
+
+ +
RESULT Studio.Bank.getStringInfo(
+  int index,
+  out Guid id,
+  out string path
+);
+
+ +
Bank.getStringInfo(
+  index,
+  id,
+  path,
+  size,
+  retrieved
+);
+
+ +
+
index
+
String table entry index.
+
id OutOpt
+
GUID. (FMOD_GUID)
+
path OutOpt
+
Path. (UTF-8 string)
+
size
+
Size of the path buffer in bytes. Must be 0 if path is null.
+
retrieved OutOpt
+
Length of the retrieved path in bytes, including the terminating null character.
+
+

May be used in conjunction with Studio::Bank::getStringCount to enumerate the string table in a bank.

+

If the path is longer than size then it is truncated and this function returns FMOD_ERR_TRUNCATED.

+

The retrieved parameter can be used to get the buffer size required to hold the full path

+

See Also: Strings bank, Studio::System::lookupID, Studio::System::lookupPath

+

Studio::Bank::getUserData

+

Retrieves the bank's user data.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
FMOD_RESULT Studio::Bank::getUserData(
+  void **userdata
+);
+
+ +
FMOD_RESULT FMOD_Studio_Bank_GetUserData(
+  FMOD_STUDIO_BANK *bank,
+  void **userdata
+);
+
+ +
RESULT Studio.Bank.getUserData(
+  out IntPtr userdata
+);
+
+ +
Bank.getUserData(
+  userdata
+);
+
+ +
+
userdata Out
+
User data set by calling Studio::Bank::setUserData.
+
+

This function allows arbitrary user data to be retrieved from this object. For information about setting a bank's user data, see Studio::Bank::getUserData. For an example of how to get and set user data, see the User Data section of the glossary.

+

Studio::Bank::getVCACount

+

Retrieves the number of VCAs in the bank.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
FMOD_RESULT Studio::Bank::getVCACount(
+  int *count
+);
+
+ +
FMOD_RESULT FMOD_Studio_Bank_GetVCACount(
+  FMOD_STUDIO_BANK *bank,
+  int *count
+);
+
+ +
RESULT Studio.Bank.getVCACount(
+  out int count
+);
+
+ +
Bank.getVCACount(
+  count
+);
+
+ +
+
count Out
+
VCA count.
+
+

May be used in conjunction with Studio::Bank::getVCAList to enumerate the VCAs in a bank.

+

Studio::Bank::getVCAList

+

Retrieves a list of the VCAs in the bank.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
FMOD_RESULT Studio::Bank::getVCAList(
+  Studio::VCA **array,
+  int capacity,
+  int *count
+);
+
+ +
FMOD_RESULT FMOD_Studio_Bank_GetVCAList(
+  FMOD_STUDIO_BANK *bank,
+  FMOD_STUDIO_VCA **array,
+  int capacity,
+  int *count
+);
+
+ +
RESULT Studio.Bank.getVCAList(
+  out VCA[] array
+);
+
+ +
Bank.getVCAList(
+  array,
+  capacity,
+  count
+);
+
+ +
+
array Out
+
Array to receive the list. (Studio::VCA)
+
capacity
+
Capacity of array.
+
count OutOpt
+
Number of VCAs written to array.
+
+

May be used in conjunction with Studio::Bank::getVCACount to enumerate the VCAs in a bank.

+

This function returns a maximum of capacity VCAs from the bank. If the bank contains more than capacity VCAs additional VCAs will be silently ignored.

+

Studio::Bank::isValid

+

Checks that the bank reference is valid.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
bool Studio::Bank::isValid()
+
+ +
bool FMOD_Studio_Bank_IsValid(FMOD_STUDIO_BANK *bank)
+
+ +
bool Studio.Bank.isValid()
+
+ +
Studio.Bank.isValid()
+
+ +

Studio::Bank::loadSampleData

+

Loads non-streaming sample data for all events in the bank.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
FMOD_RESULT Studio::Bank::loadSampleData();
+
+ +
FMOD_RESULT FMOD_Studio_Bank_LoadSampleData(FMOD_STUDIO_BANK *bank);
+
+ +
RESULT Studio.Bank.loadSampleData();
+
+ +
Bank.loadSampleData();
+
+ +

Use this function to preload sample data ahead of time so that the events in the bank can play immediately when started.

+

This function is equivalent to calling Studio::EventDescription::loadSampleData for all events in the bank, including referenced events.

+

See Also: Studio::Bank::getSampleLoadingState, Studio::Bank::unloadSampleData, Sample Data Loading

+

Studio::Bank::setUserData

+

Sets the bank's user data.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
FMOD_RESULT Studio::Bank::setUserData(
+  void *userdata
+);
+
+ +
FMOD_RESULT FMOD_Studio_Bank_SetUserData(
+  FMOD_STUDIO_BANK *bank,
+  void *userdata
+);
+
+ +
RESULT Studio.Bank.setUserData(
+  IntPtr userdata
+);
+
+ +
Bank.setUserData(
+  userdata
+);
+
+ +
+
userdata
+
User data.
+
+

This function allows arbitrary user data to be attached to this object. See the User Data section of the glossary for an example of how to get and set user data.

+

See Also: Studio::Bank::getUserData

+

Studio::Bank::unload

+

Unloads the bank.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
FMOD_RESULT Studio::Bank::unload();
+
+ +
FMOD_RESULT FMOD_Studio_Bank_Unload(FMOD_STUDIO_BANK *bank);
+
+ +
RESULT Studio.Bank.unload();
+
+ +
Bank.unload();
+
+ +

This will destroy all objects created from the bank, unload all sample data inside the bank, and invalidate all API handles referring to the bank.

+

If the bank was loaded from user-managed memory, e.g. by Studio::System::loadBankMemory with the FMOD_STUDIO_LOAD_MEMORY_POINT mode, then the memory must not be freed until the unload has completed. Poll the loading state using Studio::Bank::getLoadingState or use the FMOD_STUDIO_SYSTEM_CALLBACK_BANK_UNLOAD system callback to determine when it is safe to free the memory.

+

See Also: Studio::System::loadBankFile, Studio::System::loadBankCustom, Studio::System::setCallback

+

Studio::Bank::unloadSampleData

+

Unloads non-streaming sample data for all events in the bank.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
FMOD_RESULT Studio::Bank::unloadSampleData();
+
+ +
FMOD_RESULT FMOD_Studio_Bank_UnloadSampleData(FMOD_STUDIO_BANK *bank);
+
+ +
RESULT Studio.Bank.unloadSampleData();
+
+ +
Bank.unloadSampleData();
+
+ +

Sample data loading is reference counted and the sample data will remain loaded until unload requests corresponding to all load requests are made, or until the bank is unloaded. For more details see Sample Data Loading.

+

See Also: Studio::Bank::loadSampleData

+ + +
+ + + diff --git a/FMOD/doc/FMOD API User Manual/studio-api-bus.html b/FMOD/doc/FMOD API User Manual/studio-api-bus.html new file mode 100644 index 0000000..60dce45 --- /dev/null +++ b/FMOD/doc/FMOD API User Manual/studio-api-bus.html @@ -0,0 +1,721 @@ + + +Studio API Reference | Studio::Bus + + + + +
+ +
+

16. Studio API Reference | Studio::Bus

+

Represents a global mixer bus.

+

Playback Control:

+ +

Playback Properties:

+ +

Core:

+ +

Profiling:

+ +

General:

+ +

Studio::Bus::getChannelGroup

+

Retrieves the core ChannelGroup.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
FMOD_RESULT Studio::Bus::getChannelGroup(
+  ChannelGroup **group
+);
+
+ +
FMOD_RESULT FMOD_Studio_Bus_GetChannelGroup(
+  FMOD_STUDIO_BUS *bus,
+  FMOD_CHANNELGROUP **group
+);
+
+ +
RESULT Studio.Bus.getChannelGroup(
+  out FMOD.ChannelGroup group
+);
+
+ +
Bus.getChannelGroup(
+  group
+);
+
+ +
+
group Out
+
Core ChannelGroup. (ChannelGroup)
+
+

By default the ChannelGroup will only exist when it is needed; see Signal Paths for details. If the ChannelGroup does not exist, this function will return FMOD_ERR_STUDIO_NOT_LOADED.

+

See Also: Studio::Bus::lockChannelGroup

+

Studio::Bus::getCPUUsage

+

Retrieves the bus CPU usage data.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
FMOD_RESULT Studio::Bus::getCPUUsage(
+  unsigned int *exclusive,
+  unsigned int *inclusive
+);
+
+ +
FMOD_RESULT FMOD_Studio_Bus_GetCPUUsage(
+  FMOD_STUDIO_BUS *bus,
+  unsigned int *exclusive,
+  unsigned int *inclusive
+);
+
+ +
RESULT Studio.Bus.getCPUUsage(
+  out uint exclusive,
+  out uint inclusive
+);
+
+ +
Studio.Bus.getCPUUsage(
+    exclusive,
+    inclusive
+);
+
+ +
+
exclusive OutOpt
+
+

CPU time spent processing the events of this bus.

+
    +
  • Units: Microseconds
  • +
+
+
inclusive OutOpt
+
+

CPU time spent processing the events and all input buses of this bus.

+
    +
  • Units: Microseconds
  • +
+
+
+

FMOD_INIT_PROFILE_ENABLE with System::init is required to call this function.

+

Studio::Bus::getID

+

Retrieves the GUID.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
FMOD_RESULT Studio::Bus::getID(
+  FMOD_GUID *id
+);
+
+ +
FMOD_RESULT FMOD_Studio_Bus_GetID(
+  FMOD_STUDIO_BUS *bus,
+  FMOD_GUID *id
+);
+
+ +
RESULT Studio.Bus.getID(
+  out Guid id
+);
+
+ +
Bus.getID(
+  id
+);
+
+ +
+
id Out
+
GUID. (FMOD_GUID)
+
+

Studio::Bus::getMemoryUsage

+

Retrieves memory usage statistics.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
FMOD_RESULT Studio::Bus::getMemoryUsage(
+  FMOD_STUDIO_MEMORY_USAGE *memoryusage
+);
+
+ +
FMOD_RESULT FMOD_Studio_Bus_GetMemoryUsage(
+  FMOD_STUDIO_BUS *bus,
+  FMOD_STUDIO_MEMORY_USAGE *memoryusage
+);
+
+ +
RESULT Studio.Bus.getMemoryUsage(
+  out MEMORY_USAGE memoryusage
+);
+
+ +
+

Not supported for JavaScript.

+
+
+
memoryusage Out
+
Memory usage. (FMOD_STUDIO_MEMORY_USAGE)
+
+

Memory usage statistics are only available in logging builds, in release builds memoryusage will contain zero for all values after calling this function.

+

Studio::Bus::getMute

+

Retrieves the mute state.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
FMOD_RESULT Studio::Bus::getMute(
+  bool *mute
+);
+
+ +
FMOD_RESULT FMOD_Studio_Bus_GetMute(
+  FMOD_STUDIO_BUS *bus,
+  FMOD_BOOL *mute
+);
+
+ +
RESULT Studio.Bus.getMute(
+  out bool mute
+);
+
+ +
Bus.getMute(
+  mute
+);
+
+ +
+
mute Out
+
+

Mute state. True if the bus is muted.

+
    +
  • Units: Boolean
  • +
+
+
+

See Also: Studio::Bus::setMute

+

Studio::Bus::getPath

+

Retrieves the path.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
FMOD_RESULT Studio::Bus::getPath(
+  char *path,
+  int size,
+  int *retrieved
+);
+
+ +
FMOD_RESULT FMOD_Studio_Bus_GetPath(
+  FMOD_STUDIO_BUS *bus,
+  char *path,
+  int size,
+  int *retrieved
+);
+
+ +
RESULT Studio.Bus.getPath(
+  out string path
+);
+
+ +
Bus.getPath(
+  path,
+  size,
+  retrieved
+);
+
+ +
+
path OutOpt
+
Buffer to receive the path. (UTF-8 string)
+
size
+
Size of the path buffer in bytes. Must be 0 if path is null.
+
retrieved OutOpt
+
Length of the path in bytes, including the terminating null character.
+
+

The strings bank must be loaded prior to calling this function, otherwise FMOD_ERR_EVENT_NOTFOUND is returned.

+

If the path is longer than size then it is truncated and this function returns FMOD_ERR_TRUNCATED.

+

The retrieved parameter can be used to get the buffer size required to hold the full path.

+

Studio::Bus::getPaused

+

Retrieves the pause state.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
FMOD_RESULT Studio::Bus::getPaused(
+  bool *paused
+);
+
+ +
FMOD_RESULT FMOD_Studio_Bus_GetPaused(
+  FMOD_STUDIO_BUS *bus,
+  FMOD_BOOL *paused
+);
+
+ +
RESULT Studio.Bus.getPaused(
+  out bool paused
+);
+
+ +
Bus.getPaused(
+  paused
+);
+
+ +
+
paused Out
+
+

Pause state. True if the bus is paused.

+
    +
  • Units: Boolean
  • +
+
+
+

See Also: Studio::Bus::setPaused

+

Studio::Bus::getPortIndex

+

Retrieves the port index assigned to the bus.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
FMOD_RESULT Studio::Bus::getPortIndex(
+  FMOD_PORT_INDEX *index
+);
+
+ +
FMOD_RESULT FMOD_Studio_Bus_GetPortIndex(
+  FMOD_STUDIO_BUS *bus,
+  FMOD_PORT_INDEX *index
+);
+
+ +
RESULT Studio.Bus.getPortIndex(
+  out ulong index
+);
+
+ +
Bus.getPortIndex(
+  index
+);
+
+ +
+
index Out
+
The port index assigned to the bus. (FMOD_PORT_INDEX)
+
+

See Also: Studio::Bus::setPortIndex

+

Studio::Bus::getVolume

+

Retrieves the volume level.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
FMOD_RESULT Studio::Bus::getVolume(
+  float *volume,
+  float *finalvolume = nullptr
+);
+
+ +
FMOD_RESULT FMOD_Studio_Bus_GetVolume(
+  FMOD_STUDIO_BUS *bus,
+  float *volume,
+  float *finalvolume
+);
+
+ +
RESULT Studio.Bus.getVolume(
+  out float volume
+);
+RESULT Studio.Bus.getVolume(
+  out float volume,
+  out float finalvolume
+);
+
+ +
Bus.getVolume(
+  volume,
+  finalvolume
+);
+
+ +
+
volume OutOpt
+
Volume set via Studio::Bus::setVolume.
+
finalvolume OutOpt
+
Final combined volume.
+
+

The finalvolume value is calculated by combining the volume set via Studio::Bus::setVolume with the bus's default volume and any snapshots or VCAs that affect the bus. Volume changes are processed in the Studio system update, so finalvolume will be the value calculated by the last update.

+

Studio::Bus::isValid

+

Checks that the Bus reference is valid.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
bool Studio::Bus::isValid()
+
+ +
bool FMOD_Studio_Bus_IsValid(FMOD_STUDIO_BUS *bus)
+
+ +
bool Studio.Bus.isValid()
+
+ +
Studio.Bus.isValid()
+
+ +

Studio::Bus::lockChannelGroup

+

Locks the core ChannelGroup.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
FMOD_RESULT Studio::Bus::lockChannelGroup();
+
+ +
FMOD_RESULT FMOD_Studio_Bus_LockChannelGroup(FMOD_STUDIO_BUS *bus);
+
+ +
RESULT Studio.Bus.lockChannelGroup();
+
+ +
Bus.lockChannelGroup();
+
+ +

This function forces the system to create the ChannelGroup and keep it available until Studio::Bus::unlockChannelGroup is called. See Signal Paths for details.

+
+

The ChannelGroup may not be available immediately after calling this function. When Studio has been initialized in asynchronous mode, the ChannelGroup will not be created until the command has been executed in the async thread. When Studio has been initialized with FMOD_STUDIO_INIT_SYNCHRONOUS_UPDATE, the ChannelGroup will be created in the next Studio::System::update call.

+

You can call Studio::System::flushCommands to ensure the ChannelGroup has been created. Alternatively you can keep trying to obtain the ChannelGroup via Studio::Bus::getChannelGroup until it is ready.

+
+

Studio::Bus::setMute

+

Sets the mute state.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
FMOD_RESULT Studio::Bus::setMute(
+  bool mute
+);
+
+ +
FMOD_RESULT FMOD_Studio_Bus_SetMute(
+  FMOD_STUDIO_BUS *bus,
+  FMOD_BOOL mute
+);
+
+ +
RESULT Studio.Bus.setMute(
+  bool mute
+);
+
+ +
Bus.setMute(
+  mute
+);
+
+ +
+
mute
+
+

Mute state. True to mute the bus.

+
    +
  • Units: Boolean
  • +
+
+
+

Mute is an additional control for volume, the effect of which is equivalent to setting the volume to zero.

+

An individual mute state is kept for each bus. Muting a bus will override the mute state of its inputs (meaning they return true from Studio::Bus::getMute), while unmuting a bus will cause its inputs to obey their individual mute state. The mute state is processed in the Studio system update, so Studio::Bus::getMute will return the state as determined by the last update.

+

Studio::Bus::setPaused

+

Sets the pause state.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
FMOD_RESULT Studio::Bus::setPaused(
+  bool paused
+);
+
+ +
FMOD_RESULT FMOD_Studio_Bus_SetPaused(
+  FMOD_STUDIO_BUS *bus,
+  FMOD_BOOL paused
+);
+
+ +
RESULT Studio.Bus.setPaused(
+  bool paused
+);
+
+ +
Bus.setPaused(
+  paused
+);
+
+ +
+
paused
+
+

Pause state. True to pause the bus.

+
    +
  • Units: Boolean
  • +
+
+
+

This function allows pausing/unpausing of all audio routed into the bus.

+

An individual pause state is kept for each bus. Pausing a bus will override the pause state of its inputs (meaning they return true from Studio::Bus::getPaused), while unpausing a bus will cause its inputs to obey their individual pause state. The pause state is processed in the Studio system update, so Studio::Bus::getPaused will return the state as determined by the last update.

+

Studio::Bus::setPortIndex

+

Sets the port index to use when attaching to an output port.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
FMOD_RESULT Studio::Bus::setPortIndex(
+  FMOD_PORT_INDEX index
+);
+
+ +
FMOD_RESULT FMOD_Studio_Bus_SetPortIndex(
+  FMOD_STUDIO_BUS *bus,
+  FMOD_PORT_INDEX index
+);
+
+ +
RESULT Studio.Bus.setPortIndex(
+  ulong index
+);
+
+ +
Bus.setPortIndex(
+  index
+);
+
+ +
+
index
+
Port index to use when attaching to an output port. (FMOD_PORT_INDEX)
+
+

When a bus which is an output port is instantiated it is connected to an output port based on the port type set in FMOD Studio. For some port types, a platform-specific port index is required to connect to the correct output port. For example, if the output port type is a speaker in a controller, then a platform-specific port index may be required to specify which controller the bus is to attach to. In such a case, call this function passing the platform specific port index.

+

There is no need to call this function for port types which do not require an index.

+

This function may be called at any time after a bank containing the bus has been loaded.

+

See Also: Studio::Bus::getPortIndex, FMOD_PORT_TYPE

+

Studio::Bus::setVolume

+

Sets the volume level.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
FMOD_RESULT Studio::Bus::setVolume(
+  float volume
+);
+
+ +
FMOD_RESULT FMOD_Studio_Bus_SetVolume(
+  FMOD_STUDIO_BUS *bus,
+  float volume
+);
+
+ +
RESULT Studio.Bus.setVolume(
+  float volume
+);
+
+ +
Bus.setVolume(
+  volume
+);
+
+ +
+
volume
+
+

Volume level. Negative level inverts the signal.

+
    +
  • Units: Linear
  • +
  • Range: (-inf, inf)
  • +
  • Default: 1
  • +
+
+
+

This volume is applied as a scaling factor to the volume level set in FMOD Studio.

+

See Also: Studio::Bus::getVolume

+

Studio::Bus::stopAllEvents

+

Stops all event instances that are routed into the bus.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
FMOD_RESULT Studio::Bus::stopAllEvents(
+  FMOD_STUDIO_STOP_MODE mode
+);
+
+ +
FMOD_RESULT FMOD_Studio_Bus_StopAllEvents(
+  FMOD_STUDIO_BUS *bus,
+  FMOD_STUDIO_STOP_MODE mode
+);
+
+ +
RESULT Studio.Bus.stopAllEvents(
+  STOP_MODE mode
+);
+
+ +
Bus.stopAllEvents(
+  mode
+);
+
+ +
+
mode
+
Stop mode. (FMOD_STUDIO_STOP_MODE)
+
+

See Also: Studio::EventInstance::stop

+

Studio::Bus::unlockChannelGroup

+

Unlocks the core ChannelGroup.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
FMOD_RESULT Studio::Bus::unlockChannelGroup();
+
+ +
FMOD_RESULT FMOD_Studio_Bus_UnlockChannelGroup(FMOD_STUDIO_BUS *bus);
+
+ +
RESULT Studio.Bus.unlockChannelGroup();
+
+ +
Bus.unlockChannelGroup();
+
+ +

This function allows the system to destroy the ChannelGroup when it is not needed. See Signal Paths for details.

+

See Also: Studio::Bus::lockChannelGroup

+ + +
+ + + diff --git a/FMOD/doc/FMOD API User Manual/studio-api-commandreplay.html b/FMOD/doc/FMOD API User Manual/studio-api-commandreplay.html new file mode 100644 index 0000000..e3a8fb6 --- /dev/null +++ b/FMOD/doc/FMOD API User Manual/studio-api-commandreplay.html @@ -0,0 +1,1172 @@ + + +Studio API Reference | Studio::CommandReplay + + + + +
+ +
+

16. Studio API Reference | Studio::CommandReplay

+

The FMOD Studio command replay system allows API calls in a session to be recorded and later played back for debugging and performance purposes.

+

Setup:

+ +
+ +
+ +

Playback:

+ +

Query:

+ +

Lifetime:

+ +

See also:

+ +

FMOD_STUDIO_COMMANDREPLAY_CREATE_INSTANCE_CALLBACK

+

Callback for command replay event instance creation.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
FMOD_RESULT F_CALL FMOD_STUDIO_COMMANDREPLAY_CREATE_INSTANCE_CALLBACK(
+  FMOD_STUDIO_COMMANDREPLAY *replay,
+  int commandindex,
+  FMOD_STUDIO_EVENTDESCRIPTION *eventdescription,
+  FMOD_STUDIO_EVENTINSTANCE **instance,
+  void *userdata
+);
+
+ +
delegate RESULT Studio.COMMANDREPLAY_CREATE_INSTANCE_CALLBACK(
+  IntPtr replay,
+  int commandindex,
+  IntPtr eventdescription,
+  out IntPtr instance,
+  IntPtr userdata
+);
+
+ +
+

Not supported for JavaScript.

+
+
+
replay
+
Command replay. (Studio::CommandReplay)
+
commandindex
+
Current playback command index.
+
eventdescription
+
Event description to use. (Studio::EventDescription)
+
instance OutOpt
+
The event instance created by this function. (Studio::EventInstance)
+
userdata
+
The userdata set with Studio::CommandReplay::setUserData
+
+
+

The replay argument can be cast to FMOD::Studio::CommandReplay *.

+

The eventdescription argument can be cast to FMOD::Studio::EventDescription *.

+

The instance argument can be cast to FMOD::Studio::EventInstance *.

+
+
+

The 'replay' argument can be used via CommandReplay by using FMOD.Studio.CommandReplay commandReplay = new FMOD.Studio.CommandReplay(replay);

+

The 'eventdescription' argument can be used via EventDescription by using FMOD.EventDescription description = new FMOD.EventDescription(eventdescription);

+

The 'instance' argument can be used via EventInstance by using FMOD.EventInstance eventInstance = new FMOD.EventInstance(instance);

+
+

See Also: Studio::CommandReplay::setCreateInstanceCallback

+

FMOD_STUDIO_COMMANDREPLAY_FRAME_CALLBACK

+

Callback for when the command replay goes to the next frame.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
FMOD_RESULT F_CALL FMOD_STUDIO_COMMANDREPLAY_FRAME_CALLBACK(
+  FMOD_STUDIO_COMMANDREPLAY *replay,
+  int commandindex,
+  float currenttime,
+  void *userdata
+);
+
+ +
delegate RESULT Studio.COMMANDREPLAY_FRAME_CALLBACK(
+  IntPtr replay,
+  int commandindex,
+  float currenttime,
+  IntPtr userdata
+);
+
+ +
+

Currently not supported for JavaScript.

+
+
+
replay
+
Command replay. (Studio::CommandReplay)
+
commandindex
+
Current playback command index.
+
currenttime
+
Current playback time.
+
userdata
+
The userdata set with Studio::CommandReplay::setUserData
+
+
+

The replay argument can be cast to FMOD::Studio::CommandReplay *.

+
+
+

The 'replay' argument can be used via CommandReplay by using FMOD.Studio.CommandReplay commandReplay = new FMOD.Studio.CommandReplay(replay);

+
+

See Also: Studio::CommandReplay::setFrameCallback

+

Studio::CommandReplay::getCommandAtTime

+

Retrieves the command index corresponding to the given playback time.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
FMOD_RESULT Studio::CommandReplay::getCommandAtTime(
+  float time,
+  int *commandindex
+);
+
+ +
FMOD_RESULT FMOD_Studio_CommandReplay_GetCommandAtTime(
+  FMOD_STUDIO_COMMANDREPLAY *commandreplay,
+  float time,
+  int *commandindex
+);
+
+ +
RESULT Studio.CommandReplay.getCommandAtTime(
+  float time,
+  out int commandindex
+);
+
+ +
Studio.CommandReplay.getCommandAtTime(
+  time,
+  commandindex
+);
+
+ +
+
time
+
The time used to find a command index.
+
commandindex Out
+
Command index.
+
+

This function will return an index for the first command at or after time. If time is greater than the total playback time then FMOD_ERR_EVENT_NOTFOUND is returned.

+

See Also: Studio::CommandReplay::getLength

+

Studio::CommandReplay::getCommandCount

+

Retrieves the number of commands in the replay.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
FMOD_RESULT Studio::CommandReplay::getCommandCount(
+  int *count
+);
+
+ +
FMOD_RESULT FMOD_Studio_CommandReplay_GetCommandCount(
+  FMOD_STUDIO_COMMANDREPLAY *commandreplay,
+  int *count
+);
+
+ +
RESULT Studio.CommandReplay.getCommandCount(
+  out int count
+);
+
+ +
Studio.CommandReplay.getCommandCount(
+  count
+);
+
+ +
+
count Out
+
Number of commands in the replay.
+
+

May be used in conjunction with Studio::CommandReplay::getCommandInfo to enumerate the commands in the replay.

+

Studio::CommandReplay::getCommandInfo

+

Retrieves command information.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
FMOD_RESULT Studio::CommandReplay::getCommandInfo(
+  int commandindex,
+  FMOD_STUDIO_COMMAND_INFO *info
+);
+
+ +
FMOD_RESULT FMOD_Studio_CommandReplay_GetCommandInfo(
+  FMOD_STUDIO_COMMANDREPLAY *commandreplay,
+  int commandindex,
+  FMOD_STUDIO_COMMAND_INFO *info
+);
+
+ +
RESULT Studio.CommandReplay.getCommandInfo(
+  int commandindex,
+  out COMMAND_INFO info
+);
+
+ +
Studio.CommandReplay.getCommandInfo(
+  commandindex,
+  info
+);
+
+ +
+
commandindex
+
The index of the command.
+
info Out
+
Command info structure. (FMOD_STUDIO_COMMAND_INFO)
+
+

May be used in conjunction with Studio::CommandReplay::getCommandCount to enumerate the commands in the replay.

+

Studio::CommandReplay::getCommandString

+

Retrieves the string representation of a command.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
FMOD_RESULT Studio::CommandReplay::getCommandString(
+  int commandindex,
+  char *buffer,
+  int length
+);
+
+ +
FMOD_RESULT FMOD_Studio_CommandReplay_GetCommandString(
+  FMOD_STUDIO_COMMANDREPLAY *commandreplay,
+  int commandindex,
+  char *buffer,
+  int length
+);
+
+ +
RESULT Studio.CommandReplay.getCommandString(
+  int commandindex,
+  out string buffer
+);
+
+ +
Studio.CommandReplay.getCommandString(
+  commandindex,
+  buffer
+);
+
+ +
+
commandindex
+
The index of the command.
+
buffer
+
Buffer to receive the string.
+
length
+
The capacity of the buffer.
+
+

If the string representation of the command is too long to fit in the buffer it will be truncated and this function will return FMOD_ERR_TRUNCATED.

+

Studio::CommandReplay::getCurrentCommand

+

Retrieves the progress through the command replay.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
FMOD_RESULT Studio::CommandReplay::getCurrentCommand(
+  int *commandindex,
+  float *currenttime
+);
+
+ +
FMOD_RESULT FMOD_Studio_CommandReplay_GetCurrentCommand(
+  FMOD_STUDIO_COMMANDREPLAY *commandreplay,
+  int *commandindex,
+  float *currenttime
+);
+
+ +
RESULT Studio.CommandReplay.getCurrentCommand(
+  out int commandindex,
+  out float currenttime
+);
+
+ +
Studio.CommandReplay.getCurrentCommand(
+  commandindex,
+  currenttime
+);
+
+ +
+
commandindex OutOpt
+
The current command index.
+
currenttime OutOpt
+
The current playback time.
+
+

If this function is called before Studio::CommandReplay::start then both commandindex and currenttime will be returned as 0. If this function is called after Studio::CommandReplay::stop then the index and time of the last command which was replayed will be returned.

+

Studio::CommandReplay::getLength

+

Retrieves the total playback time.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
FMOD_RESULT Studio::CommandReplay::getLength(
+  float *length
+);
+
+ +
FMOD_RESULT FMOD_Studio_CommandReplay_GetLength(
+  FMOD_STUDIO_COMMANDREPLAY *commandreplay,
+  float *length
+);
+
+ +
RESULT Studio.CommandReplay.getLength(
+  out float length
+);
+
+ +
Studio.CommandReplay.getLength(
+  length
+);
+
+ +
+
length Out
+
The total playback time.
+
+

Studio::CommandReplay::getPaused

+

Retrieves the paused state.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
FMOD_RESULT Studio::CommandReplay::getPaused(
+  bool *paused
+);
+
+ +
FMOD_RESULT FMOD_Studio_CommandReplay_GetPaused(
+  FMOD_STUDIO_COMMANDREPLAY *commandreplay,
+  FMOD_BOOL *paused
+);
+
+ +
RESULT Studio.CommandReplay.getPaused(
+  out bool paused
+);
+
+ +
Studio.CommandReplay.getPaused(
+  paused
+);
+
+ +
+
paused
+
+

Paused state.

+
    +
  • Units: Boolean
  • +
+
+
+

See Also: Studio::CommandReplay::setPaused

+

Studio::CommandReplay::getPlaybackState

+

Retrieves the playback state.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
FMOD_RESULT Studio::CommandReplay::getPlaybackState(
+  FMOD_STUDIO_PLAYBACK_STATE *state
+);
+
+ +
FMOD_RESULT FMOD_Studio_CommandReplay_GetPlaybackState(
+  FMOD_STUDIO_COMMANDREPLAY *commandreplay,
+  FMOD_STUDIO_PLAYBACK_STATE *state
+);
+
+ +
RESULT Studio.CommandReplay.getPlaybackState(
+  out PLAYBACK_STATE state
+);
+
+ +
Studio.CommandReplay.getPlaybackState(
+  state
+);
+
+ +
+
state Out
+
Playback state. (FMOD_STUDIO_PLAYBACK_STATE)
+
+

Studio::CommandReplay::getSystem

+

Retrieves the Studio System object associated with this replay object.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
FMOD_RESULT Studio::CommandReplay::getSystem(
+  Studio::System **system
+);
+
+ +
FMOD_RESULT FMOD_Studio_CommandReplay_GetSystem(
+  FMOD_STUDIO_COMMANDREPLAY *commandreplay,
+  FMOD_STUDIO_SYSTEM **system
+);
+
+ +
RESULT Studio.CommandReplay.getSystem(
+  out System system
+);
+
+ +
Studio.CommandReplay.getSystem(
+  system
+);
+
+ +
+
system
+
Studio system object. (Studio::System)
+
+

Studio::CommandReplay::getUserData

+

Retrieves user data.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
FMOD_RESULT Studio::CommandReplay::getUserData(
+  void **userdata
+);
+
+ +
FMOD_RESULT FMOD_Studio_CommandReplay_GetUserData(
+  FMOD_STUDIO_COMMANDREPLAY *commandreplay,
+  void **userdata
+);
+
+ +
RESULT Studio.CommandReplay.getUserData(
+  out IntPtr userdata
+);
+
+ +
Studio.CommandReplay.getUserData(
+  userdata
+);
+
+ +
+
userdata
+
User data set by calling Studio::CommandReplay::setUserData.
+
+

This function allows arbitrary user data to be retrieved from this object. See the User Data section of the glossary for an example of how to get and set user data.

+

Studio::CommandReplay::isValid

+

Checks that the CommandReplay reference is valid.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
bool Studio::CommandReplay::isValid()
+
+ +
bool FMOD_Studio_CommandReplay_IsValid(FMOD_STUDIO_COMMANDREPLAY *commandreplay)
+
+ +
bool Studio.CommandReplay.isValid()
+
+ +
Studio.CommandReplay.isValid()
+
+ +

FMOD_STUDIO_COMMANDREPLAY_LOAD_BANK_CALLBACK

+

Callback for command replay bank loading.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
FMOD_RESULT F_CALL FMOD_STUDIO_COMMANDREPLAY_LOAD_BANK_CALLBACK(
+  FMOD_STUDIO_COMMANDREPLAY *replay,
+  int commandindex,
+  const FMOD_GUID *bankguid,
+  const char *bankfilename,
+  FMOD_STUDIO_LOAD_BANK_FLAGS flags,
+  FMOD_STUDIO_BANK **bank,
+  void *userdata
+);
+
+ +
delegate RESULT Studio.COMMANDREPLAY_LOAD_BANK_CALLBACK(
+  IntPtr replay,
+  int commandindex,
+  ref Guid bankguid,
+  IntPtr bankfilename,
+  LOAD_BANK_FLAGS flags,
+  out IntPtr bank,
+  IntPtr userdata
+);
+
+ +
+

Not supported for JavaScript.

+
+
+
replay
+
Command replay. (Studio::CommandReplay)
+
commandindex
+
The command that invoked this callback.
+
bankguid Opt
+
The GUID of the bank that needs to be loaded. (FMOD_GUID)
+
bankfilename Opt
+
The filename of the bank that needs to be loaded. (UTF-8 string)
+
flags
+
The flags to load the bank with. (FMOD_STUDIO_LOAD_BANK_FLAGS)
+
bank OutOpt
+
The bank loaded by this function. (Studio::Bank)
+
userdata
+
The userdata set with Studio::CommandReplay::setUserData
+
+
+

The replay argument can be cast to FMOD::Studio::CommandReplay *.

+

The bank argument can be cast to FMOD::Studio::Bank *.

+
+
+

The 'replay' argument can be used via CommandReplay by using FMOD.Studio.CommandReplay commandReplay = new FMOD.Studio.CommandReplay(replay);

+

The 'bankfilename' argument can be used via StringWrapper by using FMOD.StringWrapper bankFilename = new FMOD.StringWrapper(bankfilename);

+

The 'bank' argument can be used via CommandReplay by using FMOD.Studio.Bank studioBank = new FMOD.Studio.Bank(bank);

+
+

See Also: Studio::CommandReplay::setLoadBankCallback

+

Studio::CommandReplay::release

+

Releases the command replay.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
FMOD_RESULT Studio::CommandReplay::release();
+
+ +
FMOD_RESULT FMOD_Studio_CommandReplay_Release(FMOD_STUDIO_COMMANDREPLAY *commandreplay);
+
+ +
RESULT Studio.CommandReplay.release();
+
+ +
Studio.CommandReplay.release();
+
+ +

Studio::CommandReplay::seekToCommand

+

Seeks the playback position to a command.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
FMOD_RESULT Studio::CommandReplay::seekToCommand(
+  int commandindex
+);
+
+ +
FMOD_RESULT FMOD_Studio_CommandReplay_SeekToCommand(
+  FMOD_STUDIO_COMMANDREPLAY *commandreplay,
+  int commandindex
+);
+
+ +
RESULT Studio.CommandReplay.seekToCommand(
+  int commandindex
+);
+
+ +
Studio.CommandReplay.seekToCommand(
+  commandindex
+);
+
+ +
+
commandindex
+
Command index to seek to.
+
+

See Also: Studio::CommandReplay::seekToTime

+

Studio::CommandReplay::seekToTime

+

Seeks the playback position to a time.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
FMOD_RESULT Studio::CommandReplay::seekToTime(
+  float time
+);
+
+ +
FMOD_RESULT FMOD_Studio_CommandReplay_SeekToTime(
+  FMOD_STUDIO_COMMANDREPLAY *commandreplay,
+  float time
+);
+
+ +
RESULT Studio.CommandReplay.seekToTime(
+  float time
+);
+
+ +
Studio.CommandReplay.seekToTime(
+  time
+);
+
+ +
+
time
+
Time to seek to.
+
+

This function moves the playback position to the the first command at or after time. If no command exists at or after time then FMOD_ERR_EVENT_NOTFOUND is returned.

+

See Also: Studio::CommandReplay::seekToCommand

+

Studio::CommandReplay::setBankPath

+

Sets a path substition that will be used when loading banks with this replay.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
FMOD_RESULT Studio::CommandReplay::setBankPath(
+  const char *bankPath
+);
+
+ +
FMOD_RESULT FMOD_Studio_CommandReplay_SetBankPath(
+  FMOD_STUDIO_COMMANDREPLAY *commandreplay,
+  const char *bankPath
+);
+
+ +
RESULT Studio.CommandReplay.setBankPath(
+  string bankPath
+);
+
+ +
Studio.CommandReplay.setBankPath(
+  bankPath
+);
+
+ +
+
bankPath
+
The path to use when loading banks. (UTF-8 string)
+
+

Studio::System::loadBankFile commands in the replay are redirected to load banks from the specified directory, instead of using the directory recorded in the captured commands.

+

See Also: Studio::CommandReplay::setLoadBankCallback

+

Studio::CommandReplay::setCreateInstanceCallback

+

Sets the create event instance callback.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
FMOD_RESULT Studio::CommandReplay::setCreateInstanceCallback(
+  FMOD_STUDIO_COMMANDREPLAY_CREATE_INSTANCE_CALLBACK callback
+);
+
+ +
FMOD_RESULT FMOD_Studio_CommandReplay_SetCreateInstanceCallback(
+  FMOD_STUDIO_COMMANDREPLAY *commandreplay,
+  FMOD_STUDIO_COMMANDREPLAY_CREATE_INSTANCE_CALLBACK callback
+);
+
+ +
RESULT Studio.CommandReplay.setCreateInstanceCallback(
+  COMMANDREPLAY_CREATE_INSTANCE_CALLBACK callback
+);
+
+ +
+

Not supported for JavaScript.

+
+
+
callback
+
Callback function. (FMOD_STUDIO_COMMANDREPLAY_CREATE_INSTANCE_CALLBACK)
+
+

The create instance callback is invoked each time a Studio::EventDescription::createInstance command is processed.

+

The callback can either create a new event instance based on the callback parameters or skip creating the instance. If the instance is not created then subsequent commands for the event instance will be ignored in the replay.

+

If this callback is not set then the system will always create an event instance.

+

See Also: Studio::CommandReplay::setUserData

+

Studio::CommandReplay::setFrameCallback

+

Sets a callback that is issued each time the replay reaches a new frame.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
FMOD_RESULT Studio::CommandReplay::setFrameCallback(
+  FMOD_STUDIO_COMMANDREPLAY_FRAME_CALLBACK callback
+);
+
+ +
FMOD_RESULT FMOD_Studio_CommandReplay_SetFrameCallback(
+  FMOD_STUDIO_COMMANDREPLAY *commandreplay,
+  FMOD_STUDIO_COMMANDREPLAY_FRAME_CALLBACK callback
+);
+
+ +
RESULT Studio.CommandReplay.setFrameCallback(
+  COMMANDREPLAY_FRAME_CALLBACK callback
+);
+
+ +
+

Not supported for JavaScript.

+
+
+
callback
+
Callback function. (FMOD_STUDIO_COMMANDREPLAY_FRAME_CALLBACK)
+
+

See Also: Studio::CommandReplay::setUserData

+

Studio::CommandReplay::setLoadBankCallback

+

Sets the bank loading callback.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
FMOD_RESULT Studio::CommandReplay::setLoadBankCallback(
+  FMOD_STUDIO_COMMANDREPLAY_LOAD_BANK_CALLBACK callback
+);
+
+ +
FMOD_RESULT FMOD_Studio_CommandReplay_SetLoadBankCallback(
+  FMOD_STUDIO_COMMANDREPLAY *commandreplay,
+  FMOD_STUDIO_COMMANDREPLAY_LOAD_BANK_CALLBACK callback
+);
+
+ +
RESULT Studio.CommandReplay.setLoadBankCallback(
+  COMMANDREPLAY_LOAD_BANK_CALLBACK callback
+);
+
+ +
+

Not supported for JavaScript.

+
+
+
callback
+
Callback function. (FMOD_STUDIO_COMMANDREPLAY_LOAD_BANK_CALLBACK)
+
+

The load bank callback is invoked whenever any of the Studio load bank functions are reached.

+

This callback is required to be implemented to successfully replay Studio::System::loadBankMemory and Studio::System::loadBankCustom commands.

+

The callback is responsible for loading the bank based on the callback parameters. If the bank is not loaded subsequent commands which reference objects in the bank will fail.

+

If this callback is not set then the system will attempt to load banks from file according to recorded Studio::System::loadBankFile commands and skip other load commands.

+

See Also: Studio::CommandReplay::setUserData

+

Studio::CommandReplay::setPaused

+

Sets the paused state.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
FMOD_RESULT Studio::CommandReplay::setPaused(
+  bool paused
+);
+
+ +
FMOD_RESULT FMOD_Studio_CommandReplay_SetPaused(
+  FMOD_STUDIO_COMMANDREPLAY *commandreplay,
+  FMOD_BOOL paused
+);
+
+ +
RESULT Studio.CommandReplay.setPaused(
+  bool paused
+);
+
+ +
Studio.CommandReplay.setPaused(
+  paused
+);
+
+ +
+
paused
+
+

Paused state.

+
    +
  • Units: Boolean
  • +
+
+
+

See Also: Studio::CommandReplay::getPaused

+

Studio::CommandReplay::setUserData

+

Sets user data.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
FMOD_RESULT Studio::CommandReplay::setUserData(
+  void *userdata
+);
+
+ +
FMOD_RESULT FMOD_Studio_CommandReplay_SetUserData(
+  FMOD_STUDIO_COMMANDREPLAY *commandreplay,
+  void *userdata
+);
+
+ +
RESULT Studio.CommandReplay.setUserData(
+  IntPtr userdata
+);
+
+ +
Studio.CommandReplay.setUserData(
+  userdata
+);
+
+ +
+
userdata
+
User data.
+
+

This function allows arbitrary user data to be attached to this object. See the User Data section of the glossary for an example of how to get and set user data.

+

See Also: Studio::CommandReplay::getUserData, Studio::CommandReplay::setCreateInstanceCallback, Studio::CommandReplay::setFrameCallback, Studio::CommandReplay::setLoadBankCallback

+

Studio::CommandReplay::start

+

Begins playback.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
FMOD_RESULT Studio::CommandReplay::start();
+
+ +
FMOD_RESULT FMOD_Studio_CommandReplay_Start(FMOD_STUDIO_COMMANDREPLAY *commandreplay);
+
+ +
RESULT Studio.CommandReplay.start();
+
+ +
Studio.CommandReplay.start();
+
+ +

If the replay is already running then calling this function will restart replay from the beginning.

+

See Also: Studio::CommandReplay::stop, Studio::CommandReplay::getPlaybackState

+

Studio::CommandReplay::stop

+

Stops playback.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
FMOD_RESULT Studio::CommandReplay::stop();
+
+ +
FMOD_RESULT FMOD_Studio_CommandReplay_Stop(FMOD_STUDIO_COMMANDREPLAY *commandreplay);
+
+ +
RESULT Studio.CommandReplay.stop();
+
+ +
Studio.CommandReplay.stop();
+
+ +

If the FMOD_STUDIO_COMMANDREPLAY_SKIP_CLEANUP flag has been used then the system state is left as it was at the end of the playback, otherwise all resources that were created as part of the replay will be cleaned up.

+

See Also: Studio::CommandReplay::start, Studio::CommandReplay::getPlaybackState, Studio::System::loadCommandReplay

+

FMOD_STUDIO_COMMAND_INFO

+

Describes a command replay command.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
typedef struct FMOD_STUDIO_COMMAND_INFO {
+  const char                *commandname;
+  int                        parentcommandindex;
+  int                        framenumber;
+  float                      frametime;
+  FMOD_STUDIO_INSTANCETYPE   instancetype;
+  FMOD_STUDIO_INSTANCETYPE   outputtype;
+  unsigned int               instancehandle;
+  unsigned int               outputhandle;
+} FMOD_STUDIO_COMMAND_INFO;
+
+ +
struct Studio.COMMAND_INFO
+{
+    StringWrapper commandname;
+    int parentcommandindex;
+    int framenumber;
+    float frametime;
+    INSTANCETYPE instancetype;
+    INSTANCETYPE outputtype;
+    UInt32 instancehandle;
+    UInt32 outputhandle;
+}
+
+ +
FMOD_STUDIO_COMMAND_INFO
+{
+  commandname,
+  parentcommandindex,
+  framenumber,
+  frametime,
+  instancetype,
+  outputtype,
+  instancehandle,
+  outputhandle,
+};
+
+ +
+
commandname
+
Fully qualified C++ name of the API function for this command. (UTF-8 string)
+
parentcommandindex
+
Index of the command that created the instance this command operates on, or -1 if the command does not operate on any instance.
+
framenumber
+
Frame the command belongs to.
+
frametime
+
Playback time at which this command will be executed.
+
instancetype
+
Type of object that this command uses as an instance. (FMOD_STUDIO_INSTANCETYPE)
+
outputtype
+
Type of object that this command outputs. (FMOD_STUDIO_INSTANCETYPE)
+
instancehandle
+
Original handle value of the instance.
+
outputhandle
+
Original handle value of the command output.
+
+

Note that the handle values in the instancehandle and outputhandle are from the recorded session and are not valid handles during playback.

+

See Also: Studio::CommandReplay::getCommandInfo

+

FMOD_STUDIO_INSTANCETYPE

+

Command replay command instance handle types.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
typedef enum FMOD_STUDIO_INSTANCETYPE {
+  FMOD_STUDIO_INSTANCETYPE_NONE,
+  FMOD_STUDIO_INSTANCETYPE_SYSTEM,
+  FMOD_STUDIO_INSTANCETYPE_EVENTDESCRIPTION,
+  FMOD_STUDIO_INSTANCETYPE_EVENTINSTANCE,
+  FMOD_STUDIO_INSTANCETYPE_PARAMETERINSTANCE,
+  FMOD_STUDIO_INSTANCETYPE_BUS,
+  FMOD_STUDIO_INSTANCETYPE_VCA,
+  FMOD_STUDIO_INSTANCETYPE_BANK,
+  FMOD_STUDIO_INSTANCETYPE_COMMANDREPLAY
+} FMOD_STUDIO_INSTANCETYPE;
+
+ +
enum Studio.INSTANCETYPE
+{
+    NONE,
+    SYSTEM,
+    EVENTDESCRIPTION,
+    EVENTINSTANCE,
+    PARAMETERINSTANCE,
+    BUS,
+    VCA,
+    BANK,
+    COMMANDREPLAY,
+}
+
+ +
STUDIO_INSTANCETYPE_NONE
+STUDIO_INSTANCETYPE_SYSTEM
+STUDIO_INSTANCETYPE_EVENTDESCRIPTION
+STUDIO_INSTANCETYPE_EVENTINSTANCE
+STUDIO_INSTANCETYPE_PARAMETERINSTANCE
+STUDIO_INSTANCETYPE_BUS
+STUDIO_INSTANCETYPE_VCA
+STUDIO_INSTANCETYPE_BANK
+STUDIO_INSTANCETYPE_COMMANDREPLAY
+
+ +
+
FMOD_STUDIO_INSTANCETYPE_NONE
+
No type, handle is unused.
+
FMOD_STUDIO_INSTANCETYPE_SYSTEM
+
Studio::System.
+
FMOD_STUDIO_INSTANCETYPE_EVENTDESCRIPTION
+
Studio::EventDescription.
+
FMOD_STUDIO_INSTANCETYPE_EVENTINSTANCE
+
Studio::EventInstance.
+
FMOD_STUDIO_INSTANCETYPE_PARAMETERINSTANCE
+
Studio::ParameterInstance.
+
FMOD_STUDIO_INSTANCETYPE_BUS
+
Studio::Bus.
+
FMOD_STUDIO_INSTANCETYPE_VCA
+
Studio::VCA.
+
FMOD_STUDIO_INSTANCETYPE_BANK
+
Studio::Bank.
+
FMOD_STUDIO_INSTANCETYPE_COMMANDREPLAY
+
Studio::CommandReplay.
+
+ + +
+ + + diff --git a/FMOD/doc/FMOD API User Manual/studio-api-common.html b/FMOD/doc/FMOD API User Manual/studio-api-common.html new file mode 100644 index 0000000..8fe134c --- /dev/null +++ b/FMOD/doc/FMOD API User Manual/studio-api-common.html @@ -0,0 +1,476 @@ + + +Studio API Reference | Common + + + + +
+ +
+

16. Studio API Reference | Common

+

Loading State:

+ +

Parameters:

+ +
+ +

Playback State:

+ +

Profiling:

+ +

Utility Functions:

+ +

FMOD_STUDIO_LOADING_STATE

+

Loading state of various objects.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
typedef enum FMOD_STUDIO_LOADING_STATE {
+  FMOD_STUDIO_LOADING_STATE_UNLOADING,
+  FMOD_STUDIO_LOADING_STATE_UNLOADED,
+  FMOD_STUDIO_LOADING_STATE_LOADING,
+  FMOD_STUDIO_LOADING_STATE_LOADED,
+  FMOD_STUDIO_LOADING_STATE_ERROR
+} FMOD_STUDIO_LOADING_STATE;
+
+ +
enum Studio.LOADING_STATE
+{
+    UNLOADING,
+    UNLOADED,
+    LOADING,
+    LOADED,
+    ERROR,
+}
+
+ +
STUDIO_LOADING_STATE_UNLOADING
+STUDIO_LOADING_STATE_UNLOADED
+STUDIO_LOADING_STATE_LOADING
+STUDIO_LOADING_STATE_LOADED
+STUDIO_LOADING_STATE_ERROR
+
+ +
+
FMOD_STUDIO_LOADING_STATE_UNLOADING
+
Currently unloading.
+
FMOD_STUDIO_LOADING_STATE_UNLOADED
+
Not loaded.
+
FMOD_STUDIO_LOADING_STATE_LOADING
+
Loading in progress.
+
FMOD_STUDIO_LOADING_STATE_LOADED
+
Loaded and ready to play.
+
FMOD_STUDIO_LOADING_STATE_ERROR
+
Failed to load.
+
+

See Also: Studio::Bank::getLoadingState, Studio::Bank::getSampleLoadingState, Studio::EventDescription::getSampleLoadingState

+

FMOD_STUDIO_MEMORY_USAGE

+

Memory usage statistics.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
typedef struct FMOD_STUDIO_MEMORY_USAGE {
+  int exclusive;
+  int inclusive;
+  int sampledata;
+} FMOD_STUDIO_MEMORY_USAGE;
+
+ +
struct Studio.MEMORY_USAGE
+{
+  int exclusive;
+  int inclusive;
+  int sampledata;
+}
+
+ +
+

Not supported for JavaScript.

+
+
+
exclusive
+
Size of memory belonging to the bus or event instance.
+
inclusive
+
Size of memory belonging exclusively to the bus or event plus the inclusive memory sizes of all buses and event instances which route into it.
+
sampledata
+
Size of shared sample memory referenced by the bus or event instance, inclusive of all sample memory referenced by all buses and event instances which route into it.
+
+

Memory usage exclusive and inclusive values do not include sample data loaded in memory because sample data is a shared resource. Streaming sample data is not a shared resource and is included in the exclusive and inclusive values.

+

See Also: FMOD_STUDIO_INIT_MEMORY_TRACKING, Studio::System::getMemoryUsage, Studio::Bus::getMemoryUsage, Studio::EventInstance::getMemoryUsage

+

FMOD_STUDIO_PARAMETER_DESCRIPTION

+

Describes an event parameter.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
typedef struct FMOD_STUDIO_PARAMETER_DESCRIPTION {
+  const char                  *name;
+  FMOD_STUDIO_PARAMETER_ID     id;
+  float                        minimum;
+  float                        maximum;
+  float                        defaultvalue;
+  FMOD_STUDIO_PARAMETER_TYPE   type;
+  FMOD_STUDIO_PARAMETER_FLAGS  flags;
+  FMOD_GUID                    guid;
+} FMOD_STUDIO_PARAMETER_DESCRIPTION;
+
+ +
struct PARAMETER_DESCRIPTION
+{
+    StringWrapper name;
+    PARAMETER_ID id;
+    float minimum;
+    float maximum;
+    float defaultvalue;
+    PARAMETER_TYPE type;
+    PARAMETER_FLAGS flags;
+    Guid guid;
+}
+
+ +
FMOD_STUDIO_PARAMETER_DESCRIPTION
+{
+  name,
+  id,
+  minimum,
+  maximum,
+  defaultvalue,
+  type,
+  flags,
+  guid
+};
+
+ +
+
name
+
The parameter's name. (UTF-8 string)
+
id
+
The parameter's id. (FMOD_STUDIO_PARAMETER_ID)
+
minimum
+
The parameter's minimum value.
+
maximum
+
The parameter's maximum value.
+
defaultvalue
+
The parameter's default value.
+
type
+
The parameter's type. (FMOD_STUDIO_PARAMETER_TYPE)
+
flags
+
The parameter's behavior flags. (FMOD_STUDIO_PARAMETER_FLAGS)
+
guid
+
The parameter's GUID. (FMOD_GUID)
+
+

See Also: Studio::System::getParameterDescriptionByName, Studio::System::getParameterDescriptionByID, Studio::EventDescription::getParameterDescriptionByName, Studio::EventDescription::getParameterDescriptionByID

+

FMOD_STUDIO_PARAMETER_FLAGS

+

Flags describing the behavior of a parameter.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
#define FMOD_STUDIO_PARAMETER_READONLY              0x00000001
+#define FMOD_STUDIO_PARAMETER_AUTOMATIC             0x00000002
+#define FMOD_STUDIO_PARAMETER_GLOBAL                0x00000004
+#define FMOD_STUDIO_PARAMETER_DISCRETE              0x00000008
+#define FMOD_STUDIO_PARAMETER_LABELED               0x00000010
+
+ +
public enum PARAMETER_FLAGS : uint
+{
+    READONLY  = 0x00000001,
+    AUTOMATIC = 0x00000002,
+    GLOBAL    = 0x00000004,
+    DISCRETE  = 0x00000008,
+    LABELED   = 0x00000010,
+}
+
+ +
STUDIO_PARAMETER_READONLY   0x00000001
+STUDIO_PARAMETER_AUTOMATIC  0x00000002
+STUDIO_PARAMETER_GLOBALS    0x00000004
+STUDIO_PARAMETER_DISCRETE   0x00000008
+STUDIO_PARAMETER_LABELED    0x00000010
+
+ +
+
FMOD_STUDIO_PARAMETER_READONLY
+
Read only.
+
FMOD_STUDIO_PARAMETER_AUTOMATIC
+
Automatic parameter.
+
FMOD_STUDIO_PARAMETER_GLOBAL
+
Global parameter.
+
FMOD_STUDIO_PARAMETER_DISCRETE
+
Discrete parameter that operates on integers (whole numbers) rather than continuous fractional numbers.
+
FMOD_STUDIO_PARAMETER_LABELED
+
Labeled discrete parameter that has a label for each integer value. This flag is never set in banks built with FMOD Studio versions prior to 2.01.10. If this flag is set, FMOD_STUDIO_PARAMETER_DISCRETE is also set.
+
+

See also: FMOD_STUDIO_PARAMETER_DESCRIPTION

+

FMOD_STUDIO_PARAMETER_ID

+

Describes an event parameter identifier.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
typedef struct FMOD_STUDIO_PARAMETER_ID
+{
+    unsigned int data1;
+    unsigned int data2;
+} FMOD_STUDIO_PARAMETER_ID;
+
+ +
struct PARAMETER_ID
+{
+    uint data1;
+    uint data2;
+}
+
+ +
FMOD_STUDIO_PARAMETER_ID
+{
+    data1,
+    data2
+};
+
+ +
+
data1
+
First half of the ID.
+
data2
+
Second half of the ID.
+
+

FMOD_STUDIO_PARAMETER_ID can be retrieved from the FMOD_STUDIO_PARAMETER_DESCRIPTION.

+

FMOD_STUDIO_PARAMETER_TYPE

+

Event parameter types.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
typedef enum FMOD_STUDIO_PARAMETER_TYPE {
+  FMOD_STUDIO_PARAMETER_GAME_CONTROLLED,
+  FMOD_STUDIO_PARAMETER_AUTOMATIC_DISTANCE,
+  FMOD_STUDIO_PARAMETER_AUTOMATIC_EVENT_CONE_ANGLE,
+  FMOD_STUDIO_PARAMETER_AUTOMATIC_EVENT_ORIENTATION,
+  FMOD_STUDIO_PARAMETER_AUTOMATIC_DIRECTION,
+  FMOD_STUDIO_PARAMETER_AUTOMATIC_ELEVATION,
+  FMOD_STUDIO_PARAMETER_AUTOMATIC_LISTENER_ORIENTATION,
+  FMOD_STUDIO_PARAMETER_AUTOMATIC_SPEED,
+  FMOD_STUDIO_PARAMETER_AUTOMATIC_SPEED_ABSOLUTE,
+  FMOD_STUDIO_PARAMETER_AUTOMATIC_DISTANCE_NORMALIZED,
+  FMOD_STUDIO_PARAMETER_MAX
+} FMOD_STUDIO_PARAMETER_TYPE;
+
+ +
enum PARAMETER_TYPE
+{
+    GAME_CONTROLLED,
+    AUTOMATIC_DISTANCE,
+    AUTOMATIC_EVENT_CONE_ANGLE,
+    AUTOMATIC_EVENT_ORIENTATION,
+    AUTOMATIC_DIRECTION,
+    AUTOMATIC_ELEVATION,
+    AUTOMATIC_LISTENER_ORIENTATION,
+    AUTOMATIC_SPEED,
+    AUTOMATIC_SPEED_ABSOLUTE,
+    AUTOMATIC_DISTANCE_NORMALIZED,
+    MAX
+}
+
+ +
STUDIO_PARAMETER_GAME_CONTROLLED
+STUDIO_PARAMETER_AUTOMATIC_DISTANCE
+STUDIO_PARAMETER_AUTOMATIC_EVENT_CONE_ANGLE
+STUDIO_PARAMETER_AUTOMATIC_EVENT_ORIENTATION
+STUDIO_PARAMETER_AUTOMATIC_DIRECTION
+STUDIO_PARAMETER_AUTOMATIC_ELEVATION
+STUDIO_PARAMETER_AUTOMATIC_LISTENER_ORIENTATION
+STUDIO_PARAMETER_AUTOMATIC_SPEED
+STUDIO_PARAMETER_AUTOMATIC_SPEED_ABSOLUTE
+STUDIO_PARAMETER_AUTOMATIC_DISTANCE_NORMALIZED
+STUDIO_PARAMETER_MAX
+
+ +
+
FMOD_STUDIO_PARAMETER_GAME_CONTROLLED
+
API settable parameter.
+
FMOD_STUDIO_PARAMETER_AUTOMATIC_DISTANCE
+
Distance between the event and the listener.
+
FMOD_STUDIO_PARAMETER_AUTOMATIC_EVENT_CONE_ANGLE
+
Angle between the event's forward vector and the vector pointing from the event to the listener (0 to 180 degrees).
+
FMOD_STUDIO_PARAMETER_AUTOMATIC_EVENT_ORIENTATION
+
Horizontal angle between the event's forward vector and listener's forward vector (-180 to 180 degrees).
+
FMOD_STUDIO_PARAMETER_AUTOMATIC_DIRECTION
+
Horizontal angle between the listener's forward vector and the vector pointing from the listener to the event (-180 to 180 degrees).
+
FMOD_STUDIO_PARAMETER_AUTOMATIC_ELEVATION
+
Angle between the listener's XZ plane and the vector pointing from the listener to the event (-90 to 90 degrees).
+
FMOD_STUDIO_PARAMETER_AUTOMATIC_LISTENER_ORIENTATION
+
Horizontal angle between the listener's forward vector and the global positive Z axis (-180 to 180 degrees).
+
FMOD_STUDIO_PARAMETER_AUTOMATIC_SPEED
+
Magnitude of the relative velocity of the event and the listener.
+
FMOD_STUDIO_PARAMETER_AUTOMATIC_SPEED_ABSOLUTE
+
Magnitude of the absolute velocity of the event.
+
FMOD_STUDIO_PARAMETER_AUTOMATIC_DISTANCE_NORMALIZED
+
Distance between the event and the listener in the range min distance - max distance represented as 0 - 1.
+
FMOD_STUDIO_PARAMETER_MAX
+
Maximum number of parameter types supported.
+
+

FMOD_STUDIO_PARAMETER_GAME_CONTROLLED type parameters may have their values set using the API. All other parameter types have their values automatically set by FMOD Studio when the system is updated.

+

The horizontal angle between vectors is found by projecting both vector's onto a plane and taking the angle between the projected vectors. For FMOD_STUDIO_PARAMETER_AUTOMATIC_EVENT_ORIENTATION and FMOD_STUDIO_PARAMETER_AUTOMATIC_DIRECTION type parameters the vectors are projected onto the listener's XZ plane. For FMOD_STUDIO_PARAMETER_AUTOMATIC_LISTENER_ORIENTATION type parameters the vectors are projected onto the global XZ plane.

+

See Also: FMOD_STUDIO_PARAMETER_DESCRIPTION

+

Studio::parseID

+

Parses a GUID from a string.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
FMOD_RESULT Studio::parseID(
+  const char *idstring,
+  FMOD_GUID *id
+);
+
+ +
FMOD_RESULT FMOD_Studio_ParseID(
+  const char *idstring,
+  FMOD_GUID *id
+);
+
+ +
static RESULT Studio.Util.parseID(
+  string idstring,
+  out Guid id
+);
+
+ +
+

Not supported for JavaScript.

+
+
+
idstring
+
String representation of the GUID. (UTF-8 string)
+
id Out
+
GUID. (FMOD_GUID)
+
+

This function expects the string representation to be formatted as 32 digits separated by hyphens and enclosed in braces: {00000000-0000-0000-0000-000000000000}.

+

FMOD_STUDIO_PLAYBACK_STATE

+

Playback state of various objects.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
typedef enum FMOD_STUDIO_PLAYBACK_STATE {
+  FMOD_STUDIO_PLAYBACK_PLAYING,
+  FMOD_STUDIO_PLAYBACK_SUSTAINING,
+  FMOD_STUDIO_PLAYBACK_STOPPED,
+  FMOD_STUDIO_PLAYBACK_STARTING,
+  FMOD_STUDIO_PLAYBACK_STOPPING
+} FMOD_STUDIO_PLAYBACK_STATE;
+
+ +
enum Studio.PLAYBACK_STATE
+{
+    PLAYING,
+    SUSTAINING,
+    STOPPED,
+    STARTING,
+    STOPPING,
+}
+
+ +
STUDIO_PLAYBACK_PLAYING
+STUDIO_PLAYBACK_SUSTAINING
+STUDIO_PLAYBACK_STOPPED
+STUDIO_PLAYBACK_STARTING
+STUDIO_PLAYBACK_STOPPING
+
+ +
+
FMOD_STUDIO_PLAYBACK_PLAYING
+
Playing.
+
FMOD_STUDIO_PLAYBACK_SUSTAINING
+
The timeline cursor is paused on a sustain point. (Studio::EventInstance only.)
+
FMOD_STUDIO_PLAYBACK_STOPPED
+
Stopped.
+
FMOD_STUDIO_PLAYBACK_STARTING
+
Preparing to start.
+
FMOD_STUDIO_PLAYBACK_STOPPING
+
Preparing to stop.
+
+

See Also: Studio::CommandReplay::getPlaybackState, Studio::EventInstance::getPlaybackState

+ + +
+ + + diff --git a/FMOD/doc/FMOD API User Manual/studio-api-eventdescription.html b/FMOD/doc/FMOD API User Manual/studio-api-eventdescription.html new file mode 100644 index 0000000..7d6ad7f --- /dev/null +++ b/FMOD/doc/FMOD API User Manual/studio-api-eventdescription.html @@ -0,0 +1,1546 @@ + + +Studio API Reference | Studio::EventDescription + + + + +
+ +
+

16. Studio API Reference | Studio::EventDescription

+

The description for an FMOD Studio event.

+

Event descriptions belong to banks, and so an event description can only be queried if the relevant bank is loaded. Event descriptions may be retrieved via path or GUID lookup, or by enumerating all descriptions in a bank.

+

Instances:

+ +

Sample Data:

+ +

Attributes:

+ +

Parameters:

+ +

User Properties:

+ +
+ +
+ +

General:

+ +

See Also:

+ +

Studio::EventDescription::createInstance

+

Creates a playable instance.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
FMOD_RESULT Studio::EventDescription::createInstance(
+  Studio::EventInstance **instance
+);
+
+ +
FMOD_RESULT FMOD_Studio_EventDescription_CreateInstance(
+  FMOD_STUDIO_EVENTDESCRIPTION *eventdescription,
+  FMOD_STUDIO_EVENTINSTANCE **instance
+);
+
+ +
RESULT Studio.EventDescription.createInstance(
+  out EventInstance instance
+);
+
+ +
Studio.EventDescription.createInstance(
+  instance
+);
+
+ +
+
instance Out
+
EventInstance object. (Studio::EventInstance)
+
+

When an event instance is created, any required non-streaming sample data is loaded asynchronously.

+

Use Studio::EventDescription::getSampleLoadingState to check the loading status.

+

Sample data can be loaded ahead of time with Studio::EventDescription::loadSampleData or Studio::Bank::loadSampleData. See Sample Data Loading for more information.

+

See Also: Studio::EventInstance::release

+

Studio::EventDescription::getID

+

Retrieves the GUID associated with the event.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
FMOD_RESULT Studio::EventDescription::getID(
+  FMOD_GUID *id
+);
+
+ +
FMOD_RESULT FMOD_Studio_EventDescription_GetID(
+  FMOD_STUDIO_EVENTDESCRIPTION *eventdescription,
+  FMOD_GUID *id
+);
+
+ +
RESULT Studio.EventDescription.getID(
+  out Guid id
+);
+
+ +
Studio.EventDescription.getID(
+  id
+);
+
+ +
+
id Out
+
Event description GUID. (FMOD_GUID)
+
+

Studio::EventDescription::getInstanceCount

+

Retrieves the number of instances.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
FMOD_RESULT Studio::EventDescription::getInstanceCount(
+  int *count
+);
+
+ +
FMOD_RESULT FMOD_Studio_EventDescription_GetInstanceCount(
+  FMOD_STUDIO_EVENTDESCRIPTION *eventdescription,
+  int *count
+);
+
+ +
RESULT Studio.EventDescription.getInstanceCount(
+  out int count
+);
+
+ +
Studio.EventDescription.getInstanceCount(
+  count
+);
+
+ +
+
count Out
+
Instance count.
+
+

May be used in conjunction with Studio::EventDescription::getInstanceList to enumerate the instances of this event.

+

Studio::EventDescription::getInstanceList

+

Retrieves a list of the instances.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
FMOD_RESULT Studio::EventDescription::getInstanceList(
+  Studio::EventInstance **array,
+  int capacity,
+  int *count
+);
+
+ +
FMOD_RESULT FMOD_Studio_EventDescription_GetInstanceList(
+  FMOD_STUDIO_EVENTDESCRIPTION *eventdescription,
+  FMOD_STUDIO_EVENTINSTANCE **array,
+  int capacity,
+  int *count
+);
+
+ +
RESULT Studio.EventDescription.getInstanceList(
+  out EventInstance[] array
+);
+
+ +
Studio.EventDescription.getInstanceList(
+  array,
+  capacity,
+  count
+);
+
+ +
+
array Out
+
An array to receive the list. (Studio::EventInstance)
+
capacity
+
Capacity of array.
+
count OutOpt
+
Number of event instances written to array.
+
+

This function returns a maximum of capacity instances. If more than capacity instances have been created then additional instances will be silently ignored.

+

May be used in conjunction with Studio::EventDescription::getInstanceCount to enumerate the instances of this event.

+

Studio::EventDescription::getLength

+

Retrieves the length of the timeline.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
FMOD_RESULT Studio::EventDescription::getLength(
+  int *length
+);
+
+ +
FMOD_RESULT FMOD_Studio_EventDescription_GetLength(
+  FMOD_STUDIO_EVENTDESCRIPTION *eventdescription,
+  int *length
+);
+
+ +
RESULT Studio.EventDescription.getLength(
+  out int length
+);
+
+ +
Studio.EventDescription.getLength(
+  length
+);
+
+ +
+
length Out
+
+

Timeline length.

+
    +
  • Units: Milliseconds
  • +
+
+
+

A timeline's length is the largest of any logic markers, transition leadouts and the end of any trigger boxes on the timeline.

+

See Also: Studio::EventInstance::getTimelinePosition, Studio::EventInstance::setTimelinePosition

+

Studio::EventDescription::getMinMaxDistance

+

Retrieves the minimum and maximum distances for 3D attenuation.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
FMOD_RESULT Studio::EventDescription::getMinMaxDistance(
+  float *min,
+  float *max
+);
+
+ +
FMOD_RESULT FMOD_Studio_EventDescription_GetMinMaxDistance(
+  FMOD_STUDIO_EVENTDESCRIPTION *eventdescription,
+  float *min,
+  float *max
+);
+
+ +
RESULT Studio.EventDescription.getMinMaxDistance(
+  out float min,
+  out float max
+);
+
+ +
Studio.EventDescription.getMinMaxDistance(
+  min,
+  max
+);
+
+ +
+
min OutOpt
+
+

Minimum distance.

+ +
+
max OutOpt
+
+

Maximum distance.

+ +
+
+

See Also: Studio::EventInstance::getMinMaxDistance

+

Studio::EventDescription::getParameterDescriptionByID

+

Retrieves an event parameter description by id.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
FMOD_RESULT Studio::EventDescription::getParameterDescriptionByID(
+  FMOD_STUDIO_PARAMETER_ID id,
+  FMOD_STUDIO_PARAMETER_DESCRIPTION *parameter
+);
+
+ +
FMOD_RESULT FMOD_Studio_EventDescription_GetParameterDescriptionByID(
+  FMOD_STUDIO_EVENTDESCRIPTION *eventdescription,
+  FMOD_STUDIO_PARAMETER_ID id,
+  FMOD_STUDIO_PARAMETER_DESCRIPTION *parameter
+);
+
+ +
RESULT Studio.EventDescription.getParameterDescriptionByID(
+  PARAMETER_ID id,
+  out PARAMETER_DESCRIPTION parameter
+);
+
+ +
Studio.EventDescription.getParameterDescriptionByID(
+  id,
+  parameter
+);
+
+ +
+
id
+
Parameter id. (FMOD_STUDIO_PARAMETER_ID)
+
parameter Out
+
Parameter description. (FMOD_STUDIO_PARAMETER_DESCRIPTION)
+
+

Studio::EventDescription::getParameterDescriptionByIndex

+

Retrieves an event parameter description by index.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
FMOD_RESULT Studio::EventDescription::getParameterDescriptionByIndex(
+  int index,
+  FMOD_STUDIO_PARAMETER_DESCRIPTION *parameter
+);
+
+ +
FMOD_RESULT FMOD_Studio_EventDescription_GetParameterDescriptionByIndex(
+  FMOD_STUDIO_EVENTDESCRIPTION *eventdescription,
+  int index,
+  FMOD_STUDIO_PARAMETER_DESCRIPTION *parameter
+);
+
+ +
RESULT Studio.EventDescription.getParameterDescriptionByIndex(
+  int index,
+  out PARAMETER_DESCRIPTION parameter
+);
+
+ +
Studio.EventDescription.getParameterDescriptionByIndex(
+  index,
+  parameter
+);
+
+ +
+
index
+
Parameter index.
+
parameter Out
+
Parameter description. (FMOD_STUDIO_PARAMETER_DESCRIPTION)
+
+

May be used in combination with Studio::EventDescription::getParameterDescriptionCount to enumerate event parameters.

+
+

The order of parameters is not necessarily the same as what is shown in the FMOD Studio event editor.

+
+

Studio::EventDescription::getParameterDescriptionByName

+

Retrieves an event parameter description by name, including the path if needed.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
FMOD_RESULT Studio::EventDescription::getParameterDescriptionByName(
+  const char *name,
+  FMOD_STUDIO_PARAMETER_DESCRIPTION *parameter
+);
+
+ +
FMOD_RESULT FMOD_Studio_EventDescription_GetParameterDescriptionByName(
+  FMOD_STUDIO_EVENTDESCRIPTION *eventdescription,
+  const char *name,
+  FMOD_STUDIO_PARAMETER_DESCRIPTION *parameter
+);
+
+ +
RESULT Studio.EventDescription.getParameterDescriptionByName(
+  string name,
+  out PARAMETER_DESCRIPTION parameter
+);
+
+ +
Studio.EventDescription.getParameterDescriptionByName(
+  name,
+  parameter
+);
+
+ +
+
name
+
Parameter name, including the path if needed (case-insensitive). (UTF-8 string)
+
parameter Out
+
Parameter description. (FMOD_STUDIO_PARAMETER_DESCRIPTION)
+
+

Studio::EventDescription::getParameterDescriptionCount

+

Retrieves the number of parameters in the event.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
FMOD_RESULT Studio::EventDescription::getParameterDescriptionCount(
+  int *count
+);
+
+ +
FMOD_RESULT FMOD_Studio_EventDescription_GetParameterDescriptionCount(
+  FMOD_STUDIO_EVENTDESCRIPTION *eventdescription,
+  int *count
+);
+
+ +
RESULT Studio.EventDescription.getParameterDescriptionCount(
+  out int count
+);
+
+ +
Studio.EventDescription.getParameterDescriptionCount(
+  count
+);
+
+ +
+
count Out
+
Parameter count.
+
+

May be used in conjunction with Studio::EventDescription::getParameterDescriptionByIndex to enumerate event parameters.

+

Studio::EventDescription::getParameterLabelByID

+

Retrieves an event parameter label by ID.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
FMOD_RESULT Studio::EventDescription::getParameterLabelByID(
+  FMOD_STUDIO_PARAMETER_ID id,
+  int labelindex,
+  char *label,
+  int size,
+  int *retrieved
+);
+
+ +
FMOD_RESULT FMOD_Studio_EventDescription_GetParameterLabelByID(
+  FMOD_STUDIO_EVENTDESCRIPTION *eventdescription,
+  FMOD_STUDIO_PARAMETER_ID id,
+  int labelindex,
+  char *label,
+  int size,
+  int *retrieved
+);
+
+ +
RESULT Studio.EventDescription.getParameterLabelByID(
+  PARAMETER_ID id,
+  int labelindex,
+  out string label
+);
+
+ +
Studio.EventDescription.getParameterLabelByID(
+  id,
+  labelindex,
+  label,
+  size,
+  retrieved
+);
+
+ +
+
id
+
Parameter ID. (FMOD_STUDIO_PARAMETER_ID)
+
labelindex
+
+

Label index to retrieve.

+ +
+
label Out
+
Buffer to receive the label. (UTF-8 string)
+
size
+
Size of the label buffer in bytes. Must be 0 if label is null.
+
retrieved OutOpt
+
Length of the label in bytes, including the terminating null character.
+
+

If the label is longer than size then it is truncated and this function returns FMOD_ERR_TRUNCATED.

+

The retrieved parameter can be used to get the buffer size required to hold the full label.

+

Studio::EventDescription::getParameterLabelByIndex

+

Retrieves an event parameter label by index.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
FMOD_RESULT Studio::EventDescription::getParameterLabelByIndex(
+  int index,
+  int labelindex,
+  char *label,
+  int size,
+  int *retrieved
+);
+
+ +
FMOD_RESULT FMOD_Studio_EventDescription_GetParameterLabelByIndex(
+  FMOD_STUDIO_EVENTDESCRIPTION *eventdescription,
+  int index,
+  int labelindex,
+  char *label,
+  int size,
+  int *retrieved
+);
+
+ +
RESULT Studio.EventDescription.getParameterLabelByIndex(
+  int index,
+  int labelindex,
+  out string label
+);
+
+ +
Studio.EventDescription.getParameterLabelByIndex(
+  index,
+  labelindex,
+  label,
+  size,
+  retrieved
+);
+
+ +
+
index
+
Parameter index.
+
labelindex
+
+

Label index to retrieve.

+ +
+
label Out
+
Buffer to receive the label. (UTF-8 string)
+
size
+
Size of the label buffer in bytes. Must be 0 if label is null.
+
retrieved OutOpt
+
Length of the label in bytes, including the terminating null character.
+
+

If the label is longer than size then it is truncated and this function returns FMOD_ERR_TRUNCATED.

+

The retrieved parameter can be used to get the buffer size required to hold the full label.

+

May be used in combination with Studio::EventDescription::getParameterDescriptionCount to enumerate event parameters.

+
+

The order of parameters is not necessarily the same as what is shown in the FMOD Studio event editor.

+
+

Studio::EventDescription::getParameterLabelByName

+

Retrieves an event parameter label by name, including the path if needed.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
FMOD_RESULT Studio::EventDescription::getParameterLabelByName(
+  const char *name,
+  int labelindex,
+  char *label,
+  int size,
+  int *retrieved
+);
+
+ +
FMOD_RESULT FMOD_Studio_EventDescription_GetParameterLabelByName(
+  FMOD_STUDIO_EVENTDESCRIPTION *eventdescription,
+  const char *name,
+  int labelindex,
+  char *label,
+  int size,
+  int *retrieved
+);
+
+ +
RESULT Studio.EventDescription.getParameterLabelByName(
+  string name,
+  int labelindex,
+  out string label
+);
+
+ +
Studio.EventDescription.getParameterLabelByName(
+  name,
+  labelindex,
+  label,
+  size,
+  retrieved
+);
+
+ +
+
name
+
Parameter name, including the path if needed (case-insensitive). (UTF-8 string)
+
labelindex
+
+

Label index to retrieve.

+ +
+
label Out
+
Buffer to receive the label. (UTF-8 string)
+
size
+
Size of the label buffer in bytes. Must be 0 if label is null.
+
retrieved OutOpt
+
Length of the label in bytes, including the terminating null character.
+
+

name can be the short name (such as 'Wind') or the full path (such as 'parameter:/Ambience/Wind'). Path lookups only succeed if the strings bank has been loaded.

+

If the label is longer than size then it is truncated and this function returns FMOD_ERR_TRUNCATED.

+

The retrieved parameter can be used to get the buffer size required to hold the full label.

+

Studio::EventDescription::getPath

+

Retrieves the path.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
FMOD_RESULT Studio::EventDescription::getPath(
+  char *path,
+  int size,
+  int *retrieved
+);
+
+ +
FMOD_RESULT FMOD_Studio_EventDescription_GetPath(
+  FMOD_STUDIO_EVENTDESCRIPTION *eventdescription,
+  char *path,
+  int size,
+  int *retrieved
+);
+
+ +
RESULT Studio.EventDescription.getPath(
+  out string path
+);
+
+ +
Studio.EventDescription.getPath(
+  path,
+  size,
+  retrieved
+);
+
+ +
+
path OutOpt
+
Buffer to receive the path. (UTF-8 string)
+
size
+
Size of the path buffer in bytes. Must be 0 if path is null.
+
retrieved OutOpt
+
Length of the path in bytes, including the terminating null character.
+
+

The strings bank must be loaded prior to calling this function, otherwise FMOD_ERR_EVENT_NOTFOUND is returned.

+

If the path is longer than size then it is truncated and this function returns FMOD_ERR_TRUNCATED.

+

The retrieved parameter can be used to get the buffer size required to hold the full path.

+

Studio::EventDescription::getSampleLoadingState

+

Retrieves the sample data loading state.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
FMOD_RESULT Studio::EventDescription::getSampleLoadingState(
+  FMOD_STUDIO_LOADING_STATE *state
+);
+
+ +
FMOD_RESULT FMOD_Studio_EventDescription_GetSampleLoadingState(
+  FMOD_STUDIO_EVENTDESCRIPTION *eventdescription,
+  FMOD_STUDIO_LOADING_STATE *state
+);
+
+ +
RESULT Studio.EventDescription.getSampleLoadingState(
+  out LOADING_STATE state
+);
+
+ +
Studio.EventDescription.getSampleLoadingState(
+  state
+);
+
+ +
+
state Out
+
Loading state. (FMOD_STUDIO_LOADING_STATE)
+
+

If the event is invalid, then the state is set to FMOD_STUDIO_LOADING_STATE_UNLOADED and this function returns FMOD_ERR_INVALID_HANDLE.

+

See Also: Studio::EventDescription::loadSampleData, Studio::Bank::loadSampleData, Studio::EventDescription::createInstance, Sample Data Loading

+

Studio::EventDescription::getSoundSize

+

Retrieves the sound size for 3D panning.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
FMOD_RESULT Studio::EventDescription::getSoundSize(
+  float *size
+);
+
+ +
FMOD_RESULT FMOD_Studio_EventDescription_GetSoundSize(
+  FMOD_STUDIO_EVENTDESCRIPTION *eventdescription,
+  float *size
+);
+
+ +
RESULT Studio.EventDescription.getSoundSize(
+  out float size
+);
+
+ +
Studio.EventDescription.getSoundSize(
+  size
+);
+
+ +
+
size Out
+
Sound size.
+
+

Retrieves the largest Sound Size value of all Spatializers and 3D Object Spatializers on the event's master track. Returns zero if there are no Spatializers or 3D Object Spatializers.

+

See Also: Studio::EventDescription::is3D

+

Studio::EventDescription::getUserData

+

Retrieves the event user data.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
FMOD_RESULT Studio::EventDescription::getUserData(
+  void **userdata
+);
+
+ +
FMOD_RESULT FMOD_Studio_EventDescription_GetUserData(
+  FMOD_STUDIO_EVENTDESCRIPTION *eventdescription,
+  void **userdata
+);
+
+ +
RESULT Studio.EventDescription.getUserData(
+  out IntPtr userdata
+);
+
+ +
Studio.EventDescription.getUserData(
+  userdata
+);
+
+ +
+
userdata Out
+
User data set by calling Studio::EventDescription::setUserData.
+
+

This function allows arbitrary user data to be retrieved from this object. See the User Data section of the glossary for an example of how to get and set user data.

+

Studio::EventDescription::getUserProperty

+

Retrieves a user property by name.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
FMOD_RESULT Studio::EventDescription::getUserProperty(
+  const char *name,
+  FMOD_STUDIO_USER_PROPERTY *property
+);
+
+ +
FMOD_RESULT FMOD_Studio_EventDescription_GetUserProperty(
+  FMOD_STUDIO_EVENTDESCRIPTION *eventdescription,
+  const char *name,
+  FMOD_STUDIO_USER_PROPERTY *property
+);
+
+ +
RESULT Studio.EventDescription.getUserProperty(
+  string name,
+  out USER_PROPERTY property
+);
+
+ +
Studio.EventDescription.getUserProperty(
+  name,
+  property
+);
+
+ +
+
name
+
User property name. (UTF-8 string)
+
property Out
+
User property. (FMOD_STUDIO_USER_PROPERTY)
+
+

See Also: Studio::EventDescription::getUserPropertyCount, Studio::EventDescription::getUserPropertyByIndex

+

Studio::EventDescription::getUserPropertyByIndex

+

Retrieves a user property by index.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
FMOD_RESULT Studio::EventDescription::getUserPropertyByIndex(
+  int index,
+  FMOD_STUDIO_USER_PROPERTY *property
+);
+
+ +
FMOD_RESULT FMOD_Studio_EventDescription_GetUserPropertyByIndex(
+  FMOD_STUDIO_EVENTDESCRIPTION *eventdescription,
+  int index,
+  FMOD_STUDIO_USER_PROPERTY *property
+);
+
+ +
RESULT Studio.EventDescription.getUserPropertyByIndex(
+  int index,
+  out USER_PROPERTY property
+);
+
+ +
Studio.EventDescription.getUserPropertyByIndex(
+  index,
+  property
+);
+
+ +
+
index
+
User property index.
+
property Out
+
User property. (FMOD_STUDIO_USER_PROPERTY)
+
+

May be used in combination with Studio::EventDescription::getUserPropertyCount to enumerate event user properties.

+

See Also: Studio::EventDescription::getUserProperty

+

Studio::EventDescription::getUserPropertyCount

+

Retrieves the number of user properties attached to the event.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
FMOD_RESULT Studio::EventDescription::getUserPropertyCount(
+  int *count
+);
+
+ +
FMOD_RESULT FMOD_Studio_EventDescription_GetUserPropertyCount(
+  FMOD_STUDIO_EVENTDESCRIPTION *eventdescription,
+  int *count
+);
+
+ +
RESULT Studio.EventDescription.getUserPropertyCount(
+  out int count
+);
+
+ +
Studio.EventDescription.getUserPropertyCount(
+  count
+);
+
+ +
+
count Out
+
User property count.
+
+

May be used in combination with Studio::EventDescription::getUserPropertyByIndex to enumerate event user properties.

+

See Also: Studio::EventDescription::getUserProperty

+

Studio::EventDescription::hasSustainPoint

+

Retrieves whether the event has any sustain points.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
FMOD_RESULT Studio::EventDescription::hasSustainPoint(
+  bool *sustainPoint
+);
+
+ +
FMOD_RESULT FMOD_Studio_EventDescription_HasSustainPoint(
+  FMOD_STUDIO_EVENTDESCRIPTION *eventdescription,
+  FMOD_BOOL *sustainPoint
+);
+
+ +
RESULT Studio.EventDescription.hasSustainPoint(
+  out bool sustainPoint
+);
+
+ +
Studio.EventDescription.hasSustainPoint(
+  sustainPoint
+);
+
+ +
+
sustainPoint Out
+
+

Sustain point status. True if the event has one or more sustain points.

+
    +
  • Units: Boolean
  • +
+
+
+

Studio::EventDescription::is3D

+

Retrieves the event's 3D status.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
FMOD_RESULT Studio::EventDescription::is3D(
+  bool *is3d
+);
+
+ +
FMOD_RESULT FMOD_Studio_EventDescription_Is3D(
+  FMOD_STUDIO_EVENTDESCRIPTION *eventdescription,
+  FMOD_BOOL *is3d
+);
+
+ +
RESULT Studio.EventDescription.is3D(
+  out bool is3d
+);
+
+ +
Studio.EventDescription.is3D(
+  is3d
+);
+
+ +
+
is3d Out
+
+

3D status. True if the event is 3D.

+
    +
  • Units: Boolean
  • +
+
+
+

An event is considered 3D if any of these conditions are met:

+
    +
  • The event has a Spatializer, 3D Object Spatializer, Scatterer, or a 3rd party spatializer on its master track.
  • +
  • The event contains an automatic parameter that depends on the event's 3D attributes:
      +
    • Distance
    • +
    • Event Cone Angle
    • +
    • Event Orientation
    • +
    • Direction
    • +
    • Elevation
    • +
    • Speed
    • +
    • Speed (Absolute)
    • +
    +
  • +
  • The event contains any nested events which are 3D.
  • +
+

If the event contains any nested event built to a different bank than the parent event using any version of FMOD Studio prior to 2.00.10, and any of the nested events' banks are not loaded, this function may fail to correctly determine the event's 3D status.
+If an event contains a Scatterer, the event is considered 3D regardless of the contents of the Scatterer's playlist. This includes cases where the Scatterer instrument's playlist only contains 2D events.

+

Studio::EventDescription::isDopplerEnabled

+

Retrieves the event's doppler status.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
FMOD_RESULT Studio::EventDescription::isDopplerEnabled(
+  bool *doppler
+);
+
+ +
FMOD_RESULT FMOD_Studio_EventDescription_IsDopplerEnabled(
+  FMOD_STUDIO_EVENTDESCRIPTION *eventdescription,
+  FMOD_BOOL *doppler
+);
+
+ +
RESULT Studio.EventDescription.isDopplerEnabled(
+  out bool doppler
+);
+
+ +
Studio.EventDescription.isDopplerEnabled(
+  doppler
+);
+
+ +
+
doppler Out
+
+

Doppler status. True if doppler is enabled for the event.

+
    +
  • Units: Boolean
  • +
+
+
+

Note: If the event is in a bank built using any version of FMOD Studio older than 2.01.09, this function returns false regardless of the event's doppler state.

+

Studio::EventDescription::isOneshot

+

Retrieves the event's oneshot status.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
FMOD_RESULT Studio::EventDescription::isOneshot(
+  bool *oneshot
+);
+
+ +
FMOD_RESULT FMOD_Studio_EventDescription_IsOneshot(
+  FMOD_STUDIO_EVENTDESCRIPTION *eventdescription,
+  FMOD_BOOL *oneshot
+);
+
+ +
RESULT Studio.EventDescription.isOneshot(
+  out bool oneshot
+);
+
+ +
Studio.EventDescription.isOneshot(
+  oneshot
+);
+
+ +
+
oneshot Out
+
+

oneshot status. True if the event is a oneshot event.

+
    +
  • Units: Boolean
  • +
+
+
+

An event is considered oneshot if it is guaranteed to terminate without intervention in bounded time after being started. Instances of such events can be played in a fire-and-forget fashion by calling Studio::EventInstance::start immediately followed by Studio::EventInstance::release.

+

If the event contains any nested event built to a different bank than the parent event, and any of the nested events' banks are not loaded, this function may fail to correctly determine the event's oneshot status.

+

Studio::EventDescription::isSnapshot

+

Retrieves the event's snapshot status.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
FMOD_RESULT Studio::EventDescription::isSnapshot(
+  bool *snapshot
+);
+
+ +
FMOD_RESULT FMOD_Studio_EventDescription_IsSnapshot(
+  FMOD_STUDIO_EVENTDESCRIPTION *eventdescription,
+  FMOD_BOOL *snapshot
+);
+
+ +
RESULT Studio.EventDescription.isSnapshot(
+  out bool snapshot
+);
+
+ +
Studio.EventDescription.isSnapshot(
+  snapshot
+);
+
+ +
+
snapshot Out
+
+

Snapshot status. True if the event is a snapshot.

+
    +
  • Units: Boolean
  • +
+
+
+

Studio::EventDescription::isStream

+

Retrieves the event's stream status.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
FMOD_RESULT Studio::EventDescription::isStream(
+  bool *isStream
+);
+
+ +
FMOD_RESULT FMOD_Studio_EventDescription_IsStream(
+  FMOD_STUDIO_EVENTDESCRIPTION *eventdescription,
+  FMOD_BOOL *isStream
+);
+
+ +
RESULT Studio.EventDescription.isStream(
+  out bool isStream
+);
+
+ +
Studio.EventDescription.isStream(
+  isStream
+);
+
+ +
+
isStream Out
+
+

Stream status. True if the event contains one or more streamed sounds.

+
    +
  • Units: Boolean
  • +
+
+
+

If the event contains any nested event built to a different bank than the parent event, and any of the nested events' banks are not loaded, this function may fail to correctly determine the event's stream status.

+

Studio::EventDescription::isValid

+

Checks that the EventDescription reference is valid.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
bool Studio::EventDescription::isValid()
+
+ +
bool FMOD_Studio_EventDescription_IsValid(FMOD_STUDIO_EVENTDESCRIPTION *eventdescription)
+
+ +
bool Studio.EventDescription.isValid()
+
+ +
Studio.EventDescription.isValid()
+
+ +

Studio::EventDescription::loadSampleData

+

Loads non-streaming sample data used by the event.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
FMOD_RESULT Studio::EventDescription::loadSampleData();
+
+ +
FMOD_RESULT FMOD_Studio_EventDescription_LoadSampleData(FMOD_STUDIO_EVENTDESCRIPTION *eventdescription);
+
+ +
RESULT Studio.EventDescription.loadSampleData();
+
+ +
Studio.EventDescription.loadSampleData();
+
+ +

This function will load all non-streaming sample data required by the event and any referenced events.

+

Sample data is loaded asynchronously, Studio::EventDescription::getSampleLoadingState may be used to poll the loading state.

+

See Also: Studio::EventDescription::unloadSampleData, Sample Data Loading

+

Studio::EventDescription::releaseAllInstances

+

Releases all instances.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
FMOD_RESULT Studio::EventDescription::releaseAllInstances();
+
+ +
FMOD_RESULT FMOD_Studio_EventDescription_ReleaseAllInstances(FMOD_STUDIO_EVENTDESCRIPTION *eventdescription);
+
+ +
RESULT Studio.EventDescription.releaseAllInstances();
+
+ +
Studio.EventDescription.releaseAllInstances();
+
+ +

This function immediately stops and releases all instances of the event.

+

See Also: Studio::EventInstance::release

+

Studio::EventDescription::setCallback

+

Sets the user callback.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
FMOD_RESULT Studio::EventDescription::setCallback(
+  FMOD_STUDIO_EVENT_CALLBACK callback,
+  FMOD_STUDIO_EVENT_CALLBACK_TYPE callbackmask = FMOD_STUDIO_EVENT_CALLBACK_ALL
+);
+
+ +
FMOD_RESULT FMOD_Studio_EventDescription_SetCallback(
+  FMOD_STUDIO_EVENTDESCRIPTION *eventdescription,
+  FMOD_STUDIO_EVENT_CALLBACK callback,
+  FMOD_STUDIO_EVENT_CALLBACK_TYPE callbackmask
+);
+
+ +
RESULT Studio.EventDescription.setCallback(
+  EVENT_CALLBACK callback,
+  EVENT_CALLBACK_TYPE callbackmask = EVENT_CALLBACK_TYPE.ALL
+);
+
+ +
Studio.EventDescription.setCallback(
+  callback,
+  callbackmask
+);
+
+ +
+
callback
+
User callback. (FMOD_STUDIO_EVENT_CALLBACK)
+
callbackmask
+
Bitfield specifying which callback types are required. (FMOD_STUDIO_EVENT_CALLBACK_TYPE)
+
+

This function sets a user callback which will be assigned to all event instances subsequently created from the event. The callback for individual instances can be set with Studio::EventInstance::setCallback.

+

See Event Callbacks for more information about when callbacks occur.

+

See Also: Callback Behavior

+

Studio::EventDescription::setUserData

+

Sets the event user data.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
FMOD_RESULT Studio::EventDescription::setUserData(
+  void *userdata
+);
+
+ +
FMOD_RESULT FMOD_Studio_EventDescription_SetUserData(
+  FMOD_STUDIO_EVENTDESCRIPTION *eventdescription,
+  void *userdata
+);
+
+ +
RESULT Studio.EventDescription.setUserData(
+  IntPtr userdata
+);
+
+ +
Studio.EventDescription.setUserData(
+  userdata
+);
+
+ +
+
userdata
+
User data.
+
+

This function allows arbitrary user data to be attached to this object. See the User Data section of the glossary for an example of how to get and set user data.

+

See Also: Studio::EventDescription::getUserData

+

Studio::EventDescription::unloadSampleData

+

Unloads all non-streaming sample data.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
FMOD_RESULT Studio::EventDescription::unloadSampleData();
+
+ +
FMOD_RESULT FMOD_Studio_EventDescription_UnloadSampleData(FMOD_STUDIO_EVENTDESCRIPTION *eventdescription);
+
+ +
RESULT Studio.EventDescription.unloadSampleData();
+
+ +
Studio.EventDescription.unloadSampleData();
+
+ +

Sample data will not be unloaded until all instances of the event are released.

+

See Also: Studio::EventDescription::loadSampleData, Sample Data Loading

+

FMOD_STUDIO_USER_PROPERTY

+

Describes a user property.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
typedef struct FMOD_STUDIO_USER_PROPERTY {
+  const char                      *name;
+  FMOD_STUDIO_USER_PROPERTY_TYPE   type;
+  union
+  {
+      int                              intvalue;
+      FMOD_BOOL                        boolvalue;
+      float                            floatvalue;
+      const char                      *stringvalue;
+  }
+} FMOD_STUDIO_USER_PROPERTY;
+
+ +
struct USER_PROPERTY
+{
+    StringWrapper name;
+    USER_PROPERTY_TYPE type;
+    int intvalue;
+    bool boolvalue;
+    float floatvalue;
+    string stringvalue;
+}
+
+ +
FMOD_STUDIO_USER_PROPERTY
+{
+  name,
+  type,
+  intvalue,
+  boolvalue,
+  floatvalue,
+  stringvalue,
+};
+
+ +
+
name
+
Property name. (UTF-8 string)
+
type
+
Property type. (FMOD_STUDIO_USER_PROPERTY_TYPE)
+
intvalue
+
Integer value. Only valid when type is FMOD_STUDIO_USER_PROPERTY_TYPE_INTEGER.
+
boolvalue
+
+

Boolean value. Only valid when type is FMOD_STUDIO_USER_PROPERTY_TYPE_BOOLEAN.

+
    +
  • Units: Boolean
  • +
+
+
floatvalue
+
Floating point value. Only valid when type is FMOD_STUDIO_USER_PROPERTY_TYPE_FLOAT.
+
stringvalue
+
String value. Only valid when type is FMOD_STUDIO_USER_PROPERTY_TYPE_STRING.
+
+

See Also: Studio::EventDescription::getUserProperty

+

FMOD_STUDIO_USER_PROPERTY_TYPE

+

User property types.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
typedef enum FMOD_STUDIO_USER_PROPERTY_TYPE {
+  FMOD_STUDIO_USER_PROPERTY_TYPE_INTEGER,
+  FMOD_STUDIO_USER_PROPERTY_TYPE_BOOLEAN,
+  FMOD_STUDIO_USER_PROPERTY_TYPE_FLOAT,
+  FMOD_STUDIO_USER_PROPERTY_TYPE_STRING
+} FMOD_STUDIO_USER_PROPERTY_TYPE;
+
+ +
enum USER_PROPERTY_TYPE
+{
+    INTEGER,
+    BOOLEAN,
+    FLOAT,
+    STRING,
+}
+
+ +
STUDIO_USER_PROPERTY_TYPE_INTEGER
+STUDIO_USER_PROPERTY_TYPE_BOOLEAN
+STUDIO_USER_PROPERTY_TYPE_FLOAT
+STUDIO_USER_PROPERTY_TYPE_STRING
+
+ +
+
FMOD_STUDIO_USER_PROPERTY_TYPE_INTEGER
+
Integer.
+
FMOD_STUDIO_USER_PROPERTY_TYPE_BOOLEAN
+
Boolean.
+
FMOD_STUDIO_USER_PROPERTY_TYPE_FLOAT
+
Floating point number.
+
FMOD_STUDIO_USER_PROPERTY_TYPE_STRING
+
String.
+
+

See Also: FMOD_STUDIO_USER_PROPERTY

+ + +
+ + + diff --git a/FMOD/doc/FMOD API User Manual/studio-api-eventinstance.html b/FMOD/doc/FMOD API User Manual/studio-api-eventinstance.html new file mode 100644 index 0000000..9fd5229 --- /dev/null +++ b/FMOD/doc/FMOD API User Manual/studio-api-eventinstance.html @@ -0,0 +1,2299 @@ + + +Studio API Reference | Studio::EventInstance + + + + +
+ +
+

16. Studio API Reference | Studio::EventInstance

+

An instance of an FMOD Studio event.

+

Playback Control:

+ +
+ +

Playback Properties:

+ +
+ +

3D Attributes:

+ +

Parameters:

+ +

Core:

+ +

Profiling:

+ +

Callbacks:

+ +
+ +
+ +

General:

+ +

Studio::EventInstance::get3DAttributes

+

Retrieves the 3D attributes.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
FMOD_RESULT Studio::EventInstance::get3DAttributes(
+  FMOD_3D_ATTRIBUTES *attributes
+);
+
+ +
FMOD_RESULT FMOD_Studio_EventInstance_Get3DAttributes(
+  FMOD_STUDIO_EVENTINSTANCE *eventinstance,
+  FMOD_3D_ATTRIBUTES *attributes
+);
+
+ +
RESULT Studio.EventInstance.get3DAttributes(
+  out _3D_ATTRIBUTES attributes
+);
+
+ +
Studio.EventInstance.get3DAttributes(
+  attributes
+);
+
+ +
+
attributes Out
+
3D attributes. (FMOD_3D_ATTRIBUTES)
+
+

See Also: Studio::EventInstance::set3DAttributes

+

Studio::EventInstance::getChannelGroup

+

Retrieves the core ChannelGroup.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
FMOD_RESULT Studio::EventInstance::getChannelGroup(
+  ChannelGroup **group
+);
+
+ +
FMOD_RESULT FMOD_Studio_EventInstance_GetChannelGroup(
+  FMOD_STUDIO_EVENTINSTANCE *eventinstance,
+  FMOD_CHANNELGROUP **group
+);
+
+ +
RESULT Studio.EventInstance.getChannelGroup(
+  out FMOD.ChannelGroup group
+);
+
+ +
Studio.EventInstance.getChannelGroup(
+  group
+);
+
+ +
+
group Out
+
Core ChannelGroup corresponding to the master track. (ChannelGroup)
+
+

Until the event instance has been fully created this function will return FMOD_ERR_STUDIO_NOT_LOADED.

+

Studio::EventInstance::getCPUUsage

+

Retrieves the event CPU usage data.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
FMOD_RESULT Studio::EventInstance::getCPUUsage(
+  unsigned int *exclusive,
+  unsigned int *inclusive
+);
+
+ +
FMOD_RESULT FMOD_Studio_EventInstance_GetCPUUsage(
+  FMOD_STUDIO_EVENTINSTANCE *eventinstance,
+  unsigned int *exclusive,
+  unsigned int *inclusive
+);
+
+ +
RESULT Studio.EventInstance.getCPUUsage(
+  out uint exclusive,
+  out uint inclusive
+);
+
+ +
Studio.EventInstance.getCPUUsage(
+  exclusive,
+  inclusive
+);
+
+ +
+
exclusive OutOpt
+
+

CPU time spent processing just this unit during the last update.

+
    +
  • Units: Microseconds
  • +
+
+
inclusive OutOpt
+
+

CPU time spent processing this unit and all of its input during the last update.

+
    +
  • Units: Microseconds
  • +
+
+
+

FMOD_INIT_PROFILE_ENABLE with System::init is required to call this function.

+

Studio::EventInstance::getDescription

+

Retrieves the event description.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
FMOD_RESULT Studio::EventInstance::getDescription(
+  Studio::EventDescription **description
+);
+
+ +
FMOD_RESULT FMOD_Studio_EventInstance_GetDescription(
+  FMOD_STUDIO_EVENTINSTANCE *eventinstance,
+  FMOD_STUDIO_EVENTDESCRIPTION **description
+);
+
+ +
RESULT Studio.EventInstance.getDescription(
+  out EventDescription description
+);
+
+ +
Studio.EventInstance.getDescription(
+  description
+);
+
+ +
+
description Out
+
Event description. (Studio::EventDescription)
+
+

Studio::EventInstance::getListenerMask

+

Retrieves the listener mask.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
FMOD_RESULT Studio::EventInstance::getListenerMask(
+  unsigned int *mask
+);
+
+ +
FMOD_RESULT FMOD_Studio_EventInstance_GetListenerMask(
+  FMOD_STUDIO_EVENTINSTANCE *eventinstance,
+  unsigned int *mask
+);
+
+ +
RESULT Studio.EventInstance.getListenerMask(
+  out uint mask
+);
+
+ +
Studio.EventInstance.getListenerMask(
+  mask
+);
+
+ +
+
mask Out
+
Listener mask.
+
+

See Also: Studio::EventInstance::setListenerMask

+

Studio::EventInstance::getMemoryUsage

+

Retrieves memory usage statistics.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
FMOD_RESULT Studio::EventInstance::getMemoryUsage(
+  FMOD_STUDIO_MEMORY_USAGE *memoryusage
+);
+
+ +
FMOD_RESULT FMOD_Studio_EventInstance_GetMemoryUsage(
+  FMOD_STUDIO_EVENTINSTANCE *eventinstance,
+  FMOD_STUDIO_MEMORY_USAGE *memoryusage
+);
+
+ +
RESULT Studio.EventInstance.getMemoryUsage(
+  out MEMORY_USAGE memoryusage
+);
+
+ +
+

Not supported for JavaScript.

+
+
+
memoryusage Out
+
Memory usage. (FMOD_STUDIO_MEMORY_USAGE)
+
+

Memory usage statistics are only available in logging builds, in release builds memoryusage will contain zero for all values this function.

+

Studio::EventInstance::getMinMaxDistance

+

Retrieves the minimum and maximum distances for 3D attenuation.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
FMOD_RESULT Studio::EventInstance::getMinMaxDistance(
+  float *min,
+  float *max
+);
+
+ +
FMOD_RESULT FMOD_Studio_EventInstance_GetMinMaxDistance(
+  FMOD_STUDIO_EVENTINSTANCE *eventinstance,
+  float *min,
+  float *max
+);
+
+ +
RESULT Studio.EventInstance.getMinMaxDistance(
+  out float min,
+  out float max
+);
+
+ +
Studio.EventInstance.getMinMaxDistance(
+  min,
+  max
+);
+
+ +
+
min OutOpt
+
+

Minimum distance.

+ +
+
max OutOpt
+
+

Maximum distance.

+ +
+
+

See Also: Studio::EventDescription::getMinMaxDistance

+

Studio::EventInstance::getParameterByID

+

Retrieves a parameter value by unique identifier.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
FMOD_RESULT Studio::EventInstance::getParameterByID(
+  FMOD_STUDIO_PARAMETER_ID id,
+  float *value,
+  float *finalvalue = nullptr
+);
+
+ +
FMOD_RESULT FMOD_Studio_EventInstance_GetParameterByID(
+  FMOD_STUDIO_EVENTINSTANCE *eventinstance,
+  FMOD_STUDIO_PARAMETER_ID id,
+  float *value,
+  float *finalvalue
+);
+
+ +
RESULT Studio.EventInstance.getParameterByID(
+  PARAMETER_ID id,
+  out float value
+);
+RESULT Studio.EventInstance.getParameterByID(
+  PARAMETER_ID id,
+  out float value,
+  out float finalvalue
+);
+
+ +
Studio.EventInstance.getParameterByID(
+  id,
+  value,
+  finalvalue
+);
+
+ +
+
id
+
Parameter identifier. (FMOD_STUDIO_PARAMETER_ID)
+
value OutOpt
+
Parameter value as set from the public API.
+
finalvalue OutOpt
+
Final combined parameter value.
+
+

Automatic parameters always return value as 0 since they can never have their value set from the public API.

+

finalvalue is the final value of the parameter after applying adjustments due to automation, modulation, seek speed, and parameter velocity to value. This is calculated asynchronously when the Studio system updates.

+

See Also: Studio::EventInstance::setParameterByID

+

Studio::EventInstance::getParameterByName

+

Retrieves a parameter value by name, including the path if needed.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
FMOD_RESULT Studio::EventInstance::getParameterByName(
+  const char *name,
+  float *value,
+  float *finalvalue = nullptr
+);
+
+ +
FMOD_RESULT FMOD_Studio_EventInstance_GetParameterByName(
+  FMOD_STUDIO_EVENTINSTANCE *eventinstance,
+  const char *name,
+  float *value,
+  float *finalvalue
+);
+
+ +
RESULT Studio.EventInstance.getParameterByName(
+  string name,
+  out float value
+);
+RESULT Studio.EventInstance.getParameterByName(
+  string name,
+  out float value,
+  out float finalvalue
+);
+
+ +
Studio.EventInstance.getParameterByName(
+  name,
+  value,
+  finalvalue
+);
+
+ +
+
name
+
Parameter name, including the path if needed (case-insensitive). (UTF-8 string)
+
value OutOpt
+
Parameter value as set from the public API.
+
finalvalue OutOpt
+
Final combined parameter value.
+
+

Automatic parameters always return value as 0 since they can never have their value set from the public API.

+

finalvalue is the final value of the parameter after applying adjustments due to automation, modulation, seek speed, and parameter velocity to value. This is calculated asynchronously when the Studio system updates.

+

See Also: Studio::EventInstance::setParameterByName

+

Studio::EventInstance::getPaused

+

Retrieves the pause state.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
FMOD_RESULT Studio::EventInstance::getPaused(
+  bool *paused
+);
+
+ +
FMOD_RESULT FMOD_Studio_EventInstance_GetPaused(
+  FMOD_STUDIO_EVENTINSTANCE *eventinstance,
+  FMOD_BOOL *paused
+);
+
+ +
RESULT Studio.EventInstance.getPaused(
+  out bool paused
+);
+
+ +
Studio.EventInstance.getPaused(
+  paused
+);
+
+ +
+
paused Out
+
+

Pause state. True if the event instance is paused.

+
    +
  • Units: Boolean
  • +
+
+
+

See Also: Studio::EventInstance::setPaused

+

Studio::EventInstance::getPitch

+

Retrieves the pitch multiplier.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
FMOD_RESULT Studio::EventInstance::getPitch(
+  float *pitch,
+  float *finalpitch = nullptr
+);
+
+ +
FMOD_RESULT FMOD_Studio_EventInstance_GetPitch(
+  FMOD_STUDIO_EVENTINSTANCE *eventinstance,
+  float *pitch,
+  float *finalpitch
+);
+
+ +
RESULT Studio.EventInstance.getPitch(
+  out float pitch
+);
+RESULT Studio.EventInstance.getPitch(
+  out float pitch,
+  out float finalpitch
+);
+
+ +
Studio.EventInstance.getPitch(
+  pitch,
+  finalpitch
+);
+
+ +
+
pitch OutOpt
+
Pitch multiplier as set from the public API.
+
finalpitch OutOpt
+
Final combined pitch.
+
+

The final combined value returned in finalpitch combines the pitch set using Studio::EventInstance::setPitch with the result of any automation or modulation. The final combined pitch is calculated asynchronously when the Studio system updates.

+

Studio::EventInstance::getPlaybackState

+

Retrieves the playback state.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
FMOD_RESULT Studio::EventInstance::getPlaybackState(
+  FMOD_STUDIO_PLAYBACK_STATE *state
+);
+
+ +
FMOD_RESULT FMOD_Studio_EventInstance_GetPlaybackState(
+  FMOD_STUDIO_EVENTINSTANCE *eventinstance,
+  FMOD_STUDIO_PLAYBACK_STATE *state
+);
+
+ +
RESULT Studio.EventInstance.getPlaybackState(
+  out PLAYBACK_STATE state
+);
+
+ +
Studio.EventInstance.getPlaybackState(
+  state
+);
+
+ +
+
state Out
+
Playback state. (FMOD_STUDIO_PLAYBACK_STATE)
+
+

You can poll this function to track the playback state of an event instance.

+

If the instance is invalid, then the state will be set to FMOD_STUDIO_PLAYBACK_STOPPED.

+

See Also: Studio::EventInstance::start, Studio::EventInstance::stop, FMOD_STUDIO_EVENT_CALLBACK_TYPE

+

Studio::EventInstance::getProperty

+

Retrieves the value of a built-in property.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
FMOD_RESULT Studio::EventInstance::getProperty(
+  FMOD_STUDIO_EVENT_PROPERTY index,
+  float *value
+);
+
+ +
FMOD_RESULT FMOD_Studio_EventInstance_GetProperty(
+  FMOD_STUDIO_EVENTINSTANCE *eventinstance,
+  FMOD_STUDIO_EVENT_PROPERTY index,
+  float *value
+);
+
+ +
RESULT Studio.EventInstance.getProperty(
+  EVENT_PROPERTY index,
+  out float value
+);
+
+ +
Studio.EventInstance.getProperty(
+  index,
+  value
+);
+
+ +
+
index
+
Property index. (FMOD_STUDIO_EVENT_PROPERTY)
+
value Out
+
Property value set via Studio::EventInstance::setProperty.
+
+

A default FMOD_STUDIO_EVENT_PROPERTY value means that the Instance is using the value set in Studio and it has not been overridden using Studio::EventInstance::setProperty. Access the default property values through the Studio::EventDescription.

+

Studio::EventInstance::getReverbLevel

+

Retrieves the core reverb send level.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
FMOD_RESULT Studio::EventInstance::getReverbLevel(
+  int index,
+  float *level
+);
+
+ +
FMOD_RESULT FMOD_Studio_EventInstance_GetReverbLevel(
+  FMOD_STUDIO_EVENTINSTANCE *eventinstance,
+  int index,
+  float *level
+);
+
+ +
RESULT Studio.EventInstance.getReverbLevel(
+  int index,
+  out float level
+);
+
+ +
Studio.EventInstance.getReverbLevel(
+  index,
+  level
+);
+
+ +
+
index
+
+

Core reverb instance index.

+
    +
  • Range: [0, 3]
  • +
+
+
level Out
+
Reverb send level.
+
+

See Also: Studio::EventInstance::setReverbLevel

+

Studio::EventInstance::getSystem

+

Retrieves the FMOD Studio System.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
FMOD_RESULT Studio::EventInstance::getSystem(
+  Studio::System **system
+);
+
+ +
FMOD_RESULT FMOD_Studio_EventInstance_GetSystem(
+  FMOD_STUDIO_EVENTINSTANCE *eventinstance,
+  FMOD_STUDIO_SYSTEM **system
+);
+
+ +
RESULT Studio.EventInstance.getSystem(
+  out System system
+);
+
+ +
Studio.EventInstance.getSystem(
+  system
+);
+
+ +
+
system Out
+
Studio System. (Studio::System)
+
+

Studio::EventInstance::getTimelinePosition

+

Retrieves the timeline cursor position.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
FMOD_RESULT Studio::EventInstance::getTimelinePosition(
+  int *position
+);
+
+ +
FMOD_RESULT FMOD_Studio_EventInstance_GetTimelinePosition(
+  FMOD_STUDIO_EVENTINSTANCE *eventinstance,
+  int *position
+);
+
+ +
RESULT Studio.EventInstance.getTimelinePosition(
+  out int position
+);
+
+ +
Studio.EventInstance.getTimelinePosition(
+  position
+);
+
+ +
+
position Out
+
Timeline position.
+
+

See Also: Studio::EventInstance::setTimelinePosition

+

Studio::EventInstance::getUserData

+

Retrieves the event instance user data.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
FMOD_RESULT Studio::EventInstance::getUserData(
+  void **userdata
+);
+
+ +
FMOD_RESULT FMOD_Studio_EventInstance_GetUserData(
+  FMOD_STUDIO_EVENTINSTANCE *eventinstance,
+  void **userdata
+);
+
+ +
RESULT Studio.EventInstance.getUserData(
+  out IntPtr userdata
+);
+
+ +
Studio.EventInstance.getUserData(
+  userdata
+);
+
+ +
+
userdata Out
+
User data set by calling Studio::EventInstance::setUserData.
+
+

This function allows arbitrary user data to be retrieved from this object. See the User Data section of the glossary for an example of how to get and set user data.

+

Studio::EventInstance::getVolume

+

Retrieves the volume level.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
FMOD_RESULT Studio::EventInstance::getVolume(
+  float *volume,
+  float *finalvolume = nullptr
+);
+
+ +
FMOD_RESULT FMOD_Studio_EventInstance_GetVolume(
+  FMOD_STUDIO_EVENTINSTANCE *eventinstance,
+  float *volume,
+  float *finalvolume
+);
+
+ +
RESULT Studio.EventInstance.getVolume(
+  out float volume
+);
+RESULT Studio.EventInstance.getVolume(
+  out float volume,
+  out float finalvolume
+);
+
+ +
Studio.EventInstance.getVolume(
+  volume,
+  finalvolume
+);
+
+ +
+
volume OutOpt
+
Volume as set from the public API.
+
finalvolume OutOpt
+
Final combined volume.
+
+

The final combined value returned in finalvolume combines the volume set using the public API with the result of any automation or modulation. The final combined volume is calculated asynchronously when the Studio system updates.

+

See Also: Studio::EventInstance::setVolume

+

Studio::EventInstance::isValid

+

Checks that the EventInstance reference is valid.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
bool Studio::EventInstance::isValid()
+
+ +
bool FMOD_Studio_EventInstance_IsValid(FMOD_STUDIO_EVENTINSTANCE *eventinstance)
+
+ +
bool Studio.EventInstance.isValid()
+
+ +
Studio.EventInstance.isValid()
+
+ +

Studio::EventInstance::isVirtual

+

Retrieves the virtualization state.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
FMOD_RESULT Studio::EventInstance::isVirtual(
+  bool *virtualstate
+);
+
+ +
FMOD_RESULT FMOD_Studio_EventInstance_IsVirtual(
+  FMOD_STUDIO_EVENTINSTANCE *eventinstance,
+  FMOD_BOOL *virtualstate
+);
+
+ +
RESULT Studio.EventInstance.isVirtual(
+  out bool virtualstate
+);
+
+ +
Studio.EventInstance.isVirtual(
+  virtualstate
+);
+
+ +
+
virtualstate Out
+
+

Virtualization state. True if the event instance has been virtualized.

+
    +
  • Units: Boolean
  • +
+
+
+

This function checks whether an event instance has been virtualized due to the polyphony limit being exceeded. For more information, see the Virtual Voice System section of the Managing Resources in the Core API chapter.

+

Studio::EventInstance::keyOff

+

Allow an event to continue past a sustain point.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
FMOD_RESULT Studio::EventInstance::keyOff();
+
+ +
FMOD_RESULT FMOD_Studio_EventInstance_KeyOff(FMOD_STUDIO_EVENTINSTANCE *eventinstance);
+
+ +
RESULT Studio.EventInstance.keyOff();
+
+ +
Studio.EventInstance.keyOff();
+
+ +

Multiple sustain points may be bypassed ahead of time and the key off count will be decremented each time the timeline cursor passes a sustain point.

+

This function returns FMOD_ERR_EVENT_NOTFOUND if the event has no sustain points.

+

See Also: Studio::EventDescription::hasSustainPoint

+

Studio::EventInstance::release

+

Marks the event instance for release.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
FMOD_RESULT Studio::EventInstance::release();
+
+ +
FMOD_RESULT FMOD_Studio_EventInstance_Release(FMOD_STUDIO_EVENTINSTANCE *eventinstance);
+
+ +
RESULT Studio.EventInstance.release();
+
+ +
Studio.EventInstance.release();
+
+ +

This function marks the event instance to be released. Event instances marked for release are destroyed by the asynchronous update when they are in the stopped state (FMOD_STUDIO_PLAYBACK_STOPPED).

+

Generally it is a best practice to release event instances immediately after calling Studio::EventInstance::start, unless you want to play the event instance multiple times or explicitly stop it and start it again later. It is possible to interact with the instance after falling release(), however if the sound has stopped ERR_INVALID_HANDLE will be returned.

+

See Also: Studio::EventInstance::stop, Studio::EventInstance::getPlaybackState

+

Studio::EventInstance::set3DAttributes

+

Sets the 3D attributes.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
FMOD_RESULT Studio::EventInstance::set3DAttributes(
+  const FMOD_3D_ATTRIBUTES *attributes
+);
+
+ +
FMOD_RESULT FMOD_Studio_EventInstance_Set3DAttributes(
+  FMOD_STUDIO_EVENTINSTANCE *eventinstance,
+  FMOD_3D_ATTRIBUTES *attributes
+);
+
+ +
RESULT Studio.EventInstance.set3DAttributes(
+  _3D_ATTRIBUTES attributes
+);
+
+ +
Studio.EventInstance.set3DAttributes(
+  attributes
+);
+
+ +
+
attributes
+
3D attributes. (FMOD_3D_ATTRIBUTES)
+
+

An event's 3D attributes specify its position, velocity and orientation. The 3D attributes are used to calculate 3D panning, doppler and the values of automatic distance and angle parameters.

+

See Also: Studio::EventInstance::get3DAttributes

+

Studio::EventInstance::setCallback

+

Sets the user callback.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
FMOD_RESULT Studio::EventInstance::setCallback(
+  FMOD_STUDIO_EVENT_CALLBACK callback,
+  FMOD_STUDIO_EVENT_CALLBACK_TYPE callbackmask = FMOD_STUDIO_EVENT_CALLBACK_ALL
+);
+
+ +
FMOD_RESULT FMOD_Studio_EventInstance_SetCallback(
+  FMOD_STUDIO_EVENTINSTANCE *eventinstance,
+  FMOD_STUDIO_EVENT_CALLBACK callback,
+  FMOD_STUDIO_EVENT_CALLBACK_TYPE callbackmask
+);
+
+ +
RESULT Studio.EventInstance.setCallback(
+  EVENT_CALLBACK callback,
+  EVENT_CALLBACK_TYPE callbackmask = EVENT_CALLBACK_TYPE.ALL
+);
+
+ +
Studio.EventInstance.setCallback(
+  callback,
+  callbackmask
+);
+
+ +
+
callback
+
User callback. (FMOD_STUDIO_EVENT_CALLBACK)
+
callbackmask
+
Bitfield specifying which callback types are required. (FMOD_STUDIO_EVENT_CALLBACK_TYPE)
+
+

See Event Callbacks for more information about when callbacks occur.

+

See Also: Callback Behavior, Studio::EventDescription::setCallback

+

Studio::EventInstance::setListenerMask

+

Sets the listener mask.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
FMOD_RESULT Studio::EventInstance::setListenerMask(
+  unsigned int mask
+);
+
+ +
FMOD_RESULT FMOD_Studio_EventInstance_SetListenerMask(
+  FMOD_STUDIO_EVENTINSTANCE *eventinstance,
+  unsigned int mask
+);
+
+ +
RESULT Studio.EventInstance.setListenerMask(
+  uint mask
+);
+
+ +
Studio.EventInstance.setListenerMask(
+  mask
+);
+
+ +
+
mask
+
+

Listener mask.

+
    +
  • Default: 0xFFFFFFFF
  • +
+
+
+

The listener mask controls which listeners are considered when calculating 3D panning and the values of listener relative automatic parameters.

+

To create the mask you must perform bitwise OR and shift operations, the basic form is 1 << listener_index ORd together with other required listener indices.
+For example to create a mask for listener index 0 and 2 the calculation would be mask = (1 << 0) | (1 << 2), to include all listeners use the default mask of 0xFFFFFFFF.

+

See Also: Studio::EventInstance::getListenerMask

+

Studio::EventInstance::setParameterByID

+

Sets a parameter value by unique identifier.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
FMOD_RESULT Studio::EventInstance::setParameterByID(
+  FMOD_STUDIO_PARAMETER_ID id,
+  float value,
+  bool ignoreseekspeed = false
+);
+
+ +
FMOD_RESULT FMOD_Studio_EventInstance_SetParameterByID(
+  FMOD_STUDIO_EVENTINSTANCE *eventinstance,
+  FMOD_STUDIO_PARAMETER_ID id,
+  float value,
+  FMOD_BOOL ignoreseekspeed
+);
+
+ +
RESULT Studio.EventInstance.setParameterByID(
+  PARAMETER_ID id,
+  float value,
+  bool ignoreseekspeed = false
+);
+
+ +
Studio.EventInstance.setParameterByID(
+  id,
+  value,
+  ignoreseekspeed
+);
+
+ +
+
id
+
Parameter identifier. (FMOD_STUDIO_PARAMETER_ID)
+
value
+
Value for given identifier.
+
ignoreseekspeed
+
+

Specifies whether to ignore the parameter's seek speed and set the value immediately.

+
    +
  • Units: Boolean
  • +
+
+
+

The value will be set instantly regardless of ignoreseekspeed when the Event playback state is FMOD_STUDIO_PLAYBACK_STOPPED.

+

If the specified parameter is read only, is an automatic parameter, or is not of type FMOD_STUDIO_PARAMETER_GAME_CONTROLLED, then FMOD_ERR_INVALID_PARAM is returned.

+

See Also: Studio::EventInstance::setParameterByName, Studio::EventInstance::setParametersByIDs, Studio::EventInstance::getParameterByName, Studio::EventInstance::getParameterByID

+

Studio::EventInstance::setParameterByIDWithLabel

+

Sets a parameter value by unique identifier, looking up the value label.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
FMOD_RESULT Studio::EventInstance::setParameterByIDWithLabel(
+  FMOD_STUDIO_PARAMETER_ID id,
+  const char *label,
+  bool ignoreseekspeed = false
+);
+
+ +
FMOD_RESULT FMOD_Studio_EventInstance_SetParameterByIDWithLabel(
+  FMOD_STUDIO_EVENTINSTANCE *eventinstance,
+  FMOD_STUDIO_PARAMETER_ID id,
+  const char *label,
+  FMOD_BOOL ignoreseekspeed
+);
+
+ +
RESULT Studio.EventInstance.setParameterByIDWithLabel(
+  PARAMETER_ID id,
+  string label,
+  bool ignoreseekspeed = false
+);
+
+ +
Studio.EventInstance.setParameterByIDWithLabel(
+  id,
+  label,
+  ignoreseekspeed
+);
+
+ +
+
id
+
Parameter identifier. (FMOD_STUDIO_PARAMETER_ID)
+
label
+
Labeled value for given name.
+
ignoreseekspeed
+
Specifies whether to ignore the parameter's seek speed and set the value immediately.
+
+

The label will be set instantly regardless of ignoreseekspeed when the Event playback state is FMOD_STUDIO_PLAYBACK_STOPPED.

+

If the specified parameter is read only, is an automatic parameter or is not of type FMOD_STUDIO_PARAMETER_GAME_CONTROLLED then FMOD_ERR_INVALID_PARAM is returned.

+

If the specified label is not found, FMOD_ERR_EVENT_NOTFOUND is returned. This lookup is case sensitive.

+

See Also: Studio::EventInstance::setParameterByName, Studio::EventInstance::setParametersByIDs, Studio::EventInstance::getParameterByName, Studio::EventInstance::getParameterByID

+

Studio::EventInstance::setParameterByName

+

Sets a parameter value by name, including the path if needed.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
FMOD_RESULT Studio::EventInstance::setParameterByName(
+  const char *name,
+  float value,
+  bool ignoreseekspeed = false
+);
+
+ +
FMOD_RESULT FMOD_Studio_EventInstance_SetParameterByName(
+  FMOD_STUDIO_EVENTINSTANCE *eventinstance,
+  const char *name,
+  float value,
+  FMOD_BOOL ignoreseekspeed
+);
+
+ +
RESULT Studio.EventInstance.setParameterByName(
+  string name,
+  float value,
+  bool ignoreseekspeed = false
+);
+
+ +
Studio.EventInstance.setParameterByName(
+  name,
+  value,
+  ignoreseekspeed
+);
+
+ +
+
name
+
Parameter name, including the path if needed (case-insensitive). (UTF-8 string)
+
value
+
Value for given name.
+
ignoreseekspeed
+
+

Specifies whether to ignore the parameter's seek speed and set the value immediately.

+
    +
  • Units: Boolean
  • +
+
+
+

The value will be set instantly regardless of ignoreseekspeed when the Event playback state is FMOD_STUDIO_PLAYBACK_STOPPED.

+

If the specified parameter is read only, is an automatic parameter or is not of type FMOD_STUDIO_PARAMETER_GAME_CONTROLLED then FMOD_ERR_INVALID_PARAM is returned.

+

If the event has no parameter matching name then FMOD_ERR_EVENT_NOTFOUND is returned.

+

See Also: Studio::EventInstance::setParameterByID, Studio::EventInstance::setParametersByIDs, Studio::EventInstance::getParameterByName, Studio::EventInstance::getParameterByID

+

Studio::EventInstance::setParameterByNameWithLabel

+

Sets a parameter value by name, including the path if needed, looking up the value label.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
FMOD_RESULT Studio::EventInstance::setParameterByNameWithLabel(
+  const char *name,
+  const char *label,
+  bool ignoreseekspeed = false
+);
+
+ +
FMOD_RESULT FMOD_Studio_EventInstance_SetParameterByNameWithLabel(
+  FMOD_STUDIO_EVENTINSTANCE *eventinstance,
+  const char *name,
+  const char *label,
+  FMOD_BOOL ignoreseekspeed
+);
+
+ +
RESULT Studio.EventInstance.setParameterByNameWithLabel(
+  string name,
+  string label,
+  bool ignoreseekspeed = false
+);
+
+ +
Studio.EventInstance.setParameterByNameWithLabel(
+  name,
+  label,
+  ignoreseekspeed
+);
+
+ +
+
name
+
Parameter name, including the path if needed (case-insensitive). (UTF-8 string)
+
label
+
Labeled value for given name.
+
ignoreseekspeed
+
Specifies whether to ignore the parameter's seek speed and set the value immediately.
+
+

The label will be set instantly regardless of ignoreseekspeed when the Event playback state is FMOD_STUDIO_PLAYBACK_STOPPED.

+

If the specified parameter is read only, is an automatic parameter or is not of type FMOD_STUDIO_PARAMETER_GAME_CONTROLLED then FMOD_ERR_INVALID_PARAM is returned.

+

If the event has no parameter matching name then FMOD_ERR_EVENT_NOTFOUND is returned.

+

If the specified label is not found, FMOD_ERR_EVENT_NOTFOUND is returned. This lookup is case sensitive.

+

See Also: Studio::EventInstance::setParameterByID, Studio::EventInstance::setParametersByIDs, Studio::EventInstance::getParameterByName, Studio::EventInstance::getParameterByID

+

Studio::EventInstance::setParametersByIDs

+

Sets multiple parameter values by unique identifier.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
FMOD_RESULT Studio::EventInstance::setParametersByIDs(
+  const FMOD_STUDIO_PARAMETER_ID *ids,
+  float *values,
+  int count,
+  bool ignoreseekspeed = false
+);
+
+ +
FMOD_RESULT FMOD_Studio_EventInstance_SetParametersByIDs(
+  FMOD_STUDIO_EVENTINSTANCE *eventinstance,
+  const FMOD_STUDIO_PARAMETER_ID *ids,
+  float *values,
+  int count,
+  FMOD_BOOL ignoreseekspeed
+);
+
+ +
RESULT Studio.EventInstance.setParametersByIDs(
+  PARAMETER_ID[] ids,
+  float[] values,
+  int count,
+  bool ignoreseekspeed = false
+);
+
+ +
Studio.EventInstance.setParametersByIDs(
+  ids,
+  values,
+  count,
+  ignoreseekspeed
+);
+
+ +
+
ids
+
Array of parameter identifiers. (FMOD_STUDIO_PARAMETER_ID)
+
values
+
Array of values for each given identifier.
+
count
+
+

Number of items in the given arrays.

+
    +
  • Range: [1, 32]
  • +
+
+
ignoreseekspeed
+
+

Specifies whether to ignore the parameter's seek speed and set the value immediately.

+
    +
  • Units: Boolean
  • +
+
+
+

All values will be set instantly regardless of ignoreseekspeed when the Event playback state is FMOD_STUDIO_PLAYBACK_STOPPED.

+

If any ID is set to all zeroes then the corresponding value will be ignored.

+

See Also: Studio::EventInstance::setParameterByName, Studio::EventInstance::setParameterByID, Studio::EventInstance::getParameterByName, Studio::EventInstance::getParameterByID

+

Studio::EventInstance::setPaused

+

Sets the pause state.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
FMOD_RESULT Studio::EventInstance::setPaused(
+  bool paused
+);
+
+ +
FMOD_RESULT FMOD_Studio_EventInstance_SetPaused(
+  FMOD_STUDIO_EVENTINSTANCE *eventinstance,
+  FMOD_BOOL paused
+);
+
+ +
RESULT Studio.EventInstance.setPaused(
+  bool paused
+);
+
+ +
Studio.EventInstance.setPaused(
+  paused
+);
+
+ +
+
paused
+
+

The desired pause state. True = paused, False = unpaused.

+
    +
  • Units: Boolean
  • +
+
+
+

This function allows pausing/unpausing of an event instance.

+

See Also: Studio::EventInstance::getPaused

+

Studio::EventInstance::setPitch

+

Sets the pitch multiplier.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
FMOD_RESULT Studio::EventInstance::setPitch(
+  float pitch
+);
+
+ +
FMOD_RESULT FMOD_Studio_EventInstance_SetPitch(
+  FMOD_STUDIO_EVENTINSTANCE *eventinstance,
+  float pitch
+);
+
+ +
RESULT Studio.EventInstance.setPitch(
+  float pitch
+);
+
+ +
Studio.EventInstance.setPitch(
+  pitch
+);
+
+ +
+
pitch
+
+

Pitch multiplier.

+
    +
  • Units: Linear
  • +
  • Range: [0, inf)
  • +
  • Default: 1
  • +
+
+
+

The pitch multiplier is used to modulate the event instance's pitch. The pitch multiplier can be set to any value greater than or equal to zero but the final combined pitch is clamped to the range [0, 100] before being applied.

+

See Also: Studio::EventInstance::getPitch

+

Studio::EventInstance::setProperty

+

Sets the value of a built-in property.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
FMOD_RESULT Studio::EventInstance::setProperty(
+  FMOD_STUDIO_EVENT_PROPERTY index,
+  float value
+);
+
+ +
FMOD_RESULT FMOD_Studio_EventInstance_SetProperty(
+  FMOD_STUDIO_EVENTINSTANCE *eventinstance,
+  FMOD_STUDIO_EVENT_PROPERTY index,
+  float value
+);
+
+ +
RESULT Studio.EventInstance.setProperty(
+  EVENT_PROPERTY index,
+  float value
+);
+
+ +
Studio.EventInstance.setProperty(
+  index,
+  value
+);
+
+ +
+
index
+
Property index. (FMOD_STUDIO_EVENT_PROPERTY)
+
value
+
Property value.
+
+

This will override the value set in Studio. Using the default FMOD_STUDIO_EVENT_PROPERTY value will revert back to the default values set in Studio.

+

An FMOD spatializer or object spatializer may override the values set for FMOD_STUDIO_EVENT_PROPERTY_MINIMUM_DISTANCE and FMOD_STUDIO_EVENT_PROPERTY_MAXIMUM_DISTANCE.

+

See Also: Studio::EventInstance::getProperty

+

Studio::EventInstance::setReverbLevel

+

Sets the core reverb send level.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
FMOD_RESULT Studio::EventInstance::setReverbLevel(
+  int index,
+  float level
+);
+
+ +
FMOD_RESULT FMOD_Studio_EventInstance_SetReverbLevel(
+  FMOD_STUDIO_EVENTINSTANCE *eventinstance,
+  int index,
+  float level
+);
+
+ +
RESULT Studio.EventInstance.setReverbLevel(
+  int index,
+  float level
+);
+
+ +
Studio.EventInstance.setReverbLevel(
+  index,
+  level
+);
+
+ +
+
index
+
+

Core reverb instance index.

+
    +
  • Range: [0, 3]
  • +
+
+
level
+
+

Reverb send level.

+
    +
  • Units: Linear
  • +
  • Range: [0, 1]
  • +
  • Default: 0
  • +
+
+
+

This function controls the send level for the signal from the event instance to a core reverb instance.

+

See Also: Studio::EventInstance::getReverbLevel, Working with Reverb

+

Studio::EventInstance::setTimelinePosition

+

Sets the timeline cursor position.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
FMOD_RESULT Studio::EventInstance::setTimelinePosition(
+  int position
+);
+
+ +
FMOD_RESULT FMOD_Studio_EventInstance_SetTimelinePosition(
+  FMOD_STUDIO_EVENTINSTANCE *eventinstance,
+  int position
+);
+
+ +
RESULT Studio.EventInstance.setTimelinePosition(
+  int position
+);
+
+ +
Studio.EventInstance.setTimelinePosition(
+  position
+);
+
+ +
+
position
+
+

Timeline position.

+
    +
  • Units: Milliseconds
  • +
  • Range: [0, inf)
  • +
+
+
+

See Also: Studio::EventInstance::getTimelinePosition

+

Studio::EventInstance::setUserData

+

Sets the event instance user data.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
FMOD_RESULT Studio::EventInstance::setUserData(
+  void *userdata
+);
+
+ +
FMOD_RESULT FMOD_Studio_EventInstance_SetUserData(
+  FMOD_STUDIO_EVENTINSTANCE *eventinstance,
+  void *userdata
+);
+
+ +
RESULT Studio.EventInstance.setUserData(
+  IntPtr userdata
+);
+
+ +
Studio.EventInstance.setUserData(
+  userdata
+);
+
+ +
+
userdata
+
User data.
+
+

This function allows arbitrary user data to be attached to this object. See the User Data section of the glossary for an example of how to get and set user data.

+

See Also: Studio::EventInstance::getUserData

+

Studio::EventInstance::setVolume

+

Sets the volume level.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
FMOD_RESULT Studio::EventInstance::setVolume(
+  float volume
+);
+
+ +
FMOD_RESULT FMOD_Studio_EventInstance_SetVolume(
+  FMOD_STUDIO_EVENTINSTANCE *eventinstance,
+  float volume
+);
+
+ +
RESULT Studio.EventInstance.setVolume(
+  float volume
+);
+
+ +
Studio.EventInstance.setVolume(
+  volume
+);
+
+ +
+
volume
+
+

Volume.

+
    +
  • Units: Linear
  • +
  • Range: [0, inf)
  • +
  • Default: 1
  • +
+
+
+

This volume is applied as a scaling factor for the event volume. It does not override the volume level set in FMOD Studio, nor any internal volume automation or modulation.

+

See Also: Studio::EventInstance::getVolume

+

Studio::EventInstance::start

+

Starts playback.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
FMOD_RESULT Studio::EventInstance::start();
+
+ +
FMOD_RESULT FMOD_Studio_EventInstance_Start(FMOD_STUDIO_EVENTINSTANCE *eventinstance);
+
+ +
RESULT Studio.EventInstance.start();
+
+ +
Studio.EventInstance.start();
+
+ +

If the instance was already playing then calling this function will restart the event.

+

Generally it is a best practice to call Studio::EventInstance::release on event instances immediately after starting them, unless you want to play the event instance multiple times or explicitly stop it and start it again later.

+

See Also: Studio::EventInstance::stop, Sample Data Loading

+

Studio::EventInstance::stop

+

Stops playback.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
FMOD_RESULT Studio::EventInstance::stop(
+  FMOD_STUDIO_STOP_MODE mode
+);
+
+ +
FMOD_RESULT FMOD_Studio_EventInstance_Stop(
+  FMOD_STUDIO_EVENTINSTANCE *eventinstance,
+  FMOD_STUDIO_STOP_MODE mode
+);
+
+ +
RESULT Studio.EventInstance.stop(
+  STOP_MODE mode
+);
+
+ +
Studio.EventInstance.stop(
+  mode
+);
+
+ +
+
mode
+
Stop mode. (FMOD_STUDIO_STOP_MODE)
+
+

See Also: Studio::EventInstance::start

+

FMOD_STUDIO_EVENT_CALLBACK

+

Callback that is fired when a Studio::EventInstance changes state.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
FMOD_RESULT F_CALL FMOD_STUDIO_EVENT_CALLBACK(
+  FMOD_STUDIO_EVENT_CALLBACK_TYPE type,
+  FMOD_STUDIO_EVENTINSTANCE *event,
+  void *parameters
+);
+
+ +
delegate RESULT Studio.EVENT_CALLBACK(
+  EVENT_CALLBACK_TYPE type,
+  IntPtr event,
+  IntPtr parameters
+);
+
+ +
function FMOD_STUDIO_EVENT_CALLBACK(
+  type,
+  event,
+  parameters
+)
+
+ +
+
type
+
The type of event that has occurred. (FMOD_STUDIO_EVENT_CALLBACK_TYPE)
+
event
+
The event instance that has changed state. (Studio::EventInstance)
+
parameters
+
The callback parameters. The data passed varies based on the callback type.
+
+

The data passed to the callback function in the parameters argument varies based on the callback type. See FMOD_STUDIO_EVENT_CALLBACK_TYPE for more information.

+

Return FMOD_OK from the callback unless you wish to signal that there is an error. Select an appropriate error code from FMOD_RESULT. Returning an error will result in a warning or error message being logged.

+
+

The 'event' argument Can be cast to Studio::EventInstance *.

+
+
+

The 'event' argument can be used via EventInstance by using FMOD.Studio.EventInstance instance = new FMOD.Studio.EventInstance(event);

+
+

See Also: Callback Behavior, Studio::EventInstance::setCallback, Studio::EventDescription::setCallback, Studio::System::getSoundInfo, FMOD_STUDIO_EVENT_CALLBACK_TYPE, FMOD_STUDIO_PROGRAMMER_SOUND_PROPERTIES

+

FMOD_STUDIO_EVENT_CALLBACK_TYPE

+

Studio event callback types.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
#define FMOD_STUDIO_EVENT_CALLBACK_CREATED                  0x00000001
+#define FMOD_STUDIO_EVENT_CALLBACK_DESTROYED                0x00000002
+#define FMOD_STUDIO_EVENT_CALLBACK_STARTING                 0x00000004
+#define FMOD_STUDIO_EVENT_CALLBACK_STARTED                  0x00000008
+#define FMOD_STUDIO_EVENT_CALLBACK_RESTARTED                0x00000010
+#define FMOD_STUDIO_EVENT_CALLBACK_STOPPED                  0x00000020
+#define FMOD_STUDIO_EVENT_CALLBACK_START_FAILED             0x00000040
+#define FMOD_STUDIO_EVENT_CALLBACK_CREATE_PROGRAMMER_SOUND  0x00000080
+#define FMOD_STUDIO_EVENT_CALLBACK_DESTROY_PROGRAMMER_SOUND 0x00000100
+#define FMOD_STUDIO_EVENT_CALLBACK_PLUGIN_CREATED           0x00000200
+#define FMOD_STUDIO_EVENT_CALLBACK_PLUGIN_DESTROYED         0x00000400
+#define FMOD_STUDIO_EVENT_CALLBACK_TIMELINE_MARKER          0x00000800
+#define FMOD_STUDIO_EVENT_CALLBACK_TIMELINE_BEAT            0x00001000
+#define FMOD_STUDIO_EVENT_CALLBACK_SOUND_PLAYED             0x00002000
+#define FMOD_STUDIO_EVENT_CALLBACK_SOUND_STOPPED            0x00004000
+#define FMOD_STUDIO_EVENT_CALLBACK_REAL_TO_VIRTUAL          0x00008000
+#define FMOD_STUDIO_EVENT_CALLBACK_VIRTUAL_TO_REAL          0x00010000
+#define FMOD_STUDIO_EVENT_CALLBACK_START_EVENT_COMMAND      0x00020000
+#define FMOD_STUDIO_EVENT_CALLBACK_NESTED_TIMELINE_BEAT     0x00040000
+#define FMOD_STUDIO_EVENT_CALLBACK_ALL                      0xFFFFFFFF
+
+ +
enum Studio.EVENT_CALLBACK_TYPE : uint
+{
+  CREATED                  = 0x00000001,
+  DESTROYED                = 0x00000002,
+  STARTING                 = 0x00000004,
+  STARTED                  = 0x00000008,
+  RESTARTED                = 0x00000010,
+  STOPPED                  = 0x00000020,
+  START_FAILED             = 0x00000040,
+  CREATE_PROGRAMMER_SOUND  = 0x00000080,
+  DESTROY_PROGRAMMER_SOUND = 0x00000100,
+  PLUGIN_CREATED           = 0x00000200,
+  PLUGIN_DESTROYED         = 0x00000400,
+  TIMELINE_MARKER          = 0x00000800,
+  TIMELINE_BEAT            = 0x00001000,
+  SOUND_PLAYED             = 0x00002000,
+  SOUND_STOPPED            = 0x00004000,
+  REAL_TO_VIRTUAL          = 0x00008000,
+  VIRTUAL_TO_REAL          = 0x00010000,
+  START_EVENT_COMMAND      = 0x00020000,
+  NESTED_TIMELINE_BEAT     = 0x00040000,
+  ALL                      = 0xFFFFFFFF,
+}
+
+ +
STUDIO_EVENT_CALLBACK_CREATED                  0x00000001
+STUDIO_EVENT_CALLBACK_DESTROYED                0x00000002
+STUDIO_EVENT_CALLBACK_STARTING                 0x00000004
+STUDIO_EVENT_CALLBACK_STARTED                  0x00000008
+STUDIO_EVENT_CALLBACK_RESTARTED                0x00000010
+STUDIO_EVENT_CALLBACK_STOPPED                  0x00000020
+STUDIO_EVENT_CALLBACK_START_FAILED             0x00000040
+STUDIO_EVENT_CALLBACK_CREATE_PROGRAMMER_SOUND  0x00000080
+STUDIO_EVENT_CALLBACK_DESTROY_PROGRAMMER_SOUND 0x00000100
+STUDIO_EVENT_CALLBACK_PLUGIN_CREATED           0x00000200
+STUDIO_EVENT_CALLBACK_PLUGIN_DESTROYED         0x00000400
+STUDIO_EVENT_CALLBACK_TIMELINE_MARKER          0x00000800
+STUDIO_EVENT_CALLBACK_TIMELINE_BEAT            0x00001000
+STUDIO_EVENT_CALLBACK_SOUND_PLAYED             0x00002000
+STUDIO_EVENT_CALLBACK_SOUND_STOPPED            0x00004000
+STUDIO_EVENT_CALLBACK_REAL_TO_VIRTUAL          0x00008000
+STUDIO_EVENT_CALLBACK_VIRTUAL_TO_REAL          0x00010000
+STUDIO_EVENT_CALLBACK_START_EVENT_COMMAND      0x00020000
+STUDIO_EVENT_CALLBACK_NESTED_TIMELINE_BEAT     0x00040000
+STUDIO_EVENT_CALLBACK_ALL                      0xFFFFFFFF
+
+ +
+
FMOD_STUDIO_EVENT_CALLBACK_CREATED
+
Called when an instance is fully created. Parameters = unused.
+
FMOD_STUDIO_EVENT_CALLBACK_DESTROYED
+
Called when an instance is just about to be destroyed. Parameters = unused.
+
FMOD_STUDIO_EVENT_CALLBACK_STARTING
+
Studio::EventInstance::start has been called on an event which was not already playing. The event will remain in this state until its sample data has been loaded. Parameters = unused.
+
FMOD_STUDIO_EVENT_CALLBACK_STARTED
+
The event has commenced playing. Normally this callback will be issued immediately after FMOD_STUDIO_EVENT_CALLBACK_STARTING, but may be delayed until sample data has loaded. Parameters = unused.
+
FMOD_STUDIO_EVENT_CALLBACK_RESTARTED
+
Studio::EventInstance::start has been called on an event which was already playing. Parameters = unused.
+
FMOD_STUDIO_EVENT_CALLBACK_STOPPED
+
The event has stopped. Parameters = unused.
+
FMOD_STUDIO_EVENT_CALLBACK_START_FAILED
+
Studio::EventInstance::start has been called but the polyphony settings did not allow the event to start. In this case none of FMOD_STUDIO_EVENT_CALLBACK_STARTING, FMOD_STUDIO_EVENT_CALLBACK_STARTED and FMOD_STUDIO_EVENT_CALLBACK_STOPPED will be called. Parameters = unused.
+
FMOD_STUDIO_EVENT_CALLBACK_CREATE_PROGRAMMER_SOUND
+
A programmer sound is about to play. FMOD expects the callback to provide an FMOD::Sound object for it to use. Parameters = FMOD_STUDIO_PROGRAMMER_SOUND_PROPERTIES.
+
FMOD_STUDIO_EVENT_CALLBACK_DESTROY_PROGRAMMER_SOUND
+
A programmer sound has stopped playing. At this point it is safe to release the FMOD::Sound object that was used. Parameters = FMOD_STUDIO_PROGRAMMER_SOUND_PROPERTIES.
+
FMOD_STUDIO_EVENT_CALLBACK_PLUGIN_CREATED
+
Called when a DSP plug-in instance has just been created. Parameters = FMOD_STUDIO_PLUGIN_INSTANCE_PROPERTIES.
+
FMOD_STUDIO_EVENT_CALLBACK_PLUGIN_DESTROYED
+
Called when a DSP plug-in instance is about to be destroyed. Parameters = FMOD_STUDIO_PLUGIN_INSTANCE_PROPERTIES.
+
FMOD_STUDIO_EVENT_CALLBACK_TIMELINE_MARKER
+
Called when the timeline passes a named marker. Parameters = FMOD_STUDIO_TIMELINE_MARKER_PROPERTIES.
+
FMOD_STUDIO_EVENT_CALLBACK_TIMELINE_BEAT
+
Called when the timeline hits a beat in a tempo section. Parameters = FMOD_STUDIO_TIMELINE_BEAT_PROPERTIES.
+
FMOD_STUDIO_EVENT_CALLBACK_SOUND_PLAYED
+
Called when the event plays a sound. Parameters = Sound.
+
FMOD_STUDIO_EVENT_CALLBACK_SOUND_STOPPED
+
Called when the event finishes playing a sound. Parameters = Sound.
+
FMOD_STUDIO_EVENT_CALLBACK_REAL_TO_VIRTUAL
+
Called when the event becomes virtual. Parameters = unused.
+
FMOD_STUDIO_EVENT_CALLBACK_VIRTUAL_TO_REAL
+
Called when the event becomes real. Parameters = unused.
+
FMOD_STUDIO_EVENT_CALLBACK_START_EVENT_COMMAND
+
Called when a new event is started by a start event command. Parameters = Studio::EventInstance.
+
FMOD_STUDIO_EVENT_CALLBACK_NESTED_TIMELINE_BEAT
+
Called when the timeline hits a beat in a tempo section of a nested event. Parameters = FMOD_STUDIO_TIMELINE_NESTED_BEAT_PROPERTIES.
+
FMOD_STUDIO_EVENT_CALLBACK_ALL
+
Pass this mask to Studio::EventDescription::setCallback or Studio::EventInstance::setCallback to receive all callback types.
+
+

Callbacks are called from the Studio Update Thread in default / async mode and the main (calling) thread in synchronous mode.
+If using FMOD_STUDIO_INIT_DEFERRED_CALLBACKS, FMOD_STUDIO_EVENT_CALLBACK_TIMELINE_MARKER and FMOD_STUDIO_EVENT_CALLBACK_TIMELINE_BEAT are instead called from the main thread.

+

See Also: Callback Behavior, Studio::EventDescription::setCallback, Studio::EventInstance::setCallback, FMOD_STUDIO_EVENT_CALLBACK

+

FMOD_STUDIO_EVENT_PROPERTY

+

These definitions describe built-in event properties.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
typedef enum FMOD_STUDIO_EVENT_PROPERTY {
+  FMOD_STUDIO_EVENT_PROPERTY_CHANNELPRIORITY,
+  FMOD_STUDIO_EVENT_PROPERTY_SCHEDULE_DELAY,
+  FMOD_STUDIO_EVENT_PROPERTY_SCHEDULE_LOOKAHEAD,
+  FMOD_STUDIO_EVENT_PROPERTY_MINIMUM_DISTANCE,
+  FMOD_STUDIO_EVENT_PROPERTY_MAXIMUM_DISTANCE,
+  FMOD_STUDIO_EVENT_PROPERTY_COOLDOWN,
+  FMOD_STUDIO_EVENT_PROPERTY_MAX
+} FMOD_STUDIO_EVENT_PROPERTY;
+
+ +
enum Studio.EVENT_PROPERTY
+{
+    CHANNELPRIORITY,
+    SCHEDULE_DELAY,
+    SCHEDULE_LOOKAHEAD,
+    MINIMUM_DISTANCE,
+    MAXIMUM_DISTANCE,
+    COOLDOWN,
+    MAX
+};
+
+ +
STUDIO_EVENT_PROPERTY_CHANNELPRIORITY
+STUDIO_EVENT_PROPERTY_SCHEDULE_DELAY
+STUDIO_EVENT_PROPERTY_SCHEDULE_LOOKAHEAD
+STUDIO_EVENT_PROPERTY_MINIMUM_DISTANCE
+STUDIO_EVENT_PROPERTY_MAXIMUM_DISTANCE
+STUDIO_EVENT_PROPERTY_COOLDOWN
+STUDIO_EVENT_PROPERTY_MAX
+
+ +
+
FMOD_STUDIO_EVENT_PROPERTY_CHANNELPRIORITY
+
+

Priority to set on Core API Channels created by this event instance, 0 for most important, 256 for least important, and -1 for default.

+
    +
  • Range: [-1, 256]
  • +
  • Default: -1
  • +
+
+
FMOD_STUDIO_EVENT_PROPERTY_SCHEDULE_DELAY
+
+

Schedule delay in DSP clocks, or -1 for default.

+
    +
  • Range: -1, [0, inf)
  • +
  • Default: -1
  • +
+
+
FMOD_STUDIO_EVENT_PROPERTY_SCHEDULE_LOOKAHEAD
+
+

Schedule look-ahead on the timeline in DSP clocks, or -1 for default.

+
    +
  • Range: -1, [0, inf)
  • +
  • Default: -1
  • +
+
+
FMOD_STUDIO_EVENT_PROPERTY_MINIMUM_DISTANCE
+
+

Override the event's 3D minimum distance, or -1 for default.

+ +
+
FMOD_STUDIO_EVENT_PROPERTY_MAXIMUM_DISTANCE
+
+

Override the event's 3D maximum distance, or -1 for default.

+ +
+
FMOD_STUDIO_EVENT_PROPERTY_COOLDOWN
+
+

Override the event's cooldown, or -1 for default.

+
    +
  • Range: -1, [0, inf)
  • +
  • Default: -1
  • +
+
+
FMOD_STUDIO_EVENT_PROPERTY_MAX
+
Maximum number of event property types.
+
+

A property that returns a value of -1 from Studio::EventInstance::getProperty means it will use the values set in Studio, use Studio::EventInstance::setProperty to override these values. You can revert the properties value to default by setting it to -1.

+

FMOD_STUDIO_PLUGIN_INSTANCE_PROPERTIES

+

Describes a DSP plug-in instance.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
typedef struct FMOD_STUDIO_PLUGIN_INSTANCE_PROPERTIES {
+  const char   *name;
+  FMOD_DSP    *dsp;
+} FMOD_STUDIO_PLUGIN_INSTANCE_PROPERTIES;
+
+ +
struct Studio.PLUGIN_INSTANCE_PROPERTIES
+{
+    IntPtr name;
+    IntPtr dsp;
+}
+
+ +
FMOD_STUDIO_PLUGIN_INSTANCE_PROPERTIES
+{
+  name,
+};
+
+ +
+
name
+
Name of the plug-in effect or sound (set in FMOD Studio).
+
dsp
+
DSP plug-in instance. (DSP)
+
+

This data is passed to the event callback function when type is FMOD_STUDIO_EVENT_CALLBACK_PLUGIN_CREATED or FMOD_STUDIO_EVENT_CALLBACK_PLUGIN_DESTROYED.

+
+

The dsp argument can be cast to FMOD::DSP *.

+
+
+

The 'name' argument can be used via StringWrapper by using FMOD.StringWrapper dspName = new FMOD.StringWrapper(name);

+

The 'dsp' argument can be used via DSP by using FMOD.DSP dspInstance = new FMOD.DSP(dsp);

+
+

See Also: FMOD_STUDIO_EVENT_CALLBACK

+

FMOD_STUDIO_PROGRAMMER_SOUND_PROPERTIES

+

Describes a programmer sound.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
typedef struct FMOD_STUDIO_PROGRAMMER_SOUND_PROPERTIES {
+  const char   *name;
+  FMOD_SOUND   *sound;
+  int          subsoundIndex;
+} FMOD_STUDIO_PROGRAMMER_SOUND_PROPERTIES;
+
+ +
struct Studio.PROGRAMMER_SOUND_PROPERTIES
+{
+    StringWrapper name;
+    IntPtr sound;
+    int subsoundIndex;
+}
+
+ +
FMOD_STUDIO_PROGRAMMER_SOUND_PROPERTIES
+{
+  name,
+  sound,
+  subsoundIndex,
+};
+
+ +
+
name
+
Name of the programmer instrument (set in FMOD Studio). (UTF-8 string)
+
sound
+
Programmer-created sound. (Sound)
+
subsoundIndex
+
Subsound index.
+
+

This data is passed to the event callback function when type is FMOD_STUDIO_EVENT_CALLBACK_CREATE_PROGRAMMER_SOUND or FMOD_STUDIO_EVENT_CALLBACK_DESTROY_PROGRAMMER_SOUND.

+

When the callback type is FMOD_STUDIO_EVENT_CALLBACK_CREATE_PROGRAMMER_SOUND the callback should fill in the sound and subsoundIndex fields. The provided sound should be created with the FMOD_LOOP_NORMAL mode bit set. FMOD will set this bit internally if it is not set, possibly incurring a performance penalty. The subsound index should be set to the subsound to play, or -1 if the provided sound should be used directly.

+

When the callback type is FMOD_STUDIO_EVENT_CALLBACK_DESTROY_PROGRAMMER_SOUND the sound in sound should be cleaned up.

+
+

sound can be cast to/from FMOD::Sound *.

+
+

See Also: FMOD_STUDIO_EVENT_CALLBACK

+

FMOD_STUDIO_STOP_MODE

+

Stop modes.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
typedef enum FMOD_STUDIO_STOP_MODE {
+  FMOD_STUDIO_STOP_ALLOWFADEOUT,
+  FMOD_STUDIO_STOP_IMMEDIATE
+} FMOD_STUDIO_STOP_MODE;
+
+ +
enum Studio.STOP_MODE
+{
+    ALLOWFADEOUT,
+    IMMEDIATE,
+}
+
+ +
STUDIO_STOP_ALLOWFADEOUT
+STUDIO_STOP_IMMEDIATE
+
+ +
+
FMOD_STUDIO_STOP_ALLOWFADEOUT
+
Allows AHDSR modulators to complete their release, and DSP effect tails to play out.
+
FMOD_STUDIO_STOP_IMMEDIATE
+
Stops the event instance immediately.
+
+

See Also: Studio::EventInstance::stop, Studio::Bus::stopAllEvents

+

FMOD_STUDIO_TIMELINE_BEAT_PROPERTIES

+

Describes a beat on the timeline.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
typedef struct FMOD_STUDIO_TIMELINE_BEAT_PROPERTIES {
+  int     bar;
+  int     beat;
+  int     position;
+  float   tempo;
+  int     timesignatureupper;
+  int     timesignaturelower;
+} FMOD_STUDIO_TIMELINE_BEAT_PROPERTIES;
+
+ +
struct Studio.TIMELINE_BEAT_PROPERTIES
+{
+  int bar;
+  int beat;
+  int position;
+  float tempo;
+  int timesignatureupper;
+  int timesignaturelower;
+}
+
+ +
FMOD_STUDIO_TIMELINE_BEAT_PROPERTIES
+{
+  bar,
+  beat,
+  position,
+  tempo,
+  timesignatureupper,
+  timesignaturelower,
+};
+
+ +
+
bar
+
Bar number (starting from 1).
+
beat
+
Beat number within bar (starting from 1).
+
position
+
Position of the beat on the timeline in milliseconds.
+
tempo
+
Current tempo in beats per minute.
+
timesignatureupper
+
Current time signature upper number (beats per bar).
+
timesignaturelower
+
Current time signature lower number (beat unit).
+
+

This data is passed to the event callback function when type is FMOD_STUDIO_EVENT_CALLBACK_TIMELINE_BEAT.

+

Nested events do not trigger this callback. Instead, see FMOD_STUDIO_EVENT_CALLBACK_NESTED_TIMELINE_BEAT.

+

See Also: FMOD_STUDIO_EVENT_CALLBACK

+

FMOD_STUDIO_TIMELINE_MARKER_PROPERTIES

+

Describes a marker on the timeline.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
typedef struct FMOD_STUDIO_TIMELINE_MARKER_PROPERTIES {
+  const char   *name;
+  int          position;
+} FMOD_STUDIO_TIMELINE_MARKER_PROPERTIES;
+
+ +
struct Studio.TIMELINE_MARKER_PROPERTIES
+{
+  IntPtr name;
+  int position;
+}
+
+ +
FMOD_STUDIO_TIMELINE_MARKER_PROPERTIES
+{
+  name,
+  position,
+};
+
+ +
+
name
+
Marker name.
+
position
+
Position of the marker on the timeline in milliseconds.
+
+

This data is passed to the event callback function when type is FMOD_STUDIO_EVENT_CALLBACK_TIMELINE_MARKER.

+

See Also: Studio::EventDescription::setCallback, Studio::EventInstance::setCallback

+

FMOD_STUDIO_TIMELINE_NESTED_BEAT_PROPERTIES

+

Describes a beat on the timeline from a nested event.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
typedef struct FMOD_STUDIO_TIMELINE_NESTED_BEAT_PROPERTIES {
+  FMOD_GUID                             eventid;
+  FMOD_STUDIO_TIMELINE_BEAT_PROPERTIES  properties;
+} FMOD_STUDIO_TIMELINE_NESTED_BEAT_PROPERTIES;
+
+ +
struct Studio.TIMELINE_NESTED_BEAT_PROPERTIES
+{
+  Guid                      eventid;
+  TIMELINE_BEAT_PROPERTIES  properties;
+}
+
+ +
FMOD_STUDIO_TIMELINE_NESTED_BEAT_PROPERTIES
+{
+  eventid,
+  properties,
+};
+
+ +
+
eventid
+
Event description GUID. (FMOD_GUID)
+
properties
+
Beat properties. (FMOD_STUDIO_TIMELINE_BEAT_PROPERTIES)
+
+

This data is passed to the event callback function when type is FMOD_STUDIO_EVENT_CALLBACK_NESTED_TIMELINE_BEAT.

+

See Also: FMOD_STUDIO_EVENT_CALLBACK, FMOD_STUDIO_EVENT_CALLBACK_TIMELINE_BEAT

+ + +
+ + + diff --git a/FMOD/doc/FMOD API User Manual/studio-api-getting-started.html b/FMOD/doc/FMOD API User Manual/studio-api-getting-started.html new file mode 100644 index 0000000..71219f9 --- /dev/null +++ b/FMOD/doc/FMOD API User Manual/studio-api-getting-started.html @@ -0,0 +1,89 @@ + + +Studio API Getting Started + + + + +
+ +
+

12. Studio API Getting Started

+

The Studio API is designed to be intuitive and flexible. This chapter contains an introduction to using it, and explains the key factors involved in using it effectively.

+

12.1 Initialization

+

Before anything else can be done with the Studio API, it is necessary to initialize the studio system.

+

12.1.1 Studio API Initialization

+

The Studio API can load FMOD Studio banks and can play events created by sound designers in FMOD Studio. When using the Studio API, you can create a studio system and then call Studio::System::initialize. That function also initializes the in-built core system as well. Here is a simple example:

+
FMOD_RESULT result;
+FMOD::Studio::System* system = NULL;
+
+result = FMOD::Studio::System::create(&system); // Create the Studio System object.
+if (result != FMOD_OK)
+{
+    printf("FMOD error! (%d) %s\n", result, FMOD_ErrorString(result));
+    exit(-1);
+}
+
+// Initialize the Studio system, which also initializes the Core system
+result = system->initialize(512, FMOD_STUDIO_INIT_NORMAL, FMOD_INIT_NORMAL, 0);
+if (result != FMOD_OK)
+{
+    printf("FMOD error! (%d) %s\n", result, FMOD_ErrorString(result));
+    exit(-1);
+}
+
+ +

12.1.2 Advanced Initialization Settings

+

The FMOD Engine can be customized with advanced settings by calling Studio::System::setAdvancedSettings before initialization. For a description of the typical settings for effective virtual voices, see the Virtual Voice System section of the Managing Resources in the Core API chapter.

+

12.2 Update

+

The FMOD Engine should be ticked once per game update. To tick the FMOD Engine while using the Studio API, call Studio::System::update. Internally, this also updates the Core API system.

+

If the Studio API is running in asynchronous mode (the default, unless FMOD_STUDIO_INIT_SYNCHRONOUS_UPDATE has been specified), then Studio::System::update will be extremely quick, as it is merely swapping a buffer for the asynchronous execution of that frame's commands.

+

12.3 Shut Down

+

To shut down the Studio API, call Studio::System::release.

+

12.4 Error Checking

+

In the FMOD examples, the error codes are checked with a macro that calls into a handling function if an unexpected error occurs. That is the recommended way of calling Studio API functions. There is also a callback that can be received whenever a public FMOD function has an error. See FMOD_SYSTEM_CALLBACK for more information.

+

12.5 Configuration

+

The output hardware, the FMOD Engine's resource usage, and other types of configuration options can be set if you desire behavior differing from the default. These are generally called before System::init. For examples of these, see Studio::System::getCoreSystem, System::setAdvancedSettings, Studio::System::setAdvancedSettings.

+ + +
+ + + diff --git a/FMOD/doc/FMOD API User Manual/studio-api-system.html b/FMOD/doc/FMOD API User Manual/studio-api-system.html new file mode 100644 index 0000000..7ed18b6 --- /dev/null +++ b/FMOD/doc/FMOD API User Manual/studio-api-system.html @@ -0,0 +1,3350 @@ + + +Studio API Reference | Studio::System + + + + +
+ +
+

16. Studio API Reference | Studio::System

+

The main system object for FMOD Studio.

+

Initializing the studio system object also initializes the core System object.

+

Lifetime:

+ +
+ +

Update:

+ +

Banks:

+ +
+ +
+ +

Listeners:

+ +

Buses:

+ +

Events:

+ +

Parameters:

+ +

VCAs:

+ +

Advanced settings:

+ +
+ +

Command capture and replay:

+ +
+ +

Profiling:

+ +
+ +

Plug-ins:

+ +

System callback:

+ +
+ +

Sound table:

+ +
+ +

General:

+ +

FMOD_STUDIO_ADVANCEDSETTINGS

+

Settings for advanced features like configuring memory and cpu usage.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
typedef struct FMOD_STUDIO_ADVANCEDSETTINGS {
+  int            cbsize;
+  unsigned int   commandqueuesize;
+  unsigned int   handleinitialsize;
+  int            studioupdateperiod;
+  int            idlesampledatapoolsize;
+  unsigned int   streamingscheduledelay;
+  const char*    encryptionkey;
+} FMOD_STUDIO_ADVANCEDSETTINGS;
+
+ +
struct Studio.ADVANCEDSETTINGS
+{
+  int cbsize;
+  int commandqueuesize;
+  int handleinitialsize;
+  int studioupdateperiod;
+  int idlesampledatapoolsize;
+  int streamingscheduledelay;
+  StringWrapper encryptionkey;
+}
+
+ +
FMOD_STUDIO_ADVANCEDSETTINGS
+{
+  commandqueuesize,
+  handleinitialsize,
+  studioupdateperiod,
+  idlesampledatapoolsize,
+  streamingscheduledelay;
+};
+
+ +
+
cbsize
+
Size of this structure in bytes. Must be set to sizeof(FMOD_STUDIO_ADVANCEDSETTINGS) before calling Studio::System::setAdvancedSettings or Studio::System::getAdvancedSettings.
+
commandqueuesize
+
+

Command queue size for studio async processing.

+
    +
  • Units: Bytes
  • +
  • Default: 32768
  • +
+
+
handleinitialsize
+
+

Initial size to allocate for handles. Memory for handles will grow as needed in pages.

+
    +
  • Units: Bytes
  • +
  • Default: 8192 * sizeof(void*)
  • +
+
+
studioupdateperiod
+
+

Update period of Studio when in async mode, in milliseconds. Will be quantized to the nearest multiple of mixer duration.

+
    +
  • Units: Milliseconds
  • +
  • Default: 20
  • +
+
+
idlesampledatapoolsize
+
+

Size in bytes of sample data to retain in memory when no longer used, to avoid repeated disk I/O. Use -1 to disable.

+
    +
  • Units: Bytes
  • +
  • Default: 262144
  • +
+
+
streamingscheduledelay
+
+

Specify the schedule delay for streams, in samples. Lower values can reduce latency when scheduling events containing streams but may cause scheduling issues if too small.

+
    +
  • Units: Samples
  • +
  • Default: 8192
  • +
+
+
encryptionkey
+
Specify the key for loading sounds from encrypted banks. (UTF-8 string)
+
+

When calling Studio::System::setAdvancedSettings any member other than cbsize may be set to zero to use the default value for that setting.

+

FMOD_STUDIO_BANK_INFO

+

Information for loading a bank using user callbacks.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
typedef struct FMOD_STUDIO_BANK_INFO {
+  int                        size;
+  void                      *userdata;
+  int                        userdatalength;
+  FMOD_FILE_OPEN_CALLBACK    opencallback;
+  FMOD_FILE_CLOSE_CALLBACK   closecallback;
+  FMOD_FILE_READ_CALLBACK    readcallback;
+  FMOD_FILE_SEEK_CALLBACK    seekcallback;
+} FMOD_STUDIO_BANK_INFO;
+
+ +
struct Studio.BANK_INFO
+{
+  int size;
+  IntPtr userdata;
+  int userdatalength;
+  FILE_OPENCALLBACK opencallback;
+  FILE_CLOSECALLBACK closecallback;
+  FILE_READCALLBACK readcallback;
+  FILE_SEEKCALLBACK seekcallback;
+}
+
+ +
FMOD_STUDIO_BANK_INFO
+{
+  userdata,
+  userdatalength,
+  opencallback,
+  closecallback,
+  readcallback,
+  seekcallback,
+};
+
+ +
+
size
+
Size of this structure in bytes. Must be set to sizeof(FMOD_STUDIO_BANK_INFO).
+
userdata Opt
+
User data to be passed to the file callbacks. If userdatalength is zero, this must remain valid until the bank has been unloaded and all calls to opencallback have been matched by a call to closecallback.
+
userdatalength
+
Length of user data in bytes. If non-zero the userdata will be copied internally; this copy will be kept until the bank has been unloaded and all calls to opencallback have been matched by a call to closecallback.
+
opencallback
+
Callback for opening the bank file. (FMOD_FILE_OPEN_CALLBACK)
+
closecallback
+
Callback for closing the bank file. (FMOD_FILE_CLOSE_CALLBACK)
+
readcallback
+
Callback for reading from the bank file. (FMOD_FILE_READ_CALLBACK)
+
seekcallback
+
Callback for seeking within the bank file. (FMOD_FILE_SEEK_CALLBACK)
+
+

See Also: Studio::System::loadBankCustom

+

FMOD_STUDIO_BUFFER_INFO

+

Information for a single buffer in FMOD Studio.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
typedef struct FMOD_STUDIO_BUFFER_INFO {
+  int     currentusage;
+  int     peakusage;
+  int     capacity;
+  int     stallcount;
+  float   stalltime;
+} FMOD_STUDIO_BUFFER_INFO;
+
+ +
struct Studio.BUFFER_INFO
+{
+    int currentusage;
+    int peakusage;
+    int capacity;
+    int stallcount;
+    float stalltime;
+}
+
+ +
FMOD_STUDIO_BUFFER_INFO
+{
+  currentusage,
+  peakusage,
+  capacity,
+  stallcount,
+  stalltime,
+};
+
+ +
+
currentusage
+
Current buffer usage in bytes.
+
peakusage
+
Peak buffer usage in bytes.
+
capacity
+
Buffer capacity in bytes.
+
stallcount
+
Cumulative number of stalls due to buffer overflow.
+
stalltime
+
Cumulative amount of time stalled due to buffer overflow, in seconds.
+
+

See Also: FMOD_STUDIO_BUFFER_USAGE

+

FMOD_STUDIO_BUFFER_USAGE

+

Information for FMOD Studio buffer usage.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
typedef struct FMOD_STUDIO_BUFFER_USAGE {
+  FMOD_STUDIO_BUFFER_INFO   studiocommandqueue;
+  FMOD_STUDIO_BUFFER_INFO   studiohandle;
+} FMOD_STUDIO_BUFFER_USAGE;
+
+ +
struct Studio.BUFFER_USAGE
+{
+  BUFFER_INFO studiocommandqueue;
+  BUFFER_INFO studiohandle;
+}
+
+ +
FMOD_STUDIO_BUFFER_USAGE
+{
+  studiocommandqueue,
+  studiohandle,
+};
+
+ +
+
studiocommandqueue
+
Information for the Studio Async Command buffer. (FMOD_STUDIO_BUFFER_INFO)
+
studiohandle
+
Information for the Studio handle table. (FMOD_STUDIO_BUFFER_INFO)
+
+

See Also: Studio::System::getBufferUsage

+

FMOD_STUDIO_COMMANDCAPTURE_FLAGS

+

Flags controling command capture.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
#define FMOD_STUDIO_COMMANDCAPTURE_NORMAL             0x00000000
+#define FMOD_STUDIO_COMMANDCAPTURE_FILEFLUSH          0x00000001
+#define FMOD_STUDIO_COMMANDCAPTURE_SKIP_INITIAL_STATE 0x00000002
+
+ +
enum Studio.COMMANDCAPTURE_FLAGS : uint
+{
+    NORMAL             = 0x00000000,
+    FILEFLUSH          = 0x00000001,
+    SKIP_INITIAL_STATE = 0x00000002,
+}
+
+ +
STUDIO_COMMANDCAPTURE_NORMAL             0x00000000
+STUDIO_COMMANDCAPTURE_FILEFLUSH          0x00000001
+STUDIO_COMMANDCAPTURE_SKIP_INITIAL_STATE 0x00000002
+
+ +
+
FMOD_STUDIO_COMMANDCAPTURE_NORMAL
+
Use default options.
+
FMOD_STUDIO_COMMANDCAPTURE_FILEFLUSH
+
Call file flush on every command.
+
FMOD_STUDIO_COMMANDCAPTURE_SKIP_INITIAL_STATE
+
The initial state of banks and instances is captured, unless this flag is set.
+
+

See Also: Studio::System::startCommandCapture

+

FMOD_STUDIO_COMMANDREPLAY_FLAGS

+

Flags controlling command replay.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
#define FMOD_STUDIO_COMMANDREPLAY_NORMAL         0x00000000
+#define FMOD_STUDIO_COMMANDREPLAY_SKIP_CLEANUP   0x00000001
+#define FMOD_STUDIO_COMMANDREPLAY_FAST_FORWARD   0x00000002
+#define FMOD_STUDIO_COMMANDREPLAY_SKIP_BANK_LOAD 0x00000004
+
+ +
enum Studio.COMMANDREPLAY_FLAGS : uint
+{
+  NORMAL         = 0x00000000,
+  SKIP_CLEANUP   = 0x00000001,
+  FAST_FORWARD   = 0x00000002,
+  SKIP_BANK_LOAD = 0x00000004,
+}
+
+ +
STUDIO_COMMANDREPLAY_NORMAL         0x00000000
+STUDIO_COMMANDREPLAY_SKIP_CLEANUP   0x00000001
+STUDIO_COMMANDREPLAY_FAST_FORWARD   0x00000002
+STUDIO_COMMANDREPLAY_SKIP_BANK_LOAD 0x00000004
+
+ +
+
FMOD_STUDIO_COMMANDREPLAY_NORMAL
+
Use default options.
+
FMOD_STUDIO_COMMANDREPLAY_SKIP_CLEANUP
+
Do not free resources at the end of playback.
+
FMOD_STUDIO_COMMANDREPLAY_FAST_FORWARD
+
Play back at maximum speed, ignoring the timing of the original replay.
+
FMOD_STUDIO_COMMANDREPLAY_SKIP_BANK_LOAD
+
Skip commands related to bank loading.
+
+

See Also: Studio::System::loadCommandReplay

+

FMOD_STUDIO_CPU_USAGE

+

Performance information for Studio API functionality.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
typedef struct FMOD_STUDIO_CPU_USAGE {
+  float   update;
+} FMOD_STUDIO_CPU_USAGE;
+
+ +
struct Studio.CPU_USAGE
+{
+    float update;
+}
+
+ +
FMOD_STUDIO_CPU_USAGE
+{
+  update
+};
+
+ +
+
update
+
+

Studio::System::update CPU usage. Percentage of main thread, or main thread if FMOD_STUDIO_INIT_SYNCHRONOUS_UPDATE flag is used with Studio::System::initialize.

+
    +
  • Units: Percent
  • +
  • Range: [0, 100]
  • +
+
+
+

This structure is filled in with Studio::System::getCPUUsage.

+

See Also: System::getCPUUsage, FMOD_CPU_USAGE

+

FMOD_STUDIO_INITFLAGS

+

Studio System initialization flags.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
#define FMOD_STUDIO_INIT_NORMAL                0x00000000
+#define FMOD_STUDIO_INIT_LIVEUPDATE            0x00000001
+#define FMOD_STUDIO_INIT_ALLOW_MISSING_PLUGINS 0x00000002
+#define FMOD_STUDIO_INIT_SYNCHRONOUS_UPDATE    0x00000004
+#define FMOD_STUDIO_INIT_DEFERRED_CALLBACKS    0x00000008
+#define FMOD_STUDIO_INIT_LOAD_FROM_UPDATE      0x00000010
+#define FMOD_STUDIO_INIT_MEMORY_TRACKING       0x00000020
+
+ +
enum Studio.INITFLAGS : uint
+{
+    NORMAL                = 0x00000000
+    LIVEUPDATE            = 0x00000001
+    ALLOW_MISSING_PLUGINS = 0x00000002
+    SYNCHRONOUS_UPDATE    = 0x00000004
+    DEFERRED_CALLBACKS    = 0x00000008
+    LOAD_FROM_UPDATE      = 0x00000010
+    MEMORY_TRACKING       = 0x00000020
+}
+
+ +
STUDIO_INIT_NORMAL                0x00000000
+STUDIO_INIT_LIVEUPDATE            0x00000001
+STUDIO_INIT_ALLOW_MISSING_PLUGINS 0x00000002
+STUDIO_INIT_SYNCHRONOUS_UPDATE    0x00000004
+STUDIO_INIT_DEFERRED_CALLBACKS    0x00000008
+STUDIO_INIT_LOAD_FROM_UPDATE      0x00000010
+STUDIO_INIT_MEMORY_TRACKING       0x00000020
+
+ +
+
FMOD_STUDIO_INIT_NORMAL
+
Use defaults for all initialization options.
+
FMOD_STUDIO_INIT_LIVEUPDATE
+
Enable live update.
+
FMOD_STUDIO_INIT_ALLOW_MISSING_PLUGINS
+
Load banks even if they reference plug-ins that have not been loaded.
+
FMOD_STUDIO_INIT_SYNCHRONOUS_UPDATE
+
Disable asynchronous processing and perform all processing on the calling thread instead.
+
FMOD_STUDIO_INIT_DEFERRED_CALLBACKS
+
Defer timeline callbacks until the main update. See Studio::EventInstance::setCallback for more information.
+
FMOD_STUDIO_INIT_LOAD_FROM_UPDATE
+
No additional threads are created for bank and resource loading. Loading is driven from Studio::System::update.
+
FMOD_STUDIO_INIT_MEMORY_TRACKING
+
Enables detailed memory usage statistics. Increases memory footprint and impacts performance. See Studio::Bus::getMemoryUsage and Studio::EventInstance::getMemoryUsage for more information. Implies FMOD_INIT_MEMORY_TRACKING.
+
+

See Also: Studio::System::initialize

+

FMOD_STUDIO_LOAD_BANK_FLAGS

+

Flags for controlling bank loading.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
#define FMOD_STUDIO_LOAD_BANK_NORMAL             0x00000000
+#define FMOD_STUDIO_LOAD_BANK_NONBLOCKING        0x00000001
+#define FMOD_STUDIO_LOAD_BANK_DECOMPRESS_SAMPLES 0x00000002
+#define FMOD_STUDIO_LOAD_BANK_UNENCRYPTED        0x00000004
+
+ +
enum Studio.LOAD_BANK_FLAGS : uint
+{
+    NORMAL             = 0x00000000,
+    NONBLOCKING        = 0x00000001,
+    DECOMPRESS_SAMPLES = 0x00000002,
+    UNENCRYPTED        = 0x00000004,
+}
+
+ +
STUDIO_LOAD_BANK_NORMAL             0x00000000
+STUDIO_LOAD_BANK_NONBLOCKING        0x00000001
+STUDIO_LOAD_BANK_DECOMPRESS_SAMPLES 0x00000002
+STUDIO_LOAD_BANK_UNENCRYPTED        0x00000004
+
+ +
+
FMOD_STUDIO_LOAD_BANK_NORMAL
+
Standard behavior.
+
FMOD_STUDIO_LOAD_BANK_NONBLOCKING
+
Bank loading occurs asynchronously rather than occurring immediately.
+
FMOD_STUDIO_LOAD_BANK_DECOMPRESS_SAMPLES
+
Force samples to decompress into memory when they are loaded, rather than staying compressed.
+
FMOD_STUDIO_LOAD_BANK_UNENCRYPTED
+
Ignore the encryption key specified by Studio::System::setAdvancedSettings when loading sounds from this bank (assume the sounds in the bank are not encrypted).
+
+

See Also: Studio::System::loadBankFile, Studio::System::loadBankMemory, Studio::System::loadBankCustom

+

FMOD_STUDIO_LOAD_MEMORY_ALIGNMENT

+

The required memory alignment of banks in user memory.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
#define FMOD_STUDIO_LOAD_MEMORY_ALIGNMENT   32
+
+ +
+

Not supported for C#.

+
+
+

Not supported for JavaScript.

+
+

See Also: Studio::System::loadBankMemory

+

FMOD_STUDIO_LOAD_MEMORY_MODE

+

Specifies how to use the memory buffer passed to Studio::System::loadBankMemory.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
typedef enum FMOD_STUDIO_LOAD_MEMORY_MODE {
+  FMOD_STUDIO_LOAD_MEMORY,
+  FMOD_STUDIO_LOAD_MEMORY_POINT
+} FMOD_STUDIO_LOAD_MEMORY_MODE;
+
+ +
+

Not supported for C#.

+
+
STUDIO_LOAD_MEMORY       0
+STUDIO_LOAD_MEMORY_POINT 1
+
+ +
+
FMOD_STUDIO_LOAD_MEMORY
+
Memory buffer is copied internally.
+
FMOD_STUDIO_LOAD_MEMORY_POINT
+
Memory buffer is used directly in user memory.
+
+
+

It is not currently possible for the FMOD Engine to use banks loaded into user memory. Only FMOD.STUDIO_LOAD_MEMORY is supported.

+
+

See Also: Studio::System::loadBankMemory

+

FMOD_STUDIO_SOUND_INFO

+

Describes a sound in the audio table.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
typedef struct FMOD_STUDIO_SOUND_INFO {
+  const char              *name_or_data;
+  FMOD_MODE                mode;
+  FMOD_CREATESOUNDEXINFO   exinfo;
+  int                      subsoundindex;
+} FMOD_STUDIO_SOUND_INFO;
+
+ +
class Studio.SOUND_INFO
+{
+  byte[] name_or_data;
+  MODE mode;
+  CREATESOUNDEXINFO exinfo;
+  int subsoundindex;
+  string name { get; }
+}
+
+ +
FMOD_STUDIO_SOUND_INFO
+{
+  name_or_data,
+  mode,
+  exinfo,
+  subsoundindex,
+};
+
+ +
+
name_or_data
+
The filename (UTF-8 string) or memory buffer that contains the sound.
+
mode
+
+

Mode flags required for loading the sound. (FMOD_MODE)

+ +
+
exinfo
+
Extra information required for loading the sound. (FMOD_CREATESOUNDEXINFO)
+
subsoundindex
+
Subsound index for loading the sound.
+
+
+

The name property is a getter for the name_or_data member which will return null if the sound should be loaded from memory.

+
+

See Also: Studio::System::getSoundInfo

+

FMOD_STUDIO_SYSTEM_CALLBACK

+

Callback for Studio system events.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
FMOD_RESULT F_CALL FMOD_STUDIO_SYSTEM_CALLBACK(
+  FMOD_STUDIO_SYSTEM *system,
+  FMOD_STUDIO_SYSTEM_CALLBACK_TYPE type,
+  void *commanddata,
+  void *userdata
+);
+
+ +
delegate RESULT Studio.SYSTEM_CALLBACK(
+  IntPtr system,
+  SYSTEM_CALLBACK_TYPE type,
+  IntPtr commanddata,
+  IntPtr userdata
+);
+
+ +
function FMOD_STUDIO_SYSTEM_CALLBACK(
+  system,
+  type,
+  commanddata,
+  userdata
+)
+
+ +
+
system
+
Studio system. (Studio::System)
+
type
+
Callback type. (FMOD_STUDIO_SYSTEM_CALLBACK_TYPE)
+
commanddata
+
Data specific to callback type.
+
userdata
+
User data set with Studio::System::setUserData.
+
+
+

system can be cast to Studio::System *.

+
+

See Also: Callback Behavior, User Data

+

FMOD_STUDIO_SYSTEM_CALLBACK_TYPE

+

Callback types for the Studio System callback.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
#define FMOD_STUDIO_SYSTEM_CALLBACK_PREUPDATE               0x00000001
+#define FMOD_STUDIO_SYSTEM_CALLBACK_POSTUPDATE              0x00000002
+#define FMOD_STUDIO_SYSTEM_CALLBACK_BANK_UNLOAD             0x00000004
+#define FMOD_STUDIO_SYSTEM_CALLBACK_LIVEUPDATE_CONNECTED    0x00000008
+#define FMOD_STUDIO_SYSTEM_CALLBACK_LIVEUPDATE_DISCONNECTED 0x00000010
+#define FMOD_STUDIO_SYSTEM_CALLBACK_ALL                     0xFFFFFFFF
+
+ +
enum Studio.SYSTEM_CALLBACK_TYPE : uint
+{
+    PREUPDATE               = 0x00000001,
+    POSTUPDATE              = 0x00000002,
+    BANK_UNLOAD             = 0x00000004,
+    LIVEUPDATE_CONNECTED    = 0x00000008,
+    LIVEUPDATE_DISCONNECTED = 0x00000010,
+    ALL                     = 0xFFFFFFFF,
+}
+
+ +
STUDIO_SYSTEM_CALLBACK_PREUPDATE                0x00000001
+STUDIO_SYSTEM_CALLBACK_POSTUPDATE               0x00000002
+STUDIO_SYSTEM_CALLBACK_BANK_UNLOAD              0x00000004
+STUDIO_SYSTEM_CALLBACK_LIVEUPDATE_CONNECTED     0x00000008
+STUDIO_SYSTEM_CALLBACK_LIVEUPDATE_DISCONNECTED  0x00000010
+STUDIO_SYSTEM_CALLBACK_ALL                      0xFFFFFFFF
+
+ +
+
FMOD_STUDIO_SYSTEM_CALLBACK_PREUPDATE
+
Called at the start of the main Studio update. For async mode this will be on its own thread.
+
FMOD_STUDIO_SYSTEM_CALLBACK_POSTUPDATE
+
Called at the end of the main Studio update. For async mode this will be on its own thread.
+
FMOD_STUDIO_SYSTEM_CALLBACK_BANK_UNLOAD
+
Called directly when a bank has just been unloaded, after all resources are freed. The commanddata argument is the bank handle.
+
FMOD_STUDIO_SYSTEM_CALLBACK_ALL
+
Pass this mask to Studio::System::setCallback to receive all callback types.
+
FMOD_STUDIO_SYSTEM_CALLBACK_LIVEUPDATE_CONNECTED
+
Called after a live update connection has been established.
+
FMOD_STUDIO_SYSTEM_CALLBACK_LIVEUPDATE_DISCONNECTED
+
Called after live update session disconnects.
+
+

Callbacks are called from the Studio Update Thread in default / async mode and the main (calling) thread in synchronous mode.

+

See Also: Callback Behavior, FMOD_STUDIO_SYSTEM_CALLBACK, Studio::System::setCallback

+

Studio::System::create

+

This function creates the studio system.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
static FMOD_RESULT Studio::System::create(
+  Studio::System **system,
+  unsigned int headerversion = FMOD_VERSION
+);
+
+ +
FMOD_RESULT FMOD_Studio_System_Create(
+  FMOD_STUDIO_SYSTEM **system,
+  unsigned int headerversion
+);
+
+ +
static RESULT Studio.System.create(
+  out System system
+);
+
+ +
static Studio_System_Create(
+  system
+);
+
+ +
+
system Out
+
Studio System object. (Studio::System)
+
headerversion
+
Expected Studio API version.
+
+

Pass FMOD_VERSION in headerversion to ensure the library and header versions being used match.

+

Call Studio::System::release to free the Studio System.

+

Studio::System::create and Studio::System::release are not thread-safe. Calling either of these functions concurrently with any Studio API function (including these two functions) may cause undefined behavior. External synchronization must be used if calls to Studio::System::create or Studio::System::release could overlap other Studio API calls. All other Studio API functions are thread safe and may be called freely from any thread unless otherwise documented.

+

See Also: Creating the Studio System

+

Studio::System::flushCommands

+

Block until all pending commands have been executed.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
FMOD_RESULT Studio::System::flushCommands();
+
+ +
FMOD_RESULT FMOD_Studio_System_FlushCommands(FMOD_STUDIO_SYSTEM *system);
+
+ +
RESULT Studio.System.flushCommands();
+
+ +
Studio.System.flushCommands();
+
+ +

This function blocks the calling thread until all pending commands have been executed and all non-blocking bank loads have been completed.

+

This is equivalent to calling Studio::System::update and then sleeping until the asynchronous thread has finished executing all pending commands.

+

See Also: Studio::System::initialize, Studio::System::update, Studio::System::flushSampleLoading

+

Studio::System::flushSampleLoading

+

Block until all sample loading and unloading has completed.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
FMOD_RESULT Studio::System::flushSampleLoading();
+
+ +
FMOD_RESULT FMOD_Studio_System_FlushSampleLoading(FMOD_STUDIO_SYSTEM *system);
+
+ +
RESULT Studio.System.flushSampleLoading();
+
+ +
Studio.System.flushSampleLoading();
+
+ +
+

This function may stall for a long time if other threads are continuing to issue calls to load and unload sample data, e.g. by creating new event instances.

+
+

See Also: Studio::System::flushCommands, Sample Data Loading

+

Studio::System::getAdvancedSettings

+

Retrieves advanced settings.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
FMOD_RESULT Studio::System::getAdvancedSettings(
+  FMOD_STUDIO_ADVANCEDSETTINGS *settings
+);
+
+ +
FMOD_RESULT FMOD_Studio_System_GetAdvancedSettings(
+  FMOD_STUDIO_SYSTEM *system,
+  FMOD_STUDIO_ADVANCEDSETTINGS *settings
+);
+
+ +
RESULT Studio.System.getAdvancedSettings(
+  out ADVANCEDSETTINGS settings
+);
+
+ +
Studio.System.getAdvancedSettings(
+  settings
+);
+
+ +
+
settings Out
+
Studio System advanced settings. (FMOD_STUDIO_ADVANCEDSETTINGS)
+
+

See Also: Studio::System::setAdvancedSettings

+

Studio::System::getBank

+

Retrieves a loaded bank with the specified file path.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
FMOD_RESULT Studio::System::getBank(
+  const char *path,
+  Studio::Bank **bank
+);
+
+ +
FMOD_RESULT FMOD_Studio_System_GetBank(
+  FMOD_STUDIO_SYSTEM *system,
+  const char *path,
+  FMOD_STUDIO_BANK **bank
+);
+
+ +
RESULT Studio.System.getBank(
+  string path,
+  out Bank bank
+);
+
+ +
Studio.System.getBank(
+  path,
+  bank
+);
+
+ +
+
path
+
The bank path or the ID string that identifies the bank. (UTF-8 string)
+
bank Out
+
Bank object. (Studio::Bank)
+
+

path may be a path, such as bank:/Weapons or an ID string such as {793cddb6-7fa1-4e06-b805-4c74c0fd625b}.

+

Note that path lookups will only succeed if the strings bank has been loaded.

+

See Also: Studio::System::getBankByID

+

Studio::System::getBankByID

+

Retrieves a loaded bank with the specified ID.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
FMOD_RESULT Studio::System::getBankByID(
+  const FMOD_GUID *id,
+  Studio::Bank **bank
+);
+
+ +
FMOD_RESULT FMOD_Studio_System_GetBankByID(
+  FMOD_STUDIO_SYSTEM *system,
+  const FMOD_GUID *id,
+  FMOD_STUDIO_BANK **bank
+);
+
+ +
RESULT Studio.System.getBankByID(
+  Guid id,
+  out Bank bank
+);
+
+ +
Studio.System.getBankByID(
+  id,
+  bank
+);
+
+ +
+
id
+
Bank GUID. (FMOD_GUID)
+
bank Out
+
Bank object. (Studio::Bank)
+
+

See Also: Studio::parseID, Studio::System::lookupID, Studio::System::getBank

+

Studio::System::getBankCount

+

Retrieves the number of currently-loaded banks.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
FMOD_RESULT Studio::System::getBankCount(
+  int *count
+);
+
+ +
FMOD_RESULT FMOD_Studio_System_GetBankCount(
+  FMOD_STUDIO_SYSTEM *system,
+  int *count
+);
+
+ +
RESULT Studio.System.getBankCount(
+  out int count
+);
+
+ +
Studio.System.getBankCount(
+  count
+);
+
+ +
+
count Out
+
Number of loaded banks.
+
+

May be used in conjunction with Studio::System::getBankList to enumerate the loaded banks.

+

Studio::System::getBankList

+

Retrieves a list of the currently-loaded banks.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
FMOD_RESULT Studio::System::getBankList(
+  Studio::Bank **array,
+  int capacity,
+  int *count
+);
+
+ +
FMOD_RESULT FMOD_Studio_System_GetBankList(
+  FMOD_STUDIO_SYSTEM *system,
+  FMOD_STUDIO_BANK **array,
+  int capacity,
+  int *count
+);
+
+ +
RESULT Studio.System.getBankList(
+  out Bank[] array
+);
+
+ +
Studio.System.getBankList(
+  array,
+  capacity,
+  count
+);
+
+ +
+
array Out
+
Array to receive the list. (Studio::Bank)
+
capacity
+
Capacity of array.
+
count OutOpt
+
Number of banks written to array.
+
+

May be used in conjunction with Studio::System::getBankCount to enumerate the loaded banks.

+

Studio::System::getBufferUsage

+

Retrieves buffer usage information.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
FMOD_RESULT Studio::System::getBufferUsage(
+  FMOD_STUDIO_BUFFER_USAGE *usage
+);
+
+ +
FMOD_RESULT FMOD_Studio_System_GetBufferUsage(
+  FMOD_STUDIO_SYSTEM *system,
+  FMOD_STUDIO_BUFFER_USAGE *usage
+);
+
+ +
RESULT Studio.System.getBufferUsage(
+  out BUFFER_USAGE usage
+);
+
+ +
Studio.System.getBufferUsage(
+  usage
+);
+
+ +
+
usage Out
+
Buffer usage information. (FMOD_STUDIO_BUFFER_USAGE)
+
+

Stall count and time values are cumulative. They can be reset by calling Studio::System::resetBufferUsage.

+

Stalls due to the studio command queue overflowing can be avoided by setting a larger command queue size with Studio::System::setAdvancedSettings.

+

Studio::System::getBus

+

Retrieves a loaded bus.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
FMOD_RESULT Studio::System::getBus(
+  const char *path,
+  Studio::Bus **bus
+);
+
+ +
FMOD_RESULT FMOD_Studio_System_GetBus(
+  FMOD_STUDIO_SYSTEM *system,
+  const char *path,
+  FMOD_STUDIO_BUS **bus
+);
+
+ +
RESULT Studio.System.getBus(
+  string path,
+  out Bus bus
+);
+
+ +
Studio.System.getBus(
+  path,
+  bus
+);
+
+ +
+
path
+
The bus path or the ID string that identifies the bus. (UTF-8 string)
+
bus Out
+
Bus object. (Studio::Bus)
+
+

This function allows you to retrieve a handle for any bus in the global mixer.

+

path may be a path, such as bus:/SFX/Ambience, or an ID string, such as {d9982c58-a056-4e6c-b8e3-883854b4bffb}.

+

Path lookups only succeed if the strings bank is loaded.

+

See Also: Studio::System::getBusByID

+

Studio::System::getBusByID

+

Retrieves a loaded bus.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
FMOD_RESULT Studio::System::getBusByID(
+  const FMOD_GUID *id,
+  Studio::Bus **bus
+);
+
+ +
FMOD_RESULT FMOD_Studio_System_GetBusByID(
+  FMOD_STUDIO_SYSTEM *system,
+  const FMOD_GUID *id,
+  FMOD_STUDIO_BUS **bus
+);
+
+ +
RESULT Studio.System.getBusByID(
+  Guid id,
+  out Bus bus
+);
+
+ +
Studio.System.getBusByID(
+  id,
+  bus
+);
+
+ +
+
id
+
Bus GUID. (FMOD_GUID)
+
bus Out
+
Bus object. (Studio::Bus)
+
+

This function allows you to retrieve a handle for any bus in the global mixer.

+

See Also: Studio::System::getBus

+

Studio::System::getCoreSystem

+

Retrieves the Core System.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
FMOD_RESULT Studio::System::getCoreSystem(
+  System **system
+);
+
+ +
FMOD_RESULT FMOD_Studio_System_GetCoreSystem(
+  FMOD_STUDIO_SYSTEM *system,
+  FMOD_SYSTEM **system
+);
+
+ +
RESULT Studio.System.getCoreSystem(
+  out FMOD.System system
+);
+
+ +
Studio.System.getCoreSystem(
+  system
+);
+
+ +
+
system Out
+
Core System object. (System)
+
+

The Core System object can be retrieved before initializing the Studio System object to call additional core configuration functions.

+

See Also: System::setFileSystem, System::setDSPBufferSize, System::setSoftwareChannels, System::setSoftwareFormat, System::setAdvancedSettings, System::setCallback

+

Studio::System::getCPUUsage

+

Retrieves the amount of CPU used for different parts of the FMOD Engine.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
FMOD_RESULT Studio::System::getCPUUsage(
+  FMOD_STUDIO_CPU_USAGE *usage,
+  FMOD_CPU_USAGE *usage_core
+);
+
+ +
FMOD_RESULT FMOD_Studio_System_GetCPUUsage(
+  FMOD_STUDIO_SYSTEM *system,
+  FMOD_STUDIO_CPU_USAGE *usage,
+  FMOD_CPU_USAGE *usage_core
+);
+
+ +
RESULT Studio.System.getCPUUsage(
+  out CPU_USAGE usage,
+  out FMOD.CPU_USAGE usage_core
+);
+
+ +
Studio.System.getCPUUsage(
+  usage,
+  usage_core
+);
+
+ +
+
usage OutOpt
+
Studio API performance information. (FMOD_STUDIO_CPU_USAGE)
+
usage_core OutOpt
+
Core API performance information. (FMOD_CPU_USAGE)
+
+

For readability, the percentage values are smoothed to provide a more stable output.

+

See Also: System::getCPUUsage

+

Studio::System::getEvent

+

Retrieves an EventDescription of an event or snapshot with the specified file path.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
FMOD_RESULT Studio::System::getEvent(
+  const char *path,
+  Studio::EventDescription **event
+);
+
+ +
FMOD_RESULT FMOD_Studio_System_GetEvent(
+  FMOD_STUDIO_SYSTEM *system,
+  const char *path,
+  FMOD_STUDIO_EVENTDESCRIPTION **event
+);
+
+ +
RESULT Studio.System.getEvent(
+  string path,
+  out EventDescription _event
+);
+
+ +
Studio.System.getEvent(
+  path,
+  event
+);
+
+ +
+
path
+
The path or the ID string that identifies the event or snapshot. (UTF-8 string)
+
event Out
+
EventDescription object. (Studio::EventDescription)
+
+

This function allows you to retrieve a handle to any loaded event description.

+

path may be a path, such as event:/UI/Cancel or snapshot:/IngamePause, or an ID string, such as {2a3e48e6-94fc-4363-9468-33d2dd4d7b00}.

+

Path lookups only succeed if the strings bank is loaded.

+

See Also: Studio::parseID, Studio::System::lookupID, Studio::System::getEventByID, Studio::EventDescription::isSnapshot, Studio::EventDescription::createInstance

+

Studio::System::getEventByID

+

Retrieves an EventDescription.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
FMOD_RESULT Studio::System::getEventByID(
+  const FMOD_GUID *id,
+  Studio::EventDescription **event
+);
+
+ +
FMOD_RESULT FMOD_Studio_System_GetEventByID(
+  FMOD_STUDIO_SYSTEM *system,
+  const FMOD_GUID *id,
+  FMOD_STUDIO_EVENTDESCRIPTION **event
+);
+
+ +
RESULT Studio.System.getEventByID(
+  Guid id,
+  out EventDescription _event
+);
+
+ +
Studio.System.getEventByID(
+  id,
+  event
+);
+
+ +
+
id
+
The event or snapshot's GUID. (FMOD_GUID)
+
event Out
+
EventDescription object. (Studio::EventDescription)
+
+

This function allows you to retrieve a handle to any loaded event description.

+

See Also: Studio::System::getEvent

+

Studio::System::getListenerAttributes

+

Retrieves listener 3D attributes.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
FMOD_RESULT Studio::System::getListenerAttributes(
+  int listener,
+  FMOD_3D_ATTRIBUTES *attributes,
+  FMOD_VECTOR *attenuationposition = nullptr
+);
+
+ +
FMOD_RESULT FMOD_Studio_System_GetListenerAttributes(
+  FMOD_STUDIO_SYSTEM *system,
+  int listener,
+  FMOD_3D_ATTRIBUTES *attributes,
+  FMOD_VECTOR *attenuationposition
+);
+
+ +
RESULT Studio.System.getListenerAttributes(
+  int listener,
+  out _3D_ATTRIBUTES attributes
+);
+RESULT Studio.System.getListenerAttributes(
+  int listener,
+  out _3D_ATTRIBUTES attributes,
+  out VECTOR attenuationposition
+);
+
+ +
Studio.System.getListenerAttributes(
+  listener,
+  attributes,
+  attenuationposition
+);
+
+ +
+
listener
+
Index of listener to get 3D attributes for. Listeners are indexed from 0, to FMOD_MAX_LISTENERS - 1, in a multi-listener environment.
+
attributes Out
+
3D attributes. (FMOD_3D_ATTRIBUTES)
+
attenuationposition OutOpt
+
Position used for calculating attenuation. (FMOD_VECTOR)
+
+

See Also: Studio::EventInstance::get3DAttributes, Studio::System::getNumListeners, Studio::System::setListenerAttributes

+

Studio::System::getListenerWeight

+

Retrieves listener weighting.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
FMOD_RESULT Studio::System::getListenerWeight(
+  int listener,
+  float *weight
+);
+
+ +
FMOD_RESULT FMOD_Studio_System_GetListenerWeight(
+  FMOD_STUDIO_SYSTEM *system,
+  int listener,
+  float *weight
+);
+
+ +
RESULT Studio.System.getListenerWeight(
+  int listener,
+  out float weight
+);
+
+ +
Studio.System.getListenerWeight(
+  listener,
+  weight
+);
+
+ +
+
listener
+
Listener index.
+
weight Out
+
Weighting value.
+
+

See Also: Studio::System::setListenerWeight, Studio::System::setNumListeners, Studio::System::getListenerAttributes

+

Studio::System::getMemoryUsage

+

Retrieves memory usage statistics.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
FMOD_RESULT Studio::System::getMemoryUsage(
+  FMOD_STUDIO_MEMORY_USAGE *memoryusage
+);
+
+ +
FMOD_RESULT FMOD_Studio_System_GetMemoryUsage(
+  FMOD_STUDIO_SYSTEM *system,
+  FMOD_STUDIO_MEMORY_USAGE *memoryusage
+);
+
+ +
RESULT Studio.System.getMemoryUsage(
+  out MEMORY_USAGE memoryusage
+);
+
+ +
+

Not supported for JavaScript.

+
+
+
memoryusage Out
+
Memory usage. (FMOD_STUDIO_MEMORY_USAGE)
+
+

The memory usage sampledata value for the system is the total size of non-streaming sample data currently loaded.

+

Memory usage statistics are only available in logging builds, in release builds memoryusage will contain zero for all values after calling this function.

+

Studio::System::getNumListeners

+

Retrieves the number of listeners.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
FMOD_RESULT Studio::System::getNumListeners(
+  int *numlisteners
+);
+
+ +
FMOD_RESULT FMOD_Studio_System_GetNumListeners(
+  FMOD_STUDIO_SYSTEM *system,
+  int *numlisteners
+);
+
+ +
RESULT Studio.System.getNumListeners(
+  out int numlisteners
+);
+
+ +
Studio.System.getNumListeners(
+  numlisteners
+);
+
+ +
+
numlisteners Out
+
Number of listeners.
+
+

See Also: Studio::System::setNumListeners

+

Studio::System::getParameterByID

+

Retrieves a global parameter value by unique identifier.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
FMOD_RESULT Studio::System::getParameterByID(
+  FMOD_STUDIO_PARAMETER_ID id,
+  float *value,
+  float *finalvalue = nullptr
+);
+
+ +
FMOD_RESULT FMOD_Studio_System_GetParameterByID(
+  FMOD_STUDIO_SYSTEM *system,
+  FMOD_STUDIO_PARAMETER_ID id,
+  float *value,
+  float *finalvalue
+);
+
+ +
RESULT Studio.System.getParameterByID(
+  PARAMETER_ID id,
+  out float value
+);
+RESULT Studio.System.getParameterByID(
+  PARAMETER_ID id,
+  out float value,
+  out float finalvalue
+);
+
+ +
Studio.System.getParameterByID(
+  id,
+  value,
+  finalvalue
+);
+
+ +
+
id
+
Parameter identifier. (FMOD_STUDIO_PARAMETER_ID)
+
value OutOpt
+
Parameter value as set from the public API.
+
finalvalue OutOpt
+
Final combined value.
+
+

finalvalue is the final value of the parameter after applying adjustments due to automation, modulation, seek speed, and parameter velocity to value. This is calculated asynchronously when the Studio system updates.

+

See Also: Studio::System::setParameterByID

+

Studio::System::getParameterByName

+

Retrieves a global parameter value by name, including the path if needed.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
FMOD_RESULT Studio::System::getParameterByName(
+  const char *name,
+  float *value,
+  float *finalvalue = nullptr
+);
+
+ +
FMOD_RESULT FMOD_Studio_System_GetParameterByName(
+  FMOD_STUDIO_SYSTEM *system,
+  const char *name,
+  float *value,
+  float *finalvalue
+);
+
+ +
RESULT Studio.System.getParameterByName(
+  string name,
+  out float value
+);
+RESULT Studio.System.getParameterByName(
+  string name,
+  out float value,
+  out float finalvalue
+);
+
+ +
Studio.System.getParameterByName(
+  name,
+  value,
+  finalvalue
+);
+
+ +
+
name
+
Parameter name, including the path if needed (case-insensitive). (UTF-8 string)
+
value OutOpt
+
Parameter value as set from the public API.
+
finalvalue OutOpt
+
Final combined value.
+
+

finalvalue is the final value of the parameter after applying adjustments due to automation, modulation, seek speed, and parameter velocity to value. This is calculated asynchronously when the Studio system updates.

+

See Also: Studio::System::setParameterByName

+

Studio::System::getParameterDescriptionByID

+

Retrieves a global parameter by ID.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
FMOD_RESULT Studio::System::getParameterDescriptionByID(
+  FMOD_STUDIO_PARAMETER_ID id,
+  FMOD_STUDIO_PARAMETER_DESCRIPTION *parameter
+);
+
+ +
FMOD_RESULT FMOD_Studio_System_GetParameterDescriptionByID(
+  FMOD_STUDIO_SYSTEM *system,
+  FMOD_STUDIO_PARAMETER_ID id,
+  FMOD_STUDIO_PARAMETER_DESCRIPTION *parameter
+);
+
+ +
RESULT Studio.System.getParameterDescriptionByID(
+  PARAMETER_ID id,
+  out PARAMETER_DESCRIPTION parameter
+);
+
+ +
Studio.System.getParameterDescriptionByID(
+  id,
+  parameter
+);
+
+ +
+
id
+
Parameter ID. (FMOD_STUDIO_PARAMETER_ID)
+
parameter Out
+
Parameter description. (FMOD_STUDIO_PARAMETER_DESCRIPTION)
+
+

Studio::System::getParameterDescriptionByName

+

Retrieves a global parameter by name, including the path if needed.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
FMOD_RESULT Studio::System::getParameterDescriptionByName(
+  const char *name,
+  FMOD_STUDIO_PARAMETER_DESCRIPTION *parameter
+);
+
+ +
FMOD_RESULT FMOD_Studio_System_GetParameterDescriptionByName(
+  FMOD_STUDIO_SYSTEM *system,
+  const char *name,
+  FMOD_STUDIO_PARAMETER_DESCRIPTION *parameter
+);
+
+ +
RESULT Studio.System.getParameterDescriptionByName(
+  string name,
+  out PARAMETER_DESCRIPTION parameter
+);
+
+ +
Studio.System.getParameterDescriptionByName(
+  name,
+  parameter
+);
+
+ +
+
name
+
Parameter name, including the path if needed (case-insensitive). (UTF-8 string)
+
parameter Out
+
Parameter description. (FMOD_STUDIO_PARAMETER_DESCRIPTION)
+
+

name can be the short name (such as 'Wind') or the full path (such as 'parameter:/Ambience/Wind'). Path lookups only succeed if the strings bank is loaded.

+

Studio::System::getParameterDescriptionCount

+

Retrieves the number of global parameters.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
FMOD_RESULT Studio::System::getParameterDescriptionCount(
+  int *count
+);
+
+ +
FMOD_RESULT FMOD_Studio_System_GetParameterDescriptionCount(
+  FMOD_STUDIO_SYSTEM *system,
+  int *count
+);
+
+ +
RESULT Studio.System.getParameterDescriptionCount(
+  out int count
+);
+
+ +
Studio.System.getParameterDescriptionCount(
+  count
+);
+
+ +
+
count Out
+
Global parameter count.
+
+

See Also: Studio::System::getParameterDescriptionList

+

Studio::System::getParameterDescriptionList

+

Retrieves a list of global parameters.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
FMOD_RESULT Studio::System::getParameterDescriptionList(
+  FMOD_STUDIO_PARAMETER_DESCRIPTION *array,
+  int capacity,
+  int *count
+);
+
+ +
FMOD_RESULT FMOD_Studio_System_GetParameterDescriptionList(
+  FMOD_STUDIO_SYSTEM *system,
+  FMOD_STUDIO_PARAMETER_DESCRIPTION *array,
+  int capacity,
+  int *count
+);
+
+ +
RESULT Studio.System.getParameterDescriptionList(
+  out PARAMETER_DESCRIPTION[] array
+);
+
+ +
Studio.System.getParameterDescriptionList(
+  array,
+  capacity,
+  count
+);
+
+ +
+
array Out
+
Global parameters. (FMOD_STUDIO_PARAMETER_DESCRIPTION)
+
capacity
+
Capacity of array.
+
count Out
+
Number of parameters written to array.
+
+

See Also: Studio::System::getParameterDescriptionCount

+

Studio::System::getParameterLabelByID

+

Retrieves a global parameter label by ID.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
FMOD_RESULT Studio::System::getParameterLabelByID(
+  FMOD_STUDIO_PARAMETER_ID id,
+  int labelindex,
+  char *label,
+  int size,
+  int *retrieved
+);
+
+ +
FMOD_RESULT FMOD_Studio_System_GetParameterLabelByID(
+  FMOD_STUDIO_SYSTEM *system,
+  FMOD_STUDIO_PARAMETER_ID id,
+  int labelindex,
+  char *label,
+  int size,
+  int *retrieved
+);
+
+ +
RESULT Studio.System.getParameterLabelByID(
+  PARAMETER_ID id,
+  int labelindex,
+  out string label
+);
+
+ +
Studio.System.getParameterLabelByID(
+  id,
+  labelindex,
+  label,
+  size,
+  retrieved
+);
+
+ +
+
id
+
Parameter ID. (FMOD_STUDIO_PARAMETER_ID)
+
labelindex
+
+

Label index to retrieve.

+ +
+
label Out
+
Buffer to receive the label. (UTF-8 string)
+
size
+
Size of the label buffer in bytes. Must be 0 if label is null.
+
retrieved OutOpt
+
Length of the label in bytes, including the terminating null character.
+
+

If the label is longer than size then it is truncated and this function returns FMOD_ERR_TRUNCATED.

+

The retrieved parameter can be used to get the buffer size required to hold the full label.

+

Studio::System::getParameterLabelByName

+

Retrieves a global parameter label by name, including the path if needed.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
FMOD_RESULT Studio::System::getParameterLabelByName(
+  const char *name,
+  int labelindex,
+  char *label,
+  int size,
+  int *retrieved
+);
+
+ +
FMOD_RESULT FMOD_Studio_System_GetParameterLabelByName(
+  FMOD_STUDIO_SYSTEM *system,
+  const char *name,
+  int labelindex,
+  char *label,
+  int size,
+  int *retrieved
+);
+
+ +
RESULT Studio.System.getParameterLabelByName(
+  string name,
+  int labelindex,
+  out string label
+);
+
+ +
Studio.System.getParameterLabelByName(
+  name,
+  labelindex,
+  label,
+  size,
+  retrieved
+);
+
+ +
+
name
+
Parameter name, including the path if needed (case-insensitive). (UTF-8 string)
+
labelindex
+
+

Label index to retrieve.

+ +
+
label Out
+
Buffer to receive the label. (UTF-8 string)
+
size
+
Size of the label buffer in bytes. Must be 0 if label is null.
+
retrieved OutOpt
+
Length of the label in bytes, including the terminating null character.
+
+

name can be the short name (such as 'Wind') or the full path (such as 'parameter:/Ambience/Wind'). Path lookups only succeed if the strings bank is loaded.

+

If the label is longer than size then it is truncated and this function returns FMOD_ERR_TRUNCATED.

+

The retrieved parameter can be used to get the buffer size required to hold the full label.

+

Studio::System::getSoundInfo

+

Retrieves information for loading a sound from the audio table.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
FMOD_RESULT Studio::System::getSoundInfo(
+  const char *key,
+  FMOD_STUDIO_SOUND_INFO *info
+);
+
+ +
FMOD_RESULT FMOD_Studio_System_GetSoundInfo(
+  FMOD_STUDIO_SYSTEM *system,
+  const char *key,
+  FMOD_STUDIO_SOUND_INFO *info
+);
+
+ +
RESULT Studio.System.getSoundInfo(
+  string key,
+  out SOUND_INFO info
+);
+
+ +
Studio.System.getSoundInfo(
+  key,
+  info
+);
+
+ +
+
key
+
The key that identifies the sound. (UTF-8 string)
+
info Out
+
Sound loading information. (FMOD_STUDIO_SOUND_INFO)
+
+

The FMOD_STUDIO_SOUND_INFO structure contains information to be passed to System::createSound (which will create a parent sound), along with a subsound index to be passed to Sound::getSubSound once the parent sound is loaded.

+

The user is expected to call System::createSound with the given information. It is up to the user to combine in any desired loading flags, such as FMOD_CREATESTREAM, FMOD_CREATECOMPRESSEDSAMPLE or FMOD_NONBLOCKING with the flags in FMOD_STUDIO_SOUND_INFO::mode.

+

If the banks were loaded by Studio::System::loadBankMemory, the mode is returned as FMOD_OPENMEMORY_POINT. This won't work with the default FMOD_CREATESAMPLE mode. For in-memory banks, you should add in the FMOD_CREATECOMPRESSEDSAMPLE or FMOD_CREATESTREAM flag, or remove FMOD_OPENMEMORY_POINT and add FMOD_OPENMEMORY to decompress the sample into a new allocation.

+

Studio::System::getUserData

+

Retrieves the user data.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
FMOD_RESULT Studio::System::getUserData(
+  void **userdata
+);
+
+ +
FMOD_RESULT FMOD_Studio_System_GetUserData(
+  FMOD_STUDIO_SYSTEM *system,
+  void **userdata
+);
+
+ +
RESULT Studio.System.getUserData(
+  out IntPtr userdata
+);
+
+ +
Studio.System.getUserData(
+  userdata
+);
+
+ +
+
userdata Out
+
User data set by calling Studio::System::setUserData.
+
+

This function allows arbitrary user data to be retrieved from this object. See the User Data section of the glossary for an example of how to get and set user data.

+

Studio::System::getVCA

+

Retrieves a loaded VCA.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
FMOD_RESULT Studio::System::getVCA(
+  const char *path,
+  Studio::VCA **vca
+);
+
+ +
FMOD_RESULT FMOD_Studio_System_GetVCA(
+  FMOD_STUDIO_SYSTEM *system,
+  const char *path,
+  FMOD_STUDIO_VCA **vca
+);
+
+ +
RESULT Studio.System.getVCA(
+  string path,
+  out VCA vca
+);
+
+ +
Studio.System.getVCA(
+  path,
+  vca
+);
+
+ +
+
path
+
The path or the ID string that identifies the VCA. (UTF-8 string)
+
vca Out
+
VCA object. (Studio::VCA)
+
+

This function allows you to retrieve a handle for any VCA in the global mixer.

+

path may be a path, such as vca:/MyVCA, or an ID string, such as {d9982c58-a056-4e6c-b8e3-883854b4bffb}.

+

Path lookups only succeed if the strings bank is loaded.

+

See Also: Studio::System::getVCAByID

+

Studio::System::getVCAByID

+

Retrieves a loaded VCA.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
FMOD_RESULT Studio::System::getVCAByID(
+  const FMOD_GUID *id,
+  Studio::VCA **vca
+);
+
+ +
FMOD_RESULT FMOD_Studio_System_GetVCAByID(
+  FMOD_STUDIO_SYSTEM *system,
+  const FMOD_GUID *id,
+  FMOD_STUDIO_VCA **vca
+);
+
+ +
RESULT Studio.System.getVCAByID(
+  Guid id,
+  out VCA vca
+);
+
+ +
Studio.System.getVCAByID(
+  id,
+  vca
+);
+
+ +
+
id
+
VCA GUID. (FMOD_GUID)
+
vca Out
+
VCA object. (Studio::VCA)
+
+

This function allows you to retrieve a handle for any VCA in the global mixer.

+

See Also: Studio::System::getVCA

+

Studio::System::initialize

+

Initializes the Studio System.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
FMOD_RESULT Studio::System::initialize(
+  int maxchannels,
+  FMOD_STUDIO_INITFLAGS studioflags,
+  FMOD_INITFLAGS flags,
+  void *extradriverdata
+);
+
+ +
FMOD_RESULT FMOD_Studio_System_Initialize(
+  FMOD_STUDIO_SYSTEM *system,
+  int maxchannels,
+  FMOD_STUDIO_INITFLAGS studioflags,
+  FMOD_INITFLAGS flags,
+  void *extradriverdata
+);
+
+ +
RESULT Studio.System.initialize(
+  int maxchannels,
+  INITFLAGS studioflags,
+  FMOD.INITFLAGS flags,
+  IntPtr extradriverdata
+);
+
+ +
Studio.System.initialize(
+  maxchannels,
+  studioflags,
+  flags,
+  extradriverdata
+);
+
+ +
+
maxchannels
+
The maximum number of Channels, including both virtual and real, to be used in FMOD.
+
studioflags
+
Studio system initialization flags. (FMOD_STUDIO_INITFLAGS)
+
flags
+
Core system initialization flags. (FMOD_INITFLAGS)
+
extradriverdata Opt
+
Driver specific data to be passed to the output plug-in.
+
+

The core system used by the studio system is initialized at the same time as the studio system.

+

The flags and extradriverdata parameters are passed to System::init to initialize the core. The Studio system automatically sets the FMOD_INIT_VOL0_BECOMES_VIRTUAL flag.

+

See Also: Creating the Studio System

+

Studio::System::isValid

+

Checks that the System reference is valid and has been initialized.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
bool Studio::System::isValid()
+
+ +
bool FMOD_Studio_System_IsValid(FMOD_STUDIO_SYSTEM *system)
+
+ +
bool Studio.System.isValid()
+
+ +
Studio.System.isValid()
+
+ +

Studio::System::loadBankCustom

+

Loads the metadata of a bank using custom read callbacks.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
FMOD_RESULT Studio::System::loadBankCustom(
+  const FMOD_STUDIO_BANK_INFO *info,
+  FMOD_STUDIO_LOAD_BANK_FLAGS flags,
+  Studio::Bank **bank
+);
+
+ +
FMOD_RESULT FMOD_Studio_System_LoadBankCustom(
+  FMOD_STUDIO_SYSTEM *system,
+  const FMOD_STUDIO_BANK_INFO *info,
+  FMOD_STUDIO_LOAD_BANK_FLAGS flags,
+  FMOD_STUDIO_BANK **bank
+);
+
+ +
RESULT Studio.System.loadBankCustom(
+  BANK_INFO info,
+  LOAD_BANK_FLAGS flags,
+  out Bank bank
+);
+
+ +
Studio.System.loadBankCustom(
+  info,
+  flags,
+  bank
+);
+
+ +
+
info
+
Information for loading the bank. (FMOD_STUDIO_BANK_INFO)
+
flags
+
Flags to control bank loading. (FMOD_STUDIO_LOAD_BANK_FLAGS)
+
bank Out
+
Bank object. (Studio::Bank)
+
+

Sample data must be loaded separately see Sample Data Loading for details.

+

By default this function blocks until the load finishes, and returns the FMOD_RESULT to indicate the result. If the load fails then bank contains NULL.

+

Using the FMOD_STUDIO_LOAD_BANK_NONBLOCKING flag causes the bank to be loaded asynchronously. In that case, this function always returns FMOD_OK and bank contains a valid bank handle. Load errors for asynchronous banks can be detected by calling Studio::Bank::getLoadingState. Failed asynchronous banks should be released by calling Studio::Bank::unload.

+

If info.userdata is set but info.userdatalength is zero, info.userdata must remain valid until the bank is unloaded and each call to info.opencallback is matched by a call to info.closecallback. This requirement allows playback of shared streaming assets to continue after a bank is unloaded.

+

If a bank is split, separating out sample data and optionally streams from the metadata bank, all parts must be loaded before any APIs that use the data are called. We recommend you load each part one after another (the order in which they are loaded is not important), then proceed with dependent API calls such as Studio::Bank::loadSampleData or Studio::System::getEvent.

+

See Also: Studio::System::loadBankFile, Studio::System::loadBankMemory

+

Studio::System::loadBankFile

+

Loads the metadata of a bank. This does not load the bank's sample data.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
FMOD_RESULT Studio::System::loadBankFile(
+  const char *filename,
+  FMOD_STUDIO_LOAD_BANK_FLAGS flags,
+  Studio::Bank **bank
+);
+
+ +
FMOD_RESULT FMOD_Studio_System_LoadBankFile(
+  FMOD_STUDIO_SYSTEM *system,
+  const char *filename,
+  FMOD_STUDIO_LOAD_BANK_FLAGS flags,
+  FMOD_STUDIO_BANK **bank
+);
+
+ +
RESULT Studio.System.loadBankFile(
+  string filename,
+  LOAD_BANK_FLAGS flags,
+  out Bank bank
+);
+
+ +
Studio.System.loadBankFile(
+  filename,
+  flags,
+  bank
+);
+
+ +
+
filename
+
Name of the file on disk. (UTF-8 string)
+
flags
+
Flags to control bank loading. (FMOD_STUDIO_LOAD_BANK_FLAGS)
+
bank Out
+
Bank object. (Studio::Bank)
+
+

Sample data must be loaded separately see Sample Data Loading for details.

+

By default this function blocks until the file load finishes and returns the FMOD_RESULT to indicate the result. If the load fails, then bank contains NULL.

+

Using the FMOD_STUDIO_LOAD_BANK_NONBLOCKING flag causes the bank to be loaded asynchronously. In that case, this function returns FMOD_OK and bank contains a valid bank handle. Load errors for asynchronous banks can be detected by calling Studio::Bank::getLoadingState. Failed asynchronous banks should be released by calling Studio::Bank::unload.

+

If a bank is split, separating out sample data, metadata, and optionally streams into separate .bank files, all parts of the bank must be loaded before any APIs that use the data are called. We recommend you load each part one after another (the order is not important), then proceed with dependent API calls such as Studio::Bank::loadSampleData or Studio::System::getEvent.

+

See Also: Studio::System::loadBankCustom, Studio::System::loadBankMemory

+

Studio::System::loadBankMemory

+

Loads the metadata of a bank from memory. Does not load the bank's sample data.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
FMOD_RESULT Studio::System::loadBankMemory(
+  const char *buffer,
+  int length,
+  FMOD_STUDIO_LOAD_MEMORY_MODE mode,
+  FMOD_STUDIO_LOAD_BANK_FLAGS flags,
+  Studio::Bank **bank
+);
+
+ +
FMOD_RESULT FMOD_Studio_System_LoadBankMemory(
+  FMOD_STUDIO_SYSTEM *system,
+  const char *buffer,
+  int length,
+  FMOD_STUDIO_LOAD_MEMORY_MODE mode,
+  FMOD_STUDIO_LOAD_BANK_FLAGS flags,
+  FMOD_STUDIO_BANK **bank
+);
+
+ +
RESULT Studio.System.loadBankMemory(
+  byte[] buffer,
+  LOAD_BANK_FLAGS flags,
+  out Bank bank
+);
+
+ +
Studio.System.loadBankMemory(
+  buffer,
+  length,
+  mode,
+  flags,
+  bank
+);
+
+ +
+
buffer
+
The memory buffer.
+
length
+
The length of the memory buffer.
+
mode
+
The loading mode to use. (FMOD_STUDIO_LOAD_MEMORY_MODE)
+
flags
+
Flags to control bank loading. (FMOD_STUDIO_LOAD_BANK_FLAGS)
+
bank Out
+
The bank object. (Studio::Bank)
+
+

Sample data must be loaded separately. See the Sample Data Loading section of the Studio API Guide chapter for details.

+

When mode is FMOD_STUDIO_LOAD_MEMORY, the FMOD Engine allocates an internal buffer and copies the data from the passed-in buffer before using it. When used in this mode, there are no alignment restrictions on buffer, and the memory pointed to by buffer may be cleaned up at any time after this function returns.

+

When mode is FMOD_STUDIO_LOAD_MEMORY_POINT, the FMOD Engine uses the passed memory buffer directly. When using this mode, the buffer must be aligned to FMOD_STUDIO_LOAD_MEMORY_ALIGNMENT and the memory must persist until the bank is fully unloaded, which may not happen until some time after calling Studio::Bank::unload. You can ensure the memory is not being freed prematurely by only freeing it after receiving the FMOD_STUDIO_SYSTEM_CALLBACK_BANK_UNLOAD callback.

+

By default this function blocks until the load finishes and returns the FMOD_RESULT to indicate the result. If the load fails, bank contains NULL.

+

Using the FMOD_STUDIO_LOAD_BANK_NONBLOCKING flag causes the bank to be loaded asynchronously. In that case, this function always returns FMOD_OK and bank contains a valid bank handle. Load errors for asynchronous banks can be detected by calling Studio::Bank::getLoadingState. Failed asynchronous banks should be released by calling Studio::Bank::unload.

+

This function is not compatible with FMOD_STUDIO_ADVANCEDSETTINGS::encryptionkey, using them together will cause an error to be returned.

+

If a bank is split, separating out sample data, metadata, and optionally streams into separate .bank files, all parts of the bank must be loaded before any APIs that use the data are called. We recommend you load each part one after another (the order is not important), then proceed with dependent API calls such as Studio::Bank::loadSampleData or Studio::System::getEvent.

+

See Also: Studio::System::loadBankFile, Studio::System::loadBankCustom, Studio::System::setCallback

+

Studio::System::loadCommandReplay

+

Load a command replay.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
FMOD_RESULT Studio::System::loadCommandReplay(
+  const char *filename,
+  FMOD_STUDIO_COMMANDREPLAY_FLAGS flags,
+  Studio::CommandReplay **replay
+);
+
+ +
FMOD_RESULT FMOD_Studio_System_LoadCommandReplay(
+  FMOD_STUDIO_SYSTEM *system,
+  const char *filename,
+  FMOD_STUDIO_COMMANDREPLAY_FLAGS flags,
+  FMOD_STUDIO_COMMANDREPLAY **replay
+);
+
+ +
RESULT Studio.System.loadCommandReplay(
+  string filename,
+  COMMANDREPLAY_FLAGS flags,
+  out Studio.CommandReplay replay
+);
+
+ +
Studio.System.loadCommandReplay(
+  filename,
+  flags,
+  replay
+);
+
+ +
+
filename
+
The name of the file from which to load the command replay. (UTF-8 string)
+
flags
+
Flags that control the command replay. (FMOD_STUDIO_COMMANDREPLAY_FLAGS)
+
replay Out
+
Command replay. (Studio::CommandReplay)
+
+

See Also: Studio::System::startCommandCapture, Studio::System::stopCommandCapture, Studio::CommandReplay::start, Studio::CommandReplay::stop, Studio::CommandReplay::release

+

Studio::System::lookupID

+

Retrieves the ID for a bank, event, snapshot, bus or VCA.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
FMOD_RESULT Studio::System::lookupID(
+  const char *path,
+  FMOD_GUID *id
+);
+
+ +
FMOD_RESULT FMOD_Studio_System_LookupID(
+  FMOD_STUDIO_SYSTEM *system,
+  const char *path,
+  FMOD_GUID *id
+);
+
+ +
RESULT Studio.System.lookupID(
+  string path,
+  out Guid id
+);
+
+ +
Studio.System.lookupID(
+  path,
+  id
+);
+
+ +
+
path
+
Path. (UTF-8 string)
+
id Out
+
GUID. (FMOD_GUID)
+
+

The strings bank must be loaded prior to calling this function, otherwise FMOD_ERR_EVENT_NOTFOUND is returned.

+

The path can be copied to the system clipboard from FMOD Studio by using the "Copy Path" context menu command.

+

See Also: Studio::System::lookupPath

+

Studio::System::lookupPath

+

Retrieves the path for a bank, event, snapshot, bus or VCA.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
FMOD_RESULT Studio::System::lookupPath(
+  const FMOD_GUID *id,
+  char *path,
+  int size,
+  int *retrieved
+);
+
+ +
FMOD_RESULT FMOD_Studio_System_LookupPath(
+  FMOD_STUDIO_SYSTEM *system,
+  const FMOD_GUID *id,
+  char *path,
+  int size,
+  int *retrieved
+);
+
+ +
RESULT Studio.System.lookupPath(
+  Guid id,
+  out string path
+);
+
+ +
Studio.System.lookupPath(
+  id,
+  path,
+  size,
+  retrieved
+);
+
+ +
+
id
+
The GUID. (FMOD_GUID)
+
path OutOpt
+
The buffer to receive the path. (UTF-8 string)
+
size
+
The size of the path buffer in bytes. Must be 0 if path is null.
+
retrieved OutOpt
+
The length of the path in bytes, including the terminating null character.
+
+

The strings bank must be loaded prior to calling this function, otherwise FMOD_ERR_EVENT_NOTFOUND is returned.

+

If the path is longer than size then it is truncated and this function returns FMOD_ERR_TRUNCATED.

+

The retrieved parameter can be used to get the buffer size required to hold the full path.

+

See Also: Studio::System::lookupID

+

Studio::System::registerPlugin

+

Registers a DSP plug-in.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
FMOD_RESULT Studio::System::registerPlugin(
+  const FMOD_DSP_DESCRIPTION *description
+);
+
+ +
FMOD_RESULT FMOD_Studio_System_RegisterPlugin(
+  FMOD_STUDIO_SYSTEM *system,
+  const FMOD_DSP_DESCRIPTION *description
+);
+
+ +
Studio.System.registerPlugin(
+  description
+);
+
+ +
+

Not supported for C#.

+
+
+
description
+
The description of the DSP. (FMOD_DSP_DESCRIPTION)
+
+

DSP plug-ins used by an event must be registered using this function before loading the bank containing the event.

+

See Also: Studio::System::unregisterPlugin

+

Studio::System::release

+

Shut down and free the Studio System object.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
FMOD_RESULT Studio::System::release();
+
+ +
FMOD_RESULT FMOD_Studio_System_Release(FMOD_STUDIO_SYSTEM *system);
+
+ +
RESULT Studio.System.release();
+
+ +
Studio.System.release();
+
+ +

This function will free the memory used by the Studio System object and everything created under it.

+

Studio::System::create and Studio::System::release are not thread-safe. Calling either of these functions concurrently with any Studio API function (including these two functions) may cause undefined behavior. External synchronization must be used if calls to Studio::System::create or Studio::System::release could overlap other Studio API calls. All other Studio API functions are thread safe and may be called freely from any thread unless otherwise documented.

+

All handles or pointers to objects associated with a Studio System object become invalid when the Studio System object is released. The Studio API attempts to protect against stale handles and pointers being used with a different Studio System object but this protection cannot be guaranteed and attempting to use stale handles or pointers may cause undefined behavior.

+

See Also: Creating the Studio System

+

Studio::System::resetBufferUsage

+

Resets memory buffer usage statistics.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
FMOD_RESULT Studio::System::resetBufferUsage();
+
+ +
FMOD_RESULT FMOD_Studio_System_ResetBufferUsage(FMOD_STUDIO_SYSTEM *system);
+
+ +
RESULT Studio.System.resetBufferUsage();
+
+ +
Studio.System.resetBufferUsage();
+
+ +

This function resets the buffer usage data tracked by the Studio system.

+

See Also: FMOD_STUDIO_BUFFER_USAGE, Studio::System::getBufferUsage

+

Studio::System::setAdvancedSettings

+

Sets advanced settings.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
FMOD_RESULT Studio::System::setAdvancedSettings(
+  FMOD_STUDIO_ADVANCEDSETTINGS *settings
+);
+
+ +
FMOD_RESULT FMOD_Studio_System_SetAdvancedSettings(
+  FMOD_STUDIO_SYSTEM *system,
+  FMOD_STUDIO_ADVANCEDSETTINGS *settings
+);
+
+ +
RESULT Studio.System.setAdvancedSettings(
+  ADVANCEDSETTINGS settings
+);
+
+RESULT Studio.System.setAdvancedSettings(
+  ADVANCEDSETTINGS settings,
+  String encryptionkey
+);
+
+ +
Studio.System.setAdvancedSettings(
+  settings
+);
+
+ +
+
settings
+
The Studio system's advanced settings. (FMOD_STUDIO_ADVANCEDSETTINGS)
+
encryptionkey C#
+
The key for loading sounds from encrypted banks. (UTF-8 string)
+
+

This function must be called prior to Studio system initialization.

+
+

Use the overloaded function to provide a C# string rather than directly setting ADVANCEDSETTINGS.encryptionkey.

+
+

See Also: Studio::System::getAdvancedSettings, Studio::System::initialize

+

Studio::System::setCallback

+

Sets a callback for the Studio System.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
FMOD_RESULT Studio::System::setCallback(
+  FMOD_STUDIO_SYSTEM_CALLBACK callback,
+  FMOD_STUDIO_SYSTEM_CALLBACK_TYPE callbackmask = FMOD_STUDIO_SYSTEM_CALLBACK_ALL
+);
+
+ +
FMOD_RESULT FMOD_Studio_System_SetCallback(
+  FMOD_STUDIO_SYSTEM *system,
+  FMOD_STUDIO_SYSTEM_CALLBACK callback,
+  FMOD_STUDIO_SYSTEM_CALLBACK_TYPE callbackmask
+);
+
+ +
RESULT Studio.System.setCallback(
+  SYSTEM_CALLBACK callback,
+  SYSTEM_CALLBACK_TYPE callbackmask = SYSTEM_CALLBACK_TYPE.ALL
+);
+
+ +
Studio.System.setCallback(
+  callback,
+  callbackmask
+);
+
+ +
+
callback
+
System callback function. (FMOD_STUDIO_SYSTEM_CALLBACK)
+
callbackmask
+
A bitfield specifying which callback types are required. Defaults to FMOD_STUDIO_SYSTEM_CALLBACK_ALL. (FMOD_STUDIO_SYSTEM_CALLBACK_TYPE)
+
+

The system callback function is called for a variety of reasons, use the callbackmask to choose which callbacks you are interested in.

+

Callbacks are called from the Studio Update Thread in default / async mode and the main (calling) thread in synchronous mode. See the FMOD_STUDIO_SYSTEM_CALLBACK_TYPE for details.

+

See Also: Callback Behavior, Studio::System::setUserData

+

Studio::System::setListenerAttributes

+

Sets the 3D attributes of the listener.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
FMOD_RESULT Studio::System::setListenerAttributes(
+  int listener,
+  const FMOD_3D_ATTRIBUTES *attributes,
+  const FMOD_VECTOR *attenuationposition = nullptr
+);
+
+ +
FMOD_RESULT FMOD_Studio_System_SetListenerAttributes(
+  FMOD_STUDIO_SYSTEM *system,
+  int listener,
+  const FMOD_3D_ATTRIBUTES *attributes,
+  const FMOD_VECTOR *attenuationposition
+);
+
+ +
RESULT Studio.System.setListenerAttributes(
+  int listener,
+  _3D_ATTRIBUTES attributes
+);
+RESULT Studio.System.setListenerAttributes(
+  int listener,
+  _3D_ATTRIBUTES attributes,
+  VECTOR attenuationposition
+);
+
+ +
Studio.System.setListenerAttributes(
+  listener,
+  attributes,
+  attenuationposition
+);
+
+ +
+
listener
+
Index of listener to set 3D attributes on. Listeners are indexed from 0, to FMOD_MAX_LISTENERS - 1, in a multi-listener environment.
+
attributes
+
3D attributes. (FMOD_3D_ATTRIBUTES)
+
attenuationposition Opt
+
Position used for calculating attenuation. (FMOD_VECTOR)
+
+

Passing NULL for attenuationposition will result in the listener only using the position in attributes.

+

See Also: Studio::System::getListenerAttributes

+

Studio::System::setListenerWeight

+

Sets the listener weighting.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
FMOD_RESULT Studio::System::setListenerWeight(
+  int listener,
+  float weight
+);
+
+ +
FMOD_RESULT FMOD_Studio_System_SetListenerWeight(
+  FMOD_STUDIO_SYSTEM *system,
+  int listener,
+  float weight
+);
+
+ +
RESULT Studio.System.setListenerWeight(
+  int listener,
+  float weight
+);
+
+ +
Studio.System.setListenerWeight(
+  listener,
+  weight
+);
+
+ +
+
listener
+
Listener index.
+
weight
+
+

Weighting value.

+
    +
  • Range: [0, 1]
  • +
  • Default: 1
  • +
+
+
+

Listener weighting is a factor which determines how much the listener influences the mix. It is taken into account for 3D panning, doppler, and the automatic distance event parameter. A listener with a weight of 0 has no effect on the mix.

+

Listener weighting can be used to fade in and out multiple listeners. For example to do a crossfade, an additional listener can be created with a weighting of 0 that ramps up to 1 while the old listener weight is ramped down to 0. After the crossfade is finished the number of listeners can be reduced to 1 again.

+

The sum of all the listener weights should add up to at least 1. It is a user error to set all listener weights to 0.

+

See Also: Studio::System::getListenerWeight, Studio::System::setNumListeners

+

Studio::System::setNumListeners

+

Sets the number of listeners in the 3D sound scene.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
FMOD_RESULT Studio::System::setNumListeners(
+  int numlisteners
+);
+
+ +
FMOD_RESULT FMOD_Studio_System_SetNumListeners(
+  FMOD_STUDIO_SYSTEM *system,
+  int numlisteners
+);
+
+ +
RESULT Studio.System.setNumListeners(
+  int numlisteners
+);
+
+ +
Studio.System.setNumListeners(
+  numlisteners
+);
+
+ +
+
numlisteners
+
+

Number of listeners.

+ +
+
+

If the number of listeners is set to more than 1 then FMOD uses a 'closest sound to the listener' method to determine what should be heard.

+

See the Studio API 3D Events chapter for more information.

+

See Also: Studio::System::getNumListeners, Studio::System::setListenerAttributes, Studio::System::setListenerWeight

+

Studio::System::setParameterByID

+

Sets a global parameter value by unique identifier.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
FMOD_RESULT Studio::System::setParameterByID(
+  FMOD_STUDIO_PARAMETER_ID id,
+  float value,
+  bool ignoreseekspeed = false
+);
+
+ +
FMOD_RESULT FMOD_Studio_System_SetParameterByID(
+  FMOD_STUDIO_SYSTEM *system,
+  FMOD_STUDIO_PARAMETER_ID id,
+  float value,
+  FMOD_BOOL ignoreseekspeed
+);
+
+ +
RESULT Studio.System.setParameterByID(
+  PARAMETER_ID id,
+  float value,
+  bool ignoreseekspeed = false
+);
+
+ +
Studio.System.setParameterByID(
+  id,
+  value,
+  ignoreseekspeed
+);
+
+ +
+
id
+
Parameter identifier. (FMOD_STUDIO_PARAMETER_ID)
+
value
+
Value for given identifier.
+
ignoreseekspeed
+
+

Specifies whether to ignore the parameter's seek speed and set the value immediately.

+
    +
  • Units: Boolean
  • +
+
+
+

See Also: Studio::System::setParameterByName, Studio::System::setParametersByIDs, Studio::System::getParameterByID, Studio::System::getParameterByName

+

Studio::System::setParameterByIDWithLabel

+

Sets a global parameter value by unique identifier, looking up the value label.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
FMOD_RESULT Studio::System::setParameterByIDWithLabel(
+  FMOD_STUDIO_PARAMETER_ID id,
+  const char *label,
+  bool ignoreseekspeed = false
+);
+
+ +
FMOD_RESULT FMOD_Studio_System_SetParameterByIDWithLabel(
+  FMOD_STUDIO_SYSTEM *system,
+  FMOD_STUDIO_PARAMETER_ID id,
+  const char *label,
+  FMOD_BOOL ignoreseekspeed
+);
+
+ +
RESULT Studio.System.setParameterByIDWithLabel(
+  PARAMETER_ID id,
+  string label,
+  bool ignoreseekspeed = false
+);
+
+ +
Studio.System.setParameterByIDWithLabel(
+  id,
+  label,
+  ignoreseekspeed
+);
+
+ +
+
id
+
Parameter identifier. (FMOD_STUDIO_PARAMETER_ID)
+
label
+
Labeled value for given identifier.
+
ignoreseekspeed
+
Specifies whether to ignore the parameter's seek speed and set the value immediately.
+
+

If the specified label is not found, FMOD_ERR_EVENT_NOTFOUND is returned. This lookup is case sensitive.

+

See Also: Studio::System::setParameterByName, Studio::System::setParametersByIDs, Studio::System::getParameterByID, Studio::System::getParameterByName

+

Studio::System::setParameterByName

+

Sets a global parameter value by name, including the path if needed.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
FMOD_RESULT Studio::System::setParameterByName(
+  const char *name,
+  float value,
+  bool ignoreseekspeed = false
+);
+
+ +
FMOD_RESULT FMOD_Studio_System_SetParameterByName(
+  FMOD_STUDIO_SYSTEM *system,
+  const char *name,
+  float value,
+  FMOD_BOOL ignoreseekspeed
+);
+
+ +
RESULT Studio.System.setParameterByName(
+  string name,
+  float value,
+  bool ignoreseekspeed = false
+);
+
+ +
Studio.System.setParameterByName(
+  name,
+  value,
+  ignoreseekspeed
+);
+
+ +
+
name
+
Parameter name, including the path if needed (case-insensitive). (UTF-8 string)
+
value
+
Value for given name.
+
ignoreseekspeed
+
+

Specifies whether to ignore the parameter's seek speed and set the value immediately.

+
    +
  • Units: Boolean
  • +
+
+
+

See Also: Studio::System::setParameterByID, Studio::System::setParametersByIDs, Studio::System::getParameterByID, Studio::System::getParameterByName

+

Studio::System::setParameterByNameWithLabel

+

Sets a global parameter value by name, including the path if needed, looking up the value label.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
FMOD_RESULT Studio::System::setParameterByNameWithLabel(
+  const char *name,
+  const char *label,
+  bool ignoreseekspeed = false
+);
+
+ +
FMOD_RESULT FMOD_Studio_System_SetParameterByNameWithLabel(
+  FMOD_STUDIO_SYSTEM *system,
+  const char *name,
+  const char *label,
+  FMOD_BOOL ignoreseekspeed
+);
+
+ +
RESULT Studio.System.setParameterByNameWithLabel(
+  string name,
+  string label,
+  bool ignoreseekspeed = false
+);
+
+ +
Studio.System.setParameterByNameWithLabel(
+  name,
+  label,
+  ignoreseekspeed
+);
+
+ +
+
name
+
Parameter name, including the path if needed (case-insensitive). (UTF-8 string)
+
label
+
Labeled value for given name.
+
ignoreseekspeed
+
Specifies whether to ignore the parameter's seek speed and set the value immediately.
+
+

If the specified label is not found, FMOD_ERR_EVENT_NOTFOUND is returned. This lookup is case sensitive.

+

See Also: Studio::System::setParameterByID, Studio::System::setParametersByIDs, Studio::System::getParameterByID, Studio::System::getParameterByName

+

Studio::System::setParametersByIDs

+

Sets multiple global parameter values by unique identifier.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
FMOD_RESULT Studio::System::setParametersByIDs(
+  const FMOD_STUDIO_PARAMETER_ID *ids,
+  float *values,
+  int count,
+  bool ignoreseekspeed = false
+);
+
+ +
FMOD_RESULT FMOD_Studio_System_SetParametersByIDs(
+  FMOD_STUDIO_SYSTEM *system,
+  const FMOD_STUDIO_PARAMETER_ID *ids,
+  float *values,
+  int count,
+  FMOD_BOOL ignoreseekspeed
+);
+
+ +
RESULT Studio.System.setParametersByIDs(
+  PARAMETER_ID[] ids,
+  float[] values,
+  int count,
+  bool ignoreseekspeed = false
+);
+
+ +
Studio.System.setParametersByIDs(
+  ids,
+  values,
+  count,
+  ignoreseekspeed
+);
+
+ +
+
ids
+
Array of parameter identifiers. (FMOD_STUDIO_PARAMETER_ID)
+
values
+
Array of values for each given identifier.
+
count
+
+

Number of items in the given arrays.

+
    +
  • Range: [1, 32]
  • +
+
+
ignoreseekspeed
+
+

Specifies whether to ignore the parameter's seek speed and set the value immediately.

+
    +
  • Units: Boolean
  • +
+
+
+

If any ID is set to all zeroes then the corresponding value will be ignored.

+

See Also: Studio::System::setParameterByID, Studio::System::setParameterByName, Studio::System::getParameterByID, Studio::System::getParameterByName

+

Studio::System::setUserData

+

Sets the user data.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
FMOD_RESULT Studio::System::setUserData(
+  void *userdata
+);
+
+ +
FMOD_RESULT FMOD_Studio_System_SetUserData(
+  FMOD_STUDIO_SYSTEM *system,
+  void *userdata
+);
+
+ +
RESULT Studio.System.setUserData(
+  IntPtr userdata
+);
+
+ +
Studio.System.setUserData(
+  userdata
+);
+
+ +
+
userdata
+
User data to store within the system.
+
+

This function allows arbitrary user data to be attached to this object, which wll be passed through the userdata parameter in any FMOD_STUDIO_SYSTEM_CALLBACKs. See the User Data section of the glossary for an example of how to get and set user data.

+

See Also: Studio::System::getUserData, Studio::System::setCallback

+

Studio::System::startCommandCapture

+

Start recording Studio API commands to a file.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
FMOD_RESULT Studio::System::startCommandCapture(
+  const char *filename,
+  FMOD_STUDIO_COMMANDCAPTURE_FLAGS flags
+);
+
+ +
FMOD_RESULT FMOD_Studio_System_StartCommandCapture(
+  FMOD_STUDIO_SYSTEM *system,
+  const char *filename,
+  FMOD_STUDIO_COMMANDCAPTURE_FLAGS flags
+);
+
+ +
RESULT Studio.System.startCommandCapture(
+  string filename,
+  COMMANDCAPTURE_FLAGS flags
+);
+
+ +
Studio.System.startCommandCapture(
+  filename,
+  flags
+);
+
+ +
+
filename
+
The name of the file to which the recorded commands are to be written. (UTF-8 string)
+
flags
+
Flags that control command capturing. (FMOD_STUDIO_COMMANDCAPTURE_FLAGS)
+
+

Commands generated by the Studio API can be captured and later replayed for debugging and profiling purposes.

+

Unless the FMOD_STUDIO_COMMANDCAPTURE_SKIP_INITIAL_STATE flag is specified, the command capture first records the set of all banks and event instances that currently exist.

+

See Also: Studio::System::stopCommandCapture, Studio::System::loadCommandReplay

+

Studio::System::stopCommandCapture

+

Stop recording Studio API commands.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
FMOD_RESULT Studio::System::stopCommandCapture();
+
+ +
FMOD_RESULT FMOD_Studio_System_StopCommandCapture(FMOD_STUDIO_SYSTEM *system);
+
+ +
RESULT Studio.System.stopCommandCapture();
+
+ +
Studio.System.stopCommandCapture();
+
+ +

See Also: Studio::System::startCommandCapture, Studio::System::loadCommandReplay

+

Studio::System::unloadAll

+

Unloads all currently loaded banks.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
FMOD_RESULT Studio::System::unloadAll();
+
+ +
FMOD_RESULT FMOD_Studio_System_UnloadAll(FMOD_STUDIO_SYSTEM *system);
+
+ +
RESULT Studio.System.unloadAll();
+
+ +
Studio.System.unloadAll();
+
+ +

See Also: Studio::System::loadBankFile, Studio::System::loadBankMemory, Studio::System::loadBankCustom

+

Studio::System::unregisterPlugin

+

Unregisters a DSP plug-in.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
FMOD_RESULT Studio::System::unregisterPlugin(
+  const char *name
+);
+
+ +
FMOD_RESULT FMOD_Studio_System_UnregisterPlugin(
+  FMOD_STUDIO_SYSTEM *system,
+  const char *name
+);
+
+ +
Studio.System.unregisterPlugin(
+  name
+);
+
+ +
+

Not supported for C#.

+
+
+
name
+
The name of the DSP. This must match the description passed to Studio::System::registerPlugin.
+
+

See Also: Studio::System::registerPlugin

+

Studio::System::update

+

Update the studio system.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
FMOD_RESULT Studio::System::update();
+
+ +
FMOD_RESULT FMOD_Studio_System_Update(FMOD_STUDIO_SYSTEM *system);
+
+ +
RESULT Studio.System.update();
+
+ +
Studio.System.update();
+
+ +

When Studio is initialized in the default asynchronous processing mode this function submits all buffered commands for execution on the Studio Update thread for asynchronous processing. This is a fast operation since the commands are not processed on the calling thread. If Studio is initialized with FMOD_STUDIO_INIT_DEFERRED_CALLBACKS then any deferred callbacks fired during any asynchronous updates since the last call to this function will be called. If an error occurred during any asynchronous updates since the last call to this function then this function will return the error result.

+

When Studio is initialized with FMOD_STUDIO_INIT_SYNCHRONOUS_UPDATE queued commands will be processed immediately when calling this function, the scheduling and update logic for the Studio system are executed and all callbacks are fired. This may block the calling thread for a substantial amount of time.

+

See Also: Studio System Processing

+ + +
+ + + diff --git a/FMOD/doc/FMOD API User Manual/studio-api-threads.html b/FMOD/doc/FMOD API User Manual/studio-api-threads.html new file mode 100644 index 0000000..bfb8a8d --- /dev/null +++ b/FMOD/doc/FMOD API User Manual/studio-api-threads.html @@ -0,0 +1,67 @@ + + +Studio API Threads + + + + +
+ +
+

15. Studio API Threads

+

15.1 Studio Thread Overview

+

This section will describe how Studio execution works in regards to threads.

+

15.1.1 Studio Synchronous Mode

+

If Studio::System::initialize is called with FMOD_STUDIO_INIT_SYNCHRONOUS_UPDATE, then Studio will be created in synchronous mode. In this mode, all Studio API commands are executed during Studio::System::update.

+

As part of that Studio update, it will automatically call the core System::update to ensure that the core system is updated properly.

+

Studio Thread Synchronous

+

The above diagram shows Studio commands being called from the game thread in Studio. It also shows the core mixer thread, which is triggered based on the hardware output device. The core mixer thread normally has a period of 5ms, 10ms, or 20ms, depending on the platform. It can also be customized with System::setDSPBufferSize and System::setSoftwareFormat.

+

When running in this mode, Studio must deal with the fact that the core mix can execute at any time. For instance, an event may have two timelocked instruments that should start at the same time. Studio schedules sounds a mix block later so that even if the mix jumps in, all scheduled events will occur in the same mix block.

+

15.1.2 Studio Asynchronous Mode

+

The default operation is for Studio to create its own asynchronous thread for execution. In this mode, Studio API commands are enqueued and executed in the Studio asynchronous thread. The commands are batched up so that they are only sent to the asynchronous thread at the end of the next Studio::System::update. This prevents some Studio commands from executing earlier than others, which could cause glitches. For instance, if an event position is updated, and the listener position is updated, those two commands will always be executed together.

+

Studio Thread Asynchronous

+

In asynchronous mode, the Studio processing occurs every 20ms and is triggered off the core mixer. The core mix is split into parts, premix, midmix and postmix. It is the core premix that executes any enqueued core commands and updates DSP clocks. By triggering the asynchronous Studio processing at the end of the premix, Studio can assume that the mix isn't going to jump in as the asynchronous update is executing. Unlike the first case, Studio can also assume that the update will be called in a timely manner, even if the game's main thread has a framerate spike.

+

The size of the Studio asynchronous command buffer can be customized by calling Studio::System::setAdvancedSettings. If there is not enough space for commands, then a stall will occur until the asynchronous update has consumed enough commands. Studio::System::getBufferUsage can be used to measure if any stalls have occurred due to the command buffer not being large enough.

+

15.1.3 Game Controlled Worker Thread

+

Another command situation is for the game to have its own worker thread that invokes Studio using FMOD_STUDIO_INIT_SYNCHRONOUS_UPDATE. This is very similar to the first diagram, except that execution is in a worker rather than the game thread. It is up to the game thread how it wishes to synchronize with the rest of the game. It could be triggered per game frame, or with a fixed period.

+

In this mode, it is up to the developer to ensure that commands are not split across system updates. For example, consider the case where the game thread issues commands for the worker thread, and the worker thread wakes up periodically to execute those commands. In that case, the worker thread may wake up and execute some commands but not others, causing subtle issues with the sound playback. Instead, the commands to the worker thread should be batched up to avoid slicing commands. Or even better, just use the inbuilt asynchronous mode to do the command batching instead.

+ + +
+ + + diff --git a/FMOD/doc/FMOD API User Manual/studio-api-vca.html b/FMOD/doc/FMOD API User Manual/studio-api-vca.html new file mode 100644 index 0000000..d5e4f2a --- /dev/null +++ b/FMOD/doc/FMOD API User Manual/studio-api-vca.html @@ -0,0 +1,253 @@ + + +Studio API Reference | Studio::VCA + + + + +
+ +
+

16. Studio API Reference | Studio::VCA

+

Represents a global mixer VCA.

+

Volume:

+ +

General:

+ +

See Also:

+ +

Studio::VCA::getID

+

Retrieves the VCA's GUID.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
FMOD_RESULT Studio::VCA::getID(
+  FMOD_GUID *id
+);
+
+ +
FMOD_RESULT FMOD_Studio_VCA_GetID(
+  FMOD_STUDIO_VCA *vca,
+  FMOD_GUID *id
+);
+
+ +
RESULT Studio.VCA.getID(
+  out Guid id
+);
+
+ +
Studio.VCA.getID(
+  id
+);
+
+ +
+
id Out
+
VCA GUID. (FMOD_GUID)
+
+

Studio::VCA::getPath

+

Retrieves the path.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
FMOD_RESULT Studio::VCA::getPath(
+  char *path,
+  int size,
+  int *retrieved
+);
+
+ +
FMOD_RESULT FMOD_Studio_VCA_GetPath(
+  FMOD_STUDIO_VCA *vca,
+  char *path,
+  int size,
+  int *retrieved
+);
+
+ +
RESULT Studio.VCA.getPath(
+  out string path
+);
+
+ +
Studio.VCA.getPath(
+  path,
+  size,
+  retrieved
+);
+
+ +
+
path OutOpt
+
Buffer to receive the path. (UTF-8 string)
+
size
+
Size of the path buffer in bytes. Must be 0 if path is null.
+
retrieved OutOpt
+
Length of the path in bytes, including the terminating null character.
+
+

The strings bank must be loaded prior to calling this function, otherwise FMOD_ERR_EVENT_NOTFOUND is returned.

+

If the path is longer than size then it is truncated and this function returns FMOD_ERR_TRUNCATED.

+

The retrieved parameter can be used to get the buffer size required to hold the full path.

+

Studio::VCA::getVolume

+

Retrieves the volume level.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
FMOD_RESULT Studio::VCA::getVolume(
+  float *volume,
+  float *finalvolume = 0
+);
+
+ +
FMOD_RESULT FMOD_Studio_VCA_GetVolume(
+  FMOD_STUDIO_VCA *vca,
+  float *volume,
+  float *finalvolume
+);
+
+ +
RESULT Studio.VCA.getVolume(
+  out float volume
+);
+RESULT Studio.VCA.getVolume(
+  out float volume,
+  out float finalvolume
+);
+
+ +
Studio.VCA.getVolume(
+  volume,
+  finalvolume
+);
+
+ +
+
volume OutOpt
+
Volume set by Studio::VCA::setVolume.
+
finalvolume OutOpt
+
Final combined volume.
+
+

The final combined volume returned in finalvolume combines the user value set using Studio::VCA::setVolume with the result of any automation or modulation applied to the VCA. The final combined volume is calculated asynchronously when the Studio system updates.

+

Studio::VCA::isValid

+

Checks that the VCA reference is valid.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
bool Studio::VCA::isValid()
+
+ +
bool FMOD_Studio_VCA_IsValid(FMOD_STUDIO_VCA *vca)
+
+ +
bool Studio.VCA.isValid()
+
+ +
Studio.VCA.isValid()
+
+ +

Studio::VCA::setVolume

+

Sets the volume level.

+

+

+
C
+
C++
+
C#
+
JS
+
+

+
FMOD_RESULT Studio::VCA::setVolume(
+  float volume
+);
+
+ +
FMOD_RESULT FMOD_Studio_VCA_SetVolume(
+  FMOD_STUDIO_VCA *vca,
+  float volume
+);
+
+ +
RESULT Studio.VCA.setVolume(
+  float volume
+);
+
+ +
Studio.VCA.setVolume(
+  volume
+);
+
+ +
+
volume
+
+

Volume level. Negative level inverts the signal.

+
    +
  • Units: Linear
  • +
  • Range: (-inf, inf)
  • +
  • Default: 1
  • +
+
+
+

The VCA volume level is used to linearly modulate the levels of the buses and VCAs which it controls.

+

See Also: Studio::VCA::getVolume

+ + +
+ + + diff --git a/FMOD/doc/FMOD API User Manual/studio-api.html b/FMOD/doc/FMOD API User Manual/studio-api.html new file mode 100644 index 0000000..44d355d --- /dev/null +++ b/FMOD/doc/FMOD API User Manual/studio-api.html @@ -0,0 +1,52 @@ + + +Studio API Reference + + + + + + + + diff --git a/FMOD/doc/FMOD API User Manual/studio-guide.html b/FMOD/doc/FMOD API User Manual/studio-guide.html new file mode 100644 index 0000000..02c5fa7 --- /dev/null +++ b/FMOD/doc/FMOD API User Manual/studio-guide.html @@ -0,0 +1,292 @@ + + +Studio API Guide + + + + +
+ +
+

13. Studio API Guide

+

13.1 What is the Studio API?

+

The Studio API lets you to interact with the data driven projects created in FMOD Studio at run time. It is built on top of the Core API and provides additional functionality to what the Core API provides.

+

Studio API wrappers are available for C, C++ and C# as fmod_studio.h, fmod_studio.hpp and fmod_studio.cs respectively. Any includes and libraries required by the Core API are also required for the Studio API.

+

13.2 Getting Started

+

At the most basic level, this is achieved by creating the Studio::System object and calling Studio::System::initialize on it. You need to do this once when your game starts before you can use the FMOD Engine. Once the system is initialized, you can start loading banks and creating event instances without having to do any other preparations. A more detailed description of initialization can be found in the Studio API Getting Started chapter.

+

If using the C# wrapper, you must call a Core API function before calling anything else in the Studio API. This is because some runtimes do not perform dependency loading, and because the Studio API depends on the Core API, fmod.dll needs to be loaded before fmod_studio.dll. Calling a Core API function before Studio::System::create ensures that fmod.dll is loaded before fmod_studio.dll.

+

13.3 Creating the Studio System

+

Instances of Studio::System must be created by calling Studio::System::create. Once created an instance must be initialized with a call to Studio::System::initialize before it can be used. Studio::System::create also creates an FMOD System instance which can be retrieved using Studio::System::getCoreSystem.

+

Pre-initialization configuration of both the Studio System and the Core System may be performed prior to calling Studio::System::initialize:

+
    +
  • Studio::System::setAdvancedSettings can be called to configure various advanced settings.
  • +
  • System::setSoftwareFormat should be called on the Core System object with speakermode corresponding to the project's output format if there is a possibility of the output audio device not matching the project's format. Any differences between the project format and the Core System's speakermode will cause the mix to be incorrect.
  • +
+

The Studio System is shut down and released by calling Studio::System::release, make sure to call this before your game is exited.

+

13.4 Studio System Processing

+

FMOD Studio is built on a multithreaded processing model, in which API calls on a game thread try to be fast by only reading and writing shadow data or enqueuing commands to a buffer, while a separate Studio update thread triggered by the mixer asynchronously processes the API commands and performs all the logic required by event playback and automation.

+

When running in this default asynchronous processing mode, calling Studio::System::update from your game is a fast operation which submits the queued command buffer to the asynchronous thread and performs any asynchronous callbacks due to processing on the Studio update thread.

+

Studio may also be initialized in synchronous mode with the FMOD_STUDIO_INIT_SYNCHRONOUS_UPDATE flag. When operating in synchronous mode, API calls behave the same but all the processing of queued commands and event playback and automation is performed when your game calls Studio::System::update.

+

If you do not call Studio::System::update then previous commands will not be executed. While most of the API hides this behavior with use of shadowed variables, it can cause unexpected results if waiting in a loop for Studio::EventDescription::getSampleLoadingState or Studio::Bank::getLoadingState without calling update first.

+

13.5 Bank Layout

+

By default, a bank file created in FMOD Studio contains both event metadata and sound sample data.

+

Studio Bank Layout

+

Loading a bank loads all its metadata. A bank's metadata contains information about all the events, parameters, and other data other than sample data needed by the events in that bank.

+

Sound sample data comes in two different types: Normal sample data, and streaming sample data. Normal sample data can be loaded in advance of playback on a per-event basis. Streaming data is streamed in on demand as events are played, and is never fully loaded ahead of time. Whether sample data is streamed or not is set by the sound designer in FMOD Studio, and cannot be changed at runtime. For guidance on which sample data should be set to stream, see the Streams section of the Loading and Playing Sounds in the Core API chapter.

+

13.5.1 Strings Bank

+

The strings bank is a special bank which contains the string lookup of event path to GUID. The strings bank functions identically to a normal bank, except that it never contains sample data or streaming sample data.

+

13.5.2 Master Bank

+

Master banks contain the global mixer and are required for creating instances of events, regardless of which bank the event's metadata and sample data exist in. At least one master bank should remain loaded at all times.

+

13.5.3 Bank Separation

+

While banks normally contain both sample data and metadata, FMOD Studio also allows for metadata and sample data to be built to separate banks. This is commonly done to lower patch size when patching a project with updated banks, as separating sample data and metadata means that it is possible to update a bank's metadata without updating its sample data, or vice versa.

+

13.5.4 Referenced Events

+

FMOD Studio optionally allows referenced events to not be automatically included in the same banks as the events by which they are referenced. If this is the case, a referenced event may be assigned to a different bank than the event or events that reference it.

+

13.6 Bank Loading

+

Banks are loaded by calling Studio::System::loadBankFile. They are unloaded by Studio::Bank::unload.

+

Bank loading can be controlled with the FMOD_STUDIO_LOAD_BANK_FLAGS. When loading banks with FMOD_STUDIO_LOAD_BANK_NORMAL, the function does not return until the bank is finished loading. When using the FMOD_STUDIO_LOAD_BANK_NONBLOCKING flag (as described in the Asychronous I/O section of the Loading and Playing Sounds in the Core API chapter), the load bank function returns before the bank is finished loading.

+

When a bank is fully loaded, all metadata in that bank can be accessed. This means that event descriptions can be found with Studio::System::getEvent, and instances created from those descriptions. The bank loading state can be queried with Studio::Bank::getLoadingState.

+

If a bank's sample data and metadata have been built separately, it is possible to load a bank's metadata and not its sample data, or vice-versa. If a bank's metadata is loaded and its sample data is not, events belonging to that bank can be still instantiated and played. However, doing so causes the FMOD Engine to log a warning, and all instruments whose associated sample data is not loaded are silent during playback.

+

If referenced events are not included in the same banks as the parent events by which they are referenced, it is possible to play a loaded parent event that references a child event that is not loaded. If this occurs, the FMOD Engine logs a warning, and event instruments that would play a non-loaded child event are silent during playback.

+

13.7 Bank Unload

+

Banks can be unloaded by calling Studio::Bank::unload. Unloading a bank frees all sample data from that bank, invalidates the event descriptions belonging to that bank, and destroys all associated event instances.

+

If the bank containing sample data is unloaded after being loaded using Studio::System::loadBankMemory, the system immediately unloads that bank's sample data. If any instances of events in a bank are still playing when that bank is unloaded, it may lead to playback errors. This can occur even if multiple copies of the sample data are loaded due to multiple different banks containing that sample data being loaded, and only one of those banks is unloaded.

+

13.8 Sample Data loading

+

Sample data is loaded from one of the three actions:

+ +

For cases where most or all of the events may play at any time, then loading calling Studio::Bank::loadSampleData to load all data up front may be the best approach. Once the bank sample data has loaded, then all event instances can be created or destroyed and use that existing data immediately. However, it does have the highest memory overhead. Repeated calls to Studio::Bank::loadSampleData are reference counted, and the bank's sample data is only unloaded when Studio::Bank::unloadSampleData has been called an equal number of times.

+

Sample data can be loaded for a selected event using Studio::EventDescription::loadSampleData. It is best to load the sample data ahead of time, so that the event's sound sample data is ready when needed. For cases of very common events, the sample data could be loaded for the duration of the game or level. For less common events, the sample data may be loaded in or out as needed. Repeated calls to Studio::EventDescription::loadSampleData are reference counted, and the bank's sample data is only unloaded when Studio::EventDescription::unloadSampleData has been called an equal number of times, or if the entire bank is unloaded.

+

When either of these reference counts is incremented to one the system begins loading the referenced sample data. The sample data is loaded asynchronously and the loading state may be polled by calling Studio::Bank::getSampleLoadingState or Studio::EventDescription::getSampleLoadingState. Alternatively, you can call Studio::System::flushSampleLoading, which will block until all sample loading and unloading has completed.

+

When an instance of an event is created by calling Studio::EventDescription::createInstance the system begins loading any non-streaming sample data which is not already loaded or loading. Once again the sample data is loaded asynchronously and the loading state may be polled by calling Studio::EventDescription::getSampleLoadingState. If playback of the instance is started by calling Studio::EventInstance::start before the sample data has finished loading then the instance will stay in the FMOD_STUDIO_PLAYBACK_STARTING state until loading of the sampled data has completed.

+

The automatic loading of sample data is the simplest approach and uses the least amount of memory. However it has the following disadvantages:

+
    +
  • Sample data will only start loading when the instance is created, which may be just before Studio::EventInstance::start is called.
  • +
  • Sample data will only stay loaded for as long as at least one instance exists.
  • +
+

For the case of one-shots, this may mean that the sample data is constantly loaded and unloaded whenever a one-shot plays, which is not a good approach. For these sort of common sounds, it is better to call Studio::EventDescription::loadSampleData so the sample data stays in memory rather than constantly unloading then reloading it.

+

The three approaches to bank loading can be combined. The sample data will stay loaded for as long as at least one of the three conditions are met.

+

13.8.1 Idle Pool

+

For users who don't explicitly load sample data, sounds will be loaded and unloaded on demand. To help avoid unnecessary file access, there is an idle pool for recently used sounds. When a sound is no longer needed (e.g due to an event instance finishing), its sample data will be placed into the idle pool to be reused later if needed.

+

By default, the idle pool is set to 256kB in size. This can be customized via the FMOD_STUDIO_ADVANCEDSETTINGS::idleSampleDataPoolSize field.

+

13.9 Dialogue and Localization

+

Start by loading the banks that contain the audio tables. Next, create an instance of an event that contains a programmer instrument. Using this event instance, you can register for event callbacks, specifically FMOD_STUDIO_EVENT_CALLBACK_CREATE_PROGRAMMER_SOUND. By using these callbacks, you can create and assign sounds from the audio tables.

+

For localized dialogue, make sure that the required localized bank is loaded. Ensure that any other localized versions of the same bank are unloaded before loading a localized bank.

+

See the FMOD Studio User Manual for more information.

+

13.9.1 Scripting Example

+

This is a modified excerpt of the programmer instrument example that is included in the C++ Studio API installation folder. The error checking has been removed for brevity.

+
struct ProgrammerSoundContext
+{
+    FMOD::System* coreSystem;
+    FMOD::Studio::System* system;
+    const char* dialogueString;
+};
+
+ProgrammerSoundContext programmerSoundContext;
+programmerSoundContext.system = system;
+programmerSoundContext.coreSystem = coreSystem;
+
+ +

This section is to set up a struct to contain the various systems required for injecting audio files or loading keys into a programmer instrument.

+
eventInstance->setUserData(&programmerSoundContext);
+eventInstance->setCallback(programmerSoundCallback, FMOD_STUDIO_EVENT_CALLBACK_CREATE_PROGRAMMER_SOUND | FMOD_STUDIO_EVENT_CALLBACK_DESTROY_PROGRAMMER_SOUND);
+
+ +

The setUserData() function allows you to attach any kind of data to the event instance. In this case, the Studio system, Core system, and the dialogue string are being attached to this event instance.

+

The setCallback() function attaches the callback to the event instance. This callback will be set up outside the main thread and explained more later on.

+
// Available banks
+// "Dialogue_EN.bank", "Dialogue_JP.bank", "Dialogue_CN.bank"
+FMOD::Studio::Bank* localizedBank = NULL;
+system->loadBankFile(Common_MediaPath("Dialogue_JP.bank"), FMOD_STUDIO_LOAD_BANK_NORMAL, &localizedBank);
+programmerSoundContext.dialogueString = "welcome";
+eventInstance->start();
+
+ +

When a localized audio table is added to a bank in FMOD Studio, it builds a different version of that bank file for each locale, each with its own audio table. The programmerSoundContext.dialogueString variable is the audio table key you wish to use. In this example, "welcome" is used.

+

With "welcome" as the key, what sound plays depends on the bank loaded. In this example, it will play the Japanese bank's "welcome" audio file.

+
FMOD_RESULT F_CALL programmerSoundCallback(FMOD_STUDIO_EVENT_CALLBACK_TYPE type, FMOD_STUDIO_EVENTINSTANCE* event, void* parameters)
+
+ +

This function is to set up what happens when a programmer instrument callback is called.

+
{
+    FMOD::Studio::EventInstance* eventInstance = (FMOD::Studio::EventInstance*)event;
+
+    if (type == FMOD_STUDIO_EVENT_CALLBACK_CREATE_PROGRAMMER_SOUND)
+    {
+        // Get our context from the event instance user data
+        ProgrammerSoundContext* context = NULL;
+        eventInstance->getUserData((void**)&context);
+
+        // Find the audio file in the audio table with the key
+        FMOD_STUDIO_SOUND_INFO info;
+        context->system->getSoundInfo(context->dialogueString, &info);
+
+        FMOD::Sound* sound = NULL;
+        context->coreSystem->createSound(info.name_or_data, FMOD_LOOP_NORMAL | FMOD_CREATECOMPRESSEDSAMPLE | FMOD_NONBLOCKING | info.mode, &info.exinfo, &sound);
+
+        FMOD_STUDIO_PROGRAMMER_SOUND_PROPERTIES* props = (FMOD_STUDIO_PROGRAMMER_SOUND_PROPERTIES*)parameters;
+
+        // Pass the sound to FMOD
+        props->sound = (FMOD_SOUND*)sound;
+        props->subsoundIndex = info.subsoundindex;
+    }
+
+ +

The context struct set up previously is attached to the event with getUserData(). As mentioned previously, these are the Core system, the Studio system, and the dialogue string.

+

The context struct's dialogue string is passed to the context struct's Studio system. The system searches all loaded audio tables for the string provided, and passes the corresponding sound info into the info variable. If multiple audio tables are loaded that contain the same key, the latest-loaded audio table is used.

+

A Core API FMOD::Sound is then instantiated using the information gathered in the info variable. The audio table is passed in as info.name_or_data but the specific audio file to be used isn't specified immediately.

+

When a programmer instrument is created (triggered), the programmer instrument expects a FMOD_STUDIO_PROGRAMMER_SOUND_PROPERTIES to be passed into it. The audio table, in the FMOD::Sound, is provided to the props properties, and the subsoundIndex is the actual audio file (subsound of the audio table) chosen with the key string.

+
    else if (type == FMOD_STUDIO_EVENT_CALLBACK_DESTROY_PROGRAMMER_SOUND)
+    {
+        FMOD_STUDIO_PROGRAMMER_SOUND_PROPERTIES* props = (FMOD_STUDIO_PROGRAMMER_SOUND_PROPERTIES*)parameters;
+
+        // Obtain the sound
+        FMOD::Sound* sound = (FMOD::Sound*)props->sound;
+
+        // Release the sound
+        sound->release();
+    }
+}
+
+ +

When the programmer instrument is untriggered, either by the instrument no longer meeting its conditions in the event instance or by the event instance stopping, it fires the FMOD_STUDIO_EVENT_CALLBACK_DESTROY_PROGRAMMER_SOUND callback. In the above code, when the programmer instrument is destroyed, it finds the FMOD::Sound passed into it and releases it, freeing the memory.

+

13.10 Playing Events

+

An event is an instanceable unit of sound content that can be triggered, controlled, and stopped from game code. Everything that produces a sound in a game should have a corresponding event.

+

An event contains and is composed of tracks, instruments, and parameters. The parameters trigger the instruments, which route audio content into the tracks. The tracks route into other tracks, or into the event's master track; The output of the event's master track routes into the project mixer. In addition, the event's parameters can control and manipulate most properties of the event, of the event's instruments and logic markers, and of effects on the event's tracks.

+

To play an event with the Studio API, typically you do the following:

+
    +
  1. Load a Studio::Bank containing the event you want to play, if one is not already loaded.
  2. +
  3. Get the Studio::EventDescription for the event you want to play. This can be done by either using Studio::System::getEvent or Studio::System::getEventbyID, or finding the event description in the list returned by Studio::Bank::getEventList.
  4. +
  5. Create an instance of the event with Studio::EventDescription::createInstance. This returns a handle to the new Studio::EventInstance, and causes the Studio system to begin loading the event's non-streaming sample data.
  6. +
  7. Play the event instance with Studio::EventInstance::start. This causes the event instance to begin playback, unless the event's sample data has not finished loading, in which case the event instance will start playback when loading has completed.
  8. +
  9. Release the event instance with Studio::EventInstance::release. This can be done at any point while the event is playing, and marks it to be destroyed by the Studio system when it is no longer playing, i.e. when it is no longer in the playback state FMOD_STUDIO_PLAYBACK_PLAYING.
  10. +
+

Generally, best practice is to release event instances immediately after starting them unless you want to continue to act on them in the future. For example, you may wish to play an instance multiple times, explicitly stop an instance and start it again later, or set an instance's parameters while it is still playing. This is because if the released event instance has stopped playing, it will be destroyed by the Studio system while you're still trying to act on it.

+

13.11 Event Callbacks

+

FMOD Studio allows you to specify a callback function to call when various state changes occur in an event instance. See FMOD_STUDIO_EVENT_CALLBACK_TYPE for the full list of callbacks available. The callback can be set automatically for all new instances of an event using Studio::EventDescription::setCallback, or it can be set manually for individual event instances using Studio::EventInstance::setCallback.

+

Some callbacks may be fired asynchronously on a thread owned by FMOD, depending on Studio initialization flags.

+

When Studio has been initialized in asynchronous mode (the default mode), callbacks are fired from the Studio asynchronous thread as they occur.

+

If Studio has been initialized with FMOD_STUDIO_INIT_DEFERRED_CALLBACKS then the FMOD_STUDIO_EVENT_CALLBACK_TIMELINE_MARKER and
+FMOD_STUDIO_EVENT_CALLBACK_TIMELINE_BEAT callbacks will be fired from the next call to Studio::System::update.

+

If Studio has been initialized with FMOD_STUDIO_INIT_SYNCHRONOUS_UPDATE then all callbacks will be fired from the next call to Studio::System::update.

+

See Also: Callback Behavior

+

13.12 Setting Parameters

+

Parameters are used to control the behavior of events, snapshots, and the mixer at run time.

+

In FMOD Studio, parameters can be used to affect various behaviors, such as automating event, snapshot, and mixer properties, and acting as a trigger condition for instruments and logic markers. Parameter values can then be set at run time using the Studio API, causing automated properties to change, and dependent behaviour to trigger when trigger conditions are met.

+

Parameters can exist locally or globally. Local parameters exist on a per-event instance basis; each event instance that uses a given parameter has a single instance of that parameter, the value of which is independent from all other instances of the same parameter. A global parameter only ever has a single instance, which is shared between all events that make use of it, as well as the mixer.

+

Local parameters can be set using the following Studio::EventInstance functions:

+ +

Global parameters can be set using the following Studio::System functions:

+ +

Parameters can be set by name (case-insensitive), or by ID. A parameter's ID, FMOD_STUDIO_PARAMETER_ID, can be found in its corresponding FMOD_STUDIO_PARAMETER_DESCRIPTION. A parameter's ID is not that same as its GUID, and parameter values cannot be set using GUIDs. For local parameters, parameter descriptions can be retrieved using the following Studio::EventDescription functions:

+ +

Likewise, similar functions can be called from Studio::System for global parameters:

+ +

For more information about parameters, see the Parameters chapter of the FMOD Studio User Manual.

+

13.13 Spatialization (3D)

+

Audio spatialization is the process of taking an audio signal and making it sound "in the world". For more information, see the Studio API 3D Events chapter.

+

13.13.1 Spatial Audio in FMOD Studio

+

All of the functionality described in the [Spatial Audio] section of the Core API Spatializing Sounds chapter is also available in FMOD Studio. For detailed information about the individual components and their visual representations, read the FMOD Studio User Manual; for a quick overview of where each feature may be found, see below.

+

Output mode selection: Edit -> Preferences -> Output Device, set Windows Sonic.

+
    +
  • 7.1.4 output: Window -> Mixer, select "Master Bus", right click "out" on the deck, set Surround 7.1.4.
  • +
  • Height control: Use the "height" slider that is part of the deck panner on any bus configured as 7.1.4.
  • +
  • Object spatialization: Right click the deck for any event, Add effect -> FMOD Object Spatializer.
  • +
  • Resonance Audio spatialization: Right click the deck for any event, Add effect -> Plug-in effects -> Google -> Resonance Audio Source.
  • +
+

Note: When using Windows Sonic output you must first be running Windows 10 Creators Update. You must also configure it for your audio device. Right click the speaker icon in the system tray -> Playback devices -> Right click your default device -> Properties -> Spatial sound -> Spatial sound format, now choose your desired spatial technology. FMOD will use your default output device with the technology you select here.

+

13.14 Working with Reverb

+

Reverb in the Studio API can be handled in two ways. The first is to add reverb effects to the master bus or individual events, and to control the levels sent to those effects using FMOD Studio. The second approach is to use the core reverb system.

+

The core system has four user configurable 3d reverbs. FMOD Studio event instances can interact with the core reverb system by sending their signal to the core reverbs. The send level can be set with Studio::EventInstance::setReverbLevel and queried with Studio::EventInstance::getReverbLevel.

+

13.15 Signal Paths

+

Each event or bus has a signal path to the master bus or a port bus. The signal path is composed of all buses that receive a signal from the event or bus. This includes any buses on the direct path to the master bus as well as any buses that are targeted by sends.

+

By default, when an event instance is created, the system ensures that every bus on its signal path has a corresponding ChannelGroup. When an event instance is destroyed, the system destroys any ChannelGroups which are no longer required.

+

You can override the default behavior by calling Studio::Bus::lockChannelGroup. This forces the system to ensure the ChannelGroup exists for that bus and each bus on its signal path. The system cannot destroy any of these ChannelGroups until you call Studio::Bus::unlockChannelGroup.

+ + +
+ + + diff --git a/FMOD/doc/FMOD API User Manual/style/DINWeb-Medium.woff b/FMOD/doc/FMOD API User Manual/style/DINWeb-Medium.woff new file mode 100644 index 0000000..5c098af Binary files /dev/null and b/FMOD/doc/FMOD API User Manual/style/DINWeb-Medium.woff differ diff --git a/FMOD/doc/FMOD API User Manual/style/DINWeb.woff b/FMOD/doc/FMOD API User Manual/style/DINWeb.woff new file mode 100644 index 0000000..5aaa4b8 Binary files /dev/null and b/FMOD/doc/FMOD API User Manual/style/DINWeb.woff differ diff --git a/FMOD/doc/FMOD API User Manual/style/code_highlight.css b/FMOD/doc/FMOD API User Manual/style/code_highlight.css new file mode 100644 index 0000000..631bc92 --- /dev/null +++ b/FMOD/doc/FMOD API User Manual/style/code_highlight.css @@ -0,0 +1,69 @@ +.highlight .hll { background-color: #ffffcc } +.highlight { background: #f8f8f8; } +.highlight .c { color: #408080; font-style: italic } /* Comment */ +.highlight .err { border: 1px solid #FF0000 } /* Error */ +.highlight .k { color: #008000; font-weight: bold } /* Keyword */ +.highlight .o { color: #666666 } /* Operator */ +.highlight .ch { color: #408080; font-style: italic } /* Comment.Hashbang */ +.highlight .cm { color: #408080; font-style: italic } /* Comment.Multiline */ +.highlight .cp { color: #BC7A00 } /* Comment.Preproc */ +.highlight .cpf { color: #408080; font-style: italic } /* Comment.PreprocFile */ +.highlight .c1 { color: #408080; font-style: italic } /* Comment.Single */ +.highlight .cs { color: #408080; font-style: italic } /* Comment.Special */ +.highlight .gd { color: #A00000 } /* Generic.Deleted */ +.highlight .ge { font-style: italic } /* Generic.Emph */ +.highlight .gr { color: #FF0000 } /* Generic.Error */ +.highlight .gh { color: #000080; font-weight: bold } /* Generic.Heading */ +.highlight .gi { color: #00A000 } /* Generic.Inserted */ +.highlight .go { color: #888888 } /* Generic.Output */ +.highlight .gp { color: #000080; font-weight: bold } /* Generic.Prompt */ +.highlight .gs { font-weight: bold } /* Generic.Strong */ +.highlight .gu { color: #800080; font-weight: bold } /* Generic.Subheading */ +.highlight .gt { color: #0044DD } /* Generic.Traceback */ +.highlight .kc { color: #008000; font-weight: bold } /* Keyword.Constant */ +.highlight .kd { color: #008000; font-weight: bold } /* Keyword.Declaration */ +.highlight .kn { color: #008000; font-weight: bold } /* Keyword.Namespace */ +.highlight .kp { color: #008000 } /* Keyword.Pseudo */ +.highlight .kr { color: #008000; font-weight: bold } /* Keyword.Reserved */ +.highlight .kt { color: #B00040 } /* Keyword.Type */ +.highlight .m { color: #666666 } /* Literal.Number */ +.highlight .s { color: #BA2121 } /* Literal.String */ +.highlight .na { color: #7D9029 } /* Name.Attribute */ +.highlight .nb { color: #008000 } /* Name.Builtin */ +.highlight .nc { color: #0000FF; font-weight: bold } /* Name.Class */ +.highlight .no { color: #880000 } /* Name.Constant */ +.highlight .nd { color: #AA22FF } /* Name.Decorator */ +.highlight .ni { color: #999999; font-weight: bold } /* Name.Entity */ +.highlight .ne { color: #D2413A; font-weight: bold } /* Name.Exception */ +.highlight .nf { color: #0000FF } /* Name.Function */ +.highlight .nl { color: #A0A000 } /* Name.Label */ +.highlight .nn { color: #0000FF; font-weight: bold } /* Name.Namespace */ +.highlight .nt { color: #008000; font-weight: bold } /* Name.Tag */ +.highlight .nv { color: #19177C } /* Name.Variable */ +.highlight .ow { color: #AA22FF; font-weight: bold } /* Operator.Word */ +.highlight .w { color: #bbbbbb } /* Text.Whitespace */ +.highlight .mb { color: #666666 } /* Literal.Number.Bin */ +.highlight .mf { color: #666666 } /* Literal.Number.Float */ +.highlight .mh { color: #666666 } /* Literal.Number.Hex */ +.highlight .mi { color: #666666 } /* Literal.Number.Integer */ +.highlight .mo { color: #666666 } /* Literal.Number.Oct */ +.highlight .sa { color: #BA2121 } /* Literal.String.Affix */ +.highlight .sb { color: #BA2121 } /* Literal.String.Backtick */ +.highlight .sc { color: #BA2121 } /* Literal.String.Char */ +.highlight .dl { color: #BA2121 } /* Literal.String.Delimiter */ +.highlight .sd { color: #BA2121; font-style: italic } /* Literal.String.Doc */ +.highlight .s2 { color: #BA2121 } /* Literal.String.Double */ +.highlight .se { color: #BB6622; font-weight: bold } /* Literal.String.Escape */ +.highlight .sh { color: #BA2121 } /* Literal.String.Heredoc */ +.highlight .si { color: #BB6688; font-weight: bold } /* Literal.String.Interpol */ +.highlight .sx { color: #008000 } /* Literal.String.Other */ +.highlight .sr { color: #BB6688 } /* Literal.String.Regex */ +.highlight .s1 { color: #BA2121 } /* Literal.String.Single */ +.highlight .ss { color: #19177C } /* Literal.String.Symbol */ +.highlight .bp { color: #008000 } /* Name.Builtin.Pseudo */ +.highlight .fm { color: #0000FF } /* Name.Function.Magic */ +.highlight .vc { color: #19177C } /* Name.Variable.Class */ +.highlight .vg { color: #19177C } /* Name.Variable.Global */ +.highlight .vi { color: #19177C } /* Name.Variable.Instance */ +.highlight .vm { color: #19177C } /* Name.Variable.Magic */ +.highlight .il { color: #666666 } /* Literal.Number.Integer.Long */ \ No newline at end of file diff --git a/FMOD/doc/FMOD API User Manual/style/docs.css b/FMOD/doc/FMOD API User Manual/style/docs.css new file mode 100644 index 0000000..b081522 --- /dev/null +++ b/FMOD/doc/FMOD API User Manual/style/docs.css @@ -0,0 +1,380 @@ +@font-face { + font-family:'DINWeb-Medium'; + src:url('DINWeb-Medium.woff'); +} + +@font-face { + font-family:'DINWeb'; + src:url('DINWeb.woff'); +} + +body { + background-color: black; +} + +.docs-body { + font-family: DINWeb-Medium, -apple-system, sans-serif; + background-color: black; + padding: 24px; + margin-left: auto; + margin-right: auto; + max-width: 100%; + line-height: 24px; +} + +.docs-body a { + color: #020eab; + text-decoration: none; + font-weight: bold; +} +.docs-body .apilink { + font-family: monospace; + font-size: 17px; + letter-spacing: -0.5px; +} + +.manual-content h1 a, +.manual-content h2 a, +.manual-content h3 a, +.manual-content h4 a, +.manual-content h5 a, +.manual-content h6 a { + color: black; +} + +.docs-body img { + max-width: 100%; + box-shadow: 0px 4px 20px #333333; + margin: 20px; +} + +.admonition { + border: 1px solid #b3b3b3; + border-top: 4px solid black; + background-color: #f1f1f1; + padding: 3px; +} + +.admonition.warning { + border-top: 4px solid #cc0000; +} + +.highlight { + border: 1px solid #b3b3b3; + background-color: #f1f1f1; + overflow: auto; + padding: 6px; +} + +.highlight pre { + margin: 0; +} + +code { + background-color: #eeeeee; + color: black; +} + +pre code { + display: block; + padding: 5px; + overflow: auto; +} + +blockquote { + background-color: #eeeeee; + margin: 0px; + padding: 15px; +} + +ol li ol { + list-style-type: lower-alpha; +} + + +.manual-toc { + color: black; + background-color: #d6dceb; + font-weight: bold; + + display: block; + float: right; + width: 20%; + min-width: 300px; + top: 0; + z-index: 10000; + margin-left: 20px; +} + +@media (max-width: 600px) { + .manual-content { + position: static; + min-width: 0; + padding: 20px 30px 20px !important; + } + .manual-toc { + float: none; + width: auto; + min-width: 0; + margin-left: 0; + margin-right: 0; + } +} + +@media (min-width: 601px) and (max-width: 992px) { + .manual-content { + position: static; + min-width: 0; + } + .manual-toc { + float: none; + width: auto; + min-width: 0; + margin-left: 0; + margin-right: 0; + } +} + +@media (min-width: 993px) and (max-width: 1367px) { + body { + margin-left: 24px; + margin-right: 24px; + max-width: 100%; + } + .manual-content { + min-width: 300px; + } + .manual-toc { + float: right; + max-width: 300px; + min-width: 100px; + width: auto; + padding-left: 1em; + padding-right: 1em; + } +} + +.manual-toc p { + color: black; + font-size: larger; + text-align: center; + margin-top: 0; + margin-bottom: 0; + padding-top: 1em; +} + +.manual-toc > ul { + padding: 0px; + margin-block-start: 1em; +} + +.manual-toc > ul > li { + padding: 12px; + list-style-position: inside; +} + +.manual-toc ul { list-style-type: none; } +.manual-toc ul { counter-reset: toc-level-1; } +.manual-toc li { counter-increment: toc-level-1; } +.manual-toc li > a:before { content: counter(toc-level-1)". "; } +.manual-toc li ul { counter-reset: toc-level-2; } +.manual-toc li li { counter-increment: toc-level-2; } +.manual-toc li li a:before { content: counter(toc-level-1)"."counter(toc-level-2)" "; } +.manual-toc li li ul { counter-reset: toc-level-3; } +.manual-toc li li li { counter-increment: toc-level-3; } +.manual-toc li li li a:before { content: counter(toc-level-1)"."counter(toc-level-2)"."counter(toc-level-3)" "; } +.manual-inactive-chapter li ul { display: none; } + +.manual-current-chapter { + background-color: white; +} + +.manual-current-chapter ul { + padding-left: 20px; +} + +.manual-active-chapter > a { + color: black; +} + +.manual-current-chapter > ul { margin-top: 10px; } +.manual-current-chapter li { padding-top: 10px; font-size: 14px; } +.manual-current-chapter > ul > li:first-child { padding-top: 0px; } + +.manual-current-chapter li > ul > li > ul { + display: none; +} + +ul.subchapters { border-left: 2px dotted #b3b3b3; } +ul.subchapters li > a:before { content: ""; } +ul.subchapters .manual-active-chapter > a { border-bottom: 2px solid black; } + +.manual-content { + background-color: white; + overflow: hidden; + padding: 20px 50px 40px; +} + +.manual-content li { + margin: 0.5em 0; +} + +.manual-content h2 { + margin: 1.5em 0 1em 0; +} + +.manual-content table { + margin-bottom: 1.5em; + width: 100%; + border-collapse: collapse; + display: block; + overflow-x: auto; +} + +.manual-content th { + background-color: #d6dceb; +} + +.manual-content th, .manual-content td { + border: 1px solid #b3b3b3; + padding: 12px; + text-align: left; +} + +.manual-content td img { + margin: initial; + box-shadow: initial; +} + +.manual-content img + br + em { + display: block; + margin-left: 20px; + margin-bottom: 2em; +} + +.manual-content.api dt { + font-weight: initial; + font-style:italic; + margin-bottom: 1em; +} + +.manual-content.studio dt { + margin-bottom: 1em; +} + +/* Exclude token links (e.g. "Optional", "Output") - TODO: these need proper styling */ +.manual-content.api dt a.token { + font-style:initial; +} + +.manual-content.studio p { + line-height: 24px; +} + +.manual-content.api dd { + margin-bottom: 1em; + margin-inline-start: 40px; +} + +.manual-content.studio dd { + line-height: 24px; + margin-inline-start: 24px; + margin-bottom: 1em; +} + +.manual-content.api dd ul { + margin: 0; + padding: 0.75em 0 0.5em 1em; + font-family: DINWeb; + border: 1px solid #b3b3b3; + width:max-content; +} + +.manual-content.api dd ul li { + margin: 0; + margin-right: 1em; + display: inline; +} + +.manual-content.api dd ul li .label { + font-weight: bold; +} + +.manual-content.api dd p { + margin: 0.25em; +} + +.manual-footer { + color: white; + padding: 20px; + font-size: smaller; +} + +div.language-selector { + display: -webkit-flex; + display: flex; + text-align: center; +} + +div.language-tab { + -webkit-flex: 1; + -ms-flex: 1; + flex: 1; + border: 1px solid #bbbbbb; + border-top-left-radius: 6px; + border-top-right-radius: 6px; + box-sizing: content-box; + max-width: 30px; + padding: 2px 10px; + margin-right: -1px; + margin-bottom: -1px; + cursor: pointer; +} + +.language-tab:hover { + background-color: #d6dceb; +} + +.language-tab.selected { + background-color: #f1f1f1; + border-bottom-width: 0; +} + +.language-tab.selected:after { + content: ''; + width: 100%; + height: 3px; + bottom: -1px; + left: 0; + background: inherit; +} + +div.language-selector + p { + display: none; +} + +a.token, .token { + padding: 6px; + margin-left: 8px; + color: black; + font-size: small; + font-weight: normal; + border: 1px solid #bbbbbb; + border-radius: 6px; +} + +a.token:hover { + background-color: #d6dceb; +} + +[id]:target { animation:highlighter 3s } +@keyframes highlighter { 25% { background-color: gold; } 75% { background-color: gold; } } + +.mixdowntable table { + white-space: nowrap; +} + +.mixdowntable table td, .mixdowntable table th { + min-width: 4em; + text-align: center; +} \ No newline at end of file diff --git a/FMOD/doc/FMOD API User Manual/troubleshooting.html b/FMOD/doc/FMOD API User Manual/troubleshooting.html new file mode 100644 index 0000000..4fb6927 --- /dev/null +++ b/FMOD/doc/FMOD API User Manual/troubleshooting.html @@ -0,0 +1,78 @@ + + +Troubleshooting + + + + +
+ +
+

21. Troubleshooting

+

This chapter lists a number of common issues that can be encountered while working with the Core API and Studio API, along with techniques for overcoming them.

+

If you encounter a problem, and none of the techniques listed in this chapter help, post a question on the FMOD Forums for advice and support.

+

21.1 Audio becomes crackly or distorted over time

+

If you are finding the output of your application is starting to crackle or become distorted when playing for a long time, it is likely there are too many processes using up CPU usage. This can be due to too many large complex events playing at once, too many expensive DSPs in use such as convolution reverbs, or an excessive build up of events.

+

To visualize the audio CPU and memory usage of your application, you can record a Live Update profiler session in your FMOD Studio project, or if using the Core API only, utilize the FMOD Profiler provided with the API installation. This will assist in tracking down exactly where the resources are being used.

+

For Studio API users, some common issues that can cause a build up of events are:

+ +

21.2 The FMOD Engine cannot find events or buses with strings

+

This usually happens because the .strings.bank file has not been loaded. The error FMOD_ERR_EVENT_NOTFOUND would be logged to the game engine's debug logger. The .strings.bank file includes all the metadata required to look up events, buses, snapshots, and VCAs during runtime.

+

Refer to What Building Creates in the FMOD Studio User Manual, for more information on what a strings.bank file contains.

+

21.3 An error is being returned from an FMOD function and I need more detail

+

All Core API and Studio API functions return a FMOD_RESULT. This result is FMOD_OK if the function works as expected, or an error error code describing the problem. You can find a list of all possible errors in the documentation for FMOD_RESULT.

+

If further debugging is required, you can initialize the Studio API or Core API using the logging or "L" version of the respective library, i.e.: fmodstudioL.dll or fmodL.dll. To modify the amount of logging or the way it is displayed, see Debug_Initialize.

+

21.4 My audio device does not change automatically

+

FMOD has an automatic device switching feature which is enabled by default.

+

A reason for this not to work is that an FMOD_SYSTEM_CALLBACK_DEVICELISTCHANGED callback has been registered. This callback disables the automatic device switching feature on purpose, as it assumes you will be controlling which device gets selected in the callback.

+

21.5 Pointers returned by the FMOD Engine are behaving strangely

+

The Studio API and Core API return pointers to types. Some of these types are actually implemented as an underlying handle, but represent the handle data as a pointer type. For information about specific objects' underlying representation and lifetimes, see the Channel Groups and Routing section of the Core API Mixing and Routing chapter, the Initializing the Core API section of the Core API Getting Started chapter, and the Studio API Types section of this chapter.

+

All FMOD types, whether they are represented internally via pointer or handle, look like a pointer type. No matter the type, a null pointer can never be returned as a valid result, but it is not safe to assume anything else about the pointer value. Do not assume that the pointer value falls in any particular address range, or that it has any zero bits in the bottom of the pointer value address.

+

All FMOD types are equivalent for both the C and C++ API. It is possible to cast between the appropriate types by re-interpreting the pointer type directly.

+

21.5.1 Studio API Types

+

Studio API types are returned as pointers, but actually consist of packed handle data. If the underlying type has been destroyed then the API returns FMOD_ERR_INVALID_HANDLE. An example of this would be unloading a Studio::Bank and then referencing a Studio::EventDescription belonging to that bank.

+ + +
+ + + diff --git a/FMOD/doc/FMOD API User Manual/using-dsp-effects-in-the-core-api.html b/FMOD/doc/FMOD API User Manual/using-dsp-effects-in-the-core-api.html new file mode 100644 index 0000000..1fd6e59 --- /dev/null +++ b/FMOD/doc/FMOD API User Manual/using-dsp-effects-in-the-core-api.html @@ -0,0 +1,378 @@ + + +Core API Using DSP Effects + + + + +
+ +
+

7. Core API Using DSP Effects

+

The Core API has native/built in code to support many special effects out of the box, such as low-pass, compressor, reverb and multiband EQ. A more comprehensive list can be found in the FMOD_DSP_TYPE list.

+

An effect can be created with System::createDSPByType and added to a Channel or ChannelGroup with ChannelControl::addDSP.

+

The Core API runs on a modular synth architecture, which allows connections of signal processing nodes (the 'FMOD DSP' concept).

+

A directed graph processing tree allows the signal to flow from 'generators' at the tail node (a Sound playing through from System::playSound, or a DSP creating sound from System::playDSP for example), to other nodes, mixing together until they reach the head node, where the final result is sent to the sound card.

+

DSP Graph example

+

A visual representation taken directly from the FMOD Profiler.

+

FMOD typically processes the Sound in the graph, in blocks of 512 samples (10ms) on some platforms, or 1024 on other platforms (21ms). This is the granularity of the system, and affects how smooth parameter changes, such as pitch or volume will heard.

+

FMOD pre-built DSP effects can be inserted into the graph with functions like DSP::addInput and DSP::disconnectFrom.

+

For detailed information, see the DSP Architecture and Usage section of the Using DSP Effects in the Core API chapter.

+

7.1 DSP Architecture and Usage

+

This section will introduce you to the FMOD Engine's DSP system. With this system you can implement custom filters or create complicated signal chains to create high quality and dynamic sounding audio. The DSP system is an incredibly flexible mixing engine that has an emphasis on quality, flexibility and efficiency, and makes it an extremely powerful system when used to its full potential.

+

The figure below shows a representation of what a very basic FMOD DSP graph looks like.

+

DSP Network

+

Audio data flows from the right to the left, tail to head, until it finally arrives at the soundcard, fully mixed and processed.

+
    +
  • A blue box is a DSP unit. This unit is represented by the DSP class in the Core API header.
  • +
  • A line between the boxes, is an DSPConnection. This is what links the DSP units together into a DSP graph. Each DSPConnection has a pan matrix which you can use to configure the mapping from input speakers/channels to output speakers/channels.
  • +
  • The green vertical bars inside the grey bars are detected signal levels. You can see that the WaveTable unit produces a mono signal, that mono signal continues through the Channel Fader (untouched) then gets upmixed to 6 channels (5.1). Because the default pan for a mono sound to a 5.1 output is to have the mono signal attenuated by 3db to the Front Left speaker, and the signal attenuated by 3db to the Front Right speaker, you can see that the 6 grey bars have only signal in the first 2 speaker levels. See FMOD_SPEAKER for the speaker order, represented by those bars. Note: Since FMOD Engine version 1.04.08, the upmix happens internally, beyond the master ChannelGroup's fader; so for the purposes of this tutorial, the master ChannelGroup's fader has been forced to FMOD_SPEAKERMODE_5POINT1 so that it can be visualized. More about channel formats can be read below in the "Set the output format of a DSP unit, and control the pan matrix for its output signal" section.
  • +
+

The above image, excluding the annotation, was taken using the FMOD Profiler. You can profile your own DSP graph as long as you specify FMOD_INIT_PROFILE_ENABLE when initializing the Core API. The tool is located in the /bin directory of the SDK.

+

7.1.1 Some common units in a DSP graph

+

This section will describe the units in more detail, from the origin of the data through to the soundcard, from right to left. The following list describes some of the typical DSP units you will see in a graph.

+
    +
  • Wavetable Unit This unit reads raw PCM data from the sound buffer and resamples it to the system sample rate. A Wavetable Unit is only connected when the user calls System::playSound. Once resampled, the audio data is then processed (or flows) at the rate of the system sample rate. The system sample rate is 48khz by default or 24khz on iOS and Android, but can be manually set to a different value using System::setSoftwareFormat.
  • +
  • DSPCodec Unit This unit reads decodes compressed data from an FMOD Codec, and passes it to a built in resampler, and then passes the decompressed result to the output.
  • +
  • Channel Fader This unit provides a top level unit for a Channel to hold onto, and is a place to insert effects for a Channel. A Channel Fader also controls the volume level of a Channel, for example if the user calls ChannelControl::setVolume.
  • +
  • ChannelGroup Fader This unit provides a top level unit for a ChannelGroup to hold onto, and is a place to insert effects for a ChannelGroup. A ChannelGroup Fader also controls the volume level of a Channel, for example if the user calls ChannelControl::setVolume.
  • +
+

When FMOD plays a PCM sound on a Channel (using System::playSound), it creates a small sub-graph consisting of a fader and a Wavetable Unit. This would also happen if playing a stream, even if the source data is compressed.

+

When FMOD plays a compressed sound on a Channel (MP3/Vorbis/XMA/ADPCM usually, loaded with FMOD_CREATECOMPRESSEDSAMPLE), it creates a similar small sub-graph consisting of a Fader and a DSPCodec Unit.

+

When FMOD plays a DSP on a Channel (using System::playDSP), it creates a small sub-graph consisting of a Fader and a standalone Resampler Unit. The DSP that was specified by the user executed by the resampler as a sub-graph to the resampler, and is not visible on the profiler.

+

7.1.2 Watch a DSP graph get built (with code examples)

+

Start off with nothing, then play some sounds

+

In this section we will look at some basic techniques that can be used to manipulate DSP graphs. We shall start with the most basic signal chain (as shown in the image below) and identify the changes that occur to the DSP graph with the provided code.

+

DSP Network

+

Note that the graph only exists of 1 unit, the Master ChannelGroup's DSP Fader Unit (FMOD_DSP_TYPE_FADER). This unit can be used to control the mix output of the entire mix if desired.

+

Now we shall play a PCM sound with System::playSound.

+

DSP Network

+

Note that the sub-graph of a DSP Fader unit (FMOD_DSP_TYPE_FADER), and a system level DSP WaveTable unit have been attached to the Master ChannelGroup's DSP Fader unit.

+

Let's play the sound again, resulting in 2 channels being active.

+

DSP Network

+

Note now that the new Channel targets the same Master ChannelGroup DSP Fader unit, and when 2 lines merge into 1 unit, a 'mix' happens. This is just a summing of the 2 signals together.

+

Add a DSP effect to a Channel

+

In this example we shall add an effect to a sound by connecting a DSP effect unit to the Channel. The code below starts by playing a sound, then creates a DSP unit with System::createDSPByType and adds it to the DSP graph using ChannelControl::addDSP.

+
FMOD::Channel *channel;
+FMOD::DSP *dsp_echo;
+result = system->playSound(sound, 0, false, &channel);
+result = system->createDSPByType(FMOD_DSP_TYPE_ECHO, &dsp_echo);
+result = channel->addDSP(0, dsp_echo);
+
+ +

The figure below shows the FMOD Echo effect inserted at the 'Channel head' or position 0, as specified with the ChannelControl::addDSP command (position = 0). The Channel Fader which used to be the head unit, is now shuffled down to position 1.

+

DSP Network

+

If we call ChannelControl::setDSPIndex

+
result = channel->setDSPIndex(dsp_echo, 1);
+
+ +

We can see below, that the echo has now moved down one, and Channel Fader is back at position 0.

+

DSP Network

+

Create a new ChannelGroup and add our Channel to it
+In this example we shall introduce ChannelGroups which are effectively used as sub-mix buses. We can add an effect to a ChannelGroup and if Channels are assigned to that ChannelGroup, all Channels will be affected by any DSP inserted into a ChannelGroup.

+

These ChannelGroups can then be nested and manipulated to create hierarchical mixing.

+
result = system->createChannelGroup("my channelgroup", &channelgroup);
+result = channel->setChannelGroup(channelgroup);
+
+ +

DSP Network

+

We can now see the newly created ChannelGroup as a stand-alone DSP ChannelGroup Fader between the channel on the right and the Master ChannelGroup Fader on the left.

+

Add an effect to the ChannelGroup

+

Adding an effect to a ChannelGroup is the same as adding one to a Channel. Use ChannelControl::addDSP.

+
FMOD::DSP *dsp_lowpass;
+result = system->createDSPByType(FMOD_DSP_TYPE_LOWPASS, &dsp_lowpass);
+result = channelgroup->addDSP(1, dsp_lowpass);
+
+ +

DSP Network

+

We can now see as before, an effect attached to a ChannelGroup Fader, in position 1, the entirety of the ChannelGroup being symbolized by the box around the 2 units.

+

Creating an effect and making all Channels send to it.

+

This example demonstrates a more complex, and somewhat typical scenario, in which we create a new effect, and every time a Sound plays on a Channel, we connect the new channel to the effect.

+

Important note! Please don't use this example as a standard way to set up reverb. Simply call System::setReverbProperties instead and all connection logic is handled automatically. Note the following logic does not handle what happens when a Channel goes virtual and is removed from the graph, only to return later. You would only normally use this logic if you wanted to control the 'wet' mix levels indivudually for an effect, per channel. Otherwise a simple ChannelControl::addDSP would suffice.

+

The first step is to add an effect to the master ChannelGroup. We do this by calling System::createDSPByType again, and then using the DSP API to manually add connections.

+
FMOD::DSP *dsp_reverb;
+FMOD::DSP *dsp_tail;
+FMOD::ChannelGroup *channelgroup_master;
+result = system->createDSPByType(FMOD_DSP_TYPE_SFXREVERB, &dsp_reverb);             /* Create the reverb DSP */
+result = system->getMasterChannelGroup(&channelgroup_master);                       /* Grab the master ChannelGroup / master bus */
+result = channelgroup_master->getDSP(FMOD_CHANNELCONTROL_DSP_TAIL, &dsp_tail);      /* Grab the 'tail' unit for the master ChannelGroup.  This is the last DSP unit for the ChannelGroup, in case it has other effects already in it. */
+result = dsp_tail->addInput(dsp_reverb);
+
+ +

This will result in

+

DSP Network

+

Note that the ChannelGroup from before is still there. This is what the Channels will be playing on. The reason we have a ChannelGroup here for this example is to keep the Channels executing first in the graph, then the reverb second. This raises a topic called 'order of execution' which you can find more information about below and why it may or may not be important to you.

+

Also note that the reverb is black. This means it is inactive / disabled. All units are inactive by default, so we have to activate them. You can do this with DSP::setActive.

+
result = dsp_reverb->setActive(true);
+
+ +

DSP Network

+

Now you can see that the reverb has gone from black/inactive to active.

+

Now we will play a sound on multiple channels with the following code. The code plays the sound paused, gets its Channel DSP head unit, adds the Channel DSP head unit to the reverb, then unpauses the sound.

+
FMOD::DSP *channel_dsp_head;
+result = system->playSound(sound, channelgroup, true, &gChannel[0]);                /* Play the sound.  Play it paused so we dont hear the sound play before it is connected to the reverb. */
+result = channel->getDSP(FMOD_CHANNELCONTROL_DSP_HEAD, &channel_dsp_head);          /* Grab the 'head' unit for the Channel */
+result = dsp_reverb->addInput(channel_dsp_head);                                    /* Manually add a connection from the Channel DSP head to the reverb. */
+result = channel->setPaused(false);                                                 /* Unpause the channel and let it be audible. */
+
+ +

Note that calling ChannelControl::setPaused internally just calls DSP::setActive on the Channel's head DSP unit.

+

Here is the result

+

DSP Network

+

The interesting parts here are that the Channel DSP head units now have 2 outputs per channel, and each set of outputs mix to the user created ChannelGroup first, before being passed as the 'dry' signal to the output. The second set of outputs can be considered the 'wet' path and similarly mix to the reverb unit, before being processed by the reverb processor.

+

Controlling mix level and pan matrices for DSPConnections

+

Each connection between a DSP unit is represented by a DSPConnection object. This is the line between the boxes.

+

The primary purpose of this object type is to allow the user to control the volume / mix level between 2 processing units, and also to control the speaker / channel mapping between 2 units, so that a signal can be panned, and input signals mapped to any output signal, in any way that is needed.

+

Lets go back to the example above, but with 1 channel, and change its wet mix from the Channel to the reverb from 1.0 (0db) to 0.0 (-80db)

+

The code around the playsound would have one difference, and that is that addInput will also take a pointer to the resulting DSPConnection object.

+
FMOD::DSP *channel_dsp_head;
+FMOD::DSPConnection *dsp_connection;
+result = system->playSound(sound, channelgroup, true, &gChannel[0]);                /* Play the sound.  Play it paused so we dont hear the sound play before it is connected to the reverb. */
+result = channel->getDSP(FMOD_CHANNELCONTROL_DSP_HEAD, &channel_dsp_head);          /* Grab the 'head' unit for the Channel */
+result = dsp_reverb->addInput(channel_dsp_head, &dsp_connection);                   /* Manually add a connection from the Channel DSP head to the reverb. */
+result = channel->setPaused(false);                                                 /* Unpause the channel and let it be audible. */
+
+ +

We can then update the volume simply with DSPConnection::setMix.

+
result = dsp_connection->setMix(0.0f);
+
+ +

DSP Network

+

You can see there is no signal level in the meter for the reverb, because the only input to it is silent.

+

Set the output format of a DSP unit, and control the pan matrix for its output signal

+

In this section we will grab the first output from the channel_dsp_head and apply a pan matrix to it, to allow mapping of input signal to any output speaker within the mix.

+

The first thing to note, is that the Channel Fader outputs mono to the ChannelGroup Fader. This means there's not much to map from and to here. Any matrix representing this signal will be 1 in and 1 out.

+

To make it more interesting, we can change the output format of a DSP Unit with DSP::setChannelFormat.

+
result = channel_dsp_head->setChannelFormat(0, 0, FMOD_SPEAKER_QUAD);
+
+ +

Here is the result

+

DSP Network

+

You will notice that the ChannelFader now outputs 4 channels, and this gets propagated through the graph. A Quad to 5.1 pan has a different default upmix than mono to 5.1, so you will see that the fronts are now slightly lower on the final ChannelGroup Fader unit, and there is some signal now introduced into the Surround Left and Surround Right speakers. Now we will use some code to do something interesting, we will put the newly quad ChannelFader signal's front 2 channels into the rear 2 speakers of the quad output.

+
FMOD::DSPConnection *channel_dsp_head_output_connection;
+float matrix[4][4] =
+{   /*                                    FL FR SL SR <- Input signal (columns) */
+    /* row 0 = front left  out    <- */ { 0, 0, 0, 0 },     
+    /* row 1 = front right out    <- */ { 0, 0, 0, 0 },     
+    /* row 2 = surround left out  <- */ { 1, 0, 0, 0 },     
+    /* row 3 = surround right out <- */ { 0, 1, 0, 0 }      
+};
+result = channel_dsp_head->getOutput(0, 0, &channel_dsp_head_output_connection);
+result = channel_dsp_head_output_connection->setMixMatrix(&matrix[0][0], 4, 4);
+
+ +

DSP Network

+

We can now see that the first 2 channels are now silent on the output because they have 0s in the matrix where the first 2 input columns map to the first 2 output columns.

+

Instead the first 2 input columns have 1s where the rows map to the surround left and surround right output speakers.

+

Bypass an effect / disable it.

+

To disable an effect simply use the setBypass method. The code below plays a sound, adds an effect then bypasses it.

+
result = dsp_reverb->setBypass(true);
+
+ +

This has the benefit of not disabling all input units like DSP::setActive with false as the parameter would, and allows the signal to pass through the reverb unit untouched (The reverb process function is not called, saving CPU).

+

DSP Network

+

The bypassed reverb is represented as greyed out.

+

Note that many FMOD effects automatically bypass themselves, saving CPU, after no signal, or silence is detected and the effective 'tail' of the effect has played out.

+

Order of execution and pull / no pull traversal

+

The order of execution for a DSP graph is from right to left, but also top to bottom. Units at the top will get executed before units at the bottom.

+

Sometimes it is undesirable to have a user created effect execute the DSP units for the channel, rather than the ChannelGroup it belongs to. This typically doesn't matter, but one case where it would matter is if the user called ChannelControl::setDelay on the channel or ChannelControl::setDelay on a parent ChannelGroup, to make the sound delay before starting.

+

The reverb unit has no concept of the delay because the clock it is delaying against is stored in the ChannelGroup it belongs to.

+

The result is that the reverb will pull the signal and be audible through the reverb processor, and the dry path will still be silent because it is in a delay state.

+

The workaround in the above reverb example, is to attach the reverb to the master ChannelGroup after the ChannelGroup the Channels will play on is created, so that the ChannelGroup executes first, and the reverb second.

+

'Send' vs 'Standard' connection type

+

A second workaround is to stop the reverb pulling data from its inputs. This can be done by using the FMOD_DSPCONNECTION_TYPE 'type' parameter for DSP::addInput. If FMOD_DSPCONNECTION_TYPE_SEND is used instead of FMOD_DSPCONNECTION_TYPE_STANDARD, the inputs are not executed, and all the reverb would do is process whatever is mixed to it from a previous traversal to the inputs.

+

The delay will then work, but the downside to this method is that if the reverb is first, the signal from the channels will be sent after the reverb has processed. This means it will have to wait until the next mix before it can process that data, therefore 1 mix block of latency is introduced to the reverb.

+

7.2 Plug-in DSP Effects

+

A plug-in DSP effect must be registered using the Core API before the object referencing the plug-in is loaded in the game.

+

The following functions can be used to register a plug-in if it is statically linked or compiled with the game code:

+
FMOD_RESULT FMOD::Studio::System::registerPlugin(const FMOD_DSP_DESCRIPTION* description);
+FMOD_RESULT FMOD::System::registerDSP(const FMOD_DSP_DESCRIPTION *description, unsigned int *handle);
+
+ +

If the plug-in library is to be dynamically loaded, it can be registered using:

+
FMOD_RESULT FMOD::System::loadPlugin(const char *filename, unsigned int *handle, unsigned int priority = 0)
+
+ +

A base plug-in path can be specified using the function:

+
FMOD_RESULT FMOD::System::setPluginPath(const char *path)
+
+ +

If this is set, the filename parameter of System::loadPlugin is assumed to be relative to this path.

+

Plug-ins do not normally need to be unregistered, but it is possible with either of the following functions:

+
FMOD_RESULT FMOD::Studio::System::unregisterPlugin(const char* name)
+FMOD_RESULT FMOD::System::unloadPlugin(unsigned int handle)
+
+ +

In these functions, name refers to the name of the plug-in defined in the plug-ins descriptor and handle refers to handle returned by System::loadPlugin.

+

7.2.1 The Plug-in Descriptor

+

The plug-in descriptor is a struct, FMOD_DSP_DESCRIPTION defined in fmod_dsp.h, which describes the capabilities of the plug-in and contains function pointers for all callbacks needed to communicate with FMOD. Data in the descriptor cannot change once the plug-in is loaded. The original struct and its data must stay around until the plug-in is unloaded as data inside this struct is referenced directly within FMOD throughout the lifetime of the plug-in.

+

The first member, FMOD_DSP_DESCRIPTION::pluginsdkversion, must always hold the version number of the plug-in SDK it was complied with. This version is defined as FMOD_PLUGIN_SDK_VERSION. The SDK version is incremented whenever changes to the API occur.

+

The following two members, FMOD_DSP_DESCRIPTION::name and FMOD_DSP_DESCRIPTION::version, identify the plug-in. Each plug-in must have a unique name, usually the company name followed by the product name. Version numbers should not be included in the name in order to allow for future migration of saved data across different versions. Names should not change across versions for the same reason. The version number should be incremented whenever any changes to the plug-in have been made.

+

Here is a code snippet from the FMOD Gain example which shows how to initialize the first five members of FMOD_DSP_DESCRIPTION:

+
FMOD_DSP_DESCRIPTION FMOD_Gain_Desc =
+{
+    FMOD_PLUGIN_SDK_VERSION,
+    "FMOD Gain",    // name
+    0x00010000,     // plug-in version
+    1,              // number of input buffers to process
+    1,              // number of output buffers to process
+    ...
+};
+
+ +

The other descriptor members will be discussed in the following sections.

+

7.2.2 Thread Safety

+

Audio callbacks FMOD_DSP_DESCRIPTION::read, FMOD_DSP_DESCRIPTION::process and FMOD_DSP_DESCRIPTION::shouldiprocess are executed in FMOD's mixer thread whereas all other callbacks are executed in the host's thread (game or Studio UI). It is therefore important to ensure thread safety across parameters and states which are shared between those two types of callbacks.

+

In the FMOD Gain example, two gains are stored: target gain and current gain. target gain stores the parameter value which is set and queried from the host thread. This value is then assigned to current gain at the start of the audio processing callback and it is current gain that is then applied to the signal. FMOD Gain shows how this method can be used to perform parameter ramping by not directly assigning current gain but interpolating between current gain and target gain over a fixed number of samples so as to minimize audio artefacts during parameter changes.

+

7.2.3 Plug-in Parameters

+

Plug-in effect and sound modules can have any number of parameters. Once defined, the number of parameters and each of their properties cannot change. Parameters can be one of four types:

+
    +
  • floating-point
  • +
  • integer
  • +
  • boolean (two-state)
  • +
  • data
  • +
+

Parameters are defined in FMOD_DSP_DESCRIPTION as a list of pointers to parameter descriptors, FMOD_DSP_DESCRIPTION::paramdesc. The FMOD_DSP_DESCRIPTION::numparameters specifies the number of parameters. Each parameter descriptor is of type FMOD_DSP_PARAMETER_DESC. As with the plug-in descriptor, parameter descriptors must stay around until the plug-in is unloaded as the data within these descriptors are directly accessed throughout the lifetime of the plug-in.

+

Common to each parameter type are the members FMOD_DSP_PARAMETER_DESC::name and units, as well as FMOD_DSP_PARAMETER_DESC::description which should describe the parameter in a sentence or two. The type member will need to be set to one of the four types and either of the FMOD_DSP_PARAMETER_DESC::floatdesc, FMOD_DSP_PARAMETER_DESC::intdesc, FMOD_DSP_PARAMETER_DESC::booldesc or FMOD_DSP_PARAMETER_DESC::datadesc members will need to specified. The different parameter types and their properties are described in more detail in the sections below.

+

Floating-point Parameters

+

Floating-point parameters have type set to FMOD_DSP_PARAMETER_TYPE_FLOAT. They are continuous, singled-valued parameters and their minimum, maximum and default values are defined by the floatdesc members min, max and defaultval.

+

The following units should be used where appropriate:

+
    +
  • "Hz" for frequency or cut-off
  • +
  • "ms" for duration, time offset or delay
  • +
  • "st" (semitones) for pitch
  • +
  • "dB" for gain, threshold or feedback
  • +
  • "%" for mix, depth, feedback, quality, probability, multiplier or generic 'amount'.
  • +
  • "Deg" for angle or angular spread
  • +
+

These are preferred over other denominations (such as kHz for cut-off) as they are recognised by Studio therefore allowing values to be displayed in a more readable and consistent manner. Unitless 0-to-1 parameters should be avoided in favour of dB if the parameter describes a gain, % if it describes a multiplier, or a unitless 0-to-10 range is preferred if describing a generic amount.

+

The FMOD_DSP_DESCRIPTION members FMOD_DSP_DESCRIPTION::setparameterfloat and FMOD_DSP_DESCRIPTION::getparameterfloat will need to point to static functions of type FMOD_DSP_SETPARAM_FLOAT_CALLBACK and FMOD_DSP_GETPARAM_FLOAT_CALLBACK, respectively, if any floating-point parameters are declared.

+

These will be displayed as dials in FMOD Studio's effect deck.

+

Integer Parameters

+

Integer parameters have type set to FMOD_DSP_PARAMETER_TYPE_INT. They are discrete, singled-valued parameters and their minimum, maximum and default values are defined by the intdesc members min, max and defaultval. The member goestoinf describes whether the maximum value represents infinity as maybe used for parameters representing polyphony, count or ratio.

+

The FMOD_DSP_DESCRIPTION members FMOD_DSP_DESCRIPTION::setparameterint and FMOD_DSP_DESCRIPTION::getparameterint will need to point to static functions of type FMOD_DSP_SETPARAM_INT_CALLBACK and FMOD_DSP_GETPARAM_INT_CALLBACK, respectively, if any integer parameters are declared.

+

These will be displayed as dials in FMOD Studio's effect deck.

+

Boolean Parameters

+

Boolean parameters have type set to FMOD_DSP_PARAMETER_TYPE_BOOL. They are discrete, singled-valued parameters and their default value is defined by the booldesc member defaultval.

+

The FMOD_DSP_DESCRIPTION members FMOD_DSP_DESCRIPTION::setparameterbool and FMOD_DSP_DESCRIPTION::getparameterbool will need to point to static functions of type FMOD_DSP_SETPARAM_BOOL_CALLBACK and FMOD_DSP_GETPARAM_BOOL_CALLBACK, respectively, if any boolean parameters are declared.

+

These will be displayed as buttons in FMOD Studio's effect deck.

+

Data Parameters

+

Data parameters have type set to FMOD_DSP_PARAMETER_TYPE_DATA. These parameters can represent any type of data including built-in types which serve a special purpose in FMOD. The datadesc member datatype specifies the type of data stored in the parameter. Values 0 and above may be used to describe user types whereas negative values are reserved for special types described in the following sections.

+

The FMOD_DSP_DESCRIPTION members FMOD_DSP_DESCRIPTION::setparameterdata and FMOD_DSP_DESCRIPTION::getparameterdata will need to point to static functions of type FMOD_DSP_SETPARAM_DATA_CALLBACK and FMOD_DSP_GETPARAM_DATA_CALLBACK, respectively, if any data parameters with datatype 0 and above are declared.

+

Data parameters with datatype 0 and above will be displayed as drop-zones in FMOD Studio's effect deck. You can drag any file containing the data onto the drop-zone to set the parameter's value. Data is stored with the project just like other parameter types.

+

7.2.4 Multiple plug-ins within one file

+

Typically each plug-in only has a single definition. If you want to have multiple definitions from within the one plugin file, you can use a plugin list. An example is shown below.

+
FMOD_DSP_DESCRIPTION My_Gain_Desc = { .. };
+FMOD_DSP_DESCRIPTION My_Panner_Desc = { .. };
+FMOD_OUTPUT_DESCRIPTION My_Output_Desc = { .. };
+
+static FMOD_PLUGINLIST My_Plugin_List[] =
+{
+    { FMOD_PLUGINTYPE_DSP, &My_Gain_Desc },
+    { FMOD_PLUGINTYPE_DSP, &My_Panner_Desc },
+    { FMOD_PLUGINTYPE_OUTPUT, &My_Output_Desc },
+    { FMOD_PLUGINTYPE_MAX, NULL }
+};
+
+extern "C"
+{
+
+F_EXPORT FMOD_PLUGINLIST* F_CALL FMODGetPluginDescriptionList()
+{
+    return &My_Plugin_List;
+}
+
+} // end extern "C"
+
+ +

Support for multiple plug-ins via FMODGetPluginDescriptionList was added in 1.08. If the plug-in also implements FMODGetDSPDescription, then older versions of the FMOD Engine load a single DSP effect, whereas newer versions load all effects.

+

To load plug-ins at runtime, call System::loadPlugin as normal. The handle returned is for the first definition. System::getNumNestedPlugins and System::getNestedPlugin can be used to iterate all plug-ins in the one file.

+
unsigned int baseHandle;
+ERRCHECK(system->loadPlugin("plugin_name.dll", &baseHandle));
+int count;
+ERRCHECK(system->getNumNestedPlugins(baseHandle, &count));
+for (int index=0; index<count; ++index)
+{
+    unsigned int handle;
+    ERRCHECK(system->getNestedPlugin(baseHandle, index, &handle));        
+    FMOD_PLUGINTYPE type;
+    ERRCHECK(system->getPluginInfo(handle, &type, 0, 0, 0));
+    // We have an output plug-in, a DSP plug-in, or a codec plug-in here.
+}
+
+ +

The above code also works for plug-ins with a single definition. In that case, the count is always 1 and System::getNestedPlugin returns the same handle as passed in.

+

7.3 Standard Reverb

+

A built-in high quality I3DL2 standard compliant reverb, which is used for a fast, configurable environment simulation, and is used for the 3D reverb zone system, described below.

+

To set an environment simply, use System::setReverbProperties. This lets you set a global environment, or up to 4 different environments, which all Channels are affected by.

+

Each Channel can have a different reverb wet mix by setting the level in ChannelControl::setReverbProperties.

+

Read more about the I3DL2 configuration in the Reverb Notes section of the documentation. To avoid confusion when starting out, simply play with the pre-set list of environments in FMOD_REVERB_PRESETS.

+

7.4 Convolution Reverb

+

There is also an even higher quality Convolution Reverb which allows a user to import an impulse response file (a recording of an impulse in an environment which is used to convolve the signal playing at the time), and have the environment sound like it is in the space the impulse was recorded in.

+

This is an expensive-to-process effect, so FMOD supports GPU acceleration to offload the processing to the graphics card. This greatly reduces the overhead of the effect, making it almost negligible. GPU acceleration is supported on Xbox One and PS4 platforms. The PS5 and XSX platforms both feature dedicated convolution reverb hardware, which similarly reduce the overhead of the effect.

+

Convolution reverb can be created with System::createDSPByType with FMOD_DSP_TYPE_CONVOLUTIONREVERB and added to a ChannelGroup with ChannelControl::addDSP. It is recommended to only implement one or a limited number of these effects and place them on a sub-mix/group bus (a ChannelGroup), and not per Channel.

+ + +
+ + + diff --git a/FMOD/doc/FMOD API User Manual/welcome-revision-history.html b/FMOD/doc/FMOD API User Manual/welcome-revision-history.html new file mode 100644 index 0000000..b7fe532 --- /dev/null +++ b/FMOD/doc/FMOD API User Manual/welcome-revision-history.html @@ -0,0 +1,4727 @@ + + +Welcome to the FMOD Engine | Detailed Revision History + + + + +
+ +
+

1. Welcome to the FMOD Engine | Detailed Revision History

+
+
    +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Legend
    Win:Microsoft WindowsXboxOne:Microsoft Xbox One
    Mac:Apple macOSGameCore:Microsoft Game Core
    Linux:LinuxPS4:Sony PlayStation 4
    iOS:Apple iOS / tvOSPS5:Sony PlayStation 5
    Android:Google AndroidSwitch:Nintendo Switch
    HTML5:JavaScript WebAssemblyUWP:Microsoft Universal Windows Platform
    +

    1/4/26 2.03.13 - Studio API minor release (build 162576)

    +

    Fixes:

    +
      +
    • Studio API - Fixed instruments failing to play audibly when they are triggered exactly at the destination of a transition timeline with no destination region.
    • +
    • Core API - Fixed FMOD_DSP_TYPE_COMPRESSOR and FMOD_DSP_TYPE_MULTIBAND_DYNAMICS not correctly mixing a sidechain input when its channel count was different to that of the main signal.
    • +
    • Core API - Fixed DSP Echo crash when delay time changes.
    • +
    • Core API - Mac - Fixed examples rendering buttons invisible on certain macOS / Xcode combinations.
    • +
    • Core API - Android - Improved AAudio input stream startup time.
    • +
    • Core API - GameCore - Fixed crash when using hardware convolution reverb.
    • +
    • Core API - PS4 - Improved logging surrounding AudioOut and Audio3D initialization.
    • +
    • Core API - PS5 - Improved logging surrounding AudioOut2 and allowed additional systems to init with spatial objects.
    • +
    • Unity - Fixed an issue where active Studio Event Emitters could persist after their owning object was destroyed.
    • +
    • Unity - Fixed potential for bank references to be lost when updating the integration.
    • +
    • Unreal - Improved third party plugin inclusion by removing the need to manually create a text file.
    • +
    • Unreal - Enable Unity Build to speed up project compilation.
    • +
    • Unreal - Removed Precompiled headers and includes.
    • +
    • Unreal - Fixed events not auditioning in Sequencer and Animations.
    • +
    +

    15/01/26 2.03.12 - Studio API minor release (build 160365)

    +

    Features:

    +
      +
    • Studio API - PS4 - Added haptics support.
    • +
    • Studio API - Switch - Added haptics support.
    • +
    • Unity - Added support for NativeArray to avoid Garbage Collection allocations when loading Addressables or using Studio::System::loadBankMemory.
    • +
    • Unity - Plugins added to the Editor platform will now be loaded when auditioning events in the Event Browser.
    • +
    • Unity - Dynamic plugins added to the Editor platform in the integration settings will now be loaded for auditioning in the Unity editor.
    • +
    +

    Fixes:

    +
      +
    • Studio API - Fixed live update blocking the game's main thread when swapping audio files on single instruments that are currently playing.
    • +
    • Studio API - Win - Fixed haptics conflict between two instances of FMOD, i.e. Studio + Game for classic rumble motor controllers.
    • +
    • Studio API - HTML5 - EventDescription::setCallback now returns FMOD_ERR_UNSUPPORTED rather than causing binding errors at runtime.
    • +
    • Core API - Fixed click at end of looping PCM sounds that use Channel::setLoopCount.
    • +
    • Core API - Mac - Fixed potential crash when loading plugins if the path gets too long.
    • +
    • Unity - Fixed bank folders containing a dot not working correctly.
    • +
    • Unity - Fixed deprecation warnings when adding the integration.
    • +
    • Unreal - Replaced raw object pointers with TObjectPtr.
    • +
    • Unreal - Fixed encrypted banks not working on MacOS.
    • +
    • Unreal - Fixed issue where FMODAssetBuilder would wait for confirmation to delete files in unattended mode.
    • +
    • Unreal - Fixed FMODAudioComponents logging errors if occlusion parameter is set in settings but event does not use it.
    • +
    • Unreal - Fixed getBus error on Editor startup.
    • +
    • Unreal - Fixed validation steps setting inconsistent Built Banks Output Directory path.
    • +
    +

    18/11/25 2.03.11 - Studio API minor release (build 158528)

    +

    Features:

    + +

    Fixes:

    +
      +
    • Studio API - Fixed incorrect playback after issuing a key off command for a sustain point that is at the end of a loop around a multi instrument.
    • +
    • Studio API - Enforced Studio::System::setListenerWeight documented range [0, 1] and added a warning for incorrect weight/mask combinations.
    • +
    • Studio API - Fixed a hang in quantization logic on events that have been playing for many hours.
    • +
    • Studio API - Mac - Fixed "assertion: 'previousPoint != NULL' failed" log message when playing events that contain LFO modulators with tempo sync enabled.
    • +
    • Studio API - PS5 - Improved performance when memory tracking is enabled.
    • +
    • Core API - Win - WASAPI and WinSonic recording streams will now be categorized as "communications" for Windows.
    • +
    • Core API - Fixed (removed) some benign network related error logs.
    • +
    • Core API - Fixed Multiband Dynamics ignoring sidechain input on first mix.
    • +
    • Core API - Fixed some calls to DSP::setDelay not respecting arguments if called quickly after playsound.
    • +
    • Unity - Fixed errors caused by loading addressable assets multiple times.
    • +
    • Unreal - Removed the bStopEventsOutsideMaxDistance setting and associated functionality, as this feature had multiple issues and needs to be reworked.
    • +
    +

    23/10/25 2.03.10 - Studio API minor release (build 157581)

    +

    Features:

    +
      +
    • Studio API - Added logging defines to the C# wrappers.
    • +
    • Unreal - Added bStopEventsOutsideMaxDistance to the integration settings which controls whether events will be played or stopped when outside the max attenuation distance.
    • +
    +

    Fixes:

    +
      +
    • Core API - Fixed potential crash when releasing a streaming sound that has just transitioned from virtual to real.
    • +
    • Core API - Fixed virtual streams not ending.
    • +
    • Core API - C# - Reworked and added new accessors to FMOD_DSP_METERING_INFO to avoid Garbage Collector allocations. Note that assigning to a float[] variable from the peaklevel and rmslevel fields still causes allocation.
    • +
    • Core API - Fixed buffer overrun when Multiband Dynamics uses a sidechain and is in 'linked' mode.
    • +
    • Core API - Fixed Multiband Dynamics using input signal instead of sidechain signal when two bands are collapsed.
    • +
    • Core API - Fixed loop points for a channel not persisting when going virtual, and a mixer hang if using System::playDSP when going virtual.
    • +
    • Core API - GameCore - Reduced memory usage of convolution reverb.
    • +
    • Core API - GameCore - Fixed hardware resource leak causing Channels to go virtual when they shouldn't.
    • +
    • Core API - PS4 - Fixed potential AT9 stream hang when transitioning from virtual to real.
    • +
    • Core API - PS5 - Fixed Opus sceAjmInstanceDestroy error that causes an instance leak.
    • +
    • Unity - Preserve specified banks when updating/changing FMOD integration version.
    • +
    • Unity - Updated to preferred method for confirming 64-bit architecture.
    • +
    • Unity - Fixed plugins being loaded from the wrong location on Windows Arm64.
    • +
    • Unity - Mac - MacOS fmodstudioL.bundle now defaults to Any CPU instead of Intel-64 on some Unity versions.
    • +
    • Unity - Android - Added 16KB alignment metadata for Android plugins to remove Unity warnings.
    • +
    • Unreal - Fixed UE5.6.1 FMODCallbackHandler build issue.
    • +
    • Unreal - Fixed crash when calling FMODAudioComponent API during object construction.
    • +
    • Unreal - Fixed issue with no spatial sound resources available for Play-In-Editor.
    • +
    +

    05/08/25 2.03.09 - Studio API minor release (build 155273)

    +

    Features:

    +
      +
    • Core API - Added System::createDSPConnection and updated DSP::addInput with support for FMOD_DSPCONNECTION_TYPE_PREALLOCATED.
    • +
    • Core API - Added FMOD_DEBUG_TYPE_VIRTUAL to enable logging for Channel virtual state changes.
    • +
    • Core API - iOS - Added suspend_resume example that demonstrates how to handle suspending and resuming the mixer when interrupted by iOS.
    • +
    • Unity - Added "Serialize GUIDs Only" setting that disables event path serialization for Event References.
    • +
    • Unity - Added support for Windows Arm64.
    • +
    • Unreal - Added IFMODCallbackHandler interface to run custom configuration code prior to initialization.
    • +
    +

    Fixes:

    +
      +
    • Studio API - Fixed sidechain level being incorrect in the first mix after the sidechain is connected.
    • +
    • Studio API - Fixed transition timeline source region fade curves failing to make instruments go completely silent.
    • +
    • Studio API - Fixed EventDescription::isOneshot returning false if it contains a non-looping destination region.
    • +
    • Studio API - Fixed automation of the spectral sidechain modulator's amount property giving incorrect results when the modulator was targeting non-volume properties.
    • +
    • Studio API - Fixed positions reported by EventInstance::getTimelinePosition pausing shortly before the audio after calling EventInstance::setPaused.
    • +
    • Core API - Fixed ChannelGroup::setMode (FMOD_2D) for a 3D ChannelGroup not resetting its pan matrix.
    • +
    • Core API - Fixed erroneous debug assert when playing a 12 channel signal into a Pan DSP.
    • +
    • Core API - PS5 - Fixed audible pop when disconnecting a port.
    • +
    • Core API - Android - Fixed slow startup times when using AAudio.
    • +
    • Android / iOS/Switch - Fix ARM based device panning issue when using a 7.1 mix.
    • +
    • Unity - Fixed auditioning system initialization failures for CI builds.
    • +
    • Unity - The Studio Bank Loader will now only wait for samples to be loaded if the "Pre Load Sample Data" option is enabled.
    • +
    • Unity - Refined requirements when selecting single and multi platform build directories in the Setup Wizard to avoid getting the integration into an invalid state.
    • +
    • Unreal - Fixed unpause not working correctly when auditioning level sequence.
    • +
    • Unreal - Fixed excess logging when ending Play-In-Editor and using Sequencer.
    • +
    • Unreal - Fixed deprecation errors in Xcode.
    • +
    • Unreal - Fixed crash on launch when using events in GameplayCue.
    • +
    • Unreal - Fixed crash when using '-nosound' and PlayFMODEventPersistent in Niagara.
    • +
    • Unreal - Fixed possible hangs when ending Play-In-Editor while using AudioLink.
    • +
    • Unreal - Fixed events not triggering when being auditioned in the animation window with bFollow enabled.
    • +
    +

    11/06/25 2.03.08 - Studio API minor release (build 153137)

    +

    Features:

    +
      +
    • Core API / Studio API - HTML5 - Added pthread/SharedArrayBuffer support using the fmodP / fmodstudioP variants of the libraries.
    • +
    +

    Fixes:

    +
      +
    • Studio API - Fixed sidechain level being ignored when the connected effect is instantiated after the sidechain.
    • +
    • Studio API - Fixed parameter initial value being ignored on first playback if the parameter has a seek modulator.
    • +
    • Studio API - Fixed command instruments decrementing discrete and labeled parameters by the wrong amount.
    • +
    • Core API - Fixed deadlock when adding/removing audio device after call to System::mixerSuspend.
    • +
    • Studio API - Fixed changes to delay time on the FMOD Delay effect being ignored unless the event is playing.
    • +
    • Core API - Fixed possible crash if FMOD_CREATECOMPRESSEDSAMPLE codec ran out of memory combined with virtual voices.
    • +
    • Core API - Android/iOS - Fixed recording not returning after System::mixerResume.
    • +
    • Core API - Android - All AAudio devices now enumerated regardless of whether specific devices permissions have been granted.
    • +
    • Core API - Linux - pthread stack size is now aligned to system page size.
    • +
    • Core API - Fixed audibility calculation factoring in fader gain value incorrectly when using sends/returns, leading to voices cutting out while still audible.
    • +
    • Unreal - Fixed an issue where Events triggered by the OnEventStopped callback could continue playing once exiting PIE or unloading a level.
    • +
    • Unreal - Fixed an issue where banks would not be loaded correctly when validating FMOD or auditioning events in editor.
    • +
    • Unity - Fixed crash when passing null to setParameterData.
    • +
    • Unity - Removed dependency on the Unity UI package.
    • +
    • Unity - Oneshot events will no longer trigger outside of max distance when "Stop Events Outside Max Distance" setting is enabled.
    • +
    +

    Notes:

    +
      +
    • Unity - Added support for Unity 6.1.
    • +
    +

    03/04/25 2.03.07 - Studio API minor release (build 150747)

    +

    Features:

    +
      +
    • Unity - Added support for WeChat Mini Game platform in TuanJie Engine.
    • +
    +

    Fixes:

    +
      +
    • Studio API - Fixed parameters set to "Hold Value During Playback" changing if automated by another parameter.
    • +
    • Core API - Android - Fixed crash when calling into record API while mixer suspended.
    • +
    • Core API - Fixed DSP::setWetDryMix causing audible output on some DSPs if they were muted internally, for example FMOD_DSP_TYPE_FADER, or user DSPs using FMOD_ERR_DSP_SILENCE as a return value.
    • +
    • Core API - Mac - Fixed FMOD_ERR_OUTPUT_DRIVERCALL being returned on certain device change events.
    • +
    • Core API - XSX - Fixed hardware convolution failing to fallback to software implementation when an invalid impulse response length was provided.
    • +
    • Core API - Added support for .m3u8 file format.
    • +
    • Unity - Improved EventReferenceDrawer performance when working with large FMOD projects.
    • +
    • Unity - OpenHarmony - Removed need for manual fmod.init call in exported project's Ability.
    • +
    • Unity - Added suggestion for line ending requirements to Source Control window of the Set Up Wizard.
    • +
    • Unity/Unreal - Filter out benign FMOD_ERR_CHANNEL_STOLEN error.
    • +
    +

    Notes:

    +
      +
    • Switch - Now built with SDK 19.3.5.
    • +
    +

    07/02/25 2.03.06 - Studio API minor release (build 149358)

    +

    Features:

    +
      +
    • Core API - Android - Added support for Spatial Audio when surround speaker mode is 5.1 or higher and user has Spatial Audio enabled.
    • +
    • Unity - Added public property StudioListener::AttenuationObject.
    • +
    • Unity - Added Chinese localization to Resonance plugin.
    • +
    +

    Fixes:

    +
      +
    • Studio API - HTML5 - Added support for position independent code with Upstream WASM.
    • +
    • Core API - Fixed Channel::getAudibility not considering 3D attributes of parent ChannelGroups in audibility calculation.
    • +
    • Core API - Fixed audible pop from fix introduced in 2.02.24 regarding virtual channels and ChannelControl::setPan/setMixLevelsInput/setMixLevelsOutput/ ChannelControl::setMixMatrix.
    • +
    • Core API - Android - Fixed input stream leak when backgrounding application on some Android devices.
    • +
    • Core API - Android - Fixed small amount of old audio being played after calling System::mixerResume when using OpenSL or AAudio output types.
    • +
    • Core API - PS5 - Fixed potentially incorrect pitch / hardware errors when using very high or low pitch values with Opus.
    • +
    • Core API - PS5 - Fixed issues with the Opus codec with seamless looping.
    • +
    • Core API - Windows - Fixed ASIO failing to initialize if device CLSID is empty.
    • +
    • OpenHarmony - Reduced latency by taking advantage of SDK 11 functionality, latency for SDK 10 devices remains unchanged.
    • +
    • Unity - Fixed vector out-of-range warning when creating 3D event instances.
    • +
    • Unity - Fixed an issue with SetListenerLocation if Physic2D was disabled.
    • +
    • Unity - Fixed Setup Wizard window to be resizable and scrollable.
    • +
    • Unity - Fixed NotImplementedException error when running the event reference updater on objects that have not implemented GetEnumerator().
    • +
    • Unity - Fixed ArgumentOutOfRangeException error when trying to create a new FMOD event in editor.
    • +
    • Unreal - Fixed 3D AudioLink events playing at world zero before receiving position information from Unreal.
    • +
    +

    13/12/24 2.03.05 - Studio API minor release (build 148280)

    +

    Features:

    +
      +
    • Unity - Added Chinese localization.
    • +
    +

    Fixes:

    +
      +
    • Studio API - Added some extra validation around 3D attributes passed in.
    • +
    • Studio API - Fixed an assert that occurs when playing a transition timeline with a relative offset and a destination region that passes the end of the main timeline.
    • +
    • Studio API - Fixed incorrect timeline transition behavior when loading banks built by FMOD Studio 2.00.04 or earlier.
    • +
    • Studio API - PS4/PS5 - Fixed crash preceded by an internal assert(isValid) on PS5 SDK 10 and PS4 SDK 12.
    • +
    • Core API - Android - Fixed glitching when attempting screen recording with AAudio on Android 14 and above.
    • +
    • Core API - Android - Added protections against recording with multiple input devices simultaneously when using OpenSL.
    • +
    • Core API - Android - AAudio now correctly stops recording if a new recording begins on a different device.
    • +
    • Core API - iOS - Added protections against recording with multiple input devices simultaneously.
    • +
    • Unity - Fixed the Event Reference Updater incorrectly being triggered when capitalization changes on events or folders.
    • +
    • Unity - Fixed "Stop Events Outside Max Distance" behavior not taking listener attenuation objects into account.
    • +
    • Unity - Removed Codec assigning for the default platform as not all platforms support the same Codec values.
    • +
    +

    Notes:

    +
      +
    • PS4 - Now built with SDK 12.008.011.
    • +
    • PS5 - Now built with SDK 10.00.00.40.
    • +
    • Unreal - Added support for UE5.5.
    • +
    • Android - arm64-v8a and x86_64 libraries are now aligned to 16kb page size.
    • +
    +

    11/11/24 2.03.04 - Studio API minor release (build 147563)

    +

    Fixes:

    +
      +
    • Studio API - Fixed a crash caused by changing an event via live update and then unloading one of its assets banks.
    • +
    • Studio API - Fixed an assert when an event with manual sample loading uses a sample after an event with automatic sample loading.
    • +
    • Studio API - Fixed crash and memory leaks when loading master banks that are missing mixer content required in other banks.
    • +
    • Core API - Removed the MarshalHelper to avoid AOT build errors when using the C# wrapper.
    • +
    • Core API - FMOD_ERR_FILE_NOTFOUND logs will now be of level "log" rather than "error" as it is not an error in some cases.
    • +
    • Core API - Fixed compatibility issues with .wavs produced with FMOD_OUTTPUTTYPE_WAVWRITER or FMOD_OUTTPUTTYPE_WAVWRITER_NRT.
    • +
    • Core API - Fixed incorrect "device" name for PCM float output with FMOD_OUTTPUTTYPE_WAVWRITER and FMOD_OUTTPUTTYPE_WAVWRITER_NRT.
    • +
    • Core API - Fixed DSP creation failing with FMOD_ERR_MEMORY if called a large number of times, despite still having system memory available.
    • +
    • Core API - C# - Fixed the definition of FMOD_DSP_BUFFER_ARRAY to allow the usage of FMOD_DSP_PROCESS_CALLBACK. New properties allow easy access to the native arrays.
    • +
    • Core API - Consoles - Hardware resources will now correctly yield after an FMOD_CREATESAMPLE decode so they can be used in other sounds.
    • +
    • Core API - Fixed subsounds in FSBs returning FMOD_SOUND_TYPE_FSB from Sound::getFormat instead of their encoded sound type.
    • +
    • Core API - Mac - Fixed error initializing output after turning bluetooth off.
    • +
    • Core API - Win - Downgraded "device unplugged" errors to warnings as device switching is supported.
    • +
    • Core API - Win - Fixed potential crash with certain ASIO driver after System::close.
    • +
    • Unity - Added support for setting number of Opus Codecs on PS5.
    • +
    • Unreal - DestroyStudioSystem no longer unloads banks, as the system release handles this.
    • +
    +

    Notes:

    +
      +
    • HTML5 - Now built with SDK 3.1.67.
    • +
    • Unity - HTML5 - Now built with SDK 3.1.8 for Unity 2022.3 and 3.1.39 for Unity 6000.0.
    • +
    +

    25/09/24 2.03.03 - Studio API minor release (build 146372)

    +

    Features:

    + +

    Fixes:

    +
      +
    • Studio API - Fixed a crash when unloading an assets bank before its associated metadata bank.
    • +
    • Studio API - Fixed backwards compatibility loading banks from 1.08 and older, which presented as FMOD_ERR_INVALID_PARAM being returned from System::loadBankFile (or equivalent bank load function).
    • +
    • Studio API - Fixed invalid handle error being returned from Studio::System::update if a spectral sidechain on a global bus is released (due to the bus becoming unused).
    • +
    • Core API - Fixed passed in values being ignored when calling ChannelControl::setPan, ChannelControl::setMixLevelsInput, ChannelControl::setMixLevelsOutput, or ChannelControl::setMixMatrix on a virtual Channel.
    • +
    • Core API - Fixed MultibandEQ not handling DSP::reset correctly for bands B through E.
    • +
    • Core API - OpenHarmony - Audio will now automatically resume after interruption.
    • +
    • Core API - PS5 - Fixed Opus decode errors with certain pitch and seek combinations.
    • +
    • Unreal - Added additional validation to Content Browser Prefix to account for invalid characters and prefix lengths.
    • +
    • Unity - Added non-Rigidbody velocity effect option on Listeners.
    • +
    • Unity - Fixed source control presentation on macOS.
    • +
    • Unity - OpenHarmony - Fixed issue locating bank files on devices.
    • +
    • Unity - Fixed EventReferenceUpdater stack overflow exception caused by Input System.
    • +
    • Studio API - Reduced effect parameter allocations by allocating upfront instead of individually.
    • +
    +

    Notes:

    +
      +
    • Unity - Renamed StudioEventEmitter members PlayEvent and StopEvent to EventPlayTrigger and EventStopTrigger to disambiguate from StudioEventEmitter.Play().
    • +
    • GameCore - Now built with March 2024 Update 1 GDKX.
    • +
    • Unreal - PS4 - UE4.27 - Now built with SDK 11.008.001.
    • +
    • Unreal - PS5 - UE4.27 - Now built with SDK 8.00.00.41.
    • +
    +

    12/07/24 2.03.02 - Studio API minor release (build 144646)

    +

    Features:

    +
      +
    • Core API - Android - Non-default input and output devices can now be requested when using AAudio. Only available on devices targeting API level 26 (Oreo) and above.
    • +
    • Core API - Android - Added FMOD_Android_JNI_Init to support initializing Java layer from a native activity.
    • +
    • Core API - GameCore - Added FMOD_PORT_TYPE_CONTROLLER to the FMOD_OUTPUTTYPE_WASAPI output plug-in to route audio to a user specific audio device.
    • +
    • Unity - Fixed warnings for updated api functions in Unity 2023.1+.
    • +
    • Unity - Android - Added support for Application Entry Point GameActivity.
    • +
    +

    Fixes:

    +
      +
    • Studio API - Fixed glitches due to modulation not being applied correctly at event start time.
    • +
    • Studio API - Fixed glitches in AHDSR modulator release.
    • +
    • Studio API - Fixed an intermittent assert when playing instruments with trigger delay.
    • +
    • Studio API - GameCore - Fixed crash when setting invalid thread affinity.
    • +
    • Core API - Fixed rare crash when virtual voices swapped when using a mix of Sound and DSP based channels.
    • +
    • Core API - Android - Fixed crash when calling recordStart while mixer suspended.
    • +
    • Core API - OpenHarmony - Added support for System::mixerSuspend and System::mixerResume to allow recovery of audio when returning from the background.
    • +
    • Core API - visionOS - Fixed missing symbol build error.
    • +
    • Core API - Windows - Fixed initialization failure when audio service unavailable.
    • +
    • Unity - Fixed EventReferenceUpdater iterating over irrelevant objects.
    • +
    • Unreal - Fixed Niagara component variables using incorrect namespaces.
    • +
    • Unreal - Fixed compile errors in UE5.4 for FMODAudioLinkInputClient.cpp on some consoles.
    • +
    • Unreal - FMODAudioComponents Occlusion and Velocity is now based off the component instead of the actor.
    • +
    • Unity - Fixed CodeGeneration.cs being left in the wrong location when migrating from 2.01 to 2.02.
    • +
    • Unity - Fixed EventReferenceUpdater exception when attempting to iterate uninitialized items.
    • +
    +

    Notes:

    +
      +
    • Unity - Studio Event Emitter setting "Allow Non-Rigidbody Doppler" has been renamed "Non-Rigidbody Velocity".
    • +
    • Unity - Added support for Unity 6.
    • +
    +

    08/05/24 2.03.01 - Studio API minor release (build 142842)

    +

    Features:

    +
      +
    • Core API - Added optimizations to Multiband Dynamics plugin to skip processing of collapsed bands.
    • +
    +

    Fixes:

    +
      +
    • Studio API - Fixed a crash when unloading a bank containing a global parameter that automates a modulator property on another global parameter.
    • +
    • Studio API - Fixed the sidechain modulator producing incorrect results when it is connected to multiple sidechains.
    • +
    • Core API - Fixed rare clicks/pops when using DSP::setWetDryMix.
    • +
    • Core API - Fixed potential crashes relating to unloading Banks that hold referenced Events that are currently playing.
    • +
    • Core API - HTML5 - Fixed no-audio output when using FMOD_OUTPUTTYPE_AUDIOWORKLET in some newer browsers.
    • +
    • Core API - HTML5 - Fixed FFT DSP spectrum data not being accessible.
    • +
    • Unity - Fixed FMOD settings heading being over written by new Unity cloud integration buttons.
    • +
    • Unity - Fixed error if event browser is left open when Unity starts.
    • +
    • Unity - Fixed EventReferenceUpdater throwing invalid cast exceptions.
    • +
    • Unity - Fixed FileReorganizer not moving libs in old directories.
    • +
    • Unreal - iOS - Fixed interruption notification deprecations.
    • +
    +

    Notes:

    +
      +
    • iOS/Mac - Now compliant with Apple privacy requirements, removed usage of mach_absolute_time, no manifest needed.
    • +
    • PS4 - Now built with SDK 11.508.011.
    • +
    • PS5 - Now built with SDK 9.00.00.40.
    • +
    +

    13/03/24 2.03.00 - Studio API major release (build 141450)

    +

    Features:

    + +

    Fixes:

    +
      +
    • Studio API - Fixed popping caused by Studio::Bus::setPaused.
    • +
    • Studio API - Fixed sounds being stopped when they are in multiple banks and the first loaded bank is unloaded.
    • +
    • Studio API - Fixed looping playlist instruments displaying a warning when using a DSP buffer size of less than 1024.
    • +
    • Core API - Fixed virtual voices getting out of sync when they return to real.
    • +
    +

    Notes:

    +
      +
    • All APIs - The F_CALLBACK macro has been removed, update existing code to use F_CALL instead.
    • +
    • Core API - In C#, FMOD_DSP_STATE.functions now has a wrapper function returning an FMOD_DSP_STATE_FUNCTIONS struct instead of the IntPtr requiring marshalling.
    • +
    • Core API - Removed FMOD_DSP_TYPE_ENVELOPEFOLLOWER, FMOD_DSP_TYPE_VSTPLUGIN, FMOD_DSP_TYPE_LADSPAPLUGIN, and FMOD_DSP_TYPE_WINAMPPLUGIN.
    • +
    • Core API - Removed FMOD_SYSTEM_CALLBACK_MIDMIX.
    • +
    • Core API - Renamed the FMOD_DSP_FFT_WINDOW enum to FMOD_DSP_FFT_WINDOW_TYPE, and renamed the FMOD_DSP_FFT_WINDOWTYPE enum value to FMOD_DSP_FFT_WINDOW.
    • +
    • Core API - Win - The default DSP buffer size is now 512 rather than 1024 to reduce latency.
    • +
    • Android - Updated to NDK 26b and Android SDK 21.
    • +
    • HTML5 - Removed support for deprecated Fastcomp backend.
    • +
    • Unity - Removed support for end-of-life versions, minimum is now 2021.3.
    • +
    • Tools - Updated Qt framework to v6.5.3 which lifts the minimum requirement to macOS 11.0, Win10 1809 and Linux GLIBC 2.28.
    • +
    +

    13/03/24 2.02.21 - Studio API minor release (build 141420)

    +

    Features:

    +
      +
    • Unreal - Switch - Added functionality to open a socket on dev kit when Live Update is enabled.
    • +
    • Unreal - Added IFMODStudioModule::PrePIEDelegate to give users a chance to clean up any resources before the FMOD System is released in Editor.
    • +
    • iOS - Added support for the Apple Vision Pro device and simulator in the Core/Studio APIs and the FMOD for Unity integration.
    • +
    • Win - Added support for Arm64 processors in the Core/Studio APIs.
    • +
    +

    Fixes:

    +
      +
    • Core API - Fixed FSB sounds incorrectly being virtualized when built from 32 bit source assets.
    • +
    • Core API - Fixed incorrect handling of DSP wet/dry settings if the DSP returns FMOD_ERR_DSP_DONTPROCESS when its process callback is called with FMOD_DSP_PROCESS_QUERY.
    • +
    • Core API - OpenHarmony - Added an error check during System::init for insufficient DSP buffer size.
    • +
    • Core API - Android - Fixed global threads, like the File thread, remaining active when the app is suspended on Android.
    • +
    • Unity - Fixed editor hang when live recompiling code.
    • +
    • Unity - Fixed iOS interruption deprecation warnings.
    • +
    • Unreal - For UE5.2 onwards MacOS integration libs are now built as universal to support both x86_64 and arm64.
    • +
    • Unreal - Fixed iOS interruption deprecation warnings.
    • +
    +

    Notes:

    +
      +
    • iOS - Now built with iOS SDK 17.2 (Xcode 15.2).
    • +
    • Switch - Now built with SDK 17.5.3.
    • +
    • PS4 - Now built with SDK 11.008.001.
    • +
    • PS5 - Now built with SDK 8.00.00.41.
    • +
    +

    13/12/23 2.02.20 - Studio API minor release (build 139317)

    +

    Features:

    +
      +
    • Core API - Through FMOD_ADVANCEDSETTINGS, Spatial Objects count can be reserved per FMOD systems.
    • +
    • FSBank API - Added FSBANK_BUILD_ALIGN4K to align each sound in an FSB to a 4K boundary to help binary patching on Microsoft platforms.
    • +
    • Unity - The integration can now be hosted on Source Control and still be able to edit .asset files.
    • +
    • Unity - Debug Overlay can now have its on screen position set and font size changed.
    • +
    • Unreal - Added support for pausing FMOD Audio Components in Unreal Sequencer.
    • +
    +

    Fixes:

    +
      +
    • Studio API - Fixed crash when calling into API before FMOD::System created.
    • +
    • Core API - Fixed potential crackling caused by changing the system sample rate of a device playing as a port.
    • +
    • Win - Fixed Cygwin/MinGW libs giving linker errors from API functions that include FMOD_THREAD_AFFINITY or FMOD_STUDIO_PARAMETER_ID.
    • +
    +

    2/11/23 2.02.19 - Studio API minor release (build 137979)

    +

    Features:

    +
      +
    • Android/iOS - Added virtual recording device via System::recordStart (1, ...) that adds hardware processing including echo cancellation.
    • +
    +

    Fixes:

    +
      +
    • Studio API - Fixed a race condition between the sample data loading system and Studio::EventDescription::getSampleLoadingState.
    • +
    • Core API - Fixed WavWriter and NoSound output plugins potentially processing more audio than appropriate for the elapsed time.
    • +
    • Core API - PS4 - Increased DSPBufferSize range to handle sizes greater than 256 or 512. The AT9 codec still has a restriction of 256 or 512 but anything else will accept sizes of 256, 512, 768, 1024, 1280, 1536, 1792 or 2048.
    • +
    • Unreal - Reset locale to default every time PIE is launched.
    • +
    +

    Notes:

    +
      +
    • Core API - iOS - Disabled FMOD_OUTPUTTYPE_PHASE due to compatibility issues with iOS 17.
    • +
    • iOS - Now built with iOS SDK 17.0 (Xcode 15.0), min deploy target is now 12.0 and bitcode has been removed as mandated by Xcode.
    • +
    • Mac - Now built with macOS SDK 14.0 (Xcode 15.0.1).
    • +
    • HTML5 - Fixed Sound::lock not returning memory pointers.
    • +
    +

    2/10/23 2.02.18 - Studio API minor release (build 137105)

    +

    Features:

    +
      +
    • Core API - iOS - A new output plugin called FMOD_OUTPUTTYPE_PHASE has been enabled, which supports 3D spatial objects. For iOS 16.4.
    • +
    • Core API - PS5 - From SDK 8.00 we now support Dolby Atmos and thus 7.1.4 output. To enable this set FMOD_SPEAKERMODE_7POINT1POINT4.
    • +
    • Unity - Emitters are now able to be triggered from UI elements using mouse events.
    • +
    • Unreal - Added support for Niagara.
    • +
    +

    Fixes:

    +
      +
    • Studio API - Fixed programmer sounds getting spatialized by the Core API if the passed in Sound had the FMOD_3D mode set.
    • +
    • Studio API - Fixed shared streaming assets being forced to stop when the bank they are streaming from is unloaded if the bank was loaded via Studio::System::loadBankCustom.
    • +
    • Studio API - Fixed pops when calling Studio::EventInstance::setTimelinePosition on events with only one sound on the timeline.
    • +
    • Studio API - Fixed streaming instruments failing to stop at the right time if they were started too close to the end.
    • +
    • Studio API - Multi instruments/scatterers now factor in silence instruments when determining whether to play an instrument from a playlist in shuffle mode. If an instrument is followed by one or more silence instruments, that instrument will not be selected to play next.
    • +
    • Core API - Fixed cycles created using DSP connections not causing a feedback loop.
    • +
    • Core API - Slight improvement to Multiband EQ filter stability near the upper end of the frequency range on 24kHz devices.
    • +
    • Core API - Clamp and log a warning when setting a high pitch value rather than returning an error.
    • +
    • Core API - Fixed some DSP effects incorrectly skipping processing as if bypassed via DSP::setBypass when DSP::setWetDryMix is called with prewet set to 0.
    • +
    • Core API - Fixed potential crash in the transceiver DSP if certain pre-init calls are made in sequence, such as System::setDSPBufferSize followed by System::setOutput.
    • +
    • Core API - Fixed potential crash (or assert) when opening and closing ports.
    • +
    • Core API - Fixed potential audio corruption for 3D objects if the mixer is under heavy load.
    • +
    • Core API - PS5 - Fixed internal error from sceAudioOut2PortSetAttributes returning "not-ready" caused by a race condition in opening a port.
    • +
    • Core API - Windows - Fixed WASAPI device enumeration memory leaks when devices fail.
    • +
    • Unreal - Fixed Sequencer ignoring Start keys at frame 0.
    • +
    • Unreal - Restore "Reload Banks' option to File dropdown menu.
    • +
    • Unreal - Added validation to fix lack of leading or trailing forward slash in Content Browser Prefix.
    • +
    • Unreal - Fixed FMODAudioComponent ignoring "When Finished" behavior when Sequencer finishes playback.
    • +
    • Unreal - Fixed localized banks not working.
    • +
    • Unity - Fixed non-rigidbody doppler dividing by 0 if Time.timescale = 0.
    • +
    • Unity - Fixed issue when playing in Editor where the path plugins were attempted to be loaded from contained "/Assets" twice.
    • +
    • Android - Fixed playerSetVolume crash on devices with Android OS below Android T.
    • +
    • Windows - Removed hard dependency on msacm32.dll.
    • +
    +

    Notes:

    +
      +
    • Core API - Calling the DSP plugin API functions, FMOD_DSP_GETSAMPLERATE, FMOD_DSP_GETBLOCKSIZE, or FMOD_DSP_GETSPEAKERMODE before init will now return an error as those settings are not confirmed until after initialization.
    • +
    • PS4 - Now built with SDK 10.508.001.
    • +
    • PS5 - Now built with SDK 7.00.00.38.
    • +
    +

    21/8/23 2.02.17 - Studio API minor release (build 136061)

    +

    Fixes:

    +
      +
    • Studio API - Fixed Studio::EventInstance::getTimelinePosition occasionally reporting incorrect position.
    • +
    • Studio API - Fixed hang after running an Event for 12 hours with beat callbacks.
    • +
    • Studio API - Fixed instruments that are automated on the timeline having incorrect automated values when they start.
    • +
    • Core API - Fixed virtual voice issue that could cause Channels to restart.
    • +
    • Core API - Fixed assert firing from resampler for wildly varying pitch values.
    • +
    • Core API - Fixed FMOD_INIT_3D_RIGHTHANDED to work correctly when using FMOD_3D_HEADRELATIVE.
    • +
    • Core API - GameCore/PS5 - Fixed the Opus and XMA codecs to display an appropriate error log if the DSP buffer size is not 512.
    • +
    • Core API - HTML5 - Fixed compiler errors to do with using Strict Mode.
    • +
    • Unity - Fixed Studio Global Parameter Trigger silently failing on awake.
    • +
    • Unity - FMOD Studio system failing to initialize will no longer throw as an exception.
    • +
    • Unity - Fixed error when auditioning Events containing global parameters in Event Browser.
    • +
    • Unreal - Fixed FMODAudioComponents always using default parameter values.
    • +
    • Unreal - Fixed Sequencer restarting AudioComponents when Sequencer Editor open.
    • +
    • Unreal - Fixed crash when FMOD Studio project contains folders with "." character.
    • +
    • Unreal - Fixed FMODGenerateAssets commandlet not deleting old assets on rebuild.
    • +
    • Android - Fixed exported symbols to avoid issues with unwinder on armeabi-v7a.
    • +
    +

    13/7/23 2.02.16 - Studio API minor release (build 135072)

    +

    Fixes:

    +
      +
    • Studio API - Fixed voice stealing behavior not updating when connected to live update.
    • +
    • Studio API - Fixed instruments with AHDSR not stopping after release, introduced in 2.02.15.
    • +
    • Unity - Fixed ApplyMuteState and PauseAllEvents functions when when using Addressables
    • +
    • Unity - Fixed Editor Platform settings inheriting from the Default Platform.
    • +
    • Unity - Fixed folder references to allow the FMOD Plugin base folder to be moved anywhere on disk for use with the Unity Package Manager.
    • +
    • Unreal - Fixed potential crash when linking to Studio project locales.
    • +
    • iOS/Mac - Fixed example Xcode projects with incorrect paths failing to load.
    • +
    +

    Notes:

    +
      +
    • Unity - Added support for Unity 2023.1.
    • +
    +

    2/6/23 2.02.15 - Studio API minor release (build 134211)

    +

    Features:

    +
      +
    • Unreal - Added FMODStudioModule::GetDefaultLocale to get the default locale which can be changed in the FMOD Settings.
    • +
    +

    Fixes:

    +
      +
    • Studio API - Fixed live update crash if tweaking an Event with an empty single sound instrument.
    • +
    • Studio API - Fixed potential crash if releasing an EventInstance from the Stop callback.
    • +
    • Studio API - Fixed third party DSP plugins causing potential assert by calling DSP::setParameterDSP on effects managed by Studio.
    • +
    • Unity - Fixed Addressable banks not being built when building with batchmode.
    • +
    • Unreal - Fixed rare AudioVolume Reverb Effect cast crash.
    • +
    • Unreal - Fixed crash when using Hot Reload in UE4.26 & 4.27.
    • +
    • Unreal - FMODStudioModule::GetLocale correctly now returns the currently set locale instead of the default.
    • +
    • Unreal - PS4 - Fixed audio degradation due to mixer thread competing with renderer thread.
    • +
    +

    Notes:

    +
      +
    • iOS - Now built with iOS SDK 16.4 (Xcode 14.3).
    • +
    • Mac - Now built with macOS SDK 13.3 (Xcode 14.3), min deploy target is now 10.13 as mandated by Xcode.
    • +
    • Unreal - Added support for UE5.2.
    • +
    +

    3/5/23 2.02.14 - Studio API minor release (build 133546)

    +

    Features:

    +
      +
    • Core API - Examples now have a Common_Log function for outputting to TTY.
    • +
    • Unity - Reduced time spent generating bank stubs, and reduced time spent copying banks into StreamingAssets folder when building.
    • +
    +

    Fixes:

    +
      +
    • Studio API - Fixed crash when adding parameter sheet to a playing event while live update connected.
    • +
    • Studio API - Fixed instruments starting playback with stale property values during hotswap.
    • +
    • Studio API - Fixed Global Parameters being unable to automate other Global Parameters.
    • +
    • Core API - PS5 - Fixed out-of-resources errors when decoding a large number of FMOD_CREATESAMPLE (decompress into memory) sounds encoded as AT9.
    • +
    • Core API - Win/GameCore - Fixed potential crash when an audio device reports an invalid name.
    • +
    • Unity - Fixed Find and Replace tool not finding prefabs.
    • +
    • Unity - iOS - Fixed audio not resuming after opening and closing Siri.
    • +
    • Unity - Fixed hang caused by RuntimeManager access when auditioning in timeline.
    • +
    +

    17/3/23 2.02.13 - Studio API minor release (build 132591)

    +

    Features:

    +
      +
    • Unity - Added non-Rigidbody Doppler effect option on Emitters.
    • +
    +

    Fixes:

    +
      +
    • Studio API - Fixed voice stealing failing on events in FMOD_STUDIO_PLAYBACK_STOPPING state.
    • +
    • Studio API - Fixed assert during Live Update when deleting a Global Parameter.
    • +
    • Studio API - AHDSR modulators will now have correct release behavior when the instrument stop condition is triggered by an event condition.
    • +
    • Studio API - Fixed crash when changing parameter scope on a playing event.
    • +
    • Studio API - Fixed a crash when removing automations via Live Update.
    • +
    • Core API - Fixed playback issues with certain ice/shoutcast net-streams.
    • +
    • Core API - GameCore - Fixed rare crash when playing back compressed Opus.
    • +
    • Core API - GameCore - Reduced memory usage for hardware convolution reverb.
    • +
    • Core API - Mac - Fixed crash when using input devices below 16kHz sample rate.
    • +
    • Core API - PS5 - Fixed audio output stutters when a port disconnects.
    • +
    • Core API - Win - Fixed record enumeration fails causing crash.
    • +
    • Unity - Fixed Visual Scripting units not generating in Unity 2021+.
    • +
    • Unity - Fixed plugin bundles not working on Mac.
    • +
    • Unreal - Fixed AssetLookup being modified each time the editor is opened.
    • +
    • Unreal - Fixed Editor Live Update not connecting to Studio.
    • +
    +

    Note:

    +
      +
    • GameCore - Now built with October 2022 QFE 1 GDKX.
    • +
    • Switch - Now built with SDK 15.3.0.
    • +
    +

    31/1/23 2.02.12 - Studio API minor release (build 131544)

    +

    Features:

    +
      +
    • Core API - Warning is now logged when a voice swap occurs on an voice with an audibility above -20dB.
    • +
    • Unity - Added support for Unity 2022.2.
    • +
    • Unity - macOS can now handle .dylib plugins natively
    • +
    • Unity - Android - Added support for patch build.
    • +
    +

    Fixes:

    +
      +
    • Studio API - Fixed Live Update being ignored if Studio connects before the master Bank is loaded.
    • +
    • Studio API - Fixed a potential crash updating a referenced 3D Event if it has been forcibly stopped due to bank unload.
    • +
    • Studio API - Fixed issue where using a modulated parameter to automate a property of an AHDSR modulator would sometimes cause the AHDSR to start in a bad state.
    • +
    • Studio API - Fixed VCA handles becoming invalid when live update changes them.
    • +
    • Studio API - Fixed incorrect scheduling of playlist entries in multi instruments that have pitch changes.
    • +
    • Core API - Switch - Fixed potential Opus crash when streaming with custom async IO callbacks.
    • +
    • Core API - PS5 + GameCore - Hardware resource configuration (performed using platform specific FMOD APIs) will now apply during System::init rather than System::create.
    • +
    • Unity - The EventReferenceDrawer "Open in Browser" button now functions when there is no event selected.
    • +
    • Unity - Fixed EventRefDrawer showing incorrect "Migration target X is missing" messages on sub-object fields with MigrateTo specified.
    • +
    • Unity - Fixed hang when RuntimeManager called outside of main thread.
    • +
    • Unity - The Update Event References menu command now scans non-MonoBehaviour objects that are referenced by MonoBehaviours.
    • +
    • Unity - Fixed warning "Settings instance has not been initialized...".
    • +
    • Unity - Fixed 'multiple plugins with same name' error on Mac.
    • +
    • Unreal - Fixed occlusion not working from Audio Component reloaded from a streamed level.
    • +
    • Unreal - Fixed commandlet crashing when trying to delete assets.
    • +
    • Win - Fixed examples not rendering correctly on Windows 11.
    • +
    +

    Notes:

    +
      +
    • Unity - Added an example on how to pipe audio from a VideoPlayer into FMOD.
    • +
    • iOS - Re-enabled compilation of the now deprecated Bitcode to appease toolchains such as Unity that still require it.
    • +
    • PS4 - Now built with SDK 10.008.001.
    • +
    • PS5 - Now built with SDK 6.00.00.38.
    • +
    +

    01/12/22 2.02.11 - Studio API minor release (build 130436)

    +

    Features:

    +
      +
    • Studio API - Studio::System::getBus ("bus:/", ...) will now return the master bus if the master bank has been loaded, even if the strings bank has not.
    • +
    • Core API - GameCore - Added in FMOD_GameCore_XMAConfigure. This can be used to control whether to allocate XMA codec hardware resources inside FMOD::System_Create:: If not called before FMOD::System_Create the resources will be allocated on first codec use.
    • +
    • Core API - Mac - Added support for 7.1.4 output type.
    • +
    • Core API - PS5 - Added in FMOD_PS5_AT9Configure. This can be used to control whether to allocate AT9 codec hardware resources inside FMOD::System_Create:: If not called before FMOD::System_Create the resources will be allocated on first codec use.
    • +
    • Unity - Android - Added support for x86_64.
    • +
    • Unreal - Added a Sound Stopped callback to the FMODAudioComponent.
    • +
    +

    Fixes:

    +
      +
    • Studio API - Fixed crash when connecting live update and a bank was loaded multiple times with FMOD_STUDIO_LOAD_BANK_NONBLOCKING flag.
    • +
    • Studio API - Fixed every asset in an Audio Table being parsed when only one item is required.
    • +
    • Studio API - Logging more meaningful error message when attempting to get/set listener properties with an invalid listener index.
    • +
    • Core API - Fixed recording not starting immediately after changing output devices.
    • +
    • Core API - Fixed AAudio no-sound issue if device disconnection occurs during initialization.
    • +
    • Core API - Fixed a stall in Sound::release on nonblocking sounds.
    • +
    • Unity - Added optimized DistanceSquaredToNearestListener method to avoid unnecessary square root.
    • +
    • Unity - Fixed StudioEventEmitter clearing handle prematurely when Allow Fadeout enabled.
    • +
    • Unity - Fixed FMODStudioEventEmitter inspector not updating displayed min and max attenuation when banks refreshed.
    • +
    • Unity - Error now logged when accessing RuntimeManager from Editor-only callsite.
    • +
    • Unity - Fixed EventReferenceDrawer input losing focus when not found warning appears.
    • +
    • Unreal - Fixed BankLookup.uasset being modified whenever banks get refreshed while using split banks.
    • +
    +

    Notes:

    +
      +
    • Unreal - Added support for UE5.1.
    • +
    • iOS - Now built with iOS SDK 16.0 (Xcode 14.0.1), min deploy target is now 11.0 and 32bit support has been removed as mandated by Xcode.
    • +
    • Mac - Now built with macOS SDK 12.3 (Xcode 14.0.1).
    • +
    +

    28/10/22 2.02.10 - Studio API minor release (build 129212)

    +

    Features:

    + +

    Fixes:

    +
      +
    • Studio API - Fixed a race condition where the Studio API could delete DSP parameter data before the DSP was released.
    • +
    • Core API - Fixed bug with fallback realloc copying excess memory when memory callbacks being overridden but a realloc wasn't provided.
    • +
    • Core API - Fixed crash with .MOD format with a particular combination of commands.
    • +
    • Core API - Fixed potential FMOD_ERR_INVALID_PARAM from System::setDriver if the device list has changed since a previous call to that function.
    • +
    • Core API - Fixed potential crash when a Send mixes to an partially initialized Return. This crash can occur in the Studio API also.
    • +
    • Core API - Fixed potential access violation due to internal Sound Group list corruption.
    • +
    • Core API - Fixed Channel::setLoopPoints not applying if the stream decode buffer is larger than the Sound.
    • +
    • Unity - Removed benign errors originating from EventInstance::set3DAttributes calls when API Error Logging is enabled.
    • +
    • Unity - Fixed platform warning appearing unnecessarily.
    • +
    • Unreal - Fixed BankLookup.uasset being modified whenever banks get refreshed while using split banks.
    • +
    +

    Notes:

    +
      +
    • Unreal - Added support for UE5.1 preview 2.
    • +
    +

    26/09/22 2.02.09 - Studio API minor release (build 128289)

    +

    Features:

    +
      +
    • Studio API - Error now logged when attempting to set a readonly Parameter, or when attempting to set a Global Parameter from an EventInstance.
    • +
    • Core API - Deprecated Sound.readData(IntPtr, uint, out uint) in C# wrapper. Instead use Sound.readData(byte[], out uint) or Sound.readData(byte[]).
    • +
    • Core API - Added FMOD_SYSTEM_CALLBACK_RECORDPOSITIONCHANGED callback to notify when new data recorded to FMOD::Sound.
    • +
    • Core API - GameCore - Increased the limits of SetXApuStreamCount to match Microsoft documented maximums.
    • +
    • Unity - Added UnloadBank overloads for TextAsset and AssetReference.
    • +
    • Unreal - Added "Enable API Error Logging" option to Advanced settings section. Integration will log additional internal errors when enabled.
    • +
    • Unreal - LoadBank node "Blocking" enabled by default.
    • +
    +

    Fixes:

    +
      +
    • Core API - Fixed potential crash if calling DSP::setParameter on a Pan DSP when using the Studio API.
    • +
    • Core API - Fixed ChannelGroup::setPaused (false) to behave the same as Channel, ensuring any 3D calculations are performed before becoming audible.
    • +
    • Core API - Fixed Opus producing different FSBank result on AMD and Intel CPUs.
    • +
    • Core API - Fixed errors in the calculatePannerAttributes() function presented in Core API Guide section 3.5 Controlling a Spatializer DSP (formerly Driving the Spatializer).
    • +
    • Core API - Increased net streaming max URL length to 2048.
    • +
    • Core API - GameCore - Fixed potential XApu stream leak when playing a multi-channel Sound as the hardware limit is reached.
    • +
    • Core API - iOS - Fixed potential crash during System::mixerSuspend / System::mixerResume when playing audio with the platform native AudioQueue (AAC) decoder.
    • +
    • Core API - iOS - Fixed simulator detection.
    • +
    • Core API - Mac - Fixed CoreAudio crash when output device reports >32 outputs.
    • +
    • Core API - Win - Fixed WinSonic crash when the device list changes before System::init.
    • +
    • Resonance - Android - Removed dependency on libc++_shared.so.
    • +
    • Unity - Fixed FMODStudioSettings.asset marked dirty every time Editor reopens.
    • +
    • Unity - Prevented unnecessary allocation when setting parameter on an FMOD StudioEventEmitter.
    • +
    • Unity - Fixed errors when upgrading Unity versions.
    • +
    • Unreal - Provided default values to prevent various initialization warnings.
    • +
    +

    Notes:

    +
      +
    • Unreal - Moved various internal functions and fields to private.
    • +
    +

    15/08/22 2.02.08 - Studio API minor release (build 126901)

    +

    Features:

    +
      +
    • Core API - Added FMOD_INIT_CLIP_OUTPUT flag to enable hard clipping of float values.
    • +
    • Core API - GameCore - Added SetXApuStreamCount and XDspConfigure to C# wrapper.
    • +
    • Core API - PS5 - Added AcmConfigure and AjmConfigure to the C# wrapper.
    • +
    • Core API - PS5 - Opus hardware decoding is now supported.
    • +
    • Core API - PS5 - Added vibration support for the PSVR2 controller via FMOD_PORT_INDEX_FLAG_VR_CONTROLLER.
    • +
    • Unity - Timeline events now begin playback from relative playhead position when auditioning in the timeline.
    • +
    +

    Fixes:

    +
      +
    • Studio API - EventDescription::is3D now returns the correct result if the Event uses SpeedAbsolute or DistanceNormalized parameters. Requires bank rebuild.
    • +
    • Core API - Fixed ASIO driver enumeration crash caused by invalid driver.
    • +
    • Core API - Fixed incorrect thread IDs being used on pthread based platforms.
    • +
    • Core API - Fixed System::setReverbProperties / FMOD_DSP_TYPE_SFXREVERB not working with 7.1.4 input.
    • +
    • Core API - Fixed crash from reading bad m3u file.
    • +
    • Core API - Fixed the memory tracking system sometimes running out of memory.
    • +
    • Core API - GameCore - Fixed potential crash when there are insufficient xAPU resources remaining.
    • +
    • Core API - Win - Fixed crash in device enumeration cleanup.
    • +
    • Core API - C# - Some callback types renamed in fmod_dsp.cs to match C header. DSP_CREATECALLBACK becomes DSP_CREATE_CALLBACK for example.
    • +
    • Unity - Updated deprecated GameCore build target and runtime platform for Unity 2019.4.
    • +
    • Unity - Fixed issue with "Desktop" being added to build path twice when selecting "Multiple Platform Build" Source Type.
    • +
    • Unity - Fixed issue with HaveAllBanksLoaded not working when banks loaded via AssetReferences.
    • +
    • Unity - Fixed UnsatisfiedLinkError crash on Android when no FMODUnity components present.
    • +
    • Unity - Improved readability of folders in CreateEventPopup.
    • +
    • Unreal - Fixed Blueprint LoadBank not correctly honouring Load Sample data flag.
    • +
    • Unreal - Removed spurious log warning about initial value of global parameters.
    • +
    • Unreal - Fixed memory leak when using PlayEventAttached in nosound mode.
    • +
    +

    Notes:

    +
      +
    • Switch - Now built with SDK 14.3.0.
    • +
    • Unreal - Added support for UE5.0.3.
    • +
    +

    18/05/22 2.02.07 - Studio API minor release (build 125130)

    +

    Features:

    +
      +
    • Core API - HTML5 - FMOD now handles user interaction internally to allow sound to work. The developer no longer has to handle boilerplate code to allow user interaction.
    • +
    • FSBank API - Mac - Added FSBankLib.
    • +
    • Unreal - Added support for speaker mode 7.1.4 in the editor settings.
    • +
    • Unreal - Added separate platforms settings for a variety of options.
    • +
    +

    Fixes:

    +
      +
    • Studio API - Fixed steal quietest not working correctly causing new EventInstances to think they are the quietest and not play.
    • +
    • Core API - Fixed ChannelGroup::setPitch when applied to the master channel group causing exaggerated pitch changes as time goes on.
    • +
    • Core API - HTML5 - Fixed integer overflow crash in fastcomp builds after 70 mins.
    • +
    • Core API - Linux - Fixed potential hang on shutdown due to bad sound drivers.
    • +
    • Core API - Linux - Fixed crash during System::init if using System::setOutput (FMOD_OUTPUTTYPE_PULSEAUDIO) on a machine without PulseAudio.
    • +
    • Unity - Fixed an error occurring when a timeline playhead leaves an event playable.
    • +
    • Unity - Added missing EventReference overload for PlayOneShotAttached.
    • +
    • Unity - Fixed refcount not updating when LoadBank called with TextAsset.
    • +
    • Unity - Fixed scene hanging when auditioning timeline.
    • +
    • Unity - Fixed events in timeline not refreshing when banks updated.
    • +
    • Unity - Fixed platform objects on Settings asset showing no name in the project window.
    • +
    • Unity - Fixed stale event name left behind after clearing an FMODEventPlayable's event reference field.
    • +
    • Unity - Fixed an error caused by changing an event reference while an event is being previewed in the browser.
    • +
    • Unity - HTML5 - Fixed the audio not playing in the Safari web browser.
    • +
    • Unreal - Fixed not being able to audition events in the editor.
    • +
    • Unreal - Fixed Editor crash when importing bank with paths containing a period.
    • +
    +

    Notes:

    +
      +
    • PS4 - Now built with SDK 9.508.001.
    • +
    • PS5 - Now built with SDK 5.00.00.33.
    • +
    • Unreal - Added support for UE5.
    • +
    +

    16/03/22 2.02.06 - Studio API minor release (build 124257)

    +

    Features:

    +
      +
    • Core API - Android - Added support for loading sounds via Uri paths.
    • +
    • Unity - Added ability to set individual channel counts for each codec format supported by a given platform.
    • +
    +

    Fixes:

    +
      +
    • Studio API - Fixed issue where certain timeline instruments were causing EventDescription::isOneshot to incorrectly return false. This requires banks to be rebuilt to take effect.
    • +
    • Core API - Fixed rare vorbis decoding error.
    • +
    • Core API - Fixed crash in OutputASIO::stop if start has not been called.
    • +
    • Core API - Fixed static noise or clicks when using DSP::setWetDryMix.
    • +
    • Core API - Fixed FMOD_CODEC_METADATA macro parameters.
    • +
    • Core API - Fixed bad ASIO driver causing enumeration to fail.
    • +
    • Core API - Android - Fixed crash from headset detection with incorrect Java lifetimes.
    • +
    • Core API - HTML5 - Fixed an issue where FMOD_OUTPUTTYPE_AUDIOWORKLET would crash if the speaker mode setup was greater than stereo while refreshing the web browser.
    • +
    • Core API - PS5 - Fixed a crash in the convolution reverb to do with deallocating GPU memory.
    • +
    • Core API - UWP - Fixed corrupted audio using certain headsets that implement virtual surround sound such as those from Razer.
    • +
    • Core API - Win - Fixed WASAPI device enumeration failure causing initialization to fail.
    • +
    • Unity - Fixed il2cpp crash caused by CREATESOUNDEXINFO callbacks not being marshaled when loading sounds from audio tables.
    • +
    • Unity - Fixed event browser preview area not initially displaying at correct size.
    • +
    • Unity - Fixed error shown when attempting to delete Default and Editor platforms.
    • +
    • Unity - Fixed audible glitches on PS4 and PS5 due to FMOD feeder thread getting blocked.
    • +
    • Unity - Fixed enumeration of bank folders when creating an event from an event reference field in the inspector.
    • +
    • Unity - Fixed error if Resonance Listener is not on the Master Bus.
    • +
    • Unity - Fixed banks being reimported with every build when set to AssetBundle import type.
    • +
    • Unity - Fixed cached events losing GUIDs after updating from a 2.01 or earlier integration.
    • +
    • Unreal - Fixed crash when importing banks containing ports.
    • +
    • Unreal - Fixed net streams not working with programmer sounds.
    • +
    • Unreal - Fixed problem locking all buses on bank load if banks haven't finished loading.
    • +
    • Unreal - Fixed AudioComponent::OnEventStopped sometimes being called twice.
    • +
    • Unreal - Fixed FMODAudioComponents inside AudioVolumes not having the correct AmbientVolumeParameter value when Started after being Stopped.
    • +
    +

    Notes:

    +
      +
    • GameCore - Now built with October 2021 QFE 1 GDKX.
    • +
    • Stadia - Now built with SDK 1.71.
    • +
    • Switch - Now built with SDK 13.3.0.
    • +
    • Unity - GameCore - Now built with June 2021 QFE 4 GDKX.
    • +
    • Unreal - Added support for UE5.0 preview 1.
    • +
    +

    06/02/22 2.02.05 Patch 1 - Studio API patch release (build 123444)

    +

    Fixes:

    +
      +
    • Studio API - Fixed crash when allocating internal pool resources. Introduced 2.02.05.
    • +
    +

    Notes:

    +
      +
    • Due to the severity of the above mentioned issue, the previous release of 2.02.05 has been withdrawn and should not be used.
    • +
    +

    21/12/21 2.02.05 - Studio API minor release (build 122665)

    +

    Features:

    + +

    Fixes:

    +
      +
    • Studio API - Fixed issue where an async instrument would not trigger if its delay interval was greater than its length on the timeline.
    • +
    • Studio API - Fixed issue where the description of an event retrieved from a start event command would have an invalid handle unless first retrieved via Studio::System::getEvent.
    • +
    • Studio API - Start Event Command Instrument now gracefully handles the case when the event it is trying to start has not been loaded.
    • +
    • Studio API - Fixed issue where the scatterer instrument can spawn instruments inconsistently under certain conditions.
    • +
    • Studio API - Fixed issue where audibility based stealing would not use FMOD_DSP_PARAMETER_OVERALLGAIN::linear_gain_additive in its calculation. For events using the object spatializer or the resonance audio source this would cause the attenuation to be ignored for stealing.
    • +
    • Studio API - Improved general Studio API performance.
    • +
    • Studio API - Improved determination of whether a nested event will end, reducing the incorrect cases where it would be stopped immediately.
    • +
    • Studio API - Fixed Studio::EventInstance::getMinMaxDistance returning -1 before event starts playing.
    • +
    • Core API - GameCore - Fixed very rare Opus decoding hang.
    • +
    • Core API - GameCore - Improved convolution reverb XDSP recovery in case of unexpected hardware failure.
    • +
    • Core API - Linux - PulseAudio now attempts to load and connect for detection rather than running 'pulseaudio --check'. This improves PipeWire compatibility.
    • +
    • Unity - Fixed event reference updater not handling multiple game objects with the same path.
    • +
    • Unity - Fixed setup window showing event reference update step as completed when incomplete tasks remained.
    • +
    • Unreal - FMOD plugin no longer overwrites existing Unreal editor style.
    • +
    • Unreal - Fixed BankLookup being regenerated unnecessarily.
    • +
    • Unreal - Fixed FMODAudioComponent not handling streaming levels correctly.
    • +
    • Unreal - XSX - Fixed builds not finding fmod libs.
    • +
    • Unity - Fixed platform-specific settings not being saved.
    • +
    +

    Notes:

    +
      +
    • Stadia - Now built with SDK 1.62, LLVM 9.0.1.
    • +
    • Unity - First-time installation no longer requires an event reference update scan.
    • +
    • Unity - Event reference update tasks now display their completion status and can no longer be redundantly run multiple times.
    • +
    • Unity - Editor now restores scene setup after finishing execution of event reference update tasks.
    • +
    +

    19/11/21 2.02.04 - Studio API minor release (build 121702)

    +

    Features:

    +
      +
    • Core API - Added support for FMOD_SYSTEM_CALLBACK_DEVICELISTCHANGED with multiple Systems
    • +
    • Core API - Switch - Added Opus decoding for streams.
    • +
    • Unity - HTML5 - Added support for Unity 2021.2.
    • +
    +

    Fixes:

    +
      +
    • Studio API - When loading pre 2.02 banks, Studio::EventDescription::getMinMaxDistance will now provide a minimum and maximum value based on the spatializers of that event instead of 0.
    • +
    • Core API - Fixed potential crash / error / corruption if using Object spatializer and multiple listeners.
    • +
    • Core API - Improve handling of disconnected devices.
    • +
    • Core API - Fixed incorrect audibility calculation causing some sounds to incorrectly go virtual when sends are involved.
    • +
    • Core API - iOS - Fixed crash when suspending multiple FMOD::System objects while using the AudioQueue codec.
    • +
    • Core API - ARM based iOS / Mac / Switch. Three EQ effect optimized to be up to 2x faster.
    • +
    • Core API - Android and macOS - Now use Monotonic clock instead of Wall clock.
    • +
    • Core API - Win - Fixed issue where WASAPI would fail to gracefully handle an invalidated device due to a disconnection during initialization.
    • +
    • Unity - Added a prompt to update the FMOD folder metadata if necessary so that it can be moved to any location in the project.
    • +
    • Unity - Fixed a bug causing the Event Browser to be in an invalid state when reopening the Unity Editor.
    • +
    • Unity - Fixed a bug that caused stale cache assets to not be cleared correctly.
    • +
    • Unity - Fixed attenuation override values not updating until next GUI change when a new event is selected for an emitter.
    • +
    • Unity - Fixed a denied access error when updating FMOD for Unity integration.
    • +
    • Unity - Fixed the bank cache refresh failing when the event browser is open.
    • +
    • Unity - Android - Fixed command line builds not using split application binary.
    • +
    • Unity - Mac - Added a prompt to fix bad line endings in FMOD bundle Info.plist files if necessary (these could cause DllNotFoundException errors).
    • +
    • Unity - Fixed an error preventing command line builds from completing.
    • +
    • Unreal - Linux - Fixed missing libs.
    • +
    +

    Notes:

    +
      +
    • GameCore - Now built with June 2021 QFE 2 GDKX.
    • +
    • PS4 - Now built with SDK 9.008.001.
    • +
    • PS5 - Now built with SDK 4.00.00.31.
    • +
    • Switch - Now built with SDK 12.3.7.
    • +
    • Unity - Removed obsolete x86 Linux binaries.
    • +
    • Unity - RuntimeManager's AnyBankLoading and WaitForAllLoads methods have been renamed for clarity (to AnySampleDataLoading and WaitForAllSampleLoading respectively), retaining the same functionality. The previous methods remain for compatibility but are considered deprecated.
    • +
    +

    08/09/21 2.02.03 - Studio API minor release (build 120077)

    +

    Features:

    +
      +
    • Core API - It is now possible to specify the Opus codec count via FMOD_ADVANCEDSETTINGS, previously it was hardcoded to 128.
    • +
    • Core API - PS5 - Added ACM convolution reverb support.
    • +
    • Core API - GameCore - Added XDSP convolution reverb support on Scarlett hardware.
    • +
    • Core API - Win, GameCore, XBoxOne - Added recording support to WinSonic.
    • +
    • Unity - Added EventReference.Find() to make setting default values on EventReference fields more convenient.
    • +
    • Unreal - UE4.26 on - Integration setup will now offer to add generated assets to package settings.
    • +
    • Unreal - UE4.26 on - Added Commandlet to support generating assets from command line.
    • +
    • Unity - Added IsInitialized property to EventManager to make it easier to know when EventManager is safe to call.
    • +
    +

    Fixes:

    +
      +
    • Studio API - Fixed buffer overflow issues with command replays, system is now more robust against failure and buffers have grown to handle demand.
    • +
    • Studio API - Fixed issue where automating a labelled parameter under specific circumstances would produce an incorrect result.
    • +
    • Studio API - Fixed 7.1.4 sends losing their height speakers at the return.
    • +
    • Studio API - Fixed issue where event instruments inside a multi instrument were unable to be seemlessly looped with simple events.
    • +
    • Studio API - Streaming instruments no longer can have the end of the audio cut off if they take too long to load.
    • +
    • Studio API - Fixed volume spike at start of multi instruments using both fade curves and seek offsets.
    • +
    • Core API - Fixed issue with System::registerCodec returning FMOD_ERR_PLUGIN_VERSION regardless of FMOD_CODEC_DESCRIPTION apiversion.
    • +
    • Core API - Fixed convolution reverb crash if out of memory.
    • +
    • Core API - Fixed rare audio corruption / noise burst issue.
    • +
    • Core API - Fixed FSBankLib AT9 encoder failing with an internal error on newer versions of libatrac9.dll, 4.3.0.0 onward.
    • +
    • Core API - Fixed potential crash when up-mixing quad to 5.1.
    • +
    • Core API - GameCore - Reduced the chances of running out of Opus streams when playing back Opus compressed banks on Scarlett hardware.
    • +
    • Core API - Linux - Added support for automatic device switching.
    • +
    • Core API - Android - Fixed issue where AAudio would restart occasionally on certain devices.
    • +
    • Core API - Android - Fixed issue where AAudio would would request an amount of data far larger than its burst size on certain devices.
    • +
    • Unity - Fixed a bug where settings could be accessed while an asset database refresh was in progress, causing settings to be wiped.
    • +
    • Unity - Fixed live update breaking when domain reload is disabled.
    • +
    • Unity - Fixed an invalid handle error that would occur when an attached instance ends.
    • +
    • Unity - Fixed StudioParameterTrigger and StudioGlobalParameterTrigger not receiving Object Start and Object Destroy events.
    • +
    • Unity - Fixed the attenuation override values being overwritten when selecting multiple event emitters.
    • +
    • Unity - Fixed global parameter trigger browser showing other FMOD folders.
    • +
    • Unity - Fixed referenced events not being played when an event is previewed in the event browser if the referenced events are in a different bank.
    • +
    • Unity - Fixed RuntimeManager.MuteAllEvents not working in editor.
    • +
    • Unity - Fixed bank names including the .bank file extension when Load Banks is set to Specified.
    • +
    • Unity - Fixed a bug allowing multiple localized banks to be loaded and preventing them from being unloaded.
    • +
    • Unity - Fixed compatibility of native libraries changing after build.
    • +
    • Unity - Fixed stretched logo texture in setup wizard when targeting iOS as build platform.
    • +
    • Unity - Fixed an error caused by auditioning events with global parameters in the event browser.
    • +
    • Unity - Fixed an error state caused by inspecting a game object that contains both a Unity Image and an FMOD StudioEventEmitter.
    • +
    • Unity - Fixed staging instructions appearing for fresh integration installations.
    • +
    • Unity - Fixed an exception caused by disconnected prefab instances when updating event references.
    • +
    • Unreal - Fixed FMODAudioComponents continuing to play after actors have been destroyed.
    • +
    • Unreal - Fixed 'Reload Banks' menu option.
    • +
    • Unreal - Fixed error when building installed engine with FMOD plugin.
    • +
    +

    Notes:

    +
      +
    • GameCore - Now built with June 2021 QFE 1 GDKX.
    • +
    • Stadia - Now built with SDK 1.62
    • +
    • Unity - Removed a sleep loop in StudioEventEmitter.Start().
    • +
    • Unreal - Added support for UE4.27.
    • +
    +

    26/07/21 2.02.02 - Studio API minor release (build 118084)

    +

    Features:

    +
      +
    • Core API - Mac - Added Dolby PLII downmix support.
    • +
    • Unity - When Event Linkage is set to Path, the EventReference property drawer and Event Reference Updater tool can now update paths for events which have been moved in FMOD Studio (detected via matching GUIDs).
    • +
    • Unity - Console logging from the plugin now follows the logging level specified for FMOD.
    • +
    • Unity - Improved the Asset Bundle import type to better support Addressables: FMOD now creates a stub asset for each source .bank file, which can be added to version control and to Addressables Groups. Stub assets are replaced with source .bank files at build time, and reverted to stubs after each build.
    • +
    +

    Fixes:

    +
      +
    • Studio API - Fixed issue where silence instruments placed after a set parameter command instrument would be skipped.
    • +
    • Studio API - Fixed popping that would occur with fade curves and multi instruments in the right conditions.
    • +
    • Studio API - Fixed issue where automation and modulation would not evenly distribute values for discrete parameters.
    • +
    • Studio API - Fixed sustain point behavior where the sustain point is at the same time as the end of a loop region.
    • +
    • Studio API - Async instruments with infinite loop counts will play out their last loop after being untriggered.
    • +
    • Studio API - Scatterer instruments that have been untriggered will no longer fade out child instruments.
    • +
    • Studio API - Fixed issue where scatterer instruments would spawn instruments inconsistently.
    • +
    • Studio API - Fixed a stack overflow when releasing a very large number of events in a single frame.
    • +
    • Core API - Fixed FMOD::CREATESOUNDEXINFO::initialseekposition causing sound to not stop at the correct time.
    • +
    • Core API - Fixed disconnecting channel groups from ports when multiple instances of the same port are connected.
    • +
    • Core API - Fixed a possible crash by increasing the stack size of the file thread from 48k to 64k.
    • +
    • Core API - Fixed Object Spatializer getting out of sync with the mixer when the mixer buffer is starved, this could also cause asserts to appear the log.
    • +
    • Core API - GameCore - Fixed a race condition that could cause a hang when playing Opus compressed audio.
    • +
    • UE4 - Fixed default locale setting not working in cooked builds.
    • +
    • Unity - Fixed references in EventReferenceUpdater.cs to classes unavailable when the Unity Timeline package is missing.
    • +
    • Unity - Fixed event browser being unable to audition events when an encryption key is in use.
    • +
    • Unity - Fixed setup wizard not marking current scene as dirty when replacing Unity audio listeners.
    • +
    • Unity - Fixed banks failing to load on Mac when the project is saved in Unity on Windows.
    • +
    • Unity - Fixed a crash caused by disabling API error logging.
    • +
    • Unity - Fixed benign errors being logged to the console when API logging is enabled.
    • +
    • Unity - Fixed all banks being reimported whenever the banks are refreshed, even if nothing has changed.
    • +
    • Unity - Fixed an exception being thrown when building if version control is enabled.
    • +
    • FSBank - Fixed compatibility issue with Windows 7.
    • +
    • Profiler - Fixed compatibility issue with Windows 7.
    • +
    +

    Notes:

    +
      +
    • HTML5 - Now built with SDK 2.0.20 (Upstream) and SDK 1.40.1 (Fastcomp).
    • +
    • iOS - Now built with iOS SDK 14.5 (Xcode 12.5.1).
    • +
    • Mac - Now built with macOS SDK 11.3 (Xcode 12.5.1), min deploy target is now 10.9 as mandated by Xcode.
    • +
    • Unity - Moved images into the Assets/Plugins/FMOD folder.
    • +
    • Unreal - Added support for UE5.0 (EA1).
    • +
    +

    26/05/21 2.02.01 - Studio API minor release (build 116648)

    +

    Features:

    +
      +
    • Studio API - Added FMOD_STUDIO_EVENT_CALLBACK_NESTED_TIMELINE_BEAT which returns a FMOD_STUDIO_TIMELINE_NESTED_BEAT_PROPERTIES containing the event's id.
    • +
    • Studio API - Added an FMOD_STUDIO_PARAMETER_LABELED flag.
    • +
    • Core API - Added loudness meter to the DSP API. The loudness meter is intended for development purposes and is not recommended to be included in shipped titles.
    • +
    • Unity - Improved the UI for setting values on discrete and labeled parameters.
    • +
    • Unity - Added FMODUnity.Settings.ForceLoggingBinaries to force FMOD to use the logging binaries even when BuildOptions.Development is not set.
    • +
    • Unity - Added the ability to set global parameters when auditioning an event.
    • +
    +

    Fixes:

    +
      +
    • Studio API - Improved performance of repeated calls to Studio::EventDescription::isStream and Studio::EventDescription::isOneShot.
    • +
    • Studio API - Removed potential for performance hit from retrieving final volume and final pitch values due to thread contention.
    • +
    • Studio API - Fixed issue with audio device switching.
    • +
    • Studio API - Restrict maximum number of non-zero length transitions to 31 per update to prevent overloading the scheduler.
    • +
    • Core API - GameCore - Fixed error log (assert) with logging build when playing multichannel Opus.
    • +
    • Core API - GameCore - Fixed rare Opus failure / hang when playing streams.
    • +
    • Core API - GameCore - Fixed error log (assert) when seeking XMA streams near the file end.
    • +
    • Core API - Win/UWP/GameCore - Fixed WinSonic not falling back to no-sound automatically if no devices are available.
    • +
    • Core API - C# - Unblocked potential stalls when calling Studio::EventInstance::getVolume / Studio::EventInstance::getPitch when finalVolume / finalPitch isn't requested.
    • +
    • Unity - Fixed global parameters disappearing if banks are refreshed when the master bank hasn't changed.
    • +
    • Unity - Fixed the setup wizard's Updating page status being reset whenever scripts are recompiled.
    • +
    • Unity - Fixed errors that occur when Settings.OnEnable() is called on an object that is already initialized (e.g. "Cleaning up duplicate platform" and "An item with the same key has already been added").
    • +
    • Unity - Reverted binary selection at build time to the old method of checking for BuildOptions.Development in BuildReport.summary.options, as checking for the DEVELOPMENT_BUILD symbol was failing in some situations and causing DllNotFoundExceptions.
    • +
    • Unity - Fixed bank sizes not being displayed in the event browser.
    • +
    • Unity - Fixed compiler errors that appear when Unity's Physics and Physics 2D packages are disabled.
    • +
    • Unity - Fixed "The name 'StaticPluginManager' does not exist" error when calling AddressableAssetSettings.BuildPlayerContent() on IL2CPP platforms.
    • +
    • Unity - Removed cleanup of RegisterStaticPlugins.cs when a build finishes, in order to avoid recompiling scripts unnecessarily.
    • +
    • Unity - Create the Assets/Plugins/FMOD/Cache folder if it does not exist when generating RegisterStaticPlugins.cs during a build.
    • +
    +

    Notes:

    +
      +
    • Unity - Added type-specific icons for global parameters in the event browser.
    • +
    • Unity - Removed conditional code below Unity 2019.4 minimum specification.
    • +
    • PS4 - Now built with SDK 8.508.
    • +
    • PS5 - Now built with SDK 3.00.00.27.
    • +
    +

    15/04/21 2.02.00 - Studio API major release (build 115890)

    +

    Features:

    + +

    Fixes:

    +
      +
    • Studio API - Fixed behavior interaction between timelocked multi instruments and sustain points so that multi instruments will play from the same point that they were stopped via the sustain point.
    • +
    +

    Notes:

    + +

    12/02/21 2.01.09 - Studio API minor release

    +

    Features:

    +
      +
    • Studio API - Added FMOD_STUDIO_SYSTEM_CALLBACK_LIVEUPDATE_CONNECTED and FMOD_STUDIO_SYSTEM_CALLBACK_LIVEUPDATE_DISCONNECTED.
    • +
    • Studio API - Added Studio::EventDescription::isDopplerEnabled. Will return false with banks built prior to 2.01.09.
    • +
    • Unity - Added a Volume property to FMOD Event Tracks.
    • +
    • Unity - Improved plugin lib updates by automating the process in a few simple steps.
    • +
    • Unity - Added 7.1.4 speaker mode to Project Platform in the settings menu.
    • +
    • Unity - Added support for generating unit options for Unity 2021 Visual Scripting package.
    • +
    • Unity - Added option to enable error reporting to Unity console from internal FMOD system.
    • +
    • Unity - Added a Setup Wizard to help with adding FMOD to projects.
    • +
    +

    Fixes:

    +
      +
    • Studio API - Fixed possible memory corruption due to race condition between user code creating sounds asynchronously using sound info from an audio table and unloading the bank containing the audio table.
    • +
    • Studio API - Improved error detection and documentation regarding the requirement of loading asset banks at the same time as metadata banks.
    • +
    • Studio API - Fixed issue where stopping conditions on nested events without ahdsr modulators would not play out when the parent event is still playing and the nested event becomes untriggered.
    • +
    • Studio API - Fixed issue where hot swapping an event via live update would invalidate the API handle.
    • +
    • Studio API - Fixed incorrect count from Studio::Bank::getEventCount when loading banks built with 1.07, 1.08 or 1.09.
    • +
    • Core API - Fixed substantial performance issue when connected to a profiler.
    • +
    • Core API - Fixed sync points potentially being skipped as Channels transition from virtual to real.
    • +
    • Core API - Fixed warning being logged about truncated files on user created sounds.
    • +
    • Core API - Fixed hang on .S3M format playback when seeking past calculated end of song with FMOD_ACCURATETIME.
    • +
    • Core API - Fixed some netstreams return FMOD_ERR_HTTP. Introduced 2.01.02.
    • +
    • Core API - Fixed potential audio corruption when using the object spatializer.
    • +
    • Core API - Fixed System::getPluginHandle returning internal only DSPs.
    • +
    • Core API - Fixed crash with Convolution Reverb. Introduced 2.01.08.
    • +
    • Core API - Fixed early and late delay support for FMOD_DSP_TYPE_SFXREVERB. Introduced 2.01.04.
    • +
    • UE4 - Add a configurable delay to automatic bank reloading to avoid a race condition between banks being rebuilt in Studio and the integration trying to reload them.
    • +
    • UE4 - Remove unsupported log levels from settings.
    • +
    • UE4 - Fixed blueprint AnimNotify causing Editor to crash.
    • +
    • UE4 - 4.26 - Fixed asset generation regenerating assets when banks have not been modified.
    • +
    • UE4 - 4.26 - Fixed crashes caused by attempting to regenerate assets which are read-only on disk. User is now prompted to check-out or make writable assets which are read-only on disk.
    • +
    • UE4 - 4.26 - Fixed sequencer integration.
    • +
    • UE4 - 4.26 - Fixed AnimNotify not automatically loading referenced event asset.
    • +
    • UE4 - 4.26 - Fixed FindEventByName failing to load required event asset.
    • +
    • UE4 - 4.26 - Fixed crash when running with sound disabled (eg. running as A dedicated server or running with the "-nosound" command line option).
    • +
    • UE4 - iOS/tvOS - Fixed audio occasionally not returning on application resume.
    • +
    • UE4 - XboxOne - Fixed third party plugins not working.
    • +
    • Unity - Made binary selection at build time more robust by checking for DEVELOPMENT_BUILD in the active script compilation defines.
    • +
    • Unity - Fixed context menu entries being disabled on FMOD Event Playable parameter automation.
    • +
    • Unity - Fixed a hang that could occur when scripts were recompiled after a callback was fired from FMOD to managed code.
    • +
    • Unity - Fixed banks not loading on Mac if project was saved from PC to source control.
    • +
    • Unity - Fixed a number of build errors on various platforms caused by the static plugin system's use of the IL2CPP --additional-cpp command (the static plugin system now generates C# instead of C++).
    • +
    • Unity - PS5 - Removed unsupported Audio 3D option from the platform settings.
    • +
    • Unity - UWP - Fixed warnings and errors surrounding Marshal usage depending on Unity version, scripting backend and API compatibility combination.
    • +
    +

    Notes:

    +
      +
    • GameCore - Updated to February 2021 GDK.
    • +
    • UE4 - Changed default source directory for runtime bank files to Content/FMOD/Desktop. Platform specific INI files should be used to override this as appropriate.
    • +
    +

    11/02/21 2.01.08 - Studio API minor release (build 114355)

    +

    Features:

    +
      +
    • Core API - Added FMOD_SYSTEM_CALLBACK_OUTPUTUNDERRUN, which is called when a buffered mixer output device attempts to read more samples than are available in the output buffer.
    • +
    • Core API - Mac - Added Resonance Audio Apple Silicon support.
    • +
    • Unity - Improved bank refresh logic and added a status window that appears when a refresh is about to happen.
    • +
    • Unity - Added support for automating event parameters on the Timeline.
    • +
    +

    Fixes:

    +
      +
    • Studio API - Fixed fast spawning scatterer instruments with low polyphony spawning too few instruments.
    • +
    • Studio API - Fixed a memory leak that could occur when a sound got stuck in the loading state.
    • +
    • Core API - Fixed crash on .XM format playback.
    • +
    • Core API - Fixed potential hang with net streams if server returns errors.
    • +
    • Core API - Fixed extraneous logging of internal pool allocations.
    • +
    • Core API - Fixed rare crash when releasing convolution reverb DSP instances.
    • +
    • Core API - UWP - Fixed logging spam when using WASAPI output mode.
    • +
    • UE4 - Expose the Enable Timeline Callbacks property of FMOD Audio Component to blueprints.
    • +
    • UE4 - Fixed crash which could occur when an FMOD Audio Component which uses a programmer sound is destroyed by unloading the map or closing the game.
    • +
    • Unity - Fixed Discrete and Labelled global parameters that do not appear in the Event Browser.
    • +
    • Unity - Fix multiple listeners positioning not working correctly.
    • +
    • Unity - Fixed sample data failing to load when Load Bank Sample Data is enabled in a project with separate asset banks.
    • +
    • Unity - Fixed an Android build error when the Export Project option is set.
    • +
    • Unity - Fixed FMOD IL2CPP arguments being left in ProjectSettings after building, which could break builds on other operating systems.
    • +
    • Unity - Android - Fixed an IL2CPP build error on some NDK versions.
    • +
    • Unity - PS5 - Fixed compile error due to stale platform API CS file.
    • +
    • Unity - iOS/tvOS - Fixed audio occasionally not returning on application resume.
    • +
    +

    Notes:

    +
      +
    • Switch - Now built with SDK 11.4.0.
    • +
    • UE4 - Added support for UE4.26.
    • +
    +

    18/12/20 2.01.07 - Studio API minor release (build 113487)

    +

    Features:

    +
      +
    • Core API - Added FMOD_SYSTEM_CALLBACK_DEVICEREINITIALIZE.
    • +
    • Core API - Mac - Added Apple Silicon support.
    • +
    • Unity - Added support for generating unit options for Bolt visual scripting.
    • +
    • Unity - Added option to stop an emitter's event instance when the emitter is further than its maximum attenuation distance from all listeners.
    • +
    +

    Fixes:

    +
      +
    • Studio API - Command replays now record the initial state of global parameters.
    • +
    • Studio API - Fixed errors from instrument creation failure not being reported to the error callback.
    • +
    • Studio API - Fixed crash due to null pointer dereference when instrument creation fails due to running out of memory.
    • +
    • Studio API - Fixed crash when unloading a bank from the FMOD_STUDIO_EVENT_CALLBACK_STOPPED callback.
    • +
    • Studio API - Fixed crash when hot swapping a nested event and its parent where the child event is registered before the parent event.
    • +
    • Studio API - Fixed spurious warning messages when connecting Live Update.
    • +
    • Studio API - Fixed crash which could occur if a user thread loads a bank asynchronously while another thread releases the system.
    • +
    • Studio API - Switch log messages about missing plugins from warning to log level when the system is initialized with FMOD_STUDIO_INIT_ALLOW_MISSING_PLUGINS.
    • +
    • Core API - Fixed rare crash due to race condition when calling Sound::getOpenState for a sound created with FMOD_NONBLOCKING.
    • +
    • Core API - Fixed rare crash occurring some time after calling System::attachChannelGroupToPort due to internal buffer synchronization.
    • +
    • Core API - Fixed certain internet radio stations that serve up playlists failing to load correctly.
    • +
    • Core API - Fixed sidechain modulator release being cutoff if sidechain source is destroyed.
    • +
    • Core API - Linux - Fixed hang in shutdown when using ALSA as the output mode when ALSA is unable to write to the output buffer.
    • +
    • Core API - Android - Reduced AAudio fail to stop error message to a warning.
    • +
    • Core API - UWP - Fixed issue preventing loading of 32 bit x86 plugins.
    • +
    • UE4 - Fixed spurious warning messages when loading banks which use plugins.
    • +
    • UE4 - Fixed listener being stuck at world origin when using a standalone game from the editor (introduced in 2.00.12).
    • +
    • UE4 - XboxOne - Fixed users having to modify engine code to copy libs.
    • +
    • Unity - Android - Fixed Mobile Low and Mobile High platforms using the wrong bank path when on Android.
    • +
    • Unity - Prebuild debug warning added for invalid FMOD Event paths.
    • +
    • Unity - Fixed banks not being copied into the project when using Asset Bundles.
    • +
    • Unity - Fixed specified bank paths for multi platform builds.
    • +
    +

    Notes:

    +
      +
    • Core API - Changed THREAD_AFFINITY enum in C# wrapper from unsigned 64-bit integer to signed 64-bit integer, reducing the maximum supported number of cores by one.
    • +
    • GameCore - Updated to August 2020 QFE 5 GDK.
    • +
    • XboxOne - Now built with July 2018 QFE15 XDK.
    • +
    • PS4 - Resonance Audio now built with SDK 8.008.
    • +
    • PS5 - Resonance Audio now built with SDK 2.00.00.09.
    • +
    • iOS - Now built with iOS SDK 14.2 (Xcode 12.2), min deploy target for iOS is now 9.0 as mandated by Xcode.
    • +
    • Mac - Now built with macOS SDK 11.0 (Xcode 12.2).
    • +
    • Stadia - Now built with SDK 1.55.
    • +
    • Unity - Moved Timeline and Resonance Audio classes from global namespace into FMOD namespaces.
    • +
    +

    13/11/20 2.01.06 - Studio API minor release (build 112764)

    +

    Features:

    +
      +
    • Core API - Added FMOD_SYSTEM_CALLBACK_BUFFEREDNOMIX.
    • +
    • Core API - PS5 - Added support for microphone recording.
    • +
    • Unity - Added support for Addressables.
    • +
    • Unity - In Events Browser the banks folders now show when mirroring is disabled.
    • +
    • Unity - Setting Live Update port per-platform is now supported.
    • +
    • Unity - FMOD now automatically selects the release or logging version of the native libraries at build time, based on the Development Build setting.
    • +
    +

    Fixes:

    +
      +
    • Studio API - Fixed issue where tempo based scatterer would play slightly off beat.
    • +
    • Core API - Improved error message when binding to a port fails due to a permission error.
    • +
    • Core API - Android - Fixed issue where audio would disconnect while debugging.
    • +
    • UE4 - Fixed deprecation warning in FMODStudioEditorModule.
    • +
    • Unity - Fixed FMOD_ERR_MEMORY caused by leaking System objects on play-in-editor script reload.
    • +
    • Unity - Fixed volume value in debug window.
    • +
    • Unity - Prebuild debug warning added for invalid FMOD Event paths.
    • +
    • Unity - HTML5 - Fixed error when building for development.
    • +
    • Unity - Switch - Fixed a build error due to fmodplugins.cpp not being enabled.
    • +
    +

    Notes:

    + +

    09/10/20 2.01.05 - Studio API minor release (build 112138)

    +

    Features:

    +
      +
    • Core API - XboxOne and Switch - Added ResonanceAudio plugin support.
    • +
    • Core API - GameCore - Added FMOD_GameCore_SetXApuStreamCount to control reserved XApu resources.
    • +
    • Unity - Edit Settings now allows FMOD output mode to be set per-platform.
    • +
    • Unity - Added support for specifying static plugins in the FMOD Settings.
    • +
    • Unity - Added support for setting a per-platform callback handler to run custom configuration code prior to initialization.
    • +
    • Unity - Added settings to customize DSP buffer length and count per-platform.
    • +
    • Unity - Added metering channel order setting.
    • +
    • Unity - Assembly Definition files added to the FMOD plugin.
    • +
    • Unity - The FMOD scripts will now compile without the unity.timeline package installed. If you wish to use Timeline you will need to install this package for Unity 2019.1 and above.
    • +
    • Unity - GameCore - Add resonance audio support.
    • +
    • Unity - iOS - Added simulator support.
    • +
    • Unity - PS5 - Add resonance audio support.
    • +
    • GameCore - Added support for decoding Opus compressed FSBs / Banks using platform hardware acceleration on Scarlett devices. This is a preview release of this feature, please report any bugs found directly to FMOD support email.
    • +
    +

    Fixes:

    +
      +
    • Studio API - Live update socket errors are now handled gracefully, only warnings are logged.
    • +
    • Studio API - Fix marker callbacks for multiply nested events.
    • +
    • Studio API - Fixed Studio::EventDescription::is3D, Studio::EventDescription::isOneShot and Studio::EventDescription::isNested potentially returning an error when the event contains a nested reference to an event which has not been loaded.
    • +
    • Core API - Fixed crash in convolution reverb if out of memory.
    • +
    • Core API - Fixed rare crash when updating net stream metadata tags.
    • +
    • Core API - Android - Reduce popping encountered on certain handsets by dynamically adjusting latency.
    • +
    • Core API - Android - Fix issue where regular gaps in audio were encountered on handsets with using very large burst sizes.
    • +
    • Core API - Android - Fix issue where System::mixerSuspend would fail on certain handsets.
    • +
    • Core API - Mac - Fixed init returning an error when no output devices available.
    • +
    • Core API - Win - Fixed crash on Win7/8 devices with high end CPUs that support AVX-512.
    • +
    • Core API - Fix convolution crash if a small impulse was used followed by a large impulse. Introduced in 2.01.04.
    • +
    • Core API - HTML5 - Fix missing implementation of Sound::getSyncPoint/getSyncPointInfo/ addSyncPoint/deleteSyncPoint.
    • +
    • UE4 - Fixed potential null pointer dereference when updating FMOD listeners for play-in-editor session.
    • +
    • UE4 - PS5 - Disabled UE4 built-in audio to prevent crash at startup.
    • +
    • Unity - Fixed rare TimeZoneNotFoundException encountered on some devices.
    • +
    • Unity - Fixed play-in-editor not using new speaker mode when changed in settings.
    • +
    • Unity - HTML5 - Fix FMOD_ERR_UNSUPPORTED error being returned from bank loading. Introduced in 2.01.04.
    • +
    +

    Notes:

    +
      +
    • Studio API - Issues with reconnecting Live Update (primarily on mobile) have been resolved in FMOD Studio. Update to FMOD Studio 2.01.05 or higher.
    • +
    • GameCore - To produce Opus banks in FMOD Studio, add the new "Custom" platform to your project and select Opus as the encoding.
    • +
    • GameCore - Updated to June 2020 QFE 6 GDK.
    • +
    +

    10/09/20 2.01.04 - Studio API minor release (build 111454)

    +

    Features:

    +
      +
    • Studio API - Added a flag for discrete parameters to FMOD_STUDIO_PARAMETER_FLAGS
    • +
    • Core API - Convolution reverb optimizations. Now multithreaded to avoid spikes in mixer performance. Significant memory optimization with multiple instances.
    • +
    • Core API - Android - Added support for swapping output modes.
    • +
    • Core API - GameCore - Added FMOD_GAMECORE_PORT_TYPE_COPYRIGHT_MUSIC output port type.
    • +
    • Unity - Added OnEnabled and OnDisabled for StudioBankLoader.
    • +
    • Unity - Added attachedRigidbody to OnTriggerEnter and OnTriggerExit for EventHandler.
    • +
    • Unity - Updated the event browser for better performance and more consistent look and feel.
    • +
    +

    Fixes:

    +
      +
    • Core API - Android - Fixed recording support when using AAudio.
    • +
    • Core API - Android - Fixed issues with headphone detection with AAudio.
    • +
    • Core API - XboxOne - Fixed getOutputHandle not returning the IAudioClient on WASAPI.
    • +
    • UE4 - When running multiplayer PIE sessions a listener is added for each player in each viewport.
    • +
    • UE4 - Improved handling of FMOD Studio objects being renamed or removed when reloading banks. Previously it would appear that references to renamed objects were correctly handled when they were not; references in UE4 must be manually fixed up when FMOD Studio names are changed.
    • +
    • UE4 - Improved handling of unsupported characters in FMOD Studio object names.
    • +
    • Unity - Made the Studio Event Emitter initial parameter value UI handle prefab instances and multi-selections properly.
    • +
    • Unity - Fixed tooltips not working for EventRef.
    • +
    • Unity - Fixed bank loading on Android with split/non-split APKs.
    • +
    • Unity - Fixed plugin paths for Windows and Linux.
    • +
    +

    Notes:

    +
      +
    • Core API - GameCore - FMOD_GAMECORE_PORT_TYPE_MUSIC is no longer ignored by GameDVR. Use FMOD_GAMECORE_PORT_TYPE_COPYRIGHT_MUSIC for background music which should not be captured by GameDVR.
    • +
    • Stadia - Now built with SDK 1.50.
    • +
    • Android - Examples now include CMake based projects alongside the NdkBuild based projects.
    • +
    • GameCore - Updated to June 2020 QFE 4 GDK.
    • +
    +

    05/08/20 2.01.03 - Studio API minor release (build 110858)

    +

    Features:

    + +

    Fixes:

    +
      +
    • Studio API - Fixed named marker callbacks for nested events.
    • +
    • Studio API - Fixed issue with accumulating event instruments spawned by a scatterer.
    • +
    • Studio API - Fixed issue where an event instance handle would incorrectly remain valid.
    • +
    • Studio API - Improved detection of user code incorrectly using a dangling pointer from a previously destroyed Studio System object.
    • +
    • Studio API - Improve panner envelopment when source is above or below the listener.
    • +
    • Studio API - Fixed FMOD_STUDIO_PARAMETER_DESCRIPTION::maximum being 1 higher than the maximum value which could be set.
    • +
    • Studio API - Fixed discrete parameters with non-zero seek speed or velocity changing value too quickly after having their value set by an API call.
    • +
    • Studio API - Fixed stopping conditions for nested events.
    • +
    • Core API - Ignore data and fmt sections of a wave file that are contained in lists.
    • +
    • Core API - iOS - Fixed stale audio from before System::mixerSuspend playing after calling System::mixerResume.
    • +
    • Core API - iOS - FMOD initializes with FMOD_OUTPUTTYPE_NOSOUND if unable to initialize due AVAudioSessionErrorCodeCannotStartPlaying. Switching to FMOD_OUTPUTTYPE_COREAUDIO via System::setOutput is also supported.
    • +
    • Core API - Mac - Fixed automatic default device switching.
    • +
    • Core API - Win - Improved handling of IPv6 net-streams.
    • +
    • Core API - Fixed FMOD_DSP_STATE_DFT_FUNCTIONS::inversefftreal function possibly causing corrupted audio if it and FMOD_DSP_STATE_DFT_FUNCTIONS::fftreal were called from different threads.
    • +
    • UE4 - Android - Fixed issue which could cause Android packaged builds to crash at startup.
    • +
    • Unity - Fix crash in HasBankLoaded if RuntimeManager isn't initialized.
    • +
    +

    Notes:

    +
      +
    • Unity - Added GameCore platform.
    • +
    • Switch - Now built with SDK 10.4.1.
    • +
    • GameCore - Updated to June 2020 QFE 1 GDK.
    • +
    +

    01/07/20 2.01.02 - Studio API minor release (build 110199)

    +

    Features:

    +
      +
    • Core API - GameCore - Added XMA support for Scarlett.
    • +
    • Core API - GameCore - Added background music port support.
    • +
    • Core API - PS5 - Added support for all platform specific ports, including background music, controller speaker and vibration.
    • +
    • Unity - Added field for specifying a sub directory for Banks in the settings.
    • +
    +

    Fixes:

    +
      +
    • Studio API - Fixed an issue with events referencing missing parameter descriptions when parameters were unused for a platform. For old banks references to missing parameter descriptions are stripped out of the event at load time. Newer banks will always include all parameter descriptions to ensure consistency across platforms.
    • +
    • Studio API - Fixed assert that would occur when setting a parameter that in turn creates an entity that also is listening for that parameter to change.
    • +
    • Studio API - Fixed doppler calculation to use listener attenuation position.
    • +
    • Studio API - Fixed memory leak caused by creating a bus with missing bank data.
    • +
    • Studio API - Improved performance of repeated calls to Studio::EventDescription::is3D.
    • +
    • Studio API - HTML5 - Fixed loadBankMemory not allowing a UInt8 memory object type to be passed to it.
    • +
    • Core API - Fixed silence from ports when switching from no-sound back to a valid output mode with ports.
    • +
    • Core API - Fixed incorrect return of FMOD_ERR_DSP_RESERVED on ChannelGroups caused by internal race condition.
    • +
    • Core API - Fixed FMOD_LOOP_NORMAL flag not working with netstreams that have "Accept-Ranges: bytes header".
    • +
    • Core API - iOS - Fixed conflicting ogg vorbis symbols if linking FMOD against a project containing vorbis already.
    • +
    • Core API - Android - Fixed detection of headphones being plugged and unplugged via the headphone jack on some devices.
    • +
    • Core API - GameCore - Thread names will now show up in PIX.
    • +
    • Core API - PS5 - Fixed crash when looping AT9 playback, no change required, fixed by SDK 1.00.
    • +
    • Core API - PS5 - Fixed AT9 decode failure when seeking near the end of the file.
    • +
    • Core API - Stadia - Fixed crash on playback of Vorbis compressed audio.
    • +
    • Unity - Fixed "ERR_INVALID_HANDLE" errors in UWP builds.
    • +
    • Unity - Changed banks to only be copied into the project when building.
    • +
    +

    Notes:

    +
      +
    • PS4 - Resonance Audio now built with SDK 7.508.
    • +
    • PS5 - Updated to SDK 1.00.00.39.
    • +
    • UE4 - Added GameCore platform.
    • +
    • UE4 - Added support for UE4.25.
    • +
    • UE4 - Added PS5 platform.
    • +
    +

    12/05/20 2.01.01 - Studio API minor release (build 109257)

    +

    Features:

    +
      +
    • Core API - Stadia - Added microphone recording support.
    • +
    • Unity - Added support for separate listener attenuation position.
    • +
    +

    Fixes:

    +
      +
    • Studio API - Fixed issue where an instrument not on the timeline would fail to be untriggered while the timeline is inside a source transition region.
    • +
    • Studio API - Improve loudness meter performance.
    • +
    • Studio API - Fixed crash that occurs with instrument hotswaps that change the instrument and its position on the timeline while auditioning.
    • +
    • Studio API - Fixed issue where scatterer instrument would spawn streaming instruments that would exceed the polyphony limit.
    • +
    • Studio API - Fixed issue where the Studio update thread could hang trying to release an event instance where the instance being released used a streaming programmer sound which was reused by another instance and the second instance was still active.
    • +
    • Studio API - Fixed scheduling behavior of events inside multi instruments so that the event will play out async instruments, ahdsr modulators and adjust to pitch modulation before playing the next item in the multi instrument. It will still play before DSP tails.
    • +
    • Core API - Fixed potential crash in the mixer or stream thread when playing MIDI / MOD style files due to race condition.
    • +
    • Core API - Android - Fixed potential crash when opening a file using the Android asset syntax file:///android_asset/.
    • +
    • Core API - PS5 - Fixed error being returned from platform specific affinity API.
    • +
    • UE4 - Fixed possible crash during module shutdown if DLLs aren't loaded correctly.
    • +
    • UE4 - Fixed Android builds crashing at startup.
    • +
    • Unity - Linux - Fixed FMOD_ERR_HEADERMISMATCH error due to conflict between FMOD Studio and FMOD Ex (built into Unity) in 2019.3.
    • +
    • Unity - Fixed settings bank path using wrong directory separators.
    • +
    • Resonance - Fixed rare crash in Resonance Audio due to thread safety issue.
    • +
    +

    Notes:

    +
      +
    • GameCore - Updated to April 2020 GDK.
    • +
    • Stadia - Now built with SDK 1.46.
    • +
    • PS4 Now built with SDK 7.508.
    • +
    • XboxOne - Now built with July 2018 QFE13 XDK.
    • +
    • HTML5 - Now built with SDK 1.39.11, both fastcomp and upstream.
    • +
    • Unity - Added PS5 platform.
    • +
    +

    23/03/20 2.01.00 - Studio API major release (build 108403)

    +

    Features:

    +
      +
    • Studio API - Studio::System::setListenerAttributes now supports a separate position argument for attenuation.
    • +
    • Core API - Optimized mixing and vorbis decoding. Performance increase of 2-2.5x on all platforms.
    • +
    • Core API - Optimized Multiband EQ. Performance increase of 2-3x on all platforms for stereo and higher channel count processing.
    • +
    • Core API - Added cross-platform API for setting thread affinity, stack size and priority via FMOD_Thread_SetAttributes.
    • +
    • Core API - Win - FMOD_OUTPUT_DEVICELISTCHANGED_CALLBACK now responds to default device changes.
    • +
    +

    Fixes:

    +
      +
    • Studio API - Fixed issue where async instruments on a transition timeline with fade out curves would snap to full volume when exiting the transition timeline.
    • +
    • Studio API - The end of destination and magnet regions are included as part of the timeline length.
    • +
    • Studio API - Changed behaviour of stopped async multi-instrument entries with unlimited loop counts to not play.
    • +
    • Studio API - Loop regions of lower priority that coincide with transitions are now followed during the transition's source timeline.
    • +
    • Core API - Fixed potential crash when calling Sound::getSubSound on a playing stream, this is now prohibited and will instead return an error.
    • +
    • Unity - Fixed compatibility issues with C# wrapper. FMOD objects are now passed as IntPtr for callback arguments from native to C#. Use the constructor of the correct type to recreate the object from the IntPtr.
    • +
    +

    Notes:

    +
      +
    • Core API - Calling Sound::getSubSound from FMOD_CREATESOUNDEXINFO::nonblockcallback is no longer a synchronous operation meaning an additional callback will execute when fetching the subsound has completed.
    • +
    • Core API - Removed stackSizeStream, stackSizeNonBlocking and stackSizeMixer from FMOD_ADVANCEDSETTINGS:: These are now set via FMOD_Thread_SetAttributes .
    • +
    • Core API - Removed deprecated FMOD_ADVANCEDSETTINGS::commandQueueSize member.
    • +
    • Core API - Removed all platform specific thread affinity APIs, affinity is now controlled via FMOD_Thread_SetAttributes.
    • +
    • Core API - Renamed FMOD_OUTPUT_DESCRIPTION::polling to FMOD_OUTPUT_DESCRIPTION::method.
    • +
    • Core API - When calling FMOD_Memory_Initialize with valid 'useralloc' and 'userfree' callbacks, the requirement of 'userrealloc' is now optional.
    • +
    • Core API - DSP Echo delay effect minimum reduced to 1 millisecond.
    • +
    • FSBank - Minimum requirement for Mac version of the FSBank tool has been lifted to macOS 10.12 due to framework update.
    • +
    • Profiler - Minimum requirement for Mac version of the Profiler tool has been lifted to macOS 10.12 due to framework update.
    • +
    +

    02/03/20 2.00.08 - Studio API minor release (build 108014)

    +

    Features:

    + +

    Fixes:

    +
      +
    • Studio API - Fixed issue with determining the end of an event inside a multi instrument.
    • +
    • Studio API - Fixed issue with determining the end of an async instrument with pitch automation.
    • +
    • Studio API - Fixed potential crash when playing a command replay from a 64bit game on a 32bit host.
    • +
    • Studio API - Fixed issue where polyphony limits on an event and bus could both apply causing too many event instances to be stolen when starting a new event instance.
    • +
    • Studio API - Fixed issue where Studio update thread could get stuck in an infinite loop and eventually deadlock with the game thread when a sound object used for a programmer sound was used by more than one event instance.
    • +
    • Studio API - Fixed issue where transitioning from the start of a transition region to a destination marker using a relative transition with a tempo marker would result in the event stopping.
    • +
    • Studio API - HTML5 - Fixed missing plugin errors for banks using loudness meter, convolution reverb or pitch shifter. These effects can be CPU intensive so use them with caution.
    • +
    • Core API - Fixed seeking accuracy of mp3 files that use small mpeg frame sizes.
    • +
    • Core API - Fixed ChannelGroup::isPlaying from returning false on a parent ChannelGroup, when children groups in certain configurations had playing sounds.
    • +
    • Core API - iOS - Fixed issue causing MP3 netstreams to not work.
    • +
    • Core API - iOS - Fixed issue where FMOD_CREATECOMPRESSEDSAMPLE would not work as expected with MP3 files.
    • +
    • UE4 - Fixed crash in 4.24 caused by SetActive call in FMODAudioComponent.
    • +
    • UE4 - Fixed warning log message when using the IsBankLoaded blueprint function when the bank is not loaded.
    • +
    • Unity - TextAsset banks import directory now defaults to 'FMODBanks' instead of the root 'Assets' folder.
    • +
    • Unity - HTML5 - Fixed compilation issue preventing launch.
    • +
    +

    Notes:

    +
      +
    • XboxOne - Now built with July 2018 QFE12 XDK.
    • +
    • PS4 - Resonance Audio now built with SDK 7.008.
    • +
    • HTML5 - JavaScript bindings are now separate from the main bitcode binary to facilitate recompilation of ASM.JS / WASM or usage in strictly native projects.
    • +
    +

    17/01/20 2.00.07 - Studio API minor release (build 107206)

    +

    Features:

    +
      +
    • Unity - Changing bank import type now gives you the option of removing the previously imported banks.
    • +
    • UE4 - Added getParameter functions for getting user and final values.
    • +
    +

    Fixes:

    +
      +
    • Studio API - Fixed application of fade curves to instruments when transitioning immediately between transition timelines.
    • +
    • Studio API - Fixed Studio::EventDescription::is3D to return true for events with scatterer instruments, for 3D instruments inside multi instruments, and for spatializers on non-master tracks.
    • +
    • Studio API - Fixed relative transition calculation when performing a transition jump that would incorrectly end up at the beginning instead of the end of the destination or vice versa.
    • +
    • Studio API - Fixed issue when encountering a loop region in a destination timeline which would stop the event in specific circumstances.
    • +
    • Studio API - Fixed crash when profiling runtime with an older Studio tool version.
    • +
    • Core API - Fixed asserts from setting readonly DSP data parameters when the setter isn't implemented.
    • +
    • Core API - Fixed FSBankLib Vorbis encoder not supporting quality zero as default.
    • +
    • Core API - Fixed System::setDriver not always applying if called after System::setOutput when the device list has changed.
    • +
    • Core API - Fixed DSP_PARAMETER_DESC being populated with incorrect data in C#.
    • +
    • Core API - Fixed MP3 codec not respecting FMOD_ACCURATETIME flag when played as FMOD_CREATECOMPRESSEDSAMPLE.
    • +
    • UE4 - Fixed EncryptionKey not being saved to packaged game. Bank encryption keys in existing projects will need to be re-entered after upgrading.
    • +
    • UE4 - XBoxOne - Fixed third party plugin path.
    • +
    • UE4 - Fixed FMODEvent::GetParameterDescriptions not working in built game.
    • +
    • Unity - Fix lag in editor due to banks being reimported.
    • +
    • Unity - Fixed FMODStudioCache causing deserialization exceptions by moving the file to a separate cache folder.
    • +
    +

    Notes:

    +
      +
    • PS4 - Now built with SDK 7.008.031.
    • +
    • Stadia - Now built with SDK 1.38.
    • +
    • Switch - Now built with SDK 9.3.0.
    • +
    • HTML5 - Now built with sdk-1.38.19-64bit
    • +
    • UE4 - Added support for UE4.24.
    • +
    • UE4 - Added support for Stadia.
    • +
    • OSX - Updated Resonance Audio plugin with performance improvements.
    • +
    +

    20/11/19 2.00.06 - Studio API minor release (build 106220)

    +

    Fixes:

    +
      +
    • Studio API - Fixed issue where a loop on an instrument followed immediately by a transition timeline could result in a short pause in playback.
    • +
    • Core API - Mac - Fix crash calling recordStart at the same time as unplugging a USB microphone.
    • +
    • Core API - Android - minimum Android version for AAudio support changed to 8.1 (API 27) to circumvent AAudio RefBase crash issue.
    • +
    • Core API - XboxOne - Fixed background music port going silent if XAudio is initialized outside of FMOD.
    • +
    • Core API - Stadia - Fixed crash at static initialization time when using the logging build on system software v1.37 and newer.
    • +
    • FSBank API - Win - Fixed bug introduced in 2.00.05 which prevented banks being built when passing a non-empty encryption key to FSBank_Build.
    • +
    • UE4 - Fixed asset loading errors on dedicated server.
    • +
    • Unity - Fixed integration deleting non FMOD bank/bytes files when refreshing.
    • +
    • Unity - Fixed handling of iOS AudioSession interruption notifications.
    • +
    +

    Notes:

    +
      +
    • iOS - Now built with iOS SDK 13.1 and tvOS SDK 13.0 (Xcode 11.1).
    • +
    • Mac - Now built with macOS SDK 10.15 (Xcode 11.1).
    • +
    +

    09/10/19 2.00.05 - Studio API minor release (build 105402)

    +

    Features:

    +
      +
    • Studio API - Add event and bus instance CPU profiling to the FMOD Studio API.
    • +
    • Core API - Stadia - Added voice output port FMOD_STADIA_PORT_TYPE_VOICE.
    • +
    +

    Fixes:

    +
      +
    • Studio API - Fixed crash caused by creating an instance of an event containing a nested event which has not been loaded.
    • +
    • Studio API - Fixed pitch changes on a bus propagating across sidechain connections.
    • +
    • Studio API - Fixed application of transition fade curves to parameter triggered instruments on multi track events.
    • +
    • Core API - Fixed mixer falling silent due to very small but not denormal positions being passed into the API.
    • +
    • Core API - Fixed crash when processing loops of FMOD_DSPCONNECTION_TYPE_SEND or FMOD_DSPCONNECTION_TYPE_SEND_SIDECHAIN.
    • +
    • Unity - Removed high frequency of UnityEditor.SetDirty calls.
    • +
    • Unity - Fixed issues with using relative paths in linked project/bank directory.
    • +
    +

    Notes:

    +
      +
    • Switch - Now built with SDK 8.3.0.
    • +
    • XboxOne - Now built with July 2018 QFE9 XDK.
    • +
    +

    06/09/19 2.00.04 - Studio API minor release (build 104705)

    +

    Features:

    +
      +
    • Official support for Stadia as a separate platform is now complete, anyone using the Linux version should migrate across.
    • +
    +

    Fixes:

    +
      +
    • Studio API - Fixed issue where programmer sound without an associated sound would have unexpected behavior when modulated.
    • +
    • Studio API - Fixed issue where instruments with low polyphony would incorrectly fail to play.
    • +
    • Studio API - Fixed looping multi-instrument with streaming instruments cutting off near the end of the loop when the length of the multi-instrument is slightly longer than a multiple of the instrument length.
    • +
    • Studio API - Fixed issue where automation points are reused in transition timelines when both the timelines and the transition have no automation points.
    • +
    • Core API - Fixed crash caused by unlinking a convolution reverb dsp during a mix.
    • +
    • Core API - Fixed potential alignment crash on ARM devices if using FMOD_DSP_PAN.
    • +
    • Core API - Fixed leak of socket handles when binding to a listening port fails.
    • +
    • Core API - Win / UWP / XboxOne - Fixed incorrect DSP CPU reporting when using FMOD_OUTPUTTYPE_WINSONIC.
    • +
    • UE4 - Fixed crash in PlayEventAtLocation when world context is invalid.
    • +
    • UE4 - Fixed failed to load errors when playing in Standalone.
    • +
    • UE4 - Switch to using "Additional non-asset directories to copy" packaging setting for FMOD banks to avoid possible deadlocks at runtime.
    • +
    • Unity - Fixed banks being copied to project repeatedly when using AssetBundles.
    • +
    • Unity - Fixed Events not auditioning from split banks.
    • +
    • Unity - Fixed RuntimeManager being able to update the 3DAttributes for an Event Instance multiple times using different values.
    • +
    +

    02/08/19 2.00.03 - Studio API minor release (build 103912)

    +

    Features:

    +
      +
    • Core API - Improved ASIO channel mapping via FMOD_ADVANCEDSETTINGS::ASIOSpeakerList. Skips irrelevant speakers with FMOD_SPEAKER_NONE and supports devices up to 32 channels without using FMOD_SPEAKERMODE_RAW.
    • +
    • Core API - Android - Added support for AAudio via FMOD_OUTPUTTYPE_AAUDIO.
    • +
    • Core API - PS4 - Added ResonanceAudio plugin for PS4.
    • +
    • Core API - Android - Added support for setting thread affinity via FMOD_Android_SetThreadAffinity.
    • +
    • UE4 - Added blueprint node for Studio::EventInstance::release.
    • +
    • Unity - Added setParameter by name wrapper function to StudioEventEmitter.Features:
    • +
    • Unity - Fixed crash when setting logging level to LOG and entering playback.
    • +
    +

    Fixes:

    +
      +
    • Core API - Fixed rare crash on Studio::System::release.
    • +
    • UE4 - Fixed FMODAudioComponent not being occluded are being stopped and restarted.
    • +
    • Unity - Fixed project determinism issue causing paths to update when opening the project on Windows and Mac.
    • +
    • HTML5 - FMOD Studio examples updated with 2.0 API changes.
    • +
    +

    Notes:

    +
      +
    • Switch - Now built with SDK 8.2.0.
    • +
    • XboxOne - Now built with July 2018 QFE7 XDK.
    • +
    +

    18/06/19 2.00.02 - Studio API minor release (build 102879)

    +

    Features:

    + +

    Fixes:

    +
      +
    • Core API - Win 64bit - Skip JACK ASIO driver when enumerating ASIO devices. An unrecoverable crash occurs in the driver when attempting to query its capabilities.
    • +
    • UE4 - Fixed "Accessed too early?" crash by changing the plugin loading phase.
    • +
    • UE4 - Fixed OnEventStopped not being broadcast when the FMODAudioComponent is destroyed.
    • +
    • Unity - Fixed third party plugin paths for Win32 and Mac.
    • +
    • Unity - Changed the Debug Overlay Window ID to avoid conflicts.
    • +
    • +

      Unity - iOS - Fixed sound stopping in editor when focus is lost.

      +
    • +
    • +

      PS4 - Now built with SDK 6.508.021.

      +
    • +
    +

    09/05/19 2.00.01 - Studio API minor release (build 102182)

    +

    Features:

    +
      +
    • Core API - ChannelMix DSP now supports re-routing input channels.
    • +
    • UE4 - Added support for UE4.22.
    • +
    • UE4 - Added Encryption Key to the settings for loading sounds from encrypted banks.
    • +
    • UE4 - Added Play-In-Editor logging options to Plugin Settings.
    • +
    • UE4 - Android - Added support for x86_64.
    • +
    • Unity - Added SetParameter by ID to StudioEventEmitter.
    • +
    • Unity - Added Encryption Key to the settings for loading sounds from encrypted banks.
    • +
    • Unity - Added mouse events to StudioEventEmitter trigger options.
    • +
    +

    Fixes:

    +
      +
    • Studio API - Fixed assert caused by a backwards transition with a lead out on a transition timeline with callbacks for timeline markers.
    • +
    • Studio API - Fixed bug in cone angle built-in parameter calculation when using FMOD_INIT_3D_RIGHTHANDED.
    • +
    • Core API - Fixed virtualized objects from object spatializer being silenced (introduced in 2.00.00).
    • +
    • Core API - Fix crash when using convolution reverb with a DSP buffer size of 4096 or above.
    • +
    • Core API - Fix crash trying to load corrupt WAV files with 0 length chunk size.
    • +
    • Core API - Fix crash trying to load corrupt MP3 files.
    • +
    • Core API - Fixed send dsp data being retained after being bypassed.
    • +
    • Core API - iOS - Fixed crash when suspending or resuming the mixer while audio is loading.
    • +
    • UE4 - Fixed Ambient LPF values not being set properly.
    • +
    • UE4 - Fixed builds failing due to the integration being loaded after blueprints.
    • +
    • UE4 - Fixed listener using the correct nested AudioVolume.
    • +
    • Unity - Fixed handling banks in sub-directories.
    • +
    • Unity - Fixed IOException when trying to copy banks into StreamingAssets.
    • +
    • Unity - Fixed Events previewed in Timeline not stopping.
    • +
    • Unity - Fixed StudioListeners with an index larger than zero causing errors.
    • +
    • Unity - Fixed FMODStudioSettings.asset modifying bank list order when using different scripting backends.
    • +
    • Unity - Remove garbage collection overhead in DebugOverlay.
    • +
    • Unity - Fixed creating duplicate objects when loading banks for the Editor.
    • +
    • Unity - Fixed Emitters cleaning up properly when using one shot Events.
    • +
    • Unity - Fixed paths for plugins in editor.
    • +
    • Unity - Fixed build errors on iOS / tvOS due to "lowLevelSystem" references.
    • +
    • Unity - Removed excessive error logging when no project or folder linked to the integration.
    • +
    • Unity - Fixed occasional issues with copying banks into StreamingAssets.
    • +
    • Unity - Fixed Master Bank not being found if in a sub directory.
    • +
    • Unity - Fixed StudioParameterTrigger IndexOutOfRange exception.
    • +
    +

    Notes:

    +
      +
    • XboxOne - Now built with July 2018 QFE4 XDK.
    • +
    +

    14/03/19 2.00.00 - Studio API major release (build 101145)

    +

    Features:

    +
      +
    • Studio API - Bank sample data encryption is now supported via the Studio API. Use FMOD_STUDIO_ADVANCEDSETTINGS.encryptionkey to specify the encryption key to use when opening banks and use the FMOD_STUDIO_LOAD_BANK_UNENCRYPTED flag to load unencrypted banks if an encryption key has been set.
    • +
    • Studio API - Added built-in parameter for speed.
    • +
    • Studio API - Added support for global parameters.
    • +
    • Studio API - Added support for global mixer automation.
    • +
    • Studio API - Added the ability to set a custom final value on an AHDSR modulator.
    • +
    • Studio API - Added ignoreseekspeed argument to public api setParameter functions.
    • +
    • Studio API - Added the ability to automate time based ahdsr properties.
    • +
    • Studio API - Added a command instrument with the ability to stop all non-nested instances of an event description.
    • +
    • Core API - Added output device enumeration to Windows Sonic output plugin.
    • +
    • Unity - Switch platform settings have been moved into a separate dropdown.
    • +
    +

    Fixes:

    +
      +
    • Studio API - Event parameters with "Hold value during playback" enabled now snap to their target values when their event is started.
    • +
    • Studio API - Changed quantization calculation to use future tempo markers if no past tempo markers are present, and default to 4/4 timing at 120 bmp if no tempo markers are present.
    • +
    • Studio API - Transition regions not using quantization perform any probability determinations each time all other required conditions are newly met.
    • +
    • Studio API - Sidechain modulators now correctly handle multiple sidechain inputs.
    • +
    • Core API - Fixed volume spike due to tremolo DSP with high duty setting.
    • +
    • Core API - Fixed excessive instances of clipping that occur when adjusting the FMOD_DSP_THREE_EQ_LOWCROSSOVER value of a DSPThreeEQ DSP in the low frequency range.
    • +
    +

    Notes:

    +
      +
    • Updated Resonance Audio plugin removing additional transformation of occlusion values. If previous occlusion calculation is required, replace the resonance audio libraries with their 1.10 versions.
    • +
    • The GoogleVR plugin deprecated in 1.10 has now been removed, Resonance Audio is available as a functional drop in replacement.
    • +
    • Studio API - The parameter API has been updated. See the "What's New in 2.00" section in the API documentation for details.
    • +
    • Studio API - The deprecated ParameterInstance class has been removed.
    • +
    • Studio API - Seek speed is now applied when parameter values are modified by AHDSR or sidechain modulation.
    • +
    • Studio API - Parameters with seek speed now snap to their target value when the event stops.
    • +
    • Studio API - Automatic parameters no longer update their user value. The automatically calculated value can be retrieved using the finalvalue parameter of Studio::EventInstance::getParameter.
    • +
    • Studio API - Studio::System::getBank no longer supports getting a loaded bank from the system by filename.
    • +
    • Core API - System::getFileUsage will no longer count bytes read from user callbacks.
    • +
    • Core API - Automatic SRS downmix from 5.1 to 2.0 has been removed.
    • +
    • Core API - System::getSoundRAM API has been removed.
    • +
    • Core API - FMOD_ADVANCEDSETTINGS::HRTFMinAngle, HRTFMaxAngle, HRTFFreq removed
    • +
    • Core API - FMOD_CREATESOUNDEXINFO::channelmask removed
    • +
    • Core API - Win - Support for paths using Windows ANSI Code Page (ACP) encoding has been removed. Paths must be UTF-8 encoded.
    • +
    • Core API - Win - The minimum supported version of Windows has been lifted from Windows XP to Windows 7. Coupled with this change we have removed the legacy DirectSound and WinMM output modes.
    • +
    • Win / UWP - All binaries no longer have a suffix indicating the target architecture, instead the files are separated by directories in the installer.
    • +
    +

    14/03/19 1.10.12 - Studio API minor release (build 101101)

    +

    Features:

    +
      +
    • Unity - Added option to specify Live Update port number in editor settings.
    • +
    • Unity - Changed StudioEventEmitter private members to protected.
    • +
    +

    Fixes:

    +
      +
    • Studio API - Avoid stalling when unloading a bank which is waiting to load sample data behind other banks.
    • +
    • Core API - FMOD_OUTPUTTYPE_ASIO is now compatible with more devices without requiring calls to System::setDSPBufferSize.
    • +
    • Core API - Android - Fixed instances of audio stuttering that occurred on some devices by dynamically adding latency to compensate.
    • +
    • Core API - Fixed MP3 files with MPEG 2.5 encoding having distortion on some files.
    • +
    • Unity - Fixed plugins not being found on Android.
    • +
    • Unity - Fix for banks being read only when trying to copy new banks to StreamingAssets.
    • +
    • Unity - Fixed BatchMode builds not being able to find the MasterBank.
    • +
    • Unity - Fixed BatchMode builds not building with banks.
    • +
    • Unity - Changed console default thread affinity to not use the game thread.
    • +
    • Unity - Fixed Strings bank not being found or copied (introduced in 1.10.10).
    • +
    +

    01/02/19 1.10.11 - Studio API minor release (build 99976)

    +

    Features:

    +
      +
    • Studio API - Add streamingscheduledelay member to FMOD_STUDIO_ADVANCEDSETTINGS. May be used to reduce latency when scheduling events containing streaming sounds.
    • +
    • UE4 - Expose the FMODAudioComponent::bAutoDestroy property to the PlayEventAttached Blueprint function.
    • +
    +

    Fixes:

    +
      +
    • Studio API - Fixed fire and forget event instances not releasing when another instance of the same event is active.
    • +
    • Studio API - Fixed a bug with multi-instruments when using looping and initial seek which caused a gap of silence the same length as the initial seek when scheduling the second instrument.
    • +
    • Core API - Fixed MP3 files using Xing headers from having incorrect seek positions when using Channel::setPosition.
    • +
    • Core API - Fixed potential crash caused by third party applications sending data to the FMOD profiler port.
    • +
    • Core API - Fixed issue where bypassed faders and convolution reverb dsps could silence their output.
    • +
    • UE4 - Fixed 'An invalid object handle' errors from FMODAudioComponent in sequencer after reloading banks.
    • +
    • UE4 - Fixed playback not working correctly in Sequencer.
    • +
    • UE4 - Fixed error from FindEventInstances if zero events found.
    • +
    • UE4 - Fixed Programmer Sounds not auditioning in Editor.
    • +
    • UE4 - Fixed events not playing in Sequencer.
    • +
    • Unity - Fixed RuntimeManager being saved to scene after auditioning timeline.
    • +
    • Unity - Fix AttachInstanceToGameObject positioning not being applied correctly.
    • +
    +

    Notes:

    +
      +
    • PS4 - Now built with SDK 6.008.051.
    • +
    • iOS - Now built with iOS SDK 12.1 and tvOS SDK 12.1 (Xcode 10.1) which necessitates lifting the min spec to 8.0 for iOS, no change for tvOS.
    • +
    • Mac - Now built with macOS SDK 10.14 (Xcode 10.1) which necessitates lifting the min spec to 10.7 and the removal of x86 support.
    • +
    • Android - Added support for x86_64.
    • +
    +

    03/12/18 1.10.10 - Studio API minor release (build 98815)

    +

    Features:

    +
      +
    • Studio API - Added FMOD_STUDIO_EVENT_CALLBACK_REAL_TO_VIRTUAL and FMOD_STUDIO_EVENT_CALLBACK_VIRTUAL_TO_REAL.
    • +
    • Core API - Added DSP::GetCPUUsage to public API.
    • +
    • Core API - Linux - Added support for FMOD_ALSA_DEVICE environment variable to allow a user to specify an ALSA device.
    • +
    • HTML5 - Add Web Assembly support (WASM) to HTML5 version of FMOD Core API and Studio API. Memory usage halved, CPU speed improvements of about 30%
    • +
    • Unity - Android - Added ARM64 support.
    • +
    • Unity - Add support for working with multiple master banks and strings banks.
    • +
    +

    Fixes:

    +
      +
    • Studio API - Fixed multi-instrument playlist entries set to loop infinitely not looping correctly.
    • +
    • Studio API - Fixed pop that occurs at the start of a transition destination section with a fade curves.
    • +
    • Studio API - Fixed nested event instances stopping when their parent is paused.
    • +
    • Studio API - HTML5 - Fix Studio::System::getSoundInfo not working
    • +
    • Core API - System::setDSPBufferSize validates arguments for integer overflow.
    • +
    • Core API - Fixed potential CPU usage spike due to dsp flush on releasing a programmer sound during the destroy callback.
    • +
    • Core API - Opening a playlist from a URL now validates that the playlist file is a text file and falls back to codec probing if binary data is found.
    • +
    • Core API - Linux - Fixed occasional distortion that can occur when using PulseAudio.
    • +
    • FSBank API - Fixed issue where a file change would not be detected when it has the same modified time.
    • +
    • UE4 - Fixed occlusion using the trace channel selected in editor.
    • +
    • UE4 - Fixed plugin include directory paths.
    • +
    • UE4 - Fixed crash caused by trying to access objects pending kill.
    • +
    • UE4 - Fixed occlusion not working.
    • +
    • UE4 - Fixed programmer sounds trying to access the FMODStudioModule outside of the main thread, while also improving the performance of the FMODAudioComponent.
    • +
    • Unity - Fixed Asset Folder name updating after each keystroke.
    • +
    • Unity - Fixed Timeline playables playing the previously selected event.
    • +
    • Unity - Fixed "Bus not found" error caused when no banks loaded in editor.
    • +
    • Unity - iOS - Fixed Events not resuming after returning focus.
    • +
    • Unity - PS4 - Fixed logging libs being used for development builds.
    • +
    +

    Notes:

    +
      +
    • Studio API - Reduced the maximum number of parameter values which can be set in a batch using Studio::EventInstance::setParameterValuesByIndices to 64.
    • +
    • HTML5 - Now built with Emscripten v1.38.15
    • +
    • Switch - Now built with SDK 6.4.0.
    • +
    +

    11/10/18 1.10.09 - Studio API minor release (build 97915)

    +

    Features:

    +
      +
    • Studio API - Added globally sequential play mode to multi and scatterer instruments.
    • +
    • Unity - All logging will now be displayed in the editor console. The logging level can be changed using the dropdown in settings.
    • +
    +

    Fixes:

    +
      +
    • Studio API - Fixed missing bank warnings when playing a CommandReplay using FMOD_STUDIO_COMMANDREPLAY_SKIP_BANK_LOAD mode.
    • +
    • Studio API - UWP - Fixed Studio thread affinity not applying correctly.
    • +
    • Studio API - Android / UWP - Fixed CommandReplay not working with AppX and APK based paths.
    • +
    • Core API - Fixed loading of encrypted FSBs.
    • +
    • Core API - Fixed several panning issues when using FMOD_SPEAKERMODE_QUAD or FMOD_SPEAKERMODE_SURROUND, does not affect Studio API usage.
    • +
    • Core API - Fixed potential hang from internal fade point usage.
    • +
    • Core API - Fixed ChannelControl::setMixLevelsInput not remembering the set values when FMOD_3D is applied.
    • +
    • Core API - Fixed potential cpu usage spike due to thread lock on releasing a non-gpu convolution reverb dsp.
    • +
    • Core API - Fixed support of FMOD_3D_INVERSETAPEREDROLLOFF.
    • +
    • Core API - Fixed potential cpu usage spike due to thread lock on releasing a transciever dsp.
    • +
    • Core API - Win / UWP - Fixed Windows Sonic initialization failure when audio device is configured for a sample rate other than 48KHz.
    • +
    • Core API - Linux - Fixed ALSA default audio device selection.
    • +
    • Core API - Android - Fixed crash if System::mixerSuspend is called before System::init.
    • +
    • Unity - iOS - Fixed playback not resuming after alarm / call interruptions.
    • +
    +

    Notes:

    +
      +
    • Updated Resonance Audio plugin to add support for near field effects, and added FMOD_DSP_PARAMETER_OVERALLGAIN parameter to support virtualization.
    • +
    • PS4 - Now built with SDK 6.008.001.
    • +
    • XboxOne - Now built with July 2018 QFE2 XDK.
    • +
    +

    10/08/18 1.10.08 - Studio API minor release (build 96768)

    +

    Features:

    +
      +
    • UE4 - FMODAudioComponent is now blueprintable.
    • +
    +

    Fixes:

    +
      +
    • Studio API - Fixed potential crash when calling Studio::EventInstance::release from the FMOD_STUDIO_EVENT_CALLBACK_STOPPED triggered by Bus::stopAllEvents.
    • +
    • Studio API - Fixed a bug where changes to a parameter value made while an event was in the FMOD_STUDIO_PLAYBACK_STARTING state would not update automation controllers (introduced in 1.10.02).
    • +
    • Studio API - Fixed Studio::CommandReplay::release not cleaning up resources unless Studio::CommandReplay::stop was called earlier.
    • +
    • Studio API - HTML5/WebGL - Fixed the following functions that didn't work. - Studio::Bank::getID - Studio::EventDescription::getID - Studio::Bus::Bank::getID - Studio::VCA::Bank::getID - Studio::System::lookupID - Studio::Bank::getStringInfo - Studio::System::getBankList - Studio::EventDescription::getInstanceList - Studio::Bank::getEventList - Studio::Bank::getBusList - Studio::Bank::getVCAList
    • +
    • Core API - Fixed audible artifacts when adjusting pitch near 1.0. Issue can be seen from doppler calculations with small velocities.
    • +
    • Core API - Improved stuttering issue when using Windows Sonic with high DSP CPU usage.
    • +
    • Core API - Fixed init errors on output devices that operate at 384KHz such as the Aune X1s.
    • +
    • Core API - Windows - Improved compatibility with some audio drivers by falling back to stereo.
    • +
    • Core API - HTML5/WebGL - Added support for unimplemented System::createDSP with FMOD_DSP_DESCRIPTION. DSP callbacks are provided to allow custom DSP support in Javascript. Added dsp_custom example to example folder.
    • +
    • Core API - HTML5/WebGL - Added support for unimplemented ChannelControl::setCallback.
    • +
    • Core API - HTML5/WebGL - Enabled support for 5.1 / Surround sound in a browser. Only Firefox supports 5.1 so far, out of all browsers tested.
    • +
    • UE4 - Fixed Activate and SetActive not working for FMODAudioComponents.
    • +
    • UE4 - Fixed Simulating in editor producing no sound.
    • +
    • UE4 - Fixed BlueprintStatics::LoadBank not working for banks containing spaces.
    • +
    • UE4 - Fixed asset banks not displaying in editor or being loaded.
    • +
    • Unity - Fixed warnings due to loading sample data on a metadata-only bank before its asset bank is loaded.
    • +
    • Unity - Fixed source project not updating if the old path is still valid.
    • +
    +

    Notes:

    +
      +
    • XboxOne - Now built with April 2018 QFE1 XDK.
    • +
    +

    03/07/18 1.10.07 - Studio API minor release (build 95892)

    +

    Features:

    +
      +
    • Unity - Added support for Timeline (from Unity 2017.1 onwards).
    • +
    +

    Fixes:

    +
      +
    • Studio API - The FMOD Gain effect is now taken into account when applying event stealing behavior and virtualizing FMOD::Channels.
    • +
    • Core API - Win/XboxOne - Fixed crash during System::recordStart if the device was unplugged.
    • +
    • Core API - Win - System::loadPlugin now correctly handles UTF-8 encoded paths. Support for paths using ACP is deprecated and will be removed in FMOD 1.11.
    • +
    • UE4 - Fixed auditioning events not taking parameter values into account.
    • +
    • UE4 - Fixed game crash when built using Event-Driven-Loader.
    • +
    +

    06/06/18 1.10.06 - Studio API minor release (build 95384)

    +

    Features:

    +
      +
    • Unity - Added SampleRate for Play-In-Editor settings.
    • +
    • Unity - Added scripts for setting thread affinity on specific consoles.
    • +
    • HTML5 - Updated core API and studio API examples to handle chrome mute until mouse click or touch event happens, via System::mixerSuspend / System::mixerResume.
    • +
    +

    Fixes:

    +
      +
    • Core API - Fixed potential crash if a stream naturally ends at the same time as being released.
    • +
    • Core API - Fixed incorrect parsing of large ID3 tags.
    • +
    • Core API - Fixed FMOD_ERR_FILE_BAD error when trying to call setPosition to a point past 2GB bytes in a file.
    • +
    • Core API - Fixed crash if Windows Sonic output mode is used with the object spatializer and the device is unplugged.
    • +
    • Core API - Fixed stall in Sound::release for FSB files if another thread is performing a createSound operation.
    • +
    • Core API - Fixed potential crash when playing a netstream with tags.
    • +
    • Core API - Fixed OGG netstreams not automatically stopping if the stream goes offline.
    • +
    • Core API - Fixed potential invalid memory access when a channel group is released (introduced in 1.10.02).
    • +
    • Core API - Channel group audibility now factors in attenuation due to 3D effects when using ChannelControl::setMode (FMOD_3D).
    • +
    • Core API - HTML5/WebGL - Fix System::setDriver (0) causing garbled audio when trying to respond to a touch event and the audio is already active.
    • +
    • Core API - HTML5/WebGL - Fix floating point accuracy issues making MIDI file sound out of tune.
    • +
    • Core API - UWP - Fixed default affinity mask incorrectly putting all threads on core 0, now threads default to distributing among all cores.
    • +
    • UE4 - Removed FMODAudioComponent ticking when deactivated.
    • +
    +

    Notes:

    +
      +
    • Core API - Windows Sonic output mode no longer requires a block size of 480.
    • +
    • XboxOne - Now built with February 2018 XDK.
    • +
    • Switch - Now built with SDK 5.3.0.
    • +
    +

    26/04/18 1.10.05 - Studio API minor release (build 94661)

    +

    Features:

    + +

    Fixes:

    +
      +
    • Studio API - Fixed a rare bug where Studio::System::Update could hang if a streaming sound encountered an error.
    • +
    • Studio API - Fixed events getting stuck in a paused state if they were restarted while waiting for sample data to load (introduced in 1.10.02).
    • +
    • Studio API - Fixed an issue preventing network streams being used as programmer sounds.
    • +
    • Core API - Fixed rare hang during Sound::release when releasing a streaming sound in the FMOD_OPENSTATE_ERROR state.
    • +
    • Core API - Switch - Fixed Vorbis encoded banks producing silence when using multimedia.nso (UE4 uses this).
    • +
    • UE4 - Fixed FMODAudioComponent programmer sound creation flags.
    • +
    • UE4 - Switch - Fixed performance by changing default thread affinity.
    • +
    • Unity - Fixed FMODStudioSettings asset dirty flag being set unnecessarily.
    • +
    • Unity - Fixed callbacks crashing when using IL2CPP or Mono on some platforms.
    • +
    • Unity - Fixed editor system not being cleaned up on Play-In-Editor start.
    • +
    • Unity - Android - Fixed load bank returning ERR_INVALID_HANDLE.
    • +
    +

    Notes:

    +
      +
    • Core API - It is now possible to initialize WinSonic output even if the user has not enabled spatial audio on their default device. The platform will provide a non-binaural downmix to the user desired speaker mode.
    • +
    • PS4 - Now built with SDK 5.508.021.
    • +
    +

    05/03/18 1.10.04 - Studio API minor release (build 93853)

    +

    Features:

    +
      +
    • Studio API - Improved bank loading performance when there are already a large number of loaded events.
    • +
    • UE4 - Added the ability to enable Live Update while in editor for auditioning. The Editor will need to be restarted for this setting to take effect.
    • +
    +

    Fixes:

    +
      +
    • Studio API - Fixed a bug where Studio::System::Update could fail with FMOD_ERR_INVALID_HANDLE or FMOD_ERR_CHANNEL_STOLEN, which could lead to memory or performance problems. Introduced in 1.10.03.
    • +
    • Core API - XboxOne - Fixed XMA hang that can occur after actively using many XMA voices for several days.
    • +
    • Unity - Fixed MobileHigh/Low classifications for Apple Devices. Pre iPhone 5 is classed as MobileLow.
    • +
    +

    01/02/18 1.10.03 - Studio API minor release (build 93157)

    +

    Features:

    +
      +
    • Core API - Added ASIO support for drivers that use PCM32 as a container for smaller sized data.
    • +
    • Profiler - Draw different DSP connection types with different line styles.
    • +
    • UE4 - Added option to specify memory pool size, per platform, in the project FMOD Studio settings.
    • +
    • UE4 - Now complying with IWYU mode, this should increase compilation speed.
    • +
    +

    Fixes:

    +
      +
    • Studio API - Fixed the DSP network sometimes getting into a bad state when a sidechain is connected to the next effect in the chain.
    • +
    • Studio API - Fixed event playback sometimes using stale parameter values.
    • +
    • Studio API - Fixed events failing to stop if they contain empty Single Instruments.
    • +
    • Core API - Fixed potential crash in device list changed callback when there are no available devices remaining.
    • +
    • Core API - Fix 3D 5.1 sound not panning correctly if ChannelControl::set3DLevel (0) is used.
    • +
    • Core API - Fixed ID3v2.4 compatibility issue causing missing or corrupted tags.
    • +
    • Core API - Android - Fixed incorrect floating point check on ARM64 devices causing FMOD_ERR_NEEDSHARDWARE with some devices.
    • +
    • Core API - XboxOne - Fixed race condition causing internal errors with XMA sounds loaded as FMOD_CREATECOMPRESSEDSAMPLE.
    • +
    • Core API - PS4 - Fixed internal assertion caused by setPosition on an AT9 sound loaded as FMOD_CREATECOMPRESSEDSAMPLE.
    • +
    • FSBank API - Fixed creation of C header so it goes next to the FSB instead of the working directory of the application.
    • +
    • Unity - Fixed pause working properly in Play In Editor mode.
    • +
    • Unity - Removed excess memory allocation from APIs that return strings in C#.
    • +
    • UE4 - Fixed velocity of FMODAudioComponents.
    • +
    +

    Notes:

    +
      +
    • Unity - Added support for Unity 2017.3.
    • +
    • Android - Now built with NDK r16b.
    • +
    • Android - Minimum Android version is now API level 14 due to NDK r16b deprecating older versions.
    • +
    • Switch - Now built with SDK 3.5.1.
    • +
    +

    07/12/17 1.10.02 - Studio API minor release (build 92217)

    +

    Features:

    +
      +
    • Core API - UWP - Added Windows Sonic support.
    • +
    • Core API - UWP - Added support for setting thread affinity via FMOD_UWP_SetThreadAffinity.
    • +
    +

    Fixes:

    +
      +
    • Studio API - Fixed Quietest stealing behavior so new events don't start if they are quieter than all currently playing events.
    • +
    • Studio API - Fixed buses that have reached their Max Instances limit incorrectly preventing their input buses from applying their stealing behavior.
    • +
    • Studio API - Fixed a crash caused by wav files with invalid loop points.
    • +
    • Core API - Fixed recording devices still being marked as connected when switching to FMOD_OUTPUTTYPE_NOSOUND.
    • +
    • Core API - UWP - Made device reset / unplug behavior more robust against failure.
    • +
    • Core API - XboxOne - Fixed WASAPI init error if WinSonic was attempted first.
    • +
    • FSBank API - Fixed crash in 64bit version when encoding low sample rate mono sounds as Vorbis with low quality.
    • +
    • Unity - PlayOneshot and PlayOneshotAttached now log a warning when the event is not found, rather than throwing an exception.
    • +
    +

    Notes:

    +
      +
    • Added Resonance Audio plugin version 1.0, this plugin represents the continuation of the Google VR plugin under new branding. The Google VR plugin is now considered deprecated in favour of Resonance Audio, consider migrating to the new plugin as the GVR plugin will be removed in FMOD 1.11.
    • +
    • XboxOne - Now built with June 2017 QFE 8 XDK.
    • +
    +

    01/11/17 1.10.01 - Studio API minor release (build 91339)

    +

    Features:

    +
      +
    • UE4 - Expose Studio::Bus::stopAllEvents to be useable through blueprints.
    • +
    • Unity - Event length displayed in event browser for one shot events.
    • +
    +

    Fixes:

    +
      +
    • Studio API - Fixed modulation on plugin instruments using the parent event's lifetime rather than the instrument's lifetime.
    • +
    • Studio API - Fixed a live update issue where asset files would not reload after being moved on disk.
    • +
    • Studio API - Fixed a bug which caused sounds to pan incorrectly when using FMOD_INIT_3D_RIGHTHANDED.
    • +
    • Studio API - PS4 - Fixed excessive binary size caused by inclusion of debug symbols.
    • +
    • Core API - Fixed potential crash when re-initializing System after failure.
    • +
    • Core API - Fixed compatibility issues with Windows XP.
    • +
    • Core API - Android - Fixed exported symbols to avoid issues with unwinder.
    • +
    • Core API - Android - Automatic output mode selection will now choose AudioTrack rather than OpenSL if Bluetooth is enabled to avoid stuttering.
    • +
    • Core API - XboxOne - Ensure WinSonic internal threads are assigned to the same core as the FMOD mixer.
    • +
    • FSBank API - Fixed crash when encoding very long audio files.
    • +
    • UE4 - Integration now handles application interruption by pausing and resuming the mixer.
    • +
    • UE4 - Fixed SetEvent not setting or using new event.
    • +
    • UE4 - Fixed XboxOne thread affinity struct setup.
    • +
    • UE4 - Removed engine version ifdef's.
    • +
    • UE4 - Fixed integration attempting to set the initial value of built-in parameters.
    • +
    • Unity - Fixed compatibility for Unity 5.0 & 5.1.
    • +
    • Unity - Added check to see if any banks have been loaded before trying to pause.
    • +
    • Unity - Allow StringHelper to fast return if string is null.
    • +
    +

    Notes:

    +
      +
    • Updated Google VR plugin to version 0.6.1.
    • +
    • Studio API - Studio::EventInstance::set3DAttributes and Studio::System::setListenerAttributes will now return FMOD_ERR_INVALID_PARAM if the forward or up vectors are zero. In logging builds warnings will be logged if the forward and up vectors are not orthonormal.
    • +
    • Core API - The convolution reverb effect will not accept impulse response data if the system is not using a power-of-two DSP buffer size. Windows Sonic currently requires a DSP buffer size of 480 making it incompatible with convolution reverb until this requirement is lifted.
    • +
    • PS4 - Now built with SDK 5.008.001.
    • +
    • Unity - Exposed editor script classes for in-game FMOD objects as public.
    • +
    • Unity - Exposed StudioEventEmitter's EventInstance as public to allow easier integration with custom plugins.
    • +
    +

    19/09/17 1.10.00 - Studio API major release (build 90329)

    +

    Features:

    +
      +
    • Core API - Added FMOD_MAX_SYSTEMS constant, currently 8.
    • +
    • Core API - Exposed FMOD_DSP_FADER_GAIN on FMOD_DSP_TYPE_FADER.
    • +
    • Core API - Added FMOD_SPEAKERMODE_7POINT1POINT4 speaker mode which includes four height speakers to be used with Windows Sonic output.
    • +
    • Core API - Added FMOD_DSP_PAN_2D_HEIGHT_BLEND parameter to FMOD_DSP_TYPE_PAN that allows mixing ground speaker signal into the height speakers and vice versa.
    • +
    • Core API - Windows & XboxOne - Added Windows Sonic output plugin to support rendering multichannel (with height) speaker mode 7.1.4 as well as dynamic objects via FMOD_DSP_TYPE_OBJECTPAN.
    • +
    • Core API - PS Vita - Switched FMOD_PSVita_SetThreadAffinity to accept a mask instead of a core number to allow floating threads.
    • +
    • Core API - Added FMOD_OUTPUT_REQUESTRESET to FMOD_OUTPUT_STATE to allow output plugins to request they be reset by the System.
    • +
    +

    Fixes:

    +
      +
    • Studio API - Sequential multi and scatterer instruments now track their current playlist entry on a per-event-instance basis, rather than globally.
    • +
    • UE4 - Removed all reference to Oculus, now that Oculus functions as all other FMOD Studio plugins.
    • +
    • UE4 - Removed all legacy UE4 version code, if you are not using UE4.16 the plugin will not work without making changes to source code.
    • +
    • UE4 - Overhauled details interaction in editor and improved usability. Grouped all FMOD functionality together, added Parameters, and removed unnecessary information from attenuation/occlusion.
    • +
    • Unity - Removed garbage allocations from C# wrapper.
    • +
    +

    Notes:

    +
      +
    • Updated Google VR plugin to version 0.6.0.
    • +
    • Studio API - Changed the behaviour of nested events to stop when idle even when there are instruments on parameters. This makes nested events match the behaviour of top level events. Events which depend on the old behaviour need to be manually fixed up by (for example) adding a sustain point to the nested events timeline.
    • +
    • Core API - FMOD_DSP_TYPE_ENVELOPEFOLLOWER is now deprecated and will be removed in a future release.
    • +
    • Core API - Increment Plugin API version for Output plugins. Dynamic library Output Plugins must be rebuilt.
    • +
    • Android - Logging version will now produce proper crash stacks but due to binary size increase the release version will continue to not.
    • +
    • XboxOne - Removed "acp" and "feeder" from FMOD_XBOXONE_THREADAFFINITY. Both threads were removed in previous versions and setting them did nothing.
    • +
    • UE4 - AudioComponents using occlusion from previous versions are NOT compatible with this version. Occlusion and Attenuation now do not rely on UE4 structs.
    • +
    +

    11/09/17 1.09.08 - Studio API minor release (build 90162)

    +

    Fixes:

    +
      +
    • Core API - Fixed extraneous logging.
    • +
    +

    07/09/17 1.09.07 - Studio API minor release (build 90008)

    +

    Features:

    +
      +
    • UE4 - Cache dsp used for occlusion lowpass effect & add support for use of Multiband EQ (lowpass on band A only).
    • +
    • UE4 - FMODAudioComponent now reuses event instances until the object is no longer needed or Release() is called.
    • +
    • UE4 - Added support for UWP.
    • +
    • Unity - Added support for Unity v2017.1.
    • +
    • Unity - Added a button in the FMOD menu for Refreshing Bank files.
    • +
    +

    Fixes:

    +
      +
    • Studio API - Fixed scatterer sounds being processed by FMOD::Geometry.
    • +
    • Studio API - Fixed multi-stream events playing out of sync (introduced in 1.09.01).
    • +
    • Core API - Fixed ChannelControl::setDelay being ignored if addDSP was called immediately after it.
    • +
    • Core API - Fixed potential crash if calling Channel::setPosition soon after System::playSound with paused as true.
    • +
    • Core API - Fixed click on ChannelControl::setPaused (false) caused by a non-zero Channel::setPosition after System::playSound with paused as true.
    • +
    • Core API - Fixed potential crash if calling System::getRecordPosition while disconnecting an audio device.
    • +
    • Core API - Fix FMOD_ACCURATETIME not looping mod/s3m/xm/it files properly, and midi files not looping properly without the flag.
    • +
    • Core API - Fixed crash when attempting to load invalid VST files.
    • +
    • UE4 - Fix compile error by adding categories to AnimNotify vars.
    • +
    • Unity - Switch - Fixed "unknown pointer encoding" error when an exception occurs.
    • +
    • Unity - Fix plugin path for UWP builds.
    • +
    • Unity - Fixed possible crash when using GoogleVR plugin.
    • +
    • Unity - Fix EventEmitter SetParameter not working unless parameter had an inital value set in editor.
    • +
    +

    Notes:

    +
      +
    • Studio API - Reduced memory usage for events with a small number of instances.
    • +
    • Core API - FMOD_CREATESOUNDEXINFO::initialseekposition will now wrap if the value given is longer than the Sound length.
    • +
    • Core API - Added documentation to the top of fmod_codec_raw to be more instructional for plugin writers.
    • +
    • UE4 - Added support for UE4.17.
    • +
    • Unity - Device specific errors will now cause only a single exception to be thrown and the integration will assume no-sound mode.
    • +
    • Switch - Now built with SDK 1.7.0.
    • +
    • XboxOne - Now built with March 2017 QFE 3 XDK.
    • +
    +

    06/07/17 1.09.06 - Studio API minor release (build 88495)

    +

    Features:

    +
      +
    • Studio API - Improved performance when a large number of EventInstances have been created but not started.
    • +
    • Core API - HTML5 - Performance increased by 10%.
    • +
    +

    Fixes:

    +
      +
    • Studio API - Fixed a bug where an asynchronous looping multi instrument would stop selecting new playlist entries after playing a nested event which itself contains an asynchronous looping multi instrument.
    • +
    • Studio API - Fixed a bug where a parameter could trigger parameter instruments before having its value updated by modulators when restarting an event instance.
    • +
    • Studio API - Fixed incorrect automation interpolation on transition timelines with lead-out regions.
    • +
    • Core API - Fixed DSPs with sidechain inputs incorrectly going idle when the main input is idle but the sidechain input is not.
    • +
    • Core API - Fixed the compressor DSP not playing out its release correctly when its inputs are idle.
    • +
    • Core API - Remove main thread stall from System::playDSP (or playing a generator DSP via Studio API).
    • +
    • UE4 - Sequencer integration now supports previewing event playback in an editor viewport by using the Sequencer transport controls. A Sequencer section has been added to the documentation.
    • +
    • UE4 - Added AreBanksLoaded funtion to FMODStudioModule.
    • +
    • Unity - Events in EventBrowser window now in alpabetical order.
    • +
    • Unity - Setting parameters on StudioEventEmitter no longer generates garbage.
    • +
    +

    Notes:

    + +

    08/06/17 1.09.05 - Studio API minor release (build 87666)

    +

    Features:

    +
      +
    • Core API - Switch - Added support for HTC sockets to allow communications between FMOD tools and runtime via target manager. Enable using FMOD_Switch_SetHTCSEnabled(TRUE).
    • +
    • Core API - XboxOne - Added support for System::attachChannelGroupToPort with FMOD_XBOXONE_PORT_TYPE_MUSIC.
    • +
    +

    Fixes:

    +
      +
    • Studio API - Fixed FMOD_ERR_INTERNAL returned when loading old bank files containing transition timeline automation of instrument volumes.
    • +
    • Studio API - Fixed bug where very short instruments would not play when cross fading.
    • +
    • Studio API - Made changes to the logic in Studio::EventDescription::isOneShot so that it consistently returns true for events which are guaranteed to finish without intervention, and false for events which may play indefinitely.
    • +
    • Core API - Fixed ChannelControl::setMixLevelsInput not working and updated docs.
    • +
    • Core API - Fixed Channel::setLoopCount not working with very small streams.
    • +
    • Core API - Stricter error checking when loading IMA ADPCM wav files to prevent a potential crash from malformed data.
    • +
    • Core API - Fixed potential crash in ChannelGroup operations when a Channel failed to play on it with FMOD_ERR_SUBSOUNDS.
    • +
    • Core API - Fixed Convolution reverb panning a mono IR with a stereo input incorrectly.
    • +
    • Core API - Fixed race conditions when setting FMOD_DSP_SEND_RETURNID.
    • +
    • Core API - Fixed a crash with some MOD/S3M/XM/IT files. Introduced in 1.09.00.
    • +
    • Core API - System::setDSPBufferSize will round the requested buffer size up to the closest multiple of 4 to prevent a crash when sending metering data to studio.
    • +
    • Core API - PS4 - Fixed GPU compute compatibility issue with SDK 4.508.001. GPU compute is now re-enabled.
    • +
    • Core API - Switch - Reduced thread priority to avoid conflict with Profiler.
    • +
    • Core API - Windows - Fixed ASIO output mode failing to initialize if the devices requires a buffer size of 2048 samples.
    • +
    • Unity - Fixed bank directory path separators when developing across OSX & Win.
    • +
    • Unity - Fixed simulated Android devices producing no sound.
    • +
    • Unity - BankLoadException now display error message correctly.
    • +
    • Unity - Fixed bank loading and unloading refcount accuracy.
    • +
    • Unity - Fixed Mac editor attempting to load Linux plugins when building for Linux platform.
    • +
    • Unity - Improved detection of 3D Event Instances that haven't had their position set yet.
    • +
    • UE4 - Fixed integration working with UE4's IWYU non-monolithic header system, for now the integration is still using the old PCH system.
    • +
    • UE4 - Added new native AnimNotify class, old one didn't work on code projects.
    • +
    • UE4 - Sequencer integration. FMOD events can be started and stopped and event parameters can be controlled by adding custom tracks to sequencer.
    • +
    • UE4 - Fixed max vorbis codecs not being set correctly.
    • +
    • UE4 - Fixed file readers being accessed from multiple threads.
    • +
    +

    Notes:

    +
      +
    • UE4 - Added support for UE4.16.
    • +
    +

    Notes:

    +
      +
    • Updated Google VR plugin to version 0.4.0, please note there is a known crash when loading the plugin on Windows XP, Google are aware and investigating.
    • +
    +

    10/04/17 1.09.04 - Studio API minor release (build 86084)

    +

    Fixes:

    +
      +
    • Studio API - Fixed delayed playback on streaming sounds in events (introduced in 1.09.03).
    • +
    • Studio API - Fixed AHDSR release not working on single sounds shorter than 100 milliseconds.
    • +
    • Studio API - Fixed Studio::EventDescription::is3D returning true for events that only have 2D panners.
    • +
    • Studio API - Set programmer sounds to FMOD_LOOP_NORMAL internally if they were not created that way.
    • +
    • Studio API - Fixed regression introduced in 1.09.00 which allowed events to play at the origin before 3d attributes were updated.
    • +
    • Studio API - Fixed issue where reverb tail would cut off when all events on a bus finished playing.
    • +
    • Core API - Fixed FMOD_DSP_TRANSCEIVER making channels audible that weren't supposed to be (introduced with glitch fix in 1.09.03).
    • +
    • Core API - Fixed loop clicks on PCM sounds if using FMOD_DSP_RESAMPLER_CUBIC or FMOD_DSP_RESAMPLER_SPLINE.
    • +
    • Core API - Fixed FMOD_ADVANCEDSETTINGS::resamplerMethod being ignored.
    • +
    • Core API - Fixed plugin unloading for multi-description libraries potentially failing depending on how it's unloaded.
    • +
    • Core API - Fixed stream glitch when going virtual then resuming.
    • +
    • Core API - Fixed virtual voices losing their loop/2d/3d status, and not staying virtual if ChannelControl::setMode was used. Introduced in 1.09.00.
    • +
    • Core API - Fixed FMOD_UNIQUE not being accepted if ChannelControl::setMode or Sound::setMode was used. (it could be successfully used via createSound/createStream).
    • +
    • Core API - Fixed rare crash in mixer, introduced 1.09.00.
    • +
    • Core API - Switch - Fixed FMOD_SWITCH_THREADAFFINITY so cores can be ORd together to form a mask.
    • +
    • Core API - PS4 - GPU compute disabled due to an incompatibility with SDK 4.508.001.
    • +
    • Core API - Windows/Mac - Re-enable SRS downmixer 80Hz high pass filter by default. Add FMOD_INIT_DISABLE_SRS_HIGHPASSFILTER init flag to disable it.
    • +
    • FSBank API - Fixed PS Vita AT9 encoder not working with currently available Sony library.
    • +
    • FSBank API - Fixed full scale 32bit float wav files encoding incorrectly.
    • +
    +

    Notes:

    +
      +
    • Studio API - FMOD expects programmer sounds to be created with FMOD_LOOP_NORMAL. This is now specified in the FMOD_STUDIO_PROGRAMMER_SOUND_PROPERTIES documentation.
    • +
    • FSBank API - Building an FSB with PS Vita AT9 encoding now requires 64bit.
    • +
    • PS4 - Now built with SDK 4.508.001.
    • +
    • Switch - Now built with SDK 0.12.17.
    • +
    • XboxOne - Now built with October 2016 QFE 2 XDK.
    • +
    +

    20/03/17 1.09.03 - Studio API minor release (build 85359)

    +

    Features:

    +
      +
    • Core API - Updated the /examples/dsp_custom example to include a lot more functionality including parameters, and capture of wave data.
    • +
    • Core API - Add fmod_reduced.js for reduced functionality, but also reduced size.
    • +
    • Core API - Switch - Added support for setting thread affinity.
    • +
    • Studio API - Reduced size of fmodstudio.js and .mem files.
    • +
    +

    Fixes:

    +
      +
    • Studio API - Fixed event doppler settings not being applied to sounds spawned by scatterer.
    • +
    • Studio API - Fixed bus and VCA handles not being set up properly in Studio::Bank::getBusList and Studio::Bank::getVCAList.
    • +
    • Studio API - Fixed crashes caused by stopping events that are routed into a bus with instance limiting enabled when they are in the FMOD_STUDIO_PLAYBACK_STARTING state.
    • +
    • Studio API - Fixed tempo and marker event callbacks not being fired when the timeline cursor is in the lead-in or lead-out region of a transition timeline.
    • +
    • Core API - Fixed glitches with Transceiver DSP after inputs go idle.
    • +
    • Core API - Fix Channel::setPosition (pos, FMOD_TIMEUNIT_MODORDER) not working when playing paused.
    • +
    • Core API - Fixed short streams created as non-looping then switched to looping via the Channel API not looping seamlessly.
    • +
    • Core API - Fixed DSP plugin version >= 109 data parameters other than 3D attributes not applying if FMOD_INIT_3D_RIGHTHANDED is used.
    • +
    • Core API - Fixed rare crash in FMOD Panner DSP. Introduced in 1.09.00.
    • +
    • Core API - Re-Fix MOD/S3M/XM/IT file crash with samples that have 0 length, for 1.09 only.
    • +
    • Core API - Fixed potential memory leak if System::init returned an error.
    • +
    • Core API - Fix FMOD_ACCURATETIME not looping a mod file properly, and not seeking correctly with FMOD_TIMEUNIT_MODORDER.
    • +
    • Core API - HTML5 - Loading FSB sounds did not work properly.
    • +
    • Core API - Windows - Fixed 5.1->stereo SRS downmix causing lack of bass.
    • +
    • Core API - Windows - Fix FMOD_INIT_PREFER_DOLBY_DOWNMIX not working.
    • +
    • FSBank API - Fix crash if FSBANK_INIT_GENERATEPROGRESSITEMS is not used.
    • +
    • Unity - Removed error when plugin field is added but empty.
    • +
    • UE4 - Removed error when plugin field is added but empty.
    • +
    +

    Notes:

    +
      +
    • UE4 - Added support for UE4.15.
    • +
    +

    15/02/17 1.09.02 - Studio API minor release (build 84334)

    +

    Fixes:

    +
      +
    • Unity - Remove ifdef from EnforceLibraryOrder as it isn't harmful for static lib platforms to call GetStats.
    • +
    • UE4 - Occlusion can now use Multiband EQ instead of Lowpass filter.
    • +
    • Core API - Fix crash when connecting to FMOD Profiler.exe and there is a circular connection
    • +
    • Core API - Fix glitches with Transceiver DSP after inputs go idle.
    • +
    • Core API - Fix Channel::setPosition (pos, FMOD_TIMEUNIT_MODORDER) not working when playing paused.
    • +
    +

    09/02/17 1.09.01 - Studio API minor release (build 84153)

    +

    Features:

    +
      +
    • Core API - Added FMOD_DSP_STATE_FUNCTIONS::getlistenerattributes to the DSP plugin API to query the current listener attributes.
    • +
    • Unity - Added support for Rigidbody2D in 3D attribute settings and integration scripts.
    • +
    • Unity - Added support for Object Enable/Disable on EventEmitter and ParameterTrigger scripts.
    • +
    • UE4 - Added GetLength function for blueprints that returns the event length in milliseconds.
    • +
    • UE4 - Improved in editor profiling stats.
    • +
    +

    Fixes:

    +
      +
    • Unity - Fixed compatibility with Unity 4.6 & 4.7 for OSX and IOS.
    • +
    • Unity - Fixed "file not found" error when settings asset is corrupt
    • +
    • Unity - Fixed set3DAttributes ambiguity.
    • +
    • Unity - Fixed not being able to copy ReadOnly banks into StreamingAssets.
    • +
    • Unity - Fixed event instance leak in Unity PlayOneshotAttached not releasing.
    • +
    • Unity - Specified version to check for WiiU BuildTarget for early Unity5.
    • +
    • UE4 - Fixed XboxOne delayload error now that UE4 handles it.
    • +
    • UE4 - Android - Added ARM64 support.
    • +
    • Studio API - AHDSR modulator curve shapes now work correctly. In previous versions the envelope was interpolated linearly regardless of the shape displayed in the UI.
    • +
    • Studio API - Fixed looping single sounds in an async multi sound being cut-off when the multi sound is un-triggered.
    • +
    • Core API - Fixed ChannelControl::setReverbProperties not resetting reverb connection to a new tail DSP when turning wet mix off and on.
    • +
    • Core API - If the system is initialized in right-handed mode, FMOD will now swap to left-handed when passing attributes into plugins. This only applies to plugins rebuilt against this version, old plugins remain unswapped.
    • +
    • Core API - Fix MOD/S3M/XM/IT file crash with samples that have 0 length.
    • +
    • Core API - Fixed some potential crashes when running out of memory, these will correctly return FMOD_ERR_MEMORY now.
    • +
    • Core API - Win - Fixed WASAPI recording device enumeration taking a couple of seconds after System::init before being correct.
    • +
    • Core API - Win - Fixed potential error returned from System::update if device is unplugged.
    • +
    • Core API - MIDI - Fixed Sound::set/getMusicChannelVolume referring to wrong track indices rather than just a normal 0-15 track index.
    • +
    • Core API - MIDI - Fixed Channel::setPosition causing loud drum bang noise after seek
    • +
    +

    Notes:

    +
      +
    • Studio API - When loading legacy banks with looping sounds nested in multi sounds, the multi sound is set to cut-off all sounds when untriggered, including non-looping sounds. This is a change in behaviour compared to earlier versions where only looping sounds were cut-off.
    • +
    • Core API - DSP plugin API version has been increased, for maximum compatibility plugin writers should only rebuild against this version if they need the getlistenerattributes feature. Old plugins are still supported.
    • +
    • Switch - Now built with SDK 0.12.10
    • +
    +

    01/12/16 1.09.00 - Studio API major release (build 82164)

    +

    Important:

    +
      +
    • Added support for the Nintendo Switch platform.
    • +
    +

    Features:

    + +

    Fixes:

    +
      +
    • Studio API - Fixed incorrect playback volume for instruments and playlist items whose volume property is set to a non-zero dB value.
    • +
    +

    Notes:

    +
      +
    • Core API - Incremented Plugin SDK version for DSP plugins. Dynamic library plugins built with earlier versions will continue to load.
    • +
    • Core API - Incremented FMOD_CODEC_WAVEFORMAT version. Codecs that provide names must keep the name memory persistent for the lifetime of the codec.
    • +
    • Core API - Increment Plugin API version for Output plugins. Dynamic library Output Plugins must be rebuilt.
    • +
    • Core API - FMOD_DSP_TYPE_LOWPASS, FMOD_DSP_TYPE_LOWPASS_SIMPLE, FMOD_DSP_TYPE_HIGHPASS, FMOD_DSP_TYPE_HIGHPASS_SIMPLE and FMOD_DSP_TYPE_PARAMEQ are considered deprecated and will be removed in the future. Use the new FMOD_DSP_TYPE_MULTIBAND_EQ instead which has the performance of "simple" effects with full featured quality.
    • +
    • Core API - Changed reverb wet mix to send from the fader DSP of a ChannelGroup. Previously it sent from the head DSP. Now effects placed pre-fader will apply to the signal sent to the reverb, while effects placed post-fader will not.
    • +
    • Core API - ChannelGroup reverb wet level is now scaled by the group's effective audibility.
    • +
    • Core API - ChannelGroup reverb no longer automatically disables reverb on its child channels when the wet level is set to non-zero.
    • +
    • Core API - Channel::setReverbProperties now allows setting the wet level before the specified reverb instance has been created.
    • +
    • Core API - ChannelControl::addDSP and ChannelControl::removeDSP manage standard DSP connections (FMOD_DSPCONNECTION_TYPE_STANDARD) to maintain the mixer hierarchy. Other connection types (FMOD_DSPCONNECTION_TYPE_SIDECHAIN, FMOD_DSPCONNECTION_TYPE_SEND_SIDECHAIN, and now FMOD_DSPCONNECTION_TYPE_SEND) are left undisturbed.
    • +
    • Core API - FMOD_INIT_MIX_FROM_UPDATE will now directly execute the mixer from System::update instead of triggering the mix to happen in another thread.
    • +
    • Studio API - Incremented bank version, requires runtime 1.09.00 or later.
    • +
    • Studio API - Latest runtime supports loading old bank versions from 1.03.00.
    • +
    • Studio API - Studio::Bus::setFaderLevel, Studio::Bus::getFaderLevel, Studio::VCA::setFaderLevel and Studio::VCA::getFaderLevel is now called Studio::Bus::setVolume, Studio::Bus::getVolume, Studio::VCA::setVolume and Studio::VCA::getVolume.
    • +
    • Studio API - Studio::EventInstance::getVolume, Studio::EventInstance::getPitch, Studio::EventInstance::getParameterValue, Studio::EventInstance::getParameterValueByIndex, Studio::Bus::getVolume, Studio::VCA::getVolume now have an additional argument to get the final value which includes automation and modulation.
    • +
    • Studio API - The required alignment for Studio::System::loadBankMemory has been added as the constant FMOD_STUDIO_LOAD_MEMORY_ALIGNMENT.
    • +
    • Studio API - Event instances now disable reverb on their internal channels, for all global reverb instances. Previously only did so for reverb instance 0. Use Studio::EventInstance::setReverbLevel to control the reverb mix for the whole event instance.
    • +
    • Studio API - Disconnected sidechain modulators are now inactive. Previous behavior was to fall back to monitoring the event's master track output.
    • +
    • Core API - FMOD_DSP_RELEASE_CALLBACK is now called from the main thread
    • +
    • Core API - Unimplemented ChannelControl::overridePanDSP function has been removed, along with FMOD_CHANNELCONTROL_DSP_PANNER enum value.
    • +
    • Core API - PS3 - Removed old opt-in FIOS support via FMOD_PS3_EXTRADRIVERDATA. New recommended approach is to use FMOD_FILE_ASYNCREAD_CALLBACK and set appropriate deadlines based on FMOD_ASYNCREADINFO::priority.
    • +
    • Core API - XboxOne - Optimized XMA decoding performance and removed the ACP thread.
    • +
    • Core API - PS4 - Improved AT9 decoding performance.
    • +
    • FSBank API - Added support for source data as a memory pointer instead of file name.
    • +
    • Documentation - Some FMOD_DSP_PAN_SURROUND enums changed to FMOD_DSP_PAN_2D for clarity.
    • +
    +

    01/12/16 1.08.15 - Studio API minor release (build 82163)

    +

    Features:

    +
      +
    • PS4 - Add support for System::getOutputHandle, to return sce port handle. Fixes:
    • +
    • UE4 - Fix missing plugin error when building on Mac.
    • +
    • UE4 - Fixed compatibility with 4.14.
    • +
    • Unity - Fixed OSX working with unified library.
    • +
    • Unity - Fixed WiiU copying banks error.
    • +
    • Unity - Fixed XboxOne dll meta files missing platform target.
    • +
    • Unity - Fixed duplicate dll copying build error on some platforms.
    • +
    • Unity - Added null check to stop error being thrown when no event assigned.
    • +
    • Unity - Fix in editor out of bounds exception in RuntimeManager.
    • +
    • Core API - Allow DSP::setParameterData with null data and 0 length to free convolution reverb impulse response data.
    • +
    • Core API - Fixed short looping streams playing some of the start when switched to non-looping via the Channel API.
    • +
    • Core API - Fixed FMOD_CREATESOUNDEXINFO::pcmsetposcallback getting wrong sound pointer passed to it with a stream.
    • +
    • Studio API - Fixed incorrect parameter values being passed to nested events when value "hold" is being used.
    • +
    • Studio API - PS3 - Fix potential crash with the new Channel Mix effect.
    • +
    • FSBank API - Fixed encoder bug with FADPCM causing occasional clipping at playback.
    • +
    +

    Notes:

    +
      +
    • FSBank API - FSBs / Banks may not be binary identical to previous release due to FADPCM encoder bug fix, however full compatibility is maintained.
    • +
    +

    20/10/16 1.08.14 - Studio API minor release (build 80900)

    +

    Fixes:

    +
      +
    • UE4 - Fix for crash when using "Validate FMOD" menu item
    • +
    +

    Notes:

    +
      +
    • PS4 - Now built with SDK 4.00
    • +
    • XboxOne - Added better logging and documentation to describe an incorrectly configured appxmanifest regarding microphone recording.
    • +
    +

    04/10/16 1.08.13 - Studio API minor release (build 80479)

    +

    Fixes:

    +
      +
    • Studio API - Fixed potential crash after the following sequence of actions: load master bank, try to load master bank again and fail with FMOD_ERR_EVENT_ALREADY_LOADED, unload master bank, reload master bank.
    • +
    • Core API - Fix circular DSP connection causing hang in certain situations.
    • +
    • Unity 2 - Fix issues with multi-object editing of emitters.
    • +
    +

    22/09/16 1.08.12 - Studio API minor release (build 80229)

    +

    Features:

    +
      +
    • Unity 2 - Added ability to override minimum and maximum distance for Event emitters.
    • +
    • Unity 2 - Added support for multiple listeners.
    • +
    • Studio API - Added support for auto pitch at minimum.
    • +
    • Studio API - Added support for the global master bus being duplicated across banks.
    • +
    +

    Fixes:

    +
      +
    • Studio API - Fix auto pitch cutting off at zero for parameter with minimum value that is less than zero.
    • +
    • Studio API - Fix events with a transciever effect not allowing the event to stop
    • +
    • Android - Fixed crash when loading FSBs or Banks that contain a sound that isn't mono, stereo, 5.1 or 7.1.
    • +
    • Android - Fixed compatibility issue with some devices introduced in previous release due to r12b update. Presents as a runtime linker error when loading the FMOD library, failing to locate __aeabi_atexit.
    • +
    • iOS - Fixed stuttering during fade out when device screen goes to sleep.
    • +
    • Core API - Fix FMOD_DSP_TRANSCEIVER memory stomp.
    • +
    • Core API - Fix channels playing at incorrect pitch. Introduced in 1.08.10.
    • +
    +

    Notes:

    +
      +
    • Studio API - Incremented bank version, requires runtime 1.08.00 or later.
    • +
    • Studio API - Latest runtime supports loading old bank versions from 1.03.00.
    • +
    • Core API - Improved validation for ChannelGroup, DSP and Sound handles, detects invalid pointers and usage after release.
    • +
    +

    08/09/16 1.08.11 - Studio API minor release (build 79819)

    +

    Features:

    +
      +
    • Core API - PS3 - Added support for FMOD_DSP_CHANNELMIX.
    • +
    • Unity 2 - Respect Game View mute button.
    • +
    +

    Fixes:

    +
      +
    • FSBank - Fix crash on 64-bit when encoding 16kHz or 24kHz sources using Vorbis at low quality settings.
    • +
    • Core API - Fix FMOD_SOUND_PCMSETPOS_CALLBACK getting invalid position value when a sound opened with FMOD_OPENUSER loops.
    • +
    • Core API - Android - Fixed crash on load with old devices when using armeabi.
    • +
    • Unity 2 - Fix CREATESOUNDEXINFO not getting marshalled properly.
    • +
    +

    Notes:

    +
      +
    • Android - Now built with NDK r12b.
    • +
    • Android - Minimum Android version is now API level 9 due to NDK r12b deprecating older versions.
    • +
    +

    22/08/16 1.08.10 - Studio API minor release (build 79252)

    +

    Features:

    +
      +
    • Studio API - Improved performance of sidechain modulator.
    • +
    • Core API - Improved ChannelControl::setPitch accuracy between DSP clock and the underlying codec decoding speed.
    • +
    • Unity 2 - Added option for play-in-editor to reflect the active build target for loading banks.
    • +
    +

    Fixes:

    +
      +
    • Core API - Fixed error trying to create a Return DSP when the system format is set to FMOD_SPEAKERMODE_RAW.
    • +
    • Core API - Fixed FFT DSP crash if window size is smaller than DSP block size.
    • +
    • Core API - Removed spurious warning messages when loading plugins on some platforms.
    • +
    • Core API - Android - Tweaked OpenSL auto detection, now requires device to specify low latency and a block size <= 1024.
    • +
    • Unity 2 - Fix bank import issues when the strings bank contains bank names that differ in case from the files on disk.
    • +
    • Unity 2 - Bank import now has a longer timeout after last detected file activity before starting import.
    • +
    • Unity 2 - Fixed settings screen allowing real channels to be set higher then 256.
    • +
    • Unity 2 - Fix up errors when StudioEventEmitter is created dynamically.
    • +
    • Unity 2 - Small fixes for the settings screen when overriding the parent platform settings.
    • +
    • UE4 - Fix for crash when previewing animations using the FMOD event notifier.
    • +
    +

    Notes:

    + +

    01/08/16 1.08.09 - Studio API minor release (build 78489)

    +

    Features:

    +
      +
    • Core API - PS4 - Add support for social screen audio to the ports API.
    • +
    • Studio API - Added Studio::EventInstance:setListenerMask and Studio::EventInstance::getListenerMask, that adds the ability to specify which listeners apply to each event instance.
    • +
    • Unity 2 - Warning is now produced when playing in editor if the position of a 3D event is not set.
    • +
    • UE4 - Added blueprint functions to set event properties.
    • +
    +

    Fixes:

    +
      +
    • Studio API - Fixed case of indeterminism when building banks that contain events with automation curves.
    • +
    • Core API - Fixed FMOD_OUTPUT_OBJECT3DINFO::gain so it only includes distance attenuation not bus gain (which is now pre-applied to FMOD_OUTPUT_OBJECT3DINFO::buffer.
    • +
    • Core API - Fixed channelmix DSP volume not always being initialized.
    • +
    • Core API - WiiU - Fixed potential crash during System::init if System::setDriver or System::setOutput has been called.
    • +
    • Core API - Fix hang on netstreams when the connection times out.
    • +
    • Core API - Linux - Fix FPU control word of the calling thread being modified when the FMOD dynamic library is loaded.
    • +
    • Core API - Android - Fixed potential crash if FMOD isn't loaded with System.loadLibrary, now a proper error will be issued.
    • +
    • FSBank API - Fixed FADPCM not looping seamlessly for non-zero crossing loops.
    • +
    • UE4 - Fixed plugin loading assuming a "lib" prefix for plugins on Android, Mac, Linux and PS4. Now plugin loading will attempt to load the name with and without adding a lib prefix.
    • +
    • UE4 - Respect FApp::IsUnattended for message-box errors.
    • +
    • UE4 - Fixed deprecation warnings about AttachTo usage.
    • +
    • Unity 2 - Fix errors when bank source files are updated while Event Browser preview is playing or paused.
    • +
    • Unity 2 - Fix unnecessary copying of Bank files in OSX editor.
    • +
    +

    Notes:

    +
      +
    • Core API - Linux - Removed limit of 32 devices with ALSA output mode.
    • +
    • Core API - Incremented API version of Output plugins. Dynamic library plugins built with earlier versions of 1.08 will continue to load.
    • +
    +

    14/07/16 1.08.08 - Studio API minor release (build 77846)

    +

    Features:

    +
      +
    • UE4 - bMatchHardwareSampleRate will use the system default format to avoid excessively matching the output rate on mobile devices.
    • +
    • UE4 - Added bLockAllBuses which will force all buses to be created at startup, rather than on demand.
    • +
    +

    Fixes:

    +
      +
    • Studio API - Fixed looping sounds in a multi sound playlist failing to stop if the multi sound itself is non-looping.
    • +
    • Studio API - Fixed rare crash calling the following functions while the bank containing the event is unloading: Studio::EventInstance::getDescription, Studio::EventInstance::getParameter, Studio::EventInstance::getParameterValue, Studio::EventInstance::setParameterValue, Studio::EventInstance::setParameterValueByIndex, Studio::EventInstance::triggerCue, Studio::ParameterInstance::getDescription and Studio::ParameterInstance::setValue.
    • +
    • Studio API - Fixed shared events becoming invalidated when one of the banks containing them is unloaded. Could also manifest as Studio::EventInstance::getDescription failing with FMOD_ERR_INTERNAL.
    • +
    • Studio API - Fixed crash that could occur when using FMOD_STUDIO_INIT_SYNCHRONOUS_UPDATE and calling Studio::System::update from multiple threads at the same time.
    • +
    • Studio API - Increased scheduling lookahead time to ensure sample accurate timeline scheduling even if there is an output stall.
    • +
    • Studio API - Fixed crash that could occur when improperly calling Studio::Bus::getChannelGroup without first calling Studio::Bus::lockChannelGroup, if the bus was being destroyed as the call was made.
    • +
    • Studio API - Fixed rare crash calling the following functions while the master bank containing the bus or VCA is unloading: Studio::System::getBus, Studio::System::getBusByID, Studio::System::getVCA and Studio::System::getVCAByID.
    • +
    • Studio API - Fixed rare timing issue where Studio::System::getEvent would succeed but Studio::EventDescription::createInstance would fail with FMOD_ERR_INTERNAL, if called just as the bank containing the event finished loading.
    • +
    • Studio API - Fixed rare hang in Studio::System::getBankCount when called while banks are currently unloading.
    • +
    • Core API - Fixed rare glitch at the start of XMA playback causing non-seamless looping.
    • +
    • Core API - Fixed rare hang on shutdown when using multiple systems.
    • +
    • Core API - Fix streams with an unknown file length remaining in the playing state after an end of file is encountered.
    • +
    • Core API - Windows - Enumeration of record devices will now reflect a change of default device with WASAPI output.
    • +
    • Core API - Linux - Enumeration will now correctly display GUIDs and speaker modes for ALSA output.
    • +
    • Core API - Linux - Fixed potential crash if both PulseAudio and ALSA are missing / unavailable.
    • +
    • Unity 2 - Fix plugin loading on Linux standalone builds.
    • +
    • Unity 2 - Fix script compilation errors in standalone builds.
    • +
    • Unity 2 - Fix Event Browser preview of events with built-in parameters.
    • +
    • Unity 2 - Fix missing tvOS files.
    • +
    +

    Notes:

    +
      +
    • Core API - Significantly reduced memory consumption when using FMOD_DSP_FFT.
    • +
    • PS4 - Now built with SDK 3.508.101
    • +
    • UE4 - Updated Oculus plugin to 1.0.4.
    • +
    +

    27/06/16 1.08.07 - Studio API minor release (build 77241)

    +

    Features:

    +
      +
    • FSBank API - Added support for Linux.
    • +
    • Unity 2 - Live Update and Debug Overlay can be set to only be enabled in standalone builds when the development build option is set.
    • +
    • Unity 2 - Add MuteAllEvents and PauseAllEvents functions to the RuntimeManager.
    • +
    • Unity 2 - Audio will now pause when the application pauses.
    • +
    • UE4 - Added MixerSuspend and MixerResume blueprint functions.
    • +
    • UE4 - Added IsBankLoaded blueprint function.
    • +
    +

    Fixes:

    +
      +
    • Studio API - Fixed Studio command buffer assert and crash that could occur when using FMOD_STUDIO_INIT_SYNCHRONOUS_UPDATE in conjunction with multiple threads.
    • +
    • Core API - Fix crash when closing a system with a multi-plugin DLL still loaded.
    • +
    • Core API - iOS / Android - Improved audio stability when mixer thread is overloaded.
    • +
    • FSBank API - Fixed calling convention linker error on Windows in FSBankLib header.
    • +
    • FSBank API - Fixed issue when passing duplicate source files with different encoding settings would cause cache file conflicts.
    • +
    +

    Notes:

    +
      +
    • Unity 2 - Renamed "Level Start" and "Level End" triggers to "Object Start" and "Object Destroy" to more accurately reflect when the triggers occur.
    • +
    +

    17/06/16 1.08.06 - Studio API minor release (build 76937)

    +

    Features:

    +
      +
    • Unity 2 - Added framework for registering native plugins on iOS and tvOS.
    • +
    • Unity 2 - Added support for importing Studio Banks as TextAssets so they can be added to Unity AssetBundles.
    • +
    +

    Fixes:

    +
      +
    • Core API - Fixed crash on shutdown, after creating multiple systems and setting a system callback.
    • +
    • Core API - PS4 - Fix issues with calling FMOD_PS4_GetPadVolume() immediately after opening the controller audio port.
    • +
    +

    15/06/16 1.08.05 - Studio API minor release (build 76824)

    +

    Features:

    +
      +
    • Studio API - Added Studio::EventDescription::isSnapshot.
    • +
    • Unity 2 - Added "Preload Sample Data" checkbox to Event Emitter to reduce latency when emitters are triggered for the first time.
    • +
    • Unity 2 - Added script example to show how to build an asynchronous loading screen that includes loading FMOD Banks.
    • +
    +

    Fixes:

    +
      +
    • Studio API - Fixed Studio::EventDescription::isOneshot () incorrectly returning true for snapshots.
    • +
    • Core API - Fix FMOD_ADVANCEDSETTINGS::maxADPCMCodecs not being applied.
    • +
    • Core API - Fix crash when using CreateSound from multiple threads (including FMOD Async loading threads).
    • +
    • Unity 2 - Fix issues when bank file in the Unity project Streaming Assets folder have a different case to the banks in the Studio project.
    • +
    • Unity 2 - Fix issues when editor log file cannot be opened because it's read only.
    • +
    • Unity 2 - If the "Load All" options are selected in the FMOD Settings then the main thread will now block until it's complete.
    • +
    • UE4 - Fix for OnEventStopped callback firing repeatedly if triggers the instance to play again.
    • +
    +

    Notes:

    +
      +
    • Core API - All System, ChannelControl, ChannelGroup, Channel, and DSP API functions check for NaN and INF floats and return FMOD_ERR_INVALID_FLOAT if detected.
    • +
    • Studio API - All API functions check for NaN and INF floats and return FMOD_ERR_INVALID_FLOAT if detected.
    • +
    • Studio API - All API functions with output parameters now clear those values in the case of an error. Previously some values may have been left uninitialized. In the case of an error, int and float outputs are set to 0, bool outputs are set to false, and pointers are set to NULL. Structures are cleared to zeros, and string buffers are set to the empty string.
    • +
    +

    25/05/16 1.08.04 - Studio API minor release (build 76196)

    +

    Features:

    +
      +
    • Studio API - Added runtime support for steal quietest polyphony.
    • +
    • Core API - Improved performance when connecting sends and returns.
    • +
    • UE4 - FFMODEventInstance can now be stored as a blueprint variable.
    • +
    • UE4 - Added support for Occlusion. See the Occlusion section of the documentation for more information.
    • +
    • UE4 - Added support for Android deployment without having to modify the engine.
    • +
    • UE4 - Added InitialDriverOutputName to select output device by name at startup, as well as new Blueprint functions GetOutputDrivers, SetOutputDriverByName and SetOutputDriverByIndex.
    • +
    • UE4 - Added VCASetFaderLevel Blueprint function.
    • +
    • UE4 - "FMOD Validate" now checks for FMOD in the packaging setting, and can add it if needed.
    • +
    +

    Fixes:

    +
      +
    • Core API - Fixed unnecessary DSP queue flush when using ports.
    • +
    • Core API - Fixed ADPCM and FADPCM compressed FSBs not returning FMOD_ERR_MEMORY_CANTPOINT when loaded as FMOD_OPENMEMORY_POINT FMOD_CREATESAMPLE.
    • +
    • Core API - Fix pops when channels with a mix matrix that are started virtual become real.
    • +
    • Core API - Fixed DSP panner reset not clearing ramps, causing ramping when setting initial parameters.
    • +
    • Core API - Fixed Sound::getSyncPointInfo returning first sync point info when loading sounds from FSBs with multiple sync points.
    • +
    • Studio API - Fixed memory stomp that can occur when sharing events between multiple banks, if a streaming sound is in the middle of loading when one of the shared banks is unloaded.
    • +
    • Unity 2 - Fix error messages when previewing an event contained in the Master Bank.
    • +
    • Unity 2 - Fix WinPhone 8.1 DLL's conflicting with UWP builds.
    • +
    +

    Notes:

    +
      +
    • Studio API - Incremented bank version, requires runtime 1.08.00 or later.
    • +
    • Studio API - Latest runtime supports loading old bank versions from 1.03.00.
    • +
    • UE4 - Updated ovrfmod to version 1.0.3.
    • +
    • UE4 - Tested with 4.12 pre-release, compiles successfully.
    • +
    • PS Vita - Now built with SDK 3.570.011.
    • +
    +

    05/05/16 1.08.03 - Studio API minor release (build 75571)

    +

    Features:

    +
      +
    • Studio API - Added FMOD_STUDIO_EVENT_CALLBACK_SOUND_PLAYED and FMOD_STUDIO_EVENT_CALLBACK_SOUND_STOPPED for when an event plays sounds. Sound names will only be available if banks have been re-exported in FMOD Studio 1.08.03 or later. See the music_callbacks example for demonstration.
    • +
    • Studio API - Added runtime support for the event cooldown property set from FMOD Studio. Events that fail to start due to cooldown time will invoke the FMOD_STUDIO_EVENT_CALLBACK_START_FAILED callback.
    • +
    • Core API - Improved performance of logging.
    • +
    • Core API - PS4 - Improved performance when profiling is enabled.
    • +
    +

    Fixes:

    +
      +
    • Studio API - Events that fail to start due to bus polyphony now invoke the FMOD_STUDIO_EVENT_CALLBACK_START_FAILED callback.
    • +
    • Studio API - Fixed crash when calling Studio::System::unloadAll with crossfading nested events.
    • +
    • Studio API - Fixed unnecessary up/down mix applied to 2D events that have sidechain modulators.
    • +
    • Studio API - Fixed mixing issues and degraded performance if the system speaker mode does not match the Studio project format.
    • +
    • Studio API - Fixed case of stereo sounds panning hard right when downmixed to a mono track and later upmixed again, introduced in 1.07.04.
    • +
    • Core API - Fixed potential incorrect position when voice comes back from being virtual, which can cause a hang on XboxOne.
    • +
    • Core API - Improved handling for out of memory errors when mixing DSP buffers.
    • +
    • Core API - Fixed incorrect propagation of FMOD_DSP_STATE::channelmask when mixing signals with differing masks.
    • +
    • Core API - Fixed http streams (file from http, not shoutcast/icecast) returning FMOD_ERR_FORMAT. Introduced 1.08.01
    • +
    • Core API - Fixed m3u playlist file format support. Was returning FMOD_ERR_FORMAT.
    • +
    • Core API - Android - Improved detection of low-latency devices allowing better automatic output mode selection and less stuttering.
    • +
    • Core API - Sound::getName will now return "" for sounds without names, instead of "(null)".
    • +
    • Core API - Object 3D Panning fix for silent objects in certain speaker modes
    • +
    • Studio API - More robust live update handshaking when attempting to connect with multiple copies of FMOD Studio at once.
    • +
    • Unity 2 - Added missing Studio::EventDescription::getSoundSize function.
    • +
    +

    Notes:

    +
      +
    • Studio API - Incremented bank version, requires runtime 1.08.00 or later.
    • +
    • Studio API - Latest runtime supports loading old bank versions from 1.03.00.
    • +
    • Studio API - Sound names are now loaded into memory if they have been exported in the bank file. The option is on by default, which means by the runtime memory use might be slightly higher when loading banks exported from 1.08.03 and later. If this is a problem, make sure to disable the option to export sound names in FMOD Studio when re-exporting banks.
    • +
    • XboxOne - Now built with March 2016 QFE 1 XDK.
    • +
    • PS4 - Now built with SDK 3.508.031.
    • +
    +

    13/04/16 1.08.02 - Studio API minor release (build 74770)

    +

    Fixes:

    +
      +
    • UE4 - Fixed audio component transform not being updated in 4.11.
    • +
    • Studio API - Fixed unnecessary up/down mix applied to 2D events that have sidechain modulators.
    • +
    • Studio API - Studio::EventDescription::is3D now returns true if there is a plug-in panner on the master track.
    • +
    +

    Notes:

    +
      +
    • UE4 - PS4 - Deployment uses standard unreal plugin system.
    • +
    • UE4 - Now built against Unreal 4.11
    • +
    +

    07/04/16 1.08.01 - Studio API minor release (build 74554)

    +

    Features:

    +
      +
    • Unity 2 - Added Universal Windows Application platform support.
    • +
    • Unity 2 - Added Find and Replace tool.
    • +
    • Core API - Improved performance when creating DSPs.
    • +
    • UE4 - Added FMOD stats for CPU usage.
    • +
    +

    Fixes:

    +
      +
    • Studio API - Fixed errors being generated when the initial seek is past the loop end point of a sound.
    • +
    • Studio API - Fixed error loading sample data for banks loaded by Studio::System::loadBankMemory with FMOD_STUDIO_LOAD_BANK_DECOMPRESS_SAMPLES flag.
    • +
    • Studio API - Fixed rare Studio update error FMOD_ERR_NOTREADY when stopping modules with streaming sounds.
    • +
    • Studio API - Fixed unnecessary up/down mix on sidechain effects in game.
    • +
    • Studio API - Eliminated API stalls due to holding a lock when creating event instances on the Studio Update thread.
    • +
    • Studio API - Fixed error when loading an API capture that contains Studio::System::flushSampleLoading commands.
    • +
    • Studio API - PS4 - Fixed incorrect linking options on fmodstudio.prx that caused package creation to fail.
    • +
    • Core API - Fixed rare hang when rapidly creating and releasing Return DSPs.
    • +
    • Core API - Fixed hang or crash when loading a .it/s3m/mod/mid file as a decompressed sound.
    • +
    • Core API - Fixed some shoutcast streams playing back garbled.
    • +
    • Core API - Fixed Sound::readData returning 0 for bytes read, instead of a valid number if FMOD_ERR_FILE_EOF was returned. Introduced in 1.07.08.
    • +
    • Core API - PS4 - Fix AT9 playback when a sound created as looping is played with the channel loop-count explicitly set to zero before starting.
    • +
    • Core API - Win - Fixed ASIO device enumeration not supplying a GUID.
    • +
    • Core API - Win - Fixed ASIO device enumeration having a blank name if the device is not connected.
    • +
    • UE4 - Added lock around file accesses to avoid Unreal pak file thread safety issue.
    • +
    • UE4 - Fixed logging callback not being initialized.
    • +
    • UE4 - Avoid asset table system from mixing while normal mixer is in operation, to work around an AT9 mixer issue.
    • +
    • UE4 - Fixed always linking against ovrfmod even if it isn't present.
    • +
    • Unity 2 - Rewrote Timeline Callback and Programmer Sound Callback examples to work on iOS.
    • +
    • Unity 2 - Fix marshalling of FMOD.CREATESOUNDEXINFO structure on iOS.
    • +
    • Unity 2 - Fix DLL not found errors in standalone Windows builds.
    • +
    +

    Notes:

    +
      +
    • Studio API - Incremented bank version, requires runtime 1.08.00 or later.
    • +
    • Studio API - Latest runtime supports loading old bank versions from 1.03.00.
    • +
    • Studio API - Studio::EventInstance::setPitch () now returns an error if a NaN is passed in.
    • +
    • Studio API - Errors that occur during the Studio update thread will no longer stop the thread.
    • +
    • Studio API - Studio will set the master channel group format to the project's format to avoid an extra upmix.
    • +
    +

    04/03/16 1.08.00 - Studio API major release (build 73609)

    +

    Features:

    +
      +
    • Studio API - Sample data loading has been optimised. Load time, file access, and memory use have all been substantially improved. A new entry has been added to the per platform thread affinity settings.
    • +
    • Studio API - FMOD_STUDIO_PARAMETER_DESCRIPTION now has the parameter index and default value.
    • +
    • Studio API - Added Studio::System::flushSampleLoading.
    • +
    • Studio API - Support for left edge trimming of timelocked sounds.
    • +
    • Studio API - Support for Start Offset as a percentage of sound length.
    • +
    • Studio API - Added idle resource pool to keep recently used sounds in memory in case they might be re-used. It can be controlled by the idleResourcePoolSize field in FMOD_STUDIO_ADVANCEDSETTINGS. See the Studio Banks Programmer Topic for more information.
    • +
    • Core API - Increased performance of System::createSound and System::createStream, since they no longer block against System::update.
    • +
    • Core API - Added filebuffersize to FMOD_CREATESOUNDEXINFO for customizable file buffering.
    • +
    • Core API - Added System::getFileUsage to query file loading information.
    • +
    • Core API - Custom DSP effects now always receive a buffer length that is equal to the mix block size. The input and output buffers will always be 16-byte aligned. Custom DSP sounds still have be able to generate signal less than a mix block.
    • +
    • Core API - Added getclock callback to FMOD_DSP_STATE_SYSTEMCALLBACKS to get the clock, offset and length for a custom DSP.
    • +
    • Core API - Added support for multiple plugins within one plugin file. See FMOD_PLUGINLIST, System::getNumNestedPlugins, System::getNestedPlugin, and the DSP Plugin API Programmer Topic for more information.
    • +
    • Core API - Added support for object based panning with two backend providers, Dolby Atmos (FMOD_OUTPUTTYPE_ATMOS) and Playstation VR (FMOD_OUTPUTTYPE_AUDIO3D).
    • +
    • Core API - Added 3D object panner DSP (FMOD_DSP_TYPE_OBJECTPAN) to be used with new object pan enabled outputs.
    • +
    • Core API - Extended output mode plugin API (FMOD_OUTPUT_DESCRIPTION) to allow custom object panner backends.
    • +
    • Core API - Win - Reduced WASAPI latency by 40ms and improved mixer thread regularity.
    • +
    • FSBank - AT9 Band Extension is now enabled by default for supported bit-rates.
    • +
    • FSBank - Added Mac versions of the FSBank tool and FSBankLib API. Included in the Mac and iOS API packages.
    • +
    • Profiler - Added Mac version of the Profiler tool. Included in the Mac and iOS API packages.
    • +
    • Unity 2 - Added ability to create new studio events from within the Unity editor.
    • +
    • Unity 2 - Improved event selection UI on emitter component and when using EventRef attribute.
    • +
    • Unity 2 - Added support for default parameter values in emitter component.
    • +
    +

    Notes:

    +
      +
    • Studio API - Incremented bank version, requires runtime 1.08.00 or later.
    • +
    • Studio API - Latest runtime supports loading old bank versions from 1.03.00.
    • +
    • Studio API - New example 'object_pan' that demonstrates object based panning.
    • +
    • Studio API - Studio::EventDescription::getSampleLoadingState and Bank::getSampleLoadingState now return FMOD_STUDIO_LOADING_STATE_ERROR if sample data failed to load (e.g. due to a corrupt file).
    • +
    • Studio API - Removed Studio::CueInstance, Studio::EventInstance::getCue, Studio::EventInstance::getCueCount and Studio::EventInstance::getCueByIndex. Instead use new functions Studio::EventDescription::hasCue and Studio::EventInstance::triggerCue.
    • +
    • Studio API - Deprecated Studio::EventInstance::getParameter and Studio::EventInstance::getParameterByIndex. Instead use Studio::EventInstance::getParameterValue, Studio::EventInstance::setParameterValue, Studio::EventInstance::getParameterValueByIndex, and Studio::EventInstance::setParameterValueByIndex.
    • +
    • Studio API - Increased stack size for Studio threads to 64K.
    • +
    • Studio API - Played events will stay in the FMOD_STUDIO_PLAYBACK_STARTING state until their sample data has loaded. This avoids selected sounds in the event playing late if the sample data has not been preloaded.
    • +
    • Core API - System::getChannelsPlaying now returns the number of real and total channels playing. System::getChannelsReal has been removed.
    • +
    • FSBank - AT9 compression now requires AT9 library 1.7.1 (DLL version 2.8.0.5) or later. Compression in 32bit versions of FSBank is no longer supported in line with Sony's removal of 32bit compression libraries.
    • +
    +

    03/03/16 1.07.08 - Studio API patch release (build 73591)

    +

    Features:

    +
      +
    • Unity 2 - Importing banks has been speed up dramatically.
    • +
    +

    Fixes:

    +
      +
    • Studio API - Fixed Studio::EventInstance::setProperty not restoring the default setting for FMOD_STUDIO_EVENT_PROPERTY_MINIMUM_DISTANCE and FMOD_STUDIO_EVENT_PROPERTY_MAXIMUM_DISTANCE when a value of -1 is specified.
    • +
    • Studio API - Fixed case of mono sounds panning hard left when both mono and stereo 2D sounds are placed on the same event track, introduced in 1.07.04.
    • +
    • Core API - Fixed some net streams returning 'invalid parameter' introduced in 1.07.06.
    • +
    • Core API - Fixed potential crash if calling Sound::release soon after System::createSound with FMOD_NONBLOCKING and async IO callbacks.
    • +
    • Core API - Winstore/UWP - Fixed small memory leak on system shutdown.
    • +
    • Core API - Winstore/UWP - Fixed occasional crash when closing a socket with a pending asynchronous read.
    • +
    • Core API - Xbox One - Fixed potential hang waiting on XMA Sound::release if using async IO callbacks and a cancel was issued.
    • +
    • Core API - Android - Relaxed overly strict validation of M4A files introduced in 1.07.07.
    • +
    • Core API - Android - Fixed potential JNI_OnLoad failure introduced in 1.07.07.
    • +
    • Core API - Fix crash in convolution reverb if wet level is set to -80db and it has no inputs.
    • +
    • Core API - Fix seeking on stereo FADPCM compressed streams and samples.
    • +
    • Unity 2 - Errors opening log output file are no longer fatal.
    • +
    +

    Notes:

    + +

    16/02/16 1.07.07 - Studio API patch release (build 72710)

    +

    Features:

    +
      +
    • Core API - Win - Improved ASIO output to accept requested sample rate and buffer size instead of using defaults.
    • +
    • UE4 - FMOD Memory allocation now occurs via standard UE4 allocators.
    • +
    • Unity 2 - Added AppleTV support.
    • +
    +

    Fixes:

    +
      +
    • Core API - Fixed System::loadPlugin not unloading the library file in the case of an error.
    • +
    • Core API - Fixed automatic format detection failing for some types when the file size is less than 1KB.
    • +
    • Core API - Fixed FMOD_CREATESOUNDEXINFO::suggestedsoundtype being ignored for FMOD_OPENMEMORY and FMOD_OPENMEMORY_POINT.
    • +
    • Core API - WinStore/UWP - Fixed occasional deadlock when removing the current output device.
    • +
    • Core API - Win - Fixed potential crash if switching output mode to ASIO after System::init.
    • +
    • Core API - Android - Fixed crash if MediaCodec processes a file that isn't an M4A file.
    • +
    • Core API - Android - Fixed Marshmallow devices being unable to load M4A files.
    • +
    • Unity 2 - Remove broken inspector code for ParamRef.
    • +
    • Unity 2 - Fix PS Vita.
    • +
    • Unity 2 - Small event reference UI rendering fixes.
    • +
    • Unity 2 - Fix unnecessary copying of files that haven't been modified.
    • +
    • Unity 2 - Fix issues with copying of files that have only been partially written by the Studio tool.
    • +
    • Unity 2 - Work around IL2CPP issues introduced in Unity 5.3.2p2.
    • +
    • Legacy Unity - Work around IL2CPP issues introduced in Unity 5.3.2p2.
    • +
    • Unity 2 - Xbox One - Fix runtime errors when using Mono AOT compilation.
    • +
    +

    Notes:

    +
      +
    • Unity 2 - Unity 5.3.2p1 is not supported for iOS.
    • +
    • Legacy Unity - Unity 5.3.2p1 is not supported for iOS.
    • +
    +

    27/01/16 1.07.06 - Studio API patch release (build 71893)

    +

    Features:

    +
      +
    • +

      Studio API - Improved CPU and IO performance when capturing API commands via Studio profiler.

      +
    • +
    • +

      Core API - Android - Lollipop devices may now select 7.1 with AudioTrack output mode. Older devices will gracefully fall back to stereo.

      +
    • +
    • Unity 2 - Emitter gizmos are now pickable in the scene view.
    • +
    • Unity 2 - Event Browser layout changed to work in narrow windows. Note the Event Browser windows will need to be closed and re-opened for new minimum bounds to take effect.
    • +
    • Unity 2 - Added bitcode support for iOS.
    • +
    • UE4 - Added support for programmer sounds. See the new UE4 Programmer Sound page for more information.
    • +
    +

    Fixes:

    +
      +
    • Core API - Fixed bug if streams start virtual, they may not come back as audible. Introduced in 1.07.00
    • +
    • Core API - Update URL in Netstream example.
    • +
    • Core API - Fixed net streams not working when server delivers shoutcast with chunked HTTP data.
    • +
    • Core API - Fixed memory leak when a network connection fails.
    • +
    • Core API - Android - Devices that don't support 5.1 output will now gracefully fallback to stereo.
    • +
    • Core API - WinStore / UWP - Fixed WASAPI output so it return the correct 'no drivers' error when none are detected.
    • +
    • Core API - WinStore / UWP - Fixed WASAPI output swapped sides and rears in 7.1.
    • +
    • Core API - Fix C# wrapper of ChannelGroup.addGroup missing arguments.
    • +
    • Core API - Fix crash when using chorus effect on a channel group with channel count greater than the system channel count.
    • +
    • Core API - PS4 - Fix validation of thread affinity settings.
    • +
    • Core API - iOS - Fixed compatibility issue introduced in 1.07.02 for old devices running iOS 6.X.
    • +
    • Unity 2 - Fixed UI when EventRef attribute is used on an array of strings.
    • +
    • Unity 2 - Work around DLL loading issues on some standalone Windows builds.
    • +
    • Unity 2 - Fix DLL loading issues for play-in-editor when platform is iOS.
    • +
    • Unity 2 - Fix RuntimeManager being recreated during shutdown and leaking FMOD native instances.
    • +
    • Unity 2 - Fix issue when using RuntimeManager.LowLevelSystem and RuntimeManager.StudioSystem before RuntimeManager has initialized.
    • +
    • Unity 2 - Increase channels for Play-In-Editor.
    • +
    • Unity 2 - Fix play-in-editor not setting the speaker mode correctly.
    • +
    • Unity 2 - PS4 - Fix script compile errors.
    • +
    +

    Notes:

    +
      +
    • Xbox One - Now built with November 2015 XDK.
    • +
    • iOS - Now built with iOS SDK 9.2 and tvOS SDK 9.1 (Xcode 7.2).
    • +
    • UE4 - Updated Oculus plugin for 1.0.1.
    • +
    +

    07/01/15 1.07.05 - Studio API patch release (build 71238)

    +

    Features:

    +
      +
    • Unity 2 - When using the file browser in the settings editor to set the Studio source paths the result will be set relative to the Unity project if it is a sub-directory.
    • +
    • Unity 2 - Added Parameter Trigger component.
    • +
    +

    Fixes:

    +
      +
    • Core API - UWP - Fixed FMOD_SYSTEM_CALLBACK_DEVICELISTCHANGED not firing when the default output device changes.
    • +
    • Core API - PS3 - Fix rare crash with reverb.
    • +
    • Core API - PS3 - Fix static and audio dropouts if speaker mode is forced to stereo (normally it is 7.1).
    • +
    +

    Notes:

    +
      +
    • iOS - Reduced binary size.
    • +
    • Android - Added calling convention to public API to allow usage with hard float ABI.
    • +
    +

    11/12/15 1.07.04 - Studio API patch release (build 70728)

    +

    Features:

    +
      +
    • Core API - Better support for sounds with channel/speaker masks, ie a 1 channel sound specified as LFE, or a quad sound specified as LRCS instead of 2 front 2 back for example.
    • +
    • Unity 2 - Added optional debug overlay.
    • +
    • Unity 2 - Added migration steps for data in custom components.
    • +
    • Unity 2 - Added support for Unity 4.6.
    • +
    • Unity 2 - Added support for Android split binary.
    • +
    • Unity Legacy - Added support for Android split binary.
    • +
    +

    Fixes:

    +
      +
    • Studio API - Fixed blocking bank loads stalling for longer than necessary when other threads are constantly issuing new Studio commands.
    • +
    • Core API - Fixed corrupted playback for big endian PCM FSBs.
    • +
    • Core API - Fixed crash when switching channel count of generator DSPs during playback.
    • +
    • Core API - PS3 - Fix crash reallocating buffers on flange effect.
    • +
    • Core API - Xbox One - Fixed rare stall when playing XMA streams and compressed samples at the same time.
    • +
    • Core API - Fix crash if the Master Channel Group head DSP was set inactive right after initialization.
    • +
    • Core API - Fix Sound::getOpenState () moving from FMOD_OPENSTATE_PLAYING too early on some streaming sounds.
    • +
    • Core API - Fix Sound::Release () freeing memory still in use by the mixer.
    • +
    • Core API - Fix convolution reverb not correctly producing tails on long impulse responses when it has no input.
    • +
    • Unity 2 - Fixed issue with plugins not being loaded correctly.
    • +
    • Unity 2 - Work around DLL loading issues on some standalone Windows builds.
    • +
    • Unity 2 - Fix leaking system objects leading to ERR_MEMORY.
    • +
    • Unity 2 - Updated signature of DSP::setWetDryMix, DSP::getWetDryMix.
    • +
    +

    Notes:

    +
      +
    • Core API - FMOD_DSP_STATE::channelmask is now passed down through the dsp chain so plugin developers can see the original signal channel format even if a sound was upmixed.
    • +
    +

    17/11/15 1.07.03 - Studio API patch release (build 69975)

    +

    Features:

    +
      +
    • Core API - When using System::recordStart the provided FMOD::Sound can now be any channel count, up/down mixing will be performed as necessary.
    • +
    • Core API - Improved performance of convolution reverb effect when wet is 0 or input goes idle.
    • +
    • Core API - PS4 - Added FMOD_THREAD_CORE6 to allow access to the newly unlocked 7th core.
    • +
    • Core API - PS4 - Added FMOD_PS4_GetPadVolume() to retrieve the output volume of the pad speaker as set by the user in the system software.
    • +
    • Core API - Added FMOD_DSP_TYPE_TRANSCEIVER. Send signals from multiple sources to a single 'channel' (out of 32 global 'channels') and receieve from that or any channel from multiple receivers. Great for receiving and broadcasting a submix from multiple 3d locations (amongst other uses).
    • +
    • Unity - FMOD_StudioSystem.GetEvent() can now be used with snapshot paths.
    • +
    • Unity - Ignore OSX resource fork files when importing from FAT32 file systems.
    • +
    • UE4 - Deployment will also copy any plugins listed in a file plugins.txt in the FMODStudio/Binaries/Platform directory. See the Using Plugins page for more information.
    • +
    • UE4 - Console platforms set up thread affinity in FMODPlatformSystemSetup.
    • +
    +

    Fixes:

    +
      +
    • Studio API - Fixed snapshot applied to VCA level not working in game.
    • +
    • Studio API - Fixed profiler session timing when recording a game with a non-standard sample rate.
    • +
    • Studio API - PS4 - Fix linker error in examples.
    • +
    • Core API - Fixed buffer overrun when convolution reverb is set up with mismatched input and output channels.
    • +
    • Core API - Fix crash with invalid .mp3 files.
    • +
    • Core API - Fix Sound::getName () not returning a valid UTF8 string when loading a sound with ID3 tags specifying the title as a latin1 string.
    • +
    • Core API - Fix pops in flange and chorus effects.
    • +
    • Core API - Fix crash when using flange effect on a channel group with channel count greater than the system channel count.
    • +
    • Core API - FLAC - Fix crash when seeking in certain flac files.
    • +
    • Core API - Android - Automatic selection of OpenSL output mode will now be stricter to reduce stuttering on devices that incorrectly report they are low latency.
    • +
    • Core API - PS4 - Fix signal not being routed back to the main output when detaching a channel group from a port.
    • +
    • Core API - Fix FMOD_ADVANCEDSETTINGS::reverb3Dinstance not working.
    • +
    +

    Notes:

    + +

    02/11/15 1.07.02 - Studio API patch release (build 69450)

    +

    Important:

    +
      +
    • AppleTV platform support is now part of the iOS package.
    • +
    +

    Features:

    +
      +
    • Core API - Improved performance of System::getChannelsPlaying.
    • +
    • Core API - Added System::getChannelsReal to get the number of non-virtual playing channels.
    • +
    +

    Fixes:

    +
      +
    • Studio API - Fixed internal error during playback caused by inaccuracies in quantization calculation when timeline position is greater than 5 minutes.
    • +
    • Core API - Fix mixer not running if mixer sample rate is lower than output sample rate.
    • +
    • Core API - Fix Sound::getOpenState returning FMOD_OPENSTATE_READY when a sounded ended, when it should have returned FMOD_OPENSTATE_PLAYING for a bit longer, which meant Sound::release could stall.
    • +
    • Core API - iOS - Fixed output being mono on some devices, minimum detected hardware channel count is now 2 to ensure stereo.
    • +
    +

    Notes:

    +
      +
    • iOS - Now built with iOS SDK 9.1 and tvOS SDK 9.0 (Xcode 7.1).
    • +
    • Mac - Now built with SDK 10.11 (Xcode 7.1).
    • +
    +

    27/10/15 1.07.01 - Studio API patch release (build 69235)

    +

    Features:

    +
      +
    • Studio API - Added support for multiple parameter conditions.
    • +
    • Studio API - Added Studio::EventDescription::getSoundSize.
    • +
    • UE4 - Added validation help menu option to diagnose common issues.
    • +
    +

    Fixes:

    +
      +
    • Studio API - Fixed auto-pitch, cutoff and looping not live updating properly.
    • +
    • Core API - Fixed potential crash on ARM platforms when seeking Vorbis compressed FSBs.
    • +
    • Core API - Fix ChannelGroup::setReverbProperties from returning FMOD_ERR_REVERB_CHANNELGROUP if a child channel had a reverb connection previously.
    • +
    • Core API - Fixed FMOD_CREATESOUNDEXINFO::suggestedsoundtype being ignored if a custom codec of higher priority has been registered.
    • +
    • Core API - Fixed System::getRecordNumDrivers incorrectly reporting 0 if called within 1 second of application start on some platforms.
    • +
    • Core API - Fixed stereo AIFF files producing static.
    • +
    • Core API - Xbox One - Fixed rare crash for stereo XMA streams.
    • +
    • Core API - iOS - Fixed MP3 decoding being performed by FMOD cross-platform decoder instead of native AudioQueue.
    • +
    • Core API - Fix mp3 crash seeking, introduced in 1.07.00 if using certain types of MP3 file in FMOD_CREATECOMPRESSEDSAMPLE mode.
    • +
    • Unity - Change Android to read banks straight from APK
    • +
    • Unity - Will automatically append a "64" suffix to plugins if required.
    • +
    • Unity - Fix OSX bundles having incorrect settings
    • +
    • Unity - Fix compatibility with Unity 5.2.2
    • +
    • Unity - Fix crashes when creating a standalone OSX build.
    • +
    • UE4 - Fix for audio component direction not being set into FMOD.
    • +
    • UE4 - Fixed IOS deployment error "libfmod does not exist"
    • +
    +

    Notes:

    +
      +
    • Studio API - The FMOD_STUDIO_EVENT_CALLBACK_PLUGIN_CREATED and FMOD_STUDIO_EVENT_CALLBACK_PLUGIN_DESTROYED callbacks now fire from nested events, for both plugin effects and plugin sounds.
    • +
    • Studio API - For the FMOD_STUDIO_PLUGIN_INSTANCE_PROPERTIES callback argument, the 'name' field will contain just the user defined name of the plugin sound if one has been set. Otherwise it will be empty. You can use the 'dsp' field to determine the plugin type.
    • +
    • Studio API - Programmer sounds with no name will have an empty string for FMOD_STUDIO_PROGRAMMER_SOUND_PROPERTIES.name, previously it was an arbitrary hex sequence.
    • +
    • Core API - Plugin developers - FMOD_DSP_SYSTEM_GETSPEAKERMODE added to FMOD_DSP_STATE_SYSTEMCALLBACKS. Plugin SDK version updated to 1.07 meaning plugins created from this point onwards wont work with older versions of FMOD.
    • +
    • Android - Replaced all Eclipse examples with Visual Studio using NVIDIA Nsight Tegra integration.
    • +
    • PS4 - Now built with SDK 3.008.041
    • +
    • PS3 - Now built with SDK 475.001.
    • +
    +

    05/10/15 1.07.00 - Studio API minor release (build 68517)

    +

    Important:

    +
      +
    • Studio is now a 64-bit application. All plugin libraries must be built for 64-bit architecture to be compatible with the 64-bit version of the tool.
    • +
    • Added Universal Windows Platform (UWP) support.
    • +
    • Added AppleTV platform support. Contact support@fmod.org for beta access.
    • +
    +

    Features:

    +
      +
    • Studio API - Support for bus polyphony.
    • +
    • Studio API - Added FMOD_STUDIO_EVENT_PROPERTY_MINIMUM_DISTANCE and FMOD_STUDIO_EVENT_PROPERTY_MAXIMUM_DISTANCE to override the minimum and maximum panner distance for an instance.
    • +
    • Studio API - Added FMOD_STUDIO_INIT_DEFERRED_CALLBACKS to defer event callbacks to the main thread. See Studio::EventInstance::setCallback for more information.
    • +
    • Core API - Added FMOD_DSP_TYPE_CHANNELMIX effect. Allows user to control gain levels for up to 32 input channel signals, and pipe the output to a range of speaker formats i.e. repeating mono, stereo, quad, 5.1, 7.1 or only LFE out.
    • +
    • Core API - Improved CPU performance when using metering or profiling.
    • +
    • Core API - Added support for loading multi-channel FSBs with the FMOD_CREATECOMPRESSEDSAMPLE flag.
    • +
    • Core API - Improved record driver enumeration, list is now persistent, removed devices will remain to ensure record IDs stay valid. See record_enumeration example for new functionality.
    • +
    • Core API - Added full record device add/removal detection for Windows, Mac, Xbox 360, Xbox One, PS3 and PS4.
    • +
    • Core API - Reduced recording latency on Windows, XboxOne and PS4.
    • +
    • Core API - Mac - Added support for recording from multiple microphones at the same time.
    • +
    • Core API - Win - Improved CPU performance for FSB Vorbis decoding. See Performance Reference section of the documentation for updated benchmark results.
    • +
    • Core API - iOS - Added support for bitcode.
    • +
    +

    Fixes:

    +
      +
    • Studio API - Fixed the scatterer module's random distance calculation to ensure it is within the limit set in Studio. In previous versions the random distance may have exceeded the max limit. This change may affect the loudness of sounds with scatterer modules compared to 1.06.xx releases.
    • +
    • Core API - Fix rare crash when releasing a streamed sound.
    • +
    • Core API - Fix output plugins with GUIDs of zero stopping setDriver working.
    • +
    • Core API - PS3 - Fixed send/returns not respecting volume changes or rarely failing with an error when setting return IDs.
    • +
    • Core API - PS4 - Rewrote output to use sceAudioOutOutputs instead of multiple sceAudioOutOutput calls on a single thread.
    • +
    • Core API - Win - Fixed the audible output driver from resetting when an unrelated device is removed or disabled.
    • +
    • Core API - Xbox One - Fixed the first couple of samples of decoded XMA being lost due to SHAPE SRC.
    • +
    +

    Notes:

    +
      +
    • Studio API - Incremented bank version, requires runtime 1.07.00 or later.
    • +
    • Studio API - Latest runtime supports loading old bank versions from 1.03.00.
    • +
    • Studio API - Improved compatibility for plugin effects. Adding extra DSP parameters to an effect no longer breaks bank version compatibility.
    • +
    • Studio API - Studio::Bank::getEventCount and Studio::Bank::getEventList only return events directly added to the bank, not implicit events that are included in the bank due to event instrument references.
    • +
    • Studio API - The asynchronous command buffer for the Studio API will now grow as necessary, avoiding stalls that could occur if it was too small. The commandQueueSize field in FMOD_STUDIO_ADVANCEDSETTINGS now specifies the initial size of the buffer.
    • +
    • Studio API - Studio now enables FMOD_INIT_VOL0_BECOMES_VIRTUAL by default.
    • +
    • Studio API - WinStore - Fixed inconsistent naming of X64 libraries.
    • +
    • Core API - Increased FMOD_MAX_LISTENERS from 5 to 8.
    • +
    • Core API - System::getCPUUsage update time now includes the metering and profiling part of the update.
    • +
    • Core API - Removed support for FSB Vorbis files built using FMOD Ex 4.42 or earlier.
    • +
    • Core API - PS4 - Changed default mix buffer size to 512 samples to reduce CPU cost. Previous setting of 256 can be set using System::setDSPBufferSize.
    • +
    • Core API - PS4 - The size of each pre-allocated AT9 instance has increased by 8kB.
    • +
    • Core API - PS4 - Prebuilt static libraries are no longer provided, only dynamic libraries.
    • +
    • Core API - WinStore - Fixed inconsistent naming of X64 libraries.
    • +
    +

    05/10/15 1.06.11 - Studio API patch release (build 68487)

    +

    Features:

    +
      +
    • Win - Reduced dll and exe sizes.
    • +
    +

    Fixes:

    +
      +
    • Studio API - Fixed input buses not being released when there are no longer any event instances routed into the bus.
    • +
    • Studio API - Fixed API capture recording the initial VCA level as 0.
    • +
    • Core API - Fix rare crash when changing the master channel group head DSP when the software format and system output don't match.
    • +
    • Core API - Fix Channel::AddDSP () and ChannelGroup::AddDSP () not correctly moving a DSP if it's already a member.
    • +
    • Core API - Fix for noise being produced when panning a surround input when the system format doesn't match the panner input format.
    • +
    • Unity - FMOD RNG seed set at initialization time.
    • +
    • Unity - Can now properly cancel the copy step of the import process.
    • +
    • Unity - Updated documentation links in menu.
    • +
    +

    Notes:

    +
      +
    • iOS - Now built with SDK 9.0 (Xcode 7.0).
    • +
    • Mac - Now built with SDK 10.11 (Xcode 7.0).
    • +
    +

    15/09/15 1.06.10 - Studio API patch release (build 67958)

    +

    Features:

    +
      +
    • Core API - Add Sound::seekData support to HTTP streams.
    • +
    • UE4 - Added blueprint functions for loading and unloading sample data.
    • +
    +

    Fixes:

    +
      +
    • Core API - Fix small reverb pop on sounds that had Channel::setPosition called on then and were muted via a parent channelgroup.
    • +
    • Core API - Fix https netstream redirects not working.
    • +
    • Core API - Fix user DSP read callback firing with no data if Channel::setPaused (false) is used after a System::playSound.
    • +
    • Studio API - Fixed Trigger Delay not being applied to sounds on parameters that trigger immediately when an event starts.
    • +
    +

    Notes:

    +
      +
    • Xbox One - Now built with August 2015 XDK.
    • +
    +

    01/09/15 1.06.09 - Studio API patch release (build 67431)

    +

    Features:

    +
      +
    • Studio API - Additional logging when banks have been exported with out of date plugin effects.
    • +
    +

    Fixes:

    +
      +
    • Core API - Fix automatic device changing support if a user called System::update from their own thread.
    • +
    • Core API - Fix crash when a channel group cannot be attached to port.
    • +
    • Core API - Fixed incorrect loop length being set for ADPCM files.
    • +
    • Core API - Win64 - Enable automatic device changing support.
    • +
    • Core API - iOS - Fixed error creating the file thread on iOS 9.0.
    • +
    • Core API - Fix distance filtering not resetting its parameters properly for channels.
    • +
    • Core API - MIDI support - Fix note keyoff when evelope is in decay phase causing note to finish early.
    • +
    • Studio API - Fix crash that could occur when auditioning an event in Studio while changing the path to waveforms.
    • +
    +

    Notes:

    +
      +
    • UE4 - Updated oculus rift plugin to version 0.11
    • +
    +

    12/08/15 1.06.08 - Studio API patch release (build 66772)

    +

    Features:

    +
      +
    • UE4 - Added FMOD init settings.
    • +
    • UE4 - Added preliminary support for 4.9 engine preview build.
    • +
    • Core API - Add Channel::setPosition support to HTTP streams.
    • +
    +

    Fixes:

    +
      +
    • Core API - Fixed System::getDefaultMixMatrix crashing if passed FMOD_SPEAKERMODE_RAW:: Now returns FMOD_ERR_INVALID_PARAM .
    • +
    • Core API - Xbox One - Fixed crash if all SHAPE contexts are consumed.
    • +
    • Core API - Xbox One - Fixed XMA loops not being seamless.
    • +
    • Studio API - Fixed potential crash when disconnecting from live update while recording a profiling session.
    • +
    • Studio API - WiiU - Fixed hang on shutdown when exiting game from home menu.
    • +
    • Core API - Fix for inaccurate metering levels when the calculation spanned multiple mix blocks.
    • +
    • Core API - Fixed System::getRecordPosition race condition that could cause the returned value to be out of bounds.
    • +
    • Unity - Fixed missing functionality from C# wrapper for beat callbacks and metering.
    • +
    • Unity - Fix leaking native system objects in editor.
    • +
    • UE4 - Fixed multiple listeners.
    • +
    • FSBank - Fixed crash encoding FADPCM format in 64bit version of tool.
    • +
    +

    Notes:

    + +

    22/07/15 1.06.07 - Studio API patch release (build 66161)

    +

    Fixes:

    +
      +
    • Core API - Win - Fix audio glitches at initialization time when using the WASAPI output mode on Windows 10.
    • +
    • Core API - Fix UTF8 strings in MP3 ID3V2 tags not being null terminated properly leading to possible string overflow crash.
    • +
    • Core API - PS4 - Fixed issue with non-1024 sample aligned loop-points and AT9 compressed samples.
    • +
    • Core API - Fixed memory leak when releasing connections that have a user allocated mix matrix.
    • +
    • Core API - Added pre-wet and post-wet arguments to WetDryMix in C# wrapper.
    • +
    • Core API - Fixed crash with FADPCM streams.
    • +
    • Core API - Fixed another potential crash in PitchShifter DSP if changing channel count while running.
    • +
    • Core API - Win - Fix issues caused by WASAPI allocating the output buffer at the mixer's sample rate instead of the device's sample rate.
    • +
    • Studio API - XboxOne - Fix setting the thread affinity of the studio loading thread.
    • +
    • Studio API - Fixed case of nested events on parameters being stopped while still active. Introduced in 1.06.04.
    • +
    +

    Notes:

    +
      +
    • Studio API - Incremented bank version, requires runtime 1.06.06 or later.
    • +
    • Studio API - Latest runtime supports loading old bank versions from 1.03.00.
    • +
    • Core API - XboxOne - Thread affinity can now be set as a mask of allowed cores.
    • +
    +

    08/07/15 1.06.06 - Studio API patch release (build 65638)

    +

    Features:

    + +

    Fixes:

    +
      +
    • Studio API - Fixed potential invalid memory access when a bank is unloaded while create instance commands are queued.
    • +
    • Studio API - Removed one frame delay between setting a parameter and having conditional timeline transitions occur.
    • +
    • Studio API - Studio gracefully handles the case of a programmer sound being returned in a streaming not-ready state when the instrument is being used with timelocked seeks.
    • +
    • Core API - Fixed rare crash when streams go virtual.
    • +
    • Core API - Fixed 3EQ DSP not waiting an extra mix block before going idle, possibly cutting off a tail.
    • +
    • Core API - Fixed potential crash in PitchShifter DSP if changing channel count or FFT size while running.
    • +
    • Core API - Fixed rare volume pop when ramping with fade points as a channel goes emulated.
    • +
    • Core API - Linux - Fixed record position not advancing with ALSA output mode.
    • +
    • Core API - Fix race condition when setting the impulse response on an active convolution reverb DSP.
    • +
    • Unity - Fix compatibility with Unity 5.1
    • +
    +

    24/06/15 1.06.05 - Studio API patch release (build 65161)

    +

    Features:

    +
      +
    • Studio API - Added FMOD_STUDIO_LOAD_BANK_DECOMPRESS_SAMPLES flag to force bank sample data to decompress into memory, saving CPU on low end platforms.
    • +
    • Studio API - Improved responsiveness when reducing steal oldest polyphony over live update.
    • +
    • Studio API - Studio profiling now includes nested instance information.
    • +
    • UE4 - Exposed beat and marker callbacks as Blueprint events.
    • +
    +

    Fixes:

    +
      +
    • Studio API - Fixed Scatterer sounds having incorrect volume when min and max scatter distances are equal. Introduced in 1.06.00.
    • +
    • Studio API - Fixed FMOD_STUDIO_TIMELINE_BEAT_PROPERTIES position to return the beat position, rather than the tempo marker position.
    • +
    • Studio API - Fix deadlock in studio when removing an output device that runs at a different sample rate to the system.
    • +
    • Studio API - Fix deadlock in studio when removing certain USB headsets.
    • +
    • Core API - Fixed rare case of DSP mixer not responding momentarily if output mode was switched during playback.
    • +
    • Core API - Fix declaration of DSP.getMeteringInfo in C# wrapper.
    • +
    +

    Notes:

    +
      +
    • UE4 - Now built against Unreal 4.8
    • +
    +

    09/06/15 1.06.04 - Studio API patch release

    +

    Features:

    + +

    Fixes:

    +
      +
    • Core API - Fixed MIDI playback not correctly handling CC1 (mod wheel).
    • +
    • Studio API - Fixed livelock when scheduling nested events in a playlist that have 0 duration.
    • +
    • Studio API - Fixed events staying active when they have active but idle nested events on parameters. Events now finish once their nested parameter events go idle.
    • +
    • Studio API - Fixed Scatterer sounds not being spatialized properly. Introduced in 1.06.00.
    • +
    • FSBank - Fix bug that prevented selection of FMOD ADPCM in the tool.
    • +
    • Core API - Fix set3DPanLevel not respecting reverb mix when pan level was approaching 0.
    • +
    • Core API - Fix 2d channels not having the wet mix scaled for reverb when parent ChannelGroup volume/mute functions were called.
    • +
    • Unity - Remove warnings about banks already loaded
    • +
    • Unity - Fix Unity Editor crashing when using FMOD_LIVEUPDATE and FMOD_DEBUG pre-processor commands simultaneously.
    • +
    +

    Notes:

    +
      +
    • Studio API - Incremented bank version, requires runtime 1.06.00 or later.
    • +
    • Studio API - Latest runtime supports loading old bank versions from 1.03.00.
    • +
    • Studio API - Added a warning for events that haven't finished because they are waiting for a DSP effect to go idle.
    • +
    • Core API - WiiU - To comply with LotCheck requirements only the logging version of FMOD will link with networking APIs
    • +
    • Xbox One - Now built with May 2015 QFE 1 XDK.
    • +
    • WiiU - Now built with SDK 2.12.13.
    • +
    +

    22/05/15 1.06.03 - Studio API patch release

    +

    Features:

    +
      +
    • Studio API - Reduced memory overhead of bank metadata.
    • +
    +

    Fixes:

    +
      +
    • Studio API - Fixed steal oldest polyphony behaviour using instance creation instead of instance start time.
    • +
    • Studio API - Fixed playlist instrument cutoff not applying a volume ramp down which could cause pops when using polyphony.
    • +
    • Core API - Fixed invalid memory access when loading an incorrectly formatted or truncated IMA ADPCM wav file using FMOD_OPENMEMORY_POINT and FMOD_CREATECOMPRESSEDSAMPLE.
    • +
    • Core API - Fix rare crash due to race condition when calling Sound::Release () just after the sound has been loaded using NON_BLOCKING.
    • +
    • Core API - PS3 - Fix deadlock in streaming when using SPU Threads.
    • +
    • Core API - Attempting to attach the Master ChannelGroup to a port will now return FMOD_ERR_INVALID_PARAM.
    • +
    • Core API - PS4 - Fix issues with recording at rates other than the driver default.
    • +
    • Core API - Fix crash in DSPFader when voice goes virtual with DSP effect added at a position lower than the fader (ie post fader), and the effect is freed.
    • +
    • UE4 Integration - Fixed incorrect listener orientation.
    • +
    +

    Notes:

    +
      +
    • Studio API - Changed envelope follower DSP sidechain parameter to ignore invalid values.
    • +
    • Xbox One - Now built with April 2015 XDK.
    • +
    • 7.1 to 5.1 downmix now lowers the volumes of the back speakers' contribution to the surround speakers by 1.5db to lessen volume bulge in the middle.
    • +
    +

    06/05/15 1.06.02 - Studio API patch release

    +

    Features:

    + +

    Fixes:

    +
      +
    • Studio API - Fixed transition timeline modules not crossfading their volume properly when overlapping the lead out region.
    • +
    • Studio API - Fixed C# wrapper not linking against 64bit dll when WIN64 is defined.
    • +
    • Studio API - Fixed events with sidechains never naturally stopping.
    • +
    • Studio API - Fixed runtime crash caused by a compiler bug for customers compiling from source using VS2015 CTP.
    • +
    • Core API - WiiU - Fixed incorrect pitch for DRC if System is running a rate other than 48KHz or 32KHz.
    • +
    • Core API - PS4 - Fix small memory leak when closing output ports.
    • +
    • Core API - Fixed documentation regarding FMOD_DSP_COMPRESSOR_USESIDECHAIN and FMOD_DSP_ENVELOPEFOLLOWER_USESIDECHAIN.
    • +
    • +

      Core API - WinStore - Fix System::Init () freezing when called from the UI thread.

      +
    • +
    • +

      UE4 Integration - Fixed bad editor performance when selecting audio components.

      +
    • +
    • +

      UE4 Integration - Fixed several Android deployment issues.

      +
    • +
    • +

      Unity Integration - Fix compilation issues on iOS when using IL2CPP.

      +
    • +
    • Unity Integration - Logging libs for OSX are now included. Defining FMOD_DEBUG will now route FMOD internal logging to the Unity console in the OSX editor and standalone OSX builds.
    • +
    • Unity Integration - Make members of the REVERB_PROPERTIES structure public.
    • +
    • Unity Integration - Fix compile error on XBox One when defining FMOD_DEBUG.
    • +
    +

    Notes:

    +
      +
    • UE4 Integration - Merged documentation with main API documentation.
    • +
    +

    17/04/15 1.06.01 - Studio API patch release

    +

    Features:

    + +

    Fixes:

    +
      +
    • Core API - Fixed Channel userdata not being reset to 0 each playSound.
    • +
    • Core API - Fixed the C# wrapper for DSP.AddInput and DSP.disconnectFrom.
    • +
    • Core API - PS4 - Fixed playback issue with AT9 compressed samples that have a non-zero loop start point.
    • +
    • Core API - Fix rare issues with generator DSPs or compressed channels getting stuck looping the same fragment of audio.
    • +
    • +

      Core API - PS3 - Fix rare crash if sound stops on a channelgroup with a matrix set in it.

      +
    • +
    • +

      Unity Integration - Fix banks not being loaded on standalone OSX builds.

      +
    • +
    • Unity Integration - Logging libs for windows are now included. Defining FMOD_DEBUG will now route FMOD internal logging to the Unity console in the Windows editor and standalone Windows builds.
    • +
    +

    Notes:

    +
      +
    • PS4 - Now built with SDK 2.508.051.
    • +
    +

    10/04/15 1.06.00 - Studio API minor release

    +

    Important:

    +
      +
    • Studio API - Scatterer sounds now steal the oldest spawned sound if the polyphony limit has been reached when spawning a new sound.
    • +
    +

    Features:

    +
      +
    • Added new compression format FADPCM as a higher quality, lower CPU cost drop in replacement for standard IMA ADPCM. This custom developed format is our new recommendation for mobile, PS Vita and Wii U delivered exclusively via FSB.
    • +
    • Core API - Improved CPU performance of convolution reverb by 30%
    • +
    • Core API - Android - Improved latency by automatically resampling to the native rate to enable the fast mixer.
    • +
    • Core API - PS Vita - Removed requirement to use 48KHz mixing, default is now 24KHz for better performance.
    • +
    • Core API - Xbox One - Optimized performance for looping compressed XMA.
    • +
    • Core API - Xbox One - Added support for greater than stereo XMA streams.
    • +
    • Core API - Xbox One - Reduced output latency by 20ms.
    • +
    • Studio API - Significantly reduced memory usage.
    • +
    • Studio API - Added Studio bank loading thread.
    • +
    • Studio API - Added Studio::Bank::getUserData and Studio::Bank::setUserData.
    • +
    • Studio API - Added FMOD_STUDIO_SYSTEM_CALLBACK_BANK_UNLOAD callback.
    • +
    • Studio API - Support for transition timeline lead-in and lead-out.
    • +
    • Studio API - Added support for setting Studio async update period via FMOD_STUDIO_ADVANCEDSETTINGS.
    • +
    • Core API - PS4 - Added support for High Quality Recording API by default.
    • +
    +

    Fixes:

    +
      +
    • Studio API - Fixed parameter modulation being unable to go below the value set from the public API.
    • +
    • Studio API - Fixed effect bypass setting not being saved to banks.
    • +
    +

    Notes:

    + +

    02/04/15 1.05.15 - Studio API patch release

    +

    Fixes:

    +
      +
    • Core API - Win - Fixed occasional deadlock when removing audio devices.
    • +
    • Core API - Fixed stream crackling if initialseekposition was used immediately followed by Channel::setPosition with a close position value.
    • +
    • Core API - PS3 - Fixed six or eight channels vorbis streams crashing the SPU.
    • +
    • Core API - Xbox One - Fixed rare hang when decoding small XMA compressed audio.
    • +
    • Core API - Fixed DSP::getInfo not returning configwidth and confighheight information for VST plugins.
    • +
    • Core API - Fixed rare crash calling DSP::reset on the fader DSP, after ChannelGroup::setPan/setMixLevelsOutput/setMixMatrix. This could occur when a Studio event is started or stopped.
    • +
    • Core API - PS4 - Fixed issue with non-1024 sample aligned loop-points and AT9 compressed samples.
    • +
    • Core API - Fixed DSP effect being un-removable with FMOD_ERR_DSP_INUSE after being added to a channel and the channel stops (becoming invalid).
    • +
    +

    Notes:

    +
      +
    • PS3 - Now built with SDK 470.001.
    • +
    +

    16/03/15 1.05.14 - Studio API patch release

    +

    Fixes:

    +
      +
    • Core API - Fixed some cases where channel group audibility was not refreshed when fade points are active. This could happen when a Studio event instance is paused and unpaused.
    • +
    • Core API - PS3 - Fixed FMOD_PS3_INITFLAGS overlapping FMOD_INITFLAGS causing certain FMOD_INITFLAGS to affect PS3 specific bit-stream encoding options.
    • +
    • Core API - PS3 - Fixed a rare hang when releasing a DSP that exposes a FMOD_DSP_PARAMETER_OVERALLGAIN parameter.
    • +
    • Core API - PS3 - Fixed opening URL failing with network streams.
    • +
    • Core API - Xbox One - Fixed recording API, you can now specify any sample rate to record at. Native rate of 48KHz is still recommended for lowest latency.
    • +
    • Studio API - Fixed virtualized event failing to become real if the number of playing instances drops back below max polyphony.
    • +
    +

    Notes:

    +
      +
    • Core API - PS3 - Deprecated FMOD_PS3_EXTRADRIVERDATA::initflags. Due to a bug it was being ignored. Pass the flags to System::init instead.
    • +
    +

    25/02/15 1.05.13 - Studio API patch release

    +

    Features:

    +
      +
    • Studio API - Studio::System::getBank now accepts bank filenames as input.
    • +
    • Core API - Added 64bit versions of fsbank and fsbankcl tools.
    • +
    +

    Fixes:

    +
      +
    • Studio API - Fixed case of nested event not being destroyed even after it had finished producing sound.
    • +
    • Studio API - Fixed crash when changing output bus on an event when live update is connected.
    • +
    • Studio API - Fixed deadlock when calling Studio commands when mixer is suspended.
    • +
    • Studio API - System::release now ensures release even if flushing pending commands causes an error.
    • +
    • Studio API - The name of the string bank is now added to the string bank.
    • +
    • Studio API - Event instance restart now flushes parameter values before timeline rescheduling occurs. This avoids a potential issue for transitions with parameter conditions, where they may not have used the most recent parameter value.
    • +
    • Core API - Fix unnecessary querying of recording driver capabilities during recording.
    • +
    • Core API - PS4 - Remove AT9 workaround added in 1.05.12. Fix AT9 compressed codecs with finite loop counts.
    • +
    • Core API - PS4 - Removed stalls when an AT9 compressed sample channel is started.
    • +
    • Core API - PS4 - Fix crash in recording.
    • +
    • Core API - Fix multiple listener support not working properly.
    • +
    • Core API - Fix user file crash if using asyncfileread callback, and file open and close happens without any read occuring.
    • +
    • Core API - Fix rare crash with Sound::release if a nonblocking setPosition is in process and it is an FSB sound.
    • +
    • Core API - Fix thread safety issue loading multiple mod/s3m/xm/it files simultaneously.
    • +
    • Core API - Fix rare crash if FMOD_ACCURATETIME was used with .mp3 file followed by mp3 encoded FSB file after a time, both using FMOD_CREATECOMPRESSEDSAMPLE.
    • +
    • Core API - PS3 - Fixed custom DSP that use the plugindata member.
    • +
    +

    Notes:

    +
      +
    • Studio API - Updated programmer_sound example.
    • +
    • Core API - Added plug-in inspector example.
    • +
    • Xbox One - Now built with February 2015 XDK.
    • +
    +

    06/02/15 1.05.12 - Studio API patch release

    +

    Features:

    +
      +
    • Studio API - Improved memory use for events with repeated nested events.
    • +
    +

    Fixes:

    +
      +
    • Studio API - Fixed crash when stopping multiple one-shot events on a bus.
    • +
    • Studio API - Fixed nested event polyphony from cutting off immediately, causing pops.
    • +
    • Core API - Fixed rare crash in mixer if DSP::reset is called on a FMOD_DSP_TYPE_FADER dsp (ie ChannelControl head DSP) after DSP::setPan/setMixLevelsOutput/setMixMatrix.
    • +
    • Core API - Fixed race condition setting resampling speed while resampling is occurring.
    • +
    • Core API - Fixed crash loading mod/s3m/xm/it file using FMOD_NONBLOCKING and FMOD_CREATECOMPRESSEDSAMPLE and then immediately calling SoundI::release
    • +
    • Core API - PS4 - Work around AT9 codec issues that have appeared when using SDK 2.000
    • +
    +

    22/01/15 1.05.11 - Studio API patch release

    +

    Features:

    +
      +
    • Core API - Xbox One - Added access to 7th CPU core.
    • +
    +

    Fixes:

    +
      +
    • Studio API - Fixed crash setting Studio event callback to null as it is being invoked.
    • +
    • Studio API - Fixed crash in hashmap reallocation when running out of memory.
    • +
    • Studio API - Fixed Studio::loadBankCustom from freeing its custom userdata before the close callback for failed banks.
    • +
    • Studio API - If FMOD_OUTTPUTTYPE_WAVWRITER_NRT or NOSOUND_NRT is used as an output mode, Studio runtime will now internally force FMOD_STUDIO_INIT_SYNCHRONOUS_UPDATE to avoid a hang.
    • +
    • Core API - Fix pop noise when 3d sound goes virtual then becomes real again, only if ChannelControl::addDSP was used.
    • +
    +

    Notes:

    + +

    12/01/15 1.05.10 - Studio API patch release

    +

    Features:

    +
      +
    • Core API - Xbox One - Added support for recording from microphones.
    • +
    +

    Fixes:

    +
      +
    • Core API - PS3 - Fix deadlock in streaming sounds when linking against the SPU thread libraries.
    • +
    • Core API - Windows - Fixed crash when initializing a second ASIO system.
    • +
    • Core API - Fix ChannelControl::getDSPIndex not returning an error if the dsp did not belong in the Channel or ChannelGroup
    • +
    • Core API - PS3 - Fix linker error when using libfmod_sputhreads.a
    • +
    • Core API - Fixed AT9 and ACP XMA incorrectly allowing FMOD_OPENMEMORY_POINT and FMOD_CREATESAMPLE.
    • +
    • Core API - Fixed reverb wetlevel from ChannelControl::setReverbProperties being reset after a voice goes virtual then returns as real.
    • +
    • Core API - Fixed removing/adding DSPs in a ChannelControl chain copying setDelay commands incorrectly and making channels pause when they shouldnt
    • +
    • Studio API - Reinstated support for embedded loop points in source sounds, and fixed issue with playback of timelocked sounds.
    • +
    +

    12/12/14 1.05.09 - Studio API patch release

    +

    Features:

    + +

    Fixes:

    +
      +
    • Studio API - Fixed looping event cursor position from getting slightly out of sync with scheduled position when running at 44.1kHz.
    • +
    • Studio API - Fixed playlist steal-oldest polyphony returning errors when used with extremely small durations.
    • +
    • Studio API - Fixed silence after unpausing an event instance. Introduced in 1.05.08.
    • +
    • Core API - Fixed crash after setting the input format of a Return DSP to stereo, when the mixer output format is mono.
    • +
    • Core API - Windows - Fix crash calling FMOD_ASYNCREADINFO::done function pointer when default calling convention is not cdecl.
    • +
    • Core API - Fixed FMOD_SPEAKERMODE_RAW panning incorrectly during an up or down mix.
    • +
    • Core API - Fix crash when a Channel::setPosition is called on a non-blocking stream that is going virtual.
    • +
    • Core API - Fixed potential audio corruption when playing sounds with more than 8 channels.
    • +
    • Core API - Fixed emulated channels not updating their parent when when Channel::setChannelGroup is called.
    • +
    • Core API - Fixed channels having their volume reset when changing channel group parents.
    • +
    • Core API - Fixed channels not going virtual when being paused if no other volume changes were occurring.
    • +
    • Core API - Fixed FMOD_INIT_PROFILE_ENABLE enabling all DSP metering regardless of whether FMOD_INIT_PROFILE_METER_ALL was used.
    • +
    • Core API - Added volume ramp up for 3d channels coming back from virtual to real.
    • +
    • Core API - Fixed rare crash if the master channelgroup's DSP Head unit was changed then released.
    • +
    • Core API - PS3 - Fix loudness meter not functioning.
    • +
    • Core API - PS3 - Re-enabled playDSP.
    • +
    +

    Notes:

    +
      +
    • Core API - Xbox One - Added check to ensure DSP buffer size is specified as the default 512 samples to avoid performance degradation of XMA decoding.
    • +
    • Core API - Windows - Changed default ASIO speaker mapping to 1:1 for outputs with more than 8 channels.
    • +
    +

    28/11/14 1.05.08 - Studio API patch release

    +

    Features:

    + +

    Fixes:

    +
      +
    • Studio API - Fixed pops that could occur when stopping events that have instruments scheduled to stop already.
    • +
    • Studio API - Fixed pop that could occur when playing an sound that has an AHDSR fade in.
    • +
    • Studio API - Fixed indeterminism when exporting string banks that have multiple string entries with inconsistent case.
    • +
    • Core API - Android - Improved compatibility with Java 1.6.
    • +
    • Core API - iOS - Added armv7s back to the universal binary.
    • +
    • Core API - Windows - Fix System::getRecordDriverInfo returning incorrect device names. Introduced in 1.05.00.
    • +
    • Core API - Fix FMOD_SPEAKERMODE_RAW creating silence if playing more than 1 sound, introduced in 1.04.15.
    • +
    • Core API - Fix CELT and Vorbis FSB being allowed with FMOD_OPENMEMORY_POINT and FMOD_CREATESAMPLE when it should in fact return FMOD_ERR_MEMORY_CANTPOINT
    • +
    +

    21/11/14 1.05.07 - Studio API patch release

    +

    Important:

    +
      +
    • Studio API - Fixed scheduling for looping nested events which are cut off from the parent event. Previously the looping nested event would attempt to play to end but would cut off halfway through with a noticeable click. The nested event now cuts off immediately with a fade out ramp.
    • +
    +

    Features:

    +
      +
    • Core API - Android - Added ARM64 support.
    • +
    +

    Fixes:

    +
      +
    • Core API - Fix ChannelGroup::setMixLevelsOutput causing corrupted audio when the channel group has an input with a channel count greater than the system channel count.
    • +
    • Core API - Fixed ChannelControl::setMute not refreshing channel audibility.
    • +
    • Core API - Windows - Fix calls to DSP::getInfo () from within a custom DSP deadlocking the system during audio device change.
    • +
    • Core API - Fixed some DSP configurations with an idle first input causing signal to be downmixed to mono.
    • +
    • Core API - Fix invalid characters being printed in log messages when open certain types of media files.
    • +
    • Studio API - Fixed Studio::Bank::getEventCount and Studio::Bank::getEventList incorrectly enumerating nested events.
    • +
    • Studio API - Fixed Studio::Bus::stopAllEvents not working when snapshots or nested events are playing.
    • +
    • Studio API - Fixed "state->mInstanceCount > 0" assert that could occur when instruments were stopped repeated times.
    • +
    +

    Notes:

    +
      +
    • PS Vita - Now built with SDK 3.300.
    • +
    • WiiU - Now built with SDK 2.11.13.
    • +
    +

    13/11/14 1.05.06 - Studio API patch release

    +

    Features:

    +
      +
    • Core API - Windows - Add 64bit VST support
    • +
    +

    Fixes:

    +
      +
    • Studio API - Fixed thread safety issue when accessing sound tables as new banks with sound tables are being added.
    • +
    • Studio API - Fixed duplicate streaming sounds keeping playing when unloading the memory bank that it is streaming from. Now the stream will stop if the memory bank is unloaded.
    • +
    • Core API - Fixed sound going mono in certain DSP configurations. Introduced 1.05.00.
    • +
    • Core API - Fixed rare timing issue with fade points that caused the fader DSP to generate invalid floats.
    • +
    • Core API - Android - Fixed crashes due to insufficient stack size when running ART instead of Dalvik.
    • +
    • Core API - Windows - Fixed potential crash if using multiple FMOD::System with ASIO output mode. This is not supported by ASIO and is now disabled.
    • +
    • Core API - Linux - Fixed PulseAudio device enumeration not placing the default device at position 0.
    • +
    +

    Notes:

    +
      +
    • Xbox One - Now built with November 2014 XDK.
    • +
    • Android - Now built with NDK r10c.
    • +
    • iOS - Now built with SDK 8.1 (Xcode 6.1).
    • +
    • Mac - Now built with SDK 10.10 (Xcode 6.1).
    • +
    • PS4 - Now built with SDK 2.000.071
    • +
    +

    30/10/14 1.05.05 - Studio API patch release

    +

    Features:

    +
      +
    • Core API - Added convolution reverb example.
    • +
    +

    Fixes:

    +
      +
    • Studio API - Fixed various errors after deleting objects via Live Update
    • +
    • Studio API - Fixed possible crash using shared waveforms across multiple banks after some of the duplicate banks have been unloaded.
    • +
    • Studio API - Fixed duplicate events becoming invalidated when the first bank that contains them is unloaded.
    • +
    • Studio API - Fixed bug in load_banks example.
    • +
    • Studio API - Fixed crash when calling Studio::Bus::stopAllEvents while playing event instances that have had release called.
    • +
    • Core API - Fixed memory leaks.
    • +
    +

    22/10/14 1.05.04 - Studio API patch release

    +

    Fixes:

    +
      +
    • Studio API - Fixed transition markers failing at the start of the timeline.
    • +
    • Core API - PS3/X360/Wii-U - Fix vorbis seek getting stuck in an infinite loop.
    • +
    • Core API - Fixed incorrect behaviour when changing the channel mode from 3D to 2D.
    • +
    • FSBank - Fixed setting the cache directory and printing log messages.
    • +
    +

    Notes:

    +
      +
    • Studio API - Timeline transitions can be chained together with no delay.
    • +
    +

    13/10/14 1.05.03 - Studio API patch release

    +

    Features:

    + +

    Fixes:

    +
      +
    • Studio API - Fixed event fadeout cutting off DSP effects with long tails.
    • +
    • Studio API - Fixed crash when accessing events with a lifetime across duplicate banks. Note that when unloading the initial bank for an event, that event will be invalidated.
    • +
    • Core API - Fixed for enum mismatches in C# wrapper.
    • +
    • Core API - Fixed FMOD_DSP_LOWPASS click when being reused, ie stopping then starting a new sound.
    • +
    • Core API - Fixed rare hang during Sound::release for sounds created as FMOD_NONBLOCKING.
    • +
    • Core API - Fixed corrupted playback of MOD/S3M/XM/IT/MID sequenced formats. Introduced 1.04.05
    • +
    • Core API - Fixed ChannelGroup::setReverbProperties on the master channel group causing a stack overflow. This is now disallowed as it creates a circular dependency.
    • +
    • Core API - Mac - Replaced error condition if initializing FMOD before activating the AudioSession with a TTY warning.
    • +
    • Core API - Android - Fixed Sound::readData going forever when reading AAC audio.
    • +
    • Core API - Fix the pancallbacks member of the FMOD_DSP_STATE_SYSTEMCALLBACKS structure passed into custom DSP callbacks being NULL.
    • +
    • Core API - Fix crash in mixer if user used System::playDSP and made the dsp inactive with DSP::setByPass or DSP::setActive
    • +
    +

    01/10/14 1.05.02 - Studio API patch release

    +

    Fixes:

    +
      +
    • Studio API - Fixed a bug where event sounds could have incorrectly synchronized playback.
    • +
    • Core API - Fixed compiler warning in public header.
    • +
    • Studio API - Disabled embedded loop points on all sounds played by the Studio API to fix incorrect playback of timelocked sounds.
    • +
    • Studio API - Snapshot volumes are now interpolated in terms of linear gain.
    • +
    • Core API - Fixed 3EQ DSP not clearing out internal state when DSP::reset is called, potentially causing audible artifacts when reused.
    • +
    • Core API - Fixed resampler inaccuracies when reading partial looping data.
    • +
    • Core API - Mac - CoreAudio output mode will now allow any DSP block size and will correctly use the desired buffer count.
    • +
    • Core API - Mac - CoreAudio now correctly exposes its output AudioUnit via the System::getOutputHandle function.
    • +
    • Core API - PS3 - Fixed resampler strict aliasing bug on PPU release builds.
    • +
    • Core API - PS3 - Fixed playDSP crash.
    • +
    • Core API - Fixed convolution reverb input downmix
    • +
    • Core API - Greatly increase speed of mixing multichannel source data.
    • +
    +

    Notes:

    +
      +
    • Studio API - Loudness meters saved in banks will now be bypassed to improve performance when profiler isn't attached.
    • +
    • Xbox One - Now built with September 2014 QFE 1 XDK.
    • +
    +

    22/09/14 1.05.01 - Studio API patch release

    +

    Important:

    +
      +
    • Fixed possible large memory blowout if certain DSP pools were exceeded.
    • +
    +

    Features:

    + +

    Fixes:

    +
      +
    • Studio API - Implemented Studio::Bus::stopAllEvents.
    • +
    • Studio API - Fixed bus going silent when output format is stereo and system speaker mode is 5.1.
    • +
    • Studio API - Fixed Studio::System::getAdvancedSettings clearing FMOD_STUDIO_ADVANCEDSETTINGS.cbSize and not returning default values.
    • +
    • Studio API - Fixed a bug where looping or sustaining events could incorrectly be treated as oneshot.
    • +
    • Studio API - Fixed a bug where event sounds could have incorrectly synchronized playback.
    • +
    • Core API - Fix bug with custom 3D rolloff curve points getting corrupted.
    • +
    • Core API - Fixed incorrect documentation for FMOD_CHANNELCONTROL_CALLBACK.
    • +
    • Core API - Fix sub-mix channel count being incorrect when playing multiple sounds with different channel counts together. Introduced in 1.04
    • +
    • Core API - Fix a channel DSP head's ChannelFormat not being reset if a sound with a channel mask was played on it previously
    • +
    +

    Notes:

    +
      +
    • iOS - Now built with SDK 8.0 (Xcode 6.0).
    • +
    • Mac - Now built with SDK 10.9 (Xcode 6.0).
    • +
    +

    09/09/14 1.05.00 - Studio API minor release

    +

    Important:

    + +

    Features:

    +
      +
    • Studio API - Added FMOD_STUDIO_EVENT_CALLBACK_PLUGIN_CREATED and FMOD_STUDIO_EVENT_CALLBACK_PLUGIN_DESTROYED callback types.
    • +
    • Studio API - Added Studio::Bank::getStringCount and Studio::Bank::getStringInfo.
    • +
    • Core API - Added FMOD::Debug_Initialize to configure the destination and level of debug logging when using the logging version of FMOD. This is a more flexible replacement for the previous FMOD::Debug_SetLevel API.
    • +
    • Core API - Android - Added support for playing AAC files (requires Android 4.2).
    • +
    • Core API - Android - Reduced latency for devices that support FastMixer, see "Basic Information" section of the docs CHM for details.
    • +
    • Core API - Added DSP::setWetDryMix so any effect can have generic wet/dry signal level control.
    • +
    • Core API - Added 3D ChannelGroup support. A ChannelGroup is a 'group bus' and it can now be positioned in 3d space, affecting the mix for buses and channels below it. 3D Cones, geometry etc all work. Use ChannelGroup::setMode (FMOD_3D) to enable a 3D ChannelGroup.
    • +
    +

    Fixes:

    +
      +
    • Studio API - Fixed transitions to the end of a loop region failing to escape the loop.
    • +
    • Studio API - Fixed sends inside events occasionally having a brief period of full volume when the event is started.
    • +
    • Core API - Fix for crash when creating multiple Systems with profiling enabled.
    • +
    +

    Notes:

    +
      +
    • Studio API - Transition regions no longer include the end of their range.
    • +
    • Studio API - FMOD_ERR_EVENT_WONT_STOP has been removed.
    • +
    • Studio API - Studio::EventInstance::start now resets all DSPs inside the event to prevent incorrect ramping. This relies on FMOD_DSP_RESET_CALLBACK leaving public parameters unchanged.
    • +
    • Studio API - Studio::System::getEvent's unimplemented mode parameter has been removed, along with FMOD_STUDIO_LOADING_MODE.
    • +
    • Studio API - FMOD_STUDIO_PLAYBACK_IDLE and FMOD_STUDIO_EVENT_CALLBACK_IDLE have been removed.
    • +
    • Studio API - Removed deprecated function Studio::EventInstance::createSubEvent.
    • +
    • Core API - Changed FMOD_FILE_ASYNCCANCEL_CALLBACK to take FMOD_ASYNCREADINFO structure rather than void *handle.
    • +
    • Core API - The FMOD_DSP_RESET_CALLBACK documentation has been updated to make it clear that it should leave public parameters unchanged.
    • +
    • Core API - PS4 - Thread affinity can now be set as a mask of allowed cores.
    • +
    • Core API - iOS / Mac - Reduced default block size to 512 for lower latency.
    • +
    • Core API - Android - Renamed Java interface from FMODAudioDevice to simply FMOD, i.e. org.fmod.FMOD.init().
    • +
    • Core API - Channel::setMode moved to ChannelControl::setMode so that ChannelGroups can now also have 2D/3D mode bits set.
    • +
    +

    09/09/14 1.04.08 - Studio API patch release

    +

    Fixes:

    +
      +
    • Studio API - Fixed crash when a second system is created but never initialized.
    • +
    • Studio API - Fixed a few ordering issues that can cause binary changes in identical banks.
    • +
    • Core API - Fix for pop due to unwanted volume ramping after calling DSP::reset on fader DSP. This can happen when a Studio event instance is stopped and then restarted. Caused by timing issue with ChannelControl::setVolumeRamp.
    • +
    • Core API - Fix crash if FMOD_DSP_TYPE_MIXER or DSP with no read/process function is passed to System::playDSP.
    • +
    • Core API - iOS - Fixed MP2 files being intercepted by AudioQueue causing an internal error.
    • +
    • Core API - XboxOne - Fixed network connect not resolving host names and not honoring the requested time out.
    • +
    • Core API - Fix rare crash if calling Channel::stop () which a non blocking Channel::setPosition is happening with a stream.
    • +
    • Core API - Winphone and Windows Store Apps - fixed detection of socket errors.
    • +
    • Core API - If a user DSP is added after the master ChannelGroup's fader that changes the output channel count to something other than the software mixer's channel count, stuttering could occur. Fixed.
    • +
    • Studio API - Windows - Fixed Studio API functions deadlocking when in asynchronous mode and a sound device is removed.
    • +
    • Core API - PS3 - Fixed some DSP parameter sets being ignored (overwritten by SPU DMA)
    • +
    • Core API - Fix System::playDSP not working with custom DSP effects that use the read callback
    • +
    • Core API - Added Memory.Initialize function to the C# wrapper.
    • +
    • Core API - Fixed incorrect truncation of FMOD_CREATECOMPRESSEDSAMPLE sounds created from MP3 or MP2 files (does not affect FSB).
    • +
    • Core API - Fixed FMOD_ACCURATETIME for FMOD_CREATECOMPRESSEDSAMPLE sounds created from MP3 or MP2 files (does not affect FSB).
    • +
    +

    Notes:

    +
      +
    • Core API - The master ChannelGroup's fader/head now is not responsible for up or downmixing the signal. It is now done beyond the dsp tree, internally within FMOD. The Master ChannelGroup's Fader can still be forced to upmix if required with DSP::setChannelFormat.
    • +
    +

    20/08/14 1.04.07 - Studio API patch release

    +

    Fixes:

    +
      +
    • Studio API - Fixed an internal error when instantiating a snapshot that exposes intensity as a parameter.
    • +
    • Core API - PS3 - Fix audio dropout/corruption when using FMOD_SPEAKERMODE_STEREO. Usually when sidechain is involved.
    • +
    • Core API - iOS - Fixed System::recordStart returning FMOD_ERR_RECORD.
    • +
    • Core API - Fixed possible click noise on end of sound if using FMOD_CREATECOMPRESSEDSAPMLE or PCM on PS3.
    • +
    +

    Notes:

    +
      +
    • Xbox One - Now built with July 2014 QFE1 XDK.
    • +
    • PS4 - Now built with SDK 1.750.061
    • +
    +

    06/08/14 1.04.06 - Studio API patch release

    +

    Features:

    +
      +
    • Studio API - Added FMOD_STUDIO_PROGRAMMER_SOUND_PROPERTIES.subsoundIndex to support non-blocking loading of FSB subsounds.
    • +
    • Core API - Windows - FMOD now handles sound card removal and insertion without any programmer intervention. If System::setCallback is called with FMOD_SYSTEM_CALLBACK_DEVICELISTCHANGED bit set, this feature is disabled.
    • +
    • Core API - Windows - System::setOutput can be called post-init now, allowing dynamic switching between any output mode at runtime.
    • +
    • Core API - iOS - Improved IMA ADPCM decoding performance especially for arm64 variant.
    • +
    +

    Fixes:

    +
      +
    • Core API - Fixed bug where channels with post-fader DSP units would not play after transitioning from virtual to real.
    • +
    • Core API - Fix pops with resampler on loops.
    • +
    • Core API - Fix playDSP returning FMOD_ERR_DSP_SILENCE or FMOD_ERR_DSP_DONTPROCESS if the dsp played returned that during query mode.
    • +
    • Core API - PS3 - Fix ITEcho, SFXReverb, FFT DSP effects rarely getting parameters reset to old values.
    • +
    • Core API - Xbox One - Fixed audio corruption when playing mono streams from an XMA FSB that has both mono and stereo subsounds.
    • +
    • Core API - PS3 - Moved vorbis decode work during stream setPosition to the SPU.
    • +
    • Core API - Windows - Fix System::setSoftwareFormat with differing samplerate and speaker mode causing static.
    • +
    • FSBank API - Fixed cache being incorrectly reused when replacing source files of identical name with a different file that has an old time stamp.
    • +
    +

    Notes:

    +
      +
    • PS3 - Now built with SDK 460.001
    • +
    +

    25/07/14 1.04.05 - Studio API patch release

    +

    Fixes:

    +
      +
    • Studio API - Fix for pop when stopping events with FMOD_STUDIO_STOP_ALLOWFADEOUT.
    • +
    • Studio API - Fix incorrect scheduling when Multi Sounds contain nested events with timeline transitions.
    • +
    • Studio API - Fix for nested event modules not being cleaned up when used in a playlist module.
    • +
    • Studio API - Fix for events failing to stop when they have instruments on parameters that have Hold enabled.
    • +
    • Core API - Fix combined volume ramp and fade point ramp having an incorrect volume.
    • +
    • Core API - Fix for pop when setting zero volume with vol0virtual enabled.
    • +
    • Core API - Fix for pop when scheduling fade point ramps in the past.
    • +
    • Core API - Fix for pop on a return bus when all incoming sends go idle.
    • +
    • Core API - Fix for faders delaying going idle for a mix when volume is set to zero without ramping.
    • +
    • Core API - Fixed FSB forwards compatibility issue causing load failures.
    • +
    • Core API - XboxOne - Fixed ACP race condition when shutting down / initializing System causing XMA channels to not play.
    • +
    • Core API - XboxOne - Fixed XMA compressed sample channel leak that would eventually result in all sounds playing emulated (silent).
    • +
    • Core API - WinPhone and WSA - Fixed network connection not respecting system timeout value.
    • +
    • Core API - PS3 - Fix IMA ADPCM support for ps3 not working.
    • +
    • Core API - iOS - Fixed potential duplicate symbol error on link.
    • +
    +

    Notes:

    +
      +
    • Xbox One - Now built with July 2014 XDK.
    • +
    • iOS - Now built with SDK 7.1 (Xcode 5.1.1).
    • +
    +

    11/07/14 1.04.04 - Studio API patch release

    +

    Fixes:

    +
      +
    • Studio API - Fixed a bug where quantized timeline transitions could fail to play the audio at the destination marker.
    • +
    • Core API - Fix channel stealing not calling end callback in playDSP case.
    • +
    • Core API - Fix rare crash if System::playDSP is called, and it steals a channel with a sound on it, and System::update wasnt called in between.
    • +
    • Core API - Mac, iOS and Android - Improved network error reporting.
    • +
    +

    08/07/14 1.04.03 - Studio API patch release

    +

    Features:

    +
      +
    • Core API - Added FMOD_ADVANCEDSETTINGS.randomSeed, which specifies a seed value that FMOD will use to initialize its internal random number generators.
    • +
    +

    Fixes:

    +
      +
    • Studio API - Changed isValid() functions in C# wrapper to call through to C++.
    • +
    • Studio API - Fixed Studio::System::loadBankCustom file callbacks being ignored when System::setFileSystem is using async read functions.
    • +
    • Studio API - Fixed incorrect playback when starting an event instance immediately after creating it.
    • +
    • Studio API - Fixed some snapshot types causing silence on busses if loading files older than those created with FMOD Studio 1.04.02.
    • +
    • Core API - Fixed incorrect FMOD_ASYNCREADINFO.offset value passed to FMOD_FILE_ASYNCREAD_CALLBACK when file buffering is disabled.
    • +
    • Core API - Windows - Fixed WASAPI failing to initialize on certain old drivers.
    • +
    • Core API - Fix FMOD_SPEAKERMODE_RAW being broken.
    • +
    • Core API - Fixed System::set3DRolloffCallback not working.
    • +
    • Core API - Fixed Sound::set3DCustomRolloff not working.
    • +
    • Core API - Fix Geometry API not running in its own thread like it was in FMOD Ex.
    • +
    • Core API - Fixed incorrect DSP clock when re-routing a ChannelGroup immediately after adding DSPs to it.
    • +
    • Profiler - Fixed nodes appearing to overlap each other if multiple outputs were involved.
    • +
    • Core API - PS4 - Fixed unnecessary file reads when playing an AT9 stream.
    • +
    +

    27/06/14 1.04.02 - Studio API patch release

    +

    Fixes:

    +
      +
    • Studio API - Fixed incorrect virtualization of events that have more than one 3D position dependent effect.
    • +
    • Studio API - Studio::EventDescription::getInstanceList, Studio::Bank::getEventList, Studio::Bank::getMixerStripList and Studio::System::getBankList now accept a capacity of 0.
    • +
    • Core API - Fixed a race condition that could lead to DSP graph changes not being handled correctly.
    • +
    • Core API - Linux - Fixed "spurious thread death event" messages appearing when attached with GDB.
    • +
    • Core API - Linux - Fixed internal PulseAudio assert if System::getNumDrivers or System::getDriverInfo is used before System::init.
    • +
    • Core API - Linux - Fixed ALSA not using correct default driver in some cases.
    • +
    • Core API - Send levels set before connecting the Return DSP are now applied immediately rather than fading in over a short time.
    • +
    +

    19/06/14 1.04.01 - Studio API patch release

    +

    Features:

    + +

    Fixes:

    +
      +
    • Studio API - Fixed playlist module upmixing to system speakermode when playing multiple overlapping sounds.
    • +
    • Core API - Fix streams opened with FMOD_NONBLOCKING from playing at the incorrect position if they go virtual shortly after setPosition is called.
    • +
    • Core API - Fix EOF detection in file system causing rare extra file read past end of file.
    • +
    • Core API - Fix some FMOD_CREATECOMPRESSEDSOUND based samples finishing early if they were playing back at a low sample rate.
    • +
    • Core API - Fix a bug where DSP nodes could get stuck in an inactive state after setting pitch to 0.
    • +
    +

    11/06/14 1.04.00 - Studio API minor release

    +

    Important:

    +
      +
    • Added PS3 platform support.
    • +
    • Added WiiU platform support using SDK 2.10.04.
    • +
    • Added Linux platform support.
    • +
    • Added Windows Phone 8.1 platform support.
    • +
    • FMOD_HARDWARE and FMOD_SOFTWARE flags have been removed. All voices are software mixed in FMOD Studio.
    • +
    +

    Features:

    + +

    Fixes:

    +
      +
    • Studio API - Fixed nested events never ending if they have a parameter with non-zero seek speed.
    • +
    • Studio API - Fixed AHDSR modulation on snapshot intensity
    • +
    • Core API - Fixed incorrect fader interpolation when reparenting channels with propagate clocks.
    • +
    • Core API - Win - Fixed several issues with ASIO playback.
    • +
    • Core API - Android - Fixed audio corruption on devices without NEON support.
    • +
    • Core API - Fixed FMOD_CREATESOUNDEXINFO.length being handled incorrectly for memory sounds. This length represents the amount of data to access starting at the specified fileoffset.
    • +
    • Core API - Fix truncated FSB causing zero length subsounds, now returns FMOD_ERR_FILE_BAD
    • +
    +

    Notes:

    +
      +
    • Core API - Renamed C# wrapper SYSTEM_CALLBACKTYPE to SYSTEM_CALLBACK_TYPE so it matches the C++ API.
    • +
    • Core API - Renamed MinGW/Cygwin import library to libfmod.a
    • +
    • Studio API - Deprecated C# wrapper functions Studio.Factory.System_Create and Studio.System.init have been removed. Use Studio.System.create and Studio.System.initialize instead.
    • +
    • Studio API - Deprecated function Studio::EventInstance::getLoadingState has been removed. Use Studio::EventDescription::getSampleLoadingState instead.
    • +
    • Studio API - FMOD_STUDIO_EVENT_CALLBACK now takes an FMOD_STUDIO_EVENTINSTANCE* parameter.
    • +
    • Xbox One - Now built with June 2014 XDK.
    • +
    +

    29/05/14 1.03.09 - Studio API patch release

    +

    Fixes:

    +
      +
    • Studio API - Fixed truncation error when loading sample data from bank opened with Studio::System::loadBankMemory.
    • +
    • Studio API - Fixed numerical error when blending multiple snapshots with zero intensity.
    • +
    • Studio API - Fixed incorrect pitch when an instrument has a non-zero base pitch combined with pitch automation or modulation.
    • +
    • Core API - Xbox One - Fixed potential seeking inaccuracies with XMA sounds.
    • +
    • Core API - Fix occasional audio pops when starting a channel or channel group.
    • +
    • Core API - Fix crash when running out of memory during channel group creation.
    • +
    • Core API - Fixed the C# wrapper for Sound.setDefaults and Sound.getDefaults.
    • +
    +

    Notes:

    + +

    21/05/14 1.03.08 - Studio API patch release

    +

    Features:

    +
      +
    • Core API - Add FMOD_INIT_ASYNCREAD_FAST and FMOD_ASYNCREADINFO.done method, to improve performance of asyncread callback significantly. Instead of setting 'result', call 'done' function pointer instead.
    • +
    • Core API - Multiple channel groups can now be attached to the same output port.
    • +
    • Core API - PS4 - Minor performance improvements in AT9 decoding using new SDK features.
    • +
    +

    Fixes:

    +
      +
    • Core API - Windows Store - Fixed networking issues.
    • +
    • Core API - Windows Store - Fixed System::getRecordDriverInfo () returning incorrect number of channels.
    • +
    • Core API - Fix System::setFileSystem asyncread callback not setting priority values properly.
    • +
    • Core API - Releasing a channel group attached to an auxiliary output port now cleans up resources correctly.
    • +
    • Core API - Channel groups attached to an auxiliary output port can now be added as children of other channel groups.
    • +
    • Core API - Fix DSPConnection::setMix () not being applied properly.
    • +
    • Core API - PS Vita - Fixed potential crash during System::init if any output related pre-init APIs are used, such as System::getNumDrivers.
    • +
    • Core API - PS Vita - Fixed crash if an attempt is made to load AT9 FSBs as a compressed sample, for PS Vita this is a streaming only format.
    • +
    • Core API - Xbox One - Small improvement to XMA performance.
    • +
    • Core API - Fixed the C# wrapper for System.playDSP.
    • +
    • Core API - Fixed potential crash on ARM platforms when loading an FSB.
    • +
    +

    Notes:

    +
      +
    • PS4 - Now built with SDK 1.700.
    • +
    • Android - Now built with NDK r9d.
    • +
    +

    08/05/14 1.03.07 - Studio API patch release

    +

    Features:

    +
      +
    • Studio API - Improved performance for projects with many events.
    • +
    • Studio API - Improved memory usage for projects with many bus instances.
    • +
    • Studio API - Added Studio::System::setCallback, Studio::System::setUserData and Studio::System::getUserData.
    • +
    • Core API - Added gapless_playback example for scheduling/setDelay usage.
    • +
    • Core API - Improved performance of logging build.
    • +
    • Core API - Added FMOD_SYSTEM_CALLBACK_MIDMIX callback.
    • +
    +

    Fixes:

    +
      +
    • Studio API - Fixed AHDSR Release not working when timelocked sounds are stopped by a parameter condition.
    • +
    • Studio API - Removed some unnecessary file seeks.
    • +
    • Studio API - Fixed AHDSR Release resetting to Sustain value when instruments with limited Max Voices are stopped repeatedly.
    • +
    • Studio API - Fixed channels within paused events not going virtual.
    • +
    • Studio API - Fixed AHDSR Release not working inside nested events
    • +
    • Core API - Fixed downmixing to a quad speaker setup.
    • +
    • Core API - Fixed fsb peak volume levels on big endian platforms.
    • +
    • Core API - Fixed paused channels not going virtual.
    • +
    +

    17/04/14 1.03.06 - Studio API patch release

    +

    Features:

    +
      +
    • Studio API - Improved performance of automation and modulation
    • +
    +

    Fixes:

    +
      +
    • Studio API - Fixed crash when creating new automation via LiveUpdate
    • +
    • Studio API - Fixed possible internal error being returned from Studio::Bank::getSampleLoadingState when called on an unloading bank.
    • +
    +

    14/04/14 1.03.05 - Studio API patch release

    +

    Fixes:

    +
      +
    • Core API - Added ChannelControl to the C# wrapper to match the C++ API.
    • +
    • Core API - Fixed the definition of ChannelControl.setDelay and ChannelControl.getDelay in the C# wrapper.
    • +
    • Core API - Replaced broken C# wrapper System.set3DSpeakerPosition and System.get3DSpeakerPosition functions with System.setSpeakerPosition and System.getSpeakerPosition.
    • +
    • Core API - Fixed the capitalization of DSP.setMeteringEnabled, DSP.getMeteringEnabled and DSP.getMeteringInfo in the C# wrapper.
    • +
    • Core API - Xbox 360 - Fix hang on XMA playback
    • +
    • Core API - Fix crash when running out of memory loading an ogg vorbis file.
    • +
    • Core API - Fix symbol collisions when statically linking both FMOD and Xiph libvorbis or libtremor.
    • +
    +

    08/04/14 1.03.04 - Studio API patch release

    +

    Features:

    + +

    Fixes:

    +
      +
    • Studio API - Added Studio.System.initialize to the C# wrapper to match the C++ API (replacing Studio.System.init, which is now deprecated).
    • +
    • Studio API - Added Studio.System.create to the C# wrapper to match the C++ API (replacing Studio.Factory.System_Create, which is now deprecated).
    • +
    • Studio API - Added missing functions to the C# wrapper: Studio.EventInstance.get3DAttributes, Studio.EventInstance.isVirtual, Studio.EventInstance.setUserData, Studio.EventInstance.getUserData, Studio.MixerStrip.getChannelGroup, Studio.EventDescription.getUserProperty, Studio.EventDescription.getUserPropertyCount, Studio.EventDescription.getUserPropertyByIndex, Studio.EventDescription.setUserData, Studio.EventDescription.getUserData and Studio.System.loadBankCustom.
    • +
    • Core API - Fix for VBR sounds that dont use FMOD_CREATECOMPRESSEDSAMPLE and FMOD_ACCURATETIME not looping when FMOD_LOOP_NORMAL was set.
    • +
    • Core API - XboxOne - Fixed rare mixer hang when playing XMA as a compressed sample.
    • +
    • Core API - Fix crash with combination of FMOD_OPENUSER + FMOD_NONBLOCKING and a null pointer being passed to System::createSound/createStream.
    • +
    +

    Notes:

    +
      +
    • Added examples to the Programmer API documentation.
    • +
    • Xbox One - Now built with March 2014 QFE1 XDK.
    • +
    • Studio API - In the C# wrapper, Studio.System.init is now deprecated in favour of Studio.System.initialize.
    • +
    • Studio API - In the C# wrapper, Studio.Factory.System_Create is now deprecated in favour of Studio.System.create.
    • +
    • Studio API - Studio::EventDescription::is3D now returns true if any of its nested events are 3D.
    • +
    • Core API - FMOD_CREATESOUNDEXINFO.suggestedsoundtype now tries the suggested type first, then tries the rest of the codecs later if that fails, rather than returning FMOD_ERR_FORMAT.
    • +
    • Core API - Custom codecs. The open callback for a user created codec plugin now does not have to seek to 0 with the file function pointer before doing a read.
    • +
    +

    28/03/14 1.03.03 - Studio API patch release

    +

    Fixes:

    + +

    26/03/14 1.03.02 - Studio API patch release

    +

    Features:

    + +

    Fixes:

    +
      +
    • Studio API - Fix for setting parameter values that could cause volume changes without the appropriate volume ramp.
    • +
    • Core API - Fix for some incorrect declarations in the C header files.
    • +
    • Core API - Fixed a linker error when calling some C API functions.
    • +
    • Core API - Fixed FMOD_ChannelGroup_AddGroup not returning the DSP connection on success.
    • +
    • Core API - PS4 - Fixed FMOD macros for declaring plugin functions.
    • +
    +

    Notes:

    + +

    18/03/14 1.03.01 - Studio API patch release

    +

    Important:

    + +

    Fixes:

    +
      +
    • Studio API - Fixed simple nested events not terminating properly when inside multi sounds
    • +
    • Core API - Fix SRS downmix crash on startup if software mixer was set to 5.1, and the OS was set to stereo, and the system sample rate was not 44/48/96khz
    • +
    • Core API - Fix for deadlock that could occur when executing commands in the non-blocking callback as another thread is releasing sounds.
    • +
    • Core API - Fix for Channel::getPosition and ChannelControl::getDSPClock returning errors when called on emulated channels created with System::playDSP.
    • +
    • Core API - PS4 - Fixed leak of audio output handles on shutdown.
    • +
    • Core API - Fix crash in compressor when placed on a channel with a delay.
    • +
    +

    Notes:

    +
      +
    • PS4 - Now built with SDK 1.600.071.
    • +
    +

    03/03/14 1.03.00 - Studio API minor release

    +

    Important:

    +
      +
    • Added PS Vita platform support.
    • +
    • Updated FMOD Studio Programmers API documentation.
    • +
    • Studio API - Changed .bank file format - ALL BANKS MUST BE REBUILT
    • +
    • Studio API - Studio API is now asynchronous by default, with the processing occuring on a new Studio thread. Asynchronous behaviour can be disabled with the FMOD_STUDIO_INIT_SYNCHRONOUS_UPDATE init flag.
    • +
    • Studio API - Studio API classes are now all referenced as pointers. This reflects a change in the handle system to make it thread-safe, more performant and match the C and Core API interface.
    • +
    • Studio API - Event and mixer strip paths now include a prefix in order to guarantee uniqueness. See Studio::System::lookupID.
    • +
    • Core API - Core API is now thread-safe by default. Thread safety can be disabled with the FMOD_INIT_THREAD_UNSAFE init flag.
    • +
    • Core API - Codecs must set waveformatversion to FMOD_CODEC_WAVEFORMAT_VERSION in the FMOD_CODEC_OPEN_CALLBACK.
    • +
    • Core API - Removed support for digital CD audio
    • +
    +

    Features:

    +
      +
    • Studio API - The new .bank file format provides improved support for backward and forward compatibility. Future version updates will not generally require banks to be rebuilt.
    • +
    • Studio API - Added support for events duplicated across banks.
    • +
    • Studio API - Added support for transition marker and loop region probability.
    • +
    • Studio API - Added support for sounds on transition timelines.
    • +
    • Studio API - Added asset enumeration functions: Studio::System::getBankCount, Studio::System::getBankList, Studio::Bank::getEventCount, Studio::Bank::getEventList, Studio::Bank::getMixerStripCount, Studio::Bank::getMixerStripList.
    • +
    • Studio API - Added path retrieval functions: Studio::System::lookupPath, Studio::EventDescription::getPath, Studio::MixerStrip::getPath, Studio::Bank::getPath.
    • +
    • Studio API - Bank loading now takes an extra flags argument. It is possible to load banks in non-blocking mode in which case the function will return while the bank is still in the process of loading.
    • +
    • Studio API - Added Studio::System::setAdvancedSettings.
    • +
    • Studio API - Added Studio::System::getCPUUsage.
    • +
    • Studio API - Studio repositories have improved performance and no longer depend on the standard library map.
    • +
    • Core API - The system callback now includes the error callback type which will be invoked whenever a public FMOD function returns a result which is not FMOD_OK.
    • +
    • Core API - Optimize Sound::getNumSyncPoints when using large FSB files with many subsounds and many syncpoints.
    • +
    • Core API - Made improvements to virtual voices for DSP graphs using sends, returns, fade points, and sounds with varying peak volumes.
    • +
    • Core API - PS4 - Added recording support.
    • +
    • Core API - XBox One - Added dll loading support.
    • +
    • FSBank API - Added support for exporting peak volume per sound using the FSBANK_BUILD_WRITEPEAKVOLUME flag.
    • +
    +

    Fixes:

    +
      +
    • Core API - Channels now take fade points into account for virtualisation
    • +
    • Core API - Fixed pops when changing Echo DSP Delay parameter
    • +
    • Core API - Xbox One - Removed a CPU spike when first playing a compressed sample XMA.
    • +
    +

    Notes:

    +
      +
    • Studio API - Replaced Studio::System::lookupEventID and Studio::System::lookupBusID with Studio::System::lookupID.
    • +
    • Core API - The system callback now has an extra userdata argument that matches the userdata specified in System::setUserData.
    • +
    • Core API - Xbox One - APU allocations are now handled internally for developers using memory callbacks or memory pools.
    • +
    +

    24/02/14 1.02.13 - Studio API patch release

    +

    Fixes:

    +
      +
    • Core API - Removed stalls when removing a DSP chain from a channel
    • +
    • Core API - Fixed Channel::getPosition returning incorrect value for streams with very short loops.
    • +
    • Core API - Fixed rare bug with DSP nodes not being set active in the mixer graph.
    • +
    • Core API - Fixed rare bug with DSP metering not being set.
    • +
    • Core API - Fixed incorrect playback of multi-channel PCM8 data.
    • +
    • Core API - PS4 - Fixed issues with calling ChannelControl::setPosition on AT9 streams and compressed samples.
    • +
    • Core API - PS4 - Fixed audio glitches when using the background music port and the system format is not 7.1
    • +
    • Core API - PS4 - Added loading of plugins from PRX files.
    • +
    • Core API - Android - Fixed crash on low quality Vorbis encoded FSBs.
    • +
    • Core API - Android - Fixed one time memory leak on System::release when using OpenSL output mode.
    • +
    • Studio API - Fixed playlist instruments occasionally cutting off too early.
    • +
    • Studio API - Fixed rare timing issue that caused spawning instruments to trigger too early.
    • +
    +

    Notes:

    +
      +
    • Xbox One - Now built with August QFE11 XDK.
    • +
    • PS4 - Now built with SDK 1.600.051.
    • +
    +

    07/01/14 1.02.12 - Studio API patch release

    +

    Fixes:

    +
      +
    • Core API - Fixed potential crash with net streams.
    • +
    • Core API - PS4 - Fixed rare internal error in AT9 codec when channels are reused after stopping.
    • +
    • Studio API - Fixed nested events getting incorrect 3D position information
    • +
    +

    17/12/13 1.02.11 - Studio API patch release

    +

    Features:

    +
      +
    • Core API - Added ChannelControl::setVolumeRamp and ChannelControl::getVolumeRamp to control whether channels automatically ramp their volume changes.
    • +
    • Studio API - Added FMOD_STUDIO_EVENT_CALLBACK_IDLE callback type, fired when an event instance enters the idle state.
    • +
    +

    Fixes:

    + +

    Notes:

    +
      +
    • Core API - PCM data will now be read the main data in a single read instead of breaking the reads up into 16kb chunks.
    • +
    • Studio API - Changed behavior of Studio::EventInstance::getCue to return FMOD_ERR_EVENT_NOTFOUND if the event has no sustain points.
    • +
    +

    02/12/13 1.02.10 - Studio API patch release

    +

    Important:

    +
      +
    • Core API - Updated the C ChannelGroup functions to take 64 bit integer argument.
    • +
    +

    Fixes:

    +
      +
    • Core API - Fix FMOD_SPEAKERMODE_SURROUND upmixing to 5.1 or 7.1 incorrectly, ie surround left mixing into LFE and surround right into surround right.
    • +
    • Core API - PS4 - Fix playback of background music when system software format is not 7.1.
    • +
    +

    26/11/13 1.02.09 - Studio API patch release

    +

    Notes:

    +
      +
    • PS4 - Now built with SDK 1.500.111
    • +
    +

    19/11/13 1.02.08 - Studio API patch release

    +

    Important:

    + +

    Features:

    +
      +
    • Studio API - Added setParameterValue and setParameterValueByIndex functions in eventInstance to wrap finding and then setting a parameter value.
    • +
    +

    Fixes:

    +
      +
    • Core API - Fixed positioning of 5.1 surround speakers when soundcard is set to other surround formats
    • +
    • Core API - Fixed excessive log spam making the logging version much slower
    • +
    • Core API - Xbox One - Fixed rare XMA codec hang which could also manifest as FMOD_ERR_INTERNAL.
    • +
    • Core API - PS4 - Fixed crash when assigning a channel group to the controller speaker.
    • +
    • Studio API - Fixed MixerStrip release not working when the user has multiple handles to the same strip
    • +
    • Studio API - Fixed pops when playing nested events that have silent tracks
    • +
    • Studio API - Fixed crash when shutting down with profiler connected.
    • +
    • Studio API - Fixed unused streams being created during event preloading
    • +
    +

    Notes:

    +
      +
    • Core API - Turned off optimization for user created DSP effects that do not call the read callback if no sound is coming in. read callbacks will now always fire regardless. 'shouldiprocess' callback can be defined to optimize out no input.
    • +
    +

    12/11/13 1.02.07 - Studio API patch release

    +

    Fixes:

    +
      +
    • Core API - iOS - Fixed streams returning FMOD_ERR_INTERNAL on ARM64 devices.
    • +
    • Core API - iOS - Fixed automatic interruption handling not working for ARM64 devices.
    • +
    • Core API - Fix possible crash on startup, if using 5.1 mixing on a stereo output (downmixer enabled).
    • +
    • Core API - Fix setMute on master channelgroup not working.
    • +
    • Studio API - Fixed AHDSR modulators starting at the wrong value when attack time is 0
    • +
    • Studio API - Fixed Multi Sounds and Scatterer Sounds not randomizing correctly after deleting all entries
    • +
    +

    06/11/13 1.02.06 - Studio API patch release

    +

    Features:

    +
      +
    • Core API - iOS - Added support for ARM64 devices and x86_64 simulator.
    • +
    +

    Fixes:

    +
      +
    • Studio API - Fix playback issues after running for more than 12 hours
    • +
    • Core API - Fixed net streaming truncating or repeatings parts of the end of a netstream.
    • +
    • Core API - Fix crash due to missing functions in kernel32.dll on Windows XP.
    • +
    +

    29/10/13 1.02.05 - Studio API patch release

    +

    Features:

    +
      +
    • Studio API - Improved performance of Studio::System::setListenerAttributes
    • +
    • Studio API - FMOD profiler can now show Studio Bus and Event instances in the DSP node graph.
    • +
    +

    Fixes:

    +
      +
    • Studio API - Fixed pan jittering on events that move with the listener
    • +
    +

    22/10/13 1.02.04 - Studio API patch release

    +

    Features:

    +
      +
    • Studio API - Added ability to continue loading banks when missing plugins.
    • +
    • Studio API - Added FMOD_STUDIO_PARAMETER_TYPE enum to describe the type of a parameter to FMOD_STUDIO_PARAMETER_DESCRIPTION.
    • +
    • Core API - Added function to get parent sound from a subsound.
    • +
    • Core API - Android - Added support for dynamic plugins.
    • +
    +

    Fixes:

    +
      +
    • Studio API - Trying to set an automatic parameter will return FMOD_ERR_INVALID_PARAM.
    • +
    • Core API - Fix restarting a channel corrupting fader and panner positions if effects are added.
    • +
    • Core API - Fix channel restarting if 1. sound ended, 2. Channel::setVolume (0) with FMOD_VOL0BECOMESVIRTUAL happened, 3. setVolume(>0) happened, in between 2 system updates.
    • +
    • Core API - Fixed issues on PS4 after opening an output audio port fails.
    • +
    • Core API - Calling playSound on a fsb loaded with createStream will now return FMOD_ERR_SUBSOUND.
    • +
    +

    15/10/13 1.02.03 - Studio API patch release

    +

    Fixes:

    +
      +
    • Core API - iOS - Fixed potential crash when stopping virtual channels.
    • +
    • Studio API - Fixed click with cross-fade for nested events
    • +
    • Studio API - Mac - Fixed link issues from certain API functions.
    • +
    +

    Notes:

    +
      +
    • Studio API - FMOD_Studio_System_Create now takes a headerVersion parameter to match the C++ API
    • +
    +

    07/10/13 1.02.02 - Studio API patch release

    +

    Fixes:

    +
      +
    • Core API - Fixed rare crash when using virtual voices.
    • +
    • Core API - Fixed channel fade state not being preserved when switching to virtual.
    • +
    • Core API - Fixed 5.1 and 7.1 downmix to stereo being off-center.
    • +
    • Core API - Mac - Fixed incorrect downmix logic causing excess channels to be dropped.
    • +
    +

    Notes:

    + +

    01/10/13 1.02.01 - Studio API patch release

    +

    Features:

    +
      +
    • Core API - Improved performance of compressor on X86/x64 platforms.
    • +
    • Studio API - Added support for new automatic parameters: Event Orientation, Direction, Elevation and Listener Orientation
    • +
    +

    Fixes:

    +
      +
    • Core API - Fixed crash when downmixing to 16-bit output.
    • +
    • Core API - Fixed floating point issue when setting very low pitch values.
    • +
    • Studio API - Fixed sound glitch that could occur after crossfade.
    • +
    • Studio API - Fix for assert when rescheduling with modified pitch.
    • +
    +

    Notes:

    +
      +
    • iOS - Now built with SDK 7.0.
    • +
    • Mac - Now built with SDK 10.8.
    • +
    +

    23/09/13 1.02.00 - Studio API minor release

    +

    Important:

    +
      +
    • Added Android platform support.
    • +
    +

    Features:

    +
      +
    • Core API - Added FMOD_CREATESOUNDEXINFO.fileuserdata to hold user data that will be passed into all file callbacks for the sound
    • +
    • Core API - Added System::mixerSuspend and System::mixerResume for mobile platforms to allow FMOD to be suspended when interrupted or operating in the background.
    • +
    • Core API - Added float parameter mappings support to plug-ins
    • +
    • Core API - PS4 - Added Output Ports example
    • +
    • Studio API - Reduced memory overhead for several core types.
    • +
    • Studio API - Added Studio::System::loadBankMemory to support loading banks from a memory buffer
    • +
    • Studio API - Added Studio::System::loadBankCustom to support loading banks using bank-specific custom file callbacks
    • +
    • Studio API - Added support for placing multiple tempo markers on a timeline.
    • +
    • Studio API - Better error reporting for instruments scheduled in the past.
    • +
    +

    Fixes:

    +
      +
    • Core API - Fix incorrect error codes being returned by C# wrapper.
    • +
    • Core API - Fix bug in stereo-to-surround and surround-to-surround panning
    • +
    • Core API - Fix System::playDSP not working
    • +
    • Core API - Fix rare crash with DSPConnection::setMixMatrix. Studio API could also be affected.
    • +
    • Core API - Fix getMeteringInfo not clearing its values when pausing.
    • +
    • Core API - Fix audio pops when restarting sounds due to downmixing.
    • +
    • Core API - PS4 - Fix crash when disconnecting a channel group from an output port.
    • +
    • Core API - PS4 - Fix issue with audio channels not finishing correctly when being played through a port.
    • +
    • Core API - Xbox One - Fixed 'clicking' when a realtime decoded XMA sample loops if adjusting pitch during playback.
    • +
    • Studio API - Fix event priority not working
    • +
    • Studio API - Fix Studio::EventInstance::start () returning incorrect result with non-blocking sounds.
    • +
    • Studio API - Fix memory leaks when loading corrupt banks
    • +
    • Studio API - Fix channels leaking with nested instruments
    • +
    • Studio API - Fix MixerStrip::setFaderLevel on the game side affecting volume levels in the tool when connected via Live Update
    • +
    • Studio API - Fix a potential crash when getting a string property with Studio::EventDescription::getUserPropertyByIndex
    • +
    +

    Notes:

    +
      +
    • Studio API - Renamed Studio::System::loadBank to Studio::System::loadBankFile
    • +
    • Studio API - Updated the API examples to use the new example project
    • +
    • Core API - Changed FMOD_FILE_OPEN_CALLBACK userdata parameter from void* to void (it now comes from FMOD_CREATESOUNDEXINFO.fileuserdata rather than being set by the open callback)
    • +
    • Core API - iOS - Removed automatic handling of interruptions. Developers should call the new System::mixerSuspend / System::mixerResume API from their interruption handler.
    • +
    • Core API - iOS - Removed all usage of AudioSession API, developers are now encouraged to use the platform native APIs as there is no possible conflict with FMOD.
    • +
    • PS4 - Now built with SDK 1.020.041.
    • +
    +

    02/09/13 1.01.15 - Studio API patch release

    +

    Features:

    +
      +
    • Core API - Performance optimizations.
    • +
    • Studio API - Performance optimizations.
    • +
    +

    Fixes:

    +
      +
    • Core API - Fix oscillators not changing pitch if System::playDSP was used.
    • +
    • Core API - Fix crash when setting 0 or invalid pitch.
    • +
    • Studio API - Fix for some allocations not propagating FMOD_ERR_MEMORY errors.
    • +
    • Studio API - Fix for memory leak when failing to load a bank.
    • +
    +

    26/08/13 1.01.14 - Studio API patch release

    +

    Fixes:

    +
      +
    • Core API - Fix crash if adding an FMOD_DSP_TYPE_FADER dsp to a channelgroup.
    • +
    • Core API - Xbox One - Internal WASAPI (mmdevapi.dll) threads will now have their affinity set to match the FMOD feeder thread.
    • +
    +

    Notes:

    +
      +
    • Xbox One - Now built with August XDK.
    • +
    +

    19/08/13 1.01.13 - Studio API patch release

    +

    Features:

    +
      +
    • +

      Studio API - Global mixer strips will now be automatically cleaned up when when the events routed into them complete.

      +
    • +
    • +

      Studio API - Improved performance of Studio::System::Update by removing stalls waiting on the mixer the complete.

      +
    • +
    +

    Fixes:

    +
      +
    • Core API - Channel::setPitch () now returns an error if a NaN is passed in. Fixes crashes occuring later in the mixer thread.
    • +
    • Studio API - Fixed sustain points at the start of the timeline not working
    • +
    • Studio API - Fixed sustain point keyoff incorrectly being ignored if the cursor is not currently sustaining
    • +
    • Studio API - Fixed sustain point keyoff incorrectly skipping sustain points repeatedly when looping
    • +
    +

    Notes:

    +
      +
    • Studio API - Changed behavior of Studio::EventInstance::getCue to return FMOD_ERR_INVALID_PARAM if the event contains no sustain points.
    • +
    +

    12/08/13 1.01.12 - Studio API patch release

    +

    Features:

    +
      +
    • Added FMOD SoundBank Generator tool for creating .fsb files. Both a GUI version (fsbank.exe) and a command line version (fsbankcl.exe) are provided.
    • +
    +

    Fixes:

    +
      +
    • Core API - Fix FSB Vorbis seek table containing an invalid entry at the end.
    • +
    • Core API - Fix cpu stall when using System::playDSP. Also if using oscillator in studio.
    • +
    • Core API - Xbox One - Fixed rare crash on System::init when using WASAPI.
    • +
    +

    05/08/13 1.01.11 - Studio API patch release

    +

    Fixes:

    +
      +
    • Studio API - Fixed resource leak.
    • +
    • Studio API - Fixed a crash when releasing an event instance with sub events.
    • +
    • Core API - Fixed FMOD_SYSTEM_CALLBACK_MEMORYALLOCATIONFAILED not being passed to the application.
    • +
    • Core API - PS4 - Fix crashes caused by out-of-memory conditions. FMOD_ERR_MEMORY is now returned correctly.
    • +
    • Core API - Xbox One - Fixed race condition that causes a hang when playing compressed XMA samples and streams at the same time.
    • +
    • Core API - Xbox One - Fixed leak of SHAPE contexts that would cause createSound to fail if playing and releasing lots of XMA streams.
    • +
    • Core API - Xbox One & Win - Fixed surrounds and rears being swapped in 7.1.
    • +
    +

    29/07/13 1.01.10 - Studio API patch release

    +

    Important:

    +
      +
    • Studio API - Changed .bank file format - API is backward compatible but must be upgraded for compatibility with Studio tool 1.01.10 or newer.
    • +
    +

    Fixes:

    +
      +
    • Studio API - Fixed plugin effect sounds not working in game.
    • +
    • Studio API - Fixed a crash in Studio::System::update after calling Studio::EventDescription::releaseAllInstances
    • +
    • Studio API - Fixed sustain points at the start of the timeline not working
    • +
    • Studio API - Fixed sustain point keyoff incorrectly being ignored if the cursor is not currently sustaining
    • +
    • Studio API - Fixed sustain point keyoff incorrectly skipping sustain points repeatedly when looping
    • +
    • Studio API - Fixed a crash when unloading a bank that contains a nested event that is currently playing
    • +
    • Studio API - Fixed Studio::System::update sometimes failing with FMOD_ERR_INTERNAL and leaving the system in an inconsistent state
    • +
    • Core API - Xbox One - Fixed FMOD_CREATECOMPRESSEDSAMPLE XMA playback issues.
    • +
    +

    Notes:

    +
      +
    • Studio API - Changed behavior of Studio::EventInstance::getCue to return FMOD_ERR_INVALID_PARAM if the event contains no sustain points.
    • +
    +

    22/07/13 1.01.09 - Studio API patch release

    +

    Important:

    +
      +
    • Core API - Fixed rare crash in mixer.
    • +
    +

    Features:

    +
      +
    • Studio API - Fixed spawning sounds not playing at correct 3D position.
    • +
    • Studio API - Fixed 40ms of latency getting added for each layer of event sound nesting.
    • +
    • Core API - Optimized mixer by about 30% in some configurations.
    • +
    +

    Fixes:

    +
      +
    • Core API - Remove FMOD_CHANNELCONTROL union, used in ChannelControl type callbacks, as it was incorrect and using it as a union would have lead to corruption/crash. A simple opaque FMOD_CHANNELCONTROL type is now used for callbacks, and the user should just cast to the relevant channel or channelgroup type.
    • +
    • Core API - Fixed fade point interpolation on channels with pitch.
    • +
    • Core API - Fixed race condition when channels were reused after stopping.
    • +
    • Core API - Xbox One - Fixed hang for short (2KB) XMA files.
    • +
    • Core API - Xbox One - Fixed incorrect seek offset for XMA files.
    • +
    • Core API - PS4 - Added support for AT9 streams with greater than 2 channels.
    • +
    • Studio API - PS4 - Fixed crash when Handle derived classes went out of scope after the dynamic lib was unloaded
    • +
    +

    Notes:

    +
      +
    • PS4 - Now built with SDK 1.0.
    • +
    +

    15/07/13 1.01.08 - Studio API patch release

    +

    Features:

    +
      +
    • Studio API - Added Studio::EventDescription::getMinimumDistance
    • +
    • Studio API - Added Studio::EventDescription::isStream
    • +
    +

    Fixes:

    +
      +
    • Core API - Fixed crash / corruption from DSP Fader/Panner objects.
    • +
    • Core API - Fixed mod/s3m/xm/mid playback.
    • +
    • Studio API - Fixed Studio::EventDescription::isOneshot () incorrectly returning true for an event that has a loop on the logic track.
    • +
    • Linux - Fixed crash on playback of certain CELT streams.
    • +
    • Xbox One - Fixed potential hangs with compressed XMA samples.
    • +
    • Xbox One - Fixed potential silence if XMA sample rate was not one of 24K, 32K, 44.1K or 48K.
    • +
    +

    10/07/13 1.01.07 - Studio API patch release

    +

    Fixes:

    +
      +
    • Core API - Fix "Sample Rate Change" tag from passing through 0 rate when EOF was hit on certain MP3 files.
    • +
    • Core API - Fix crash when using FMOD_CREATECOMPRESSEDSAMPLE introduced in 1.01.06
    • +
    • Core API - iOS - Fixed crash when using DSP Echo.
    • +
    • Core API - iOS - Fixed crash in mixer due to misaligned buffers.
    • +
    +

    08/07/13 1.01.06 - Studio API patch release

    +

    Features:

    +
      +
    • XboxOne - Officially added support for XMA. Please note this requires the July XDK to avoid a hang.
    • +
    • Studio API - Added Studio::ParameterInstance::getDescription
    • +
    • Studio API - Added EventDescription getParameter, getParameterCount and getParameterByIndex functions
    • +
    +

    Fixes:

    +
      +
    • Fix Sound userdata being overwritten when FMOD_SOUND_NONBLOCKCALLBACK was called for a 2nd or more time.
    • +
    • Core API - Fix rare crash in mixer when releasing a ChannelGroup
    • +
    • Core API - Fix 3D Panner DSPs and Studio Event 3d volumes not being considered by virtual voice system.
    • +
    • Core API - Fixed compressor sounding erratic and unresponsive
    • +
    • Studio API - Fixed clicks when a Studio::ParameterInstance::setValue call causes sounds to be cut off
    • +
    +

    Notes:

    +
      +
    • XboxOne - Now built with July XDK.
    • +
    • Core API - Changed FMOD_DSP_TYPE_PAN FMOD_DSP_PAN_STEREO_POSITION parameter to go from -100 to 100.
    • +
    • Core API - Changed FMOD_DSP_TYPE_COMPRESSOR FMOD_DSP_COMPRESSOR_ATTACK parameter to go from 0.1 to 500ms.
    • +
    +

    28/06/13 1.01.05 - Studio API patch release

    +

    Important:

    +
      +
    • Core API - Changed .fsb file format - ALL BANKS MUST BE REBUILT
    • +
    • Studio API - Changed .bank file format - ALL BANKS MUST BE REBUILT
    • +
    +

    Features:

    + +

    Fixes:

    +
      +
    • Core API - PS4 - Improved AT9 decoding performance, fixed issue with when a sound has loop points not aligned to frame size, fixed seamless looping playback glitches.
    • +
    • Core API - Fixed bug that was causing virtual channels to stop prematurely.
    • +
    • Core API - Fixed fade points leaking when channels go virtual.
    • +
    +

    Notes:

    +
      +
    • Studio API - Effect data parameter buffers are now 16-byte aligned (128-byte aligned on PS3)
    • +
    • Studio API - Added automatic header version verification to Studio::System::create
    • +
    +

    19/06/13 1.01.04 - Studio API patch release

    +

    Fixes:

    +
      +
    • Core API - Fix rare crash with Fader DSP unit.
    • +
    • Studio API - Fixed some effects causing events to not stop correctly
    • +
    • Studio API - Fixed multiple concurrent playbacks of one event sometimes failing with FMOD_ERR_SUBSOUNDS returned from Studio::System::update
    • +
    +

    Notes:

    + +

    07/06/13 1.01.03 - Studio API patch release

    +

    Features:

    + +

    Fixes:

    +
      +
    • Core API - Fixed silence in certain DSP configurations.
    • +
    • Core API - Fixed virtual channels not stopping correctly when a parent channelgroup stops due to an end delay
    • +
    • Core API - Fixed virtual channels not cleaning up fade points correctly
    • +
    • Core API - Fixed fade points being ignored when channels go from virtual to non-virtual
    • +
    • Studio API - Fixed crash when playing a multisound after unloading and reloading it's bank.
    • +
    • Studio API - Implemented Studio::Bank::loadSampleData, Studio::Bank::unloadSampleData and Studio::Bank::getSampleLoadingState (they previously did nothing)
    • +
    • Studio API - Fixed crashes and unexpected behavior with sidechains when they are connected to multiple compressors.
    • +
    • Studio API - Fixed a linker error when calling handle assignment operators
    • +
    • Studio API - Fixed a crash in the game when adding a sound to an event while connected via Live Update
    • +
    +

    Notes:

    +
      +
    • Core API - Specific parameter description structures like FMOD_DSP_PARAMETER_DESC_FLOAT no longer inherit from FMOD_DSP_PARAMETER_DESC; instead, FMOD_DSP_PARAMETER_DESC includes a union of all the specific structures with floatdesc, intdesc, booldesc and datadesc members. The FMOD_DSP_INIT_PARAMDESC_xxxx macros have been updated to reflect this.
    • +
    • PS4 - Now built with SDK 0.930.060.
    • +
    +

    31/05/13 1.01.02 - Studio API patch release

    +

    Fixes:

    +
      +
    • Studio API - Fixed getMixerStrip not returning a valid handle when retrieving a VCA.
    • +
    +

    30/05/13 1.01.01 - Studio API patch release

    +

    Fixes:

    +
      +
    • Core API - Fix rare crash in DSPFader.
    • +
    • Studio API - Studio::EventInstance::getParameter and Studio::EventInstance::getCue now use case-insensitive name comparison
    • +
    +

    Notes:

    +
      +
    • Studio API - Renamed Studio::EventInstance::getNumCues to Studio::EventInstance::getCueCount
    • +
    +

    27/05/13 1.01.00 - Studio API minor release

    +

    Important:

    +
      +
    • Studio API - Changed .bank file format - ALL BANKS MUST BE REBUILT
    • +
    +

    Features:

    + +

    Fixes:

    +
      +
    • Core API - Fixed FSB Vorbis not working with encryption key enabled.
    • +
    • Core API - Fixed virtual voices not respecting ChannelControl::setDelay
    • +
    • Core API - Fixed parameter index validation when getting/setting DSP parameters.
    • +
    • Core API - Fixed reverb not always idling when it should.
    • +
    • Core API - Fixed bug with loop count being incorrectly set to infinite
    • +
    • Core API - Optimised Echo DSP effect on x86/x64 architectures
    • +
    • Core API - Fixed ChannelControl::set3DLevel, ChannelControl::set3DSpeakerSpread and stereo 3d sounds not working
    • +
    • Core API - Fixed flange effect not updating 'rate' parameter if the rate was set before adding it to a channel or channelgroup or system object.
    • +
    • Core API - PS4 - Added support for music, voice, personal device and pad speaker routing. See System::AttachChannelGroupToPort and fmod_ps4.h
    • +
    • Core API - PS4 - Added dynamic linking option.
    • +
    • Studio API - Fixed stop/release behaviour of event instances containing logic markers.
    • +
    • Studio API - Fixed memory corruption in Studio::System::release
    • +
    • Studio API - Fixed FMOD_STUDIO_STOP_ALLOWFADEOUT cutting off delay and reverb
    • +
    • PS4 - Fixed closing the FMOD::System causing platform wide networking to be shutdown even if the system did not initialize it.
    • +
    +

    Notes:

    +
      +
    • XboxOne - Now built with April XDK.
    • +
    • PS4 - Now built with SDK 0.930.
    • +
    +

    09/05/13 1.00.03 - Studio API patch release

    +

    Features:

    +
      +
    • Core API - Added memory callbacks for DSP plugins
    • +
    +

    Fixes:

    +
      +
    • Core API - Fixed true peak calculation in loudness meter
    • +
    • Core API - Fix thread related crash in fader DSP and possibly panner DSP.
    • +
    • Studio API - Fixed automatic angle parameter calculation
    • +
    +

    12/04/13 1.00.02 - Studio API patch release

    +

    Fixes:

    +
      +
    • Studio API - Fixed snapshots sometimes not working on some properties
    • +
    • Studio API - Fixed VCAs applying fader level twice to controlled buses
    • +
    +

    09/04/13 1.00.01 - Studio API patch release

    +

    Important:

    +
      +
    • Studio API - Changed .bank file format - ALL BANKS MUST BE REBUILT
    • +
    +

    Features:

    +
      +
    • PS4 & XboxOne - Reduced CPU usage with optimized SSE and AVX functions.
    • +
    +

    Fixes:

    +
      +
    • Core API - Fix potential crash when stopping and starting sounds quickly and a leak for FMOD_CREATECOMPRESSED codecs which made all sounds go virtual.
    • +
    • Studio API - Fixed a crash when connecting to the game via Live Update
    • +
    • Studio API - Fixed serialization of snapshots with automation
    • +
    +

    Notes:

    +
      +
    • XboxOne - Now built with March XDK.
    • +
    +

    25/03/13 1.00.00 - Studio API major release

    +

    Important:

    +
      +
    • Studio API - Changed .bank file format - ALL BANKS MUST BE REBUILT
    • +
    +

    Features:

    +
      +
    • Mac - Reduced CPU usage with optimized SSE and AVX functions.
    • +
    • XboxOne - Added ability to set affinity via FMOD_XboxOne_SetThreadAffinity.
    • +
    • PS4 - Added ability to set affinity via FMOD_PS4_SetThreadAffinity.
    • +
    +

    Fixes:

    +
      +
    • Studio API - Fixed Studio::EventDescription::getLength return incorrect values
    • +
    • Studio API - Fixed playback glitches when sounds are placed end-to-end on the timeline
    • +
    • Studio API - Studio::System::lookupEventID and Studio::System::lookupBusID now ignore case
    • +
    • Studio API - Fixed playback of Sound Scatterers with non-zero pitch
    • +
    • Made return DSPs go idle when there is no input from sends
    • +
    • Fixed sends sometimes going silent if there are multiple sends to a single return
    • +
    • Fixed rare hang in mixer when using setDelay with a pitch on the parent
    • +
    +

    Notes:

    +
      +
    • Studio API - Replaced Studio::System::lookupID with Studio::System::lookupEventID and Studio::System::lookupBusID.
    • +
    • FSBank API will now always encode PCM FSBs as PCM16 instead of deciding based on the source file format.
    • +
    • PS4 - Now built with SDK 0.920.
    • +
    +

    25/02/13 0.02.04 - Studio API patch release

    +

    Fixes:

    + +

    15/02/13 0.02.03 - Studio API patch release

    +

    Features:

    +
      +
    • Studio API - Added Studio::System::lookupID () to look up event IDs from paths (using any string tables present in currently loaded banks).
    • +
    • Studio API - Added Studio::Bank::unload () to free loaded bank data.
    • +
    • Windows - Added optimisations to the 64 bit build.
    • +
    +

    Fixes:

    +
      +
    • Studio API - Fixed a linker error when calling Studio::EventDescription::getID
    • +
    • Fixed constant FMOD_ERR_MEMORY in the TTY and hang if FMOD_ADVANCEDSETTINGS is used with DSPBufferPoolSize being set to 0.
    • +
    • Changed custom DSPs with no shouldiprocess callback to only be processed when their inputs are active.
    • +
    • Fixed high freqency noise coming from send DSP when channel counts mismatches the return DSP.
    • +
    • Fixed metering not working via LiveUpdate
    • +
    • Windows - fixed bug in 5.1 mixing in 32bit builds.
    • +
    +

    Notes:

    +
      +
    • XboxOne - Now built with January XDK.
    • +
    • PS4 - Now built with SDK 0.915.
    • +
    +

    18/01/13 0.02.02 - Studio API patch release

    +

    Important:

    +
      +
    • Studio API - Changed .bank file format - ALL BANKS MUST BE REBUILT
    • +
    • Studio API - Changed function signature for Studio::System::initialize, added STUDIO_FLAGS field
    • +
    +

    Features:

    + +

    Fixes:

    +
      +
    • Studio API - Fixed an internal error on instantiating a VCA when not all of the mixer strips it controls are loaded
    • +
    +

    Notes:

    +
      +
    • XboxOne - Now built with December XDK.
    • +
    +

    11/01/13 0.02.01 - Studio API patch release

    +

    Fixes:

    +
      +
    • Studio API - Fixed Distance and Angle parameters not being created properly by live update
    • +
    • Fixed reverb effect generating denorm floats after silence
    • +
    +

    20/12/12 0.02.00 - Studio API minor release

    +

    Features:

    +
      +
    • Added Xbox360 support.
    • +
    • Added iOS support.
    • +
    • Studio API - Added sub-event instantiation via Studio::EventInstance::createSubEvent
    • +
    +

    23/11/12 0.01.04 - Patch release

    +

    Fixes:

    + +

    9/11/12 0.01.03 - Patch release

    +

    Fixes:

    +
      +
    • Fixed a linker error when using Studio::EventInstance::setPaused
    • +
    +

    29/10/12 0.01.02 - Patch release

    +

    Fixes:

    +
      +
    • Fixed distortion when the distance between 3D sound and the listener is greater than the maximum attenuation distance.
    • +
    • Fixed memory leaks when playing a persistent event and triggering sounds via parameter changes.
    • +
    +

    16/10/12 0.01.00 - Minor release

    +

    Features:

    +
      +
    • Implemented side chaining for FMOD Compressor
    • +
    +

    Fixes:

    +
      +
    • Studio API - Fixed linker error when calling Studio::EventInstance::isVirtual
    • +
    • Studio API - Added log message for asset not found error
    • +
    +

    Notes:

    +
      +
    • Second Developer Preview release
    • +
    +

    28/09/12 0.00.04 - Patch release

    +

    Important:

    +
      +
    • Studio API - Changed .bank file format - ALL BANKS MUST BE REBUILT
    • +
    +

    Features:

    +
      +
    • Add DSP::addSideChain and FMOD_DSP_STATE::sidechainbuffer to allow a DSP unit to support sidechaining from the output of another DSP.
    • +
    +

    Fixes:

    +
      +
    • Studio API - Fixed Event::getParameter () and retrieving the name of a parameter via EventParameter::getInfo ()
    • +
    • Studio API - Added version checking to bank loading, the runtime will return FMOD_ERR_FORMAT when attempting to load an old bank
    • +
    +

    19/09/12 0.00.03 - Patch release

    +

    Fixes:

    +
      +
    • Fix panning issue introduced in 5.00.02
    • +
    • Fix possible crackling noises from mixer optimization in 5.00.02
    • +
    +

    14/09/12 0.00.02 - Patch release

    +

    Important:

    +
      +
    • Studio API - Changed .bank file format - ALL BANKS MUST BE REBUILT
    • +
    +

    Features:

    +
      +
    • Optimized mixer to be 20% faster in some cases.
    • +
    • Studio API - Improved performance of event playback containing mono/stereo tracks
    • +
    +

    Fixes:

    +
      +
    • Studio API - Fixed panning different in game to tool
    • +
    +

    27/08/12 0.00.00 - Initial release

    +

    Notes:

    +
      +
    • First Developer Preview release
    • +
    + + +
    + + + diff --git a/FMOD/doc/FMOD API User Manual/welcome-whats-new-110.html b/FMOD/doc/FMOD API User Manual/welcome-whats-new-110.html new file mode 100644 index 0000000..48169c3 --- /dev/null +++ b/FMOD/doc/FMOD API User Manual/welcome-whats-new-110.html @@ -0,0 +1,57 @@ + + +Welcome to the FMOD Engine | New in FMOD Engine 1.10 + + + + +
    + +
    +

    1. Welcome to the FMOD Engine | New in FMOD Engine 1.10

    + +

    What's New in 1.10?

    +

    This section describes the major features introduced in the 1.10 release. See the Detailed Revision History for information regarding each patch release.

    +

    Spatial audio features

    +

    Windows Sonic spatialization has been added for Windows and Xbox One with a new output plugin FMOD_OUTPUTTYPE_WINSONIC. This will allow FMOD to be rendered using Windows Sonic for headphones, Dolby Atmos for headphones and Dolby Atmos Home Theatre. These technologies allow for a more immersive surround experience which includes height spatialization via 7.1.4 surround speaker mode and dynamic objects.

    +

    To facilitate getting signal into the height speakers FMOD can play 12 channel audio (7.1.4) as a source or upmix with the help of FMOD_DSP_TYPE_PAN and the new FMOD_DSP_PAN_2D_HEIGHT_BLEND parameter.

    +

    For more detail about using spatial audio features with FMOD please refer to the dedicated Spatial Audio section of the Core API Spatializing Sounds chapter.

    + + +
    + + + diff --git a/FMOD/doc/FMOD API User Manual/welcome-whats-new-200.html b/FMOD/doc/FMOD API User Manual/welcome-whats-new-200.html new file mode 100644 index 0000000..29a7527 --- /dev/null +++ b/FMOD/doc/FMOD API User Manual/welcome-whats-new-200.html @@ -0,0 +1,116 @@ + + +Welcome to the FMOD Engine | New in FMOD Engine 2.00 + + + + +
    + +
    +

    1. Welcome to the FMOD Engine | New in FMOD Engine 2.00

    + +

    What's New in 2.00?

    +

    This section describes the major features introduced in the 2.00 release. See the Detailed Revision History for information regarding each patch release.

    +

    Global Parameters

    +

    The Studio API now supports global parameters. These parameters are controlled via the System parameter API and have a single value that is shared between all instances. This feature is intended for parameters like "time of day" or "wind speed" that affect a number of different events at the same time.

    +

    Global parameters are read-only when accessed via an event. They must be accessed via the System parameter API in order to set their value.

    +

    Global Mixer Automation

    +

    The Studio API now supports automation of objects in the global mixer (for example effect parameters or bus volume). Parameters that drive global mixer automation are controlled via the System parameter API.

    +

    New Parameter API

    +

    The Studio parameter API has been updated to support global parameters and provide a more robust fast path for setting parameter values frequently:

    +
      +
    • Indices have been replaced with IDs. These IDs are intended to be cached by game code, and provide fast access while remaining stable if the parameter list changes due to live update or bank loading.
    • +
    • A global parameter API has been added to the Studio::System class.
    • +
    • The Studio::EventDescription parameter functions have been renamed to be consistent with the corresponding System functions.
    • +
    • The '...ByName' parameter functions now accept paths (which can be copied from FMOD Studio) as well as short parameter names.
    • +
    • The FMOD_STUDIO_PARAMETER_DESCRIPTION index field has been replaced with an id field.
    • +
    • A flags field has been added to FMOD_STUDIO_PARAMETER_DESCRIPTION. It provides information on whether the parameter is read-only, automatic, or global.
    • +
    • The deprecated ParameterInstance class has been removed.
    • +
    +

    The following event functions have been added:

    + +

    In addition, to support global parameters, the following system functions have been added:

    + +

    The following functions have been renamed:

    + +

    The following functions have been removed:

    +
      +
    • Studio::EventInstance::getParameterValueByIndex
    • +
    • Studio::EventInstance::setParameterValueByIndex
    • +
    • Studio::EventInstance::setParameterValuesByIndices
    • +
    • Studio::EventInstance::getParameter
    • +
    • Studio::EventInstance::getParameterByIndex
    • +
    • Studio::EventInstance::getParameterCount
    • +
    +

    Sample Data Encryption

    +

    Bank sample data can now be encrypted using FMOD Studio. This implentation is an extension of the Core API FSB encryption feature. To allow bank loading when used with the Studio API, set the key via FMOD_STUDIO_ADVANCEDSETTINGS::encryptionkey. When some banks are unencrypted you can use the FMOD_STUDIO_LOAD_BANK_UNENCRYPTED load flag to ignore the given key.

    +

    LowLevel API Renamed to Core API

    +

    The LowLevel API has been renamed to Core API, other than that it should still function the same way it previously has.

    +
    + + +
    + + + diff --git a/FMOD/doc/FMOD API User Manual/welcome-whats-new-201.html b/FMOD/doc/FMOD API User Manual/welcome-whats-new-201.html new file mode 100644 index 0000000..6df835b --- /dev/null +++ b/FMOD/doc/FMOD API User Manual/welcome-whats-new-201.html @@ -0,0 +1,117 @@ + + +Welcome to the FMOD Engine | New in FMOD Engine 2.01 + + + + +
    + +
    +

    1. Welcome to the FMOD Engine | New in FMOD Engine 2.01

    + +

    What's New in 2.01?

    +

    This section describes the major features introduced in the 2.01 release. See the Detailed Revision History for information regarding each patch release.

    +

    Performance improvements

    +

    With every release of FMOD performance is kept in mind, however particularly with this release a strong focus has been made to improve performance across several key areas.

    +
      +
    • Mixing
    • +
    • Resampling
    • +
    • FSB Vorbis
    • +
    • Convolution reverb
    • +
    • Multiband EQ
    • +
    +

    This process involved improving existing and adding new hardware specific optimization for SSE, AVX, AVX2, AVX-512 and Neon instruction sets which cover all platforms FMOD currently targets.

    +
      +
    • Synthetic benchmarks for Vorbis playback with resampling for mono, stereo, quad, 5.1 and 7.1 showed performance increase of 2-2.5x.
    • +
    • Synthetic benchmarks for Multiband EQ showed performance increase of 2-3x for stereo and higher channel counts.
    • +
    • Replay of commands from existing games showed real world improvements of 20% for a mix of workloads.
    • +
    +

    Thread attributes

    +

    Prior to this release setting thread related attributes such as priority, stack size and thread affinity was split over several API locations (some platform specific).
    +Now we have a unified API for controlling all these values in a single place accessed via Thread_SetAttributes.

    +

    In 2.0 you could override the stack size for the stream, non-blocking and mixer threads using FMOD_ADVANCEDSETTINGS::stackSizeStream, FMOD_ADVANCEDSETTINGS::stackSizeNonBlocking and FMOD_ADVANCEDSETTINGS::stackSizeMixer respectively. These have all been removed in favor of using the new set attributes function as follows:

    +
    FMOD::Thread_SetAttributes(FMOD_THREAD_TYPE_STREAM,      FMOD_THREAD_AFFINITY_GROUP_DEFAULT, FMOD_THREAD_PRIORITY_DEFAULT, stackSizeStream);
    +FMOD::Thread_SetAttributes(FMOD_THREAD_TYPE_NONBLOCKING, FMOD_THREAD_AFFINITY_GROUP_DEFAULT, FMOD_THREAD_PRIORITY_DEFAULT, stackSizeNonBlocking);
    +FMOD::Thread_SetAttributes(FMOD_THREAD_TYPE_MIXER,       FMOD_THREAD_AFFINITY_GROUP_DEFAULT, FMOD_THREAD_PRIORITY_DEFAULT, stackSizeMixer);
    +
    + +

    In 2.0 you could override the affinity for all threads in a platform specific way, e.g. FMOD_UWP_SetThreadAffinity or FMOD_Android_SetThreadAffinity. These have all been removed in favor of using the new set attributes function as follows:

    +
    FMOD::Thread_SetAttributes(FMOD_THREAD_TYPE_MIXER, FMOD_THREAD_AFFINITY_CORE_5);
    +FMOD::Thread_SetAttributes(FMOD_THREAD_TYPE_STREAM, FMOD_THREAD_AFFINITY_CORE_3);
    +
    + +

    Additionally it's now possible to specify the thread priority for all FMOD threads using the same API.

    +

    Minor API differences

    + +

    What's new since 2.00 initial release?

    +

    Improved CPU tracking

    +

    It is now possible to track both inclusive and exclusive CPU usage costs for the Studio update thread via Studio::Bus::getCPUUsage and Studio::EventInstance::getCPUUsage.

    +

    Improved memory tracking

    +

    It is now possible to track the instances and sample data memory usage for each System, Bus and EventInstance via Studio::System::getMemoryUsage, Studio::Bus::getCPUUsage and Studio::EventInstance::getCPUUsage respectively.

    +

    Stadia platform

    +

    Official support for the Stadia platform has been added.

    +

    Minor API differences

    +
    + + +
    + + + diff --git a/FMOD/doc/FMOD API User Manual/welcome-whats-new-202.html b/FMOD/doc/FMOD API User Manual/welcome-whats-new-202.html new file mode 100644 index 0000000..d3aafc0 --- /dev/null +++ b/FMOD/doc/FMOD API User Manual/welcome-whats-new-202.html @@ -0,0 +1,164 @@ + + +Welcome to the FMOD Engine | New in FMOD Engine 2.02 + + + + +
    + +
    +

    1. Welcome to the FMOD Engine | New in FMOD Engine 2.02

    + +

    What's New in 2.02?

    +

    This section describes the major features introduced in the 2.02 release. See the Detailed Revision History for information regarding each patch release.

    +

    Minimum / Maximum Distance

    +

    Events (rather than spatializer DSPs) now encapsulate the functionality of minimum and maximum distance.

    +

    As a result, Studio::EventDescription::getMinimumDistance and Studio::EventDescription::getMaximumDistance have been removed. Those APIs which returned values reported by FMOD spatializers have been replaced with the new Studio::EventDescription::getMinMaxDistance. The new API returns the initial values specified for minimum and maximum distance as set in FMOD Studio. If the minimum or maximum distance have been automated you can query the runtime value per EventInstance using Studio::EventInstance::getMinMaxDistance.

    +

    DSP plugins interested in receiving the new Event level min/max distance information can now add a data parameter of data type FMOD_DSP_PARAMETER_ATTENUATION_RANGE. For compatibility with the old behavior of each spatializer DSP having its own min/max distance, FMOD_DSP_TYPE_PAN and FMOD_DSP_TYPE_OBJECTPAN now have override properties that ignore the Event level values. Resonance Audio has been updated to use the new method, so if the old method is desired please use the Resonance plugin from v2.01.xx.

    +

    Using the new Event level min/max we are able to provide a new built-in parameter, FMOD_STUDIO_PARAMETER_AUTOMATIC_DISTANCE_NORMALIZED, that presents the range from min to max as 0 to 1.

    +

    Labeled Parameters

    +

    Labeled or enumerated parameters have existed in FMOD Studio for a while, however until now they have been unavailable in the API.

    +

    With this release we have introduced a way to query all of the labels associated with one of these parameters. You can fetch labels for global parameters via Studio::System::getParameterLabelByID or Studio::System::getParameterLabelByName and you can fetch labels for local parameter via Studio::EventDescription::getParameterLabelByID, Studio::EventDescription::getParameterLabelByName or Studio::EventDescription::getParameterLabelByIndex. The main purpose of this API is to expose these strings to your level editor for ease of value selection. We recommend still storing the related index in you level data for best performance at runtime when setting enumerated parameters.

    +

    Despite this advice, we also provide some new APIs for setting enumerated parameter with their string value. For global parameters you can use Studio::System::setParameterByIDWithLabel or Studio::System::setParameterByNameWithLabel to lookup the parameter by ID or name respectively then set the value string. For local parameters you can use Studio::EventInstance::setParameterByIDWithLabel or Studio::EventInstance::setParameterByNameWithLabel to lookup the parameter by ID or name respectively then set the value string.

    +

    Ports

    +

    To accompany the addition of Ports into the FMOD Studio tool an additional API was necessary for setting the port index. In the Core API, System::attachChannelGroupToPort would accept both a port type and an index in order to disambiguate between multiple ports targeting the same device type, for example controller speakers. In the Studio API the port type is set on a bus at design time, for ports that require disambiguation you can now use Studio::Bus::setPortIndex to provide that value and Studio::Bus::getPortIndex to query it back.

    +

    With this change we have now unified all port types previously spread over platform specific APIs in the form of FMOD_<PLATFORM>_PORT_TYPE. Now you can find the complete set in the FMOD_PORT_TYPE enumeration with information of availability in each platforms getting started guide.

    +

    Platform Notes

    +
      +
    • Added support for Windows N versions by separating MediaFoundation into a separate DLL
    • +
    • Linux is now built with LLVM / Clang 10, lifting 32bit min-spec to ARMv7 (with NEON) and adding 64bit support
    • +
    • Android minimum API version raised to 16 for 32bit
    • +
    • Renamed PS5 specific APIs and headers from codename to official name
    • +
    +

    API Differences

    +

    APIs that have changed with this release that haven't been called out explicitly above.

    +

    Studio API

    + +

    Core API

    + +

    Output Plugin API

    + +

    Codec Plugin API

    + +

    FSBank API

    + +

    What's new since 2.01 initial release?

    +

    This section describes any major changes that occurred in 2.01.xx leading up to the release of 2.02.

    +

    Platforms

    +
      +
    • Added Apple Silicon, PS5 and Game Core platforms
    • +
    • Added microphone recording support to Stadia
    • +
    • Optimized convolution reverb performance and memory usage
    • +
    +

    API differences

    +

    APIs that have changed with this release that haven't been called out explicitly above.

    +

    Studio API

    + +

    Core API

    +
    + + +
    + + + diff --git a/FMOD/doc/FMOD API User Manual/welcome-whats-new-203.html b/FMOD/doc/FMOD API User Manual/welcome-whats-new-203.html new file mode 100644 index 0000000..0da09ae --- /dev/null +++ b/FMOD/doc/FMOD API User Manual/welcome-whats-new-203.html @@ -0,0 +1,175 @@ + + +Welcome to the FMOD Engine | New in FMOD Engine 2.03 + + + + +
    + +
    +

    1. Welcome to the FMOD Engine | New in FMOD Engine 2.03

    + +

    What's New in 2.03?

    +

    This section describes the major features introduced in the 2.03 release. See the Detailed Revision History for information regarding each patch release.

    +

    Echo Improvements

    +

    Changes in delay time can now be ramped gradually using FMOD_DSP_ECHO_DELAYCHANGEMODE_LERP. This mode is best suited for small changes in delay, otherwise a noticeable warping effect can occur. This warping can be used for simulating doppler, and as an effect with large parameter changes.

    +

    The existing delay change mode of FMOD_DSP_ECHO_DELAYCHANGEMODE_FADE has been made the default, and is best suited to large changes in delay time. With small changes, a noticeable zipper effect can occur.

    +

    EQ Improvements

    +

    The Multiband EQ effect now has low-overhead 6dB highpass and lowpass filters.

    +

    The 6dB lowpass filter can be set with FMOD_DSP_MULTIBAND_EQ_FILTER_LOWPASS_6DB, and uses an efficient one-pole low pass design.

    +

    The 6dB highpass can be set with FMOD_DSP_MULTIBAND_EQ_FILTER_HIGHPASS_6DB, and uses a slightly less efficient one-pole one-zero highpass design.

    +

    FFT Improvements

    +

    Hardware offloading of the FFT DSP can now be enabled using FMOD_DSP_FFT_IMMEDIATE_MODE.

    +

    The RMS value of the analysis band's spectral components can now be queried using FMOD_DSP_FFT_RMS. The analysis band's range can now be set with FMOD_DSP_FFT_BAND_START_FREQ and FMOD_DSP_FFT_BAND_STOP_FREQ.

    +

    FMOD_DSP_FFT_DOWNMIX and FMOD_DSP_FFT_CHANNEL have been added to provide greater control over how the input signal is processed and which part of a spectrum is analyzed.

    +

    Multiband Dynamics

    +

    A new DSP effect has been added, FMOD_DSP_MULTIBAND_DYNAMICS. This plugin can be used to compress or expand the dynamic range of a signal within three separate frequency bands.
    +The Multiband Dynamics plugin operates similarly to the existing FMOD_DSP_COMPRESSOR plugin, providing gain, threshold, ratio, attack and release controls to alter the envelope of the signal. The difference is that the Multiband Dynamics plugin can perform this same processing in a limited frequency range, and rather than just attenuating the signal above the threshold it can also be configured to amplify or attenuate the signal above or below the threshold.

    +

    Here are the different modes available in each band, as well as some suggested use cases for them:

    +

    Upward Compression

    +

    This mode can be set with FMOD_DSP_MULTIBAND_DYNAMICS_MODE_COMPRESS_UP to amplify the signal below the threshold.
    +Upward Compression can be useful for bringing out quieter details in sounds, such as breath in the middle frequency range of vocals, or fret noise in the upper frequency range of a guitar.

    +

    Downward Compression

    +

    This mode can be set with FMOD_DSP_MULTIBAND_DYNAMICS_MODE_COMPRESS_DOWN to attenuate the signal above the threshold.
    +This is the mode that the existing FMOD Compressor uses, and is useful for bringing down harsh percussive sounds, such as plosives and sibilance in the upper frequency range.

    +

    Upward Expansion

    +

    This mode can be set with FMOD_DSP_MULTIBAND_DYNAMICS_MODE_EXPAND_UP to amplify the signal above the threshold.
    +Upward Expansion can easily cause clipping, so use with caution, but can be useful for bringing percussive sounds forward, such as snares in the upper frequency range or explosions in the lower frequency range.

    +

    Downward Expansion

    +

    This mode can be set with FMOD_DSP_MULTIBAND_DYNAMICS_MODE_EXPAND_DOWN to attenuate the signal below the threshold.
    +Downward Epansion be useful for removing noise in the signal, such as bird chirps in the upper frequency range, or room tone in the lower frequency range.

    +

    Passthrough Ports

    +

    A new port type has been added, FMOD_PORT_TYPE_PASSTHROUGH, to bypass the binauralization applied to all sounds by WinSonic and PS5.

    +

    You can use this port type to preserve multi-channel layouts for non-diegetic sounds.

    +

    VR Vibration

    +

    Controller vibration for VR devices that support vibration, such as the PlayStation VR2 Sense™ controller, can now be controlled by FMOD_PORT_TYPE_VR_VIBRATION Ports.

    +

    To use VR vibration ports in the Core API call System::attachChannelGroupToPort, passing in FMOD_PORT_TYPE_VR_VIBRATION for the portType and the controller's user id for the portIndex.

    +

    For the Studio API, you must create a Port Bus in FMOD Studio, set to the "VR Vibration" port type, and route audio into the Port. Then in the API, retrieve the Port with Studio::System::getBus and call Studio::Bus::setPortIndex with the controller's user id to route the Port's audio to the controller.

    +

    Platform Notes

    +
      +
    • Changed default dsp buffer size on Windows from 512 to 1024
    • +
    • Removed Fastcomp support for HTML5
    • +
    • Android minimum version raised to SDK 21 and NDK 26b
    • +
    • Unity Editor minimum version raised to 2021.3
    • +
    • Profiler & FSBank tool minimum macOS version raised to 11.0
    • +
    • Profiler & FSBank tool minimum Windows version raised to Win10 1809
    • +
    • Profiler & FSBank tool minimum Linux GNU C library version raised to GLIBC_2.28
    • +
    +

    API Differences

    +

    APIs that have changed with this release that haven't been called out explicitly above.

    +

    Studio API

    + +

    Core API

    +
      +
    • Modified FMOD_DSP_TYPE_FFT to add FMOD_DSP_FFT_BAND_START_FREQ, FMOD_DSP_FFT_BAND_STOP_FREQ, FMOD_DSP_FFT_DOWNMIX, FMOD_DSP_FFT_CHANNEL, and FMOD_DSP_FFT_IMMEDIATE_MODE
    • +
    • Modified System::getVersion to output build number from second argument
    • +
    • Removed FMOD_DSP_TYPE_ENVELOPEFOLLOWER
    • +
    • Removed FMOD_DSP_TYPE_LADSPAPLUGIN
    • +
    • Removed FMOD_DSP_TYPE_VSTPLUGIN
    • +
    • Removed FMOD_DSP_TYPE_WINAMPPLUGIN
    • +
    • Removed FMOD_PORT_INDEX_FLAG_VR_CONTROLLER
    • +
    • Renamed F_CALLBACK to F_CALL
    • +
    • Renamed FMOD_DSP_FFT_DOMINANT_FREQ to FMOD_DSP_FFT_SPECTRAL_CENTROID
    • +
    • Renamed FMOD_DSP_FFT_WINDOW to FMOD_DSP_FFT_WINDOW_TYPE
    • +
    • Renamed FMOD_DSP_FFT_WINDOWTYPE enum value to FMOD_DSP_FFT_WINDOW_TYPE
    • +
    +

    What's New Since 2.02 Initial Release?

    +

    This section describes any major changes that occurred in 2.02.xx leading up to the release of 2.03.

    +

    Platforms

    +
      +
    • Removed support for Stadia
    • +
    • Added Open Harmony platform
    • +
    • Added support for Vision Pro, and Windows arm64 devices
    • +
    • Added support for hardware offloaded convolution reverb on XSX and PS5
    • +
    • Added support for hardware echo cancellation on Android and iOS
    • +
    +

    API Differences

    +

    APIs that have changed with this release that haven't been called out explicitly above.

    +

    Studio API

    + +

    Core API

    + +

    FSBank API

    +
    + + +
    + + + diff --git a/FMOD/doc/FMOD API User Manual/welcome.html b/FMOD/doc/FMOD API User Manual/welcome.html new file mode 100644 index 0000000..9e6899a --- /dev/null +++ b/FMOD/doc/FMOD API User Manual/welcome.html @@ -0,0 +1,57 @@ + + +Welcome to the FMOD Engine + + + + +
    + +
    +

    1. Welcome to the FMOD Engine

    +

    Welcome to the FMOD Engine User Manual. Here you will find information regarding the functionality and use of the FMOD Engine and all of its APIs.

    +

    If you want your team to design sound for your game using a user-friendly DAW-like interface, the best starting point is the Studio API guide used alongside the Studio API reference. The Studio API plays back content created in FMOD Studio, our adaptive audio content creation tool. Studio's data-driven approach and rich graphical user interface make audio behaviors easily accessible and editable to sound designers.

    +

    If your project has custom requirements that go beyond what the Studio API offers, the Core API provides fast and flexible access to low-level audio primitives. To learn more about the Core API, start with the Core API: Key Concepts chapter, which introduces the fundamental concepts on which the FMOD Engine is built.

    +

    Whether you're developing with the Studio API or Core API, it's important to consider your target platform and any specific functionality, compatibility and requirements it may have. You can see this information in the platform details chapter.

    +

    If you are a plug-in developer, read the Plug-in API Reference for the particular type of plug-in you're interested in creating.

    +

    Additionally, to integrate the creation of compressed assets using the FSB file format into your tools and development pipelines, use the FSBank API reference.

    +

    If you have used the FMOD Engine before and are migrating to a newer major version of FMOD, make sure to check out the "New in FMOD Engine" sections below for information on new, changed and removed APIs.

    +

    For information on using any FMOD example code from this documentation in your own programs, please visit https://www.fmod.com/legal.

    + + +
    + + + diff --git a/FMOD/doc/LICENSE.TXT b/FMOD/doc/LICENSE.TXT new file mode 100644 index 0000000..2ce86fa --- /dev/null +++ b/FMOD/doc/LICENSE.TXT @@ -0,0 +1,1053 @@ + FMOD END USER LICENCE AGREEMENT + =============================== + +This End User Licence Agreement (EULA) is a legal agreement between you and +Firelight Technologies Pty Ltd (ACN 099 182 448) (us or we) and governs your +use of FMOD Studio and FMOD Engine, together the Software. + +1. GRANT OF LICENCE + +1.1 FMOD Studio + +This EULA grants you the right to use FMOD Studio, being the desktop +application for adaptive audio content creation, for all use, including +Commercial use, subject to the following: + + i. FMOD Studio is used to create content for use with the FMOD Engine + only; + ii. FMOD Studio is not redistributed in any form. + +1.2 FMOD Engine + +This EULA grants you the right to use the FMOD Engine, 'FMOD Ex' or 'FMOD 3' +being the run-time engines for adaptive audio playback, without payment, for +personal (hobbyist), educational (students and teachers) or Non-Commercial use, +subject to the following: + + i. FMOD Engine is integrated and redistributed in a software application + (Product) only; + ii. FMOD Engine is not distributed as part of a game engine or tool set; + iii. FMOD Engine is not used in any Commercial enterprise or for any + Commercial production or subcontracting, except for the purposes of + Evaluation or Development of a Commercial Product; + iv. Non-Commercial use does not involve any form of monetisation, + sponsorship or promotion; + v. Product includes attribution in accordance with Clause 3. + +This EULA grants you the right to use FMOD Engine, for limited Commercial +use, subject to the following: + + i. Development budget of the project is less than $600k USD (Refer to + https://www.fmod.com/licensing#licensing-faq) for information); + ii. Total gross revenue / funding per year for the developer, before + expenses, is less than $200k USD (Refer to + https://www.fmod.com/licensing#licensing-faq for information); + iii. FMOD Engine is integrated and redistributed in a game application + (Product) only; + iv. FMOD Engine is not distributed as part of a game engine or tool set; + v. FMOD Engine is not distributed as part of a Product with the intent + to be commercially exploited by another business or institution; + vi. Project is registered in your profile page at + https://www.fmod.com/profile#projects; + vii. Product includes attribution in accordance with Clause 3. + +This EULA does not grant you the right to use 'FMOD Ex' or 'FMOD 3', for +Commercial use. A custom commercial license must be acquired from Firelight +Technologies by contacting sales@fmod.com. + +1.3 FMOD SDK + +This EULA grants you the right to use the FMOD SDK, interfacing either 'FMOD +Engine', 'FMOD Ex' or 'FMOD 3', comprising the programming interface +specification, documentation and examples subject to the following: + + i. FMOD SDK is used to develop a software application using the FMOD + Engine; + ii. FMOD SDK is used to develop an external DSP, Output or Codec plugin; + iii. FMOD SDK files are not be distributed with the exception of the FMOD + Engine run-time libraries (.DLL, .SO for example). + +1.4 FMOD example code and media + +This EULA grants you the right to use FMOD example code, being all or snippets +of source code files located in the FMOD API examples folder and scripting +examples in the documentation, for all use, including Commercial use, subject +to the following: + + i. Media files included in FMOD examples, including wav, ogg, mp3, fsb + and bank files, are not to be redistributed. + +2.OTHER USE + +For all Commercial use, and any Non Commercial use not permitted by this +license, a separate license is required. Refer to www.fmod.com/licensing for +information. + +3. CREDITS + +All Products require an in game credit line which must include the words "FMOD" +and "Firelight Technologies Pty Ltd." Refer to www.fmod.com/attribution for +examples. + +4. INTELLECTUAL PROPERTY RIGHTS + +We are and remain at all times the owner of the Software (including all +intellectual property rights in or to the Software). For the avoidance of doubt, +nothing in this EULA may be deemed to grant or assign to you any proprietary or +ownership interest or intellectual property rights in or to the Software other +than the rights licensed pursuant to Clause 1. + +You acknowledge and agree that you have no right, title or interest in and to +the intellectual property rights in the Software. + +5. SECURITY AND RISK + +You are responsible for protecting the Software and any related materials at all +times from unauthorised access, use or damage. + +6. WARRANTY AND LIMITATION OF LIABILITY + +The Software is provided by us “as is†and, to the maximum extent permitted by +law, any express or implied warranties of any kind, including (but not limited +to) all implied warranties of merchantability and fitness for a particular +purpose are disclaimed. + +In no event shall we (and our employees, contractors and subcontractors), +developers and contributors be liable for any direct, special, indirect or +consequential damages whatsoever resulting from loss of data or profits, whether +in an action of contract, negligence or other tortious conduct, arising out of +or in connection with the use or performance of the Software. + +7. OGG VORBIS CODEC + +FMOD uses the Ogg Vorbis codec © 2002, Xiph.Org Foundation. + +Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + + i. Redistributions of source code must retain the above copyright notice, + the list of conditions and the following disclaimer. + + ii. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other material provided with the distribution. + + iii. Neither the name of the Xiph.org Foundation nor the names of its + contributors may be used to endorse or promote products derived from this + software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND +CONTRIBUTORS “AS IS†AND ANY EXPRESS OR IMPLIED WARRANTIES, +INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT +OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR +BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF +LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +8. RESONANCE AUDIO SDK + +FMOD includes Resonance Audio SDK, licensed under the Apache Licence, Version +2.0 (the Licence); you may not use this file except in compliance with the +License. You may obtain a copy of the License at: + +http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software distributed +under the License is distributed on an “AS IS†BASIS, WITHOUT WARRANTIES OR +CONDITIONS OF ANY KIND, either express or implied. See the License for the +specific language governing permissions and limitations under the License. + +8. ANDROID PLATFORM CODE + +Copyright (C) 2010 The Android Open Source Project All rights reserved. + +Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + + * Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS +FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS +OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED +AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT +OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +SUCH DAMAGE. + +9. AUDIOMOTORS DEMO CONTENT + +The audiogaming_audiomotors_demo_engine.agp file is provided for evaluation +purposes only and is not to be redistributed. AudioMotors V2 Pro is required to +create your own engine content. Refer to https://lesound.io for information. + +10. Qt Toolkit + +FMOD uses Qt Toolkit Copyright (C) 2017 The Qt Company Ltd under the +GNU Lesser General Public License version 3. + +FMOD dynamically links to the unmodified Qt libraries, as provided by +The Qt Company in the pre-compiled binary format. If unable to obtain +source code from The Qt Company, we offer to provide it via the support +options available to all users outlined on our website. + +------------------------------------------------------------------------- + + + GNU GENERAL PUBLIC LICENSE + Version 3, 29 June 2007 + + Copyright (C) 2007 Free Software Foundation, Inc. + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The GNU General Public License is a free, copyleft license for +software and other kinds of works. + + The licenses for most software and other practical works are designed +to take away your freedom to share and change the works. By contrast, +the GNU General Public License is intended to guarantee your freedom to +share and change all versions of a program--to make sure it remains free +software for all its users. We, the Free Software Foundation, use the +GNU General Public License for most of our software; it applies also to +any other work released this way by its authors. You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +them if you wish), that you receive source code or can get it if you +want it, that you can change the software or use pieces of it in new +free programs, and that you know you can do these things. + + To protect your rights, we need to prevent others from denying you +these rights or asking you to surrender the rights. Therefore, you have +certain responsibilities if you distribute copies of the software, or if +you modify it: responsibilities to respect the freedom of others. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must pass on to the recipients the same +freedoms that you received. You must make sure that they, too, receive +or can get the source code. And you must show them these terms so they +know their rights. + + Developers that use the GNU GPL protect your rights with two steps: +(1) assert copyright on the software, and (2) offer you this License +giving you legal permission to copy, distribute and/or modify it. + + For the developers' and authors' protection, the GPL clearly explains +that there is no warranty for this free software. For both users' and +authors' sake, the GPL requires that modified versions be marked as +changed, so that their problems will not be attributed erroneously to +authors of previous versions. + + Some devices are designed to deny users access to install or run +modified versions of the software inside them, although the manufacturer +can do so. This is fundamentally incompatible with the aim of +protecting users' freedom to change the software. The systematic +pattern of such abuse occurs in the area of products for individuals to +use, which is precisely where it is most unacceptable. Therefore, we +have designed this version of the GPL to prohibit the practice for those +products. If such problems arise substantially in other domains, we +stand ready to extend this provision to those domains in future versions +of the GPL, as needed to protect the freedom of users. + + Finally, every program is threatened constantly by software patents. +States should not allow patents to restrict development and use of +software on general-purpose computers, but in those that do, we wish to +avoid the special danger that patents applied to a free program could +make it effectively proprietary. To prevent this, the GPL assures that +patents cannot be used to render the program non-free. + + The precise terms and conditions for copying, distribution and +modification follow. + + TERMS AND CONDITIONS + + 0. Definitions. + + "This License" refers to version 3 of the GNU General Public License. + + "Copyright" also means copyright-like laws that apply to other kinds of +works, such as semiconductor masks. + + "The Program" refers to any copyrightable work licensed under this +License. Each licensee is addressed as "you". "Licensees" and +"recipients" may be individuals or organizations. + + To "modify" a work means to copy from or adapt all or part of the work +in a fashion requiring copyright permission, other than the making of an +exact copy. The resulting work is called a "modified version" of the +earlier work or a work "based on" the earlier work. + + A "covered work" means either the unmodified Program or a work based +on the Program. + + To "propagate" a work means to do anything with it that, without +permission, would make you directly or secondarily liable for +infringement under applicable copyright law, except executing it on a +computer or modifying a private copy. Propagation includes copying, +distribution (with or without modification), making available to the +public, and in some countries other activities as well. + + To "convey" a work means any kind of propagation that enables other +parties to make or receive copies. Mere interaction with a user through +a computer network, with no transfer of a copy, is not conveying. + + An interactive user interface displays "Appropriate Legal Notices" +to the extent that it includes a convenient and prominently visible +feature that (1) displays an appropriate copyright notice, and (2) +tells the user that there is no warranty for the work (except to the +extent that warranties are provided), that licensees may convey the +work under this License, and how to view a copy of this License. If +the interface presents a list of user commands or options, such as a +menu, a prominent item in the list meets this criterion. + + 1. Source Code. + + The "source code" for a work means the preferred form of the work +for making modifications to it. "Object code" means any non-source +form of a work. + + A "Standard Interface" means an interface that either is an official +standard defined by a recognized standards body, or, in the case of +interfaces specified for a particular programming language, one that +is widely used among developers working in that language. + + The "System Libraries" of an executable work include anything, other +than the work as a whole, that (a) is included in the normal form of +packaging a Major Component, but which is not part of that Major +Component, and (b) serves only to enable use of the work with that +Major Component, or to implement a Standard Interface for which an +implementation is available to the public in source code form. A +"Major Component", in this context, means a major essential component +(kernel, window system, and so on) of the specific operating system +(if any) on which the executable work runs, or a compiler used to +produce the work, or an object code interpreter used to run it. + + The "Corresponding Source" for a work in object code form means all +the source code needed to generate, install, and (for an executable +work) run the object code and to modify the work, including scripts to +control those activities. However, it does not include the work's +System Libraries, or general-purpose tools or generally available free +programs which are used unmodified in performing those activities but +which are not part of the work. For example, Corresponding Source +includes interface definition files associated with source files for +the work, and the source code for shared libraries and dynamically +linked subprograms that the work is specifically designed to require, +such as by intimate data communication or control flow between those +subprograms and other parts of the work. + + The Corresponding Source need not include anything that users +can regenerate automatically from other parts of the Corresponding +Source. + + The Corresponding Source for a work in source code form is that +same work. + + 2. Basic Permissions. + + All rights granted under this License are granted for the term of +copyright on the Program, and are irrevocable provided the stated +conditions are met. This License explicitly affirms your unlimited +permission to run the unmodified Program. The output from running a +covered work is covered by this License only if the output, given its +content, constitutes a covered work. This License acknowledges your +rights of fair use or other equivalent, as provided by copyright law. + + You may make, run and propagate covered works that you do not +convey, without conditions so long as your license otherwise remains +in force. You may convey covered works to others for the sole purpose +of having them make modifications exclusively for you, or provide you +with facilities for running those works, provided that you comply with +the terms of this License in conveying all material for which you do +not control copyright. Those thus making or running the covered works +for you must do so exclusively on your behalf, under your direction +and control, on terms that prohibit them from making any copies of +your copyrighted material outside their relationship with you. + + Conveying under any other circumstances is permitted solely under +the conditions stated below. Sublicensing is not allowed; section 10 +makes it unnecessary. + + 3. Protecting Users' Legal Rights From Anti-Circumvention Law. + + No covered work shall be deemed part of an effective technological +measure under any applicable law fulfilling obligations under article +11 of the WIPO copyright treaty adopted on 20 December 1996, or +similar laws prohibiting or restricting circumvention of such +measures. + + When you convey a covered work, you waive any legal power to forbid +circumvention of technological measures to the extent such circumvention +is effected by exercising rights under this License with respect to +the covered work, and you disclaim any intention to limit operation or +modification of the work as a means of enforcing, against the work's +users, your or third parties' legal rights to forbid circumvention of +technological measures. + + 4. Conveying Verbatim Copies. + + You may convey verbatim copies of the Program's source code as you +receive it, in any medium, provided that you conspicuously and +appropriately publish on each copy an appropriate copyright notice; +keep intact all notices stating that this License and any +non-permissive terms added in accord with section 7 apply to the code; +keep intact all notices of the absence of any warranty; and give all +recipients a copy of this License along with the Program. + + You may charge any price or no price for each copy that you convey, +and you may offer support or warranty protection for a fee. + + 5. Conveying Modified Source Versions. + + You may convey a work based on the Program, or the modifications to +produce it from the Program, in the form of source code under the +terms of section 4, provided that you also meet all of these conditions: + + a) The work must carry prominent notices stating that you modified + it, and giving a relevant date. + + b) The work must carry prominent notices stating that it is + released under this License and any conditions added under section + 7. This requirement modifies the requirement in section 4 to + "keep intact all notices". + + c) You must license the entire work, as a whole, under this + License to anyone who comes into possession of a copy. This + License will therefore apply, along with any applicable section 7 + additional terms, to the whole of the work, and all its parts, + regardless of how they are packaged. This License gives no + permission to license the work in any other way, but it does not + invalidate such permission if you have separately received it. + + d) If the work has interactive user interfaces, each must display + Appropriate Legal Notices; however, if the Program has interactive + interfaces that do not display Appropriate Legal Notices, your + work need not make them do so. + + A compilation of a covered work with other separate and independent +works, which are not by their nature extensions of the covered work, +and which are not combined with it such as to form a larger program, +in or on a volume of a storage or distribution medium, is called an +"aggregate" if the compilation and its resulting copyright are not +used to limit the access or legal rights of the compilation's users +beyond what the individual works permit. Inclusion of a covered work +in an aggregate does not cause this License to apply to the other +parts of the aggregate. + + 6. Conveying Non-Source Forms. + + You may convey a covered work in object code form under the terms +of sections 4 and 5, provided that you also convey the +machine-readable Corresponding Source under the terms of this License, +in one of these ways: + + a) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by the + Corresponding Source fixed on a durable physical medium + customarily used for software interchange. + + b) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by a + written offer, valid for at least three years and valid for as + long as you offer spare parts or customer support for that product + model, to give anyone who possesses the object code either (1) a + copy of the Corresponding Source for all the software in the + product that is covered by this License, on a durable physical + medium customarily used for software interchange, for a price no + more than your reasonable cost of physically performing this + conveying of source, or (2) access to copy the + Corresponding Source from a network server at no charge. + + c) Convey individual copies of the object code with a copy of the + written offer to provide the Corresponding Source. This + alternative is allowed only occasionally and noncommercially, and + only if you received the object code with such an offer, in accord + with subsection 6b. + + d) Convey the object code by offering access from a designated + place (gratis or for a charge), and offer equivalent access to the + Corresponding Source in the same way through the same place at no + further charge. You need not require recipients to copy the + Corresponding Source along with the object code. If the place to + copy the object code is a network server, the Corresponding Source + may be on a different server (operated by you or a third party) + that supports equivalent copying facilities, provided you maintain + clear directions next to the object code saying where to find the + Corresponding Source. Regardless of what server hosts the + Corresponding Source, you remain obligated to ensure that it is + available for as long as needed to satisfy these requirements. + + e) Convey the object code using peer-to-peer transmission, provided + you inform other peers where the object code and Corresponding + Source of the work are being offered to the general public at no + charge under subsection 6d. + + A separable portion of the object code, whose source code is excluded +from the Corresponding Source as a System Library, need not be +included in conveying the object code work. + + A "User Product" is either (1) a "consumer product", which means any +tangible personal property which is normally used for personal, family, +or household purposes, or (2) anything designed or sold for incorporation +into a dwelling. In determining whether a product is a consumer product, +doubtful cases shall be resolved in favor of coverage. For a particular +product received by a particular user, "normally used" refers to a +typical or common use of that class of product, regardless of the status +of the particular user or of the way in which the particular user +actually uses, or expects or is expected to use, the product. A product +is a consumer product regardless of whether the product has substantial +commercial, industrial or non-consumer uses, unless such uses represent +the only significant mode of use of the product. + + "Installation Information" for a User Product means any methods, +procedures, authorization keys, or other information required to install +and execute modified versions of a covered work in that User Product from +a modified version of its Corresponding Source. The information must +suffice to ensure that the continued functioning of the modified object +code is in no case prevented or interfered with solely because +modification has been made. + + If you convey an object code work under this section in, or with, or +specifically for use in, a User Product, and the conveying occurs as +part of a transaction in which the right of possession and use of the +User Product is transferred to the recipient in perpetuity or for a +fixed term (regardless of how the transaction is characterized), the +Corresponding Source conveyed under this section must be accompanied +by the Installation Information. But this requirement does not apply +if neither you nor any third party retains the ability to install +modified object code on the User Product (for example, the work has +been installed in ROM). + + The requirement to provide Installation Information does not include a +requirement to continue to provide support service, warranty, or updates +for a work that has been modified or installed by the recipient, or for +the User Product in which it has been modified or installed. Access to a +network may be denied when the modification itself materially and +adversely affects the operation of the network or violates the rules and +protocols for communication across the network. + + Corresponding Source conveyed, and Installation Information provided, +in accord with this section must be in a format that is publicly +documented (and with an implementation available to the public in +source code form), and must require no special password or key for +unpacking, reading or copying. + + 7. Additional Terms. + + "Additional permissions" are terms that supplement the terms of this +License by making exceptions from one or more of its conditions. +Additional permissions that are applicable to the entire Program shall +be treated as though they were included in this License, to the extent +that they are valid under applicable law. If additional permissions +apply only to part of the Program, that part may be used separately +under those permissions, but the entire Program remains governed by +this License without regard to the additional permissions. + + When you convey a copy of a covered work, you may at your option +remove any additional permissions from that copy, or from any part of +it. (Additional permissions may be written to require their own +removal in certain cases when you modify the work.) You may place +additional permissions on material, added by you to a covered work, +for which you have or can give appropriate copyright permission. + + Notwithstanding any other provision of this License, for material you +add to a covered work, you may (if authorized by the copyright holders of +that material) supplement the terms of this License with terms: + + a) Disclaiming warranty or limiting liability differently from the + terms of sections 15 and 16 of this License; or + + b) Requiring preservation of specified reasonable legal notices or + author attributions in that material or in the Appropriate Legal + Notices displayed by works containing it; or + + c) Prohibiting misrepresentation of the origin of that material, or + requiring that modified versions of such material be marked in + reasonable ways as different from the original version; or + + d) Limiting the use for publicity purposes of names of licensors or + authors of the material; or + + e) Declining to grant rights under trademark law for use of some + trade names, trademarks, or service marks; or + + f) Requiring indemnification of licensors and authors of that + material by anyone who conveys the material (or modified versions of + it) with contractual assumptions of liability to the recipient, for + any liability that these contractual assumptions directly impose on + those licensors and authors. + + All other non-permissive additional terms are considered "further +restrictions" within the meaning of section 10. If the Program as you +received it, or any part of it, contains a notice stating that it is +governed by this License along with a term that is a further +restriction, you may remove that term. If a license document contains +a further restriction but permits relicensing or conveying under this +License, you may add to a covered work material governed by the terms +of that license document, provided that the further restriction does +not survive such relicensing or conveying. + + If you add terms to a covered work in accord with this section, you +must place, in the relevant source files, a statement of the +additional terms that apply to those files, or a notice indicating +where to find the applicable terms. + + Additional terms, permissive or non-permissive, may be stated in the +form of a separately written license, or stated as exceptions; +the above requirements apply either way. + + 8. Termination. + + You may not propagate or modify a covered work except as expressly +provided under this License. Any attempt otherwise to propagate or +modify it is void, and will automatically terminate your rights under +this License (including any patent licenses granted under the third +paragraph of section 11). + + However, if you cease all violation of this License, then your +license from a particular copyright holder is reinstated (a) +provisionally, unless and until the copyright holder explicitly and +finally terminates your license, and (b) permanently, if the copyright +holder fails to notify you of the violation by some reasonable means +prior to 60 days after the cessation. + + Moreover, your license from a particular copyright holder is +reinstated permanently if the copyright holder notifies you of the +violation by some reasonable means, this is the first time you have +received notice of violation of this License (for any work) from that +copyright holder, and you cure the violation prior to 30 days after +your receipt of the notice. + + Termination of your rights under this section does not terminate the +licenses of parties who have received copies or rights from you under +this License. If your rights have been terminated and not permanently +reinstated, you do not qualify to receive new licenses for the same +material under section 10. + + 9. Acceptance Not Required for Having Copies. + + You are not required to accept this License in order to receive or +run a copy of the Program. Ancillary propagation of a covered work +occurring solely as a consequence of using peer-to-peer transmission +to receive a copy likewise does not require acceptance. However, +nothing other than this License grants you permission to propagate or +modify any covered work. These actions infringe copyright if you do +not accept this License. Therefore, by modifying or propagating a +covered work, you indicate your acceptance of this License to do so. + + 10. Automatic Licensing of Downstream Recipients. + + Each time you convey a covered work, the recipient automatically +receives a license from the original licensors, to run, modify and +propagate that work, subject to this License. You are not responsible +for enforcing compliance by third parties with this License. + + An "entity transaction" is a transaction transferring control of an +organization, or substantially all assets of one, or subdividing an +organization, or merging organizations. If propagation of a covered +work results from an entity transaction, each party to that +transaction who receives a copy of the work also receives whatever +licenses to the work the party's predecessor in interest had or could +give under the previous paragraph, plus a right to possession of the +Corresponding Source of the work from the predecessor in interest, if +the predecessor has it or can get it with reasonable efforts. + + You may not impose any further restrictions on the exercise of the +rights granted or affirmed under this License. For example, you may +not impose a license fee, royalty, or other charge for exercise of +rights granted under this License, and you may not initiate litigation +(including a cross-claim or counterclaim in a lawsuit) alleging that +any patent claim is infringed by making, using, selling, offering for +sale, or importing the Program or any portion of it. + + 11. Patents. + + A "contributor" is a copyright holder who authorizes use under this +License of the Program or a work on which the Program is based. The +work thus licensed is called the contributor's "contributor version". + + A contributor's "essential patent claims" are all patent claims +owned or controlled by the contributor, whether already acquired or +hereafter acquired, that would be infringed by some manner, permitted +by this License, of making, using, or selling its contributor version, +but do not include claims that would be infringed only as a +consequence of further modification of the contributor version. For +purposes of this definition, "control" includes the right to grant +patent sublicenses in a manner consistent with the requirements of +this License. + + Each contributor grants you a non-exclusive, worldwide, royalty-free +patent license under the contributor's essential patent claims, to +make, use, sell, offer for sale, import and otherwise run, modify and +propagate the contents of its contributor version. + + In the following three paragraphs, a "patent license" is any express +agreement or commitment, however denominated, not to enforce a patent +(such as an express permission to practice a patent or covenant not to +sue for patent infringement). To "grant" such a patent license to a +party means to make such an agreement or commitment not to enforce a +patent against the party. + + If you convey a covered work, knowingly relying on a patent license, +and the Corresponding Source of the work is not available for anyone +to copy, free of charge and under the terms of this License, through a +publicly available network server or other readily accessible means, +then you must either (1) cause the Corresponding Source to be so +available, or (2) arrange to deprive yourself of the benefit of the +patent license for this particular work, or (3) arrange, in a manner +consistent with the requirements of this License, to extend the patent +license to downstream recipients. "Knowingly relying" means you have +actual knowledge that, but for the patent license, your conveying the +covered work in a country, or your recipient's use of the covered work +in a country, would infringe one or more identifiable patents in that +country that you have reason to believe are valid. + + If, pursuant to or in connection with a single transaction or +arrangement, you convey, or propagate by procuring conveyance of, a +covered work, and grant a patent license to some of the parties +receiving the covered work authorizing them to use, propagate, modify +or convey a specific copy of the covered work, then the patent license +you grant is automatically extended to all recipients of the covered +work and works based on it. + + A patent license is "discriminatory" if it does not include within +the scope of its coverage, prohibits the exercise of, or is +conditioned on the non-exercise of one or more of the rights that are +specifically granted under this License. You may not convey a covered +work if you are a party to an arrangement with a third party that is +in the business of distributing software, under which you make payment +to the third party based on the extent of your activity of conveying +the work, and under which the third party grants, to any of the +parties who would receive the covered work from you, a discriminatory +patent license (a) in connection with copies of the covered work +conveyed by you (or copies made from those copies), or (b) primarily +for and in connection with specific products or compilations that +contain the covered work, unless you entered into that arrangement, +or that patent license was granted, prior to 28 March 2007. + + Nothing in this License shall be construed as excluding or limiting +any implied license or other defenses to infringement that may +otherwise be available to you under applicable patent law. + + 12. No Surrender of Others' Freedom. + + If conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot convey a +covered work so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you may +not convey it at all. For example, if you agree to terms that obligate you +to collect a royalty for further conveying from those to whom you convey +the Program, the only way you could satisfy both those terms and this +License would be to refrain entirely from conveying the Program. + + 13. Use with the GNU Affero General Public License. + + Notwithstanding any other provision of this License, you have +permission to link or combine any covered work with a work licensed +under version 3 of the GNU Affero General Public License into a single +combined work, and to convey the resulting work. The terms of this +License will continue to apply to the part which is the covered work, +but the special requirements of the GNU Affero General Public License, +section 13, concerning interaction through a network will apply to the +combination as such. + + 14. Revised Versions of this License. + + The Free Software Foundation may publish revised and/or new versions of +the GNU General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + + Each version is given a distinguishing version number. If the +Program specifies that a certain numbered version of the GNU General +Public License "or any later version" applies to it, you have the +option of following the terms and conditions either of that numbered +version or of any later version published by the Free Software +Foundation. If the Program does not specify a version number of the +GNU General Public License, you may choose any version ever published +by the Free Software Foundation. + + If the Program specifies that a proxy can decide which future +versions of the GNU General Public License can be used, that proxy's +public statement of acceptance of a version permanently authorizes you +to choose that version for the Program. + + Later license versions may give you additional or different +permissions. However, no additional obligations are imposed on any +author or copyright holder as a result of your choosing to follow a +later version. + + 15. Disclaimer of Warranty. + + THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY +APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT +HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY +OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, +THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM +IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF +ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + + 16. Limitation of Liability. + + IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS +THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY +GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE +USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF +DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD +PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), +EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF +SUCH DAMAGES. + + 17. Interpretation of Sections 15 and 16. + + If the disclaimer of warranty and limitation of liability provided +above cannot be given local legal effect according to their terms, +reviewing courts shall apply local law that most closely approximates +an absolute waiver of all civil liability in connection with the +Program, unless a warranty or assumption of liability accompanies a +copy of the Program in return for a fee. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +state the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . + +Also add information on how to contact you by electronic and paper mail. + + If the program does terminal interaction, make it output a short +notice like this when it starts in an interactive mode: + + Copyright (C) + This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, your program's commands +might be different; for a GUI interface, you would use an "about box". + + You should also get your employer (if you work as a programmer) or school, +if any, to sign a "copyright disclaimer" for the program, if necessary. +For more information on this, and how to apply and follow the GNU GPL, see +. + + The GNU General Public License does not permit incorporating your program +into proprietary programs. If your program is a subroutine library, you +may consider it more useful to permit linking proprietary applications with +the library. If this is what you want to do, use the GNU Lesser General +Public License instead of this License. But first, please read +. + + +------------------------------------------------------------------------- + + GNU LESSER GENERAL PUBLIC LICENSE + Version 3, 29 June 2007 + + Copyright © 2007 Free Software Foundation, Inc. + Everyone is permitted to copy and distribute verbatim copies of this + license document, but changing it is not allowed. + +This version of the GNU Lesser General Public License incorporates +the terms and conditions of version 3 of the GNU General Public +License, supplemented by the additional permissions listed below. + +0. Additional Definitions. + + As used herein, “this License†refers to version 3 of the GNU Lesser +General Public License, and the “GNU GPL†refers to version 3 of the +GNU General Public License. + + “The Library†refers to a covered work governed by this License, +other than an Application or a Combined Work as defined below. + + An “Application†is any work that makes use of an interface provided +by the Library, but which is not otherwise based on the Library. +Defining a subclass of a class defined by the Library is deemed a mode +of using an interface provided by the Library. + + A “Combined Work†is a work produced by combining or linking an +Application with the Library. The particular version of the Library +with which the Combined Work was made is also called the “Linked +Versionâ€. + + The “Minimal Corresponding Source†for a Combined Work means the +Corresponding Source for the Combined Work, excluding any source code +for portions of the Combined Work that, considered in isolation, are +based on the Application, and not on the Linked Version. + + The “Corresponding Application Code†for a Combined Work means the +object code and/or source code for the Application, including any data +and utility programs needed for reproducing the Combined Work from the +Application, but excluding the System Libraries of the Combined Work. + +1. Exception to Section 3 of the GNU GPL. + + You may convey a covered work under sections 3 and 4 of this License +without being bound by section 3 of the GNU GPL. + +2. Conveying Modified Versions. + + If you modify a copy of the Library, and, in your modifications, a +facility refers to a function or data to be supplied by an Application +that uses the facility (other than as an argument passed when the +facility is invoked), then you may convey a copy of the modified +version: + + a) under this License, provided that you make a good faith effort + to ensure that, in the event an Application does not supply the + function or data, the facility still operates, and performs + whatever part of its purpose remains meaningful, or + + b) under the GNU GPL, with none of the additional permissions of + this License applicable to that copy. + +3. Object Code Incorporating Material from Library Header Files. + + The object code form of an Application may incorporate material from +a header file that is part of the Library. You may convey such object +code under terms of your choice, provided that, if the incorporated +material is not limited to numerical parameters, data structure +layouts and accessors, or small macros, inline functions and templates +(ten or fewer lines in length), you do both of the following: + + a) Give prominent notice with each copy of the object code that + the Library is used in it and that the Library and its use are + covered by this License. + + b) Accompany the object code with a copy of the GNU GPL and this + license document. + +4. Combined Works. + + You may convey a Combined Work under terms of your choice that, taken +together, effectively do not restrict modification of the portions of +the Library contained in the Combined Work and reverse engineering for +debugging such modifications, if you also do each of the following: + + a) Give prominent notice with each copy of the Combined Work that + the Library is used in it and that the Library and its use are + covered by this License. + + b) Accompany the Combined Work with a copy of the GNU GPL and this + license document. + + c) For a Combined Work that displays copyright notices during + execution, include the copyright notice for the Library among + these notices, as well as a reference directing the user to the + copies of the GNU GPL and this license document. + + d) Do one of the following: + + 0) Convey the Minimal Corresponding Source under the terms of + this License, and the Corresponding Application Code in a form + suitable for, and under terms that permit, the user to + recombine or relink the Application with a modified version of + the Linked Version to produce a modified Combined Work, in the + manner specified by section 6 of the GNU GPL for conveying + Corresponding Source. + + 1) Use a suitable shared library mechanism for linking with + the Library. A suitable mechanism is one that (a) uses at run + time a copy of the Library already present on the user's + computer system, and (b) will operate properly with a modified + version of the Library that is interface-compatible with the + Linked Version. + + e) Provide Installation Information, but only if you would + otherwise be required to provide such information under section 6 + of the GNU GPL, and only to the extent that such information is + necessary to install and execute a modified version of the + Combined Work produced by recombining or relinking the Application + with a modified version of the Linked Version. (If you use option + 4d0, the Installation Information must accompany the Minimal + Corresponding Source and Corresponding Application Code. If you + use option 4d1, you must provide the Installation Information in + the manner specified by section 6 of the GNU GPL for conveying + Corresponding Source.) + +5. Combined Libraries. + + You may place library facilities that are a work based on the Library +side by side in a single library together with other library +facilities that are not Applications and are not covered by this +License, and convey such a combined library under terms of your +choice, if you do both of the following: + + a) Accompany the combined library with a copy of the same work + based on the Library, uncombined with any other library + facilities, conveyed under the terms of this License. + + b) Give prominent notice with the combined library that part of + it is a work based on the Library, and explaining where to find + the accompanying uncombined form of the same work. + +6. Revised Versions of the GNU Lesser General Public License. + + The Free Software Foundation may publish revised and/or new versions +of the GNU Lesser General Public License from time to time. Such new +versions will be similar in spirit to the present version, but may +differ in detail to address new problems or concerns. + +Each version is given a distinguishing version number. If the Library +as you received it specifies that a certain numbered version of the +GNU Lesser General Public License “or any later version†applies to +it, you have the option of following the terms and conditions either +of that published version or of any later version published by the +Free Software Foundation. If the Library as you received it does not +specify a version number of the GNU Lesser General Public License, +you may choose any version of the GNU Lesser General Public License +ever published by the Free Software Foundation. + +If the Library as you received it specifies that a proxy can decide +whether future versions of the GNU Lesser General Public License shall +apply, that proxy's public statement of acceptance of any version is +permanent authorization for you to choose that version for the Library. + +--------------------------- +Last updated 17th Jun 2024. \ No newline at end of file diff --git a/FMOD/doc/revision.txt b/FMOD/doc/revision.txt new file mode 100644 index 0000000..c36e072 --- /dev/null +++ b/FMOD/doc/revision.txt @@ -0,0 +1,6542 @@ + +========================================================================================== + REVISION HISTORY : FMOD Studio API + Copyright (c) Firelight Technologies, Pty, Ltd, 2011-2026 + https://www.fmod.com +========================================================================================== + +Legend +------ +Win: Microsoft Windows XboxOne: Microsoft Xbox One +Mac: Apple macOS GameCore: Microsoft Game Core +Linux: Linux PS4: Sony PlayStation 4 +iOS: Apple iOS / tvOS PS5: Sony PlayStation 5 +Android: Google Android Switch: Nintendo Switch +HTML5: JavaScript WebAssembly UWP: Microsoft Universal Windows Platform + +1/4/26 2.03.13 - Studio API minor release (build 162576) +------------------------------------------------------------------------------------------ + +Fixes: +* Studio API - Fixed instruments failing to play audibly when they are triggered + exactly at the destination of a transition timeline with no destination + region. +* Core API - Fixed FMOD_DSP_TYPE_COMPRESSOR and FMOD_DSP_TYPE_MULTIBAND_DYNAMICS + not correctly mixing a sidechain input when its channel count was + different to that of the main signal. +* Core API - Fixed DSP Echo crash when delay time changes. +* Core API - Mac - Fixed examples rendering buttons invisible on certain macOS + / Xcode combinations. +* Core API - Android - Improved AAudio input stream startup time. +* Core API - GameCore - Fixed crash when using hardware convolution reverb. +* Core API - PS4 - Improved logging surrounding AudioOut and Audio3D initialization. +* Core API - PS5 - Improved logging surrounding AudioOut2 and allowed additional + systems to init with spatial objects. +* Unity - Fixed an issue where active Studio Event Emitters could persist + after their owning object was destroyed. +* Unity - Fixed potential for bank references to be lost when updating the + integration. +* Unreal - Improved third party plugin inclusion by removing the need to manually + create a text file. +* Unreal - Enable Unity Build to speed up project compilation. +* Unreal - Removed Precompiled headers and includes. +* Unreal - Fixed events not auditioning in Sequencer and Animations. + +15/01/26 2.03.12 - Studio API minor release (build 160365) +------------------------------------------------------------------------------------------ + +Features: +* Studio API - PS4 - Added haptics support. +* Studio API - Switch - Added haptics support. +* Unity - Added support for NativeArray to avoid Garbage Collection allocations + when loading Addressables or using Studio::System::loadBankMemory. +* Unity - Plugins added to the `Editor` platform will now be loaded when + auditioning events in the Event Browser. +* Unity - Dynamic plugins added to the Editor platform in the integration + settings will now be loaded for auditioning in the Unity editor. + +Fixes: +* Studio API - Fixed live update blocking the game's main thread when swapping + audio files on single instruments that are currently playing. +* Studio API - Win - Fixed haptics conflict between two instances of FMOD, i.e. + Studio + Game for classic rumble motor controllers. +* Studio API - HTML5 - EventDescription::setCallback now returns FMOD_ERR_UNSUPPORTED + rather than causing binding errors at runtime. +* Core API - Fixed click at end of looping PCM sounds that use Channel::setLoopCount. +* Core API - Mac - Fixed potential crash when loading plugins if the path gets + too long. +* Unity - Fixed bank folders containing a dot not working correctly. +* Unity - Fixed deprecation warnings when adding the integration. +* Unreal - Replaced raw object pointers with TObjectPtr. +* Unreal - Fixed encrypted banks not working on MacOS. +* Unreal - Fixed issue where FMODAssetBuilder would wait for confirmation + to delete files in unattended mode. +* Unreal - Fixed FMODAudioComponents logging errors if occlusion parameter + is set in settings but event does not use it. +* Unreal - Fixed getBus error on Editor startup. +* Unreal - Fixed validation steps setting inconsistent Built Banks Output + Directory path. + +18/11/25 2.03.11 - Studio API minor release (build 158528) +------------------------------------------------------------------------------------------ + +Features: +* Studio API - Added support for plug-in instruments that end, detected via a + data parameter of type FMOD_DSP_PARAMETER_DATA_TYPE_FINITE_LENGTH. +* Core API - Added support for DSPs to report when they are finished by returning + FMOD_ERR_FILE_EOF from their process callback. This is used by + System::playDSP to determine when playback should end. + +Fixes: +* Studio API - Fixed incorrect playback after issuing a key off command for a + sustain point that is at the end of a loop around a multi instrument. +* Studio API - Enforced Studio::System::setListenerWeight documented range [0, + 1] and added a warning for incorrect weight/mask combinations. +* Studio API - Fixed a hang in quantization logic on events that have been playing + for many hours. +* Studio API - Mac - Fixed "assertion: 'previousPoint != NULL' failed" log message + when playing events that contain LFO modulators with tempo sync + enabled. +* Studio API - PS5 - Improved performance when memory tracking is enabled. +* Core API - Win - WASAPI and WinSonic recording streams will now be categorized + as "communications" for Windows. +* Core API - Fixed (removed) some benign network related error logs. +* Core API - Fixed Multiband Dynamics ignoring sidechain input on first mix. +* Core API - Fixed some calls to DSP::setDelay not respecting arguments if called + quickly after playsound. +* Unity - Fixed errors caused by loading addressable assets multiple times. +* Unreal - Removed the bStopEventsOutsideMaxDistance setting and associated + functionality, as this feature had multiple issues and needs to + be reworked. + +23/10/25 2.03.10 - Studio API minor release (build 157581) +------------------------------------------------------------------------------------------ + +Features: +* Studio API - Added logging defines to the C# wrappers. +* Unreal - Added bStopEventsOutsideMaxDistance to the integration settings + which controls whether events will be played or stopped when outside + the max attenuation distance. + +Fixes: +* Core API - Fixed potential crash when releasing a streaming sound that has + just transitioned from virtual to real. +* Core API - Fixed virtual streams not ending. +* Core API - C# - Reworked and added new accessors to [[FMOD_DSP_METERING_INFO]] + to avoid Garbage Collector allocations. Note that assigning to + a float[] variable from the peaklevel and rmslevel fields still + causes allocation. +* Core API - Fixed buffer overrun when Multiband Dynamics uses a sidechain and + is in 'linked' mode. +* Core API - Fixed Multiband Dynamics using input signal instead of sidechain + signal when two bands are collapsed. +* Core API - Fixed loop points for a channel not persisting when going virtual, + and a mixer hang if using System::playDSP when going virtual. +* Core API - GameCore - Reduced memory usage of convolution reverb. +* Core API - GameCore - Fixed hardware resource leak causing Channels to go + virtual when they shouldn't. +* Core API - PS4 - Fixed potential AT9 stream hang when transitioning from virtual + to real. +* Core API - PS5 - Fixed Opus sceAjmInstanceDestroy error that causes an instance + leak. +* Unity - Preserve specified banks when updating/changing FMOD integration + version. +* Unity - Updated to preferred method for confirming 64-bit architecture. +* Unity - Fixed plugins being loaded from the wrong location on Windows Arm64. +* Unity - Mac - MacOS fmodstudioL.bundle now defaults to Any CPU instead + of Intel-64 on some Unity versions. +* Unity - Android - Added 16KB alignment metadata for Android plugins to + remove Unity warnings. +* Unreal - Fixed UE5.6.1 FMODCallbackHandler build issue. +* Unreal - Fixed crash when calling FMODAudioComponent API during object + construction. +* Unreal - Fixed issue with no spatial sound resources available for Play-In-Editor. + +05/08/25 2.03.09 - Studio API minor release (build 155273) +------------------------------------------------------------------------------------------ + +Features: +* Core API - Added System::createDSPConnection and updated DSP::addInput with + support for FMOD_DSPCONNECTION_TYPE_PREALLOCATED. +* Core API - Added FMOD_DEBUG_TYPE_VIRTUAL to enable logging for Channel virtual state + changes. +* Core API - iOS - Added suspend_resume example that demonstrates how to handle + suspending and resuming the mixer when interrupted by iOS. +* Unity - Added "Serialize GUIDs Only" setting that disables event path + serialization for Event References. +* Unity - Added support for Windows Arm64. +* Unreal - Added IFMODCallbackHandler interface to run custom configuration code + prior to initialization. + +Fixes: +* Studio API - Fixed sidechain level being incorrect in the first mix after the + sidechain is connected. +* Studio API - Fixed transition timeline source region fade curves failing to make + instruments go completely silent. +* Studio API - Fixed EventDescription::isOneshot returning false if it contains a + non-looping destination region. +* Studio API - Fixed automation of the spectral sidechain modulator's amount property + giving incorrect results when the modulator was targeting non-volume + properties. +* Studio API - Fixed positions reported by EventInstance::getTimelinePosition + pausing shortly before the audio after calling EventInstance::setPaused. +* Core API - Fixed ChannelGroup::setMode(FMOD_2D) for a 3D ChannelGroup not + resetting its pan matrix. +* Core API - Fixed erroneous debug assert when playing a 12 channel signal into + a Pan DSP. +* Core API - PS5 - Fixed audible pop when disconnecting a port. +* Core API - Android - Fixed slow startup times when using AAudio. +* Android / + iOS/Switch - Fix ARM based device panning issue when using a 7.1 mix. +* Unity - Fixed auditioning system initialization failures for CI builds. +* Unity - The Studio Bank Loader will now only wait for samples to be loaded if + the "Pre Load Sample Data" option is enabled. +* Unity - Refined requirements when selecting single and multi platform build + directories in the Setup Wizard to avoid getting the integration + into an invalid state. +* Unreal - Fixed unpause not working correctly when auditioning level sequence. +* Unreal - Fixed excess logging when ending Play-In-Editor and using Sequencer. +* Unreal - Fixed deprecation errors in Xcode. +* Unreal - Fixed crash on launch when using events in GameplayCue. +* Unreal - Fixed crash when using '-nosound' and PlayFMODEventPersistent in + Niagara. +* Unreal - Fixed possible hangs when ending Play-In-Editor while using AudioLink. +* Unreal - Fixed events not triggering when being auditioned in the animation + window with bFollow enabled. + +11/06/25 2.03.08 - Studio API minor release (build 153137) +------------------------------------------------------------------------------------------ + +Features: +* Core API / + Studio API - HTML5 - Added pthread/SharedArrayBuffer support using the fmodP / + fmodstudioP variants of the libraries. + +Fixes: +* Studio API - Fixed sidechain level being ignored when the connected effect is + instantiated after the sidechain. +* Studio API - Fixed parameter initial value being ignored on first playback if + the parameter has a seek modulator. +* Studio API - Fixed command instruments decrementing discrete and labeled parameters + by the wrong amount. +* Core API - Fixed deadlock when adding/removing audio device after call to + System::mixerSuspend. +* Studio API - Fixed changes to delay time on the FMOD Delay effect being ignored + unless the event is playing. +* Core API - Fixed possible crash if FMOD_CREATECOMPRESSEDSAMPLE codec ran out of + memory combined with virtual voices. +* Core API - Android/iOS - Fixed recording not returning after System::mixerResume. +* Core API - Android - All AAudio devices now enumerated regardless of whether + specific devices permissions have been granted. +* Core API - Linux - pthread stack size is now aligned to system page size. +* Core API - Fixed audibility calculation factoring in fader gain value incorrectly + when using sends/returns, leading to voices cutting out while still + audible. +* Unreal - Fixed an issue where Events triggered by the OnEventStopped callback + could continue playing once exiting PIE or unloading a level. +* Unreal - Fixed an issue where banks would not be loaded correctly when validating + FMOD or auditioning events in editor. +* Unity - Fixed crash when passing null to setParameterData. +* Unity - Removed dependency on the Unity UI package. +* Unity - Oneshot events will no longer trigger outside of max distance when + "Stop Events Outside Max Distance" setting is enabled. + +Notes: +* Unity - Added support for Unity 6.1. + +03/04/25 2.03.07 - Studio API minor release (build 150747) +------------------------------------------------------------------------------------------ + +Features: +* Unity - Added support for WeChat Mini Game platform in TuanJie Engine. + +Fixes: +* Studio API - Fixed parameters set to "Hold Value During Playback" changing if + automated by another parameter. +* Core API - Android - Fixed crash when calling into record API while mixer suspended. +* Core API - Fixed DSP::setWetDryMix causing audible output on some DSPs if they + were muted internally, for example FMOD_DSP_TYPE_FADER, or user DSPs + using FMOD_ERR_DSP_SILENCE as a return value. +* Core API - Mac - Fixed FMOD_ERR_OUTPUT_DRIVERCALL being returned on certain + device change events. +* Core API - XSX - Fixed hardware convolution failing to fallback to software + implementation when an invalid impulse response length was provided. +* Core API - Added support for .m3u8 file format. +* Unity - Improved EventReferenceDrawer performance when working with large FMOD + projects. +* Unity - OpenHarmony - Removed need for manual fmod.init call in exported + project's Ability. +* Unity - Added suggestion for line ending requirements to Source Control window of the + Set Up Wizard. +* Unity/Unreal - Filter out benign FMOD_ERR_CHANNEL_STOLEN error. + +Notes: +* Switch - Now built with SDK 19.3.5. + +07/02/25 2.03.06 - Studio API minor release (build 149358) +------------------------------------------------------------------------------------------ + +Features: +* Core API - Android - Added support for Spatial Audio when surround speaker mode is + 5.1 or higher and user has Spatial Audio enabled. +* Unity - Added public property StudioListener::AttenuationObject. +* Unity - Added Chinese localization to Resonance plugin. + +Fixes: +* Studio API - HTML5 - Added support for position independent code with Upstream WASM. +* Core API - Fixed Channel::getAudibility not considering 3D attributes of parent + ChannelGroups in audibility calculation. +* Core API - Fixed audible pop from fix introduced in 2.02.24 regarding virtual channels + and ChannelControl::setPan/setMixLevelsInput/setMixLevelsOutput/ + ChannelControl::setMixMatrix. +* Core API - Android - Fixed input stream leak when backgrounding application on some + Android devices. +* Core API - Android - Fixed small amount of old audio being played after calling + System::mixerResume when using OpenSL or AAudio output types. +* Core API - PS5 - Fixed potentially incorrect pitch / hardware errors when using + very high or low pitch values with Opus. +* Core API - PS5 - Fixed issues with the Opus codec with seamless looping. +* Core API - Windows - Fixed ASIO failing to initialize if device CLSID is empty. +* OpenHarmony - Reduced latency by taking advantage of SDK 11 functionality, latency + for SDK 10 devices remains unchanged. +* Unity - Fixed vector out-of-range warning when creating 3D event instances. +* Unity - Fixed an issue with SetListenerLocation if Physic2D was disabled. +* Unity - Fixed Setup Wizard window to be resizable and scrollable. +* Unity - Fixed NotImplementedException error when running the event reference + updater on objects that have not implemented GetEnumerator(). +* Unity - Fixed ArgumentOutOfRangeException error when trying to create a new + FMOD event in editor. +* Unreal - Fixed 3D AudioLink events playing at world zero before receiving + position information from Unreal. + +13/12/24 2.03.05 - Studio API minor release (build 148280) +------------------------------------------------------------------------------------------ + +Features: +* Unity - Added Chinese localization. + +Fixes: +* Studio API - Added some extra validation around 3D attributes passed in. +* Studio API - Fixed an assert that occurs when playing a transition timeline with a + relative offset and a destination region that passes the end of the main + timeline. +* Studio API - Fixed incorrect timeline transition behavior when loading banks built by + FMOD Studio 2.00.04 or earlier. +* Studio API - PS4/PS5 - Fixed crash preceded by an internal assert(isValid) on + PS5 SDK 10 and PS4 SDK 12. +* Core API - Android - Fixed glitching when attempting screen recording with AAudio + on Android 14 and above. +* Core API - Android - Added protections against recording with multiple input devices + simultaneously when using OpenSL. +* Core API - Android - AAudio now correctly stops recording if a new recording begins + on a different device. +* Core API - iOS - Added protections against recording with multiple input devices + simultaneously. +* Unity - Fixed the Event Reference Updater incorrectly being triggered when + capitalization changes on events or folders. +* Unity - Fixed "Stop Events Outside Max Distance" behavior not taking listener + attenuation objects into account. +* Unity - Removed Codec assigning for the default platform as not all platforms + support the same Codec values. + +Notes: +* PS4 - Now built with SDK 12.008.011. +* PS5 - Now built with SDK 10.00.00.40. +* Unreal - Added support for UE5.5. +* Android - arm64-v8a and x86_64 libraries are now aligned to 16kb page size. + +11/11/24 2.03.04 - Studio API minor release (build 147563) +------------------------------------------------------------------------------------------ + +Fixes: +* Studio API - Fixed a crash caused by changing an event via live update and then + unloading one of its assets banks. +* Studio API - Fixed an assert when an event with manual sample loading uses a sample + after an event with automatic sample loading. +* Studio API - Fixed crash and memory leaks when loading master banks that are missing + mixer content required in other banks. +* Core API - Removed the MarshalHelper to avoid AOT build errors when using the + C# wrapper. +* Core API - FMOD_ERR_FILE_NOTFOUND logs will now be of level "log" rather than + "error" as it is not an error in some cases. +* Core API - Fixed compatibility issues with .wavs produced with + FMOD_OUTTPUTTYPE_WAVWRITER or FMOD_OUTTPUTTYPE_WAVWRITER_NRT. +* Core API - Fixed incorrect "device" name for PCM float output with + FMOD_OUTTPUTTYPE_WAVWRITER and FMOD_OUTTPUTTYPE_WAVWRITER_NRT. +* Core API - Fixed DSP creation failing with FMOD_ERR_MEMORY if called a large number + of times, despite still having system memory available. +* Core API - C# - Fixed the definition of FMOD_DSP_BUFFER_ARRAY to allow the + usage of FMOD_DSP_PROCESS_CALLBACK. New properties allow easy access + to the native arrays. +* Core API - Consoles - Hardware resources will now correctly yield after an + FMOD_CREATESAMPLE decode so they can be used in other sounds. +* Core API - Fixed subsounds in FSBs returning FMOD_SOUND_TYPE_FSB from + Sound::getFormat instead of their encoded sound type. +* Core API - Mac - Fixed error initializing output after turning bluetooth off. +* Core API - Win - Downgraded "device unplugged" errors to warnings as device + switching is supported. +* Core API - Win - Fixed potential crash with certain ASIO driver after System::close. +* Unity - Added support for setting number of Opus Codecs on PS5. +* Unreal - DestroyStudioSystem no longer unloads banks, as the system release + handles this. + +Notes: +* HTML5 - Now built with SDK 3.1.67. +* Unity - HTML5 - Now built with SDK 3.1.8 for Unity 2022.3 and 3.1.39 for + Unity 6000.0. + +25/09/24 2.03.03 - Studio API minor release (build 146372) +------------------------------------------------------------------------------------------ + +Features: +* Core API - Mac/iOS - System::mixerSuspend/System::mixerResume now suspends the mixer + and all other threads. +* Core API - Added logging to System::setAdvancedSettings. +* Unity - Added AttachInstanceToGameObject overload that accepts GameObject + instead of Transform. + +Fixes: +* Studio API - Fixed a crash when unloading an assets bank before its associated + metadata bank. +* Studio API - Fixed backwards compatibility loading banks from 1.08 and older, which + presented as FMOD_ERR_INVALID_PARAM being returned from + System::loadBankFile (or equivalent bank load function). +* Studio API - Fixed invalid handle error being returned from Studio::System::update + if a spectral sidechain on a global bus is released (due to the + bus becoming unused). +* Core API - Fixed passed in values being ignored when calling ChannelControl::setPan, + ChannelControl::setMixLevelsInput, ChannelControl::setMixLevelsOutput, + or ChannelControl::setMixMatrix on a virtual Channel. +* Core API - Fixed MultibandEQ not handling DSP::reset correctly for bands + B through E. +* Core API - OpenHarmony - Audio will now automatically resume after interruption. +* Core API - PS5 - Fixed Opus decode errors with certain pitch and seek combinations. +* Unreal - Added additional validation to Content Browser Prefix to account for + invalid characters and prefix lengths. +* Unity - Added non-Rigidbody velocity effect option on Listeners. +* Unity - Fixed source control presentation on macOS. +* Unity - OpenHarmony - Fixed issue locating bank files on devices. +* Unity - Fixed EventReferenceUpdater stack overflow exception caused by + Input System. +* Studio API - Reduced effect parameter allocations by allocating upfront instead of + individually. + +Notes: +* Unity - Renamed StudioEventEmitter members PlayEvent and StopEvent to + EventPlayTrigger and EventStopTrigger to disambiguate from + StudioEventEmitter.Play(). +* GameCore - Now built with March 2024 Update 1 GDKX. +* Unreal - PS4 - UE4.27 - Now built with SDK 11.008.001. +* Unreal - PS5 - UE4.27 - Now built with SDK 8.00.00.41. + +12/07/24 2.03.02 - Studio API minor release (build 144646) +------------------------------------------------------------------------------------------ + +Features: +* Core API - Android - Non-default input and output devices can now be requested when + using AAudio. Only available on devices targeting API level 26 (Oreo) + and above. +* Core API - Android - Added FMOD_Android_JNI_Init to support initializing Java + layer from a native activity. +* Core API - GameCore - Added FMOD_PORT_TYPE_CONTROLLER to the FMOD_OUTPUTTYPE_WASAPI + output plug-in to route audio to a user specific audio device. +* Unity - Fixed warnings for updated api functions in Unity 2023.1+. +* Unity - Android - Added support for Application Entry Point GameActivity. + +Fixes: +* Studio API - Fixed glitches due to modulation not being applied correctly at event + start time. +* Studio API - Fixed glitches in AHDSR modulator release. +* Studio API - Fixed an intermittent assert when playing instruments with trigger delay. +* Studio API - GameCore - Fixed crash when setting invalid thread affinity. +* Core API - Fixed rare crash when virtual voices swapped when using a mix of Sound + and DSP based channels. +* Core API - Android - Fixed crash when calling recordStart while mixer suspended. +* Core API - OpenHarmony - Added support for System::mixerSuspend and + System::mixerResume to allow recovery of audio when returning from + the background. +* Core API - visionOS - Fixed missing symbol build error. +* Core API - Windows - Fixed initialization failure when audio service unavailable. +* Unity - Fixed EventReferenceUpdater iterating over irrelevant objects. +* Unreal - Fixed Niagara component variables using incorrect namespaces. +* Unreal - Fixed compile errors in UE5.4 for FMODAudioLinkInputClient.cpp + on some consoles. +* Unreal - FMODAudioComponents Occlusion and Velocity is now based off the + component instead of the actor. +* Unity - Fixed CodeGeneration.cs being left in the wrong location when migrating + from 2.01 to 2.02. +* Unity - Fixed EventReferenceUpdater exception when attempting to iterate + uninitialized items. + +Notes: +* Unity - Studio Event Emitter setting "Allow Non-Rigidbody Doppler" has been + renamed "Non-Rigidbody Velocity". +* Unity - Added support for Unity 6. + +08/05/24 2.03.01 - Studio API minor release (build 142842) +------------------------------------------------------------------------------------------ + +Features: +* Core API - Added optimizations to Multiband Dynamics plugin to skip processing of + collapsed bands. + +Fixes: +* Studio API - Fixed a crash when unloading a bank containing a global parameter that + automates a modulator property on another global parameter. +* Studio API - Fixed the sidechain modulator producing incorrect results when it is + connected to multiple sidechains. +* Core API - Fixed rare clicks/pops when using DSP::setWetDryMix. +* Core API - Fixed potential crashes relating to unloading Banks that hold + referenced Events that are currently playing. +* Core API - HTML5 - Fixed no-audio output when using FMOD_OUTPUTTYPE_AUDIOWORKLET in + some newer browsers. +* Core API - HTML5 - Fixed FFT DSP spectrum data not being accessible. +* Unity - Fixed FMOD settings heading being over written by new Unity cloud + integration buttons. +* Unity - Fixed error if event browser is left open when Unity starts. +* Unity - Fixed EventReferenceUpdater throwing invalid cast exceptions. +* Unity - Fixed FileReorganizer not moving libs in old directories. +* Unreal - iOS - Fixed interruption notification deprecations. + +Notes: +* iOS/Mac - Now compliant with Apple privacy requirements, removed usage of + mach_absolute_time, no manifest needed. +* PS4 - Now built with SDK 11.508.011. +* PS5 - Now built with SDK 9.00.00.40. + +13/03/24 2.03.00 - Studio API major release (build 141450) +------------------------------------------------------------------------------------------ + +Features: +* Studio API - Referenced events now continue playing after they are untriggered. +* Studio API - Added Studio::EventInstance::getSystem for accessing the FMOD System + from event callbacks. +* Core API - System::getVersion now outputs build number from second argument. +* Core API - Recording is now automatically restarted after device resets and + changing output types where the devices of the output types have + matching GUIDs. This continues the recording with the sound previously + passed in. If the output types are incompatible, the behavior is + unchanged. +* Core API - Added new port type, FMOD_PORT_TYPE_VR_VIBRATION, to cater for + VR controllers that support vibration. Removed the old method + of controlling vibration via FMOD_PORT_INDEX_FLAG_VR_CONTROLLER. + Supported by PS5 (PSVR2). +* Core API - Added new port type, FMOD_PORT_TYPE_PASSTHROUGH, to provide a bypass + for platform-provided multichannel spatialization. + Supported by PS5 and Windows (WinSonic). +* Core API - Added new FMOD_DSP_TYPE_ECHO parameter FMOD_DSP_ECHO_DELAYCHANGEMODE. + FMOD_DSP_ECHO_DELAYCHANGEMODE_FADE (default) is best suited to + large changes in delay time, FMOD_DSP_ECHO_DELAYCHANGEMODE_LERP + is best suited to small changes in delay time, and + FMOD_DSP_ECHO_DELAYCHANGEMODE_NONE is available to avoid additional + processing between delay time changes, but can introduce zipper + noise. +* Core API - Added new FMOD_DSP_TYPE_FFT parameters FMOD_DSP_FFT_BAND_START_FREQ, + FMOD_DSP_FFT_BAND_STOP_FREQ, FMOD_DSP_FFT_DOWNMIX, and + FMOD_DSP_FFT_CHANNEL to give control over how the input signal + is processed and which part of a spectrum is analyzed. +* Core API - Added new FMOD_DSP_TYPE_FFT parameter FMOD_DSP_FFT_RMS and renamed + FMOD_DSP_FFT_DOMINANT_FREQ to FMOD_DSP_FFT_SPECTRAL_CENTROID. Both + provide information about the nature of the signal within the analysis + band. +* Core API - Added new FMOD_DSP_TYPE_FFT parameter FMOD_DSP_FFT_IMMEDIATE_MODE + to control whether processing is immediate or delayed to reduce + CPU cost by offloading to compatible hardware. The default is delayed. +* Core API - Added new 6dB high/low pass filters to FMOD_DSP_MULTIBAND_EQ_FILTER_TYPE + for FMOD_DSP_TYPE_MULTIBAND_EQ. These give a more gentle roll-off + and lower CPU cost. +* Core API - Added new Multiband Dynamics effect FMOD_DSP_MULTIBAND_DYNAMICS. + It supports upward/downward compression/expansion across three bands. +* Unreal - Added cross platform Memory Pool and Codec settings. + +Fixes: +* Studio API - Fixed popping caused by Studio::Bus::setPaused. +* Studio API - Fixed sounds being stopped when they are in multiple banks and + the first loaded bank is unloaded. +* Studio API - Fixed looping playlist instruments displaying a warning when using + a DSP buffer size of less than 1024. +* Core API - Fixed virtual voices getting out of sync when they return to real. + +Notes: +* All APIs - The F_CALLBACK macro has been removed, update existing code to + use F_CALL instead. +* Core API - In C#, FMOD_DSP_STATE.functions now has a wrapper function returning + an FMOD_DSP_STATE_FUNCTIONS struct instead of the IntPtr requiring + marshalling. +* Core API - Removed FMOD_DSP_TYPE_ENVELOPEFOLLOWER, FMOD_DSP_TYPE_VSTPLUGIN, + FMOD_DSP_TYPE_LADSPAPLUGIN, and FMOD_DSP_TYPE_WINAMPPLUGIN. +* Core API - Removed FMOD_SYSTEM_CALLBACK_MIDMIX. +* Core API - Renamed the FMOD_DSP_FFT_WINDOW enum to FMOD_DSP_FFT_WINDOW_TYPE, + and renamed the FMOD_DSP_FFT_WINDOWTYPE enum value to + FMOD_DSP_FFT_WINDOW. +* Core API - Win - The default DSP buffer size is now 512 rather than 1024 to + reduce latency. +* Android - Updated to NDK 26b and Android SDK 21. +* HTML5 - Removed support for deprecated Fastcomp backend. +* Unity - Removed support for end-of-life versions, minimum is now 2021.3. +* Tools - Updated Qt framework to v6.5.3 which lifts the minimum requirement + to macOS 11.0, Win10 1809 and Linux GLIBC 2.28. + +13/03/24 2.02.21 - Studio API minor release (build 141420) +------------------------------------------------------------------------------------------ + +Features: +* Unreal - Switch - Added functionality to open a socket on dev kit when + Live Update is enabled. +* Unreal - Added IFMODStudioModule::PrePIEDelegate to give users a chance + to clean up any resources before the FMOD System is released in + Editor. +* iOS - Added support for the Apple Vision Pro device and simulator in + the Core/Studio APIs and the FMOD for Unity integration. +* Win - Added support for Arm64 processors in the Core/Studio APIs. + +Fixes: +* Core API - Fixed FSB sounds incorrectly being virtualized when built from + 32 bit source assets. +* Core API - Fixed incorrect handling of DSP wet/dry settings if the DSP returns + FMOD_ERR_DSP_DONTPROCESS when its process callback is called with + FMOD_DSP_PROCESS_QUERY. +* Core API - OpenHarmony - Added an error check during System::init for insufficient + DSP buffer size. +* Core API - Android - Fixed global threads, like the File thread, remaining + active when the app is suspended on Android. +* Unity - Fixed editor hang when live recompiling code. +* Unity - Fixed iOS interruption deprecation warnings. +* Unreal - For UE5.2 onwards MacOS integration libs are now built as universal + to support both x86_64 and arm64. +* Unreal - Fixed iOS interruption deprecation warnings. + +Notes: +* iOS - Now built with iOS SDK 17.2 (Xcode 15.2). +* Switch - Now built with SDK 17.5.3. +* PS4 - Now built with SDK 11.008.001. +* PS5 - Now built with SDK 8.00.00.41. + +13/12/23 2.02.20 - Studio API minor release (build 139317) +------------------------------------------------------------------------------------------ + +Features: +* Core API - Through FMOD_ADVANCEDSETTINGS, Spatial Objects count can be reserved per + FMOD systems. +* FSBank API - Added FSBANK_BUILD_ALIGN4K to align each sound in an FSB to + a 4K boundary to help binary patching on Microsoft platforms. +* Unity - The integration can now be hosted on Source Control and still be + able to edit .asset files. +* Unity - Debug Overlay can now have its on screen position set and font size + changed. +* Unreal - Added support for pausing FMOD Audio Components in Unreal Sequencer. + +Fixes: +* Studio API - Fixed crash when calling into API before FMOD::System created. +* Core API - Fixed potential crackling caused by changing the system sample + rate of a device playing as a port. +* Win - Fixed Cygwin/MinGW libs giving linker errors from API functions + that include FMOD_THREAD_AFFINITY or FMOD_STUDIO_PARAMETER_ID. + +2/11/23 2.02.19 - Studio API minor release (build 137979) +------------------------------------------------------------------------------------------ + +Features: +* Android/iOS - Added virtual recording device via System::recordStart(1, ...) that adds + hardware processing including echo cancellation. + +Fixes: +* Studio API - Fixed a race condition between the sample data loading system and + Studio::EventDescription::getSampleLoadingState. +* Core API - Fixed WavWriter and NoSound output plugins potentially processing + more audio than appropriate for the elapsed time. +* Core API - PS4 - Increased DSPBufferSize range to handle sizes greater than + 256 or 512. The AT9 codec still has a restriction of 256 or 512 but + anything else will accept sizes of 256, 512, 768, 1024, 1280, 1536, + 1792 or 2048. +* Unreal - Reset locale to default every time PIE is launched. + +Notes: +* Core API - iOS - Disabled FMOD_OUTPUTTYPE_PHASE due to compatibility issues + with iOS 17. +* iOS - Now built with iOS SDK 17.0 (Xcode 15.0), min deploy target + is now 12.0 and bitcode has been removed as mandated by Xcode. +* Mac - Now built with macOS SDK 14.0 (Xcode 15.0.1). +* HTML5 - Fixed Sound::lock not returning memory pointers. + +2/10/23 2.02.18 - Studio API minor release (build 137105) +------------------------------------------------------------------------------------------ + +Features: +* Core API - iOS - A new output plugin called FMOD_OUTPUTTYPE_PHASE has been + enabled, which supports 3D spatial objects. For iOS 16.4. +* Core API - PS5 - From SDK 8.00 we now support Dolby Atmos and thus 7.1.4 output. + To enable this set FMOD_SPEAKERMODE_7POINT1POINT4. +* Unity - Emitters are now able to be triggered from UI elements using mouse events. +* Unreal - Added support for Niagara. + +Fixes: +* Studio API - Fixed programmer sounds getting spatialized by the Core API if + the passed in Sound had the FMOD_3D mode set. +* Studio API - Fixed shared streaming assets being forced to stop when the bank they are + streaming from is unloaded if the bank was loaded via + Studio::System::loadBankCustom. +* Studio API - Fixed pops when calling Studio::EventInstance::setTimelinePosition on + events with only one sound on the timeline. +* Studio API - Fixed streaming instruments failing to stop at the right time if they + were started too close to the end. +* Studio API - Multi instruments/scatterers now factor in silence instruments when + determining whether to play an instrument from a playlist in shuffle + mode. If an instrument is followed by one or more silence instruments, + that instrument will not be selected to play next. +* Core API - Fixed cycles created using DSP connections not causing a feedback + loop. +* Core API - Slight improvement to Multiband EQ filter stability near the upper + end of the frequency range on 24kHz devices. +* Core API - Clamp and log a warning when setting a high pitch value rather + than returning an error. +* Core API - Fixed some DSP effects incorrectly skipping processing as if bypassed + via DSP::setBypass when DSP::setWetDryMix is called with prewet set to 0. +* Core API - Fixed potential crash in the transceiver DSP if certain pre-init + calls are made in sequence, such as System::setDSPBufferSize followed + by System::setOutput. +* Core API - Fixed potential crash (or assert) when opening and closing ports. +* Core API - Fixed potential audio corruption for 3D objects if the mixer is + under heavy load. +* Core API - PS5 - Fixed internal error from sceAudioOut2PortSetAttributes returning + "not-ready" caused by a race condition in opening a port. +* Core API - Windows - Fixed WASAPI device enumeration memory leaks when devices fail. +* Unreal - Fixed Sequencer ignoring Start keys at frame 0. +* Unreal - Restore "Reload Banks' option to File dropdown menu. +* Unreal - Added validation to fix lack of leading or trailing forward slash in + Content Browser Prefix. +* Unreal - Fixed FMODAudioComponent ignoring "When Finished" behavior when + Sequencer finishes playback. +* Unreal - Fixed localized banks not working. +* Unity - Fixed non-rigidbody doppler dividing by 0 if Time.timescale = 0. +* Unity - Fixed issue when playing in Editor where the path plugins were + attempted to be loaded from contained "/Assets" twice. +* Android - Fixed playerSetVolume crash on devices with Android OS below Android T. +* Windows - Removed hard dependency on msacm32.dll. + +Notes: +* Core API - Calling the DSP plugin API functions, FMOD_DSP_GETSAMPLERATE, + FMOD_DSP_GETBLOCKSIZE, or FMOD_DSP_GETSPEAKERMODE before init + will now return an error as those settings are not confirmed until + after initialization. +* PS4 - Now built with SDK 10.508.001. +* PS5 - Now built with SDK 7.00.00.38. + +21/8/23 2.02.17 - Studio API minor release (build 136061) +------------------------------------------------------------------------------------------ + +Fixes: +* Studio API - Fixed Studio::EventInstance::getTimelinePosition occasionally reporting + incorrect position. +* Studio API - Fixed hang after running an Event for 12 hours with beat callbacks. +* Studio API - Fixed instruments that are automated on the timeline having incorrect + automated values when they start. +* Core API - Fixed virtual voice issue that could cause Channels to restart. +* Core API - Fixed assert firing from resampler for wildly varying pitch values. +* Core API - Fixed FMOD_INIT_3D_RIGHTHANDED to work correctly when using + FMOD_3D_HEADRELATIVE. +* Core API - GameCore/PS5 - Fixed the Opus and XMA codecs to display an appropriate + error log if the DSP buffer size is not 512. +* Core API - HTML5 - Fixed compiler errors to do with using Strict Mode. +* Unity - Fixed Studio Global Parameter Trigger silently failing on awake. +* Unity - FMOD Studio system failing to initialize will no longer throw as + an exception. +* Unity - Fixed error when auditioning Events containing global parameters in + Event Browser. +* Unreal - Fixed FMODAudioComponents always using default parameter values. +* Unreal - Fixed Sequencer restarting AudioComponents when Sequencer Editor + open. +* Unreal - Fixed crash when FMOD Studio project contains folders with "." + character. +* Unreal - Fixed FMODGenerateAssets commandlet not deleting old assets on + rebuild. +* Android - Fixed exported symbols to avoid issues with unwinder on armeabi-v7a. + +13/7/23 2.02.16 - Studio API minor release (build 135072) +------------------------------------------------------------------------------------------ + +Fixes: +* Studio API - Fixed voice stealing behavior not updating when connected to live + update. +* Studio API - Fixed instruments with AHDSR not stopping after release, introduced + in 2.02.15. +* Unity - Fixed ApplyMuteState and PauseAllEvents functions when when using + Addressables +* Unity - Fixed Editor Platform settings inheriting from the Default Platform. +* Unity - Fixed folder references to allow the FMOD Plugin base folder to + be moved anywhere on disk for use with the Unity Package Manager. +* Unreal - Fixed potential crash when linking to Studio project locales. +* iOS/Mac - Fixed example Xcode projects with incorrect paths failing to load. + +Notes: +* Unity - Added support for Unity 2023.1. + +2/6/23 2.02.15 - Studio API minor release (build 134211) +------------------------------------------------------------------------------------------ + +Features: +* Unreal - Added FMODStudioModule::GetDefaultLocale to get the default locale + which can be changed in the FMOD Settings. + +Fixes: +* Studio API - Fixed live update crash if tweaking an Event with an empty single + sound instrument. +* Studio API - Fixed potential crash if releasing an EventInstance from the Stop + callback. +* Studio API - Fixed third party DSP plugins causing potential assert by calling + DSP::setParameterDSP on effects managed by Studio. +* Unity - Fixed Addressable banks not being built when building with batchmode. +* Unreal - Fixed rare AudioVolume Reverb Effect cast crash. +* Unreal - Fixed crash when using Hot Reload in UE4.26 & 4.27. +* Unreal - FMODStudioModule::GetLocale correctly now returns the currently + set locale instead of the default. +* Unreal - PS4 - Fixed audio degradation due to mixer thread competing with + renderer thread. + +Notes: +* iOS - Now built with iOS SDK 16.4 (Xcode 14.3). +* Mac - Now built with macOS SDK 13.3 (Xcode 14.3), min deploy target + is now 10.13 as mandated by Xcode. +* Unreal - Added support for UE5.2. + +3/5/23 2.02.14 - Studio API minor release (build 133546) +------------------------------------------------------------------------------------------ + +Features: +* Core API - Examples now have a Common_Log function for outputting to TTY. +* Unity - Reduced time spent generating bank stubs, and reduced time spent copying + banks into StreamingAssets folder when building. + +Fixes: +* Studio API - Fixed crash when adding parameter sheet to a playing event while live + update connected. +* Studio API - Fixed instruments starting playback with stale property values during + hotswap. +* Studio API - Fixed Global Parameters being unable to automate other Global Parameters. +* Core API - PS5 - Fixed out-of-resources errors when decoding a large number + of FMOD_CREATESAMPLE (decompress into memory) sounds encoded as AT9. +* Core API - Win/GameCore - Fixed potential crash when an audio device reports + an invalid name. +* Unity - Fixed Find and Replace tool not finding prefabs. +* Unity - iOS - Fixed audio not resuming after opening and closing Siri. +* Unity - Fixed hang caused by RuntimeManager access when auditioning in timeline. + +17/3/23 2.02.13 - Studio API minor release (build 132591) +------------------------------------------------------------------------------------------ + +Features: +* Unity - Added non-Rigidbody Doppler effect option on Emitters. + +Fixes: +* Studio API - Fixed voice stealing failing on events in FMOD_STUDIO_PLAYBACK_STOPPING + state. +* Studio API - Fixed assert during Live Update when deleting a Global Parameter. +* Studio API - AHDSR modulators will now have correct release behavior when + the instrument stop condition is triggered by an event condition. +* Studio API - Fixed crash when changing parameter scope on a playing event. +* Studio API - Fixed a crash when removing automations via Live Update. +* Core API - Fixed playback issues with certain ice/shoutcast net-streams. +* Core API - GameCore - Fixed rare crash when playing back compressed Opus. +* Core API - GameCore - Reduced memory usage for hardware convolution reverb. +* Core API - Mac - Fixed crash when using input devices below 16kHz sample rate. +* Core API - PS5 - Fixed audio output stutters when a port disconnects. +* Core API - Win - Fixed record enumeration fails causing crash. +* Unity - Fixed Visual Scripting units not generating in Unity 2021+. +* Unity - Fixed plugin bundles not working on Mac. +* Unreal - Fixed AssetLookup being modified each time the editor is opened. +* Unreal - Fixed Editor Live Update not connecting to Studio. + +Note: +* GameCore - Now built with October 2022 QFE 1 GDKX. +* Switch - Now built with SDK 15.3.0. + +31/1/23 2.02.12 - Studio API minor release (build 131544) +------------------------------------------------------------------------------------------ + +Features: +* Core API - Warning is now logged when a voice swap occurs on an voice with an + audibility above -20dB. +* Unity - Added support for Unity 2022.2. +* Unity - macOS can now handle .dylib plugins natively +* Unity - Android - Added support for patch build. + +Fixes: +* Studio API - Fixed Live Update being ignored if Studio connects before the master Bank + is loaded. +* Studio API - Fixed a potential crash updating a referenced 3D Event if it has + been forcibly stopped due to bank unload. +* Studio API - Fixed issue where using a modulated parameter to automate a property of an + AHDSR modulator would sometimes cause the AHDSR to start in a bad state. +* Studio API - Fixed VCA handles becoming invalid when live update changes them. +* Studio API - Fixed incorrect scheduling of playlist entries in multi instruments that + have pitch changes. +* Core API - Switch - Fixed potential Opus crash when streaming with custom + async IO callbacks. +* Core API - PS5 + GameCore - Hardware resource configuration (performed using + platform specific FMOD APIs) will now apply during System::init + rather than System::create. +* Unity - The EventReferenceDrawer "Open in Browser" button now functions + when there is no event selected. +* Unity - Fixed EventRefDrawer showing incorrect "Migration target X is missing" + messages on sub-object fields with MigrateTo specified. +* Unity - Fixed hang when RuntimeManager called outside of main thread. +* Unity - The Update Event References menu command now scans non-MonoBehaviour + objects that are referenced by MonoBehaviours. +* Unity - Fixed warning "Settings instance has not been initialized...". +* Unity - Fixed 'multiple plugins with same name' error on Mac. +* Unreal - Fixed occlusion not working from Audio Component reloaded from + a streamed level. +* Unreal - Fixed commandlet crashing when trying to delete assets. +* Win - Fixed examples not rendering correctly on Windows 11. + +Notes: +* Unity - Added an example on how to pipe audio from a VideoPlayer into FMOD. +* iOS - Re-enabled compilation of the now deprecated Bitcode to appease + toolchains such as Unity that still require it. +* PS4 - Now built with SDK 10.008.001. +* PS5 - Now built with SDK 6.00.00.38. + +01/12/22 2.02.11 - Studio API minor release (build 130436) +------------------------------------------------------------------------------------------ + +Features: +* Studio API - Studio::System::getBus("bus:/", ...) will now return the master + bus if the master bank has been loaded, even if the strings bank has not. +* Core API - GameCore - Added in FMOD_GameCore_XMAConfigure. This can be used to + control whether to allocate XMA codec hardware resources inside + FMOD::System_Create. If not called before FMOD::System_Create the + resources will be allocated on first codec use. +* Core API - Mac - Added support for 7.1.4 output type. +* Core API - PS5 - Added in FMOD_PS5_AT9Configure. This can be used to + control whether to allocate AT9 codec hardware resources inside + FMOD::System_Create. If not called before FMOD::System_Create the + resources will be allocated on first codec use. +* Unity - Android - Added support for x86_64. +* Unreal - Added a Sound Stopped callback to the FMODAudioComponent. + +Fixes: +* Studio API - Fixed crash when connecting live update and a bank was loaded multiple + times with FMOD_STUDIO_LOAD_BANK_NONBLOCKING flag. +* Studio API - Fixed every asset in an Audio Table being parsed when only one + item is required. +* Studio API - Logging more meaningful error message when attempting to get/set listener + properties with an invalid listener index. +* Core API - Fixed recording not starting immediately after changing output devices. +* Core API - Fixed AAudio no-sound issue if device disconnection occurs during + initialization. +* Core API - Fixed a stall in Sound::release on nonblocking sounds. +* Unity - Added optimized DistanceSquaredToNearestListener method to avoid + unnecessary square root. +* Unity - Fixed StudioEventEmitter clearing handle prematurely when Allow Fadeout + enabled. +* Unity - Fixed FMODStudioEventEmitter inspector not updating displayed min and max + attenuation when banks refreshed. +* Unity - Error now logged when accessing RuntimeManager from Editor-only callsite. +* Unity - Fixed EventReferenceDrawer input losing focus when not found + warning appears. +* Unreal - Fixed BankLookup.uasset being modified whenever banks get refreshed + while using split banks. + +Notes: +* Unreal - Added support for UE5.1. +* iOS - Now built with iOS SDK 16.0 (Xcode 14.0.1), min deploy target + is now 11.0 and 32bit support has been removed as mandated by Xcode. +* Mac - Now built with macOS SDK 12.3 (Xcode 14.0.1). + +28/10/22 2.02.10 - Studio API minor release (build 129212) +------------------------------------------------------------------------------------------ + +Features: +* Core API - Added DSP::setCallback. + +Fixes: +* Studio API - Fixed a race condition where the Studio API could delete DSP parameter + data before the DSP was released. +* Core API - Fixed bug with fallback realloc copying excess memory when memory + callbacks being overridden but a realloc wasn't provided. +* Core API - Fixed crash with .MOD format with a particular combination of commands. +* Core API - Fixed potential FMOD_ERR_INVALID_PARAM from System::setDriver if + the device list has changed since a previous call to that function. +* Core API - Fixed potential crash when a Send mixes to an partially initialized + Return. This crash can occur in the Studio API also. +* Core API - Fixed potential access violation due to internal Sound Group list + corruption. +* Core API - Fixed Channel::setLoopPoints not applying if the stream decode buffer + is larger than the Sound. +* Unity - Removed benign errors originating from EventInstance::set3DAttributes + calls when API Error Logging is enabled. +* Unity - Fixed platform warning appearing unnecessarily. +* Unreal - Fixed BankLookup.uasset being modified whenever banks get refreshed + while using split banks. + +Notes: +* Unreal - Added support for UE5.1 preview 2. + +26/09/22 2.02.09 - Studio API minor release (build 128289) +------------------------------------------------------------------------------------------ + +Features: +* Studio API - Error now logged when attempting to set a readonly Parameter, or when + attempting to set a Global Parameter from an EventInstance. +* Core API - Deprecated Sound.readData(IntPtr, uint, out uint) in C# wrapper. Instead + use Sound.readData(byte[], out uint) or Sound.readData(byte[]). +* Core API - Added FMOD_SYSTEM_CALLBACK_RECORDPOSITIONCHANGED callback to notify when + new data recorded to FMOD::Sound. +* Core API - GameCore - Increased the limits of SetXApuStreamCount to match + Microsoft documented maximums. +* Unity - Added UnloadBank overloads for TextAsset and AssetReference. +* Unreal - Added "Enable API Error Logging" option to Advanced settings section. + Integration will log additional internal errors when enabled. +* Unreal - LoadBank node "Blocking" enabled by default. + +Fixes: +* Core API - Fixed potential crash if calling DSP::setParameter on a Pan DSP + when using the Studio API. +* Core API - Fixed ChannelGroup::setPaused(false) to behave the same as Channel, + ensuring any 3D calculations are performed before becoming audible. +* Core API - Fixed Opus producing different FSBank result on AMD and Intel CPUs. +* Core API - Fixed errors in the calculatePannerAttributes() function presented in + Core API Guide section 3.5 Controlling a Spatializer DSP + (formerly Driving the Spatializer). +* Core API - Increased net streaming max URL length to 2048. +* Core API - GameCore - Fixed potential XApu stream leak when playing a multi-channel + Sound as the hardware limit is reached. +* Core API - iOS - Fixed potential crash during System::mixerSuspend / + System::mixerResume when playing audio with the platform native + AudioQueue (AAC) decoder. +* Core API - iOS - Fixed simulator detection. +* Core API - Mac - Fixed CoreAudio crash when output device reports >32 outputs. +* Core API - Win - Fixed WinSonic crash when the device list changes before + System::init. +* Resonance - Android - Removed dependency on libc++_shared.so. +* Unity - Fixed FMODStudioSettings.asset marked dirty every time Editor reopens. +* Unity - Prevented unnecessary allocation when setting parameter on an FMOD + StudioEventEmitter. +* Unity - Fixed errors when upgrading Unity versions. +* Unreal - Provided default values to prevent various initialization warnings. + +Notes: +* Unreal - Moved various internal functions and fields to private. + +15/08/22 2.02.08 - Studio API minor release (build 126901) +------------------------------------------------------------------------------------------ + +Features: +* Core API - Added FMOD_INIT_CLIP_OUTPUT flag to enable hard clipping of float values. +* Core API - GameCore - Added SetXApuStreamCount and XDspConfigure to C# wrapper. +* Core API - PS5 - Added AcmConfigure and AjmConfigure to the C# wrapper. +* Core API - PS5 - Opus hardware decoding is now supported. +* Core API - PS5 - Added vibration support for the PSVR2 controller via + FMOD_PORT_INDEX_FLAG_VR_CONTROLLER. +* Unity - Timeline events now begin playback from relative playhead position when + auditioning in the timeline. + +Fixes: +* Studio API - EventDescription::is3D now returns the correct result if the Event uses + SpeedAbsolute or DistanceNormalized parameters. Requires bank rebuild. +* Core API - Fixed ASIO driver enumeration crash caused by invalid driver. +* Core API - Fixed incorrect thread IDs being used on pthread based platforms. +* Core API - Fixed System::setReverbProperties / FMOD_DSP_TYPE_SFXREVERB not working + with 7.1.4 input. +* Core API - Fixed crash from reading bad m3u file. +* Core API - Fixed the memory tracking system sometimes running out of memory. +* Core API - GameCore - Fixed potential crash when there are insufficient xAPU + resources remaining. +* Core API - Win - Fixed crash in device enumeration cleanup. +* Core API - C# - Some callback types renamed in fmod_dsp.cs to match C header. + DSP_CREATECALLBACK becomes DSP_CREATE_CALLBACK for example. +* Unity - Updated deprecated GameCore build target and runtime platform for Unity + 2019.4. +* Unity - Fixed issue with "Desktop" being added to build path twice when + selecting "Multiple Platform Build" Source Type. +* Unity - Fixed issue with HaveAllBanksLoaded not working when banks loaded via + AssetReferences. +* Unity - Fixed UnsatisfiedLinkError crash on Android when no FMODUnity components + present. +* Unity - Improved readability of folders in CreateEventPopup. +* Unreal - Fixed Blueprint LoadBank not correctly honouring Load Sample data flag. +* Unreal - Removed spurious log warning about initial value of global parameters. +* Unreal - Fixed memory leak when using PlayEventAttached in nosound mode. + +Notes: +* Switch - Now built with SDK 14.3.0. +* Unreal - Added support for UE5.0.3. + +18/05/22 2.02.07 - Studio API minor release (build 125130) +------------------------------------------------------------------------------------------ + +Features: +* Core API - HTML5 - FMOD now handles user interaction internally to allow sound to + work. The developer no longer has to handle boilerplate code + to allow user interaction. +* FSBank API - Mac - Added FSBankLib. +* Unreal - Added support for speaker mode 7.1.4 in the editor settings. +* Unreal - Added separate platforms settings for a variety of options. + +Fixes: +* Studio API - Fixed steal quietest not working correctly causing new EventInstances + to think they are the quietest and not play. +* Core API - Fixed ChannelGroup::setPitch when applied to the master channel + group causing exaggerated pitch changes as time goes on. +* Core API - HTML5 - Fixed integer overflow crash in fastcomp builds after 70 mins. +* Core API - Linux - Fixed potential hang on shutdown due to bad sound drivers. +* Core API - Linux - Fixed crash during System::init if using + System::setOutput(FMOD_OUTPUTTYPE_PULSEAUDIO) on a machine + without PulseAudio. +* Unity - Fixed an error occurring when a timeline playhead leaves an event + playable. +* Unity - Added missing EventReference overload for PlayOneShotAttached. +* Unity - Fixed refcount not updating when LoadBank called with TextAsset. +* Unity - Fixed scene hanging when auditioning timeline. +* Unity - Fixed events in timeline not refreshing when banks updated. +* Unity - Fixed platform objects on Settings asset showing no name in the project + window. +* Unity - Fixed stale event name left behind after clearing an FMODEventPlayable's + event reference field. +* Unity - Fixed an error caused by changing an event reference while an event is + being previewed in the browser. +* Unity - HTML5 - Fixed the audio not playing in the Safari web browser. +* Unreal - Fixed not being able to audition events in the editor. +* Unreal - Fixed Editor crash when importing bank with paths containing a period. + +Notes: +* PS4 - Now built with SDK 9.508.001. +* PS5 - Now built with SDK 5.00.00.33. +* Unreal - Added support for UE5. + +16/03/22 2.02.06 - Studio API minor release (build 124257) +------------------------------------------------------------------------------------------ + +Features: +* Core API - Android - Added support for loading sounds via Uri paths. +* Unity - Added ability to set individual channel counts for each codec format + supported by a given platform. + +Fixes: +* Studio API - Fixed issue where certain timeline instruments were causing + EventDescription::isOneshot to incorrectly return false. This requires + banks to be rebuilt to take effect. +* Core API - Fixed rare vorbis decoding error. +* Core API - Fixed crash in OutputASIO::stop if start has not been called. +* Core API - Fixed static noise or clicks when using DSP::setWetDryMix. +* Core API - Fixed FMOD_CODEC_METADATA macro parameters. +* Core API - Fixed bad ASIO driver causing enumeration to fail. +* Core API - Android - Fixed crash from headset detection with incorrect Java + lifetimes. +* Core API - HTML5 - Fixed an issue where FMOD_OUTPUTTYPE_AUDIOWORKLET would crash + if the speaker mode setup was greater than stereo while refreshing the + web browser. +* Core API - PS5 - Fixed a crash in the convolution reverb to do with + deallocating GPU memory. +* Core API - UWP - Fixed corrupted audio using certain headsets that implement + virtual surround sound such as those from Razer. +* Core API - Win - Fixed WASAPI device enumeration failure causing + initialization to fail. +* Unity - Fixed il2cpp crash caused by CREATESOUNDEXINFO callbacks not being + marshaled when loading sounds from audio tables. +* Unity - Fixed event browser preview area not initially displaying at correct + size. +* Unity - Fixed error shown when attempting to delete Default and Editor platforms. +* Unity - Fixed audible glitches on PS4 and PS5 due to FMOD feeder thread getting + blocked. +* Unity - Fixed enumeration of bank folders when creating an event from an event + reference field in the inspector. +* Unity - Fixed error if Resonance Listener is not on the Master Bus. +* Unity - Fixed banks being reimported with every build when set to AssetBundle + import type. +* Unity - Fixed cached events losing GUIDs after updating from a 2.01 or earlier + integration. +* Unreal - Fixed crash when importing banks containing ports. +* Unreal - Fixed net streams not working with programmer sounds. +* Unreal - Fixed problem locking all buses on bank load if banks haven't finished + loading. +* Unreal - Fixed AudioComponent::OnEventStopped sometimes being called twice. +* Unreal - Fixed FMODAudioComponents inside AudioVolumes not having the correct + AmbientVolumeParameter value when Started after being Stopped. + +Notes: +* GameCore - Now built with October 2021 QFE 1 GDKX. +* Stadia - Now built with SDK 1.71. +* Switch - Now built with SDK 13.3.0. +* Unity - GameCore - Now built with June 2021 QFE 4 GDKX. +* Unreal - Added support for UE5.0 preview 1. + +06/02/22 2.02.05 Patch 1 - Studio API patch release (build 123444) +------------------------------------------------------------------------------------------ + +Fixes: +* Studio API - Fixed crash when allocating internal pool resources. Introduced 2.02.05. + +Notes: +* Due to the severity of the above mentioned issue, the previous release of 2.02.05 + has been withdrawn and should not be used. + +21/12/21 2.02.05 - Studio API minor release (build 122665) +------------------------------------------------------------------------------------------ + +Features: +* Core API - HTML5 - Added a new FMOD_OUTPUTTYPE called FMOD_OUTPUTTYPE_AUDIOWORKLET, + which uses the Web Audio AudioWorkletNode functionality. + +Fixes: +* Studio API - Fixed issue where an async instrument would not trigger if its delay + interval was greater than its length on the timeline. +* Studio API - Fixed issue where the description of an event retrieved from a start + event command would have an invalid handle unless first retrieved via + Studio::System::getEvent. +* Studio API - Start Event Command Instrument now gracefully handles the case when the + event it is trying to start has not been loaded. +* Studio API - Fixed issue where the scatterer instrument can spawn instruments + inconsistently under certain conditions. +* Studio API - Fixed issue where audibility based stealing would not use + FMOD_DSP_PARAMETER_OVERALLGAIN::linear_gain_additive in its calculation. + For events using the object spatializer or the resonance audio + source this would cause the attenuation to be ignored for stealing. +* Studio API - Improved general Studio API performance. +* Studio API - Improved determination of whether a nested event will end, reducing the + incorrect cases where it would be stopped immediately. +* Studio API - Fixed Studio::EventInstance::getMinMaxDistance returning -1 before + event starts playing. +* Core API - GameCore - Fixed very rare Opus decoding hang. +* Core API - GameCore - Improved convolution reverb XDSP recovery in case of + unexpected hardware failure. +* Core API - Linux - PulseAudio now attempts to load and connect for detection rather + than running 'pulseaudio --check'. This improves PipeWire compatibility. +* Unity - Fixed event reference updater not handling multiple game objects with the + same path. +* Unity - Fixed setup window showing event reference update step as completed when + incomplete tasks remained. +* Unreal - FMOD plugin no longer overwrites existing Unreal editor style. +* Unreal - Fixed BankLookup being regenerated unnecessarily. +* Unreal - Fixed FMODAudioComponent not handling streaming levels correctly. +* Unreal - XSX - Fixed builds not finding fmod libs. +* Unity - Fixed platform-specific settings not being saved. + +Notes: +* Stadia - Now built with SDK 1.62, LLVM 9.0.1. +* Unity - First-time installation no longer requires an event reference update + scan. +* Unity - Event reference update tasks now display their completion status and + can no longer be redundantly run multiple times. +* Unity - Editor now restores scene setup after finishing execution of event + reference update tasks. + +19/11/21 2.02.04 - Studio API minor release (build 121702) +------------------------------------------------------------------------------------------ + +Features: +* Core API - Added support for FMOD_SYSTEM_CALLBACK_DEVICELISTCHANGED with multiple + Systems +* Core API - Switch - Added Opus decoding for streams. +* Unity - HTML5 - Added support for Unity 2021.2. + +Fixes: +* Studio API - When loading pre 2.02 banks, Studio::EventDescription::getMinMaxDistance + will now provide a minimum and maximum value based on the spatializers of + that event instead of 0. +* Core API - Fixed potential crash / error / corruption if using Object spatializer + and multiple listeners. +* Core API - Improve handling of disconnected devices. +* Core API - Fixed incorrect audibility calculation causing some sounds to incorrectly + go virtual when sends are involved. +* Core API - iOS - Fixed crash when suspending multiple FMOD::System objects while using + the AudioQueue codec. +* Core API - ARM based iOS / Mac / Switch. Three EQ effect optimized to be up to + 2x faster. +* Core API - Android and macOS - Now use Monotonic clock instead of Wall clock. +* Core API - Win - Fixed issue where WASAPI would fail to gracefully handle an + invalidated device due to a disconnection during initialization. +* Unity - Added a prompt to update the FMOD folder metadata if necessary so that + it can be moved to any location in the project. +* Unity - Fixed a bug causing the Event Browser to be in an invalid state when + reopening the Unity Editor. +* Unity - Fixed a bug that caused stale cache assets to not be cleared correctly. +* Unity - Fixed attenuation override values not updating until next GUI change when + a new event is selected for an emitter. +* Unity - Fixed a denied access error when updating FMOD for Unity integration. +* Unity - Fixed the bank cache refresh failing when the event browser is open. +* Unity - Android - Fixed command line builds not using split application binary. +* Unity - Mac - Added a prompt to fix bad line endings in FMOD bundle Info.plist + files if necessary (these could cause DllNotFoundException errors). +* Unity - Fixed an error preventing command line builds from completing. +* Unreal - Linux - Fixed missing libs. + +Notes: +* GameCore - Now built with June 2021 QFE 2 GDKX. +* PS4 - Now built with SDK 9.008.001. +* PS5 - Now built with SDK 4.00.00.31. +* Switch - Now built with SDK 12.3.7. +* Unity - Removed obsolete x86 Linux binaries. +* Unity - RuntimeManager's AnyBankLoading and WaitForAllLoads methods have been + renamed for clarity (to AnySampleDataLoading and WaitForAllSampleLoading + respectively), retaining the same functionality. The previous methods + remain for compatibility but are considered deprecated. + +08/09/21 2.02.03 - Studio API minor release (build 120077) +------------------------------------------------------------------------------------------ + +Features: +* Core API - It is now possible to specify the Opus codec count via + FMOD_ADVANCEDSETTINGS, previously it was hardcoded to 128. +* Core API - PS5 - Added ACM convolution reverb support. +* Core API - GameCore - Added XDSP convolution reverb support on Scarlett hardware. +* Core API - Win, GameCore, XBoxOne - Added recording support to WinSonic. +* Unity - Added EventReference.Find() to make setting default values on + EventReference fields more convenient. +* Unreal - UE4.26 on - Integration setup will now offer to add generated assets + to package settings. +* Unreal - UE4.26 on - Added Commandlet to support generating assets from + command line. +* Unity - Added IsInitialized property to EventManager to make it easier to know when + EventManager is safe to call. + +Fixes: +* Studio API - Fixed buffer overflow issues with command replays, system is now + more robust against failure and buffers have grown to handle demand. +* Studio API - Fixed issue where automating a labelled parameter under specific + circumstances would produce an incorrect result. +* Studio API - Fixed 7.1.4 sends losing their height speakers at the return. +* Studio API - Fixed issue where event instruments inside a multi instrument were unable + to be seemlessly looped with simple events. +* Studio API - Streaming instruments no longer can have the end of the audio cut off + if they take too long to load. +* Studio API - Fixed volume spike at start of multi instruments using both fade curves + and seek offsets. +* Core API - Fixed issue with System::registerCodec returning FMOD_ERR_PLUGIN_VERSION + regardless of FMOD_CODEC_DESCRIPTION apiversion. +* Core API - Fixed convolution reverb crash if out of memory. +* Core API - Fixed rare audio corruption / noise burst issue. +* Core API - Fixed FSBankLib AT9 encoder failing with an internal error on newer + versions of libatrac9.dll, 4.3.0.0 onward. +* Core API - Fixed potential crash when up-mixing quad to 5.1. +* Core API - GameCore - Reduced the chances of running out of Opus streams + when playing back Opus compressed banks on Scarlett hardware. +* Core API - Linux - Added support for automatic device switching. +* Core API - Android - Fixed issue where AAudio would restart occasionally on certain + devices. +* Core API - Android - Fixed issue where AAudio would would request an amount of data + far larger than its burst size on certain devices. +* Unity - Fixed a bug where settings could be accessed while an asset database + refresh was in progress, causing settings to be wiped. +* Unity - Fixed live update breaking when domain reload is disabled. +* Unity - Fixed an invalid handle error that would occur when an attached instance + ends. +* Unity - Fixed StudioParameterTrigger and StudioGlobalParameterTrigger not + receiving Object Start and Object Destroy events. +* Unity - Fixed the attenuation override values being overwritten when selecting + multiple event emitters. +* Unity - Fixed global parameter trigger browser showing other FMOD folders. +* Unity - Fixed referenced events not being played when an event is previewed in + the event browser if the referenced events are in a different bank. +* Unity - Fixed RuntimeManager.MuteAllEvents not working in editor. +* Unity - Fixed bank names including the .bank file extension when Load Banks is + set to Specified. +* Unity - Fixed a bug allowing multiple localized banks to be loaded and preventing + them from being unloaded. +* Unity - Fixed compatibility of native libraries changing after build. +* Unity - Fixed stretched logo texture in setup wizard when targeting iOS as build + platform. +* Unity - Fixed an error caused by auditioning events with global parameters in the + event browser. +* Unity - Fixed an error state caused by inspecting a game object that contains + both a Unity Image and an FMOD StudioEventEmitter. +* Unity - Fixed staging instructions appearing for fresh integration installations. +* Unity - Fixed an exception caused by disconnected prefab instances when updating + event references. +* Unreal - Fixed FMODAudioComponents continuing to play after actors have been + destroyed. +* Unreal - Fixed 'Reload Banks' menu option. +* Unreal - Fixed error when building installed engine with FMOD plugin. + +Notes: +* GameCore - Now built with June 2021 QFE 1 GDKX. +* Stadia - Now built with SDK 1.62 +* Unity - Removed a sleep loop in StudioEventEmitter.Start(). +* Unreal - Added support for UE4.27. + +26/07/21 2.02.02 - Studio API minor release (build 118084) +------------------------------------------------------------------------------------------ + +Features: +* Core API - Mac - Added Dolby PLII downmix support. +* Unity - When Event Linkage is set to Path, the EventReference property drawer and + Event Reference Updater tool can now update paths for events which have + been moved in FMOD Studio (detected via matching GUIDs). +* Unity - Console logging from the plugin now follows the logging level specified + for FMOD. +* Unity - Improved the Asset Bundle import type to better support Addressables: + FMOD now creates a stub asset for each source .bank file, which can be + added to version control and to Addressables Groups. Stub assets are + replaced with source .bank files at build time, and reverted to stubs + after each build. + +Fixes: +* Studio API - Fixed issue where silence instruments placed after a set parameter + command instrument would be skipped. +* Studio API - Fixed popping that would occur with fade curves and multi instruments in + the right conditions. +* Studio API - Fixed issue where automation and modulation would not evenly distribute + values for discrete parameters. +* Studio API - Fixed sustain point behavior where the sustain point is at the same time + as the end of a loop region. +* Studio API - Async instruments with infinite loop counts will play out their last loop + after being untriggered. +* Studio API - Scatterer instruments that have been untriggered will no longer fade out + child instruments. +* Studio API - Fixed issue where scatterer instruments would spawn instruments + inconsistently. +* Studio API - Fixed a stack overflow when releasing a very large number of events in a + single frame. +* Core API - Fixed FMOD::CREATESOUNDEXINFO::initialseekposition causing sound to not stop + at the correct time. +* Core API - Fixed disconnecting channel groups from ports when multiple instances of + the same port are connected. +* Core API - Fixed a possible crash by increasing the stack size of the file thread + from 48k to 64k. +* Core API - Fixed Object Spatializer getting out of sync with the mixer when the + mixer buffer is starved, this could also cause asserts to appear the log. +* Core API - GameCore - Fixed a race condition that could cause a hang when playing + Opus compressed audio. +* UE4 - Fixed default locale setting not working in cooked builds. +* Unity - Fixed references in EventReferenceUpdater.cs to classes unavailable when + the Unity Timeline package is missing. +* Unity - Fixed event browser being unable to audition events when an encryption + key is in use. +* Unity - Fixed setup wizard not marking current scene as dirty when replacing + Unity audio listeners. +* Unity - Fixed banks failing to load on Mac when the project is saved in Unity on + Windows. +* Unity - Fixed a crash caused by disabling API error logging. +* Unity - Fixed benign errors being logged to the console when API logging is + enabled. +* Unity - Fixed all banks being reimported whenever the banks are refreshed, + even if nothing has changed. +* Unity - Fixed an exception being thrown when building if version control is + enabled. +* FSBank - Fixed compatibility issue with Windows 7. +* Profiler - Fixed compatibility issue with Windows 7. + +Notes: +* HTML5 - Now built with SDK 2.0.20 (Upstream) and SDK 1.40.1 (Fastcomp). +* iOS - Now built with iOS SDK 14.5 (Xcode 12.5.1). +* Mac - Now built with macOS SDK 11.3 (Xcode 12.5.1), min deploy target + is now 10.9 as mandated by Xcode. +* Unity - Moved images into the Assets/Plugins/FMOD folder. +* Unreal - Added support for UE5.0 (EA1). + +26/05/21 2.02.01 - Studio API minor release (build 116648) +------------------------------------------------------------------------------------------ + +Features: +* Studio API - Added FMOD_STUDIO_EVENT_CALLBACK_NESTED_TIMELINE_BEAT which returns a + FMOD_STUDIO_TIMELINE_NESTED_BEAT_PROPERTIES containing the event's id. +* Studio API - Added an FMOD_STUDIO_PARAMETER_LABELED flag. +* Core API - Added loudness meter to the DSP API. The loudness meter is intended for + development purposes and is not recommended to be included in shipped + titles. +* Unity - Improved the UI for setting values on discrete and labeled parameters. +* Unity - Added FMODUnity.Settings.ForceLoggingBinaries to force FMOD to use the + logging binaries even when BuildOptions.Development is not set. +* Unity - Added the ability to set global parameters when auditioning an event. + +Fixes: +* Studio API - Improved performance of repeated calls to + Studio::EventDescription::isStream and + Studio::EventDescription::isOneShot. +* Studio API - Removed potential for performance hit from retrieving final volume and + final pitch values due to thread contention. +* Studio API - Fixed issue with audio device switching. +* Studio API - Restrict maximum number of non-zero length transitions to 31 per update + to prevent overloading the scheduler. +* Core API - GameCore - Fixed error log (assert) with logging build when playing + multichannel Opus. +* Core API - GameCore - Fixed rare Opus failure / hang when playing streams. +* Core API - GameCore - Fixed error log (assert) when seeking XMA streams near + the file end. +* Core API - Win/UWP/GameCore - Fixed WinSonic not falling back to no-sound + automatically if no devices are available. +* Core API - C# - Unblocked potential stalls when calling Studio::EventInstance::getVolume + / Studio::EventInstance::getPitch when finalVolume / finalPitch isn't + requested. +* Unity - Fixed global parameters disappearing if banks are refreshed when + the master bank hasn't changed. +* Unity - Fixed the setup wizard's Updating page status being reset whenever + scripts are recompiled. +* Unity - Fixed errors that occur when Settings.OnEnable() is called on an object + that is already initialized (e.g. "Cleaning up duplicate platform" and + "An item with the same key has already been added"). +* Unity - Reverted binary selection at build time to the old method of checking for + BuildOptions.Development in BuildReport.summary.options, as checking for + the DEVELOPMENT_BUILD symbol was failing in some situations and causing + DllNotFoundExceptions. +* Unity - Fixed bank sizes not being displayed in the event browser. +* Unity - Fixed compiler errors that appear when Unity's Physics and Physics 2D + packages are disabled. +* Unity - Fixed "The name 'StaticPluginManager' does not exist" error when calling + AddressableAssetSettings.BuildPlayerContent() on IL2CPP platforms. +* Unity - Removed cleanup of RegisterStaticPlugins.cs when a build finishes, in + order to avoid recompiling scripts unnecessarily. +* Unity - Create the Assets/Plugins/FMOD/Cache folder if it does not exist when + generating RegisterStaticPlugins.cs during a build. + +Notes: +* Unity - Added type-specific icons for global parameters in the event browser. +* Unity - Removed conditional code below Unity 2019.4 minimum specification. +* PS4 - Now built with SDK 8.508. +* PS5 - Now built with SDK 3.00.00.27. + +15/04/21 2.02.00 - Studio API major release (build 115890) +------------------------------------------------------------------------------------------ + +Features: +* Studio API - Event instances now have minimum and maximum distance properties that can + be automated by parameters. These can be overridden by + FMOD_STUDIO_EVENT_PROPERTY_MINIMUM_DISTANCE and + FMOD_STUDIO_EVENT_PROPERTY_MAXIMUM_DISTANCE. +* Studio API - Added Studio::EventInstance::getMinMaxDistance. +* Studio API - Added FMOD_STUDIO_PARAMETER_AUTOMATIC_DISTANCE_NORMALIZED. Converts the + range min distance to max distance into the range 0 to 1, clamping values + outside that range. +* Studio API - Added a guid field to FMOD_STUDIO_PARAMETER_DESCRIPTION. +* Studio API - Added Studio::System::getParameterLabelByID, + Studio::System::getParameterLabelByName, + Studio::System::setParameterByIDWithLabel, + Studio::System::setParameterByNameWithLabel, + Studio::EventDescription::getParameterLabelByName, + Studio::EventDescription::getParameterLabelByID, + Studio::EventDescription::getParameterLabelByIndex, + Studio::EventInstance::setParameterByIDWithLabel, + Studio::EventInstance::setParameterByNameWithLabel. +* Studio API - Added Studio::Bus::getPortIndex and Studio::Bus::setPortIndex. +* Core API - Added FMOD_DSP_PARAMETER_ATTENUATION_RANGE for spatializing DSPs to + utilize Studio::EventInstance min and max distance. +* Core API - Unified platform specific output port types FMOD_[PLATFORM]_PORT_TYPE + and moved them to common FMOD_PORT_TYPE. Attempting to attach a channel + group to an output port type which is not available on the platform will + return an error. +* Core API - UWP - Added support for Windows N versions. +* Unity - In Events Browser the Global Parameters now show in folders. +* FSBank - Added native Linux version of Gui and Command line application. +* Profiler - Added native Linux version of the Core API profiler. +* Linux - Added ARM 64 bit support. + +Fixes: +* Studio API - Fixed behavior interaction between timelocked multi instruments and + sustain points so that multi instruments will play from the same point + that they were stopped via the sustain point. + +Notes: +* Studio API - Studio::EventDescription::getMinimumDistance and + Studio::EventDescription::getMaximumDistance replaced with + Studio::EventDescription::getMinMaxDistance. +* Studio API - Studio::EventInstance::setProperty on + FMOD_STUDIO_EVENT_PROPERTY_MINIMUM_DISTANCE or + FMOD_STUDIO_EVENT_PROPERTY_MAXIMUM_DISTANCE does not affect spatializers + with Override Range set. This is most noticeable with effect presets. +* Studio API - Studio::System::getCPUUsage changed to take a struct FMOD_CPU_USAGE as + 2nd parameter, also FMOD_STUDIO_CPU_USAGE removes core api values. Use + FMOD_CPU_USAGE for that. +* Studio API - Renamed Studio::EventInstance::triggerCue to + Studio::EventInstance::keyOff and Studio::EventDescription::hasCue to + Studio::EventDescription::hasSustainPoint. +* Core API - FMOD_DSP_TYPE_PAN and FMOD_DSP_TYPE_OBJECTPAN have an override attenuation + range property to use the min and max distance properties of the dsp and + ignore the attenuation range of the event instance. Defaults to true for + backwards compatibility. +* Core API - FMOD::System_Create takes a headerversion argument to check the core api + headers and libraries match. +* Core API - System::getCPUUsage changed to take a struct FMOD_CPU_USAGE. +* Core API - Incremented FMOD_OUTPUT_PLUGIN_VERSION for Output plugins. Dynamic + library Output Plugins must be rebuilt. FMOD_OUTPUT_INIT_CALLBACK argument + dspnumbuffers can now be modified and dspnumadditionalbuffers has been + added. Additionally, FMOD_OUTPUT_METHOD_POLLING has been removed. +* Core API - Incremented FMOD_CODEC_PLUGIN_VERSION for Codec plugins. Dynamic + library Codec Plugins must be rebuilt. Codec API now exposes + FMOD_CODEC_FILE_TELL_FUNC, FMOD_CODEC_ALLOC_FUNC, FMOD_CODEC_FREE_FUNC and + FMOD_CODEC_LOG_FUNC functions. Additionally, FMOD_CODEC_FILE_SEEK_FUNC + accepts a FMOD_CODEC_SEEK_METHOD. +* Core API - Changed FMOD_THREAD_AFFINITY from unsigned 64-bit integer to signed 64-bit + integer, reducing the maximum supported number of cores by one. +* Core API - UWP - FMOD MediaFoundation Codec is now included as a separate dll. +* FSBank API - Removed deprecated FSBANK_FORMAT_PCM_BIGENDIAN and + FSBANK_FORMAT_AT9_PSVITA, and renamed FSBANK_FORMAT_AT9_PS4 to + FSBANK_FORMAT_AT9. +* Resonance - Replaced min and max distance with FMOD_DSP_PARAMETER_ATTENUATION_RANGE. + If previous behavior is required, FMOD 2.2 is compatible with resonance + audio included with 2.1. +* Android - Minimum API version raised to 16 for 32 bit. +* Linux - Now built with LLVM/Clang 10. +* Linux - ARM - the minimum supported architecture has been lifted to armv7 with + NEON support. +* PS5 - Renamed platform specific APIs and headers from codename to official name. +* Unity - The [EventRef] attribute has been replaced with the EventReference type. + This change requires migration; use the FMOD/Update Event References + menu command to assist you with the migration process. +* Unity - The minimum version of Unity supported is now 2019.4 + +12/02/21 2.01.09 - Studio API minor release +------------------------------------------------------------------------------------------ + +Features: +* Studio API - Added FMOD_STUDIO_SYSTEM_CALLBACK_LIVEUPDATE_CONNECTED and + FMOD_STUDIO_SYSTEM_CALLBACK_LIVEUPDATE_DISCONNECTED. +* Studio API - Added Studio::EventDescription::isDopplerEnabled. Will return false with + banks built prior to 2.01.09. +* Unity - Added a Volume property to FMOD Event Tracks. +* Unity - Improved plugin lib updates by automating the process in a few simple + steps. +* Unity - Added 7.1.4 speaker mode to Project Platform in the settings menu. +* Unity - Added support for generating unit options for Unity 2021 Visual + Scripting package. +* Unity - Added option to enable error reporting to Unity console from internal + FMOD system. +* Unity - Added a Setup Wizard to help with adding FMOD to projects. + +Fixes: +* Studio API - Fixed possible memory corruption due to race condition between user code + creating sounds asynchronously using sound info from an audio table and + unloading the bank containing the audio table. +* Studio API - Improved error detection and documentation regarding the requirement of + loading asset banks at the same time as metadata banks. +* Studio API - Fixed issue where stopping conditions on nested events without ahdsr + modulators would not play out when the parent event is still playing and + the nested event becomes untriggered. +* Studio API - Fixed issue where hot swapping an event via live update would invalidate + the API handle. +* Studio API - Fixed incorrect count from Studio::Bank::getEventCount when loading + banks built with 1.07, 1.08 or 1.09. +* Core API - Fixed substantial performance issue when connected to a profiler. +* Core API - Fixed sync points potentially being skipped as Channels transition from + virtual to real. +* Core API - Fixed warning being logged about truncated files on user created sounds. +* Core API - Fixed hang on .S3M format playback when seeking past calculated end of + song with FMOD_ACCURATETIME. +* Core API - Fixed some netstreams return FMOD_ERR_HTTP. Introduced 2.01.02. +* Core API - Fixed potential audio corruption when using the object spatializer. +* Core API - Fixed System::getPluginHandle returning internal only DSPs. +* Core API - Fixed crash with Convolution Reverb. Introduced 2.01.08. +* Core API - Fixed early and late delay support for FMOD_DSP_TYPE_SFXREVERB. + Introduced 2.01.04. +* UE4 - Add a configurable delay to automatic bank reloading to avoid a race + condition between banks being rebuilt in Studio and the integration + trying to reload them. +* UE4 - Remove unsupported log levels from settings. +* UE4 - Fixed blueprint AnimNotify causing Editor to crash. +* UE4 - 4.26 - Fixed asset generation regenerating assets when banks have not + been modified. +* UE4 - 4.26 - Fixed crashes caused by attempting to regenerate assets which are + read-only on disk. User is now prompted to check-out or make writable + assets which are read-only on disk. +* UE4 - 4.26 - Fixed sequencer integration. +* UE4 - 4.26 - Fixed AnimNotify not automatically loading referenced event asset. +* UE4 - 4.26 - Fixed FindEventByName failing to load required event asset. +* UE4 - 4.26 - Fixed crash when running with sound disabled (eg. running as A + dedicated server or running with the "-nosound" command line option). +* UE4 - iOS/tvOS - Fixed audio occasionally not returning on application resume. +* UE4 - XboxOne - Fixed third party plugins not working. +* Unity - Made binary selection at build time more robust by checking for + DEVELOPMENT_BUILD in the active script compilation defines. +* Unity - Fixed context menu entries being disabled on FMOD Event Playable + parameter automation. +* Unity - Fixed a hang that could occur when scripts were recompiled after a + callback was fired from FMOD to managed code. +* Unity - Fixed banks not loading on Mac if project was saved from PC to source + control. +* Unity - Fixed a number of build errors on various platforms caused by the + static plugin system's use of the IL2CPP --additional-cpp command + (the static plugin system now generates C# instead of C++). +* Unity - PS5 - Removed unsupported Audio 3D option from the platform settings. +* Unity - UWP - Fixed warnings and errors surrounding Marshal usage depending + on Unity version, scripting backend and API compatibility combination. + +Notes: +* GameCore - Updated to February 2021 GDK. +* UE4 - Changed default source directory for runtime bank files to + Content/FMOD/Desktop. Platform specific INI files should be used to + override this as appropriate. + +11/02/21 2.01.08 - Studio API minor release (build 114355) +------------------------------------------------------------------------------------------ + +Features: +* Core API - Added FMOD_SYSTEM_CALLBACK_OUTPUTUNDERRUN, which is called when a + buffered mixer output device attempts to read more samples than are + available in the output buffer. +* Core API - Mac - Added Resonance Audio Apple Silicon support. +* Unity - Improved bank refresh logic and added a status window that appears when a + refresh is about to happen. +* Unity - Added support for automating event parameters on the Timeline. + +Fixes: +* Studio API - Fixed fast spawning scatterer instruments with low polyphony spawning too + few instruments. +* Studio API - Fixed a memory leak that could occur when a sound got stuck in the + loading state. +* Core API - Fixed crash on .XM format playback. +* Core API - Fixed potential hang with net streams if server returns errors. +* Core API - Fixed extraneous logging of internal pool allocations. +* Core API - Fixed rare crash when releasing convolution reverb DSP instances. +* Core API - UWP - Fixed logging spam when using WASAPI output mode. +* UE4 - Expose the Enable Timeline Callbacks property of FMOD Audio Component to + blueprints. +* UE4 - Fixed crash which could occur when an FMOD Audio Component which uses a + programmer sound is destroyed by unloading the map or closing the game. +* Unity - Fixed Discrete and Labelled global parameters that do not appear in the + Event Browser. +* Unity - Fix multiple listeners positioning not working correctly. +* Unity - Fixed sample data failing to load when Load Bank Sample Data is enabled + in a project with separate asset banks. +* Unity - Fixed an Android build error when the Export Project option is set. +* Unity - Fixed FMOD IL2CPP arguments being left in ProjectSettings after building, + which could break builds on other operating systems. +* Unity - Android - Fixed an IL2CPP build error on some NDK versions. +* Unity - PS5 - Fixed compile error due to stale platform API CS file. +* Unity - iOS/tvOS - Fixed audio occasionally not returning on application resume. + +Notes: +* Switch - Now built with SDK 11.4.0. +* UE4 - Added support for UE4.26. + +18/12/20 2.01.07 - Studio API minor release (build 113487) +------------------------------------------------------------------------------------------ + +Features: +* Core API - Added FMOD_SYSTEM_CALLBACK_DEVICEREINITIALIZE. +* Core API - Mac - Added Apple Silicon support. +* Unity - Added support for generating unit options for Bolt visual scripting. +* Unity - Added option to stop an emitter's event instance when the emitter is + further than its maximum attenuation distance from all listeners. + +Fixes: +* Studio API - Command replays now record the initial state of global parameters. +* Studio API - Fixed errors from instrument creation failure not being reported to the + error callback. +* Studio API - Fixed crash due to null pointer dereference when instrument creation + fails due to running out of memory. +* Studio API - Fixed crash when unloading a bank from the + FMOD_STUDIO_EVENT_CALLBACK_STOPPED callback. +* Studio API - Fixed crash when hot swapping a nested event and its parent where the + child event is registered before the parent event. +* Studio API - Fixed spurious warning messages when connecting Live Update. +* Studio API - Fixed crash which could occur if a user thread loads a bank + asynchronously while another thread releases the system. +* Studio API - Switch log messages about missing plugins from warning to log level when + the system is initialized with FMOD_STUDIO_INIT_ALLOW_MISSING_PLUGINS. +* Core API - Fixed rare crash due to race condition when calling Sound::getOpenState + for a sound created with FMOD_NONBLOCKING. +* Core API - Fixed rare crash occurring some time after calling + System::attachChannelGroupToPort due to internal buffer synchronization. +* Core API - Fixed certain internet radio stations that serve up playlists failing to + load correctly. +* Core API - Fixed sidechain modulator release being cutoff if sidechain source is + destroyed. +* Core API - Linux - Fixed hang in shutdown when using ALSA as the output mode when + ALSA is unable to write to the output buffer. +* Core API - Android - Reduced AAudio fail to stop error message to a warning. +* Core API - UWP - Fixed issue preventing loading of 32 bit x86 plugins. +* UE4 - Fixed spurious warning messages when loading banks which use plugins. +* UE4 - Fixed listener being stuck at world origin when using a standalone game + from the editor (introduced in 2.00.12). +* UE4 - XboxOne - Fixed users having to modify engine code to copy libs. +* Unity - Android - Fixed Mobile Low and Mobile High platforms using the wrong + bank path when on Android. +* Unity - Prebuild debug warning added for invalid FMOD Event paths. +* Unity - Fixed banks not being copied into the project when using Asset Bundles. +* Unity - Fixed specified bank paths for multi platform builds. + +Notes: +* Core API - Changed THREAD_AFFINITY enum in C# wrapper from unsigned 64-bit integer + to signed 64-bit integer, reducing the maximum supported number of cores + by one. +* GameCore - Updated to August 2020 QFE 5 GDK. +* XboxOne - Now built with July 2018 QFE15 XDK. +* PS4 - Resonance Audio now built with SDK 8.008. +* PS5 - Resonance Audio now built with SDK 2.00.00.09. +* iOS - Now built with iOS SDK 14.2 (Xcode 12.2), min deploy target + for iOS is now 9.0 as mandated by Xcode. +* Mac - Now built with macOS SDK 11.0 (Xcode 12.2). +* Stadia - Now built with SDK 1.55. +* Unity - Moved Timeline and Resonance Audio classes from global namespace into + FMOD namespaces. + +13/11/20 2.01.06 - Studio API minor release (build 112764) +------------------------------------------------------------------------------------------ + +Features: +* Core API - Added FMOD_SYSTEM_CALLBACK_BUFFEREDNOMIX. +* Core API - PS5 - Added support for microphone recording. +* Unity - Added support for Addressables. +* Unity - In Events Browser the banks folders now show when mirroring is disabled. +* Unity - Setting Live Update port per-platform is now supported. +* Unity - FMOD now automatically selects the release or logging version of the + native libraries at build time, based on the Development Build setting. + +Fixes: +* Studio API - Fixed issue where tempo based scatterer would play slightly off beat. +* Core API - Improved error message when binding to a port fails due to a permission + error. +* Core API - Android - Fixed issue where audio would disconnect while debugging. +* UE4 - Fixed deprecation warning in FMODStudioEditorModule. +* Unity - Fixed FMOD_ERR_MEMORY caused by leaking System objects on play-in-editor + script reload. +* Unity - Fixed volume value in debug window. +* Unity - Prebuild debug warning added for invalid FMOD Event paths. +* Unity - HTML5 - Fixed error when building for development. +* Unity - Switch - Fixed a build error due to fmodplugins.cpp not being enabled. + +Notes: +* Core API - Renamed FMOD_CODEC_METADATA_CALLBACK to FMOD_CODEC_METADATA_FUNC to + better reflect its purpose. +* Core API - Sound::getFormat now returns FMOD_SOUND_FORMAT_BITSTREAM if + FMOD_CREATECOMPRESSEDSAMPLE is used with System::createSound. +* GameCore - Updated to August 2020 QFE 4 GDK. +* PS4 - Now built with SDK 8.008. +* PS5 - Now built with SDK 2.00.00.09. + +09/10/20 2.01.05 - Studio API minor release (build 112138) +------------------------------------------------------------------------------------------ + +Features: +* Core API - XboxOne and Switch - Added ResonanceAudio plugin support. +* Core API - GameCore - Added FMOD_GameCore_SetXApuStreamCount to control reserved + XApu resources. +* Unity - Edit Settings now allows FMOD output mode to be set per-platform. +* Unity - Added support for specifying static plugins in the FMOD Settings. +* Unity - Added support for setting a per-platform callback handler to run custom + configuration code prior to initialization. +* Unity - Added settings to customize DSP buffer length and count per-platform. +* Unity - Added metering channel order setting. +* Unity - Assembly Definition files added to the FMOD plugin. +* Unity - The FMOD scripts will now compile without the unity.timeline package + installed. If you wish to use Timeline you will need to install this + package for Unity 2019.1 and above. +* Unity - GameCore - Add resonance audio support. +* Unity - iOS - Added simulator support. +* Unity - PS5 - Add resonance audio support. +* GameCore - Added support for decoding Opus compressed FSBs / Banks using platform + hardware acceleration on Scarlett devices. This is a preview release of + this feature, please report any bugs found directly to FMOD support email. + +Fixes: +* Studio API - Live update socket errors are now handled gracefully, only warnings are + logged. +* Studio API - Fix marker callbacks for multiply nested events. +* Studio API - Fixed Studio::EventDescription::is3D, Studio::EventDescription::isOneShot and + Studio::EventDescription::isNested potentially returning an error when the event + contains a nested reference to an event which has not been loaded. +* Core API - Fixed crash in convolution reverb if out of memory. +* Core API - Fixed rare crash when updating net stream metadata tags. +* Core API - Android - Reduce popping encountered on certain handsets by dynamically + adjusting latency. +* Core API - Android - Fix issue where regular gaps in audio were encountered on + handsets with using very large burst sizes. +* Core API - Android - Fix issue where System::mixerSuspend would fail on certain + handsets. +* Core API - Mac - Fixed init returning an error when no output devices available. +* Core API - Win - Fixed crash on Win7/8 devices with high end CPUs that support + AVX-512. +* Core API - Fix convolution crash if a small impulse was used followed by a large + impulse. Introduced in 2.01.04. +* Core API - HTML5 - Fix missing implementation of Sound::getSyncPoint/getSyncPointInfo/ + addSyncPoint/deleteSyncPoint. +* UE4 - Fixed potential null pointer dereference when updating FMOD listeners for + play-in-editor session. +* UE4 - PS5 - Disabled UE4 built-in audio to prevent crash at startup. +* Unity - Fixed rare TimeZoneNotFoundException encountered on some devices. +* Unity - Fixed play-in-editor not using new speaker mode when changed in settings. +* Unity - HTML5 - Fix FMOD_ERR_UNSUPPORTED error being returned from bank loading. + Introduced in 2.01.04. + +Notes: +* Studio API - Issues with reconnecting Live Update (primarily on mobile) have been + resolved in FMOD Studio. Update to FMOD Studio 2.01.05 or higher. +* GameCore - To produce Opus banks in FMOD Studio, add the new "Custom" platform to + your project and select Opus as the encoding. +* GameCore - Updated to June 2020 QFE 6 GDK. + +10/09/20 2.01.04 - Studio API minor release (build 111454) +------------------------------------------------------------------------------------------ + +Features: +* Studio API - Added a flag for discrete parameters to FMOD_STUDIO_PARAMETER_FLAGS +* Core API - Convolution reverb optimizations. Now multithreaded to avoid spikes in + mixer performance. Significant memory optimization with multiple instances. +* Core API - Android - Added support for swapping output modes. +* Core API - GameCore - Added FMOD_GAMECORE_PORT_TYPE_COPYRIGHT_MUSIC output port + type. +* Unity - Added OnEnabled and OnDisabled for StudioBankLoader. +* Unity - Added attachedRigidbody to OnTriggerEnter and OnTriggerExit for EventHandler. +* Unity - Updated the event browser for better performance and more consistent + look and feel. + +Fixes: +* Core API - Android - Fixed recording support when using AAudio. +* Core API - Android - Fixed issues with headphone detection with AAudio. +* Core API - XboxOne - Fixed getOutputHandle not returning the IAudioClient on WASAPI. +* UE4 - When running multiplayer PIE sessions a listener is added for each player + in each viewport. +* UE4 - Improved handling of FMOD Studio objects being renamed or removed when + reloading banks. Previously it would appear that references to renamed + objects were correctly handled when they were not; references in UE4 + must be manually fixed up when FMOD Studio names are changed. +* UE4 - Improved handling of unsupported characters in FMOD Studio object names. +* Unity - Made the Studio Event Emitter initial parameter value UI handle prefab + instances and multi-selections properly. +* Unity - Fixed tooltips not working for EventRef. +* Unity - Fixed bank loading on Android with split/non-split APKs. +* Unity - Fixed plugin paths for Windows and Linux. + +Notes: +* Core API - GameCore - FMOD_GAMECORE_PORT_TYPE_MUSIC is no longer ignored by + GameDVR. Use FMOD_GAMECORE_PORT_TYPE_COPYRIGHT_MUSIC for background music + which should not be captured by GameDVR. +* Stadia - Now built with SDK 1.50. +* Android - Examples now include CMake based projects alongside the NdkBuild based + projects. +* GameCore - Updated to June 2020 QFE 4 GDK. + +05/08/20 2.01.03 - Studio API minor release (build 110858) +------------------------------------------------------------------------------------------ + +Features: +* Core API - Added System::getDSPInfoByType. +* Core API - GameCore - Added support for microphone recording. + +Fixes: +* Studio API - Fixed named marker callbacks for nested events. +* Studio API - Fixed issue with accumulating event instruments spawned by a scatterer. +* Studio API - Fixed issue where an event instance handle would incorrectly remain valid. +* Studio API - Improved detection of user code incorrectly using a dangling pointer from + a previously destroyed Studio System object. +* Studio API - Improve panner envelopment when source is above or below the listener. +* Studio API - Fixed FMOD_STUDIO_PARAMETER_DESCRIPTION::maximum being 1 higher than the + maximum value which could be set. +* Studio API - Fixed discrete parameters with non-zero seek speed or velocity changing + value too quickly after having their value set by an API call. +* Studio API - Fixed stopping conditions for nested events. +* Core API - Ignore data and fmt sections of a wave file that are contained in lists. +* Core API - iOS - Fixed stale audio from before System::mixerSuspend playing after + calling System::mixerResume. +* Core API - iOS - FMOD initializes with FMOD_OUTPUTTYPE_NOSOUND if unable to + initialize due AVAudioSessionErrorCodeCannotStartPlaying. Switching to + FMOD_OUTPUTTYPE_COREAUDIO via System::setOutput is also supported. +* Core API - Mac - Fixed automatic default device switching. +* Core API - Win - Improved handling of IPv6 net-streams. +* Core API - Fixed FMOD_DSP_STATE_DFT_FUNCTIONS::inversefftreal function possibly + causing corrupted audio if it and FMOD_DSP_STATE_DFT_FUNCTIONS::fftreal + were called from different threads. +* UE4 - Android - Fixed issue which could cause Android packaged builds to crash + at startup. +* Unity - Fix crash in HasBankLoaded if RuntimeManager isn't initialized. + +Notes: +* Unity - Added GameCore platform. +* Switch - Now built with SDK 10.4.1. +* GameCore - Updated to June 2020 QFE 1 GDK. + +01/07/20 2.01.02 - Studio API minor release (build 110199) +------------------------------------------------------------------------------------------ + +Features: +* Core API - GameCore - Added XMA support for Scarlett. +* Core API - GameCore - Added background music port support. +* Core API - PS5 - Added support for all platform specific ports, including background + music, controller speaker and vibration. +* Unity - Added field for specifying a sub directory for Banks in the settings. + +Fixes: +* Studio API - Fixed an issue with events referencing missing parameter descriptions + when parameters were unused for a platform. For old banks references to + missing parameter descriptions are stripped out of the event at load + time. Newer banks will always include all parameter descriptions to + ensure consistency across platforms. +* Studio API - Fixed assert that would occur when setting a parameter that in turn + creates an entity that also is listening for that parameter to change. +* Studio API - Fixed doppler calculation to use listener attenuation position. +* Studio API - Fixed memory leak caused by creating a bus with missing bank data. +* Studio API - Improved performance of repeated calls to Studio::EventDescription::is3D. +* Studio API - HTML5 - Fixed loadBankMemory not allowing a UInt8 memory object type to + be passed to it. +* Core API - Fixed silence from ports when switching from no-sound back to a valid + output mode with ports. +* Core API - Fixed incorrect return of FMOD_ERR_DSP_RESERVED on ChannelGroups caused + by internal race condition. +* Core API - Fixed FMOD_LOOP_NORMAL flag not working with netstreams that have + "Accept-Ranges: bytes header". +* Core API - iOS - Fixed conflicting ogg vorbis symbols if linking FMOD against a + project containing vorbis already. +* Core API - Android - Fixed detection of headphones being plugged and unplugged via + the headphone jack on some devices. +* Core API - GameCore - Thread names will now show up in PIX. +* Core API - PS5 - Fixed crash when looping AT9 playback, no change required, fixed + by SDK 1.00. +* Core API - PS5 - Fixed AT9 decode failure when seeking near the end of the file. +* Core API - Stadia - Fixed crash on playback of Vorbis compressed audio. +* Unity - Fixed "ERR_INVALID_HANDLE" errors in UWP builds. +* Unity - Changed banks to only be copied into the project when building. + +Notes: +* PS4 - Resonance Audio now built with SDK 7.508. +* PS5 - Updated to SDK 1.00.00.39. +* UE4 - Added GameCore platform. +* UE4 - Added support for UE4.25. +* UE4 - Added PS5 platform. + +12/05/20 2.01.01 - Studio API minor release (build 109257) +------------------------------------------------------------------------------------------ + +Features: +* Core API - Stadia - Added microphone recording support. +* Unity - Added support for separate listener attenuation position. + +Fixes: +* Studio API - Fixed issue where an instrument not on the timeline would fail to be + untriggered while the timeline is inside a source transition region. +* Studio API - Improve loudness meter performance. +* Studio API - Fixed crash that occurs with instrument hotswaps that change the + instrument and its position on the timeline while auditioning. +* Studio API - Fixed issue where scatterer instrument would spawn streaming instruments + that would exceed the polyphony limit. +* Studio API - Fixed issue where the Studio update thread could hang trying to release + an event instance where the instance being released used a streaming + programmer sound which was reused by another instance and the second + instance was still active. +* Studio API - Fixed scheduling behavior of events inside multi instruments so that the + event will play out async instruments, ahdsr modulators and adjust to + pitch modulation before playing the next item in the multi instrument. + It will still play before DSP tails. +* Core API - Fixed potential crash in the mixer or stream thread when playing + MIDI / MOD style files due to race condition. +* Core API - Android - Fixed potential crash when opening a file using the Android + asset syntax file:///android_asset/. +* Core API - PS5 - Fixed error being returned from platform specific affinity API. +* UE4 - Fixed possible crash during module shutdown if DLLs aren't loaded + correctly. +* UE4 - Fixed Android builds crashing at startup. +* Unity - Linux - Fixed FMOD_ERR_HEADERMISMATCH error due to conflict between + FMOD Studio and FMOD Ex (built into Unity) in 2019.3. +* Unity - Fixed settings bank path using wrong directory separators. +* Resonance - Fixed rare crash in Resonance Audio due to thread safety issue. + +Notes: +* GameCore - Updated to April 2020 GDK. +* Stadia - Now built with SDK 1.46. +* PS4 Now built with SDK 7.508. +* XboxOne - Now built with July 2018 QFE13 XDK. +* HTML5 - Now built with SDK 1.39.11, both fastcomp and upstream. +* Unity - Added PS5 platform. + +23/03/20 2.01.00 - Studio API major release (build 108403) +------------------------------------------------------------------------------------------ + +Features: +* Studio API - Studio::System::setListenerAttributes now supports a separate position + argument for attenuation. +* Core API - Optimized mixing and vorbis decoding. Performance increase of 2-2.5x on + all platforms. +* Core API - Optimized Multiband EQ. Performance increase of 2-3x on all platforms + for stereo and higher channel count processing. +* Core API - Added cross-platform API for setting thread affinity, stack size and + priority via FMOD_Thread_SetAttributes. +* Core API - Win - FMOD_OUTPUT_DEVICELISTCHANGED_CALLBACK now responds to default + device changes. + +Fixes: +* Studio API - Fixed issue where async instruments on a transition timeline with fade + out curves would snap to full volume when exiting the transition + timeline. +* Studio API - The end of destination and magnet regions are included as part of the + timeline length. +* Studio API - Changed behaviour of stopped async multi-instrument entries with + unlimited loop counts to not play. +* Studio API - Loop regions of lower priority that coincide with transitions are now + followed during the transition's source timeline. +* Core API - Fixed potential crash when calling Sound::getSubSound on a playing + stream, this is now prohibited and will instead return an error. +* Unity - Fixed compatibility issues with C# wrapper. FMOD objects are now passed + as IntPtr for callback arguments from native to C#. Use the constructor + of the correct type to recreate the object from the IntPtr. + +Notes: +* Core API - Calling Sound::getSubSound from FMOD_CREATESOUNDEXINFO::nonblockcallback + is no longer a synchronous operation meaning an additional callback + will execute when fetching the subsound has completed. +* Core API - Removed stackSizeStream, stackSizeNonBlocking and stackSizeMixer from + FMOD_ADVANCEDSETTINGS. These are now set via FMOD_Thread_SetAttributes. +* Core API - Removed deprecated FMOD_ADVANCEDSETTINGS::commandQueueSize member. +* Core API - Removed all platform specific thread affinity APIs, affinity is now + controlled via FMOD_Thread_SetAttributes. +* Core API - Renamed FMOD_OUTPUT_DESCRIPTION::polling to FMOD_OUTPUT_DESCRIPTION::method. +* Core API - When calling FMOD_Memory_Initialize with valid 'useralloc' and 'userfree' + callbacks, the requirement of 'userrealloc' is now optional. +* Core API - DSP Echo delay effect minimum reduced to 1 millisecond. +* FSBank - Minimum requirement for Mac version of the FSBank tool has been lifted + to macOS 10.12 due to framework update. +* Profiler - Minimum requirement for Mac version of the Profiler tool has been lifted + to macOS 10.12 due to framework update. + +02/03/20 2.00.08 - Studio API minor release (build 108014) +------------------------------------------------------------------------------------------ + +Features: +* Studio API - Added FMOD_STUDIO_EVENT_PROPERTY_COOLDOWN to set per instance cooldown. +* Studio API - Added Studio::getMemoryUsage, Bus::getMemoryUsage, + Studio::EventInstance::getMemoryUsage and FMOD_STUDIO_MEMORY_USAGE for retrieving + memory usage statistics in logging builds. + +Fixes: +* Studio API - Fixed issue with determining the end of an event inside a multi + instrument. +* Studio API - Fixed issue with determining the end of an async instrument with pitch + automation. +* Studio API - Fixed potential crash when playing a command replay from a 64bit game + on a 32bit host. +* Studio API - Fixed issue where polyphony limits on an event and bus could both apply + causing too many event instances to be stolen when starting a new event + instance. +* Studio API - Fixed issue where Studio update thread could get stuck in an infinite + loop and eventually deadlock with the game thread when a sound object + used for a programmer sound was used by more than one event instance. +* Studio API - Fixed issue where transitioning from the start of a transition region + to a destination marker using a relative transition with a tempo marker + would result in the event stopping. +* Studio API - HTML5 - Fixed missing plugin errors for banks using loudness meter, + convolution reverb or pitch shifter. These effects can be CPU intensive + so use them with caution. +* Core API - Fixed seeking accuracy of mp3 files that use small mpeg frame sizes. +* Core API - Fixed ChannelGroup::isPlaying from returning false on a parent + ChannelGroup, when children groups in certain configurations had playing + sounds. +* Core API - iOS - Fixed issue causing MP3 netstreams to not work. +* Core API - iOS - Fixed issue where FMOD_CREATECOMPRESSEDSAMPLE would not work as + expected with MP3 files. +* UE4 - Fixed crash in 4.24 caused by SetActive call in FMODAudioComponent. +* UE4 - Fixed warning log message when using the IsBankLoaded blueprint function + when the bank is not loaded. +* Unity - TextAsset banks import directory now defaults to 'FMODBanks' instead + of the root 'Assets' folder. +* Unity - HTML5 - Fixed compilation issue preventing launch. + +Notes: +* XboxOne - Now built with July 2018 QFE12 XDK. +* PS4 - Resonance Audio now built with SDK 7.008. +* HTML5 - JavaScript bindings are now separate from the main bitcode binary to + facilitate recompilation of ASM.JS / WASM or usage in strictly native + projects. + +17/01/20 2.00.07 - Studio API minor release (build 107206) +------------------------------------------------------------------------------------------ + +Features: +* Unity - Changing bank import type now gives you the option of removing the + previously imported banks. +* UE4 - Added getParameter functions for getting user and final values. + +Fixes: +* Studio API - Fixed application of fade curves to instruments when transitioning + immediately between transition timelines. +* Studio API - Fixed Studio::EventDescription::is3D to return true for events with + scatterer instruments, for 3D instruments inside multi instruments, and + for spatializers on non-master tracks. +* Studio API - Fixed relative transition calculation when performing a transition jump + that would incorrectly end up at the beginning instead of the end of the + destination or vice versa. +* Studio API - Fixed issue when encountering a loop region in a destination timeline + which would stop the event in specific circumstances. +* Studio API - Fixed crash when profiling runtime with an older Studio tool version. +* Core API - Fixed asserts from setting readonly DSP data parameters when the setter + isn't implemented. +* Core API - Fixed FSBankLib Vorbis encoder not supporting quality zero as default. +* Core API - Fixed System::setDriver not always applying if called after + System::setOutput when the device list has changed. +* Core API - Fixed DSP_PARAMETER_DESC being populated with incorrect data in C#. +* Core API - Fixed MP3 codec not respecting FMOD_ACCURATETIME flag when played as + FMOD_CREATECOMPRESSEDSAMPLE. +* UE4 - Fixed EncryptionKey not being saved to packaged game. Bank encryption keys + in existing projects will need to be re-entered after upgrading. +* UE4 - XBoxOne - Fixed third party plugin path. +* UE4 - Fixed FMODEvent::GetParameterDescriptions not working in built game. +* Unity - Fix lag in editor due to banks being reimported. +* Unity - Fixed FMODStudioCache causing deserialization exceptions by moving the + file to a separate cache folder. + +Notes: +* PS4 - Now built with SDK 7.008.031. +* Stadia - Now built with SDK 1.38. +* Switch - Now built with SDK 9.3.0. +* HTML5 - Now built with sdk-1.38.19-64bit +* UE4 - Added support for UE4.24. +* UE4 - Added support for Stadia. +* OSX - Updated Resonance Audio plugin with performance improvements. + +20/11/19 2.00.06 - Studio API minor release (build 106220) +------------------------------------------------------------------------------------------ + +Fixes: +* Studio API - Fixed issue where a loop on an instrument followed immediately by a + transition timeline could result in a short pause in playback. +* Core API - Mac - Fix crash calling recordStart at the same time as unplugging a USB + microphone. +* Core API - Android - minimum Android version for AAudio support changed to 8.1 + (API 27) to circumvent AAudio RefBase crash issue. +* Core API - XboxOne - Fixed background music port going silent if XAudio is + initialized outside of FMOD. +* Core API - Stadia - Fixed crash at static initialization time when using the logging + build on system software v1.37 and newer. +* FSBank API - Win - Fixed bug introduced in 2.00.05 which prevented banks being built + when passing a non-empty encryption key to FSBank_Build. +* UE4 - Fixed asset loading errors on dedicated server. +* Unity - Fixed integration deleting non FMOD bank/bytes files when refreshing. +* Unity - Fixed handling of iOS AudioSession interruption notifications. + +Notes: +* iOS - Now built with iOS SDK 13.1 and tvOS SDK 13.0 (Xcode 11.1). +* Mac - Now built with macOS SDK 10.15 (Xcode 11.1). + +09/10/19 2.00.05 - Studio API minor release (build 105402) +------------------------------------------------------------------------------------------ + +Features: +* Studio API - Add event and bus instance CPU profiling to the FMOD Studio API. +* Core API - Stadia - Added voice output port FMOD_STADIA_PORT_TYPE_VOICE. + +Fixes: +* Studio API - Fixed crash caused by creating an instance of an event containing a + nested event which has not been loaded. +* Studio API - Fixed pitch changes on a bus propagating across sidechain connections. +* Studio API - Fixed application of transition fade curves to parameter triggered + instruments on multi track events. +* Core API - Fixed mixer falling silent due to very small but not denormal positions + being passed into the API. +* Core API - Fixed crash when processing loops of FMOD_DSPCONNECTION_TYPE_SEND + or FMOD_DSPCONNECTION_TYPE_SEND_SIDECHAIN. +* Unity - Removed high frequency of UnityEditor.SetDirty calls. +* Unity - Fixed issues with using relative paths in linked project/bank directory. + +Notes: +* Switch - Now built with SDK 8.3.0. +* XboxOne - Now built with July 2018 QFE9 XDK. + +06/09/19 2.00.04 - Studio API minor release (build 104705) +------------------------------------------------------------------------------------------ + +Features: +* Official support for Stadia as a separate platform is now complete, anyone using + the Linux version should migrate across. + +Fixes: +* Studio API - Fixed issue where programmer sound without an associated sound would + have unexpected behavior when modulated. +* Studio API - Fixed issue where instruments with low polyphony would incorrectly fail + to play. +* Studio API - Fixed looping multi-instrument with streaming instruments cutting + off near the end of the loop when the length of the multi-instrument is + slightly longer than a multiple of the instrument length. +* Studio API - Fixed issue where automation points are reused in transition timelines + when both the timelines and the transition have no automation points. +* Core API - Fixed crash caused by unlinking a convolution reverb dsp during a mix. +* Core API - Fixed potential alignment crash on ARM devices if using FMOD_DSP_PAN. +* Core API - Fixed leak of socket handles when binding to a listening port fails. +* Core API - Win / UWP / XboxOne - Fixed incorrect DSP CPU reporting when using + FMOD_OUTPUTTYPE_WINSONIC. +* UE4 - Fixed crash in PlayEventAtLocation when world context is invalid. +* UE4 - Fixed failed to load errors when playing in Standalone. +* UE4 - Switch to using "Additional non-asset directories to copy" packaging + setting for FMOD banks to avoid possible deadlocks at runtime. +* Unity - Fixed banks being copied to project repeatedly when using AssetBundles. +* Unity - Fixed Events not auditioning from split banks. +* Unity - Fixed RuntimeManager being able to update the 3DAttributes for an + Event Instance multiple times using different values. + +02/08/19 2.00.03 - Studio API minor release (build 103912) +------------------------------------------------------------------------------------------ + +Features: +* Core API - Improved ASIO channel mapping via FMOD_ADVANCEDSETTINGS::ASIOSpeakerList. + Skips irrelevant speakers with FMOD_SPEAKER_NONE and supports devices up + to 32 channels without using FMOD_SPEAKERMODE_RAW. +* Core API - Android - Added support for AAudio via FMOD_OUTPUTTYPE_AAUDIO. +* Core API - PS4 - Added ResonanceAudio plugin for PS4. +* Core API - Android - Added support for setting thread affinity via + FMOD_Android_SetThreadAffinity. +* UE4 - Added blueprint node for Studio::EventInstance::release. +* Unity - Added setParameter by name wrapper function to StudioEventEmitter.Features: +* Unity - Fixed crash when setting logging level to LOG and entering playback. + +Fixes: +* Core API - Fixed rare crash on Studio::System::release. +* UE4 - Fixed FMODAudioComponent not being occluded are being stopped and + restarted. +* Unity - Fixed project determinism issue causing paths to update when opening + the project on Windows and Mac. +* HTML5 - FMOD Studio examples updated with 2.0 API changes. + +Notes: +* Switch - Now built with SDK 8.2.0. +* XboxOne - Now built with July 2018 QFE7 XDK. + +18/06/19 2.00.02 - Studio API minor release (build 102879) +------------------------------------------------------------------------------------------ + +Features: +* Core API - C# - Added getters to DSP_PARAMETER_FFT that will fill a user provided + buffer, to avoid garbage collection. +* Studio API - FMOD_STUDIO_EVENT_CALLBACK_SOUND_PLAYED, + FMOD_STUDIO_EVENT_CALLBACK_TIMELINE_MARKER, and + FMOD_STUDIO_EVENT_CALLBACK_SOUND_STOPPED callbacks are now called from + nested events. +* UE4 - Added support for tvOS. +* Unity - StudioEventEmitter and EventRef now support the use of GUIDs or paths. +* Unity - StudioListener components will be assigned an index from the + RuntimeManager at runtime, rather than user specified. + +Fixes: +* Core API - Win 64bit - Skip JACK ASIO driver when enumerating ASIO devices. An + unrecoverable crash occurs in the driver when attempting to query its + capabilities. +* UE4 - Fixed "Accessed too early?" crash by changing the plugin loading phase. +* UE4 - Fixed OnEventStopped not being broadcast when the FMODAudioComponent + is destroyed. +* Unity - Fixed third party plugin paths for Win32 and Mac. +* Unity - Changed the Debug Overlay Window ID to avoid conflicts. +* Unity - iOS - Fixed sound stopping in editor when focus is lost. + +* PS4 - Now built with SDK 6.508.021. + +09/05/19 2.00.01 - Studio API minor release (build 102182) +------------------------------------------------------------------------------------------ + +Features: +* Core API - ChannelMix DSP now supports re-routing input channels. +* UE4 - Added support for UE4.22. +* UE4 - Added Encryption Key to the settings for loading sounds from + encrypted banks. +* UE4 - Added Play-In-Editor logging options to Plugin Settings. +* UE4 - Android - Added support for x86_64. +* Unity - Added SetParameter by ID to StudioEventEmitter. +* Unity - Added Encryption Key to the settings for loading sounds from + encrypted banks. +* Unity - Added mouse events to StudioEventEmitter trigger options. + +Fixes: +* Studio API - Fixed assert caused by a backwards transition with a lead out on a + transition timeline with callbacks for timeline markers. +* Studio API - Fixed bug in cone angle built-in parameter calculation when using + FMOD_INIT_3D_RIGHTHANDED. +* Core API - Fixed virtualized objects from object spatializer being silenced + (introduced in 2.00.00). +* Core API - Fix crash when using convolution reverb with a DSP buffer size of 4096 or + above. +* Core API - Fix crash trying to load corrupt WAV files with 0 length chunk size. +* Core API - Fix crash trying to load corrupt MP3 files. +* Core API - Fixed send dsp data being retained after being bypassed. +* Core API - iOS - Fixed crash when suspending or resuming the mixer while audio is + loading. +* UE4 - Fixed Ambient LPF values not being set properly. +* UE4 - Fixed builds failing due to the integration being loaded after + blueprints. +* UE4 - Fixed listener using the correct nested AudioVolume. +* Unity - Fixed handling banks in sub-directories. +* Unity - Fixed IOException when trying to copy banks into StreamingAssets. +* Unity - Fixed Events previewed in Timeline not stopping. +* Unity - Fixed StudioListeners with an index larger than zero causing errors. +* Unity - Fixed FMODStudioSettings.asset modifying bank list order when + using different scripting backends. +* Unity - Remove garbage collection overhead in DebugOverlay. +* Unity - Fixed creating duplicate objects when loading banks for the Editor. +* Unity - Fixed Emitters cleaning up properly when using one shot Events. +* Unity - Fixed paths for plugins in editor. +* Unity - Fixed build errors on iOS / tvOS due to "lowLevelSystem" references. +* Unity - Removed excessive error logging when no project or folder linked + to the integration. +* Unity - Fixed occasional issues with copying banks into StreamingAssets. +* Unity - Fixed Master Bank not being found if in a sub directory. +* Unity - Fixed StudioParameterTrigger IndexOutOfRange exception. + +Notes: +* XboxOne - Now built with July 2018 QFE4 XDK. + +14/03/19 2.00.00 - Studio API major release (build 101145) +------------------------------------------------------------------------------------------ + +Features: +* Studio API - Bank sample data encryption is now supported via the Studio API. + Use FMOD_STUDIO_ADVANCEDSETTINGS.encryptionkey to specify the + encryption key to use when opening banks and use the + FMOD_STUDIO_LOAD_BANK_UNENCRYPTED flag to load unencrypted banks + if an encryption key has been set. +* Studio API - Added built-in parameter for speed. +* Studio API - Added support for global parameters. +* Studio API - Added support for global mixer automation. +* Studio API - Added the ability to set a custom final value on an AHDSR modulator. +* Studio API - Added ignoreseekspeed argument to public api setParameter functions. +* Studio API - Added the ability to automate time based ahdsr properties. +* Studio API - Added a command instrument with the ability to stop all non-nested + instances of an event description. +* Core API - Added output device enumeration to Windows Sonic output plugin. +* Unity - Switch platform settings have been moved into a separate dropdown. + +Fixes: +* Studio API - Event parameters with "Hold value during playback" enabled now + snap to their target values when their event is started. +* Studio API - Changed quantization calculation to use future tempo markers if no past + tempo markers are present, and default to 4/4 timing at 120 bmp if no + tempo markers are present. +* Studio API - Transition regions not using quantization perform any probability + determinations each time all other required conditions are newly met. +* Studio API - Sidechain modulators now correctly handle multiple sidechain inputs. +* Core API - Fixed volume spike due to tremolo DSP with high duty setting. +* Core API - Fixed excessive instances of clipping that occur when adjusting + the FMOD_DSP_THREE_EQ_LOWCROSSOVER value of a DSPThreeEQ DSP in + the low frequency range. + +Notes: +* Updated Resonance Audio plugin removing additional transformation of occlusion values. + If previous occlusion calculation is required, replace the resonance audio libraries + with their 1.10 versions. +* The GoogleVR plugin deprecated in 1.10 has now been removed, Resonance Audio + is available as a functional drop in replacement. +* Studio API - The parameter API has been updated. See the "What's New in 2.00" + section in the API documentation for details. +* Studio API - The deprecated ParameterInstance class has been removed. +* Studio API - Seek speed is now applied when parameter values are modified by + AHDSR or sidechain modulation. +* Studio API - Parameters with seek speed now snap to their target value when + the event stops. +* Studio API - Automatic parameters no longer update their user value. The + automatically calculated value can be retrieved using the finalvalue + parameter of Studio::EventInstance::getParameter. +* Studio API - Studio::System::getBank no longer supports getting a loaded bank from + the system by filename. +* Core API - System::getFileUsage will no longer count bytes read from user callbacks. +* Core API - Automatic SRS downmix from 5.1 to 2.0 has been removed. +* Core API - System::getSoundRAM API has been removed. +* Core API - FMOD_ADVANCEDSETTINGS::HRTFMinAngle, HRTFMaxAngle, HRTFFreq removed +* Core API - FMOD_CREATESOUNDEXINFO::channelmask removed +* Core API - Win - Support for paths using Windows ANSI Code Page (ACP) encoding + has been removed. Paths must be UTF-8 encoded. +* Core API - Win - The minimum supported version of Windows has been lifted + from Windows XP to Windows 7. Coupled with this change we have + removed the legacy DirectSound and WinMM output modes. +* Win / UWP - All binaries no longer have a suffix indicating the target architecture, + instead the files are separated by directories in the installer. + +14/03/19 1.10.12 - Studio API minor release (build 101101) +------------------------------------------------------------------------------------------ + +Features: +* Unity - Added option to specify Live Update port number in editor settings. +* Unity - Changed StudioEventEmitter private members to protected. + +Fixes: +* Studio API - Avoid stalling when unloading a bank which is waiting to load sample data + behind other banks. +* Core API - FMOD_OUTPUTTYPE_ASIO is now compatible with more devices without + requiring calls to System::setDSPBufferSize. +* Core API - Android - Fixed instances of audio stuttering that occurred on some + devices by dynamically adding latency to compensate. +* Core API - Fixed MP3 files with MPEG 2.5 encoding having distortion on some files. +* Unity - Fixed plugins not being found on Android. +* Unity - Fix for banks being read only when trying to copy new banks to + StreamingAssets. +* Unity - Fixed BatchMode builds not being able to find the MasterBank. +* Unity - Fixed BatchMode builds not building with banks. +* Unity - Changed console default thread affinity to not use the game thread. +* Unity - Fixed Strings bank not being found or copied (introduced in 1.10.10). + +01/02/19 1.10.11 - Studio API minor release (build 99976) +------------------------------------------------------------------------------------------ + +Features: +* Studio API - Add streamingscheduledelay member to FMOD_STUDIO_ADVANCEDSETTINGS. May be + used to reduce latency when scheduling events containing streaming + sounds. +* UE4 - Expose the FMODAudioComponent::bAutoDestroy property to the + PlayEventAttached Blueprint function. + +Fixes: +* Studio API - Fixed fire and forget event instances not releasing when another instance + of the same event is active. +* Studio API - Fixed a bug with multi-instruments when using looping and initial seek + which caused a gap of silence the same length as the initial seek when + scheduling the second instrument. +* Core API - Fixed MP3 files using Xing headers from having incorrect seek positions + when using Channel::setPosition. +* Core API - Fixed potential crash caused by third party applications sending + data to the FMOD profiler port. +* Core API - Fixed issue where bypassed faders and convolution reverb dsps could + silence their output. +* UE4 - Fixed 'An invalid object handle' errors from FMODAudioComponent + in sequencer after reloading banks. +* UE4 - Fixed playback not working correctly in Sequencer. +* UE4 - Fixed error from FindEventInstances if zero events found. +* UE4 - Fixed Programmer Sounds not auditioning in Editor. +* UE4 - Fixed events not playing in Sequencer. +* Unity - Fixed RuntimeManager being saved to scene after auditioning timeline. +* Unity - Fix AttachInstanceToGameObject positioning not being applied correctly. + +Notes: +* PS4 - Now built with SDK 6.008.051. +* iOS - Now built with iOS SDK 12.1 and tvOS SDK 12.1 (Xcode 10.1) which + necessitates lifting the min spec to 8.0 for iOS, no change for tvOS. +* Mac - Now built with macOS SDK 10.14 (Xcode 10.1) which necessitates + lifting the min spec to 10.7 and the removal of x86 support. +* Android - Added support for x86_64. + +03/12/18 1.10.10 - Studio API minor release (build 98815) +------------------------------------------------------------------------------------------ + +Features: +* Studio API - Added FMOD_STUDIO_EVENT_CALLBACK_REAL_TO_VIRTUAL and + FMOD_STUDIO_EVENT_CALLBACK_VIRTUAL_TO_REAL. +* Core API - Added DSP::GetCPUUsage to public API. +* Core API - Linux - Added support for FMOD_ALSA_DEVICE environment variable to + allow a user to specify an ALSA device. +* HTML5 - Add Web Assembly support (WASM) to HTML5 version of FMOD Core API + and Studio API. Memory usage halved, CPU speed improvements of about 30% +* Unity - Android - Added ARM64 support. +* Unity - Add support for working with multiple master banks and strings banks. + +Fixes: +* Studio API - Fixed multi-instrument playlist entries set to loop infinitely not + looping correctly. +* Studio API - Fixed pop that occurs at the start of a transition destination section + with a fade curves. +* Studio API - Fixed nested event instances stopping when their parent is paused. +* Studio API - HTML5 - Fix Studio::System::getSoundInfo not working +* Core API - System::setDSPBufferSize validates arguments for integer overflow. +* Core API - Fixed potential CPU usage spike due to dsp flush on releasing a + programmer sound during the destroy callback. +* Core API - Opening a playlist from a URL now validates that the playlist file is a + text file and falls back to codec probing if binary data is found. +* Core API - Linux - Fixed occasional distortion that can occur when using + PulseAudio. +* FSBank API - Fixed issue where a file change would not be detected when it has the + same modified time. +* UE4 - Fixed occlusion using the trace channel selected in editor. +* UE4 - Fixed plugin include directory paths. +* UE4 - Fixed crash caused by trying to access objects pending kill. +* UE4 - Fixed occlusion not working. +* UE4 - Fixed programmer sounds trying to access the FMODStudioModule outside + of the main thread, while also improving the performance of the + FMODAudioComponent. +* Unity - Fixed Asset Folder name updating after each keystroke. +* Unity - Fixed Timeline playables playing the previously selected event. +* Unity - Fixed "Bus not found" error caused when no banks loaded in editor. +* Unity - iOS - Fixed Events not resuming after returning focus. +* Unity - PS4 - Fixed logging libs being used for development builds. + +Notes: +* Studio API - Reduced the maximum number of parameter values which can be set in a + batch using Studio::EventInstance::setParameterValuesByIndices to 64. +* HTML5 - Now built with Emscripten v1.38.15 +* Switch - Now built with SDK 6.4.0. + +11/10/18 1.10.09 - Studio API minor release (build 97915) +------------------------------------------------------------------------------------------ + +Features: +* Studio API - Added globally sequential play mode to multi and scatterer instruments. +* Unity - All logging will now be displayed in the editor console. The logging + level can be changed using the dropdown in settings. + +Fixes: +* Studio API - Fixed missing bank warnings when playing a CommandReplay using + FMOD_STUDIO_COMMANDREPLAY_SKIP_BANK_LOAD mode. +* Studio API - UWP - Fixed Studio thread affinity not applying correctly. +* Studio API - Android / UWP - Fixed CommandReplay not working with AppX and + APK based paths. +* Core API - Fixed loading of encrypted FSBs. +* Core API - Fixed several panning issues when using FMOD_SPEAKERMODE_QUAD or + FMOD_SPEAKERMODE_SURROUND, does not affect Studio API usage. +* Core API - Fixed potential hang from internal fade point usage. +* Core API - Fixed ChannelControl::setMixLevelsInput not remembering the set + values when FMOD_3D is applied. +* Core API - Fixed potential cpu usage spike due to thread lock on releasing a + non-gpu convolution reverb dsp. +* Core API - Fixed support of FMOD_3D_INVERSETAPEREDROLLOFF. +* Core API - Fixed potential cpu usage spike due to thread lock on releasing a + transciever dsp. +* Core API - Win / UWP - Fixed Windows Sonic initialization failure when audio + device is configured for a sample rate other than 48KHz. +* Core API - Linux - Fixed ALSA default audio device selection. +* Core API - Android - Fixed crash if System::mixerSuspend is called before + System::init. +* Unity - iOS - Fixed playback not resuming after alarm / call interruptions. + +Notes: +* Updated Resonance Audio plugin to add support for near field effects, and added + FMOD_DSP_PARAMETER_OVERALLGAIN parameter to support virtualization. +* PS4 - Now built with SDK 6.008.001. +* XboxOne - Now built with July 2018 QFE2 XDK. + +10/08/18 1.10.08 - Studio API minor release (build 96768) +------------------------------------------------------------------------------------------ + +Features: +* UE4 - FMODAudioComponent is now blueprintable. + +Fixes: +* Studio API - Fixed potential crash when calling Studio::EventInstance::release from + the FMOD_STUDIO_EVENT_CALLBACK_STOPPED triggered by Bus::stopAllEvents. +* Studio API - Fixed a bug where changes to a parameter value made while an event was in + the FMOD_STUDIO_PLAYBACK_STARTING state would not update automation + controllers (introduced in 1.10.02). +* Studio API - Fixed Studio::CommandReplay::release not cleaning up resources + unless Studio::CommandReplay::stop was called earlier. +* Studio API - HTML5/WebGL - Fixed the following functions that didn't work. + - Studio::Bank::getID + - Studio::EventDescription::getID + - Studio::Bus::Bank::getID + - Studio::VCA::Bank::getID + - Studio::System::lookupID + - Studio::Bank::getStringInfo + - Studio::System::getBankList + - Studio::EventDescription::getInstanceList + - Studio::Bank::getEventList + - Studio::Bank::getBusList + - Studio::Bank::getVCAList +* Core API - Fixed audible artifacts when adjusting pitch near 1.0. Issue + can be seen from doppler calculations with small velocities. +* Core API - Improved stuttering issue when using Windows Sonic with high + DSP CPU usage. +* Core API - Fixed init errors on output devices that operate at 384KHz such + as the Aune X1s. +* Core API - Windows - Improved compatibility with some audio drivers by falling + back to stereo. +* Core API - HTML5/WebGL - Added support for unimplemented System::createDSP + with FMOD_DSP_DESCRIPTION. DSP callbacks are provided to allow + custom DSP support in Javascript. Added dsp_custom example to + example folder. +* Core API - HTML5/WebGL - Added support for unimplemented + ChannelControl::setCallback. +* Core API - HTML5/WebGL - Enabled support for 5.1 / Surround sound in a browser. + Only Firefox supports 5.1 so far, out of all browsers tested. +* UE4 - Fixed Activate and SetActive not working for FMODAudioComponents. +* UE4 - Fixed Simulating in editor producing no sound. +* UE4 - Fixed BlueprintStatics::LoadBank not working for banks containing spaces. +* UE4 - Fixed asset banks not displaying in editor or being loaded. +* Unity - Fixed warnings due to loading sample data on a metadata-only bank + before its asset bank is loaded. +* Unity - Fixed source project not updating if the old path is still valid. + +Notes: +* XboxOne - Now built with April 2018 QFE1 XDK. + +03/07/18 1.10.07 - Studio API minor release (build 95892) +------------------------------------------------------------------------------------------ + +Features: +* Unity - Added support for Timeline (from Unity 2017.1 onwards). + +Fixes: +* Studio API - The FMOD Gain effect is now taken into account when applying event + stealing behavior and virtualizing FMOD::Channels. +* Core API - Win/XboxOne - Fixed crash during System::recordStart if the + device was unplugged. +* Core API - Win - System::loadPlugin now correctly handles UTF-8 encoded + paths. Support for paths using ACP is deprecated and will be removed in + FMOD 1.11. +* UE4 - Fixed auditioning events not taking parameter values into account. +* UE4 - Fixed game crash when built using Event-Driven-Loader. + +06/06/18 1.10.06 - Studio API minor release (build 95384) +------------------------------------------------------------------------------------------ + +Features: +* Unity - Added SampleRate for Play-In-Editor settings. +* Unity - Added scripts for setting thread affinity on specific consoles. +* HTML5 - Updated core API and studio API examples to handle chrome mute until + mouse click or touch event happens, via System::mixerSuspend / + System::mixerResume. + +Fixes: +* Core API - Fixed potential crash if a stream naturally ends at the same time + as being released. +* Core API - Fixed incorrect parsing of large ID3 tags. +* Core API - Fixed FMOD_ERR_FILE_BAD error when trying to call setPosition to a point + past 2GB bytes in a file. +* Core API - Fixed crash if Windows Sonic output mode is used with the object + spatializer and the device is unplugged. +* Core API - Fixed stall in Sound::release for FSB files if another thread is + performing a createSound operation. +* Core API - Fixed potential crash when playing a netstream with tags. +* Core API - Fixed OGG netstreams not automatically stopping if the stream goes + offline. +* Core API - Fixed potential invalid memory access when a channel group is released + (introduced in 1.10.02). +* Core API - Channel group audibility now factors in attenuation due to 3D effects + when using ChannelControl::setMode(FMOD_3D). +* Core API - HTML5/WebGL - Fix System::setDriver(0) causing garbled audio when trying + to respond to a touch event and the audio is already active. +* Core API - HTML5/WebGL - Fix floating point accuracy issues making MIDI file sound + out of tune. +* Core API - UWP - Fixed default affinity mask incorrectly putting all threads + on core 0, now threads default to distributing among all cores. +* UE4 - Removed FMODAudioComponent ticking when deactivated. + +Notes: +* Core API - Windows Sonic output mode no longer requires a block size of 480. +* XboxOne - Now built with February 2018 XDK. +* Switch - Now built with SDK 5.3.0. + +26/04/18 1.10.05 - Studio API minor release (build 94661) +------------------------------------------------------------------------------------------ + +Features: +* Core API - Add "Channel mask" tag to MIDI file support, to allow a user to + map used / unused channels in a midi file to the channel IDs in the + Sound::setMusicChannelVolume / Sound::getMusicChannelVolume functions +* Core API - Fixed System::recordStart memory leak if an error was returned. +* UE4 - File buffer size is now customizable in the settings menu. + +Fixes: +* Studio API - Fixed a rare bug where Studio::System::Update could hang if a streaming + sound encountered an error. +* Studio API - Fixed events getting stuck in a paused state if they were restarted while + waiting for sample data to load (introduced in 1.10.02). +* Studio API - Fixed an issue preventing network streams being used as programmer + sounds. +* Core API - Fixed rare hang during Sound::release when releasing a streaming sound in + the FMOD_OPENSTATE_ERROR state. +* Core API - Switch - Fixed Vorbis encoded banks producing silence when using + multimedia.nso (UE4 uses this). +* UE4 - Fixed FMODAudioComponent programmer sound creation flags. +* UE4 - Switch - Fixed performance by changing default thread affinity. +* Unity - Fixed FMODStudioSettings asset dirty flag being set unnecessarily. +* Unity - Fixed callbacks crashing when using IL2CPP or Mono on some platforms. +* Unity - Fixed editor system not being cleaned up on Play-In-Editor start. +* Unity - Android - Fixed load bank returning ERR_INVALID_HANDLE. + +Notes: +* Core API - It is now possible to initialize WinSonic output even if the user + has not enabled spatial audio on their default device. The platform + will provide a non-binaural downmix to the user desired speaker mode. +* PS4 - Now built with SDK 5.508.021. + +05/03/18 1.10.04 - Studio API minor release (build 93853) +------------------------------------------------------------------------------------------ + +Features: +* Studio API - Improved bank loading performance when there are already a large number + of loaded events. +* UE4 - Added the ability to enable Live Update while in editor for auditioning. + The Editor will need to be restarted for this setting to take effect. + +Fixes: +* Studio API - Fixed a bug where Studio::System::Update could fail with + FMOD_ERR_INVALID_HANDLE or FMOD_ERR_CHANNEL_STOLEN, which could lead to + memory or performance problems. Introduced in 1.10.03. +* Core API - XboxOne - Fixed XMA hang that can occur after actively using + many XMA voices for several days. +* Unity - Fixed MobileHigh/Low classifications for Apple Devices. Pre iPhone 5 + is classed as MobileLow. + +01/02/18 1.10.03 - Studio API minor release (build 93157) +------------------------------------------------------------------------------------------ + +Features: +* Core API - Added ASIO support for drivers that use PCM32 as a container for + smaller sized data. +* Profiler - Draw different DSP connection types with different line styles. +* UE4 - Added option to specify memory pool size, per platform, in the project + FMOD Studio settings. +* UE4 - Now complying with IWYU mode, this should increase compilation speed. + +Fixes: +* Studio API - Fixed the DSP network sometimes getting into a bad state when a sidechain + is connected to the next effect in the chain. +* Studio API - Fixed event playback sometimes using stale parameter values. +* Studio API - Fixed events failing to stop if they contain empty Single Instruments. +* Core API - Fixed potential crash in device list changed callback when there + are no available devices remaining. +* Core API - Fix 3D 5.1 sound not panning correctly if ChannelControl::set3DLevel(0) is used. +* Core API - Fixed ID3v2.4 compatibility issue causing missing or corrupted tags. +* Core API - Android - Fixed incorrect floating point check on ARM64 devices + causing FMOD_ERR_NEEDSHARDWARE with some devices. +* Core API - XboxOne - Fixed race condition causing internal errors with XMA + sounds loaded as FMOD_CREATECOMPRESSEDSAMPLE. +* Core API - PS4 - Fixed internal assertion caused by setPosition on an AT9 + sound loaded as FMOD_CREATECOMPRESSEDSAMPLE. +* FSBank API - Fixed creation of C header so it goes next to the FSB instead + of the working directory of the application. +* Unity - Fixed pause working properly in Play In Editor mode. +* Unity - Removed excess memory allocation from APIs that return strings in C#. +* UE4 - Fixed velocity of FMODAudioComponents. + +Notes: +* Unity - Added support for Unity 2017.3. +* Android - Now built with NDK r16b. +* Android - Minimum Android version is now API level 14 due to NDK r16b + deprecating older versions. +* Switch - Now built with SDK 3.5.1. + +07/12/17 1.10.02 - Studio API minor release (build 92217) +------------------------------------------------------------------------------------------ + +Features: +* Core API - UWP - Added Windows Sonic support. +* Core API - UWP - Added support for setting thread affinity via + FMOD_UWP_SetThreadAffinity. + +Fixes: +* Studio API - Fixed Quietest stealing behavior so new events don't start if they are + quieter than all currently playing events. +* Studio API - Fixed buses that have reached their Max Instances limit incorrectly + preventing their input buses from applying their stealing behavior. +* Studio API - Fixed a crash caused by wav files with invalid loop points. +* Core API - Fixed recording devices still being marked as connected when + switching to FMOD_OUTPUTTYPE_NOSOUND. +* Core API - UWP - Made device reset / unplug behavior more robust against failure. +* Core API - XboxOne - Fixed WASAPI init error if WinSonic was attempted first. +* FSBank API - Fixed crash in 64bit version when encoding low sample rate mono + sounds as Vorbis with low quality. +* Unity - PlayOneshot and PlayOneshotAttached now log a warning when the + event is not found, rather than throwing an exception. + +Notes: +* Added Resonance Audio plugin version 1.0, this plugin represents the continuation + of the Google VR plugin under new branding. The Google VR plugin is now considered + deprecated in favour of Resonance Audio, consider migrating to the new plugin as + the GVR plugin will be removed in FMOD 1.11. +* XboxOne - Now built with June 2017 QFE 8 XDK. + +01/11/17 1.10.01 - Studio API minor release (build 91339) +------------------------------------------------------------------------------------------ + +Features: +* UE4 - Expose Studio::Bus::stopAllEvents to be useable through blueprints. +* Unity - Event length displayed in event browser for one shot events. + +Fixes: +* Studio API - Fixed modulation on plugin instruments using the parent event's lifetime + rather than the instrument's lifetime. +* Studio API - Fixed a live update issue where asset files would not reload after being + moved on disk. +* Studio API - Fixed a bug which caused sounds to pan incorrectly when using + FMOD_INIT_3D_RIGHTHANDED. +* Studio API - PS4 - Fixed excessive binary size caused by inclusion of debug symbols. +* Core API - Fixed potential crash when re-initializing System after failure. +* Core API - Fixed compatibility issues with Windows XP. +* Core API - Android - Fixed exported symbols to avoid issues with unwinder. +* Core API - Android - Automatic output mode selection will now choose AudioTrack + rather than OpenSL if Bluetooth is enabled to avoid stuttering. +* Core API - XboxOne - Ensure WinSonic internal threads are assigned to the + same core as the FMOD mixer. +* FSBank API - Fixed crash when encoding very long audio files. +* UE4 - Integration now handles application interruption by pausing and resuming + the mixer. +* UE4 - Fixed SetEvent not setting or using new event. +* UE4 - Fixed XboxOne thread affinity struct setup. +* UE4 - Removed engine version ifdef's. +* UE4 - Fixed integration attempting to set the initial value of + built-in parameters. +* Unity - Fixed compatibility for Unity 5.0 & 5.1. +* Unity - Added check to see if any banks have been loaded before trying to pause. +* Unity - Allow StringHelper to fast return if string is null. + +Notes: +* Updated Google VR plugin to version 0.6.1. +* Studio API - Studio::EventInstance::set3DAttributes and + Studio::System::setListenerAttributes will now return + FMOD_ERR_INVALID_PARAM if the forward or up vectors are zero. In + logging builds warnings will be logged if the forward and up vectors are + not orthonormal. +* Core API - The convolution reverb effect will not accept impulse response data if + the system is not using a power-of-two DSP buffer size. Windows Sonic + currently requires a DSP buffer size of 480 making it incompatible with + convolution reverb until this requirement is lifted. +* PS4 - Now built with SDK 5.008.001. +* Unity - Exposed editor script classes for in-game FMOD objects as public. +* Unity - Exposed StudioEventEmitter's EventInstance as public to allow + easier integration with custom plugins. + +19/09/17 1.10.00 - Studio API major release (build 90329) +------------------------------------------------------------------------------------------ + +Features: +* Core API - Added FMOD_MAX_SYSTEMS constant, currently 8. +* Core API - Exposed FMOD_DSP_FADER_GAIN on FMOD_DSP_TYPE_FADER. +* Core API - Added FMOD_SPEAKERMODE_7POINT1POINT4 speaker mode which includes + four height speakers to be used with Windows Sonic output. +* Core API - Added FMOD_DSP_PAN_2D_HEIGHT_BLEND parameter to FMOD_DSP_TYPE_PAN + that allows mixing ground speaker signal into the height speakers + and vice versa. +* Core API - Windows & XboxOne - Added Windows Sonic output plugin to support + rendering multichannel (with height) speaker mode 7.1.4 as well + as dynamic objects via FMOD_DSP_TYPE_OBJECTPAN. +* Core API - PS Vita - Switched FMOD_PSVita_SetThreadAffinity to accept a + mask instead of a core number to allow floating threads. +* Core API - Added FMOD_OUTPUT_REQUESTRESET to FMOD_OUTPUT_STATE to allow output + plugins to request they be reset by the System. + +Fixes: +* Studio API - Sequential multi and scatterer instruments now track their current + playlist entry on a per-event-instance basis, rather than globally. +* UE4 - Removed all reference to Oculus, now that Oculus functions as + all other FMOD Studio plugins. +* UE4 - Removed all legacy UE4 version code, if you are not using UE4.16 + the plugin will not work without making changes to source code. +* UE4 - Overhauled details interaction in editor and improved usability. + Grouped all FMOD functionality together, added Parameters, and + removed unnecessary information from attenuation/occlusion. +* Unity - Removed garbage allocations from C# wrapper. + +Notes: +* Updated Google VR plugin to version 0.6.0. +* Studio API - Changed the behaviour of nested events to stop when idle even + when there are instruments on parameters. This makes nested + events match the behaviour of top level events. Events which + depend on the old behaviour need to be manually fixed up by (for + example) adding a sustain point to the nested events timeline. +* Core API - FMOD_DSP_TYPE_ENVELOPEFOLLOWER is now deprecated and will be + removed in a future release. +* Core API - Increment Plugin API version for Output plugins. Dynamic library + Output Plugins must be rebuilt. +* Android - Logging version will now produce proper crash stacks but due to + binary size increase the release version will continue to not. +* XboxOne - Removed "acp" and "feeder" from FMOD_XBOXONE_THREADAFFINITY. + Both threads were removed in previous versions and setting them + did nothing. +* UE4 - AudioComponents using occlusion from previous versions are NOT + compatible with this version. Occlusion and Attenuation now do + not rely on UE4 structs. + +11/09/17 1.09.08 - Studio API minor release (build 90162) +------------------------------------------------------------------------------------------ + +Fixes: +* Core API - Fixed extraneous logging. + +07/09/17 1.09.07 - Studio API minor release (build 90008) +------------------------------------------------------------------------------------------ + +Features: +* UE4 - Cache dsp used for occlusion lowpass effect & add support for + use of Multiband EQ (lowpass on band A only). +* UE4 - FMODAudioComponent now reuses event instances until the object + is no longer needed or Release() is called. +* UE4 - Added support for UWP. +* Unity - Added support for Unity v2017.1. +* Unity - Added a button in the FMOD menu for Refreshing Bank files. + +Fixes: +* Studio API - Fixed scatterer sounds being processed by FMOD::Geometry. +* Studio API - Fixed multi-stream events playing out of sync (introduced in 1.09.01). +* Core API - Fixed ChannelControl::setDelay being ignored if addDSP was + called immediately after it. +* Core API - Fixed potential crash if calling Channel::setPosition soon + after System::playSound with paused as true. +* Core API - Fixed click on ChannelControl::setPaused(false) caused by a non-zero + Channel::setPosition after System::playSound with paused as true. +* Core API - Fixed potential crash if calling System::getRecordPosition while + disconnecting an audio device. +* Core API - Fix FMOD_ACCURATETIME not looping mod/s3m/xm/it files properly, and midi + files not looping properly without the flag. +* Core API - Fixed crash when attempting to load invalid VST files. +* UE4 - Fix compile error by adding categories to AnimNotify vars. +* Unity - Switch - Fixed "unknown pointer encoding" error when an exception occurs. +* Unity - Fix plugin path for UWP builds. +* Unity - Fixed possible crash when using GoogleVR plugin. +* Unity - Fix EventEmitter SetParameter not working unless parameter had + an inital value set in editor. + +Notes: +* Studio API - Reduced memory usage for events with a small number of instances. +* Core API - FMOD_CREATESOUNDEXINFO::initialseekposition will now wrap if + the value given is longer than the Sound length. +* Core API - Added documentation to the top of fmod_codec_raw to be more instructional + for plugin writers. +* UE4 - Added support for UE4.17. +* Unity - Device specific errors will now cause only a single exception + to be thrown and the integration will assume no-sound mode. +* Switch - Now built with SDK 1.7.0. +* XboxOne - Now built with March 2017 QFE 3 XDK. + +06/07/17 1.09.06 - Studio API minor release (build 88495) +------------------------------------------------------------------------------------------ + +Features: +* Studio API - Improved performance when a large number of EventInstances have + been created but not started. +* Core API - HTML5 - Performance increased by 10%. + +Fixes: +* Studio API - Fixed a bug where an asynchronous looping multi instrument would + stop selecting new playlist entries after playing a nested event + which itself contains an asynchronous looping multi instrument. +* Studio API - Fixed a bug where a parameter could trigger parameter + instruments before having its value updated by modulators when + restarting an event instance. +* Studio API - Fixed incorrect automation interpolation on transition timelines with + lead-out regions. +* Core API - Fixed DSPs with sidechain inputs incorrectly going idle when + the main input is idle but the sidechain input is not. +* Core API - Fixed the compressor DSP not playing out its release correctly + when its inputs are idle. +* Core API - Remove main thread stall from System::playDSP (or playing a + generator DSP via Studio API). +* UE4 - Sequencer integration now supports previewing event playback in + an editor viewport by using the Sequencer transport controls. A + Sequencer section has been added to the documentation. +* UE4 - Added AreBanksLoaded funtion to FMODStudioModule. +* Unity - Events in EventBrowser window now in alpabetical order. +* Unity - Setting parameters on StudioEventEmitter no longer generates garbage. + +Notes: +* Core API - Added checking to System::mixerResume to ensure called from + the same thread as System::mixerSuspend. +* XboxOne - Now built with October 2016 QFE 3 XDK. + +08/06/17 1.09.05 - Studio API minor release (build 87666) +------------------------------------------------------------------------------------------ + +Features: +* Core API - Switch - Added support for HTC sockets to allow communications + between FMOD tools and runtime via target manager. Enable using + FMOD_Switch_SetHTCSEnabled(TRUE). +* Core API - XboxOne - Added support for System::attachChannelGroupToPort + with FMOD_XBOXONE_PORT_TYPE_MUSIC. + +Fixes: +* Studio API - Fixed FMOD_ERR_INTERNAL returned when loading old bank files + containing transition timeline automation of instrument volumes. +* Studio API - Fixed bug where very short instruments would not play when cross fading. +* Studio API - Made changes to the logic in Studio::EventDescription::isOneShot so that + it consistently returns true for events which are guaranteed to + finish without intervention, and false for events which may play + indefinitely. +* Core API - Fixed ChannelControl::setMixLevelsInput not working and updated docs. +* Core API - Fixed Channel::setLoopCount not working with very small streams. +* Core API - Stricter error checking when loading IMA ADPCM wav files to + prevent a potential crash from malformed data. +* Core API - Fixed potential crash in ChannelGroup operations when a Channel + failed to play on it with FMOD_ERR_SUBSOUNDS. +* Core API - Fixed Convolution reverb panning a mono IR with a stereo input + incorrectly. +* Core API - Fixed race conditions when setting FMOD_DSP_SEND_RETURNID. +* Core API - Fixed a crash with some MOD/S3M/XM/IT files. Introduced in 1.09.00. +* Core API - System::setDSPBufferSize will round the requested buffer size up + to the closest multiple of 4 to prevent a crash when sending + metering data to studio. +* Core API - PS4 - Fixed GPU compute compatibility issue with SDK 4.508.001. + GPU compute is now re-enabled. +* Core API - Switch - Reduced thread priority to avoid conflict with Profiler. +* Core API - Windows - Fixed ASIO output mode failing to initialize if the + devices requires a buffer size of 2048 samples. +* Unity - Fixed bank directory path separators when developing across OSX & Win. +* Unity - Fixed simulated Android devices producing no sound. +* Unity - BankLoadException now display error message correctly. +* Unity - Fixed bank loading and unloading refcount accuracy. +* Unity - Fixed Mac editor attempting to load Linux plugins when building + for Linux platform. +* Unity - Improved detection of 3D Event Instances that haven't had their + position set yet. +* UE4 - Fixed integration working with UE4's IWYU non-monolithic header + system, for now the integration is still using the old PCH system. +* UE4 - Added new native AnimNotify class, old one didn't work on code projects. +* UE4 - Sequencer integration. FMOD events can be started and stopped + and event parameters can be controlled by adding custom tracks + to sequencer. +* UE4 - Fixed max vorbis codecs not being set correctly. +* UE4 - Fixed file readers being accessed from multiple threads. + +Notes: +* UE4 - Added support for UE4.16. + +Notes: +* Updated Google VR plugin to version 0.4.0, please note there is a known crash + when loading the plugin on Windows XP, Google are aware and investigating. + +10/04/17 1.09.04 - Studio API minor release (build 86084) +------------------------------------------------------------------------------------------ + +Fixes: +* Studio API - Fixed delayed playback on streaming sounds in events (introduced + in 1.09.03). +* Studio API - Fixed AHDSR release not working on single sounds shorter than + 100 milliseconds. +* Studio API - Fixed Studio::EventDescription::is3D returning true for events that only + have 2D panners. +* Studio API - Set programmer sounds to FMOD_LOOP_NORMAL internally if they were + not created that way. +* Studio API - Fixed regression introduced in 1.09.00 which allowed events to + play at the origin before 3d attributes were updated. +* Studio API - Fixed issue where reverb tail would cut off when all events on + a bus finished playing. +* Core API - Fixed FMOD_DSP_TRANSCEIVER making channels audible that weren't + supposed to be (introduced with glitch fix in 1.09.03). +* Core API - Fixed loop clicks on PCM sounds if using FMOD_DSP_RESAMPLER_CUBIC + or FMOD_DSP_RESAMPLER_SPLINE. +* Core API - Fixed FMOD_ADVANCEDSETTINGS::resamplerMethod being ignored. +* Core API - Fixed plugin unloading for multi-description libraries potentially + failing depending on how it's unloaded. +* Core API - Fixed stream glitch when going virtual then resuming. +* Core API - Fixed virtual voices losing their loop/2d/3d status, and not + staying virtual if ChannelControl::setMode was used. Introduced in 1.09.00. +* Core API - Fixed FMOD_UNIQUE not being accepted if ChannelControl::setMode or + Sound::setMode was used. (it could be successfully used via + createSound/createStream). +* Core API - Fixed rare crash in mixer, introduced 1.09.00. +* Core API - Switch - Fixed FMOD_SWITCH_THREADAFFINITY so cores can be ORd together + to form a mask. +* Core API - PS4 - GPU compute disabled due to an incompatibility with SDK 4.508.001. +* Core API - Windows/Mac - Re-enable SRS downmixer 80Hz high pass filter by + default. Add FMOD_INIT_DISABLE_SRS_HIGHPASSFILTER init flag to + disable it. +* FSBank API - Fixed PS Vita AT9 encoder not working with currently available + Sony library. +* FSBank API - Fixed full scale 32bit float wav files encoding incorrectly. + +Notes: +* Studio API - FMOD expects programmer sounds to be created with FMOD_LOOP_NORMAL. + This is now specified in the FMOD_STUDIO_PROGRAMMER_SOUND_PROPERTIES + documentation. +* FSBank API - Building an FSB with PS Vita AT9 encoding now requires 64bit. +* PS4 - Now built with SDK 4.508.001. +* Switch - Now built with SDK 0.12.17. +* XboxOne - Now built with October 2016 QFE 2 XDK. + +20/03/17 1.09.03 - Studio API minor release (build 85359) +------------------------------------------------------------------------------------------ + +Features: +* Core API - Updated the /examples/dsp_custom example to include a lot more + functionality including parameters, and capture of wave data. +* Core API - Add fmod_reduced.js for reduced functionality, but also reduced size. +* Core API - Switch - Added support for setting thread affinity. +* Studio API - Reduced size of fmodstudio.js and .mem files. + +Fixes: +* Studio API - Fixed event doppler settings not being applied to sounds spawned + by scatterer. +* Studio API - Fixed bus and VCA handles not being set up properly in + Studio::Bank::getBusList and Studio::Bank::getVCAList. +* Studio API - Fixed crashes caused by stopping events that are routed into a + bus with instance limiting enabled when they are in the + FMOD_STUDIO_PLAYBACK_STARTING state. +* Studio API - Fixed tempo and marker event callbacks not being fired when the + timeline cursor is in the lead-in or lead-out region of a + transition timeline. +* Core API - Fixed glitches with Transceiver DSP after inputs go idle. +* Core API - Fix Channel::setPosition(pos, FMOD_TIMEUNIT_MODORDER) not + working when playing paused. +* Core API - Fixed short streams created as non-looping then switched to + looping via the Channel API not looping seamlessly. +* Core API - Fixed DSP plugin version >= 109 data parameters other than 3D + attributes not applying if FMOD_INIT_3D_RIGHTHANDED is used. +* Core API - Fixed rare crash in FMOD Panner DSP. Introduced in 1.09.00. +* Core API - Re-Fix MOD/S3M/XM/IT file crash with samples that have 0 length, + for 1.09 only. +* Core API - Fixed potential memory leak if System::init returned an error. +* Core API - Fix FMOD_ACCURATETIME not looping a mod file properly, and not + seeking correctly with FMOD_TIMEUNIT_MODORDER. +* Core API - HTML5 - Loading FSB sounds did not work properly. +* Core API - Windows - Fixed 5.1->stereo SRS downmix causing lack of bass. +* Core API - Windows - Fix FMOD_INIT_PREFER_DOLBY_DOWNMIX not working. +* FSBank API - Fix crash if FSBANK_INIT_GENERATEPROGRESSITEMS is not used. +* Unity - Removed error when plugin field is added but empty. +* UE4 - Removed error when plugin field is added but empty. + +Notes: +* UE4 - Added support for UE4.15. + +15/02/17 1.09.02 - Studio API minor release (build 84334) +---------------------------------------------------- + +Fixes: +* Unity - Remove ifdef from EnforceLibraryOrder as it isn't harmful for static lib platforms to call GetStats. +* UE4 - Occlusion can now use Multiband EQ instead of Lowpass filter. +* Core API - Fix crash when connecting to FMOD Profiler.exe and there is a circular connection +* Core API - Fix glitches with Transceiver DSP after inputs go idle. +* Core API - Fix Channel::setPosition(pos, FMOD_TIMEUNIT_MODORDER) not working when playing paused. + +09/02/17 1.09.01 - Studio API minor release (build 84153) +---------------------------------------------------- + +Features: +* Core API - Added FMOD_DSP_STATE_FUNCTIONS::getlistenerattributes to the + DSP plugin API to query the current listener attributes. +* Unity - Added support for Rigidbody2D in 3D attribute settings and + integration scripts. +* Unity - Added support for Object Enable/Disable on EventEmitter and + ParameterTrigger scripts. +* UE4 - Added GetLength function for blueprints that returns the event length + in milliseconds. +* UE4 - Improved in editor profiling stats. + +Fixes: +* Unity - Fixed compatibility with Unity 4.6 & 4.7 for OSX and IOS. +* Unity - Fixed "file not found" error when settings asset is corrupt +* Unity - Fixed set3DAttributes ambiguity. +* Unity - Fixed not being able to copy ReadOnly banks into StreamingAssets. +* Unity - Fixed event instance leak in Unity PlayOneshotAttached not releasing. +* Unity - Specified version to check for WiiU BuildTarget for early Unity5. +* UE4 - Fixed XboxOne delayload error now that UE4 handles it. +* UE4 - Android - Added ARM64 support. +* Studio API - AHDSR modulator curve shapes now work correctly. In previous versions + the envelope was interpolated linearly regardless of the shape displayed + in the UI. +* Studio API - Fixed looping single sounds in an async multi sound being cut-off when + the multi sound is un-triggered. +* Core API - Fixed ChannelControl::setReverbProperties not resetting reverb connection + to a new tail DSP when turning wet mix off and on. +* Core API - If the system is initialized in right-handed mode, FMOD will now swap + to left-handed when passing attributes into plugins. This only applies + to plugins rebuilt against this version, old plugins remain unswapped. +* Core API - Fix MOD/S3M/XM/IT file crash with samples that have 0 length. +* Core API - Fixed some potential crashes when running out of memory, these will + correctly return FMOD_ERR_MEMORY now. +* Core API - Win - Fixed WASAPI recording device enumeration taking a couple of seconds + after System::init before being correct. +* Core API - Win - Fixed potential error returned from System::update if device is unplugged. +* Core API - MIDI - Fixed Sound::set/getMusicChannelVolume referring to wrong track + indices rather than just a normal 0-15 track index. +* Core API - MIDI - Fixed Channel::setPosition causing loud drum bang noise after seek + +Notes: +* Studio API - When loading legacy banks with looping sounds nested in multi sounds, + the multi sound is set to cut-off all sounds when untriggered, including + non-looping sounds. This is a change in behaviour compared to earlier + versions where only looping sounds were cut-off. +* Core API - DSP plugin API version has been increased, for maximum compatibility + plugin writers should only rebuild against this version if they need + the getlistenerattributes feature. Old plugins are still supported. +* Switch - Now built with SDK 0.12.10 + +01/12/16 1.09.00 - Studio API major release (build 82164) +---------------------------------------------------- + +Important: +* Added support for the Nintendo Switch platform. + +Features: +* Studio API - Added support for multiple listener weights, with + Studio::System::setListenerWeight and + Studio::System::getListenerWeight. This allows listeners to be + faded in or out smoothly. +* Studio API - Profiling uses less CPU and memory. +* Studio API - Added FMOD_STUDIO_INIT_LOAD_FROM_UPDATE to drive all loading from + Studio::System::update rather than the bank and resource loading + threads. Mainly used in non-realtime situations. +* Studio API - Added ability to run replays at faster than real time speed using + FMOD_STUDIO_COMMANDREPLAY_FAST_FORWARD. +* Studio API - Added Studio::EventInstance::setReverbLevel and + Studio::EventInstance::getReverbLevel. +* Studio API - Support for automation of modulator properties. +* Core API - Improved memory use when loading sounds with names. +* Core API - Added new efficient multiband equalizer (FMOD_DSP_TYPE_MULTIBAND_EQ) + featuring 5 toggleable bands with variable rolloff low/high pass, shelf, + peaking, band-pass, all-pass and notch modes. +* Core API - Added logging function to the DSP plugin API. Use FMOD_DSP_LOG + helper macro from a DSP callback. +* Core API - Added FMOD_DSP_STATE_FUNCTIONS::getuserdata to the DSP plugin API. + Use FMOD_DSP_GETUSERDATA helper macro from a DSP callback. +* FSBank API - Added ability to pass NULL as the FSB file name for FSBank_Build causing + the FSB to be built in memory. Use FSBank_FetchFSBMemory to get access + to the data once the build has completed. + +Fixes: +* Studio API - Fixed incorrect playback volume for instruments and playlist + items whose volume property is set to a non-zero dB value. + +Notes: +* Core API - Incremented Plugin SDK version for DSP plugins. Dynamic library + plugins built with earlier versions will continue to load. +* Core API - Incremented FMOD_CODEC_WAVEFORMAT version. Codecs that provide + names must keep the name memory persistent for the lifetime + of the codec. +* Core API - Increment Plugin API version for Output plugins. Dynamic library + Output Plugins must be rebuilt. +* Core API - FMOD_DSP_TYPE_LOWPASS, FMOD_DSP_TYPE_LOWPASS_SIMPLE, + FMOD_DSP_TYPE_HIGHPASS, FMOD_DSP_TYPE_HIGHPASS_SIMPLE and + FMOD_DSP_TYPE_PARAMEQ are considered deprecated and will be removed + in the future. Use the new FMOD_DSP_TYPE_MULTIBAND_EQ instead which + has the performance of "simple" effects with full featured quality. +* Core API - Changed reverb wet mix to send from the fader DSP of a ChannelGroup. + Previously it sent from the head DSP. Now effects placed pre-fader + will apply to the signal sent to the reverb, while effects placed + post-fader will not. +* Core API - ChannelGroup reverb wet level is now scaled by the group's + effective audibility. +* Core API - ChannelGroup reverb no longer automatically disables reverb + on its child channels when the wet level is set to non-zero. +* Core API - Channel::setReverbProperties now allows setting the wet level + before the specified reverb instance has been created. +* Core API - ChannelControl::addDSP and ChannelControl::removeDSP manage + standard DSP connections (FMOD_DSPCONNECTION_TYPE_STANDARD) + to maintain the mixer hierarchy. + Other connection types (FMOD_DSPCONNECTION_TYPE_SIDECHAIN, + FMOD_DSPCONNECTION_TYPE_SEND_SIDECHAIN, and now + FMOD_DSPCONNECTION_TYPE_SEND) are left undisturbed. +* Core API - FMOD_INIT_MIX_FROM_UPDATE will now directly execute the mixer from + System::update instead of triggering the mix to happen in another + thread. +* Studio API - Incremented bank version, requires runtime 1.09.00 or later. +* Studio API - Latest runtime supports loading old bank versions from 1.03.00. +* Studio API - Studio::Bus::setFaderLevel, Studio::Bus::getFaderLevel, + Studio::VCA::setFaderLevel and Studio::VCA::getFaderLevel is now + called Studio::Bus::setVolume, Studio::Bus::getVolume, + Studio::VCA::setVolume and Studio::VCA::getVolume. +* Studio API - Studio::EventInstance::getVolume, + Studio::EventInstance::getPitch, + Studio::EventInstance::getParameterValue, + Studio::EventInstance::getParameterValueByIndex, + Studio::Bus::getVolume, + Studio::VCA::getVolume now have an additional argument + to get the final value which includes automation and modulation. +* Studio API - The required alignment for Studio::System::loadBankMemory has + been added as the constant FMOD_STUDIO_LOAD_MEMORY_ALIGNMENT. +* Studio API - Event instances now disable reverb on their internal channels, + for all global reverb instances. Previously only did so for + reverb instance 0. Use Studio::EventInstance::setReverbLevel + to control the reverb mix for the whole event instance. +* Studio API - Disconnected sidechain modulators are now inactive. Previous + behavior was to fall back to monitoring the event's master + track output. +* Core API - FMOD_DSP_RELEASE_CALLBACK is now called from the main thread +* Core API - Unimplemented ChannelControl::overridePanDSP function has been + removed, along with FMOD_CHANNELCONTROL_DSP_PANNER enum value. +* Core API - PS3 - Removed old opt-in FIOS support via FMOD_PS3_EXTRADRIVERDATA. + New recommended approach is to use FMOD_FILE_ASYNCREAD_CALLBACK + and set appropriate deadlines based on FMOD_ASYNCREADINFO::priority. +* Core API - XboxOne - Optimized XMA decoding performance and removed the ACP thread. +* Core API - PS4 - Improved AT9 decoding performance. +* FSBank API - Added support for source data as a memory pointer instead of file name. +* Documentation - Some FMOD_DSP_PAN_SURROUND enums changed to FMOD_DSP_PAN_2D for clarity. + +01/12/16 1.08.15 - Studio API minor release (build 82163) +---------------------------------------------------- + +Features: +* PS4 - Add support for System::getOutputHandle, to return sce + port handle. +Fixes: +* UE4 - Fix missing plugin error when building on Mac. +* UE4 - Fixed compatibility with 4.14. +* Unity - Fixed OSX working with unified library. +* Unity - Fixed WiiU copying banks error. +* Unity - Fixed XboxOne dll meta files missing platform target. +* Unity - Fixed duplicate dll copying build error on some platforms. +* Unity - Added null check to stop error being thrown when no event assigned. +* Unity - Fix in editor out of bounds exception in RuntimeManager. +* Core API - Allow DSP::setParameterData with null data and 0 length to free + convolution reverb impulse response data. +* Core API - Fixed short looping streams playing some of the start when + switched to non-looping via the Channel API. +* Core API - Fixed FMOD_CREATESOUNDEXINFO::pcmsetposcallback getting wrong sound + pointer passed to it with a stream. +* Studio API - Fixed incorrect parameter values being passed to nested events + when value "hold" is being used. +* Studio API - PS3 - Fix potential crash with the new Channel Mix effect. +* FSBank API - Fixed encoder bug with FADPCM causing occasional clipping at playback. + +Notes: +* FSBank API - FSBs / Banks may not be binary identical to previous release due to + FADPCM encoder bug fix, however full compatibility is maintained. + +20/10/16 1.08.14 - Studio API minor release (build 80900) +---------------------------------------------------- + +Fixes: +* UE4 - Fix for crash when using "Validate FMOD" menu item + +Notes: +* PS4 - Now built with SDK 4.00 +* XboxOne - Added better logging and documentation to describe an incorrectly + configured appxmanifest regarding microphone recording. + +04/10/16 1.08.13 - Studio API minor release (build 80479) +---------------------------------------------------- + +Fixes: +* Studio API - Fixed potential crash after the following sequence of actions: + load master bank, try to load master bank again and fail with + FMOD_ERR_EVENT_ALREADY_LOADED, unload master bank, reload + master bank. +* Core API - Fix circular DSP connection causing hang in certain situations. +* Unity 2 - Fix issues with multi-object editing of emitters. + +22/09/16 1.08.12 - Studio API minor release (build 80229) +---------------------------------------------------- + +Features: +* Unity 2 - Added ability to override minimum and maximum distance for + Event emitters. +* Unity 2 - Added support for multiple listeners. +* Studio API - Added support for auto pitch at minimum. +* Studio API - Added support for the global master bus being duplicated across + banks. + +Fixes: +* Studio API - Fix auto pitch cutting off at zero for parameter with minimum + value that is less than zero. +* Studio API - Fix events with a transciever effect not allowing the event to stop +* Android - Fixed crash when loading FSBs or Banks that contain a sound that + isn't mono, stereo, 5.1 or 7.1. +* Android - Fixed compatibility issue with some devices introduced in previous + release due to r12b update. Presents as a runtime linker error + when loading the FMOD library, failing to locate __aeabi_atexit. +* iOS - Fixed stuttering during fade out when device screen goes to sleep. +* Core API - Fix FMOD_DSP_TRANSCEIVER memory stomp. +* Core API - Fix channels playing at incorrect pitch. Introduced in 1.08.10. + +Notes: +* Studio API - Incremented bank version, requires runtime 1.08.00 or later. +* Studio API - Latest runtime supports loading old bank versions from 1.03.00. +* Core API - Improved validation for ChannelGroup, DSP and Sound handles, + detects invalid pointers and usage after release. + +08/09/16 1.08.11 - Studio API minor release (build 79819) +---------------------------------------------------- + +Features: +* Core API - PS3 - Added support for FMOD_DSP_CHANNELMIX. +* Unity 2 - Respect Game View mute button. + +Fixes: +* FSBank - Fix crash on 64-bit when encoding 16kHz or 24kHz sources using + Vorbis at low quality settings. +* Core API - Fix FMOD_SOUND_PCMSETPOS_CALLBACK getting invalid position value + when a sound opened with FMOD_OPENUSER loops. +* Core API - Android - Fixed crash on load with old devices when using armeabi. +* Unity 2 - Fix CREATESOUNDEXINFO not getting marshalled properly. + +Notes: +* Android - Now built with NDK r12b. +* Android - Minimum Android version is now API level 9 due to NDK r12b + deprecating older versions. + +22/08/16 1.08.10 - Studio API minor release (build 79252) +---------------------------------------------------- + +Features: +* Studio API - Improved performance of sidechain modulator. +* Core API - Improved ChannelControl::setPitch accuracy between DSP clock and + the underlying codec decoding speed. +* Unity 2 - Added option for play-in-editor to reflect the active build target + for loading banks. + +Fixes: +* Core API - Fixed error trying to create a Return DSP when the system + format is set to FMOD_SPEAKERMODE_RAW. +* Core API - Fixed FFT DSP crash if window size is smaller than DSP block size. +* Core API - Removed spurious warning messages when loading plugins on + some platforms. +* Core API - Android - Tweaked OpenSL auto detection, now requires device to + specify low latency and a block size <= 1024. +* Unity 2 - Fix bank import issues when the strings bank contains bank + names that differ in case from the files on disk. +* Unity 2 - Bank import now has a longer timeout after last detected file + activity before starting import. +* Unity 2 - Fixed settings screen allowing real channels to be set higher + then 256. +* Unity 2 - Fix up errors when StudioEventEmitter is created dynamically. +* Unity 2 - Small fixes for the settings screen when overriding the parent + platform settings. +* UE4 - Fix for crash when previewing animations using the FMOD event + notifier. + +Notes: +* Core API - System::getSpeakerModeChannels returns the system channel + count when passed FMOD_SPEAKERMODE_DEFAULT. Now works even + if the system format is set to FMOD_SPEAKERMODE_RAW. +* UE4 - Can be recompiled with 4.13 pre-release. +* Documentation - Added documentation for FMOD_DSP_PAN enums. + +01/08/16 1.08.09 - Studio API minor release (build 78489) +---------------------------------------------------- + +Features: +* Core API - PS4 - Add support for social screen audio to the ports API. +* Studio API - Added Studio::EventInstance:setListenerMask and + Studio::EventInstance::getListenerMask, that adds the ability + to specify which listeners apply to each event instance. +* Unity 2 - Warning is now produced when playing in editor if the position + of a 3D event is not set. +* UE4 - Added blueprint functions to set event properties. + +Fixes: +* Studio API - Fixed case of indeterminism when building banks that contain + events with automation curves. +* Core API - Fixed FMOD_OUTPUT_OBJECT3DINFO::gain so it only includes + distance attenuation not bus gain (which is now pre-applied + to FMOD_OUTPUT_OBJECT3DINFO::buffer. +* Core API - Fixed channelmix DSP volume not always being initialized. +* Core API - WiiU - Fixed potential crash during System::init if + System::setDriver or System::setOutput has been called. +* Core API - Fix hang on netstreams when the connection times out. +* Core API - Linux - Fix FPU control word of the calling thread being modified + when the FMOD dynamic library is loaded. +* Core API - Android - Fixed potential crash if FMOD isn't loaded with + System.loadLibrary, now a proper error will be issued. +* FSBank API - Fixed FADPCM not looping seamlessly for non-zero crossing loops. +* UE4 - Fixed plugin loading assuming a "lib" prefix for plugins on + Android, Mac, Linux and PS4. Now plugin loading will attempt + to load the name with and without adding a lib prefix. +* UE4 - Respect FApp::IsUnattended for message-box errors. +* UE4 - Fixed deprecation warnings about AttachTo usage. +* Unity 2 - Fix errors when bank source files are updated while Event Browser + preview is playing or paused. +* Unity 2 - Fix unnecessary copying of Bank files in OSX editor. + +Notes: +* Core API - Linux - Removed limit of 32 devices with ALSA output mode. +* Core API - Incremented API version of Output plugins. Dynamic library + plugins built with earlier versions of 1.08 will continue to load. + +14/07/16 1.08.08 - Studio API minor release (build 77846) +---------------------------------------------------- + +Features: +* UE4 - bMatchHardwareSampleRate will use the system default format + to avoid excessively matching the output rate on mobile devices. +* UE4 - Added bLockAllBuses which will force all buses to be created + at startup, rather than on demand. + +Fixes: +* Studio API - Fixed looping sounds in a multi sound playlist failing to stop + if the multi sound itself is non-looping. +* Studio API - Fixed rare crash calling the following functions while the + bank containing the event is unloading: + Studio::EventInstance::getDescription, + Studio::EventInstance::getParameter, + Studio::EventInstance::getParameterValue, + Studio::EventInstance::setParameterValue, + Studio::EventInstance::setParameterValueByIndex, + Studio::EventInstance::triggerCue, + Studio::ParameterInstance::getDescription and + Studio::ParameterInstance::setValue. +* Studio API - Fixed shared events becoming invalidated when one of the + banks containing them is unloaded. Could also manifest as + Studio::EventInstance::getDescription failing with + FMOD_ERR_INTERNAL. +* Studio API - Fixed crash that could occur when using + FMOD_STUDIO_INIT_SYNCHRONOUS_UPDATE and calling + Studio::System::update from multiple threads at the same time. +* Studio API - Increased scheduling lookahead time to ensure sample accurate + timeline scheduling even if there is an output stall. +* Studio API - Fixed crash that could occur when improperly calling + Studio::Bus::getChannelGroup without first calling + Studio::Bus::lockChannelGroup, if the bus was being destroyed + as the call was made. +* Studio API - Fixed rare crash calling the following functions while the + master bank containing the bus or VCA is unloading: + Studio::System::getBus, + Studio::System::getBusByID, + Studio::System::getVCA and + Studio::System::getVCAByID. +* Studio API - Fixed rare timing issue where Studio::System::getEvent would + succeed but Studio::EventDescription::createInstance would + fail with FMOD_ERR_INTERNAL, if called just as the bank + containing the event finished loading. +* Studio API - Fixed rare hang in Studio::System::getBankCount when called + while banks are currently unloading. +* Core API - Fixed rare glitch at the start of XMA playback causing non-seamless + looping. +* Core API - Fixed rare hang on shutdown when using multiple systems. +* Core API - Fix streams with an unknown file length remaining in the playing state + after an end of file is encountered. +* Core API - Windows - Enumeration of record devices will now reflect a change + of default device with WASAPI output. +* Core API - Linux - Enumeration will now correctly display GUIDs and speaker + modes for ALSA output. +* Core API - Linux - Fixed potential crash if both PulseAudio and ALSA are + missing / unavailable. +* Unity 2 - Fix plugin loading on Linux standalone builds. +* Unity 2 - Fix script compilation errors in standalone builds. +* Unity 2 - Fix Event Browser preview of events with built-in parameters. +* Unity 2 - Fix missing tvOS files. + +Notes: +* Core API - Significantly reduced memory consumption when using FMOD_DSP_FFT. +* PS4 - Now built with SDK 3.508.101 +* UE4 - Updated Oculus plugin to 1.0.4. + +27/06/16 1.08.07 - Studio API minor release (build 77241) +---------------------------------------------------- + +Features: +* FSBank API - Added support for Linux. +* Unity 2 - Live Update and Debug Overlay can be set to only be enabled in + standalone builds when the development build option is set. +* Unity 2 - Add MuteAllEvents and PauseAllEvents functions to the RuntimeManager. +* Unity 2 - Audio will now pause when the application pauses. +* UE4 - Added MixerSuspend and MixerResume blueprint functions. +* UE4 - Added IsBankLoaded blueprint function. + +Fixes: +* Studio API - Fixed Studio command buffer assert and crash that could occur + when using FMOD_STUDIO_INIT_SYNCHRONOUS_UPDATE in conjunction + with multiple threads. +* Core API - Fix crash when closing a system with a multi-plugin DLL still loaded. +* Core API - iOS / Android - Improved audio stability when mixer thread is overloaded. +* FSBank API - Fixed calling convention linker error on Windows in FSBankLib header. +* FSBank API - Fixed issue when passing duplicate source files with different encoding + settings would cause cache file conflicts. + +Notes: +* Unity 2 - Renamed "Level Start" and "Level End" triggers to "Object Start" and + "Object Destroy" to more accurately reflect when the triggers occur. + +17/06/16 1.08.06 - Studio API minor release (build 76937) +---------------------------------------------------- + +Features: +* Unity 2 - Added framework for registering native plugins on iOS and tvOS. +* Unity 2 - Added support for importing Studio Banks as TextAssets so they + can be added to Unity AssetBundles. + +Fixes: +* Core API - Fixed crash on shutdown, after creating multiple systems and + setting a system callback. +* Core API - PS4 - Fix issues with calling FMOD_PS4_GetPadVolume() immediately + after opening the controller audio port. + +15/06/16 1.08.05 - Studio API minor release (build 76824) +---------------------------------------------------- + +Features: +* Studio API - Added Studio::EventDescription::isSnapshot. +* Unity 2 - Added "Preload Sample Data" checkbox to Event Emitter to reduce + latency when emitters are triggered for the first time. +* Unity 2 - Added script example to show how to build an asynchronous loading + screen that includes loading FMOD Banks. + +Fixes: +* Studio API - Fixed Studio::EventDescription::isOneshot() incorrectly + returning true for snapshots. +* Core API - Fix FMOD_ADVANCEDSETTINGS::maxADPCMCodecs not being applied. +* Core API - Fix crash when using CreateSound from multiple threads + (including FMOD Async loading threads). +* Unity 2 - Fix issues when bank file in the Unity project Streaming Assets + folder have a different case to the banks in the Studio project. +* Unity 2 - Fix issues when editor log file cannot be opened because it's + read only. +* Unity 2 - If the "Load All" options are selected in the FMOD Settings + then the main thread will now block until it's complete. +* UE4 - Fix for OnEventStopped callback firing repeatedly if triggers + the instance to play again. + +Notes: +* Core API - All System, ChannelControl, ChannelGroup, Channel, and DSP API + functions check for NaN and INF floats and return + FMOD_ERR_INVALID_FLOAT if detected. +* Studio API - All API functions check for NaN and INF floats and return + FMOD_ERR_INVALID_FLOAT if detected. +* Studio API - All API functions with output parameters now clear those + values in the case of an error. Previously some values may + have been left uninitialized. + In the case of an error, int and float outputs are set to 0, + bool outputs are set to false, and pointers are set to NULL. + Structures are cleared to zeros, and string buffers are set + to the empty string. + +25/05/16 1.08.04 - Studio API minor release (build 76196) +---------------------------------------------------- + +Features: +* Studio API - Added runtime support for steal quietest polyphony. +* Core API - Improved performance when connecting sends and returns. +* UE4 - FFMODEventInstance can now be stored as a blueprint variable. +* UE4 - Added support for Occlusion. See the Occlusion section of the + documentation for more information. +* UE4 - Added support for Android deployment without having to modify + the engine. +* UE4 - Added InitialDriverOutputName to select output device by name + at startup, as well as new Blueprint functions GetOutputDrivers, + SetOutputDriverByName and SetOutputDriverByIndex. +* UE4 - Added VCASetFaderLevel Blueprint function. +* UE4 - "FMOD Validate" now checks for FMOD in the packaging setting, + and can add it if needed. + +Fixes: +* Core API - Fixed unnecessary DSP queue flush when using ports. +* Core API - Fixed ADPCM and FADPCM compressed FSBs not returning + FMOD_ERR_MEMORY_CANTPOINT when loaded as FMOD_OPENMEMORY_POINT + FMOD_CREATESAMPLE. +* Core API - Fix pops when channels with a mix matrix that are started virtual + become real. +* Core API - Fixed DSP panner reset not clearing ramps, causing ramping when + setting initial parameters. +* Core API - Fixed Sound::getSyncPointInfo returning first sync point info + when loading sounds from FSBs with multiple sync points. +* Studio API - Fixed memory stomp that can occur when sharing events between + multiple banks, if a streaming sound is in the middle of loading + when one of the shared banks is unloaded. +* Unity 2 - Fix error messages when previewing an event contained in the + Master Bank. +* Unity 2 - Fix WinPhone 8.1 DLL's conflicting with UWP builds. + +Notes: +* Studio API - Incremented bank version, requires runtime 1.08.00 or later. +* Studio API - Latest runtime supports loading old bank versions from 1.03.00. +* UE4 - Updated ovrfmod to version 1.0.3. +* UE4 - Tested with 4.12 pre-release, compiles successfully. +* PS Vita - Now built with SDK 3.570.011. + +05/05/16 1.08.03 - Studio API minor release (build 75571) +---------------------------------------------------- + +Features: +* Studio API - Added FMOD_STUDIO_EVENT_CALLBACK_SOUND_PLAYED and + FMOD_STUDIO_EVENT_CALLBACK_SOUND_STOPPED for when an event + plays sounds. Sound names will only be available if + banks have been re-exported in FMOD Studio 1.08.03 or later. + See the music_callbacks example for demonstration. +* Studio API - Added runtime support for the event cooldown property + set from FMOD Studio. Events that fail to start due to + cooldown time will invoke the + FMOD_STUDIO_EVENT_CALLBACK_START_FAILED callback. +* Core API - Improved performance of logging. +* Core API - PS4 - Improved performance when profiling is enabled. + +Fixes: +* Studio API - Events that fail to start due to bus polyphony now invoke the + FMOD_STUDIO_EVENT_CALLBACK_START_FAILED callback. +* Studio API - Fixed crash when calling Studio::System::unloadAll with + crossfading nested events. +* Studio API - Fixed unnecessary up/down mix applied to 2D events that have + sidechain modulators. +* Studio API - Fixed mixing issues and degraded performance if the system + speaker mode does not match the Studio project format. +* Studio API - Fixed case of stereo sounds panning hard right when downmixed + to a mono track and later upmixed again, introduced in 1.07.04. +* Core API - Fixed potential incorrect position when voice comes back from + being virtual, which can cause a hang on XboxOne. +* Core API - Improved handling for out of memory errors when mixing DSP + buffers. +* Core API - Fixed incorrect propagation of FMOD_DSP_STATE::channelmask + when mixing signals with differing masks. +* Core API - Fixed http streams (file from http, not shoutcast/icecast) + returning FMOD_ERR_FORMAT. Introduced 1.08.01 +* Core API - Fixed m3u playlist file format support. Was returning + FMOD_ERR_FORMAT. +* Core API - Android - Improved detection of low-latency devices allowing better + automatic output mode selection and less stuttering. +* Core API - Sound::getName will now return "" for sounds without names, + instead of "(null)". +* Core API - Object 3D Panning fix for silent objects in certain speaker modes +* Studio API - More robust live update handshaking when attempting to connect + with multiple copies of FMOD Studio at once. +* Unity 2 - Added missing Studio::EventDescription::getSoundSize function. + +Notes: +* Studio API - Incremented bank version, requires runtime 1.08.00 or later. +* Studio API - Latest runtime supports loading old bank versions from 1.03.00. +* Studio API - Sound names are now loaded into memory if they have been + exported in the bank file. The option is on by default, + which means by the runtime memory use might be slightly higher + when loading banks exported from 1.08.03 and later. If this is + a problem, make sure to disable the option to export sound names + in FMOD Studio when re-exporting banks. +* XboxOne - Now built with March 2016 QFE 1 XDK. +* PS4 - Now built with SDK 3.508.031. + +13/04/16 1.08.02 - Studio API minor release (build 74770) +---------------------------------------------------- + +Fixes: +* UE4 - Fixed audio component transform not being updated in 4.11. +* Studio API - Fixed unnecessary up/down mix applied to 2D events that have + sidechain modulators. +* Studio API - Studio::EventDescription::is3D now returns true if there is a + plug-in panner on the master track. + +Notes: +* UE4 - PS4 - Deployment uses standard unreal plugin system. +* UE4 - Now built against Unreal 4.11 + +07/04/16 1.08.01 - Studio API minor release (build 74554) +---------------------------------------------------- + +Features: +* Unity 2 - Added Universal Windows Application platform support. +* Unity 2 - Added Find and Replace tool. +* Core API - Improved performance when creating DSPs. +* UE4 - Added FMOD stats for CPU usage. + +Fixes: +* Studio API - Fixed errors being generated when the initial seek is past + the loop end point of a sound. +* Studio API - Fixed error loading sample data for banks + loaded by Studio::System::loadBankMemory with + FMOD_STUDIO_LOAD_BANK_DECOMPRESS_SAMPLES flag. +* Studio API - Fixed rare Studio update error FMOD_ERR_NOTREADY when stopping + modules with streaming sounds. +* Studio API - Fixed unnecessary up/down mix on sidechain effects in game. +* Studio API - Eliminated API stalls due to holding a lock when creating + event instances on the Studio Update thread. +* Studio API - Fixed error when loading an API capture that contains + Studio::System::flushSampleLoading commands. +* Studio API - PS4 - Fixed incorrect linking options on fmodstudio.prx that + caused package creation to fail. +* Core API - Fixed rare hang when rapidly creating and releasing Return DSPs. +* Core API - Fixed hang or crash when loading a .it/s3m/mod/mid file as a + decompressed sound. +* Core API - Fixed some shoutcast streams playing back garbled. +* Core API - Fixed Sound::readData returning 0 for bytes read, instead of a + valid number if FMOD_ERR_FILE_EOF was returned. + Introduced in 1.07.08. +* Core API - PS4 - Fix AT9 playback when a sound created as looping is + played with the channel loop-count explicitly set to zero + before starting. +* Core API - Win - Fixed ASIO device enumeration not supplying a GUID. +* Core API - Win - Fixed ASIO device enumeration having a blank name if the + device is not connected. +* UE4 - Added lock around file accesses to avoid Unreal pak file thread + safety issue. +* UE4 - Fixed logging callback not being initialized. +* UE4 - Avoid asset table system from mixing while normal mixer is in + operation, to work around an AT9 mixer issue. +* UE4 - Fixed always linking against ovrfmod even if it isn't present. +* Unity 2 - Rewrote Timeline Callback and Programmer Sound Callback examples + to work on iOS. +* Unity 2 - Fix marshalling of FMOD.CREATESOUNDEXINFO structure on iOS. +* Unity 2 - Fix DLL not found errors in standalone Windows builds. + +Notes: +* Studio API - Incremented bank version, requires runtime 1.08.00 or later. +* Studio API - Latest runtime supports loading old bank versions from 1.03.00. +* Studio API - Studio::EventInstance::setPitch() now returns an error if a NaN + is passed in. +* Studio API - Errors that occur during the Studio update thread will no longer + stop the thread. +* Studio API - Studio will set the master channel group format to the + project's format to avoid an extra upmix. + +04/03/16 1.08.00 - Studio API major release (build 73609) +---------------------------------------------------- + +Features: +* Studio API - Sample data loading has been optimised. Load time, file access, + and memory use have all been substantially improved. A new entry + has been added to the per platform thread affinity settings. +* Studio API - FMOD_STUDIO_PARAMETER_DESCRIPTION now has the parameter index and + default value. +* Studio API - Added Studio::System::flushSampleLoading. +* Studio API - Support for left edge trimming of timelocked sounds. +* Studio API - Support for Start Offset as a percentage of sound length. +* Studio API - Added idle resource pool to keep recently used sounds in memory in + case they might be re-used. It can be controlled by the + idleResourcePoolSize field in FMOD_STUDIO_ADVANCEDSETTINGS. See + the Studio Banks Programmer Topic for more information. +* Core API - Increased performance of System::createSound and System::createStream, + since they no longer block against System::update. +* Core API - Added filebuffersize to FMOD_CREATESOUNDEXINFO for customizable + file buffering. +* Core API - Added System::getFileUsage to query file loading information. +* Core API - Custom DSP effects now always receive a buffer length that is equal + to the mix block size. The input and output buffers will always be + 16-byte aligned. Custom DSP sounds still have be able to generate + signal less than a mix block. +* Core API - Added getclock callback to FMOD_DSP_STATE_SYSTEMCALLBACKS to get the + clock, offset and length for a custom DSP. +* Core API - Added support for multiple plugins within one plugin file. See + FMOD_PLUGINLIST, System::getNumNestedPlugins, System::getNestedPlugin, + and the DSP Plugin API Programmer Topic for more information. +* Core API - Added support for object based panning with two backend providers, Dolby + Atmos (FMOD_OUTPUTTYPE_ATMOS) and Playstation VR (FMOD_OUTPUTTYPE_AUDIO3D). +* Core API - Added 3D object panner DSP (FMOD_DSP_TYPE_OBJECTPAN) to be used + with new object pan enabled outputs. +* Core API - Extended output mode plugin API (FMOD_OUTPUT_DESCRIPTION) to allow custom + object panner backends. +* Core API - Win - Reduced WASAPI latency by 40ms and improved mixer thread regularity. +* FSBank - AT9 Band Extension is now enabled by default for supported bit-rates. +* FSBank - Added Mac versions of the FSBank tool and FSBankLib API. Included + in the Mac and iOS API packages. +* Profiler - Added Mac version of the Profiler tool. Included in the Mac and + iOS API packages. +* Unity 2 - Added ability to create new studio events from within the Unity editor. +* Unity 2 - Improved event selection UI on emitter component and when using EventRef attribute. +* Unity 2 - Added support for default parameter values in emitter component. + +Notes: +* Studio API - Incremented bank version, requires runtime 1.08.00 or later. +* Studio API - Latest runtime supports loading old bank versions from 1.03.00. +* Studio API - New example 'object_pan' that demonstrates object based panning. +* Studio API - Studio::EventDescription::getSampleLoadingState and + Bank::getSampleLoadingState now return FMOD_STUDIO_LOADING_STATE_ERROR + if sample data failed to load (e.g. due to a corrupt file). +* Studio API - Removed Studio::CueInstance, Studio::EventInstance::getCue, + Studio::EventInstance::getCueCount and + Studio::EventInstance::getCueByIndex. Instead use new functions + Studio::EventDescription::hasCue and Studio::EventInstance::triggerCue. +* Studio API - Deprecated Studio::EventInstance::getParameter and + Studio::EventInstance::getParameterByIndex. Instead use + Studio::EventInstance::getParameterValue, + Studio::EventInstance::setParameterValue, + Studio::EventInstance::getParameterValueByIndex, and + Studio::EventInstance::setParameterValueByIndex. +* Studio API - Increased stack size for Studio threads to 64K. +* Studio API - Played events will stay in the FMOD_STUDIO_PLAYBACK_STARTING state until + their sample data has loaded. This avoids selected sounds in the event + playing late if the sample data has not been preloaded. +* Core API - System::getChannelsPlaying now returns the number of real and + total channels playing. System::getChannelsReal has been + removed. +* FSBank - AT9 compression now requires AT9 library 1.7.1 (DLL version 2.8.0.5) + or later. Compression in 32bit versions of FSBank is no longer supported + in line with Sony's removal of 32bit compression libraries. + +03/03/16 1.07.08 - Studio API patch release (build 73591) +---------------------------------------------------- + +Features: +* Unity 2 - Importing banks has been speed up dramatically. + +Fixes: +* Studio API - Fixed Studio::EventInstance::setProperty not restoring the default + setting for FMOD_STUDIO_EVENT_PROPERTY_MINIMUM_DISTANCE and + FMOD_STUDIO_EVENT_PROPERTY_MAXIMUM_DISTANCE when a value of -1 + is specified. +* Studio API - Fixed case of mono sounds panning hard left when both mono and + stereo 2D sounds are placed on the same event track, introduced + in 1.07.04. +* Core API - Fixed some net streams returning 'invalid parameter' introduced + in 1.07.06. +* Core API - Fixed potential crash if calling Sound::release soon after + System::createSound with FMOD_NONBLOCKING and async IO callbacks. +* Core API - Winstore/UWP - Fixed small memory leak on system shutdown. +* Core API - Winstore/UWP - Fixed occasional crash when closing a socket with a + pending asynchronous read. +* Core API - Xbox One - Fixed potential hang waiting on XMA Sound::release if + using async IO callbacks and a cancel was issued. +* Core API - Android - Relaxed overly strict validation of M4A files introduced + in 1.07.07. +* Core API - Android - Fixed potential JNI_OnLoad failure introduced in 1.07.07. +* Core API - Fix crash in convolution reverb if wet level is set to -80db + and it has no inputs. +* Core API - Fix seeking on stereo FADPCM compressed streams and samples. +* Unity 2 - Errors opening log output file are no longer fatal. + +Notes: +* Core API - Ensure FMOD_FILE_ASYNCDONE is called with FMOD_ERR_FILE_DISKEJECTED + if implementing FMOD_FILE_ASYNCCANCEL_CALLBACK to notify FMOD that + you will not be servicing the FMOD_ASYNCREADINFO::buffer. + +16/02/16 1.07.07 - Studio API patch release (build 72710) +---------------------------------------------------- + +Features: +* Core API - Win - Improved ASIO output to accept requested sample rate and + buffer size instead of using defaults. +* UE4 - FMOD Memory allocation now occurs via standard UE4 allocators. +* Unity 2 - Added AppleTV support. + +Fixes: +* Core API - Fixed System::loadPlugin not unloading the library file in the + case of an error. +* Core API - Fixed automatic format detection failing for some types when + the file size is less than 1KB. +* Core API - Fixed FMOD_CREATESOUNDEXINFO::suggestedsoundtype being ignored for + FMOD_OPENMEMORY and FMOD_OPENMEMORY_POINT. +* Core API - WinStore/UWP - Fixed occasional deadlock when removing the current + output device. +* Core API - Win - Fixed potential crash if switching output mode to ASIO after + System::init. +* Core API - Android - Fixed crash if MediaCodec processes a file that isn't an + M4A file. +* Core API - Android - Fixed Marshmallow devices being unable to load M4A files. +* Unity 2 - Remove broken inspector code for ParamRef. +* Unity 2 - Fix PS Vita. +* Unity 2 - Small event reference UI rendering fixes. +* Unity 2 - Fix unnecessary copying of files that haven't been modified. +* Unity 2 - Fix issues with copying of files that have only been partially + written by the Studio tool. +* Unity 2 - Work around IL2CPP issues introduced in Unity 5.3.2p2. +* Legacy Unity - Work around IL2CPP issues introduced in Unity 5.3.2p2. +* Unity 2 - Xbox One - Fix runtime errors when using Mono AOT compilation. + +Notes: +* Unity 2 - Unity 5.3.2p1 is not supported for iOS. +* Legacy Unity - Unity 5.3.2p1 is not supported for iOS. + +27/01/16 1.07.06 - Studio API patch release (build 71893) +---------------------------------------------------- + +Features: +* Studio API - Improved CPU and IO performance when capturing API commands + via Studio profiler. + +* Core API - Android - Lollipop devices may now select 7.1 with AudioTrack + output mode. Older devices will gracefully fall back + to stereo. +* Unity 2 - Emitter gizmos are now pickable in the scene view. +* Unity 2 - Event Browser layout changed to work in narrow windows. Note the + Event Browser windows will need to be closed and re-opened for new + minimum bounds to take effect. +* Unity 2 - Added bitcode support for iOS. +* UE4 - Added support for programmer sounds. See the new UE4 Programmer + Sound page for more information. + +Fixes: +* Core API - Fixed bug if streams start virtual, they may not come back as audible. + Introduced in 1.07.00 +* Core API - Update URL in Netstream example. +* Core API - Fixed net streams not working when server delivers shoutcast + with chunked HTTP data. +* Core API - Fixed memory leak when a network connection fails. +* Core API - Android - Devices that don't support 5.1 output will now + gracefully fallback to stereo. +* Core API - WinStore / UWP - Fixed WASAPI output so it return the correct 'no + drivers' error when none are detected. +* Core API - WinStore / UWP - Fixed WASAPI output swapped sides and rears in 7.1. +* Core API - Fix C# wrapper of ChannelGroup.addGroup missing arguments. +* Core API - Fix crash when using chorus effect on a channel group with + channel count greater than the system channel count. +* Core API - PS4 - Fix validation of thread affinity settings. +* Core API - iOS - Fixed compatibility issue introduced in 1.07.02 for old + devices running iOS 6.X. +* Unity 2 - Fixed UI when EventRef attribute is used on an array of strings. +* Unity 2 - Work around DLL loading issues on some standalone Windows builds. +* Unity 2 - Fix DLL loading issues for play-in-editor when platform is iOS. +* Unity 2 - Fix RuntimeManager being recreated during shutdown and leaking FMOD + native instances. +* Unity 2 - Fix issue when using RuntimeManager.LowLevelSystem and + RuntimeManager.StudioSystem before RuntimeManager has initialized. +* Unity 2 - Increase channels for Play-In-Editor. +* Unity 2 - Fix play-in-editor not setting the speaker mode correctly. +* Unity 2 - PS4 - Fix script compile errors. + +Notes: +* Xbox One - Now built with November 2015 XDK. +* iOS - Now built with iOS SDK 9.2 and tvOS SDK 9.1 (Xcode 7.2). +* UE4 - Updated Oculus plugin for 1.0.1. + +07/01/15 1.07.05 - Studio API patch release (build 71238) +---------------------------------------------------- + +Features: +* Unity 2 - When using the file browser in the settings editor to set + the Studio source paths the result will be set relative + to the Unity project if it is a sub-directory. +* Unity 2 - Added Parameter Trigger component. + +Fixes: +* Core API - UWP - Fixed FMOD_SYSTEM_CALLBACK_DEVICELISTCHANGED not firing + when the default output device changes. +* Core API - PS3 - Fix rare crash with reverb. +* Core API - PS3 - Fix static and audio dropouts if speaker mode is forced + to stereo (normally it is 7.1). + +Notes: +* iOS - Reduced binary size. +* Android - Added calling convention to public API to allow usage with + hard float ABI. + +11/12/15 1.07.04 - Studio API patch release (build 70728) +---------------------------------------------------- + +Features: +* Core API - Better support for sounds with channel/speaker masks, ie a 1 + channel sound specified as LFE, or a quad sound specified as LRCS + instead of 2 front 2 back for example. +* Unity 2 - Added optional debug overlay. +* Unity 2 - Added migration steps for data in custom components. +* Unity 2 - Added support for Unity 4.6. +* Unity 2 - Added support for Android split binary. +* Unity Legacy - Added support for Android split binary. + +Fixes: +* Studio API - Fixed blocking bank loads stalling for longer than necessary when + other threads are constantly issuing new Studio commands. +* Core API - Fixed corrupted playback for big endian PCM FSBs. +* Core API - Fixed crash when switching channel count of generator DSPs + during playback. +* Core API - PS3 - Fix crash reallocating buffers on flange effect. +* Core API - Xbox One - Fixed rare stall when playing XMA streams and + compressed samples at the same time. +* Core API - Fix crash if the Master Channel Group head DSP was set inactive right + after initialization. +* Core API - Fix Sound::getOpenState() moving from FMOD_OPENSTATE_PLAYING too early + on some streaming sounds. +* Core API - Fix Sound::Release() freeing memory still in use by the mixer. +* Core API - Fix convolution reverb not correctly producing tails on long impulse + responses when it has no input. +* Unity 2 - Fixed issue with plugins not being loaded correctly. +* Unity 2 - Work around DLL loading issues on some standalone Windows builds. +* Unity 2 - Fix leaking system objects leading to ERR_MEMORY. +* Unity 2 - Updated signature of DSP::setWetDryMix, DSP::getWetDryMix. + +Notes: +* Core API - FMOD_DSP_STATE::channelmask is now passed down through the dsp chain + so plugin developers can see the original signal channel format even + if a sound was upmixed. + +17/11/15 1.07.03 - Studio API patch release (build 69975) +---------------------------------------------------- + +Features: +* Core API - When using System::recordStart the provided FMOD::Sound can now be + any channel count, up/down mixing will be performed as necessary. +* Core API - Improved performance of convolution reverb effect when wet is 0 + or input goes idle. +* Core API - PS4 - Added FMOD_THREAD_CORE6 to allow access to the newly unlocked + 7th core. +* Core API - PS4 - Added FMOD_PS4_GetPadVolume() to retrieve the output volume + of the pad speaker as set by the user in the system software. +* Core API - Added FMOD_DSP_TYPE_TRANSCEIVER. Send signals from multiple sources + to a single 'channel' (out of 32 global 'channels') and receieve from + that or any channel from multiple receivers. Great for receiving + and broadcasting a submix from multiple 3d locations (amongst other + uses). +* Unity - FMOD_StudioSystem.GetEvent() can now be used with snapshot paths. +* Unity - Ignore OSX resource fork files when importing from FAT32 file systems. +* UE4 - Deployment will also copy any plugins listed in a file plugins.txt + in the FMODStudio/Binaries/Platform directory. See the Using + Plugins page for more information. +* UE4 - Console platforms set up thread affinity in FMODPlatformSystemSetup. + +Fixes: +* Studio API - Fixed snapshot applied to VCA level not working in game. +* Studio API - Fixed profiler session timing when recording a game with a non-standard + sample rate. +* Studio API - PS4 - Fix linker error in examples. +* Core API - Fixed buffer overrun when convolution reverb is set up with + mismatched input and output channels. +* Core API - Fix crash with invalid .mp3 files. +* Core API - Fix Sound::getName() not returning a valid UTF8 string when + loading a sound with ID3 tags specifying the title as a latin1 + string. +* Core API - Fix pops in flange and chorus effects. +* Core API - Fix crash when using flange effect on a channel group with + channel count greater than the system channel count. +* Core API - FLAC - Fix crash when seeking in certain flac files. +* Core API - Android - Automatic selection of OpenSL output mode will now + be stricter to reduce stuttering on devices that + incorrectly report they are low latency. +* Core API - PS4 - Fix signal not being routed back to the main output when + detaching a channel group from a port. +* Core API - Fix FMOD_ADVANCEDSETTINGS::reverb3Dinstance not working. + +Notes: +* Android - Now built with NDK r10e. +* PS Vita - Now built with SDK 3.550. +* Core API - FMOD_DSP_CHANNELGAIN_OUTPUT_DEFAULT ... FMOD_DSP_CHANNELGAIN_OUTPUT_ALLLFE + (from the FMOD_DSP_CHANNELMIX_OUTPUT enum) have been renamed to + FMOD_DSP_CHANNELMIX_OUTPUT_DEFAULT ... FMOD_DSP_CHANNELMIX_OUTPUT_ALLLFE + (ie CHANNELGAIN renamed to CHANNELMIX) to fit with the correct naming + convention. Rename required if using this effect. + +02/11/15 1.07.02 - Studio API patch release (build 69450) +---------------------------------------------------- + +Important: +* AppleTV platform support is now part of the iOS package. + +Features: +* Core API - Improved performance of System::getChannelsPlaying. +* Core API - Added System::getChannelsReal to get the number of + non-virtual playing channels. + +Fixes: +* Studio API - Fixed internal error during playback caused by inaccuracies + in quantization calculation when timeline position is greater + than 5 minutes. +* Core API - Fix mixer not running if mixer sample rate is lower than output + sample rate. +* Core API - Fix Sound::getOpenState returning FMOD_OPENSTATE_READY when a + sounded ended, when it should have returned + FMOD_OPENSTATE_PLAYING for a bit longer, which meant + Sound::release could stall. +* Core API - iOS - Fixed output being mono on some devices, minimum detected + hardware channel count is now 2 to ensure stereo. + +Notes: +* iOS - Now built with iOS SDK 9.1 and tvOS SDK 9.0 (Xcode 7.1). +* Mac - Now built with SDK 10.11 (Xcode 7.1). + +27/10/15 1.07.01 - Studio API patch release (build 69235) +---------------------------------------------------- + +Features: +* Studio API - Added support for multiple parameter conditions. +* Studio API - Added Studio::EventDescription::getSoundSize. +* UE4 - Added validation help menu option to diagnose common issues. + +Fixes: +* Studio API - Fixed auto-pitch, cutoff and looping not live updating properly. +* Core API - Fixed potential crash on ARM platforms when seeking Vorbis + compressed FSBs. +* Core API - Fix ChannelGroup::setReverbProperties from returning + FMOD_ERR_REVERB_CHANNELGROUP if a child channel had a reverb + connection previously. +* Core API - Fixed FMOD_CREATESOUNDEXINFO::suggestedsoundtype being ignored if + a custom codec of higher priority has been registered. +* Core API - Fixed System::getRecordNumDrivers incorrectly reporting 0 if + called within 1 second of application start on some platforms. +* Core API - Fixed stereo AIFF files producing static. +* Core API - Xbox One - Fixed rare crash for stereo XMA streams. +* Core API - iOS - Fixed MP3 decoding being performed by FMOD cross-platform + decoder instead of native AudioQueue. +* Core API - Fix mp3 crash seeking, introduced in 1.07.00 if using certain types + of MP3 file in FMOD_CREATECOMPRESSEDSAMPLE mode. +* Unity - Change Android to read banks straight from APK +* Unity - Will automatically append a "64" suffix to plugins if required. +* Unity - Fix OSX bundles having incorrect settings +* Unity - Fix compatibility with Unity 5.2.2 +* Unity - Fix crashes when creating a standalone OSX build. +* UE4 - Fix for audio component direction not being set into FMOD. +* UE4 - Fixed IOS deployment error "libfmod does not exist" + +Notes: +* Studio API - The FMOD_STUDIO_EVENT_CALLBACK_PLUGIN_CREATED and + FMOD_STUDIO_EVENT_CALLBACK_PLUGIN_DESTROYED callbacks now + fire from nested events, for both plugin effects and plugin + sounds. +* Studio API - For the FMOD_STUDIO_PLUGIN_INSTANCE_PROPERTIES callback + argument, the 'name' field will contain just the user defined + name of the plugin sound if one has been set. Otherwise it + will be empty. You can use the 'dsp' field to determine the + plugin type. +* Studio API - Programmer sounds with no name will have an empty string for + FMOD_STUDIO_PROGRAMMER_SOUND_PROPERTIES.name, previously it + was an arbitrary hex sequence. +* Core API - Plugin developers - FMOD_DSP_SYSTEM_GETSPEAKERMODE added to + FMOD_DSP_STATE_SYSTEMCALLBACKS. Plugin SDK version updated to 1.07 meaning + plugins created from this point onwards wont work with older versions of + FMOD. +* Android - Replaced all Eclipse examples with Visual Studio using NVIDIA + Nsight Tegra integration. +* PS4 - Now built with SDK 3.008.041 +* PS3 - Now built with SDK 475.001. + +05/10/15 1.07.00 - Studio API minor release (build 68517) +---------------------------------------------------- + +Important: +* Studio is now a 64-bit application. All plugin libraries must be built for + 64-bit architecture to be compatible with the 64-bit version of the tool. +* Added Universal Windows Platform (UWP) support. +* Added AppleTV platform support. Contact support@fmod.org for beta access. + +Features: +* Studio API - Support for bus polyphony. +* Studio API - Added FMOD_STUDIO_EVENT_PROPERTY_MINIMUM_DISTANCE and + FMOD_STUDIO_EVENT_PROPERTY_MAXIMUM_DISTANCE to override the + minimum and maximum panner distance for an instance. +* Studio API - Added FMOD_STUDIO_INIT_DEFERRED_CALLBACKS to defer event + callbacks to the main thread. See + Studio::EventInstance::setCallback for more information. +* Core API - Added FMOD_DSP_TYPE_CHANNELMIX effect. Allows user to control + gain levels for up to 32 input channel signals, and pipe the + output to a range of speaker formats i.e. repeating mono, + stereo, quad, 5.1, 7.1 or only LFE out. +* Core API - Improved CPU performance when using metering or profiling. +* Core API - Added support for loading multi-channel FSBs with the + FMOD_CREATECOMPRESSEDSAMPLE flag. +* Core API - Improved record driver enumeration, list is now persistent, + removed devices will remain to ensure record IDs stay valid. + See record_enumeration example for new functionality. +* Core API - Added full record device add/removal detection for Windows, + Mac, Xbox 360, Xbox One, PS3 and PS4. +* Core API - Reduced recording latency on Windows, XboxOne and PS4. +* Core API - Mac - Added support for recording from multiple microphones at + the same time. +* Core API - Win - Improved CPU performance for FSB Vorbis decoding. See + Performance Reference section of the documentation for + updated benchmark results. +* Core API - iOS - Added support for bitcode. + +Fixes: +* Studio API - Fixed the scatterer module's random distance calculation to + ensure it is within the limit set in Studio. In previous + versions the random distance may have exceeded the max limit. + This change may affect the loudness of sounds with scatterer + modules compared to 1.06.xx releases. +* Core API - Fix rare crash when releasing a streamed sound. +* Core API - Fix output plugins with GUIDs of zero stopping setDriver + working. +* Core API - PS3 - Fixed send/returns not respecting volume changes or + rarely failing with an error when setting return IDs. +* Core API - PS4 - Rewrote output to use sceAudioOutOutputs instead of + multiple sceAudioOutOutput calls on a single thread. +* Core API - Win - Fixed the audible output driver from resetting when an + unrelated device is removed or disabled. +* Core API - Xbox One - Fixed the first couple of samples of decoded XMA + being lost due to SHAPE SRC. + +Notes: +* Studio API - Incremented bank version, requires runtime 1.07.00 or later. +* Studio API - Latest runtime supports loading old bank versions from 1.03.00. +* Studio API - Improved compatibility for plugin effects. Adding extra DSP + parameters to an effect no longer breaks bank version + compatibility. +* Studio API - Studio::Bank::getEventCount and Studio::Bank::getEventList only + return events directly added to the bank, not implicit events + that are included in the bank due to event instrument references. +* Studio API - The asynchronous command buffer for the Studio API will now + grow as necessary, avoiding stalls that could occur if it was too + small. The commandQueueSize field in FMOD_STUDIO_ADVANCEDSETTINGS + now specifies the initial size of the buffer. +* Studio API - Studio now enables FMOD_INIT_VOL0_BECOMES_VIRTUAL by default. +* Studio API - WinStore - Fixed inconsistent naming of X64 libraries. +* Core API - Increased FMOD_MAX_LISTENERS from 5 to 8. +* Core API - System::getCPUUsage update time now includes the metering and + profiling part of the update. +* Core API - Removed support for FSB Vorbis files built using FMOD Ex 4.42 or + earlier. +* Core API - PS4 - Changed default mix buffer size to 512 samples to reduce + CPU cost. Previous setting of 256 can be set using + System::setDSPBufferSize. +* Core API - PS4 - The size of each pre-allocated AT9 instance has increased + by 8kB. +* Core API - PS4 - Prebuilt static libraries are no longer provided, + only dynamic libraries. +* Core API - WinStore - Fixed inconsistent naming of X64 libraries. + +05/10/15 1.06.11 - Studio API patch release (build 68487) +---------------------------------------------------- + +Features: +* Win - Reduced dll and exe sizes. + +Fixes: +* Studio API - Fixed input buses not being released when there are no longer + any event instances routed into the bus. +* Studio API - Fixed API capture recording the initial VCA level as 0. +* Core API - Fix rare crash when changing the master channel group head DSP + when the software format and system output don't match. +* Core API - Fix Channel::AddDSP() and ChannelGroup::AddDSP() not correctly + moving a DSP if it's already a member. +* Core API - Fix for noise being produced when panning a surround input + when the system format doesn't match the panner input format. +* Unity - FMOD RNG seed set at initialization time. +* Unity - Can now properly cancel the copy step of the import process. +* Unity - Updated documentation links in menu. + +Notes: +* iOS - Now built with SDK 9.0 (Xcode 7.0). +* Mac - Now built with SDK 10.11 (Xcode 7.0). + +15/09/15 1.06.10 - Studio API patch release (build 67958) +---------------------------------------------------- + +Features: +* Core API - Add Sound::seekData support to HTTP streams. +* UE4 - Added blueprint functions for loading and unloading sample data. + +Fixes: +* Core API - Fix small reverb pop on sounds that had Channel::setPosition + called on then and were muted via a parent channelgroup. +* Core API - Fix https netstream redirects not working. +* Core API - Fix user DSP read callback firing with no data if + Channel::setPaused(false) is used after a System::playSound. +* Studio API - Fixed Trigger Delay not being applied to sounds on parameters + that trigger immediately when an event starts. + +Notes: +* Xbox One - Now built with August 2015 XDK. + +01/09/15 1.06.09 - Studio API patch release (build 67431) +---------------------------------------------------- + +Features: +* Studio API - Additional logging when banks have been exported with out of + date plugin effects. + +Fixes: +* Core API - Fix automatic device changing support if a user called + System::update from their own thread. +* Core API - Fix crash when a channel group cannot be attached to port. +* Core API - Fixed incorrect loop length being set for ADPCM files. +* Core API - Win64 - Enable automatic device changing support. +* Core API - iOS - Fixed error creating the file thread on iOS 9.0. +* Core API - Fix distance filtering not resetting its parameters properly + for channels. +* Core API - MIDI support - Fix note keyoff when evelope is in decay phase + causing note to finish early. +* Studio API - Fix crash that could occur when auditioning an event in + Studio while changing the path to waveforms. + +Notes: +* UE4 - Updated oculus rift plugin to version 0.11 + +12/08/15 1.06.08 - Studio API patch release (build 66772) +---------------------------------------------------- + +Features: +* UE4 - Added FMOD init settings. +* UE4 - Added preliminary support for 4.9 engine preview build. +* Core API - Add Channel::setPosition support to HTTP streams. + +Fixes: +* Core API - Fixed System::getDefaultMixMatrix crashing if passed + FMOD_SPEAKERMODE_RAW. Now returns FMOD_ERR_INVALID_PARAM. +* Core API - Xbox One - Fixed crash if all SHAPE contexts are consumed. +* Core API - Xbox One - Fixed XMA loops not being seamless. +* Studio API - Fixed potential crash when disconnecting from live update + while recording a profiling session. +* Studio API - WiiU - Fixed hang on shutdown when exiting game from home menu. +* Core API - Fix for inaccurate metering levels when the calculation spanned + multiple mix blocks. +* Core API - Fixed System::getRecordPosition race condition that could cause + the returned value to be out of bounds. +* Unity - Fixed missing functionality from C# wrapper for beat callbacks + and metering. +* Unity - Fix leaking native system objects in editor. +* UE4 - Fixed multiple listeners. +* FSBank - Fixed crash encoding FADPCM format in 64bit version of tool. + +Notes: +* Studio API - Reduced memory usage for instruments that do not require + up/down mix. +* Core API - Improved performance of DSP::getParameterFloat, + DSP::getParameterInt, DSP::getParameterBool and + DSP::getParameterData when 'valuestr' argument is NULL. + +22/07/15 1.06.07 - Studio API patch release (build 66161) +---------------------------------------------------- + +Fixes: +* Core API - Win - Fix audio glitches at initialization time when using + the WASAPI output mode on Windows 10. +* Core API - Fix UTF8 strings in MP3 ID3V2 tags not being null terminated + properly leading to possible string overflow crash. +* Core API - PS4 - Fixed issue with non-1024 sample aligned loop-points and AT9 + compressed samples. +* Core API - Fixed memory leak when releasing connections that have a user + allocated mix matrix. +* Core API - Added pre-wet and post-wet arguments to WetDryMix in C# wrapper. +* Core API - Fixed crash with FADPCM streams. +* Core API - Fixed another potential crash in PitchShifter DSP if changing + channel count while running. +* Core API - Win - Fix issues caused by WASAPI allocating the output buffer at + the mixer's sample rate instead of the device's sample rate. +* Studio API - XboxOne - Fix setting the thread affinity of the studio loading thread. +* Studio API - Fixed case of nested events on parameters being stopped while + still active. Introduced in 1.06.04. + +Notes: +* Studio API - Incremented bank version, requires runtime 1.06.06 or later. +* Studio API - Latest runtime supports loading old bank versions from 1.03.00. +* Core API - XboxOne - Thread affinity can now be set as a mask of allowed cores. + +08/07/15 1.06.06 - Studio API patch release (build 65638) +---------------------------------------------------- + +Features: +* Core API - Added FMOD_DSP_COMPRESSOR_LINKED parameter to DSP compressor. + +Fixes: +* Studio API - Fixed potential invalid memory access when a bank is unloaded + while create instance commands are queued. +* Studio API - Removed one frame delay between setting a parameter and having + conditional timeline transitions occur. +* Studio API - Studio gracefully handles the case of a programmer sound being + returned in a streaming not-ready state when the instrument is + being used with timelocked seeks. +* Core API - Fixed rare crash when streams go virtual. +* Core API - Fixed 3EQ DSP not waiting an extra mix block before going idle, + possibly cutting off a tail. +* Core API - Fixed potential crash in PitchShifter DSP if changing channel + count or FFT size while running. +* Core API - Fixed rare volume pop when ramping with fade points as a channel + goes emulated. +* Core API - Linux - Fixed record position not advancing with ALSA output mode. +* Core API - Fix race condition when setting the impulse response on an active + convolution reverb DSP. +* Unity - Fix compatibility with Unity 5.1 + +24/06/15 1.06.05 - Studio API patch release (build 65161) +---------------------------------------------------- + +Features: +* Studio API - Added FMOD_STUDIO_LOAD_BANK_DECOMPRESS_SAMPLES flag to + force bank sample data to decompress into memory, saving + CPU on low end platforms. +* Studio API - Improved responsiveness when reducing steal oldest polyphony + over live update. +* Studio API - Studio profiling now includes nested instance information. +* UE4 - Exposed beat and marker callbacks as Blueprint events. + +Fixes: +* Studio API - Fixed Scatterer sounds having incorrect volume when min and + max scatter distances are equal. Introduced in 1.06.00. +* Studio API - Fixed FMOD_STUDIO_TIMELINE_BEAT_PROPERTIES position to + return the beat position, rather than the tempo marker + position. +* Studio API - Fix deadlock in studio when removing an output device that + runs at a different sample rate to the system. +* Studio API - Fix deadlock in studio when removing certain USB headsets. +* Core API - Fixed rare case of DSP mixer not responding momentarily if + output mode was switched during playback. +* Core API - Fix declaration of DSP.getMeteringInfo in C# wrapper. + +Notes: +* UE4 - Now built against Unreal 4.8 + +09/06/15 1.06.04 - Studio API patch release +---------------------------------------------------- + +Features: +* Studio API - Added tempo and marker event callbacks. See + FMOD_STUDIO_EVENT_CALLBACK_TIMELINE_MARKER and + FMOD_STUDIO_EVENT_CALLBACK_TIMELINE_BEAT. +* Core API - Add FMOD_DSP_DESCRIPTION::sys_register, sys_deregister and + sys_mix for DSP plugin developers, to allow a per type (not + instance) level init/shutdown/mix callback for a plugin. + +Fixes: +* Core API - Fixed MIDI playback not correctly handling CC1 (mod wheel). +* Studio API - Fixed livelock when scheduling nested events in a playlist that + have 0 duration. +* Studio API - Fixed events staying active when they have active but idle + nested events on parameters. Events now finish once their + nested parameter events go idle. +* Studio API - Fixed Scatterer sounds not being spatialized properly. + Introduced in 1.06.00. +* FSBank - Fix bug that prevented selection of FMOD ADPCM in the tool. +* Core API - Fix set3DPanLevel not respecting reverb mix when pan level + was approaching 0. +* Core API - Fix 2d channels not having the wet mix scaled for reverb when + parent ChannelGroup volume/mute functions were called. +* Unity - Remove warnings about banks already loaded +* Unity - Fix Unity Editor crashing when using FMOD_LIVEUPDATE and + FMOD_DEBUG pre-processor commands simultaneously. + +Notes: +* Studio API - Incremented bank version, requires runtime 1.06.00 or later. +* Studio API - Latest runtime supports loading old bank versions from 1.03.00. +* Studio API - Added a warning for events that haven't finished because they + are waiting for a DSP effect to go idle. +* Core API - WiiU - To comply with LotCheck requirements only the logging version + of FMOD will link with networking APIs +* Xbox One - Now built with May 2015 QFE 1 XDK. +* WiiU - Now built with SDK 2.12.13. + +22/05/15 1.06.03 - Studio API patch release +---------------------------------------------------- + +Features: +* Studio API - Reduced memory overhead of bank metadata. + +Fixes: +* Studio API - Fixed steal oldest polyphony behaviour using instance creation + instead of instance start time. +* Studio API - Fixed playlist instrument cutoff not applying a volume ramp down + which could cause pops when using polyphony. +* Core API - Fixed invalid memory access when loading an incorrectly formatted + or truncated IMA ADPCM wav file using FMOD_OPENMEMORY_POINT and + FMOD_CREATECOMPRESSEDSAMPLE. +* Core API - Fix rare crash due to race condition when calling Sound::Release() + just after the sound has been loaded using NON_BLOCKING. +* Core API - PS3 - Fix deadlock in streaming when using SPU Threads. +* Core API - Attempting to attach the Master ChannelGroup to a port will now + return FMOD_ERR_INVALID_PARAM. +* Core API - PS4 - Fix issues with recording at rates other than the driver + default. +* Core API - Fix crash in DSPFader when voice goes virtual with DSP effect added + at a position lower than the fader (ie post fader), and the effect + is freed. +* UE4 Integration - Fixed incorrect listener orientation. + +Notes: +* Studio API - Changed envelope follower DSP sidechain parameter to ignore + invalid values. +* Xbox One - Now built with April 2015 XDK. +* 7.1 to 5.1 downmix now lowers the volumes of the back speakers' + contribution to the surround speakers by 1.5db to lessen volume bulge + in the middle. + +06/05/15 1.06.02 - Studio API patch release +---------------------------------------------------- + +Features: +* Studio API - Sounds on parameters that are cross-fading in will now apply a + ramp volume up to the initial cross-fade value. This avoids pops + even if the sound has been improperly authored. +* UE4 Integration - Added support for Reverb zones. +* UE4 Integration - Exposed Studio::EventInstance::getTimelinePosition and + Studio::EventInstance::setTimelinePosition as blueprint + functions. + +Fixes: +* Studio API - Fixed transition timeline modules not crossfading their + volume properly when overlapping the lead out region. +* Studio API - Fixed C# wrapper not linking against 64bit dll when WIN64 is defined. +* Studio API - Fixed events with sidechains never naturally stopping. +* Studio API - Fixed runtime crash caused by a compiler bug for customers compiling + from source using VS2015 CTP. +* Core API - WiiU - Fixed incorrect pitch for DRC if System is running a + rate other than 48KHz or 32KHz. +* Core API - PS4 - Fix small memory leak when closing output ports. +* Core API - Fixed documentation regarding FMOD_DSP_COMPRESSOR_USESIDECHAIN and + FMOD_DSP_ENVELOPEFOLLOWER_USESIDECHAIN. +* Core API - WinStore - Fix System::Init() freezing when called from the UI thread. + +* UE4 Integration - Fixed bad editor performance when selecting audio components. +* UE4 Integration - Fixed several Android deployment issues. + +* Unity Integration - Fix compilation issues on iOS when using IL2CPP. +* Unity Integration - Logging libs for OSX are now included. Defining FMOD_DEBUG + will now route FMOD internal logging to the Unity console in the + OSX editor and standalone OSX builds. +* Unity Integration - Make members of the REVERB_PROPERTIES structure public. +* Unity Integration - Fix compile error on XBox One when defining FMOD_DEBUG. + +Notes: +* UE4 Integration - Merged documentation with main API documentation. + +17/04/15 1.06.01 - Studio API patch release +---------------------------------------------------- + +Features: +* Studio API - Added FMOD_STUDIO_EVENT_CALLBACK_CREATED, + FMOD_STUDIO_EVENT_CALLBACK_DESTROYED and + FMOD_STUDIO_EVENT_CALLBACK_START_FAILED callback types. +* Studio API - Exposed FMOD_STUDIO_EVENT_PROPERTY_SCHEDULE_DELAY and + FMOD_STUDIO_EVENT_PROPERTY_SCHEDULE_LOOKAHEAD as advanced + properties that can be set per instance. + +Fixes: +* Core API - Fixed Channel userdata not being reset to 0 each playSound. +* Core API - Fixed the C# wrapper for DSP.AddInput and DSP.disconnectFrom. +* Core API - PS4 - Fixed playback issue with AT9 compressed samples that have + a non-zero loop start point. +* Core API - Fix rare issues with generator DSPs or compressed channels getting + stuck looping the same fragment of audio. +* Core API - PS3 - Fix rare crash if sound stops on a channelgroup with a matrix + set in it. + +* Unity Integration - Fix banks not being loaded on standalone OSX builds. +* Unity Integration - Logging libs for windows are now included. Defining FMOD_DEBUG + will now route FMOD internal logging to the Unity console in the + Windows editor and standalone Windows builds. + +Notes: +* PS4 - Now built with SDK 2.508.051. + +10/04/15 1.06.00 - Studio API minor release +---------------------------------------------------- + +Important: +* Studio API - Scatterer sounds now steal the oldest spawned sound if the + polyphony limit has been reached when spawning a new sound. + +Features: +* Added new compression format FADPCM as a higher quality, lower CPU cost drop + in replacement for standard IMA ADPCM. This custom developed format is our new + recommendation for mobile, PS Vita and Wii U delivered exclusively via FSB. +* Core API - Improved CPU performance of convolution reverb by 30% +* Core API - Android - Improved latency by automatically resampling to the + native rate to enable the fast mixer. +* Core API - PS Vita - Removed requirement to use 48KHz mixing, default is + now 24KHz for better performance. +* Core API - Xbox One - Optimized performance for looping compressed XMA. +* Core API - Xbox One - Added support for greater than stereo XMA streams. +* Core API - Xbox One - Reduced output latency by 20ms. +* Studio API - Significantly reduced memory usage. +* Studio API - Added Studio bank loading thread. +* Studio API - Added Studio::Bank::getUserData and Studio::Bank::setUserData. +* Studio API - Added FMOD_STUDIO_SYSTEM_CALLBACK_BANK_UNLOAD callback. +* Studio API - Support for transition timeline lead-in and lead-out. +* Studio API - Added support for setting Studio async update period via + FMOD_STUDIO_ADVANCEDSETTINGS. +* Core API - PS4 - Added support for High Quality Recording API by default. + +Fixes: +* Studio API - Fixed parameter modulation being unable to go below the value + set from the public API. +* Studio API - Fixed effect bypass setting not being saved to banks. + +Notes: +* Studio API - The C# wrapper now uses System.Guid instead of FMOD.GUID. +* Studio API - Default command buffer size has been increased to 32K. +* Studio API - Studio::System::setListenerAttributes and + Studio::System::getListenerAttributes now take a listener + index in preparation for multiple listener support. +* Studio API - Deprecated Studio::ID typedef. Please use FMOD_GUID type. +* Studio API - Changed FMOD_STUDIO_EVENT_CALLBACK_TYPE from an enum to a + bitfield. Added 'callbackmask' parameter to + Studio::EventDescription::setCallback and + Studio::EventInstance::setCallback. +* Studio API - Studio::System::startRecordCommands and + Studio::System::stopRecordCommands has been renamed to + Studio::System::startCommandCapture and + Studio::System::stopCommandCapture. +* Studio API - Studio::System::playbackCommands has been renamed to + Studio::System::loadCommandReplay and now returns + a CommandReplay object. +* Studio API - Schedule delay and look-ahead has been reduced for Studio + async mode. This reduces latency and improves responsiveness + of events to parameter changes. +* Core API - System::set3DListenerAttributes checks for invalid + arguments in release. +* Core API - Thread safety no longer uses a command queue for deferring + selected API functions until the next update. The queue of + deferred functions was most often flushed by a subsequent + getter function or other setter function anyway. +* Core API - Added 'numconnected' to System::getRecordNumDrivers and + 'state' to System::getRecordDriverInfo in preperation for + changes to how recording device removal is handled. Currently + 'numconnected' will equal 'numdrivers' and 'state' will + be FMOD_DRIVER_STATE_CONNECTED. +* Core API - Some of the FMOD_PAN_ types have been renamed FMOD_DSP_PAN_ + for consistency. +* Core API - Calling ChannelControl::getAudibility on a ChannelGroup now + returns the combined audibility of itself and the parent + audibility. + +02/04/15 1.05.15 - Studio API patch release +---------------------------------------------------- + +Fixes: +* Core API - Win - Fixed occasional deadlock when removing audio devices. +* Core API - Fixed stream crackling if initialseekposition was used immediately + followed by Channel::setPosition with a close position value. +* Core API - PS3 - Fixed six or eight channels vorbis streams crashing the SPU. +* Core API - Xbox One - Fixed rare hang when decoding small XMA compressed audio. +* Core API - Fixed DSP::getInfo not returning configwidth and confighheight + information for VST plugins. +* Core API - Fixed rare crash calling DSP::reset on the fader DSP, after + ChannelGroup::setPan/setMixLevelsOutput/setMixMatrix. This + could occur when a Studio event is started or stopped. +* Core API - PS4 - Fixed issue with non-1024 sample aligned loop-points and AT9 + compressed samples. +* Core API - Fixed DSP effect being un-removable with FMOD_ERR_DSP_INUSE after + being added to a channel and the channel stops (becoming invalid). + +Notes: +* PS3 - Now built with SDK 470.001. + +16/03/15 1.05.14 - Studio API patch release +---------------------------------------------------- + +Fixes: +* Core API - Fixed some cases where channel group audibility was not refreshed + when fade points are active. This could happen when a Studio event + instance is paused and unpaused. +* Core API - PS3 - Fixed FMOD_PS3_INITFLAGS overlapping FMOD_INITFLAGS causing + certain FMOD_INITFLAGS to affect PS3 specific bit-stream + encoding options. +* Core API - PS3 - Fixed a rare hang when releasing a DSP that exposes + a FMOD_DSP_PARAMETER_OVERALLGAIN parameter. +* Core API - PS3 - Fixed opening URL failing with network streams. +* Core API - Xbox One - Fixed recording API, you can now specify any sample rate + to record at. Native rate of 48KHz is still recommended + for lowest latency. +* Studio API - Fixed virtualized event failing to become real if the number + of playing instances drops back below max polyphony. + +Notes: +* Core API - PS3 - Deprecated FMOD_PS3_EXTRADRIVERDATA::initflags. Due to a + bug it was being ignored. Pass the flags to System::init instead. + +25/02/15 1.05.13 - Studio API patch release +---------------------------------------------------- + +Features: +* Studio API - Studio::System::getBank now accepts bank filenames as input. +* Core API - Added 64bit versions of fsbank and fsbankcl tools. + +Fixes: +* Studio API - Fixed case of nested event not being destroyed even after it + had finished producing sound. +* Studio API - Fixed crash when changing output bus on an event when live update + is connected. +* Studio API - Fixed deadlock when calling Studio commands when mixer is suspended. +* Studio API - System::release now ensures release even if flushing pending commands + causes an error. +* Studio API - The name of the string bank is now added to the string bank. +* Studio API - Event instance restart now flushes parameter values before timeline + rescheduling occurs. This avoids a potential issue for transitions + with parameter conditions, where they may not have used the most + recent parameter value. +* Core API - Fix unnecessary querying of recording driver capabilities during + recording. +* Core API - PS4 - Remove AT9 workaround added in 1.05.12. Fix AT9 compressed + codecs with finite loop counts. +* Core API - PS4 - Removed stalls when an AT9 compressed sample channel is started. +* Core API - PS4 - Fix crash in recording. +* Core API - Fix multiple listener support not working properly. +* Core API - Fix user file crash if using asyncfileread callback, and file + open and close happens without any read occuring. +* Core API - Fix rare crash with Sound::release if a nonblocking setPosition + is in process and it is an FSB sound. +* Core API - Fix thread safety issue loading multiple mod/s3m/xm/it files + simultaneously. +* Core API - Fix rare crash if FMOD_ACCURATETIME was used with .mp3 file + followed by mp3 encoded FSB file after a time, both using + FMOD_CREATECOMPRESSEDSAMPLE. +* Core API - PS3 - Fixed custom DSP that use the plugindata member. + +Notes: +* Studio API - Updated programmer_sound example. +* Core API - Added plug-in inspector example. +* Xbox One - Now built with February 2015 XDK. + +06/02/15 1.05.12 - Studio API patch release +---------------------------------------------------- + +Features: +* Studio API - Improved memory use for events with repeated nested events. + +Fixes: +* Studio API - Fixed crash when stopping multiple one-shot events on a bus. +* Studio API - Fixed nested event polyphony from cutting off immediately, + causing pops. +* Core API - Fixed rare crash in mixer if DSP::reset is called on a + FMOD_DSP_TYPE_FADER dsp (ie ChannelControl head DSP) + after DSP::setPan/setMixLevelsOutput/setMixMatrix. +* Core API - Fixed race condition setting resampling speed while resampling + is occurring. +* Core API - Fixed crash loading mod/s3m/xm/it file using FMOD_NONBLOCKING + and FMOD_CREATECOMPRESSEDSAMPLE and then immediately calling + SoundI::release +* Core API - PS4 - Work around AT9 codec issues that have appeared when using SDK 2.000 + +22/01/15 1.05.11 - Studio API patch release +---------------------------------------------------- + +Features: +* Core API - Xbox One - Added access to 7th CPU core. + +Fixes: +* Studio API - Fixed crash setting Studio event callback to null as it is + being invoked. +* Studio API - Fixed crash in hashmap reallocation when running out of memory. +* Studio API - Fixed Studio::loadBankCustom from freeing its custom userdata + before the close callback for failed banks. +* Studio API - If FMOD_OUTTPUTTYPE_WAVWRITER_NRT or NOSOUND_NRT is used as an + output mode, Studio runtime will now internally force + FMOD_STUDIO_INIT_SYNCHRONOUS_UPDATE to avoid a hang. +* Core API - Fix pop noise when 3d sound goes virtual then becomes real again, + only if ChannelControl::addDSP was used. + +Notes: +* Studio API - Studio::EventInstance::getPlaybackState will now return the state + as FMOD_STUDIO_PLAYBACK_STOPPED if the instance is invalid. +* Studio API - Studio::Bank::getLoadingState, Studio::Bank::getSampleLoadingState, + and Studio::EventDescription::getSampleLoadingState will now return + the state as FMOD_STUDIO_LOADING_STATE_UNLOADED if the object + is invalid. + +12/01/15 1.05.10 - Studio API patch release +---------------------------------------------------- + +Features: +* Core API - Xbox One - Added support for recording from microphones. + +Fixes: +* Core API - PS3 - Fix deadlock in streaming sounds when linking against the + SPU thread libraries. +* Core API - Windows - Fixed crash when initializing a second ASIO system. +* Core API - Fix ChannelControl::getDSPIndex not returning an error if the dsp + did not belong in the Channel or ChannelGroup +* Core API - PS3 - Fix linker error when using libfmod_sputhreads.a +* Core API - Fixed AT9 and ACP XMA incorrectly allowing FMOD_OPENMEMORY_POINT + and FMOD_CREATESAMPLE. +* Core API - Fixed reverb wetlevel from ChannelControl::setReverbProperties + being reset after a voice goes virtual then returns as real. +* Core API - Fixed removing/adding DSPs in a ChannelControl chain copying + setDelay commands incorrectly and making channels pause when + they shouldnt +* Studio API - Reinstated support for embedded loop points in source sounds, + and fixed issue with playback of timelocked sounds. + +12/12/14 1.05.09 - Studio API patch release +---------------------------------------------------- + +Features: +* Core API - Added System::registerOutput to allow the creation of + statically linked custom output modes. + +Fixes: +* Studio API - Fixed looping event cursor position from getting slightly + out of sync with scheduled position when running at 44.1kHz. +* Studio API - Fixed playlist steal-oldest polyphony returning errors + when used with extremely small durations. +* Studio API - Fixed silence after unpausing an event instance. + Introduced in 1.05.08. +* Core API - Fixed crash after setting the input format of a Return DSP + to stereo, when the mixer output format is mono. +* Core API - Windows - Fix crash calling FMOD_ASYNCREADINFO::done function + pointer when default calling convention is not cdecl. +* Core API - Fixed FMOD_SPEAKERMODE_RAW panning incorrectly during an + up or down mix. +* Core API - Fix crash when a Channel::setPosition is called on a + non-blocking stream that is going virtual. +* Core API - Fixed potential audio corruption when playing sounds with + more than 8 channels. +* Core API - Fixed emulated channels not updating their parent when + when Channel::setChannelGroup is called. +* Core API - Fixed channels having their volume reset when changing + channel group parents. +* Core API - Fixed channels not going virtual when being paused if no + other volume changes were occurring. +* Core API - Fixed FMOD_INIT_PROFILE_ENABLE enabling all DSP metering + regardless of whether FMOD_INIT_PROFILE_METER_ALL was used. +* Core API - Added volume ramp up for 3d channels coming back from virtual + to real. +* Core API - Fixed rare crash if the master channelgroup's DSP Head unit + was changed then released. +* Core API - PS3 - Fix loudness meter not functioning. +* Core API - PS3 - Re-enabled playDSP. + +Notes: +* Core API - Xbox One - Added check to ensure DSP buffer size is specified + as the default 512 samples to avoid performance + degradation of XMA decoding. +* Core API - Windows - Changed default ASIO speaker mapping to 1:1 for + outputs with more than 8 channels. + +28/11/14 1.05.08 - Studio API patch release +---------------------------------------------------- + +Features: +* Core API - Added ChannelControl::setFadePointRamp helper function + that automatically adds a volume ramp using fade points. + +Fixes: +* Studio API - Fixed pops that could occur when stopping events that have + instruments scheduled to stop already. +* Studio API - Fixed pop that could occur when playing an sound + that has an AHDSR fade in. +* Studio API - Fixed indeterminism when exporting string banks that have + multiple string entries with inconsistent case. +* Core API - Android - Improved compatibility with Java 1.6. +* Core API - iOS - Added armv7s back to the universal binary. +* Core API - Windows - Fix System::getRecordDriverInfo returning + incorrect device names. Introduced in 1.05.00. +* Core API - Fix FMOD_SPEAKERMODE_RAW creating silence if playing more than + 1 sound, introduced in 1.04.15. +* Core API - Fix CELT and Vorbis FSB being allowed with FMOD_OPENMEMORY_POINT + and FMOD_CREATESAMPLE when it should in fact + return FMOD_ERR_MEMORY_CANTPOINT + +21/11/14 1.05.07 - Studio API patch release +---------------------------------------------------- + +Important: +* Studio API - Fixed scheduling for looping nested events which are cut off + from the parent event. Previously the looping nested event + would attempt to play to end but would cut off halfway through + with a noticeable click. The nested event now cuts off + immediately with a fade out ramp. + +Features: +* Core API - Android - Added ARM64 support. + +Fixes: +* Core API - Fix ChannelGroup::setMixLevelsOutput causing corrupted audio + when the channel group has an input with a channel count greater + than the system channel count. +* Core API - Fixed ChannelControl::setMute not refreshing channel audibility. +* Core API - Windows - Fix calls to DSP::getInfo() from within a custom DSP + deadlocking the system during audio device change. +* Core API - Fixed some DSP configurations with an idle first input causing + signal to be downmixed to mono. +* Core API - Fix invalid characters being printed in log messages when open + certain types of media files. +* Studio API - Fixed Studio::Bank::getEventCount and Studio::Bank::getEventList + incorrectly enumerating nested events. +* Studio API - Fixed Studio::Bus::stopAllEvents not working when snapshots or + nested events are playing. +* Studio API - Fixed "state->mInstanceCount > 0" assert that could occur when + instruments were stopped repeated times. + +Notes: +* PS Vita - Now built with SDK 3.300. +* WiiU - Now built with SDK 2.11.13. + +13/11/14 1.05.06 - Studio API patch release +---------------------------------------------------- + +Features: +* Core API - Windows - Add 64bit VST support + +Fixes: +* Studio API - Fixed thread safety issue when accessing sound tables as + new banks with sound tables are being added. +* Studio API - Fixed duplicate streaming sounds keeping playing when unloading + the memory bank that it is streaming from. Now the stream + will stop if the memory bank is unloaded. +* Core API - Fixed sound going mono in certain DSP configurations. + Introduced 1.05.00. +* Core API - Fixed rare timing issue with fade points that caused the fader + DSP to generate invalid floats. +* Core API - Android - Fixed crashes due to insufficient stack size when + running ART instead of Dalvik. +* Core API - Windows - Fixed potential crash if using multiple FMOD::System + with ASIO output mode. This is not supported by ASIO + and is now disabled. +* Core API - Linux - Fixed PulseAudio device enumeration not placing the + default device at position 0. + +Notes: +* Xbox One - Now built with November 2014 XDK. +* Android - Now built with NDK r10c. +* iOS - Now built with SDK 8.1 (Xcode 6.1). +* Mac - Now built with SDK 10.10 (Xcode 6.1). +* PS4 - Now built with SDK 2.000.071 + +30/10/14 1.05.05 - Studio API patch release +---------------------------------------------------- + +Features: +* Core API - Added convolution reverb example. + +Fixes: +* Studio API - Fixed various errors after deleting objects via Live Update +* Studio API - Fixed possible crash using shared waveforms across multiple banks + after some of the duplicate banks have been unloaded. +* Studio API - Fixed duplicate events becoming invalidated when the first bank that + contains them is unloaded. +* Studio API - Fixed bug in load_banks example. +* Studio API - Fixed crash when calling Studio::Bus::stopAllEvents while + playing event instances that have had release called. +* Core API - Fixed memory leaks. + +22/10/14 1.05.04 - Studio API patch release +---------------------------------------------------- + +Fixes: +* Studio API - Fixed transition markers failing at the start of the timeline. +* Core API - PS3/X360/Wii-U - Fix vorbis seek getting stuck in an infinite loop. +* Core API - Fixed incorrect behaviour when changing the channel mode from 3D to 2D. +* FSBank - Fixed setting the cache directory and printing log messages. + +Notes: +* Studio API - Timeline transitions can be chained together with no delay. + +13/10/14 1.05.03 - Studio API patch release +---------------------------------------------------- + +Features: +* Studio API - Added Studio::Bus::lockChannelGroup and + Studio::Bus::unlockChannelGroup. + +Fixes: +* Studio API - Fixed event fadeout cutting off DSP effects with long tails. +* Studio API - Fixed crash when accessing events with a lifetime across + duplicate banks. Note that when unloading the initial + bank for an event, that event will be invalidated. +* Core API - Fixed for enum mismatches in C# wrapper. +* Core API - Fixed FMOD_DSP_LOWPASS click when being reused, ie stopping + then starting a new sound. +* Core API - Fixed rare hang during Sound::release for sounds created as + FMOD_NONBLOCKING. +* Core API - Fixed corrupted playback of MOD/S3M/XM/IT/MID sequenced + formats. Introduced 1.04.05 +* Core API - Fixed ChannelGroup::setReverbProperties on the master channel + group causing a stack overflow. This is now disallowed as it + creates a circular dependency. +* Core API - Mac - Replaced error condition if initializing FMOD before + activating the AudioSession with a TTY warning. +* Core API - Android - Fixed Sound::readData going forever when reading + AAC audio. +* Core API - Fix the pancallbacks member of the FMOD_DSP_STATE_SYSTEMCALLBACKS + structure passed into custom DSP callbacks being NULL. +* Core API - Fix crash in mixer if user used System::playDSP and made + the dsp inactive with DSP::setByPass or DSP::setActive + +01/10/14 1.05.02 - Studio API patch release +---------------------------------------------------- + +Fixes: +* Studio API - Fixed a bug where event sounds could have incorrectly + synchronized playback. +* Core API - Fixed compiler warning in public header. +* Studio API - Disabled embedded loop points on all sounds played by the + Studio API to fix incorrect playback of timelocked sounds. +* Studio API - Snapshot volumes are now interpolated in terms of linear gain. +* Core API - Fixed 3EQ DSP not clearing out internal state when DSP::reset is + called, potentially causing audible artifacts when reused. +* Core API - Fixed resampler inaccuracies when reading partial looping data. +* Core API - Mac - CoreAudio output mode will now allow any DSP block size + and will correctly use the desired buffer count. +* Core API - Mac - CoreAudio now correctly exposes its output AudioUnit + via the System::getOutputHandle function. +* Core API - PS3 - Fixed resampler strict aliasing bug on PPU release builds. +* Core API - PS3 - Fixed playDSP crash. +* Core API - Fixed convolution reverb input downmix +* Core API - Greatly increase speed of mixing multichannel source data. + +Notes: +* Studio API - Loudness meters saved in banks will now be bypassed to improve + performance when profiler isn't attached. +* Xbox One - Now built with September 2014 QFE 1 XDK. + +22/09/14 1.05.01 - Studio API patch release +---------------------------------------------------- + +Important: +* Fixed possible large memory blowout if certain DSP pools were exceeded. + +Features: +* Core API - Added FMOD_SYSTEM_CALLBACK_PREUPDATE and + FMOD_SYSTEM_CALLBACK_POSTUPDATE callbacks. +* Core API - iOS - Added support for multichannel output via accessory. + +Fixes: +* Studio API - Implemented Studio::Bus::stopAllEvents. +* Studio API - Fixed bus going silent when output format is stereo and system + speaker mode is 5.1. +* Studio API - Fixed Studio::System::getAdvancedSettings clearing + FMOD_STUDIO_ADVANCEDSETTINGS.cbSize and not returning + default values. +* Studio API - Fixed a bug where looping or sustaining events could + incorrectly be treated as oneshot. +* Studio API - Fixed a bug where event sounds could have incorrectly + synchronized playback. +* Core API - Fix bug with custom 3D rolloff curve points getting corrupted. +* Core API - Fixed incorrect documentation for FMOD_CHANNELCONTROL_CALLBACK. +* Core API - Fix sub-mix channel count being incorrect when playing multiple + sounds with different channel counts together. Introduced in + 1.04 +* Core API - Fix a channel DSP head's ChannelFormat not being reset if a sound + with a channel mask was played on it previously + +Notes: +* iOS - Now built with SDK 8.0 (Xcode 6.0). +* Mac - Now built with SDK 10.9 (Xcode 6.0). + +09/09/14 1.05.00 - Studio API minor release +---------------------------------------------------- + +Important: +* Studio API - Studio::MixerStrip has been replaced by Studio::Bus and Studio::VCA. + The new classes do not have a release method, as their handles + remain valid until the bank containing them is unloaded. +* Studio API - Studio::System::getEvent, Studio::System::getBus, Studio::System::getVCA, + and Studio::System::getBank now take a string path. + Functions that take an ID are now named Studio::System::getEventByID, + Studio::System::getBusByID, Studio::System::getVCAByID, and + Studio::System::getBankByID. +* Studio API - Studio::EventInstance::release no longer invalidates the + handle immediately. The handle remains valid until the event + stops and is actually destroyed. In addition, this function + now succeeds even if the event will not stop naturally. +* Studio API - Events with sounds triggered by parameters will now stop rather + than going idle when all sounds have finished and the timeline + cursor has reached the end. +* Core API - The wide string argument of System::getDriverInfo() and + System::getRecordDriverInfo() has been removed. These functions + now return UTF-8 encoded strings. +* Core API - FMOD_UNICODE flag for System::createSound() and System::createStream() + has been removed. These functions now accept UTF-8 encoded file names + to load sounds with non-ASCII characters on Windows, PS3, PS4, PS Vita, + XBox One, iOS, Android, Mac, Linux, Windows Phone, and Windows Store. +* FSBank API - FSBANK_INIT_UNICODE flag has been removed. All file name structure + members and function arguments now accept UTF-8 encoded strings. + +Features: +* Studio API - Added FMOD_STUDIO_EVENT_CALLBACK_PLUGIN_CREATED and + FMOD_STUDIO_EVENT_CALLBACK_PLUGIN_DESTROYED callback types. +* Studio API - Added Studio::Bank::getStringCount and Studio::Bank::getStringInfo. +* Core API - Added FMOD::Debug_Initialize to configure the destination and + level of debug logging when using the logging version of FMOD. + This is a more flexible replacement for the previous + FMOD::Debug_SetLevel API. +* Core API - Android - Added support for playing AAC files (requires Android 4.2). +* Core API - Android - Reduced latency for devices that support FastMixer, see + "Basic Information" section of the docs CHM for details. +* Core API - Added DSP::setWetDryMix so any effect can have generic wet/dry + signal level control. +* Core API - Added 3D ChannelGroup support. A ChannelGroup is a 'group bus' + and it can now be positioned in 3d space, affecting the mix for + buses and channels below it. 3D Cones, geometry etc all work. + Use ChannelGroup::setMode(FMOD_3D) to enable a 3D ChannelGroup. + +Fixes: +* Studio API - Fixed transitions to the end of a loop region failing to escape + the loop. +* Studio API - Fixed sends inside events occasionally having a brief period + of full volume when the event is started. +* Core API - Fix for crash when creating multiple Systems with profiling enabled. + +Notes: +* Studio API - Transition regions no longer include the end of their range. +* Studio API - FMOD_ERR_EVENT_WONT_STOP has been removed. +* Studio API - Studio::EventInstance::start now resets all DSPs inside the + event to prevent incorrect ramping. This relies on + FMOD_DSP_RESET_CALLBACK leaving public parameters unchanged. +* Studio API - Studio::System::getEvent's unimplemented mode parameter has + been removed, along with FMOD_STUDIO_LOADING_MODE. +* Studio API - FMOD_STUDIO_PLAYBACK_IDLE and FMOD_STUDIO_EVENT_CALLBACK_IDLE + have been removed. +* Studio API - Removed deprecated function Studio::EventInstance::createSubEvent. +* Core API - Changed FMOD_FILE_ASYNCCANCEL_CALLBACK to take FMOD_ASYNCREADINFO + structure rather than void *handle. +* Core API - The FMOD_DSP_RESET_CALLBACK documentation has been updated to + make it clear that it should leave public parameters unchanged. +* Core API - PS4 - Thread affinity can now be set as a mask of allowed cores. +* Core API - iOS / Mac - Reduced default block size to 512 for lower latency. +* Core API - Android - Renamed Java interface from FMODAudioDevice to simply + FMOD, i.e. org.fmod.FMOD.init(). +* Core API - Channel::setMode moved to ChannelControl::setMode so that + ChannelGroups can now also have 2D/3D mode bits set. + +09/09/14 1.04.08 - Studio API patch release +---------------------------------------------------- + +Fixes: +* Studio API - Fixed crash when a second system is created but never initialized. +* Studio API - Fixed a few ordering issues that can cause binary changes in + identical banks. +* Core API - Fix for pop due to unwanted volume ramping after calling + DSP::reset on fader DSP. This can happen when a Studio event + instance is stopped and then restarted. Caused by timing issue + with ChannelControl::setVolumeRamp. +* Core API - Fix crash if FMOD_DSP_TYPE_MIXER or DSP with no read/process + function is passed to System::playDSP. +* Core API - iOS - Fixed MP2 files being intercepted by AudioQueue causing an + internal error. +* Core API - XboxOne - Fixed network connect not resolving host names and + not honoring the requested time out. +* Core API - Fix rare crash if calling Channel::stop() which a non blocking + Channel::setPosition is happening with a stream. +* Core API - Winphone and Windows Store Apps - fixed detection of socket errors. +* Core API - If a user DSP is added after the master ChannelGroup's fader that + changes the output channel count to something other than the + software mixer's channel count, stuttering could occur. Fixed. +* Studio API - Windows - Fixed Studio API functions deadlocking when in + asynchronous mode and a sound device is removed. +* Core API - PS3 - Fixed some DSP parameter sets being ignored + (overwritten by SPU DMA) +* Core API - Fix System::playDSP not working with custom DSP effects that + use the read callback +* Core API - Added Memory.Initialize function to the C# wrapper. +* Core API - Fixed incorrect truncation of FMOD_CREATECOMPRESSEDSAMPLE + sounds created from MP3 or MP2 files (does not affect FSB). +* Core API - Fixed FMOD_ACCURATETIME for FMOD_CREATECOMPRESSEDSAMPLE + sounds created from MP3 or MP2 files (does not affect FSB). + +Notes: +* Core API - The master ChannelGroup's fader/head now is not responsible for + up or downmixing the signal. It is now done beyond the dsp tree, + internally within FMOD. The Master ChannelGroup's Fader can still + be forced to upmix if required with DSP::setChannelFormat. + +20/08/14 1.04.07 - Studio API patch release +---------------------------------------------------- + +Fixes: +* Studio API - Fixed an internal error when instantiating a snapshot that + exposes intensity as a parameter. +* Core API - PS3 - Fix audio dropout/corruption when using + FMOD_SPEAKERMODE_STEREO. Usually when sidechain is involved. +* Core API - iOS - Fixed System::recordStart returning FMOD_ERR_RECORD. +* Core API - Fixed possible click noise on end of sound if using + FMOD_CREATECOMPRESSEDSAPMLE or PCM on PS3. + +Notes: +* Xbox One - Now built with July 2014 QFE1 XDK. +* PS4 - Now built with SDK 1.750.061 + +06/08/14 1.04.06 - Studio API patch release +---------------------------------------------------- + +Features: +* Studio API - Added FMOD_STUDIO_PROGRAMMER_SOUND_PROPERTIES.subsoundIndex + to support non-blocking loading of FSB subsounds. +* Core API - Windows - FMOD now handles sound card removal + and insertion without any programmer intervention. If + System::setCallback is called with + FMOD_SYSTEM_CALLBACK_DEVICELISTCHANGED bit set, this feature + is disabled. +* Core API - Windows - System::setOutput can be called post-init now, + allowing dynamic switching between any output mode at runtime. +* Core API - iOS - Improved IMA ADPCM decoding performance especially for + arm64 variant. + +Fixes: +* Core API - Fixed bug where channels with post-fader DSP units would not play + after transitioning from virtual to real. +* Core API - Fix pops with resampler on loops. +* Core API - Fix playDSP returning FMOD_ERR_DSP_SILENCE or + FMOD_ERR_DSP_DONTPROCESS if the dsp played returned that during + query mode. +* Core API - PS3 - Fix ITEcho, SFXReverb, FFT DSP effects rarely getting + parameters reset to old values. +* Core API - Xbox One - Fixed audio corruption when playing mono streams from an + XMA FSB that has both mono and stereo subsounds. +* Core API - PS3 - Moved vorbis decode work during stream setPosition to the SPU. +* Core API - Windows - Fix System::setSoftwareFormat with differing samplerate and + speaker mode causing static. +* FSBank API - Fixed cache being incorrectly reused when replacing source files + of identical name with a different file that has an old time stamp. + +Notes: +* PS3 - Now built with SDK 460.001 + +25/07/14 1.04.05 - Studio API patch release +---------------------------------------------------- + +Fixes: +* Studio API - Fix for pop when stopping events with FMOD_STUDIO_STOP_ALLOWFADEOUT. +* Studio API - Fix incorrect scheduling when Multi Sounds contain nested + events with timeline transitions. +* Studio API - Fix for nested event modules not being cleaned up when used + in a playlist module. +* Studio API - Fix for events failing to stop when they have instruments on + parameters that have Hold enabled. +* Core API - Fix combined volume ramp and fade point ramp having an incorrect + volume. +* Core API - Fix for pop when setting zero volume with vol0virtual enabled. +* Core API - Fix for pop when scheduling fade point ramps in the past. +* Core API - Fix for pop on a return bus when all incoming sends go idle. +* Core API - Fix for faders delaying going idle for a mix when volume is set + to zero without ramping. +* Core API - Fixed FSB forwards compatibility issue causing load failures. +* Core API - XboxOne - Fixed ACP race condition when shutting down / initializing + System causing XMA channels to not play. +* Core API - XboxOne - Fixed XMA compressed sample channel leak that would + eventually result in all sounds playing emulated (silent). +* Core API - WinPhone and WSA - Fixed network connection not respecting system + timeout value. +* Core API - PS3 - Fix IMA ADPCM support for ps3 not working. +* Core API - iOS - Fixed potential duplicate symbol error on link. + +Notes: +* Xbox One - Now built with July 2014 XDK. +* iOS - Now built with SDK 7.1 (Xcode 5.1.1). + +11/07/14 1.04.04 - Studio API patch release +---------------------------------------------------- + +Fixes: +* Studio API - Fixed a bug where quantized timeline transitions could fail to + play the audio at the destination marker. +* Core API - Fix channel stealing not calling end callback in playDSP case. +* Core API - Fix rare crash if System::playDSP is called, and it steals a + channel with a sound on it, and System::update wasnt called in + between. +* Core API - Mac, iOS and Android - Improved network error reporting. + +08/07/14 1.04.03 - Studio API patch release +---------------------------------------------------- + +Features: +* Core API - Added FMOD_ADVANCEDSETTINGS.randomSeed, which specifies a seed + value that FMOD will use to initialize its internal random + number generators. + +Fixes: +* Studio API - Changed isValid() functions in C# wrapper to call through to C++. +* Studio API - Fixed Studio::System::loadBankCustom file callbacks being ignored + when System::setFileSystem is using async read functions. +* Studio API - Fixed incorrect playback when starting an event instance + immediately after creating it. +* Studio API - Fixed some snapshot types causing silence on busses if loading + files older than those created with FMOD Studio 1.04.02. +* Core API - Fixed incorrect FMOD_ASYNCREADINFO.offset value passed to + FMOD_FILE_ASYNCREAD_CALLBACK when file buffering is disabled. +* Core API - Windows - Fixed WASAPI failing to initialize on certain old drivers. +* Core API - Fix FMOD_SPEAKERMODE_RAW being broken. +* Core API - Fixed System::set3DRolloffCallback not working. +* Core API - Fixed Sound::set3DCustomRolloff not working. +* Core API - Fix Geometry API not running in its own thread like it was in FMOD Ex. +* Core API - Fixed incorrect DSP clock when re-routing a ChannelGroup + immediately after adding DSPs to it. +* Profiler - Fixed nodes appearing to overlap each other if multiple outputs were + involved. +* Core API - PS4 - Fixed unnecessary file reads when playing an AT9 stream. + +27/06/14 1.04.02 - Studio API patch release +---------------------------------------------------- + +Fixes: +* Studio API - Fixed incorrect virtualization of events that have more than + one 3D position dependent effect. +* Studio API - Studio::EventDescription::getInstanceList, + Studio::Bank::getEventList, Studio::Bank::getMixerStripList + and Studio::System::getBankList now accept a capacity of 0. +* Core API - Fixed a race condition that could lead to DSP graph changes not + being handled correctly. +* Core API - Linux - Fixed "spurious thread death event" messages appearing + when attached with GDB. +* Core API - Linux - Fixed internal PulseAudio assert if System::getNumDrivers + or System::getDriverInfo is used before System::init. +* Core API - Linux - Fixed ALSA not using correct default driver in some cases. +* Core API - Send levels set before connecting the Return DSP are now + applied immediately rather than fading in over a short time. + +19/06/14 1.04.01 - Studio API patch release +---------------------------------------------------- + +Features: +* Studio API - Added event playback states FMOD_STUDIO_PLAYBACK_STARTING + and FMOD_STUDIO_PLAYBACK_STOPPING. + FMOD_STUDIO_PLAYBACK_STARTING will be returned after + Studio::EventInstance::start until the event + actually starts. FMOD_STUDIO_PLAYBACK_STOPPING will + be returned after Studio::EventInstance::stop until + the event actually stops. +* Core API - PS4 - Added support for background music that cannot be broadcast. + +Fixes: +* Studio API - Fixed playlist module upmixing to system speakermode when playing + multiple overlapping sounds. +* Core API - Fix streams opened with FMOD_NONBLOCKING from playing at the + incorrect position if they go virtual shortly after setPosition + is called. +* Core API - Fix EOF detection in file system causing rare extra file read past + end of file. +* Core API - Fix some FMOD_CREATECOMPRESSEDSOUND based samples finishing early + if they were playing back at a low sample rate. +* Core API - Fix a bug where DSP nodes could get stuck in an inactive state + after setting pitch to 0. + +11/06/14 1.04.00 - Studio API minor release +---------------------------------------------------- + +Important: +* Added PS3 platform support. +* Added WiiU platform support using SDK 2.10.04. +* Added Linux platform support. +* Added Windows Phone 8.1 platform support. +* FMOD_HARDWARE and FMOD_SOFTWARE flags have been removed. All voices are software + mixed in FMOD Studio. + +Features: +* Studio API - Added Studio::System::getSoundInfo for accessing sound table entries +* Studio API - Added Studio::EventInstance::setProperty, + Studio::EventInstance::getProperty and + FMOD_STUDIO_EVENT_PROPERTY_CHANNELPRIORITY +* Studio API - Added doppler effect support +* Studio API - Added libfmodstudio.a import library for MinGW/Cygwin. + C API only, C++ linking not supported. +* Core API - Improved DSP mixing performance by about 30% +* Core API - Added new System callback type FMOD_SYSTEM_CALLBACK_THREADDESTROYED. +* Core API - System::attachChannelGroupToPort now has an argument to allow + signal to be passed to main mix. + +Fixes: +* Studio API - Fixed nested events never ending if they have a parameter with + non-zero seek speed. +* Studio API - Fixed AHDSR modulation on snapshot intensity +* Core API - Fixed incorrect fader interpolation when reparenting channels + with propagate clocks. +* Core API - Win - Fixed several issues with ASIO playback. +* Core API - Android - Fixed audio corruption on devices without NEON support. +* Core API - Fixed FMOD_CREATESOUNDEXINFO.length being handled incorrectly for + memory sounds. This length represents the amount of data to access + starting at the specified fileoffset. +* Core API - Fix truncated FSB causing zero length subsounds, now returns + FMOD_ERR_FILE_BAD + +Notes: +* Core API - Renamed C# wrapper SYSTEM_CALLBACKTYPE to SYSTEM_CALLBACK_TYPE + so it matches the C++ API. +* Core API - Renamed MinGW/Cygwin import library to libfmod.a +* Studio API - Deprecated C# wrapper functions Studio.Factory.System_Create + and Studio.System.init have been removed. + Use Studio.System.create and Studio.System.initialize instead. +* Studio API - Deprecated function Studio::EventInstance::getLoadingState has + been removed. + Use Studio::EventDescription::getSampleLoadingState instead. +* Studio API - FMOD_STUDIO_EVENT_CALLBACK now takes an + FMOD_STUDIO_EVENTINSTANCE* parameter. +* Xbox One - Now built with June 2014 XDK. + +29/05/14 1.03.09 - Studio API patch release +---------------------------------------------------- + +Fixes: +* Studio API - Fixed truncation error when loading sample data from bank + opened with Studio::System::loadBankMemory. +* Studio API - Fixed numerical error when blending multiple snapshots with + zero intensity. +* Studio API - Fixed incorrect pitch when an instrument has a non-zero base + pitch combined with pitch automation or modulation. +* Core API - Xbox One - Fixed potential seeking inaccuracies with XMA sounds. +* Core API - Fix occasional audio pops when starting a channel or channel group. +* Core API - Fix crash when running out of memory during channel group creation. +* Core API - Fixed the C# wrapper for Sound.setDefaults and Sound.getDefaults. + +Notes: +* Studio API - C# wrapper now takes care of setting the + FMOD_STUDIO_ADVANCEDSETTINGS.cbSize and + FMOD_STUDIO_BANK_INFO.size fields. +* Core API - C# wrapper now takes care of setting the + FMOD_ADVANCEDSETTINGS.cbSize and + FMOD_CREATESOUNDEXINFO.cbsize fields. +* PS Vita - Now built with SDK 3.150.021. + +21/05/14 1.03.08 - Studio API patch release +---------------------------------------------------- + +Features: +* Core API - Add FMOD_INIT_ASYNCREAD_FAST and FMOD_ASYNCREADINFO.done + method, to improve performance of asyncread callback + significantly. Instead of setting 'result', call 'done' + function pointer instead. +* Core API - Multiple channel groups can now be attached to the same output port. +* Core API - PS4 - Minor performance improvements in AT9 decoding using new SDK + features. + +Fixes: +* Core API - Windows Store - Fixed networking issues. +* Core API - Windows Store - Fixed System::getRecordDriverInfo() returning + incorrect number of channels. +* Core API - Fix System::setFileSystem asyncread callback not setting priority + values properly. +* Core API - Releasing a channel group attached to an auxiliary output port now + cleans up resources correctly. +* Core API - Channel groups attached to an auxiliary output port can now be + added as children of other channel groups. +* Core API - Fix DSPConnection::setMix() not being applied properly. +* Core API - PS Vita - Fixed potential crash during System::init if any output + related pre-init APIs are used, such as System::getNumDrivers. +* Core API - PS Vita - Fixed crash if an attempt is made to load AT9 FSBs as + a compressed sample, for PS Vita this is a streaming only format. +* Core API - Xbox One - Small improvement to XMA performance. +* Core API - Fixed the C# wrapper for System.playDSP. +* Core API - Fixed potential crash on ARM platforms when loading an FSB. + +Notes: +* PS4 - Now built with SDK 1.700. +* Android - Now built with NDK r9d. + +08/05/14 1.03.07 - Studio API patch release +---------------------------------------------------- + +Features: +* Studio API - Improved performance for projects with many events. +* Studio API - Improved memory usage for projects with many bus instances. +* Studio API - Added Studio::System::setCallback, Studio::System::setUserData + and Studio::System::getUserData. +* Core API - Added gapless_playback example for scheduling/setDelay usage. +* Core API - Improved performance of logging build. +* Core API - Added FMOD_SYSTEM_CALLBACK_MIDMIX callback. + +Fixes: +* Studio API - Fixed AHDSR Release not working when timelocked sounds are + stopped by a parameter condition. +* Studio API - Removed some unnecessary file seeks. +* Studio API - Fixed AHDSR Release resetting to Sustain value when instruments + with limited Max Voices are stopped repeatedly. +* Studio API - Fixed channels within paused events not going virtual. +* Studio API - Fixed AHDSR Release not working inside nested events +* Core API - Fixed downmixing to a quad speaker setup. +* Core API - Fixed fsb peak volume levels on big endian platforms. +* Core API - Fixed paused channels not going virtual. + +17/04/14 1.03.06 - Studio API patch release +---------------------------------------------------- + +Features: +* Studio API - Improved performance of automation and modulation + +Fixes: +* Studio API - Fixed crash when creating new automation via LiveUpdate +* Studio API - Fixed possible internal error being returned from + Studio::Bank::getSampleLoadingState when called on an + unloading bank. + +14/04/14 1.03.05 - Studio API patch release +---------------------------------------------------- + +Fixes: +* Core API - Added ChannelControl to the C# wrapper to match the C++ API. +* Core API - Fixed the definition of ChannelControl.setDelay and + ChannelControl.getDelay in the C# wrapper. +* Core API - Replaced broken C# wrapper System.set3DSpeakerPosition and + System.get3DSpeakerPosition functions with + System.setSpeakerPosition and System.getSpeakerPosition. +* Core API - Fixed the capitalization of DSP.setMeteringEnabled, + DSP.getMeteringEnabled and DSP.getMeteringInfo in the C# + wrapper. +* Core API - Xbox 360 - Fix hang on XMA playback +* Core API - Fix crash when running out of memory loading an ogg vorbis + file. +* Core API - Fix symbol collisions when statically linking both FMOD + and Xiph libvorbis or libtremor. + +08/04/14 1.03.04 - Studio API patch release +---------------------------------------------------- + +Features: +* Studio API - Studio::EventInstance::start now does a full restart of the + event if already playing. Restarting events will trigger the + FMOD_STUDIO_EVENT_CALLBACK_RESTARTED callback type. +* Studio API - Added Studio::MixerStrip::setMute, and Studio::MixerStrip::getMute + for muting buses. +* Studio API - Added Studio::System::getBufferUsage and + Studio::System::resetBufferUsage for querying command and handle + buffer size usage. +* Core API - System::createSound and System::createStream now faster due to + file extension check and immediate prioritization of the relevant + codec, before scanning rest of codec types. +* Core API - Paused channels now have an effective audibility of 0 and + will go virtual if FMOD_INIT_VOL0_BECOMES_VIRTUAL is enabled. + +Fixes: +* Studio API - Added Studio.System.initialize to the C# wrapper to match the C++ API + (replacing Studio.System.init, which is now deprecated). +* Studio API - Added Studio.System.create to the C# wrapper to match the C++ API + (replacing Studio.Factory.System_Create, which is now deprecated). +* Studio API - Added missing functions to the C# wrapper: + Studio.EventInstance.get3DAttributes, + Studio.EventInstance.isVirtual, + Studio.EventInstance.setUserData, + Studio.EventInstance.getUserData, + Studio.MixerStrip.getChannelGroup, + Studio.EventDescription.getUserProperty, + Studio.EventDescription.getUserPropertyCount, + Studio.EventDescription.getUserPropertyByIndex, + Studio.EventDescription.setUserData, + Studio.EventDescription.getUserData and + Studio.System.loadBankCustom. +* Core API - Fix for VBR sounds that dont use FMOD_CREATECOMPRESSEDSAMPLE + and FMOD_ACCURATETIME not looping when FMOD_LOOP_NORMAL was set. +* Core API - XboxOne - Fixed rare mixer hang when playing XMA as a compressed + sample. +* Core API - Fix crash with combination of FMOD_OPENUSER + FMOD_NONBLOCKING and + a null pointer being passed to System::createSound/createStream. + +Notes: +* Added examples to the Programmer API documentation. +* Xbox One - Now built with March 2014 QFE1 XDK. +* Studio API - In the C# wrapper, Studio.System.init is now deprecated in favour of + Studio.System.initialize. +* Studio API - In the C# wrapper, Studio.Factory.System_Create is now deprecated in + favour of Studio.System.create. +* Studio API - Studio::EventDescription::is3D now returns true if any of its nested + events are 3D. +* Core API - FMOD_CREATESOUNDEXINFO.suggestedsoundtype now tries the suggested + type first, then tries the rest of the codecs later if that fails, + rather than returning FMOD_ERR_FORMAT. +* Core API - Custom codecs. The open callback for a user created codec plugin + now does not have to seek to 0 with the file function pointer before + doing a read. + +28/03/14 1.03.03 - Studio API patch release +---------------------------------------------------- + +Fixes: +* Studio API - Fixed Studio::EventDescription::getInstanceCount and + Studio::EventDescription::getInstanceList incorrectly providing + data for all events in the bank, not just the queried event. +* Studio API - Added Studio::EventDescription::loadSampleData, + Studio::EventDescription::unloadSampleData and + Studio::EventDescription::getSampleLoadingState to C# wrapper. + +26/03/14 1.03.02 - Studio API patch release +---------------------------------------------------- + +Features: +* Studio API - Added Studio::EventDescription::loadSampleData, + Studio::EventDescription::unloadSampleData and + Studio::EventDescription::getSampleLoadingState functions. +* Core API - Added FMOD_ChannelGroup_IsPlaying to C API. + +Fixes: +* Studio API - Fix for setting parameter values that could cause volume + changes without the appropriate volume ramp. +* Core API - Fix for some incorrect declarations in the C header files. +* Core API - Fixed a linker error when calling some C API functions. +* Core API - Fixed FMOD_ChannelGroup_AddGroup not returning the DSP + connection on success. +* Core API - PS4 - Fixed FMOD macros for declaring plugin functions. + +Notes: +* Studio API - Studio::EventInstance::getLoadingState is now deprecated in + favour of Studio::EventDescription::getSampleLoadingState. + +18/03/14 1.03.01 - Studio API patch release +--------------------------------------------------- + +Important: +* Core API - Blocking commands are not allowed to be called from the + non-blocking callback. Attempting to do so will log an error + and return FMOD_ERR_INVALID_THREAD. See FMOD_SOUND_NONBLOCK_CALLBACK + for more information. + +Fixes: +* Studio API - Fixed simple nested events not terminating properly when inside + multi sounds +* Core API - Fix SRS downmix crash on startup if software mixer was set to 5.1, + and the OS was set to stereo, and the system sample rate was not + 44/48/96khz +* Core API - Fix for deadlock that could occur when executing commands in the + non-blocking callback as another thread is releasing sounds. +* Core API - Fix for Channel::getPosition and ChannelControl::getDSPClock + returning errors when called on emulated channels created with + System::playDSP. +* Core API - PS4 - Fixed leak of audio output handles on shutdown. +* Core API - Fix crash in compressor when placed on a channel with a delay. + +Notes: +* PS4 - Now built with SDK 1.600.071. + +03/03/14 1.03.00 - Studio API minor release +---------------------------------------------------- + +Important: +* Added PS Vita platform support. +* Updated FMOD Studio Programmers API documentation. +* Studio API - Changed .bank file format - ALL BANKS MUST BE REBUILT +* Studio API - Studio API is now asynchronous by default, with the processing + occuring on a new Studio thread. Asynchronous behaviour can be + disabled with the FMOD_STUDIO_INIT_SYNCHRONOUS_UPDATE init flag. +* Studio API - Studio API classes are now all referenced as pointers. This + reflects a change in the handle system to make it thread-safe, + more performant and match the C and Core API interface. +* Studio API - Event and mixer strip paths now include a prefix in order to + guarantee uniqueness. See Studio::System::lookupID. +* Core API - Core API is now thread-safe by default. Thread safety can be + disabled with the FMOD_INIT_THREAD_UNSAFE init flag. +* Core API - Codecs must set waveformatversion to FMOD_CODEC_WAVEFORMAT_VERSION + in the FMOD_CODEC_OPEN_CALLBACK. +* Core API - Removed support for digital CD audio + +Features: +* Studio API - The new .bank file format provides improved support for backward + and forward compatibility. Future version updates will not + generally require banks to be rebuilt. +* Studio API - Added support for events duplicated across banks. +* Studio API - Added support for transition marker and loop region probability. +* Studio API - Added support for sounds on transition timelines. +* Studio API - Added asset enumeration functions: Studio::System::getBankCount, + Studio::System::getBankList, Studio::Bank::getEventCount, + Studio::Bank::getEventList, Studio::Bank::getMixerStripCount, + Studio::Bank::getMixerStripList. +* Studio API - Added path retrieval functions: Studio::System::lookupPath, + Studio::EventDescription::getPath, Studio::MixerStrip::getPath, + Studio::Bank::getPath. +* Studio API - Bank loading now takes an extra flags argument. It is possible + to load banks in non-blocking mode in which case the function + will return while the bank is still in the process of loading. +* Studio API - Added Studio::System::setAdvancedSettings. +* Studio API - Added Studio::System::getCPUUsage. +* Studio API - Studio repositories have improved performance and no longer depend + on the standard library map. +* Core API - The system callback now includes the error callback type which + will be invoked whenever a public FMOD function returns a result + which is not FMOD_OK. +* Core API - Optimize Sound::getNumSyncPoints when using large FSB files with + many subsounds and many syncpoints. +* Core API - Made improvements to virtual voices for DSP graphs using sends, + returns, fade points, and sounds with varying peak volumes. +* Core API - PS4 - Added recording support. +* Core API - XBox One - Added dll loading support. +* FSBank API - Added support for exporting peak volume per sound using the + FSBANK_BUILD_WRITEPEAKVOLUME flag. + +Fixes: +* Core API - Channels now take fade points into account for virtualisation +* Core API - Fixed pops when changing Echo DSP Delay parameter +* Core API - Xbox One - Removed a CPU spike when first playing a compressed + sample XMA. + +Notes: +* Studio API - Replaced Studio::System::lookupEventID and Studio::System::lookupBusID + with Studio::System::lookupID. +* Core API - The system callback now has an extra userdata argument that matches + the userdata specified in System::setUserData. +* Core API - Xbox One - APU allocations are now handled internally for developers + using memory callbacks or memory pools. + +24/02/14 1.02.13 - Studio API patch release +---------------------------------------------------- + +Fixes: +* Core API - Removed stalls when removing a DSP chain from a channel +* Core API - Fixed Channel::getPosition returning incorrect value for streams + with very short loops. +* Core API - Fixed rare bug with DSP nodes not being set active in the mixer graph. +* Core API - Fixed rare bug with DSP metering not being set. +* Core API - Fixed incorrect playback of multi-channel PCM8 data. +* Core API - PS4 - Fixed issues with calling ChannelControl::setPosition on AT9 + streams and compressed samples. +* Core API - PS4 - Fixed audio glitches when using the background music port and + the system format is not 7.1 +* Core API - PS4 - Added loading of plugins from PRX files. +* Core API - Android - Fixed crash on low quality Vorbis encoded FSBs. +* Core API - Android - Fixed one time memory leak on System::release when using + OpenSL output mode. +* Studio API - Fixed playlist instruments occasionally cutting off too early. +* Studio API - Fixed rare timing issue that caused spawning instruments to trigger + too early. + +Notes: +* Xbox One - Now built with August QFE11 XDK. +* PS4 - Now built with SDK 1.600.051. + +07/01/14 1.02.12 - Studio API patch release +---------------------------------------------------- + +Fixes: +* Core API - Fixed potential crash with net streams. +* Core API - PS4 - Fixed rare internal error in AT9 codec when channels are + reused after stopping. +* Studio API - Fixed nested events getting incorrect 3D position information + +17/12/13 1.02.11 - Studio API patch release +---------------------------------------------------- + +Features: +* Core API - Added ChannelControl::setVolumeRamp and ChannelControl::getVolumeRamp + to control whether channels automatically ramp their volume changes. +* Studio API - Added FMOD_STUDIO_EVENT_CALLBACK_IDLE callback type, fired + when an event instance enters the idle state. + +Fixes: +* Studio API - Fixed FMOD_STUDIO_EVENT_CALLBACK_STOPPED callback firing when + an event instance is already stopped. +* Studio API - Fixed Studio::EventInstance::getCueCount returning 1 even on events + with no sustain points. +* Core API - Fixed ChannelControl::setDelay rarely being ignored. + +Notes: +* Core API - PCM data will now be read the main data in a single read instead + of breaking the reads up into 16kb chunks. +* Studio API - Changed behavior of Studio::EventInstance::getCue to return + FMOD_ERR_EVENT_NOTFOUND if the event has no sustain points. + +02/12/13 1.02.10 - Studio API patch release +---------------------------------------------------- + +Important: +* Core API - Updated the C ChannelGroup functions to take 64 bit integer argument. + +Fixes: +* Core API - Fix FMOD_SPEAKERMODE_SURROUND upmixing to 5.1 or 7.1 incorrectly, + ie surround left mixing into LFE and surround right into surround + right. +* Core API - PS4 - Fix playback of background music when system software format + is not 7.1. + +26/11/13 1.02.09 - Studio API patch release +---------------------------------------------------- + +Notes: +* PS4 - Now built with SDK 1.500.111 + +19/11/13 1.02.08 - Studio API patch release +---------------------------------------------------- + +Important: +* Core API - DSP clock now uses 64 bit integers. The following functions have + been modified to accept a 64 bit integer argument: ChannelControl::getDSPClock, + ChannelControl::setDelay, ChannelControl::getDelay, ChannelControl::addFadePoint, + ChannelControl::removeFadePoints, ChannelControl::getFadePoints. + +Features: +* Studio API - Added setParameterValue and setParameterValueByIndex functions in + eventInstance to wrap finding and then setting a parameter value. + +Fixes: +* Core API - Fixed positioning of 5.1 surround speakers when soundcard is + set to other surround formats +* Core API - Fixed excessive log spam making the logging version much slower +* Core API - Xbox One - Fixed rare XMA codec hang which could also manifest as + FMOD_ERR_INTERNAL. +* Core API - PS4 - Fixed crash when assigning a channel group to the controller speaker. +* Studio API - Fixed MixerStrip release not working when the user has multiple + handles to the same strip +* Studio API - Fixed pops when playing nested events that have silent tracks +* Studio API - Fixed crash when shutting down with profiler connected. +* Studio API - Fixed unused streams being created during event preloading + +Notes: +* Core API - Turned off optimization for user created DSP effects that do not call the read + callback if no sound is coming in. read callbacks will now always fire + regardless. 'shouldiprocess' callback can be defined to optimize out no input. + +12/11/13 1.02.07 - Studio API patch release +---------------------------------------------------- + +Fixes: +* Core API - iOS - Fixed streams returning FMOD_ERR_INTERNAL on ARM64 devices. +* Core API - iOS - Fixed automatic interruption handling not working for ARM64 + devices. +* Core API - Fix possible crash on startup, if using 5.1 mixing on a + stereo output (downmixer enabled). +* Core API - Fix setMute on master channelgroup not working. +* Studio API - Fixed AHDSR modulators starting at the wrong value when + attack time is 0 +* Studio API - Fixed Multi Sounds and Scatterer Sounds not randomizing + correctly after deleting all entries + +06/11/13 1.02.06 - Studio API patch release +---------------------------------------------------- + +Features: +* Core API - iOS - Added support for ARM64 devices and x86_64 simulator. + +Fixes: +* Studio API - Fix playback issues after running for more than 12 hours +* Core API - Fixed net streaming truncating or repeatings parts of the end + of a netstream. +* Core API - Fix crash due to missing functions in kernel32.dll on Windows XP. + +29/10/13 1.02.05 - Studio API patch release +---------------------------------------------------- + +Features: +* Studio API - Improved performance of Studio::System::setListenerAttributes +* Studio API - FMOD profiler can now show Studio Bus and Event instances in + the DSP node graph. + +Fixes: +* Studio API - Fixed pan jittering on events that move with the listener + +22/10/13 1.02.04 - Studio API patch release +---------------------------------------------------- + +Features: +* Studio API - Added ability to continue loading banks when missing plugins. +* Studio API - Added FMOD_STUDIO_PARAMETER_TYPE enum to describe the type of a + parameter to FMOD_STUDIO_PARAMETER_DESCRIPTION. +* Core API - Added function to get parent sound from a subsound. +* Core API - Android - Added support for dynamic plugins. + +Fixes: +* Studio API - Trying to set an automatic parameter will return FMOD_ERR_INVALID_PARAM. +* Core API - Fix restarting a channel corrupting fader and panner positions + if effects are added. +* Core API - Fix channel restarting if 1. sound ended, 2. Channel::setVolume(0) + with FMOD_VOL0BECOMESVIRTUAL happened, 3. setVolume(>0) happened, + in between 2 system updates. +* Core API - Fixed issues on PS4 after opening an output audio port fails. +* Core API - Calling playSound on a fsb loaded with createStream will now + return FMOD_ERR_SUBSOUND. + +15/10/13 1.02.03 - Studio API patch release +---------------------------------------------------- + +Fixes: +* Core API - iOS - Fixed potential crash when stopping virtual channels. +* Studio API - Fixed click with cross-fade for nested events +* Studio API - Mac - Fixed link issues from certain API functions. + +Notes: +* Studio API - FMOD_Studio_System_Create now takes a headerVersion parameter + to match the C++ API + +07/10/13 1.02.02 - Studio API patch release +---------------------------------------------------- + +Fixes: +* Core API - Fixed rare crash when using virtual voices. +* Core API - Fixed channel fade state not being preserved when switching to virtual. +* Core API - Fixed 5.1 and 7.1 downmix to stereo being off-center. +* Core API - Mac - Fixed incorrect downmix logic causing excess channels to + be dropped. + +Notes: +* Core API - changed FMOD_DSP_LIMITER_MODE parameter to bool + +01/10/13 1.02.01 - Studio API patch release +---------------------------------------------------- + +Features: +* Core API - Improved performance of compressor on X86/x64 platforms. +* Studio API - Added support for new automatic parameters: Event Orientation, + Direction, Elevation and Listener Orientation + +Fixes: +* Core API - Fixed crash when downmixing to 16-bit output. +* Core API - Fixed floating point issue when setting very low pitch values. +* Studio API - Fixed sound glitch that could occur after crossfade. +* Studio API - Fix for assert when rescheduling with modified pitch. + +Notes: +* iOS - Now built with SDK 7.0. +* Mac - Now built with SDK 10.8. + +23/09/13 1.02.00 - Studio API minor release +---------------------------------------------------- + +Important: +* Added Android platform support. + +Features: +* Core API - Added FMOD_CREATESOUNDEXINFO.fileuserdata to hold user data + that will be passed into all file callbacks for the sound +* Core API - Added System::mixerSuspend and System::mixerResume for mobile + platforms to allow FMOD to be suspended when interrupted or + operating in the background. +* Core API - Added float parameter mappings support to plug-ins +* Core API - PS4 - Added Output Ports example +* Studio API - Reduced memory overhead for several core types. +* Studio API - Added Studio::System::loadBankMemory to support loading banks + from a memory buffer +* Studio API - Added Studio::System::loadBankCustom to support loading banks + using bank-specific custom file callbacks +* Studio API - Added support for placing multiple tempo markers on a timeline. +* Studio API - Better error reporting for instruments scheduled in the past. + +Fixes: +* Core API - Fix incorrect error codes being returned by C# wrapper. +* Core API - Fix bug in stereo-to-surround and surround-to-surround panning +* Core API - Fix System::playDSP not working +* Core API - Fix rare crash with DSPConnection::setMixMatrix. Studio API + could also be affected. +* Core API - Fix getMeteringInfo not clearing its values when pausing. +* Core API - Fix audio pops when restarting sounds due to downmixing. +* Core API - PS4 - Fix crash when disconnecting a channel group from an output + port. +* Core API - PS4 - Fix issue with audio channels not finishing correctly when + being played through a port. +* Core API - Xbox One - Fixed 'clicking' when a realtime decoded XMA sample + loops if adjusting pitch during playback. +* Studio API - Fix event priority not working +* Studio API - Fix Studio::EventInstance::start() returning incorrect result with + non-blocking sounds. +* Studio API - Fix memory leaks when loading corrupt banks +* Studio API - Fix channels leaking with nested instruments +* Studio API - Fix MixerStrip::setFaderLevel on the game side affecting volume + levels in the tool when connected via Live Update +* Studio API - Fix a potential crash when getting a string property with + Studio::EventDescription::getUserPropertyByIndex + +Notes: +* Studio API - Renamed Studio::System::loadBank to Studio::System::loadBankFile +* Studio API - Updated the API examples to use the new example project +* Core API - Changed FMOD_FILE_OPEN_CALLBACK userdata parameter from void** + to void* (it now comes from FMOD_CREATESOUNDEXINFO.fileuserdata + rather than being set by the open callback) +* Core API - iOS - Removed automatic handling of interruptions. Developers + should call the new System::mixerSuspend / + System::mixerResume API from their interruption handler. +* Core API - iOS - Removed all usage of AudioSession API, developers are + now encouraged to use the platform native APIs as there + is no possible conflict with FMOD. +* PS4 - Now built with SDK 1.020.041. + +02/09/13 1.01.15 - Studio API patch release +---------------------------------------------------- + +Features: +* Core API - Performance optimizations. +* Studio API - Performance optimizations. + +Fixes: +* Core API - Fix oscillators not changing pitch if System::playDSP was used. +* Core API - Fix crash when setting 0 or invalid pitch. +* Studio API - Fix for some allocations not propagating FMOD_ERR_MEMORY errors. +* Studio API - Fix for memory leak when failing to load a bank. + +26/08/13 1.01.14 - Studio API patch release +---------------------------------------------------- + +Fixes: +* Core API - Fix crash if adding an FMOD_DSP_TYPE_FADER dsp to a channelgroup. +* Core API - Xbox One - Internal WASAPI (mmdevapi.dll) threads will now have + their affinity set to match the FMOD feeder thread. + +Notes: +* Xbox One - Now built with August XDK. + +19/08/13 1.01.13 - Studio API patch release +---------------------------------------------------- + +Features: +* Studio API - Global mixer strips will now be automatically cleaned up when + when the events routed into them complete. + +* Studio API - Improved performance of Studio::System::Update by removing stalls + waiting on the mixer the complete. + +Fixes: +* Core API - Channel::setPitch() now returns an error if a NaN is passed in. + Fixes crashes occuring later in the mixer thread. +* Studio API - Fixed sustain points at the start of the timeline not working +* Studio API - Fixed sustain point keyoff incorrectly being ignored if the + cursor is not currently sustaining +* Studio API - Fixed sustain point keyoff incorrectly skipping sustain points + repeatedly when looping + +Notes: +* Studio API - Changed behavior of Studio::EventInstance::getCue to return + FMOD_ERR_INVALID_PARAM if the event contains no sustain points. + +12/08/13 1.01.12 - Studio API patch release +---------------------------------------------------- + +Features: +* Added FMOD SoundBank Generator tool for creating .fsb files. Both a GUI version + (fsbank.exe) and a command line version (fsbankcl.exe) are provided. + +Fixes: +* Core API - Fix FSB Vorbis seek table containing an invalid entry at the end. +* Core API - Fix cpu stall when using System::playDSP. Also if using + oscillator in studio. +* Core API - Xbox One - Fixed rare crash on System::init when using WASAPI. + +05/08/13 1.01.11 - Studio API patch release +---------------------------------------------------- + +Fixes: +* Studio API - Fixed resource leak. +* Studio API - Fixed a crash when releasing an event instance with sub events. +* Core API - Fixed FMOD_SYSTEM_CALLBACK_MEMORYALLOCATIONFAILED not being + passed to the application. +* Core API - PS4 - Fix crashes caused by out-of-memory conditions. + FMOD_ERR_MEMORY is now returned correctly. +* Core API - Xbox One - Fixed race condition that causes a hang when playing + compressed XMA samples and streams at the same time. +* Core API - Xbox One - Fixed leak of SHAPE contexts that would cause + createSound to fail if playing and releasing lots of + XMA streams. +* Core API - Xbox One & Win - Fixed surrounds and rears being swapped in 7.1. + +29/07/13 1.01.10 - Studio API patch release +---------------------------------------------------- + +Important: +* Studio API - Changed .bank file format - API is backward compatible but must + be upgraded for compatibility with Studio tool 1.01.10 or newer. + +Fixes: +* Studio API - Fixed plugin effect sounds not working in game. +* Studio API - Fixed a crash in Studio::System::update after calling + Studio::EventDescription::releaseAllInstances +* Studio API - Fixed sustain points at the start of the timeline not working +* Studio API - Fixed sustain point keyoff incorrectly being ignored if the + cursor is not currently sustaining +* Studio API - Fixed sustain point keyoff incorrectly skipping sustain points + repeatedly when looping +* Studio API - Fixed a crash when unloading a bank that contains a nested + event that is currently playing +* Studio API - Fixed Studio::System::update sometimes failing with FMOD_ERR_INTERNAL + and leaving the system in an inconsistent state +* Core API - Xbox One - Fixed FMOD_CREATECOMPRESSEDSAMPLE XMA playback issues. + +Notes: +* Studio API - Changed behavior of Studio::EventInstance::getCue to return + FMOD_ERR_INVALID_PARAM if the event contains no sustain points. + +22/07/13 1.01.09 - Studio API patch release +---------------------------------------------------- + +Important: +* Core API - Fixed rare crash in mixer. + +Features: +* Studio API - Fixed spawning sounds not playing at correct 3D position. +* Studio API - Fixed 40ms of latency getting added for each layer of event + sound nesting. +* Core API - Optimized mixer by about 30% in some configurations. + +Fixes: +* Core API - Remove FMOD_CHANNELCONTROL union, used in ChannelControl type + callbacks, as it was incorrect and using it as a union would + have lead to corruption/crash. A simple opaque + FMOD_CHANNELCONTROL type is now used for callbacks, and the + user should just cast to the relevant channel or channelgroup + type. +* Core API - Fixed fade point interpolation on channels with pitch. +* Core API - Fixed race condition when channels were reused after stopping. +* Core API - Xbox One - Fixed hang for short (2KB) XMA files. +* Core API - Xbox One - Fixed incorrect seek offset for XMA files. +* Core API - PS4 - Added support for AT9 streams with greater than 2 channels. +* Studio API - PS4 - Fixed crash when Handle derived classes went out of scope after + the dynamic lib was unloaded + +Notes: +* PS4 - Now built with SDK 1.0. + +15/07/13 1.01.08 - Studio API patch release +---------------------------------------------------- + +Features: +* Studio API - Added Studio::EventDescription::getMinimumDistance +* Studio API - Added Studio::EventDescription::isStream + +Fixes: +* Core API - Fixed crash / corruption from DSP Fader/Panner objects. +* Core API - Fixed mod/s3m/xm/mid playback. +* Studio API - Fixed Studio::EventDescription::isOneshot() incorrectly returning true + for an event that has a loop on the logic track. +* Linux - Fixed crash on playback of certain CELT streams. +* Xbox One - Fixed potential hangs with compressed XMA samples. +* Xbox One - Fixed potential silence if XMA sample rate was not one of 24K, 32K, + 44.1K or 48K. + +10/07/13 1.01.07 - Studio API patch release +---------------------------------------------------- + +Fixes: +* Core API - Fix "Sample Rate Change" tag from passing through 0 rate when + EOF was hit on certain MP3 files. +* Core API - Fix crash when using FMOD_CREATECOMPRESSEDSAMPLE introduced in + 1.01.06 +* Core API - iOS - Fixed crash when using DSP Echo. +* Core API - iOS - Fixed crash in mixer due to misaligned buffers. + +08/07/13 1.01.06 - Studio API patch release +---------------------------------------------------- + +Features: +* XboxOne - Officially added support for XMA. Please note this requires the July + XDK to avoid a hang. +* Studio API - Added Studio::ParameterInstance::getDescription +* Studio API - Added EventDescription getParameter, getParameterCount and + getParameterByIndex functions + +Fixes: +* Fix Sound userdata being overwritten when FMOD_SOUND_NONBLOCKCALLBACK was + called for a 2nd or more time. +* Core API - Fix rare crash in mixer when releasing a ChannelGroup +* Core API - Fix 3D Panner DSPs and Studio Event 3d volumes not being + considered by virtual voice system. +* Core API - Fixed compressor sounding erratic and unresponsive +* Studio API - Fixed clicks when a Studio::ParameterInstance::setValue call causes + sounds to be cut off + +Notes: +* XboxOne - Now built with July XDK. +* Core API - Changed FMOD_DSP_TYPE_PAN FMOD_DSP_PAN_STEREO_POSITION + parameter to go from -100 to 100. +* Core API - Changed FMOD_DSP_TYPE_COMPRESSOR FMOD_DSP_COMPRESSOR_ATTACK + parameter to go from 0.1 to 500ms. + +28/06/13 1.01.05 - Studio API patch release +---------------------------------------------------- + +Important: +* Core API - Changed .fsb file format - ALL BANKS MUST BE REBUILT +* Studio API - Changed .bank file format - ALL BANKS MUST BE REBUILT + +Features: +* Studio API - Added Studio::System::unloadAll function + +Fixes: +* Core API - PS4 - Improved AT9 decoding performance, fixed issue with + when a sound has loop points not aligned to frame size, + fixed seamless looping playback glitches. +* Core API - Fixed bug that was causing virtual channels to stop prematurely. +* Core API - Fixed fade points leaking when channels go virtual. + +Notes: +* Studio API - Effect data parameter buffers are now 16-byte aligned + (128-byte aligned on PS3) +* Studio API - Added automatic header version verification to + Studio::System::create + +19/06/13 1.01.04 - Studio API patch release +---------------------------------------------------- + +Fixes: +* Core API - Fix rare crash with Fader DSP unit. +* Studio API - Fixed some effects causing events to not stop correctly +* Studio API - Fixed multiple concurrent playbacks of one event sometimes + failing with FMOD_ERR_SUBSOUNDS returned from Studio::System::update + +Notes: +* Studio API - Changed Studio::EventInstance::getTimelinePosition to const +* PS4 - Now built with SDK 0.990.020. + +07/06/13 1.01.03 - Studio API patch release +---------------------------------------------------- + +Features: +* Core API - Optimized mixer when pausing or delaying nodes. Should + provide significant speed increase for Studio runtime + projects. +* Core API - Add FMOD_DSPCONNECTION_TYPE_SEND_SIDECHAIN. + +Fixes: +* Core API - Fixed silence in certain DSP configurations. +* Core API - Fixed virtual channels not stopping correctly when a parent + channelgroup stops due to an end delay +* Core API - Fixed virtual channels not cleaning up fade points correctly +* Core API - Fixed fade points being ignored when channels go from virtual + to non-virtual +* Studio API - Fixed crash when playing a multisound after unloading and + reloading it's bank. +* Studio API - Implemented Studio::Bank::loadSampleData, Studio::Bank::unloadSampleData and + Studio::Bank::getSampleLoadingState (they previously did nothing) +* Studio API - Fixed crashes and unexpected behavior with sidechains when they + are connected to multiple compressors. +* Studio API - Fixed a linker error when calling handle assignment operators +* Studio API - Fixed a crash in the game when adding a sound to an event + while connected via Live Update + +Notes: +* Core API - Specific parameter description structures like + FMOD_DSP_PARAMETER_DESC_FLOAT no longer inherit from + FMOD_DSP_PARAMETER_DESC; instead, FMOD_DSP_PARAMETER_DESC + includes a union of all the specific structures with + floatdesc, intdesc, booldesc and datadesc members. + The FMOD_DSP_INIT_PARAMDESC_xxxx macros have been updated + to reflect this. +* PS4 - Now built with SDK 0.930.060. + +31/05/13 1.01.02 - Studio API patch release +---------------------------------------------------- + +Fixes: +* Studio API - Fixed getMixerStrip not returning a valid handle when + retrieving a VCA. + +30/05/13 1.01.01 - Studio API patch release +---------------------------------------------------- + +Fixes: +* Core API - Fix rare crash in DSPFader. +* Studio API - Studio::EventInstance::getParameter and Studio::EventInstance::getCue now use + case-insensitive name comparison + +Notes: +* Studio API - Renamed Studio::EventInstance::getNumCues to Studio::EventInstance::getCueCount + +27/05/13 1.01.00 - Studio API minor release +---------------------------------------------------- + +Important: +* Studio API - Changed .bank file format - ALL BANKS MUST BE REBUILT + +Features: +* PS4 - Added support for mono and stereo AT9 FSBs. +* Core API - Optimized mixer by about 10% +* Core API - Added 'sends' which is a special type of DSPConnection that + does not try and execute the input, the output (return) just + consumes what was generated by the input (the send). See + FMOD_DSPCONNECTION_TYPE_SEND +* Core API - Added DSP::getIdle. Very useful for seeing if a signal is + still running to a DSP unit. +* Core API - Added FadePoint API - now arbitrary volume ramps can be set + anywhere on the timeline. ChannelControl::SetDelay removes + ramp in/ramp out in favour of this. See + ChannelControl::addFadePoint/removeFadePointsgetFadePoints. +* Studio API - Added Studio::EventInstance::setTimelinePosition and + Studio::EventInstance::getTimelinePosition +* Studio API - Disconnect stopped events from the DSP graph to reduce CPU usage +* Core API - removed 'sidechain' API, added FMOD_DSPCONNECTION_TYPE which is now + a parameter to DSP::addInput. FMOD_DSPCONNECTION_TYPE_STANDARD, + FMOD_DSPCONNECTION_TYPE_SIDECHAIN, and FMOD_DSPCONNECTION_TYPE_SEND + are now supported. DSPConnection::getType replaces DSPConnection::isSideChain + +Fixes: +* Core API - Fixed FSB Vorbis not working with encryption key enabled. +* Core API - Fixed virtual voices not respecting ChannelControl::setDelay +* Core API - Fixed parameter index validation when getting/setting DSP parameters. +* Core API - Fixed reverb not always idling when it should. +* Core API - Fixed bug with loop count being incorrectly set to infinite +* Core API - Optimised Echo DSP effect on x86/x64 architectures +* Core API - Fixed ChannelControl::set3DLevel, ChannelControl::set3DSpeakerSpread + and stereo 3d sounds not working +* Core API - Fixed flange effect not updating 'rate' parameter if the rate was + set before adding it to a channel or channelgroup or system object. +* Core API - PS4 - Added support for music, voice, personal device and pad speaker routing. + See System::AttachChannelGroupToPort and fmod_ps4.h +* Core API - PS4 - Added dynamic linking option. +* Studio API - Fixed stop/release behaviour of event instances containing logic markers. +* Studio API - Fixed memory corruption in Studio::System::release +* Studio API - Fixed FMOD_STUDIO_STOP_ALLOWFADEOUT cutting off delay and reverb +* PS4 - Fixed closing the FMOD::System causing platform wide networking to be shutdown + even if the system did not initialize it. + +Notes: +* XboxOne - Now built with April XDK. +* PS4 - Now built with SDK 0.930. + +09/05/13 1.00.03 - Studio API patch release +---------------------------------------------------- + +Features: +* Core API - Added memory callbacks for DSP plugins + +Fixes: +* Core API - Fixed true peak calculation in loudness meter +* Core API - Fix thread related crash in fader DSP and possibly panner DSP. +* Studio API - Fixed automatic angle parameter calculation + +12/04/13 1.00.02 - Studio API patch release +---------------------------------------------------- + +Fixes: +* Studio API - Fixed snapshots sometimes not working on some properties +* Studio API - Fixed VCAs applying fader level twice to controlled buses + +09/04/13 1.00.01 - Studio API patch release +---------------------------------------------------- + +Important: +* Studio API - Changed .bank file format - ALL BANKS MUST BE REBUILT + +Features: +* PS4 & XboxOne - Reduced CPU usage with optimized SSE and AVX functions. + +Fixes: +* Core API - Fix potential crash when stopping and starting sounds quickly + and a leak for FMOD_CREATECOMPRESSED codecs which made all + sounds go virtual. +* Studio API - Fixed a crash when connecting to the game via Live Update +* Studio API - Fixed serialization of snapshots with automation + +Notes: +* XboxOne - Now built with March XDK. + +25/03/13 1.00.00 - Studio API major release +---------------------------------------------------- + +Important: +* Studio API - Changed .bank file format - ALL BANKS MUST BE REBUILT + +Features: +* Mac - Reduced CPU usage with optimized SSE and AVX functions. +* XboxOne - Added ability to set affinity via FMOD_XboxOne_SetThreadAffinity. +* PS4 - Added ability to set affinity via FMOD_PS4_SetThreadAffinity. + +Fixes: +* Studio API - Fixed Studio::EventDescription::getLength return incorrect values +* Studio API - Fixed playback glitches when sounds are placed end-to-end on the + timeline +* Studio API - Studio::System::lookupEventID and Studio::System::lookupBusID + now ignore case +* Studio API - Fixed playback of Sound Scatterers with non-zero pitch +* Made return DSPs go idle when there is no input from sends +* Fixed sends sometimes going silent if there are multiple sends to a + single return +* Fixed rare hang in mixer when using setDelay with a pitch on the parent + +Notes: +* Studio API - Replaced Studio::System::lookupID with Studio::System::lookupEventID + and Studio::System::lookupBusID. +* FSBank API will now always encode PCM FSBs as PCM16 instead of deciding based + on the source file format. +* PS4 - Now built with SDK 0.920. + +25/02/13 0.02.04 - Studio API patch release +---------------------------------------------------- + +Fixes: +* Studio API - Studio::System::loadBank now returns FMOD_ERR_PLUGIN_MISSING instead of + FMOD_ERR_FILE_BAD when the bank uses a missing plugin + +15/02/13 0.02.03 - Studio API patch release +---------------------------------------------------- + +Features: +* Studio API - Added Studio::System::lookupID() to look up event IDs from paths + (using any string tables present in currently loaded banks). +* Studio API - Added Studio::Bank::unload() to free loaded bank data. +* Windows - Added optimisations to the 64 bit build. + +Fixes: +* Studio API - Fixed a linker error when calling Studio::EventDescription::getID +* Fixed constant FMOD_ERR_MEMORY in the TTY and hang if FMOD_ADVANCEDSETTINGS is + used with DSPBufferPoolSize being set to 0. +* Changed custom DSPs with no shouldiprocess callback to only be processed when + their inputs are active. +* Fixed high freqency noise coming from send DSP when channel counts mismatches + the return DSP. +* Fixed metering not working via LiveUpdate +* Windows - fixed bug in 5.1 mixing in 32bit builds. + +Notes: +* XboxOne - Now built with January XDK. +* PS4 - Now built with SDK 0.915. + +18/01/13 0.02.02 - Studio API patch release +---------------------------------------------------- + +Important: +* Studio API - Changed .bank file format - ALL BANKS MUST BE REBUILT +* Studio API - Changed function signature for Studio::System::initialize, added + STUDIO_FLAGS field + +Features: +* Studio API - Added FMOD_STUDIO_INIT_LIVEUPDATE flag to make Live Update optional + +Fixes: +* Studio API - Fixed an internal error on instantiating a VCA when not all of + the mixer strips it controls are loaded + +Notes: +* XboxOne - Now built with December XDK. + +11/01/13 0.02.01 - Studio API patch release +---------------------------------------------------- + +Fixes: +* Studio API - Fixed Distance and Angle parameters not being created properly + by live update +* Fixed reverb effect generating denorm floats after silence + +20/12/12 0.02.00 - Studio API minor release +---------------------------------------------------- + +Features: +* Added Xbox360 support. +* Added iOS support. +* Studio API - Added sub-event instantiation via Studio::EventInstance::createSubEvent + +23/11/12 0.01.04 - Patch release +---------------------------------------------------- + +Fixes: +* Fixed a crash when calling Studio::EventInstance::release in a callback fired from + Studio::EventInstance::stop with FMOD_STUDIO_STOP_IMMEDIATE +* Fixed a linker error when using Studio::CueInstance::trigger +* Fixed a bug in volume conflict resolver + +9/11/12 0.01.03 - Patch release +---------------------------------------------------- + +Fixes: +* Fixed a linker error when using Studio::EventInstance::setPaused + +29/10/12 0.01.02 - Patch release +---------------------------------------------------- + +Fixes: +* Fixed distortion when the distance between 3D sound and the listener is greater + than the maximum attenuation distance. +* Fixed memory leaks when playing a persistent event and triggering sounds via + parameter changes. + +16/10/12 0.01.00 - Minor release +---------------------------------------------------- + +Features: +* Implemented side chaining for FMOD Compressor + +Fixes: +* Studio API - Fixed linker error when calling Studio::EventInstance::isVirtual +* Studio API - Added log message for asset not found error + +Notes: +* Second Developer Preview release + +28/09/12 0.00.04 - Patch release +---------------------------------------------------- + +Important: +* Studio API - Changed .bank file format - ALL BANKS MUST BE REBUILT + +Features: +* Add DSP::addSideChain and FMOD_DSP_STATE::sidechainbuffer to allow a DSP unit + to support sidechaining from the output of another DSP. + +Fixes: +* Studio API - Fixed Event::getParameter() and retrieving the name of a parameter + via EventParameter::getInfo() +* Studio API - Added version checking to bank loading, the runtime will + return FMOD_ERR_FORMAT when attempting to load an old bank + +19/09/12 0.00.03 - Patch release +---------------------------------------------------- + +Fixes: +* Fix panning issue introduced in 5.00.02 +* Fix possible crackling noises from mixer optimization in 5.00.02 + +14/09/12 0.00.02 - Patch release +---------------------------------------------------- + +Important: +* Studio API - Changed .bank file format - ALL BANKS MUST BE REBUILT + +Features: +* Optimized mixer to be 20% faster in some cases. +* Studio API - Improved performance of event playback containing mono/stereo tracks + +Fixes: +* Studio API - Fixed panning different in game to tool + +27/08/12 0.00.00 - Initial release +---------------------------------------------------- + +Notes: +* First Developer Preview release + diff --git a/FMOD/plugins/fmod_haptics/inc/fmod_haptics.h b/FMOD/plugins/fmod_haptics/inc/fmod_haptics.h new file mode 100644 index 0000000..e598b25 --- /dev/null +++ b/FMOD/plugins/fmod_haptics/inc/fmod_haptics.h @@ -0,0 +1,15 @@ +#pragma once + +#include "fmod_common.h" +#include "fmod_dsp.h" + +extern "C" F_EXPORT FMOD_DSP_DESCRIPTION *F_CALL FMOD_Haptics_GetDSPDescription(); +extern "C" F_EXPORT FMOD_RESULT F_CALL FMOD_Haptics_OpenXrFocused(void *session, void *instance, void *action); + +typedef enum FMOD_HAPTICS +{ + FMOD_HAPTICS_CLIP, + FMOD_HAPTICS_FINITE_LENGTH, + FMOD_HAPTICS_INTENSITY_LEFT, + FMOD_HAPTICS_INTENSITY_RIGHT, +} FMOD_HAPTICS; diff --git a/FMOD/plugins/fmod_haptics/lib/x64/fmod_haptics.dll b/FMOD/plugins/fmod_haptics/lib/x64/fmod_haptics.dll new file mode 100644 index 0000000..b0a43e2 Binary files /dev/null and b/FMOD/plugins/fmod_haptics/lib/x64/fmod_haptics.dll differ diff --git a/FMOD/plugins/resonance_audio/inc/RoomProperties.h b/FMOD/plugins/resonance_audio/inc/RoomProperties.h new file mode 100644 index 0000000..36021bf --- /dev/null +++ b/FMOD/plugins/resonance_audio/inc/RoomProperties.h @@ -0,0 +1,107 @@ +// Copyright 2017 Google Inc. All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS-IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +#ifndef RESONANCE_AUDIO_PLATFORM_COMMON_ROOM_PROPERTIES_H_ +#define RESONANCE_AUDIO_PLATFORM_COMMON_ROOM_PROPERTIES_H_ + +namespace vraudio { + +// Room surface material names, used to set room properties. +// Note that this enum is C-compatible by design to be used across external +// C/C++ and C# implementations. +enum MaterialName { + kTransparent = 0, + kAcousticCeilingTiles, + kBrickBare, + kBrickPainted, + kConcreteBlockCoarse, + kConcreteBlockPainted, + kCurtainHeavy, + kFiberGlassInsulation, + kGlassThin, + kGlassThick, + kGrass, + kLinoleumOnConcrete, + kMarble, + kMetal, + kParquetOnConcrete, + kPlasterRough, + kPlasterSmooth, + kPlywoodPanel, + kPolishedConcreteOrTile, + kSheetrock, + kWaterOrIceSurface, + kWoodCeiling, + kWoodPanel, + kUniform, + kNumMaterialNames +}; + +// Acoustic room properties. This struct can be used to describe an acoustic +// environment with a given geometry and surface properties. +// Note that this struct is C-compatible by design to be used across external +// C/C++ and C# implementations. +struct RoomProperties { + // Constructs |RoomProperties| with the default values. + RoomProperties() + : position{0.0f, 0.0f, 0.0f}, + rotation{0.0f, 0.0f, 0.0f, 1.0f}, + dimensions{0.0f, 0.0f, 0.0f}, + material_names{MaterialName::kTransparent, MaterialName::kTransparent, + MaterialName::kTransparent, MaterialName::kTransparent, + MaterialName::kTransparent, MaterialName::kTransparent}, + reflection_scalar(1.0f), + reverb_gain(1.0f), + reverb_time(1.0f), + reverb_brightness(0.0f) {} + + // Center position of the room in world space, uses right-handed coordinate + // system. + float position[3]; + + // Rotation (quaternion) of the room in world space, uses right-handed + // coordinate system. + float rotation[4]; + + // Size of the shoebox room in world space, uses right-handed coordinate + // system. + float dimensions[3]; + + // Material name of each surface of the shoebox room in this order: + // [0] (-)ive x-axis wall (left) + // [1] (+)ive x-axis wall (right) + // [2] (-)ive y-axis wall (bottom) + // [3] (+)ive y-axis wall (top) + // [4] (-)ive z-axis wall (front) + // [5] (+)ive z-axis wall (back) + MaterialName material_names[6]; + + // User defined uniform scaling factor for all reflection coefficients. + float reflection_scalar; + + // User defined reverb tail gain multiplier. + float reverb_gain; + + // Adjusts the reverberation time across all frequency bands. RT60 values + // are multiplied by this factor. Has no effect when set to 1.0f. + float reverb_time; + + // Controls the slope of a line from the lowest to the highest RT60 values + // (increases high frequency RT60s when positive, decreases when negative). + // Has no effect when set to 0.0f. + float reverb_brightness; +}; + +} // namespace vraudio + +#endif // RESONANCE_AUDIO_PLATFORM_COMMON_ROOM_PROPERTIES_H_ diff --git a/FMOD/plugins/resonance_audio/lib/x64/resonanceaudio.dll b/FMOD/plugins/resonance_audio/lib/x64/resonanceaudio.dll new file mode 100644 index 0000000..aea7ae8 Binary files /dev/null and b/FMOD/plugins/resonance_audio/lib/x64/resonanceaudio.dll differ diff --git a/FMOD/plugins/resonance_audio/lib/x86/resonanceaudio.dll b/FMOD/plugins/resonance_audio/lib/x86/resonanceaudio.dll new file mode 100644 index 0000000..0a1e0b5 Binary files /dev/null and b/FMOD/plugins/resonance_audio/lib/x86/resonanceaudio.dll differ diff --git a/FMOD/plugins/resonance_audio/license.txt b/FMOD/plugins/resonance_audio/license.txt new file mode 100644 index 0000000..dadef8e --- /dev/null +++ b/FMOD/plugins/resonance_audio/license.txt @@ -0,0 +1,189 @@ + Copyright (c) 2016, Google Inc. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + diff --git a/FMOD/plugins/resonance_audio/readme.txt b/FMOD/plugins/resonance_audio/readme.txt new file mode 100644 index 0000000..d5807d4 --- /dev/null +++ b/FMOD/plugins/resonance_audio/readme.txt @@ -0,0 +1,7 @@ +# Resonance Audio SDK for [FMOD](https://www.fmod.com) v1.0 + +Enables high-quality spatial audio on mobile and desktop platforms. + +To get started read the online [documentation](https://resonance-audio.github.io/resonance-audio/develop/fmod/getting-started). + +Copyright (c) 2019 Google Inc. All rights reserved. \ No newline at end of file diff --git a/FMOD/uninstall.exe b/FMOD/uninstall.exe new file mode 100644 index 0000000..e6d47e7 Binary files /dev/null and b/FMOD/uninstall.exe differ diff --git a/Folder.h b/Folder.h new file mode 100644 index 0000000..dd79268 --- /dev/null +++ b/Folder.h @@ -0,0 +1,9 @@ +#ifndef FOLDER_CLASS +#define FOLDER_CLASS + +#include "Object.h" + +class Folder : public Object { +}; + +#endif \ No newline at end of file diff --git a/Gui.h b/Gui.h new file mode 100644 index 0000000..9613d1d --- /dev/null +++ b/Gui.h @@ -0,0 +1,222 @@ +#ifndef BOX_CLASS +#define BOX_CLASS + +#include +#include "common.h" +#include "VAO.h" +#include "VBO.h" +#include "QuadVertices.h" +#include "shaderClass.h" +#include "texture.h" +#include "t2d.h" +#include "font.h" +#include "RenderSystem.h" +#include "Object.h" + +class Box : public Renderable, public Object { +public: + VAO boxVAO; + VBO boxVBO; + + glm::vec3 Color = { 1.0f, 1.0f, 1.0f }; + float Opacity = 1.0f; + t2d_package t2d; + float z = 0.0f; + float rotation = 0.0f; + float rounding = 0.0f; + + Box() { + shadertype = ShaderType::BoxShader; + boxVBO.GenerateID(); + boxVAO.GenerateID(); + boxVAO.Bind(); + boxVBO.BufferData(&quadVertices, sizeof(quadVertices)); + boxVAO.LinkVBO(boxVBO, 0, 2, GL_FLOAT, 4 * sizeof(float), (void*)0); + boxVAO.LinkVBO(boxVBO, 1, 2, GL_FLOAT, 4 * sizeof(float), (void*)(2 * sizeof(float))); + } + + virtual void Render(Shader& ShaderProgram) override { + if (Opacity <= 0.0f) return; + ShaderProgram.Activate(); + t2d.Recalculate(); + ShaderProgram.Set4F("Color", { Color, Opacity }); + ShaderProgram.Set2F("normalizedCenterScale", t2d.NormalizedCenterScale); + ShaderProgram.Set2F("normalizedCenterPos", t2d.NormalizedCenterPos); + ShaderProgram.Set1F("z", z); + ShaderProgram.Set1F("rotation", rotation); + ShaderProgram.Set2F("pixelScale", t2d.pixelsize); + ShaderProgram.Set2F("pixelPos", t2d.pixelposition); + ShaderProgram.Set1F("rounding", rounding); + boxVAO.Bind(); + glDrawArrays(GL_TRIANGLES, 0, 6); + boxVAO.Unbind(); + } +}; + +class BoxButton : public Box { +public: + bool clicked = false; + + void UpdateClicked(float mousex, float mousey) { + if (mousex > t2d.pixelposition.x && mousey > t2d.pixelposition.y && + mousex < t2d.pixelposition.x + t2d.pixelsize.x && + mousey < t2d.pixelposition.y + t2d.pixelsize.y) + { + clicked = true; + std::cout << "CLICKED\n"; + } + else { + clicked = false; + } + } + + BoxButton() {} +}; + +class TextBox : public Box { +public: + Font* font = nullptr; + std::string text; + float fontsize = 1.0f; + + // textCenter: 0,0 = text top-left anchored to box top-left + // 0.5,0.5 = text centered in box + // 1,1 = text bottom-right anchored to box bottom-right + glm::vec2 textCenter = { 0.0f, 0.0f }; + + TextBox() { + shadertype = ShaderType::TextShader; + } + + virtual void Render(Shader& ShaderProgram) override { + if (!font || Opacity <= 0.0f) return; + t2d.Recalculate(); + + // Box bounds in pixels + const float boxLeft = t2d.pixelposition.x; + const float boxTop = t2d.pixelposition.y; + const float boxRight = boxLeft + t2d.pixelsize.x; + const float boxBottom = boxTop + t2d.pixelsize.y; + + // Split text into lines + std::vector lines; + std::string current; + for (char c : text) { + if (c == '\n') { lines.push_back(current); current.clear(); } + else current += c; + } + lines.push_back(current); + + // Measure line height + float lineHeight = 0.0f; + for (auto& [key, ch] : font->Characters) + lineHeight = glm::max(lineHeight, (float)ch.Size.y * fontsize); + const float lineSpacing = lineHeight * 1.2f; + const float totalBlockH = lineSpacing * (float)lines.size(); + + // Vertical start: textCenter.y controls where the block sits inside the box + // 0 = top, 0.5 = center, 1 = bottom + float blockTop = boxTop + (t2d.pixelsize.y - totalBlockH) * textCenter.y; + + glEnable(GL_BLEND); + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + + // Scissor to clip text to box bounds + glEnable(GL_SCISSOR_TEST); + glScissor( + (GLint)boxLeft, + (GLint)(window->height - boxBottom), // OpenGL scissor Y is from bottom + (GLsizei)t2d.pixelsize.x, + (GLsizei)t2d.pixelsize.y + ); + + ShaderProgram.Activate(); + ShaderProgram.Set4F("textColor", { Color, Opacity }); + ShaderProgram.Set2F("screenSize", glm::vec2(window->width, window->height)); + ShaderProgram.SetInt("text", 0); + glActiveTexture(GL_TEXTURE0); + font->vao.Bind(); + + for (int i = 0; i < (int)lines.size(); i++) { + // Measure this line's width + float lineWidth = 0.0f; + for (char c : lines[i]) + lineWidth += (float)(font->Characters[(unsigned char)c].Advance >> 6) * fontsize; + + // Horizontal start: textCenter.x controls where the line sits inside the box + float x = boxLeft + (t2d.pixelsize.x - lineWidth) * textCenter.x; + float y = blockTop + lineSpacing * (float)i; + + for (char c : lines[i]) { + TextCharacter ch = font->Characters[(unsigned char)c]; + + if (ch.Size.x == 0 || ch.Size.y == 0) { + x += (float)(ch.Advance >> 6) * fontsize; + continue; + } + + float x0 = x + ch.Bearing.x * fontsize; + float y0 = y + (ch.Size.y - ch.Bearing.y) * fontsize; + float x1 = x0 + ch.Size.x * fontsize; + float y1 = y0 - ch.Size.y * fontsize; + + float vertices[6][4] = { + { x0, y1, 0.0f, 0.0f }, + { x0, y0, 0.0f, 1.0f }, + { x1, y0, 1.0f, 1.0f }, + { x0, y1, 0.0f, 0.0f }, + { x1, y0, 1.0f, 1.0f }, + { x1, y1, 1.0f, 0.0f } + }; + + glBindTexture(GL_TEXTURE_2D, ch.TextureID); + font->vbo.Bind(); + glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(vertices), vertices); + font->vbo.Unbind(); + glDrawArrays(GL_TRIANGLES, 0, 6); + + x += (float)(ch.Advance >> 6) * fontsize; + } + } + + font->vao.Unbind(); + glBindTexture(GL_TEXTURE_2D, 0); + glDisable(GL_SCISSOR_TEST); + } +}; + +class ImageBox : public Box { +public: + Texture* tex = nullptr; + + ImageBox() { + shadertype = ShaderType::ImageBoxShader; + } + + virtual void Render(Shader& ShaderProgram) override { + if (Opacity <= 0.0f) return; + ShaderProgram.Activate(); + t2d.Recalculate(); + ShaderProgram.Set4F("Color", { Color, Opacity }); + ShaderProgram.Set2F("normalizedCenterScale", t2d.NormalizedCenterScale); + ShaderProgram.Set2F("normalizedCenterPos", t2d.NormalizedCenterPos); + ShaderProgram.Set1F("z", z); + ShaderProgram.Set1F("rotation", rotation); + ShaderProgram.Set2F("pixelScale", t2d.pixelsize); + ShaderProgram.Set2F("pixelPos", t2d.pixelposition); + ShaderProgram.Set1F("rounding", rounding); + glActiveTexture(GL_TEXTURE0); + if (tex) { + glBindTexture(GL_TEXTURE_2D, tex->ID); + ShaderProgram.SetInt("tex", 0); + } + else { + glBindTexture(GL_TEXTURE_2D, 0); + } + boxVAO.Bind(); + glDrawArrays(GL_TRIANGLES, 0, 6); + boxVAO.Unbind(); + } +}; + +#endif \ No newline at end of file diff --git a/Keyboard.h b/Keyboard.h new file mode 100644 index 0000000..3e3c373 --- /dev/null +++ b/Keyboard.h @@ -0,0 +1,138 @@ + +#ifndef KEYBOARD_CLASS +#define KEYBOARD_CLASS + +#include +#include + +class Keyboard { +public: + //EVENT CLASS + class Event { + public: + enum class Type { + Press, + Release, + Invalid + }; + + Event() : type(Type::Invalid), code(0u) {} + Event(Type typ, unsigned char cod) : type(typ), code(cod) {} + bool IsPress() const noexcept { + return type == Type::Press; + }; + bool IsRelease() const noexcept { + return type == Type::Release; + }; + bool IsValid() const noexcept { + return type != Type::Invalid; + }; + + unsigned char GetCode() const noexcept { + return code; + } + + explicit operator bool() const { + return IsValid(); + } + private: + Type type; + unsigned char code; + }; + +public: + Keyboard() = default; + ~Keyboard() = default; + Keyboard(const Keyboard&) = delete; + + bool IsKeyDown(const unsigned char key) const noexcept { + return keys[key]; + } + + bool IsKeyEmpty() const noexcept { + return keybuffer.empty(); + } + bool IsCharEmpty() const noexcept { + return charbuffer.empty(); + } + unsigned char ReadChar() noexcept { + if (charbuffer.size() > 0u) { + unsigned char e = charbuffer.front(); + charbuffer.pop(); + return e; + } + else { + return 0; + } + } + + + Event ReadKey() noexcept { + if (keybuffer.size() > 0u) { + Event e = keybuffer.front(); + keybuffer.pop(); + return e; + } + else { + return Event(); + } + } + + void EnableAutorepeat() noexcept { + AutorepeatEnabled = true; + } + void DisableAutorepeat() noexcept { + AutorepeatEnabled = false; + } + bool IsAutorepeatEnabled() const noexcept { + return AutorepeatEnabled; + } + void Char(unsigned char key) { + charbuffer.push(key); + TrimBuffer(charbuffer); + } + + void KeyDown(const unsigned char key) noexcept { + keybuffer.push(Event(Event::Type::Press, key)); + keys[key] = true; + TrimBuffer(keybuffer); + } + void KeyUp(const unsigned char key) noexcept { + keybuffer.push(Event(Event::Type::Release, key)); + keys[key] = false; + TrimBuffer(keybuffer); + } + + void ClearKeyboard() noexcept { + keys.reset(); + } + + void FlushKey() noexcept { + keybuffer = std::queue(); + } + void FlushChar() noexcept { + charbuffer = std::queue(); + } + void Flush() { + FlushKey(); + FlushChar(); + } + +private: + std::queue keybuffer; + std::queue charbuffer; + + template void TrimBuffer(std::queue& q) noexcept { + while (q.size() > bufferSize) { + q.pop(); + } + } + + bool AutorepeatEnabled = false; + static constexpr unsigned int numerodekeys = 256u; + static constexpr unsigned int bufferSize = 16u; + std::bitset keys; + +}; + +#endif // !KEYBOARD_CLASS diff --git a/Lighting.h b/Lighting.h new file mode 100644 index 0000000..d2e1089 --- /dev/null +++ b/Lighting.h @@ -0,0 +1,21 @@ +#ifndef LIGHTING_CLASS +#define LIGHTING_CLASS + +#include "t.h" +#include "tFunctions.h" + +class Lighting { +public: + t dirlighting; + + Lighting() { + dirlighting.RotateToQuaternion(glm::quat({ glm::radians(90.0f),0.0f,0.0f})); + dirlighting.TranslateTo({0.0f,0.0f,0.0f}); + } + + +private: + +}; + +#endif \ No newline at end of file diff --git a/Material.h b/Material.h new file mode 100644 index 0000000..d6cf33e --- /dev/null +++ b/Material.h @@ -0,0 +1,40 @@ +#ifndef MATERIAL_CLASS +#define MATERIAL_CLASS + +#include "shaderClass.h" + +#include +#include +#include + +class Material { + +public: + Material() = delete; + Material(glm::vec3 ambient, glm::vec3 diffuse, glm::vec3 specular, float shininess) : + ambient(ambient), diffuse(diffuse), specular(specular), shininess(shininess) + { } + void Bind(Shader& shader) { + shader.Set3F("material.ambient", ambient); + shader.Set3F("material.diffuse", diffuse); + shader.Set3F("material.specular", specular); + shader.Set1F("material.shininess", shininess); + }; + + void Unbind(Shader shader) { + shader.Set3F("material.ambient", glm::vec3(1.0f)); + shader.Set3F("material.diffuse", glm::vec3(0.0f)); + shader.Set3F("material.specular", glm::vec3(0.0f)); + shader.Set1F("material.shininess", 0.0f); + //finish unbinding + }; + glm::vec3 ambient; + glm::vec3 diffuse; + glm::vec3 specular; + float shininess; + +private: + +}; + +#endif \ No newline at end of file diff --git a/Mesh.h b/Mesh.h new file mode 100644 index 0000000..21adfd9 --- /dev/null +++ b/Mesh.h @@ -0,0 +1,577 @@ +#ifndef MESH_CLASS +#define MESH_CLASS + +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#include "common.h" +#include "Engine.h" +#include "RenderSystem.h" +#include "Object.h" +#include "VAO.h" +#include "VBO.h" +#include "EBO.h" +#include "shaderClass.h" +#include "t.h" +#include "tFunctions.h" +#include "Vertex.h" +#include "texture.h" +#include "MeshData.h" + +struct IntersectionData { + glm::vec3 intersection; + int face; +}; + +class Mesh : public Object , public Renderable, public t_package , public MeshData { + friend class Model; +protected: +public: + Texture* meshTexture = nullptr; + + VAO vao; + VBO vbo; + EBO ebo; + + Mesh() { + + }; + + Mesh(const std::vector& meshvertices, const std::vector& meshindices/*, std::vector textures*/) + { + InitializeMesh(meshvertices,meshindices); + }; + + void InitializeMesh(const std::vector& meshvertices, const std::vector& meshindices) { + vertices = meshvertices; + indices = meshindices; + this->shadertype = ShaderType::MeshShader; + GenerateRenderData(); + NormalizeVertices(); + UpdateVertices(); + } + + void GenerateRenderData() { + vbo.GenerateID(); + vao.GenerateID(); + ebo.GenerateID(); + + if (vertices.size() <= 0 or indices.size() <= 0) { + std::cout << "NO VERTICES OR INDICES DURING RENDER DATA INTIALIZATION\n"; + + } + else { + + vao.Bind(); + vbo.BufferData(&vertices[0], vertices.size() * sizeof(Vertex)); + ebo.BufferData(&indices[0], indices.size() * sizeof(GLuint)); + + vbo.Bind(); + ebo.Bind(); + + vao.LinkVBO(vbo, 0, 3, GL_FLOAT, sizeof(Vertex), (void*)0); + vao.LinkVBO(vbo, 1, 3, GL_FLOAT, sizeof(Vertex), (void*)offsetof(Vertex, Normal)); + vao.LinkVBO(vbo, 2, 2, GL_FLOAT, sizeof(Vertex), (void*)offsetof(Vertex, TexCoords)); + + vao.Unbind(); + vbo.Unbind(); + ebo.Unbind(); + } + } + + virtual ~Mesh() { + vao.Delete(); + vbo.Delete(); + ebo.Delete(); + //delete this; + } + + float GetVolume() const { + float runningtotal = 0.0f; + + for (int i = 0; i < indices.size() / 3; i++) { + runningtotal += VolumeOfTriangle(vertices[indices[i * 3]].Position, vertices[indices[i * 3 + 1]].Position, vertices[indices[i * 3 + 2]].Position); + } + + return runningtotal * t.GetScale().x * t.GetScale().y * t.GetScale().z; + } + + void Slice(glm::vec3 origin, glm::quat slicequat) { + + glm::vec3 pos = glm::conjugate(slicequat) * (t.GetTranslation() - origin); + float relativeslicepos = -pos.y; + std::vector rotatedvertices; + std::vector vstates; + + if (pos.y * pos.y <= t.ScaleMagnitude2()) { + bool posfound = false; + bool negfound = false; + for (int i = 0; i < vertices.size(); i++) { + glm::vec3 vpos = glm::conjugate(slicequat) * (vertices[i].Position * t.GetScale()); + rotatedvertices.push_back(vpos); + + if (vpos.y> relativeslicepos) { + posfound = true; + vstates.push_back(true); + } + else { + negfound = true; + vstates.push_back(false); + } + } + + if (posfound and negfound) { + std::vector posvertices; + std::vector negvertices; + std::vector posindices; + std::vector negindices; + + std::vector posnewvertices; + std::vector negnewvertices; + + glm::vec3 center; + glm::vec3 negnormal = slicequat * glm::vec3(0.0f,1.0f,0.0f); + glm::vec3 posnormal = -negnormal; + + for (int i = 0; i < indices.size()/3; i++) { + //I IS THE CURRENT TRIANGLE + + //CONVERT TO VERTICES BY MULTI 3 + whatever + + int ind1 = indices[i * 3 + 0]; + int ind2 = indices[i * 3 + 1]; + int ind3 = indices[i * 3 + 2]; + + bool vstate1 = vstates[ind1]; + bool vstate2 = vstates[ind2]; + bool vstate3 = vstates[ind3]; + + if (vstate1 and vstate2 and vstate3) { + + posvertices.push_back(vertices[ind1]); + posvertices.push_back(vertices[ind2]); + posvertices.push_back(vertices[ind3]); + + posindices.push_back(posvertices.size() -3); + posindices.push_back(posvertices.size() - 2); + posindices.push_back(posvertices.size() - 1); + } + else if (not vstate1 and not vstate2 and not vstate3) { + negvertices.push_back(vertices[ind1]); + negvertices.push_back(vertices[ind2]); + negvertices.push_back(vertices[ind3]); + + negindices.push_back(negvertices.size() - 3); + negindices.push_back(negvertices.size() - 2); + negindices.push_back(negvertices.size() - 1); + } + else { + /**/ + int niso1; + int niso2; + int iso; + Vertex v1; + Vertex v2; + + bool isopos = false; + if (vstate1 != vstate2 and vstate1 != vstate3) { + //STATE1 IS THE ISO + niso1 = ind2; + niso2 = ind3; + iso = ind1; + isopos = vstate1; + } + else if (vstate2 != vstate1 and vstate2 != vstate3) { + //STATE 2 IS THE ISO + niso1 = ind3; + niso2 = ind1; + iso = ind2; + isopos = vstate2; + } + else { + //STATE 3 IS THE ISO + niso1 = ind1; + niso2 = ind2; + iso = ind3; + isopos = vstate3; + } + + float v1factor = (rotatedvertices[niso1].y - relativeslicepos) / (rotatedvertices[niso1].y - rotatedvertices[iso].y); + float v2factor = (rotatedvertices[niso2].y - relativeslicepos) / (rotatedvertices[niso2].y - rotatedvertices[iso].y); + + glm::vec3 v1pos = glm::mix(rotatedvertices[niso1], rotatedvertices[iso], v1factor); + glm::vec3 v2pos = glm::mix(rotatedvertices[niso2], rotatedvertices[iso], v2factor); + v1.Position = (slicequat * v1pos) / t.GetScale(); + v2.Position = (slicequat * v2pos) / t.GetScale(); + v1.Normal = glm::mix(vertices[niso1].Normal, vertices[iso].Normal, v1factor); + v2.Normal = glm::mix(vertices[niso2].Normal, vertices[iso].Normal, v2factor); + v1.TexCoords = glm::mix(vertices[niso1].TexCoords, vertices[iso].TexCoords, v1factor); + v2.TexCoords = glm::mix(vertices[niso2].TexCoords, vertices[iso].TexCoords, v2factor); + + if (isopos) { + //THE ISOLATED VERTEX IS IN THE POS MESH + posvertices.push_back(v1); + posvertices.push_back(v2); + posvertices.push_back(vertices[iso]); + posnewvertices.push_back(posvertices.size() - 3); + posnewvertices.push_back(posvertices.size() - 2); + + posindices.push_back(posvertices.size() - 3); + posindices.push_back(posvertices.size() - 2); + posindices.push_back(posvertices.size() - 1); + + negvertices.push_back(vertices[niso1]); + negvertices.push_back(vertices[niso2]); + negvertices.push_back(v1); + negvertices.push_back(v2); + + negindices.push_back(negvertices.size() - 4); + negindices.push_back(negvertices.size() - 3); + negindices.push_back(negvertices.size() - 1); + + negindices.push_back(negvertices.size() - 1); + negindices.push_back(negvertices.size() - 2); + negindices.push_back(negvertices.size() - 4); + + negnewvertices.push_back(negvertices.size() - 2); + negnewvertices.push_back(negvertices.size() - 1); + } + else { + //THE ISOLATED VERTEX IS IN THE NEG MESH + negvertices.push_back(v1); + negvertices.push_back(v2); + negvertices.push_back(vertices[iso]); + + negindices.push_back(negvertices.size() - 3); + negindices.push_back(negvertices.size() - 2); + negindices.push_back(negvertices.size() - 1); + + negnewvertices.push_back(negvertices.size() - 3); + negnewvertices.push_back(negvertices.size() - 2); + + posvertices.push_back(vertices[niso1]); + posvertices.push_back(vertices[niso2]); + posvertices.push_back(v1); + posvertices.push_back(v2); + + posindices.push_back(posvertices.size() - 4); + posindices.push_back(posvertices.size() - 3); + posindices.push_back(posvertices.size() - 1); + + posindices.push_back(posvertices.size() - 1); + posindices.push_back(posvertices.size() - 2); + posindices.push_back(posvertices.size() - 4); + + posnewvertices.push_back(posvertices.size() - 2); + posnewvertices.push_back(posvertices.size() - 1); + } + } + } + + if (negnewvertices.size() >= 3) { + + std::sort(negnewvertices.begin(), negnewvertices.end(), [&negvertices](int& a, int& b) { + return negvertices[a].Position.x > negvertices[b].Position.x; + }); + + for (int i = 2; i < negnewvertices.size(); i++) + { + int index0 = negnewvertices[i]; + int index1 = negnewvertices[i - 1]; + int index2 = negnewvertices[i - 2]; + + negvertices.push_back(negvertices[index0]); + if ((i+1) % 2 == 0) { + negvertices.push_back(negvertices[index2]); + + negvertices.push_back(negvertices[index1]); + } + else { + negvertices.push_back(negvertices[index1]); + negvertices.push_back(negvertices[index2]); + } + + negindices.push_back(negvertices.size()-3); + negindices.push_back(negvertices.size() - 2); + negindices.push_back(negvertices.size() - 1); + } + } + if (posnewvertices.size() >= 3) { + + for (int i = 2; i < posnewvertices.size(); i++) + { + int index0 = posnewvertices[i]; + int index1 = posnewvertices[i - 1]; + int index2 = posnewvertices[i - 2]; + posvertices.push_back(posvertices[index0]); + if (i% 2 == 0) { + posvertices.push_back(posvertices[index2]); + posvertices.push_back(posvertices[index1]); + } + else { + posvertices.push_back(posvertices[index1]); + posvertices.push_back(posvertices[index2]); + } + + posindices.push_back(posvertices.size() - 3); + posindices.push_back(posvertices.size() - 2); + posindices.push_back(posvertices.size() - 1); + } + } + + if (posindices.size() > 0) { + Mesh* posmesh = Clone(); + posmesh->vertices = posvertices; + posmesh->indices = posindices; + posmesh->t.TranslateBy(slicequat* glm::vec3(0.0f, 0.1f, 0.0f)); + posmesh->NormalizeVertices(); + posmesh->UpdateVertices(); + posmesh->UpdateIndices(); + GetParent()->AddChild(posmesh); + } + if (negindices.size() > 0) { + Mesh* negmesh = Clone(); + negmesh->indices = negindices; + negmesh->vertices = negvertices; + negmesh->t.TranslateBy(slicequat* glm::vec3(0.0f, -0.1f, 0.0f)); + negmesh->NormalizeVertices(); + negmesh->UpdateVertices(); + negmesh->UpdateIndices(); + GetParent()->AddChild(negmesh); + } + + Delete(); + } + } + } + + virtual Mesh* Clone() override { + Mesh* tr = new Mesh(*this); + tr->GenerateRenderData(); + return tr; + }; + + void Clear() { + vertices = std::vector(); + indices = std::vector(); + } + + void SetVertices(std::vector& e) { + glBufferSubData(GL_ARRAY_BUFFER, NULL, sizeof(e), &e[0]); + + glBindBuffer(GL_ARRAY_BUFFER, vbo.ID); + glBufferData(GL_ARRAY_BUFFER, sizeof(e), &e[0], GL_DYNAMIC_DRAW); + glBindBuffer(GL_ARRAY_BUFFER, 0); + } + + void UpdateVertices() { + if (vertices.size() > 0) { + + glBufferSubData(GL_ARRAY_BUFFER, NULL, sizeof(vertices), &vertices[0]); + glBindBuffer(GL_ARRAY_BUFFER, vbo.ID); + glBufferData(GL_ARRAY_BUFFER, vertices.size() * sizeof(Vertex), &vertices[0], GL_STATIC_DRAW); + glBindBuffer(GL_ARRAY_BUFFER, 0); + } + else std::cout << "NO VERTICES IN THIS MESH!!!!\n"; + } + + void UpdateIndices() { + if (ebo.ID == 0) { + std::cout << "EBO NOT INITIALIZED\m"; + return; + } + if (indices.size() > 0) { + glBufferSubData(GL_ELEMENT_ARRAY_BUFFER, NULL, sizeof(indices), &indices[0]); + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ebo.ID); + glBufferData(GL_ELEMENT_ARRAY_BUFFER, indices.size() * sizeof(GLuint), &indices[0], GL_STATIC_DRAW); + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); + } + else std::cout << "NO INDICES IN THIS MESH!!!!\n"; + } + + void NormalizeVertices() { + if (vertices.size() == 0) { + std::cout << "TRIED TO NORMALIZED ZERO VERTICES???\n"; + } + float biggestx = -FLT_MAX; + float smallestx = FLT_MAX; + float biggesty = -FLT_MAX; + float smallesty = FLT_MAX; + float biggestz = -FLT_MAX; + float smallestz = FLT_MAX; + for (Vertex& vertex : vertices) { + biggestx = glm::max(biggestx, vertex.Position.x); + smallestx = glm::min(smallestx, vertex.Position.x); + biggesty = glm::max(biggesty, vertex.Position.y); + smallesty = glm::min(smallesty, vertex.Position.y); + biggestz = glm::max(biggestz, vertex.Position.z); + smallestz = glm::min(smallestz, vertex.Position.z); + } + + float xf = biggestx - smallestx; + float yf = biggesty - smallesty; + float zf = biggestz - smallestz; + + float midx = (biggestx + smallestx) / 2.0f; + float midy = (biggesty + smallesty) / 2.0f; + float midz = (biggestz + smallestz) / 2.0f; + t.TranslateBy(glm::vec3(midx, midy, midz) * t.GetScale()); + + t.ScaleBy(glm::vec3(xf,yf,zf)); + glm::vec3 scale = t.GetScale(); + if (scale.x == 0.0f) { + t.ScaleToX(xf); + } + if (scale.y == 0.0f) { + t.ScaleToY(yf); + } + if (scale.z == 0.0f) { + t.ScaleToZ(zf); + } + + for (Vertex& vertex : vertices) { + vertex.Position = glm::vec3( + (vertex.Position.x - midx) / xf, + (vertex.Position.y - midy) / yf, + (vertex.Position.z - midz) / zf + ); + + if (xf == 0.0f) { + vertex.Position.x = 0.0f; + } + if (yf == 0.0f) { + vertex.Position.y = 0.0f; + } + if (zf == 0.0f) { + vertex.Position.z = 0.0f; + } + } + } + + void Render(Shader& ShaderProgram) override { + glm::mat4 topass = t.GetMatrix(); + + ShaderProgram.Activate(); + glActiveTexture(GL_TEXTURE1); + if (meshTexture != nullptr) { + glBindTexture(GL_TEXTURE_2D, meshTexture->ID); + ShaderProgram.SetInt("tex", 1); + } + else glBindTexture(GL_TEXTURE_2D, 0); + + ShaderProgram.SetMat4("modl", topass); + vao.Bind(); + glDrawElements(GL_TRIANGLES, indices.size(), GL_UNSIGNED_INT, 0); + vao.Unbind(); + }; + + virtual void RenderWireframe(Shader& ShaderProgram) { + glDisable(GL_CULL_FACE); + glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); + Render(ShaderProgram); + glEnable(GL_CULL_FACE); + glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); + + }; + + void DeleteRenderData() { + vbo.Delete(); + ebo.Delete(); + vao.Delete(); + } + + virtual void Delete() override { + DeleteRenderData(); + Object::Delete(); + } +public: + //random ass functions + void DivideFace(int face, glm::vec3 centerlocalspace) { + + int v1 = indices[face * 3]; + int v2 = indices[face * 3 + 1]; + int v3 = indices[face * 3 + 2]; + + Vertex newvertex; + newvertex.Position = centerlocalspace; + newvertex.TexCoords = { 0.0f,0.0f }; + newvertex.Normal = CalculateTriangleNormal({ vertices[v1].Position ,vertices[v2].Position ,vertices[v3].Position }); + vertices.push_back(newvertex); + int nvp = vertices.size() - 1; + + indices.erase(indices.begin() + face * 3, indices.begin() + face * 3 + 3); + + + + indices.push_back(v1); + indices.push_back(v2); + indices.push_back(nvp); + + indices.push_back(v2); + indices.push_back(v3); + indices.push_back(nvp); + + indices.push_back(v3); + indices.push_back(v1); + indices.push_back(nvp); + + UpdateIndices(); + UpdateVertices(); + } + + bool RayIntersectsMeshNoInfo(const Ray& ray) + { + glm::mat4 inverse = glm::inverse(t.GetMatrix()); + glm::vec3 ray_origin = glm::vec3(inverse * glm::vec4(ray.origin, 1.0f)); + glm::vec3 ray_direction = glm::vec3(inverse * glm::vec4(ray.direction, 0.0f)); + + for (int i = 0; i < indices.size() / 3; i++) { + std::optional intersection = RayIntersectsTriangle({ ray_origin,ray_direction }, { vertices[indices[i * 3]].Position, vertices[indices[i * 3 + 1]].Position,vertices[indices[i * 3 + 2]].Position }); + if (intersection.has_value()) { + return true; + } + } + return false; + } + + std::optional> RayIntersectsMesh(const Ray& ray, Mesh* mesh) + { + //USE THIS AFTER A CHEAPER CHECK + std::vector intersections = {}; + + glm::mat4 inverse = glm::inverse(t.GetMatrix()); + glm::vec3 ray_origin = glm::vec3(inverse * glm::vec4(ray.origin, 1.0f)); + glm::vec3 ray_direction = glm::vec3(inverse * glm::vec4(ray.direction, 0.0f)); + + + std::map sorted; + + for (int i = 0; i < indices.size() / 3; i++) { + std::optional intersection = RayIntersectsTriangle({ ray_origin,ray_direction }, { vertices[indices[i * 3]].Position, vertices[indices[i * 3 + 1]].Position,vertices[indices[i * 3 + 2]].Position }); + if (intersection.has_value()) { + sorted[Magnitude2(intersection.value() - ray_origin)] = { intersection.value(),i }; + + //intersections.push_back(intersection.value()); + } + } + + if (intersections.size() > 0) return intersections; + else return {}; + } + +public: + +private: + +}; + +#endif \ No newline at end of file diff --git a/MeshData.h b/MeshData.h new file mode 100644 index 0000000..13c066b --- /dev/null +++ b/MeshData.h @@ -0,0 +1,22 @@ +#ifndef MESH_DATA_CLASS +#define MESH_DATA_CLASS + +#include + +#include + +#include "Vertex.h" + +class MeshData { +public: + std::vector vertices; + std::vector indices; +}; + +class RigMeshData { +public: + std::vector vertices; + std::vector indices; +}; + +#endif \ No newline at end of file diff --git a/Model.h b/Model.h new file mode 100644 index 0000000..0d82e1f --- /dev/null +++ b/Model.h @@ -0,0 +1,205 @@ +#ifndef MODEL_CLASS +#define MODEL_CLASS +//DEPRECATED +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "RenderSystem.h" +#include "Object.h" +#include "VAO.h" +#include "VBO.h" +#include "EBO.h" +#include "shaderClass.h" +#include "t.h" +#include "Vertex.h" +#include "Mesh.h" +#include "Physics.h" + +class Model : public Object, public Renderable, public t_package { +public: + Model(const char* path) { + LoadModel(path); + //NormalizeVertices(); + } + + std::vector ReturnMeshes() { + return meshes; + } + + float GetVolume() { + float runningtotal = 0.0f; + glm::vec3 modelscale = t.GetScale(); + for (const Mesh* mesh : meshes) { + runningtotal += mesh->GetVolume() * modelscale.x * modelscale.y * modelscale.z; + } + return runningtotal; + } + + void Render(Shader& shader) override + { + glm::mat4 matrix = t.GetMatrix(); + for (unsigned int i = 0; i < meshes.size(); i++) { + meshes[i]->Render(shader); + } + } + void RenderWireframe(Shader& shader) + { + for (unsigned int i = 0; i < meshes.size(); i++) { + meshes[i]->RenderWireframe(shader); + } + } + + ~Model() { + for (Mesh* mesh : meshes) { + mesh->~Mesh(); + } + } + + std::vector meshes; + void NormalizeVertices() { + float biggestx; + float smallestx; + float biggesty; + float smallesty; + float biggestz; + float smallestz; + bool initalized = false; + for (Mesh* mesh : meshes) { + for (Vertex& vertex : mesh->vertices) { + if (not initalized) { + biggestx = vertex.Position.x; + smallestx = vertex.Position.x; + biggesty = vertex.Position.y; + smallesty = vertex.Position.y; + biggestz = vertex.Position.z; + smallestz = vertex.Position.z; + + initalized = true; + } + else { + biggestx = std::max(biggestx, vertex.Position.x); + smallestx = std::min(smallestx, vertex.Position.x); + biggesty = std::max(biggesty, vertex.Position.y); + smallesty = std::min(smallesty, vertex.Position.y); + biggestz = std::max(biggestz, vertex.Position.z); + smallestz = std::min(smallestz, vertex.Position.z); + } + } + } + + if (not initalized) { + std::cout << "NO VERTICES"; + } + else { + t.ScaleBy(glm::vec3(biggestx-smallestx,biggesty-smallesty,biggestz-smallestz)); + float midx = (biggestx + smallestx) / 2.0f; + float midy = (biggesty + smallesty) / 2.0f; + float midz = (biggestz + smallestz) / 2.0f; + float xf = biggestx - smallestx; + float yf = biggesty - smallesty; + float zf = biggestz - smallestz; + + for (Mesh* mesh : meshes) { + for (Vertex& vertex : mesh->vertices) { + vertex.Position = glm::vec3( + (vertex.Position.x - midx)/xf, + (vertex.Position.y - midy)/yf, + (vertex.Position.z - midz)/zf + ); + } + mesh->UpdateVertices(); + } + + } + + } +private: + //IMPORT STUFF + std::string directory; + + void LoadModel(std::string path) { + Assimp::Importer import; + const aiScene* scene = import.ReadFile(path, aiProcess_Triangulate); + + if (!scene || scene->mFlags & AI_SCENE_FLAGS_INCOMPLETE || !scene->mRootNode) + { + std::cout << "ERROR::ASSIMP::" << import.GetErrorString() << '\n'; + return; + } + directory = path.substr(0, path.find_last_of('/')); + + processNode(scene->mRootNode, scene); + } + + void processNode(aiNode* node, const aiScene* scene) { + // process all the node's meshes (if any) + for (unsigned int i = 0; i < node->mNumMeshes; i++) + { + aiMesh* mesh = scene->mMeshes[node->mMeshes[i]]; + meshes.push_back(processMesh(mesh, scene)); + } + // then do the same for each of its children + for (unsigned int i = 0; i < node->mNumChildren; i++) + { + processNode(node->mChildren[i], scene); + } + }; + + Mesh* processMesh(aiMesh* mesh, const aiScene* scene) + { + std::vector vertices; + std::vector indices; + + for (unsigned int i = 0; i < mesh->mNumVertices; i++) + { + Vertex vertex; + + glm::vec3 vector; + vector.x = mesh->mVertices[i].x; + vector.y = mesh->mVertices[i].y; + vector.z = mesh->mVertices[i].z; + vertex.Position = vector; + + vector.x = mesh->mNormals[i].x; + vector.y = mesh->mNormals[i].y; + vector.z = mesh->mNormals[i].z; + vertex.Normal = vector; + + // process vertex positions, normals and texture coordinates + + if (mesh->mTextureCoords[0]) // does the mesh contain texture coordinates? + { + glm::vec2 vec; + vec.x = mesh->mTextureCoords[0][i].x; + vec.y = mesh->mTextureCoords[0][i].y; + vertex.TexCoords = vec; + } + else { + vertex.TexCoords = glm::vec2(0.0f, 0.0f); + } + + vertices.push_back(vertex); + } + // process indices + for (unsigned int i = 0; i < mesh->mNumFaces; i++) + { + aiFace face = mesh->mFaces[i]; + for (unsigned int j = 0; j < face.mNumIndices; j++) + indices.push_back(face.mIndices[j]); + } + + return new Mesh(vertices, indices); + } +}; + +#endif \ No newline at end of file diff --git a/Mouse.cpp b/Mouse.cpp new file mode 100644 index 0000000..22307c6 --- /dev/null +++ b/Mouse.cpp @@ -0,0 +1,86 @@ +#include "Mouse.h" + +void Mouse::OnMouseMove(unsigned int x, unsigned int y) noexcept +{ + lastX = X; + lastY = Y; + X = x; + Y = y; + buffer.push(Mouse::Event(Event::Type::Move, *this)); + TrimBuffer(); +} + +void Mouse::MouseEnter() noexcept +{ + IsInWindow = true; + buffer.push(Mouse::Event(Event::Type::Enter, *this)); + TrimBuffer(); +} + +void Mouse::MouseExit() noexcept +{ + IsInWindow = false; + buffer.push(Mouse::Event(Event::Type::Exit, *this)); + TrimBuffer(); +} + +void Mouse::RightDown() noexcept +{ + RightIsDown = true; + buffer.push(Mouse::Event(Event::Type::RPress, *this)); + TrimBuffer(); +} + +void Mouse::RightUp() noexcept +{ + RightIsDown = false; + buffer.push(Mouse::Event(Event::Type::RRelease, *this)); + TrimBuffer(); +} + +void Mouse::LeftDown() noexcept +{ + LeftIsDown = true; + buffer.push(Mouse::Event(Event::Type::LPress, *this)); + TrimBuffer(); +} + +void Mouse::LeftUp() noexcept +{ + LeftIsDown = false; + buffer.push(Mouse::Event(Event::Type::LRelease, *this)); + TrimBuffer(); +} + +void Mouse::WheelUp(int x, int y) noexcept { + buffer.push(Mouse::Event(Mouse::Event::Type::WheelUp, *this)); + TrimBuffer(); +} + +void Mouse::WheelDown(int x, int y) noexcept { + buffer.push(Mouse::Event(Mouse::Event::Type::WheelDown, *this)); + TrimBuffer(); +} + +void Mouse::OnWheelDelta(int x, int y, int delta) noexcept { + wheeldeltacarry += delta; + while (wheeldeltacarry >= 120) { + wheeldeltacarry -= 120; + WheelUp(x, y); + } + while (wheeldeltacarry <= -120) { + wheeldeltacarry += 120; + WheelDown(x, y); + } +} + +Mouse::Event Mouse::Read() noexcept { + if (buffer.size() > 0u) { + Mouse::Event e = buffer.front(); + buffer.pop(); + return e; + } + else { + return Mouse::Event(); + } +} \ No newline at end of file diff --git a/Mouse.h b/Mouse.h new file mode 100644 index 0000000..d24db5b --- /dev/null +++ b/Mouse.h @@ -0,0 +1,130 @@ +#ifndef MOUSE_CLASS +#define MOUSE_CLASS + +#include +#include +#include + +class Mouse { + friend class Window; +public: + //EVENT CLASS + class Event { + public: + enum class Type { + LPress, + LRelease, + RPress, + RRelease, + WheelUp, + WheelDown, + Move, + Invalid, + Enter, + Exit + }; + Event() noexcept : type(Type::Invalid), LeftIsPressed(false), RightIsDown(false), x(0), y(0) {} + Event(Type t, const Mouse& parent) noexcept : type(t), LeftIsPressed(parent.LeftIsDown), RightIsDown(parent.RightIsDown), x(parent.X), y(parent.Y) {} + bool const IsValid() const noexcept { + return type != Type::Invalid; + } + Type GetType() noexcept { + return type; + } + bool IsLeftDown() noexcept { + return LeftIsPressed; + } + + bool IsRightDown() noexcept { + return RightIsDown; + } + int GetPosX() noexcept { + return x; + } + int GetPosY() noexcept { + return y; + } + std::pair GetPos() noexcept { + return { x,y }; + } + + explicit operator bool() const { + return IsValid(); + } + private: + Type type; + int x; + int y; + bool LeftIsPressed; + bool RightIsDown; + }; + +public: + Mouse() = default; + Mouse(const Mouse&) = delete; + Mouse& operator = (const Mouse&) = delete; + + //I <3 HARDCODING + + std::pair GetPos() { + return { X,Y }; + }; + int GetX() const noexcept { + return X; + } + int GetY() const noexcept { + return Y; + } + int GetLastX() const noexcept { + return lastX; + } + int GetLastY() const noexcept { + return lastY; + } + + bool MouseIsInWindow() const noexcept { + return IsInWindow; + }; + bool IsLeftDown() const noexcept { + return LeftIsDown; + }; + bool IsRightDown() const noexcept { + return RightIsDown; + }; + + Mouse::Event Read() noexcept; +public: + //yummy + void OnMouseMove(unsigned int x, unsigned int y) noexcept; + void MouseEnter() noexcept; + void MouseExit() noexcept; + void OnWheelDelta(int x, int y, int delta) noexcept; + void WheelUp(int x, int y) noexcept; + void WheelDown(int x, int y) noexcept; + void LeftDown() noexcept; + void RightDown() noexcept; + void LeftUp() noexcept; + void RightUp() noexcept; +private: + void Flush() noexcept { + buffer = std::queue(); + }; + void TrimBuffer() noexcept { + while (buffer.size() > bufferSize) { + buffer.pop(); + } + } + + bool RightIsDown = false; + bool LeftIsDown = false; + static constexpr unsigned int bufferSize = 16u; + int X = 0; + int Y = 0; + int lastX = 0; + int lastY = 0; + int wheeldeltacarry = 0; + std::queue buffer; + bool IsInWindow = false; +}; + +#endif \ No newline at end of file diff --git a/Object.h b/Object.h new file mode 100644 index 0000000..761fb74 --- /dev/null +++ b/Object.h @@ -0,0 +1,110 @@ + +#ifndef OBJECTS_CLASS +#define OBJECTS_CLASS + +#include +#include +#include + +#include + +#include "t.h" +#include "Physics.h" + +class Object { + +public: + std::string name; + + + Object() { + + } + + ~Object() { + for (auto child : children) { + child->Delete(); + } + } + + Object(Object* parent) : parent(parent) { + + } + + std::vector GetChildren() { + return children; + } + + Object* GetFirstChildOfName(std::string name) { + for (int i = 0; i < children.size(); i++) { + if (children[i]->name == name) { + return children[i]; + } + }; + return nullptr; + } + + void RemoveFromParent() { + if (parent != nullptr) { + parent->RemoveChild(this); + } + } + + void AddChild(Object* obj) { + obj->RemoveFromParent(); + obj->parent = this; + children.push_back(obj); + } + + void RemoveChild(Object* obj) { + auto it = std::find(children.begin(), children.end(), obj); + if (it != children.end()) { + children.erase(it); + obj->parent = nullptr; + } + } + + void DeleteChild(Object* obj) { + auto it = std::find(children.begin(),children.end(),obj); + if (it != children.end()) { + children.erase(it); + obj->parent = nullptr; + obj->Delete(); + } + } + + void SetParent(Object* nparent) { + nparent->AddChild(this); + } + + Object* GetParent() { + return parent; + } + + int GetChildrenAmount() { + return children.size(); + } + + void ClearChildren() { + children = {}; + } + + virtual void Delete() { + for (auto child : children) { + child->Delete(); + } + RemoveFromParent(); + + delete this; + } + + virtual Object* Clone() { + return new Object(*this); + } + +private: + std::vector children = {}; + Object* parent = nullptr; +}; + +#endif \ No newline at end of file diff --git a/Particle.h b/Particle.h new file mode 100644 index 0000000..7d54228 --- /dev/null +++ b/Particle.h @@ -0,0 +1,201 @@ +#ifndef PARTICLE_CLASS +#define PARTICLE_CLASS + +#include +#include +#include + +#include + +#include "common.h" +#include "Engine.h" +#include "Object.h" +#include "Mesh.h" +#include "QuadVertices.h" +#include "t.h" +#include "VAO.h" +#include "VBO.h" +#include "EBO.h" +#include "shaderClass.h" +#include "Vertex.h" +#include "texture.h" +#include "Camera.h" +#include "RenderSystem.h" + +class Particle : public t_package { +public: + + Particle() { + + } + + void Render() { + + } + + void Step(float dt) { + t.RotateByEulerAnglesCumulate(angularvelocity * dt); + t.TranslateBy(linearvelocity*dt); + } + glm::vec3 linearvelocity; + glm::vec3 angularvelocity; + float lifespan; +private: +}; + +class ParticleEmitter : public Renderable, public t_package, public Object { +public: + + enum EmitDirection { + Perpendicular, + Aligned, + Outward + }; + + EmitDirection emitdirection = Outward; + //PARTICLE SETTINGS + glm::vec3 size = {1.0f,1.0f,1.0f}; + glm::vec3 emitangle = {0.0f,0.0f,0.0f}; + float lifespan = 5.0f; + float speed = 1.0f; + glm::vec3 angularvelocity = {0.0f,0.0f,0.0f}; + bool facecamera = false; + + glm::vec4 color = {1.0f,1.0f,1.0f,1.0f}; + +public: + std::vector particles; + + Texture* tex; + + Mesh* mesh; + + ParticleEmitter() { + shadertype = ParticleShader; + mesh = new Mesh(quadVertices3D, quadIndices3D); + } + + ParticleEmitter(const std::vector& meshvertices, const std::vector& meshindices) { + shadertype = ParticleShader; + mesh = new Mesh(meshvertices, meshindices); + } + + ~ParticleEmitter() { + mesh->Delete(); + } + + void Emit() { + Particle* np = new Particle(); + glm::quat rot = glm::quat(glm::vec3({ (float)rand() / (float)RAND_MAX * emitangle[0] - emitangle[0] / 2.0f,(float)rand() / (float)RAND_MAX * emitangle[1] - emitangle[1] / 2.0f,(float)rand() / RAND_MAX * emitangle[2] - emitangle[2] / 2.0f })); + np->t.TranslateTo(t.GetTranslation()); + np->linearvelocity = (t.GetFrontVector() * speed) * rot; + np->angularvelocity = angularvelocity; + np->t.ScaleTo(size); + + if (emitdirection == Perpendicular) { + np->t.RotateToQuaternion(glm::conjugate(rot) * glm::quat({ glm::radians(90.0f),0.0f,0.0f }) * t.GetRotationQuaternion()); + } + else if (emitdirection == Outward) { + np->t.RotateToQuaternion(glm::conjugate(rot) * t.GetRotationQuaternion()); + } + else { + np->t.RotateToQuaternion(t.GetRotationQuaternion()); + } + + np->lifespan = lifespan; + + particles.push_back(np); + } + + void Step(float dt) { + for (auto it = particles.begin(); it != particles.end(); ) { + Particle* p = *it; + p->lifespan -= dt; + + if (p->lifespan <= 0.0f) { + delete p; + it = particles.erase(it); + } + else { + p->Step(dt); + ++it; + } + } + } + + void Render(Shader& ShaderProgram) override { + if (particles.size() <= 0) return; + ShaderProgram.Activate(); + + mesh->vao.Bind(); + + ShaderProgram.Set4F("color",color); + + glActiveTexture(0); + + if (tex != nullptr) { + glBindTexture(GL_TEXTURE_2D, tex->ID); + ShaderProgram.SetInt("tex", 0); + } + else glBindTexture(GL_TEXTURE_2D, 0); + std::vector matrices; + + if (color.w != 1.0f) { + std::map sorted; + for (unsigned int i = 0; i < particles.size(); i++) + { + sorted[Magnitude2(engine->camera->t.GetTranslation() - particles[i]->t.GetTranslation())] = particles[i]; + } + for (std::map::reverse_iterator it = sorted.rbegin(); it != sorted.rend(); ++it) + { + if (facecamera) { + matrices.emplace_back(it->second->t.GetTranslationMatrix() * engine->camera->t.GetRotationMatrix() * it->second->t.GetScaleMatrix()); + } + else { + matrices.emplace_back(it->second->t.GetMatrix()); + } + } + } + else { + for (int i = 0; i < particles.size(); i++) + { + if (facecamera) { + matrices.emplace_back(particles[i]->t.GetTranslationMatrix() * engine->camera->t.GetRotationMatrix() * particles[i]->t.GetScaleMatrix()); + } + else { + matrices.emplace_back(particles[i]->t.GetMatrix()); + } + } + } + unsigned int buffer; + glGenBuffers(1, &buffer); + glBindBuffer(GL_ARRAY_BUFFER, buffer); + glBufferData(GL_ARRAY_BUFFER, particles.size() * sizeof(glm::mat4), &matrices[0], GL_STATIC_DRAW); + + mesh->vao.Bind(); + // vertex attributes + std::size_t vec4Size = sizeof(glm::vec4); + glEnableVertexAttribArray(3); + glVertexAttribPointer(3, 4, GL_FLOAT, GL_FALSE, 4 * vec4Size, (void*)0); + glEnableVertexAttribArray(4); + glVertexAttribPointer(4, 4, GL_FLOAT, GL_FALSE, 4 * vec4Size, (void*)(1 * vec4Size)); + glEnableVertexAttribArray(5); + glVertexAttribPointer(5, 4, GL_FLOAT, GL_FALSE, 4 * vec4Size, (void*)(2 * vec4Size)); + glEnableVertexAttribArray(6); + glVertexAttribPointer(6, 4, GL_FLOAT, GL_FALSE, 4 * vec4Size, (void*)(3 * vec4Size)); + + glVertexAttribDivisor(3, 1); + glVertexAttribDivisor(4, 1); + glVertexAttribDivisor(5, 1); + glVertexAttribDivisor(6, 1); + + glDrawElementsInstanced(GL_TRIANGLES, mesh->indices.size(), GL_UNSIGNED_INT, 0, particles.size()); + + mesh->vao.Unbind(); + } + +private: + +}; + +#endif \ No newline at end of file diff --git a/Physics.cpp b/Physics.cpp new file mode 100644 index 0000000..d9a870a --- /dev/null +++ b/Physics.cpp @@ -0,0 +1,172 @@ +#include "Physics.h" + +// ============================================================================ +// ComputeInvInertiaTensor +// Returns zero matrix for static or rotation-locked bodies. +// ============================================================================ +glm::mat3 Physics::ComputeInvInertiaTensor(const p* body) +{ + if (!body->velocity || body->lockRotation) + return glm::mat3(0.0f); + + constexpr float k = 1.0f / 12.0f; + const glm::vec3 s = body->pointer->t.GetScale(); + const glm::vec3 sq = s * s; + + glm::mat3 localInvI(0.0f); + localInvI[0][0] = 1.0f / (k * body->mass * (sq.y + sq.z)); + localInvI[1][1] = 1.0f / (k * body->mass * (sq.x + sq.z)); + localInvI[2][2] = 1.0f / (k * body->mass * (sq.x + sq.y)); + + const glm::mat3 R = glm::mat3(body->pointer->t.GetRotationMatrix()); + return R * localInvI * glm::transpose(R); +} + +// ============================================================================ +// UpdateSleep +// ============================================================================ +bool Physics::UpdateSleep(p* body, float dt) +{ + if (!body->velocity) return true; + + const float linSq = glm::dot(body->linearvelocity, body->linearvelocity); + const float angSq = glm::dot(body->angularvelocity, body->angularvelocity); + + if (linSq < PHYSICS_SLEEP_LINEAR_SQ && angSq < PHYSICS_SLEEP_ANGULAR_SQ) { + body->sleepTimer += dt; + if (body->sleepTimer >= PHYSICS_SLEEP_TIME_THRESHOLD) { + body->isSleeping = true; + body->linearvelocity = glm::vec3(0.0f); + body->angularvelocity = glm::vec3(0.0f); + return true; + } + } + else { + body->sleepTimer = 0.0f; + body->isSleeping = false; + } + return false; +} + +// ============================================================================ +// Step +// ============================================================================ +void Physics::Step(float dt) +{ + // Integrate forces ? velocities + for (p* body : objects) { + if (!body->velocity || body->isSleeping) continue; + + body->force += body->mass * gravity; + + body->linearvelocity += (body->force / body->mass) * dt; + + if (!body->lockRotation) + body->angularvelocity += (ComputeInvInertiaTensor(body) * body->torque) * dt; + + body->linearvelocity *= PHYSICS_LINEAR_DAMPING; + body->angularvelocity *= PHYSICS_ANGULAR_DAMPING; + + body->force = glm::vec3(0.0f); + body->torque = glm::vec3(0.0f); + } + + ResolveCollisions(dt); + + // Integrate velocities ? positions + for (p* body : objects) { + if (!body->velocity) continue; + if (UpdateSleep(body, dt)) continue; + + body->pointer->t.TranslateBy(body->linearvelocity * dt); + + if (!body->lockRotation) + body->pointer->t.RotateByQuaternion(glm::quat(body->angularvelocity * dt)); + } +} + +// ============================================================================ +// Resolve +// ============================================================================ +void Physics::Resolve(Collision* c) +{ + p* a = c->ObjA; + p* b = c->ObjB; + + a->WakeUp(); + b->WakeUp(); + + const glm::vec3 n = c->CN; + const glm::vec3 rA = c->POI - a->pointer->t.GetTranslation(); + const glm::vec3 rB = c->POI - b->pointer->t.GetTranslation(); + + const glm::mat3 invIA = ComputeInvInertiaTensor(a); + const glm::mat3 invIB = ComputeInvInertiaTensor(b); + + const float invMassA = a->GetInvMass(); + const float invMassB = b->GetInvMass(); + + const glm::vec3 velA = a->linearvelocity + glm::cross(a->angularvelocity, rA); + const glm::vec3 velB = b->linearvelocity + glm::cross(b->angularvelocity, rB); + const glm::vec3 relVel = velA - velB; + + const float relVelN = glm::dot(relVel, n); + if (relVelN > 0.0f) return; + + const float e = (glm::abs(relVelN) < PHYSICS_RESTITUTION_THRESHOLD) + ? 0.0f + : glm::min(a->restitution, b->restitution); + + auto angDenom = [](const glm::mat3& invI, const glm::vec3& r, const glm::vec3& d) { + return glm::dot(glm::cross(invI * glm::cross(r, d), r), d); + }; + + // ---- Normal impulse ---- + const float denomN = invMassA + invMassB + angDenom(invIA, rA, n) + angDenom(invIB, rB, n); + const float jN = -(1.0f + e) * relVelN / denomN; + + const glm::vec3 impulseN = jN * n; + if (a->velocity) { + a->linearvelocity += invMassA * impulseN; + if (!a->lockRotation) + a->angularvelocity += invIA * glm::cross(rA, impulseN); + } + if (b->velocity) { + b->linearvelocity -= invMassB * impulseN; + if (!b->lockRotation) + b->angularvelocity -= invIB * glm::cross(rB, impulseN); + } + + // ---- Friction impulse ---- + glm::vec3 tangent = relVel - relVelN * n; + const float tangLen = glm::length(tangent); + if (tangLen > 1e-6f) { + tangent /= tangLen; + + const float denomT = invMassA + invMassB + angDenom(invIA, rA, tangent) + angDenom(invIB, rB, tangent); + float jT = -glm::dot(relVel, tangent) / denomT; + + const float mu = (a->friction + b->friction) * 0.5f; + jT = glm::clamp(jT, -mu * jN, mu * jN); + + const glm::vec3 impulseT = jT * tangent; + if (a->velocity) { + a->linearvelocity += invMassA * impulseT; + if (!a->lockRotation) + a->angularvelocity += invIA * glm::cross(rA, impulseT); + } + if (b->velocity) { + b->linearvelocity -= invMassB * impulseT; + if (!b->lockRotation) + b->angularvelocity -= invIB * glm::cross(rB, impulseT); + } + } + + // ---- Baumgarte positional correction ---- + const float correction = glm::max(c->overlap - PHYSICS_BAUMGARTE_SLOP, 0.0f) + / (invMassA + invMassB) + * PHYSICS_BAUMGARTE_FACTOR; + const glm::vec3 corrVec = correction * n; + if (a->velocity) a->pointer->t.TranslateBy(invMassA * corrVec); + if (b->velocity) b->pointer->t.TranslateBy(-invMassB * corrVec); +} \ No newline at end of file diff --git a/Physics.h b/Physics.h new file mode 100644 index 0000000..f1e8995 --- /dev/null +++ b/Physics.h @@ -0,0 +1,168 @@ +#ifndef PHYSICS_CLASS +#define PHYSICS_CLASS +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "common.h" +#include "Engine.h" +#include "Camera.h" +#include "t.h" +#include "tFunctions.h" + +// ============================================================================ +// Tuneable constants +// ============================================================================ +static constexpr float PHYSICS_LINEAR_DAMPING = 0.995f; +static constexpr float PHYSICS_ANGULAR_DAMPING = 0.990f; +static constexpr float PHYSICS_BAUMGARTE_FACTOR = 0.1f; +static constexpr float PHYSICS_BAUMGARTE_SLOP = 0.02f; +static constexpr float PHYSICS_SLEEP_LINEAR_SQ = 0.01f * 0.01f; +static constexpr float PHYSICS_SLEEP_ANGULAR_SQ = 0.01f * 0.01f; +static constexpr float PHYSICS_SLEEP_TIME_THRESHOLD = 0.5f; +static constexpr float PHYSICS_RESTITUTION_THRESHOLD = 1.0f; + +// ============================================================================ +// Physics body +// ============================================================================ +class p { + friend class Physics; +public: + p() { + pointer = nullptr; + std::cout << "PHYSICS OBJECT INITIALIZED WITHOUT POINTER IN CONSTRUCTOR!!!\n"; + } + p(t_package* t) : pointer(t) {} + + void SetLinearVelocity(glm::vec3 nf) { linearvelocity = nf; } + void SetMass(float newmass) { mass = newmass; } + + void EnableCollision() { collision = true; } + void DisableCollision() { collision = false; } + void EnableVelocity() { velocity = true; } + void DisableVelocity() { velocity = false; } + + void AddForce(const glm::vec3& f) { if (velocity) { force += f; WakeUp(); } } + void AddTorque(const glm::vec3& t) { if (velocity) { torque += t; WakeUp(); } } + + float GetMass() const noexcept { return mass; } + float GetInvMass() const noexcept { return velocity ? 1.0f / mass : 0.0f; } + + void WakeUp() { isSleeping = false; sleepTimer = 0.0f; } + +public: + t_package* pointer = nullptr; + + bool collision = true; + bool velocity = true; + bool isSleeping = false; + bool lockRotation = false; + + float mass = 1.0f; + float restitution = 0.2f; + float friction = 0.5f; + + glm::vec3 linearvelocity = { 0.0f, 0.0f, 0.0f }; + glm::vec3 angularvelocity = { 0.0f, 0.0f, 0.0f }; + glm::vec3 force = { 0.0f, 0.0f, 0.0f }; + glm::vec3 torque = { 0.0f, 0.0f, 0.0f }; + + float sleepTimer = 0.0f; +}; + +// ============================================================================ +// Collision manifold +// ============================================================================ +struct Collision { + glm::vec3 POI; + glm::vec3 CN; + float overlap = 0.0f; + p* ObjA = nullptr; + p* ObjB = nullptr; + + Collision(p* a, p* b) : ObjA(a), ObjB(b) {} +}; + +// ============================================================================ +// Physics world +// ============================================================================ +class Physics { +private: + std::vector objects; + glm::vec3 gravity = glm::vec3(0.0f, -9.81f, 0.0f); + + static glm::mat3 ComputeInvInertiaTensor(const p* body); + static bool UpdateSleep(p* body, float dt); + void Resolve(Collision* c); + +public: + Physics() {} + + int GetObjectAmount() const noexcept { return (int)objects.size(); } + void AddObject(p* obj) { objects.push_back(obj); } + const std::vector& GetObjects() const { return objects; } + + p* PPointerOfObject(t_package* pointer) const { + for (p* obj : objects) + if (obj->pointer == pointer) return obj; + return nullptr; + } + + void RemoveP(p* obj) { + objects.erase(std::find(objects.begin(), objects.end(), obj)); + } + + void RemoveObject(t_package* pointer) { + for (int i = 0; i < (int)objects.size(); i++) { + if (objects[i]->pointer == pointer) { + delete objects[i]; + objects.erase(objects.begin() + i); + return; + } + } + } + + void Step(float dt); + + void SolveCollisions(std::vector& collisions) { + for (Collision& col : collisions) + Resolve(&col); + } + + void ResolveCollisions(float dt) { + std::vector collisions; + + for (p* a : objects) { + if (!a->collision) continue; + for (p* b : objects) { + if (b <= a || !b->collision) continue; + if (!a->velocity && !b->velocity) continue; + if (a->isSleeping && b->isSleeping) continue; + + if (TNearT(a->pointer->t, b->pointer->t) && + BoundingBoxInBoundingBox(a->pointer->t.GetAABB(), b->pointer->t.GetAABB())) + { + std::optional e = TInT(a->pointer->t, b->pointer->t); + if (e.has_value()) { + Collision tp(a, b); + tp.POI = e.value().POI; + tp.CN = e.value().CN; + tp.overlap = e.value().overlap; + collisions.push_back(tp); + } + } + } + } + SolveCollisions(collisions); + } +}; + +#endif \ No newline at end of file diff --git a/QuadVertices.h b/QuadVertices.h new file mode 100644 index 0000000..4ae60b6 --- /dev/null +++ b/QuadVertices.h @@ -0,0 +1,43 @@ + +#ifndef QUAD_VERTICES +#define QUAD_VERTICES + +#include +#include "Vertex.h" + +inline float quadVertices[] = { // vertex attributes for a quad that fills the entire screen in Normalized Device Coordinates. + // positions // texCoords + -1.0f, 1.0f, 0.0f, 1.0f, + -1.0f, -1.0f, 0.0f, 0.0f, + 1.0f, -1.0f, 1.0f, 0.0f, + + -1.0f, 1.0f, 0.0f, 1.0f, + 1.0f, -1.0f, 1.0f, 0.0f, + 1.0f, 1.0f, 1.0f, 1.0f +}; + +inline std::vector quadVertices3D = { // vertex attributes for a quad that fills the entire screen in Normalized Device Coordinates. + // positions //normals // texCoords + {{-1.0f, 1.0f,0.0f}, {0.0f,0.0f,1.0f},{0.0f, 1.0f}}, + {{-1.0f, -1.0f, 0.0f}, {0.0f,0.0f,1.0f},{0.0f, 0.0f}}, + {{1.0f, -1.0f, 0.0f}, {0.0f,0.0f,1.0f},{1.0f, 0.0f}}, + {{1.0f, 1.0f, 0.0f},{0.0f,0.0f,1.0f}, {1.0f, 1.0f}} +}; + +inline std::vector quadIndices3D = { + 0,1,2, + 0,2,3, +}; + +inline float quadVerticesNoTexCoords[] = { + // positions + -1.0f, 1.0f, + -1.0f, -1.0f, + 1.0f, -1.0f, + + -1.0f, 1.0f, + 1.0f, -1.0f, + 1.0f, 1.0f, +}; + +#endif \ No newline at end of file diff --git a/README.md b/README.md new file mode 100644 index 0000000..f4e5452 --- /dev/null +++ b/README.md @@ -0,0 +1,16 @@ + +EIIFWHRN proprietary anything engine +anything as in it's pretty bare and can be molded into anything + +third party stuff includes: glfw, glm, glad, stbi, freetype, assimp, + +current list of cool stuff ive implemented: +-raycasting, can detect collision between boxes and models +-volume calculations +-model importing +-collision detection between boxes using axis aligned bounding boxes and seperating axis theorem +-gui +-gui rounding +-basic box physics (very dogwater rn) +-mesh slicing (as in cutting them in half and whatnot) +-more coming soon (tm) diff --git a/RenderSystem.cpp b/RenderSystem.cpp new file mode 100644 index 0000000..66cbd63 --- /dev/null +++ b/RenderSystem.cpp @@ -0,0 +1,372 @@ +#include "Debug.h" +#include "RenderSystem.h" +#include "common.h" +#include "VBO.h" +#include "VAO.h" +#include "EBO.h" +#include "FBO.h" +#include "shaderClass.h" +#include "Object.h" +#include "Camera.h" +#include "Cubemap.h" +#include "QuadVertices.h" +#include "Lighting.h" +#include "Animator.h" + +// ============================================================================ +// Initialize +// ============================================================================ +void RenderSystem::Initialize() +{ + glEnable(GL_DEPTH_TEST); + glViewport(0, 0, window->width, window->height); + glEnable(GL_MULTISAMPLE); + glEnable(GL_BLEND); + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + glEnable(GL_CULL_FACE); + glCullFace(GL_BACK); + glFrontFace(GL_CCW); + + // Screen quad + screenfbo = new FBO(); + skyboxVAO = new VAO(); + skyboxVBO = new VBO(); + quadVAO = new VAO(); + quadVBO = new VBO(); + + skyboxVAO->GenerateID(); + skyboxVBO->GenerateID(); + skyboxVAO->Bind(); + skyboxVBO->Bind(); + glBufferData(GL_ARRAY_BUFFER, sizeof(skyboxVertices), &skyboxVertices, GL_STATIC_DRAW); + glEnableVertexAttribArray(0); + glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(float), (void*)0); + + quadVAO->GenerateID(); + quadVBO->GenerateID(); + quadVAO->Bind(); + quadVBO->Bind(); + quadVBO->BufferData(quadVertices, sizeof(quadVertices)); + quadVAO->LinkVBO(*quadVBO, 0, 2, GL_FLOAT, 4 * sizeof(float), (void*)0); + quadVAO->LinkVBO(*quadVBO, 1, 2, GL_FLOAT, 4 * sizeof(float), (void*)(2 * sizeof(float))); + + std::vector faces = { + "assets/miramar_ft.tga", "assets/miramar_bk.tga", + "assets/miramar_up.tga", "assets/miramar_dn.tga", + "assets/miramar_rt.tga", "assets/miramar_lf.tga" + }; + Cubemap* skyboxcm = new Cubemap(); + skyboxcm->FillCubemap(faces); + skybox = skyboxcm; + + // Screen framebuffer + screenfbo->Bind(); + glGenTextures(1, &textureColorbuffer); + glBindTexture(GL_TEXTURE_2D, textureColorbuffer); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, window->width, window->height, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + glBindTexture(GL_TEXTURE_2D, 0); + glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, textureColorbuffer, 0); + + glGenRenderbuffers(1, &rbo); + glBindRenderbuffer(GL_RENDERBUFFER, rbo); + glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH24_STENCIL8, window->width, window->height); + glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_RENDERBUFFER, rbo); + + if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) + std::cout << "ERROR::FRAMEBUFFER:: Framebuffer is not complete!\n"; + screenfbo->Unbind(); + + // Shadow framebuffer + shadowdepthmapfbo = new FBO(); + SHADOW_RESOLUTION = 4096; + glGenTextures(1, &depthMaptexture); + glBindTexture(GL_TEXTURE_2D, depthMaptexture); + glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT, + SHADOW_RESOLUTION, SHADOW_RESOLUTION, 0, GL_DEPTH_COMPONENT, GL_FLOAT, NULL); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER); + float borderColor[] = { 1.0f, 1.0f, 1.0f, 1.0f }; + glTexParameterfv(GL_TEXTURE_2D, GL_TEXTURE_BORDER_COLOR, borderColor); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE, GL_COMPARE_REF_TO_TEXTURE); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_FUNC, GL_LEQUAL); + + shadowdepthmapfbo->Bind(); + glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, depthMaptexture, 0); + glDrawBuffer(GL_NONE); + glReadBuffer(GL_NONE); + glBindFramebuffer(GL_FRAMEBUFFER, 0); + + lighting = new Lighting(); +} + +// ============================================================================ +// RenderTranslucent +// Collects all non-opaque 3D renderables (mesh + particle), sorts back-to-front, +// then renders each with the correct shader. Blending stays on throughout. +// ============================================================================ +void RenderSystem::RenderTranslucent(Camera& camera, const glm::mat4& lightSpaceMatrix, + const glm::vec3& camPos) +{ + // Collect translucent 3D renderables + std::vector> sorted; + for (Renderable* r : renderables) { + if (r->opaque) continue; + if (r->shadertype != Renderable::MeshShader && + r->shadertype != Renderable::ParticleShader && + r->shadertype != Renderable::RigShader) continue; + + glm::vec3 pos = r->GetWorldPosition(); + float dist = glm::length(pos - camPos); + sorted.push_back({ dist, r }); + } + + // Sort back-to-front + std::sort(sorted.begin(), sorted.end(), + [](const auto& a, const auto& b) { return a.first > b.first; }); + + glEnable(GL_BLEND); + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + glDepthMask(GL_FALSE); // write to color but not depth — prevents z-fighting between translucents + + Renderable::ShaderType lastShader = Renderable::ShaderType::MeshShader; + bool shaderSet = false; + + for (auto& [dist, r] : sorted) { + // Only re-bind shader when it changes + if (!shaderSet || r->shadertype != lastShader) { + if (r->shadertype == Renderable::MeshShader) { + PrepareMeshShader(camera); + MeshShader->SetMat4("lightSpaceMatrix", lightSpaceMatrix); + glActiveTexture(GL_TEXTURE0); + glBindTexture(GL_TEXTURE_2D, depthMaptexture); + MeshShader->Set3F("dirLight.ambient", glm::vec3(0.3f)); + MeshShader->Set3F("dirLight.diffuse", glm::vec3(0.4f)); + MeshShader->Set3F("dirLight.specular", glm::vec3(0.3f)); + MeshShader->Set3F("dirLight.direction", lighting->dirlighting.GetFrontVector()); + } + else if (r->shadertype == Renderable::ParticleShader) { + PrepareParticleShader(camera); + } + else if (r->shadertype == Renderable::RigShader) { + PrepareRigShader(camera); + RigShader->SetMat4("lightSpaceMatrix", lightSpaceMatrix); + glActiveTexture(GL_TEXTURE0); + glBindTexture(GL_TEXTURE_2D, depthMaptexture); + RigShader->Set3F("dirLight.ambient", glm::vec3(0.3f)); + RigShader->Set3F("dirLight.diffuse", glm::vec3(0.4f)); + RigShader->Set3F("dirLight.specular", glm::vec3(0.3f)); + RigShader->Set3F("dirLight.direction", lighting->dirlighting.GetFrontVector()); + } + lastShader = r->shadertype; + shaderSet = true; + } + + Shader* sh = (r->shadertype == Renderable::MeshShader) ? MeshShader + : (r->shadertype == Renderable::ParticleShader) ? ParticleShader + : RigShader; + r->Render(*sh); + } + + glDepthMask(GL_TRUE); // restore depth writing for subsequent passes +} + +// ============================================================================ +// Render +// ============================================================================ +void RenderSystem::Render(Camera& camera) +{ + lighting->dirlighting.RotateByEulerAngles({ glm::radians(0.05f), 0.0f, 0.0f }); + + const glm::mat4 proj = camera.GetProjectionMatrix(0.05f, 2000.0f); + const glm::mat4 view = camera.GetViewMatrix(); + const glm::vec3 camPos = camera.t.GetTranslation(); + + const float near_plane = 0.1f, far_plane = 100.0f; + const glm::mat4 lightSpaceMatrix = + glm::ortho(-32.0f, 32.0f, -32.0f, 32.0f, near_plane, far_plane) + * glm::lookAt(camPos - lighting->dirlighting.GetFrontVector() * 10.0f, + camPos, camera.t.GetUpVector()); + + // ---- Shadow pass ---- + glCullFace(GL_FRONT); + glEnable(GL_DEPTH_TEST); + glViewport(0, 0, SHADOW_RESOLUTION, SHADOW_RESOLUTION); + shadowdepthmapfbo->Bind(); + glClear(GL_DEPTH_BUFFER_BIT); + + MeshShadowShader->Activate(); + MeshShadowShader->SetMat4("lightSpaceMatrix", lightSpaceMatrix); + for (Renderable* r : renderables) { + if (!r->castshadow || r->shadertype != Renderable::MeshShader) continue; + r->Render(*MeshShadowShader); + } + + RigShadowShader->Activate(); + RigShadowShader->SetMat4("lightSpaceMatrix", lightSpaceMatrix); + for (Renderable* r : renderables) { + if (!r->castshadow || r->shadertype != Renderable::RigShader) continue; + r->Render(*RigShadowShader); + } + + glCullFace(GL_BACK); + + // ---- Main scene ---- + screenfbo->Bind(); + glViewport(0, 0, window->width, window->height); + glEnable(GL_DEPTH_TEST); + glClearColor(212.f / 255.f, 223.f / 255.f, 232.f / 255.f, 1.0f); + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + + // Skybox + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); + glDisable(GL_DEPTH_TEST); + SkyboxShader->Activate(); + SkyboxShader->SetMat4("proj", proj); + SkyboxShader->SetMat4("view", glm::mat4(glm::mat3(view))); + skyboxVAO->Bind(); + glActiveTexture(GL_TEXTURE0); + skybox->Bind(); + glDrawArrays(GL_TRIANGLES, 0, 36); + glBindVertexArray(0); + glEnable(GL_DEPTH_TEST); + + // ---- Opaque meshes ---- + PrepareMeshShader(camera); + MeshShader->SetMat4("lightSpaceMatrix", lightSpaceMatrix); + glActiveTexture(GL_TEXTURE0); + glBindTexture(GL_TEXTURE_2D, depthMaptexture); + MeshShader->Set3F("dirLight.ambient", glm::vec3(0.3f)); + MeshShader->Set3F("dirLight.diffuse", glm::vec3(0.4f)); + MeshShader->Set3F("dirLight.specular", glm::vec3(0.3f)); + MeshShader->Set3F("dirLight.direction", lighting->dirlighting.GetFrontVector()); + for (Renderable* r : renderables) { + if (r->shadertype == Renderable::MeshShader && r->opaque) + r->Render(*MeshShader); + } + + // ---- Opaque rigs ---- + PrepareRigShader(camera); + RigShader->SetMat4("lightSpaceMatrix", lightSpaceMatrix); + glActiveTexture(GL_TEXTURE0); + glBindTexture(GL_TEXTURE_2D, depthMaptexture); + RigShader->Set3F("dirLight.ambient", glm::vec3(0.3f)); + RigShader->Set3F("dirLight.diffuse", glm::vec3(0.4f)); + RigShader->Set3F("dirLight.specular", glm::vec3(0.3f)); + RigShader->Set3F("dirLight.direction", lighting->dirlighting.GetFrontVector()); + for (Renderable* r : renderables) { + if (r->shadertype == Renderable::RigShader && r->opaque) + r->Render(*RigShader); + } + + // ---- Translucent pass (meshes + particles + rigs, sorted back-to-front) ---- + // Disable face culling so thin translucent quads render both sides + glDisable(GL_CULL_FACE); + RenderTranslucent(camera, lightSpaceMatrix, camPos); + glEnable(GL_CULL_FACE); + + // ---- Framebuffer blit to screen ---- + screenfbo->Unbind(); + glDisable(GL_DEPTH_TEST); + glClearColor(0.0f, 0.0f, 0.0f, 0.0f); + glClear(GL_COLOR_BUFFER_BIT); + ScreenShader->Activate(); + quadVAO->Bind(); + glActiveTexture(GL_TEXTURE0); + glBindTexture(GL_TEXTURE_2D, textureColorbuffer); + glDrawArrays(GL_TRIANGLES, 0, 6); + + // ---- GUI (always on top, no depth) ---- + PrepareBoxShader(camera); + for (Renderable* r : renderables) { + if (r->shadertype == Renderable::BoxShader) + r->Render(*BoxShader); + } + + PrepareImageBoxShader(camera); + for (Renderable* r : renderables) { + if (r->shadertype == Renderable::ImageBoxShader) + r->Render(*ImageBoxShader); + } + + PrepareTextShader(camera); + for (Renderable* r : renderables) { + if (r->shadertype == Renderable::TextShader) + r->Render(*Text2DShader); + } + + glActiveTexture(GL_TEXTURE0); + glBindTexture(GL_TEXTURE_2D, 0); + glfwSwapBuffers(window->handle); +} + +// ============================================================================ +// Shader preparation helpers +// ============================================================================ +void RenderSystem::RenderRenderable(Renderable* renderable, Camera& camera) +{ + Shader* shader = (renderable->shadertype == Renderable::MeshShader) ? MeshShader + : (renderable->shadertype == Renderable::ParticleShader) ? ParticleShader + : RigShader; + shader->Activate(); + renderable->Render(*shader); +} + +void RenderSystem::PrepareMeshShader(Camera& camera) +{ + MeshShader->Activate(); + MeshShader->SetMat4("proj", camera.GetProjectionMatrix(0.05f, 2000.0f)); + MeshShader->SetMat4("view", camera.GetViewMatrix()); + MeshShader->Set3F("viewPos", camera.t.GetTranslation()); +} + +void RenderSystem::PrepareRigShader(Camera& camera) +{ + RigShader->Activate(); + RigShader->SetMat4("proj", camera.GetProjectionMatrix(0.05f, 2000.0f)); + RigShader->SetMat4("view", camera.GetViewMatrix()); + RigShader->Set3F("viewPos", camera.t.GetTranslation()); +} + +void RenderSystem::PrepareParticleShader(Camera& camera) +{ + ParticleShader->Activate(); + ParticleShader->SetMat4("proj", camera.GetProjectionMatrix(0.05f, 2000.0f)); + ParticleShader->SetMat4("view", camera.GetViewMatrix()); +} + +void RenderSystem::PrepareBoxShader(Camera& camera) +{ + BoxShader->Activate(); + BoxShader->Set2F("screenSize", { (float)window->width, (float)window->height }); +} + +void RenderSystem::PrepareImageBoxShader(Camera& camera) +{ + ImageBoxShader->Activate(); + ImageBoxShader->Set2F("screenSize", { (float)window->width, (float)window->height }); +} + +void RenderSystem::PrepareTextShader(Camera& camera) +{ + Text2DShader->Activate(); + Text2DShader->Set2F("screenSize", { (float)window->width, (float)window->height }); +} + +// ============================================================================ +// Renderable base +// ============================================================================ +Renderable::Renderable() {} + +Renderable::~Renderable() +{ + engine->rendersystem->RemoveRenderable(this); +} + +void Renderable::BindToRenderSystem() +{ + engine->rendersystem->AddRenderable(this); +} \ No newline at end of file diff --git a/RenderSystem.h b/RenderSystem.h new file mode 100644 index 0000000..671293c --- /dev/null +++ b/RenderSystem.h @@ -0,0 +1,89 @@ +#ifndef RENDER_SYSTEM +#define RENDER_SYSTEM +#include +#include +#include +const float skyboxVertices[] = { + -1.0f, 1.0f, -1.0f, -1.0f, -1.0f, -1.0f, 1.0f, -1.0f, -1.0f, + 1.0f, -1.0f, -1.0f, 1.0f, 1.0f, -1.0f, -1.0f, 1.0f, -1.0f, + -1.0f, -1.0f, 1.0f, -1.0f, -1.0f, -1.0f, -1.0f, 1.0f, -1.0f, + -1.0f, 1.0f, -1.0f, -1.0f, 1.0f, 1.0f, -1.0f, -1.0f, 1.0f, + 1.0f, -1.0f, -1.0f, 1.0f, -1.0f, 1.0f, 1.0f, 1.0f, 1.0f, + 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, -1.0f, 1.0f, -1.0f, -1.0f, + -1.0f, -1.0f, 1.0f, -1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, + 1.0f, 1.0f, 1.0f, 1.0f, -1.0f, 1.0f, -1.0f, -1.0f, 1.0f, + -1.0f, 1.0f, -1.0f, 1.0f, 1.0f, -1.0f, 1.0f, 1.0f, 1.0f, + 1.0f, 1.0f, 1.0f, -1.0f, 1.0f, 1.0f, -1.0f, 1.0f, -1.0f, + -1.0f, -1.0f, -1.0f, -1.0f, -1.0f, 1.0f, 1.0f, -1.0f, -1.0f, + 1.0f, -1.0f, -1.0f, -1.0f, -1.0f, 1.0f, 1.0f, -1.0f, 1.0f +}; +class Camera; +class Shader; +class FBO; +class VBO; +class VAO; +class Cubemap; +class Lighting; +class Renderable { +public: + enum ShaderType { + RigShader, + MeshShader, + ImageBoxShader, + BoxShader, + TextShader, + ParticleShader + }; + ShaderType shadertype = ShaderType::MeshShader; + bool opaque = true; + bool castshadow = false; + Renderable(); + ~Renderable(); + void BindToRenderSystem(); + virtual void Render(Shader& ShaderProgram) {} + virtual glm::vec3 GetWorldPosition() const { return glm::vec3(0.0f); } +}; +class RenderSystem { +public: + Lighting* lighting = nullptr; + FBO* screenfbo = nullptr; + FBO* shadowdepthmapfbo = nullptr; + unsigned int depthMaptexture = 0; + unsigned int textureColorbuffer = 0; + unsigned int rbo = 0; + unsigned int SHADOW_RESOLUTION = 0; + VAO* quadVAO = nullptr; VBO* quadVBO = nullptr; + VAO* skyboxVAO = nullptr; VBO* skyboxVBO = nullptr; + Shader* MeshShadowShader = nullptr; + Shader* RigShadowShader = nullptr; + Shader* SkyboxShader = nullptr; + Shader* ScreenShader = nullptr; + Shader* RigShader = nullptr; + Shader* MeshShader = nullptr; + Shader* ImageBoxShader = nullptr; + Shader* BoxShader = nullptr; + Shader* Text2DShader = nullptr; + Shader* ParticleShader = nullptr; + Cubemap* skybox = nullptr; + RenderSystem() {} + void Initialize(); + void Render(Camera& camera); + void AddRenderable(Renderable* r) { renderables.push_back(r); } + void RemoveRenderable(Renderable* r) { + for (int i = 0; i < (int)renderables.size(); i++) { + if (renderables[i] == r) { renderables.erase(renderables.begin() + i); return; } + } + std::cout << "didn't find renderable to remove\n"; + } + void RenderRenderable(Renderable* renderable, Camera& camera); + std::vector renderables; +private: + void PrepareRigShader(Camera& camera); + void PrepareMeshShader(Camera& camera); + void PrepareParticleShader(Camera& camera); + void PrepareBoxShader(Camera& camera); + void PrepareImageBoxShader(Camera& camera); + void PrepareTextShader(Camera& camera); + void RenderTranslucent(Camera& camera, const glm::mat4& lightSpaceMatrix, const glm::vec3& camPos); +}; +#endif \ No newline at end of file diff --git a/ResourceManager.h b/ResourceManager.h new file mode 100644 index 0000000..37bd620 --- /dev/null +++ b/ResourceManager.h @@ -0,0 +1,20 @@ +#ifndef RESOURCE_MANAGER_CLASS +#define RESOURCE_MANAGER_CLASS + +#include + +#include "Folder.h" +//#include "font.h" +#include "Model.h" +#include "SoundSystem.h" + +class ResourceManager { +public: + //std::vector fonts; + std::vector models; + std::vector sounds; +public: + +}; + +#endif \ No newline at end of file diff --git a/Rig.h b/Rig.h new file mode 100644 index 0000000..86d607d --- /dev/null +++ b/Rig.h @@ -0,0 +1,683 @@ +#ifndef RIG_CLASS +#define RIG_CLASS + +#include +#include + +#include + +#include +#include +#include +#include +#include +#include + +#include + +#include "Mesh.h" + +class AssimpGLMHelpers +{ +public: + + static inline glm::mat4 ConvertMatrixToGLMFormat(const aiMatrix4x4& from) + { + glm::mat4 to; + //the a,b,c,d in assimp is the row ; the 1,2,3,4 is the column + to[0][0] = from.a1; to[1][0] = from.a2; to[2][0] = from.a3; to[3][0] = from.a4; + to[0][1] = from.b1; to[1][1] = from.b2; to[2][1] = from.b3; to[3][1] = from.b4; + to[0][2] = from.c1; to[1][2] = from.c2; to[2][2] = from.c3; to[3][2] = from.c4; + to[0][3] = from.d1; to[1][3] = from.d2; to[2][3] = from.d3; to[3][3] = from.d4; + return to; + } + + static inline glm::vec3 GetGLMVec(const aiVector3D& vec) + { + return glm::vec3(vec.x, vec.y, vec.z); + } + + static inline glm::quat GetGLMQuat(const aiQuaternion& pOrientation) + { + return glm::quat(pOrientation.w, pOrientation.x, pOrientation.y, pOrientation.z); + } +}; + +struct BoneInfo +{ + /*id is index in finalBoneMatrices*/ + int id; + + /*offset matrix transforms vertex from model space to bone space*/ + glm::mat4 offset; + +}; + +struct KeyPosition +{ + glm::vec3 position; + float timeStamp; +}; + +struct KeyRotation +{ + glm::quat orientation; + float timeStamp; +}; + +struct KeyScale +{ + glm::vec3 scale; + float timeStamp; +}; + +class Bone +{ +private: + std::vector m_Positions; + std::vector m_Rotations; + std::vector m_Scales; + int m_NumPositions; + int m_NumRotations; + int m_NumScalings; + + glm::mat4 m_LocalTransform; + std::string m_Name; + int m_ID; + +public: + + /*reads keyframes from aiNodeAnim*/ + Bone(const std::string& name, int ID, const aiNodeAnim* channel) + : + m_Name(name), + m_ID(ID), + m_LocalTransform(1.0f) + { + m_NumPositions = channel->mNumPositionKeys; + + for (int positionIndex = 0; positionIndex < m_NumPositions; ++positionIndex) + { + aiVector3D aiPosition = channel->mPositionKeys[positionIndex].mValue; + float timeStamp = channel->mPositionKeys[positionIndex].mTime; + KeyPosition data; + data.position = AssimpGLMHelpers::GetGLMVec(aiPosition); + data.timeStamp = timeStamp; + m_Positions.push_back(data); + } + + m_NumRotations = channel->mNumRotationKeys; + for (int rotationIndex = 0; rotationIndex < m_NumRotations; ++rotationIndex) + { + aiQuaternion aiOrientation = channel->mRotationKeys[rotationIndex].mValue; + float timeStamp = channel->mRotationKeys[rotationIndex].mTime; + KeyRotation data; + data.orientation = AssimpGLMHelpers::GetGLMQuat(aiOrientation); + data.timeStamp = timeStamp; + m_Rotations.push_back(data); + } + + m_NumScalings = channel->mNumScalingKeys; + for (int keyIndex = 0; keyIndex < m_NumScalings; ++keyIndex) + { + aiVector3D scale = channel->mScalingKeys[keyIndex].mValue; + float timeStamp = channel->mScalingKeys[keyIndex].mTime; + KeyScale data; + data.scale = AssimpGLMHelpers::GetGLMVec(scale); + data.timeStamp = timeStamp; + m_Scales.push_back(data); + } + } + + /*interpolates b/w positions,rotations & scaling keys based on the curren time of + the animation and prepares the local transformation matrix by combining all keys + tranformations*/ + void Update(float animationTime) + { + glm::mat4 translation = InterpolatePosition(animationTime); + glm::mat4 rotation = InterpolateRotation(animationTime); + glm::mat4 scale = InterpolateScaling(animationTime); + m_LocalTransform = translation * rotation;// *scale; + } + + glm::mat4 GetLocalTransform() { return m_LocalTransform; } + std::string GetBoneName() const { return m_Name; } + int GetBoneID() { return m_ID; } + + + /* Gets the current index on mKeyPositions to interpolate to based on + the current animation time*/ + int GetPositionIndex(float animationTime) + { + for (int index = 0; index < m_NumPositions - 1; ++index) + { + if (animationTime < m_Positions[index + 1].timeStamp) + return index; + } + assert(0); + } + + /* Gets the current index on mKeyRotations to interpolate to based on the + current animation time*/ + int GetRotationIndex(float animationTime) + { + for (int index = 0; index < m_NumRotations - 1; ++index) + { + if (animationTime < m_Rotations[index + 1].timeStamp) + return index; + } + assert(0); + } + + /* Gets the current index on mKeyScalings to interpolate to based on the + current animation time */ + int GetScaleIndex(float animationTime) + { + for (int index = 0; index < m_NumScalings - 1; ++index) + { + if (animationTime < m_Scales[index + 1].timeStamp) + return index; + } + assert(0); + } + +private: + + /* Gets normalized value for Lerp & Slerp*/ + float GetScaleFactor(float lastTimeStamp, float nextTimeStamp, float animationTime) + { + float scaleFactor = 0.0f; + float midWayLength = animationTime - lastTimeStamp; + float framesDiff = nextTimeStamp - lastTimeStamp; + scaleFactor = midWayLength / framesDiff; + return scaleFactor; + } + + /*figures out which position keys to interpolate b/w and performs the interpolation + and returns the translation matrix*/ + glm::mat4 InterpolatePosition(float animationTime) + { + if (1 == m_NumPositions) + return glm::translate(glm::mat4(1.0f), m_Positions[0].position); + + int p0Index = GetPositionIndex(animationTime); + int p1Index = p0Index + 1; + float scaleFactor = GetScaleFactor(m_Positions[p0Index].timeStamp, + m_Positions[p1Index].timeStamp, animationTime); + glm::vec3 finalPosition = glm::mix(m_Positions[p0Index].position, + m_Positions[p1Index].position, scaleFactor); + return glm::translate(glm::mat4(1.0f), finalPosition); + } + + /*figures out which rotations keys to interpolate b/w and performs the interpolation + and returns the rotation matrix*/ + glm::mat4 InterpolateRotation(float animationTime) + { + if (1 == m_NumRotations) + { + auto rotation = glm::normalize(m_Rotations[0].orientation); + return glm::mat4_cast(rotation); + } + + int p0Index = GetRotationIndex(animationTime); + int p1Index = p0Index + 1; + float scaleFactor = GetScaleFactor(m_Rotations[p0Index].timeStamp, + m_Rotations[p1Index].timeStamp, animationTime); + glm::quat finalRotation = glm::slerp(m_Rotations[p0Index].orientation, + m_Rotations[p1Index].orientation, scaleFactor); + finalRotation = glm::normalize(finalRotation); + return glm::mat4_cast(finalRotation); + } + + /*figures out which scaling keys to interpolate b/w and performs the interpolation + and returns the scale matrix*/ + glm::mat4 InterpolateScaling(float animationTime) + { + if (1 == m_NumScalings) + return glm::scale(glm::mat4(1.0f), m_Scales[0].scale); + + int p0Index = GetScaleIndex(animationTime); + int p1Index = p0Index + 1; + float scaleFactor = GetScaleFactor(m_Scales[p0Index].timeStamp, + m_Scales[p1Index].timeStamp, animationTime); + glm::vec3 finalScale = glm::mix(m_Scales[p0Index].scale, m_Scales[p1Index].scale + , scaleFactor); + return glm::scale(glm::mat4(1.0f), finalScale); + } + +}; + +class RigMesh : public Object, public Renderable, public t_package, public RigMeshData { + friend class Model; +protected: +public: + VAO vao; + VBO vbo; + EBO ebo; + + RigMesh() { + + }; + + RigMesh(const std::vector& meshvertices, const std::vector& meshindices/*, std::vector textures*/) + { + InitializeMesh(meshvertices, meshindices); + }; + + void InitializeMesh(const std::vector& meshvertices, const std::vector& meshindices) { + vertices = meshvertices; + indices = meshindices; + this->shadertype = MeshShader; + GenerateRenderData(); + //NormalizeVertices(); + UpdateVertices(); + } + + void GenerateRenderData() { + vbo.GenerateID(); + vao.GenerateID(); + ebo.GenerateID(); + + if (vertices.size() <= 0 or indices.size() <= 0) { + std::cout << "NO VERTICES OR INDICES DURING RENDER DATA INTIALIZATION\n"; + + } + else { + vao.Bind(); + ebo.Bind(); + vbo.BufferData(&vertices[0], vertices.size() * sizeof(RigVertex)); + ebo.BufferData(&indices[0], indices.size() * sizeof(GLuint)); + + vbo.Bind(); + ebo.Bind(); + + vao.LinkVBO(vbo, 0, 3, GL_FLOAT, sizeof(RigVertex), (void*)0); + vao.LinkVBO(vbo, 1, 3, GL_FLOAT, sizeof(RigVertex), (void*)offsetof(RigVertex, Normal)); + vao.LinkVBO(vbo, 2, 2, GL_FLOAT, sizeof(RigVertex), (void*)offsetof(RigVertex, TexCoords)); + vbo.Bind(); + glEnableVertexAttribArray(3); + glVertexAttribIPointer(3, 4, GL_INT, sizeof(RigVertex), (void*)offsetof(RigVertex, m_BoneIDs)); + + glEnableVertexAttribArray(4); + glVertexAttribPointer(4, 4, GL_FLOAT, GL_FALSE, sizeof(RigVertex), (void*)offsetof(RigVertex, m_Weights)); + + vao.Unbind(); + vbo.Unbind(); + ebo.Unbind(); + } + } + + virtual ~RigMesh() { + vao.Delete(); + vbo.Delete(); + ebo.Delete(); + //delete this; + } + + float GetVolume() const { + float runningtotal = 0.0f; + + for (int i = 0; i < indices.size() / 3; i++) { + runningtotal += VolumeOfTriangle(vertices[indices[i * 3]].Position, vertices[indices[i * 3 + 1]].Position, vertices[indices[i * 3 + 2]].Position); + } + + return runningtotal * t.GetScale().x * t.GetScale().y * t.GetScale().z; + } + + virtual RigMesh* Clone() override { + RigMesh* tr = new RigMesh(*this); + tr->GenerateRenderData(); + return tr; + }; + + void Clear() { + vertices = std::vector(); + indices = std::vector(); + } + + glm::vec3 GetAABB() const { + if (vertices.empty()) { + return glm::vec3(0.0f); + } + + glm::vec3 min(FLT_MAX); + glm::vec3 max(-FLT_MAX); + + for (const RigVertex& vertex : vertices) { + min = glm::min(min, vertex.Position); + max = glm::max(max, vertex.Position); + } + + return (max - min) * t.GetScale(); + } + + void SetVertices(std::vector& e) { + glBufferSubData(GL_ARRAY_BUFFER, NULL, sizeof(e), &e[0]); + + glBindBuffer(GL_ARRAY_BUFFER, vbo.ID); + glBufferData(GL_ARRAY_BUFFER, sizeof(e), &e[0], GL_DYNAMIC_DRAW); + glBindBuffer(GL_ARRAY_BUFFER, 0); + } + + void UpdateVertices() { + if (vertices.size() > 0) { + + glBufferSubData(GL_ARRAY_BUFFER, NULL, sizeof(vertices), &vertices[0]); + glBindBuffer(GL_ARRAY_BUFFER, vbo.ID); + glBufferData(GL_ARRAY_BUFFER, vertices.size() * sizeof(RigVertex), &vertices[0], GL_STATIC_DRAW); + glBindBuffer(GL_ARRAY_BUFFER, 0); + } + else std::cout << "NO VERTICES IN THIS MESH!!!!\n"; + } + + void UpdateIndices() { + if (ebo.ID == 0) { + std::cout << "EBO NOT INITIALIZED\m"; + return; + } + if (indices.size() > 0) { + glBufferSubData(GL_ELEMENT_ARRAY_BUFFER, NULL, sizeof(indices), &indices[0]); + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ebo.ID); + glBufferData(GL_ELEMENT_ARRAY_BUFFER, indices.size() * sizeof(GLuint), &indices[0], GL_STATIC_DRAW); + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); + } + else std::cout << "NO INDICES IN THIS MESH!!!!\n"; + } + /* + void NormalizeVertices() { + if (vertices.size() == 0) { + std::cout << "TRIED TO NORMALIZE ZERO VERTICES???\n"; + throw; + } + float biggestx = -FLT_MAX; + float smallestx = FLT_MAX; + float biggesty = -FLT_MAX; + float smallesty = FLT_MAX; + float biggestz = -FLT_MAX; + float smallestz = FLT_MAX; + for (RigVertex& vertex : vertices) { + biggestx = glm::max(biggestx, vertex.Position.x); + smallestx = glm::min(smallestx, vertex.Position.x); + biggesty = glm::max(biggesty, vertex.Position.y); + smallesty = glm::min(smallesty, vertex.Position.y); + biggestz = glm::max(biggestz, vertex.Position.z); + smallestz = glm::min(smallestz, vertex.Position.z); + } + + float xf = biggestx - smallestx; + float yf = biggesty - smallesty; + float zf = biggestz - smallestz; + + float midx = (biggestx + smallestx) / 2.0f; + float midy = (biggesty + smallesty) / 2.0f; + float midz = (biggestz + smallestz) / 2.0f; + t.TranslateBy(glm::vec3(midx, midy, midz) * t.GetScale()); + + t.ScaleBy(glm::vec3(xf, yf, zf)); + glm::vec3 scale = t.GetScale(); + if (scale.x == 0.0f) { + t.ScaleToX(xf); + } + if (scale.y == 0.0f) { + t.ScaleToY(yf); + } + if (scale.z == 0.0f) { + t.ScaleToZ(zf); + } + + for (RigVertex& vertex : vertices) { + vertex.Position = glm::vec3( + (vertex.Position.x - midx) / xf, + (vertex.Position.y - midy) / yf, + (vertex.Position.z - midz) / zf + ); + + if (xf == 0.0f) { + vertex.Position.x = 0.0f; + } + if (yf == 0.0f) { + vertex.Position.y = 0.0f; + } + if (zf == 0.0f) { + vertex.Position.z = 0.0f; + } + } + } + */ + void Render(Shader& ShaderProgram, glm::mat4 modelmat) { + glm::mat4 topass = modelmat * t.GetMatrix(); + ShaderProgram.SetMat4("modl", topass); + vao.Bind(); + glDrawElements(GL_TRIANGLES, indices.size(), GL_UNSIGNED_INT, 0); + vao.Unbind(); + }; + + void DeleteRenderData() { + vbo.Delete(); + ebo.Delete(); + vao.Delete(); + } + + virtual void Delete() override { + DeleteRenderData(); + Object::Delete(); + } +public: + //random ass funcs + + bool RayIntersectsMeshNoInfo(const Ray& ray) + { + glm::mat4 inverse = glm::inverse(t.GetMatrix()); + glm::vec3 ray_origin = glm::vec3(inverse * glm::vec4(ray.origin, 1.0f)); + glm::vec3 ray_direction = glm::vec3(inverse * glm::vec4(ray.direction, 0.0f)); + + for (int i = 0; i < indices.size() / 3; i++) { + std::optional intersection = RayIntersectsTriangle({ ray_origin,ray_direction }, { vertices[indices[i * 3]].Position, vertices[indices[i * 3 + 1]].Position,vertices[indices[i * 3 + 2]].Position }); + if (intersection.has_value()) { + return true; + } + } + return false; + } + + std::optional> RayIntersectsMesh(const Ray& ray, Mesh* mesh) + { + //USE THIS AFTER A CHEAPER CHECK + std::vector intersections = {}; + + glm::mat4 inverse = glm::inverse(t.GetMatrix()); + glm::vec3 ray_origin = glm::vec3(inverse * glm::vec4(ray.origin, 1.0f)); + glm::vec3 ray_direction = glm::vec3(inverse * glm::vec4(ray.direction, 0.0f)); + + + std::map sorted; + + for (int i = 0; i < indices.size() / 3; i++) { + std::optional intersection = RayIntersectsTriangle({ ray_origin,ray_direction }, { vertices[indices[i * 3]].Position, vertices[indices[i * 3 + 1]].Position,vertices[indices[i * 3 + 2]].Position }); + if (intersection.has_value()) { + sorted[Magnitude2(intersection.value() - ray_origin)] = { intersection.value(),i }; + + //intersections.push_back(intersection.value()); + } + } + + if (intersections.size() > 0) return intersections; + else return {}; + } + +public: + +private: + +}; + +class Rig : public Renderable, public t_package { +public: + std::vector meshes; + std::vector bones; +public: + std::map m_BoneInfoMap; + int m_BoneCounter = 0; + std::string directory; + + Rig(std::string path) { + shadertype = RigShader; + LoadRig(path); + } + + void Render(Shader& shader) override { + shader.Activate(); + + glm::mat4 rigmat = t.GetMatrix(); + for (auto p : meshes) { + p->Render(shader, rigmat); + } + } + + void Render(Shader& shader, glm::mat4 mat) { + shader.Activate(); + + glm::mat4 rigmat = t.GetMatrix(); + for (auto p : meshes) { + p->Render(shader, mat); + } + } + + void LoadRig(std::string path) { + Assimp::Importer import; + const aiScene* scene = import.ReadFile(path, + aiProcess_Triangulate | + aiProcess_FlipUVs + ); + + if (!scene || scene->mFlags & AI_SCENE_FLAGS_INCOMPLETE || !scene->mRootNode) + { + std::cout << "ERROR::ASSIMP::" << import.GetErrorString() << '\n'; + return; + } + directory = path.substr(0, path.find_last_of('/')); + + processNode(scene->mRootNode, scene); + } +private: + void processNode(aiNode* node, const aiScene* scene) { + // process all the node's meshes (if any) + for (unsigned int i = 0; i < node->mNumMeshes; i++) + { + aiMesh* mesh = scene->mMeshes[node->mMeshes[i]]; + meshes.push_back(processRigMesh(mesh, scene)); + } + // then do the same for each of its children + for (unsigned int i = 0; i < node->mNumChildren; i++) + { + processNode(node->mChildren[i], scene); + } + }; + + RigMesh* processRigMesh(aiMesh* mesh, const aiScene* scene) + { + std::vector vertices; + std::vector indices; + + for (unsigned int i = 0; i < mesh->mNumVertices; i++) + { + RigVertex vertex; + + glm::vec3 vector; + vector.x = mesh->mVertices[i].x; + vector.y = mesh->mVertices[i].y; + vector.z = mesh->mVertices[i].z; + vertex.Position = vector; + + vector.x = mesh->mNormals[i].x; + vector.y = mesh->mNormals[i].y; + vector.z = mesh->mNormals[i].z; + vertex.Normal = vector; + + // process vertex positions, normals and texture coordinates + + if (mesh->mTextureCoords[0]) // does the mesh contain texture coordinates? + { + glm::vec2 vec; + vec.x = mesh->mTextureCoords[0][i].x; + vec.y = mesh->mTextureCoords[0][i].y; + vertex.TexCoords = vec; + } + else { + vertex.TexCoords = glm::vec2(0.0f, 0.0f); + } + + for (int i = 0; i < MAX_BONE_INFLUENCE; i++) + { + vertex.m_BoneIDs[i] = -1; + vertex.m_Weights[i] = 0.0f; + } + + vertices.push_back(vertex); + } + // process indices + for (unsigned int i = 0; i < mesh->mNumFaces; i++) + { + aiFace face = mesh->mFaces[i]; + for (unsigned int j = 0; j < face.mNumIndices; j++) + indices.push_back(face.mIndices[j]); + } + + ExtractBoneWeightForVertices(vertices, mesh, scene); + + return new RigMesh(vertices, indices); + } + + void SetVertexBoneData(RigVertex& vertex, int boneID, float weight) + { + for (int i = 0; i < MAX_BONE_INFLUENCE; ++i) + { + if (vertex.m_BoneIDs[i] < 0) + { + vertex.m_Weights[i] = weight; + vertex.m_BoneIDs[i] = boneID; + break; + } + } + } + + + void ExtractBoneWeightForVertices(std::vector& vertices, aiMesh* mesh, const aiScene* scene) + { + auto& boneInfoMap = m_BoneInfoMap; + int& boneCount = m_BoneCounter; + + for (int boneIndex = 0; boneIndex < mesh->mNumBones; ++boneIndex) + { + int boneID = -1; + std::string boneName = mesh->mBones[boneIndex]->mName.C_Str(); + if (boneInfoMap.find(boneName) == boneInfoMap.end()) + { + BoneInfo newBoneInfo; + newBoneInfo.id = boneCount; + newBoneInfo.offset = AssimpGLMHelpers::ConvertMatrixToGLMFormat(mesh->mBones[boneIndex]->mOffsetMatrix); + boneInfoMap[boneName] = newBoneInfo; + boneID = boneCount; + boneCount++; + } + else + { + boneID = boneInfoMap[boneName].id; + } + assert(boneID != -1); + auto weights = mesh->mBones[boneIndex]->mWeights; + int numWeights = mesh->mBones[boneIndex]->mNumWeights; + + for (int weightIndex = 0; weightIndex < numWeights; ++weightIndex) + { + int vertexId = weights[weightIndex].mVertexId; + float weight = weights[weightIndex].mWeight; + assert(vertexId <= vertices.size()); + SetVertexBoneData(vertices[vertexId], boneID, weight); + } + } + } + +}; + +#endif \ No newline at end of file diff --git a/Sound.cpp b/Sound.cpp new file mode 100644 index 0000000..73182a5 --- /dev/null +++ b/Sound.cpp @@ -0,0 +1,87 @@ +#include "Sound.h" +#include "common.h" + +Sound::Sound() +{ + pos = { 0.0f, 0.0f, 0.0f }; + m_soundData = nullptr; + m_channel = nullptr; +} + +Sound::~Sound() +{ + StopTrack(); + // SoundSystem owns the SoundData lifetime — don't delete m_soundData here. +} + +// --------------------------------------------------------------------------- +// LoadSound +// Delegates to SoundSystem's cache so the same file is never loaded twice. +// --------------------------------------------------------------------------- +void Sound::LoadSound(const std::string& filename, bool is3D) +{ + StopTrack(); + m_soundData = soundsystem->LoadSound(filename, is3D); + if (!m_soundData) + std::cout << "Sound::LoadSound — failed to load: " << filename << "\n"; + else if (is3D) + m_soundData->sound->set3DMinMaxDistance(minDistance, maxDistance); +} + +// --------------------------------------------------------------------------- +// PlayTrack +// --------------------------------------------------------------------------- +bool Sound::PlayTrack(bool loop) +{ + if (!m_soundData || !m_soundData->sound) { + std::cout << "Sound::PlayTrack — no sound loaded\n"; + return false; + } + + if (m_soundData->is3D) { + m_channel = soundsystem->PlaySound3D(m_soundData, pos, loop); + } + else { + m_channel = soundsystem->PlaySound(m_soundData, loop); + } + + return m_channel != nullptr; +} + +// --------------------------------------------------------------------------- +// StopTrack +// --------------------------------------------------------------------------- +bool Sound::StopTrack() +{ + if (!m_channel) return true; + + bool isPlaying = false; + m_channel->isPlaying(&isPlaying); + if (isPlaying) + m_channel->stop(); + + m_channel = nullptr; + return true; +} + +// --------------------------------------------------------------------------- +// Update3DPosition +// Call every frame for moving emitters. +// --------------------------------------------------------------------------- +void Sound::Update3DPosition(float x, float y, float z) +{ + pos = { x, y, z }; + + // If channel is still active, push the new position immediately. + if (m_channel) { + bool isPlaying = false; + m_channel->isPlaying(&isPlaying); + if (isPlaying) { + // Velocity estimated as zero — pass your actual velocity if you have it. + soundsystem->SetChannelPosition(m_channel, pos); + } + else { + m_channel = nullptr; // channel finished, clean up handle + } + } +} \ No newline at end of file diff --git a/Sound.h b/Sound.h new file mode 100644 index 0000000..2d862b8 --- /dev/null +++ b/Sound.h @@ -0,0 +1,42 @@ +#ifndef SOUND_CLASS +#define SOUND_CLASS + +#include +#include +#include "Object.h" +#include "SoundSystem.h" + +class Sound : public Object { +public: + Sound(); + ~Sound(); + + // Load a sound file through the system cache. + // is3D=false for music/UI that doesn't need spatialization. + void LoadSound(const std::string& filename, bool is3D = true); + + bool PlayTrack(bool loop = false); + bool StopTrack(); + + // Call every frame if the sound is moving. + void Update3DPosition(float x, float y, float z); + void Update3DPosition(const glm::vec3& p) { Update3DPosition(p.x, p.y, p.z); } + + FMOD::Channel* GetChannel() const { return m_channel; } + +public: + glm::vec3 pos = { 0.0f, 0.0f, 0.0f }; + + // Attenuation distances — set before PlayTrack if you want non-defaults. + float minDistance = 1.0f; + float maxDistance = 100.0f; + + // Doppler scale for this emitter (1.0 = normal). + float dopplerScale = 1.0f; + +private: + SoundData* m_soundData = nullptr; + FMOD::Channel* m_channel = nullptr; +}; + +#endif \ No newline at end of file diff --git a/SoundSystem.cpp b/SoundSystem.cpp new file mode 100644 index 0000000..b1a7ae5 --- /dev/null +++ b/SoundSystem.cpp @@ -0,0 +1,172 @@ +#include "SoundSystem.h" +#include + +// --------------------------------------------------------------------------- +// Helpers +// --------------------------------------------------------------------------- + +void SoundSystem::CheckError(FMOD_RESULT result, const char* context) +{ + if (result != FMOD_OK) { + std::cout << "FMOD error [" << context << "]: " + << FMOD_ErrorString(result) << "\n"; + } +} + +FMOD_VECTOR SoundSystem::ToFMOD(const glm::vec3& v) +{ + return { v.x, v.y, v.z }; +} + +// --------------------------------------------------------------------------- +// Construction / destruction +// --------------------------------------------------------------------------- + +SoundSystem::SoundSystem() +{ + FMOD_RESULT result; + + result = FMOD::System_Create(&system); + CheckError(result, "System_Create"); + + // 512 max channels – raise if you need more simultaneous voices. + result = system->init(512, FMOD_INIT_NORMAL | FMOD_INIT_3D_RIGHTHANDED, nullptr); + CheckError(result, "system->init"); + + // Default 3D settings: scale 1 unit = 1 metre, doppler on, rolloff linear. + system->set3DSettings(1.0f, // doppler scale + 1.0f, // distance factor (metres per unit) + 1.0f); // rolloff scale + + // Default listener orientation (matches XAudio2 original). + SetListenerPosition({ 0.0f, 0.0f, 0.0f }, + { 0.0f, 0.0f, 1.0f }, + { 0.0f, 1.0f, 0.0f }); +} + +SoundSystem::~SoundSystem() +{ + for (auto& [key, sd] : cache) { + if (sd && sd->sound) + sd->sound->release(); + delete sd; + } + cache.clear(); + + if (system) { + system->close(); + system->release(); + } +} + +// --------------------------------------------------------------------------- +// Asset loading +// --------------------------------------------------------------------------- + +SoundData* SoundSystem::LoadSound(const std::string& filename, bool is3D) +{ + // Return cached version if already loaded. + auto it = cache.find(filename); + if (it != cache.end()) return it->second; + + FMOD_MODE mode = FMOD_DEFAULT | FMOD_CREATECOMPRESSEDSAMPLE; + if (is3D) mode |= FMOD_3D | FMOD_3D_LINEARROLLOFF; + else mode |= FMOD_2D; + + SoundData* sd = new SoundData(); + sd->is3D = is3D; + + FMOD_RESULT result = system->createSound(filename.c_str(), mode, nullptr, &sd->sound); + CheckError(result, "createSound"); + + if (result != FMOD_OK) { + delete sd; + return nullptr; + } + + // Default min/max distances for 3D sounds (tune per-asset if needed). + if (is3D) + sd->sound->set3DMinMaxDistance(1.0f, 100.0f); + + cache[filename] = sd; + return sd; +} + +// --------------------------------------------------------------------------- +// Playback +// --------------------------------------------------------------------------- + +FMOD::Channel* SoundSystem::PlaySound(SoundData* data, bool loop) +{ + if (!data || !data->sound) return nullptr; + + data->sound->setMode(loop ? FMOD_LOOP_NORMAL : FMOD_LOOP_OFF); + + FMOD::Channel* channel = nullptr; + FMOD_RESULT result = system->playSound(data->sound, nullptr, false, &channel); + CheckError(result, "playSound"); + + return (result == FMOD_OK) ? channel : nullptr; +} + +FMOD::Channel* SoundSystem::PlaySound3D(SoundData* data, + const glm::vec3& position, + bool loop) +{ + if (!data || !data->sound) return nullptr; + + // Start paused so we can set position before the first audio callback. + data->sound->setMode(loop ? FMOD_LOOP_NORMAL : FMOD_LOOP_OFF); + + FMOD::Channel* channel = nullptr; + FMOD_RESULT result = system->playSound(data->sound, nullptr, true, &channel); + CheckError(result, "playSound3D"); + + if (result != FMOD_OK || !channel) return nullptr; + + FMOD_VECTOR pos = ToFMOD(position); + FMOD_VECTOR vel = { 0.0f, 0.0f, 0.0f }; + channel->set3DAttributes(&pos, &vel); + channel->setPaused(false); + + return channel; +} + +// --------------------------------------------------------------------------- +// Listener +// --------------------------------------------------------------------------- + +void SoundSystem::SetListenerPosition(const glm::vec3& position, + const glm::vec3& forward, + const glm::vec3& up, + const glm::vec3& velocity) +{ + FMOD_VECTOR pos = ToFMOD(position); + FMOD_VECTOR vel = ToFMOD(velocity); + FMOD_VECTOR fwd = ToFMOD(forward); + FMOD_VECTOR up_ = ToFMOD(up); + system->set3DListenerAttributes(0, &pos, &vel, &fwd, &up_); +} + +// --------------------------------------------------------------------------- +// Per-channel 3D update +// --------------------------------------------------------------------------- + +void SoundSystem::SetChannelPosition(FMOD::Channel* channel, + const glm::vec3& position, + const glm::vec3& velocity) +{ + if (!channel) return; + FMOD_VECTOR pos = ToFMOD(position); + FMOD_VECTOR vel = ToFMOD(velocity); + channel->set3DAttributes(&pos, &vel); +} + +// --------------------------------------------------------------------------- +// Frame update – must be called once per game loop tick +// --------------------------------------------------------------------------- + +void SoundSystem::Update() +{ + system->update(); +} \ No newline at end of file diff --git a/SoundSystem.h b/SoundSystem.h new file mode 100644 index 0000000..ca89eb1 --- /dev/null +++ b/SoundSystem.h @@ -0,0 +1,62 @@ +#ifndef SOUND_SYSTEM_CLASS +#define SOUND_SYSTEM_CLASS +#define NOMINMAX +#include +#include +#include +#include +#include + +// Loaded sound asset – owns the FMOD::Sound* handle. +// Call SoundSystem::LoadSound() to get one; the system owns the lifetime. +struct SoundData { + FMOD::Sound* sound = nullptr; + bool is3D = true; +}; + +class SoundSystem { +public: + SoundSystem(); + ~SoundSystem(); + + // ---- asset loading ---- + // Returns a non-owning pointer into the internal cache. + // Pass is3D=false for music/UI sounds that don't need spatialization. + SoundData* LoadSound(const std::string& filename, bool is3D = true); + + // ---- playback ---- + // Plays a sound and returns the channel it's playing on (nullptr on failure). + FMOD::Channel* PlaySound(SoundData* data, bool loop = false); + + // Plays a sound at a world position with full 3D attenuation. + FMOD::Channel* PlaySound3D(SoundData* data, const glm::vec3& position, bool loop = false); + + // ---- 3D listener ---- + void SetListenerPosition(const glm::vec3& position, + const glm::vec3& forward, + const glm::vec3& up, + const glm::vec3& velocity = glm::vec3(0.0f)); + + // ---- per-channel 3D updates ---- + // Call every frame for moving emitters. + void SetChannelPosition(FMOD::Channel* channel, + const glm::vec3& position, + const glm::vec3& velocity = glm::vec3(0.0f)); + + // ---- must be called once per frame ---- + void Update(); + + // ---- helpers ---- + FMOD::System* GetSystem() const { return system; } + +private: + FMOD::System* system = nullptr; + + // Cache: filename ? SoundData. System owns all SoundData objects. + std::unordered_map cache; + + static void CheckError(FMOD_RESULT result, const char* context); + static FMOD_VECTOR ToFMOD(const glm::vec3& v); +}; + +#endif \ No newline at end of file diff --git a/Structures.h b/Structures.h new file mode 100644 index 0000000..662f6bc --- /dev/null +++ b/Structures.h @@ -0,0 +1,32 @@ + +#ifndef BOUNDING_BOX_CLASS +#define BOUNDING_BOX_CLASS + +#include +#include +#include +#include +#include + +struct Ray { + glm::vec3 origin; + glm::vec3 direction; +}; + +struct Triangle { + glm::vec3 a; + glm::vec3 b; + glm::vec3 c; +}; + +struct BoundingAxis { + float min; + float max; +}; + +struct BoundingBox { + glm::vec3 min; + glm::vec3 max; +}; + +#endif \ No newline at end of file diff --git a/VAO.cpp b/VAO.cpp new file mode 100644 index 0000000..e5fee5d --- /dev/null +++ b/VAO.cpp @@ -0,0 +1,31 @@ + +#include "VAO.h" + +VAO::VAO() +{ +} + +void VAO::LinkVBO(VBO& vbo, GLuint layout, GLuint numComponents, GLenum type, GLsizeiptr stride, void* offset) { + vbo.Bind(); + + glEnableVertexAttribArray(layout); + glVertexAttribPointer(layout, numComponents, type, GL_FALSE, stride, offset); + + vbo.Unbind(); +} + +void VAO::Bind() +{ + glBindVertexArray(ID); +} + +void VAO::Unbind() +{ + glBindVertexArray(0); +} + +void VAO::Delete() +{ + glDeleteVertexArrays(1, &ID); + ID = 0; +} \ No newline at end of file diff --git a/VAO.h b/VAO.h new file mode 100644 index 0000000..bba7acb --- /dev/null +++ b/VAO.h @@ -0,0 +1,21 @@ + +#ifndef VAO_CLASS_H +#define VAO_CLASS_H + +#include +#include "VBO.h" + +class VAO { +public: + GLuint ID; + VAO(); + void GenerateID() { + glGenVertexArrays(1, &ID); + } + void LinkVBO(VBO& vbo, GLuint layout, GLuint numComponents, GLenum type, GLsizeiptr stride, void* offset); + void Bind(); + void Unbind(); + void Delete(); +}; + +#endif \ No newline at end of file diff --git a/VBO.cpp b/VBO.cpp new file mode 100644 index 0000000..234109f --- /dev/null +++ b/VBO.cpp @@ -0,0 +1,30 @@ + +#include "VBO.h" + +VBO::VBO() +{ +} + + + +void VBO::Bind() +{ + glBindBuffer(GL_ARRAY_BUFFER, ID); +} + +void VBO::BufferData(void* vertices, GLsizeiptr size) { + glBindBuffer(GL_ARRAY_BUFFER, ID); + glBufferData(GL_ARRAY_BUFFER, size, vertices, GL_STATIC_DRAW); + glBindBuffer(GL_ARRAY_BUFFER, 0); +} + +void VBO::Unbind() +{ + glBindBuffer(GL_ARRAY_BUFFER, 0); +} + +void VBO::Delete() +{ + glDeleteBuffers(1, &ID); + ID = 0; +} \ No newline at end of file diff --git a/VBO.h b/VBO.h new file mode 100644 index 0000000..4e49b98 --- /dev/null +++ b/VBO.h @@ -0,0 +1,22 @@ + +#ifndef VBO_CLASS_H +#define VBO_CLASS_H + +#include + +#include "Vertex.h" + +class VBO { +public: + GLuint ID; + VBO(); + void GenerateID() { + glGenBuffers(1, &ID); + }; + void BufferData(void* vertices, GLsizeiptr size); + void Bind(); + void Unbind(); + void Delete(); +}; + +#endif \ No newline at end of file diff --git a/Vertex.h b/Vertex.h new file mode 100644 index 0000000..203eda2 --- /dev/null +++ b/Vertex.h @@ -0,0 +1,24 @@ + +#ifndef VERTEX_CLASS +#define VERTEX_CLASS + +#define MAX_BONE_INFLUENCE 4 + +#include + +struct Vertex { + glm::vec3 Position; + glm::vec3 Normal; + glm::vec2 TexCoords; +}; + +struct RigVertex { + glm::vec3 Position; + glm::vec3 Normal; + glm::vec2 TexCoords; + int m_BoneIDs[MAX_BONE_INFLUENCE]; + + float m_Weights[MAX_BONE_INFLUENCE]; +}; + +#endif \ No newline at end of file diff --git a/Window.h b/Window.h new file mode 100644 index 0000000..48380f5 --- /dev/null +++ b/Window.h @@ -0,0 +1,30 @@ +#ifndef WINDOW_CLASS +#define WINDOW_CLASS + +#include + +#include +#include + +class Window { +public: + int height; + int width; + GLFWwindow* handle; + Window(int width, int height, const char* name) : height(height) , width(width) { + handle = glfwCreateWindow(width,height,name, NULL, NULL); + if (handle == NULL) { + std::cout << "WINDOW HANDLE IS NULL\n"; + glfwTerminate(); + throw - 1; + } + glfwMakeContextCurrent(handle); + } + + ~Window() { + glfwDestroyWindow(handle); + } + +}; + +#endif \ No newline at end of file diff --git a/assets/Agartha.wav b/assets/Agartha.wav new file mode 100644 index 0000000..4b0de0b Binary files /dev/null and b/assets/Agartha.wav differ diff --git a/assets/baserig.dae b/assets/baserig.dae new file mode 100644 index 0000000..73fac04 --- /dev/null +++ b/assets/baserig.dae @@ -0,0 +1,599 @@ + + + + + Blender User + Blender 4.4.0 commit date:2025-03-17, commit time:17:00, hash:05377985c527 + + 2026-05-09T03:07:37 + 2026-05-09T03:07:37 + + Z_UP + + + + + + + 0 0.7079822 0.06255221 0 0.8718193 0.06932413 0 0.6545094 -0.1097838 0 0.8785912 -0.09451282 0 0.8989413 -0.03298085 0 0.8974408 0.009063601 0 0.8287115 0.08787089 0 0.7843001 0.08980035 0 0.7729939 -0.1215322 0 0.8176806 -0.1183151 0 0.1549041 0.06755244 0 0.5745529 0.1219433 0 0.04557543 -0.1175378 0 0.5789203 -0.06545978 0 0.2651275 -0.1027395 0 0.2543504 0.07313084 0 0.3575181 -0.1285356 0 0.3733248 0.1355553 0 0.6900667 0.05161052 0 0.6660543 -0.06195473 0 0.4541965 -0.1305649 0 0.469731 0.1270233 0 0.2040756 0.07034164 0 0.1419116 -0.1175287 0 0.6305531 -0.04670101 0 0.6373879 0.08105164 0 -0.02776277 -0.1056256 0 -0.02776277 0.06779295 0 -0.02776277 -0.03598755 0 0.06741583 0.1123341 0 0.008906304 -0.1115817 0.06725132 0.7233154 0.04843622 0.07409763 0.8640959 0.04852974 0.03184431 0.6632936 -0.09416538 0.06932163 0.864995 -0.08048981 0.06158161 0.6886598 -0.03553307 0.06859195 0.7061829 0.007524728 0.08121687 0.871434 0.00881952 0.08007913 0.8718743 -0.0346632 0.07436501 0.8269675 0.05527436 0.07227855 0.7827159 0.06018775 0.06492465 0.7745726 -0.09337866 0.06896835 0.8194977 -0.09084856 0.07881098 0.8220392 -0.03684562 0.07431328 0.7776878 -0.03379517 0.07724028 0.7800226 0.009846389 0.08073413 0.8243758 0.006829857 0.1466862 0.1538009 0.06755244 0.1892135 0.5700379 0.09274744 0.07138669 0.08345532 -0.1065121 0.1341176 0.5789203 -0.05284017 0.1299207 0.2543504 0.07313078 0.1053827 0.2651275 -0.1027395 0.1871518 0.3686333 0.1079901 0.1422255 0.3595595 -0.1286 0.04103904 0.6865502 0.03497922 0.04103904 0.6695708 -0.04532349 0.1933467 0.4699194 0.07660758 0.1625556 0.4651417 -0.1105885 0.1383035 0.2040756 0.07034164 0.08952623 0.1419116 -0.1175287 0.1466861 0.1009141 -0.01752233 0.1871023 0.5860964 0.002086579 0.1299207 0.2489024 -0.02869874 0.1841033 0.3572139 -0.01173281 0.05803799 0.6780605 -0.005172073 0.1912354 0.4859779 -0.01405316 0.1383035 0.1729936 -0.03369176 0.07872211 0.6373879 0.08105164 0.06150025 0.6305531 -0.04670101 0.07872211 0.6336538 0.01125448 0.1603331 -0.02776277 -0.02889543 0.1272936 -0.02776277 0.07906466 0.03987193 -0.02776277 -0.1044155 0.1529055 0.03621953 -0.04125523 0.1499075 0.06994056 0.09381413 0.05208736 0.04012161 -0.1153447 0.1385688 -0.3725179 0.00126028 0.108603 -0.3725178 0.04537951 0.06215226 -0.3725178 -0.05064243 0.1153436 -0.372518 -0.0467509 0.05541151 -0.3725179 0.04148775 0.03218621 -0.372518 -0.006523191 0.1435203 -0.4766288 0.02890777 0.1082584 -0.4766288 0.07825905 0.05427747 -0.4766288 -0.02959161 0.1165298 -0.4766288 -0.02501755 0.04600608 -0.4766288 0.07368499 0.01901561 -0.4766288 0.01975959 0.1179746 -0.815149 0.01085764 0.09648084 -0.8194054 0.04221558 0.06316304 -0.8101418 -0.02603232 0.1013157 -0.8105171 -0.02326631 0.05832815 -0.8190301 0.03944951 0.04166924 -0.8143981 0.005325555 0.05521249 -0.5979837 0.08895218 0.02599006 -0.5979837 0.02830719 0.1228194 -0.5979837 0.09419441 0.06437444 -0.5979837 -0.02709555 0.1319813 -0.5979837 -0.02185338 0.1612038 -0.5979837 0.03879153 0.1270821 -0.8989198 0.00528407 0.1035308 -0.8989198 0.05807638 0.06722432 -0.8989198 -0.03550797 0.1089289 -0.8989198 -0.03239136 0.06182622 -0.8989198 0.05495977 0.04367297 -0.8989198 -9.49059e-4 0.07238107 -0.8729894 -0.212285 0.1161065 -0.8730859 -0.2115751 0.1351986 -0.8742746 -0.2028175 0.04774791 -0.8740817 -0.2042372 0.03638011 -0.8989198 -0.2050544 0.07227367 -0.8989198 -0.2168489 0.1358339 -0.8989198 -0.2157853 0.1635004 -0.8989198 -0.2029271 0.04386603 -0.3426398 0.05136859 0.02477848 -0.3426398 -0.01036179 0.1143667 -0.3426398 0.05537402 0.05317163 -0.3426398 -0.06285506 0.1056225 -0.3426398 -0.05644989 0.1425745 -0.3426398 -0.002380967 0.0273739 -0.3982791 0.003080129 0.05927491 -0.3982791 -0.0429508 0.115777 -0.3982791 -0.03880983 0.140378 -0.3982791 0.01136225 0.1084771 -0.3982791 0.05739319 0.05197489 -0.3982791 0.0532521 0.1917174 0.511882 0.103454 0.1873019 0.5968263 0.05075973 0.193147 0.4591896 0.02793449 0.1887316 0.5345921 -0.02475976 0.3892558 0.5540321 0.06503957 0.3879023 0.5388871 0.0945273 0.3832473 0.5131938 0.004426181 0.387948 0.5474473 0.03288102 0.3782811 0.4679223 0.04336446 0.3802581 0.477815 0.08540642 0.3842896 0.5087608 0.1039779 0.3796346 0.4830673 0.01387673 0.3073278 0.5749695 0.0631048 0.2992821 0.528962 -0.008572161 0.2925196 0.4719955 0.07885032 0.3045268 0.5513733 0.09931641 0.3059278 0.5677596 0.01969408 0.2911196 0.4647855 0.03543961 0.2991654 0.5107931 0.1071166 0.2939207 0.4883819 -7.71955e-4 0.5178557 0.4813 0.03066152 0.5212268 0.496173 0.09846448 0.5182156 0.4767222 0.08442473 0.5168192 0.4705615 0.0563398 0.523729 0.5220979 0.0364716 0.5207178 0.5026472 0.02243191 0.524089 0.5175201 0.09023481 0.5251256 0.5282586 0.06455653 0.7496773 0.458608 0.03048175 0.7536201 0.4717426 0.09934371 0.750365 0.4538324 0.08557885 0.7477803 0.453044 0.05886799 0.7556289 0.4977447 0.03571099 0.752713 0.4781761 0.02129983 0.7562703 0.4931956 0.0908963 0.7571024 0.5039662 0.06453877 0.6184251 0.4666639 0.03493303 0.6172493 0.4563034 0.05817848 0.6214525 0.4918081 0.01717758 0.6246236 0.5153057 0.02984327 0.6249668 0.510181 0.09713989 0.6260936 0.5222191 0.06499779 0.6186978 0.4644279 0.08986729 0.6219034 0.486243 0.1074412 0.525434 0.4685065 0.05650633 0.5339909 0.5283208 0.06466519 0.5268689 0.4749975 0.08505898 0.5265088 0.479456 0.03085529 0.5294554 0.501659 0.02181601 0.532554 0.521946 0.03583735 0.5329209 0.5172103 0.09102272 0.5299709 0.495123 0.09947013 0.5167927 0.523872 0.03571861 0.511078 0.4766653 0.08517771 0.5096337 0.4702555 0.05621081 0.5171612 0.5191103 0.09117025 0.5141959 0.4969016 0.09965842 0.5136747 0.5036356 0.02123796 0.5107095 0.4814269 0.02972608 0.5182368 0.5302819 0.06468552 0.4484695 0.4774022 0.08645331 0.4551953 0.5268458 0.09278559 0.4519062 0.5009776 0.1017549 0.4514017 0.5088055 0.01888859 0.4481127 0.4829373 0.02785795 0.4564098 0.5398534 0.06479936 0.4548385 0.5323809 0.03419023 0.4468982 0.4699297 0.05584412 0.6842736 0.4618328 0.03125846 0.6874039 0.4837863 0.0190314 0.6905242 0.505142 0.03322219 0.6908841 0.5002641 0.09374541 0.6879003 0.4775027 0.1030098 0.6828393 0.4557945 0.05877107 0.691971 0.5117127 0.0648384 0.6846268 0.4578605 0.08765435 0.8628704 0.4514805 0.0193634 0.866443 0.4670654 0.1144846 0.8630042 0.4534783 0.09540998 0.8604124 0.4528549 0.05839538 0.8690243 0.4796012 0.02630561 0.8659073 0.4647625 0.006335377 0.8693139 0.4833273 0.1027787 0.8705615 0.4843245 0.06625372 0.7864555 0.4607649 0.009515643 0.783861 0.4455807 0.01824021 0.8588501 0.4538585 -0.01108193 0.858614 0.4354407 8.64532e-4 0.05671924 -0.7048832 0.07492291 0.1100819 -0.7050647 0.07896763 0.06378859 -0.7005848 -0.0265814 0.03357261 -0.7026432 0.02710366 0.1171512 -0.7007662 -0.02253669 0.1402978 -0.7030062 0.03519308 0 0.7461411 0.07617628 0 0.7137517 -0.1156581 0.06976497 0.7530156 0.05431199 0.07291615 0.7431028 0.008685588 0.06794744 0.7331738 -0.03466409 0.04838448 0.7189331 -0.09377199 0.01909106 0.7123349 0.05854499 0.02103459 0.8696268 0.06342113 0.009039819 0.657003 -0.1053501 0.01967877 0.8747316 -0.090532 0.02305555 0.8900581 0.008994281 0.02273261 0.8912576 -0.03345847 0.02051818 0.7838504 0.08139401 0.02111047 0.8282164 0.07861745 0.01957851 0.8181964 -0.110518 0.01843059 0.773442 -0.1135401 0.01980465 0.7480926 0.06996947 0.01373517 0.7152225 -0.1094451 0.01656049 -0.1954255 -0.0231747 0.07274723 -0.1954255 -0.08043271 0.1581723 -0.1954255 -0.01563823 0.02193295 -0.1954255 0.05958074 0.1275486 -0.1954255 0.06721937 0.03075706 -0.1954255 -0.08424031 0.5603675 0.4740875 0.03272974 0.5634854 0.498062 0.02117294 0.5667597 0.5201651 0.03449147 0.5671351 0.5151417 0.09231507 0.5640013 0.4916983 0.1011663 0.5592031 0.4630349 0.05711817 0.5682777 0.526933 0.06469744 0.5607118 0.4703359 0.08606618 0.8654698 0.4646088 0.1109825 0.8696007 0.4827507 0.1039345 0.86443 0.4576198 0.09238308 0.8685609 0.4757617 0.08533507 0.9453653 0.4697838 0.09854924 0.9431693 0.4591111 0.0936436 0.9436109 0.4620792 0.1015424 0.9445391 0.4654284 0.09384059 0.9420582 0.4545325 0.0980736 0.9451637 0.469626 0.1050113 0.9426828 0.4587301 0.1092442 0.86628 0.4652432 0.08500701 0.8699362 0.4830135 0.09317511 0.8677505 0.4751272 0.1113106 0.8640944 0.457357 0.1031425 0.9440525 0.4650474 0.1094413 0.9418567 0.4543747 0.1045356 0.8959893 0.477632 0.1039152 0.8931936 0.4628919 0.08797955 0.8916358 0.4564735 0.09418964 0.8951138 0.4717478 0.0882557 0.8944315 0.4712136 0.1101253 0.8913533 0.4562522 0.1032484 0.8925113 0.4623578 0.1098492 0.8962718 0.4778532 0.0948565 0.9204287 0.4739223 0.1046588 0.918 0.4611184 0.09081643 0.916647 0.4555431 0.09621083 0.9164015 0.4553509 0.1040796 0.9196681 0.4688109 0.09105634 0.9190754 0.468347 0.1100532 0.9174075 0.4606544 0.1098133 0.9206739 0.4741144 0.09679007 0.8653622 0.4626087 0.06172025 0.869493 0.4807506 0.05467224 0.8643224 0.4556198 0.04312086 0.8684532 0.4737616 0.03607285 0.9858044 0.4695075 0.04928702 0.9836084 0.4588348 0.04438132 0.98405 0.4618029 0.05228018 0.9849783 0.4651521 0.04457837 0.9824974 0.4542562 0.04881137 0.9856029 0.4693496 0.05574905 0.9831219 0.4584537 0.059982 0.8661724 0.4632432 0.03574478 0.8698286 0.4810134 0.04391288 0.8676429 0.4731271 0.06204831 0.8639867 0.455357 0.05388027 0.9844916 0.464771 0.06017905 0.9822958 0.4540984 0.05527335 0.9102148 0.4762413 0.05465292 0.907419 0.4615013 0.03871726 0.9058613 0.4550828 0.04492741 0.9093391 0.470357 0.03899347 0.9086569 0.4698229 0.06086307 0.9055787 0.4548615 0.05398613 0.9067367 0.4609671 0.06058692 0.9104972 0.4764626 0.04559427 0.9474191 0.4730742 0.05539655 0.9449903 0.4602704 0.04155421 0.9436373 0.4546951 0.04694861 0.9433919 0.4545029 0.05481731 0.9466584 0.4679628 0.04179412 0.9460658 0.4674989 0.06079095 0.9443979 0.4598064 0.06055104 0.9476643 0.4732664 0.04752784 0.9367303 0.4658342 0.02330559 0.933464 0.4523742 0.03632879 0.9351319 0.4600667 0.0365687 0.9357245 0.4605307 0.01757186 0.932458 0.4470707 0.03059506 0.9327034 0.447263 0.02272635 0.9340564 0.4528383 0.01733195 0.9364851 0.465642 0.0311743 0.9037702 0.4692093 0.02137202 0.9000097 0.4537138 0.03636467 0.8988517 0.4476082 0.02976387 0.9019299 0.4625696 0.03664082 0.9026122 0.4631037 0.01477122 0.8991343 0.4478296 0.02070516 0.9006919 0.454248 0.01449501 0.9034878 0.468988 0.03043067 0.9734653 0.4467557 0.03105109 0.9756612 0.4574283 0.03595679 0.86357 0.448372 0.02965801 0.8672262 0.4661421 0.03782606 0.8694119 0.4740284 0.01969063 0.8657557 0.4562582 0.01152253 0.9742915 0.451111 0.03575974 0.9767724 0.4620069 0.0315268 0.9736669 0.4469135 0.02458912 0.9761478 0.4578093 0.02035611 0.9752196 0.4544602 0.02805793 0.9747779 0.451492 0.02015906 0.976974 0.4621648 0.02506476 0.8680365 0.4667766 0.01185059 0.8639057 0.4486348 0.0188986 0.8690763 0.4737656 0.03044998 0.8649455 0.4556238 0.03749799 0.9104184 0.4541124 0.002959966 0.9082223 0.4434397 -0.001945674 0.9086639 0.4464079 0.005953133 0.9095923 0.449757 -0.001748621 0.9071112 0.4388611 0.002484321 0.9102168 0.4539545 0.009422004 0.9077358 0.4430587 0.013655 0.9091055 0.4493759 0.013852 0.9069097 0.4387033 0.008946299 0.8610426 0.4619606 0.008325874 0.8582468 0.4472206 -0.007609724 0.8566889 0.4408021 -0.001399576 0.860167 0.4560763 -0.007333517 0.8594847 0.4555422 0.01453608 0.8564065 0.4405809 0.007659077 0.8575645 0.4466864 0.01425987 0.861325 0.4621819 -7.32757e-4 0.8854817 0.4582508 0.009069502 0.8830531 0.445447 -0.004772782 0.8817 0.4398717 6.21583e-4 0.8814545 0.4396796 0.008490264 0.8847212 0.4531396 -0.004532873 0.8841285 0.4526756 0.0144639 0.8824605 0.444983 0.01422399 0.8857269 0.4584431 0.001200795 0.9364138 0.4732781 0.07383358 0.9331476 0.4598181 0.08685678 0.9348154 0.4675107 0.08709675 0.9354081 0.4679746 0.06809991 0.9321415 0.4545146 0.08112311 0.9323869 0.4547068 0.07325434 0.93374 0.4602821 0.06786 0.9361687 0.4730859 0.08170235 0.9034537 0.4766531 0.07190001 0.8996932 0.4611576 0.08689266 0.8985352 0.4550521 0.08029186 0.9016134 0.4700134 0.08716887 0.9022957 0.4705476 0.06529927 0.8988178 0.4552734 0.07123321 0.9003755 0.4616918 0.06502306 0.9031714 0.4764319 0.08095872 0.9731489 0.4541995 0.08157914 0.9753447 0.4648722 0.08648478 0.8632536 0.4558158 0.080186 0.8669097 0.473586 0.08835411 0.8690954 0.4814723 0.07021862 0.8654392 0.463702 0.06205058 0.973975 0.4585549 0.08628779 0.976456 0.4694507 0.08205479 0.9733504 0.4543574 0.07511711 0.9758314 0.4652532 0.0708841 0.9749031 0.4619041 0.07858598 0.9744614 0.4589359 0.07068711 0.9766575 0.4696086 0.07559281 0.86772 0.4742205 0.06237864 0.8635892 0.4560786 0.06942659 0.8687598 0.4812095 0.08097803 0.864629 0.4630676 0.08802604 -0.06725132 0.7233154 0.04843622 -0.07409763 0.8640959 0.04852974 -0.03184431 0.6632936 -0.09416538 -0.06932163 0.864995 -0.08048981 -0.06158161 0.6886598 -0.03553307 -0.06859195 0.7061829 0.007524728 -0.08121687 0.871434 0.00881952 -0.08007913 0.8718743 -0.0346632 -0.07436501 0.8269675 0.05527436 -0.07227855 0.7827159 0.06018775 -0.06492465 0.7745726 -0.09337866 -0.06896835 0.8194977 -0.09084856 -0.07881098 0.8220392 -0.03684562 -0.07431328 0.7776878 -0.03379517 -0.07724028 0.7800226 0.009846389 -0.08073413 0.8243758 0.006829857 -0.1466862 0.1538009 0.06755244 -0.1892135 0.5700379 0.09274744 -0.07138669 0.08345532 -0.1065121 -0.1341176 0.5789203 -0.05284017 -0.1299207 0.2543504 0.07313078 -0.1053827 0.2651275 -0.1027395 -0.1871518 0.3686333 0.1079901 -0.1422255 0.3595595 -0.1286 -0.04103904 0.6865502 0.03497922 -0.04103904 0.6695708 -0.04532349 -0.1933467 0.4699194 0.07660758 -0.1625556 0.4651417 -0.1105885 -0.1383035 0.2040756 0.07034164 -0.08952623 0.1419116 -0.1175287 -0.1466861 0.1009141 -0.01752233 -0.1871023 0.5860964 0.002086579 -0.1299207 0.2489024 -0.02869874 -0.1841033 0.3572139 -0.01173281 -0.05803799 0.6780605 -0.005172073 -0.1912354 0.4859779 -0.01405316 -0.1383035 0.1729936 -0.03369176 -0.07872211 0.6373879 0.08105164 -0.06150025 0.6305531 -0.04670101 -0.07872211 0.6336538 0.01125448 -0.1603331 -0.02776277 -0.02889543 -0.1272936 -0.02776277 0.07906466 -0.03987193 -0.02776277 -0.1044155 -0.1529055 0.03621953 -0.04125523 -0.1499075 0.06994056 0.09381413 -0.05208736 0.04012161 -0.1153447 -0.1385688 -0.3725179 0.00126028 -0.108603 -0.3725178 0.04537951 -0.06215226 -0.3725178 -0.05064243 -0.1153436 -0.372518 -0.0467509 -0.05541151 -0.3725179 0.04148775 -0.03218621 -0.372518 -0.006523191 -0.1435203 -0.4766288 0.02890777 -0.1082584 -0.4766288 0.07825905 -0.05427747 -0.4766288 -0.02959161 -0.1165298 -0.4766288 -0.02501755 -0.04600608 -0.4766288 0.07368499 -0.01901561 -0.4766288 0.01975959 -0.1179746 -0.815149 0.01085764 -0.09648084 -0.8194054 0.04221558 -0.06316304 -0.8101418 -0.02603232 -0.1013157 -0.8105171 -0.02326631 -0.05832815 -0.8190301 0.03944951 -0.04166924 -0.8143981 0.005325555 -0.05521249 -0.5979837 0.08895218 -0.02599 -0.5979837 0.02830719 -0.1228194 -0.5979837 0.09419441 -0.06437444 -0.5979837 -0.02709555 -0.1319813 -0.5979837 -0.02185338 -0.1612038 -0.5979837 0.03879153 -0.1270821 -0.8989198 0.00528407 -0.1035308 -0.8989198 0.05807638 -0.06722432 -0.8989198 -0.03550797 -0.1089289 -0.8989198 -0.03239136 -0.06182622 -0.8989198 0.05495977 -0.04367297 -0.8989198 -9.49059e-4 -0.07238107 -0.8729894 -0.212285 -0.1161065 -0.8730859 -0.2115751 -0.1351986 -0.8742746 -0.2028175 -0.04774791 -0.8740817 -0.2042372 -0.03638011 -0.8989198 -0.2050544 -0.07227367 -0.8989198 -0.2168489 -0.1358339 -0.8989198 -0.2157853 -0.1635004 -0.8989198 -0.2029271 -0.04386603 -0.3426398 0.05136859 -0.02477848 -0.3426398 -0.01036179 -0.1143667 -0.3426398 0.05537402 -0.05317163 -0.3426398 -0.06285506 -0.1056225 -0.3426398 -0.05644989 -0.1425745 -0.3426398 -0.002380967 -0.02737385 -0.3982791 0.003080129 -0.05927491 -0.3982791 -0.0429508 -0.115777 -0.3982791 -0.03880983 -0.140378 -0.3982791 0.01136225 -0.1084771 -0.3982791 0.05739319 -0.05197489 -0.3982791 0.0532521 -0.1917174 0.511882 0.103454 -0.1873019 0.5968263 0.05075973 -0.193147 0.4591896 0.02793449 -0.1887316 0.5345921 -0.02475976 -0.3892558 0.5540321 0.06503957 -0.3879023 0.5388871 0.0945273 -0.3832473 0.5131938 0.004426181 -0.387948 0.5474473 0.03288102 -0.3782811 0.4679223 0.04336446 -0.3802581 0.477815 0.08540642 -0.3842896 0.5087608 0.1039779 -0.3796346 0.4830673 0.01387673 -0.3073278 0.5749695 0.0631048 -0.2992821 0.528962 -0.008572161 -0.2925196 0.4719955 0.07885032 -0.3045268 0.5513733 0.09931641 -0.3059278 0.5677596 0.01969408 -0.2911196 0.4647855 0.03543961 -0.2991654 0.5107931 0.1071166 -0.2939207 0.4883819 -7.71955e-4 -0.5178558 0.4813 0.03066152 -0.521227 0.496173 0.09846448 -0.5182157 0.4767222 0.08442473 -0.5168194 0.4705615 0.0563398 -0.5237292 0.5220979 0.0364716 -0.5207179 0.5026472 0.02243191 -0.5240892 0.5175201 0.09023481 -0.5251257 0.5282586 0.06455653 -0.7496774 0.458608 0.03048175 -0.7536202 0.4717426 0.09934371 -0.7503651 0.4538324 0.08557885 -0.7477804 0.453044 0.05886799 -0.755629 0.4977447 0.03571099 -0.7527132 0.4781761 0.02129983 -0.7562704 0.4931956 0.0908963 -0.7571026 0.5039662 0.06453877 -0.6184252 0.4666639 0.03493303 -0.6172494 0.4563034 0.05817848 -0.6214526 0.4918081 0.01717758 -0.6246237 0.5153057 0.02984327 -0.6249669 0.510181 0.09713989 -0.6260937 0.5222191 0.06499779 -0.618698 0.4644279 0.08986729 -0.6219035 0.486243 0.1074412 -0.5254341 0.4685065 0.05650633 -0.533991 0.5283208 0.06466519 -0.5268691 0.4749975 0.08505898 -0.5265089 0.479456 0.03085529 -0.5294555 0.501659 0.02181601 -0.5325542 0.521946 0.03583735 -0.532921 0.5172103 0.09102272 -0.529971 0.495123 0.09947013 -0.5167928 0.523872 0.03571861 -0.5110781 0.4766653 0.08517771 -0.5096338 0.4702555 0.05621081 -0.5171613 0.5191103 0.09117025 -0.514196 0.4969016 0.09965842 -0.5136749 0.5036356 0.02123796 -0.5107096 0.4814269 0.02972608 -0.5182369 0.5302819 0.06468552 -0.4484695 0.4774022 0.08645331 -0.4551953 0.5268458 0.09278559 -0.4519062 0.5009776 0.1017549 -0.4514017 0.5088055 0.01888859 -0.4481127 0.4829373 0.02785795 -0.4564098 0.5398534 0.06479936 -0.4548385 0.5323809 0.03419023 -0.4468982 0.4699297 0.05584412 -0.6842737 0.4618328 0.03125846 -0.687404 0.4837863 0.0190314 -0.6905243 0.505142 0.03322219 -0.6908842 0.5002641 0.09374541 -0.6879004 0.4775027 0.1030098 -0.6828395 0.4557945 0.05877107 -0.6919711 0.5117127 0.0648384 -0.6846269 0.4578605 0.08765435 -0.8628705 0.4514805 0.0193634 -0.8664431 0.4670654 0.1144846 -0.8630043 0.4534783 0.09540998 -0.8604125 0.4528549 0.05839538 -0.8690245 0.4796012 0.02630561 -0.8659074 0.4647625 0.006335377 -0.869314 0.4833273 0.1027787 -0.8705617 0.4843245 0.06625372 -0.7864556 0.4607649 0.009515643 -0.7838611 0.4455807 0.01824021 -0.8588503 0.4538585 -0.01108193 -0.8586141 0.4354407 8.64532e-4 -0.05671924 -0.7048832 0.07492291 -0.1100819 -0.7050647 0.07896763 -0.06378859 -0.7005848 -0.0265814 -0.03357261 -0.7026432 0.02710366 -0.1171512 -0.7007662 -0.02253669 -0.1402978 -0.7030062 0.03519308 -0.06976497 0.7530156 0.05431199 -0.07291615 0.7431028 0.008685588 -0.06794744 0.7331738 -0.03466409 -0.04838448 0.7189331 -0.09377199 -0.01909106 0.7123349 0.05854499 -0.02103459 0.8696268 0.06342113 -0.009039819 0.657003 -0.1053501 -0.01967877 0.8747316 -0.090532 -0.02305555 0.8900581 0.008994281 -0.02273255 0.8912576 -0.03345847 -0.02051818 0.7838504 0.08139401 -0.02111047 0.8282164 0.07861745 -0.01957851 0.8181964 -0.110518 -0.01843059 0.773442 -0.1135401 -0.01980459 0.7480926 0.06996947 -0.01373517 0.7152225 -0.1094451 -0.01656043 -0.1954255 -0.0231747 -0.07274723 -0.1954255 -0.08043271 -0.1581723 -0.1954255 -0.01563823 -0.02193295 -0.1954255 0.05958074 -0.1275486 -0.1954255 0.06721937 -0.03075706 -0.1954255 -0.08424031 -0.5603677 0.4740875 0.03272974 -0.5634855 0.498062 0.02117294 -0.5667598 0.5201651 0.03449147 -0.5671352 0.5151417 0.09231507 -0.5640014 0.4916983 0.1011663 -0.5592032 0.4630349 0.05711817 -0.5682778 0.526933 0.06469744 -0.5607119 0.4703359 0.08606618 -0.8654699 0.4646088 0.1109825 -0.8696008 0.4827507 0.1039345 -0.8644301 0.4576198 0.09238308 -0.868561 0.4757617 0.08533507 -0.9453654 0.4697838 0.09854924 -0.9431694 0.4591111 0.0936436 -0.943611 0.4620792 0.1015424 -0.9445393 0.4654284 0.09384059 -0.9420583 0.4545325 0.0980736 -0.9451639 0.469626 0.1050113 -0.9426829 0.4587301 0.1092442 -0.8662801 0.4652432 0.08500701 -0.8699363 0.4830135 0.09317511 -0.8677507 0.4751272 0.1113106 -0.8640945 0.457357 0.1031425 -0.9440526 0.4650474 0.1094413 -0.9418568 0.4543747 0.1045356 -0.8959894 0.477632 0.1039152 -0.8931937 0.4628919 0.08797955 -0.8916359 0.4564735 0.09418964 -0.8951139 0.4717478 0.0882557 -0.8944317 0.4712136 0.1101253 -0.8913534 0.4562522 0.1032484 -0.8925114 0.4623578 0.1098492 -0.8962719 0.4778532 0.0948565 -0.9204288 0.4739223 0.1046588 -0.9180001 0.4611184 0.09081643 -0.9166471 0.4555431 0.09621083 -0.9164016 0.4553509 0.1040796 -0.9196683 0.4688109 0.09105634 -0.9190756 0.468347 0.1100532 -0.9174076 0.4606544 0.1098133 -0.920674 0.4741144 0.09679007 -0.8653623 0.4626087 0.06172025 -0.8694931 0.4807506 0.05467224 -0.8643225 0.4556198 0.04312086 -0.8684533 0.4737616 0.03607285 -0.9858046 0.4695075 0.04928702 -0.9836085 0.4588348 0.04438132 -0.9840501 0.4618029 0.05228018 -0.9849784 0.4651521 0.04457837 -0.9824975 0.4542562 0.04881137 -0.985603 0.4693496 0.05574905 -0.9831221 0.4584537 0.059982 -0.8661726 0.4632432 0.03574478 -0.8698287 0.4810134 0.04391288 -0.867643 0.4731271 0.06204831 -0.8639869 0.455357 0.05388027 -0.9844917 0.464771 0.06017905 -0.9822959 0.4540984 0.05527335 -0.9102149 0.4762413 0.05465292 -0.9074191 0.4615013 0.03871726 -0.9058614 0.4550828 0.04492741 -0.9093393 0.470357 0.03899347 -0.908657 0.4698229 0.06086307 -0.9055788 0.4548615 0.05398613 -0.9067368 0.4609671 0.06058692 -0.9104973 0.4764626 0.04559427 -0.9474192 0.4730742 0.05539655 -0.9449905 0.4602704 0.04155421 -0.9436374 0.4546951 0.04694861 -0.943392 0.4545029 0.05481731 -0.9466586 0.4679628 0.04179412 -0.9460659 0.4674989 0.06079095 -0.9443981 0.4598064 0.06055104 -0.9476644 0.4732664 0.04752784 -0.9367305 0.4658342 0.02330559 -0.9334641 0.4523742 0.03632879 -0.935132 0.4600667 0.0365687 -0.9357246 0.4605307 0.01757186 -0.9324581 0.4470707 0.03059506 -0.9327035 0.447263 0.02272635 -0.9340565 0.4528383 0.01733195 -0.9364852 0.465642 0.0311743 -0.9037703 0.4692093 0.02137202 -0.9000098 0.4537138 0.03636467 -0.8988518 0.4476082 0.02976387 -0.90193 0.4625696 0.03664082 -0.9026123 0.4631037 0.01477122 -0.8991344 0.4478296 0.02070516 -0.9006921 0.454248 0.01449501 -0.9034879 0.468988 0.03043067 -0.9734655 0.4467557 0.03105109 -0.9756613 0.4574283 0.03595679 -0.8635702 0.448372 0.02965801 -0.8672263 0.4661421 0.03782606 -0.869412 0.4740284 0.01969063 -0.8657559 0.4562582 0.01152253 -0.9742916 0.451111 0.03575974 -0.9767725 0.4620069 0.0315268 -0.973667 0.4469135 0.02458912 -0.976148 0.4578093 0.02035611 -0.9752197 0.4544602 0.02805793 -0.9747781 0.451492 0.02015906 -0.9769741 0.4621648 0.02506476 -0.8680366 0.4667766 0.01185059 -0.8639058 0.4486348 0.0188986 -0.8690764 0.4737656 0.03044998 -0.8649456 0.4556238 0.03749799 -0.9104185 0.4541124 0.002959966 -0.9082224 0.4434397 -0.001945674 -0.9086641 0.4464079 0.005953133 -0.9095924 0.449757 -0.001748621 -0.9071114 0.4388611 0.002484321 -0.9102169 0.4539545 0.009422004 -0.907736 0.4430587 0.013655 -0.9091057 0.4493759 0.013852 -0.9069098 0.4387033 0.008946299 -0.8610427 0.4619606 0.008325874 -0.8582469 0.4472206 -0.007609724 -0.856689 0.4408021 -0.001399576 -0.8601671 0.4560763 -0.007333517 -0.8594848 0.4555422 0.01453608 -0.8564066 0.4405809 0.007659077 -0.8575646 0.4466864 0.01425987 -0.8613252 0.4621819 -7.32757e-4 -0.8854818 0.4582508 0.009069502 -0.8830532 0.445447 -0.004772782 -0.8817001 0.4398717 6.21583e-4 -0.8814547 0.4396796 0.008490264 -0.8847213 0.4531396 -0.004532873 -0.8841286 0.4526756 0.0144639 -0.8824606 0.444983 0.01422399 -0.8857271 0.4584431 0.001200795 -0.936414 0.4732781 0.07383358 -0.9331477 0.4598181 0.08685678 -0.9348155 0.4675107 0.08709675 -0.9354082 0.4679746 0.06809991 -0.9321416 0.4545146 0.08112311 -0.9323871 0.4547068 0.07325434 -0.9337401 0.4602821 0.06786 -0.9361688 0.4730859 0.08170235 -0.9034538 0.4766531 0.07190001 -0.8996933 0.4611576 0.08689266 -0.8985353 0.4550521 0.08029186 -0.9016135 0.4700134 0.08716887 -0.9022958 0.4705476 0.06529927 -0.8988179 0.4552734 0.07123321 -0.9003756 0.4616918 0.06502306 -0.9031715 0.4764319 0.08095872 -0.973149 0.4541995 0.08157914 -0.9753448 0.4648722 0.08648478 -0.8632537 0.4558158 0.080186 -0.8669098 0.473586 0.08835411 -0.8690955 0.4814723 0.07021862 -0.8654394 0.463702 0.06205058 -0.9739751 0.4585549 0.08628779 -0.9764561 0.4694507 0.08205479 -0.9733505 0.4543574 0.07511711 -0.9758315 0.4652532 0.0708841 -0.9749032 0.4619041 0.07858598 -0.9744616 0.4589359 0.07068711 -0.9766576 0.4696086 0.07559281 -0.8677201 0.4742205 0.06237864 -0.8635893 0.4560786 0.06942659 -0.8687599 0.4812095 0.08097803 -0.8646291 0.4630676 0.08802604 + + + + + + + + + + 0.9892109 -0.1041101 0.103068 0.386828 0.3183112 0.8654723 0.3979624 -0.09626644 -0.912337 0.3021122 0.911219 -0.2800147 0.3572784 -0.2907155 0.8876017 0.9988095 -0.02354627 -0.04272139 0.9795474 -0.1372095 -0.147175 0.2870689 0.8932481 0.3459761 0.9739232 -0.01486963 -0.2263904 0.2480421 0.3224936 -0.9134949 0.9916154 -0.1142422 -0.060395 0.3049342 0.9520562 0.02457994 0.3795642 0.04015576 0.9242935 0.3682524 0.05323183 -0.9282007 0.9946352 -0.0825873 -0.06229108 0.9886372 -0.06878805 0.1336587 0.9786071 -0.1111484 -0.1731302 0.9912159 0.03051519 0.1286851 0.1541727 0.1853095 0.9705107 0.6442092 0.3694566 -0.6696987 0.9497107 0.1237967 -0.2876176 0 -0.05539351 0.9984646 0.8668302 -0.3837681 -0.3183197 0 -0.4646174 0.8855115 0.807321 0.5892698 -0.03152579 -2.42421e-7 0.03528326 -0.9993774 0.9603253 -0.05810719 -0.272762 0.1473 0.08719384 0.9852411 0 -0.05663251 0.9983951 0.8661219 -0.01136922 -0.4997035 0.9847019 0.1669552 -0.0498811 0.9950737 -0.05658352 -0.08140403 0.9047946 0.3157365 -0.2857572 0.8914443 -0.4526674 0.02047687 0.9862645 0.164938 -0.008824169 0 -0.1851995 -0.9827009 0.1109472 0.1463277 -0.9829948 0.00337255 -0.2653499 -0.9641463 0 0.1191721 -0.9928736 0 0.6838048 0.7296651 0.9683468 -0.2362778 0.08048206 0.07688128 0.4664646 -0.8811925 0.1490195 0.4014077 0.9036952 0.3320318 0.8395674 -0.4299785 0.09087991 0.2426548 -0.9658465 0.4211201 0.7732085 0.4741377 -0.05350303 -0.3321063 0.9417233 -0.937014 -0.1950907 0.289732 0.1236155 -0.176039 0.9765907 0.5705664 -0.2296158 -0.7884989 0.6966104 0.305166 -0.6493133 0.002248048 0.2989262 0.9542736 0.9992842 0.03213006 -0.01997417 0.8957511 -0.06871044 -0.439214 -0.8210926 -0.04465347 -0.5690459 0.113711 -0.3464318 -0.9311578 -0.799438 -0.4170385 -0.4324091 0.822612 0.08514463 -0.5621922 0.8557712 -0.304899 0.4179621 -0.07316827 -0.2972875 0.9519804 -0.8932492 -0.14485 0.4255871 0.8115245 0.158493 0.5624126 -0.8821706 0.1861942 0.4325581 -0.07064199 0.2568881 0.9638559 0.07199954 -0.1722484 -0.9824187 0.5780757 0.7972158 -0.1739982 0 -1 0 0.0755648 -0.004273951 -0.9971318 -0.8715252 0.0322082 -0.4892917 0.9219107 -0.1024407 -0.373613 0.7986873 -0.2681554 0.538694 0.8026756 0.1636735 0.5735181 0.8896101 0.1016595 -0.4452633 -0.8105362 -0.08737415 -0.5791346 0.07327145 -0.0144146 -0.9972079 -0.8940664 -0.01986408 0.4474937 -0.07275819 0.1190562 0.9902181 0 -1 0 0 -1 0 0.8204876 0.05132156 0.5693559 -0.9001892 -0.05342626 0.4322093 -0.06919878 0.1872097 0.9798796 -0.9994995 -0.02200776 -0.02272385 0.3976117 0.4352651 -0.8077433 -0.3128861 0.1658951 -0.9351904 0.0163694 0.1732529 -0.9847413 0 -1 0 0 -1 0 0.03238403 0.9474993 -0.3181139 0.9932018 0.1045786 0.05112236 -0.5226539 0.8158264 -0.247508 0.1513023 -0.9608915 0.2319379 0.6896257 -0.7232264 -0.03687572 0.9378876 -0.3467457 -0.01158571 0.7667317 -0.4801382 0.4261336 0.2858345 -0.5024609 0.8159851 0.03608834 -0.9920325 0.1207031 0.711286 -0.6853201 -0.1562325 0.7281244 -0.6234186 0.2849282 0.2883951 -0.4990726 0.8171626 0.9358144 -0.06800496 0.3458709 0.604315 0.005157411 -0.7967287 -0.9584181 -0.1782945 -0.2228135 0.08954453 -0.1298145 -0.9874867 -0.9966509 -0.05000525 0.06470298 -0.07197749 -0.06624013 0.9952043 0.06976789 -0.2927876 -0.9536288 -0.06615543 0.4219868 0.9041851 -0.8547306 0.3138056 0.4134752 0.796922 0.2682213 0.5412694 -0.8248928 -0.07514852 -0.560272 0.8938878 -0.118254 -0.4324125 0.0247662 -0.160278 -0.9867612 0.02994322 -0.1602553 -0.9866213 0.1412579 -0.3116959 -0.9396232 0.2621552 0.950583 -0.1663329 0.01924186 -0.5163249 0.8561766 0.07316255 -0.8885112 -0.4529846 0.227494 0.5476539 -0.8051842 0.1953119 0.8147078 0.5459895 0.04758769 -0.9728084 0.22667 0.09774237 0.2871931 0.9528728 -0.02690178 0.1798721 0.9833221 0.0169571 -0.9864328 0.1632875 0.09841603 0.8409674 0.5320602 0.1515184 0.4606506 -0.8745532 0.08912634 -0.837626 -0.538924 -0.03355425 -0.5847581 0.8105135 0.1797055 0.9604995 -0.2124776 0.1302704 -0.2037244 -0.9703226 0.03022766 -0.9766428 0.2127326 0.2001283 0.3289599 0.9228944 0.2139494 0.5464429 -0.8097072 0.07508569 -0.591234 0.8029971 0.2671164 0.8851682 0.3809541 0.0461719 -0.922254 -0.3838172 0.1140794 -0.370642 -0.9217432 0.2641089 0.9388512 -0.2209185 -0.0409922 -0.9754812 -0.2162319 -0.03418743 -0.4825674 -0.8751913 0.07576644 0.544155 -0.8355566 0.1110141 0.918741 0.3789337 -0.06001353 -0.9975749 0.03525137 0.1182605 0.9711168 -0.2072358 0.0791257 0.3567544 0.9308413 -0.009043991 -0.6083136 0.7936453 -0.1419395 -0.6082586 0.7809447 -0.04213517 0.3994789 0.9157735 0.06649297 0.9785046 -0.1952113 -0.1144121 -0.9610381 0.251626 0.07264918 0.9161662 0.3941594 -0.003299653 0.5164662 -0.8563013 -0.02100831 -0.4319149 -0.9016696 -0.09772658 -0.9071653 -0.4092684 -0.2063531 -0.8967678 -0.3914409 -0.05804997 -0.3698148 -0.9272903 0.008888781 0.584343 -0.8114581 -0.01120114 0.9226791 0.3854063 -0.2063316 -0.9518449 0.2267568 0.001411974 0.97676 -0.2143315 -0.07005804 0.3644931 0.9285669 -0.1606434 -0.5581462 0.8140433 0.1378826 0.9605376 -0.2415695 0.02020895 -0.3298249 -0.9438258 0.007171511 -0.9069307 -0.4212188 0.1394348 0.8956498 0.4223379 -0.01060956 -0.5808191 0.8139635 0.07616025 0.5350115 -0.841405 0.0678482 0.348273 0.9349346 -0.007082104 -0.9762824 0.2163855 -0.009525716 -0.9713133 0.2376127 0.07659405 0.2900632 0.9539375 0.2019467 0.6092831 -0.7668061 -0.03458619 -0.5405511 0.8406 0.1854499 0.8706189 0.4556655 0.1020344 -0.9037874 -0.4156408 0.1893194 -0.3144993 -0.9301872 0.2189037 0.9541251 -0.2042704 -0.02811795 -0.6127377 0.7897859 0.102366 0.3634706 0.9259645 0.1592955 0.9673948 -0.1969069 -0.09627056 -0.9923768 0.07694351 0.1472514 0.9176954 0.3689882 0.08127307 0.4643896 -0.8818939 -0.0873261 -0.5675864 -0.8186696 -0.003406524 -0.9133155 -0.4072386 0.1469666 0.9816242 -0.1217165 -0.03365188 0.5877929 0.8083112 -0.1123096 -0.7996611 0.5898548 -0.002454876 -0.9812922 -0.1925088 -0.4386112 -0.3902069 -0.8095422 0.01591479 0.8013805 -0.5979432 0.1523763 0.9131914 0.3779718 -0.004641234 -0.9998419 0.01716285 -0.2596173 -0.4473868 -0.8558293 -0.05914008 0.4783867 -0.8761556 0.04754287 -0.7600731 0.6480962 0.9456669 -0.1853826 -0.2671092 0.9517541 -0.3068616 -3.42063e-4 0.8085462 -0.1801439 0.5601798 0.8889277 -0.1622742 -0.4283393 -0.8208414 -0.05292999 -0.5686983 0.07730656 -0.004526197 -0.9969971 -0.8986897 -0.06949883 0.4330436 -0.07663661 -0.131427 0.9883591 0.9897139 -0.1131663 -0.0875194 0.9501959 -0.1303589 -0.2830799 0.2607684 -0.2985297 0.9180849 0.418809 -0.0972802 -0.9028486 0.990682 -0.1017538 0.09052813 0.4197325 -0.1184133 -0.8998905 0.2645652 -0.3242647 0.9082167 0.3694864 0.01906377 -0.9290405 0.3795773 0.05273705 0.9236558 0.3049647 0.9523622 0.001663863 0.2338472 0.2141158 -0.9484038 0.2977657 0.927786 0.2248302 0.3539721 -0.314476 0.8808 0.3089522 0.9272134 -0.2117159 0.3976336 -0.1117674 -0.9107117 0.3808692 0.3654264 0.849354 -0.0880438 -0.06021845 0.9942947 -0.9951574 -0.09829425 0 0.03011226 -0.1210293 -0.9921921 -0.9835869 -0.1804351 0 0.5310937 -0.01704001 -0.8471418 0.9561676 0.01081436 0.29262 -0.1382545 -0.8995858 -0.4142838 -0.01861298 -0.4321886 -0.9015911 0.04396909 0.5634636 -0.82497 0.03680831 0.9185112 0.3936778 -0.1394249 -0.9584177 0.2489907 0.04219996 0.9750961 -0.2177311 -0.01385873 0.3548076 0.9348366 -0.09765416 -0.5643823 0.8197172 -0.112146 -0.006672859 0.9936694 0.03785294 0.9989558 0.02558046 -0.01979398 0.03545719 -0.9991751 -0.9768141 0.2125924 -0.02527338 -0.9768103 0.2126086 -0.02527874 -0.1073554 -0.6777516 -0.7274116 -0.02467697 0.6982269 0.7154511 -0.9768126 0.2125993 -0.02527606 -0.9768143 0.2125926 -0.02526402 -0.1729345 -0.7077372 0.6849831 0.04022026 0.7299895 -0.6822739 -0.1706504 -0.9848936 -0.02937924 -0.1903579 -0.9812593 -0.02990227 0.03227019 0.7308984 -0.6817229 -0.1819956 -0.7057303 0.6847061 -0.01818048 0.6975077 0.7163467 -0.1310269 -0.6727488 -0.7281764 -0.03855919 0.03950297 -0.9984752 0.04038208 0.9988549 0.0256536 -0.1103852 -0.007061362 0.9938638 -0.1491567 -0.9883944 -0.02878981 0.04888814 0.7289419 -0.6828278 -0.1630566 -0.7098599 0.6852092 -0.03173297 0.6989681 0.7144485 -0.08154422 -0.6827431 -0.7260938 6.82091e-4 0.03102481 -0.9995184 0.03510272 0.9990585 0.02549582 -0.1140599 -0.006250679 0.9934542 -0.07356333 -0.01514703 0.9971755 0.01010304 0.999643 0.0247358 -0.01349306 0.03409469 -0.9993275 -0.9768182 0.2125746 -0.02526646 -0.9768087 0.2126168 -0.02527648 -0.0602743 -0.6864925 -0.7246345 -0.02639675 0.6984106 0.7152103 -0.9768085 0.212617 -0.02528291 -0.9768155 0.212588 -0.02525693 -0.1026754 -0.7211841 0.6850922 0.01559394 0.7326565 -0.6804199 -0.09679734 -0.9949293 -0.027314 -0.1100331 -0.993542 -0.02769619 0.0104646 0.7331563 -0.6799798 -0.1089144 -0.7201458 0.6852208 -0.0221098 0.6979455 0.7158096 -0.07605791 -0.68374 -0.7257512 -0.02590578 0.03677499 -0.9989877 0.01184415 0.9996225 0.02478784 -0.07251769 -0.01537913 0.9972485 -0.08425474 -0.9960796 -0.02695125 0.02191084 0.7320142 -0.6809369 -0.09772187 -0.7219905 0.6849673 -0.0310564 0.6989001 0.7145448 -0.04420506 -0.6891096 -0.7233076 8.58024e-6 0.03117156 -0.9995141 0.008938848 0.999655 0.02469801 -0.07576262 -0.01466739 0.997018 0.01789659 0.7324262 -0.6806112 -0.08959704 -0.9956091 -0.02711004 -0.09580028 -0.7222968 0.6849158 -0.02076709 0.6977998 0.7159918 -0.03023064 0.03770798 -0.9988314 0.01319569 0.732892 -0.680217 -0.1339257 -0.7156739 0.6854742 0.02155739 0.9994528 0.0250867 -0.1374774 -0.9900956 -0.02847152 -0.08548641 -0.01253622 0.9962605 -0.9768142 0.212593 -0.02526307 -0.09484928 -0.6802315 -0.7268348 -0.05340856 -0.6876336 -0.7240908 -0.08524346 -0.01258754 0.9962806 0.02855134 0.7313084 -0.6814491 -0.03122425 0.698915 0.7145228 1.74888e-4 0.03113561 -0.9995151 0.01537239 0.9995719 0.02489668 -0.1138572 -0.7193004 0.6853053 -0.1002343 -0.9945861 -0.02741652 -0.9768106 0.2126073 -0.02528071 -0.06977593 -0.01597821 0.9974347 -0.01287692 0.03396153 -0.9993402 -0.05567526 -0.6872623 -0.7242726 -0.02656292 0.6984311 0.7151841 0.007406651 0.9996688 0.02464771 -0.9768161 0.2125834 -0.02527147 -0.9768102 0.2126098 -0.02527767 -0.1121451 -0.006671488 0.9936695 0.03785324 0.998956 0.02557665 -0.01979416 0.03545629 -0.9991752 -0.9768143 0.2125914 -0.02527296 -0.9768088 0.2126163 -0.02527749 -0.1073565 -0.6777564 -0.7274069 -0.02467781 0.6982256 0.7154524 -0.9768087 0.2126161 -0.02528256 -0.9768142 0.212593 -0.02526307 -0.1729336 -0.7077413 0.684979 0.04022008 0.7299933 -0.6822698 -0.1706484 -0.9848938 -0.02938371 -0.1491595 -0.9883938 -0.02879482 0.04888784 0.7289419 -0.6828277 -0.1630595 -0.7098633 0.6852049 -0.03173345 0.698968 0.7144486 -0.08154487 -0.6827446 -0.7260925 6.82505e-4 0.03102588 -0.9995184 0.03510385 0.9990583 0.02549892 -0.1140605 -0.006250917 0.9934542 0.01789659 0.7324249 -0.6806125 -0.08959764 -0.995609 -0.02711313 -0.09580069 -0.722297 0.6849154 -0.02076786 0.6977978 0.7159936 -0.03023082 0.03770792 -0.9988315 0.01319605 0.7328919 -0.6802171 -0.1339263 -0.7156742 0.6854737 0.02155739 0.9994528 0.0250867 -0.1374774 -0.9900957 -0.02847069 -0.08548629 -0.01253587 0.9962605 -0.9768156 0.2125871 -0.0252574 -0.09485054 -0.6802325 -0.7268336 -0.0534079 -0.6876322 -0.7240923 -0.08524352 -0.01258754 0.9962806 0.02855068 0.7313082 -0.6814494 -0.03122431 0.6989148 0.714523 1.75114e-4 0.03113639 -0.9995151 0.0153715 0.9995719 0.02489662 -0.1138558 -0.7192972 0.6853089 -0.1002343 -0.9945859 -0.0274195 -0.9768084 0.212617 -0.02528375 -0.06977564 -0.01597648 0.9974348 -0.0128771 0.03396058 -0.9993402 -0.05567598 -0.6872621 -0.7242727 -0.02656352 0.698431 0.7151844 0.007405519 0.9996685 0.02465683 -0.9768159 0.2125839 -0.02527087 -0.976808 0.2126209 -0.02526736 -0.9884612 -0.1187292 0.09406286 -0.3868279 0.3183112 0.8654722 -0.4184271 -0.08961862 -0.9038181 -0.2422898 0.9211348 -0.3046414 -0.3111631 -0.2097139 0.9269291 -0.9996136 -0.009144544 -0.02624797 -0.9305749 -0.2749262 -0.2417558 -0.287069 0.893248 0.345976 -0.9829612 0.03351688 -0.1807321 -0.3398381 0.3423089 -0.8759765 -0.9868844 -0.1395477 -0.08115255 -0.3049343 0.9520562 0.02457994 -0.4019384 0.05184662 0.9141977 -0.3682524 0.05323177 -0.9282007 -0.9939026 -0.1034213 -0.03823202 -0.9943517 -0.03578913 0.09991949 -0.9786071 -0.1111484 -0.1731302 -0.9912159 0.03051519 0.1286851 -0.1541727 0.1853095 0.9705107 -0.6722882 0.4617269 -0.5786509 -0.8716286 -0.053689 -0.4872177 0 -0.05539321 0.9984647 -0.8280422 -0.4236363 -0.3672578 0 -0.4646174 0.8855115 -0.8379997 0.483734 0.2525039 -0.3763101 -0.3657525 -0.8512437 -0.9335401 -0.122271 -0.3369758 -0.1473 0.08719384 0.9852411 4.17114e-4 -0.05546301 0.9984607 -0.7498043 -0.339681 -0.5678119 -0.9928558 0.1013352 -0.06299567 -0.9950737 -0.05658352 -0.08140403 -0.7942925 0.4316291 -0.4275462 -0.8925641 -0.4502766 0.02408981 -0.99316 0.1118749 -0.03342473 -0.1525924 9.26376e-5 -0.9882892 1.51087e-4 -0.02098524 -0.9997798 0 -0.2689219 -0.963162 0 0.1191722 -0.9928737 0 0.6838048 0.7296651 -0.9683468 -0.2362778 0.08048206 -0.07688134 0.4664646 -0.8811923 -0.1490195 0.4014078 0.9036952 -0.5550583 0.8053788 -0.2080268 2.2773e-7 0.3414732 -0.9398915 -0.3371583 0.9401035 -0.05029505 0.05350303 -0.3321063 0.9417233 0.9370139 -0.1950907 0.289732 0.07994467 -0.4225014 0.9028298 -0.5284286 -0.1014805 -0.8428909 -0.6966105 0.3051659 -0.6493133 -0.1017684 0.4532731 0.8855431 -0.9992842 0.03213006 -0.01997417 -0.8923963 -0.06423294 -0.4466578 0.8210925 -0.04465347 -0.5690459 -0.06988793 -0.2873592 -0.9552698 0.7994381 -0.4170385 -0.4324092 -0.8869144 -0.1711966 -0.4290391 -0.8557712 -0.304899 0.417962 0.07195448 -0.2969248 0.952186 0.8966405 -0.1463912 0.4178579 -0.804342 0.15081 0.5747088 0.8821706 0.1861943 0.4325582 0.07082259 0.2567646 0.9638755 -0.0719996 -0.1722484 -0.9824187 -0.5780757 0.7972158 -0.1739982 0 -1 0 -0.0755648 -0.004273951 -0.9971318 0.8249545 0.001877963 -0.565196 -0.9219107 -0.1024407 -0.3736129 -0.7986873 -0.2681554 0.538694 -0.8099066 0.1708598 0.5611223 -0.8967524 0.09547847 -0.4321098 0.819369 -0.0798493 -0.5676782 -0.07729727 -0.01615047 -0.9968773 0.8940664 -0.01986408 0.4474937 0.07275819 0.1190563 0.9902181 0 -1 0 0 -1 0 -0.9014587 0.1601434 0.4021523 0.9001892 -0.05342626 0.4322093 0.06919878 0.1872097 0.9798796 0.9994995 -0.02200776 -0.02272385 -0.3787636 0.4385838 -0.8149739 0.312886 0.1658951 -0.9351904 -0.01647913 0.1730729 -0.9847711 0 -1 0 0 -1 0 -0.007206559 0.949131 -0.314799 -0.6526672 0.7489948 0.1141583 0.1469138 0.9350052 -0.3227718 -0.1513023 -0.9608915 0.2319378 -0.6896257 -0.7232264 -0.03687572 -0.9378876 -0.3467457 -0.01158571 -0.7667317 -0.4801382 0.4261336 -0.2858338 -0.5024614 0.8159851 -0.03608834 -0.9920325 0.1207031 -0.711286 -0.6853201 -0.1562325 -0.7281244 -0.6234186 0.2849282 -0.2883951 -0.4990726 0.8171626 -0.8925945 -0.1150026 0.4359467 -0.8178272 -0.1369842 -0.5589222 0.9584181 -0.1782945 -0.2228135 -0.1201334 -0.1334357 -0.9837493 0.9966509 -0.05000525 0.06470298 0.07197743 -0.06624013 0.9952043 -0.06976789 -0.2927876 -0.9536288 0.06627464 0.4217919 0.9042673 0.8547305 0.3138058 0.4134752 -0.7951516 0.2531019 0.5510656 0.8248928 -0.0751484 -0.560272 -0.8925302 -0.10893 -0.4376347 -0.05958807 0.1738171 -0.9829735 -0.02679419 -0.1635901 -0.9861645 -0.1126963 -0.2018982 -0.9729012 -0.2621552 0.950583 -0.1663329 0.02162379 -0.5862906 0.8098121 -0.04085254 -0.838564 -0.5432693 -0.227494 0.5476539 -0.8051843 -0.1953119 0.8147078 0.5459895 -0.02066409 -0.9863832 0.1631597 -0.04059505 0.1834312 0.982194 0.02690178 0.1798721 0.9833221 -0.03926992 -0.9758334 0.2149581 -0.09841603 0.8409674 0.5320602 -0.1515184 0.4606506 -0.8745532 -0.08927589 -0.8378205 -0.5385968 0.007759869 -0.5391136 0.8421972 -0.1797055 0.9604994 -0.2124776 -0.1314351 -0.2067537 -0.9695245 -0.03772777 -0.9760814 0.2141069 -0.1910935 0.3280676 0.9251242 -0.2139494 0.5464429 -0.8097072 -0.08945035 -0.5886787 0.8034027 -0.255532 0.8870356 0.3845403 -0.0343303 -0.9213422 -0.3872338 -0.1051242 -0.36725 -0.9241626 -0.2641089 0.9388511 -0.2209185 0.04099214 -0.9754812 -0.2162319 0.03418743 -0.4825674 -0.8751913 -0.07576644 0.544155 -0.8355566 -0.1157706 0.9219887 0.3695049 0.04230958 -0.9963685 0.07388955 -0.1182605 0.9711168 -0.2072358 -0.0837959 0.3662232 0.9267464 0.01275086 -0.6145241 0.7887951 0.1110014 -0.5621908 0.8195244 0.06689327 0.3602434 0.9304568 -0.08038288 0.9717792 -0.2217739 0.1160601 -0.961632 0.2485837 -0.07264918 0.9161662 0.3941594 0.003299653 0.5164662 -0.8563013 0.02100831 -0.4319149 -0.9016696 0.09991413 -0.9044712 -0.4146673 0.1840536 -0.9041485 -0.3855383 0.1048053 -0.3454656 -0.9325607 -0.00888884 0.584343 -0.8114581 0.0112012 0.9226791 0.3854063 0.230392 -0.9480381 0.2194156 -0.001411914 0.97676 -0.2143315 0.06278407 0.3663213 0.9283678 0.1709023 -0.5591278 0.8112759 -0.1378824 0.9605377 -0.2415695 -0.02020895 -0.3298249 -0.9438259 -0.007171511 -0.9069307 -0.4212188 -0.1394345 0.8956499 0.422338 -0.01065385 -0.5454903 0.8380494 -0.07616007 0.5350115 -0.8414049 -0.05283886 0.3211377 0.9455574 -0.003660261 -0.9715069 0.236983 0.01329219 -0.9731889 0.2296224 -0.07659405 0.2900632 0.9539375 -0.2019468 0.6092832 -0.7668061 0.01627707 -0.5129503 0.858264 -0.1854499 0.8706189 0.4556654 -0.09053879 -0.8875637 -0.4517004 -0.1893194 -0.3144993 -0.9301872 -0.2189038 0.9541251 -0.2042704 0.03592306 -0.6237311 0.7808131 -0.1120456 0.3806634 0.9179004 -0.1592955 0.9673948 -0.1969069 0.009761571 -0.9685161 0.2487593 -0.1569536 0.923048 0.3512094 -0.08127307 0.4643896 -0.8818939 0.0873261 -0.5675864 -0.8186696 0.003406524 -0.9133155 -0.4072386 -0.1697183 0.9614899 -0.2161781 0.1079425 0.3757565 0.9204105 0.071455 -0.5996178 0.79709 0.002454876 -0.9812922 -0.1925088 0.4550984 -0.3194119 -0.8311808 -0.02749484 0.5901047 -0.8068584 -0.1523763 0.9131914 0.3779718 0.001553416 -0.999559 0.02965301 0.2596173 -0.4473868 -0.8558293 0.05914008 0.4783867 -0.8761556 -0.03620821 -0.6322348 0.7739303 -0.9710211 -0.2384092 -0.01670622 -0.9708335 -0.2295454 0.06921982 -0.8140376 -0.1755584 0.5536443 -0.8889277 -0.1622743 -0.4283394 0.8714885 0.002518475 -0.4904094 -0.07730656 -0.004526197 -0.9969971 0.899167 -0.07011187 0.4319525 0.07537293 -0.1307963 0.9885399 -0.9848578 -0.1388146 -0.103854 -0.9013103 -0.2655161 -0.3422586 -0.2607684 -0.2985297 0.9180849 -0.458054 -0.08771145 -0.8845865 -0.9895613 -0.1184797 0.08204251 -0.460096 -0.09916561 -0.8823139 -0.2645653 -0.3242648 0.9082167 -0.3694864 0.01906377 -0.9290405 -0.4017134 0.08232843 0.9120572 -0.3049647 0.9523622 0.001663863 -0.3443584 0.3123724 -0.8853479 -0.2977657 0.927786 0.2248302 -0.3120965 -0.2947847 0.9031599 -0.2392512 0.9291517 -0.2818438 -0.4188077 -0.0972802 -0.9028491 -0.3808693 0.3654264 0.849354 0.0880438 -0.06021845 0.9942947 0.9951574 -0.09829425 0 -0.08961409 -0.1237902 -0.9882537 0.9835869 -0.1804351 0 -0.6028147 -0.07061088 -0.7947506 -0.9377365 -0.0230596 0.3465812 0.1226185 -0.9109081 -0.3939685 0.05663383 -0.3700072 -0.9273011 -0.04396909 0.5634636 -0.82497 -0.04091548 0.9201101 0.3895166 0.1597857 -0.9608251 0.2264591 -0.04219996 0.9750961 -0.2177311 0.01045769 0.3584202 0.9335018 0.1026133 -0.568618 0.8161765 0.1121459 -0.006672501 0.9936694 -0.03785294 0.9989558 0.02558046 0.01979398 0.03545719 -0.9991751 0.9768146 0.2125906 -0.02526932 0.9768092 0.2126131 -0.02528876 0.1073554 -0.6777516 -0.7274116 0.02467733 0.6982263 0.7154516 0.9768126 0.2125993 -0.02527606 0.9768143 0.2125926 -0.02526402 0.1729356 -0.7077394 0.6849806 -0.04022026 0.7299895 -0.6822739 0.1706493 -0.9848939 -0.02937412 0.1903582 -0.9812592 -0.02990311 -0.03227019 0.7308984 -0.6817229 0.181995 -0.7057294 0.6847071 0.01817929 0.6975094 0.7163451 0.1310269 -0.6727488 -0.7281764 0.03855919 0.03950297 -0.9984752 -0.04038208 0.9988549 0.0256536 0.1103855 -0.007061898 0.9938638 0.1491573 -0.9883942 -0.02879184 -0.04888814 0.7289419 -0.6828278 0.1630582 -0.7098625 0.6852061 0.03173542 0.6989643 0.7144521 0.08154422 -0.6827431 -0.7260938 -6.82091e-4 0.03102481 -0.9995184 -0.03510272 0.9990585 0.02549582 0.1140603 -0.006251692 0.9934541 0.07356387 -0.01514905 0.9971754 -0.01010394 0.9996431 0.02473151 0.01349306 0.03409469 -0.9993275 0.9768167 0.2125799 -0.02527868 0.976808 0.2126191 -0.02528214 0.0602743 -0.6864925 -0.7246345 0.02639627 0.6984119 0.7152091 0.9768085 0.212617 -0.02528291 0.9768154 0.2125881 -0.02525693 0.1026756 -0.721185 0.6850913 -0.01559394 0.7326565 -0.6804199 0.09679734 -0.9949293 -0.027314 0.1100331 -0.993542 -0.02769619 -0.0104646 0.7331563 -0.6799798 0.1089146 -0.7201462 0.6852205 0.02210873 0.6979479 0.7158071 0.07605791 -0.68374 -0.7257512 0.02590578 0.03677499 -0.9989877 -0.01184487 0.9996227 0.02478516 0.07251763 -0.01537889 0.9972486 0.08425545 -0.9960795 -0.02695524 -0.02191084 0.7320142 -0.6809369 0.09772253 -0.7219923 0.6849653 0.03105783 0.6988966 0.7145481 0.04420506 -0.6891096 -0.7233076 -8.58016e-6 0.03117156 -0.9995141 -0.008938848 0.999655 0.02469801 0.07576286 -0.01466828 0.997018 -0.01789659 0.7324262 -0.6806112 0.08959704 -0.9956091 -0.02710998 0.09580117 -0.7222999 0.6849124 0.02076804 0.6977979 0.7159936 0.03023064 0.03770798 -0.9988314 -0.01319569 0.732892 -0.680217 0.1339262 -0.7156748 0.685473 -0.02155905 0.999453 0.02508127 0.1374774 -0.9900956 -0.02847146 0.08548665 -0.0125367 0.9962605 0.9768142 0.212593 -0.02526307 0.09484928 -0.6802315 -0.7268348 0.05340856 -0.6876336 -0.7240909 0.08524405 -0.01258939 0.9962806 -0.02855134 0.7313084 -0.6814491 0.03122401 0.6989156 0.7145222 -1.74888e-4 0.03113561 -0.9995151 -0.01537239 0.9995719 0.02489668 0.1138567 -0.7192993 0.6853067 0.100235 -0.9945859 -0.02741956 0.9768106 0.2126072 -0.02528071 0.06977581 -0.01597762 0.9974347 0.01287692 0.03396153 -0.9993402 0.05567526 -0.6872622 -0.7242726 0.02656418 0.6984274 0.7151877 -0.007406592 0.9996688 0.02464812 0.9768152 0.2125868 -0.0252794 0.97681 0.2126107 -0.02527964 0.1121457 -0.006672859 0.9936694 -0.03785324 0.998956 0.02557671 0.01979416 0.03545629 -0.9991752 0.9768146 0.2125902 -0.02527034 0.9768081 0.2126186 -0.02528274 0.1073566 -0.6777564 -0.7274069 0.02467739 0.6982263 0.7154517 0.9768087 0.2126161 -0.02528256 0.9768142 0.212593 -0.02526307 0.1729347 -0.7077434 0.6849765 -0.04022008 0.7299933 -0.6822698 0.1706473 -0.984894 -0.02937912 0.1491596 -0.9883938 -0.02879512 -0.04888784 0.7289419 -0.6828277 0.1630575 -0.7098599 0.6852089 0.03173434 0.6989667 0.7144498 0.08154487 -0.6827446 -0.7260925 -6.82504e-4 0.03102588 -0.9995184 -0.03510379 0.9990583 0.02549892 0.1140614 -0.006252706 0.993454 -0.01789659 0.7324249 -0.6806126 0.08959764 -0.995609 -0.02711313 0.09580051 -0.7222965 0.6849161 0.02076798 0.6977977 0.7159938 0.03023082 0.03770792 -0.9988315 -0.01319605 0.7328919 -0.6802171 0.1339268 -0.7156751 0.6854727 -0.02155911 0.999453 0.02508109 0.1374774 -0.9900957 -0.02847069 0.08548641 -0.01253628 0.9962605 0.9768157 0.2125871 -0.0252574 0.09485054 -0.6802325 -0.7268336 0.0534079 -0.6876322 -0.7240923 0.08524405 -0.01258903 0.9962806 -0.02855068 0.7313081 -0.6814495 0.03122478 0.6989138 0.714524 -1.75114e-4 0.03113639 -0.9995151 -0.0153715 0.9995719 0.02489662 0.1138568 -0.7192995 0.6853064 0.1002334 -0.9945862 -0.02741557 0.9768084 0.212617 -0.02528375 0.06977593 -0.01597768 0.9974347 0.0128771 0.03396058 -0.9993402 0.05567598 -0.6872622 -0.7242727 0.02656471 0.6984273 0.7151879 -0.007407307 0.9996688 0.02464812 0.9768163 0.2125829 -0.02526855 0.9768058 0.212629 -0.02528601 0.9884612 -0.1187292 0.09406286 0.2828168 0.1734057 0.943369 0.4184271 -0.08961862 -0.9038181 0.2422897 0.9211348 -0.3046414 0.311163 -0.2097139 0.9269291 0.9996137 -0.009144544 -0.02624797 0.9305749 -0.2749262 -0.2417558 0.2015094 0.901394 0.383253 0.9829611 0.03351688 -0.1807321 0.339838 0.3423089 -0.8759765 0.9868844 -0.1395477 -0.08115255 0.3206606 0.9465916 0.033782 0.4019383 0.05184662 0.9141977 0.3956244 0.06594794 -0.9160416 0.9939026 -0.1034213 -0.03823202 0.9943517 -0.03578913 0.09991949 0.985268 -0.08017754 -0.1510581 0.9847116 -0.01742941 0.1733183 0.1114524 0.04810512 0.9926048 0.2159584 -0.5202355 0.826267 0.9592605 -0.01275163 -0.2822352 0.6722882 0.4617269 -0.5786509 0.8716286 -0.053689 -0.4872177 0 -0.05539321 0.9984647 0.8280422 -0.4236363 -0.3672579 0.1281039 -0.3474888 0.9288923 0.8379996 0.4837339 0.2525039 0.3763101 -0.3657525 -0.8512437 0.9335401 -0.122271 -0.3369758 0.2424414 0.2735695 0.9307963 -4.17113e-4 -0.05546301 0.9984607 0.7498043 -0.339681 -0.5678119 0.9928558 0.1013352 -0.06299567 0.9982583 -0.05833935 0.008766055 0.9965154 -0.0815311 -0.01759821 0.7942925 0.4316291 -0.4275461 0.8925642 -0.4502765 0.02408981 0.99316 0.1118749 -0.03342473 0.1525924 9.26376e-5 -0.9882892 -1.51087e-4 -0.02098524 -0.9997798 0 -0.2689219 -0.963162 0 0.1191722 -0.9928737 0.3678277 0.453657 0.8117253 0.9430798 0.1652334 0.2886146 0.08312451 0.4611421 -0.8834242 0 0.5454469 0.8381454 0.5550583 0.8053788 -0.2080268 -2.2773e-7 0.3414732 -0.9398915 0.3793621 0.9032253 -0.2006705 0.3371583 0.9401035 -0.05029505 -0.06950753 -0.3043785 0.9500117 -0.8077753 -0.4413666 0.3907616 -0.07994467 -0.4225014 0.9028298 0.5284286 -0.1014805 -0.8428909 0.5868957 -0.09755438 -0.803764 0.1017684 0.4532732 0.8855432 0.9953396 0.09641188 -0.001977026 0.8923963 -0.06423294 -0.4466578 -0.8130927 -0.03693777 -0.5809612 0.06988793 -0.2873592 -0.9552698 -0.7971544 -0.2672001 -0.5414324 0.8869144 -0.1711966 -0.4290391 0.8264902 -0.04239428 0.5613526 -0.07195448 -0.2969248 0.952186 -0.8966405 -0.1463912 0.417858 0.804342 0.15081 0.5747088 -0.8793457 0.1817709 0.4401258 -0.07082259 0.2567646 0.9638755 0.07218551 -0.1721147 -0.9824286 0.1938278 0.9354441 -0.2955931 0 -1 0 0.07225537 -0.00541085 -0.9973714 -0.8249545 0.001877963 -0.565196 0.8848431 -0.1246861 -0.4488943 0.8102551 -0.2737453 0.5182181 0.8099066 0.1708597 0.5611223 0.8967524 0.09547847 -0.4321098 -0.819369 -0.0798493 -0.5676781 0.07729727 -0.01615047 -0.9968773 -0.9007831 -0.01373016 0.4340523 -0.07674145 0.1207528 0.9897118 0 -1 0 0 -1 0 0.9014587 0.1601433 0.4021523 -0.9509604 0.01830768 0.3087705 -0.07318145 0.1888487 0.9792756 -0.9092159 0.4150556 0.03248691 0.3787636 0.4385838 -0.8149739 -0.3075465 0.1715487 -0.9359413 0.01647913 0.1730729 -0.9847711 0 -1 0 0 -1 0 0.007206559 0.949131 -0.314799 0.6526672 0.7489948 0.1141583 -0.1469138 0.9350052 -0.3227718 -0.4903541 0.3859561 0.781403 0.2858338 -0.5024614 0.8159851 0.8925945 -0.1150026 0.4359467 0.8178272 -0.1369842 -0.5589222 -0.8759967 -0.0901404 -0.473819 0.1201334 -0.1334357 -0.9837493 -0.9435458 -0.1568514 0.2917516 -0.05656254 -0.07504248 0.9955749 0.06989419 -0.2925534 -0.9536914 -0.06627464 0.421792 0.9042673 -0.8549486 0.3054926 0.4192103 0.7951516 0.253102 0.5510656 -0.820495 -0.058703 -0.5686317 0.8925302 -0.1089299 -0.4376347 0.05958807 0.1738171 -0.9829735 0.02679419 -0.1635901 -0.9861645 0.1126963 -0.2018982 -0.9729012 0.2469136 0.947318 -0.2040157 -0.02162379 -0.5862906 0.8098121 0.04085254 -0.838564 -0.5432693 0.2689242 0.5933514 -0.7586923 0.1573562 0.8754985 0.4568821 0.02066409 -0.9863832 0.1631597 0.04059511 0.1834312 0.982194 -0.03147858 0.1926774 0.9807572 0.03926992 -0.9758334 0.2149581 0.1030426 0.8296977 0.5486201 0.2050098 0.5531601 -0.8074558 0.08927589 -0.8378205 -0.5385969 -0.007759869 -0.5391136 0.8421974 0.1932245 0.9668697 -0.1668148 0.1314351 -0.2067537 -0.9695245 0.03772777 -0.9760814 0.2141069 0.1910935 0.3280676 0.9251242 0.2272909 0.5465738 -0.8059751 0.08945035 -0.5886788 0.8034028 0.255532 0.8870356 0.3845403 0.0343303 -0.9213422 -0.3872338 0.1051242 -0.36725 -0.9241626 0.2711786 0.9372648 -0.2190821 -0.05061155 -0.9794246 -0.1953609 -0.004981994 -0.4241523 -0.9055772 0.09688812 0.5807979 -0.8082615 0.1157706 0.9219887 0.3695049 -0.04230958 -0.9963685 0.07388955 0.1143614 0.9698607 -0.215155 0.0837959 0.3662232 0.9267463 -0.01275086 -0.6145241 0.7887951 -0.1110014 -0.5621908 0.8195244 -0.06689327 0.3602434 0.9304569 0.08038288 0.9717792 -0.2217739 -0.1160601 -0.9616321 0.2485837 0.05082124 0.9346777 0.3518444 -0.03044557 0.4774409 -0.8781362 -0.1171522 -0.5634045 -0.8178331 -0.09991413 -0.9044712 -0.4146673 -0.1840536 -0.9041485 -0.3855383 -0.1048053 -0.3454656 -0.9325607 -0.048936 0.5729334 -0.8181398 -0.002320885 0.9215087 0.3883509 -0.230392 -0.9480381 0.2194156 -0.00420928 0.976447 -0.2157167 -0.06278407 0.3663213 0.9283678 -0.1709023 -0.5591278 0.8112759 0.1488195 0.9639173 -0.2207176 0.005538165 -0.3576516 -0.9338387 -0.01061832 -0.9211803 -0.3889912 0.1240699 0.9124514 0.3899219 0.01065385 -0.5454904 0.8380494 0.09829616 0.5690543 -0.8164037 0.05283898 0.3211376 0.9455573 0.003660261 -0.9715069 0.236983 -0.01329219 -0.9731889 0.2296224 0.06781178 0.3191375 0.9452792 0.1348162 0.5255552 -0.8400098 -0.01627707 -0.5129503 0.858264 0.1702956 0.8907435 0.4213969 0.09053879 -0.8875638 -0.4517004 0.1739012 -0.3422725 -0.9233677 0.1996108 0.9495099 -0.2420462 -0.03592306 -0.6237311 0.780813 0.1120456 0.3806635 0.9179004 0.1535664 0.9660423 -0.2077968 -0.009761571 -0.9685161 0.2487593 0.1569536 0.923048 0.3512094 0.1255055 0.5362868 -0.8346526 -0.0340963 -0.4825789 -0.8751885 -0.08349531 -0.9724208 -0.2177759 0.1697183 0.9614899 -0.2161781 -0.1079425 0.3757565 0.9204105 -0.071455 -0.5996179 0.79709 -0.05974328 -0.9977206 0.03137171 -0.4550984 -0.3194119 -0.8311808 0.02749484 0.5901046 -0.8068584 0.08379071 0.99603 0.03005361 -0.001553416 -0.999559 0.02965301 -0.279276 -0.5200095 -0.8072145 -0.06358426 0.8572714 -0.5109235 0.03620821 -0.6322348 0.7739303 0.9710211 -0.2384092 -0.01670622 0.9794978 -0.198337 -0.03530573 0.9543163 -0.2923163 -0.06189918 0.9708335 -0.2295455 0.06921982 0.9766114 -0.213241 0.02753829 0.9764481 -0.2156115 0.007800996 0.8140376 -0.1755584 0.5536442 0.9185371 -0.1300503 -0.3733317 -0.8714885 0.002518475 -0.4904094 0.07556045 -0.005428552 -0.9971265 -0.899167 -0.07011181 0.4319525 -0.07537293 -0.1307963 0.9885399 0.9848578 -0.1388145 -0.103854 0.9013103 -0.2655161 -0.3422586 0.3111631 -0.2097137 0.9269291 0.458054 -0.08771145 -0.8845865 0.9895613 -0.1184797 0.08204251 0.460096 -0.09916561 -0.8823139 0.3120964 -0.2947854 0.9031596 0.3962478 0.05173611 -0.9166848 0.4017135 0.08232843 0.9120572 0.3205693 0.9469129 0.02431565 0.3443583 0.3123724 -0.8853479 0.1940032 0.91603 0.3510724 0.3120965 -0.2947847 0.9031599 0.2392513 0.9291517 -0.2818438 0.4188077 -0.09728026 -0.9028491 0.2867903 0.3304973 0.8991791 -0.07195693 -0.07040029 0.9949201 -0.9890962 -0.1325349 0.0642125 0.08961409 -0.1237902 -0.9882537 -0.9678096 -0.1127874 -0.2249969 0.6028147 -0.07061088 -0.7947506 0.9377365 -0.0230596 0.3465812 -0.1226185 -0.9109081 -0.3939685 -0.05663383 -0.3700072 -0.9273011 -0.006774842 0.5168347 -0.8560584 0.04091548 0.9201101 0.3895166 -0.1597857 -0.9608251 0.2264591 0.03965699 0.9746117 -0.2203619 -0.01045769 0.3584202 0.9335018 -0.1026133 -0.5686179 0.8161765 -0.1121459 -0.006672501 0.9936694 0.03785383 0.9989557 0.02558434 -0.01979529 0.03545403 -0.9991752 -0.9768146 0.2125906 -0.02526932 -0.9768092 0.2126131 -0.02528876 -0.107355 -0.6777509 -0.7274122 -0.02467733 0.6982263 0.7154516 -0.9768099 0.2126119 -0.02527022 -0.9768183 0.2125728 -0.02527314 -0.1729356 -0.7077394 0.6849806 0.04021894 0.7299869 -0.6822767 -0.1706493 -0.9848939 -0.02937412 -0.1903582 -0.9812592 -0.02990311 0.03227037 0.7308988 -0.6817226 -0.181995 -0.7057294 0.6847071 -0.01817929 0.6975094 0.7163451 -0.1310268 -0.6727488 -0.7281765 -0.03856015 0.03950124 -0.9984752 0.04038274 0.9988549 0.0256555 -0.1103855 -0.007061898 0.9938638 -0.1491573 -0.9883942 -0.02879184 0.04888874 0.7289428 -0.6828266 -0.1630581 -0.7098625 0.6852059 -0.03173542 0.6989643 0.7144521 -0.08154374 -0.6827425 -0.7260945 6.83521e-4 0.03102791 -0.9995183 0.03510308 0.9990584 0.02549719 -0.1140603 -0.006251692 0.9934541 -0.07356387 -0.01514911 0.9971754 0.01010394 0.9996431 0.02473151 -0.01349335 0.03409361 -0.9993276 -0.9768167 0.2125799 -0.02527868 -0.976808 0.2126191 -0.02528214 -0.06027394 -0.6864913 -0.7246356 -0.02639627 0.6984119 0.7152091 -0.9768092 0.2126137 -0.02528446 -0.9768186 0.2125726 -0.02526402 -0.1026756 -0.721185 0.6850913 0.01559442 0.7326582 -0.6804181 -0.09679394 -0.9949291 -0.02732956 -0.1100329 -0.993542 -0.0276969 0.01046353 0.7331537 -0.6799826 -0.1089146 -0.7201462 0.6852205 -0.02210873 0.6979479 0.7158071 -0.07605844 -0.6837413 -0.72575 -0.02590602 0.03677421 -0.9989877 0.01184487 0.9996227 0.02478516 -0.07251763 -0.01537889 0.9972486 -0.08425545 -0.9960795 -0.02695524 0.02191132 0.7320156 -0.6809356 -0.09772253 -0.7219923 0.6849653 -0.03105783 0.6988966 0.7145481 -0.04420489 -0.6891093 -0.7233079 9.00498e-6 0.03117305 -0.9995141 0.008938372 0.9996551 0.02469545 -0.07576286 -0.01466828 0.997018 0.01789599 0.7324249 -0.6806125 -0.08959561 -0.9956091 -0.02711701 -0.09580117 -0.7222999 0.6849124 -0.02076804 0.6977978 0.7159936 -0.03023093 0.03770726 -0.9988315 0.01319551 0.7328914 -0.6802176 -0.1339262 -0.7156749 0.685473 0.02155905 0.999453 0.02508127 -0.1374776 -0.9900956 -0.02847069 -0.08548659 -0.01253676 0.9962604 -0.9768166 0.2125815 -0.02526831 -0.09484893 -0.6802307 -0.7268354 -0.05340921 -0.6876351 -0.7240895 -0.08524405 -0.01258939 0.9962806 0.02855187 0.7313097 -0.6814477 -0.03122401 0.6989157 0.7145222 1.75343e-4 0.03113704 -0.9995151 0.01537185 0.9995719 0.02489411 -0.1138567 -0.7192993 0.6853067 -0.100235 -0.9945859 -0.02741956 -0.9768103 0.212609 -0.02527993 -0.06977581 -0.01597762 0.9974347 -0.01287716 0.03396052 -0.9993402 -0.05567514 -0.6872619 -0.724273 -0.02656412 0.6984274 0.7151877 0.007406592 0.9996688 0.02464812 -0.9768152 0.2125868 -0.0252794 -0.9768099 0.2126107 -0.02527964 -0.1121457 -0.006672859 0.9936694 0.03785395 0.9989559 0.02557975 -0.01979482 0.03545469 -0.9991752 -0.9768146 0.2125902 -0.02527034 -0.9768081 0.2126186 -0.02528274 -0.1073535 -0.6777512 -0.7274122 -0.02467739 0.6982263 0.7154517 -0.976809 0.2126141 -0.02528345 -0.9768166 0.2125815 -0.02526831 -0.1729347 -0.7077434 0.6849765 0.04021811 0.7299893 -0.6822742 -0.1706473 -0.984894 -0.02937906 -0.1491596 -0.9883938 -0.02879518 0.04889041 0.7289465 -0.6828227 -0.1630575 -0.7098599 0.6852089 -0.03173434 0.6989667 0.7144498 -0.0815463 -0.6827468 -0.7260903 6.82942e-4 0.03102684 -0.9995183 0.0351023 0.9990586 0.02549338 -0.1140614 -0.006252706 0.993454 0.01789641 0.7324246 -0.680613 -0.08959609 -0.9956089 -0.02712076 -0.09580051 -0.7222965 0.6849161 -0.02076798 0.6977977 0.7159938 -0.03023076 0.0377081 -0.9988315 0.01319593 0.7328914 -0.6802176 -0.1339268 -0.7156752 0.6854727 0.02155911 0.999453 0.02508109 -0.1374787 -0.9900956 -0.02846652 -0.08548641 -0.01253628 0.9962605 -0.9768187 0.2125726 -0.02526408 -0.09484869 -0.6802291 -0.726837 -0.05340921 -0.6876351 -0.7240895 -0.08524405 -0.01258903 0.9962806 0.02855128 0.7313095 -0.6814478 -0.03122478 0.6989138 0.714524 1.75022e-4 0.03113615 -0.9995151 0.01537096 0.9995719 0.02489417 -0.1138568 -0.7192996 0.6853064 -0.1002334 -0.9945862 -0.02741557 -0.976809 0.2126143 -0.025285 -0.06977593 -0.01597768 0.9974347 -0.0128774 0.03395926 -0.9993402 -0.05567544 -0.6872605 -0.7242743 -0.02656471 0.6984273 0.7151879 0.007407307 0.9996688 0.02464812 -0.9768163 0.2125829 -0.02526861 -0.9768058 0.212629 -0.02528601 -0.9892109 -0.1041101 0.103068 -0.2828168 0.1734057 0.943369 -0.3979625 -0.09626638 -0.9123369 -0.3021122 0.911219 -0.2800147 -0.3572784 -0.2907155 0.8876017 -0.9988095 -0.02354627 -0.04272139 -0.9795474 -0.1372095 -0.147175 -0.2015094 0.901394 0.383253 -0.9739232 -0.01486963 -0.2263904 -0.2480421 0.3224936 -0.9134949 -0.9916154 -0.1142422 -0.060395 -0.3206607 0.9465915 0.033782 -0.3795642 0.04015576 0.9242935 -0.3956245 0.06594794 -0.9160416 -0.9946352 -0.0825873 -0.06229108 -0.9886372 -0.06878805 0.1336587 -0.985268 -0.08017754 -0.1510581 -0.9847116 -0.01742941 0.1733183 -0.2159584 -0.5202355 0.826267 -0.1114524 0.04810512 0.9926048 -0.9592605 -0.01275163 -0.2822352 -0.6442092 0.3694566 -0.6696987 -0.9497107 0.1237967 -0.2876176 0 -0.05539351 0.9984646 -0.8668302 -0.3837681 -0.3183197 -0.1281039 -0.3474888 0.9288923 -0.807321 0.5892698 -0.03152579 2.42143e-7 0.03528326 -0.9993774 -0.9603252 -0.05810719 -0.272762 -0.2424414 0.2735695 0.9307963 0 -0.05663251 0.9983951 -0.8661219 -0.01136928 -0.4997035 -0.9847019 0.1669552 -0.0498811 -0.9965154 -0.0815311 -0.01759821 -0.9982583 -0.05833935 0.008766055 -0.9047946 0.3157365 -0.2857572 -0.8914443 -0.4526674 0.02047687 -0.9862645 0.164938 -0.008824169 0 -0.1851995 -0.9827009 -0.1109472 0.1463277 -0.9829948 -0.00337255 -0.2653499 -0.9641463 0 0.1191721 -0.9928736 -0.3678277 0.453657 0.8117253 -0.9430798 0.1652334 0.2886146 -0.08312451 0.4611421 -0.8834242 0 0.5454469 0.8381454 -0.3320318 0.8395674 -0.4299785 -0.09087991 0.2426548 -0.9658465 -0.3793621 0.9032253 -0.2006705 -0.4211201 0.7732085 0.4741377 0.06950753 -0.3043785 0.9500117 0.8077753 -0.4413666 0.3907616 -0.1236155 -0.176039 0.9765908 -0.5705664 -0.2296157 -0.7884989 -0.5868957 -0.09755438 -0.803764 -0.002248048 0.2989262 0.9542736 -0.9953396 0.09641188 -0.001977026 -0.8957511 -0.06871044 -0.439214 0.8130927 -0.03693777 -0.5809612 -0.113711 -0.3464318 -0.9311578 0.7971543 -0.2672002 -0.5414324 -0.8226119 0.08514457 -0.5621922 -0.8264902 -0.04239428 0.5613526 0.07316827 -0.2972875 0.9519804 0.8932492 -0.14485 0.4255871 -0.8115245 0.158493 0.5624126 0.8793455 0.1817709 0.4401258 0.07064193 0.2568881 0.9638559 -0.07218551 -0.1721147 -0.9824286 -0.1938278 0.9354441 -0.2955931 0 -1 0 -0.07225537 -0.00541085 -0.9973714 0.8715252 0.0322082 -0.4892917 -0.8848431 -0.1246861 -0.4488943 -0.8102551 -0.2737453 0.5182181 -0.8026755 0.1636735 0.5735181 -0.8896101 0.1016595 -0.4452633 0.8105362 -0.08737415 -0.5791346 -0.07327145 -0.0144146 -0.9972079 0.900783 -0.01373016 0.4340523 0.07674145 0.1207528 0.9897118 0 -1 0 0 -1 0 -0.8204876 0.05132156 0.5693559 0.9509604 0.01830768 0.3087705 0.07318145 0.1888487 0.9792756 0.9092159 0.4150556 0.03248691 -0.3976117 0.4352651 -0.8077433 0.3075465 0.1715487 -0.9359413 -0.0163694 0.1732529 -0.9847413 0 -1 0 0 -1 0 -0.03238409 0.9474993 -0.3181139 -0.9932018 0.1045786 0.05112236 0.5226539 0.8158264 -0.247508 0.4903541 0.3859561 0.781403 -0.2858346 -0.5024608 0.8159852 -0.9358144 -0.06800496 0.3458709 -0.604315 0.005157411 -0.7967287 0.8759967 -0.0901404 -0.4738191 -0.08954453 -0.1298145 -0.9874867 0.9435458 -0.1568514 0.2917517 0.05656254 -0.07504248 0.9955749 -0.06989419 -0.2925534 -0.9536914 0.06615543 0.4219868 0.9041851 0.8549485 0.3054925 0.4192103 -0.796922 0.2682213 0.5412694 0.8204949 -0.05870294 -0.5686317 -0.8938878 -0.118254 -0.4324125 -0.0247662 -0.160278 -0.9867612 -0.02994322 -0.1602553 -0.9866213 -0.1412579 -0.3116959 -0.9396232 -0.2469136 0.947318 -0.2040157 -0.01924186 -0.5163249 0.8561766 -0.07316255 -0.8885112 -0.4529846 -0.2689242 0.5933514 -0.7586923 -0.1573562 0.8754985 0.4568821 -0.04758769 -0.9728084 0.22667 -0.09774237 0.2871931 0.9528728 0.03147858 0.1926774 0.9807572 -0.0169571 -0.9864328 0.1632875 -0.1030426 0.8296977 0.5486201 -0.2050098 0.5531601 -0.8074558 -0.0891264 -0.837626 -0.538924 0.03355425 -0.584758 0.8105135 -0.1932245 0.9668697 -0.1668148 -0.1302704 -0.2037244 -0.9703226 -0.03022766 -0.9766428 0.2127326 -0.2001283 0.3289599 0.9228944 -0.2272909 0.5465738 -0.8059751 -0.07508558 -0.591234 0.8029972 -0.2671164 0.8851683 0.3809541 -0.04617202 -0.922254 -0.3838171 -0.1140793 -0.3706419 -0.9217432 -0.2711786 0.9372648 -0.2190821 0.05061155 -0.9794246 -0.1953609 0.004981994 -0.4241523 -0.9055772 -0.09688812 0.5807979 -0.8082615 -0.1110141 0.918741 0.3789338 0.06001353 -0.9975749 0.03525137 -0.1143614 0.9698607 -0.215155 -0.0791257 0.3567544 0.9308413 0.009043991 -0.6083135 0.7936453 0.1419395 -0.6082586 0.7809447 0.04213517 0.3994789 0.9157735 -0.06649297 0.9785046 -0.1952113 0.1144121 -0.9610381 0.251626 -0.05082124 0.9346777 0.3518444 0.03044557 0.4774409 -0.8781362 0.1171522 -0.5634045 -0.8178331 0.09772658 -0.9071653 -0.4092684 0.2063531 -0.8967678 -0.3914409 0.05805003 -0.3698148 -0.9272903 0.048936 0.5729334 -0.8181398 0.002320885 0.9215087 0.3883509 0.2063317 -0.9518449 0.2267568 0.00420928 0.976447 -0.2157167 0.07005804 0.3644931 0.9285669 0.1606435 -0.5581462 0.8140432 -0.1488192 0.9639173 -0.2207176 -0.005538165 -0.3576516 -0.9338387 0.01061832 -0.9211803 -0.3889912 -0.1240697 0.9124515 0.3899219 0.0106095 -0.5808191 0.8139635 -0.09829598 0.5690544 -0.8164037 -0.06784808 0.348273 0.9349345 0.007082104 -0.9762823 0.2163855 0.009525716 -0.9713133 0.2376126 -0.06781178 0.3191375 0.9452792 -0.1348162 0.5255552 -0.8400098 0.03458613 -0.5405511 0.8406 -0.1702956 0.8907435 0.4213969 -0.1020344 -0.9037875 -0.4156408 -0.1739012 -0.3422725 -0.9233677 -0.1996108 0.9495099 -0.2420462 0.02811795 -0.6127378 0.789786 -0.102366 0.3634706 0.9259645 -0.1535664 0.9660423 -0.2077968 0.09627056 -0.9923768 0.07694351 -0.1472514 0.9176954 0.3689882 -0.1255055 0.5362868 -0.8346526 0.0340963 -0.4825789 -0.8751885 0.08349531 -0.9724208 -0.2177759 -0.1469666 0.9816242 -0.1217165 0.03365188 0.5877929 0.8083112 0.1123096 -0.7996611 0.5898548 0.05974328 -0.9977206 0.03137171 0.4386112 -0.3902069 -0.8095423 -0.01591479 0.8013805 -0.5979431 -0.08379071 0.99603 0.03005361 0.004641234 -0.9998419 0.01716285 0.279276 -0.5200095 -0.8072145 0.06358426 0.8572714 -0.5109235 -0.04754287 -0.7600731 0.648096 -0.9456669 -0.1853826 -0.2671092 -0.9794978 -0.198337 -0.03530573 -0.9766114 -0.213241 0.02753829 -0.9517541 -0.3068616 -3.42063e-4 -0.9543163 -0.2923163 -0.06189918 -0.9764481 -0.2156115 0.007800996 -0.8085462 -0.1801439 0.5601798 -0.9185371 -0.1300503 -0.3733317 0.8208414 -0.05293005 -0.5686983 -0.07556045 -0.005428552 -0.9971265 0.8986896 -0.06949883 0.4330436 0.07663661 -0.131427 0.9883591 -0.989714 -0.1131663 -0.0875194 -0.9501959 -0.1303589 -0.2830799 -0.3111631 -0.2097137 0.9269291 -0.418809 -0.0972802 -0.9028486 -0.990682 -0.1017538 0.09052819 -0.4197325 -0.1184133 -0.8998905 -0.3120965 -0.2947854 0.9031596 -0.3962478 0.05173611 -0.9166848 -0.3795773 0.05273705 0.9236558 -0.3205693 0.9469129 0.02431565 -0.2338472 0.2141158 -0.9484039 -0.1940032 0.91603 0.3510724 -0.3539721 -0.314476 0.8808 -0.3089522 0.9272136 -0.2117159 -0.3976334 -0.1117674 -0.9107116 -0.2867904 0.3304972 0.899179 0.07195693 -0.07040029 0.9949201 0.9890962 -0.1325349 0.0642125 -0.03011232 -0.1210293 -0.9921921 0.9678096 -0.1127874 -0.2249969 -0.5310937 -0.01704001 -0.8471418 -0.9561676 0.01081436 0.29262 0.1382545 -0.8995858 -0.4142839 0.01861298 -0.4321886 -0.9015911 0.006774842 0.5168347 -0.8560584 -0.03680831 0.9185113 0.3936779 0.1394249 -0.9584177 0.2489907 -0.03965699 0.9746117 -0.2203619 0.01385873 0.3548076 0.9348366 0.09765416 -0.5643823 0.8197172 0.112146 -0.006672859 0.9936694 -0.03785383 0.9989557 0.02558434 0.01979529 0.03545403 -0.9991752 0.976814 0.2125924 -0.02527338 0.9768103 0.2126086 -0.02527874 0.107355 -0.6777509 -0.7274122 0.02467697 0.6982269 0.715451 0.9768099 0.2126119 -0.02527022 0.9768183 0.2125728 -0.02527314 0.1729345 -0.7077372 0.684983 -0.04021894 0.7299869 -0.6822767 0.1706504 -0.9848936 -0.02937924 0.1903579 -0.9812593 -0.02990227 -0.03227037 0.7308988 -0.6817226 0.1819956 -0.7057303 0.6847061 0.01818048 0.6975077 0.7163467 0.1310268 -0.6727488 -0.7281765 0.03856015 0.03950124 -0.9984752 -0.04038274 0.9988549 0.0256555 0.1103852 -0.007061362 0.9938638 0.1491567 -0.9883944 -0.02878981 -0.04888874 0.7289428 -0.6828266 0.1630566 -0.7098599 0.6852092 0.03173297 0.6989681 0.7144485 0.08154374 -0.6827425 -0.7260945 -6.83521e-4 0.03102791 -0.9995183 -0.03510308 0.9990584 0.02549719 0.1140599 -0.006250739 0.9934542 0.07356333 -0.01514703 0.9971755 -0.01010304 0.999643 0.0247358 0.01349335 0.03409361 -0.9993276 0.9768182 0.2125746 -0.02526646 0.9768087 0.2126167 -0.02527648 0.06027394 -0.6864913 -0.7246356 0.02639675 0.6984107 0.7152103 0.9768092 0.2126137 -0.02528446 0.9768186 0.2125726 -0.02526402 0.1026753 -0.7211841 0.6850922 -0.01559442 0.7326582 -0.6804181 0.09679394 -0.9949291 -0.02732956 0.1100329 -0.993542 -0.0276969 -0.01046353 0.7331537 -0.6799826 0.1089144 -0.7201458 0.6852209 0.0221098 0.6979454 0.7158096 0.07605844 -0.6837413 -0.72575 0.02590602 0.03677421 -0.9989877 -0.01184415 0.9996225 0.02478784 0.07251769 -0.01537913 0.9972485 0.08425474 -0.9960796 -0.02695125 -0.02191132 0.7320156 -0.6809356 0.09772187 -0.7219905 0.6849673 0.0310564 0.6989001 0.7145448 0.04420489 -0.6891093 -0.7233079 -9.00498e-6 0.03117305 -0.9995141 -0.008938372 0.9996551 0.02469545 0.07576262 -0.01466739 0.997018 -0.01789599 0.7324249 -0.6806125 0.08959561 -0.9956091 -0.02711701 0.09580028 -0.7222968 0.6849157 0.02076709 0.6977998 0.7159918 0.03023093 0.03770726 -0.9988315 -0.01319551 0.7328914 -0.6802176 0.1339257 -0.7156739 0.6854742 -0.02155739 0.9994528 0.0250867 0.1374776 -0.9900956 -0.02847069 0.08548641 -0.01253622 0.9962605 0.9768166 0.2125815 -0.02526831 0.09484893 -0.6802307 -0.7268354 0.05340921 -0.6876351 -0.7240895 0.08524346 -0.01258754 0.9962806 -0.02855187 0.7313097 -0.6814477 0.03122425 0.698915 0.7145228 -1.75343e-4 0.03113704 -0.9995151 -0.01537185 0.9995719 0.02489411 0.1138572 -0.7193004 0.6853053 0.1002343 -0.9945861 -0.02741652 0.9768103 0.212609 -0.02527993 0.06977593 -0.01597821 0.9974347 0.01287716 0.03396052 -0.9993402 0.05567514 -0.6872619 -0.724273 0.02656292 0.6984311 0.7151841 -0.007406651 0.9996688 0.02464771 0.9768161 0.2125834 -0.02527147 0.9768102 0.2126098 -0.02527767 0.1121451 -0.006671488 0.9936695 -0.03785395 0.9989559 0.02557975 0.01979482 0.03545469 -0.9991752 0.9768143 0.2125914 -0.02527296 0.9768088 0.2126163 -0.02527749 0.1073535 -0.6777512 -0.7274122 0.02467781 0.6982256 0.7154524 0.976809 0.2126141 -0.02528345 0.9768166 0.2125815 -0.02526831 0.1729336 -0.7077413 0.684979 -0.04021811 0.7299893 -0.6822742 0.1706484 -0.9848938 -0.02938371 0.1491595 -0.9883938 -0.02879482 -0.04889041 0.7289465 -0.6828227 0.1630595 -0.7098633 0.6852049 0.03173345 0.6989681 0.7144485 0.0815463 -0.6827468 -0.7260903 -6.82942e-4 0.03102684 -0.9995183 -0.0351023 0.9990586 0.02549338 0.1140605 -0.006250917 0.9934542 -0.01789641 0.7324246 -0.680613 0.08959609 -0.9956089 -0.02712076 0.09580069 -0.722297 0.6849155 0.02076786 0.6977978 0.7159936 0.03023076 0.0377081 -0.9988315 -0.01319593 0.7328914 -0.6802176 0.1339263 -0.7156742 0.6854737 -0.02155739 0.9994528 0.0250867 0.1374787 -0.9900956 -0.02846652 0.08548629 -0.01253587 0.9962605 0.9768187 0.2125726 -0.02526408 0.09484869 -0.6802291 -0.726837 0.05340921 -0.6876351 -0.7240895 0.08524358 -0.01258754 0.9962806 -0.02855128 0.7313095 -0.6814478 0.03122431 0.6989148 0.7145231 -1.75022e-4 0.03113615 -0.9995151 -0.01537096 0.9995719 0.02489417 0.1138558 -0.7192972 0.6853089 0.1002343 -0.9945859 -0.0274195 0.976809 0.2126143 -0.025285 0.06977564 -0.01597648 0.9974348 0.0128774 0.03395926 -0.9993402 0.05567544 -0.6872605 -0.7242743 0.02656352 0.698431 0.7151844 -0.007405519 0.9996685 0.02465683 0.9768159 0.2125839 -0.02527087 0.976808 0.2126209 -0.02526736 + + + + + + + + + + 0.4179599 0.25 0.4660116 0.3370637 0.4609198 0.25 0.5535107 0.25 0.625 0.1604846 0.5416738 0.1604846 0.4264599 0.5895153 0.4783663 0.625 0.4779197 0.5895153 0.625 0.5895153 0.7174506 0.625 0.7151563 0.5895153 0.4189209 0.1604846 0.4609198 0.25 0.4628418 0.1604846 0.6250001 0.4156315 0.5442035 0.3363016 0.5428493 0.4108949 0.4230285 0.4083356 0.4767932 0.5000001 0.4710571 0.4083909 0.7815917 0.6250001 0.8750001 0.5895155 0.7850587 0.5895155 0.5428493 0.4108949 0.625 0.5 0.6250001 0.4156315 0.5406954 0.5895153 0.625 0.625 0.625 0.5895153 0.4205058 0.3343435 0.4710571 0.4083909 0.4660116 0.3370637 0.7151563 0.5895153 0.7815917 0.6250001 0.7850587 0.5895155 0.4628418 0.1604846 0.5369816 0.125 0.4636037 0.125 0.4779197 0.5895153 0.5373701 0.625 0.5406954 0.5895153 0.4710571 0.4083909 0.5442035 0.3363016 0.4660116 0.3370637 0.5535107 0.25 0.4660116 0.3370637 0.5442035 0.3363016 0.4710571 0.4083909 0.5490843 0.5 0.5428493 0.4108949 0.5442035 0.3363016 0.625 0.25 0.5535107 0.25 0.6068539 0.25 0.625 0.25 0.625 0.125 0.625 0.5 0.625 0.375 0.6068539 0.375 0.4389258 0.375 0.5028517 0.5 0.5028517 0.375 0.4389259 0.125 0.5028517 0.25 0.5028517 0.125 0.5028517 0.375 0.5524157 0.5 0.5524157 0.375 0.5028517 0.25 0.5524157 0.125 0.5028517 0.125 0.625 0.375 0.625 0.25 0.625 0.25 0.625 0.625 0.625 0.5 0.625 0.5 0.5524157 0.375 0.5887079 0.5 0.5887078 0.375 0.5524157 0.25 0.5887078 0.125 0.5524157 0.125 0.375 0.125 0.4389259 0.25 0.4389259 0.125 0.375 0.375 0.4389258 0.5 0.4389258 0.375 0.375 0.25 0.4389258 0.375 0.4389259 0.25 0.5524157 0.375 0.5887078 0.375 0.5887078 0.3125 0.625 0.5 0.625 0.375 0.625 0.375 0.5028517 0.25 0.5524157 0.375 0.5524157 0.25 0.4389259 0.25 0.5028517 0.375 0.5028517 0.25 0.375 0.5 0.4389258 0.625 0.4389258 0.5 0.5524157 0.5 0.5887079 0.625 0.5887079 0.5 0.5028517 0.5 0.5524157 0.625 0.5524157 0.5 0.4389258 0.5 0.5028517 0.625 0.5028517 0.5 0.625 0.25 0.625 0.125 0.625 0.25 0.375 0.25 0.375 0.375 0.375 0.25 0.5887079 0.625 0.625 0.5 0.5887079 0.5 0.625 0.25 0.625 0.125 0.625 0.25 0.625 0.5 0.625 0.375 0.625 0.375 0.625 0.625 0.625 0.5 0.625 0.5 0.625 0.25 0.625 0.25 0.625 0.3125 0.375 0.125 0.375 0.25 0.375 0.125 0 0 0 0 0 0 0.375 0.125 0.375 0.25 0.375 0.25 0.375 0.375 0.375 0.5 0.375 0.5 0.375 0.375 0.375 0.5 0.375 0.375 0.375 0.125 0.375 0.25 0.375 0.25 0.375 0.25 0.375 0.375 0.375 0.25 0.375 0.375 0.375 0.5 0.375 0.5 0 0 0 0 0 0 0.375 0.5 0.375 0.625 0.375 0.625 0 0 0 0 0 0 0.375 0.375 0.375 0.5 0.375 0.5 0.375 0.25 0.375 0.375 0.375 0.25 0.375 0.125 0.375 0.25 0.375 0.25 0 0 0 0 0 0 0.375 0.25 0.375 0.375 0.375 0.375 0 0 0 0 0 0 0.375 0.125 0.375 0.25 0.375 0.25 0.375 0.5 0.375 0.625 0.375 0.5 0.375 0.375 0.375 0.5 0.375 0.375 0.375 0.625 0.375 0.5 0.375 0.625 0.375 0.5 0.375 0.625 0.375 0.5 0 0 0 0 0 0 0.375 0.375 0.375 0.5 0.375 0.375 0.375 0.25 0.375 0.375 0.375 0.25 0.375 0.25 0.375 0.375 0.375 0.375 0.375 0.375 0.375 0.5 0.375 0.5 0 0 0 0 0 0 0.375 0.5 0.375 0.625 0.375 0.625 0 0 0 0 0 0 0.375 0.125 0.375 0.25 0.375 0.125 0.125 0.625 0.25 0.5 0.125 0.5 0.25 0.625 0.375 0.5 0.25 0.5 0.375 0.25 0.375 0.375 0.375 0.375 0 0 0 0 0 0 0.375 0.125 0.375 0.25 0.375 0.125 0 0 0 0 0 0 0.375 0.375 0.375 0.5 0.375 0.5 0 0 0 0 0 0 0.375 0.5 0.375 0.625 0.375 0.625 0.25 0.625 0.375 0.625 0.25 0.625 0.375 0.5 0.25 0.5 0.25 0.5 0.375 0.5 0.375 0.625 0.375 0.625 0.375 0.375 0.375 0.375 0.375 0.375 0 0 0 0 0 0 0.3750001 0.625 0.375 0.5 0.625 0.625 0.625 0.5 0.375 0.5 0.375 0.4082801 0.625 0.375 0.375 0.4082801 0.375 0.3316233 0.625 0.25 0.625 0.375 0.375 0.3316233 0.625 0.25 0.375 0.1604846 0.375 0.125 0.625 0.625 0.375 0.5 0.625 0.5 0.625 0.5 0.375 0.4082801 0.625 0.375 0.625 0.25 0.375 0.3316233 0.375 0.25 0.625 0.25 0.375 0.125 0.625 0.125 0.375 0.25 0.375 0.375 0.375 0.375 0.375 0.375 0.375 0.5 0.375 0.5000001 0 0 0 0 0 0 0.375 0.5000001 0.375 0.625 0.375 0.625 0 0 0 0 0 0 0.375 0.125 0.375 0.25 0.375 0.125 0.375 0.5 0.375 0.625 0.375 0.5 0.375 0.125 0.375 0.25 0.375 0.25 0 0 0 0 0 0 0.375 0.25 0.375 0.375 0.375 0.375 0 0 0 0 0 0 0.375 0.375 0.375 0.5 0.375 0.5 0.375 0.625 0.375 0.5 0 0 0 0 0.375 0.5 0.375 0.625 0.5887078 0.375 0.6068539 0.375 0.5887078 0.375 0.625 0.3125 0.625 0.375 0.625 0.375 0.6068539 0.25 0.5887078 0.25 0.6068539 0.25 0.5887078 0.3125 0.5887078 0.375 0.5887078 0.3125 0.625 0.375 0.6068539 0.375 0.6068539 0.375 0.625 0.25 0.625 0.3125 0.625 0.3125 0.5887078 0.25 0.5887078 0.3125 0.5887078 0.25 0.625 0.25 0.6068539 0.25 0.625 0.25 0.6068539 0.25 0.625 0.25 0.625 0.25 0.5887078 0.25 0.5887078 0.3125 0.5887078 0.25 0.625 0.25 0.625 0.3125 0.625 0.3125 0.625 0.375 0.6068539 0.375 0.6068539 0.375 0.5887078 0.3125 0.5887078 0.375 0.5887078 0.3125 0.6068539 0.25 0.5887078 0.25 0.6068539 0.25 0.625 0.3125 0.625 0.375 0.625 0.375 0.5887078 0.375 0.6068539 0.375 0.5887078 0.375 0.5887078 0.25 0.5887078 0.3125 0.5887078 0.25 0.6250001 0.25 0.6068539 0.25 0.625 0.25 0.625 0.375 0.6068539 0.375 0.6068539 0.375 0.6068539 0.25 0.5887078 0.25 0.6068539 0.25 0.625 0.3125 0.625 0.25 0.625 0.3125 0.5887078 0.3125 0.5887078 0.375 0.5887078 0.3125 0.5887078 0.375 0.6068539 0.375 0.5887078 0.375 0.625 0.3125 0.625 0.375 0.625 0.375 0.5887078 0.375 0.5887078 0.3125 0.5887078 0.3125 0.6068539 0.375 0.5887078 0.375 0.5887078 0.375 0.6249999 0.375 0.6068539 0.375 0.6068539 0.375 0.625 0.3125 0.625 0.25 0.625 0.3125 0.5887078 0.25 0.5887078 0.3125 0.5887078 0.25 0.625 0.3125 0.625 0.375 0.6249999 0.375 0.625 0.25 0.6068539 0.25 0.625 0.25 0.6068539 0.25 0.5887078 0.25 0.6068539 0.25 0.6068539 0.25 0.5887078 0.25 0.6068539 0.25 0.625 0.25 0.6068539 0.25 0.625 0.25 0.6249999 0.375 0.6249999 0.3125 0.6249999 0.375 0.5887078 0.2499999 0.5887078 0.3125 0.5887078 0.25 0.625 0.25 0.6249999 0.3125 0.6249999 0.3125 0.6249999 0.375 0.6068539 0.375 0.6068539 0.375 0.6068539 0.375 0.5887078 0.375 0.5887078 0.375 0.5887078 0.3125 0.5887078 0.375 0.5887078 0.3125 0.5887078 0.3125 0.5887078 0.375 0.5887078 0.3125 0.5887078 0.375 0.6068538 0.375 0.5887078 0.375 0.625 0.375 0.6068538 0.375 0.6068539 0.375 0.625 0.25 0.625 0.3125 0.625 0.3125 0.5887078 0.25 0.5887078 0.3125 0.5887078 0.25 0.625 0.3125 0.6249999 0.375 0.625 0.375 0.625 0.25 0.6068539 0.25 0.625 0.25 0.6068539 0.25 0.5887078 0.25 0.6068539 0.25 0.625 0.3125 0.625 0.375 0.625 0.375 0.6068539 0.375 0.5887078 0.375 0.5887078 0.375 0.5887078 0.375 0.5887078 0.3125 0.5887078 0.3125 0.625 0.25 0.625 0.3125 0.625 0.3125 0.6068539 0.25 0.5887078 0.25 0.6068539 0.25 0.625 0.375 0.6068539 0.375 0.6068539 0.375 0.625 0.25 0.6068539 0.25 0.6250001 0.25 0.5887078 0.25 0.5887078 0.3125 0.5887078 0.25 0.5887078 0.25 0.5887078 0.3125 0.5887078 0.25 0.6068539 0.25 0.625 0.25 0.625 0.25 0.625 0.375 0.6068539 0.375 0.6068539 0.375 0.6068539 0.25 0.5887078 0.25 0.6068539 0.25 0.625 0.25 0.625 0.3125 0.625 0.3125 0.5887078 0.3125 0.5887078 0.375 0.5887078 0.3125 0.6068539 0.375 0.5887078 0.375 0.5887078 0.375 0.625 0.3125 0.625 0.375 0.625 0.375 0.6068539 0.25 0.5887078 0.25 0.6068539 0.25 0.625 0.25 0.6068539 0.25 0.625 0.25 0.6249999 0.3125 0.6249999 0.375 0.6249999 0.375 0.5887078 0.25 0.5887078 0.3125 0.5887078 0.25 0.6249999 0.3125 0.625 0.25 0.625 0.3125 0.6249999 0.375 0.6068539 0.375 0.6068539 0.375 0.6068539 0.375 0.5887078 0.375 0.5887078 0.375 0.5887078 0.375 0.5887078 0.3125 0.5887078 0.3125 0.625 0.375 0.625 0.3125 0.625 0.375 0.625 0.25 0.6068539 0.25 0.625 0.25 0.6068539 0.25 0.5887078 0.25 0.6068539 0.25 0.5887078 0.375 0.5887078 0.3125 0.5887078 0.3125 0.5887078 0.375 0.6068539 0.375 0.5887078 0.375 0.6068539 0.375 0.625 0.375 0.6068539 0.375 0.625 0.25 0.625 0.3125 0.625 0.3125 0.5887078 0.25 0.5887078 0.3125 0.5887078 0.25 0.6068539 0.375 0.5887078 0.375 0.5887078 0.375 0.6068539 0.375 0.6068539 0.375 0.6068539 0.375 0.5887078 0.375 0.5887078 0.375 0.5887078 0.375 0 0 0 0 0 0 0.625 0.375 0.625 0.3125 0.5887078 0.3125 0.375 0.25 0.375 0.375 0.375 0.375 0.375 0.375 0.375 0.5 0.375 0.375 0 0 0 0 0 0 0.375 0.5 0.375 0.625 0.375 0.5 0 0 0 0 0 0 0.375 0.125 0.375 0.25 0.375 0.25 0.375 0.3316233 0.4230285 0.4083356 0.4205058 0.3343435 0.375 0.4082801 0.4258966 0.5 0.4230285 0.4083356 0.375 0.25 0.4189209 0.1604846 0.375 0.1604846 0.3750001 0.5895154 0.4266832 0.625 0.4264599 0.5895153 0.375 0.25 0.4205058 0.3343435 0.4179599 0.25 0.375 0.5 0.4264599 0.5895153 0.4258966 0.5 0.375 0.1604846 0.4193019 0.125 0.375 0.125 0.4767932 0.5000001 0.5406954 0.5895153 0.5490843 0.5 0.4609198 0.25 0.5416738 0.1604846 0.4628418 0.1604846 0.7093685 0.5 0.7850587 0.5895155 0.7938052 0.5000001 0.5490843 0.5 0.625 0.5895153 0.625 0.5 0.7850587 0.5895155 0.8750001 0.5000001 0.7938052 0.5000001 0.4193019 0.125 0.4628418 0.1604846 0.4636037 0.125 0.625 0.5 0.7151563 0.5895153 0.7093685 0.5 0.4258966 0.5 0.4779197 0.5895153 0.4767932 0.5000001 0.5416738 0.1604846 0.6250001 0.125 0.5369816 0.125 0.375 0.125 0.375 0.25 0.375 0.125 0 0 0 0 0 0 0.375 0.5 0.375 0.625 0.375 0.625 0 0 0 0 0 0 0.375 0.375 0.375 0.5000001 0.375 0.5 0.375 0.25 0.375 0.375 0.375 0.375 0.5887078 0.3125 0.5887078 0.375 0.5887078 0.3125 0.5887078 0.375 0.6068539 0.375 0.5887078 0.375 0.6249999 0.375 0.6068539 0.375 0.6068538 0.375 0.625 0.3125 0.625 0.25 0.6249999 0.3125 0.5887078 0.25 0.5887078 0.3125 0.5887078 0.2499999 0.625 0.3125 0.6249999 0.375 0.6249999 0.375 0.625 0.25 0.6068539 0.25 0.625 0.25 0.6068539 0.25 0.5887078 0.2499999 0.6068539 0.25 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.4179599 0.25 0.4660116 0.3370637 0.4205058 0.3343435 0.625 0.1604846 0.5535107 0.25 0.5416738 0.1604846 0.4264599 0.5895153 0.4783663 0.625 0.4266832 0.625 0.625 0.5895153 0.7174506 0.625 0.625 0.625 0.4189209 0.1604846 0.4609198 0.25 0.4179599 0.25 0.6250001 0.4156315 0.5442035 0.3363016 0.6250001 0.3311949 0.4230285 0.4083356 0.4767932 0.5000001 0.4258966 0.5 0.8750001 0.5895155 0.7815917 0.6250001 0.7850587 0.5895155 0.5428493 0.4108949 0.625 0.5 0.5490843 0.5 0.5406954 0.5895153 0.625 0.625 0.5373701 0.625 0.4205058 0.3343435 0.4710571 0.4083909 0.4230285 0.4083356 0.7815917 0.6250001 0.7151563 0.5895153 0.7850587 0.5895155 0.4628418 0.1604846 0.5369816 0.125 0.5416738 0.1604846 0.5373701 0.625 0.4779197 0.5895153 0.5406954 0.5895153 0.4710571 0.4083909 0.5442035 0.3363016 0.5428493 0.4108949 0.5535107 0.25 0.4660116 0.3370637 0.4609198 0.25 0.5490843 0.5 0.4710571 0.4083909 0.5428493 0.4108949 0.625 0.25 0.5442035 0.3363016 0.5535107 0.25 0.625 0.125 0.625 0.25 0.6068539 0.25 0.6068539 0.375 0.625 0.5 0.5887079 0.5 0.4389258 0.375 0.5028517 0.5 0.4389258 0.5 0.4389259 0.125 0.5028517 0.25 0.4389259 0.25 0.5028517 0.375 0.5524157 0.5 0.5028517 0.5 0.5524157 0.125 0.5028517 0.25 0.5028517 0.125 0.625 0.375 0.625 0.25 0.625 0.375 0.625 0.625 0.625 0.5 0.625 0.625 0.5524157 0.375 0.5887079 0.5 0.5524157 0.5 0.5887078 0.125 0.5524157 0.25 0.5524157 0.125 0.375 0.125 0.4389259 0.25 0.375 0.25 0.375 0.375 0.4389258 0.5 0.375 0.5 0.375 0.25 0.4389258 0.375 0.375 0.375 0.5887078 0.3125 0.5887078 0.375 0.5524157 0.375 0.625 0.5 0.625 0.375 0.625 0.5 0.5028517 0.25 0.5524157 0.375 0.5028517 0.375 0.4389259 0.25 0.5028517 0.375 0.4389258 0.375 0.375 0.5 0.4389258 0.625 0.375 0.625 0.5524157 0.5 0.5887079 0.625 0.5524157 0.625 0.5028517 0.5 0.5524157 0.625 0.5028517 0.625 0.4389258 0.5 0.5028517 0.625 0.4389258 0.625 0.625 0.125 0.625 0.25 0.625 0.25 0.375 0.375 0.375 0.25 0.375 0.25 0.625 0.5 0.5887079 0.625 0.5887079 0.5 0.625 0.125 0.625 0.25 0.625 0.25 0.625 0.5 0.625 0.375 0.625 0.5 0.625 0.625 0.625 0.5 0.625 0.625 0.625 0.3125 0.625 0.25 0.625 0.375 0.375 0.25 0.375 0.125 0.375 0.125 0 0 0 0 0 0 0.375 0.125 0.375 0.25 0.375 0.125 0.375 0.375 0.375 0.5 0.375 0.375 0.375 0.5 0.375 0.375 0.375 0.375 0.375 0.125 0.375 0.25 0.375 0.125 0.375 0.375 0.375 0.25 0.375 0.25 0.375 0.375 0.375 0.5 0.375 0.375 0 0 0 0 0 0 0.375 0.5 0.375 0.625 0.375 0.5 0 0 0 0 0 0 0.375 0.375 0.375 0.5 0.375 0.375 0.375 0.375 0.375 0.25 0.375 0.25 0.375 0.125 0.375 0.25 0.375 0.125 0 0 0 0 0 0 0.375 0.25 0.375 0.375 0.375 0.25 0 0 0 0 0 0 0.375 0.125 0.375 0.25 0.375 0.125 0.375 0.625 0.375 0.5 0.375 0.5 0.375 0.5 0.375 0.375 0.375 0.375 0.375 0.5 0.375 0.625 0.375 0.625 0.375 0.625 0.375 0.5 0.375 0.5 0 0 0 0 0 0 0.375 0.5 0.375 0.375 0.375 0.375 0.375 0.375 0.375 0.25 0.375 0.25 0.375 0.25 0.375 0.375 0.375 0.25 0.375 0.375 0.375 0.5 0.375 0.375 0 0 0 0 0 0 0.375 0.5 0.375 0.625 0.375 0.5 0 0 0 0 0 0 0.375 0.25 0.375 0.125 0.375 0.125 0.25 0.5 0.125 0.625 0.125 0.5 0.375 0.5 0.25 0.625 0.25 0.5 0.375 0.25 0.375 0.375 0.375 0.25 0 0 0 0 0 0 0.375 0.25 0.375 0.125 0.375 0.125 0 0 0 0 0 0 0.375 0.375 0.375 0.5 0.375 0.375 0 0 0 0 0 0 0.375 0.5 0.375 0.625 0.375 0.5 0.375 0.625 0.25 0.625 0.25 0.625 0.375 0.5 0.25 0.5 0.375 0.5 0.375 0.5 0.375 0.625 0.375 0.5 0.375 0.375 0.375 0.375 0.375 0.375 0 0 0 0 0 0 0.375 0.5 0.3750001 0.625 0.625 0.625 0.625 0.5 0.375 0.4082801 0.375 0.5 0.625 0.375 0.375 0.3316233 0.375 0.4082801 0.625 0.25 0.375 0.3316233 0.625 0.375 0.625 0.25 0.375 0.1604846 0.375 0.25 0.625 0.625 0.625 0.5 0.375 0.5 0.625 0.5 0.625 0.375 0.375 0.4082801 0.625 0.25 0.375 0.25 0.375 0.3316233 0.625 0.25 0.625 0.125 0.375 0.125 0.375 0.25 0.375 0.375 0.375 0.25 0.375 0.375 0.375 0.5 0.375 0.375 0 0 0 0 0 0 0.375 0.5000001 0.375 0.625 0.375 0.5 0 0 0 0 0 0 0.375 0.25 0.375 0.125 0.375 0.125 0.375 0.625 0.375 0.5 0.375 0.5 0.375 0.125 0.375 0.25 0.375 0.125 0 0 0 0 0 0 0.375 0.25 0.375 0.375 0.375 0.25 0 0 0 0 0 0 0.375 0.375 0.375 0.5 0.375 0.375 0.375 0.625 0.375 0.5 0.375 0.5 0 0 0.375 0.5 0.375 0.5 0.5887078 0.375 0.6068539 0.375 0.6068539 0.375 0.625 0.375 0.625 0.3125 0.625 0.375 0.6068539 0.25 0.5887078 0.25 0.5887078 0.25 0.5887078 0.3125 0.5887078 0.375 0.5887078 0.375 0.6068539 0.375 0.625 0.375 0.6068539 0.375 0.625 0.3125 0.625 0.25 0.625 0.3125 0.5887078 0.25 0.5887078 0.3125 0.5887078 0.3125 0.625 0.25 0.6068539 0.25 0.6068539 0.25 0.625 0.25 0.6068539 0.25 0.625 0.25 0.5887078 0.25 0.5887078 0.3125 0.5887078 0.3125 0.625 0.3125 0.625 0.25 0.625 0.3125 0.6068539 0.375 0.625 0.375 0.6068539 0.375 0.5887078 0.3125 0.5887078 0.375 0.5887078 0.375 0.6068539 0.25 0.5887078 0.25 0.5887078 0.25 0.625 0.375 0.625 0.3125 0.625 0.375 0.5887078 0.375 0.6068539 0.375 0.6068539 0.375 0.5887078 0.25 0.5887078 0.3125 0.5887078 0.3125 0.6250001 0.25 0.6068539 0.25 0.6068539 0.25 0.6068539 0.375 0.625 0.375 0.6068539 0.375 0.6068539 0.25 0.5887078 0.25 0.5887078 0.25 0.625 0.3125 0.625 0.25 0.6250001 0.25 0.5887078 0.3125 0.5887078 0.375 0.5887078 0.375 0.5887078 0.375 0.6068539 0.375 0.6068539 0.375 0.625 0.375 0.625 0.3125 0.625 0.375 0.5887078 0.3125 0.5887078 0.375 0.5887078 0.3125 0.5887078 0.375 0.6068539 0.375 0.5887078 0.375 0.6068539 0.375 0.6249999 0.375 0.6068539 0.375 0.625 0.3125 0.625 0.25 0.625 0.25 0.5887078 0.25 0.5887078 0.3125 0.5887078 0.3125 0.625 0.375 0.625 0.3125 0.6249999 0.375 0.625 0.25 0.6068539 0.25 0.6068539 0.25 0.6068539 0.25 0.5887078 0.25 0.5887078 0.25 0.6068539 0.25 0.5887078 0.25 0.5887078 0.2499999 0.625 0.25 0.6068539 0.25 0.6068539 0.25 0.6249999 0.375 0.6249999 0.3125 0.6249999 0.3125 0.5887078 0.2499999 0.5887078 0.3125 0.5887078 0.3125 0.6249999 0.3125 0.625 0.25 0.6249999 0.3125 0.6068539 0.375 0.6249999 0.375 0.6068539 0.375 0.5887078 0.375 0.6068539 0.375 0.5887078 0.375 0.5887078 0.3125 0.5887078 0.375 0.5887078 0.375 0.5887078 0.3125 0.5887078 0.375 0.5887078 0.375 0.5887078 0.375 0.6068538 0.375 0.6068539 0.375 0.6068538 0.375 0.625 0.375 0.6068539 0.375 0.625 0.3125 0.625 0.25 0.625 0.3125 0.5887078 0.25 0.5887078 0.3125 0.5887078 0.3125 0.6249999 0.375 0.625 0.3125 0.625 0.375 0.625 0.25 0.6068539 0.25 0.6068539 0.25 0.6068539 0.25 0.5887078 0.25 0.5887078 0.25 0.625 0.375 0.625 0.3125 0.625 0.375 0.5887078 0.375 0.6068539 0.375 0.5887078 0.375 0.5887078 0.3125 0.5887078 0.375 0.5887078 0.3125 0.625 0.3125 0.625 0.25 0.625 0.3125 0.6068539 0.25 0.5887078 0.25 0.5887078 0.25 0.6068539 0.375 0.625 0.375 0.6068539 0.375 0.625 0.25 0.6068539 0.25 0.6068539 0.25 0.5887078 0.25 0.5887078 0.3125 0.5887078 0.3125 0.5887078 0.25 0.5887078 0.3125 0.5887078 0.3125 0.625 0.25 0.6068539 0.25 0.625 0.25 0.6068539 0.375 0.625 0.375 0.6068539 0.375 0.6068539 0.25 0.5887078 0.25 0.5887078 0.25 0.625 0.3125 0.625 0.25 0.625 0.3125 0.5887078 0.3125 0.5887078 0.375 0.5887078 0.375 0.5887078 0.375 0.6068539 0.375 0.5887078 0.375 0.625 0.375 0.625 0.3125 0.625 0.375 0.6068539 0.25 0.5887078 0.25 0.5887078 0.25 0.625 0.25 0.6068539 0.25 0.6068539 0.25 0.6249999 0.375 0.6249999 0.3125 0.6249999 0.375 0.5887078 0.25 0.5887078 0.3125 0.5887078 0.3125 0.6249999 0.3125 0.625 0.25 0.625 0.25 0.6068539 0.375 0.6249999 0.375 0.6068539 0.375 0.5887078 0.375 0.6068539 0.375 0.5887078 0.375 0.5887078 0.3125 0.5887078 0.375 0.5887078 0.3125 0.625 0.375 0.625 0.3125 0.625 0.3125 0.625 0.25 0.6068539 0.25 0.6068539 0.25 0.6068539 0.25 0.5887078 0.25 0.5887078 0.25 0.5887078 0.3125 0.5887078 0.375 0.5887078 0.3125 0.5887078 0.375 0.6068539 0.375 0.6068539 0.375 0.6068539 0.375 0.625 0.375 0.625 0.375 0.625 0.3125 0.625 0.25 0.625 0.3125 0.5887078 0.25 0.5887078 0.3125 0.5887078 0.3125 0.5887078 0.375 0.6068539 0.375 0.5887078 0.375 0.6068539 0.375 0.6068539 0.375 0.6068539 0.375 0.5887078 0.375 0.5887078 0.375 0.5887078 0.375 0 0 0 0 0 0 0.5887078 0.375 0.5887078 0.3125 0.625 0.375 0.375 0.25 0.375 0.375 0.375 0.25 0.375 0.5 0.375 0.375 0.375 0.375 0 0 0 0 0 0 0.375 0.625 0.375 0.5 0.375 0.5 0 0 0 0 0 0 0.375 0.125 0.375 0.25 0.375 0.125 0.375 0.3316233 0.4230285 0.4083356 0.375 0.4082801 0.375 0.4082801 0.4258966 0.5 0.375 0.5 0.4189209 0.1604846 0.375 0.25 0.375 0.1604846 0.3750001 0.5895154 0.4266832 0.625 0.3750001 0.625 0.375 0.25 0.4205058 0.3343435 0.375 0.3316233 0.375 0.5 0.4264599 0.5895153 0.3750001 0.5895154 0.4193019 0.125 0.375 0.1604846 0.375 0.125 0.5406954 0.5895153 0.4767932 0.5000001 0.5490843 0.5 0.4609198 0.25 0.5416738 0.1604846 0.5535107 0.25 0.7850587 0.5895155 0.7093685 0.5 0.7938052 0.5000001 0.5490843 0.5 0.625 0.5895153 0.5406954 0.5895153 0.8750001 0.5000001 0.7850587 0.5895155 0.7938052 0.5000001 0.4193019 0.125 0.4628418 0.1604846 0.4189209 0.1604846 0.625 0.5 0.7151563 0.5895153 0.625 0.5895153 0.4258966 0.5 0.4779197 0.5895153 0.4264599 0.5895153 0.6250001 0.125 0.5416738 0.1604846 0.5369816 0.125 0.375 0.25 0.375 0.125 0.375 0.125 0 0 0 0 0 0 0.375 0.5 0.375 0.625 0.375 0.5000001 0 0 0 0 0 0 0.375 0.375 0.375 0.5000001 0.375 0.375 0.375 0.25 0.375 0.375 0.375 0.25 0.5887078 0.3125 0.5887078 0.375 0.5887078 0.375 0.5887078 0.375 0.6068539 0.375 0.6068538 0.375 0.6068539 0.375 0.6249999 0.375 0.6068538 0.375 0.625 0.3125 0.625 0.25 0.625 0.25 0.5887078 0.25 0.5887078 0.3125 0.5887078 0.3125 0.6249999 0.375 0.625 0.3125 0.6249999 0.375 0.625 0.25 0.6068539 0.25 0.6068539 0.25 0.6068539 0.25 0.5887078 0.2499999 0.5887078 0.25 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.4179599 0.25 0.4205058 0.3343435 0.4660116 0.3370637 0.5535107 0.25 0.625 0.25 0.625 0.1604846 0.4264599 0.5895153 0.4266832 0.625 0.4783663 0.625 0.625 0.5895153 0.625 0.625 0.7174506 0.625 0.4189209 0.1604846 0.4179599 0.25 0.4609198 0.25 0.6250001 0.4156315 0.6250001 0.3311949 0.5442035 0.3363016 0.4230285 0.4083356 0.4258966 0.5 0.4767932 0.5000001 0.7815917 0.6250001 0.8750001 0.6250001 0.8750001 0.5895155 0.5428493 0.4108949 0.5490843 0.5 0.625 0.5 0.5406954 0.5895153 0.5373701 0.625 0.625 0.625 0.4205058 0.3343435 0.4230285 0.4083356 0.4710571 0.4083909 0.7151563 0.5895153 0.7174506 0.625 0.7815917 0.6250001 0.4628418 0.1604846 0.5416738 0.1604846 0.5369816 0.125 0.4779197 0.5895153 0.4783663 0.625 0.5373701 0.625 0.4710571 0.4083909 0.5428493 0.4108949 0.5442035 0.3363016 0.5535107 0.25 0.4609198 0.25 0.4660116 0.3370637 0.4710571 0.4083909 0.4767932 0.5000001 0.5490843 0.5 0.5442035 0.3363016 0.6250001 0.3311949 0.625 0.25 0.625 0.125 0.5887078 0.125 0.6068539 0.25 0.5887078 0.125 0.5887078 0.25 0.6068539 0.25 0.6068539 0.375 0.5887078 0.375 0.5887079 0.5 0.5887079 0.5 0.625 0.5 0.6068539 0.375 0.4389258 0.375 0.4389258 0.5 0.5028517 0.5 0.4389259 0.125 0.4389259 0.25 0.5028517 0.25 0.5028517 0.375 0.5028517 0.5 0.5524157 0.5 0.5028517 0.25 0.5524157 0.25 0.5524157 0.125 0.625 0.375 0.625 0.375 0.625 0.25 0.625 0.625 0.625 0.625 0.625 0.5 0.5524157 0.375 0.5524157 0.5 0.5887079 0.5 0.5524157 0.25 0.5887078 0.25 0.5887078 0.125 0.375 0.125 0.375 0.25 0.4389259 0.25 0.375 0.375 0.375 0.5 0.4389258 0.5 0.375 0.25 0.375 0.375 0.4389258 0.375 0.5887078 0.25 0.5524157 0.25 0.5887078 0.3125 0.5524157 0.25 0.5524157 0.375 0.5887078 0.3125 0.625 0.5 0.625 0.5 0.625 0.375 0.5028517 0.25 0.5028517 0.375 0.5524157 0.375 0.4389259 0.25 0.4389258 0.375 0.5028517 0.375 0.375 0.5 0.375 0.625 0.4389258 0.625 0.5524157 0.5 0.5524157 0.625 0.5887079 0.625 0.5028517 0.5 0.5028517 0.625 0.5524157 0.625 0.4389258 0.5 0.4389258 0.625 0.5028517 0.625 0.625 0.25 0.625 0.125 0.625 0.125 0.375 0.25 0.375 0.375 0.375 0.375 0.5887079 0.625 0.625 0.625 0.625 0.5 0.625 0.25 0.625 0.125 0.625 0.125 0.625 0.5 0.625 0.5 0.625 0.375 0.625 0.625 0.625 0.625 0.625 0.5 0.625 0.3125 0.625 0.375 0.625 0.375 0.625 0.375 0.625 0.25 0.625 0.3125 0.375 0.125 0.375 0.25 0.375 0.25 0 0 0 0 0 0 0.375 0.125 0.375 0.125 0.375 0.25 0.375 0.375 0.375 0.375 0.375 0.5 0.375 0.375 0.375 0.5 0.375 0.5 0.375 0.125 0.375 0.125 0.375 0.25 0.375 0.25 0.375 0.375 0.375 0.375 0.375 0.375 0.375 0.375 0.375 0.5 0 0 0 0 0 0 0.375 0.5 0.375 0.5 0.375 0.625 0 0 0 0 0 0 0.375 0.375 0.375 0.375 0.375 0.5 0.375 0.25 0.375 0.375 0.375 0.375 0.375 0.125 0.375 0.125 0.375 0.25 0 0 0 0 0 0 0.375 0.25 0.375 0.25 0.375 0.375 0 0 0 0 0 0 0.375 0.125 0.375 0.125 0.375 0.25 0.375 0.5 0.375 0.625 0.375 0.625 0.375 0.375 0.375 0.5 0.375 0.5 0.375 0.625 0.375 0.5 0.375 0.5 0.375 0.5 0.375 0.625 0.375 0.625 0 0 0 0 0 0 0.375 0.375 0.375 0.5 0.375 0.5 0.375 0.25 0.375 0.375 0.375 0.375 0.375 0.25 0.375 0.25 0.375 0.375 0.375 0.375 0.375 0.375 0.375 0.5 0 0 0 0 0 0 0.375 0.5 0.375 0.5 0.375 0.625 0 0 0 0 0 0 0.375 0.125 0.375 0.25 0.375 0.25 0.125 0.625 0.25 0.625 0.25 0.5 0.25 0.625 0.375 0.625 0.375 0.5 0.375 0.25 0.375 0.25 0.375 0.375 0 0 0 0 0 0 0.375 0.125 0.375 0.25 0.375 0.25 0 0 0 0 0 0 0.375 0.375 0.375 0.375 0.375 0.5 0 0 0 0 0 0 0.375 0.5 0.375 0.5 0.375 0.625 0.25 0.625 0.375 0.625 0.375 0.625 0.375 0.5 0.375 0.5 0.25 0.5 0.375 0.5 0.375 0.5 0.375 0.625 0.375 0.375 0.375 0.375 0.375 0.375 0 0 0 0 0 0 0.3750001 0.625 0.3750001 0.5895154 0.375 0.5 0.625 0.25 0.375 0.25 0.375 0.1604846 0.375 0.25 0.375 0.25 0.375 0.375 0.375 0.375 0.375 0.375 0.375 0.5 0 0 0 0 0 0 0.375 0.5000001 0.375 0.5 0.375 0.625 0 0 0 0 0 0 0.375 0.125 0.375 0.25 0.375 0.25 0.375 0.5 0.375 0.625 0.375 0.625 0.375 0.125 0.375 0.125 0.375 0.25 0 0 0 0 0 0 0.375 0.25 0.375 0.25 0.375 0.375 0 0 0 0 0 0 0.375 0.375 0.375 0.375 0.375 0.5 0.375 0.625 0.375 0.5 0.375 0.5 0 0 0.375 0.5 0.375 0.5 0.5887078 0.375 0.6068539 0.375 0.6068539 0.375 0.625 0.3125 0.625 0.3125 0.625 0.375 0.6068539 0.25 0.5887078 0.25 0.5887078 0.25 0.5887078 0.3125 0.5887078 0.375 0.5887078 0.375 0.625 0.375 0.625 0.375 0.6068539 0.375 0.625 0.25 0.625 0.25 0.625 0.3125 0.5887078 0.25 0.5887078 0.3125 0.5887078 0.3125 0.625 0.25 0.6068539 0.25 0.6068539 0.25 0.6068539 0.25 0.6068539 0.25 0.625 0.25 0.5887078 0.25 0.5887078 0.3125 0.5887078 0.3125 0.625 0.25 0.625 0.25 0.625 0.3125 0.625 0.375 0.625 0.375 0.6068539 0.375 0.5887078 0.3125 0.5887078 0.375 0.5887078 0.375 0.6068539 0.25 0.5887078 0.25 0.5887078 0.25 0.625 0.3125 0.625 0.3125 0.625 0.375 0.5887078 0.375 0.6068539 0.375 0.6068539 0.375 0.5887078 0.25 0.5887078 0.3125 0.5887078 0.3125 0.6250001 0.25 0.6068539 0.25 0.6068539 0.25 0.625 0.375 0.625 0.375 0.6068539 0.375 0.6068539 0.25 0.5887078 0.25 0.5887078 0.25 0.625 0.3125 0.6250001 0.25 0.625 0.25 0.5887078 0.3125 0.5887078 0.375 0.5887078 0.375 0.5887078 0.375 0.6068539 0.375 0.6068539 0.375 0.625 0.3125 0.625 0.3125 0.625 0.375 0.5887078 0.375 0.5887078 0.375 0.5887078 0.3125 0.6068539 0.375 0.6068539 0.375 0.5887078 0.375 0.6249999 0.375 0.625 0.375 0.6068539 0.375 0.625 0.3125 0.625 0.25 0.625 0.25 0.5887078 0.25 0.5887078 0.3125 0.5887078 0.3125 0.625 0.3125 0.625 0.3125 0.625 0.375 0.625 0.25 0.6068539 0.25 0.6068539 0.25 0.6068539 0.25 0.5887078 0.25 0.5887078 0.25 0.6068539 0.25 0.5887078 0.2499999 0.5887078 0.25 0.625 0.25 0.6068539 0.25 0.6068539 0.25 0.6249999 0.375 0.6249999 0.3125 0.6249999 0.3125 0.5887078 0.2499999 0.5887078 0.3125 0.5887078 0.3125 0.625 0.25 0.625 0.25 0.6249999 0.3125 0.6249999 0.375 0.6249999 0.375 0.6068539 0.375 0.6068539 0.375 0.6068539 0.375 0.5887078 0.375 0.5887078 0.3125 0.5887078 0.375 0.5887078 0.375 0.5887078 0.3125 0.5887078 0.375 0.5887078 0.375 0.5887078 0.375 0.6068539 0.375 0.6068538 0.375 0.625 0.375 0.6249999 0.375 0.6068538 0.375 0.625 0.25 0.625 0.25 0.625 0.3125 0.5887078 0.25 0.5887078 0.3125 0.5887078 0.3125 0.625 0.3125 0.625 0.3125 0.6249999 0.375 0.625 0.25 0.6068539 0.25 0.6068539 0.25 0.6068539 0.25 0.5887078 0.25 0.5887078 0.25 0.625 0.3125 0.625 0.3125 0.625 0.375 0.6068539 0.375 0.6068539 0.375 0.5887078 0.375 0.5887078 0.375 0.5887078 0.375 0.5887078 0.3125 0.625 0.25 0.6250001 0.25 0.625 0.3125 0.6068539 0.25 0.5887078 0.25 0.5887078 0.25 0.625 0.375 0.625 0.375 0.6068539 0.375 0.625 0.25 0.6068539 0.25 0.6068539 0.25 0.5887078 0.25 0.5887078 0.3125 0.5887078 0.3125 0.5887078 0.25 0.5887078 0.3125 0.5887078 0.3125 0.6068539 0.25 0.6068539 0.25 0.625 0.25 0.625 0.375 0.625 0.375 0.6068539 0.375 0.6068539 0.25 0.5887078 0.25 0.5887078 0.25 0.625 0.25 0.625 0.25 0.625 0.3125 0.5887078 0.3125 0.5887078 0.375 0.5887078 0.375 0.6068539 0.375 0.6068539 0.375 0.5887078 0.375 0.625 0.3125 0.625 0.3125 0.625 0.375 0.6068539 0.25 0.5887078 0.25 0.5887078 0.25 0.625 0.25 0.6068539 0.25 0.6068539 0.25 0.6249999 0.3125 0.625 0.3125 0.6249999 0.375 0.5887078 0.25 0.5887078 0.3125 0.5887078 0.3125 0.6249999 0.3125 0.625 0.25 0.625 0.25 0.6249999 0.375 0.6249999 0.375 0.6068539 0.375 0.6068539 0.375 0.6068539 0.375 0.5887078 0.375 0.5887078 0.375 0.5887078 0.375 0.5887078 0.3125 0.625 0.375 0.625 0.3125 0.625 0.3125 0.625 0.25 0.6068539 0.25 0.6068539 0.25 0.6068539 0.25 0.5887078 0.25 0.5887078 0.25 0.5887078 0.375 0.5887078 0.375 0.5887078 0.3125 0.5887078 0.375 0.6068539 0.375 0.6068539 0.375 0.6068539 0.375 0.625 0.375 0.625 0.375 0.625 0.25 0.625 0.25 0.625 0.3125 0.5887078 0.25 0.5887078 0.3125 0.5887078 0.3125 0.6068539 0.375 0.6068539 0.375 0.5887078 0.375 0.6068539 0.375 0.6068539 0.375 0.6068539 0.375 0.5887078 0.375 0.5887078 0.375 0.5887078 0.375 0 0 0 0 0 0 0.625 0.25 0.6068539 0.25 0.5887078 0.25 0.5887078 0.25 0.5887078 0.3125 0.625 0.3125 0.5887078 0.3125 0.5887078 0.375 0.625 0.375 0.5887078 0.25 0.625 0.3125 0.625 0.25 0.5887078 0.375 0 0 0.625 0.375 0.375 0.25 0.375 0.25 0.375 0.375 0.375 0.375 0.375 0.5 0.375 0.5 0 0 0 0 0 0 0.375 0.5 0.375 0.625 0.375 0.625 0 0 0 0 0 0 0.375 0.125 0.375 0.125 0.375 0.25 0.375 0.3316233 0.375 0.4082801 0.4230285 0.4083356 0.375 0.4082801 0.375 0.5 0.4258966 0.5 0.375 0.25 0.4179599 0.25 0.4189209 0.1604846 0.3750001 0.5895154 0.3750001 0.625 0.4266832 0.625 0.375 0.25 0.375 0.3316233 0.4205058 0.3343435 0.375 0.5 0.3750001 0.5895154 0.4264599 0.5895153 0.375 0.1604846 0.4189209 0.1604846 0.4193019 0.125 0.4767932 0.5000001 0.4779197 0.5895153 0.5406954 0.5895153 0.4609198 0.25 0.5535107 0.25 0.5416738 0.1604846 0.7093685 0.5 0.7151563 0.5895153 0.7850587 0.5895155 0.5490843 0.5 0.5406954 0.5895153 0.625 0.5895153 0.7850587 0.5895155 0.8750001 0.5895155 0.8750001 0.5000001 0.4193019 0.125 0.4189209 0.1604846 0.4628418 0.1604846 0.625 0.5 0.625 0.5895153 0.7151563 0.5895153 0.4258966 0.5 0.4264599 0.5895153 0.4779197 0.5895153 0.5416738 0.1604846 0.625 0.1604846 0.6250001 0.125 0.375 0.125 0.375 0.25 0.375 0.25 0 0 0 0 0 0 0.375 0.5 0.375 0.5000001 0.375 0.625 0 0 0 0 0 0 0.375 0.375 0.375 0.375 0.375 0.5000001 0.375 0.25 0.375 0.25 0.375 0.375 0.5887078 0.3125 0.5887078 0.375 0.5887078 0.375 0.5887078 0.375 0.6068538 0.375 0.6068539 0.375 0.6249999 0.375 0.6249999 0.375 0.6068539 0.375 0.625 0.3125 0.625 0.25 0.625 0.25 0.5887078 0.25 0.5887078 0.3125 0.5887078 0.3125 0.625 0.3125 0.6249999 0.3125 0.6249999 0.375 0.625 0.25 0.6068539 0.25 0.6068539 0.25 0.6068539 0.25 0.5887078 0.25 0.5887078 0.2499999 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.4179599 0.25 0.4609198 0.25 0.4660116 0.3370637 0.625 0.1604846 0.625 0.25 0.5535107 0.25 0.4264599 0.5895153 0.4779197 0.5895153 0.4783663 0.625 0.625 0.5895153 0.7151563 0.5895153 0.7174506 0.625 0.4189209 0.1604846 0.4628418 0.1604846 0.4609198 0.25 0.6250001 0.4156315 0.5428493 0.4108949 0.5442035 0.3363016 0.4230285 0.4083356 0.4710571 0.4083909 0.4767932 0.5000001 0.8750001 0.5895155 0.8750001 0.6250001 0.7815917 0.6250001 0.5428493 0.4108949 0.6250001 0.4156315 0.625 0.5 0.5406954 0.5895153 0.625 0.5895153 0.625 0.625 0.4205058 0.3343435 0.4660116 0.3370637 0.4710571 0.4083909 0.7815917 0.6250001 0.7174506 0.625 0.7151563 0.5895153 0.4628418 0.1604846 0.4636037 0.125 0.5369816 0.125 0.5373701 0.625 0.4783663 0.625 0.4779197 0.5895153 0.4710571 0.4083909 0.4660116 0.3370637 0.5442035 0.3363016 0.5535107 0.25 0.5442035 0.3363016 0.4660116 0.3370637 0.5490843 0.5 0.4767932 0.5000001 0.4710571 0.4083909 0.625 0.25 0.6250001 0.3311949 0.5442035 0.3363016 0.5887078 0.25 0.5887078 0.125 0.6068539 0.25 0.5887078 0.125 0.625 0.125 0.6068539 0.25 0.5887079 0.5 0.5887078 0.375 0.6068539 0.375 0.6068539 0.375 0.625 0.375 0.625 0.5 0.4389258 0.375 0.5028517 0.375 0.5028517 0.5 0.4389259 0.125 0.5028517 0.125 0.5028517 0.25 0.5028517 0.375 0.5524157 0.375 0.5524157 0.5 0.5524157 0.125 0.5524157 0.25 0.5028517 0.25 0.625 0.375 0.625 0.25 0.625 0.25 0.625 0.625 0.625 0.5 0.625 0.5 0.5524157 0.375 0.5887078 0.375 0.5887079 0.5 0.5887078 0.125 0.5887078 0.25 0.5524157 0.25 0.375 0.125 0.4389259 0.125 0.4389259 0.25 0.375 0.375 0.4389258 0.375 0.4389258 0.5 0.375 0.25 0.4389259 0.25 0.4389258 0.375 0.5524157 0.375 0.5524157 0.25 0.5887078 0.3125 0.5524157 0.25 0.5887078 0.25 0.5887078 0.3125 0.625 0.5 0.625 0.375 0.625 0.375 0.5028517 0.25 0.5524157 0.25 0.5524157 0.375 0.4389259 0.25 0.5028517 0.25 0.5028517 0.375 0.375 0.5 0.4389258 0.5 0.4389258 0.625 0.5524157 0.5 0.5887079 0.5 0.5887079 0.625 0.5028517 0.5 0.5524157 0.5 0.5524157 0.625 0.4389258 0.5 0.5028517 0.5 0.5028517 0.625 0.625 0.125 0.625 0.125 0.625 0.25 0.375 0.375 0.375 0.375 0.375 0.25 0.625 0.5 0.625 0.625 0.5887079 0.625 0.625 0.125 0.625 0.125 0.625 0.25 0.625 0.5 0.625 0.375 0.625 0.375 0.625 0.625 0.625 0.5 0.625 0.5 0.625 0.375 0.625 0.375 0.625 0.3125 0.625 0.3125 0.625 0.25 0.625 0.25 0.375 0.25 0.375 0.25 0.375 0.125 0 0 0 0 0 0 0.375 0.125 0.375 0.25 0.375 0.25 0.375 0.375 0.375 0.5 0.375 0.5 0.375 0.5 0.375 0.5 0.375 0.375 0.375 0.125 0.375 0.25 0.375 0.25 0.375 0.375 0.375 0.375 0.375 0.25 0.375 0.375 0.375 0.5 0.375 0.5 0 0 0 0 0 0 0.375 0.5 0.375 0.625 0.375 0.625 0 0 0 0 0 0 0.375 0.375 0.375 0.5 0.375 0.5 0.375 0.375 0.375 0.375 0.375 0.25 0.375 0.125 0.375 0.25 0.375 0.25 0 0 0 0 0 0 0.375 0.25 0.375 0.375 0.375 0.375 0 0 0 0 0 0 0.375 0.125 0.375 0.25 0.375 0.25 0.375 0.625 0.375 0.625 0.375 0.5 0.375 0.5 0.375 0.5 0.375 0.375 0.375 0.5 0.375 0.5 0.375 0.625 0.375 0.625 0.375 0.625 0.375 0.5 0 0 0 0 0 0 0.375 0.5 0.375 0.5 0.375 0.375 0.375 0.375 0.375 0.375 0.375 0.25 0.375 0.25 0.375 0.375 0.375 0.375 0.375 0.375 0.375 0.5 0.375 0.5 0 0 0 0 0 0 0.375 0.5 0.375 0.625 0.375 0.625 0 0 0 0 0 0 0.375 0.25 0.375 0.25 0.375 0.125 0.25 0.5 0.25 0.625 0.125 0.625 0.375 0.5 0.375 0.625 0.25 0.625 0.375 0.25 0.375 0.375 0.375 0.375 0 0 0 0 0 0 0.375 0.25 0.375 0.25 0.375 0.125 0 0 0 0 0 0 0.375 0.375 0.375 0.5 0.375 0.5 0 0 0 0 0 0 0.375 0.5 0.375 0.625 0.375 0.625 0.375 0.625 0.375 0.625 0.25 0.625 0.375 0.5 0.25 0.5 0.25 0.5 0.375 0.5 0.375 0.625 0.375 0.625 0.375 0.375 0.375 0.375 0.375 0.375 0 0 0 0 0 0 0.375 0.5 0.3750001 0.5895154 0.3750001 0.625 0.625 0.25 0.375 0.125 0.375 0.1604846 0.375 0.25 0.375 0.375 0.375 0.375 0.375 0.375 0.375 0.5000001 0.375 0.5 0 0 0 0 0 0 0.375 0.5000001 0.375 0.625 0.375 0.625 0 0 0 0 0 0 0.375 0.25 0.375 0.25 0.375 0.125 0.375 0.625 0.375 0.625 0.375 0.5 0.375 0.125 0.375 0.25 0.375 0.25 0 0 0 0 0 0 0.375 0.25 0.375 0.375 0.375 0.375 0 0 0 0 0 0 0.375 0.375 0.375 0.5 0.375 0.5 0.375 0.625 0 0 0.375 0.5 0 0 0.375 0.625 0.375 0.5 0.5887078 0.375 0.5887078 0.375 0.6068539 0.375 0.625 0.375 0.625 0.3125 0.625 0.3125 0.6068539 0.25 0.6068539 0.25 0.5887078 0.25 0.5887078 0.3125 0.5887078 0.3125 0.5887078 0.375 0.6068539 0.375 0.625 0.375 0.625 0.375 0.625 0.3125 0.625 0.25 0.625 0.25 0.5887078 0.25 0.5887078 0.25 0.5887078 0.3125 0.625 0.25 0.625 0.25 0.6068539 0.25 0.625 0.25 0.6068539 0.25 0.6068539 0.25 0.5887078 0.25 0.5887078 0.25 0.5887078 0.3125 0.625 0.3125 0.625 0.25 0.625 0.25 0.6068539 0.375 0.625 0.375 0.625 0.375 0.5887078 0.3125 0.5887078 0.3125 0.5887078 0.375 0.6068539 0.25 0.6068539 0.25 0.5887078 0.25 0.625 0.375 0.625 0.3125 0.625 0.3125 0.5887078 0.375 0.5887078 0.375 0.6068539 0.375 0.5887078 0.25 0.5887078 0.25 0.5887078 0.3125 0.6250001 0.25 0.625 0.25 0.6068539 0.25 0.6068539 0.375 0.625 0.375 0.625 0.375 0.6068539 0.25 0.6068539 0.25 0.5887078 0.25 0.625 0.3125 0.625 0.3125 0.625 0.25 0.5887078 0.3125 0.5887078 0.3125 0.5887078 0.375 0.5887078 0.375 0.5887078 0.375 0.6068539 0.375 0.625 0.375 0.625 0.3125 0.625 0.3125 0.5887078 0.3125 0.5887078 0.375 0.5887078 0.375 0.5887078 0.375 0.6068539 0.375 0.6068539 0.375 0.6068539 0.375 0.625 0.375 0.6249999 0.375 0.625 0.3125 0.625 0.3125 0.625 0.25 0.5887078 0.25 0.5887078 0.25 0.5887078 0.3125 0.625 0.375 0.625 0.3125 0.625 0.3125 0.625 0.25 0.625 0.25 0.6068539 0.25 0.6068539 0.25 0.6068539 0.25 0.5887078 0.25 0.6068539 0.25 0.6068539 0.25 0.5887078 0.25 0.625 0.25 0.625 0.25 0.6068539 0.25 0.6249999 0.375 0.6249999 0.375 0.6249999 0.3125 0.5887078 0.2499999 0.5887078 0.25 0.5887078 0.3125 0.6249999 0.3125 0.625 0.25 0.625 0.25 0.6068539 0.375 0.6249999 0.375 0.6249999 0.375 0.5887078 0.375 0.6068539 0.375 0.6068539 0.375 0.5887078 0.3125 0.5887078 0.3125 0.5887078 0.375 0.5887078 0.3125 0.5887078 0.3125 0.5887078 0.375 0.5887078 0.375 0.5887078 0.375 0.6068538 0.375 0.6068538 0.375 0.6249999 0.375 0.625 0.375 0.625 0.3125 0.625 0.25 0.625 0.25 0.5887078 0.25 0.5887078 0.25 0.5887078 0.3125 0.6249999 0.375 0.625 0.3125 0.625 0.3125 0.625 0.25 0.625 0.25 0.6068539 0.25 0.6068539 0.25 0.6068539 0.25 0.5887078 0.25 0.625 0.375 0.625 0.3125 0.625 0.3125 0.5887078 0.375 0.6068539 0.375 0.6068539 0.375 0.5887078 0.3125 0.5887078 0.375 0.5887078 0.375 0.625 0.3125 0.6250001 0.25 0.625 0.25 0.6068539 0.25 0.6068539 0.25 0.5887078 0.25 0.6068539 0.375 0.625 0.375 0.625 0.375 0.625 0.25 0.6250001 0.25 0.6068539 0.25 0.5887078 0.25 0.5887078 0.25 0.5887078 0.3125 0.5887078 0.25 0.5887078 0.25 0.5887078 0.3125 0.625 0.25 0.6068539 0.25 0.6068539 0.25 0.6068539 0.375 0.625 0.375 0.625 0.375 0.6068539 0.25 0.6068539 0.25 0.5887078 0.25 0.625 0.3125 0.625 0.25 0.625 0.25 0.5887078 0.3125 0.5887078 0.3125 0.5887078 0.375 0.5887078 0.375 0.6068539 0.375 0.6068539 0.375 0.625 0.375 0.625 0.3125 0.625 0.3125 0.6068539 0.25 0.6068539 0.25 0.5887078 0.25 0.625 0.25 0.625 0.25 0.6068539 0.25 0.6249999 0.375 0.625 0.3125 0.6249999 0.3125 0.5887078 0.25 0.5887078 0.25 0.5887078 0.3125 0.6249999 0.3125 0.625 0.3125 0.625 0.25 0.6068539 0.375 0.6249999 0.375 0.6249999 0.375 0.5887078 0.375 0.6068539 0.375 0.6068539 0.375 0.5887078 0.3125 0.5887078 0.375 0.5887078 0.375 0.625 0.375 0.625 0.375 0.625 0.3125 0.625 0.25 0.625 0.25 0.6068539 0.25 0.6068539 0.25 0.6068539 0.25 0.5887078 0.25 0.5887078 0.3125 0.5887078 0.375 0.5887078 0.375 0.5887078 0.375 0.5887078 0.375 0.6068539 0.375 0.6068539 0.375 0.6068539 0.375 0.625 0.375 0.625 0.3125 0.625 0.25 0.625 0.25 0.5887078 0.25 0.5887078 0.25 0.5887078 0.3125 0.5887078 0.375 0.6068539 0.375 0.6068539 0.375 0.6068539 0.375 0.6068539 0.375 0.6068539 0.375 0.5887078 0.375 0.5887078 0.375 0.5887078 0.375 0 0 0 0 0 0 0.5887078 0.25 0.6068539 0.25 0.625 0.25 0.625 0.25 0.625 0.3125 0.5887078 0.25 0.625 0.3125 0.625 0.375 0.5887078 0.3125 0.5887078 0.25 0.625 0.3125 0.5887078 0.3125 0.625 0.375 0 0 0.5887078 0.375 0.375 0.25 0.375 0.375 0.375 0.375 0.375 0.5 0.375 0.5 0.375 0.375 0 0 0 0 0 0 0.375 0.625 0.375 0.625 0.375 0.5 0 0 0 0 0 0 0.375 0.125 0.375 0.25 0.375 0.25 0.375 0.3316233 0.4205058 0.3343435 0.4230285 0.4083356 0.375 0.4082801 0.4230285 0.4083356 0.4258966 0.5 0.4189209 0.1604846 0.4179599 0.25 0.375 0.25 0.3750001 0.5895154 0.4264599 0.5895153 0.4266832 0.625 0.375 0.25 0.4179599 0.25 0.4205058 0.3343435 0.375 0.5 0.4258966 0.5 0.4264599 0.5895153 0.4193019 0.125 0.4189209 0.1604846 0.375 0.1604846 0.5406954 0.5895153 0.4779197 0.5895153 0.4767932 0.5000001 0.4609198 0.25 0.4628418 0.1604846 0.5416738 0.1604846 0.7850587 0.5895155 0.7151563 0.5895153 0.7093685 0.5 0.5490843 0.5 0.625 0.5 0.625 0.5895153 0.8750001 0.5000001 0.8750001 0.5895155 0.7850587 0.5895155 0.4193019 0.125 0.4636037 0.125 0.4628418 0.1604846 0.625 0.5 0.7093685 0.5 0.7151563 0.5895153 0.4258966 0.5 0.4767932 0.5000001 0.4779197 0.5895153 0.6250001 0.125 0.625 0.1604846 0.5416738 0.1604846 0.375 0.25 0.375 0.25 0.375 0.125 0 0 0 0 0 0 0.375 0.5 0.375 0.625 0.375 0.625 0 0 0 0 0 0 0.375 0.375 0.375 0.5 0.375 0.5000001 0.375 0.25 0.375 0.375 0.375 0.375 0.5887078 0.3125 0.5887078 0.3125 0.5887078 0.375 0.5887078 0.375 0.5887078 0.375 0.6068539 0.375 0.6068539 0.375 0.6249999 0.375 0.6249999 0.375 0.625 0.3125 0.6249999 0.3125 0.625 0.25 0.5887078 0.25 0.5887078 0.2499999 0.5887078 0.3125 0.6249999 0.375 0.6249999 0.3125 0.625 0.3125 0.625 0.25 0.625 0.25 0.6068539 0.25 0.6068539 0.25 0.6068539 0.25 0.5887078 0.2499999 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 + + + + + + + + + 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 + + + + + + + + + + + + + + + + + +

    223 0 0 0 45 0 1 1 40 0 2 2 39 1 3 3 228 1 4 4 234 1 5 5 238 2 6 6 8 2 7 7 236 2 8 8 230 3 9 9 4 3 10 10 232 3 11 11 237 4 12 12 40 4 13 13 233 4 14 14 38 5 15 15 46 5 16 16 43 5 17 17 225 6 18 18 41 6 19 19 44 6 20 20 5 7 21 21 228 7 22 22 231 7 23 23 43 8 24 24 34 8 25 25 38 8 26 26 235 9 27 27 3 9 28 28 230 9 29 29 224 10 30 30 44 10 31 31 45 10 32 32 232 11 33 33 5 11 34 34 231 11 35 35 233 12 36 36 6 12 37 37 7 12 38 38 236 13 39 39 9 13 40 40 235 13 41 41 44 14 42 42 46 14 43 43 45 14 44 44 39 15 45 45 45 15 46 46 46 15 47 47 44 16 48 48 42 16 49 49 43 16 50 50 46 17 51 51 32 17 52 52 39 17 53 53 127 18 54 54 48 18 55 55 11 18 56 56 50 19 57 57 62 19 58 58 130 19 59 59 67 20 60 60 52 20 61 61 63 20 62 62 22 21 63 63 51 21 64 64 15 21 65 65 63 22 66 66 54 22 67 67 64 22 68 68 51 23 69 69 17 23 70 70 15 23 71 71 70 24 72 72 55 24 73 73 68 24 74 74 24 25 75 75 56 25 76 76 69 25 77 77 64 26 78 78 58 26 79 79 66 26 80 80 53 27 81 81 21 27 82 82 17 27 83 83 10 28 84 84 59 28 85 85 22 28 86 86 61 29 87 87 60 29 88 88 67 29 89 89 47 30 90 90 67 30 91 91 59 30 92 92 64 31 93 93 66 31 94 94 129 31 95 95 69 32 96 96 65 32 97 97 70 32 98 98 51 33 99 99 64 33 100 100 53 33 101 101 59 34 102 102 63 34 103 103 51 34 104 104 49 35 105 105 23 35 106 106 60 35 107 107 54 36 108 108 20 36 109 109 58 36 110 110 52 37 111 111 16 37 112 112 54 37 113 113 60 38 114 114 14 38 115 115 52 38 116 116 55 39 117 117 25 39 118 118 68 39 119 119 72 40 120 120 74 40 121 121 75 40 122 122 20 41 123 123 50 41 124 124 58 41 125 125 68 42 126 126 11 42 127 127 48 42 128 128 50 43 129 129 70 43 130 130 62 43 131 131 13 44 132 132 69 44 133 133 50 44 134 134 68 45 135 135 48 45 136 136 128 45 137 137 81 46 138 138 117 46 139 139 115 46 140 140 82 47 141 141 115 47 142 142 116 47 143 143 29 48 144 144 72 48 145 145 75 48 146 146 74 49 147 147 73 49 148 148 76 49 149 149 74 50 150 150 49 50 151 151 61 50 152 152 10 51 153 153 75 51 154 154 47 51 155 155 75 52 156 156 61 52 157 157 47 52 158 158 124 53 159 159 86 53 160 160 123 53 161 161 85 54 162 162 121 54 163 163 122 54 164 164 119 55 165 165 79 55 166 166 118 55 167 167 79 56 168 168 116 56 169 169 118 56 170 170 120 57 171 171 80 57 172 172 119 57 173 173 78 58 174 174 120 58 175 175 117 58 176 176 215 59 177 177 90 59 178 178 216 59 179 179 218 60 180 180 93 60 181 181 215 60 182 182 125 61 183 183 83 61 184 184 124 61 185 185 88 62 186 186 126 62 187 187 121 62 188 188 126 63 189 189 84 63 190 190 125 63 191 191 86 64 192 192 122 64 193 193 123 64 194 194 109 65 195 195 92 65 196 196 89 65 197 197 112 66 198 198 104 66 199 199 103 66 200 200 92 67 201 201 217 67 202 202 219 67 203 203 217 68 204 204 94 68 205 205 218 68 206 206 89 69 207 207 219 69 208 208 220 69 209 209 90 70 210 210 220 70 211 211 216 70 212 212 84 71 213 213 100 71 214 214 83 71 215 215 83 72 216 216 99 72 217 217 86 72 218 218 85 73 219 219 96 73 220 220 88 73 221 221 86 74 222 222 98 74 223 223 85 74 224 224 96 75 225 225 87 75 226 226 88 75 227 227 95 76 228 228 84 76 229 229 87 76 230 230 105 77 231 231 101 77 232 232 102 77 233 233 106 78 234 234 104 78 235 235 101 78 236 236 90 79 237 237 101 79 238 238 89 79 239 239 106 80 240 240 93 80 241 241 94 80 242 242 105 81 243 243 90 81 244 244 93 81 245 245 110 82 246 246 106 82 247 247 94 82 248 248 109 83 249 249 113 83 250 250 108 83 251 251 112 84 252 252 110 84 253 253 107 84 254 254 108 85 255 255 112 85 256 256 107 85 257 257 111 86 258 258 103 86 259 259 106 86 260 260 104 87 261 261 114 87 262 262 101 87 263 263 92 88 264 264 107 88 265 265 91 88 266 266 101 89 267 267 109 89 268 268 89 89 269 269 91 90 270 270 110 90 271 271 94 90 272 272 2 91 273 273 33 91 274 274 19 91 275 275 56 92 276 276 33 92 277 277 35 92 278 278 65 93 279 279 35 93 280 280 36 93 281 281 55 94 282 282 65 94 283 283 36 94 284 284 55 95 285 285 227 95 286 286 0 95 287 287 19 96 288 288 33 96 289 289 56 96 290 290 56 97 291 291 35 97 292 292 65 97 293 293 55 98 294 294 36 98 295 295 31 98 296 296 55 99 297 297 0 99 298 298 18 99 299 299 243 100 300 300 120 100 301 301 241 100 302 302 241 101 303 303 119 101 304 304 240 101 305 305 118 102 306 306 239 102 307 307 244 102 308 308 240 103 309 309 118 103 310 310 244 103 311 311 116 104 312 312 242 104 313 313 239 104 314 314 115 105 315 315 243 105 316 316 242 105 317 317 123 106 318 318 79 106 319 319 80 106 320 320 81 107 321 321 125 107 322 322 78 107 323 323 121 108 324 324 81 108 325 325 82 108 326 326 78 109 327 327 124 109 328 328 77 109 329 329 122 110 330 330 82 110 331 331 79 110 332 332 77 111 333 333 123 111 334 334 80 111 335 335 12 112 336 336 76 112 337 337 30 112 338 338 30 113 339 339 73 113 340 340 26 113 341 341 146 114 342 342 133 114 343 343 138 114 344 344 139 115 345 345 134 115 346 346 143 115 347 347 145 116 348 348 136 116 349 349 137 116 350 350 144 117 351 351 138 117 352 352 135 117 353 353 143 118 354 354 133 118 355 355 140 118 356 356 142 119 357 357 131 119 358 358 139 119 359 359 141 120 360 360 135 120 361 361 136 120 362 362 142 121 363 363 137 121 364 364 132 121 365 365 127 122 366 366 142 122 367 367 48 122 368 368 57 123 369 369 144 123 370 370 141 123 371 371 48 124 372 372 139 124 373 373 128 124 374 374 62 125 375 375 140 125 376 376 130 125 377 377 129 126 378 378 146 126 379 379 144 126 380 380 127 127 381 381 141 127 382 382 145 127 383 383 128 128 384 384 143 128 385 385 62 128 386 386 66 129 387 387 140 129 388 388 146 129 389 389 180 130 390 390 150 130 391 391 149 130 392 392 182 131 393 393 148 131 394 394 153 131 395 395 179 132 396 396 152 132 397 397 184 132 398 398 183 133 399 399 149 133 400 400 148 133 401 401 186 134 402 402 153 134 403 403 154 134 404 404 181 135 405 405 147 135 406 406 150 135 407 407 185 136 408 408 152 136 409 409 147 136 410 410 186 137 411 411 151 137 412 412 179 137 413 413 195 138 414 414 158 138 415 415 200 138 416 416 196 139 417 417 155 139 418 418 195 139 419 419 197 140 420 420 160 140 421 421 196 140 422 422 201 141 423 423 161 141 424 424 162 141 425 425 202 142 426 426 158 142 427 427 157 142 428 428 201 143 429 429 159 143 430 430 197 143 431 431 198 144 432 432 156 144 433 433 161 144 434 434 199 145 435 435 157 145 436 436 156 145 437 437 249 146 438 438 169 146 439 439 170 146 440 440 248 147 441 441 170 147 442 442 167 147 443 443 247 148 444 444 168 148 445 445 166 148 446 446 252 149 447 447 164 149 448 448 169 149 449 449 248 150 450 450 168 150 451 451 251 150 452 452 247 151 453 453 165 151 454 454 246 151 455 455 246 152 456 456 163 152 457 457 245 152 458 458 250 153 459 459 163 153 460 460 164 153 461 461 150 154 462 462 174 154 463 463 171 154 464 464 147 155 465 465 175 155 466 466 174 155 467 467 151 156 468 468 175 156 469 469 152 156 470 470 153 157 471 471 172 157 472 472 154 157 473 473 149 158 474 474 171 158 475 475 173 158 476 476 154 159 477 477 176 159 478 478 151 159 479 479 153 160 480 480 178 160 481 481 177 160 482 482 148 161 483 483 173 161 484 484 178 161 485 485 192 162 486 486 179 162 487 487 193 162 488 488 190 163 489 489 185 163 490 490 191 163 491 491 191 164 492 492 181 164 493 493 194 164 494 494 188 165 495 495 186 165 496 496 192 165 497 497 189 166 498 498 180 166 499 499 183 166 500 500 193 167 501 501 184 167 502 502 190 167 503 503 188 168 504 504 183 168 505 505 182 168 506 506 187 169 507 507 181 169 508 508 180 169 509 509 136 170 510 510 194 170 511 511 187 170 512 512 137 171 513 513 188 171 514 514 132 171 515 515 134 172 516 516 190 172 517 517 133 172 518 518 137 173 519 519 187 173 520 520 189 173 521 521 132 174 522 522 192 174 523 523 131 174 524 524 135 175 525 525 191 175 526 526 194 175 527 527 133 176 528 528 191 176 529 529 138 176 530 530 131 177 531 531 193 177 532 532 134 177 533 533 170 178 534 534 202 178 535 535 199 178 536 536 167 179 537 537 199 179 538 538 198 179 539 539 168 180 540 540 197 180 541 541 166 180 542 542 169 181 543 543 200 181 544 544 202 181 545 545 168 182 546 546 198 182 547 547 201 182 548 548 166 183 549 549 196 183 550 550 165 183 551 551 165 184 552 552 195 184 553 553 163 184 554 554 163 185 555 555 200 185 556 556 164 185 557 557 159 186 558 558 210 186 559 559 207 186 560 560 161 187 561 561 204 187 562 562 209 187 563 563 156 188 564 564 205 188 565 565 204 188 566 566 155 189 567 567 206 189 568 568 158 189 569 569 155 190 570 570 211 190 571 571 212 190 572 572 160 191 573 573 207 191 574 574 208 191 575 575 161 192 576 576 210 192 577 577 162 192 578 578 157 193 579 579 206 193 580 580 205 193 581 581 211 194 582 582 214 194 583 583 212 194 584 584 208 195 585 585 211 195 586 586 160 195 587 587 203 196 588 588 212 196 589 589 214 196 590 590 208 197 591 591 214 197 592 592 213 197 593 593 207 198 594 594 210 198 595 595 206 198 596 596 97 199 597 597 220 199 598 598 100 199 599 599 220 200 600 600 99 200 601 601 100 200 602 602 98 201 603 603 218 201 604 604 96 201 605 605 219 202 606 606 98 202 607 607 99 202 608 608 96 203 609 609 215 203 610 610 95 203 611 611 95 204 612 612 216 204 613 613 97 204 614 614 36 205 615 615 225 205 616 616 224 205 617 617 35 206 618 618 226 206 619 619 225 206 620 620 31 207 621 621 237 207 622 622 227 207 623 623 229 208 624 624 222 208 625 625 238 208 626 626 31 209 627 627 224 209 628 628 223 209 629 629 33 210 630 630 238 210 631 631 226 210 632 632 227 211 633 633 221 211 634 634 0 211 635 635 41 212 636 636 235 212 637 637 42 212 638 638 40 213 639 639 234 213 640 640 233 213 641 641 38 214 642 642 231 214 643 643 37 214 644 644 42 215 645 645 230 215 646 646 34 215 647 647 231 216 648 648 32 216 649 649 37 216 650 650 221 217 651 651 233 217 652 652 7 217 653 653 34 218 654 654 232 218 655 655 38 218 656 656 226 219 657 657 236 219 658 658 41 219 659 659 234 220 660 660 1 220 661 661 6 220 662 662 242 221 663 663 72 221 664 664 27 221 665 665 239 222 666 666 27 222 667 667 28 222 668 668 73 223 669 669 244 223 670 670 26 223 671 671 244 224 672 672 28 224 673 673 26 224 674 674 71 225 675 675 240 225 676 676 73 225 677 677 72 226 678 678 241 226 679 679 71 226 680 680 171 227 681 681 245 227 682 682 250 227 683 683 174 228 684 684 246 228 685 685 245 228 686 686 176 229 687 687 246 229 688 688 175 229 689 689 172 230 690 690 248 230 691 691 251 230 692 692 173 231 693 693 250 231 694 694 252 231 695 695 172 232 696 696 247 232 697 697 176 232 698 698 177 233 699 699 249 233 700 700 248 233 701 701 178 234 702 702 252 234 703 703 249 234 704 704 282 235 705 705 258 235 706 706 260 235 707 707 281 236 708 708 261 236 709 709 280 236 710 710 283 237 711 711 263 237 712 712 284 237 713 713 261 238 714 714 259 238 715 715 258 238 716 716 259 239 717 717 262 239 718 718 257 239 719 719 278 240 720 720 268 240 721 721 283 240 722 722 279 241 723 723 261 241 724 724 258 241 725 725 259 242 726 726 260 242 727 727 258 242 728 728 263 243 729 729 259 243 730 730 269 243 731 731 285 244 732 732 260 244 733 733 257 244 734 734 284 245 735 735 269 245 736 736 281 245 737 737 278 246 738 738 257 246 739 739 262 246 740 740 254 247 741 741 277 247 742 742 270 247 743 743 253 248 744 744 275 248 745 745 267 248 746 746 265 249 747 747 273 249 748 748 277 249 749 749 264 250 750 750 272 250 751 751 271 250 752 752 254 251 753 753 274 251 754 754 266 251 755 755 266 252 756 756 276 252 757 757 253 252 758 758 267 253 759 759 272 253 760 760 255 253 761 761 256 254 762 762 271 254 763 763 273 254 764 764 270 255 765 765 285 255 766 766 278 255 767 767 276 256 768 768 281 256 769 769 275 256 770 770 277 257 771 771 282 257 772 772 285 257 773 773 271 258 774 774 280 258 775 775 279 258 776 776 270 259 777 777 283 259 778 778 274 259 779 779 274 260 780 780 284 260 781 781 276 260 782 782 275 261 783 783 280 261 784 784 272 261 785 785 273 262 786 786 279 262 787 787 282 262 788 788 315 263 789 789 291 263 790 790 293 263 791 791 313 264 792 792 302 264 793 793 294 264 794 794 316 265 795 795 296 265 796 796 317 265 797 797 294 266 798 798 292 266 799 799 291 266 800 800 292 267 801 801 295 267 802 802 290 267 803 803 311 268 804 804 301 268 805 805 316 268 806 806 312 269 807 807 294 269 808 808 291 269 809 809 292 270 810 810 293 270 811 811 291 270 812 812 296 271 813 813 292 271 814 814 302 271 815 815 318 272 816 816 293 272 817 817 290 272 818 818 317 273 819 819 302 273 820 820 314 273 821 821 318 274 822 822 295 274 823 823 311 274 824 824 298 275 825 825 303 275 826 826 287 275 827 827 286 276 828 828 308 276 829 829 300 276 830 830 298 277 831 831 306 277 832 832 310 277 833 833 297 278 834 834 305 278 835 835 304 278 836 836 287 279 837 837 307 279 838 838 299 279 839 839 299 280 840 840 309 280 841 841 286 280 842 842 288 281 843 843 308 281 844 844 305 281 845 845 289 282 846 846 304 282 847 847 306 282 848 848 303 283 849 849 318 283 850 850 311 283 851 851 309 284 852 852 314 284 853 853 308 284 854 854 310 285 855 855 315 285 856 856 318 285 857 857 304 286 858 858 313 286 859 859 312 286 860 860 303 287 861 861 316 287 862 862 307 287 863 863 307 288 864 864 317 288 865 865 309 288 866 866 308 289 867 867 313 289 868 868 305 289 869 869 306 290 870 870 312 290 871 871 315 290 872 872 351 291 873 873 329 291 874 874 337 291 875 875 319 292 876 876 342 292 877 877 326 292 878 878 319 293 879 879 344 293 880 880 347 293 881 881 340 294 882 882 332 294 883 883 333 294 884 884 338 295 885 885 328 295 886 886 351 295 887 887 320 296 888 888 335 296 889 889 323 296 890 890 339 297 891 891 331 297 892 892 327 297 893 893 349 298 894 894 329 298 895 895 332 298 896 896 339 299 897 897 334 299 898 898 350 299 899 899 348 300 900 900 333 300 901 901 331 300 902 902 341 301 903 903 345 301 904 904 335 301 905 905 350 302 906 906 330 302 907 907 338 302 908 908 334 303 909 909 321 303 910 910 330 303 911 911 331 304 912 912 325 304 913 913 322 304 914 914 328 305 915 915 323 305 916 916 329 305 917 917 333 306 918 918 324 306 919 919 325 306 920 920 330 307 921 921 320 307 922 922 328 307 923 923 329 308 924 924 324 308 925 925 332 308 926 926 327 309 927 927 322 309 928 928 319 309 929 929 334 310 930 930 319 310 931 931 326 310 932 932 345 311 933 933 344 311 934 934 346 311 935 935 322 312 936 936 346 312 937 937 344 312 938 938 321 313 939 939 341 313 940 940 320 313 941 941 326 314 942 942 336 314 943 943 321 314 944 944 325 315 945 945 343 315 946 946 346 315 947 947 324 316 948 948 335 316 949 949 343 316 950 950 343 317 951 951 345 317 952 952 346 317 953 953 345 318 954 954 342 318 955 955 347 318 956 956 373 319 957 957 353 319 958 958 355 319 959 959 372 320 960 960 356 320 961 961 371 320 962 962 374 321 963 963 358 321 964 964 375 321 965 965 356 322 966 966 354 322 967 967 353 322 968 968 354 323 969 969 357 323 970 970 352 323 971 971 369 324 972 972 359 324 973 973 374 324 974 974 370 325 975 975 356 325 976 976 353 325 977 977 354 326 978 978 355 326 979 979 353 326 980 980 358 327 981 981 354 327 982 982 360 327 983 983 376 328 984 984 355 328 985 985 352 328 986 986 375 329 987 987 360 329 988 988 372 329 989 989 369 330 990 990 352 330 991 991 357 330 992 992 361 331 993 993 376 331 994 994 369 331 995 995 367 332 996 996 372 332 997 997 366 332 998 998 368 333 999 999 373 333 1000 1000 376 333 1001 1001 362 334 1002 1002 371 334 1003 1003 370 334 1004 1004 361 335 1005 1005 374 335 1006 1006 365 335 1007 1007 365 336 1008 1008 375 336 1009 1009 367 336 1010 1010 366 337 1011 1011 371 337 1012 1012 363 337 1013 1013 364 338 1014 1014 370 338 1015 1015 373 338 1016 1016 409 339 1017 1017 387 339 1018 1018 395 339 1019 1019 377 340 1020 1020 400 340 1021 1021 384 340 1022 1022 377 341 1023 1023 402 341 1024 1024 405 341 1025 1025 398 342 1026 1026 390 342 1027 1027 391 342 1028 1028 396 343 1029 1029 386 343 1030 1030 409 343 1031 1031 378 344 1032 1032 393 344 1033 1033 381 344 1034 1034 397 345 1035 1035 389 345 1036 1036 385 345 1037 1037 407 346 1038 1038 387 346 1039 1039 390 346 1040 1040 397 347 1041 1041 392 347 1042 1042 408 347 1043 1043 406 348 1044 1044 391 348 1045 1045 389 348 1046 1046 399 349 1047 1047 403 349 1048 1048 393 349 1049 1049 408 350 1050 1050 388 350 1051 1051 396 350 1052 1052 392 351 1053 1053 379 351 1054 1054 388 351 1055 1055 389 352 1056 1056 383 352 1057 1057 380 352 1058 1058 386 353 1059 1059 381 353 1060 1060 387 353 1061 1061 391 354 1062 1062 382 354 1063 1063 383 354 1064 1064 388 355 1065 1065 378 355 1066 1066 386 355 1067 1067 387 356 1068 1068 382 356 1069 1069 390 356 1070 1070 385 357 1071 1071 380 357 1072 1072 377 357 1073 1073 392 358 1074 1074 377 358 1075 1075 384 358 1076 1076 403 359 1077 1077 402 359 1078 1078 404 359 1079 1079 380 360 1080 1080 404 360 1081 1081 402 360 1082 1082 379 361 1083 1083 399 361 1084 1084 378 361 1085 1085 384 362 1086 1086 394 362 1087 1087 379 362 1088 1088 383 363 1089 1089 401 363 1090 1090 404 363 1091 1091 382 364 1092 1092 393 364 1093 1093 401 364 1094 1094 401 365 1095 1095 403 365 1096 1096 404 365 1097 1097 403 366 1098 1098 400 366 1099 1099 405 366 1100 1100 600 367 1101 1101 424 367 1102 1102 601 367 1103 1103 605 368 1104 1104 418 368 1105 1105 611 368 1106 1106 615 369 1107 1107 8 369 1108 1108 222 369 1109 1109 607 370 1110 1110 4 370 1111 1111 3 370 1112 1112 614 371 1113 1113 419 371 1114 1114 600 371 1115 1115 417 372 1116 1116 425 372 1117 1117 416 372 1118 1118 602 373 1119 1119 420 373 1120 1120 603 373 1121 1121 605 374 1122 1122 5 374 1123 1123 608 374 1124 1124 422 375 1125 1125 413 375 1126 1126 421 375 1127 1127 612 376 1128 1128 3 376 1129 1129 9 376 1130 1130 601 377 1131 1131 423 377 1132 1132 602 377 1133 1133 5 378 1134 1134 609 378 1135 1135 608 378 1136 1136 610 379 1137 1137 6 379 1138 1138 611 379 1139 1139 9 380 1140 1140 613 380 1141 1141 612 380 1142 1142 423 381 1143 1143 425 381 1144 1144 422 381 1145 1145 418 382 1146 1146 424 382 1147 1147 419 382 1148 1148 421 383 1149 1149 423 383 1150 1150 422 383 1151 1151 411 384 1152 1152 425 384 1153 1153 418 384 1154 1154 11 385 1155 1155 427 385 1156 1156 506 385 1157 1157 509 386 1158 1158 429 386 1159 1159 437 386 1160 1160 446 387 1161 1161 431 387 1162 1162 439 387 1163 1163 22 388 1164 1164 430 388 1165 1165 438 388 1166 1166 442 389 1167 1167 433 389 1168 1168 431 389 1169 1169 17 390 1170 1170 430 390 1171 1171 15 390 1172 1172 449 391 1173 1173 434 391 1174 1174 444 391 1175 1175 24 392 1176 1176 435 392 1177 1177 19 392 1178 1178 443 393 1179 1179 437 393 1180 1180 433 393 1181 1181 21 394 1182 1182 432 394 1183 1183 17 394 1184 1184 10 395 1185 1185 438 395 1186 1186 426 395 1187 1187 440 396 1188 1188 439 396 1189 1189 428 396 1190 1190 426 397 1191 1191 446 397 1192 1192 440 397 1193 1193 508 398 1194 1194 445 398 1195 1195 443 398 1196 1196 448 399 1197 1197 444 399 1198 1198 435 399 1199 1199 430 400 1200 1200 443 400 1201 1201 442 400 1202 1202 438 401 1203 1203 442 401 1204 1204 446 401 1205 1205 428 402 1206 1206 23 402 1207 1207 12 402 1208 1208 433 403 1209 1209 20 403 1210 1210 16 403 1211 1211 431 404 1212 1212 16 404 1213 1213 14 404 1214 1214 439 405 1215 1215 14 405 1216 1216 23 405 1217 1217 25 406 1218 1218 434 406 1219 1219 447 406 1220 1220 453 407 1221 1221 451 407 1222 1222 454 407 1223 1223 429 408 1224 1224 20 408 1225 1225 437 408 1226 1226 11 409 1227 1227 447 409 1228 1228 427 409 1229 1229 429 410 1230 1230 449 410 1231 1231 448 410 1232 1232 13 411 1233 1233 448 411 1234 1234 24 411 1235 1235 507 412 1236 1236 447 412 1237 1237 449 412 1238 1238 496 413 1239 1239 460 413 1240 1240 494 413 1241 1241 494 414 1242 1242 461 414 1243 1243 495 414 1244 1244 29 415 1245 1245 451 415 1246 1246 27 415 1247 1247 453 416 1248 1248 452 416 1249 1249 450 416 1250 1250 428 417 1251 1251 453 417 1252 1252 440 417 1253 1253 10 418 1254 1254 454 418 1255 1255 29 418 1256 1256 440 419 1257 1257 454 419 1258 1258 426 419 1259 1259 503 420 1260 1260 465 420 1261 1261 462 420 1262 1262 500 421 1263 1263 464 421 1264 1264 501 421 1265 1265 498 422 1266 1266 458 422 1267 1267 459 422 1268 1268 495 423 1269 1269 458 423 1270 1270 497 423 1271 1271 499 424 1272 1272 459 424 1273 1273 456 424 1274 1274 499 425 1275 1275 457 425 1276 1276 496 425 1277 1277 594 426 1278 1278 469 426 1279 1279 472 426 1280 1280 597 427 1281 1281 472 427 1282 1282 473 427 1283 1283 504 428 1284 1284 462 428 1285 1285 463 428 1286 1286 505 429 1287 1287 467 429 1288 1288 500 429 1289 1289 505 430 1290 1290 463 430 1291 1291 466 430 1292 1292 501 431 1293 1293 465 431 1294 1294 502 431 1295 1295 471 432 1296 1296 488 432 1297 1297 468 432 1298 1298 483 433 1299 1299 491 433 1300 1300 482 433 1301 1301 596 434 1302 1302 471 434 1303 1303 598 434 1304 1304 596 435 1305 1305 473 435 1306 1306 470 435 1307 1307 598 436 1308 1308 468 436 1309 1309 599 436 1310 1310 599 437 1311 1311 469 437 1312 1312 595 437 1313 1313 463 438 1314 1314 479 438 1315 1315 476 438 1316 1316 462 439 1317 1317 478 439 1318 1318 479 439 1319 1319 464 440 1320 1320 475 440 1321 1321 477 440 1322 1322 465 441 1323 1323 477 441 1324 1324 478 441 1325 1325 466 442 1326 1326 475 442 1327 1327 467 442 1328 1328 463 443 1329 1329 474 443 1330 1330 466 443 1331 1331 480 444 1332 1332 484 444 1333 1333 481 444 1334 1334 483 445 1335 1335 485 445 1336 1336 480 445 1337 1337 469 446 1338 1338 480 446 1339 1339 481 446 1340 1340 472 447 1341 1341 485 447 1342 1342 473 447 1343 1343 469 448 1344 1344 484 448 1345 1345 472 448 1346 1346 485 449 1347 1347 489 449 1348 1348 473 449 1349 1349 488 450 1350 1350 492 450 1351 1351 493 450 1352 1352 489 451 1353 1353 491 451 1354 1354 486 451 1355 1355 487 452 1356 1356 491 452 1357 1357 492 452 1358 1358 482 453 1359 1359 490 453 1360 1360 485 453 1361 1361 483 454 1362 1362 493 454 1363 1363 492 454 1364 1364 471 455 1365 1365 486 455 1366 1366 487 455 1367 1367 480 456 1368 1368 488 456 1369 1369 493 456 1370 1370 470 457 1371 1371 489 457 1372 1372 486 457 1373 1373 412 458 1374 1374 2 458 1375 1375 19 458 1376 1376 435 459 1377 1377 414 459 1378 1378 412 459 1379 1379 444 460 1380 1380 415 460 1381 1381 414 460 1382 1382 434 461 1383 1383 415 461 1384 1384 444 461 1385 1385 434 462 1386 1386 604 462 1387 1387 410 462 1388 1388 19 463 1389 1389 435 463 1390 1390 412 463 1391 1391 435 464 1392 1392 444 464 1393 1393 414 464 1394 1394 434 465 1395 1395 410 465 1396 1396 415 465 1397 1397 434 466 1398 1398 18 466 1399 1399 0 466 1400 1400 620 467 1401 1401 499 467 1402 1402 496 467 1403 1403 618 468 1404 1404 498 468 1405 1405 499 468 1406 1406 616 469 1407 1407 497 469 1408 1408 621 469 1409 1409 617 470 1410 1410 497 470 1411 1411 498 470 1412 1412 619 471 1413 1413 495 471 1414 1414 616 471 1415 1415 620 472 1416 1416 494 472 1417 1417 619 472 1418 1418 458 473 1419 1419 502 473 1420 1420 459 473 1421 1421 460 474 1422 1422 504 474 1423 1423 505 474 1424 1424 460 475 1425 1425 500 475 1426 1426 461 475 1427 1427 457 476 1428 1428 503 476 1429 1429 504 476 1430 1430 461 477 1431 1431 501 477 1432 1432 458 477 1433 1433 456 478 1434 1434 502 478 1435 1435 503 478 1436 1436 12 479 1437 1437 455 479 1438 1438 428 479 1439 1439 30 480 1440 1440 452 480 1441 1441 455 480 1442 1442 525 481 1443 1443 512 481 1444 1444 519 481 1445 1445 513 482 1446 1446 518 482 1447 1447 522 482 1448 1448 524 483 1449 1449 515 483 1450 1450 520 483 1451 1451 523 484 1452 1452 517 484 1453 1453 525 484 1454 1454 512 485 1455 1455 522 485 1456 1456 519 485 1457 1457 510 486 1458 1458 521 486 1459 1459 518 486 1460 1460 520 487 1461 1461 514 487 1462 1462 523 487 1463 1463 521 488 1464 1464 516 488 1465 1465 524 488 1466 1466 521 489 1467 1467 506 489 1468 1468 427 489 1469 1469 436 490 1470 1470 523 490 1471 1471 508 490 1472 1472 518 491 1473 1473 427 491 1474 1474 507 491 1475 1475 519 492 1476 1476 441 492 1477 1477 509 492 1478 1478 508 493 1479 1479 525 493 1480 1480 445 493 1481 1481 506 494 1482 1482 520 494 1483 1483 436 494 1484 1484 522 495 1485 1485 507 495 1486 1486 441 495 1487 1487 445 496 1488 1488 519 496 1489 1489 509 496 1490 1490 559 497 1491 1491 529 497 1492 1492 560 497 1493 1493 561 498 1494 1494 527 498 1495 1495 562 498 1496 1496 531 499 1497 1497 558 499 1498 1498 563 499 1499 1499 562 500 1500 1500 528 500 1501 1501 559 500 1502 1502 565 501 1503 1503 532 501 1504 1504 561 501 1505 1505 560 502 1506 1506 526 502 1507 1507 564 502 1508 1508 564 503 1509 1509 531 503 1510 1510 563 503 1511 1511 530 504 1512 1512 565 504 1513 1513 558 504 1514 1514 537 505 1515 1515 574 505 1516 1516 579 505 1517 1517 534 506 1518 1518 575 506 1519 1519 574 506 1520 1520 539 507 1521 1521 576 507 1522 1522 575 507 1523 1523 580 508 1524 1524 540 508 1525 1525 577 508 1526 1526 581 509 1527 1527 537 509 1528 1528 579 509 1529 1529 538 510 1530 1530 580 510 1531 1531 576 510 1532 1532 577 511 1533 1533 535 511 1534 1534 578 511 1535 1535 578 512 1536 1536 536 512 1537 1537 581 512 1538 1538 626 513 1539 1539 548 513 1540 1540 629 513 1541 1541 625 514 1542 1542 549 514 1543 1543 626 514 1544 1544 624 515 1545 1545 547 515 1546 1546 628 515 1547 1547 629 516 1548 1548 543 516 1549 1549 627 516 1550 1550 547 517 1551 1551 625 517 1552 1552 628 517 1553 1553 544 518 1554 1554 624 518 1555 1555 623 518 1556 1556 542 519 1557 1557 623 519 1558 1558 622 519 1559 1559 627 520 1560 1560 542 520 1561 1561 622 520 1562 1562 529 521 1563 1563 553 521 1564 1564 526 521 1565 1565 526 522 1566 1566 554 522 1567 1567 531 522 1568 1568 554 523 1569 1569 530 523 1570 1570 531 523 1571 1571 551 524 1572 1572 532 524 1573 1573 533 524 1574 1574 528 525 1575 1575 550 525 1576 1576 529 525 1577 1577 555 526 1578 1578 533 526 1579 1579 530 526 1580 1580 532 527 1581 1581 557 527 1582 1582 527 527 1583 1583 527 528 1584 1584 552 528 1585 1585 528 528 1586 1586 558 529 1587 1587 571 529 1588 1588 572 529 1589 1589 564 530 1590 1590 569 530 1591 1591 570 530 1592 1592 560 531 1593 1593 570 531 1594 1594 573 531 1595 1595 565 532 1596 1596 567 532 1597 1597 571 532 1598 1598 568 533 1599 1599 559 533 1600 1600 566 533 1601 1601 563 534 1602 1602 572 534 1603 1603 569 534 1604 1604 567 535 1605 1605 562 535 1606 1606 568 535 1607 1607 566 536 1608 1608 560 536 1609 1609 573 536 1610 1610 515 537 1611 1611 573 537 1612 1612 514 537 1613 1613 567 538 1614 1614 516 538 1615 1615 511 538 1616 1616 569 539 1617 1617 513 539 1618 1618 512 539 1619 1619 516 540 1620 1620 566 540 1621 1621 515 540 1622 1622 571 541 1623 1623 511 541 1624 1624 510 541 1625 1625 514 542 1626 1626 570 542 1627 1627 517 542 1628 1628 570 543 1629 1629 512 543 1630 1630 517 543 1631 1631 572 544 1632 1632 510 544 1633 1633 513 544 1634 1634 549 545 1635 1635 581 545 1636 1636 548 545 1637 1637 546 546 1638 1638 578 546 1639 1639 549 546 1640 1640 576 547 1641 1641 547 547 1642 1642 545 547 1643 1643 548 548 1644 1644 579 548 1645 1645 543 548 1646 1646 547 549 1647 1647 577 549 1648 1648 546 549 1649 1649 575 550 1650 1650 545 550 1651 1651 544 550 1652 1652 574 551 1653 1653 544 551 1654 1654 542 551 1655 1655 579 552 1656 1656 542 552 1657 1657 543 552 1658 1658 538 553 1659 1659 589 553 1660 1660 541 553 1661 1661 540 554 1662 1662 583 554 1663 1663 535 554 1664 1664 535 555 1665 1665 584 555 1666 1666 536 555 1667 1667 585 556 1668 1668 534 556 1669 1669 537 556 1670 1670 534 557 1671 1671 590 557 1672 1672 539 557 1673 1673 539 558 1674 1674 586 558 1675 1675 538 558 1676 1676 589 559 1677 1677 540 559 1678 1678 541 559 1679 1679 536 560 1680 1680 585 560 1681 1681 537 560 1682 1682 593 561 1683 1683 590 561 1684 1684 591 561 1685 1685 590 562 1686 1686 587 562 1687 1687 539 562 1688 1688 582 563 1689 1689 591 563 1690 1690 534 563 1691 1691 587 564 1692 1692 593 564 1693 1693 582 564 1694 1694 582 565 1695 1695 585 565 1696 1696 586 565 1697 1697 476 566 1698 1698 599 566 1699 1699 595 566 1700 1700 478 567 1701 1701 599 567 1702 1702 479 567 1703 1703 477 568 1704 1704 597 568 1705 1705 596 568 1706 1706 477 569 1707 1707 598 569 1708 1708 478 569 1709 1709 475 570 1710 1710 594 570 1711 1711 597 570 1712 1712 474 571 1713 1713 595 571 1714 1714 594 571 1715 1715 415 572 1716 1716 602 572 1717 1717 414 572 1718 1718 414 573 1719 1719 603 573 1720 1720 412 573 1721 1721 614 574 1722 1722 410 574 1723 1723 604 574 1724 1724 606 575 1725 1725 222 575 1726 1726 2 575 1727 1727 410 576 1728 1728 601 576 1729 1729 415 576 1730 1730 412 577 1731 1731 615 577 1732 1732 606 577 1733 1733 221 578 1734 1734 604 578 1735 1735 0 578 1736 1736 612 579 1737 1737 420 579 1738 1738 421 579 1739 1739 419 580 1740 1740 611 580 1741 1741 418 580 1742 1742 608 581 1743 1743 417 581 1744 1744 416 581 1745 1745 421 582 1746 1746 607 582 1747 1747 612 582 1748 1748 411 583 1749 1749 608 583 1750 1750 416 583 1751 1751 221 584 1752 1752 610 584 1753 1753 614 584 1754 1754 413 585 1755 1755 609 585 1756 1756 607 585 1757 1757 603 586 1758 1758 613 586 1759 1759 615 586 1760 1760 1 587 1761 1761 611 587 1762 1762 6 587 1763 1763 451 588 1764 1764 619 588 1765 1765 27 588 1766 1766 27 589 1767 1767 616 589 1768 1768 28 589 1769 1769 452 590 1770 1770 621 590 1771 1771 617 590 1772 1772 28 591 1773 1773 621 591 1774 1774 26 591 1775 1775 450 592 1776 1776 617 592 1777 1777 618 592 1778 1778 451 593 1779 1779 618 593 1780 1780 620 593 1781 1781 550 594 1782 1782 622 594 1783 1783 553 594 1784 1784 553 595 1785 1785 623 595 1786 1786 554 595 1787 1787 623 596 1788 1788 555 596 1789 1789 554 596 1790 1790 551 597 1791 1791 625 597 1792 1792 556 597 1793 1793 552 598 1794 1794 627 598 1795 1795 550 598 1796 1796 624 599 1797 1797 551 599 1798 1798 555 599 1799 1799 556 600 1800 1800 626 600 1801 1801 557 600 1802 1802 557 601 1803 1803 629 601 1804 1804 552 601 1805 1805 659 602 1806 1806 635 602 1807 1807 656 602 1808 1808 638 603 1809 1809 658 603 1810 1810 657 603 1811 1811 640 604 1812 1812 660 604 1813 1813 661 604 1814 1814 638 605 1815 1815 636 605 1816 1816 646 605 1817 1817 636 606 1818 1818 639 606 1819 1819 645 606 1820 1820 645 607 1821 1821 655 607 1822 1822 660 607 1823 1823 656 608 1824 1824 638 608 1825 1825 657 608 1826 1826 637 609 1827 1827 636 609 1828 1828 635 609 1829 1829 636 610 1830 1830 640 610 1831 1831 646 610 1832 1832 662 611 1833 1833 637 611 1834 1834 659 611 1835 1835 646 612 1836 1836 661 612 1837 1837 658 612 1838 1838 655 613 1839 1839 634 613 1840 1840 662 613 1841 1841 631 614 1842 1842 654 614 1843 1843 642 614 1844 1844 652 615 1845 1845 630 615 1846 1846 644 615 1847 1847 642 616 1848 1848 650 616 1849 1849 633 616 1850 1850 641 617 1851 1851 649 617 1852 1852 632 617 1853 1853 651 618 1854 1854 631 618 1855 1855 643 618 1856 1856 653 619 1857 1857 643 619 1858 1858 630 619 1859 1859 649 620 1860 1860 644 620 1861 1861 632 620 1862 1862 633 621 1863 1863 648 621 1864 1864 641 621 1865 1865 647 622 1866 1866 662 622 1867 1867 654 622 1868 1868 658 623 1869 1869 653 623 1870 1870 652 623 1871 1871 654 624 1872 1872 659 624 1873 1873 650 624 1874 1874 648 625 1875 1875 657 625 1876 1876 649 625 1877 1877 660 626 1878 1878 647 626 1879 1879 651 626 1880 1880 661 627 1881 1881 651 627 1882 1882 653 627 1883 1883 657 628 1884 1884 652 628 1885 1885 649 628 1886 1886 650 629 1887 1887 656 629 1888 1888 648 629 1889 1889 692 630 1890 1890 668 630 1891 1891 689 630 1892 1892 690 631 1893 1893 679 631 1894 1894 691 631 1895 1895 673 632 1896 1896 693 632 1897 1897 694 632 1898 1898 671 633 1899 1899 669 633 1900 1900 679 633 1901 1901 669 634 1902 1902 672 634 1903 1903 678 634 1904 1904 678 635 1905 1905 688 635 1906 1906 693 635 1907 1907 689 636 1908 1908 671 636 1909 1909 690 636 1910 1910 670 637 1911 1911 669 637 1912 1912 668 637 1913 1913 669 638 1914 1914 673 638 1915 1915 679 638 1916 1916 695 639 1917 1917 670 639 1918 1918 692 639 1919 1919 679 640 1920 1920 694 640 1921 1921 691 640 1922 1922 672 641 1923 1923 695 641 1924 1924 688 641 1925 1925 680 642 1926 1926 675 642 1927 1927 664 642 1928 1928 685 643 1929 1929 663 643 1930 1930 677 643 1931 1931 675 644 1932 1932 683 644 1933 1933 666 644 1934 1934 674 645 1935 1935 682 645 1936 1936 665 645 1937 1937 684 646 1938 1938 664 646 1939 1939 676 646 1940 1940 686 647 1941 1941 676 647 1942 1942 663 647 1943 1943 665 648 1944 1944 685 648 1945 1945 677 648 1946 1946 666 649 1947 1947 681 649 1948 1948 674 649 1949 1949 680 650 1950 1950 695 650 1951 1951 687 650 1952 1952 691 651 1953 1953 686 651 1954 1954 685 651 1955 1955 687 652 1956 1956 692 652 1957 1957 683 652 1958 1958 681 653 1959 1959 690 653 1960 1960 682 653 1961 1961 693 654 1962 1962 680 654 1963 1963 684 654 1964 1964 694 655 1965 1965 684 655 1966 1966 686 655 1967 1967 690 656 1968 1968 685 656 1969 1969 682 656 1970 1970 683 657 1971 1971 689 657 1972 1972 681 657 1973 1973 706 658 1974 1974 728 658 1975 1975 714 658 1976 1976 719 659 1977 1977 696 659 1978 1978 703 659 1979 1979 696 660 1980 1980 721 660 1981 1981 699 660 1982 1982 717 661 1983 1983 709 661 1984 1984 726 661 1985 1985 705 662 1986 1986 715 662 1987 1987 728 662 1988 1988 712 663 1989 1989 697 663 1990 1990 700 663 1991 1991 716 664 1992 1992 708 664 1993 1993 725 664 1994 1994 726 665 1995 1995 706 665 1996 1996 714 665 1997 1997 711 666 1998 1998 716 666 1999 1999 727 666 2000 2000 725 667 2001 2001 710 667 2002 2002 717 667 2003 2003 722 668 2004 2004 718 668 2005 2005 712 668 2006 2006 707 669 2007 2007 727 669 2008 2008 715 669 2009 2009 698 670 2010 2010 711 670 2011 2011 707 670 2012 2012 708 671 2013 2013 702 671 2014 2014 710 671 2015 2015 700 672 2016 2016 705 672 2017 2017 706 672 2018 2018 710 673 2019 2019 701 673 2020 2020 709 673 2021 2021 697 674 2022 2022 707 674 2023 2023 705 674 2024 2024 701 675 2025 2025 706 675 2026 2026 709 675 2027 2027 704 676 2028 2028 699 676 2029 2029 708 676 2030 2030 711 677 2031 2031 696 677 2032 2032 704 677 2033 2033 721 678 2034 2034 722 678 2035 2035 723 678 2036 2036 699 679 2037 2037 723 679 2038 2038 702 679 2039 2039 718 680 2040 2040 698 680 2041 2041 697 680 2042 2042 713 681 2043 2043 703 681 2044 2044 698 681 2045 2045 702 682 2046 2046 720 682 2047 2047 701 682 2048 2048 701 683 2049 2049 712 683 2050 2050 700 683 2051 2051 720 684 2052 2052 722 684 2053 2053 712 684 2054 2054 722 685 2055 2055 719 685 2056 2056 713 685 2057 2057 750 686 2058 2058 730 686 2059 2059 747 686 2060 2060 733 687 2061 2061 749 687 2062 2062 748 687 2063 2063 735 688 2064 2064 751 688 2065 2065 752 688 2066 2066 733 689 2067 2067 731 689 2068 2068 737 689 2069 2069 731 690 2070 2070 734 690 2071 2071 736 690 2072 2072 736 691 2073 2073 746 691 2074 2074 751 691 2075 2075 747 692 2076 2076 733 692 2077 2077 748 692 2078 2078 732 693 2079 2079 731 693 2080 2080 730 693 2081 2081 731 694 2082 2082 735 694 2083 2083 737 694 2084 2084 753 695 2085 2085 732 695 2086 2086 750 695 2087 2087 737 696 2088 2088 752 696 2089 2089 749 696 2090 2090 746 697 2091 2091 729 697 2092 2092 753 697 2093 2093 738 698 2094 2094 753 698 2095 2095 745 698 2096 2096 749 699 2097 2097 744 699 2098 2098 743 699 2099 2099 745 700 2100 2100 750 700 2101 2101 741 700 2102 2102 739 701 2103 2103 748 701 2104 2104 740 701 2105 2105 751 702 2106 2106 738 702 2107 2107 742 702 2108 2108 752 703 2109 2109 742 703 2110 2110 744 703 2111 2111 748 704 2112 2112 743 704 2113 2113 740 704 2114 2114 741 705 2115 2115 747 705 2116 2116 739 705 2117 2117 764 706 2118 2118 786 706 2119 2119 772 706 2120 2120 777 707 2121 2121 754 707 2122 2122 761 707 2123 2123 754 708 2124 2124 779 708 2125 2125 757 708 2126 2126 775 709 2127 2127 767 709 2128 2128 784 709 2129 2129 763 710 2130 2130 773 710 2131 2131 786 710 2132 2132 770 711 2133 2133 755 711 2134 2134 758 711 2135 2135 774 712 2136 2136 766 712 2137 2137 783 712 2138 2138 784 713 2139 2139 764 713 2140 2140 772 713 2141 2141 769 714 2142 2142 774 714 2143 2143 785 714 2144 2144 783 715 2145 2145 768 715 2146 2146 775 715 2147 2147 780 716 2148 2148 776 716 2149 2149 770 716 2150 2150 765 717 2151 2151 785 717 2152 2152 773 717 2153 2153 756 718 2154 2154 769 718 2155 2155 765 718 2156 2156 766 719 2157 2157 760 719 2158 2158 768 719 2159 2159 758 720 2160 2160 763 720 2161 2161 764 720 2162 2162 768 721 2163 2163 759 721 2164 2164 767 721 2165 2165 755 722 2166 2166 765 722 2167 2167 763 722 2168 2168 759 723 2169 2169 764 723 2170 2170 767 723 2171 2171 762 724 2172 2172 757 724 2173 2173 766 724 2174 2174 769 725 2175 2175 754 725 2176 2176 762 725 2177 2177 779 726 2178 2178 780 726 2179 2179 781 726 2180 2180 757 727 2181 2181 781 727 2182 2182 760 727 2183 2183 776 728 2184 2184 756 728 2185 2185 755 728 2186 2186 771 729 2187 2187 761 729 2188 2188 756 729 2189 2189 760 730 2190 2190 778 730 2191 2191 759 730 2192 2192 759 731 2193 2193 770 731 2194 2194 758 731 2195 2195 778 732 2196 2196 780 732 2197 2197 770 732 2198 2198 780 733 2199 2199 777 733 2200 2200 771 733 2201 2201 223 734 2202 2202 224 734 2203 2203 45 734 2204 2204 39 735 2205 2205 32 735 2206 2206 228 735 2207 2207 238 736 2208 2208 222 736 2209 2209 8 736 2210 2210 230 737 2211 2211 3 737 2212 2212 4 737 2213 2213 237 738 2214 2214 223 738 2215 2215 40 738 2216 2216 38 739 2217 2217 37 739 2218 2218 46 739 2219 2219 225 740 2220 2220 226 740 2221 2221 41 740 2222 2222 5 741 2223 2223 1 741 2224 2224 228 741 2225 2225 43 742 2226 2226 42 742 2227 2227 34 742 2228 2228 235 743 2229 2229 9 743 2230 2230 3 743 2231 2231 224 744 2232 2232 225 744 2233 2233 44 744 2234 2234 232 745 2235 2235 4 745 2236 2236 5 745 2237 2237 233 746 2238 2238 234 746 2239 2239 6 746 2240 2240 236 747 2241 2241 8 747 2242 2242 9 747 2243 2243 44 748 2244 2244 43 748 2245 2245 46 748 2246 2246 39 749 2247 2247 40 749 2248 2248 45 749 2249 2249 44 750 2250 2250 41 750 2251 2251 42 750 2252 2252 46 751 2253 2253 37 751 2254 2254 32 751 2255 2255 11 752 2256 2256 21 752 2257 2257 127 752 2258 2258 21 753 2259 2259 57 753 2260 2260 127 753 2261 2261 130 754 2262 2262 66 754 2263 2263 58 754 2264 2264 58 755 2265 2265 50 755 2266 2266 130 755 2267 2267 67 756 2268 2268 60 756 2269 2269 52 756 2270 2270 22 757 2271 2271 59 757 2272 2272 51 757 2273 2273 63 758 2274 2274 52 758 2275 2275 54 758 2276 2276 51 759 2277 2277 53 759 2278 2278 17 759 2279 2279 70 760 2280 2280 65 760 2281 2281 55 760 2282 2282 24 761 2283 2283 19 761 2284 2284 56 761 2285 2285 64 762 2286 2286 54 762 2287 2287 58 762 2288 2288 53 763 2289 2289 57 763 2290 2290 21 763 2291 2291 10 764 2292 2292 47 764 2293 2293 59 764 2294 2294 61 765 2295 2295 49 765 2296 2296 60 765 2297 2297 47 766 2298 2298 61 766 2299 2299 67 766 2300 2300 57 767 2301 2301 53 767 2302 2302 129 767 2303 2303 53 768 2304 2304 64 768 2305 2305 129 768 2306 2306 69 769 2307 2307 56 769 2308 2308 65 769 2309 2309 51 770 2310 2310 63 770 2311 2311 64 770 2312 2312 59 771 2313 2313 67 771 2314 2314 63 771 2315 2315 49 772 2316 2316 12 772 2317 2317 23 772 2318 2318 54 773 2319 2319 16 773 2320 2320 20 773 2321 2321 52 774 2322 2322 14 774 2323 2323 16 774 2324 2324 60 775 2325 2325 23 775 2326 2326 14 775 2327 2327 55 776 2328 2328 18 776 2329 2329 25 776 2330 2330 72 777 2331 2331 71 777 2332 2332 74 777 2333 2333 20 778 2334 2334 13 778 2335 2335 50 778 2336 2336 68 779 2337 2337 25 779 2338 2338 11 779 2339 2339 50 780 2340 2340 69 780 2341 2341 70 780 2342 2342 13 781 2343 2343 24 781 2344 2344 69 781 2345 2345 128 782 2346 2346 62 782 2347 2347 70 782 2348 2348 70 783 2349 2349 68 783 2350 2350 128 783 2351 2351 81 784 2352 2352 78 784 2353 2353 117 784 2354 2354 82 785 2355 2355 81 785 2356 2356 115 785 2357 2357 29 786 2358 2358 27 786 2359 2359 72 786 2360 2360 74 787 2361 2361 71 787 2362 2362 73 787 2363 2363 74 788 2364 2364 76 788 2365 2365 49 788 2366 2366 10 789 2367 2367 29 789 2368 2368 75 789 2369 2369 75 790 2370 2370 74 790 2371 2371 61 790 2372 2372 124 791 2373 2373 83 791 2374 2374 86 791 2375 2375 85 792 2376 2376 88 792 2377 2377 121 792 2378 2378 119 793 2379 2379 80 793 2380 2380 79 793 2381 2381 79 794 2382 2382 82 794 2383 2383 116 794 2384 2384 120 795 2385 2385 77 795 2386 2386 80 795 2387 2387 78 796 2388 2388 77 796 2389 2389 120 796 2390 2390 215 797 2391 2391 93 797 2392 2392 90 797 2393 2393 218 798 2394 2394 94 798 2395 2395 93 798 2396 2396 125 799 2397 2397 84 799 2398 2398 83 799 2399 2399 88 800 2400 2400 87 800 2401 2401 126 800 2402 2402 126 801 2403 2403 87 801 2404 2404 84 801 2405 2405 86 802 2406 2406 85 802 2407 2407 122 802 2408 2408 109 803 2409 2409 108 803 2410 2410 92 803 2411 2411 112 804 2412 2412 113 804 2413 2413 104 804 2414 2414 92 805 2415 2415 91 805 2416 2416 217 805 2417 2417 217 806 2418 2418 91 806 2419 2419 94 806 2420 2420 89 807 2421 2421 92 807 2422 2422 219 807 2423 2423 90 808 2424 2424 89 808 2425 2425 220 808 2426 2426 84 809 2427 2427 97 809 2428 2428 100 809 2429 2429 83 810 2430 2430 100 810 2431 2431 99 810 2432 2432 85 811 2433 2433 98 811 2434 2434 96 811 2435 2435 86 812 2436 2436 99 812 2437 2437 98 812 2438 2438 96 813 2439 2439 95 813 2440 2440 87 813 2441 2441 95 814 2442 2442 97 814 2443 2443 84 814 2444 2444 105 815 2445 2445 106 815 2446 2446 101 815 2447 2447 106 816 2448 2448 103 816 2449 2449 104 816 2450 2450 90 817 2451 2451 102 817 2452 2452 101 817 2453 2453 106 818 2454 2454 105 818 2455 2455 93 818 2456 2456 105 819 2457 2457 102 819 2458 2458 90 819 2459 2459 110 820 2460 2460 111 820 2461 2461 106 820 2462 2462 109 821 2463 2463 114 821 2464 2464 113 821 2465 2465 112 822 2466 2466 111 822 2467 2467 110 822 2468 2468 108 823 2469 2469 113 823 2470 2470 112 823 2471 2471 111 824 2472 2472 112 824 2473 2473 103 824 2474 2474 104 825 2475 2475 113 825 2476 2476 114 825 2477 2477 92 826 2478 2478 108 826 2479 2479 107 826 2480 2480 101 827 2481 2481 114 827 2482 2482 109 827 2483 2483 91 828 2484 2484 107 828 2485 2485 110 828 2486 2486 2 829 2487 2487 229 829 2488 2488 33 829 2489 2489 55 830 2490 2490 31 830 2491 2491 227 830 2492 2492 243 831 2493 2493 117 831 2494 2494 120 831 2495 2495 241 832 2496 2496 120 832 2497 2497 119 832 2498 2498 118 833 2499 2499 116 833 2500 2500 239 833 2501 2501 240 834 2502 2502 119 834 2503 2503 118 834 2504 2504 116 835 2505 2505 115 835 2506 2506 242 835 2507 2507 115 836 2508 2508 117 836 2509 2509 243 836 2510 2510 123 837 2511 2511 122 837 2512 2512 79 837 2513 2513 81 838 2514 2514 126 838 2515 2515 125 838 2516 2516 121 839 2517 2517 126 839 2518 2518 81 839 2519 2519 78 840 2520 2520 125 840 2521 2521 124 840 2522 2522 122 841 2523 2523 121 841 2524 2524 82 841 2525 2525 77 842 2526 2526 124 842 2527 2527 123 842 2528 2528 12 843 2529 2529 49 843 2530 2530 76 843 2531 2531 30 844 2532 2532 76 844 2533 2533 73 844 2534 2534 146 845 2535 2535 140 845 2536 2536 133 845 2537 2537 139 846 2538 2538 131 846 2539 2539 134 846 2540 2540 145 847 2541 2541 141 847 2542 2542 136 847 2543 2543 144 848 2544 2544 146 848 2545 2545 138 848 2546 2546 143 849 2547 2547 134 849 2548 2548 133 849 2549 2549 142 850 2550 2550 132 850 2551 2551 131 850 2552 2552 141 851 2553 2553 144 851 2554 2554 135 851 2555 2555 142 852 2556 2556 145 852 2557 2557 137 852 2558 2558 127 853 2559 2559 145 853 2560 2560 142 853 2561 2561 57 854 2562 2562 129 854 2563 2563 144 854 2564 2564 48 855 2565 2565 142 855 2566 2566 139 855 2567 2567 62 856 2568 2568 143 856 2569 2569 140 856 2570 2570 129 857 2571 2571 66 857 2572 2572 146 857 2573 2573 127 858 2574 2574 57 858 2575 2575 141 858 2576 2576 128 859 2577 2577 139 859 2578 2578 143 859 2579 2579 66 860 2580 2580 130 860 2581 2581 140 860 2582 2582 180 861 2583 2583 181 861 2584 2584 150 861 2585 2585 182 862 2586 2586 183 862 2587 2587 148 862 2588 2588 179 863 2589 2589 151 863 2590 2590 152 863 2591 2591 183 864 2592 2592 180 864 2593 2593 149 864 2594 2594 186 865 2595 2595 182 865 2596 2596 153 865 2597 2597 181 866 2598 2598 185 866 2599 2599 147 866 2600 2600 185 867 2601 2601 184 867 2602 2602 152 867 2603 2603 186 868 2604 2604 154 868 2605 2605 151 868 2606 2606 195 869 2607 2607 155 869 2608 2608 158 869 2609 2609 196 870 2610 2610 160 870 2611 2611 155 870 2612 2612 197 871 2613 2613 159 871 2614 2614 160 871 2615 2615 201 872 2616 2616 198 872 2617 2617 161 872 2618 2618 202 873 2619 2619 200 873 2620 2620 158 873 2621 2621 201 874 2622 2622 162 874 2623 2623 159 874 2624 2624 198 875 2625 2625 199 875 2626 2626 156 875 2627 2627 199 876 2628 2628 202 876 2629 2629 157 876 2630 2630 249 877 2631 2631 252 877 2632 2632 169 877 2633 2633 248 878 2634 2634 249 878 2635 2635 170 878 2636 2636 247 879 2637 2637 251 879 2638 2638 168 879 2639 2639 252 880 2640 2640 250 880 2641 2641 164 880 2642 2642 248 881 2643 2643 167 881 2644 2644 168 881 2645 2645 247 882 2646 2646 166 882 2647 2647 165 882 2648 2648 246 883 2649 2649 165 883 2650 2650 163 883 2651 2651 250 884 2652 2652 245 884 2653 2653 163 884 2654 2654 150 885 2655 2655 147 885 2656 2656 174 885 2657 2657 147 886 2658 2658 152 886 2659 2659 175 886 2660 2660 151 887 2661 2661 176 887 2662 2662 175 887 2663 2663 153 888 2664 2664 177 888 2665 2665 172 888 2666 2666 149 889 2667 2667 150 889 2668 2668 171 889 2669 2669 154 890 2670 2670 172 890 2671 2671 176 890 2672 2672 153 891 2673 2673 148 891 2674 2674 178 891 2675 2675 148 892 2676 2676 149 892 2677 2677 173 892 2678 2678 192 893 2679 2679 186 893 2680 2680 179 893 2681 2681 190 894 2682 2682 184 894 2683 2683 185 894 2684 2684 191 895 2685 2685 185 895 2686 2686 181 895 2687 2687 188 896 2688 2688 182 896 2689 2689 186 896 2690 2690 189 897 2691 2691 187 897 2692 2692 180 897 2693 2693 193 898 2694 2694 179 898 2695 2695 184 898 2696 2696 188 899 2697 2697 189 899 2698 2698 183 899 2699 2699 187 900 2700 2700 194 900 2701 2701 181 900 2702 2702 136 901 2703 2703 135 901 2704 2704 194 901 2705 2705 137 902 2706 2706 189 902 2707 2707 188 902 2708 2708 134 903 2709 2709 193 903 2710 2710 190 903 2711 2711 137 904 2712 2712 136 904 2713 2713 187 904 2714 2714 132 905 2715 2715 188 905 2716 2716 192 905 2717 2717 135 906 2718 2718 138 906 2719 2719 191 906 2720 2720 133 907 2721 2721 190 907 2722 2722 191 907 2723 2723 131 908 2724 2724 192 908 2725 2725 193 908 2726 2726 170 909 2727 2727 169 909 2728 2728 202 909 2729 2729 167 910 2730 2730 170 910 2731 2731 199 910 2732 2732 168 911 2733 2733 201 911 2734 2734 197 911 2735 2735 169 912 2736 2736 164 912 2737 2737 200 912 2738 2738 168 913 2739 2739 167 913 2740 2740 198 913 2741 2741 166 914 2742 2742 197 914 2743 2743 196 914 2744 2744 165 915 2745 2745 196 915 2746 2746 195 915 2747 2747 163 916 2748 2748 195 916 2749 2749 200 916 2750 2750 159 917 2751 2751 162 917 2752 2752 210 917 2753 2753 161 918 2754 2754 156 918 2755 2755 204 918 2756 2756 156 919 2757 2757 157 919 2758 2758 205 919 2759 2759 155 920 2760 2760 203 920 2761 2761 206 920 2762 2762 155 921 2763 2763 160 921 2764 2764 211 921 2765 2765 160 922 2766 2766 159 922 2767 2767 207 922 2768 2768 161 923 2769 2769 209 923 2770 2770 210 923 2771 2771 157 924 2772 2772 158 924 2773 2773 206 924 2774 2774 211 925 2775 2775 213 925 2776 2776 214 925 2777 2777 208 926 2778 2778 213 926 2779 2779 211 926 2780 2780 203 927 2781 2781 155 927 2782 2782 212 927 2783 2783 208 928 2784 2784 203 928 2785 2785 214 928 2786 2786 209 929 2787 2787 204 929 2788 2788 205 929 2789 2789 205 930 2790 2790 206 930 2791 2791 210 930 2792 2792 206 931 2793 2793 203 931 2794 2794 207 931 2795 2795 205 932 2796 2796 210 932 2797 2797 209 932 2798 2798 203 933 2799 2799 208 933 2800 2800 207 933 2801 2801 97 934 2802 2802 216 934 2803 2803 220 934 2804 2804 220 935 2805 2805 219 935 2806 2806 99 935 2807 2807 98 936 2808 2808 217 936 2809 2809 218 936 2810 2810 219 937 2811 2811 217 937 2812 2812 98 937 2813 2813 96 938 2814 2814 218 938 2815 2815 215 938 2816 2816 95 939 2817 2817 215 939 2818 2818 216 939 2819 2819 36 940 2820 2820 35 940 2821 2821 225 940 2822 2822 35 941 2823 2823 33 941 2824 2824 226 941 2825 2825 31 942 2826 2826 223 942 2827 2827 237 942 2828 2828 229 943 2829 2829 2 943 2830 2830 222 943 2831 2831 31 944 2832 2832 36 944 2833 2833 224 944 2834 2834 33 945 2835 2835 229 945 2836 2836 238 945 2837 2837 227 946 2838 2838 237 946 2839 2839 221 946 2840 2840 41 947 2841 2841 236 947 2842 2842 235 947 2843 2843 40 948 2844 2844 39 948 2845 2845 234 948 2846 2846 38 949 2847 2847 232 949 2848 2848 231 949 2849 2849 42 950 2850 2850 235 950 2851 2851 230 950 2852 2852 231 951 2853 2853 228 951 2854 2854 32 951 2855 2855 221 952 2856 2856 237 952 2857 2857 233 952 2858 2858 34 953 2859 2859 230 953 2860 2860 232 953 2861 2861 226 954 2862 2862 238 954 2863 2863 236 954 2864 2864 234 955 2865 2865 228 955 2866 2866 1 955 2867 2867 242 956 2868 2868 243 956 2869 2869 72 956 2870 2870 239 957 2871 2871 242 957 2872 2872 27 957 2873 2873 73 958 2874 2874 240 958 2875 2875 244 958 2876 2876 244 959 2877 2877 239 959 2878 2878 28 959 2879 2879 71 960 2880 2880 241 960 2881 2881 240 960 2882 2882 72 961 2883 2883 243 961 2884 2884 241 961 2885 2885 171 962 2886 2886 174 962 2887 2887 245 962 2888 2888 174 963 2889 2889 175 963 2890 2890 246 963 2891 2891 176 964 2892 2892 247 964 2893 2893 246 964 2894 2894 172 965 2895 2895 177 965 2896 2896 248 965 2897 2897 173 966 2898 2898 171 966 2899 2899 250 966 2900 2900 172 967 2901 2901 251 967 2902 2902 247 967 2903 2903 177 968 2904 2904 178 968 2905 2905 249 968 2906 2906 178 969 2907 2907 173 969 2908 2908 252 969 2909 2909 282 970 2910 2910 279 970 2911 2911 258 970 2912 2912 281 971 2913 2913 269 971 2914 2914 261 971 2915 2915 283 972 2916 2916 268 972 2917 2917 263 972 2918 2918 261 973 2919 2919 269 973 2920 2920 259 973 2921 2921 259 974 2922 2922 268 974 2923 2923 262 974 2924 2924 278 975 2925 2925 262 975 2926 2926 268 975 2927 2927 279 976 2928 2928 280 976 2929 2929 261 976 2930 2930 259 977 2931 2931 257 977 2932 2932 260 977 2933 2933 263 978 2934 2934 268 978 2935 2935 259 978 2936 2936 285 979 2937 2937 282 979 2938 2938 260 979 2939 2939 284 980 2940 2940 263 980 2941 2941 269 980 2942 2942 278 981 2943 2943 285 981 2944 2944 257 981 2945 2945 254 982 2946 2946 265 982 2947 2947 277 982 2948 2948 253 983 2949 2949 276 983 2950 2950 275 983 2951 2951 265 984 2952 2952 256 984 2953 2953 273 984 2954 2954 264 985 2955 2955 255 985 2956 2956 272 985 2957 2957 254 986 2958 2958 270 986 2959 2959 274 986 2960 2960 266 987 2961 2961 274 987 2962 2962 276 987 2963 2963 267 988 2964 2964 275 988 2965 2965 272 988 2966 2966 256 989 2967 2967 264 989 2968 2968 271 989 2969 2969 270 990 2970 2970 277 990 2971 2971 285 990 2972 2972 276 991 2973 2973 284 991 2974 2974 281 991 2975 2975 277 992 2976 2976 273 992 2977 2977 282 992 2978 2978 271 993 2979 2979 272 993 2980 2980 280 993 2981 2981 270 994 2982 2982 278 994 2983 2983 283 994 2984 2984 274 995 2985 2985 283 995 2986 2986 284 995 2987 2987 275 996 2988 2988 281 996 2989 2989 280 996 2990 2990 273 997 2991 2991 271 997 2992 2992 279 997 2993 2993 315 998 2994 2994 312 998 2995 2995 291 998 2996 2996 313 999 2997 2997 314 999 2998 2998 302 999 2999 2999 316 1000 3000 3000 301 1000 3001 3001 296 1000 3002 3002 294 1001 3003 3003 302 1001 3004 3004 292 1001 3005 3005 292 1002 3006 3006 301 1002 3007 3007 295 1002 3008 3008 311 1003 3009 3009 295 1003 3010 3010 301 1003 3011 3011 312 1004 3012 3012 313 1004 3013 3013 294 1004 3014 3014 292 1005 3015 3015 290 1005 3016 3016 293 1005 3017 3017 296 1006 3018 3018 301 1006 3019 3019 292 1006 3020 3020 318 1007 3021 3021 315 1007 3022 3022 293 1007 3023 3023 317 1008 3024 3024 296 1008 3025 3025 302 1008 3026 3026 318 1009 3027 3027 290 1009 3028 3028 295 1009 3029 3029 298 1010 3030 3030 310 1010 3031 3031 303 1010 3032 3032 286 1011 3033 3033 309 1011 3034 3034 308 1011 3035 3035 298 1012 3036 3036 289 1012 3037 3037 306 1012 3038 3038 297 1013 3039 3039 288 1013 3040 3040 305 1013 3041 3041 287 1014 3042 3042 303 1014 3043 3043 307 1014 3044 3044 299 1015 3045 3045 307 1015 3046 3046 309 1015 3047 3047 288 1016 3048 3048 300 1016 3049 3049 308 1016 3050 3050 289 1017 3051 3051 297 1017 3052 3052 304 1017 3053 3053 303 1018 3054 3054 310 1018 3055 3055 318 1018 3056 3056 309 1019 3057 3057 317 1019 3058 3058 314 1019 3059 3059 310 1020 3060 3060 306 1020 3061 3061 315 1020 3062 3062 304 1021 3063 3063 305 1021 3064 3064 313 1021 3065 3065 303 1022 3066 3066 311 1022 3067 3067 316 1022 3068 3068 307 1023 3069 3069 316 1023 3070 3070 317 1023 3071 3071 308 1024 3072 3072 314 1024 3073 3073 313 1024 3074 3074 306 1025 3075 3075 304 1025 3076 3076 312 1025 3077 3077 351 1026 3078 3078 328 1026 3079 3079 329 1026 3080 3080 319 1027 3081 3081 347 1027 3082 3082 342 1027 3083 3083 319 1028 3084 3084 322 1028 3085 3085 344 1028 3086 3086 340 1029 3087 3087 349 1029 3088 3088 332 1029 3089 3089 338 1030 3090 3090 330 1030 3091 3091 328 1030 3092 3092 320 1031 3093 3093 341 1031 3094 3094 335 1031 3095 3095 339 1032 3096 3096 348 1032 3097 3097 331 1032 3098 3098 349 1033 3099 3099 337 1033 3100 3100 329 1033 3101 3101 339 1034 3102 3102 327 1034 3103 3103 334 1034 3104 3104 348 1035 3105 3105 340 1035 3106 3106 333 1035 3107 3107 341 1036 3108 3108 336 1036 3109 3109 345 1036 3110 3110 350 1037 3111 3111 334 1037 3112 3112 330 1037 3113 3113 334 1038 3114 3114 326 1038 3115 3115 321 1038 3116 3116 331 1039 3117 3117 333 1039 3118 3118 325 1039 3119 3119 328 1040 3120 3120 320 1040 3121 3121 323 1040 3122 3122 333 1041 3123 3123 332 1041 3124 3124 324 1041 3125 3125 330 1042 3126 3126 321 1042 3127 3127 320 1042 3128 3128 329 1043 3129 3129 323 1043 3130 3130 324 1043 3131 3131 327 1044 3132 3132 331 1044 3133 3133 322 1044 3134 3134 334 1045 3135 3135 327 1045 3136 3136 319 1045 3137 3137 345 1046 3138 3138 347 1046 3139 3139 344 1046 3140 3140 322 1047 3141 3141 325 1047 3142 3142 346 1047 3143 3143 321 1048 3144 3144 336 1048 3145 3145 341 1048 3146 3146 326 1049 3147 3147 342 1049 3148 3148 336 1049 3149 3149 325 1050 3150 3150 324 1050 3151 3151 343 1050 3152 3152 324 1051 3153 3153 323 1051 3154 3154 335 1051 3155 3155 343 1052 3156 3156 335 1052 3157 3157 345 1052 3158 3158 345 1053 3159 3159 336 1053 3160 3160 342 1053 3161 3161 373 1054 3162 3162 370 1054 3163 3163 353 1054 3164 3164 372 1055 3165 3165 360 1055 3166 3166 356 1055 3167 3167 374 1056 3168 3168 359 1056 3169 3169 358 1056 3170 3170 356 1057 3171 3171 360 1057 3172 3172 354 1057 3173 3173 354 1058 3174 3174 359 1058 3175 3175 357 1058 3176 3176 369 1059 3177 3177 357 1059 3178 3178 359 1059 3179 3179 370 1060 3180 3180 371 1060 3181 3181 356 1060 3182 3182 354 1061 3183 3183 352 1061 3184 3184 355 1061 3185 3185 358 1062 3186 3186 359 1062 3187 3187 354 1062 3188 3188 376 1063 3189 3189 373 1063 3190 3190 355 1063 3191 3191 375 1064 3192 3192 358 1064 3193 3193 360 1064 3194 3194 369 1065 3195 3195 376 1065 3196 3196 352 1065 3197 3197 361 1066 3198 3198 368 1066 3199 3199 376 1066 3200 3200 367 1067 3201 3201 375 1067 3202 3202 372 1067 3203 3203 368 1068 3204 3204 364 1068 3205 3205 373 1068 3206 3206 362 1069 3207 3207 363 1069 3208 3208 371 1069 3209 3209 361 1070 3210 3210 369 1070 3211 3211 374 1070 3212 3212 365 1071 3213 3213 374 1071 3214 3214 375 1071 3215 3215 366 1072 3216 3216 372 1072 3217 3217 371 1072 3218 3218 364 1073 3219 3219 362 1073 3220 3220 370 1073 3221 3221 409 1074 3222 3222 386 1074 3223 3223 387 1074 3224 3224 377 1075 3225 3225 405 1075 3226 3226 400 1075 3227 3227 377 1076 3228 3228 380 1076 3229 3229 402 1076 3230 3230 398 1077 3231 3231 407 1077 3232 3232 390 1077 3233 3233 396 1078 3234 3234 388 1078 3235 3235 386 1078 3236 3236 378 1079 3237 3237 399 1079 3238 3238 393 1079 3239 3239 397 1080 3240 3240 406 1080 3241 3241 389 1080 3242 3242 407 1081 3243 3243 395 1081 3244 3244 387 1081 3245 3245 397 1082 3246 3246 385 1082 3247 3247 392 1082 3248 3248 406 1083 3249 3249 398 1083 3250 3250 391 1083 3251 3251 399 1084 3252 3252 394 1084 3253 3253 403 1084 3254 3254 408 1085 3255 3255 392 1085 3256 3256 388 1085 3257 3257 392 1086 3258 3258 384 1086 3259 3259 379 1086 3260 3260 389 1087 3261 3261 391 1087 3262 3262 383 1087 3263 3263 386 1088 3264 3264 378 1088 3265 3265 381 1088 3266 3266 391 1089 3267 3267 390 1089 3268 3268 382 1089 3269 3269 388 1090 3270 3270 379 1090 3271 3271 378 1090 3272 3272 387 1091 3273 3273 381 1091 3274 3274 382 1091 3275 3275 385 1092 3276 3276 389 1092 3277 3277 380 1092 3278 3278 392 1093 3279 3279 385 1093 3280 3280 377 1093 3281 3281 403 1094 3282 3282 405 1094 3283 3283 402 1094 3284 3284 380 1095 3285 3285 383 1095 3286 3286 404 1095 3287 3287 379 1096 3288 3288 394 1096 3289 3289 399 1096 3290 3290 384 1097 3291 3291 400 1097 3292 3292 394 1097 3293 3293 383 1098 3294 3294 382 1098 3295 3295 401 1098 3296 3296 382 1099 3297 3297 381 1099 3298 3298 393 1099 3299 3299 401 1100 3300 3300 393 1100 3301 3301 403 1100 3302 3302 403 1101 3303 3303 394 1101 3304 3304 400 1101 3305 3305 600 1102 3306 3306 419 1102 3307 3307 424 1102 3308 3308 605 1103 3309 3309 411 1103 3310 3310 418 1103 3311 3311 615 1104 3312 3312 613 1104 3313 3313 8 1104 3314 3314 607 1105 3315 3315 609 1105 3316 3316 4 1105 3317 3317 614 1106 3318 3318 610 1106 3319 3319 419 1106 3320 3320 417 1107 3321 3321 422 1107 3322 3322 425 1107 3323 3323 602 1108 3324 3324 423 1108 3325 3325 420 1108 3326 3326 605 1109 3327 3327 1 1109 3328 3328 5 1109 3329 3329 422 1110 3330 3330 417 1110 3331 3331 413 1110 3332 3332 612 1111 3333 3333 607 1111 3334 3334 3 1111 3335 3335 601 1112 3336 3336 424 1112 3337 3337 423 1112 3338 3338 5 1113 3339 3339 4 1113 3340 3340 609 1113 3341 3341 610 1114 3342 3342 7 1114 3343 3343 6 1114 3344 3344 9 1115 3345 3345 8 1115 3346 3346 613 1115 3347 3347 423 1116 3348 3348 424 1116 3349 3349 425 1116 3350 3350 418 1117 3351 3351 425 1117 3352 3352 424 1117 3353 3353 421 1118 3354 3354 420 1118 3355 3355 423 1118 3356 3356 411 1119 3357 3357 416 1119 3358 3358 425 1119 3359 3359 436 1120 3360 3360 21 1120 3361 3361 506 1120 3362 3362 21 1121 3363 3363 11 1121 3364 3364 506 1121 3365 3365 437 1122 3366 3366 445 1122 3367 3367 509 1122 3368 3368 509 1123 3369 3369 441 1123 3370 3370 429 1123 3371 3371 446 1124 3372 3372 442 1124 3373 3373 431 1124 3374 3374 22 1125 3375 3375 15 1125 3376 3376 430 1125 3377 3377 442 1126 3378 3378 443 1126 3379 3379 433 1126 3380 3380 17 1127 3381 3381 432 1127 3382 3382 430 1127 3383 3383 449 1128 3384 3384 447 1128 3385 3385 434 1128 3386 3386 24 1129 3387 3387 448 1129 3388 3388 435 1129 3389 3389 443 1130 3390 3390 445 1130 3391 3391 437 1130 3392 3392 21 1131 3393 3393 436 1131 3394 3394 432 1131 3395 3395 10 1132 3396 3396 22 1132 3397 3397 438 1132 3398 3398 440 1133 3399 3399 446 1133 3400 3400 439 1133 3401 3401 426 1134 3402 3402 438 1134 3403 3403 446 1134 3404 3404 443 1135 3405 3405 432 1135 3406 3406 508 1135 3407 3407 432 1136 3408 3408 436 1136 3409 3409 508 1136 3410 3410 448 1137 3411 3411 449 1137 3412 3412 444 1137 3413 3413 430 1138 3414 3414 432 1138 3415 3415 443 1138 3416 3416 438 1139 3417 3417 430 1139 3418 3418 442 1139 3419 3419 428 1140 3420 3420 439 1140 3421 3421 23 1140 3422 3422 433 1141 3423 3423 437 1141 3424 3424 20 1141 3425 3425 431 1142 3426 3426 433 1142 3427 3427 16 1142 3428 3428 439 1143 3429 3429 431 1143 3430 3430 14 1143 3431 3431 25 1144 3432 3432 18 1144 3433 3433 434 1144 3434 3434 453 1145 3435 3435 450 1145 3436 3436 451 1145 3437 3437 429 1146 3438 3438 13 1146 3439 3439 20 1146 3440 3440 11 1147 3441 3441 25 1147 3442 3442 447 1147 3443 3443 429 1148 3444 3444 441 1148 3445 3445 449 1148 3446 3446 13 1149 3447 3447 429 1149 3448 3448 448 1149 3449 3449 449 1150 3450 3450 441 1150 3451 3451 507 1150 3452 3452 507 1151 3453 3453 427 1151 3454 3454 447 1151 3455 3455 496 1152 3456 3456 457 1152 3457 3457 460 1152 3458 3458 494 1153 3459 3459 460 1153 3460 3460 461 1153 3461 3461 29 1154 3462 3462 454 1154 3463 3463 451 1154 3464 3464 453 1155 3465 3465 455 1155 3466 3466 452 1155 3467 3467 428 1156 3468 3468 455 1156 3469 3469 453 1156 3470 3470 10 1157 3471 3471 426 1157 3472 3472 454 1157 3473 3473 440 1158 3474 3474 453 1158 3475 3475 454 1158 3476 3476 503 1159 3477 3477 502 1159 3478 3478 465 1159 3479 3479 500 1160 3480 3480 467 1160 3481 3481 464 1160 3482 3482 498 1161 3483 3483 497 1161 3484 3484 458 1161 3485 3485 495 1162 3486 3486 461 1162 3487 3487 458 1162 3488 3488 499 1163 3489 3489 498 1163 3490 3490 459 1163 3491 3491 499 1164 3492 3492 456 1164 3493 3493 457 1164 3494 3494 594 1165 3495 3495 595 1165 3496 3496 469 1165 3497 3497 597 1166 3498 3498 594 1166 3499 3499 472 1166 3500 3500 504 1167 3501 3501 503 1167 3502 3502 462 1167 3503 3503 505 1168 3504 3504 466 1168 3505 3505 467 1168 3506 3506 505 1169 3507 3507 504 1169 3508 3508 463 1169 3509 3509 501 1170 3510 3510 464 1170 3511 3511 465 1170 3512 3512 471 1171 3513 3513 487 1171 3514 3514 488 1171 3515 3515 483 1172 3516 3516 492 1172 3517 3517 491 1172 3518 3518 596 1173 3519 3519 470 1173 3520 3520 471 1173 3521 3521 596 1174 3522 3522 597 1174 3523 3523 473 1174 3524 3524 598 1175 3525 3525 471 1175 3526 3526 468 1175 3527 3527 599 1176 3528 3528 468 1176 3529 3529 469 1176 3530 3530 463 1177 3531 3531 462 1177 3532 3532 479 1177 3533 3533 462 1178 3534 3534 465 1178 3535 3535 478 1178 3536 3536 464 1179 3537 3537 467 1179 3538 3538 475 1179 3539 3539 465 1180 3540 3540 464 1180 3541 3541 477 1180 3542 3542 466 1181 3543 3543 474 1181 3544 3544 475 1181 3545 3545 463 1182 3546 3546 476 1182 3547 3547 474 1182 3548 3548 480 1183 3549 3549 485 1183 3550 3550 484 1183 3551 3551 483 1184 3552 3552 482 1184 3553 3553 485 1184 3554 3554 469 1185 3555 3555 468 1185 3556 3556 480 1185 3557 3557 472 1186 3558 3558 484 1186 3559 3559 485 1186 3560 3560 469 1187 3561 3561 481 1187 3562 3562 484 1187 3563 3563 485 1188 3564 3564 490 1188 3565 3565 489 1188 3566 3566 488 1189 3567 3567 487 1189 3568 3568 492 1189 3569 3569 489 1190 3570 3570 490 1190 3571 3571 491 1190 3572 3572 487 1191 3573 3573 486 1191 3574 3574 491 1191 3575 3575 482 1192 3576 3576 491 1192 3577 3577 490 1192 3578 3578 483 1193 3579 3579 480 1193 3580 3580 493 1193 3581 3581 471 1194 3582 3582 470 1194 3583 3583 486 1194 3584 3584 480 1195 3585 3585 468 1195 3586 3586 488 1195 3587 3587 470 1196 3588 3588 473 1196 3589 3589 489 1196 3590 3590 412 1197 3591 3591 606 1197 3592 3592 2 1197 3593 3593 434 1198 3594 3594 0 1198 3595 3595 604 1198 3596 3596 620 1199 3597 3597 618 1199 3598 3598 499 1199 3599 3599 618 1200 3600 3600 617 1200 3601 3601 498 1200 3602 3602 616 1201 3603 3603 495 1201 3604 3604 497 1201 3605 3605 617 1202 3606 3606 621 1202 3607 3607 497 1202 3608 3608 619 1203 3609 3609 494 1203 3610 3610 495 1203 3611 3611 620 1204 3612 3612 496 1204 3613 3613 494 1204 3614 3614 458 1205 3615 3615 501 1205 3616 3616 502 1205 3617 3617 460 1206 3618 3618 457 1206 3619 3619 504 1206 3620 3620 460 1207 3621 3621 505 1207 3622 3622 500 1207 3623 3623 457 1208 3624 3624 456 1208 3625 3625 503 1208 3626 3626 461 1209 3627 3627 500 1209 3628 3628 501 1209 3629 3629 456 1210 3630 3630 459 1210 3631 3631 502 1210 3632 3632 12 1211 3633 3633 30 1211 3634 3634 455 1211 3635 3635 30 1212 3636 3636 26 1212 3637 3637 452 1212 3638 3638 525 1213 3639 3639 517 1213 3640 3640 512 1213 3641 3641 513 1214 3642 3642 510 1214 3643 3643 518 1214 3644 3644 524 1215 3645 3645 516 1215 3646 3646 515 1215 3647 3647 523 1216 3648 3648 514 1216 3649 3649 517 1216 3650 3650 512 1217 3651 3651 513 1217 3652 3652 522 1217 3653 3653 510 1218 3654 3654 511 1218 3655 3655 521 1218 3656 3656 520 1219 3657 3657 515 1219 3658 3658 514 1219 3659 3659 521 1220 3660 3660 511 1220 3661 3661 516 1220 3662 3662 521 1221 3663 3663 524 1221 3664 3664 506 1221 3665 3665 436 1222 3666 3666 520 1222 3667 3667 523 1222 3668 3668 518 1223 3669 3669 521 1223 3670 3670 427 1223 3671 3671 519 1224 3672 3672 522 1224 3673 3673 441 1224 3674 3674 508 1225 3675 3675 523 1225 3676 3676 525 1225 3677 3677 506 1226 3678 3678 524 1226 3679 3679 520 1226 3680 3680 522 1227 3681 3681 518 1227 3682 3682 507 1227 3683 3683 445 1228 3684 3684 525 1228 3685 3685 519 1228 3686 3686 559 1229 3687 3687 528 1229 3688 3688 529 1229 3689 3689 561 1230 3690 3690 532 1230 3691 3691 527 1230 3692 3692 531 1231 3693 3693 530 1231 3694 3694 558 1231 3695 3695 562 1232 3696 3696 527 1232 3697 3697 528 1232 3698 3698 565 1233 3699 3699 533 1233 3700 3700 532 1233 3701 3701 560 1234 3702 3702 529 1234 3703 3703 526 1234 3704 3704 564 1235 3705 3705 526 1235 3706 3706 531 1235 3707 3707 530 1236 3708 3708 533 1236 3709 3709 565 1236 3710 3710 537 1237 3711 3711 534 1237 3712 3712 574 1237 3713 3713 534 1238 3714 3714 539 1238 3715 3715 575 1238 3716 3716 539 1239 3717 3717 538 1239 3718 3718 576 1239 3719 3719 580 1240 3720 3720 541 1240 3721 3721 540 1240 3722 3722 581 1241 3723 3723 536 1241 3724 3724 537 1241 3725 3725 538 1242 3726 3726 541 1242 3727 3727 580 1242 3728 3728 577 1243 3729 3729 540 1243 3730 3730 535 1243 3731 3731 578 1244 3732 3732 535 1244 3733 3733 536 1244 3734 3734 626 1245 3735 3735 549 1245 3736 3736 548 1245 3737 3737 625 1246 3738 3738 546 1246 3739 3739 549 1246 3740 3740 624 1247 3741 3741 545 1247 3742 3742 547 1247 3743 3743 629 1248 3744 3744 548 1248 3745 3745 543 1248 3746 3746 547 1249 3747 3747 546 1249 3748 3748 625 1249 3749 3749 544 1250 3750 3750 545 1250 3751 3751 624 1250 3752 3752 542 1251 3753 3753 544 1251 3754 3754 623 1251 3755 3755 627 1252 3756 3756 543 1252 3757 3757 542 1252 3758 3758 529 1253 3759 3759 550 1253 3760 3760 553 1253 3761 3761 526 1254 3762 3762 553 1254 3763 3763 554 1254 3764 3764 554 1255 3765 3765 555 1255 3766 3766 530 1255 3767 3767 551 1256 3768 3768 556 1256 3769 3769 532 1256 3770 3770 528 1257 3771 3771 552 1257 3772 3772 550 1257 3773 3773 555 1258 3774 3774 551 1258 3775 3775 533 1258 3776 3776 532 1259 3777 3777 556 1259 3778 3778 557 1259 3779 3779 527 1260 3780 3780 557 1260 3781 3781 552 1260 3782 3782 558 1261 3783 3783 565 1261 3784 3784 571 1261 3785 3785 564 1262 3786 3786 563 1262 3787 3787 569 1262 3788 3788 560 1263 3789 3789 564 1263 3790 3790 570 1263 3791 3791 565 1264 3792 3792 561 1264 3793 3793 567 1264 3794 3794 568 1265 3795 3795 562 1265 3796 3796 559 1265 3797 3797 563 1266 3798 3798 558 1266 3799 3799 572 1266 3800 3800 567 1267 3801 3801 561 1267 3802 3802 562 1267 3803 3803 566 1268 3804 3804 559 1268 3805 3805 560 1268 3806 3806 515 1269 3807 3807 566 1269 3808 3808 573 1269 3809 3809 567 1270 3810 3810 568 1270 3811 3811 516 1270 3812 3812 569 1271 3813 3813 572 1271 3814 3814 513 1271 3815 3815 516 1272 3816 3816 568 1272 3817 3817 566 1272 3818 3818 571 1273 3819 3819 567 1273 3820 3820 511 1273 3821 3821 514 1274 3822 3822 573 1274 3823 3823 570 1274 3824 3824 570 1275 3825 3825 569 1275 3826 3826 512 1275 3827 3827 572 1276 3828 3828 571 1276 3829 3829 510 1276 3830 3830 549 1277 3831 3831 578 1277 3832 3832 581 1277 3833 3833 546 1278 3834 3834 577 1278 3835 3835 578 1278 3836 3836 576 1279 3837 3837 580 1279 3838 3838 547 1279 3839 3839 548 1280 3840 3840 581 1280 3841 3841 579 1280 3842 3842 547 1281 3843 3843 580 1281 3844 3844 577 1281 3845 3845 575 1282 3846 3846 576 1282 3847 3847 545 1282 3848 3848 574 1283 3849 3849 575 1283 3850 3850 544 1283 3851 3851 579 1284 3852 3852 574 1284 3853 3853 542 1284 3854 3854 538 1285 3855 3855 586 1285 3856 3856 589 1285 3857 3857 540 1286 3858 3858 588 1286 3859 3859 583 1286 3860 3860 535 1287 3861 3861 583 1287 3862 3862 584 1287 3863 3863 585 1288 3864 3864 582 1288 3865 3865 534 1288 3866 3866 534 1289 3867 3867 591 1289 3868 3868 590 1289 3869 3869 539 1290 3870 3870 587 1290 3871 3871 586 1290 3872 3872 589 1291 3873 3873 588 1291 3874 3874 540 1291 3875 3875 536 1292 3876 3876 584 1292 3877 3877 585 1292 3878 3878 593 1293 3879 3879 592 1293 3880 3880 590 1293 3881 3881 590 1294 3882 3882 592 1294 3883 3883 587 1294 3884 3884 582 1295 3885 3885 593 1295 3886 3886 591 1295 3887 3887 587 1296 3888 3888 592 1296 3889 3889 593 1296 3890 3890 584 1297 3891 3891 583 1297 3892 3892 588 1297 3893 3893 588 1298 3894 3894 589 1298 3895 3895 584 1298 3896 3896 589 1299 3897 3897 586 1299 3898 3898 585 1299 3899 3899 584 1300 3900 3900 589 1300 3901 3901 585 1300 3902 3902 586 1301 3903 3903 587 1301 3904 3904 582 1301 3905 3905 476 1302 3906 3906 479 1302 3907 3907 599 1302 3908 3908 478 1303 3909 3909 598 1303 3910 3910 599 1303 3911 3911 477 1304 3912 3912 475 1304 3913 3913 597 1304 3914 3914 477 1305 3915 3915 596 1305 3916 3916 598 1305 3917 3917 475 1306 3918 3918 474 1306 3919 3919 594 1306 3920 3920 474 1307 3921 3921 476 1307 3922 3922 595 1307 3923 3923 415 1308 3924 3924 601 1308 3925 3925 602 1308 3926 3926 414 1309 3927 3927 602 1309 3928 3928 603 1309 3929 3929 614 1310 3930 3930 600 1310 3931 3931 410 1310 3932 3932 606 1311 3933 3933 615 1311 3934 3934 222 1311 3935 3935 410 1312 3936 3936 600 1312 3937 3937 601 1312 3938 3938 412 1313 3939 3939 603 1313 3940 3940 615 1313 3941 3941 221 1314 3942 3942 614 1314 3943 3943 604 1314 3944 3944 612 1315 3945 3945 613 1315 3946 3946 420 1315 3947 3947 419 1316 3948 3948 610 1316 3949 3949 611 1316 3950 3950 608 1317 3951 3951 609 1317 3952 3952 417 1317 3953 3953 421 1318 3954 3954 413 1318 3955 3955 607 1318 3956 3956 411 1319 3957 3957 605 1319 3958 3958 608 1319 3959 3959 221 1320 3960 3960 7 1320 3961 3961 610 1320 3962 3962 413 1321 3963 3963 417 1321 3964 3964 609 1321 3965 3965 603 1322 3966 3966 420 1322 3967 3967 613 1322 3968 3968 1 1323 3969 3969 605 1323 3970 3970 611 1323 3971 3971 451 1324 3972 3972 620 1324 3973 3973 619 1324 3974 3974 27 1325 3975 3975 619 1325 3976 3976 616 1325 3977 3977 452 1326 3978 3978 26 1326 3979 3979 621 1326 3980 3980 28 1327 3981 3981 616 1327 3982 3982 621 1327 3983 3983 450 1328 3984 3984 452 1328 3985 3985 617 1328 3986 3986 451 1329 3987 3987 450 1329 3988 3988 618 1329 3989 3989 550 1330 3990 3990 627 1330 3991 3991 622 1330 3992 3992 553 1331 3993 3993 622 1331 3994 3994 623 1331 3995 3995 623 1332 3996 3996 624 1332 3997 3997 555 1332 3998 3998 551 1333 3999 3999 628 1333 4000 4000 625 1333 4001 4001 552 1334 4002 4002 629 1334 4003 4003 627 1334 4004 4004 624 1335 4005 4005 628 1335 4006 4006 551 1335 4007 4007 556 1336 4008 4008 625 1336 4009 4009 626 1336 4010 4010 557 1337 4011 4011 626 1337 4012 4012 629 1337 4013 4013 659 1338 4014 4014 637 1338 4015 4015 635 1338 4016 4016 638 1339 4017 4017 646 1339 4018 4018 658 1339 4019 4019 640 1340 4020 4020 645 1340 4021 4021 660 1340 4022 4022 638 1341 4023 4023 635 1341 4024 4024 636 1341 4025 4025 636 1342 4026 4026 634 1342 4027 4027 639 1342 4028 4028 645 1343 4029 4029 639 1343 4030 4030 655 1343 4031 4031 656 1344 4032 4032 635 1344 4033 4033 638 1344 4034 4034 637 1345 4035 4035 634 1345 4036 4036 636 1345 4037 4037 636 1346 4038 4038 645 1346 4039 4039 640 1346 4040 4040 662 1347 4041 4041 634 1347 4042 4042 637 1347 4043 4043 646 1348 4044 4044 640 1348 4045 4045 661 1348 4046 4046 655 1349 4047 4047 639 1349 4048 4048 634 1349 4049 4049 631 1350 4050 4050 647 1350 4051 4051 654 1350 4052 4052 652 1351 4053 4053 653 1351 4054 4054 630 1351 4055 4055 642 1352 4056 4056 654 1352 4057 4057 650 1352 4058 4058 641 1353 4059 4059 648 1353 4060 4060 649 1353 4061 4061 651 1354 4062 4062 647 1354 4063 4063 631 1354 4064 4064 653 1355 4065 4065 651 1355 4066 4066 643 1355 4067 4067 649 1356 4068 4068 652 1356 4069 4069 644 1356 4070 4070 633 1357 4071 4071 650 1357 4072 4072 648 1357 4073 4073 647 1358 4074 4074 655 1358 4075 4075 662 1358 4076 4076 658 1359 4077 4077 661 1359 4078 4078 653 1359 4079 4079 654 1360 4080 4080 662 1360 4081 4081 659 1360 4082 4082 648 1361 4083 4083 656 1361 4084 4084 657 1361 4085 4085 660 1362 4086 4086 655 1362 4087 4087 647 1362 4088 4088 661 1363 4089 4089 660 1363 4090 4090 651 1363 4091 4091 657 1364 4092 4092 658 1364 4093 4093 652 1364 4094 4094 650 1365 4095 4095 659 1365 4096 4096 656 1365 4097 4097 692 1366 4098 4098 670 1366 4099 4099 668 1366 4100 4100 690 1367 4101 4101 671 1367 4102 4102 679 1367 4103 4103 673 1368 4104 4104 678 1368 4105 4105 693 1368 4106 4106 671 1369 4107 4107 668 1369 4108 4108 669 1369 4109 4109 669 1370 4110 4110 667 1370 4111 4111 672 1370 4112 4112 678 1371 4113 4113 672 1371 4114 4114 688 1371 4115 4115 689 1372 4116 4116 668 1372 4117 4117 671 1372 4118 4118 670 1373 4119 4119 667 1373 4120 4120 669 1373 4121 4121 669 1374 4122 4122 678 1374 4123 4123 673 1374 4124 4124 695 1375 4125 4125 667 1375 4126 4126 670 1375 4127 4127 679 1376 4128 4128 673 1376 4129 4129 694 1376 4130 4130 672 1377 4131 4131 667 1377 4132 4132 695 1377 4133 4133 680 1378 4134 4134 687 1378 4135 4135 675 1378 4136 4136 685 1379 4137 4137 686 1379 4138 4138 663 1379 4139 4139 675 1380 4140 4140 687 1380 4141 4141 683 1380 4142 4142 674 1381 4143 4143 681 1381 4144 4144 682 1381 4145 4145 684 1382 4146 4146 680 1382 4147 4147 664 1382 4148 4148 686 1383 4149 4149 684 1383 4150 4150 676 1383 4151 4151 665 1384 4152 4152 682 1384 4153 4153 685 1384 4154 4154 666 1385 4155 4155 683 1385 4156 4156 681 1385 4157 4157 680 1386 4158 4158 688 1386 4159 4159 695 1386 4160 4160 691 1387 4161 4161 694 1387 4162 4162 686 1387 4163 4163 687 1388 4164 4164 695 1388 4165 4165 692 1388 4166 4166 681 1389 4167 4167 689 1389 4168 4168 690 1389 4169 4169 693 1390 4170 4170 688 1390 4171 4171 680 1390 4172 4172 694 1391 4173 4173 693 1391 4174 4174 684 1391 4175 4175 690 1392 4176 4176 691 1392 4177 4177 685 1392 4178 4178 683 1393 4179 4179 692 1393 4180 4180 689 1393 4181 4181 706 1394 4182 4182 705 1394 4183 4183 728 1394 4184 4184 719 1395 4185 4185 724 1395 4186 4186 696 1395 4187 4187 696 1396 4188 4188 724 1396 4189 4189 721 1396 4190 4190 717 1397 4191 4191 710 1397 4192 4192 709 1397 4193 4193 705 1398 4194 4194 707 1398 4195 4195 715 1398 4196 4196 712 1399 4197 4197 718 1399 4198 4198 697 1399 4199 4199 716 1400 4200 4200 704 1400 4201 4201 708 1400 4202 4202 726 1401 4203 4203 709 1401 4204 4204 706 1401 4205 4205 711 1402 4206 4206 704 1402 4207 4207 716 1402 4208 4208 725 1403 4209 4209 708 1403 4210 4210 710 1403 4211 4211 722 1404 4212 4212 713 1404 4213 4213 718 1404 4214 4214 707 1405 4215 4215 711 1405 4216 4216 727 1405 4217 4217 698 1406 4218 4218 703 1406 4219 4219 711 1406 4220 4220 708 1407 4221 4221 699 1407 4222 4222 702 1407 4223 4223 700 1408 4224 4224 697 1408 4225 4225 705 1408 4226 4226 710 1409 4227 4227 702 1409 4228 4228 701 1409 4229 4229 697 1410 4230 4230 698 1410 4231 4231 707 1410 4232 4232 701 1411 4233 4233 700 1411 4234 4234 706 1411 4235 4235 704 1412 4236 4236 696 1412 4237 4237 699 1412 4238 4238 711 1413 4239 4239 703 1413 4240 4240 696 1413 4241 4241 721 1414 4242 4242 724 1414 4243 4243 722 1414 4244 4244 699 1415 4245 4245 721 1415 4246 4246 723 1415 4247 4247 718 1416 4248 4248 713 1416 4249 4249 698 1416 4250 4250 713 1417 4251 4251 719 1417 4252 4252 703 1417 4253 4253 702 1418 4254 4254 723 1418 4255 4255 720 1418 4256 4256 701 1419 4257 4257 720 1419 4258 4258 712 1419 4259 4259 720 1420 4260 4260 723 1420 4261 4261 722 1420 4262 4262 722 1421 4263 4263 724 1421 4264 4264 719 1421 4265 4265 750 1422 4266 4266 732 1422 4267 4267 730 1422 4268 4268 733 1423 4269 4269 737 1423 4270 4270 749 1423 4271 4271 735 1424 4272 4272 736 1424 4273 4273 751 1424 4274 4274 733 1425 4275 4275 730 1425 4276 4276 731 1425 4277 4277 731 1426 4278 4278 729 1426 4279 4279 734 1426 4280 4280 736 1427 4281 4281 734 1427 4282 4282 746 1427 4283 4283 747 1428 4284 4284 730 1428 4285 4285 733 1428 4286 4286 732 1429 4287 4287 729 1429 4288 4288 731 1429 4289 4289 731 1430 4290 4290 736 1430 4291 4291 735 1430 4292 4292 753 1431 4293 4293 729 1431 4294 4294 732 1431 4295 4295 737 1432 4296 4296 735 1432 4297 4297 752 1432 4298 4298 746 1433 4299 4299 734 1433 4300 4300 729 1433 4301 4301 738 1434 4302 4302 746 1434 4303 4303 753 1434 4304 4304 749 1435 4305 4305 752 1435 4306 4306 744 1435 4307 4307 745 1436 4308 4308 753 1436 4309 4309 750 1436 4310 4310 739 1437 4311 4311 747 1437 4312 4312 748 1437 4313 4313 751 1438 4314 4314 746 1438 4315 4315 738 1438 4316 4316 752 1439 4317 4317 751 1439 4318 4318 742 1439 4319 4319 748 1440 4320 4320 749 1440 4321 4321 743 1440 4322 4322 741 1441 4323 4323 750 1441 4324 4324 747 1441 4325 4325 764 1442 4326 4326 763 1442 4327 4327 786 1442 4328 4328 777 1443 4329 4329 782 1443 4330 4330 754 1443 4331 4331 754 1444 4332 4332 782 1444 4333 4333 779 1444 4334 4334 775 1445 4335 4335 768 1445 4336 4336 767 1445 4337 4337 763 1446 4338 4338 765 1446 4339 4339 773 1446 4340 4340 770 1447 4341 4341 776 1447 4342 4342 755 1447 4343 4343 774 1448 4344 4344 762 1448 4345 4345 766 1448 4346 4346 784 1449 4347 4347 767 1449 4348 4348 764 1449 4349 4349 769 1450 4350 4350 762 1450 4351 4351 774 1450 4352 4352 783 1451 4353 4353 766 1451 4354 4354 768 1451 4355 4355 780 1452 4356 4356 771 1452 4357 4357 776 1452 4358 4358 765 1453 4359 4359 769 1453 4360 4360 785 1453 4361 4361 756 1454 4362 4362 761 1454 4363 4363 769 1454 4364 4364 766 1455 4365 4365 757 1455 4366 4366 760 1455 4367 4367 758 1456 4368 4368 755 1456 4369 4369 763 1456 4370 4370 768 1457 4371 4371 760 1457 4372 4372 759 1457 4373 4373 755 1458 4374 4374 756 1458 4375 4375 765 1458 4376 4376 759 1459 4377 4377 758 1459 4378 4378 764 1459 4379 4379 762 1460 4380 4380 754 1460 4381 4381 757 1460 4382 4382 769 1461 4383 4383 761 1461 4384 4384 754 1461 4385 4385 779 1462 4386 4386 782 1462 4387 4387 780 1462 4388 4388 757 1463 4389 4389 779 1463 4390 4390 781 1463 4391 4391 776 1464 4392 4392 771 1464 4393 4393 756 1464 4394 4394 771 1465 4395 4395 777 1465 4396 4396 761 1465 4397 4397 760 1466 4398 4398 781 1466 4399 4399 778 1466 4400 4400 759 1467 4401 4401 778 1467 4402 4402 770 1467 4403 4403 778 1468 4404 4404 781 1468 4405 4405 780 1468 4406 4406 780 1469 4407 4407 782 1469 4408 4408 777 1469 4409 4409

    +
    +
    +
    +
    + + + + 1 0 0 0 0 1 0 0 0 0 1 0 0 0 0 1 + + Hip UpperTorso Head R_UpperLeg R_LowerLeg R_Foot R_UpperArm R_LowerArm R_Hand R_Middle1 R_Middle2 R_Middle3 R_Index1 R_Index2 R_Index3 R_Thumb1 R_Thumb2 R_Ring1 R_Ring2 R_Ring3 R_Pinky1 R_Pinky2 R_Pinky3 L_UpperLeg L_LowerLeg L_Foot L_UpperArm L_LowerArm L_Hand L_Middle1 L_Middle2 L_Middle3 L_Index1 L_Index2 L_Index3 L_Thumb1 L_Thumb2 L_Ring1 L_Ring2 L_Ring3 L_Pinky1 L_Pinky2 L_Pinky3 + + + + + + + + 1 0 0 0 0 0 1 0.02018749 0 -1 0 0.04088389 0 0 0 1 1 0 0 0 0 -0.114376 0.9934375 0.04697024 0 -0.9934375 -0.114376 0.2314686 0 0 0 1 1 0 0 0 0 0.1803278 0.9836065 -0.1226577 0 -0.9836066 0.1803278 0.6644025 0 0 0 1 1 0 -1.50996e-7 -0.08954161 -1.50996e-7 6.34688e-7 -1 0.004032433 0 1 6.34688e-7 -0.001769244 0 0 0 1 1 0 1.74749e-7 -0.08954161 1.74901e-7 -0.04180443 -0.9991259 -0.01160109 0 0.9991259 -0.04180443 0.3737195 0 0 0 1 1 -2.01772e-7 0 -0.08954179 2.17315e-7 0.9284765 -0.3713911 0.7552185 0 0.3713911 0.9284765 0.278336 0 0 0 1 -0.09349691 -0.9956195 9.93591e-5 0.5444146 -0.05538833 0.005301058 0.9984508 -0.03221464 -0.9940778 0.09334671 -0.05564129 0.1172065 0 0 0 1 -0.08144223 -0.9966781 4.5924e-5 0.5390704 -0.007708489 6.75958e-4 0.9999701 -0.05323129 -0.9966484 0.08143955 -0.007737994 0.4455847 0 0 0 1 -0.1064302 -0.9943196 0.001017689 0.5564942 0.07073462 -0.006550371 0.9974736 -0.1080467 -0.9918012 0.1062334 0.07102996 0.6836103 0 0 0 1 5.68249e-5 -0.9999961 -0.002784132 0.4680798 -0.02040374 -0.002784729 0.999788 -0.03181701 -0.9997919 1.20493e-7 -0.02040386 0.8578922 0 0 0 1 0 -0.9999961 -0.002784729 0.4681313 0 -0.002784729 0.9999962 -0.0503202 -1 1.25141e-7 0 0.9063248 0 0 0 1 1.63528e-4 -0.999996 -0.00277996 0.4679766 -0.05872195 -0.002784729 0.9982705 0.005234539 -0.9982744 1.25685e-7 -0.05872219 0.9459486 0 0 0 1 -1.19556e-5 -0.9998971 -0.01433706 0.4609888 8.34029e-4 -0.01433706 0.9998968 -0.02060472 -0.9999997 1.22365e-7 8.34113e-4 0.8560982 0 0 0 1 -0.02179658 -0.9996583 -0.01441586 0.4806011 -0.003929436 -0.01433354 0.9998894 -0.01629412 -0.9997546 0.02185094 -0.003615677 0.8950381 0 0 0 1 6.44256e-4 -0.9998974 -0.01432222 0.459672 -0.04493266 -0.0143367 0.9988872 0.02217113 -0.9989899 1.21363e-7 -0.04493731 0.937667 0 0 0 1 -1.19709e-5 -0.9998972 -0.01433706 0.4501786 8.34081e-4 -0.01433706 0.9998968 7.88012e-4 -0.9999998 1.36575e-7 8.34165e-4 0.8582169 0 0 0 1 2.39489e-4 -0.9998973 -0.01433509 0.4499565 -0.01670241 -0.01433706 0.9997578 0.01627933 -0.9998608 1.2535e-7 -0.01670414 0.8832979 0 0 0 1 -1.39439e-5 -0.9998971 -0.01433706 0.469051 9.72342e-4 -0.01433706 0.9998967 -0.07068216 -0.9999997 1.30621e-7 9.7244e-4 0.8659414 0 0 0 1 8.43448e-4 -0.9998971 -0.0143122 0.4682704 -0.05882376 -0.01433706 0.9981654 -0.01624643 -0.9982683 1.29105e-7 -0.05882978 0.9110693 0 0 0 1 -9.75233e-5 -0.9998971 -0.0143367 0.4691566 0.006801426 -0.01433706 0.9998741 -0.0780515 -0.9999771 1.28552e-7 0.006802141 0.9391934 0 0 0 1 -1.39327e-5 -0.9998971 -0.01433706 0.4693887 9.72812e-4 -0.01433706 0.9998967 -0.09423512 -0.9999997 0 9.72909e-4 0.8668717 0 0 0 1 8.43446e-4 -0.9998972 -0.0143122 0.4686181 -0.05882358 -0.01433706 0.9981654 -0.04049479 -0.9982683 1.33237e-7 -0.0588296 0.9001603 0 0 0 1 -9.75188e-5 -0.9998972 -0.0143367 0.4694839 0.006801128 -0.01433706 0.9998741 -0.1008771 -0.9999771 1.32764e-7 0.006801843 0.9167639 0 0 0 1 1 0 -1.50996e-7 0.08954161 -1.50996e-7 6.34688e-7 -1 0.004032373 0 1 6.34688e-7 -0.001769244 0 0 0 1 1 0 -3.01672e-7 0.08954161 -3.01936e-7 -0.04180443 -0.9991259 -0.01160109 0 0.9991259 -0.04180443 0.3737195 0 0 0 1 1 2.4096e-7 0 0.08954179 -2.59522e-7 0.9284765 -0.3713911 0.7552185 0 0.3713911 0.9284765 0.278336 0 0 0 1 -0.09349691 0.9956195 -9.93591e-5 -0.5444146 0.05538833 0.005301058 0.9984508 -0.03221464 0.9940778 0.09334671 -0.05564129 0.1172065 0 0 0 1 -0.08144223 0.9966781 -4.5924e-5 -0.5390704 0.007708489 6.75958e-4 0.9999701 -0.05323129 0.9966484 0.08143955 -0.007737994 0.4455847 0 0 0 1 -0.1064302 0.9943196 -0.001017689 -0.5564942 -0.07073462 -0.006550371 0.9974736 -0.1080467 0.9918012 0.1062334 0.07102996 0.6836103 0 0 0 1 5.68249e-5 0.9999961 0.002784132 -0.4680798 0.02040374 -0.002784729 0.999788 -0.03181701 0.9997919 1.20493e-7 -0.02040386 0.8578922 0 0 0 1 0 0.9999961 0.002784729 -0.4681313 0 -0.002784729 0.9999962 -0.0503202 1 1.25141e-7 0 0.9063248 0 0 0 1 1.63528e-4 0.999996 0.00277996 -0.4679766 0.05872195 -0.002784729 0.9982705 0.005234539 0.9982744 1.25685e-7 -0.05872219 0.9459486 0 0 0 1 -1.19556e-5 0.9998971 0.01433706 -0.4609888 -8.34029e-4 -0.01433706 0.9998968 -0.02060472 0.9999997 1.22365e-7 8.34113e-4 0.8560982 0 0 0 1 -0.02179658 0.9996583 0.01441586 -0.4806011 0.003929436 -0.01433354 0.9998894 -0.01629412 0.9997546 0.02185094 -0.003615677 0.8950381 0 0 0 1 6.44256e-4 0.9998974 0.01432222 -0.459672 0.04493266 -0.0143367 0.9988872 0.02217113 0.9989899 1.21363e-7 -0.04493731 0.937667 0 0 0 1 -1.19709e-5 0.9998972 0.01433706 -0.4501786 -8.34081e-4 -0.01433706 0.9998968 7.88012e-4 0.9999998 1.36575e-7 8.34165e-4 0.8582169 0 0 0 1 2.39489e-4 0.9998973 0.01433509 -0.4499565 0.01670241 -0.01433706 0.9997578 0.01627933 0.9998608 1.2535e-7 -0.01670414 0.8832979 0 0 0 1 -1.39439e-5 0.9998971 0.01433706 -0.469051 -9.72342e-4 -0.01433706 0.9998967 -0.07068216 0.9999997 1.30621e-7 9.7244e-4 0.8659414 0 0 0 1 8.43448e-4 0.9998971 0.0143122 -0.4682704 0.05882376 -0.01433706 0.9981654 -0.01624643 0.9982683 1.29105e-7 -0.05882978 0.9110693 0 0 0 1 -9.75233e-5 0.9998971 0.0143367 -0.4691566 -0.006801426 -0.01433706 0.9998741 -0.0780515 0.9999771 1.28552e-7 0.006802141 0.9391934 0 0 0 1 -1.39327e-5 0.9998971 0.01433706 -0.4693887 -9.72812e-4 -0.01433706 0.9998967 -0.09423512 0.9999997 0 9.72909e-4 0.8668717 0 0 0 1 8.43446e-4 0.9998972 0.0143122 -0.4686181 0.05882358 -0.01433706 0.9981654 -0.04049479 0.9982683 1.33237e-7 -0.0588296 0.9001603 0 0 0 1 -9.75188e-5 0.9998972 0.0143367 -0.4694839 -0.006801128 -0.01433706 0.9998741 -0.1008771 0.9999771 1.32764e-7 0.006801843 0.9167639 0 0 0 1 + + + + + + + + 0.009747385 0.9902526 1 0.03261351 0.9673864 1 1 1 1 1 1 1 0.8851624 0.09736192 0.008737802 0.008737862 0.9900468 0.009953141 0.9121798 0.001293599 0.04326325 0.04326337 0.949214 0.05078595 0.1002475 0.8997526 0.1848154 0.8151847 0.01050829 0.9894916 0.02367436 0.9763256 0.06021809 0.9397819 0.0938819 0.9061181 1 1 0.7128452 0.2871549 0.8657404 0.1342597 0.4488505 0.5511496 0.6851214 0.3148787 0.8365766 0.0817117 0.0817117 0.7405815 0.1297092 0.1297092 0.8845823 0.05770885 0.05770885 0.8022206 0.002585649 0.09759688 0.09759688 0.8758505 0.06207472 0.06207472 1 1 0.03338342 0.9666165 1 0.04481494 0.955185 0.03188955 0.9681105 1 1 1 1 1 1 1 1 1 1 0.5509104 0.170792 0.2782974 0.6733965 0.3266035 0.8097835 0.06213706 0.1280794 0.9557135 0.04428654 0.2353773 0.7135918 0.05103081 0.148473 0.851527 0.06413429 0.9358657 0.04474073 0.9552593 0.0827232 0.9172767 0.08602505 0.913975 0.7023966 0.2976034 1 0.5091803 0.3586917 0.132128 0.7637495 0.1617161 0.07453435 0.3201102 0.09440428 0.5854856 0.8125143 0.1874858 0.1930446 0.7589149 0.04804044 0.06565737 0.9195793 0.01476329 0.1145322 0.8854677 0.618896 0.3811039 0.5746111 0.2528563 0.1725326 0.7589083 0.2410917 0.5125058 0.4874941 0.7417163 0.2582837 0.06215286 0.9378471 0.09308642 0.9069135 0.787115 0.1973227 0.01556235 0.1384345 0.8615654 0.232329 0.044245 0.7234261 0.8642567 0.1357432 0.7372296 0.2627704 0.7270892 0.2729108 0.7027738 0.2972262 0.7149568 0.2850432 0.3618105 0.6381896 0.6529391 0.3470609 1 1 1 1 1 1 0.03952097 0.960479 0.4720094 0.5279906 0.01018065 0.9898193 1 0.4497087 0.5502913 0.0835371 0.9164629 1 1 1 1 1 1 0.007469236 0.9925307 0.1134245 0.8865755 1 1 0.1269704 0.8730296 0.01691371 0.9830862 1 1 1 1 1 1 1 1 0.8675646 0.1324354 0.9043847 0.09561532 0.9410637 0.05893641 0.9195941 0.08040589 0.9308353 0.06916463 0.947664 0.05233591 0.21345 0.78655 0.235332 0.7646681 0.2214974 0.7785025 0.2100566 0.7899434 0.1979752 0.8020249 0.1299701 0.8700299 0.7210903 0.2789097 0.6340441 0.3659558 0.7529239 0.2470761 0.7972487 0.2027513 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0.4857384 0.5142616 0.46769 0.5323101 0.4656245 0.5343755 0.488262 0.5117381 0.4801961 0.519804 0.4844771 0.515523 0.4676146 0.5323855 0.466703 0.533297 0.04236173 0.9576383 0 0.04842025 0.9515797 0.04657995 0.95342 0.02325743 0.9767426 0.01867407 0.9813259 0.03530508 0.9646949 1 0.008479714 0.9915203 1 1 1 1 1 1 1 1 0.4266502 0.5733498 0.4614043 0.5385957 0.4338659 0.5661341 0.4731085 0.5268915 0.4767726 0.5232275 0.4710413 0.5289587 0.4595558 0.5404441 0.4595376 0.5404624 0.4887408 0.5112593 0.4772686 0.5227314 0.5111354 0.4888646 0.4765726 0.5234273 0.4769619 0.5230381 0.4937973 0.5062028 0.4942522 0.5057478 0.4735062 0.5264937 0.929642 0.07035791 0.922245 0.07775503 0.9191334 0.08086651 0.9452059 0.05479401 0.9485576 0.05144238 0.9355674 0.06443256 0.9449989 0.05500096 0.9435644 0.05643546 1 1 1 1 1 1 1 1 0.9999987 1.33246e-6 1 1 1 0.9924246 0.007575392 0.963296 0.03670394 1 1 3.00802e-4 0.9593265 0.04037266 0.006971418 0.8998582 0.09317028 0.5000107 0.4999893 0.5000013 0.4999988 0.9845678 0.01543211 0.9946691 0.00533086 0.959392 0.0406081 0.9636743 0.03632569 0.9669464 0.03305363 0.9731333 0.02686673 1 1 1 1 1 1 0.01027381 0.9897261 1 0.03472888 0.9652711 1 1 1 1 1 1 1 1 1 0.05407774 0.9459223 0.03934556 0.9606544 1 0.04615539 0.9538445 1 0.06712955 0.9328703 0.004417955 0.995582 1 0.05174678 0.9482532 0.02940702 0.970593 0.05391931 0.9460806 0.08414971 0.9158503 0.08636218 0.9136378 0.01083451 0.9891654 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0.9999987 1.25572e-6 1 0 1 0 0.9997983 2.01736e-4 0.9999065 9.34351e-5 0.9999293 7.07932e-5 1 0 0.9999646 3.53761e-5 1 1 1 0 0.9768831 0.02311688 0.999752 2.48015e-4 0.9999743 2.57918e-5 1 1 1 1 1 1 1 0.9998885 1.11466e-4 0.9999994 5.66496e-7 0.9990707 9.29309e-4 0.9999904 9.69049e-6 1 1 1 1 1 1 1 1 1 0.9234747 0.07652521 0.5000025 0.4999975 0.5000002 0.4999998 0.5000149 0.4999851 1 0.5028221 0.4971779 0.9948755 0.005124509 0.5329355 0.4670646 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0.03322649 0.9667736 1 0.04436701 0.9556331 0.0313546 0.9686454 1 1 1 1 1 1 1 1 1 1 0.5508908 0.1708222 0.2782871 0.6733965 0.3266035 0.8097595 0.06216478 0.1280757 0.9487037 0.05129629 0.235357 0.713616 0.05102699 0.1483705 0.8516295 0.06414002 0.9358599 0.0448625 0.9551374 0.08178913 0.9182108 0.08562761 0.9143724 0.7023966 0.2976034 1 0.5091491 0.3587312 0.1321196 0.7636697 0.1618033 0.07452696 0.3200997 0.09443593 0.5854643 0.8125143 0.1874858 0.1929965 0.7589738 0.04802966 0.06570005 0.9195373 0.01476258 0.1139538 0.8860461 0.618896 0.3811039 0.5745469 0.2529404 0.1725128 0.7551838 0.2448161 0.508906 0.4910939 0.7349897 0.2650103 0.06215292 0.9378471 0.09308648 0.9069135 0.7871149 0.01556235 0.1973227 0.1384348 0.8615651 0.2323246 0.04426425 0.7234112 0.8642567 0.1357432 0.7372296 0.2627704 0.7270892 0.2729108 0.7027738 0.2972262 0.7149568 0.2850432 0.3618105 0.6381896 0.6529391 0.3470609 1 1 1 1 1 1 0.03952097 0.960479 0.4720094 0.5279906 0.01018065 0.9898193 1 0.4497087 0.5502913 0.0835371 0.9164629 1 1 1 1 1 1 0.007469236 0.9925307 0.1134245 0.8865755 1 1 0.1269704 0.8730296 0.01691371 0.9830862 1 1 1 1 1 1 1 1 0.8675646 0.1324354 0.9043847 0.09561532 0.9410637 0.05893641 0.9195941 0.08040589 0.9308353 0.06916463 0.947664 0.05233591 0.21345 0.7865501 0.235332 0.7646681 0.2214975 0.7785026 0.2100566 0.7899434 0.1979751 0.8020249 0.1299701 0.8700299 0.7210903 0.2789097 0.6340441 0.3659558 0.7529239 0.2470761 0.7972487 0.2027513 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0.4857383 0.5142617 0.4676899 0.5323101 0.4656245 0.5343756 0.4882619 0.5117381 0.480196 0.519804 0.4844769 0.515523 0.4676145 0.5323855 0.466703 0.5332971 0.04236197 0.957638 0 0.04842036 0.9515796 0.04658037 0.9534196 0.02325755 0.9767425 0.01867544 0.9813246 0.03530615 0.9646938 1 0.008479893 0.9915201 1 1 1 1 1 1 1 1 0.4266502 0.5733498 0.4614043 0.5385957 0.4338659 0.5661341 0.4731085 0.5268915 0.4767725 0.5232275 0.4710413 0.5289587 0.4595558 0.5404441 0.4595375 0.5404624 0.4887407 0.5112593 0.4772685 0.5227315 0.5111353 0.4888646 0.4765726 0.5234274 0.4769618 0.5230381 0.4937971 0.5062028 0.4942521 0.5057479 0.4735062 0.5264938 0.9296422 0.07035779 0.9222451 0.07775485 0.9191337 0.08086633 0.9452061 0.05479389 0.9485577 0.05144226 0.9355676 0.06443238 0.944999 0.05500084 0.9435645 0.05643534 1 1 1 1 1 1 1 1 0.9999987 1.33246e-6 1 1 1 0.9924246 0.007575392 0.963296 0.03670394 1 1 3.02733e-4 0.9593246 0.04037261 0.006974518 0.8998554 0.09316998 0.5000107 0.4999893 0.5000013 0.4999988 0.9845678 0.01543211 0.9946691 0.00533086 0.9593919 0.0406081 0.9636743 0.03632569 0.9669464 0.03305363 0.9731333 0.02686673 1 1 1 1 0.009894013 0.9901059 1 0.0346924 0.9653076 1 1 1 1 1 1 1 1 1 0.05407774 0.9459223 0.03934556 0.9606543 1 0.04615545 0.9538445 1 0.06712955 0.9328703 0.004417955 0.995582 1 0.05174678 0.9482532 0.02940702 0.970593 0.05391931 0.9460806 0.08414971 0.9158503 0.08636218 0.9136378 0.01083451 0.9891654 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0.921509 0.07849097 0.9415001 0.05849987 1 0.9379092 0.06209075 1 1 1 1 1 1 1 1 1 1 1 0.9999875 1.11714e-5 1.2557e-6 1 0 1 0 0.9997983 2.01736e-4 0.9999065 9.34351e-5 0.9999293 7.07932e-5 1 0 0.9999646 3.53761e-5 1 1 1 0 0.9768831 0.02311688 0.999752 2.48015e-4 0.9999743 2.57918e-5 1 1 1 1 1 1 1 0.9998885 1.11466e-4 0.9999994 5.66496e-7 0.9990707 9.29309e-4 0.9999904 9.69049e-6 0.2526424 0.7473576 1 0.2011374 0.7988626 1 1 0.3220899 0.67791 0.2794484 0.7205516 0.3227831 0.677217 1 0.9234747 0.07652521 0.5000025 0.4999975 0.5000002 0.4999998 0.5000149 0.4999851 1 0.5028221 0.4971779 0.9948755 0.005124509 0.5329355 0.4670646 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 + + + + + + + + + + + + + + 2 1 2 1 1 1 1 1 1 1 4 2 4 2 2 2 2 2 2 2 1 1 2 2 2 2 3 3 3 4 3 1 1 2 1 2 2 1 1 1 1 1 1 1 1 1 1 3 2 3 2 3 2 2 2 2 2 2 1 3 3 3 2 3 3 2 2 3 2 2 2 2 2 3 2 3 2 2 2 2 2 2 2 1 1 1 1 1 1 2 2 2 1 2 2 1 1 1 1 1 1 2 2 1 1 2 2 1 1 1 1 1 1 1 1 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 2 2 2 2 2 2 2 2 3 2 2 2 2 2 1 2 1 1 1 1 1 1 1 1 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 1 1 1 1 1 1 1 1 2 1 1 1 2 2 1 1 3 3 2 2 2 2 2 2 2 2 1 1 1 1 1 1 2 1 2 1 1 1 1 1 1 1 1 1 2 2 1 2 1 2 2 1 2 2 2 2 2 2 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 2 2 2 2 2 2 2 2 1 1 2 2 2 2 1 1 1 1 1 1 1 2 2 2 2 1 1 1 1 1 1 1 1 1 2 2 2 2 1 2 2 2 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 2 1 2 2 1 1 1 1 1 1 1 1 1 1 3 2 3 2 3 2 2 2 2 2 2 1 3 3 3 2 3 3 2 2 3 2 2 2 2 2 3 2 3 2 2 2 2 2 2 2 1 1 1 1 1 1 2 2 2 1 2 2 1 1 1 1 1 1 2 2 1 1 2 2 1 1 1 1 1 1 1 1 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 2 2 2 2 2 2 2 2 3 2 2 2 2 2 1 2 1 1 1 1 1 1 1 1 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 1 1 1 1 1 1 1 1 2 1 1 1 2 2 1 1 3 3 2 2 2 2 2 2 2 2 1 1 1 1 2 1 2 1 1 1 1 1 1 1 1 1 2 2 1 2 1 2 2 1 2 2 2 2 2 2 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 2 2 1 2 1 1 1 1 1 1 1 1 1 1 1 3 2 2 2 2 2 2 2 1 1 2 2 2 2 1 1 1 1 1 1 1 2 2 2 2 2 1 2 1 1 2 2 2 1 2 2 2 2 1 2 2 2 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 + 1 0 2 1 2 2 1 3 2 4 2 5 2 6 2 7 2 8 2 9 2 10 2 11 0 12 1 13 3 14 23 15 1 16 2 17 0 18 1 19 3 20 23 21 1 22 2 23 0 24 1 25 0 26 1 27 0 28 1 29 0 30 1 31 1 32 2 33 1 34 2 35 1 36 1 37 0 38 1 39 0 40 1 41 1 42 2 43 1 44 2 45 0 46 3 47 23 48 0 49 3 50 23 51 0 52 3 53 23 54 0 55 1 56 3 57 23 58 0 59 3 60 23 61 2 62 2 63 1 64 2 65 2 66 1 67 2 68 1 69 2 70 2 71 2 72 2 73 2 74 2 75 2 76 2 77 2 78 2 79 2 80 0 81 1 82 3 83 1 84 6 85 0 86 1 87 3 88 1 89 2 90 0 91 1 92 3 93 0 94 1 95 0 96 1 97 0 98 1 99 1 100 2 101 1 102 2 103 1 104 6 105 1 106 0 107 1 108 3 109 0 110 1 111 3 112 0 113 1 114 3 115 1 116 6 117 0 118 1 119 3 120 0 121 1 122 6 123 1 124 2 125 1 126 6 127 0 128 1 129 3 130 1 131 2 132 1 133 2 134 1 135 2 136 0 137 3 138 0 139 3 140 0 141 3 142 23 143 0 144 3 145 0 146 1 147 3 148 0 149 3 150 3 151 4 152 3 153 4 154 3 155 4 156 3 157 4 158 3 159 4 160 3 161 4 162 4 163 4 164 4 165 4 166 4 167 4 168 4 169 5 170 4 171 5 172 4 173 5 174 5 175 4 176 5 177 4 178 5 179 4 180 4 181 4 182 4 183 4 184 4 185 4 186 5 187 4 188 5 189 5 190 5 191 4 192 5 193 4 194 5 195 5 196 5 197 5 198 5 199 5 200 5 201 5 202 5 203 3 204 4 205 3 206 4 207 3 208 4 209 3 210 4 211 3 212 4 213 3 214 4 215 3 216 4 217 3 218 4 219 3 220 4 221 3 222 4 223 3 224 4 225 3 226 4 227 1 228 6 229 1 230 6 231 1 232 6 233 1 234 6 235 6 236 6 237 6 238 6 239 6 240 6 241 6 242 6 243 6 244 6 245 6 246 6 247 6 248 6 249 6 250 6 251 6 252 7 253 6 254 7 255 6 256 7 257 6 258 7 259 6 260 7 261 6 262 7 263 6 264 7 265 6 266 7 267 7 268 8 269 15 270 7 271 8 272 7 273 8 274 7 275 8 276 7 277 8 278 7 279 8 280 7 281 7 282 8 283 7 284 7 285 7 286 7 287 7 288 7 289 7 290 7 291 6 292 7 293 6 294 7 295 6 296 7 297 6 298 7 299 6 300 7 301 6 302 7 303 6 304 7 305 6 306 7 307 6 308 7 309 6 310 7 311 6 312 7 313 6 314 7 315 6 316 7 317 6 318 7 319 6 320 7 321 6 322 7 323 6 324 7 325 6 326 7 327 6 328 7 329 6 330 7 331 6 332 7 333 6 334 7 335 6 336 7 337 6 338 7 339 7 340 7 341 7 342 7 343 7 344 7 345 7 346 7 347 8 348 15 349 8 350 8 351 8 352 8 353 15 354 8 355 15 356 8 357 8 358 7 359 8 360 15 361 7 362 8 363 15 364 8 365 15 366 8 367 15 368 4 369 5 370 4 371 5 372 4 373 5 374 4 375 5 376 4 377 5 378 4 379 5 380 2 381 2 382 2 383 2 384 2 385 2 386 1 387 2 388 2 389 1 390 2 391 2 392 2 393 2 394 2 395 2 396 2 397 2 398 2 399 2 400 0 401 3 402 0 403 3 404 3 405 0 406 3 407 3 408 0 409 3 410 6 411 7 412 7 413 6 414 7 415 6 416 7 417 6 418 7 419 6 420 7 421 6 422 7 423 6 424 7 425 8 426 8 427 8 428 8 429 22 430 22 431 22 432 22 433 22 434 22 435 22 436 8 437 8 438 8 439 8 440 22 441 22 442 20 443 20 444 20 445 20 446 20 447 20 448 20 449 20 450 21 451 21 452 21 453 21 454 21 455 21 456 21 457 21 458 8 459 8 460 8 461 8 462 11 463 11 464 11 465 11 466 11 467 11 468 11 469 8 470 8 471 8 472 8 473 11 474 11 475 9 476 9 477 9 478 9 479 9 480 9 481 9 482 9 483 10 484 10 485 10 486 10 487 10 488 10 489 10 490 10 491 13 492 13 493 13 494 13 495 13 496 13 497 13 498 13 499 12 500 15 501 12 502 15 503 12 504 15 505 12 506 15 507 12 508 15 509 12 510 15 511 12 512 15 513 12 514 15 515 14 516 14 517 8 518 15 519 8 520 15 521 8 522 15 523 8 524 15 525 14 526 14 527 14 528 14 529 14 530 14 531 14 532 8 533 15 534 8 535 15 536 8 537 15 538 8 539 15 540 16 541 16 542 16 543 16 544 16 545 16 546 16 547 16 548 16 549 8 550 15 551 8 552 15 553 8 554 15 555 8 556 15 557 8 558 8 559 15 560 8 561 15 562 8 563 15 564 15 565 15 566 15 567 15 568 15 569 15 570 15 571 15 572 18 573 18 574 18 575 18 576 18 577 18 578 18 579 18 580 17 581 17 582 17 583 17 584 17 585 17 586 17 587 17 588 19 589 19 590 8 591 8 592 8 593 8 594 19 595 19 596 19 597 19 598 19 599 19 600 19 601 8 602 8 603 8 604 8 605 2 606 2 607 1 608 2 609 2 610 1 611 2 612 1 613 2 614 2 615 2 616 2 617 2 618 2 619 2 620 2 621 2 622 2 623 2 624 0 625 1 626 23 627 1 628 26 629 0 630 1 631 23 632 1 633 2 634 0 635 1 636 23 637 0 638 1 639 0 640 1 641 0 642 1 643 1 644 2 645 1 646 2 647 1 648 26 649 1 650 0 651 1 652 23 653 0 654 1 655 23 656 0 657 1 658 23 659 1 660 26 661 0 662 1 663 23 664 0 665 1 666 26 667 1 668 2 669 1 670 26 671 0 672 1 673 23 674 1 675 2 676 1 677 2 678 1 679 2 680 0 681 23 682 0 683 23 684 0 685 3 686 23 687 0 688 23 689 0 690 1 691 23 692 0 693 23 694 23 695 24 696 23 697 24 698 23 699 24 700 23 701 24 702 23 703 24 704 23 705 24 706 24 707 24 708 24 709 24 710 24 711 24 712 24 713 25 714 24 715 25 716 24 717 25 718 25 719 24 720 25 721 24 722 25 723 24 724 24 725 24 726 24 727 24 728 24 729 24 730 25 731 24 732 25 733 25 734 25 735 24 736 25 737 24 738 25 739 25 740 25 741 25 742 25 743 25 744 25 745 25 746 25 747 23 748 24 749 23 750 24 751 23 752 24 753 23 754 24 755 23 756 24 757 23 758 24 759 23 760 24 761 23 762 24 763 23 764 24 765 23 766 24 767 23 768 24 769 23 770 24 771 1 772 26 773 1 774 26 775 1 776 26 777 1 778 26 779 26 780 26 781 26 782 26 783 26 784 26 785 26 786 26 787 26 788 26 789 26 790 26 791 26 792 26 793 26 794 26 795 26 796 27 797 26 798 27 799 26 800 27 801 26 802 27 803 26 804 27 805 26 806 27 807 26 808 27 809 26 810 27 811 27 812 28 813 35 814 27 815 28 816 27 817 28 818 27 819 28 820 27 821 28 822 27 823 28 824 27 825 27 826 28 827 27 828 27 829 27 830 27 831 27 832 27 833 27 834 27 835 26 836 27 837 26 838 27 839 26 840 27 841 26 842 27 843 26 844 27 845 26 846 27 847 26 848 27 849 26 850 27 851 26 852 27 853 26 854 27 855 26 856 27 857 26 858 27 859 26 860 27 861 26 862 27 863 26 864 27 865 26 866 27 867 26 868 27 869 26 870 27 871 26 872 27 873 26 874 27 875 26 876 27 877 26 878 27 879 26 880 27 881 26 882 27 883 27 884 27 885 27 886 27 887 27 888 27 889 27 890 27 891 28 892 35 893 28 894 28 895 28 896 28 897 35 898 28 899 35 900 28 901 28 902 27 903 28 904 35 905 27 906 28 907 35 908 28 909 35 910 28 911 35 912 24 913 25 914 24 915 25 916 24 917 25 918 24 919 25 920 24 921 25 922 24 923 25 924 2 925 2 926 2 927 2 928 1 929 2 930 2 931 1 932 2 933 2 934 2 935 2 936 2 937 2 938 2 939 2 940 2 941 2 942 0 943 23 944 0 945 23 946 23 947 0 948 23 949 23 950 0 951 23 952 26 953 27 954 27 955 26 956 27 957 26 958 27 959 26 960 27 961 26 962 27 963 26 964 27 965 26 966 27 967 28 968 28 969 28 970 28 971 42 972 42 973 42 974 42 975 42 976 42 977 42 978 28 979 28 980 28 981 28 982 42 983 42 984 40 985 40 986 40 987 40 988 40 989 40 990 40 991 40 992 41 993 41 994 41 995 41 996 41 997 41 998 41 999 41 1000 28 1001 28 1002 28 1003 28 1004 31 1005 31 1006 31 1007 31 1008 31 1009 31 1010 31 1011 28 1012 28 1013 28 1014 28 1015 31 1016 31 1017 29 1018 29 1019 29 1020 29 1021 29 1022 29 1023 29 1024 29 1025 30 1026 30 1027 33 1028 30 1029 33 1030 30 1031 30 1032 33 1033 30 1034 30 1035 30 1036 33 1037 33 1038 33 1039 33 1040 33 1041 33 1042 33 1043 33 1044 32 1045 33 1046 35 1047 32 1048 35 1049 32 1050 35 1051 32 1052 35 1053 32 1054 35 1055 32 1056 35 1057 32 1058 35 1059 32 1060 35 1061 34 1062 34 1063 28 1064 35 1065 28 1066 35 1067 28 1068 35 1069 28 1070 35 1071 34 1072 34 1073 34 1074 34 1075 34 1076 34 1077 34 1078 28 1079 35 1080 28 1081 35 1082 28 1083 35 1084 28 1085 35 1086 33 1087 36 1088 36 1089 33 1090 36 1091 36 1092 36 1093 33 1094 36 1095 33 1096 36 1097 33 1098 36 1099 36 1100 28 1101 35 1102 28 1103 35 1104 28 1105 35 1106 28 1107 35 1108 28 1109 28 1110 35 1111 28 1112 35 1113 28 1114 35 1115 35 1116 35 1117 35 1118 35 1119 35 1120 35 1121 35 1122 35 1123 38 1124 38 1125 38 1126 38 1127 38 1128 38 1129 38 1130 38 1131 37 1132 37 1133 37 1134 37 1135 37 1136 37 1137 37 1138 37 1139 39 1140 39 1141 28 1142 28 1143 28 1144 28 1145 39 1146 39 1147 39 1148 39 1149 39 1150 39 1151 39 1152 28 1153 28 1154 28 1155 28 1156 + + + + + + + + 1 0 0 0 0 1 0 0 0 0 1 0 0 0 0 1 + + 1 0 0 0 0 0 -1 0.04088391 0 1 0 -0.02018755 0 0 0 1 + + 1 0 0 0 0 0.9934375 -0.1143761 0 0 0.1143761 0.9934375 -0.194438 0 0 0 1 + + 1 0 0 0 -2.22827e-16 0.9258054 0.3780007 -3.72529e-9 0 -0.3780007 0.9258053 -0.3676334 0 0 0 1 + + 1 0 0 0 0 0.9957995 -0.09156074 -9.77889e-9 0 0.09156077 0.9957995 -0.07797433 0 0 0 1 + + + 1 + Bones + 0 + 0 + 0.1802077 + -0.03303807 + + + + + + 1 + Bones + 0 + + + + + -0.09349707 -0.05538832 -0.9940777 0.1656292 0.1139737 0.9912922 -0.0659528 0.02458553 0.9890745 -0.1194651 -0.08636999 -0.3007234 0 0 0 1 + + 0.9999269 1.47073e-4 0.0121001 2.98023e-8 -7.26653e-4 0.9988516 0.0479084 -5.58794e-9 -0.01207914 -0.04791368 0.9987785 -0.3238729 0 0 0 1 + + 0.9996847 8.13621e-4 -0.02510269 -8.56817e-8 0.001165986 0.9968942 0.07874503 0 0.02508879 -0.07874946 0.9965788 -0.2581572 0 0 0 1 + + 0.9943069 0.005958037 0.1063873 1.49012e-8 0.003777199 0.995837 -0.09107221 -1.49012e-8 -0.1064871 0.09095558 0.9901453 -0.1130893 0 0 0 1 + + 0.9999999 5.80214e-7 -5.68249e-5 -1.97906e-8 5.79515e-7 0.9997917 0.02040377 0 5.68249e-5 -0.02040377 0.9997917 -0.04929709 0 0 0 1 + + 0.9999999 4.80562e-6 1.63528e-4 6.49015e-9 4.80539e-6 0.9982743 -0.05872198 0 -1.63528e-4 0.05872198 0.9982743 -0.03822243 0 0 0 1 + + + 1 + Bones + 1.573581 + 0.03419893 + 0 + 0.002011656 + + + + + + 1 + Bones + 1.573581 + + + + + + 1 + Bones + 1.573581 + + + + + 0.9942042 0.01518451 0.106431 0.007374659 -0.007752027 0.9975237 -0.06990261 -0.02407584 -0.1072289 0.0686724 0.99186 -0.114673 0 0 0 1 + + 0.9997627 -3.39467e-6 -0.02178483 -2.43017e-8 -1.00378e-4 0.9999886 -0.00476245 -1.86265e-9 0.0217846 0.004763506 0.9997514 -0.04910958 0 0 0 1 + + 0.9997481 9.11376e-4 0.02242242 3.35276e-8 8.86247e-6 0.9991589 -0.04100683 0 -0.02244093 0.0409967 0.9989072 -0.03219759 0 0 0 1 + + + 1 + Bones + 1.585134 + 0.03364485 + 0 + 0.001513421 + + + + + + 1 + Bones + 1.607066 + + + + + + Bones + 1.585134 + + + + + 0.9942042 0.0151845 0.106431 0.01757193 -0.007752028 0.9975237 -0.06990255 -0.0453514 -0.1072289 0.06867235 0.9918599 -0.1194025 0 0 0 1 + + 1 2.20258e-6 2.51458e-4 -7.61065e-9 2.20817e-6 0.9998462 -0.01753639 0 -2.51458e-4 0.01753639 0.9998461 -0.02511728 0 0 0 1 + + + 1 + Bones + 1.585134 + 0.02438956 + 0 + 4.07464e-4 + + + + + + Bones + 1.585134 + + + + + 0.9942043 0.01516978 0.1064312 -9.2914e-4 -0.007752162 0.9975333 -0.06976461 0.02650937 -0.107227 0.06853521 0.9918696 -0.1201515 0 0 0 1 + + 0.9999996 2.56589e-5 8.57367e-4 5.82077e-10 2.56533e-5 0.9982107 -0.05979438 -7.45058e-9 -8.57368e-4 0.05979437 0.9982103 -0.04212457 0 0 0 1 + + 0.9999995 3.08976e-5 -9.40783e-4 9.77889e-9 3.08966e-5 0.9978453 0.06561208 -7.45058e-9 9.40783e-4 -0.06561208 0.9978448 -0.0316624 0 0 0 1 + + + 1 + Bones + 1.585134 + 0.03422701 + 0 + -2.32823e-4 + + + + + + 1 + Bones + 1.585134 + + + + + + Bones + 1.585134 + + + + + 0.9942043 0.01516974 0.1064312 -0.001006626 -0.007752167 0.9975334 -0.06976414 0.05007137 -0.107227 0.06853475 0.9918696 -0.1194239 0 0 0 1 + + 0.9999996 2.56523e-5 8.57354e-4 2.04891e-8 2.56589e-5 0.9982107 -0.05979469 0 -8.57354e-4 0.05979469 0.9982103 -0.02885437 0 0 0 1 + + 0.9999996 3.08966e-5 -9.40776e-4 2.64845e-8 3.08957e-5 0.9978453 0.06561161 0 9.40776e-4 -0.0656116 0.9978449 -0.02168822 0 0 0 1 + + + 1 + Bones + 1.585134 + 0.02344489 + 0 + -1.59472e-4 + + + + + + 1 + Bones + 1.585134 + + + + + + Bones + 1.585134 + + + + + + 1 + Bones + 1.676481 + + + + + + 1 + Bones + 1.652283 + + + + + + Bones + 1.664325 + + + + + -0.09349707 0.05538832 0.9940777 -0.1656292 -0.1139737 0.9912922 -0.0659528 0.02458553 -0.9890745 -0.1194651 -0.08636999 -0.3007234 0 0 0 1 + + 0.9999269 -1.47073e-4 -0.0121001 -2.98023e-8 7.26653e-4 0.9988516 0.0479084 -5.58794e-9 0.01207914 -0.04791368 0.9987785 -0.3238729 0 0 0 1 + + 0.9996847 -8.13621e-4 0.02510269 8.56817e-8 -0.001165986 0.9968942 0.07874503 0 -0.02508879 -0.07874946 0.9965788 -0.2581572 0 0 0 1 + + 0.9943069 -0.005958037 -0.1063873 -1.49012e-8 -0.003777199 0.995837 -0.09107221 -1.49012e-8 0.1064871 0.09095558 0.9901453 -0.1130893 0 0 0 1 + + 0.9999999 -5.80214e-7 5.68249e-5 1.97906e-8 -5.79515e-7 0.9997917 0.02040377 0 -5.68249e-5 -0.02040377 0.9997917 -0.04929709 0 0 0 1 + + 0.9999999 -4.80562e-6 -1.63528e-4 -6.49015e-9 -4.80539e-6 0.9982743 -0.05872198 0 1.63528e-4 0.05872198 0.9982743 -0.03822243 0 0 0 1 + + + 1 + Bones + -1.573581 + -0.03419893 + 0 + 0.002011656 + + + + + + 1 + Bones + -1.573581 + + + + + + 1 + Bones + -1.573581 + + + + + 0.9942042 -0.01518451 -0.106431 -0.007374659 0.007752027 0.9975237 -0.06990261 -0.02407584 0.1072289 0.0686724 0.99186 -0.114673 0 0 0 1 + + 0.9997627 3.39467e-6 0.02178483 2.43017e-8 1.00378e-4 0.9999886 -0.00476245 -1.86265e-9 -0.0217846 0.004763506 0.9997514 -0.04910958 0 0 0 1 + + 0.9997481 -9.11376e-4 -0.02242242 -3.35276e-8 -8.86247e-6 0.9991589 -0.04100683 0 0.02244093 0.0409967 0.9989072 -0.03219759 0 0 0 1 + + + 1 + Bones + -1.585134 + -0.03364485 + 0 + 0.001513421 + + + + + + 1 + Bones + -1.607066 + + + + + + Bones + -1.585134 + + + + + 0.9942042 -0.0151845 -0.106431 -0.01757193 0.007752028 0.9975237 -0.06990255 -0.0453514 0.1072289 0.06867235 0.9918599 -0.1194025 0 0 0 1 + + 1 -2.20258e-6 -2.51458e-4 7.61065e-9 -2.20817e-6 0.9998462 -0.01753639 0 2.51458e-4 0.01753639 0.9998461 -0.02511728 0 0 0 1 + + + 1 + Bones + -1.585134 + -0.02438956 + 0 + 4.07464e-4 + + + + + + Bones + -1.585134 + + + + + 0.9942043 -0.01516978 -0.1064312 9.2914e-4 0.007752162 0.9975333 -0.06976461 0.02650937 0.107227 0.06853521 0.9918696 -0.1201515 0 0 0 1 + + 0.9999996 -2.56589e-5 -8.57367e-4 -5.82077e-10 -2.56533e-5 0.9982107 -0.05979438 -7.45058e-9 8.57368e-4 0.05979437 0.9982103 -0.04212457 0 0 0 1 + + 0.9999995 -3.08976e-5 9.40783e-4 -9.77889e-9 -3.08966e-5 0.9978453 0.06561208 -7.45058e-9 -9.40783e-4 -0.06561208 0.9978448 -0.0316624 0 0 0 1 + + + 1 + Bones + -1.585134 + -0.03422701 + 0 + -2.32823e-4 + + + + + + 1 + Bones + -1.585134 + + + + + + Bones + -1.585134 + + + + + 0.9942043 -0.01516974 -0.1064312 0.001006626 0.007752167 0.9975334 -0.06976414 0.05007137 0.107227 0.06853475 0.9918696 -0.1194239 0 0 0 1 + + 0.9999996 -2.56523e-5 -8.57354e-4 -2.04891e-8 -2.56589e-5 0.9982107 -0.05979469 0 8.57354e-4 0.05979469 0.9982103 -0.02885437 0 0 0 1 + + 0.9999996 -3.08966e-5 9.40776e-4 -2.64845e-8 -3.08957e-5 0.9978453 0.06561161 0 -9.40776e-4 -0.0656116 0.9978449 -0.02168822 0 0 0 1 + + + 1 + Bones + -1.585134 + -0.02344489 + 0 + -1.59472e-4 + + + + + + 1 + Bones + -1.585134 + + + + + + Bones + -1.585134 + + + + + + 1 + Bones + -1.676481 + + + + + + 1 + Bones + -1.652283 + + + + + + Bones + -1.664325 + + + + + + 1 + Bones + 0 + + + + + 1 -1.50996e-7 4.79176e-14 0.08954165 -1.50996e-7 -1 6.34688e-7 0.02421998 -4.79176e-14 -6.34688e-7 -1 0.03911464 0 0 0 1 + + 1 3.25765e-7 6.31234e-9 0 -3.25744e-7 0.9991258 0.04180507 0 7.31181e-9 -0.04180507 0.9991258 -0.375647 0 0 0 1 + + 1 1.59203e-7 1.64965e-7 -7.45058e-9 1.02698e-7 0.332252 -0.9431908 0 -2.04969e-7 0.9431908 0.332252 -0.4310732 0 0 0 1 + + + 1 + Bones + 2.17315e-7 + 0 + -0.07929152 + -0.1982285 + + + + + + 1 + Bones + 1.74901e-7 + + + + + + Bones + -1.50996e-7 + + + + + 1 -1.50996e-7 4.79176e-14 -0.08954165 -1.50996e-7 -1 6.34688e-7 0.02421998 -4.79176e-14 -6.34688e-7 -1 0.03911464 0 0 0 1 + + 1 -1.51072e-7 6.31234e-9 0 1.50676e-7 0.9991258 0.04180507 0 -1.26224e-8 -0.04180507 0.9991258 -0.375647 0 0 0 1 + + 1 -1.59203e-7 -2.84783e-7 0 -2.15709e-7 0.332252 -0.9431908 1.86265e-9 2.44779e-7 0.9431908 0.332252 -0.4310732 0 0 0 1 + + + 1 + Bones + -2.59522e-7 + 0 + -0.07929152 + -0.1982285 + + + + + + 1 + Bones + -3.01936e-7 + + + + + + Bones + -1.50996e-7 + + + + + + Bones + + + + + 1 0 0 0 0 1 0 0 0 0 1 0 0 0 0 1 + + #Armature_Hip + + + + + Bones + Bones + Bones + + + + + + + + +
    \ No newline at end of file diff --git a/assets/blanktexture.png b/assets/blanktexture.png new file mode 100644 index 0000000..1691867 Binary files /dev/null and b/assets/blanktexture.png differ diff --git a/assets/bullet.obj b/assets/bullet.obj new file mode 100644 index 0000000..064d174 --- /dev/null +++ b/assets/bullet.obj @@ -0,0 +1,786 @@ +# Blender 4.4.0 +# www.blender.org +mtllib bullet.mtl +o Cylinder +v -0.000000 -0.356739 -0.291425 +v -0.000000 1.967766 -0.291425 +v 0.111523 -0.356739 -0.269241 +v 0.111523 1.967766 -0.269241 +v 0.206068 -0.356739 -0.206068 +v 0.206068 1.967766 -0.206068 +v 0.269241 -0.356739 -0.111523 +v 0.269241 1.967766 -0.111523 +v 0.291425 -0.356739 0.000000 +v 0.291425 1.967766 0.000000 +v 0.269241 -0.356739 0.111523 +v 0.269241 1.967766 0.111523 +v 0.206068 -0.356739 0.206068 +v 0.206068 1.967766 0.206068 +v 0.111523 -0.356739 0.269241 +v 0.111523 1.967766 0.269241 +v -0.000000 -0.356739 0.291425 +v -0.000000 1.967766 0.291425 +v -0.111523 -0.356739 0.269241 +v -0.111523 1.967766 0.269241 +v -0.206068 -0.356739 0.206068 +v -0.206068 1.967766 0.206068 +v -0.269241 -0.356739 0.111523 +v -0.269241 1.967766 0.111523 +v -0.291425 -0.356739 0.000000 +v -0.291425 1.967766 0.000000 +v -0.269241 -0.356739 -0.111523 +v -0.269241 1.967766 -0.111523 +v -0.206068 -0.356739 -0.206068 +v -0.206068 1.967766 -0.206068 +v -0.111523 -0.356739 -0.269241 +v -0.111523 1.967766 -0.269241 +v 0.079137 2.172900 -0.191053 +v -0.000000 2.172900 -0.206794 +v 0.146225 2.172900 -0.146225 +v 0.191053 2.172900 -0.079137 +v 0.206794 2.172900 0.000000 +v 0.191053 2.172900 0.079137 +v 0.146225 2.172900 0.146225 +v 0.079137 2.172900 0.191053 +v -0.000000 2.172900 0.206794 +v -0.079137 2.172900 0.191053 +v -0.146225 2.172900 0.146225 +v -0.191053 2.172900 0.079137 +v -0.206794 2.172900 0.000000 +v -0.191053 2.172900 -0.079137 +v -0.146225 2.172900 -0.146225 +v -0.079137 2.172900 -0.191053 +v 0.072378 2.571189 -0.174735 +v -0.000000 2.571189 -0.189132 +v 0.133736 2.571189 -0.133736 +v 0.174735 2.571189 -0.072378 +v 0.189132 2.571189 0.000000 +v 0.174735 2.571189 0.072378 +v 0.133736 2.571189 0.133736 +v 0.072378 2.571189 0.174735 +v -0.000000 2.571189 0.189132 +v -0.072378 2.571189 0.174735 +v -0.133736 2.571189 0.133736 +v -0.174735 2.571189 0.072378 +v -0.189132 2.571189 0.000000 +v -0.174735 2.571189 -0.072378 +v -0.133736 2.571189 -0.133736 +v -0.072378 2.571189 -0.174735 +v -0.000000 -0.457327 -0.242024 +v 0.092618 -0.457327 -0.223601 +v 0.171137 -0.457327 -0.171137 +v 0.223601 -0.457327 -0.092618 +v 0.242024 -0.457327 0.000000 +v 0.223601 -0.457327 0.092618 +v 0.171137 -0.457327 0.171137 +v 0.092618 -0.457327 0.223601 +v -0.000000 -0.457327 0.242024 +v -0.092618 -0.457327 0.223601 +v -0.171137 -0.457327 0.171137 +v -0.223601 -0.457327 0.092618 +v -0.242024 -0.457327 0.000000 +v -0.223601 -0.457327 -0.092618 +v -0.171137 -0.457327 -0.171137 +v -0.092618 -0.457327 -0.223601 +v -0.000000 -0.527447 -0.242024 +v 0.092618 -0.527447 -0.223601 +v 0.171137 -0.527447 -0.171137 +v 0.223601 -0.527447 -0.092618 +v 0.242024 -0.527447 0.000000 +v 0.223601 -0.527447 0.092618 +v 0.171137 -0.527447 0.171137 +v 0.092618 -0.527447 0.223601 +v -0.000000 -0.527447 0.242024 +v -0.092618 -0.527447 0.223601 +v -0.171137 -0.527447 0.171137 +v -0.223601 -0.527447 0.092618 +v -0.242024 -0.527447 0.000000 +v -0.223601 -0.527447 -0.092618 +v -0.171137 -0.527447 -0.171137 +v -0.092618 -0.527447 -0.223601 +v -0.000000 -0.527447 -0.292334 +v 0.111872 -0.527447 -0.270082 +v 0.206712 -0.527447 -0.206712 +v 0.270082 -0.527447 -0.111872 +v 0.292334 -0.527447 0.000000 +v 0.270082 -0.527447 0.111872 +v 0.206712 -0.527447 0.206712 +v 0.111872 -0.527447 0.270082 +v -0.000000 -0.527447 0.292334 +v -0.111872 -0.527447 0.270082 +v -0.206712 -0.527447 0.206712 +v -0.270082 -0.527447 0.111872 +v -0.292334 -0.527447 0.000000 +v -0.270082 -0.527447 -0.111872 +v -0.206712 -0.527447 -0.206712 +v -0.111872 -0.527447 -0.270082 +v -0.000000 -0.569571 -0.115503 +v 0.044201 -0.569571 -0.106711 +v 0.081673 -0.569571 -0.081673 +v 0.106711 -0.569571 -0.044201 +v 0.115503 -0.569571 -0.000000 +v 0.106711 -0.569571 0.044201 +v 0.081673 -0.569571 0.081673 +v 0.044201 -0.569571 0.106711 +v -0.000000 -0.569571 0.115503 +v -0.044201 -0.569571 0.106711 +v -0.081673 -0.569571 0.081673 +v -0.106711 -0.569571 0.044201 +v -0.115503 -0.569571 -0.000000 +v -0.106711 -0.569571 -0.044201 +v -0.081673 -0.569571 -0.081673 +v -0.044201 -0.569571 -0.106711 +v 0.079137 2.571189 -0.191053 +v -0.000000 2.571189 -0.206794 +v 0.146225 2.571189 -0.146225 +v 0.191053 2.571189 -0.079137 +v 0.206794 2.571189 0.000000 +v 0.191053 2.571189 0.079137 +v 0.146225 2.571189 0.146225 +v 0.079137 2.571189 0.191053 +v -0.000000 2.571189 0.206794 +v -0.079137 2.571189 0.191053 +v -0.146225 2.571189 0.146225 +v -0.191053 2.571189 0.079137 +v -0.206794 2.571189 0.000000 +v -0.191053 2.571189 -0.079137 +v -0.146225 2.571189 -0.146225 +v -0.079137 2.571189 -0.191053 +v 0.084496 -0.319021 -0.203993 +v -0.000000 -0.319021 -0.220800 +v 0.156129 -0.319021 -0.156129 +v 0.203993 -0.319021 -0.084497 +v 0.220800 -0.319021 0.000000 +v 0.203993 -0.319021 0.084497 +v 0.156129 -0.319021 0.156129 +v 0.084496 -0.319021 0.203993 +v -0.000000 -0.319021 0.220800 +v -0.084497 -0.319021 0.203993 +v -0.156129 -0.319021 0.156129 +v -0.203993 -0.319021 0.084497 +v -0.220800 -0.319021 0.000000 +v -0.203993 -0.319021 -0.084497 +v -0.156129 -0.319021 -0.156129 +v -0.084497 -0.319021 -0.203993 +v -0.000000 -0.569571 -0.292334 +v 0.111872 -0.569571 -0.270082 +v 0.206712 -0.569571 -0.206712 +v 0.270082 -0.569571 -0.111872 +v 0.292334 -0.569571 0.000000 +v 0.270082 -0.569571 0.111872 +v 0.206712 -0.569571 0.206712 +v 0.111872 -0.569571 0.270082 +v -0.000000 -0.569571 0.292334 +v -0.111872 -0.569571 0.270082 +v -0.206712 -0.569571 0.206712 +v -0.270082 -0.569571 0.111872 +v -0.292334 -0.569571 0.000000 +v -0.270082 -0.569571 -0.111872 +v -0.206712 -0.569571 -0.206712 +v -0.111872 -0.569571 -0.270082 +v -0.000000 -0.510787 -0.115503 +v 0.044201 -0.510787 -0.106711 +v 0.081673 -0.510787 -0.081673 +v 0.106711 -0.510787 -0.044201 +v 0.115503 -0.510787 -0.000000 +v 0.106711 -0.510787 0.044201 +v 0.081673 -0.510787 0.081673 +v 0.044201 -0.510787 0.106711 +v -0.000000 -0.510787 0.115503 +v -0.044201 -0.510787 0.106711 +v -0.081673 -0.510787 0.081673 +v -0.106711 -0.510787 0.044201 +v -0.115503 -0.510787 -0.000000 +v -0.106711 -0.510787 -0.044201 +v -0.081673 -0.510787 -0.081673 +v -0.044201 -0.510787 -0.106711 +vn 0.1951 -0.0000 -0.9808 +vn 0.5556 -0.0000 -0.8315 +vn 0.8315 -0.0000 -0.5556 +vn 0.9808 -0.0000 -0.1951 +vn 0.9808 -0.0000 0.1951 +vn 0.8315 -0.0000 0.5556 +vn 0.5556 -0.0000 0.8315 +vn 0.1951 -0.0000 0.9808 +vn -0.1951 -0.0000 0.9808 +vn -0.5556 -0.0000 0.8315 +vn -0.8315 -0.0000 0.5556 +vn -0.9808 -0.0000 0.1951 +vn -0.9808 -0.0000 -0.1951 +vn -0.8315 -0.0000 -0.5556 +vn -0.5150 0.3751 -0.7708 +vn -0.5556 -0.0000 -0.8315 +vn -0.1951 -0.0000 -0.9808 +vn 0.7491 -0.4340 -0.5005 +vn 0.7708 0.3751 -0.5150 +vn 0.1808 0.3751 0.9092 +vn 0.1808 0.3751 -0.9092 +vn -0.9092 0.3751 -0.1808 +vn 0.7708 0.3751 0.5150 +vn -0.7708 0.3751 0.5150 +vn -0.1808 0.3751 -0.9092 +vn 0.9092 0.3751 -0.1808 +vn -0.1808 0.3751 0.9092 +vn -0.7708 0.3751 -0.5150 +vn 0.5150 0.3751 -0.7708 +vn 0.5150 0.3751 0.7708 +vn -0.9092 0.3751 0.1808 +vn 0.9092 0.3751 0.1808 +vn -0.5150 0.3751 0.7708 +vn -0.5555 -0.0107 -0.8314 +vn 0.1758 -0.4340 0.8836 +vn 0.1758 -0.4340 -0.8836 +vn -0.8836 -0.4340 -0.1758 +vn 0.7491 -0.4340 0.5005 +vn -0.7491 -0.4340 0.5005 +vn -0.1758 -0.4340 -0.8836 +vn 0.8836 -0.4340 -0.1758 +vn -0.1758 -0.4340 0.8836 +vn -0.7491 -0.4340 -0.5005 +vn 0.5005 -0.4340 -0.7491 +vn 0.5005 -0.4340 0.7491 +vn -0.8836 -0.4340 0.1758 +vn 0.8836 -0.4340 0.1758 +vn -0.5005 -0.4340 0.7491 +vn -0.5005 -0.4340 -0.7491 +vn -0.0000 1.0000 -0.0000 +vn 0.5555 -0.0107 0.8314 +vn -0.1951 -0.0107 -0.9807 +vn -0.1951 -0.0107 0.9807 +vn 0.1951 -0.0107 0.9807 +vn 0.1951 -0.0107 -0.9807 +vn -0.5555 -0.0107 0.8314 +vn 0.5555 -0.0107 -0.8314 +vn -0.8314 -0.0107 0.5555 +vn 0.8314 -0.0107 -0.5555 +vn -0.9807 -0.0107 0.1951 +vn 0.9807 -0.0107 -0.1951 +vn -0.9807 -0.0107 -0.1951 +vn 0.9807 -0.0107 0.1951 +vn -0.8314 -0.0107 -0.5555 +vn 0.8314 -0.0107 0.5555 +vn -0.0000 -1.0000 -0.0000 +vt 1.000000 0.500000 +vt 1.000000 1.000000 +vt 0.937500 1.000000 +vt 0.937500 0.500000 +vt 0.875000 1.000000 +vt 0.875000 0.500000 +vt 0.812500 1.000000 +vt 0.812500 0.500000 +vt 0.750000 1.000000 +vt 0.750000 0.500000 +vt 0.687500 1.000000 +vt 0.687500 0.500000 +vt 0.625000 1.000000 +vt 0.625000 0.500000 +vt 0.562500 1.000000 +vt 0.562500 0.500000 +vt 0.500000 1.000000 +vt 0.500000 0.500000 +vt 0.437500 1.000000 +vt 0.437500 0.500000 +vt 0.375000 1.000000 +vt 0.375000 0.500000 +vt 0.312500 1.000000 +vt 0.312500 0.500000 +vt 0.250000 1.000000 +vt 0.250000 0.500000 +vt 0.187500 1.000000 +vt 0.187500 0.500000 +vt 0.125000 1.000000 +vt 0.125000 0.500000 +vt 0.062500 1.000000 +vt 0.062500 0.500000 +vt 0.000000 1.000000 +vt 0.000000 0.500000 +vt 0.334000 0.047207 +vt 0.405211 0.094789 +vt 0.709809 0.152971 +vt 0.675737 0.175737 +vt 0.250000 0.469502 +vt 0.334000 0.452793 +vt 0.341844 0.471731 +vt 0.250000 0.490000 +vt 0.405211 0.405211 +vt 0.419706 0.419706 +vt 0.452793 0.334000 +vt 0.471731 0.341844 +vt 0.469502 0.250000 +vt 0.490000 0.250000 +vt 0.452793 0.166000 +vt 0.471731 0.158156 +vt 0.419706 0.080294 +vt 0.341844 0.028269 +vt 0.250000 0.030498 +vt 0.250000 0.010000 +vt 0.166000 0.047207 +vt 0.158156 0.028269 +vt 0.094789 0.094789 +vt 0.080294 0.080294 +vt 0.047207 0.166000 +vt 0.028269 0.158156 +vt 0.030498 0.250000 +vt 0.010000 0.250000 +vt 0.047207 0.334000 +vt 0.028269 0.341844 +vt 0.094789 0.405211 +vt 0.080294 0.419706 +vt 0.166000 0.452793 +vt 0.158156 0.471731 +vt 0.790191 0.347029 +vt 0.750000 0.355023 +vt 0.750000 0.490000 +vt 0.841844 0.471731 +vt 0.824263 0.324263 +vt 0.919706 0.419706 +vt 0.847029 0.290191 +vt 0.971731 0.341844 +vt 0.855023 0.250000 +vt 0.990000 0.250000 +vt 0.847029 0.209809 +vt 0.971731 0.158156 +vt 0.824262 0.175737 +vt 0.919706 0.080294 +vt 0.790191 0.152971 +vt 0.841844 0.028269 +vt 0.750000 0.144977 +vt 0.750000 0.010000 +vt 0.658156 0.028269 +vt 0.580294 0.080294 +vt 0.652971 0.209809 +vt 0.528269 0.158156 +vt 0.644977 0.250000 +vt 0.510000 0.250000 +vt 0.652971 0.290191 +vt 0.528269 0.341844 +vt 0.675737 0.324263 +vt 0.580294 0.419706 +vt 0.709809 0.347029 +vt 0.658156 0.471731 +s 0 +f 1/1/1 2/2/1 4/3/1 3/4/1 +f 3/4/2 4/3/2 6/5/2 5/6/2 +f 5/6/3 6/5/3 8/7/3 7/8/3 +f 7/8/4 8/7/4 10/9/4 9/10/4 +f 9/10/5 10/9/5 12/11/5 11/12/5 +f 11/12/6 12/11/6 14/13/6 13/14/6 +f 13/14/7 14/13/7 16/15/7 15/16/7 +f 15/16/8 16/15/8 18/17/8 17/18/8 +f 17/18/9 18/17/9 20/19/9 19/20/9 +f 19/20/10 20/19/10 22/21/10 21/22/10 +f 21/22/11 22/21/11 24/23/11 23/24/11 +f 23/24/12 24/23/12 26/25/12 25/26/12 +f 25/26/13 26/25/13 28/27/13 27/28/13 +f 27/28/14 28/27/14 30/29/14 29/30/14 +f 32/31/15 30/29/15 47/29/15 48/31/15 +f 29/30/16 30/29/16 32/31/16 31/32/16 +f 31/32/17 32/31/17 2/33/17 1/34/17 +f 5/6/18 7/8/18 68/8/18 67/6/18 +f 45/25/12 44/23/12 140/23/12 141/25/12 +f 8/7/19 6/5/19 35/5/19 36/7/19 +f 18/17/20 16/15/20 40/15/20 41/17/20 +f 4/3/21 2/2/21 34/2/21 33/3/21 +f 28/27/22 26/25/22 45/25/22 46/27/22 +f 14/13/23 12/11/23 38/11/23 39/13/23 +f 24/23/24 22/21/24 43/21/24 44/23/24 +f 2/33/25 32/31/25 48/31/25 34/33/25 +f 10/9/26 8/7/26 36/7/26 37/9/26 +f 20/19/27 18/17/27 41/17/27 42/19/27 +f 30/29/28 28/27/28 46/27/28 47/29/28 +f 6/5/29 4/3/29 33/3/29 35/5/29 +f 16/15/30 14/13/30 39/13/30 40/15/30 +f 26/25/31 24/23/31 44/23/31 45/25/31 +f 12/11/32 10/9/32 37/9/32 38/11/32 +f 22/21/33 20/19/33 42/19/33 43/21/33 +f 56/35/34 55/36/34 151/36/34 152/35/34 +f 38/11/5 37/9/5 133/9/5 134/11/5 +f 46/27/13 45/25/13 141/25/13 142/27/13 +f 39/13/6 38/11/6 134/11/6 135/13/6 +f 47/29/14 46/27/14 142/27/14 143/29/14 +f 40/15/7 39/13/7 135/13/7 136/15/7 +f 48/31/16 47/29/16 143/29/16 144/31/16 +f 41/17/8 40/15/8 136/15/8 137/17/8 +f 33/3/1 34/2/1 130/2/1 129/3/1 +f 34/33/17 48/31/17 144/31/17 130/33/17 +f 42/19/9 41/17/9 137/17/9 138/19/9 +f 35/5/2 33/3/2 129/3/2 131/5/2 +f 43/21/10 42/19/10 138/19/10 139/21/10 +f 36/7/3 35/5/3 131/5/3 132/7/3 +f 44/23/11 43/21/11 139/21/11 140/23/11 +f 37/9/4 36/7/4 132/7/4 133/9/4 +f 71/14/7 72/16/7 88/16/7 87/14/7 +f 15/16/35 17/18/35 73/18/35 72/16/35 +f 1/1/36 3/4/36 66/4/36 65/1/36 +f 25/26/37 27/28/37 78/28/37 77/26/37 +f 11/12/38 13/14/38 71/14/38 70/12/38 +f 21/22/39 23/24/39 76/24/39 75/22/39 +f 31/32/40 1/34/40 65/34/40 80/32/40 +f 7/8/41 9/10/41 69/10/41 68/8/41 +f 17/18/42 19/20/42 74/20/42 73/18/42 +f 27/28/43 29/30/43 79/30/43 78/28/43 +f 3/4/44 5/6/44 67/6/44 66/4/44 +f 13/14/45 15/16/45 72/16/45 71/14/45 +f 23/24/46 25/26/46 77/26/46 76/24/46 +f 9/10/47 11/12/47 70/12/47 69/10/47 +f 19/20/48 21/22/48 75/22/48 74/20/48 +f 29/30/49 31/32/49 80/32/49 79/30/49 +f 92/24/50 93/26/50 109/26/50 108/24/50 +f 79/30/16 80/32/16 96/32/16 95/30/16 +f 72/16/8 73/18/8 89/18/8 88/16/8 +f 65/1/1 66/4/1 82/4/1 81/1/1 +f 80/32/17 65/34/17 81/34/17 96/32/17 +f 73/18/9 74/20/9 90/20/9 89/18/9 +f 66/4/2 67/6/2 83/6/2 82/4/2 +f 74/20/10 75/22/10 91/22/10 90/20/10 +f 67/6/3 68/8/3 84/8/3 83/6/3 +f 75/22/11 76/24/11 92/24/11 91/22/11 +f 68/8/4 69/10/4 85/10/4 84/8/4 +f 76/24/12 77/26/12 93/26/12 92/24/12 +f 69/10/5 70/12/5 86/12/5 85/10/5 +f 77/26/13 78/28/13 94/28/13 93/26/13 +f 70/12/6 71/14/6 87/14/6 86/12/6 +f 78/28/14 79/30/14 95/30/14 94/28/14 +f 106/20/10 107/22/10 171/22/10 170/20/10 +f 85/10/50 86/12/50 102/12/50 101/10/50 +f 93/26/50 94/28/50 110/28/50 109/26/50 +f 86/12/50 87/14/50 103/14/50 102/12/50 +f 94/28/50 95/30/50 111/30/50 110/28/50 +f 87/14/50 88/16/50 104/16/50 103/14/50 +f 95/30/50 96/32/50 112/32/50 111/30/50 +f 88/16/50 89/18/50 105/18/50 104/16/50 +f 81/1/50 82/4/50 98/4/50 97/1/50 +f 96/32/50 81/34/50 97/34/50 112/32/50 +f 89/18/50 90/20/50 106/20/50 105/18/50 +f 82/4/50 83/6/50 99/6/50 98/4/50 +f 90/20/50 91/22/50 107/22/50 106/20/50 +f 83/6/50 84/8/50 100/8/50 99/6/50 +f 91/22/50 92/24/50 108/24/50 107/22/50 +f 84/8/50 85/10/50 101/10/50 100/8/50 +f 122/37/2 123/38/2 187/38/2 186/37/2 +f 99/6/3 100/8/3 164/8/3 163/6/3 +f 107/22/11 108/24/11 172/24/11 171/22/11 +f 100/8/4 101/10/4 165/10/4 164/8/4 +f 108/24/12 109/26/12 173/26/12 172/24/12 +f 101/10/5 102/12/5 166/12/5 165/10/5 +f 109/26/13 110/28/13 174/28/13 173/26/13 +f 102/12/6 103/14/6 167/14/6 166/12/6 +f 110/28/14 111/30/14 175/30/14 174/28/14 +f 103/14/7 104/16/7 168/16/7 167/14/7 +f 111/30/16 112/32/16 176/32/16 175/30/16 +f 104/16/8 105/18/8 169/18/8 168/16/8 +f 97/1/1 98/4/1 162/4/1 161/1/1 +f 112/32/17 97/34/17 161/34/17 176/32/17 +f 105/18/9 106/20/9 170/20/9 169/18/9 +f 98/4/2 99/6/2 163/6/2 162/4/2 +f 50/39/50 49/40/50 129/41/50 130/42/50 +f 49/40/50 51/43/50 131/44/50 129/41/50 +f 51/43/50 52/45/50 132/46/50 131/44/50 +f 52/45/50 53/47/50 133/48/50 132/46/50 +f 53/47/50 54/49/50 134/50/50 133/48/50 +f 54/49/50 55/36/50 135/51/50 134/50/50 +f 55/36/50 56/35/50 136/52/50 135/51/50 +f 56/35/50 57/53/50 137/54/50 136/52/50 +f 57/53/50 58/55/50 138/56/50 137/54/50 +f 58/55/50 59/57/50 139/58/50 138/56/50 +f 59/57/50 60/59/50 140/60/50 139/58/50 +f 60/59/50 61/61/50 141/62/50 140/60/50 +f 61/61/50 62/63/50 142/64/50 141/62/50 +f 62/63/50 63/65/50 143/66/50 142/64/50 +f 63/65/50 64/67/50 144/68/50 143/66/50 +f 64/67/50 50/39/50 130/42/50 144/68/50 +f 145/40/50 146/39/50 160/67/50 159/65/50 158/63/50 157/61/50 156/59/50 155/57/50 154/55/50 153/53/50 152/35/50 151/36/50 150/49/50 149/47/50 148/45/50 147/43/50 +f 64/67/51 63/65/51 159/65/51 160/67/51 +f 57/53/52 56/35/52 152/35/52 153/53/52 +f 49/40/53 50/39/53 146/39/53 145/40/53 +f 50/39/54 64/67/54 160/67/54 146/39/54 +f 58/55/55 57/53/55 153/53/55 154/55/55 +f 51/43/56 49/40/56 145/40/56 147/43/56 +f 59/57/57 58/55/57 154/55/57 155/57/57 +f 52/45/58 51/43/58 147/43/58 148/45/58 +f 60/59/59 59/57/59 155/57/59 156/59/59 +f 53/47/60 52/45/60 148/45/60 149/47/60 +f 61/61/61 60/59/61 156/59/61 157/61/61 +f 54/49/62 53/47/62 149/47/62 150/49/62 +f 62/63/63 61/61/63 157/61/63 158/63/63 +f 55/36/64 54/49/64 150/49/64 151/36/64 +f 63/65/65 62/63/65 158/63/65 159/65/65 +f 114/69/66 113/70/66 161/71/66 162/72/66 +f 115/73/66 114/69/66 162/72/66 163/74/66 +f 116/75/66 115/73/66 163/74/66 164/76/66 +f 117/77/66 116/75/66 164/76/66 165/78/66 +f 118/79/66 117/77/66 165/78/66 166/80/66 +f 119/81/66 118/79/66 166/80/66 167/82/66 +f 120/83/66 119/81/66 167/82/66 168/84/66 +f 121/85/66 120/83/66 168/84/66 169/86/66 +f 122/37/66 121/85/66 169/86/66 170/87/66 +f 123/38/66 122/37/66 170/87/66 171/88/66 +f 124/89/66 123/38/66 171/88/66 172/90/66 +f 125/91/66 124/89/66 172/90/66 173/92/66 +f 126/93/66 125/91/66 173/92/66 174/94/66 +f 127/95/66 126/93/66 174/94/66 175/96/66 +f 128/97/66 127/95/66 175/96/66 176/98/66 +f 113/70/66 128/97/66 176/98/66 161/71/66 +f 177/70/66 178/69/66 179/73/66 180/75/66 181/77/66 182/79/66 183/81/66 184/83/66 185/85/66 186/37/66 187/38/66 188/89/66 189/91/66 190/93/66 191/95/66 192/97/66 +f 115/73/11 116/75/11 180/75/11 179/73/11 +f 123/38/3 124/89/3 188/89/3 187/38/3 +f 116/75/12 117/77/12 181/77/12 180/75/12 +f 124/89/4 125/91/4 189/91/4 188/89/4 +f 117/77/13 118/79/13 182/79/13 181/77/13 +f 125/91/5 126/93/5 190/93/5 189/91/5 +f 118/79/14 119/81/14 183/81/14 182/79/14 +f 126/93/6 127/95/6 191/95/6 190/93/6 +f 119/81/16 120/83/16 184/83/16 183/81/16 +f 127/95/7 128/97/7 192/97/7 191/95/7 +f 120/83/17 121/85/17 185/85/17 184/83/17 +f 113/70/9 114/69/9 178/69/9 177/70/9 +f 128/97/8 113/70/8 177/70/8 192/97/8 +f 121/85/1 122/37/1 186/37/1 185/85/1 +f 114/69/10 115/73/10 179/73/10 178/69/10 +o Cylinder.001 +v -0.000000 2.336913 -0.171348 +v -0.000000 2.781507 -0.171348 +v 0.065572 2.336913 -0.158305 +v 0.065572 2.781507 -0.158305 +v 0.121162 2.336913 -0.121162 +v 0.121162 2.781507 -0.121162 +v 0.158305 2.336913 -0.065572 +v 0.158305 2.781507 -0.065572 +v 0.171348 2.336913 0.000000 +v 0.171348 2.781507 0.000000 +v 0.158305 2.336913 0.065572 +v 0.158305 2.781507 0.065572 +v 0.121162 2.336913 0.121162 +v 0.121162 2.781507 0.121162 +v 0.065572 2.336913 0.158305 +v 0.065572 2.781507 0.158305 +v -0.000000 2.336913 0.171348 +v -0.000000 2.781507 0.171348 +v -0.065572 2.336913 0.158305 +v -0.065572 2.781507 0.158305 +v -0.121162 2.336913 0.121162 +v -0.121162 2.781507 0.121162 +v -0.158305 2.336913 0.065572 +v -0.158305 2.781507 0.065572 +v -0.171348 2.336913 0.000000 +v -0.171348 2.781507 0.000000 +v -0.158305 2.336913 -0.065572 +v -0.158305 2.781507 -0.065572 +v -0.121162 2.336913 -0.121162 +v -0.121162 2.781507 -0.121162 +v -0.065572 2.336913 -0.158305 +v -0.065572 2.781507 -0.158305 +v 0.000000 2.206204 -0.142372 +v 0.054484 2.206204 -0.131535 +v 0.100672 2.206204 -0.100672 +v 0.131535 2.206204 -0.054484 +v 0.142372 2.206204 0.000000 +v 0.131535 2.206204 0.054484 +v 0.100672 2.206204 0.100672 +v 0.054484 2.206204 0.131535 +v 0.000000 2.206204 0.142372 +v -0.054484 2.206204 0.131535 +v -0.100672 2.206204 0.100672 +v -0.131535 2.206204 0.054484 +v -0.142372 2.206204 0.000000 +v -0.131535 2.206204 -0.054484 +v -0.100672 2.206204 -0.100672 +v -0.054484 2.206204 -0.131535 +v -0.000000 3.048973 -0.122817 +v 0.047000 3.048973 -0.113468 +v 0.086845 3.048973 -0.086845 +v 0.113468 3.048973 -0.047000 +v 0.122817 3.048973 0.000000 +v 0.113468 3.048973 0.047000 +v 0.086845 3.048973 0.086845 +v 0.047000 3.048973 0.113468 +v -0.000000 3.048973 0.122817 +v -0.047000 3.048973 0.113468 +v -0.086845 3.048973 0.086845 +v -0.113468 3.048973 0.047000 +v -0.122817 3.048973 0.000000 +v -0.113468 3.048973 -0.047000 +v -0.086845 3.048973 -0.086845 +v -0.047000 3.048973 -0.113468 +v -0.000000 3.227060 0.000000 +vn 0.1951 -0.0000 -0.9808 +vn 0.5556 -0.0000 -0.8315 +vn 0.8315 -0.0000 -0.5556 +vn 0.9808 -0.0000 -0.1951 +vn 0.9808 -0.0000 0.1951 +vn 0.8315 -0.0000 0.5556 +vn 0.5556 -0.0000 0.8315 +vn 0.1951 -0.0000 0.9808 +vn -0.1951 -0.0000 0.9808 +vn -0.5556 -0.0000 0.8315 +vn -0.8315 -0.0000 0.5556 +vn -0.9808 -0.0000 0.1951 +vn -0.9808 -0.0000 -0.1951 +vn -0.8315 -0.0000 -0.5556 +vn 0.5470 0.1752 -0.8186 +vn -0.5556 -0.0000 -0.8315 +vn -0.1951 -0.0000 -0.9808 +vn 0.9584 -0.2125 0.1906 +vn -0.0000 -1.0000 -0.0000 +vn -0.5429 -0.2125 0.8125 +vn -0.5429 -0.2125 -0.8125 +vn 0.8125 -0.2125 -0.5429 +vn 0.1906 -0.2125 0.9584 +vn 0.1906 -0.2125 -0.9584 +vn -0.9584 -0.2125 -0.1906 +vn 0.8125 -0.2125 0.5429 +vn -0.8125 -0.2125 0.5429 +vn -0.1906 -0.2125 -0.9584 +vn 0.9584 -0.2125 -0.1906 +vn -0.1906 -0.2125 0.9584 +vn -0.8125 -0.2125 -0.5429 +vn 0.5429 -0.2125 -0.8125 +vn 0.5429 -0.2125 0.8125 +vn -0.9584 -0.2125 0.1906 +vn 0.4602 0.5603 0.6887 +vn 0.5470 0.1752 0.8186 +vn -0.9656 0.1752 0.1921 +vn 0.9656 0.1752 0.1921 +vn -0.5470 0.1752 0.8186 +vn -0.5470 0.1752 -0.8186 +vn 0.8186 0.1752 -0.5470 +vn 0.1921 0.1752 0.9656 +vn 0.1921 0.1752 -0.9656 +vn -0.9656 0.1752 -0.1921 +vn 0.8186 0.1752 0.5470 +vn -0.8186 0.1752 0.5470 +vn -0.1921 0.1752 -0.9656 +vn 0.9656 0.1752 -0.1921 +vn -0.1921 0.1752 0.9656 +vn -0.8186 0.1752 -0.5470 +vn -0.4602 0.5603 -0.6887 +vn 0.1616 0.5603 0.8124 +vn 0.1616 0.5603 -0.8124 +vn -0.1616 0.5603 -0.8124 +vn -0.1616 0.5603 0.8124 +vn 0.4602 0.5603 -0.6887 +vn -0.4602 0.5603 0.6887 +vn 0.6887 0.5603 -0.4602 +vn -0.6887 0.5603 0.4602 +vn 0.8124 0.5603 -0.1616 +vn -0.8124 0.5603 0.1616 +vn 0.8124 0.5603 0.1616 +vn -0.8124 0.5603 -0.1616 +vn 0.6887 0.5603 0.4602 +vn -0.6887 0.5603 -0.4602 +vt 1.000000 0.500000 +vt 1.000000 1.000000 +vt 0.937500 1.000000 +vt 0.937500 0.500000 +vt 0.875000 1.000000 +vt 0.875000 0.500000 +vt 0.812500 1.000000 +vt 0.812500 0.500000 +vt 0.750000 1.000000 +vt 0.750000 0.500000 +vt 0.687500 1.000000 +vt 0.687500 0.500000 +vt 0.625000 1.000000 +vt 0.625000 0.500000 +vt 0.562500 1.000000 +vt 0.562500 0.500000 +vt 0.500000 1.000000 +vt 0.500000 0.500000 +vt 0.437500 1.000000 +vt 0.437500 0.500000 +vt 0.375000 1.000000 +vt 0.375000 0.500000 +vt 0.312500 1.000000 +vt 0.312500 0.500000 +vt 0.250000 1.000000 +vt 0.250000 0.500000 +vt 0.187500 1.000000 +vt 0.187500 0.500000 +vt 0.125000 1.000000 +vt 0.125000 0.500000 +vt 0.062500 1.000000 +vt 0.062500 0.500000 +vt 0.000000 1.000000 +vt 0.000000 0.500000 +vt 0.750000 0.490000 +vt 0.841844 0.471731 +vt 0.919706 0.419706 +vt 0.971731 0.341844 +vt 0.990000 0.250000 +vt 0.971731 0.158156 +vt 0.919706 0.080294 +vt 0.841844 0.028269 +vt 0.750000 0.010000 +vt 0.658156 0.028269 +vt 0.580294 0.080294 +vt 0.528269 0.158156 +vt 0.510000 0.250000 +vt 0.528269 0.341844 +vt 0.580294 0.419706 +vt 0.658156 0.471731 +s 0 +f 193/99/67 194/100/67 196/101/67 195/102/67 +f 195/102/68 196/101/68 198/103/68 197/104/68 +f 197/104/69 198/103/69 200/105/69 199/106/69 +f 199/106/70 200/105/70 202/107/70 201/108/70 +f 201/108/71 202/107/71 204/109/71 203/110/71 +f 203/110/72 204/109/72 206/111/72 205/112/72 +f 205/112/73 206/111/73 208/113/73 207/114/73 +f 207/114/74 208/113/74 210/115/74 209/116/74 +f 209/116/75 210/115/75 212/117/75 211/118/75 +f 211/118/76 212/117/76 214/119/76 213/120/76 +f 213/120/77 214/119/77 216/121/77 215/122/77 +f 215/122/78 216/121/78 218/123/78 217/124/78 +f 217/124/79 218/123/79 220/125/79 219/126/79 +f 219/126/80 220/125/80 222/127/80 221/128/80 +f 198/103/81 196/101/81 242/101/81 243/103/81 +f 221/128/82 222/127/82 224/129/82 223/130/82 +f 223/130/83 224/129/83 194/131/83 193/132/83 +f 201/108/84 203/110/84 230/110/84 229/108/84 +f 225/133/85 226/134/85 227/135/85 228/136/85 229/137/85 230/138/85 231/139/85 232/140/85 233/141/85 234/142/85 235/143/85 236/144/85 237/145/85 238/146/85 239/147/85 240/148/85 +f 211/118/86 213/120/86 235/120/86 234/118/86 +f 221/128/87 223/130/87 240/130/87 239/128/87 +f 197/104/88 199/106/88 228/106/88 227/104/88 +f 207/114/89 209/116/89 233/116/89 232/114/89 +f 193/99/90 195/102/90 226/102/90 225/99/90 +f 217/124/91 219/126/91 238/126/91 237/124/91 +f 203/110/92 205/112/92 231/112/92 230/110/92 +f 213/120/93 215/122/93 236/122/93 235/120/93 +f 223/130/94 193/132/94 225/132/94 240/130/94 +f 199/106/95 201/108/95 229/108/95 228/106/95 +f 209/116/96 211/118/96 234/118/96 233/116/96 +f 219/126/97 221/128/97 239/128/97 238/126/97 +f 195/102/98 197/104/98 227/104/98 226/102/98 +f 205/112/99 207/114/99 232/114/99 231/112/99 +f 215/122/100 217/124/100 237/124/100 236/122/100 +f 248/113/101 247/111/101 257/113/101 +f 208/113/102 206/111/102 247/111/102 248/113/102 +f 218/123/103 216/121/103 252/121/103 253/123/103 +f 204/109/104 202/107/104 245/107/104 246/109/104 +f 214/119/105 212/117/105 250/117/105 251/119/105 +f 224/129/106 222/127/106 255/127/106 256/129/106 +f 200/105/107 198/103/107 243/103/107 244/105/107 +f 210/115/108 208/113/108 248/113/108 249/115/108 +f 196/101/109 194/100/109 241/100/109 242/101/109 +f 220/125/110 218/123/110 253/123/110 254/125/110 +f 206/111/111 204/109/111 246/109/111 247/111/111 +f 216/121/112 214/119/112 251/119/112 252/121/112 +f 194/131/113 224/129/113 256/129/113 241/131/113 +f 202/107/114 200/105/114 244/105/114 245/107/114 +f 212/117/115 210/115/115 249/115/115 250/117/115 +f 222/127/116 220/125/116 254/125/116 255/127/116 +f 256/129/117 255/127/117 257/129/117 +f 249/115/118 248/113/118 257/115/118 +f 242/101/119 241/100/119 257/101/119 +f 241/131/120 256/129/120 257/131/120 +f 250/117/121 249/115/121 257/117/121 +f 243/103/122 242/101/122 257/103/122 +f 251/119/123 250/117/123 257/119/123 +f 244/105/124 243/103/124 257/105/124 +f 252/121/125 251/119/125 257/121/125 +f 245/107/126 244/105/126 257/107/126 +f 253/123/127 252/121/127 257/123/127 +f 246/109/128 245/107/128 257/109/128 +f 254/125/129 253/123/129 257/125/129 +f 247/111/130 246/109/130 257/111/130 +f 255/127/131 254/125/131 257/127/131 diff --git a/assets/c1.png b/assets/c1.png new file mode 100644 index 0000000..bb03f1c Binary files /dev/null and b/assets/c1.png differ diff --git a/assets/fs.wav b/assets/fs.wav new file mode 100644 index 0000000..afd40c6 Binary files /dev/null and b/assets/fs.wav differ diff --git a/assets/ft/arial.ttf b/assets/ft/arial.ttf new file mode 100644 index 0000000..810df57 Binary files /dev/null and b/assets/ft/arial.ttf differ diff --git a/assets/itsmagicbitch.jpg b/assets/itsmagicbitch.jpg new file mode 100644 index 0000000..00b5892 Binary files /dev/null and b/assets/itsmagicbitch.jpg differ diff --git a/assets/leonrevolver.obj b/assets/leonrevolver.obj new file mode 100644 index 0000000..df9993e --- /dev/null +++ b/assets/leonrevolver.obj @@ -0,0 +1,5606 @@ +# Blender 4.4.0 +# www.blender.org +mtllib leonrevolver.mtl +o Cube +v 0.139900 -0.118258 0.021770 +v 0.143794 -0.042260 0.019362 +v 0.192419 -0.118952 0.021415 +v 0.188323 -0.048532 0.020630 +v 0.123794 -0.018785 0.011689 +v 0.183807 -0.007234 0.009619 +v 0.125913 -0.023983 0.013918 +v 0.173645 -0.022859 0.016366 +v 0.149049 -0.100018 0.022217 +v 0.151891 -0.082679 0.021331 +v 0.149139 -0.064102 0.019454 +v 0.190674 -0.065233 0.021626 +v 0.192186 -0.083158 0.021215 +v 0.192359 -0.101070 0.021386 +v 0.139825 -0.118444 0.001676 +v 0.210447 -0.119031 0.000008 +v 0.202689 -0.049214 0.000008 +v 0.195765 -0.001247 0.000008 +v 0.179792 -0.024053 0.000008 +v 0.212938 -0.101169 0.000008 +v 0.215044 -0.083276 0.000008 +v 0.207230 -0.065325 0.000008 +v 0.143600 -0.100092 0.002470 +v 0.139861 -0.082775 0.002911 +v 0.138451 -0.063525 0.001606 +v 0.137617 -0.118240 0.015588 +v 0.200031 -0.049520 0.013337 +v 0.196453 -0.001545 0.006516 +v 0.182221 -0.024219 0.009589 +v 0.208996 -0.101120 0.010712 +v 0.208741 -0.083214 0.010747 +v 0.203173 -0.065265 0.012401 +v 0.139309 -0.041790 0.012742 +v 0.207297 -0.118992 0.010712 +v 0.122264 -0.019261 0.006159 +v 0.124371 -0.024179 0.007746 +v 0.145405 -0.099793 0.016169 +v 0.144087 -0.082594 0.016621 +v 0.142990 -0.063696 0.014693 +v 0.149484 -0.053223 0.017908 +v 0.189086 -0.056543 0.021284 +v 0.203424 -0.056608 0.000008 +v 0.141603 -0.052495 0.000008 +v 0.143451 -0.052280 0.013079 +v 0.200550 -0.056716 0.013067 +v 0.154505 -0.091421 0.021199 +v 0.192267 -0.092114 0.021284 +v 0.143810 -0.091279 0.002527 +v 0.214645 -0.092221 0.000008 +v 0.147130 -0.091138 0.016157 +v 0.209473 -0.092168 0.010712 +v 0.171926 -0.118676 0.020044 +v 0.172237 -0.048646 0.017017 +v 0.143400 -0.013736 0.011539 +v 0.143547 -0.023161 0.014443 +v 0.175291 -0.100653 0.017901 +v 0.175773 -0.082916 0.016207 +v 0.174831 -0.065405 0.016884 +v 0.180658 -0.118902 0.000008 +v 0.141370 -0.012555 0.006210 +v 0.174466 -0.118737 0.011560 +v 0.174803 -0.056934 0.017114 +v 0.176421 -0.091766 0.016824 +v 0.133067 -0.033116 0.018654 +v 0.181819 -0.034877 0.018254 +v 0.192825 -0.035904 0.000008 +v 0.191893 -0.036225 0.011230 +v 0.130462 -0.032952 0.011919 +v 0.158146 -0.035637 0.013249 +v 0.124774 -0.021385 0.012784 +v 0.179322 -0.015819 0.012958 +v 0.187739 -0.016893 0.000008 +v 0.189764 -0.016882 0.009437 +v 0.123301 -0.021725 0.006930 +v 0.143211 -0.018572 0.012953 +v 0.139949 -0.118470 0.000008 +v 0.139622 -0.041398 0.000008 +v 0.120589 -0.020440 0.000008 +v 0.126299 -0.024890 0.000008 +v 0.143972 -0.100125 0.000008 +v 0.140408 -0.082818 0.000008 +v 0.138629 -0.063472 0.000008 +v 0.140289 -0.044695 0.000008 +v 0.141894 -0.052425 0.000008 +v 0.144213 -0.091321 0.000008 +v 0.139984 -0.011290 0.000008 +v 0.132669 -0.033177 0.000008 +v 0.122080 -0.022675 0.000008 +v 0.182173 -0.118814 0.020729 +v 0.163380 -0.009523 0.005730 +v 0.180280 -0.048589 0.018823 +v 0.160693 -0.010063 0.010687 +v 0.158179 -0.023827 0.015445 +v 0.183825 -0.100862 0.019644 +v 0.183980 -0.083037 0.018711 +v 0.182753 -0.065319 0.019255 +v 0.195553 -0.118967 0.000008 +v 0.190881 -0.118864 0.011136 +v 0.181944 -0.056738 0.019199 +v 0.184344 -0.091940 0.019054 +v 0.169747 -0.035131 0.015765 +v 0.159433 -0.017426 0.013031 +v 0.161553 -0.007796 0.000008 +v 0.139900 -0.118258 -0.021755 +v 0.143794 -0.042260 -0.019347 +v 0.192419 -0.118952 -0.021399 +v 0.188323 -0.048532 -0.020614 +v 0.123794 -0.018785 -0.011673 +v 0.183807 -0.007234 -0.009603 +v 0.125913 -0.023983 -0.013902 +v 0.173645 -0.022859 -0.016350 +v 0.149049 -0.100018 -0.022201 +v 0.151891 -0.082679 -0.021316 +v 0.149139 -0.064102 -0.019439 +v 0.190674 -0.065233 -0.021610 +v 0.192186 -0.083158 -0.021200 +v 0.192359 -0.101070 -0.021370 +v 0.139825 -0.118444 -0.001660 +v 0.143600 -0.100092 -0.002455 +v 0.139861 -0.082775 -0.002895 +v 0.138451 -0.063525 -0.001591 +v 0.137617 -0.118240 -0.015573 +v 0.200031 -0.049520 -0.013321 +v 0.196453 -0.001545 -0.006500 +v 0.182221 -0.024219 -0.009574 +v 0.208996 -0.101120 -0.010696 +v 0.208741 -0.083214 -0.010731 +v 0.203173 -0.065265 -0.012385 +v 0.139309 -0.041790 -0.012726 +v 0.207297 -0.118992 -0.010696 +v 0.122264 -0.019261 -0.006143 +v 0.124371 -0.024179 -0.007730 +v 0.145405 -0.099793 -0.016154 +v 0.144087 -0.082594 -0.016605 +v 0.142990 -0.063696 -0.014677 +v 0.149484 -0.053223 -0.017892 +v 0.189086 -0.056543 -0.021268 +v 0.143451 -0.052280 -0.013063 +v 0.200550 -0.056716 -0.013052 +v 0.154505 -0.091421 -0.021183 +v 0.192267 -0.092114 -0.021268 +v 0.143810 -0.091279 -0.002511 +v 0.147130 -0.091138 -0.016141 +v 0.209473 -0.092168 -0.010696 +v 0.171926 -0.118676 -0.020028 +v 0.172237 -0.048646 -0.017001 +v 0.143400 -0.013736 -0.011524 +v 0.143547 -0.023161 -0.014427 +v 0.175291 -0.100653 -0.017885 +v 0.175773 -0.082916 -0.016192 +v 0.174831 -0.065405 -0.016869 +v 0.141370 -0.012555 -0.006194 +v 0.174466 -0.118737 -0.011544 +v 0.174803 -0.056934 -0.017098 +v 0.176421 -0.091766 -0.016808 +v 0.133067 -0.033116 -0.018638 +v 0.181819 -0.034877 -0.018238 +v 0.191893 -0.036225 -0.011215 +v 0.130462 -0.032952 -0.011903 +v 0.158146 -0.035637 -0.013234 +v 0.124774 -0.021385 -0.012768 +v 0.179322 -0.015819 -0.012943 +v 0.189764 -0.016882 -0.009421 +v 0.123301 -0.021725 -0.006914 +v 0.143211 -0.018572 -0.012938 +v 0.182173 -0.118814 -0.020714 +v 0.163380 -0.009523 -0.005714 +v 0.180280 -0.048589 -0.018807 +v 0.160693 -0.010063 -0.010671 +v 0.158179 -0.023827 -0.015429 +v 0.183825 -0.100862 -0.019628 +v 0.183980 -0.083037 -0.018696 +v 0.182753 -0.065319 -0.019239 +v 0.190881 -0.118864 -0.011120 +v 0.181944 -0.056738 -0.019183 +v 0.184344 -0.091940 -0.019038 +v 0.169747 -0.035131 -0.015749 +v 0.159433 -0.017426 -0.013016 +v 0.020081 -0.009461 0.010273 +v -0.152620 -0.009461 0.010273 +v 0.020081 -0.009461 0.000008 +v 0.020081 0.031701 0.000008 +v -0.176539 0.031701 0.000008 +v -0.152620 -0.009461 0.000008 +v -0.179147 0.031701 0.011803 +v -0.155228 -0.009461 0.011803 +v 0.020081 0.031701 0.007321 +v 0.020081 0.026353 0.010273 +v -0.173432 0.026353 0.010273 +v -0.176539 0.031701 0.007321 +v -0.181887 0.031701 0.010273 +v -0.179143 0.031701 0.011801 +v 0.020081 -0.009461 -0.010462 +v -0.152620 -0.009461 -0.010462 +v -0.179147 0.031701 -0.011993 +v -0.155228 -0.009461 -0.011993 +v 0.020081 0.031701 -0.007511 +v 0.020081 0.026353 -0.010462 +v -0.173432 0.026353 -0.010462 +v -0.176539 0.031701 -0.007511 +v -0.181887 0.031701 -0.010462 +v -0.179143 0.031701 -0.011990 +v -0.035607 -0.009461 0.010273 +v -0.035607 -0.009461 0.000008 +v -0.043320 0.031701 0.007321 +v -0.042318 0.026353 0.010273 +v -0.035607 -0.009461 -0.010462 +v -0.043320 0.031701 -0.007511 +v -0.042318 0.026353 -0.010462 +v -0.021728 -0.009461 0.010273 +v -0.026767 0.026353 0.010273 +v -0.021728 -0.009461 -0.010462 +v -0.026767 0.026353 -0.010462 +v -0.021728 -0.009461 0.000008 +v -0.027519 0.031701 0.007321 +v -0.027519 0.031701 -0.007511 +v -0.205808 -0.008602 0.010273 +v -0.204949 -0.009461 0.010273 +v -0.205808 0.030841 0.010273 +v -0.204949 0.031701 0.010273 +v -0.205808 -0.008602 0.000008 +v -0.204949 -0.009461 0.000008 +v -0.205808 0.030841 0.000008 +v -0.204949 0.031701 0.000008 +v -0.205808 -0.008602 0.011329 +v -0.204949 -0.009461 0.011803 +v -0.205808 0.030841 0.011329 +v -0.204949 0.031701 0.011803 +v -0.205808 -0.008602 -0.010462 +v -0.204949 -0.009461 -0.010462 +v -0.204949 0.031701 -0.010462 +v -0.205808 0.030841 -0.010462 +v -0.205808 -0.008602 -0.011518 +v -0.204949 -0.009461 -0.011993 +v -0.205808 0.030841 -0.011518 +v -0.204949 0.031701 -0.011993 +v 0.150405 -0.019900 0.011237 +v 0.136851 0.053452 0.006379 +v 0.018282 -0.004658 0.011237 +v 0.150405 -0.004496 0.011237 +v 0.018282 0.049166 0.006379 +v 0.136851 0.049166 0.006379 +v 0.030613 0.053452 0.006379 +v 0.030613 -0.004658 0.011237 +v 0.030613 0.049166 0.006379 +v 0.119458 0.053452 0.006379 +v 0.119458 -0.004658 0.011237 +v 0.119458 0.049166 0.006379 +v 0.136851 0.034941 0.007998 +v 0.150697 0.012664 0.009617 +v 0.119458 0.034941 0.007998 +v 0.119458 0.013283 0.009617 +v 0.018282 -0.022292 0.000008 +v 0.150405 -0.019900 0.000008 +v 0.136851 0.053452 0.000008 +v 0.018282 -0.004658 0.000008 +v 0.136851 0.049166 0.000008 +v 0.018282 0.049166 0.000008 +v 0.030613 0.053452 0.000008 +v 0.119458 0.053452 0.000008 +v 0.119458 -0.022292 0.000008 +v 0.030613 -0.004658 0.000008 +v 0.030613 0.049166 0.000008 +v 0.119458 0.049166 0.000008 +v 0.119458 -0.004658 0.000008 +v 0.119458 0.034941 0.000008 +v 0.119458 0.013283 0.000008 +v 0.150697 0.012974 0.000008 +v 0.136851 0.034941 0.000008 +v 0.150697 0.012664 0.012189 +v 0.150405 -0.004496 0.013808 +v 0.119458 -0.004658 0.013808 +v 0.119458 0.013283 0.012189 +v 0.136851 0.034941 0.010569 +v 0.119458 0.034941 0.010569 +v 0.180565 -0.002142 0.011214 +v 0.178227 -0.013162 0.011214 +v 0.176474 0.004497 0.009594 +v 0.180273 0.000553 0.000008 +v 0.176474 0.004806 0.000008 +v 0.178227 -0.013162 0.000008 +v 0.195400 -0.001154 0.008179 +v 0.195400 -0.001154 0.000008 +v 0.144144 0.022692 0.007025 +v 0.119458 0.024112 0.008808 +v 0.143774 0.023957 0.000008 +v 0.119458 0.024112 0.000008 +v 0.143774 0.023803 0.011379 +v 0.119458 0.024112 0.011379 +v 0.148284 0.016031 0.007509 +v 0.119458 0.017637 0.009292 +v 0.147913 0.017390 0.000008 +v 0.147913 0.017142 0.011863 +v 0.119458 0.017637 0.011863 +v 0.119458 0.017637 0.000008 +v 0.159770 0.034336 0.000008 +v 0.160140 0.034336 0.002814 +v 0.158107 0.034336 0.002814 +v 0.157855 0.034336 0.000008 +v 0.154349 0.032997 0.004218 +v 0.150297 0.030437 0.005621 +v 0.151783 0.026180 0.000008 +v 0.155206 0.031110 0.000008 +v 0.154967 0.030547 0.004379 +v 0.151533 0.025536 0.005944 +v 0.154259 0.034210 0.000008 +v 0.150214 0.031701 0.000008 +v 0.023368 0.053452 0.006379 +v 0.023368 0.053452 0.000008 +v 0.018282 -0.022292 0.006819 +v 0.018282 -0.017874 0.011237 +v 0.119458 -0.017874 0.011237 +v 0.119458 -0.022292 0.006819 +v 0.123876 -0.019900 0.011237 +v 0.030613 -0.004658 0.013326 +v 0.018282 -0.004658 0.013326 +v 0.018282 0.040268 0.007182 +v 0.030613 0.040268 0.007182 +v 0.030613 0.040268 0.000008 +v 0.018282 0.040268 0.000008 +v 0.137229 -0.041002 0.009470 +v 0.137229 -0.041002 0.000008 +v 0.122667 -0.023098 0.000008 +v 0.122667 -0.023098 0.006504 +v 0.124450 -0.025467 0.009470 +v 0.137140 -0.019900 0.011237 +v 0.128665 -0.031495 0.009470 +v 0.127773 -0.030310 0.000008 +v 0.030613 0.040268 0.008154 +v 0.030613 0.039156 0.009371 +v 0.018282 0.039156 0.009371 +v 0.018282 0.040268 0.008154 +v 0.012531 -0.004658 0.011237 +v 0.012531 -0.004658 0.000008 +v 0.012531 -0.022292 0.000008 +v 0.012531 -0.017874 0.011237 +v 0.012531 -0.022292 0.006819 +v 0.150405 -0.019900 -0.011221 +v 0.136851 0.053452 -0.006363 +v 0.018282 -0.004658 -0.011221 +v 0.150405 -0.004496 -0.011221 +v 0.018282 0.049166 -0.006363 +v 0.136851 0.049166 -0.006363 +v 0.030613 0.053452 -0.006363 +v 0.030613 -0.004658 -0.011221 +v 0.030613 0.049166 -0.006363 +v 0.119458 0.053452 -0.006363 +v 0.119458 -0.004658 -0.011221 +v 0.119458 0.049166 -0.006363 +v 0.136851 0.034941 -0.007982 +v 0.150697 0.012664 -0.009602 +v 0.119458 0.034941 -0.007982 +v 0.119458 0.013283 -0.009602 +v 0.150697 0.012664 -0.012173 +v 0.150405 -0.004496 -0.013792 +v 0.119458 -0.004658 -0.013792 +v 0.119458 0.013283 -0.012173 +v 0.136851 0.034941 -0.010553 +v 0.119458 0.034941 -0.010553 +v 0.180565 -0.002142 -0.011198 +v 0.178227 -0.013162 -0.011198 +v 0.176474 0.004497 -0.009578 +v 0.195400 -0.001154 -0.008163 +v 0.144144 0.022692 -0.007009 +v 0.119458 0.024112 -0.008792 +v 0.143774 0.023803 -0.011363 +v 0.119458 0.024112 -0.011363 +v 0.148284 0.016031 -0.007493 +v 0.119458 0.017637 -0.009276 +v 0.147913 0.017142 -0.011847 +v 0.119458 0.017637 -0.011847 +v 0.160140 0.034336 -0.002799 +v 0.158107 0.034336 -0.002799 +v 0.154349 0.032997 -0.004202 +v 0.150297 0.030437 -0.005606 +v 0.154967 0.030547 -0.004364 +v 0.151533 0.025536 -0.005928 +v 0.023368 0.053452 -0.006363 +v 0.018282 -0.022292 -0.006803 +v 0.018282 -0.017874 -0.011221 +v 0.119458 -0.017874 -0.011221 +v 0.119458 -0.022292 -0.006803 +v 0.123876 -0.019900 -0.011221 +v 0.030613 -0.004658 -0.013310 +v 0.018282 -0.004658 -0.013310 +v 0.018282 0.040268 -0.007166 +v 0.030613 0.040268 -0.007166 +v 0.137229 -0.041002 -0.009454 +v 0.122667 -0.023098 -0.006489 +v 0.124450 -0.025467 -0.009454 +v 0.137140 -0.019900 -0.011221 +v 0.128665 -0.031495 -0.009454 +v 0.030613 0.040268 -0.008138 +v 0.030613 0.039156 -0.009355 +v 0.018282 0.039156 -0.009355 +v 0.018282 0.040268 -0.008138 +v 0.012531 -0.004658 -0.011221 +v 0.012531 -0.017874 -0.011221 +v 0.012531 -0.022292 -0.006803 +v 0.120250 0.019273 -0.028287 +v 0.120250 0.043777 -0.014140 +v 0.120250 0.043777 0.014155 +v 0.120250 0.019273 0.028303 +v 0.120250 -0.005232 0.014155 +v 0.120250 -0.005232 -0.014140 +v 0.031085 0.033393 -0.016296 +v 0.031085 0.026333 -0.020372 +v 0.031085 0.040453 0.004084 +v 0.031085 0.040453 -0.004068 +v 0.031085 0.026333 0.020388 +v 0.031085 0.033393 0.016312 +v 0.031085 0.005153 0.016312 +v 0.031085 0.012213 0.020388 +v 0.031085 -0.001907 -0.004068 +v 0.031085 -0.001907 0.004084 +v 0.031085 0.012213 -0.020372 +v 0.031085 0.005153 -0.016296 +v 0.120250 0.035609 -0.018856 +v 0.120250 0.027441 -0.023571 +v 0.120250 0.043777 0.004724 +v 0.120250 0.043777 -0.004708 +v 0.120250 0.027441 0.023587 +v 0.120250 0.035609 0.018871 +v 0.120250 0.002936 0.018871 +v 0.120250 0.011105 0.023587 +v 0.120250 -0.005232 -0.004708 +v 0.120250 -0.005232 0.004724 +v 0.120250 0.011105 -0.023571 +v 0.120250 0.002936 -0.018856 +v 0.105661 0.006365 0.014912 +v 0.105661 0.012819 0.018638 +v 0.105661 0.012819 -0.018622 +v 0.105661 0.006365 -0.014896 +v 0.105661 0.032180 -0.014896 +v 0.105661 0.025726 -0.018622 +v 0.105661 0.025726 0.018638 +v 0.105661 0.032180 0.014912 +v 0.105661 -0.000088 -0.003718 +v 0.105661 -0.000088 0.003734 +v 0.105661 0.038634 0.003734 +v 0.105661 0.038634 -0.003718 +v 0.031085 0.035609 -0.018856 +v 0.031085 0.027441 -0.023571 +v 0.031085 0.043777 0.004724 +v 0.031085 0.043777 -0.004708 +v 0.031085 0.027441 0.023587 +v 0.031085 0.035609 0.018871 +v 0.031085 0.002936 0.018871 +v 0.031085 0.011105 0.023587 +v 0.031085 -0.005232 -0.004708 +v 0.031085 -0.005232 0.004724 +v 0.031085 0.011105 -0.023571 +v 0.031085 0.002936 -0.018856 +v 0.109872 0.002936 0.018871 +v 0.109872 0.011105 0.023587 +v 0.109872 0.011105 -0.023571 +v 0.109872 0.002936 -0.018856 +v 0.109872 0.035609 -0.018856 +v 0.109872 0.027441 -0.023571 +v 0.109872 0.027441 0.023587 +v 0.109872 0.035609 0.018871 +v 0.109872 -0.005232 -0.004708 +v 0.109872 -0.005232 0.004724 +v 0.109872 0.043777 0.004724 +v 0.109872 0.043777 -0.004708 +v 0.031085 0.016645 -0.026770 +v 0.031085 0.021900 -0.026770 +v 0.031085 0.021292 -0.026023 +v 0.031085 0.017253 -0.026023 +v 0.031085 0.041149 -0.015657 +v 0.031085 0.043777 -0.011105 +v 0.031085 0.042826 -0.011258 +v 0.031085 0.040806 -0.014757 +v 0.031085 0.043777 0.011121 +v 0.031085 0.041149 0.015673 +v 0.031085 0.040806 0.014772 +v 0.031085 0.042826 0.011274 +v 0.031085 0.021900 0.026786 +v 0.031085 0.016645 0.026786 +v 0.031085 0.017253 0.026039 +v 0.031085 0.021292 0.026039 +v 0.031085 -0.002604 0.015673 +v 0.031085 -0.005232 0.011121 +v 0.031085 -0.004281 0.011274 +v 0.031085 -0.002261 0.014772 +v 0.031085 -0.005232 -0.011105 +v 0.031085 -0.002604 -0.015657 +v 0.031085 -0.002261 -0.014757 +v 0.031085 -0.004281 -0.011258 +v 0.109872 0.043777 -0.011105 +v 0.109872 0.041149 -0.015657 +v 0.112906 0.043777 -0.014140 +v 0.109872 0.041149 0.015673 +v 0.109872 0.043777 0.011121 +v 0.112906 0.043777 0.014155 +v 0.109872 -0.005232 0.011121 +v 0.109872 -0.002604 0.015673 +v 0.112906 -0.005232 0.014155 +v 0.109872 -0.002604 -0.015657 +v 0.109872 -0.005232 -0.011105 +v 0.112906 -0.005232 -0.014140 +v 0.109872 0.016645 0.026786 +v 0.109872 0.021900 0.026786 +v 0.112906 0.019273 0.028303 +v 0.109872 0.021900 -0.026770 +v 0.109872 0.016645 -0.026770 +v 0.112906 0.019273 -0.028287 +v -0.208716 0.003153 -0.008427 +v -0.201195 0.003153 -0.010839 +v -0.208716 0.001507 -0.008265 +v -0.201195 0.001037 -0.010631 +v -0.208716 -0.000075 -0.007785 +v -0.201195 -0.000998 -0.010013 +v -0.208716 -0.001533 -0.007005 +v -0.201195 -0.002873 -0.009011 +v -0.208716 -0.002811 -0.005956 +v -0.201195 -0.004517 -0.007662 +v -0.208716 -0.003860 -0.004678 +v -0.201195 -0.005866 -0.006018 +v -0.208716 -0.004640 -0.003220 +v -0.201195 -0.006868 -0.004143 +v -0.208716 -0.005120 -0.001638 +v -0.201195 -0.007486 -0.002108 +v -0.208716 -0.005282 0.000008 +v -0.201195 -0.007694 0.000008 +v -0.208716 -0.005120 0.001653 +v -0.201195 -0.007486 0.002124 +v -0.208716 -0.004640 0.003236 +v -0.201195 -0.006868 0.004159 +v -0.208716 -0.003860 0.004694 +v -0.201195 -0.005866 0.006034 +v -0.208716 -0.002811 0.005972 +v -0.201195 -0.004517 0.007678 +v -0.208716 -0.001533 0.007021 +v -0.201195 -0.002873 0.009027 +v -0.208716 -0.000075 0.007801 +v -0.201195 -0.000998 0.010029 +v -0.208716 0.001507 0.008281 +v -0.201195 0.001037 0.010646 +v -0.208716 0.003153 0.008443 +v -0.201195 0.003153 0.010855 +v -0.208716 0.004799 0.008281 +v -0.201195 0.005269 0.010646 +v -0.208716 0.006381 0.007801 +v -0.201195 0.007304 0.010029 +v -0.208716 0.007839 0.007021 +v -0.201195 0.009179 0.009027 +v -0.208716 0.009117 0.005972 +v -0.201195 0.010823 0.007678 +v -0.208716 0.010166 0.004694 +v -0.201195 0.012172 0.006034 +v -0.208716 0.010946 0.003236 +v -0.201195 0.013174 0.004159 +v -0.208716 0.011426 0.001653 +v -0.201195 0.013792 0.002124 +v -0.208716 0.011588 0.000008 +v -0.201195 0.014000 0.000008 +v -0.208716 0.011426 -0.001638 +v -0.201195 0.013792 -0.002108 +v -0.208716 0.010946 -0.003220 +v -0.201195 0.013174 -0.004143 +v -0.208716 0.010166 -0.004678 +v -0.201195 0.012172 -0.006018 +v -0.208716 0.009117 -0.005956 +v -0.201195 0.010823 -0.007662 +v -0.208716 0.007839 -0.007005 +v -0.201195 0.009179 -0.009011 +v -0.208716 0.006381 -0.007785 +v -0.201195 0.007304 -0.010013 +v -0.208716 0.004799 -0.008265 +v -0.201195 0.005269 -0.010631 +v -0.208716 0.003153 -0.010839 +v -0.208716 0.001037 -0.010631 +v -0.208716 -0.000998 -0.010013 +v -0.208716 -0.002873 -0.009011 +v -0.208716 -0.004517 -0.007662 +v -0.208716 -0.005866 -0.006018 +v -0.208716 -0.006868 -0.004143 +v -0.208716 -0.007486 -0.002108 +v -0.208716 -0.007694 0.000008 +v -0.208716 -0.007486 0.002124 +v -0.208716 -0.006868 0.004159 +v -0.208716 -0.005866 0.006034 +v -0.208716 -0.004517 0.007678 +v -0.208716 -0.002873 0.009027 +v -0.208716 -0.000998 0.010029 +v -0.208716 0.001037 0.010646 +v -0.208716 0.003153 0.010855 +v -0.208716 0.005269 0.010646 +v -0.208716 0.007304 0.010029 +v -0.208716 0.009179 0.009027 +v -0.208716 0.010823 0.007678 +v -0.208716 0.012172 0.006034 +v -0.208716 0.013174 0.004159 +v -0.208716 0.013792 0.002124 +v -0.208716 0.014000 0.000008 +v -0.208716 0.013792 -0.002108 +v -0.208716 0.013174 -0.004143 +v -0.208716 0.012172 -0.006018 +v -0.208716 0.010823 -0.007662 +v -0.208716 0.009179 -0.009011 +v -0.208716 0.007304 -0.010013 +v -0.208716 0.005269 -0.010631 +v -0.188137 0.003153 -0.008427 +v -0.188137 0.001507 -0.008265 +v -0.188137 -0.000075 -0.007785 +v -0.188137 -0.001533 -0.007005 +v -0.188137 -0.002811 -0.005956 +v -0.188137 -0.003860 -0.004678 +v -0.188137 -0.004640 -0.003220 +v -0.188137 -0.005120 -0.001638 +v -0.188137 -0.005282 0.000008 +v -0.188137 -0.005120 0.001653 +v -0.188137 -0.004640 0.003236 +v -0.188137 -0.003860 0.004694 +v -0.188137 -0.002811 0.005972 +v -0.188137 -0.001533 0.007021 +v -0.188137 -0.000075 0.007801 +v -0.188137 0.001507 0.008281 +v -0.188137 0.003153 0.008443 +v -0.188137 0.004799 0.008281 +v -0.188137 0.006381 0.007801 +v -0.188137 0.007839 0.007021 +v -0.188137 0.009117 0.005972 +v -0.188137 0.010166 0.004694 +v -0.188137 0.010946 0.003236 +v -0.188137 0.011426 0.001653 +v -0.188137 0.011588 0.000008 +v -0.188137 0.011426 -0.001638 +v -0.188137 0.010946 -0.003220 +v -0.188137 0.010166 -0.004678 +v -0.188137 0.009117 -0.005956 +v -0.188137 0.007839 -0.007005 +v -0.188137 0.006381 -0.007785 +v -0.188137 0.004799 -0.008265 +v 0.071324 -0.022016 0.003754 +v 0.086124 -0.022016 0.003754 +v 0.071324 -0.022016 0.000008 +v 0.071324 -0.022016 -0.003738 +v 0.086124 -0.022016 0.000008 +v 0.076586 -0.029882 0.000008 +v 0.076881 -0.036585 0.000008 +v 0.080797 -0.044784 0.000008 +v 0.090116 -0.053212 0.000008 +v 0.101947 -0.057320 0.000008 +v 0.113507 -0.058345 0.000008 +v 0.121550 -0.054918 0.000008 +v 0.127258 -0.049891 0.000008 +v 0.130949 -0.043388 0.000008 +v 0.135695 -0.036701 0.000008 +v 0.135695 -0.036701 -0.003471 +v 0.135695 -0.036701 0.003487 +v 0.128106 -0.030621 0.003487 +v 0.128106 -0.030621 0.000008 +v 0.128106 -0.030621 -0.003471 +v 0.125683 -0.042796 0.000008 +v 0.123071 -0.046744 0.000008 +v 0.118539 -0.050540 0.000008 +v 0.113054 -0.053023 0.000008 +v 0.102600 -0.052103 0.000008 +v 0.092591 -0.048589 0.000008 +v 0.086353 -0.043368 0.000008 +v 0.082256 -0.036188 0.000008 +v 0.081868 -0.029762 0.000008 +v 0.086124 -0.022016 -0.003738 +v 0.076586 -0.029882 0.001961 +v 0.077914 -0.029852 0.002609 +v 0.075949 -0.028929 0.002748 +v 0.077914 -0.029852 -0.002594 +v 0.076586 -0.029882 -0.001946 +v 0.075949 -0.028929 -0.002732 +v 0.076881 -0.036585 -0.001946 +v 0.078212 -0.036487 -0.002594 +v 0.078212 -0.036487 0.002609 +v 0.076881 -0.036585 0.001961 +v 0.080797 -0.044784 -0.001946 +v 0.082041 -0.044467 -0.002594 +v 0.082041 -0.044467 0.002609 +v 0.080797 -0.044784 0.001961 +v 0.090116 -0.053212 -0.001946 +v 0.090646 -0.052222 -0.002594 +v 0.090646 -0.052222 0.002609 +v 0.090116 -0.053212 0.001961 +v 0.101947 -0.057320 -0.001945 +v 0.102089 -0.056182 -0.002594 +v 0.102089 -0.056182 0.002609 +v 0.101947 -0.057320 0.001961 +v 0.113507 -0.058345 -0.001945 +v 0.113408 -0.057176 -0.002594 +v 0.113408 -0.057176 0.002609 +v 0.113507 -0.058345 0.001961 +v 0.121550 -0.054918 -0.001945 +v 0.120902 -0.053976 -0.002594 +v 0.120902 -0.053976 0.002609 +v 0.121550 -0.054918 0.001961 +v 0.127258 -0.049891 -0.001944 +v 0.126329 -0.049192 -0.002594 +v 0.126329 -0.049192 0.002609 +v 0.127258 -0.049891 0.001960 +v 0.130949 -0.043388 -0.002620 +v 0.129705 -0.043248 -0.003269 +v 0.131628 -0.042432 -0.003298 +v 0.129705 -0.043248 0.003285 +v 0.130949 -0.043388 0.002636 +v 0.131628 -0.042432 0.003314 +v 0.125683 -0.042796 0.002633 +v 0.126958 -0.042940 0.003285 +v 0.125912 -0.041646 0.003304 +v 0.126958 -0.042940 -0.003269 +v 0.125683 -0.042796 -0.002617 +v 0.125912 -0.041646 -0.003288 +v 0.123994 -0.047437 0.002609 +v 0.123072 -0.046745 0.001957 +v 0.123071 -0.046744 -0.001942 +v 0.123993 -0.047437 -0.002594 +v 0.119176 -0.051467 0.002609 +v 0.118539 -0.050540 0.001959 +v 0.118539 -0.050540 -0.001943 +v 0.119176 -0.051467 -0.002594 +v 0.113153 -0.054184 0.002609 +v 0.113054 -0.053023 0.001959 +v 0.113054 -0.053023 -0.001944 +v 0.113153 -0.054184 -0.002594 +v 0.102459 -0.053230 0.002609 +v 0.102600 -0.052103 0.001960 +v 0.102600 -0.052103 -0.001944 +v 0.102459 -0.053230 -0.002594 +v 0.092069 -0.049565 0.002609 +v 0.092591 -0.048589 0.001960 +v 0.092591 -0.048589 -0.001945 +v 0.092069 -0.049565 -0.002594 +v 0.085086 -0.043691 0.002609 +v 0.086353 -0.043368 0.001961 +v 0.086353 -0.043368 -0.001945 +v 0.085086 -0.043691 -0.002594 +v 0.080886 -0.036289 0.002609 +v 0.082256 -0.036188 0.001961 +v 0.082256 -0.036188 -0.001945 +v 0.080886 -0.036289 -0.002594 +v 0.080501 -0.029793 0.002609 +v 0.081868 -0.029762 0.001961 +v 0.082418 -0.028761 0.002757 +v 0.081868 -0.029762 -0.001945 +v 0.080501 -0.029793 -0.002594 +v 0.082418 -0.028761 -0.002742 +v 0.019206 0.038580 -0.003805 +v 0.019206 0.038580 0.003821 +v -0.188839 0.040578 -0.003805 +v -0.188839 0.040578 0.003821 +v -0.163034 0.038580 0.003821 +v -0.163034 0.038580 -0.003805 +v -0.084561 0.038580 -0.003805 +v -0.084561 0.038580 0.003821 +v -0.063202 0.038580 -0.003805 +v -0.063202 0.038580 0.003821 +v -0.032943 0.038580 -0.003805 +v -0.032943 0.038580 0.003821 +v 0.009776 0.038580 -0.003805 +v 0.009776 0.038580 0.003821 +v -0.019148 0.038580 0.003821 +v -0.019148 0.038580 -0.003805 +v -0.113931 0.038580 0.003821 +v -0.113931 0.038580 -0.003805 +v -0.139295 0.038580 0.003821 +v -0.139295 0.038580 -0.003805 +v 0.019206 0.031646 -0.003805 +v 0.019206 0.031646 0.003821 +v -0.163034 0.031646 0.003821 +v -0.188839 0.031646 0.003821 +v -0.188839 0.031646 -0.003805 +v 0.009776 0.031646 -0.003805 +v -0.163034 0.031646 -0.003805 +v -0.063202 0.031646 0.003821 +v -0.084561 0.031646 0.003821 +v -0.084561 0.031646 -0.003805 +v -0.063202 0.031646 -0.003805 +v -0.019148 0.031646 0.003821 +v -0.032943 0.031646 0.003821 +v -0.032943 0.031646 -0.003805 +v 0.009776 0.031646 0.003821 +v -0.019148 0.031646 -0.003805 +v -0.139295 0.031646 -0.003805 +v -0.113931 0.031646 -0.003805 +v -0.113931 0.031646 0.003821 +v -0.139295 0.031646 0.003821 +v -0.084573 0.037374 0.003821 +v -0.084308 0.036203 0.003821 +v -0.083931 0.035113 0.003821 +v -0.083761 0.034056 0.003821 +v -0.084015 0.032920 0.003821 +v -0.084015 0.032920 -0.003805 +v -0.083761 0.034056 -0.003805 +v -0.083931 0.035113 -0.003805 +v -0.084308 0.036203 -0.003805 +v -0.084573 0.037374 -0.003805 +v -0.063191 0.037374 -0.003805 +v -0.063456 0.036203 -0.003805 +v -0.063833 0.035113 -0.003805 +v -0.064003 0.034056 -0.003805 +v -0.063749 0.032920 -0.003805 +v -0.063749 0.032920 0.003821 +v -0.064003 0.034056 0.003821 +v -0.063833 0.035113 0.003821 +v -0.063456 0.036203 0.003821 +v -0.063191 0.037374 0.003821 +v -0.019137 0.037374 0.003821 +v -0.019402 0.036203 0.003821 +v -0.019779 0.035113 0.003821 +v -0.019949 0.034056 0.003821 +v -0.019695 0.032920 0.003821 +v -0.032396 0.032920 0.003821 +v -0.032142 0.034056 0.003821 +v -0.032312 0.035113 0.003821 +v -0.032689 0.036203 0.003821 +v -0.032954 0.037374 0.003821 +v -0.032954 0.037374 -0.003805 +v -0.032689 0.036203 -0.003805 +v -0.032312 0.035113 -0.003805 +v -0.032142 0.034056 -0.003805 +v -0.032396 0.032920 -0.003805 +v -0.019695 0.032920 -0.003805 +v -0.019949 0.034056 -0.003805 +v -0.019779 0.035113 -0.003805 +v -0.019402 0.036203 -0.003805 +v -0.019137 0.037374 -0.003805 +v 0.019206 0.037401 0.003821 +v 0.019206 0.036224 0.003821 +v 0.019206 0.035113 0.003821 +v 0.019206 0.034047 0.003821 +v 0.019206 0.032916 0.003821 +v 0.010323 0.032920 0.003821 +v 0.010577 0.034056 0.003821 +v 0.010407 0.035113 0.003821 +v 0.010030 0.036203 0.003821 +v 0.009765 0.037374 0.003821 +v 0.019206 0.037401 -0.003805 +v 0.019206 0.036224 -0.003805 +v 0.019206 0.035113 -0.003805 +v 0.019206 0.034047 -0.003805 +v 0.019206 0.032916 -0.003805 +v 0.009765 0.037374 -0.003805 +v 0.010030 0.036203 -0.003805 +v 0.010407 0.035113 -0.003805 +v 0.010577 0.034056 -0.003805 +v 0.010323 0.032920 -0.003805 +v -0.113920 0.037374 0.003821 +v -0.114184 0.036203 0.003821 +v -0.114561 0.035113 0.003821 +v -0.114731 0.034056 0.003821 +v -0.114478 0.032920 0.003821 +v -0.138748 0.032920 0.003821 +v -0.138494 0.034056 0.003821 +v -0.138664 0.035113 0.003821 +v -0.139041 0.036203 0.003821 +v -0.139306 0.037374 0.003821 +v -0.139306 0.037374 -0.003805 +v -0.139041 0.036203 -0.003805 +v -0.138664 0.035113 -0.003805 +v -0.138494 0.034056 -0.003805 +v -0.138748 0.032920 -0.003805 +v -0.114478 0.032920 -0.003805 +v -0.114731 0.034056 -0.003805 +v -0.114561 0.035113 -0.003805 +v -0.114184 0.036203 -0.003805 +v -0.113920 0.037374 -0.003805 +v -0.163581 0.032920 -0.003805 +v -0.163835 0.034056 -0.003805 +v -0.163665 0.035113 -0.003805 +v -0.163288 0.036203 -0.003805 +v -0.163023 0.037374 -0.003805 +v -0.163581 0.032920 0.003821 +v -0.163835 0.034056 0.003821 +v -0.163665 0.035113 0.003821 +v -0.163288 0.036203 0.003821 +v -0.163023 0.037374 0.003821 +v 0.019206 0.046547 -0.002474 +v 0.019206 0.045215 -0.003805 +v 0.019206 0.045215 0.003821 +v 0.019206 0.046547 0.002490 +v -0.188839 0.045215 -0.003805 +v -0.188839 0.046547 -0.002474 +v -0.188839 0.046547 0.002490 +v -0.188839 0.045215 0.003821 +v -0.193775 0.040578 -0.003805 +v -0.193775 0.040578 0.003821 +v -0.193775 0.031646 0.003821 +v -0.193775 0.031646 -0.003805 +v -0.202588 0.031646 -0.003805 +v -0.202588 0.031646 0.003821 +v -0.202588 0.031646 0.003821 +v -0.202588 0.031646 -0.003805 +v 0.120283 0.031646 -0.003805 +v 0.120283 0.031646 0.003821 +v -0.197527 -0.014269 -0.009589 +v -0.197527 -0.009485 -0.009589 +v -0.197527 -0.014269 0.009605 +v -0.197527 -0.009485 0.009605 +v -0.192126 -0.014269 -0.009589 +v -0.192126 -0.014269 0.009605 +v -0.199379 -0.015503 -0.009589 +v -0.199379 -0.009485 -0.009589 +v -0.199379 -0.015503 0.009605 +v -0.199379 -0.009485 0.009605 +v -0.204626 -0.015503 -0.009589 +v -0.204626 -0.009485 -0.009589 +v -0.204626 -0.015503 0.009605 +v -0.204626 -0.009485 0.009605 +v -0.185027 -0.014269 -0.009589 +v -0.185027 -0.009485 -0.009589 +v -0.185027 -0.014269 0.009605 +v -0.185027 -0.009485 0.009605 +v -0.179626 -0.014269 -0.009589 +v -0.179626 -0.009485 -0.009589 +v -0.179626 -0.014269 0.009605 +v -0.179626 -0.009485 0.009605 +v -0.186879 -0.015503 -0.009589 +v -0.186879 -0.009485 -0.009589 +v -0.186879 -0.015503 0.009605 +v -0.186879 -0.009485 0.009605 +v -0.192126 -0.015503 -0.009589 +v -0.192126 -0.009485 -0.009589 +v -0.192126 -0.015503 0.009605 +v -0.192126 -0.009485 0.009605 +v -0.172527 -0.014269 -0.009589 +v -0.172527 -0.009485 -0.009589 +v -0.172527 -0.014269 0.009605 +v -0.172527 -0.009485 0.009605 +v -0.167126 -0.014269 -0.009589 +v -0.167126 -0.009485 -0.009589 +v -0.167126 -0.014269 0.009605 +v -0.174379 -0.015503 -0.009589 +v -0.174379 -0.009485 -0.009589 +v -0.174379 -0.015503 0.009605 +v -0.174379 -0.009485 0.009605 +v -0.179626 -0.015503 -0.009589 +v -0.179626 -0.015503 0.009605 +v -0.160027 -0.014269 -0.009589 +v -0.160027 -0.009485 -0.009589 +v -0.160027 -0.014269 0.009605 +v -0.160027 -0.009485 0.009605 +v -0.154626 -0.014269 -0.009589 +v -0.154626 -0.009485 -0.009589 +v -0.154626 -0.014269 0.009605 +v -0.154626 -0.009485 0.009605 +v -0.161879 -0.015503 -0.009589 +v -0.161879 -0.009485 -0.009589 +v -0.161879 -0.015503 0.009605 +v -0.161879 -0.009485 0.009605 +v -0.167126 -0.015503 -0.009589 +v -0.167126 -0.015503 0.009605 +v -0.167126 -0.009485 0.009605 +v -0.147527 -0.014269 -0.009589 +v -0.147527 -0.009485 -0.009589 +v -0.147527 -0.014269 0.009605 +v -0.147527 -0.009485 0.009605 +v -0.142126 -0.014269 -0.009589 +v -0.142126 -0.014269 0.009605 +v -0.142126 -0.009485 0.009605 +v -0.149379 -0.015503 -0.009589 +v -0.149379 -0.009485 -0.009589 +v -0.149379 -0.015503 0.009605 +v -0.149379 -0.009485 0.009605 +v -0.154626 -0.015503 -0.009589 +v -0.154626 -0.015503 0.009605 +v -0.135027 -0.014269 -0.009589 +v -0.135027 -0.009485 -0.009589 +v -0.135027 -0.014269 0.009605 +v -0.135027 -0.009485 0.009605 +v -0.129626 -0.014269 -0.009589 +v -0.129626 -0.009485 -0.009589 +v -0.129626 -0.014269 0.009605 +v -0.136879 -0.015503 -0.009589 +v -0.136879 -0.009485 -0.009589 +v -0.136879 -0.015503 0.009605 +v -0.136879 -0.009485 0.009605 +v -0.142126 -0.015503 -0.009589 +v -0.142126 -0.009485 -0.009589 +v -0.142126 -0.015503 0.009605 +v -0.122527 -0.014269 -0.009589 +v -0.122527 -0.009485 -0.009589 +v -0.122527 -0.014269 0.009605 +v -0.122527 -0.009485 0.009605 +v -0.117126 -0.014269 -0.009589 +v -0.117126 -0.009485 -0.009589 +v -0.117126 -0.014269 0.009605 +v -0.117126 -0.009485 0.009605 +v -0.124379 -0.015503 -0.009589 +v -0.124379 -0.009485 -0.009589 +v -0.124379 -0.015503 0.009605 +v -0.124379 -0.009485 0.009605 +v -0.129626 -0.015503 -0.009589 +v -0.129626 -0.015503 0.009605 +v -0.129626 -0.009485 0.009605 +v -0.110027 -0.014269 -0.009589 +v -0.110027 -0.009485 -0.009589 +v -0.110027 -0.014269 0.009605 +v -0.110027 -0.009485 0.009605 +v -0.104626 -0.014269 -0.009589 +v -0.104626 -0.014269 0.009605 +v -0.111879 -0.015503 -0.009589 +v -0.111879 -0.009485 -0.009589 +v -0.111879 -0.015503 0.009605 +v -0.111879 -0.009485 0.009605 +v -0.117126 -0.015503 -0.009589 +v -0.117126 -0.015503 0.009605 +v -0.097527 -0.014269 -0.009589 +v -0.097527 -0.009485 -0.009589 +v -0.097527 -0.014269 0.009605 +v -0.097527 -0.009485 0.009605 +v -0.092126 -0.014269 -0.009589 +v -0.092126 -0.009485 -0.009589 +v -0.092126 -0.014269 0.009605 +v -0.092126 -0.009485 0.009605 +v -0.099379 -0.015503 -0.009589 +v -0.099379 -0.009485 -0.009589 +v -0.099379 -0.015503 0.009605 +v -0.099379 -0.009485 0.009605 +v -0.104626 -0.015503 -0.009589 +v -0.104626 -0.009485 -0.009589 +v -0.104626 -0.015503 0.009605 +v -0.104626 -0.009485 0.009605 +v -0.085027 -0.014269 -0.009589 +v -0.085027 -0.009485 -0.009589 +v -0.085027 -0.014269 0.009605 +v -0.085027 -0.009485 0.009605 +v -0.079626 -0.014269 -0.009589 +v -0.079626 -0.009485 -0.009589 +v -0.079626 -0.014269 0.009605 +v -0.079626 -0.009485 0.009605 +v -0.086879 -0.015503 -0.009589 +v -0.086879 -0.009485 -0.009589 +v -0.086879 -0.015503 0.009605 +v -0.086879 -0.009485 0.009605 +v -0.092126 -0.015503 -0.009589 +v -0.092126 -0.015503 0.009605 +v -0.072527 -0.014269 -0.009589 +v -0.072527 -0.009485 -0.009589 +v -0.072527 -0.014269 0.009605 +v -0.072527 -0.009485 0.009605 +v -0.067126 -0.014269 -0.009589 +v -0.067126 -0.014269 0.009605 +v -0.074379 -0.015503 -0.009589 +v -0.074379 -0.009485 -0.009589 +v -0.074379 -0.015503 0.009605 +v -0.074379 -0.009485 0.009605 +v -0.079626 -0.015503 -0.009589 +v -0.079626 -0.015503 0.009605 +v -0.060027 -0.014269 -0.009589 +v -0.060027 -0.009485 -0.009589 +v -0.060027 -0.014269 0.009605 +v -0.060027 -0.009485 0.009605 +v -0.054626 -0.014269 -0.009589 +v -0.054626 -0.009485 -0.009589 +v -0.054626 -0.014269 0.009605 +v -0.061879 -0.015503 -0.009589 +v -0.061879 -0.009485 -0.009589 +v -0.061879 -0.015503 0.009605 +v -0.061879 -0.009485 0.009605 +v -0.067126 -0.015503 -0.009589 +v -0.067126 -0.009485 -0.009589 +v -0.067126 -0.015503 0.009605 +v -0.067126 -0.009485 0.009605 +v -0.047527 -0.014269 -0.009589 +v -0.047527 -0.009485 -0.009589 +v -0.047527 -0.014269 0.009605 +v -0.047527 -0.009485 0.009605 +v -0.042126 -0.014269 -0.009589 +v -0.042126 -0.009485 -0.009589 +v -0.042126 -0.014269 0.009605 +v -0.049379 -0.015503 -0.009589 +v -0.049379 -0.009485 -0.009589 +v -0.049379 -0.015503 0.009605 +v -0.049379 -0.009485 0.009605 +v -0.054626 -0.015503 -0.009589 +v -0.054626 -0.015503 0.009605 +v -0.054626 -0.009485 0.009605 +v -0.035027 -0.014269 -0.009589 +v -0.035027 -0.009485 -0.009589 +v -0.035027 -0.014269 0.009605 +v -0.035027 -0.009485 0.009605 +v -0.029626 -0.014269 -0.009589 +v -0.029626 -0.009485 -0.009589 +v -0.029626 -0.014269 0.009605 +v -0.029626 -0.009485 0.009605 +v -0.036879 -0.015503 -0.009589 +v -0.036879 -0.009485 -0.009589 +v -0.036879 -0.015503 0.009605 +v -0.036879 -0.009485 0.009605 +v -0.042126 -0.015503 -0.009589 +v -0.042126 -0.015503 0.009605 +v -0.042126 -0.009485 0.009605 +v -0.006269 -0.009314 0.000960 +v -0.006269 -0.009314 -0.000944 +v 0.013161 -0.021859 0.000960 +v 0.013161 -0.009314 0.000960 +v 0.013161 -0.021859 -0.000944 +v 0.013161 -0.009314 -0.000944 +v -0.006269 -0.011794 0.000960 +v 0.005252 -0.021859 0.000960 +v 0.005252 -0.021859 -0.000944 +v -0.006269 -0.011794 -0.000944 +v 0.135609 0.051689 0.005059 +v 0.135609 0.059954 0.004141 +v 0.135609 0.051689 -0.005043 +v 0.135609 0.059954 -0.004125 +v 0.149134 0.051689 0.005059 +v 0.149134 0.059954 0.004141 +v 0.149134 0.051689 -0.005043 +v 0.149134 0.059954 -0.004125 +v 0.135609 0.055536 0.005059 +v 0.135609 0.055536 -0.005043 +v 0.149134 0.055536 -0.005043 +v 0.149134 0.055536 0.005059 +v 0.144626 0.059954 -0.004125 +v 0.144626 0.059954 0.004141 +v 0.147543 0.059954 -0.004125 +v 0.147543 0.059954 0.004141 +v 0.147543 0.061477 0.004141 +v 0.144626 0.061477 0.004141 +v 0.144626 0.061477 -0.004125 +v 0.147543 0.061477 -0.004125 +v 0.149134 0.059954 -0.001267 +v 0.149134 0.059954 0.001283 +v 0.149134 0.055536 -0.001550 +v 0.149134 0.055536 0.001566 +v 0.144626 0.059954 -0.001267 +v 0.144626 0.059954 0.001283 +v 0.147543 0.059954 -0.001267 +v 0.147543 0.059954 0.001283 +v 0.144626 0.061477 -0.001267 +v 0.144626 0.061477 0.001283 +v 0.147543 0.061477 -0.001267 +v 0.147543 0.061477 0.001283 +v 0.135609 0.051689 -0.002884 +v 0.135609 0.051689 0.002900 +v 0.135609 0.055536 0.002900 +v 0.135609 0.055536 -0.002884 +v 0.111403 0.051689 -0.002884 +v 0.111403 0.051689 0.002900 +v 0.111403 0.055536 0.002900 +v 0.111403 0.055536 -0.002884 +v 0.105555 -0.029919 0.000664 +v 0.106013 -0.029919 0.001114 +v 0.099064 -0.022161 0.003014 +v 0.099526 -0.022161 0.003464 +v 0.106013 -0.029919 -0.001328 +v 0.105555 -0.029919 -0.000878 +v 0.099526 -0.022161 -0.003679 +v 0.099064 -0.022161 -0.003228 +v 0.111796 -0.029919 0.001114 +v 0.112301 -0.029919 0.000664 +v 0.118284 -0.022161 0.003464 +v 0.118791 -0.022161 0.003014 +v 0.112301 -0.029919 -0.000878 +v 0.111796 -0.029919 -0.001328 +v 0.118791 -0.022161 -0.003228 +v 0.118284 -0.022161 -0.003679 +v 0.097823 -0.047619 0.000241 +v 0.097358 -0.047276 -0.000236 +v 0.097823 -0.047619 -0.000456 +v 0.097358 -0.047276 0.000022 +v 0.097876 -0.048571 0.000235 +v 0.097455 -0.049042 -0.000236 +v 0.097876 -0.048571 -0.000450 +v 0.097455 -0.049042 0.000022 +v 0.105555 -0.035911 0.000665 +v 0.106008 -0.035911 0.001114 +v 0.104854 -0.041096 0.000435 +v 0.105281 -0.041252 0.000884 +v 0.102417 -0.045500 0.000530 +v 0.102203 -0.045039 0.000081 +v 0.103706 -0.048278 0.000081 +v 0.103523 -0.047883 0.000530 +v 0.110052 -0.042996 0.000435 +v 0.109598 -0.042830 0.000884 +v 0.111797 -0.035911 0.001114 +v 0.112301 -0.035911 0.000665 +v 0.112301 -0.035911 -0.000879 +v 0.111797 -0.035911 -0.001328 +v 0.110052 -0.042996 -0.000649 +v 0.109598 -0.042830 -0.001099 +v 0.103523 -0.047883 -0.000744 +v 0.103706 -0.048278 -0.000295 +v 0.102203 -0.045039 -0.000295 +v 0.102417 -0.045500 -0.000744 +v 0.104854 -0.041096 -0.000649 +v 0.105281 -0.041252 -0.001099 +v 0.106008 -0.035911 -0.001328 +v 0.105555 -0.035911 -0.000879 +v 0.002195 0.049146 0.001016 +v 0.002195 0.052914 0.001016 +v 0.000259 0.049146 0.000008 +v 0.000259 0.052914 0.000008 +v 0.004131 0.049146 0.000008 +v 0.004131 0.052914 0.000008 +v 0.002195 0.049146 -0.001000 +v 0.002195 0.052914 -0.001000 +v -0.008685 0.049146 0.001016 +v -0.008685 0.052914 0.001016 +v -0.010621 0.049146 0.000008 +v -0.010621 0.052914 0.000008 +v -0.006749 0.049146 0.000008 +v -0.006749 0.052914 0.000008 +v -0.008685 0.049146 -0.001000 +v -0.008685 0.052914 -0.001000 +v -0.019565 0.049146 0.001016 +v -0.019565 0.052914 0.001016 +v -0.021501 0.049146 0.000008 +v -0.021501 0.052914 0.000008 +v -0.017629 0.049146 0.000008 +v -0.017629 0.052914 0.000008 +v -0.019565 0.049146 -0.001000 +v -0.019565 0.052914 -0.001000 +v -0.030446 0.049146 0.001016 +v -0.030446 0.052914 0.001016 +v -0.032382 0.049146 0.000008 +v -0.032382 0.052914 0.000008 +v -0.028510 0.049146 0.000008 +v -0.028510 0.052914 0.000008 +v -0.030446 0.049146 -0.001000 +v -0.030446 0.052914 -0.001000 +v -0.041326 0.049146 0.001016 +v -0.041326 0.052914 0.001016 +v -0.043262 0.049146 0.000008 +v -0.043262 0.052914 0.000008 +v -0.039390 0.049146 0.000008 +v -0.039390 0.052914 0.000008 +v -0.041326 0.049146 -0.001000 +v -0.041326 0.052914 -0.001000 +v -0.052206 0.049146 0.001016 +v -0.052206 0.052914 0.001016 +v -0.054142 0.049146 0.000008 +v -0.054142 0.052914 0.000008 +v -0.050270 0.049146 0.000008 +v -0.050270 0.052914 0.000008 +v -0.052206 0.049146 -0.001000 +v -0.052206 0.052914 -0.001000 +v -0.063086 0.049146 0.001016 +v -0.063086 0.052914 0.001016 +v -0.065022 0.049146 0.000008 +v -0.065022 0.052914 0.000008 +v -0.061150 0.049146 0.000008 +v -0.061150 0.052914 0.000008 +v -0.063086 0.049146 -0.001000 +v -0.063086 0.052914 -0.001000 +v -0.073966 0.049146 0.001016 +v -0.073966 0.052914 0.001016 +v -0.075902 0.049146 0.000008 +v -0.075902 0.052914 0.000008 +v -0.072031 0.049146 0.000008 +v -0.072031 0.052914 0.000008 +v -0.073966 0.049146 -0.001000 +v -0.073966 0.052914 -0.001000 +v -0.084847 0.049146 0.001016 +v -0.084847 0.052914 0.001016 +v -0.086783 0.049146 0.000008 +v -0.086783 0.052914 0.000008 +v -0.082911 0.049146 0.000008 +v -0.082911 0.052914 0.000008 +v -0.084847 0.049146 -0.001000 +v -0.084847 0.052914 -0.001000 +v -0.095727 0.049146 0.001016 +v -0.095727 0.052914 0.001016 +v -0.097663 0.049146 0.000008 +v -0.097663 0.052914 0.000008 +v -0.093791 0.049146 0.000008 +v -0.093791 0.052914 0.000008 +v -0.095727 0.049146 -0.001000 +v -0.095727 0.052914 -0.001000 +v -0.106607 0.049146 0.001016 +v -0.106607 0.052914 0.001016 +v -0.108543 0.049146 0.000008 +v -0.108543 0.052914 0.000008 +v -0.104671 0.049146 0.000008 +v -0.104671 0.052914 0.000008 +v -0.106607 0.049146 -0.001000 +v -0.106607 0.052914 -0.001000 +v -0.117487 0.049146 0.001016 +v -0.117487 0.052914 0.001016 +v -0.119423 0.049146 0.000008 +v -0.119423 0.052914 0.000008 +v -0.115551 0.049146 0.000008 +v -0.115551 0.052914 0.000008 +v -0.117487 0.049146 -0.001000 +v -0.117487 0.052914 -0.001000 +v -0.128368 0.049146 0.001016 +v -0.128368 0.052914 0.001016 +v -0.130304 0.049146 0.000008 +v -0.130304 0.052914 0.000008 +v -0.126432 0.049146 0.000008 +v -0.126432 0.052914 0.000008 +v -0.128368 0.049146 -0.001000 +v -0.128368 0.052914 -0.001000 +v -0.139248 0.049146 0.001016 +v -0.139248 0.052914 0.001016 +v -0.141184 0.049146 0.000008 +v -0.141184 0.052914 0.000008 +v -0.137312 0.049146 0.000008 +v -0.137312 0.052914 0.000008 +v -0.139248 0.049146 -0.001000 +v -0.139248 0.052914 -0.001000 +v -0.150128 0.049146 0.001016 +v -0.150128 0.052914 0.001016 +v -0.152064 0.049146 0.000008 +v -0.152064 0.052914 0.000008 +v -0.148192 0.049146 0.000008 +v -0.148192 0.052914 0.000008 +v -0.150128 0.049146 -0.001000 +v -0.150128 0.052914 -0.001000 +v 0.006134 0.046257 0.001989 +v 0.006134 0.046257 -0.001973 +v -0.155851 0.046257 0.001989 +v -0.155851 0.046257 -0.001973 +v 0.007537 0.046183 -0.001973 +v 0.008031 0.046157 -0.001136 +v 0.008031 0.046157 0.001152 +v 0.007537 0.046183 0.001989 +v 0.006134 0.048695 0.001989 +v 0.006134 0.049524 0.001152 +v 0.006134 0.048695 -0.001973 +v 0.006134 0.049524 -0.001136 +v -0.155851 0.048700 0.001989 +v -0.155851 0.049524 0.001152 +v -0.155851 0.049524 -0.001136 +v -0.155851 0.048700 -0.001973 +vn 0.8051 0.1581 0.5716 +vn 0.8034 0.2913 0.5193 +vn 0.2132 0.1801 0.9603 +vn 0.1554 0.0529 0.9864 +vn -0.1177 -0.0072 0.9930 +vn -0.0993 0.0335 0.9945 +vn -0.2857 -0.0693 0.9558 +vn -0.2806 -0.0326 0.9593 +vn -0.0080 -1.0000 0.0010 +vn 0.5865 -0.6676 0.4585 +vn 0.1746 -0.6426 0.7461 +vn -0.1003 -0.6813 0.7251 +vn -0.8632 -0.4615 0.2047 +vn -0.6399 0.0133 0.7683 +vn -0.7049 -0.0253 0.7088 +vn -0.8946 -0.3612 0.2630 +vn -0.0313 0.3504 0.9361 +vn 0.2020 0.1339 0.9702 +vn 0.0228 0.5932 0.8047 +vn -0.0579 0.5041 0.8617 +vn -0.1698 -0.0006 0.9855 +vn 0.2237 0.2988 0.9277 +vn 0.1133 0.2208 0.9687 +vn -0.0917 0.1141 0.9892 +vn -0.7826 -0.6126 0.1108 +vn -0.4184 -0.2304 0.8786 +vn -0.6055 -0.0958 0.7900 +vn -0.8342 -0.5421 0.1010 +vn -0.0079 -0.7026 0.7115 +vn -0.0183 0.0724 0.9972 +vn -0.3624 0.2163 0.9066 +vn -0.5263 -0.4673 0.7104 +vn -0.0474 0.0678 0.9966 +vn -0.0523 0.0246 0.9983 +vn -0.2146 -0.0293 0.9763 +vn -0.1259 0.0589 0.9903 +vn -0.0841 0.0109 0.9964 +vn -0.2693 0.0714 0.9604 +vn 0.7785 -0.0671 0.6240 +vn 0.1984 0.0129 0.9800 +vn 0.7504 -0.0208 0.6607 +vn 0.7531 0.1170 0.6475 +vn 0.1536 0.0171 0.9880 +vn 0.1489 0.0213 0.9886 +vn 0.7728 0.2156 0.5969 +vn 0.1713 0.0373 0.9845 +vn -0.7928 -0.1563 0.5892 +vn -0.8171 0.0799 0.5710 +vn -0.9963 0.0770 0.0378 +vn -0.9707 -0.2289 0.0724 +vn -0.8303 -0.0431 0.5556 +vn -0.9837 -0.1771 0.0325 +vn -0.8403 -0.5124 0.1773 +vn -0.8986 0.2886 0.3305 +vn -0.9859 0.1647 -0.0291 +vn -0.7847 -0.6181 -0.0465 +vn 0.7103 0.5764 0.4040 +vn 0.7776 0.6287 -0.0000 +vn 0.9995 -0.0320 -0.0000 +vn 0.8438 0.1283 0.5211 +vn 0.7619 -0.3852 0.5207 +vn 0.7943 -0.6075 -0.0000 +vn 0.7572 0.6532 -0.0000 +vn 0.7231 0.5350 0.4369 +vn -0.8051 -0.5471 0.2291 +vn -0.8813 -0.1029 0.4611 +vn 0.9854 0.1702 -0.0000 +vn 0.9419 0.3360 -0.0000 +vn 0.9987 -0.0514 -0.0000 +vn 0.7178 -0.6963 -0.0000 +vn 0.9929 -0.1188 -0.0000 +vn -0.7598 -0.6502 -0.0000 +vn -0.7411 -0.6713 -0.0000 +vn -0.7982 -0.6024 -0.0000 +vn -0.8985 -0.4389 -0.0000 +vn -0.0061 -1.0000 -0.0000 +vn 0.9764 0.2159 -0.0000 +vn 0.9440 0.3298 -0.0000 +vn -0.9968 0.0767 -0.0205 +vn -0.1797 0.0742 0.9809 +vn -0.2569 0.0511 0.9651 +vn -0.2862 -0.0348 0.9575 +vn -0.2658 -0.0114 0.9640 +vn -0.0079 -1.0000 -0.0000 +vn -0.0104 -0.9999 0.0057 +vn -0.7607 -0.6491 -0.0000 +vn -0.2853 -0.0117 0.9584 +vn 0.0114 0.1275 0.9918 +vn 0.0085 0.2623 0.9650 +vn -0.0448 0.3200 0.9463 +vn -0.0391 0.3034 0.9521 +vn -0.2298 0.0253 0.9729 +vn -0.8703 -0.4926 -0.0000 +vn -0.0000 -0.0000 1.0000 +vn -0.9652 0.2615 -0.0000 +vn -0.9958 0.0911 -0.0000 +vn -0.9657 -0.2597 -0.0000 +vn -0.9815 -0.1912 -0.0000 +vn -0.9929 0.1187 -0.0000 +vn -0.9623 -0.2721 -0.0000 +vn -0.2133 0.9770 -0.0000 +vn -0.1908 0.9364 0.2944 +vn 0.8051 0.1581 -0.5716 +vn 0.1554 0.0529 -0.9864 +vn 0.2132 0.1801 -0.9603 +vn 0.8034 0.2913 -0.5193 +vn -0.1177 -0.0072 -0.9930 +vn -0.2806 -0.0326 -0.9593 +vn -0.2857 -0.0693 -0.9558 +vn -0.0993 0.0335 -0.9945 +vn -0.0080 -1.0000 -0.0010 +vn -0.1003 -0.6813 -0.7251 +vn 0.1746 -0.6426 -0.7461 +vn 0.5865 -0.6676 -0.4585 +vn -0.8632 -0.4615 -0.2047 +vn -0.8946 -0.3612 -0.2630 +vn -0.7049 -0.0253 -0.7088 +vn -0.6399 0.0133 -0.7683 +vn -0.0313 0.3504 -0.9361 +vn -0.0141 0.3224 -0.9465 +vn 0.1768 0.1951 -0.9647 +vn 0.2020 0.1339 -0.9702 +vn -0.1698 -0.0006 -0.9855 +vn -0.0917 0.1141 -0.9892 +vn 0.1133 0.2208 -0.9687 +vn 0.2237 0.2988 -0.9277 +vn -0.7826 -0.6126 -0.1108 +vn -0.8342 -0.5421 -0.1010 +vn -0.6055 -0.0958 -0.7900 +vn -0.4184 -0.2304 -0.8786 +vn -0.0079 -0.7026 -0.7115 +vn -0.5263 -0.4673 -0.7104 +vn -0.3624 0.2163 -0.9066 +vn -0.0183 0.0724 -0.9972 +vn -0.0474 0.0678 -0.9966 +vn -0.1259 0.0589 -0.9903 +vn -0.2146 -0.0293 -0.9763 +vn -0.0523 0.0246 -0.9983 +vn -0.2693 0.0714 -0.9604 +vn -0.0841 0.0109 -0.9964 +vn 0.1984 0.0129 -0.9800 +vn 0.7785 -0.0671 -0.6240 +vn 0.7504 -0.0208 -0.6607 +vn 0.1489 0.0213 -0.9886 +vn 0.1536 0.0171 -0.9880 +vn 0.7531 0.1170 -0.6475 +vn 0.1713 0.0373 -0.9845 +vn 0.7728 0.2156 -0.5969 +vn -0.7928 -0.1563 -0.5892 +vn -0.9707 -0.2289 -0.0724 +vn -0.9963 0.0770 -0.0378 +vn -0.8171 0.0799 -0.5710 +vn -0.8303 -0.0431 -0.5556 +vn -0.9837 -0.1771 -0.0325 +vn -0.8403 -0.5124 -0.1773 +vn -0.7847 -0.6181 0.0465 +vn -0.9859 0.1647 0.0291 +vn -0.8986 0.2886 -0.3305 +vn 0.7103 0.5764 -0.4040 +vn 0.8438 0.1283 -0.5211 +vn 0.7619 -0.3852 -0.5207 +vn 0.8118 0.4190 -0.4067 +vn -0.8813 -0.1029 -0.4611 +vn -0.8051 -0.5471 -0.2291 +vn -0.9968 0.0767 0.0205 +vn -0.1797 0.0742 -0.9809 +vn -0.2569 0.0511 -0.9651 +vn -0.2862 -0.0348 -0.9575 +vn -0.2658 -0.0114 -0.9640 +vn -0.0104 -0.9999 -0.0057 +vn -0.2853 -0.0117 -0.9584 +vn 0.0085 0.2623 -0.9650 +vn 0.0114 0.1275 -0.9918 +vn -0.0391 0.3034 -0.9521 +vn -0.0448 0.3200 -0.9463 +vn -0.2298 0.0253 -0.9729 +vn -0.2090 0.9570 -0.2014 +vn -0.0000 -1.0000 -0.0000 +vn 0.4856 0.2822 0.8274 +vn 1.0000 -0.0000 -0.0000 +vn -0.0000 1.0000 -0.0000 +vn 0.5105 0.8071 0.2967 +vn -0.0000 0.4832 0.8755 +vn -0.0000 -0.0000 -1.0000 +vn 0.4856 0.2822 -0.8274 +vn 0.5105 0.8071 -0.2967 +vn -0.0000 0.4832 -0.8755 +vn -0.7071 -0.7071 -0.0000 +vn -0.7071 0.7071 -0.0000 +vn -0.4832 -0.0000 0.8755 +vn -0.4832 -0.0000 -0.8755 +vn -1.0000 -0.0000 -0.0000 +vn 0.3019 0.9528 0.0307 +vn -0.0000 0.0899 0.9960 +vn -0.2437 -0.9699 -0.0000 +vn -0.0000 0.1131 0.9936 +vn 0.0008 -0.0001 1.0000 +vn 0.8532 0.5211 0.0229 +vn 0.0007 0.0919 0.9958 +vn 0.0005 0.0737 0.9973 +vn 0.9999 -0.0170 -0.0000 +vn 0.0052 -1.0000 -0.0000 +vn 0.8538 0.5192 -0.0376 +vn 0.0376 0.9898 0.1371 +vn 0.8023 0.5923 0.0743 +vn 0.2354 -0.9719 -0.0000 +vn 0.0151 0.1372 0.9904 +vn 0.2030 -0.0431 0.9782 +vn 0.5731 -0.8195 -0.0000 +vn 0.8497 0.5237 -0.0613 +vn 0.0011 0.0739 0.9973 +vn 0.7097 -0.3554 0.6083 +vn 0.7918 -0.6108 -0.0000 +vn 0.4418 -0.8971 -0.0000 +vn 0.5204 -0.7336 0.4371 +vn 0.8265 0.5618 0.0369 +vn 0.0014 0.0740 0.9973 +vn 0.8390 0.5426 -0.0422 +vn -0.9801 -0.1985 -0.0000 +vn -0.0784 0.2386 0.9680 +vn -0.0387 0.6540 0.7555 +vn -0.3025 0.9531 -0.0000 +vn -0.7690 0.6393 -0.0000 +vn -0.3272 0.4252 0.8438 +vn -0.3280 0.5779 0.7473 +vn -0.6347 0.7728 -0.0000 +vn 0.8224 -0.2354 0.5180 +vn 0.6881 -0.2080 0.6952 +vn 0.9301 -0.3673 -0.0000 +vn 0.8774 -0.4797 -0.0000 +vn -0.6445 0.7646 -0.0000 +vn -0.3085 -0.6726 0.6726 +vn -0.0000 -0.7071 0.7071 +vn -0.7462 -0.6657 -0.0065 +vn -0.0602 -0.1746 0.9828 +vn 0.8482 -0.5296 -0.0000 +vn -0.6371 -0.5533 0.5367 +vn -0.0364 -0.0835 0.9958 +vn -0.8177 -0.5757 0.0075 +vn -0.0000 0.7382 0.6746 +vn 0.3019 0.9528 -0.0307 +vn -0.0000 0.0899 -0.9960 +vn -0.0000 0.1131 -0.9936 +vn 0.0008 -0.0001 -1.0000 +vn 0.8532 0.5211 -0.0229 +vn 0.0007 0.0919 -0.9958 +vn 0.0005 0.0737 -0.9973 +vn 0.8538 0.5192 0.0376 +vn 0.0376 0.9898 -0.1371 +vn 0.8023 0.5923 -0.0743 +vn 0.0151 0.1372 -0.9904 +vn 0.2030 -0.0431 -0.9782 +vn 0.8497 0.5237 0.0613 +vn 0.0011 0.0739 -0.9973 +vn 0.7097 -0.3554 -0.6083 +vn 0.5204 -0.7336 -0.4371 +vn 0.8265 0.5618 -0.0369 +vn 0.0014 0.0740 -0.9973 +vn 0.8390 0.5426 0.0422 +vn -0.0784 0.2386 -0.9680 +vn -0.0387 0.6540 -0.7555 +vn -0.3280 0.5779 -0.7473 +vn -0.3272 0.4252 -0.8438 +vn 0.6881 -0.2080 -0.6952 +vn 0.8224 -0.2354 -0.5180 +vn -0.3085 -0.6726 -0.6726 +vn -0.0000 -0.7071 -0.7071 +vn -0.7462 -0.6657 0.0065 +vn -0.0602 -0.1746 -0.9828 +vn -0.6371 -0.5533 -0.5367 +vn -0.0364 -0.0835 -0.9958 +vn -0.8177 -0.5757 -0.0075 +vn -0.0000 0.7382 -0.6746 +vn -0.0000 -0.5000 0.8660 +vn -0.0000 0.5000 0.8660 +vn -0.0000 -0.5000 -0.8660 +vn 0.0244 -0.4999 0.8658 +vn -0.0000 0.5000 -0.8660 +vn 0.0244 -0.4999 -0.8658 +vn 0.0244 0.4999 -0.8658 +vn 0.0244 0.4999 0.8658 +vn 0.0244 -0.9997 -0.0000 +vn 0.0244 0.9997 -0.0000 +vn -0.0000 0.7559 0.6547 +vn -0.0000 -0.9449 -0.3273 +vn -0.7738 -0.3167 0.5486 +vn -0.0000 -0.9449 0.3273 +vn -0.0000 0.7559 -0.6547 +vn -0.7738 -0.3167 -0.5486 +vn -0.0000 -0.7559 -0.6547 +vn -0.0000 0.9449 0.3273 +vn -0.7738 0.3167 -0.5486 +vn -0.0000 0.9449 -0.3273 +vn -0.0000 -0.7559 0.6547 +vn -0.7738 0.3167 0.5486 +vn -0.0000 -0.1890 0.9820 +vn -0.0000 -0.1890 -0.9820 +vn -0.7738 -0.6335 -0.0000 +vn -0.0000 0.1890 -0.9820 +vn -0.0000 0.1890 0.9820 +vn -0.7738 0.6335 -0.0000 +vn -0.4472 0.7746 -0.4472 +vn -0.4472 0.7746 0.4472 +vn -0.4472 -0.7746 0.4472 +vn -0.4472 -0.7746 -0.4472 +vn -0.4472 -0.0000 0.8944 +vn -0.4472 -0.0000 -0.8944 +vn -0.0000 0.8660 -0.5000 +vn -0.0000 0.8660 0.5000 +vn -0.0000 -0.8660 0.5000 +vn -0.0000 -0.8660 -0.5000 +vn -0.0000 -0.1951 -0.9808 +vn -0.0000 -0.3827 -0.9239 +vn -0.0000 -0.5556 -0.8315 +vn -0.0000 -0.8315 -0.5556 +vn -0.0000 -0.9239 -0.3827 +vn -0.0000 -0.9808 -0.1951 +vn -0.0000 -0.9808 0.1951 +vn -0.0000 -0.9239 0.3827 +vn -0.0000 -0.8315 0.5556 +vn -0.0000 -0.5556 0.8315 +vn -0.0000 -0.3827 0.9239 +vn -0.0000 -0.1951 0.9808 +vn -0.0000 0.1951 0.9808 +vn -0.0000 0.3827 0.9239 +vn -0.0000 0.5556 0.8315 +vn -0.0000 0.7071 0.7071 +vn -0.0000 0.8315 0.5556 +vn -0.0000 0.9239 0.3827 +vn -0.0000 0.9808 0.1951 +vn -0.0000 0.9808 -0.1951 +vn -0.0000 0.9239 -0.3827 +vn -0.0000 0.8315 -0.5556 +vn -0.0000 0.7071 -0.7071 +vn -0.0000 0.5556 -0.8315 +vn -0.0000 0.3827 -0.9239 +vn -0.0000 0.1951 -0.9808 +vn -0.0000 -0.8819 -0.4714 +vn -0.0000 -0.6344 -0.7730 +vn -0.0000 -0.7730 -0.6344 +vn -0.8407 -0.2058 0.5008 +vn -0.6984 -0.3388 0.6304 +vn -0.9990 -0.0440 -0.0000 +vn -0.9702 -0.2423 -0.0000 +vn 0.1843 0.0498 0.9816 +vn 0.2455 -0.1216 0.9617 +vn -0.2512 -0.1463 0.9568 +vn -0.2454 -0.0675 0.9671 +vn -0.2454 -0.0675 -0.9671 +vn -0.2512 -0.1463 -0.9568 +vn 0.2455 -0.1216 -0.9617 +vn 0.1843 0.0498 -0.9816 +vn 0.0008 -0.1450 -0.9894 +vn -0.6984 -0.3388 -0.6304 +vn -0.8407 -0.2058 -0.5008 +vn -0.2157 -0.1785 -0.9600 +vn 0.1737 0.1334 -0.9757 +vn 0.1737 0.1334 0.9757 +vn -0.2157 -0.1785 0.9600 +vn -0.1492 -0.2485 -0.9571 +vn 0.1157 0.2034 -0.9722 +vn 0.1157 0.2034 0.9722 +vn -0.1492 -0.2485 0.9571 +vn -0.0592 -0.2677 -0.9617 +vn 0.0493 0.2332 -0.9712 +vn 0.0493 0.2332 0.9712 +vn -0.0592 -0.2677 0.9617 +vn 0.0483 -0.2826 -0.9580 +vn -0.0335 0.2106 -0.9770 +vn -0.0335 0.2106 0.9770 +vn 0.0483 -0.2826 0.9580 +vn 0.1482 -0.2371 -0.9601 +vn -0.1273 0.2017 -0.9711 +vn -0.1273 0.2017 0.9711 +vn 0.1482 -0.2371 0.9601 +vn 0.1961 -0.2215 -0.9552 +vn -0.2006 0.1002 -0.9745 +vn -0.2006 0.1002 0.9745 +vn 0.1961 -0.2215 0.9552 +vn 0.2472 -0.3326 -0.9101 +vn -0.2576 -0.0964 -0.9614 +vn -0.2576 -0.0964 0.9614 +vn 0.2336 -0.2424 0.9416 +vn -0.0094 -0.0178 -0.9998 +vn -0.0094 -0.0178 0.9998 +vn -0.9808 0.1952 -0.0000 +vn -0.8341 0.5517 -0.0000 +vn -0.7458 0.6661 -0.0000 +vn -0.6606 0.5478 0.5132 +vn -0.6836 0.1605 0.7119 +vn -0.5321 0.8467 -0.0000 +vn -0.4539 0.7246 0.5187 +vn -0.6836 0.1606 -0.7119 +vn -0.6606 0.5478 -0.5132 +vn -0.4539 0.7246 -0.5187 +vn -0.1679 0.9858 -0.0000 +vn -0.1448 0.8261 0.5445 +vn -0.1448 0.8261 -0.5445 +vn 0.2111 0.9775 -0.0000 +vn 0.1828 0.8351 0.5187 +vn 0.1828 0.8351 -0.5187 +vn 0.4945 0.8692 -0.0000 +vn 0.4229 0.7402 0.5227 +vn 0.4229 0.7402 -0.5227 +vn 0.7672 0.6414 -0.0000 +vn 0.6404 0.5546 0.5313 +vn 0.6404 0.5546 -0.5313 +vn 0.9584 0.2854 -0.0000 +vn 0.7860 0.2435 0.5683 +vn 0.7860 0.2435 -0.5683 +vn 0.9982 0.0603 -0.0000 +vn 0.7135 -0.2644 0.6489 +vn 0.7135 -0.2644 -0.6489 +vn 0.8764 -0.4816 -0.0000 +vn -0.8311 -0.5561 -0.0000 +vn -0.8017 -0.5977 -0.0000 +vn -0.7061 -0.5142 -0.4869 +vn -0.7061 -0.5142 0.4869 +vn -0.5096 -0.8604 -0.0000 +vn -0.4479 -0.7582 -0.4739 +vn -0.4479 -0.7582 0.4739 +vn -0.2098 -0.9778 -0.0000 +vn -0.1818 -0.8544 -0.4867 +vn -0.1818 -0.8544 0.4867 +vn 0.1565 -0.9877 -0.0000 +vn 0.1355 -0.8690 -0.4758 +vn 0.1355 -0.8690 0.4758 +vn 0.5332 -0.8460 -0.0000 +vn 0.4680 -0.7408 -0.4820 +vn 0.4680 -0.7408 0.4820 +vn 0.7760 -0.6307 -0.0000 +vn 0.6738 -0.5715 -0.4684 +vn 0.6738 -0.5715 0.4684 +vn 0.8697 -0.4936 -0.0000 +vn 0.5753 -0.5840 -0.5727 +vn 0.7510 -0.4760 0.4576 +vn 0.8155 -0.5787 -0.0000 +vn -0.2923 -0.7176 0.6322 +vn -0.2923 -0.7176 -0.6322 +vn 0.2782 -0.6794 -0.6790 +vn 0.2782 -0.6794 0.6790 +vn -0.4548 -0.3799 0.8055 +vn -0.4548 -0.3799 -0.8055 +vn 0.3225 -0.6915 0.6463 +vn 0.3225 -0.6915 -0.6463 +vn 0.0008 -0.1450 0.9894 +vn 0.9189 0.3945 -0.0000 +vn -0.9189 0.3945 -0.0000 +vn 1.0000 0.0093 -0.0000 +vn 0.9754 -0.2205 -0.0000 +vn 0.9451 -0.3268 -0.0000 +vn 0.9873 -0.1589 -0.0000 +vn 0.9759 0.2181 -0.0000 +vn -1.0000 0.0093 -0.0000 +vn -0.9754 -0.2205 -0.0000 +vn -0.9451 -0.3268 -0.0000 +vn -0.9873 -0.1589 -0.0000 +vn -0.9759 0.2181 -0.0000 +vn 0.9754 -0.2206 -0.0000 +vn 0.9451 -0.3269 -0.0000 +vn 0.9759 0.2182 -0.0000 +vn -0.7118 0.7024 -0.0000 +vn 0.5547 -0.8320 -0.0000 +vn 0.5547 -0.8321 -0.0000 +vn -0.6579 -0.7531 -0.0000 +vn -0.0000 0.2035 0.9791 +vn -0.0000 0.2035 -0.9791 +vn -0.0000 -0.2899 0.9570 +vn -0.4193 0.9079 -0.0000 +vn -0.0514 -0.0197 -0.9985 +vn -0.0000 -0.2899 -0.9570 +vn -0.0514 -0.0197 0.9985 +vn 0.1213 -0.9926 -0.0000 +vn 0.9985 0.0550 -0.0000 +vn -0.0056 -0.0361 0.9993 +vn 0.7670 -0.6417 -0.0000 +vn -0.0056 -0.0361 -0.9993 +vn 0.9531 -0.3025 -0.0000 +vn -0.7670 -0.6417 -0.0000 +vn -0.0327 -0.0447 0.9985 +vn 0.6397 -0.7686 -0.0000 +vn -0.0327 -0.0447 -0.9985 +vn -0.9910 0.1339 -0.0000 +vn -0.8298 0.5580 -0.0000 +vn -0.5459 -0.6255 0.5575 +vn -0.5459 -0.6255 -0.5575 +vn 0.5237 -0.6163 -0.5882 +vn 0.5237 -0.6163 0.5882 +vn -0.7271 -0.0416 -0.6853 +vn -0.7271 -0.0416 0.6853 +vn -0.3187 0.5873 0.7440 +vn 0.6659 0.0001 0.7460 +vn 0.0549 -0.7343 -0.6766 +vn -0.7030 0.0003 -0.7112 +vn -0.7030 0.0003 0.7112 +vn -0.7077 0.0653 0.7035 +vn -0.6243 0.3603 0.6931 +vn 0.0549 -0.7343 0.6766 +vn 0.4457 -0.5823 0.6799 +vn 0.6451 -0.2288 0.7291 +vn 0.6659 0.0001 -0.7460 +vn 0.6451 -0.2288 -0.7291 +vn 0.4457 -0.5823 -0.6799 +vn -0.3187 0.5873 -0.7440 +vn -0.6243 0.3603 -0.6931 +vn -0.7077 0.0653 -0.7035 +vn -0.4619 -0.0000 0.8869 +vn -0.4619 -0.0000 -0.8869 +vn 0.4619 -0.0000 -0.8869 +vn 0.4619 -0.0000 0.8869 +vn -0.0526 -0.9986 -0.0000 +vn 0.8713 0.4908 -0.0000 +vn 0.7824 0.4391 -0.4416 +vn -0.0000 0.7116 0.7026 +vn 0.7824 0.4391 0.4416 +vn -0.0000 0.7116 -0.7026 +vn -0.7990 -0.6013 -0.0000 +vt 0.444828 0.128043 +vt 0.443550 0.111526 +vt 0.469839 0.105618 +vt 0.470844 0.124113 +vt 0.503434 0.119926 +vt 0.506431 0.100208 +vt 0.568903 0.076084 +vt 0.559714 0.102874 +vt 0.312172 0.567042 +vt 0.311197 0.529326 +vt 0.335799 0.563512 +vt 0.334223 0.587052 +vt 0.036099 0.431464 +vt 0.022645 0.430742 +vt 0.025162 0.424728 +vt 0.037872 0.425759 +vt 0.524852 0.024701 +vt 0.479097 0.027845 +vt 0.465961 0.009714 +vt 0.519466 0.008290 +vt 0.507469 0.068587 +vt 0.479948 0.072253 +vt 0.494415 0.042062 +vt 0.529897 0.038931 +vt 0.024632 0.457549 +vt 0.009152 0.458030 +vt 0.020039 0.436757 +vt 0.034225 0.437146 +vt 0.531088 0.259383 +vt 0.517272 0.219478 +vt 0.576712 0.209264 +vt 0.603741 0.247566 +vt 0.511663 0.199618 +vt 0.510109 0.179257 +vt 0.564322 0.170794 +vt 0.561368 0.191547 +vt 0.506266 0.139174 +vt 0.564223 0.127550 +vt 0.450780 0.271759 +vt 0.440808 0.231726 +vt 0.478629 0.226423 +vt 0.484605 0.267082 +vt 0.436663 0.211546 +vt 0.435266 0.190951 +vt 0.472898 0.185651 +vt 0.475776 0.206035 +vt 0.441790 0.148335 +vt 0.470207 0.144421 +vt 0.013825 0.572177 +vt 0.018257 0.528703 +vt 0.048336 0.528128 +vt 0.045337 0.572425 +vt 0.014892 0.591932 +vt 0.046219 0.592124 +vt 0.016199 0.653838 +vt 0.014863 0.611754 +vt 0.046350 0.612370 +vt 0.048177 0.654395 +vt 0.566186 0.576144 +vt 0.540406 0.575051 +vt 0.540917 0.546406 +vt 0.562925 0.547448 +vt 0.861752 0.427138 +vt 0.861951 0.405464 +vt 0.896984 0.405464 +vt 0.896225 0.420423 +vt 0.010868 0.504891 +vt 0.007524 0.479471 +vt 0.022741 0.478212 +vt 0.021966 0.502484 +vt 0.455718 0.033666 +vt 0.435266 0.000963 +vt 0.457497 0.078433 +vt 0.475372 0.047767 +vt 0.001989 0.653970 +vt 0.000963 0.612415 +vt 0.582020 0.167714 +vt 0.578024 0.188147 +vt 0.578049 0.124304 +vt 0.538423 0.686247 +vt 0.539173 0.644177 +vt 0.567665 0.644099 +vt 0.563118 0.685849 +vt 0.538058 0.706736 +vt 0.562669 0.706481 +vt 0.536968 0.767814 +vt 0.537695 0.727087 +vt 0.562303 0.726977 +vt 0.561575 0.767814 +vt 0.052010 0.458154 +vt 0.052010 0.438856 +vt 0.052010 0.433599 +vt 0.052010 0.428403 +vt 0.286594 0.556313 +vt 0.286594 0.522090 +vt 0.539538 0.623748 +vt 0.539842 0.606694 +vt 0.570467 0.607649 +vt 0.569551 0.624213 +vt 0.573095 0.098443 +vt 0.052010 0.502905 +vt 0.584903 0.207226 +vt 0.497951 0.222951 +vt 0.493720 0.202826 +vt 0.488236 0.141797 +vt 0.487139 0.122019 +vt 0.290428 0.684347 +vt 0.286594 0.590536 +vt 0.313147 0.604758 +vt 0.322406 0.689413 +vt 0.286594 0.684064 +vt 0.491503 0.182454 +vt 0.507846 0.263232 +vt 0.590157 0.051605 +vt 0.534004 0.065654 +vt 0.562924 0.032369 +vt 0.603284 0.028184 +vt 0.604982 0.021839 +vt 0.562115 0.021757 +vt 0.560029 0.010765 +vt 0.606320 0.015544 +vt 0.332646 0.610592 +vt 0.336615 0.684167 +vt 0.488135 0.102913 +vt 0.052010 0.477324 +vt 0.893788 0.359568 +vt 0.907964 0.347890 +vt 0.908633 0.372138 +vt 0.893788 0.379553 +vt 0.606289 0.837597 +vt 0.605101 0.855879 +vt 0.602468 0.854446 +vt 0.596853 0.839288 +vt 0.287026 0.889023 +vt 0.281452 0.867000 +vt 0.300064 0.867000 +vt 0.304719 0.888673 +vt 0.104983 0.442904 +vt 0.105669 0.442856 +vt 0.104983 0.424728 +vt 0.052010 0.502755 +vt 0.052010 0.528015 +vt 0.052010 0.572543 +vt 0.052010 0.592237 +vt 0.052010 0.612460 +vt 0.052010 0.484928 +vt 0.052010 0.654460 +vt 0.795354 0.429778 +vt 0.810348 0.430947 +vt 0.812221 0.510443 +vt 0.798966 0.506855 +vt 0.787723 0.513376 +vt 0.788908 0.459875 +vt 0.596758 0.400764 +vt 0.570742 0.396831 +vt 0.571747 0.378336 +vt 0.598037 0.384247 +vt 0.538152 0.392645 +vt 0.481872 0.375593 +vt 0.472683 0.348803 +vt 0.535155 0.372928 +vt 0.261017 0.567042 +vt 0.238966 0.587052 +vt 0.237390 0.563512 +vt 0.261992 0.529326 +vt 0.067921 0.431464 +vt 0.066149 0.425759 +vt 0.078859 0.424728 +vt 0.081375 0.430742 +vt 0.516734 0.297422 +vt 0.522120 0.281011 +vt 0.575625 0.282435 +vt 0.562489 0.300566 +vt 0.534117 0.341306 +vt 0.511689 0.311651 +vt 0.547172 0.314781 +vt 0.561638 0.344973 +vt 0.079388 0.457549 +vt 0.069796 0.437146 +vt 0.083981 0.436757 +vt 0.094868 0.458030 +vt 0.510498 0.532102 +vt 0.437845 0.520285 +vt 0.464875 0.481983 +vt 0.524314 0.492197 +vt 0.529923 0.472338 +vt 0.480218 0.464266 +vt 0.477264 0.443513 +vt 0.531478 0.451977 +vt 0.477363 0.400269 +vt 0.535321 0.411894 +vt 0.590806 0.544480 +vt 0.556981 0.539801 +vt 0.562957 0.499142 +vt 0.600778 0.504447 +vt 0.604923 0.484267 +vt 0.565810 0.478753 +vt 0.568688 0.458370 +vt 0.606320 0.463672 +vt 0.571379 0.417140 +vt 0.599796 0.421056 +vt 0.090196 0.572177 +vt 0.058683 0.572425 +vt 0.055684 0.528128 +vt 0.085763 0.528703 +vt 0.089128 0.591932 +vt 0.057801 0.592124 +vt 0.087822 0.653838 +vt 0.055844 0.654395 +vt 0.057670 0.612370 +vt 0.089157 0.611754 +vt 0.514604 0.575224 +vt 0.518886 0.546662 +vt 0.861752 0.383791 +vt 0.896225 0.390506 +vt 0.093153 0.504891 +vt 0.082054 0.502484 +vt 0.081279 0.478212 +vt 0.096496 0.479471 +vt 0.606320 0.273685 +vt 0.585868 0.306387 +vt 0.566215 0.320488 +vt 0.584089 0.351154 +vt 0.102031 0.653970 +vt 0.103057 0.612415 +vt 0.463562 0.460867 +vt 0.459566 0.440434 +vt 0.463537 0.397024 +vt 0.513758 0.684968 +vt 0.510702 0.643083 +vt 0.513471 0.705603 +vt 0.512377 0.766937 +vt 0.513106 0.726100 +vt 0.509527 0.623142 +vt 0.509202 0.606556 +vt 0.468491 0.371164 +vt 0.456683 0.479946 +vt 0.543636 0.495670 +vt 0.547866 0.475546 +vt 0.553350 0.414517 +vt 0.554447 0.394738 +vt 0.282761 0.684347 +vt 0.250783 0.689413 +vt 0.260042 0.604758 +vt 0.550083 0.455174 +vt 0.533740 0.535951 +vt 0.451429 0.324324 +vt 0.438302 0.300904 +vt 0.478662 0.305088 +vt 0.507582 0.338374 +vt 0.436604 0.294559 +vt 0.435266 0.288265 +vt 0.481557 0.283486 +vt 0.479471 0.294477 +vt 0.236574 0.684167 +vt 0.240543 0.610592 +vt 0.553451 0.375632 +vt 0.513511 0.928038 +vt 0.513511 0.948024 +vt 0.498666 0.940609 +vt 0.499335 0.916361 +vt 0.596853 0.823124 +vt 0.598826 0.820866 +vt 0.287026 0.844977 +vt 0.304719 0.845327 +vt 0.825263 0.429064 +vt 0.825263 0.506227 +vt 0.241886 0.128963 +vt 0.324189 0.144384 +vt 0.324189 0.445748 +vt 0.241886 0.397916 +vt 0.692448 0.097039 +vt 0.692448 0.000963 +vt 0.716041 0.000963 +vt 0.716041 0.097039 +vt 0.336407 0.458868 +vt 0.336407 0.458876 +vt 0.241815 0.403903 +vt 0.334668 0.785841 +vt 0.334668 0.691338 +vt 0.351479 0.691338 +vt 0.358262 0.703616 +vt 0.358262 0.785841 +vt 0.716041 0.518073 +vt 0.716041 0.397824 +vt 0.719559 0.403816 +vt 0.719559 0.518073 +vt 0.608250 0.457682 +vt 0.611763 0.463973 +vt 0.611763 0.516842 +vt 0.608245 0.516842 +vt 0.608245 0.457690 +vt 0.668383 0.518073 +vt 0.664865 0.518073 +vt 0.664865 0.403816 +vt 0.668383 0.397824 +vt 0.692448 0.518073 +vt 0.692448 0.397824 +vt 0.635356 0.451718 +vt 0.635357 0.516847 +vt 0.618547 0.451715 +vt 0.611727 0.445476 +vt 0.336615 0.146701 +vt 0.336615 0.452904 +vt 0.635356 0.000966 +vt 0.652638 0.000970 +vt 0.652638 0.110092 +vt 0.618547 0.110085 +vt 0.618547 0.000963 +vt 0.433270 0.128963 +vt 0.433270 0.397916 +vt 0.350966 0.445748 +vt 0.350966 0.144384 +vt 0.668383 0.097039 +vt 0.668383 0.000963 +vt 0.433341 0.403903 +vt 0.338748 0.458876 +vt 0.338748 0.458868 +vt 0.310603 0.785841 +vt 0.310603 0.703616 +vt 0.317387 0.691338 +vt 0.652638 0.451722 +vt 0.659422 0.463983 +vt 0.659422 0.516852 +vt 0.336407 0.518182 +vt 0.241815 0.518186 +vt 0.652638 0.146315 +vt 0.618547 0.146308 +vt 0.433341 0.518186 +vt 0.338748 0.518182 +vt 0.662934 0.457693 +vt 0.662939 0.457702 +vt 0.662939 0.516853 +vt 0.659386 0.445486 +vt 0.338541 0.146701 +vt 0.338541 0.452904 +vt 0.338541 0.110384 +vt 0.350966 0.108641 +vt 0.668383 0.128931 +vt 0.692448 0.128931 +vt 0.433270 0.097064 +vt 0.336615 0.110384 +vt 0.324189 0.108641 +vt 0.716041 0.128931 +vt 0.241886 0.097064 +vt 0.241886 0.000966 +vt 0.324189 0.000963 +vt 0.336615 0.000976 +vt 0.433270 0.000966 +vt 0.350966 0.000963 +vt 0.338541 0.000976 +vt 0.081619 0.874066 +vt 0.058026 0.874066 +vt 0.058026 0.872056 +vt 0.081619 0.872056 +vt 0.635351 0.518961 +vt 0.611758 0.518956 +vt 0.334454 0.520160 +vt 0.243812 0.520164 +vt 0.609330 0.518955 +vt 0.054508 0.874066 +vt 0.055599 0.872056 +vt 0.105684 0.872056 +vt 0.105684 0.874066 +vt 0.659416 0.518966 +vt 0.431343 0.520164 +vt 0.340702 0.520160 +vt 0.661843 0.518966 +vt 0.108112 0.872056 +vt 0.109202 0.874066 +vt 0.055599 0.781409 +vt 0.058026 0.781409 +vt 0.081619 0.781409 +vt 0.105684 0.781409 +vt 0.108112 0.781409 +vt 0.639965 0.737665 +vt 0.639965 0.727823 +vt 0.654608 0.727823 +vt 0.654608 0.737665 +vt 0.587061 0.789958 +vt 0.587063 0.806569 +vt 0.572420 0.806568 +vt 0.572418 0.789957 +vt 0.165649 0.108951 +vt 0.200771 0.104539 +vt 0.209265 0.175161 +vt 0.179131 0.178946 +vt 0.173246 0.169451 +vt 0.169447 0.139201 +vt 0.383420 0.912402 +vt 0.361330 0.912448 +vt 0.361330 0.854709 +vt 0.383366 0.854663 +vt 0.788621 0.765082 +vt 0.809104 0.765085 +vt 0.809104 0.793428 +vt 0.788621 0.793425 +vt 0.639965 0.770322 +vt 0.658330 0.770322 +vt 0.846906 0.205126 +vt 0.846906 0.000963 +vt 0.861549 0.000963 +vt 0.861549 0.205126 +vt 0.587040 0.586281 +vt 0.572397 0.586279 +vt 0.809104 0.560876 +vt 0.818955 0.560876 +vt 0.818955 0.765085 +vt 0.809104 0.520899 +vt 0.818955 0.520898 +vt 0.587036 0.546407 +vt 0.572392 0.546406 +vt 0.764260 0.531161 +vt 0.748605 0.531161 +vt 0.748605 0.523828 +vt 0.763537 0.523828 +vt 0.776340 0.520892 +vt 0.776340 0.560870 +vt 0.152000 0.784068 +vt 0.152000 0.763642 +vt 0.166643 0.763642 +vt 0.168489 0.784068 +vt 0.393049 0.811506 +vt 0.393049 0.852737 +vt 0.367240 0.852737 +vt 0.370962 0.811506 +vt 0.846690 0.520898 +vt 0.846690 0.724575 +vt 0.820881 0.724570 +vt 0.820881 0.520892 +vt 0.393049 0.729043 +vt 0.393049 0.761733 +vt 0.374684 0.761733 +vt 0.378406 0.729043 +vt 0.393049 0.801499 +vt 0.371710 0.801499 +vt 0.697858 0.777338 +vt 0.697858 0.817212 +vt 0.691948 0.817211 +vt 0.691948 0.777337 +vt 0.361330 0.852737 +vt 0.365052 0.811506 +vt 0.173043 0.043570 +vt 0.197501 0.035082 +vt 0.639965 0.796304 +vt 0.656093 0.799251 +vt 0.449388 0.773202 +vt 0.451234 0.752755 +vt 0.465877 0.752755 +vt 0.465877 0.773202 +vt 0.818955 0.781739 +vt 0.234710 0.377778 +vt 0.238242 0.405901 +vt 0.208108 0.409686 +vt 0.499337 0.860528 +vt 0.498665 0.821019 +vt 0.570467 0.819585 +vt 0.570467 0.860890 +vt 0.514576 0.795383 +vt 0.530487 0.769746 +vt 0.570465 0.769740 +vt 0.570466 0.794663 +vt 0.665775 0.862361 +vt 0.662052 0.822997 +vt 0.667962 0.822997 +vt 0.671684 0.862361 +vt 0.365801 0.801499 +vt 0.426694 0.800164 +vt 0.426694 0.729043 +vt 0.432604 0.729043 +vt 0.432604 0.800164 +vt 0.664240 0.770322 +vt 0.666101 0.796659 +vt 0.810737 0.874637 +vt 0.810514 0.900411 +vt 0.776340 0.893438 +vt 0.776340 0.874656 +vt 0.348217 0.881761 +vt 0.358402 0.881761 +vt 0.357691 0.903795 +vt 0.341997 0.907517 +vt 0.052582 0.885726 +vt 0.026773 0.885726 +vt 0.026773 0.821461 +vt 0.052529 0.821461 +vt 0.239889 0.098956 +vt 0.213885 0.042510 +vt 0.195647 0.000963 +vt 0.026773 0.781409 +vt 0.045554 0.781409 +vt 0.657206 0.814999 +vt 0.667214 0.812407 +vt 0.372823 0.786619 +vt 0.366913 0.786619 +vt 0.368775 0.761733 +vt 0.505063 0.810711 +vt 0.570466 0.809564 +vt 0.650012 0.782413 +vt 0.639965 0.781148 +vt 0.639965 0.774032 +vt 0.646416 0.774060 +vt 0.393049 0.786619 +vt 0.639965 0.822286 +vt 0.639965 0.811839 +vt 0.111128 0.860040 +vt 0.115528 0.860040 +vt 0.116379 0.866491 +vt 0.111706 0.866491 +vt 0.683095 0.911127 +vt 0.678846 0.915098 +vt 0.677539 0.903811 +vt 0.673610 0.901280 +vt 0.563122 0.927244 +vt 0.563119 0.936928 +vt 0.549618 0.933697 +vt 0.550467 0.927245 +vt 0.915049 0.155244 +vt 0.912126 0.139116 +vt 0.929682 0.142341 +vt 0.932589 0.155244 +vt 0.572811 0.927258 +vt 0.572832 0.940169 +vt 0.689909 0.943840 +vt 0.673610 0.951573 +vt 0.679202 0.929108 +vt 0.687699 0.921167 +vt 0.639965 0.792086 +vt 0.653609 0.793537 +vt 0.587036 0.818938 +vt 0.572392 0.818937 +vt 0.764260 0.763661 +vt 0.748605 0.763661 +vt 0.774415 0.530945 +vt 0.774415 0.520892 +vt 0.774415 0.763445 +vt 0.239889 0.419016 +vt 0.209755 0.422802 +vt 0.152000 0.887211 +vt 0.177810 0.887211 +vt 0.440067 0.876449 +vt 0.435266 0.876449 +vt 0.444356 0.775757 +vt 0.447153 0.773202 +vt 0.170724 0.784068 +vt 0.173521 0.786621 +vt 0.182611 0.887211 +vt 0.116167 0.823210 +vt 0.116167 0.851480 +vt 0.113933 0.851479 +vt 0.113933 0.823210 +vt 0.547693 0.888625 +vt 0.547693 0.910374 +vt 0.525504 0.910374 +vt 0.522746 0.888625 +vt 0.160470 0.169736 +vt 0.145518 0.161850 +vt 0.608245 0.890096 +vt 0.608245 0.864286 +vt 0.655236 0.868347 +vt 0.655236 0.890096 +vt 0.498666 0.914435 +vt 0.503987 0.904280 +vt 0.505967 0.903557 +vt 0.511484 0.910374 +vt 0.121389 0.145042 +vt 0.505967 0.888625 +vt 0.465877 0.876449 +vt 0.812663 0.877236 +vt 0.812663 0.848899 +vt 0.817464 0.848899 +vt 0.817464 0.877236 +vt 0.111128 0.851663 +vt 0.111128 0.823394 +vt 0.212880 0.864511 +vt 0.184536 0.864515 +vt 0.184536 0.763646 +vt 0.212880 0.763642 +vt 0.816865 0.836819 +vt 0.806713 0.846974 +vt 0.776340 0.846974 +vt 0.776340 0.821164 +vt 0.816865 0.821164 +vt 0.774415 0.776661 +vt 0.764260 0.776877 +vt 0.940603 0.492056 +vt 0.940603 0.466246 +vt 0.953787 0.466243 +vt 0.953787 0.492053 +vt 0.748605 0.776877 +vt 0.625322 0.737665 +vt 0.625322 0.727823 +vt 0.601704 0.789960 +vt 0.601706 0.806571 +vt 0.075203 0.108951 +vt 0.071404 0.139201 +vt 0.067605 0.169451 +vt 0.061721 0.178946 +vt 0.031587 0.175161 +vt 0.040080 0.104539 +vt 0.405398 0.854719 +vt 0.405505 0.912458 +vt 0.818057 0.245153 +vt 0.818057 0.273496 +vt 0.797574 0.273499 +vt 0.797574 0.245156 +vt 0.621599 0.770322 +vt 0.832263 0.205126 +vt 0.832263 0.000963 +vt 0.601683 0.586282 +vt 0.797574 0.040947 +vt 0.787723 0.245155 +vt 0.787723 0.040946 +vt 0.797574 0.000969 +vt 0.787723 0.000969 +vt 0.601679 0.546409 +vt 0.732949 0.531161 +vt 0.733673 0.523828 +vt 0.830337 0.000963 +vt 0.830337 0.040940 +vt 0.135511 0.784068 +vt 0.137357 0.763642 +vt 0.415137 0.811506 +vt 0.418859 0.852737 +vt 0.872500 0.520903 +vt 0.872500 0.724581 +vt 0.407693 0.729043 +vt 0.411415 0.761733 +vt 0.414389 0.801499 +vt 0.111128 0.781409 +vt 0.117038 0.781411 +vt 0.117038 0.821284 +vt 0.111128 0.821283 +vt 0.421047 0.811506 +vt 0.424769 0.852737 +vt 0.043351 0.035082 +vt 0.067808 0.043570 +vt 0.623837 0.799251 +vt 0.482366 0.773202 +vt 0.480520 0.752755 +vt 0.787723 0.261810 +vt 0.032744 0.409686 +vt 0.002610 0.405901 +vt 0.006142 0.377778 +vt 0.773743 0.869590 +vt 0.702614 0.869952 +vt 0.702614 0.828648 +vt 0.774415 0.830082 +vt 0.758504 0.804445 +vt 0.702614 0.803725 +vt 0.702615 0.778803 +vt 0.742593 0.778809 +vt 0.614155 0.862361 +vt 0.608245 0.862361 +vt 0.611968 0.822997 +vt 0.617877 0.822997 +vt 0.420298 0.801499 +vt 0.231741 0.834763 +vt 0.225832 0.834763 +vt 0.225832 0.763642 +vt 0.231741 0.763642 +vt 0.613829 0.796659 +vt 0.615690 0.770322 +vt 0.776340 0.855874 +vt 0.810514 0.848899 +vt 0.341997 0.856005 +vt 0.357691 0.859727 +vt 0.000963 0.885726 +vt 0.001016 0.821461 +vt 0.000963 0.098956 +vt 0.026967 0.042510 +vt 0.045205 0.000963 +vt 0.007991 0.781410 +vt 0.622724 0.814999 +vt 0.612716 0.812407 +vt 0.417324 0.761733 +vt 0.419185 0.786619 +vt 0.413276 0.786619 +vt 0.768017 0.819774 +vt 0.702614 0.818627 +vt 0.629917 0.782413 +vt 0.633514 0.774060 +vt 0.111706 0.853589 +vt 0.116379 0.853589 +vt 0.783155 0.912184 +vt 0.792640 0.902337 +vt 0.788710 0.904868 +vt 0.787403 0.916155 +vt 0.549618 0.920795 +vt 0.563119 0.917575 +vt 0.929682 0.168146 +vt 0.912126 0.171372 +vt 0.572832 0.914364 +vt 0.776340 0.944896 +vt 0.778550 0.922224 +vt 0.787047 0.930165 +vt 0.792640 0.952630 +vt 0.626320 0.793537 +vt 0.601679 0.818940 +vt 0.732949 0.763661 +vt 0.722795 0.530945 +vt 0.722795 0.520892 +vt 0.722795 0.763445 +vt 0.031097 0.422802 +vt 0.000963 0.419016 +vt 0.126190 0.887211 +vt 0.484601 0.773202 +vt 0.487398 0.775757 +vt 0.496488 0.876449 +vt 0.491687 0.876449 +vt 0.121389 0.887211 +vt 0.130479 0.786621 +vt 0.133276 0.784068 +vt 0.225832 0.836689 +vt 0.228066 0.836689 +vt 0.228066 0.864959 +vt 0.225832 0.864958 +vt 0.525504 0.866876 +vt 0.547693 0.866876 +vt 0.095334 0.161850 +vt 0.080383 0.169736 +vt 0.655236 0.911845 +vt 0.608245 0.915906 +vt 0.498666 0.862815 +vt 0.511484 0.866876 +vt 0.505967 0.873693 +vt 0.503987 0.872970 +vt 0.119463 0.145042 +vt 0.431687 0.882999 +vt 0.426886 0.882999 +vt 0.426886 0.854663 +vt 0.431687 0.854663 +vt 0.230856 0.836874 +vt 0.230856 0.865144 +vt 0.310603 0.888635 +vt 0.310603 0.787766 +vt 0.338946 0.787771 +vt 0.338946 0.888639 +vt 0.816865 0.805508 +vt 0.776340 0.795354 +vt 0.806713 0.795354 +vt 0.732949 0.776877 +vt 0.722795 0.776661 +vt 0.940603 0.440436 +vt 0.953787 0.440434 +vt 0.429854 0.538967 +vt 0.429854 0.522090 +vt 0.408175 0.522090 +vt 0.408175 0.545939 +vt 0.422879 0.545939 +vt 0.503772 0.563256 +vt 0.503772 0.546419 +vt 0.482093 0.546415 +vt 0.482093 0.570207 +vt 0.496798 0.570210 +vt 0.121389 0.612852 +vt 0.121390 0.629732 +vt 0.140378 0.629710 +vt 0.140377 0.605855 +vt 0.127497 0.605870 +vt 0.178354 0.612784 +vt 0.178355 0.629665 +vt 0.196907 0.629687 +vt 0.196906 0.605833 +vt 0.184322 0.605817 +vt 0.665213 0.537840 +vt 0.665214 0.520960 +vt 0.646225 0.520937 +vt 0.646224 0.544792 +vt 0.659104 0.544807 +vt 0.234031 0.664180 +vt 0.215257 0.653339 +vt 0.196484 0.642499 +vt 0.177710 0.631658 +vt 0.158936 0.642494 +vt 0.140163 0.653329 +vt 0.121389 0.664165 +vt 0.121389 0.685842 +vt 0.121389 0.707518 +vt 0.121389 0.729194 +vt 0.140163 0.740035 +vt 0.158936 0.750875 +vt 0.177710 0.761716 +vt 0.196484 0.750880 +vt 0.215257 0.740044 +vt 0.234031 0.729209 +vt 0.234031 0.707532 +vt 0.234031 0.685856 +vt 0.460414 0.570203 +vt 0.460414 0.546410 +vt 0.438736 0.546406 +vt 0.438736 0.563242 +vt 0.445710 0.570200 +vt 0.159366 0.629687 +vt 0.159365 0.605833 +vt 0.910200 0.172495 +vt 0.908790 0.001061 +vt 0.893788 0.000963 +vt 0.893788 0.172388 +vt 0.052584 0.658103 +vt 0.041012 0.671091 +vt 0.073429 0.671091 +vt 0.061858 0.658103 +vt 0.683757 0.725882 +vt 0.683765 0.544792 +vt 0.671181 0.544807 +vt 0.671174 0.725897 +vt 0.683766 0.520937 +vt 0.627235 0.520915 +vt 0.627234 0.544769 +vt 0.690022 0.899248 +vt 0.690022 0.727823 +vt 0.675019 0.727920 +vt 0.673610 0.899355 +vt 0.105846 0.727304 +vt 0.089638 0.755410 +vt 0.106658 0.751871 +vt 0.111295 0.743830 +vt 0.386496 0.726988 +vt 0.386496 0.545939 +vt 0.371792 0.545939 +vt 0.371792 0.726988 +vt 0.386496 0.522090 +vt 0.364817 0.522090 +vt 0.364817 0.538967 +vt 0.702317 0.544769 +vt 0.702318 0.520915 +vt 0.893881 0.520892 +vt 0.895258 0.692328 +vt 0.909916 0.692436 +vt 0.909916 0.521010 +vt 0.061858 0.777766 +vt 0.073429 0.764779 +vt 0.041012 0.764779 +vt 0.052584 0.777766 +vt 0.159358 0.424743 +vt 0.172245 0.605817 +vt 0.172237 0.424728 +vt 0.215460 0.629710 +vt 0.215459 0.605855 +vt 0.893788 0.174538 +vt 0.893788 0.345964 +vt 0.908446 0.345857 +vt 0.909824 0.174420 +vt 0.008595 0.708566 +vt 0.003146 0.692039 +vt 0.000963 0.692391 +vt 0.000963 0.707095 +vt 0.627227 0.725859 +vt 0.614354 0.544754 +vt 0.614347 0.725844 +vt 0.608246 0.520892 +vt 0.608245 0.537772 +vt 0.860282 0.897773 +vt 0.859453 0.726507 +vt 0.842325 0.726507 +vt 0.841544 0.897773 +vt 0.106658 0.683998 +vt 0.089638 0.680459 +vt 0.105846 0.708566 +vt 0.111295 0.692039 +vt 0.215452 0.424765 +vt 0.228043 0.605870 +vt 0.228036 0.424781 +vt 0.234013 0.629732 +vt 0.234012 0.612852 +vt 0.839618 0.897790 +vt 0.838814 0.726507 +vt 0.821685 0.726507 +vt 0.820881 0.897790 +vt 0.024804 0.755410 +vt 0.007783 0.751871 +vt 0.006996 0.753940 +vt 0.019716 0.761292 +vt 0.460415 0.750821 +vt 0.445710 0.750818 +vt 0.941969 0.355361 +vt 0.947851 0.355469 +vt 0.947851 0.174420 +vt 0.938751 0.183929 +vt 0.943715 0.713282 +vt 0.932328 0.703911 +vt 0.932328 0.884530 +vt 0.939688 0.884347 +vt 0.070264 0.941574 +vt 0.082316 0.944238 +vt 0.082316 0.922578 +vt 0.070264 0.924460 +vt 0.936745 0.701325 +vt 0.944090 0.701511 +vt 0.944090 0.520892 +vt 0.932726 0.530259 +vt 0.223906 0.773150 +vt 0.214805 0.763642 +vt 0.214805 0.944691 +vt 0.220687 0.944582 +vt 0.028771 0.935585 +vt 0.016719 0.933703 +vt 0.016719 0.955363 +vt 0.028771 0.952699 +vt 0.866603 0.907491 +vt 0.872500 0.907125 +vt 0.872500 0.726506 +vt 0.863376 0.736726 +vt 0.930402 0.713671 +vt 0.919026 0.703911 +vt 0.919026 0.884960 +vt 0.926379 0.885014 +vt 0.957602 0.676038 +vt 0.946016 0.674180 +vt 0.946016 0.695840 +vt 0.957602 0.693152 +vt 0.929472 0.355524 +vt 0.936825 0.355469 +vt 0.936825 0.174420 +vt 0.925449 0.184181 +vt 0.954719 0.714135 +vt 0.945641 0.703911 +vt 0.945641 0.884530 +vt 0.951508 0.884898 +vt 0.718370 0.940087 +vt 0.729955 0.942775 +vt 0.729955 0.921115 +vt 0.718370 0.922973 +vt 0.898077 0.875454 +vt 0.905747 0.875452 +vt 0.905747 0.694362 +vt 0.893881 0.704044 +vt 0.119463 0.434410 +vt 0.107598 0.424728 +vt 0.107598 0.605817 +vt 0.115267 0.605820 +vt 0.592675 0.933768 +vt 0.604949 0.936043 +vt 0.604949 0.914364 +vt 0.592675 0.916640 +vt 0.923190 0.701985 +vt 0.930800 0.701982 +vt 0.930800 0.520892 +vt 0.919026 0.530576 +vt 0.923523 0.184104 +vt 0.911749 0.174420 +vt 0.911749 0.355510 +vt 0.919359 0.355514 +vt 0.957622 0.360150 +vt 0.946279 0.357874 +vt 0.946279 0.379553 +vt 0.957622 0.377278 +vt 0.051188 0.656386 +vt 0.038468 0.663738 +vt 0.659096 0.725897 +vt 0.646216 0.725882 +vt 0.008595 0.727304 +vt 0.003146 0.743830 +vt 0.000963 0.728774 +vt 0.000963 0.743479 +vt 0.075973 0.772132 +vt 0.063254 0.779484 +vt 0.007783 0.683998 +vt 0.024804 0.680459 +vt 0.019716 0.674577 +vt 0.006996 0.681929 +vt 0.714892 0.725844 +vt 0.714900 0.544754 +vt 0.702309 0.725859 +vt 0.496798 0.750829 +vt 0.482093 0.750826 +vt 0.720869 0.537772 +vt 0.720869 0.520892 +vt 0.127490 0.424781 +vt 0.140369 0.424765 +vt 0.113479 0.743479 +vt 0.113479 0.728774 +vt 0.094726 0.761292 +vt 0.107446 0.753940 +vt 0.094726 0.674577 +vt 0.107446 0.681929 +vt 0.075973 0.663738 +vt 0.063254 0.656386 +vt 0.422879 0.726988 +vt 0.408175 0.726988 +vt 0.184315 0.424728 +vt 0.196899 0.424743 +vt 0.113479 0.707095 +vt 0.113479 0.692391 +vt 0.051188 0.779484 +vt 0.361330 0.546068 +vt 0.433341 0.546068 +vt 0.435266 0.569762 +vt 0.507276 0.569777 +vt 0.361330 0.727117 +vt 0.433341 0.727117 +vt 0.435266 0.750380 +vt 0.507276 0.750395 +vt 0.038468 0.772132 +vt 0.342012 0.927216 +vt 0.359298 0.927216 +vt 0.359297 0.932069 +vt 0.342011 0.932070 +vt 0.359294 0.936716 +vt 0.342008 0.936717 +vt 0.359290 0.940980 +vt 0.342003 0.940980 +vt 0.359283 0.944695 +vt 0.341997 0.944695 +vt 0.236729 0.911284 +vt 0.254012 0.911284 +vt 0.253946 0.915062 +vt 0.236663 0.915062 +vt 0.253897 0.919372 +vt 0.236614 0.919372 +vt 0.253866 0.924049 +vt 0.236584 0.924049 +vt 0.253856 0.928913 +vt 0.236574 0.928913 +vt 0.253866 0.933777 +vt 0.236584 0.933777 +vt 0.253897 0.938454 +vt 0.236614 0.938454 +vt 0.253946 0.942764 +vt 0.236663 0.942764 +vt 0.254012 0.946543 +vt 0.236729 0.946543 +vt 0.273239 0.946536 +vt 0.255953 0.946535 +vt 0.255946 0.942821 +vt 0.273232 0.942821 +vt 0.255941 0.938558 +vt 0.273228 0.938558 +vt 0.255938 0.933910 +vt 0.273225 0.933911 +vt 0.255937 0.929057 +vt 0.273224 0.929058 +vt 0.255938 0.924184 +vt 0.273225 0.924185 +vt 0.255941 0.919480 +vt 0.273228 0.919480 +vt 0.255946 0.915124 +vt 0.273232 0.915124 +vt 0.255953 0.911284 +vt 0.273239 0.911285 +vt 0.425199 0.946272 +vt 0.407958 0.946276 +vt 0.407734 0.942489 +vt 0.424975 0.942485 +vt 0.407568 0.938172 +vt 0.424809 0.938168 +vt 0.407466 0.933491 +vt 0.424707 0.933487 +vt 0.407431 0.928626 +vt 0.424672 0.928622 +vt 0.407466 0.923763 +vt 0.424707 0.923759 +vt 0.407568 0.919090 +vt 0.424809 0.919086 +vt 0.407734 0.914786 +vt 0.424975 0.914783 +vt 0.407958 0.911017 +vt 0.425199 0.911014 +vt 0.341997 0.909444 +vt 0.359283 0.909443 +vt 0.359290 0.913283 +vt 0.342003 0.913283 +vt 0.359294 0.917638 +vt 0.342008 0.917639 +vt 0.359297 0.922343 +vt 0.342011 0.922344 +vt 0.856743 0.254410 +vt 0.853391 0.254372 +vt 0.853391 0.207083 +vt 0.856743 0.207121 +vt 0.572527 0.906921 +vt 0.576326 0.906921 +vt 0.576870 0.912439 +vt 0.571983 0.912439 +vt 0.568800 0.906179 +vt 0.567190 0.911485 +vt 0.565289 0.904725 +vt 0.562676 0.909615 +vt 0.562129 0.902613 +vt 0.558612 0.906899 +vt 0.559442 0.899926 +vt 0.555157 0.903443 +vt 0.557331 0.896766 +vt 0.552442 0.899379 +vt 0.555877 0.893254 +vt 0.550572 0.894864 +vt 0.555136 0.889527 +vt 0.549618 0.890070 +vt 0.555135 0.885726 +vt 0.549618 0.885183 +vt 0.555877 0.881999 +vt 0.550572 0.880389 +vt 0.557331 0.878488 +vt 0.552442 0.875874 +vt 0.559442 0.875328 +vt 0.555157 0.871810 +vt 0.562129 0.872640 +vt 0.558612 0.868354 +vt 0.565289 0.870529 +vt 0.562675 0.865639 +vt 0.568799 0.869075 +vt 0.567190 0.863769 +vt 0.572526 0.868333 +vt 0.571983 0.862815 +vt 0.576326 0.868333 +vt 0.576870 0.862815 +vt 0.580053 0.869075 +vt 0.581663 0.863769 +vt 0.583564 0.870529 +vt 0.586177 0.865640 +vt 0.586724 0.872641 +vt 0.590241 0.868355 +vt 0.589411 0.875328 +vt 0.593696 0.871811 +vt 0.591522 0.878488 +vt 0.596411 0.875875 +vt 0.592976 0.882000 +vt 0.598281 0.880390 +vt 0.593717 0.885727 +vt 0.599234 0.885184 +vt 0.593717 0.889528 +vt 0.599234 0.890071 +vt 0.592976 0.893255 +vt 0.598281 0.894865 +vt 0.591522 0.896766 +vt 0.596411 0.899380 +vt 0.589411 0.899926 +vt 0.593696 0.903444 +vt 0.586724 0.902614 +vt 0.590241 0.906900 +vt 0.583564 0.904725 +vt 0.586178 0.909615 +vt 0.580053 0.906179 +vt 0.581663 0.911485 +vt 0.705640 0.775411 +vt 0.701859 0.775384 +vt 0.701859 0.728208 +vt 0.705640 0.728235 +vt 0.849754 0.254348 +vt 0.849754 0.207060 +vt 0.698225 0.775303 +vt 0.698225 0.728127 +vt 0.845972 0.254340 +vt 0.845972 0.207052 +vt 0.694879 0.775173 +vt 0.694879 0.727997 +vt 0.842189 0.254348 +vt 0.842189 0.207060 +vt 0.691948 0.774999 +vt 0.691948 0.727823 +vt 0.838552 0.254372 +vt 0.838552 0.207083 +vt 0.211948 0.913741 +vt 0.208963 0.913746 +vt 0.208963 0.866447 +vt 0.211948 0.866442 +vt 0.835201 0.254410 +vt 0.835201 0.207121 +vt 0.205576 0.913750 +vt 0.205576 0.866451 +vt 0.716434 0.919189 +vt 0.712645 0.919188 +vt 0.712645 0.871889 +vt 0.716434 0.871890 +vt 0.832263 0.254461 +vt 0.832263 0.207173 +vt 0.201917 0.913752 +vt 0.201917 0.866453 +vt 0.708987 0.919186 +vt 0.708987 0.871887 +vt 0.730026 0.919177 +vt 0.727137 0.919182 +vt 0.727137 0.871883 +vt 0.730026 0.871877 +vt 0.198128 0.913753 +vt 0.198128 0.866453 +vt 0.705599 0.919183 +vt 0.705599 0.871884 +vt 0.723822 0.919186 +vt 0.723822 0.871887 +vt 0.194354 0.913752 +vt 0.194354 0.866452 +vt 0.702614 0.919178 +vt 0.702614 0.871879 +vt 0.720208 0.919188 +vt 0.720208 0.871889 +vt 0.190740 0.913749 +vt 0.190740 0.866450 +vt 0.719366 0.775005 +vt 0.716421 0.775178 +vt 0.716421 0.728002 +vt 0.719366 0.727829 +vt 0.187425 0.913745 +vt 0.187425 0.866446 +vt 0.713064 0.775307 +vt 0.713064 0.728130 +vt 0.184536 0.913740 +vt 0.184536 0.866441 +vt 0.709424 0.775385 +vt 0.709424 0.728209 +vt 0.859680 0.254461 +vt 0.859680 0.207173 +vt 0.035870 0.921356 +vt 0.035869 0.905938 +vt 0.040360 0.905938 +vt 0.040360 0.921356 +vt 0.822221 0.303520 +vt 0.807773 0.299659 +vt 0.809098 0.293860 +vt 0.823899 0.297590 +vt 0.390864 0.914386 +vt 0.390864 0.948315 +vt 0.382254 0.948313 +vt 0.382254 0.914384 +vt 0.399474 0.914387 +vt 0.399474 0.948317 +vt 0.272501 0.713504 +vt 0.287302 0.709774 +vt 0.288627 0.715573 +vt 0.274178 0.719434 +vt 0.288466 0.704926 +vt 0.301852 0.691338 +vt 0.308678 0.724664 +vt 0.291828 0.719414 +vt 0.044850 0.905938 +vt 0.044850 0.921356 +vt 0.256301 0.725805 +vt 0.259452 0.732303 +vt 0.836948 0.316390 +vt 0.840099 0.309892 +vt 0.242810 0.748755 +vt 0.249449 0.750735 +vt 0.846951 0.334821 +vt 0.853590 0.332842 +vt 0.239171 0.776349 +vt 0.245989 0.775820 +vt 0.850411 0.359907 +vt 0.857228 0.360435 +vt 0.242154 0.802293 +vt 0.248774 0.800341 +vt 0.847626 0.384427 +vt 0.854246 0.386380 +vt 0.252814 0.817693 +vt 0.257668 0.812649 +vt 0.838732 0.396736 +vt 0.843586 0.401779 +vt 0.266087 0.827708 +vt 0.268961 0.821640 +vt 0.827439 0.405727 +vt 0.830313 0.411794 +vt 0.280997 0.832579 +vt 0.280425 0.826252 +vt 0.815975 0.410339 +vt 0.815403 0.416666 +vt 0.298491 0.843051 +vt 0.283720 0.836533 +vt 0.282853 0.823300 +vt 0.308678 0.823160 +vt 0.787723 0.407247 +vt 0.813547 0.407386 +vt 0.812680 0.420619 +vt 0.797910 0.427138 +vt 0.582754 0.914364 +vt 0.582754 0.942248 +vt 0.576721 0.942248 +vt 0.575177 0.939614 +vt 0.574758 0.914364 +vt 0.582754 0.951218 +vt 0.578273 0.951218 +vt 0.661702 0.864289 +vt 0.661672 0.875310 +vt 0.657189 0.875308 +vt 0.657220 0.864287 +vt 0.588786 0.942248 +vt 0.587235 0.951218 +vt 0.590750 0.914364 +vt 0.590330 0.939614 +vt 0.666183 0.864292 +vt 0.666156 0.875313 +vt 0.661651 0.888294 +vt 0.657166 0.888292 +vt 0.666136 0.888297 +vt 0.661649 0.912108 +vt 0.657162 0.912106 +vt 0.666135 0.912111 +vt 0.661664 0.934471 +vt 0.657177 0.934468 +vt 0.666152 0.934473 +vt 0.661694 0.947908 +vt 0.657206 0.947905 +vt 0.666183 0.947910 +vt 0.290062 0.939995 +vt 0.290062 0.923058 +vt 0.294551 0.923058 +vt 0.294550 0.939995 +vt 0.285574 0.939995 +vt 0.285574 0.923058 +vt 0.290062 0.908261 +vt 0.294551 0.908261 +vt 0.285574 0.908261 +vt 0.290062 0.890949 +vt 0.298672 0.890949 +vt 0.296382 0.906024 +vt 0.283742 0.906024 +vt 0.281452 0.890949 +vt 0.040360 0.887652 +vt 0.048970 0.887652 +vt 0.046658 0.903723 +vt 0.040360 0.940354 +vt 0.044850 0.940354 +vt 0.034061 0.903723 +vt 0.031750 0.887652 +vt 0.035870 0.940354 +vt 0.934187 0.468526 +vt 0.934187 0.489529 +vt 0.929697 0.489529 +vt 0.929697 0.468526 +vt 0.938677 0.468526 +vt 0.938677 0.489529 +vt 0.934187 0.441541 +vt 0.929698 0.441541 +vt 0.938677 0.441541 +vt 0.934187 0.415026 +vt 0.929698 0.415026 +vt 0.938676 0.415026 +vt 0.934187 0.396377 +vt 0.929699 0.396377 +vt 0.938675 0.396377 +vt 0.934187 0.383013 +vt 0.929700 0.383013 +vt 0.938674 0.383013 +vt 0.523432 0.931189 +vt 0.523432 0.945710 +vt 0.518945 0.945710 +vt 0.517393 0.931189 +vt 0.529472 0.931189 +vt 0.527919 0.945710 +vt 0.523432 0.916361 +vt 0.515833 0.929069 +vt 0.515436 0.916361 +vt 0.531428 0.916361 +vt 0.531031 0.929069 +vt 0.603632 0.568539 +vt 0.605335 0.565600 +vt 0.605335 0.570082 +vt 0.603632 0.559193 +vt 0.605334 0.562131 +vt 0.603632 0.563674 +vt 0.605167 0.573636 +vt 0.603632 0.576466 +vt 0.603632 0.572007 +vt 0.605167 0.582851 +vt 0.603632 0.580020 +vt 0.605167 0.578392 +vt 0.816212 0.407392 +vt 0.280188 0.823305 +vt 0.605358 0.557267 +vt 0.603632 0.554248 +vt 0.605358 0.552799 +vt 0.605358 0.547854 +vt 0.603632 0.550873 +vt 0.603632 0.546406 +vt 0.289356 0.718626 +vt 0.275067 0.722462 +vt 0.821333 0.306549 +vt 0.807044 0.302713 +vt 0.260792 0.734998 +vt 0.835608 0.319084 +vt 0.251916 0.751452 +vt 0.844484 0.335539 +vt 0.248621 0.775609 +vt 0.847779 0.359696 +vt 0.251370 0.799574 +vt 0.845030 0.383660 +vt 0.259489 0.810778 +vt 0.836911 0.394865 +vt 0.270125 0.819236 +vt 0.826275 0.403322 +vt 0.831427 0.414199 +vt 0.815115 0.419523 +vt 0.281285 0.835436 +vt 0.264972 0.830113 +vt 0.845379 0.403663 +vt 0.251021 0.819577 +vt 0.856802 0.387133 +vt 0.239598 0.803047 +vt 0.859826 0.360630 +vt 0.236574 0.776543 +vt 0.856033 0.332096 +vt 0.240367 0.748010 +vt 0.841358 0.307227 +vt 0.255042 0.723140 +vt 0.824706 0.294630 +vt 0.271694 0.710544 +vt 0.809749 0.290875 +vt 0.286650 0.706789 +vt 0.804572 0.303501 +vt 0.787723 0.308751 +vt 0.794548 0.275425 +vt 0.807934 0.289012 +vt 0.888895 0.998972 +vt 0.888895 0.520892 +vt 0.877486 0.520892 +vt 0.877486 0.998972 +vt 0.281452 0.944981 +vt 0.281452 0.956390 +vt 0.284509 0.959451 +vt 0.295157 0.959451 +vt 0.295157 0.941921 +vt 0.284509 0.941921 +vt 0.724418 0.147699 +vt 0.721491 0.146442 +vt 0.721493 0.204741 +vt 0.724420 0.203484 +vt 0.861076 0.512900 +vt 0.864025 0.512900 +vt 0.864025 0.495371 +vt 0.861076 0.495371 +vt 0.341875 0.660718 +vt 0.359404 0.660722 +vt 0.359404 0.593393 +vt 0.341875 0.593389 +vt 0.874426 0.520957 +vt 0.874426 0.999037 +vt 0.724428 0.392148 +vt 0.721501 0.390891 +vt 0.721503 0.422598 +vt 0.724430 0.421341 +vt 0.341875 0.591459 +vt 0.359404 0.591463 +vt 0.359404 0.522094 +vt 0.341875 0.522090 +vt 0.340872 0.854075 +vt 0.358402 0.854079 +vt 0.358402 0.787770 +vt 0.340872 0.787766 +vt 0.407431 0.909084 +vt 0.424961 0.909088 +vt 0.424961 0.854666 +vt 0.407431 0.854663 +vt 0.724432 0.490337 +vt 0.721505 0.489080 +vt 0.721506 0.510753 +vt 0.724425 0.510753 +vt 0.945742 0.518966 +vt 0.948660 0.518966 +vt 0.948660 0.501437 +vt 0.945742 0.501437 +vt 0.757541 0.090377 +vt 0.754614 0.089120 +vt 0.754614 0.120827 +vt 0.757541 0.119570 +vt 0.757533 0.000964 +vt 0.754614 0.000964 +vt 0.754614 0.022638 +vt 0.757541 0.021381 +vt 0.757542 0.308233 +vt 0.754614 0.306976 +vt 0.754614 0.365276 +vt 0.757541 0.364019 +vt 0.152304 0.952717 +vt 0.155167 0.952717 +vt 0.155167 0.935188 +vt 0.152303 0.935188 +vt 0.923544 0.379553 +vt 0.926493 0.379553 +vt 0.926493 0.362023 +vt 0.923544 0.362023 +vt 0.323658 0.954146 +vt 0.326522 0.954146 +vt 0.326522 0.936616 +vt 0.323658 0.936616 +vt 0.134374 0.952717 +vt 0.137323 0.952717 +vt 0.137323 0.935188 +vt 0.134374 0.935188 +vt 0.924896 0.957752 +vt 0.927760 0.957752 +vt 0.927760 0.940222 +vt 0.924896 0.940222 +vt 0.170147 0.952717 +vt 0.173011 0.952717 +vt 0.173011 0.935188 +vt 0.170148 0.935188 +vt 0.941404 0.379553 +vt 0.944353 0.379553 +vt 0.944353 0.362023 +vt 0.941404 0.362023 +vt 0.757541 0.191634 +vt 0.754614 0.190377 +vt 0.754614 0.239471 +vt 0.757541 0.238214 +vt 0.724423 0.273503 +vt 0.721496 0.272246 +vt 0.721498 0.321341 +vt 0.724425 0.320084 +vt 0.737430 0.272246 +vt 0.734660 0.272220 +vt 0.734662 0.321366 +vt 0.737432 0.321341 +vt 0.731969 0.272829 +vt 0.731971 0.320758 +vt 0.729463 0.273696 +vt 0.729465 0.319891 +vt 0.727034 0.274087 +vt 0.727036 0.319500 +vt 0.770548 0.190376 +vt 0.767778 0.190351 +vt 0.767778 0.239497 +vt 0.770548 0.239471 +vt 0.765087 0.190960 +vt 0.765087 0.238888 +vt 0.762581 0.191826 +vt 0.762581 0.238021 +vt 0.760152 0.192217 +vt 0.760152 0.237631 +vt 0.910559 0.379553 +vt 0.913329 0.379553 +vt 0.913329 0.362023 +vt 0.910559 0.362023 +vt 0.916010 0.379553 +vt 0.916010 0.362023 +vt 0.918501 0.379553 +vt 0.918501 0.362023 +vt 0.920923 0.379553 +vt 0.920923 0.362023 +vt 0.139249 0.952717 +vt 0.142015 0.952717 +vt 0.142015 0.935188 +vt 0.139249 0.935188 +vt 0.144733 0.952717 +vt 0.144733 0.935188 +vt 0.147278 0.952717 +vt 0.147278 0.935188 +vt 0.149723 0.952717 +vt 0.149723 0.935188 +vt 0.121389 0.952717 +vt 0.124159 0.952717 +vt 0.124159 0.935188 +vt 0.121389 0.935188 +vt 0.126840 0.952717 +vt 0.126840 0.935188 +vt 0.129331 0.952717 +vt 0.129331 0.935188 +vt 0.131753 0.952717 +vt 0.131753 0.935188 +vt 0.310603 0.954146 +vt 0.313369 0.954146 +vt 0.313369 0.936616 +vt 0.310603 0.936616 +vt 0.316087 0.954146 +vt 0.316087 0.936616 +vt 0.318632 0.954146 +vt 0.318632 0.936616 +vt 0.321077 0.954146 +vt 0.321077 0.936616 +vt 0.770548 0.089119 +vt 0.767778 0.089094 +vt 0.767778 0.120852 +vt 0.770548 0.120826 +vt 0.765087 0.089702 +vt 0.765087 0.120243 +vt 0.762581 0.090569 +vt 0.762581 0.119377 +vt 0.760152 0.090960 +vt 0.760152 0.118986 +vt 0.737435 0.390891 +vt 0.734665 0.390865 +vt 0.734666 0.422623 +vt 0.737436 0.422598 +vt 0.731974 0.391474 +vt 0.731975 0.422015 +vt 0.729468 0.392341 +vt 0.729469 0.421148 +vt 0.727039 0.392732 +vt 0.727041 0.420757 +vt 0.157093 0.952717 +vt 0.159859 0.952717 +vt 0.159859 0.935188 +vt 0.157093 0.935188 +vt 0.162577 0.952717 +vt 0.162577 0.935188 +vt 0.165122 0.952717 +vt 0.165122 0.935188 +vt 0.167567 0.952717 +vt 0.167567 0.935188 +vt 0.770548 0.000964 +vt 0.767840 0.000964 +vt 0.767778 0.022663 +vt 0.770548 0.022637 +vt 0.765134 0.000964 +vt 0.765087 0.022054 +vt 0.762581 0.000964 +vt 0.762581 0.021188 +vt 0.760131 0.000964 +vt 0.760152 0.020797 +vt 0.932726 0.518966 +vt 0.935434 0.518966 +vt 0.935434 0.501437 +vt 0.932726 0.501437 +vt 0.938140 0.518966 +vt 0.938140 0.501437 +vt 0.940693 0.518966 +vt 0.940693 0.501437 +vt 0.943143 0.518966 +vt 0.943143 0.501437 +vt 0.737439 0.489080 +vt 0.734669 0.489054 +vt 0.734732 0.510753 +vt 0.737440 0.510753 +vt 0.731978 0.489663 +vt 0.732026 0.510753 +vt 0.729472 0.490529 +vt 0.729473 0.510753 +vt 0.727043 0.490920 +vt 0.727023 0.510753 +vt 0.928419 0.379553 +vt 0.931189 0.379553 +vt 0.931189 0.362023 +vt 0.928419 0.362023 +vt 0.933870 0.379553 +vt 0.933870 0.362023 +vt 0.936361 0.379553 +vt 0.936361 0.362023 +vt 0.938783 0.379553 +vt 0.938783 0.362023 +vt 0.911842 0.957752 +vt 0.914607 0.957752 +vt 0.914607 0.940222 +vt 0.911842 0.940222 +vt 0.917325 0.957752 +vt 0.917325 0.940222 +vt 0.919870 0.957752 +vt 0.919870 0.940222 +vt 0.922316 0.957752 +vt 0.922316 0.940222 +vt 0.770548 0.306976 +vt 0.767778 0.306950 +vt 0.767778 0.365301 +vt 0.770548 0.365275 +vt 0.765087 0.307559 +vt 0.765087 0.364693 +vt 0.762581 0.308426 +vt 0.762581 0.363826 +vt 0.760152 0.308817 +vt 0.760152 0.363435 +vt 0.737425 0.146442 +vt 0.734655 0.146416 +vt 0.734657 0.204767 +vt 0.737427 0.204741 +vt 0.731964 0.147025 +vt 0.731966 0.204158 +vt 0.729458 0.147891 +vt 0.729460 0.203292 +vt 0.727029 0.148282 +vt 0.727031 0.202901 +vt 0.737422 0.091878 +vt 0.752689 0.510753 +vt 0.752669 0.032566 +vt 0.742011 0.032566 +vt 0.721486 0.032566 +vt 0.721489 0.091878 +vt 0.724416 0.090621 +vt 0.727027 0.090038 +vt 0.729455 0.090428 +vt 0.731961 0.091295 +vt 0.734652 0.091904 +vt 0.770548 0.419839 +vt 0.767778 0.419813 +vt 0.765087 0.420422 +vt 0.762581 0.421289 +vt 0.760152 0.421680 +vt 0.757541 0.421096 +vt 0.754614 0.419839 +vt 0.754614 0.479152 +vt 0.775139 0.479151 +vt 0.785797 0.479150 +vt 0.785797 0.000963 +vt 0.848091 0.512900 +vt 0.850861 0.512900 +vt 0.850861 0.495371 +vt 0.848091 0.495371 +vt 0.853542 0.512900 +vt 0.853542 0.495371 +vt 0.856033 0.512900 +vt 0.856033 0.495371 +vt 0.858455 0.512900 +vt 0.858455 0.495371 +vt 0.891956 0.999037 +vt 0.891956 0.520957 +vt 0.742010 0.021221 +vt 0.721486 0.021221 +vt 0.754614 0.490496 +vt 0.775139 0.490495 +vt 0.184536 0.915678 +vt 0.184536 0.927020 +vt 0.202066 0.927020 +vt 0.202066 0.915678 +vt 0.721485 0.000963 +vt 0.721485 0.000963 +vt 0.184536 0.947712 +vt 0.202066 0.947712 +vt 0.754614 0.510755 +vt 0.754615 0.510755 +vt 0.768710 0.941856 +vt 0.768710 0.929441 +vt 0.757717 0.929441 +vt 0.757717 0.941855 +vt 0.948853 0.520893 +vt 0.948853 0.533307 +vt 0.959846 0.533306 +vt 0.959846 0.520892 +vt 0.911292 0.427130 +vt 0.911292 0.383013 +vt 0.898910 0.383015 +vt 0.898910 0.427133 +vt 0.946016 0.537564 +vt 0.946016 0.549624 +vt 0.959846 0.549623 +vt 0.959846 0.537563 +vt 0.915742 0.427138 +vt 0.915742 0.383020 +vt 0.757717 0.946112 +vt 0.771548 0.946112 +vt 0.927771 0.427135 +vt 0.927771 0.383017 +vt 0.757717 0.958172 +vt 0.771548 0.958173 +vt 0.096256 0.934457 +vt 0.096256 0.922043 +vt 0.085262 0.922042 +vt 0.085262 0.934457 +vt 0.952614 0.174421 +vt 0.952614 0.186835 +vt 0.963607 0.186835 +vt 0.963607 0.174420 +vt 0.924508 0.137182 +vt 0.924508 0.093065 +vt 0.912126 0.093067 +vt 0.912126 0.137185 +vt 0.949777 0.191092 +vt 0.949777 0.203152 +vt 0.963607 0.203152 +vt 0.963607 0.191091 +vt 0.928958 0.137190 +vt 0.928958 0.093072 +vt 0.085262 0.938713 +vt 0.099093 0.938714 +vt 0.940987 0.137187 +vt 0.940987 0.093069 +vt 0.085262 0.950773 +vt 0.099093 0.950774 +vt 0.544347 0.928775 +vt 0.544347 0.916361 +vt 0.533354 0.916361 +vt 0.533354 0.928775 +vt 0.469616 0.924426 +vt 0.469616 0.936840 +vt 0.480609 0.936840 +vt 0.480609 0.924425 +vt 0.013345 0.931770 +vt 0.013345 0.887652 +vt 0.000963 0.887655 +vt 0.000963 0.931773 +vt 0.466779 0.941097 +vt 0.466779 0.953157 +vt 0.480609 0.953157 +vt 0.480609 0.941096 +vt 0.017795 0.931777 +vt 0.017795 0.887659 +vt 0.533354 0.933031 +vt 0.547184 0.933032 +vt 0.029824 0.931775 +vt 0.029824 0.887657 +vt 0.533354 0.945092 +vt 0.547184 0.945092 +vt 0.493528 0.936840 +vt 0.493528 0.924426 +vt 0.482535 0.924425 +vt 0.482535 0.936840 +vt 0.948853 0.551550 +vt 0.948853 0.563964 +vt 0.959846 0.563964 +vt 0.959846 0.551550 +vt 0.133771 0.933255 +vt 0.133771 0.889137 +vt 0.121389 0.889139 +vt 0.121389 0.933257 +vt 0.946016 0.568221 +vt 0.946016 0.580281 +vt 0.959846 0.580281 +vt 0.959846 0.568220 +vt 0.138221 0.933262 +vt 0.138221 0.889144 +vt 0.482535 0.941096 +vt 0.496365 0.941097 +vt 0.150250 0.933259 +vt 0.150250 0.889142 +vt 0.482535 0.953157 +vt 0.496365 0.953157 +vt 0.112012 0.934457 +vt 0.112012 0.922043 +vt 0.101018 0.922042 +vt 0.101018 0.934457 +vt 0.945750 0.047014 +vt 0.945750 0.059429 +vt 0.956743 0.059428 +vt 0.956743 0.047014 +vt 0.924508 0.091132 +vt 0.924508 0.047014 +vt 0.912126 0.047016 +vt 0.912126 0.091134 +vt 0.942912 0.063685 +vt 0.942912 0.075746 +vt 0.956743 0.075745 +vt 0.956743 0.063685 +vt 0.928958 0.091139 +vt 0.928958 0.047021 +vt 0.101018 0.938713 +vt 0.114849 0.938714 +vt 0.940987 0.091136 +vt 0.940987 0.047019 +vt 0.101018 0.950773 +vt 0.114849 0.950774 +vt 0.065501 0.934993 +vt 0.065501 0.922579 +vt 0.054508 0.922578 +vt 0.054508 0.934993 +vt 0.948853 0.582208 +vt 0.948853 0.594622 +vt 0.959846 0.594621 +vt 0.959846 0.582207 +vt 0.924508 0.045081 +vt 0.924508 0.000963 +vt 0.912126 0.000965 +vt 0.912126 0.045083 +vt 0.946016 0.598879 +vt 0.946016 0.610939 +vt 0.959846 0.610938 +vt 0.959846 0.598878 +vt 0.928958 0.045088 +vt 0.928958 0.000970 +vt 0.054508 0.939249 +vt 0.068339 0.939250 +vt 0.940987 0.045085 +vt 0.940987 0.000968 +vt 0.054508 0.951310 +vt 0.068339 0.951310 +vt 0.953906 0.090086 +vt 0.953906 0.077672 +vt 0.942912 0.077671 +vt 0.942912 0.090086 +vt 0.948853 0.612865 +vt 0.948853 0.625279 +vt 0.959847 0.625279 +vt 0.959847 0.612865 +vt 0.833263 0.943834 +vt 0.833263 0.899716 +vt 0.820881 0.899719 +vt 0.820881 0.943836 +vt 0.946016 0.629536 +vt 0.946016 0.641596 +vt 0.959847 0.641596 +vt 0.959847 0.629536 +vt 0.837713 0.943841 +vt 0.837713 0.899723 +vt 0.942912 0.094342 +vt 0.956743 0.094343 +vt 0.849742 0.943839 +vt 0.849742 0.899721 +vt 0.942912 0.106402 +vt 0.956743 0.106403 +vt 0.446260 0.936840 +vt 0.446260 0.924426 +vt 0.435266 0.924425 +vt 0.435266 0.936840 +vt 0.948853 0.643523 +vt 0.948853 0.655937 +vt 0.959846 0.655937 +vt 0.959846 0.643522 +vt 0.097644 0.920109 +vt 0.097644 0.875991 +vt 0.085262 0.875994 +vt 0.085262 0.920112 +vt 0.946016 0.660194 +vt 0.946016 0.672254 +vt 0.959846 0.672253 +vt 0.959846 0.660193 +vt 0.102094 0.920116 +vt 0.102094 0.875999 +vt 0.435266 0.941096 +vt 0.449097 0.941097 +vt 0.114123 0.920114 +vt 0.114123 0.875996 +vt 0.435266 0.953157 +vt 0.449097 0.953157 +vt 0.945508 0.151530 +vt 0.945508 0.139116 +vt 0.934515 0.139116 +vt 0.934515 0.151530 +vt 0.896718 0.932008 +vt 0.896718 0.944422 +vt 0.907712 0.944422 +vt 0.907712 0.932007 +vt 0.164558 0.933255 +vt 0.164558 0.889137 +vt 0.152176 0.889140 +vt 0.152176 0.933257 +vt 0.893881 0.948679 +vt 0.893881 0.960739 +vt 0.907712 0.960739 +vt 0.907712 0.948678 +vt 0.169008 0.933262 +vt 0.169008 0.889144 +vt 0.934515 0.155786 +vt 0.948345 0.155787 +vt 0.181037 0.933259 +vt 0.181037 0.889142 +vt 0.934515 0.167847 +vt 0.948345 0.167847 +vt 0.462016 0.936840 +vt 0.462016 0.924426 +vt 0.451023 0.924426 +vt 0.451023 0.936840 +vt 0.945750 0.108329 +vt 0.945750 0.120744 +vt 0.956743 0.120743 +vt 0.956743 0.108329 +vt 0.322985 0.934683 +vt 0.322985 0.890565 +vt 0.310603 0.890568 +vt 0.310603 0.934686 +vt 0.942912 0.125000 +vt 0.942912 0.137061 +vt 0.956743 0.137060 +vt 0.956743 0.125000 +vt 0.327436 0.934690 +vt 0.327436 0.890572 +vt 0.451023 0.941096 +vt 0.464853 0.941097 +vt 0.339465 0.934688 +vt 0.339465 0.890570 +vt 0.451023 0.953157 +vt 0.464853 0.953157 +vt 0.713607 0.933530 +vt 0.713607 0.921115 +vt 0.702614 0.921115 +vt 0.702614 0.933529 +vt 0.734788 0.918465 +vt 0.734788 0.930879 +vt 0.745782 0.930879 +vt 0.745782 0.918464 +vt 0.447648 0.922492 +vt 0.447648 0.878375 +vt 0.435266 0.878377 +vt 0.435266 0.922495 +vt 0.731951 0.935136 +vt 0.731951 0.947196 +vt 0.745782 0.947196 +vt 0.745782 0.935135 +vt 0.452099 0.922500 +vt 0.452099 0.878382 +vt 0.702614 0.937786 +vt 0.716444 0.937786 +vt 0.464128 0.922497 +vt 0.464128 0.878379 +vt 0.702614 0.949846 +vt 0.716444 0.949847 +vt 0.960770 0.217493 +vt 0.960770 0.205078 +vt 0.949777 0.205078 +vt 0.949777 0.217492 +vt 0.952614 0.235736 +vt 0.952614 0.248150 +vt 0.963607 0.248150 +vt 0.963607 0.235735 +vt 0.909594 0.473181 +vt 0.909594 0.429063 +vt 0.897212 0.429066 +vt 0.897212 0.473184 +vt 0.949777 0.252407 +vt 0.949777 0.264467 +vt 0.963607 0.264466 +vt 0.963607 0.252406 +vt 0.914044 0.473189 +vt 0.914044 0.429071 +vt 0.949777 0.221749 +vt 0.963607 0.221749 +vt 0.926073 0.473186 +vt 0.926073 0.429068 +vt 0.949777 0.233809 +vt 0.963607 0.233810 +vt 0.619239 0.930247 +vt 0.619239 0.917832 +vt 0.608245 0.917832 +vt 0.608245 0.930246 +vt 0.626839 0.917832 +vt 0.626839 0.930247 +vt 0.637832 0.930246 +vt 0.637832 0.917832 +vt 0.478435 0.922492 +vt 0.478435 0.878375 +vt 0.466053 0.878377 +vt 0.466053 0.922495 +vt 0.624002 0.934503 +vt 0.624002 0.946564 +vt 0.637832 0.946563 +vt 0.637832 0.934503 +vt 0.482886 0.922500 +vt 0.482885 0.878382 +vt 0.608245 0.934503 +vt 0.622076 0.934503 +vt 0.494914 0.922497 +vt 0.494914 0.878379 +vt 0.608245 0.946563 +vt 0.622076 0.946564 +vt 0.650751 0.930246 +vt 0.650751 0.917832 +vt 0.639758 0.917832 +vt 0.639758 0.930246 +vt 0.003800 0.933703 +vt 0.003800 0.946118 +vt 0.014793 0.946117 +vt 0.014793 0.933703 +vt 0.924224 0.938289 +vt 0.924224 0.894172 +vt 0.911842 0.894174 +vt 0.911842 0.938292 +vt 0.000963 0.950374 +vt 0.000963 0.962435 +vt 0.014793 0.962434 +vt 0.014793 0.950374 +vt 0.928674 0.938297 +vt 0.928674 0.894179 +vt 0.639758 0.934503 +vt 0.653588 0.934503 +vt 0.940703 0.938294 +vt 0.940703 0.894176 +vt 0.639758 0.946563 +vt 0.653588 0.946563 +vt 0.119463 0.607746 +vt 0.105646 0.607746 +vt 0.105646 0.651864 +vt 0.119463 0.651864 +vt 0.953906 0.045081 +vt 0.953906 0.000963 +vt 0.942912 0.000963 +vt 0.942912 0.045081 +vt 0.054508 0.875993 +vt 0.083337 0.875991 +vt 0.083337 0.920652 +vt 0.077637 0.920653 +vt 0.054508 0.894172 +vt 0.601913 0.886605 +vt 0.601913 0.857805 +vt 0.606289 0.857805 +vt 0.606289 0.886605 +vt 0.760780 0.890058 +vt 0.737651 0.916539 +vt 0.731951 0.916538 +vt 0.731951 0.871878 +vt 0.760780 0.871879 +vt 0.721485 0.518379 +vt 0.721485 0.512679 +vt 0.725861 0.512679 +vt 0.725861 0.518379 +vt 0.431071 0.802091 +vt 0.431071 0.846636 +vt 0.426694 0.846635 +vt 0.426694 0.802090 +vt 0.693481 0.837313 +vt 0.697858 0.837313 +vt 0.697858 0.863295 +vt 0.693481 0.863295 +vt 0.693481 0.819138 +vt 0.697858 0.819138 +vt 0.837331 0.503399 +vt 0.827189 0.504050 +vt 0.827189 0.497481 +vt 0.837331 0.495371 +vt 0.591429 0.824527 +vt 0.591429 0.831232 +vt 0.591429 0.851956 +vt 0.581235 0.851952 +vt 0.581235 0.820866 +vt 0.591429 0.820870 +vt 0.350562 0.685866 +vt 0.340409 0.683756 +vt 0.340409 0.664758 +vt 0.350562 0.662647 +vt 0.350562 0.667610 +vt 0.350562 0.680903 +vt 0.572392 0.851952 +vt 0.572392 0.820866 +vt 0.895286 0.460143 +vt 0.890324 0.460143 +vt 0.877030 0.460143 +vt 0.872068 0.460143 +vt 0.872068 0.429063 +vt 0.895286 0.429063 +vt 0.900711 0.485480 +vt 0.900711 0.478776 +vt 0.900711 0.475118 +vt 0.910905 0.475114 +vt 0.910905 0.506200 +vt 0.900711 0.506204 +vt 0.594928 0.824527 +vt 0.594928 0.831232 +vt 0.919747 0.475115 +vt 0.919747 0.506201 +vt 0.359404 0.680903 +vt 0.359404 0.685866 +vt 0.578962 0.853883 +vt 0.578962 0.860570 +vt 0.572392 0.860569 +vt 0.572392 0.853882 +vt 0.897212 0.485480 +vt 0.897212 0.478775 +vt 0.119463 0.662420 +vt 0.119463 0.668990 +vt 0.115965 0.668990 +vt 0.115965 0.662420 +vt 0.119460 0.679410 +vt 0.119460 0.685979 +vt 0.115965 0.685979 +vt 0.115965 0.679410 +vt 0.119460 0.687905 +vt 0.119460 0.694474 +vt 0.115965 0.694474 +vt 0.115965 0.687905 +vt 0.115965 0.653790 +vt 0.119463 0.653790 +vt 0.119463 0.660494 +vt 0.115965 0.660495 +vt 0.119463 0.670915 +vt 0.119463 0.677485 +vt 0.115965 0.677485 +vt 0.115965 0.670915 +vt 0.367899 0.924720 +vt 0.367899 0.918033 +vt 0.373759 0.918034 +vt 0.373759 0.924721 +vt 0.587457 0.853883 +vt 0.587457 0.860570 +vt 0.580887 0.860569 +vt 0.580887 0.853882 +vt 0.239889 0.513459 +vt 0.239889 0.520164 +vt 0.236391 0.520164 +vt 0.236391 0.513459 +vt 0.361330 0.918031 +vt 0.361330 0.914384 +vt 0.367899 0.914385 +vt 0.373759 0.914386 +vt 0.380328 0.914388 +vt 0.380328 0.918035 +vt 0.837331 0.510561 +vt 0.846165 0.495371 +vt 0.846165 0.518589 +vt 0.837331 0.518589 +vt 0.380328 0.945393 +vt 0.361330 0.945389 +vt 0.361330 0.924719 +vt 0.380328 0.924723 +vt 0.827189 0.516479 +vt 0.827189 0.509910 +vt 0.359404 0.662647 +vt 0.359404 0.667610 +vt 0.942628 0.894172 +vt 0.951471 0.894172 +vt 0.951471 0.949809 +vt 0.942628 0.949809 +vt 0.498414 0.752755 +vt 0.507257 0.752755 +vt 0.507257 0.766048 +vt 0.498414 0.766048 +vt 0.940603 0.383013 +vt 0.953896 0.383015 +vt 0.953896 0.438508 +vt 0.940603 0.438505 +vt 0.890324 0.515767 +vt 0.877030 0.515767 +vt 0.762705 0.871878 +vt 0.771548 0.871878 +vt 0.771548 0.927515 +vt 0.762705 0.927515 +vt 0.249907 0.863922 +vt 0.236574 0.844977 +vt 0.279526 0.848713 +vt 0.263151 0.865074 +vt 0.843565 0.449161 +vt 0.856809 0.448009 +vt 0.858004 0.461728 +vt 0.844746 0.462881 +vt 0.338609 0.540147 +vt 0.339473 0.540147 +vt 0.338732 0.551626 +vt 0.339324 0.551626 +vt 0.261970 0.878794 +vt 0.248712 0.877641 +vt 0.838428 0.485524 +vt 0.841433 0.490757 +vt 0.828638 0.493445 +vt 0.828328 0.491276 +vt 0.827189 0.432799 +vt 0.870142 0.429063 +vt 0.265282 0.906670 +vt 0.268288 0.901437 +vt 0.278388 0.907189 +vt 0.278077 0.909358 +vt 0.237993 0.439569 +vt 0.238857 0.439569 +vt 0.238129 0.453971 +vt 0.238721 0.453971 +vt 0.105575 0.444829 +vt 0.105575 0.448893 +vt 0.104983 0.448893 +vt 0.104983 0.444829 +vt 0.262573 0.891155 +vt 0.252372 0.893910 +vt 0.863553 0.926510 +vt 0.858152 0.909417 +vt 0.872500 0.909417 +vt 0.867099 0.926510 +vt 0.854343 0.477997 +vt 0.844143 0.475242 +vt 0.863552 0.940268 +vt 0.867100 0.940268 +vt 0.866573 0.956285 +vt 0.864080 0.956285 +vt 0.899282 0.895467 +vt 0.893881 0.877380 +vt 0.908229 0.877380 +vt 0.902828 0.895467 +vt 0.237179 0.424728 +vt 0.239671 0.424728 +vt 0.809948 0.902340 +vt 0.810983 0.903503 +vt 0.810983 0.946505 +vt 0.809948 0.947564 +vt 0.795601 0.947561 +vt 0.794565 0.946502 +vt 0.794565 0.903499 +vt 0.795601 0.902337 +vt 0.899281 0.909238 +vt 0.902829 0.909238 +vt 0.902301 0.921126 +vt 0.899809 0.921126 +vt 0.901487 0.930082 +vt 0.900623 0.930082 +vt 0.238297 0.493687 +vt 0.238301 0.509184 +vt 0.236961 0.509818 +vt 0.236961 0.494312 +vt 0.338609 0.537587 +vt 0.338613 0.522090 +vt 0.339949 0.522715 +vt 0.339949 0.538222 +vt 0.238325 0.455897 +vt 0.238325 0.472118 +vt 0.236964 0.472866 +vt 0.236961 0.456651 +vt 0.238325 0.475546 +vt 0.238322 0.491761 +vt 0.236961 0.491013 +vt 0.236961 0.474792 +vt 0.338609 0.563599 +vt 0.338609 0.559539 +vt 0.339706 0.560345 +vt 0.339692 0.562535 +vt 0.339706 0.553552 +vt 0.339706 0.557613 +vt 0.338622 0.556548 +vt 0.338609 0.554358 +vt 0.268874 0.900402 +vt 0.279526 0.906475 +vt 0.247563 0.877520 +vt 0.248756 0.863801 +vt 0.237638 0.452980 +vt 0.236961 0.439971 +vt 0.843706 0.462951 +vt 0.842513 0.449232 +vt 0.264203 0.865145 +vt 0.263010 0.878864 +vt 0.898776 0.921501 +vt 0.898248 0.909256 +vt 0.263584 0.890863 +vt 0.239889 0.439971 +vt 0.239212 0.452980 +vt 0.264788 0.907518 +vt 0.251305 0.894178 +vt 0.857960 0.447888 +vt 0.859152 0.461607 +vt 0.855411 0.478265 +vt 0.841928 0.491605 +vt 0.827189 0.490562 +vt 0.837842 0.484489 +vt 0.843131 0.474950 +vt 0.903862 0.909256 +vt 0.903334 0.921501 +vt 0.842896 0.260832 +vt 0.851556 0.260832 +vt 0.851602 0.265287 +vt 0.842942 0.265287 +vt 0.929732 0.940223 +vt 0.938392 0.940223 +vt 0.938346 0.944677 +vt 0.929686 0.944677 +vt 0.938392 0.949122 +vt 0.929732 0.949122 +vt 0.842943 0.256387 +vt 0.851603 0.256387 +vt 0.430995 0.899727 +vt 0.426886 0.902588 +vt 0.426886 0.897581 +vt 0.430995 0.894720 +vt 0.225832 0.903991 +vt 0.234492 0.903991 +vt 0.234538 0.908445 +vt 0.225878 0.908445 +vt 0.918524 0.508130 +vt 0.927185 0.508130 +vt 0.927138 0.512585 +vt 0.918478 0.512585 +vt 0.927185 0.517030 +vt 0.918525 0.517030 +vt 0.225879 0.899546 +vt 0.234539 0.899546 +vt 0.606289 0.903333 +vt 0.602181 0.906194 +vt 0.602181 0.901187 +vt 0.606289 0.898326 +vt 0.691981 0.908799 +vt 0.700641 0.908799 +vt 0.700687 0.913253 +vt 0.692027 0.913253 +vt 0.747754 0.918464 +vt 0.756414 0.918464 +vt 0.756368 0.922919 +vt 0.747707 0.922919 +vt 0.756414 0.927364 +vt 0.747754 0.927364 +vt 0.692028 0.904354 +vt 0.700688 0.904354 +vt 0.817464 0.903758 +vt 0.813356 0.906619 +vt 0.813356 0.901612 +vt 0.817464 0.898750 +vt 0.907845 0.512575 +vt 0.916505 0.512575 +vt 0.916552 0.517030 +vt 0.907892 0.517030 +vt 0.297129 0.941921 +vt 0.305789 0.941921 +vt 0.305743 0.946376 +vt 0.297083 0.946376 +vt 0.305790 0.950821 +vt 0.297129 0.950821 +vt 0.907892 0.508130 +vt 0.916552 0.508130 +vt 0.817464 0.913552 +vt 0.813356 0.916413 +vt 0.813356 0.911406 +vt 0.817464 0.908545 +vt 0.225832 0.914816 +vt 0.234492 0.914816 +vt 0.234538 0.919271 +vt 0.225878 0.919271 +vt 0.692027 0.936830 +vt 0.700687 0.936830 +vt 0.700641 0.941285 +vt 0.691981 0.941285 +vt 0.700688 0.945730 +vt 0.692027 0.945730 +vt 0.225879 0.910371 +vt 0.234539 0.910371 +vt 0.855776 0.914518 +vt 0.851667 0.917379 +vt 0.851667 0.912372 +vt 0.855776 0.909510 +vt 0.225832 0.871514 +vt 0.234492 0.871514 +vt 0.234538 0.875969 +vt 0.225878 0.875969 +vt 0.225878 0.921196 +vt 0.234538 0.921196 +vt 0.234492 0.925651 +vt 0.225832 0.925651 +vt 0.234539 0.930096 +vt 0.225878 0.930096 +vt 0.225879 0.867069 +vt 0.234539 0.867069 +vt 0.430995 0.889933 +vt 0.426886 0.892794 +vt 0.426886 0.887787 +vt 0.430995 0.884925 +vt 0.691981 0.876322 +vt 0.700641 0.876322 +vt 0.700687 0.880777 +vt 0.692027 0.880777 +vt 0.921719 0.497305 +vt 0.930380 0.497305 +vt 0.930333 0.501759 +vt 0.921673 0.501759 +vt 0.930380 0.506204 +vt 0.921720 0.506204 +vt 0.692028 0.871877 +vt 0.700688 0.871877 +vt 0.855776 0.904723 +vt 0.851668 0.907585 +vt 0.851668 0.902577 +vt 0.855776 0.899716 +vt 0.691981 0.919624 +vt 0.700641 0.919624 +vt 0.700687 0.924079 +vt 0.692027 0.924079 +vt 0.204038 0.937329 +vt 0.212698 0.937329 +vt 0.212652 0.941784 +vt 0.203992 0.941784 +vt 0.212699 0.946229 +vt 0.204039 0.946229 +vt 0.692028 0.915179 +vt 0.700688 0.915179 +vt 0.308106 0.906989 +vt 0.303998 0.909850 +vt 0.303998 0.904843 +vt 0.308106 0.901982 +vt 0.225832 0.882340 +vt 0.234492 0.882340 +vt 0.234538 0.886795 +vt 0.225878 0.886795 +vt 0.328494 0.936616 +vt 0.337154 0.936616 +vt 0.337108 0.941071 +vt 0.328447 0.941071 +vt 0.337154 0.945516 +vt 0.328494 0.945516 +vt 0.225879 0.877895 +vt 0.234539 0.877895 +vt 0.817464 0.884169 +vt 0.813356 0.887030 +vt 0.813356 0.882023 +vt 0.817464 0.879162 +vt 0.691981 0.887148 +vt 0.700641 0.887148 +vt 0.700687 0.891603 +vt 0.692027 0.891603 +vt 0.692027 0.926005 +vt 0.700687 0.926005 +vt 0.700641 0.930459 +vt 0.691981 0.930459 +vt 0.700688 0.934904 +vt 0.692027 0.934904 +vt 0.692028 0.882703 +vt 0.700688 0.882703 +vt 0.870059 0.500378 +vt 0.865951 0.503239 +vt 0.865951 0.498232 +vt 0.870059 0.495371 +vt 0.832263 0.260832 +vt 0.840923 0.260832 +vt 0.840970 0.265287 +vt 0.832309 0.265287 +vt 0.204038 0.926504 +vt 0.212698 0.926504 +vt 0.212652 0.930958 +vt 0.203992 0.930958 +vt 0.212699 0.935403 +vt 0.204039 0.935403 +vt 0.832310 0.256387 +vt 0.840970 0.256387 +vt 0.431233 0.916021 +vt 0.427125 0.918882 +vt 0.427125 0.913875 +vt 0.431233 0.911014 +vt 0.225832 0.893165 +vt 0.234492 0.893165 +vt 0.234538 0.897620 +vt 0.225878 0.897620 +vt 0.225878 0.932022 +vt 0.234538 0.932022 +vt 0.234492 0.936477 +vt 0.225832 0.936477 +vt 0.234539 0.940922 +vt 0.225878 0.940922 +vt 0.225879 0.888720 +vt 0.234539 0.888720 +vt 0.870059 0.510172 +vt 0.865951 0.513034 +vt 0.865951 0.508026 +vt 0.870059 0.505165 +vt 0.203992 0.920123 +vt 0.212652 0.920123 +vt 0.212699 0.924578 +vt 0.204038 0.924578 +vt 0.560297 0.942095 +vt 0.568958 0.942095 +vt 0.568911 0.946550 +vt 0.560251 0.946550 +vt 0.568958 0.950995 +vt 0.560298 0.950995 +vt 0.204039 0.915678 +vt 0.212699 0.915678 +vt 0.279273 0.916291 +vt 0.275165 0.919152 +vt 0.275165 0.914145 +vt 0.279273 0.911284 +vt 0.691981 0.897973 +vt 0.700641 0.897973 +vt 0.700687 0.902428 +vt 0.692027 0.902428 +vt 0.549665 0.942095 +vt 0.558325 0.942095 +vt 0.558279 0.946550 +vt 0.549618 0.946550 +vt 0.558325 0.950995 +vt 0.549665 0.950995 +vt 0.692028 0.893528 +vt 0.700688 0.893528 +vt 0.606289 0.893539 +vt 0.602181 0.896400 +vt 0.602181 0.891393 +vt 0.606290 0.888531 +vt 0.897212 0.512575 +vt 0.905872 0.512575 +vt 0.905919 0.517030 +vt 0.897259 0.517030 +vt 0.592722 0.937969 +vt 0.601382 0.937969 +vt 0.601335 0.942424 +vt 0.592675 0.942424 +vt 0.601382 0.946868 +vt 0.592722 0.946868 +vt 0.897259 0.508130 +vt 0.905919 0.508130 +vt 0.817464 0.893963 +vt 0.813356 0.896825 +vt 0.813356 0.891817 +vt 0.817464 0.888956 +vt 0.884148 0.000970 +vt 0.889762 0.000968 +vt 0.889918 0.373289 +vt 0.884316 0.373291 +vt 0.917101 0.892246 +vt 0.911842 0.892245 +vt 0.911842 0.520892 +vt 0.917101 0.520893 +vt 0.876608 0.000968 +vt 0.882222 0.000970 +vt 0.882054 0.373292 +vt 0.876452 0.373289 +vt 0.872582 0.377554 +vt 0.863475 0.377554 +vt 0.863475 0.005316 +vt 0.872582 0.005316 +vt 0.882222 0.376515 +vt 0.308106 0.900056 +vt 0.302491 0.900056 +vt 0.300598 0.898132 +vt 0.300598 0.892873 +vt 0.302491 0.890949 +vt 0.308106 0.890949 +vt 0.863475 0.002097 +vt 0.865399 0.000963 +vt 0.870658 0.000963 +vt 0.872582 0.002097 +vt 0.853529 0.263570 +vt 0.853529 0.258311 +vt 0.861468 0.258311 +vt 0.861468 0.263570 +vt 0.861353 0.265494 +vt 0.855432 0.265494 +vt 0.874508 0.373284 +vt 0.874676 0.000963 +vt 0.855432 0.256387 +vt 0.861353 0.256387 +vt 0.891694 0.000963 +vt 0.891862 0.373284 +vt 0.884148 0.376515 +s 1 +usemtl Black_leather +f 45/1/1 27/2/2 4/3/3 41/4/4 +f 62/5/5 53/6/6 2/7/7 40/8/8 +f 98/9/9 34/10/10 3/11/11 89/12/12 +f 74/13/13 70/14/14 5/15/15 35/16/16 +f 102/17/17 71/18/18 6/19/19 92/20/20 +f 101/21/21 65/22/22 8/23/23 93/24/24 +f 68/25/25 64/26/26 7/27/27 36/28/28 +f 52/29/29 56/30/30 9/31/31 1/32/32 +f 63/33/33 57/34/34 10/35/35 46/36/36 +f 57/34/34 58/37/37 11/38/38 10/35/35 +f 34/39/10 30/40/39 14/41/40 3/42/11 +f 51/43/41 31/44/42 13/45/43 47/46/44 +f 31/44/42 32/47/45 12/48/46 13/45/43 +f 38/49/47 39/50/48 25/51/49 24/52/50 +f 50/53/51 38/49/47 24/52/50 48/54/52 +f 26/55/53 37/56/54 23/57/55 15/58/56 +f 67/59/57 66/60/58 19/61/59 29/62/60 +f 73/63/61 72/64/62 18/65/63 28/66/64 +f 40/67/8 2/68/7 33/69/65 44/70/66 +f 71/18/18 73/71/61 28/72/64 6/19/19 +f 65/22/22 67/73/57 29/74/60 8/23/23 +f 1/75/32 9/76/31 37/56/54 26/55/53 +f 46/36/36 10/35/35 38/77/47 50/78/51 +f 10/35/35 11/38/38 39/79/48 38/77/47 +f 21/80/67 22/81/68 32/82/45 31/83/42 +f 49/84/69 21/80/67 31/83/42 51/85/41 +f 16/86/70 20/87/71 30/88/39 34/89/10 +f 87/90/72 68/25/25 36/28/28 79/91/73 +f 88/92/74 74/13/13 35/16/16 78/93/75 +f 97/94/76 16/95/70 34/10/10 98/9/9 +f 42/96/77 17/97/78 27/98/2 45/99/1 +f 22/81/68 42/96/77 45/99/1 32/82/45 +f 11/38/38 40/8/8 44/100/66 39/79/48 +f 39/50/48 44/70/66 43/101/79 25/51/49 +f 58/37/37 62/5/5 40/8/8 11/38/38 +f 32/47/45 45/1/1 41/4/4 12/48/46 +f 20/87/71 49/84/69 51/85/41 30/88/39 +f 9/31/31 46/36/36 50/78/51 37/102/54 +f 37/56/54 50/53/51 48/54/52 23/57/55 +f 30/40/39 51/43/41 47/46/44 14/41/40 +f 56/30/30 63/33/33 46/36/36 9/31/31 +f 94/103/80 100/104/81 63/33/33 56/30/30 +f 96/105/82 99/106/83 62/5/5 58/37/37 +f 15/107/56 59/108/84 61/109/85 26/110/53 +f 76/111/86 59/108/84 15/107/56 +f 95/112/87 96/105/82 58/37/37 57/34/34 +f 100/104/81 95/112/87 57/34/34 63/33/33 +f 89/113/12 94/103/80 56/30/30 52/29/29 +f 64/114/26 69/115/88 55/116/89 7/117/27 +f 70/118/14 75/119/90 54/120/91 5/121/15 +f 26/110/53 61/109/85 52/122/29 1/123/32 +f 99/106/83 91/124/92 53/6/6 62/5/5 +f 2/7/7 53/6/6 69/115/88 64/114/26 +f 77/125/93 33/69/65 68/25/25 87/90/72 +f 4/3/3 27/2/2 67/73/57 65/22/22 +f 27/98/2 17/97/78 66/60/58 67/59/57 +f 33/126/65 2/127/7 64/128/26 68/129/25 +f 91/124/92 4/3/3 65/22/22 101/21/21 +f 7/117/27 55/116/89 75/119/90 70/118/14 +f 79/130/73 36/131/28 74/132/13 88/133/74 +f 8/23/23 29/74/60 73/71/61 71/18/18 +f 29/134/60 19/135/59 72/136/62 73/137/61 +f 93/24/24 8/23/23 71/18/18 102/17/17 +f 36/28/28 7/27/27 70/14/14 74/13/13 +f 43/138/94 84/139/94 83/140/94 +f 25/51/49 43/101/79 84/141/95 82/142/96 +f 24/52/50 25/51/49 82/142/96 81/143/97 +f 48/54/52 24/52/50 81/143/97 85/144/98 +f 23/57/55 48/54/52 85/144/98 80/145/99 +f 44/70/66 33/69/65 77/125/93 83/146/100 43/101/79 +f 15/58/56 23/57/55 80/145/99 76/147/86 +f 28/148/64 18/149/63 103/150/101 90/151/102 +f 55/116/89 93/24/24 102/17/17 75/119/90 +f 53/6/6 91/124/92 101/21/21 69/115/88 +f 41/4/4 4/3/3 91/124/92 99/106/83 +f 28/148/64 90/151/102 92/152/20 6/153/19 +f 3/42/11 14/41/40 94/103/80 89/113/12 +f 47/46/44 13/45/43 95/112/87 100/104/81 +f 13/45/43 12/48/46 96/105/82 95/112/87 +f 12/48/46 41/4/4 99/106/83 96/105/82 +f 14/41/40 47/46/44 100/104/81 94/103/80 +f 59/108/84 97/94/76 98/9/9 61/109/85 +f 69/115/88 101/21/21 93/24/24 55/116/89 +f 75/119/90 102/17/17 92/20/20 54/120/91 +f 61/109/85 98/9/9 89/12/12 52/122/29 +f 139/154/103 137/155/104 107/156/105 123/157/106 +f 154/158/107 136/159/108 105/160/109 146/161/110 +f 174/162/111 166/163/112 106/164/113 130/165/114 +f 164/166/115 131/167/116 108/168/117 161/169/118 +f 178/170/119 169/171/120 109/172/121 162/173/122 +f 177/174/123 170/175/124 111/176/125 157/177/126 +f 159/178/127 132/179/128 110/180/129 156/181/130 +f 145/182/131 104/183/132 112/184/133 149/185/134 +f 155/186/135 140/187/136 113/188/137 150/189/138 +f 150/189/138 113/188/137 114/190/139 151/191/140 +f 130/192/114 106/193/113 117/194/141 126/195/142 +f 144/196/143 141/197/144 116/198/145 127/199/146 +f 127/199/146 116/198/145 115/200/147 128/201/148 +f 134/202/149 120/203/150 121/204/151 135/205/152 +f 143/206/153 142/207/154 120/203/150 134/202/149 +f 122/208/155 118/209/156 119/210/157 133/211/158 +f 158/212/159 125/213/160 19/61/59 66/60/58 +f 163/214/161 124/215/162 18/65/63 72/64/62 +f 136/216/108 138/217/163 129/218/164 105/219/109 +f 162/173/122 109/172/121 124/220/162 163/221/161 +f 157/177/126 111/176/125 125/222/160 158/223/159 +f 104/224/132 122/208/155 133/211/158 112/225/133 +f 140/187/136 143/226/153 134/227/149 113/188/137 +f 113/188/137 134/227/149 135/228/152 114/190/139 +f 21/80/67 127/229/146 128/230/148 22/81/68 +f 49/84/69 144/231/143 127/229/146 21/80/67 +f 16/86/70 130/232/114 126/233/142 20/87/71 +f 87/90/72 79/91/73 132/179/128 159/178/127 +f 88/92/74 78/93/75 131/167/116 164/166/115 +f 97/94/76 174/162/111 130/165/114 16/95/70 +f 42/96/77 139/234/103 123/235/106 17/97/78 +f 22/81/68 128/230/148 139/234/103 42/96/77 +f 114/190/139 135/228/152 138/236/163 136/159/108 +f 135/205/152 121/204/151 43/101/165 138/217/163 +f 151/191/140 114/190/139 136/159/108 154/158/107 +f 128/201/148 115/200/147 137/155/104 139/154/103 +f 20/87/71 126/233/142 144/231/143 49/84/69 +f 112/184/133 133/237/158 143/226/153 140/187/136 +f 133/211/158 119/210/157 142/207/154 143/206/153 +f 126/195/142 117/194/141 141/197/144 144/196/143 +f 149/185/134 112/184/133 140/187/136 155/186/135 +f 171/238/166 149/185/134 155/186/135 176/239/167 +f 173/240/168 151/191/140 154/158/107 175/241/169 +f 118/242/156 122/243/155 153/244/170 59/108/84 +f 76/111/86 118/242/156 59/108/84 +f 172/245/171 150/189/138 151/191/140 173/240/168 +f 176/239/167 155/186/135 150/189/138 172/245/171 +f 166/246/112 145/182/131 149/185/134 171/238/166 +f 156/247/130 110/248/129 148/249/172 160/250/173 +f 161/251/118 108/252/117 147/253/174 165/254/175 +f 122/243/155 104/255/132 145/256/131 153/244/170 +f 175/241/169 154/158/107 146/161/110 168/257/176 +f 105/160/109 156/247/130 160/250/173 146/161/110 +f 77/125/93 87/90/72 159/178/127 129/218/164 +f 107/156/105 157/177/126 158/223/159 123/157/106 +f 123/235/106 158/212/159 66/60/58 17/97/78 +f 129/258/164 159/259/127 156/260/130 105/261/109 +f 168/257/176 177/174/123 157/177/126 107/156/105 +f 110/248/129 161/251/118 165/254/175 148/249/172 +f 79/130/73 88/133/74 164/262/115 132/263/128 +f 111/176/125 162/173/122 163/221/161 125/222/160 +f 125/264/160 163/265/161 72/136/62 19/135/59 +f 170/175/124 178/170/119 162/173/122 111/176/125 +f 132/179/128 164/166/115 161/169/118 110/180/129 +f 121/204/151 82/142/96 84/141/95 43/101/165 +f 120/203/150 81/143/97 82/142/96 121/204/151 +f 142/207/154 85/144/98 81/143/97 120/203/150 +f 119/210/157 80/145/99 85/144/98 142/207/154 +f 138/217/163 43/101/165 83/146/100 77/125/93 129/218/164 +f 118/209/156 76/147/86 80/145/99 119/210/157 +f 124/266/162 167/267/177 103/150/101 18/149/63 +f 148/249/172 165/254/175 178/170/119 170/175/124 +f 146/161/110 160/250/173 177/174/123 168/257/176 +f 137/155/104 175/241/169 168/257/176 107/156/105 +f 106/193/113 166/246/112 171/238/166 117/194/141 +f 141/197/144 176/239/167 172/245/171 116/198/145 +f 116/198/145 172/245/171 173/240/168 115/200/147 +f 115/200/147 173/240/168 175/241/169 137/155/104 +f 117/194/141 171/238/166 176/239/167 141/197/144 +f 59/108/84 153/244/170 174/162/111 97/94/76 +f 160/250/173 148/249/172 170/175/124 177/174/123 +f 165/254/175 147/253/174 169/171/120 178/170/119 +f 153/244/170 145/256/131 166/163/112 174/162/111 +s 0 +usemtl Forged_Iron +f 203/268/94 206/269/94 189/270/94 180/271/94 +f 214/272/178 181/273/178 179/274/178 210/275/178 +f 180/271/179 189/270/179 192/276/179 185/277/179 186/278/179 +f 181/279/180 182/280/180 187/281/180 188/282/180 179/283/180 +f 218/284/178 180/285/178 186/286/178 226/287/178 +f 192/288/181 191/289/181 220/290/181 228/291/181 185/292/181 +f 230/293/178 234/294/178 196/295/178 194/296/178 +f 222/297/178 230/293/178 194/296/178 184/298/178 +f 183/299/181 224/300/181 220/290/181 191/289/181 190/301/181 +f 189/302/182 190/301/182 191/289/182 192/288/182 +f 205/303/183 190/304/183 189/270/183 206/269/183 +f 182/305/181 197/306/181 216/307/181 215/308/181 187/309/181 +f 207/310/184 194/311/184 199/312/184 209/313/184 +f 214/272/178 212/314/178 193/315/178 181/273/178 +f 194/311/185 196/316/185 195/317/185 202/318/185 199/312/185 +f 181/279/180 193/319/180 198/320/180 197/321/180 182/280/180 +f 183/299/181 200/322/181 201/323/181 231/324/181 224/300/181 +f 186/278/94 185/277/94 228/325/94 226/326/94 +f 208/327/181 200/322/181 183/299/181 190/301/181 205/328/181 +f 196/316/184 234/329/184 236/330/184 195/317/184 +f 202/331/181 195/332/181 236/333/181 231/324/181 201/323/181 +f 199/334/186 202/331/186 201/323/186 200/322/186 +f 208/335/187 209/313/187 199/312/187 200/336/187 +f 216/337/187 213/338/187 209/313/187 208/335/187 +f 184/298/178 194/296/178 207/339/178 204/340/178 +f 212/341/184 207/310/184 209/313/184 213/338/184 +f 215/342/183 205/303/183 206/269/183 211/343/183 +f 184/298/178 204/340/178 203/344/178 180/285/178 +f 210/345/94 211/343/94 206/269/94 203/268/94 +f 179/346/94 188/347/94 211/343/94 210/345/94 +f 187/348/183 215/342/183 211/343/183 188/347/183 +f 208/327/181 205/328/181 215/308/181 216/307/181 +f 193/349/184 212/341/184 213/338/184 198/350/184 +f 197/351/187 198/350/187 213/338/187 216/337/187 +f 204/340/178 207/339/178 212/314/178 214/272/178 +f 204/340/178 214/272/178 210/275/178 203/344/178 +f 222/297/178 184/298/178 180/285/178 218/284/178 +f 222/352/188 218/353/188 217/354/188 221/355/188 +f 220/290/189 224/300/189 223/356/189 219/357/189 +f 226/326/190 228/325/190 227/358/190 225/359/190 +f 219/357/189 227/360/189 228/291/189 220/290/189 +f 218/353/188 226/361/188 225/362/188 217/354/188 +f 221/355/188 229/363/188 230/364/188 222/352/188 +f 232/365/189 223/356/189 224/300/189 231/324/189 +f 233/366/191 235/367/191 236/330/191 234/329/191 +f 231/324/189 236/333/189 235/368/189 232/365/189 +f 229/363/188 233/369/188 234/370/188 230/364/188 +f 217/354/192 225/362/192 227/371/192 219/372/192 223/373/192 232/374/192 235/375/192 233/369/192 229/363/192 221/355/192 +f 257/376/180 255/377/180 238/378/180 242/379/180 +f 259/380/181 309/381/181 308/382/181 243/383/181 +f 237/384/94 240/385/94 247/386/94 312/387/94 314/388/94 326/389/94 +f 268/390/193 250/391/193 278/392/193 280/393/193 +f 318/394/194 245/395/194 241/396/194 317/397/194 +f 269/398/180 257/376/180 242/379/180 249/399/180 +f 263/400/178 264/401/178 248/402/178 245/403/178 +f 260/404/181 259/380/181 243/383/181 246/405/181 +f 248/406/94 246/407/94 243/408/94 245/395/94 +f 242/409/94 238/410/94 246/407/94 248/406/94 +f 255/411/181 260/404/181 246/405/181 238/412/181 +f 313/413/195 261/414/195 323/415/195 324/416/195 +f 249/417/196 242/409/196 248/406/196 251/418/196 +f 319/419/180 263/420/180 245/421/180 318/422/180 +f 267/423/192 265/424/192 247/425/192 252/426/192 +f 265/427/181 262/428/181 244/429/181 247/430/181 +f 264/431/192 266/432/192 251/433/192 248/434/192 +f 295/435/192 267/423/192 252/426/192 291/436/192 +f 249/437/181 251/438/181 275/439/181 274/440/181 +f 252/426/192 247/425/192 272/441/192 273/442/192 +f 240/385/197 237/384/197 277/443/197 276/444/197 +f 286/445/198 269/398/198 249/399/198 284/446/198 +f 317/447/192 241/448/192 258/449/192 320/450/192 +f 245/395/94 243/408/94 308/451/94 241/396/94 +f 312/387/94 247/386/94 244/452/94 239/453/94 311/454/94 +f 271/455/199 270/456/199 273/457/199 272/458/199 +f 288/459/200 274/460/200 275/461/200 289/462/200 +f 240/463/201 250/464/201 270/465/201 271/466/201 +f 291/436/192 252/426/192 273/442/192 294/467/192 +f 247/468/202 240/469/202 271/470/202 272/471/202 +f 284/446/203 249/399/203 274/472/203 288/473/203 +f 279/474/204 276/475/204 282/476/204 283/477/204 +f 279/478/205 280/479/205 278/480/205 276/481/205 +f 237/482/206 254/483/206 281/484/206 277/485/206 +f 250/486/207 240/385/207 276/444/207 278/487/207 +f 276/444/208 277/443/208 282/488/208 +f 277/485/209 281/484/209 283/489/209 282/490/209 +f 290/491/210 284/446/210 288/473/210 293/492/210 +f 251/433/192 285/493/192 289/494/192 275/495/192 +f 293/496/211 288/459/211 289/462/211 294/497/211 +s 1 +f 304/498/212 303/499/213 299/500/214 298/501/215 +s 0 +f 266/432/192 287/502/192 285/493/192 251/433/192 +f 268/503/216 292/504/216 290/491/216 250/464/216 +f 270/456/217 293/496/217 294/497/217 273/457/217 +f 250/464/218 290/491/218 293/492/218 270/465/218 +f 285/493/192 291/436/192 294/467/192 289/494/192 +f 287/502/192 295/435/192 291/436/192 285/493/192 +s 1 +f 299/505/214 296/506/219 297/507/220 298/508/215 +f 300/509/221 304/510/212 298/511/215 297/512/220 +f 306/513/222 300/514/221 297/515/220 296/516/219 +f 286/517/223 284/518/224 301/519/225 307/520/226 +f 307/521/226 301/522/225 300/514/221 306/513/222 +f 284/523/224 290/524/227 305/525/228 301/526/225 +f 301/526/225 305/525/228 304/510/212 300/509/221 +f 290/491/227 292/504/229 302/527/230 305/528/228 +f 305/528/228 302/527/230 303/499/213 304/498/212 +s 0 +f 308/382/231 309/381/231 258/529/231 241/530/231 +f 261/414/178 313/413/178 310/531/178 253/532/178 +f 312/533/232 313/413/232 314/534/232 +f 310/531/233 313/413/233 312/533/233 311/535/233 +f 311/454/94 239/453/94 333/536/94 336/537/94 +f 262/538/180 319/419/180 318/422/180 244/539/180 +f 317/447/192 239/540/192 316/541/192 331/542/192 332/543/192 +f 244/539/180 318/422/180 329/544/180 330/545/180 315/546/180 +f 318/547/181 317/548/181 332/549/181 329/550/181 +f 322/551/234 321/552/234 327/553/234 328/554/234 +f 326/389/235 314/388/235 325/555/235 327/556/235 +f 254/557/236 237/558/236 321/559/236 322/560/236 +f 314/561/237 313/562/237 324/563/237 325/564/237 +f 237/384/238 326/389/238 327/556/238 321/565/238 +f 328/554/239 327/553/239 325/564/239 323/566/239 +f 239/540/192 317/447/192 320/450/192 256/567/192 +f 239/568/178 244/569/178 315/570/178 316/571/178 +f 329/550/240 332/549/240 331/572/240 330/573/240 +f 316/574/194 315/575/194 330/576/194 331/577/194 +f 337/578/192 336/579/192 333/580/192 334/581/192 335/582/192 +f 310/531/233 311/535/233 336/583/233 337/584/233 +f 239/585/181 256/586/181 334/587/181 333/588/181 +f 253/532/178 310/531/178 337/584/178 335/589/178 +f 257/376/180 343/590/180 339/591/180 255/377/180 +f 259/380/181 344/592/181 378/593/181 309/381/181 +f 338/594/184 391/595/184 383/596/184 381/597/184 348/598/184 341/599/184 +f 268/390/241 280/393/241 362/600/241 351/601/241 +f 387/602/242 386/603/242 342/604/242 346/605/242 +f 269/398/180 350/606/180 343/590/180 257/376/180 +f 263/400/178 346/607/178 349/608/178 264/401/178 +f 260/404/181 347/609/181 344/592/181 259/380/181 +f 349/610/184 346/605/184 344/611/184 347/612/184 +f 343/613/184 349/610/184 347/612/184 339/614/184 +f 255/411/181 339/615/181 347/609/181 260/404/181 +f 382/616/195 389/617/195 323/415/195 261/414/195 +f 350/618/243 352/619/243 349/610/243 343/613/243 +f 319/419/180 387/620/180 346/621/180 263/420/180 +f 267/423/192 353/622/192 348/623/192 265/424/192 +f 265/427/181 348/624/181 345/625/181 262/428/181 +f 264/431/192 349/626/192 352/627/192 266/432/192 +f 295/435/192 369/628/192 353/622/192 267/423/192 +f 350/629/181 358/630/181 359/631/181 352/632/181 +f 353/622/192 357/633/192 356/634/192 348/623/192 +f 341/599/244 360/635/244 361/636/244 338/594/244 +f 286/445/245 364/637/245 350/606/245 269/398/245 +f 386/638/192 320/450/192 258/449/192 342/639/192 +f 346/605/184 342/604/184 378/640/184 344/611/184 +f 381/597/184 380/641/184 340/642/184 345/643/184 348/598/184 +f 355/644/246 356/645/246 357/646/246 354/647/246 +f 366/648/247 367/649/247 359/650/247 358/651/247 +f 341/652/201 355/653/201 354/654/201 351/655/201 +f 369/628/192 371/656/192 357/633/192 353/622/192 +f 348/657/202 356/658/202 355/659/202 341/660/202 +f 364/637/248 366/661/248 358/662/248 350/606/248 +f 279/474/249 283/477/249 363/663/249 360/664/249 +f 279/478/250 360/665/250 362/666/250 280/479/250 +f 338/667/206 361/668/206 281/484/206 254/483/206 +f 351/669/251 362/670/251 360/635/251 341/599/251 +f 360/635/252 363/671/252 361/636/252 +f 361/668/209 363/672/209 283/489/209 281/484/209 +f 368/673/253 370/674/253 366/661/253 364/637/253 +f 352/627/192 359/675/192 367/676/192 365/677/192 +f 370/678/254 371/679/254 367/649/254 366/648/254 +s 1 +f 376/680/255 373/681/256 299/500/214 303/499/213 +s 0 +f 266/432/192 352/627/192 365/677/192 287/502/192 +f 268/503/257 351/655/257 368/673/257 292/504/257 +f 354/647/258 357/646/258 371/679/258 370/678/258 +f 351/655/259 354/654/259 370/674/259 368/673/259 +f 365/677/192 367/676/192 371/656/192 369/628/192 +f 287/502/192 365/677/192 369/628/192 295/435/192 +s 1 +f 299/505/214 373/682/256 372/683/260 296/506/219 +f 374/684/261 372/685/260 373/686/256 376/687/255 +f 306/513/222 296/516/219 372/688/260 374/689/261 +f 286/517/223 307/520/226 375/690/262 364/691/263 +f 307/521/226 306/513/222 374/689/261 375/692/262 +f 364/693/263 375/694/262 377/695/264 368/696/265 +f 375/694/262 374/684/261 376/687/255 377/695/264 +f 368/673/265 377/697/264 302/527/230 292/504/229 +f 377/697/264 376/680/255 303/499/213 302/527/230 +s 0 +f 378/593/231 342/698/231 258/529/231 309/381/231 +f 261/414/178 253/532/178 379/699/178 382/616/178 +f 381/700/266 383/701/266 382/616/266 +f 379/699/267 380/702/267 381/700/267 382/616/267 +f 380/641/184 398/703/184 397/704/184 340/642/184 +f 262/538/180 345/705/180 387/620/180 319/419/180 +f 386/638/192 396/706/192 395/707/192 385/708/192 340/709/192 +f 345/705/180 384/710/180 394/711/180 393/712/180 387/620/180 +f 387/713/181 393/714/181 396/715/181 386/716/181 +f 322/551/268 328/554/268 392/717/268 388/718/268 +f 391/595/269 392/719/269 390/720/269 383/596/269 +f 254/557/236 322/560/236 388/721/236 338/722/236 +f 383/723/270 390/724/270 389/725/270 382/726/270 +f 338/594/271 388/727/271 392/719/271 391/595/271 +f 328/554/272 323/566/272 390/724/272 392/717/272 +f 340/709/192 256/567/192 320/450/192 386/638/192 +f 340/728/178 385/729/178 384/730/178 345/731/178 +f 393/714/273 394/732/273 395/733/273 396/715/273 +f 385/734/242 395/735/242 394/736/242 384/737/242 +f 399/738/192 335/582/192 334/581/192 397/739/192 398/740/192 +f 379/699/267 399/741/267 398/742/267 380/702/267 +f 340/743/181 397/744/181 334/587/181 256/586/181 +f 253/532/178 335/589/178 399/741/178 379/699/178 +s 1 +f 572/995/184 509/996/184 511/997/312 573/998/312 +f 573/998/312 511/997/312 513/999/313 574/1000/313 +f 574/1000/313 513/999/313 515/1001/314 575/1002/314 +f 575/1002/314 515/1001/314 517/1003/267 576/1004/267 +f 576/1005/267 517/1006/267 519/1007/315 577/1008/315 +f 577/1008/315 519/1007/315 521/1009/316 578/1010/316 +f 578/1010/316 521/1009/316 523/1011/317 579/1012/317 +f 579/1012/317 523/1011/317 525/1013/178 580/1014/178 +f 580/1014/178 525/1013/178 527/1015/318 581/1016/318 +f 581/1016/318 527/1015/318 529/1017/319 582/1018/319 +f 582/1018/319 529/1017/319 531/1019/320 583/1020/320 +f 583/1020/320 531/1019/320 533/1021/233 584/1022/233 +f 584/1023/233 533/1024/233 535/1025/321 585/1026/321 +f 585/1026/321 535/1025/321 537/1027/322 586/1028/322 +f 586/1028/322 537/1027/322 539/1029/323 587/1030/323 +f 587/1030/323 539/1029/323 541/1031/94 588/1032/94 +f 588/1032/94 541/1031/94 543/1033/324 589/1034/324 +f 589/1034/324 543/1033/324 545/1035/325 590/1036/325 +f 590/1036/325 545/1035/325 547/1037/326 591/1038/326 +f 591/1038/326 547/1037/326 549/1039/327 592/1040/327 +f 592/1041/327 549/1042/327 551/1043/328 593/1044/328 +f 593/1044/328 551/1043/328 553/1045/329 594/1046/329 +f 594/1046/329 553/1045/329 555/1047/330 595/1048/330 +f 595/1048/330 555/1047/330 557/1049/181 596/1050/181 +f 596/1050/181 557/1049/181 559/1051/331 597/1052/331 +f 597/1052/331 559/1051/331 561/1053/332 598/1054/332 +f 598/1054/332 561/1053/332 563/1055/333 599/1056/333 +f 599/1056/333 563/1055/333 565/1057/334 600/1058/334 +f 600/1059/334 565/1060/334 567/1061/335 601/1062/335 +f 601/1062/335 567/1061/335 569/1063/336 602/1064/336 +f 602/1064/336 569/1063/336 571/1065/337 603/1066/337 +f 603/1066/337 571/1065/337 509/996/184 572/995/184 +f 550/1067/338 552/1068/316 626/1069/316 625/1070/338 +s 0 +f 510/1071/192 508/1072/192 572/1073/192 573/1074/192 +f 512/1075/192 510/1071/192 573/1074/192 574/1076/192 +f 514/1077/192 512/1075/192 574/1076/192 575/1078/192 +f 516/1079/192 514/1077/192 575/1078/192 576/1080/192 +f 518/1081/192 516/1079/192 576/1080/192 577/1082/192 +f 520/1083/192 518/1081/192 577/1082/192 578/1084/192 +f 522/1085/192 520/1083/192 578/1084/192 579/1086/192 +f 524/1087/192 522/1085/192 579/1086/192 580/1088/192 +f 526/1089/192 524/1087/192 580/1088/192 581/1090/192 +f 528/1091/192 526/1089/192 581/1090/192 582/1092/192 +f 530/1093/192 528/1091/192 582/1092/192 583/1094/192 +f 532/1095/192 530/1093/192 583/1094/192 584/1096/192 +f 534/1097/192 532/1095/192 584/1096/192 585/1098/192 +f 536/1099/192 534/1097/192 585/1098/192 586/1100/192 +f 538/1101/192 536/1099/192 586/1100/192 587/1102/192 +f 540/1103/192 538/1101/192 587/1102/192 588/1104/192 +f 542/1105/192 540/1103/192 588/1104/192 589/1106/192 +f 544/1107/192 542/1105/192 589/1106/192 590/1108/192 +f 546/1109/192 544/1107/192 590/1108/192 591/1110/192 +f 548/1111/192 546/1109/192 591/1110/192 592/1112/192 +f 550/1113/192 548/1111/192 592/1112/192 593/1114/192 +f 552/1115/192 550/1113/192 593/1114/192 594/1116/192 +f 554/1117/192 552/1115/192 594/1116/192 595/1118/192 +f 556/1119/192 554/1117/192 595/1118/192 596/1120/192 +f 558/1121/192 556/1119/192 596/1120/192 597/1122/192 +f 560/1123/192 558/1121/192 597/1122/192 598/1124/192 +f 562/1125/192 560/1123/192 598/1124/192 599/1126/192 +f 564/1127/192 562/1125/192 599/1126/192 600/1128/192 +f 566/1129/192 564/1127/192 600/1128/192 601/1130/192 +f 568/1131/192 566/1129/192 601/1130/192 602/1132/192 +f 570/1133/192 568/1131/192 602/1132/192 603/1134/192 +f 508/1072/192 570/1133/192 603/1134/192 572/1073/192 +s 1 +f 524/1135/181 526/1136/331 613/1137/331 612/1138/181 +f 552/1068/316 554/1139/317 627/1140/317 626/1069/316 +f 526/1136/331 528/1141/332 614/1142/332 613/1137/331 +f 554/1139/317 556/1143/178 628/1144/178 627/1140/317 +f 528/1141/332 530/1145/333 615/1146/333 614/1142/332 +f 556/1143/178 558/1147/318 629/1148/318 628/1144/178 +f 530/1145/333 532/1149/334 616/1150/334 615/1146/333 +f 558/1147/318 560/1151/319 630/1152/319 629/1148/318 +f 532/1153/334 534/1154/335 617/1155/335 616/1156/334 +f 560/1151/319 562/1157/320 631/1158/320 630/1152/319 +f 534/1154/335 536/1159/336 618/1160/336 617/1155/335 +f 508/1161/94 510/1162/324 605/1163/324 604/1164/94 +f 562/1157/320 564/1165/233 632/1166/233 631/1158/320 +f 536/1159/336 538/1167/337 619/1168/337 618/1160/336 +f 510/1162/324 512/1169/325 606/1170/325 605/1163/324 +f 564/1171/233 566/1172/321 633/1173/321 632/1174/233 +f 538/1167/337 540/1175/184 620/1176/184 619/1168/337 +f 512/1169/325 514/1177/326 607/1178/326 606/1170/325 +f 566/1172/321 568/1179/322 634/1180/322 633/1173/321 +f 540/1175/184 542/1181/312 621/1182/312 620/1176/184 +f 514/1177/326 516/1183/327 608/1184/327 607/1178/326 +f 568/1179/322 570/1185/323 635/1186/323 634/1180/322 +f 542/1181/312 544/1187/313 622/1188/313 621/1182/312 +f 516/1189/327 518/1190/328 609/1191/328 608/1192/327 +f 570/1185/323 508/1161/94 604/1164/94 635/1186/323 +f 544/1187/313 546/1193/314 623/1194/314 622/1188/313 +f 518/1190/328 520/1195/329 610/1196/329 609/1191/328 +f 546/1193/314 548/1197/339 624/1198/339 623/1194/314 +f 520/1195/329 522/1199/330 611/1200/330 610/1196/329 +s 0 +f 548/1201/340 550/1067/340 625/1070/340 624/1202/340 +s 1 +f 522/1199/330 524/1135/181 612/1138/181 611/1200/330 +f 675/1203/341 666/1204/342 641/1205/343 642/1206/344 +f 736/1207/345 740/1208/346 667/1209/347 674/1210/348 +s 0 +f 640/1211/181 638/1212/181 636/1213/181 637/1214/181 +f 665/1215/181 639/1216/181 638/1212/181 640/1211/181 +s 1 +f 673/1217/349 669/1218/350 744/1219/351 739/1220/352 +s 0 +f 669/1218/353 671/1221/353 639/1222/353 665/1223/353 745/1224/353 744/1219/353 +s 1 +f 642/1206/344 641/1205/343 670/1225/354 672/1226/355 +f 677/1227/356 673/1217/349 739/1220/352 735/1228/357 +f 732/1229/358 736/1207/345 674/1210/348 678/1230/359 +f 681/1231/360 677/1227/356 735/1228/357 731/1232/361 +f 728/1233/362 732/1229/358 678/1230/359 682/1234/363 +f 685/1235/364 681/1231/360 731/1232/361 727/1236/365 +f 724/1237/366 728/1233/362 682/1234/363 686/1238/367 +f 689/1239/368 685/1235/364 727/1236/365 723/1240/369 +f 720/1241/370 724/1237/366 686/1238/367 690/1242/371 +f 693/1243/372 689/1239/368 723/1240/369 719/1244/373 +f 716/1245/374 720/1241/370 690/1242/371 694/1246/375 +f 697/1247/376 693/1243/372 719/1244/373 715/1248/377 +f 712/1249/378 716/1245/374 694/1246/375 698/1250/379 +f 701/1251/380 697/1247/376 715/1248/377 709/1252/381 +f 707/1253/382 712/1249/378 698/1250/379 703/1254/383 +s 0 +f 651/1255/384 702/1256/384 701/1251/384 709/1252/384 711/1257/384 655/1258/384 +f 653/1259/385 708/1260/385 707/1253/385 703/1254/385 705/1261/385 652/1262/385 +f 654/1263/386 656/1264/386 706/1265/386 708/1266/386 653/1267/386 +s 1 +f 656/1264/387 657/1268/388 713/1269/389 706/1265/390 +f 657/1270/388 658/1271/391 717/1272/392 713/1273/389 +f 710/1274/393 714/1275/394 657/1268/388 656/1264/387 +s 0 +f 655/1276/386 711/1277/386 710/1274/386 656/1264/386 654/1263/386 +s 1 +f 714/1278/394 718/1279/395 658/1271/391 657/1270/388 +f 658/1271/391 659/1280/396 721/1281/397 717/1272/392 +f 718/1279/395 722/1282/398 659/1280/396 658/1271/391 +f 659/1280/396 660/1283/399 725/1284/400 721/1281/397 +f 722/1282/398 726/1285/401 660/1283/399 659/1280/396 +f 660/1283/399 661/1286/402 729/1287/403 725/1284/400 +f 726/1285/401 730/1288/404 661/1286/402 660/1283/399 +f 661/1286/402 662/1289/405 733/1290/406 729/1287/403 +f 730/1288/404 734/1291/407 662/1289/405 661/1286/402 +f 662/1292/405 663/1293/408 737/1294/409 733/1295/406 +f 734/1296/407 738/1297/410 663/1293/408 662/1292/405 +f 663/1293/408 664/1298/411 741/1299/412 737/1294/409 +f 738/1297/410 743/1300/413 664/1298/411 663/1293/408 +s 0 +f 664/1298/414 640/1301/414 637/1302/414 742/1303/414 741/1299/414 +f 743/1300/414 745/1304/414 665/1305/414 640/1301/414 664/1298/414 +f 641/1205/415 638/1306/415 639/1307/415 671/1308/415 670/1225/415 +s 1 +f 643/1309/416 642/1206/344 672/1226/355 676/1310/417 +s 0 +f 666/1204/415 668/1311/415 636/1312/415 638/1306/415 641/1205/415 +s 1 +f 679/1313/418 675/1203/341 642/1206/344 643/1309/416 +f 644/1314/419 643/1315/416 676/1316/417 680/1317/420 +f 683/1318/421 679/1319/418 643/1315/416 644/1314/419 +f 645/1320/422 644/1314/419 680/1317/420 684/1321/423 +f 687/1322/424 683/1318/421 644/1314/419 645/1320/422 +f 646/1323/425 645/1320/422 684/1321/423 688/1324/426 +f 691/1325/427 687/1322/424 645/1320/422 646/1323/425 +f 647/1326/428 646/1323/425 688/1324/426 692/1327/429 +f 695/1328/430 691/1325/427 646/1323/425 647/1326/428 +f 648/1329/431 647/1326/428 692/1327/429 696/1330/432 +f 699/1331/433 695/1328/430 647/1326/428 648/1329/431 +f 649/1332/434 648/1333/431 696/1334/432 700/1335/435 +f 704/1336/436 699/1337/433 648/1333/431 649/1332/434 +s 0 +f 650/1338/437 649/1332/437 700/1335/437 702/1339/437 651/1340/437 +f 652/1341/437 705/1342/437 704/1336/437 649/1332/437 650/1338/437 +s 1 +f 666/1343/342 667/1344/347 668/1345/438 +f 669/1346/350 670/1347/354 671/1348/439 +f 700/1349/435 701/1350/380 702/1351/440 +s 0 +f 703/1352/441 704/1353/441 705/1354/441 +s 1 +f 706/1355/390 707/1253/382 708/1260/442 +f 709/1252/381 710/1356/393 711/1257/443 +f 740/1357/346 741/1358/412 742/1359/444 +f 743/1360/413 744/1361/351 745/1362/445 +f 743/1363/413 738/1364/410 739/1220/352 744/1219/351 +f 740/1208/346 736/1207/345 737/1365/409 741/1366/412 +f 738/1364/410 734/1367/407 735/1228/357 739/1220/352 +f 736/1207/345 732/1229/358 733/1368/406 737/1365/409 +f 734/1367/407 730/1369/404 731/1232/361 735/1228/357 +f 732/1229/358 728/1233/362 729/1370/403 733/1368/406 +f 730/1369/404 726/1371/401 727/1236/365 731/1232/361 +f 728/1233/362 724/1237/366 725/1372/400 729/1370/403 +f 726/1371/401 722/1373/398 723/1240/369 727/1236/365 +f 724/1237/366 720/1241/370 721/1374/397 725/1372/400 +f 722/1373/398 718/1375/395 719/1244/373 723/1240/369 +f 720/1241/370 716/1245/374 717/1376/392 721/1374/397 +f 718/1375/395 714/1377/394 715/1248/377 719/1244/373 +f 716/1245/374 712/1249/378 713/1378/389 717/1376/392 +f 714/1377/394 710/1356/393 709/1252/381 715/1248/377 +f 712/1249/378 707/1253/382 706/1355/390 713/1378/389 +f 703/1254/383 698/1250/379 699/1379/433 704/1380/436 +f 697/1247/376 701/1251/380 700/1381/435 696/1382/432 +f 698/1250/379 694/1246/375 695/1383/430 699/1379/433 +f 693/1243/372 697/1247/376 696/1382/432 692/1384/429 +f 694/1246/375 690/1242/371 691/1385/427 695/1383/430 +f 689/1239/368 693/1243/372 692/1384/429 688/1386/426 +f 690/1242/371 686/1238/367 687/1387/424 691/1385/427 +f 685/1235/364 689/1239/368 688/1386/426 684/1388/423 +f 686/1238/367 682/1234/363 683/1389/421 687/1387/424 +f 681/1231/360 685/1235/364 684/1388/423 680/1390/420 +f 682/1234/363 678/1230/359 679/1391/418 683/1389/421 +f 677/1227/356 681/1231/360 680/1390/420 676/1392/417 +f 678/1230/359 674/1210/348 675/1393/341 679/1391/418 +f 673/1217/349 677/1227/356 676/1392/417 672/1394/355 +f 674/1210/348 667/1209/347 666/1395/342 675/1393/341 +f 669/1218/350 673/1217/349 672/1394/355 670/1396/354 +s 0 +f 740/1208/446 742/1397/446 637/1398/446 636/1399/446 668/1400/446 667/1209/446 +f 882/1401/181 879/1402/181 876/1403/181 881/1404/181 +f 882/1405/192 881/1406/192 880/1407/192 748/1408/192 749/1409/192 883/1410/192 +f 851/1411/94 785/1412/94 784/1413/94 850/1414/94 +f 871/1415/447 768/1416/447 772/1417/447 866/1418/447 +f 762/1419/178 763/1420/178 752/1421/178 753/1422/178 +f 881/1404/334 876/1403/334 877/1423/334 880/1424/334 +f 811/1425/94 778/1426/94 777/1427/94 810/1428/94 +f 755/1429/178 754/1430/178 756/1431/178 757/1432/178 +f 760/1433/178 761/1434/178 758/1435/178 759/1436/178 +f 750/1437/178 751/1438/178 765/1439/178 764/1440/178 +f 831/1441/94 780/1442/94 767/1443/94 830/1444/94 +f 830/1445/180 767/1446/180 766/1447/180 840/1448/180 +f 821/1449/184 781/1450/184 779/1451/184 820/1452/184 +f 840/1453/184 766/1454/184 771/1455/184 845/1456/184 +f 861/1457/184 783/1458/184 782/1459/184 860/1460/184 +f 791/1461/448 775/1462/448 774/1463/448 790/1464/448 +f 801/1465/447 773/1466/447 776/1467/447 800/1468/447 +f 820/1469/448 779/1470/448 778/1471/448 811/1472/448 +f 810/1473/447 777/1474/447 781/1475/447 821/1476/447 +f 860/1477/448 782/1478/448 785/1479/448 851/1480/448 +f 845/1481/448 771/1482/448 780/1483/448 831/1484/448 +f 850/1485/447 784/1486/447 783/1487/447 861/1488/447 +f 800/1489/184 776/1490/184 775/1491/184 791/1492/184 +f 790/1493/94 774/1494/94 773/1495/94 801/1496/94 +f 753/1497/94 786/1498/94 805/1499/94 755/1500/94 +f 786/1498/94 787/1501/94 804/1502/94 805/1499/94 +f 787/1501/94 788/1503/94 803/1504/94 804/1502/94 +f 788/1503/94 789/1505/94 802/1506/94 803/1504/94 +f 789/1505/94 790/1493/94 801/1496/94 802/1506/94 +f 754/1507/184 796/1508/184 795/1509/184 752/1510/184 +f 796/1508/184 797/1511/184 794/1512/184 795/1509/184 +f 797/1511/184 798/1513/184 793/1514/184 794/1512/184 +f 798/1513/184 799/1515/184 792/1516/184 793/1514/184 +f 799/1515/184 800/1489/184 791/1492/184 792/1516/184 +f 755/1517/449 805/1518/449 796/1519/449 754/1520/449 +f 805/1518/450 804/1521/450 797/1522/450 796/1519/450 +f 804/1521/451 803/1523/451 798/1524/451 797/1522/451 +f 803/1523/452 802/1525/452 799/1526/452 798/1524/452 +f 802/1525/453 801/1465/453 800/1468/453 799/1526/453 +f 752/1527/454 795/1528/454 786/1529/454 753/1530/454 +f 795/1528/455 794/1531/455 787/1532/455 786/1529/455 +f 794/1531/456 793/1533/456 788/1534/456 787/1532/456 +f 793/1533/457 792/1535/457 789/1536/457 788/1534/457 +f 792/1535/458 791/1461/458 790/1464/458 789/1536/458 +f 760/1537/449 806/1538/449 825/1539/449 761/1540/449 +f 806/1538/450 807/1541/450 824/1542/450 825/1539/450 +f 807/1541/451 808/1543/451 823/1544/451 824/1542/451 +f 808/1543/452 809/1545/452 822/1546/452 823/1544/452 +f 809/1545/453 810/1473/453 821/1476/453 822/1546/453 +f 756/1547/454 816/1548/454 815/1549/454 757/1550/454 +f 816/1548/455 817/1551/455 814/1552/455 815/1549/455 +f 817/1551/456 818/1553/456 813/1554/456 814/1552/456 +f 818/1553/457 819/1555/457 812/1556/457 813/1554/457 +f 819/1555/458 820/1469/458 811/1472/458 812/1556/458 +f 761/1557/184 825/1558/184 816/1559/184 756/1560/184 +f 825/1558/184 824/1561/184 817/1562/184 816/1559/184 +f 824/1561/184 823/1563/184 818/1564/184 817/1562/184 +f 823/1563/184 822/1565/184 819/1566/184 818/1564/184 +f 822/1565/184 821/1449/184 820/1452/184 819/1566/184 +f 757/1567/94 815/1568/94 806/1569/94 760/1570/94 +f 815/1568/94 814/1571/94 807/1572/94 806/1569/94 +f 814/1571/94 813/1573/94 808/1574/94 807/1572/94 +f 813/1573/94 812/1575/94 809/1576/94 808/1574/94 +f 812/1575/94 811/1425/94 810/1428/94 809/1576/94 +f 758/1577/454 841/1578/454 835/1579/454 759/1580/454 +f 841/1578/455 842/1581/455 834/1582/455 835/1579/455 +f 842/1581/456 843/1583/456 833/1584/456 834/1582/456 +f 843/1583/457 844/1585/457 832/1586/457 833/1584/457 +f 844/1585/458 845/1481/458 831/1484/458 832/1586/458 +f 746/1587/184 836/1588/184 841/1589/184 758/1590/184 +f 836/1588/184 837/1591/184 842/1592/184 841/1589/184 +f 837/1591/184 838/1593/184 843/1594/184 842/1592/184 +f 838/1593/184 839/1595/184 844/1596/184 843/1594/184 +f 839/1595/184 840/1453/184 845/1456/184 844/1596/184 +f 747/1597/180 826/1598/180 836/1599/180 746/1600/180 +f 826/1598/180 827/1601/180 837/1602/180 836/1599/180 +f 827/1601/180 828/1603/180 838/1604/180 837/1602/180 +f 828/1603/180 829/1605/180 839/1606/180 838/1604/180 +f 829/1605/180 830/1445/180 840/1448/180 839/1606/180 +f 759/1607/94 835/1608/94 826/1609/94 747/1610/94 +f 835/1608/94 834/1611/94 827/1612/94 826/1609/94 +f 834/1611/94 833/1613/94 828/1614/94 827/1612/94 +f 833/1613/94 832/1615/94 829/1616/94 828/1614/94 +f 832/1615/94 831/1441/94 830/1444/94 829/1616/94 +f 762/1617/449 846/1618/449 865/1619/449 763/1620/449 +f 846/1618/459 847/1621/459 864/1622/459 865/1619/459 +f 847/1621/451 848/1623/451 863/1624/451 864/1622/451 +f 848/1623/452 849/1625/452 862/1626/452 863/1624/452 +f 849/1625/453 850/1485/453 861/1488/453 862/1626/453 +f 765/1627/454 856/1628/454 855/1629/454 764/1630/454 +f 856/1628/455 857/1631/455 854/1632/455 855/1629/455 +f 857/1631/456 858/1633/456 853/1634/456 854/1632/456 +f 858/1633/457 859/1635/457 852/1636/457 853/1634/457 +f 859/1635/458 860/1477/458 851/1480/458 852/1636/458 +f 763/1637/184 865/1638/184 856/1639/184 765/1640/184 +f 865/1638/184 864/1641/184 857/1642/184 856/1639/184 +f 864/1641/184 863/1643/184 858/1644/184 857/1642/184 +f 863/1643/184 862/1645/184 859/1646/184 858/1644/184 +f 862/1645/184 861/1457/184 860/1460/184 859/1646/184 +f 764/1647/94 855/1648/94 846/1649/94 762/1650/94 +f 855/1648/94 854/1651/94 847/1652/94 846/1649/94 +f 854/1651/94 853/1653/94 848/1654/94 847/1652/94 +f 853/1653/94 852/1655/94 849/1656/94 848/1654/94 +f 852/1655/94 851/1411/94 850/1414/94 849/1656/94 +f 750/1657/94 764/1647/94 762/1650/94 753/1497/94 755/1500/94 757/1567/94 760/1570/94 759/1607/94 747/1610/94 878/1658/94 883/1659/94 749/1660/94 769/1661/94 768/1662/94 871/1663/94 872/1664/94 873/1665/94 874/1666/94 875/1667/94 +f 751/1668/184 870/1669/184 869/1670/184 868/1671/184 867/1672/184 866/1673/184 772/1674/184 770/1675/184 748/1676/184 880/1677/184 877/1678/184 746/1587/184 758/1590/184 761/1557/184 756/1560/184 754/1507/184 752/1510/184 763/1637/184 765/1640/184 +f 750/1679/449 875/1680/449 870/1681/449 751/1682/449 +f 875/1680/450 874/1683/450 869/1684/450 870/1681/450 +f 874/1683/460 873/1685/460 868/1686/460 869/1684/460 +f 873/1685/452 872/1687/452 867/1688/452 868/1686/452 +f 872/1687/461 871/1415/461 866/1418/461 867/1688/461 +f 882/1401/327 883/1689/327 878/1690/327 879/1402/327 +f 749/1660/94 885/1691/94 886/1692/94 769/1661/94 +f 770/1675/184 887/1693/184 884/1694/184 748/1676/184 +f 748/1695/181 884/1696/181 885/1697/181 749/1698/181 +f 885/1691/94 889/1699/94 890/1700/94 886/1692/94 +f 884/1696/462 888/1701/462 889/1702/462 885/1697/462 +f 887/1693/184 891/1703/184 888/1704/184 884/1694/184 +f 896/1705/94 899/1706/94 923/1707/94 897/1708/94 +f 898/1709/184 894/1710/184 895/1711/184 921/1712/184 +f 896/1713/178 894/1714/178 898/1715/178 899/1716/178 +f 900/1717/184 904/1718/184 905/1719/184 901/1720/184 +f 896/1713/463 902/1721/463 900/1722/463 894/1714/463 +f 897/1708/94 903/1723/94 902/1724/94 896/1705/94 +f 894/1710/184 900/1717/184 901/1720/184 895/1711/184 +f 902/1721/178 906/1725/178 904/1726/178 900/1722/178 +f 903/1723/94 907/1727/94 906/1728/94 902/1724/94 +f 910/1729/94 914/1730/94 915/1731/94 911/1732/94 +f 912/1733/184 908/1734/184 909/1735/184 913/1736/184 +f 910/1737/178 908/1738/178 912/1739/178 914/1740/178 +f 916/1741/184 920/1742/184 921/1743/184 917/1744/184 +f 910/1737/463 918/1745/463 916/1746/463 908/1738/463 +f 911/1732/94 919/1747/94 918/1748/94 910/1729/94 +f 908/1734/184 916/1741/184 917/1744/184 909/1735/184 +f 918/1745/178 922/1749/178 920/1750/178 916/1746/178 +f 919/1747/94 923/1751/94 922/1752/94 918/1748/94 +f 926/1753/94 930/1754/94 951/1755/94 927/1756/94 +f 928/1757/184 924/1758/184 925/1759/184 929/1760/184 +f 926/1761/178 924/1762/178 928/1763/178 930/1764/178 +f 931/1765/184 935/1766/184 913/1767/184 932/1768/184 +f 926/1761/463 933/1769/463 931/1770/463 924/1762/463 +f 927/1756/94 934/1771/94 933/1772/94 926/1753/94 +f 924/1758/184 931/1765/184 932/1768/184 925/1759/184 +f 933/1769/178 936/1773/178 935/1774/178 931/1770/178 +f 934/1771/94 915/1775/94 936/1776/94 933/1772/94 +f 939/1777/94 943/1778/94 944/1779/94 940/1780/94 +f 941/1781/184 937/1782/184 938/1783/184 942/1784/184 +f 939/1785/178 937/1786/178 941/1787/178 943/1788/178 +f 945/1789/184 949/1790/184 929/1791/184 946/1792/184 +f 939/1785/464 947/1793/464 945/1794/464 937/1786/464 +f 940/1780/94 948/1795/94 947/1796/94 939/1777/94 +f 937/1782/184 945/1789/184 946/1792/184 938/1783/184 +f 947/1793/178 950/1797/178 949/1798/178 945/1794/178 +f 948/1795/94 951/1799/94 950/1800/94 947/1796/94 +f 954/1801/94 957/1802/94 958/1803/94 955/1804/94 +f 956/1805/184 952/1806/184 953/1807/184 977/1808/184 +f 954/1809/178 952/1810/178 956/1811/178 957/1812/178 +f 959/1813/184 963/1814/184 942/1815/184 960/1816/184 +f 954/1809/463 961/1817/463 959/1818/463 952/1810/463 +f 955/1804/94 962/1819/94 961/1820/94 954/1801/94 +f 952/1806/184 959/1813/184 960/1816/184 953/1807/184 +f 961/1817/178 964/1821/178 963/1822/178 959/1818/178 +f 962/1819/94 944/1823/94 964/1824/94 961/1820/94 +f 967/1825/94 971/1826/94 993/1827/94 968/1828/94 +f 969/1829/184 965/1830/184 966/1831/184 970/1832/184 +f 967/1833/178 965/1834/178 969/1835/178 971/1836/178 +f 972/1837/184 976/1838/184 977/1839/184 973/1840/184 +f 967/1833/464 974/1841/464 972/1842/464 965/1834/464 +f 968/1828/94 975/1843/94 974/1844/94 967/1825/94 +f 965/1830/184 972/1837/184 973/1840/184 966/1831/184 +f 974/1841/178 978/1845/178 976/1846/178 972/1842/178 +f 975/1843/94 958/1847/94 978/1848/94 974/1844/94 +f 981/1849/94 985/1850/94 986/1851/94 982/1852/94 +f 983/1853/184 979/1854/184 980/1855/184 984/1856/184 +f 981/1857/178 979/1858/178 983/1859/178 985/1860/178 +f 987/1861/184 991/1862/184 970/1863/184 988/1864/184 +f 981/1857/464 989/1865/464 987/1866/464 979/1858/464 +f 982/1852/94 990/1867/94 989/1868/94 981/1849/94 +f 979/1854/184 987/1861/184 988/1864/184 980/1855/184 +f 989/1865/178 992/1869/178 991/1870/178 987/1866/178 +f 990/1867/94 993/1871/94 992/1872/94 989/1868/94 +f 996/1873/94 999/1874/94 1021/1875/94 997/1876/94 +f 998/1877/184 994/1878/184 995/1879/184 1019/1880/184 +f 996/1881/178 994/1882/178 998/1883/178 999/1884/178 +f 1000/1885/184 1004/1886/184 984/1887/184 1001/1888/184 +f 996/1881/463 1002/1889/463 1000/1890/463 994/1882/463 +f 997/1876/94 1003/1891/94 1002/1892/94 996/1873/94 +f 994/1878/184 1000/1885/184 1001/1888/184 995/1879/184 +f 1002/1889/178 1005/1893/178 1004/1894/178 1000/1890/178 +f 1003/1891/94 986/1895/94 1005/1896/94 1002/1892/94 +f 1008/1897/94 1012/1898/94 1013/1899/94 1009/1900/94 +f 1010/1901/184 1006/1902/184 1007/1903/184 1011/1904/184 +f 1008/1905/178 1006/1906/178 1010/1907/178 1012/1908/178 +f 1014/1909/184 1018/1910/184 1019/1911/184 1015/1912/184 +f 1008/1905/464 1016/1913/464 1014/1914/464 1006/1906/464 +f 1009/1900/94 1017/1915/94 1016/1916/94 1008/1897/94 +f 1006/1902/184 1014/1909/184 1015/1912/184 1007/1903/184 +f 1016/1913/178 1020/1917/178 1018/1918/178 1014/1914/178 +f 1017/1915/94 1021/1919/94 1020/1920/94 1016/1916/94 +f 1024/1921/94 1028/1922/94 1029/1923/94 1025/1924/94 +f 1026/1925/184 1022/1926/184 1023/1927/184 1027/1928/184 +f 1024/1929/178 1022/1930/178 1026/1931/178 1028/1932/178 +f 1030/1933/184 1034/1934/184 1011/1935/184 1031/1936/184 +f 1024/1929/463 1032/1937/463 1030/1938/463 1022/1930/463 +f 1025/1924/94 1033/1939/94 1032/1940/94 1024/1921/94 +f 1022/1926/184 1030/1933/184 1031/1936/184 1023/1927/184 +f 1032/1937/178 1035/1941/178 1034/1942/178 1030/1938/178 +f 1033/1939/94 1013/1943/94 1035/1944/94 1032/1940/94 +f 1038/1945/94 1041/1946/94 1062/1947/94 1039/1948/94 +f 1040/1949/184 1036/1950/184 1037/1951/184 1060/1952/184 +f 1038/1953/178 1036/1954/178 1040/1955/178 1041/1956/178 +f 1042/1957/184 1046/1958/184 1027/1959/184 1043/1960/184 +f 1038/1953/464 1044/1961/464 1042/1962/464 1036/1954/464 +f 1039/1948/94 1045/1963/94 1044/1964/94 1038/1945/94 +f 1036/1950/184 1042/1957/184 1043/1960/184 1037/1951/184 +f 1044/1961/178 1047/1965/178 1046/1966/178 1042/1962/178 +f 1045/1963/94 1029/1967/94 1047/1968/94 1044/1964/94 +f 1050/1969/94 1054/1970/94 1076/1971/94 1051/1972/94 +f 1052/1973/184 1048/1974/184 1049/1975/184 1053/1976/184 +f 1050/1977/178 1048/1978/178 1052/1979/178 1054/1980/178 +f 1055/1981/184 1059/1982/184 1060/1983/184 1056/1984/184 +f 1050/1977/463 1057/1985/463 1055/1986/463 1048/1978/463 +f 1051/1972/94 1058/1987/94 1057/1988/94 1050/1969/94 +f 1048/1974/184 1055/1981/184 1056/1984/184 1049/1975/184 +f 1057/1985/178 1061/1989/178 1059/1990/178 1055/1986/178 +f 1058/1987/94 1062/1991/94 1061/1992/94 1057/1988/94 +f 1065/1993/94 1069/1994/94 1091/1995/94 1066/1996/94 +f 1067/1997/184 1063/1998/184 1064/1999/184 1068/2000/184 +f 1065/2001/178 1063/2002/178 1067/2003/178 1069/2004/178 +f 1070/2005/184 1074/2006/184 1053/2007/184 1071/2008/184 +f 1065/2001/463 1072/2009/463 1070/2010/463 1063/2002/463 +f 1066/1996/94 1073/2011/94 1072/2012/94 1065/1993/94 +f 1063/1998/184 1070/2005/184 1071/2008/184 1064/1999/184 +f 1072/2009/178 1075/2013/178 1074/2014/178 1070/2010/178 +f 1073/2011/94 1076/2015/94 1075/2016/94 1072/2012/94 +f 1079/2017/94 1083/2018/94 1084/2019/94 1080/2020/94 +f 1081/2021/184 1077/2022/184 1078/2023/184 1082/2024/184 +f 1079/2025/178 1077/2026/178 1081/2027/178 1083/2028/178 +f 1085/2029/184 1089/2030/184 1068/2031/184 1086/2032/184 +f 1079/2025/464 1087/2033/464 1085/2034/464 1077/2026/464 +f 1080/2020/94 1088/2035/94 1087/2036/94 1079/2017/94 +f 1077/2022/184 1085/2029/184 1086/2032/184 1078/2023/184 +f 1087/2033/178 1090/2037/178 1089/2038/178 1085/2034/178 +f 1088/2035/94 1091/2039/94 1090/2040/94 1087/2036/94 +f 906/2041/192 907/2042/192 905/2043/192 904/2044/192 +f 1083/2045/180 1081/2046/180 1082/2047/180 1084/2048/180 +f 1094/2049/94 1095/2050/94 1092/2051/94 1098/2052/94 1099/2053/94 +f 1096/2054/180 1097/2055/180 1095/2056/180 1094/2057/180 +f 1100/2058/184 1101/2059/184 1093/2060/184 1097/2061/184 1096/2062/184 +f 1098/2063/192 1092/2064/192 1093/2065/192 1101/2066/192 +f 1097/2067/181 1093/2068/181 1092/2069/181 1095/2070/181 +f 1100/2071/465 1099/2072/465 1098/2073/465 1101/2074/465 +f 1100/2071/178 1096/2075/178 1094/2076/178 1099/2072/178 +f 1125/2077/180 1123/2078/180 1107/2079/180 1113/2080/180 +f 1117/2081/466 1115/2082/466 1103/2083/466 1110/2084/466 1113/2085/466 1107/2086/466 +f 1110/2087/192 1103/2088/192 1105/2089/192 1111/2090/192 1137/2091/192 1136/2092/192 +f 1110/2084/94 1102/2093/94 1106/2094/94 1113/2085/94 +f 1102/2095/178 1135/2096/178 1134/2097/178 1104/2098/178 1108/2099/178 1106/2100/178 +f 1114/2101/467 1116/2102/467 1109/2103/467 1112/2104/467 1111/2105/467 1105/2106/467 +f 1115/2082/94 1117/2081/94 1118/2107/94 1119/2108/94 +f 1111/2105/184 1112/2104/184 1108/2109/184 1104/2110/184 +f 1136/2092/192 1135/2111/192 1102/2112/192 1110/2087/192 +f 1133/2113/181 1131/2114/181 1119/2115/181 1118/2116/181 +f 1116/2102/184 1114/2101/184 1120/2117/184 1121/2118/184 +f 1127/2119/192 1115/2120/192 1119/2121/192 1131/2122/192 +f 1128/2123/180 1116/2124/180 1121/2125/180 1132/2126/180 +f 1117/2127/180 1129/2128/180 1133/2129/180 1118/2130/180 +f 1128/2131/94 1132/2132/94 1130/2133/94 1126/2134/94 +f 1114/2135/192 1126/2136/192 1130/2137/192 1120/2138/192 +f 1127/2139/181 1129/2140/181 1128/2141/181 1126/2142/181 +f 1121/2143/181 1120/2144/181 1130/2145/181 1132/2146/181 +f 1129/2147/184 1127/2148/184 1131/2149/184 1133/2150/184 +f 1128/2141/181 1129/2140/181 1117/2151/181 1107/2152/181 1123/2153/181 1122/2154/181 1109/2155/181 1116/2156/181 +f 1124/2157/180 1125/2077/180 1113/2080/180 1106/2158/180 1108/2159/180 1112/2160/180 +f 1105/2161/181 1103/2162/181 1115/2163/181 1127/2139/181 1126/2142/181 1114/2164/181 +f 1112/2160/180 1109/2165/180 1122/2166/180 1124/2157/180 +f 1124/2157/180 1122/2166/180 1123/2078/180 1125/2077/180 +f 1111/2090/192 1104/2167/192 1134/2168/192 1137/2091/192 +f 1135/2169/94 1136/2170/94 1140/2171/94 1139/2172/94 +f 1141/2173/192 1138/2174/192 1139/2175/192 1140/2176/192 +f 1136/2177/181 1137/2178/181 1141/2179/181 1140/2180/181 +f 1134/2097/178 1135/2096/178 1139/2181/178 1138/2182/178 +f 1137/2183/184 1134/2184/184 1138/2185/184 1141/2186/184 +f 1150/2187/468 1152/2188/468 1145/2189/468 1143/2190/468 +f 1146/2191/184 1155/2192/184 1179/2193/184 1188/2194/184 +f 1171/2195/469 1184/2196/469 1161/2197/469 1159/2198/469 +f 1150/2187/94 1143/2190/94 1167/2199/94 1176/2200/94 +f 1185/2201/470 1182/2202/470 1164/2203/470 1160/2204/470 +f 1146/2191/471 1148/2205/471 1157/2206/471 1155/2192/471 +f 1173/2207/472 1170/2208/472 1158/2209/472 1162/2210/472 +f 1183/2211/473 1172/2212/473 1163/2213/473 1165/2214/473 +f 1161/2215/474 1165/2216/474 1163/2217/474 1159/2218/474 +f 1176/2200/475 1167/2199/475 1169/2219/475 1175/2220/475 +f 1154/2221/476 1156/2222/476 1153/2223/476 1151/2224/476 +f 1188/2194/477 1179/2193/477 1181/2225/477 1187/2226/477 +f 1178/2227/478 1177/2228/478 1174/2229/478 1180/2230/478 +f 1142/2231/479 1144/2232/479 1149/2233/479 1147/2234/479 +f 1175/2220/480 1169/2219/480 1170/2208/480 1173/2207/480 +f 1180/2235/481 1174/2236/481 1172/2212/481 1183/2211/481 +f 1154/2221/180 1151/2224/180 1177/2228/180 1178/2227/180 +f 1187/2226/482 1181/2225/482 1182/2202/482 1185/2201/482 +f 1156/2237/181 1157/2238/181 1148/2239/181 1149/2240/181 1144/2241/181 1145/2242/181 1152/2243/181 1153/2244/181 +f 1166/2245/483 1189/2246/483 1186/2247/483 1168/2248/483 +f 1168/2248/484 1186/2247/484 1184/2249/484 1171/2250/484 +f 1143/2251/485 1145/2252/485 1144/2253/485 1142/2254/485 +f 1148/2255/486 1146/2256/486 1147/2257/486 1149/2258/486 +f 1156/2259/487 1154/2260/487 1155/2261/487 1157/2262/487 +f 1152/2263/488 1150/2264/488 1151/2265/488 1153/2266/488 +f 1165/2267/489 1161/2268/489 1160/2269/489 1164/2270/489 +f 1159/2271/490 1163/2272/490 1162/2273/490 1158/2274/490 +f 1171/2275/491 1159/2276/491 1158/2209/491 1170/2208/491 +f 1177/2277/492 1151/2278/492 1150/2187/492 1176/2200/492 +f 1183/2211/493 1165/2214/493 1164/2279/493 1182/2280/493 +f 1189/2281/494 1147/2282/494 1146/2191/494 1188/2194/494 +f 1142/2283/495 1166/2284/495 1167/2199/495 1143/2190/495 +f 1166/2245/496 1168/2248/496 1169/2285/496 1167/2286/496 +f 1168/2287/497 1171/2275/497 1170/2208/497 1169/2219/497 +f 1163/2213/498 1172/2212/498 1173/2288/498 1162/2289/498 +f 1172/2290/499 1174/2291/499 1175/2220/499 1173/2207/499 +f 1174/2291/500 1177/2277/500 1176/2200/500 1175/2220/500 +f 1154/2292/501 1178/2293/501 1179/2193/501 1155/2192/501 +f 1178/2293/502 1180/2294/502 1181/2225/502 1179/2193/502 +f 1180/2294/503 1183/2295/503 1182/2202/503 1181/2225/503 +f 1161/2296/504 1184/2297/504 1185/2201/504 1160/2204/504 +f 1184/2297/505 1186/2298/505 1187/2226/505 1185/2201/505 +f 1186/2247/506 1189/2246/506 1188/2299/506 1187/2300/506 +f 1142/2231/192 1147/2234/192 1189/2246/192 1166/2245/192 +f 1190/2301/507 1191/2302/507 1193/2303/507 1192/2304/507 +f 1192/2305/508 1193/2306/508 1197/2307/508 1196/2308/508 +f 1196/2308/509 1197/2307/509 1195/2309/509 1194/2310/509 +f 1194/2311/510 1195/2312/510 1191/2302/510 1190/2301/510 +f 1197/2313/181 1193/2314/181 1191/2315/181 1195/2316/181 +f 1198/2317/507 1199/2318/507 1201/2319/507 1200/2320/507 +f 1200/2321/508 1201/2322/508 1205/2323/508 1204/2324/508 +f 1204/2324/509 1205/2323/509 1203/2325/509 1202/2326/509 +f 1202/2327/510 1203/2328/510 1199/2318/510 1198/2317/510 +f 1205/2329/181 1201/2330/181 1199/2331/181 1203/2332/181 +f 1206/2333/507 1207/2334/507 1209/2335/507 1208/2336/507 +f 1208/2337/508 1209/2338/508 1213/2339/508 1212/2340/508 +f 1212/2340/509 1213/2339/509 1211/2341/509 1210/2342/509 +f 1210/2343/510 1211/2344/510 1207/2334/510 1206/2333/510 +f 1213/2345/181 1209/2346/181 1207/2347/181 1211/2348/181 +f 1214/2349/507 1215/2350/507 1217/2351/507 1216/2352/507 +f 1216/2353/508 1217/2354/508 1221/2355/508 1220/2356/508 +f 1220/2356/509 1221/2355/509 1219/2357/509 1218/2358/509 +f 1218/2359/510 1219/2360/510 1215/2350/510 1214/2349/510 +f 1221/2361/181 1217/2362/181 1215/2363/181 1219/2364/181 +f 1222/2365/507 1223/2366/507 1225/2367/507 1224/2368/507 +f 1224/2369/508 1225/2370/508 1229/2371/508 1228/2372/508 +f 1228/2372/509 1229/2371/509 1227/2373/509 1226/2374/509 +f 1226/2375/510 1227/2376/510 1223/2366/510 1222/2365/510 +f 1229/2377/181 1225/2378/181 1223/2379/181 1227/2380/181 +f 1230/2381/507 1231/2382/507 1233/2383/507 1232/2384/507 +f 1232/2385/508 1233/2386/508 1237/2387/508 1236/2388/508 +f 1236/2388/509 1237/2387/509 1235/2389/509 1234/2390/509 +f 1234/2391/510 1235/2392/510 1231/2382/510 1230/2381/510 +f 1237/2393/181 1233/2394/181 1231/2395/181 1235/2396/181 +f 1238/2397/507 1239/2398/507 1241/2399/507 1240/2400/507 +f 1240/2401/508 1241/2402/508 1245/2403/508 1244/2404/508 +f 1244/2404/509 1245/2403/509 1243/2405/509 1242/2406/509 +f 1242/2407/510 1243/2408/510 1239/2398/510 1238/2397/510 +f 1245/2409/181 1241/2410/181 1239/2411/181 1243/2412/181 +f 1246/2413/507 1247/2414/507 1249/2415/507 1248/2416/507 +f 1248/2417/508 1249/2418/508 1253/2419/508 1252/2420/508 +f 1252/2420/509 1253/2419/509 1251/2421/509 1250/2422/509 +f 1250/2423/510 1251/2424/510 1247/2414/510 1246/2413/510 +f 1253/2425/181 1249/2426/181 1247/2427/181 1251/2428/181 +f 1254/2429/507 1255/2430/507 1257/2431/507 1256/2432/507 +f 1256/2433/508 1257/2434/508 1261/2435/508 1260/2436/508 +f 1260/2436/509 1261/2435/509 1259/2437/509 1258/2438/509 +f 1258/2439/510 1259/2440/510 1255/2430/510 1254/2429/510 +f 1261/2441/181 1257/2442/181 1255/2443/181 1259/2444/181 +f 1262/2445/507 1263/2446/507 1265/2447/507 1264/2448/507 +f 1264/2449/508 1265/2450/508 1269/2451/508 1268/2452/508 +f 1268/2452/509 1269/2451/509 1267/2453/509 1266/2454/509 +f 1266/2455/510 1267/2456/510 1263/2446/510 1262/2445/510 +f 1269/2457/181 1265/2458/181 1263/2459/181 1267/2460/181 +f 1270/2461/507 1271/2462/507 1273/2463/507 1272/2464/507 +f 1272/2465/508 1273/2466/508 1277/2467/508 1276/2468/508 +f 1276/2468/509 1277/2467/509 1275/2469/509 1274/2470/509 +f 1274/2471/510 1275/2472/510 1271/2462/510 1270/2461/510 +f 1277/2473/181 1273/2474/181 1271/2475/181 1275/2476/181 +f 1278/2477/507 1279/2478/507 1281/2479/507 1280/2480/507 +f 1280/2481/508 1281/2482/508 1285/2483/508 1284/2484/508 +f 1284/2484/509 1285/2483/509 1283/2485/509 1282/2486/509 +f 1282/2487/510 1283/2488/510 1279/2478/510 1278/2477/510 +f 1285/2489/181 1281/2490/181 1279/2491/181 1283/2492/181 +f 1286/2493/507 1287/2494/507 1289/2495/507 1288/2496/507 +f 1288/2497/508 1289/2498/508 1293/2499/508 1292/2500/508 +f 1292/2500/509 1293/2499/509 1291/2501/509 1290/2502/509 +f 1290/2503/510 1291/2504/510 1287/2494/510 1286/2493/510 +f 1293/2505/181 1289/2506/181 1287/2507/181 1291/2508/181 +f 1294/2509/507 1295/2510/507 1297/2511/507 1296/2512/507 +f 1296/2513/508 1297/2514/508 1301/2515/508 1300/2516/508 +f 1300/2516/509 1301/2515/509 1299/2517/509 1298/2518/509 +f 1298/2519/510 1299/2520/510 1295/2510/510 1294/2509/510 +f 1301/2521/181 1297/2522/181 1295/2523/181 1299/2524/181 +f 1302/2525/507 1303/2526/507 1305/2527/507 1304/2528/507 +f 1304/2529/508 1305/2530/508 1309/2531/508 1308/2532/508 +f 1308/2532/509 1309/2531/509 1307/2533/509 1306/2534/509 +f 1306/2535/510 1307/2536/510 1303/2526/510 1302/2525/510 +f 1309/2537/181 1305/2538/181 1303/2539/181 1307/2540/181 +f 1313/2541/184 1325/2542/184 1320/2543/184 1311/2544/184 +f 1324/2545/181 1323/2546/181 1319/2547/181 1321/2548/181 +f 1322/2549/94 1312/2550/94 1310/2551/94 1318/2552/94 +f 1312/2553/178 1313/2554/178 1311/2555/178 1310/2556/178 +f 1318/2552/94 1310/2551/94 1317/2557/94 +f 1312/2558/192 1322/2559/192 1323/2560/192 1324/2561/192 1325/2562/192 1313/2563/192 +f 1310/2556/511 1311/2555/511 1314/2564/511 1315/2565/511 1316/2566/511 1317/2567/511 +f 1321/2568/512 1319/2569/512 1316/2570/512 1315/2571/512 +f 1314/2572/513 1320/2573/513 1321/2568/513 1315/2571/513 +f 1322/2549/514 1318/2552/514 1319/2574/514 1323/2575/514 +f 1316/2570/515 1319/2569/515 1318/2576/515 1317/2577/515 +f 1320/2543/516 1325/2542/516 1324/2578/516 1321/2579/516 +f 1311/2544/184 1320/2543/184 1314/2580/184 +f 389/725/517 390/724/517 323/566/517 +f 324/563/517 323/566/517 325/564/517 +usemtl Black_steel +f 495/745/181 402/746/181 420/747/181 464/748/181 494/749/181 +f 501/750/178 405/751/178 426/752/178 462/753/178 500/754/178 +f 498/755/274 404/756/274 424/757/274 454/758/274 497/759/274 +f 504/760/275 403/761/275 422/762/275 460/763/275 503/764/275 +f 507/765/276 400/766/276 428/767/276 456/768/276 506/769/276 +f 401/770/180 421/771/180 420/772/180 402/773/180 423/774/180 422/775/180 403/776/180 425/777/180 424/778/180 404/779/180 427/780/180 426/781/180 405/782/180 429/783/180 428/784/180 400/785/180 419/786/180 418/787/180 +f 463/788/178 427/789/178 404/790/178 498/791/178 496/792/178 +f 454/758/274 424/757/274 425/793/274 455/794/274 +f 412/795/277 430/796/277 431/797/277 413/798/277 +f 481/799/192 410/800/192 413/801/192 480/802/192 +f 443/803/278 459/804/278 505/805/278 467/806/278 +f 459/804/278 419/807/278 400/766/278 507/765/278 505/805/278 +f 456/768/276 428/767/276 429/808/276 457/809/276 +f 416/810/279 432/811/279 433/812/279 417/813/279 +f 414/814/192 417/815/192 488/816/192 489/817/192 +f 445/818/181 465/819/181 490/820/181 471/821/181 +f 465/819/181 421/822/181 401/823/181 492/824/181 490/820/181 +f 458/825/278 418/826/278 419/807/278 459/804/278 +f 406/827/280 434/828/280 435/829/280 407/830/280 +f 469/831/192 416/832/192 407/833/192 468/834/192 +f 449/835/274 455/794/274 502/836/274 479/837/274 +f 455/794/274 425/793/274 403/761/274 504/760/274 502/836/274 +f 460/763/275 422/762/275 423/838/275 461/839/275 +f 410/840/281 436/841/281 437/842/281 411/843/281 +f 408/844/192 477/845/192 474/846/192 444/847/192 +f 453/848/276 457/809/276 499/849/276 487/850/276 +f 457/809/276 429/808/276 405/851/276 501/852/276 499/849/276 +f 462/753/178 426/752/178 427/789/178 463/788/178 +f 414/853/282 438/854/282 439/855/282 415/856/282 +f 485/857/192 412/858/192 415/859/192 484/860/192 +f 447/861/275 461/839/275 493/862/275 475/863/275 +f 461/839/275 423/838/275 402/864/275 495/865/275 493/862/275 +f 464/748/181 420/747/181 421/822/181 465/819/181 +f 408/866/283 440/867/283 441/868/283 409/869/283 +f 406/870/192 473/871/192 470/872/192 442/873/192 +f 451/874/178 463/788/178 496/792/178 483/875/178 +f 412/876/284 448/877/284 454/878/284 430/879/284 +f 431/880/285 455/881/285 449/882/285 413/883/285 +f 430/884/286 454/885/286 455/886/286 431/887/286 +f 416/888/287 452/889/287 456/890/287 432/891/287 +f 433/892/288 457/893/288 453/894/288 417/895/288 +f 432/896/289 456/897/289 457/898/289 433/899/289 +f 406/900/290 442/901/290 458/902/290 434/903/290 +f 435/904/291 459/905/291 443/906/291 407/907/291 +f 434/908/292 458/909/292 459/910/292 435/911/292 +f 410/912/293 446/913/293 460/914/293 436/915/293 +f 437/916/294 461/917/294 447/918/294 411/919/294 +f 436/920/295 460/921/295 461/922/295 437/923/295 +f 414/924/296 450/925/296 462/926/296 438/927/296 +f 439/928/297 463/929/297 451/930/297 415/931/297 +f 438/932/298 462/933/298 463/934/298 439/935/298 +f 408/936/299 444/937/299 464/938/299 440/939/299 +f 441/940/300 465/941/300 445/942/300 409/943/300 +f 440/944/301 464/945/301 465/946/301 441/947/301 +f 410/800/192 481/799/192 478/948/192 446/949/192 +f 466/950/276 506/769/276 456/768/276 452/951/276 +f 406/870/192 409/952/192 472/953/192 473/871/192 +f 472/953/192 409/952/192 445/954/192 471/955/192 +f 452/956/192 416/832/192 469/831/192 466/957/192 +f 476/958/192 411/959/192 447/960/192 475/961/192 +f 470/962/278 491/963/278 458/825/278 442/964/278 +f 407/833/192 416/832/192 406/870/192 +f 408/844/192 411/959/192 476/958/192 477/845/192 +f 406/870/192 417/815/192 409/952/192 +f 409/952/192 414/814/192 408/844/192 +f 417/815/192 414/814/192 409/952/192 +f 417/815/192 406/870/192 416/832/192 +f 486/965/178 500/754/178 462/753/178 450/966/178 +f 492/967/278 401/968/278 418/826/278 458/825/278 491/963/278 +f 482/969/274 497/759/274 454/758/274 448/970/274 +f 414/814/192 489/817/192 486/971/192 450/972/192 +f 488/816/192 417/815/192 453/973/192 487/974/192 +f 448/975/192 412/858/192 485/857/192 482/976/192 +f 415/859/192 408/844/192 414/814/192 +f 480/802/192 413/801/192 449/977/192 479/978/192 +f 474/979/181 494/749/181 464/748/181 444/980/181 +f 478/981/275 503/764/275 460/763/275 446/982/275 +f 413/801/192 410/800/192 412/858/192 +f 412/858/192 411/959/192 415/859/192 +f 410/800/192 411/959/192 412/858/192 +f 415/859/192 411/959/192 408/844/192 +f 484/860/192 415/859/192 451/983/192 483/984/192 +f 466/957/192 469/831/192 468/834/192 467/985/192 +f 470/872/192 473/871/192 472/953/192 471/955/192 +f 474/846/192 477/845/192 476/958/192 475/961/192 +f 478/948/192 481/799/192 480/802/192 479/978/192 +f 482/976/192 485/857/192 484/860/192 483/984/192 +f 486/971/192 489/817/192 488/816/192 487/974/192 +f 490/820/302 492/824/302 491/986/302 +f 493/987/303 495/745/303 494/749/303 +f 496/792/304 498/791/304 497/988/304 +f 499/989/305 501/750/305 500/754/305 +f 502/836/306 504/760/306 503/764/306 +f 505/805/307 507/765/307 506/769/307 +f 470/990/308 471/821/308 490/820/308 491/986/308 +f 493/987/309 494/749/309 474/979/309 475/991/309 +f 482/992/310 483/875/310 496/792/310 497/988/310 +f 499/989/311 500/754/311 486/965/311 487/993/311 +f 502/836/94 503/764/94 478/981/94 479/837/94 +f 466/950/184 467/806/184 505/805/184 506/769/184 +f 468/834/192 407/833/192 443/994/192 467/985/192 +l 35 60 +l 86 60 +l 60 54 +l 103 86 +l 78 86 +l 60 90 +l 131 152 +l 86 152 +l 152 147 +l 152 167 +l 167 169 +l 890 891 +l 888 892 +l 889 893 +l 895 897 +l 901 903 +l 909 911 +l 915 913 +l 917 919 +l 921 923 +l 925 927 +l 932 934 +l 938 940 +l 944 942 +l 946 948 +l 953 955 +l 960 962 +l 966 968 +l 973 975 +l 980 982 +l 986 984 +l 988 990 +l 995 997 +l 1001 1003 +l 1007 1009 +l 1013 1011 +l 1015 1017 +l 1019 1021 +l 1023 1025 +l 1029 1027 +l 1031 1033 +l 1037 1039 +l 1043 1045 +l 1049 1051 +l 1056 1058 +l 1060 1062 +l 1064 1066 +l 1071 1073 +l 1078 1080 +l 1086 1088 +l 951 929 +l 958 977 +l 993 970 +l 1076 1053 +l 1091 1068 diff --git a/assets/lh.mtl b/assets/lh.mtl new file mode 100644 index 0000000..ab0025f --- /dev/null +++ b/assets/lh.mtl @@ -0,0 +1,83 @@ +# Blender 4.4.0 MTL File: 'leihengsword.blend' +# www.blender.org + +newmtl Brass.001 +Ns 250.000000 +Ka 1.000000 1.000000 1.000000 +Ke 0.000000 0.000000 0.000000 +Ni 1.500000 +d 1.000000 +illum 2 +map_Kd C:/brass_basecolor.jpg +map_Ks C:/brass_specular.jpg +map_refl C:/brass_metallic.jpg +map_Bump -bm 1.000000 C:/brass_normal_opengl.jpg + +newmtl Cherry_Red_Scratched_Painted_Steel +Ka 1.000000 1.000000 1.000000 +Ks 0.000000 0.000000 0.000000 +Ke 0.000000 0.000000 0.000000 +Ni 1.450000 +d 1.000000 +illum 1 +map_Kd C:/painted_steel_scratched_27_color.jpg +map_Ns C:/painted_steel_scratched_27_roughness.jpg +map_refl C:/painted_steel_scratched_27_metallic.jpg +map_Bump -bm 1.000000 C:/painted_steel_scratched_27_normal.jpg + +newmtl Dark_iron +Ns 250.000000 +Ka 1.000000 1.000000 1.000000 +Kd 0.800000 0.800000 0.800000 +Ks 1.000000 1.000000 1.000000 +Ke 0.000000 0.000000 0.000000 +Ni 1.450000 +d 1.000000 +illum 2 +map_Bump -bm 0.400000 C:/tiled_plane_DefaultMaterial_Normal.jpg + +newmtl Floral_Engraved_Gold +Ka 1.000000 1.000000 1.000000 +Ks 0.500000 0.500000 0.500000 +Ke 0.000000 0.000000 0.000000 +Ni 1.500000 +d 1.000000 +illum 2 +map_Kd C:/Floral Engraved Gold_BaseColor.jpg +map_Ns C:/Floral Engraved Gold_Roughness.jpg +map_refl C:/Floral Engraved Gold_Metallic.jpg +map_Bump -bm 1.000000 C:/Floral Engraved Gold_Normal.jpg + +newmtl Geometric_Brass_Engraved_Pattern +Ka 1.000000 1.000000 1.000000 +Ks 0.500000 0.500000 0.500000 +Ke 0.000000 0.000000 0.000000 +Ni 1.500000 +d 1.000000 +illum 2 +map_Kd C:/Geometric Brass Engraved Pattern_BaseColor.jpg +map_Ns C:/Geometric Brass Engraved Pattern_Roughness.jpg +map_refl C:/Geometric Brass Engraved Pattern_Metallic.jpg +map_Bump -bm 1.500000 C:/Geometric Brass Engraved Pattern_Normal.jpg + +newmtl Leather_red +Ka 1.000000 1.000000 1.000000 +Ks 0.500000 0.500000 0.500000 +Ke 0.000000 0.000000 0.000000 +Ni 1.500000 +d 1.000000 +illum 2 +map_Kd C:/plane_divided_DefaultMaterial_BaseColor.jpg +map_Ns C:/plane_divided_DefaultMaterial_Roughness.jpg +map_Bump -bm 1.000000 C:/plane_divided_DefaultMaterial_Normal.jpg + +newmtl leihengblade +Ns 250.000000 +Ka 1.000000 1.000000 1.000000 +Ke 0.000000 0.000000 0.000000 +Ni 1.500000 +d 1.000000 +illum 2 +map_Kd C:/Users/yulia/Downloads/leihengbladetexture.png +map_Ks C:/Users/yulia/Downloads/leihengbladetexture.png +map_refl C:/Users/yulia/Downloads/leihengbladetexture.png diff --git a/assets/lh.obj b/assets/lh.obj new file mode 100644 index 0000000..3f89ad1 --- /dev/null +++ b/assets/lh.obj @@ -0,0 +1,11468 @@ +# Blender 4.4.0 +# www.blender.org +mtllib lh.mtl +o Cube.004 +v 0.038247 0.492880 0.185090 +v 0.038247 0.494871 0.180590 +v 0.038247 0.499676 0.178726 +v 0.038247 0.504481 0.180590 +v 0.038247 0.506471 0.185090 +v 0.038247 0.504481 0.189590 +v 0.038247 0.499676 0.191453 +v 0.038247 0.494871 0.189590 +v 0.041890 0.494660 0.185090 +v 0.041890 0.496129 0.181768 +v 0.041890 0.499676 0.180393 +v 0.041890 0.503222 0.181768 +v 0.041890 0.504691 0.185090 +v 0.041890 0.503222 0.188411 +v 0.041890 0.499676 0.189787 +v 0.041890 0.496129 0.188411 +v 0.041890 0.499676 0.185090 +vn 0.3923 0.3327 -0.8576 +vn 0.4079 -0.8350 -0.3693 +vn 0.4079 -0.8350 0.3693 +vn 0.3923 0.3327 0.8576 +vn 0.4079 0.8350 -0.3693 +vn 0.3923 -0.3327 -0.8576 +vn 0.3923 -0.3327 0.8576 +vn 0.4079 0.8350 0.3693 +vn 1.0000 -0.0000 -0.0000 +vt 0.291593 0.578690 +vt 0.000096 0.226179 +vt 0.000096 0.696826 +vt 0.412885 0.000096 +vt 0.573193 0.312773 +vt 0.711565 0.079221 +vt 0.924438 0.303174 +vt 0.924438 0.773821 +vt 0.475238 0.687493 +vt 0.511650 0.999904 +vt 0.351342 0.687226 +vt 0.212970 0.920779 +vt 0.449297 0.312507 +vt 0.632942 0.421311 +vt 0.462267 0.500000 +vt 0.586821 0.573794 +vt 0.337714 0.426206 +s 0 +usemtl Geometric_Brass_Engraved_Pattern +f 12/1/1 3/2/1 4/3/1 +f 2/4/2 9/5/2 1/6/2 +f 9/5/3 8/7/3 1/6/3 +f 7/8/4 14/9/4 6/10/4 +f 13/11/5 4/3/5 5/12/5 +f 3/2/6 10/13/6 2/4/6 +f 16/14/7 7/8/7 8/7/7 +f 6/10/8 13/11/8 5/12/8 +f 16/14/9 17/15/9 15/16/9 +f 14/9/9 17/15/9 13/11/9 +f 12/1/9 17/15/9 11/17/9 +f 10/13/9 17/15/9 9/5/9 +f 9/5/9 17/15/9 16/14/9 +f 15/16/9 17/15/9 14/9/9 +f 13/11/9 17/15/9 12/1/9 +f 11/17/9 17/15/9 10/13/9 +f 12/1/1 11/17/1 3/2/1 +f 2/4/2 10/13/2 9/5/2 +f 9/5/3 16/14/3 8/7/3 +f 7/8/4 15/16/4 14/9/4 +f 13/11/5 12/1/5 4/3/5 +f 3/2/6 11/17/6 10/13/6 +f 16/14/7 15/16/7 7/8/7 +f 6/10/8 14/9/8 13/11/8 +o Cube.001 +v -0.010445 -0.479576 0.064744 +v -0.014772 -0.493718 0.064744 +v 0.014772 -0.493718 0.064744 +v 0.010445 -0.479576 0.064744 +v -0.000000 -0.473718 0.064744 +v 0.010445 -0.507861 0.064744 +v -0.010445 -0.507861 0.064744 +v 0.000000 -0.513718 0.064744 +vn -0.0000 -0.0000 -1.0000 +vt 0.000000 0.000000 +vt 0.428571 0.000000 +vt 1.000000 0.000000 +vt 0.285714 0.000000 +vt 0.142857 0.000000 +vt 0.571429 0.000000 +vt 0.857143 0.000000 +vt 0.714286 0.000000 +s 0 +usemtl Brass.001 +f 18/18/10 20/19/10 19/20/10 +f 18/18/10 21/21/10 20/19/10 +f 22/22/10 21/21/10 18/18/10 +f 19/20/10 20/19/10 23/23/10 +f 19/20/10 23/23/10 24/24/10 +f 24/24/10 23/23/10 25/25/10 +o Cube.002 +v -0.010445 -0.476616 0.016443 +v 0.010445 -0.476616 0.016443 +v -0.014772 -0.494455 0.019116 +v -0.000000 -0.469227 0.015336 +v 0.014772 -0.494455 0.019116 +v -0.010445 -0.512293 0.021789 +v 0.010445 -0.512293 0.021789 +v 0.000000 -0.519682 0.022896 +vn -0.0000 -0.1482 -0.9890 +vt 0.142857 0.000000 +vt 0.285714 0.000000 +vt 0.000000 0.000000 +vt 1.000000 0.000000 +vt 0.428571 0.000000 +vt 0.857143 0.000000 +vt 0.571429 0.000000 +vt 0.714286 0.000000 +s 0 +usemtl Brass.001 +f 29/26/11 27/27/11 26/28/11 +f 27/27/11 28/29/11 26/28/11 +f 27/27/11 30/30/11 28/29/11 +f 30/30/11 31/31/11 28/29/11 +f 30/30/11 32/32/11 31/31/11 +f 32/32/11 33/33/11 31/31/11 +o Cube.003 +v -0.010445 -0.476616 0.016443 +v -0.014772 -0.494455 0.019116 +v -0.010445 -0.498700 -0.007884 +v -0.000000 -0.469227 0.015336 +v -0.000000 -0.493757 -0.010205 +v 0.010445 -0.476616 0.016443 +v 0.010445 -0.498700 -0.007884 +v 0.014772 -0.494455 0.019116 +v 0.014772 -0.510634 -0.002279 +v 0.010445 -0.512293 0.021789 +v 0.010445 -0.522568 0.003326 +v 0.000000 -0.519682 0.022896 +v 0.000000 -0.527511 0.005648 +v -0.010445 -0.512293 0.021789 +v -0.010445 -0.522568 0.003326 +v -0.014772 -0.510634 -0.002279 +v -0.010445 -0.545655 -0.016382 +v 0.000000 -0.547655 -0.012316 +v -0.014772 -0.540828 -0.026200 +v -0.010445 -0.625046 -0.018814 +v 0.000000 -0.620904 -0.015755 +v -0.014772 -0.635046 -0.026200 +v -0.010445 -0.625046 0.076236 +v 0.000000 -0.620904 0.073177 +v -0.014772 -0.635046 0.083622 +v -0.010445 -0.512618 0.076236 +v 0.000000 -0.516760 0.073177 +v -0.014772 -0.502618 0.083622 +v -0.010445 -0.507861 0.064744 +v 0.000000 -0.513718 0.064744 +v -0.014772 -0.493718 0.064744 +v -0.010445 -0.479576 0.064744 +v -0.010445 -0.492618 0.091008 +v -0.000000 -0.473718 0.064744 +v -0.000000 -0.488476 0.094067 +v 0.010445 -0.479576 0.064744 +v 0.010445 -0.492618 0.091008 +v 0.014772 -0.493718 0.064744 +v 0.014772 -0.502618 0.083622 +v 0.010445 -0.507861 0.064744 +v 0.010445 -0.512618 0.076236 +v 0.010445 -0.625046 0.076236 +v 0.010445 -0.625046 -0.018814 +v 0.014772 -0.635046 0.083622 +v 0.014772 -0.635046 -0.026200 +v 0.010445 -0.645046 0.091008 +v 0.010445 -0.645046 -0.033587 +v -0.000000 -0.649188 0.094067 +v -0.000000 -0.649188 -0.036646 +v -0.010445 -0.645046 0.091008 +v -0.010445 -0.645046 -0.033587 +v -0.010445 -0.536000 -0.036018 +v -0.000000 -0.534000 -0.040085 +v 0.010445 -0.536000 -0.036018 +v 0.014772 -0.540828 -0.026200 +v 0.010445 -0.545655 -0.016383 +vn -0.9608 0.2051 -0.1862 +vn -0.5041 0.6229 -0.5983 +vn 0.5041 0.6229 -0.5983 +vn 0.9608 0.2051 -0.1862 +vn 0.9647 -0.2102 0.1589 +vn 0.5564 -0.7260 0.4041 +vn -0.5564 -0.7260 0.4040 +vn -0.9647 -0.2102 0.1589 +vn -0.4300 -0.5862 0.6867 +vn -0.9389 -0.2137 0.2698 +vn -0.3697 -0.0436 0.9281 +vn -0.9172 -0.0122 0.3982 +vn -0.3686 0.9296 -0.0000 +vn -0.9178 0.3971 -0.0000 +vn -0.2811 -0.0000 -0.9597 +vn -0.8629 -0.0000 -0.5055 +vn -0.4271 -0.8505 -0.3069 +vn -0.9413 -0.3119 -0.1291 +vn -0.9424 0.3024 0.1426 +vn -0.4367 0.8057 0.4001 +vn 0.4367 0.8057 0.4001 +vn 0.9424 0.3024 0.1426 +vn 0.9413 -0.3119 -0.1291 +vn 0.4271 -0.8505 -0.3068 +vn 0.2811 -0.0000 -0.9597 +vn 0.8629 -0.0000 -0.5054 +vn 0.3686 0.9296 -0.0000 +vn 0.9178 0.3971 -0.0000 +vn 0.9178 -0.3971 -0.0000 +vn 0.8629 -0.0000 0.5055 +vn 0.3686 -0.9296 -0.0000 +vn 0.2811 -0.0000 0.9597 +vn -0.3686 -0.9296 -0.0000 +vn -0.2811 -0.0000 0.9597 +vn -0.9178 -0.3971 -0.0000 +vn -0.8629 -0.0000 0.5054 +vn -0.3593 -0.0208 -0.9330 +vn -0.9151 -0.0000 -0.4033 +vn -0.4183 0.5415 -0.7293 +vn -0.9375 0.2095 -0.2777 +vn 0.4183 0.5415 -0.7293 +vn 0.3593 -0.0208 -0.9330 +vn 0.9375 0.2095 -0.2777 +vn 0.9151 -0.0000 -0.4033 +vn 0.9389 -0.2137 0.2698 +vn 0.9172 -0.0122 0.3982 +vn 0.4300 -0.5862 0.6867 +vn 0.3697 -0.0436 0.9281 +vn -0.9481 0.2536 -0.1918 +vn -0.4470 0.6623 -0.6012 +vn 0.4470 0.6623 -0.6012 +vn 0.9481 0.2536 -0.1918 +vn 0.9499 -0.2730 0.1519 +vn 0.4633 -0.8070 0.3663 +vn -0.4633 -0.8070 0.3663 +vn -0.9499 -0.2730 0.1519 +vn -0.3857 -0.6141 0.6886 +vn -0.9259 -0.2453 0.2874 +vn -0.2702 -0.0295 0.9624 +vn -0.8629 -0.0000 -0.5054 +vn -0.4601 -0.8204 -0.3396 +vn -0.9473 -0.2898 -0.1366 +vn -0.9463 0.2895 0.1438 +vn -0.4479 0.7986 0.4019 +vn 0.4479 0.7986 0.4019 +vn 0.9463 0.2895 0.1438 +vn 0.9473 -0.2898 -0.1366 +vn 0.4601 -0.8204 -0.3396 +vn 0.8629 -0.0000 0.5054 +vn -0.2914 -0.0285 -0.9562 +vn -0.8692 -0.0110 -0.4943 +vn -0.3920 0.5540 -0.7345 +vn -0.9270 0.2329 -0.2940 +vn 0.3920 0.5540 -0.7345 +vn 0.2914 -0.0285 -0.9562 +vn 0.9270 0.2329 -0.2940 +vn 0.8692 -0.0110 -0.4943 +vn 0.9259 -0.2453 0.2874 +vn 0.3857 -0.6141 0.6886 +vn 0.2702 -0.0295 0.9624 +vt 0.166667 1.000000 +vt 0.000000 0.875000 +vt 0.000000 1.000000 +vt 0.166667 0.125000 +vt 0.000000 0.000000 +vt 0.000000 0.125000 +vt 0.000000 0.250000 +vt 0.000000 0.375000 +vt 0.166667 0.250000 +vt 0.000000 0.500000 +vt 0.166667 0.375000 +vt 0.000000 0.625000 +vt 0.166667 0.500000 +vt 0.166667 0.750000 +vt 0.000000 0.750000 +vt 0.166667 0.875000 +vt 0.333333 0.750000 +vt 0.166667 0.625000 +vt 0.333333 0.875000 +vt 0.500000 0.625000 +vt 0.333333 0.625000 +vt 0.500000 0.750000 +vt 0.666667 0.625000 +vt 0.500000 0.875000 +vt 0.666667 0.750000 +vt 0.833333 0.750000 +vt 0.666667 0.875000 +vt 1.000000 0.625000 +vt 0.833333 0.625000 +vt 0.833333 0.875000 +vt 1.000000 0.750000 +vt 0.833333 1.000000 +vt 1.000000 0.875000 +vt 0.833333 0.125000 +vt 1.000000 0.000000 +vt 0.833333 0.000000 +vt 1.000000 0.250000 +vt 0.833333 0.250000 +vt 1.000000 0.375000 +vt 0.833333 0.375000 +vt 1.000000 0.500000 +vt 0.833333 0.500000 +vt 0.666667 0.500000 +vt 0.666667 0.375000 +vt 0.500000 0.500000 +vt 0.500000 0.375000 +vt 0.500000 0.250000 +vt 0.666667 0.250000 +vt 0.500000 0.125000 +vt 0.666667 0.125000 +vt 0.500000 0.000000 +vt 0.666667 0.000000 +vt 0.666667 1.000000 +vt 0.500000 1.000000 +vt 0.333333 0.125000 +vt 0.333333 0.000000 +vt 0.333333 1.000000 +vt 0.166667 0.000000 +vt 0.333333 0.250000 +vt 0.333333 0.375000 +vt 0.333333 0.500000 +vt 1.000000 1.000000 +vt 1.000000 0.125000 +s 0 +usemtl Brass.001 +f 36/34/12 35/35/12 34/36/12 +f 38/37/13 34/38/13 37/39/13 +f 39/40/14 38/37/14 37/39/14 +f 41/41/15 40/42/15 39/40/15 +f 43/43/16 42/44/16 41/41/16 +f 45/45/17 44/46/17 43/43/17 +f 48/47/18 45/45/18 47/48/18 +f 49/49/19 47/48/19 35/35/19 +f 50/50/20 46/51/20 48/47/20 +f 52/52/21 48/47/21 49/49/21 +f 50/50/22 54/53/22 51/54/22 +f 52/52/23 53/55/23 50/50/23 +f 53/55/24 57/56/24 54/53/24 +f 55/57/25 56/58/25 53/55/25 +f 59/59/26 57/56/26 56/58/26 +f 58/60/27 59/59/27 56/58/27 +f 59/59/28 63/61/28 60/62/28 +f 61/63/29 62/64/29 59/59/29 +f 66/65/30 64/66/30 61/63/30 +f 68/67/31 65/68/31 66/69/31 +f 69/70/32 68/67/32 70/71/32 +f 71/72/33 70/71/33 72/73/33 +f 73/74/34 72/73/34 74/75/34 +f 63/61/35 74/75/35 60/62/35 +f 57/56/36 74/75/36 75/76/36 +f 75/76/37 72/73/37 77/77/37 +f 54/53/38 75/76/38 76/78/38 +f 75/76/39 78/79/39 76/78/39 +f 77/77/40 80/80/40 78/79/40 +f 77/77/41 70/71/41 79/81/41 +f 79/81/42 82/82/42 80/80/42 +f 79/81/43 68/67/43 81/83/43 +f 81/83/44 84/84/44 82/82/44 +f 68/67/45 83/85/45 81/83/45 +f 83/86/46 55/57/46 84/87/46 +f 66/65/47 58/60/47 83/86/47 +f 86/88/48 84/84/48 85/89/48 +f 85/90/49 55/57/49 52/52/49 +f 86/88/50 36/91/50 38/37/50 +f 85/90/51 49/49/51 36/34/51 +f 40/42/52 86/88/52 38/37/52 +f 80/80/53 86/88/53 87/92/53 +f 42/44/54 87/92/54 40/42/54 +f 78/79/55 87/92/55 88/93/55 +f 44/46/56 88/93/56 42/44/56 +f 76/78/57 88/93/57 89/94/57 +f 46/51/58 89/94/58 44/46/58 +f 54/53/59 89/94/59 51/54/59 +f 36/34/60 49/49/60 35/35/60 +f 38/37/61 36/91/61 34/38/61 +f 39/40/62 40/42/62 38/37/62 +f 41/41/63 42/44/63 40/42/63 +f 43/43/64 44/46/64 42/44/64 +f 45/45/65 46/51/65 44/46/65 +f 48/47/66 46/51/66 45/45/66 +f 49/49/67 48/47/67 47/48/67 +f 50/50/68 51/54/68 46/51/68 +f 52/52/69 50/50/69 48/47/69 +f 50/50/70 53/55/70 54/53/70 +f 52/52/47 55/57/47 53/55/47 +f 53/55/24 56/58/24 57/56/24 +f 55/57/25 58/60/25 56/58/25 +f 59/59/26 60/62/26 57/56/26 +f 58/60/71 61/63/71 59/59/71 +f 59/59/72 62/64/72 63/61/72 +f 61/63/73 64/66/73 62/64/73 +f 66/65/74 65/95/74 64/66/74 +f 68/67/75 67/96/75 65/68/75 +f 69/70/76 67/96/76 68/67/76 +f 71/72/77 69/70/77 70/71/77 +f 73/74/78 71/72/78 72/73/78 +f 63/61/79 73/74/79 74/75/79 +f 57/56/36 60/62/36 74/75/36 +f 75/76/37 74/75/37 72/73/37 +f 54/53/38 57/56/38 75/76/38 +f 75/76/39 77/77/39 78/79/39 +f 77/77/40 79/81/40 80/80/40 +f 77/77/80 72/73/80 70/71/80 +f 79/81/42 81/83/42 82/82/42 +f 79/81/43 70/71/43 68/67/43 +f 81/83/44 83/85/44 84/84/44 +f 68/67/45 66/69/45 83/85/45 +f 83/86/46 58/60/46 55/57/46 +f 66/65/47 61/63/47 58/60/47 +f 86/88/81 82/82/81 84/84/81 +f 85/90/82 84/87/82 55/57/82 +f 86/88/83 85/89/83 36/91/83 +f 85/90/84 52/52/84 49/49/84 +f 40/42/85 87/92/85 86/88/85 +f 80/80/86 82/82/86 86/88/86 +f 42/44/87 88/93/87 87/92/87 +f 78/79/88 80/80/88 87/92/88 +f 44/46/89 89/94/89 88/93/89 +f 76/78/80 78/79/80 88/93/80 +f 46/51/90 51/54/90 89/94/90 +f 54/53/91 76/78/91 89/94/91 +o Cube.005 +v 0.000000 -0.516170 0.019414 +v -0.004624 -0.516873 0.020014 +v 0.000000 -0.531458 0.038988 +v 0.000000 -0.466137 0.012642 +v 0.004624 -0.516873 0.020014 +v 0.009195 -0.517334 0.021079 +v 0.005399 -0.466776 0.013139 +v 0.010633 -0.467337 0.014588 +v 0.007310 0.085889 -0.007513 +v 0.000000 0.085915 -0.008262 +v 0.014350 0.085915 -0.005408 +v 0.020825 0.085891 -0.001931 +v 0.026515 0.085915 0.002721 +v 0.015386 -0.469078 0.016939 +v 0.019647 -0.470754 0.020129 +v 0.013178 -0.519118 0.023219 +v 0.016989 -0.520648 0.025820 +v 0.019752 -0.523268 0.029154 +v 0.022197 -0.525608 0.032916 +v 0.023049 -0.473338 0.023975 +v 0.025670 -0.475868 0.028423 +v 0.031184 0.085894 0.008399 +v 0.034644 0.085915 0.014886 +v 0.036800 0.085899 0.021916 +v 0.037498 0.085915 0.029236 +v 0.027215 -0.478910 0.033193 +v 0.027785 -0.481901 0.038206 +v 0.023346 -0.528700 0.036933 +v 0.024026 -0.531458 0.041286 +v 0.023400 -0.534593 0.045388 +v 0.022197 -0.537309 0.049657 +v 0.027232 -0.484943 0.043190 +v 0.025670 -0.487934 0.047988 +v 0.036802 0.085904 0.036556 +v 0.034644 0.085915 0.043586 +v 0.031188 0.085908 0.050075 +v 0.026515 0.085915 0.055751 +v 0.023083 -0.490513 0.052430 +v 0.019647 -0.493048 0.056282 +v 0.019884 -0.540055 0.053232 +v 0.016989 -0.542269 0.056752 +v 0.013314 -0.544251 0.059260 +v 0.009195 -0.545583 0.061494 +v 0.015412 -0.494770 0.059488 +v 0.010633 -0.496465 0.061823 +v 0.020829 0.085910 0.060409 +v 0.014350 0.085915 0.063880 +v 0.007312 0.085911 0.065995 +v 0.000000 0.085915 0.066734 +v 0.005409 -0.497071 0.063297 +v 0.000000 -0.497665 0.063769 +v 0.004681 -0.546529 0.062534 +v 0.000000 -0.546746 0.063159 +v -0.004681 -0.546529 0.062534 +v -0.009194 -0.545583 0.061494 +v -0.005409 -0.497071 0.063297 +v -0.010633 -0.496465 0.061823 +v -0.007312 0.085911 0.065995 +v -0.014350 0.085915 0.063880 +v -0.020829 0.085910 0.060409 +v -0.026515 0.085915 0.055751 +v -0.015412 -0.494770 0.059488 +v -0.019647 -0.493048 0.056282 +v -0.013314 -0.544251 0.059260 +v -0.016989 -0.542269 0.056752 +v -0.019884 -0.540055 0.053232 +v -0.022197 -0.537309 0.049657 +v -0.023083 -0.490513 0.052430 +v -0.025670 -0.487934 0.047988 +v -0.031188 0.085908 0.050075 +v -0.034644 0.085915 0.043586 +v -0.036802 0.085904 0.036556 +v -0.037498 0.085915 0.029236 +v -0.027232 -0.484943 0.043190 +v -0.027785 -0.481901 0.038206 +v -0.023400 -0.534593 0.045388 +v -0.024026 -0.531458 0.041286 +v -0.023346 -0.528700 0.036933 +v -0.022197 -0.525608 0.032916 +v -0.027215 -0.478910 0.033193 +v -0.025670 -0.475868 0.028423 +v -0.036800 0.085899 0.021916 +v -0.034644 0.085915 0.014886 +v -0.031184 0.085894 0.008399 +v -0.026515 0.085915 0.002721 +v -0.023049 -0.473338 0.023976 +v -0.019647 -0.470754 0.020129 +v -0.019752 -0.523268 0.029154 +v -0.016989 -0.520648 0.025820 +v -0.013178 -0.519118 0.023219 +v -0.009195 -0.517334 0.021079 +v -0.015386 -0.469078 0.016939 +v -0.010633 -0.467337 0.014588 +v -0.020825 0.085891 -0.001931 +v -0.014350 0.085915 -0.005408 +v -0.007310 0.085889 -0.007513 +v -0.005399 -0.466776 0.013139 +vn -0.1071 -0.1368 -0.9848 +vn -0.0591 -0.7984 -0.5993 +vn -0.0399 -0.7875 -0.6150 +vn 0.1071 -0.1368 -0.9848 +vn 0.2117 -0.1361 -0.9678 +vn 0.2630 -0.0366 -0.9641 +vn 0.0872 -0.0375 -0.9955 +vn 0.4328 -0.0349 -0.9008 +vn 0.5908 -0.0325 -0.8061 +vn 0.5231 -0.1288 -0.8425 +vn 0.4231 -0.1312 -0.8965 +vn -0.0147 -0.7814 -0.6238 +vn 0.7168 -0.1186 -0.6871 +vn 0.0129 -0.7809 -0.6245 +vn 0.8010 -0.1091 -0.5886 +vn 0.8547 -0.0261 -0.5185 +vn 0.7387 -0.0295 -0.6733 +vn 0.9468 -0.0225 -0.3211 +vn 0.9921 -0.0189 -0.1240 +vn 0.9744 -0.0868 -0.2073 +vn 0.9342 -0.0984 -0.3428 +vn 0.0555 -0.8126 -0.5801 +vn 0.9927 -0.0723 0.0962 +vn 0.0540 -0.8239 -0.5641 +vn 0.9701 -0.0603 0.2350 +vn 0.9531 -0.0126 0.3024 +vn 0.9948 -0.0155 0.1009 +vn 0.8667 -0.0101 0.4988 +vn 0.7489 -0.0083 0.6627 +vn 0.7829 -0.0363 0.6210 +vn 0.8547 -0.0468 0.5170 +vn 0.0653 -0.8113 -0.5809 +vn 0.5737 -0.0281 0.8186 +vn 0.0620 -0.8252 -0.5614 +vn 0.4816 -0.0200 0.8762 +vn 0.4407 -0.0060 0.8976 +vn 0.6054 -0.0069 0.7959 +vn 0.2720 -0.0053 0.9623 +vn 0.0876 -0.0051 0.9961 +vn 0.1329 -0.0123 0.9911 +vn 0.2281 -0.0184 0.9735 +vn 0.0498 -0.8367 -0.5454 +vn -0.1329 -0.0123 0.9911 +vn 0.0321 -0.8447 -0.5343 +vn -0.2281 -0.0184 0.9735 +vn -0.2720 -0.0053 0.9623 +vn -0.0876 -0.0051 0.9961 +vn -0.4407 -0.0060 0.8976 +vn -0.6054 -0.0069 0.7959 +vn -0.5737 -0.0281 0.8186 +vn -0.4816 -0.0200 0.8762 +vn 0.0119 -0.8491 -0.5281 +vn -0.7829 -0.0363 0.6210 +vn -0.0096 -0.8501 -0.5266 +vn -0.8547 -0.0468 0.5170 +vn -0.8667 -0.0101 0.4988 +vn -0.7489 -0.0083 0.6627 +vn -0.9531 -0.0126 0.3024 +vn -0.9948 -0.0155 0.1009 +vn -0.9927 -0.0723 0.0962 +vn -0.9701 -0.0603 0.2350 +vn -0.0540 -0.8239 -0.5641 +vn -0.9744 -0.0868 -0.2073 +vn -0.0555 -0.8126 -0.5801 +vn -0.9342 -0.0984 -0.3428 +vn -0.9468 -0.0225 -0.3211 +vn -0.9921 -0.0189 -0.1240 +vn -0.8547 -0.0261 -0.5185 +vn -0.7387 -0.0295 -0.6733 +vn -0.7168 -0.1186 -0.6871 +vn -0.8010 -0.1091 -0.5886 +vn -0.0657 -0.8277 -0.5574 +vn -0.5231 -0.1288 -0.8425 +vn -0.0686 -0.8127 -0.5787 +vn -0.4231 -0.1312 -0.8965 +vn -0.4328 -0.0349 -0.9008 +vn -0.5908 -0.0325 -0.8061 +vn -0.2630 -0.0366 -0.9641 +vn -0.0872 -0.0375 -0.9955 +vn -0.2117 -0.1361 -0.9678 +vn -0.0751 -0.1337 -0.9882 +vn 0.0399 -0.7875 -0.6150 +vn 0.0591 -0.7984 -0.5993 +vn 0.0751 -0.1337 -0.9882 +vn 0.2514 -0.1317 -0.9589 +vn 0.2864 -0.0368 -0.9574 +vn 0.1017 -0.0376 -0.9941 +vn 0.4727 -0.0350 -0.8805 +vn 0.6326 -0.0325 -0.7738 +vn 0.5633 -0.1232 -0.8170 +vn 0.4012 -0.1293 -0.9068 +vn 0.0686 -0.8127 -0.5787 +vn 0.7033 -0.1174 -0.7011 +vn 0.0657 -0.8277 -0.5574 +vn 0.8270 -0.1118 -0.5509 +vn 0.8821 -0.0259 -0.4704 +vn 0.7720 -0.0294 -0.6349 +vn 0.9558 -0.0223 -0.2932 +vn 0.9953 -0.0188 -0.0949 +vn 0.9824 -0.0887 -0.1645 +vn 0.9269 -0.0975 -0.3625 +vn -0.6885 -0.6564 -0.3084 +vn 0.9952 -0.0713 0.0669 +vn -0.5902 -0.5954 -0.5451 +vn 0.9598 -0.0619 0.2738 +vn 0.9559 -0.0126 0.2934 +vn 0.9954 -0.0155 0.0947 +vn 0.8826 -0.0102 0.4700 +vn 0.7720 -0.0083 0.6356 +vn 0.7581 -0.0384 0.6510 +vn 0.8744 -0.0452 0.4830 +vn 0.0096 -0.8501 -0.5266 +vn 0.6100 -0.0254 0.7920 +vn -0.0118 -0.8491 -0.5281 +vn 0.4455 -0.0230 0.8950 +vn 0.4721 -0.0058 0.8815 +vn 0.6337 -0.0068 0.7735 +vn 0.2879 -0.0052 0.9577 +vn 0.1005 -0.0049 0.9949 +vn 0.0889 -0.0167 0.9959 +vn 0.2729 -0.0144 0.9619 +vn -0.0321 -0.8447 -0.5343 +vn -0.0889 -0.0167 0.9959 +vn -0.0498 -0.8367 -0.5454 +vn -0.2729 -0.0144 0.9619 +vn -0.2879 -0.0052 0.9577 +vn -0.1005 -0.0049 0.9949 +vn -0.4721 -0.0058 0.8815 +vn -0.6337 -0.0068 0.7735 +vn -0.6100 -0.0254 0.7920 +vn -0.4455 -0.0230 0.8950 +vn -0.0620 -0.8252 -0.5614 +vn -0.7581 -0.0384 0.6510 +vn -0.0653 -0.8114 -0.5809 +vn -0.8744 -0.0452 0.4830 +vn -0.8826 -0.0102 0.4700 +vn -0.7720 -0.0083 0.6356 +vn -0.9559 -0.0126 0.2934 +vn -0.9954 -0.0155 0.0947 +vn -0.9952 -0.0713 0.0669 +vn -0.9598 -0.0619 0.2738 +vn 0.5900 -0.5955 -0.5452 +vn -0.9824 -0.0887 -0.1645 +vn 0.6885 -0.6564 -0.3084 +vn -0.9269 -0.0975 -0.3625 +vn -0.9558 -0.0223 -0.2932 +vn -0.9953 -0.0188 -0.0949 +vn -0.8821 -0.0259 -0.4704 +vn -0.7720 -0.0294 -0.6349 +vn -0.7033 -0.1174 -0.7011 +vn -0.8270 -0.1118 -0.5509 +vn -0.0129 -0.7809 -0.6245 +vn -0.5633 -0.1232 -0.8170 +vn 0.0147 -0.7814 -0.6238 +vn -0.4012 -0.1293 -0.9068 +vn -0.4727 -0.0350 -0.8805 +vn -0.6326 -0.0325 -0.7738 +vn -0.2864 -0.0368 -0.9574 +vn -0.1017 -0.0376 -0.9941 +vn -0.2514 -0.1317 -0.9589 +vt 0.558360 0.280518 +vt 0.580295 0.262975 +vt 0.580519 0.280229 +vt 0.580744 0.297483 +vt 0.587266 0.797840 +vt 0.587490 0.815094 +vt 0.565106 0.798129 +vt 0.587041 0.780586 +vt 0.310981 0.784184 +vt 0.564881 0.780875 +vt 0.565331 0.815383 +vt 0.311206 0.801438 +vt 0.310757 0.766931 +vt 0.564656 0.763621 +vt 0.310532 0.749677 +vt 0.564431 0.746368 +vt 0.586591 0.746079 +vt 0.586816 0.763333 +vt 0.564206 0.729114 +vt 0.586366 0.728825 +vt 0.563982 0.711860 +vt 0.586141 0.711572 +vt 0.310082 0.715169 +vt 0.310307 0.732423 +vt 0.309857 0.697916 +vt 0.563757 0.694607 +vt 0.309632 0.680662 +vt 0.563532 0.677353 +vt 0.585916 0.694318 +vt 0.585691 0.677064 +vt 0.563307 0.660099 +vt 0.585467 0.659810 +vt 0.585242 0.642557 +vt 0.563082 0.642846 +vt 0.309182 0.646155 +vt 0.309407 0.663408 +vt 0.308957 0.628901 +vt 0.562857 0.625592 +vt 0.308733 0.611647 +vt 0.562632 0.608338 +vt 0.585017 0.625303 +vt 0.584792 0.608049 +vt 0.562407 0.591084 +vt 0.584567 0.590796 +vt 0.562183 0.573831 +vt 0.584342 0.573542 +vt 0.308283 0.577140 +vt 0.308508 0.594393 +vt 0.308058 0.559886 +vt 0.561958 0.556577 +vt 0.307833 0.542632 +vt 0.561733 0.539323 +vt 0.584117 0.556288 +vt 0.583892 0.539034 +vt 0.583668 0.521781 +vt 0.561508 0.522070 +vt 0.583443 0.504527 +vt 0.307608 0.525379 +vt 0.561283 0.504816 +vt 0.307383 0.508125 +vt 0.561058 0.487562 +vt 0.307159 0.490871 +vt 0.560833 0.470308 +vt 0.582993 0.470020 +vt 0.583218 0.487273 +vt 0.582768 0.452766 +vt 0.560609 0.453055 +vt 0.582543 0.435512 +vt 0.306709 0.456364 +vt 0.560384 0.435801 +vt 0.306934 0.473618 +vt 0.306484 0.439110 +vt 0.560159 0.418547 +vt 0.306259 0.421856 +vt 0.559934 0.401294 +vt 0.582093 0.401005 +vt 0.582318 0.418258 +vt 0.581869 0.383751 +vt 0.581644 0.366497 +vt 0.559709 0.384040 +vt 0.305809 0.387349 +vt 0.559484 0.366786 +vt 0.306034 0.404603 +vt 0.305584 0.370095 +vt 0.559259 0.349532 +vt 0.305359 0.352842 +vt 0.559034 0.332279 +vt 0.581194 0.331990 +vt 0.581419 0.349244 +vt 0.558810 0.315025 +vt 0.580969 0.314736 +vt 0.304910 0.318334 +vt 0.558585 0.297771 +vt 0.305135 0.335588 +vt 0.304685 0.301081 +vt 0.304460 0.283827 +vt 0.558135 0.263264 +vt 0.311431 0.818692 +vt 0.304235 0.266573 +s 0 +usemtl Leather_red +f 186/97/92 90/98/92 91/99/92 +f 91/99/93 92/100/93 180/100/93 +f 94/101/94 92/102/94 90/102/94 +f 90/102/95 96/103/95 94/101/95 +f 96/103/96 95/104/96 94/101/96 +f 96/103/97 100/105/97 97/106/97 +f 93/107/98 98/108/98 96/103/98 +f 97/106/99 101/109/99 103/110/99 +f 103/110/100 102/111/100 104/112/100 +f 103/110/101 106/113/101 105/114/101 +f 95/104/102 103/110/102 105/114/102 +f 105/114/103 92/104/103 95/104/103 +f 106/113/104 109/115/104 107/116/104 +f 107/116/105 92/113/105 106/113/105 +f 107/116/106 110/117/106 108/118/106 +f 109/115/107 112/119/107 110/117/107 +f 104/112/108 111/120/108 109/115/108 +f 110/117/109 113/121/109 115/122/109 +f 115/122/110 114/123/110 116/124/110 +f 117/125/111 116/124/111 118/126/111 +f 108/118/112 115/122/112 117/125/112 +f 108/118/113 118/126/113 92/118/113 +f 118/126/114 121/127/114 119/128/114 +f 118/126/115 120/129/115 92/126/115 +f 119/128/116 122/130/116 120/129/116 +f 121/127/117 124/131/117 122/130/117 +f 116/124/118 123/132/118 121/127/118 +f 122/130/119 125/133/119 127/134/119 +f 127/134/120 126/135/120 128/136/120 +f 129/137/121 128/136/121 130/138/121 +f 120/129/122 127/134/122 129/137/122 +f 129/137/123 92/129/123 120/129/123 +f 130/138/124 133/139/124 131/140/124 +f 131/140/125 92/138/125 130/138/125 +f 131/140/126 134/141/126 132/142/126 +f 133/139/127 136/143/127 134/141/127 +f 128/136/128 135/144/128 133/139/128 +f 134/141/129 137/145/129 139/146/129 +f 139/146/130 138/147/130 140/148/130 +f 141/149/131 140/148/131 142/150/131 +f 132/142/132 139/146/132 141/149/132 +f 141/149/133 92/142/133 132/142/133 +f 140/148/134 143/151/134 142/150/134 +f 143/151/135 92/150/135 142/150/135 +f 145/152/136 144/153/136 143/151/136 +f 147/154/137 146/155/137 145/152/137 +f 138/147/138 145/152/138 140/148/138 +f 148/156/139 151/157/139 146/155/139 +f 149/158/140 152/159/140 151/157/140 +f 151/157/141 154/160/141 153/161/141 +f 146/155/142 153/161/142 144/153/142 +f 153/161/143 92/153/143 144/153/143 +f 152/159/144 155/162/144 154/160/144 +f 155/162/145 92/160/145 154/160/145 +f 157/163/146 156/164/146 155/162/146 +f 159/165/147 158/166/147 157/163/147 +f 150/167/148 157/163/148 152/159/148 +f 160/168/149 163/169/149 158/166/149 +f 161/170/150 164/171/150 163/169/150 +f 163/169/151 166/172/151 165/173/151 +f 158/166/152 165/173/152 156/164/152 +f 156/164/153 166/172/153 92/164/153 +f 164/171/154 167/174/154 166/172/154 +f 166/172/155 168/175/155 92/172/155 +f 169/176/156 168/175/156 167/174/156 +f 171/177/157 170/178/157 169/176/157 +f 162/179/158 169/176/158 164/171/158 +f 172/180/159 175/181/159 170/178/159 +f 173/182/160 176/183/160 175/181/160 +f 175/181/161 178/184/161 177/185/161 +f 170/178/162 177/185/162 168/175/162 +f 177/185/163 92/175/163 168/175/163 +f 178/184/164 181/186/164 179/187/164 +f 179/187/165 92/184/165 178/184/165 +f 181/186/166 180/100/166 179/187/166 +f 183/188/167 182/189/167 181/186/167 +f 174/190/168 181/186/168 176/183/168 +f 184/191/169 186/97/169 182/189/169 +f 185/192/170 93/193/170 186/97/170 +f 180/100/171 186/97/171 91/99/171 +f 186/97/172 93/193/172 90/98/172 +f 91/99/173 90/98/173 92/100/173 +f 94/101/174 95/104/174 92/102/174 +f 90/102/175 93/107/175 96/103/175 +f 96/103/176 97/106/176 95/104/176 +f 96/103/177 98/108/177 100/105/177 +f 93/107/178 99/194/178 98/108/178 +f 97/106/179 100/105/179 101/109/179 +f 103/110/180 101/109/180 102/111/180 +f 103/110/181 104/112/181 106/113/181 +f 95/104/182 97/106/182 103/110/182 +f 105/114/183 106/113/183 92/104/183 +f 106/113/184 104/112/184 109/115/184 +f 107/116/185 108/118/185 92/113/185 +f 107/116/186 109/115/186 110/117/186 +f 109/115/187 111/120/187 112/119/187 +f 104/112/188 102/111/188 111/120/188 +f 110/117/189 112/119/189 113/121/189 +f 115/122/190 113/121/190 114/123/190 +f 117/125/191 115/122/191 116/124/191 +f 108/118/192 110/117/192 115/122/192 +f 108/118/193 117/125/193 118/126/193 +f 118/126/194 116/124/194 121/127/194 +f 118/126/195 119/128/195 120/129/195 +f 119/128/196 121/127/196 122/130/196 +f 121/127/197 123/132/197 124/131/197 +f 116/124/198 114/123/198 123/132/198 +f 122/130/199 124/131/199 125/133/199 +f 127/134/200 125/133/200 126/135/200 +f 129/137/201 127/134/201 128/136/201 +f 120/129/202 122/130/202 127/134/202 +f 129/137/203 130/138/203 92/129/203 +f 130/138/204 128/136/204 133/139/204 +f 131/140/205 132/142/205 92/138/205 +f 131/140/206 133/139/206 134/141/206 +f 133/139/207 135/144/207 136/143/207 +f 128/136/208 126/135/208 135/144/208 +f 134/141/209 136/143/209 137/145/209 +f 139/146/210 137/145/210 138/147/210 +f 141/149/211 139/146/211 140/148/211 +f 132/142/212 134/141/212 139/146/212 +f 141/149/213 142/150/213 92/142/213 +f 140/148/214 145/152/214 143/151/214 +f 143/151/215 144/153/215 92/150/215 +f 145/152/216 146/155/216 144/153/216 +f 147/154/217 148/156/217 146/155/217 +f 138/147/218 147/154/218 145/152/218 +f 148/156/219 149/158/219 151/157/219 +f 149/158/220 150/167/220 152/159/220 +f 151/157/221 152/159/221 154/160/221 +f 146/155/222 151/157/222 153/161/222 +f 153/161/223 154/160/223 92/153/223 +f 152/159/224 157/163/224 155/162/224 +f 155/162/225 156/164/225 92/160/225 +f 157/163/226 158/166/226 156/164/226 +f 159/165/227 160/168/227 158/166/227 +f 150/167/228 159/165/228 157/163/228 +f 160/168/229 161/170/229 163/169/229 +f 161/170/230 162/179/230 164/171/230 +f 163/169/231 164/171/231 166/172/231 +f 158/166/232 163/169/232 165/173/232 +f 156/164/233 165/173/233 166/172/233 +f 164/171/234 169/176/234 167/174/234 +f 166/172/235 167/174/235 168/175/235 +f 169/176/236 170/178/236 168/175/236 +f 171/177/237 172/180/237 170/178/237 +f 162/179/238 171/177/238 169/176/238 +f 172/180/239 173/182/239 175/181/239 +f 173/182/240 174/190/240 176/183/240 +f 175/181/241 176/183/241 178/184/241 +f 170/178/242 175/181/242 177/185/242 +f 177/185/243 178/184/243 92/175/243 +f 178/184/244 176/183/244 181/186/244 +f 179/187/245 180/100/245 92/184/245 +f 181/186/246 182/189/246 180/100/246 +f 183/188/247 184/191/247 182/189/247 +f 174/190/248 183/188/248 181/186/248 +f 184/191/249 185/192/249 186/97/249 +f 185/192/250 99/195/250 93/193/250 +f 180/100/251 182/189/251 186/97/251 +o Cube.006 +v -0.000000 0.205794 -0.031838 +v 0.017347 0.205794 -0.027318 +v -0.017347 0.205794 -0.027318 +v -0.000000 0.216399 -0.072421 +v -0.000000 0.205794 0.027553 +v -0.023773 0.205794 -0.014443 +v 0.031061 0.205794 0.004825 +v 0.033620 0.205794 0.027553 +v 0.012866 0.205794 0.082423 +v -0.000000 0.205794 0.086943 +v -0.031061 0.205794 0.050280 +v -0.033620 0.205794 0.027553 +v 0.031061 0.205794 0.050280 +v -0.012866 0.205794 0.082423 +v -0.031061 0.205794 0.004825 +v 0.023773 0.205794 0.069548 +v -0.023773 0.205794 0.069548 +v 0.023773 0.205794 -0.014443 +v 0.027003 0.216399 -0.055026 +v 0.030662 0.151893 -0.013788 +v 0.040061 0.151893 0.005088 +v 0.016594 0.151893 -0.026400 +v 0.027003 0.168434 -0.055026 +v 0.034041 0.101594 -0.014301 +v 0.019623 0.151893 -0.013788 +v 0.025639 0.151893 0.005088 +v 0.021787 0.101594 -0.014301 +v 0.028465 0.101594 0.004882 +v 0.044477 0.101594 0.004882 +v 0.039445 0.087340 0.008107 +v 0.048142 0.101594 0.027509 +v 0.042695 0.087340 0.027725 +v 0.043362 0.151893 0.027353 +v 0.030811 0.101594 0.027509 +v 0.027325 0.087340 0.027725 +v 0.027752 0.151893 0.027353 +v 0.028465 0.101594 0.050137 +v 0.044477 0.101594 0.050137 +v 0.025245 0.087340 0.047344 +v 0.025639 0.151893 0.049618 +v 0.040061 0.151893 0.049618 +v 0.030662 0.151893 0.068493 +v 0.016594 0.151893 0.081105 +v 0.034041 0.101594 0.069320 +v 0.030190 0.087340 0.063976 +v 0.018423 0.101594 0.082137 +v 0.016339 0.087340 0.075089 +v -0.000000 0.101594 0.086638 +v -0.000000 0.087340 0.078991 +v -0.000000 0.151893 0.085534 +v -0.018423 0.101594 0.082137 +v -0.016339 0.087340 0.075089 +v -0.016594 0.151893 0.081105 +v -0.034041 0.101594 0.069320 +v -0.030190 0.087340 0.063976 +v -0.030662 0.151893 0.068493 +v -0.044477 0.101594 0.050137 +v -0.039445 0.087340 0.047344 +v -0.040061 0.151893 0.049618 +v -0.028466 0.101594 0.050137 +v -0.025245 0.087340 0.047344 +v -0.025639 0.151893 0.049618 +v -0.030811 0.101594 0.027509 +v -0.027325 0.087340 0.027725 +v -0.027752 0.151893 0.027353 +v -0.048142 0.101594 0.027509 +v -0.042695 0.087340 0.027725 +v -0.043362 0.151893 0.027353 +v -0.044477 0.101594 0.004882 +v -0.039445 0.087340 0.008107 +v -0.040061 0.151893 0.005088 +v -0.034041 0.101594 -0.014301 +v -0.028466 0.101594 0.004882 +v -0.025639 0.151893 0.005088 +v -0.021787 0.101594 -0.014301 +v -0.019624 0.151893 -0.013788 +v -0.030662 0.151893 -0.013788 +v -0.016594 0.151893 -0.026400 +v -0.027003 0.168434 -0.055026 +v -0.027003 0.216399 -0.055026 +v -0.014614 0.168434 -0.067900 +v -0.014614 0.216399 -0.067900 +v -0.000000 0.168434 -0.072421 +v 0.014614 0.168434 -0.067900 +v -0.000000 0.151893 -0.030829 +v -0.000000 0.101594 -0.031620 +v -0.000000 0.087340 -0.023541 +v 0.018423 0.101594 -0.027119 +v -0.018423 0.101594 -0.027119 +v -0.016339 0.087340 -0.019638 +v -0.030190 0.087340 -0.008525 +v -0.014833 0.082187 -0.015273 +v -0.027408 0.082187 -0.005184 +v -0.000000 0.082187 -0.018816 +v 0.014833 0.082187 -0.015273 +v 0.027408 0.082187 -0.005184 +v 0.016339 0.087340 -0.019638 +v 0.030190 0.087340 -0.008525 +v 0.035810 0.082187 0.009915 +v 0.031008 0.082187 0.027725 +v 0.028648 0.082187 0.045536 +v 0.028738 0.081733 0.027553 +v 0.026551 0.081733 0.048186 +v 0.027408 0.082187 0.060635 +v 0.039445 0.087340 0.047344 +v 0.014833 0.082187 0.070724 +v -0.000000 0.082187 0.074267 +v -0.014833 0.082187 0.070724 +v -0.027408 0.082187 0.060635 +v -0.028648 0.082187 0.045536 +v -0.031008 0.082187 0.027725 +v -0.026551 0.081733 0.048186 +v -0.028738 0.081733 0.027553 +v -0.035810 0.082187 0.009915 +v 0.014614 0.216399 -0.067900 +vn -0.0000 1.0000 -0.0000 +vn -0.0780 0.9646 0.2521 +vn 0.0668 0.9642 0.2565 +vn 0.9968 -0.0000 0.0793 +vn -0.2706 0.9268 0.2604 +vn 0.8856 0.1457 -0.4410 +vn -0.0000 -1.0000 -0.0000 +vn 0.3372 -0.8631 -0.3761 +vn 0.6336 0.0505 -0.7720 +vn -0.0000 -0.0102 0.9999 +vn 0.9430 0.0543 -0.3283 +vn -0.0000 0.0041 -1.0000 +vn 0.9206 -0.3595 -0.1525 +vn 0.8018 -0.3975 -0.4462 +vn 0.9829 0.0929 -0.1592 +vn -0.0000 0.0152 0.9999 +vn -0.0000 0.0031 1.0000 +vn 0.9658 -0.2383 0.1024 +vn 0.9928 0.0607 0.1029 +vn -0.0000 -0.0103 -0.9999 +vn -0.0000 0.1923 -0.9813 +vn 0.8860 0.1425 0.4412 +vn 0.9738 0.1755 0.1444 +vn 0.8755 0.0818 0.4763 +vn 0.6659 0.0706 0.7427 +vn 0.6334 0.0552 0.7718 +vn 0.5648 -0.4307 0.7039 +vn 0.8061 -0.3860 0.4486 +vn 0.2060 -0.4626 0.8623 +vn 0.2372 0.0286 0.9710 +vn -0.2060 -0.4626 0.8623 +vn -0.2372 0.0285 0.9710 +vn -0.5648 -0.4307 0.7039 +vn -0.6334 0.0552 0.7718 +vn -0.8061 -0.3860 0.4486 +vn -0.8755 0.0818 0.4763 +vn -0.9658 -0.2383 0.1024 +vn -0.9928 0.0607 0.1029 +vn -0.0000 0.0151 0.9999 +vn -0.9206 -0.3595 -0.1525 +vn -0.9829 0.0929 -0.1592 +vn -0.8018 -0.3975 -0.4462 +vn -0.9430 0.0543 -0.3283 +vn -0.9913 0.1262 -0.0373 +vn -0.8856 0.1457 -0.4410 +vn -0.3729 -0.8557 -0.3588 +vn -0.6336 0.0505 -0.7720 +vn -0.7206 -0.0000 -0.6934 +vn -0.2955 -0.0000 -0.9553 +vn -0.1136 -0.9232 -0.3672 +vn 0.2955 -0.0000 -0.9553 +vn 0.0994 -0.9227 -0.3725 +vn 0.2373 0.0225 -0.9712 +vn -0.2373 0.0225 -0.9712 +vn -0.2034 -0.4828 -0.8518 +vn 0.2034 -0.4828 -0.8518 +vn -0.5595 -0.4478 -0.6974 +vn -0.1734 -0.6656 -0.7259 +vn -0.4783 -0.6448 -0.5962 +vn 0.1734 -0.6656 -0.7259 +vn 0.4783 -0.6448 -0.5962 +vn 0.5595 -0.4478 -0.6974 +vn 0.6867 -0.6185 -0.3821 +vn 0.7880 -0.6017 -0.1305 +vn -0.2423 0.9699 -0.0257 +vn -0.0664 -0.0474 0.9967 +vn 0.9653 0.2402 0.1023 +vn -0.0000 0.3311 -0.9436 +vn 0.3905 -0.8946 0.2173 +vn 0.4783 -0.6448 0.5962 +vn 0.1734 -0.6656 0.7259 +vn -0.1734 -0.6656 0.7259 +vn -0.4783 -0.6448 0.5962 +vn -0.8579 -0.5089 0.0705 +vn 0.1941 0.9807 -0.0257 +vn 0.7335 -0.2648 -0.6259 +vn -0.9653 0.2402 0.1023 +vn -0.0000 -0.0000 1.0000 +vn -0.4011 -0.9096 0.1081 +vn -0.6867 -0.6185 -0.3821 +vn 0.7206 -0.0000 -0.6934 +vn 0.4031 0.8928 0.2012 +vn -0.9737 0.1765 -0.1443 +vn -0.9738 0.1755 0.1444 +vn -0.8860 0.1425 0.4412 +vn -0.6659 0.0706 0.7427 +vn -0.2579 -0.0058 0.9662 +vn 0.2579 -0.0058 0.9662 +vn 0.9737 0.1765 -0.1443 +vn -0.0668 0.9642 0.2565 +vn 0.0780 0.9646 0.2521 +vn 0.9913 0.1262 -0.0373 +vn -0.4031 0.8928 0.2012 +vn 0.9292 0.1145 -0.3515 +vn 0.3729 -0.8557 -0.3588 +vn 0.6671 0.0349 -0.7441 +vn 0.9519 0.0440 -0.3034 +vn 0.9229 -0.3549 -0.1495 +vn 0.8104 -0.3858 -0.4409 +vn 0.9854 0.0871 -0.1461 +vn 0.9668 -0.2349 0.1002 +vn 0.9939 0.0568 0.0943 +vn 0.9295 0.1119 0.3516 +vn 0.9805 0.1624 0.1104 +vn 0.8931 0.0673 0.4448 +vn 0.7625 0.0370 0.6460 +vn 0.6670 0.0395 0.7440 +vn 0.5761 -0.4188 0.7019 +vn 0.8145 -0.3744 0.4431 +vn 0.2110 -0.4579 0.8636 +vn 0.2578 0.0212 0.9660 +vn -0.2110 -0.4579 0.8636 +vn -0.2578 0.0212 0.9660 +vn -0.5761 -0.4188 0.7019 +vn -0.6670 0.0395 0.7440 +vn -0.8145 -0.3744 0.4431 +vn -0.8931 0.0673 0.4448 +vn -0.9668 -0.2349 0.1002 +vn -0.9939 0.0568 0.0943 +vn -0.9229 -0.3549 -0.1495 +vn -0.9854 0.0871 -0.1461 +vn -0.8104 -0.3858 -0.4409 +vn -0.9519 0.0440 -0.3034 +vn -0.9968 -0.0000 0.0793 +vn -0.9292 0.1145 -0.3515 +vn -0.3372 -0.8631 -0.3761 +vn -0.6671 0.0349 -0.7441 +vn -0.0994 -0.9227 -0.3725 +vn 0.1136 -0.9232 -0.3672 +vn 0.2578 0.0152 -0.9661 +vn -0.2578 0.0152 -0.9661 +vn -0.2084 -0.4782 -0.8532 +vn 0.2084 -0.4782 -0.8532 +vn -0.5709 -0.4361 -0.6956 +vn 0.5709 -0.4361 -0.6956 +vn 0.4011 -0.9096 0.1081 +vn -0.1941 0.9807 -0.0257 +vn -0.7335 -0.2648 -0.6259 +vn 0.8579 -0.5089 0.0705 +vn -0.3905 -0.8946 0.2173 +vn 0.2423 0.9699 -0.0257 +vn 0.0664 -0.0474 0.9967 +vn -0.7880 -0.6017 -0.1305 +vn 0.2706 0.9268 0.2604 +vn -0.9804 0.1632 -0.1104 +vn -0.9805 0.1624 0.1104 +vn -0.9295 0.1119 0.3516 +vn -0.7625 0.0370 0.6460 +vn -0.3314 -0.0247 0.9432 +vn 0.3314 -0.0247 0.9432 +vn 0.9804 0.1632 -0.1104 +vt 0.500227 0.427634 +vt 0.500000 0.874915 +vt 0.500000 0.812429 +vt 0.500000 0.187571 +vt 0.500000 0.125085 +vt 0.500000 0.250057 +vt 0.500000 0.312543 +vt 0.500000 0.437514 +vt 0.500000 0.375028 +vt 0.500000 0.500000 +vt 0.500000 0.562486 +vt 0.500000 0.687458 +vt 0.500000 0.624972 +vt 0.500000 0.749943 +vt 0.295876 0.125085 +vt 0.295876 0.187571 +vt 0.295876 0.062599 +vt 0.081821 0.062599 +vt 0.081821 0.125085 +vt 0.081821 0.187571 +vt 0.022705 0.250057 +vt 0.022705 0.187571 +vt 0.022705 0.125085 +vt 0.295876 0.250057 +vt 0.081821 0.250057 +vt 0.081821 0.312543 +vt 0.022705 0.312543 +vt 0.295876 0.312543 +vt 0.295876 0.375028 +vt 0.081821 0.375028 +vt 0.295876 0.437514 +vt 0.081821 0.437514 +vt 0.022705 0.375028 +vt 0.022705 0.437514 +vt 0.022705 0.375028 +vt 0.081821 0.500000 +vt 0.022705 0.500000 +vt 0.022705 0.562486 +vt 0.295876 0.562486 +vt 0.081821 0.562486 +vt 0.022705 0.624972 +vt 0.295876 0.624972 +vt 0.081821 0.624972 +vt 0.022706 0.687458 +vt 0.295876 0.687458 +vt 0.081821 0.687458 +vt 0.022706 0.749943 +vt 0.295876 0.749943 +vt 0.081821 0.749943 +vt 0.081821 0.812429 +vt 0.022706 0.812429 +vt 0.081821 0.874915 +vt 0.022706 0.874915 +vt 0.295876 0.812429 +vt 0.295876 0.874915 +vt 0.295876 0.937401 +vt 0.081821 0.937401 +vt 0.500000 0.937401 +vt 0.500000 0.999887 +vt 0.295876 0.999887 +vt 0.295876 0.000113 +vt 0.500000 0.062599 +vt 0.081821 0.000113 +vt 0.081821 0.999887 +vt 0.022706 0.937401 +vt 0.022706 0.999887 +vt 0.022705 0.062599 +vt 0.022705 0.000113 +vt 0.000113 0.940280 +vt 0.000113 0.877794 +vt 0.927520 0.256257 +vt 0.894995 0.092739 +vt 0.532753 0.092739 +vt 0.000113 0.059720 +vt 0.000113 0.002993 +vt 0.000113 0.122206 +vt 0.000113 0.065479 +vt 0.000113 0.184692 +vt 0.000113 0.127964 +vt 0.000113 0.190450 +vt 0.834895 0.394881 +vt 0.756371 0.427407 +vt 0.000113 0.247177 +vt 0.000113 0.309663 +vt 0.000113 0.252936 +vt 0.000113 0.315422 +vt 0.000113 0.377908 +vt 0.000113 0.440394 +vt 0.000113 0.559607 +vt 0.000113 0.502879 +vt 0.000113 0.622092 +vt 0.000113 0.565365 +vt 0.000113 0.684578 +vt 0.000113 0.627851 +vt 0.756371 0.000113 +vt 0.671377 0.000113 +vt 0.000113 0.690337 +vt 0.000113 0.752823 +vt 0.000113 0.809550 +vt 0.000113 0.815309 +vt 0.295876 0.500000 +vt 0.500000 0.000113 +vt 0.000113 0.997007 +vt 0.000113 0.934521 +vt 0.500227 0.171263 +vt 0.500227 0.256257 +vt 0.532753 0.334781 +vt 0.592852 0.394881 +vt 0.671377 0.427407 +vt 0.592853 0.032639 +vt 0.834895 0.032639 +vt 0.894994 0.334781 +vt 0.927520 0.171263 +vt 0.000113 0.372149 +vt 0.000113 0.434635 +vt 0.000113 0.497121 +vt 0.000113 0.747064 +vt 0.000113 0.872036 +s 0 +usemtl Cherry_Red_Scratched_Painted_Steel +f 188/196/252 187/196/252 191/196/252 +f 187/196/253 301/196/253 190/196/253 +f 187/196/252 189/196/252 191/196/252 +f 187/196/254 268/196/254 189/196/254 +f 192/197/252 201/198/252 191/197/252 +f 189/196/252 192/196/252 191/196/252 +f 193/199/252 204/200/252 191/199/252 +f 194/201/252 193/199/252 191/201/252 +f 199/202/252 194/201/252 191/202/252 +f 204/196/252 188/196/252 191/196/252 +f 195/203/252 202/204/252 191/203/252 +f 196/205/252 195/203/252 191/205/252 +f 200/206/252 196/205/252 191/206/252 +f 197/207/252 203/208/252 191/207/252 +f 198/209/252 197/207/252 191/209/252 +f 201/198/252 198/209/252 191/198/252 +f 202/204/252 199/202/252 191/204/252 +f 203/208/252 200/206/252 191/208/252 +f 204/200/255 209/210/255 205/200/255 +f 188/196/256 205/196/256 301/196/256 +f 206/210/257 193/199/257 207/211/257 +f 206/210/258 212/211/258 211/210/258 +f 208/212/259 209/210/259 206/210/259 +f 274/213/260 206/210/260 210/214/260 +f 206/210/261 213/214/261 210/214/261 +f 213/214/262 212/211/262 214/215/262 +f 210/214/252 214/215/252 215/215/252 +f 207/211/263 214/215/263 212/211/263 +f 215/215/264 218/216/264 216/217/264 +f 210/214/265 216/217/265 284/218/265 +f 215/215/266 219/219/266 217/220/266 +f 218/216/267 220/220/267 221/216/267 +f 219/219/268 220/220/268 217/220/268 +f 221/216/269 223/221/269 225/222/269 +f 222/219/270 223/221/270 220/220/270 +f 227/223/271 223/221/271 226/223/271 +f 291/222/272 223/221/272 224/221/272 +f 227/223/258 222/219/258 219/219/258 +f 199/202/273 228/224/273 227/223/273 +f 194/201/274 227/223/274 219/219/274 +f 227/223/275 230/225/275 224/221/275 +f 202/204/276 229/226/276 228/224/276 +f 228/224/277 232/227/277 230/225/277 +f 231/228/278 232/227/278 233/229/278 +f 291/222/279 230/225/279 231/230/279 +f 233/229/280 234/231/280 235/232/280 +f 229/226/281 234/231/281 232/227/281 +f 234/231/282 238/233/282 235/232/282 +f 234/231/283 239/234/283 237/235/283 +f 237/235/284 241/236/284 238/233/284 +f 237/235/285 242/237/285 240/238/285 +f 240/238/286 244/239/286 241/236/286 +f 240/238/287 245/240/287 243/241/287 +f 244/239/272 246/241/272 247/239/272 +f 245/240/271 246/241/271 243/241/271 +f 246/241/288 250/242/288 247/239/288 +f 246/241/289 251/243/289 249/244/289 +f 253/242/290 249/244/290 252/244/290 +f 254/243/268 249/244/268 251/243/268 +f 253/242/291 255/245/291 256/246/291 +f 254/243/292 255/245/292 252/244/292 +f 256/246/293 258/247/293 277/248/293 +f 257/249/263 259/245/263 255/245/263 +f 258/247/252 259/245/252 261/247/252 +f 260/249/294 261/247/294 259/245/294 +f 263/250/261 261/247/261 262/250/261 +f 263/250/258 260/249/258 257/249/258 +f 192/197/295 265/250/295 263/250/295 +f 201/198/296 263/250/296 257/249/296 +f 264/251/297 265/250/297 267/251/297 +f 263/250/298 275/252/298 258/247/298 +f 265/250/299 268/253/299 267/251/299 +f 267/251/300 190/254/300 269/255/300 +f 271/255/301 267/251/301 269/255/301 +f 269/256/302 301/257/302 270/212/302 +f 271/256/303 270/212/303 208/212/303 +f 272/258/304 208/212/304 274/213/304 +f 264/251/305 272/259/305 275/252/305 +f 276/260/306 272/259/306 273/261/306 +f 272/258/307 283/262/307 273/263/307 +f 277/248/308 275/252/308 276/260/308 +f 273/261/309 278/264/309 276/260/309 +f 276/260/310 279/265/310 277/248/310 +f 292/266/258 294/267/258 279/268/258 +f 273/263/311 281/269/311 280/270/311 +f 283/262/312 282/271/312 281/272/312 +f 274/213/313 284/218/313 283/262/313 +f 284/218/314 285/273/314 282/274/314 +f 218/216/315 285/275/315 216/217/315 +f 287/276/316 288/277/316 289/276/316 +f 286/278/317 221/216/317 288/278/317 +f 221/216/318 289/279/318 288/280/318 +f 287/281/319 225/222/319 291/222/319 +f 231/230/320 287/281/320 291/222/320 +f 233/229/321 290/282/321 231/228/321 +f 235/232/322 292/283/322 233/229/322 +f 235/232/323 294/284/323 293/285/323 +f 238/233/324 295/286/324 294/287/324 +f 241/236/325 296/288/325 295/289/325 +f 296/290/326 299/291/326 297/291/326 +f 296/288/327 247/239/327 298/288/327 +f 250/242/328 298/292/328 247/239/328 +f 297/293/329 250/242/329 253/242/329 +f 253/242/330 300/294/330 297/293/330 +f 277/248/331 300/295/331 256/246/331 +f 270/212/332 205/200/332 209/210/332 +f 189/196/333 266/196/333 192/196/333 +f 198/209/334 257/249/334 254/243/334 +f 245/240/335 198/209/335 254/243/335 +f 245/240/258 251/243/258 248/240/258 +f 242/237/336 197/207/336 245/240/336 +f 239/234/337 203/208/337 242/237/337 +f 236/296/338 200/206/338 239/234/338 +f 195/203/339 236/296/339 229/226/339 +f 207/211/340 194/201/340 219/219/340 +f 187/196/341 188/196/341 301/196/341 +f 187/196/342 190/196/342 268/196/342 +f 204/200/343 206/210/343 209/210/343 +f 188/196/344 204/196/344 205/196/344 +f 206/210/345 204/200/345 193/199/345 +f 206/210/258 207/211/258 212/211/258 +f 208/212/346 270/212/346 209/210/346 +f 274/213/347 208/212/347 206/210/347 +f 206/210/261 211/210/261 213/214/261 +f 213/214/348 211/210/348 212/211/348 +f 210/214/252 213/214/252 214/215/252 +f 207/211/263 215/215/263 214/215/263 +f 215/215/349 217/220/349 218/216/349 +f 210/214/350 215/215/350 216/217/350 +f 215/215/351 207/211/351 219/219/351 +f 218/216/267 217/220/267 220/220/267 +f 219/219/268 222/219/268 220/220/268 +f 221/216/352 220/220/352 223/221/352 +f 222/219/353 226/223/353 223/221/353 +f 227/223/271 224/221/271 223/221/271 +f 291/222/272 225/222/272 223/221/272 +f 227/223/258 226/223/258 222/219/258 +f 199/202/354 202/204/354 228/224/354 +f 194/201/355 199/202/355 227/223/355 +f 227/223/356 228/224/356 230/225/356 +f 202/204/357 195/203/357 229/226/357 +f 228/224/358 229/226/358 232/227/358 +f 231/228/359 230/225/359 232/227/359 +f 291/222/360 224/221/360 230/225/360 +f 233/229/361 232/227/361 234/231/361 +f 229/226/362 236/296/362 234/231/362 +f 234/231/363 237/235/363 238/233/363 +f 234/231/364 236/296/364 239/234/364 +f 237/235/365 240/238/365 241/236/365 +f 237/235/366 239/234/366 242/237/366 +f 240/238/367 243/241/367 244/239/367 +f 240/238/368 242/237/368 245/240/368 +f 244/239/272 243/241/272 246/241/272 +f 245/240/271 248/240/271 246/241/271 +f 246/241/369 249/244/369 250/242/369 +f 246/241/370 248/240/370 251/243/370 +f 253/242/290 250/242/290 249/244/290 +f 254/243/268 252/244/268 249/244/268 +f 253/242/371 252/244/371 255/245/371 +f 254/243/372 257/249/372 255/245/372 +f 256/246/373 255/245/373 258/247/373 +f 257/249/263 260/249/263 259/245/263 +f 258/247/252 255/245/252 259/245/252 +f 260/249/374 262/250/374 261/247/374 +f 263/250/261 258/247/261 261/247/261 +f 263/250/258 262/250/258 260/249/258 +f 192/197/375 266/197/375 265/250/375 +f 201/198/376 192/197/376 263/250/376 +f 264/251/377 263/250/377 265/250/377 +f 263/250/378 264/251/378 275/252/378 +f 265/250/299 266/197/299 268/253/299 +f 267/251/300 268/253/300 190/254/300 +f 271/255/379 264/251/379 267/251/379 +f 269/256/302 190/297/302 301/257/302 +f 271/256/380 269/256/380 270/212/380 +f 272/258/381 271/256/381 208/212/381 +f 264/251/382 271/255/382 272/259/382 +f 276/260/383 275/252/383 272/259/383 +f 272/258/384 274/213/384 283/262/384 +f 277/248/385 258/247/385 275/252/385 +f 273/261/309 280/298/309 278/264/309 +f 276/260/310 278/299/310 279/265/310 +f 278/300/258 280/301/258 281/302/258 +f 281/302/258 282/303/258 285/304/258 +f 281/302/258 285/304/258 286/277/258 +f 279/268/258 278/300/258 281/302/258 +f 297/291/258 300/305/258 279/268/258 +f 294/267/258 295/306/258 296/290/258 +f 296/290/258 297/291/258 279/268/258 +f 279/268/258 281/302/258 286/277/258 +f 287/276/258 290/307/258 292/266/258 +f 279/268/258 286/277/258 287/276/258 +f 294/267/258 296/290/258 279/268/258 +f 292/266/258 293/308/258 294/267/258 +f 279/268/258 287/276/258 292/266/258 +f 273/263/311 283/262/311 281/269/311 +f 283/262/312 284/218/312 282/271/312 +f 274/213/386 210/214/386 284/218/386 +f 284/218/314 216/217/314 285/273/314 +f 218/216/387 286/278/387 285/275/387 +f 287/276/388 286/277/388 288/277/388 +f 286/278/329 218/216/329 221/216/329 +f 221/216/318 225/222/318 289/279/318 +f 287/281/389 289/281/389 225/222/389 +f 231/230/390 290/309/390 287/281/390 +f 233/229/321 292/310/321 290/282/321 +f 235/232/322 293/311/322 292/283/322 +f 235/232/323 238/233/323 294/284/323 +f 238/233/324 241/236/324 295/286/324 +f 241/236/391 244/239/391 296/288/391 +f 296/290/392 298/290/392 299/291/392 +f 296/288/319 244/239/319 247/239/319 +f 250/242/328 299/312/328 298/292/328 +f 297/293/393 299/293/393 250/242/393 +f 253/242/394 256/246/394 300/294/394 +f 277/248/331 279/313/331 300/295/331 +f 270/212/332 301/257/332 205/200/332 +f 189/196/395 268/196/395 266/196/395 +f 198/209/396 201/198/396 257/249/396 +f 245/240/397 197/207/397 198/209/397 +f 245/240/258 254/243/258 251/243/258 +f 242/237/398 203/208/398 197/207/398 +f 239/234/399 200/206/399 203/208/399 +f 236/296/400 196/205/400 200/206/400 +f 195/203/401 196/205/401 236/296/401 +f 207/211/402 193/199/402 194/201/402 +o Cube.007 +v -0.083986 0.268745 -0.053080 +v -0.083986 0.272597 -0.057378 +v -0.070974 0.268745 -0.050492 +v -0.096997 0.268745 -0.050492 +v -0.098642 0.272597 -0.054463 +v -0.108028 0.268745 -0.043122 +v -0.111067 0.272597 -0.046161 +v -0.115398 0.268745 -0.032091 +v -0.119369 0.272597 -0.033736 +v -0.117987 0.268745 -0.019079 +v -0.122285 0.272597 -0.019079 +v -0.115398 0.268745 -0.006068 +v -0.119369 0.272597 -0.004423 +v -0.108028 0.268745 0.004963 +v -0.111067 0.272597 0.008002 +v -0.096997 0.268745 0.012334 +v -0.098642 0.272597 0.016305 +v -0.083986 0.268745 0.014922 +v -0.083986 0.272597 0.019220 +v -0.070974 0.268745 0.012334 +v -0.069329 0.272597 0.016305 +v -0.059943 0.268745 0.004963 +v -0.056904 0.272597 0.008002 +v -0.052573 0.268745 -0.006068 +v -0.048602 0.272597 -0.004423 +v -0.049985 0.268745 -0.019079 +v -0.045686 0.272597 -0.019079 +v -0.052573 0.268745 -0.032091 +v -0.048602 0.272597 -0.033736 +v -0.059943 0.268745 -0.043122 +v -0.056904 0.272597 -0.046161 +v -0.069329 0.272597 -0.054463 +v -0.056904 0.510706 -0.046161 +v -0.060736 0.515562 -0.042329 +v -0.069329 0.510706 -0.054463 +v -0.048602 0.510706 -0.033736 +v -0.053608 0.515562 -0.031662 +v -0.045686 0.510706 -0.019079 +v -0.051105 0.515562 -0.019079 +v -0.048602 0.510706 -0.004423 +v -0.053608 0.515562 -0.006497 +v -0.056904 0.510706 0.008002 +v -0.060736 0.515562 0.004171 +v -0.069329 0.510706 0.016305 +v -0.071403 0.515562 0.011298 +v -0.083986 0.510706 0.019220 +v -0.083986 0.515562 0.013801 +v -0.098642 0.510706 0.016305 +v -0.096568 0.515562 0.011298 +v -0.111067 0.510706 0.008002 +v -0.107235 0.515562 0.004171 +v -0.119369 0.510706 -0.004423 +v -0.114363 0.515562 -0.006497 +v -0.122285 0.510706 -0.019079 +v -0.116866 0.515562 -0.019079 +v -0.119369 0.510706 -0.033736 +v -0.114363 0.515562 -0.031662 +v -0.111067 0.510706 -0.046161 +v -0.107235 0.515562 -0.042329 +v -0.098642 0.510706 -0.054463 +v -0.096568 0.515562 -0.049457 +v -0.083986 0.510706 -0.057378 +v -0.083986 0.515562 -0.051959 +v -0.071403 0.515562 -0.049457 +vn -0.0000 -0.9294 -0.3691 +vn -0.0000 -0.4021 -0.9156 +vn 0.1164 -0.9269 -0.3569 +vn -0.1164 -0.9269 -0.3569 +vn -0.3894 -0.3940 -0.8326 +vn -0.2524 -0.9177 -0.3067 +vn -0.7013 -0.3568 -0.6171 +vn -0.4028 -0.8932 -0.1999 +vn -0.9145 -0.2606 -0.3094 +vn -0.5152 -0.8571 -0.0000 +vn -0.9831 -0.1831 -0.0000 +vn -0.4028 -0.8932 0.1999 +vn -0.9145 -0.2606 0.3094 +vn -0.2524 -0.9177 0.3067 +vn -0.7013 -0.3568 0.6171 +vn -0.1164 -0.9269 0.3569 +vn -0.3894 -0.3940 0.8326 +vn -0.0000 -0.9294 0.3691 +vn -0.0000 -0.4021 0.9156 +vn 0.1164 -0.9269 0.3569 +vn 0.3894 -0.3940 0.8326 +vn 0.2524 -0.9177 0.3067 +vn 0.7013 -0.3568 0.6171 +vn 0.4028 -0.8932 0.1999 +vn 0.9145 -0.2606 0.3094 +vn 0.5152 -0.8571 -0.0000 +vn 0.9831 -0.1831 -0.0000 +vn 0.4028 -0.8932 -0.1999 +vn 0.9145 -0.2606 -0.3094 +vn 0.2524 -0.9177 -0.3067 +vn 0.7013 -0.3568 -0.6171 +vn 0.3894 -0.3940 -0.8326 +vn 0.7013 0.3568 -0.6171 +vn 0.2524 0.9177 -0.3067 +vn 0.3894 0.3940 -0.8326 +vn 0.9145 0.2606 -0.3094 +vn 0.4028 0.8932 -0.1999 +vn 0.9831 0.1831 -0.0000 +vn 0.5152 0.8571 -0.0000 +vn 0.9145 0.2606 0.3094 +vn 0.4028 0.8932 0.1999 +vn 0.7013 0.3568 0.6171 +vn 0.2524 0.9177 0.3067 +vn 0.3894 0.3940 0.8326 +vn 0.1164 0.9269 0.3569 +vn -0.0000 0.4021 0.9156 +vn -0.0000 0.9294 0.3691 +vn -0.3894 0.3940 0.8326 +vn -0.1164 0.9269 0.3569 +vn -0.7013 0.3568 0.6171 +vn -0.2524 0.9177 0.3067 +vn -0.9145 0.2606 0.3094 +vn -0.4028 0.8932 0.1999 +vn -0.9831 0.1831 -0.0000 +vn -0.5152 0.8571 -0.0000 +vn -0.9145 0.2606 -0.3094 +vn -0.4028 0.8932 -0.1999 +vn -0.7013 0.3568 -0.6171 +vn -0.2524 0.9177 -0.3067 +vn -0.3894 0.3940 -0.8326 +vn -0.1164 0.9269 -0.3569 +vn -0.0000 0.4021 -0.9156 +vn -0.0000 0.9294 -0.3691 +vn 0.1164 0.9269 -0.3569 +vt 0.750000 0.490000 +vt 0.668463 0.446847 +vt 0.658156 0.471731 +vt 0.831537 0.446847 +vt 0.750000 0.463065 +vt 0.831537 0.053153 +vt 0.553153 0.168463 +vt 0.599340 0.400660 +vt 0.580294 0.419706 +vt 0.553153 0.331537 +vt 0.528269 0.341844 +vt 0.536935 0.250000 +vt 0.510000 0.250000 +vt 0.528269 0.158156 +vt 0.580294 0.080294 +vt 0.599340 0.099340 +vt 0.658156 0.028269 +vt 0.668463 0.053153 +vt 0.750000 0.010000 +vt 0.750000 0.036935 +vt 0.841844 0.028269 +vt 0.900660 0.099340 +vt 0.919706 0.080294 +vt 0.946847 0.168463 +vt 0.971731 0.158156 +vt 0.963065 0.250000 +vt 0.990000 0.250000 +vt 0.971731 0.341844 +vt 0.946847 0.331537 +vt 0.919706 0.419706 +vt 0.900660 0.400660 +vt 0.841844 0.471731 +vt 0.937500 0.507803 +vt 0.875000 0.990163 +vt 0.875000 0.507803 +vt 0.812500 0.507803 +vt 0.419706 0.419706 +vt 0.440358 0.328849 +vt 0.471731 0.341844 +vt 0.341844 0.471731 +vt 0.395694 0.395694 +vt 0.456042 0.250000 +vt 0.490000 0.250000 +vt 0.812500 0.990163 +vt 0.750000 0.507803 +vt 0.471731 0.158156 +vt 0.440358 0.171151 +vt 0.750000 0.990163 +vt 0.687500 0.507803 +vt 0.419706 0.080294 +vt 0.395694 0.104306 +vt 0.687500 0.990163 +vt 0.625000 0.507803 +vt 0.341844 0.028269 +vt 0.328849 0.059642 +vt 0.625000 0.990163 +vt 0.562500 0.507803 +vt 0.250000 0.010000 +vt 0.250000 0.043958 +vt 0.562500 0.990163 +vt 0.500000 0.507803 +vt 0.171151 0.059642 +vt 0.158156 0.028269 +vt 0.500000 0.990163 +vt 0.437500 0.507803 +vt 0.104306 0.104306 +vt 0.080294 0.080294 +vt 0.437500 0.990163 +vt 0.375000 0.507803 +vt 0.059642 0.171151 +vt 0.028269 0.158156 +vt 0.375000 0.990163 +vt 0.312500 0.507803 +vt 0.043958 0.250000 +vt 0.010000 0.250000 +vt 0.312500 0.990163 +vt 0.250000 0.507803 +vt 0.028269 0.341844 +vt 0.059642 0.328849 +vt 0.187500 0.990163 +vt 0.187500 0.507803 +vt 0.080294 0.419706 +vt 0.104306 0.395694 +vt 0.125000 0.507803 +vt 0.158156 0.471731 +vt 0.171151 0.440358 +vt 0.062500 0.990163 +vt 0.062500 0.507803 +vt 0.250000 0.490000 +vt 0.250000 0.456042 +vt 0.000000 0.990163 +vt 0.000000 0.507803 +vt 1.000000 0.507803 +vt 0.937500 0.990163 +vt 0.328849 0.440358 +vt 0.250000 0.990163 +vt 0.125000 0.990163 +vt 1.000000 0.990163 +s 1 +usemtl Cherry_Red_Scratched_Painted_Steel +f 303/314/404 305/315/406 306/316/407 +f 303/314/404 304/317/405 302/318/403 +f 321/319/422 313/320/414 305/315/406 +f 306/316/407 307/321/408 308/322/409 +f 308/322/409 309/323/410 310/324/411 +f 310/324/411 311/325/412 312/326/413 +f 314/327/415 311/325/412 313/320/414 +f 316/328/417 313/320/414 315/329/416 +f 318/330/419 315/329/416 317/331/418 +f 320/332/421 317/331/418 319/333/420 +f 320/332/421 321/319/422 322/334/423 +f 322/334/423 323/335/424 324/336/425 +f 324/336/425 325/337/426 326/338/427 +f 326/338/427 327/339/428 328/340/429 +f 330/341/431 327/339/428 329/342/430 +f 332/343/433 329/342/430 331/344/432 +f 333/345/434 331/344/432 304/317/405 +f 333/346/434 334/347/435 332/348/433 +f 334/347/435 330/349/431 332/348/433 +f 334/350/435 338/351/439 337/352/438 +f 336/353/437 335/354/436 334/350/435 +f 337/352/438 340/355/441 339/356/440 +f 337/357/438 328/358/429 330/349/431 +f 341/359/442 340/355/441 342/360/443 +f 339/361/440 326/362/427 328/358/429 +f 343/363/444 342/360/443 344/364/445 +f 341/365/442 324/366/425 326/362/427 +f 345/367/446 344/364/445 346/368/447 +f 343/369/444 322/370/423 324/366/425 +f 347/371/448 346/368/447 348/372/449 +f 345/373/446 320/374/421 322/370/423 +f 347/371/448 350/375/451 349/376/450 +f 347/377/448 318/378/419 320/374/421 +f 349/376/450 352/379/453 351/380/452 +f 349/381/450 316/382/417 318/378/419 +f 351/380/452 354/383/455 353/384/454 +f 351/385/452 314/386/415 316/382/417 +f 353/384/454 356/387/457 355/388/456 +f 353/389/454 312/390/413 314/386/415 +f 357/391/458 356/387/457 358/392/459 +f 312/390/413 357/393/458 310/394/411 +f 359/395/460 358/392/459 360/396/461 +f 357/393/458 308/397/409 310/394/411 +f 361/398/462 360/396/461 362/399/463 +f 308/397/409 361/400/462 306/401/407 +f 363/402/464 362/399/463 364/403/465 +f 306/401/407 363/404/464 303/405/404 +f 303/406/404 336/407/437 333/346/434 +f 363/402/464 365/408/466 336/353/437 +f 352/379/453 344/364/445 335/354/436 +f 303/314/404 302/318/403 305/315/406 +f 303/314/404 333/345/434 304/317/405 +f 305/315/406 302/318/403 304/317/405 +f 304/317/405 331/344/432 329/342/430 +f 329/342/430 327/339/428 325/337/426 +f 325/337/426 323/335/424 321/319/422 +f 321/319/422 319/333/420 317/331/418 +f 317/331/418 315/329/416 313/320/414 +f 313/320/414 311/325/412 309/323/410 +f 309/323/410 307/321/408 305/315/406 +f 305/315/406 304/317/405 329/342/430 +f 329/342/430 325/337/426 321/319/422 +f 321/319/422 317/331/418 313/320/414 +f 313/320/414 309/323/410 305/315/406 +f 305/315/406 329/342/430 321/319/422 +f 306/316/407 305/315/406 307/321/408 +f 308/322/409 307/321/408 309/323/410 +f 310/324/411 309/323/410 311/325/412 +f 314/327/415 312/326/413 311/325/412 +f 316/328/417 314/327/415 313/320/414 +f 318/330/419 316/328/417 315/329/416 +f 320/332/421 318/330/419 317/331/418 +f 320/332/421 319/333/420 321/319/422 +f 322/334/423 321/319/422 323/335/424 +f 324/336/425 323/335/424 325/337/426 +f 326/338/427 325/337/426 327/339/428 +f 330/341/431 328/340/429 327/339/428 +f 332/343/433 330/341/431 329/342/430 +f 333/345/434 332/343/433 331/344/432 +f 333/346/434 336/407/437 334/347/435 +f 334/347/435 337/357/438 330/349/431 +f 334/350/435 335/354/436 338/351/439 +f 336/353/437 365/408/466 335/354/436 +f 337/352/438 338/351/439 340/355/441 +f 337/357/438 339/361/440 328/358/429 +f 341/359/442 339/356/440 340/355/441 +f 339/361/440 341/365/442 326/362/427 +f 343/363/444 341/359/442 342/360/443 +f 341/365/442 343/369/444 324/366/425 +f 345/367/446 343/363/444 344/364/445 +f 343/369/444 345/373/446 322/370/423 +f 347/371/448 345/367/446 346/368/447 +f 345/373/446 347/377/448 320/374/421 +f 347/371/448 348/372/449 350/375/451 +f 347/377/448 349/381/450 318/378/419 +f 349/376/450 350/375/451 352/379/453 +f 349/381/450 351/385/452 316/382/417 +f 351/380/452 352/379/453 354/383/455 +f 351/385/452 353/389/454 314/386/415 +f 353/384/454 354/383/455 356/387/457 +f 353/389/454 355/409/456 312/390/413 +f 357/391/458 355/388/456 356/387/457 +f 312/390/413 355/409/456 357/393/458 +f 359/395/460 357/391/458 358/392/459 +f 357/393/458 359/410/460 308/397/409 +f 361/398/462 359/395/460 360/396/461 +f 308/397/409 359/410/460 361/400/462 +f 363/402/464 361/398/462 362/399/463 +f 306/401/407 361/400/462 363/404/464 +f 303/406/404 363/411/464 336/407/437 +f 363/402/464 364/403/465 365/408/466 +f 335/354/436 365/408/466 364/403/465 +f 364/403/465 362/399/463 360/396/461 +f 360/396/461 358/392/459 356/387/457 +f 356/387/457 354/383/455 352/379/453 +f 352/379/453 350/375/451 348/372/449 +f 348/372/449 346/368/447 344/364/445 +f 344/364/445 342/360/443 340/355/441 +f 340/355/441 338/351/439 335/354/436 +f 335/354/436 364/403/465 360/396/461 +f 360/396/461 356/387/457 352/379/453 +f 352/379/453 348/372/449 344/364/445 +f 344/364/445 340/355/441 335/354/436 +f 335/354/436 360/396/461 352/379/453 +o Cube.008 +v -0.041993 0.268745 0.019653 +v -0.041993 0.272597 0.015355 +v -0.028981 0.268745 0.022242 +v -0.055004 0.268745 0.022242 +v -0.056649 0.272597 0.018271 +v -0.066035 0.268745 0.029612 +v -0.069074 0.272597 0.026573 +v -0.073406 0.268745 0.040643 +v -0.077377 0.272597 0.038998 +v -0.075994 0.268745 0.053654 +v -0.080292 0.272597 0.053654 +v -0.073406 0.268745 0.066666 +v -0.077377 0.272597 0.068311 +v -0.066035 0.268745 0.077697 +v -0.069074 0.272597 0.080736 +v -0.055004 0.268745 0.085067 +v -0.056649 0.272597 0.089038 +v -0.041993 0.268745 0.087655 +v -0.041993 0.272597 0.091954 +v -0.028981 0.268745 0.085067 +v -0.027336 0.272597 0.089038 +v -0.017950 0.268745 0.077697 +v -0.014911 0.272597 0.080736 +v -0.010580 0.268745 0.066666 +v -0.006609 0.272597 0.068311 +v -0.007992 0.268745 0.053654 +v -0.003694 0.272597 0.053654 +v -0.010580 0.268745 0.040643 +v -0.006609 0.272597 0.038998 +v -0.017950 0.268745 0.029612 +v -0.014911 0.272597 0.026573 +v -0.027336 0.272597 0.018271 +v -0.014911 0.510706 0.026573 +v -0.018743 0.515562 0.030405 +v -0.027336 0.510706 0.018271 +v -0.006609 0.510706 0.038998 +v -0.011615 0.515562 0.041072 +v -0.003694 0.510706 0.053654 +v -0.009113 0.515562 0.053654 +v -0.006609 0.510706 0.068311 +v -0.011615 0.515562 0.066237 +v -0.014911 0.510706 0.080736 +v -0.018743 0.515562 0.076904 +v -0.027336 0.510706 0.089038 +v -0.029410 0.515562 0.084032 +v -0.041993 0.510706 0.091954 +v -0.041993 0.515562 0.086535 +v -0.056649 0.510706 0.089038 +v -0.054575 0.515562 0.084032 +v -0.069074 0.510706 0.080736 +v -0.065243 0.515562 0.076904 +v -0.077377 0.510706 0.068311 +v -0.072370 0.515562 0.066237 +v -0.080292 0.510706 0.053654 +v -0.074873 0.515562 0.053654 +v -0.077377 0.510706 0.038998 +v -0.072370 0.515562 0.041072 +v -0.069074 0.510706 0.026573 +v -0.065243 0.515562 0.030405 +v -0.056649 0.510706 0.018271 +v -0.054576 0.515562 0.023277 +v -0.041993 0.510706 0.015355 +v -0.041993 0.515562 0.020774 +v -0.029410 0.515562 0.023277 +vn -0.0000 -0.9294 -0.3691 +vn -0.0000 -0.4021 -0.9156 +vn 0.1164 -0.9269 -0.3569 +vn -0.1164 -0.9269 -0.3569 +vn -0.3894 -0.3940 -0.8326 +vn -0.2524 -0.9177 -0.3067 +vn -0.7013 -0.3568 -0.6171 +vn -0.4028 -0.8932 -0.1999 +vn -0.9145 -0.2606 -0.3094 +vn -0.5152 -0.8571 -0.0000 +vn -0.9831 -0.1831 -0.0000 +vn -0.4028 -0.8932 0.1999 +vn -0.9145 -0.2606 0.3094 +vn -0.2524 -0.9177 0.3067 +vn -0.7013 -0.3568 0.6171 +vn -0.1164 -0.9269 0.3569 +vn -0.3894 -0.3940 0.8326 +vn -0.0000 -0.9294 0.3691 +vn -0.0000 -0.4021 0.9156 +vn 0.1164 -0.9269 0.3569 +vn 0.3894 -0.3940 0.8326 +vn 0.2524 -0.9177 0.3067 +vn 0.7013 -0.3568 0.6171 +vn 0.4028 -0.8932 0.1999 +vn 0.9145 -0.2606 0.3094 +vn 0.5152 -0.8571 -0.0000 +vn 0.9831 -0.1831 -0.0000 +vn 0.4028 -0.8932 -0.1999 +vn 0.9145 -0.2606 -0.3094 +vn 0.2524 -0.9177 -0.3067 +vn 0.7013 -0.3568 -0.6171 +vn 0.3894 -0.3940 -0.8326 +vn 0.7013 0.3568 -0.6171 +vn 0.2524 0.9177 -0.3067 +vn 0.3894 0.3940 -0.8326 +vn 0.9145 0.2606 -0.3094 +vn 0.4028 0.8932 -0.1999 +vn 0.9831 0.1831 -0.0000 +vn 0.5152 0.8571 -0.0000 +vn 0.9145 0.2606 0.3094 +vn 0.4028 0.8932 0.1999 +vn 0.7013 0.3568 0.6171 +vn 0.2524 0.9177 0.3067 +vn 0.3894 0.3940 0.8326 +vn 0.1164 0.9269 0.3569 +vn -0.0000 0.4021 0.9156 +vn -0.0000 0.9294 0.3691 +vn -0.3894 0.3940 0.8326 +vn -0.1164 0.9269 0.3569 +vn -0.7013 0.3568 0.6171 +vn -0.2524 0.9177 0.3067 +vn -0.9145 0.2606 0.3094 +vn -0.4028 0.8932 0.1999 +vn -0.9831 0.1831 -0.0000 +vn -0.5152 0.8571 -0.0000 +vn -0.9145 0.2606 -0.3094 +vn -0.4028 0.8932 -0.1999 +vn -0.7013 0.3568 -0.6171 +vn -0.2524 0.9177 -0.3067 +vn -0.3894 0.3940 -0.8326 +vn -0.1164 0.9269 -0.3569 +vn -0.0000 0.4021 -0.9156 +vn -0.0000 0.9294 -0.3691 +vn 0.1164 0.9269 -0.3569 +vt 0.750000 0.490000 +vt 0.668463 0.446847 +vt 0.658156 0.471731 +vt 0.831537 0.446847 +vt 0.750000 0.463065 +vt 0.831537 0.053153 +vt 0.553153 0.168463 +vt 0.599340 0.400660 +vt 0.580294 0.419706 +vt 0.553153 0.331537 +vt 0.528269 0.341844 +vt 0.536935 0.250000 +vt 0.510000 0.250000 +vt 0.528269 0.158156 +vt 0.580294 0.080294 +vt 0.599340 0.099340 +vt 0.658156 0.028269 +vt 0.668463 0.053153 +vt 0.750000 0.010000 +vt 0.750000 0.036935 +vt 0.841844 0.028269 +vt 0.900660 0.099340 +vt 0.919706 0.080294 +vt 0.946847 0.168463 +vt 0.971731 0.158156 +vt 0.963065 0.250000 +vt 0.990000 0.250000 +vt 0.971731 0.341844 +vt 0.946847 0.331537 +vt 0.919706 0.419706 +vt 0.900660 0.400660 +vt 0.841844 0.471731 +vt 0.937500 0.990163 +vt 0.875000 0.507803 +vt 0.937500 0.507803 +vt 0.875000 0.990163 +vt 0.812500 0.507803 +vt 0.419706 0.419706 +vt 0.440358 0.328849 +vt 0.471731 0.341844 +vt 0.341844 0.471731 +vt 0.395694 0.395694 +vt 0.456042 0.250000 +vt 0.490000 0.250000 +vt 0.750000 0.990163 +vt 0.750000 0.507803 +vt 0.471731 0.158156 +vt 0.440358 0.171151 +vt 0.687500 0.507803 +vt 0.419706 0.080294 +vt 0.395694 0.104306 +vt 0.687500 0.990163 +vt 0.625000 0.507803 +vt 0.341844 0.028269 +vt 0.328849 0.059642 +vt 0.625000 0.990163 +vt 0.562500 0.507803 +vt 0.250000 0.010000 +vt 0.250000 0.043958 +vt 0.562500 0.990163 +vt 0.500000 0.507803 +vt 0.171151 0.059642 +vt 0.158156 0.028269 +vt 0.500000 0.990163 +vt 0.437500 0.507803 +vt 0.104306 0.104306 +vt 0.080294 0.080294 +vt 0.437500 0.990163 +vt 0.375000 0.507803 +vt 0.059642 0.171151 +vt 0.028269 0.158156 +vt 0.375000 0.990163 +vt 0.312500 0.507803 +vt 0.043958 0.250000 +vt 0.010000 0.250000 +vt 0.312500 0.990163 +vt 0.250000 0.507803 +vt 0.028269 0.341844 +vt 0.059642 0.328849 +vt 0.250000 0.990163 +vt 0.187500 0.507803 +vt 0.080294 0.419706 +vt 0.104306 0.395694 +vt 0.125000 0.990163 +vt 0.125000 0.507803 +vt 0.158156 0.471731 +vt 0.171151 0.440358 +vt 0.062500 0.990163 +vt 0.062500 0.507803 +vt 0.250000 0.490000 +vt 0.250000 0.456042 +vt 0.000000 0.990163 +vt 0.000000 0.507803 +vt 1.000000 0.507803 +vt 0.328849 0.440358 +vt 0.812500 0.990163 +vt 0.187500 0.990163 +vt 1.000000 0.990163 +s 1 +usemtl Cherry_Red_Scratched_Painted_Steel +f 367/412/468 369/413/470 370/414/471 +f 367/412/468 368/415/469 366/416/467 +f 385/417/486 377/418/478 369/413/470 +f 370/414/471 371/419/472 372/420/473 +f 372/420/473 373/421/474 374/422/475 +f 374/422/475 375/423/476 376/424/477 +f 378/425/479 375/423/476 377/418/478 +f 380/426/481 377/418/478 379/427/480 +f 382/428/483 379/427/480 381/429/482 +f 384/430/485 381/429/482 383/431/484 +f 384/430/485 385/417/486 386/432/487 +f 386/432/487 387/433/488 388/434/489 +f 388/434/489 389/435/490 390/436/491 +f 390/436/491 391/437/492 392/438/493 +f 394/439/495 391/437/492 393/440/494 +f 396/441/497 393/440/494 395/442/496 +f 397/443/498 395/442/496 368/415/469 +f 400/444/501 396/445/497 397/446/498 +f 398/447/499 394/448/495 396/445/497 +f 398/449/499 402/450/503 401/451/502 +f 400/452/501 399/453/500 398/449/499 +f 401/451/502 404/454/505 403/455/504 +f 394/448/495 403/456/504 392/457/493 +f 405/458/506 404/454/505 406/459/507 +f 403/456/504 390/460/491 392/457/493 +f 407/461/508 406/459/507 408/462/509 +f 405/463/506 388/464/489 390/460/491 +f 409/465/510 408/462/509 410/466/511 +f 407/467/508 386/468/487 388/464/489 +f 411/469/512 410/466/511 412/470/513 +f 409/471/510 384/472/485 386/468/487 +f 411/469/512 414/473/515 413/474/514 +f 411/475/512 382/476/483 384/472/485 +f 413/474/514 416/477/517 415/478/516 +f 413/479/514 380/480/481 382/476/483 +f 415/478/516 418/481/519 417/482/518 +f 415/483/516 378/484/479 380/480/481 +f 417/482/518 420/485/521 419/486/520 +f 417/487/518 376/488/477 378/484/479 +f 421/489/522 420/485/521 422/490/523 +f 419/491/520 374/492/475 376/488/477 +f 423/493/524 422/490/523 424/494/525 +f 374/492/475 423/495/524 372/496/473 +f 425/497/526 424/494/525 426/498/527 +f 372/496/473 425/499/526 370/500/471 +f 427/501/528 426/498/527 428/502/529 +f 370/500/471 427/503/528 367/504/468 +f 367/505/468 400/444/501 397/446/498 +f 427/501/528 429/506/530 400/452/501 +f 416/477/517 408/462/509 399/453/500 +f 367/412/468 366/416/467 369/413/470 +f 367/412/468 397/443/498 368/415/469 +f 369/413/470 366/416/467 368/415/469 +f 368/415/469 395/442/496 393/440/494 +f 393/440/494 391/437/492 389/435/490 +f 389/435/490 387/433/488 385/417/486 +f 385/417/486 383/431/484 381/429/482 +f 381/429/482 379/427/480 377/418/478 +f 377/418/478 375/423/476 373/421/474 +f 373/421/474 371/419/472 369/413/470 +f 369/413/470 368/415/469 393/440/494 +f 393/440/494 389/435/490 385/417/486 +f 385/417/486 381/429/482 377/418/478 +f 377/418/478 373/421/474 369/413/470 +f 369/413/470 393/440/494 385/417/486 +f 370/414/471 369/413/470 371/419/472 +f 372/420/473 371/419/472 373/421/474 +f 374/422/475 373/421/474 375/423/476 +f 378/425/479 376/424/477 375/423/476 +f 380/426/481 378/425/479 377/418/478 +f 382/428/483 380/426/481 379/427/480 +f 384/430/485 382/428/483 381/429/482 +f 384/430/485 383/431/484 385/417/486 +f 386/432/487 385/417/486 387/433/488 +f 388/434/489 387/433/488 389/435/490 +f 390/436/491 389/435/490 391/437/492 +f 394/439/495 392/438/493 391/437/492 +f 396/441/497 394/439/495 393/440/494 +f 397/443/498 396/441/497 395/442/496 +f 400/444/501 398/447/499 396/445/497 +f 398/447/499 401/507/502 394/448/495 +f 398/449/499 399/453/500 402/450/503 +f 400/452/501 429/506/530 399/453/500 +f 401/451/502 402/450/503 404/454/505 +f 394/448/495 401/507/502 403/456/504 +f 405/458/506 403/455/504 404/454/505 +f 403/456/504 405/463/506 390/460/491 +f 407/461/508 405/458/506 406/459/507 +f 405/463/506 407/467/508 388/464/489 +f 409/465/510 407/461/508 408/462/509 +f 407/467/508 409/471/510 386/468/487 +f 411/469/512 409/465/510 410/466/511 +f 409/471/510 411/475/512 384/472/485 +f 411/469/512 412/470/513 414/473/515 +f 411/475/512 413/479/514 382/476/483 +f 413/474/514 414/473/515 416/477/517 +f 413/479/514 415/483/516 380/480/481 +f 415/478/516 416/477/517 418/481/519 +f 415/483/516 417/487/518 378/484/479 +f 417/482/518 418/481/519 420/485/521 +f 417/487/518 419/491/520 376/488/477 +f 421/489/522 419/486/520 420/485/521 +f 419/491/520 421/508/522 374/492/475 +f 423/493/524 421/489/522 422/490/523 +f 374/492/475 421/508/522 423/495/524 +f 425/497/526 423/493/524 424/494/525 +f 372/496/473 423/495/524 425/499/526 +f 427/501/528 425/497/526 426/498/527 +f 370/500/471 425/499/526 427/503/528 +f 367/505/468 427/509/528 400/444/501 +f 427/501/528 428/502/529 429/506/530 +f 399/453/500 429/506/530 428/502/529 +f 428/502/529 426/498/527 424/494/525 +f 424/494/525 422/490/523 420/485/521 +f 420/485/521 418/481/519 416/477/517 +f 416/477/517 414/473/515 412/470/513 +f 412/470/513 410/466/511 408/462/509 +f 408/462/509 406/459/507 404/454/505 +f 404/454/505 402/450/503 399/453/500 +f 399/453/500 428/502/529 424/494/525 +f 424/494/525 420/485/521 416/477/517 +f 416/477/517 412/470/513 408/462/509 +f 408/462/509 404/454/505 399/453/500 +f 399/453/500 424/494/525 416/477/517 +o Cube.009 +v 0.041993 0.268745 0.019653 +v 0.041993 0.272597 0.015355 +v 0.055004 0.268745 0.022242 +v 0.028981 0.268745 0.022242 +v 0.027336 0.272597 0.018271 +v 0.017951 0.268745 0.029612 +v 0.014911 0.272597 0.026573 +v 0.010580 0.268745 0.040643 +v 0.006609 0.272597 0.038998 +v 0.007992 0.268745 0.053654 +v 0.003694 0.272597 0.053654 +v 0.010580 0.268745 0.066666 +v 0.006609 0.272597 0.068311 +v 0.017951 0.268745 0.077697 +v 0.014911 0.272597 0.080736 +v 0.028981 0.268745 0.085067 +v 0.027336 0.272597 0.089038 +v 0.041993 0.268745 0.087655 +v 0.041993 0.272597 0.091954 +v 0.055004 0.268745 0.085067 +v 0.056649 0.272597 0.089038 +v 0.066035 0.268745 0.077697 +v 0.069074 0.272597 0.080736 +v 0.073406 0.268745 0.066666 +v 0.077377 0.272597 0.068311 +v 0.075994 0.268745 0.053654 +v 0.080292 0.272597 0.053654 +v 0.073406 0.268745 0.040643 +v 0.077377 0.272597 0.038998 +v 0.066035 0.268745 0.029612 +v 0.069074 0.272597 0.026573 +v 0.056649 0.272597 0.018271 +v 0.069074 0.510706 0.026573 +v 0.065243 0.515562 0.030405 +v 0.056649 0.510706 0.018271 +v 0.077377 0.510706 0.038998 +v 0.072370 0.515562 0.041072 +v 0.080292 0.510706 0.053654 +v 0.074873 0.515562 0.053654 +v 0.077377 0.510706 0.068311 +v 0.072370 0.515562 0.066237 +v 0.069074 0.510706 0.080736 +v 0.065243 0.515562 0.076904 +v 0.056649 0.510706 0.089038 +v 0.054576 0.515562 0.084032 +v 0.041993 0.510706 0.091954 +v 0.041993 0.515562 0.086535 +v 0.027336 0.510706 0.089038 +v 0.029410 0.515562 0.084032 +v 0.014911 0.510706 0.080736 +v 0.018743 0.515562 0.076904 +v 0.006609 0.510706 0.068311 +v 0.011615 0.515562 0.066237 +v 0.003694 0.510706 0.053654 +v 0.009113 0.515562 0.053654 +v 0.006609 0.510706 0.038998 +v 0.011615 0.515562 0.041072 +v 0.014911 0.510706 0.026573 +v 0.018743 0.515562 0.030405 +v 0.027336 0.510706 0.018271 +v 0.029410 0.515562 0.023277 +v 0.041993 0.510706 0.015355 +v 0.041993 0.515562 0.020774 +v 0.054576 0.515562 0.023277 +vn -0.0000 -0.9294 -0.3691 +vn -0.0000 -0.4021 -0.9156 +vn 0.1164 -0.9269 -0.3569 +vn -0.1164 -0.9269 -0.3569 +vn -0.3894 -0.3940 -0.8326 +vn -0.2524 -0.9177 -0.3067 +vn -0.7013 -0.3568 -0.6171 +vn -0.4028 -0.8932 -0.1999 +vn -0.9145 -0.2606 -0.3094 +vn -0.5152 -0.8571 -0.0000 +vn -0.9831 -0.1831 -0.0000 +vn -0.4028 -0.8932 0.1999 +vn -0.9145 -0.2606 0.3094 +vn -0.2524 -0.9177 0.3067 +vn -0.7013 -0.3568 0.6171 +vn -0.1164 -0.9269 0.3569 +vn -0.3894 -0.3940 0.8326 +vn -0.0000 -0.9294 0.3691 +vn -0.0000 -0.4021 0.9156 +vn 0.1164 -0.9269 0.3569 +vn 0.3894 -0.3940 0.8326 +vn 0.2524 -0.9177 0.3067 +vn 0.7013 -0.3568 0.6171 +vn 0.4028 -0.8932 0.1999 +vn 0.9145 -0.2606 0.3094 +vn 0.5152 -0.8571 -0.0000 +vn 0.9831 -0.1831 -0.0000 +vn 0.4028 -0.8932 -0.1999 +vn 0.9145 -0.2606 -0.3094 +vn 0.2524 -0.9177 -0.3067 +vn 0.7013 -0.3568 -0.6171 +vn 0.3894 -0.3940 -0.8326 +vn 0.7013 0.3568 -0.6171 +vn 0.2524 0.9177 -0.3067 +vn 0.3894 0.3940 -0.8326 +vn 0.9145 0.2606 -0.3094 +vn 0.4028 0.8932 -0.1999 +vn 0.9831 0.1831 -0.0000 +vn 0.5152 0.8571 -0.0000 +vn 0.9145 0.2606 0.3094 +vn 0.4028 0.8932 0.1999 +vn 0.7013 0.3568 0.6171 +vn 0.2524 0.9177 0.3067 +vn 0.3894 0.3940 0.8326 +vn 0.1164 0.9269 0.3569 +vn -0.0000 0.4021 0.9156 +vn -0.0000 0.9294 0.3691 +vn -0.3894 0.3940 0.8326 +vn -0.1164 0.9269 0.3569 +vn -0.7013 0.3568 0.6171 +vn -0.2524 0.9177 0.3067 +vn -0.9145 0.2606 0.3094 +vn -0.4028 0.8932 0.1999 +vn -0.9831 0.1831 -0.0000 +vn -0.5152 0.8571 -0.0000 +vn -0.9145 0.2606 -0.3094 +vn -0.4028 0.8932 -0.1999 +vn -0.7013 0.3568 -0.6171 +vn -0.2524 0.9177 -0.3067 +vn -0.3894 0.3940 -0.8326 +vn -0.1164 0.9269 -0.3569 +vn -0.0000 0.4021 -0.9156 +vn -0.0000 0.9294 -0.3691 +vn 0.1164 0.9269 -0.3569 +vt 0.750000 0.490000 +vt 0.668463 0.446847 +vt 0.658156 0.471731 +vt 0.831537 0.446847 +vt 0.750000 0.463065 +vt 0.831537 0.053153 +vt 0.553153 0.168463 +vt 0.599340 0.400660 +vt 0.580294 0.419706 +vt 0.553153 0.331537 +vt 0.528269 0.341844 +vt 0.536935 0.250000 +vt 0.510000 0.250000 +vt 0.528269 0.158156 +vt 0.580294 0.080294 +vt 0.599340 0.099340 +vt 0.658156 0.028269 +vt 0.668463 0.053153 +vt 0.750000 0.010000 +vt 0.750000 0.036935 +vt 0.841844 0.028269 +vt 0.900660 0.099340 +vt 0.919706 0.080294 +vt 0.946847 0.168463 +vt 0.971731 0.158156 +vt 0.963065 0.250000 +vt 0.990000 0.250000 +vt 0.971731 0.341844 +vt 0.946847 0.331537 +vt 0.919706 0.419706 +vt 0.900660 0.400660 +vt 0.841844 0.471731 +vt 0.937500 0.507803 +vt 0.875000 0.990163 +vt 0.875000 0.507803 +vt 0.812500 0.507803 +vt 0.419706 0.419706 +vt 0.440358 0.328849 +vt 0.471731 0.341844 +vt 0.341844 0.471731 +vt 0.395694 0.395694 +vt 0.456042 0.250000 +vt 0.490000 0.250000 +vt 0.812500 0.990163 +vt 0.750000 0.507803 +vt 0.471731 0.158156 +vt 0.440358 0.171151 +vt 0.750000 0.990163 +vt 0.687500 0.507803 +vt 0.419706 0.080294 +vt 0.395694 0.104306 +vt 0.687500 0.990163 +vt 0.625000 0.507803 +vt 0.341844 0.028269 +vt 0.328849 0.059642 +vt 0.625000 0.990163 +vt 0.562500 0.507803 +vt 0.250000 0.010000 +vt 0.250000 0.043958 +vt 0.562500 0.990163 +vt 0.500000 0.507803 +vt 0.171151 0.059642 +vt 0.158156 0.028269 +vt 0.500000 0.990163 +vt 0.437500 0.507803 +vt 0.104306 0.104306 +vt 0.080294 0.080294 +vt 0.437500 0.990163 +vt 0.375000 0.507803 +vt 0.059642 0.171151 +vt 0.028269 0.158156 +vt 0.375000 0.990163 +vt 0.312500 0.507803 +vt 0.043958 0.250000 +vt 0.010000 0.250000 +vt 0.312500 0.990163 +vt 0.250000 0.507803 +vt 0.028269 0.341844 +vt 0.059642 0.328849 +vt 0.187500 0.990163 +vt 0.187500 0.507803 +vt 0.080294 0.419706 +vt 0.104306 0.395694 +vt 0.125000 0.507803 +vt 0.158156 0.471731 +vt 0.171151 0.440358 +vt 0.125000 0.990163 +vt 0.062500 0.507803 +vt 0.250000 0.490000 +vt 0.250000 0.456042 +vt 0.062500 0.990163 +vt 0.000000 0.507803 +vt 1.000000 0.507803 +vt 0.937500 0.990163 +vt 0.328849 0.440358 +vt 0.250000 0.990163 +vt 0.000000 0.990163 +vt 1.000000 0.990163 +s 1 +usemtl Cherry_Red_Scratched_Painted_Steel +f 431/510/532 433/511/534 434/512/535 +f 431/510/532 432/513/533 430/514/531 +f 449/515/550 441/516/542 433/511/534 +f 434/512/535 435/517/536 436/518/537 +f 436/518/537 437/519/538 438/520/539 +f 438/520/539 439/521/540 440/522/541 +f 442/523/543 439/521/540 441/516/542 +f 444/524/545 441/516/542 443/525/544 +f 446/526/547 443/525/544 445/527/546 +f 448/528/549 445/527/546 447/529/548 +f 448/528/549 449/515/550 450/530/551 +f 450/530/551 451/531/552 452/532/553 +f 452/532/553 453/533/554 454/534/555 +f 454/534/555 455/535/556 456/536/557 +f 458/537/559 455/535/556 457/538/558 +f 460/539/561 457/538/558 459/540/560 +f 461/541/562 459/540/560 432/513/533 +f 461/542/562 462/543/563 460/544/561 +f 462/543/563 458/545/559 460/544/561 +f 462/546/563 466/547/567 465/548/566 +f 464/549/565 463/550/564 462/546/563 +f 465/548/566 468/551/569 467/552/568 +f 465/553/566 456/554/557 458/545/559 +f 469/555/570 468/551/569 470/556/571 +f 467/557/568 454/558/555 456/554/557 +f 471/559/572 470/556/571 472/560/573 +f 469/561/570 452/562/553 454/558/555 +f 473/563/574 472/560/573 474/564/575 +f 471/565/572 450/566/551 452/562/553 +f 475/567/576 474/564/575 476/568/577 +f 473/569/574 448/570/549 450/566/551 +f 475/567/576 478/571/579 477/572/578 +f 475/573/576 446/574/547 448/570/549 +f 477/572/578 480/575/581 479/576/580 +f 477/577/578 444/578/545 446/574/547 +f 479/576/580 482/579/583 481/580/582 +f 479/581/580 442/582/543 444/578/545 +f 481/580/582 484/583/585 483/584/584 +f 481/585/582 440/586/541 442/582/543 +f 485/587/586 484/583/585 486/588/587 +f 440/586/541 485/589/586 438/590/539 +f 487/591/588 486/588/587 488/592/589 +f 485/589/586 436/593/537 438/590/539 +f 489/594/590 488/592/589 490/595/591 +f 487/596/588 434/597/535 436/593/537 +f 491/598/592 490/595/591 492/599/593 +f 489/600/590 431/601/532 434/597/535 +f 431/602/532 464/603/565 461/542/562 +f 491/598/592 493/604/594 464/549/565 +f 480/575/581 472/560/573 463/550/564 +f 431/510/532 430/514/531 433/511/534 +f 431/510/532 461/541/562 432/513/533 +f 433/511/534 430/514/531 432/513/533 +f 432/513/533 459/540/560 457/538/558 +f 457/538/558 455/535/556 453/533/554 +f 453/533/554 451/531/552 449/515/550 +f 449/515/550 447/529/548 445/527/546 +f 445/527/546 443/525/544 441/516/542 +f 441/516/542 439/521/540 437/519/538 +f 437/519/538 435/517/536 433/511/534 +f 433/511/534 432/513/533 457/538/558 +f 457/538/558 453/533/554 449/515/550 +f 449/515/550 445/527/546 441/516/542 +f 441/516/542 437/519/538 433/511/534 +f 433/511/534 457/538/558 449/515/550 +f 434/512/535 433/511/534 435/517/536 +f 436/518/537 435/517/536 437/519/538 +f 438/520/539 437/519/538 439/521/540 +f 442/523/543 440/522/541 439/521/540 +f 444/524/545 442/523/543 441/516/542 +f 446/526/547 444/524/545 443/525/544 +f 448/528/549 446/526/547 445/527/546 +f 448/528/549 447/529/548 449/515/550 +f 450/530/551 449/515/550 451/531/552 +f 452/532/553 451/531/552 453/533/554 +f 454/534/555 453/533/554 455/535/556 +f 458/537/559 456/536/557 455/535/556 +f 460/539/561 458/537/559 457/538/558 +f 461/541/562 460/539/561 459/540/560 +f 461/542/562 464/603/565 462/543/563 +f 462/543/563 465/553/566 458/545/559 +f 462/546/563 463/550/564 466/547/567 +f 464/549/565 493/604/594 463/550/564 +f 465/548/566 466/547/567 468/551/569 +f 465/553/566 467/557/568 456/554/557 +f 469/555/570 467/552/568 468/551/569 +f 467/557/568 469/561/570 454/558/555 +f 471/559/572 469/555/570 470/556/571 +f 469/561/570 471/565/572 452/562/553 +f 473/563/574 471/559/572 472/560/573 +f 471/565/572 473/569/574 450/566/551 +f 475/567/576 473/563/574 474/564/575 +f 473/569/574 475/573/576 448/570/549 +f 475/567/576 476/568/577 478/571/579 +f 475/573/576 477/577/578 446/574/547 +f 477/572/578 478/571/579 480/575/581 +f 477/577/578 479/581/580 444/578/545 +f 479/576/580 480/575/581 482/579/583 +f 479/581/580 481/585/582 442/582/543 +f 481/580/582 482/579/583 484/583/585 +f 481/585/582 483/605/584 440/586/541 +f 485/587/586 483/584/584 484/583/585 +f 440/586/541 483/605/584 485/589/586 +f 487/591/588 485/587/586 486/588/587 +f 485/589/586 487/596/588 436/593/537 +f 489/594/590 487/591/588 488/592/589 +f 487/596/588 489/600/590 434/597/535 +f 491/598/592 489/594/590 490/595/591 +f 489/600/590 491/606/592 431/601/532 +f 431/602/532 491/607/592 464/603/565 +f 491/598/592 492/599/593 493/604/594 +f 463/550/564 493/604/594 492/599/593 +f 492/599/593 490/595/591 488/592/589 +f 488/592/589 486/588/587 484/583/585 +f 484/583/585 482/579/583 480/575/581 +f 480/575/581 478/571/579 476/568/577 +f 476/568/577 474/564/575 472/560/573 +f 472/560/573 470/556/571 468/551/569 +f 468/551/569 466/547/567 463/550/564 +f 463/550/564 492/599/593 488/592/589 +f 488/592/589 484/583/585 480/575/581 +f 480/575/581 476/568/577 472/560/573 +f 472/560/573 468/551/569 463/550/564 +f 463/550/564 488/592/589 480/575/581 +o Cube.010 +v 0.083986 0.268745 -0.053080 +v 0.083986 0.272597 -0.057379 +v 0.096997 0.268745 -0.050492 +v 0.070974 0.268745 -0.050492 +v 0.069329 0.272597 -0.054463 +v 0.059943 0.268745 -0.043122 +v 0.056904 0.272597 -0.046161 +v 0.052573 0.268745 -0.032091 +v 0.048602 0.272597 -0.033736 +v 0.049985 0.268745 -0.019079 +v 0.045686 0.272597 -0.019079 +v 0.052573 0.268745 -0.006068 +v 0.048602 0.272597 -0.004423 +v 0.059943 0.268745 0.004963 +v 0.056904 0.272597 0.008002 +v 0.070974 0.268745 0.012334 +v 0.069329 0.272597 0.016305 +v 0.083986 0.268745 0.014922 +v 0.083986 0.272597 0.019220 +v 0.096997 0.268745 0.012334 +v 0.098642 0.272597 0.016305 +v 0.108028 0.268745 0.004963 +v 0.111067 0.272597 0.008002 +v 0.115398 0.268745 -0.006068 +v 0.119369 0.272597 -0.004423 +v 0.117987 0.268745 -0.019079 +v 0.122285 0.272597 -0.019079 +v 0.115398 0.268745 -0.032091 +v 0.119369 0.272597 -0.033736 +v 0.108028 0.268745 -0.043122 +v 0.111067 0.272597 -0.046161 +v 0.098642 0.272597 -0.054463 +v 0.111067 0.510706 -0.046161 +v 0.107235 0.515562 -0.042329 +v 0.098642 0.510706 -0.054463 +v 0.119369 0.510706 -0.033736 +v 0.114363 0.515562 -0.031662 +v 0.122285 0.510706 -0.019079 +v 0.116866 0.515562 -0.019079 +v 0.119369 0.510706 -0.004423 +v 0.114363 0.515562 -0.006497 +v 0.111067 0.510706 0.008002 +v 0.107235 0.515562 0.004171 +v 0.098642 0.510706 0.016305 +v 0.096568 0.515562 0.011298 +v 0.083986 0.510706 0.019220 +v 0.083986 0.515562 0.013801 +v 0.069329 0.510706 0.016305 +v 0.071403 0.515562 0.011298 +v 0.056904 0.510706 0.008002 +v 0.060736 0.515562 0.004171 +v 0.048602 0.510706 -0.004423 +v 0.053608 0.515562 -0.006497 +v 0.045686 0.510706 -0.019079 +v 0.051105 0.515562 -0.019079 +v 0.048602 0.510706 -0.033736 +v 0.053608 0.515562 -0.031662 +v 0.056904 0.510706 -0.046161 +v 0.060736 0.515562 -0.042329 +v 0.069329 0.510706 -0.054463 +v 0.071403 0.515562 -0.049457 +v 0.083986 0.510706 -0.057378 +v 0.083986 0.515562 -0.051959 +v 0.096568 0.515562 -0.049457 +vn -0.0000 -0.9294 -0.3691 +vn -0.0000 -0.4021 -0.9156 +vn 0.1164 -0.9269 -0.3569 +vn -0.1164 -0.9269 -0.3569 +vn -0.3894 -0.3940 -0.8326 +vn -0.2524 -0.9177 -0.3067 +vn -0.7013 -0.3568 -0.6171 +vn -0.4028 -0.8932 -0.1999 +vn -0.9145 -0.2606 -0.3094 +vn -0.5152 -0.8571 -0.0000 +vn -0.9831 -0.1831 -0.0000 +vn -0.4028 -0.8932 0.1999 +vn -0.9145 -0.2606 0.3094 +vn -0.2524 -0.9177 0.3067 +vn -0.7013 -0.3568 0.6171 +vn -0.1164 -0.9269 0.3569 +vn -0.3894 -0.3940 0.8326 +vn -0.0000 -0.9294 0.3691 +vn -0.0000 -0.4021 0.9156 +vn 0.1164 -0.9269 0.3569 +vn 0.3894 -0.3940 0.8326 +vn 0.2524 -0.9177 0.3067 +vn 0.7013 -0.3568 0.6171 +vn 0.4028 -0.8932 0.1999 +vn 0.9145 -0.2606 0.3094 +vn 0.5152 -0.8571 -0.0000 +vn 0.9831 -0.1831 -0.0000 +vn 0.4028 -0.8932 -0.1999 +vn 0.9145 -0.2606 -0.3094 +vn 0.2524 -0.9177 -0.3067 +vn 0.7013 -0.3568 -0.6171 +vn 0.3894 -0.3940 -0.8326 +vn 0.7013 0.3568 -0.6171 +vn 0.2524 0.9177 -0.3067 +vn 0.3894 0.3940 -0.8326 +vn 0.9145 0.2606 -0.3094 +vn 0.4028 0.8932 -0.1999 +vn 0.9831 0.1831 -0.0000 +vn 0.5152 0.8571 -0.0000 +vn 0.9145 0.2606 0.3094 +vn 0.4028 0.8932 0.1999 +vn 0.7013 0.3568 0.6171 +vn 0.2524 0.9177 0.3067 +vn 0.3894 0.3940 0.8326 +vn 0.1164 0.9269 0.3569 +vn -0.0000 0.4021 0.9156 +vn -0.0000 0.9294 0.3691 +vn -0.3894 0.3940 0.8326 +vn -0.1164 0.9269 0.3569 +vn -0.7013 0.3568 0.6171 +vn -0.2524 0.9177 0.3067 +vn -0.9145 0.2606 0.3094 +vn -0.4028 0.8932 0.1999 +vn -0.9831 0.1831 -0.0000 +vn -0.5152 0.8571 -0.0000 +vn -0.9145 0.2606 -0.3094 +vn -0.4028 0.8932 -0.1999 +vn -0.7013 0.3568 -0.6171 +vn -0.2524 0.9177 -0.3067 +vn -0.3894 0.3940 -0.8326 +vn -0.1164 0.9269 -0.3569 +vn -0.0000 0.4021 -0.9156 +vn -0.0000 0.9294 -0.3691 +vn 0.1164 0.9269 -0.3569 +vt 0.750000 0.490000 +vt 0.668463 0.446847 +vt 0.658156 0.471731 +vt 0.831537 0.446847 +vt 0.750000 0.463065 +vt 0.831537 0.053153 +vt 0.553153 0.168463 +vt 0.599340 0.400660 +vt 0.580294 0.419706 +vt 0.553153 0.331537 +vt 0.528269 0.341844 +vt 0.536935 0.250000 +vt 0.510000 0.250000 +vt 0.528269 0.158156 +vt 0.580294 0.080294 +vt 0.599340 0.099340 +vt 0.658156 0.028269 +vt 0.668463 0.053153 +vt 0.750000 0.010000 +vt 0.750000 0.036935 +vt 0.841844 0.028269 +vt 0.900660 0.099340 +vt 0.919706 0.080294 +vt 0.946847 0.168463 +vt 0.971731 0.158156 +vt 0.963065 0.250000 +vt 0.990000 0.250000 +vt 0.971731 0.341844 +vt 0.946847 0.331537 +vt 0.919706 0.419706 +vt 0.900660 0.400660 +vt 0.841844 0.471731 +vt 0.937500 0.990163 +vt 0.875000 0.507803 +vt 0.937500 0.507803 +vt 0.812500 0.990163 +vt 0.812500 0.507803 +vt 0.419706 0.419706 +vt 0.440358 0.328849 +vt 0.471731 0.341844 +vt 0.341844 0.471731 +vt 0.395694 0.395694 +vt 0.456042 0.250000 +vt 0.490000 0.250000 +vt 0.750000 0.990163 +vt 0.750000 0.507803 +vt 0.471731 0.158156 +vt 0.440358 0.171151 +vt 0.687500 0.507803 +vt 0.419706 0.080294 +vt 0.395694 0.104306 +vt 0.687500 0.990163 +vt 0.625000 0.507803 +vt 0.341844 0.028269 +vt 0.328849 0.059642 +vt 0.625000 0.990163 +vt 0.562500 0.507803 +vt 0.250000 0.010000 +vt 0.250000 0.043958 +vt 0.562500 0.990163 +vt 0.500000 0.507803 +vt 0.171151 0.059642 +vt 0.158156 0.028269 +vt 0.500000 0.990163 +vt 0.437500 0.507803 +vt 0.104306 0.104306 +vt 0.080294 0.080294 +vt 0.437500 0.990163 +vt 0.375000 0.507803 +vt 0.059642 0.171151 +vt 0.028269 0.158156 +vt 0.375000 0.990163 +vt 0.312500 0.507803 +vt 0.043958 0.250000 +vt 0.010000 0.250000 +vt 0.312500 0.990163 +vt 0.250000 0.507803 +vt 0.028269 0.341844 +vt 0.059642 0.328849 +vt 0.187500 0.990163 +vt 0.187500 0.507803 +vt 0.080294 0.419706 +vt 0.104306 0.395694 +vt 0.125000 0.990163 +vt 0.125000 0.507803 +vt 0.158156 0.471731 +vt 0.171151 0.440358 +vt 0.062500 0.990163 +vt 0.062500 0.507803 +vt 0.250000 0.490000 +vt 0.250000 0.456042 +vt 0.000000 0.990163 +vt 0.000000 0.507803 +vt 1.000000 0.507803 +vt 0.328849 0.440358 +vt 0.875000 0.990163 +vt 0.250000 0.990163 +vt 1.000000 0.990163 +s 1 +usemtl Cherry_Red_Scratched_Painted_Steel +f 495/608/596 497/609/598 498/610/599 +f 495/608/596 496/611/597 494/612/595 +f 513/613/614 505/614/606 497/609/598 +f 498/610/599 499/615/600 500/616/601 +f 500/616/601 501/617/602 502/618/603 +f 502/618/603 503/619/604 504/620/605 +f 506/621/607 503/619/604 505/614/606 +f 508/622/609 505/614/606 507/623/608 +f 510/624/611 507/623/608 509/625/610 +f 512/626/613 509/625/610 511/627/612 +f 512/626/613 513/613/614 514/628/615 +f 514/628/615 515/629/616 516/630/617 +f 516/630/617 517/631/618 518/632/619 +f 518/632/619 519/633/620 520/634/621 +f 522/635/623 519/633/620 521/636/622 +f 524/637/625 521/636/622 523/638/624 +f 525/639/626 523/638/624 496/611/597 +f 528/640/629 524/641/625 525/642/626 +f 524/641/625 529/643/630 522/644/623 +f 526/645/627 530/646/631 529/647/630 +f 528/648/629 527/649/628 526/645/627 +f 529/647/630 532/650/633 531/651/632 +f 522/644/623 531/652/632 520/653/621 +f 533/654/634 532/650/633 534/655/635 +f 531/652/632 518/656/619 520/653/621 +f 535/657/636 534/655/635 536/658/637 +f 533/659/634 516/660/617 518/656/619 +f 537/661/638 536/658/637 538/662/639 +f 535/663/636 514/664/615 516/660/617 +f 539/665/640 538/662/639 540/666/641 +f 537/667/638 512/668/613 514/664/615 +f 539/665/640 542/669/643 541/670/642 +f 539/671/640 510/672/611 512/668/613 +f 541/670/642 544/673/645 543/674/644 +f 541/675/642 508/676/609 510/672/611 +f 543/674/644 546/677/647 545/678/646 +f 543/679/644 506/680/607 508/676/609 +f 545/678/646 548/681/649 547/682/648 +f 545/683/646 504/684/605 506/680/607 +f 549/685/650 548/681/649 550/686/651 +f 504/684/605 549/687/650 502/688/603 +f 551/689/652 550/686/651 552/690/653 +f 502/688/603 551/691/652 500/692/601 +f 553/693/654 552/690/653 554/694/655 +f 500/692/601 553/695/654 498/696/599 +f 555/697/656 554/694/655 556/698/657 +f 498/696/599 555/699/656 495/700/596 +f 495/701/596 528/640/629 525/642/626 +f 555/697/656 557/702/658 528/648/629 +f 544/673/645 536/658/637 527/649/628 +f 495/608/596 494/612/595 497/609/598 +f 495/608/596 525/639/626 496/611/597 +f 497/609/598 494/612/595 496/611/597 +f 496/611/597 523/638/624 521/636/622 +f 521/636/622 519/633/620 517/631/618 +f 517/631/618 515/629/616 513/613/614 +f 513/613/614 511/627/612 509/625/610 +f 509/625/610 507/623/608 505/614/606 +f 505/614/606 503/619/604 501/617/602 +f 501/617/602 499/615/600 497/609/598 +f 497/609/598 496/611/597 521/636/622 +f 521/636/622 517/631/618 513/613/614 +f 513/613/614 509/625/610 505/614/606 +f 505/614/606 501/617/602 497/609/598 +f 497/609/598 521/636/622 513/613/614 +f 498/610/599 497/609/598 499/615/600 +f 500/616/601 499/615/600 501/617/602 +f 502/618/603 501/617/602 503/619/604 +f 506/621/607 504/620/605 503/619/604 +f 508/622/609 506/621/607 505/614/606 +f 510/624/611 508/622/609 507/623/608 +f 512/626/613 510/624/611 509/625/610 +f 512/626/613 511/627/612 513/613/614 +f 514/628/615 513/613/614 515/629/616 +f 516/630/617 515/629/616 517/631/618 +f 518/632/619 517/631/618 519/633/620 +f 522/635/623 520/634/621 519/633/620 +f 524/637/625 522/635/623 521/636/622 +f 525/639/626 524/637/625 523/638/624 +f 528/640/629 526/703/627 524/641/625 +f 524/641/625 526/703/627 529/643/630 +f 526/645/627 527/649/628 530/646/631 +f 528/648/629 557/702/658 527/649/628 +f 529/647/630 530/646/631 532/650/633 +f 522/644/623 529/643/630 531/652/632 +f 533/654/634 531/651/632 532/650/633 +f 531/652/632 533/659/634 518/656/619 +f 535/657/636 533/654/634 534/655/635 +f 533/659/634 535/663/636 516/660/617 +f 537/661/638 535/657/636 536/658/637 +f 535/663/636 537/667/638 514/664/615 +f 539/665/640 537/661/638 538/662/639 +f 537/667/638 539/671/640 512/668/613 +f 539/665/640 540/666/641 542/669/643 +f 539/671/640 541/675/642 510/672/611 +f 541/670/642 542/669/643 544/673/645 +f 541/675/642 543/679/644 508/676/609 +f 543/674/644 544/673/645 546/677/647 +f 543/679/644 545/683/646 506/680/607 +f 545/678/646 546/677/647 548/681/649 +f 545/683/646 547/704/648 504/684/605 +f 549/685/650 547/682/648 548/681/649 +f 504/684/605 547/704/648 549/687/650 +f 551/689/652 549/685/650 550/686/651 +f 502/688/603 549/687/650 551/691/652 +f 553/693/654 551/689/652 552/690/653 +f 500/692/601 551/691/652 553/695/654 +f 555/697/656 553/693/654 554/694/655 +f 498/696/599 553/695/654 555/699/656 +f 495/701/596 555/705/656 528/640/629 +f 555/697/656 556/698/657 557/702/658 +f 527/649/628 557/702/658 556/698/657 +f 556/698/657 554/694/655 552/690/653 +f 552/690/653 550/686/651 548/681/649 +f 548/681/649 546/677/647 544/673/645 +f 544/673/645 542/669/643 540/666/641 +f 540/666/641 538/662/639 536/658/637 +f 536/658/637 534/655/635 532/650/633 +f 532/650/633 530/646/631 527/649/628 +f 527/649/628 556/698/657 552/690/653 +f 552/690/653 548/681/649 544/673/645 +f 544/673/645 540/666/641 536/658/637 +f 536/658/637 532/650/633 527/649/628 +f 527/649/628 552/690/653 544/673/645 +o Cube.011 +v 0.041993 0.268745 -0.125814 +v 0.041993 0.272597 -0.130112 +v 0.055004 0.268745 -0.123226 +v 0.028981 0.268745 -0.123226 +v 0.027336 0.272597 -0.127197 +v 0.017950 0.268745 -0.115855 +v 0.014911 0.272597 -0.118895 +v 0.010580 0.268745 -0.104825 +v 0.006609 0.272597 -0.106469 +v 0.007992 0.268745 -0.091813 +v 0.003694 0.272597 -0.091813 +v 0.010580 0.268745 -0.078801 +v 0.006609 0.272597 -0.077156 +v 0.017950 0.268745 -0.067771 +v 0.014911 0.272597 -0.064731 +v 0.028981 0.268745 -0.060400 +v 0.027336 0.272597 -0.056429 +v 0.041993 0.268745 -0.057812 +v 0.041993 0.272597 -0.053514 +v 0.055004 0.268745 -0.060400 +v 0.056649 0.272597 -0.056429 +v 0.066035 0.268745 -0.067771 +v 0.069074 0.272597 -0.064731 +v 0.073406 0.268745 -0.078801 +v 0.077377 0.272597 -0.077156 +v 0.075994 0.268745 -0.091813 +v 0.080292 0.272597 -0.091813 +v 0.073406 0.268745 -0.104825 +v 0.077377 0.272597 -0.106469 +v 0.066035 0.268745 -0.115855 +v 0.069074 0.272597 -0.118895 +v 0.056649 0.272597 -0.127197 +v 0.069074 0.510706 -0.118895 +v 0.065243 0.515562 -0.115063 +v 0.056649 0.510706 -0.127197 +v 0.077377 0.510706 -0.106469 +v 0.072370 0.515562 -0.104396 +v 0.080292 0.510706 -0.091813 +v 0.074873 0.515562 -0.091813 +v 0.077377 0.510706 -0.077156 +v 0.072370 0.515562 -0.079230 +v 0.069074 0.510706 -0.064731 +v 0.065243 0.515562 -0.068563 +v 0.056649 0.510706 -0.056429 +v 0.054575 0.515562 -0.061436 +v 0.041993 0.510706 -0.053514 +v 0.041993 0.515562 -0.058933 +v 0.027336 0.510706 -0.056429 +v 0.029410 0.515562 -0.061436 +v 0.014911 0.510706 -0.064731 +v 0.018743 0.515562 -0.068563 +v 0.006609 0.510706 -0.077156 +v 0.011615 0.515562 -0.079230 +v 0.003694 0.510706 -0.091813 +v 0.009113 0.515562 -0.091813 +v 0.006609 0.510706 -0.106469 +v 0.011615 0.515562 -0.104396 +v 0.014911 0.510706 -0.118895 +v 0.018743 0.515562 -0.115063 +v 0.027336 0.510706 -0.127197 +v 0.029410 0.515562 -0.122190 +v 0.041993 0.510706 -0.130112 +v 0.041993 0.515562 -0.124693 +v 0.054576 0.515562 -0.122190 +vn -0.0000 -0.9294 -0.3691 +vn -0.0000 -0.4021 -0.9156 +vn 0.1164 -0.9269 -0.3569 +vn -0.1164 -0.9269 -0.3569 +vn -0.3894 -0.3940 -0.8326 +vn -0.2524 -0.9177 -0.3067 +vn -0.7013 -0.3568 -0.6171 +vn -0.4028 -0.8932 -0.1999 +vn -0.9145 -0.2606 -0.3094 +vn -0.5152 -0.8571 -0.0000 +vn -0.9831 -0.1831 -0.0000 +vn -0.4028 -0.8932 0.1999 +vn -0.9145 -0.2606 0.3094 +vn -0.2524 -0.9177 0.3067 +vn -0.7013 -0.3568 0.6171 +vn -0.1164 -0.9269 0.3569 +vn -0.3894 -0.3940 0.8326 +vn -0.0000 -0.9294 0.3691 +vn -0.0000 -0.4021 0.9156 +vn 0.1164 -0.9269 0.3569 +vn 0.3894 -0.3940 0.8326 +vn 0.2524 -0.9177 0.3067 +vn 0.7013 -0.3568 0.6171 +vn 0.4028 -0.8932 0.1999 +vn 0.9145 -0.2606 0.3094 +vn 0.5152 -0.8571 -0.0000 +vn 0.9831 -0.1831 -0.0000 +vn 0.4028 -0.8932 -0.1999 +vn 0.9145 -0.2606 -0.3094 +vn 0.2524 -0.9177 -0.3067 +vn 0.7013 -0.3568 -0.6171 +vn 0.3894 -0.3940 -0.8326 +vn 0.7013 0.3568 -0.6171 +vn 0.2524 0.9177 -0.3067 +vn 0.3894 0.3940 -0.8326 +vn 0.9145 0.2606 -0.3094 +vn 0.4028 0.8932 -0.1999 +vn 0.9831 0.1831 -0.0000 +vn 0.5152 0.8571 -0.0000 +vn 0.9145 0.2606 0.3094 +vn 0.4028 0.8932 0.1999 +vn 0.7013 0.3568 0.6171 +vn 0.2524 0.9177 0.3067 +vn 0.3894 0.3940 0.8326 +vn 0.1164 0.9269 0.3569 +vn -0.0000 0.4021 0.9156 +vn -0.0000 0.9294 0.3691 +vn -0.3894 0.3940 0.8326 +vn -0.1164 0.9269 0.3569 +vn -0.7013 0.3568 0.6171 +vn -0.2524 0.9177 0.3067 +vn -0.9145 0.2606 0.3094 +vn -0.4028 0.8932 0.1999 +vn -0.9831 0.1831 -0.0000 +vn -0.5152 0.8571 -0.0000 +vn -0.9145 0.2606 -0.3094 +vn -0.4028 0.8932 -0.1999 +vn -0.7013 0.3568 -0.6171 +vn -0.2524 0.9177 -0.3067 +vn -0.3894 0.3940 -0.8326 +vn -0.1164 0.9269 -0.3569 +vn -0.0000 0.4021 -0.9156 +vn -0.0000 0.9294 -0.3691 +vn 0.1164 0.9269 -0.3569 +vt 0.750000 0.490000 +vt 0.668463 0.446847 +vt 0.658156 0.471731 +vt 0.831537 0.446847 +vt 0.750000 0.463065 +vt 0.831537 0.053153 +vt 0.553153 0.168463 +vt 0.599340 0.400660 +vt 0.580294 0.419706 +vt 0.553153 0.331537 +vt 0.528269 0.341844 +vt 0.536935 0.250000 +vt 0.510000 0.250000 +vt 0.528269 0.158156 +vt 0.580294 0.080294 +vt 0.599340 0.099340 +vt 0.658156 0.028269 +vt 0.668463 0.053153 +vt 0.750000 0.010000 +vt 0.750000 0.036935 +vt 0.841844 0.028269 +vt 0.900660 0.099340 +vt 0.919706 0.080294 +vt 0.946847 0.168463 +vt 0.971731 0.158156 +vt 0.963065 0.250000 +vt 0.990000 0.250000 +vt 0.971731 0.341844 +vt 0.946847 0.331537 +vt 0.919706 0.419706 +vt 0.900660 0.400660 +vt 0.841844 0.471731 +vt 0.937500 0.507803 +vt 0.875000 0.990163 +vt 0.875000 0.507803 +vt 0.812500 0.990163 +vt 0.812500 0.507803 +vt 0.419706 0.419706 +vt 0.440358 0.328849 +vt 0.471731 0.341844 +vt 0.341844 0.471731 +vt 0.395694 0.395694 +vt 0.456042 0.250000 +vt 0.490000 0.250000 +vt 0.750000 0.507803 +vt 0.471731 0.158156 +vt 0.440358 0.171151 +vt 0.750000 0.990163 +vt 0.687500 0.507803 +vt 0.419706 0.080294 +vt 0.395694 0.104306 +vt 0.687500 0.990163 +vt 0.625000 0.507803 +vt 0.341844 0.028269 +vt 0.328849 0.059642 +vt 0.625000 0.990163 +vt 0.562500 0.507803 +vt 0.250000 0.010000 +vt 0.250000 0.043958 +vt 0.562500 0.990163 +vt 0.500000 0.507803 +vt 0.171151 0.059642 +vt 0.158156 0.028269 +vt 0.500000 0.990163 +vt 0.437500 0.507803 +vt 0.104306 0.104306 +vt 0.080294 0.080294 +vt 0.437500 0.990163 +vt 0.375000 0.507803 +vt 0.059642 0.171151 +vt 0.028269 0.158156 +vt 0.375000 0.990163 +vt 0.312500 0.507803 +vt 0.043958 0.250000 +vt 0.010000 0.250000 +vt 0.312500 0.990163 +vt 0.250000 0.507803 +vt 0.028269 0.341844 +vt 0.059642 0.328849 +vt 0.187500 0.990163 +vt 0.187500 0.507803 +vt 0.080294 0.419706 +vt 0.104306 0.395694 +vt 0.125000 0.990163 +vt 0.125000 0.507803 +vt 0.158156 0.471731 +vt 0.171151 0.440358 +vt 0.062500 0.990163 +vt 0.062500 0.507803 +vt 0.250000 0.490000 +vt 0.250000 0.456042 +vt 0.000000 0.507803 +vt 1.000000 0.507803 +vt 0.937500 0.990163 +vt 0.328849 0.440358 +vt 0.250000 0.990163 +vt 0.000000 0.990163 +vt 1.000000 0.990163 +s 1 +usemtl Cherry_Red_Scratched_Painted_Steel +f 559/706/660 561/707/662 562/708/663 +f 559/706/660 560/709/661 558/710/659 +f 577/711/678 569/712/670 561/707/662 +f 562/708/663 563/713/664 564/714/665 +f 564/714/665 565/715/666 566/716/667 +f 566/716/667 567/717/668 568/718/669 +f 570/719/671 567/717/668 569/712/670 +f 572/720/673 569/712/670 571/721/672 +f 574/722/675 571/721/672 573/723/674 +f 576/724/677 573/723/674 575/725/676 +f 576/724/677 577/711/678 578/726/679 +f 578/726/679 579/727/680 580/728/681 +f 580/728/681 581/729/682 582/730/683 +f 582/730/683 583/731/684 584/732/685 +f 586/733/687 583/731/684 585/734/686 +f 588/735/689 585/734/686 587/736/688 +f 589/737/690 587/736/688 560/709/661 +f 589/738/690 590/739/691 588/740/689 +f 588/740/689 593/741/694 586/742/687 +f 590/743/691 594/744/695 593/745/694 +f 592/746/693 591/747/692 590/743/691 +f 593/745/694 596/748/697 595/749/696 +f 593/741/694 584/750/685 586/742/687 +f 597/751/698 596/748/697 598/752/699 +f 595/753/696 582/754/683 584/750/685 +f 599/755/700 598/752/699 600/756/701 +f 597/757/698 580/758/681 582/754/683 +f 601/759/702 600/756/701 602/760/703 +f 599/761/700 578/762/679 580/758/681 +f 603/763/704 602/760/703 604/764/705 +f 601/765/702 576/766/677 578/762/679 +f 603/763/704 606/767/707 605/768/706 +f 603/769/704 574/770/675 576/766/677 +f 605/768/706 608/771/709 607/772/708 +f 605/773/706 572/774/673 574/770/675 +f 607/772/708 610/775/711 609/776/710 +f 607/777/708 570/778/671 572/774/673 +f 609/776/710 612/779/713 611/780/712 +f 609/781/710 568/782/669 570/778/671 +f 613/783/714 612/779/713 614/784/715 +f 568/782/669 613/785/714 566/786/667 +f 615/787/716 614/784/715 616/788/717 +f 566/786/667 615/789/716 564/790/665 +f 617/791/718 616/788/717 618/792/719 +f 564/790/665 617/793/718 562/794/663 +f 619/795/720 618/792/719 620/796/721 +f 617/793/718 559/797/660 562/794/663 +f 559/798/660 592/799/693 589/738/690 +f 619/795/720 621/800/722 592/746/693 +f 608/771/709 600/756/701 591/747/692 +f 559/706/660 558/710/659 561/707/662 +f 559/706/660 589/737/690 560/709/661 +f 561/707/662 558/710/659 560/709/661 +f 560/709/661 587/736/688 585/734/686 +f 585/734/686 583/731/684 581/729/682 +f 581/729/682 579/727/680 577/711/678 +f 577/711/678 575/725/676 573/723/674 +f 573/723/674 571/721/672 569/712/670 +f 569/712/670 567/717/668 565/715/666 +f 565/715/666 563/713/664 561/707/662 +f 561/707/662 560/709/661 585/734/686 +f 585/734/686 581/729/682 577/711/678 +f 577/711/678 573/723/674 569/712/670 +f 569/712/670 565/715/666 561/707/662 +f 561/707/662 585/734/686 577/711/678 +f 562/708/663 561/707/662 563/713/664 +f 564/714/665 563/713/664 565/715/666 +f 566/716/667 565/715/666 567/717/668 +f 570/719/671 568/718/669 567/717/668 +f 572/720/673 570/719/671 569/712/670 +f 574/722/675 572/720/673 571/721/672 +f 576/724/677 574/722/675 573/723/674 +f 576/724/677 575/725/676 577/711/678 +f 578/726/679 577/711/678 579/727/680 +f 580/728/681 579/727/680 581/729/682 +f 582/730/683 581/729/682 583/731/684 +f 586/733/687 584/732/685 583/731/684 +f 588/735/689 586/733/687 585/734/686 +f 589/737/690 588/735/689 587/736/688 +f 589/738/690 592/799/693 590/739/691 +f 588/740/689 590/739/691 593/741/694 +f 590/743/691 591/747/692 594/744/695 +f 592/746/693 621/800/722 591/747/692 +f 593/745/694 594/744/695 596/748/697 +f 593/741/694 595/753/696 584/750/685 +f 597/751/698 595/749/696 596/748/697 +f 595/753/696 597/757/698 582/754/683 +f 599/755/700 597/751/698 598/752/699 +f 597/757/698 599/761/700 580/758/681 +f 601/759/702 599/755/700 600/756/701 +f 599/761/700 601/765/702 578/762/679 +f 603/763/704 601/759/702 602/760/703 +f 601/765/702 603/769/704 576/766/677 +f 603/763/704 604/764/705 606/767/707 +f 603/769/704 605/773/706 574/770/675 +f 605/768/706 606/767/707 608/771/709 +f 605/773/706 607/777/708 572/774/673 +f 607/772/708 608/771/709 610/775/711 +f 607/777/708 609/781/710 570/778/671 +f 609/776/710 610/775/711 612/779/713 +f 609/781/710 611/801/712 568/782/669 +f 613/783/714 611/780/712 612/779/713 +f 568/782/669 611/801/712 613/785/714 +f 615/787/716 613/783/714 614/784/715 +f 566/786/667 613/785/714 615/789/716 +f 617/791/718 615/787/716 616/788/717 +f 564/790/665 615/789/716 617/793/718 +f 619/795/720 617/791/718 618/792/719 +f 617/793/718 619/802/720 559/797/660 +f 559/798/660 619/803/720 592/799/693 +f 619/795/720 620/796/721 621/800/722 +f 591/747/692 621/800/722 620/796/721 +f 620/796/721 618/792/719 616/788/717 +f 616/788/717 614/784/715 612/779/713 +f 612/779/713 610/775/711 608/771/709 +f 608/771/709 606/767/707 604/764/705 +f 604/764/705 602/760/703 600/756/701 +f 600/756/701 598/752/699 596/748/697 +f 596/748/697 594/744/695 591/747/692 +f 591/747/692 620/796/721 616/788/717 +f 616/788/717 612/779/713 608/771/709 +f 608/771/709 604/764/705 600/756/701 +f 600/756/701 596/748/697 591/747/692 +f 591/747/692 616/788/717 608/771/709 +o Cube.012 +v -0.041993 0.268745 -0.125814 +v -0.041993 0.272597 -0.130112 +v -0.028981 0.268745 -0.123226 +v -0.055004 0.268745 -0.123226 +v -0.056649 0.272597 -0.127197 +v -0.066035 0.268745 -0.115855 +v -0.069074 0.272597 -0.118895 +v -0.073406 0.268745 -0.104825 +v -0.077377 0.272597 -0.106469 +v -0.075994 0.268745 -0.091813 +v -0.080292 0.272597 -0.091813 +v -0.073406 0.268745 -0.078801 +v -0.077377 0.272597 -0.077156 +v -0.066035 0.268745 -0.067771 +v -0.069074 0.272597 -0.064731 +v -0.055004 0.268745 -0.060400 +v -0.056649 0.272597 -0.056429 +v -0.041993 0.268745 -0.057812 +v -0.041993 0.272597 -0.053514 +v -0.028981 0.268745 -0.060400 +v -0.027336 0.272597 -0.056429 +v -0.017950 0.268745 -0.067771 +v -0.014911 0.272597 -0.064731 +v -0.010580 0.268745 -0.078801 +v -0.006609 0.272597 -0.077156 +v -0.007992 0.268745 -0.091813 +v -0.003694 0.272597 -0.091813 +v -0.010580 0.268745 -0.104825 +v -0.006609 0.272597 -0.106469 +v -0.017950 0.268745 -0.115855 +v -0.014911 0.272597 -0.118895 +v -0.027336 0.272597 -0.127197 +v -0.014911 0.510706 -0.118895 +v -0.018743 0.515562 -0.115063 +v -0.027336 0.510706 -0.127197 +v -0.006609 0.510706 -0.106469 +v -0.011615 0.515562 -0.104396 +v -0.003694 0.510706 -0.091813 +v -0.009113 0.515562 -0.091813 +v -0.006609 0.510706 -0.077156 +v -0.011615 0.515562 -0.079230 +v -0.014911 0.510706 -0.064731 +v -0.018743 0.515562 -0.068563 +v -0.027336 0.510706 -0.056429 +v -0.029410 0.515562 -0.061436 +v -0.041993 0.510706 -0.053514 +v -0.041993 0.515562 -0.058933 +v -0.056649 0.510706 -0.056429 +v -0.054576 0.515562 -0.061436 +v -0.069074 0.510706 -0.064731 +v -0.065243 0.515562 -0.068563 +v -0.077377 0.510706 -0.077156 +v -0.072370 0.515562 -0.079230 +v -0.080292 0.510706 -0.091813 +v -0.074873 0.515562 -0.091813 +v -0.077377 0.510706 -0.106469 +v -0.072370 0.515562 -0.104396 +v -0.069074 0.510706 -0.118895 +v -0.065243 0.515562 -0.115063 +v -0.056649 0.510706 -0.127197 +v -0.054576 0.515562 -0.122190 +v -0.041993 0.510706 -0.130112 +v -0.041993 0.515562 -0.124693 +v -0.029410 0.515562 -0.122190 +vn -0.0000 -0.9294 -0.3691 +vn -0.0000 -0.4021 -0.9156 +vn 0.1164 -0.9269 -0.3569 +vn -0.1164 -0.9269 -0.3569 +vn -0.3894 -0.3940 -0.8326 +vn -0.2524 -0.9177 -0.3067 +vn -0.7013 -0.3568 -0.6171 +vn -0.4028 -0.8932 -0.1999 +vn -0.9145 -0.2606 -0.3094 +vn -0.5151 -0.8571 -0.0000 +vn -0.9831 -0.1831 -0.0000 +vn -0.4028 -0.8932 0.1999 +vn -0.9145 -0.2606 0.3094 +vn -0.2524 -0.9177 0.3067 +vn -0.7013 -0.3568 0.6171 +vn -0.1164 -0.9269 0.3569 +vn -0.3894 -0.3940 0.8326 +vn -0.0000 -0.9294 0.3691 +vn -0.0000 -0.4021 0.9156 +vn 0.1164 -0.9269 0.3569 +vn 0.3894 -0.3940 0.8326 +vn 0.2524 -0.9177 0.3067 +vn 0.7013 -0.3568 0.6171 +vn 0.4028 -0.8932 0.1999 +vn 0.9145 -0.2606 0.3094 +vn 0.5151 -0.8571 -0.0000 +vn 0.9831 -0.1831 -0.0000 +vn 0.4028 -0.8932 -0.1999 +vn 0.9145 -0.2606 -0.3094 +vn 0.2524 -0.9177 -0.3067 +vn 0.7013 -0.3568 -0.6171 +vn 0.3894 -0.3940 -0.8326 +vn 0.7013 0.3568 -0.6171 +vn 0.2524 0.9177 -0.3067 +vn 0.3894 0.3940 -0.8326 +vn 0.9145 0.2606 -0.3094 +vn 0.4028 0.8932 -0.1999 +vn 0.9831 0.1831 -0.0000 +vn 0.5152 0.8571 -0.0000 +vn 0.9145 0.2606 0.3094 +vn 0.4028 0.8932 0.1999 +vn 0.7013 0.3568 0.6171 +vn 0.2524 0.9177 0.3067 +vn 0.3894 0.3940 0.8326 +vn 0.1164 0.9269 0.3569 +vn -0.0000 0.4021 0.9156 +vn -0.0000 0.9294 0.3691 +vn -0.3894 0.3940 0.8326 +vn -0.1164 0.9269 0.3569 +vn -0.7013 0.3568 0.6171 +vn -0.2524 0.9177 0.3067 +vn -0.9145 0.2606 0.3094 +vn -0.4028 0.8932 0.1999 +vn -0.9831 0.1831 -0.0000 +vn -0.5152 0.8571 -0.0000 +vn -0.9145 0.2606 -0.3094 +vn -0.4028 0.8932 -0.1999 +vn -0.7013 0.3568 -0.6171 +vn -0.2524 0.9177 -0.3067 +vn -0.3894 0.3940 -0.8326 +vn -0.1164 0.9269 -0.3569 +vn -0.0000 0.4021 -0.9156 +vn -0.0000 0.9294 -0.3691 +vn 0.1164 0.9269 -0.3569 +vt 0.750000 0.490000 +vt 0.668463 0.446847 +vt 0.658156 0.471731 +vt 0.831537 0.446847 +vt 0.750000 0.463065 +vt 0.831537 0.053153 +vt 0.553153 0.168463 +vt 0.599340 0.400660 +vt 0.580294 0.419706 +vt 0.553153 0.331537 +vt 0.528269 0.341844 +vt 0.536935 0.250000 +vt 0.510000 0.250000 +vt 0.528269 0.158156 +vt 0.580294 0.080294 +vt 0.599340 0.099340 +vt 0.658156 0.028269 +vt 0.668463 0.053153 +vt 0.750000 0.010000 +vt 0.750000 0.036935 +vt 0.841844 0.028269 +vt 0.900660 0.099340 +vt 0.919706 0.080294 +vt 0.946847 0.168463 +vt 0.971731 0.158156 +vt 0.963065 0.250000 +vt 0.990000 0.250000 +vt 0.971731 0.341844 +vt 0.946847 0.331537 +vt 0.919706 0.419706 +vt 0.900660 0.400660 +vt 0.841844 0.471731 +vt 0.937500 0.507803 +vt 0.875000 0.990163 +vt 0.875000 0.507803 +vt 0.812500 0.990163 +vt 0.812500 0.507803 +vt 0.419706 0.419706 +vt 0.440358 0.328849 +vt 0.471731 0.341844 +vt 0.341844 0.471731 +vt 0.395694 0.395694 +vt 0.456042 0.250000 +vt 0.490000 0.250000 +vt 0.750000 0.990163 +vt 0.750000 0.507803 +vt 0.471731 0.158156 +vt 0.440358 0.171151 +vt 0.687500 0.507803 +vt 0.419706 0.080294 +vt 0.395694 0.104306 +vt 0.687500 0.990163 +vt 0.625000 0.507803 +vt 0.341844 0.028269 +vt 0.328849 0.059642 +vt 0.625000 0.990163 +vt 0.562500 0.507803 +vt 0.250000 0.010000 +vt 0.250000 0.043958 +vt 0.562500 0.990163 +vt 0.500000 0.507803 +vt 0.171151 0.059642 +vt 0.158156 0.028269 +vt 0.500000 0.990163 +vt 0.437500 0.507803 +vt 0.104306 0.104306 +vt 0.080294 0.080294 +vt 0.437500 0.990163 +vt 0.375000 0.507803 +vt 0.059642 0.171151 +vt 0.028269 0.158156 +vt 0.312500 0.990163 +vt 0.312500 0.507803 +vt 0.043958 0.250000 +vt 0.010000 0.250000 +vt 0.250000 0.507803 +vt 0.028269 0.341844 +vt 0.059642 0.328849 +vt 0.250000 0.990163 +vt 0.187500 0.507803 +vt 0.080294 0.419706 +vt 0.104306 0.395694 +vt 0.125000 0.990163 +vt 0.125000 0.507803 +vt 0.158156 0.471731 +vt 0.171151 0.440358 +vt 0.062500 0.990163 +vt 0.062500 0.507803 +vt 0.250000 0.490000 +vt 0.250000 0.456042 +vt 0.000000 0.990163 +vt 0.000000 0.507803 +vt 1.000000 0.507803 +vt 0.937500 0.990163 +vt 0.328849 0.440358 +vt 0.375000 0.990163 +vt 0.187500 0.990163 +vt 1.000000 0.990163 +s 1 +usemtl Cherry_Red_Scratched_Painted_Steel +f 623/804/724 625/805/726 626/806/727 +f 623/804/724 624/807/725 622/808/723 +f 641/809/742 633/810/734 625/805/726 +f 626/806/727 627/811/728 628/812/729 +f 628/812/729 629/813/730 630/814/731 +f 630/814/731 631/815/732 632/816/733 +f 634/817/735 631/815/732 633/810/734 +f 636/818/737 633/810/734 635/819/736 +f 638/820/739 635/819/736 637/821/738 +f 640/822/741 637/821/738 639/823/740 +f 640/822/741 641/809/742 642/824/743 +f 642/824/743 643/825/744 644/826/745 +f 644/826/745 645/827/746 646/828/747 +f 646/828/747 647/829/748 648/830/749 +f 650/831/751 647/829/748 649/832/750 +f 652/833/753 649/832/750 651/834/752 +f 653/835/754 651/834/752 624/807/725 +f 653/836/754 654/837/755 652/838/753 +f 652/838/753 657/839/758 650/840/751 +f 654/841/755 658/842/759 657/843/758 +f 656/844/757 655/845/756 654/841/755 +f 657/843/758 660/846/761 659/847/760 +f 650/840/751 659/848/760 648/849/749 +f 661/850/762 660/846/761 662/851/763 +f 659/848/760 646/852/747 648/849/749 +f 663/853/764 662/851/763 664/854/765 +f 661/855/762 644/856/745 646/852/747 +f 665/857/766 664/854/765 666/858/767 +f 663/859/764 642/860/743 644/856/745 +f 667/861/768 666/858/767 668/862/769 +f 665/863/766 640/864/741 642/860/743 +f 667/861/768 670/865/771 669/866/770 +f 667/867/768 638/868/739 640/864/741 +f 669/866/770 672/869/773 671/870/772 +f 669/871/770 636/872/737 638/868/739 +f 671/870/772 674/873/775 673/874/774 +f 636/872/737 673/875/774 634/876/735 +f 673/874/774 676/877/777 675/878/776 +f 673/875/774 632/879/733 634/876/735 +f 677/880/778 676/877/777 678/881/779 +f 675/882/776 630/883/731 632/879/733 +f 679/884/780 678/881/779 680/885/781 +f 630/883/731 679/886/780 628/887/729 +f 681/888/782 680/885/781 682/889/783 +f 628/887/729 681/890/782 626/891/727 +f 683/892/784 682/889/783 684/893/785 +f 626/891/727 683/894/784 623/895/724 +f 623/896/724 656/897/757 653/836/754 +f 683/892/784 685/898/786 656/844/757 +f 672/869/773 664/854/765 655/845/756 +f 623/804/724 622/808/723 625/805/726 +f 623/804/724 653/835/754 624/807/725 +f 625/805/726 622/808/723 624/807/725 +f 624/807/725 651/834/752 649/832/750 +f 649/832/750 647/829/748 645/827/746 +f 645/827/746 643/825/744 641/809/742 +f 641/809/742 639/823/740 637/821/738 +f 637/821/738 635/819/736 633/810/734 +f 633/810/734 631/815/732 629/813/730 +f 629/813/730 627/811/728 625/805/726 +f 625/805/726 624/807/725 649/832/750 +f 649/832/750 645/827/746 641/809/742 +f 641/809/742 637/821/738 633/810/734 +f 633/810/734 629/813/730 625/805/726 +f 625/805/726 649/832/750 641/809/742 +f 626/806/727 625/805/726 627/811/728 +f 628/812/729 627/811/728 629/813/730 +f 630/814/731 629/813/730 631/815/732 +f 634/817/735 632/816/733 631/815/732 +f 636/818/737 634/817/735 633/810/734 +f 638/820/739 636/818/737 635/819/736 +f 640/822/741 638/820/739 637/821/738 +f 640/822/741 639/823/740 641/809/742 +f 642/824/743 641/809/742 643/825/744 +f 644/826/745 643/825/744 645/827/746 +f 646/828/747 645/827/746 647/829/748 +f 650/831/751 648/830/749 647/829/748 +f 652/833/753 650/831/751 649/832/750 +f 653/835/754 652/833/753 651/834/752 +f 653/836/754 656/897/757 654/837/755 +f 652/838/753 654/837/755 657/839/758 +f 654/841/755 655/845/756 658/842/759 +f 656/844/757 685/898/786 655/845/756 +f 657/843/758 658/842/759 660/846/761 +f 650/840/751 657/839/758 659/848/760 +f 661/850/762 659/847/760 660/846/761 +f 659/848/760 661/855/762 646/852/747 +f 663/853/764 661/850/762 662/851/763 +f 661/855/762 663/859/764 644/856/745 +f 665/857/766 663/853/764 664/854/765 +f 663/859/764 665/863/766 642/860/743 +f 667/861/768 665/857/766 666/858/767 +f 665/863/766 667/867/768 640/864/741 +f 667/861/768 668/862/769 670/865/771 +f 667/867/768 669/871/770 638/868/739 +f 669/866/770 670/865/771 672/869/773 +f 669/871/770 671/899/772 636/872/737 +f 671/870/772 672/869/773 674/873/775 +f 636/872/737 671/899/772 673/875/774 +f 673/874/774 674/873/775 676/877/777 +f 673/875/774 675/882/776 632/879/733 +f 677/880/778 675/878/776 676/877/777 +f 675/882/776 677/900/778 630/883/731 +f 679/884/780 677/880/778 678/881/779 +f 630/883/731 677/900/778 679/886/780 +f 681/888/782 679/884/780 680/885/781 +f 628/887/729 679/886/780 681/890/782 +f 683/892/784 681/888/782 682/889/783 +f 626/891/727 681/890/782 683/894/784 +f 623/896/724 683/901/784 656/897/757 +f 683/892/784 684/893/785 685/898/786 +f 655/845/756 685/898/786 684/893/785 +f 684/893/785 682/889/783 680/885/781 +f 680/885/781 678/881/779 676/877/777 +f 676/877/777 674/873/775 672/869/773 +f 672/869/773 670/865/771 668/862/769 +f 668/862/769 666/858/767 664/854/765 +f 664/854/765 662/851/763 660/846/761 +f 660/846/761 658/842/759 655/845/756 +f 655/845/756 684/893/785 680/885/781 +f 680/885/781 676/877/777 672/869/773 +f 672/869/773 668/862/769 664/854/765 +f 664/854/765 660/846/761 655/845/756 +f 655/845/756 680/885/781 672/869/773 +o Cube.013 +v 0.034762 0.270456 0.148590 +v 0.034762 0.270456 0.138299 +v 0.000000 0.270456 0.148590 +v 0.034762 0.270456 0.148590 +v 0.005201 0.307279 0.206004 +v 0.015518 0.307344 0.184305 +v 0.000000 0.307279 0.206004 +v 0.015590 0.412104 0.206004 +v 0.037029 0.412104 0.209149 +v 0.000000 0.412104 0.206004 +v 0.030871 0.412170 0.184305 +v 0.030769 0.412236 0.168046 +v 0.037029 0.412104 0.187285 +v 0.037029 0.412104 0.171015 +v 0.037029 0.430353 0.178406 +v 0.037029 0.430353 0.209149 +v 0.037029 0.430353 0.155529 +v 0.037029 0.444250 0.181941 +v 0.037029 0.444250 0.209149 +v 0.037029 0.444250 0.161695 +v 0.037029 0.460359 0.181883 +v 0.037029 0.460263 0.209149 +v 0.037029 0.460430 0.161593 +v 0.036707 0.474259 0.186464 +v 0.037029 0.474259 0.209149 +v 0.036467 0.474259 0.169584 +v 0.037029 0.491055 0.178915 +v 0.037029 0.491055 0.209149 +v 0.037029 0.491055 0.156417 +v 0.037029 0.517217 0.187285 +v 0.037029 0.517217 0.209149 +v 0.037029 0.517217 0.171015 +v 0.037029 0.517217 0.132880 +v 0.038376 0.517217 0.094746 +v 0.037029 0.491055 0.147478 +v 0.038376 0.491055 0.094746 +v 0.036467 0.474259 0.134311 +v 0.037828 0.491033 0.147478 +v 0.037828 0.491033 0.156417 +v 0.037267 0.474237 0.134311 +v 0.037616 0.488800 0.148512 +v 0.037616 0.488800 0.155383 +v 0.037683 0.474438 0.136737 +v 0.032953 0.488832 0.148530 +v 0.032676 0.475559 0.136699 +v 0.032953 0.488832 0.155365 +v 0.033192 0.460810 0.151947 +v 0.033257 0.446828 0.144649 +v 0.033740 0.460430 0.144533 +v 0.033334 0.432402 0.149734 +v 0.033740 0.460430 0.159362 +v 0.033257 0.446828 0.159246 +v 0.032676 0.475559 0.167196 +v 0.033334 0.432402 0.154161 +v 0.037993 0.432379 0.154161 +v 0.037993 0.432379 0.149734 +v 0.038010 0.444853 0.159312 +v 0.037828 0.430330 0.155529 +v 0.037828 0.430330 0.148366 +v 0.037828 0.444228 0.161695 +v 0.037828 0.460407 0.161593 +v 0.037267 0.474237 0.169584 +v 0.038068 0.460407 0.159164 +v 0.037683 0.474438 0.167158 +v 0.037029 0.430353 0.148366 +v 0.037828 0.444228 0.142200 +v 0.037029 0.444250 0.142200 +v 0.037828 0.460407 0.142302 +v 0.038010 0.444853 0.144583 +v 0.038068 0.460407 0.144731 +v 0.037029 0.460430 0.142302 +v 0.038376 0.460263 0.094746 +v 0.038376 0.444250 0.094746 +v 0.000000 0.456638 0.094746 +v 0.038376 0.474259 0.094746 +v 0.000000 0.472336 0.094746 +v 0.000000 0.491055 0.094746 +v -0.038376 0.474259 0.094746 +v -0.038376 0.491056 0.094746 +v -0.038376 0.460263 0.094746 +v -0.036467 0.474259 0.134311 +v -0.037029 0.491056 0.147478 +v -0.037029 0.460430 0.142302 +v -0.037267 0.474237 0.134311 +v -0.037828 0.491033 0.147478 +v -0.037828 0.460407 0.142302 +v -0.037683 0.474438 0.136737 +v -0.037616 0.488800 0.148512 +v -0.038068 0.460407 0.144731 +v -0.032676 0.475559 0.136699 +v -0.033192 0.460810 0.151947 +v -0.033740 0.460430 0.144533 +v -0.032953 0.488832 0.148530 +v -0.032953 0.488832 0.155365 +v -0.032676 0.475559 0.167196 +v -0.037616 0.488800 0.155383 +v -0.037828 0.491033 0.156417 +v -0.037683 0.474438 0.167158 +v -0.037267 0.474237 0.169584 +v -0.038068 0.460407 0.159164 +v -0.033740 0.460430 0.159362 +v -0.038010 0.444853 0.159312 +v -0.037828 0.460407 0.161593 +v -0.037029 0.460430 0.161593 +v -0.037828 0.444228 0.161695 +v -0.037828 0.430330 0.155529 +v -0.037029 0.444250 0.161695 +v -0.037029 0.430353 0.155529 +v -0.037029 0.444250 0.181941 +v -0.037029 0.444250 0.209149 +v -0.037029 0.430353 0.178406 +v -0.037029 0.460359 0.181883 +v -0.037029 0.460263 0.209149 +v -0.036707 0.474259 0.186464 +v -0.037029 0.474259 0.209149 +v -0.036467 0.474259 0.169584 +v -0.037029 0.491056 0.178915 +v -0.037029 0.491056 0.209149 +v -0.037029 0.491056 0.156417 +v -0.037029 0.517217 0.187285 +v -0.037029 0.517217 0.209149 +v -0.037029 0.517217 0.171015 +v -0.037029 0.517217 0.132880 +v -0.038376 0.517217 0.094746 +v 0.000000 0.517217 0.094746 +v 0.000000 0.517217 0.209149 +v 0.000000 0.491055 0.209149 +v 0.000000 0.472336 0.209149 +v 0.000000 0.456638 0.209149 +v 0.000000 0.441984 0.209149 +v 0.000000 0.430353 0.209149 +v 0.000000 0.412104 0.209149 +v -0.037029 0.430353 0.209149 +v -0.037029 0.412104 0.209149 +v -0.015590 0.412104 0.206004 +v -0.037029 0.412104 0.187285 +v -0.037029 0.412104 0.171015 +v -0.030871 0.412170 0.184305 +v -0.030769 0.412236 0.168046 +v -0.015518 0.307344 0.184305 +v -0.005201 0.307279 0.206004 +v -0.035671 0.307279 0.168918 +v -0.034762 0.270456 0.138299 +v -0.030769 0.307410 0.168046 +v -0.034762 0.270456 0.148590 +v -0.037393 0.270456 0.130642 +v -0.035671 0.307279 0.131832 +v -0.031860 0.233518 0.095798 +v -0.036898 0.233518 0.095798 +v -0.034762 0.270456 0.148590 +v -0.059152 0.270456 0.094746 +v 0.000000 0.270456 0.094746 +v -0.057429 0.307279 0.094746 +v -0.059270 0.270456 0.011695 +v -0.059359 0.270456 -0.022993 +v -0.036898 0.233518 0.011695 +v 0.000000 0.270456 0.011695 +v -0.058330 0.259095 0.005689 +v -0.058399 0.259089 -0.016987 +v -0.039066 0.233782 0.005689 +v -0.039452 0.259095 0.005689 +v -0.039452 0.259089 -0.016987 +v -0.039098 0.258741 0.005335 +v -0.039098 0.233782 0.005689 +v -0.039098 0.234136 0.005689 +v -0.039098 0.233429 0.005689 +v -0.039098 0.233784 0.004803 +v -0.038744 0.212613 0.005689 +v -0.034026 0.233783 0.005689 +v -0.036395 0.212613 0.005689 +v -0.031860 0.233518 0.011695 +v -0.034762 0.200932 0.011695 +v -0.034762 0.200932 0.096725 +v 0.000000 0.200932 0.011695 +v -0.034762 0.200932 -0.022993 +v -0.034762 0.200932 -0.055703 +v -0.031860 0.233518 -0.022993 +v 0.000000 0.200932 -0.022993 +v -0.036395 0.212613 -0.016987 +v -0.034026 0.233783 -0.016987 +v -0.038744 0.212613 -0.016987 +v -0.039098 0.214056 -0.015761 +v -0.038744 0.233783 -0.016987 +v -0.039098 0.233783 -0.015761 +v -0.038744 0.233785 -0.016987 +v -0.039098 0.233785 -0.016633 +v -0.039061 0.233785 -0.016987 +v -0.036898 0.233518 -0.022993 +v -0.036898 0.233518 -0.104625 +v -0.031860 0.233518 -0.094050 +v -0.059448 0.270456 -0.127018 +v 0.000000 0.233518 -0.104625 +v 0.000000 0.270456 -0.127018 +v 0.000000 0.233518 -0.094050 +v 0.036898 0.233518 -0.104625 +v 0.031860 0.233518 -0.094050 +v 0.059448 0.270456 -0.127017 +v 0.036898 0.233518 -0.022993 +v 0.059359 0.270456 -0.022993 +v 0.031860 0.233518 -0.022993 +v 0.039061 0.233785 -0.016987 +v 0.058399 0.259089 -0.016987 +v 0.034026 0.233783 -0.016987 +v 0.038744 0.233785 -0.016987 +v 0.039098 0.233785 -0.016633 +v 0.039452 0.259089 -0.016987 +v 0.038744 0.233783 -0.016987 +v 0.039098 0.233783 -0.015761 +v 0.038744 0.212613 -0.016987 +v 0.038744 0.212613 0.005689 +v 0.039098 0.214056 -0.015761 +v 0.036395 0.212613 -0.016987 +v 0.036395 0.212613 0.005689 +v 0.034762 0.200932 -0.022993 +v 0.034762 0.200932 -0.055702 +v 0.034762 0.200932 0.011695 +v 0.034762 0.200932 0.096725 +v 0.031860 0.233518 0.011695 +v 0.031860 0.233518 0.095798 +v 0.036898 0.233518 0.011695 +v 0.034026 0.233783 0.005689 +v 0.039066 0.233782 0.005689 +v 0.039098 0.233429 0.005689 +v 0.039098 0.233782 0.005689 +v 0.039098 0.233784 0.004803 +v 0.039098 0.234136 0.005689 +v 0.039098 0.214056 0.004477 +v 0.039098 0.258741 0.005335 +v 0.039452 0.259095 0.005689 +v 0.039098 0.258736 -0.016633 +v 0.058330 0.259095 0.005689 +v 0.059270 0.270456 0.011695 +v 0.059152 0.270456 0.094746 +v 0.057429 0.307279 0.094746 +v 0.036898 0.233518 0.095798 +v 0.037393 0.270456 0.130642 +v 0.035671 0.307279 0.168918 +v 0.035671 0.307279 0.131832 +v 0.035671 0.412104 0.131832 +v 0.057429 0.390552 0.094746 +v 0.035671 0.412104 0.168918 +v 0.037029 0.412104 0.132880 +v 0.038376 0.412104 0.094746 +v 0.000000 0.412104 0.094746 +v 0.038376 0.430353 0.094746 +v 0.000000 0.430353 0.094746 +v 0.000000 0.441984 0.094746 +v -0.038376 0.430353 0.094746 +v -0.038376 0.412104 0.094746 +v -0.037029 0.430353 0.148366 +v -0.038376 0.444250 0.094746 +v -0.037029 0.444250 0.142200 +v -0.037828 0.444228 0.142200 +v -0.037828 0.430330 0.148366 +v -0.038010 0.444853 0.144583 +v -0.037993 0.432379 0.149734 +v -0.033257 0.446828 0.144649 +v -0.033334 0.432402 0.149734 +v -0.033334 0.432402 0.154161 +v -0.033257 0.446828 0.159246 +v -0.037993 0.432379 0.154161 +v -0.037029 0.412104 0.132880 +v -0.035671 0.412104 0.131832 +v -0.057429 0.390552 0.094746 +v -0.035671 0.412104 0.168918 +v 0.000000 0.412104 0.094746 +v 0.000000 0.307279 0.094746 +v 0.030769 0.307410 0.168046 +v 0.034762 0.200932 0.096725 +v 0.000000 0.200932 0.096725 +v 0.000000 0.270456 0.148590 +v 0.000000 0.200932 0.096725 +v -0.034762 0.200932 0.096725 +v 0.000000 0.200932 -0.055702 +v 0.000000 0.270456 -0.022993 +v -0.039098 0.258736 -0.016633 +v -0.039098 0.214056 0.004477 +vn 0.9017 0.0552 0.4289 +vn -0.0000 -0.8418 0.5399 +vn 1.0000 -0.0000 -0.0000 +vn 0.8996 -0.0892 0.4275 +vn -0.0000 -0.0000 1.0000 +vn 0.0004 -1.0000 -0.0027 +vn -0.0000 -1.0000 -0.0000 +vn -0.0210 -0.9998 -0.0000 +vn 0.7254 -0.1062 0.6800 +vn 0.9999 -0.0000 -0.0142 +vn 0.9995 0.0278 -0.0142 +vn 0.9996 -0.0255 -0.0142 +vn 0.9996 0.0142 0.0255 +vn 0.9982 -0.0534 0.0255 +vn 0.0282 0.9996 -0.0000 +vn 0.0173 0.6165 -0.7872 +vn 0.9955 -0.0947 -0.0000 +vn 0.9786 0.1058 -0.1767 +vn -0.0067 -1.0000 -0.0000 +vn -0.0016 -0.6654 0.7465 +vn 0.9996 0.0050 -0.0290 +vn 1.0000 0.0085 -0.0000 +vn 0.9996 0.0050 0.0290 +vn 1.0000 0.0051 -0.0008 +vn 0.9965 -0.0348 0.0754 +vn 0.9922 0.1050 0.0679 +vn 1.0000 0.0050 -0.0000 +vn 0.9922 0.1050 -0.0679 +vn 0.9965 -0.0348 -0.0754 +vn 1.0000 0.0051 0.0008 +vn 0.1499 0.3294 -0.9322 +vn 0.0048 1.0000 -0.0000 +vn 0.9968 -0.0802 -0.0000 +vn 0.9972 -0.0295 0.0682 +vn -0.0281 -0.9996 -0.0000 +vn -0.0114 -0.4055 0.9140 +vn 0.0002 0.0063 1.0000 +vn 0.9951 -0.0028 0.0983 +vn -0.0140 -0.5007 0.8655 +vn 0.9848 -0.0550 0.1645 +vn 0.0971 0.4630 -0.8810 +vn 0.0171 0.0079 -0.9998 +vn -0.0016 -0.6654 -0.7465 +vn 0.9953 -0.0588 -0.0774 +vn 0.0174 0.6165 0.7872 +vn -0.0114 -0.4055 -0.9140 +vn 0.9969 -0.0320 -0.0721 +vn 0.0002 0.0063 -1.0000 +vn 0.9971 0.0005 -0.0760 +vn 0.0171 0.0079 0.9998 +vn 0.1499 0.3294 0.9322 +vn 0.0971 0.4630 0.8810 +vn 0.9947 -0.0287 -0.0983 +vn -0.0141 -0.5007 -0.8655 +vn 0.9980 0.0567 0.0281 +vn 0.9996 -0.0002 0.0283 +vn -0.0000 -0.0000 -1.0000 +vn -0.9988 -0.0000 0.0482 +vn -0.9980 0.0567 0.0281 +vn -0.0173 0.6165 -0.7872 +vn 0.0140 -0.5007 -0.8655 +vn -0.9786 0.1058 -0.1767 +vn -0.9848 -0.0550 -0.1645 +vn 0.1462 -0.6276 0.7647 +vn 0.0372 0.4939 0.8687 +vn -0.9996 0.0050 -0.0290 +vn -0.9922 0.1050 0.0679 +vn 0.0067 -1.0000 -0.0000 +vn -1.0000 0.0085 -0.0000 +vn -0.9996 0.0050 0.0290 +vn 0.0016 -0.6654 -0.7465 +vn -0.9955 -0.0947 -0.0000 +vn -0.9786 0.1058 0.1767 +vn -0.0971 0.4630 -0.8810 +vn -0.9848 -0.0550 0.1645 +vn 0.0457 -0.0094 -0.9989 +vn -0.9971 0.0005 0.0760 +vn -0.0002 0.0063 1.0000 +vn 0.0140 -0.5007 0.8655 +vn -0.9969 -0.0320 0.0721 +vn 0.0114 -0.4055 0.9140 +vn -1.0000 -0.0000 -0.0000 +vn -0.9997 0.0231 0.0001 +vn -0.9992 0.0405 0.0001 +vn -0.9999 -0.0000 -0.0142 +vn -0.9996 -0.0255 -0.0142 +vn -0.9996 0.0142 0.0255 +vn -0.0004 -1.0000 -0.0027 +vn 0.0272 -0.9996 0.0020 +vn -0.8120 -0.1189 0.5714 +vn -0.7254 -0.1062 0.6800 +vn -0.8866 0.4625 -0.0000 +vn -0.0224 0.9994 0.0250 +vn -0.9074 -0.2817 0.3118 +vn 0.1751 -0.0000 0.9845 +vn -0.9989 0.0467 -0.0000 +vn -0.8623 0.0240 0.5059 +vn -0.9899 0.0849 -0.1138 +vn -0.0000 -0.6862 0.7274 +vn -0.7647 -0.4475 0.4636 +vn -0.0000 1.0000 -0.0000 +vn -0.8553 -0.5181 0.0012 +vn -0.9965 -0.0841 0.0031 +vn -0.5569 -0.4238 0.7144 +vn -0.0000 -1.0000 0.0002 +vn -0.0000 0.0001 1.0000 +vn -0.7071 -0.7071 0.0002 +vn -0.0000 -0.0001 1.0000 +vn -0.9649 -0.0164 0.2622 +vn 0.0003 -0.9990 -0.0440 +vn -0.9341 0.1045 0.3414 +vn -0.9961 0.0887 -0.0000 +vn -0.9904 -0.1384 -0.0000 +vn -0.9341 0.1045 -0.3414 +vn -0.9712 -0.2382 -0.0000 +vn -0.9608 -0.0000 -0.2773 +vn -0.0057 -1.0000 -0.0016 +vn -0.0000 -0.0931 0.9957 +vn -0.7071 -0.0000 -0.7071 +vn -0.5557 -0.4246 -0.7148 +vn -0.0003 -0.9990 0.0443 +vn -0.8537 -0.5207 0.0007 +vn -0.0000 -0.5184 -0.8551 +vn 0.8544 -0.5196 -0.0000 +vn 0.5557 -0.4246 -0.7148 +vn 0.0003 -0.9990 0.0443 +vn 0.0015 -1.0000 -0.0016 +vn 0.7169 -0.0201 0.6969 +vn 0.9608 -0.0000 -0.2773 +vn 0.9712 -0.2382 -0.0000 +vn 0.9904 -0.1384 -0.0000 +vn 0.9341 0.1045 -0.3414 +vn 0.9961 0.0887 -0.0000 +vn 0.9106 0.0811 0.4053 +vn -0.0000 -0.9990 -0.0442 +vn 0.7121 -0.0101 -0.7020 +vn 0.7071 -0.7072 0.0002 +vn 0.9965 -0.0841 0.0031 +vn 0.8224 -0.4981 0.2750 +vn 0.8566 -0.5160 -0.0000 +vn 0.8545 0.0400 0.5179 +vn 0.7647 -0.4475 0.4636 +vn 0.9989 0.0467 -0.0000 +vn 0.5014 -0.5605 0.6591 +vn 0.9899 0.0849 -0.1138 +vn 0.8625 -0.0000 0.5060 +vn 0.7481 0.6614 0.0546 +vn 0.9995 -0.0213 0.0251 +vn 0.9996 0.0111 0.0251 +vn -0.9994 -0.0000 0.0353 +vn -0.9996 0.0111 0.0251 +vn -0.9996 -0.0000 0.0284 +vn -0.0002 0.0063 -1.0000 +vn 0.0114 -0.4055 -0.9140 +vn -0.9971 0.0005 -0.0760 +vn -0.9969 -0.0320 -0.0721 +vn -0.0171 0.0079 0.9998 +vn -0.0018 0.3817 0.9243 +vn -1.0000 0.0051 -0.0008 +vn -0.9965 -0.0348 0.0754 +vn -1.0000 0.0050 -0.0000 +vn -0.0048 1.0000 -0.0000 +vn -1.0000 0.0051 0.0008 +vn -0.1499 0.3294 -0.9322 +vn -0.9968 -0.0802 -0.0000 +vn -0.9965 -0.0348 -0.0754 +vn 0.0281 -0.9996 -0.0000 +vn -0.7481 0.6614 0.0546 +vn -0.8625 -0.0000 0.5060 +vn -0.1751 -0.0000 0.9845 +vn 0.0224 0.9994 0.0250 +vn -0.0000 -0.5979 0.8015 +vn -0.0000 -0.7620 -0.6475 +vn -0.0282 0.9996 -0.0000 +vn -0.0173 0.6165 0.7872 +vn -0.9922 0.1050 -0.0679 +vn 0.8866 0.4625 -0.0000 +vn 0.8120 -0.1189 0.5714 +vn -0.0107 -0.9999 -0.0000 +vn -0.0088 -1.0000 -0.0040 +vn -0.0303 -0.9993 0.0196 +vn 1.0000 -0.0000 -0.0062 +vn 0.9997 0.0231 0.0001 +vn 0.9992 0.0405 0.0001 +vn 0.9998 -0.0192 -0.0000 +vn 0.9994 -0.0334 -0.0000 +vn 0.9994 -0.0000 0.0353 +vn 0.9988 -0.0000 0.0482 +vn 0.0174 0.6165 -0.7872 +vn 0.9953 -0.0588 0.0774 +vn -0.1462 -0.6276 0.7647 +vn 0.0018 0.3817 -0.9243 +vn 0.9969 -0.0320 0.0721 +vn 0.9971 0.0005 0.0760 +vn -0.0141 -0.5007 0.8655 +vn 0.9947 -0.0287 0.0983 +vn -0.0372 0.4939 -0.8687 +vn -0.0457 -0.0094 -0.9989 +vn -0.1462 -0.6276 -0.7647 +vn 0.9786 0.1058 0.1767 +vn 0.0173 0.6165 0.7872 +vn 0.9972 -0.0295 -0.0682 +vn 0.9951 -0.0028 -0.0983 +vn -0.0457 -0.0094 0.9989 +vn 0.0018 0.3817 0.9243 +vn -0.0371 0.4939 0.8687 +vn 0.9848 -0.0550 -0.1645 +vn -0.0140 -0.5007 -0.8655 +vn 0.9996 -0.0000 0.0284 +vn -0.9982 -0.0534 0.0255 +vn -0.0174 0.6165 -0.7872 +vn 0.0141 -0.5007 -0.8655 +vn -0.9953 -0.0588 0.0774 +vn -0.9947 -0.0287 -0.0983 +vn 0.0016 -0.6654 0.7465 +vn -0.0971 0.4630 0.8810 +vn 0.1462 -0.6276 -0.7647 +vn -0.9953 -0.0588 -0.0774 +vn 0.0372 0.4939 -0.8687 +vn -0.9947 -0.0287 0.0983 +vn -0.0171 0.0079 -0.9998 +vn -0.9951 -0.0028 0.0983 +vn 0.0141 -0.5007 0.8655 +vn -0.9972 -0.0295 0.0682 +vn -0.9995 0.0278 -0.0142 +vn -0.9998 -0.0192 -0.0000 +vn -0.9994 -0.0334 -0.0000 +vn 0.0107 -0.9999 -0.0000 +vn 0.0088 -1.0000 -0.0040 +vn -0.8996 -0.0892 0.4275 +vn -1.0000 -0.0000 -0.0062 +vn -0.9017 0.0552 0.4289 +vn -0.5014 -0.5605 0.6591 +vn 0.1752 -0.0000 0.9845 +vn -0.8545 0.0400 0.5179 +vn -0.9515 -0.2741 0.1395 +vn -0.8566 -0.5160 -0.0000 +vn -0.9966 -0.0828 0.0026 +vn -0.8224 -0.4981 0.2750 +vn -0.7071 -0.7072 0.0002 +vn -0.7121 -0.0101 -0.7020 +vn -0.9106 0.0811 0.4053 +vn -0.9106 0.0811 -0.4053 +vn -0.7057 -0.0000 -0.7085 +vn -0.7169 -0.0201 0.6969 +vn -0.8218 -0.4997 -0.2737 +vn -0.0000 -0.9990 0.0442 +vn -0.8544 -0.5196 -0.0000 +vn 0.8537 -0.5207 0.0007 +vn 0.8218 -0.4997 -0.2737 +vn -0.0000 -0.0467 0.9989 +vn 0.9630 -0.0000 -0.2696 +vn 0.7071 -0.0000 -0.7071 +vn 0.9106 0.0811 -0.4053 +vn 0.9341 0.1045 0.3414 +vn -0.0003 -0.9990 -0.0440 +vn 0.9649 -0.0164 0.2622 +vn 0.7071 -0.7071 0.0002 +vn 0.9966 -0.0828 0.0026 +vn 0.5569 -0.4238 0.7144 +vn 0.8553 -0.5181 0.0012 +vn 0.8623 0.0240 0.5059 +vn 0.9074 -0.2817 0.3118 +vn 0.9515 -0.2741 0.1395 +vn -0.9995 -0.0213 0.0251 +vn -0.9996 -0.0002 0.0283 +vn -0.9951 -0.0028 -0.0983 +vn -0.9972 -0.0295 -0.0682 +vn 0.0457 -0.0094 0.9989 +vn -0.1499 0.3294 0.9322 +vn -0.0018 0.3817 -0.9243 +vn -0.0174 0.6165 0.7872 +vt -0.075461 -3.073388 +vt -1.115436 -2.014103 +vt -1.727124 -2.014102 +vt -0.348835 -0.075461 +vt 0.651165 -1.727124 +vt -0.348835 -1.727124 +vt 0.651165 -0.075461 +vt -1.727124 0.677011 +vt 0.651165 -2.014102 +vt -0.348835 0.677011 +vt -0.348835 -2.014102 +vt 0.651165 -1.115436 +vt 0.751427 -1.817582 +vt -0.348835 -1.817582 +vt 0.651165 -0.660256 +vt 0.751427 -0.720562 +vt 0.751427 -1.188606 +vt -0.660256 -2.014102 +vt -1.115436 0.677011 +vt -1.188606 0.677011 +vt -1.817582 1.201967 +vt -1.817582 0.677011 +vt -0.720562 0.677011 +vt -0.933193 1.201967 +vt -1.034887 1.611333 +vt -1.817582 1.536579 +vt -0.452454 1.666962 +vt -1.817582 1.958113 +vt -1.033208 2.067708 +vt -1.165011 2.473156 +vt -1.817582 2.409707 +vt -0.679409 2.520372 +vt -1.817582 2.948223 +vt -0.947834 2.948223 +vt -1.188606 4.025256 +vt -1.817582 4.025256 +vt -0.720562 4.025256 +vt -0.300623 2.948223 +vt 0.376458 4.025256 +vt 1.473479 2.948223 +vt -0.043481 2.948223 +vt 0.335306 2.520372 +vt 0.751427 -0.043481 +vt 0.640409 -0.300623 +vt 0.640409 -0.043481 +vt 0.624255 2.520372 +vt 0.751427 2.948223 +vt 0.640409 2.948223 +vt 0.525442 0.827867 +vt 0.258549 0.999927 +vt 0.333102 0.500457 +vt 0.140956 0.967478 +vt 0.000072 0.682895 +vt 0.506366 0.021092 +vt 0.525442 0.293697 +vt 0.463333 0.529057 +vt 0.430194 0.000073 +vt 0.206633 0.458221 +vt 0.274014 0.224317 +vt 0.751427 1.666962 +vt 0.640409 1.201967 +vt 0.640409 1.666962 +vt 0.751427 -0.275088 +vt 0.640409 -0.069017 +vt 0.640409 -0.275088 +vt -0.069017 1.201967 +vt -0.275088 1.201967 +vt -0.449526 2.149261 +vt 0.735272 2.520372 +vt 0.640409 2.149261 +vt 0.108349 1.666962 +vt 0.105422 2.149261 +vt 1.473479 1.958113 +vt 0.751427 1.536579 +vt -0.348835 1.958113 +vt 0.751427 1.958113 +vt -0.348835 2.409707 +vt 0.751427 2.409707 +vt -0.348835 2.948223 +vt 1.473479 2.409707 +vt 0.751427 2.149261 +vt 0.751427 4.025256 +vt -0.348835 4.025256 +vt -0.348835 1.536579 +vt 0.751427 1.201967 +vt -0.348835 1.201967 +vt 0.751427 0.677011 +vt 0.220567 -3.073388 +vt 0.440852 -3.073388 +vt -0.660256 0.677011 +vt 0.406611 -2.014102 +vt 1.473479 -2.014102 +vt 0.651165 -3.073388 +vt 1.443224 -4.135998 +vt 0.651165 -5.073388 +vt 0.000000 0.000000 +vt 0.651165 1.473479 +vt -0.348835 4.139208 +vt 0.651165 4.139207 +vt -0.348835 -3.073388 +vt 3.622119 -4.135998 +vt 1.473479 -3.073388 +vt 4.139208 -3.073388 +vt 5.690037 -3.221059 +vt 4.401579 -3.221134 +vt -0.348835 6.147160 +vt 0.651165 6.147160 +vt 3.906295 -4.135998 +vt 3.906287 -4.136012 +vt 4.421692 -3.221133 +vt 3.913219 -4.123208 +vt 3.906294 -4.135998 +vt 3.906288 -4.135963 +vt 3.899373 -4.148791 +vt 3.513786 -4.888495 +vt 3.492246 -4.901289 +vt 3.165965 -5.073388 +vt 0.651165 3.165965 +vt -0.348835 1.416534 +vt 0.651165 1.416534 +vt 0.651165 4.483718 +vt -0.348835 3.165966 +vt 4.384322 -4.901289 +vt 5.801472 -5.073388 +vt 5.263364 -4.135997 +vt 6.904611 -4.135998 +vt 0.651165 5.801472 +vt -0.348835 4.483719 +vt 4.979189 -4.135997 +vt 4.379648 -4.888495 +vt 4.384322 -4.901289 +vt 4.962351 -4.136020 +vt 4.979189 -4.135997 +vt 5.680099 -3.233851 +vt 6.147160 -3.073388 +vt 5.263365 -4.135998 +vt 8.155111 -3.073388 +vt 0.651165 6.904611 +vt -0.348835 6.904611 +vt -0.348835 8.155111 +vt 0.651165 8.155111 +vt 4.483718 -5.073388 +vt -0.348835 5.801472 +vt 1.416534 -5.073388 +vt 3.906329 -4.135935 +vt 4.414068 -3.233924 +vt 4.394653 -3.233927 +vt 5.669934 -3.221060 +vt -0.348835 1.473479 +vt 1.473479 0.677011 +vt 0.406611 0.677011 +vt 0.751427 1.473479 +vt 0.751427 0.376458 +vt 0.376458 0.677011 +vt 1.473479 1.201967 +vt 1.473479 1.536579 +vt 0.751427 -0.069017 +vt 0.651165 0.406611 +vt 0.651165 0.677011 +vt -0.348835 -5.073388 +vt 1.473479 4.025256 +vt 0.751427 -0.300623 +vt 4.962389 -4.135972 +vt 5.660683 -3.233854 +s 0 +usemtl Geometric_Brass_Engraved_Pattern +f 730/950/807 729/951/807 732/952/807 +f 729/951/808 731/953/808 732/952/808 +f 731/953/809 738/954/809 732/952/809 +f 735/955/810 733/956/810 732/952/810 +f 733/956/811 734/957/811 732/952/811 +f 734/957/812 730/950/812 732/952/812 +f 739/958/813 735/955/813 732/952/813 +f 738/954/814 736/959/814 732/952/814 +f 736/959/815 737/960/815 732/952/815 +f 737/960/816 739/958/816 732/952/816 +f 775/947/852 776/947/852 778/949/852 +f 777/971/853 776/971/853 775/947/853 +f 778/946/855 776/946/855 779/945/855 +f 779/949/856 776/949/856 780/947/856 +f 851/1015/895 962/1016/895 853/1017/895 +f 851/1015/791 855/1017/791 854/1009/791 +f 853/1017/793 864/1024/793 855/1017/793 +f 864/1024/843 868/1030/843 865/1030/843 +f 853/1017/901 867/1031/901 866/1032/901 +f 868/1030/902 867/1031/902 869/1033/902 +f 896/1031/915 892/1030/915 893/1033/915 +f 897/1024/843 892/1030/843 894/1032/843 +f 895/1017/916 896/1031/916 912/1016/916 +f 897/1024/793 895/1017/793 898/1017/793 +f 898/1017/791 908/1015/791 906/1009/791 +f 908/1015/789 912/1016/789 910/1046/789 +f 910/1046/789 893/1033/789 913/1047/789 +f 943/962/945 776/962/945 942/963/945 +f 942/963/946 776/963/946 777/971/946 +f 944/966/947 776/966/947 943/965/947 +f 945/963/949 776/963/949 944/962/949 +f 786/971/952 776/971/952 945/963/952 +f 852/1046/868 848/1047/868 869/1033/868 +f 780/947/962 776/947/962 786/971/962 +f 851/1015/868 852/1046/868 962/1016/868 +f 851/1015/791 853/1017/791 855/1017/791 +f 853/1017/793 866/1032/793 864/1024/793 +f 864/1024/843 866/1032/843 868/1030/843 +f 853/1017/901 962/1016/901 867/1031/901 +f 868/1030/902 866/1032/902 867/1031/902 +f 896/1031/915 894/1032/915 892/1030/915 +f 897/1024/843 888/1030/843 892/1030/843 +f 895/1017/916 894/1032/916 896/1031/916 +f 897/1024/793 894/1032/793 895/1017/793 +f 898/1017/791 895/1017/791 908/1015/791 +f 908/1015/1043 895/1017/1043 912/1016/1043 +f 910/1046/789 912/1016/789 896/1031/789 +f 893/1033/789 890/1064/789 915/1065/789 +f 910/1046/789 896/1031/789 893/1033/789 +f 913/1047/789 911/1012/789 910/1046/789 +f 893/1033/789 915/1065/789 913/1047/789 +f 852/1046/868 850/1012/868 848/1047/868 +f 848/1047/868 961/1065/868 871/1064/868 +f 869/1033/868 867/1031/868 962/1016/868 +f 848/1047/868 871/1064/868 869/1033/868 +f 869/1033/868 962/1016/868 852/1046/868 +usemtl Dark_iron +f 723/942/803 727/939/803 726/942/803 +f 723/942/804 728/943/804 725/943/804 +f 726/944/805 731/945/805 729/946/805 +f 730/947/806 726/948/806 729/949/806 +f 742/961/817 739/962/817 737/963/817 +f 740/964/818 735/965/818 739/966/818 +f 744/967/819 740/968/819 743/968/819 +f 745/928/820 740/968/820 742/928/820 +f 746/969/824 742/928/824 748/969/824 +f 746/969/826 749/933/826 747/933/826 +f 749/970/827 736/971/827 738/947/827 +f 736/971/828 742/961/828 737/963/828 +f 727/948/829 738/947/829 731/949/829 +f 724/939/830 749/933/830 727/939/830 +f 751/972/833 741/967/833 744/967/833 +f 753/973/835 754/972/835 751/972/835 +f 754/961/836 734/971/836 733/963/836 +f 735/962/837 754/961/837 733/963/837 +f 734/971/838 728/970/838 730/947/838 +f 753/973/839 728/943/839 755/973/839 +f 723/942/803 724/939/803 727/939/803 +f 723/942/976 726/942/976 728/943/976 +f 726/944/805 727/1063/805 731/945/805 +f 730/947/977 728/970/977 726/948/977 +f 742/961/978 740/986/978 739/962/978 +f 740/964/818 741/1058/818 735/965/818 +f 744/967/819 741/967/819 740/968/819 +f 745/928/979 743/968/979 740/968/979 +f 746/969/980 745/928/980 742/928/980 +f 746/969/982 748/969/982 749/933/982 +f 749/970/983 748/982/983 736/971/983 +f 736/971/984 748/982/984 742/961/984 +f 727/948/985 749/970/985 738/947/985 +f 724/939/986 747/933/986 749/933/986 +f 751/972/988 754/972/988 741/967/988 +f 753/973/989 755/973/989 754/972/989 +f 754/961/990 755/982/990 734/971/990 +f 735/962/991 741/986/991 754/961/991 +f 734/971/992 755/982/992 728/970/992 +f 753/973/993 725/943/993 728/943/993 +usemtl Cherry_Red_Scratched_Painted_Steel +f 686/902/787 691/903/787 690/904/787 +f 688/905/788 690/906/788 692/907/788 +f 689/908/789 688/905/789 956/905/789 +f 691/903/790 693/909/790 690/904/790 +f 690/910/791 695/911/791 692/912/791 +f 696/913/792 694/914/792 693/906/792 +f 693/906/793 817/915/793 695/907/793 +f 697/916/794 699/917/794 698/918/794 +f 953/919/795 696/920/795 691/903/795 +f 698/921/789 701/922/789 694/923/789 +f 699/924/789 700/925/789 698/921/789 +f 701/922/789 703/926/789 704/927/789 +f 700/925/789 705/928/789 703/926/789 +f 703/926/789 707/929/789 704/927/789 +f 705/928/789 706/930/789 703/926/789 +f 707/929/796 709/931/796 710/932/796 +f 706/930/797 711/933/797 709/931/797 +f 709/931/796 713/934/796 710/932/796 +f 711/933/798 712/935/798 709/931/798 +f 713/934/789 715/936/789 716/937/789 +f 712/935/789 717/938/789 715/936/789 +f 714/939/789 718/940/789 717/938/789 +f 721/941/799 718/940/799 720/942/799 +f 722/943/800 721/941/800 720/942/800 +f 720/942/801 724/939/801 723/942/801 +f 720/942/802 725/943/802 722/943/802 +f 750/967/821 743/968/821 702/968/821 +f 702/968/822 745/928/822 705/928/822 +f 705/928/823 746/969/823 708/969/823 +f 708/969/825 747/933/825 711/933/825 +f 714/939/831 747/933/831 724/939/831 +f 750/967/832 751/972/832 744/967/832 +f 752/972/834 753/973/834 751/972/834 +f 756/973/840 725/943/840 753/973/840 +f 757/974/841 722/943/841 756/973/841 +f 752/972/842 757/974/842 756/973/842 +f 758/975/843 759/976/843 757/977/843 +f 757/977/843 761/978/843 760/979/843 +f 760/979/843 762/980/843 721/948/843 +f 763/979/843 762/980/843 761/978/843 +f 765/977/843 761/978/843 759/976/843 +f 766/943/844 764/941/844 763/981/844 +f 766/943/845 765/974/845 768/973/845 +f 769/943/846 767/942/846 766/943/846 +f 768/973/847 769/943/847 766/943/847 +f 772/943/848 770/942/848 769/943/848 +f 771/973/849 772/943/849 769/943/849 +f 775/947/850 773/948/850 772/970/850 +f 777/971/851 772/970/851 774/982/851 +f 779/945/854 773/944/854 778/946/854 +f 780/947/857 781/948/857 779/949/857 +f 770/942/858 781/939/858 782/939/858 +f 782/939/859 783/933/859 784/933/859 +f 786/971/860 783/970/860 780/947/860 +f 783/933/861 788/969/861 784/933/861 +f 786/971/862 787/961/862 785/982/862 +f 788/969/863 787/928/863 790/928/863 +f 788/969/864 792/928/864 789/969/864 +f 784/933/865 789/969/865 801/933/865 +f 790/928/866 946/968/866 791/968/866 +f 790/928/867 793/968/867 792/928/867 +f 797/930/868 792/928/868 794/926/868 +f 796/925/868 792/928/868 793/968/868 +f 798/929/868 794/926/868 795/927/868 +f 818/922/868 794/926/868 796/925/868 +f 798/929/869 799/931/869 797/930/869 +f 797/930/870 801/933/870 789/969/870 +f 803/934/871 799/931/871 800/932/871 +f 802/935/872 801/933/872 799/931/872 +f 803/934/868 805/936/868 802/935/868 +f 802/935/868 807/938/868 804/939/868 +f 807/938/868 767/942/868 804/939/868 +f 808/940/873 764/941/873 767/942/873 +f 809/983/843 762/980/843 764/948/843 +f 762/980/843 719/983/843 721/948/843 +f 811/984/791 803/948/791 812/980/791 +f 812/980/791 716/983/791 811/984/791 +f 710/979/791 812/980/791 813/978/791 +f 812/980/791 800/979/791 813/978/791 +f 813/978/791 798/977/791 814/976/791 +f 707/977/791 813/978/791 814/976/791 +f 704/975/791 814/976/791 815/985/791 +f 814/976/791 795/975/791 815/985/791 +f 815/985/791 818/986/791 816/987/791 +f 701/986/791 815/985/791 816/987/791 +f 816/987/791 819/988/791 817/911/791 +f 817/911/791 701/986/791 816/987/791 +f 818/922/868 821/921/868 819/923/868 +f 819/914/874 823/913/874 820/906/874 +f 817/915/793 820/906/793 695/907/793 +f 821/918/875 950/916/875 824/916/875 +f 796/925/868 822/924/868 821/921/868 +f 825/903/876 820/909/876 823/920/876 +f 823/920/877 829/919/877 825/903/877 +f 830/902/878 825/903/878 828/989/878 +f 825/903/879 829/919/879 827/919/879 +f 828/989/880 827/919/880 831/990/880 +f 829/919/881 950/991/881 827/919/881 +f 831/990/882 827/919/882 832/992/882 +f 838/993/883 831/990/883 832/992/883 +f 835/994/884 833/995/884 958/996/884 +f 834/995/885 833/995/885 831/997/885 +f 834/995/886 831/997/886 836/994/886 +f 836/998/887 842/999/887 839/1000/887 +f 838/910/843 837/1001/843 836/994/843 +f 841/1002/888 836/1003/888 839/1004/888 +f 839/1004/889 844/1005/889 843/1006/889 +f 839/1000/887 960/1007/887 840/1008/887 +f 845/1009/890 839/1004/890 843/1006/890 +f 847/1005/891 843/1006/891 844/1005/891 +f 843/1006/892 849/1010/892 845/1009/892 +f 847/1005/893 848/1011/893 846/1006/893 +f 846/1006/843 850/1012/843 849/1010/843 +f 849/1013/868 852/1009/868 851/1014/868 +f 845/1009/894 851/1014/894 854/1009/894 +f 854/1009/896 841/1002/896 845/1009/896 +f 855/1017/897 856/1002/897 854/1009/897 +f 833/995/793 841/1002/793 856/1002/793 +f 857/1018/898 833/995/898 856/1002/898 +f 857/1019/793 957/1020/793 858/1021/793 +f 860/1022/793 859/1023/793 857/1019/793 +f 864/1024/899 857/1018/899 855/1017/899 +f 861/1025/898 862/1026/898 875/1027/898 +f 861/1028/793 863/1029/793 860/1022/793 +f 862/1026/900 864/1024/900 865/1030/900 +f 871/1034/903 868/1030/903 869/1030/903 +f 865/1030/904 870/1030/904 872/1034/904 +f 961/1035/905 870/1030/905 871/1034/905 +f 872/1034/791 847/1005/791 844/1005/791 +f 840/1036/906 872/1034/906 844/1005/906 +f 873/1037/907 865/1030/907 872/1034/907 +f 875/1027/793 873/1037/793 874/1027/793 +f 874/1027/908 840/1036/908 876/1038/908 +f 875/1039/793 877/1040/793 879/1040/793 +f 874/1039/909 878/1041/909 877/1040/909 +f 880/1039/909 878/1041/909 882/1042/909 +f 881/1039/793 877/1040/793 880/1039/793 +f 881/1027/793 883/1037/793 885/1026/793 +f 880/1027/910 884/1036/910 883/1037/910 +f 886/1034/911 884/1036/911 887/1005/911 +f 888/1030/912 883/1037/912 886/1034/912 +f 886/1034/791 891/1005/791 889/1030/791 +f 888/1030/843 889/1030/843 892/1030/843 +f 893/1030/913 889/1030/913 890/1034/913 +f 915/1035/914 889/1030/914 891/1005/914 +f 898/1017/917 899/1043/917 897/1024/917 +f 897/1024/918 885/1026/918 888/1030/918 +f 900/1025/919 885/1026/919 899/1043/919 +f 899/1022/793 959/1044/793 900/1028/793 +f 901/1019/793 863/1029/793 899/1022/793 +f 902/1021/793 859/1023/793 901/1019/793 +f 901/1018/919 904/995/919 902/1045/919 +f 898/1017/920 903/1002/920 901/1018/920 +f 903/1002/793 920/995/793 904/995/793 +f 906/1009/921 905/1002/921 903/1002/921 +f 907/1009/791 908/1014/791 909/1013/791 +f 909/1013/789 910/1009/789 911/1009/789 +f 914/1006/922 911/1012/922 913/1048/922 +f 891/1005/923 913/1011/923 915/1049/923 +f 916/1006/891 891/1005/891 887/1005/891 +f 916/1006/843 909/1010/843 914/1006/843 +f 887/1005/924 917/1004/924 916/1006/924 +f 907/1009/925 917/1004/925 905/1002/925 +f 918/998/887 842/999/887 837/1050/887 +f 905/1002/926 918/1003/926 920/995/926 +f 917/1000/887 960/1007/887 842/999/887 +f 837/1001/843 919/910/843 918/994/843 +f 919/993/927 921/990/927 918/994/927 +f 920/995/928 918/994/928 921/997/928 +f 921/990/929 923/992/929 922/919/929 +f 687/989/930 922/919/930 691/903/930 +f 904/995/931 689/994/931 954/996/931 +f 920/995/885 921/997/885 904/995/885 +f 923/992/932 925/1051/932 924/1052/932 +f 923/992/789 926/991/789 922/919/789 +f 928/1053/933 924/1052/933 925/1051/933 +f 926/916/793 927/1054/793 699/917/793 +f 929/911/843 930/986/843 928/988/843 +f 925/998/843 929/1050/843 928/1053/843 +f 927/1055/934 930/1056/934 750/967/934 +f 930/986/843 932/985/843 758/975/843 +f 930/1056/935 752/972/935 750/967/935 +f 934/988/843 931/987/843 929/911/843 +f 933/986/843 932/985/843 931/987/843 +f 947/1055/936 933/1056/936 934/1051/936 +f 937/972/937 933/1056/937 935/967/937 +f 937/972/938 765/974/938 936/1057/938 +f 936/975/843 759/976/843 932/985/843 +f 937/972/939 771/973/939 768/973/939 +f 935/967/940 938/972/940 937/972/940 +f 940/972/941 771/973/941 938/972/941 +f 941/967/942 938/972/942 939/967/942 +f 777/971/943 940/961/943 942/963/943 +f 943/962/944 940/961/944 941/986/944 +f 944/966/948 941/1058/948 946/964/948 +f 944/962/950 787/961/950 945/963/950 +f 791/968/951 941/967/951 939/967/951 +f 793/968/953 939/967/953 935/967/953 +f 822/924/868 935/967/868 947/1055/868 +f 950/916/793 947/1054/793 948/1059/793 +f 934/1053/954 949/1051/954 948/1052/954 +f 832/992/955 949/1051/955 838/993/955 +f 827/919/868 948/1052/868 832/992/868 +f 949/998/789 929/1050/789 951/1050/789 +f 949/1060/843 952/912/843 838/910/843 +f 952/912/843 925/1060/843 919/910/843 +f 699/924/789 750/967/789 702/968/789 +f 926/991/956 953/919/956 922/919/956 +f 691/903/957 922/919/957 953/919/957 +f 955/1061/958 689/994/958 956/1001/958 +f 957/1020/789 954/1021/789 955/1020/789 +f 956/1001/958 958/996/958 955/1061/958 +f 957/1020/789 958/1021/789 858/1021/789 +f 835/908/789 688/905/789 830/908/789 +f 959/1044/959 881/1039/959 900/1028/959 +f 875/1039/959 959/1044/959 861/1028/959 +f 884/1008/887 878/1041/887 960/1007/887 +f 840/1008/887 878/1041/887 876/1042/887 +f 688/905/788 826/906/788 830/908/788 +f 695/911/791 826/910/791 692/912/791 +f 770/942/960 804/939/960 767/942/960 +f 804/939/961 784/933/961 801/933/961 +f 686/902/963 687/989/963 691/903/963 +f 688/905/788 686/908/788 690/906/788 +f 689/908/789 686/908/789 688/905/789 +f 691/903/964 696/920/964 693/909/964 +f 690/910/791 693/1060/791 695/911/791 +f 696/913/965 698/918/965 694/914/965 +f 693/906/793 694/914/793 817/915/793 +f 698/918/966 696/913/966 697/916/966 +f 697/916/967 926/916/967 699/917/967 +f 953/919/968 697/991/968 696/920/968 +f 698/921/789 700/925/789 701/922/789 +f 699/924/789 702/968/789 700/925/789 +f 701/922/789 700/925/789 703/926/789 +f 700/925/789 702/968/789 705/928/789 +f 703/926/789 706/930/789 707/929/789 +f 705/928/789 708/969/789 706/930/789 +f 707/929/969 706/930/969 709/931/969 +f 706/930/970 708/969/970 711/933/970 +f 709/931/971 712/935/971 713/934/971 +f 711/933/972 714/939/972 712/935/972 +f 713/934/789 712/935/789 715/936/789 +f 712/935/789 714/939/789 717/938/789 +f 714/939/789 720/942/789 718/940/789 +f 721/941/973 719/1062/973 718/940/973 +f 722/943/974 760/981/974 721/941/974 +f 720/942/801 714/939/801 724/939/801 +f 720/942/975 723/942/975 725/943/975 +f 750/967/821 744/967/821 743/968/821 +f 702/968/822 743/968/822 745/928/822 +f 705/928/823 745/928/823 746/969/823 +f 708/969/981 746/969/981 747/933/981 +f 714/939/987 711/933/987 747/933/987 +f 750/967/832 752/972/832 751/972/832 +f 752/972/834 756/973/834 753/973/834 +f 756/973/994 722/943/994 725/943/994 +f 757/974/974 760/981/974 722/943/974 +f 752/972/995 758/1057/995 757/974/995 +f 758/975/843 932/985/843 759/976/843 +f 757/977/843 759/976/843 761/978/843 +f 760/979/843 761/978/843 762/980/843 +f 763/979/843 764/948/843 762/980/843 +f 765/977/843 763/979/843 761/978/843 +f 766/943/996 767/942/996 764/941/996 +f 766/943/844 763/981/844 765/974/844 +f 769/943/997 770/942/997 767/942/997 +f 768/973/998 771/973/998 769/943/998 +f 772/943/999 773/942/999 770/942/999 +f 771/973/1000 774/973/1000 772/943/1000 +f 775/947/1001 778/949/1001 773/948/1001 +f 777/971/1002 775/947/1002 772/970/1002 +f 779/945/854 781/1063/854 773/944/854 +f 780/947/1003 783/970/1003 781/948/1003 +f 770/942/858 773/942/858 781/939/858 +f 782/939/1004 781/939/1004 783/933/1004 +f 786/971/1005 785/982/1005 783/970/1005 +f 783/933/1006 785/969/1006 788/969/1006 +f 786/971/1007 945/963/1007 787/961/1007 +f 788/969/1008 785/969/1008 787/928/1008 +f 788/969/864 790/928/864 792/928/864 +f 784/933/1009 788/969/1009 789/969/1009 +f 790/928/1010 787/928/1010 946/968/1010 +f 790/928/867 791/968/867 793/968/867 +f 797/930/868 789/969/868 792/928/868 +f 796/925/868 794/926/868 792/928/868 +f 798/929/868 797/930/868 794/926/868 +f 818/922/868 795/927/868 794/926/868 +f 798/929/871 800/932/871 799/931/871 +f 797/930/1011 799/931/1011 801/933/1011 +f 803/934/1012 802/935/1012 799/931/1012 +f 802/935/1013 804/939/1013 801/933/1013 +f 803/934/868 806/937/868 805/936/868 +f 802/935/868 805/936/868 807/938/868 +f 807/938/868 808/940/868 767/942/868 +f 808/940/936 809/1062/936 764/941/936 +f 809/983/843 810/984/843 762/980/843 +f 762/980/843 810/984/843 719/983/843 +f 811/984/791 806/983/791 803/948/791 +f 812/980/791 713/948/791 716/983/791 +f 710/979/791 713/948/791 812/980/791 +f 812/980/791 803/948/791 800/979/791 +f 813/978/791 800/979/791 798/977/791 +f 707/977/791 710/979/791 813/978/791 +f 704/975/791 707/977/791 814/976/791 +f 814/976/791 798/977/791 795/975/791 +f 815/985/791 795/975/791 818/986/791 +f 701/986/791 704/975/791 815/985/791 +f 816/987/791 818/986/791 819/988/791 +f 817/911/791 694/988/791 701/986/791 +f 818/922/868 796/925/868 821/921/868 +f 819/914/1014 821/918/1014 823/913/1014 +f 817/915/793 819/914/793 820/906/793 +f 824/916/1015 823/913/1015 821/918/1015 +f 821/918/793 822/917/793 950/916/793 +f 796/925/868 793/968/868 822/924/868 +f 825/903/1016 826/904/1016 820/909/1016 +f 823/920/1017 824/991/1017 829/919/1017 +f 830/902/1018 826/904/1018 825/903/1018 +f 828/989/1019 825/903/1019 827/919/1019 +f 829/919/1020 824/991/1020 950/991/1020 +f 838/993/1021 836/994/1021 831/990/1021 +f 835/994/1022 831/997/1022 833/995/1022 +f 836/998/887 837/1050/887 842/999/887 +f 838/910/843 952/912/843 837/1001/843 +f 841/1002/1023 834/995/1023 836/1003/1023 +f 839/1004/1024 840/1036/1024 844/1005/1024 +f 839/1000/887 842/999/887 960/1007/887 +f 845/1009/1025 841/1002/1025 839/1004/1025 +f 847/1005/891 846/1006/891 843/1006/891 +f 843/1006/843 846/1006/843 849/1010/843 +f 847/1005/1026 961/1049/1026 848/1011/1026 +f 846/1006/1027 848/1048/1027 850/1012/1027 +f 849/1013/868 850/1009/868 852/1009/868 +f 845/1009/791 849/1013/791 851/1014/791 +f 854/1009/921 856/1002/921 841/1002/921 +f 855/1017/1028 857/1018/1028 856/1002/1028 +f 833/995/793 834/995/793 841/1002/793 +f 857/1018/898 858/1045/898 833/995/898 +f 857/1019/793 859/1023/793 957/1020/793 +f 860/1022/793 863/1029/793 859/1023/793 +f 864/1024/899 860/1043/899 857/1018/899 +f 861/1025/898 860/1043/898 862/1026/898 +f 861/1028/793 959/1044/793 863/1029/793 +f 862/1026/1029 860/1043/1029 864/1024/1029 +f 871/1034/1030 870/1030/1030 868/1030/1030 +f 865/1030/843 868/1030/843 870/1030/843 +f 961/1035/1031 847/1005/1031 870/1030/1031 +f 872/1034/791 870/1030/791 847/1005/791 +f 840/1036/1032 873/1037/1032 872/1034/1032 +f 873/1037/1033 862/1026/1033 865/1030/1033 +f 875/1027/793 862/1026/793 873/1037/793 +f 874/1027/1034 873/1037/1034 840/1036/1034 +f 875/1039/793 874/1039/793 877/1040/793 +f 874/1039/909 876/1042/909 878/1041/909 +f 880/1039/909 877/1040/909 878/1041/909 +f 881/1039/793 879/1040/793 877/1040/793 +f 881/1027/793 880/1027/793 883/1037/793 +f 880/1027/1035 882/1038/1035 884/1036/1035 +f 886/1034/1036 883/1037/1036 884/1036/1036 +f 888/1030/1033 885/1026/1033 883/1037/1033 +f 886/1034/791 887/1005/791 891/1005/791 +f 888/1030/1037 886/1034/1037 889/1030/1037 +f 893/1030/1038 892/1030/1038 889/1030/1038 +f 915/1035/1039 890/1034/1039 889/1030/1039 +f 898/1017/917 901/1018/917 899/1043/917 +f 897/1024/1040 899/1043/1040 885/1026/1040 +f 900/1025/919 881/1027/919 885/1026/919 +f 899/1022/793 863/1029/793 959/1044/793 +f 901/1019/793 859/1023/793 863/1029/793 +f 902/1021/793 957/1020/793 859/1023/793 +f 901/1018/919 903/1002/919 904/995/919 +f 898/1017/1041 906/1009/1041 903/1002/1041 +f 903/1002/793 905/1002/793 920/995/793 +f 906/1009/1042 907/1009/1042 905/1002/1042 +f 907/1009/894 906/1009/894 908/1014/894 +f 909/1013/789 908/1014/789 910/1009/789 +f 914/1006/843 909/1010/843 911/1012/843 +f 891/1005/1044 914/1006/1044 913/1011/1044 +f 916/1006/891 914/1006/891 891/1005/891 +f 916/1006/892 907/1009/892 909/1010/892 +f 887/1005/1045 884/1036/1045 917/1004/1045 +f 907/1009/1046 916/1006/1046 917/1004/1046 +f 918/998/887 917/1000/887 842/999/887 +f 905/1002/1047 917/1004/1047 918/1003/1047 +f 917/1000/887 884/1008/887 960/1007/887 +f 837/1001/843 952/912/843 919/910/843 +f 919/993/1048 923/992/1048 921/990/1048 +f 687/989/1049 921/990/1049 922/919/1049 +f 904/995/1050 921/997/1050 689/994/1050 +f 923/992/932 919/993/932 925/1051/932 +f 923/992/789 924/1052/789 926/991/789 +f 926/916/793 924/1059/793 927/1054/793 +f 929/911/843 931/987/843 930/986/843 +f 925/998/789 951/1050/789 929/1050/789 +f 927/1055/973 928/1051/973 930/1056/973 +f 930/986/843 931/987/843 932/985/843 +f 930/1056/995 758/1057/995 752/972/995 +f 934/988/843 933/986/843 931/987/843 +f 933/986/843 936/975/843 932/985/843 +f 947/1055/1051 935/967/1051 933/1056/1051 +f 937/972/938 936/1057/938 933/1056/938 +f 937/972/1052 768/973/1052 765/974/1052 +f 936/975/843 765/977/843 759/976/843 +f 937/972/939 938/972/939 771/973/939 +f 935/967/940 939/967/940 938/972/940 +f 940/972/1053 774/973/1053 771/973/1053 +f 941/967/1054 940/972/1054 938/972/1054 +f 777/971/1055 774/982/1055 940/961/1055 +f 943/962/1056 942/963/1056 940/961/1056 +f 944/966/948 943/965/948 941/1058/948 +f 944/962/1057 946/986/1057 787/961/1057 +f 791/968/951 946/968/951 941/967/951 +f 793/968/953 791/968/953 939/967/953 +f 822/924/868 793/968/868 935/967/868 +f 950/916/793 822/917/793 947/1054/793 +f 832/992/955 948/1052/955 949/1051/955 +f 827/919/868 950/991/868 948/1052/868 +f 949/998/843 934/1053/843 929/1050/843 +f 949/1060/843 951/911/843 952/912/843 +f 952/912/843 951/911/843 925/1060/843 +f 699/924/789 927/1055/789 750/967/789 +f 926/991/956 697/991/956 953/919/956 +f 955/1061/958 954/996/958 689/994/958 +f 957/1020/789 902/1021/789 954/1021/789 +f 956/1001/958 835/994/958 958/996/958 +f 957/1020/789 955/1020/789 958/1021/789 +f 835/908/789 956/905/789 688/905/789 +f 959/1044/959 879/1040/959 881/1039/959 +f 875/1039/959 879/1040/959 959/1044/959 +f 884/1008/887 882/1042/887 878/1041/887 +f 840/1008/887 960/1007/887 878/1041/887 +f 688/905/788 692/907/788 826/906/788 +f 695/911/791 820/1060/791 826/910/791 +f 770/942/960 782/939/960 804/939/960 +f 804/939/1058 782/939/1058 784/933/1058 +o Cube.014 +v 0.034276 0.460430 0.151947 +o Cube.015 +v -0.034276 0.460430 0.151947 +o Cube.016 +v 0.028556 0.559234 0.200419 +v 0.028555 0.559234 0.193721 +v 0.040395 0.552137 0.212258 +v 0.001078 0.559234 0.200419 +v 0.001078 0.552137 0.212258 +v 0.001078 0.559234 0.193721 +v -0.026399 0.559234 0.200419 +v -0.026399 0.559234 0.193721 +v -0.038238 0.552137 0.212258 +v -0.038238 0.547543 0.212258 +v -0.038238 0.552137 0.204308 +v -0.038238 0.552137 -0.119297 +v -0.038238 0.547543 0.206823 +v -0.038238 0.547543 -0.121812 +v -0.038238 0.519058 0.206823 +v -0.036564 0.547543 0.206823 +v -0.036564 0.547543 -0.121812 +v -0.035310 0.546339 0.205619 +v -0.036564 0.519058 0.206823 +v -0.035310 0.520262 0.205619 +v -0.036564 0.519058 -0.121812 +v -0.035310 0.520262 -0.120607 +v -0.038238 0.519058 -0.121812 +v -0.038238 0.519058 -0.127017 +v -0.038238 0.514705 -0.119297 +v -0.038238 0.514705 -0.127017 +v -0.038238 0.514705 0.204308 +v -0.036097 0.512564 -0.117254 +v -0.036097 0.512564 -0.124876 +v -0.036097 0.512564 0.202266 +v 0.001078 0.512564 -0.117254 +v 0.038253 0.512564 -0.117254 +v 0.001078 0.512564 0.202266 +v 0.001078 0.512564 -0.124876 +v 0.038253 0.512564 -0.124876 +v 0.001078 0.514705 -0.127017 +v 0.040395 0.514705 -0.127017 +v 0.001078 0.519058 -0.127017 +v 0.040395 0.519058 -0.127017 +v 0.001078 0.547543 -0.127017 +v 0.040395 0.547543 -0.127017 +v 0.001078 0.552137 -0.127017 +v -0.038238 0.547543 -0.127017 +v -0.038238 0.552137 -0.127017 +v -0.026399 0.559234 -0.114439 +v 0.001078 0.559234 -0.114439 +v -0.026399 0.559234 -0.106594 +v 0.001078 0.559234 -0.106594 +v 0.028555 0.559234 -0.106594 +v 0.028555 0.559234 -0.114439 +v 0.040395 0.552137 -0.119297 +v 0.040395 0.552137 -0.127017 +v 0.040395 0.552137 0.204308 +v 0.040395 0.547543 -0.121812 +v 0.040395 0.547543 0.206823 +v 0.040395 0.519058 -0.121812 +v 0.038720 0.547543 -0.121812 +v 0.037467 0.546339 -0.120607 +v 0.038720 0.547543 0.206823 +v 0.038720 0.519058 -0.121812 +v 0.037467 0.520262 -0.120607 +v 0.038720 0.519058 0.206823 +v 0.037467 0.520262 0.205619 +v 0.040395 0.519058 0.206823 +v 0.040395 0.519058 0.212258 +v 0.040395 0.514705 0.204308 +v 0.040395 0.514705 0.212258 +v 0.040395 0.514705 -0.119297 +v 0.038253 0.512564 0.202266 +v 0.038253 0.512564 0.210117 +v 0.001078 0.512564 0.210117 +v 0.001078 0.514705 0.212258 +v -0.036097 0.512564 0.210117 +v -0.038238 0.514705 0.212259 +v -0.038238 0.519058 0.212259 +v 0.001078 0.519058 0.212258 +v 0.001078 0.547543 0.212258 +v 0.040395 0.547543 0.212258 +v 0.037467 0.546339 0.205619 +v -0.035310 0.546339 -0.120607 +vn -0.0000 1.0000 -0.0000 +vn 0.5141 0.8577 -0.0000 +vn -0.0000 0.8577 0.5141 +vn -0.5141 0.8577 -0.0000 +vn -0.0000 -0.0000 1.0000 +vn -1.0000 -0.0000 -0.0000 +vn -0.0000 -1.0000 -0.0000 +vn -0.0000 -0.0000 -1.0000 +vn -0.6928 -0.7212 -0.0000 +vn -0.6928 -0.0000 -0.7211 +vn -0.6928 0.7211 -0.0000 +vn -0.6928 -0.0000 0.7211 +vn -0.7071 -0.7071 -0.0000 +vn -0.0000 -0.7071 -0.7071 +vn -0.0000 0.8710 -0.4914 +vn 1.0000 -0.0000 -0.0000 +vn 0.6928 -0.0000 0.7211 +vn 0.6928 -0.7212 -0.0000 +vn 0.6928 0.7211 -0.0000 +vn 0.6928 -0.0000 -0.7211 +vn 0.7071 -0.7071 -0.0000 +vn -0.0000 -0.7071 0.7071 +vn -0.6928 0.7212 -0.0000 +vn 0.6928 0.7212 -0.0000 +vt 0.188319 0.057421 +vt 0.125007 0.328806 +vt 0.120189 0.057463 +vt 0.234358 0.320760 +vt 0.195525 0.328778 +vt 0.117918 0.018572 +vt 0.222515 0.020502 +vt 0.117338 0.004185 +vt 0.234458 0.008151 +vt 0.248090 0.319033 +vt 0.246201 0.621018 +vt 0.261723 0.629915 +vt 0.202732 0.600134 +vt 0.739354 0.447773 +vt 0.673124 0.631952 +vt 0.743306 0.677457 +vt 0.261673 0.628776 +vt 0.676096 0.634881 +vt 0.275793 0.623873 +vt 0.275793 0.313189 +vt 0.275793 0.622730 +vt 0.275793 0.312046 +vt 0.673124 0.017876 +vt 0.744112 0.000219 +vt 0.676254 0.016131 +vt 0.747257 0.000388 +vt 0.290071 0.922709 +vt 0.275793 0.935700 +vt 0.673124 0.310554 +vt 0.751209 0.230072 +vt 0.288897 0.317933 +vt 0.289484 0.620321 +vt 0.299695 0.913532 +vt 0.298894 0.617459 +vt 0.399012 0.617230 +vt 0.399813 0.913303 +vt 0.398211 0.321158 +vt 0.298093 0.321387 +vt 0.399492 0.922776 +vt 0.398612 0.936935 +vt 0.842380 0.230204 +vt 0.836453 0.324695 +vt 0.137022 0.919263 +vt 0.275356 0.940797 +vt 0.137787 0.936406 +vt 0.258044 0.921276 +vt 0.209938 0.871491 +vt 0.134644 0.871491 +vt 0.129826 0.600149 +vt 0.740348 0.676442 +vt 0.288311 0.015546 +vt 0.297292 0.025314 +vt 0.397410 0.025085 +vt 0.397732 0.015613 +vt 0.275793 0.000219 +vt 0.836453 0.353415 +vt 0.673124 0.339273 +vt 0.830525 0.447905 +vt 0.988867 0.502325 +vt 0.048197 0.427134 +vt 0.988867 0.427134 +vt 0.248140 0.320172 +vt 0.398612 0.001453 +vt 0.048197 0.502325 +s 0 +usemtl Geometric_Brass_Engraved_Pattern +f 1022/1124/1074 1027/1125/1074 1025/1126/1074 +f 984/1125/1064 1044/1124/1064 986/1126/1064 +f 1022/1124/1074 1043/1129/1074 1027/1125/1074 +f 984/1125/1064 982/1129/1064 1044/1124/1064 +usemtl Brass.001 +f 965/1066/1059 970/1067/1059 968/1068/1059 +f 965/1066/1060 1017/1069/1060 966/1070/1060 +f 965/1066/1061 969/1071/1061 967/1072/1061 +f 971/1066/1061 969/1071/1061 968/1068/1061 +f 968/1068/1059 972/1070/1059 971/1066/1059 +f 975/1069/1062 971/1066/1062 972/1070/1062 +f 1041/1073/1063 973/1072/1063 974/1074/1063 +f 977/1075/1064 973/1072/1064 975/1069/1064 +f 977/1075/1064 976/1076/1064 978/1077/1064 +f 1011/1078/1062 975/1069/1062 972/1070/1062 +f 1039/1079/1064 977/1080/1064 979/1081/1064 +f 981/1077/1065 977/1075/1065 978/1077/1065 +f 980/1080/1066 979/1081/1066 977/1080/1066 +f 1044/1082/1067 980/1075/1067 981/1077/1067 +f 982/1083/1068 983/1081/1068 980/1080/1068 +f 985/1084/1069 984/1085/1069 986/1086/1069 +f 983/1087/1059 987/1084/1059 979/1087/1059 +f 981/1088/1070 986/1089/1070 1044/1090/1070 +f 987/1091/1063 981/1088/1063 978/1088/1063 +f 990/1092/1064 987/1084/1064 988/1093/1064 +f 987/1091/1064 1007/1094/1064 988/1095/1064 +f 991/1096/1064 987/1084/1064 989/1097/1064 +f 993/1098/1071 989/1097/1071 990/1092/1071 +f 992/1099/1071 991/1096/1071 989/1097/1071 +f 995/1100/1065 993/1098/1065 998/1101/1065 +f 997/1102/1065 992/1099/1065 995/1100/1065 +f 995/1100/1065 1033/1103/1065 997/1102/1065 +f 995/1100/1065 999/1098/1065 996/1099/1065 +f 1000/1104/1072 999/1098/1072 998/1101/1072 +f 1000/1104/1072 993/1098/1072 990/1092/1072 +f 1002/1105/1066 1001/1092/1066 1000/1104/1066 +f 990/1092/1066 1002/1105/1066 1000/1104/1066 +f 1002/1106/1066 1005/1094/1066 1003/1095/1066 +f 988/1095/1066 1004/1107/1066 1002/1106/1066 +f 1006/1108/1066 1005/1109/1066 1004/1110/1066 +f 1007/1109/1066 1006/1108/1066 1004/1110/1066 +f 978/1077/1064 1008/1111/1064 1007/1109/1064 +f 1009/1112/1062 976/1076/1062 1011/1078/1062 +f 1006/1108/1073 1009/1112/1073 1010/1113/1073 +f 1010/1113/1059 1011/1078/1059 1012/1114/1059 +f 970/1067/1059 1011/1078/1059 972/1070/1059 +f 966/1070/1059 1012/1114/1059 970/1067/1059 +f 1013/1078/1059 1010/1113/1059 1012/1114/1059 +f 1014/1112/1060 1015/1076/1060 1016/1111/1060 +f 1013/1078/1060 1017/1069/1060 1015/1076/1060 +f 1016/1111/1074 1018/1077/1074 1005/1109/1074 +f 1015/1076/1074 1019/1075/1074 1018/1077/1074 +f 1005/1094/1074 1020/1091/1074 1003/1095/1074 +f 1019/1075/1065 1021/1077/1065 1018/1077/1065 +f 1018/1088/1063 1024/1091/1063 1020/1091/1063 +f 1025/1089/1075 1021/1088/1075 1022/1090/1075 +f 1023/1075/1076 1022/1082/1076 1021/1077/1076 +f 1027/1085/1077 1024/1084/1077 1025/1086/1077 +f 1020/1084/1059 1026/1087/1059 1028/1087/1059 +f 1023/1080/1078 1027/1115/1078 1043/1083/1078 +f 1019/1080/1066 1026/1081/1066 1023/1080/1066 +f 1019/1080/1074 1029/1079/1074 1028/1081/1074 +f 1028/1087/1074 1031/1116/1074 1030/1096/1074 +f 1020/1084/1074 1030/1096/1074 1032/1097/1074 +f 1030/1096/1079 1034/1117/1079 1033/1103/1079 +f 1030/1096/1079 996/1099/1079 1032/1097/1079 +f 997/1102/1065 1034/1117/1065 1035/1118/1065 +f 1036/1119/1080 1034/1117/1080 1031/1116/1080 +f 1037/1117/1065 997/1102/1065 1035/1118/1065 +f 1037/1117/1080 1036/1119/1080 1038/1116/1080 +f 991/1096/1071 1037/1117/1071 1038/1116/1071 +f 1038/1116/1064 979/1087/1064 991/1096/1064 +f 1036/1119/1063 1039/1120/1063 1038/1116/1063 +f 1039/1079/1063 1041/1121/1063 974/1122/1063 +f 1029/1120/1063 1036/1119/1063 1031/1116/1063 +f 1042/1122/1063 1040/1123/1063 1029/1079/1063 +f 967/1072/1063 1041/1073/1063 1042/1074/1063 +f 1019/1075/1074 967/1072/1074 1042/1074/1074 +f 1032/1097/1079 999/1098/1079 1001/1092/1079 +f 1001/1092/1074 1020/1084/1074 1032/1097/1074 +f 1014/1112/1073 1006/1108/1073 1010/1113/1073 +f 965/1066/1059 966/1070/1059 970/1067/1059 +f 965/1066/1060 967/1072/1060 1017/1069/1060 +f 965/1066/1061 968/1068/1061 969/1071/1061 +f 971/1066/1061 973/1072/1061 969/1071/1061 +f 968/1068/1059 970/1067/1059 972/1070/1059 +f 975/1069/1062 973/1072/1062 971/1066/1062 +f 1041/1073/1063 969/1071/1063 973/1072/1063 +f 977/1075/1064 974/1074/1064 973/1072/1064 +f 977/1075/1064 975/1069/1064 976/1076/1064 +f 1011/1078/1062 976/1076/1062 975/1069/1062 +f 1039/1079/1064 974/1122/1064 977/1080/1064 +f 981/1077/1065 980/1075/1065 977/1075/1065 +f 980/1080/1066 983/1081/1066 979/1081/1066 +f 1044/1082/1067 982/1127/1067 980/1075/1067 +f 982/1083/1068 984/1115/1068 983/1081/1068 +f 985/1084/1081 983/1087/1081 984/1085/1081 +f 983/1087/1059 985/1084/1059 987/1084/1059 +f 981/1088/1070 985/1091/1070 986/1089/1070 +f 987/1091/1063 985/1091/1063 981/1088/1063 +f 990/1092/1064 989/1097/1064 987/1084/1064 +f 987/1091/1064 978/1088/1064 1007/1094/1064 +f 991/1096/1064 979/1087/1064 987/1084/1064 +f 993/1098/1071 992/1099/1071 989/1097/1071 +f 992/1099/1071 994/1103/1071 991/1096/1071 +f 995/1100/1065 992/1099/1065 993/1098/1065 +f 997/1102/1065 994/1103/1065 992/1099/1065 +f 995/1100/1065 996/1099/1065 1033/1103/1065 +f 995/1100/1065 998/1101/1065 999/1098/1065 +f 1000/1104/1072 1001/1092/1072 999/1098/1072 +f 1000/1104/1072 998/1101/1072 993/1098/1072 +f 1002/1105/1066 1003/1093/1066 1001/1092/1066 +f 990/1092/1066 988/1093/1066 1002/1105/1066 +f 1002/1106/1066 1004/1107/1066 1005/1094/1066 +f 988/1095/1066 1007/1094/1066 1004/1107/1066 +f 1006/1108/1066 1016/1111/1066 1005/1109/1066 +f 1007/1109/1066 1008/1111/1066 1006/1108/1066 +f 978/1077/1064 976/1076/1064 1008/1111/1064 +f 1009/1112/1062 1008/1111/1062 976/1076/1062 +f 1006/1108/1073 1008/1111/1073 1009/1112/1073 +f 1010/1113/1059 1009/1112/1059 1011/1078/1059 +f 970/1067/1059 1012/1114/1059 1011/1078/1059 +f 966/1070/1059 1013/1078/1059 1012/1114/1059 +f 1013/1078/1059 1014/1112/1059 1010/1113/1059 +f 1014/1112/1060 1013/1078/1060 1015/1076/1060 +f 1013/1078/1060 966/1070/1060 1017/1069/1060 +f 1016/1111/1074 1015/1076/1074 1018/1077/1074 +f 1015/1076/1074 1017/1069/1074 1019/1075/1074 +f 1005/1094/1074 1018/1088/1074 1020/1091/1074 +f 1019/1075/1065 1023/1075/1065 1021/1077/1065 +f 1018/1088/1063 1021/1088/1063 1024/1091/1063 +f 1025/1089/1075 1024/1091/1075 1021/1088/1075 +f 1023/1075/1076 1043/1127/1076 1022/1082/1076 +f 1027/1085/1082 1026/1087/1082 1024/1084/1082 +f 1020/1084/1059 1024/1084/1059 1026/1087/1059 +f 1023/1080/1078 1026/1081/1078 1027/1115/1078 +f 1019/1080/1066 1028/1081/1066 1026/1081/1066 +f 1019/1080/1074 1042/1122/1074 1029/1079/1074 +f 1028/1087/1074 1029/1120/1074 1031/1116/1074 +f 1020/1084/1074 1028/1087/1074 1030/1096/1074 +f 1030/1096/1079 1031/1116/1079 1034/1117/1079 +f 1030/1096/1079 1033/1103/1079 996/1099/1079 +f 997/1102/1065 1033/1103/1065 1034/1117/1065 +f 1036/1119/1080 1035/1118/1080 1034/1117/1080 +f 1037/1117/1065 994/1103/1065 997/1102/1065 +f 1037/1117/1080 1035/1118/1080 1036/1119/1080 +f 991/1096/1071 994/1103/1071 1037/1117/1071 +f 1038/1116/1064 1039/1120/1064 979/1087/1064 +f 1036/1119/1063 1040/1128/1063 1039/1120/1063 +f 1039/1079/1063 1040/1123/1063 1041/1121/1063 +f 1029/1120/1063 1040/1128/1063 1036/1119/1063 +f 1042/1122/1063 1041/1121/1063 1040/1123/1063 +f 967/1072/1063 969/1071/1063 1041/1073/1063 +f 1019/1075/1074 1017/1069/1074 967/1072/1074 +f 1032/1097/1079 996/1099/1079 999/1098/1079 +f 1001/1092/1074 1003/1093/1074 1020/1084/1074 +f 1014/1112/1073 1016/1111/1073 1006/1108/1073 +o Cube.017 +v 0.000000 0.553164 0.122282 +v -0.014040 0.553164 0.131086 +v 0.014040 0.553164 0.131086 +v 0.000000 0.557203 0.124255 +v 0.013119 0.557203 0.132482 +v -0.013119 0.557203 0.132482 +v 0.000000 0.557203 0.126696 +v 0.000000 0.569280 0.130155 +v 0.011979 0.557203 0.134208 +v -0.011979 0.557203 0.134208 +v -0.010363 0.569280 0.136654 +v -0.016940 0.557203 0.152343 +v -0.014655 0.569280 0.152343 +v -0.018553 0.557203 0.152343 +v -0.011979 0.557203 0.170478 +v -0.013119 0.557203 0.172203 +v -0.010363 0.569280 0.168032 +v 0.000000 0.557203 0.177989 +v 0.000000 0.557203 0.180430 +v 0.000000 0.569280 0.174530 +v 0.011979 0.557203 0.170478 +v 0.010363 0.569280 0.168032 +v 0.013119 0.557203 0.172203 +v 0.016940 0.557203 0.152343 +v 0.018553 0.557203 0.152343 +v 0.014656 0.569280 0.152343 +v 0.010363 0.569280 0.136654 +v 0.000000 0.569280 0.152343 +v 0.019856 0.553164 0.152343 +v 0.014040 0.553164 0.173599 +v 0.000000 0.553164 0.182404 +v -0.014040 0.553164 0.173599 +v -0.019856 0.553164 0.152343 +vn -0.4909 0.3824 -0.7828 +vn 0.4909 0.3824 -0.7828 +vn -0.0000 1.0000 -0.0000 +vn 0.5163 0.2358 -0.8233 +vn -0.5163 0.2358 -0.8233 +vn -0.9489 0.1795 -0.2596 +vn -0.9489 0.1795 0.2596 +vn -0.5163 0.2358 0.8233 +vn 0.5163 0.2358 0.8233 +vn 0.9489 0.1795 0.2596 +vn 0.9489 0.1795 -0.2596 +vn 0.9210 0.2972 0.2520 +vn 0.9210 0.2972 -0.2520 +vn 0.4909 0.3824 0.7828 +vn -0.4909 0.3824 0.7828 +vn -0.9210 0.2972 0.2520 +vn -0.9210 0.2972 -0.2520 +vt 0.502362 0.919267 +vt 0.212969 0.920779 +vt 0.511650 0.999904 +vt 0.075282 0.666237 +vt 0.000096 0.696826 +vt 0.249032 0.859912 +vt 0.075282 0.666237 +vt 0.300053 0.574789 +vt 0.474595 0.678198 +vt 0.838265 0.722766 +vt 0.580648 0.570137 +vt 0.849253 0.333763 +vt 0.849253 0.333763 +vt 0.675503 0.140088 +vt 0.624482 0.425210 +vt 0.422174 0.080733 +vt 0.422174 0.080733 +vt 0.449942 0.321802 +vt 0.343889 0.429863 +vt 0.086270 0.277234 +vt 0.086270 0.277234 +vt 0.462268 0.500000 +vt 0.356842 0.677946 +vt 0.567694 0.322055 +vt 0.412885 0.000096 +vt 0.000096 0.226179 +vt 0.711565 0.079221 +vt 0.924438 0.303174 +vt 0.924438 0.773821 +s 0 +usemtl Geometric_Brass_Engraved_Pattern +f 1051/1135/1086 1071/1137/1086 1053/1136/1086 +f 1055/1138/1087 1051/1135/1087 1054/1130/1087 +f 1057/1140/1088 1054/1130/1088 1056/1139/1088 +f 1059/1141/1089 1057/1140/1089 1056/1139/1089 +f 1062/1143/1090 1061/1144/1090 1059/1141/1090 +f 1066/1147/1091 1062/1143/1091 1065/1145/1091 +f 1070/1148/1092 1065/1145/1092 1068/1149/1092 +f 1053/1136/1093 1070/1148/1093 1068/1149/1093 +f 1070/1148/1085 1072/1151/1085 1066/1147/1085 +f 1071/1137/1085 1072/1151/1085 1070/1148/1085 +f 1052/1152/1085 1072/1151/1085 1071/1137/1085 +f 1055/1138/1085 1072/1151/1085 1052/1152/1085 +f 1064/1153/1085 1072/1151/1085 1061/1144/1085 +f 1066/1147/1085 1072/1151/1085 1064/1153/1085 +f 1057/1140/1085 1072/1151/1085 1055/1138/1085 +f 1061/1144/1085 1072/1151/1085 1057/1140/1085 +f 1051/1135/1086 1052/1152/1086 1071/1137/1086 +f 1055/1138/1087 1052/1152/1087 1051/1135/1087 +f 1057/1140/1088 1055/1138/1088 1054/1130/1088 +f 1059/1141/1089 1061/1144/1089 1057/1140/1089 +f 1062/1143/1090 1064/1153/1090 1061/1144/1090 +f 1066/1147/1091 1064/1153/1091 1062/1143/1091 +f 1070/1148/1092 1066/1147/1092 1065/1145/1092 +f 1053/1136/1093 1071/1137/1093 1070/1148/1093 +usemtl Brass.001 +f 1050/1130/1083 1045/1131/1083 1046/1132/1083 +f 1045/1131/1084 1049/1133/1084 1047/1134/1084 +f 1048/1135/1085 1053/1136/1085 1049/1133/1085 +f 1054/1130/1085 1048/1135/1085 1050/1130/1085 +f 1056/1139/1085 1050/1130/1085 1058/1139/1085 +f 1060/1142/1085 1056/1139/1085 1058/1139/1085 +f 1063/1143/1085 1059/1141/1085 1060/1142/1085 +f 1065/1145/1085 1063/1143/1085 1067/1146/1085 +f 1068/1149/1085 1067/1146/1085 1069/1150/1085 +f 1049/1133/1085 1068/1149/1085 1069/1150/1085 +f 1069/1150/1094 1074/1154/1094 1073/1155/1094 +f 1047/1134/1095 1069/1150/1095 1073/1155/1095 +f 1067/1146/1096 1075/1156/1096 1074/1154/1096 +f 1075/1156/1097 1060/1142/1097 1076/1157/1097 +f 1076/1157/1098 1058/1139/1098 1077/1158/1098 +f 1058/1139/1099 1046/1132/1099 1077/1158/1099 +f 1050/1130/1083 1048/1135/1083 1045/1131/1083 +f 1045/1131/1084 1048/1135/1084 1049/1133/1084 +f 1048/1135/1085 1051/1135/1085 1053/1136/1085 +f 1054/1130/1085 1051/1135/1085 1048/1135/1085 +f 1056/1139/1085 1054/1130/1085 1050/1130/1085 +f 1060/1142/1085 1059/1141/1085 1056/1139/1085 +f 1063/1143/1085 1062/1143/1085 1059/1141/1085 +f 1065/1145/1085 1062/1143/1085 1063/1143/1085 +f 1068/1149/1085 1065/1145/1085 1067/1146/1085 +f 1049/1133/1085 1053/1136/1085 1068/1149/1085 +f 1069/1150/1094 1067/1146/1094 1074/1154/1094 +f 1047/1134/1095 1049/1133/1095 1069/1150/1095 +f 1067/1146/1096 1063/1143/1096 1075/1156/1096 +f 1075/1156/1097 1063/1143/1097 1060/1142/1097 +f 1076/1157/1098 1060/1142/1098 1058/1139/1098 +f 1058/1139/1099 1050/1130/1099 1046/1132/1099 +o Cube.018 +v 0.025783 0.550671 0.058633 +v 0.025783 0.667936 0.058633 +v 0.000000 0.550671 0.058633 +v 0.000000 0.550671 0.121818 +v 0.019316 0.550671 0.017213 +v 0.019316 0.667936 0.017213 +v 0.000000 0.550671 0.017213 +v 0.019316 0.550671 -0.000565 +v 0.019316 0.550671 -0.058633 +v 0.019316 0.667936 -0.000565 +v 0.000000 0.550671 -0.000565 +v -0.000000 0.550671 -0.058633 +v -0.019316 0.550671 -0.000565 +v -0.019316 0.550671 -0.058633 +v -0.019316 0.550671 0.017213 +v -0.019316 0.667936 -0.000565 +v -0.019316 0.667936 0.017213 +v -0.019316 0.667936 -0.058633 +v -0.019316 0.953599 -0.016506 +v -0.019316 0.953599 0.003502 +v -0.019316 0.953599 -0.081856 +v -0.019316 1.441523 -0.040524 +v -0.019316 1.444128 -0.013817 +v -0.019316 1.433015 -0.127755 +v -0.019316 1.855349 -0.100881 +v -0.019316 1.874354 -0.070983 +v -0.019316 1.793271 -0.198536 +v -0.019316 1.948604 -0.128265 +v -0.019316 1.968110 -0.098286 +v -0.019316 1.884892 -0.226184 +v -0.019316 2.072556 -0.181420 +v -0.019316 2.097684 -0.153605 +v -0.019316 1.990481 -0.272272 +v -0.019316 2.189436 -0.248720 +v -0.019316 2.218020 -0.227400 +v -0.019316 2.096069 -0.318359 +v 0.000000 2.189436 -0.248720 +v 0.000000 2.218020 -0.227400 +v 0.000000 2.096069 -0.318359 +v 0.019316 2.189436 -0.248720 +v 0.019316 2.218020 -0.227400 +v 0.019316 2.096069 -0.318359 +v 0.019316 2.072556 -0.181420 +v 0.019316 2.097684 -0.153605 +v 0.019316 1.990481 -0.272272 +v 0.019316 1.948604 -0.128265 +v 0.019316 1.968110 -0.098286 +v 0.019316 1.884892 -0.226184 +v 0.019316 1.855349 -0.100881 +v 0.019316 1.874354 -0.070983 +v 0.019316 1.793271 -0.198536 +v 0.019316 1.441523 -0.040524 +v 0.019316 1.444128 -0.013817 +v 0.019316 1.433015 -0.127755 +v 0.019316 0.953599 -0.016506 +v 0.019316 0.953599 0.003502 +v 0.019316 0.953599 -0.081856 +v 0.000000 0.953599 -0.081856 +v 0.019316 0.667936 -0.058633 +v 0.000000 0.667936 -0.058633 +v 0.000000 1.433015 -0.127755 +v 0.000000 1.793271 -0.198536 +v 0.000000 1.884892 -0.226184 +v 0.000000 1.990481 -0.272272 +v 0.025783 0.953599 0.050116 +v 0.025783 1.450198 0.048404 +v 0.000000 0.954651 0.121818 +v 0.000000 0.668879 0.121818 +v 0.000000 1.448829 0.121818 +v -0.025783 0.953599 0.050116 +v -0.025783 0.667936 0.058633 +v -0.025783 1.450198 0.048404 +v -0.025783 1.918634 -0.001326 +v -0.025783 2.013555 -0.028440 +v 0.000000 1.927957 0.105368 +v 0.025783 1.918634 -0.001326 +v 0.000000 2.033326 0.081542 +v 0.025783 2.013555 -0.028440 +v 0.000000 2.188759 0.025373 +v 0.000000 2.408869 -0.126955 +v 0.025783 2.156228 -0.088800 +v -0.025783 2.156228 -0.088800 +v -0.025783 2.284618 -0.177727 +v 0.000000 2.284618 -0.177727 +v 0.025783 2.284618 -0.177727 +v -0.025783 0.550671 0.058633 +vn 0.9259 -0.0000 0.3778 +vn 0.9973 -0.0012 -0.0740 +vn 0.9616 -0.2299 -0.1501 +vn 0.9353 -0.3470 -0.0688 +vn -0.0000 -1.0000 -0.0000 +vn 1.0000 -0.0000 -0.0000 +vn 0.9566 -0.2915 -0.0000 +vn -0.0000 -0.7071 -0.7071 +vn 0.9587 -0.0115 -0.2843 +vn 0.9184 -0.2798 -0.2798 +vn -0.9566 -0.2914 -0.0000 +vn -0.9184 -0.2798 -0.2798 +vn -0.9587 -0.0115 -0.2843 +vn -0.9353 -0.3470 -0.0688 +vn -1.0000 -0.0000 -0.0000 +vn -0.9978 -0.0027 -0.0657 +vn -0.9973 -0.0012 -0.0740 +vn -0.9570 -0.0256 -0.2891 +vn -0.9986 -0.0035 -0.0522 +vn -0.9591 -0.0682 -0.2746 +vn -0.9591 -0.0408 -0.2800 +vn -0.9990 -0.0076 -0.0433 +vn -0.9596 -0.0971 -0.2640 +vn -0.9992 -0.0133 -0.0386 +vn -0.9566 -0.1166 -0.2671 +vn -0.9992 -0.0177 -0.0355 +vn -0.9566 0.1743 -0.2336 +vn -0.9297 0.0421 -0.3659 +vn -0.0000 0.5979 -0.8016 +vn -0.0000 0.1144 -0.9934 +vn 0.9420 0.1643 -0.2928 +vn 0.9566 0.1743 -0.2336 +vn 0.9297 0.0421 -0.3659 +vn 0.9992 -0.0177 -0.0355 +vn 0.9992 -0.0133 -0.0386 +vn 0.9566 -0.1166 -0.2671 +vn 0.9990 -0.0076 -0.0433 +vn 0.9596 -0.0971 -0.2640 +vn 0.9986 -0.0035 -0.0522 +vn 0.9591 -0.0682 -0.2746 +vn 0.9978 -0.0027 -0.0657 +vn 0.9570 -0.0256 -0.2891 +vn -0.0000 -0.0405 -0.9992 +vn -0.0000 -0.0882 -0.9961 +vn 0.9591 -0.0408 -0.2800 +vn -0.0000 -0.1442 -0.9895 +vn -0.0000 -0.2411 -0.9705 +vn -0.0000 -0.3451 -0.9386 +vn -0.0000 -0.4000 -0.9165 +vn 0.9906 -0.0054 -0.1368 +vn 0.9880 -0.0023 -0.1543 +vn 0.9948 -0.0069 -0.1018 +vn 0.9410 -0.0000 0.3384 +vn -0.9410 0.0101 0.3382 +vn -0.9435 0.0011 0.3314 +vn -0.9906 -0.0054 -0.1368 +vn -0.9880 -0.0023 -0.1543 +vn -0.9948 -0.0069 -0.1018 +vn -0.9722 0.0247 0.2328 +vn -0.9965 -0.0175 -0.0812 +vn -0.9741 0.0620 0.2172 +vn 0.9434 0.0114 0.3315 +vn 0.9717 0.0521 0.2303 +vn 0.9737 0.0775 0.2143 +vn -0.9769 0.0833 0.1969 +vn -0.9747 0.1273 0.1838 +vn 0.9747 0.1273 0.1838 +vn -0.9968 -0.0271 -0.0746 +vn -0.9970 -0.0369 -0.0680 +vn -0.9420 0.1643 -0.2928 +vn -0.0000 0.4920 -0.8706 +vn -0.8503 0.2102 -0.4826 +vn -0.0000 0.3783 -0.9257 +vn 0.8503 0.2102 -0.4826 +vn 0.9970 -0.0369 -0.0680 +vn 0.9968 -0.0271 -0.0746 +vn 0.9965 -0.0175 -0.0812 +vn -0.9259 -0.0000 0.3778 +vn -0.9616 -0.2299 -0.1501 +vn 0.9410 0.0101 0.3382 +vn 0.9435 0.0011 0.3314 +vn -0.9410 -0.0000 0.3384 +vn -0.9434 0.0114 0.3315 +vn -0.9717 0.0521 0.2303 +vn 0.9722 0.0247 0.2328 +vn 0.9741 0.0620 0.2172 +vn 0.9769 0.0833 0.1969 +vn -0.9737 0.0775 0.2143 +vn -0.9747 0.1272 0.1838 +vn 0.9747 0.1272 0.1838 +vt 0.625000 0.750000 +vt 0.375000 0.750000 +vt 0.625000 0.661697 +vt 0.375000 0.661697 +vt 0.249681 0.750000 +vt 0.125000 0.750000 +vt 0.249681 0.661697 +vt 0.625000 0.623796 +vt 0.375000 0.623796 +vt 0.249681 0.623796 +vt 0.249681 0.500000 +vt 0.625000 0.500000 +vt 0.375000 0.500000 +vt 0.625000 0.623796 +vt 0.625000 0.623796 +vt 0.625000 0.623796 +vt 0.625000 0.623796 +vt 0.625000 0.500000 +vt 0.625000 0.661697 +vt 0.750319 0.661697 +vt 0.750319 0.623796 +vt 0.750319 0.500000 +vt 0.625000 0.661697 +vt 0.625000 0.374681 +vt 0.375000 0.374681 +vt 0.625000 0.374681 +vt 0.625000 0.750000 +vt 0.625000 0.750000 +vt 0.750319 0.750000 +s 0 +usemtl Brass.001 +f 1079/1159/1100 1081/1160/1100 1078/1160/1100 +f 1080/1163/1104 1078/1160/1104 1081/1164/1104 +f 1079/1159/1100 1144/1159/1100 1145/1159/1100 +f 1142/1159/1152 1146/1159/1152 1144/1159/1152 +f 1148/1159/1153 1144/1159/1153 1147/1159/1153 +f 1147/1159/1154 1146/1159/1154 1149/1159/1154 +f 1149/1159/1158 1152/1159/1158 1150/1159/1158 +f 1150/1159/1160 1154/1185/1160 1151/1185/1160 +f 1143/1159/1161 1152/1159/1161 1146/1159/1161 +f 1153/1159/1162 1154/1185/1162 1152/1159/1162 +f 1155/1185/1163 1156/1186/1163 1154/1185/1163 +f 1151/1185/1164 1156/1186/1164 1159/1186/1164 +f 1156/1186/1165 1160/1159/1165 1159/1186/1165 +f 1162/1159/1166 1156/1186/1166 1158/1186/1166 +s 1 +f 1160/1159/1171 1157/1159/1172 1161/1187/1170 +f 1162/1159/1173 1161/1187/1170 1157/1159/1172 +s 0 +f 1081/1160/1177 1148/1159/1177 1163/1160/1177 +f 1080/1163/1104 1081/1164/1104 1163/1160/1104 +f 1079/1159/1100 1145/1159/1100 1081/1160/1100 +f 1079/1159/1179 1142/1159/1179 1144/1159/1179 +f 1142/1159/1180 1143/1159/1180 1146/1159/1180 +f 1148/1159/1177 1145/1159/1177 1144/1159/1177 +f 1147/1159/1181 1144/1159/1181 1146/1159/1181 +f 1149/1159/1182 1146/1159/1182 1152/1159/1182 +f 1150/1159/1183 1152/1159/1183 1154/1185/1183 +f 1143/1159/1184 1153/1159/1184 1152/1159/1184 +f 1153/1159/1185 1155/1185/1185 1154/1185/1185 +f 1155/1185/1186 1158/1186/1186 1156/1186/1186 +f 1151/1185/1187 1154/1185/1187 1156/1186/1187 +f 1156/1186/1188 1157/1159/1188 1160/1159/1188 +f 1162/1159/1189 1157/1159/1189 1156/1186/1189 +f 1081/1160/1177 1145/1159/1177 1148/1159/1177 +s 1 +usemtl leihengblade +f 1083/1161/1101 1078/1160/1102 1082/1162/1103 +f 1082/1162/1103 1080/1163/1104 1084/1165/1104 +f 1087/1166/1105 1082/1162/1103 1085/1167/1106 +f 1088/1168/1104 1082/1162/1103 1084/1165/1104 +f 1089/1169/1107 1085/1167/1106 1088/1168/1104 +f 1136/1170/1108 1085/1167/1106 1086/1171/1109 +f 1084/1165/1104 1090/1167/1110 1088/1168/1104 +f 1088/1168/1104 1091/1171/1111 1089/1169/1107 +f 1090/1167/1110 1095/1170/1112 1091/1171/1111 +f 1092/1162/1113 1093/1166/1114 1090/1167/1110 +f 1097/1161/1115 1093/1166/1114 1094/1161/1116 +f 1096/1172/1114 1095/1170/1112 1093/1166/1114 +f 1097/1161/1115 1099/1173/1114 1096/1172/1114 +f 1099/1173/1114 1098/1170/1117 1096/1172/1114 +f 1100/1161/1118 1102/1172/1114 1099/1173/1114 +f 1099/1173/1114 1104/1170/1119 1101/1170/1120 +f 1103/1161/1121 1105/1174/1114 1102/1172/1114 +f 1102/1172/1114 1107/1170/1122 1104/1170/1119 +f 1106/1161/1123 1108/1175/1114 1105/1174/1114 +f 1105/1174/1114 1110/1176/1124 1107/1170/1122 +f 1109/1177/1125 1111/1172/1126 1108/1175/1114 +f 1108/1175/1114 1113/1170/1127 1110/1176/1124 +f 1111/1172/1126 1115/1178/1128 1114/1179/1128 +f 1113/1170/1127 1114/1179/1128 1116/1180/1129 +f 1114/1179/1128 1118/1181/1130 1117/1172/1131 +f 1116/1180/1129 1117/1172/1131 1119/1170/1132 +f 1121/1177/1133 1117/1172/1131 1118/1181/1130 +f 1120/1175/1105 1119/1170/1132 1117/1172/1131 +f 1124/1161/1134 1120/1175/1105 1121/1177/1133 +f 1123/1172/1105 1122/1176/1135 1120/1175/1105 +f 1127/1161/1136 1123/1172/1105 1124/1161/1134 +f 1126/1172/1105 1125/1170/1137 1123/1172/1105 +f 1130/1161/1138 1126/1172/1105 1127/1161/1136 +f 1129/1173/1105 1128/1170/1139 1126/1172/1105 +f 1133/1161/1140 1129/1173/1105 1130/1161/1138 +f 1134/1170/1141 1129/1173/1105 1132/1172/1105 +f 1087/1166/1105 1133/1161/1140 1083/1161/1101 +f 1136/1170/1108 1132/1172/1105 1087/1166/1105 +f 1137/1182/1142 1134/1170/1141 1136/1170/1108 +f 1135/1182/1143 1131/1170/1144 1134/1170/1141 +f 1089/1183/1107 1136/1170/1108 1086/1171/1109 +f 1095/1170/1112 1135/1182/1143 1137/1182/1142 +f 1091/1171/1111 1137/1182/1142 1089/1183/1107 +f 1098/1170/1117 1138/1182/1145 1135/1182/1143 +f 1138/1182/1145 1128/1170/1139 1131/1170/1144 +f 1101/1170/1120 1139/1182/1146 1138/1182/1145 +f 1139/1182/1146 1125/1170/1137 1128/1170/1139 +f 1104/1170/1119 1140/1182/1147 1139/1182/1146 +f 1140/1182/1147 1122/1176/1135 1125/1170/1137 +f 1107/1170/1122 1141/1184/1148 1140/1182/1147 +f 1141/1184/1148 1119/1170/1132 1122/1176/1135 +f 1110/1176/1124 1116/1182/1129 1141/1184/1148 +f 1083/1161/1101 1142/1159/1149 1079/1159/1150 +f 1142/1159/1149 1130/1161/1138 1143/1159/1151 +f 1147/1159/1155 1094/1161/1116 1148/1159/1156 +f 1147/1159/1155 1100/1161/1118 1097/1161/1115 +f 1149/1159/1157 1103/1161/1121 1100/1161/1118 +f 1150/1159/1159 1106/1161/1123 1103/1161/1121 +f 1151/1185/1167 1109/1177/1125 1106/1161/1123 +f 1159/1186/1168 1112/1181/1169 1109/1177/1125 +f 1112/1181/1169 1161/1187/1170 1115/1178/1128 +f 1118/1181/1130 1161/1187/1170 1162/1159/1173 +f 1158/1186/1174 1118/1181/1130 1162/1159/1173 +f 1155/1185/1175 1121/1177/1133 1158/1186/1174 +f 1153/1159/1176 1124/1161/1134 1155/1185/1175 +f 1143/1159/1151 1127/1161/1136 1153/1159/1176 +f 1163/1160/1178 1094/1161/1116 1092/1162/1113 +f 1080/1163/1104 1092/1162/1113 1084/1165/1104 +f 1083/1161/1101 1079/1159/1150 1078/1160/1102 +f 1082/1162/1103 1078/1160/1102 1080/1163/1104 +f 1087/1166/1105 1083/1161/1101 1082/1162/1103 +f 1088/1168/1104 1085/1167/1106 1082/1162/1103 +f 1089/1169/1107 1086/1171/1109 1085/1167/1106 +f 1136/1170/1108 1087/1166/1105 1085/1167/1106 +f 1084/1165/1104 1092/1162/1113 1090/1167/1110 +f 1088/1168/1104 1090/1167/1110 1091/1171/1111 +f 1090/1167/1110 1093/1166/1114 1095/1170/1112 +f 1092/1162/1113 1094/1161/1116 1093/1166/1114 +f 1097/1161/1115 1096/1172/1114 1093/1166/1114 +f 1096/1172/1114 1098/1170/1117 1095/1170/1112 +f 1097/1161/1115 1100/1161/1118 1099/1173/1114 +f 1099/1173/1114 1101/1170/1120 1098/1170/1117 +f 1100/1161/1118 1103/1161/1121 1102/1172/1114 +f 1099/1173/1114 1102/1172/1114 1104/1170/1119 +f 1103/1161/1121 1106/1161/1123 1105/1174/1114 +f 1102/1172/1114 1105/1174/1114 1107/1170/1122 +f 1106/1161/1123 1109/1177/1125 1108/1175/1114 +f 1105/1174/1114 1108/1175/1114 1110/1176/1124 +f 1109/1177/1125 1112/1181/1169 1111/1172/1126 +f 1108/1175/1114 1111/1172/1126 1113/1170/1127 +f 1111/1172/1126 1112/1181/1169 1115/1178/1128 +f 1113/1170/1127 1111/1172/1126 1114/1179/1128 +f 1114/1179/1128 1115/1178/1128 1118/1181/1130 +f 1116/1180/1129 1114/1179/1128 1117/1172/1131 +f 1121/1177/1133 1120/1175/1105 1117/1172/1131 +f 1120/1175/1105 1122/1176/1135 1119/1170/1132 +f 1124/1161/1134 1123/1172/1105 1120/1175/1105 +f 1123/1172/1105 1125/1170/1137 1122/1176/1135 +f 1127/1161/1136 1126/1172/1105 1123/1172/1105 +f 1126/1172/1105 1128/1170/1139 1125/1170/1137 +f 1130/1161/1138 1129/1173/1105 1126/1172/1105 +f 1129/1173/1105 1131/1170/1144 1128/1170/1139 +f 1133/1161/1140 1132/1172/1105 1129/1173/1105 +f 1134/1170/1141 1131/1170/1144 1129/1173/1105 +f 1087/1166/1105 1132/1172/1105 1133/1161/1140 +f 1136/1170/1108 1134/1170/1141 1132/1172/1105 +f 1137/1182/1142 1135/1182/1143 1134/1170/1141 +f 1135/1182/1143 1138/1182/1145 1131/1170/1144 +f 1089/1183/1107 1137/1182/1142 1136/1170/1108 +f 1095/1170/1112 1098/1170/1117 1135/1182/1143 +f 1091/1171/1111 1095/1170/1112 1137/1182/1142 +f 1098/1170/1117 1101/1170/1120 1138/1182/1145 +f 1138/1182/1145 1139/1182/1146 1128/1170/1139 +f 1101/1170/1120 1104/1170/1119 1139/1182/1146 +f 1139/1182/1146 1140/1182/1147 1125/1170/1137 +f 1104/1170/1119 1107/1170/1122 1140/1182/1147 +f 1140/1182/1147 1141/1184/1148 1122/1176/1135 +f 1107/1170/1122 1110/1176/1124 1141/1184/1148 +f 1141/1184/1148 1116/1182/1129 1119/1170/1132 +f 1110/1176/1124 1113/1170/1127 1116/1182/1129 +f 1083/1161/1101 1133/1161/1140 1142/1159/1149 +f 1142/1159/1149 1133/1161/1140 1130/1161/1138 +f 1147/1159/1155 1097/1161/1115 1094/1161/1116 +f 1147/1159/1155 1149/1159/1157 1100/1161/1118 +f 1149/1159/1157 1150/1159/1159 1103/1161/1121 +f 1150/1159/1159 1151/1185/1167 1106/1161/1123 +f 1151/1185/1167 1159/1186/1168 1109/1177/1125 +f 1159/1186/1168 1160/1159/1171 1112/1181/1169 +f 1112/1181/1169 1160/1159/1171 1161/1187/1170 +f 1118/1181/1130 1115/1178/1128 1161/1187/1170 +f 1158/1186/1174 1121/1177/1133 1118/1181/1130 +f 1155/1185/1175 1124/1161/1134 1121/1177/1133 +f 1153/1159/1176 1127/1161/1136 1124/1161/1134 +f 1143/1159/1151 1130/1161/1138 1127/1161/1136 +f 1163/1160/1178 1148/1159/1156 1094/1161/1116 +f 1080/1163/1104 1163/1160/1178 1092/1162/1113 +o Cube.019 +v -0.014631 0.787520 -0.119965 +v -0.027035 0.779232 -0.119965 +v 0.000000 0.790430 -0.119965 +v -0.014667 0.787606 -0.110090 +v -0.011146 0.779106 -0.129910 +v -0.020595 0.772792 -0.129910 +v 0.000000 0.781323 -0.129910 +v 0.011146 0.779106 -0.129910 +v 0.014631 0.787520 -0.119965 +v 0.020595 0.772792 -0.129910 +v 0.027035 0.779232 -0.119965 +v 0.026909 0.763343 -0.129910 +v 0.035323 0.766828 -0.119965 +v 0.029126 0.752197 -0.129910 +v 0.038233 0.752197 -0.119965 +v 0.026909 0.741051 -0.129910 +v 0.035323 0.737566 -0.119965 +v 0.020595 0.731602 -0.129910 +v 0.027035 0.725162 -0.119965 +v 0.011146 0.725288 -0.129910 +v 0.014631 0.716874 -0.119965 +v 0.000000 0.723071 -0.129910 +v 0.000000 0.713964 -0.119965 +v -0.011146 0.725288 -0.129910 +v -0.014631 0.716874 -0.119965 +v -0.020595 0.731602 -0.129910 +v -0.027035 0.725162 -0.119965 +v -0.026909 0.741051 -0.129910 +v -0.035323 0.737566 -0.119965 +v -0.029126 0.752197 -0.129910 +v -0.038233 0.752197 -0.119965 +v -0.026909 0.763343 -0.129910 +v -0.035323 0.766828 -0.119965 +v -0.035409 0.766864 -0.110090 +v -0.038076 0.767968 -0.103977 +v -0.038327 0.752197 -0.110090 +v -0.027101 0.779298 -0.110090 +v -0.029142 0.781339 -0.103977 +v -0.015772 0.790273 -0.103977 +v -0.029142 0.781339 0.019706 +v -0.028016 0.780213 0.019706 +v -0.038076 0.767968 0.019706 +v -0.015772 0.790273 0.019706 +v -0.015162 0.788801 0.019706 +v 0.000000 0.793410 0.019706 +v 0.015772 0.790273 0.019706 +v 0.000000 0.791817 0.019706 +v 0.000000 0.793410 -0.103977 +v 0.000000 0.790523 -0.110090 +v 0.015772 0.790273 -0.103977 +v 0.029142 0.781339 -0.103977 +v 0.014667 0.787606 -0.110090 +v 0.027101 0.779298 -0.110090 +v 0.035409 0.766864 -0.110090 +v 0.038076 0.767968 -0.103977 +v 0.038327 0.752197 -0.110090 +v 0.041213 0.752197 -0.103977 +v 0.035409 0.737530 -0.110090 +v 0.038076 0.736425 -0.103977 +v 0.027101 0.725096 -0.110090 +v 0.029142 0.723055 -0.103977 +v 0.014667 0.716788 -0.110090 +v 0.015772 0.714121 -0.103977 +v 0.000000 0.713870 -0.110090 +v 0.000000 0.710983 -0.103977 +v -0.014667 0.716788 -0.110090 +v -0.015772 0.714121 -0.103977 +v -0.027101 0.725096 -0.110090 +v -0.029142 0.723055 -0.103977 +v -0.035409 0.737530 -0.110090 +v -0.038076 0.736425 -0.103977 +v -0.041213 0.752197 -0.103977 +v -0.038076 0.736425 0.019706 +v -0.036605 0.737035 0.019706 +v -0.029142 0.723055 0.019706 +v -0.041213 0.752197 0.019706 +v -0.039621 0.752197 0.019706 +v -0.039621 0.752197 0.026483 +v -0.036605 0.767359 0.019706 +v -0.036605 0.767359 0.026483 +v -0.038076 0.767968 0.026483 +v -0.028016 0.780213 0.026483 +v -0.029142 0.781339 0.026483 +v -0.015162 0.788801 0.026483 +v -0.015772 0.790273 0.026483 +v 0.000000 0.791817 0.026483 +v 0.000000 0.793410 0.026483 +v 0.015162 0.788801 0.026483 +v 0.015772 0.790273 0.026483 +v 0.028016 0.780213 0.026483 +v 0.015162 0.788801 0.019706 +v 0.028016 0.780213 0.019706 +v 0.036605 0.767359 0.019706 +v 0.029142 0.781339 0.019706 +v 0.038076 0.767968 0.019706 +v 0.041213 0.752197 0.019706 +v 0.038076 0.736425 0.019706 +v 0.039621 0.752197 0.019706 +v 0.039621 0.752197 0.026483 +v 0.036605 0.737035 0.019706 +v 0.036605 0.737035 0.026483 +v 0.028016 0.724181 0.019706 +v 0.028016 0.724181 0.026483 +v 0.015162 0.715592 0.019706 +v 0.029142 0.723055 0.019706 +v 0.015772 0.714121 0.019706 +v 0.000000 0.710983 0.019706 +v -0.015772 0.714121 0.019706 +v 0.000000 0.712576 0.019706 +v 0.000000 0.712576 0.026483 +v -0.015162 0.715592 0.019706 +v -0.015162 0.715592 0.026483 +v -0.028016 0.724181 0.019706 +v -0.028016 0.724181 0.026483 +v -0.036605 0.737035 0.026483 +v -0.029142 0.723055 0.026483 +v -0.029142 0.723055 0.048805 +v -0.038076 0.736425 0.026483 +v -0.015772 0.714121 0.026483 +v -0.015772 0.714121 0.048805 +v 0.000000 0.710983 0.026483 +v 0.000000 0.710983 0.048805 +v 0.015772 0.714121 0.026483 +v 0.015772 0.714121 0.048805 +v 0.029142 0.723055 0.026483 +v 0.015162 0.715592 0.026483 +v 0.029142 0.723055 0.048805 +v 0.038076 0.736425 0.026483 +v 0.038076 0.736425 0.048805 +v 0.041213 0.752197 0.026483 +v 0.041213 0.752197 0.048805 +v 0.038076 0.767968 0.026483 +v 0.038076 0.767968 0.048805 +v 0.029142 0.781339 0.026483 +v 0.036605 0.767359 0.026483 +v 0.029142 0.781339 0.048805 +v 0.027609 0.779806 0.055286 +v 0.015772 0.790273 0.048805 +v 0.014942 0.788270 0.055286 +v 0.000000 0.793410 0.048805 +v 0.000000 0.791242 0.055286 +v -0.015772 0.790273 0.048805 +v -0.014942 0.788270 0.055286 +v -0.029142 0.781339 0.048805 +v -0.027609 0.779806 0.055286 +v -0.038076 0.767968 0.048805 +v -0.036073 0.767139 0.055286 +v -0.041213 0.752197 0.048805 +v -0.041213 0.752197 0.026483 +v -0.039045 0.752197 0.055286 +v -0.038076 0.736425 0.048805 +v -0.036073 0.737255 0.055286 +v -0.027609 0.724588 0.055286 +v -0.036073 0.737255 0.055286 +v -0.027609 0.724588 0.055286 +v -0.039045 0.752197 0.055286 +v -0.036073 0.767139 0.055286 +v -0.027609 0.779806 0.055286 +v -0.014942 0.788270 0.055286 +v 0.000000 0.791242 0.055286 +v 0.014942 0.788270 0.055286 +v 0.027609 0.779806 0.055286 +v 0.036073 0.767139 0.055286 +v 0.039045 0.752197 0.055286 +v 0.036073 0.767139 0.055286 +v 0.039045 0.752197 0.055286 +v 0.036073 0.737255 0.055286 +v 0.027609 0.724588 0.055286 +v 0.036073 0.737255 0.055286 +v 0.027609 0.724588 0.055286 +v 0.014942 0.716124 0.055286 +v 0.000000 0.713152 0.055286 +v 0.014942 0.716124 0.055286 +v 0.000000 0.713152 0.055286 +v -0.014942 0.716124 0.055286 +v -0.014942 0.716124 0.055286 +vn -0.3953 0.8464 -0.3568 +vn -0.7091 0.6233 -0.3296 +vn -0.0000 0.9321 -0.3621 +vn -0.3620 0.9053 -0.2221 +vn -0.1339 0.4019 -0.9059 +vn -0.2889 0.3467 -0.8924 +vn -0.0000 0.4157 -0.9095 +vn 0.1339 0.4018 -0.9059 +vn 0.3953 0.8464 -0.3568 +vn 0.2889 0.3467 -0.8924 +vn 0.7091 0.6233 -0.3296 +vn 0.4621 0.2268 -0.8574 +vn 0.9171 0.3102 -0.2505 +vn 0.5874 -0.0000 -0.8093 +vn 0.9835 -0.0000 -0.1810 +vn 0.4621 -0.2268 -0.8574 +vn 0.9171 -0.3102 -0.2505 +vn 0.2889 -0.3467 -0.8924 +vn 0.7091 -0.6233 -0.3296 +vn 0.1339 -0.4019 -0.9059 +vn 0.3953 -0.8464 -0.3568 +vn -0.0000 -0.4157 -0.9095 +vn -0.0000 -0.9322 -0.3621 +vn -0.1339 -0.4018 -0.9059 +vn -0.3953 -0.8464 -0.3568 +vn -0.2889 -0.3467 -0.8924 +vn -0.7091 -0.6233 -0.3296 +vn -0.4621 -0.2268 -0.8574 +vn -0.9171 -0.3102 -0.2505 +vn -0.5874 -0.0000 -0.8093 +vn -0.9835 -0.0000 -0.1810 +vn -0.4621 0.2268 -0.8574 +vn -0.9171 0.3102 -0.2505 +vn -0.9104 0.3614 -0.2012 +vn -0.9338 0.3102 -0.1781 +vn -0.9775 -0.0000 -0.2109 +vn -0.6851 0.6965 -0.2132 +vn -0.7350 0.6447 -0.2101 +vn -0.4089 0.8866 -0.2165 +vn -0.6058 0.5677 0.5574 +vn -0.5765 0.5402 0.6131 +vn -0.8822 0.3126 0.3521 +vn -0.2963 0.6869 0.6635 +vn -0.2843 0.6591 0.6962 +vn -0.0000 0.7202 0.6938 +vn 0.2963 0.6869 0.6635 +vn -0.0000 0.6930 0.7210 +vn -0.0000 0.9762 -0.2170 +vn -0.0000 0.9743 -0.2252 +vn 0.4088 0.8866 -0.2165 +vn 0.7350 0.6447 -0.2101 +vn 0.3620 0.9053 -0.2221 +vn 0.6851 0.6965 -0.2132 +vn 0.9104 0.3614 -0.2012 +vn 0.9338 0.3102 -0.1781 +vn 0.9775 -0.0000 -0.2109 +vn 0.9902 -0.0000 -0.1394 +vn 0.9104 -0.3614 -0.2012 +vn 0.9338 -0.3102 -0.1781 +vn 0.6851 -0.6965 -0.2132 +vn 0.7350 -0.6447 -0.2101 +vn 0.3620 -0.9053 -0.2221 +vn 0.4089 -0.8866 -0.2165 +vn -0.0000 -0.9743 -0.2252 +vn -0.0000 -0.9762 -0.2170 +vn -0.3620 -0.9053 -0.2221 +vn -0.4089 -0.8866 -0.2165 +vn -0.6851 -0.6965 -0.2132 +vn -0.7350 -0.6447 -0.2101 +vn -0.9104 -0.3614 -0.2012 +vn -0.9338 -0.3102 -0.1781 +vn -0.9902 -0.0000 -0.1394 +vn -0.8822 -0.3126 0.3521 +vn -0.8290 -0.2938 0.4759 +vn -0.6058 -0.5677 0.5574 +vn -0.9746 -0.0000 0.2240 +vn -0.8952 -0.0000 0.4457 +vn -0.8952 -0.0000 -0.4457 +vn -0.8290 0.2938 0.4759 +vn -0.8290 0.2938 -0.4759 +vn -0.8822 0.3126 -0.3521 +vn -0.5764 0.5402 -0.6131 +vn -0.6058 0.5677 -0.5574 +vn -0.2843 0.6591 -0.6962 +vn -0.2963 0.6869 -0.6635 +vn -0.0000 0.6930 -0.7210 +vn -0.0000 0.7202 -0.6938 +vn 0.2843 0.6591 -0.6962 +vn 0.2963 0.6869 -0.6636 +vn 0.5765 0.5402 -0.6131 +vn 0.2843 0.6591 0.6962 +vn 0.5764 0.5402 0.6131 +vn 0.8290 0.2938 0.4759 +vn 0.6058 0.5677 0.5574 +vn 0.8822 0.3126 0.3521 +vn 0.9746 -0.0000 0.2240 +vn 0.8822 -0.3126 0.3521 +vn 0.8952 -0.0000 0.4457 +vn 0.8952 -0.0000 -0.4457 +vn 0.8290 -0.2938 0.4759 +vn 0.8290 -0.2938 -0.4759 +vn 0.5765 -0.5402 0.6131 +vn 0.5765 -0.5402 -0.6131 +vn 0.2843 -0.6591 0.6962 +vn 0.6058 -0.5677 0.5574 +vn 0.2963 -0.6869 0.6636 +vn -0.0000 -0.7202 0.6938 +vn -0.2963 -0.6869 0.6636 +vn -0.0000 -0.6930 0.7210 +vn -0.0000 -0.6930 -0.7210 +vn -0.2843 -0.6591 0.6962 +vn -0.2843 -0.6591 -0.6962 +vn -0.5765 -0.5402 0.6131 +vn -0.5765 -0.5402 -0.6131 +vn -0.8290 -0.2938 -0.4759 +vn -0.6058 -0.5677 -0.5574 +vn -0.7397 -0.6542 0.1577 +vn -0.8822 -0.3126 -0.3521 +vn -0.2963 -0.6869 -0.6635 +vn -0.4090 -0.8984 0.1598 +vn -0.0000 -0.7202 -0.6938 +vn -0.0000 -0.9872 0.1598 +vn 0.2963 -0.6869 -0.6636 +vn 0.4090 -0.8984 0.1598 +vn 0.6058 -0.5677 -0.5574 +vn 0.2843 -0.6591 -0.6962 +vn 0.7397 -0.6542 0.1577 +vn 0.8822 -0.3126 -0.3521 +vn 0.9394 -0.3123 0.1414 +vn 0.9746 -0.0000 -0.2240 +vn 0.9932 -0.0000 0.1167 +vn 0.8822 0.3126 -0.3521 +vn 0.9394 0.3123 0.1414 +vn 0.6058 0.5677 -0.5574 +vn 0.8290 0.2938 -0.4759 +vn 0.7397 0.6542 0.1577 +vn 0.9721 0.2134 0.0970 +vn 0.4090 0.8984 0.1598 +vn 0.9639 0.2509 0.0897 +vn -0.0000 0.9872 0.1598 +vn 0.9557 0.2791 0.0934 +vn -0.4090 0.8984 0.1598 +vn 0.9455 0.3067 0.1097 +vn -0.7397 0.6542 0.1577 +vn 0.9270 0.3416 0.1552 +vn -0.9394 0.3123 0.1414 +vn 0.8642 0.3869 0.3216 +vn -0.9932 -0.0000 0.1167 +vn -0.9746 -0.0000 -0.2240 +vn 0.6455 -0.0000 0.7637 +vn -0.9394 -0.3123 0.1414 +vn 0.8642 -0.3869 0.3216 +vn 0.9270 -0.3415 0.1552 +vn 0.9702 -0.0000 0.2424 +vn 0.9623 -0.0000 0.2720 +vn 0.9820 -0.0000 0.1890 +vn 0.9702 -0.0000 0.2425 +vn 0.9602 -0.0000 0.2795 +vn 0.9597 -0.0000 0.2811 +vn 0.9821 0.1448 0.1203 +vn 0.9894 -0.0000 0.1450 +vn 0.9821 -0.1448 0.1203 +vn 0.9721 -0.2134 0.0970 +vn 0.9639 -0.2508 0.0897 +vn 0.9557 -0.2791 0.0934 +vn 0.9455 -0.3067 0.1097 +vn 0.9602 -0.0000 0.2794 +vt 0.661368 0.463977 +vt 0.605181 0.394819 +vt 0.586229 0.413771 +vt 0.671624 0.439216 +vt 0.630067 0.369933 +vt 0.750000 0.454806 +vt 0.685093 0.406700 +vt 0.750000 0.481607 +vt 0.814908 0.093300 +vt 0.593300 0.185093 +vt 0.814907 0.406700 +vt 0.750000 0.419611 +vt 0.828376 0.439216 +vt 0.869933 0.369933 +vt 0.894819 0.394819 +vt 0.906701 0.314908 +vt 0.939216 0.328376 +vt 0.919611 0.250000 +vt 0.939216 0.171624 +vt 0.954806 0.250000 +vt 0.894819 0.105181 +vt 0.906700 0.185093 +vt 0.828376 0.060784 +vt 0.869933 0.130067 +vt 0.750000 0.045194 +vt 0.685093 0.093300 +vt 0.750000 0.080389 +vt 0.671624 0.060784 +vt 0.630067 0.130067 +vt 0.605181 0.105181 +vt 0.560784 0.171624 +vt 0.580389 0.250000 +vt 0.560784 0.328376 +vt 0.545194 0.250000 +vt 0.593300 0.314907 +vt 0.536023 0.338632 +vt 0.518393 0.250000 +vt 0.580294 0.419706 +vt 0.528269 0.341844 +vt 0.510000 0.250000 +vt 0.658156 0.471731 +vt 0.187500 0.895448 +vt 0.125000 0.532007 +vt 0.187500 0.532007 +vt 0.125000 0.895448 +vt 0.062500 0.532007 +vt 0.125000 0.532007 +vt 0.062500 0.895448 +vt 0.000000 0.895448 +vt 0.062500 0.532007 +vt 0.937500 0.895448 +vt 1.000000 0.532007 +vt 1.000000 0.895448 +vt 0.750000 0.490000 +vt 0.838632 0.463977 +vt 0.841844 0.471731 +vt 0.913771 0.413771 +vt 0.937500 0.532007 +vt 0.875000 0.895448 +vt 0.875000 0.532007 +vt 0.919706 0.419706 +vt 0.963977 0.338632 +vt 0.971731 0.341844 +vt 0.981607 0.250000 +vt 0.963977 0.161368 +vt 0.971731 0.158156 +vt 0.990000 0.250000 +vt 0.913771 0.086229 +vt 0.919706 0.080294 +vt 0.838632 0.036023 +vt 0.841844 0.028269 +vt 0.750000 0.018393 +vt 0.750000 0.010000 +vt 0.661368 0.036023 +vt 0.658156 0.028269 +vt 0.586229 0.086229 +vt 0.580294 0.080294 +vt 0.536023 0.161368 +vt 0.528269 0.158156 +vt 0.375000 0.895448 +vt 0.312500 0.532007 +vt 0.375000 0.532007 +vt 0.312500 0.895448 +vt 0.250000 0.532007 +vt 0.312500 0.532007 +vt 0.250000 0.895448 +vt 0.250000 0.532007 +vt 0.187500 0.532007 +vt 0.250000 0.915363 +vt 0.125000 0.915363 +vt 0.187500 0.915363 +vt 0.062500 0.915363 +vt 0.000000 0.915363 +vt 1.000000 0.915363 +vt 0.937500 0.915363 +vt 0.875000 0.915363 +vt 0.812500 0.915363 +vt 0.812500 0.895448 +vt 0.875000 0.532007 +vt 0.812500 0.532007 +vt 0.750000 0.895448 +vt 0.812500 0.532007 +vt 0.750000 0.532007 +vt 0.687500 0.895448 +vt 0.750000 0.532007 +vt 0.687500 0.532007 +vt 0.750000 0.915363 +vt 0.687500 0.915363 +vt 0.625000 0.895448 +vt 0.625000 0.915363 +vt 0.562500 0.895448 +vt 0.625000 0.532007 +vt 0.687500 0.532007 +vt 0.562500 0.532007 +vt 0.625000 0.532007 +vt 0.500000 0.895448 +vt 0.500000 0.532007 +vt 0.562500 0.532007 +vt 0.437500 0.895448 +vt 0.437500 0.532007 +vt 0.500000 0.532007 +vt 0.562500 0.915363 +vt 0.500000 0.915363 +vt 0.437500 0.915363 +vt 0.375000 0.915363 +vt 0.312500 0.915363 +vt 0.437500 0.980957 +vt 0.375000 0.980957 +vt 0.500000 0.980957 +vt 0.562500 0.980957 +vt 0.625000 0.980957 +vt 0.687500 0.980957 +vt 0.750000 0.980957 +vt 0.875000 0.980957 +vt 0.937500 0.980957 +vt 0.875000 1.000000 +vt 0.812500 1.000000 +vt 0.812500 0.980957 +vt 1.000000 0.980957 +vt 0.937500 1.000000 +vt 0.062500 1.000000 +vt 0.000000 0.980957 +vt 0.062500 0.980957 +vt 0.125000 1.000000 +vt 0.125000 0.980957 +vt 0.187500 0.980957 +vt 0.187500 1.000000 +vt 0.250000 0.980957 +vt 0.250000 1.000000 +vt 0.312500 0.980957 +vt 0.312500 1.000000 +vt 0.375000 1.000000 +vt 0.080294 0.080294 +vt 0.419706 0.080294 +vt 0.419706 0.419706 +vt 0.000000 1.000000 +vt 1.000000 1.000000 +vt 0.750000 1.000000 +vt 0.687500 1.000000 +vt 0.625000 1.000000 +vt 0.562500 1.000000 +vt 0.500000 1.000000 +vt 0.437500 1.000000 +vt 0.375000 0.532007 +vt 0.437500 0.532007 +vt 0.000000 0.532007 +vt 0.937500 0.532007 +vt 0.341844 0.471731 +vt 0.250000 0.490000 +vt 0.158156 0.471731 +vt 0.080294 0.419706 +vt 0.028269 0.341844 +vt 0.010000 0.250000 +vt 0.028269 0.158156 +vt 0.158156 0.028269 +vt 0.250000 0.010000 +vt 0.341844 0.028269 +vt 0.471731 0.158156 +vt 0.490000 0.250000 +vt 0.471731 0.341844 +s 1 +usemtl Brass.001 +f 1167/1188/1193 1165/1189/1191 1200/1190/1226 +f 1164/1191/1190 1169/1192/1195 1165/1189/1191 +f 1166/1193/1192 1168/1194/1194 1164/1191/1190 +f 1212/1195/1238 1164/1191/1190 1167/1188/1193 +f 1183/1196/1209 1191/1197/1217 1168/1194/1194 +f 1166/1193/1192 1171/1198/1197 1170/1199/1196 +f 1172/1200/1198 1173/1201/1199 1171/1198/1197 +f 1174/1202/1200 1175/1203/1201 1173/1201/1199 +f 1176/1204/1202 1177/1205/1203 1175/1203/1201 +f 1180/1206/1206 1177/1205/1203 1178/1207/1204 +f 1182/1208/1208 1179/1209/1205 1180/1206/1206 +f 1184/1210/1210 1181/1211/1207 1182/1208/1208 +f 1186/1212/1212 1183/1196/1209 1184/1210/1210 +f 1186/1212/1212 1187/1213/1213 1185/1214/1211 +f 1188/1215/1214 1189/1216/1215 1187/1213/1213 +f 1190/1217/1216 1191/1197/1217 1189/1216/1215 +f 1192/1218/1218 1193/1219/1219 1191/1197/1217 +f 1196/1220/1222 1193/1219/1219 1194/1221/1220 +f 1165/1189/1191 1195/1222/1221 1196/1220/1222 +f 1197/1223/1223 1194/1221/1220 1199/1224/1225 +f 1200/1190/1226 1196/1220/1222 1197/1223/1223 +f 1201/1225/1227 1197/1223/1223 1198/1226/1224 +f 1198/1226/1224 1199/1224/1225 1235/1227/1261 +f 1202/1228/1228 1200/1190/1226 1201/1225/1227 +f 1211/1241/1237 1167/1188/1193 1202/1228/1228 +f 1211/1241/1237 1215/1242/1241 1212/1195/1238 +f 1213/1243/1239 1216/1244/1242 1215/1242/1241 +f 1212/1195/1238 1172/1200/1198 1166/1193/1192 +f 1215/1242/1241 1174/1202/1200 1172/1200/1198 +f 1216/1244/1242 1176/1204/1202 1174/1202/1200 +f 1214/1248/1240 1217/1249/1243 1216/1244/1242 +f 1217/1249/1243 1178/1207/1204 1176/1204/1202 +f 1218/1250/1244 1219/1251/1245 1217/1249/1243 +f 1221/1252/1247 1178/1207/1204 1219/1251/1245 +f 1222/1253/1248 1219/1251/1245 1220/1254/1246 +f 1223/1255/1249 1180/1206/1206 1221/1252/1247 +f 1224/1256/1250 1221/1252/1247 1222/1253/1248 +f 1225/1257/1251 1182/1208/1208 1223/1255/1249 +f 1226/1258/1252 1223/1255/1249 1224/1256/1250 +f 1227/1259/1253 1184/1210/1210 1225/1257/1251 +f 1228/1260/1254 1225/1257/1251 1226/1258/1252 +f 1227/1259/1253 1188/1215/1214 1186/1212/1212 +f 1228/1260/1254 1229/1261/1255 1227/1259/1253 +f 1229/1261/1255 1190/1217/1216 1188/1215/1214 +f 1230/1262/1256 1231/1263/1257 1229/1261/1255 +f 1231/1263/1257 1192/1218/1218 1190/1217/1216 +f 1232/1264/1258 1233/1265/1259 1231/1263/1257 +f 1233/1265/1259 1194/1221/1220 1192/1218/1218 +f 1234/1266/1260 1199/1224/1225 1233/1265/1259 +f 1237/1270/1263 1241/1276/1267 1240/1273/1266 +f 1241/1276/1267 1242/1229/1268 1240/1273/1266 +f 1242/1229/1268 1245/1277/1271 1204/1232/1230 +f 1204/1232/1230 1247/1279/1273 1207/1235/1233 +f 1247/1279/1273 1210/1236/1236 1207/1235/1233 +f 1210/1240/1236 1251/1282/1277 1254/1238/1280 +f 1251/1282/1277 1255/1246/1281 1254/1238/1280 +f 1255/1246/1281 1298/1284/1324 1256/1285/1282 +f 1256/1285/1282 1262/1294/1288 1261/1288/1287 +f 1262/1294/1288 1263/1291/1289 1261/1288/1287 +f 1264/1295/1290 1265/1296/1291 1263/1291/1289 +f 1266/1297/1292 1267/1298/1293 1265/1296/1291 +f 1289/1309/1315 1272/1303/1298 1267/1298/1293 +f 1273/1310/1299 1274/1306/1300 1272/1303/1298 +f 1275/1311/1301 1276/1267/1302 1274/1306/1300 +f 1277/1312/1303 1237/1270/1263 1276/1267/1302 +f 1301/1322/1327 1300/1323/1326 1299/1321/1325 +f 1299/1321/1325 1328/1324/1349 1296/1325/1322 +f 1303/1326/1329 1302/1327/1328 1301/1322/1327 +f 1306/1328/1332 1303/1329/1329 1305/1330/1331 +f 1308/1331/1334 1305/1330/1331 1307/1332/1333 +f 1310/1334/1336 1307/1332/1333 1309/1333/1335 +f 1313/1336/1339 1309/1333/1335 1311/1335/1337 +f 1314/1337/1340 1313/1336/1339 1311/1335/1337 +f 1280/1315/1306 1315/1338/1341 1314/1337/1340 +f 1315/1338/1341 1318/1339/1344 1317/1338/1343 +f 1313/1336/1339 1317/1338/1343 1319/1336/1345 +f 1318/1340/1344 1333/1341/1344 1325/1342/1344 +f 1310/1334/1336 1319/1336/1345 1320/1334/1346 +f 1308/1331/1334 1320/1334/1346 1321/1331/1344 +f 1306/1328/1332 1321/1331/1344 1322/1328/1347 +f 1304/1343/1330 1322/1328/1347 1323/1343/1348 +f 1302/1327/1328 1323/1344/1348 1324/1327/1347 +f 1300/1323/1326 1324/1327/1347 1325/1323/1344 +f 1328/1324/1349 1325/1323/1344 1326/1324/1346 +f 1329/1345/1350 1326/1324/1346 1327/1345/1345 +f 1296/1325/1322 1329/1345/1350 1294/1320/1320 +f 1330/1346/1351 1327/1345/1345 1332/1346/1346 +f 1329/1345/1350 1292/1319/1318 1294/1320/1320 +f 1331/1347/1352 1332/1346/1346 1333/1347/1344 +f 1330/1346/1351 1290/1318/1316 1292/1319/1318 +f 1336/1348/1353 1333/1347/1344 1334/1348/1347 +f 1337/1349/1354 1334/1348/1347 1335/1349/1348 +f 1331/1347/1352 1287/1317/1313 1290/1318/1316 +f 1336/1348/1353 1285/1316/1311 1287/1317/1313 +f 1338/1350/1355 1335/1349/1348 1339/1350/1356 +f 1285/1316/1311 1338/1350/1355 1283/1314/1309 +f 1316/1339/1342 1339/1350/1356 1318/1339/1344 +f 1283/1314/1309 1316/1339/1342 1280/1315/1306 +f 1167/1188/1193 1164/1191/1190 1165/1189/1191 +f 1164/1191/1190 1168/1194/1194 1169/1192/1195 +f 1166/1193/1192 1170/1199/1196 1168/1194/1194 +f 1212/1195/1238 1166/1193/1192 1164/1191/1190 +f 1168/1194/1194 1170/1199/1196 1171/1198/1197 +f 1171/1198/1197 1173/1201/1199 1175/1203/1201 +f 1175/1203/1201 1177/1205/1203 1179/1209/1205 +f 1179/1209/1205 1181/1211/1207 1183/1196/1209 +f 1183/1196/1209 1185/1214/1211 1187/1213/1213 +f 1187/1213/1213 1189/1216/1215 1191/1197/1217 +f 1191/1197/1217 1193/1219/1219 1195/1222/1221 +f 1195/1222/1221 1169/1192/1195 1168/1194/1194 +f 1168/1194/1194 1171/1198/1197 1175/1203/1201 +f 1175/1203/1201 1179/1209/1205 1183/1196/1209 +f 1183/1196/1209 1187/1213/1213 1191/1197/1217 +f 1191/1197/1217 1195/1222/1221 1168/1194/1194 +f 1168/1194/1194 1175/1203/1201 1183/1196/1209 +f 1166/1193/1192 1172/1200/1198 1171/1198/1197 +f 1172/1200/1198 1174/1202/1200 1173/1201/1199 +f 1174/1202/1200 1176/1204/1202 1175/1203/1201 +f 1176/1204/1202 1178/1207/1204 1177/1205/1203 +f 1180/1206/1206 1179/1209/1205 1177/1205/1203 +f 1182/1208/1208 1181/1211/1207 1179/1209/1205 +f 1184/1210/1210 1183/1196/1209 1181/1211/1207 +f 1186/1212/1212 1185/1214/1211 1183/1196/1209 +f 1186/1212/1212 1188/1215/1214 1187/1213/1213 +f 1188/1215/1214 1190/1217/1216 1189/1216/1215 +f 1190/1217/1216 1192/1218/1218 1191/1197/1217 +f 1192/1218/1218 1194/1221/1220 1193/1219/1219 +f 1196/1220/1222 1195/1222/1221 1193/1219/1219 +f 1165/1189/1191 1169/1192/1195 1195/1222/1221 +f 1197/1223/1223 1196/1220/1222 1194/1221/1220 +f 1200/1190/1226 1165/1189/1191 1196/1220/1222 +f 1201/1225/1227 1200/1190/1226 1197/1223/1223 +f 1198/1226/1224 1197/1223/1223 1199/1224/1225 +f 1202/1228/1228 1167/1188/1193 1200/1190/1226 +f 1211/1241/1237 1212/1195/1238 1167/1188/1193 +f 1211/1241/1237 1213/1243/1239 1215/1242/1241 +f 1213/1243/1239 1214/1248/1240 1216/1244/1242 +f 1212/1195/1238 1215/1242/1241 1172/1200/1198 +f 1215/1242/1241 1216/1244/1242 1174/1202/1200 +f 1216/1244/1242 1217/1249/1243 1176/1204/1202 +f 1214/1248/1240 1218/1250/1244 1217/1249/1243 +f 1217/1249/1243 1219/1251/1245 1178/1207/1204 +f 1218/1250/1244 1220/1254/1246 1219/1251/1245 +f 1221/1252/1247 1180/1206/1206 1178/1207/1204 +f 1222/1253/1248 1221/1252/1247 1219/1251/1245 +f 1223/1255/1249 1182/1208/1208 1180/1206/1206 +f 1224/1256/1250 1223/1255/1249 1221/1252/1247 +f 1225/1257/1251 1184/1210/1210 1182/1208/1208 +f 1226/1258/1252 1225/1257/1251 1223/1255/1249 +f 1227/1259/1253 1186/1212/1212 1184/1210/1210 +f 1228/1260/1254 1227/1259/1253 1225/1257/1251 +f 1227/1259/1253 1229/1261/1255 1188/1215/1214 +f 1228/1260/1254 1230/1262/1256 1229/1261/1255 +f 1229/1261/1255 1231/1263/1257 1190/1217/1216 +f 1230/1262/1256 1232/1264/1258 1231/1263/1257 +f 1231/1263/1257 1233/1265/1259 1192/1218/1218 +f 1232/1264/1258 1234/1266/1260 1233/1265/1259 +f 1233/1265/1259 1199/1224/1225 1194/1221/1220 +f 1234/1266/1260 1235/1227/1261 1199/1224/1225 +f 1237/1270/1263 1278/1313/1304 1241/1276/1267 +f 1241/1276/1267 1243/1278/1269 1242/1229/1268 +f 1242/1229/1268 1243/1278/1269 1245/1277/1271 +f 1204/1232/1230 1245/1277/1271 1247/1279/1273 +f 1247/1279/1273 1249/1280/1275 1210/1236/1236 +f 1210/1240/1236 1249/1281/1275 1251/1282/1277 +f 1251/1282/1277 1253/1283/1279 1255/1246/1281 +f 1255/1246/1281 1253/1283/1279 1298/1284/1324 +f 1256/1285/1282 1298/1284/1324 1262/1294/1288 +f 1262/1294/1288 1264/1295/1290 1263/1291/1289 +f 1264/1295/1290 1266/1297/1292 1265/1296/1291 +f 1266/1297/1292 1289/1309/1315 1267/1298/1293 +f 1289/1309/1315 1273/1310/1299 1272/1303/1298 +f 1273/1310/1299 1275/1311/1301 1274/1306/1300 +f 1275/1311/1301 1277/1312/1303 1276/1267/1302 +f 1277/1312/1303 1278/1313/1304 1237/1270/1263 +f 1301/1322/1327 1302/1327/1328 1300/1323/1326 +f 1299/1321/1325 1300/1323/1326 1328/1324/1349 +f 1303/1326/1329 1304/1344/1330 1302/1327/1328 +f 1306/1328/1332 1304/1343/1330 1303/1329/1329 +f 1308/1331/1334 1306/1328/1332 1305/1330/1331 +f 1310/1334/1336 1308/1331/1334 1307/1332/1333 +f 1313/1336/1339 1310/1334/1336 1309/1333/1335 +f 1314/1337/1340 1315/1338/1341 1313/1336/1339 +f 1280/1315/1306 1316/1339/1342 1315/1338/1341 +f 1315/1338/1341 1316/1339/1342 1318/1339/1344 +f 1313/1336/1339 1315/1338/1341 1317/1338/1343 +f 1325/1342/1344 1324/1355/1347 1323/1356/1348 +f 1323/1356/1348 1322/1357/1347 1321/1358/1344 +f 1321/1358/1344 1320/1359/1346 1319/1360/1345 +f 1319/1360/1345 1317/1361/1343 1318/1340/1344 +f 1318/1340/1344 1339/1362/1356 1335/1363/1348 +f 1335/1363/1348 1334/1364/1347 1333/1341/1344 +f 1333/1341/1344 1332/1365/1346 1327/1366/1345 +f 1327/1366/1345 1326/1367/1346 1325/1342/1344 +f 1325/1342/1344 1323/1356/1348 1321/1358/1344 +f 1321/1358/1344 1319/1360/1345 1318/1340/1344 +f 1318/1340/1344 1335/1363/1348 1333/1341/1344 +f 1333/1341/1344 1327/1366/1345 1325/1342/1344 +f 1325/1342/1344 1321/1358/1344 1318/1340/1344 +f 1310/1334/1336 1313/1336/1339 1319/1336/1345 +f 1308/1331/1334 1310/1334/1336 1320/1334/1346 +f 1306/1328/1332 1308/1331/1334 1321/1331/1344 +f 1304/1343/1330 1306/1328/1332 1322/1328/1347 +f 1302/1327/1328 1304/1344/1330 1323/1344/1348 +f 1300/1323/1326 1302/1327/1328 1324/1327/1347 +f 1328/1324/1349 1300/1323/1326 1325/1323/1344 +f 1329/1345/1350 1328/1324/1349 1326/1324/1346 +f 1296/1325/1322 1328/1324/1349 1329/1345/1350 +f 1330/1346/1351 1329/1345/1350 1327/1345/1345 +f 1329/1345/1350 1330/1346/1351 1292/1319/1318 +f 1331/1347/1352 1330/1346/1351 1332/1346/1346 +f 1330/1346/1351 1331/1347/1352 1290/1318/1316 +f 1336/1348/1353 1331/1347/1352 1333/1347/1344 +f 1337/1349/1354 1336/1348/1353 1334/1348/1347 +f 1331/1347/1352 1336/1348/1353 1287/1317/1313 +f 1336/1348/1353 1337/1349/1354 1285/1316/1311 +f 1338/1350/1355 1337/1349/1354 1335/1349/1348 +f 1285/1316/1311 1337/1349/1354 1338/1350/1355 +f 1316/1339/1342 1338/1350/1355 1339/1350/1356 +f 1283/1314/1309 1338/1350/1355 1316/1339/1342 +usemtl Floral_Engraved_Gold +f 1205/1229/1231 1201/1230/1227 1198/1231/1224 +f 1203/1232/1229 1202/1233/1228 1201/1234/1227 +f 1203/1232/1229 1242/1229/1268 1204/1232/1230 +f 1206/1235/1232 1204/1232/1230 1207/1235/1233 +f 1208/1236/1234 1207/1235/1233 1210/1236/1236 +f 1208/1236/1234 1202/1237/1228 1206/1235/1232 +f 1209/1238/1235 1211/1239/1237 1208/1240/1234 +f 1208/1240/1234 1254/1238/1280 1209/1238/1235 +f 1213/1245/1239 1257/1246/1283 1214/1247/1240 +f 1238/1267/1264 1234/1268/1260 1232/1269/1258 +f 1236/1270/1262 1235/1271/1261 1234/1272/1260 +f 1238/1267/1264 1237/1270/1263 1236/1270/1262 +f 1236/1270/1262 1240/1273/1266 1239/1273/1265 +f 1205/1229/1231 1240/1273/1266 1242/1229/1268 +f 1235/1274/1261 1205/1229/1231 1198/1275/1224 +f 1246/1277/1272 1243/1278/1269 1244/1278/1270 +f 1244/1278/1270 1241/1276/1267 1312/1276/1338 +f 1248/1279/1274 1245/1277/1271 1246/1277/1272 +f 1250/1280/1276 1247/1279/1273 1248/1279/1274 +f 1250/1281/1276 1251/1282/1277 1249/1281/1275 +f 1252/1282/1278 1253/1283/1279 1251/1282/1277 +f 1209/1238/1235 1255/1246/1281 1257/1246/1283 +f 1257/1246/1283 1256/1285/1282 1258/1285/1284 +f 1214/1286/1240 1258/1285/1284 1218/1287/1244 +f 1258/1285/1284 1261/1288/1287 1259/1288/1285 +f 1218/1289/1244 1259/1288/1285 1220/1290/1246 +f 1260/1291/1286 1261/1288/1287 1263/1291/1289 +f 1220/1292/1246 1260/1291/1286 1222/1293/1248 +f 1268/1296/1294 1263/1291/1289 1265/1296/1291 +f 1269/1298/1295 1265/1296/1291 1267/1298/1293 +f 1260/1291/1286 1224/1299/1250 1222/1300/1248 +f 1268/1296/1294 1226/1301/1252 1224/1302/1250 +f 1270/1303/1296 1267/1298/1293 1272/1303/1298 +f 1269/1298/1295 1228/1304/1254 1226/1305/1252 +f 1270/1303/1296 1274/1306/1300 1271/1306/1297 +f 1270/1303/1296 1230/1307/1256 1228/1308/1254 +f 1271/1306/1297 1276/1267/1302 1238/1267/1264 +f 1279/1312/1305 1278/1313/1304 1277/1312/1303 +f 1282/1311/1308 1277/1312/1303 1275/1311/1301 +f 1283/1314/1309 1279/1312/1305 1282/1311/1308 +f 1280/1315/1306 1281/1313/1307 1279/1312/1305 +f 1285/1316/1311 1282/1311/1308 1284/1310/1310 +f 1284/1310/1310 1275/1311/1301 1273/1310/1299 +f 1287/1317/1313 1284/1310/1310 1286/1309/1312 +f 1284/1310/1310 1289/1309/1315 1286/1309/1312 +f 1290/1318/1316 1286/1309/1312 1288/1297/1314 +f 1286/1309/1312 1266/1297/1292 1288/1297/1314 +f 1292/1319/1318 1288/1297/1314 1291/1295/1317 +f 1288/1297/1314 1264/1295/1290 1291/1295/1317 +f 1293/1294/1319 1292/1319/1318 1291/1295/1317 +f 1291/1295/1317 1262/1294/1288 1293/1294/1319 +f 1295/1284/1321 1294/1320/1320 1293/1294/1319 +f 1295/1284/1321 1262/1294/1288 1298/1284/1324 +f 1299/1321/1325 1295/1284/1321 1297/1283/1323 +f 1297/1283/1323 1298/1284/1324 1253/1283/1279 +f 1252/1282/1278 1299/1321/1325 1297/1283/1323 +f 1250/1281/1276 1301/1322/1327 1252/1282/1278 +f 1248/1279/1274 1303/1329/1329 1250/1280/1276 +f 1246/1277/1272 1305/1330/1331 1248/1279/1274 +f 1309/1333/1335 1246/1277/1272 1244/1278/1270 +f 1311/1335/1337 1244/1278/1270 1312/1276/1338 +f 1314/1337/1340 1312/1276/1338 1281/1313/1307 +f 1281/1313/1307 1241/1276/1267 1278/1313/1304 +f 1271/1306/1297 1232/1351/1258 1230/1352/1256 +f 1205/1229/1231 1203/1232/1229 1201/1230/1227 +f 1203/1232/1229 1206/1235/1232 1202/1233/1228 +f 1203/1232/1229 1205/1229/1231 1242/1229/1268 +f 1206/1235/1232 1203/1232/1229 1204/1232/1230 +f 1208/1236/1234 1206/1235/1232 1207/1235/1233 +f 1208/1236/1234 1211/1353/1237 1202/1237/1228 +f 1209/1238/1235 1213/1354/1239 1211/1239/1237 +f 1208/1240/1234 1210/1240/1236 1254/1238/1280 +f 1213/1245/1239 1209/1238/1235 1257/1246/1283 +f 1238/1267/1264 1236/1270/1262 1234/1268/1260 +f 1236/1270/1262 1239/1273/1265 1235/1271/1261 +f 1238/1267/1264 1276/1267/1302 1237/1270/1263 +f 1236/1270/1262 1237/1270/1263 1240/1273/1266 +f 1205/1229/1231 1239/1273/1265 1240/1273/1266 +f 1235/1274/1261 1239/1273/1265 1205/1229/1231 +f 1246/1277/1272 1245/1277/1271 1243/1278/1269 +f 1244/1278/1270 1243/1278/1269 1241/1276/1267 +f 1248/1279/1274 1247/1279/1273 1245/1277/1271 +f 1250/1280/1276 1249/1280/1275 1247/1279/1273 +f 1250/1281/1276 1252/1282/1278 1251/1282/1277 +f 1252/1282/1278 1297/1283/1323 1253/1283/1279 +f 1209/1238/1235 1254/1238/1280 1255/1246/1281 +f 1257/1246/1283 1255/1246/1281 1256/1285/1282 +f 1214/1286/1240 1257/1246/1283 1258/1285/1284 +f 1258/1285/1284 1256/1285/1282 1261/1288/1287 +f 1218/1289/1244 1258/1285/1284 1259/1288/1285 +f 1260/1291/1286 1259/1288/1285 1261/1288/1287 +f 1220/1292/1246 1259/1288/1285 1260/1291/1286 +f 1268/1296/1294 1260/1291/1286 1263/1291/1289 +f 1269/1298/1295 1268/1296/1294 1265/1296/1291 +f 1260/1291/1286 1268/1296/1294 1224/1299/1250 +f 1268/1296/1294 1269/1298/1295 1226/1301/1252 +f 1270/1303/1296 1269/1298/1295 1267/1298/1293 +f 1269/1298/1295 1270/1303/1296 1228/1304/1254 +f 1270/1303/1296 1272/1303/1298 1274/1306/1300 +f 1270/1303/1296 1271/1306/1297 1230/1307/1256 +f 1271/1306/1297 1274/1306/1300 1276/1267/1302 +f 1279/1312/1305 1281/1313/1307 1278/1313/1304 +f 1282/1311/1308 1279/1312/1305 1277/1312/1303 +f 1283/1314/1309 1280/1315/1306 1279/1312/1305 +f 1280/1315/1306 1314/1337/1340 1281/1313/1307 +f 1285/1316/1311 1283/1314/1309 1282/1311/1308 +f 1284/1310/1310 1282/1311/1308 1275/1311/1301 +f 1287/1317/1313 1285/1316/1311 1284/1310/1310 +f 1284/1310/1310 1273/1310/1299 1289/1309/1315 +f 1290/1318/1316 1287/1317/1313 1286/1309/1312 +f 1286/1309/1312 1289/1309/1315 1266/1297/1292 +f 1292/1319/1318 1290/1318/1316 1288/1297/1314 +f 1288/1297/1314 1266/1297/1292 1264/1295/1290 +f 1293/1294/1319 1294/1320/1320 1292/1319/1318 +f 1291/1295/1317 1264/1295/1290 1262/1294/1288 +f 1295/1284/1321 1296/1325/1322 1294/1320/1320 +f 1295/1284/1321 1293/1294/1319 1262/1294/1288 +f 1299/1321/1325 1296/1325/1322 1295/1284/1321 +f 1297/1283/1323 1295/1284/1321 1298/1284/1324 +f 1252/1282/1278 1301/1322/1327 1299/1321/1325 +f 1250/1281/1276 1303/1326/1329 1301/1322/1327 +f 1248/1279/1274 1305/1330/1331 1303/1329/1329 +f 1246/1277/1272 1307/1332/1333 1305/1330/1331 +f 1309/1333/1335 1307/1332/1333 1246/1277/1272 +f 1311/1335/1337 1309/1333/1335 1244/1278/1270 +f 1314/1337/1340 1311/1335/1337 1312/1276/1338 +f 1281/1313/1307 1312/1276/1338 1241/1276/1267 +f 1271/1306/1297 1238/1267/1264 1232/1351/1258 +o Cube.020 +v -0.014631 1.026110 -0.119965 +v -0.027035 1.017822 -0.119965 +v 0.000000 1.029020 -0.119965 +v -0.014667 1.026196 -0.110090 +v -0.011146 1.017696 -0.129910 +v -0.020595 1.011382 -0.129910 +v 0.000000 1.019913 -0.129910 +v 0.011146 1.017696 -0.129910 +v 0.014631 1.026110 -0.119965 +v 0.020595 1.011382 -0.129910 +v 0.027035 1.017822 -0.119965 +v 0.026909 1.001933 -0.129910 +v 0.035323 1.005418 -0.119965 +v 0.029126 0.990787 -0.129910 +v 0.038233 0.990787 -0.119965 +v 0.026909 0.979641 -0.129910 +v 0.035323 0.976156 -0.119965 +v 0.020595 0.970192 -0.129910 +v 0.027035 0.963752 -0.119965 +v 0.011146 0.963878 -0.129910 +v 0.014631 0.955464 -0.119965 +v 0.000000 0.961661 -0.129910 +v 0.000000 0.952554 -0.119965 +v -0.011146 0.963878 -0.129910 +v -0.014631 0.955464 -0.119965 +v -0.020595 0.970192 -0.129910 +v -0.027035 0.963752 -0.119965 +v -0.026909 0.979641 -0.129910 +v -0.035323 0.976156 -0.119965 +v -0.029126 0.990787 -0.129910 +v -0.038233 0.990787 -0.119965 +v -0.026909 1.001933 -0.129910 +v -0.035323 1.005418 -0.119965 +v -0.035409 1.005454 -0.110090 +v -0.038076 1.006559 -0.103977 +v -0.038327 0.990787 -0.110090 +v -0.027101 1.017888 -0.110090 +v -0.029142 1.019929 -0.103977 +v -0.015772 1.028863 -0.103977 +v -0.029142 1.019929 0.019706 +v -0.028016 1.018803 0.019706 +v -0.038076 1.006559 0.019706 +v -0.015772 1.028863 0.019706 +v -0.015162 1.027392 0.019706 +v 0.000000 1.032000 0.019706 +v 0.015772 1.028863 0.019706 +v 0.000000 1.030408 0.019706 +v 0.000000 1.032000 -0.103977 +v 0.000000 1.029114 -0.110090 +v 0.015772 1.028863 -0.103977 +v 0.029142 1.019929 -0.103977 +v 0.014667 1.026196 -0.110090 +v 0.027101 1.017888 -0.110090 +v 0.035409 1.005454 -0.110090 +v 0.038076 1.006559 -0.103977 +v 0.038327 0.990787 -0.110090 +v 0.041213 0.990787 -0.103977 +v 0.035409 0.976120 -0.110090 +v 0.038076 0.975015 -0.103977 +v 0.027101 0.963686 -0.110090 +v 0.029142 0.961645 -0.103977 +v 0.014667 0.955378 -0.110090 +v 0.015772 0.952711 -0.103977 +v 0.000000 0.952461 -0.110090 +v 0.000000 0.949574 -0.103977 +v -0.014667 0.955378 -0.110090 +v -0.015772 0.952711 -0.103977 +v -0.027101 0.963686 -0.110090 +v -0.029142 0.961645 -0.103977 +v -0.035409 0.976120 -0.110090 +v -0.038076 0.975015 -0.103977 +v -0.041213 0.990787 -0.103977 +v -0.038076 0.975015 0.019706 +v -0.036605 0.975625 0.019706 +v -0.029142 0.961645 0.019706 +v -0.041213 0.990787 0.019706 +v -0.039621 0.990787 0.019706 +v -0.039621 0.990787 0.026483 +v -0.036605 1.005949 0.019706 +v -0.036605 1.005949 0.026483 +v -0.038076 1.006559 0.026483 +v -0.028016 1.018803 0.026483 +v -0.029142 1.019929 0.026483 +v -0.015162 1.027392 0.026483 +v -0.015772 1.028863 0.026483 +v 0.000000 1.030408 0.026483 +v 0.000000 1.032000 0.026483 +v 0.015162 1.027392 0.026483 +v 0.015772 1.028863 0.026483 +v 0.028016 1.018803 0.026483 +v 0.015162 1.027392 0.019706 +v 0.028016 1.018803 0.019706 +v 0.036605 1.005949 0.019706 +v 0.029142 1.019929 0.019706 +v 0.038076 1.006559 0.019706 +v 0.041213 0.990787 0.019706 +v 0.038076 0.975015 0.019706 +v 0.039621 0.990787 0.019706 +v 0.039621 0.990787 0.026483 +v 0.036605 0.975625 0.019706 +v 0.036605 0.975625 0.026483 +v 0.028016 0.962771 0.019706 +v 0.028016 0.962771 0.026483 +v 0.015162 0.954183 0.019706 +v 0.029142 0.961645 0.019706 +v 0.015772 0.952711 0.019706 +v 0.000000 0.949574 0.019706 +v -0.015772 0.952711 0.019706 +v 0.000000 0.951167 0.019706 +v 0.000000 0.951167 0.026483 +v -0.015162 0.954183 0.019706 +v -0.015162 0.954183 0.026483 +v -0.028016 0.962771 0.019706 +v -0.028016 0.962771 0.026483 +v -0.036605 0.975625 0.026483 +v -0.029142 0.961645 0.026483 +v -0.029142 0.961645 0.048805 +v -0.038076 0.975015 0.026483 +v -0.015772 0.952711 0.026483 +v -0.015772 0.952711 0.048805 +v 0.000000 0.949574 0.026483 +v 0.000000 0.949574 0.048805 +v 0.015772 0.952711 0.026483 +v 0.015772 0.952711 0.048805 +v 0.029142 0.961645 0.026483 +v 0.015162 0.954183 0.026483 +v 0.029142 0.961645 0.048805 +v 0.038076 0.975015 0.026483 +v 0.038076 0.975015 0.048805 +v 0.041213 0.990787 0.026483 +v 0.041213 0.990787 0.048805 +v 0.038076 1.006559 0.026483 +v 0.038076 1.006559 0.048805 +v 0.029142 1.019929 0.026483 +v 0.036605 1.005949 0.026483 +v 0.029142 1.019929 0.048805 +v 0.027609 1.018396 0.055286 +v 0.015772 1.028863 0.048805 +v 0.014942 1.026860 0.055286 +v 0.000000 1.032000 0.048805 +v 0.000000 1.029832 0.055286 +v -0.015772 1.028863 0.048805 +v -0.014942 1.026860 0.055286 +v -0.029142 1.019929 0.048805 +v -0.027609 1.018396 0.055286 +v -0.038076 1.006559 0.048805 +v -0.036073 1.005729 0.055286 +v -0.041213 0.990787 0.048805 +v -0.041213 0.990787 0.026483 +v -0.039045 0.990787 0.055286 +v -0.038076 0.975015 0.048805 +v -0.036073 0.975845 0.055286 +v -0.027609 0.963178 0.055286 +v -0.036073 0.975845 0.055286 +v -0.027609 0.963178 0.055286 +v -0.039045 0.990787 0.055286 +v -0.036073 1.005729 0.055286 +v -0.027609 1.018396 0.055286 +v -0.014942 1.026860 0.055286 +v 0.000000 1.029832 0.055286 +v 0.014942 1.026860 0.055286 +v 0.027609 1.018396 0.055286 +v 0.036073 1.005729 0.055286 +v 0.039045 0.990787 0.055286 +v 0.036073 1.005729 0.055286 +v 0.039045 0.990787 0.055286 +v 0.036073 0.975845 0.055286 +v 0.027609 0.963178 0.055286 +v 0.036073 0.975845 0.055286 +v 0.027609 0.963178 0.055286 +v 0.014942 0.954714 0.055286 +v 0.000000 0.951742 0.055286 +v 0.014942 0.954714 0.055286 +v 0.000000 0.951742 0.055286 +v -0.014942 0.954714 0.055286 +v -0.014942 0.954714 0.055286 +vn -0.3953 0.8464 -0.3568 +vn -0.7091 0.6233 -0.3296 +vn -0.0000 0.9322 -0.3621 +vn -0.3620 0.9053 -0.2221 +vn -0.1339 0.4019 -0.9059 +vn -0.2889 0.3467 -0.8924 +vn -0.0000 0.4157 -0.9095 +vn 0.1339 0.4018 -0.9059 +vn 0.3953 0.8464 -0.3568 +vn 0.2889 0.3467 -0.8924 +vn 0.7091 0.6233 -0.3296 +vn 0.4621 0.2268 -0.8574 +vn 0.9171 0.3102 -0.2505 +vn 0.5874 -0.0000 -0.8093 +vn 0.9835 -0.0000 -0.1810 +vn 0.4621 -0.2268 -0.8574 +vn 0.9171 -0.3102 -0.2505 +vn 0.2889 -0.3467 -0.8924 +vn 0.7091 -0.6233 -0.3296 +vn 0.1339 -0.4019 -0.9059 +vn 0.3953 -0.8464 -0.3568 +vn -0.0000 -0.4157 -0.9095 +vn -0.0000 -0.9322 -0.3621 +vn -0.1339 -0.4018 -0.9059 +vn -0.3953 -0.8464 -0.3568 +vn -0.2889 -0.3467 -0.8924 +vn -0.7091 -0.6233 -0.3296 +vn -0.4621 -0.2268 -0.8574 +vn -0.9171 -0.3102 -0.2505 +vn -0.5874 -0.0000 -0.8093 +vn -0.9835 -0.0000 -0.1810 +vn -0.4621 0.2268 -0.8574 +vn -0.9171 0.3102 -0.2505 +vn -0.9104 0.3614 -0.2012 +vn -0.9338 0.3102 -0.1781 +vn -0.9775 -0.0000 -0.2109 +vn -0.6851 0.6965 -0.2132 +vn -0.7350 0.6447 -0.2101 +vn -0.4089 0.8866 -0.2165 +vn -0.6058 0.5677 0.5574 +vn -0.5765 0.5402 0.6131 +vn -0.8822 0.3126 0.3521 +vn -0.2963 0.6869 0.6636 +vn -0.2843 0.6591 0.6962 +vn -0.0000 0.7202 0.6938 +vn 0.2963 0.6869 0.6636 +vn -0.0000 0.6930 0.7210 +vn -0.0000 0.9762 -0.2170 +vn -0.0000 0.9743 -0.2252 +vn 0.4089 0.8866 -0.2165 +vn 0.7350 0.6447 -0.2101 +vn 0.3620 0.9053 -0.2221 +vn 0.6851 0.6965 -0.2132 +vn 0.9104 0.3614 -0.2012 +vn 0.9338 0.3102 -0.1781 +vn 0.9775 -0.0000 -0.2109 +vn 0.9902 -0.0000 -0.1394 +vn 0.9104 -0.3614 -0.2012 +vn 0.9338 -0.3102 -0.1781 +vn 0.6851 -0.6965 -0.2132 +vn 0.7350 -0.6447 -0.2101 +vn 0.3620 -0.9053 -0.2221 +vn 0.4089 -0.8866 -0.2165 +vn -0.0000 -0.9743 -0.2252 +vn -0.0000 -0.9762 -0.2170 +vn -0.3620 -0.9053 -0.2221 +vn -0.4089 -0.8866 -0.2165 +vn -0.6851 -0.6965 -0.2132 +vn -0.7350 -0.6447 -0.2101 +vn -0.9104 -0.3614 -0.2012 +vn -0.9338 -0.3102 -0.1781 +vn -0.9902 -0.0000 -0.1394 +vn -0.8822 -0.3126 0.3521 +vn -0.8290 -0.2938 0.4759 +vn -0.6058 -0.5677 0.5574 +vn -0.9746 -0.0000 0.2240 +vn -0.8952 -0.0000 0.4457 +vn -0.8952 -0.0000 -0.4457 +vn -0.8290 0.2938 0.4759 +vn -0.8290 0.2938 -0.4759 +vn -0.8822 0.3126 -0.3521 +vn -0.5765 0.5402 -0.6131 +vn -0.6058 0.5677 -0.5574 +vn -0.2843 0.6591 -0.6962 +vn -0.2963 0.6869 -0.6636 +vn -0.0000 0.6930 -0.7210 +vn -0.0000 0.7202 -0.6938 +vn 0.2843 0.6591 -0.6962 +vn 0.2963 0.6869 -0.6636 +vn 0.5765 0.5402 -0.6131 +vn 0.2843 0.6591 0.6962 +vn 0.5765 0.5402 0.6131 +vn 0.8290 0.2938 0.4759 +vn 0.6058 0.5677 0.5574 +vn 0.8822 0.3126 0.3521 +vn 0.9746 -0.0000 0.2240 +vn 0.8822 -0.3126 0.3521 +vn 0.8952 -0.0000 0.4457 +vn 0.8952 -0.0000 -0.4457 +vn 0.8290 -0.2938 0.4759 +vn 0.8290 -0.2938 -0.4759 +vn 0.5765 -0.5402 0.6131 +vn 0.5765 -0.5402 -0.6131 +vn 0.2843 -0.6591 0.6962 +vn 0.6058 -0.5677 0.5574 +vn 0.2963 -0.6869 0.6636 +vn -0.0000 -0.7202 0.6938 +vn -0.2963 -0.6869 0.6636 +vn -0.0000 -0.6930 0.7210 +vn -0.0000 -0.6930 -0.7210 +vn -0.2843 -0.6591 0.6962 +vn -0.2843 -0.6591 -0.6962 +vn -0.5765 -0.5402 0.6131 +vn -0.5765 -0.5402 -0.6131 +vn -0.8290 -0.2938 -0.4759 +vn -0.6058 -0.5677 -0.5574 +vn -0.7397 -0.6542 0.1577 +vn -0.8822 -0.3126 -0.3521 +vn -0.2963 -0.6869 -0.6636 +vn -0.4090 -0.8984 0.1598 +vn -0.0000 -0.7202 -0.6938 +vn -0.0000 -0.9872 0.1598 +vn 0.2963 -0.6869 -0.6636 +vn 0.4090 -0.8984 0.1598 +vn 0.6058 -0.5677 -0.5574 +vn 0.2843 -0.6591 -0.6962 +vn 0.7397 -0.6542 0.1577 +vn 0.8822 -0.3126 -0.3521 +vn 0.9394 -0.3123 0.1414 +vn 0.9746 -0.0000 -0.2240 +vn 0.9932 -0.0000 0.1167 +vn 0.8822 0.3126 -0.3521 +vn 0.9394 0.3123 0.1414 +vn 0.6058 0.5677 -0.5574 +vn 0.8290 0.2938 -0.4759 +vn 0.7397 0.6542 0.1577 +vn 0.9721 0.2134 0.0970 +vn 0.4090 0.8984 0.1598 +vn 0.9639 0.2509 0.0897 +vn -0.0000 0.9872 0.1598 +vn 0.9557 0.2791 0.0934 +vn -0.4090 0.8984 0.1598 +vn 0.9455 0.3067 0.1097 +vn -0.7397 0.6542 0.1577 +vn 0.9270 0.3416 0.1552 +vn -0.9394 0.3123 0.1414 +vn 0.8643 0.3868 0.3215 +vn -0.9932 -0.0000 0.1167 +vn -0.9746 -0.0000 -0.2240 +vn 0.6455 -0.0000 0.7637 +vn -0.9394 -0.3123 0.1414 +vn 0.8642 -0.3869 0.3216 +vn 0.9270 -0.3416 0.1552 +vn 0.9702 -0.0000 0.2424 +vn 0.9623 -0.0000 0.2720 +vn 0.9820 -0.0000 0.1890 +vn 0.9702 -0.0000 0.2425 +vn 0.9602 -0.0000 0.2795 +vn 0.9597 -0.0000 0.2811 +vn 0.9821 0.1448 0.1203 +vn 0.9894 -0.0000 0.1450 +vn 0.9821 -0.1448 0.1203 +vn 0.9721 -0.2134 0.0970 +vn 0.9638 -0.2509 0.0897 +vn 0.9557 -0.2791 0.0934 +vn 0.9455 -0.3067 0.1097 +vt 0.661368 0.463977 +vt 0.605181 0.394819 +vt 0.586229 0.413771 +vt 0.671624 0.439216 +vt 0.630067 0.369933 +vt 0.750000 0.454806 +vt 0.685093 0.406700 +vt 0.750000 0.481607 +vt 0.814908 0.093300 +vt 0.593300 0.185093 +vt 0.814907 0.406700 +vt 0.750000 0.419611 +vt 0.828376 0.439216 +vt 0.869933 0.369933 +vt 0.894819 0.394819 +vt 0.906701 0.314908 +vt 0.939216 0.328376 +vt 0.919611 0.250000 +vt 0.939216 0.171624 +vt 0.954806 0.250000 +vt 0.894819 0.105181 +vt 0.906700 0.185093 +vt 0.828376 0.060784 +vt 0.869933 0.130067 +vt 0.750000 0.045194 +vt 0.685093 0.093300 +vt 0.750000 0.080389 +vt 0.671624 0.060784 +vt 0.630067 0.130067 +vt 0.605181 0.105181 +vt 0.560784 0.171624 +vt 0.580389 0.250000 +vt 0.560784 0.328376 +vt 0.545194 0.250000 +vt 0.593300 0.314907 +vt 0.536023 0.338632 +vt 0.518393 0.250000 +vt 0.580294 0.419706 +vt 0.528269 0.341844 +vt 0.510000 0.250000 +vt 0.658156 0.471731 +vt 0.187500 0.532007 +vt 0.125000 0.895448 +vt 0.125000 0.532007 +vt 0.125000 0.532007 +vt 0.062500 0.895448 +vt 0.062500 0.532007 +vt 0.187500 0.895448 +vt 0.000000 0.895448 +vt 0.062500 0.532007 +vt 0.937500 0.895448 +vt 1.000000 0.532007 +vt 1.000000 0.895448 +vt 0.750000 0.490000 +vt 0.838632 0.463977 +vt 0.841844 0.471731 +vt 0.913771 0.413771 +vt 0.937500 0.532007 +vt 0.875000 0.895448 +vt 0.875000 0.532007 +vt 0.919706 0.419706 +vt 0.963977 0.338632 +vt 0.971731 0.341844 +vt 0.981607 0.250000 +vt 0.963977 0.161368 +vt 0.971731 0.158156 +vt 0.990000 0.250000 +vt 0.913771 0.086229 +vt 0.919706 0.080294 +vt 0.838632 0.036023 +vt 0.841844 0.028269 +vt 0.750000 0.018393 +vt 0.750000 0.010000 +vt 0.661368 0.036023 +vt 0.658156 0.028269 +vt 0.586229 0.086229 +vt 0.580294 0.080294 +vt 0.536023 0.161368 +vt 0.528269 0.158156 +vt 0.375000 0.895448 +vt 0.312500 0.532007 +vt 0.375000 0.532007 +vt 0.312500 0.532007 +vt 0.250000 0.895448 +vt 0.250000 0.532007 +vt 0.312500 0.895448 +vt 0.187500 0.532007 +vt 0.250000 0.532007 +vt 0.250000 0.915363 +vt 0.125000 0.915363 +vt 0.187500 0.915363 +vt 0.062500 0.915363 +vt 0.000000 0.915363 +vt 1.000000 0.915363 +vt 0.937500 0.915363 +vt 0.875000 0.915363 +vt 0.812500 0.915363 +vt 0.812500 0.895448 +vt 0.875000 0.532007 +vt 0.812500 0.532007 +vt 0.750000 0.895448 +vt 0.750000 0.532007 +vt 0.812500 0.532007 +vt 0.687500 0.895448 +vt 0.687500 0.532007 +vt 0.750000 0.532007 +vt 0.687500 0.915363 +vt 0.625000 0.895448 +vt 0.625000 0.915363 +vt 0.562500 0.895448 +vt 0.625000 0.532007 +vt 0.687500 0.532007 +vt 0.562500 0.532007 +vt 0.625000 0.532007 +vt 0.500000 0.895448 +vt 0.500000 0.532007 +vt 0.562500 0.532007 +vt 0.437500 0.895448 +vt 0.437500 0.532007 +vt 0.500000 0.532007 +vt 0.562500 0.915363 +vt 0.500000 0.915363 +vt 0.437500 0.915363 +vt 0.375000 0.915363 +vt 0.312500 0.915363 +vt 0.437500 0.980957 +vt 0.312500 0.980957 +vt 0.500000 0.980957 +vt 0.562500 0.980957 +vt 0.625000 0.980957 +vt 0.750000 0.915363 +vt 0.687500 0.980957 +vt 0.750000 0.980957 +vt 0.875000 0.980957 +vt 0.937500 0.980957 +vt 0.875000 1.000000 +vt 0.812500 1.000000 +vt 0.812500 0.980957 +vt 1.000000 0.980957 +vt 0.937500 1.000000 +vt 0.062500 1.000000 +vt 0.000000 0.980957 +vt 0.062500 0.980957 +vt 0.125000 1.000000 +vt 0.125000 0.980957 +vt 0.187500 1.000000 +vt 0.187500 0.980957 +vt 0.250000 0.980957 +vt 0.250000 1.000000 +vt 0.375000 0.980957 +vt 0.312500 1.000000 +vt 0.375000 1.000000 +vt 0.080294 0.080294 +vt 0.419706 0.080294 +vt 0.419706 0.419706 +vt 0.000000 1.000000 +vt 1.000000 1.000000 +vt 0.750000 1.000000 +vt 0.687500 1.000000 +vt 0.625000 1.000000 +vt 0.562500 1.000000 +vt 0.500000 1.000000 +vt 0.437500 1.000000 +vt 0.375000 0.532007 +vt 0.437500 0.532007 +vt 0.000000 0.532007 +vt 0.937500 0.532007 +vt 0.341844 0.471731 +vt 0.250000 0.490000 +vt 0.158156 0.471731 +vt 0.080294 0.419706 +vt 0.028269 0.341844 +vt 0.010000 0.250000 +vt 0.028269 0.158156 +vt 0.158156 0.028269 +vt 0.250000 0.010000 +vt 0.341844 0.028269 +vt 0.471731 0.158156 +vt 0.490000 0.250000 +vt 0.471731 0.341844 +s 1 +usemtl Brass.001 +f 1343/1368/1360 1341/1369/1358 1376/1370/1393 +f 1340/1371/1357 1345/1372/1362 1341/1369/1358 +f 1342/1373/1359 1344/1374/1361 1340/1371/1357 +f 1388/1375/1405 1340/1371/1357 1343/1368/1360 +f 1359/1376/1376 1367/1377/1384 1344/1374/1361 +f 1342/1373/1359 1347/1378/1364 1346/1379/1363 +f 1348/1380/1365 1349/1381/1366 1347/1378/1364 +f 1350/1382/1367 1351/1383/1368 1349/1381/1366 +f 1352/1384/1369 1353/1385/1370 1351/1383/1368 +f 1356/1386/1373 1353/1385/1370 1354/1387/1371 +f 1358/1388/1375 1355/1389/1372 1356/1386/1373 +f 1360/1390/1377 1357/1391/1374 1358/1388/1375 +f 1362/1392/1379 1359/1376/1376 1360/1390/1377 +f 1362/1392/1379 1363/1393/1380 1361/1394/1378 +f 1364/1395/1381 1365/1396/1382 1363/1393/1380 +f 1366/1397/1383 1367/1377/1384 1365/1396/1382 +f 1368/1398/1385 1369/1399/1386 1367/1377/1384 +f 1372/1400/1389 1369/1399/1386 1370/1401/1387 +f 1341/1369/1358 1371/1402/1388 1372/1400/1389 +f 1373/1403/1390 1370/1401/1387 1375/1404/1392 +f 1376/1370/1393 1372/1400/1389 1373/1403/1390 +f 1377/1405/1394 1373/1403/1390 1374/1406/1391 +f 1374/1406/1391 1375/1404/1392 1411/1407/1428 +f 1378/1408/1395 1376/1370/1393 1377/1405/1394 +f 1387/1421/1404 1343/1368/1360 1378/1408/1395 +f 1387/1421/1404 1391/1422/1408 1388/1375/1405 +f 1389/1423/1406 1392/1424/1409 1391/1422/1408 +f 1388/1375/1405 1348/1380/1365 1342/1373/1359 +f 1391/1422/1408 1350/1382/1367 1348/1380/1365 +f 1392/1424/1409 1352/1384/1369 1350/1382/1367 +f 1390/1428/1407 1393/1429/1410 1392/1424/1409 +f 1393/1429/1410 1354/1387/1371 1352/1384/1369 +f 1394/1430/1411 1395/1431/1412 1393/1429/1410 +f 1397/1432/1414 1354/1387/1371 1395/1431/1412 +f 1398/1433/1415 1395/1431/1412 1396/1434/1413 +f 1399/1435/1416 1356/1386/1373 1397/1432/1414 +f 1400/1436/1417 1397/1432/1414 1398/1433/1415 +f 1401/1437/1418 1358/1388/1375 1399/1435/1416 +f 1402/1438/1419 1399/1435/1416 1400/1436/1417 +f 1403/1439/1420 1360/1390/1377 1401/1437/1418 +f 1404/1440/1421 1401/1437/1418 1402/1438/1419 +f 1403/1439/1420 1364/1395/1381 1362/1392/1379 +f 1404/1440/1421 1405/1441/1422 1403/1439/1420 +f 1405/1441/1422 1366/1397/1383 1364/1395/1381 +f 1406/1442/1423 1407/1443/1424 1405/1441/1422 +f 1407/1443/1424 1368/1398/1385 1366/1397/1383 +f 1408/1444/1425 1409/1445/1426 1407/1443/1424 +f 1409/1445/1426 1370/1401/1387 1368/1398/1385 +f 1410/1446/1427 1375/1404/1392 1409/1445/1426 +f 1413/1453/1430 1417/1456/1434 1416/1451/1433 +f 1417/1456/1434 1418/1415/1435 1416/1451/1433 +f 1418/1415/1435 1421/1457/1438 1380/1410/1397 +f 1380/1410/1397 1423/1459/1440 1383/1413/1400 +f 1383/1413/1400 1425/1460/1442 1386/1416/1403 +f 1386/1420/1403 1427/1462/1444 1430/1418/1447 +f 1430/1418/1447 1429/1463/1446 1431/1426/1448 +f 1431/1426/1448 1474/1464/1491 1432/1465/1449 +f 1474/1464/1491 1437/1468/1454 1432/1465/1449 +f 1437/1468/1454 1440/1474/1457 1439/1471/1456 +f 1440/1474/1457 1441/1475/1458 1439/1471/1456 +f 1442/1476/1459 1443/1477/1460 1441/1475/1458 +f 1465/1488/1482 1448/1482/1465 1443/1477/1460 +f 1449/1489/1466 1450/1485/1467 1448/1482/1465 +f 1451/1490/1468 1452/1447/1469 1450/1485/1467 +f 1453/1491/1470 1413/1453/1430 1452/1447/1469 +f 1477/1502/1494 1476/1503/1493 1475/1501/1492 +f 1475/1501/1492 1504/1504/1516 1472/1505/1489 +f 1479/1506/1496 1478/1507/1495 1477/1502/1494 +f 1482/1508/1499 1479/1509/1496 1481/1510/1498 +f 1484/1511/1501 1481/1510/1498 1483/1512/1500 +f 1486/1513/1503 1483/1512/1500 1485/1514/1502 +f 1489/1516/1506 1485/1514/1502 1487/1515/1504 +f 1490/1494/1507 1489/1516/1506 1487/1515/1504 +f 1456/1517/1473 1491/1518/1508 1490/1494/1507 +f 1491/1518/1508 1494/1519/1511 1493/1518/1510 +f 1489/1516/1506 1493/1518/1510 1495/1516/1512 +f 1494/1520/1511 1509/1521/1511 1501/1522/1511 +f 1486/1513/1503 1495/1516/1512 1496/1513/1513 +f 1484/1511/1501 1496/1513/1513 1497/1511/1511 +f 1482/1508/1499 1497/1511/1511 1498/1508/1514 +f 1480/1523/1497 1498/1508/1514 1499/1523/1515 +f 1478/1507/1495 1499/1524/1515 1500/1507/1514 +f 1476/1503/1493 1500/1507/1514 1501/1503/1511 +f 1504/1504/1516 1501/1503/1511 1502/1504/1513 +f 1505/1525/1517 1502/1504/1513 1503/1525/1512 +f 1472/1505/1489 1505/1525/1517 1470/1500/1487 +f 1506/1526/1518 1503/1525/1512 1508/1526/1513 +f 1505/1525/1517 1468/1499/1485 1470/1500/1487 +f 1507/1527/1519 1508/1526/1513 1509/1527/1511 +f 1506/1526/1518 1466/1497/1483 1468/1499/1485 +f 1512/1528/1520 1509/1527/1511 1510/1528/1514 +f 1513/1529/1521 1510/1528/1514 1511/1529/1515 +f 1507/1527/1519 1463/1496/1480 1466/1497/1483 +f 1512/1528/1520 1461/1495/1478 1463/1496/1480 +f 1514/1530/1522 1511/1529/1515 1515/1530/1514 +f 1461/1495/1478 1514/1530/1522 1459/1493/1476 +f 1492/1519/1509 1515/1530/1514 1494/1519/1511 +f 1459/1493/1476 1492/1519/1509 1456/1517/1473 +f 1343/1368/1360 1340/1371/1357 1341/1369/1358 +f 1340/1371/1357 1344/1374/1361 1345/1372/1362 +f 1342/1373/1359 1346/1379/1363 1344/1374/1361 +f 1388/1375/1405 1342/1373/1359 1340/1371/1357 +f 1344/1374/1361 1346/1379/1363 1347/1378/1364 +f 1347/1378/1364 1349/1381/1366 1351/1383/1368 +f 1351/1383/1368 1353/1385/1370 1355/1389/1372 +f 1355/1389/1372 1357/1391/1374 1359/1376/1376 +f 1359/1376/1376 1361/1394/1378 1363/1393/1380 +f 1363/1393/1380 1365/1396/1382 1367/1377/1384 +f 1367/1377/1384 1369/1399/1386 1371/1402/1388 +f 1371/1402/1388 1345/1372/1362 1344/1374/1361 +f 1344/1374/1361 1347/1378/1364 1351/1383/1368 +f 1351/1383/1368 1355/1389/1372 1359/1376/1376 +f 1359/1376/1376 1363/1393/1380 1367/1377/1384 +f 1367/1377/1384 1371/1402/1388 1344/1374/1361 +f 1344/1374/1361 1351/1383/1368 1359/1376/1376 +f 1342/1373/1359 1348/1380/1365 1347/1378/1364 +f 1348/1380/1365 1350/1382/1367 1349/1381/1366 +f 1350/1382/1367 1352/1384/1369 1351/1383/1368 +f 1352/1384/1369 1354/1387/1371 1353/1385/1370 +f 1356/1386/1373 1355/1389/1372 1353/1385/1370 +f 1358/1388/1375 1357/1391/1374 1355/1389/1372 +f 1360/1390/1377 1359/1376/1376 1357/1391/1374 +f 1362/1392/1379 1361/1394/1378 1359/1376/1376 +f 1362/1392/1379 1364/1395/1381 1363/1393/1380 +f 1364/1395/1381 1366/1397/1383 1365/1396/1382 +f 1366/1397/1383 1368/1398/1385 1367/1377/1384 +f 1368/1398/1385 1370/1401/1387 1369/1399/1386 +f 1372/1400/1389 1371/1402/1388 1369/1399/1386 +f 1341/1369/1358 1345/1372/1362 1371/1402/1388 +f 1373/1403/1390 1372/1400/1389 1370/1401/1387 +f 1376/1370/1393 1341/1369/1358 1372/1400/1389 +f 1377/1405/1394 1376/1370/1393 1373/1403/1390 +f 1374/1406/1391 1373/1403/1390 1375/1404/1392 +f 1378/1408/1395 1343/1368/1360 1376/1370/1393 +f 1387/1421/1404 1388/1375/1405 1343/1368/1360 +f 1387/1421/1404 1389/1423/1406 1391/1422/1408 +f 1389/1423/1406 1390/1428/1407 1392/1424/1409 +f 1388/1375/1405 1391/1422/1408 1348/1380/1365 +f 1391/1422/1408 1392/1424/1409 1350/1382/1367 +f 1392/1424/1409 1393/1429/1410 1352/1384/1369 +f 1390/1428/1407 1394/1430/1411 1393/1429/1410 +f 1393/1429/1410 1395/1431/1412 1354/1387/1371 +f 1394/1430/1411 1396/1434/1413 1395/1431/1412 +f 1397/1432/1414 1356/1386/1373 1354/1387/1371 +f 1398/1433/1415 1397/1432/1414 1395/1431/1412 +f 1399/1435/1416 1358/1388/1375 1356/1386/1373 +f 1400/1436/1417 1399/1435/1416 1397/1432/1414 +f 1401/1437/1418 1360/1390/1377 1358/1388/1375 +f 1402/1438/1419 1401/1437/1418 1399/1435/1416 +f 1403/1439/1420 1362/1392/1379 1360/1390/1377 +f 1404/1440/1421 1403/1439/1420 1401/1437/1418 +f 1403/1439/1420 1405/1441/1422 1364/1395/1381 +f 1404/1440/1421 1406/1442/1423 1405/1441/1422 +f 1405/1441/1422 1407/1443/1424 1366/1397/1383 +f 1406/1442/1423 1408/1444/1425 1407/1443/1424 +f 1407/1443/1424 1409/1445/1426 1368/1398/1385 +f 1408/1444/1425 1410/1446/1427 1409/1445/1426 +f 1409/1445/1426 1375/1404/1392 1370/1401/1387 +f 1410/1446/1427 1411/1407/1428 1375/1404/1392 +f 1413/1453/1430 1454/1492/1471 1417/1456/1434 +f 1417/1456/1434 1419/1458/1436 1418/1415/1435 +f 1418/1415/1435 1419/1458/1436 1421/1457/1438 +f 1380/1410/1397 1421/1457/1438 1423/1459/1440 +f 1383/1413/1400 1423/1459/1440 1425/1460/1442 +f 1386/1420/1403 1425/1461/1442 1427/1462/1444 +f 1430/1418/1447 1427/1462/1444 1429/1463/1446 +f 1431/1426/1448 1429/1463/1446 1474/1464/1491 +f 1474/1464/1491 1438/1498/1455 1437/1468/1454 +f 1437/1468/1454 1438/1498/1455 1440/1474/1457 +f 1440/1474/1457 1442/1476/1459 1441/1475/1458 +f 1442/1476/1459 1465/1488/1482 1443/1477/1460 +f 1465/1488/1482 1449/1489/1466 1448/1482/1465 +f 1449/1489/1466 1451/1490/1468 1450/1485/1467 +f 1451/1490/1468 1453/1491/1470 1452/1447/1469 +f 1453/1491/1470 1454/1492/1471 1413/1453/1430 +f 1477/1502/1494 1478/1507/1495 1476/1503/1493 +f 1475/1501/1492 1476/1503/1493 1504/1504/1516 +f 1479/1506/1496 1480/1524/1497 1478/1507/1495 +f 1482/1508/1499 1480/1523/1497 1479/1509/1496 +f 1484/1511/1501 1482/1508/1499 1481/1510/1498 +f 1486/1513/1503 1484/1511/1501 1483/1512/1500 +f 1489/1516/1506 1486/1513/1503 1485/1514/1502 +f 1490/1494/1507 1491/1518/1508 1489/1516/1506 +f 1456/1517/1473 1492/1519/1509 1491/1518/1508 +f 1491/1518/1508 1492/1519/1509 1494/1519/1511 +f 1489/1516/1506 1491/1518/1508 1493/1518/1510 +f 1501/1522/1511 1500/1535/1514 1499/1536/1515 +f 1499/1536/1515 1498/1537/1514 1497/1538/1511 +f 1497/1538/1511 1496/1539/1513 1495/1540/1512 +f 1495/1540/1512 1493/1541/1510 1494/1520/1511 +f 1494/1520/1511 1515/1542/1514 1511/1543/1515 +f 1511/1543/1515 1510/1544/1514 1509/1521/1511 +f 1509/1521/1511 1508/1545/1513 1503/1546/1512 +f 1503/1546/1512 1502/1547/1513 1501/1522/1511 +f 1501/1522/1511 1499/1536/1515 1497/1538/1511 +f 1497/1538/1511 1495/1540/1512 1494/1520/1511 +f 1494/1520/1511 1511/1543/1515 1509/1521/1511 +f 1509/1521/1511 1503/1546/1512 1501/1522/1511 +f 1501/1522/1511 1497/1538/1511 1494/1520/1511 +f 1486/1513/1503 1489/1516/1506 1495/1516/1512 +f 1484/1511/1501 1486/1513/1503 1496/1513/1513 +f 1482/1508/1499 1484/1511/1501 1497/1511/1511 +f 1480/1523/1497 1482/1508/1499 1498/1508/1514 +f 1478/1507/1495 1480/1524/1497 1499/1524/1515 +f 1476/1503/1493 1478/1507/1495 1500/1507/1514 +f 1504/1504/1516 1476/1503/1493 1501/1503/1511 +f 1505/1525/1517 1504/1504/1516 1502/1504/1513 +f 1472/1505/1489 1504/1504/1516 1505/1525/1517 +f 1506/1526/1518 1505/1525/1517 1503/1525/1512 +f 1505/1525/1517 1506/1526/1518 1468/1499/1485 +f 1507/1527/1519 1506/1526/1518 1508/1526/1513 +f 1506/1526/1518 1507/1527/1519 1466/1497/1483 +f 1512/1528/1520 1507/1527/1519 1509/1527/1511 +f 1513/1529/1521 1512/1528/1520 1510/1528/1514 +f 1507/1527/1519 1512/1528/1520 1463/1496/1480 +f 1512/1528/1520 1513/1529/1521 1461/1495/1478 +f 1514/1530/1522 1513/1529/1521 1511/1529/1515 +f 1461/1495/1478 1513/1529/1521 1514/1530/1522 +f 1492/1519/1509 1514/1530/1522 1515/1530/1514 +f 1459/1493/1476 1514/1530/1522 1492/1519/1509 +usemtl Floral_Engraved_Gold +f 1374/1409/1391 1379/1410/1396 1377/1411/1394 +f 1377/1412/1394 1382/1413/1399 1378/1414/1395 +f 1379/1410/1396 1418/1415/1435 1380/1410/1397 +f 1382/1413/1399 1380/1410/1397 1383/1413/1400 +f 1384/1416/1401 1383/1413/1400 1386/1416/1403 +f 1384/1416/1401 1378/1417/1395 1382/1413/1399 +f 1385/1418/1402 1387/1419/1404 1384/1420/1401 +f 1384/1420/1401 1430/1418/1447 1385/1418/1402 +f 1389/1425/1406 1433/1426/1450 1390/1427/1407 +f 1414/1447/1431 1410/1448/1427 1408/1449/1425 +f 1410/1450/1427 1415/1451/1432 1411/1452/1428 +f 1414/1447/1431 1413/1453/1430 1412/1453/1429 +f 1412/1453/1429 1416/1451/1433 1415/1451/1432 +f 1381/1415/1398 1416/1451/1433 1418/1415/1435 +f 1415/1451/1432 1374/1454/1391 1411/1455/1428 +f 1422/1457/1439 1419/1458/1436 1420/1458/1437 +f 1420/1458/1437 1417/1456/1434 1488/1456/1505 +f 1424/1459/1441 1421/1457/1438 1422/1457/1439 +f 1426/1460/1443 1423/1459/1440 1424/1459/1441 +f 1426/1461/1443 1427/1462/1444 1425/1461/1442 +f 1428/1462/1445 1429/1463/1446 1427/1462/1444 +f 1385/1418/1402 1431/1426/1448 1433/1426/1450 +f 1433/1426/1450 1432/1465/1449 1434/1465/1451 +f 1390/1466/1407 1434/1465/1451 1394/1467/1411 +f 1434/1465/1451 1437/1468/1454 1435/1468/1452 +f 1434/1465/1451 1396/1469/1413 1394/1470/1411 +f 1436/1471/1453 1437/1468/1454 1439/1471/1456 +f 1435/1468/1452 1398/1472/1415 1396/1473/1413 +f 1444/1475/1461 1439/1471/1456 1441/1475/1458 +f 1445/1477/1462 1441/1475/1458 1443/1477/1460 +f 1436/1471/1453 1400/1478/1417 1398/1479/1415 +f 1444/1475/1461 1402/1480/1419 1400/1481/1417 +f 1446/1482/1463 1443/1477/1460 1448/1482/1465 +f 1445/1477/1462 1404/1483/1421 1402/1484/1419 +f 1446/1482/1463 1450/1485/1467 1447/1485/1464 +f 1446/1482/1463 1406/1486/1423 1404/1487/1421 +f 1447/1485/1464 1452/1447/1469 1414/1447/1431 +f 1455/1491/1472 1454/1492/1471 1453/1491/1470 +f 1458/1490/1475 1453/1491/1470 1451/1490/1468 +f 1459/1493/1476 1455/1491/1472 1458/1490/1475 +f 1455/1491/1472 1490/1494/1507 1457/1492/1474 +f 1461/1495/1478 1458/1490/1475 1460/1489/1477 +f 1460/1489/1477 1451/1490/1468 1449/1489/1466 +f 1463/1496/1480 1460/1489/1477 1462/1488/1479 +f 1460/1489/1477 1465/1488/1482 1462/1488/1479 +f 1466/1497/1483 1462/1488/1479 1464/1476/1481 +f 1462/1488/1479 1442/1476/1459 1464/1476/1481 +f 1467/1474/1484 1466/1497/1483 1464/1476/1481 +f 1464/1476/1481 1440/1474/1457 1467/1474/1484 +f 1469/1498/1486 1468/1499/1485 1467/1474/1484 +f 1467/1474/1484 1438/1498/1455 1469/1498/1486 +f 1471/1464/1488 1470/1500/1487 1469/1498/1486 +f 1471/1464/1488 1438/1498/1455 1474/1464/1491 +f 1475/1501/1492 1471/1464/1488 1473/1463/1490 +f 1473/1463/1490 1474/1464/1491 1429/1463/1446 +f 1428/1462/1445 1475/1501/1492 1473/1463/1490 +f 1426/1461/1443 1477/1502/1494 1428/1462/1445 +f 1424/1459/1441 1479/1509/1496 1426/1460/1443 +f 1422/1457/1439 1481/1510/1498 1424/1459/1441 +f 1420/1458/1437 1483/1512/1500 1422/1457/1439 +f 1487/1515/1504 1420/1458/1437 1488/1456/1505 +f 1490/1494/1507 1488/1456/1505 1457/1492/1474 +f 1457/1492/1474 1417/1456/1434 1454/1492/1471 +f 1447/1485/1464 1408/1531/1425 1406/1532/1423 +f 1374/1409/1391 1381/1415/1398 1379/1410/1396 +f 1377/1412/1394 1379/1410/1396 1382/1413/1399 +f 1379/1410/1396 1381/1415/1398 1418/1415/1435 +f 1382/1413/1399 1379/1410/1396 1380/1410/1397 +f 1384/1416/1401 1382/1413/1399 1383/1413/1400 +f 1384/1416/1401 1387/1533/1404 1378/1417/1395 +f 1385/1418/1402 1389/1534/1406 1387/1419/1404 +f 1384/1420/1401 1386/1420/1403 1430/1418/1447 +f 1389/1425/1406 1385/1418/1402 1433/1426/1450 +f 1414/1447/1431 1412/1453/1429 1410/1448/1427 +f 1410/1450/1427 1412/1453/1429 1415/1451/1432 +f 1414/1447/1431 1452/1447/1469 1413/1453/1430 +f 1412/1453/1429 1413/1453/1430 1416/1451/1433 +f 1381/1415/1398 1415/1451/1432 1416/1451/1433 +f 1415/1451/1432 1381/1415/1398 1374/1454/1391 +f 1422/1457/1439 1421/1457/1438 1419/1458/1436 +f 1420/1458/1437 1419/1458/1436 1417/1456/1434 +f 1424/1459/1441 1423/1459/1440 1421/1457/1438 +f 1426/1460/1443 1425/1460/1442 1423/1459/1440 +f 1426/1461/1443 1428/1462/1445 1427/1462/1444 +f 1428/1462/1445 1473/1463/1490 1429/1463/1446 +f 1385/1418/1402 1430/1418/1447 1431/1426/1448 +f 1433/1426/1450 1431/1426/1448 1432/1465/1449 +f 1390/1466/1407 1433/1426/1450 1434/1465/1451 +f 1434/1465/1451 1432/1465/1449 1437/1468/1454 +f 1434/1465/1451 1435/1468/1452 1396/1469/1413 +f 1436/1471/1453 1435/1468/1452 1437/1468/1454 +f 1435/1468/1452 1436/1471/1453 1398/1472/1415 +f 1444/1475/1461 1436/1471/1453 1439/1471/1456 +f 1445/1477/1462 1444/1475/1461 1441/1475/1458 +f 1436/1471/1453 1444/1475/1461 1400/1478/1417 +f 1444/1475/1461 1445/1477/1462 1402/1480/1419 +f 1446/1482/1463 1445/1477/1462 1443/1477/1460 +f 1445/1477/1462 1446/1482/1463 1404/1483/1421 +f 1446/1482/1463 1448/1482/1465 1450/1485/1467 +f 1446/1482/1463 1447/1485/1464 1406/1486/1423 +f 1447/1485/1464 1450/1485/1467 1452/1447/1469 +f 1455/1491/1472 1457/1492/1474 1454/1492/1471 +f 1458/1490/1475 1455/1491/1472 1453/1491/1470 +f 1459/1493/1476 1456/1517/1473 1455/1491/1472 +f 1455/1491/1472 1456/1517/1473 1490/1494/1507 +f 1461/1495/1478 1459/1493/1476 1458/1490/1475 +f 1460/1489/1477 1458/1490/1475 1451/1490/1468 +f 1463/1496/1480 1461/1495/1478 1460/1489/1477 +f 1460/1489/1477 1449/1489/1466 1465/1488/1482 +f 1466/1497/1483 1463/1496/1480 1462/1488/1479 +f 1462/1488/1479 1465/1488/1482 1442/1476/1459 +f 1467/1474/1484 1468/1499/1485 1466/1497/1483 +f 1464/1476/1481 1442/1476/1459 1440/1474/1457 +f 1469/1498/1486 1470/1500/1487 1468/1499/1485 +f 1467/1474/1484 1440/1474/1457 1438/1498/1455 +f 1471/1464/1488 1472/1505/1489 1470/1500/1487 +f 1471/1464/1488 1469/1498/1486 1438/1498/1455 +f 1475/1501/1492 1472/1505/1489 1471/1464/1488 +f 1473/1463/1490 1471/1464/1488 1474/1464/1491 +f 1428/1462/1445 1477/1502/1494 1475/1501/1492 +f 1426/1461/1443 1479/1506/1496 1477/1502/1494 +f 1424/1459/1441 1481/1510/1498 1479/1509/1496 +f 1422/1457/1439 1483/1512/1500 1481/1510/1498 +f 1420/1458/1437 1485/1514/1502 1483/1512/1500 +f 1487/1515/1504 1485/1514/1502 1420/1458/1437 +f 1490/1494/1507 1487/1515/1504 1488/1456/1505 +f 1457/1492/1474 1488/1456/1505 1417/1456/1434 +f 1447/1485/1464 1414/1447/1431 1408/1531/1425 +o Cube.021 +v -0.014631 1.275680 -0.142741 +v -0.027035 1.267392 -0.142741 +v 0.000000 1.278590 -0.142741 +v -0.014667 1.275766 -0.132866 +v -0.011146 1.267266 -0.152686 +v -0.020595 1.260952 -0.152686 +v 0.000000 1.269483 -0.152686 +v 0.011146 1.267266 -0.152686 +v 0.014631 1.275680 -0.142741 +v 0.020595 1.260952 -0.152686 +v 0.027035 1.267392 -0.142741 +v 0.026909 1.251503 -0.152686 +v 0.035323 1.254988 -0.142741 +v 0.029126 1.240357 -0.152686 +v 0.038233 1.240357 -0.142741 +v 0.026909 1.229211 -0.152686 +v 0.035323 1.225726 -0.142741 +v 0.020595 1.219762 -0.152686 +v 0.027035 1.213322 -0.142741 +v 0.011146 1.213448 -0.152686 +v 0.014631 1.205034 -0.142741 +v 0.000000 1.211231 -0.152686 +v 0.000000 1.202124 -0.142741 +v -0.011146 1.213448 -0.152686 +v -0.014631 1.205034 -0.142741 +v -0.020595 1.219762 -0.152686 +v -0.027035 1.213322 -0.142741 +v -0.026909 1.229211 -0.152686 +v -0.035323 1.225726 -0.142741 +v -0.029126 1.240357 -0.152686 +v -0.038233 1.240357 -0.142741 +v -0.026909 1.251503 -0.152686 +v -0.035323 1.254988 -0.142741 +v -0.035409 1.255024 -0.132866 +v -0.038076 1.256129 -0.126753 +v -0.038327 1.240357 -0.132866 +v -0.027101 1.267458 -0.132866 +v -0.029142 1.269499 -0.126753 +v -0.015772 1.278433 -0.126753 +v -0.029142 1.269499 0.000664 +v -0.028016 1.268373 0.000664 +v -0.038076 1.256129 0.000664 +v -0.015772 1.278433 0.000664 +v -0.015162 1.276962 0.000664 +v 0.000000 1.281570 0.000664 +v 0.015772 1.278433 0.000664 +v 0.000000 1.279978 0.000664 +v 0.000000 1.281570 -0.126753 +v 0.000000 1.278684 -0.132866 +v 0.015772 1.278433 -0.126753 +v 0.029142 1.269499 -0.126753 +v 0.014667 1.275766 -0.132866 +v 0.027101 1.267458 -0.132866 +v 0.035409 1.255024 -0.132866 +v 0.038076 1.256129 -0.126753 +v 0.038327 1.240357 -0.132866 +v 0.041213 1.240357 -0.126753 +v 0.035409 1.225690 -0.132866 +v 0.038076 1.224585 -0.126753 +v 0.027101 1.213256 -0.132866 +v 0.029142 1.211215 -0.126753 +v 0.014667 1.204948 -0.132866 +v 0.015772 1.202281 -0.126753 +v 0.000000 1.202030 -0.132866 +v 0.000000 1.199144 -0.126753 +v -0.014667 1.204948 -0.132866 +v -0.015772 1.202281 -0.126753 +v -0.027101 1.213256 -0.132866 +v -0.029142 1.211215 -0.126753 +v -0.035409 1.225690 -0.132866 +v -0.038076 1.224585 -0.126753 +v -0.041213 1.240357 -0.126753 +v -0.038076 1.224585 0.000664 +v -0.036605 1.225195 0.000664 +v -0.029142 1.211215 0.000664 +v -0.041213 1.240357 0.000664 +v -0.039621 1.240357 0.000664 +v -0.039621 1.240357 0.007441 +v -0.036605 1.255519 0.000664 +v -0.036605 1.255519 0.007441 +v -0.038076 1.256129 0.007441 +v -0.028016 1.268373 0.007441 +v -0.029142 1.269499 0.007441 +v -0.015162 1.276962 0.007441 +v -0.015772 1.278433 0.007441 +v 0.000000 1.279978 0.007441 +v 0.000000 1.281570 0.007441 +v 0.015162 1.276962 0.007441 +v 0.015772 1.278433 0.007441 +v 0.028016 1.268373 0.007441 +v 0.015162 1.276962 0.000664 +v 0.028016 1.268373 0.000664 +v 0.036605 1.255519 0.000664 +v 0.029142 1.269499 0.000664 +v 0.038076 1.256129 0.000664 +v 0.041213 1.240357 0.000664 +v 0.038076 1.224585 0.000664 +v 0.039621 1.240357 0.000664 +v 0.039621 1.240357 0.007441 +v 0.036605 1.225195 0.000664 +v 0.036605 1.225195 0.007441 +v 0.028016 1.212341 0.000664 +v 0.028016 1.212341 0.007441 +v 0.015162 1.203752 0.000664 +v 0.029142 1.211215 0.000664 +v 0.015772 1.202281 0.000664 +v 0.000000 1.199144 0.000664 +v -0.015772 1.202281 0.000664 +v 0.000000 1.200737 0.000664 +v 0.000000 1.200737 0.007441 +v -0.015162 1.203752 0.000664 +v -0.015162 1.203752 0.007441 +v -0.028016 1.212341 0.000664 +v -0.028016 1.212341 0.007441 +v -0.036605 1.225195 0.007441 +v -0.029142 1.211215 0.007441 +v -0.029142 1.211215 0.038248 +v -0.038076 1.224585 0.007441 +v -0.015772 1.202281 0.007441 +v -0.015772 1.202281 0.038248 +v 0.000000 1.199144 0.007441 +v 0.000000 1.199144 0.038248 +v 0.015772 1.202281 0.007441 +v 0.015772 1.202281 0.038248 +v 0.029142 1.211215 0.007441 +v 0.015162 1.203752 0.007441 +v 0.029142 1.211215 0.038248 +v 0.038076 1.224585 0.007441 +v 0.038076 1.224585 0.038248 +v 0.041213 1.240357 0.007441 +v 0.041213 1.240357 0.038248 +v 0.038076 1.256129 0.007441 +v 0.038076 1.256129 0.038248 +v 0.029142 1.269499 0.007441 +v 0.036605 1.255519 0.007441 +v 0.029142 1.269499 0.038248 +v 0.027609 1.267966 0.044729 +v 0.015772 1.278433 0.038248 +v 0.014942 1.276430 0.044729 +v 0.000000 1.281570 0.038248 +v 0.000000 1.279402 0.044729 +v -0.015772 1.278433 0.038248 +v -0.014942 1.276430 0.044729 +v -0.029142 1.269499 0.038248 +v -0.027609 1.267966 0.044729 +v -0.038076 1.256129 0.038248 +v -0.036073 1.255299 0.044729 +v -0.041213 1.240357 0.038248 +v -0.041213 1.240357 0.007441 +v -0.039045 1.240357 0.044729 +v -0.038076 1.224585 0.038248 +v -0.036073 1.225415 0.044729 +v -0.027609 1.212748 0.044729 +v -0.036073 1.225415 0.044729 +v -0.027609 1.212748 0.044729 +v -0.039045 1.240357 0.044729 +v -0.036073 1.255299 0.044729 +v -0.027609 1.267966 0.044729 +v -0.014942 1.276430 0.044729 +v 0.000000 1.279402 0.044729 +v 0.014942 1.276430 0.044729 +v 0.027609 1.267966 0.044729 +v 0.036073 1.255299 0.044729 +v 0.039045 1.240357 0.044729 +v 0.036073 1.255299 0.044729 +v 0.039045 1.240357 0.044729 +v 0.036073 1.225415 0.044729 +v 0.027609 1.212748 0.044729 +v 0.036073 1.225415 0.044729 +v 0.027609 1.212748 0.044729 +v 0.014942 1.204284 0.044729 +v 0.000000 1.201312 0.044729 +v 0.014942 1.204284 0.044729 +v 0.000000 1.201312 0.044729 +v -0.014942 1.204284 0.044729 +v -0.014942 1.204284 0.044729 +vn -0.3953 0.8464 -0.3568 +vn -0.7091 0.6233 -0.3296 +vn -0.0000 0.9321 -0.3621 +vn -0.3620 0.9053 -0.2221 +vn -0.1339 0.4019 -0.9059 +vn -0.2889 0.3467 -0.8924 +vn -0.0000 0.4157 -0.9095 +vn 0.1339 0.4018 -0.9059 +vn 0.3953 0.8464 -0.3568 +vn 0.2889 0.3467 -0.8924 +vn 0.7091 0.6233 -0.3296 +vn 0.4621 0.2268 -0.8574 +vn 0.9171 0.3102 -0.2505 +vn 0.5874 -0.0000 -0.8093 +vn 0.9835 -0.0000 -0.1810 +vn 0.4621 -0.2268 -0.8574 +vn 0.9171 -0.3102 -0.2505 +vn 0.2889 -0.3467 -0.8924 +vn 0.7091 -0.6233 -0.3296 +vn 0.1339 -0.4019 -0.9059 +vn 0.3953 -0.8464 -0.3568 +vn -0.0000 -0.4157 -0.9095 +vn -0.0000 -0.9322 -0.3621 +vn -0.1339 -0.4018 -0.9059 +vn -0.3953 -0.8464 -0.3568 +vn -0.2889 -0.3467 -0.8924 +vn -0.7091 -0.6233 -0.3296 +vn -0.4621 -0.2268 -0.8574 +vn -0.9171 -0.3102 -0.2505 +vn -0.5874 -0.0000 -0.8093 +vn -0.9835 -0.0000 -0.1810 +vn -0.4621 0.2268 -0.8574 +vn -0.9171 0.3102 -0.2505 +vn -0.9104 0.3614 -0.2012 +vn -0.9338 0.3102 -0.1781 +vn -0.9775 -0.0000 -0.2109 +vn -0.6851 0.6965 -0.2132 +vn -0.7350 0.6447 -0.2101 +vn -0.4089 0.8866 -0.2165 +vn -0.6058 0.5677 0.5574 +vn -0.5764 0.5402 0.6131 +vn -0.8822 0.3126 0.3521 +vn -0.2963 0.6869 0.6636 +vn -0.2843 0.6591 0.6962 +vn -0.0000 0.7202 0.6938 +vn 0.2963 0.6869 0.6636 +vn -0.0000 0.6930 0.7210 +vn -0.0000 0.9762 -0.2170 +vn -0.0000 0.9743 -0.2252 +vn 0.4088 0.8866 -0.2165 +vn 0.7350 0.6447 -0.2101 +vn 0.3620 0.9053 -0.2221 +vn 0.6851 0.6965 -0.2132 +vn 0.9104 0.3614 -0.2012 +vn 0.9338 0.3102 -0.1781 +vn 0.9775 -0.0000 -0.2109 +vn 0.9902 -0.0000 -0.1394 +vn 0.9104 -0.3614 -0.2012 +vn 0.9338 -0.3102 -0.1781 +vn 0.6851 -0.6965 -0.2132 +vn 0.7350 -0.6447 -0.2101 +vn 0.3620 -0.9053 -0.2221 +vn 0.4089 -0.8866 -0.2165 +vn -0.0000 -0.9743 -0.2252 +vn -0.0000 -0.9762 -0.2170 +vn -0.3620 -0.9053 -0.2221 +vn -0.4089 -0.8866 -0.2165 +vn -0.6851 -0.6965 -0.2132 +vn -0.7350 -0.6447 -0.2101 +vn -0.9104 -0.3614 -0.2012 +vn -0.9338 -0.3102 -0.1781 +vn -0.9902 -0.0000 -0.1394 +vn -0.8822 -0.3126 0.3521 +vn -0.8290 -0.2938 0.4759 +vn -0.6058 -0.5677 0.5574 +vn -0.9746 -0.0000 0.2240 +vn -0.8952 -0.0000 0.4457 +vn -0.8952 -0.0000 -0.4457 +vn -0.8290 0.2938 0.4759 +vn -0.8290 0.2938 -0.4759 +vn -0.8822 0.3126 -0.3521 +vn -0.5765 0.5402 -0.6131 +vn -0.6058 0.5677 -0.5574 +vn -0.2843 0.6591 -0.6962 +vn -0.2963 0.6869 -0.6635 +vn -0.0000 0.6930 -0.7210 +vn -0.0000 0.7202 -0.6938 +vn 0.2843 0.6591 -0.6962 +vn 0.2963 0.6870 -0.6635 +vn 0.5765 0.5402 -0.6131 +vn 0.2843 0.6591 0.6962 +vn 0.5765 0.5402 0.6131 +vn 0.8290 0.2938 0.4759 +vn 0.6058 0.5677 0.5574 +vn 0.8822 0.3126 0.3521 +vn 0.9746 -0.0000 0.2240 +vn 0.8822 -0.3126 0.3521 +vn 0.8952 -0.0000 0.4457 +vn 0.8952 -0.0000 -0.4457 +vn 0.8290 -0.2938 0.4759 +vn 0.8290 -0.2938 -0.4759 +vn 0.5764 -0.5402 0.6131 +vn 0.5765 -0.5402 -0.6131 +vn 0.2843 -0.6591 0.6962 +vn 0.6058 -0.5677 0.5574 +vn 0.2963 -0.6869 0.6636 +vn -0.0000 -0.7202 0.6938 +vn -0.2963 -0.6869 0.6635 +vn -0.0000 -0.6930 0.7210 +vn -0.0000 -0.6930 -0.7210 +vn -0.2843 -0.6591 0.6962 +vn -0.2843 -0.6591 -0.6962 +vn -0.5765 -0.5402 0.6131 +vn -0.5765 -0.5402 -0.6131 +vn -0.8290 -0.2938 -0.4759 +vn -0.6058 -0.5677 -0.5574 +vn -0.7397 -0.6542 0.1577 +vn -0.8822 -0.3126 -0.3521 +vn -0.2963 -0.6869 -0.6635 +vn -0.4090 -0.8984 0.1598 +vn -0.0000 -0.7202 -0.6937 +vn -0.0000 -0.9872 0.1598 +vn 0.2963 -0.6869 -0.6635 +vn 0.4090 -0.8984 0.1598 +vn 0.6058 -0.5677 -0.5574 +vn 0.2843 -0.6591 -0.6962 +vn 0.7397 -0.6542 0.1577 +vn 0.8822 -0.3126 -0.3521 +vn 0.9394 -0.3124 0.1414 +vn 0.9746 -0.0000 -0.2240 +vn 0.9932 -0.0000 0.1167 +vn 0.8822 0.3126 -0.3521 +vn 0.9394 0.3123 0.1414 +vn 0.6058 0.5677 -0.5574 +vn 0.8290 0.2938 -0.4759 +vn 0.7397 0.6542 0.1577 +vn 0.9721 0.2134 0.0970 +vn 0.4090 0.8984 0.1598 +vn 0.9638 0.2509 0.0897 +vn -0.0000 0.9872 0.1598 +vn 0.9557 0.2791 0.0934 +vn -0.4090 0.8984 0.1598 +vn 0.9455 0.3067 0.1097 +vn -0.7397 0.6542 0.1577 +vn 0.9270 0.3416 0.1552 +vn -0.9394 0.3123 0.1414 +vn 0.8642 0.3869 0.3216 +vn -0.9932 -0.0000 0.1167 +vn -0.9746 -0.0000 -0.2240 +vn 0.6455 -0.0000 0.7637 +vn -0.9394 -0.3123 0.1414 +vn 0.8642 -0.3869 0.3216 +vn 0.9270 -0.3416 0.1552 +vn 0.9702 -0.0000 0.2424 +vn 0.9623 -0.0000 0.2720 +vn 0.9820 -0.0000 0.1890 +vn 0.9702 -0.0000 0.2425 +vn 0.9602 -0.0000 0.2795 +vn 0.9597 -0.0000 0.2811 +vn 0.9821 0.1448 0.1203 +vn 0.9894 -0.0000 0.1450 +vn 0.9821 -0.1448 0.1203 +vn 0.9721 -0.2134 0.0970 +vn 0.9638 -0.2509 0.0897 +vn 0.9557 -0.2791 0.0934 +vn 0.9455 -0.3067 0.1097 +vt 0.661368 0.463977 +vt 0.605181 0.394819 +vt 0.586229 0.413771 +vt 0.671624 0.439216 +vt 0.630067 0.369933 +vt 0.750000 0.454806 +vt 0.685093 0.406700 +vt 0.750000 0.481607 +vt 0.814908 0.093300 +vt 0.593300 0.185093 +vt 0.814907 0.406700 +vt 0.750000 0.419611 +vt 0.828376 0.439216 +vt 0.869933 0.369933 +vt 0.894819 0.394819 +vt 0.906701 0.314908 +vt 0.939216 0.328376 +vt 0.919611 0.250000 +vt 0.939216 0.171624 +vt 0.954806 0.250000 +vt 0.894819 0.105181 +vt 0.906700 0.185093 +vt 0.828376 0.060784 +vt 0.869933 0.130067 +vt 0.750000 0.045194 +vt 0.685093 0.093300 +vt 0.750000 0.080389 +vt 0.671624 0.060784 +vt 0.630067 0.130067 +vt 0.605181 0.105181 +vt 0.560784 0.171624 +vt 0.580389 0.250000 +vt 0.560784 0.328376 +vt 0.545194 0.250000 +vt 0.593300 0.314907 +vt 0.536023 0.338632 +vt 0.518393 0.250000 +vt 0.580294 0.419706 +vt 0.528269 0.341844 +vt 0.510000 0.250000 +vt 0.658156 0.471731 +vt 0.187500 0.895448 +vt 0.125000 0.532007 +vt 0.187500 0.532007 +vt 0.125000 0.532007 +vt 0.062500 0.895448 +vt 0.062500 0.532007 +vt 0.125000 0.895448 +vt 0.000000 0.895448 +vt 0.062500 0.532007 +vt 0.937500 0.895448 +vt 1.000000 0.532007 +vt 1.000000 0.895448 +vt 0.750000 0.490000 +vt 0.838632 0.463977 +vt 0.841844 0.471731 +vt 0.913771 0.413771 +vt 0.937500 0.532007 +vt 0.875000 0.895448 +vt 0.875000 0.532007 +vt 0.919706 0.419706 +vt 0.963977 0.338632 +vt 0.971731 0.341844 +vt 0.981607 0.250000 +vt 0.963977 0.161368 +vt 0.971731 0.158156 +vt 0.990000 0.250000 +vt 0.913771 0.086229 +vt 0.919706 0.080294 +vt 0.838632 0.036023 +vt 0.841844 0.028269 +vt 0.750000 0.018393 +vt 0.750000 0.010000 +vt 0.661368 0.036023 +vt 0.658156 0.028269 +vt 0.586229 0.086229 +vt 0.580294 0.080294 +vt 0.536023 0.161368 +vt 0.528269 0.158156 +vt 0.375000 0.895448 +vt 0.312500 0.532007 +vt 0.375000 0.532007 +vt 0.312500 0.895448 +vt 0.250000 0.532007 +vt 0.312500 0.532007 +vt 0.250000 0.895448 +vt 0.250000 0.532007 +vt 0.187500 0.532007 +vt 0.312500 0.915363 +vt 0.250000 0.915363 +vt 0.187500 0.915363 +vt 0.125000 0.915363 +vt 0.062500 0.915363 +vt 0.000000 0.915363 +vt 1.000000 0.915363 +vt 0.937500 0.915363 +vt 0.875000 0.915363 +vt 0.812500 0.895448 +vt 0.875000 0.532007 +vt 0.812500 0.532007 +vt 0.750000 0.895448 +vt 0.812500 0.532007 +vt 0.750000 0.532007 +vt 0.687500 0.895448 +vt 0.687500 0.532007 +vt 0.750000 0.532007 +vt 0.812500 0.915363 +vt 0.750000 0.915363 +vt 0.687500 0.915363 +vt 0.625000 0.895448 +vt 0.625000 0.915363 +vt 0.562500 0.895448 +vt 0.625000 0.532007 +vt 0.687500 0.532007 +vt 0.562500 0.532007 +vt 0.625000 0.532007 +vt 0.500000 0.895448 +vt 0.500000 0.532007 +vt 0.562500 0.532007 +vt 0.437500 0.895448 +vt 0.437500 0.532007 +vt 0.500000 0.532007 +vt 0.562500 0.915363 +vt 0.500000 0.915363 +vt 0.437500 0.915363 +vt 0.375000 0.915363 +vt 0.437500 0.980957 +vt 0.375000 0.980957 +vt 0.500000 0.980957 +vt 0.562500 0.980957 +vt 0.625000 0.980957 +vt 0.687500 0.980957 +vt 0.750000 0.980957 +vt 0.812500 0.980957 +vt 0.875000 0.980957 +vt 0.937500 0.980957 +vt 0.875000 1.000000 +vt 0.812500 1.000000 +vt 1.000000 0.980957 +vt 0.937500 1.000000 +vt 0.062500 1.000000 +vt 0.000000 0.980957 +vt 0.062500 0.980957 +vt 0.125000 1.000000 +vt 0.125000 0.980957 +vt 0.187500 1.000000 +vt 0.187500 0.980957 +vt 0.250000 1.000000 +vt 0.250000 0.980957 +vt 0.312500 0.980957 +vt 0.312500 1.000000 +vt 0.375000 1.000000 +vt 0.080294 0.080294 +vt 0.419706 0.080294 +vt 0.419706 0.419706 +vt 0.000000 1.000000 +vt 1.000000 1.000000 +vt 0.750000 1.000000 +vt 0.687500 1.000000 +vt 0.625000 1.000000 +vt 0.562500 1.000000 +vt 0.500000 1.000000 +vt 0.437500 1.000000 +vt 0.375000 0.532007 +vt 0.437500 0.532007 +vt 0.000000 0.532007 +vt 0.937500 0.532007 +vt 0.341844 0.471731 +vt 0.250000 0.490000 +vt 0.158156 0.471731 +vt 0.080294 0.419706 +vt 0.028269 0.341844 +vt 0.010000 0.250000 +vt 0.028269 0.158156 +vt 0.158156 0.028269 +vt 0.250000 0.010000 +vt 0.341844 0.028269 +vt 0.471731 0.158156 +vt 0.490000 0.250000 +vt 0.471731 0.341844 +s 1 +usemtl Brass.001 +f 1519/1548/1526 1517/1549/1524 1552/1550/1559 +f 1516/1551/1523 1521/1552/1528 1517/1549/1524 +f 1518/1553/1525 1520/1554/1527 1516/1551/1523 +f 1564/1555/1571 1516/1551/1523 1519/1548/1526 +f 1535/1556/1542 1543/1557/1550 1520/1554/1527 +f 1518/1553/1525 1523/1558/1530 1522/1559/1529 +f 1524/1560/1531 1525/1561/1532 1523/1558/1530 +f 1526/1562/1533 1527/1563/1534 1525/1561/1532 +f 1528/1564/1535 1529/1565/1536 1527/1563/1534 +f 1532/1566/1539 1529/1565/1536 1530/1567/1537 +f 1534/1568/1541 1531/1569/1538 1532/1566/1539 +f 1536/1570/1543 1533/1571/1540 1534/1568/1541 +f 1538/1572/1545 1535/1556/1542 1536/1570/1543 +f 1538/1572/1545 1539/1573/1546 1537/1574/1544 +f 1540/1575/1547 1541/1576/1548 1539/1573/1546 +f 1542/1577/1549 1543/1557/1550 1541/1576/1548 +f 1544/1578/1551 1545/1579/1552 1543/1557/1550 +f 1548/1580/1555 1545/1579/1552 1546/1581/1553 +f 1517/1549/1524 1547/1582/1554 1548/1580/1555 +f 1549/1583/1556 1546/1581/1553 1551/1584/1558 +f 1552/1550/1559 1548/1580/1555 1549/1583/1556 +f 1553/1585/1560 1549/1583/1556 1550/1586/1557 +f 1550/1586/1557 1551/1584/1558 1587/1587/1594 +f 1554/1588/1561 1552/1550/1559 1553/1585/1560 +f 1563/1601/1570 1519/1548/1526 1554/1588/1561 +f 1563/1601/1570 1567/1602/1574 1564/1555/1571 +f 1565/1603/1572 1568/1604/1575 1567/1602/1574 +f 1564/1555/1571 1524/1560/1531 1518/1553/1525 +f 1567/1602/1574 1526/1562/1533 1524/1560/1531 +f 1568/1604/1575 1528/1564/1535 1526/1562/1533 +f 1566/1608/1573 1569/1609/1576 1568/1604/1575 +f 1569/1609/1576 1530/1567/1537 1528/1564/1535 +f 1570/1610/1577 1571/1611/1578 1569/1609/1576 +f 1573/1612/1580 1530/1567/1537 1571/1611/1578 +f 1574/1613/1581 1571/1611/1578 1572/1614/1579 +f 1575/1615/1582 1532/1566/1539 1573/1612/1580 +f 1576/1616/1583 1573/1612/1580 1574/1613/1581 +f 1577/1617/1584 1534/1568/1541 1575/1615/1582 +f 1578/1618/1585 1575/1615/1582 1576/1616/1583 +f 1579/1619/1586 1536/1570/1543 1577/1617/1584 +f 1580/1620/1587 1577/1617/1584 1578/1618/1585 +f 1579/1619/1586 1540/1575/1547 1538/1572/1545 +f 1580/1620/1587 1581/1621/1588 1579/1619/1586 +f 1581/1621/1588 1542/1577/1549 1540/1575/1547 +f 1582/1622/1589 1583/1623/1590 1581/1621/1588 +f 1583/1623/1590 1544/1578/1551 1542/1577/1549 +f 1584/1624/1591 1585/1625/1592 1583/1623/1590 +f 1585/1625/1592 1546/1581/1553 1544/1578/1551 +f 1586/1626/1593 1551/1584/1558 1585/1625/1592 +f 1630/1636/1637 1592/1633/1599 1589/1630/1596 +f 1593/1637/1600 1594/1589/1601 1592/1633/1599 +f 1595/1638/1602 1556/1595/1563 1594/1589/1601 +f 1597/1639/1604 1559/1593/1566 1556/1595/1563 +f 1599/1640/1606 1562/1596/1569 1559/1593/1566 +f 1601/1642/1608 1606/1598/1613 1562/1600/1569 +f 1603/1643/1610 1607/1606/1614 1606/1598/1613 +f 1605/1644/1612 1608/1645/1615 1607/1606/1614 +f 1650/1654/1657 1613/1648/1620 1608/1645/1615 +f 1614/1655/1621 1615/1651/1622 1613/1648/1620 +f 1616/1656/1623 1617/1657/1624 1615/1651/1622 +f 1618/1658/1625 1619/1659/1626 1617/1657/1624 +f 1641/1670/1648 1624/1664/1631 1619/1659/1626 +f 1625/1671/1632 1626/1667/1633 1624/1664/1631 +f 1627/1672/1634 1628/1627/1635 1626/1667/1633 +f 1629/1673/1636 1589/1630/1596 1628/1627/1635 +f 1653/1683/1660 1652/1684/1659 1651/1682/1658 +f 1651/1682/1658 1680/1685/1682 1648/1681/1655 +f 1655/1686/1662 1654/1687/1661 1653/1683/1660 +f 1658/1688/1665 1655/1689/1662 1657/1690/1664 +f 1660/1691/1667 1657/1690/1664 1659/1692/1666 +f 1662/1693/1669 1659/1692/1666 1661/1694/1668 +f 1665/1695/1672 1661/1694/1668 1663/1696/1670 +f 1666/1697/1673 1665/1695/1672 1663/1696/1670 +f 1632/1675/1639 1667/1698/1674 1666/1697/1673 +f 1667/1698/1674 1670/1699/1677 1669/1698/1676 +f 1665/1695/1672 1669/1698/1676 1671/1695/1678 +f 1670/1700/1677 1685/1701/1677 1677/1702/1677 +f 1662/1693/1669 1671/1695/1678 1672/1693/1679 +f 1660/1691/1667 1672/1693/1679 1673/1691/1677 +f 1658/1688/1665 1673/1691/1677 1674/1688/1680 +f 1656/1703/1663 1674/1688/1680 1675/1703/1681 +f 1654/1687/1661 1675/1704/1681 1676/1687/1680 +f 1652/1684/1659 1676/1687/1680 1677/1684/1677 +f 1680/1685/1682 1677/1684/1677 1678/1685/1679 +f 1681/1705/1683 1678/1685/1679 1679/1705/1678 +f 1648/1681/1655 1681/1705/1683 1646/1680/1653 +f 1682/1706/1684 1679/1705/1678 1684/1706/1679 +f 1681/1705/1683 1644/1679/1651 1646/1680/1653 +f 1683/1707/1685 1684/1706/1679 1685/1707/1677 +f 1682/1706/1684 1642/1678/1649 1644/1679/1651 +f 1688/1708/1686 1685/1707/1677 1686/1708/1680 +f 1689/1709/1687 1686/1708/1680 1687/1709/1681 +f 1683/1707/1685 1639/1677/1646 1642/1678/1649 +f 1688/1708/1686 1637/1676/1644 1639/1677/1646 +f 1690/1710/1688 1687/1709/1681 1691/1710/1680 +f 1637/1676/1644 1690/1710/1688 1635/1674/1642 +f 1668/1699/1675 1691/1710/1680 1670/1699/1677 +f 1635/1674/1642 1668/1699/1675 1632/1675/1639 +f 1519/1548/1526 1516/1551/1523 1517/1549/1524 +f 1516/1551/1523 1520/1554/1527 1521/1552/1528 +f 1518/1553/1525 1522/1559/1529 1520/1554/1527 +f 1564/1555/1571 1518/1553/1525 1516/1551/1523 +f 1520/1554/1527 1522/1559/1529 1523/1558/1530 +f 1523/1558/1530 1525/1561/1532 1527/1563/1534 +f 1527/1563/1534 1529/1565/1536 1531/1569/1538 +f 1531/1569/1538 1533/1571/1540 1535/1556/1542 +f 1535/1556/1542 1537/1574/1544 1539/1573/1546 +f 1539/1573/1546 1541/1576/1548 1543/1557/1550 +f 1543/1557/1550 1545/1579/1552 1547/1582/1554 +f 1547/1582/1554 1521/1552/1528 1520/1554/1527 +f 1520/1554/1527 1523/1558/1530 1527/1563/1534 +f 1527/1563/1534 1531/1569/1538 1535/1556/1542 +f 1535/1556/1542 1539/1573/1546 1543/1557/1550 +f 1543/1557/1550 1547/1582/1554 1520/1554/1527 +f 1520/1554/1527 1527/1563/1534 1535/1556/1542 +f 1518/1553/1525 1524/1560/1531 1523/1558/1530 +f 1524/1560/1531 1526/1562/1533 1525/1561/1532 +f 1526/1562/1533 1528/1564/1535 1527/1563/1534 +f 1528/1564/1535 1530/1567/1537 1529/1565/1536 +f 1532/1566/1539 1531/1569/1538 1529/1565/1536 +f 1534/1568/1541 1533/1571/1540 1531/1569/1538 +f 1536/1570/1543 1535/1556/1542 1533/1571/1540 +f 1538/1572/1545 1537/1574/1544 1535/1556/1542 +f 1538/1572/1545 1540/1575/1547 1539/1573/1546 +f 1540/1575/1547 1542/1577/1549 1541/1576/1548 +f 1542/1577/1549 1544/1578/1551 1543/1557/1550 +f 1544/1578/1551 1546/1581/1553 1545/1579/1552 +f 1548/1580/1555 1547/1582/1554 1545/1579/1552 +f 1517/1549/1524 1521/1552/1528 1547/1582/1554 +f 1549/1583/1556 1548/1580/1555 1546/1581/1553 +f 1552/1550/1559 1517/1549/1524 1548/1580/1555 +f 1553/1585/1560 1552/1550/1559 1549/1583/1556 +f 1550/1586/1557 1549/1583/1556 1551/1584/1558 +f 1554/1588/1561 1519/1548/1526 1552/1550/1559 +f 1563/1601/1570 1564/1555/1571 1519/1548/1526 +f 1563/1601/1570 1565/1603/1572 1567/1602/1574 +f 1565/1603/1572 1566/1608/1573 1568/1604/1575 +f 1564/1555/1571 1567/1602/1574 1524/1560/1531 +f 1567/1602/1574 1568/1604/1575 1526/1562/1533 +f 1568/1604/1575 1569/1609/1576 1528/1564/1535 +f 1566/1608/1573 1570/1610/1577 1569/1609/1576 +f 1569/1609/1576 1571/1611/1578 1530/1567/1537 +f 1570/1610/1577 1572/1614/1579 1571/1611/1578 +f 1573/1612/1580 1532/1566/1539 1530/1567/1537 +f 1574/1613/1581 1573/1612/1580 1571/1611/1578 +f 1575/1615/1582 1534/1568/1541 1532/1566/1539 +f 1576/1616/1583 1575/1615/1582 1573/1612/1580 +f 1577/1617/1584 1536/1570/1543 1534/1568/1541 +f 1578/1618/1585 1577/1617/1584 1575/1615/1582 +f 1579/1619/1586 1538/1572/1545 1536/1570/1543 +f 1580/1620/1587 1579/1619/1586 1577/1617/1584 +f 1579/1619/1586 1581/1621/1588 1540/1575/1547 +f 1580/1620/1587 1582/1622/1589 1581/1621/1588 +f 1581/1621/1588 1583/1623/1590 1542/1577/1549 +f 1582/1622/1589 1584/1624/1591 1583/1623/1590 +f 1583/1623/1590 1585/1625/1592 1544/1578/1551 +f 1584/1624/1591 1586/1626/1593 1585/1625/1592 +f 1585/1625/1592 1551/1584/1558 1546/1581/1553 +f 1586/1626/1593 1587/1587/1594 1551/1584/1558 +f 1630/1636/1637 1593/1637/1600 1592/1633/1599 +f 1593/1637/1600 1595/1638/1602 1594/1589/1601 +f 1595/1638/1602 1597/1639/1604 1556/1595/1563 +f 1597/1639/1604 1599/1640/1606 1559/1593/1566 +f 1599/1640/1606 1601/1641/1608 1562/1596/1569 +f 1601/1642/1608 1603/1643/1610 1606/1598/1613 +f 1603/1643/1610 1605/1644/1612 1607/1606/1614 +f 1605/1644/1612 1650/1654/1657 1608/1645/1615 +f 1650/1654/1657 1614/1655/1621 1613/1648/1620 +f 1614/1655/1621 1616/1656/1623 1615/1651/1622 +f 1616/1656/1623 1618/1658/1625 1617/1657/1624 +f 1618/1658/1625 1641/1670/1648 1619/1659/1626 +f 1641/1670/1648 1625/1671/1632 1624/1664/1631 +f 1625/1671/1632 1627/1672/1634 1626/1667/1633 +f 1627/1672/1634 1629/1673/1636 1628/1627/1635 +f 1629/1673/1636 1630/1636/1637 1589/1630/1596 +f 1653/1683/1660 1654/1687/1661 1652/1684/1659 +f 1651/1682/1658 1652/1684/1659 1680/1685/1682 +f 1655/1686/1662 1656/1704/1663 1654/1687/1661 +f 1658/1688/1665 1656/1703/1663 1655/1689/1662 +f 1660/1691/1667 1658/1688/1665 1657/1690/1664 +f 1662/1693/1669 1660/1691/1667 1659/1692/1666 +f 1665/1695/1672 1662/1693/1669 1661/1694/1668 +f 1666/1697/1673 1667/1698/1674 1665/1695/1672 +f 1632/1675/1639 1668/1699/1675 1667/1698/1674 +f 1667/1698/1674 1668/1699/1675 1670/1699/1677 +f 1665/1695/1672 1667/1698/1674 1669/1698/1676 +f 1677/1702/1677 1676/1715/1680 1675/1716/1681 +f 1675/1716/1681 1674/1717/1680 1673/1718/1677 +f 1673/1718/1677 1672/1719/1679 1671/1720/1678 +f 1671/1720/1678 1669/1721/1676 1670/1700/1677 +f 1670/1700/1677 1691/1722/1680 1687/1723/1681 +f 1687/1723/1681 1686/1724/1680 1685/1701/1677 +f 1685/1701/1677 1684/1725/1679 1679/1726/1678 +f 1679/1726/1678 1678/1727/1679 1677/1702/1677 +f 1677/1702/1677 1675/1716/1681 1673/1718/1677 +f 1673/1718/1677 1671/1720/1678 1670/1700/1677 +f 1670/1700/1677 1687/1723/1681 1685/1701/1677 +f 1685/1701/1677 1679/1726/1678 1677/1702/1677 +f 1677/1702/1677 1673/1718/1677 1670/1700/1677 +f 1662/1693/1669 1665/1695/1672 1671/1695/1678 +f 1660/1691/1667 1662/1693/1669 1672/1693/1679 +f 1658/1688/1665 1660/1691/1667 1673/1691/1677 +f 1656/1703/1663 1658/1688/1665 1674/1688/1680 +f 1654/1687/1661 1656/1704/1663 1675/1704/1681 +f 1652/1684/1659 1654/1687/1661 1676/1687/1680 +f 1680/1685/1682 1652/1684/1659 1677/1684/1677 +f 1681/1705/1683 1680/1685/1682 1678/1685/1679 +f 1648/1681/1655 1680/1685/1682 1681/1705/1683 +f 1682/1706/1684 1681/1705/1683 1679/1705/1678 +f 1681/1705/1683 1682/1706/1684 1644/1679/1651 +f 1683/1707/1685 1682/1706/1684 1684/1706/1679 +f 1682/1706/1684 1683/1707/1685 1642/1678/1649 +f 1688/1708/1686 1683/1707/1685 1685/1707/1677 +f 1689/1709/1687 1688/1708/1686 1686/1708/1680 +f 1683/1707/1685 1688/1708/1686 1639/1677/1646 +f 1688/1708/1686 1689/1709/1687 1637/1676/1644 +f 1690/1710/1688 1689/1709/1687 1687/1709/1681 +f 1637/1676/1644 1689/1709/1687 1690/1710/1688 +f 1668/1699/1675 1690/1710/1688 1691/1710/1680 +f 1635/1674/1642 1690/1710/1688 1668/1699/1675 +usemtl Floral_Engraved_Gold +f 1557/1589/1564 1553/1590/1560 1550/1591/1557 +f 1553/1592/1560 1558/1593/1565 1554/1594/1561 +f 1555/1595/1562 1594/1589/1601 1556/1595/1563 +f 1558/1593/1565 1556/1595/1563 1559/1593/1566 +f 1560/1596/1567 1559/1593/1566 1562/1596/1569 +f 1560/1596/1567 1554/1597/1561 1558/1593/1565 +f 1561/1598/1568 1563/1599/1570 1560/1600/1567 +f 1560/1600/1567 1606/1598/1613 1561/1598/1568 +f 1565/1605/1572 1609/1606/1616 1566/1607/1573 +f 1590/1627/1597 1586/1628/1593 1584/1629/1591 +f 1588/1630/1595 1587/1631/1594 1586/1632/1593 +f 1590/1627/1597 1589/1630/1596 1588/1630/1595 +f 1588/1630/1595 1592/1633/1599 1591/1633/1598 +f 1557/1589/1564 1592/1633/1599 1594/1589/1601 +f 1587/1634/1594 1557/1589/1564 1550/1635/1557 +f 1598/1639/1605 1595/1638/1602 1596/1638/1603 +f 1596/1638/1603 1593/1637/1600 1664/1637/1671 +f 1600/1640/1607 1597/1639/1604 1598/1639/1605 +f 1602/1641/1609 1599/1640/1606 1600/1640/1607 +f 1602/1642/1609 1603/1643/1610 1601/1642/1608 +f 1604/1643/1611 1605/1644/1612 1603/1643/1610 +f 1561/1598/1568 1607/1606/1614 1609/1606/1616 +f 1609/1606/1616 1608/1645/1615 1610/1645/1617 +f 1566/1646/1573 1610/1645/1617 1570/1647/1577 +f 1610/1645/1617 1613/1648/1620 1611/1648/1618 +f 1570/1649/1577 1611/1648/1618 1572/1650/1579 +f 1612/1651/1619 1613/1648/1620 1615/1651/1622 +f 1611/1648/1618 1574/1652/1581 1572/1653/1579 +f 1620/1657/1627 1615/1651/1622 1617/1657/1624 +f 1621/1659/1628 1617/1657/1624 1619/1659/1626 +f 1612/1651/1619 1576/1660/1583 1574/1661/1581 +f 1620/1657/1627 1578/1662/1585 1576/1663/1583 +f 1622/1664/1629 1619/1659/1626 1624/1664/1631 +f 1621/1659/1628 1580/1665/1587 1578/1666/1585 +f 1622/1664/1629 1626/1667/1633 1623/1667/1630 +f 1622/1664/1629 1582/1668/1589 1580/1669/1587 +f 1623/1667/1630 1628/1627/1635 1590/1627/1597 +f 1631/1673/1638 1630/1636/1637 1629/1673/1636 +f 1634/1672/1641 1629/1673/1636 1627/1672/1634 +f 1635/1674/1642 1631/1673/1638 1634/1672/1641 +f 1632/1675/1639 1633/1636/1640 1631/1673/1638 +f 1637/1676/1644 1634/1672/1641 1636/1671/1643 +f 1636/1671/1643 1627/1672/1634 1625/1671/1632 +f 1639/1677/1646 1636/1671/1643 1638/1670/1645 +f 1636/1671/1643 1641/1670/1648 1638/1670/1645 +f 1642/1678/1649 1638/1670/1645 1640/1658/1647 +f 1638/1670/1645 1618/1658/1625 1640/1658/1647 +f 1644/1679/1651 1640/1658/1647 1643/1656/1650 +f 1640/1658/1647 1616/1656/1623 1643/1656/1650 +f 1646/1680/1653 1643/1656/1650 1645/1655/1652 +f 1643/1656/1650 1614/1655/1621 1645/1655/1652 +f 1647/1654/1654 1646/1680/1653 1645/1655/1652 +f 1647/1654/1654 1614/1655/1621 1650/1654/1657 +f 1649/1644/1656 1648/1681/1655 1647/1654/1654 +f 1649/1644/1656 1650/1654/1657 1605/1644/1612 +f 1604/1643/1611 1651/1682/1658 1649/1644/1656 +f 1602/1642/1609 1653/1683/1660 1604/1643/1611 +f 1600/1640/1607 1655/1689/1662 1602/1641/1609 +f 1598/1639/1605 1657/1690/1664 1600/1640/1607 +f 1596/1638/1603 1659/1692/1666 1598/1639/1605 +f 1664/1637/1671 1661/1694/1668 1596/1638/1603 +f 1666/1697/1673 1664/1637/1671 1633/1636/1640 +f 1633/1636/1640 1593/1637/1600 1630/1636/1637 +f 1623/1667/1630 1584/1711/1591 1582/1712/1589 +f 1557/1589/1564 1555/1595/1562 1553/1590/1560 +f 1553/1592/1560 1555/1595/1562 1558/1593/1565 +f 1555/1595/1562 1557/1589/1564 1594/1589/1601 +f 1558/1593/1565 1555/1595/1562 1556/1595/1563 +f 1560/1596/1567 1558/1593/1565 1559/1593/1566 +f 1560/1596/1567 1563/1713/1570 1554/1597/1561 +f 1561/1598/1568 1565/1714/1572 1563/1599/1570 +f 1560/1600/1567 1562/1600/1569 1606/1598/1613 +f 1565/1605/1572 1561/1598/1568 1609/1606/1616 +f 1590/1627/1597 1588/1630/1595 1586/1628/1593 +f 1588/1630/1595 1591/1633/1598 1587/1631/1594 +f 1590/1627/1597 1628/1627/1635 1589/1630/1596 +f 1588/1630/1595 1589/1630/1596 1592/1633/1599 +f 1557/1589/1564 1591/1633/1598 1592/1633/1599 +f 1587/1634/1594 1591/1633/1598 1557/1589/1564 +f 1598/1639/1605 1597/1639/1604 1595/1638/1602 +f 1596/1638/1603 1595/1638/1602 1593/1637/1600 +f 1600/1640/1607 1599/1640/1606 1597/1639/1604 +f 1602/1641/1609 1601/1641/1608 1599/1640/1606 +f 1602/1642/1609 1604/1643/1611 1603/1643/1610 +f 1604/1643/1611 1649/1644/1656 1605/1644/1612 +f 1561/1598/1568 1606/1598/1613 1607/1606/1614 +f 1609/1606/1616 1607/1606/1614 1608/1645/1615 +f 1566/1646/1573 1609/1606/1616 1610/1645/1617 +f 1610/1645/1617 1608/1645/1615 1613/1648/1620 +f 1570/1649/1577 1610/1645/1617 1611/1648/1618 +f 1612/1651/1619 1611/1648/1618 1613/1648/1620 +f 1611/1648/1618 1612/1651/1619 1574/1652/1581 +f 1620/1657/1627 1612/1651/1619 1615/1651/1622 +f 1621/1659/1628 1620/1657/1627 1617/1657/1624 +f 1612/1651/1619 1620/1657/1627 1576/1660/1583 +f 1620/1657/1627 1621/1659/1628 1578/1662/1585 +f 1622/1664/1629 1621/1659/1628 1619/1659/1626 +f 1621/1659/1628 1622/1664/1629 1580/1665/1587 +f 1622/1664/1629 1624/1664/1631 1626/1667/1633 +f 1622/1664/1629 1623/1667/1630 1582/1668/1589 +f 1623/1667/1630 1626/1667/1633 1628/1627/1635 +f 1631/1673/1638 1633/1636/1640 1630/1636/1637 +f 1634/1672/1641 1631/1673/1638 1629/1673/1636 +f 1635/1674/1642 1632/1675/1639 1631/1673/1638 +f 1632/1675/1639 1666/1697/1673 1633/1636/1640 +f 1637/1676/1644 1635/1674/1642 1634/1672/1641 +f 1636/1671/1643 1634/1672/1641 1627/1672/1634 +f 1639/1677/1646 1637/1676/1644 1636/1671/1643 +f 1636/1671/1643 1625/1671/1632 1641/1670/1648 +f 1642/1678/1649 1639/1677/1646 1638/1670/1645 +f 1638/1670/1645 1641/1670/1648 1618/1658/1625 +f 1644/1679/1651 1642/1678/1649 1640/1658/1647 +f 1640/1658/1647 1618/1658/1625 1616/1656/1623 +f 1646/1680/1653 1644/1679/1651 1643/1656/1650 +f 1643/1656/1650 1616/1656/1623 1614/1655/1621 +f 1647/1654/1654 1648/1681/1655 1646/1680/1653 +f 1647/1654/1654 1645/1655/1652 1614/1655/1621 +f 1649/1644/1656 1651/1682/1658 1648/1681/1655 +f 1649/1644/1656 1647/1654/1654 1650/1654/1657 +f 1604/1643/1611 1653/1683/1660 1651/1682/1658 +f 1602/1642/1609 1655/1686/1662 1653/1683/1660 +f 1600/1640/1607 1657/1690/1664 1655/1689/1662 +f 1598/1639/1605 1659/1692/1666 1657/1690/1664 +f 1596/1638/1603 1661/1694/1668 1659/1692/1666 +f 1664/1637/1671 1663/1696/1670 1661/1694/1668 +f 1666/1697/1673 1663/1696/1670 1664/1637/1671 +f 1633/1636/1640 1664/1637/1671 1593/1637/1600 +f 1623/1667/1630 1590/1627/1597 1584/1711/1591 +o Cube.022 +v -0.014631 1.528037 -0.200218 +v -0.027035 1.519749 -0.200218 +v 0.000000 1.530947 -0.200218 +v -0.014667 1.528123 -0.190344 +v -0.011146 1.519623 -0.210163 +v -0.020595 1.513309 -0.210163 +v 0.000000 1.521840 -0.210163 +v 0.011146 1.519623 -0.210163 +v 0.014631 1.528037 -0.200218 +v 0.020595 1.513309 -0.210163 +v 0.027035 1.519749 -0.200218 +v 0.026909 1.503860 -0.210163 +v 0.035323 1.507345 -0.200218 +v 0.029126 1.492714 -0.210163 +v 0.038233 1.492714 -0.200218 +v 0.026909 1.481568 -0.210163 +v 0.035323 1.478083 -0.200218 +v 0.020595 1.472119 -0.210163 +v 0.027035 1.465679 -0.200218 +v 0.011146 1.465805 -0.210163 +v 0.014631 1.457391 -0.200218 +v 0.000000 1.463588 -0.210163 +v 0.000000 1.454481 -0.200218 +v -0.011146 1.465805 -0.210163 +v -0.014631 1.457391 -0.200218 +v -0.020595 1.472119 -0.210163 +v -0.027035 1.465679 -0.200218 +v -0.026909 1.481568 -0.210163 +v -0.035323 1.478083 -0.200218 +v -0.029126 1.492714 -0.210163 +v -0.038233 1.492714 -0.200218 +v -0.026909 1.503860 -0.210163 +v -0.035323 1.507345 -0.200218 +v -0.035409 1.507381 -0.190344 +v -0.038076 1.508486 -0.184230 +v -0.038327 1.492714 -0.190344 +v -0.027101 1.519815 -0.190344 +v -0.029142 1.521856 -0.184230 +v -0.015772 1.530790 -0.184230 +v -0.029142 1.521856 -0.011067 +v -0.028016 1.520730 -0.011067 +v -0.038076 1.508486 -0.011067 +v -0.015772 1.530790 -0.011067 +v -0.015162 1.529319 -0.011067 +v 0.000000 1.533927 -0.011067 +v 0.015772 1.530790 -0.011067 +v 0.000000 1.532335 -0.011067 +v 0.000000 1.533927 -0.184230 +v 0.000000 1.531041 -0.190344 +v 0.015772 1.530790 -0.184230 +v 0.029142 1.521856 -0.184230 +v 0.014667 1.528123 -0.190344 +v 0.027101 1.519815 -0.190344 +v 0.035409 1.507381 -0.190344 +v 0.038076 1.508486 -0.184230 +v 0.038327 1.492714 -0.190344 +v 0.041213 1.492714 -0.184230 +v 0.035409 1.478047 -0.190344 +v 0.038076 1.476942 -0.184230 +v 0.027101 1.465613 -0.190344 +v 0.029142 1.463572 -0.184230 +v 0.014667 1.457305 -0.190344 +v 0.015772 1.454638 -0.184230 +v 0.000000 1.454387 -0.190344 +v 0.000000 1.451501 -0.184230 +v -0.014667 1.457305 -0.190344 +v -0.015772 1.454638 -0.184230 +v -0.027101 1.465613 -0.190344 +v -0.029142 1.463572 -0.184230 +v -0.035409 1.478047 -0.190344 +v -0.038076 1.476942 -0.184230 +v -0.041213 1.492714 -0.184230 +v -0.038076 1.476942 -0.011067 +v -0.036605 1.477552 -0.011067 +v -0.029142 1.463572 -0.011067 +v -0.041213 1.492714 -0.011067 +v -0.039621 1.492714 -0.011067 +v -0.039621 1.492714 -0.004289 +v -0.036605 1.507876 -0.011067 +v -0.036605 1.507876 -0.004289 +v -0.038076 1.508486 -0.004289 +v -0.028016 1.520730 -0.004289 +v -0.029142 1.521856 -0.004289 +v -0.015162 1.529319 -0.004289 +v -0.015772 1.530790 -0.004289 +v 0.000000 1.532335 -0.004289 +v 0.000000 1.533927 -0.004289 +v 0.015162 1.529319 -0.004289 +v 0.015772 1.530790 -0.004289 +v 0.028016 1.520730 -0.004289 +v 0.015162 1.529319 -0.011067 +v 0.028016 1.520730 -0.011067 +v 0.036605 1.507876 -0.011067 +v 0.029142 1.521856 -0.011067 +v 0.038076 1.508486 -0.011067 +v 0.041213 1.492714 -0.011067 +v 0.038076 1.476942 -0.011067 +v 0.039621 1.492714 -0.011067 +v 0.039621 1.492714 -0.004289 +v 0.036605 1.477552 -0.011067 +v 0.036605 1.477552 -0.004289 +v 0.028016 1.464698 -0.011067 +v 0.028016 1.464698 -0.004289 +v 0.015162 1.456109 -0.011067 +v 0.029142 1.463572 -0.011067 +v 0.015772 1.454638 -0.011067 +v 0.000000 1.451501 -0.011067 +v -0.015772 1.454638 -0.011067 +v 0.000000 1.453093 -0.011067 +v 0.000000 1.453093 -0.004289 +v -0.015162 1.456109 -0.011067 +v -0.015162 1.456109 -0.004289 +v -0.028016 1.464698 -0.011067 +v -0.028016 1.464698 -0.004289 +v -0.036605 1.477552 -0.004289 +v -0.029142 1.463572 -0.004289 +v -0.029142 1.463572 0.037075 +v -0.038076 1.476942 -0.004289 +v -0.015772 1.454638 -0.004289 +v -0.015772 1.454638 0.037075 +v 0.000000 1.451501 -0.004289 +v 0.000000 1.451501 0.037075 +v 0.015772 1.454638 -0.004289 +v 0.015772 1.454638 0.037075 +v 0.029142 1.463572 -0.004289 +v 0.015162 1.456109 -0.004289 +v 0.029142 1.463572 0.037075 +v 0.038076 1.476942 -0.004289 +v 0.038076 1.476942 0.037075 +v 0.041213 1.492714 -0.004289 +v 0.041213 1.492714 0.037075 +v 0.038076 1.508486 -0.004289 +v 0.038076 1.508486 0.037075 +v 0.029142 1.521856 -0.004289 +v 0.036605 1.507876 -0.004289 +v 0.029142 1.521856 0.037075 +v 0.027609 1.520323 0.043556 +v 0.015772 1.530790 0.037075 +v 0.014942 1.528787 0.043556 +v 0.000000 1.533927 0.037075 +v 0.000000 1.531759 0.043556 +v -0.015772 1.530790 0.037075 +v -0.014942 1.528787 0.043556 +v -0.029142 1.521856 0.037075 +v -0.027609 1.520323 0.043556 +v -0.038076 1.508486 0.037075 +v -0.036073 1.507656 0.043556 +v -0.041213 1.492714 0.037075 +v -0.041213 1.492714 -0.004289 +v -0.039045 1.492714 0.043556 +v -0.038076 1.476942 0.037075 +v -0.036073 1.477772 0.043556 +v -0.027609 1.465105 0.043556 +v -0.036073 1.477772 0.043556 +v -0.027609 1.465105 0.043556 +v -0.039045 1.492714 0.043556 +v -0.036073 1.507656 0.043556 +v -0.027609 1.520323 0.043556 +v -0.014942 1.528787 0.043556 +v 0.000000 1.531759 0.043556 +v 0.014942 1.528787 0.043556 +v 0.027609 1.520323 0.043556 +v 0.036073 1.507656 0.043556 +v 0.039045 1.492714 0.043556 +v 0.036073 1.507656 0.043556 +v 0.039045 1.492714 0.043556 +v 0.036073 1.477772 0.043556 +v 0.027609 1.465105 0.043556 +v 0.036073 1.477772 0.043556 +v 0.027609 1.465105 0.043556 +v 0.014942 1.456641 0.043556 +v 0.000000 1.453669 0.043556 +v 0.014942 1.456641 0.043556 +v 0.000000 1.453669 0.043556 +v -0.014942 1.456641 0.043556 +v -0.014942 1.456641 0.043556 +vn -0.3953 0.8464 -0.3568 +vn -0.7091 0.6233 -0.3296 +vn -0.0000 0.9322 -0.3621 +vn -0.3620 0.9053 -0.2221 +vn -0.1339 0.4019 -0.9059 +vn -0.2889 0.3467 -0.8924 +vn -0.0000 0.4157 -0.9095 +vn 0.1339 0.4018 -0.9059 +vn 0.3953 0.8464 -0.3568 +vn 0.2889 0.3467 -0.8924 +vn 0.7091 0.6233 -0.3296 +vn 0.4621 0.2268 -0.8574 +vn 0.9171 0.3102 -0.2505 +vn 0.5874 -0.0000 -0.8093 +vn 0.9835 -0.0000 -0.1810 +vn 0.4620 -0.2268 -0.8574 +vn 0.9171 -0.3102 -0.2505 +vn 0.2889 -0.3467 -0.8924 +vn 0.7091 -0.6233 -0.3296 +vn 0.1339 -0.4019 -0.9059 +vn 0.3953 -0.8464 -0.3568 +vn -0.0000 -0.4157 -0.9095 +vn -0.0000 -0.9321 -0.3621 +vn -0.1339 -0.4019 -0.9059 +vn -0.3953 -0.8464 -0.3568 +vn -0.2889 -0.3467 -0.8924 +vn -0.7091 -0.6233 -0.3296 +vn -0.4620 -0.2268 -0.8574 +vn -0.9171 -0.3102 -0.2505 +vn -0.5874 -0.0000 -0.8093 +vn -0.9835 -0.0000 -0.1810 +vn -0.4621 0.2268 -0.8574 +vn -0.9171 0.3102 -0.2505 +vn -0.9104 0.3614 -0.2012 +vn -0.9338 0.3102 -0.1781 +vn -0.9775 -0.0000 -0.2109 +vn -0.6851 0.6965 -0.2132 +vn -0.7350 0.6447 -0.2101 +vn -0.4089 0.8865 -0.2165 +vn -0.6058 0.5677 0.5574 +vn -0.5764 0.5402 0.6131 +vn -0.8822 0.3126 0.3521 +vn -0.2963 0.6869 0.6635 +vn -0.2843 0.6591 0.6962 +vn -0.0000 0.7202 0.6938 +vn 0.2963 0.6869 0.6636 +vn -0.0000 0.6930 0.7210 +vn -0.0000 0.9762 -0.2170 +vn -0.0000 0.9743 -0.2252 +vn 0.4089 0.8866 -0.2165 +vn 0.7350 0.6447 -0.2101 +vn 0.3620 0.9053 -0.2221 +vn 0.6851 0.6965 -0.2132 +vn 0.9104 0.3614 -0.2012 +vn 0.9338 0.3102 -0.1781 +vn 0.9775 -0.0000 -0.2109 +vn 0.9902 -0.0000 -0.1394 +vn 0.9104 -0.3614 -0.2012 +vn 0.9338 -0.3102 -0.1781 +vn 0.6851 -0.6965 -0.2132 +vn 0.7350 -0.6447 -0.2101 +vn 0.3620 -0.9053 -0.2221 +vn 0.4089 -0.8866 -0.2165 +vn -0.0000 -0.9743 -0.2252 +vn -0.0000 -0.9762 -0.2170 +vn -0.3620 -0.9053 -0.2221 +vn -0.4089 -0.8866 -0.2165 +vn -0.6851 -0.6965 -0.2132 +vn -0.7350 -0.6447 -0.2101 +vn -0.9104 -0.3614 -0.2012 +vn -0.9338 -0.3102 -0.1781 +vn -0.9902 -0.0000 -0.1394 +vn -0.8822 -0.3126 0.3521 +vn -0.8290 -0.2938 0.4759 +vn -0.6058 -0.5677 0.5574 +vn -0.9746 -0.0000 0.2240 +vn -0.8952 -0.0000 0.4457 +vn -0.8952 -0.0000 -0.4457 +vn -0.8290 0.2938 0.4759 +vn -0.8290 0.2938 -0.4759 +vn -0.8822 0.3126 -0.3521 +vn -0.5765 0.5402 -0.6131 +vn -0.6058 0.5677 -0.5574 +vn -0.2843 0.6591 -0.6962 +vn -0.2963 0.6869 -0.6635 +vn -0.0000 0.6930 -0.7210 +vn -0.0000 0.7202 -0.6937 +vn 0.2843 0.6591 -0.6962 +vn 0.2963 0.6870 -0.6635 +vn 0.5765 0.5402 -0.6131 +vn 0.2843 0.6591 0.6962 +vn 0.5765 0.5402 0.6131 +vn 0.8290 0.2938 0.4759 +vn 0.6058 0.5677 0.5574 +vn 0.8822 0.3126 0.3521 +vn 0.9746 -0.0000 0.2240 +vn 0.8822 -0.3126 0.3521 +vn 0.8952 -0.0000 0.4457 +vn 0.8952 -0.0000 -0.4457 +vn 0.8290 -0.2938 0.4759 +vn 0.8290 -0.2938 -0.4759 +vn 0.5765 -0.5402 0.6131 +vn 0.5764 -0.5402 -0.6131 +vn 0.2843 -0.6591 0.6962 +vn 0.6058 -0.5677 0.5574 +vn 0.2963 -0.6869 0.6636 +vn -0.0000 -0.7202 0.6938 +vn -0.2963 -0.6869 0.6636 +vn -0.0000 -0.6930 0.7210 +vn -0.0000 -0.6930 -0.7210 +vn -0.2843 -0.6591 0.6962 +vn -0.2843 -0.6591 -0.6962 +vn -0.5765 -0.5402 0.6131 +vn -0.5765 -0.5402 -0.6131 +vn -0.8290 -0.2938 -0.4759 +vn -0.6058 -0.5677 -0.5574 +vn -0.7397 -0.6542 0.1577 +vn -0.8822 -0.3126 -0.3521 +vn -0.2963 -0.6870 -0.6635 +vn -0.4090 -0.8984 0.1598 +vn -0.0000 -0.7202 -0.6937 +vn -0.0000 -0.9872 0.1597 +vn 0.2963 -0.6870 -0.6635 +vn 0.4090 -0.8984 0.1598 +vn 0.6058 -0.5677 -0.5574 +vn 0.2843 -0.6591 -0.6962 +vn 0.7397 -0.6542 0.1577 +vn 0.8822 -0.3126 -0.3521 +vn 0.9394 -0.3124 0.1414 +vn 0.9746 -0.0000 -0.2240 +vn 0.9932 -0.0000 0.1167 +vn 0.8822 0.3126 -0.3521 +vn 0.9394 0.3124 0.1414 +vn 0.6058 0.5677 -0.5574 +vn 0.8290 0.2938 -0.4759 +vn 0.7397 0.6542 0.1577 +vn 0.9721 0.2134 0.0970 +vn 0.4090 0.8984 0.1598 +vn 0.9638 0.2509 0.0897 +vn -0.0000 0.9872 0.1598 +vn 0.9557 0.2791 0.0934 +vn -0.4090 0.8984 0.1598 +vn 0.9455 0.3067 0.1097 +vn -0.7397 0.6542 0.1577 +vn 0.9270 0.3416 0.1552 +vn -0.9394 0.3123 0.1414 +vn 0.8642 0.3869 0.3216 +vn -0.9932 -0.0000 0.1167 +vn -0.9746 -0.0000 -0.2240 +vn 0.6455 -0.0000 0.7637 +vn -0.9394 -0.3123 0.1414 +vn 0.8642 -0.3869 0.3216 +vn 0.9270 -0.3416 0.1552 +vn 0.9702 -0.0000 0.2424 +vn 0.9623 -0.0000 0.2720 +vn 0.9820 -0.0000 0.1890 +vn 0.9702 -0.0000 0.2425 +vn 0.9602 -0.0000 0.2795 +vn 0.9597 -0.0000 0.2811 +vn 0.9602 -0.0000 0.2794 +vn 0.9821 0.1448 0.1203 +vn 0.9894 -0.0000 0.1450 +vn 0.9821 -0.1448 0.1203 +vn 0.9721 -0.2134 0.0970 +vn 0.9638 -0.2509 0.0897 +vn 0.9557 -0.2790 0.0933 +vn 0.9455 -0.3067 0.1097 +vt 0.661368 0.463977 +vt 0.605181 0.394819 +vt 0.586229 0.413771 +vt 0.671624 0.439216 +vt 0.630067 0.369933 +vt 0.750000 0.454806 +vt 0.685093 0.406700 +vt 0.750000 0.481607 +vt 0.814908 0.093300 +vt 0.593300 0.185093 +vt 0.814907 0.406700 +vt 0.750000 0.419611 +vt 0.828376 0.439216 +vt 0.869933 0.369933 +vt 0.894819 0.394819 +vt 0.906701 0.314908 +vt 0.939216 0.328376 +vt 0.919611 0.250000 +vt 0.939216 0.171624 +vt 0.954806 0.250000 +vt 0.894819 0.105181 +vt 0.906700 0.185093 +vt 0.828376 0.060784 +vt 0.869933 0.130067 +vt 0.750000 0.045194 +vt 0.685093 0.093300 +vt 0.750000 0.080389 +vt 0.671624 0.060784 +vt 0.630067 0.130067 +vt 0.605181 0.105181 +vt 0.560784 0.171624 +vt 0.580389 0.250000 +vt 0.560784 0.328376 +vt 0.545194 0.250000 +vt 0.593300 0.314907 +vt 0.536023 0.338632 +vt 0.518393 0.250000 +vt 0.580294 0.419706 +vt 0.528269 0.341844 +vt 0.510000 0.250000 +vt 0.658156 0.471731 +vt 0.187500 0.895448 +vt 0.125000 0.532007 +vt 0.187500 0.532007 +vt 0.125000 0.532007 +vt 0.062500 0.895448 +vt 0.062500 0.532007 +vt 0.125000 0.895448 +vt 0.000000 0.895448 +vt 0.062500 0.532007 +vt 0.937500 0.895448 +vt 1.000000 0.532007 +vt 1.000000 0.895448 +vt 0.750000 0.490000 +vt 0.838632 0.463977 +vt 0.841844 0.471731 +vt 0.913771 0.413771 +vt 0.937500 0.532007 +vt 0.875000 0.895448 +vt 0.875000 0.532007 +vt 0.919706 0.419706 +vt 0.963977 0.338632 +vt 0.971731 0.341844 +vt 0.981607 0.250000 +vt 0.963977 0.161368 +vt 0.971731 0.158156 +vt 0.990000 0.250000 +vt 0.913771 0.086229 +vt 0.919706 0.080294 +vt 0.838632 0.036023 +vt 0.841844 0.028269 +vt 0.750000 0.018393 +vt 0.750000 0.010000 +vt 0.661368 0.036023 +vt 0.658156 0.028269 +vt 0.586229 0.086229 +vt 0.580294 0.080294 +vt 0.536023 0.161368 +vt 0.528269 0.158156 +vt 0.375000 0.895448 +vt 0.312500 0.532007 +vt 0.375000 0.532007 +vt 0.312500 0.895448 +vt 0.250000 0.532007 +vt 0.312500 0.532007 +vt 0.250000 0.895448 +vt 0.187500 0.532007 +vt 0.250000 0.532007 +vt 0.312500 0.915363 +vt 0.250000 0.915363 +vt 0.187500 0.915363 +vt 0.125000 0.915363 +vt 0.062500 0.915363 +vt 0.000000 0.915363 +vt 1.000000 0.915363 +vt 0.937500 0.915363 +vt 0.875000 0.915363 +vt 0.812500 0.895448 +vt 0.875000 0.532007 +vt 0.812500 0.532007 +vt 0.750000 0.895448 +vt 0.750000 0.532007 +vt 0.812500 0.532007 +vt 0.687500 0.895448 +vt 0.687500 0.532007 +vt 0.750000 0.532007 +vt 0.812500 0.915363 +vt 0.750000 0.915363 +vt 0.625000 0.915363 +vt 0.625000 0.895448 +vt 0.562500 0.895448 +vt 0.625000 0.532007 +vt 0.687500 0.532007 +vt 0.562500 0.532007 +vt 0.625000 0.532007 +vt 0.500000 0.895448 +vt 0.500000 0.532007 +vt 0.562500 0.532007 +vt 0.437500 0.895448 +vt 0.437500 0.532007 +vt 0.500000 0.532007 +vt 0.562500 0.915363 +vt 0.500000 0.915363 +vt 0.437500 0.915363 +vt 0.375000 0.915363 +vt 0.437500 0.980957 +vt 0.375000 0.980957 +vt 0.500000 0.980957 +vt 0.562500 0.980957 +vt 0.625000 0.980957 +vt 0.687500 0.980957 +vt 0.687500 0.915363 +vt 0.812500 0.980957 +vt 0.875000 0.980957 +vt 0.937500 0.980957 +vt 0.875000 1.000000 +vt 0.812500 1.000000 +vt 1.000000 0.980957 +vt 0.937500 1.000000 +vt 0.062500 1.000000 +vt 0.000000 0.980957 +vt 0.062500 0.980957 +vt 0.125000 1.000000 +vt 0.125000 0.980957 +vt 0.187500 0.980957 +vt 0.187500 1.000000 +vt 0.250000 0.980957 +vt 0.250000 1.000000 +vt 0.312500 0.980957 +vt 0.312500 1.000000 +vt 0.375000 1.000000 +vt 0.080294 0.080294 +vt 0.419706 0.080294 +vt 0.419706 0.419706 +vt 0.000000 1.000000 +vt 1.000000 1.000000 +vt 0.750000 1.000000 +vt 0.750000 0.980957 +vt 0.687500 1.000000 +vt 0.625000 1.000000 +vt 0.562500 1.000000 +vt 0.500000 1.000000 +vt 0.437500 1.000000 +vt 0.375000 0.532007 +vt 0.437500 0.532007 +vt 0.000000 0.532007 +vt 0.937500 0.532007 +vt 0.341844 0.471731 +vt 0.250000 0.490000 +vt 0.158156 0.471731 +vt 0.080294 0.419706 +vt 0.028269 0.341844 +vt 0.010000 0.250000 +vt 0.028269 0.158156 +vt 0.158156 0.028269 +vt 0.250000 0.010000 +vt 0.341844 0.028269 +vt 0.471731 0.158156 +vt 0.490000 0.250000 +vt 0.471731 0.341844 +s 1 +usemtl Brass.001 +f 1695/1728/1692 1693/1729/1690 1728/1730/1725 +f 1692/1731/1689 1697/1732/1694 1693/1729/1690 +f 1694/1733/1691 1696/1734/1693 1692/1731/1689 +f 1740/1735/1737 1692/1731/1689 1695/1728/1692 +f 1711/1736/1708 1719/1737/1716 1696/1734/1693 +f 1694/1733/1691 1699/1738/1696 1698/1739/1695 +f 1700/1740/1697 1701/1741/1698 1699/1738/1696 +f 1702/1742/1699 1703/1743/1700 1701/1741/1698 +f 1704/1744/1701 1705/1745/1702 1703/1743/1700 +f 1708/1746/1705 1705/1745/1702 1706/1747/1703 +f 1710/1748/1707 1707/1749/1704 1708/1746/1705 +f 1712/1750/1709 1709/1751/1706 1710/1748/1707 +f 1714/1752/1711 1711/1736/1708 1712/1750/1709 +f 1714/1752/1711 1715/1753/1712 1713/1754/1710 +f 1716/1755/1713 1717/1756/1714 1715/1753/1712 +f 1718/1757/1715 1719/1737/1716 1717/1756/1714 +f 1720/1758/1717 1721/1759/1718 1719/1737/1716 +f 1724/1760/1721 1721/1759/1718 1722/1761/1719 +f 1693/1729/1690 1723/1762/1720 1724/1760/1721 +f 1725/1763/1722 1722/1761/1719 1727/1764/1724 +f 1728/1730/1725 1724/1760/1721 1725/1763/1722 +f 1729/1765/1726 1725/1763/1722 1726/1766/1723 +f 1726/1766/1723 1727/1764/1724 1763/1767/1760 +f 1730/1768/1727 1728/1730/1725 1729/1765/1726 +f 1739/1781/1736 1695/1728/1692 1730/1768/1727 +f 1739/1781/1736 1743/1782/1740 1740/1735/1737 +f 1741/1783/1738 1744/1784/1741 1743/1782/1740 +f 1740/1735/1737 1700/1740/1697 1694/1733/1691 +f 1743/1782/1740 1702/1742/1699 1700/1740/1697 +f 1744/1784/1741 1704/1744/1701 1702/1742/1699 +f 1742/1788/1739 1745/1789/1742 1744/1784/1741 +f 1745/1789/1742 1706/1747/1703 1704/1744/1701 +f 1746/1790/1743 1747/1791/1744 1745/1789/1742 +f 1749/1792/1746 1706/1747/1703 1747/1791/1744 +f 1750/1793/1747 1747/1791/1744 1748/1794/1745 +f 1751/1795/1748 1708/1746/1705 1749/1792/1746 +f 1752/1796/1749 1749/1792/1746 1750/1793/1747 +f 1753/1797/1750 1710/1748/1707 1751/1795/1748 +f 1754/1798/1751 1751/1795/1748 1752/1796/1749 +f 1755/1799/1752 1712/1750/1709 1753/1797/1750 +f 1756/1800/1753 1753/1797/1750 1754/1798/1751 +f 1755/1799/1752 1716/1755/1713 1714/1752/1711 +f 1756/1800/1753 1757/1801/1754 1755/1799/1752 +f 1757/1801/1754 1718/1757/1715 1716/1755/1713 +f 1758/1802/1755 1759/1803/1756 1757/1801/1754 +f 1759/1803/1756 1720/1758/1717 1718/1757/1715 +f 1760/1804/1757 1761/1805/1758 1759/1803/1756 +f 1761/1805/1758 1722/1761/1719 1720/1758/1717 +f 1762/1806/1759 1727/1764/1724 1761/1805/1758 +f 1806/1816/1803 1768/1813/1765 1765/1810/1762 +f 1769/1817/1766 1770/1769/1767 1768/1813/1765 +f 1771/1818/1768 1732/1775/1729 1770/1769/1767 +f 1732/1775/1729 1775/1820/1772 1735/1773/1732 +f 1735/1773/1732 1777/1821/1774 1738/1776/1735 +f 1738/1780/1735 1779/1823/1776 1782/1778/1779 +f 1782/1778/1779 1781/1824/1778 1783/1786/1780 +f 1781/1824/1778 1784/1825/1781 1783/1786/1780 +f 1826/1834/1823 1789/1828/1786 1784/1825/1781 +f 1790/1835/1787 1791/1831/1788 1789/1828/1786 +f 1791/1831/1788 1794/1836/1791 1793/1837/1790 +f 1794/1836/1791 1795/1838/1792 1793/1837/1790 +f 1817/1849/1814 1800/1843/1797 1795/1838/1792 +f 1801/1850/1798 1802/1846/1799 1800/1843/1797 +f 1803/1851/1800 1804/1807/1801 1802/1846/1799 +f 1805/1852/1802 1765/1810/1762 1804/1807/1801 +f 1829/1862/1826 1828/1863/1825 1827/1861/1824 +f 1827/1861/1824 1856/1864/1849 1824/1860/1821 +f 1831/1865/1828 1830/1866/1827 1829/1862/1826 +f 1834/1867/1831 1831/1868/1828 1833/1869/1830 +f 1836/1870/1833 1833/1869/1830 1835/1871/1832 +f 1838/1873/1835 1835/1871/1832 1837/1872/1834 +f 1841/1875/1838 1837/1872/1834 1839/1874/1836 +f 1842/1876/1839 1841/1875/1838 1839/1874/1836 +f 1808/1854/1805 1843/1877/1840 1842/1876/1839 +f 1843/1877/1840 1846/1878/1843 1845/1877/1842 +f 1841/1875/1838 1845/1877/1842 1847/1875/1844 +f 1846/1879/1843 1861/1880/1843 1853/1881/1843 +f 1838/1873/1835 1847/1875/1844 1848/1873/1845 +f 1836/1870/1833 1848/1873/1845 1849/1870/1843 +f 1834/1867/1831 1849/1870/1843 1850/1867/1846 +f 1832/1882/1829 1850/1867/1846 1851/1882/1847 +f 1830/1866/1827 1851/1883/1847 1852/1866/1848 +f 1828/1863/1825 1852/1866/1848 1853/1863/1843 +f 1856/1864/1849 1853/1863/1843 1854/1864/1845 +f 1857/1884/1850 1854/1864/1845 1855/1884/1844 +f 1824/1860/1821 1857/1884/1850 1822/1885/1819 +f 1858/1886/1851 1855/1884/1844 1860/1886/1845 +f 1857/1884/1850 1820/1858/1817 1822/1885/1819 +f 1859/1887/1852 1860/1886/1845 1861/1887/1843 +f 1858/1886/1851 1818/1857/1815 1820/1858/1817 +f 1864/1888/1853 1861/1887/1843 1862/1888/1848 +f 1865/1889/1854 1862/1888/1848 1863/1889/1847 +f 1859/1887/1852 1815/1856/1812 1818/1857/1815 +f 1864/1888/1853 1813/1855/1810 1815/1856/1812 +f 1866/1890/1855 1863/1889/1847 1867/1890/1846 +f 1813/1855/1810 1866/1890/1855 1811/1853/1808 +f 1844/1878/1841 1867/1890/1846 1846/1878/1843 +f 1811/1853/1808 1844/1878/1841 1808/1854/1805 +f 1695/1728/1692 1692/1731/1689 1693/1729/1690 +f 1692/1731/1689 1696/1734/1693 1697/1732/1694 +f 1694/1733/1691 1698/1739/1695 1696/1734/1693 +f 1740/1735/1737 1694/1733/1691 1692/1731/1689 +f 1696/1734/1693 1698/1739/1695 1699/1738/1696 +f 1699/1738/1696 1701/1741/1698 1703/1743/1700 +f 1703/1743/1700 1705/1745/1702 1707/1749/1704 +f 1707/1749/1704 1709/1751/1706 1711/1736/1708 +f 1711/1736/1708 1713/1754/1710 1715/1753/1712 +f 1715/1753/1712 1717/1756/1714 1719/1737/1716 +f 1719/1737/1716 1721/1759/1718 1723/1762/1720 +f 1723/1762/1720 1697/1732/1694 1696/1734/1693 +f 1696/1734/1693 1699/1738/1696 1703/1743/1700 +f 1703/1743/1700 1707/1749/1704 1711/1736/1708 +f 1711/1736/1708 1715/1753/1712 1719/1737/1716 +f 1719/1737/1716 1723/1762/1720 1696/1734/1693 +f 1696/1734/1693 1703/1743/1700 1711/1736/1708 +f 1694/1733/1691 1700/1740/1697 1699/1738/1696 +f 1700/1740/1697 1702/1742/1699 1701/1741/1698 +f 1702/1742/1699 1704/1744/1701 1703/1743/1700 +f 1704/1744/1701 1706/1747/1703 1705/1745/1702 +f 1708/1746/1705 1707/1749/1704 1705/1745/1702 +f 1710/1748/1707 1709/1751/1706 1707/1749/1704 +f 1712/1750/1709 1711/1736/1708 1709/1751/1706 +f 1714/1752/1711 1713/1754/1710 1711/1736/1708 +f 1714/1752/1711 1716/1755/1713 1715/1753/1712 +f 1716/1755/1713 1718/1757/1715 1717/1756/1714 +f 1718/1757/1715 1720/1758/1717 1719/1737/1716 +f 1720/1758/1717 1722/1761/1719 1721/1759/1718 +f 1724/1760/1721 1723/1762/1720 1721/1759/1718 +f 1693/1729/1690 1697/1732/1694 1723/1762/1720 +f 1725/1763/1722 1724/1760/1721 1722/1761/1719 +f 1728/1730/1725 1693/1729/1690 1724/1760/1721 +f 1729/1765/1726 1728/1730/1725 1725/1763/1722 +f 1726/1766/1723 1725/1763/1722 1727/1764/1724 +f 1730/1768/1727 1695/1728/1692 1728/1730/1725 +f 1739/1781/1736 1740/1735/1737 1695/1728/1692 +f 1739/1781/1736 1741/1783/1738 1743/1782/1740 +f 1741/1783/1738 1742/1788/1739 1744/1784/1741 +f 1740/1735/1737 1743/1782/1740 1700/1740/1697 +f 1743/1782/1740 1744/1784/1741 1702/1742/1699 +f 1744/1784/1741 1745/1789/1742 1704/1744/1701 +f 1742/1788/1739 1746/1790/1743 1745/1789/1742 +f 1745/1789/1742 1747/1791/1744 1706/1747/1703 +f 1746/1790/1743 1748/1794/1745 1747/1791/1744 +f 1749/1792/1746 1708/1746/1705 1706/1747/1703 +f 1750/1793/1747 1749/1792/1746 1747/1791/1744 +f 1751/1795/1748 1710/1748/1707 1708/1746/1705 +f 1752/1796/1749 1751/1795/1748 1749/1792/1746 +f 1753/1797/1750 1712/1750/1709 1710/1748/1707 +f 1754/1798/1751 1753/1797/1750 1751/1795/1748 +f 1755/1799/1752 1714/1752/1711 1712/1750/1709 +f 1756/1800/1753 1755/1799/1752 1753/1797/1750 +f 1755/1799/1752 1757/1801/1754 1716/1755/1713 +f 1756/1800/1753 1758/1802/1755 1757/1801/1754 +f 1757/1801/1754 1759/1803/1756 1718/1757/1715 +f 1758/1802/1755 1760/1804/1757 1759/1803/1756 +f 1759/1803/1756 1761/1805/1758 1720/1758/1717 +f 1760/1804/1757 1762/1806/1759 1761/1805/1758 +f 1761/1805/1758 1727/1764/1724 1722/1761/1719 +f 1762/1806/1759 1763/1767/1760 1727/1764/1724 +f 1806/1816/1803 1769/1817/1766 1768/1813/1765 +f 1769/1817/1766 1771/1818/1768 1770/1769/1767 +f 1771/1818/1768 1773/1819/1770 1732/1775/1729 +f 1732/1775/1729 1773/1819/1770 1775/1820/1772 +f 1735/1773/1732 1775/1820/1772 1777/1821/1774 +f 1738/1780/1735 1777/1822/1774 1779/1823/1776 +f 1782/1778/1779 1779/1823/1776 1781/1824/1778 +f 1781/1824/1778 1826/1834/1823 1784/1825/1781 +f 1826/1834/1823 1790/1835/1787 1789/1828/1786 +f 1790/1835/1787 1792/1859/1789 1791/1831/1788 +f 1791/1831/1788 1792/1859/1789 1794/1836/1791 +f 1794/1836/1791 1817/1849/1814 1795/1838/1792 +f 1817/1849/1814 1801/1850/1798 1800/1843/1797 +f 1801/1850/1798 1803/1851/1800 1802/1846/1799 +f 1803/1851/1800 1805/1852/1802 1804/1807/1801 +f 1805/1852/1802 1806/1816/1803 1765/1810/1762 +f 1829/1862/1826 1830/1866/1827 1828/1863/1825 +f 1827/1861/1824 1828/1863/1825 1856/1864/1849 +f 1831/1865/1828 1832/1883/1829 1830/1866/1827 +f 1834/1867/1831 1832/1882/1829 1831/1868/1828 +f 1836/1870/1833 1834/1867/1831 1833/1869/1830 +f 1838/1873/1835 1836/1870/1833 1835/1871/1832 +f 1841/1875/1838 1838/1873/1835 1837/1872/1834 +f 1842/1876/1839 1843/1877/1840 1841/1875/1838 +f 1808/1854/1805 1844/1878/1841 1843/1877/1840 +f 1843/1877/1840 1844/1878/1841 1846/1878/1843 +f 1841/1875/1838 1843/1877/1840 1845/1877/1842 +f 1853/1881/1843 1852/1895/1848 1851/1896/1847 +f 1851/1896/1847 1850/1897/1846 1849/1898/1843 +f 1849/1898/1843 1848/1899/1845 1847/1900/1844 +f 1847/1900/1844 1845/1901/1842 1846/1879/1843 +f 1846/1879/1843 1867/1902/1846 1863/1903/1847 +f 1863/1903/1847 1862/1904/1848 1861/1880/1843 +f 1861/1880/1843 1860/1905/1845 1855/1906/1844 +f 1855/1906/1844 1854/1907/1845 1853/1881/1843 +f 1853/1881/1843 1851/1896/1847 1849/1898/1843 +f 1849/1898/1843 1847/1900/1844 1846/1879/1843 +f 1846/1879/1843 1863/1903/1847 1861/1880/1843 +f 1861/1880/1843 1855/1906/1844 1853/1881/1843 +f 1853/1881/1843 1849/1898/1843 1846/1879/1843 +f 1838/1873/1835 1841/1875/1838 1847/1875/1844 +f 1836/1870/1833 1838/1873/1835 1848/1873/1845 +f 1834/1867/1831 1836/1870/1833 1849/1870/1843 +f 1832/1882/1829 1834/1867/1831 1850/1867/1846 +f 1830/1866/1827 1832/1883/1829 1851/1883/1847 +f 1828/1863/1825 1830/1866/1827 1852/1866/1848 +f 1856/1864/1849 1828/1863/1825 1853/1863/1843 +f 1857/1884/1850 1856/1864/1849 1854/1864/1845 +f 1824/1860/1821 1856/1864/1849 1857/1884/1850 +f 1858/1886/1851 1857/1884/1850 1855/1884/1844 +f 1857/1884/1850 1858/1886/1851 1820/1858/1817 +f 1859/1887/1852 1858/1886/1851 1860/1886/1845 +f 1858/1886/1851 1859/1887/1852 1818/1857/1815 +f 1864/1888/1853 1859/1887/1852 1861/1887/1843 +f 1865/1889/1854 1864/1888/1853 1862/1888/1848 +f 1859/1887/1852 1864/1888/1853 1815/1856/1812 +f 1864/1888/1853 1865/1889/1854 1813/1855/1810 +f 1866/1890/1855 1865/1889/1854 1863/1889/1847 +f 1813/1855/1810 1865/1889/1854 1866/1890/1855 +f 1844/1878/1841 1866/1890/1855 1867/1890/1846 +f 1811/1853/1808 1866/1890/1855 1844/1878/1841 +usemtl Floral_Engraved_Gold +f 1733/1769/1730 1729/1770/1726 1726/1771/1723 +f 1729/1772/1726 1734/1773/1731 1730/1774/1727 +f 1731/1775/1728 1770/1769/1767 1732/1775/1729 +f 1734/1773/1731 1732/1775/1729 1735/1773/1732 +f 1736/1776/1733 1735/1773/1732 1738/1776/1735 +f 1736/1776/1733 1730/1777/1727 1734/1773/1731 +f 1737/1778/1734 1739/1779/1736 1736/1780/1733 +f 1736/1780/1733 1782/1778/1779 1737/1778/1734 +f 1741/1785/1738 1785/1786/1782 1742/1787/1739 +f 1766/1807/1763 1762/1808/1759 1760/1809/1757 +f 1764/1810/1761 1763/1811/1760 1762/1812/1759 +f 1766/1807/1763 1765/1810/1762 1764/1810/1761 +f 1764/1810/1761 1768/1813/1765 1767/1813/1764 +f 1733/1769/1730 1768/1813/1765 1770/1769/1767 +f 1767/1813/1764 1726/1814/1723 1763/1815/1760 +f 1774/1819/1771 1771/1818/1768 1772/1818/1769 +f 1772/1818/1769 1769/1817/1766 1840/1817/1837 +f 1776/1820/1773 1773/1819/1770 1774/1819/1771 +f 1778/1821/1775 1775/1820/1772 1776/1820/1773 +f 1778/1822/1775 1779/1823/1776 1777/1822/1774 +f 1780/1823/1777 1781/1824/1778 1779/1823/1776 +f 1737/1778/1734 1783/1786/1780 1785/1786/1782 +f 1785/1786/1782 1784/1825/1781 1786/1825/1783 +f 1742/1826/1739 1786/1825/1783 1746/1827/1743 +f 1786/1825/1783 1789/1828/1786 1787/1828/1784 +f 1786/1825/1783 1748/1829/1745 1746/1830/1743 +f 1788/1831/1785 1789/1828/1786 1791/1831/1788 +f 1787/1828/1784 1750/1832/1747 1748/1833/1745 +f 1796/1837/1793 1791/1831/1788 1793/1837/1790 +f 1797/1838/1794 1793/1837/1790 1795/1838/1792 +f 1788/1831/1785 1752/1839/1749 1750/1840/1747 +f 1796/1837/1793 1754/1841/1751 1752/1842/1749 +f 1798/1843/1795 1795/1838/1792 1800/1843/1797 +f 1797/1838/1794 1756/1844/1753 1754/1845/1751 +f 1798/1843/1795 1802/1846/1799 1799/1846/1796 +f 1798/1843/1795 1758/1847/1755 1756/1848/1753 +f 1799/1846/1796 1804/1807/1801 1766/1807/1763 +f 1807/1852/1804 1806/1816/1803 1805/1852/1802 +f 1810/1851/1807 1805/1852/1802 1803/1851/1800 +f 1811/1853/1808 1807/1852/1804 1810/1851/1807 +f 1808/1854/1805 1809/1816/1806 1807/1852/1804 +f 1813/1855/1810 1810/1851/1807 1812/1850/1809 +f 1812/1850/1809 1803/1851/1800 1801/1850/1798 +f 1815/1856/1812 1812/1850/1809 1814/1849/1811 +f 1812/1850/1809 1817/1849/1814 1814/1849/1811 +f 1818/1857/1815 1814/1849/1811 1816/1836/1813 +f 1814/1849/1811 1794/1836/1791 1816/1836/1813 +f 1820/1858/1817 1816/1836/1813 1819/1859/1816 +f 1816/1836/1813 1792/1859/1789 1819/1859/1816 +f 1821/1835/1818 1820/1858/1817 1819/1859/1816 +f 1819/1859/1816 1790/1835/1787 1821/1835/1818 +f 1824/1860/1821 1821/1835/1818 1823/1834/1820 +f 1823/1834/1820 1790/1835/1787 1826/1834/1823 +f 1825/1824/1822 1824/1860/1821 1823/1834/1820 +f 1825/1824/1822 1826/1834/1823 1781/1824/1778 +f 1780/1823/1777 1827/1861/1824 1825/1824/1822 +f 1778/1822/1775 1829/1862/1826 1780/1823/1777 +f 1776/1820/1773 1831/1868/1828 1778/1821/1775 +f 1774/1819/1771 1833/1869/1830 1776/1820/1773 +f 1837/1872/1834 1774/1819/1771 1772/1818/1769 +f 1839/1874/1836 1772/1818/1769 1840/1817/1837 +f 1842/1876/1839 1840/1817/1837 1809/1816/1806 +f 1809/1816/1806 1769/1817/1766 1806/1816/1803 +f 1799/1846/1796 1760/1891/1757 1758/1892/1755 +f 1733/1769/1730 1731/1775/1728 1729/1770/1726 +f 1729/1772/1726 1731/1775/1728 1734/1773/1731 +f 1731/1775/1728 1733/1769/1730 1770/1769/1767 +f 1734/1773/1731 1731/1775/1728 1732/1775/1729 +f 1736/1776/1733 1734/1773/1731 1735/1773/1732 +f 1736/1776/1733 1739/1893/1736 1730/1777/1727 +f 1737/1778/1734 1741/1894/1738 1739/1779/1736 +f 1736/1780/1733 1738/1780/1735 1782/1778/1779 +f 1741/1785/1738 1737/1778/1734 1785/1786/1782 +f 1766/1807/1763 1764/1810/1761 1762/1808/1759 +f 1764/1810/1761 1767/1813/1764 1763/1811/1760 +f 1766/1807/1763 1804/1807/1801 1765/1810/1762 +f 1764/1810/1761 1765/1810/1762 1768/1813/1765 +f 1733/1769/1730 1767/1813/1764 1768/1813/1765 +f 1767/1813/1764 1733/1769/1730 1726/1814/1723 +f 1774/1819/1771 1773/1819/1770 1771/1818/1768 +f 1772/1818/1769 1771/1818/1768 1769/1817/1766 +f 1776/1820/1773 1775/1820/1772 1773/1819/1770 +f 1778/1821/1775 1777/1821/1774 1775/1820/1772 +f 1778/1822/1775 1780/1823/1777 1779/1823/1776 +f 1780/1823/1777 1825/1824/1822 1781/1824/1778 +f 1737/1778/1734 1782/1778/1779 1783/1786/1780 +f 1785/1786/1782 1783/1786/1780 1784/1825/1781 +f 1742/1826/1739 1785/1786/1782 1786/1825/1783 +f 1786/1825/1783 1784/1825/1781 1789/1828/1786 +f 1786/1825/1783 1787/1828/1784 1748/1829/1745 +f 1788/1831/1785 1787/1828/1784 1789/1828/1786 +f 1787/1828/1784 1788/1831/1785 1750/1832/1747 +f 1796/1837/1793 1788/1831/1785 1791/1831/1788 +f 1797/1838/1794 1796/1837/1793 1793/1837/1790 +f 1788/1831/1785 1796/1837/1793 1752/1839/1749 +f 1796/1837/1793 1797/1838/1794 1754/1841/1751 +f 1798/1843/1795 1797/1838/1794 1795/1838/1792 +f 1797/1838/1794 1798/1843/1795 1756/1844/1753 +f 1798/1843/1795 1800/1843/1797 1802/1846/1799 +f 1798/1843/1795 1799/1846/1796 1758/1847/1755 +f 1799/1846/1796 1802/1846/1799 1804/1807/1801 +f 1807/1852/1804 1809/1816/1806 1806/1816/1803 +f 1810/1851/1807 1807/1852/1804 1805/1852/1802 +f 1811/1853/1808 1808/1854/1805 1807/1852/1804 +f 1808/1854/1805 1842/1876/1839 1809/1816/1806 +f 1813/1855/1810 1811/1853/1808 1810/1851/1807 +f 1812/1850/1809 1810/1851/1807 1803/1851/1800 +f 1815/1856/1812 1813/1855/1810 1812/1850/1809 +f 1812/1850/1809 1801/1850/1798 1817/1849/1814 +f 1818/1857/1815 1815/1856/1812 1814/1849/1811 +f 1814/1849/1811 1817/1849/1814 1794/1836/1791 +f 1820/1858/1817 1818/1857/1815 1816/1836/1813 +f 1816/1836/1813 1794/1836/1791 1792/1859/1789 +f 1821/1835/1818 1822/1885/1819 1820/1858/1817 +f 1819/1859/1816 1792/1859/1789 1790/1835/1787 +f 1824/1860/1821 1822/1885/1819 1821/1835/1818 +f 1823/1834/1820 1821/1835/1818 1790/1835/1787 +f 1825/1824/1822 1827/1861/1824 1824/1860/1821 +f 1825/1824/1822 1823/1834/1820 1826/1834/1823 +f 1780/1823/1777 1829/1862/1826 1827/1861/1824 +f 1778/1822/1775 1831/1865/1828 1829/1862/1826 +f 1776/1820/1773 1833/1869/1830 1831/1868/1828 +f 1774/1819/1771 1835/1871/1832 1833/1869/1830 +f 1837/1872/1834 1835/1871/1832 1774/1819/1771 +f 1839/1874/1836 1837/1872/1834 1772/1818/1769 +f 1842/1876/1839 1839/1874/1836 1840/1817/1837 +f 1809/1816/1806 1840/1817/1837 1769/1817/1766 +f 1799/1846/1796 1766/1807/1763 1760/1891/1757 +o Cube.023 +v -0.014631 1.795596 -0.250658 +v -0.027035 1.787308 -0.250658 +v 0.000000 1.798506 -0.250658 +v -0.014667 1.795682 -0.240783 +v -0.011146 1.787182 -0.260603 +v -0.020595 1.780868 -0.260603 +v 0.000000 1.789399 -0.260603 +v 0.011146 1.787182 -0.260603 +v 0.014631 1.795596 -0.250658 +v 0.020595 1.780868 -0.260603 +v 0.027035 1.787308 -0.250658 +v 0.026909 1.771419 -0.260603 +v 0.035323 1.774904 -0.250658 +v 0.029126 1.760273 -0.260603 +v 0.038233 1.760273 -0.250658 +v 0.026909 1.749127 -0.260603 +v 0.035323 1.745642 -0.250658 +v 0.020595 1.739678 -0.260603 +v 0.027035 1.733238 -0.250658 +v 0.011146 1.733364 -0.260603 +v 0.014631 1.724950 -0.250658 +v 0.000000 1.731147 -0.260603 +v 0.000000 1.722040 -0.250658 +v -0.011146 1.733364 -0.260603 +v -0.014631 1.724950 -0.250658 +v -0.020595 1.739678 -0.260603 +v -0.027035 1.733238 -0.250658 +v -0.026909 1.749127 -0.260603 +v -0.035323 1.745642 -0.250658 +v -0.029126 1.760273 -0.260603 +v -0.038233 1.760273 -0.250658 +v -0.026909 1.771419 -0.260603 +v -0.035323 1.774904 -0.250658 +v -0.035409 1.774940 -0.240783 +v -0.038076 1.776045 -0.234670 +v -0.038327 1.760273 -0.240783 +v -0.027101 1.787374 -0.240783 +v -0.029142 1.789415 -0.234670 +v -0.015772 1.798349 -0.234670 +v -0.029142 1.789415 -0.039512 +v -0.028016 1.788289 -0.039512 +v -0.038076 1.776045 -0.039512 +v -0.015772 1.798349 -0.039512 +v -0.015162 1.796878 -0.039512 +v 0.000000 1.801486 -0.039512 +v 0.015772 1.798349 -0.039512 +v 0.000000 1.799894 -0.039512 +v 0.000000 1.801486 -0.234670 +v 0.000000 1.798600 -0.240783 +v 0.015772 1.798349 -0.234670 +v 0.029142 1.789415 -0.234670 +v 0.014667 1.795682 -0.240783 +v 0.027101 1.787374 -0.240783 +v 0.035409 1.774940 -0.240783 +v 0.038076 1.776045 -0.234670 +v 0.038327 1.760273 -0.240783 +v 0.041213 1.760273 -0.234670 +v 0.035409 1.745606 -0.240783 +v 0.038076 1.744501 -0.234670 +v 0.027101 1.733172 -0.240783 +v 0.029142 1.731131 -0.234670 +v 0.014667 1.724864 -0.240783 +v 0.015772 1.722197 -0.234670 +v 0.000000 1.721947 -0.240783 +v 0.000000 1.719060 -0.234670 +v -0.014667 1.724864 -0.240783 +v -0.015772 1.722197 -0.234670 +v -0.027101 1.733172 -0.240783 +v -0.029142 1.731131 -0.234670 +v -0.035409 1.745606 -0.240783 +v -0.038076 1.744501 -0.234670 +v -0.041213 1.760273 -0.234670 +v -0.038076 1.744501 -0.039512 +v -0.036605 1.745111 -0.039512 +v -0.029142 1.731131 -0.039512 +v -0.041213 1.760273 -0.039512 +v -0.039621 1.760273 -0.039512 +v -0.039621 1.760273 -0.032735 +v -0.036605 1.775435 -0.039512 +v -0.036605 1.775435 -0.032735 +v -0.038076 1.776045 -0.032735 +v -0.028016 1.788289 -0.032735 +v -0.029142 1.789415 -0.032735 +v -0.015162 1.796878 -0.032735 +v -0.015772 1.798349 -0.032735 +v 0.000000 1.799894 -0.032735 +v 0.000000 1.801486 -0.032735 +v 0.015162 1.796878 -0.032735 +v 0.015772 1.798349 -0.032735 +v 0.028016 1.788289 -0.032735 +v 0.015162 1.796878 -0.039512 +v 0.028016 1.788289 -0.039512 +v 0.036605 1.775435 -0.039512 +v 0.029142 1.789415 -0.039512 +v 0.038076 1.776045 -0.039512 +v 0.041213 1.760273 -0.039512 +v 0.038076 1.744501 -0.039512 +v 0.039621 1.760273 -0.039512 +v 0.039621 1.760273 -0.032735 +v 0.036605 1.745111 -0.039512 +v 0.036605 1.745111 -0.032735 +v 0.028016 1.732257 -0.039512 +v 0.028016 1.732257 -0.032735 +v 0.015162 1.723668 -0.039512 +v 0.029142 1.731131 -0.039512 +v 0.015772 1.722197 -0.039512 +v 0.000000 1.719060 -0.039512 +v -0.015772 1.722197 -0.039512 +v 0.000000 1.720653 -0.039512 +v 0.000000 1.720653 -0.032735 +v -0.015162 1.723668 -0.039512 +v -0.015162 1.723668 -0.032735 +v -0.028016 1.732257 -0.039512 +v -0.028016 1.732257 -0.032735 +v -0.036605 1.745111 -0.032735 +v -0.029142 1.731131 -0.032735 +v -0.029142 1.731131 0.015961 +v -0.038076 1.744501 -0.032735 +v -0.015772 1.722197 -0.032735 +v -0.015772 1.722197 0.015961 +v 0.000000 1.719060 -0.032735 +v 0.000000 1.719060 0.015961 +v 0.015772 1.722197 -0.032735 +v 0.015772 1.722197 0.015961 +v 0.029142 1.731131 -0.032735 +v 0.015162 1.723668 -0.032735 +v 0.029142 1.731131 0.015961 +v 0.038076 1.744501 -0.032735 +v 0.038076 1.744501 0.015961 +v 0.041213 1.760273 -0.032735 +v 0.041213 1.760273 0.015961 +v 0.038076 1.776045 -0.032735 +v 0.038076 1.776045 0.015961 +v 0.029142 1.789415 -0.032735 +v 0.036605 1.775435 -0.032735 +v 0.029142 1.789415 0.015961 +v 0.027609 1.787882 0.022442 +v 0.015772 1.798349 0.015961 +v 0.014942 1.796346 0.022442 +v 0.000000 1.801486 0.015961 +v 0.000000 1.799318 0.022442 +v -0.015772 1.798349 0.015961 +v -0.014942 1.796346 0.022442 +v -0.029142 1.789415 0.015961 +v -0.027609 1.787882 0.022442 +v -0.038076 1.776045 0.015961 +v -0.036073 1.775215 0.022442 +v -0.041213 1.760273 0.015961 +v -0.041213 1.760273 -0.032735 +v -0.039045 1.760273 0.022442 +v -0.038076 1.744501 0.015961 +v -0.036073 1.745331 0.022442 +v -0.027609 1.732664 0.022442 +v -0.036073 1.745331 0.022442 +v -0.027609 1.732664 0.022442 +v -0.039045 1.760273 0.022442 +v -0.036073 1.775215 0.022442 +v -0.027609 1.787882 0.022442 +v -0.014942 1.796346 0.022442 +v 0.000000 1.799318 0.022442 +v 0.014942 1.796346 0.022442 +v 0.027609 1.787882 0.022442 +v 0.036073 1.775215 0.022442 +v 0.039045 1.760273 0.022442 +v 0.036073 1.775215 0.022442 +v 0.039045 1.760273 0.022442 +v 0.036073 1.745331 0.022442 +v 0.027609 1.732664 0.022442 +v 0.036073 1.745331 0.022442 +v 0.027609 1.732664 0.022442 +v 0.014942 1.724200 0.022442 +v 0.000000 1.721228 0.022442 +v 0.014942 1.724200 0.022442 +v 0.000000 1.721228 0.022442 +v -0.014942 1.724200 0.022442 +v -0.014942 1.724200 0.022442 +vn -0.3953 0.8464 -0.3568 +vn -0.7091 0.6233 -0.3296 +vn -0.0000 0.9322 -0.3621 +vn -0.3620 0.9053 -0.2221 +vn -0.1339 0.4019 -0.9059 +vn -0.2889 0.3467 -0.8924 +vn -0.0000 0.4157 -0.9095 +vn 0.1339 0.4018 -0.9059 +vn 0.3953 0.8464 -0.3568 +vn 0.2889 0.3467 -0.8924 +vn 0.7091 0.6233 -0.3296 +vn 0.4621 0.2268 -0.8574 +vn 0.9171 0.3102 -0.2505 +vn 0.5874 -0.0000 -0.8093 +vn 0.9835 -0.0000 -0.1810 +vn 0.4621 -0.2268 -0.8574 +vn 0.9171 -0.3102 -0.2505 +vn 0.2889 -0.3467 -0.8924 +vn 0.7091 -0.6233 -0.3296 +vn 0.1339 -0.4019 -0.9059 +vn 0.3953 -0.8464 -0.3568 +vn -0.0000 -0.4157 -0.9095 +vn -0.0000 -0.9322 -0.3621 +vn -0.1339 -0.4019 -0.9059 +vn -0.3953 -0.8464 -0.3568 +vn -0.2889 -0.3467 -0.8924 +vn -0.7091 -0.6233 -0.3296 +vn -0.4621 -0.2268 -0.8574 +vn -0.9171 -0.3102 -0.2505 +vn -0.5874 -0.0000 -0.8093 +vn -0.9835 -0.0000 -0.1810 +vn -0.4621 0.2268 -0.8574 +vn -0.9171 0.3102 -0.2505 +vn -0.9104 0.3614 -0.2012 +vn -0.9338 0.3102 -0.1781 +vn -0.9775 -0.0000 -0.2109 +vn -0.6851 0.6965 -0.2132 +vn -0.7350 0.6447 -0.2101 +vn -0.4089 0.8865 -0.2165 +vn -0.6058 0.5677 0.5574 +vn -0.5764 0.5402 0.6131 +vn -0.8822 0.3126 0.3521 +vn -0.2963 0.6869 0.6636 +vn -0.2843 0.6591 0.6962 +vn -0.0000 0.7202 0.6938 +vn 0.2963 0.6869 0.6635 +vn -0.0000 0.6930 0.7210 +vn -0.0000 0.9762 -0.2170 +vn -0.0000 0.9743 -0.2252 +vn 0.4088 0.8866 -0.2165 +vn 0.7350 0.6447 -0.2101 +vn 0.3620 0.9053 -0.2221 +vn 0.6851 0.6965 -0.2132 +vn 0.9104 0.3614 -0.2012 +vn 0.9338 0.3102 -0.1781 +vn 0.9775 -0.0000 -0.2109 +vn 0.9902 -0.0000 -0.1394 +vn 0.9104 -0.3614 -0.2012 +vn 0.9338 -0.3102 -0.1781 +vn 0.6851 -0.6965 -0.2132 +vn 0.7350 -0.6447 -0.2101 +vn 0.3620 -0.9053 -0.2221 +vn 0.4088 -0.8866 -0.2165 +vn -0.0000 -0.9743 -0.2252 +vn -0.0000 -0.9762 -0.2170 +vn -0.3620 -0.9053 -0.2221 +vn -0.4089 -0.8866 -0.2165 +vn -0.6851 -0.6965 -0.2132 +vn -0.7350 -0.6447 -0.2101 +vn -0.9104 -0.3614 -0.2012 +vn -0.9338 -0.3102 -0.1781 +vn -0.9902 -0.0000 -0.1394 +vn -0.8822 -0.3126 0.3521 +vn -0.8290 -0.2938 0.4759 +vn -0.6058 -0.5677 0.5574 +vn -0.9746 -0.0000 0.2240 +vn -0.8952 -0.0000 0.4457 +vn -0.8952 -0.0000 -0.4457 +vn -0.8290 0.2938 0.4759 +vn -0.8290 0.2938 -0.4759 +vn -0.8822 0.3126 -0.3521 +vn -0.5765 0.5402 -0.6131 +vn -0.6058 0.5677 -0.5574 +vn -0.2843 0.6591 -0.6962 +vn -0.2963 0.6870 -0.6635 +vn -0.0000 0.6930 -0.7210 +vn -0.0000 0.7202 -0.6937 +vn 0.2843 0.6591 -0.6962 +vn 0.2963 0.6870 -0.6635 +vn 0.5765 0.5402 -0.6131 +vn 0.2843 0.6591 0.6962 +vn 0.5765 0.5402 0.6131 +vn 0.8290 0.2938 0.4759 +vn 0.6058 0.5677 0.5574 +vn 0.8822 0.3126 0.3521 +vn 0.9746 -0.0000 0.2240 +vn 0.8822 -0.3126 0.3521 +vn 0.8952 -0.0000 0.4457 +vn 0.8952 -0.0000 -0.4457 +vn 0.8290 -0.2938 0.4759 +vn 0.8290 -0.2938 -0.4759 +vn 0.5765 -0.5402 0.6131 +vn 0.5765 -0.5402 -0.6131 +vn 0.2843 -0.6591 0.6962 +vn 0.6058 -0.5677 0.5574 +vn 0.2963 -0.6869 0.6635 +vn -0.0000 -0.7202 0.6938 +vn -0.2963 -0.6869 0.6635 +vn -0.0000 -0.6930 0.7210 +vn -0.0000 -0.6930 -0.7210 +vn -0.2843 -0.6591 0.6962 +vn -0.2843 -0.6591 -0.6962 +vn -0.5765 -0.5402 0.6131 +vn -0.5765 -0.5402 -0.6131 +vn -0.8290 -0.2938 -0.4759 +vn -0.6058 -0.5677 -0.5574 +vn -0.7397 -0.6542 0.1577 +vn -0.8822 -0.3126 -0.3521 +vn -0.2963 -0.6870 -0.6635 +vn -0.4090 -0.8984 0.1598 +vn -0.0000 -0.7202 -0.6937 +vn -0.0000 -0.9872 0.1598 +vn 0.2963 -0.6870 -0.6635 +vn 0.4090 -0.8984 0.1598 +vn 0.6058 -0.5677 -0.5574 +vn 0.2843 -0.6591 -0.6962 +vn 0.7397 -0.6542 0.1577 +vn 0.8822 -0.3126 -0.3521 +vn 0.9394 -0.3123 0.1414 +vn 0.9746 -0.0000 -0.2240 +vn 0.9932 -0.0000 0.1167 +vn 0.8822 0.3126 -0.3521 +vn 0.9394 0.3123 0.1414 +vn 0.6058 0.5677 -0.5574 +vn 0.8290 0.2938 -0.4759 +vn 0.7397 0.6542 0.1577 +vn 0.9721 0.2134 0.0970 +vn 0.4090 0.8984 0.1598 +vn 0.9638 0.2509 0.0897 +vn -0.0000 0.9872 0.1598 +vn 0.9557 0.2791 0.0934 +vn -0.4090 0.8984 0.1598 +vn 0.9455 0.3067 0.1097 +vn -0.7397 0.6542 0.1577 +vn 0.9270 0.3416 0.1552 +vn -0.9394 0.3123 0.1414 +vn 0.8642 0.3869 0.3216 +vn -0.9932 -0.0000 0.1167 +vn -0.9746 -0.0000 -0.2241 +vn 0.6455 -0.0000 0.7637 +vn -0.9394 -0.3123 0.1414 +vn 0.8643 -0.3868 0.3215 +vn 0.9270 -0.3416 0.1552 +vn 0.9702 -0.0000 0.2424 +vn 0.9623 -0.0000 0.2720 +vn 0.9820 -0.0000 0.1890 +vn 0.9702 -0.0000 0.2425 +vn 0.9602 -0.0000 0.2795 +vn 0.9597 -0.0000 0.2811 +vn 0.9821 0.1448 0.1203 +vn 0.9894 -0.0000 0.1450 +vn 0.9821 -0.1448 0.1203 +vn 0.9721 -0.2134 0.0970 +vn 0.9602 -0.0000 0.2794 +vn 0.9639 -0.2509 0.0897 +vn 0.9557 -0.2790 0.0934 +vn 0.9455 -0.3067 0.1097 +vt 0.661368 0.463977 +vt 0.605181 0.394819 +vt 0.586229 0.413771 +vt 0.671624 0.439216 +vt 0.630067 0.369933 +vt 0.750000 0.454806 +vt 0.685093 0.406700 +vt 0.750000 0.481607 +vt 0.814908 0.093300 +vt 0.593300 0.185093 +vt 0.814907 0.406700 +vt 0.750000 0.419611 +vt 0.828376 0.439216 +vt 0.869933 0.369933 +vt 0.894819 0.394819 +vt 0.906701 0.314908 +vt 0.939216 0.328376 +vt 0.919611 0.250000 +vt 0.939216 0.171624 +vt 0.954806 0.250000 +vt 0.894819 0.105181 +vt 0.906700 0.185093 +vt 0.828376 0.060784 +vt 0.869933 0.130067 +vt 0.750000 0.045194 +vt 0.685093 0.093300 +vt 0.750000 0.080389 +vt 0.671624 0.060784 +vt 0.630067 0.130067 +vt 0.605181 0.105181 +vt 0.560784 0.171624 +vt 0.580389 0.250000 +vt 0.560784 0.328376 +vt 0.545194 0.250000 +vt 0.593300 0.314907 +vt 0.536023 0.338632 +vt 0.518393 0.250000 +vt 0.580294 0.419706 +vt 0.528269 0.341844 +vt 0.510000 0.250000 +vt 0.658156 0.471731 +vt 0.187500 0.532007 +vt 0.125000 0.895448 +vt 0.125000 0.532007 +vt 0.125000 0.532007 +vt 0.062500 0.895448 +vt 0.062500 0.532007 +vt 0.187500 0.895448 +vt 0.000000 0.895448 +vt 0.062500 0.532007 +vt 0.937500 0.895448 +vt 1.000000 0.532007 +vt 1.000000 0.895448 +vt 0.750000 0.490000 +vt 0.838632 0.463977 +vt 0.841844 0.471731 +vt 0.913771 0.413771 +vt 0.937500 0.532007 +vt 0.875000 0.895448 +vt 0.875000 0.532007 +vt 0.919706 0.419706 +vt 0.963977 0.338632 +vt 0.971731 0.341844 +vt 0.981607 0.250000 +vt 0.963977 0.161368 +vt 0.971731 0.158156 +vt 0.990000 0.250000 +vt 0.913771 0.086229 +vt 0.919706 0.080294 +vt 0.838632 0.036023 +vt 0.841844 0.028269 +vt 0.750000 0.018393 +vt 0.750000 0.010000 +vt 0.661368 0.036023 +vt 0.658156 0.028269 +vt 0.586229 0.086229 +vt 0.580294 0.080294 +vt 0.536023 0.161368 +vt 0.528269 0.158156 +vt 0.375000 0.895448 +vt 0.312500 0.532007 +vt 0.375000 0.532007 +vt 0.312500 0.895448 +vt 0.250000 0.532007 +vt 0.312500 0.532007 +vt 0.250000 0.895448 +vt 0.250000 0.532007 +vt 0.187500 0.532007 +vt 0.250000 0.915363 +vt 0.187500 0.915363 +vt 0.125000 0.915363 +vt 0.062500 0.915363 +vt 0.000000 0.915363 +vt 1.000000 0.915363 +vt 0.937500 0.915363 +vt 0.875000 0.915363 +vt 0.812500 0.915363 +vt 0.812500 0.895448 +vt 0.875000 0.532007 +vt 0.812500 0.532007 +vt 0.750000 0.895448 +vt 0.750000 0.532007 +vt 0.812500 0.532007 +vt 0.687500 0.895448 +vt 0.687500 0.532007 +vt 0.750000 0.532007 +vt 0.687500 0.915363 +vt 0.625000 0.915363 +vt 0.625000 0.895448 +vt 0.562500 0.895448 +vt 0.625000 0.532007 +vt 0.687500 0.532007 +vt 0.562500 0.532007 +vt 0.625000 0.532007 +vt 0.500000 0.895448 +vt 0.500000 0.532007 +vt 0.562500 0.532007 +vt 0.437500 0.895448 +vt 0.437500 0.532007 +vt 0.500000 0.532007 +vt 0.562500 0.915363 +vt 0.500000 0.915363 +vt 0.437500 0.915363 +vt 0.375000 0.915363 +vt 0.312500 0.915363 +vt 0.437500 0.980957 +vt 0.375000 0.980957 +vt 0.500000 0.980957 +vt 0.562500 0.980957 +vt 0.625000 0.980957 +vt 0.687500 0.980957 +vt 0.750000 0.980957 +vt 0.750000 0.915363 +vt 0.812500 0.980957 +vt 0.875000 0.980957 +vt 0.937500 0.980957 +vt 0.875000 1.000000 +vt 0.812500 1.000000 +vt 1.000000 0.980957 +vt 0.937500 1.000000 +vt 0.062500 1.000000 +vt 0.000000 0.980957 +vt 0.062500 0.980957 +vt 0.125000 1.000000 +vt 0.125000 0.980957 +vt 0.187500 1.000000 +vt 0.187500 0.980957 +vt 0.250000 1.000000 +vt 0.250000 0.980957 +vt 0.312500 0.980957 +vt 0.312500 1.000000 +vt 0.375000 1.000000 +vt 0.080294 0.080294 +vt 0.419706 0.080294 +vt 0.419706 0.419706 +vt 0.000000 1.000000 +vt 1.000000 1.000000 +vt 0.750000 1.000000 +vt 0.687500 1.000000 +vt 0.625000 1.000000 +vt 0.562500 1.000000 +vt 0.500000 1.000000 +vt 0.437500 1.000000 +vt 0.375000 0.532007 +vt 0.437500 0.532007 +vt 0.000000 0.532007 +vt 0.937500 0.532007 +vt 0.341844 0.471731 +vt 0.250000 0.490000 +vt 0.158156 0.471731 +vt 0.080294 0.419706 +vt 0.028269 0.341844 +vt 0.010000 0.250000 +vt 0.028269 0.158156 +vt 0.158156 0.028269 +vt 0.250000 0.010000 +vt 0.341844 0.028269 +vt 0.471731 0.158156 +vt 0.490000 0.250000 +vt 0.471731 0.341844 +s 1 +usemtl Brass.001 +f 1871/1908/1859 1869/1909/1857 1904/1910/1892 +f 1868/1911/1856 1873/1912/1861 1869/1909/1857 +f 1870/1913/1858 1872/1914/1860 1868/1911/1856 +f 1916/1915/1904 1868/1911/1856 1871/1908/1859 +f 1887/1916/1875 1895/1917/1883 1872/1914/1860 +f 1870/1913/1858 1875/1918/1863 1874/1919/1862 +f 1876/1920/1864 1877/1921/1865 1875/1918/1863 +f 1878/1922/1866 1879/1923/1867 1877/1921/1865 +f 1880/1924/1868 1881/1925/1869 1879/1923/1867 +f 1884/1926/1872 1881/1925/1869 1882/1927/1870 +f 1886/1928/1874 1883/1929/1871 1884/1926/1872 +f 1888/1930/1876 1885/1931/1873 1886/1928/1874 +f 1890/1932/1878 1887/1916/1875 1888/1930/1876 +f 1890/1932/1878 1891/1933/1879 1889/1934/1877 +f 1892/1935/1880 1893/1936/1881 1891/1933/1879 +f 1894/1937/1882 1895/1917/1883 1893/1936/1881 +f 1896/1938/1884 1897/1939/1885 1895/1917/1883 +f 1900/1940/1888 1897/1939/1885 1898/1941/1886 +f 1869/1909/1857 1899/1942/1887 1900/1940/1888 +f 1901/1943/1889 1898/1941/1886 1903/1944/1891 +f 1904/1910/1892 1900/1940/1888 1901/1943/1889 +f 1905/1945/1893 1901/1943/1889 1902/1946/1890 +f 1902/1946/1890 1903/1944/1891 1939/1947/1927 +f 1906/1948/1894 1904/1910/1892 1905/1945/1893 +f 1915/1961/1903 1871/1908/1859 1906/1948/1894 +f 1915/1961/1903 1919/1962/1907 1916/1915/1904 +f 1917/1963/1905 1920/1964/1908 1919/1962/1907 +f 1916/1915/1904 1876/1920/1864 1870/1913/1858 +f 1919/1962/1907 1878/1922/1866 1876/1920/1864 +f 1920/1964/1908 1880/1924/1868 1878/1922/1866 +f 1918/1968/1906 1921/1969/1909 1920/1964/1908 +f 1921/1969/1909 1882/1927/1870 1880/1924/1868 +f 1922/1970/1910 1923/1971/1911 1921/1969/1909 +f 1925/1972/1913 1882/1927/1870 1923/1971/1911 +f 1926/1973/1914 1923/1971/1911 1924/1974/1912 +f 1927/1975/1915 1884/1926/1872 1925/1972/1913 +f 1928/1976/1916 1925/1972/1913 1926/1973/1914 +f 1929/1977/1917 1886/1928/1874 1927/1975/1915 +f 1930/1978/1918 1927/1975/1915 1928/1976/1916 +f 1931/1979/1919 1888/1930/1876 1929/1977/1917 +f 1932/1980/1920 1929/1977/1917 1930/1978/1918 +f 1931/1979/1919 1892/1935/1880 1890/1932/1878 +f 1932/1980/1920 1933/1981/1921 1931/1979/1919 +f 1933/1981/1921 1894/1937/1882 1892/1935/1880 +f 1934/1982/1922 1935/1983/1923 1933/1981/1921 +f 1935/1983/1923 1896/1938/1884 1894/1937/1882 +f 1936/1984/1924 1937/1985/1925 1935/1983/1923 +f 1937/1985/1925 1898/1941/1886 1896/1938/1884 +f 1938/1986/1926 1903/1944/1891 1937/1985/1925 +f 1941/1990/1929 1945/1996/1933 1944/1993/1932 +f 1944/1993/1932 1947/1997/1935 1946/1955/1934 +f 1947/1997/1935 1908/1950/1896 1946/1955/1934 +f 1949/1998/1937 1911/1953/1899 1908/1950/1896 +f 1951/1999/1939 1914/1956/1902 1911/1953/1899 +f 1953/2001/1941 1958/1958/1946 1914/1960/1902 +f 1955/2002/1943 1959/1966/1947 1958/1958/1946 +f 1959/1966/1947 2002/2004/1990 1960/2005/1948 +f 2002/2004/1990 1965/2008/1953 1960/2005/1948 +f 1965/2008/1953 1968/2014/1956 1967/2011/1955 +f 1967/2011/1955 1970/2015/1958 1969/2016/1957 +f 1970/2015/1958 1971/2017/1959 1969/2016/1957 +f 1993/2028/1981 1976/2022/1964 1971/2017/1959 +f 1977/2029/1965 1978/2025/1966 1976/2022/1964 +f 1979/2030/1967 1980/1987/1968 1978/2025/1966 +f 1981/2031/1969 1941/1990/1929 1980/1987/1968 +f 2005/2043/1993 2004/2044/1992 2003/2042/1991 +f 2003/2042/1991 2032/2045/2015 2000/2041/1988 +f 2007/2046/1995 2006/2047/1994 2005/2043/1993 +f 2010/2048/1998 2007/2049/1995 2009/2050/1997 +f 2012/2051/2000 2009/2050/1997 2011/2052/1999 +f 2014/2053/2002 2011/2052/1999 2013/2054/2001 +f 2017/2055/2005 2013/2054/2001 2015/2056/2003 +f 2018/2057/2006 2017/2055/2005 2015/2056/2003 +f 1984/2034/1972 2019/2058/2007 2018/2057/2006 +f 2019/2058/2007 2022/2059/2010 2021/2058/2009 +f 2017/2055/2005 2021/2058/2009 2023/2055/2011 +f 2022/2060/2010 2037/2061/2010 2029/2062/2010 +f 2014/2053/2002 2023/2055/2011 2024/2053/2012 +f 2012/2051/2000 2024/2053/2012 2025/2051/2010 +f 2010/2048/1998 2025/2051/2010 2026/2048/2013 +f 2008/2063/1996 2026/2048/2013 2027/2063/2014 +f 2006/2047/1994 2027/2064/2014 2028/2047/2013 +f 2004/2044/1992 2028/2047/2013 2029/2044/2010 +f 2032/2045/2015 2029/2044/2010 2030/2045/2012 +f 2033/2065/2016 2030/2045/2012 2031/2065/2011 +f 2000/2041/1988 2033/2065/2016 1998/2039/1986 +f 2034/2066/2017 2031/2065/2011 2036/2066/2009 +f 2033/2065/2016 1996/2038/1984 1998/2039/1986 +f 2035/2067/2018 2036/2066/2009 2037/2067/2010 +f 2034/2066/2017 1994/2037/1982 1996/2038/1984 +f 2040/2068/2020 2037/2067/2010 2038/2068/2019 +f 2041/2069/2021 2038/2068/2019 2039/2069/2014 +f 2035/2067/2018 1991/2036/1979 1994/2037/1982 +f 2040/2068/2020 1989/2035/1977 1991/2036/1979 +f 2042/2070/2022 2039/2069/2014 2043/2070/2013 +f 1989/2035/1977 2042/2070/2022 1987/2033/1975 +f 2020/2059/2008 2043/2070/2013 2022/2059/2010 +f 1987/2033/1975 2020/2059/2008 1984/2034/1972 +f 1871/1908/1859 1868/1911/1856 1869/1909/1857 +f 1868/1911/1856 1872/1914/1860 1873/1912/1861 +f 1870/1913/1858 1874/1919/1862 1872/1914/1860 +f 1916/1915/1904 1870/1913/1858 1868/1911/1856 +f 1872/1914/1860 1874/1919/1862 1875/1918/1863 +f 1875/1918/1863 1877/1921/1865 1879/1923/1867 +f 1879/1923/1867 1881/1925/1869 1883/1929/1871 +f 1883/1929/1871 1885/1931/1873 1887/1916/1875 +f 1887/1916/1875 1889/1934/1877 1891/1933/1879 +f 1891/1933/1879 1893/1936/1881 1895/1917/1883 +f 1895/1917/1883 1897/1939/1885 1899/1942/1887 +f 1899/1942/1887 1873/1912/1861 1872/1914/1860 +f 1872/1914/1860 1875/1918/1863 1879/1923/1867 +f 1879/1923/1867 1883/1929/1871 1887/1916/1875 +f 1887/1916/1875 1891/1933/1879 1895/1917/1883 +f 1895/1917/1883 1899/1942/1887 1872/1914/1860 +f 1872/1914/1860 1879/1923/1867 1887/1916/1875 +f 1870/1913/1858 1876/1920/1864 1875/1918/1863 +f 1876/1920/1864 1878/1922/1866 1877/1921/1865 +f 1878/1922/1866 1880/1924/1868 1879/1923/1867 +f 1880/1924/1868 1882/1927/1870 1881/1925/1869 +f 1884/1926/1872 1883/1929/1871 1881/1925/1869 +f 1886/1928/1874 1885/1931/1873 1883/1929/1871 +f 1888/1930/1876 1887/1916/1875 1885/1931/1873 +f 1890/1932/1878 1889/1934/1877 1887/1916/1875 +f 1890/1932/1878 1892/1935/1880 1891/1933/1879 +f 1892/1935/1880 1894/1937/1882 1893/1936/1881 +f 1894/1937/1882 1896/1938/1884 1895/1917/1883 +f 1896/1938/1884 1898/1941/1886 1897/1939/1885 +f 1900/1940/1888 1899/1942/1887 1897/1939/1885 +f 1869/1909/1857 1873/1912/1861 1899/1942/1887 +f 1901/1943/1889 1900/1940/1888 1898/1941/1886 +f 1904/1910/1892 1869/1909/1857 1900/1940/1888 +f 1905/1945/1893 1904/1910/1892 1901/1943/1889 +f 1902/1946/1890 1901/1943/1889 1903/1944/1891 +f 1906/1948/1894 1871/1908/1859 1904/1910/1892 +f 1915/1961/1903 1916/1915/1904 1871/1908/1859 +f 1915/1961/1903 1917/1963/1905 1919/1962/1907 +f 1917/1963/1905 1918/1968/1906 1920/1964/1908 +f 1916/1915/1904 1919/1962/1907 1876/1920/1864 +f 1919/1962/1907 1920/1964/1908 1878/1922/1866 +f 1920/1964/1908 1921/1969/1909 1880/1924/1868 +f 1918/1968/1906 1922/1970/1910 1921/1969/1909 +f 1921/1969/1909 1923/1971/1911 1882/1927/1870 +f 1922/1970/1910 1924/1974/1912 1923/1971/1911 +f 1925/1972/1913 1884/1926/1872 1882/1927/1870 +f 1926/1973/1914 1925/1972/1913 1923/1971/1911 +f 1927/1975/1915 1886/1928/1874 1884/1926/1872 +f 1928/1976/1916 1927/1975/1915 1925/1972/1913 +f 1929/1977/1917 1888/1930/1876 1886/1928/1874 +f 1930/1978/1918 1929/1977/1917 1927/1975/1915 +f 1931/1979/1919 1890/1932/1878 1888/1930/1876 +f 1932/1980/1920 1931/1979/1919 1929/1977/1917 +f 1931/1979/1919 1933/1981/1921 1892/1935/1880 +f 1932/1980/1920 1934/1982/1922 1933/1981/1921 +f 1933/1981/1921 1935/1983/1923 1894/1937/1882 +f 1934/1982/1922 1936/1984/1924 1935/1983/1923 +f 1935/1983/1923 1937/1985/1925 1896/1938/1884 +f 1936/1984/1924 1938/1986/1926 1937/1985/1925 +f 1937/1985/1925 1903/1944/1891 1898/1941/1886 +f 1938/1986/1926 1939/1947/1927 1903/1944/1891 +f 1941/1990/1929 1982/2032/1970 1945/1996/1933 +f 1944/1993/1932 1945/1996/1933 1947/1997/1935 +f 1947/1997/1935 1949/1998/1937 1908/1950/1896 +f 1949/1998/1937 1951/1999/1939 1911/1953/1899 +f 1951/1999/1939 1953/2000/1941 1914/1956/1902 +f 1953/2001/1941 1955/2002/1943 1958/1958/1946 +f 1955/2002/1943 1957/2003/1945 1959/1966/1947 +f 1959/1966/1947 1957/2003/1945 2002/2004/1990 +f 2002/2004/1990 1966/2040/1954 1965/2008/1953 +f 1965/2008/1953 1966/2040/1954 1968/2014/1956 +f 1967/2011/1955 1968/2014/1956 1970/2015/1958 +f 1970/2015/1958 1993/2028/1981 1971/2017/1959 +f 1993/2028/1981 1977/2029/1965 1976/2022/1964 +f 1977/2029/1965 1979/2030/1967 1978/2025/1966 +f 1979/2030/1967 1981/2031/1969 1980/1987/1968 +f 1981/2031/1969 1982/2032/1970 1941/1990/1929 +f 2005/2043/1993 2006/2047/1994 2004/2044/1992 +f 2003/2042/1991 2004/2044/1992 2032/2045/2015 +f 2007/2046/1995 2008/2064/1996 2006/2047/1994 +f 2010/2048/1998 2008/2063/1996 2007/2049/1995 +f 2012/2051/2000 2010/2048/1998 2009/2050/1997 +f 2014/2053/2002 2012/2051/2000 2011/2052/1999 +f 2017/2055/2005 2014/2053/2002 2013/2054/2001 +f 2018/2057/2006 2019/2058/2007 2017/2055/2005 +f 1984/2034/1972 2020/2059/2008 2019/2058/2007 +f 2019/2058/2007 2020/2059/2008 2022/2059/2010 +f 2017/2055/2005 2019/2058/2007 2021/2058/2009 +f 2029/2062/2010 2028/2075/2013 2027/2076/2014 +f 2027/2076/2014 2026/2077/2013 2025/2078/2010 +f 2025/2078/2010 2024/2079/2012 2023/2080/2011 +f 2023/2080/2011 2021/2081/2009 2022/2060/2010 +f 2022/2060/2010 2043/2082/2013 2039/2083/2014 +f 2039/2083/2014 2038/2084/2019 2037/2061/2010 +f 2037/2061/2010 2036/2085/2009 2031/2086/2011 +f 2031/2086/2011 2030/2087/2012 2029/2062/2010 +f 2029/2062/2010 2027/2076/2014 2025/2078/2010 +f 2025/2078/2010 2023/2080/2011 2022/2060/2010 +f 2022/2060/2010 2039/2083/2014 2037/2061/2010 +f 2037/2061/2010 2031/2086/2011 2029/2062/2010 +f 2029/2062/2010 2025/2078/2010 2022/2060/2010 +f 2014/2053/2002 2017/2055/2005 2023/2055/2011 +f 2012/2051/2000 2014/2053/2002 2024/2053/2012 +f 2010/2048/1998 2012/2051/2000 2025/2051/2010 +f 2008/2063/1996 2010/2048/1998 2026/2048/2013 +f 2006/2047/1994 2008/2064/1996 2027/2064/2014 +f 2004/2044/1992 2006/2047/1994 2028/2047/2013 +f 2032/2045/2015 2004/2044/1992 2029/2044/2010 +f 2033/2065/2016 2032/2045/2015 2030/2045/2012 +f 2000/2041/1988 2032/2045/2015 2033/2065/2016 +f 2034/2066/2017 2033/2065/2016 2031/2065/2011 +f 2033/2065/2016 2034/2066/2017 1996/2038/1984 +f 2035/2067/2018 2034/2066/2017 2036/2066/2009 +f 2034/2066/2017 2035/2067/2018 1994/2037/1982 +f 2040/2068/2020 2035/2067/2018 2037/2067/2010 +f 2041/2069/2021 2040/2068/2020 2038/2068/2019 +f 2035/2067/2018 2040/2068/2020 1991/2036/1979 +f 2040/2068/2020 2041/2069/2021 1989/2035/1977 +f 2042/2070/2022 2041/2069/2021 2039/2069/2014 +f 1989/2035/1977 2041/2069/2021 2042/2070/2022 +f 2020/2059/2008 2042/2070/2022 2043/2070/2013 +f 1987/2033/1975 2042/2070/2022 2020/2059/2008 +usemtl Floral_Engraved_Gold +f 1902/1949/1890 1907/1950/1895 1905/1951/1893 +f 1905/1952/1893 1910/1953/1898 1906/1954/1894 +f 1907/1950/1895 1946/1955/1934 1908/1950/1896 +f 1910/1953/1898 1908/1950/1896 1911/1953/1899 +f 1912/1956/1900 1911/1953/1899 1914/1956/1902 +f 1912/1956/1900 1906/1957/1894 1910/1953/1898 +f 1913/1958/1901 1915/1959/1903 1912/1960/1900 +f 1912/1960/1900 1958/1958/1946 1913/1958/1901 +f 1917/1965/1905 1961/1966/1949 1918/1967/1906 +f 1942/1987/1930 1938/1988/1926 1936/1989/1924 +f 1940/1990/1928 1939/1991/1927 1938/1992/1926 +f 1942/1987/1930 1941/1990/1929 1940/1990/1928 +f 1940/1990/1928 1944/1993/1932 1943/1993/1931 +f 1909/1955/1897 1944/1993/1932 1946/1955/1934 +f 1939/1994/1927 1909/1955/1897 1902/1995/1890 +f 1950/1998/1938 1947/1997/1935 1948/1997/1936 +f 1948/1997/1936 1945/1996/1933 2016/1996/2004 +f 1952/1999/1940 1949/1998/1937 1950/1998/1938 +f 1954/2000/1942 1951/1999/1939 1952/1999/1940 +f 1954/2001/1942 1955/2002/1943 1953/2001/1941 +f 1956/2002/1944 1957/2003/1945 1955/2002/1943 +f 1913/1958/1901 1959/1966/1947 1961/1966/1949 +f 1961/1966/1949 1960/2005/1948 1962/2005/1950 +f 1918/2006/1906 1962/2005/1950 1922/2007/1910 +f 1962/2005/1950 1965/2008/1953 1963/2008/1951 +f 1962/2005/1950 1924/2009/1912 1922/2010/1910 +f 1964/2011/1952 1965/2008/1953 1967/2011/1955 +f 1963/2008/1951 1926/2012/1914 1924/2013/1912 +f 1972/2016/1960 1967/2011/1955 1969/2016/1957 +f 1973/2017/1961 1969/2016/1957 1971/2017/1959 +f 1964/2011/1952 1928/2018/1916 1926/2019/1914 +f 1972/2016/1960 1930/2020/1918 1928/2021/1916 +f 1974/2022/1962 1971/2017/1959 1976/2022/1964 +f 1973/2017/1961 1932/2023/1920 1930/2024/1918 +f 1974/2022/1962 1978/2025/1966 1975/2025/1963 +f 1974/2022/1962 1934/2026/1922 1932/2027/1920 +f 1975/2025/1963 1980/1987/1968 1942/1987/1930 +f 1983/2031/1971 1982/2032/1970 1981/2031/1969 +f 1986/2030/1974 1981/2031/1969 1979/2030/1967 +f 1987/2033/1975 1983/2031/1971 1986/2030/1974 +f 1984/2034/1972 1985/2032/1973 1983/2031/1971 +f 1989/2035/1977 1986/2030/1974 1988/2029/1976 +f 1988/2029/1976 1979/2030/1967 1977/2029/1965 +f 1991/2036/1979 1988/2029/1976 1990/2028/1978 +f 1988/2029/1976 1993/2028/1981 1990/2028/1978 +f 1994/2037/1982 1990/2028/1978 1992/2015/1980 +f 1990/2028/1978 1970/2015/1958 1992/2015/1980 +f 1996/2038/1984 1992/2015/1980 1995/2014/1983 +f 1992/2015/1980 1968/2014/1956 1995/2014/1983 +f 1998/2039/1986 1995/2014/1983 1997/2040/1985 +f 1995/2014/1983 1966/2040/1954 1997/2040/1985 +f 1999/2004/1987 1998/2039/1986 1997/2040/1985 +f 1999/2004/1987 1966/2040/1954 2002/2004/1990 +f 2001/2003/1989 2000/2041/1988 1999/2004/1987 +f 2001/2003/1989 2002/2004/1990 1957/2003/1945 +f 1956/2002/1944 2003/2042/1991 2001/2003/1989 +f 1954/2001/1942 2005/2043/1993 1956/2002/1944 +f 1952/1999/1940 2007/2049/1995 1954/2000/1942 +f 1950/1998/1938 2009/2050/1997 1952/1999/1940 +f 1948/1997/1936 2011/2052/1999 1950/1998/1938 +f 2016/1996/2004 2013/2054/2001 1948/1997/1936 +f 2018/2057/2006 2016/1996/2004 1985/2032/1973 +f 1985/2032/1973 1945/1996/1933 1982/2032/1970 +f 1975/2025/1963 1936/2071/1924 1934/2072/1922 +f 1902/1949/1890 1909/1955/1897 1907/1950/1895 +f 1905/1952/1893 1907/1950/1895 1910/1953/1898 +f 1907/1950/1895 1909/1955/1897 1946/1955/1934 +f 1910/1953/1898 1907/1950/1895 1908/1950/1896 +f 1912/1956/1900 1910/1953/1898 1911/1953/1899 +f 1912/1956/1900 1915/2073/1903 1906/1957/1894 +f 1913/1958/1901 1917/2074/1905 1915/1959/1903 +f 1912/1960/1900 1914/1960/1902 1958/1958/1946 +f 1917/1965/1905 1913/1958/1901 1961/1966/1949 +f 1942/1987/1930 1940/1990/1928 1938/1988/1926 +f 1940/1990/1928 1943/1993/1931 1939/1991/1927 +f 1942/1987/1930 1980/1987/1968 1941/1990/1929 +f 1940/1990/1928 1941/1990/1929 1944/1993/1932 +f 1909/1955/1897 1943/1993/1931 1944/1993/1932 +f 1939/1994/1927 1943/1993/1931 1909/1955/1897 +f 1950/1998/1938 1949/1998/1937 1947/1997/1935 +f 1948/1997/1936 1947/1997/1935 1945/1996/1933 +f 1952/1999/1940 1951/1999/1939 1949/1998/1937 +f 1954/2000/1942 1953/2000/1941 1951/1999/1939 +f 1954/2001/1942 1956/2002/1944 1955/2002/1943 +f 1956/2002/1944 2001/2003/1989 1957/2003/1945 +f 1913/1958/1901 1958/1958/1946 1959/1966/1947 +f 1961/1966/1949 1959/1966/1947 1960/2005/1948 +f 1918/2006/1906 1961/1966/1949 1962/2005/1950 +f 1962/2005/1950 1960/2005/1948 1965/2008/1953 +f 1962/2005/1950 1963/2008/1951 1924/2009/1912 +f 1964/2011/1952 1963/2008/1951 1965/2008/1953 +f 1963/2008/1951 1964/2011/1952 1926/2012/1914 +f 1972/2016/1960 1964/2011/1952 1967/2011/1955 +f 1973/2017/1961 1972/2016/1960 1969/2016/1957 +f 1964/2011/1952 1972/2016/1960 1928/2018/1916 +f 1972/2016/1960 1973/2017/1961 1930/2020/1918 +f 1974/2022/1962 1973/2017/1961 1971/2017/1959 +f 1973/2017/1961 1974/2022/1962 1932/2023/1920 +f 1974/2022/1962 1976/2022/1964 1978/2025/1966 +f 1974/2022/1962 1975/2025/1963 1934/2026/1922 +f 1975/2025/1963 1978/2025/1966 1980/1987/1968 +f 1983/2031/1971 1985/2032/1973 1982/2032/1970 +f 1986/2030/1974 1983/2031/1971 1981/2031/1969 +f 1987/2033/1975 1984/2034/1972 1983/2031/1971 +f 1984/2034/1972 2018/2057/2006 1985/2032/1973 +f 1989/2035/1977 1987/2033/1975 1986/2030/1974 +f 1988/2029/1976 1986/2030/1974 1979/2030/1967 +f 1991/2036/1979 1989/2035/1977 1988/2029/1976 +f 1988/2029/1976 1977/2029/1965 1993/2028/1981 +f 1994/2037/1982 1991/2036/1979 1990/2028/1978 +f 1990/2028/1978 1993/2028/1981 1970/2015/1958 +f 1996/2038/1984 1994/2037/1982 1992/2015/1980 +f 1992/2015/1980 1970/2015/1958 1968/2014/1956 +f 1998/2039/1986 1996/2038/1984 1995/2014/1983 +f 1995/2014/1983 1968/2014/1956 1966/2040/1954 +f 1999/2004/1987 2000/2041/1988 1998/2039/1986 +f 1999/2004/1987 1997/2040/1985 1966/2040/1954 +f 2001/2003/1989 2003/2042/1991 2000/2041/1988 +f 2001/2003/1989 1999/2004/1987 2002/2004/1990 +f 1956/2002/1944 2005/2043/1993 2003/2042/1991 +f 1954/2001/1942 2007/2046/1995 2005/2043/1993 +f 1952/1999/1940 2009/2050/1997 2007/2049/1995 +f 1950/1998/1938 2011/2052/1999 2009/2050/1997 +f 1948/1997/1936 2013/2054/2001 2011/2052/1999 +f 2016/1996/2004 2015/2056/2003 2013/2054/2001 +f 2018/2057/2006 2015/2056/2003 2016/1996/2004 +f 1985/2032/1973 2016/1996/2004 1945/1996/1933 +f 1975/2025/1963 1942/1987/1930 1936/2071/1924 +o Cube.024 +v -0.014631 2.062691 -0.322446 +v -0.027035 2.054403 -0.322446 +v 0.000000 2.065601 -0.322446 +v -0.014667 2.062777 -0.312571 +v -0.011146 2.054277 -0.332391 +v -0.020595 2.047963 -0.332391 +v 0.000000 2.056494 -0.332391 +v 0.011146 2.054277 -0.332391 +v 0.014631 2.062691 -0.322446 +v 0.020595 2.047963 -0.332391 +v 0.027035 2.054403 -0.322446 +v 0.026909 2.038514 -0.332391 +v 0.035323 2.041999 -0.322446 +v 0.029126 2.027368 -0.332391 +v 0.038233 2.027368 -0.322446 +v 0.026909 2.016222 -0.332391 +v 0.035323 2.012737 -0.322446 +v 0.020595 2.006773 -0.332391 +v 0.027035 2.000333 -0.322446 +v 0.011146 2.000459 -0.332391 +v 0.014631 1.992045 -0.322446 +v 0.000000 1.998242 -0.332391 +v 0.000000 1.989135 -0.322446 +v -0.011146 2.000459 -0.332391 +v -0.014631 1.992045 -0.322446 +v -0.020595 2.006773 -0.332391 +v -0.027035 2.000333 -0.322446 +v -0.026909 2.016222 -0.332391 +v -0.035323 2.012737 -0.322446 +v -0.029126 2.027368 -0.332391 +v -0.038233 2.027368 -0.322446 +v -0.026909 2.038514 -0.332391 +v -0.035323 2.041999 -0.322446 +v -0.035409 2.042035 -0.312571 +v -0.038076 2.043139 -0.306458 +v -0.038327 2.027368 -0.312571 +v -0.027101 2.054469 -0.312571 +v -0.029142 2.056510 -0.306458 +v -0.015772 2.065444 -0.306458 +v -0.029142 2.056510 -0.085963 +v -0.028016 2.055384 -0.085963 +v -0.038076 2.043139 -0.085963 +v -0.015772 2.065444 -0.085963 +v -0.015162 2.063972 -0.085963 +v 0.000000 2.068581 -0.085963 +v 0.015772 2.065444 -0.085963 +v 0.000000 2.066988 -0.085963 +v 0.000000 2.068581 -0.306458 +v 0.000000 2.065694 -0.312571 +v 0.015772 2.065444 -0.306458 +v 0.029142 2.056510 -0.306458 +v 0.014667 2.062777 -0.312571 +v 0.027101 2.054469 -0.312571 +v 0.035409 2.042035 -0.312571 +v 0.038076 2.043139 -0.306458 +v 0.038327 2.027368 -0.312571 +v 0.041213 2.027368 -0.306458 +v 0.035409 2.012701 -0.312571 +v 0.038076 2.011596 -0.306458 +v 0.027101 2.000267 -0.312571 +v 0.029142 1.998226 -0.306458 +v 0.014667 1.991959 -0.312571 +v 0.015772 1.989292 -0.306458 +v 0.000000 1.989041 -0.312571 +v 0.000000 1.986155 -0.306458 +v -0.014667 1.991959 -0.312571 +v -0.015772 1.989292 -0.306458 +v -0.027101 2.000267 -0.312571 +v -0.029142 1.998226 -0.306458 +v -0.035409 2.012701 -0.312571 +v -0.038076 2.011596 -0.306458 +v -0.041213 2.027368 -0.306458 +v -0.038076 2.011596 -0.085963 +v -0.036605 2.012206 -0.085963 +v -0.029142 1.998226 -0.085963 +v -0.041213 2.027368 -0.085963 +v -0.039621 2.027368 -0.085963 +v -0.039621 2.027368 -0.079186 +v -0.036605 2.042530 -0.085963 +v -0.036605 2.042530 -0.079186 +v -0.038076 2.043139 -0.079186 +v -0.028016 2.055384 -0.079186 +v -0.029142 2.056510 -0.079186 +v -0.015162 2.063972 -0.079186 +v -0.015772 2.065444 -0.079186 +v 0.000000 2.066988 -0.079186 +v 0.000000 2.068581 -0.079186 +v 0.015162 2.063972 -0.079186 +v 0.015772 2.065444 -0.079186 +v 0.028016 2.055384 -0.079186 +v 0.015162 2.063972 -0.085963 +v 0.028016 2.055384 -0.085963 +v 0.036605 2.042530 -0.085963 +v 0.029142 2.056510 -0.085963 +v 0.038076 2.043139 -0.085963 +v 0.041213 2.027368 -0.085963 +v 0.038076 2.011596 -0.085963 +v 0.039621 2.027368 -0.085963 +v 0.039621 2.027368 -0.079186 +v 0.036605 2.012206 -0.085963 +v 0.036605 2.012206 -0.079186 +v 0.028016 1.999352 -0.085963 +v 0.028016 1.999352 -0.079186 +v 0.015162 1.990763 -0.085963 +v 0.029142 1.998226 -0.085963 +v 0.015772 1.989292 -0.085963 +v 0.000000 1.986155 -0.085963 +v -0.015772 1.989292 -0.085963 +v 0.000000 1.987747 -0.085963 +v 0.000000 1.987747 -0.079186 +v -0.015162 1.990763 -0.085963 +v -0.015162 1.990763 -0.079186 +v -0.028016 1.999352 -0.085963 +v -0.028016 1.999352 -0.079186 +v -0.036605 2.012206 -0.079186 +v -0.029142 1.998226 -0.079186 +v -0.029142 1.998226 -0.032602 +v -0.038076 2.011596 -0.079186 +v -0.015772 1.989292 -0.079186 +v -0.015772 1.989292 -0.032602 +v 0.000000 1.986155 -0.079186 +v 0.000000 1.986155 -0.032602 +v 0.015772 1.989292 -0.079186 +v 0.015772 1.989292 -0.032602 +v 0.029142 1.998226 -0.079186 +v 0.015162 1.990763 -0.079186 +v 0.029142 1.998226 -0.032602 +v 0.038076 2.011596 -0.079186 +v 0.038076 2.011596 -0.032602 +v 0.041213 2.027368 -0.079186 +v 0.041213 2.027368 -0.032602 +v 0.038076 2.043139 -0.079186 +v 0.038076 2.043139 -0.032602 +v 0.029142 2.056510 -0.079186 +v 0.036605 2.042530 -0.079186 +v 0.029142 2.056510 -0.032602 +v 0.027609 2.054977 -0.026121 +v 0.015772 2.065444 -0.032602 +v 0.014942 2.063441 -0.026121 +v 0.000000 2.068581 -0.032602 +v 0.000000 2.066413 -0.026121 +v -0.015772 2.065444 -0.032602 +v -0.014942 2.063441 -0.026121 +v -0.029142 2.056510 -0.032602 +v -0.027609 2.054977 -0.026121 +v -0.038076 2.043139 -0.032602 +v -0.036073 2.042310 -0.026121 +v -0.041213 2.027368 -0.032602 +v -0.041213 2.027368 -0.079186 +v -0.039045 2.027368 -0.026121 +v -0.038076 2.011596 -0.032602 +v -0.036073 2.012426 -0.026121 +v -0.027609 1.999759 -0.026121 +v -0.036073 2.012426 -0.026121 +v -0.027609 1.999759 -0.026121 +v -0.039045 2.027368 -0.026121 +v -0.036073 2.042310 -0.026121 +v -0.027609 2.054977 -0.026121 +v -0.014942 2.063441 -0.026121 +v 0.000000 2.066413 -0.026121 +v 0.014942 2.063441 -0.026121 +v 0.027609 2.054977 -0.026121 +v 0.036073 2.042310 -0.026121 +v 0.039045 2.027368 -0.026121 +v 0.036073 2.042310 -0.026121 +v 0.039045 2.027368 -0.026121 +v 0.036073 2.012426 -0.026121 +v 0.027609 1.999759 -0.026121 +v 0.036073 2.012426 -0.026121 +v 0.027609 1.999759 -0.026121 +v 0.014942 1.991295 -0.026121 +v 0.000000 1.988323 -0.026121 +v 0.014942 1.991295 -0.026121 +v 0.000000 1.988323 -0.026121 +v -0.014942 1.991295 -0.026121 +v -0.014942 1.991295 -0.026121 +vn -0.3953 0.8464 -0.3568 +vn -0.7091 0.6233 -0.3296 +vn -0.0000 0.9322 -0.3621 +vn -0.3620 0.9053 -0.2221 +vn -0.1339 0.4019 -0.9059 +vn -0.2889 0.3467 -0.8924 +vn -0.0000 0.4157 -0.9095 +vn 0.1339 0.4018 -0.9059 +vn 0.3953 0.8464 -0.3568 +vn 0.2889 0.3467 -0.8924 +vn 0.7091 0.6233 -0.3296 +vn 0.4621 0.2268 -0.8574 +vn 0.9171 0.3102 -0.2505 +vn 0.5874 -0.0000 -0.8093 +vn 0.9835 -0.0000 -0.1810 +vn 0.4621 -0.2268 -0.8574 +vn 0.9171 -0.3102 -0.2505 +vn 0.2889 -0.3467 -0.8924 +vn 0.7091 -0.6233 -0.3296 +vn 0.1339 -0.4019 -0.9059 +vn 0.3953 -0.8464 -0.3568 +vn -0.0000 -0.4157 -0.9095 +vn -0.0000 -0.9321 -0.3621 +vn -0.1339 -0.4018 -0.9059 +vn -0.3953 -0.8464 -0.3568 +vn -0.2889 -0.3467 -0.8924 +vn -0.7091 -0.6233 -0.3296 +vn -0.4621 -0.2268 -0.8574 +vn -0.9171 -0.3102 -0.2505 +vn -0.5874 -0.0000 -0.8093 +vn -0.9835 -0.0000 -0.1810 +vn -0.4621 0.2268 -0.8574 +vn -0.9171 0.3102 -0.2505 +vn -0.9104 0.3614 -0.2012 +vn -0.9338 0.3102 -0.1781 +vn -0.9775 -0.0000 -0.2109 +vn -0.6851 0.6965 -0.2132 +vn -0.7350 0.6447 -0.2101 +vn -0.4089 0.8866 -0.2165 +vn -0.6058 0.5677 0.5574 +vn -0.5764 0.5402 0.6131 +vn -0.8822 0.3126 0.3521 +vn -0.2963 0.6869 0.6635 +vn -0.2843 0.6591 0.6962 +vn -0.0000 0.7202 0.6938 +vn 0.2963 0.6869 0.6635 +vn -0.0000 0.6930 0.7210 +vn -0.0000 0.9762 -0.2170 +vn -0.0000 0.9743 -0.2252 +vn 0.4089 0.8866 -0.2165 +vn 0.7350 0.6447 -0.2101 +vn 0.3620 0.9053 -0.2221 +vn 0.6851 0.6965 -0.2132 +vn 0.9104 0.3614 -0.2012 +vn 0.9338 0.3102 -0.1781 +vn 0.9775 -0.0000 -0.2109 +vn 0.9902 -0.0000 -0.1394 +vn 0.9104 -0.3614 -0.2012 +vn 0.9338 -0.3102 -0.1781 +vn 0.6851 -0.6965 -0.2132 +vn 0.7350 -0.6447 -0.2101 +vn 0.3620 -0.9053 -0.2221 +vn 0.4088 -0.8866 -0.2165 +vn -0.0000 -0.9743 -0.2252 +vn -0.0000 -0.9762 -0.2170 +vn -0.3620 -0.9053 -0.2221 +vn -0.4088 -0.8866 -0.2165 +vn -0.6851 -0.6965 -0.2132 +vn -0.7350 -0.6447 -0.2101 +vn -0.9104 -0.3614 -0.2012 +vn -0.9338 -0.3102 -0.1781 +vn -0.9902 -0.0000 -0.1394 +vn -0.8822 -0.3126 0.3521 +vn -0.8290 -0.2938 0.4759 +vn -0.6058 -0.5677 0.5574 +vn -0.9746 -0.0000 0.2240 +vn -0.8952 -0.0000 0.4457 +vn -0.8952 -0.0000 -0.4457 +vn -0.8290 0.2938 0.4759 +vn -0.8290 0.2938 -0.4759 +vn -0.8822 0.3126 -0.3521 +vn -0.5765 0.5402 -0.6131 +vn -0.6058 0.5677 -0.5574 +vn -0.2843 0.6591 -0.6962 +vn -0.2963 0.6870 -0.6635 +vn -0.0000 0.6930 -0.7210 +vn -0.0000 0.7202 -0.6937 +vn 0.2843 0.6591 -0.6962 +vn 0.2963 0.6870 -0.6635 +vn 0.5765 0.5402 -0.6131 +vn 0.2843 0.6591 0.6962 +vn 0.5765 0.5402 0.6131 +vn 0.8290 0.2938 0.4759 +vn 0.6058 0.5677 0.5574 +vn 0.8822 0.3126 0.3521 +vn 0.9746 -0.0000 0.2240 +vn 0.8822 -0.3126 0.3521 +vn 0.8952 -0.0000 0.4457 +vn 0.8952 -0.0000 -0.4457 +vn 0.8290 -0.2938 0.4759 +vn 0.8290 -0.2938 -0.4759 +vn 0.5764 -0.5402 0.6131 +vn 0.5765 -0.5402 -0.6131 +vn 0.2843 -0.6591 0.6962 +vn 0.6058 -0.5677 0.5574 +vn 0.2963 -0.6869 0.6635 +vn -0.0000 -0.7202 0.6938 +vn -0.2963 -0.6869 0.6635 +vn -0.0000 -0.6930 0.7210 +vn -0.0000 -0.6930 -0.7210 +vn -0.2843 -0.6591 0.6962 +vn -0.2843 -0.6591 -0.6962 +vn -0.5765 -0.5402 0.6131 +vn -0.5764 -0.5402 -0.6131 +vn -0.8290 -0.2938 -0.4759 +vn -0.6058 -0.5677 -0.5574 +vn -0.7397 -0.6542 0.1577 +vn -0.8822 -0.3126 -0.3521 +vn -0.2963 -0.6870 -0.6635 +vn -0.4090 -0.8984 0.1598 +vn -0.0000 -0.7202 -0.6937 +vn -0.0000 -0.9872 0.1598 +vn 0.2963 -0.6870 -0.6635 +vn 0.4090 -0.8984 0.1598 +vn 0.6058 -0.5677 -0.5574 +vn 0.2843 -0.6591 -0.6962 +vn 0.7397 -0.6542 0.1577 +vn 0.8822 -0.3126 -0.3521 +vn 0.9394 -0.3123 0.1414 +vn 0.9746 -0.0000 -0.2240 +vn 0.9932 -0.0000 0.1167 +vn 0.8822 0.3126 -0.3521 +vn 0.9394 0.3123 0.1414 +vn 0.6058 0.5677 -0.5574 +vn 0.8290 0.2938 -0.4759 +vn 0.7397 0.6542 0.1577 +vn 0.9721 0.2134 0.0970 +vn 0.4090 0.8984 0.1598 +vn 0.9639 0.2509 0.0897 +vn -0.0000 0.9872 0.1597 +vn 0.9557 0.2791 0.0934 +vn -0.4090 0.8984 0.1598 +vn 0.9455 0.3067 0.1097 +vn -0.7397 0.6542 0.1577 +vn 0.9270 0.3416 0.1552 +vn -0.9394 0.3123 0.1414 +vn 0.8643 0.3868 0.3215 +vn -0.9932 -0.0000 0.1167 +vn -0.9746 -0.0000 -0.2240 +vn 0.6453 -0.0000 0.7640 +vn -0.9394 -0.3124 0.1414 +vn 0.8643 -0.3868 0.3215 +vn 0.9270 -0.3416 0.1552 +vn 0.9702 -0.0000 0.2425 +vn 0.9623 -0.0000 0.2720 +vn 0.9820 -0.0000 0.1890 +vn 0.9602 -0.0000 0.2795 +vn 0.9597 -0.0000 0.2811 +vn 0.9702 -0.0000 0.2424 +vn 0.9821 0.1448 0.1203 +vn 0.9894 -0.0000 0.1450 +vn 0.9821 -0.1448 0.1203 +vn 0.9721 -0.2134 0.0970 +vn 0.9638 -0.2509 0.0897 +vn 0.9557 -0.2791 0.0934 +vn 0.9455 -0.3067 0.1097 +vt 0.661368 0.463977 +vt 0.605181 0.394819 +vt 0.586229 0.413771 +vt 0.671624 0.439216 +vt 0.630067 0.369933 +vt 0.750000 0.454806 +vt 0.685093 0.406700 +vt 0.750000 0.481607 +vt 0.814908 0.093300 +vt 0.593300 0.185093 +vt 0.814907 0.406700 +vt 0.750000 0.419611 +vt 0.828376 0.439216 +vt 0.869933 0.369933 +vt 0.894819 0.394819 +vt 0.906701 0.314908 +vt 0.939216 0.328376 +vt 0.919611 0.250000 +vt 0.939216 0.171624 +vt 0.954806 0.250000 +vt 0.894819 0.105181 +vt 0.906700 0.185093 +vt 0.828376 0.060784 +vt 0.869933 0.130067 +vt 0.750000 0.045194 +vt 0.685093 0.093300 +vt 0.750000 0.080389 +vt 0.671624 0.060784 +vt 0.630067 0.130067 +vt 0.605181 0.105181 +vt 0.560784 0.171624 +vt 0.580389 0.250000 +vt 0.560784 0.328376 +vt 0.545194 0.250000 +vt 0.593300 0.314907 +vt 0.536023 0.338632 +vt 0.518393 0.250000 +vt 0.580294 0.419706 +vt 0.528269 0.341844 +vt 0.510000 0.250000 +vt 0.658156 0.471731 +vt 0.187500 0.532007 +vt 0.125000 0.895448 +vt 0.125000 0.532007 +vt 0.125000 0.532007 +vt 0.062500 0.895448 +vt 0.062500 0.532007 +vt 0.187500 0.895448 +vt 0.000000 0.895448 +vt 0.062500 0.532007 +vt 0.937500 0.895448 +vt 1.000000 0.532007 +vt 1.000000 0.895448 +vt 0.750000 0.490000 +vt 0.838632 0.463977 +vt 0.841844 0.471731 +vt 0.913771 0.413771 +vt 0.937500 0.532007 +vt 0.875000 0.895448 +vt 0.875000 0.532007 +vt 0.919706 0.419706 +vt 0.963977 0.338632 +vt 0.971731 0.341844 +vt 0.981607 0.250000 +vt 0.963977 0.161368 +vt 0.971731 0.158156 +vt 0.990000 0.250000 +vt 0.913771 0.086229 +vt 0.919706 0.080294 +vt 0.838632 0.036023 +vt 0.841844 0.028269 +vt 0.750000 0.018393 +vt 0.750000 0.010000 +vt 0.661368 0.036023 +vt 0.658156 0.028269 +vt 0.586229 0.086229 +vt 0.580294 0.080294 +vt 0.536023 0.161368 +vt 0.528269 0.158156 +vt 0.375000 0.895448 +vt 0.312500 0.532007 +vt 0.375000 0.532007 +vt 0.312500 0.895448 +vt 0.250000 0.532007 +vt 0.312500 0.532007 +vt 0.250000 0.895448 +vt 0.187500 0.532007 +vt 0.250000 0.532007 +vt 0.312500 0.915363 +vt 0.250000 0.915363 +vt 0.187500 0.915363 +vt 0.125000 0.915363 +vt 0.062500 0.915363 +vt 0.000000 0.915363 +vt 1.000000 0.915363 +vt 0.937500 0.915363 +vt 0.875000 0.915363 +vt 0.812500 0.895448 +vt 0.875000 0.532007 +vt 0.812500 0.532007 +vt 0.750000 0.895448 +vt 0.750000 0.532007 +vt 0.812500 0.532007 +vt 0.687500 0.895448 +vt 0.687500 0.532007 +vt 0.750000 0.532007 +vt 0.812500 0.915363 +vt 0.750000 0.915363 +vt 0.687500 0.915363 +vt 0.625000 0.895448 +vt 0.625000 0.915363 +vt 0.562500 0.895448 +vt 0.625000 0.532007 +vt 0.687500 0.532007 +vt 0.562500 0.532007 +vt 0.625000 0.532007 +vt 0.500000 0.895448 +vt 0.500000 0.532007 +vt 0.562500 0.532007 +vt 0.437500 0.895448 +vt 0.437500 0.532007 +vt 0.500000 0.532007 +vt 0.562500 0.915363 +vt 0.500000 0.915363 +vt 0.437500 0.915363 +vt 0.375000 0.915363 +vt 0.375000 0.980957 +vt 0.500000 0.980957 +vt 0.562500 0.980957 +vt 0.625000 0.980957 +vt 0.687500 0.980957 +vt 0.750000 0.980957 +vt 0.812500 0.980957 +vt 0.875000 0.980957 +vt 0.937500 0.980957 +vt 0.875000 1.000000 +vt 0.812500 1.000000 +vt 1.000000 0.980957 +vt 0.937500 1.000000 +vt 0.062500 1.000000 +vt 0.000000 0.980957 +vt 0.062500 0.980957 +vt 0.125000 1.000000 +vt 0.125000 0.980957 +vt 0.187500 1.000000 +vt 0.187500 0.980957 +vt 0.250000 1.000000 +vt 0.250000 0.980957 +vt 0.312500 0.980957 +vt 0.312500 1.000000 +vt 0.375000 1.000000 +vt 0.080294 0.080294 +vt 0.419706 0.080294 +vt 0.419706 0.419706 +vt 0.000000 1.000000 +vt 1.000000 1.000000 +vt 0.750000 1.000000 +vt 0.687500 1.000000 +vt 0.625000 1.000000 +vt 0.562500 1.000000 +vt 0.500000 1.000000 +vt 0.437500 1.000000 +vt 0.437500 0.980957 +vt 0.375000 0.532007 +vt 0.437500 0.532007 +vt 0.000000 0.532007 +vt 0.937500 0.532007 +vt 0.341844 0.471731 +vt 0.250000 0.490000 +vt 0.158156 0.471731 +vt 0.080294 0.419706 +vt 0.028269 0.341844 +vt 0.010000 0.250000 +vt 0.028269 0.158156 +vt 0.158156 0.028269 +vt 0.250000 0.010000 +vt 0.341844 0.028269 +vt 0.471731 0.158156 +vt 0.490000 0.250000 +vt 0.471731 0.341844 +s 1 +usemtl Brass.001 +f 2047/2088/2026 2045/2089/2024 2080/2090/2059 +f 2044/2091/2023 2049/2092/2028 2045/2089/2024 +f 2046/2093/2025 2048/2094/2027 2044/2091/2023 +f 2092/2095/2071 2044/2091/2023 2047/2088/2026 +f 2063/2096/2042 2071/2097/2050 2048/2094/2027 +f 2046/2093/2025 2051/2098/2030 2050/2099/2029 +f 2052/2100/2031 2053/2101/2032 2051/2098/2030 +f 2054/2102/2033 2055/2103/2034 2053/2101/2032 +f 2056/2104/2035 2057/2105/2036 2055/2103/2034 +f 2060/2106/2039 2057/2105/2036 2058/2107/2037 +f 2062/2108/2041 2059/2109/2038 2060/2106/2039 +f 2064/2110/2043 2061/2111/2040 2062/2108/2041 +f 2066/2112/2045 2063/2096/2042 2064/2110/2043 +f 2066/2112/2045 2067/2113/2046 2065/2114/2044 +f 2068/2115/2047 2069/2116/2048 2067/2113/2046 +f 2070/2117/2049 2071/2097/2050 2069/2116/2048 +f 2072/2118/2051 2073/2119/2052 2071/2097/2050 +f 2076/2120/2055 2073/2119/2052 2074/2121/2053 +f 2045/2089/2024 2075/2122/2054 2076/2120/2055 +f 2077/2123/2056 2074/2121/2053 2079/2124/2058 +f 2080/2090/2059 2076/2120/2055 2077/2123/2056 +f 2081/2125/2060 2077/2123/2056 2078/2126/2057 +f 2078/2126/2057 2079/2124/2058 2115/2127/2094 +f 2082/2128/2061 2080/2090/2059 2081/2125/2060 +f 2091/2141/2070 2047/2088/2026 2082/2128/2061 +f 2091/2141/2070 2095/2142/2074 2092/2095/2071 +f 2093/2143/2072 2096/2144/2075 2095/2142/2074 +f 2092/2095/2071 2052/2100/2031 2046/2093/2025 +f 2095/2142/2074 2054/2102/2033 2052/2100/2031 +f 2096/2144/2075 2056/2104/2035 2054/2102/2033 +f 2094/2148/2073 2097/2149/2076 2096/2144/2075 +f 2097/2149/2076 2058/2107/2037 2056/2104/2035 +f 2098/2150/2077 2099/2151/2078 2097/2149/2076 +f 2101/2152/2080 2058/2107/2037 2099/2151/2078 +f 2102/2153/2081 2099/2151/2078 2100/2154/2079 +f 2103/2155/2082 2060/2106/2039 2101/2152/2080 +f 2104/2156/2083 2101/2152/2080 2102/2153/2081 +f 2105/2157/2084 2062/2108/2041 2103/2155/2082 +f 2106/2158/2085 2103/2155/2082 2104/2156/2083 +f 2107/2159/2086 2064/2110/2043 2105/2157/2084 +f 2108/2160/2087 2105/2157/2084 2106/2158/2085 +f 2107/2159/2086 2068/2115/2047 2066/2112/2045 +f 2108/2160/2087 2109/2161/2088 2107/2159/2086 +f 2109/2161/2088 2070/2117/2049 2068/2115/2047 +f 2110/2162/2089 2111/2163/2090 2109/2161/2088 +f 2111/2163/2090 2072/2118/2051 2070/2117/2049 +f 2112/2164/2091 2113/2165/2092 2111/2163/2090 +f 2113/2165/2092 2074/2121/2053 2072/2118/2051 +f 2114/2166/2093 2079/2124/2058 2113/2165/2092 +f 2158/2176/2137 2120/2173/2099 2117/2170/2096 +f 2121/2177/2100 2122/2135/2101 2120/2173/2099 +f 2123/2178/2102 2084/2130/2063 2122/2135/2101 +f 2084/2130/2063 2127/2180/2106 2087/2133/2066 +f 2087/2133/2066 2129/2181/2108 2090/2136/2069 +f 2129/2182/2108 2134/2138/2113 2090/2140/2069 +f 2131/2183/2110 2135/2146/2114 2134/2138/2113 +f 2133/2184/2112 2136/2185/2115 2135/2146/2114 +f 2178/2194/2157 2141/2188/2120 2136/2185/2115 +f 2142/2195/2121 2143/2191/2122 2141/2188/2120 +f 2144/2196/2123 2145/2197/2124 2143/2191/2122 +f 2146/2198/2125 2147/2199/2126 2145/2197/2124 +f 2169/2210/2148 2152/2204/2131 2147/2199/2126 +f 2153/2211/2132 2154/2207/2133 2152/2204/2131 +f 2155/2212/2134 2156/2167/2135 2154/2207/2133 +f 2157/2213/2136 2117/2170/2096 2156/2167/2135 +f 2181/2222/2160 2180/2223/2159 2179/2221/2158 +f 2179/2221/2158 2208/2224/2182 2176/2220/2155 +f 2183/2225/2162 2182/2226/2161 2181/2222/2160 +f 2186/2227/2165 2183/2228/2162 2185/2229/2164 +f 2188/2230/2167 2185/2229/2164 2187/2231/2166 +f 2190/2232/2169 2187/2231/2166 2189/2233/2168 +f 2193/2234/2172 2189/2233/2168 2191/2235/2170 +f 2194/2236/2173 2193/2234/2172 2191/2235/2170 +f 2160/2214/2139 2195/2237/2174 2194/2236/2173 +f 2195/2237/2174 2198/2238/2177 2197/2237/2176 +f 2193/2234/2172 2197/2237/2176 2199/2234/2178 +f 2198/2239/2177 2213/2240/2177 2205/2241/2177 +f 2190/2232/2169 2199/2234/2178 2200/2232/2176 +f 2188/2230/2167 2200/2232/2176 2201/2230/2177 +f 2186/2227/2165 2201/2230/2177 2202/2227/2179 +f 2184/2242/2163 2202/2227/2179 2203/2242/2180 +f 2182/2226/2161 2203/2243/2180 2204/2226/2179 +f 2180/2223/2159 2204/2226/2179 2205/2223/2177 +f 2208/2224/2182 2205/2223/2177 2206/2224/2181 +f 2209/2244/2183 2206/2224/2181 2207/2244/2178 +f 2176/2220/2155 2209/2244/2183 2174/2219/2153 +f 2210/2245/2184 2207/2244/2178 2212/2245/2181 +f 2209/2244/2183 2172/2218/2151 2174/2219/2153 +f 2211/2246/2185 2212/2245/2181 2213/2246/2177 +f 2210/2245/2184 2170/2217/2149 2172/2218/2151 +f 2216/2247/2186 2213/2246/2177 2214/2247/2179 +f 2217/2248/2187 2214/2247/2179 2215/2248/2180 +f 2211/2246/2185 2167/2216/2146 2170/2217/2149 +f 2216/2247/2186 2165/2215/2144 2167/2216/2146 +f 2218/2249/2188 2215/2248/2180 2219/2249/2179 +f 2165/2215/2144 2218/2249/2188 2163/2250/2142 +f 2196/2238/2175 2219/2249/2179 2198/2238/2177 +f 2163/2250/2142 2196/2238/2175 2160/2214/2139 +f 2047/2088/2026 2044/2091/2023 2045/2089/2024 +f 2044/2091/2023 2048/2094/2027 2049/2092/2028 +f 2046/2093/2025 2050/2099/2029 2048/2094/2027 +f 2092/2095/2071 2046/2093/2025 2044/2091/2023 +f 2048/2094/2027 2050/2099/2029 2051/2098/2030 +f 2051/2098/2030 2053/2101/2032 2055/2103/2034 +f 2055/2103/2034 2057/2105/2036 2059/2109/2038 +f 2059/2109/2038 2061/2111/2040 2063/2096/2042 +f 2063/2096/2042 2065/2114/2044 2067/2113/2046 +f 2067/2113/2046 2069/2116/2048 2071/2097/2050 +f 2071/2097/2050 2073/2119/2052 2075/2122/2054 +f 2075/2122/2054 2049/2092/2028 2048/2094/2027 +f 2048/2094/2027 2051/2098/2030 2055/2103/2034 +f 2055/2103/2034 2059/2109/2038 2063/2096/2042 +f 2063/2096/2042 2067/2113/2046 2071/2097/2050 +f 2071/2097/2050 2075/2122/2054 2048/2094/2027 +f 2048/2094/2027 2055/2103/2034 2063/2096/2042 +f 2046/2093/2025 2052/2100/2031 2051/2098/2030 +f 2052/2100/2031 2054/2102/2033 2053/2101/2032 +f 2054/2102/2033 2056/2104/2035 2055/2103/2034 +f 2056/2104/2035 2058/2107/2037 2057/2105/2036 +f 2060/2106/2039 2059/2109/2038 2057/2105/2036 +f 2062/2108/2041 2061/2111/2040 2059/2109/2038 +f 2064/2110/2043 2063/2096/2042 2061/2111/2040 +f 2066/2112/2045 2065/2114/2044 2063/2096/2042 +f 2066/2112/2045 2068/2115/2047 2067/2113/2046 +f 2068/2115/2047 2070/2117/2049 2069/2116/2048 +f 2070/2117/2049 2072/2118/2051 2071/2097/2050 +f 2072/2118/2051 2074/2121/2053 2073/2119/2052 +f 2076/2120/2055 2075/2122/2054 2073/2119/2052 +f 2045/2089/2024 2049/2092/2028 2075/2122/2054 +f 2077/2123/2056 2076/2120/2055 2074/2121/2053 +f 2080/2090/2059 2045/2089/2024 2076/2120/2055 +f 2081/2125/2060 2080/2090/2059 2077/2123/2056 +f 2078/2126/2057 2077/2123/2056 2079/2124/2058 +f 2082/2128/2061 2047/2088/2026 2080/2090/2059 +f 2091/2141/2070 2092/2095/2071 2047/2088/2026 +f 2091/2141/2070 2093/2143/2072 2095/2142/2074 +f 2093/2143/2072 2094/2148/2073 2096/2144/2075 +f 2092/2095/2071 2095/2142/2074 2052/2100/2031 +f 2095/2142/2074 2096/2144/2075 2054/2102/2033 +f 2096/2144/2075 2097/2149/2076 2056/2104/2035 +f 2094/2148/2073 2098/2150/2077 2097/2149/2076 +f 2097/2149/2076 2099/2151/2078 2058/2107/2037 +f 2098/2150/2077 2100/2154/2079 2099/2151/2078 +f 2101/2152/2080 2060/2106/2039 2058/2107/2037 +f 2102/2153/2081 2101/2152/2080 2099/2151/2078 +f 2103/2155/2082 2062/2108/2041 2060/2106/2039 +f 2104/2156/2083 2103/2155/2082 2101/2152/2080 +f 2105/2157/2084 2064/2110/2043 2062/2108/2041 +f 2106/2158/2085 2105/2157/2084 2103/2155/2082 +f 2107/2159/2086 2066/2112/2045 2064/2110/2043 +f 2108/2160/2087 2107/2159/2086 2105/2157/2084 +f 2107/2159/2086 2109/2161/2088 2068/2115/2047 +f 2108/2160/2087 2110/2162/2089 2109/2161/2088 +f 2109/2161/2088 2111/2163/2090 2070/2117/2049 +f 2110/2162/2089 2112/2164/2091 2111/2163/2090 +f 2111/2163/2090 2113/2165/2092 2072/2118/2051 +f 2112/2164/2091 2114/2166/2093 2113/2165/2092 +f 2113/2165/2092 2079/2124/2058 2074/2121/2053 +f 2114/2166/2093 2115/2127/2094 2079/2124/2058 +f 2158/2176/2137 2121/2177/2100 2120/2173/2099 +f 2121/2177/2100 2123/2178/2102 2122/2135/2101 +f 2123/2178/2102 2125/2179/2104 2084/2130/2063 +f 2084/2130/2063 2125/2179/2104 2127/2180/2106 +f 2087/2133/2066 2127/2180/2106 2129/2181/2108 +f 2129/2182/2108 2131/2183/2110 2134/2138/2113 +f 2131/2183/2110 2133/2184/2112 2135/2146/2114 +f 2133/2184/2112 2178/2194/2157 2136/2185/2115 +f 2178/2194/2157 2142/2195/2121 2141/2188/2120 +f 2142/2195/2121 2144/2196/2123 2143/2191/2122 +f 2144/2196/2123 2146/2198/2125 2145/2197/2124 +f 2146/2198/2125 2169/2210/2148 2147/2199/2126 +f 2169/2210/2148 2153/2211/2132 2152/2204/2131 +f 2153/2211/2132 2155/2212/2134 2154/2207/2133 +f 2155/2212/2134 2157/2213/2136 2156/2167/2135 +f 2157/2213/2136 2158/2176/2137 2117/2170/2096 +f 2181/2222/2160 2182/2226/2161 2180/2223/2159 +f 2179/2221/2158 2180/2223/2159 2208/2224/2182 +f 2183/2225/2162 2184/2243/2163 2182/2226/2161 +f 2186/2227/2165 2184/2242/2163 2183/2228/2162 +f 2188/2230/2167 2186/2227/2165 2185/2229/2164 +f 2190/2232/2169 2188/2230/2167 2187/2231/2166 +f 2193/2234/2172 2190/2232/2169 2189/2233/2168 +f 2194/2236/2173 2195/2237/2174 2193/2234/2172 +f 2160/2214/2139 2196/2238/2175 2195/2237/2174 +f 2195/2237/2174 2196/2238/2175 2198/2238/2177 +f 2193/2234/2172 2195/2237/2174 2197/2237/2176 +f 2205/2241/2177 2204/2255/2179 2203/2256/2180 +f 2203/2256/2180 2202/2257/2179 2201/2258/2177 +f 2201/2258/2177 2200/2259/2176 2199/2260/2178 +f 2199/2260/2178 2197/2261/2176 2198/2239/2177 +f 2198/2239/2177 2219/2262/2179 2215/2263/2180 +f 2215/2263/2180 2214/2264/2179 2213/2240/2177 +f 2213/2240/2177 2212/2265/2181 2207/2266/2178 +f 2207/2266/2178 2206/2267/2181 2205/2241/2177 +f 2205/2241/2177 2203/2256/2180 2201/2258/2177 +f 2201/2258/2177 2199/2260/2178 2198/2239/2177 +f 2198/2239/2177 2215/2263/2180 2213/2240/2177 +f 2213/2240/2177 2207/2266/2178 2205/2241/2177 +f 2205/2241/2177 2201/2258/2177 2198/2239/2177 +f 2190/2232/2169 2193/2234/2172 2199/2234/2178 +f 2188/2230/2167 2190/2232/2169 2200/2232/2176 +f 2186/2227/2165 2188/2230/2167 2201/2230/2177 +f 2184/2242/2163 2186/2227/2165 2202/2227/2179 +f 2182/2226/2161 2184/2243/2163 2203/2243/2180 +f 2180/2223/2159 2182/2226/2161 2204/2226/2179 +f 2208/2224/2182 2180/2223/2159 2205/2223/2177 +f 2209/2244/2183 2208/2224/2182 2206/2224/2181 +f 2176/2220/2155 2208/2224/2182 2209/2244/2183 +f 2210/2245/2184 2209/2244/2183 2207/2244/2178 +f 2209/2244/2183 2210/2245/2184 2172/2218/2151 +f 2211/2246/2185 2210/2245/2184 2212/2245/2181 +f 2210/2245/2184 2211/2246/2185 2170/2217/2149 +f 2216/2247/2186 2211/2246/2185 2213/2246/2177 +f 2217/2248/2187 2216/2247/2186 2214/2247/2179 +f 2211/2246/2185 2216/2247/2186 2167/2216/2146 +f 2216/2247/2186 2217/2248/2187 2165/2215/2144 +f 2218/2249/2188 2217/2248/2187 2215/2248/2180 +f 2165/2215/2144 2217/2248/2187 2218/2249/2188 +f 2196/2238/2175 2218/2249/2188 2219/2249/2179 +f 2163/2250/2142 2218/2249/2188 2196/2238/2175 +usemtl Floral_Engraved_Gold +f 2078/2129/2057 2083/2130/2062 2081/2131/2060 +f 2081/2132/2060 2086/2133/2065 2082/2134/2061 +f 2083/2130/2062 2122/2135/2101 2084/2130/2063 +f 2086/2133/2065 2084/2130/2063 2087/2133/2066 +f 2088/2136/2067 2087/2133/2066 2090/2136/2069 +f 2088/2136/2067 2082/2137/2061 2086/2133/2065 +f 2089/2138/2068 2091/2139/2070 2088/2140/2067 +f 2088/2140/2067 2134/2138/2113 2089/2138/2068 +f 2093/2145/2072 2137/2146/2116 2094/2147/2073 +f 2118/2167/2097 2114/2168/2093 2112/2169/2091 +f 2116/2170/2095 2115/2171/2094 2114/2172/2093 +f 2118/2167/2097 2117/2170/2096 2116/2170/2095 +f 2116/2170/2095 2120/2173/2099 2119/2173/2098 +f 2085/2135/2064 2120/2173/2099 2122/2135/2101 +f 2119/2173/2098 2078/2174/2057 2115/2175/2094 +f 2126/2179/2105 2123/2178/2102 2124/2178/2103 +f 2124/2178/2103 2121/2177/2100 2192/2177/2171 +f 2128/2180/2107 2125/2179/2104 2126/2179/2105 +f 2130/2181/2109 2127/2180/2106 2128/2180/2107 +f 2130/2182/2109 2131/2183/2110 2129/2182/2108 +f 2132/2183/2111 2133/2184/2112 2131/2183/2110 +f 2089/2138/2068 2135/2146/2114 2137/2146/2116 +f 2137/2146/2116 2136/2185/2115 2138/2185/2117 +f 2094/2186/2073 2138/2185/2117 2098/2187/2077 +f 2138/2185/2117 2141/2188/2120 2139/2188/2118 +f 2138/2185/2117 2100/2189/2079 2098/2190/2077 +f 2140/2191/2119 2141/2188/2120 2143/2191/2122 +f 2139/2188/2118 2102/2192/2081 2100/2193/2079 +f 2148/2197/2127 2143/2191/2122 2145/2197/2124 +f 2149/2199/2128 2145/2197/2124 2147/2199/2126 +f 2140/2191/2119 2104/2200/2083 2102/2201/2081 +f 2148/2197/2127 2106/2202/2085 2104/2203/2083 +f 2150/2204/2129 2147/2199/2126 2152/2204/2131 +f 2149/2199/2128 2108/2205/2087 2106/2206/2085 +f 2150/2204/2129 2154/2207/2133 2151/2207/2130 +f 2150/2204/2129 2110/2208/2089 2108/2209/2087 +f 2151/2207/2130 2156/2167/2135 2118/2167/2097 +f 2159/2213/2138 2158/2176/2137 2157/2213/2136 +f 2162/2212/2141 2157/2213/2136 2155/2212/2134 +f 2162/2212/2141 2160/2214/2139 2159/2213/2138 +f 2160/2214/2139 2161/2176/2140 2159/2213/2138 +f 2165/2215/2144 2162/2212/2141 2164/2211/2143 +f 2164/2211/2143 2155/2212/2134 2153/2211/2132 +f 2167/2216/2146 2164/2211/2143 2166/2210/2145 +f 2164/2211/2143 2169/2210/2148 2166/2210/2145 +f 2170/2217/2149 2166/2210/2145 2168/2198/2147 +f 2166/2210/2145 2146/2198/2125 2168/2198/2147 +f 2172/2218/2151 2168/2198/2147 2171/2196/2150 +f 2168/2198/2147 2144/2196/2123 2171/2196/2150 +f 2174/2219/2153 2171/2196/2150 2173/2195/2152 +f 2171/2196/2150 2142/2195/2121 2173/2195/2152 +f 2175/2194/2154 2174/2219/2153 2173/2195/2152 +f 2175/2194/2154 2142/2195/2121 2178/2194/2157 +f 2177/2184/2156 2176/2220/2155 2175/2194/2154 +f 2177/2184/2156 2178/2194/2157 2133/2184/2112 +f 2132/2183/2111 2179/2221/2158 2177/2184/2156 +f 2130/2182/2109 2181/2222/2160 2132/2183/2111 +f 2128/2180/2107 2183/2228/2162 2130/2181/2109 +f 2126/2179/2105 2185/2229/2164 2128/2180/2107 +f 2124/2178/2103 2187/2231/2166 2126/2179/2105 +f 2192/2177/2171 2189/2233/2168 2124/2178/2103 +f 2194/2236/2173 2192/2177/2171 2161/2176/2140 +f 2161/2176/2140 2121/2177/2100 2158/2176/2137 +f 2151/2207/2130 2112/2251/2091 2110/2252/2089 +f 2078/2129/2057 2085/2135/2064 2083/2130/2062 +f 2081/2132/2060 2083/2130/2062 2086/2133/2065 +f 2083/2130/2062 2085/2135/2064 2122/2135/2101 +f 2086/2133/2065 2083/2130/2062 2084/2130/2063 +f 2088/2136/2067 2086/2133/2065 2087/2133/2066 +f 2088/2136/2067 2091/2253/2070 2082/2137/2061 +f 2089/2138/2068 2093/2254/2072 2091/2139/2070 +f 2088/2140/2067 2090/2140/2069 2134/2138/2113 +f 2093/2145/2072 2089/2138/2068 2137/2146/2116 +f 2118/2167/2097 2116/2170/2095 2114/2168/2093 +f 2116/2170/2095 2119/2173/2098 2115/2171/2094 +f 2118/2167/2097 2156/2167/2135 2117/2170/2096 +f 2116/2170/2095 2117/2170/2096 2120/2173/2099 +f 2085/2135/2064 2119/2173/2098 2120/2173/2099 +f 2119/2173/2098 2085/2135/2064 2078/2174/2057 +f 2126/2179/2105 2125/2179/2104 2123/2178/2102 +f 2124/2178/2103 2123/2178/2102 2121/2177/2100 +f 2128/2180/2107 2127/2180/2106 2125/2179/2104 +f 2130/2181/2109 2129/2181/2108 2127/2180/2106 +f 2130/2182/2109 2132/2183/2111 2131/2183/2110 +f 2132/2183/2111 2177/2184/2156 2133/2184/2112 +f 2089/2138/2068 2134/2138/2113 2135/2146/2114 +f 2137/2146/2116 2135/2146/2114 2136/2185/2115 +f 2094/2186/2073 2137/2146/2116 2138/2185/2117 +f 2138/2185/2117 2136/2185/2115 2141/2188/2120 +f 2138/2185/2117 2139/2188/2118 2100/2189/2079 +f 2140/2191/2119 2139/2188/2118 2141/2188/2120 +f 2139/2188/2118 2140/2191/2119 2102/2192/2081 +f 2148/2197/2127 2140/2191/2119 2143/2191/2122 +f 2149/2199/2128 2148/2197/2127 2145/2197/2124 +f 2140/2191/2119 2148/2197/2127 2104/2200/2083 +f 2148/2197/2127 2149/2199/2128 2106/2202/2085 +f 2150/2204/2129 2149/2199/2128 2147/2199/2126 +f 2149/2199/2128 2150/2204/2129 2108/2205/2087 +f 2150/2204/2129 2152/2204/2131 2154/2207/2133 +f 2150/2204/2129 2151/2207/2130 2110/2208/2089 +f 2151/2207/2130 2154/2207/2133 2156/2167/2135 +f 2159/2213/2138 2161/2176/2140 2158/2176/2137 +f 2162/2212/2141 2159/2213/2138 2157/2213/2136 +f 2162/2212/2141 2163/2250/2142 2160/2214/2139 +f 2160/2214/2139 2194/2236/2173 2161/2176/2140 +f 2165/2215/2144 2163/2250/2142 2162/2212/2141 +f 2164/2211/2143 2162/2212/2141 2155/2212/2134 +f 2167/2216/2146 2165/2215/2144 2164/2211/2143 +f 2164/2211/2143 2153/2211/2132 2169/2210/2148 +f 2170/2217/2149 2167/2216/2146 2166/2210/2145 +f 2166/2210/2145 2169/2210/2148 2146/2198/2125 +f 2172/2218/2151 2170/2217/2149 2168/2198/2147 +f 2168/2198/2147 2146/2198/2125 2144/2196/2123 +f 2174/2219/2153 2172/2218/2151 2171/2196/2150 +f 2171/2196/2150 2144/2196/2123 2142/2195/2121 +f 2175/2194/2154 2176/2220/2155 2174/2219/2153 +f 2175/2194/2154 2173/2195/2152 2142/2195/2121 +f 2177/2184/2156 2179/2221/2158 2176/2220/2155 +f 2177/2184/2156 2175/2194/2154 2178/2194/2157 +f 2132/2183/2111 2181/2222/2160 2179/2221/2158 +f 2130/2182/2109 2183/2225/2162 2181/2222/2160 +f 2128/2180/2107 2185/2229/2164 2183/2228/2162 +f 2126/2179/2105 2187/2231/2166 2185/2229/2164 +f 2124/2178/2103 2189/2233/2168 2187/2231/2166 +f 2192/2177/2171 2191/2235/2170 2189/2233/2168 +f 2194/2236/2173 2191/2235/2170 2192/2177/2171 +f 2161/2176/2140 2192/2177/2171 2121/2177/2100 +f 2151/2207/2130 2118/2167/2097 2112/2251/2091 +o Cube.025 +v 0.000000 0.555217 -0.109416 +v -0.018999 0.555217 -0.084157 +v 0.018999 0.555216 -0.084157 +v 0.000000 0.559271 -0.107279 +v 0.018528 0.559271 -0.082647 +v -0.018528 0.559271 -0.082647 +v 0.000000 0.559188 -0.103427 +v 0.000000 0.579339 -0.092809 +v 0.017770 0.559188 -0.079802 +v -0.017770 0.559188 -0.079802 +v -0.015431 0.579339 -0.072294 +v -0.025131 0.559188 -0.004438 +v -0.021823 0.579339 -0.004438 +v -0.026203 0.559271 -0.004068 +v -0.026522 0.559188 0.052598 +v -0.027653 0.559271 0.055401 +v -0.023030 0.579339 0.045090 +v 0.000000 0.559188 0.061839 +v 0.000000 0.559271 0.065035 +v 0.000000 0.579339 0.051221 +v 0.026522 0.559188 0.052598 +v 0.023030 0.579339 0.045090 +v 0.027653 0.559271 0.055401 +v 0.025131 0.559188 -0.004438 +v 0.026203 0.559271 -0.004068 +v 0.021823 0.579339 -0.004438 +v 0.015431 0.579339 -0.072294 +v 0.000000 0.579339 -0.004438 +v 0.026868 0.555216 -0.004068 +v 0.028355 0.555216 0.056911 +v 0.000000 0.555217 0.067172 +v -0.028355 0.555217 0.056911 +v -0.026868 0.555217 -0.004068 +vn -0.7619 0.3020 -0.5731 +vn 0.7619 0.3020 -0.5731 +vn -0.0286 0.9994 0.0215 +vn 0.0286 0.9994 0.0215 +vn 0.0799 0.9968 0.0078 +vn -0.9840 0.1500 -0.0961 +vn -0.9865 0.1620 -0.0241 +vn 0.0778 0.9970 0.0019 +vn 0.0090 0.9996 -0.0259 +vn -0.3046 0.3784 0.8741 +vn -0.0090 0.9996 -0.0259 +vn 0.3046 0.3784 0.8741 +vn 0.9865 0.1620 -0.0241 +vn -0.0778 0.9970 0.0019 +vn -0.0799 0.9968 0.0078 +vn 0.9840 0.1500 -0.0961 +vn -0.0000 1.0000 -0.0000 +vn 0.9839 0.1502 -0.0967 +vn 0.3149 0.3788 0.8702 +vn -0.3149 0.3788 0.8703 +vn -0.9839 0.1502 -0.0967 +vn -0.9826 0.1613 -0.0926 +vn -0.2292 0.4538 0.8611 +vn 0.2292 0.4538 0.8611 +vn 0.9826 0.1613 -0.0926 +vn 0.9822 0.1613 -0.0959 +vn 0.2946 0.4455 0.8454 +vn -0.2946 0.4455 0.8454 +vn -0.9822 0.1613 -0.0959 +vt 0.505656 0.947866 +vt 0.212969 0.920779 +vt 0.511650 0.999904 +vt 0.048615 0.677086 +vt 0.000096 0.696826 +vt 0.236242 0.881500 +vt 0.236242 0.881500 +vt 0.300053 0.574789 +vt 0.474595 0.678198 +vt 0.868828 0.740874 +vt 0.624482 0.425210 +vt 0.875919 0.322914 +vt 0.688293 0.118500 +vt 0.418879 0.052134 +vt 0.418879 0.052134 +vt 0.449942 0.321802 +vt 0.055706 0.259126 +vt 0.343889 0.429863 +vt 0.462268 0.500000 +vt 0.356842 0.677946 +vt 0.567694 0.322055 +vt 0.580648 0.570137 +vt 0.000096 0.226179 +vt 0.412885 0.000096 +vt 0.711565 0.079221 +vt 0.924438 0.303174 +vt 0.924438 0.773821 +s 0 +usemtl Geometric_Brass_Engraved_Pattern +f 2226/2273/2190 2246/2275/2190 2228/2271/2190 +f 2230/2276/2189 2226/2273/2189 2229/2268/2189 +f 2231/2277/2194 2230/2276/2194 2229/2268/2194 +f 2236/2278/2195 2231/2277/2195 2234/2279/2195 +f 2237/2280/2198 2236/2278/2198 2234/2279/2198 +f 2241/2283/2200 2237/2280/2200 2240/2281/2200 +f 2243/2284/2201 2241/2283/2201 2240/2281/2201 +f 2246/2275/2204 2243/2284/2204 2228/2271/2204 +f 2245/2285/2205 2247/2286/2205 2241/2283/2205 +f 2246/2275/2205 2247/2286/2205 2245/2285/2205 +f 2227/2287/2205 2247/2286/2205 2246/2275/2205 +f 2230/2276/2205 2247/2286/2205 2227/2287/2205 +f 2239/2288/2205 2247/2286/2205 2236/2278/2205 +f 2241/2283/2205 2247/2286/2205 2239/2288/2205 +f 2232/2289/2205 2247/2286/2205 2230/2276/2205 +f 2236/2278/2205 2247/2286/2205 2232/2289/2205 +f 2226/2273/2190 2227/2287/2190 2246/2275/2190 +f 2230/2276/2189 2227/2287/2189 2226/2273/2189 +f 2231/2277/2210 2232/2289/2210 2230/2276/2210 +f 2236/2278/2195 2232/2289/2195 2231/2277/2195 +f 2237/2280/2211 2239/2288/2211 2236/2278/2211 +f 2241/2283/2212 2239/2288/2212 2237/2280/2212 +f 2243/2284/2201 2245/2285/2201 2241/2283/2201 +f 2246/2275/2213 2245/2285/2213 2243/2284/2213 +usemtl Brass.001 +f 2225/2268/2189 2220/2269/2189 2221/2270/2189 +f 2220/2269/2190 2224/2271/2190 2222/2272/2190 +f 2226/2273/2191 2224/2271/2191 2223/2274/2191 +f 2225/2268/2192 2226/2273/2192 2223/2274/2192 +f 2233/2277/2193 2229/2268/2193 2225/2268/2193 +f 2234/2279/2196 2233/2277/2196 2235/2279/2196 +f 2238/2280/2197 2234/2279/2197 2235/2279/2197 +f 2240/2281/2199 2238/2280/2199 2242/2282/2199 +f 2244/2284/2202 2240/2281/2202 2242/2282/2202 +f 2228/2271/2203 2244/2284/2203 2224/2271/2203 +f 2248/2290/2201 2242/2282/2201 2249/2291/2201 +f 2224/2271/2206 2248/2290/2206 2222/2272/2206 +f 2242/2282/2207 2250/2292/2207 2249/2291/2207 +f 2250/2292/2208 2235/2279/2208 2251/2293/2208 +f 2235/2279/2195 2252/2294/2195 2251/2293/2195 +f 2252/2294/2209 2225/2268/2209 2221/2270/2209 +f 2225/2268/2189 2223/2274/2189 2220/2269/2189 +f 2220/2269/2190 2223/2274/2190 2224/2271/2190 +f 2226/2273/2191 2228/2271/2191 2224/2271/2191 +f 2225/2268/2192 2229/2268/2192 2226/2273/2192 +f 2233/2277/2193 2231/2277/2193 2229/2268/2193 +f 2234/2279/2196 2231/2277/2196 2233/2277/2196 +f 2238/2280/2197 2237/2280/2197 2234/2279/2197 +f 2240/2281/2199 2237/2280/2199 2238/2280/2199 +f 2244/2284/2202 2243/2284/2202 2240/2281/2202 +f 2228/2271/2203 2243/2284/2203 2244/2284/2203 +f 2248/2290/2201 2244/2284/2201 2242/2282/2201 +f 2224/2271/2214 2244/2284/2214 2248/2290/2214 +f 2242/2282/2215 2238/2280/2215 2250/2292/2215 +f 2250/2292/2216 2238/2280/2216 2235/2279/2216 +f 2235/2279/2195 2233/2277/2195 2252/2294/2195 +f 2252/2294/2217 2233/2277/2217 2225/2268/2217 +o Cube.026 +v 0.013838 0.330423 0.175394 +v -0.013838 0.330423 0.175394 +v 0.000000 0.324393 0.170296 +v -0.019570 0.344983 0.187701 +v 0.019570 0.344983 0.187701 +v -0.013838 0.359542 0.200008 +v 0.013838 0.359542 0.200008 +v 0.000000 0.365572 0.205106 +vn -0.0000 -0.6456 0.7637 +vt 0.428571 0.000000 +vt 0.285714 0.000000 +vt 0.000000 0.000000 +vt 0.142857 0.000000 +vt 1.000000 0.000000 +vt 0.571429 0.000000 +vt 0.857143 0.000000 +vt 0.714286 0.000000 +s 1 +usemtl Brass.001 +f 2256/2295/2218 2254/2296/2218 2253/2297/2218 +f 2254/2296/2218 2255/2298/2218 2253/2297/2218 +f 2256/2295/2218 2253/2297/2218 2257/2299/2218 +f 2258/2300/2218 2256/2295/2218 2257/2299/2218 +f 2258/2300/2218 2257/2299/2218 2259/2301/2218 +f 2260/2302/2218 2258/2300/2218 2259/2301/2218 +o Cube.027 +v 0.008899 0.102645 0.095615 +v 0.012585 0.095108 0.100345 +v 0.000000 0.105767 0.093656 +v 0.000000 0.095108 0.100345 +v 0.000000 0.084449 0.107035 +v 0.008899 0.087571 0.105076 +v -0.008899 0.102645 0.095615 +v -0.012585 0.095108 0.100345 +v -0.008899 0.087571 0.105076 +v 0.000000 0.084449 0.107035 +v -0.008899 0.087571 0.105076 +v 0.000000 0.105767 0.093656 +v -0.008899 0.102645 0.095615 +v 0.012585 0.095108 0.100345 +v 0.008899 0.102645 0.095615 +v 0.008899 0.087571 0.105076 +v -0.012585 0.095108 0.100345 +v 0.012169 0.171553 0.198117 +v 0.017209 0.165942 0.208915 +v 0.000000 0.173878 0.193645 +v 0.016860 0.308293 0.178662 +v 0.023844 0.313587 0.201278 +v 0.000000 0.306101 0.169294 +v 0.013838 0.330423 0.175394 +v 0.019570 0.344983 0.187701 +v 0.000000 0.324393 0.170296 +v -0.013838 0.330423 0.175394 +v -0.016860 0.308293 0.178662 +v -0.019570 0.344983 0.187701 +v -0.023844 0.313587 0.201278 +v -0.013838 0.359542 0.200008 +v -0.016860 0.318880 0.223894 +v 0.000000 0.365572 0.205106 +v 0.000000 0.321073 0.233262 +v 0.013838 0.359542 0.200008 +v 0.016860 0.318880 0.223894 +v 0.012169 0.160330 0.219712 +v 0.000000 0.158005 0.224184 +v -0.012168 0.160330 0.219712 +v -0.017209 0.165942 0.208915 +v -0.012168 0.171553 0.198117 +vn -0.0000 -0.5316 -0.8470 +vn -0.0000 -0.9825 -0.1861 +vn 0.6696 -0.7280 -0.1473 +vn -0.9743 -0.1215 -0.1894 +vn -0.6696 -0.7280 -0.1473 +vn -0.0000 0.2415 -0.9704 +vn -0.6690 0.1719 -0.7231 +vn 0.9743 -0.1215 -0.1894 +vn 0.6690 0.1719 -0.7231 +vn 0.8335 0.2029 -0.5139 +vn 0.9959 -0.0741 0.0512 +vn -0.0000 0.3801 -0.9250 +vn 0.8708 -0.0510 -0.4890 +vn 0.9994 0.0338 0.0108 +vn -0.0000 -0.0746 -0.9972 +vn 0.7471 0.0149 -0.6646 +vn 0.9900 0.1405 -0.0091 +vn -0.0000 0.0547 -0.9985 +vn -0.7471 0.0149 -0.6646 +vn -0.8708 -0.0510 -0.4890 +vn -0.9900 0.1405 -0.0091 +vn -0.9994 0.0338 0.0108 +vn -0.8174 0.3355 0.4683 +vn -0.8656 0.1432 0.4798 +vn -0.0000 0.5347 0.8451 +vn -0.0000 0.2562 0.9666 +vn 0.8174 0.3355 0.4683 +vn 0.8656 0.1432 0.4798 +vn 0.7725 -0.3294 0.5429 +vn -0.0000 -0.5077 0.8615 +vn -0.7725 -0.3294 0.5429 +vn -0.9959 -0.0741 0.0512 +vn -0.8335 0.2029 -0.5139 +vt 0.000000 0.000000 +vt 0.000000 0.625000 +vt 0.000000 0.500000 +vt 0.000000 0.750000 +vt 0.000000 0.875000 +vt 0.000000 0.375000 +vt 0.000000 0.250000 +vt 0.000000 0.125000 +vt 0.000000 1.000000 +vt 0.333333 1.000000 +vt 0.333333 0.125000 +vt 0.666667 0.875000 +vt 0.333333 0.875000 +vt 0.666667 0.125000 +vt 0.333333 0.000000 +vt 0.666667 1.000000 +vt 1.000000 0.875000 +vt 1.000000 0.000000 +vt 0.666667 0.000000 +vt 1.000000 0.250000 +vt 0.666667 0.250000 +vt 1.000000 0.375000 +vt 0.666667 0.375000 +vt 0.666667 0.500000 +vt 0.666667 0.625000 +vt 1.000000 0.500000 +vt 1.000000 0.750000 +vt 0.666667 0.750000 +vt 0.333333 0.750000 +vt 0.333333 0.625000 +vt 0.333333 0.500000 +vt 0.333333 0.375000 +vt 0.333333 0.250000 +vt 1.000000 1.000000 +vt 1.000000 0.125000 +vt 1.000000 0.625000 +s 1 +usemtl Brass.001 +f 2261/2303/2219 2262/2303/2219 2264/2303/2219 +f 2261/2303/2219 2264/2303/2219 2263/2303/2219 +f 2265/2304/2220 2269/2305/2223 2264/2304/2219 +f 2266/2306/2221 2265/2304/2220 2264/2306/2219 +f 2274/2307/2226 2266/2306/2221 2264/2307/2219 +f 2276/2303/2219 2264/2303/2219 2262/2303/2219 +f 2267/2303/2219 2264/2303/2219 2277/2303/2219 +f 2263/2303/2219 2264/2303/2219 2267/2303/2219 +f 2268/2308/2222 2273/2309/2225 2264/2308/2219 +f 2269/2305/2223 2268/2308/2222 2264/2305/2219 +f 2270/2303/2219 2264/2303/2219 2276/2303/2219 +f 2271/2303/2219 2264/2303/2219 2270/2303/2219 +f 2277/2303/2219 2264/2303/2219 2271/2303/2219 +f 2272/2310/2224 2275/2303/2227 2264/2310/2219 +f 2273/2309/2225 2272/2310/2224 2264/2309/2219 +f 2275/2311/2227 2274/2307/2226 2264/2311/2219 +f 2278/2312/2228 2274/2307/2226 2275/2311/2227 +f 2280/2313/2230 2275/2303/2227 2272/2310/2224 +f 2278/2312/2228 2282/2314/2232 2279/2315/2229 +f 2283/2316/2233 2278/2317/2228 2280/2313/2230 +f 2281/2318/2231 2285/2319/2235 2282/2314/2232 +f 2283/2316/2233 2284/2320/2234 2281/2321/2231 +f 2287/2322/2237 2283/2316/2233 2288/2323/2238 +f 2289/2324/2239 2288/2323/2238 2290/2325/2240 +f 2292/2326/2242 2289/2324/2239 2290/2325/2240 +f 2294/2327/2244 2291/2328/2241 2292/2326/2242 +f 2295/2329/2245 2294/2327/2244 2296/2330/2246 +f 2285/2319/2235 2296/2330/2246 2282/2314/2232 +f 2279/2315/2229 2296/2330/2246 2297/2331/2247 +f 2297/2331/2247 2294/2327/2244 2298/2332/2248 +f 2279/2315/2229 2266/2306/2221 2274/2307/2226 +f 2266/2306/2221 2298/2332/2248 2265/2304/2220 +f 2298/2332/2248 2269/2305/2223 2265/2304/2220 +f 2294/2327/2244 2299/2333/2249 2298/2332/2248 +f 2269/2305/2223 2300/2334/2250 2268/2308/2222 +f 2292/2326/2242 2300/2334/2250 2299/2333/2249 +f 2268/2308/2222 2301/2335/2251 2273/2309/2225 +f 2290/2325/2240 2301/2335/2251 2300/2334/2250 +f 2273/2309/2225 2280/2313/2230 2272/2310/2224 +f 2301/2335/2251 2283/2316/2233 2280/2313/2230 +f 2278/2312/2228 2279/2315/2229 2274/2307/2226 +f 2280/2313/2230 2278/2317/2228 2275/2303/2227 +f 2278/2312/2228 2281/2318/2231 2282/2314/2232 +f 2283/2316/2233 2281/2321/2231 2278/2317/2228 +f 2281/2318/2231 2284/2336/2234 2285/2319/2235 +f 2283/2316/2233 2286/2337/2236 2284/2320/2234 +f 2287/2322/2237 2286/2337/2236 2283/2316/2233 +f 2289/2324/2239 2287/2322/2237 2288/2323/2238 +f 2292/2326/2242 2291/2328/2241 2289/2324/2239 +f 2294/2327/2244 2293/2338/2243 2291/2328/2241 +f 2295/2329/2245 2293/2338/2243 2294/2327/2244 +f 2285/2319/2235 2295/2329/2245 2296/2330/2246 +f 2279/2315/2229 2282/2314/2232 2296/2330/2246 +f 2297/2331/2247 2296/2330/2246 2294/2327/2244 +f 2279/2315/2229 2297/2331/2247 2266/2306/2221 +f 2266/2306/2221 2297/2331/2247 2298/2332/2248 +f 2298/2332/2248 2299/2333/2249 2269/2305/2223 +f 2294/2327/2244 2292/2326/2242 2299/2333/2249 +f 2269/2305/2223 2299/2333/2249 2300/2334/2250 +f 2292/2326/2242 2290/2325/2240 2300/2334/2250 +f 2268/2308/2222 2300/2334/2250 2301/2335/2251 +f 2290/2325/2240 2288/2323/2238 2301/2335/2251 +f 2273/2309/2225 2301/2335/2251 2280/2313/2230 +f 2301/2335/2251 2288/2323/2238 2283/2316/2233 +o Cube.028 +v -0.019413 0.230184 0.148041 +v -0.019413 0.206194 0.117513 +v -0.019413 0.252358 0.130616 +v 0.019413 0.230184 0.148041 +v -0.010758 0.204461 0.157247 +v -0.010758 0.191167 0.140329 +v 0.010758 0.204461 0.157247 +v -0.010758 0.192498 0.166648 +v -0.010127 0.180447 0.164094 +v 0.010758 0.192498 0.166648 +v 0.010127 0.180447 0.164094 +v 0.006504 0.154641 0.115370 +v -0.006504 0.154641 0.115370 +v 0.006504 0.166442 0.106097 +v -0.006504 0.166442 0.106097 +v 0.010758 0.191167 0.140329 +v 0.019413 0.206194 0.117513 +v 0.019413 0.228368 0.100088 +v -0.019413 0.228368 0.100088 +v 0.019413 0.252358 0.130616 +vn -0.9522 0.0520 0.3009 +vn -0.9522 -0.2801 -0.1217 +vn -0.9184 0.3929 0.0471 +vn 0.9522 0.0520 0.3009 +vn -0.8658 -0.0852 0.4931 +vn -0.4493 -0.8622 0.2341 +vn 0.8658 -0.0852 0.4931 +vn -0.9544 0.0503 0.2942 +vn -0.9383 -0.2388 0.2502 +vn 0.9544 0.0503 0.2943 +vn 0.9383 -0.2388 0.2502 +vn 0.9476 -0.3059 0.0916 +vn -0.9476 -0.3059 0.0916 +vn 0.9387 0.2383 -0.2490 +vn -0.9387 0.2383 -0.2490 +vn 0.4493 -0.8622 0.2341 +vn 0.9522 -0.2800 -0.1217 +vn 0.9184 0.0471 -0.3929 +vn -0.9184 0.0471 -0.3929 +vn 0.9184 0.3929 0.0471 +vt 0.375000 0.250000 +vt 0.375000 0.000000 +vt 0.625000 0.250000 +vt 0.625000 0.750000 +vt 0.375000 1.000000 +vt 0.375000 0.750000 +vt 0.000000 0.000000 +vt 0.125000 0.500000 +vt 0.125000 0.750000 +vt 0.125000 0.750000 +vt 0.375000 0.500000 +vt 0.625000 0.500000 +vt 0.875000 0.500000 +vt 0.625000 0.000000 +vt 0.625000 1.000000 +vt 0.875000 0.750000 +s 1 +usemtl Brass.001 +f 2303/2339/2253 2306/2340/2256 2302/2340/2252 +f 2302/2340/2252 2320/2341/2270 2303/2339/2253 +f 2321/2342/2271 2302/2343/2252 2305/2344/2255 +f 2305/2344/2255 2306/2343/2256 2308/2344/2258 +f 2316/2345/2266 2310/2345/2260 2306/2345/2256 +f 2307/2346/2257 2308/2344/2258 2306/2347/2256 +f 2306/2347/2256 2311/2344/2261 2308/2344/2258 +f 2312/2344/2262 2309/2347/2259 2310/2348/2260 +f 2312/2345/2262 2315/2345/2265 2308/2345/2258 +f 2312/2344/2262 2314/2347/2264 2313/2344/2263 +f 2317/2349/2267 2316/2346/2266 2307/2346/2257 +f 2318/2349/2268 2307/2339/2257 2303/2339/2253 +f 2305/2344/2255 2317/2349/2267 2318/2349/2268 +f 2320/2341/2270 2318/2349/2268 2303/2339/2253 +f 2319/2350/2269 2305/2344/2255 2318/2349/2268 +f 2320/2351/2270 2321/2342/2271 2319/2350/2269 +f 2303/2339/2253 2307/2339/2257 2306/2340/2256 +f 2302/2340/2252 2304/2352/2254 2320/2341/2270 +f 2321/2342/2271 2304/2353/2254 2302/2343/2252 +f 2305/2344/2255 2302/2343/2252 2306/2343/2256 +f 2306/2345/2256 2307/2345/2257 2316/2345/2266 +f 2316/2345/2266 2314/2345/2264 2310/2345/2260 +f 2310/2345/2260 2309/2345/2259 2306/2345/2256 +f 2307/2346/2257 2317/2349/2267 2308/2344/2258 +f 2306/2347/2256 2309/2347/2259 2311/2344/2261 +f 2312/2344/2262 2311/2344/2261 2309/2347/2259 +f 2308/2345/2258 2311/2345/2261 2312/2345/2262 +f 2312/2345/2262 2313/2345/2263 2315/2345/2265 +f 2315/2345/2265 2317/2345/2267 2308/2345/2258 +f 2312/2344/2262 2310/2348/2260 2314/2347/2264 +f 2317/2349/2267 2315/2349/2265 2316/2346/2266 +f 2318/2349/2268 2317/2349/2267 2307/2339/2257 +f 2305/2344/2255 2308/2344/2258 2317/2349/2267 +f 2320/2341/2270 2319/2350/2269 2318/2349/2268 +f 2319/2350/2269 2321/2342/2271 2305/2344/2255 +f 2320/2351/2270 2304/2354/2254 2321/2342/2271 diff --git a/assets/miramar_bk.tga b/assets/miramar_bk.tga new file mode 100644 index 0000000..5023835 Binary files /dev/null and b/assets/miramar_bk.tga differ diff --git a/assets/miramar_dn.tga b/assets/miramar_dn.tga new file mode 100644 index 0000000..3e7a5c0 Binary files /dev/null and b/assets/miramar_dn.tga differ diff --git a/assets/miramar_ft.tga b/assets/miramar_ft.tga new file mode 100644 index 0000000..a1f11e2 Binary files /dev/null and b/assets/miramar_ft.tga differ diff --git a/assets/miramar_lf.tga b/assets/miramar_lf.tga new file mode 100644 index 0000000..61ff00d Binary files /dev/null and b/assets/miramar_lf.tga differ diff --git a/assets/miramar_rt.tga b/assets/miramar_rt.tga new file mode 100644 index 0000000..dcc4461 Binary files /dev/null and b/assets/miramar_rt.tga differ diff --git a/assets/miramar_up.tga b/assets/miramar_up.tga new file mode 100644 index 0000000..1695fe6 Binary files /dev/null and b/assets/miramar_up.tga differ diff --git a/assets/parry.wav b/assets/parry.wav new file mode 100644 index 0000000..bfec75e Binary files /dev/null and b/assets/parry.wav differ diff --git a/assets/punchanim.glb b/assets/punchanim.glb new file mode 100644 index 0000000..ff31696 Binary files /dev/null and b/assets/punchanim.glb differ diff --git a/assets/revolvertex.png b/assets/revolvertex.png new file mode 100644 index 0000000..68bf34e Binary files /dev/null and b/assets/revolvertex.png differ diff --git a/assets/rig.glb b/assets/rig.glb new file mode 100644 index 0000000..1278c77 Binary files /dev/null and b/assets/rig.glb differ diff --git a/assets/snowflake.png b/assets/snowflake.png new file mode 100644 index 0000000..16e650a Binary files /dev/null and b/assets/snowflake.png differ diff --git a/assets/test.mtl b/assets/test.mtl new file mode 100644 index 0000000..fbfdf64 --- /dev/null +++ b/assets/test.mtl @@ -0,0 +1,2 @@ +# Blender 4.4.0 MTL File: 'None' +# www.blender.org diff --git a/assets/test.obj b/assets/test.obj new file mode 100644 index 0000000..30d17a0 --- /dev/null +++ b/assets/test.obj @@ -0,0 +1,3298 @@ +# Blender 4.4.0 +# www.blender.org +mtllib test.mtl +o Icosphere +v 0.000000 -1.000000 0.000000 +v 0.723607 -0.447220 0.525725 +v -0.276388 -0.447220 0.850649 +v -0.894426 -0.447216 0.000000 +v -0.276388 -0.447220 -0.850649 +v 0.723607 -0.447220 -0.525725 +v 0.276388 0.447220 0.850649 +v -0.723607 0.447220 0.525725 +v -0.723607 0.447220 -0.525725 +v 0.276388 0.447220 -0.850649 +v 0.894426 0.447216 0.000000 +v 0.000000 1.000000 0.000000 +v -0.257937 -0.550685 0.793860 +v -0.232822 -0.657519 0.716563 +v -0.200688 -0.760403 0.617666 +v -0.162456 -0.850654 0.499995 +v -0.120413 -0.920955 0.370598 +v -0.077607 -0.967950 0.238853 +v -0.036848 -0.992865 0.113408 +v 0.096471 -0.992865 0.070089 +v 0.203181 -0.967950 0.147618 +v 0.315251 -0.920955 0.229040 +v 0.425323 -0.850654 0.309011 +v 0.525420 -0.760403 0.381735 +v 0.609547 -0.657519 0.442856 +v 0.675300 -0.550685 0.490628 +v 0.638452 -0.476987 0.604038 +v 0.531941 -0.502302 0.681712 +v 0.405008 -0.519572 0.752338 +v 0.262869 -0.525738 0.809012 +v 0.114564 -0.519572 0.846711 +v -0.029639 -0.502302 0.864184 +v -0.161465 -0.476988 0.863951 +v 0.771771 -0.476987 -0.420539 +v 0.812729 -0.502301 -0.295238 +v 0.840673 -0.519571 -0.152694 +v 0.850648 -0.525736 0.000000 +v 0.840673 -0.519571 0.152694 +v 0.812729 -0.502301 0.295238 +v 0.771771 -0.476987 0.420539 +v 0.096471 -0.992865 -0.070089 +v 0.203181 -0.967950 -0.147618 +v 0.315251 -0.920955 -0.229040 +v 0.425323 -0.850654 -0.309011 +v 0.525420 -0.760403 -0.381735 +v 0.609547 -0.657519 -0.442856 +v 0.675300 -0.550685 -0.490628 +v -0.834716 -0.550681 0.000000 +v -0.753442 -0.657515 0.000000 +v -0.649456 -0.760399 0.000000 +v -0.525730 -0.850652 0.000000 +v -0.389673 -0.920953 0.000000 +v -0.251147 -0.967949 0.000000 +v -0.119245 -0.992865 0.000000 +v -0.377183 -0.476988 0.793861 +v -0.483971 -0.502302 0.716565 +v -0.590366 -0.519572 0.617668 +v -0.688189 -0.525736 0.499997 +v -0.769872 -0.519570 0.370600 +v -0.831051 -0.502299 0.238853 +v -0.871565 -0.476984 0.113408 +v -0.257937 -0.550685 -0.793860 +v -0.232822 -0.657519 -0.716563 +v -0.200688 -0.760403 -0.617666 +v -0.162456 -0.850654 -0.499995 +v -0.120413 -0.920955 -0.370598 +v -0.077607 -0.967950 -0.238853 +v -0.036848 -0.992865 -0.113408 +v -0.871565 -0.476984 -0.113408 +v -0.831051 -0.502299 -0.238853 +v -0.769872 -0.519570 -0.370600 +v -0.688189 -0.525736 -0.499997 +v -0.590366 -0.519572 -0.617668 +v -0.483971 -0.502302 -0.716565 +v -0.377183 -0.476988 -0.793861 +v -0.161465 -0.476988 -0.863951 +v -0.029639 -0.502302 -0.864184 +v 0.114564 -0.519573 -0.846711 +v 0.262869 -0.525738 -0.809012 +v 0.405008 -0.519572 -0.752338 +v 0.531941 -0.502302 -0.681712 +v 0.638453 -0.476987 -0.604038 +v 0.931188 0.357738 0.070089 +v 0.956626 0.251149 0.147618 +v 0.964711 0.129893 0.229041 +v 0.951058 -0.000000 0.309013 +v 0.915098 -0.129893 0.381737 +v 0.860698 -0.251151 0.442858 +v 0.794547 -0.357741 0.490629 +v 0.794547 -0.357741 -0.490629 +v 0.860698 -0.251151 -0.442858 +v 0.915098 -0.129893 -0.381737 +v 0.951058 0.000000 -0.309013 +v 0.964711 0.129893 -0.229041 +v 0.956626 0.251149 -0.147618 +v 0.931188 0.357738 -0.070089 +v 0.221089 0.357741 0.907271 +v 0.155215 0.251152 0.955422 +v 0.080276 0.129894 0.988273 +v -0.000000 -0.000000 1.000000 +v -0.080276 -0.129894 0.988273 +v -0.155215 -0.251152 0.955422 +v -0.221089 -0.357741 0.907271 +v 0.712150 -0.357741 0.604039 +v 0.687159 -0.251152 0.681715 +v 0.645839 -0.129894 0.752343 +v 0.587786 0.000000 0.809017 +v 0.515946 0.129894 0.846716 +v 0.436007 0.251152 0.864188 +v 0.354409 0.357742 0.863953 +v -0.794547 0.357741 0.490629 +v -0.860698 0.251151 0.442858 +v -0.915098 0.129893 0.381737 +v -0.951058 -0.000000 0.309013 +v -0.964711 -0.129893 0.229041 +v -0.956626 -0.251149 0.147618 +v -0.931188 -0.357738 0.070089 +v -0.354409 -0.357742 0.863953 +v -0.436007 -0.251152 0.864188 +v -0.515946 -0.129894 0.846716 +v -0.587786 0.000000 0.809017 +v -0.645839 0.129894 0.752342 +v -0.687159 0.251152 0.681715 +v -0.712150 0.357741 0.604039 +v -0.712150 0.357741 -0.604039 +v -0.687159 0.251152 -0.681715 +v -0.645839 0.129894 -0.752343 +v -0.587786 -0.000000 -0.809017 +v -0.515946 -0.129894 -0.846716 +v -0.436007 -0.251152 -0.864188 +v -0.354409 -0.357742 -0.863953 +v -0.931188 -0.357738 -0.070089 +v -0.956626 -0.251149 -0.147618 +v -0.964711 -0.129893 -0.229041 +v -0.951058 0.000000 -0.309013 +v -0.915098 0.129893 -0.381737 +v -0.860698 0.251151 -0.442858 +v -0.794547 0.357741 -0.490629 +v 0.354409 0.357742 -0.863953 +v 0.436007 0.251152 -0.864188 +v 0.515946 0.129894 -0.846716 +v 0.587786 -0.000000 -0.809017 +v 0.645839 -0.129894 -0.752342 +v 0.687159 -0.251152 -0.681715 +v 0.712150 -0.357741 -0.604039 +v -0.221089 -0.357741 -0.907271 +v -0.155215 -0.251152 -0.955422 +v -0.080276 -0.129894 -0.988273 +v 0.000000 0.000000 -1.000000 +v 0.080276 0.129894 -0.988273 +v 0.155215 0.251152 -0.955422 +v 0.221089 0.357741 -0.907271 +v 0.871565 0.476984 0.113408 +v 0.831051 0.502299 0.238853 +v 0.769872 0.519570 0.370600 +v 0.688189 0.525736 0.499997 +v 0.590366 0.519572 0.617668 +v 0.483971 0.502302 0.716565 +v 0.377183 0.476988 0.793861 +v 0.161465 0.476988 0.863951 +v 0.029639 0.502302 0.864184 +v -0.114564 0.519573 0.846711 +v -0.262869 0.525738 0.809012 +v -0.405008 0.519572 0.752338 +v -0.531941 0.502302 0.681712 +v -0.638453 0.476987 0.604038 +v -0.771771 0.476987 0.420539 +v -0.812729 0.502301 0.295238 +v -0.840673 0.519571 0.152694 +v -0.850648 0.525736 -0.000000 +v -0.840673 0.519571 -0.152694 +v -0.812729 0.502301 -0.295238 +v -0.771771 0.476987 -0.420539 +v -0.638452 0.476987 -0.604038 +v -0.531941 0.502302 -0.681712 +v -0.405008 0.519572 -0.752338 +v -0.262869 0.525738 -0.809012 +v -0.114564 0.519572 -0.846711 +v 0.029639 0.502302 -0.864184 +v 0.161465 0.476988 -0.863951 +v 0.377183 0.476988 -0.793861 +v 0.483971 0.502302 -0.716565 +v 0.590366 0.519572 -0.617668 +v 0.688189 0.525736 -0.499997 +v 0.769872 0.519570 -0.370600 +v 0.831051 0.502299 -0.238853 +v 0.871565 0.476984 -0.113408 +v 0.036848 0.992865 0.113408 +v 0.077607 0.967950 0.238853 +v 0.120413 0.920955 0.370598 +v 0.162456 0.850654 0.499995 +v 0.200688 0.760403 0.617666 +v 0.232822 0.657519 0.716563 +v 0.257937 0.550685 0.793860 +v 0.834716 0.550681 0.000000 +v 0.753442 0.657515 0.000000 +v 0.649456 0.760399 0.000000 +v 0.525730 0.850652 0.000000 +v 0.389673 0.920953 0.000000 +v 0.251147 0.967949 0.000000 +v 0.119245 0.992865 0.000000 +v -0.096471 0.992865 0.070089 +v -0.203181 0.967950 0.147618 +v -0.315251 0.920955 0.229040 +v -0.425323 0.850654 0.309011 +v -0.525420 0.760403 0.381735 +v -0.609547 0.657519 0.442856 +v -0.675300 0.550685 0.490628 +v -0.096471 0.992865 -0.070089 +v -0.203181 0.967950 -0.147618 +v -0.315251 0.920955 -0.229040 +v -0.425323 0.850654 -0.309011 +v -0.525420 0.760403 -0.381735 +v -0.609547 0.657519 -0.442856 +v -0.675300 0.550685 -0.490628 +v 0.036848 0.992865 -0.113408 +v 0.077607 0.967950 -0.238853 +v 0.120413 0.920955 -0.370598 +v 0.162456 0.850654 -0.499995 +v 0.200688 0.760403 -0.617666 +v 0.232822 0.657519 -0.716563 +v 0.257937 0.550685 -0.793860 +v 0.166198 0.978672 -0.120749 +v 0.307167 0.943208 -0.126518 +v 0.215245 0.943209 -0.253036 +v 0.451375 0.882854 -0.129731 +v 0.361800 0.894429 -0.262863 +v 0.262862 0.882855 -0.389192 +v 0.587783 0.798549 -0.129731 +v 0.506729 0.819912 -0.266403 +v 0.409951 0.819913 -0.399604 +v 0.305014 0.798552 -0.518924 +v 0.706258 0.696558 -0.126519 +v 0.638194 0.723610 -0.262864 +v 0.550008 0.733353 -0.399605 +v 0.447209 0.723612 -0.525728 +v 0.338569 0.696561 -0.632593 +v 0.801022 0.586331 -0.120750 +v 0.747366 0.614342 -0.253038 +v 0.672087 0.629942 -0.389194 +v 0.577830 0.629943 -0.518926 +v 0.471599 0.614344 -0.632594 +v 0.362366 0.586334 -0.724502 +v -0.063483 0.978672 -0.195376 +v -0.025408 0.943209 -0.331227 +v -0.174138 0.943209 -0.282901 +v 0.016098 0.882855 -0.469369 +v -0.138197 0.894430 -0.425319 +v -0.288916 0.882855 -0.370262 +v 0.058250 0.798552 -0.599101 +v -0.096779 0.819914 -0.564248 +v -0.253366 0.819914 -0.513369 +v -0.399272 0.798552 -0.450440 +v 0.097915 0.696561 -0.710785 +v -0.052790 0.723612 -0.688185 +v -0.210088 0.733355 -0.646571 +v -0.361804 0.723612 -0.587778 +v -0.497009 0.696561 -0.517479 +v 0.132684 0.586334 -0.799129 +v -0.009708 0.614345 -0.788978 +v -0.162463 0.629944 -0.759458 +v -0.314971 0.629944 -0.709904 +v -0.455902 0.614344 -0.643998 +v -0.577066 0.586334 -0.568513 +v -0.205432 0.978671 0.000000 +v -0.322868 0.943208 -0.078192 +v -0.322868 0.943208 0.078192 +v -0.441423 0.882855 -0.160354 +v -0.447210 0.894429 0.000000 +v -0.441423 0.882855 0.160354 +v -0.551779 0.798551 -0.240532 +v -0.566539 0.819912 -0.082322 +v -0.566539 0.819912 0.082322 +v -0.551779 0.798551 0.240532 +v -0.645740 0.696561 -0.312768 +v -0.670817 0.723611 -0.162457 +v -0.679848 0.733353 0.000000 +v -0.670817 0.723611 0.162457 +v -0.645740 0.696560 0.312768 +v -0.719015 0.586334 -0.373135 +v -0.753363 0.614343 -0.234576 +v -0.772492 0.629942 -0.080177 +v -0.772492 0.629942 0.080177 +v -0.753363 0.614343 0.234576 +v -0.719015 0.586334 0.373135 +v -0.063483 0.978672 0.195376 +v -0.174138 0.943209 0.282901 +v -0.025408 0.943209 0.331227 +v -0.288916 0.882855 0.370262 +v -0.138197 0.894430 0.425319 +v 0.016098 0.882855 0.469369 +v -0.399272 0.798552 0.450440 +v -0.253366 0.819914 0.513369 +v -0.096779 0.819914 0.564248 +v 0.058250 0.798552 0.599101 +v -0.497009 0.696561 0.517479 +v -0.361804 0.723612 0.587778 +v -0.210088 0.733355 0.646571 +v -0.052790 0.723612 0.688185 +v 0.097915 0.696561 0.710785 +v -0.577066 0.586334 0.568513 +v -0.455902 0.614345 0.643998 +v -0.314971 0.629944 0.709904 +v -0.162463 0.629944 0.759458 +v -0.009708 0.614345 0.788978 +v 0.132684 0.586335 0.799129 +v 0.166198 0.978672 0.120749 +v 0.215245 0.943209 0.253036 +v 0.307167 0.943208 0.126518 +v 0.262862 0.882855 0.389192 +v 0.361800 0.894429 0.262863 +v 0.451375 0.882854 0.129731 +v 0.305014 0.798552 0.518924 +v 0.409951 0.819913 0.399604 +v 0.506729 0.819912 0.266403 +v 0.587783 0.798549 0.129731 +v 0.338569 0.696561 0.632593 +v 0.447209 0.723612 0.525728 +v 0.550008 0.733353 0.399605 +v 0.638194 0.723610 0.262864 +v 0.706258 0.696558 0.126519 +v 0.362366 0.586334 0.724502 +v 0.471599 0.614344 0.632594 +v 0.577830 0.629943 0.518926 +v 0.672087 0.629942 0.389194 +v 0.747366 0.614342 0.253038 +v 0.801022 0.586331 0.120750 +v 0.903740 0.380897 -0.195376 +v 0.921508 0.266063 -0.282902 +v 0.854992 0.399094 -0.331229 +v 0.918856 0.136410 -0.370264 +v 0.861804 0.276396 -0.425322 +v 0.782446 0.409229 -0.469371 +v 0.892805 -0.000000 -0.450443 +v 0.846660 0.140059 -0.513372 +v 0.776630 0.280118 -0.564251 +v 0.688190 0.409230 -0.599104 +v 0.845290 -0.133032 -0.517481 +v 0.809019 0.000000 -0.587782 +v 0.749882 0.140059 -0.646576 +v 0.670821 0.276397 -0.688189 +v 0.579226 0.399096 -0.710788 +v 0.782501 -0.253933 -0.568515 +v 0.753368 -0.133032 -0.644002 +v 0.704293 0.000000 -0.709909 +v 0.636088 0.136411 -0.759463 +v 0.553820 0.266065 -0.788982 +v 0.465085 0.380900 -0.799132 +v 0.093451 0.380900 -0.919882 +v 0.015700 0.266064 -0.963827 +v -0.050816 0.399096 -0.915500 +v -0.068205 0.136410 -0.988302 +v -0.138198 0.276397 -0.951055 +v -0.204615 0.409230 -0.889193 +v -0.152509 -0.000000 -0.988302 +v -0.226618 0.140059 -0.963861 +v -0.296648 0.280118 -0.912981 +v -0.357124 0.409230 -0.839639 +v -0.230948 -0.133033 -0.963829 +v -0.309016 -0.000000 -0.951057 +v -0.383207 0.140059 -0.912982 +v -0.447215 0.276397 -0.850649 +v -0.497012 0.399096 -0.770520 +v -0.298885 -0.253934 -0.919883 +v -0.379680 -0.133033 -0.915503 +v -0.457527 -0.000000 -0.889196 +v -0.525732 0.136410 -0.839642 +v -0.579229 0.266065 -0.770522 +v -0.616302 0.380900 -0.689266 +v -0.845982 0.380899 -0.373136 +v -0.911804 0.266063 -0.312769 +v -0.886396 0.399095 -0.234577 +v -0.961008 0.136410 -0.240533 +v -0.947213 0.276396 -0.162458 +v -0.908902 0.409229 -0.080178 +v -0.987059 0.000000 -0.160355 +v -0.986715 0.140059 -0.082322 +v -0.959966 0.280117 0.000000 +v -0.908902 0.409229 0.080178 +v -0.988023 -0.133031 -0.078192 +v -1.000000 0.000001 0.000000 +v -0.986715 0.140059 0.082323 +v -0.947213 0.276397 0.162458 +v -0.886395 0.399095 0.234577 +v -0.967222 -0.253931 0.000000 +v -0.988023 -0.133030 0.078193 +v -0.987059 0.000001 0.160356 +v -0.961008 0.136411 0.240534 +v -0.911803 0.266065 0.312769 +v -0.845982 0.380900 0.373136 +v -0.616302 0.380900 0.689266 +v -0.579229 0.266064 0.770521 +v -0.497012 0.399096 0.770520 +v -0.525732 0.136410 0.839641 +v -0.447216 0.276397 0.850649 +v -0.357124 0.409230 0.839639 +v -0.457527 -0.000001 0.889196 +v -0.383208 0.140059 0.912982 +v -0.296649 0.280118 0.912981 +v -0.204616 0.409230 0.889193 +v -0.379681 -0.133033 0.915502 +v -0.309017 -0.000001 0.951056 +v -0.226619 0.140059 0.963861 +v -0.138199 0.276397 0.951055 +v -0.050817 0.399096 0.915500 +v -0.298885 -0.253934 0.919883 +v -0.230948 -0.133033 0.963828 +v -0.152509 -0.000000 0.988302 +v -0.068206 0.136410 0.988302 +v 0.015699 0.266064 0.963827 +v 0.093451 0.380900 0.919882 +v 0.465085 0.380900 0.799132 +v 0.553820 0.266064 0.788983 +v 0.579226 0.399096 0.710788 +v 0.636088 0.136410 0.759463 +v 0.670820 0.276396 0.688190 +v 0.688190 0.409229 0.599104 +v 0.704293 -0.000001 0.709909 +v 0.749882 0.140058 0.646576 +v 0.776630 0.280116 0.564252 +v 0.782446 0.409228 0.469372 +v 0.753368 -0.133034 0.644002 +v 0.809019 -0.000002 0.587783 +v 0.846659 0.140057 0.513373 +v 0.861804 0.276394 0.425323 +v 0.854992 0.399093 0.331230 +v 0.782501 -0.253934 0.568515 +v 0.845289 -0.133034 0.517482 +v 0.892805 -0.000002 0.450444 +v 0.918856 0.136407 0.370266 +v 0.921508 0.266061 0.282904 +v 0.903740 0.380896 0.195377 +v 0.298886 0.253934 -0.919883 +v 0.379681 0.133033 -0.915502 +v 0.230948 0.133033 -0.963828 +v 0.457527 -0.000000 -0.889196 +v 0.309017 -0.000000 -0.951056 +v 0.152509 0.000000 -0.988302 +v 0.525732 -0.136411 -0.839641 +v 0.383207 -0.140060 -0.912982 +v 0.226619 -0.140060 -0.963861 +v 0.068205 -0.136410 -0.988302 +v 0.579229 -0.266065 -0.770521 +v 0.447216 -0.276398 -0.850648 +v 0.296648 -0.280119 -0.912980 +v 0.138199 -0.276398 -0.951055 +v -0.015699 -0.266065 -0.963827 +v 0.616302 -0.380900 -0.689265 +v 0.497012 -0.399097 -0.770520 +v 0.357124 -0.409231 -0.839639 +v 0.204615 -0.409231 -0.889192 +v 0.050817 -0.399097 -0.915500 +v -0.093451 -0.380900 -0.919881 +v -0.782501 0.253934 -0.568515 +v -0.753368 0.133032 -0.644002 +v -0.845290 0.133032 -0.517482 +v -0.704293 -0.000000 -0.709910 +v -0.809018 -0.000000 -0.587783 +v -0.892805 0.000000 -0.450444 +v -0.636087 -0.136411 -0.759464 +v -0.749881 -0.140059 -0.646577 +v -0.846659 -0.140059 -0.513374 +v -0.918856 -0.136410 -0.370265 +v -0.553819 -0.266065 -0.788983 +v -0.670819 -0.276397 -0.688191 +v -0.776628 -0.280118 -0.564253 +v -0.861803 -0.276396 -0.425324 +v -0.921507 -0.266063 -0.282904 +v -0.465084 -0.380900 -0.799132 +v -0.579224 -0.399096 -0.710789 +v -0.688189 -0.409230 -0.599106 +v -0.782445 -0.409229 -0.469374 +v -0.854991 -0.399094 -0.331231 +v -0.903739 -0.380897 -0.195378 +v -0.782501 0.253934 0.568515 +v -0.845290 0.133032 0.517482 +v -0.753368 0.133032 0.644002 +v -0.892805 -0.000000 0.450444 +v -0.809018 0.000000 0.587783 +v -0.704293 0.000000 0.709910 +v -0.918856 -0.136410 0.370265 +v -0.846659 -0.140059 0.513374 +v -0.749881 -0.140059 0.646577 +v -0.636087 -0.136411 0.759464 +v -0.921508 -0.266063 0.282904 +v -0.861803 -0.276396 0.425324 +v -0.776629 -0.280118 0.564253 +v -0.670819 -0.276397 0.688191 +v -0.553819 -0.266065 0.788983 +v -0.903739 -0.380897 0.195378 +v -0.854991 -0.399094 0.331231 +v -0.782445 -0.409229 0.469374 +v -0.688189 -0.409230 0.599106 +v -0.579224 -0.399096 0.710789 +v -0.465084 -0.380900 0.799132 +v 0.298886 0.253934 0.919883 +v 0.230948 0.133032 0.963828 +v 0.379681 0.133033 0.915502 +v 0.152509 -0.000000 0.988302 +v 0.309017 0.000000 0.951056 +v 0.457527 0.000000 0.889196 +v 0.068206 -0.136410 0.988302 +v 0.226619 -0.140060 0.963861 +v 0.383207 -0.140060 0.912982 +v 0.525732 -0.136411 0.839641 +v -0.015699 -0.266065 0.963827 +v 0.138199 -0.276397 0.951055 +v 0.296648 -0.280119 0.912980 +v 0.447216 -0.276398 0.850648 +v 0.579229 -0.266065 0.770521 +v -0.093451 -0.380900 0.919882 +v 0.050817 -0.399097 0.915500 +v 0.204615 -0.409230 0.889192 +v 0.357124 -0.409230 0.839639 +v 0.497012 -0.399097 0.770520 +v 0.616302 -0.380900 0.689266 +v 0.967222 0.253931 0.000000 +v 0.988023 0.133031 0.078192 +v 0.988023 0.133031 -0.078192 +v 0.987059 -0.000000 0.160355 +v 1.000000 0.000000 0.000000 +v 0.987059 0.000000 -0.160355 +v 0.961008 -0.136410 0.240533 +v 0.986715 -0.140059 0.082322 +v 0.986715 -0.140059 -0.082322 +v 0.961008 -0.136410 -0.240533 +v 0.911804 -0.266064 0.312769 +v 0.947213 -0.276396 0.162458 +v 0.959966 -0.280117 0.000000 +v 0.947213 -0.276396 -0.162458 +v 0.911804 -0.266064 -0.312769 +v 0.845982 -0.380899 0.373136 +v 0.886396 -0.399095 0.234576 +v 0.908902 -0.409229 0.080178 +v 0.908902 -0.409229 -0.080178 +v 0.886396 -0.399095 -0.234576 +v 0.845982 -0.380899 -0.373136 +v 0.577066 -0.586334 -0.568513 +v 0.497009 -0.696561 -0.517479 +v 0.455902 -0.614344 -0.643999 +v 0.399272 -0.798552 -0.450441 +v 0.361804 -0.723612 -0.587779 +v 0.314971 -0.629943 -0.709905 +v 0.288916 -0.882855 -0.370263 +v 0.253366 -0.819913 -0.513370 +v 0.210087 -0.733354 -0.646572 +v 0.162463 -0.629943 -0.759459 +v 0.174138 -0.943209 -0.282902 +v 0.138197 -0.894429 -0.425321 +v 0.096779 -0.819912 -0.564250 +v 0.052789 -0.723611 -0.688186 +v 0.009708 -0.614344 -0.788979 +v 0.063482 -0.978671 -0.195377 +v 0.025407 -0.943208 -0.331229 +v -0.016099 -0.882854 -0.469371 +v -0.058250 -0.798550 -0.599103 +v -0.097915 -0.696560 -0.710786 +v -0.132684 -0.586334 -0.799129 +v -0.362367 -0.586334 -0.724501 +v -0.338569 -0.696561 -0.632593 +v -0.471601 -0.614344 -0.632593 +v -0.305014 -0.798552 -0.518923 +v -0.447211 -0.723612 -0.525727 +v -0.577832 -0.629943 -0.518924 +v -0.262862 -0.882855 -0.389192 +v -0.409952 -0.819913 -0.399603 +v -0.550010 -0.733353 -0.399603 +v -0.672088 -0.629942 -0.389192 +v -0.215245 -0.943209 -0.253036 +v -0.361801 -0.894429 -0.262863 +v -0.506730 -0.819912 -0.266402 +v -0.638195 -0.723609 -0.262863 +v -0.747367 -0.614341 -0.253036 +v -0.166198 -0.978671 -0.120749 +v -0.307168 -0.943208 -0.126518 +v -0.451376 -0.882853 -0.129730 +v -0.587784 -0.798549 -0.129730 +v -0.706258 -0.696557 -0.126518 +v -0.801022 -0.586330 -0.120749 +v -0.801022 -0.586330 0.120750 +v -0.706258 -0.696558 0.126518 +v -0.747367 -0.614341 0.253037 +v -0.587784 -0.798549 0.129731 +v -0.638195 -0.723609 0.262864 +v -0.672088 -0.629941 0.389193 +v -0.451375 -0.882853 0.129731 +v -0.506730 -0.819911 0.266403 +v -0.550009 -0.733352 0.399605 +v -0.577832 -0.629942 0.518925 +v -0.307168 -0.943208 0.126519 +v -0.361801 -0.894428 0.262864 +v -0.409952 -0.819912 0.399605 +v -0.447211 -0.723610 0.525729 +v -0.471601 -0.614343 0.632594 +v -0.166198 -0.978671 0.120750 +v -0.215246 -0.943208 0.253038 +v -0.262863 -0.882854 0.389194 +v -0.305015 -0.798550 0.518925 +v -0.338569 -0.696560 0.632594 +v -0.362367 -0.586333 0.724502 +v 0.719015 -0.586334 -0.373135 +v 0.753363 -0.614343 -0.234576 +v 0.645740 -0.696560 -0.312768 +v 0.772493 -0.629942 -0.080177 +v 0.670817 -0.723611 -0.162457 +v 0.551780 -0.798551 -0.240532 +v 0.772493 -0.629942 0.080178 +v 0.679849 -0.733353 0.000000 +v 0.566540 -0.819912 -0.082322 +v 0.441423 -0.882854 -0.160354 +v 0.753364 -0.614343 0.234576 +v 0.670818 -0.723610 0.162458 +v 0.566541 -0.819911 0.082323 +v 0.447211 -0.894428 0.000001 +v 0.322869 -0.943208 -0.078191 +v 0.719016 -0.586333 0.373136 +v 0.645741 -0.696559 0.312769 +v 0.551781 -0.798550 0.240533 +v 0.441424 -0.882854 0.160356 +v 0.322870 -0.943208 0.078193 +v 0.205432 -0.978671 0.000001 +v -0.132684 -0.586334 0.799129 +v -0.097915 -0.696561 0.710785 +v 0.009709 -0.614344 0.788978 +v -0.058249 -0.798552 0.599101 +v 0.052790 -0.723612 0.688185 +v 0.162463 -0.629944 0.759458 +v -0.016097 -0.882855 0.469370 +v 0.096780 -0.819913 0.564249 +v 0.210089 -0.733354 0.646572 +v 0.314971 -0.629943 0.709905 +v 0.025409 -0.943209 0.331228 +v 0.138199 -0.894429 0.425321 +v 0.253368 -0.819912 0.513370 +v 0.361805 -0.723611 0.587779 +v 0.455903 -0.614344 0.643999 +v 0.063484 -0.978671 0.195377 +v 0.174140 -0.943208 0.282902 +v 0.288918 -0.882854 0.370264 +v 0.399274 -0.798550 0.450441 +v 0.497011 -0.696560 0.517480 +v 0.577067 -0.586333 0.568513 +vn -0.0000 -1.0000 -0.0000 +vn 0.7236 -0.4472 0.5257 +vn -0.2764 -0.4472 0.8506 +vn -0.8944 -0.4472 -0.0000 +vn -0.2764 -0.4472 -0.8506 +vn 0.7236 -0.4472 -0.5257 +vn 0.2764 0.4472 0.8506 +vn -0.7236 0.4472 0.5257 +vn -0.7236 0.4472 -0.5257 +vn 0.2764 0.4472 -0.8506 +vn 0.8944 0.4472 -0.0000 +vn -0.0000 1.0000 -0.0000 +vn -0.2575 -0.5530 0.7924 +vn -0.2324 -0.6591 0.7152 +vn -0.2004 -0.7612 0.6168 +vn -0.1625 -0.8507 0.5000 +vn -0.1207 -0.9205 0.3716 +vn -0.0782 -0.9674 0.2408 +vn -0.0377 -0.9925 0.1161 +vn 0.0987 -0.9925 0.0717 +vn 0.2048 -0.9674 0.1488 +vn 0.3161 -0.9205 0.2297 +vn 0.4253 -0.8507 0.3090 +vn 0.5247 -0.7612 0.3812 +vn 0.6084 -0.6591 0.4420 +vn 0.6740 -0.5530 0.4897 +vn 0.6363 -0.4776 0.6058 +vn 0.5302 -0.5026 0.6828 +vn 0.4040 -0.5197 0.7528 +vn 0.2629 -0.5257 0.8090 +vn 0.1157 -0.5197 0.8465 +vn -0.0275 -0.5026 0.8641 +vn -0.1587 -0.4776 0.8641 +vn 0.7728 -0.4776 -0.4180 +vn 0.8133 -0.5026 -0.2932 +vn 0.8408 -0.5197 -0.1516 +vn 0.8506 -0.5257 -0.0000 +vn 0.8408 -0.5197 0.1516 +vn 0.8133 -0.5026 0.2932 +vn 0.7728 -0.4776 0.4180 +vn 0.0987 -0.9925 -0.0717 +vn 0.2048 -0.9674 -0.1488 +vn 0.3161 -0.9205 -0.2297 +vn 0.4253 -0.8507 -0.3090 +vn 0.5247 -0.7612 -0.3812 +vn 0.6084 -0.6591 -0.4420 +vn 0.6740 -0.5530 -0.4897 +vn -0.8332 -0.5530 -0.0000 +vn -0.7520 -0.6591 -0.0000 +vn -0.6486 -0.7612 -0.0000 +vn -0.5257 -0.8507 -0.0000 +vn -0.3907 -0.9205 -0.0000 +vn -0.2532 -0.9674 -0.0000 +vn -0.1220 -0.9925 -0.0000 +vn -0.3795 -0.4776 0.7924 +vn -0.4856 -0.5026 0.7152 +vn -0.5912 -0.5197 0.6168 +vn -0.6882 -0.5257 0.5000 +vn -0.7693 -0.5197 0.3716 +vn -0.8303 -0.5026 0.2408 +vn -0.8709 -0.4776 0.1161 +vn -0.2575 -0.5530 -0.7924 +vn -0.2324 -0.6591 -0.7152 +vn -0.2004 -0.7612 -0.6168 +vn -0.1625 -0.8507 -0.5000 +vn -0.1207 -0.9205 -0.3716 +vn -0.0782 -0.9674 -0.2408 +vn -0.0377 -0.9925 -0.1161 +vn -0.8709 -0.4776 -0.1161 +vn -0.8303 -0.5026 -0.2408 +vn -0.7693 -0.5197 -0.3716 +vn -0.6882 -0.5257 -0.5000 +vn -0.5912 -0.5197 -0.6168 +vn -0.4856 -0.5026 -0.7152 +vn -0.3795 -0.4776 -0.7924 +vn -0.1587 -0.4776 -0.8641 +vn -0.0275 -0.5026 -0.8641 +vn 0.1157 -0.5197 -0.8465 +vn 0.2629 -0.5257 -0.8090 +vn 0.4040 -0.5197 -0.7528 +vn 0.5302 -0.5026 -0.6828 +vn 0.6363 -0.4776 -0.6058 +vn 0.9319 0.3556 0.0717 +vn 0.9569 0.2494 0.1488 +vn 0.9647 0.1289 0.2297 +vn 0.9511 -0.0000 0.3090 +vn 0.9155 -0.1289 0.3812 +vn 0.8616 -0.2494 0.4420 +vn 0.7961 -0.3556 0.4897 +vn 0.7961 -0.3556 -0.4897 +vn 0.8616 -0.2494 -0.4420 +vn 0.9155 -0.1289 -0.3812 +vn 0.9511 -0.0000 -0.3090 +vn 0.9647 0.1289 -0.2297 +vn 0.9569 0.2494 -0.1488 +vn 0.9319 0.3556 -0.0717 +vn 0.2198 0.3556 0.9084 +vn 0.1541 0.2494 0.9560 +vn 0.0797 0.1289 0.9884 +vn -0.0000 -0.0000 1.0000 +vn -0.0797 -0.1289 0.9884 +vn -0.1541 -0.2494 0.9560 +vn -0.2198 -0.3556 0.9084 +vn 0.7118 -0.3556 0.6058 +vn 0.6867 -0.2494 0.6829 +vn 0.6455 -0.1289 0.7528 +vn 0.5878 -0.0000 0.8090 +vn 0.5165 0.1289 0.8465 +vn 0.4372 0.2494 0.8641 +vn 0.3562 0.3556 0.8641 +vn -0.7961 0.3556 0.4897 +vn -0.8616 0.2494 0.4420 +vn -0.9155 0.1289 0.3812 +vn -0.9511 -0.0000 0.3090 +vn -0.9647 -0.1289 0.2297 +vn -0.9569 -0.2494 0.1488 +vn -0.9319 -0.3556 0.0717 +vn -0.3562 -0.3556 0.8641 +vn -0.4372 -0.2494 0.8641 +vn -0.5165 -0.1289 0.8465 +vn -0.5878 -0.0000 0.8090 +vn -0.6455 0.1289 0.7528 +vn -0.6867 0.2494 0.6829 +vn -0.7118 0.3556 0.6058 +vn -0.7118 0.3556 -0.6058 +vn -0.6867 0.2494 -0.6829 +vn -0.6455 0.1289 -0.7528 +vn -0.5878 -0.0000 -0.8090 +vn -0.5165 -0.1289 -0.8465 +vn -0.4372 -0.2494 -0.8641 +vn -0.3562 -0.3556 -0.8641 +vn -0.9319 -0.3556 -0.0717 +vn -0.9569 -0.2494 -0.1488 +vn -0.9647 -0.1289 -0.2297 +vn -0.9511 -0.0000 -0.3090 +vn -0.9155 0.1289 -0.3812 +vn -0.8616 0.2494 -0.4420 +vn -0.7961 0.3556 -0.4897 +vn 0.3562 0.3556 -0.8641 +vn 0.4372 0.2494 -0.8641 +vn 0.5165 0.1289 -0.8465 +vn 0.5878 -0.0000 -0.8090 +vn 0.6455 -0.1289 -0.7528 +vn 0.6867 -0.2494 -0.6829 +vn 0.7118 -0.3556 -0.6058 +vn -0.2198 -0.3556 -0.9084 +vn -0.1541 -0.2494 -0.9560 +vn -0.0797 -0.1289 -0.9884 +vn -0.0000 -0.0000 -1.0000 +vn 0.0797 0.1289 -0.9884 +vn 0.1541 0.2494 -0.9560 +vn 0.2198 0.3556 -0.9084 +vn 0.8709 0.4776 0.1161 +vn 0.8303 0.5026 0.2408 +vn 0.7693 0.5197 0.3716 +vn 0.6882 0.5257 0.5000 +vn 0.5912 0.5197 0.6168 +vn 0.4856 0.5026 0.7152 +vn 0.3795 0.4776 0.7924 +vn 0.1587 0.4776 0.8641 +vn 0.0275 0.5026 0.8641 +vn -0.1157 0.5197 0.8465 +vn -0.2629 0.5257 0.8090 +vn -0.4040 0.5197 0.7528 +vn -0.5302 0.5026 0.6828 +vn -0.6363 0.4776 0.6058 +vn -0.7728 0.4776 0.4180 +vn -0.8133 0.5026 0.2932 +vn -0.8408 0.5197 0.1515 +vn -0.8506 0.5257 -0.0000 +vn -0.8408 0.5197 -0.1516 +vn -0.8133 0.5026 -0.2932 +vn -0.7728 0.4776 -0.4180 +vn -0.6363 0.4776 -0.6058 +vn -0.5302 0.5026 -0.6828 +vn -0.4040 0.5197 -0.7528 +vn -0.2629 0.5257 -0.8090 +vn -0.1157 0.5197 -0.8465 +vn 0.0275 0.5026 -0.8641 +vn 0.1587 0.4776 -0.8641 +vn 0.3795 0.4776 -0.7924 +vn 0.4856 0.5026 -0.7152 +vn 0.5912 0.5197 -0.6168 +vn 0.6882 0.5257 -0.5000 +vn 0.7693 0.5197 -0.3716 +vn 0.8303 0.5026 -0.2408 +vn 0.8709 0.4776 -0.1161 +vn 0.0377 0.9925 0.1161 +vn 0.0782 0.9674 0.2408 +vn 0.1207 0.9205 0.3716 +vn 0.1625 0.8507 0.5000 +vn 0.2004 0.7612 0.6168 +vn 0.2324 0.6591 0.7152 +vn 0.2575 0.5530 0.7924 +vn 0.8332 0.5530 -0.0000 +vn 0.7520 0.6591 -0.0000 +vn 0.6486 0.7612 -0.0000 +vn 0.5257 0.8507 -0.0000 +vn 0.3907 0.9205 -0.0000 +vn 0.2532 0.9674 -0.0000 +vn 0.1220 0.9925 -0.0000 +vn -0.0987 0.9925 0.0717 +vn -0.2048 0.9674 0.1488 +vn -0.3161 0.9205 0.2297 +vn -0.4253 0.8507 0.3090 +vn -0.5247 0.7612 0.3812 +vn -0.6084 0.6591 0.4420 +vn -0.6740 0.5530 0.4897 +vn -0.0987 0.9925 -0.0717 +vn -0.2048 0.9674 -0.1488 +vn -0.3161 0.9205 -0.2297 +vn -0.4253 0.8507 -0.3090 +vn -0.5247 0.7612 -0.3812 +vn -0.6084 0.6591 -0.4420 +vn -0.6740 0.5530 -0.4897 +vn 0.0377 0.9925 -0.1161 +vn 0.0782 0.9674 -0.2408 +vn 0.1207 0.9205 -0.3716 +vn 0.1625 0.8507 -0.5000 +vn 0.2004 0.7612 -0.6168 +vn 0.2324 0.6591 -0.7152 +vn 0.2575 0.5530 -0.7924 +vn 0.1698 0.9777 -0.1233 +vn 0.3095 0.9421 -0.1293 +vn 0.2186 0.9421 -0.2544 +vn 0.4520 0.8821 -0.1326 +vn 0.3635 0.8934 -0.2641 +vn 0.2658 0.8821 -0.3889 +vn 0.5868 0.7988 -0.1326 +vn 0.5066 0.8196 -0.2676 +vn 0.4110 0.8196 -0.3991 +vn 0.3074 0.7988 -0.5171 +vn 0.7042 0.6981 -0.1293 +vn 0.6365 0.7247 -0.2641 +vn 0.5493 0.7342 -0.3991 +vn 0.4479 0.7247 -0.5237 +vn 0.3406 0.6981 -0.6298 +vn 0.7986 0.5891 -0.1233 +vn 0.7449 0.6168 -0.2544 +vn 0.6701 0.6322 -0.3889 +vn 0.5770 0.6322 -0.5171 +vn 0.4721 0.6168 -0.6298 +vn 0.3641 0.5891 -0.7214 +vn -0.0648 0.9777 -0.1996 +vn -0.0273 0.9421 -0.3343 +vn -0.1744 0.9421 -0.2865 +vn 0.0136 0.8821 -0.4709 +vn -0.1389 0.8934 -0.4274 +vn -0.2878 0.8821 -0.3730 +vn 0.0552 0.7988 -0.5991 +vn -0.0980 0.8196 -0.5645 +vn -0.2525 0.8196 -0.5142 +vn -0.3968 0.7988 -0.4522 +vn 0.0947 0.6981 -0.7097 +vn -0.0545 0.7247 -0.6869 +vn -0.2098 0.7342 -0.6457 +vn -0.3597 0.7247 -0.5878 +vn -0.4937 0.6981 -0.5185 +vn 0.1295 0.5891 -0.7976 +vn -0.0118 0.6168 -0.7870 +vn -0.1628 0.6322 -0.7575 +vn -0.3135 0.6322 -0.7085 +vn -0.4531 0.6168 -0.6436 +vn -0.5736 0.5891 -0.5692 +vn -0.2098 0.9777 -0.0000 +vn -0.3264 0.9421 -0.0773 +vn -0.3264 0.9421 0.0773 +vn -0.4436 0.8821 -0.1584 +vn -0.4493 0.8934 -0.0000 +vn -0.4436 0.8821 0.1584 +vn -0.5527 0.7988 -0.2376 +vn -0.5671 0.8196 -0.0812 +vn -0.5671 0.8196 0.0812 +vn -0.5527 0.7988 0.2377 +vn -0.6457 0.6981 -0.3093 +vn -0.6702 0.7247 -0.1604 +vn -0.6789 0.7342 -0.0000 +vn -0.6702 0.7247 0.1604 +vn -0.6457 0.6981 0.3093 +vn -0.7186 0.5891 -0.3696 +vn -0.7521 0.6168 -0.2320 +vn -0.7707 0.6322 -0.0792 +vn -0.7707 0.6322 0.0792 +vn -0.7521 0.6168 0.2320 +vn -0.7186 0.5891 0.3696 +vn -0.0648 0.9777 0.1996 +vn -0.1744 0.9421 0.2865 +vn -0.0273 0.9421 0.3343 +vn -0.2878 0.8821 0.3730 +vn -0.1389 0.8934 0.4274 +vn 0.0136 0.8821 0.4709 +vn -0.3968 0.7988 0.4522 +vn -0.2525 0.8196 0.5142 +vn -0.0980 0.8196 0.5645 +vn 0.0552 0.7988 0.5991 +vn -0.4937 0.6981 0.5185 +vn -0.3597 0.7247 0.5878 +vn -0.2098 0.7342 0.6457 +vn -0.0545 0.7247 0.6869 +vn 0.0947 0.6981 0.7097 +vn -0.5736 0.5891 0.5692 +vn -0.4531 0.6168 0.6436 +vn -0.3135 0.6322 0.7085 +vn -0.1628 0.6322 0.7575 +vn -0.0118 0.6168 0.7870 +vn 0.1295 0.5891 0.7976 +vn 0.1698 0.9777 0.1233 +vn 0.2186 0.9421 0.2544 +vn 0.3095 0.9421 0.1293 +vn 0.2658 0.8821 0.3889 +vn 0.3635 0.8934 0.2641 +vn 0.4520 0.8821 0.1326 +vn 0.3074 0.7988 0.5171 +vn 0.4110 0.8196 0.3991 +vn 0.5066 0.8196 0.2676 +vn 0.5868 0.7988 0.1326 +vn 0.3406 0.6981 0.6298 +vn 0.4479 0.7247 0.5237 +vn 0.5493 0.7342 0.3991 +vn 0.6365 0.7247 0.2641 +vn 0.7042 0.6981 0.1293 +vn 0.3641 0.5891 0.7214 +vn 0.4721 0.6168 0.6298 +vn 0.5770 0.6322 0.5171 +vn 0.6701 0.6322 0.3889 +vn 0.7449 0.6168 0.2544 +vn 0.7986 0.5891 0.1233 +vn 0.9035 0.3793 -0.1996 +vn 0.9206 0.2653 -0.2865 +vn 0.8548 0.3969 -0.3343 +vn 0.9177 0.1371 -0.3730 +vn 0.8611 0.2753 -0.4274 +vn 0.7829 0.4066 -0.4709 +vn 0.8919 0.0023 -0.4522 +vn 0.8460 0.1407 -0.5142 +vn 0.7769 0.2789 -0.5645 +vn 0.6898 0.4066 -0.5991 +vn 0.8452 -0.1294 -0.5185 +vn 0.8090 0.0024 -0.5878 +vn 0.7505 0.1407 -0.6457 +vn 0.6725 0.2753 -0.6869 +vn 0.5821 0.3969 -0.7097 +vn 0.7834 -0.2496 -0.5692 +vn 0.7543 -0.1294 -0.6436 +vn 0.7057 0.0023 -0.7085 +vn 0.6383 0.1371 -0.7575 +vn 0.5570 0.2653 -0.7870 +vn 0.4690 0.3793 -0.7976 +vn 0.0894 0.3793 -0.9210 +vn 0.0120 0.2653 -0.9641 +vn -0.0538 0.3969 -0.9163 +vn -0.0711 0.1371 -0.9880 +vn -0.1403 0.2753 -0.9511 +vn -0.2059 0.4066 -0.8901 +vn -0.1544 0.0023 -0.9880 +vn -0.2276 0.1407 -0.9635 +vn -0.2968 0.2789 -0.9133 +vn -0.3566 0.4066 -0.8411 +vn -0.2319 -0.1294 -0.9641 +vn -0.3090 0.0024 -0.9511 +vn -0.3822 0.1407 -0.9133 +vn -0.4455 0.2753 -0.8519 +vn -0.4951 0.3969 -0.7729 +vn -0.2992 -0.2496 -0.9210 +vn -0.3790 -0.1294 -0.9163 +vn -0.4558 0.0023 -0.8901 +vn -0.5232 0.1371 -0.8411 +vn -0.5764 0.2653 -0.7729 +vn -0.6137 0.3793 -0.6925 +vn -0.8483 0.3793 -0.3696 +vn -0.9132 0.2653 -0.3093 +vn -0.8881 0.3969 -0.2320 +vn -0.9616 0.1371 -0.2377 +vn -0.9479 0.2753 -0.1604 +vn -0.9101 0.4066 -0.0792 +vn -0.9874 0.0023 -0.1584 +vn -0.9867 0.1407 -0.0812 +vn -0.9603 0.2789 -0.0000 +vn -0.9101 0.4066 0.0792 +vn -0.9886 -0.1294 -0.0773 +vn -1.0000 0.0024 -0.0000 +vn -0.9867 0.1407 0.0812 +vn -0.9479 0.2753 0.1604 +vn -0.8881 0.3969 0.2320 +vn -0.9684 -0.2496 -0.0000 +vn -0.9886 -0.1294 0.0773 +vn -0.9874 0.0023 0.1584 +vn -0.9616 0.1371 0.2377 +vn -0.9132 0.2653 0.3093 +vn -0.8483 0.3793 0.3696 +vn -0.6137 0.3793 0.6925 +vn -0.5764 0.2653 0.7729 +vn -0.4951 0.3969 0.7729 +vn -0.5232 0.1371 0.8411 +vn -0.4455 0.2753 0.8519 +vn -0.3566 0.4066 0.8411 +vn -0.4558 0.0023 0.8901 +vn -0.3822 0.1407 0.9133 +vn -0.2968 0.2789 0.9133 +vn -0.2059 0.4066 0.8901 +vn -0.3790 -0.1294 0.9163 +vn -0.3090 0.0024 0.9511 +vn -0.2276 0.1407 0.9635 +vn -0.1403 0.2753 0.9511 +vn -0.0538 0.3969 0.9163 +vn -0.2992 -0.2496 0.9210 +vn -0.2319 -0.1294 0.9641 +vn -0.1544 0.0023 0.9880 +vn -0.0711 0.1371 0.9880 +vn 0.0120 0.2653 0.9641 +vn 0.0894 0.3793 0.9210 +vn 0.4690 0.3793 0.7976 +vn 0.5570 0.2653 0.7870 +vn 0.5821 0.3969 0.7097 +vn 0.6383 0.1371 0.7575 +vn 0.6725 0.2753 0.6869 +vn 0.6898 0.4066 0.5991 +vn 0.7057 0.0023 0.7085 +vn 0.7505 0.1407 0.6457 +vn 0.7769 0.2789 0.5645 +vn 0.7829 0.4066 0.4709 +vn 0.7543 -0.1294 0.6436 +vn 0.8090 0.0024 0.5878 +vn 0.8460 0.1407 0.5142 +vn 0.8611 0.2753 0.4274 +vn 0.8548 0.3969 0.3343 +vn 0.7834 -0.2496 0.5692 +vn 0.8452 -0.1294 0.5185 +vn 0.8919 0.0023 0.4522 +vn 0.9177 0.1371 0.3730 +vn 0.9206 0.2653 0.2865 +vn 0.9035 0.3793 0.1996 +vn 0.2992 0.2496 -0.9210 +vn 0.3790 0.1294 -0.9163 +vn 0.2319 0.1294 -0.9641 +vn 0.4558 -0.0023 -0.8901 +vn 0.3090 -0.0024 -0.9511 +vn 0.1544 -0.0023 -0.9880 +vn 0.5232 -0.1371 -0.8411 +vn 0.3822 -0.1407 -0.9133 +vn 0.2276 -0.1407 -0.9635 +vn 0.0711 -0.1371 -0.9880 +vn 0.5764 -0.2653 -0.7729 +vn 0.4455 -0.2753 -0.8519 +vn 0.2968 -0.2789 -0.9133 +vn 0.1403 -0.2753 -0.9511 +vn -0.0120 -0.2653 -0.9641 +vn 0.6137 -0.3793 -0.6925 +vn 0.4951 -0.3969 -0.7729 +vn 0.3566 -0.4066 -0.8411 +vn 0.2059 -0.4066 -0.8901 +vn 0.0538 -0.3969 -0.9163 +vn -0.0894 -0.3793 -0.9210 +vn -0.7834 0.2496 -0.5692 +vn -0.7543 0.1294 -0.6436 +vn -0.8452 0.1294 -0.5185 +vn -0.7057 -0.0023 -0.7085 +vn -0.8090 -0.0024 -0.5878 +vn -0.8919 -0.0023 -0.4522 +vn -0.6383 -0.1371 -0.7575 +vn -0.7505 -0.1407 -0.6457 +vn -0.8460 -0.1407 -0.5142 +vn -0.9177 -0.1371 -0.3730 +vn -0.5570 -0.2653 -0.7870 +vn -0.6725 -0.2753 -0.6869 +vn -0.7769 -0.2789 -0.5645 +vn -0.8611 -0.2753 -0.4274 +vn -0.9206 -0.2653 -0.2865 +vn -0.4690 -0.3793 -0.7976 +vn -0.5821 -0.3969 -0.7097 +vn -0.6898 -0.4066 -0.5991 +vn -0.7829 -0.4066 -0.4709 +vn -0.8548 -0.3969 -0.3343 +vn -0.9035 -0.3793 -0.1996 +vn -0.7834 0.2496 0.5692 +vn -0.8452 0.1294 0.5185 +vn -0.7543 0.1294 0.6436 +vn -0.8919 -0.0023 0.4522 +vn -0.8090 -0.0024 0.5878 +vn -0.7057 -0.0023 0.7085 +vn -0.9177 -0.1371 0.3730 +vn -0.8460 -0.1407 0.5142 +vn -0.7505 -0.1407 0.6457 +vn -0.6383 -0.1371 0.7575 +vn -0.9206 -0.2653 0.2865 +vn -0.8611 -0.2753 0.4274 +vn -0.7769 -0.2789 0.5645 +vn -0.6725 -0.2753 0.6869 +vn -0.5570 -0.2653 0.7870 +vn -0.9035 -0.3793 0.1996 +vn -0.8548 -0.3969 0.3343 +vn -0.7829 -0.4066 0.4709 +vn -0.6898 -0.4066 0.5991 +vn -0.5821 -0.3969 0.7097 +vn -0.4690 -0.3793 0.7976 +vn 0.2992 0.2496 0.9210 +vn 0.2319 0.1294 0.9641 +vn 0.3790 0.1294 0.9163 +vn 0.1544 -0.0023 0.9880 +vn 0.3090 -0.0024 0.9511 +vn 0.4558 -0.0023 0.8901 +vn 0.0711 -0.1371 0.9880 +vn 0.2276 -0.1407 0.9635 +vn 0.3822 -0.1407 0.9133 +vn 0.5232 -0.1371 0.8411 +vn -0.0120 -0.2653 0.9641 +vn 0.1403 -0.2753 0.9511 +vn 0.2968 -0.2789 0.9133 +vn 0.4455 -0.2753 0.8519 +vn 0.5764 -0.2653 0.7729 +vn -0.0894 -0.3793 0.9210 +vn 0.0538 -0.3969 0.9163 +vn 0.2059 -0.4066 0.8901 +vn 0.3566 -0.4066 0.8411 +vn 0.4951 -0.3969 0.7729 +vn 0.6137 -0.3793 0.6925 +vn 0.9684 0.2496 -0.0000 +vn 0.9886 0.1294 0.0773 +vn 0.9886 0.1294 -0.0773 +vn 0.9874 -0.0023 0.1584 +vn 1.0000 -0.0024 -0.0000 +vn 0.9874 -0.0023 -0.1584 +vn 0.9616 -0.1371 0.2377 +vn 0.9867 -0.1407 0.0812 +vn 0.9867 -0.1407 -0.0812 +vn 0.9616 -0.1371 -0.2377 +vn 0.9132 -0.2653 0.3093 +vn 0.9479 -0.2753 0.1604 +vn 0.9603 -0.2789 -0.0000 +vn 0.9479 -0.2753 -0.1604 +vn 0.9132 -0.2653 -0.3093 +vn 0.8483 -0.3793 0.3696 +vn 0.8881 -0.3969 0.2320 +vn 0.9101 -0.4066 0.0792 +vn 0.9101 -0.4066 -0.0792 +vn 0.8881 -0.3969 -0.2320 +vn 0.8483 -0.3793 -0.3696 +vn 0.5736 -0.5891 -0.5692 +vn 0.4937 -0.6981 -0.5185 +vn 0.4531 -0.6168 -0.6436 +vn 0.3968 -0.7988 -0.4522 +vn 0.3597 -0.7247 -0.5878 +vn 0.3135 -0.6322 -0.7085 +vn 0.2878 -0.8821 -0.3730 +vn 0.2525 -0.8196 -0.5142 +vn 0.2098 -0.7342 -0.6457 +vn 0.1628 -0.6322 -0.7575 +vn 0.1744 -0.9421 -0.2865 +vn 0.1389 -0.8934 -0.4274 +vn 0.0980 -0.8196 -0.5645 +vn 0.0545 -0.7247 -0.6869 +vn 0.0118 -0.6168 -0.7870 +vn 0.0648 -0.9777 -0.1996 +vn 0.0273 -0.9421 -0.3343 +vn -0.0136 -0.8821 -0.4709 +vn -0.0552 -0.7988 -0.5991 +vn -0.0947 -0.6981 -0.7097 +vn -0.1295 -0.5891 -0.7976 +vn -0.3641 -0.5891 -0.7214 +vn -0.3406 -0.6981 -0.6298 +vn -0.4721 -0.6168 -0.6298 +vn -0.3074 -0.7988 -0.5171 +vn -0.4479 -0.7247 -0.5237 +vn -0.5770 -0.6322 -0.5171 +vn -0.2658 -0.8821 -0.3889 +vn -0.4110 -0.8196 -0.3991 +vn -0.5493 -0.7342 -0.3991 +vn -0.6701 -0.6322 -0.3889 +vn -0.2186 -0.9421 -0.2544 +vn -0.3635 -0.8934 -0.2641 +vn -0.5066 -0.8196 -0.2676 +vn -0.6365 -0.7247 -0.2641 +vn -0.7449 -0.6168 -0.2544 +vn -0.1698 -0.9777 -0.1233 +vn -0.3095 -0.9421 -0.1293 +vn -0.4520 -0.8821 -0.1326 +vn -0.5868 -0.7988 -0.1326 +vn -0.7042 -0.6981 -0.1293 +vn -0.7986 -0.5891 -0.1233 +vn -0.7986 -0.5891 0.1233 +vn -0.7042 -0.6981 0.1293 +vn -0.7449 -0.6168 0.2544 +vn -0.5868 -0.7988 0.1326 +vn -0.6365 -0.7247 0.2641 +vn -0.6701 -0.6322 0.3889 +vn -0.4520 -0.8821 0.1326 +vn -0.5066 -0.8196 0.2676 +vn -0.5493 -0.7342 0.3991 +vn -0.5770 -0.6322 0.5171 +vn -0.3095 -0.9421 0.1293 +vn -0.3635 -0.8934 0.2641 +vn -0.4110 -0.8196 0.3991 +vn -0.4479 -0.7247 0.5237 +vn -0.4721 -0.6168 0.6298 +vn -0.1698 -0.9777 0.1233 +vn -0.2186 -0.9421 0.2544 +vn -0.2658 -0.8821 0.3889 +vn -0.3074 -0.7988 0.5171 +vn -0.3406 -0.6981 0.6298 +vn -0.3641 -0.5891 0.7214 +vn 0.7186 -0.5891 -0.3696 +vn 0.7521 -0.6168 -0.2320 +vn 0.6457 -0.6981 -0.3093 +vn 0.7707 -0.6322 -0.0792 +vn 0.6702 -0.7247 -0.1604 +vn 0.5527 -0.7988 -0.2376 +vn 0.7707 -0.6322 0.0792 +vn 0.6789 -0.7342 -0.0000 +vn 0.5671 -0.8196 -0.0812 +vn 0.4436 -0.8821 -0.1584 +vn 0.7521 -0.6168 0.2320 +vn 0.6702 -0.7247 0.1604 +vn 0.5671 -0.8196 0.0812 +vn 0.4493 -0.8934 -0.0000 +vn 0.3264 -0.9421 -0.0773 +vn 0.7186 -0.5891 0.3696 +vn 0.6457 -0.6981 0.3093 +vn 0.5527 -0.7988 0.2377 +vn 0.4436 -0.8821 0.1584 +vn 0.3264 -0.9421 0.0773 +vn 0.2098 -0.9777 -0.0000 +vn -0.1295 -0.5891 0.7976 +vn -0.0947 -0.6981 0.7097 +vn 0.0118 -0.6168 0.7870 +vn -0.0552 -0.7988 0.5991 +vn 0.0545 -0.7247 0.6869 +vn 0.1628 -0.6322 0.7575 +vn -0.0136 -0.8821 0.4709 +vn 0.0980 -0.8196 0.5645 +vn 0.2098 -0.7342 0.6457 +vn 0.3135 -0.6322 0.7085 +vn 0.0273 -0.9421 0.3343 +vn 0.1389 -0.8934 0.4274 +vn 0.2525 -0.8196 0.5142 +vn 0.3597 -0.7247 0.5878 +vn 0.4531 -0.6168 0.6436 +vn 0.0648 -0.9777 0.1996 +vn 0.1744 -0.9421 0.2865 +vn 0.2878 -0.8821 0.3730 +vn 0.3968 -0.7988 0.4522 +vn 0.4937 -0.6981 0.5185 +vn 0.5736 -0.5891 0.5692 +vt 0.181819 0.000000 +vt 0.193183 0.019683 +vt 0.170455 0.019683 +vt 0.272728 0.157461 +vt 0.284092 0.137778 +vt 0.295455 0.157461 +vt 0.909091 0.000000 +vt 0.920455 0.019683 +vt 0.897727 0.019683 +vt 0.727273 0.000000 +vt 0.738637 0.019683 +vt 0.715909 0.019683 +vt 0.545455 0.000000 +vt 0.556819 0.019683 +vt 0.534091 0.019683 +vt 0.284092 0.177143 +vt 0.090910 0.157461 +vt 0.113637 0.157461 +vt 0.102274 0.177143 +vt 0.818182 0.157461 +vt 0.840909 0.157461 +vt 0.829546 0.177143 +vt 0.636364 0.157461 +vt 0.659091 0.157461 +vt 0.647728 0.177143 +vt 0.454546 0.157461 +vt 0.477273 0.157461 +vt 0.465910 0.177143 +vt 0.261364 0.177143 +vt 0.079546 0.177143 +vt 0.806818 0.177143 +vt 0.625000 0.177143 +vt 0.443182 0.177143 +vt 0.181819 0.314921 +vt 0.204546 0.314921 +vt 0.193183 0.334604 +vt 0.000000 0.314921 +vt 0.022727 0.314921 +vt 0.011364 0.334604 +vt 0.727273 0.314921 +vt 0.750000 0.314921 +vt 0.738637 0.334604 +vt 0.545455 0.314921 +vt 0.568182 0.314921 +vt 0.556819 0.334604 +vt 0.363637 0.314921 +vt 0.386364 0.314921 +vt 0.375001 0.334604 +vt 0.443182 0.452699 +vt 0.465910 0.452699 +vt 0.454546 0.472382 +vt 0.431819 0.433017 +vt 0.454546 0.433017 +vt 0.420455 0.413334 +vt 0.443182 0.413334 +vt 0.409092 0.393652 +vt 0.431819 0.393652 +vt 0.397728 0.373969 +vt 0.420455 0.373969 +vt 0.386364 0.354286 +vt 0.409091 0.354286 +vt 0.397728 0.334604 +vt 0.477273 0.433017 +vt 0.465910 0.413334 +vt 0.488637 0.413334 +vt 0.454546 0.393652 +vt 0.477273 0.393652 +vt 0.500000 0.393652 +vt 0.443182 0.373969 +vt 0.465910 0.373969 +vt 0.488637 0.373969 +vt 0.511364 0.373969 +vt 0.431819 0.354286 +vt 0.454546 0.354286 +vt 0.477273 0.354286 +vt 0.500000 0.354286 +vt 0.522728 0.354286 +vt 0.420455 0.334604 +vt 0.443182 0.334604 +vt 0.465910 0.334604 +vt 0.488637 0.334604 +vt 0.511364 0.334604 +vt 0.534091 0.334604 +vt 0.409091 0.314921 +vt 0.431819 0.314921 +vt 0.454546 0.314921 +vt 0.477273 0.314921 +vt 0.500000 0.314921 +vt 0.522728 0.314921 +vt 0.625000 0.452699 +vt 0.647728 0.452699 +vt 0.636364 0.472382 +vt 0.613637 0.433017 +vt 0.636364 0.433017 +vt 0.602273 0.413334 +vt 0.625000 0.413334 +vt 0.590910 0.393652 +vt 0.613637 0.393652 +vt 0.579546 0.373969 +vt 0.602273 0.373969 +vt 0.568182 0.354286 +vt 0.590909 0.354286 +vt 0.579546 0.334604 +vt 0.659091 0.433017 +vt 0.647728 0.413334 +vt 0.670455 0.413334 +vt 0.636364 0.393652 +vt 0.659091 0.393652 +vt 0.681818 0.393652 +vt 0.625000 0.373969 +vt 0.647728 0.373969 +vt 0.670455 0.373969 +vt 0.693182 0.373969 +vt 0.613637 0.354286 +vt 0.636364 0.354286 +vt 0.659091 0.354286 +vt 0.681818 0.354286 +vt 0.704546 0.354286 +vt 0.602273 0.334604 +vt 0.625000 0.334604 +vt 0.647728 0.334604 +vt 0.670455 0.334604 +vt 0.693182 0.334604 +vt 0.715909 0.334604 +vt 0.590909 0.314921 +vt 0.613637 0.314921 +vt 0.636364 0.314921 +vt 0.659091 0.314921 +vt 0.681819 0.314921 +vt 0.704546 0.314921 +vt 0.806818 0.452699 +vt 0.829546 0.452699 +vt 0.818182 0.472382 +vt 0.795455 0.433017 +vt 0.818182 0.433017 +vt 0.784091 0.413334 +vt 0.806818 0.413334 +vt 0.772727 0.393652 +vt 0.795455 0.393652 +vt 0.761364 0.373969 +vt 0.784091 0.373969 +vt 0.750000 0.354286 +vt 0.772727 0.354286 +vt 0.761364 0.334604 +vt 0.840909 0.433017 +vt 0.829546 0.413334 +vt 0.852273 0.413334 +vt 0.818182 0.393652 +vt 0.840909 0.393652 +vt 0.863636 0.393652 +vt 0.806818 0.373969 +vt 0.829546 0.373969 +vt 0.852273 0.373969 +vt 0.875000 0.373969 +vt 0.795455 0.354286 +vt 0.818182 0.354286 +vt 0.840909 0.354286 +vt 0.863636 0.354286 +vt 0.886364 0.354286 +vt 0.784091 0.334604 +vt 0.806818 0.334604 +vt 0.829546 0.334604 +vt 0.852273 0.334604 +vt 0.875000 0.334604 +vt 0.897727 0.334604 +vt 0.772727 0.314921 +vt 0.795455 0.314921 +vt 0.818182 0.314921 +vt 0.840909 0.314921 +vt 0.863636 0.314921 +vt 0.886364 0.314921 +vt 0.909091 0.314921 +vt 0.079546 0.452699 +vt 0.102274 0.452699 +vt 0.090910 0.472382 +vt 0.068182 0.433017 +vt 0.090910 0.433017 +vt 0.056819 0.413334 +vt 0.079546 0.413334 +vt 0.045455 0.393652 +vt 0.068182 0.393652 +vt 0.034091 0.373969 +vt 0.056819 0.373969 +vt 0.022727 0.354286 +vt 0.045455 0.354286 +vt 0.034091 0.334604 +vt 0.113637 0.433017 +vt 0.102274 0.413334 +vt 0.125001 0.413334 +vt 0.090910 0.393652 +vt 0.113637 0.393652 +vt 0.136365 0.393652 +vt 0.079546 0.373969 +vt 0.102273 0.373969 +vt 0.125001 0.373969 +vt 0.147728 0.373969 +vt 0.068182 0.354286 +vt 0.090910 0.354286 +vt 0.113637 0.354286 +vt 0.136364 0.354286 +vt 0.159092 0.354286 +vt 0.056819 0.334604 +vt 0.079546 0.334604 +vt 0.102273 0.334604 +vt 0.125001 0.334604 +vt 0.147728 0.334604 +vt 0.170455 0.334604 +vt 0.045455 0.314921 +vt 0.068182 0.314921 +vt 0.090910 0.314921 +vt 0.113637 0.314921 +vt 0.136364 0.314921 +vt 0.159092 0.314921 +vt 0.261364 0.452699 +vt 0.284092 0.452699 +vt 0.272728 0.472382 +vt 0.250001 0.433017 +vt 0.272728 0.433017 +vt 0.238637 0.413334 +vt 0.261364 0.413334 +vt 0.227273 0.393652 +vt 0.250001 0.393652 +vt 0.215910 0.373969 +vt 0.238637 0.373969 +vt 0.204546 0.354286 +vt 0.227273 0.354286 +vt 0.215910 0.334604 +vt 0.295455 0.433017 +vt 0.284092 0.413334 +vt 0.306819 0.413334 +vt 0.272728 0.393652 +vt 0.295455 0.393652 +vt 0.318182 0.393652 +vt 0.261364 0.373969 +vt 0.284092 0.373969 +vt 0.306819 0.373969 +vt 0.329546 0.373969 +vt 0.250001 0.354286 +vt 0.272728 0.354286 +vt 0.295455 0.354286 +vt 0.318182 0.354286 +vt 0.340910 0.354286 +vt 0.238637 0.334604 +vt 0.261364 0.334604 +vt 0.284092 0.334604 +vt 0.306819 0.334604 +vt 0.329546 0.334604 +vt 0.352273 0.334604 +vt 0.227274 0.314921 +vt 0.250001 0.314921 +vt 0.272728 0.314921 +vt 0.295455 0.314921 +vt 0.318183 0.314921 +vt 0.340910 0.314921 +vt 0.375001 0.295238 +vt 0.386364 0.275556 +vt 0.397728 0.295238 +vt 0.397728 0.255874 +vt 0.409092 0.275556 +vt 0.409092 0.236191 +vt 0.420455 0.255874 +vt 0.420455 0.216509 +vt 0.431819 0.236191 +vt 0.431819 0.196826 +vt 0.443182 0.216509 +vt 0.454546 0.196826 +vt 0.420455 0.295238 +vt 0.431819 0.275556 +vt 0.443182 0.295238 +vt 0.443182 0.255874 +vt 0.454546 0.275556 +vt 0.465910 0.295238 +vt 0.454546 0.236191 +vt 0.465910 0.255874 +vt 0.477273 0.275556 +vt 0.488637 0.295238 +vt 0.465910 0.216509 +vt 0.477273 0.236191 +vt 0.488637 0.255874 +vt 0.500000 0.275556 +vt 0.511364 0.295238 +vt 0.477273 0.196826 +vt 0.488637 0.216508 +vt 0.500000 0.236191 +vt 0.511364 0.255874 +vt 0.522728 0.275556 +vt 0.534091 0.295238 +vt 0.556819 0.295238 +vt 0.568182 0.275556 +vt 0.579546 0.295238 +vt 0.579546 0.255874 +vt 0.590910 0.275556 +vt 0.590910 0.236191 +vt 0.602273 0.255874 +vt 0.602273 0.216509 +vt 0.613637 0.236191 +vt 0.613637 0.196826 +vt 0.625000 0.216509 +vt 0.636364 0.196826 +vt 0.602273 0.295238 +vt 0.613637 0.275556 +vt 0.625000 0.295238 +vt 0.625000 0.255874 +vt 0.636364 0.275556 +vt 0.647728 0.295238 +vt 0.636364 0.236191 +vt 0.647728 0.255874 +vt 0.659091 0.275556 +vt 0.670455 0.295238 +vt 0.647728 0.216509 +vt 0.659091 0.236191 +vt 0.670455 0.255874 +vt 0.681818 0.275556 +vt 0.693182 0.295238 +vt 0.659091 0.196826 +vt 0.670455 0.216508 +vt 0.681818 0.236191 +vt 0.693182 0.255874 +vt 0.704546 0.275556 +vt 0.715909 0.295238 +vt 0.738637 0.295238 +vt 0.750000 0.275556 +vt 0.761364 0.295238 +vt 0.761364 0.255874 +vt 0.772727 0.275556 +vt 0.772727 0.236191 +vt 0.784091 0.255874 +vt 0.784091 0.216509 +vt 0.795455 0.236191 +vt 0.795455 0.196826 +vt 0.806818 0.216509 +vt 0.818182 0.196826 +vt 0.784091 0.295238 +vt 0.795455 0.275556 +vt 0.806818 0.295238 +vt 0.806818 0.255874 +vt 0.818182 0.275556 +vt 0.829546 0.295238 +vt 0.818182 0.236191 +vt 0.829546 0.255874 +vt 0.840909 0.275556 +vt 0.852273 0.295238 +vt 0.829546 0.216509 +vt 0.840909 0.236191 +vt 0.852273 0.255874 +vt 0.863636 0.275556 +vt 0.875000 0.295238 +vt 0.840909 0.196826 +vt 0.852273 0.216508 +vt 0.863636 0.236191 +vt 0.875000 0.255874 +vt 0.886364 0.275556 +vt 0.897727 0.295238 +vt 0.011364 0.295238 +vt 0.022727 0.275556 +vt 0.034091 0.295238 +vt 0.034091 0.255874 +vt 0.045455 0.275556 +vt 0.045455 0.236191 +vt 0.056819 0.255874 +vt 0.056819 0.216509 +vt 0.068182 0.236191 +vt 0.068182 0.196826 +vt 0.079546 0.216509 +vt 0.090910 0.196826 +vt 0.056819 0.295238 +vt 0.068182 0.275556 +vt 0.079546 0.295238 +vt 0.079546 0.255874 +vt 0.090910 0.275556 +vt 0.102273 0.295238 +vt 0.090910 0.236191 +vt 0.102273 0.255874 +vt 0.113637 0.275556 +vt 0.125001 0.295238 +vt 0.102274 0.216509 +vt 0.113637 0.236191 +vt 0.125001 0.255874 +vt 0.136364 0.275556 +vt 0.147728 0.295238 +vt 0.113637 0.196826 +vt 0.125001 0.216508 +vt 0.136365 0.236191 +vt 0.147728 0.255874 +vt 0.159092 0.275556 +vt 0.170455 0.295238 +vt 0.193183 0.295238 +vt 0.204546 0.275556 +vt 0.215910 0.295238 +vt 0.215910 0.255874 +vt 0.227274 0.275556 +vt 0.227273 0.236191 +vt 0.238637 0.255874 +vt 0.238637 0.216509 +vt 0.250001 0.236191 +vt 0.250001 0.196826 +vt 0.261364 0.216509 +vt 0.272728 0.196826 +vt 0.238637 0.295238 +vt 0.250001 0.275556 +vt 0.261364 0.295238 +vt 0.261364 0.255874 +vt 0.272728 0.275556 +vt 0.284092 0.295238 +vt 0.272728 0.236191 +vt 0.284092 0.255874 +vt 0.295455 0.275556 +vt 0.306819 0.295238 +vt 0.284092 0.216509 +vt 0.295455 0.236191 +vt 0.306819 0.255874 +vt 0.318182 0.275556 +vt 0.329546 0.295238 +vt 0.295455 0.196826 +vt 0.306819 0.216508 +vt 0.318182 0.236191 +vt 0.329546 0.255874 +vt 0.340910 0.275556 +vt 0.352273 0.295238 +vt 0.545455 0.275556 +vt 0.534091 0.255874 +vt 0.522728 0.236191 +vt 0.511364 0.216508 +vt 0.500000 0.196826 +vt 0.488637 0.177143 +vt 0.556819 0.255874 +vt 0.545455 0.236191 +vt 0.568182 0.236191 +vt 0.534091 0.216508 +vt 0.556819 0.216508 +vt 0.579546 0.216508 +vt 0.522728 0.196826 +vt 0.545455 0.196826 +vt 0.568182 0.196826 +vt 0.590909 0.196826 +vt 0.511364 0.177143 +vt 0.534091 0.177143 +vt 0.556819 0.177143 +vt 0.579546 0.177143 +vt 0.602273 0.177143 +vt 0.500000 0.157461 +vt 0.522728 0.157461 +vt 0.545455 0.157461 +vt 0.568182 0.157461 +vt 0.590909 0.157461 +vt 0.613637 0.157461 +vt 0.727273 0.275556 +vt 0.715909 0.255874 +vt 0.704546 0.236191 +vt 0.693182 0.216508 +vt 0.681818 0.196826 +vt 0.670455 0.177143 +vt 0.738637 0.255874 +vt 0.727273 0.236191 +vt 0.750000 0.236191 +vt 0.715909 0.216508 +vt 0.738637 0.216508 +vt 0.761364 0.216508 +vt 0.704546 0.196826 +vt 0.727273 0.196826 +vt 0.750000 0.196826 +vt 0.772727 0.196826 +vt 0.693182 0.177143 +vt 0.715909 0.177143 +vt 0.738637 0.177143 +vt 0.761364 0.177143 +vt 0.784091 0.177143 +vt 0.681818 0.157461 +vt 0.704546 0.157461 +vt 0.727273 0.157461 +vt 0.750000 0.157461 +vt 0.772727 0.157461 +vt 0.795455 0.157461 +vt 0.920455 0.295238 +vt 0.909091 0.275556 +vt 0.897727 0.255874 +vt 0.886364 0.236191 +vt 0.875000 0.216508 +vt 0.863636 0.196826 +vt 0.852273 0.177143 +vt 0.931818 0.275556 +vt 0.920455 0.255874 +vt 0.943182 0.255874 +vt 0.909091 0.236191 +vt 0.931818 0.236191 +vt 0.954545 0.236191 +vt 0.897727 0.216508 +vt 0.920455 0.216508 +vt 0.943182 0.216508 +vt 0.965909 0.216509 +vt 0.886364 0.196826 +vt 0.909091 0.196826 +vt 0.931818 0.196826 +vt 0.954545 0.196826 +vt 0.977273 0.196826 +vt 0.875000 0.177143 +vt 0.897727 0.177143 +vt 0.920455 0.177143 +vt 0.943182 0.177143 +vt 0.965909 0.177143 +vt 0.988636 0.177143 +vt 0.863636 0.157461 +vt 0.886364 0.157461 +vt 0.909091 0.157461 +vt 0.931818 0.157461 +vt 0.954545 0.157461 +vt 0.977273 0.157461 +vt 1.000000 0.157461 +vt 0.181819 0.275556 +vt 0.170455 0.255874 +vt 0.159092 0.236191 +vt 0.147728 0.216508 +vt 0.136364 0.196826 +vt 0.125001 0.177143 +vt 0.193183 0.255874 +vt 0.181819 0.236191 +vt 0.204546 0.236191 +vt 0.170455 0.216508 +vt 0.193183 0.216508 +vt 0.215910 0.216508 +vt 0.159092 0.196826 +vt 0.181819 0.196826 +vt 0.204546 0.196826 +vt 0.227273 0.196826 +vt 0.147728 0.177143 +vt 0.170455 0.177143 +vt 0.193183 0.177143 +vt 0.215910 0.177143 +vt 0.238637 0.177143 +vt 0.136364 0.157461 +vt 0.159092 0.157461 +vt 0.181819 0.157461 +vt 0.204546 0.157461 +vt 0.227273 0.157461 +vt 0.250001 0.157461 +vt 0.363637 0.275556 +vt 0.352273 0.255874 +vt 0.340910 0.236191 +vt 0.329546 0.216508 +vt 0.318182 0.196826 +vt 0.306819 0.177143 +vt 0.375001 0.255874 +vt 0.363637 0.236191 +vt 0.386364 0.236191 +vt 0.352273 0.216508 +vt 0.375001 0.216508 +vt 0.397728 0.216508 +vt 0.340910 0.196826 +vt 0.363637 0.196826 +vt 0.386364 0.196826 +vt 0.409092 0.196826 +vt 0.329546 0.177143 +vt 0.352273 0.177143 +vt 0.375001 0.177143 +vt 0.397728 0.177143 +vt 0.420455 0.177143 +vt 0.318182 0.157461 +vt 0.340910 0.157461 +vt 0.363637 0.157461 +vt 0.386364 0.157461 +vt 0.409092 0.157461 +vt 0.431819 0.157461 +vt 0.465910 0.137778 +vt 0.477273 0.118096 +vt 0.488637 0.137778 +vt 0.488637 0.098413 +vt 0.500000 0.118096 +vt 0.500000 0.078731 +vt 0.511364 0.098413 +vt 0.511364 0.059048 +vt 0.522728 0.078731 +vt 0.522728 0.039365 +vt 0.534091 0.059048 +vt 0.545455 0.039365 +vt 0.511364 0.137778 +vt 0.522728 0.118096 +vt 0.534091 0.137778 +vt 0.534091 0.098413 +vt 0.545455 0.118096 +vt 0.556819 0.137778 +vt 0.545455 0.078731 +vt 0.556819 0.098413 +vt 0.568182 0.118096 +vt 0.579546 0.137778 +vt 0.556819 0.059048 +vt 0.568182 0.078731 +vt 0.579546 0.098413 +vt 0.590909 0.118096 +vt 0.602273 0.137778 +vt 0.568182 0.039365 +vt 0.579546 0.059048 +vt 0.590910 0.078731 +vt 0.602273 0.098413 +vt 0.613637 0.118096 +vt 0.625000 0.137778 +vt 0.647728 0.137778 +vt 0.659091 0.118096 +vt 0.670455 0.137778 +vt 0.670455 0.098413 +vt 0.681818 0.118096 +vt 0.681818 0.078731 +vt 0.693182 0.098413 +vt 0.693182 0.059048 +vt 0.704546 0.078731 +vt 0.704546 0.039365 +vt 0.715909 0.059048 +vt 0.727273 0.039365 +vt 0.693182 0.137778 +vt 0.704546 0.118096 +vt 0.715909 0.137778 +vt 0.715909 0.098413 +vt 0.727273 0.118096 +vt 0.738637 0.137778 +vt 0.727273 0.078731 +vt 0.738637 0.098413 +vt 0.750000 0.118096 +vt 0.761364 0.137778 +vt 0.738637 0.059048 +vt 0.750000 0.078731 +vt 0.761364 0.098413 +vt 0.772727 0.118096 +vt 0.784091 0.137778 +vt 0.750000 0.039365 +vt 0.761364 0.059048 +vt 0.772727 0.078731 +vt 0.784091 0.098413 +vt 0.795455 0.118096 +vt 0.806818 0.137778 +vt 0.829546 0.137778 +vt 0.840909 0.118096 +vt 0.852273 0.137778 +vt 0.852273 0.098413 +vt 0.863636 0.118096 +vt 0.863636 0.078731 +vt 0.875000 0.098413 +vt 0.875000 0.059048 +vt 0.886364 0.078731 +vt 0.886364 0.039365 +vt 0.897727 0.059048 +vt 0.909091 0.039365 +vt 0.875000 0.137778 +vt 0.886364 0.118096 +vt 0.897727 0.137778 +vt 0.897727 0.098413 +vt 0.909091 0.118096 +vt 0.920455 0.137778 +vt 0.909091 0.078731 +vt 0.920455 0.098413 +vt 0.931818 0.118096 +vt 0.943182 0.137778 +vt 0.920455 0.059048 +vt 0.931818 0.078731 +vt 0.943182 0.098413 +vt 0.954545 0.118096 +vt 0.965909 0.137778 +vt 0.931818 0.039365 +vt 0.943182 0.059048 +vt 0.954545 0.078731 +vt 0.965909 0.098413 +vt 0.977273 0.118096 +vt 0.988636 0.137778 +vt 0.443182 0.137778 +vt 0.420455 0.137778 +vt 0.397728 0.137778 +vt 0.375001 0.137778 +vt 0.352273 0.137778 +vt 0.329546 0.137778 +vt 0.306819 0.137778 +vt 0.431819 0.118096 +vt 0.409091 0.118096 +vt 0.420455 0.098413 +vt 0.386364 0.118096 +vt 0.397728 0.098413 +vt 0.409092 0.078731 +vt 0.363637 0.118096 +vt 0.375001 0.098413 +vt 0.386364 0.078731 +vt 0.397728 0.059048 +vt 0.340910 0.118096 +vt 0.352273 0.098413 +vt 0.363637 0.078731 +vt 0.375001 0.059048 +vt 0.386364 0.039365 +vt 0.318182 0.118096 +vt 0.329546 0.098413 +vt 0.340910 0.078731 +vt 0.352273 0.059048 +vt 0.363637 0.039365 +vt 0.375001 0.019683 +vt 0.295455 0.118096 +vt 0.306819 0.098413 +vt 0.318182 0.078731 +vt 0.329546 0.059048 +vt 0.340910 0.039365 +vt 0.352273 0.019683 +vt 0.363637 0.000000 +vt 0.102274 0.137778 +vt 0.113637 0.118096 +vt 0.125001 0.137778 +vt 0.125001 0.098413 +vt 0.136365 0.118096 +vt 0.136365 0.078731 +vt 0.147728 0.098413 +vt 0.147728 0.059048 +vt 0.159092 0.078731 +vt 0.159092 0.039365 +vt 0.170455 0.059048 +vt 0.181819 0.039365 +vt 0.147728 0.137778 +vt 0.159092 0.118096 +vt 0.170455 0.137778 +vt 0.170455 0.098413 +vt 0.181819 0.118096 +vt 0.193183 0.137778 +vt 0.181819 0.078731 +vt 0.193183 0.098413 +vt 0.204546 0.118096 +vt 0.215910 0.137778 +vt 0.193183 0.059048 +vt 0.204546 0.078731 +vt 0.215910 0.098413 +vt 0.227273 0.118096 +vt 0.238637 0.137778 +vt 0.204546 0.039365 +vt 0.215910 0.059048 +vt 0.227274 0.078731 +vt 0.238637 0.098413 +vt 0.250001 0.118096 +vt 0.261364 0.137778 +s 1 +f 1/1/1 20/2/20 19/3/19 +f 2/4/2 26/5/26 40/6/40 +f 1/7/1 19/8/19 54/9/54 +f 1/10/1 54/11/54 68/12/68 +f 1/13/1 68/14/68 41/15/41 +f 2/4/2 40/6/40 89/16/89 +f 3/17/3 33/18/33 103/19/103 +f 4/20/4 61/21/61 117/22/117 +f 5/23/5 75/24/75 131/25/131 +f 6/26/6 82/27/82 145/28/145 +f 2/4/2 89/16/89 104/29/104 +f 3/17/3 103/19/103 118/30/118 +f 4/20/4 117/22/117 132/31/132 +f 5/23/5 131/25/131 146/32/146 +f 6/26/6 145/28/145 90/33/90 +f 7/34/7 159/35/159 194/36/194 +f 8/37/8 166/38/166 208/39/208 +f 9/40/9 173/41/173 215/42/215 +f 10/43/10 180/44/180 222/45/222 +f 11/46/11 187/47/187 195/48/195 +f 201/49/201 216/50/216 12/51/12 +f 200/52/200 223/53/223 201/49/201 +f 199/54/199 224/55/224 200/52/200 +f 198/56/198 226/57/226 199/54/199 +f 197/58/197 229/59/229 198/56/198 +f 196/60/196 233/61/233 197/58/197 +f 195/48/195 238/62/238 196/60/196 +f 201/49/201 223/53/223 216/50/216 +f 223/53/223 217/63/217 216/50/216 +f 200/52/200 224/55/224 223/53/223 +f 224/55/224 225/64/225 223/53/223 +f 223/53/223 225/64/225 217/63/217 +f 225/64/225 218/65/218 217/63/217 +f 199/54/199 226/57/226 224/55/224 +f 226/57/226 227/66/227 224/55/224 +f 224/55/224 227/66/227 225/64/225 +f 227/66/227 228/67/228 225/64/225 +f 225/64/225 228/67/228 218/65/218 +f 228/67/228 219/68/219 218/65/218 +f 198/56/198 229/59/229 226/57/226 +f 229/59/229 230/69/230 226/57/226 +f 226/57/226 230/69/230 227/66/227 +f 230/69/230 231/70/231 227/66/227 +f 227/66/227 231/70/231 228/67/228 +f 231/70/231 232/71/232 228/67/228 +f 228/67/228 232/71/232 219/68/219 +f 232/71/232 220/72/220 219/68/219 +f 197/58/197 233/61/233 229/59/229 +f 233/61/233 234/73/234 229/59/229 +f 229/59/229 234/73/234 230/69/230 +f 234/73/234 235/74/235 230/69/230 +f 230/69/230 235/74/235 231/70/231 +f 235/74/235 236/75/236 231/70/231 +f 231/70/231 236/75/236 232/71/232 +f 236/75/236 237/76/237 232/71/232 +f 232/71/232 237/76/237 220/72/220 +f 237/76/237 221/77/221 220/72/220 +f 196/60/196 238/62/238 233/61/233 +f 238/62/238 239/78/239 233/61/233 +f 233/61/233 239/78/239 234/73/234 +f 239/78/239 240/79/240 234/73/234 +f 234/73/234 240/79/240 235/74/235 +f 240/79/240 241/80/241 235/74/235 +f 235/74/235 241/80/241 236/75/236 +f 241/80/241 242/81/242 236/75/236 +f 236/75/236 242/81/242 237/76/237 +f 242/81/242 243/82/243 237/76/237 +f 237/76/237 243/82/243 221/77/221 +f 243/82/243 222/83/222 221/77/221 +f 195/48/195 187/47/187 238/62/238 +f 187/47/187 186/84/186 238/62/238 +f 238/62/238 186/84/186 239/78/239 +f 186/84/186 185/85/185 239/78/239 +f 239/78/239 185/85/185 240/79/240 +f 185/85/185 184/86/184 240/79/240 +f 240/79/240 184/86/184 241/80/241 +f 184/86/184 183/87/183 241/80/241 +f 241/80/241 183/87/183 242/81/242 +f 183/87/183 182/88/182 242/81/242 +f 242/81/242 182/88/182 243/82/243 +f 182/88/182 181/89/181 243/82/243 +f 243/82/243 181/89/181 222/83/222 +f 181/89/181 10/43/10 222/83/222 +f 216/90/216 209/91/209 12/92/12 +f 217/93/217 244/94/244 216/90/216 +f 218/95/218 245/96/245 217/93/217 +f 219/97/219 247/98/247 218/95/218 +f 220/99/220 250/100/250 219/97/219 +f 221/101/221 254/102/254 220/99/220 +f 222/45/222 259/103/259 221/101/221 +f 216/90/216 244/94/244 209/91/209 +f 244/94/244 210/104/210 209/91/209 +f 217/93/217 245/96/245 244/94/244 +f 245/96/245 246/105/246 244/94/244 +f 244/94/244 246/105/246 210/104/210 +f 246/105/246 211/106/211 210/104/210 +f 218/95/218 247/98/247 245/96/245 +f 247/98/247 248/107/248 245/96/245 +f 245/96/245 248/107/248 246/105/246 +f 248/107/248 249/108/249 246/105/246 +f 246/105/246 249/108/249 211/106/211 +f 249/108/249 212/109/212 211/106/211 +f 219/97/219 250/100/250 247/98/247 +f 250/100/250 251/110/251 247/98/247 +f 247/98/247 251/110/251 248/107/248 +f 251/110/251 252/111/252 248/107/248 +f 248/107/248 252/111/252 249/108/249 +f 252/111/252 253/112/253 249/108/249 +f 249/108/249 253/112/253 212/109/212 +f 253/112/253 213/113/213 212/109/212 +f 220/99/220 254/102/254 250/100/250 +f 254/102/254 255/114/255 250/100/250 +f 250/100/250 255/114/255 251/110/251 +f 255/114/255 256/115/256 251/110/251 +f 251/110/251 256/115/256 252/111/252 +f 256/115/256 257/116/257 252/111/252 +f 252/111/252 257/116/257 253/112/253 +f 257/116/257 258/117/258 253/112/253 +f 253/112/253 258/117/258 213/113/213 +f 258/117/258 214/118/214 213/113/213 +f 221/101/221 259/103/259 254/102/254 +f 259/103/259 260/119/260 254/102/254 +f 254/102/254 260/119/260 255/114/255 +f 260/119/260 261/120/261 255/114/255 +f 255/114/255 261/120/261 256/115/256 +f 261/120/261 262/121/262 256/115/256 +f 256/115/256 262/121/262 257/116/257 +f 262/121/262 263/122/263 257/116/257 +f 257/116/257 263/122/263 258/117/258 +f 263/122/263 264/123/264 258/117/258 +f 258/117/258 264/123/264 214/118/214 +f 264/123/264 215/124/215 214/118/214 +f 222/45/222 180/44/180 259/103/259 +f 180/44/180 179/125/179 259/103/259 +f 259/103/259 179/125/179 260/119/260 +f 179/125/179 178/126/178 260/119/260 +f 260/119/260 178/126/178 261/120/261 +f 178/126/178 177/127/177 261/120/261 +f 261/120/261 177/127/177 262/121/262 +f 177/127/177 176/128/176 262/121/262 +f 262/121/262 176/128/176 263/122/263 +f 176/128/176 175/129/175 263/122/263 +f 263/122/263 175/129/175 264/123/264 +f 175/129/175 174/130/174 264/123/264 +f 264/123/264 174/130/174 215/124/215 +f 174/130/174 9/40/9 215/124/215 +f 209/131/209 202/132/202 12/133/12 +f 210/134/210 265/135/265 209/131/209 +f 211/136/211 266/137/266 210/134/210 +f 212/138/212 268/139/268 211/136/211 +f 213/140/213 271/141/271 212/138/212 +f 214/142/214 275/143/275 213/140/213 +f 215/42/215 280/144/280 214/142/214 +f 209/131/209 265/135/265 202/132/202 +f 265/135/265 203/145/203 202/132/202 +f 210/134/210 266/137/266 265/135/265 +f 266/137/266 267/146/267 265/135/265 +f 265/135/265 267/146/267 203/145/203 +f 267/146/267 204/147/204 203/145/203 +f 211/136/211 268/139/268 266/137/266 +f 268/139/268 269/148/269 266/137/266 +f 266/137/266 269/148/269 267/146/267 +f 269/148/269 270/149/270 267/146/267 +f 267/146/267 270/149/270 204/147/204 +f 270/149/270 205/150/205 204/147/204 +f 212/138/212 271/141/271 268/139/268 +f 271/141/271 272/151/272 268/139/268 +f 268/139/268 272/151/272 269/148/269 +f 272/151/272 273/152/273 269/148/269 +f 269/148/269 273/152/273 270/149/270 +f 273/152/273 274/153/274 270/149/270 +f 270/149/270 274/153/274 205/150/205 +f 274/153/274 206/154/206 205/150/205 +f 213/140/213 275/143/275 271/141/271 +f 275/143/275 276/155/276 271/141/271 +f 271/141/271 276/155/276 272/151/272 +f 276/155/276 277/156/277 272/151/272 +f 272/151/272 277/156/277 273/152/273 +f 277/156/277 278/157/278 273/152/273 +f 273/152/273 278/157/278 274/153/274 +f 278/157/278 279/158/279 274/153/274 +f 274/153/274 279/158/279 206/154/206 +f 279/158/279 207/159/207 206/154/206 +f 214/142/214 280/144/280 275/143/275 +f 280/144/280 281/160/281 275/143/275 +f 275/143/275 281/160/281 276/155/276 +f 281/160/281 282/161/282 276/155/276 +f 276/155/276 282/161/282 277/156/277 +f 282/161/282 283/162/283 277/156/277 +f 277/156/277 283/162/283 278/157/278 +f 283/162/283 284/163/284 278/157/278 +f 278/157/278 284/163/284 279/158/279 +f 284/163/284 285/164/285 279/158/279 +f 279/158/279 285/164/285 207/159/207 +f 285/164/285 208/165/208 207/159/207 +f 215/42/215 173/41/173 280/144/280 +f 173/41/173 172/166/172 280/144/280 +f 280/144/280 172/166/172 281/160/281 +f 172/166/172 171/167/171 281/160/281 +f 281/160/281 171/167/171 282/161/282 +f 171/167/171 170/168/170 282/161/282 +f 282/161/282 170/168/170 283/162/283 +f 170/168/170 169/169/169 283/162/283 +f 283/162/283 169/169/169 284/163/284 +f 169/169/169 168/170/168 284/163/284 +f 284/163/284 168/170/168 285/164/285 +f 168/170/168 167/171/167 285/164/285 +f 285/164/285 167/171/167 208/165/208 +f 167/171/167 8/172/8 208/165/208 +f 202/173/202 188/174/188 12/175/12 +f 203/176/203 286/177/286 202/173/202 +f 204/178/204 287/179/287 203/176/203 +f 205/180/205 289/181/289 204/178/204 +f 206/182/206 292/183/292 205/180/205 +f 207/184/207 296/185/296 206/182/206 +f 208/39/208 301/186/301 207/184/207 +f 202/173/202 286/177/286 188/174/188 +f 286/177/286 189/187/189 188/174/188 +f 203/176/203 287/179/287 286/177/286 +f 287/179/287 288/188/288 286/177/286 +f 286/177/286 288/188/288 189/187/189 +f 288/188/288 190/189/190 189/187/189 +f 204/178/204 289/181/289 287/179/287 +f 289/181/289 290/190/290 287/179/287 +f 287/179/287 290/190/290 288/188/288 +f 290/190/290 291/191/291 288/188/288 +f 288/188/288 291/191/291 190/189/190 +f 291/191/291 191/192/191 190/189/190 +f 205/180/205 292/183/292 289/181/289 +f 292/183/292 293/193/293 289/181/289 +f 289/181/289 293/193/293 290/190/290 +f 293/193/293 294/194/294 290/190/290 +f 290/190/290 294/194/294 291/191/291 +f 294/194/294 295/195/295 291/191/291 +f 291/191/291 295/195/295 191/192/191 +f 295/195/295 192/196/192 191/192/191 +f 206/182/206 296/185/296 292/183/292 +f 296/185/296 297/197/297 292/183/292 +f 292/183/292 297/197/297 293/193/293 +f 297/197/297 298/198/298 293/193/293 +f 293/193/293 298/198/298 294/194/294 +f 298/198/298 299/199/299 294/194/294 +f 294/194/294 299/199/299 295/195/295 +f 299/199/299 300/200/300 295/195/295 +f 295/195/295 300/200/300 192/196/192 +f 300/200/300 193/201/193 192/196/192 +f 207/184/207 301/186/301 296/185/296 +f 301/186/301 302/202/302 296/185/296 +f 296/185/296 302/202/302 297/197/297 +f 302/202/302 303/203/303 297/197/297 +f 297/197/297 303/203/303 298/198/298 +f 303/203/303 304/204/304 298/198/298 +f 298/198/298 304/204/304 299/199/299 +f 304/204/304 305/205/305 299/199/299 +f 299/199/299 305/205/305 300/200/300 +f 305/205/305 306/206/306 300/200/300 +f 300/200/300 306/206/306 193/201/193 +f 306/206/306 194/207/194 193/201/193 +f 208/39/208 166/38/166 301/186/301 +f 166/38/166 165/208/165 301/186/301 +f 301/186/301 165/208/165 302/202/302 +f 165/208/165 164/209/164 302/202/302 +f 302/202/302 164/209/164 303/203/303 +f 164/209/164 163/210/163 303/203/303 +f 303/203/303 163/210/163 304/204/304 +f 163/210/163 162/211/162 304/204/304 +f 304/204/304 162/211/162 305/205/305 +f 162/211/162 161/212/161 305/205/305 +f 305/205/305 161/212/161 306/206/306 +f 161/212/161 160/213/160 306/206/306 +f 306/206/306 160/213/160 194/207/194 +f 160/213/160 7/34/7 194/207/194 +f 188/214/188 201/215/201 12/216/12 +f 189/217/189 307/218/307 188/214/188 +f 190/219/190 308/220/308 189/217/189 +f 191/221/191 310/222/310 190/219/190 +f 192/223/192 313/224/313 191/221/191 +f 193/225/193 317/226/317 192/223/192 +f 194/36/194 322/227/322 193/225/193 +f 188/214/188 307/218/307 201/215/201 +f 307/218/307 200/228/200 201/215/201 +f 189/217/189 308/220/308 307/218/307 +f 308/220/308 309/229/309 307/218/307 +f 307/218/307 309/229/309 200/228/200 +f 309/229/309 199/230/199 200/228/200 +f 190/219/190 310/222/310 308/220/308 +f 310/222/310 311/231/311 308/220/308 +f 308/220/308 311/231/311 309/229/309 +f 311/231/311 312/232/312 309/229/309 +f 309/229/309 312/232/312 199/230/199 +f 312/232/312 198/233/198 199/230/199 +f 191/221/191 313/224/313 310/222/310 +f 313/224/313 314/234/314 310/222/310 +f 310/222/310 314/234/314 311/231/311 +f 314/234/314 315/235/315 311/231/311 +f 311/231/311 315/235/315 312/232/312 +f 315/235/315 316/236/316 312/232/312 +f 312/232/312 316/236/316 198/233/198 +f 316/236/316 197/237/197 198/233/198 +f 192/223/192 317/226/317 313/224/313 +f 317/226/317 318/238/318 313/224/313 +f 313/224/313 318/238/318 314/234/314 +f 318/238/318 319/239/319 314/234/314 +f 314/234/314 319/239/319 315/235/315 +f 319/239/319 320/240/320 315/235/315 +f 315/235/315 320/240/320 316/236/316 +f 320/240/320 321/241/321 316/236/316 +f 316/236/316 321/241/321 197/237/197 +f 321/241/321 196/242/196 197/237/197 +f 193/225/193 322/227/322 317/226/317 +f 322/227/322 323/243/323 317/226/317 +f 317/226/317 323/243/323 318/238/318 +f 323/243/323 324/244/324 318/238/318 +f 318/238/318 324/244/324 319/239/319 +f 324/244/324 325/245/325 319/239/319 +f 319/239/319 325/245/325 320/240/320 +f 325/245/325 326/246/326 320/240/320 +f 320/240/320 326/246/326 321/241/321 +f 326/246/326 327/247/327 321/241/321 +f 321/241/321 327/247/327 196/242/196 +f 327/247/327 195/248/195 196/242/196 +f 194/36/194 159/35/159 322/227/322 +f 159/35/159 158/249/158 322/227/322 +f 322/227/322 158/249/158 323/243/323 +f 158/249/158 157/250/157 323/243/323 +f 323/243/323 157/250/157 324/244/324 +f 157/250/157 156/251/156 324/244/324 +f 324/244/324 156/251/156 325/245/325 +f 156/251/156 155/252/155 325/245/325 +f 325/245/325 155/252/155 326/246/326 +f 155/252/155 154/253/154 326/246/326 +f 326/246/326 154/253/154 327/247/327 +f 154/253/154 153/254/153 327/247/327 +f 327/247/327 153/254/153 195/248/195 +f 153/254/153 11/46/11 195/248/195 +f 96/255/96 187/47/187 11/46/11 +f 95/256/95 328/257/328 96/255/96 +f 94/258/94 329/259/329 95/256/95 +f 93/260/93 331/261/331 94/258/94 +f 92/262/92 334/263/334 93/260/93 +f 91/264/91 338/265/338 92/262/92 +f 90/33/90 343/266/343 91/264/91 +f 96/255/96 328/257/328 187/47/187 +f 328/257/328 186/84/186 187/47/187 +f 95/256/95 329/259/329 328/257/328 +f 329/259/329 330/267/330 328/257/328 +f 328/257/328 330/267/330 186/84/186 +f 330/267/330 185/85/185 186/84/186 +f 94/258/94 331/261/331 329/259/329 +f 331/261/331 332/268/332 329/259/329 +f 329/259/329 332/268/332 330/267/330 +f 332/268/332 333/269/333 330/267/330 +f 330/267/330 333/269/333 185/85/185 +f 333/269/333 184/86/184 185/85/185 +f 93/260/93 334/263/334 331/261/331 +f 334/263/334 335/270/335 331/261/331 +f 331/261/331 335/270/335 332/268/332 +f 335/270/335 336/271/336 332/268/332 +f 332/268/332 336/271/336 333/269/333 +f 336/271/336 337/272/337 333/269/333 +f 333/269/333 337/272/337 184/86/184 +f 337/272/337 183/87/183 184/86/184 +f 92/262/92 338/265/338 334/263/334 +f 338/265/338 339/273/339 334/263/334 +f 334/263/334 339/273/339 335/270/335 +f 339/273/339 340/274/340 335/270/335 +f 335/270/335 340/274/340 336/271/336 +f 340/274/340 341/275/341 336/271/336 +f 336/271/336 341/275/341 337/272/337 +f 341/275/341 342/276/342 337/272/337 +f 337/272/337 342/276/342 183/87/183 +f 342/276/342 182/88/182 183/87/183 +f 91/264/91 343/266/343 338/265/338 +f 343/266/343 344/277/344 338/265/338 +f 338/265/338 344/277/344 339/273/339 +f 344/277/344 345/278/345 339/273/339 +f 339/273/339 345/278/345 340/274/340 +f 345/278/345 346/279/346 340/274/340 +f 340/274/340 346/279/346 341/275/341 +f 346/279/346 347/280/347 341/275/341 +f 341/275/341 347/280/347 342/276/342 +f 347/280/347 348/281/348 342/276/342 +f 342/276/342 348/281/348 182/88/182 +f 348/281/348 181/89/181 182/88/182 +f 90/33/90 145/28/145 343/266/343 +f 145/28/145 144/282/144 343/266/343 +f 343/266/343 144/282/144 344/277/344 +f 144/282/144 143/283/143 344/277/344 +f 344/277/344 143/283/143 345/278/345 +f 143/283/143 142/284/142 345/278/345 +f 345/278/345 142/284/142 346/279/346 +f 142/284/142 141/285/141 346/279/346 +f 346/279/346 141/285/141 347/280/347 +f 141/285/141 140/286/140 347/280/347 +f 347/280/347 140/286/140 348/281/348 +f 140/286/140 139/287/139 348/281/348 +f 348/281/348 139/287/139 181/89/181 +f 139/287/139 10/43/10 181/89/181 +f 152/288/152 180/44/180 10/43/10 +f 151/289/151 349/290/349 152/288/152 +f 150/291/150 350/292/350 151/289/151 +f 149/293/149 352/294/352 150/291/150 +f 148/295/148 355/296/355 149/293/149 +f 147/297/147 359/298/359 148/295/148 +f 146/32/146 364/299/364 147/297/147 +f 152/288/152 349/290/349 180/44/180 +f 349/290/349 179/125/179 180/44/180 +f 151/289/151 350/292/350 349/290/349 +f 350/292/350 351/300/351 349/290/349 +f 349/290/349 351/300/351 179/125/179 +f 351/300/351 178/126/178 179/125/179 +f 150/291/150 352/294/352 350/292/350 +f 352/294/352 353/301/353 350/292/350 +f 350/292/350 353/301/353 351/300/351 +f 353/301/353 354/302/354 351/300/351 +f 351/300/351 354/302/354 178/126/178 +f 354/302/354 177/127/177 178/126/178 +f 149/293/149 355/296/355 352/294/352 +f 355/296/355 356/303/356 352/294/352 +f 352/294/352 356/303/356 353/301/353 +f 356/303/356 357/304/357 353/301/353 +f 353/301/353 357/304/357 354/302/354 +f 357/304/357 358/305/358 354/302/354 +f 354/302/354 358/305/358 177/127/177 +f 358/305/358 176/128/176 177/127/177 +f 148/295/148 359/298/359 355/296/355 +f 359/298/359 360/306/360 355/296/355 +f 355/296/355 360/306/360 356/303/356 +f 360/306/360 361/307/361 356/303/356 +f 356/303/356 361/307/361 357/304/357 +f 361/307/361 362/308/362 357/304/357 +f 357/304/357 362/308/362 358/305/358 +f 362/308/362 363/309/363 358/305/358 +f 358/305/358 363/309/363 176/128/176 +f 363/309/363 175/129/175 176/128/176 +f 147/297/147 364/299/364 359/298/359 +f 364/299/364 365/310/365 359/298/359 +f 359/298/359 365/310/365 360/306/360 +f 365/310/365 366/311/366 360/306/360 +f 360/306/360 366/311/366 361/307/361 +f 366/311/366 367/312/367 361/307/361 +f 361/307/361 367/312/367 362/308/362 +f 367/312/367 368/313/368 362/308/362 +f 362/308/362 368/313/368 363/309/363 +f 368/313/368 369/314/369 363/309/363 +f 363/309/363 369/314/369 175/129/175 +f 369/314/369 174/130/174 175/129/175 +f 146/32/146 131/25/131 364/299/364 +f 131/25/131 130/315/130 364/299/364 +f 364/299/364 130/315/130 365/310/365 +f 130/315/130 129/316/129 365/310/365 +f 365/310/365 129/316/129 366/311/366 +f 129/316/129 128/317/128 366/311/366 +f 366/311/366 128/317/128 367/312/367 +f 128/317/128 127/318/127 367/312/367 +f 367/312/367 127/318/127 368/313/368 +f 127/318/127 126/319/126 368/313/368 +f 368/313/368 126/319/126 369/314/369 +f 126/319/126 125/320/125 369/314/369 +f 369/314/369 125/320/125 174/130/174 +f 125/320/125 9/40/9 174/130/174 +f 138/321/138 173/41/173 9/40/9 +f 137/322/137 370/323/370 138/321/138 +f 136/324/136 371/325/371 137/322/137 +f 135/326/135 373/327/373 136/324/136 +f 134/328/134 376/329/376 135/326/135 +f 133/330/133 380/331/380 134/328/134 +f 132/31/132 385/332/385 133/330/133 +f 138/321/138 370/323/370 173/41/173 +f 370/323/370 172/166/172 173/41/173 +f 137/322/137 371/325/371 370/323/370 +f 371/325/371 372/333/372 370/323/370 +f 370/323/370 372/333/372 172/166/172 +f 372/333/372 171/167/171 172/166/172 +f 136/324/136 373/327/373 371/325/371 +f 373/327/373 374/334/374 371/325/371 +f 371/325/371 374/334/374 372/333/372 +f 374/334/374 375/335/375 372/333/372 +f 372/333/372 375/335/375 171/167/171 +f 375/335/375 170/168/170 171/167/171 +f 135/326/135 376/329/376 373/327/373 +f 376/329/376 377/336/377 373/327/373 +f 373/327/373 377/336/377 374/334/374 +f 377/336/377 378/337/378 374/334/374 +f 374/334/374 378/337/378 375/335/375 +f 378/337/378 379/338/379 375/335/375 +f 375/335/375 379/338/379 170/168/170 +f 379/338/379 169/169/169 170/168/170 +f 134/328/134 380/331/380 376/329/376 +f 380/331/380 381/339/381 376/329/376 +f 376/329/376 381/339/381 377/336/377 +f 381/339/381 382/340/382 377/336/377 +f 377/336/377 382/340/382 378/337/378 +f 382/340/382 383/341/383 378/337/378 +f 378/337/378 383/341/383 379/338/379 +f 383/341/383 384/342/384 379/338/379 +f 379/338/379 384/342/384 169/169/169 +f 384/342/384 168/170/168 169/169/169 +f 133/330/133 385/332/385 380/331/380 +f 385/332/385 386/343/386 380/331/380 +f 380/331/380 386/343/386 381/339/381 +f 386/343/386 387/344/387 381/339/381 +f 381/339/381 387/344/387 382/340/382 +f 387/344/387 388/345/388 382/340/382 +f 382/340/382 388/345/388 383/341/383 +f 388/345/388 389/346/389 383/341/383 +f 383/341/383 389/346/389 384/342/384 +f 389/346/389 390/347/390 384/342/384 +f 384/342/384 390/347/390 168/170/168 +f 390/347/390 167/171/167 168/170/168 +f 132/31/132 117/22/117 385/332/385 +f 117/22/117 116/348/116 385/332/385 +f 385/332/385 116/348/116 386/343/386 +f 116/348/116 115/349/115 386/343/386 +f 386/343/386 115/349/115 387/344/387 +f 115/349/115 114/350/114 387/344/387 +f 387/344/387 114/350/114 388/345/388 +f 114/350/114 113/351/113 388/345/388 +f 388/345/388 113/351/113 389/346/389 +f 113/351/113 112/352/112 389/346/389 +f 389/346/389 112/352/112 390/347/390 +f 112/352/112 111/353/111 390/347/390 +f 390/347/390 111/353/111 167/171/167 +f 111/353/111 8/172/8 167/171/167 +f 124/354/124 166/38/166 8/37/8 +f 123/355/123 391/356/391 124/354/124 +f 122/357/122 392/358/392 123/355/123 +f 121/359/121 394/360/394 122/357/122 +f 120/361/120 397/362/397 121/359/121 +f 119/363/119 401/364/401 120/361/120 +f 118/30/118 406/365/406 119/363/119 +f 124/354/124 391/356/391 166/38/166 +f 391/356/391 165/208/165 166/38/166 +f 123/355/123 392/358/392 391/356/391 +f 392/358/392 393/366/393 391/356/391 +f 391/356/391 393/366/393 165/208/165 +f 393/366/393 164/209/164 165/208/165 +f 122/357/122 394/360/394 392/358/392 +f 394/360/394 395/367/395 392/358/392 +f 392/358/392 395/367/395 393/366/393 +f 395/367/395 396/368/396 393/366/393 +f 393/366/393 396/368/396 164/209/164 +f 396/368/396 163/210/163 164/209/164 +f 121/359/121 397/362/397 394/360/394 +f 397/362/397 398/369/398 394/360/394 +f 394/360/394 398/369/398 395/367/395 +f 398/369/398 399/370/399 395/367/395 +f 395/367/395 399/370/399 396/368/396 +f 399/370/399 400/371/400 396/368/396 +f 396/368/396 400/371/400 163/210/163 +f 400/371/400 162/211/162 163/210/163 +f 120/361/120 401/364/401 397/362/397 +f 401/364/401 402/372/402 397/362/397 +f 397/362/397 402/372/402 398/369/398 +f 402/372/402 403/373/403 398/369/398 +f 398/369/398 403/373/403 399/370/399 +f 403/373/403 404/374/404 399/370/399 +f 399/370/399 404/374/404 400/371/400 +f 404/374/404 405/375/405 400/371/400 +f 400/371/400 405/375/405 162/211/162 +f 405/375/405 161/212/161 162/211/162 +f 119/363/119 406/365/406 401/364/401 +f 406/365/406 407/376/407 401/364/401 +f 401/364/401 407/376/407 402/372/402 +f 407/376/407 408/377/408 402/372/402 +f 402/372/402 408/377/408 403/373/403 +f 408/377/408 409/378/409 403/373/403 +f 403/373/403 409/378/409 404/374/404 +f 409/378/409 410/379/410 404/374/404 +f 404/374/404 410/379/410 405/375/405 +f 410/379/410 411/380/411 405/375/405 +f 405/375/405 411/380/411 161/212/161 +f 411/380/411 160/213/160 161/212/161 +f 118/30/118 103/19/103 406/365/406 +f 103/19/103 102/381/102 406/365/406 +f 406/365/406 102/381/102 407/376/407 +f 102/381/102 101/382/101 407/376/407 +f 407/376/407 101/382/101 408/377/408 +f 101/382/101 100/383/100 408/377/408 +f 408/377/408 100/383/100 409/378/409 +f 100/383/100 99/384/99 409/378/409 +f 409/378/409 99/384/99 410/379/410 +f 99/384/99 98/385/98 410/379/410 +f 410/379/410 98/385/98 411/380/411 +f 98/385/98 97/386/97 411/380/411 +f 411/380/411 97/386/97 160/213/160 +f 97/386/97 7/34/7 160/213/160 +f 110/387/110 159/35/159 7/34/7 +f 109/388/109 412/389/412 110/387/110 +f 108/390/108 413/391/413 109/388/109 +f 107/392/107 415/393/415 108/390/108 +f 106/394/106 418/395/418 107/392/107 +f 105/396/105 422/397/422 106/394/106 +f 104/29/104 427/398/427 105/396/105 +f 110/387/110 412/389/412 159/35/159 +f 412/389/412 158/249/158 159/35/159 +f 109/388/109 413/391/413 412/389/412 +f 413/391/413 414/399/414 412/389/412 +f 412/389/412 414/399/414 158/249/158 +f 414/399/414 157/250/157 158/249/158 +f 108/390/108 415/393/415 413/391/413 +f 415/393/415 416/400/416 413/391/413 +f 413/391/413 416/400/416 414/399/414 +f 416/400/416 417/401/417 414/399/414 +f 414/399/414 417/401/417 157/250/157 +f 417/401/417 156/251/156 157/250/157 +f 107/392/107 418/395/418 415/393/415 +f 418/395/418 419/402/419 415/393/415 +f 415/393/415 419/402/419 416/400/416 +f 419/402/419 420/403/420 416/400/416 +f 416/400/416 420/403/420 417/401/417 +f 420/403/420 421/404/421 417/401/417 +f 417/401/417 421/404/421 156/251/156 +f 421/404/421 155/252/155 156/251/156 +f 106/394/106 422/397/422 418/395/418 +f 422/397/422 423/405/423 418/395/418 +f 418/395/418 423/405/423 419/402/419 +f 423/405/423 424/406/424 419/402/419 +f 419/402/419 424/406/424 420/403/420 +f 424/406/424 425/407/425 420/403/420 +f 420/403/420 425/407/425 421/404/421 +f 425/407/425 426/408/426 421/404/421 +f 421/404/421 426/408/426 155/252/155 +f 426/408/426 154/253/154 155/252/155 +f 105/396/105 427/398/427 422/397/422 +f 427/398/427 428/409/428 422/397/422 +f 422/397/422 428/409/428 423/405/423 +f 428/409/428 429/410/429 423/405/423 +f 423/405/423 429/410/429 424/406/424 +f 429/410/429 430/411/430 424/406/424 +f 424/406/424 430/411/430 425/407/425 +f 430/411/430 431/412/431 425/407/425 +f 425/407/425 431/412/431 426/408/426 +f 431/412/431 432/413/432 426/408/426 +f 426/408/426 432/413/432 154/253/154 +f 432/413/432 153/254/153 154/253/154 +f 104/29/104 89/16/89 427/398/427 +f 89/16/89 88/414/88 427/398/427 +f 427/398/427 88/414/88 428/409/428 +f 88/414/88 87/415/87 428/409/428 +f 428/409/428 87/415/87 429/410/429 +f 87/415/87 86/416/86 429/410/429 +f 429/410/429 86/416/86 430/411/430 +f 86/416/86 85/417/85 430/411/430 +f 430/411/430 85/417/85 431/412/431 +f 85/417/85 84/418/84 431/412/431 +f 431/412/431 84/418/84 432/413/432 +f 84/418/84 83/419/83 432/413/432 +f 432/413/432 83/419/83 153/254/153 +f 83/419/83 11/46/11 153/254/153 +f 139/287/139 152/288/152 10/43/10 +f 140/286/140 433/420/433 139/287/139 +f 141/285/141 434/421/434 140/286/140 +f 142/284/142 436/422/436 141/285/141 +f 143/283/143 439/423/439 142/284/142 +f 144/282/144 443/424/443 143/283/143 +f 145/28/145 448/425/448 144/282/144 +f 139/287/139 433/420/433 152/288/152 +f 433/420/433 151/289/151 152/288/152 +f 140/286/140 434/421/434 433/420/433 +f 434/421/434 435/426/435 433/420/433 +f 433/420/433 435/426/435 151/289/151 +f 435/426/435 150/291/150 151/289/151 +f 141/285/141 436/422/436 434/421/434 +f 436/422/436 437/427/437 434/421/434 +f 434/421/434 437/427/437 435/426/435 +f 437/427/437 438/428/438 435/426/435 +f 435/426/435 438/428/438 150/291/150 +f 438/428/438 149/293/149 150/291/150 +f 142/284/142 439/423/439 436/422/436 +f 439/423/439 440/429/440 436/422/436 +f 436/422/436 440/429/440 437/427/437 +f 440/429/440 441/430/441 437/427/437 +f 437/427/437 441/430/441 438/428/438 +f 441/430/441 442/431/442 438/428/438 +f 438/428/438 442/431/442 149/293/149 +f 442/431/442 148/295/148 149/293/149 +f 143/283/143 443/424/443 439/423/439 +f 443/424/443 444/432/444 439/423/439 +f 439/423/439 444/432/444 440/429/440 +f 444/432/444 445/433/445 440/429/440 +f 440/429/440 445/433/445 441/430/441 +f 445/433/445 446/434/446 441/430/441 +f 441/430/441 446/434/446 442/431/442 +f 446/434/446 447/435/447 442/431/442 +f 442/431/442 447/435/447 148/295/148 +f 447/435/447 147/297/147 148/295/148 +f 144/282/144 448/425/448 443/424/443 +f 448/425/448 449/436/449 443/424/443 +f 443/424/443 449/436/449 444/432/444 +f 449/436/449 450/437/450 444/432/444 +f 444/432/444 450/437/450 445/433/445 +f 450/437/450 451/438/451 445/433/445 +f 445/433/445 451/438/451 446/434/446 +f 451/438/451 452/439/452 446/434/446 +f 446/434/446 452/439/452 447/435/447 +f 452/439/452 453/440/453 447/435/447 +f 447/435/447 453/440/453 147/297/147 +f 453/440/453 146/32/146 147/297/147 +f 145/28/145 82/27/82 448/425/448 +f 82/27/82 81/441/81 448/425/448 +f 448/425/448 81/441/81 449/436/449 +f 81/441/81 80/442/80 449/436/449 +f 449/436/449 80/442/80 450/437/450 +f 80/442/80 79/443/79 450/437/450 +f 450/437/450 79/443/79 451/438/451 +f 79/443/79 78/444/78 451/438/451 +f 451/438/451 78/444/78 452/439/452 +f 78/444/78 77/445/77 452/439/452 +f 452/439/452 77/445/77 453/440/453 +f 77/445/77 76/446/76 453/440/453 +f 453/440/453 76/446/76 146/32/146 +f 76/446/76 5/23/5 146/32/146 +f 125/320/125 138/321/138 9/40/9 +f 126/319/126 454/447/454 125/320/125 +f 127/318/127 455/448/455 126/319/126 +f 128/317/128 457/449/457 127/318/127 +f 129/316/129 460/450/460 128/317/128 +f 130/315/130 464/451/464 129/316/129 +f 131/25/131 469/452/469 130/315/130 +f 125/320/125 454/447/454 138/321/138 +f 454/447/454 137/322/137 138/321/138 +f 126/319/126 455/448/455 454/447/454 +f 455/448/455 456/453/456 454/447/454 +f 454/447/454 456/453/456 137/322/137 +f 456/453/456 136/324/136 137/322/137 +f 127/318/127 457/449/457 455/448/455 +f 457/449/457 458/454/458 455/448/455 +f 455/448/455 458/454/458 456/453/456 +f 458/454/458 459/455/459 456/453/456 +f 456/453/456 459/455/459 136/324/136 +f 459/455/459 135/326/135 136/324/136 +f 128/317/128 460/450/460 457/449/457 +f 460/450/460 461/456/461 457/449/457 +f 457/449/457 461/456/461 458/454/458 +f 461/456/461 462/457/462 458/454/458 +f 458/454/458 462/457/462 459/455/459 +f 462/457/462 463/458/463 459/455/459 +f 459/455/459 463/458/463 135/326/135 +f 463/458/463 134/328/134 135/326/135 +f 129/316/129 464/451/464 460/450/460 +f 464/451/464 465/459/465 460/450/460 +f 460/450/460 465/459/465 461/456/461 +f 465/459/465 466/460/466 461/456/461 +f 461/456/461 466/460/466 462/457/462 +f 466/460/466 467/461/467 462/457/462 +f 462/457/462 467/461/467 463/458/463 +f 467/461/467 468/462/468 463/458/463 +f 463/458/463 468/462/468 134/328/134 +f 468/462/468 133/330/133 134/328/134 +f 130/315/130 469/452/469 464/451/464 +f 469/452/469 470/463/470 464/451/464 +f 464/451/464 470/463/470 465/459/465 +f 470/463/470 471/464/471 465/459/465 +f 465/459/465 471/464/471 466/460/466 +f 471/464/471 472/465/472 466/460/466 +f 466/460/466 472/465/472 467/461/467 +f 472/465/472 473/466/473 467/461/467 +f 467/461/467 473/466/473 468/462/468 +f 473/466/473 474/467/474 468/462/468 +f 468/462/468 474/467/474 133/330/133 +f 474/467/474 132/31/132 133/330/133 +f 131/25/131 75/24/75 469/452/469 +f 75/24/75 74/468/74 469/452/469 +f 469/452/469 74/468/74 470/463/470 +f 74/468/74 73/469/73 470/463/470 +f 470/463/470 73/469/73 471/464/471 +f 73/469/73 72/470/72 471/464/471 +f 471/464/471 72/470/72 472/465/472 +f 72/470/72 71/471/71 472/465/472 +f 472/465/472 71/471/71 473/466/473 +f 71/471/71 70/472/70 473/466/473 +f 473/466/473 70/472/70 474/467/474 +f 70/472/70 69/473/69 474/467/474 +f 474/467/474 69/473/69 132/31/132 +f 69/473/69 4/20/4 132/31/132 +f 111/353/111 124/474/124 8/172/8 +f 112/352/112 475/475/475 111/353/111 +f 113/351/113 476/476/476 112/352/112 +f 114/350/114 478/477/478 113/351/113 +f 115/349/115 481/478/481 114/350/114 +f 116/348/116 485/479/485 115/349/115 +f 117/22/117 490/480/490 116/348/116 +f 111/353/111 475/475/475 124/474/124 +f 475/475/475 123/481/123 124/474/124 +f 112/352/112 476/476/476 475/475/475 +f 476/476/476 477/482/477 475/475/475 +f 475/475/475 477/482/477 123/481/123 +f 477/482/477 122/483/122 123/481/123 +f 113/351/113 478/477/478 476/476/476 +f 478/477/478 479/484/479 476/476/476 +f 476/476/476 479/484/479 477/482/477 +f 479/484/479 480/485/480 477/482/477 +f 477/482/477 480/485/480 122/483/122 +f 480/485/480 121/486/121 122/483/122 +f 114/350/114 481/478/481 478/477/478 +f 481/478/481 482/487/482 478/477/478 +f 478/477/478 482/487/482 479/484/479 +f 482/487/482 483/488/483 479/484/479 +f 479/484/479 483/488/483 480/485/480 +f 483/488/483 484/489/484 480/485/480 +f 480/485/480 484/489/484 121/486/121 +f 484/489/484 120/490/120 121/486/121 +f 115/349/115 485/479/485 481/478/481 +f 485/479/485 486/491/486 481/478/481 +f 481/478/481 486/491/486 482/487/482 +f 486/491/486 487/492/487 482/487/482 +f 482/487/482 487/492/487 483/488/483 +f 487/492/487 488/493/488 483/488/483 +f 483/488/483 488/493/488 484/489/484 +f 488/493/488 489/494/489 484/489/484 +f 484/489/484 489/494/489 120/490/120 +f 489/494/489 119/495/119 120/490/120 +f 116/348/116 490/480/490 485/479/485 +f 490/480/490 491/496/491 485/479/485 +f 485/479/485 491/496/491 486/491/486 +f 491/496/491 492/497/492 486/491/486 +f 486/491/486 492/497/492 487/492/487 +f 492/497/492 493/498/493 487/492/487 +f 487/492/487 493/498/493 488/493/488 +f 493/498/493 494/499/494 488/493/488 +f 488/493/488 494/499/494 489/494/489 +f 494/499/494 495/500/495 489/494/489 +f 489/494/489 495/500/495 119/495/119 +f 495/500/495 118/501/118 119/495/119 +f 117/22/117 61/21/61 490/480/490 +f 61/21/61 60/502/60 490/480/490 +f 490/480/490 60/502/60 491/496/491 +f 60/502/60 59/503/59 491/496/491 +f 491/496/491 59/503/59 492/497/492 +f 59/503/59 58/504/58 492/497/492 +f 492/497/492 58/504/58 493/498/493 +f 58/504/58 57/505/57 493/498/493 +f 493/498/493 57/505/57 494/499/494 +f 57/505/57 56/506/56 494/499/494 +f 494/499/494 56/506/56 495/500/495 +f 56/506/56 55/507/55 495/500/495 +f 495/500/495 55/507/55 118/501/118 +f 55/507/55 3/508/3 118/501/118 +f 97/386/97 110/387/110 7/34/7 +f 98/385/98 496/509/496 97/386/97 +f 99/384/99 497/510/497 98/385/98 +f 100/383/100 499/511/499 99/384/99 +f 101/382/101 502/512/502 100/383/100 +f 102/381/102 506/513/506 101/382/101 +f 103/19/103 511/514/511 102/381/102 +f 97/386/97 496/509/496 110/387/110 +f 496/509/496 109/388/109 110/387/110 +f 98/385/98 497/510/497 496/509/496 +f 497/510/497 498/515/498 496/509/496 +f 496/509/496 498/515/498 109/388/109 +f 498/515/498 108/390/108 109/388/109 +f 99/384/99 499/511/499 497/510/497 +f 499/511/499 500/516/500 497/510/497 +f 497/510/497 500/516/500 498/515/498 +f 500/516/500 501/517/501 498/515/498 +f 498/515/498 501/517/501 108/390/108 +f 501/517/501 107/392/107 108/390/108 +f 100/383/100 502/512/502 499/511/499 +f 502/512/502 503/518/503 499/511/499 +f 499/511/499 503/518/503 500/516/500 +f 503/518/503 504/519/504 500/516/500 +f 500/516/500 504/519/504 501/517/501 +f 504/519/504 505/520/505 501/517/501 +f 501/517/501 505/520/505 107/392/107 +f 505/520/505 106/394/106 107/392/107 +f 101/382/101 506/513/506 502/512/502 +f 506/513/506 507/521/507 502/512/502 +f 502/512/502 507/521/507 503/518/503 +f 507/521/507 508/522/508 503/518/503 +f 503/518/503 508/522/508 504/519/504 +f 508/522/508 509/523/509 504/519/504 +f 504/519/504 509/523/509 505/520/505 +f 509/523/509 510/524/510 505/520/505 +f 505/520/505 510/524/510 106/394/106 +f 510/524/510 105/396/105 106/394/106 +f 102/381/102 511/514/511 506/513/506 +f 511/514/511 512/525/512 506/513/506 +f 506/513/506 512/525/512 507/521/507 +f 512/525/512 513/526/513 507/521/507 +f 507/521/507 513/526/513 508/522/508 +f 513/526/513 514/527/514 508/522/508 +f 508/522/508 514/527/514 509/523/509 +f 514/527/514 515/528/515 509/523/509 +f 509/523/509 515/528/515 510/524/510 +f 515/528/515 516/529/516 510/524/510 +f 510/524/510 516/529/516 105/396/105 +f 516/529/516 104/29/104 105/396/105 +f 103/19/103 33/18/33 511/514/511 +f 33/18/33 32/530/32 511/514/511 +f 511/514/511 32/530/32 512/525/512 +f 32/530/32 31/531/31 512/525/512 +f 512/525/512 31/531/31 513/526/513 +f 31/531/31 30/532/30 513/526/513 +f 513/526/513 30/532/30 514/527/514 +f 30/532/30 29/533/29 514/527/514 +f 514/527/514 29/533/29 515/528/515 +f 29/533/29 28/534/28 515/528/515 +f 515/528/515 28/534/28 516/529/516 +f 28/534/28 27/535/27 516/529/516 +f 516/529/516 27/535/27 104/29/104 +f 27/535/27 2/4/2 104/29/104 +f 83/419/83 96/255/96 11/46/11 +f 84/418/84 517/536/517 83/419/83 +f 85/417/85 518/537/518 84/418/84 +f 86/416/86 520/538/520 85/417/85 +f 87/415/87 523/539/523 86/416/86 +f 88/414/88 527/540/527 87/415/87 +f 89/16/89 532/541/532 88/414/88 +f 83/419/83 517/536/517 96/255/96 +f 517/536/517 95/256/95 96/255/96 +f 84/418/84 518/537/518 517/536/517 +f 518/537/518 519/542/519 517/536/517 +f 517/536/517 519/542/519 95/256/95 +f 519/542/519 94/258/94 95/256/95 +f 85/417/85 520/538/520 518/537/518 +f 520/538/520 521/543/521 518/537/518 +f 518/537/518 521/543/521 519/542/519 +f 521/543/521 522/544/522 519/542/519 +f 519/542/519 522/544/522 94/258/94 +f 522/544/522 93/260/93 94/258/94 +f 86/416/86 523/539/523 520/538/520 +f 523/539/523 524/545/524 520/538/520 +f 520/538/520 524/545/524 521/543/521 +f 524/545/524 525/546/525 521/543/521 +f 521/543/521 525/546/525 522/544/522 +f 525/546/525 526/547/526 522/544/522 +f 522/544/522 526/547/526 93/260/93 +f 526/547/526 92/262/92 93/260/93 +f 87/415/87 527/540/527 523/539/523 +f 527/540/527 528/548/528 523/539/523 +f 523/539/523 528/548/528 524/545/524 +f 528/548/528 529/549/529 524/545/524 +f 524/545/524 529/549/529 525/546/525 +f 529/549/529 530/550/530 525/546/525 +f 525/546/525 530/550/530 526/547/526 +f 530/550/530 531/551/531 526/547/526 +f 526/547/526 531/551/531 92/262/92 +f 531/551/531 91/264/91 92/262/92 +f 88/414/88 532/541/532 527/540/527 +f 532/541/532 533/552/533 527/540/527 +f 527/540/527 533/552/533 528/548/528 +f 533/552/533 534/553/534 528/548/528 +f 528/548/528 534/553/534 529/549/529 +f 534/553/534 535/554/535 529/549/529 +f 529/549/529 535/554/535 530/550/530 +f 535/554/535 536/555/536 530/550/530 +f 530/550/530 536/555/536 531/551/531 +f 536/555/536 537/556/537 531/551/531 +f 531/551/531 537/556/537 91/264/91 +f 537/556/537 90/33/90 91/264/91 +f 89/16/89 40/6/40 532/541/532 +f 40/6/40 39/557/39 532/541/532 +f 532/541/532 39/557/39 533/552/533 +f 39/557/39 38/558/38 533/552/533 +f 533/552/533 38/558/38 534/553/534 +f 38/558/38 37/559/37 534/553/534 +f 534/553/534 37/559/37 535/554/535 +f 37/559/37 36/560/36 535/554/535 +f 535/554/535 36/560/36 536/555/536 +f 36/560/36 35/561/35 536/555/536 +f 536/555/536 35/561/35 537/556/537 +f 35/561/35 34/562/34 537/556/537 +f 537/556/537 34/562/34 90/33/90 +f 34/562/34 6/26/6 90/33/90 +f 47/563/47 82/27/82 6/26/6 +f 46/564/46 538/565/538 47/563/47 +f 45/566/45 539/567/539 46/564/46 +f 44/568/44 541/569/541 45/566/45 +f 43/570/43 544/571/544 44/568/44 +f 42/572/42 548/573/548 43/570/43 +f 41/15/41 553/574/553 42/572/42 +f 47/563/47 538/565/538 82/27/82 +f 538/565/538 81/441/81 82/27/82 +f 46/564/46 539/567/539 538/565/538 +f 539/567/539 540/575/540 538/565/538 +f 538/565/538 540/575/540 81/441/81 +f 540/575/540 80/442/80 81/441/81 +f 45/566/45 541/569/541 539/567/539 +f 541/569/541 542/576/542 539/567/539 +f 539/567/539 542/576/542 540/575/540 +f 542/576/542 543/577/543 540/575/540 +f 540/575/540 543/577/543 80/442/80 +f 543/577/543 79/443/79 80/442/80 +f 44/568/44 544/571/544 541/569/541 +f 544/571/544 545/578/545 541/569/541 +f 541/569/541 545/578/545 542/576/542 +f 545/578/545 546/579/546 542/576/542 +f 542/576/542 546/579/546 543/577/543 +f 546/579/546 547/580/547 543/577/543 +f 543/577/543 547/580/547 79/443/79 +f 547/580/547 78/444/78 79/443/79 +f 43/570/43 548/573/548 544/571/544 +f 548/573/548 549/581/549 544/571/544 +f 544/571/544 549/581/549 545/578/545 +f 549/581/549 550/582/550 545/578/545 +f 545/578/545 550/582/550 546/579/546 +f 550/582/550 551/583/551 546/579/546 +f 546/579/546 551/583/551 547/580/547 +f 551/583/551 552/584/552 547/580/547 +f 547/580/547 552/584/552 78/444/78 +f 552/584/552 77/445/77 78/444/78 +f 42/572/42 553/574/553 548/573/548 +f 553/574/553 554/585/554 548/573/548 +f 548/573/548 554/585/554 549/581/549 +f 554/585/554 555/586/555 549/581/549 +f 549/581/549 555/586/555 550/582/550 +f 555/586/555 556/587/556 550/582/550 +f 550/582/550 556/587/556 551/583/551 +f 556/587/556 557/588/557 551/583/551 +f 551/583/551 557/588/557 552/584/552 +f 557/588/557 558/589/558 552/584/552 +f 552/584/552 558/589/558 77/445/77 +f 558/589/558 76/446/76 77/445/77 +f 41/15/41 68/14/68 553/574/553 +f 68/14/68 67/590/67 553/574/553 +f 553/574/553 67/590/67 554/585/554 +f 67/590/67 66/591/66 554/585/554 +f 554/585/554 66/591/66 555/586/555 +f 66/591/66 65/592/65 555/586/555 +f 555/586/555 65/592/65 556/587/556 +f 65/592/65 64/593/64 556/587/556 +f 556/587/556 64/593/64 557/588/557 +f 64/593/64 63/594/63 557/588/557 +f 557/588/557 63/594/63 558/589/558 +f 63/594/63 62/595/62 558/589/558 +f 558/589/558 62/595/62 76/446/76 +f 62/595/62 5/23/5 76/446/76 +f 62/596/62 75/24/75 5/23/5 +f 63/597/63 559/598/559 62/596/62 +f 64/599/64 560/600/560 63/597/63 +f 65/601/65 562/602/562 64/599/64 +f 66/603/66 565/604/565 65/601/65 +f 67/605/67 569/606/569 66/603/66 +f 68/12/68 574/607/574 67/605/67 +f 62/596/62 559/598/559 75/24/75 +f 559/598/559 74/468/74 75/24/75 +f 63/597/63 560/600/560 559/598/559 +f 560/600/560 561/608/561 559/598/559 +f 559/598/559 561/608/561 74/468/74 +f 561/608/561 73/469/73 74/468/74 +f 64/599/64 562/602/562 560/600/560 +f 562/602/562 563/609/563 560/600/560 +f 560/600/560 563/609/563 561/608/561 +f 563/609/563 564/610/564 561/608/561 +f 561/608/561 564/610/564 73/469/73 +f 564/610/564 72/470/72 73/469/73 +f 65/601/65 565/604/565 562/602/562 +f 565/604/565 566/611/566 562/602/562 +f 562/602/562 566/611/566 563/609/563 +f 566/611/566 567/612/567 563/609/563 +f 563/609/563 567/612/567 564/610/564 +f 567/612/567 568/613/568 564/610/564 +f 564/610/564 568/613/568 72/470/72 +f 568/613/568 71/471/71 72/470/72 +f 66/603/66 569/606/569 565/604/565 +f 569/606/569 570/614/570 565/604/565 +f 565/604/565 570/614/570 566/611/566 +f 570/614/570 571/615/571 566/611/566 +f 566/611/566 571/615/571 567/612/567 +f 571/615/571 572/616/572 567/612/567 +f 567/612/567 572/616/572 568/613/568 +f 572/616/572 573/617/573 568/613/568 +f 568/613/568 573/617/573 71/471/71 +f 573/617/573 70/472/70 71/471/71 +f 67/605/67 574/607/574 569/606/569 +f 574/607/574 575/618/575 569/606/569 +f 569/606/569 575/618/575 570/614/570 +f 575/618/575 576/619/576 570/614/570 +f 570/614/570 576/619/576 571/615/571 +f 576/619/576 577/620/577 571/615/571 +f 571/615/571 577/620/577 572/616/572 +f 577/620/577 578/621/578 572/616/572 +f 572/616/572 578/621/578 573/617/573 +f 578/621/578 579/622/579 573/617/573 +f 573/617/573 579/622/579 70/472/70 +f 579/622/579 69/473/69 70/472/70 +f 68/12/68 54/11/54 574/607/574 +f 54/11/54 53/623/53 574/607/574 +f 574/607/574 53/623/53 575/618/575 +f 53/623/53 52/624/52 575/618/575 +f 575/618/575 52/624/52 576/619/576 +f 52/624/52 51/625/51 576/619/576 +f 576/619/576 51/625/51 577/620/577 +f 51/625/51 50/626/50 577/620/577 +f 577/620/577 50/626/50 578/621/578 +f 50/626/50 49/627/49 578/621/578 +f 578/621/578 49/627/49 579/622/579 +f 49/627/49 48/628/48 579/622/579 +f 579/622/579 48/628/48 69/473/69 +f 48/628/48 4/20/4 69/473/69 +f 48/629/48 61/21/61 4/20/4 +f 49/630/49 580/631/580 48/629/48 +f 50/632/50 581/633/581 49/630/49 +f 51/634/51 583/635/583 50/632/50 +f 52/636/52 586/637/586 51/634/51 +f 53/638/53 590/639/590 52/636/52 +f 54/9/54 595/640/595 53/638/53 +f 48/629/48 580/631/580 61/21/61 +f 580/631/580 60/502/60 61/21/61 +f 49/630/49 581/633/581 580/631/580 +f 581/633/581 582/641/582 580/631/580 +f 580/631/580 582/641/582 60/502/60 +f 582/641/582 59/503/59 60/502/60 +f 50/632/50 583/635/583 581/633/581 +f 583/635/583 584/642/584 581/633/581 +f 581/633/581 584/642/584 582/641/582 +f 584/642/584 585/643/585 582/641/582 +f 582/641/582 585/643/585 59/503/59 +f 585/643/585 58/504/58 59/503/59 +f 51/634/51 586/637/586 583/635/583 +f 586/637/586 587/644/587 583/635/583 +f 583/635/583 587/644/587 584/642/584 +f 587/644/587 588/645/588 584/642/584 +f 584/642/584 588/645/588 585/643/585 +f 588/645/588 589/646/589 585/643/585 +f 585/643/585 589/646/589 58/504/58 +f 589/646/589 57/505/57 58/504/58 +f 52/636/52 590/639/590 586/637/586 +f 590/639/590 591/647/591 586/637/586 +f 586/637/586 591/647/591 587/644/587 +f 591/647/591 592/648/592 587/644/587 +f 587/644/587 592/648/592 588/645/588 +f 592/648/592 593/649/593 588/645/588 +f 588/645/588 593/649/593 589/646/589 +f 593/649/593 594/650/594 589/646/589 +f 589/646/589 594/650/594 57/505/57 +f 594/650/594 56/506/56 57/505/57 +f 53/638/53 595/640/595 590/639/590 +f 595/640/595 596/651/596 590/639/590 +f 590/639/590 596/651/596 591/647/591 +f 596/651/596 597/652/597 591/647/591 +f 591/647/591 597/652/597 592/648/592 +f 597/652/597 598/653/598 592/648/592 +f 592/648/592 598/653/598 593/649/593 +f 598/653/598 599/654/599 593/649/593 +f 593/649/593 599/654/599 594/650/594 +f 599/654/599 600/655/600 594/650/594 +f 594/650/594 600/655/600 56/506/56 +f 600/655/600 55/507/55 56/506/56 +f 54/9/54 19/8/19 595/640/595 +f 19/8/19 18/656/18 595/640/595 +f 595/640/595 18/656/18 596/651/596 +f 18/656/18 17/657/17 596/651/596 +f 596/651/596 17/657/17 597/652/597 +f 17/657/17 16/658/16 597/652/597 +f 597/652/597 16/658/16 598/653/598 +f 16/658/16 15/659/15 598/653/598 +f 598/653/598 15/659/15 599/654/599 +f 15/659/15 14/660/14 599/654/599 +f 599/654/599 14/660/14 600/655/600 +f 14/660/14 13/661/13 600/655/600 +f 600/655/600 13/661/13 55/507/55 +f 13/661/13 3/508/3 55/507/55 +f 34/562/34 47/662/47 6/26/6 +f 35/561/35 601/663/601 34/562/34 +f 36/560/36 602/664/602 35/561/35 +f 37/559/37 604/665/604 36/560/36 +f 38/558/38 607/666/607 37/559/37 +f 39/557/39 611/667/611 38/558/38 +f 40/6/40 616/668/616 39/557/39 +f 34/562/34 601/663/601 47/662/47 +f 601/663/601 46/669/46 47/662/47 +f 35/561/35 602/664/602 601/663/601 +f 602/664/602 603/670/603 601/663/601 +f 601/663/601 603/670/603 46/669/46 +f 603/670/603 45/671/45 46/669/46 +f 36/560/36 604/665/604 602/664/602 +f 604/665/604 605/672/605 602/664/602 +f 602/664/602 605/672/605 603/670/603 +f 605/672/605 606/673/606 603/670/603 +f 603/670/603 606/673/606 45/671/45 +f 606/673/606 44/674/44 45/671/45 +f 37/559/37 607/666/607 604/665/604 +f 607/666/607 608/675/608 604/665/604 +f 604/665/604 608/675/608 605/672/605 +f 608/675/608 609/676/609 605/672/605 +f 605/672/605 609/676/609 606/673/606 +f 609/676/609 610/677/610 606/673/606 +f 606/673/606 610/677/610 44/674/44 +f 610/677/610 43/678/43 44/674/44 +f 38/558/38 611/667/611 607/666/607 +f 611/667/611 612/679/612 607/666/607 +f 607/666/607 612/679/612 608/675/608 +f 612/679/612 613/680/613 608/675/608 +f 608/675/608 613/680/613 609/676/609 +f 613/680/613 614/681/614 609/676/609 +f 609/676/609 614/681/614 610/677/610 +f 614/681/614 615/682/615 610/677/610 +f 610/677/610 615/682/615 43/678/43 +f 615/682/615 42/683/42 43/678/43 +f 39/557/39 616/668/616 611/667/611 +f 616/668/616 617/684/617 611/667/611 +f 611/667/611 617/684/617 612/679/612 +f 617/684/617 618/685/618 612/679/612 +f 612/679/612 618/685/618 613/680/613 +f 618/685/618 619/686/619 613/680/613 +f 613/680/613 619/686/619 614/681/614 +f 619/686/619 620/687/620 614/681/614 +f 614/681/614 620/687/620 615/682/615 +f 620/687/620 621/688/621 615/682/615 +f 615/682/615 621/688/621 42/683/42 +f 621/688/621 41/689/41 42/683/42 +f 40/6/40 26/5/26 616/668/616 +f 26/5/26 25/690/25 616/668/616 +f 616/668/616 25/690/25 617/684/617 +f 25/690/25 24/691/24 617/684/617 +f 617/684/617 24/691/24 618/685/618 +f 24/691/24 23/692/23 618/685/618 +f 618/685/618 23/692/23 619/686/619 +f 23/692/23 22/693/22 619/686/619 +f 619/686/619 22/693/22 620/687/620 +f 22/693/22 21/694/21 620/687/620 +f 620/687/620 21/694/21 621/688/621 +f 21/694/21 20/695/20 621/688/621 +f 621/688/621 20/695/20 41/689/41 +f 20/695/20 1/696/1 41/689/41 +f 13/697/13 33/18/33 3/17/3 +f 14/698/14 622/699/622 13/697/13 +f 15/700/15 623/701/623 14/698/14 +f 16/702/16 625/703/625 15/700/15 +f 17/704/17 628/705/628 16/702/16 +f 18/706/18 632/707/632 17/704/17 +f 19/3/19 637/708/637 18/706/18 +f 13/697/13 622/699/622 33/18/33 +f 622/699/622 32/530/32 33/18/33 +f 14/698/14 623/701/623 622/699/622 +f 623/701/623 624/709/624 622/699/622 +f 622/699/622 624/709/624 32/530/32 +f 624/709/624 31/531/31 32/530/32 +f 15/700/15 625/703/625 623/701/623 +f 625/703/625 626/710/626 623/701/623 +f 623/701/623 626/710/626 624/709/624 +f 626/710/626 627/711/627 624/709/624 +f 624/709/624 627/711/627 31/531/31 +f 627/711/627 30/532/30 31/531/31 +f 16/702/16 628/705/628 625/703/625 +f 628/705/628 629/712/629 625/703/625 +f 625/703/625 629/712/629 626/710/626 +f 629/712/629 630/713/630 626/710/626 +f 626/710/626 630/713/630 627/711/627 +f 630/713/630 631/714/631 627/711/627 +f 627/711/627 631/714/631 30/532/30 +f 631/714/631 29/533/29 30/532/30 +f 17/704/17 632/707/632 628/705/628 +f 632/707/632 633/715/633 628/705/628 +f 628/705/628 633/715/633 629/712/629 +f 633/715/633 634/716/634 629/712/629 +f 629/712/629 634/716/634 630/713/630 +f 634/716/634 635/717/635 630/713/630 +f 630/713/630 635/717/635 631/714/631 +f 635/717/635 636/718/636 631/714/631 +f 631/714/631 636/718/636 29/533/29 +f 636/718/636 28/534/28 29/533/29 +f 18/706/18 637/708/637 632/707/632 +f 637/708/637 638/719/638 632/707/632 +f 632/707/632 638/719/638 633/715/633 +f 638/719/638 639/720/639 633/715/633 +f 633/715/633 639/720/639 634/716/634 +f 639/720/639 640/721/640 634/716/634 +f 634/716/634 640/721/640 635/717/635 +f 640/721/640 641/722/641 635/717/635 +f 635/717/635 641/722/641 636/718/636 +f 641/722/641 642/723/642 636/718/636 +f 636/718/636 642/723/642 28/534/28 +f 642/723/642 27/535/27 28/534/28 +f 19/3/19 20/2/20 637/708/637 +f 20/2/20 21/724/21 637/708/637 +f 637/708/637 21/724/21 638/719/638 +f 21/724/21 22/725/22 638/719/638 +f 638/719/638 22/725/22 639/720/639 +f 22/725/22 23/726/23 639/720/639 +f 639/720/639 23/726/23 640/721/640 +f 23/726/23 24/727/24 640/721/640 +f 640/721/640 24/727/24 641/722/641 +f 24/727/24 25/728/25 641/722/641 +f 641/722/641 25/728/25 642/723/642 +f 25/728/25 26/729/26 642/723/642 +f 642/723/642 26/729/26 27/535/27 +f 26/729/26 2/4/2 27/535/27 diff --git a/assets/testanim.dae b/assets/testanim.dae new file mode 100644 index 0000000..c165f41 --- /dev/null +++ b/assets/testanim.dae @@ -0,0 +1,741 @@ + + + + + Blender User + Blender 4.4.0 commit date:2025-03-17, commit time:17:00, hash:05377985c527 + + 2026-05-12T18:38:45 + 2026-05-12T18:38:45 + + Z_UP + + + + + + + + 0 0.04166662 0.08333331 0.125 0.1666666 0.2083333 0.25 0.2916666 0.3333333 0.375 0.4166666 0.4583333 0.5 0.5416667 0.5833333 0.625 0.6666667 0.7083333 0.75 0.7916667 0.8333333 0.875 0.9166667 0.9583333 1 1.041667 1.083333 1.125 1.166667 1.208333 1.25 1.291667 1.333333 1.375 1.416667 1.458333 1.5 1.541667 1.583333 1.625 1.666667 1.708333 1.75 1.791667 1.833333 1.875 1.916667 1.958333 2 2.041667 2.083333 2.125 2.166667 2.208333 2.25 2.291667 2.333333 2.375 2.416667 2.458333 + + + + + + + + 0.9974608 -0.001416472 -0.07120392 0 0.07121801 0.01983875 0.9972635 0 9.31323e-10 -0.9998022 0.01988925 -0.194438 0 0 0 1 0.9975046 -0.001404219 -0.070588 0 0.07060197 0.01983961 0.9973072 0 1.86265e-9 -0.9998022 0.01988924 -0.194438 0 0 0 1 0.9976298 -0.00136857 -0.06879594 0 0.06880955 0.01984211 0.9974325 0 0 -0.9998022 0.01988925 -0.194438 0 0 0 1 0.9978247 -0.00131118 -0.06591107 0 0.06592412 0.019846 0.9976273 0 2.32831e-9 -0.9998022 0.01988927 -0.194438 0 0 0 1 0.9980744 -0.001233704 -0.06201645 0 0.06202872 0.01985096 0.9978769 0 9.31323e-10 -0.9998022 0.01988926 -0.194438 0 0 0 1 0.9983624 -0.00113779 -0.057195 0 0.05720631 0.01985669 0.998165 0 9.31323e-10 -0.9998022 0.01988927 -0.194438 0 0 0 1 0.9986709 -0.001025089 -0.05152971 0 0.05153991 0.01986281 0.9984733 0 4.65661e-10 -0.9998022 0.01988924 -0.194438 0 0 0 1 0.9989819 -8.97256e-4 -0.04510372 0 0.04511264 0.01986901 0.9987842 0 4.65661e-10 -0.9998022 0.01988925 -0.194438 0 0 0 1 0.9992774 -7.55949e-4 -0.03800046 0 0.03800798 0.01987486 0.9990798 0 9.31323e-10 -0.9998022 0.01988923 -0.194438 0 0 0 1 0.9995406 -6.02836e-4 -0.03030368 0 0.03030967 0.01988014 0.9993429 0 9.31323e-10 -0.9998022 0.01988928 -0.194438 0 0 0 1 0.9997557 -4.3959e-4 -0.02209756 0 0.02210193 0.01988438 0.9995579 0 4.65661e-10 -0.9998022 0.01988924 -0.194438 0 0 0 1 0.9999093 -2.67894e-4 -0.01346664 0 0.0134693 0.01988745 0.9997115 0 5.82077e-10 -0.9998022 0.01988926 -0.194438 0 0 0 1 0.9999899 -8.94357e-5 -0.004495829 0 0.004496719 0.01988903 0.9997921 0 6.98492e-10 -0.9998022 0.01988924 -0.194438 0 0 0 1 0.9999888 9.4088e-5 0.004729615 0 -0.004730551 0.01988902 0.999791 0 7.567e-10 -0.9998022 0.01988924 -0.194438 0 0 0 1 0.9999002 2.80976e-4 0.01412421 0 -0.014127 0.01988728 0.9997025 0 6.98492e-10 -0.9998022 0.01988926 -0.194438 0 0 0 1 0.9997213 4.69527e-4 0.02360236 0 -0.02360703 0.0198837 0.9995236 0 9.31323e-10 -0.9998022 0.01988925 -0.194438 0 0 0 1 0.9994525 6.58036e-4 0.03307839 0 -0.03308493 0.01987838 0.9992549 0 9.31323e-10 -0.9998022 0.01988926 -0.194438 0 0 0 1 0.9990975 8.44799e-4 0.0424667 0 -0.04247511 0.01987129 0.9988999 0 4.65661e-10 -0.9998022 0.01988924 -0.194438 0 0 0 1 0.9986631 0.001028119 0.05168191 0 -0.05169213 0.01986264 0.9984655 0 2.32831e-9 -0.9998022 0.01988924 -0.194438 0 0 0 1 0.9981591 0.001206302 0.06063889 0 -0.06065089 0.01985265 0.9979616 0 4.65661e-10 -0.9998022 0.01988927 -0.194438 0 0 0 1 0.9975982 0.001377662 0.06925299 0 -0.06926668 0.01984148 0.9974008 0 -9.31323e-10 -0.9998022 0.01988924 -0.194438 0 0 0 1 0.9969959 0.001540526 0.07743976 0 -0.07745508 0.01982953 0.9967986 0 1.86265e-9 -0.9998022 0.01988927 -0.194438 0 0 0 1 0.9963697 0.001693219 0.08511558 0 -0.08513242 0.01981702 0.9961725 0 -9.31323e-10 -0.9998022 0.01988924 -0.194438 0 0 0 1 0.9957391 0.001834092 0.09219695 0 -0.09221519 0.01980451 0.9955422 0 9.31323e-10 -0.9998022 0.01988927 -0.194438 0 0 0 1 0.9951251 0.001961492 0.09860113 0 -0.09862063 0.01979231 0.9949282 0 1.86265e-9 -0.9998022 0.01988926 -0.194438 0 0 0 1 0.9945495 0.002073777 0.1042455 0 -0.1042662 0.01978086 0.9943527 0 9.31323e-10 -0.9998022 0.01988926 -0.194438 0 0 0 1 0.9940341 0.002169312 0.109048 0 -0.1090696 0.01977059 0.9938375 0 1.86265e-9 -0.9998022 0.01988924 -0.194438 0 0 0 1 0.9936008 0.002246468 0.1129265 0 -0.1129489 0.01976195 0.9934043 0 0 -0.9998022 0.01988923 -0.194438 0 0 0 1 0.99327 0.002303609 0.1157989 0 -0.1158219 0.01975539 0.9930735 0 0 -0.9998022 0.01988924 -0.194438 0 0 0 1 0.9930603 0.002339103 0.1175831 0 -0.1176064 0.01975122 0.9928639 0 1.86265e-9 -0.9998022 0.01988924 -0.194438 0 0 0 1 0.9929875 0.002351301 0.1181963 0 -0.1182197 0.01974978 0.9927911 0 9.31323e-10 -0.9998022 0.01988925 -0.194438 0 0 0 1 0.9930603 0.002339103 0.1175831 0 -0.1176064 0.01975122 0.9928639 0 0 -0.9998022 0.01988924 -0.194438 0 0 0 1 0.99327 0.002303611 0.115799 0 -0.1158219 0.01975539 0.9930735 0 9.31323e-10 -0.9998022 0.01988924 -0.194438 0 0 0 1 0.9936008 0.002246468 0.1129265 0 -0.1129489 0.01976195 0.9934043 0 9.31323e-10 -0.9998022 0.01988923 -0.194438 0 0 0 1 0.9940341 0.002169313 0.109048 0 -0.1090696 0.01977059 0.9938375 0 1.86265e-9 -0.9998022 0.01988924 -0.194438 0 0 0 1 0.9945495 0.002073776 0.1042455 0 -0.1042662 0.01978086 0.9943527 0 9.31323e-10 -0.9998022 0.01988926 -0.194438 0 0 0 1 0.9951251 0.001961491 0.09860111 0 -0.09862062 0.0197923 0.9949282 0 9.31323e-10 -0.9998022 0.01988925 -0.194438 0 0 0 1 0.9957391 0.001834093 0.09219695 0 -0.09221519 0.01980452 0.9955422 0 9.31323e-10 -0.9998022 0.01988927 -0.194438 0 0 0 1 0.9963697 0.001693221 0.08511557 0 -0.08513241 0.01981703 0.9961725 0 0 -0.9998022 0.01988924 -0.194438 0 0 0 1 0.9969959 0.001540524 0.07743978 0 -0.0774551 0.01982952 0.9967986 0 0 -0.9998022 0.01988927 -0.194438 0 0 0 1 0.9975982 0.001377663 0.06925295 0 -0.06926665 0.01984149 0.9974008 0 9.31323e-10 -0.9998022 0.01988926 -0.194438 0 0 0 1 0.9981591 0.001206302 0.0606389 0 -0.0606509 0.01985262 0.9979616 0 1.39698e-9 -0.9998022 0.01988924 -0.194438 0 0 0 1 0.9986631 0.001028119 0.05168191 0 -0.05169213 0.01986265 0.9984655 0 9.31323e-10 -0.9998022 0.01988924 -0.194438 0 0 0 1 0.9990975 8.44798e-4 0.0424667 0 -0.0424751 0.0198713 0.9988999 0 4.65661e-10 -0.9998022 0.01988924 -0.194438 0 0 0 1 0.9994525 6.58035e-4 0.03307838 0 -0.03308493 0.01987838 0.9992549 0 6.98492e-10 -0.9998022 0.01988926 -0.194438 0 0 0 1 0.9997213 4.69527e-4 0.02360236 0 -0.02360703 0.01988371 0.9995236 0 6.98492e-10 -0.9998022 0.01988926 -0.194438 0 0 0 1 0.9999002 2.80976e-4 0.0141242 0 -0.014127 0.01988728 0.9997025 0 4.65661e-10 -0.9998022 0.01988926 -0.194438 0 0 0 1 0.9999888 9.40877e-5 0.004729605 0 -0.004730541 0.01988903 0.999791 0 6.98492e-10 -0.9998022 0.01988925 -0.194438 0 0 0 1 0.9999899 -8.94363e-5 -0.004495837 0 0.004496726 0.01988904 0.9997921 0 2.32831e-10 -0.9998022 0.01988924 -0.194438 0 0 0 1 0.9999093 -2.67893e-4 -0.01346664 0 0.01346931 0.01988745 0.9997115 0 1.16415e-9 -0.9998022 0.01988925 -0.194438 0 0 0 1 0.9997557 -4.39589e-4 -0.02209759 0 0.02210196 0.01988439 0.9995579 0 2.79397e-9 -0.9998022 0.01988925 -0.194438 0 0 0 1 0.9995406 -6.02837e-4 -0.03030367 0 0.03030967 0.01988013 0.9993429 0 -2.32831e-10 -0.9998022 0.01988927 -0.194438 0 0 0 1 0.9992774 -7.55949e-4 -0.03800048 0 0.03800799 0.01987487 0.9990798 0 1.39698e-9 -0.9998022 0.01988924 -0.194438 0 0 0 1 0.9989819 -8.97254e-4 -0.04510372 0 0.04511264 0.01986901 0.9987842 0 2.32831e-9 -0.9998022 0.01988926 -0.194438 0 0 0 1 0.9986709 -0.00102509 -0.05152974 0 0.05153993 0.01986282 0.9984733 0 4.65661e-10 -0.9998022 0.01988925 -0.194438 0 0 0 1 0.9983624 -0.00113779 -0.05719502 0 0.05720633 0.01985669 0.998165 0 9.31323e-10 -0.9998022 0.01988927 -0.194438 0 0 0 1 0.9980744 -0.001233703 -0.06201646 0 0.06202873 0.01985098 0.9978769 0 2.32831e-9 -0.9998022 0.01988927 -0.194438 0 0 0 1 0.9978246 -0.001311179 -0.06591108 0 0.06592412 0.019846 0.9976273 0 3.25963e-9 -0.9998022 0.01988927 -0.194438 0 0 0 1 0.9976298 -0.001368568 -0.06879591 0 0.06880952 0.01984212 0.9974325 0 1.86265e-9 -0.9998022 0.01988926 -0.194438 0 0 0 1 0.9975046 -0.00140422 -0.07058802 0 0.07060198 0.01983961 0.9973072 0 1.86265e-9 -0.9998022 0.01988924 -0.194438 0 0 0 1 + + + + + + + + LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR + + + + + + + + + + + + + + + + 0 0.04166662 0.08333331 0.125 0.1666666 0.2083333 0.25 0.2916666 0.3333333 0.375 0.4166666 0.4583333 0.5 0.5416667 0.5833333 0.625 0.6666667 0.7083333 0.75 0.7916667 0.8333333 0.875 0.9166667 0.9583333 1 1.041667 1.083333 1.125 1.166667 1.208333 1.25 1.291667 1.333333 1.375 1.416667 1.458333 1.5 1.541667 1.583333 1.625 1.666667 1.708333 1.75 1.791667 1.833333 1.875 1.916667 1.958333 2 2.041667 2.083333 2.125 2.166667 2.208333 2.25 2.291667 2.333333 2.375 2.416667 2.458333 + + + + + + + + -0.994738 0.1023279 -0.005040132 0.1841546 -0.002406535 0.02584402 0.9996631 0.02375563 0.1024238 0.9944149 -0.0254618 -0.3068413 0 0 0 1 -0.9947398 0.1023122 -0.005031362 0.1841546 -0.002286472 0.02692832 0.9996347 0.02375564 0.1024104 0.9943879 -0.02655273 -0.3068413 0 0 0 1 -0.9947444 0.1022676 -0.005005769 0.1841547 -0.001937124 0.03008302 0.9995455 0.02375563 0.1023718 0.9943019 -0.02972682 -0.3068413 0 0 0 1 -0.994752 0.1021953 -0.004964218 0.1841547 -0.001375027 0.03516119 0.9993808 0.02375563 0.1023067 0.9941428 -0.03483615 -0.3068413 0 0 0 1 -0.9947625 0.1020979 -0.004907541 0.1841547 -6.16694e-4 0.0420161 0.9991167 0.02375563 0.102214 0.9938869 -0.04173308 -0.3068413 0 0 0 1 -0.9947748 0.1019785 -0.004836466 0.1841547 3.21394e-4 0.05050072 0.998724 0.02375563 0.1020927 0.9935038 -0.05026964 -0.3068413 0 0 0 1 -0.9947895 0.1018386 -0.004751615 0.1841547 0.001422411 0.06046723 0.9981692 0.02375563 0.1019396 0.9929615 -0.06029704 -0.3068413 0 0 0 1 -0.9948062 0.1016808 -0.004653655 0.1841547 0.002669538 0.0717667 0.9974178 0.02375563 0.1017523 0.992225 -0.07166544 -0.3068413 0 0 0 1 -0.9948246 0.1015076 -0.004543237 0.1841547 0.004045799 0.08424889 0.9964365 0.02375563 0.1015287 0.9912611 -0.08422353 -0.3068413 0 0 0 1 -0.9948439 0.1013217 -0.004421121 0.1841547 0.005534077 0.0977619 0.9951945 0.02375563 0.1012671 0.9900386 -0.09781858 -0.3068413 0 0 0 1 -0.9948645 0.1011252 -0.00428809 0.1841547 0.00711709 0.1121526 0.9936656 0.02375564 0.1009657 0.988532 -0.1122963 -0.3068413 0 0 0 1 -0.9948857 0.1009206 -0.004145053 0.1841547 0.008777505 0.1272662 0.9918298 0.02375563 0.1006237 0.9867208 -0.1275012 -0.3068413 0 0 0 1 -0.9949079 0.1007101 -0.003993002 0.1841547 0.01049793 0.1429475 0.9896746 0.02375563 0.1002411 0.984593 -0.1432768 -0.3068413 0 0 0 1 -0.9949302 0.1004962 -0.003833147 0.1841547 0.01226103 0.1590401 0.9871961 0.02375564 0.09981913 0.982144 -0.159466 -0.3068413 0 0 0 1 -0.9949526 0.1002809 -0.00366668 0.1841547 0.01404954 0.1753882 0.9843992 0.02375563 0.09935968 0.9793788 -0.1759118 -0.3068413 0 0 0 1 -0.9949746 0.1000668 -0.00349509 0.1841547 0.01584638 0.1918364 0.981299 0.02375563 0.09886605 0.976312 -0.1924581 -0.3068413 0 0 0 1 -0.9949964 0.09985533 -0.003319897 0.1841547 0.01763462 0.2082308 0.9779208 0.02375564 0.09834203 0.9729691 -0.2089498 -0.3068413 0 0 0 1 -0.9950179 0.09964868 -0.003142759 0.1841547 0.01939772 0.224419 0.9742997 0.02375563 0.09779306 0.9693845 -0.2252339 -0.3068413 0 0 0 1 -0.9950384 0.09944856 -0.002965522 0.1841547 0.02111953 0.2402518 0.9704809 0.02375563 0.09722549 0.965603 -0.2411601 -0.3068413 0 0 0 1 -0.9950579 0.0992572 -0.002790067 0.1841547 0.02278439 0.2555827 0.9665186 0.02375563 0.09664714 0.9616784 -0.2565811 -0.3068413 0 0 0 1 -0.9950765 0.09907566 -0.002618462 0.1841547 0.02437683 0.2702685 0.9624765 0.02375564 0.09606574 0.9576737 -0.271353 -0.3068413 0 0 0 1 -0.9950939 0.09890533 -0.002452716 0.1841547 0.02588219 0.28417 0.9584246 0.02375563 0.09549041 0.9536588 -0.2853357 -0.3068413 0 0 0 1 -0.9951101 0.09874772 -0.00229507 0.1841547 0.02728596 0.2971514 0.9544404 0.02375563 0.09493088 0.9497105 -0.2983927 -0.3068413 0 0 0 1 -0.9951245 0.09860446 -0.002147734 0.1841546 0.02857441 0.3090805 0.9506066 0.02375563 0.09439797 0.9459105 -0.310391 -0.3068413 0 0 0 1 -0.9951375 0.09847637 -0.002012886 0.1841547 0.02973389 0.3198281 0.947009 0.02375563 0.09390187 0.9423442 -0.3212009 -0.3068413 0 0 0 1 -0.9951488 0.09836485 -0.00189282 0.1841546 0.03075125 0.3292676 0.9437358 0.02375563 0.09345376 0.9390993 -0.330695 -0.3068413 0 0 0 1 -0.9951581 0.09827074 -0.001789845 0.1841546 0.03161319 0.3372737 0.9408756 0.02375563 0.09306433 0.9362634 -0.3387473 -0.3068413 0 0 0 1 -0.9951656 0.09819564 -0.001706035 0.1841547 0.03230707 0.3437221 0.9385155 0.02375563 0.09274463 0.9339231 -0.3452329 -0.3068413 0 0 0 1 -0.9951712 0.09814024 -0.001643531 0.1841547 0.03281958 0.3484877 0.9367386 0.02375564 0.0925046 0.9321613 -0.3500259 -0.3068413 0 0 0 1 -0.9951749 0.09810586 -0.001604669 0.1841547 0.03313719 0.3514434 0.9356226 0.02375563 0.09235409 0.9310547 -0.3529985 -0.3068413 0 0 0 1 -0.9951759 0.09809409 -0.001591251 0.1841546 0.0332463 0.3524583 0.9352368 0.02375563 0.09230212 0.9306721 -0.3540193 -0.3068413 0 0 0 1 -0.9951749 0.09810585 -0.001604647 0.1841547 0.03313722 0.3514434 0.9356226 0.02375563 0.09235407 0.9310547 -0.3529985 -0.3068413 0 0 0 1 -0.9951714 0.09814008 -0.001643539 0.1841547 0.03281953 0.3484878 0.9367386 0.02375564 0.09250443 0.9321614 -0.350026 -0.3068413 0 0 0 1 -0.9951658 0.09819549 -0.001705975 0.1841547 0.03230708 0.3437222 0.9385155 0.02375563 0.09274446 0.9339232 -0.3452329 -0.3068413 0 0 0 1 -0.9951583 0.09827074 -0.001789771 0.1841546 0.0316133 0.3372737 0.9408756 0.02375563 0.09306428 0.9362635 -0.3387473 -0.3068413 0 0 0 1 -0.9951488 0.09836484 -0.001892835 0.1841546 0.03075123 0.3292675 0.9437359 0.02375563 0.09345378 0.9390992 -0.3306949 -0.3068413 0 0 0 1 -0.9951375 0.09847637 -0.002012894 0.1841547 0.02973389 0.3198281 0.947009 0.02375564 0.09390189 0.9423442 -0.3212009 -0.3068413 0 0 0 1 -0.9951245 0.09860446 -0.002147742 0.1841547 0.0285744 0.3090805 0.9506066 0.02375563 0.09439798 0.9459105 -0.3103911 -0.3068413 0 0 0 1 -0.9951101 0.09874772 -0.00229507 0.1841547 0.02728597 0.2971514 0.9544404 0.02375563 0.09493088 0.9497105 -0.2983927 -0.3068413 0 0 0 1 -0.995094 0.09890517 -0.002452723 0.1841547 0.02588213 0.28417 0.9584245 0.02375563 0.09549023 0.9536589 -0.2853357 -0.3068413 0 0 0 1 -0.9950765 0.09907565 -0.002618469 0.1841547 0.02437683 0.2702685 0.9624765 0.02375564 0.09606574 0.9576737 -0.271353 -0.3068413 0 0 0 1 -0.9950579 0.0992572 -0.002790086 0.1841547 0.02278436 0.2555827 0.9665186 0.02375563 0.09664714 0.9616784 -0.2565811 -0.3068413 0 0 0 1 -0.9950382 0.09944887 -0.002965536 0.1841547 0.02111958 0.2402518 0.9704809 0.02375564 0.09722582 0.9656029 -0.2411601 -0.3068413 0 0 0 1 -0.9950179 0.09964884 -0.003142759 0.1841547 0.01939776 0.2244191 0.9742997 0.02375563 0.09779321 0.9693845 -0.2252339 -0.3068413 0 0 0 1 -0.9949966 0.09985516 -0.003319893 0.1841547 0.0176346 0.2082308 0.9779208 0.02375564 0.09834187 0.9729692 -0.2089498 -0.3068413 0 0 0 1 -0.9949747 0.1000665 -0.003495079 0.1841547 0.01584633 0.1918364 0.981299 0.02375563 0.09886573 0.9763122 -0.1924581 -0.3068413 0 0 0 1 -0.9949524 0.1002811 -0.003666691 0.1841547 0.01404957 0.1753882 0.9843992 0.02375563 0.09935984 0.9793787 -0.1759118 -0.3068413 0 0 0 1 -0.9949301 0.1004964 -0.003833137 0.1841547 0.01226107 0.1590401 0.9871961 0.02375563 0.0998193 0.9821439 -0.159466 -0.3068413 0 0 0 1 -0.9949077 0.1007102 -0.003993013 0.1841547 0.01049795 0.1429475 0.9896746 0.02375563 0.1002412 0.9845929 -0.1432768 -0.3068413 0 0 0 1 -0.9948857 0.1009206 -0.004145071 0.1841547 0.008777495 0.1272662 0.9918298 0.02375563 0.1006237 0.9867208 -0.1275012 -0.3068413 0 0 0 1 -0.9948645 0.1011252 -0.004288108 0.1841547 0.007117081 0.1121526 0.9936656 0.02375563 0.1009657 0.988532 -0.1122963 -0.3068413 0 0 0 1 -0.994844 0.1013216 -0.004421132 0.1841547 0.005534053 0.09776193 0.9951945 0.02375564 0.101267 0.9900387 -0.0978186 -0.3068413 0 0 0 1 -0.9948246 0.1015076 -0.004543234 0.1841547 0.004045807 0.08424888 0.9964365 0.02375564 0.1015287 0.9912611 -0.08422352 -0.3068413 0 0 0 1 -0.9948063 0.1016808 -0.004653674 0.1841547 0.002669524 0.07176676 0.9974179 0.02375563 0.1017523 0.992225 -0.07166548 -0.3068413 0 0 0 1 -0.9947895 0.1018386 -0.004751619 0.1841547 0.001422405 0.06046721 0.9981692 0.02375563 0.1019396 0.9929615 -0.06029703 -0.3068413 0 0 0 1 -0.9947747 0.1019785 -0.004836489 0.1841547 3.21375e-4 0.05050069 0.998724 0.02375563 0.1020927 0.9935037 -0.05026962 -0.3068413 0 0 0 1 -0.9947624 0.102098 -0.004907504 0.1841547 -6.16626e-4 0.0420161 0.9991167 0.02375563 0.1022142 0.9938868 -0.04173306 -0.3068413 0 0 0 1 -0.9947521 0.1021952 -0.004964203 0.1841547 -0.001375024 0.03516119 0.9993808 0.02375563 0.1023066 0.9941428 -0.03483615 -0.3068413 0 0 0 1 -0.9947443 0.1022676 -0.005005792 0.1841547 -0.001937139 0.03008303 0.9995455 0.02375563 0.1023718 0.9943018 -0.02972685 -0.3068413 0 0 0 1 -0.9947398 0.1023124 -0.005031295 0.1841546 -0.002286402 0.02692827 0.9996347 0.02375564 0.1024106 0.9943879 -0.02655271 -0.3068413 0 0 0 1 + + + + + + + + LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR + + + + + + + + + + + + + + + + 0 0.04166662 0.08333331 0.125 0.1666666 0.2083333 0.25 0.2916666 0.3333333 0.375 0.4166666 0.4583333 0.5 0.5416667 0.5833333 0.625 0.6666667 0.7083333 0.75 0.7916667 0.8333333 0.875 0.9166667 0.9583333 1 1.041667 1.083333 1.125 1.166667 1.208333 1.25 1.291667 1.333333 1.375 1.416667 1.458333 1.5 1.541667 1.583333 1.625 1.666667 1.708333 1.75 1.791667 1.833333 1.875 1.916667 1.958333 2 2.041667 2.083333 2.125 2.166667 2.208333 2.25 2.291667 2.333333 2.375 2.416667 2.458333 + + + + + + + + -0.9972966 -0.07346461 0.001561246 -0.196505 -0.02513009 0.3609575 0.9322436 0.02470914 -0.06905058 0.929684 -0.3618279 -0.3007402 0 0 0 1 -0.9972927 -0.07352819 8.35106e-4 -0.196505 -0.02574329 0.3597598 0.9326897 0.02470914 -0.06887954 0.9301432 -0.3606787 -0.3007402 0 0 0 1 -0.9972792 -0.07370809 -0.00127843 -0.196505 -0.02752899 0.356271 0.9339771 0.02470914 -0.06838627 0.9314709 -0.3573307 -0.3007402 0 0 0 1 -0.9972486 -0.07398129 -0.00468319 -0.196505 -0.03040818 0.3506422 0.9360157 0.02470914 -0.06760562 0.9335828 -0.3519271 -0.3007402 0 0 0 1 -0.9971914 -0.07431778 -0.009284001 -0.196505 -0.03430372 0.3430192 0.9387018 0.02470914 -0.06657775 0.9363839 -0.3446052 -0.3007402 0 0 0 1 -0.9970948 -0.07468273 -0.0149861 -0.196505 -0.0391395 0.3335451 0.9419213 0.02470914 -0.06534681 0.9397713 -0.3354991 -0.3007402 0 0 0 1 -0.9969449 -0.07503799 -0.02169404 -0.196505 -0.0448393 0.322362 0.9455539 0.02470914 -0.06395924 0.9436378 -0.3247418 -0.3007402 0 0 0 1 -0.9967265 -0.07534564 -0.02931118 -0.196505 -0.05132636 0.3096138 0.9494761 0.02470914 -0.06246385 0.9478723 -0.3124675 -0.3007402 0 0 0 1 -0.9964265 -0.0755663 -0.03773944 -0.196505 -0.058522 0.2954472 0.9535649 0.02470914 -0.06090743 0.9523659 -0.2988137 -0.3007402 0 0 0 1 -0.9960307 -0.07566409 -0.0468784 -0.196505 -0.0663458 0.2800135 0.9577007 0.02470914 -0.05933706 0.9570096 -0.2839221 -0.3007402 0 0 0 1 -0.9955286 -0.07560558 -0.05662572 -0.196505 -0.07471478 0.2634694 0.9617701 0.02470914 -0.05779614 0.9617005 -0.2679402 -0.3007402 0 0 0 1 -0.9949113 -0.07536274 -0.06687686 -0.196505 -0.08354357 0.2459775 0.9656684 0.02470914 -0.05632533 0.9663414 -0.2510218 -0.3007402 0 0 0 1 -0.9941719 -0.07491323 -0.07752538 -0.196505 -0.09274434 0.2277066 0.9693029 0.02470914 -0.0549607 0.9708437 -0.2333272 -0.3007402 0 0 0 1 -0.993309 -0.07424116 -0.08846353 -0.196505 -0.102227 0.2088313 0.972594 0.02470914 -0.05373265 0.9751297 -0.2150234 -0.3007402 0 0 0 1 -0.992323 -0.07333828 -0.09958255 -0.196505 -0.1118995 0.1895313 0.9754775 0.02470914 -0.05266592 0.9791319 -0.1962828 -0.3007402 0 0 0 1 -0.9912193 -0.07220417 -0.1107737 -0.196505 -0.1216687 0.1699911 0.9779058 0.02470914 -0.05177841 0.9827967 -0.1772835 -0.3007402 0 0 0 1 -0.9900072 -0.07084639 -0.1219288 -0.196505 -0.1314404 0.1503979 0.979849 0.02470914 -0.05108105 0.9860839 -0.1582071 -0.3007402 0 0 0 1 -0.9886999 -0.06928141 -0.1329407 -0.196505 -0.1411205 0.1309413 0.9812948 0.02470914 -0.05057816 0.9889665 -0.1392387 -0.3007402 0 0 0 1 -0.9873137 -0.06753387 -0.1437047 -0.196505 -0.1506156 0.1118111 0.9822491 0.02470914 -0.05026739 0.991432 -0.1205643 -0.3007402 0 0 0 1 -0.9858699 -0.06563479 -0.1541185 -0.196505 -0.159833 0.0931968 0.9827347 0.02470914 -0.05013835 0.9934819 -0.1023706 -0.3007402 0 0 0 1 -0.9843926 -0.0636233 -0.1640833 -0.196505 -0.1686823 0.0752859 0.9827912 0.02470914 -0.05017537 0.9951304 -0.08484304 -0.3007402 0 0 0 1 -0.9829084 -0.06154423 -0.1735035 -0.196505 -0.1770745 0.05826319 0.9824715 0.02470914 -0.05035668 0.9964024 -0.06816533 -0.3007402 0 0 0 1 -0.9814466 -0.05944823 -0.1822874 -0.196505 -0.1849236 0.04230972 0.9818417 0.02470914 -0.0506563 0.9973344 -0.05251813 -0.3007402 0 0 0 1 -0.9800382 -0.05738885 -0.1903466 -0.196505 -0.1921456 0.02760303 0.9809781 0.02470913 -0.05104316 0.9979703 -0.03807908 -0.3007402 0 0 0 1 -0.9787154 -0.0554239 -0.1975959 -0.196505 -0.1986587 0.01431649 0.9799641 0.02470914 -0.05148466 0.9983602 -0.02502223 -0.3007402 0 0 0 1 -0.9775119 -0.05361152 -0.203953 -0.196505 -0.2043837 0.002619825 0.9788874 0.02470914 -0.05194541 0.9985584 -0.01351826 -0.3007402 0 0 0 1 -0.9764594 -0.05201036 -0.2093367 -0.196505 -0.209242 -0.007320015 0.9778365 0.02470914 -0.05239006 0.9986197 -0.003735118 -0.3007402 0 0 0 1 -0.9755911 -0.05067791 -0.2136675 -0.196505 -0.2131569 -0.01533832 0.9768976 0.02470913 -0.05278451 0.9985973 0.004161529 -0.3007402 0 0 0 1 -0.9749375 -0.04966868 -0.2168646 -0.196505 -0.2160508 -0.02127093 0.9761504 0.02470914 -0.05309709 0.9985393 0.01000679 -0.3007402 0 0 0 1 -0.9745268 -0.04903205 -0.2188459 -0.196505 -0.2178459 -0.02495317 0.9756642 0.02470914 -0.05329979 0.9984854 0.01363603 -0.3007402 0 0 0 1 -0.9743847 -0.04881178 -0.219526 -0.196505 -0.2184623 -0.02621815 0.975493 0.02470914 -0.05337122 0.9984637 0.01488301 -0.3007402 0 0 0 1 -0.9745268 -0.04903223 -0.2188459 -0.196505 -0.2178459 -0.02495315 0.9756641 0.02470914 -0.05329996 0.9984854 0.01363599 -0.3007402 0 0 0 1 -0.9749375 -0.04966868 -0.2168646 -0.196505 -0.2160508 -0.02127091 0.9761505 0.02470914 -0.05309709 0.9985393 0.01000679 -0.3007402 0 0 0 1 -0.9755909 -0.05067824 -0.2136674 -0.196505 -0.2131568 -0.01533831 0.9768975 0.02470913 -0.05278483 0.9985971 0.004161462 -0.3007402 0 0 0 1 -0.9764594 -0.05201036 -0.2093367 -0.196505 -0.209242 -0.007319987 0.9778365 0.02470914 -0.05239006 0.9986196 -0.003735147 -0.3007402 0 0 0 1 -0.9775118 -0.05361154 -0.2039529 -0.196505 -0.2043836 0.002619898 0.9788875 0.02470914 -0.05194543 0.9985583 -0.01351833 -0.3007402 0 0 0 1 -0.9787155 -0.0554239 -0.1975959 -0.196505 -0.1986587 0.0143165 0.9799641 0.02470914 -0.05148465 0.9983603 -0.02502227 -0.3007402 0 0 0 1 -0.9800382 -0.05738902 -0.1903465 -0.196505 -0.1921455 0.02760307 0.9809782 0.02470914 -0.05104333 0.9979702 -0.03807914 -0.3007402 0 0 0 1 -0.9814466 -0.05944824 -0.1822874 -0.196505 -0.1849236 0.04230976 0.9818417 0.02470914 -0.05065631 0.9973344 -0.05251817 -0.3007402 0 0 0 1 -0.9829084 -0.06154422 -0.1735035 -0.196505 -0.1770745 0.05826316 0.9824715 0.02470914 -0.05035668 0.9964024 -0.06816529 -0.3007402 0 0 0 1 -0.9843926 -0.06362334 -0.1640833 -0.196505 -0.1686823 0.07528593 0.9827911 0.02470914 -0.05017538 0.9951302 -0.08484305 -0.3007402 0 0 0 1 -0.9858699 -0.06563481 -0.1541185 -0.196505 -0.159833 0.09319681 0.9827349 0.02470914 -0.05013835 0.9934818 -0.1023706 -0.3007402 0 0 0 1 -0.9873137 -0.06753386 -0.1437047 -0.196505 -0.1506156 0.1118111 0.9822491 0.02470914 -0.05026739 0.991432 -0.1205643 -0.3007402 0 0 0 1 -0.9886997 -0.06928174 -0.1329406 -0.196505 -0.1411205 0.1309413 0.9812948 0.02470914 -0.05057849 0.9889663 -0.1392387 -0.3007402 0 0 0 1 -0.9900073 -0.07084639 -0.1219287 -0.196505 -0.1314404 0.150398 0.979849 0.02470914 -0.05108105 0.9860839 -0.1582072 -0.3007402 0 0 0 1 -0.9912193 -0.07220399 -0.1107737 -0.196505 -0.1216686 0.1699911 0.9779058 0.02470914 -0.05177825 0.9827967 -0.1772834 -0.3007402 0 0 0 1 -0.9923229 -0.07333842 -0.09958251 -0.196505 -0.1118995 0.1895314 0.9754775 0.02470914 -0.05266609 0.9791319 -0.1962829 -0.3007402 0 0 0 1 -0.9933091 -0.07424115 -0.08846352 -0.196505 -0.102227 0.2088313 0.9725941 0.02470914 -0.05373264 0.9751297 -0.2150234 -0.3007402 0 0 0 1 -0.994172 -0.07491323 -0.07752535 -0.196505 -0.09274432 0.2277066 0.9693029 0.02470914 -0.05496068 0.9708437 -0.2333273 -0.3007402 0 0 0 1 -0.9949111 -0.07536274 -0.06687686 -0.196505 -0.08354358 0.2459775 0.9656684 0.02470914 -0.05632534 0.9663413 -0.2510218 -0.3007402 0 0 0 1 -0.9955286 -0.07560558 -0.05662568 -0.196505 -0.07471474 0.2634694 0.9617701 0.02470914 -0.05779615 0.9617004 -0.2679402 -0.3007402 0 0 0 1 -0.9960307 -0.07566408 -0.04687842 -0.196505 -0.06634582 0.2800134 0.9577007 0.02470914 -0.05933706 0.9570097 -0.283922 -0.3007402 0 0 0 1 -0.9964265 -0.0755663 -0.03773942 -0.196505 -0.05852199 0.2954472 0.9535649 0.02470914 -0.06090743 0.9523659 -0.2988137 -0.3007402 0 0 0 1 -0.9967267 -0.07534563 -0.02931118 -0.196505 -0.05132637 0.3096138 0.9494761 0.02470914 -0.06246382 0.9478725 -0.3124675 -0.3007402 0 0 0 1 -0.9969448 -0.07503818 -0.02169403 -0.196505 -0.04483935 0.322362 0.9455539 0.02470914 -0.06395938 0.9436377 -0.3247418 -0.3007402 0 0 0 1 -0.9970949 -0.07468256 -0.0149861 -0.196505 -0.03913948 0.3335451 0.9419213 0.02470914 -0.06534665 0.9397714 -0.3354991 -0.3007402 0 0 0 1 -0.9971914 -0.07431778 -0.009284032 -0.196505 -0.03430375 0.3430192 0.9387018 0.02470914 -0.06657775 0.9363839 -0.3446052 -0.3007402 0 0 0 1 -0.9972486 -0.07398129 -0.004683168 -0.196505 -0.03040817 0.3506422 0.9360157 0.02470914 -0.06760563 0.9335828 -0.3519271 -0.3007402 0 0 0 1 -0.9972792 -0.07370809 -0.001278453 -0.196505 -0.02752901 0.3562709 0.9339771 0.02470914 -0.06838628 0.9314709 -0.3573307 -0.3007402 0 0 0 1 -0.9972927 -0.07352835 8.35143e-4 -0.196505 -0.02574332 0.3597598 0.9326897 0.02470914 -0.06887969 0.9301432 -0.3606787 -0.3007402 0 0 0 1 + + + + + + + + LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR + + + + + + + + + + + + + + + + 0 0.04166662 0.08333331 0.125 0.1666666 0.2083333 0.25 0.2916666 0.3333333 0.375 0.4166666 0.4583333 0.5 0.5416667 0.5833333 0.625 0.6666667 0.7083333 0.75 0.7916667 0.8333333 0.875 0.9166667 0.9583333 1 1.041667 1.083333 1.125 1.166667 1.208333 1.25 1.291667 1.333333 1.375 1.416667 1.458333 1.5 1.541667 1.583333 1.625 1.666667 1.708333 1.75 1.791667 1.833333 1.875 1.916667 1.958333 2 2.041667 2.083333 2.125 2.166667 2.208333 2.25 2.291667 2.333333 2.375 2.416667 2.458333 + + + + + + + + 1 -5.68434e-14 -1.50996e-7 0.08954165 -1.47115e-7 0.2252731 -0.9742956 0.02421998 3.40154e-8 0.9742956 0.2252731 0.03911464 0 0 0 1 1 -9.1709e-10 -1.51098e-7 0.08954165 -1.47215e-7 0.2194009 -0.9756348 0.02421998 3.40457e-8 0.9756348 0.2194009 0.03911464 0 0 0 1 1 -3.56721e-9 -1.51361e-7 0.08954165 -1.47505e-7 0.2024163 -0.9792995 0.02421998 3.41312e-8 0.9792995 0.2024163 0.03911464 0 0 0 1 1 -7.80744e-9 -1.51685e-7 0.08954165 -1.47972e-7 0.1751854 -0.9845355 0.02421998 3.42597e-8 0.9845355 0.1751854 0.03911464 0 0 0 1 1 -1.34983e-8 -1.51935e-7 0.08954165 -1.48601e-7 0.138526 -0.9903588 0.02421998 3.44152e-8 0.9903588 0.138526 0.03911464 0 0 0 1 1 -2.04937e-8 -1.51954e-7 0.08954165 -1.49379e-7 0.09328314 -0.9956396 0.02421998 3.4579e-8 0.9956396 0.09328314 0.03911464 0 0 0 1 1 -2.86316e-8 -1.51574e-7 0.08954165 -1.50294e-7 0.04039756 -0.9991837 0.02421998 3.47315e-8 0.9991837 0.04039756 0.03911464 0 0 0 1 1 -3.77285e-8 -1.50637e-7 0.08954165 -1.51328e-7 -0.01904369 -0.9998187 0.02421998 3.4853e-8 0.9998187 -0.01904369 0.03911464 0 0 0 1 1 -4.75762e-8 -1.48999e-7 0.08954165 -1.52461e-7 -0.08378153 -0.9964842 0.02421998 3.49255e-8 0.9964842 -0.08378153 0.03911464 0 0 0 1 1 -5.79443e-8 -1.46555e-7 0.08954165 -1.53673e-7 -0.152389 -0.9883206 0.02421998 3.49342e-8 0.9883206 -0.152389 0.03911464 0 0 0 1 1 -6.85873e-8 -1.4324e-7 0.08954165 -1.54939e-7 -0.2233078 -0.974748 0.02421998 3.48687e-8 0.974748 -0.2233078 0.03911464 0 0 0 1 1 -7.92547e-8 -1.39043e-7 0.08954165 -1.56233e-7 -0.2949125 -0.9555243 0.02421998 3.47242e-8 0.9555243 -0.2949125 0.03911464 0 0 0 1 1 -8.97051e-8 -1.3401e-7 0.08954165 -1.57529e-7 -0.3655948 -0.9307741 0.02421998 3.45018e-8 0.9307741 -0.3655948 0.03911464 0 0 0 1 1 -9.97191e-8 -1.28237e-7 0.08954165 -1.58803e-7 -0.4338519 -0.9009842 0.02421998 3.42092e-8 0.9009842 -0.4338519 0.03911464 0 0 0 1 1 -1.09111e-7 -1.2187e-7 0.08954165 -1.60034e-7 -0.4983692 -0.8669649 0.02421998 3.38597e-8 0.8669649 -0.4983692 0.03911464 0 0 0 1 1 -1.17739e-7 -1.15086e-7 0.08954165 -1.61204e-7 -0.5580807 -0.8297867 0.02421998 3.34713e-8 0.8297867 -0.5580807 0.03911464 0 0 0 1 1 -1.25444e-7 -1.08146e-7 0.08954165 -1.62291e-7 -0.6117895 -0.7910206 0.02421998 3.30661e-8 0.7910206 -0.6117895 0.03911464 0 0 0 1 1 -1.31889e-7 -1.01584e-7 0.08954165 -1.63237e-7 -0.6570727 -0.7538272 0.02421998 3.26737e-8 0.7538272 -0.6570727 0.03911464 0 0 0 1 1 -1.36779e-7 -9.60605e-8 0.08954165 -1.63983e-7 -0.6916946 -0.7221903 0.02421998 3.23357e-8 0.7221903 -0.6916946 0.03911464 0 0 0 1 1 -1.39888e-7 -9.22663e-8 0.08954165 -1.64473e-7 -0.7138438 -0.7003049 0.02421998 3.21004e-8 0.7003049 -0.7138438 0.03911464 0 0 0 1 1 -1.40988e-7 -9.08655e-8 0.08954165 -1.64649e-7 -0.7217078 -0.6921978 0.02421998 3.20135e-8 0.6921978 -0.7217078 0.03911464 0 0 0 1 1 -1.4069e-7 -9.12315e-8 0.08954165 -1.64596e-7 -0.7197154 -0.6942692 0.02421998 3.20161e-8 0.6942692 -0.7197154 0.03911464 0 0 0 1 1 -1.39834e-7 -9.22733e-8 0.08954165 -1.64445e-7 -0.7139772 -0.7001689 0.02421998 3.20263e-8 0.7001689 -0.7139772 0.03911464 0 0 0 1 1 -1.38473e-7 -9.38996e-8 0.08954165 -1.6421e-7 -0.7048258 -0.7093803 0.02421998 3.20471e-8 0.7093803 -0.7048258 0.03911464 0 0 0 1 1 -1.36655e-7 -9.6014e-8 0.08954165 -1.63903e-7 -0.6925686 -0.7213521 0.02421998 3.20803e-8 0.7213521 -0.6925686 0.03911464 0 0 0 1 1 -1.34427e-7 -9.85195e-8 0.08954165 -1.63538e-7 -0.6774971 -0.7355254 0.02421998 3.21278e-8 0.7355254 -0.6774971 0.03911464 0 0 0 1 1 -1.31833e-7 -1.01322e-7 0.08954165 -1.63125e-7 -0.6598982 -0.751355 0.02421998 3.21915e-8 0.751355 -0.6598982 0.03911464 0 0 0 1 1 -1.2892e-7 -1.04332e-7 0.08954165 -1.62678e-7 -0.6400582 -0.7683264 0.02421998 3.22741e-8 0.7683264 -0.6400582 0.03911464 0 0 0 1 1 -1.25735e-7 -1.07469e-7 0.08954165 -1.62205e-7 -0.6182666 -0.7859684 0.02421998 3.23789e-8 0.7859684 -0.6182666 0.03911464 0 0 0 1 1 -1.22325e-7 -1.1066e-7 0.08954165 -1.61716e-7 -0.5948161 -0.8038619 0.02421998 3.25103e-8 0.8038619 -0.5948161 0.03911464 0 0 0 1 1 -4.9738e-14 -1.50996e-7 0.08954165 -1.24065e-7 -0.5700014 -0.8216438 0.02421998 -8.60678e-8 0.8216438 -0.5700014 0.03911464 0 0 0 1 1 4.44332e-9 -1.5231e-7 0.08954165 -1.25404e-7 -0.543797 -0.8392168 0.02421998 -8.65544e-8 0.8392168 -0.543797 0.03911464 0 0 0 1 1 9.13216e-9 -1.53534e-7 0.08954165 -1.26801e-7 -0.5160257 -0.8565732 0.02421998 -8.70499e-8 0.8565732 -0.5160257 0.03911464 0 0 0 1 1 1.40453e-8 -1.54645e-7 0.08954165 -1.2825e-7 -0.4867682 -0.8735312 0.02421998 -8.75453e-8 0.8735312 -0.4867682 0.03911464 0 0 0 1 1 1.91592e-8 -1.5562e-7 0.08954165 -1.2975e-7 -0.4561235 -0.8899165 0.02421998 -8.8032e-8 0.8899165 -0.4561235 0.03911464 0 0 0 1 1 2.44479e-8 -1.56438e-7 0.08954165 -1.31294e-7 -0.4242102 -0.9055637 0.02421998 -8.85019e-8 0.9055637 -0.4242102 0.03911464 0 0 0 1 1 2.98832e-8 -1.57083e-7 0.08954165 -1.32877e-7 -0.3911669 -0.9203198 0.02421998 -8.89478e-8 0.9203198 -0.3911669 0.03911464 0 0 0 1 1 3.54347e-8 -1.57539e-7 0.08954165 -1.34494e-7 -0.3571504 -0.9340469 0.02421998 -8.93629e-8 0.9340469 -0.3571504 0.03911464 0 0 0 1 1 4.10701e-8 -1.57796e-7 0.08954165 -1.36136e-7 -0.3223356 -0.9466255 0.02421998 -8.97414e-8 0.9466255 -0.3223356 0.03911464 0 0 0 1 1 4.67555e-8 -1.57847e-7 0.08954165 -1.37796e-7 -0.2869141 -0.9579563 0.02421998 -9.00784e-8 0.9579563 -0.2869141 0.03911464 0 0 0 1 1 5.24564e-8 -1.57689e-7 0.08954165 -1.39466e-7 -0.2510906 -0.9679636 0.02421998 -9.037e-8 0.9679636 -0.2510906 0.03911464 0 0 0 1 1 5.81372e-8 -1.57322e-7 0.08954165 -1.41136e-7 -0.2150814 -0.9765961 0.02421998 -9.06136e-8 0.9765961 -0.2150814 0.03911464 0 0 0 1 1 6.37626e-8 -1.56753e-7 0.08954165 -1.42797e-7 -0.179111 -0.9838288 0.02421998 -9.08076e-8 0.9838288 -0.179111 0.03911464 0 0 0 1 1 6.92975e-8 -1.55991e-7 0.08954165 -1.4444e-7 -0.1434086 -0.9896635 0.02421998 -9.09516e-8 0.9896635 -0.1434086 0.03911464 0 0 0 1 1 7.47077e-8 -1.5505e-7 0.08954165 -1.46055e-7 -0.1082051 -0.9941286 0.02421998 -9.10462e-8 0.9941286 -0.1082051 0.03911464 0 0 0 1 1 7.99606e-8 -1.53948e-7 0.08954165 -1.47633e-7 -0.07372994 -0.9972782 0.02421998 -9.10935e-8 0.9972782 -0.07372994 0.03911464 0 0 0 1 1 8.50252e-8 -1.52706e-7 0.08954165 -1.49164e-7 -0.04020775 -0.9991913 0.02421998 -9.10964e-8 0.9991913 -0.04020775 0.03911464 0 0 0 1 1 8.98725e-8 -1.51349e-7 0.08954165 -1.50638e-7 -0.00785643 -0.9999691 0.02421998 -9.10588e-8 0.9999691 -0.00785643 0.03911464 0 0 0 1 1 9.44759e-8 -1.49904e-7 0.08954165 -1.52048e-7 0.02311564 -0.9997328 0.02421998 -9.09855e-8 0.9997328 0.02311564 0.03911464 0 0 0 1 1 9.88109e-8 -1.484e-7 0.08954165 -1.53384e-7 0.05251035 -0.9986204 0.02421998 -9.08821e-8 0.9986204 0.05251035 0.03911464 0 0 0 1 1 1.02856e-7 -1.46868e-7 0.08954165 -1.54638e-7 0.08014154 -0.9967835 0.02421998 -9.07546e-8 0.9967835 0.08014154 0.03911464 0 0 0 1 1 1.0659e-7 -1.45339e-7 0.08954165 -1.55804e-7 0.1058342 -0.9943838 0.02421998 -9.06096e-8 0.9943838 0.1058342 0.03911464 0 0 0 1 1 1.09997e-7 -1.43848e-7 0.08954165 -1.56874e-7 0.1294252 -0.9915892 0.02421998 -9.04539e-8 0.9915892 0.1294252 0.03911464 0 0 0 1 1 1.13059e-7 -1.42424e-7 0.08954165 -1.57841e-7 0.1507608 -0.9885703 0.02421998 -9.02945e-8 0.9885703 0.1507608 0.03911464 0 0 0 1 1 1.15762e-7 -1.41102e-7 0.08954165 -1.587e-7 0.1696964 -0.9854964 0.02421998 -9.01382e-8 0.9854964 0.1696964 0.03911464 0 0 0 1 1 1.18091e-7 -1.39911e-7 0.08954165 -1.59443e-7 0.1860936 -0.982532 0.02421998 -8.99917e-8 0.982532 0.1860936 0.03911464 0 0 0 1 1 1.20033e-7 -1.38881e-7 0.08954165 -1.60065e-7 0.1998178 -0.9798331 0.02421998 -8.98611e-8 0.9798331 0.1998178 0.03911464 0 0 0 1 1 1.21573e-7 -1.3804e-7 0.08954165 -1.6056e-7 0.2107358 -0.9775431 0.02421998 -8.97523e-8 0.9775431 0.2107358 0.03911464 0 0 0 1 1 1.22695e-7 -1.37414e-7 0.08954165 -1.60922e-7 0.2187122 -0.9757894 0.02421998 -8.96703e-8 0.9757894 0.2187122 0.03911464 0 0 0 1 1 1.23383e-7 -1.37024e-7 0.08954165 -1.61144e-7 0.2236073 -0.9746793 0.02421998 -8.9619e-8 0.9746793 0.2236073 0.03911464 0 0 0 1 + + + + + + + + LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR + + + + + + + + + + + + + + + + 0 0.04166662 0.08333331 0.125 0.1666666 0.2083333 0.25 0.2916666 0.3333333 0.375 0.4166666 0.4583333 0.5 0.5416667 0.5833333 0.625 0.6666667 0.7083333 0.75 0.7916667 0.8333333 0.875 0.9166667 0.9583333 1 1.041667 1.083333 1.125 1.166667 1.208333 1.25 1.291667 1.333333 1.375 1.416667 1.458333 1.5 1.541667 1.583333 1.625 1.666667 1.708333 1.75 1.791667 1.833333 1.875 1.916667 1.958333 2 2.041667 2.083333 2.125 2.166667 2.208333 2.25 2.291667 2.333333 2.375 2.416667 2.458333 + + + + + + + + 1 -5.82433e-8 3.14212e-7 -7.45058e-9 -3.12362e-7 -0.3857283 0.9226125 0 6.74645e-8 -0.9226125 -0.3857283 -0.3756471 0 0 0 1 1 -6.26876e-8 3.12885e-7 -7.45058e-9 -3.11879e-7 -0.3994478 0.9167559 0 6.7512e-8 -0.9167559 -0.3994478 -0.3756471 0 0 0 1 1 -7.51957e-8 3.08756e-7 -7.45058e-9 -3.10506e-7 -0.4379178 0.8990152 7.45058e-9 6.76076e-8 -0.8990152 -0.4379178 -0.3756471 0 0 0 1 1 -9.44608e-8 3.0121e-7 0 -3.08343e-7 -0.4967385 0.8679003 0 6.76401e-8 -0.8679003 -0.4967385 -0.3756471 0 0 0 1 1 -1.18959e-7 2.89365e-7 -7.45058e-9 -3.05503e-7 -0.570719 0.8211454 0 6.74637e-8 -0.8211454 -0.570719 -0.3756471 0 0 0 1 1 -1.46835e-7 2.72403e-7 -7.45058e-9 -3.02134e-7 -0.6536345 0.7568104 3.72529e-9 6.69259e-8 -0.7568104 -0.6536345 -0.375647 0 0 0 1 1 -1.75914e-7 2.49916e-7 0 -2.9843e-7 -0.7383844 0.6743801 -1.86265e-9 6.5901e-8 -0.6743801 -0.7383844 -0.3756471 0 0 0 1 1 -2.03887e-7 2.22199e-7 0 -2.94626e-7 -0.8177024 0.5756412 -9.31323e-10 6.43263e-8 -0.5756412 -0.8177024 -0.375647 0 0 0 1 1 -2.28662e-7 1.90393e-7 7.45058e-9 -2.90969e-7 -0.885311 0.4649994 0 6.22294e-8 -0.4649994 -0.885311 -0.3756471 0 0 0 1 1 -2.48741e-7 1.56384e-7 0 -2.8768e-7 -0.9371141 0.349023 -3.72529e-9 5.97333e-8 -0.349023 -0.9371141 -0.375647 0 0 0 1 1 -2.63486e-7 1.22485e-7 0 -2.84911e-7 -0.971914 0.2353361 7.45058e-9 5.70367e-8 -0.2353361 -0.971914 -0.3756471 0 0 0 1 1 -2.73141e-7 9.10383e-8 0 -2.82732e-7 -0.9913377 0.1313377 -7.45058e-9 5.4376e-8 -0.1313377 -0.9913377 -0.375647 0 0 0 1 1 -2.78622e-7 6.41035e-8 -1.49012e-8 -2.81135e-7 -0.9990633 0.04327336 0 5.19865e-8 -0.04327336 -0.9990633 -0.3756471 0 0 0 1 1 -2.81188e-7 4.33293e-8 -7.45058e-9 -2.80065e-7 -0.9997109 -0.02404481 0 5.00779e-8 0.02404481 -0.9997109 -0.3756471 0 0 0 1 1 -2.82091e-7 3.00198e-8 -7.45058e-9 -2.7945e-7 -0.9977595 -0.0669046 0 4.88257e-8 0.0669046 -0.9977595 -0.375647 0 0 0 1 1 -2.82273e-7 2.53234e-8 -7.45058e-9 -2.79247e-7 -0.9966342 -0.08197841 -1.49012e-8 4.83784e-8 0.08197841 -0.9966342 -0.375647 0 0 0 1 1 -2.82205e-7 2.80832e-8 0 -2.79401e-7 -0.997331 -0.07301685 1.49012e-8 4.8614e-8 0.07301685 -0.997331 -0.3756471 0 0 0 1 1 -2.81879e-7 3.58935e-8 -7.45058e-9 -2.7985e-7 -0.9988658 -0.0476135 -1.49012e-8 4.9274e-8 0.0476135 -0.9988658 -0.375647 0 0 0 1 1 -2.80972e-7 4.80509e-8 0 -2.80581e-7 -0.9999685 -0.007944405 0 5.02815e-8 0.007944405 -0.9999685 -0.3756471 0 0 0 1 1 -2.79066e-7 6.38198e-8 7.45058e-9 -2.81591e-7 -0.9990427 0.0437434 0 5.15514e-8 -0.0437434 -0.9990427 -0.3756471 0 0 0 1 1 -2.75742e-7 8.24005e-8 7.45058e-9 -2.8287e-7 -0.9944726 0.1049954 -2.98023e-8 5.29934e-8 -0.1049954 -0.9944726 -0.375647 0 0 0 1 1 -2.70671e-7 1.0292e-7 0 -2.844e-7 -0.984906 0.1730909 -2.98023e-8 5.45158e-8 -0.1730909 -0.984906 -0.3756471 0 0 0 1 1 -2.63686e-7 1.24451e-7 0 -2.86144e-7 -0.9695026 0.2450812 0 5.60314e-8 -0.2450812 -0.9695026 -0.375647 0 0 0 1 1 -2.54835e-7 1.46059e-7 7.45058e-9 -2.88049e-7 -0.948117 0.3179216 -1.49012e-8 5.74637e-8 -0.3179216 -0.948117 -0.375647 0 0 0 1 1 -2.44402e-7 1.66864e-7 0 -2.90042e-7 -0.9213779 0.388668 -2.98023e-8 5.87536e-8 -0.388668 -0.9213779 -0.375647 0 0 0 1 1 -2.32886e-7 1.86102e-7 0 -2.92038e-7 -0.8906543 0.4546813 -2.98023e-8 5.98636e-8 -0.4546813 -0.8906543 -0.375647 0 0 0 1 1 -2.20956e-7 2.03169e-7 0 -2.93947e-7 -0.8579203 0.5137829 0 6.07792e-8 -0.5137829 -0.8579203 -0.375647 0 0 0 1 1 -2.0939e-7 2.17634e-7 0 -2.95678e-7 -0.8255563 0.5643197 -1.49012e-8 6.15065e-8 -0.5643197 -0.8255563 -0.375647 0 0 0 1 1 -1.99009e-7 2.29221e-7 0 -2.97144e-7 -0.7961363 0.6051172 -1.49012e-8 6.20671e-8 -0.6051172 -0.7961363 -0.3756471 0 0 0 1 1 -1.90628e-7 2.37753e-7 0 -2.98262e-7 -0.7722414 0.6353294 -1.49012e-8 6.24909e-8 -0.6353294 -0.7722414 -0.3756471 0 0 0 1 1 -1.65126e-7 2.51676e-7 0 -2.89535e-7 -0.7563159 0.6542065 0 8.23201e-8 -0.6542065 -0.7563159 -0.3756471 0 0 0 1 1 -1.61543e-7 2.54706e-7 -7.45058e-9 -2.90073e-7 -0.7464681 0.6654212 0 8.26361e-8 -0.6654212 -0.7464681 -0.3756471 0 0 0 1 1 -1.58877e-7 2.56903e-7 -7.45058e-9 -2.90473e-7 -0.7391119 0.6735829 0 8.28632e-8 -0.6735829 -0.7391119 -0.3756471 0 0 0 1 1 -1.57007e-7 2.58414e-7 7.45058e-9 -2.90752e-7 -0.7339389 0.6792155 0 8.30183e-8 -0.6792155 -0.7339389 -0.3756471 0 0 0 1 1 -1.55801e-7 2.59376e-7 0 -2.90932e-7 -0.7305951 0.682811 0 8.31163e-8 -0.682811 -0.7305951 -0.375647 0 0 0 1 1 -1.55117e-7 2.59918e-7 0 -2.91035e-7 -0.7286952 0.6848385 -1.49012e-8 8.3171e-8 -0.6848385 -0.7286952 -0.3756471 0 0 0 1 1 -1.54808e-7 2.60162e-7 7.45058e-9 -2.91081e-7 -0.7278349 0.6857525 0 8.3195e-8 -0.6857525 -0.7278349 -0.3756471 0 0 0 1 1 -1.54725e-7 2.60228e-7 0 -2.91094e-7 -0.7276021 0.6859995 0 8.32009e-8 -0.6859995 -0.7276021 -0.3756471 0 0 0 1 1 -1.54718e-7 2.60234e-7 7.45058e-9 -2.91096e-7 -0.7275792 0.6860234 0 8.32008e-8 -0.6860234 -0.7275792 -0.375647 0 0 0 1 1 -1.54635e-7 2.60299e-7 -7.45058e-9 -2.91109e-7 -0.7273492 0.6862676 -7.45058e-9 8.3207e-8 -0.6862676 -0.7273492 -0.375647 0 0 0 1 1 -1.54327e-7 2.60541e-7 0 -2.91154e-7 -0.726493 0.6871739 -7.45058e-9 8.32315e-8 -0.6871739 -0.726493 -0.3756471 0 0 0 1 1 -1.53641e-7 2.61077e-7 0 -2.91256e-7 -0.7245885 0.6891816 0 8.32865e-8 -0.6891816 -0.7245885 -0.375647 0 0 0 1 1 -1.52424e-7 2.62021e-7 -1.49012e-8 -2.91437e-7 -0.7212045 0.6927223 -7.45058e-9 8.33834e-8 -0.6927223 -0.7212045 -0.3756471 0 0 0 1 1 -1.50515e-7 2.63482e-7 -7.45058e-9 -2.91719e-7 -0.7158908 0.6982123 3.72529e-9 8.35329e-8 -0.6982123 -0.7158908 -0.375647 0 0 0 1 1 -1.47749e-7 2.6556e-7 0 -2.92127e-7 -0.70817 0.706042 -3.72529e-9 8.37445e-8 -0.706042 -0.70817 -0.375647 0 0 0 1 1 -1.43946e-7 2.68338e-7 7.45058e-9 -2.92687e-7 -0.6975226 0.7165629 0 8.40252e-8 -0.7165629 -0.6975226 -0.375647 0 0 0 1 1 -1.38865e-7 2.71916e-7 -7.45058e-9 -2.93429e-7 -0.683246 0.7301883 0 8.43877e-8 -0.7301883 -0.683246 -0.375647 0 0 0 1 1 -1.32502e-7 2.76187e-7 0 -2.94349e-7 -0.6652939 0.7465814 -1.16415e-10 8.48221e-8 -0.7465814 -0.6652939 -0.375647 0 0 0 1 1 -1.25035e-7 2.80919e-7 0 -2.9542e-7 -0.6441137 0.7649297 9.31323e-10 8.53007e-8 -0.7649297 -0.6441137 -0.375647 0 0 0 1 1 -1.16657e-7 2.85887e-7 -7.45058e-9 -2.96613e-7 -0.6202025 0.7844418 0 8.57972e-8 -0.7844418 -0.6202025 -0.3756471 0 0 0 1 1 -1.07581e-7 2.90885e-7 -7.45058e-9 -2.97897e-7 -0.5941277 0.8043707 -3.72529e-9 8.62877e-8 -0.8043707 -0.5941277 -0.375647 0 0 0 1 1 -9.80414e-8 2.95731e-7 -1.49012e-8 -2.99237e-7 -0.5665358 0.8240372 0 8.67524e-8 -0.8240372 -0.5665358 -0.3756471 0 0 0 1 1 -8.82921e-8 3.00273e-7 7.45058e-9 -3.00599e-7 -0.5381513 0.8428482 7.45058e-9 8.71753e-8 -0.8428482 -0.5381513 -0.3756471 0 0 0 1 1 -7.86057e-8 3.04394e-7 7.45058e-9 -3.01944e-7 -0.5097702 0.8603107 3.72529e-9 8.75456e-8 -0.8603107 -0.5097702 -0.375647 0 0 0 1 1 -6.92671e-8 3.08013e-7 -7.45058e-9 -3.03234e-7 -0.4822454 0.8760363 0 8.78574e-8 -0.8760363 -0.4822454 -0.3756471 0 0 0 1 1 -6.05688e-8 3.11083e-7 -1.49012e-8 -3.0443e-7 -0.456469 0.8897392 0 8.81092e-8 -0.8897392 -0.456469 -0.3756471 0 0 0 1 1 -5.28062e-8 3.13584e-7 -7.45058e-9 -3.05493e-7 -0.4333555 0.9012231 0 8.83034e-8 -0.9012231 -0.4333555 -0.375647 0 0 0 1 1 -4.62728e-8 3.1552e-7 -7.45058e-9 -3.06385e-7 -0.4138241 0.9103569 7.45058e-9 8.84451e-8 -0.9103569 -0.4138241 -0.3756471 0 0 0 1 1 -4.12583e-8 3.16903e-7 -7.45058e-9 -3.07067e-7 -0.3987856 0.9170442 0 8.85406e-8 -0.9170442 -0.3987856 -0.375647 0 0 0 1 1 -3.80466e-8 3.17742e-7 -7.45058e-9 -3.07503e-7 -0.3891323 0.9211819 -7.45058e-9 8.85959e-8 -0.9211819 -0.3891323 -0.3756471 0 0 0 1 + + + + + + + + LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR + + + + + + + + + + + + + + + + 0 0.04166662 0.08333331 0.125 0.1666666 0.2083333 0.25 0.2916666 0.3333333 0.375 0.4166666 0.4583333 0.5 0.5416667 0.5833333 0.625 0.6666667 0.7083333 0.75 0.7916667 0.8333333 0.875 0.9166667 0.9583333 1 1.041667 1.083333 1.125 1.166667 1.208333 1.25 1.291667 1.333333 1.375 1.416667 1.458333 1.5 1.541667 1.583333 1.625 1.666667 1.708333 1.75 1.791667 1.833333 1.875 1.916667 1.958333 2 2.041667 2.083333 2.125 2.166667 2.208333 2.25 2.291667 2.333333 2.375 2.416667 2.458333 + + + + + + + + 1 -1.69902e-7 2.58833e-7 0 2.26488e-7 0.9714168 -0.23738 2.98023e-8 -2.11103e-7 0.2373798 0.971417 -0.4310732 0 0 0 1 1 -1.70197e-7 2.58702e-7 7.45058e-9 2.2649e-7 0.9717014 -0.2362132 2.98023e-8 -2.11178e-7 0.2362131 0.9717014 -0.4310732 0 0 0 1 1 -1.71049e-7 2.5832e-7 1.49012e-8 2.26495e-7 0.9725155 -0.232838 5.96046e-8 -2.11394e-7 0.232838 0.9725156 -0.4310732 0 0 0 1 1 -1.72408e-7 2.57705e-7 0 2.26501e-7 0.9737923 -0.2274397 0 -2.11738e-7 0.2274396 0.9737923 -0.4310733 0 0 0 1 1 -1.74221e-7 2.56868e-7 7.45058e-9 2.26507e-7 0.9754546 -0.2202001 2.98023e-8 -2.122e-7 0.2202001 0.9754546 -0.4310732 0 0 0 1 1 -1.76437e-7 2.55824e-7 -7.45058e-9 2.2651e-7 0.9774209 -0.2113017 1.49012e-8 -2.12766e-7 0.2113016 0.9774209 -0.4310733 0 0 0 1 1 -1.79004e-7 2.54584e-7 -7.45058e-9 2.26506e-7 0.9796066 -0.2009258 -4.47035e-8 -2.13425e-7 0.2009258 0.9796066 -0.4310733 0 0 0 1 1 -1.81868e-7 2.5316e-7 0 2.26493e-7 0.9819279 -0.1892559 5.96046e-8 -2.14165e-7 0.1892558 0.9819279 -0.4310733 0 0 0 1 1 -1.84977e-7 2.51565e-7 -7.45058e-9 2.2647e-7 0.9843047 -0.1764781 0 -2.14972e-7 0.176478 0.9843047 -0.4310733 0 0 0 1 1 -1.88279e-7 2.49815e-7 0 2.26433e-7 0.9866621 -0.1627813 0 -2.15835e-7 0.1627811 0.9866621 -0.4310732 0 0 0 1 1 -1.91721e-7 2.47928e-7 -7.45058e-9 2.26381e-7 0.9889339 -0.1483572 -1.49012e-8 -2.16741e-7 0.1483572 0.9889339 -0.4310733 0 0 0 1 1 -1.95252e-7 2.45923e-7 1.49012e-8 2.26314e-7 0.991062 -0.1334014 1.49012e-8 -2.17678e-7 0.1334014 0.9910621 -0.4310732 0 0 0 1 1 -1.98824e-7 2.43822e-7 -1.49012e-8 2.2623e-7 0.9930004 -0.118112 -1.49012e-8 -2.18632e-7 0.1181119 0.9930004 -0.4310733 0 0 0 1 1 -2.02386e-7 2.41652e-7 0 2.26131e-7 0.9947135 -0.1026897 -3.72529e-8 -2.19591e-7 0.1026897 0.9947135 -0.4310732 0 0 0 1 1 -2.05893e-7 2.3944e-7 7.45058e-9 2.26018e-7 0.9961788 -0.08733717 -1.49012e-8 -2.20543e-7 0.08733711 0.9961788 -0.4310732 0 0 0 1 1 -2.09299e-7 2.37218e-7 -7.45058e-9 2.25893e-7 0.997386 -0.07225832 -7.45058e-9 -2.21475e-7 0.07225817 0.997386 -0.4310732 0 0 0 1 1 -2.12566e-7 2.35017e-7 -7.45058e-9 2.25758e-7 0.9983379 -0.05763507 7.45058e-8 -2.22375e-7 0.05763498 0.998338 -0.4310732 0 0 0 1 1 -2.15676e-7 2.32856e-7 0 2.25615e-7 0.9990507 -0.04356194 6.33299e-8 -2.23239e-7 0.04356188 0.9990507 -0.4310732 0 0 0 1 1 -2.18619e-7 2.3075e-7 0 2.25468e-7 0.9995465 -0.03011096 6.33299e-8 -2.24063e-7 0.0301109 0.9995465 -0.4310733 0 0 0 1 1 -2.21382e-7 2.28718e-7 0 2.25318e-7 0.9998494 -0.01735258 -5.21541e-8 -2.24842e-7 0.01735249 0.9998494 -0.4310732 0 0 0 1 1 -2.23956e-7 2.26775e-7 0 2.25168e-7 0.9999857 -0.005356282 -2.8871e-8 -2.25572e-7 0.005356222 0.9999856 -0.4310733 0 0 0 1 1 -2.2633e-7 2.24939e-7 0 2.2502e-7 0.9999831 0.005809188 -1.67638e-8 -2.2625e-7 -0.005809307 0.9999832 -0.4310732 0 0 0 1 1 -2.28496e-7 2.23228e-7 -7.45058e-9 2.24877e-7 0.9998708 0.01607645 2.98023e-8 -2.26872e-7 -0.01607662 0.9998708 -0.4310733 0 0 0 1 1 -2.30442e-7 2.21658e-7 0 2.24743e-7 0.999678 0.02537924 7.45058e-9 -2.27435e-7 -0.0253793 0.999678 -0.4310733 0 0 0 1 1 -2.32162e-7 2.20246e-7 0 2.24618e-7 0.9994336 0.03365147 -1.49012e-8 -2.27934e-7 -0.03365156 0.9994337 -0.4310732 0 0 0 1 1 -2.33644e-7 2.19009e-7 0 2.24507e-7 0.9991661 0.04082832 -7.45058e-9 -2.28366e-7 -0.04082841 0.9991662 -0.4310732 0 0 0 1 1 -2.3488e-7 2.17964e-7 -1.49012e-8 2.24411e-7 0.9989021 0.04684514 -7.45058e-9 -2.28728e-7 -0.0468452 0.9989021 -0.4310733 0 0 0 1 1 -2.3586e-7 2.17126e-7 0 2.24334e-7 0.9986659 0.05163768 2.98023e-8 -2.29016e-7 -0.05163774 0.998666 -0.4310733 0 0 0 1 1 -2.36575e-7 2.1651e-7 -7.45058e-9 2.24276e-7 0.9984787 0.05514105 -7.45058e-9 -2.29226e-7 -0.05514111 0.9984787 -0.4310733 0 0 0 1 1 -2.37012e-7 2.16131e-7 -7.45058e-9 2.2424e-7 0.9983575 0.05729116 1.49012e-8 -2.29355e-7 -0.05729122 0.9983576 -0.4310732 0 0 0 1 1 -1.04755e-7 1.973e-7 0 9.31304e-8 0.9983154 0.05802244 0 -2.03046e-7 -0.05802245 0.9983155 -0.4310732 0 0 0 1 1 -1.03787e-7 1.97831e-7 -7.45058e-9 9.31232e-8 0.9985858 0.05316371 7.45058e-9 -2.03069e-7 -0.05316377 0.9985858 -0.4310732 0 0 0 1 1 -1.01049e-7 1.993e-7 -7.45058e-9 9.31035e-8 0.9992208 0.03947142 -7.45058e-9 -2.03133e-7 -0.03947148 0.9992207 -0.4310732 0 0 0 1 1 -9.67703e-8 2.015e-7 -7.45058e-9 9.30748e-8 0.9998333 0.01826009 3.72529e-9 -2.03233e-7 -0.01826018 0.9998334 -0.4310732 0 0 0 1 1 -9.11767e-8 2.04206e-7 0 9.30408e-8 0.9999582 -0.009147048 2.79397e-8 -2.03364e-7 0.009146929 0.9999582 -0.4310732 0 0 0 1 1 -8.45015e-8 2.07193e-7 7.45058e-9 9.30054e-8 0.9991429 -0.04139304 1.02445e-8 -2.03518e-7 0.04139307 0.999143 -0.4310732 0 0 0 1 1 -7.69954e-8 2.1025e-7 -7.45058e-9 9.29721e-8 0.997025 -0.07707849 -2.79397e-8 -2.0369e-7 0.07707843 0.9970251 -0.4310733 0 0 0 1 1 -6.89314e-8 2.13194e-7 0 9.29434e-8 0.9933925 -0.1147667 -4.09782e-8 -2.03874e-7 0.1147667 0.9933925 -0.4310732 0 0 0 1 1 -6.06053e-8 2.15877e-7 7.45058e-9 9.29215e-8 0.9882258 -0.1530031 3.72529e-8 -2.04062e-7 0.153003 0.9882258 -0.4310733 0 0 0 1 1 -5.23312e-8 2.18198e-7 0 9.2907e-8 0.9817176 -0.1903436 1.49012e-8 -2.04248e-7 0.1903436 0.9817176 -0.4310732 0 0 0 1 1 -4.44355e-8 2.20102e-7 0 9.28997e-8 0.9742699 -0.2253849 -1.49012e-8 -2.04423e-7 0.2253848 0.9742699 -0.4310732 0 0 0 1 1 -3.72499e-8 2.21577e-7 7.45058e-9 9.28986e-8 0.9664685 -0.2567855 1.49012e-8 -2.04582e-7 0.2567854 0.9664686 -0.4310733 0 0 0 1 1 -3.11045e-8 2.22648e-7 7.45058e-9 9.29017e-8 0.959038 -0.2832776 -2.98023e-8 -2.04717e-7 0.2832776 0.959038 -0.4310733 0 0 0 1 1 -2.63244e-8 2.23362e-7 7.45058e-9 9.29067e-8 0.9527816 -0.3036564 0 -2.04822e-7 0.3036564 0.9527817 -0.4310732 0 0 0 1 1 -2.32276e-8 2.23769e-7 0 9.2911e-8 0.948508 -0.3167533 0 -2.04889e-7 0.3167533 0.948508 -0.4310733 0 0 0 1 1 -2.21265e-8 2.23903e-7 0 9.29128e-8 0.946947 -0.3213899 -2.98023e-8 -2.04913e-7 0.3213899 0.946947 -0.4310732 0 0 0 1 1 -2.23788e-8 2.23873e-7 -7.45058e-9 9.29131e-8 0.9473056 -0.320331 2.98023e-8 -2.04908e-7 0.3203311 0.9473057 -0.4310732 0 0 0 1 1 -2.30886e-8 2.23787e-7 -1.49012e-8 9.29139e-8 0.9483087 -0.3173497 -1.49012e-8 -2.04892e-7 0.3173496 0.9483087 -0.4310733 0 0 0 1 1 -2.41847e-8 2.2365e-7 7.45058e-9 9.29152e-8 0.9498399 -0.3127367 2.98023e-8 -2.04868e-7 0.3127366 0.9498399 -0.4310732 0 0 0 1 1 -2.55961e-8 2.23466e-7 -7.45058e-9 9.29171e-8 0.9517798 -0.306782 -1.49012e-8 -2.04838e-7 0.306782 0.9517798 -0.4310733 0 0 0 1 1 -2.72512e-8 2.23238e-7 1.49012e-8 9.29195e-8 0.9540094 -0.299777 -1.49012e-8 -2.04802e-7 0.2997768 0.9540094 -0.4310732 0 0 0 1 1 -2.90791e-8 2.22972e-7 7.45058e-9 9.29225e-8 0.9564143 -0.2920137 -1.49012e-8 -2.04762e-7 0.2920136 0.9564143 -0.4310733 0 0 0 1 1 -3.10086e-8 2.22675e-7 7.45058e-9 9.29261e-8 0.9588873 -0.2837871 2.98023e-8 -2.0472e-7 0.283787 0.9588873 -0.4310733 0 0 0 1 1 -3.29695e-8 2.22356e-7 -7.45058e-9 9.293e-8 0.9613314 -0.2753944 2.98023e-8 -2.04678e-7 0.2753944 0.9613314 -0.4310732 0 0 0 1 1 -3.48914e-8 2.22025e-7 -7.45058e-9 9.29343e-8 0.9636589 -0.2671355 5.96046e-8 -2.04636e-7 0.2671355 0.9636589 -0.4310732 0 0 0 1 1 -3.67052e-8 2.21698e-7 -7.45058e-9 9.29386e-8 0.9657937 -0.2593124 0 -2.04596e-7 0.2593123 0.9657936 -0.4310732 0 0 0 1 1 -3.83418e-8 2.2139e-7 7.45058e-9 9.29428e-8 0.9676678 -0.2522283 0 -2.04561e-7 0.2522283 0.9676678 -0.4310732 0 0 0 1 1 -3.97329e-8 2.21118e-7 -7.45058e-9 9.29466e-8 0.969222 -0.2461883 -2.98023e-8 -2.04531e-7 0.2461883 0.9692221 -0.4310732 0 0 0 1 1 -4.08107e-8 2.20901e-7 0 9.29497e-8 0.9704015 -0.2414971 2.98023e-8 -2.04507e-7 0.2414971 0.9704015 -0.4310732 0 0 0 1 1 -4.15073e-8 2.20758e-7 -1.49012e-8 9.29517e-8 0.9711525 -0.2384597 -2.98023e-8 -2.04492e-7 0.2384597 0.9711525 -0.4310733 0 0 0 1 + + + + + + + + LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR + + + + + + + + + + + + + + + + 0 0.04166662 0.08333331 0.125 0.1666666 0.2083333 0.25 0.2916666 0.3333333 0.375 0.4166666 0.4583333 0.5 0.5416667 0.5833333 0.625 0.6666667 0.7083333 0.75 0.7916667 0.8333333 0.875 0.9166667 0.9583333 1 1.041667 1.083333 1.125 1.166667 1.208333 1.25 1.291667 1.333333 1.375 1.416667 1.458333 1.5 1.541667 1.583333 1.625 1.666667 1.708333 1.75 1.791667 1.833333 1.875 1.916667 1.958333 2 2.041667 2.083333 2.125 2.166667 2.208333 2.25 2.291667 2.333333 2.375 2.416667 2.458333 + + + + + + + + 1 -4.9738e-14 -1.50996e-7 -0.08954165 -1.32845e-7 -0.4753538 -0.8797947 0.02421998 -7.17764e-8 0.8797947 -0.4753538 0.03911464 0 0 0 1 1 3.38403e-10 -1.51081e-7 -0.08954165 -1.32923e-7 -0.4733466 -0.8808763 0.02421998 -7.18118e-8 0.8808763 -0.4733466 0.03911464 0 0 0 1 1 1.32488e-9 -1.51325e-7 -0.08954165 -1.33151e-7 -0.4674889 -0.883999 0.02421998 -7.19137e-8 0.883999 -0.4674889 0.03911464 0 0 0 1 1 2.91824e-9 -1.51703e-7 -0.08954165 -1.3352e-7 -0.4580039 -0.8889502 0.02421998 -7.20749e-8 0.8889502 -0.4580039 0.03911464 0 0 0 1 1 5.07937e-9 -1.52189e-7 -0.08954165 -1.34022e-7 -0.4450934 -0.8954841 0.02421998 -7.22866e-8 0.8954841 -0.4450934 0.03911464 0 0 0 1 1 7.77001e-9 -1.52747e-7 -0.08954165 -1.34648e-7 -0.4289464 -0.9033299 0.02421998 -7.25391e-8 0.9033299 -0.4289464 0.03911464 0 0 0 1 1 1.09517e-8 -1.53343e-7 -0.08954165 -1.35391e-7 -0.4097492 -0.9121982 0.02421998 -7.28221e-8 0.9121982 -0.4097492 0.03911464 0 0 0 1 1 1.45846e-8 -1.53938e-7 -0.08954165 -1.36244e-7 -0.3876937 -0.9217883 0.02421998 -7.31247e-8 0.9217883 -0.3876937 0.03911464 0 0 0 1 1 1.8627e-8 -1.54496e-7 -0.08954165 -1.37197e-7 -0.3629846 -0.9317952 0.02421998 -7.34361e-8 0.9317952 -0.3629846 0.03911464 0 0 0 1 1 2.30343e-8 -1.54979e-7 -0.08954165 -1.38242e-7 -0.3358454 -0.9419171 0.02421998 -7.37455e-8 0.9419171 -0.3358454 0.03911464 0 0 0 1 1 2.77589e-8 -1.55355e-7 -0.08954165 -1.39368e-7 -0.3065238 -0.951863 0.02421998 -7.40427e-8 0.951863 -0.3065238 0.03911464 0 0 0 1 1 3.27499e-8 -1.55593e-7 -0.08954165 -1.40565e-7 -0.2752931 -0.9613603 0.02421998 -7.4318e-8 0.9613603 -0.2752931 0.03911464 0 0 0 1 1 3.79535e-8 -1.55666e-7 -0.08954165 -1.4182e-7 -0.2424542 -0.9701628 0.02421998 -7.45631e-8 0.9701628 -0.2424542 0.03911464 0 0 0 1 1 4.33132e-8 -1.55558e-7 -0.08954165 -1.43121e-7 -0.2083342 -0.9780577 0.02421998 -7.47708e-8 0.9780577 -0.2083342 0.03911464 0 0 0 1 1 4.87705e-8 -1.55254e-7 -0.08954165 -1.44454e-7 -0.1732831 -0.984872 0.02421998 -7.49356e-8 0.984872 -0.1732831 0.03911464 0 0 0 1 1 5.42658e-8 -1.54749e-7 -0.08954165 -1.45805e-7 -0.1376704 -0.9904781 0.02421998 -7.50535e-8 0.9904781 -0.1376704 0.03911464 0 0 0 1 1 5.97394e-8 -1.54047e-7 -0.08954165 -1.47159e-7 -0.1018787 -0.9947968 0.02421998 -7.51227e-8 0.9947968 -0.1018787 0.03911464 0 0 0 1 1 6.51323e-8 -1.53157e-7 -0.08954165 -1.48502e-7 -0.06629794 -0.9977999 0.02421998 -7.5143e-8 0.9977999 -0.06629794 0.03911464 0 0 0 1 1 7.03875e-8 -1.52098e-7 -0.08954165 -1.49819e-7 -0.0313181 -0.9995095 0.02421998 -7.51164e-8 0.9995095 -0.0313181 0.03911464 0 0 0 1 1 7.54506e-8 -1.50895e-7 -0.08954165 -1.51096e-7 0.002676592 -0.9999964 0.02421998 -7.50464e-8 0.9999964 0.002676592 0.03911464 0 0 0 1 1 8.02706e-8 -1.49578e-7 -0.08954165 -1.52319e-7 0.03531351 -0.9993762 0.02421998 -7.49384e-8 0.9993762 0.03531351 0.03911464 0 0 0 1 1 8.48005e-8 -1.48184e-7 -0.08954165 -1.53476e-7 0.06623603 -0.997804 0.02421998 -7.47992e-8 0.997804 0.06623603 0.03911464 0 0 0 1 1 8.89973e-8 -1.46754e-7 -0.08954165 -1.54553e-7 0.0951069 -0.9954671 0.02421998 -7.46365e-8 0.9954671 0.0951069 0.03911464 0 0 0 1 1 9.28217e-8 -1.45331e-7 -0.08954165 -1.5554e-7 0.1216085 -0.9925781 0.02421998 -7.44594e-8 0.9925781 0.1216085 0.03911464 0 0 0 1 1 9.62383e-8 -1.4396e-7 -0.08954165 -1.56426e-7 0.1454435 -0.9893666 0.02421998 -7.4277e-8 0.9893666 0.1454435 0.03911464 0 0 0 1 1 9.92144e-8 -1.42687e-7 -0.08954165 -1.57202e-7 0.1663315 -0.9860699 0.02421998 -7.4099e-8 0.9860699 0.1663315 0.03911464 0 0 0 1 1 1.01719e-7 -1.41557e-7 -0.08954165 -1.57857e-7 0.184006 -0.9829251 0.02421998 -7.39351e-8 0.9829251 0.184006 0.03911464 0 0 0 1 1 1.03723e-7 -1.40613e-7 -0.08954165 -1.58382e-7 0.1982091 -0.9801598 0.02421998 -7.37945e-8 0.9801598 0.1982091 0.03911464 0 0 0 1 1 1.05196e-7 -1.39897e-7 -0.08954165 -1.5877e-7 0.2086847 -0.9779829 0.02421998 -7.36856e-8 0.9779829 0.2086847 0.03911464 0 0 0 1 1 1.06106e-7 -1.39445e-7 -0.08954165 -1.5901e-7 0.2151721 -0.9765761 0.02421998 -7.3616e-8 0.9765761 0.2151721 0.03911464 0 0 0 1 1 -4.26326e-14 -1.50996e-7 -0.08954165 -1.47384e-7 0.2173982 -0.976083 0.02421998 3.28263e-8 0.976083 0.2173982 0.03911464 0 0 0 1 1 -6.5662e-10 -1.51067e-7 -0.08954165 -1.47455e-7 0.2131555 -0.9770183 0.02421998 3.28422e-8 0.9770183 0.2131555 0.03911464 0 0 0 1 1 -2.5789e-9 -1.51257e-7 -0.08954165 -1.47661e-7 0.2007328 -0.979646 0.02421998 3.28887e-8 0.979646 0.2007328 0.03911464 0 0 0 1 1 -5.69999e-9 -1.51515e-7 -0.08954165 -1.47996e-7 0.1805459 -0.9835666 0.02421998 3.29617e-8 0.9835666 0.1805459 0.03911464 0 0 0 1 1 -9.95615e-9 -1.51762e-7 -0.08954165 -1.48453e-7 0.1529729 -0.9882304 0.02421998 3.30544e-8 0.9882304 0.1529729 0.03911464 0 0 0 1 1 -1.52831e-8 -1.51904e-7 -0.08954165 -1.49026e-7 0.1183832 -0.992968 0.02421998 3.31584e-8 0.992968 0.1183832 0.03911464 0 0 0 1 1 -2.16118e-8 -1.51831e-7 -0.08954165 -1.4971e-7 0.07716671 -0.9970182 0.02421998 3.32636e-8 0.9970182 0.07716671 0.03911464 0 0 0 1 1 -2.88646e-8 -1.51425e-7 -0.08954165 -1.50499e-7 0.02976404 -0.999557 0.02421998 3.33589e-8 0.999557 0.02976404 0.03911464 0 0 0 1 1 -3.69519e-8 -1.50565e-7 -0.08954165 -1.51385e-7 -0.0233081 -0.9997283 0.02421998 3.34325e-8 0.9997283 -0.0233081 0.03911464 0 0 0 1 1 -4.57691e-8 -1.49129e-7 -0.08954165 -1.52361e-7 -0.08143603 -0.9966786 0.02421998 3.34727e-8 0.9966786 -0.08143603 0.03911464 0 0 0 1 1 -5.51958e-8 -1.47004e-7 -0.08954165 -1.53416e-7 -0.1438971 -0.9895926 0.02421998 3.3468e-8 0.9895926 -0.1438971 0.03911464 0 0 0 1 1 -6.50956e-8 -1.44089e-7 -0.08954165 -1.54541e-7 -0.2098567 -0.9777322 0.02421998 3.34081e-8 0.9777322 -0.2098567 0.03911464 0 0 0 1 1 -7.53178e-8 -1.40301e-7 -0.08954165 -1.55722e-7 -0.2783768 -0.9604719 0.02421998 3.32841e-8 0.9604719 -0.2783768 0.03911464 0 0 0 1 1 -8.57013e-8 -1.35582e-7 -0.08954165 -1.56947e-7 -0.3484354 -0.9373328 0.02421998 3.3089e-8 0.9373328 -0.3484354 0.03911464 0 0 0 1 1 -9.60788e-8 -1.29899e-7 -0.08954165 -1.58202e-7 -0.4189552 -0.908007 0.02421998 3.28183e-8 0.908007 -0.4189552 0.03911464 0 0 0 1 1 -1.06283e-7 -1.23247e-7 -0.08954165 -1.59473e-7 -0.4888408 -0.872373 0.02421998 3.24699e-8 0.872373 -0.4888408 0.03911464 0 0 0 1 1 -1.16089e-7 -1.15714e-7 -0.08954165 -1.60742e-7 -0.5564463 -0.8308836 0.02421998 3.20683e-8 0.8308836 -0.5564463 0.03911464 0 0 0 1 1 -1.24783e-7 -1.0793e-7 -0.08954165 -1.6192e-7 -0.6167832 -0.787133 0.02421998 3.16516e-8 0.787133 -0.6167832 0.03911464 0 0 0 1 1 -1.3163e-7 -1.00918e-7 -0.08954165 -1.62891e-7 -0.6646845 -0.7471242 0.02421998 3.12657e-8 0.7471242 -0.6646845 0.03911464 0 0 0 1 1 -1.36091e-7 -9.58506e-8 -0.08954165 -1.63549e-7 -0.6961176 -0.7179278 0.02421998 3.09805e-8 0.7179278 -0.6961176 0.03911464 0 0 0 1 1 -1.37699e-7 -9.39157e-8 -0.08954165 -1.63793e-7 -0.7074876 -0.7067257 0.02421998 3.08711e-8 0.7067257 -0.7074876 0.03911464 0 0 0 1 1 -1.36871e-7 -9.49157e-8 -0.08954165 -1.63666e-7 -0.7016662 -0.7125059 0.02421998 3.0922e-8 0.7125059 -0.7016662 0.03911464 0 0 0 1 1 -1.34582e-7 -9.7595e-8 -0.08954165 -1.63318e-7 -0.6856314 -0.7279488 0.02421998 3.10547e-8 0.7279488 -0.6856314 0.03911464 0 0 0 1 1 -1.31105e-7 -1.01446e-7 -0.08954165 -1.62801e-7 -0.661402 -0.7500317 0.02421998 3.12361e-8 0.7500317 -0.661402 0.03911464 0 0 0 1 1 -1.26723e-7 -1.0596e-7 -0.08954165 -1.62167e-7 -0.6310738 -0.7757228 0.02421998 3.14331e-8 0.7757228 -0.6310738 0.03911464 0 0 0 1 1 -1.21767e-7 -1.10658e-7 -0.08954165 -1.6147e-7 -0.5970257 -0.8022222 0.02421998 3.16183e-8 0.8022222 -0.5970257 0.03911464 0 0 0 1 1 -1.16631e-7 -1.15122e-7 -0.08954165 -1.60768e-7 -0.561992 -0.8271427 0.02421998 3.17727e-8 0.8271427 -0.561992 0.03911464 0 0 0 1 1 -1.11768e-7 -1.19011e-7 -0.08954165 -1.60121e-7 -0.5290233 -0.8486072 0.02421998 3.18874e-8 0.8486072 -0.5290233 0.03911464 0 0 0 1 1 -1.07668e-7 -1.22054e-7 -0.08954165 -1.59587e-7 -0.5013782 -0.8652282 0.02421998 3.19625e-8 0.8652282 -0.5013782 0.03911464 0 0 0 1 1 -1.04843e-7 -1.24036e-7 -0.08954165 -1.59225e-7 -0.4823915 -0.8759558 0.02421998 3.20034e-8 0.8759558 -0.4823915 0.03911464 0 0 0 1 + + + + + + + + LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR + + + + + + + + + + + + + + + + 0 0.04166662 0.08333331 0.125 0.1666666 0.2083333 0.25 0.2916666 0.3333333 0.375 0.4166666 0.4583333 0.5 0.5416667 0.5833333 0.625 0.6666667 0.7083333 0.75 0.7916667 0.8333333 0.875 0.9166667 0.9583333 1 1.041667 1.083333 1.125 1.166667 1.208333 1.25 1.291667 1.333333 1.375 1.416667 1.458333 1.5 1.541667 1.583333 1.625 1.666667 1.708333 1.75 1.791667 1.833333 1.875 1.916667 1.958333 2 2.041667 2.083333 2.125 2.166667 2.208333 2.25 2.291667 2.333333 2.375 2.416667 2.458333 + + + + + + + + 1 -9.23719e-8 -1.82491e-7 0 8.78508e-8 -0.6117519 0.7910497 0 -1.8471e-7 -0.7910497 -0.6117519 -0.375647 0 0 0 1 1 -9.21309e-8 -1.82502e-7 0 8.77097e-8 -0.6130231 0.7900649 -1.49012e-8 -1.84667e-7 -0.7900649 -0.6130231 -0.3756471 0 0 0 1 1 -9.14523e-8 -1.82529e-7 0 8.73129e-8 -0.6165926 0.7872824 1.49012e-8 -1.84545e-7 -0.7872824 -0.6165926 -0.3756471 0 0 0 1 1 -9.04029e-8 -1.82565e-7 0 8.67007e-8 -0.6220857 0.7829491 0 -1.84352e-7 -0.7829491 -0.6220857 -0.3756471 0 0 0 1 1 -8.90498e-8 -1.82601e-7 0 8.59134e-8 -0.6291227 0.7773059 0 -1.84097e-7 -0.7773059 -0.6291227 -0.375647 0 0 0 1 1 -8.74598e-8 -1.82627e-7 0 8.49915e-8 -0.6373243 0.7705957 1.49012e-8 -1.83789e-7 -0.7705957 -0.6373243 -0.3756471 0 0 0 1 1 -8.57004e-8 -1.82637e-7 1.49012e-8 8.39752e-8 -0.6463159 0.7630702 0 -1.83436e-7 -0.7630702 -0.6463159 -0.3756471 0 0 0 1 1 -8.3839e-8 -1.82625e-7 7.45058e-9 8.29047e-8 -0.6557313 0.7549945 0 -1.83051e-7 -0.7549945 -0.6557313 -0.3756471 0 0 0 1 1 -8.19435e-8 -1.82588e-7 0 8.18194e-8 -0.6652167 0.7466503 -1.49012e-8 -1.82644e-7 -0.7466503 -0.6652167 -0.3756471 0 0 0 1 1 -8.0082e-8 -1.82529e-7 -7.45058e-9 8.07583e-8 -0.6744326 0.7383364 1.49012e-8 -1.82231e-7 -0.7383364 -0.6744326 -0.3756471 0 0 0 1 1 -7.83221e-8 -1.82453e-7 -7.45058e-9 7.97594e-8 -0.683053 0.7303687 7.45058e-9 -1.81829e-7 -0.7303687 -0.683053 -0.375647 0 0 0 1 1 -7.67317e-8 -1.82365e-7 0 7.88604e-8 -0.6907667 0.7230778 7.45058e-9 -1.81455e-7 -0.7230778 -0.6907667 -0.375647 0 0 0 1 1 -7.53781e-8 -1.82277e-7 0 7.8098e-8 -0.6972747 0.7168041 7.45058e-9 -1.81129e-7 -0.7168041 -0.6972747 -0.3756471 0 0 0 1 1 -7.43283e-8 -1.82201e-7 -7.45058e-9 7.75084e-8 -0.7022852 0.7118958 0 -1.80871e-7 -0.7118958 -0.7022852 -0.375647 0 0 0 1 1 -7.36494e-8 -1.82148e-7 -1.49012e-8 7.71279e-8 -0.7055086 0.7087014 3.72529e-9 -1.80702e-7 -0.7087014 -0.7055086 -0.375647 0 0 0 1 1 -7.34082e-8 -1.82128e-7 0 7.69929e-8 -0.7066507 0.7075625 0 -1.80642e-7 -0.7075625 -0.7066507 -0.375647 0 0 0 1 1 -7.40854e-8 -1.8219e-7 7.45058e-9 7.73468e-8 -0.7035621 0.7106338 0 -1.8083e-7 -0.7106338 -0.7035621 -0.3756471 0 0 0 1 1 -7.59935e-8 -1.8235e-7 -7.45058e-9 7.83476e-8 -0.6947945 0.7192084 0 -1.81351e-7 -0.7192084 -0.6947945 -0.3756471 0 0 0 1 1 -7.8949e-8 -1.8255e-7 0 7.99084e-8 -0.6810244 0.7322606 -9.31323e-10 -1.82133e-7 -0.7322606 -0.6810244 -0.3756471 0 0 0 1 1 -8.27674e-8 -1.82727e-7 0 8.19438e-8 -0.662894 0.7487133 2.32831e-10 -1.83097e-7 -0.7487133 -0.662894 -0.375647 0 0 0 1 1 -8.72608e-8 -1.82814e-7 0 8.43663e-8 -0.6410699 0.7674825 9.31323e-10 -1.84168e-7 -0.7674825 -0.6410699 -0.3756471 0 0 0 1 1 -9.2236e-8 -1.8276e-7 -7.45058e-9 8.70829e-8 -0.6162902 0.7875191 0 -1.85271e-7 -0.7875191 -0.6162902 -0.375647 0 0 0 1 1 -9.74954e-8 -1.8253e-7 -7.45058e-9 8.9994e-8 -0.5893902 0.8078485 0 -1.86343e-7 -0.8078485 -0.5893902 -0.375647 0 0 0 1 1 -1.02839e-7 -1.82114e-7 7.45058e-9 9.29933e-8 -0.5613146 0.8276026 -3.72529e-9 -1.87333e-7 -0.8276026 -0.5613146 -0.375647 0 0 0 1 1 -1.08068e-7 -1.81528e-7 7.45058e-9 9.59687e-8 -0.5331112 0.8460453 -3.72529e-9 -1.88205e-7 -0.8460453 -0.5331112 -0.3756471 0 0 0 1 1 -1.12986e-7 -1.80812e-7 -7.45058e-9 9.88048e-8 -0.5059144 0.8625836 7.45058e-9 -1.88935e-7 -0.8625836 -0.5059144 -0.375647 0 0 0 1 1 -1.17404e-7 -1.80032e-7 0 1.01384e-7 -0.4809202 0.8767643 1.49012e-8 -1.89517e-7 -0.8767643 -0.4809202 -0.375647 0 0 0 1 1 -1.21141e-7 -1.7927e-7 -1.49012e-8 1.03589e-7 -0.4593579 0.8882512 7.45058e-9 -1.89953e-7 -0.8882512 -0.4593579 -0.375647 0 0 0 1 1 -1.24023e-7 -1.78616e-7 -7.45058e-9 1.05304e-7 -0.4424657 0.8967854 0 -1.90254e-7 -0.8967854 -0.4424657 -0.3756471 0 0 0 1 1 -1.25879e-7 -1.78165e-7 -1.49012e-8 1.06416e-7 -0.4314651 0.9021297 0 -1.90431e-7 -0.9021297 -0.4314651 -0.375647 0 0 0 1 1 -6.45572e-8 -1.65437e-7 0 1.21953e-7 -0.4275432 0.903995 7.45058e-9 -1.29091e-7 -0.903995 -0.4275432 -0.3756471 0 0 0 1 1 -6.28213e-8 -1.65539e-7 0 1.21171e-7 -0.4388915 0.8985401 7.45058e-9 -1.29101e-7 -0.8985401 -0.4388915 -0.3756471 0 0 0 1 1 -5.79009e-8 -1.65708e-7 -7.45058e-9 1.18958e-7 -0.4706401 0.8823252 7.45058e-9 -1.29076e-7 -0.8823252 -0.4706401 -0.3756471 0 0 0 1 1 -5.021e-8 -1.65622e-7 7.45058e-9 1.15506e-7 -0.5190303 0.8547559 7.45058e-9 -1.2888e-7 -0.8547559 -0.5190303 -0.375647 0 0 0 1 1 -4.01929e-8 -1.64866e-7 0 1.11023e-7 -0.5797908 0.8147655 3.72529e-9 -1.28335e-7 -0.8147655 -0.5797908 -0.3756471 0 0 0 1 1 -2.83783e-8 -1.63018e-7 -7.45058e-9 1.05755e-7 -0.6481006 0.7615547 0 -1.27264e-7 -0.7615547 -0.6481006 -0.375647 0 0 0 1 1 -1.54023e-8 -1.59748e-7 7.45058e-9 9.9995e-8 -0.7187634 0.6952548 0 -1.2553e-7 -0.6952548 -0.7187634 -0.375647 0 0 0 1 1 -1.98788e-9 -1.54897e-7 0 9.40702e-8 -0.7866458 0.6174045 9.31323e-10 -1.23076e-7 -0.6174045 -0.7866458 -0.3756471 0 0 0 1 1 1.11198e-8 -1.48542e-7 0 8.8314e-8 -0.8473023 0.5311109 -9.31323e-10 -1.19954e-7 -0.5311109 -0.8473023 -0.3756471 0 0 0 1 1 2.3244e-8 -1.4101e-7 7.45058e-9 8.30235e-8 -0.8975955 0.44082 -1.86265e-9 -1.16323e-7 -0.44082 -0.8975955 -0.3756471 0 0 0 1 1 3.38599e-8 -1.32836e-7 -7.45058e-9 7.84235e-8 -0.9360867 0.3517694 -3.72529e-9 -1.12435e-7 -0.3517694 -0.9360867 -0.3756471 0 0 0 1 1 4.26408e-8 -1.24688e-7 1.49012e-8 7.4647e-8 -0.9630488 0.2693275 0 -1.08596e-7 -0.2693275 -0.9630488 -0.3756471 0 0 0 1 1 4.94508e-8 -1.17273e-7 -7.45058e-9 7.17406e-8 -0.9801102 0.1984538 0 -1.05127e-7 -0.1984538 -0.9801102 -0.3756471 0 0 0 1 1 5.42906e-8 -1.11271e-7 7.45058e-9 6.96901e-8 -0.9896587 0.1434426 -7.45058e-9 -1.02332e-7 -0.1434426 -0.9896587 -0.3756471 0 0 0 1 1 5.72101e-8 -1.07289e-7 0 6.84605e-8 -0.9941532 0.1079777 0 -1.00485e-7 -0.1079777 -0.9941532 -0.375647 0 0 0 1 1 5.82071e-8 -1.05858e-7 7.45058e-9 6.80421e-8 -0.9954376 0.09541538 0 -9.98216e-8 -0.09541538 -0.9954376 -0.3756471 0 0 0 1 1 5.74341e-8 -1.06986e-7 0 6.84018e-8 -0.994418 0.1055111 0 -1.00329e-7 -0.1055111 -0.994418 -0.375647 0 0 0 1 1 5.51895e-8 -1.10128e-7 7.45058e-9 6.94453e-8 -0.9909862 0.1339645 1.49012e-8 -1.01742e-7 -0.1339645 -0.9909862 -0.3756471 0 0 0 1 1 5.15209e-8 -1.14886e-7 -7.45058e-9 7.11481e-8 -0.98403 0.1780031 0 -1.0388e-7 -0.1780031 -0.98403 -0.3756471 0 0 0 1 1 4.64444e-8 -1.20813e-7 7.45058e-9 7.34997e-8 -0.972073 0.2346787 0 -1.0654e-7 -0.2346787 -0.972073 -0.3756471 0 0 0 1 1 4.00031e-8 -1.27437e-7 7.45058e-9 7.64772e-8 -0.9537049 0.3007442 1.49012e-8 -1.09507e-7 -0.3007442 -0.9537049 -0.375647 0 0 0 1 1 3.23149e-8 -1.34275e-7 7.45058e-9 8.00234e-8 -0.9279765 0.3726389 -2.98023e-8 -1.12562e-7 -0.3726389 -0.9279765 -0.3756471 0 0 0 1 1 2.36023e-8 -1.40872e-7 7.45058e-9 8.40338e-8 -0.8947237 0.44662 -2.98023e-8 -1.155e-7 -0.44662 -0.8947237 -0.3756471 0 0 0 1 1 1.41989e-8 -1.46849e-7 0 8.8354e-8 -0.8547637 0.5190172 0 -1.18152e-7 -0.5190172 -0.8547637 -0.375647 0 0 0 1 1 4.53275e-9 -1.51934e-7 7.45058e-9 9.27874e-8 -0.8099177 0.5865436 1.49012e-8 -1.20396e-7 -0.5865436 -0.8099177 -0.3756471 0 0 0 1 1 -4.91e-9 -1.55989e-7 7.45058e-9 9.71116e-8 -0.7628592 0.6465646 0 -1.22173e-7 -0.6465646 -0.7628592 -0.375647 0 0 0 1 1 -1.36261e-8 -1.59006e-7 0 1.01098e-7 -0.7168373 0.6972403 0 -1.23482e-7 -0.6972403 -0.7168373 -0.375647 0 0 0 1 1 -2.11316e-8 -1.61085e-7 -7.45058e-9 1.04527e-7 -0.6753571 0.7374908 1.49012e-8 -1.24374e-7 -0.7374908 -0.6753571 -0.375647 0 0 0 1 1 -2.69808e-8 -1.62386e-7 1.49012e-8 1.07197e-7 -0.6418994 0.7667888 -1.49012e-8 -1.24924e-7 -0.7667888 -0.6418994 -0.375647 0 0 0 1 1 -3.07678e-8 -1.63085e-7 1.49012e-8 1.08925e-7 -0.619724 0.7848199 0 -1.25215e-7 -0.7848199 -0.619724 -0.3756471 0 0 0 1 + + + + + + + + LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR + + + + + + + + + + + + + + + + 0 0.04166662 0.08333331 0.125 0.1666666 0.2083333 0.25 0.2916666 0.3333333 0.375 0.4166666 0.4583333 0.5 0.5416667 0.5833333 0.625 0.6666667 0.7083333 0.75 0.7916667 0.8333333 0.875 0.9166667 0.9583333 1 1.041667 1.083333 1.125 1.166667 1.208333 1.25 1.291667 1.333333 1.375 1.416667 1.458333 1.5 1.541667 1.583333 1.625 1.666667 1.708333 1.75 1.791667 1.833333 1.875 1.916667 1.958333 2 2.041667 2.083333 2.125 2.166667 2.208333 2.25 2.291667 2.333333 2.375 2.416667 2.458333 + + + + + + + + 1 3.01186e-7 -2.3825e-7 -7.45058e-9 -2.83652e-7 0.9975151 0.07045417 7.45058e-9 2.58877e-7 -0.07045422 0.9975151 -0.4310732 0 0 0 1 1 3.00348e-7 -2.39224e-7 0 -2.83694e-7 0.9977656 0.06681252 0 2.58757e-7 -0.06681257 0.9977656 -0.4310732 0 0 0 1 1 2.97955e-7 -2.4197e-7 0 -2.83811e-7 0.9984034 0.0564853 -7.45058e-9 2.58414e-7 -0.05648535 0.9984035 -0.4310732 0 0 0 1 1 2.94162e-7 -2.46205e-7 -7.45058e-9 -2.83986e-7 0.9991853 0.04035893 0 2.57877e-7 -0.04035901 0.9991853 -0.4310732 0 0 0 1 1 2.89115e-7 -2.51633e-7 0 -2.842e-7 0.9998134 0.01931971 1.49012e-8 2.57172e-7 -0.01931977 0.9998134 -0.4310733 0 0 0 1 1 2.8296e-7 -2.57953e-7 1.49012e-8 -2.84434e-7 0.9999837 -0.005731463 -1.11759e-8 2.56327e-7 0.005731419 0.9999838 -0.4310732 0 0 0 1 1 2.75857e-7 -2.64866e-7 0 -2.8467e-7 0.9994262 -0.03386962 1.86265e-8 2.55371e-7 0.03386953 0.9994263 -0.4310733 0 0 0 1 1 2.67991e-7 -2.72085e-7 -7.45058e-9 -2.84892e-7 0.9979407 -0.06414352 9.31323e-9 2.54334e-7 0.06414346 0.9979407 -0.4310733 0 0 0 1 1 2.59575e-7 -2.79338e-7 0 -2.85086e-7 0.9954218 -0.09558101 -1.30385e-8 2.53249e-7 0.09558089 0.9954217 -0.4310732 0 0 0 1 1 2.50854e-7 -2.86382e-7 -7.45058e-9 -2.85244e-7 0.9918774 -0.1271988 2.98023e-8 2.52147e-7 0.1271986 0.9918773 -0.4310733 0 0 0 1 1 2.42103e-7 -2.93002e-7 -7.45058e-9 -2.8536e-7 0.9874364 -0.1580167 2.98023e-8 2.51065e-7 0.1580166 0.9874365 -0.4310732 0 0 0 1 1 2.3362e-7 -2.99019e-7 0 -2.85434e-7 0.9823464 -0.1870718 -7.45058e-9 2.50036e-7 0.1870718 0.9823464 -0.4310732 0 0 0 1 1 2.25725e-7 -3.04284e-7 0 -2.85467e-7 0.9769583 -0.2134305 2.23517e-8 2.49096e-7 0.2134304 0.9769583 -0.4310733 0 0 0 1 1 2.18748e-7 -3.08679e-7 0 -2.85467e-7 0.971706 -0.2361934 1.49012e-8 2.48278e-7 0.2361934 0.9717062 -0.4310732 0 0 0 1 1 2.13024e-7 -3.12108e-7 7.45058e-9 -2.8544e-7 0.9670739 -0.2544962 2.98023e-8 2.47617e-7 0.2544961 0.9670739 -0.4310733 0 0 0 1 1 2.08884e-7 -3.14482e-7 -7.45058e-9 -2.85396e-7 0.9635583 -0.2674987 4.47035e-8 2.47146e-7 0.2674987 0.9635583 -0.4310732 0 0 0 1 1 2.05851e-7 -3.16165e-7 -7.45058e-9 -2.85347e-7 0.9608997 -0.2768966 1.49012e-8 2.46804e-7 0.2768965 0.9608998 -0.4310733 0 0 0 1 1 2.03212e-7 -3.17598e-7 0 -2.85302e-7 0.9585249 -0.285009 0 2.46508e-7 0.285009 0.9585249 -0.4310732 0 0 0 1 1 2.00943e-7 -3.18806e-7 0 -2.85261e-7 0.956437 -0.2919388 0 2.46255e-7 0.2919386 0.9564371 -0.4310732 0 0 0 1 1 1.99018e-7 -3.19815e-7 0 -2.85226e-7 0.954633 -0.2977853 -2.98023e-8 2.46042e-7 0.2977853 0.954633 -0.4310732 0 0 0 1 1 1.9741e-7 -3.20647e-7 7.45058e-9 -2.85195e-7 0.9531031 -0.3026462 0 2.45864e-7 0.3026462 0.9531031 -0.4310732 0 0 0 1 1 1.96092e-7 -3.21321e-7 0 -2.85169e-7 0.9518331 -0.3066168 -4.47035e-8 2.45719e-7 0.3066167 0.9518332 -0.4310732 0 0 0 1 1 1.95035e-7 -3.21856e-7 7.45058e-9 -2.85148e-7 0.9508051 -0.3097898 0 2.45603e-7 0.3097898 0.9508051 -0.4310732 0 0 0 1 1 1.94211e-7 -3.2227e-7 0 -2.85131e-7 0.9499977 -0.3122572 -1.49012e-8 2.45512e-7 0.3122572 0.9499977 -0.4310733 0 0 0 1 1 1.93592e-7 -3.2258e-7 -7.45058e-9 -2.85119e-7 0.9493868 -0.3141092 0 2.45444e-7 0.3141091 0.9493868 -0.4310732 0 0 0 1 1 1.93148e-7 -3.22801e-7 1.49012e-8 -2.8511e-7 0.9489471 -0.3154351 0 2.45396e-7 0.3154351 0.9489471 -0.4310732 0 0 0 1 1 1.9285e-7 -3.22949e-7 0 -2.85103e-7 0.9486516 -0.3163233 -2.98023e-8 2.45363e-7 0.3163232 0.9486516 -0.4310732 0 0 0 1 1 1.92669e-7 -3.23039e-7 0 -2.851e-7 0.9484717 -0.316862 5.96046e-8 2.45344e-7 0.316862 0.9484716 -0.4310732 0 0 0 1 1 1.92576e-7 -3.23085e-7 0 -2.85098e-7 0.9483793 -0.3171385 0 2.45333e-7 0.3171385 0.9483793 -0.4310733 0 0 0 1 1 1.92542e-7 -3.23102e-7 7.45058e-9 -2.85097e-7 0.9483453 -0.3172403 0 2.4533e-7 0.3172403 0.9483452 -0.4310732 0 0 0 1 1 2.86338e-7 -3.55313e-7 0 -3.84271e-7 0.9483405 -0.3172548 -2.98023e-8 2.46116e-7 0.3172547 0.9483405 -0.4310733 0 0 0 1 1 2.86444e-7 -3.5525e-7 0 -3.84275e-7 0.9484386 -0.3169612 -2.98023e-8 2.46142e-7 0.3169612 0.9484387 -0.4310732 0 0 0 1 1 2.86781e-7 -3.55049e-7 7.45058e-9 -3.84287e-7 0.9487527 -0.3160196 0 2.46225e-7 0.3160195 0.9487528 -0.4310732 0 0 0 1 1 2.87381e-7 -3.54689e-7 0 -3.84307e-7 0.9493109 -0.3143387 -2.98023e-8 2.46375e-7 0.3143386 0.9493109 -0.4310732 0 0 0 1 1 2.88276e-7 -3.54148e-7 -2.23517e-8 -3.84335e-7 0.9501391 -0.3118261 0 2.46598e-7 0.311826 0.9501392 -0.4310732 0 0 0 1 1 2.89495e-7 -3.53405e-7 7.45058e-9 -3.8437e-7 0.9512609 -0.3083877 1.49012e-8 2.46904e-7 0.3083875 0.9512609 -0.4310733 0 0 0 1 1 2.91067e-7 -3.52435e-7 7.45058e-9 -3.84413e-7 0.9526949 -0.3039284 -2.98023e-8 2.47299e-7 0.3039284 0.9526949 -0.4310732 0 0 0 1 1 2.93022e-7 -3.51213e-7 7.45058e-9 -3.84461e-7 0.9544564 -0.2983507 2.98023e-8 2.47794e-7 0.2983507 0.9544564 -0.4310733 0 0 0 1 1 2.95387e-7 -3.49711e-7 7.45058e-9 -3.84514e-7 0.956554 -0.2915555 -1.49012e-8 2.48395e-7 0.2915555 0.9565541 -0.4310733 0 0 0 1 1 2.98189e-7 -3.47898e-7 0 -3.84569e-7 0.9589897 -0.283441 0 2.49112e-7 0.2834409 0.9589899 -0.4310733 0 0 0 1 1 3.0145e-7 -3.45743e-7 7.45058e-9 -3.84622e-7 0.9617573 -0.2739032 4.47035e-8 2.49953e-7 0.2739032 0.9617574 -0.4310733 0 0 0 1 1 3.05193e-7 -3.43209e-7 7.45058e-9 -3.84671e-7 0.9648407 -0.2628356 -1.49012e-8 2.50926e-7 0.2628355 0.9648408 -0.4310733 0 0 0 1 1 3.09438e-7 -3.40255e-7 0 -3.84709e-7 0.9682125 -0.2501294 0 2.5204e-7 0.2501293 0.9682126 -0.4310733 0 0 0 1 1 3.14198e-7 -3.3684e-7 -7.45058e-9 -3.84732e-7 0.9718321 -0.2356741 -7.45058e-9 2.53303e-7 0.2356739 0.9718321 -0.4310732 0 0 0 1 1 3.19487e-7 -3.32914e-7 -7.45058e-9 -3.84733e-7 0.9756446 -0.2193576 2.98023e-8 2.54724e-7 0.2193575 0.9756446 -0.4310733 0 0 0 1 1 3.2531e-7 -3.28425e-7 7.45058e-9 -3.84702e-7 0.9795773 -0.2010675 -2.23517e-8 2.56309e-7 0.2010675 0.9795774 -0.4310732 0 0 0 1 1 3.3164e-7 -3.23341e-7 -7.45058e-9 -3.8463e-7 0.9835232 -0.1807818 4.47035e-8 2.58059e-7 0.1807816 0.9835234 -0.4310732 0 0 0 1 1 3.38338e-7 -3.17717e-7 -7.45058e-9 -3.84509e-7 0.9873044 -0.1588394 2.98023e-8 2.59942e-7 0.1588393 0.9873044 -0.4310733 0 0 0 1 1 3.45243e-7 -3.11643e-7 7.45058e-9 -3.84334e-7 0.9907528 -0.1356803 -4.00469e-8 2.61919e-7 0.1356803 0.9907528 -0.4310732 0 0 0 1 1 3.522e-7 -3.05221e-7 0 -3.84104e-7 0.9937357 -0.1117559 -1.86265e-9 2.63949e-7 0.1117558 0.9937357 -0.4310732 0 0 0 1 1 3.59067e-7 -2.98567e-7 7.45058e-9 -3.83821e-7 0.9961623 -0.08752683 -5.58794e-8 2.65993e-7 0.08752674 0.9961623 -0.4310732 0 0 0 1 1 3.6571e-7 -2.91807e-7 7.45058e-9 -3.8349e-7 0.9979844 -0.06345913 -7.45058e-9 2.68012e-7 0.06345904 0.9979845 -0.4310732 0 0 0 1 1 3.7201e-7 -2.85082e-7 7.45058e-9 -3.83121e-7 0.999199 -0.04002023 4.47035e-8 2.69966e-7 0.0400202 0.999199 -0.4310733 0 0 0 1 1 3.77862e-7 -2.78541e-7 1.49012e-8 -3.82726e-7 0.9998438 -0.01767585 7.45058e-9 2.71819e-7 0.0176757 0.9998438 -0.4310733 0 0 0 1 1 3.83171e-7 -2.72342e-7 0 -3.82321e-7 0.9999952 0.003114864 7.45058e-9 2.73534e-7 -0.003114983 0.9999952 -0.4310733 0 0 0 1 1 3.87856e-7 -2.66646e-7 0 -3.81924e-7 0.9997602 0.02189974 -2.98023e-8 2.75076e-7 -0.02189988 0.9997602 -0.4310733 0 0 0 1 1 3.91844e-7 -2.6162e-7 0 -3.81555e-7 0.9992688 0.03823569 -7.45058e-9 2.76411e-7 -0.03823574 0.9992688 -0.4310732 0 0 0 1 1 3.95068e-7 -2.5743e-7 0 -3.81234e-7 0.9986634 0.05168781 2.98023e-8 2.77506e-7 -0.05168788 0.9986634 -0.4310733 0 0 0 1 1 3.97461e-7 -2.54242e-7 7.45058e-9 -3.80982e-7 0.998087 0.06182647 -7.45058e-9 2.78329e-7 -0.06182654 0.998087 -0.4310732 0 0 0 1 1 3.98955e-7 -2.52216e-7 0 -3.80818e-7 0.9976699 0.068225 7.45058e-9 2.78848e-7 -0.06822507 0.99767 -0.4310732 0 0 0 1 + + + + + + + + LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR + + + + + + + + + + + + + + + + + + + 1 0 0 0 0 0 1 0 0 -1 0 0 0 0 0 1 + + 1 0 0 0 0 0 -1 0.02018755 0 1 0 0.04088391 0 0 0 1 + + 1 0 0 0 0 0.9934375 -0.1143761 0.194438 0 0.1143761 0.9934375 0 0 0 0 1 + + 1 0 0 0 0 0.9258053 0.3780007 0.3676334 -2.22827e-16 -0.3780007 0.9258054 -3.72529e-9 0 0 0 1 + + 1 0 0 0 0 0.9957995 -0.09156077 0.07797433 0 0.09156074 0.9957995 -9.77889e-9 0 0 0 1 + + + 1 + 0 + 0 + 0.03303807 + 0.1802077 + + + + + + 1 + 0 + + + + + -0.09349707 0.9940777 -0.05538832 0.1656292 -0.9890745 -0.08636999 0.1194651 0.3007234 0.1139737 0.0659528 0.9912922 0.02458553 0 0 0 1 + + 0.9999269 -0.0121001 1.47073e-4 2.98023e-8 0.01207914 0.9987785 0.04791368 0.3238729 -7.26653e-4 -0.0479084 0.9988516 -5.58794e-9 0 0 0 1 + + 0.9996847 0.02510269 8.13621e-4 -8.56817e-8 -0.02508879 0.9965788 0.07874946 0.2581572 0.001165986 -0.07874503 0.9968942 0 0 0 0 1 + + 0.9943069 -0.1063873 0.005958037 1.49012e-8 0.1064871 0.9901453 -0.09095558 0.1130893 0.003777199 0.09107221 0.995837 -1.49012e-8 0 0 0 1 + + 0.9999999 5.68249e-5 5.80214e-7 -1.97906e-8 -5.68249e-5 0.9997917 0.02040377 0.04929709 5.79515e-7 -0.02040377 0.9997917 0 0 0 0 1 + + 0.9999999 -1.63528e-4 4.80562e-6 6.49015e-9 1.63528e-4 0.9982743 -0.05872198 0.03822243 4.80539e-6 0.05872198 0.9982743 0 0 0 0 1 + + + 1 + 1.573581 + 0.03419893 + -0.002011656 + 0 + + + + + + 1 + 1.573581 + + + + + + 1 + 1.573581 + + + + + 0.9942042 -0.106431 0.01518451 0.007374659 0.1072289 0.99186 -0.0686724 0.114673 -0.007752027 0.06990261 0.9975237 -0.02407584 0 0 0 1 + + 0.9997627 0.02178483 -3.39467e-6 -2.43017e-8 -0.0217846 0.9997514 -0.004763506 0.04910958 -1.00378e-4 0.00476245 0.9999886 -1.86265e-9 0 0 0 1 + + 0.9997481 -0.02242242 9.11376e-4 3.35276e-8 0.02244093 0.9989072 -0.0409967 0.03219759 8.86247e-6 0.04100683 0.9991589 0 0 0 0 1 + + + 1 + 1.585134 + 0.03364485 + -0.001513421 + 0 + + + + + + 1 + 1.607066 + + + + + + 1.585134 + + + + + 0.9942042 -0.106431 0.0151845 0.01757193 0.1072289 0.9918599 -0.06867235 0.1194025 -0.007752028 0.06990255 0.9975237 -0.0453514 0 0 0 1 + + 1 -2.51458e-4 2.20258e-6 -7.61065e-9 2.51458e-4 0.9998461 -0.01753639 0.02511728 2.20817e-6 0.01753639 0.9998462 0 0 0 0 1 + + + 1 + 1.585134 + 0.02438956 + -4.07464e-4 + 0 + + + + + + 1.585134 + + + + + 0.9942043 -0.1064312 0.01516978 -9.2914e-4 0.107227 0.9918696 -0.06853521 0.1201515 -0.007752162 0.06976461 0.9975333 0.02650937 0 0 0 1 + + 0.9999996 -8.57367e-4 2.56589e-5 5.82077e-10 8.57368e-4 0.9982103 -0.05979437 0.04212457 2.56533e-5 0.05979438 0.9982107 -7.45058e-9 0 0 0 1 + + 0.9999995 9.40783e-4 3.08976e-5 9.77889e-9 -9.40783e-4 0.9978448 0.06561208 0.0316624 3.08966e-5 -0.06561208 0.9978453 -7.45058e-9 0 0 0 1 + + + 1 + 1.585134 + 0.03422701 + 2.32823e-4 + 0 + + + + + + 1 + 1.585134 + + + + + + 1.585134 + + + + + 0.9942043 -0.1064312 0.01516974 -0.001006626 0.107227 0.9918696 -0.06853475 0.1194239 -0.007752167 0.06976414 0.9975334 0.05007137 0 0 0 1 + + 0.9999996 -8.57354e-4 2.56523e-5 2.04891e-8 8.57354e-4 0.9982103 -0.05979469 0.02885437 2.56589e-5 0.05979469 0.9982107 0 0 0 0 1 + + 0.9999996 9.40776e-4 3.08966e-5 2.64845e-8 -9.40776e-4 0.9978449 0.0656116 0.02168822 3.08957e-5 -0.06561161 0.9978453 0 0 0 0 1 + + + 1 + 1.585134 + 0.02344489 + 1.59472e-4 + 0 + + + + + + 1 + 1.585134 + + + + + + 1.585134 + + + + + + 1 + 1.676481 + + + + + + 1 + 1.652283 + + + + + + 1.664325 + + + + + -0.09349707 -0.9940777 0.05538832 -0.1656292 0.9890745 -0.08636999 0.1194651 0.3007234 -0.1139737 0.0659528 0.9912922 0.02458553 0 0 0 1 + + 0.9999269 0.0121001 -1.47073e-4 -2.98023e-8 -0.01207914 0.9987785 0.04791368 0.3238729 7.26653e-4 -0.0479084 0.9988516 -5.58794e-9 0 0 0 1 + + 0.9996847 -0.02510269 -8.13621e-4 8.56817e-8 0.02508879 0.9965788 0.07874946 0.2581572 -0.001165986 -0.07874503 0.9968942 0 0 0 0 1 + + 0.9943069 0.1063873 -0.005958037 -1.49012e-8 -0.1064871 0.9901453 -0.09095558 0.1130893 -0.003777199 0.09107221 0.995837 -1.49012e-8 0 0 0 1 + + 0.9999999 -5.68249e-5 -5.80214e-7 1.97906e-8 5.68249e-5 0.9997917 0.02040377 0.04929709 -5.79515e-7 -0.02040377 0.9997917 0 0 0 0 1 + + 0.9999999 1.63528e-4 -4.80562e-6 -6.49015e-9 -1.63528e-4 0.9982743 -0.05872198 0.03822243 -4.80539e-6 0.05872198 0.9982743 0 0 0 0 1 + + + 1 + -1.573581 + -0.03419893 + -0.002011656 + 0 + + + + + + 1 + -1.573581 + + + + + + 1 + -1.573581 + + + + + 0.9942042 0.106431 -0.01518451 -0.007374659 -0.1072289 0.99186 -0.0686724 0.114673 0.007752027 0.06990261 0.9975237 -0.02407584 0 0 0 1 + + 0.9997627 -0.02178483 3.39467e-6 2.43017e-8 0.0217846 0.9997514 -0.004763506 0.04910958 1.00378e-4 0.00476245 0.9999886 -1.86265e-9 0 0 0 1 + + 0.9997481 0.02242242 -9.11376e-4 -3.35276e-8 -0.02244093 0.9989072 -0.0409967 0.03219759 -8.86247e-6 0.04100683 0.9991589 0 0 0 0 1 + + + 1 + -1.585134 + -0.03364485 + -0.001513421 + 0 + + + + + + 1 + -1.607066 + + + + + + -1.585134 + + + + + 0.9942042 0.106431 -0.0151845 -0.01757193 -0.1072289 0.9918599 -0.06867235 0.1194025 0.007752028 0.06990255 0.9975237 -0.0453514 0 0 0 1 + + 1 2.51458e-4 -2.20258e-6 7.61065e-9 -2.51458e-4 0.9998461 -0.01753639 0.02511728 -2.20817e-6 0.01753639 0.9998462 0 0 0 0 1 + + + 1 + -1.585134 + -0.02438956 + -4.07464e-4 + 0 + + + + + + -1.585134 + + + + + 0.9942043 0.1064312 -0.01516978 9.2914e-4 -0.107227 0.9918696 -0.06853521 0.1201515 0.007752162 0.06976461 0.9975333 0.02650937 0 0 0 1 + + 0.9999996 8.57367e-4 -2.56589e-5 -5.82077e-10 -8.57368e-4 0.9982103 -0.05979437 0.04212457 -2.56533e-5 0.05979438 0.9982107 -7.45058e-9 0 0 0 1 + + 0.9999995 -9.40783e-4 -3.08976e-5 -9.77889e-9 9.40783e-4 0.9978448 0.06561208 0.0316624 -3.08966e-5 -0.06561208 0.9978453 -7.45058e-9 0 0 0 1 + + + 1 + -1.585134 + -0.03422701 + 2.32823e-4 + 0 + + + + + + 1 + -1.585134 + + + + + + -1.585134 + + + + + 0.9942043 0.1064312 -0.01516974 0.001006626 -0.107227 0.9918696 -0.06853475 0.1194239 0.007752167 0.06976414 0.9975334 0.05007137 0 0 0 1 + + 0.9999996 8.57354e-4 -2.56523e-5 -2.04891e-8 -8.57354e-4 0.9982103 -0.05979469 0.02885437 -2.56589e-5 0.05979469 0.9982107 0 0 0 0 1 + + 0.9999996 -9.40776e-4 -3.08966e-5 -2.64845e-8 9.40776e-4 0.9978449 0.0656116 0.02168822 -3.08957e-5 -0.06561161 0.9978453 0 0 0 0 1 + + + 1 + -1.585134 + -0.02344489 + 1.59472e-4 + 0 + + + + + + 1 + -1.585134 + + + + + + -1.585134 + + + + + + 1 + -1.676481 + + + + + + 1 + -1.652283 + + + + + + -1.664325 + + + + + + 1 + 0 + + + + + 1 -4.79176e-14 -1.50996e-7 0.08954165 4.79176e-14 -1 6.34688e-7 -0.03911464 -1.50996e-7 -6.34688e-7 -1 0.02421998 0 0 0 1 + + 1 -6.31234e-9 3.25765e-7 0 -7.31181e-9 0.9991258 0.04180507 0.375647 -3.25744e-7 -0.04180507 0.9991258 0 0 0 0 1 + + 1 -1.64965e-7 1.59203e-7 -7.45058e-9 2.04969e-7 0.332252 -0.9431908 0.4310732 1.02698e-7 0.9431908 0.332252 0 0 0 0 1 + + + 1 + 2.17315e-7 + 0 + 0.1982285 + -0.07929152 + + + + + + 1 + 1.74901e-7 + + + + + + -1.50996e-7 + + + + + 1 -4.79176e-14 -1.50996e-7 -0.08954165 4.79176e-14 -1 6.34688e-7 -0.03911464 -1.50996e-7 -6.34688e-7 -1 0.02421998 0 0 0 1 + + 1 -6.31234e-9 -1.51072e-7 0 1.26224e-8 0.9991258 0.04180507 0.375647 1.50676e-7 -0.04180507 0.9991258 0 0 0 0 1 + + 1 2.84783e-7 -1.59203e-7 0 -2.44779e-7 0.332252 -0.9431908 0.4310732 -2.15709e-7 0.9431908 0.332252 1.86265e-9 0 0 0 1 + + + 1 + -2.59522e-7 + 0 + 0.1982285 + -0.07929152 + + + + + + 1 + -3.01936e-7 + + + + + + -1.50996e-7 + + + + + + + Bones + Bones + Bones + + + + + + + + + \ No newline at end of file diff --git a/assets/walkanim.dae b/assets/walkanim.dae new file mode 100644 index 0000000..7ba0af1 --- /dev/null +++ b/assets/walkanim.dae @@ -0,0 +1,741 @@ + + + + + Blender User + Blender 4.4.0 commit date:2025-03-17, commit time:17:00, hash:05377985c527 + + 2026-05-12T20:30:57 + 2026-05-12T20:30:57 + + Z_UP + + + + + + + + 0 0.04166662 0.08333331 0.125 0.1666666 0.2083333 0.25 0.2916666 0.3333333 0.375 0.4166666 0.4583333 0.5 0.5416667 0.5833333 0.625 0.6666667 0.7083333 0.75 0.7916667 0.8333333 0.875 0.9166667 0.9583333 1 1.041667 1.083333 1.125 1.166667 1.208333 1.25 1.291667 1.333333 1.375 1.416667 1.458333 1.5 1.541667 1.583333 1.625 1.666667 1.708333 1.75 1.791667 1.833333 1.875 1.916667 1.958333 2 2.041667 2.083333 2.125 2.166667 2.208333 2.25 2.291667 2.333333 2.375 2.416667 2.458333 + + + + + + + + 0.9974608 -0.07120392 0.001416472 0 0.07121801 0.9972635 -0.01983875 0 9.31323e-10 0.01988925 0.9998022 -0.194438 0 0 0 1 0.9975046 -0.070588 0.001404219 0 0.07060197 0.9973072 -0.01983961 0 1.86265e-9 0.01988924 0.9998022 -0.194438 0 0 0 1 0.9976298 -0.06879594 0.00136857 0 0.06880955 0.9974325 -0.01984211 0 0 0.01988925 0.9998022 -0.194438 0 0 0 1 0.9978247 -0.06591107 0.00131118 0 0.06592412 0.9976273 -0.019846 0 2.32831e-9 0.01988927 0.9998022 -0.194438 0 0 0 1 0.9980744 -0.06201645 0.001233704 0 0.06202872 0.9978769 -0.01985096 0 9.31323e-10 0.01988926 0.9998022 -0.194438 0 0 0 1 0.9983624 -0.057195 0.00113779 0 0.05720631 0.998165 -0.01985669 0 9.31323e-10 0.01988927 0.9998022 -0.194438 0 0 0 1 0.9986709 -0.05152971 0.001025089 0 0.05153991 0.9984733 -0.01986281 0 4.65661e-10 0.01988924 0.9998022 -0.194438 0 0 0 1 0.9989819 -0.04510372 8.97256e-4 0 0.04511264 0.9987842 -0.01986901 0 4.65661e-10 0.01988925 0.9998022 -0.194438 0 0 0 1 0.9992774 -0.03800046 7.55949e-4 0 0.03800798 0.9990798 -0.01987486 0 9.31323e-10 0.01988923 0.9998022 -0.194438 0 0 0 1 0.9995406 -0.03030368 6.02836e-4 0 0.03030967 0.9993429 -0.01988014 0 9.31323e-10 0.01988928 0.9998022 -0.194438 0 0 0 1 0.9997557 -0.02209756 4.3959e-4 0 0.02210193 0.9995579 -0.01988438 0 4.65661e-10 0.01988924 0.9998022 -0.194438 0 0 0 1 0.9999093 -0.01346664 2.67894e-4 0 0.0134693 0.9997115 -0.01988745 0 5.82077e-10 0.01988926 0.9998022 -0.194438 0 0 0 1 0.9999899 -0.004495829 8.94357e-5 0 0.004496719 0.9997921 -0.01988903 0 6.98492e-10 0.01988924 0.9998022 -0.194438 0 0 0 1 0.9999888 0.004729615 -9.4088e-5 0 -0.004730551 0.999791 -0.01988902 0 7.567e-10 0.01988924 0.9998022 -0.194438 0 0 0 1 0.9999002 0.01412421 -2.80976e-4 0 -0.014127 0.9997025 -0.01988728 0 6.98492e-10 0.01988926 0.9998022 -0.194438 0 0 0 1 0.9997213 0.02360236 -4.69527e-4 0 -0.02360703 0.9995236 -0.0198837 0 9.31323e-10 0.01988925 0.9998022 -0.194438 0 0 0 1 0.9994525 0.03307839 -6.58036e-4 0 -0.03308493 0.9992549 -0.01987838 0 9.31323e-10 0.01988926 0.9998022 -0.194438 0 0 0 1 0.9990975 0.0424667 -8.44799e-4 0 -0.04247511 0.9988999 -0.01987129 0 4.65661e-10 0.01988924 0.9998022 -0.194438 0 0 0 1 0.9986631 0.05168191 -0.001028119 0 -0.05169213 0.9984655 -0.01986264 0 2.32831e-9 0.01988924 0.9998022 -0.194438 0 0 0 1 0.9981591 0.06063889 -0.001206302 0 -0.06065089 0.9979616 -0.01985265 0 4.65661e-10 0.01988927 0.9998022 -0.194438 0 0 0 1 0.9975982 0.06925299 -0.001377662 0 -0.06926668 0.9974008 -0.01984148 0 -9.31323e-10 0.01988924 0.9998022 -0.194438 0 0 0 1 0.9969959 0.07743976 -0.001540526 0 -0.07745508 0.9967986 -0.01982953 0 1.86265e-9 0.01988927 0.9998022 -0.194438 0 0 0 1 0.9963697 0.08511558 -0.001693219 0 -0.08513242 0.9961725 -0.01981702 0 -9.31323e-10 0.01988924 0.9998022 -0.194438 0 0 0 1 0.9957391 0.09219695 -0.001834092 0 -0.09221519 0.9955422 -0.01980451 0 9.31323e-10 0.01988927 0.9998022 -0.194438 0 0 0 1 0.9951251 0.09860113 -0.001961492 0 -0.09862063 0.9949282 -0.01979231 0 1.86265e-9 0.01988926 0.9998022 -0.194438 0 0 0 1 0.9945495 0.1042455 -0.002073777 0 -0.1042662 0.9943527 -0.01978086 0 9.31323e-10 0.01988926 0.9998022 -0.194438 0 0 0 1 0.9940341 0.109048 -0.002169312 0 -0.1090696 0.9938375 -0.01977059 0 1.86265e-9 0.01988924 0.9998022 -0.194438 0 0 0 1 0.9936008 0.1129265 -0.002246468 0 -0.1129489 0.9934043 -0.01976195 0 0 0.01988923 0.9998022 -0.194438 0 0 0 1 0.99327 0.1157989 -0.002303609 0 -0.1158219 0.9930735 -0.01975539 0 0 0.01988924 0.9998022 -0.194438 0 0 0 1 0.9930603 0.1175831 -0.002339103 0 -0.1176064 0.9928639 -0.01975122 0 1.86265e-9 0.01988924 0.9998022 -0.194438 0 0 0 1 0.9929875 0.1181963 -0.002351301 0 -0.1182197 0.9927911 -0.01974978 0 9.31323e-10 0.01988925 0.9998022 -0.194438 0 0 0 1 0.9930603 0.1175831 -0.002339103 0 -0.1176064 0.9928639 -0.01975122 0 0 0.01988924 0.9998022 -0.194438 0 0 0 1 0.99327 0.115799 -0.002303611 0 -0.1158219 0.9930735 -0.01975539 0 9.31323e-10 0.01988924 0.9998022 -0.194438 0 0 0 1 0.9936008 0.1129265 -0.002246468 0 -0.1129489 0.9934043 -0.01976195 0 9.31323e-10 0.01988923 0.9998022 -0.194438 0 0 0 1 0.9940341 0.109048 -0.002169313 0 -0.1090696 0.9938375 -0.01977059 0 1.86265e-9 0.01988924 0.9998022 -0.194438 0 0 0 1 0.9945495 0.1042455 -0.002073776 0 -0.1042662 0.9943527 -0.01978086 0 9.31323e-10 0.01988926 0.9998022 -0.194438 0 0 0 1 0.9951251 0.09860111 -0.001961491 0 -0.09862062 0.9949282 -0.0197923 0 9.31323e-10 0.01988925 0.9998022 -0.194438 0 0 0 1 0.9957391 0.09219695 -0.001834093 0 -0.09221519 0.9955422 -0.01980452 0 9.31323e-10 0.01988927 0.9998022 -0.194438 0 0 0 1 0.9963697 0.08511557 -0.001693221 0 -0.08513241 0.9961725 -0.01981703 0 0 0.01988924 0.9998022 -0.194438 0 0 0 1 0.9969959 0.07743978 -0.001540524 0 -0.0774551 0.9967986 -0.01982952 0 0 0.01988927 0.9998022 -0.194438 0 0 0 1 0.9975982 0.06925295 -0.001377663 0 -0.06926665 0.9974008 -0.01984149 0 9.31323e-10 0.01988926 0.9998022 -0.194438 0 0 0 1 0.9981591 0.0606389 -0.001206302 0 -0.0606509 0.9979616 -0.01985262 0 1.39698e-9 0.01988924 0.9998022 -0.194438 0 0 0 1 0.9986631 0.05168191 -0.001028119 0 -0.05169213 0.9984655 -0.01986265 0 9.31323e-10 0.01988924 0.9998022 -0.194438 0 0 0 1 0.9990975 0.0424667 -8.44798e-4 0 -0.0424751 0.9988999 -0.0198713 0 4.65661e-10 0.01988924 0.9998022 -0.194438 0 0 0 1 0.9994525 0.03307838 -6.58035e-4 0 -0.03308493 0.9992549 -0.01987838 0 6.98492e-10 0.01988926 0.9998022 -0.194438 0 0 0 1 0.9997213 0.02360236 -4.69527e-4 0 -0.02360703 0.9995236 -0.01988371 0 6.98492e-10 0.01988926 0.9998022 -0.194438 0 0 0 1 0.9999002 0.0141242 -2.80976e-4 0 -0.014127 0.9997025 -0.01988728 0 4.65661e-10 0.01988926 0.9998022 -0.194438 0 0 0 1 0.9999888 0.004729605 -9.40877e-5 0 -0.004730541 0.999791 -0.01988903 0 6.98492e-10 0.01988925 0.9998022 -0.194438 0 0 0 1 0.9999899 -0.004495837 8.94363e-5 0 0.004496726 0.9997921 -0.01988904 0 2.32831e-10 0.01988924 0.9998022 -0.194438 0 0 0 1 0.9999093 -0.01346664 2.67893e-4 0 0.01346931 0.9997115 -0.01988745 0 1.16415e-9 0.01988925 0.9998022 -0.194438 0 0 0 1 0.9997557 -0.02209759 4.39589e-4 0 0.02210196 0.9995579 -0.01988439 0 2.79397e-9 0.01988925 0.9998022 -0.194438 0 0 0 1 0.9995406 -0.03030367 6.02837e-4 0 0.03030967 0.9993429 -0.01988013 0 -2.32831e-10 0.01988927 0.9998022 -0.194438 0 0 0 1 0.9992774 -0.03800048 7.55949e-4 0 0.03800799 0.9990798 -0.01987487 0 1.39698e-9 0.01988924 0.9998022 -0.194438 0 0 0 1 0.9989819 -0.04510372 8.97254e-4 0 0.04511264 0.9987842 -0.01986901 0 2.32831e-9 0.01988926 0.9998022 -0.194438 0 0 0 1 0.9986709 -0.05152974 0.00102509 0 0.05153993 0.9984733 -0.01986282 0 4.65661e-10 0.01988925 0.9998022 -0.194438 0 0 0 1 0.9983624 -0.05719502 0.00113779 0 0.05720633 0.998165 -0.01985669 0 9.31323e-10 0.01988927 0.9998022 -0.194438 0 0 0 1 0.9980744 -0.06201646 0.001233703 0 0.06202873 0.9978769 -0.01985098 0 2.32831e-9 0.01988927 0.9998022 -0.194438 0 0 0 1 0.9978246 -0.06591108 0.001311179 0 0.06592412 0.9976273 -0.019846 0 3.25963e-9 0.01988927 0.9998022 -0.194438 0 0 0 1 0.9976298 -0.06879591 0.001368568 0 0.06880952 0.9974325 -0.01984212 0 1.86265e-9 0.01988926 0.9998022 -0.194438 0 0 0 1 0.9975046 -0.07058802 0.00140422 0 0.07060198 0.9973072 -0.01983961 0 1.86265e-9 0.01988924 0.9998022 -0.194438 0 0 0 1 + + + + + + + + LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR + + + + + + + + + + + + + + + + 0 0.04166662 0.08333331 0.125 0.1666666 0.2083333 0.25 0.2916666 0.3333333 0.375 0.4166666 0.4583333 0.5 0.5416667 0.5833333 0.625 0.6666667 0.7083333 0.75 0.7916667 0.8333333 0.875 0.9166667 0.9583333 1 1.041667 1.083333 1.125 1.166667 1.208333 1.25 1.291667 1.333333 1.375 1.416667 1.458333 1.5 1.541667 1.583333 1.625 1.666667 1.708333 1.75 1.791667 1.833333 1.875 1.916667 1.958333 2 2.041667 2.083333 2.125 2.166667 2.208333 2.25 2.291667 2.333333 2.375 2.416667 2.458333 + + + + + + + + -0.994738 -0.005040132 -0.1023279 0.1841546 -0.002406535 0.9996631 -0.02584402 0.02375563 0.1024238 -0.0254618 -0.9944149 -0.3068413 0 0 0 1 -0.9947398 -0.005031362 -0.1023122 0.1841546 -0.002286472 0.9996347 -0.02692832 0.02375564 0.1024104 -0.02655273 -0.9943879 -0.3068413 0 0 0 1 -0.9947444 -0.005005769 -0.1022676 0.1841547 -0.001937124 0.9995455 -0.03008302 0.02375563 0.1023718 -0.02972682 -0.9943019 -0.3068413 0 0 0 1 -0.994752 -0.004964218 -0.1021953 0.1841547 -0.001375027 0.9993808 -0.03516119 0.02375563 0.1023067 -0.03483615 -0.9941428 -0.3068413 0 0 0 1 -0.9947625 -0.004907541 -0.1020979 0.1841547 -6.16694e-4 0.9991167 -0.0420161 0.02375563 0.102214 -0.04173308 -0.9938869 -0.3068413 0 0 0 1 -0.9947748 -0.004836466 -0.1019785 0.1841547 3.21394e-4 0.998724 -0.05050072 0.02375563 0.1020927 -0.05026964 -0.9935038 -0.3068413 0 0 0 1 -0.9947895 -0.004751615 -0.1018386 0.1841547 0.001422411 0.9981692 -0.06046723 0.02375563 0.1019396 -0.06029704 -0.9929615 -0.3068413 0 0 0 1 -0.9948062 -0.004653655 -0.1016808 0.1841547 0.002669538 0.9974178 -0.0717667 0.02375563 0.1017523 -0.07166544 -0.992225 -0.3068413 0 0 0 1 -0.9948246 -0.004543237 -0.1015076 0.1841547 0.004045799 0.9964365 -0.08424889 0.02375563 0.1015287 -0.08422353 -0.9912611 -0.3068413 0 0 0 1 -0.9948439 -0.004421121 -0.1013217 0.1841547 0.005534077 0.9951945 -0.0977619 0.02375563 0.1012671 -0.09781858 -0.9900386 -0.3068413 0 0 0 1 -0.9948645 -0.00428809 -0.1011252 0.1841547 0.00711709 0.9936656 -0.1121526 0.02375564 0.1009657 -0.1122963 -0.988532 -0.3068413 0 0 0 1 -0.9948857 -0.004145053 -0.1009206 0.1841547 0.008777505 0.9918298 -0.1272662 0.02375563 0.1006237 -0.1275012 -0.9867208 -0.3068413 0 0 0 1 -0.9949079 -0.003993002 -0.1007101 0.1841547 0.01049793 0.9896746 -0.1429475 0.02375563 0.1002411 -0.1432768 -0.984593 -0.3068413 0 0 0 1 -0.9949302 -0.003833147 -0.1004962 0.1841547 0.01226103 0.9871961 -0.1590401 0.02375564 0.09981913 -0.159466 -0.982144 -0.3068413 0 0 0 1 -0.9949526 -0.00366668 -0.1002809 0.1841547 0.01404954 0.9843992 -0.1753882 0.02375563 0.09935968 -0.1759118 -0.9793788 -0.3068413 0 0 0 1 -0.9949746 -0.00349509 -0.1000668 0.1841547 0.01584638 0.981299 -0.1918364 0.02375563 0.09886605 -0.1924581 -0.976312 -0.3068413 0 0 0 1 -0.9949964 -0.003319897 -0.09985533 0.1841547 0.01763462 0.9779208 -0.2082308 0.02375564 0.09834203 -0.2089498 -0.9729691 -0.3068413 0 0 0 1 -0.9950179 -0.003142759 -0.09964868 0.1841547 0.01939772 0.9742997 -0.224419 0.02375563 0.09779306 -0.2252339 -0.9693845 -0.3068413 0 0 0 1 -0.9950384 -0.002965522 -0.09944856 0.1841547 0.02111953 0.9704809 -0.2402518 0.02375563 0.09722549 -0.2411601 -0.965603 -0.3068413 0 0 0 1 -0.9950579 -0.002790067 -0.0992572 0.1841547 0.02278439 0.9665186 -0.2555827 0.02375563 0.09664714 -0.2565811 -0.9616784 -0.3068413 0 0 0 1 -0.9950765 -0.002618462 -0.09907566 0.1841547 0.02437683 0.9624765 -0.2702685 0.02375564 0.09606574 -0.271353 -0.9576737 -0.3068413 0 0 0 1 -0.9950939 -0.002452716 -0.09890533 0.1841547 0.02588219 0.9584246 -0.28417 0.02375563 0.09549041 -0.2853357 -0.9536588 -0.3068413 0 0 0 1 -0.9951101 -0.00229507 -0.09874772 0.1841547 0.02728596 0.9544404 -0.2971514 0.02375563 0.09493088 -0.2983927 -0.9497105 -0.3068413 0 0 0 1 -0.9951245 -0.002147734 -0.09860446 0.1841546 0.02857441 0.9506066 -0.3090805 0.02375563 0.09439797 -0.310391 -0.9459105 -0.3068413 0 0 0 1 -0.9951375 -0.002012886 -0.09847637 0.1841547 0.02973389 0.947009 -0.3198281 0.02375563 0.09390187 -0.3212009 -0.9423442 -0.3068413 0 0 0 1 -0.9951488 -0.00189282 -0.09836485 0.1841546 0.03075125 0.9437358 -0.3292676 0.02375563 0.09345376 -0.330695 -0.9390993 -0.3068413 0 0 0 1 -0.9951581 -0.001789845 -0.09827074 0.1841546 0.03161319 0.9408756 -0.3372737 0.02375563 0.09306433 -0.3387473 -0.9362634 -0.3068413 0 0 0 1 -0.9951656 -0.001706035 -0.09819564 0.1841547 0.03230707 0.9385155 -0.3437221 0.02375563 0.09274463 -0.3452329 -0.9339231 -0.3068413 0 0 0 1 -0.9951712 -0.001643531 -0.09814024 0.1841547 0.03281958 0.9367386 -0.3484877 0.02375564 0.0925046 -0.3500259 -0.9321613 -0.3068413 0 0 0 1 -0.9951749 -0.001604669 -0.09810586 0.1841547 0.03313719 0.9356226 -0.3514434 0.02375563 0.09235409 -0.3529985 -0.9310547 -0.3068413 0 0 0 1 -0.9951759 -0.001591251 -0.09809409 0.1841546 0.0332463 0.9352368 -0.3524583 0.02375563 0.09230212 -0.3540193 -0.9306721 -0.3068413 0 0 0 1 -0.9951749 -0.001604647 -0.09810585 0.1841547 0.03313722 0.9356226 -0.3514434 0.02375563 0.09235407 -0.3529985 -0.9310547 -0.3068413 0 0 0 1 -0.9951714 -0.001643539 -0.09814008 0.1841547 0.03281953 0.9367386 -0.3484878 0.02375564 0.09250443 -0.350026 -0.9321614 -0.3068413 0 0 0 1 -0.9951658 -0.001705975 -0.09819549 0.1841547 0.03230708 0.9385155 -0.3437222 0.02375563 0.09274446 -0.3452329 -0.9339232 -0.3068413 0 0 0 1 -0.9951583 -0.001789771 -0.09827074 0.1841546 0.0316133 0.9408756 -0.3372737 0.02375563 0.09306428 -0.3387473 -0.9362635 -0.3068413 0 0 0 1 -0.9951488 -0.001892835 -0.09836484 0.1841546 0.03075123 0.9437359 -0.3292675 0.02375563 0.09345378 -0.3306949 -0.9390992 -0.3068413 0 0 0 1 -0.9951375 -0.002012894 -0.09847637 0.1841547 0.02973389 0.947009 -0.3198281 0.02375564 0.09390189 -0.3212009 -0.9423442 -0.3068413 0 0 0 1 -0.9951245 -0.002147742 -0.09860446 0.1841547 0.0285744 0.9506066 -0.3090805 0.02375563 0.09439798 -0.3103911 -0.9459105 -0.3068413 0 0 0 1 -0.9951101 -0.00229507 -0.09874772 0.1841547 0.02728597 0.9544404 -0.2971514 0.02375563 0.09493088 -0.2983927 -0.9497105 -0.3068413 0 0 0 1 -0.995094 -0.002452723 -0.09890517 0.1841547 0.02588213 0.9584245 -0.28417 0.02375563 0.09549023 -0.2853357 -0.9536589 -0.3068413 0 0 0 1 -0.9950765 -0.002618469 -0.09907565 0.1841547 0.02437683 0.9624765 -0.2702685 0.02375564 0.09606574 -0.271353 -0.9576737 -0.3068413 0 0 0 1 -0.9950579 -0.002790086 -0.0992572 0.1841547 0.02278436 0.9665186 -0.2555827 0.02375563 0.09664714 -0.2565811 -0.9616784 -0.3068413 0 0 0 1 -0.9950382 -0.002965536 -0.09944887 0.1841547 0.02111958 0.9704809 -0.2402518 0.02375564 0.09722582 -0.2411601 -0.9656029 -0.3068413 0 0 0 1 -0.9950179 -0.003142759 -0.09964884 0.1841547 0.01939776 0.9742997 -0.2244191 0.02375563 0.09779321 -0.2252339 -0.9693845 -0.3068413 0 0 0 1 -0.9949966 -0.003319893 -0.09985516 0.1841547 0.0176346 0.9779208 -0.2082308 0.02375564 0.09834187 -0.2089498 -0.9729692 -0.3068413 0 0 0 1 -0.9949747 -0.003495079 -0.1000665 0.1841547 0.01584633 0.981299 -0.1918364 0.02375563 0.09886573 -0.1924581 -0.9763122 -0.3068413 0 0 0 1 -0.9949524 -0.003666691 -0.1002811 0.1841547 0.01404957 0.9843992 -0.1753882 0.02375563 0.09935984 -0.1759118 -0.9793787 -0.3068413 0 0 0 1 -0.9949301 -0.003833137 -0.1004964 0.1841547 0.01226107 0.9871961 -0.1590401 0.02375563 0.0998193 -0.159466 -0.9821439 -0.3068413 0 0 0 1 -0.9949077 -0.003993013 -0.1007102 0.1841547 0.01049795 0.9896746 -0.1429475 0.02375563 0.1002412 -0.1432768 -0.9845929 -0.3068413 0 0 0 1 -0.9948857 -0.004145071 -0.1009206 0.1841547 0.008777495 0.9918298 -0.1272662 0.02375563 0.1006237 -0.1275012 -0.9867208 -0.3068413 0 0 0 1 -0.9948645 -0.004288108 -0.1011252 0.1841547 0.007117081 0.9936656 -0.1121526 0.02375563 0.1009657 -0.1122963 -0.988532 -0.3068413 0 0 0 1 -0.994844 -0.004421132 -0.1013216 0.1841547 0.005534053 0.9951945 -0.09776193 0.02375564 0.101267 -0.0978186 -0.9900387 -0.3068413 0 0 0 1 -0.9948246 -0.004543234 -0.1015076 0.1841547 0.004045807 0.9964365 -0.08424888 0.02375564 0.1015287 -0.08422352 -0.9912611 -0.3068413 0 0 0 1 -0.9948063 -0.004653674 -0.1016808 0.1841547 0.002669524 0.9974179 -0.07176676 0.02375563 0.1017523 -0.07166548 -0.992225 -0.3068413 0 0 0 1 -0.9947895 -0.004751619 -0.1018386 0.1841547 0.001422405 0.9981692 -0.06046721 0.02375563 0.1019396 -0.06029703 -0.9929615 -0.3068413 0 0 0 1 -0.9947747 -0.004836489 -0.1019785 0.1841547 3.21375e-4 0.998724 -0.05050069 0.02375563 0.1020927 -0.05026962 -0.9935037 -0.3068413 0 0 0 1 -0.9947624 -0.004907504 -0.102098 0.1841547 -6.16626e-4 0.9991167 -0.0420161 0.02375563 0.1022142 -0.04173306 -0.9938868 -0.3068413 0 0 0 1 -0.9947521 -0.004964203 -0.1021952 0.1841547 -0.001375024 0.9993808 -0.03516119 0.02375563 0.1023066 -0.03483615 -0.9941428 -0.3068413 0 0 0 1 -0.9947443 -0.005005792 -0.1022676 0.1841547 -0.001937139 0.9995455 -0.03008303 0.02375563 0.1023718 -0.02972685 -0.9943018 -0.3068413 0 0 0 1 -0.9947398 -0.005031295 -0.1023124 0.1841546 -0.002286402 0.9996347 -0.02692827 0.02375564 0.1024106 -0.02655271 -0.9943879 -0.3068413 0 0 0 1 + + + + + + + + LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR + + + + + + + + + + + + + + + + 0 0.04166662 0.08333331 0.125 0.1666666 0.2083333 0.25 0.2916666 0.3333333 0.375 0.4166666 0.4583333 0.5 0.5416667 0.5833333 0.625 0.6666667 0.7083333 0.75 0.7916667 0.8333333 0.875 0.9166667 0.9583333 1 1.041667 1.083333 1.125 1.166667 1.208333 1.25 1.291667 1.333333 1.375 1.416667 1.458333 1.5 1.541667 1.583333 1.625 1.666667 1.708333 1.75 1.791667 1.833333 1.875 1.916667 1.958333 2 2.041667 2.083333 2.125 2.166667 2.208333 2.25 2.291667 2.333333 2.375 2.416667 2.458333 + + + + + + + + -0.9972966 0.001561246 0.07346461 -0.196505 -0.02513009 0.9322436 -0.3609575 0.02470914 -0.06905058 -0.3618279 -0.929684 -0.3007402 0 0 0 1 -0.9972927 8.35106e-4 0.07352819 -0.196505 -0.02574329 0.9326897 -0.3597598 0.02470914 -0.06887954 -0.3606787 -0.9301432 -0.3007402 0 0 0 1 -0.9972792 -0.00127843 0.07370809 -0.196505 -0.02752899 0.9339771 -0.356271 0.02470914 -0.06838627 -0.3573307 -0.9314709 -0.3007402 0 0 0 1 -0.9972486 -0.00468319 0.07398129 -0.196505 -0.03040818 0.9360157 -0.3506422 0.02470914 -0.06760562 -0.3519271 -0.9335828 -0.3007402 0 0 0 1 -0.9971914 -0.009284001 0.07431778 -0.196505 -0.03430372 0.9387018 -0.3430192 0.02470914 -0.06657775 -0.3446052 -0.9363839 -0.3007402 0 0 0 1 -0.9970948 -0.0149861 0.07468273 -0.196505 -0.0391395 0.9419213 -0.3335451 0.02470914 -0.06534681 -0.3354991 -0.9397713 -0.3007402 0 0 0 1 -0.9969449 -0.02169404 0.07503799 -0.196505 -0.0448393 0.9455539 -0.322362 0.02470914 -0.06395924 -0.3247418 -0.9436378 -0.3007402 0 0 0 1 -0.9967265 -0.02931118 0.07534564 -0.196505 -0.05132636 0.9494761 -0.3096138 0.02470914 -0.06246385 -0.3124675 -0.9478723 -0.3007402 0 0 0 1 -0.9964265 -0.03773944 0.0755663 -0.196505 -0.058522 0.9535649 -0.2954472 0.02470914 -0.06090743 -0.2988137 -0.9523659 -0.3007402 0 0 0 1 -0.9960307 -0.0468784 0.07566409 -0.196505 -0.0663458 0.9577007 -0.2800135 0.02470914 -0.05933706 -0.2839221 -0.9570096 -0.3007402 0 0 0 1 -0.9955286 -0.05662572 0.07560558 -0.196505 -0.07471478 0.9617701 -0.2634694 0.02470914 -0.05779614 -0.2679402 -0.9617005 -0.3007402 0 0 0 1 -0.9949113 -0.06687686 0.07536274 -0.196505 -0.08354357 0.9656684 -0.2459775 0.02470914 -0.05632533 -0.2510218 -0.9663414 -0.3007402 0 0 0 1 -0.9941719 -0.07752538 0.07491323 -0.196505 -0.09274434 0.9693029 -0.2277066 0.02470914 -0.0549607 -0.2333272 -0.9708437 -0.3007402 0 0 0 1 -0.993309 -0.08846353 0.07424116 -0.196505 -0.102227 0.972594 -0.2088313 0.02470914 -0.05373265 -0.2150234 -0.9751297 -0.3007402 0 0 0 1 -0.992323 -0.09958255 0.07333828 -0.196505 -0.1118995 0.9754775 -0.1895313 0.02470914 -0.05266592 -0.1962828 -0.9791319 -0.3007402 0 0 0 1 -0.9912193 -0.1107737 0.07220417 -0.196505 -0.1216687 0.9779058 -0.1699911 0.02470914 -0.05177841 -0.1772835 -0.9827967 -0.3007402 0 0 0 1 -0.9900072 -0.1219288 0.07084639 -0.196505 -0.1314404 0.979849 -0.1503979 0.02470914 -0.05108105 -0.1582071 -0.9860839 -0.3007402 0 0 0 1 -0.9886999 -0.1329407 0.06928141 -0.196505 -0.1411205 0.9812948 -0.1309413 0.02470914 -0.05057816 -0.1392387 -0.9889665 -0.3007402 0 0 0 1 -0.9873137 -0.1437047 0.06753387 -0.196505 -0.1506156 0.9822491 -0.1118111 0.02470914 -0.05026739 -0.1205643 -0.991432 -0.3007402 0 0 0 1 -0.9858699 -0.1541185 0.06563479 -0.196505 -0.159833 0.9827347 -0.0931968 0.02470914 -0.05013835 -0.1023706 -0.9934819 -0.3007402 0 0 0 1 -0.9843926 -0.1640833 0.0636233 -0.196505 -0.1686823 0.9827912 -0.0752859 0.02470914 -0.05017537 -0.08484304 -0.9951304 -0.3007402 0 0 0 1 -0.9829084 -0.1735035 0.06154423 -0.196505 -0.1770745 0.9824715 -0.05826319 0.02470914 -0.05035668 -0.06816533 -0.9964024 -0.3007402 0 0 0 1 -0.9814466 -0.1822874 0.05944823 -0.196505 -0.1849236 0.9818417 -0.04230972 0.02470914 -0.0506563 -0.05251813 -0.9973344 -0.3007402 0 0 0 1 -0.9800382 -0.1903466 0.05738885 -0.196505 -0.1921456 0.9809781 -0.02760303 0.02470913 -0.05104316 -0.03807908 -0.9979703 -0.3007402 0 0 0 1 -0.9787154 -0.1975959 0.0554239 -0.196505 -0.1986587 0.9799641 -0.01431649 0.02470914 -0.05148466 -0.02502223 -0.9983602 -0.3007402 0 0 0 1 -0.9775119 -0.203953 0.05361152 -0.196505 -0.2043837 0.9788874 -0.002619825 0.02470914 -0.05194541 -0.01351826 -0.9985584 -0.3007402 0 0 0 1 -0.9764594 -0.2093367 0.05201036 -0.196505 -0.209242 0.9778365 0.007320015 0.02470914 -0.05239006 -0.003735118 -0.9986197 -0.3007402 0 0 0 1 -0.9755911 -0.2136675 0.05067791 -0.196505 -0.2131569 0.9768976 0.01533832 0.02470913 -0.05278451 0.004161529 -0.9985973 -0.3007402 0 0 0 1 -0.9749375 -0.2168646 0.04966868 -0.196505 -0.2160508 0.9761504 0.02127093 0.02470914 -0.05309709 0.01000679 -0.9985393 -0.3007402 0 0 0 1 -0.9745268 -0.2188459 0.04903205 -0.196505 -0.2178459 0.9756642 0.02495317 0.02470914 -0.05329979 0.01363603 -0.9984854 -0.3007402 0 0 0 1 -0.9743847 -0.219526 0.04881178 -0.196505 -0.2184623 0.975493 0.02621815 0.02470914 -0.05337122 0.01488301 -0.9984637 -0.3007402 0 0 0 1 -0.9745268 -0.2188459 0.04903223 -0.196505 -0.2178459 0.9756641 0.02495315 0.02470914 -0.05329996 0.01363599 -0.9984854 -0.3007402 0 0 0 1 -0.9749375 -0.2168646 0.04966868 -0.196505 -0.2160508 0.9761505 0.02127091 0.02470914 -0.05309709 0.01000679 -0.9985393 -0.3007402 0 0 0 1 -0.9755909 -0.2136674 0.05067824 -0.196505 -0.2131568 0.9768975 0.01533831 0.02470913 -0.05278483 0.004161462 -0.9985971 -0.3007402 0 0 0 1 -0.9764594 -0.2093367 0.05201036 -0.196505 -0.209242 0.9778365 0.007319987 0.02470914 -0.05239006 -0.003735147 -0.9986196 -0.3007402 0 0 0 1 -0.9775118 -0.2039529 0.05361154 -0.196505 -0.2043836 0.9788875 -0.002619898 0.02470914 -0.05194543 -0.01351833 -0.9985583 -0.3007402 0 0 0 1 -0.9787155 -0.1975959 0.0554239 -0.196505 -0.1986587 0.9799641 -0.0143165 0.02470914 -0.05148465 -0.02502227 -0.9983603 -0.3007402 0 0 0 1 -0.9800382 -0.1903465 0.05738902 -0.196505 -0.1921455 0.9809782 -0.02760307 0.02470914 -0.05104333 -0.03807914 -0.9979702 -0.3007402 0 0 0 1 -0.9814466 -0.1822874 0.05944824 -0.196505 -0.1849236 0.9818417 -0.04230976 0.02470914 -0.05065631 -0.05251817 -0.9973344 -0.3007402 0 0 0 1 -0.9829084 -0.1735035 0.06154422 -0.196505 -0.1770745 0.9824715 -0.05826316 0.02470914 -0.05035668 -0.06816529 -0.9964024 -0.3007402 0 0 0 1 -0.9843926 -0.1640833 0.06362334 -0.196505 -0.1686823 0.9827911 -0.07528593 0.02470914 -0.05017538 -0.08484305 -0.9951302 -0.3007402 0 0 0 1 -0.9858699 -0.1541185 0.06563481 -0.196505 -0.159833 0.9827349 -0.09319681 0.02470914 -0.05013835 -0.1023706 -0.9934818 -0.3007402 0 0 0 1 -0.9873137 -0.1437047 0.06753386 -0.196505 -0.1506156 0.9822491 -0.1118111 0.02470914 -0.05026739 -0.1205643 -0.991432 -0.3007402 0 0 0 1 -0.9886997 -0.1329406 0.06928174 -0.196505 -0.1411205 0.9812948 -0.1309413 0.02470914 -0.05057849 -0.1392387 -0.9889663 -0.3007402 0 0 0 1 -0.9900073 -0.1219287 0.07084639 -0.196505 -0.1314404 0.979849 -0.150398 0.02470914 -0.05108105 -0.1582072 -0.9860839 -0.3007402 0 0 0 1 -0.9912193 -0.1107737 0.07220399 -0.196505 -0.1216686 0.9779058 -0.1699911 0.02470914 -0.05177825 -0.1772834 -0.9827967 -0.3007402 0 0 0 1 -0.9923229 -0.09958251 0.07333842 -0.196505 -0.1118995 0.9754775 -0.1895314 0.02470914 -0.05266609 -0.1962829 -0.9791319 -0.3007402 0 0 0 1 -0.9933091 -0.08846352 0.07424115 -0.196505 -0.102227 0.9725941 -0.2088313 0.02470914 -0.05373264 -0.2150234 -0.9751297 -0.3007402 0 0 0 1 -0.994172 -0.07752535 0.07491323 -0.196505 -0.09274432 0.9693029 -0.2277066 0.02470914 -0.05496068 -0.2333273 -0.9708437 -0.3007402 0 0 0 1 -0.9949111 -0.06687686 0.07536274 -0.196505 -0.08354358 0.9656684 -0.2459775 0.02470914 -0.05632534 -0.2510218 -0.9663413 -0.3007402 0 0 0 1 -0.9955286 -0.05662568 0.07560558 -0.196505 -0.07471474 0.9617701 -0.2634694 0.02470914 -0.05779615 -0.2679402 -0.9617004 -0.3007402 0 0 0 1 -0.9960307 -0.04687842 0.07566408 -0.196505 -0.06634582 0.9577007 -0.2800134 0.02470914 -0.05933706 -0.283922 -0.9570097 -0.3007402 0 0 0 1 -0.9964265 -0.03773942 0.0755663 -0.196505 -0.05852199 0.9535649 -0.2954472 0.02470914 -0.06090743 -0.2988137 -0.9523659 -0.3007402 0 0 0 1 -0.9967267 -0.02931118 0.07534563 -0.196505 -0.05132637 0.9494761 -0.3096138 0.02470914 -0.06246382 -0.3124675 -0.9478725 -0.3007402 0 0 0 1 -0.9969448 -0.02169403 0.07503818 -0.196505 -0.04483935 0.9455539 -0.322362 0.02470914 -0.06395938 -0.3247418 -0.9436377 -0.3007402 0 0 0 1 -0.9970949 -0.0149861 0.07468256 -0.196505 -0.03913948 0.9419213 -0.3335451 0.02470914 -0.06534665 -0.3354991 -0.9397714 -0.3007402 0 0 0 1 -0.9971914 -0.009284032 0.07431778 -0.196505 -0.03430375 0.9387018 -0.3430192 0.02470914 -0.06657775 -0.3446052 -0.9363839 -0.3007402 0 0 0 1 -0.9972486 -0.004683168 0.07398129 -0.196505 -0.03040817 0.9360157 -0.3506422 0.02470914 -0.06760563 -0.3519271 -0.9335828 -0.3007402 0 0 0 1 -0.9972792 -0.001278453 0.07370809 -0.196505 -0.02752901 0.9339771 -0.3562709 0.02470914 -0.06838628 -0.3573307 -0.9314709 -0.3007402 0 0 0 1 -0.9972927 8.35143e-4 0.07352835 -0.196505 -0.02574332 0.9326897 -0.3597598 0.02470914 -0.06887969 -0.3606787 -0.9301432 -0.3007402 0 0 0 1 + + + + + + + + LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR + + + + + + + + + + + + + + + + 0 0.04166662 0.08333331 0.125 0.1666666 0.2083333 0.25 0.2916666 0.3333333 0.375 0.4166666 0.4583333 0.5 0.5416667 0.5833333 0.625 0.6666667 0.7083333 0.75 0.7916667 0.8333333 0.875 0.9166667 0.9583333 1 1.041667 1.083333 1.125 1.166667 1.208333 1.25 1.291667 1.333333 1.375 1.416667 1.458333 1.5 1.541667 1.583333 1.625 1.666667 1.708333 1.75 1.791667 1.833333 1.875 1.916667 1.958333 2 2.041667 2.083333 2.125 2.166667 2.208333 2.25 2.291667 2.333333 2.375 2.416667 2.458333 + + + + + + + + 1 -1.50996e-7 5.68434e-14 0.08954165 -1.47115e-7 -0.9742956 -0.2252731 0.02421998 3.40154e-8 0.2252731 -0.9742956 0.03911464 0 0 0 1 1 -1.51098e-7 9.1709e-10 0.08954165 -1.47215e-7 -0.9756348 -0.2194009 0.02421998 3.40457e-8 0.2194009 -0.9756348 0.03911464 0 0 0 1 1 -1.51361e-7 3.56721e-9 0.08954165 -1.47505e-7 -0.9792995 -0.2024163 0.02421998 3.41312e-8 0.2024163 -0.9792995 0.03911464 0 0 0 1 1 -1.51685e-7 7.80744e-9 0.08954165 -1.47972e-7 -0.9845355 -0.1751854 0.02421998 3.42597e-8 0.1751854 -0.9845355 0.03911464 0 0 0 1 1 -1.51935e-7 1.34983e-8 0.08954165 -1.48601e-7 -0.9903588 -0.138526 0.02421998 3.44152e-8 0.138526 -0.9903588 0.03911464 0 0 0 1 1 -1.51954e-7 2.04937e-8 0.08954165 -1.49379e-7 -0.9956396 -0.09328314 0.02421998 3.4579e-8 0.09328314 -0.9956396 0.03911464 0 0 0 1 1 -1.51574e-7 2.86316e-8 0.08954165 -1.50294e-7 -0.9991837 -0.04039756 0.02421998 3.47315e-8 0.04039756 -0.9991837 0.03911464 0 0 0 1 1 -1.50637e-7 3.77285e-8 0.08954165 -1.51328e-7 -0.9998187 0.01904369 0.02421998 3.4853e-8 -0.01904369 -0.9998187 0.03911464 0 0 0 1 1 -1.48999e-7 4.75762e-8 0.08954165 -1.52461e-7 -0.9964842 0.08378153 0.02421998 3.49255e-8 -0.08378153 -0.9964842 0.03911464 0 0 0 1 1 -1.46555e-7 5.79443e-8 0.08954165 -1.53673e-7 -0.9883206 0.152389 0.02421998 3.49342e-8 -0.152389 -0.9883206 0.03911464 0 0 0 1 1 -1.4324e-7 6.85873e-8 0.08954165 -1.54939e-7 -0.974748 0.2233078 0.02421998 3.48687e-8 -0.2233078 -0.974748 0.03911464 0 0 0 1 1 -1.39043e-7 7.92547e-8 0.08954165 -1.56233e-7 -0.9555243 0.2949125 0.02421998 3.47242e-8 -0.2949125 -0.9555243 0.03911464 0 0 0 1 1 -1.3401e-7 8.97051e-8 0.08954165 -1.57529e-7 -0.9307741 0.3655948 0.02421998 3.45018e-8 -0.3655948 -0.9307741 0.03911464 0 0 0 1 1 -1.28237e-7 9.97191e-8 0.08954165 -1.58803e-7 -0.9009842 0.4338519 0.02421998 3.42092e-8 -0.4338519 -0.9009842 0.03911464 0 0 0 1 1 -1.2187e-7 1.09111e-7 0.08954165 -1.60034e-7 -0.8669649 0.4983692 0.02421998 3.38597e-8 -0.4983692 -0.8669649 0.03911464 0 0 0 1 1 -1.15086e-7 1.17739e-7 0.08954165 -1.61204e-7 -0.8297867 0.5580807 0.02421998 3.34713e-8 -0.5580807 -0.8297867 0.03911464 0 0 0 1 1 -1.08146e-7 1.25444e-7 0.08954165 -1.62291e-7 -0.7910206 0.6117895 0.02421998 3.30661e-8 -0.6117895 -0.7910206 0.03911464 0 0 0 1 1 -1.01584e-7 1.31889e-7 0.08954165 -1.63237e-7 -0.7538272 0.6570727 0.02421998 3.26737e-8 -0.6570727 -0.7538272 0.03911464 0 0 0 1 1 -9.60605e-8 1.36779e-7 0.08954165 -1.63983e-7 -0.7221903 0.6916946 0.02421998 3.23357e-8 -0.6916946 -0.7221903 0.03911464 0 0 0 1 1 -9.22663e-8 1.39888e-7 0.08954165 -1.64473e-7 -0.7003049 0.7138438 0.02421998 3.21004e-8 -0.7138438 -0.7003049 0.03911464 0 0 0 1 1 -9.08655e-8 1.40988e-7 0.08954165 -1.64649e-7 -0.6921978 0.7217078 0.02421998 3.20135e-8 -0.7217078 -0.6921978 0.03911464 0 0 0 1 1 -9.12315e-8 1.4069e-7 0.08954165 -1.64596e-7 -0.6942692 0.7197154 0.02421998 3.20161e-8 -0.7197154 -0.6942692 0.03911464 0 0 0 1 1 -9.22733e-8 1.39834e-7 0.08954165 -1.64445e-7 -0.7001689 0.7139772 0.02421998 3.20263e-8 -0.7139772 -0.7001689 0.03911464 0 0 0 1 1 -9.38996e-8 1.38473e-7 0.08954165 -1.6421e-7 -0.7093803 0.7048258 0.02421998 3.20471e-8 -0.7048258 -0.7093803 0.03911464 0 0 0 1 1 -9.6014e-8 1.36655e-7 0.08954165 -1.63903e-7 -0.7213521 0.6925686 0.02421998 3.20803e-8 -0.6925686 -0.7213521 0.03911464 0 0 0 1 1 -9.85195e-8 1.34427e-7 0.08954165 -1.63538e-7 -0.7355254 0.6774971 0.02421998 3.21278e-8 -0.6774971 -0.7355254 0.03911464 0 0 0 1 1 -1.01322e-7 1.31833e-7 0.08954165 -1.63125e-7 -0.751355 0.6598982 0.02421998 3.21915e-8 -0.6598982 -0.751355 0.03911464 0 0 0 1 1 -1.04332e-7 1.2892e-7 0.08954165 -1.62678e-7 -0.7683264 0.6400582 0.02421998 3.22741e-8 -0.6400582 -0.7683264 0.03911464 0 0 0 1 1 -1.07469e-7 1.25735e-7 0.08954165 -1.62205e-7 -0.7859684 0.6182666 0.02421998 3.23789e-8 -0.6182666 -0.7859684 0.03911464 0 0 0 1 1 -1.1066e-7 1.22325e-7 0.08954165 -1.61716e-7 -0.8038619 0.5948161 0.02421998 3.25103e-8 -0.5948161 -0.8038619 0.03911464 0 0 0 1 1 -1.50996e-7 4.9738e-14 0.08954165 -1.24065e-7 -0.8216438 0.5700014 0.02421998 -8.60678e-8 -0.5700014 -0.8216438 0.03911464 0 0 0 1 1 -1.5231e-7 -4.44332e-9 0.08954165 -1.25404e-7 -0.8392168 0.543797 0.02421998 -8.65544e-8 -0.543797 -0.8392168 0.03911464 0 0 0 1 1 -1.53534e-7 -9.13216e-9 0.08954165 -1.26801e-7 -0.8565732 0.5160257 0.02421998 -8.70499e-8 -0.5160257 -0.8565732 0.03911464 0 0 0 1 1 -1.54645e-7 -1.40453e-8 0.08954165 -1.2825e-7 -0.8735312 0.4867682 0.02421998 -8.75453e-8 -0.4867682 -0.8735312 0.03911464 0 0 0 1 1 -1.5562e-7 -1.91592e-8 0.08954165 -1.2975e-7 -0.8899165 0.4561235 0.02421998 -8.8032e-8 -0.4561235 -0.8899165 0.03911464 0 0 0 1 1 -1.56438e-7 -2.44479e-8 0.08954165 -1.31294e-7 -0.9055637 0.4242102 0.02421998 -8.85019e-8 -0.4242102 -0.9055637 0.03911464 0 0 0 1 1 -1.57083e-7 -2.98832e-8 0.08954165 -1.32877e-7 -0.9203198 0.3911669 0.02421998 -8.89478e-8 -0.3911669 -0.9203198 0.03911464 0 0 0 1 1 -1.57539e-7 -3.54347e-8 0.08954165 -1.34494e-7 -0.9340469 0.3571504 0.02421998 -8.93629e-8 -0.3571504 -0.9340469 0.03911464 0 0 0 1 1 -1.57796e-7 -4.10701e-8 0.08954165 -1.36136e-7 -0.9466255 0.3223356 0.02421998 -8.97414e-8 -0.3223356 -0.9466255 0.03911464 0 0 0 1 1 -1.57847e-7 -4.67555e-8 0.08954165 -1.37796e-7 -0.9579563 0.2869141 0.02421998 -9.00784e-8 -0.2869141 -0.9579563 0.03911464 0 0 0 1 1 -1.57689e-7 -5.24564e-8 0.08954165 -1.39466e-7 -0.9679636 0.2510906 0.02421998 -9.037e-8 -0.2510906 -0.9679636 0.03911464 0 0 0 1 1 -1.57322e-7 -5.81372e-8 0.08954165 -1.41136e-7 -0.9765961 0.2150814 0.02421998 -9.06136e-8 -0.2150814 -0.9765961 0.03911464 0 0 0 1 1 -1.56753e-7 -6.37626e-8 0.08954165 -1.42797e-7 -0.9838288 0.179111 0.02421998 -9.08076e-8 -0.179111 -0.9838288 0.03911464 0 0 0 1 1 -1.55991e-7 -6.92975e-8 0.08954165 -1.4444e-7 -0.9896635 0.1434086 0.02421998 -9.09516e-8 -0.1434086 -0.9896635 0.03911464 0 0 0 1 1 -1.5505e-7 -7.47077e-8 0.08954165 -1.46055e-7 -0.9941286 0.1082051 0.02421998 -9.10462e-8 -0.1082051 -0.9941286 0.03911464 0 0 0 1 1 -1.53948e-7 -7.99606e-8 0.08954165 -1.47633e-7 -0.9972782 0.07372994 0.02421998 -9.10935e-8 -0.07372994 -0.9972782 0.03911464 0 0 0 1 1 -1.52706e-7 -8.50252e-8 0.08954165 -1.49164e-7 -0.9991913 0.04020775 0.02421998 -9.10964e-8 -0.04020775 -0.9991913 0.03911464 0 0 0 1 1 -1.51349e-7 -8.98725e-8 0.08954165 -1.50638e-7 -0.9999691 0.00785643 0.02421998 -9.10588e-8 -0.00785643 -0.9999691 0.03911464 0 0 0 1 1 -1.49904e-7 -9.44759e-8 0.08954165 -1.52048e-7 -0.9997328 -0.02311564 0.02421998 -9.09855e-8 0.02311564 -0.9997328 0.03911464 0 0 0 1 1 -1.484e-7 -9.88109e-8 0.08954165 -1.53384e-7 -0.9986204 -0.05251035 0.02421998 -9.08821e-8 0.05251035 -0.9986204 0.03911464 0 0 0 1 1 -1.46868e-7 -1.02856e-7 0.08954165 -1.54638e-7 -0.9967835 -0.08014154 0.02421998 -9.07546e-8 0.08014154 -0.9967835 0.03911464 0 0 0 1 1 -1.45339e-7 -1.0659e-7 0.08954165 -1.55804e-7 -0.9943838 -0.1058342 0.02421998 -9.06096e-8 0.1058342 -0.9943838 0.03911464 0 0 0 1 1 -1.43848e-7 -1.09997e-7 0.08954165 -1.56874e-7 -0.9915892 -0.1294252 0.02421998 -9.04539e-8 0.1294252 -0.9915892 0.03911464 0 0 0 1 1 -1.42424e-7 -1.13059e-7 0.08954165 -1.57841e-7 -0.9885703 -0.1507608 0.02421998 -9.02945e-8 0.1507608 -0.9885703 0.03911464 0 0 0 1 1 -1.41102e-7 -1.15762e-7 0.08954165 -1.587e-7 -0.9854964 -0.1696964 0.02421998 -9.01382e-8 0.1696964 -0.9854964 0.03911464 0 0 0 1 1 -1.39911e-7 -1.18091e-7 0.08954165 -1.59443e-7 -0.982532 -0.1860936 0.02421998 -8.99917e-8 0.1860936 -0.982532 0.03911464 0 0 0 1 1 -1.38881e-7 -1.20033e-7 0.08954165 -1.60065e-7 -0.9798331 -0.1998178 0.02421998 -8.98611e-8 0.1998178 -0.9798331 0.03911464 0 0 0 1 1 -1.3804e-7 -1.21573e-7 0.08954165 -1.6056e-7 -0.9775431 -0.2107358 0.02421998 -8.97523e-8 0.2107358 -0.9775431 0.03911464 0 0 0 1 1 -1.37414e-7 -1.22695e-7 0.08954165 -1.60922e-7 -0.9757894 -0.2187122 0.02421998 -8.96703e-8 0.2187122 -0.9757894 0.03911464 0 0 0 1 1 -1.37024e-7 -1.23383e-7 0.08954165 -1.61144e-7 -0.9746793 -0.2236073 0.02421998 -8.9619e-8 0.2236073 -0.9746793 0.03911464 0 0 0 1 + + + + + + + + LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR + + + + + + + + + + + + + + + + 0 0.04166662 0.08333331 0.125 0.1666666 0.2083333 0.25 0.2916666 0.3333333 0.375 0.4166666 0.4583333 0.5 0.5416667 0.5833333 0.625 0.6666667 0.7083333 0.75 0.7916667 0.8333333 0.875 0.9166667 0.9583333 1 1.041667 1.083333 1.125 1.166667 1.208333 1.25 1.291667 1.333333 1.375 1.416667 1.458333 1.5 1.541667 1.583333 1.625 1.666667 1.708333 1.75 1.791667 1.833333 1.875 1.916667 1.958333 2 2.041667 2.083333 2.125 2.166667 2.208333 2.25 2.291667 2.333333 2.375 2.416667 2.458333 + + + + + + + + 1 3.14212e-7 5.82433e-8 -7.45058e-9 -3.12362e-7 0.9226125 0.3857283 0 6.74645e-8 -0.3857283 0.9226125 -0.3756471 0 0 0 1 1 3.12885e-7 6.26876e-8 -7.45058e-9 -3.11879e-7 0.9167559 0.3994478 0 6.7512e-8 -0.3994478 0.9167559 -0.3756471 0 0 0 1 1 3.08756e-7 7.51957e-8 -7.45058e-9 -3.10506e-7 0.8990152 0.4379178 7.45058e-9 6.76076e-8 -0.4379178 0.8990152 -0.3756471 0 0 0 1 1 3.0121e-7 9.44608e-8 0 -3.08343e-7 0.8679003 0.4967385 0 6.76401e-8 -0.4967385 0.8679003 -0.3756471 0 0 0 1 1 2.89365e-7 1.18959e-7 -7.45058e-9 -3.05503e-7 0.8211454 0.570719 0 6.74637e-8 -0.570719 0.8211454 -0.3756471 0 0 0 1 1 2.72403e-7 1.46835e-7 -7.45058e-9 -3.02134e-7 0.7568104 0.6536345 3.72529e-9 6.69259e-8 -0.6536345 0.7568104 -0.375647 0 0 0 1 1 2.49916e-7 1.75914e-7 0 -2.9843e-7 0.6743801 0.7383844 -1.86265e-9 6.5901e-8 -0.7383844 0.6743801 -0.3756471 0 0 0 1 1 2.22199e-7 2.03887e-7 0 -2.94626e-7 0.5756412 0.8177024 -9.31323e-10 6.43263e-8 -0.8177024 0.5756412 -0.375647 0 0 0 1 1 1.90393e-7 2.28662e-7 7.45058e-9 -2.90969e-7 0.4649994 0.885311 0 6.22294e-8 -0.885311 0.4649994 -0.3756471 0 0 0 1 1 1.56384e-7 2.48741e-7 0 -2.8768e-7 0.349023 0.9371141 -3.72529e-9 5.97333e-8 -0.9371141 0.349023 -0.375647 0 0 0 1 1 1.22485e-7 2.63486e-7 0 -2.84911e-7 0.2353361 0.971914 7.45058e-9 5.70367e-8 -0.971914 0.2353361 -0.3756471 0 0 0 1 1 9.10383e-8 2.73141e-7 0 -2.82732e-7 0.1313377 0.9913377 -7.45058e-9 5.4376e-8 -0.9913377 0.1313377 -0.375647 0 0 0 1 1 6.41035e-8 2.78622e-7 -1.49012e-8 -2.81135e-7 0.04327336 0.9990633 0 5.19865e-8 -0.9990633 0.04327336 -0.3756471 0 0 0 1 1 4.33293e-8 2.81188e-7 -7.45058e-9 -2.80065e-7 -0.02404481 0.9997109 0 5.00779e-8 -0.9997109 -0.02404481 -0.3756471 0 0 0 1 1 3.00198e-8 2.82091e-7 -7.45058e-9 -2.7945e-7 -0.0669046 0.9977595 0 4.88257e-8 -0.9977595 -0.0669046 -0.375647 0 0 0 1 1 2.53234e-8 2.82273e-7 -7.45058e-9 -2.79247e-7 -0.08197841 0.9966342 -1.49012e-8 4.83784e-8 -0.9966342 -0.08197841 -0.375647 0 0 0 1 1 2.80832e-8 2.82205e-7 0 -2.79401e-7 -0.07301685 0.997331 1.49012e-8 4.8614e-8 -0.997331 -0.07301685 -0.3756471 0 0 0 1 1 3.58935e-8 2.81879e-7 -7.45058e-9 -2.7985e-7 -0.0476135 0.9988658 -1.49012e-8 4.9274e-8 -0.9988658 -0.0476135 -0.375647 0 0 0 1 1 4.80509e-8 2.80972e-7 0 -2.80581e-7 -0.007944405 0.9999685 0 5.02815e-8 -0.9999685 -0.007944405 -0.3756471 0 0 0 1 1 6.38198e-8 2.79066e-7 7.45058e-9 -2.81591e-7 0.0437434 0.9990427 0 5.15514e-8 -0.9990427 0.0437434 -0.3756471 0 0 0 1 1 8.24005e-8 2.75742e-7 7.45058e-9 -2.8287e-7 0.1049954 0.9944726 -2.98023e-8 5.29934e-8 -0.9944726 0.1049954 -0.375647 0 0 0 1 1 1.0292e-7 2.70671e-7 0 -2.844e-7 0.1730909 0.984906 -2.98023e-8 5.45158e-8 -0.984906 0.1730909 -0.3756471 0 0 0 1 1 1.24451e-7 2.63686e-7 0 -2.86144e-7 0.2450812 0.9695026 0 5.60314e-8 -0.9695026 0.2450812 -0.375647 0 0 0 1 1 1.46059e-7 2.54835e-7 7.45058e-9 -2.88049e-7 0.3179216 0.948117 -1.49012e-8 5.74637e-8 -0.948117 0.3179216 -0.375647 0 0 0 1 1 1.66864e-7 2.44402e-7 0 -2.90042e-7 0.388668 0.9213779 -2.98023e-8 5.87536e-8 -0.9213779 0.388668 -0.375647 0 0 0 1 1 1.86102e-7 2.32886e-7 0 -2.92038e-7 0.4546813 0.8906543 -2.98023e-8 5.98636e-8 -0.8906543 0.4546813 -0.375647 0 0 0 1 1 2.03169e-7 2.20956e-7 0 -2.93947e-7 0.5137829 0.8579203 0 6.07792e-8 -0.8579203 0.5137829 -0.375647 0 0 0 1 1 2.17634e-7 2.0939e-7 0 -2.95678e-7 0.5643197 0.8255563 -1.49012e-8 6.15065e-8 -0.8255563 0.5643197 -0.375647 0 0 0 1 1 2.29221e-7 1.99009e-7 0 -2.97144e-7 0.6051172 0.7961363 -1.49012e-8 6.20671e-8 -0.7961363 0.6051172 -0.3756471 0 0 0 1 1 2.37753e-7 1.90628e-7 0 -2.98262e-7 0.6353294 0.7722414 -1.49012e-8 6.24909e-8 -0.7722414 0.6353294 -0.3756471 0 0 0 1 1 2.51676e-7 1.65126e-7 0 -2.89535e-7 0.6542065 0.7563159 0 8.23201e-8 -0.7563159 0.6542065 -0.3756471 0 0 0 1 1 2.54706e-7 1.61543e-7 -7.45058e-9 -2.90073e-7 0.6654212 0.7464681 0 8.26361e-8 -0.7464681 0.6654212 -0.3756471 0 0 0 1 1 2.56903e-7 1.58877e-7 -7.45058e-9 -2.90473e-7 0.6735829 0.7391119 0 8.28632e-8 -0.7391119 0.6735829 -0.3756471 0 0 0 1 1 2.58414e-7 1.57007e-7 7.45058e-9 -2.90752e-7 0.6792155 0.7339389 0 8.30183e-8 -0.7339389 0.6792155 -0.3756471 0 0 0 1 1 2.59376e-7 1.55801e-7 0 -2.90932e-7 0.682811 0.7305951 0 8.31163e-8 -0.7305951 0.682811 -0.375647 0 0 0 1 1 2.59918e-7 1.55117e-7 0 -2.91035e-7 0.6848385 0.7286952 -1.49012e-8 8.3171e-8 -0.7286952 0.6848385 -0.3756471 0 0 0 1 1 2.60162e-7 1.54808e-7 7.45058e-9 -2.91081e-7 0.6857525 0.7278349 0 8.3195e-8 -0.7278349 0.6857525 -0.3756471 0 0 0 1 1 2.60228e-7 1.54725e-7 0 -2.91094e-7 0.6859995 0.7276021 0 8.32009e-8 -0.7276021 0.6859995 -0.3756471 0 0 0 1 1 2.60234e-7 1.54718e-7 7.45058e-9 -2.91096e-7 0.6860234 0.7275792 0 8.32008e-8 -0.7275792 0.6860234 -0.375647 0 0 0 1 1 2.60299e-7 1.54635e-7 -7.45058e-9 -2.91109e-7 0.6862676 0.7273492 -7.45058e-9 8.3207e-8 -0.7273492 0.6862676 -0.375647 0 0 0 1 1 2.60541e-7 1.54327e-7 0 -2.91154e-7 0.6871739 0.726493 -7.45058e-9 8.32315e-8 -0.726493 0.6871739 -0.3756471 0 0 0 1 1 2.61077e-7 1.53641e-7 0 -2.91256e-7 0.6891816 0.7245885 0 8.32865e-8 -0.7245885 0.6891816 -0.375647 0 0 0 1 1 2.62021e-7 1.52424e-7 -1.49012e-8 -2.91437e-7 0.6927223 0.7212045 -7.45058e-9 8.33834e-8 -0.7212045 0.6927223 -0.3756471 0 0 0 1 1 2.63482e-7 1.50515e-7 -7.45058e-9 -2.91719e-7 0.6982123 0.7158908 3.72529e-9 8.35329e-8 -0.7158908 0.6982123 -0.375647 0 0 0 1 1 2.6556e-7 1.47749e-7 0 -2.92127e-7 0.706042 0.70817 -3.72529e-9 8.37445e-8 -0.70817 0.706042 -0.375647 0 0 0 1 1 2.68338e-7 1.43946e-7 7.45058e-9 -2.92687e-7 0.7165629 0.6975226 0 8.40252e-8 -0.6975226 0.7165629 -0.375647 0 0 0 1 1 2.71916e-7 1.38865e-7 -7.45058e-9 -2.93429e-7 0.7301883 0.683246 0 8.43877e-8 -0.683246 0.7301883 -0.375647 0 0 0 1 1 2.76187e-7 1.32502e-7 0 -2.94349e-7 0.7465814 0.6652939 -1.16415e-10 8.48221e-8 -0.6652939 0.7465814 -0.375647 0 0 0 1 1 2.80919e-7 1.25035e-7 0 -2.9542e-7 0.7649297 0.6441137 9.31323e-10 8.53007e-8 -0.6441137 0.7649297 -0.375647 0 0 0 1 1 2.85887e-7 1.16657e-7 -7.45058e-9 -2.96613e-7 0.7844418 0.6202025 0 8.57972e-8 -0.6202025 0.7844418 -0.3756471 0 0 0 1 1 2.90885e-7 1.07581e-7 -7.45058e-9 -2.97897e-7 0.8043707 0.5941277 -3.72529e-9 8.62877e-8 -0.5941277 0.8043707 -0.375647 0 0 0 1 1 2.95731e-7 9.80414e-8 -1.49012e-8 -2.99237e-7 0.8240372 0.5665358 0 8.67524e-8 -0.5665358 0.8240372 -0.3756471 0 0 0 1 1 3.00273e-7 8.82921e-8 7.45058e-9 -3.00599e-7 0.8428482 0.5381513 7.45058e-9 8.71753e-8 -0.5381513 0.8428482 -0.3756471 0 0 0 1 1 3.04394e-7 7.86057e-8 7.45058e-9 -3.01944e-7 0.8603107 0.5097702 3.72529e-9 8.75456e-8 -0.5097702 0.8603107 -0.375647 0 0 0 1 1 3.08013e-7 6.92671e-8 -7.45058e-9 -3.03234e-7 0.8760363 0.4822454 0 8.78574e-8 -0.4822454 0.8760363 -0.3756471 0 0 0 1 1 3.11083e-7 6.05688e-8 -1.49012e-8 -3.0443e-7 0.8897392 0.456469 0 8.81092e-8 -0.456469 0.8897392 -0.3756471 0 0 0 1 1 3.13584e-7 5.28062e-8 -7.45058e-9 -3.05493e-7 0.9012231 0.4333555 0 8.83034e-8 -0.4333555 0.9012231 -0.375647 0 0 0 1 1 3.1552e-7 4.62728e-8 -7.45058e-9 -3.06385e-7 0.9103569 0.4138241 7.45058e-9 8.84451e-8 -0.4138241 0.9103569 -0.3756471 0 0 0 1 1 3.16903e-7 4.12583e-8 -7.45058e-9 -3.07067e-7 0.9170442 0.3987856 0 8.85406e-8 -0.3987856 0.9170442 -0.375647 0 0 0 1 1 3.17742e-7 3.80466e-8 -7.45058e-9 -3.07503e-7 0.9211819 0.3891323 -7.45058e-9 8.85959e-8 -0.3891323 0.9211819 -0.3756471 0 0 0 1 + + + + + + + + LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR + + + + + + + + + + + + + + + + 0 0.04166662 0.08333331 0.125 0.1666666 0.2083333 0.25 0.2916666 0.3333333 0.375 0.4166666 0.4583333 0.5 0.5416667 0.5833333 0.625 0.6666667 0.7083333 0.75 0.7916667 0.8333333 0.875 0.9166667 0.9583333 1 1.041667 1.083333 1.125 1.166667 1.208333 1.25 1.291667 1.333333 1.375 1.416667 1.458333 1.5 1.541667 1.583333 1.625 1.666667 1.708333 1.75 1.791667 1.833333 1.875 1.916667 1.958333 2 2.041667 2.083333 2.125 2.166667 2.208333 2.25 2.291667 2.333333 2.375 2.416667 2.458333 + + + + + + + + 1 2.58833e-7 1.69902e-7 0 2.26488e-7 -0.23738 -0.9714168 2.98023e-8 -2.11103e-7 0.971417 -0.2373798 -0.4310732 0 0 0 1 1 2.58702e-7 1.70197e-7 7.45058e-9 2.2649e-7 -0.2362132 -0.9717014 2.98023e-8 -2.11178e-7 0.9717014 -0.2362131 -0.4310732 0 0 0 1 1 2.5832e-7 1.71049e-7 1.49012e-8 2.26495e-7 -0.232838 -0.9725155 5.96046e-8 -2.11394e-7 0.9725156 -0.232838 -0.4310732 0 0 0 1 1 2.57705e-7 1.72408e-7 0 2.26501e-7 -0.2274397 -0.9737923 0 -2.11738e-7 0.9737923 -0.2274396 -0.4310733 0 0 0 1 1 2.56868e-7 1.74221e-7 7.45058e-9 2.26507e-7 -0.2202001 -0.9754546 2.98023e-8 -2.122e-7 0.9754546 -0.2202001 -0.4310732 0 0 0 1 1 2.55824e-7 1.76437e-7 -7.45058e-9 2.2651e-7 -0.2113017 -0.9774209 1.49012e-8 -2.12766e-7 0.9774209 -0.2113016 -0.4310733 0 0 0 1 1 2.54584e-7 1.79004e-7 -7.45058e-9 2.26506e-7 -0.2009258 -0.9796066 -4.47035e-8 -2.13425e-7 0.9796066 -0.2009258 -0.4310733 0 0 0 1 1 2.5316e-7 1.81868e-7 0 2.26493e-7 -0.1892559 -0.9819279 5.96046e-8 -2.14165e-7 0.9819279 -0.1892558 -0.4310733 0 0 0 1 1 2.51565e-7 1.84977e-7 -7.45058e-9 2.2647e-7 -0.1764781 -0.9843047 0 -2.14972e-7 0.9843047 -0.176478 -0.4310733 0 0 0 1 1 2.49815e-7 1.88279e-7 0 2.26433e-7 -0.1627813 -0.9866621 0 -2.15835e-7 0.9866621 -0.1627811 -0.4310732 0 0 0 1 1 2.47928e-7 1.91721e-7 -7.45058e-9 2.26381e-7 -0.1483572 -0.9889339 -1.49012e-8 -2.16741e-7 0.9889339 -0.1483572 -0.4310733 0 0 0 1 1 2.45923e-7 1.95252e-7 1.49012e-8 2.26314e-7 -0.1334014 -0.991062 1.49012e-8 -2.17678e-7 0.9910621 -0.1334014 -0.4310732 0 0 0 1 1 2.43822e-7 1.98824e-7 -1.49012e-8 2.2623e-7 -0.118112 -0.9930004 -1.49012e-8 -2.18632e-7 0.9930004 -0.1181119 -0.4310733 0 0 0 1 1 2.41652e-7 2.02386e-7 0 2.26131e-7 -0.1026897 -0.9947135 -3.72529e-8 -2.19591e-7 0.9947135 -0.1026897 -0.4310732 0 0 0 1 1 2.3944e-7 2.05893e-7 7.45058e-9 2.26018e-7 -0.08733717 -0.9961788 -1.49012e-8 -2.20543e-7 0.9961788 -0.08733711 -0.4310732 0 0 0 1 1 2.37218e-7 2.09299e-7 -7.45058e-9 2.25893e-7 -0.07225832 -0.997386 -7.45058e-9 -2.21475e-7 0.997386 -0.07225817 -0.4310732 0 0 0 1 1 2.35017e-7 2.12566e-7 -7.45058e-9 2.25758e-7 -0.05763507 -0.9983379 7.45058e-8 -2.22375e-7 0.998338 -0.05763498 -0.4310732 0 0 0 1 1 2.32856e-7 2.15676e-7 0 2.25615e-7 -0.04356194 -0.9990507 6.33299e-8 -2.23239e-7 0.9990507 -0.04356188 -0.4310732 0 0 0 1 1 2.3075e-7 2.18619e-7 0 2.25468e-7 -0.03011096 -0.9995465 6.33299e-8 -2.24063e-7 0.9995465 -0.0301109 -0.4310733 0 0 0 1 1 2.28718e-7 2.21382e-7 0 2.25318e-7 -0.01735258 -0.9998494 -5.21541e-8 -2.24842e-7 0.9998494 -0.01735249 -0.4310732 0 0 0 1 1 2.26775e-7 2.23956e-7 0 2.25168e-7 -0.005356282 -0.9999857 -2.8871e-8 -2.25572e-7 0.9999856 -0.005356222 -0.4310733 0 0 0 1 1 2.24939e-7 2.2633e-7 0 2.2502e-7 0.005809188 -0.9999831 -1.67638e-8 -2.2625e-7 0.9999832 0.005809307 -0.4310732 0 0 0 1 1 2.23228e-7 2.28496e-7 -7.45058e-9 2.24877e-7 0.01607645 -0.9998708 2.98023e-8 -2.26872e-7 0.9998708 0.01607662 -0.4310733 0 0 0 1 1 2.21658e-7 2.30442e-7 0 2.24743e-7 0.02537924 -0.999678 7.45058e-9 -2.27435e-7 0.999678 0.0253793 -0.4310733 0 0 0 1 1 2.20246e-7 2.32162e-7 0 2.24618e-7 0.03365147 -0.9994336 -1.49012e-8 -2.27934e-7 0.9994337 0.03365156 -0.4310732 0 0 0 1 1 2.19009e-7 2.33644e-7 0 2.24507e-7 0.04082832 -0.9991661 -7.45058e-9 -2.28366e-7 0.9991662 0.04082841 -0.4310732 0 0 0 1 1 2.17964e-7 2.3488e-7 -1.49012e-8 2.24411e-7 0.04684514 -0.9989021 -7.45058e-9 -2.28728e-7 0.9989021 0.0468452 -0.4310733 0 0 0 1 1 2.17126e-7 2.3586e-7 0 2.24334e-7 0.05163768 -0.9986659 2.98023e-8 -2.29016e-7 0.998666 0.05163774 -0.4310733 0 0 0 1 1 2.1651e-7 2.36575e-7 -7.45058e-9 2.24276e-7 0.05514105 -0.9984787 -7.45058e-9 -2.29226e-7 0.9984787 0.05514111 -0.4310733 0 0 0 1 1 2.16131e-7 2.37012e-7 -7.45058e-9 2.2424e-7 0.05729116 -0.9983575 1.49012e-8 -2.29355e-7 0.9983576 0.05729122 -0.4310732 0 0 0 1 1 1.973e-7 1.04755e-7 0 9.31304e-8 0.05802244 -0.9983154 0 -2.03046e-7 0.9983155 0.05802245 -0.4310732 0 0 0 1 1 1.97831e-7 1.03787e-7 -7.45058e-9 9.31232e-8 0.05316371 -0.9985858 7.45058e-9 -2.03069e-7 0.9985858 0.05316377 -0.4310732 0 0 0 1 1 1.993e-7 1.01049e-7 -7.45058e-9 9.31035e-8 0.03947142 -0.9992208 -7.45058e-9 -2.03133e-7 0.9992207 0.03947148 -0.4310732 0 0 0 1 1 2.015e-7 9.67703e-8 -7.45058e-9 9.30748e-8 0.01826009 -0.9998333 3.72529e-9 -2.03233e-7 0.9998334 0.01826018 -0.4310732 0 0 0 1 1 2.04206e-7 9.11767e-8 0 9.30408e-8 -0.009147048 -0.9999582 2.79397e-8 -2.03364e-7 0.9999582 -0.009146929 -0.4310732 0 0 0 1 1 2.07193e-7 8.45015e-8 7.45058e-9 9.30054e-8 -0.04139304 -0.9991429 1.02445e-8 -2.03518e-7 0.999143 -0.04139307 -0.4310732 0 0 0 1 1 2.1025e-7 7.69954e-8 -7.45058e-9 9.29721e-8 -0.07707849 -0.997025 -2.79397e-8 -2.0369e-7 0.9970251 -0.07707843 -0.4310733 0 0 0 1 1 2.13194e-7 6.89314e-8 0 9.29434e-8 -0.1147667 -0.9933925 -4.09782e-8 -2.03874e-7 0.9933925 -0.1147667 -0.4310732 0 0 0 1 1 2.15877e-7 6.06053e-8 7.45058e-9 9.29215e-8 -0.1530031 -0.9882258 3.72529e-8 -2.04062e-7 0.9882258 -0.153003 -0.4310733 0 0 0 1 1 2.18198e-7 5.23312e-8 0 9.2907e-8 -0.1903436 -0.9817176 1.49012e-8 -2.04248e-7 0.9817176 -0.1903436 -0.4310732 0 0 0 1 1 2.20102e-7 4.44355e-8 0 9.28997e-8 -0.2253849 -0.9742699 -1.49012e-8 -2.04423e-7 0.9742699 -0.2253848 -0.4310732 0 0 0 1 1 2.21577e-7 3.72499e-8 7.45058e-9 9.28986e-8 -0.2567855 -0.9664685 1.49012e-8 -2.04582e-7 0.9664686 -0.2567854 -0.4310733 0 0 0 1 1 2.22648e-7 3.11045e-8 7.45058e-9 9.29017e-8 -0.2832776 -0.959038 -2.98023e-8 -2.04717e-7 0.959038 -0.2832776 -0.4310733 0 0 0 1 1 2.23362e-7 2.63244e-8 7.45058e-9 9.29067e-8 -0.3036564 -0.9527816 0 -2.04822e-7 0.9527817 -0.3036564 -0.4310732 0 0 0 1 1 2.23769e-7 2.32276e-8 0 9.2911e-8 -0.3167533 -0.948508 0 -2.04889e-7 0.948508 -0.3167533 -0.4310733 0 0 0 1 1 2.23903e-7 2.21265e-8 0 9.29128e-8 -0.3213899 -0.946947 -2.98023e-8 -2.04913e-7 0.946947 -0.3213899 -0.4310732 0 0 0 1 1 2.23873e-7 2.23788e-8 -7.45058e-9 9.29131e-8 -0.320331 -0.9473056 2.98023e-8 -2.04908e-7 0.9473057 -0.3203311 -0.4310732 0 0 0 1 1 2.23787e-7 2.30886e-8 -1.49012e-8 9.29139e-8 -0.3173497 -0.9483087 -1.49012e-8 -2.04892e-7 0.9483087 -0.3173496 -0.4310733 0 0 0 1 1 2.2365e-7 2.41847e-8 7.45058e-9 9.29152e-8 -0.3127367 -0.9498399 2.98023e-8 -2.04868e-7 0.9498399 -0.3127366 -0.4310732 0 0 0 1 1 2.23466e-7 2.55961e-8 -7.45058e-9 9.29171e-8 -0.306782 -0.9517798 -1.49012e-8 -2.04838e-7 0.9517798 -0.306782 -0.4310733 0 0 0 1 1 2.23238e-7 2.72512e-8 1.49012e-8 9.29195e-8 -0.299777 -0.9540094 -1.49012e-8 -2.04802e-7 0.9540094 -0.2997768 -0.4310732 0 0 0 1 1 2.22972e-7 2.90791e-8 7.45058e-9 9.29225e-8 -0.2920137 -0.9564143 -1.49012e-8 -2.04762e-7 0.9564143 -0.2920136 -0.4310733 0 0 0 1 1 2.22675e-7 3.10086e-8 7.45058e-9 9.29261e-8 -0.2837871 -0.9588873 2.98023e-8 -2.0472e-7 0.9588873 -0.283787 -0.4310733 0 0 0 1 1 2.22356e-7 3.29695e-8 -7.45058e-9 9.293e-8 -0.2753944 -0.9613314 2.98023e-8 -2.04678e-7 0.9613314 -0.2753944 -0.4310732 0 0 0 1 1 2.22025e-7 3.48914e-8 -7.45058e-9 9.29343e-8 -0.2671355 -0.9636589 5.96046e-8 -2.04636e-7 0.9636589 -0.2671355 -0.4310732 0 0 0 1 1 2.21698e-7 3.67052e-8 -7.45058e-9 9.29386e-8 -0.2593124 -0.9657937 0 -2.04596e-7 0.9657936 -0.2593123 -0.4310732 0 0 0 1 1 2.2139e-7 3.83418e-8 7.45058e-9 9.29428e-8 -0.2522283 -0.9676678 0 -2.04561e-7 0.9676678 -0.2522283 -0.4310732 0 0 0 1 1 2.21118e-7 3.97329e-8 -7.45058e-9 9.29466e-8 -0.2461883 -0.969222 -2.98023e-8 -2.04531e-7 0.9692221 -0.2461883 -0.4310732 0 0 0 1 1 2.20901e-7 4.08107e-8 0 9.29497e-8 -0.2414971 -0.9704015 2.98023e-8 -2.04507e-7 0.9704015 -0.2414971 -0.4310732 0 0 0 1 1 2.20758e-7 4.15073e-8 -1.49012e-8 9.29517e-8 -0.2384597 -0.9711525 -2.98023e-8 -2.04492e-7 0.9711525 -0.2384597 -0.4310733 0 0 0 1 + + + + + + + + LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR + + + + + + + + + + + + + + + + 0 0.04166662 0.08333331 0.125 0.1666666 0.2083333 0.25 0.2916666 0.3333333 0.375 0.4166666 0.4583333 0.5 0.5416667 0.5833333 0.625 0.6666667 0.7083333 0.75 0.7916667 0.8333333 0.875 0.9166667 0.9583333 1 1.041667 1.083333 1.125 1.166667 1.208333 1.25 1.291667 1.333333 1.375 1.416667 1.458333 1.5 1.541667 1.583333 1.625 1.666667 1.708333 1.75 1.791667 1.833333 1.875 1.916667 1.958333 2 2.041667 2.083333 2.125 2.166667 2.208333 2.25 2.291667 2.333333 2.375 2.416667 2.458333 + + + + + + + + 1 -1.50996e-7 4.9738e-14 -0.08954165 -1.32845e-7 -0.8797947 0.4753538 0.02421998 -7.17764e-8 -0.4753538 -0.8797947 0.03911464 0 0 0 1 1 -1.51081e-7 -3.38403e-10 -0.08954165 -1.32923e-7 -0.8808763 0.4733466 0.02421998 -7.18118e-8 -0.4733466 -0.8808763 0.03911464 0 0 0 1 1 -1.51325e-7 -1.32488e-9 -0.08954165 -1.33151e-7 -0.883999 0.4674889 0.02421998 -7.19137e-8 -0.4674889 -0.883999 0.03911464 0 0 0 1 1 -1.51703e-7 -2.91824e-9 -0.08954165 -1.3352e-7 -0.8889502 0.4580039 0.02421998 -7.20749e-8 -0.4580039 -0.8889502 0.03911464 0 0 0 1 1 -1.52189e-7 -5.07937e-9 -0.08954165 -1.34022e-7 -0.8954841 0.4450934 0.02421998 -7.22866e-8 -0.4450934 -0.8954841 0.03911464 0 0 0 1 1 -1.52747e-7 -7.77001e-9 -0.08954165 -1.34648e-7 -0.9033299 0.4289464 0.02421998 -7.25391e-8 -0.4289464 -0.9033299 0.03911464 0 0 0 1 1 -1.53343e-7 -1.09517e-8 -0.08954165 -1.35391e-7 -0.9121982 0.4097492 0.02421998 -7.28221e-8 -0.4097492 -0.9121982 0.03911464 0 0 0 1 1 -1.53938e-7 -1.45846e-8 -0.08954165 -1.36244e-7 -0.9217883 0.3876937 0.02421998 -7.31247e-8 -0.3876937 -0.9217883 0.03911464 0 0 0 1 1 -1.54496e-7 -1.8627e-8 -0.08954165 -1.37197e-7 -0.9317952 0.3629846 0.02421998 -7.34361e-8 -0.3629846 -0.9317952 0.03911464 0 0 0 1 1 -1.54979e-7 -2.30343e-8 -0.08954165 -1.38242e-7 -0.9419171 0.3358454 0.02421998 -7.37455e-8 -0.3358454 -0.9419171 0.03911464 0 0 0 1 1 -1.55355e-7 -2.77589e-8 -0.08954165 -1.39368e-7 -0.951863 0.3065238 0.02421998 -7.40427e-8 -0.3065238 -0.951863 0.03911464 0 0 0 1 1 -1.55593e-7 -3.27499e-8 -0.08954165 -1.40565e-7 -0.9613603 0.2752931 0.02421998 -7.4318e-8 -0.2752931 -0.9613603 0.03911464 0 0 0 1 1 -1.55666e-7 -3.79535e-8 -0.08954165 -1.4182e-7 -0.9701628 0.2424542 0.02421998 -7.45631e-8 -0.2424542 -0.9701628 0.03911464 0 0 0 1 1 -1.55558e-7 -4.33132e-8 -0.08954165 -1.43121e-7 -0.9780577 0.2083342 0.02421998 -7.47708e-8 -0.2083342 -0.9780577 0.03911464 0 0 0 1 1 -1.55254e-7 -4.87705e-8 -0.08954165 -1.44454e-7 -0.984872 0.1732831 0.02421998 -7.49356e-8 -0.1732831 -0.984872 0.03911464 0 0 0 1 1 -1.54749e-7 -5.42658e-8 -0.08954165 -1.45805e-7 -0.9904781 0.1376704 0.02421998 -7.50535e-8 -0.1376704 -0.9904781 0.03911464 0 0 0 1 1 -1.54047e-7 -5.97394e-8 -0.08954165 -1.47159e-7 -0.9947968 0.1018787 0.02421998 -7.51227e-8 -0.1018787 -0.9947968 0.03911464 0 0 0 1 1 -1.53157e-7 -6.51323e-8 -0.08954165 -1.48502e-7 -0.9977999 0.06629794 0.02421998 -7.5143e-8 -0.06629794 -0.9977999 0.03911464 0 0 0 1 1 -1.52098e-7 -7.03875e-8 -0.08954165 -1.49819e-7 -0.9995095 0.0313181 0.02421998 -7.51164e-8 -0.0313181 -0.9995095 0.03911464 0 0 0 1 1 -1.50895e-7 -7.54506e-8 -0.08954165 -1.51096e-7 -0.9999964 -0.002676592 0.02421998 -7.50464e-8 0.002676592 -0.9999964 0.03911464 0 0 0 1 1 -1.49578e-7 -8.02706e-8 -0.08954165 -1.52319e-7 -0.9993762 -0.03531351 0.02421998 -7.49384e-8 0.03531351 -0.9993762 0.03911464 0 0 0 1 1 -1.48184e-7 -8.48005e-8 -0.08954165 -1.53476e-7 -0.997804 -0.06623603 0.02421998 -7.47992e-8 0.06623603 -0.997804 0.03911464 0 0 0 1 1 -1.46754e-7 -8.89973e-8 -0.08954165 -1.54553e-7 -0.9954671 -0.0951069 0.02421998 -7.46365e-8 0.0951069 -0.9954671 0.03911464 0 0 0 1 1 -1.45331e-7 -9.28217e-8 -0.08954165 -1.5554e-7 -0.9925781 -0.1216085 0.02421998 -7.44594e-8 0.1216085 -0.9925781 0.03911464 0 0 0 1 1 -1.4396e-7 -9.62383e-8 -0.08954165 -1.56426e-7 -0.9893666 -0.1454435 0.02421998 -7.4277e-8 0.1454435 -0.9893666 0.03911464 0 0 0 1 1 -1.42687e-7 -9.92144e-8 -0.08954165 -1.57202e-7 -0.9860699 -0.1663315 0.02421998 -7.4099e-8 0.1663315 -0.9860699 0.03911464 0 0 0 1 1 -1.41557e-7 -1.01719e-7 -0.08954165 -1.57857e-7 -0.9829251 -0.184006 0.02421998 -7.39351e-8 0.184006 -0.9829251 0.03911464 0 0 0 1 1 -1.40613e-7 -1.03723e-7 -0.08954165 -1.58382e-7 -0.9801598 -0.1982091 0.02421998 -7.37945e-8 0.1982091 -0.9801598 0.03911464 0 0 0 1 1 -1.39897e-7 -1.05196e-7 -0.08954165 -1.5877e-7 -0.9779829 -0.2086847 0.02421998 -7.36856e-8 0.2086847 -0.9779829 0.03911464 0 0 0 1 1 -1.39445e-7 -1.06106e-7 -0.08954165 -1.5901e-7 -0.9765761 -0.2151721 0.02421998 -7.3616e-8 0.2151721 -0.9765761 0.03911464 0 0 0 1 1 -1.50996e-7 4.26326e-14 -0.08954165 -1.47384e-7 -0.976083 -0.2173982 0.02421998 3.28263e-8 0.2173982 -0.976083 0.03911464 0 0 0 1 1 -1.51067e-7 6.5662e-10 -0.08954165 -1.47455e-7 -0.9770183 -0.2131555 0.02421998 3.28422e-8 0.2131555 -0.9770183 0.03911464 0 0 0 1 1 -1.51257e-7 2.5789e-9 -0.08954165 -1.47661e-7 -0.979646 -0.2007328 0.02421998 3.28887e-8 0.2007328 -0.979646 0.03911464 0 0 0 1 1 -1.51515e-7 5.69999e-9 -0.08954165 -1.47996e-7 -0.9835666 -0.1805459 0.02421998 3.29617e-8 0.1805459 -0.9835666 0.03911464 0 0 0 1 1 -1.51762e-7 9.95615e-9 -0.08954165 -1.48453e-7 -0.9882304 -0.1529729 0.02421998 3.30544e-8 0.1529729 -0.9882304 0.03911464 0 0 0 1 1 -1.51904e-7 1.52831e-8 -0.08954165 -1.49026e-7 -0.992968 -0.1183832 0.02421998 3.31584e-8 0.1183832 -0.992968 0.03911464 0 0 0 1 1 -1.51831e-7 2.16118e-8 -0.08954165 -1.4971e-7 -0.9970182 -0.07716671 0.02421998 3.32636e-8 0.07716671 -0.9970182 0.03911464 0 0 0 1 1 -1.51425e-7 2.88646e-8 -0.08954165 -1.50499e-7 -0.999557 -0.02976404 0.02421998 3.33589e-8 0.02976404 -0.999557 0.03911464 0 0 0 1 1 -1.50565e-7 3.69519e-8 -0.08954165 -1.51385e-7 -0.9997283 0.0233081 0.02421998 3.34325e-8 -0.0233081 -0.9997283 0.03911464 0 0 0 1 1 -1.49129e-7 4.57691e-8 -0.08954165 -1.52361e-7 -0.9966786 0.08143603 0.02421998 3.34727e-8 -0.08143603 -0.9966786 0.03911464 0 0 0 1 1 -1.47004e-7 5.51958e-8 -0.08954165 -1.53416e-7 -0.9895926 0.1438971 0.02421998 3.3468e-8 -0.1438971 -0.9895926 0.03911464 0 0 0 1 1 -1.44089e-7 6.50956e-8 -0.08954165 -1.54541e-7 -0.9777322 0.2098567 0.02421998 3.34081e-8 -0.2098567 -0.9777322 0.03911464 0 0 0 1 1 -1.40301e-7 7.53178e-8 -0.08954165 -1.55722e-7 -0.9604719 0.2783768 0.02421998 3.32841e-8 -0.2783768 -0.9604719 0.03911464 0 0 0 1 1 -1.35582e-7 8.57013e-8 -0.08954165 -1.56947e-7 -0.9373328 0.3484354 0.02421998 3.3089e-8 -0.3484354 -0.9373328 0.03911464 0 0 0 1 1 -1.29899e-7 9.60788e-8 -0.08954165 -1.58202e-7 -0.908007 0.4189552 0.02421998 3.28183e-8 -0.4189552 -0.908007 0.03911464 0 0 0 1 1 -1.23247e-7 1.06283e-7 -0.08954165 -1.59473e-7 -0.872373 0.4888408 0.02421998 3.24699e-8 -0.4888408 -0.872373 0.03911464 0 0 0 1 1 -1.15714e-7 1.16089e-7 -0.08954165 -1.60742e-7 -0.8308836 0.5564463 0.02421998 3.20683e-8 -0.5564463 -0.8308836 0.03911464 0 0 0 1 1 -1.0793e-7 1.24783e-7 -0.08954165 -1.6192e-7 -0.787133 0.6167832 0.02421998 3.16516e-8 -0.6167832 -0.787133 0.03911464 0 0 0 1 1 -1.00918e-7 1.3163e-7 -0.08954165 -1.62891e-7 -0.7471242 0.6646845 0.02421998 3.12657e-8 -0.6646845 -0.7471242 0.03911464 0 0 0 1 1 -9.58506e-8 1.36091e-7 -0.08954165 -1.63549e-7 -0.7179278 0.6961176 0.02421998 3.09805e-8 -0.6961176 -0.7179278 0.03911464 0 0 0 1 1 -9.39157e-8 1.37699e-7 -0.08954165 -1.63793e-7 -0.7067257 0.7074876 0.02421998 3.08711e-8 -0.7074876 -0.7067257 0.03911464 0 0 0 1 1 -9.49157e-8 1.36871e-7 -0.08954165 -1.63666e-7 -0.7125059 0.7016662 0.02421998 3.0922e-8 -0.7016662 -0.7125059 0.03911464 0 0 0 1 1 -9.7595e-8 1.34582e-7 -0.08954165 -1.63318e-7 -0.7279488 0.6856314 0.02421998 3.10547e-8 -0.6856314 -0.7279488 0.03911464 0 0 0 1 1 -1.01446e-7 1.31105e-7 -0.08954165 -1.62801e-7 -0.7500317 0.661402 0.02421998 3.12361e-8 -0.661402 -0.7500317 0.03911464 0 0 0 1 1 -1.0596e-7 1.26723e-7 -0.08954165 -1.62167e-7 -0.7757228 0.6310738 0.02421998 3.14331e-8 -0.6310738 -0.7757228 0.03911464 0 0 0 1 1 -1.10658e-7 1.21767e-7 -0.08954165 -1.6147e-7 -0.8022222 0.5970257 0.02421998 3.16183e-8 -0.5970257 -0.8022222 0.03911464 0 0 0 1 1 -1.15122e-7 1.16631e-7 -0.08954165 -1.60768e-7 -0.8271427 0.561992 0.02421998 3.17727e-8 -0.561992 -0.8271427 0.03911464 0 0 0 1 1 -1.19011e-7 1.11768e-7 -0.08954165 -1.60121e-7 -0.8486072 0.5290233 0.02421998 3.18874e-8 -0.5290233 -0.8486072 0.03911464 0 0 0 1 1 -1.22054e-7 1.07668e-7 -0.08954165 -1.59587e-7 -0.8652282 0.5013782 0.02421998 3.19625e-8 -0.5013782 -0.8652282 0.03911464 0 0 0 1 1 -1.24036e-7 1.04843e-7 -0.08954165 -1.59225e-7 -0.8759558 0.4823915 0.02421998 3.20034e-8 -0.4823915 -0.8759558 0.03911464 0 0 0 1 + + + + + + + + LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR + + + + + + + + + + + + + + + + 0 0.04166662 0.08333331 0.125 0.1666666 0.2083333 0.25 0.2916666 0.3333333 0.375 0.4166666 0.4583333 0.5 0.5416667 0.5833333 0.625 0.6666667 0.7083333 0.75 0.7916667 0.8333333 0.875 0.9166667 0.9583333 1 1.041667 1.083333 1.125 1.166667 1.208333 1.25 1.291667 1.333333 1.375 1.416667 1.458333 1.5 1.541667 1.583333 1.625 1.666667 1.708333 1.75 1.791667 1.833333 1.875 1.916667 1.958333 2 2.041667 2.083333 2.125 2.166667 2.208333 2.25 2.291667 2.333333 2.375 2.416667 2.458333 + + + + + + + + 1 -1.82491e-7 9.23719e-8 0 8.78508e-8 0.7910497 0.6117519 0 -1.8471e-7 -0.6117519 0.7910497 -0.375647 0 0 0 1 1 -1.82502e-7 9.21309e-8 0 8.77097e-8 0.7900649 0.6130231 -1.49012e-8 -1.84667e-7 -0.6130231 0.7900649 -0.3756471 0 0 0 1 1 -1.82529e-7 9.14523e-8 0 8.73129e-8 0.7872824 0.6165926 1.49012e-8 -1.84545e-7 -0.6165926 0.7872824 -0.3756471 0 0 0 1 1 -1.82565e-7 9.04029e-8 0 8.67007e-8 0.7829491 0.6220857 0 -1.84352e-7 -0.6220857 0.7829491 -0.3756471 0 0 0 1 1 -1.82601e-7 8.90498e-8 0 8.59134e-8 0.7773059 0.6291227 0 -1.84097e-7 -0.6291227 0.7773059 -0.375647 0 0 0 1 1 -1.82627e-7 8.74598e-8 0 8.49915e-8 0.7705957 0.6373243 1.49012e-8 -1.83789e-7 -0.6373243 0.7705957 -0.3756471 0 0 0 1 1 -1.82637e-7 8.57004e-8 1.49012e-8 8.39752e-8 0.7630702 0.6463159 0 -1.83436e-7 -0.6463159 0.7630702 -0.3756471 0 0 0 1 1 -1.82625e-7 8.3839e-8 7.45058e-9 8.29047e-8 0.7549945 0.6557313 0 -1.83051e-7 -0.6557313 0.7549945 -0.3756471 0 0 0 1 1 -1.82588e-7 8.19435e-8 0 8.18194e-8 0.7466503 0.6652167 -1.49012e-8 -1.82644e-7 -0.6652167 0.7466503 -0.3756471 0 0 0 1 1 -1.82529e-7 8.0082e-8 -7.45058e-9 8.07583e-8 0.7383364 0.6744326 1.49012e-8 -1.82231e-7 -0.6744326 0.7383364 -0.3756471 0 0 0 1 1 -1.82453e-7 7.83221e-8 -7.45058e-9 7.97594e-8 0.7303687 0.683053 7.45058e-9 -1.81829e-7 -0.683053 0.7303687 -0.375647 0 0 0 1 1 -1.82365e-7 7.67317e-8 0 7.88604e-8 0.7230778 0.6907667 7.45058e-9 -1.81455e-7 -0.6907667 0.7230778 -0.375647 0 0 0 1 1 -1.82277e-7 7.53781e-8 0 7.8098e-8 0.7168041 0.6972747 7.45058e-9 -1.81129e-7 -0.6972747 0.7168041 -0.3756471 0 0 0 1 1 -1.82201e-7 7.43283e-8 -7.45058e-9 7.75084e-8 0.7118958 0.7022852 0 -1.80871e-7 -0.7022852 0.7118958 -0.375647 0 0 0 1 1 -1.82148e-7 7.36494e-8 -1.49012e-8 7.71279e-8 0.7087014 0.7055086 3.72529e-9 -1.80702e-7 -0.7055086 0.7087014 -0.375647 0 0 0 1 1 -1.82128e-7 7.34082e-8 0 7.69929e-8 0.7075625 0.7066507 0 -1.80642e-7 -0.7066507 0.7075625 -0.375647 0 0 0 1 1 -1.8219e-7 7.40854e-8 7.45058e-9 7.73468e-8 0.7106338 0.7035621 0 -1.8083e-7 -0.7035621 0.7106338 -0.3756471 0 0 0 1 1 -1.8235e-7 7.59935e-8 -7.45058e-9 7.83476e-8 0.7192084 0.6947945 0 -1.81351e-7 -0.6947945 0.7192084 -0.3756471 0 0 0 1 1 -1.8255e-7 7.8949e-8 0 7.99084e-8 0.7322606 0.6810244 -9.31323e-10 -1.82133e-7 -0.6810244 0.7322606 -0.3756471 0 0 0 1 1 -1.82727e-7 8.27674e-8 0 8.19438e-8 0.7487133 0.662894 2.32831e-10 -1.83097e-7 -0.662894 0.7487133 -0.375647 0 0 0 1 1 -1.82814e-7 8.72608e-8 0 8.43663e-8 0.7674825 0.6410699 9.31323e-10 -1.84168e-7 -0.6410699 0.7674825 -0.3756471 0 0 0 1 1 -1.8276e-7 9.2236e-8 -7.45058e-9 8.70829e-8 0.7875191 0.6162902 0 -1.85271e-7 -0.6162902 0.7875191 -0.375647 0 0 0 1 1 -1.8253e-7 9.74954e-8 -7.45058e-9 8.9994e-8 0.8078485 0.5893902 0 -1.86343e-7 -0.5893902 0.8078485 -0.375647 0 0 0 1 1 -1.82114e-7 1.02839e-7 7.45058e-9 9.29933e-8 0.8276026 0.5613146 -3.72529e-9 -1.87333e-7 -0.5613146 0.8276026 -0.375647 0 0 0 1 1 -1.81528e-7 1.08068e-7 7.45058e-9 9.59687e-8 0.8460453 0.5331112 -3.72529e-9 -1.88205e-7 -0.5331112 0.8460453 -0.3756471 0 0 0 1 1 -1.80812e-7 1.12986e-7 -7.45058e-9 9.88048e-8 0.8625836 0.5059144 7.45058e-9 -1.88935e-7 -0.5059144 0.8625836 -0.375647 0 0 0 1 1 -1.80032e-7 1.17404e-7 0 1.01384e-7 0.8767643 0.4809202 1.49012e-8 -1.89517e-7 -0.4809202 0.8767643 -0.375647 0 0 0 1 1 -1.7927e-7 1.21141e-7 -1.49012e-8 1.03589e-7 0.8882512 0.4593579 7.45058e-9 -1.89953e-7 -0.4593579 0.8882512 -0.375647 0 0 0 1 1 -1.78616e-7 1.24023e-7 -7.45058e-9 1.05304e-7 0.8967854 0.4424657 0 -1.90254e-7 -0.4424657 0.8967854 -0.3756471 0 0 0 1 1 -1.78165e-7 1.25879e-7 -1.49012e-8 1.06416e-7 0.9021297 0.4314651 0 -1.90431e-7 -0.4314651 0.9021297 -0.375647 0 0 0 1 1 -1.65437e-7 6.45572e-8 0 1.21953e-7 0.903995 0.4275432 7.45058e-9 -1.29091e-7 -0.4275432 0.903995 -0.3756471 0 0 0 1 1 -1.65539e-7 6.28213e-8 0 1.21171e-7 0.8985401 0.4388915 7.45058e-9 -1.29101e-7 -0.4388915 0.8985401 -0.3756471 0 0 0 1 1 -1.65708e-7 5.79009e-8 -7.45058e-9 1.18958e-7 0.8823252 0.4706401 7.45058e-9 -1.29076e-7 -0.4706401 0.8823252 -0.3756471 0 0 0 1 1 -1.65622e-7 5.021e-8 7.45058e-9 1.15506e-7 0.8547559 0.5190303 7.45058e-9 -1.2888e-7 -0.5190303 0.8547559 -0.375647 0 0 0 1 1 -1.64866e-7 4.01929e-8 0 1.11023e-7 0.8147655 0.5797908 3.72529e-9 -1.28335e-7 -0.5797908 0.8147655 -0.3756471 0 0 0 1 1 -1.63018e-7 2.83783e-8 -7.45058e-9 1.05755e-7 0.7615547 0.6481006 0 -1.27264e-7 -0.6481006 0.7615547 -0.375647 0 0 0 1 1 -1.59748e-7 1.54023e-8 7.45058e-9 9.9995e-8 0.6952548 0.7187634 0 -1.2553e-7 -0.7187634 0.6952548 -0.375647 0 0 0 1 1 -1.54897e-7 1.98788e-9 0 9.40702e-8 0.6174045 0.7866458 9.31323e-10 -1.23076e-7 -0.7866458 0.6174045 -0.3756471 0 0 0 1 1 -1.48542e-7 -1.11198e-8 0 8.8314e-8 0.5311109 0.8473023 -9.31323e-10 -1.19954e-7 -0.8473023 0.5311109 -0.3756471 0 0 0 1 1 -1.4101e-7 -2.3244e-8 7.45058e-9 8.30235e-8 0.44082 0.8975955 -1.86265e-9 -1.16323e-7 -0.8975955 0.44082 -0.3756471 0 0 0 1 1 -1.32836e-7 -3.38599e-8 -7.45058e-9 7.84235e-8 0.3517694 0.9360867 -3.72529e-9 -1.12435e-7 -0.9360867 0.3517694 -0.3756471 0 0 0 1 1 -1.24688e-7 -4.26408e-8 1.49012e-8 7.4647e-8 0.2693275 0.9630488 0 -1.08596e-7 -0.9630488 0.2693275 -0.3756471 0 0 0 1 1 -1.17273e-7 -4.94508e-8 -7.45058e-9 7.17406e-8 0.1984538 0.9801102 0 -1.05127e-7 -0.9801102 0.1984538 -0.3756471 0 0 0 1 1 -1.11271e-7 -5.42906e-8 7.45058e-9 6.96901e-8 0.1434426 0.9896587 -7.45058e-9 -1.02332e-7 -0.9896587 0.1434426 -0.3756471 0 0 0 1 1 -1.07289e-7 -5.72101e-8 0 6.84605e-8 0.1079777 0.9941532 0 -1.00485e-7 -0.9941532 0.1079777 -0.375647 0 0 0 1 1 -1.05858e-7 -5.82071e-8 7.45058e-9 6.80421e-8 0.09541538 0.9954376 0 -9.98216e-8 -0.9954376 0.09541538 -0.3756471 0 0 0 1 1 -1.06986e-7 -5.74341e-8 0 6.84018e-8 0.1055111 0.994418 0 -1.00329e-7 -0.994418 0.1055111 -0.375647 0 0 0 1 1 -1.10128e-7 -5.51895e-8 7.45058e-9 6.94453e-8 0.1339645 0.9909862 1.49012e-8 -1.01742e-7 -0.9909862 0.1339645 -0.3756471 0 0 0 1 1 -1.14886e-7 -5.15209e-8 -7.45058e-9 7.11481e-8 0.1780031 0.98403 0 -1.0388e-7 -0.98403 0.1780031 -0.3756471 0 0 0 1 1 -1.20813e-7 -4.64444e-8 7.45058e-9 7.34997e-8 0.2346787 0.972073 0 -1.0654e-7 -0.972073 0.2346787 -0.3756471 0 0 0 1 1 -1.27437e-7 -4.00031e-8 7.45058e-9 7.64772e-8 0.3007442 0.9537049 1.49012e-8 -1.09507e-7 -0.9537049 0.3007442 -0.375647 0 0 0 1 1 -1.34275e-7 -3.23149e-8 7.45058e-9 8.00234e-8 0.3726389 0.9279765 -2.98023e-8 -1.12562e-7 -0.9279765 0.3726389 -0.3756471 0 0 0 1 1 -1.40872e-7 -2.36023e-8 7.45058e-9 8.40338e-8 0.44662 0.8947237 -2.98023e-8 -1.155e-7 -0.8947237 0.44662 -0.3756471 0 0 0 1 1 -1.46849e-7 -1.41989e-8 0 8.8354e-8 0.5190172 0.8547637 0 -1.18152e-7 -0.8547637 0.5190172 -0.375647 0 0 0 1 1 -1.51934e-7 -4.53275e-9 7.45058e-9 9.27874e-8 0.5865436 0.8099177 1.49012e-8 -1.20396e-7 -0.8099177 0.5865436 -0.3756471 0 0 0 1 1 -1.55989e-7 4.91e-9 7.45058e-9 9.71116e-8 0.6465646 0.7628592 0 -1.22173e-7 -0.7628592 0.6465646 -0.375647 0 0 0 1 1 -1.59006e-7 1.36261e-8 0 1.01098e-7 0.6972403 0.7168373 0 -1.23482e-7 -0.7168373 0.6972403 -0.375647 0 0 0 1 1 -1.61085e-7 2.11316e-8 -7.45058e-9 1.04527e-7 0.7374908 0.6753571 1.49012e-8 -1.24374e-7 -0.6753571 0.7374908 -0.375647 0 0 0 1 1 -1.62386e-7 2.69808e-8 1.49012e-8 1.07197e-7 0.7667888 0.6418994 -1.49012e-8 -1.24924e-7 -0.6418994 0.7667888 -0.375647 0 0 0 1 1 -1.63085e-7 3.07678e-8 1.49012e-8 1.08925e-7 0.7848199 0.619724 0 -1.25215e-7 -0.619724 0.7848199 -0.3756471 0 0 0 1 + + + + + + + + LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR + + + + + + + + + + + + + + + + 0 0.04166662 0.08333331 0.125 0.1666666 0.2083333 0.25 0.2916666 0.3333333 0.375 0.4166666 0.4583333 0.5 0.5416667 0.5833333 0.625 0.6666667 0.7083333 0.75 0.7916667 0.8333333 0.875 0.9166667 0.9583333 1 1.041667 1.083333 1.125 1.166667 1.208333 1.25 1.291667 1.333333 1.375 1.416667 1.458333 1.5 1.541667 1.583333 1.625 1.666667 1.708333 1.75 1.791667 1.833333 1.875 1.916667 1.958333 2 2.041667 2.083333 2.125 2.166667 2.208333 2.25 2.291667 2.333333 2.375 2.416667 2.458333 + + + + + + + + 1 -2.3825e-7 -3.01186e-7 -7.45058e-9 -2.83652e-7 0.07045417 -0.9975151 7.45058e-9 2.58877e-7 0.9975151 0.07045422 -0.4310732 0 0 0 1 1 -2.39224e-7 -3.00348e-7 0 -2.83694e-7 0.06681252 -0.9977656 0 2.58757e-7 0.9977656 0.06681257 -0.4310732 0 0 0 1 1 -2.4197e-7 -2.97955e-7 0 -2.83811e-7 0.0564853 -0.9984034 -7.45058e-9 2.58414e-7 0.9984035 0.05648535 -0.4310732 0 0 0 1 1 -2.46205e-7 -2.94162e-7 -7.45058e-9 -2.83986e-7 0.04035893 -0.9991853 0 2.57877e-7 0.9991853 0.04035901 -0.4310732 0 0 0 1 1 -2.51633e-7 -2.89115e-7 0 -2.842e-7 0.01931971 -0.9998134 1.49012e-8 2.57172e-7 0.9998134 0.01931977 -0.4310733 0 0 0 1 1 -2.57953e-7 -2.8296e-7 1.49012e-8 -2.84434e-7 -0.005731463 -0.9999837 -1.11759e-8 2.56327e-7 0.9999838 -0.005731419 -0.4310732 0 0 0 1 1 -2.64866e-7 -2.75857e-7 0 -2.8467e-7 -0.03386962 -0.9994262 1.86265e-8 2.55371e-7 0.9994263 -0.03386953 -0.4310733 0 0 0 1 1 -2.72085e-7 -2.67991e-7 -7.45058e-9 -2.84892e-7 -0.06414352 -0.9979407 9.31323e-9 2.54334e-7 0.9979407 -0.06414346 -0.4310733 0 0 0 1 1 -2.79338e-7 -2.59575e-7 0 -2.85086e-7 -0.09558101 -0.9954218 -1.30385e-8 2.53249e-7 0.9954217 -0.09558089 -0.4310732 0 0 0 1 1 -2.86382e-7 -2.50854e-7 -7.45058e-9 -2.85244e-7 -0.1271988 -0.9918774 2.98023e-8 2.52147e-7 0.9918773 -0.1271986 -0.4310733 0 0 0 1 1 -2.93002e-7 -2.42103e-7 -7.45058e-9 -2.8536e-7 -0.1580167 -0.9874364 2.98023e-8 2.51065e-7 0.9874365 -0.1580166 -0.4310732 0 0 0 1 1 -2.99019e-7 -2.3362e-7 0 -2.85434e-7 -0.1870718 -0.9823464 -7.45058e-9 2.50036e-7 0.9823464 -0.1870718 -0.4310732 0 0 0 1 1 -3.04284e-7 -2.25725e-7 0 -2.85467e-7 -0.2134305 -0.9769583 2.23517e-8 2.49096e-7 0.9769583 -0.2134304 -0.4310733 0 0 0 1 1 -3.08679e-7 -2.18748e-7 0 -2.85467e-7 -0.2361934 -0.971706 1.49012e-8 2.48278e-7 0.9717062 -0.2361934 -0.4310732 0 0 0 1 1 -3.12108e-7 -2.13024e-7 7.45058e-9 -2.8544e-7 -0.2544962 -0.9670739 2.98023e-8 2.47617e-7 0.9670739 -0.2544961 -0.4310733 0 0 0 1 1 -3.14482e-7 -2.08884e-7 -7.45058e-9 -2.85396e-7 -0.2674987 -0.9635583 4.47035e-8 2.47146e-7 0.9635583 -0.2674987 -0.4310732 0 0 0 1 1 -3.16165e-7 -2.05851e-7 -7.45058e-9 -2.85347e-7 -0.2768966 -0.9608997 1.49012e-8 2.46804e-7 0.9608998 -0.2768965 -0.4310733 0 0 0 1 1 -3.17598e-7 -2.03212e-7 0 -2.85302e-7 -0.285009 -0.9585249 0 2.46508e-7 0.9585249 -0.285009 -0.4310732 0 0 0 1 1 -3.18806e-7 -2.00943e-7 0 -2.85261e-7 -0.2919388 -0.956437 0 2.46255e-7 0.9564371 -0.2919386 -0.4310732 0 0 0 1 1 -3.19815e-7 -1.99018e-7 0 -2.85226e-7 -0.2977853 -0.954633 -2.98023e-8 2.46042e-7 0.954633 -0.2977853 -0.4310732 0 0 0 1 1 -3.20647e-7 -1.9741e-7 7.45058e-9 -2.85195e-7 -0.3026462 -0.9531031 0 2.45864e-7 0.9531031 -0.3026462 -0.4310732 0 0 0 1 1 -3.21321e-7 -1.96092e-7 0 -2.85169e-7 -0.3066168 -0.9518331 -4.47035e-8 2.45719e-7 0.9518332 -0.3066167 -0.4310732 0 0 0 1 1 -3.21856e-7 -1.95035e-7 7.45058e-9 -2.85148e-7 -0.3097898 -0.9508051 0 2.45603e-7 0.9508051 -0.3097898 -0.4310732 0 0 0 1 1 -3.2227e-7 -1.94211e-7 0 -2.85131e-7 -0.3122572 -0.9499977 -1.49012e-8 2.45512e-7 0.9499977 -0.3122572 -0.4310733 0 0 0 1 1 -3.2258e-7 -1.93592e-7 -7.45058e-9 -2.85119e-7 -0.3141092 -0.9493868 0 2.45444e-7 0.9493868 -0.3141091 -0.4310732 0 0 0 1 1 -3.22801e-7 -1.93148e-7 1.49012e-8 -2.8511e-7 -0.3154351 -0.9489471 0 2.45396e-7 0.9489471 -0.3154351 -0.4310732 0 0 0 1 1 -3.22949e-7 -1.9285e-7 0 -2.85103e-7 -0.3163233 -0.9486516 -2.98023e-8 2.45363e-7 0.9486516 -0.3163232 -0.4310732 0 0 0 1 1 -3.23039e-7 -1.92669e-7 0 -2.851e-7 -0.316862 -0.9484717 5.96046e-8 2.45344e-7 0.9484716 -0.316862 -0.4310732 0 0 0 1 1 -3.23085e-7 -1.92576e-7 0 -2.85098e-7 -0.3171385 -0.9483793 0 2.45333e-7 0.9483793 -0.3171385 -0.4310733 0 0 0 1 1 -3.23102e-7 -1.92542e-7 7.45058e-9 -2.85097e-7 -0.3172403 -0.9483453 0 2.4533e-7 0.9483452 -0.3172403 -0.4310732 0 0 0 1 1 -3.55313e-7 -2.86338e-7 0 -3.84271e-7 -0.3172548 -0.9483405 -2.98023e-8 2.46116e-7 0.9483405 -0.3172547 -0.4310733 0 0 0 1 1 -3.5525e-7 -2.86444e-7 0 -3.84275e-7 -0.3169612 -0.9484386 -2.98023e-8 2.46142e-7 0.9484387 -0.3169612 -0.4310732 0 0 0 1 1 -3.55049e-7 -2.86781e-7 7.45058e-9 -3.84287e-7 -0.3160196 -0.9487527 0 2.46225e-7 0.9487528 -0.3160195 -0.4310732 0 0 0 1 1 -3.54689e-7 -2.87381e-7 0 -3.84307e-7 -0.3143387 -0.9493109 -2.98023e-8 2.46375e-7 0.9493109 -0.3143386 -0.4310732 0 0 0 1 1 -3.54148e-7 -2.88276e-7 -2.23517e-8 -3.84335e-7 -0.3118261 -0.9501391 0 2.46598e-7 0.9501392 -0.311826 -0.4310732 0 0 0 1 1 -3.53405e-7 -2.89495e-7 7.45058e-9 -3.8437e-7 -0.3083877 -0.9512609 1.49012e-8 2.46904e-7 0.9512609 -0.3083875 -0.4310733 0 0 0 1 1 -3.52435e-7 -2.91067e-7 7.45058e-9 -3.84413e-7 -0.3039284 -0.9526949 -2.98023e-8 2.47299e-7 0.9526949 -0.3039284 -0.4310732 0 0 0 1 1 -3.51213e-7 -2.93022e-7 7.45058e-9 -3.84461e-7 -0.2983507 -0.9544564 2.98023e-8 2.47794e-7 0.9544564 -0.2983507 -0.4310733 0 0 0 1 1 -3.49711e-7 -2.95387e-7 7.45058e-9 -3.84514e-7 -0.2915555 -0.956554 -1.49012e-8 2.48395e-7 0.9565541 -0.2915555 -0.4310733 0 0 0 1 1 -3.47898e-7 -2.98189e-7 0 -3.84569e-7 -0.283441 -0.9589897 0 2.49112e-7 0.9589899 -0.2834409 -0.4310733 0 0 0 1 1 -3.45743e-7 -3.0145e-7 7.45058e-9 -3.84622e-7 -0.2739032 -0.9617573 4.47035e-8 2.49953e-7 0.9617574 -0.2739032 -0.4310733 0 0 0 1 1 -3.43209e-7 -3.05193e-7 7.45058e-9 -3.84671e-7 -0.2628356 -0.9648407 -1.49012e-8 2.50926e-7 0.9648408 -0.2628355 -0.4310733 0 0 0 1 1 -3.40255e-7 -3.09438e-7 0 -3.84709e-7 -0.2501294 -0.9682125 0 2.5204e-7 0.9682126 -0.2501293 -0.4310733 0 0 0 1 1 -3.3684e-7 -3.14198e-7 -7.45058e-9 -3.84732e-7 -0.2356741 -0.9718321 -7.45058e-9 2.53303e-7 0.9718321 -0.2356739 -0.4310732 0 0 0 1 1 -3.32914e-7 -3.19487e-7 -7.45058e-9 -3.84733e-7 -0.2193576 -0.9756446 2.98023e-8 2.54724e-7 0.9756446 -0.2193575 -0.4310733 0 0 0 1 1 -3.28425e-7 -3.2531e-7 7.45058e-9 -3.84702e-7 -0.2010675 -0.9795773 -2.23517e-8 2.56309e-7 0.9795774 -0.2010675 -0.4310732 0 0 0 1 1 -3.23341e-7 -3.3164e-7 -7.45058e-9 -3.8463e-7 -0.1807818 -0.9835232 4.47035e-8 2.58059e-7 0.9835234 -0.1807816 -0.4310732 0 0 0 1 1 -3.17717e-7 -3.38338e-7 -7.45058e-9 -3.84509e-7 -0.1588394 -0.9873044 2.98023e-8 2.59942e-7 0.9873044 -0.1588393 -0.4310733 0 0 0 1 1 -3.11643e-7 -3.45243e-7 7.45058e-9 -3.84334e-7 -0.1356803 -0.9907528 -4.00469e-8 2.61919e-7 0.9907528 -0.1356803 -0.4310732 0 0 0 1 1 -3.05221e-7 -3.522e-7 0 -3.84104e-7 -0.1117559 -0.9937357 -1.86265e-9 2.63949e-7 0.9937357 -0.1117558 -0.4310732 0 0 0 1 1 -2.98567e-7 -3.59067e-7 7.45058e-9 -3.83821e-7 -0.08752683 -0.9961623 -5.58794e-8 2.65993e-7 0.9961623 -0.08752674 -0.4310732 0 0 0 1 1 -2.91807e-7 -3.6571e-7 7.45058e-9 -3.8349e-7 -0.06345913 -0.9979844 -7.45058e-9 2.68012e-7 0.9979845 -0.06345904 -0.4310732 0 0 0 1 1 -2.85082e-7 -3.7201e-7 7.45058e-9 -3.83121e-7 -0.04002023 -0.999199 4.47035e-8 2.69966e-7 0.999199 -0.0400202 -0.4310733 0 0 0 1 1 -2.78541e-7 -3.77862e-7 1.49012e-8 -3.82726e-7 -0.01767585 -0.9998438 7.45058e-9 2.71819e-7 0.9998438 -0.0176757 -0.4310733 0 0 0 1 1 -2.72342e-7 -3.83171e-7 0 -3.82321e-7 0.003114864 -0.9999952 7.45058e-9 2.73534e-7 0.9999952 0.003114983 -0.4310733 0 0 0 1 1 -2.66646e-7 -3.87856e-7 0 -3.81924e-7 0.02189974 -0.9997602 -2.98023e-8 2.75076e-7 0.9997602 0.02189988 -0.4310733 0 0 0 1 1 -2.6162e-7 -3.91844e-7 0 -3.81555e-7 0.03823569 -0.9992688 -7.45058e-9 2.76411e-7 0.9992688 0.03823574 -0.4310732 0 0 0 1 1 -2.5743e-7 -3.95068e-7 0 -3.81234e-7 0.05168781 -0.9986634 2.98023e-8 2.77506e-7 0.9986634 0.05168788 -0.4310733 0 0 0 1 1 -2.54242e-7 -3.97461e-7 7.45058e-9 -3.80982e-7 0.06182647 -0.998087 -7.45058e-9 2.78329e-7 0.998087 0.06182654 -0.4310732 0 0 0 1 1 -2.52216e-7 -3.98955e-7 0 -3.80818e-7 0.068225 -0.9976699 7.45058e-9 2.78848e-7 0.99767 0.06822507 -0.4310732 0 0 0 1 + + + + + + + + LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR + + + + + + + + + + + + + + + + + + + 1 0 0 0 0 -4.37114e-8 -1 0 0 1 -4.37114e-8 0 0 0 0 1 + + 1 0 0 0 0 0 -1 0.04088391 0 1 0 -0.02018755 0 0 0 1 + + 1 0 0 0 0 0.9934375 -0.1143761 0 0 0.1143761 0.9934375 -0.194438 0 0 0 1 + + 1 0 0 0 -2.22827e-16 0.9258054 0.3780007 -3.72529e-9 0 -0.3780007 0.9258053 -0.3676334 0 0 0 1 + + 1 0 0 0 0 0.9957995 -0.09156074 -9.77889e-9 0 0.09156077 0.9957995 -0.07797433 0 0 0 1 + + + 1 + 0 + 0 + 0.1802077 + -0.03303807 + + + + + + 1 + 0 + + + + + -0.09349707 -0.05538832 -0.9940777 0.1656292 0.1139737 0.9912922 -0.0659528 0.02458553 0.9890745 -0.1194651 -0.08636999 -0.3007234 0 0 0 1 + + 0.9999269 1.47073e-4 0.0121001 2.98023e-8 -7.26653e-4 0.9988516 0.0479084 -5.58794e-9 -0.01207914 -0.04791368 0.9987785 -0.3238729 0 0 0 1 + + 0.9996847 8.13621e-4 -0.02510269 -8.56817e-8 0.001165986 0.9968942 0.07874503 0 0.02508879 -0.07874946 0.9965788 -0.2581572 0 0 0 1 + + 0.9943069 0.005958037 0.1063873 1.49012e-8 0.003777199 0.995837 -0.09107221 -1.49012e-8 -0.1064871 0.09095558 0.9901453 -0.1130893 0 0 0 1 + + 0.9999999 5.80214e-7 -5.68249e-5 -1.97906e-8 5.79515e-7 0.9997917 0.02040377 0 5.68249e-5 -0.02040377 0.9997917 -0.04929709 0 0 0 1 + + 0.9999999 4.80562e-6 1.63528e-4 6.49015e-9 4.80539e-6 0.9982743 -0.05872198 0 -1.63528e-4 0.05872198 0.9982743 -0.03822243 0 0 0 1 + + + 1 + 1.573581 + 0.03419893 + 0 + 0.002011656 + + + + + + 1 + 1.573581 + + + + + + 1 + 1.573581 + + + + + 0.9942042 0.01518451 0.106431 0.007374659 -0.007752027 0.9975237 -0.06990261 -0.02407584 -0.1072289 0.0686724 0.99186 -0.114673 0 0 0 1 + + 0.9997627 -3.39467e-6 -0.02178483 -2.43017e-8 -1.00378e-4 0.9999886 -0.00476245 -1.86265e-9 0.0217846 0.004763506 0.9997514 -0.04910958 0 0 0 1 + + 0.9997481 9.11376e-4 0.02242242 3.35276e-8 8.86247e-6 0.9991589 -0.04100683 0 -0.02244093 0.0409967 0.9989072 -0.03219759 0 0 0 1 + + + 1 + 1.585134 + 0.03364485 + 0 + 0.001513421 + + + + + + 1 + 1.607066 + + + + + + 1.585134 + + + + + 0.9942042 0.0151845 0.106431 0.01757193 -0.007752028 0.9975237 -0.06990255 -0.0453514 -0.1072289 0.06867235 0.9918599 -0.1194025 0 0 0 1 + + 1 2.20258e-6 2.51458e-4 -7.61065e-9 2.20817e-6 0.9998462 -0.01753639 0 -2.51458e-4 0.01753639 0.9998461 -0.02511728 0 0 0 1 + + + 1 + 1.585134 + 0.02438956 + 0 + 4.07464e-4 + + + + + + 1.585134 + + + + + 0.9942043 0.01516978 0.1064312 -9.2914e-4 -0.007752162 0.9975333 -0.06976461 0.02650937 -0.107227 0.06853521 0.9918696 -0.1201515 0 0 0 1 + + 0.9999996 2.56589e-5 8.57367e-4 5.82077e-10 2.56533e-5 0.9982107 -0.05979438 -7.45058e-9 -8.57368e-4 0.05979437 0.9982103 -0.04212457 0 0 0 1 + + 0.9999995 3.08976e-5 -9.40783e-4 9.77889e-9 3.08966e-5 0.9978453 0.06561208 -7.45058e-9 9.40783e-4 -0.06561208 0.9978448 -0.0316624 0 0 0 1 + + + 1 + 1.585134 + 0.03422701 + 0 + -2.32823e-4 + + + + + + 1 + 1.585134 + + + + + + 1.585134 + + + + + 0.9942043 0.01516974 0.1064312 -0.001006626 -0.007752167 0.9975334 -0.06976414 0.05007137 -0.107227 0.06853475 0.9918696 -0.1194239 0 0 0 1 + + 0.9999996 2.56523e-5 8.57354e-4 2.04891e-8 2.56589e-5 0.9982107 -0.05979469 0 -8.57354e-4 0.05979469 0.9982103 -0.02885437 0 0 0 1 + + 0.9999996 3.08966e-5 -9.40776e-4 2.64845e-8 3.08957e-5 0.9978453 0.06561161 0 9.40776e-4 -0.0656116 0.9978449 -0.02168822 0 0 0 1 + + + 1 + 1.585134 + 0.02344489 + 0 + -1.59472e-4 + + + + + + 1 + 1.585134 + + + + + + 1.585134 + + + + + + 1 + 1.676481 + + + + + + 1 + 1.652283 + + + + + + 1.664325 + + + + + -0.09349707 0.05538832 0.9940777 -0.1656292 -0.1139737 0.9912922 -0.0659528 0.02458553 -0.9890745 -0.1194651 -0.08636999 -0.3007234 0 0 0 1 + + 0.9999269 -1.47073e-4 -0.0121001 -2.98023e-8 7.26653e-4 0.9988516 0.0479084 -5.58794e-9 0.01207914 -0.04791368 0.9987785 -0.3238729 0 0 0 1 + + 0.9996847 -8.13621e-4 0.02510269 8.56817e-8 -0.001165986 0.9968942 0.07874503 0 -0.02508879 -0.07874946 0.9965788 -0.2581572 0 0 0 1 + + 0.9943069 -0.005958037 -0.1063873 -1.49012e-8 -0.003777199 0.995837 -0.09107221 -1.49012e-8 0.1064871 0.09095558 0.9901453 -0.1130893 0 0 0 1 + + 0.9999999 -5.80214e-7 5.68249e-5 1.97906e-8 -5.79515e-7 0.9997917 0.02040377 0 -5.68249e-5 -0.02040377 0.9997917 -0.04929709 0 0 0 1 + + 0.9999999 -4.80562e-6 -1.63528e-4 -6.49015e-9 -4.80539e-6 0.9982743 -0.05872198 0 1.63528e-4 0.05872198 0.9982743 -0.03822243 0 0 0 1 + + + 1 + -1.573581 + -0.03419893 + 0 + 0.002011656 + + + + + + 1 + -1.573581 + + + + + + 1 + -1.573581 + + + + + 0.9942042 -0.01518451 -0.106431 -0.007374659 0.007752027 0.9975237 -0.06990261 -0.02407584 0.1072289 0.0686724 0.99186 -0.114673 0 0 0 1 + + 0.9997627 3.39467e-6 0.02178483 2.43017e-8 1.00378e-4 0.9999886 -0.00476245 -1.86265e-9 -0.0217846 0.004763506 0.9997514 -0.04910958 0 0 0 1 + + 0.9997481 -9.11376e-4 -0.02242242 -3.35276e-8 -8.86247e-6 0.9991589 -0.04100683 0 0.02244093 0.0409967 0.9989072 -0.03219759 0 0 0 1 + + + 1 + -1.585134 + -0.03364485 + 0 + 0.001513421 + + + + + + 1 + -1.607066 + + + + + + -1.585134 + + + + + 0.9942042 -0.0151845 -0.106431 -0.01757193 0.007752028 0.9975237 -0.06990255 -0.0453514 0.1072289 0.06867235 0.9918599 -0.1194025 0 0 0 1 + + 1 -2.20258e-6 -2.51458e-4 7.61065e-9 -2.20817e-6 0.9998462 -0.01753639 0 2.51458e-4 0.01753639 0.9998461 -0.02511728 0 0 0 1 + + + 1 + -1.585134 + -0.02438956 + 0 + 4.07464e-4 + + + + + + -1.585134 + + + + + 0.9942043 -0.01516978 -0.1064312 9.2914e-4 0.007752162 0.9975333 -0.06976461 0.02650937 0.107227 0.06853521 0.9918696 -0.1201515 0 0 0 1 + + 0.9999996 -2.56589e-5 -8.57367e-4 -5.82077e-10 -2.56533e-5 0.9982107 -0.05979438 -7.45058e-9 8.57368e-4 0.05979437 0.9982103 -0.04212457 0 0 0 1 + + 0.9999995 -3.08976e-5 9.40783e-4 -9.77889e-9 -3.08966e-5 0.9978453 0.06561208 -7.45058e-9 -9.40783e-4 -0.06561208 0.9978448 -0.0316624 0 0 0 1 + + + 1 + -1.585134 + -0.03422701 + 0 + -2.32823e-4 + + + + + + 1 + -1.585134 + + + + + + -1.585134 + + + + + 0.9942043 -0.01516974 -0.1064312 0.001006626 0.007752167 0.9975334 -0.06976414 0.05007137 0.107227 0.06853475 0.9918696 -0.1194239 0 0 0 1 + + 0.9999996 -2.56523e-5 -8.57354e-4 -2.04891e-8 -2.56589e-5 0.9982107 -0.05979469 0 8.57354e-4 0.05979469 0.9982103 -0.02885437 0 0 0 1 + + 0.9999996 -3.08966e-5 9.40776e-4 -2.64845e-8 -3.08957e-5 0.9978453 0.06561161 0 -9.40776e-4 -0.0656116 0.9978449 -0.02168822 0 0 0 1 + + + 1 + -1.585134 + -0.02344489 + 0 + -1.59472e-4 + + + + + + 1 + -1.585134 + + + + + + -1.585134 + + + + + + 1 + -1.676481 + + + + + + 1 + -1.652283 + + + + + + -1.664325 + + + + + + 1 + 0 + + + + + 1 -1.50996e-7 4.79176e-14 0.08954165 -1.50996e-7 -1 6.34688e-7 0.02421998 -4.79176e-14 -6.34688e-7 -1 0.03911464 0 0 0 1 + + 1 3.25765e-7 6.31234e-9 0 -3.25744e-7 0.9991258 0.04180507 0 7.31181e-9 -0.04180507 0.9991258 -0.375647 0 0 0 1 + + 1 1.59203e-7 1.64965e-7 -7.45058e-9 1.02698e-7 0.332252 -0.9431908 0 -2.04969e-7 0.9431908 0.332252 -0.4310732 0 0 0 1 + + + 1 + 2.17315e-7 + 0 + -0.07929152 + -0.1982285 + + + + + + 1 + 1.74901e-7 + + + + + + -1.50996e-7 + + + + + 1 -1.50996e-7 4.79176e-14 -0.08954165 -1.50996e-7 -1 6.34688e-7 0.02421998 -4.79176e-14 -6.34688e-7 -1 0.03911464 0 0 0 1 + + 1 -1.51072e-7 6.31234e-9 0 1.50676e-7 0.9991258 0.04180507 0 -1.26224e-8 -0.04180507 0.9991258 -0.375647 0 0 0 1 + + 1 -1.59203e-7 -2.84783e-7 0 -2.15709e-7 0.332252 -0.9431908 1.86265e-9 2.44779e-7 0.9431908 0.332252 -0.4310732 0 0 0 1 + + + 1 + -2.59522e-7 + 0 + -0.07929152 + -0.1982285 + + + + + + 1 + -3.01936e-7 + + + + + + -1.50996e-7 + + + + + + + Bones + Bones + Bones + + + + + + + + + \ No newline at end of file diff --git a/assets/walkanim.fbx b/assets/walkanim.fbx new file mode 100644 index 0000000..0480c0e Binary files /dev/null and b/assets/walkanim.fbx differ diff --git a/assets/walkanim.glb b/assets/walkanim.glb new file mode 100644 index 0000000..351321d Binary files /dev/null and b/assets/walkanim.glb differ diff --git a/assimp-vc143-mt.dll b/assimp-vc143-mt.dll new file mode 100644 index 0000000..9c52b43 Binary files /dev/null and b/assimp-vc143-mt.dll differ diff --git a/common.h b/common.h new file mode 100644 index 0000000..b55a55f --- /dev/null +++ b/common.h @@ -0,0 +1,21 @@ +#ifndef COMMON_H +#define COMMON_H + +#include +#include + +class Engine; +class Window; +class Mouse; +class Keyboard; +class SoundSystem; +class ResourceManager; + +inline Window* window; +inline Engine* engine; +inline Keyboard* keyboard; +inline Mouse* mouse; +inline SoundSystem* soundsystem; +inline ResourceManager* resourcemanager; + +#endif // ! COMMON_H \ No newline at end of file diff --git a/dependencies/includes/GLFW/glfw3.h b/dependencies/includes/GLFW/glfw3.h new file mode 100644 index 0000000..9c55ac9 --- /dev/null +++ b/dependencies/includes/GLFW/glfw3.h @@ -0,0 +1,6547 @@ +/************************************************************************* + * GLFW 3.4 - www.glfw.org + * A library for OpenGL, window and input + *------------------------------------------------------------------------ + * Copyright (c) 2002-2006 Marcus Geelnard + * Copyright (c) 2006-2019 Camilla Löwy + * + * This software is provided 'as-is', without any express or implied + * warranty. In no event will the authors be held liable for any damages + * arising from the use of this software. + * + * Permission is granted to anyone to use this software for any purpose, + * including commercial applications, and to alter it and redistribute it + * freely, subject to the following restrictions: + * + * 1. The origin of this software must not be misrepresented; you must not + * claim that you wrote the original software. If you use this software + * in a product, an acknowledgment in the product documentation would + * be appreciated but is not required. + * + * 2. Altered source versions must be plainly marked as such, and must not + * be misrepresented as being the original software. + * + * 3. This notice may not be removed or altered from any source + * distribution. + * + *************************************************************************/ + +#ifndef _glfw3_h_ +#define _glfw3_h_ + +#ifdef __cplusplus +extern "C" { +#endif + + +/************************************************************************* + * Doxygen documentation + *************************************************************************/ + +/*! @file glfw3.h + * @brief The header of the GLFW 3 API. + * + * This is the header file of the GLFW 3 API. It defines all its types and + * declares all its functions. + * + * For more information about how to use this file, see @ref build_include. + */ +/*! @defgroup context Context reference + * @brief Functions and types related to OpenGL and OpenGL ES contexts. + * + * This is the reference documentation for OpenGL and OpenGL ES context related + * functions. For more task-oriented information, see the @ref context_guide. + */ +/*! @defgroup vulkan Vulkan support reference + * @brief Functions and types related to Vulkan. + * + * This is the reference documentation for Vulkan related functions and types. + * For more task-oriented information, see the @ref vulkan_guide. + */ +/*! @defgroup init Initialization, version and error reference + * @brief Functions and types related to initialization and error handling. + * + * This is the reference documentation for initialization and termination of + * the library, version management and error handling. For more task-oriented + * information, see the @ref intro_guide. + */ +/*! @defgroup input Input reference + * @brief Functions and types related to input handling. + * + * This is the reference documentation for input related functions and types. + * For more task-oriented information, see the @ref input_guide. + */ +/*! @defgroup monitor Monitor reference + * @brief Functions and types related to monitors. + * + * This is the reference documentation for monitor related functions and types. + * For more task-oriented information, see the @ref monitor_guide. + */ +/*! @defgroup window Window reference + * @brief Functions and types related to windows. + * + * This is the reference documentation for window related functions and types, + * including creation, deletion and event polling. For more task-oriented + * information, see the @ref window_guide. + */ + + +/************************************************************************* + * Compiler- and platform-specific preprocessor work + *************************************************************************/ + +/* If we are we on Windows, we want a single define for it. + */ +#if !defined(_WIN32) && (defined(__WIN32__) || defined(WIN32) || defined(__MINGW32__)) + #define _WIN32 +#endif /* _WIN32 */ + +/* Include because most Windows GLU headers need wchar_t and + * the macOS OpenGL header blocks the definition of ptrdiff_t by glext.h. + * Include it unconditionally to avoid surprising side-effects. + */ +#include + +/* Include because it is needed by Vulkan and related functions. + * Include it unconditionally to avoid surprising side-effects. + */ +#include + +#if defined(GLFW_INCLUDE_VULKAN) + #include +#endif /* Vulkan header */ + +/* The Vulkan header may have indirectly included windows.h (because of + * VK_USE_PLATFORM_WIN32_KHR) so we offer our replacement symbols after it. + */ + +/* It is customary to use APIENTRY for OpenGL function pointer declarations on + * all platforms. Additionally, the Windows OpenGL header needs APIENTRY. + */ +#if !defined(APIENTRY) + #if defined(_WIN32) + #define APIENTRY __stdcall + #else + #define APIENTRY + #endif + #define GLFW_APIENTRY_DEFINED +#endif /* APIENTRY */ + +/* Some Windows OpenGL headers need this. + */ +#if !defined(WINGDIAPI) && defined(_WIN32) + #define WINGDIAPI __declspec(dllimport) + #define GLFW_WINGDIAPI_DEFINED +#endif /* WINGDIAPI */ + +/* Some Windows GLU headers need this. + */ +#if !defined(CALLBACK) && defined(_WIN32) + #define CALLBACK __stdcall + #define GLFW_CALLBACK_DEFINED +#endif /* CALLBACK */ + +/* Include the chosen OpenGL or OpenGL ES headers. + */ +#if defined(GLFW_INCLUDE_ES1) + + #include + #if defined(GLFW_INCLUDE_GLEXT) + #include + #endif + +#elif defined(GLFW_INCLUDE_ES2) + + #include + #if defined(GLFW_INCLUDE_GLEXT) + #include + #endif + +#elif defined(GLFW_INCLUDE_ES3) + + #include + #if defined(GLFW_INCLUDE_GLEXT) + #include + #endif + +#elif defined(GLFW_INCLUDE_ES31) + + #include + #if defined(GLFW_INCLUDE_GLEXT) + #include + #endif + +#elif defined(GLFW_INCLUDE_ES32) + + #include + #if defined(GLFW_INCLUDE_GLEXT) + #include + #endif + +#elif defined(GLFW_INCLUDE_GLCOREARB) + + #if defined(__APPLE__) + + #include + #if defined(GLFW_INCLUDE_GLEXT) + #include + #endif /*GLFW_INCLUDE_GLEXT*/ + + #else /*__APPLE__*/ + + #include + #if defined(GLFW_INCLUDE_GLEXT) + #include + #endif + + #endif /*__APPLE__*/ + +#elif defined(GLFW_INCLUDE_GLU) + + #if defined(__APPLE__) + + #if defined(GLFW_INCLUDE_GLU) + #include + #endif + + #else /*__APPLE__*/ + + #if defined(GLFW_INCLUDE_GLU) + #include + #endif + + #endif /*__APPLE__*/ + +#elif !defined(GLFW_INCLUDE_NONE) && \ + !defined(__gl_h_) && \ + !defined(__gles1_gl_h_) && \ + !defined(__gles2_gl2_h_) && \ + !defined(__gles2_gl3_h_) && \ + !defined(__gles2_gl31_h_) && \ + !defined(__gles2_gl32_h_) && \ + !defined(__gl_glcorearb_h_) && \ + !defined(__gl2_h_) /*legacy*/ && \ + !defined(__gl3_h_) /*legacy*/ && \ + !defined(__gl31_h_) /*legacy*/ && \ + !defined(__gl32_h_) /*legacy*/ && \ + !defined(__glcorearb_h_) /*legacy*/ && \ + !defined(__GL_H__) /*non-standard*/ && \ + !defined(__gltypes_h_) /*non-standard*/ && \ + !defined(__glee_h_) /*non-standard*/ + + #if defined(__APPLE__) + + #if !defined(GLFW_INCLUDE_GLEXT) + #define GL_GLEXT_LEGACY + #endif + #include + + #else /*__APPLE__*/ + + #include + #if defined(GLFW_INCLUDE_GLEXT) + #include + #endif + + #endif /*__APPLE__*/ + +#endif /* OpenGL and OpenGL ES headers */ + +#if defined(GLFW_DLL) && defined(_GLFW_BUILD_DLL) + /* GLFW_DLL must be defined by applications that are linking against the DLL + * version of the GLFW library. _GLFW_BUILD_DLL is defined by the GLFW + * configuration header when compiling the DLL version of the library. + */ + #error "You must not have both GLFW_DLL and _GLFW_BUILD_DLL defined" +#endif + +/* GLFWAPI is used to declare public API functions for export + * from the DLL / shared library / dynamic library. + */ +#if defined(_WIN32) && defined(_GLFW_BUILD_DLL) + /* We are building GLFW as a Win32 DLL */ + #define GLFWAPI __declspec(dllexport) +#elif defined(_WIN32) && defined(GLFW_DLL) + /* We are calling a GLFW Win32 DLL */ + #define GLFWAPI __declspec(dllimport) +#elif defined(__GNUC__) && defined(_GLFW_BUILD_DLL) + /* We are building GLFW as a Unix shared library */ + #define GLFWAPI __attribute__((visibility("default"))) +#else + #define GLFWAPI +#endif + + +/************************************************************************* + * GLFW API tokens + *************************************************************************/ + +/*! @name GLFW version macros + * @{ */ +/*! @brief The major version number of the GLFW header. + * + * The major version number of the GLFW header. This is incremented when the + * API is changed in non-compatible ways. + * @ingroup init + */ +#define GLFW_VERSION_MAJOR 3 +/*! @brief The minor version number of the GLFW header. + * + * The minor version number of the GLFW header. This is incremented when + * features are added to the API but it remains backward-compatible. + * @ingroup init + */ +#define GLFW_VERSION_MINOR 4 +/*! @brief The revision number of the GLFW header. + * + * The revision number of the GLFW header. This is incremented when a bug fix + * release is made that does not contain any API changes. + * @ingroup init + */ +#define GLFW_VERSION_REVISION 0 +/*! @} */ + +/*! @brief One. + * + * This is only semantic sugar for the number 1. You can instead use `1` or + * `true` or `_True` or `GL_TRUE` or `VK_TRUE` or anything else that is equal + * to one. + * + * @ingroup init + */ +#define GLFW_TRUE 1 +/*! @brief Zero. + * + * This is only semantic sugar for the number 0. You can instead use `0` or + * `false` or `_False` or `GL_FALSE` or `VK_FALSE` or anything else that is + * equal to zero. + * + * @ingroup init + */ +#define GLFW_FALSE 0 + +/*! @name Key and button actions + * @{ */ +/*! @brief The key or mouse button was released. + * + * The key or mouse button was released. + * + * @ingroup input + */ +#define GLFW_RELEASE 0 +/*! @brief The key or mouse button was pressed. + * + * The key or mouse button was pressed. + * + * @ingroup input + */ +#define GLFW_PRESS 1 +/*! @brief The key was held down until it repeated. + * + * The key was held down until it repeated. + * + * @ingroup input + */ +#define GLFW_REPEAT 2 +/*! @} */ + +/*! @defgroup hat_state Joystick hat states + * @brief Joystick hat states. + * + * See [joystick hat input](@ref joystick_hat) for how these are used. + * + * @ingroup input + * @{ */ +#define GLFW_HAT_CENTERED 0 +#define GLFW_HAT_UP 1 +#define GLFW_HAT_RIGHT 2 +#define GLFW_HAT_DOWN 4 +#define GLFW_HAT_LEFT 8 +#define GLFW_HAT_RIGHT_UP (GLFW_HAT_RIGHT | GLFW_HAT_UP) +#define GLFW_HAT_RIGHT_DOWN (GLFW_HAT_RIGHT | GLFW_HAT_DOWN) +#define GLFW_HAT_LEFT_UP (GLFW_HAT_LEFT | GLFW_HAT_UP) +#define GLFW_HAT_LEFT_DOWN (GLFW_HAT_LEFT | GLFW_HAT_DOWN) + +/*! @ingroup input + */ +#define GLFW_KEY_UNKNOWN -1 + +/*! @} */ + +/*! @defgroup keys Keyboard key tokens + * @brief Keyboard key tokens. + * + * See [key input](@ref input_key) for how these are used. + * + * These key codes are inspired by the _USB HID Usage Tables v1.12_ (p. 53-60), + * but re-arranged to map to 7-bit ASCII for printable keys (function keys are + * put in the 256+ range). + * + * The naming of the key codes follow these rules: + * - The US keyboard layout is used + * - Names of printable alphanumeric characters are used (e.g. "A", "R", + * "3", etc.) + * - For non-alphanumeric characters, Unicode:ish names are used (e.g. + * "COMMA", "LEFT_SQUARE_BRACKET", etc.). Note that some names do not + * correspond to the Unicode standard (usually for brevity) + * - Keys that lack a clear US mapping are named "WORLD_x" + * - For non-printable keys, custom names are used (e.g. "F4", + * "BACKSPACE", etc.) + * + * @ingroup input + * @{ + */ + +/* Printable keys */ +#define GLFW_KEY_SPACE 32 +#define GLFW_KEY_APOSTROPHE 39 /* ' */ +#define GLFW_KEY_COMMA 44 /* , */ +#define GLFW_KEY_MINUS 45 /* - */ +#define GLFW_KEY_PERIOD 46 /* . */ +#define GLFW_KEY_SLASH 47 /* / */ +#define GLFW_KEY_0 48 +#define GLFW_KEY_1 49 +#define GLFW_KEY_2 50 +#define GLFW_KEY_3 51 +#define GLFW_KEY_4 52 +#define GLFW_KEY_5 53 +#define GLFW_KEY_6 54 +#define GLFW_KEY_7 55 +#define GLFW_KEY_8 56 +#define GLFW_KEY_9 57 +#define GLFW_KEY_SEMICOLON 59 /* ; */ +#define GLFW_KEY_EQUAL 61 /* = */ +#define GLFW_KEY_A 65 +#define GLFW_KEY_B 66 +#define GLFW_KEY_C 67 +#define GLFW_KEY_D 68 +#define GLFW_KEY_E 69 +#define GLFW_KEY_F 70 +#define GLFW_KEY_G 71 +#define GLFW_KEY_H 72 +#define GLFW_KEY_I 73 +#define GLFW_KEY_J 74 +#define GLFW_KEY_K 75 +#define GLFW_KEY_L 76 +#define GLFW_KEY_M 77 +#define GLFW_KEY_N 78 +#define GLFW_KEY_O 79 +#define GLFW_KEY_P 80 +#define GLFW_KEY_Q 81 +#define GLFW_KEY_R 82 +#define GLFW_KEY_S 83 +#define GLFW_KEY_T 84 +#define GLFW_KEY_U 85 +#define GLFW_KEY_V 86 +#define GLFW_KEY_W 87 +#define GLFW_KEY_X 88 +#define GLFW_KEY_Y 89 +#define GLFW_KEY_Z 90 +#define GLFW_KEY_LEFT_BRACKET 91 /* [ */ +#define GLFW_KEY_BACKSLASH 92 /* \ */ +#define GLFW_KEY_RIGHT_BRACKET 93 /* ] */ +#define GLFW_KEY_GRAVE_ACCENT 96 /* ` */ +#define GLFW_KEY_WORLD_1 161 /* non-US #1 */ +#define GLFW_KEY_WORLD_2 162 /* non-US #2 */ + +/* Function keys */ +#define GLFW_KEY_ESCAPE 256 +#define GLFW_KEY_ENTER 257 +#define GLFW_KEY_TAB 258 +#define GLFW_KEY_BACKSPACE 259 +#define GLFW_KEY_INSERT 260 +#define GLFW_KEY_DELETE 261 +#define GLFW_KEY_RIGHT 262 +#define GLFW_KEY_LEFT 263 +#define GLFW_KEY_DOWN 264 +#define GLFW_KEY_UP 265 +#define GLFW_KEY_PAGE_UP 266 +#define GLFW_KEY_PAGE_DOWN 267 +#define GLFW_KEY_HOME 268 +#define GLFW_KEY_END 269 +#define GLFW_KEY_CAPS_LOCK 280 +#define GLFW_KEY_SCROLL_LOCK 281 +#define GLFW_KEY_NUM_LOCK 282 +#define GLFW_KEY_PRINT_SCREEN 283 +#define GLFW_KEY_PAUSE 284 +#define GLFW_KEY_F1 290 +#define GLFW_KEY_F2 291 +#define GLFW_KEY_F3 292 +#define GLFW_KEY_F4 293 +#define GLFW_KEY_F5 294 +#define GLFW_KEY_F6 295 +#define GLFW_KEY_F7 296 +#define GLFW_KEY_F8 297 +#define GLFW_KEY_F9 298 +#define GLFW_KEY_F10 299 +#define GLFW_KEY_F11 300 +#define GLFW_KEY_F12 301 +#define GLFW_KEY_F13 302 +#define GLFW_KEY_F14 303 +#define GLFW_KEY_F15 304 +#define GLFW_KEY_F16 305 +#define GLFW_KEY_F17 306 +#define GLFW_KEY_F18 307 +#define GLFW_KEY_F19 308 +#define GLFW_KEY_F20 309 +#define GLFW_KEY_F21 310 +#define GLFW_KEY_F22 311 +#define GLFW_KEY_F23 312 +#define GLFW_KEY_F24 313 +#define GLFW_KEY_F25 314 +#define GLFW_KEY_KP_0 320 +#define GLFW_KEY_KP_1 321 +#define GLFW_KEY_KP_2 322 +#define GLFW_KEY_KP_3 323 +#define GLFW_KEY_KP_4 324 +#define GLFW_KEY_KP_5 325 +#define GLFW_KEY_KP_6 326 +#define GLFW_KEY_KP_7 327 +#define GLFW_KEY_KP_8 328 +#define GLFW_KEY_KP_9 329 +#define GLFW_KEY_KP_DECIMAL 330 +#define GLFW_KEY_KP_DIVIDE 331 +#define GLFW_KEY_KP_MULTIPLY 332 +#define GLFW_KEY_KP_SUBTRACT 333 +#define GLFW_KEY_KP_ADD 334 +#define GLFW_KEY_KP_ENTER 335 +#define GLFW_KEY_KP_EQUAL 336 +#define GLFW_KEY_LEFT_SHIFT 340 +#define GLFW_KEY_LEFT_CONTROL 341 +#define GLFW_KEY_LEFT_ALT 342 +#define GLFW_KEY_LEFT_SUPER 343 +#define GLFW_KEY_RIGHT_SHIFT 344 +#define GLFW_KEY_RIGHT_CONTROL 345 +#define GLFW_KEY_RIGHT_ALT 346 +#define GLFW_KEY_RIGHT_SUPER 347 +#define GLFW_KEY_MENU 348 + +#define GLFW_KEY_LAST GLFW_KEY_MENU + +/*! @} */ + +/*! @defgroup mods Modifier key flags + * @brief Modifier key flags. + * + * See [key input](@ref input_key) for how these are used. + * + * @ingroup input + * @{ */ + +/*! @brief If this bit is set one or more Shift keys were held down. + * + * If this bit is set one or more Shift keys were held down. + */ +#define GLFW_MOD_SHIFT 0x0001 +/*! @brief If this bit is set one or more Control keys were held down. + * + * If this bit is set one or more Control keys were held down. + */ +#define GLFW_MOD_CONTROL 0x0002 +/*! @brief If this bit is set one or more Alt keys were held down. + * + * If this bit is set one or more Alt keys were held down. + */ +#define GLFW_MOD_ALT 0x0004 +/*! @brief If this bit is set one or more Super keys were held down. + * + * If this bit is set one or more Super keys were held down. + */ +#define GLFW_MOD_SUPER 0x0008 +/*! @brief If this bit is set the Caps Lock key is enabled. + * + * If this bit is set the Caps Lock key is enabled and the @ref + * GLFW_LOCK_KEY_MODS input mode is set. + */ +#define GLFW_MOD_CAPS_LOCK 0x0010 +/*! @brief If this bit is set the Num Lock key is enabled. + * + * If this bit is set the Num Lock key is enabled and the @ref + * GLFW_LOCK_KEY_MODS input mode is set. + */ +#define GLFW_MOD_NUM_LOCK 0x0020 + +/*! @} */ + +/*! @defgroup buttons Mouse buttons + * @brief Mouse button IDs. + * + * See [mouse button input](@ref input_mouse_button) for how these are used. + * + * @ingroup input + * @{ */ +#define GLFW_MOUSE_BUTTON_1 0 +#define GLFW_MOUSE_BUTTON_2 1 +#define GLFW_MOUSE_BUTTON_3 2 +#define GLFW_MOUSE_BUTTON_4 3 +#define GLFW_MOUSE_BUTTON_5 4 +#define GLFW_MOUSE_BUTTON_6 5 +#define GLFW_MOUSE_BUTTON_7 6 +#define GLFW_MOUSE_BUTTON_8 7 +#define GLFW_MOUSE_BUTTON_LAST GLFW_MOUSE_BUTTON_8 +#define GLFW_MOUSE_BUTTON_LEFT GLFW_MOUSE_BUTTON_1 +#define GLFW_MOUSE_BUTTON_RIGHT GLFW_MOUSE_BUTTON_2 +#define GLFW_MOUSE_BUTTON_MIDDLE GLFW_MOUSE_BUTTON_3 +/*! @} */ + +/*! @defgroup joysticks Joysticks + * @brief Joystick IDs. + * + * See [joystick input](@ref joystick) for how these are used. + * + * @ingroup input + * @{ */ +#define GLFW_JOYSTICK_1 0 +#define GLFW_JOYSTICK_2 1 +#define GLFW_JOYSTICK_3 2 +#define GLFW_JOYSTICK_4 3 +#define GLFW_JOYSTICK_5 4 +#define GLFW_JOYSTICK_6 5 +#define GLFW_JOYSTICK_7 6 +#define GLFW_JOYSTICK_8 7 +#define GLFW_JOYSTICK_9 8 +#define GLFW_JOYSTICK_10 9 +#define GLFW_JOYSTICK_11 10 +#define GLFW_JOYSTICK_12 11 +#define GLFW_JOYSTICK_13 12 +#define GLFW_JOYSTICK_14 13 +#define GLFW_JOYSTICK_15 14 +#define GLFW_JOYSTICK_16 15 +#define GLFW_JOYSTICK_LAST GLFW_JOYSTICK_16 +/*! @} */ + +/*! @defgroup gamepad_buttons Gamepad buttons + * @brief Gamepad buttons. + * + * See @ref gamepad for how these are used. + * + * @ingroup input + * @{ */ +#define GLFW_GAMEPAD_BUTTON_A 0 +#define GLFW_GAMEPAD_BUTTON_B 1 +#define GLFW_GAMEPAD_BUTTON_X 2 +#define GLFW_GAMEPAD_BUTTON_Y 3 +#define GLFW_GAMEPAD_BUTTON_LEFT_BUMPER 4 +#define GLFW_GAMEPAD_BUTTON_RIGHT_BUMPER 5 +#define GLFW_GAMEPAD_BUTTON_BACK 6 +#define GLFW_GAMEPAD_BUTTON_START 7 +#define GLFW_GAMEPAD_BUTTON_GUIDE 8 +#define GLFW_GAMEPAD_BUTTON_LEFT_THUMB 9 +#define GLFW_GAMEPAD_BUTTON_RIGHT_THUMB 10 +#define GLFW_GAMEPAD_BUTTON_DPAD_UP 11 +#define GLFW_GAMEPAD_BUTTON_DPAD_RIGHT 12 +#define GLFW_GAMEPAD_BUTTON_DPAD_DOWN 13 +#define GLFW_GAMEPAD_BUTTON_DPAD_LEFT 14 +#define GLFW_GAMEPAD_BUTTON_LAST GLFW_GAMEPAD_BUTTON_DPAD_LEFT + +#define GLFW_GAMEPAD_BUTTON_CROSS GLFW_GAMEPAD_BUTTON_A +#define GLFW_GAMEPAD_BUTTON_CIRCLE GLFW_GAMEPAD_BUTTON_B +#define GLFW_GAMEPAD_BUTTON_SQUARE GLFW_GAMEPAD_BUTTON_X +#define GLFW_GAMEPAD_BUTTON_TRIANGLE GLFW_GAMEPAD_BUTTON_Y +/*! @} */ + +/*! @defgroup gamepad_axes Gamepad axes + * @brief Gamepad axes. + * + * See @ref gamepad for how these are used. + * + * @ingroup input + * @{ */ +#define GLFW_GAMEPAD_AXIS_LEFT_X 0 +#define GLFW_GAMEPAD_AXIS_LEFT_Y 1 +#define GLFW_GAMEPAD_AXIS_RIGHT_X 2 +#define GLFW_GAMEPAD_AXIS_RIGHT_Y 3 +#define GLFW_GAMEPAD_AXIS_LEFT_TRIGGER 4 +#define GLFW_GAMEPAD_AXIS_RIGHT_TRIGGER 5 +#define GLFW_GAMEPAD_AXIS_LAST GLFW_GAMEPAD_AXIS_RIGHT_TRIGGER +/*! @} */ + +/*! @defgroup errors Error codes + * @brief Error codes. + * + * See [error handling](@ref error_handling) for how these are used. + * + * @ingroup init + * @{ */ +/*! @brief No error has occurred. + * + * No error has occurred. + * + * @analysis Yay. + */ +#define GLFW_NO_ERROR 0 +/*! @brief GLFW has not been initialized. + * + * This occurs if a GLFW function was called that must not be called unless the + * library is [initialized](@ref intro_init). + * + * @analysis Application programmer error. Initialize GLFW before calling any + * function that requires initialization. + */ +#define GLFW_NOT_INITIALIZED 0x00010001 +/*! @brief No context is current for this thread. + * + * This occurs if a GLFW function was called that needs and operates on the + * current OpenGL or OpenGL ES context but no context is current on the calling + * thread. One such function is @ref glfwSwapInterval. + * + * @analysis Application programmer error. Ensure a context is current before + * calling functions that require a current context. + */ +#define GLFW_NO_CURRENT_CONTEXT 0x00010002 +/*! @brief One of the arguments to the function was an invalid enum value. + * + * One of the arguments to the function was an invalid enum value, for example + * requesting @ref GLFW_RED_BITS with @ref glfwGetWindowAttrib. + * + * @analysis Application programmer error. Fix the offending call. + */ +#define GLFW_INVALID_ENUM 0x00010003 +/*! @brief One of the arguments to the function was an invalid value. + * + * One of the arguments to the function was an invalid value, for example + * requesting a non-existent OpenGL or OpenGL ES version like 2.7. + * + * Requesting a valid but unavailable OpenGL or OpenGL ES version will instead + * result in a @ref GLFW_VERSION_UNAVAILABLE error. + * + * @analysis Application programmer error. Fix the offending call. + */ +#define GLFW_INVALID_VALUE 0x00010004 +/*! @brief A memory allocation failed. + * + * A memory allocation failed. + * + * @analysis A bug in GLFW or the underlying operating system. Report the bug + * to our [issue tracker](https://github.com/glfw/glfw/issues). + */ +#define GLFW_OUT_OF_MEMORY 0x00010005 +/*! @brief GLFW could not find support for the requested API on the system. + * + * GLFW could not find support for the requested API on the system. + * + * @analysis The installed graphics driver does not support the requested + * API, or does not support it via the chosen context creation API. + * Below are a few examples. + * + * @par + * Some pre-installed Windows graphics drivers do not support OpenGL. AMD only + * supports OpenGL ES via EGL, while Nvidia and Intel only support it via + * a WGL or GLX extension. macOS does not provide OpenGL ES at all. The Mesa + * EGL, OpenGL and OpenGL ES libraries do not interface with the Nvidia binary + * driver. Older graphics drivers do not support Vulkan. + */ +#define GLFW_API_UNAVAILABLE 0x00010006 +/*! @brief The requested OpenGL or OpenGL ES version is not available. + * + * The requested OpenGL or OpenGL ES version (including any requested context + * or framebuffer hints) is not available on this machine. + * + * @analysis The machine does not support your requirements. If your + * application is sufficiently flexible, downgrade your requirements and try + * again. Otherwise, inform the user that their machine does not match your + * requirements. + * + * @par + * Future invalid OpenGL and OpenGL ES versions, for example OpenGL 4.8 if 5.0 + * comes out before the 4.x series gets that far, also fail with this error and + * not @ref GLFW_INVALID_VALUE, because GLFW cannot know what future versions + * will exist. + */ +#define GLFW_VERSION_UNAVAILABLE 0x00010007 +/*! @brief A platform-specific error occurred that does not match any of the + * more specific categories. + * + * A platform-specific error occurred that does not match any of the more + * specific categories. + * + * @analysis A bug or configuration error in GLFW, the underlying operating + * system or its drivers, or a lack of required resources. Report the issue to + * our [issue tracker](https://github.com/glfw/glfw/issues). + */ +#define GLFW_PLATFORM_ERROR 0x00010008 +/*! @brief The requested format is not supported or available. + * + * If emitted during window creation, the requested pixel format is not + * supported. + * + * If emitted when querying the clipboard, the contents of the clipboard could + * not be converted to the requested format. + * + * @analysis If emitted during window creation, one or more + * [hard constraints](@ref window_hints_hard) did not match any of the + * available pixel formats. If your application is sufficiently flexible, + * downgrade your requirements and try again. Otherwise, inform the user that + * their machine does not match your requirements. + * + * @par + * If emitted when querying the clipboard, ignore the error or report it to + * the user, as appropriate. + */ +#define GLFW_FORMAT_UNAVAILABLE 0x00010009 +/*! @brief The specified window does not have an OpenGL or OpenGL ES context. + * + * A window that does not have an OpenGL or OpenGL ES context was passed to + * a function that requires it to have one. + * + * @analysis Application programmer error. Fix the offending call. + */ +#define GLFW_NO_WINDOW_CONTEXT 0x0001000A +/*! @brief The specified cursor shape is not available. + * + * The specified standard cursor shape is not available, either because the + * current platform cursor theme does not provide it or because it is not + * available on the platform. + * + * @analysis Platform or system settings limitation. Pick another + * [standard cursor shape](@ref shapes) or create a + * [custom cursor](@ref cursor_custom). + */ +#define GLFW_CURSOR_UNAVAILABLE 0x0001000B +/*! @brief The requested feature is not provided by the platform. + * + * The requested feature is not provided by the platform, so GLFW is unable to + * implement it. The documentation for each function notes if it could emit + * this error. + * + * @analysis Platform or platform version limitation. The error can be ignored + * unless the feature is critical to the application. + * + * @par + * A function call that emits this error has no effect other than the error and + * updating any existing out parameters. + */ +#define GLFW_FEATURE_UNAVAILABLE 0x0001000C +/*! @brief The requested feature is not implemented for the platform. + * + * The requested feature has not yet been implemented in GLFW for this platform. + * + * @analysis An incomplete implementation of GLFW for this platform, hopefully + * fixed in a future release. The error can be ignored unless the feature is + * critical to the application. + * + * @par + * A function call that emits this error has no effect other than the error and + * updating any existing out parameters. + */ +#define GLFW_FEATURE_UNIMPLEMENTED 0x0001000D +/*! @brief Platform unavailable or no matching platform was found. + * + * If emitted during initialization, no matching platform was found. If the @ref + * GLFW_PLATFORM init hint was set to `GLFW_ANY_PLATFORM`, GLFW could not detect any of + * the platforms supported by this library binary, except for the Null platform. If the + * init hint was set to a specific platform, it is either not supported by this library + * binary or GLFW was not able to detect it. + * + * If emitted by a native access function, GLFW was initialized for a different platform + * than the function is for. + * + * @analysis Failure to detect any platform usually only happens on non-macOS Unix + * systems, either when no window system is running or the program was run from + * a terminal that does not have the necessary environment variables. Fall back to + * a different platform if possible or notify the user that no usable platform was + * detected. + * + * Failure to detect a specific platform may have the same cause as above or be because + * support for that platform was not compiled in. Call @ref glfwPlatformSupported to + * check whether a specific platform is supported by a library binary. + */ +#define GLFW_PLATFORM_UNAVAILABLE 0x0001000E +/*! @} */ + +/*! @addtogroup window + * @{ */ +/*! @brief Input focus window hint and attribute + * + * Input focus [window hint](@ref GLFW_FOCUSED_hint) or + * [window attribute](@ref GLFW_FOCUSED_attrib). + */ +#define GLFW_FOCUSED 0x00020001 +/*! @brief Window iconification window attribute + * + * Window iconification [window attribute](@ref GLFW_ICONIFIED_attrib). + */ +#define GLFW_ICONIFIED 0x00020002 +/*! @brief Window resize-ability window hint and attribute + * + * Window resize-ability [window hint](@ref GLFW_RESIZABLE_hint) and + * [window attribute](@ref GLFW_RESIZABLE_attrib). + */ +#define GLFW_RESIZABLE 0x00020003 +/*! @brief Window visibility window hint and attribute + * + * Window visibility [window hint](@ref GLFW_VISIBLE_hint) and + * [window attribute](@ref GLFW_VISIBLE_attrib). + */ +#define GLFW_VISIBLE 0x00020004 +/*! @brief Window decoration window hint and attribute + * + * Window decoration [window hint](@ref GLFW_DECORATED_hint) and + * [window attribute](@ref GLFW_DECORATED_attrib). + */ +#define GLFW_DECORATED 0x00020005 +/*! @brief Window auto-iconification window hint and attribute + * + * Window auto-iconification [window hint](@ref GLFW_AUTO_ICONIFY_hint) and + * [window attribute](@ref GLFW_AUTO_ICONIFY_attrib). + */ +#define GLFW_AUTO_ICONIFY 0x00020006 +/*! @brief Window decoration window hint and attribute + * + * Window decoration [window hint](@ref GLFW_FLOATING_hint) and + * [window attribute](@ref GLFW_FLOATING_attrib). + */ +#define GLFW_FLOATING 0x00020007 +/*! @brief Window maximization window hint and attribute + * + * Window maximization [window hint](@ref GLFW_MAXIMIZED_hint) and + * [window attribute](@ref GLFW_MAXIMIZED_attrib). + */ +#define GLFW_MAXIMIZED 0x00020008 +/*! @brief Cursor centering window hint + * + * Cursor centering [window hint](@ref GLFW_CENTER_CURSOR_hint). + */ +#define GLFW_CENTER_CURSOR 0x00020009 +/*! @brief Window framebuffer transparency hint and attribute + * + * Window framebuffer transparency + * [window hint](@ref GLFW_TRANSPARENT_FRAMEBUFFER_hint) and + * [window attribute](@ref GLFW_TRANSPARENT_FRAMEBUFFER_attrib). + */ +#define GLFW_TRANSPARENT_FRAMEBUFFER 0x0002000A +/*! @brief Mouse cursor hover window attribute. + * + * Mouse cursor hover [window attribute](@ref GLFW_HOVERED_attrib). + */ +#define GLFW_HOVERED 0x0002000B +/*! @brief Input focus on calling show window hint and attribute + * + * Input focus [window hint](@ref GLFW_FOCUS_ON_SHOW_hint) or + * [window attribute](@ref GLFW_FOCUS_ON_SHOW_attrib). + */ +#define GLFW_FOCUS_ON_SHOW 0x0002000C + +/*! @brief Mouse input transparency window hint and attribute + * + * Mouse input transparency [window hint](@ref GLFW_MOUSE_PASSTHROUGH_hint) or + * [window attribute](@ref GLFW_MOUSE_PASSTHROUGH_attrib). + */ +#define GLFW_MOUSE_PASSTHROUGH 0x0002000D + +/*! @brief Initial position x-coordinate window hint. + * + * Initial position x-coordinate [window hint](@ref GLFW_POSITION_X). + */ +#define GLFW_POSITION_X 0x0002000E + +/*! @brief Initial position y-coordinate window hint. + * + * Initial position y-coordinate [window hint](@ref GLFW_POSITION_Y). + */ +#define GLFW_POSITION_Y 0x0002000F + +/*! @brief Framebuffer bit depth hint. + * + * Framebuffer bit depth [hint](@ref GLFW_RED_BITS). + */ +#define GLFW_RED_BITS 0x00021001 +/*! @brief Framebuffer bit depth hint. + * + * Framebuffer bit depth [hint](@ref GLFW_GREEN_BITS). + */ +#define GLFW_GREEN_BITS 0x00021002 +/*! @brief Framebuffer bit depth hint. + * + * Framebuffer bit depth [hint](@ref GLFW_BLUE_BITS). + */ +#define GLFW_BLUE_BITS 0x00021003 +/*! @brief Framebuffer bit depth hint. + * + * Framebuffer bit depth [hint](@ref GLFW_ALPHA_BITS). + */ +#define GLFW_ALPHA_BITS 0x00021004 +/*! @brief Framebuffer bit depth hint. + * + * Framebuffer bit depth [hint](@ref GLFW_DEPTH_BITS). + */ +#define GLFW_DEPTH_BITS 0x00021005 +/*! @brief Framebuffer bit depth hint. + * + * Framebuffer bit depth [hint](@ref GLFW_STENCIL_BITS). + */ +#define GLFW_STENCIL_BITS 0x00021006 +/*! @brief Framebuffer bit depth hint. + * + * Framebuffer bit depth [hint](@ref GLFW_ACCUM_RED_BITS). + */ +#define GLFW_ACCUM_RED_BITS 0x00021007 +/*! @brief Framebuffer bit depth hint. + * + * Framebuffer bit depth [hint](@ref GLFW_ACCUM_GREEN_BITS). + */ +#define GLFW_ACCUM_GREEN_BITS 0x00021008 +/*! @brief Framebuffer bit depth hint. + * + * Framebuffer bit depth [hint](@ref GLFW_ACCUM_BLUE_BITS). + */ +#define GLFW_ACCUM_BLUE_BITS 0x00021009 +/*! @brief Framebuffer bit depth hint. + * + * Framebuffer bit depth [hint](@ref GLFW_ACCUM_ALPHA_BITS). + */ +#define GLFW_ACCUM_ALPHA_BITS 0x0002100A +/*! @brief Framebuffer auxiliary buffer hint. + * + * Framebuffer auxiliary buffer [hint](@ref GLFW_AUX_BUFFERS). + */ +#define GLFW_AUX_BUFFERS 0x0002100B +/*! @brief OpenGL stereoscopic rendering hint. + * + * OpenGL stereoscopic rendering [hint](@ref GLFW_STEREO). + */ +#define GLFW_STEREO 0x0002100C +/*! @brief Framebuffer MSAA samples hint. + * + * Framebuffer MSAA samples [hint](@ref GLFW_SAMPLES). + */ +#define GLFW_SAMPLES 0x0002100D +/*! @brief Framebuffer sRGB hint. + * + * Framebuffer sRGB [hint](@ref GLFW_SRGB_CAPABLE). + */ +#define GLFW_SRGB_CAPABLE 0x0002100E +/*! @brief Monitor refresh rate hint. + * + * Monitor refresh rate [hint](@ref GLFW_REFRESH_RATE). + */ +#define GLFW_REFRESH_RATE 0x0002100F +/*! @brief Framebuffer double buffering hint and attribute. + * + * Framebuffer double buffering [hint](@ref GLFW_DOUBLEBUFFER_hint) and + * [attribute](@ref GLFW_DOUBLEBUFFER_attrib). + */ +#define GLFW_DOUBLEBUFFER 0x00021010 + +/*! @brief Context client API hint and attribute. + * + * Context client API [hint](@ref GLFW_CLIENT_API_hint) and + * [attribute](@ref GLFW_CLIENT_API_attrib). + */ +#define GLFW_CLIENT_API 0x00022001 +/*! @brief Context client API major version hint and attribute. + * + * Context client API major version [hint](@ref GLFW_CONTEXT_VERSION_MAJOR_hint) + * and [attribute](@ref GLFW_CONTEXT_VERSION_MAJOR_attrib). + */ +#define GLFW_CONTEXT_VERSION_MAJOR 0x00022002 +/*! @brief Context client API minor version hint and attribute. + * + * Context client API minor version [hint](@ref GLFW_CONTEXT_VERSION_MINOR_hint) + * and [attribute](@ref GLFW_CONTEXT_VERSION_MINOR_attrib). + */ +#define GLFW_CONTEXT_VERSION_MINOR 0x00022003 +/*! @brief Context client API revision number attribute. + * + * Context client API revision number + * [attribute](@ref GLFW_CONTEXT_REVISION_attrib). + */ +#define GLFW_CONTEXT_REVISION 0x00022004 +/*! @brief Context robustness hint and attribute. + * + * Context client API revision number [hint](@ref GLFW_CONTEXT_ROBUSTNESS_hint) + * and [attribute](@ref GLFW_CONTEXT_ROBUSTNESS_attrib). + */ +#define GLFW_CONTEXT_ROBUSTNESS 0x00022005 +/*! @brief OpenGL forward-compatibility hint and attribute. + * + * OpenGL forward-compatibility [hint](@ref GLFW_OPENGL_FORWARD_COMPAT_hint) + * and [attribute](@ref GLFW_OPENGL_FORWARD_COMPAT_attrib). + */ +#define GLFW_OPENGL_FORWARD_COMPAT 0x00022006 +/*! @brief Debug mode context hint and attribute. + * + * Debug mode context [hint](@ref GLFW_CONTEXT_DEBUG_hint) and + * [attribute](@ref GLFW_CONTEXT_DEBUG_attrib). + */ +#define GLFW_CONTEXT_DEBUG 0x00022007 +/*! @brief Legacy name for compatibility. + * + * This is an alias for compatibility with earlier versions. + */ +#define GLFW_OPENGL_DEBUG_CONTEXT GLFW_CONTEXT_DEBUG +/*! @brief OpenGL profile hint and attribute. + * + * OpenGL profile [hint](@ref GLFW_OPENGL_PROFILE_hint) and + * [attribute](@ref GLFW_OPENGL_PROFILE_attrib). + */ +#define GLFW_OPENGL_PROFILE 0x00022008 +/*! @brief Context flush-on-release hint and attribute. + * + * Context flush-on-release [hint](@ref GLFW_CONTEXT_RELEASE_BEHAVIOR_hint) and + * [attribute](@ref GLFW_CONTEXT_RELEASE_BEHAVIOR_attrib). + */ +#define GLFW_CONTEXT_RELEASE_BEHAVIOR 0x00022009 +/*! @brief Context error suppression hint and attribute. + * + * Context error suppression [hint](@ref GLFW_CONTEXT_NO_ERROR_hint) and + * [attribute](@ref GLFW_CONTEXT_NO_ERROR_attrib). + */ +#define GLFW_CONTEXT_NO_ERROR 0x0002200A +/*! @brief Context creation API hint and attribute. + * + * Context creation API [hint](@ref GLFW_CONTEXT_CREATION_API_hint) and + * [attribute](@ref GLFW_CONTEXT_CREATION_API_attrib). + */ +#define GLFW_CONTEXT_CREATION_API 0x0002200B +/*! @brief Window content area scaling window + * [window hint](@ref GLFW_SCALE_TO_MONITOR). + */ +#define GLFW_SCALE_TO_MONITOR 0x0002200C +/*! @brief Window framebuffer scaling + * [window hint](@ref GLFW_SCALE_FRAMEBUFFER_hint). + */ +#define GLFW_SCALE_FRAMEBUFFER 0x0002200D +/*! @brief Legacy name for compatibility. + * + * This is an alias for the + * [GLFW_SCALE_FRAMEBUFFER](@ref GLFW_SCALE_FRAMEBUFFER_hint) window hint for + * compatibility with earlier versions. + */ +#define GLFW_COCOA_RETINA_FRAMEBUFFER 0x00023001 +/*! @brief macOS specific + * [window hint](@ref GLFW_COCOA_FRAME_NAME_hint). + */ +#define GLFW_COCOA_FRAME_NAME 0x00023002 +/*! @brief macOS specific + * [window hint](@ref GLFW_COCOA_GRAPHICS_SWITCHING_hint). + */ +#define GLFW_COCOA_GRAPHICS_SWITCHING 0x00023003 +/*! @brief X11 specific + * [window hint](@ref GLFW_X11_CLASS_NAME_hint). + */ +#define GLFW_X11_CLASS_NAME 0x00024001 +/*! @brief X11 specific + * [window hint](@ref GLFW_X11_CLASS_NAME_hint). + */ +#define GLFW_X11_INSTANCE_NAME 0x00024002 +#define GLFW_WIN32_KEYBOARD_MENU 0x00025001 +/*! @brief Win32 specific [window hint](@ref GLFW_WIN32_SHOWDEFAULT_hint). + */ +#define GLFW_WIN32_SHOWDEFAULT 0x00025002 +/*! @brief Wayland specific + * [window hint](@ref GLFW_WAYLAND_APP_ID_hint). + * + * Allows specification of the Wayland app_id. + */ +#define GLFW_WAYLAND_APP_ID 0x00026001 +/*! @} */ + +#define GLFW_NO_API 0 +#define GLFW_OPENGL_API 0x00030001 +#define GLFW_OPENGL_ES_API 0x00030002 + +#define GLFW_NO_ROBUSTNESS 0 +#define GLFW_NO_RESET_NOTIFICATION 0x00031001 +#define GLFW_LOSE_CONTEXT_ON_RESET 0x00031002 + +#define GLFW_OPENGL_ANY_PROFILE 0 +#define GLFW_OPENGL_CORE_PROFILE 0x00032001 +#define GLFW_OPENGL_COMPAT_PROFILE 0x00032002 + +#define GLFW_CURSOR 0x00033001 +#define GLFW_STICKY_KEYS 0x00033002 +#define GLFW_STICKY_MOUSE_BUTTONS 0x00033003 +#define GLFW_LOCK_KEY_MODS 0x00033004 +#define GLFW_RAW_MOUSE_MOTION 0x00033005 + +#define GLFW_CURSOR_NORMAL 0x00034001 +#define GLFW_CURSOR_HIDDEN 0x00034002 +#define GLFW_CURSOR_DISABLED 0x00034003 +#define GLFW_CURSOR_CAPTURED 0x00034004 + +#define GLFW_ANY_RELEASE_BEHAVIOR 0 +#define GLFW_RELEASE_BEHAVIOR_FLUSH 0x00035001 +#define GLFW_RELEASE_BEHAVIOR_NONE 0x00035002 + +#define GLFW_NATIVE_CONTEXT_API 0x00036001 +#define GLFW_EGL_CONTEXT_API 0x00036002 +#define GLFW_OSMESA_CONTEXT_API 0x00036003 + +#define GLFW_ANGLE_PLATFORM_TYPE_NONE 0x00037001 +#define GLFW_ANGLE_PLATFORM_TYPE_OPENGL 0x00037002 +#define GLFW_ANGLE_PLATFORM_TYPE_OPENGLES 0x00037003 +#define GLFW_ANGLE_PLATFORM_TYPE_D3D9 0x00037004 +#define GLFW_ANGLE_PLATFORM_TYPE_D3D11 0x00037005 +#define GLFW_ANGLE_PLATFORM_TYPE_VULKAN 0x00037007 +#define GLFW_ANGLE_PLATFORM_TYPE_METAL 0x00037008 + +#define GLFW_WAYLAND_PREFER_LIBDECOR 0x00038001 +#define GLFW_WAYLAND_DISABLE_LIBDECOR 0x00038002 + +#define GLFW_ANY_POSITION 0x80000000 + +/*! @defgroup shapes Standard cursor shapes + * @brief Standard system cursor shapes. + * + * These are the [standard cursor shapes](@ref cursor_standard) that can be + * requested from the platform (window system). + * + * @ingroup input + * @{ */ + +/*! @brief The regular arrow cursor shape. + * + * The regular arrow cursor shape. + */ +#define GLFW_ARROW_CURSOR 0x00036001 +/*! @brief The text input I-beam cursor shape. + * + * The text input I-beam cursor shape. + */ +#define GLFW_IBEAM_CURSOR 0x00036002 +/*! @brief The crosshair cursor shape. + * + * The crosshair cursor shape. + */ +#define GLFW_CROSSHAIR_CURSOR 0x00036003 +/*! @brief The pointing hand cursor shape. + * + * The pointing hand cursor shape. + */ +#define GLFW_POINTING_HAND_CURSOR 0x00036004 +/*! @brief The horizontal resize/move arrow shape. + * + * The horizontal resize/move arrow shape. This is usually a horizontal + * double-headed arrow. + */ +#define GLFW_RESIZE_EW_CURSOR 0x00036005 +/*! @brief The vertical resize/move arrow shape. + * + * The vertical resize/move shape. This is usually a vertical double-headed + * arrow. + */ +#define GLFW_RESIZE_NS_CURSOR 0x00036006 +/*! @brief The top-left to bottom-right diagonal resize/move arrow shape. + * + * The top-left to bottom-right diagonal resize/move shape. This is usually + * a diagonal double-headed arrow. + * + * @note @macos This shape is provided by a private system API and may fail + * with @ref GLFW_CURSOR_UNAVAILABLE in the future. + * + * @note @wayland This shape is provided by a newer standard not supported by + * all cursor themes. + * + * @note @x11 This shape is provided by a newer standard not supported by all + * cursor themes. + */ +#define GLFW_RESIZE_NWSE_CURSOR 0x00036007 +/*! @brief The top-right to bottom-left diagonal resize/move arrow shape. + * + * The top-right to bottom-left diagonal resize/move shape. This is usually + * a diagonal double-headed arrow. + * + * @note @macos This shape is provided by a private system API and may fail + * with @ref GLFW_CURSOR_UNAVAILABLE in the future. + * + * @note @wayland This shape is provided by a newer standard not supported by + * all cursor themes. + * + * @note @x11 This shape is provided by a newer standard not supported by all + * cursor themes. + */ +#define GLFW_RESIZE_NESW_CURSOR 0x00036008 +/*! @brief The omni-directional resize/move cursor shape. + * + * The omni-directional resize cursor/move shape. This is usually either + * a combined horizontal and vertical double-headed arrow or a grabbing hand. + */ +#define GLFW_RESIZE_ALL_CURSOR 0x00036009 +/*! @brief The operation-not-allowed shape. + * + * The operation-not-allowed shape. This is usually a circle with a diagonal + * line through it. + * + * @note @wayland This shape is provided by a newer standard not supported by + * all cursor themes. + * + * @note @x11 This shape is provided by a newer standard not supported by all + * cursor themes. + */ +#define GLFW_NOT_ALLOWED_CURSOR 0x0003600A +/*! @brief Legacy name for compatibility. + * + * This is an alias for compatibility with earlier versions. + */ +#define GLFW_HRESIZE_CURSOR GLFW_RESIZE_EW_CURSOR +/*! @brief Legacy name for compatibility. + * + * This is an alias for compatibility with earlier versions. + */ +#define GLFW_VRESIZE_CURSOR GLFW_RESIZE_NS_CURSOR +/*! @brief Legacy name for compatibility. + * + * This is an alias for compatibility with earlier versions. + */ +#define GLFW_HAND_CURSOR GLFW_POINTING_HAND_CURSOR +/*! @} */ + +#define GLFW_CONNECTED 0x00040001 +#define GLFW_DISCONNECTED 0x00040002 + +/*! @addtogroup init + * @{ */ +/*! @brief Joystick hat buttons init hint. + * + * Joystick hat buttons [init hint](@ref GLFW_JOYSTICK_HAT_BUTTONS). + */ +#define GLFW_JOYSTICK_HAT_BUTTONS 0x00050001 +/*! @brief ANGLE rendering backend init hint. + * + * ANGLE rendering backend [init hint](@ref GLFW_ANGLE_PLATFORM_TYPE_hint). + */ +#define GLFW_ANGLE_PLATFORM_TYPE 0x00050002 +/*! @brief Platform selection init hint. + * + * Platform selection [init hint](@ref GLFW_PLATFORM). + */ +#define GLFW_PLATFORM 0x00050003 +/*! @brief macOS specific init hint. + * + * macOS specific [init hint](@ref GLFW_COCOA_CHDIR_RESOURCES_hint). + */ +#define GLFW_COCOA_CHDIR_RESOURCES 0x00051001 +/*! @brief macOS specific init hint. + * + * macOS specific [init hint](@ref GLFW_COCOA_MENUBAR_hint). + */ +#define GLFW_COCOA_MENUBAR 0x00051002 +/*! @brief X11 specific init hint. + * + * X11 specific [init hint](@ref GLFW_X11_XCB_VULKAN_SURFACE_hint). + */ +#define GLFW_X11_XCB_VULKAN_SURFACE 0x00052001 +/*! @brief Wayland specific init hint. + * + * Wayland specific [init hint](@ref GLFW_WAYLAND_LIBDECOR_hint). + */ +#define GLFW_WAYLAND_LIBDECOR 0x00053001 +/*! @} */ + +/*! @addtogroup init + * @{ */ +/*! @brief Hint value that enables automatic platform selection. + * + * Hint value for @ref GLFW_PLATFORM that enables automatic platform selection. + */ +#define GLFW_ANY_PLATFORM 0x00060000 +#define GLFW_PLATFORM_WIN32 0x00060001 +#define GLFW_PLATFORM_COCOA 0x00060002 +#define GLFW_PLATFORM_WAYLAND 0x00060003 +#define GLFW_PLATFORM_X11 0x00060004 +#define GLFW_PLATFORM_NULL 0x00060005 +/*! @} */ + +#define GLFW_DONT_CARE -1 + + +/************************************************************************* + * GLFW API types + *************************************************************************/ + +/*! @brief Client API function pointer type. + * + * Generic function pointer used for returning client API function pointers + * without forcing a cast from a regular pointer. + * + * @sa @ref context_glext + * @sa @ref glfwGetProcAddress + * + * @since Added in version 3.0. + * + * @ingroup context + */ +typedef void (*GLFWglproc)(void); + +/*! @brief Vulkan API function pointer type. + * + * Generic function pointer used for returning Vulkan API function pointers + * without forcing a cast from a regular pointer. + * + * @sa @ref vulkan_proc + * @sa @ref glfwGetInstanceProcAddress + * + * @since Added in version 3.2. + * + * @ingroup vulkan + */ +typedef void (*GLFWvkproc)(void); + +/*! @brief Opaque monitor object. + * + * Opaque monitor object. + * + * @see @ref monitor_object + * + * @since Added in version 3.0. + * + * @ingroup monitor + */ +typedef struct GLFWmonitor GLFWmonitor; + +/*! @brief Opaque window object. + * + * Opaque window object. + * + * @see @ref window_object + * + * @since Added in version 3.0. + * + * @ingroup window + */ +typedef struct GLFWwindow GLFWwindow; + +/*! @brief Opaque cursor object. + * + * Opaque cursor object. + * + * @see @ref cursor_object + * + * @since Added in version 3.1. + * + * @ingroup input + */ +typedef struct GLFWcursor GLFWcursor; + +/*! @brief The function pointer type for memory allocation callbacks. + * + * This is the function pointer type for memory allocation callbacks. A memory + * allocation callback function has the following signature: + * @code + * void* function_name(size_t size, void* user) + * @endcode + * + * This function must return either a memory block at least `size` bytes long, + * or `NULL` if allocation failed. Note that not all parts of GLFW handle allocation + * failures gracefully yet. + * + * This function must support being called during @ref glfwInit but before the library is + * flagged as initialized, as well as during @ref glfwTerminate after the library is no + * longer flagged as initialized. + * + * Any memory allocated via this function will be deallocated via the same allocator + * during library termination or earlier. + * + * Any memory allocated via this function must be suitably aligned for any object type. + * If you are using C99 or earlier, this alignment is platform-dependent but will be the + * same as what `malloc` provides. If you are using C11 or later, this is the value of + * `alignof(max_align_t)`. + * + * The size will always be greater than zero. Allocations of size zero are filtered out + * before reaching the custom allocator. + * + * If this function returns `NULL`, GLFW will emit @ref GLFW_OUT_OF_MEMORY. + * + * This function must not call any GLFW function. + * + * @param[in] size The minimum size, in bytes, of the memory block. + * @param[in] user The user-defined pointer from the allocator. + * @return The address of the newly allocated memory block, or `NULL` if an + * error occurred. + * + * @pointer_lifetime The returned memory block must be valid at least until it + * is deallocated. + * + * @reentrancy This function should not call any GLFW function. + * + * @thread_safety This function must support being called from any thread that calls GLFW + * functions. + * + * @sa @ref init_allocator + * @sa @ref GLFWallocator + * + * @since Added in version 3.4. + * + * @ingroup init + */ +typedef void* (* GLFWallocatefun)(size_t size, void* user); + +/*! @brief The function pointer type for memory reallocation callbacks. + * + * This is the function pointer type for memory reallocation callbacks. + * A memory reallocation callback function has the following signature: + * @code + * void* function_name(void* block, size_t size, void* user) + * @endcode + * + * This function must return a memory block at least `size` bytes long, or + * `NULL` if allocation failed. Note that not all parts of GLFW handle allocation + * failures gracefully yet. + * + * This function must support being called during @ref glfwInit but before the library is + * flagged as initialized, as well as during @ref glfwTerminate after the library is no + * longer flagged as initialized. + * + * Any memory allocated via this function will be deallocated via the same allocator + * during library termination or earlier. + * + * Any memory allocated via this function must be suitably aligned for any object type. + * If you are using C99 or earlier, this alignment is platform-dependent but will be the + * same as what `realloc` provides. If you are using C11 or later, this is the value of + * `alignof(max_align_t)`. + * + * The block address will never be `NULL` and the size will always be greater than zero. + * Reallocations of a block to size zero are converted into deallocations before reaching + * the custom allocator. Reallocations of `NULL` to a non-zero size are converted into + * regular allocations before reaching the custom allocator. + * + * If this function returns `NULL`, GLFW will emit @ref GLFW_OUT_OF_MEMORY. + * + * This function must not call any GLFW function. + * + * @param[in] block The address of the memory block to reallocate. + * @param[in] size The new minimum size, in bytes, of the memory block. + * @param[in] user The user-defined pointer from the allocator. + * @return The address of the newly allocated or resized memory block, or + * `NULL` if an error occurred. + * + * @pointer_lifetime The returned memory block must be valid at least until it + * is deallocated. + * + * @reentrancy This function should not call any GLFW function. + * + * @thread_safety This function must support being called from any thread that calls GLFW + * functions. + * + * @sa @ref init_allocator + * @sa @ref GLFWallocator + * + * @since Added in version 3.4. + * + * @ingroup init + */ +typedef void* (* GLFWreallocatefun)(void* block, size_t size, void* user); + +/*! @brief The function pointer type for memory deallocation callbacks. + * + * This is the function pointer type for memory deallocation callbacks. + * A memory deallocation callback function has the following signature: + * @code + * void function_name(void* block, void* user) + * @endcode + * + * This function may deallocate the specified memory block. This memory block + * will have been allocated with the same allocator. + * + * This function must support being called during @ref glfwInit but before the library is + * flagged as initialized, as well as during @ref glfwTerminate after the library is no + * longer flagged as initialized. + * + * The block address will never be `NULL`. Deallocations of `NULL` are filtered out + * before reaching the custom allocator. + * + * If this function returns `NULL`, GLFW will emit @ref GLFW_OUT_OF_MEMORY. + * + * This function must not call any GLFW function. + * + * @param[in] block The address of the memory block to deallocate. + * @param[in] user The user-defined pointer from the allocator. + * + * @pointer_lifetime The specified memory block will not be accessed by GLFW + * after this function is called. + * + * @reentrancy This function should not call any GLFW function. + * + * @thread_safety This function must support being called from any thread that calls GLFW + * functions. + * + * @sa @ref init_allocator + * @sa @ref GLFWallocator + * + * @since Added in version 3.4. + * + * @ingroup init + */ +typedef void (* GLFWdeallocatefun)(void* block, void* user); + +/*! @brief The function pointer type for error callbacks. + * + * This is the function pointer type for error callbacks. An error callback + * function has the following signature: + * @code + * void callback_name(int error_code, const char* description) + * @endcode + * + * @param[in] error_code An [error code](@ref errors). Future releases may add + * more error codes. + * @param[in] description A UTF-8 encoded string describing the error. + * + * @pointer_lifetime The error description string is valid until the callback + * function returns. + * + * @sa @ref error_handling + * @sa @ref glfwSetErrorCallback + * + * @since Added in version 3.0. + * + * @ingroup init + */ +typedef void (* GLFWerrorfun)(int error_code, const char* description); + +/*! @brief The function pointer type for window position callbacks. + * + * This is the function pointer type for window position callbacks. A window + * position callback function has the following signature: + * @code + * void callback_name(GLFWwindow* window, int xpos, int ypos) + * @endcode + * + * @param[in] window The window that was moved. + * @param[in] xpos The new x-coordinate, in screen coordinates, of the + * upper-left corner of the content area of the window. + * @param[in] ypos The new y-coordinate, in screen coordinates, of the + * upper-left corner of the content area of the window. + * + * @sa @ref window_pos + * @sa @ref glfwSetWindowPosCallback + * + * @since Added in version 3.0. + * + * @ingroup window + */ +typedef void (* GLFWwindowposfun)(GLFWwindow* window, int xpos, int ypos); + +/*! @brief The function pointer type for window size callbacks. + * + * This is the function pointer type for window size callbacks. A window size + * callback function has the following signature: + * @code + * void callback_name(GLFWwindow* window, int width, int height) + * @endcode + * + * @param[in] window The window that was resized. + * @param[in] width The new width, in screen coordinates, of the window. + * @param[in] height The new height, in screen coordinates, of the window. + * + * @sa @ref window_size + * @sa @ref glfwSetWindowSizeCallback + * + * @since Added in version 1.0. + * @glfw3 Added window handle parameter. + * + * @ingroup window + */ +typedef void (* GLFWwindowsizefun)(GLFWwindow* window, int width, int height); + +/*! @brief The function pointer type for window close callbacks. + * + * This is the function pointer type for window close callbacks. A window + * close callback function has the following signature: + * @code + * void function_name(GLFWwindow* window) + * @endcode + * + * @param[in] window The window that the user attempted to close. + * + * @sa @ref window_close + * @sa @ref glfwSetWindowCloseCallback + * + * @since Added in version 2.5. + * @glfw3 Added window handle parameter. + * + * @ingroup window + */ +typedef void (* GLFWwindowclosefun)(GLFWwindow* window); + +/*! @brief The function pointer type for window content refresh callbacks. + * + * This is the function pointer type for window content refresh callbacks. + * A window content refresh callback function has the following signature: + * @code + * void function_name(GLFWwindow* window); + * @endcode + * + * @param[in] window The window whose content needs to be refreshed. + * + * @sa @ref window_refresh + * @sa @ref glfwSetWindowRefreshCallback + * + * @since Added in version 2.5. + * @glfw3 Added window handle parameter. + * + * @ingroup window + */ +typedef void (* GLFWwindowrefreshfun)(GLFWwindow* window); + +/*! @brief The function pointer type for window focus callbacks. + * + * This is the function pointer type for window focus callbacks. A window + * focus callback function has the following signature: + * @code + * void function_name(GLFWwindow* window, int focused) + * @endcode + * + * @param[in] window The window that gained or lost input focus. + * @param[in] focused `GLFW_TRUE` if the window was given input focus, or + * `GLFW_FALSE` if it lost it. + * + * @sa @ref window_focus + * @sa @ref glfwSetWindowFocusCallback + * + * @since Added in version 3.0. + * + * @ingroup window + */ +typedef void (* GLFWwindowfocusfun)(GLFWwindow* window, int focused); + +/*! @brief The function pointer type for window iconify callbacks. + * + * This is the function pointer type for window iconify callbacks. A window + * iconify callback function has the following signature: + * @code + * void function_name(GLFWwindow* window, int iconified) + * @endcode + * + * @param[in] window The window that was iconified or restored. + * @param[in] iconified `GLFW_TRUE` if the window was iconified, or + * `GLFW_FALSE` if it was restored. + * + * @sa @ref window_iconify + * @sa @ref glfwSetWindowIconifyCallback + * + * @since Added in version 3.0. + * + * @ingroup window + */ +typedef void (* GLFWwindowiconifyfun)(GLFWwindow* window, int iconified); + +/*! @brief The function pointer type for window maximize callbacks. + * + * This is the function pointer type for window maximize callbacks. A window + * maximize callback function has the following signature: + * @code + * void function_name(GLFWwindow* window, int maximized) + * @endcode + * + * @param[in] window The window that was maximized or restored. + * @param[in] maximized `GLFW_TRUE` if the window was maximized, or + * `GLFW_FALSE` if it was restored. + * + * @sa @ref window_maximize + * @sa glfwSetWindowMaximizeCallback + * + * @since Added in version 3.3. + * + * @ingroup window + */ +typedef void (* GLFWwindowmaximizefun)(GLFWwindow* window, int maximized); + +/*! @brief The function pointer type for framebuffer size callbacks. + * + * This is the function pointer type for framebuffer size callbacks. + * A framebuffer size callback function has the following signature: + * @code + * void function_name(GLFWwindow* window, int width, int height) + * @endcode + * + * @param[in] window The window whose framebuffer was resized. + * @param[in] width The new width, in pixels, of the framebuffer. + * @param[in] height The new height, in pixels, of the framebuffer. + * + * @sa @ref window_fbsize + * @sa @ref glfwSetFramebufferSizeCallback + * + * @since Added in version 3.0. + * + * @ingroup window + */ +typedef void (* GLFWframebuffersizefun)(GLFWwindow* window, int width, int height); + +/*! @brief The function pointer type for window content scale callbacks. + * + * This is the function pointer type for window content scale callbacks. + * A window content scale callback function has the following signature: + * @code + * void function_name(GLFWwindow* window, float xscale, float yscale) + * @endcode + * + * @param[in] window The window whose content scale changed. + * @param[in] xscale The new x-axis content scale of the window. + * @param[in] yscale The new y-axis content scale of the window. + * + * @sa @ref window_scale + * @sa @ref glfwSetWindowContentScaleCallback + * + * @since Added in version 3.3. + * + * @ingroup window + */ +typedef void (* GLFWwindowcontentscalefun)(GLFWwindow* window, float xscale, float yscale); + +/*! @brief The function pointer type for mouse button callbacks. + * + * This is the function pointer type for mouse button callback functions. + * A mouse button callback function has the following signature: + * @code + * void function_name(GLFWwindow* window, int button, int action, int mods) + * @endcode + * + * @param[in] window The window that received the event. + * @param[in] button The [mouse button](@ref buttons) that was pressed or + * released. + * @param[in] action One of `GLFW_PRESS` or `GLFW_RELEASE`. Future releases + * may add more actions. + * @param[in] mods Bit field describing which [modifier keys](@ref mods) were + * held down. + * + * @sa @ref input_mouse_button + * @sa @ref glfwSetMouseButtonCallback + * + * @since Added in version 1.0. + * @glfw3 Added window handle and modifier mask parameters. + * + * @ingroup input + */ +typedef void (* GLFWmousebuttonfun)(GLFWwindow* window, int button, int action, int mods); + +/*! @brief The function pointer type for cursor position callbacks. + * + * This is the function pointer type for cursor position callbacks. A cursor + * position callback function has the following signature: + * @code + * void function_name(GLFWwindow* window, double xpos, double ypos); + * @endcode + * + * @param[in] window The window that received the event. + * @param[in] xpos The new cursor x-coordinate, relative to the left edge of + * the content area. + * @param[in] ypos The new cursor y-coordinate, relative to the top edge of the + * content area. + * + * @sa @ref cursor_pos + * @sa @ref glfwSetCursorPosCallback + * + * @since Added in version 3.0. Replaces `GLFWmouseposfun`. + * + * @ingroup input + */ +typedef void (* GLFWcursorposfun)(GLFWwindow* window, double xpos, double ypos); + +/*! @brief The function pointer type for cursor enter/leave callbacks. + * + * This is the function pointer type for cursor enter/leave callbacks. + * A cursor enter/leave callback function has the following signature: + * @code + * void function_name(GLFWwindow* window, int entered) + * @endcode + * + * @param[in] window The window that received the event. + * @param[in] entered `GLFW_TRUE` if the cursor entered the window's content + * area, or `GLFW_FALSE` if it left it. + * + * @sa @ref cursor_enter + * @sa @ref glfwSetCursorEnterCallback + * + * @since Added in version 3.0. + * + * @ingroup input + */ +typedef void (* GLFWcursorenterfun)(GLFWwindow* window, int entered); + +/*! @brief The function pointer type for scroll callbacks. + * + * This is the function pointer type for scroll callbacks. A scroll callback + * function has the following signature: + * @code + * void function_name(GLFWwindow* window, double xoffset, double yoffset) + * @endcode + * + * @param[in] window The window that received the event. + * @param[in] xoffset The scroll offset along the x-axis. + * @param[in] yoffset The scroll offset along the y-axis. + * + * @sa @ref scrolling + * @sa @ref glfwSetScrollCallback + * + * @since Added in version 3.0. Replaces `GLFWmousewheelfun`. + * + * @ingroup input + */ +typedef void (* GLFWscrollfun)(GLFWwindow* window, double xoffset, double yoffset); + +/*! @brief The function pointer type for keyboard key callbacks. + * + * This is the function pointer type for keyboard key callbacks. A keyboard + * key callback function has the following signature: + * @code + * void function_name(GLFWwindow* window, int key, int scancode, int action, int mods) + * @endcode + * + * @param[in] window The window that received the event. + * @param[in] key The [keyboard key](@ref keys) that was pressed or released. + * @param[in] scancode The platform-specific scancode of the key. + * @param[in] action `GLFW_PRESS`, `GLFW_RELEASE` or `GLFW_REPEAT`. Future + * releases may add more actions. + * @param[in] mods Bit field describing which [modifier keys](@ref mods) were + * held down. + * + * @sa @ref input_key + * @sa @ref glfwSetKeyCallback + * + * @since Added in version 1.0. + * @glfw3 Added window handle, scancode and modifier mask parameters. + * + * @ingroup input + */ +typedef void (* GLFWkeyfun)(GLFWwindow* window, int key, int scancode, int action, int mods); + +/*! @brief The function pointer type for Unicode character callbacks. + * + * This is the function pointer type for Unicode character callbacks. + * A Unicode character callback function has the following signature: + * @code + * void function_name(GLFWwindow* window, unsigned int codepoint) + * @endcode + * + * @param[in] window The window that received the event. + * @param[in] codepoint The Unicode code point of the character. + * + * @sa @ref input_char + * @sa @ref glfwSetCharCallback + * + * @since Added in version 2.4. + * @glfw3 Added window handle parameter. + * + * @ingroup input + */ +typedef void (* GLFWcharfun)(GLFWwindow* window, unsigned int codepoint); + +/*! @brief The function pointer type for Unicode character with modifiers + * callbacks. + * + * This is the function pointer type for Unicode character with modifiers + * callbacks. It is called for each input character, regardless of what + * modifier keys are held down. A Unicode character with modifiers callback + * function has the following signature: + * @code + * void function_name(GLFWwindow* window, unsigned int codepoint, int mods) + * @endcode + * + * @param[in] window The window that received the event. + * @param[in] codepoint The Unicode code point of the character. + * @param[in] mods Bit field describing which [modifier keys](@ref mods) were + * held down. + * + * @sa @ref input_char + * @sa @ref glfwSetCharModsCallback + * + * @deprecated Scheduled for removal in version 4.0. + * + * @since Added in version 3.1. + * + * @ingroup input + */ +typedef void (* GLFWcharmodsfun)(GLFWwindow* window, unsigned int codepoint, int mods); + +/*! @brief The function pointer type for path drop callbacks. + * + * This is the function pointer type for path drop callbacks. A path drop + * callback function has the following signature: + * @code + * void function_name(GLFWwindow* window, int path_count, const char* paths[]) + * @endcode + * + * @param[in] window The window that received the event. + * @param[in] path_count The number of dropped paths. + * @param[in] paths The UTF-8 encoded file and/or directory path names. + * + * @pointer_lifetime The path array and its strings are valid until the + * callback function returns. + * + * @sa @ref path_drop + * @sa @ref glfwSetDropCallback + * + * @since Added in version 3.1. + * + * @ingroup input + */ +typedef void (* GLFWdropfun)(GLFWwindow* window, int path_count, const char* paths[]); + +/*! @brief The function pointer type for monitor configuration callbacks. + * + * This is the function pointer type for monitor configuration callbacks. + * A monitor callback function has the following signature: + * @code + * void function_name(GLFWmonitor* monitor, int event) + * @endcode + * + * @param[in] monitor The monitor that was connected or disconnected. + * @param[in] event One of `GLFW_CONNECTED` or `GLFW_DISCONNECTED`. Future + * releases may add more events. + * + * @sa @ref monitor_event + * @sa @ref glfwSetMonitorCallback + * + * @since Added in version 3.0. + * + * @ingroup monitor + */ +typedef void (* GLFWmonitorfun)(GLFWmonitor* monitor, int event); + +/*! @brief The function pointer type for joystick configuration callbacks. + * + * This is the function pointer type for joystick configuration callbacks. + * A joystick configuration callback function has the following signature: + * @code + * void function_name(int jid, int event) + * @endcode + * + * @param[in] jid The joystick that was connected or disconnected. + * @param[in] event One of `GLFW_CONNECTED` or `GLFW_DISCONNECTED`. Future + * releases may add more events. + * + * @sa @ref joystick_event + * @sa @ref glfwSetJoystickCallback + * + * @since Added in version 3.2. + * + * @ingroup input + */ +typedef void (* GLFWjoystickfun)(int jid, int event); + +/*! @brief Video mode type. + * + * This describes a single video mode. + * + * @sa @ref monitor_modes + * @sa @ref glfwGetVideoMode + * @sa @ref glfwGetVideoModes + * + * @since Added in version 1.0. + * @glfw3 Added refresh rate member. + * + * @ingroup monitor + */ +typedef struct GLFWvidmode +{ + /*! The width, in screen coordinates, of the video mode. + */ + int width; + /*! The height, in screen coordinates, of the video mode. + */ + int height; + /*! The bit depth of the red channel of the video mode. + */ + int redBits; + /*! The bit depth of the green channel of the video mode. + */ + int greenBits; + /*! The bit depth of the blue channel of the video mode. + */ + int blueBits; + /*! The refresh rate, in Hz, of the video mode. + */ + int refreshRate; +} GLFWvidmode; + +/*! @brief Gamma ramp. + * + * This describes the gamma ramp for a monitor. + * + * @sa @ref monitor_gamma + * @sa @ref glfwGetGammaRamp + * @sa @ref glfwSetGammaRamp + * + * @since Added in version 3.0. + * + * @ingroup monitor + */ +typedef struct GLFWgammaramp +{ + /*! An array of value describing the response of the red channel. + */ + unsigned short* red; + /*! An array of value describing the response of the green channel. + */ + unsigned short* green; + /*! An array of value describing the response of the blue channel. + */ + unsigned short* blue; + /*! The number of elements in each array. + */ + unsigned int size; +} GLFWgammaramp; + +/*! @brief Image data. + * + * This describes a single 2D image. See the documentation for each related + * function what the expected pixel format is. + * + * @sa @ref cursor_custom + * @sa @ref window_icon + * + * @since Added in version 2.1. + * @glfw3 Removed format and bytes-per-pixel members. + * + * @ingroup window + */ +typedef struct GLFWimage +{ + /*! The width, in pixels, of this image. + */ + int width; + /*! The height, in pixels, of this image. + */ + int height; + /*! The pixel data of this image, arranged left-to-right, top-to-bottom. + */ + unsigned char* pixels; +} GLFWimage; + +/*! @brief Gamepad input state + * + * This describes the input state of a gamepad. + * + * @sa @ref gamepad + * @sa @ref glfwGetGamepadState + * + * @since Added in version 3.3. + * + * @ingroup input + */ +typedef struct GLFWgamepadstate +{ + /*! The states of each [gamepad button](@ref gamepad_buttons), `GLFW_PRESS` + * or `GLFW_RELEASE`. + */ + unsigned char buttons[15]; + /*! The states of each [gamepad axis](@ref gamepad_axes), in the range -1.0 + * to 1.0 inclusive. + */ + float axes[6]; +} GLFWgamepadstate; + +/*! @brief Custom heap memory allocator. + * + * This describes a custom heap memory allocator for GLFW. To set an allocator, pass it + * to @ref glfwInitAllocator before initializing the library. + * + * @sa @ref init_allocator + * @sa @ref glfwInitAllocator + * + * @since Added in version 3.4. + * + * @ingroup init + */ +typedef struct GLFWallocator +{ + /*! The memory allocation function. See @ref GLFWallocatefun for details about + * allocation function. + */ + GLFWallocatefun allocate; + /*! The memory reallocation function. See @ref GLFWreallocatefun for details about + * reallocation function. + */ + GLFWreallocatefun reallocate; + /*! The memory deallocation function. See @ref GLFWdeallocatefun for details about + * deallocation function. + */ + GLFWdeallocatefun deallocate; + /*! The user pointer for this custom allocator. This value will be passed to the + * allocator functions. + */ + void* user; +} GLFWallocator; + + +/************************************************************************* + * GLFW API functions + *************************************************************************/ + +/*! @brief Initializes the GLFW library. + * + * This function initializes the GLFW library. Before most GLFW functions can + * be used, GLFW must be initialized, and before an application terminates GLFW + * should be terminated in order to free any resources allocated during or + * after initialization. + * + * If this function fails, it calls @ref glfwTerminate before returning. If it + * succeeds, you should call @ref glfwTerminate before the application exits. + * + * Additional calls to this function after successful initialization but before + * termination will return `GLFW_TRUE` immediately. + * + * The @ref GLFW_PLATFORM init hint controls which platforms are considered during + * initialization. This also depends on which platforms the library was compiled to + * support. + * + * @return `GLFW_TRUE` if successful, or `GLFW_FALSE` if an + * [error](@ref error_handling) occurred. + * + * @errors Possible errors include @ref GLFW_PLATFORM_UNAVAILABLE and @ref + * GLFW_PLATFORM_ERROR. + * + * @remark @macos This function will change the current directory of the + * application to the `Contents/Resources` subdirectory of the application's + * bundle, if present. This can be disabled with the @ref + * GLFW_COCOA_CHDIR_RESOURCES init hint. + * + * @remark @macos This function will create the main menu and dock icon for the + * application. If GLFW finds a `MainMenu.nib` it is loaded and assumed to + * contain a menu bar. Otherwise a minimal menu bar is created manually with + * common commands like Hide, Quit and About. The About entry opens a minimal + * about dialog with information from the application's bundle. The menu bar + * and dock icon can be disabled entirely with the @ref GLFW_COCOA_MENUBAR init + * hint. + * + * @remark __Wayland, X11:__ If the library was compiled with support for both + * Wayland and X11, and the @ref GLFW_PLATFORM init hint is set to + * `GLFW_ANY_PLATFORM`, the `XDG_SESSION_TYPE` environment variable affects + * which platform is picked. If the environment variable is not set, or is set + * to something other than `wayland` or `x11`, the regular detection mechanism + * will be used instead. + * + * @remark @x11 This function will set the `LC_CTYPE` category of the + * application locale according to the current environment if that category is + * still "C". This is because the "C" locale breaks Unicode text input. + * + * @thread_safety This function must only be called from the main thread. + * + * @sa @ref intro_init + * @sa @ref glfwInitHint + * @sa @ref glfwInitAllocator + * @sa @ref glfwTerminate + * + * @since Added in version 1.0. + * + * @ingroup init + */ +GLFWAPI int glfwInit(void); + +/*! @brief Terminates the GLFW library. + * + * This function destroys all remaining windows and cursors, restores any + * modified gamma ramps and frees any other allocated resources. Once this + * function is called, you must again call @ref glfwInit successfully before + * you will be able to use most GLFW functions. + * + * If GLFW has been successfully initialized, this function should be called + * before the application exits. If initialization fails, there is no need to + * call this function, as it is called by @ref glfwInit before it returns + * failure. + * + * This function has no effect if GLFW is not initialized. + * + * @errors Possible errors include @ref GLFW_PLATFORM_ERROR. + * + * @remark This function may be called before @ref glfwInit. + * + * @warning The contexts of any remaining windows must not be current on any + * other thread when this function is called. + * + * @reentrancy This function must not be called from a callback. + * + * @thread_safety This function must only be called from the main thread. + * + * @sa @ref intro_init + * @sa @ref glfwInit + * + * @since Added in version 1.0. + * + * @ingroup init + */ +GLFWAPI void glfwTerminate(void); + +/*! @brief Sets the specified init hint to the desired value. + * + * This function sets hints for the next initialization of GLFW. + * + * The values you set hints to are never reset by GLFW, but they only take + * effect during initialization. Once GLFW has been initialized, any values + * you set will be ignored until the library is terminated and initialized + * again. + * + * Some hints are platform specific. These may be set on any platform but they + * will only affect their specific platform. Other platforms will ignore them. + * Setting these hints requires no platform specific headers or functions. + * + * @param[in] hint The [init hint](@ref init_hints) to set. + * @param[in] value The new value of the init hint. + * + * @errors Possible errors include @ref GLFW_INVALID_ENUM and @ref + * GLFW_INVALID_VALUE. + * + * @remarks This function may be called before @ref glfwInit. + * + * @thread_safety This function must only be called from the main thread. + * + * @sa init_hints + * @sa glfwInit + * + * @since Added in version 3.3. + * + * @ingroup init + */ +GLFWAPI void glfwInitHint(int hint, int value); + +/*! @brief Sets the init allocator to the desired value. + * + * To use the default allocator, call this function with a `NULL` argument. + * + * If you specify an allocator struct, every member must be a valid function + * pointer. If any member is `NULL`, this function will emit @ref + * GLFW_INVALID_VALUE and the init allocator will be unchanged. + * + * The functions in the allocator must fulfil a number of requirements. See the + * documentation for @ref GLFWallocatefun, @ref GLFWreallocatefun and @ref + * GLFWdeallocatefun for details. + * + * @param[in] allocator The allocator to use at the next initialization, or + * `NULL` to use the default one. + * + * @errors Possible errors include @ref GLFW_INVALID_VALUE. + * + * @pointer_lifetime The specified allocator is copied before this function + * returns. + * + * @thread_safety This function must only be called from the main thread. + * + * @sa @ref init_allocator + * @sa @ref glfwInit + * + * @since Added in version 3.4. + * + * @ingroup init + */ +GLFWAPI void glfwInitAllocator(const GLFWallocator* allocator); + +#if defined(VK_VERSION_1_0) + +/*! @brief Sets the desired Vulkan `vkGetInstanceProcAddr` function. + * + * This function sets the `vkGetInstanceProcAddr` function that GLFW will use for all + * Vulkan related entry point queries. + * + * This feature is mostly useful on macOS, if your copy of the Vulkan loader is in + * a location where GLFW cannot find it through dynamic loading, or if you are still + * using the static library version of the loader. + * + * If set to `NULL`, GLFW will try to load the Vulkan loader dynamically by its standard + * name and get this function from there. This is the default behavior. + * + * The standard name of the loader is `vulkan-1.dll` on Windows, `libvulkan.so.1` on + * Linux and other Unix-like systems and `libvulkan.1.dylib` on macOS. If your code is + * also loading it via these names then you probably don't need to use this function. + * + * The function address you set is never reset by GLFW, but it only takes effect during + * initialization. Once GLFW has been initialized, any updates will be ignored until the + * library is terminated and initialized again. + * + * @param[in] loader The address of the function to use, or `NULL`. + * + * @par Loader function signature + * @code + * PFN_vkVoidFunction vkGetInstanceProcAddr(VkInstance instance, const char* name) + * @endcode + * For more information about this function, see the + * [Vulkan Registry](https://www.khronos.org/registry/vulkan/). + * + * @errors None. + * + * @remark This function may be called before @ref glfwInit. + * + * @thread_safety This function must only be called from the main thread. + * + * @sa @ref vulkan_loader + * @sa @ref glfwInit + * + * @since Added in version 3.4. + * + * @ingroup init + */ +GLFWAPI void glfwInitVulkanLoader(PFN_vkGetInstanceProcAddr loader); + +#endif /*VK_VERSION_1_0*/ + +/*! @brief Retrieves the version of the GLFW library. + * + * This function retrieves the major, minor and revision numbers of the GLFW + * library. It is intended for when you are using GLFW as a shared library and + * want to ensure that you are using the minimum required version. + * + * Any or all of the version arguments may be `NULL`. + * + * @param[out] major Where to store the major version number, or `NULL`. + * @param[out] minor Where to store the minor version number, or `NULL`. + * @param[out] rev Where to store the revision number, or `NULL`. + * + * @errors None. + * + * @remark This function may be called before @ref glfwInit. + * + * @thread_safety This function may be called from any thread. + * + * @sa @ref intro_version + * @sa @ref glfwGetVersionString + * + * @since Added in version 1.0. + * + * @ingroup init + */ +GLFWAPI void glfwGetVersion(int* major, int* minor, int* rev); + +/*! @brief Returns a string describing the compile-time configuration. + * + * This function returns the compile-time generated + * [version string](@ref intro_version_string) of the GLFW library binary. It describes + * the version, platforms, compiler and any platform or operating system specific + * compile-time options. It should not be confused with the OpenGL or OpenGL ES version + * string, queried with `glGetString`. + * + * __Do not use the version string__ to parse the GLFW library version. The + * @ref glfwGetVersion function provides the version of the running library + * binary in numerical format. + * + * __Do not use the version string__ to parse what platforms are supported. The @ref + * glfwPlatformSupported function lets you query platform support. + * + * @return The ASCII encoded GLFW version string. + * + * @errors None. + * + * @remark This function may be called before @ref glfwInit. + * + * @pointer_lifetime The returned string is static and compile-time generated. + * + * @thread_safety This function may be called from any thread. + * + * @sa @ref intro_version + * @sa @ref glfwGetVersion + * + * @since Added in version 3.0. + * + * @ingroup init + */ +GLFWAPI const char* glfwGetVersionString(void); + +/*! @brief Returns and clears the last error for the calling thread. + * + * This function returns and clears the [error code](@ref errors) of the last + * error that occurred on the calling thread, and optionally a UTF-8 encoded + * human-readable description of it. If no error has occurred since the last + * call, it returns @ref GLFW_NO_ERROR (zero) and the description pointer is + * set to `NULL`. + * + * @param[in] description Where to store the error description pointer, or `NULL`. + * @return The last error code for the calling thread, or @ref GLFW_NO_ERROR + * (zero). + * + * @errors None. + * + * @pointer_lifetime The returned string is allocated and freed by GLFW. You + * should not free it yourself. It is guaranteed to be valid only until the + * next error occurs or the library is terminated. + * + * @remark This function may be called before @ref glfwInit. + * + * @thread_safety This function may be called from any thread. + * + * @sa @ref error_handling + * @sa @ref glfwSetErrorCallback + * + * @since Added in version 3.3. + * + * @ingroup init + */ +GLFWAPI int glfwGetError(const char** description); + +/*! @brief Sets the error callback. + * + * This function sets the error callback, which is called with an error code + * and a human-readable description each time a GLFW error occurs. + * + * The error code is set before the callback is called. Calling @ref + * glfwGetError from the error callback will return the same value as the error + * code argument. + * + * The error callback is called on the thread where the error occurred. If you + * are using GLFW from multiple threads, your error callback needs to be + * written accordingly. + * + * Because the description string may have been generated specifically for that + * error, it is not guaranteed to be valid after the callback has returned. If + * you wish to use it after the callback returns, you need to make a copy. + * + * Once set, the error callback remains set even after the library has been + * terminated. + * + * @param[in] callback The new callback, or `NULL` to remove the currently set + * callback. + * @return The previously set callback, or `NULL` if no callback was set. + * + * @callback_signature + * @code + * void callback_name(int error_code, const char* description) + * @endcode + * For more information about the callback parameters, see the + * [callback pointer type](@ref GLFWerrorfun). + * + * @errors None. + * + * @remark This function may be called before @ref glfwInit. + * + * @thread_safety This function must only be called from the main thread. + * + * @sa @ref error_handling + * @sa @ref glfwGetError + * + * @since Added in version 3.0. + * + * @ingroup init + */ +GLFWAPI GLFWerrorfun glfwSetErrorCallback(GLFWerrorfun callback); + +/*! @brief Returns the currently selected platform. + * + * This function returns the platform that was selected during initialization. The + * returned value will be one of `GLFW_PLATFORM_WIN32`, `GLFW_PLATFORM_COCOA`, + * `GLFW_PLATFORM_WAYLAND`, `GLFW_PLATFORM_X11` or `GLFW_PLATFORM_NULL`. + * + * @return The currently selected platform, or zero if an error occurred. + * + * @errors Possible errors include @ref GLFW_NOT_INITIALIZED. + * + * @thread_safety This function may be called from any thread. + * + * @sa @ref platform + * @sa @ref glfwPlatformSupported + * + * @since Added in version 3.4. + * + * @ingroup init + */ +GLFWAPI int glfwGetPlatform(void); + +/*! @brief Returns whether the library includes support for the specified platform. + * + * This function returns whether the library was compiled with support for the specified + * platform. The platform must be one of `GLFW_PLATFORM_WIN32`, `GLFW_PLATFORM_COCOA`, + * `GLFW_PLATFORM_WAYLAND`, `GLFW_PLATFORM_X11` or `GLFW_PLATFORM_NULL`. + * + * @param[in] platform The platform to query. + * @return `GLFW_TRUE` if the platform is supported, or `GLFW_FALSE` otherwise. + * + * @errors Possible errors include @ref GLFW_INVALID_ENUM. + * + * @remark This function may be called before @ref glfwInit. + * + * @thread_safety This function may be called from any thread. + * + * @sa @ref platform + * @sa @ref glfwGetPlatform + * + * @since Added in version 3.4. + * + * @ingroup init + */ +GLFWAPI int glfwPlatformSupported(int platform); + +/*! @brief Returns the currently connected monitors. + * + * This function returns an array of handles for all currently connected + * monitors. The primary monitor is always first in the returned array. If no + * monitors were found, this function returns `NULL`. + * + * @param[out] count Where to store the number of monitors in the returned + * array. This is set to zero if an error occurred. + * @return An array of monitor handles, or `NULL` if no monitors were found or + * if an [error](@ref error_handling) occurred. + * + * @errors Possible errors include @ref GLFW_NOT_INITIALIZED. + * + * @pointer_lifetime The returned array is allocated and freed by GLFW. You + * should not free it yourself. It is guaranteed to be valid only until the + * monitor configuration changes or the library is terminated. + * + * @thread_safety This function must only be called from the main thread. + * + * @sa @ref monitor_monitors + * @sa @ref monitor_event + * @sa @ref glfwGetPrimaryMonitor + * + * @since Added in version 3.0. + * + * @ingroup monitor + */ +GLFWAPI GLFWmonitor** glfwGetMonitors(int* count); + +/*! @brief Returns the primary monitor. + * + * This function returns the primary monitor. This is usually the monitor + * where elements like the task bar or global menu bar are located. + * + * @return The primary monitor, or `NULL` if no monitors were found or if an + * [error](@ref error_handling) occurred. + * + * @errors Possible errors include @ref GLFW_NOT_INITIALIZED. + * + * @thread_safety This function must only be called from the main thread. + * + * @remark The primary monitor is always first in the array returned by @ref + * glfwGetMonitors. + * + * @sa @ref monitor_monitors + * @sa @ref glfwGetMonitors + * + * @since Added in version 3.0. + * + * @ingroup monitor + */ +GLFWAPI GLFWmonitor* glfwGetPrimaryMonitor(void); + +/*! @brief Returns the position of the monitor's viewport on the virtual screen. + * + * This function returns the position, in screen coordinates, of the upper-left + * corner of the specified monitor. + * + * Any or all of the position arguments may be `NULL`. If an error occurs, all + * non-`NULL` position arguments will be set to zero. + * + * @param[in] monitor The monitor to query. + * @param[out] xpos Where to store the monitor x-coordinate, or `NULL`. + * @param[out] ypos Where to store the monitor y-coordinate, or `NULL`. + * + * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref + * GLFW_PLATFORM_ERROR. + * + * @thread_safety This function must only be called from the main thread. + * + * @sa @ref monitor_properties + * + * @since Added in version 3.0. + * + * @ingroup monitor + */ +GLFWAPI void glfwGetMonitorPos(GLFWmonitor* monitor, int* xpos, int* ypos); + +/*! @brief Retrieves the work area of the monitor. + * + * This function returns the position, in screen coordinates, of the upper-left + * corner of the work area of the specified monitor along with the work area + * size in screen coordinates. The work area is defined as the area of the + * monitor not occluded by the window system task bar where present. If no + * task bar exists then the work area is the monitor resolution in screen + * coordinates. + * + * Any or all of the position and size arguments may be `NULL`. If an error + * occurs, all non-`NULL` position and size arguments will be set to zero. + * + * @param[in] monitor The monitor to query. + * @param[out] xpos Where to store the monitor x-coordinate, or `NULL`. + * @param[out] ypos Where to store the monitor y-coordinate, or `NULL`. + * @param[out] width Where to store the monitor width, or `NULL`. + * @param[out] height Where to store the monitor height, or `NULL`. + * + * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref + * GLFW_PLATFORM_ERROR. + * + * @thread_safety This function must only be called from the main thread. + * + * @sa @ref monitor_workarea + * + * @since Added in version 3.3. + * + * @ingroup monitor + */ +GLFWAPI void glfwGetMonitorWorkarea(GLFWmonitor* monitor, int* xpos, int* ypos, int* width, int* height); + +/*! @brief Returns the physical size of the monitor. + * + * This function returns the size, in millimetres, of the display area of the + * specified monitor. + * + * Some platforms do not provide accurate monitor size information, either + * because the monitor [EDID][] data is incorrect or because the driver does + * not report it accurately. + * + * [EDID]: https://en.wikipedia.org/wiki/Extended_display_identification_data + * + * Any or all of the size arguments may be `NULL`. If an error occurs, all + * non-`NULL` size arguments will be set to zero. + * + * @param[in] monitor The monitor to query. + * @param[out] widthMM Where to store the width, in millimetres, of the + * monitor's display area, or `NULL`. + * @param[out] heightMM Where to store the height, in millimetres, of the + * monitor's display area, or `NULL`. + * + * @errors Possible errors include @ref GLFW_NOT_INITIALIZED. + * + * @remark @win32 On Windows 8 and earlier the physical size is calculated from + * the current resolution and system DPI instead of querying the monitor EDID data. + * + * @thread_safety This function must only be called from the main thread. + * + * @sa @ref monitor_properties + * + * @since Added in version 3.0. + * + * @ingroup monitor + */ +GLFWAPI void glfwGetMonitorPhysicalSize(GLFWmonitor* monitor, int* widthMM, int* heightMM); + +/*! @brief Retrieves the content scale for the specified monitor. + * + * This function retrieves the content scale for the specified monitor. The + * content scale is the ratio between the current DPI and the platform's + * default DPI. This is especially important for text and any UI elements. If + * the pixel dimensions of your UI scaled by this look appropriate on your + * machine then it should appear at a reasonable size on other machines + * regardless of their DPI and scaling settings. This relies on the system DPI + * and scaling settings being somewhat correct. + * + * The content scale may depend on both the monitor resolution and pixel + * density and on user settings. It may be very different from the raw DPI + * calculated from the physical size and current resolution. + * + * @param[in] monitor The monitor to query. + * @param[out] xscale Where to store the x-axis content scale, or `NULL`. + * @param[out] yscale Where to store the y-axis content scale, or `NULL`. + * + * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref + * GLFW_PLATFORM_ERROR. + * + * @remark @wayland Fractional scaling information is not yet available for + * monitors, so this function only returns integer content scales. + * + * @thread_safety This function must only be called from the main thread. + * + * @sa @ref monitor_scale + * @sa @ref glfwGetWindowContentScale + * + * @since Added in version 3.3. + * + * @ingroup monitor + */ +GLFWAPI void glfwGetMonitorContentScale(GLFWmonitor* monitor, float* xscale, float* yscale); + +/*! @brief Returns the name of the specified monitor. + * + * This function returns a human-readable name, encoded as UTF-8, of the + * specified monitor. The name typically reflects the make and model of the + * monitor and is not guaranteed to be unique among the connected monitors. + * + * @param[in] monitor The monitor to query. + * @return The UTF-8 encoded name of the monitor, or `NULL` if an + * [error](@ref error_handling) occurred. + * + * @errors Possible errors include @ref GLFW_NOT_INITIALIZED. + * + * @pointer_lifetime The returned string is allocated and freed by GLFW. You + * should not free it yourself. It is valid until the specified monitor is + * disconnected or the library is terminated. + * + * @thread_safety This function must only be called from the main thread. + * + * @sa @ref monitor_properties + * + * @since Added in version 3.0. + * + * @ingroup monitor + */ +GLFWAPI const char* glfwGetMonitorName(GLFWmonitor* monitor); + +/*! @brief Sets the user pointer of the specified monitor. + * + * This function sets the user-defined pointer of the specified monitor. The + * current value is retained until the monitor is disconnected. The initial + * value is `NULL`. + * + * This function may be called from the monitor callback, even for a monitor + * that is being disconnected. + * + * @param[in] monitor The monitor whose pointer to set. + * @param[in] pointer The new value. + * + * @errors Possible errors include @ref GLFW_NOT_INITIALIZED. + * + * @thread_safety This function may be called from any thread. Access is not + * synchronized. + * + * @sa @ref monitor_userptr + * @sa @ref glfwGetMonitorUserPointer + * + * @since Added in version 3.3. + * + * @ingroup monitor + */ +GLFWAPI void glfwSetMonitorUserPointer(GLFWmonitor* monitor, void* pointer); + +/*! @brief Returns the user pointer of the specified monitor. + * + * This function returns the current value of the user-defined pointer of the + * specified monitor. The initial value is `NULL`. + * + * This function may be called from the monitor callback, even for a monitor + * that is being disconnected. + * + * @param[in] monitor The monitor whose pointer to return. + * + * @errors Possible errors include @ref GLFW_NOT_INITIALIZED. + * + * @thread_safety This function may be called from any thread. Access is not + * synchronized. + * + * @sa @ref monitor_userptr + * @sa @ref glfwSetMonitorUserPointer + * + * @since Added in version 3.3. + * + * @ingroup monitor + */ +GLFWAPI void* glfwGetMonitorUserPointer(GLFWmonitor* monitor); + +/*! @brief Sets the monitor configuration callback. + * + * This function sets the monitor configuration callback, or removes the + * currently set callback. This is called when a monitor is connected to or + * disconnected from the system. + * + * @param[in] callback The new callback, or `NULL` to remove the currently set + * callback. + * @return The previously set callback, or `NULL` if no callback was set or the + * library had not been [initialized](@ref intro_init). + * + * @callback_signature + * @code + * void function_name(GLFWmonitor* monitor, int event) + * @endcode + * For more information about the callback parameters, see the + * [function pointer type](@ref GLFWmonitorfun). + * + * @errors Possible errors include @ref GLFW_NOT_INITIALIZED. + * + * @thread_safety This function must only be called from the main thread. + * + * @sa @ref monitor_event + * + * @since Added in version 3.0. + * + * @ingroup monitor + */ +GLFWAPI GLFWmonitorfun glfwSetMonitorCallback(GLFWmonitorfun callback); + +/*! @brief Returns the available video modes for the specified monitor. + * + * This function returns an array of all video modes supported by the specified + * monitor. The returned array is sorted in ascending order, first by color + * bit depth (the sum of all channel depths), then by resolution area (the + * product of width and height), then resolution width and finally by refresh + * rate. + * + * @param[in] monitor The monitor to query. + * @param[out] count Where to store the number of video modes in the returned + * array. This is set to zero if an error occurred. + * @return An array of video modes, or `NULL` if an + * [error](@ref error_handling) occurred. + * + * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref + * GLFW_PLATFORM_ERROR. + * + * @pointer_lifetime The returned array is allocated and freed by GLFW. You + * should not free it yourself. It is valid until the specified monitor is + * disconnected, this function is called again for that monitor or the library + * is terminated. + * + * @thread_safety This function must only be called from the main thread. + * + * @sa @ref monitor_modes + * @sa @ref glfwGetVideoMode + * + * @since Added in version 1.0. + * @glfw3 Changed to return an array of modes for a specific monitor. + * + * @ingroup monitor + */ +GLFWAPI const GLFWvidmode* glfwGetVideoModes(GLFWmonitor* monitor, int* count); + +/*! @brief Returns the current mode of the specified monitor. + * + * This function returns the current video mode of the specified monitor. If + * you have created a full screen window for that monitor, the return value + * will depend on whether that window is iconified. + * + * @param[in] monitor The monitor to query. + * @return The current mode of the monitor, or `NULL` if an + * [error](@ref error_handling) occurred. + * + * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref + * GLFW_PLATFORM_ERROR. + * + * @pointer_lifetime The returned array is allocated and freed by GLFW. You + * should not free it yourself. It is valid until the specified monitor is + * disconnected or the library is terminated. + * + * @thread_safety This function must only be called from the main thread. + * + * @sa @ref monitor_modes + * @sa @ref glfwGetVideoModes + * + * @since Added in version 3.0. Replaces `glfwGetDesktopMode`. + * + * @ingroup monitor + */ +GLFWAPI const GLFWvidmode* glfwGetVideoMode(GLFWmonitor* monitor); + +/*! @brief Generates a gamma ramp and sets it for the specified monitor. + * + * This function generates an appropriately sized gamma ramp from the specified + * exponent and then calls @ref glfwSetGammaRamp with it. The value must be + * a finite number greater than zero. + * + * The software controlled gamma ramp is applied _in addition_ to the hardware + * gamma correction, which today is usually an approximation of sRGB gamma. + * This means that setting a perfectly linear ramp, or gamma 1.0, will produce + * the default (usually sRGB-like) behavior. + * + * For gamma correct rendering with OpenGL or OpenGL ES, see the @ref + * GLFW_SRGB_CAPABLE hint. + * + * @param[in] monitor The monitor whose gamma ramp to set. + * @param[in] gamma The desired exponent. + * + * @errors Possible errors include @ref GLFW_NOT_INITIALIZED, @ref GLFW_INVALID_VALUE, + * @ref GLFW_PLATFORM_ERROR and @ref GLFW_FEATURE_UNAVAILABLE (see remarks). + * + * @remark @wayland Gamma handling is a privileged protocol, this function + * will thus never be implemented and emits @ref GLFW_FEATURE_UNAVAILABLE. + * + * @thread_safety This function must only be called from the main thread. + * + * @sa @ref monitor_gamma + * + * @since Added in version 3.0. + * + * @ingroup monitor + */ +GLFWAPI void glfwSetGamma(GLFWmonitor* monitor, float gamma); + +/*! @brief Returns the current gamma ramp for the specified monitor. + * + * This function returns the current gamma ramp of the specified monitor. + * + * @param[in] monitor The monitor to query. + * @return The current gamma ramp, or `NULL` if an + * [error](@ref error_handling) occurred. + * + * @errors Possible errors include @ref GLFW_NOT_INITIALIZED, @ref GLFW_PLATFORM_ERROR + * and @ref GLFW_FEATURE_UNAVAILABLE (see remarks). + * + * @remark @wayland Gamma handling is a privileged protocol, this function + * will thus never be implemented and emits @ref GLFW_FEATURE_UNAVAILABLE while + * returning `NULL`. + * + * @pointer_lifetime The returned structure and its arrays are allocated and + * freed by GLFW. You should not free them yourself. They are valid until the + * specified monitor is disconnected, this function is called again for that + * monitor or the library is terminated. + * + * @thread_safety This function must only be called from the main thread. + * + * @sa @ref monitor_gamma + * + * @since Added in version 3.0. + * + * @ingroup monitor + */ +GLFWAPI const GLFWgammaramp* glfwGetGammaRamp(GLFWmonitor* monitor); + +/*! @brief Sets the current gamma ramp for the specified monitor. + * + * This function sets the current gamma ramp for the specified monitor. The + * original gamma ramp for that monitor is saved by GLFW the first time this + * function is called and is restored by @ref glfwTerminate. + * + * The software controlled gamma ramp is applied _in addition_ to the hardware + * gamma correction, which today is usually an approximation of sRGB gamma. + * This means that setting a perfectly linear ramp, or gamma 1.0, will produce + * the default (usually sRGB-like) behavior. + * + * For gamma correct rendering with OpenGL or OpenGL ES, see the @ref + * GLFW_SRGB_CAPABLE hint. + * + * @param[in] monitor The monitor whose gamma ramp to set. + * @param[in] ramp The gamma ramp to use. + * + * @errors Possible errors include @ref GLFW_NOT_INITIALIZED, @ref GLFW_PLATFORM_ERROR + * and @ref GLFW_FEATURE_UNAVAILABLE (see remarks). + * + * @remark The size of the specified gamma ramp should match the size of the + * current ramp for that monitor. + * + * @remark @win32 The gamma ramp size must be 256. + * + * @remark @wayland Gamma handling is a privileged protocol, this function + * will thus never be implemented and emits @ref GLFW_FEATURE_UNAVAILABLE. + * + * @pointer_lifetime The specified gamma ramp is copied before this function + * returns. + * + * @thread_safety This function must only be called from the main thread. + * + * @sa @ref monitor_gamma + * + * @since Added in version 3.0. + * + * @ingroup monitor + */ +GLFWAPI void glfwSetGammaRamp(GLFWmonitor* monitor, const GLFWgammaramp* ramp); + +/*! @brief Resets all window hints to their default values. + * + * This function resets all window hints to their + * [default values](@ref window_hints_values). + * + * @errors Possible errors include @ref GLFW_NOT_INITIALIZED. + * + * @thread_safety This function must only be called from the main thread. + * + * @sa @ref window_hints + * @sa @ref glfwWindowHint + * @sa @ref glfwWindowHintString + * + * @since Added in version 3.0. + * + * @ingroup window + */ +GLFWAPI void glfwDefaultWindowHints(void); + +/*! @brief Sets the specified window hint to the desired value. + * + * This function sets hints for the next call to @ref glfwCreateWindow. The + * hints, once set, retain their values until changed by a call to this + * function or @ref glfwDefaultWindowHints, or until the library is terminated. + * + * Only integer value hints can be set with this function. String value hints + * are set with @ref glfwWindowHintString. + * + * This function does not check whether the specified hint values are valid. + * If you set hints to invalid values this will instead be reported by the next + * call to @ref glfwCreateWindow. + * + * Some hints are platform specific. These may be set on any platform but they + * will only affect their specific platform. Other platforms will ignore them. + * Setting these hints requires no platform specific headers or functions. + * + * @param[in] hint The [window hint](@ref window_hints) to set. + * @param[in] value The new value of the window hint. + * + * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref + * GLFW_INVALID_ENUM. + * + * @thread_safety This function must only be called from the main thread. + * + * @sa @ref window_hints + * @sa @ref glfwWindowHintString + * @sa @ref glfwDefaultWindowHints + * + * @since Added in version 3.0. Replaces `glfwOpenWindowHint`. + * + * @ingroup window + */ +GLFWAPI void glfwWindowHint(int hint, int value); + +/*! @brief Sets the specified window hint to the desired value. + * + * This function sets hints for the next call to @ref glfwCreateWindow. The + * hints, once set, retain their values until changed by a call to this + * function or @ref glfwDefaultWindowHints, or until the library is terminated. + * + * Only string type hints can be set with this function. Integer value hints + * are set with @ref glfwWindowHint. + * + * This function does not check whether the specified hint values are valid. + * If you set hints to invalid values this will instead be reported by the next + * call to @ref glfwCreateWindow. + * + * Some hints are platform specific. These may be set on any platform but they + * will only affect their specific platform. Other platforms will ignore them. + * Setting these hints requires no platform specific headers or functions. + * + * @param[in] hint The [window hint](@ref window_hints) to set. + * @param[in] value The new value of the window hint. + * + * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref + * GLFW_INVALID_ENUM. + * + * @pointer_lifetime The specified string is copied before this function + * returns. + * + * @thread_safety This function must only be called from the main thread. + * + * @sa @ref window_hints + * @sa @ref glfwWindowHint + * @sa @ref glfwDefaultWindowHints + * + * @since Added in version 3.3. + * + * @ingroup window + */ +GLFWAPI void glfwWindowHintString(int hint, const char* value); + +/*! @brief Creates a window and its associated context. + * + * This function creates a window and its associated OpenGL or OpenGL ES + * context. Most of the options controlling how the window and its context + * should be created are specified with [window hints](@ref window_hints). + * + * Successful creation does not change which context is current. Before you + * can use the newly created context, you need to + * [make it current](@ref context_current). For information about the `share` + * parameter, see @ref context_sharing. + * + * The created window, framebuffer and context may differ from what you + * requested, as not all parameters and hints are + * [hard constraints](@ref window_hints_hard). This includes the size of the + * window, especially for full screen windows. To query the actual attributes + * of the created window, framebuffer and context, see @ref + * glfwGetWindowAttrib, @ref glfwGetWindowSize and @ref glfwGetFramebufferSize. + * + * To create a full screen window, you need to specify the monitor the window + * will cover. If no monitor is specified, the window will be windowed mode. + * Unless you have a way for the user to choose a specific monitor, it is + * recommended that you pick the primary monitor. For more information on how + * to query connected monitors, see @ref monitor_monitors. + * + * For full screen windows, the specified size becomes the resolution of the + * window's _desired video mode_. As long as a full screen window is not + * iconified, the supported video mode most closely matching the desired video + * mode is set for the specified monitor. For more information about full + * screen windows, including the creation of so called _windowed full screen_ + * or _borderless full screen_ windows, see @ref window_windowed_full_screen. + * + * Once you have created the window, you can switch it between windowed and + * full screen mode with @ref glfwSetWindowMonitor. This will not affect its + * OpenGL or OpenGL ES context. + * + * By default, newly created windows use the placement recommended by the + * window system. To create the window at a specific position, set the @ref + * GLFW_POSITION_X and @ref GLFW_POSITION_Y window hints before creation. To + * restore the default behavior, set either or both hints back to + * `GLFW_ANY_POSITION`. + * + * As long as at least one full screen window is not iconified, the screensaver + * is prohibited from starting. + * + * Window systems put limits on window sizes. Very large or very small window + * dimensions may be overridden by the window system on creation. Check the + * actual [size](@ref window_size) after creation. + * + * The [swap interval](@ref buffer_swap) is not set during window creation and + * the initial value may vary depending on driver settings and defaults. + * + * @param[in] width The desired width, in screen coordinates, of the window. + * This must be greater than zero. + * @param[in] height The desired height, in screen coordinates, of the window. + * This must be greater than zero. + * @param[in] title The initial, UTF-8 encoded window title. + * @param[in] monitor The monitor to use for full screen mode, or `NULL` for + * windowed mode. + * @param[in] share The window whose context to share resources with, or `NULL` + * to not share resources. + * @return The handle of the created window, or `NULL` if an + * [error](@ref error_handling) occurred. + * + * @errors Possible errors include @ref GLFW_NOT_INITIALIZED, @ref + * GLFW_INVALID_ENUM, @ref GLFW_INVALID_VALUE, @ref GLFW_API_UNAVAILABLE, @ref + * GLFW_VERSION_UNAVAILABLE, @ref GLFW_FORMAT_UNAVAILABLE, @ref + * GLFW_NO_WINDOW_CONTEXT and @ref GLFW_PLATFORM_ERROR. + * + * @remark @win32 Window creation will fail if the Microsoft GDI software + * OpenGL implementation is the only one available. + * + * @remark @win32 If the executable has an icon resource named `GLFW_ICON,` it + * will be set as the initial icon for the window. If no such icon is present, + * the `IDI_APPLICATION` icon will be used instead. To set a different icon, + * see @ref glfwSetWindowIcon. + * + * @remark @win32 The context to share resources with must not be current on + * any other thread. + * + * @remark @macos The OS only supports core profile contexts for OpenGL + * versions 3.2 and later. Before creating an OpenGL context of version 3.2 or + * later you must set the [GLFW_OPENGL_PROFILE](@ref GLFW_OPENGL_PROFILE_hint) + * hint accordingly. OpenGL 3.0 and 3.1 contexts are not supported at all + * on macOS. + * + * @remark @macos The GLFW window has no icon, as it is not a document + * window, but the dock icon will be the same as the application bundle's icon. + * For more information on bundles, see the + * [Bundle Programming Guide][bundle-guide] in the Mac Developer Library. + * + * [bundle-guide]: https://developer.apple.com/library/mac/documentation/CoreFoundation/Conceptual/CFBundles/ + * + * @remark @macos On OS X 10.10 and later the window frame will not be rendered + * at full resolution on Retina displays unless the + * [GLFW_SCALE_FRAMEBUFFER](@ref GLFW_SCALE_FRAMEBUFFER_hint) + * hint is `GLFW_TRUE` and the `NSHighResolutionCapable` key is enabled in the + * application bundle's `Info.plist`. For more information, see + * [High Resolution Guidelines for OS X][hidpi-guide] in the Mac Developer + * Library. The GLFW test and example programs use a custom `Info.plist` + * template for this, which can be found as `CMake/Info.plist.in` in the source + * tree. + * + * [hidpi-guide]: https://developer.apple.com/library/mac/documentation/GraphicsAnimation/Conceptual/HighResolutionOSX/Explained/Explained.html + * + * @remark @macos When activating frame autosaving with + * [GLFW_COCOA_FRAME_NAME](@ref GLFW_COCOA_FRAME_NAME_hint), the specified + * window size and position may be overridden by previously saved values. + * + * @remark @wayland GLFW uses [libdecor][] where available to create its window + * decorations. This in turn uses server-side XDG decorations where available + * and provides high quality client-side decorations on compositors like GNOME. + * If both XDG decorations and libdecor are unavailable, GLFW falls back to + * a very simple set of window decorations that only support moving, resizing + * and the window manager's right-click menu. + * + * [libdecor]: https://gitlab.freedesktop.org/libdecor/libdecor + * + * @remark @x11 Some window managers will not respect the placement of + * initially hidden windows. + * + * @remark @x11 Due to the asynchronous nature of X11, it may take a moment for + * a window to reach its requested state. This means you may not be able to + * query the final size, position or other attributes directly after window + * creation. + * + * @remark @x11 The class part of the `WM_CLASS` window property will by + * default be set to the window title passed to this function. The instance + * part will use the contents of the `RESOURCE_NAME` environment variable, if + * present and not empty, or fall back to the window title. Set the + * [GLFW_X11_CLASS_NAME](@ref GLFW_X11_CLASS_NAME_hint) and + * [GLFW_X11_INSTANCE_NAME](@ref GLFW_X11_INSTANCE_NAME_hint) window hints to + * override this. + * + * @thread_safety This function must only be called from the main thread. + * + * @sa @ref window_creation + * @sa @ref glfwDestroyWindow + * + * @since Added in version 3.0. Replaces `glfwOpenWindow`. + * + * @ingroup window + */ +GLFWAPI GLFWwindow* glfwCreateWindow(int width, int height, const char* title, GLFWmonitor* monitor, GLFWwindow* share); + +/*! @brief Destroys the specified window and its context. + * + * This function destroys the specified window and its context. On calling + * this function, no further callbacks will be called for that window. + * + * If the context of the specified window is current on the main thread, it is + * detached before being destroyed. + * + * @param[in] window The window to destroy. + * + * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref + * GLFW_PLATFORM_ERROR. + * + * @note The context of the specified window must not be current on any other + * thread when this function is called. + * + * @reentrancy This function must not be called from a callback. + * + * @thread_safety This function must only be called from the main thread. + * + * @sa @ref window_creation + * @sa @ref glfwCreateWindow + * + * @since Added in version 3.0. Replaces `glfwCloseWindow`. + * + * @ingroup window + */ +GLFWAPI void glfwDestroyWindow(GLFWwindow* window); + +/*! @brief Checks the close flag of the specified window. + * + * This function returns the value of the close flag of the specified window. + * + * @param[in] window The window to query. + * @return The value of the close flag. + * + * @errors Possible errors include @ref GLFW_NOT_INITIALIZED. + * + * @thread_safety This function may be called from any thread. Access is not + * synchronized. + * + * @sa @ref window_close + * + * @since Added in version 3.0. + * + * @ingroup window + */ +GLFWAPI int glfwWindowShouldClose(GLFWwindow* window); + +/*! @brief Sets the close flag of the specified window. + * + * This function sets the value of the close flag of the specified window. + * This can be used to override the user's attempt to close the window, or + * to signal that it should be closed. + * + * @param[in] window The window whose flag to change. + * @param[in] value The new value. + * + * @errors Possible errors include @ref GLFW_NOT_INITIALIZED. + * + * @thread_safety This function may be called from any thread. Access is not + * synchronized. + * + * @sa @ref window_close + * + * @since Added in version 3.0. + * + * @ingroup window + */ +GLFWAPI void glfwSetWindowShouldClose(GLFWwindow* window, int value); + +/*! @brief Returns the title of the specified window. + * + * This function returns the window title, encoded as UTF-8, of the specified + * window. This is the title set previously by @ref glfwCreateWindow + * or @ref glfwSetWindowTitle. + * + * @param[in] window The window to query. + * @return The UTF-8 encoded window title, or `NULL` if an + * [error](@ref error_handling) occurred. + * + * @errors Possible errors include @ref GLFW_NOT_INITIALIZED. + * + * @remark The returned title is currently a copy of the title last set by @ref + * glfwCreateWindow or @ref glfwSetWindowTitle. It does not include any + * additional text which may be appended by the platform or another program. + * + * @pointer_lifetime The returned string is allocated and freed by GLFW. You + * should not free it yourself. It is valid until the next call to @ref + * glfwGetWindowTitle or @ref glfwSetWindowTitle, or until the library is + * terminated. + * + * @thread_safety This function must only be called from the main thread. + * + * @sa @ref window_title + * @sa @ref glfwSetWindowTitle + * + * @since Added in version 3.4. + * + * @ingroup window + */ +GLFWAPI const char* glfwGetWindowTitle(GLFWwindow* window); + +/*! @brief Sets the title of the specified window. + * + * This function sets the window title, encoded as UTF-8, of the specified + * window. + * + * @param[in] window The window whose title to change. + * @param[in] title The UTF-8 encoded window title. + * + * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref + * GLFW_PLATFORM_ERROR. + * + * @remark @macos The window title will not be updated until the next time you + * process events. + * + * @thread_safety This function must only be called from the main thread. + * + * @sa @ref window_title + * @sa @ref glfwGetWindowTitle + * + * @since Added in version 1.0. + * @glfw3 Added window handle parameter. + * + * @ingroup window + */ +GLFWAPI void glfwSetWindowTitle(GLFWwindow* window, const char* title); + +/*! @brief Sets the icon for the specified window. + * + * This function sets the icon of the specified window. If passed an array of + * candidate images, those of or closest to the sizes desired by the system are + * selected. If no images are specified, the window reverts to its default + * icon. + * + * The pixels are 32-bit, little-endian, non-premultiplied RGBA, i.e. eight + * bits per channel with the red channel first. They are arranged canonically + * as packed sequential rows, starting from the top-left corner. + * + * The desired image sizes varies depending on platform and system settings. + * The selected images will be rescaled as needed. Good sizes include 16x16, + * 32x32 and 48x48. + * + * @param[in] window The window whose icon to set. + * @param[in] count The number of images in the specified array, or zero to + * revert to the default window icon. + * @param[in] images The images to create the icon from. This is ignored if + * count is zero. + * + * @errors Possible errors include @ref GLFW_NOT_INITIALIZED, @ref + * GLFW_INVALID_VALUE, @ref GLFW_PLATFORM_ERROR and @ref + * GLFW_FEATURE_UNAVAILABLE (see remarks). + * + * @pointer_lifetime The specified image data is copied before this function + * returns. + * + * @remark @macos Regular windows do not have icons on macOS. This function + * will emit @ref GLFW_FEATURE_UNAVAILABLE. The dock icon will be the same as + * the application bundle's icon. For more information on bundles, see the + * [Bundle Programming Guide][bundle-guide] in the Mac Developer Library. + * + * [bundle-guide]: https://developer.apple.com/library/mac/documentation/CoreFoundation/Conceptual/CFBundles/ + * + * @remark @wayland There is no existing protocol to change an icon, the + * window will thus inherit the one defined in the application's desktop file. + * This function will emit @ref GLFW_FEATURE_UNAVAILABLE. + * + * @thread_safety This function must only be called from the main thread. + * + * @sa @ref window_icon + * + * @since Added in version 3.2. + * + * @ingroup window + */ +GLFWAPI void glfwSetWindowIcon(GLFWwindow* window, int count, const GLFWimage* images); + +/*! @brief Retrieves the position of the content area of the specified window. + * + * This function retrieves the position, in screen coordinates, of the + * upper-left corner of the content area of the specified window. + * + * Any or all of the position arguments may be `NULL`. If an error occurs, all + * non-`NULL` position arguments will be set to zero. + * + * @param[in] window The window to query. + * @param[out] xpos Where to store the x-coordinate of the upper-left corner of + * the content area, or `NULL`. + * @param[out] ypos Where to store the y-coordinate of the upper-left corner of + * the content area, or `NULL`. + * + * @errors Possible errors include @ref GLFW_NOT_INITIALIZED, @ref + * GLFW_PLATFORM_ERROR and @ref GLFW_FEATURE_UNAVAILABLE (see remarks). + * + * @remark @wayland There is no way for an application to retrieve the global + * position of its windows. This function will emit @ref + * GLFW_FEATURE_UNAVAILABLE. + * + * @thread_safety This function must only be called from the main thread. + * + * @sa @ref window_pos + * @sa @ref glfwSetWindowPos + * + * @since Added in version 3.0. + * + * @ingroup window + */ +GLFWAPI void glfwGetWindowPos(GLFWwindow* window, int* xpos, int* ypos); + +/*! @brief Sets the position of the content area of the specified window. + * + * This function sets the position, in screen coordinates, of the upper-left + * corner of the content area of the specified windowed mode window. If the + * window is a full screen window, this function does nothing. + * + * __Do not use this function__ to move an already visible window unless you + * have very good reasons for doing so, as it will confuse and annoy the user. + * + * The window manager may put limits on what positions are allowed. GLFW + * cannot and should not override these limits. + * + * @param[in] window The window to query. + * @param[in] xpos The x-coordinate of the upper-left corner of the content area. + * @param[in] ypos The y-coordinate of the upper-left corner of the content area. + * + * @errors Possible errors include @ref GLFW_NOT_INITIALIZED, @ref + * GLFW_PLATFORM_ERROR and @ref GLFW_FEATURE_UNAVAILABLE (see remarks). + * + * @remark @wayland There is no way for an application to set the global + * position of its windows. This function will emit @ref + * GLFW_FEATURE_UNAVAILABLE. + * + * @thread_safety This function must only be called from the main thread. + * + * @sa @ref window_pos + * @sa @ref glfwGetWindowPos + * + * @since Added in version 1.0. + * @glfw3 Added window handle parameter. + * + * @ingroup window + */ +GLFWAPI void glfwSetWindowPos(GLFWwindow* window, int xpos, int ypos); + +/*! @brief Retrieves the size of the content area of the specified window. + * + * This function retrieves the size, in screen coordinates, of the content area + * of the specified window. If you wish to retrieve the size of the + * framebuffer of the window in pixels, see @ref glfwGetFramebufferSize. + * + * Any or all of the size arguments may be `NULL`. If an error occurs, all + * non-`NULL` size arguments will be set to zero. + * + * @param[in] window The window whose size to retrieve. + * @param[out] width Where to store the width, in screen coordinates, of the + * content area, or `NULL`. + * @param[out] height Where to store the height, in screen coordinates, of the + * content area, or `NULL`. + * + * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref + * GLFW_PLATFORM_ERROR. + * + * @thread_safety This function must only be called from the main thread. + * + * @sa @ref window_size + * @sa @ref glfwSetWindowSize + * + * @since Added in version 1.0. + * @glfw3 Added window handle parameter. + * + * @ingroup window + */ +GLFWAPI void glfwGetWindowSize(GLFWwindow* window, int* width, int* height); + +/*! @brief Sets the size limits of the specified window. + * + * This function sets the size limits of the content area of the specified + * window. If the window is full screen, the size limits only take effect + * once it is made windowed. If the window is not resizable, this function + * does nothing. + * + * The size limits are applied immediately to a windowed mode window and may + * cause it to be resized. + * + * The maximum dimensions must be greater than or equal to the minimum + * dimensions and all must be greater than or equal to zero. + * + * @param[in] window The window to set limits for. + * @param[in] minwidth The minimum width, in screen coordinates, of the content + * area, or `GLFW_DONT_CARE`. + * @param[in] minheight The minimum height, in screen coordinates, of the + * content area, or `GLFW_DONT_CARE`. + * @param[in] maxwidth The maximum width, in screen coordinates, of the content + * area, or `GLFW_DONT_CARE`. + * @param[in] maxheight The maximum height, in screen coordinates, of the + * content area, or `GLFW_DONT_CARE`. + * + * @errors Possible errors include @ref GLFW_NOT_INITIALIZED, @ref + * GLFW_INVALID_VALUE and @ref GLFW_PLATFORM_ERROR. + * + * @remark If you set size limits and an aspect ratio that conflict, the + * results are undefined. + * + * @remark @wayland The size limits will not be applied until the window is + * actually resized, either by the user or by the compositor. + * + * @thread_safety This function must only be called from the main thread. + * + * @sa @ref window_sizelimits + * @sa @ref glfwSetWindowAspectRatio + * + * @since Added in version 3.2. + * + * @ingroup window + */ +GLFWAPI void glfwSetWindowSizeLimits(GLFWwindow* window, int minwidth, int minheight, int maxwidth, int maxheight); + +/*! @brief Sets the aspect ratio of the specified window. + * + * This function sets the required aspect ratio of the content area of the + * specified window. If the window is full screen, the aspect ratio only takes + * effect once it is made windowed. If the window is not resizable, this + * function does nothing. + * + * The aspect ratio is specified as a numerator and a denominator and both + * values must be greater than zero. For example, the common 16:9 aspect ratio + * is specified as 16 and 9, respectively. + * + * If the numerator and denominator is set to `GLFW_DONT_CARE` then the aspect + * ratio limit is disabled. + * + * The aspect ratio is applied immediately to a windowed mode window and may + * cause it to be resized. + * + * @param[in] window The window to set limits for. + * @param[in] numer The numerator of the desired aspect ratio, or + * `GLFW_DONT_CARE`. + * @param[in] denom The denominator of the desired aspect ratio, or + * `GLFW_DONT_CARE`. + * + * @errors Possible errors include @ref GLFW_NOT_INITIALIZED, @ref + * GLFW_INVALID_VALUE and @ref GLFW_PLATFORM_ERROR. + * + * @remark If you set size limits and an aspect ratio that conflict, the + * results are undefined. + * + * @remark @wayland The aspect ratio will not be applied until the window is + * actually resized, either by the user or by the compositor. + * + * @thread_safety This function must only be called from the main thread. + * + * @sa @ref window_sizelimits + * @sa @ref glfwSetWindowSizeLimits + * + * @since Added in version 3.2. + * + * @ingroup window + */ +GLFWAPI void glfwSetWindowAspectRatio(GLFWwindow* window, int numer, int denom); + +/*! @brief Sets the size of the content area of the specified window. + * + * This function sets the size, in screen coordinates, of the content area of + * the specified window. + * + * For full screen windows, this function updates the resolution of its desired + * video mode and switches to the video mode closest to it, without affecting + * the window's context. As the context is unaffected, the bit depths of the + * framebuffer remain unchanged. + * + * If you wish to update the refresh rate of the desired video mode in addition + * to its resolution, see @ref glfwSetWindowMonitor. + * + * The window manager may put limits on what sizes are allowed. GLFW cannot + * and should not override these limits. + * + * @param[in] window The window to resize. + * @param[in] width The desired width, in screen coordinates, of the window + * content area. + * @param[in] height The desired height, in screen coordinates, of the window + * content area. + * + * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref + * GLFW_PLATFORM_ERROR. + * + * @thread_safety This function must only be called from the main thread. + * + * @sa @ref window_size + * @sa @ref glfwGetWindowSize + * @sa @ref glfwSetWindowMonitor + * + * @since Added in version 1.0. + * @glfw3 Added window handle parameter. + * + * @ingroup window + */ +GLFWAPI void glfwSetWindowSize(GLFWwindow* window, int width, int height); + +/*! @brief Retrieves the size of the framebuffer of the specified window. + * + * This function retrieves the size, in pixels, of the framebuffer of the + * specified window. If you wish to retrieve the size of the window in screen + * coordinates, see @ref glfwGetWindowSize. + * + * Any or all of the size arguments may be `NULL`. If an error occurs, all + * non-`NULL` size arguments will be set to zero. + * + * @param[in] window The window whose framebuffer to query. + * @param[out] width Where to store the width, in pixels, of the framebuffer, + * or `NULL`. + * @param[out] height Where to store the height, in pixels, of the framebuffer, + * or `NULL`. + * + * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref + * GLFW_PLATFORM_ERROR. + * + * @thread_safety This function must only be called from the main thread. + * + * @sa @ref window_fbsize + * @sa @ref glfwSetFramebufferSizeCallback + * + * @since Added in version 3.0. + * + * @ingroup window + */ +GLFWAPI void glfwGetFramebufferSize(GLFWwindow* window, int* width, int* height); + +/*! @brief Retrieves the size of the frame of the window. + * + * This function retrieves the size, in screen coordinates, of each edge of the + * frame of the specified window. This size includes the title bar, if the + * window has one. The size of the frame may vary depending on the + * [window-related hints](@ref window_hints_wnd) used to create it. + * + * Because this function retrieves the size of each window frame edge and not + * the offset along a particular coordinate axis, the retrieved values will + * always be zero or positive. + * + * Any or all of the size arguments may be `NULL`. If an error occurs, all + * non-`NULL` size arguments will be set to zero. + * + * @param[in] window The window whose frame size to query. + * @param[out] left Where to store the size, in screen coordinates, of the left + * edge of the window frame, or `NULL`. + * @param[out] top Where to store the size, in screen coordinates, of the top + * edge of the window frame, or `NULL`. + * @param[out] right Where to store the size, in screen coordinates, of the + * right edge of the window frame, or `NULL`. + * @param[out] bottom Where to store the size, in screen coordinates, of the + * bottom edge of the window frame, or `NULL`. + * + * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref + * GLFW_PLATFORM_ERROR. + * + * @thread_safety This function must only be called from the main thread. + * + * @sa @ref window_size + * + * @since Added in version 3.1. + * + * @ingroup window + */ +GLFWAPI void glfwGetWindowFrameSize(GLFWwindow* window, int* left, int* top, int* right, int* bottom); + +/*! @brief Retrieves the content scale for the specified window. + * + * This function retrieves the content scale for the specified window. The + * content scale is the ratio between the current DPI and the platform's + * default DPI. This is especially important for text and any UI elements. If + * the pixel dimensions of your UI scaled by this look appropriate on your + * machine then it should appear at a reasonable size on other machines + * regardless of their DPI and scaling settings. This relies on the system DPI + * and scaling settings being somewhat correct. + * + * On platforms where each monitors can have its own content scale, the window + * content scale will depend on which monitor the system considers the window + * to be on. + * + * @param[in] window The window to query. + * @param[out] xscale Where to store the x-axis content scale, or `NULL`. + * @param[out] yscale Where to store the y-axis content scale, or `NULL`. + * + * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref + * GLFW_PLATFORM_ERROR. + * + * @thread_safety This function must only be called from the main thread. + * + * @sa @ref window_scale + * @sa @ref glfwSetWindowContentScaleCallback + * @sa @ref glfwGetMonitorContentScale + * + * @since Added in version 3.3. + * + * @ingroup window + */ +GLFWAPI void glfwGetWindowContentScale(GLFWwindow* window, float* xscale, float* yscale); + +/*! @brief Returns the opacity of the whole window. + * + * This function returns the opacity of the window, including any decorations. + * + * The opacity (or alpha) value is a positive finite number between zero and + * one, where zero is fully transparent and one is fully opaque. If the system + * does not support whole window transparency, this function always returns one. + * + * The initial opacity value for newly created windows is one. + * + * @param[in] window The window to query. + * @return The opacity value of the specified window. + * + * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref + * GLFW_PLATFORM_ERROR. + * + * @thread_safety This function must only be called from the main thread. + * + * @sa @ref window_transparency + * @sa @ref glfwSetWindowOpacity + * + * @since Added in version 3.3. + * + * @ingroup window + */ +GLFWAPI float glfwGetWindowOpacity(GLFWwindow* window); + +/*! @brief Sets the opacity of the whole window. + * + * This function sets the opacity of the window, including any decorations. + * + * The opacity (or alpha) value is a positive finite number between zero and + * one, where zero is fully transparent and one is fully opaque. + * + * The initial opacity value for newly created windows is one. + * + * A window created with framebuffer transparency may not use whole window + * transparency. The results of doing this are undefined. + * + * @param[in] window The window to set the opacity for. + * @param[in] opacity The desired opacity of the specified window. + * + * @errors Possible errors include @ref GLFW_NOT_INITIALIZED, @ref + * GLFW_PLATFORM_ERROR and @ref GLFW_FEATURE_UNAVAILABLE (see remarks). + * + * @remark @wayland There is no way to set an opacity factor for a window. + * This function will emit @ref GLFW_FEATURE_UNAVAILABLE. + * + * @thread_safety This function must only be called from the main thread. + * + * @sa @ref window_transparency + * @sa @ref glfwGetWindowOpacity + * + * @since Added in version 3.3. + * + * @ingroup window + */ +GLFWAPI void glfwSetWindowOpacity(GLFWwindow* window, float opacity); + +/*! @brief Iconifies the specified window. + * + * This function iconifies (minimizes) the specified window if it was + * previously restored. If the window is already iconified, this function does + * nothing. + * + * If the specified window is a full screen window, GLFW restores the original + * video mode of the monitor. The window's desired video mode is set again + * when the window is restored. + * + * @param[in] window The window to iconify. + * + * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref + * GLFW_PLATFORM_ERROR. + * + * @remark @wayland Once a window is iconified, @ref glfwRestoreWindow won’t + * be able to restore it. This is a design decision of the xdg-shell + * protocol. + * + * @thread_safety This function must only be called from the main thread. + * + * @sa @ref window_iconify + * @sa @ref glfwRestoreWindow + * @sa @ref glfwMaximizeWindow + * + * @since Added in version 2.1. + * @glfw3 Added window handle parameter. + * + * @ingroup window + */ +GLFWAPI void glfwIconifyWindow(GLFWwindow* window); + +/*! @brief Restores the specified window. + * + * This function restores the specified window if it was previously iconified + * (minimized) or maximized. If the window is already restored, this function + * does nothing. + * + * If the specified window is an iconified full screen window, its desired + * video mode is set again for its monitor when the window is restored. + * + * @param[in] window The window to restore. + * + * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref + * GLFW_PLATFORM_ERROR. + * + * @thread_safety This function must only be called from the main thread. + * + * @sa @ref window_iconify + * @sa @ref glfwIconifyWindow + * @sa @ref glfwMaximizeWindow + * + * @since Added in version 2.1. + * @glfw3 Added window handle parameter. + * + * @ingroup window + */ +GLFWAPI void glfwRestoreWindow(GLFWwindow* window); + +/*! @brief Maximizes the specified window. + * + * This function maximizes the specified window if it was previously not + * maximized. If the window is already maximized, this function does nothing. + * + * If the specified window is a full screen window, this function does nothing. + * + * @param[in] window The window to maximize. + * + * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref + * GLFW_PLATFORM_ERROR. + * + * @par Thread Safety + * This function may only be called from the main thread. + * + * @sa @ref window_iconify + * @sa @ref glfwIconifyWindow + * @sa @ref glfwRestoreWindow + * + * @since Added in GLFW 3.2. + * + * @ingroup window + */ +GLFWAPI void glfwMaximizeWindow(GLFWwindow* window); + +/*! @brief Makes the specified window visible. + * + * This function makes the specified window visible if it was previously + * hidden. If the window is already visible or is in full screen mode, this + * function does nothing. + * + * By default, windowed mode windows are focused when shown + * Set the [GLFW_FOCUS_ON_SHOW](@ref GLFW_FOCUS_ON_SHOW_hint) window hint + * to change this behavior for all newly created windows, or change the + * behavior for an existing window with @ref glfwSetWindowAttrib. + * + * @param[in] window The window to make visible. + * + * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref + * GLFW_PLATFORM_ERROR. + * + * @remark @wayland Because Wayland wants every frame of the desktop to be + * complete, this function does not immediately make the window visible. + * Instead it will become visible the next time the window framebuffer is + * updated after this call. + * + * @thread_safety This function must only be called from the main thread. + * + * @sa @ref window_hide + * @sa @ref glfwHideWindow + * + * @since Added in version 3.0. + * + * @ingroup window + */ +GLFWAPI void glfwShowWindow(GLFWwindow* window); + +/*! @brief Hides the specified window. + * + * This function hides the specified window if it was previously visible. If + * the window is already hidden or is in full screen mode, this function does + * nothing. + * + * @param[in] window The window to hide. + * + * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref + * GLFW_PLATFORM_ERROR. + * + * @thread_safety This function must only be called from the main thread. + * + * @sa @ref window_hide + * @sa @ref glfwShowWindow + * + * @since Added in version 3.0. + * + * @ingroup window + */ +GLFWAPI void glfwHideWindow(GLFWwindow* window); + +/*! @brief Brings the specified window to front and sets input focus. + * + * This function brings the specified window to front and sets input focus. + * The window should already be visible and not iconified. + * + * By default, both windowed and full screen mode windows are focused when + * initially created. Set the [GLFW_FOCUSED](@ref GLFW_FOCUSED_hint) to + * disable this behavior. + * + * Also by default, windowed mode windows are focused when shown + * with @ref glfwShowWindow. Set the + * [GLFW_FOCUS_ON_SHOW](@ref GLFW_FOCUS_ON_SHOW_hint) to disable this behavior. + * + * __Do not use this function__ to steal focus from other applications unless + * you are certain that is what the user wants. Focus stealing can be + * extremely disruptive. + * + * For a less disruptive way of getting the user's attention, see + * [attention requests](@ref window_attention). + * + * @param[in] window The window to give input focus. + * + * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref + * GLFW_PLATFORM_ERROR. + * + * @remark @wayland The compositor will likely ignore focus requests unless + * another window created by the same application already has input focus. + * + * @thread_safety This function must only be called from the main thread. + * + * @sa @ref window_focus + * @sa @ref window_attention + * + * @since Added in version 3.2. + * + * @ingroup window + */ +GLFWAPI void glfwFocusWindow(GLFWwindow* window); + +/*! @brief Requests user attention to the specified window. + * + * This function requests user attention to the specified window. On + * platforms where this is not supported, attention is requested to the + * application as a whole. + * + * Once the user has given attention, usually by focusing the window or + * application, the system will end the request automatically. + * + * @param[in] window The window to request attention to. + * + * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref + * GLFW_PLATFORM_ERROR. + * + * @remark @macos Attention is requested to the application as a whole, not the + * specific window. + * + * @thread_safety This function must only be called from the main thread. + * + * @sa @ref window_attention + * + * @since Added in version 3.3. + * + * @ingroup window + */ +GLFWAPI void glfwRequestWindowAttention(GLFWwindow* window); + +/*! @brief Returns the monitor that the window uses for full screen mode. + * + * This function returns the handle of the monitor that the specified window is + * in full screen on. + * + * @param[in] window The window to query. + * @return The monitor, or `NULL` if the window is in windowed mode or an + * [error](@ref error_handling) occurred. + * + * @errors Possible errors include @ref GLFW_NOT_INITIALIZED. + * + * @thread_safety This function must only be called from the main thread. + * + * @sa @ref window_monitor + * @sa @ref glfwSetWindowMonitor + * + * @since Added in version 3.0. + * + * @ingroup window + */ +GLFWAPI GLFWmonitor* glfwGetWindowMonitor(GLFWwindow* window); + +/*! @brief Sets the mode, monitor, video mode and placement of a window. + * + * This function sets the monitor that the window uses for full screen mode or, + * if the monitor is `NULL`, makes it windowed mode. + * + * When setting a monitor, this function updates the width, height and refresh + * rate of the desired video mode and switches to the video mode closest to it. + * The window position is ignored when setting a monitor. + * + * When the monitor is `NULL`, the position, width and height are used to + * place the window content area. The refresh rate is ignored when no monitor + * is specified. + * + * If you only wish to update the resolution of a full screen window or the + * size of a windowed mode window, see @ref glfwSetWindowSize. + * + * When a window transitions from full screen to windowed mode, this function + * restores any previous window settings such as whether it is decorated, + * floating, resizable, has size or aspect ratio limits, etc. + * + * @param[in] window The window whose monitor, size or video mode to set. + * @param[in] monitor The desired monitor, or `NULL` to set windowed mode. + * @param[in] xpos The desired x-coordinate of the upper-left corner of the + * content area. + * @param[in] ypos The desired y-coordinate of the upper-left corner of the + * content area. + * @param[in] width The desired with, in screen coordinates, of the content + * area or video mode. + * @param[in] height The desired height, in screen coordinates, of the content + * area or video mode. + * @param[in] refreshRate The desired refresh rate, in Hz, of the video mode, + * or `GLFW_DONT_CARE`. + * + * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref + * GLFW_PLATFORM_ERROR. + * + * @remark The OpenGL or OpenGL ES context will not be destroyed or otherwise + * affected by any resizing or mode switching, although you may need to update + * your viewport if the framebuffer size has changed. + * + * @remark @wayland The desired window position is ignored, as there is no way + * for an application to set this property. + * + * @thread_safety This function must only be called from the main thread. + * + * @sa @ref window_monitor + * @sa @ref window_full_screen + * @sa @ref glfwGetWindowMonitor + * @sa @ref glfwSetWindowSize + * + * @since Added in version 3.2. + * + * @ingroup window + */ +GLFWAPI void glfwSetWindowMonitor(GLFWwindow* window, GLFWmonitor* monitor, int xpos, int ypos, int width, int height, int refreshRate); + +/*! @brief Returns an attribute of the specified window. + * + * This function returns the value of an attribute of the specified window or + * its OpenGL or OpenGL ES context. + * + * @param[in] window The window to query. + * @param[in] attrib The [window attribute](@ref window_attribs) whose value to + * return. + * @return The value of the attribute, or zero if an + * [error](@ref error_handling) occurred. + * + * @errors Possible errors include @ref GLFW_NOT_INITIALIZED, @ref + * GLFW_INVALID_ENUM and @ref GLFW_PLATFORM_ERROR. + * + * @remark Framebuffer related hints are not window attributes. See @ref + * window_attribs_fb for more information. + * + * @remark Zero is a valid value for many window and context related + * attributes so you cannot use a return value of zero as an indication of + * errors. However, this function should not fail as long as it is passed + * valid arguments and the library has been [initialized](@ref intro_init). + * + * @remark @wayland The Wayland protocol provides no way to check whether a + * window is iconfied, so @ref GLFW_ICONIFIED always returns `GLFW_FALSE`. + * + * @thread_safety This function must only be called from the main thread. + * + * @sa @ref window_attribs + * @sa @ref glfwSetWindowAttrib + * + * @since Added in version 3.0. Replaces `glfwGetWindowParam` and + * `glfwGetGLVersion`. + * + * @ingroup window + */ +GLFWAPI int glfwGetWindowAttrib(GLFWwindow* window, int attrib); + +/*! @brief Sets an attribute of the specified window. + * + * This function sets the value of an attribute of the specified window. + * + * The supported attributes are [GLFW_DECORATED](@ref GLFW_DECORATED_attrib), + * [GLFW_RESIZABLE](@ref GLFW_RESIZABLE_attrib), + * [GLFW_FLOATING](@ref GLFW_FLOATING_attrib), + * [GLFW_AUTO_ICONIFY](@ref GLFW_AUTO_ICONIFY_attrib) and + * [GLFW_FOCUS_ON_SHOW](@ref GLFW_FOCUS_ON_SHOW_attrib). + * [GLFW_MOUSE_PASSTHROUGH](@ref GLFW_MOUSE_PASSTHROUGH_attrib) + * + * Some of these attributes are ignored for full screen windows. The new + * value will take effect if the window is later made windowed. + * + * Some of these attributes are ignored for windowed mode windows. The new + * value will take effect if the window is later made full screen. + * + * @param[in] window The window to set the attribute for. + * @param[in] attrib A supported window attribute. + * @param[in] value `GLFW_TRUE` or `GLFW_FALSE`. + * + * @errors Possible errors include @ref GLFW_NOT_INITIALIZED, @ref + * GLFW_INVALID_ENUM, @ref GLFW_INVALID_VALUE, @ref GLFW_PLATFORM_ERROR and @ref + * GLFW_FEATURE_UNAVAILABLE (see remarks). + * + * @remark Calling @ref glfwGetWindowAttrib will always return the latest + * value, even if that value is ignored by the current mode of the window. + * + * @remark @wayland The [GLFW_FLOATING](@ref GLFW_FLOATING_attrib) window attribute is + * not supported. Setting this will emit @ref GLFW_FEATURE_UNAVAILABLE. + * + * @thread_safety This function must only be called from the main thread. + * + * @sa @ref window_attribs + * @sa @ref glfwGetWindowAttrib + * + * @since Added in version 3.3. + * + * @ingroup window + */ +GLFWAPI void glfwSetWindowAttrib(GLFWwindow* window, int attrib, int value); + +/*! @brief Sets the user pointer of the specified window. + * + * This function sets the user-defined pointer of the specified window. The + * current value is retained until the window is destroyed. The initial value + * is `NULL`. + * + * @param[in] window The window whose pointer to set. + * @param[in] pointer The new value. + * + * @errors Possible errors include @ref GLFW_NOT_INITIALIZED. + * + * @thread_safety This function may be called from any thread. Access is not + * synchronized. + * + * @sa @ref window_userptr + * @sa @ref glfwGetWindowUserPointer + * + * @since Added in version 3.0. + * + * @ingroup window + */ +GLFWAPI void glfwSetWindowUserPointer(GLFWwindow* window, void* pointer); + +/*! @brief Returns the user pointer of the specified window. + * + * This function returns the current value of the user-defined pointer of the + * specified window. The initial value is `NULL`. + * + * @param[in] window The window whose pointer to return. + * + * @errors Possible errors include @ref GLFW_NOT_INITIALIZED. + * + * @thread_safety This function may be called from any thread. Access is not + * synchronized. + * + * @sa @ref window_userptr + * @sa @ref glfwSetWindowUserPointer + * + * @since Added in version 3.0. + * + * @ingroup window + */ +GLFWAPI void* glfwGetWindowUserPointer(GLFWwindow* window); + +/*! @brief Sets the position callback for the specified window. + * + * This function sets the position callback of the specified window, which is + * called when the window is moved. The callback is provided with the + * position, in screen coordinates, of the upper-left corner of the content + * area of the window. + * + * @param[in] window The window whose callback to set. + * @param[in] callback The new callback, or `NULL` to remove the currently set + * callback. + * @return The previously set callback, or `NULL` if no callback was set or the + * library had not been [initialized](@ref intro_init). + * + * @callback_signature + * @code + * void function_name(GLFWwindow* window, int xpos, int ypos) + * @endcode + * For more information about the callback parameters, see the + * [function pointer type](@ref GLFWwindowposfun). + * + * @errors Possible errors include @ref GLFW_NOT_INITIALIZED. + * + * @remark @wayland This callback will never be called, as there is no way for + * an application to know its global position. + * + * @thread_safety This function must only be called from the main thread. + * + * @sa @ref window_pos + * + * @since Added in version 3.0. + * + * @ingroup window + */ +GLFWAPI GLFWwindowposfun glfwSetWindowPosCallback(GLFWwindow* window, GLFWwindowposfun callback); + +/*! @brief Sets the size callback for the specified window. + * + * This function sets the size callback of the specified window, which is + * called when the window is resized. The callback is provided with the size, + * in screen coordinates, of the content area of the window. + * + * @param[in] window The window whose callback to set. + * @param[in] callback The new callback, or `NULL` to remove the currently set + * callback. + * @return The previously set callback, or `NULL` if no callback was set or the + * library had not been [initialized](@ref intro_init). + * + * @callback_signature + * @code + * void function_name(GLFWwindow* window, int width, int height) + * @endcode + * For more information about the callback parameters, see the + * [function pointer type](@ref GLFWwindowsizefun). + * + * @errors Possible errors include @ref GLFW_NOT_INITIALIZED. + * + * @thread_safety This function must only be called from the main thread. + * + * @sa @ref window_size + * + * @since Added in version 1.0. + * @glfw3 Added window handle parameter and return value. + * + * @ingroup window + */ +GLFWAPI GLFWwindowsizefun glfwSetWindowSizeCallback(GLFWwindow* window, GLFWwindowsizefun callback); + +/*! @brief Sets the close callback for the specified window. + * + * This function sets the close callback of the specified window, which is + * called when the user attempts to close the window, for example by clicking + * the close widget in the title bar. + * + * The close flag is set before this callback is called, but you can modify it + * at any time with @ref glfwSetWindowShouldClose. + * + * The close callback is not triggered by @ref glfwDestroyWindow. + * + * @param[in] window The window whose callback to set. + * @param[in] callback The new callback, or `NULL` to remove the currently set + * callback. + * @return The previously set callback, or `NULL` if no callback was set or the + * library had not been [initialized](@ref intro_init). + * + * @callback_signature + * @code + * void function_name(GLFWwindow* window) + * @endcode + * For more information about the callback parameters, see the + * [function pointer type](@ref GLFWwindowclosefun). + * + * @errors Possible errors include @ref GLFW_NOT_INITIALIZED. + * + * @remark @macos Selecting Quit from the application menu will trigger the + * close callback for all windows. + * + * @thread_safety This function must only be called from the main thread. + * + * @sa @ref window_close + * + * @since Added in version 2.5. + * @glfw3 Added window handle parameter and return value. + * + * @ingroup window + */ +GLFWAPI GLFWwindowclosefun glfwSetWindowCloseCallback(GLFWwindow* window, GLFWwindowclosefun callback); + +/*! @brief Sets the refresh callback for the specified window. + * + * This function sets the refresh callback of the specified window, which is + * called when the content area of the window needs to be redrawn, for example + * if the window has been exposed after having been covered by another window. + * + * On compositing window systems such as Aero, Compiz, Aqua or Wayland, where + * the window contents are saved off-screen, this callback may be called only + * very infrequently or never at all. + * + * @param[in] window The window whose callback to set. + * @param[in] callback The new callback, or `NULL` to remove the currently set + * callback. + * @return The previously set callback, or `NULL` if no callback was set or the + * library had not been [initialized](@ref intro_init). + * + * @callback_signature + * @code + * void function_name(GLFWwindow* window); + * @endcode + * For more information about the callback parameters, see the + * [function pointer type](@ref GLFWwindowrefreshfun). + * + * @errors Possible errors include @ref GLFW_NOT_INITIALIZED. + * + * @thread_safety This function must only be called from the main thread. + * + * @sa @ref window_refresh + * + * @since Added in version 2.5. + * @glfw3 Added window handle parameter and return value. + * + * @ingroup window + */ +GLFWAPI GLFWwindowrefreshfun glfwSetWindowRefreshCallback(GLFWwindow* window, GLFWwindowrefreshfun callback); + +/*! @brief Sets the focus callback for the specified window. + * + * This function sets the focus callback of the specified window, which is + * called when the window gains or loses input focus. + * + * After the focus callback is called for a window that lost input focus, + * synthetic key and mouse button release events will be generated for all such + * that had been pressed. For more information, see @ref glfwSetKeyCallback + * and @ref glfwSetMouseButtonCallback. + * + * @param[in] window The window whose callback to set. + * @param[in] callback The new callback, or `NULL` to remove the currently set + * callback. + * @return The previously set callback, or `NULL` if no callback was set or the + * library had not been [initialized](@ref intro_init). + * + * @callback_signature + * @code + * void function_name(GLFWwindow* window, int focused) + * @endcode + * For more information about the callback parameters, see the + * [function pointer type](@ref GLFWwindowfocusfun). + * + * @errors Possible errors include @ref GLFW_NOT_INITIALIZED. + * + * @thread_safety This function must only be called from the main thread. + * + * @sa @ref window_focus + * + * @since Added in version 3.0. + * + * @ingroup window + */ +GLFWAPI GLFWwindowfocusfun glfwSetWindowFocusCallback(GLFWwindow* window, GLFWwindowfocusfun callback); + +/*! @brief Sets the iconify callback for the specified window. + * + * This function sets the iconification callback of the specified window, which + * is called when the window is iconified or restored. + * + * @param[in] window The window whose callback to set. + * @param[in] callback The new callback, or `NULL` to remove the currently set + * callback. + * @return The previously set callback, or `NULL` if no callback was set or the + * library had not been [initialized](@ref intro_init). + * + * @callback_signature + * @code + * void function_name(GLFWwindow* window, int iconified) + * @endcode + * For more information about the callback parameters, see the + * [function pointer type](@ref GLFWwindowiconifyfun). + * + * @errors Possible errors include @ref GLFW_NOT_INITIALIZED. + * + * @thread_safety This function must only be called from the main thread. + * + * @sa @ref window_iconify + * + * @since Added in version 3.0. + * + * @ingroup window + */ +GLFWAPI GLFWwindowiconifyfun glfwSetWindowIconifyCallback(GLFWwindow* window, GLFWwindowiconifyfun callback); + +/*! @brief Sets the maximize callback for the specified window. + * + * This function sets the maximization callback of the specified window, which + * is called when the window is maximized or restored. + * + * @param[in] window The window whose callback to set. + * @param[in] callback The new callback, or `NULL` to remove the currently set + * callback. + * @return The previously set callback, or `NULL` if no callback was set or the + * library had not been [initialized](@ref intro_init). + * + * @callback_signature + * @code + * void function_name(GLFWwindow* window, int maximized) + * @endcode + * For more information about the callback parameters, see the + * [function pointer type](@ref GLFWwindowmaximizefun). + * + * @errors Possible errors include @ref GLFW_NOT_INITIALIZED. + * + * @thread_safety This function must only be called from the main thread. + * + * @sa @ref window_maximize + * + * @since Added in version 3.3. + * + * @ingroup window + */ +GLFWAPI GLFWwindowmaximizefun glfwSetWindowMaximizeCallback(GLFWwindow* window, GLFWwindowmaximizefun callback); + +/*! @brief Sets the framebuffer resize callback for the specified window. + * + * This function sets the framebuffer resize callback of the specified window, + * which is called when the framebuffer of the specified window is resized. + * + * @param[in] window The window whose callback to set. + * @param[in] callback The new callback, or `NULL` to remove the currently set + * callback. + * @return The previously set callback, or `NULL` if no callback was set or the + * library had not been [initialized](@ref intro_init). + * + * @callback_signature + * @code + * void function_name(GLFWwindow* window, int width, int height) + * @endcode + * For more information about the callback parameters, see the + * [function pointer type](@ref GLFWframebuffersizefun). + * + * @errors Possible errors include @ref GLFW_NOT_INITIALIZED. + * + * @thread_safety This function must only be called from the main thread. + * + * @sa @ref window_fbsize + * + * @since Added in version 3.0. + * + * @ingroup window + */ +GLFWAPI GLFWframebuffersizefun glfwSetFramebufferSizeCallback(GLFWwindow* window, GLFWframebuffersizefun callback); + +/*! @brief Sets the window content scale callback for the specified window. + * + * This function sets the window content scale callback of the specified window, + * which is called when the content scale of the specified window changes. + * + * @param[in] window The window whose callback to set. + * @param[in] callback The new callback, or `NULL` to remove the currently set + * callback. + * @return The previously set callback, or `NULL` if no callback was set or the + * library had not been [initialized](@ref intro_init). + * + * @callback_signature + * @code + * void function_name(GLFWwindow* window, float xscale, float yscale) + * @endcode + * For more information about the callback parameters, see the + * [function pointer type](@ref GLFWwindowcontentscalefun). + * + * @errors Possible errors include @ref GLFW_NOT_INITIALIZED. + * + * @thread_safety This function must only be called from the main thread. + * + * @sa @ref window_scale + * @sa @ref glfwGetWindowContentScale + * + * @since Added in version 3.3. + * + * @ingroup window + */ +GLFWAPI GLFWwindowcontentscalefun glfwSetWindowContentScaleCallback(GLFWwindow* window, GLFWwindowcontentscalefun callback); + +/*! @brief Processes all pending events. + * + * This function processes only those events that are already in the event + * queue and then returns immediately. Processing events will cause the window + * and input callbacks associated with those events to be called. + * + * On some platforms, a window move, resize or menu operation will cause event + * processing to block. This is due to how event processing is designed on + * those platforms. You can use the + * [window refresh callback](@ref window_refresh) to redraw the contents of + * your window when necessary during such operations. + * + * Do not assume that callbacks you set will _only_ be called in response to + * event processing functions like this one. While it is necessary to poll for + * events, window systems that require GLFW to register callbacks of its own + * can pass events to GLFW in response to many window system function calls. + * GLFW will pass those events on to the application callbacks before + * returning. + * + * Event processing is not required for joystick input to work. + * + * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref + * GLFW_PLATFORM_ERROR. + * + * @reentrancy This function must not be called from a callback. + * + * @thread_safety This function must only be called from the main thread. + * + * @sa @ref events + * @sa @ref glfwWaitEvents + * @sa @ref glfwWaitEventsTimeout + * + * @since Added in version 1.0. + * + * @ingroup window + */ +GLFWAPI void glfwPollEvents(void); + +/*! @brief Waits until events are queued and processes them. + * + * This function puts the calling thread to sleep until at least one event is + * available in the event queue. Once one or more events are available, + * it behaves exactly like @ref glfwPollEvents, i.e. the events in the queue + * are processed and the function then returns immediately. Processing events + * will cause the window and input callbacks associated with those events to be + * called. + * + * Since not all events are associated with callbacks, this function may return + * without a callback having been called even if you are monitoring all + * callbacks. + * + * On some platforms, a window move, resize or menu operation will cause event + * processing to block. This is due to how event processing is designed on + * those platforms. You can use the + * [window refresh callback](@ref window_refresh) to redraw the contents of + * your window when necessary during such operations. + * + * Do not assume that callbacks you set will _only_ be called in response to + * event processing functions like this one. While it is necessary to poll for + * events, window systems that require GLFW to register callbacks of its own + * can pass events to GLFW in response to many window system function calls. + * GLFW will pass those events on to the application callbacks before + * returning. + * + * Event processing is not required for joystick input to work. + * + * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref + * GLFW_PLATFORM_ERROR. + * + * @reentrancy This function must not be called from a callback. + * + * @thread_safety This function must only be called from the main thread. + * + * @sa @ref events + * @sa @ref glfwPollEvents + * @sa @ref glfwWaitEventsTimeout + * + * @since Added in version 2.5. + * + * @ingroup window + */ +GLFWAPI void glfwWaitEvents(void); + +/*! @brief Waits with timeout until events are queued and processes them. + * + * This function puts the calling thread to sleep until at least one event is + * available in the event queue, or until the specified timeout is reached. If + * one or more events are available, it behaves exactly like @ref + * glfwPollEvents, i.e. the events in the queue are processed and the function + * then returns immediately. Processing events will cause the window and input + * callbacks associated with those events to be called. + * + * The timeout value must be a positive finite number. + * + * Since not all events are associated with callbacks, this function may return + * without a callback having been called even if you are monitoring all + * callbacks. + * + * On some platforms, a window move, resize or menu operation will cause event + * processing to block. This is due to how event processing is designed on + * those platforms. You can use the + * [window refresh callback](@ref window_refresh) to redraw the contents of + * your window when necessary during such operations. + * + * Do not assume that callbacks you set will _only_ be called in response to + * event processing functions like this one. While it is necessary to poll for + * events, window systems that require GLFW to register callbacks of its own + * can pass events to GLFW in response to many window system function calls. + * GLFW will pass those events on to the application callbacks before + * returning. + * + * Event processing is not required for joystick input to work. + * + * @param[in] timeout The maximum amount of time, in seconds, to wait. + * + * @errors Possible errors include @ref GLFW_NOT_INITIALIZED, @ref + * GLFW_INVALID_VALUE and @ref GLFW_PLATFORM_ERROR. + * + * @reentrancy This function must not be called from a callback. + * + * @thread_safety This function must only be called from the main thread. + * + * @sa @ref events + * @sa @ref glfwPollEvents + * @sa @ref glfwWaitEvents + * + * @since Added in version 3.2. + * + * @ingroup window + */ +GLFWAPI void glfwWaitEventsTimeout(double timeout); + +/*! @brief Posts an empty event to the event queue. + * + * This function posts an empty event from the current thread to the event + * queue, causing @ref glfwWaitEvents or @ref glfwWaitEventsTimeout to return. + * + * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref + * GLFW_PLATFORM_ERROR. + * + * @thread_safety This function may be called from any thread. + * + * @sa @ref events + * @sa @ref glfwWaitEvents + * @sa @ref glfwWaitEventsTimeout + * + * @since Added in version 3.1. + * + * @ingroup window + */ +GLFWAPI void glfwPostEmptyEvent(void); + +/*! @brief Returns the value of an input option for the specified window. + * + * This function returns the value of an input option for the specified window. + * The mode must be one of @ref GLFW_CURSOR, @ref GLFW_STICKY_KEYS, + * @ref GLFW_STICKY_MOUSE_BUTTONS, @ref GLFW_LOCK_KEY_MODS or + * @ref GLFW_RAW_MOUSE_MOTION. + * + * @param[in] window The window to query. + * @param[in] mode One of `GLFW_CURSOR`, `GLFW_STICKY_KEYS`, + * `GLFW_STICKY_MOUSE_BUTTONS`, `GLFW_LOCK_KEY_MODS` or + * `GLFW_RAW_MOUSE_MOTION`. + * + * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref + * GLFW_INVALID_ENUM. + * + * @thread_safety This function must only be called from the main thread. + * + * @sa @ref glfwSetInputMode + * + * @since Added in version 3.0. + * + * @ingroup input + */ +GLFWAPI int glfwGetInputMode(GLFWwindow* window, int mode); + +/*! @brief Sets an input option for the specified window. + * + * This function sets an input mode option for the specified window. The mode + * must be one of @ref GLFW_CURSOR, @ref GLFW_STICKY_KEYS, + * @ref GLFW_STICKY_MOUSE_BUTTONS, @ref GLFW_LOCK_KEY_MODS or + * @ref GLFW_RAW_MOUSE_MOTION. + * + * If the mode is `GLFW_CURSOR`, the value must be one of the following cursor + * modes: + * - `GLFW_CURSOR_NORMAL` makes the cursor visible and behaving normally. + * - `GLFW_CURSOR_HIDDEN` makes the cursor invisible when it is over the + * content area of the window but does not restrict the cursor from leaving. + * - `GLFW_CURSOR_DISABLED` hides and grabs the cursor, providing virtual + * and unlimited cursor movement. This is useful for implementing for + * example 3D camera controls. + * - `GLFW_CURSOR_CAPTURED` makes the cursor visible and confines it to the + * content area of the window. + * + * If the mode is `GLFW_STICKY_KEYS`, the value must be either `GLFW_TRUE` to + * enable sticky keys, or `GLFW_FALSE` to disable it. If sticky keys are + * enabled, a key press will ensure that @ref glfwGetKey returns `GLFW_PRESS` + * the next time it is called even if the key had been released before the + * call. This is useful when you are only interested in whether keys have been + * pressed but not when or in which order. + * + * If the mode is `GLFW_STICKY_MOUSE_BUTTONS`, the value must be either + * `GLFW_TRUE` to enable sticky mouse buttons, or `GLFW_FALSE` to disable it. + * If sticky mouse buttons are enabled, a mouse button press will ensure that + * @ref glfwGetMouseButton returns `GLFW_PRESS` the next time it is called even + * if the mouse button had been released before the call. This is useful when + * you are only interested in whether mouse buttons have been pressed but not + * when or in which order. + * + * If the mode is `GLFW_LOCK_KEY_MODS`, the value must be either `GLFW_TRUE` to + * enable lock key modifier bits, or `GLFW_FALSE` to disable them. If enabled, + * callbacks that receive modifier bits will also have the @ref + * GLFW_MOD_CAPS_LOCK bit set when the event was generated with Caps Lock on, + * and the @ref GLFW_MOD_NUM_LOCK bit when Num Lock was on. + * + * If the mode is `GLFW_RAW_MOUSE_MOTION`, the value must be either `GLFW_TRUE` + * to enable raw (unscaled and unaccelerated) mouse motion when the cursor is + * disabled, or `GLFW_FALSE` to disable it. If raw motion is not supported, + * attempting to set this will emit @ref GLFW_FEATURE_UNAVAILABLE. Call @ref + * glfwRawMouseMotionSupported to check for support. + * + * @param[in] window The window whose input mode to set. + * @param[in] mode One of `GLFW_CURSOR`, `GLFW_STICKY_KEYS`, + * `GLFW_STICKY_MOUSE_BUTTONS`, `GLFW_LOCK_KEY_MODS` or + * `GLFW_RAW_MOUSE_MOTION`. + * @param[in] value The new value of the specified input mode. + * + * @errors Possible errors include @ref GLFW_NOT_INITIALIZED, @ref + * GLFW_INVALID_ENUM, @ref GLFW_PLATFORM_ERROR and @ref + * GLFW_FEATURE_UNAVAILABLE (see above). + * + * @thread_safety This function must only be called from the main thread. + * + * @sa @ref glfwGetInputMode + * + * @since Added in version 3.0. Replaces `glfwEnable` and `glfwDisable`. + * + * @ingroup input + */ +GLFWAPI void glfwSetInputMode(GLFWwindow* window, int mode, int value); + +/*! @brief Returns whether raw mouse motion is supported. + * + * This function returns whether raw mouse motion is supported on the current + * system. This status does not change after GLFW has been initialized so you + * only need to check this once. If you attempt to enable raw motion on + * a system that does not support it, @ref GLFW_PLATFORM_ERROR will be emitted. + * + * Raw mouse motion is closer to the actual motion of the mouse across + * a surface. It is not affected by the scaling and acceleration applied to + * the motion of the desktop cursor. That processing is suitable for a cursor + * while raw motion is better for controlling for example a 3D camera. Because + * of this, raw mouse motion is only provided when the cursor is disabled. + * + * @return `GLFW_TRUE` if raw mouse motion is supported on the current machine, + * or `GLFW_FALSE` otherwise. + * + * @errors Possible errors include @ref GLFW_NOT_INITIALIZED. + * + * @thread_safety This function must only be called from the main thread. + * + * @sa @ref raw_mouse_motion + * @sa @ref glfwSetInputMode + * + * @since Added in version 3.3. + * + * @ingroup input + */ +GLFWAPI int glfwRawMouseMotionSupported(void); + +/*! @brief Returns the layout-specific name of the specified printable key. + * + * This function returns the name of the specified printable key, encoded as + * UTF-8. This is typically the character that key would produce without any + * modifier keys, intended for displaying key bindings to the user. For dead + * keys, it is typically the diacritic it would add to a character. + * + * __Do not use this function__ for [text input](@ref input_char). You will + * break text input for many languages even if it happens to work for yours. + * + * If the key is `GLFW_KEY_UNKNOWN`, the scancode is used to identify the key, + * otherwise the scancode is ignored. If you specify a non-printable key, or + * `GLFW_KEY_UNKNOWN` and a scancode that maps to a non-printable key, this + * function returns `NULL` but does not emit an error. + * + * This behavior allows you to always pass in the arguments in the + * [key callback](@ref input_key) without modification. + * + * The printable keys are: + * - `GLFW_KEY_APOSTROPHE` + * - `GLFW_KEY_COMMA` + * - `GLFW_KEY_MINUS` + * - `GLFW_KEY_PERIOD` + * - `GLFW_KEY_SLASH` + * - `GLFW_KEY_SEMICOLON` + * - `GLFW_KEY_EQUAL` + * - `GLFW_KEY_LEFT_BRACKET` + * - `GLFW_KEY_RIGHT_BRACKET` + * - `GLFW_KEY_BACKSLASH` + * - `GLFW_KEY_WORLD_1` + * - `GLFW_KEY_WORLD_2` + * - `GLFW_KEY_0` to `GLFW_KEY_9` + * - `GLFW_KEY_A` to `GLFW_KEY_Z` + * - `GLFW_KEY_KP_0` to `GLFW_KEY_KP_9` + * - `GLFW_KEY_KP_DECIMAL` + * - `GLFW_KEY_KP_DIVIDE` + * - `GLFW_KEY_KP_MULTIPLY` + * - `GLFW_KEY_KP_SUBTRACT` + * - `GLFW_KEY_KP_ADD` + * - `GLFW_KEY_KP_EQUAL` + * + * Names for printable keys depend on keyboard layout, while names for + * non-printable keys are the same across layouts but depend on the application + * language and should be localized along with other user interface text. + * + * @param[in] key The key to query, or `GLFW_KEY_UNKNOWN`. + * @param[in] scancode The scancode of the key to query. + * @return The UTF-8 encoded, layout-specific name of the key, or `NULL`. + * + * @errors Possible errors include @ref GLFW_NOT_INITIALIZED, @ref + * GLFW_INVALID_VALUE, @ref GLFW_INVALID_ENUM and @ref GLFW_PLATFORM_ERROR. + * + * @remark The contents of the returned string may change when a keyboard + * layout change event is received. + * + * @pointer_lifetime The returned string is allocated and freed by GLFW. You + * should not free it yourself. It is valid until the library is terminated. + * + * @thread_safety This function must only be called from the main thread. + * + * @sa @ref input_key_name + * + * @since Added in version 3.2. + * + * @ingroup input + */ +GLFWAPI const char* glfwGetKeyName(int key, int scancode); + +/*! @brief Returns the platform-specific scancode of the specified key. + * + * This function returns the platform-specific scancode of the specified key. + * + * If the specified [key token](@ref keys) corresponds to a physical key not + * supported on the current platform then this method will return `-1`. + * Calling this function with anything other than a key token will return `-1` + * and generate a @ref GLFW_INVALID_ENUM error. + * + * @param[in] key Any [key token](@ref keys). + * @return The platform-specific scancode for the key, or `-1` if the key is + * not supported on the current platform or an [error](@ref error_handling) + * occurred. + * + * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref + * GLFW_INVALID_ENUM. + * + * @thread_safety This function may be called from any thread. + * + * @sa @ref input_key + * + * @since Added in version 3.3. + * + * @ingroup input + */ +GLFWAPI int glfwGetKeyScancode(int key); + +/*! @brief Returns the last reported state of a keyboard key for the specified + * window. + * + * This function returns the last state reported for the specified key to the + * specified window. The returned state is one of `GLFW_PRESS` or + * `GLFW_RELEASE`. The action `GLFW_REPEAT` is only reported to the key callback. + * + * If the @ref GLFW_STICKY_KEYS input mode is enabled, this function returns + * `GLFW_PRESS` the first time you call it for a key that was pressed, even if + * that key has already been released. + * + * The key functions deal with physical keys, with [key tokens](@ref keys) + * named after their use on the standard US keyboard layout. If you want to + * input text, use the Unicode character callback instead. + * + * The [modifier key bit masks](@ref mods) are not key tokens and cannot be + * used with this function. + * + * __Do not use this function__ to implement [text input](@ref input_char). + * + * @param[in] window The desired window. + * @param[in] key The desired [keyboard key](@ref keys). `GLFW_KEY_UNKNOWN` is + * not a valid key for this function. + * @return One of `GLFW_PRESS` or `GLFW_RELEASE`. + * + * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref + * GLFW_INVALID_ENUM. + * + * @thread_safety This function must only be called from the main thread. + * + * @sa @ref input_key + * + * @since Added in version 1.0. + * @glfw3 Added window handle parameter. + * + * @ingroup input + */ +GLFWAPI int glfwGetKey(GLFWwindow* window, int key); + +/*! @brief Returns the last reported state of a mouse button for the specified + * window. + * + * This function returns the last state reported for the specified mouse button + * to the specified window. The returned state is one of `GLFW_PRESS` or + * `GLFW_RELEASE`. + * + * If the @ref GLFW_STICKY_MOUSE_BUTTONS input mode is enabled, this function + * returns `GLFW_PRESS` the first time you call it for a mouse button that was + * pressed, even if that mouse button has already been released. + * + * @param[in] window The desired window. + * @param[in] button The desired [mouse button](@ref buttons). + * @return One of `GLFW_PRESS` or `GLFW_RELEASE`. + * + * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref + * GLFW_INVALID_ENUM. + * + * @thread_safety This function must only be called from the main thread. + * + * @sa @ref input_mouse_button + * + * @since Added in version 1.0. + * @glfw3 Added window handle parameter. + * + * @ingroup input + */ +GLFWAPI int glfwGetMouseButton(GLFWwindow* window, int button); + +/*! @brief Retrieves the position of the cursor relative to the content area of + * the window. + * + * This function returns the position of the cursor, in screen coordinates, + * relative to the upper-left corner of the content area of the specified + * window. + * + * If the cursor is disabled (with `GLFW_CURSOR_DISABLED`) then the cursor + * position is unbounded and limited only by the minimum and maximum values of + * a `double`. + * + * The coordinate can be converted to their integer equivalents with the + * `floor` function. Casting directly to an integer type works for positive + * coordinates, but fails for negative ones. + * + * Any or all of the position arguments may be `NULL`. If an error occurs, all + * non-`NULL` position arguments will be set to zero. + * + * @param[in] window The desired window. + * @param[out] xpos Where to store the cursor x-coordinate, relative to the + * left edge of the content area, or `NULL`. + * @param[out] ypos Where to store the cursor y-coordinate, relative to the to + * top edge of the content area, or `NULL`. + * + * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref + * GLFW_PLATFORM_ERROR. + * + * @thread_safety This function must only be called from the main thread. + * + * @sa @ref cursor_pos + * @sa @ref glfwSetCursorPos + * + * @since Added in version 3.0. Replaces `glfwGetMousePos`. + * + * @ingroup input + */ +GLFWAPI void glfwGetCursorPos(GLFWwindow* window, double* xpos, double* ypos); + +/*! @brief Sets the position of the cursor, relative to the content area of the + * window. + * + * This function sets the position, in screen coordinates, of the cursor + * relative to the upper-left corner of the content area of the specified + * window. The window must have input focus. If the window does not have + * input focus when this function is called, it fails silently. + * + * __Do not use this function__ to implement things like camera controls. GLFW + * already provides the `GLFW_CURSOR_DISABLED` cursor mode that hides the + * cursor, transparently re-centers it and provides unconstrained cursor + * motion. See @ref glfwSetInputMode for more information. + * + * If the cursor mode is `GLFW_CURSOR_DISABLED` then the cursor position is + * unconstrained and limited only by the minimum and maximum values of + * a `double`. + * + * @param[in] window The desired window. + * @param[in] xpos The desired x-coordinate, relative to the left edge of the + * content area. + * @param[in] ypos The desired y-coordinate, relative to the top edge of the + * content area. + * + * @errors Possible errors include @ref GLFW_NOT_INITIALIZED, @ref + * GLFW_PLATFORM_ERROR and @ref GLFW_FEATURE_UNAVAILABLE (see remarks). + * + * @remark @wayland This function will only work when the cursor mode is + * `GLFW_CURSOR_DISABLED`, otherwise it will emit @ref GLFW_FEATURE_UNAVAILABLE. + * + * @thread_safety This function must only be called from the main thread. + * + * @sa @ref cursor_pos + * @sa @ref glfwGetCursorPos + * + * @since Added in version 3.0. Replaces `glfwSetMousePos`. + * + * @ingroup input + */ +GLFWAPI void glfwSetCursorPos(GLFWwindow* window, double xpos, double ypos); + +/*! @brief Creates a custom cursor. + * + * Creates a new custom cursor image that can be set for a window with @ref + * glfwSetCursor. The cursor can be destroyed with @ref glfwDestroyCursor. + * Any remaining cursors are destroyed by @ref glfwTerminate. + * + * The pixels are 32-bit, little-endian, non-premultiplied RGBA, i.e. eight + * bits per channel with the red channel first. They are arranged canonically + * as packed sequential rows, starting from the top-left corner. + * + * The cursor hotspot is specified in pixels, relative to the upper-left corner + * of the cursor image. Like all other coordinate systems in GLFW, the X-axis + * points to the right and the Y-axis points down. + * + * @param[in] image The desired cursor image. + * @param[in] xhot The desired x-coordinate, in pixels, of the cursor hotspot. + * @param[in] yhot The desired y-coordinate, in pixels, of the cursor hotspot. + * @return The handle of the created cursor, or `NULL` if an + * [error](@ref error_handling) occurred. + * + * @errors Possible errors include @ref GLFW_NOT_INITIALIZED, @ref + * GLFW_INVALID_VALUE and @ref GLFW_PLATFORM_ERROR. + * + * @pointer_lifetime The specified image data is copied before this function + * returns. + * + * @thread_safety This function must only be called from the main thread. + * + * @sa @ref cursor_object + * @sa @ref glfwDestroyCursor + * @sa @ref glfwCreateStandardCursor + * + * @since Added in version 3.1. + * + * @ingroup input + */ +GLFWAPI GLFWcursor* glfwCreateCursor(const GLFWimage* image, int xhot, int yhot); + +/*! @brief Creates a cursor with a standard shape. + * + * Returns a cursor with a standard shape, that can be set for a window with + * @ref glfwSetCursor. The images for these cursors come from the system + * cursor theme and their exact appearance will vary between platforms. + * + * Most of these shapes are guaranteed to exist on every supported platform but + * a few may not be present. See the table below for details. + * + * Cursor shape | Windows | macOS | X11 | Wayland + * ------------------------------ | ------- | ----- | ------ | ------- + * @ref GLFW_ARROW_CURSOR | Yes | Yes | Yes | Yes + * @ref GLFW_IBEAM_CURSOR | Yes | Yes | Yes | Yes + * @ref GLFW_CROSSHAIR_CURSOR | Yes | Yes | Yes | Yes + * @ref GLFW_POINTING_HAND_CURSOR | Yes | Yes | Yes | Yes + * @ref GLFW_RESIZE_EW_CURSOR | Yes | Yes | Yes | Yes + * @ref GLFW_RESIZE_NS_CURSOR | Yes | Yes | Yes | Yes + * @ref GLFW_RESIZE_NWSE_CURSOR | Yes | Yes1 | Maybe2 | Maybe2 + * @ref GLFW_RESIZE_NESW_CURSOR | Yes | Yes1 | Maybe2 | Maybe2 + * @ref GLFW_RESIZE_ALL_CURSOR | Yes | Yes | Yes | Yes + * @ref GLFW_NOT_ALLOWED_CURSOR | Yes | Yes | Maybe2 | Maybe2 + * + * 1) This uses a private system API and may fail in the future. + * + * 2) This uses a newer standard that not all cursor themes support. + * + * If the requested shape is not available, this function emits a @ref + * GLFW_CURSOR_UNAVAILABLE error and returns `NULL`. + * + * @param[in] shape One of the [standard shapes](@ref shapes). + * @return A new cursor ready to use or `NULL` if an + * [error](@ref error_handling) occurred. + * + * @errors Possible errors include @ref GLFW_NOT_INITIALIZED, @ref + * GLFW_INVALID_ENUM, @ref GLFW_CURSOR_UNAVAILABLE and @ref + * GLFW_PLATFORM_ERROR. + * + * @thread_safety This function must only be called from the main thread. + * + * @sa @ref cursor_standard + * @sa @ref glfwCreateCursor + * + * @since Added in version 3.1. + * + * @ingroup input + */ +GLFWAPI GLFWcursor* glfwCreateStandardCursor(int shape); + +/*! @brief Destroys a cursor. + * + * This function destroys a cursor previously created with @ref + * glfwCreateCursor. Any remaining cursors will be destroyed by @ref + * glfwTerminate. + * + * If the specified cursor is current for any window, that window will be + * reverted to the default cursor. This does not affect the cursor mode. + * + * @param[in] cursor The cursor object to destroy. + * + * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref + * GLFW_PLATFORM_ERROR. + * + * @reentrancy This function must not be called from a callback. + * + * @thread_safety This function must only be called from the main thread. + * + * @sa @ref cursor_object + * @sa @ref glfwCreateCursor + * + * @since Added in version 3.1. + * + * @ingroup input + */ +GLFWAPI void glfwDestroyCursor(GLFWcursor* cursor); + +/*! @brief Sets the cursor for the window. + * + * This function sets the cursor image to be used when the cursor is over the + * content area of the specified window. The set cursor will only be visible + * when the [cursor mode](@ref cursor_mode) of the window is + * `GLFW_CURSOR_NORMAL`. + * + * On some platforms, the set cursor may not be visible unless the window also + * has input focus. + * + * @param[in] window The window to set the cursor for. + * @param[in] cursor The cursor to set, or `NULL` to switch back to the default + * arrow cursor. + * + * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref + * GLFW_PLATFORM_ERROR. + * + * @thread_safety This function must only be called from the main thread. + * + * @sa @ref cursor_object + * + * @since Added in version 3.1. + * + * @ingroup input + */ +GLFWAPI void glfwSetCursor(GLFWwindow* window, GLFWcursor* cursor); + +/*! @brief Sets the key callback. + * + * This function sets the key callback of the specified window, which is called + * when a key is pressed, repeated or released. + * + * The key functions deal with physical keys, with layout independent + * [key tokens](@ref keys) named after their values in the standard US keyboard + * layout. If you want to input text, use the + * [character callback](@ref glfwSetCharCallback) instead. + * + * When a window loses input focus, it will generate synthetic key release + * events for all pressed keys with associated key tokens. You can tell these + * events from user-generated events by the fact that the synthetic ones are + * generated after the focus loss event has been processed, i.e. after the + * [window focus callback](@ref glfwSetWindowFocusCallback) has been called. + * + * The scancode of a key is specific to that platform or sometimes even to that + * machine. Scancodes are intended to allow users to bind keys that don't have + * a GLFW key token. Such keys have `key` set to `GLFW_KEY_UNKNOWN`, their + * state is not saved and so it cannot be queried with @ref glfwGetKey. + * + * Sometimes GLFW needs to generate synthetic key events, in which case the + * scancode may be zero. + * + * @param[in] window The window whose callback to set. + * @param[in] callback The new key callback, or `NULL` to remove the currently + * set callback. + * @return The previously set callback, or `NULL` if no callback was set or the + * library had not been [initialized](@ref intro_init). + * + * @callback_signature + * @code + * void function_name(GLFWwindow* window, int key, int scancode, int action, int mods) + * @endcode + * For more information about the callback parameters, see the + * [function pointer type](@ref GLFWkeyfun). + * + * @errors Possible errors include @ref GLFW_NOT_INITIALIZED. + * + * @thread_safety This function must only be called from the main thread. + * + * @sa @ref input_key + * + * @since Added in version 1.0. + * @glfw3 Added window handle parameter and return value. + * + * @ingroup input + */ +GLFWAPI GLFWkeyfun glfwSetKeyCallback(GLFWwindow* window, GLFWkeyfun callback); + +/*! @brief Sets the Unicode character callback. + * + * This function sets the character callback of the specified window, which is + * called when a Unicode character is input. + * + * The character callback is intended for Unicode text input. As it deals with + * characters, it is keyboard layout dependent, whereas the + * [key callback](@ref glfwSetKeyCallback) is not. Characters do not map 1:1 + * to physical keys, as a key may produce zero, one or more characters. If you + * want to know whether a specific physical key was pressed or released, see + * the key callback instead. + * + * The character callback behaves as system text input normally does and will + * not be called if modifier keys are held down that would prevent normal text + * input on that platform, for example a Super (Command) key on macOS or Alt key + * on Windows. + * + * @param[in] window The window whose callback to set. + * @param[in] callback The new callback, or `NULL` to remove the currently set + * callback. + * @return The previously set callback, or `NULL` if no callback was set or the + * library had not been [initialized](@ref intro_init). + * + * @callback_signature + * @code + * void function_name(GLFWwindow* window, unsigned int codepoint) + * @endcode + * For more information about the callback parameters, see the + * [function pointer type](@ref GLFWcharfun). + * + * @errors Possible errors include @ref GLFW_NOT_INITIALIZED. + * + * @thread_safety This function must only be called from the main thread. + * + * @sa @ref input_char + * + * @since Added in version 2.4. + * @glfw3 Added window handle parameter and return value. + * + * @ingroup input + */ +GLFWAPI GLFWcharfun glfwSetCharCallback(GLFWwindow* window, GLFWcharfun callback); + +/*! @brief Sets the Unicode character with modifiers callback. + * + * This function sets the character with modifiers callback of the specified + * window, which is called when a Unicode character is input regardless of what + * modifier keys are used. + * + * The character with modifiers callback is intended for implementing custom + * Unicode character input. For regular Unicode text input, see the + * [character callback](@ref glfwSetCharCallback). Like the character + * callback, the character with modifiers callback deals with characters and is + * keyboard layout dependent. Characters do not map 1:1 to physical keys, as + * a key may produce zero, one or more characters. If you want to know whether + * a specific physical key was pressed or released, see the + * [key callback](@ref glfwSetKeyCallback) instead. + * + * @param[in] window The window whose callback to set. + * @param[in] callback The new callback, or `NULL` to remove the currently set + * callback. + * @return The previously set callback, or `NULL` if no callback was set or an + * [error](@ref error_handling) occurred. + * + * @callback_signature + * @code + * void function_name(GLFWwindow* window, unsigned int codepoint, int mods) + * @endcode + * For more information about the callback parameters, see the + * [function pointer type](@ref GLFWcharmodsfun). + * + * @deprecated Scheduled for removal in version 4.0. + * + * @errors Possible errors include @ref GLFW_NOT_INITIALIZED. + * + * @thread_safety This function must only be called from the main thread. + * + * @sa @ref input_char + * + * @since Added in version 3.1. + * + * @ingroup input + */ +GLFWAPI GLFWcharmodsfun glfwSetCharModsCallback(GLFWwindow* window, GLFWcharmodsfun callback); + +/*! @brief Sets the mouse button callback. + * + * This function sets the mouse button callback of the specified window, which + * is called when a mouse button is pressed or released. + * + * When a window loses input focus, it will generate synthetic mouse button + * release events for all pressed mouse buttons. You can tell these events + * from user-generated events by the fact that the synthetic ones are generated + * after the focus loss event has been processed, i.e. after the + * [window focus callback](@ref glfwSetWindowFocusCallback) has been called. + * + * @param[in] window The window whose callback to set. + * @param[in] callback The new callback, or `NULL` to remove the currently set + * callback. + * @return The previously set callback, or `NULL` if no callback was set or the + * library had not been [initialized](@ref intro_init). + * + * @callback_signature + * @code + * void function_name(GLFWwindow* window, int button, int action, int mods) + * @endcode + * For more information about the callback parameters, see the + * [function pointer type](@ref GLFWmousebuttonfun). + * + * @errors Possible errors include @ref GLFW_NOT_INITIALIZED. + * + * @thread_safety This function must only be called from the main thread. + * + * @sa @ref input_mouse_button + * + * @since Added in version 1.0. + * @glfw3 Added window handle parameter and return value. + * + * @ingroup input + */ +GLFWAPI GLFWmousebuttonfun glfwSetMouseButtonCallback(GLFWwindow* window, GLFWmousebuttonfun callback); + +/*! @brief Sets the cursor position callback. + * + * This function sets the cursor position callback of the specified window, + * which is called when the cursor is moved. The callback is provided with the + * position, in screen coordinates, relative to the upper-left corner of the + * content area of the window. + * + * @param[in] window The window whose callback to set. + * @param[in] callback The new callback, or `NULL` to remove the currently set + * callback. + * @return The previously set callback, or `NULL` if no callback was set or the + * library had not been [initialized](@ref intro_init). + * + * @callback_signature + * @code + * void function_name(GLFWwindow* window, double xpos, double ypos); + * @endcode + * For more information about the callback parameters, see the + * [function pointer type](@ref GLFWcursorposfun). + * + * @errors Possible errors include @ref GLFW_NOT_INITIALIZED. + * + * @thread_safety This function must only be called from the main thread. + * + * @sa @ref cursor_pos + * + * @since Added in version 3.0. Replaces `glfwSetMousePosCallback`. + * + * @ingroup input + */ +GLFWAPI GLFWcursorposfun glfwSetCursorPosCallback(GLFWwindow* window, GLFWcursorposfun callback); + +/*! @brief Sets the cursor enter/leave callback. + * + * This function sets the cursor boundary crossing callback of the specified + * window, which is called when the cursor enters or leaves the content area of + * the window. + * + * @param[in] window The window whose callback to set. + * @param[in] callback The new callback, or `NULL` to remove the currently set + * callback. + * @return The previously set callback, or `NULL` if no callback was set or the + * library had not been [initialized](@ref intro_init). + * + * @callback_signature + * @code + * void function_name(GLFWwindow* window, int entered) + * @endcode + * For more information about the callback parameters, see the + * [function pointer type](@ref GLFWcursorenterfun). + * + * @errors Possible errors include @ref GLFW_NOT_INITIALIZED. + * + * @thread_safety This function must only be called from the main thread. + * + * @sa @ref cursor_enter + * + * @since Added in version 3.0. + * + * @ingroup input + */ +GLFWAPI GLFWcursorenterfun glfwSetCursorEnterCallback(GLFWwindow* window, GLFWcursorenterfun callback); + +/*! @brief Sets the scroll callback. + * + * This function sets the scroll callback of the specified window, which is + * called when a scrolling device is used, such as a mouse wheel or scrolling + * area of a touchpad. + * + * The scroll callback receives all scrolling input, like that from a mouse + * wheel or a touchpad scrolling area. + * + * @param[in] window The window whose callback to set. + * @param[in] callback The new scroll callback, or `NULL` to remove the + * currently set callback. + * @return The previously set callback, or `NULL` if no callback was set or the + * library had not been [initialized](@ref intro_init). + * + * @callback_signature + * @code + * void function_name(GLFWwindow* window, double xoffset, double yoffset) + * @endcode + * For more information about the callback parameters, see the + * [function pointer type](@ref GLFWscrollfun). + * + * @errors Possible errors include @ref GLFW_NOT_INITIALIZED. + * + * @thread_safety This function must only be called from the main thread. + * + * @sa @ref scrolling + * + * @since Added in version 3.0. Replaces `glfwSetMouseWheelCallback`. + * + * @ingroup input + */ +GLFWAPI GLFWscrollfun glfwSetScrollCallback(GLFWwindow* window, GLFWscrollfun callback); + +/*! @brief Sets the path drop callback. + * + * This function sets the path drop callback of the specified window, which is + * called when one or more dragged paths are dropped on the window. + * + * Because the path array and its strings may have been generated specifically + * for that event, they are not guaranteed to be valid after the callback has + * returned. If you wish to use them after the callback returns, you need to + * make a deep copy. + * + * @param[in] window The window whose callback to set. + * @param[in] callback The new file drop callback, or `NULL` to remove the + * currently set callback. + * @return The previously set callback, or `NULL` if no callback was set or the + * library had not been [initialized](@ref intro_init). + * + * @callback_signature + * @code + * void function_name(GLFWwindow* window, int path_count, const char* paths[]) + * @endcode + * For more information about the callback parameters, see the + * [function pointer type](@ref GLFWdropfun). + * + * @errors Possible errors include @ref GLFW_NOT_INITIALIZED. + * + * @thread_safety This function must only be called from the main thread. + * + * @sa @ref path_drop + * + * @since Added in version 3.1. + * + * @ingroup input + */ +GLFWAPI GLFWdropfun glfwSetDropCallback(GLFWwindow* window, GLFWdropfun callback); + +/*! @brief Returns whether the specified joystick is present. + * + * This function returns whether the specified joystick is present. + * + * There is no need to call this function before other functions that accept + * a joystick ID, as they all check for presence before performing any other + * work. + * + * @param[in] jid The [joystick](@ref joysticks) to query. + * @return `GLFW_TRUE` if the joystick is present, or `GLFW_FALSE` otherwise. + * + * @errors Possible errors include @ref GLFW_NOT_INITIALIZED, @ref + * GLFW_INVALID_ENUM and @ref GLFW_PLATFORM_ERROR. + * + * @thread_safety This function must only be called from the main thread. + * + * @sa @ref joystick + * + * @since Added in version 3.0. Replaces `glfwGetJoystickParam`. + * + * @ingroup input + */ +GLFWAPI int glfwJoystickPresent(int jid); + +/*! @brief Returns the values of all axes of the specified joystick. + * + * This function returns the values of all axes of the specified joystick. + * Each element in the array is a value between -1.0 and 1.0. + * + * If the specified joystick is not present this function will return `NULL` + * but will not generate an error. This can be used instead of first calling + * @ref glfwJoystickPresent. + * + * @param[in] jid The [joystick](@ref joysticks) to query. + * @param[out] count Where to store the number of axis values in the returned + * array. This is set to zero if the joystick is not present or an error + * occurred. + * @return An array of axis values, or `NULL` if the joystick is not present or + * an [error](@ref error_handling) occurred. + * + * @errors Possible errors include @ref GLFW_NOT_INITIALIZED, @ref + * GLFW_INVALID_ENUM and @ref GLFW_PLATFORM_ERROR. + * + * @pointer_lifetime The returned array is allocated and freed by GLFW. You + * should not free it yourself. It is valid until the specified joystick is + * disconnected or the library is terminated. + * + * @thread_safety This function must only be called from the main thread. + * + * @sa @ref joystick_axis + * + * @since Added in version 3.0. Replaces `glfwGetJoystickPos`. + * + * @ingroup input + */ +GLFWAPI const float* glfwGetJoystickAxes(int jid, int* count); + +/*! @brief Returns the state of all buttons of the specified joystick. + * + * This function returns the state of all buttons of the specified joystick. + * Each element in the array is either `GLFW_PRESS` or `GLFW_RELEASE`. + * + * For backward compatibility with earlier versions that did not have @ref + * glfwGetJoystickHats, the button array also includes all hats, each + * represented as four buttons. The hats are in the same order as returned by + * __glfwGetJoystickHats__ and are in the order _up_, _right_, _down_ and + * _left_. To disable these extra buttons, set the @ref + * GLFW_JOYSTICK_HAT_BUTTONS init hint before initialization. + * + * If the specified joystick is not present this function will return `NULL` + * but will not generate an error. This can be used instead of first calling + * @ref glfwJoystickPresent. + * + * @param[in] jid The [joystick](@ref joysticks) to query. + * @param[out] count Where to store the number of button states in the returned + * array. This is set to zero if the joystick is not present or an error + * occurred. + * @return An array of button states, or `NULL` if the joystick is not present + * or an [error](@ref error_handling) occurred. + * + * @errors Possible errors include @ref GLFW_NOT_INITIALIZED, @ref + * GLFW_INVALID_ENUM and @ref GLFW_PLATFORM_ERROR. + * + * @pointer_lifetime The returned array is allocated and freed by GLFW. You + * should not free it yourself. It is valid until the specified joystick is + * disconnected or the library is terminated. + * + * @thread_safety This function must only be called from the main thread. + * + * @sa @ref joystick_button + * + * @since Added in version 2.2. + * @glfw3 Changed to return a dynamic array. + * + * @ingroup input + */ +GLFWAPI const unsigned char* glfwGetJoystickButtons(int jid, int* count); + +/*! @brief Returns the state of all hats of the specified joystick. + * + * This function returns the state of all hats of the specified joystick. + * Each element in the array is one of the following values: + * + * Name | Value + * ---- | ----- + * `GLFW_HAT_CENTERED` | 0 + * `GLFW_HAT_UP` | 1 + * `GLFW_HAT_RIGHT` | 2 + * `GLFW_HAT_DOWN` | 4 + * `GLFW_HAT_LEFT` | 8 + * `GLFW_HAT_RIGHT_UP` | `GLFW_HAT_RIGHT` \| `GLFW_HAT_UP` + * `GLFW_HAT_RIGHT_DOWN` | `GLFW_HAT_RIGHT` \| `GLFW_HAT_DOWN` + * `GLFW_HAT_LEFT_UP` | `GLFW_HAT_LEFT` \| `GLFW_HAT_UP` + * `GLFW_HAT_LEFT_DOWN` | `GLFW_HAT_LEFT` \| `GLFW_HAT_DOWN` + * + * The diagonal directions are bitwise combinations of the primary (up, right, + * down and left) directions and you can test for these individually by ANDing + * it with the corresponding direction. + * + * @code + * if (hats[2] & GLFW_HAT_RIGHT) + * { + * // State of hat 2 could be right-up, right or right-down + * } + * @endcode + * + * If the specified joystick is not present this function will return `NULL` + * but will not generate an error. This can be used instead of first calling + * @ref glfwJoystickPresent. + * + * @param[in] jid The [joystick](@ref joysticks) to query. + * @param[out] count Where to store the number of hat states in the returned + * array. This is set to zero if the joystick is not present or an error + * occurred. + * @return An array of hat states, or `NULL` if the joystick is not present + * or an [error](@ref error_handling) occurred. + * + * @errors Possible errors include @ref GLFW_NOT_INITIALIZED, @ref + * GLFW_INVALID_ENUM and @ref GLFW_PLATFORM_ERROR. + * + * @pointer_lifetime The returned array is allocated and freed by GLFW. You + * should not free it yourself. It is valid until the specified joystick is + * disconnected, this function is called again for that joystick or the library + * is terminated. + * + * @thread_safety This function must only be called from the main thread. + * + * @sa @ref joystick_hat + * + * @since Added in version 3.3. + * + * @ingroup input + */ +GLFWAPI const unsigned char* glfwGetJoystickHats(int jid, int* count); + +/*! @brief Returns the name of the specified joystick. + * + * This function returns the name, encoded as UTF-8, of the specified joystick. + * The returned string is allocated and freed by GLFW. You should not free it + * yourself. + * + * If the specified joystick is not present this function will return `NULL` + * but will not generate an error. This can be used instead of first calling + * @ref glfwJoystickPresent. + * + * @param[in] jid The [joystick](@ref joysticks) to query. + * @return The UTF-8 encoded name of the joystick, or `NULL` if the joystick + * is not present or an [error](@ref error_handling) occurred. + * + * @errors Possible errors include @ref GLFW_NOT_INITIALIZED, @ref + * GLFW_INVALID_ENUM and @ref GLFW_PLATFORM_ERROR. + * + * @pointer_lifetime The returned string is allocated and freed by GLFW. You + * should not free it yourself. It is valid until the specified joystick is + * disconnected or the library is terminated. + * + * @thread_safety This function must only be called from the main thread. + * + * @sa @ref joystick_name + * + * @since Added in version 3.0. + * + * @ingroup input + */ +GLFWAPI const char* glfwGetJoystickName(int jid); + +/*! @brief Returns the SDL compatible GUID of the specified joystick. + * + * This function returns the SDL compatible GUID, as a UTF-8 encoded + * hexadecimal string, of the specified joystick. The returned string is + * allocated and freed by GLFW. You should not free it yourself. + * + * The GUID is what connects a joystick to a gamepad mapping. A connected + * joystick will always have a GUID even if there is no gamepad mapping + * assigned to it. + * + * If the specified joystick is not present this function will return `NULL` + * but will not generate an error. This can be used instead of first calling + * @ref glfwJoystickPresent. + * + * The GUID uses the format introduced in SDL 2.0.5. This GUID tries to + * uniquely identify the make and model of a joystick but does not identify + * a specific unit, e.g. all wired Xbox 360 controllers will have the same + * GUID on that platform. The GUID for a unit may vary between platforms + * depending on what hardware information the platform specific APIs provide. + * + * @param[in] jid The [joystick](@ref joysticks) to query. + * @return The UTF-8 encoded GUID of the joystick, or `NULL` if the joystick + * is not present or an [error](@ref error_handling) occurred. + * + * @errors Possible errors include @ref GLFW_NOT_INITIALIZED, @ref + * GLFW_INVALID_ENUM and @ref GLFW_PLATFORM_ERROR. + * + * @pointer_lifetime The returned string is allocated and freed by GLFW. You + * should not free it yourself. It is valid until the specified joystick is + * disconnected or the library is terminated. + * + * @thread_safety This function must only be called from the main thread. + * + * @sa @ref gamepad + * + * @since Added in version 3.3. + * + * @ingroup input + */ +GLFWAPI const char* glfwGetJoystickGUID(int jid); + +/*! @brief Sets the user pointer of the specified joystick. + * + * This function sets the user-defined pointer of the specified joystick. The + * current value is retained until the joystick is disconnected. The initial + * value is `NULL`. + * + * This function may be called from the joystick callback, even for a joystick + * that is being disconnected. + * + * @param[in] jid The joystick whose pointer to set. + * @param[in] pointer The new value. + * + * @errors Possible errors include @ref GLFW_NOT_INITIALIZED. + * + * @thread_safety This function may be called from any thread. Access is not + * synchronized. + * + * @sa @ref joystick_userptr + * @sa @ref glfwGetJoystickUserPointer + * + * @since Added in version 3.3. + * + * @ingroup input + */ +GLFWAPI void glfwSetJoystickUserPointer(int jid, void* pointer); + +/*! @brief Returns the user pointer of the specified joystick. + * + * This function returns the current value of the user-defined pointer of the + * specified joystick. The initial value is `NULL`. + * + * This function may be called from the joystick callback, even for a joystick + * that is being disconnected. + * + * @param[in] jid The joystick whose pointer to return. + * + * @errors Possible errors include @ref GLFW_NOT_INITIALIZED. + * + * @thread_safety This function may be called from any thread. Access is not + * synchronized. + * + * @sa @ref joystick_userptr + * @sa @ref glfwSetJoystickUserPointer + * + * @since Added in version 3.3. + * + * @ingroup input + */ +GLFWAPI void* glfwGetJoystickUserPointer(int jid); + +/*! @brief Returns whether the specified joystick has a gamepad mapping. + * + * This function returns whether the specified joystick is both present and has + * a gamepad mapping. + * + * If the specified joystick is present but does not have a gamepad mapping + * this function will return `GLFW_FALSE` but will not generate an error. Call + * @ref glfwJoystickPresent to check if a joystick is present regardless of + * whether it has a mapping. + * + * @param[in] jid The [joystick](@ref joysticks) to query. + * @return `GLFW_TRUE` if a joystick is both present and has a gamepad mapping, + * or `GLFW_FALSE` otherwise. + * + * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref + * GLFW_INVALID_ENUM. + * + * @thread_safety This function must only be called from the main thread. + * + * @sa @ref gamepad + * @sa @ref glfwGetGamepadState + * + * @since Added in version 3.3. + * + * @ingroup input + */ +GLFWAPI int glfwJoystickIsGamepad(int jid); + +/*! @brief Sets the joystick configuration callback. + * + * This function sets the joystick configuration callback, or removes the + * currently set callback. This is called when a joystick is connected to or + * disconnected from the system. + * + * For joystick connection and disconnection events to be delivered on all + * platforms, you need to call one of the [event processing](@ref events) + * functions. Joystick disconnection may also be detected and the callback + * called by joystick functions. The function will then return whatever it + * returns if the joystick is not present. + * + * @param[in] callback The new callback, or `NULL` to remove the currently set + * callback. + * @return The previously set callback, or `NULL` if no callback was set or the + * library had not been [initialized](@ref intro_init). + * + * @callback_signature + * @code + * void function_name(int jid, int event) + * @endcode + * For more information about the callback parameters, see the + * [function pointer type](@ref GLFWjoystickfun). + * + * @errors Possible errors include @ref GLFW_NOT_INITIALIZED. + * + * @thread_safety This function must only be called from the main thread. + * + * @sa @ref joystick_event + * + * @since Added in version 3.2. + * + * @ingroup input + */ +GLFWAPI GLFWjoystickfun glfwSetJoystickCallback(GLFWjoystickfun callback); + +/*! @brief Adds the specified SDL_GameControllerDB gamepad mappings. + * + * This function parses the specified ASCII encoded string and updates the + * internal list with any gamepad mappings it finds. This string may + * contain either a single gamepad mapping or many mappings separated by + * newlines. The parser supports the full format of the `gamecontrollerdb.txt` + * source file including empty lines and comments. + * + * See @ref gamepad_mapping for a description of the format. + * + * If there is already a gamepad mapping for a given GUID in the internal list, + * it will be replaced by the one passed to this function. If the library is + * terminated and re-initialized the internal list will revert to the built-in + * default. + * + * @param[in] string The string containing the gamepad mappings. + * @return `GLFW_TRUE` if successful, or `GLFW_FALSE` if an + * [error](@ref error_handling) occurred. + * + * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref + * GLFW_INVALID_VALUE. + * + * @thread_safety This function must only be called from the main thread. + * + * @sa @ref gamepad + * @sa @ref glfwJoystickIsGamepad + * @sa @ref glfwGetGamepadName + * + * @since Added in version 3.3. + * + * @ingroup input + */ +GLFWAPI int glfwUpdateGamepadMappings(const char* string); + +/*! @brief Returns the human-readable gamepad name for the specified joystick. + * + * This function returns the human-readable name of the gamepad from the + * gamepad mapping assigned to the specified joystick. + * + * If the specified joystick is not present or does not have a gamepad mapping + * this function will return `NULL` but will not generate an error. Call + * @ref glfwJoystickPresent to check whether it is present regardless of + * whether it has a mapping. + * + * @param[in] jid The [joystick](@ref joysticks) to query. + * @return The UTF-8 encoded name of the gamepad, or `NULL` if the + * joystick is not present, does not have a mapping or an + * [error](@ref error_handling) occurred. + * + * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref GLFW_INVALID_ENUM. + * + * @pointer_lifetime The returned string is allocated and freed by GLFW. You + * should not free it yourself. It is valid until the specified joystick is + * disconnected, the gamepad mappings are updated or the library is terminated. + * + * @thread_safety This function must only be called from the main thread. + * + * @sa @ref gamepad + * @sa @ref glfwJoystickIsGamepad + * + * @since Added in version 3.3. + * + * @ingroup input + */ +GLFWAPI const char* glfwGetGamepadName(int jid); + +/*! @brief Retrieves the state of the specified joystick remapped as a gamepad. + * + * This function retrieves the state of the specified joystick remapped to + * an Xbox-like gamepad. + * + * If the specified joystick is not present or does not have a gamepad mapping + * this function will return `GLFW_FALSE` but will not generate an error. Call + * @ref glfwJoystickPresent to check whether it is present regardless of + * whether it has a mapping. + * + * The Guide button may not be available for input as it is often hooked by the + * system or the Steam client. + * + * Not all devices have all the buttons or axes provided by @ref + * GLFWgamepadstate. Unavailable buttons and axes will always report + * `GLFW_RELEASE` and 0.0 respectively. + * + * @param[in] jid The [joystick](@ref joysticks) to query. + * @param[out] state The gamepad input state of the joystick. + * @return `GLFW_TRUE` if successful, or `GLFW_FALSE` if no joystick is + * connected, it has no gamepad mapping or an [error](@ref error_handling) + * occurred. + * + * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref + * GLFW_INVALID_ENUM. + * + * @thread_safety This function must only be called from the main thread. + * + * @sa @ref gamepad + * @sa @ref glfwUpdateGamepadMappings + * @sa @ref glfwJoystickIsGamepad + * + * @since Added in version 3.3. + * + * @ingroup input + */ +GLFWAPI int glfwGetGamepadState(int jid, GLFWgamepadstate* state); + +/*! @brief Sets the clipboard to the specified string. + * + * This function sets the system clipboard to the specified, UTF-8 encoded + * string. + * + * @param[in] window Deprecated. Any valid window or `NULL`. + * @param[in] string A UTF-8 encoded string. + * + * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref + * GLFW_PLATFORM_ERROR. + * + * @remark @win32 The clipboard on Windows has a single global lock for reading and + * writing. GLFW tries to acquire it a few times, which is almost always enough. If it + * cannot acquire the lock then this function emits @ref GLFW_PLATFORM_ERROR and returns. + * It is safe to try this multiple times. + * + * @pointer_lifetime The specified string is copied before this function + * returns. + * + * @thread_safety This function must only be called from the main thread. + * + * @sa @ref clipboard + * @sa @ref glfwGetClipboardString + * + * @since Added in version 3.0. + * + * @ingroup input + */ +GLFWAPI void glfwSetClipboardString(GLFWwindow* window, const char* string); + +/*! @brief Returns the contents of the clipboard as a string. + * + * This function returns the contents of the system clipboard, if it contains + * or is convertible to a UTF-8 encoded string. If the clipboard is empty or + * if its contents cannot be converted, `NULL` is returned and a @ref + * GLFW_FORMAT_UNAVAILABLE error is generated. + * + * @param[in] window Deprecated. Any valid window or `NULL`. + * @return The contents of the clipboard as a UTF-8 encoded string, or `NULL` + * if an [error](@ref error_handling) occurred. + * + * @errors Possible errors include @ref GLFW_NOT_INITIALIZED, @ref + * GLFW_FORMAT_UNAVAILABLE and @ref GLFW_PLATFORM_ERROR. + * + * @remark @win32 The clipboard on Windows has a single global lock for reading and + * writing. GLFW tries to acquire it a few times, which is almost always enough. If it + * cannot acquire the lock then this function emits @ref GLFW_PLATFORM_ERROR and returns. + * It is safe to try this multiple times. + * + * @pointer_lifetime The returned string is allocated and freed by GLFW. You + * should not free it yourself. It is valid until the next call to @ref + * glfwGetClipboardString or @ref glfwSetClipboardString, or until the library + * is terminated. + * + * @thread_safety This function must only be called from the main thread. + * + * @sa @ref clipboard + * @sa @ref glfwSetClipboardString + * + * @since Added in version 3.0. + * + * @ingroup input + */ +GLFWAPI const char* glfwGetClipboardString(GLFWwindow* window); + +/*! @brief Returns the GLFW time. + * + * This function returns the current GLFW time, in seconds. Unless the time + * has been set using @ref glfwSetTime it measures time elapsed since GLFW was + * initialized. + * + * This function and @ref glfwSetTime are helper functions on top of @ref + * glfwGetTimerFrequency and @ref glfwGetTimerValue. + * + * The resolution of the timer is system dependent, but is usually on the order + * of a few micro- or nanoseconds. It uses the highest-resolution monotonic + * time source on each operating system. + * + * @return The current time, in seconds, or zero if an + * [error](@ref error_handling) occurred. + * + * @errors Possible errors include @ref GLFW_NOT_INITIALIZED. + * + * @thread_safety This function may be called from any thread. Reading and + * writing of the internal base time is not atomic, so it needs to be + * externally synchronized with calls to @ref glfwSetTime. + * + * @sa @ref time + * + * @since Added in version 1.0. + * + * @ingroup input + */ +GLFWAPI double glfwGetTime(void); + +/*! @brief Sets the GLFW time. + * + * This function sets the current GLFW time, in seconds. The value must be + * a positive finite number less than or equal to 18446744073.0, which is + * approximately 584.5 years. + * + * This function and @ref glfwGetTime are helper functions on top of @ref + * glfwGetTimerFrequency and @ref glfwGetTimerValue. + * + * @param[in] time The new value, in seconds. + * + * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref + * GLFW_INVALID_VALUE. + * + * @remark The upper limit of GLFW time is calculated as + * floor((264 - 1) / 109) and is due to implementations + * storing nanoseconds in 64 bits. The limit may be increased in the future. + * + * @thread_safety This function may be called from any thread. Reading and + * writing of the internal base time is not atomic, so it needs to be + * externally synchronized with calls to @ref glfwGetTime. + * + * @sa @ref time + * + * @since Added in version 2.2. + * + * @ingroup input + */ +GLFWAPI void glfwSetTime(double time); + +/*! @brief Returns the current value of the raw timer. + * + * This function returns the current value of the raw timer, measured in + * 1 / frequency seconds. To get the frequency, call @ref + * glfwGetTimerFrequency. + * + * @return The value of the timer, or zero if an + * [error](@ref error_handling) occurred. + * + * @errors Possible errors include @ref GLFW_NOT_INITIALIZED. + * + * @thread_safety This function may be called from any thread. + * + * @sa @ref time + * @sa @ref glfwGetTimerFrequency + * + * @since Added in version 3.2. + * + * @ingroup input + */ +GLFWAPI uint64_t glfwGetTimerValue(void); + +/*! @brief Returns the frequency, in Hz, of the raw timer. + * + * This function returns the frequency, in Hz, of the raw timer. + * + * @return The frequency of the timer, in Hz, or zero if an + * [error](@ref error_handling) occurred. + * + * @errors Possible errors include @ref GLFW_NOT_INITIALIZED. + * + * @thread_safety This function may be called from any thread. + * + * @sa @ref time + * @sa @ref glfwGetTimerValue + * + * @since Added in version 3.2. + * + * @ingroup input + */ +GLFWAPI uint64_t glfwGetTimerFrequency(void); + +/*! @brief Makes the context of the specified window current for the calling + * thread. + * + * This function makes the OpenGL or OpenGL ES context of the specified window + * current on the calling thread. It can also detach the current context from + * the calling thread without making a new one current by passing in `NULL`. + * + * A context must only be made current on a single thread at a time and each + * thread can have only a single current context at a time. Making a context + * current detaches any previously current context on the calling thread. + * + * When moving a context between threads, you must detach it (make it + * non-current) on the old thread before making it current on the new one. + * + * By default, making a context non-current implicitly forces a pipeline flush. + * On machines that support `GL_KHR_context_flush_control`, you can control + * whether a context performs this flush by setting the + * [GLFW_CONTEXT_RELEASE_BEHAVIOR](@ref GLFW_CONTEXT_RELEASE_BEHAVIOR_hint) + * hint. + * + * The specified window must have an OpenGL or OpenGL ES context. Specifying + * a window without a context will generate a @ref GLFW_NO_WINDOW_CONTEXT + * error. + * + * @param[in] window The window whose context to make current, or `NULL` to + * detach the current context. + * + * @remarks If the previously current context was created via a different + * context creation API than the one passed to this function, GLFW will still + * detach the previous one from its API before making the new one current. + * + * @errors Possible errors include @ref GLFW_NOT_INITIALIZED, @ref + * GLFW_NO_WINDOW_CONTEXT and @ref GLFW_PLATFORM_ERROR. + * + * @thread_safety This function may be called from any thread. + * + * @sa @ref context_current + * @sa @ref glfwGetCurrentContext + * + * @since Added in version 3.0. + * + * @ingroup context + */ +GLFWAPI void glfwMakeContextCurrent(GLFWwindow* window); + +/*! @brief Returns the window whose context is current on the calling thread. + * + * This function returns the window whose OpenGL or OpenGL ES context is + * current on the calling thread. + * + * @return The window whose context is current, or `NULL` if no window's + * context is current. + * + * @errors Possible errors include @ref GLFW_NOT_INITIALIZED. + * + * @thread_safety This function may be called from any thread. + * + * @sa @ref context_current + * @sa @ref glfwMakeContextCurrent + * + * @since Added in version 3.0. + * + * @ingroup context + */ +GLFWAPI GLFWwindow* glfwGetCurrentContext(void); + +/*! @brief Swaps the front and back buffers of the specified window. + * + * This function swaps the front and back buffers of the specified window when + * rendering with OpenGL or OpenGL ES. If the swap interval is greater than + * zero, the GPU driver waits the specified number of screen updates before + * swapping the buffers. + * + * The specified window must have an OpenGL or OpenGL ES context. Specifying + * a window without a context will generate a @ref GLFW_NO_WINDOW_CONTEXT + * error. + * + * This function does not apply to Vulkan. If you are rendering with Vulkan, + * see `vkQueuePresentKHR` instead. + * + * @param[in] window The window whose buffers to swap. + * + * @errors Possible errors include @ref GLFW_NOT_INITIALIZED, @ref + * GLFW_NO_WINDOW_CONTEXT and @ref GLFW_PLATFORM_ERROR. + * + * @remark __EGL:__ The context of the specified window must be current on the + * calling thread. + * + * @thread_safety This function may be called from any thread. + * + * @sa @ref buffer_swap + * @sa @ref glfwSwapInterval + * + * @since Added in version 1.0. + * @glfw3 Added window handle parameter. + * + * @ingroup window + */ +GLFWAPI void glfwSwapBuffers(GLFWwindow* window); + +/*! @brief Sets the swap interval for the current context. + * + * This function sets the swap interval for the current OpenGL or OpenGL ES + * context, i.e. the number of screen updates to wait from the time @ref + * glfwSwapBuffers was called before swapping the buffers and returning. This + * is sometimes called _vertical synchronization_, _vertical retrace + * synchronization_ or just _vsync_. + * + * A context that supports either of the `WGL_EXT_swap_control_tear` and + * `GLX_EXT_swap_control_tear` extensions also accepts _negative_ swap + * intervals, which allows the driver to swap immediately even if a frame + * arrives a little bit late. You can check for these extensions with @ref + * glfwExtensionSupported. + * + * A context must be current on the calling thread. Calling this function + * without a current context will cause a @ref GLFW_NO_CURRENT_CONTEXT error. + * + * This function does not apply to Vulkan. If you are rendering with Vulkan, + * see the present mode of your swapchain instead. + * + * @param[in] interval The minimum number of screen updates to wait for + * until the buffers are swapped by @ref glfwSwapBuffers. + * + * @errors Possible errors include @ref GLFW_NOT_INITIALIZED, @ref + * GLFW_NO_CURRENT_CONTEXT and @ref GLFW_PLATFORM_ERROR. + * + * @remark This function is not called during context creation, leaving the + * swap interval set to whatever is the default for that API. This is done + * because some swap interval extensions used by GLFW do not allow the swap + * interval to be reset to zero once it has been set to a non-zero value. + * + * @remark Some GPU drivers do not honor the requested swap interval, either + * because of a user setting that overrides the application's request or due to + * bugs in the driver. + * + * @thread_safety This function may be called from any thread. + * + * @sa @ref buffer_swap + * @sa @ref glfwSwapBuffers + * + * @since Added in version 1.0. + * + * @ingroup context + */ +GLFWAPI void glfwSwapInterval(int interval); + +/*! @brief Returns whether the specified extension is available. + * + * This function returns whether the specified + * [API extension](@ref context_glext) is supported by the current OpenGL or + * OpenGL ES context. It searches both for client API extension and context + * creation API extensions. + * + * A context must be current on the calling thread. Calling this function + * without a current context will cause a @ref GLFW_NO_CURRENT_CONTEXT error. + * + * As this functions retrieves and searches one or more extension strings each + * call, it is recommended that you cache its results if it is going to be used + * frequently. The extension strings will not change during the lifetime of + * a context, so there is no danger in doing this. + * + * This function does not apply to Vulkan. If you are using Vulkan, see @ref + * glfwGetRequiredInstanceExtensions, `vkEnumerateInstanceExtensionProperties` + * and `vkEnumerateDeviceExtensionProperties` instead. + * + * @param[in] extension The ASCII encoded name of the extension. + * @return `GLFW_TRUE` if the extension is available, or `GLFW_FALSE` + * otherwise. + * + * @errors Possible errors include @ref GLFW_NOT_INITIALIZED, @ref + * GLFW_NO_CURRENT_CONTEXT, @ref GLFW_INVALID_VALUE and @ref + * GLFW_PLATFORM_ERROR. + * + * @thread_safety This function may be called from any thread. + * + * @sa @ref context_glext + * @sa @ref glfwGetProcAddress + * + * @since Added in version 1.0. + * + * @ingroup context + */ +GLFWAPI int glfwExtensionSupported(const char* extension); + +/*! @brief Returns the address of the specified function for the current + * context. + * + * This function returns the address of the specified OpenGL or OpenGL ES + * [core or extension function](@ref context_glext), if it is supported + * by the current context. + * + * A context must be current on the calling thread. Calling this function + * without a current context will cause a @ref GLFW_NO_CURRENT_CONTEXT error. + * + * This function does not apply to Vulkan. If you are rendering with Vulkan, + * see @ref glfwGetInstanceProcAddress, `vkGetInstanceProcAddr` and + * `vkGetDeviceProcAddr` instead. + * + * @param[in] procname The ASCII encoded name of the function. + * @return The address of the function, or `NULL` if an + * [error](@ref error_handling) occurred. + * + * @errors Possible errors include @ref GLFW_NOT_INITIALIZED, @ref + * GLFW_NO_CURRENT_CONTEXT and @ref GLFW_PLATFORM_ERROR. + * + * @remark The address of a given function is not guaranteed to be the same + * between contexts. + * + * @remark This function may return a non-`NULL` address despite the + * associated version or extension not being available. Always check the + * context version or extension string first. + * + * @pointer_lifetime The returned function pointer is valid until the context + * is destroyed or the library is terminated. + * + * @thread_safety This function may be called from any thread. + * + * @sa @ref context_glext + * @sa @ref glfwExtensionSupported + * + * @since Added in version 1.0. + * + * @ingroup context + */ +GLFWAPI GLFWglproc glfwGetProcAddress(const char* procname); + +/*! @brief Returns whether the Vulkan loader and an ICD have been found. + * + * This function returns whether the Vulkan loader and any minimally functional + * ICD have been found. + * + * The availability of a Vulkan loader and even an ICD does not by itself guarantee that + * surface creation or even instance creation is possible. Call @ref + * glfwGetRequiredInstanceExtensions to check whether the extensions necessary for Vulkan + * surface creation are available and @ref glfwGetPhysicalDevicePresentationSupport to + * check whether a queue family of a physical device supports image presentation. + * + * @return `GLFW_TRUE` if Vulkan is minimally available, or `GLFW_FALSE` + * otherwise. + * + * @errors Possible errors include @ref GLFW_NOT_INITIALIZED. + * + * @thread_safety This function may be called from any thread. + * + * @sa @ref vulkan_support + * + * @since Added in version 3.2. + * + * @ingroup vulkan + */ +GLFWAPI int glfwVulkanSupported(void); + +/*! @brief Returns the Vulkan instance extensions required by GLFW. + * + * This function returns an array of names of Vulkan instance extensions required + * by GLFW for creating Vulkan surfaces for GLFW windows. If successful, the + * list will always contain `VK_KHR_surface`, so if you don't require any + * additional extensions you can pass this list directly to the + * `VkInstanceCreateInfo` struct. + * + * If Vulkan is not available on the machine, this function returns `NULL` and + * generates a @ref GLFW_API_UNAVAILABLE error. Call @ref glfwVulkanSupported + * to check whether Vulkan is at least minimally available. + * + * If Vulkan is available but no set of extensions allowing window surface + * creation was found, this function returns `NULL`. You may still use Vulkan + * for off-screen rendering and compute work. + * + * @param[out] count Where to store the number of extensions in the returned + * array. This is set to zero if an error occurred. + * @return An array of ASCII encoded extension names, or `NULL` if an + * [error](@ref error_handling) occurred. + * + * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref + * GLFW_API_UNAVAILABLE. + * + * @remark Additional extensions may be required by future versions of GLFW. + * You should check if any extensions you wish to enable are already in the + * returned array, as it is an error to specify an extension more than once in + * the `VkInstanceCreateInfo` struct. + * + * @pointer_lifetime The returned array is allocated and freed by GLFW. You + * should not free it yourself. It is guaranteed to be valid only until the + * library is terminated. + * + * @thread_safety This function may be called from any thread. + * + * @sa @ref vulkan_ext + * @sa @ref glfwCreateWindowSurface + * + * @since Added in version 3.2. + * + * @ingroup vulkan + */ +GLFWAPI const char** glfwGetRequiredInstanceExtensions(uint32_t* count); + +#if defined(VK_VERSION_1_0) + +/*! @brief Returns the address of the specified Vulkan instance function. + * + * This function returns the address of the specified Vulkan core or extension + * function for the specified instance. If instance is set to `NULL` it can + * return any function exported from the Vulkan loader, including at least the + * following functions: + * + * - `vkEnumerateInstanceExtensionProperties` + * - `vkEnumerateInstanceLayerProperties` + * - `vkCreateInstance` + * - `vkGetInstanceProcAddr` + * + * If Vulkan is not available on the machine, this function returns `NULL` and + * generates a @ref GLFW_API_UNAVAILABLE error. Call @ref glfwVulkanSupported + * to check whether Vulkan is at least minimally available. + * + * This function is equivalent to calling `vkGetInstanceProcAddr` with + * a platform-specific query of the Vulkan loader as a fallback. + * + * @param[in] instance The Vulkan instance to query, or `NULL` to retrieve + * functions related to instance creation. + * @param[in] procname The ASCII encoded name of the function. + * @return The address of the function, or `NULL` if an + * [error](@ref error_handling) occurred. + * + * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref + * GLFW_API_UNAVAILABLE. + * + * @pointer_lifetime The returned function pointer is valid until the library + * is terminated. + * + * @thread_safety This function may be called from any thread. + * + * @sa @ref vulkan_proc + * + * @since Added in version 3.2. + * + * @ingroup vulkan + */ +GLFWAPI GLFWvkproc glfwGetInstanceProcAddress(VkInstance instance, const char* procname); + +/*! @brief Returns whether the specified queue family can present images. + * + * This function returns whether the specified queue family of the specified + * physical device supports presentation to the platform GLFW was built for. + * + * If Vulkan or the required window surface creation instance extensions are + * not available on the machine, or if the specified instance was not created + * with the required extensions, this function returns `GLFW_FALSE` and + * generates a @ref GLFW_API_UNAVAILABLE error. Call @ref glfwVulkanSupported + * to check whether Vulkan is at least minimally available and @ref + * glfwGetRequiredInstanceExtensions to check what instance extensions are + * required. + * + * @param[in] instance The instance that the physical device belongs to. + * @param[in] device The physical device that the queue family belongs to. + * @param[in] queuefamily The index of the queue family to query. + * @return `GLFW_TRUE` if the queue family supports presentation, or + * `GLFW_FALSE` otherwise. + * + * @errors Possible errors include @ref GLFW_NOT_INITIALIZED, @ref + * GLFW_API_UNAVAILABLE and @ref GLFW_PLATFORM_ERROR. + * + * @remark @macos This function currently always returns `GLFW_TRUE`, as the + * `VK_MVK_macos_surface` and `VK_EXT_metal_surface` extensions do not provide + * a `vkGetPhysicalDevice*PresentationSupport` type function. + * + * @thread_safety This function may be called from any thread. For + * synchronization details of Vulkan objects, see the Vulkan specification. + * + * @sa @ref vulkan_present + * + * @since Added in version 3.2. + * + * @ingroup vulkan + */ +GLFWAPI int glfwGetPhysicalDevicePresentationSupport(VkInstance instance, VkPhysicalDevice device, uint32_t queuefamily); + +/*! @brief Creates a Vulkan surface for the specified window. + * + * This function creates a Vulkan surface for the specified window. + * + * If the Vulkan loader or at least one minimally functional ICD were not found, + * this function returns `VK_ERROR_INITIALIZATION_FAILED` and generates a @ref + * GLFW_API_UNAVAILABLE error. Call @ref glfwVulkanSupported to check whether + * Vulkan is at least minimally available. + * + * If the required window surface creation instance extensions are not + * available or if the specified instance was not created with these extensions + * enabled, this function returns `VK_ERROR_EXTENSION_NOT_PRESENT` and + * generates a @ref GLFW_API_UNAVAILABLE error. Call @ref + * glfwGetRequiredInstanceExtensions to check what instance extensions are + * required. + * + * The window surface cannot be shared with another API so the window must + * have been created with the [client api hint](@ref GLFW_CLIENT_API_attrib) + * set to `GLFW_NO_API` otherwise it generates a @ref GLFW_INVALID_VALUE error + * and returns `VK_ERROR_NATIVE_WINDOW_IN_USE_KHR`. + * + * The window surface must be destroyed before the specified Vulkan instance. + * It is the responsibility of the caller to destroy the window surface. GLFW + * does not destroy it for you. Call `vkDestroySurfaceKHR` to destroy the + * surface. + * + * @param[in] instance The Vulkan instance to create the surface in. + * @param[in] window The window to create the surface for. + * @param[in] allocator The allocator to use, or `NULL` to use the default + * allocator. + * @param[out] surface Where to store the handle of the surface. This is set + * to `VK_NULL_HANDLE` if an error occurred. + * @return `VK_SUCCESS` if successful, or a Vulkan error code if an + * [error](@ref error_handling) occurred. + * + * @errors Possible errors include @ref GLFW_NOT_INITIALIZED, @ref + * GLFW_API_UNAVAILABLE, @ref GLFW_PLATFORM_ERROR and @ref GLFW_INVALID_VALUE + * + * @remark If an error occurs before the creation call is made, GLFW returns + * the Vulkan error code most appropriate for the error. Appropriate use of + * @ref glfwVulkanSupported and @ref glfwGetRequiredInstanceExtensions should + * eliminate almost all occurrences of these errors. + * + * @remark @macos GLFW prefers the `VK_EXT_metal_surface` extension, with the + * `VK_MVK_macos_surface` extension as a fallback. The name of the selected + * extension, if any, is included in the array returned by @ref + * glfwGetRequiredInstanceExtensions. + * + * @remark @macos This function creates and sets a `CAMetalLayer` instance for + * the window content view, which is required for MoltenVK to function. + * + * @remark @x11 By default GLFW prefers the `VK_KHR_xcb_surface` extension, + * with the `VK_KHR_xlib_surface` extension as a fallback. You can make + * `VK_KHR_xlib_surface` the preferred extension by setting the + * [GLFW_X11_XCB_VULKAN_SURFACE](@ref GLFW_X11_XCB_VULKAN_SURFACE_hint) init + * hint. The name of the selected extension, if any, is included in the array + * returned by @ref glfwGetRequiredInstanceExtensions. + * + * @thread_safety This function may be called from any thread. For + * synchronization details of Vulkan objects, see the Vulkan specification. + * + * @sa @ref vulkan_surface + * @sa @ref glfwGetRequiredInstanceExtensions + * + * @since Added in version 3.2. + * + * @ingroup vulkan + */ +GLFWAPI VkResult glfwCreateWindowSurface(VkInstance instance, GLFWwindow* window, const VkAllocationCallbacks* allocator, VkSurfaceKHR* surface); + +#endif /*VK_VERSION_1_0*/ + + +/************************************************************************* + * Global definition cleanup + *************************************************************************/ + +/* ------------------- BEGIN SYSTEM/COMPILER SPECIFIC -------------------- */ + +#ifdef GLFW_WINGDIAPI_DEFINED + #undef WINGDIAPI + #undef GLFW_WINGDIAPI_DEFINED +#endif + +#ifdef GLFW_CALLBACK_DEFINED + #undef CALLBACK + #undef GLFW_CALLBACK_DEFINED +#endif + +/* Some OpenGL related headers need GLAPIENTRY, but it is unconditionally + * defined by some gl.h variants (OpenBSD) so define it after if needed. + */ +#ifndef GLAPIENTRY + #define GLAPIENTRY APIENTRY + #define GLFW_GLAPIENTRY_DEFINED +#endif + +/* -------------------- END SYSTEM/COMPILER SPECIFIC --------------------- */ + + +#ifdef __cplusplus +} +#endif + +#endif /* _glfw3_h_ */ + diff --git a/dependencies/includes/GLFW/glfw3native.h b/dependencies/includes/GLFW/glfw3native.h new file mode 100644 index 0000000..92f0d32 --- /dev/null +++ b/dependencies/includes/GLFW/glfw3native.h @@ -0,0 +1,663 @@ +/************************************************************************* + * GLFW 3.4 - www.glfw.org + * A library for OpenGL, window and input + *------------------------------------------------------------------------ + * Copyright (c) 2002-2006 Marcus Geelnard + * Copyright (c) 2006-2018 Camilla Löwy + * + * This software is provided 'as-is', without any express or implied + * warranty. In no event will the authors be held liable for any damages + * arising from the use of this software. + * + * Permission is granted to anyone to use this software for any purpose, + * including commercial applications, and to alter it and redistribute it + * freely, subject to the following restrictions: + * + * 1. The origin of this software must not be misrepresented; you must not + * claim that you wrote the original software. If you use this software + * in a product, an acknowledgment in the product documentation would + * be appreciated but is not required. + * + * 2. Altered source versions must be plainly marked as such, and must not + * be misrepresented as being the original software. + * + * 3. This notice may not be removed or altered from any source + * distribution. + * + *************************************************************************/ + +#ifndef _glfw3_native_h_ +#define _glfw3_native_h_ + +#ifdef __cplusplus +extern "C" { +#endif + + +/************************************************************************* + * Doxygen documentation + *************************************************************************/ + +/*! @file glfw3native.h + * @brief The header of the native access functions. + * + * This is the header file of the native access functions. See @ref native for + * more information. + */ +/*! @defgroup native Native access + * @brief Functions related to accessing native handles. + * + * **By using the native access functions you assert that you know what you're + * doing and how to fix problems caused by using them. If you don't, you + * shouldn't be using them.** + * + * Before the inclusion of @ref glfw3native.h, you may define zero or more + * window system API macro and zero or more context creation API macros. + * + * The chosen backends must match those the library was compiled for. Failure + * to do this will cause a link-time error. + * + * The available window API macros are: + * * `GLFW_EXPOSE_NATIVE_WIN32` + * * `GLFW_EXPOSE_NATIVE_COCOA` + * * `GLFW_EXPOSE_NATIVE_X11` + * * `GLFW_EXPOSE_NATIVE_WAYLAND` + * + * The available context API macros are: + * * `GLFW_EXPOSE_NATIVE_WGL` + * * `GLFW_EXPOSE_NATIVE_NSGL` + * * `GLFW_EXPOSE_NATIVE_GLX` + * * `GLFW_EXPOSE_NATIVE_EGL` + * * `GLFW_EXPOSE_NATIVE_OSMESA` + * + * These macros select which of the native access functions that are declared + * and which platform-specific headers to include. It is then up your (by + * definition platform-specific) code to handle which of these should be + * defined. + * + * If you do not want the platform-specific headers to be included, define + * `GLFW_NATIVE_INCLUDE_NONE` before including the @ref glfw3native.h header. + * + * @code + * #define GLFW_EXPOSE_NATIVE_WIN32 + * #define GLFW_EXPOSE_NATIVE_WGL + * #define GLFW_NATIVE_INCLUDE_NONE + * #include + * @endcode + */ + + +/************************************************************************* + * System headers and types + *************************************************************************/ + +#if !defined(GLFW_NATIVE_INCLUDE_NONE) + + #if defined(GLFW_EXPOSE_NATIVE_WIN32) || defined(GLFW_EXPOSE_NATIVE_WGL) + /* This is a workaround for the fact that glfw3.h needs to export APIENTRY (for + * example to allow applications to correctly declare a GL_KHR_debug callback) + * but windows.h assumes no one will define APIENTRY before it does + */ + #if defined(GLFW_APIENTRY_DEFINED) + #undef APIENTRY + #undef GLFW_APIENTRY_DEFINED + #endif + #include + #endif + + #if defined(GLFW_EXPOSE_NATIVE_COCOA) || defined(GLFW_EXPOSE_NATIVE_NSGL) + #if defined(__OBJC__) + #import + #else + #include + #include + #endif + #endif + + #if defined(GLFW_EXPOSE_NATIVE_X11) || defined(GLFW_EXPOSE_NATIVE_GLX) + #include + #include + #endif + + #if defined(GLFW_EXPOSE_NATIVE_WAYLAND) + #include + #endif + + #if defined(GLFW_EXPOSE_NATIVE_WGL) + /* WGL is declared by windows.h */ + #endif + #if defined(GLFW_EXPOSE_NATIVE_NSGL) + /* NSGL is declared by Cocoa.h */ + #endif + #if defined(GLFW_EXPOSE_NATIVE_GLX) + /* This is a workaround for the fact that glfw3.h defines GLAPIENTRY because by + * default it also acts as an OpenGL header + * However, glx.h will include gl.h, which will define it unconditionally + */ + #if defined(GLFW_GLAPIENTRY_DEFINED) + #undef GLAPIENTRY + #undef GLFW_GLAPIENTRY_DEFINED + #endif + #include + #endif + #if defined(GLFW_EXPOSE_NATIVE_EGL) + #include + #endif + #if defined(GLFW_EXPOSE_NATIVE_OSMESA) + /* This is a workaround for the fact that glfw3.h defines GLAPIENTRY because by + * default it also acts as an OpenGL header + * However, osmesa.h will include gl.h, which will define it unconditionally + */ + #if defined(GLFW_GLAPIENTRY_DEFINED) + #undef GLAPIENTRY + #undef GLFW_GLAPIENTRY_DEFINED + #endif + #include + #endif + +#endif /*GLFW_NATIVE_INCLUDE_NONE*/ + + +/************************************************************************* + * Functions + *************************************************************************/ + +#if defined(GLFW_EXPOSE_NATIVE_WIN32) +/*! @brief Returns the adapter device name of the specified monitor. + * + * @return The UTF-8 encoded adapter device name (for example `\\.\DISPLAY1`) + * of the specified monitor, or `NULL` if an [error](@ref error_handling) + * occurred. + * + * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref + * GLFW_PLATFORM_UNAVAILABLE. + * + * @thread_safety This function may be called from any thread. Access is not + * synchronized. + * + * @since Added in version 3.1. + * + * @ingroup native + */ +GLFWAPI const char* glfwGetWin32Adapter(GLFWmonitor* monitor); + +/*! @brief Returns the display device name of the specified monitor. + * + * @return The UTF-8 encoded display device name (for example + * `\\.\DISPLAY1\Monitor0`) of the specified monitor, or `NULL` if an + * [error](@ref error_handling) occurred. + * + * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref + * GLFW_PLATFORM_UNAVAILABLE. + * + * @thread_safety This function may be called from any thread. Access is not + * synchronized. + * + * @since Added in version 3.1. + * + * @ingroup native + */ +GLFWAPI const char* glfwGetWin32Monitor(GLFWmonitor* monitor); + +/*! @brief Returns the `HWND` of the specified window. + * + * @return The `HWND` of the specified window, or `NULL` if an + * [error](@ref error_handling) occurred. + * + * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref + * GLFW_PLATFORM_UNAVAILABLE. + * + * @remark The `HDC` associated with the window can be queried with the + * [GetDC](https://docs.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-getdc) + * function. + * @code + * HDC dc = GetDC(glfwGetWin32Window(window)); + * @endcode + * This DC is private and does not need to be released. + * + * @thread_safety This function may be called from any thread. Access is not + * synchronized. + * + * @since Added in version 3.0. + * + * @ingroup native + */ +GLFWAPI HWND glfwGetWin32Window(GLFWwindow* window); +#endif + +#if defined(GLFW_EXPOSE_NATIVE_WGL) +/*! @brief Returns the `HGLRC` of the specified window. + * + * @return The `HGLRC` of the specified window, or `NULL` if an + * [error](@ref error_handling) occurred. + * + * @errors Possible errors include @ref GLFW_NOT_INITIALIZED, @ref + * GLFW_PLATFORM_UNAVAILABLE and @ref GLFW_NO_WINDOW_CONTEXT. + * + * @remark The `HDC` associated with the window can be queried with the + * [GetDC](https://docs.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-getdc) + * function. + * @code + * HDC dc = GetDC(glfwGetWin32Window(window)); + * @endcode + * This DC is private and does not need to be released. + * + * @thread_safety This function may be called from any thread. Access is not + * synchronized. + * + * @since Added in version 3.0. + * + * @ingroup native + */ +GLFWAPI HGLRC glfwGetWGLContext(GLFWwindow* window); +#endif + +#if defined(GLFW_EXPOSE_NATIVE_COCOA) +/*! @brief Returns the `CGDirectDisplayID` of the specified monitor. + * + * @return The `CGDirectDisplayID` of the specified monitor, or + * `kCGNullDirectDisplay` if an [error](@ref error_handling) occurred. + * + * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref + * GLFW_PLATFORM_UNAVAILABLE. + * + * @thread_safety This function may be called from any thread. Access is not + * synchronized. + * + * @since Added in version 3.1. + * + * @ingroup native + */ +GLFWAPI CGDirectDisplayID glfwGetCocoaMonitor(GLFWmonitor* monitor); + +/*! @brief Returns the `NSWindow` of the specified window. + * + * @return The `NSWindow` of the specified window, or `nil` if an + * [error](@ref error_handling) occurred. + * + * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref + * GLFW_PLATFORM_UNAVAILABLE. + * + * @thread_safety This function may be called from any thread. Access is not + * synchronized. + * + * @since Added in version 3.0. + * + * @ingroup native + */ +GLFWAPI id glfwGetCocoaWindow(GLFWwindow* window); + +/*! @brief Returns the `NSView` of the specified window. + * + * @return The `NSView` of the specified window, or `nil` if an + * [error](@ref error_handling) occurred. + * + * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref + * GLFW_PLATFORM_UNAVAILABLE. + * + * @thread_safety This function may be called from any thread. Access is not + * synchronized. + * + * @since Added in version 3.4. + * + * @ingroup native + */ +GLFWAPI id glfwGetCocoaView(GLFWwindow* window); +#endif + +#if defined(GLFW_EXPOSE_NATIVE_NSGL) +/*! @brief Returns the `NSOpenGLContext` of the specified window. + * + * @return The `NSOpenGLContext` of the specified window, or `nil` if an + * [error](@ref error_handling) occurred. + * + * @errors Possible errors include @ref GLFW_NOT_INITIALIZED, @ref + * GLFW_PLATFORM_UNAVAILABLE and @ref GLFW_NO_WINDOW_CONTEXT. + * + * @thread_safety This function may be called from any thread. Access is not + * synchronized. + * + * @since Added in version 3.0. + * + * @ingroup native + */ +GLFWAPI id glfwGetNSGLContext(GLFWwindow* window); +#endif + +#if defined(GLFW_EXPOSE_NATIVE_X11) +/*! @brief Returns the `Display` used by GLFW. + * + * @return The `Display` used by GLFW, or `NULL` if an + * [error](@ref error_handling) occurred. + * + * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref + * GLFW_PLATFORM_UNAVAILABLE. + * + * @thread_safety This function may be called from any thread. Access is not + * synchronized. + * + * @since Added in version 3.0. + * + * @ingroup native + */ +GLFWAPI Display* glfwGetX11Display(void); + +/*! @brief Returns the `RRCrtc` of the specified monitor. + * + * @return The `RRCrtc` of the specified monitor, or `None` if an + * [error](@ref error_handling) occurred. + * + * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref + * GLFW_PLATFORM_UNAVAILABLE. + * + * @thread_safety This function may be called from any thread. Access is not + * synchronized. + * + * @since Added in version 3.1. + * + * @ingroup native + */ +GLFWAPI RRCrtc glfwGetX11Adapter(GLFWmonitor* monitor); + +/*! @brief Returns the `RROutput` of the specified monitor. + * + * @return The `RROutput` of the specified monitor, or `None` if an + * [error](@ref error_handling) occurred. + * + * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref + * GLFW_PLATFORM_UNAVAILABLE. + * + * @thread_safety This function may be called from any thread. Access is not + * synchronized. + * + * @since Added in version 3.1. + * + * @ingroup native + */ +GLFWAPI RROutput glfwGetX11Monitor(GLFWmonitor* monitor); + +/*! @brief Returns the `Window` of the specified window. + * + * @return The `Window` of the specified window, or `None` if an + * [error](@ref error_handling) occurred. + * + * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref + * GLFW_PLATFORM_UNAVAILABLE. + * + * @thread_safety This function may be called from any thread. Access is not + * synchronized. + * + * @since Added in version 3.0. + * + * @ingroup native + */ +GLFWAPI Window glfwGetX11Window(GLFWwindow* window); + +/*! @brief Sets the current primary selection to the specified string. + * + * @param[in] string A UTF-8 encoded string. + * + * @errors Possible errors include @ref GLFW_NOT_INITIALIZED, @ref + * GLFW_PLATFORM_UNAVAILABLE and @ref GLFW_PLATFORM_ERROR. + * + * @pointer_lifetime The specified string is copied before this function + * returns. + * + * @thread_safety This function must only be called from the main thread. + * + * @sa @ref clipboard + * @sa glfwGetX11SelectionString + * @sa glfwSetClipboardString + * + * @since Added in version 3.3. + * + * @ingroup native + */ +GLFWAPI void glfwSetX11SelectionString(const char* string); + +/*! @brief Returns the contents of the current primary selection as a string. + * + * If the selection is empty or if its contents cannot be converted, `NULL` + * is returned and a @ref GLFW_FORMAT_UNAVAILABLE error is generated. + * + * @return The contents of the selection as a UTF-8 encoded string, or `NULL` + * if an [error](@ref error_handling) occurred. + * + * @errors Possible errors include @ref GLFW_NOT_INITIALIZED, @ref + * GLFW_PLATFORM_UNAVAILABLE and @ref GLFW_PLATFORM_ERROR. + * + * @pointer_lifetime The returned string is allocated and freed by GLFW. You + * should not free it yourself. It is valid until the next call to @ref + * glfwGetX11SelectionString or @ref glfwSetX11SelectionString, or until the + * library is terminated. + * + * @thread_safety This function must only be called from the main thread. + * + * @sa @ref clipboard + * @sa glfwSetX11SelectionString + * @sa glfwGetClipboardString + * + * @since Added in version 3.3. + * + * @ingroup native + */ +GLFWAPI const char* glfwGetX11SelectionString(void); +#endif + +#if defined(GLFW_EXPOSE_NATIVE_GLX) +/*! @brief Returns the `GLXContext` of the specified window. + * + * @return The `GLXContext` of the specified window, or `NULL` if an + * [error](@ref error_handling) occurred. + * + * @errors Possible errors include @ref GLFW_NOT_INITIALIZED, @ref + * GLFW_NO_WINDOW_CONTEXT and @ref GLFW_PLATFORM_UNAVAILABLE. + * + * @thread_safety This function may be called from any thread. Access is not + * synchronized. + * + * @since Added in version 3.0. + * + * @ingroup native + */ +GLFWAPI GLXContext glfwGetGLXContext(GLFWwindow* window); + +/*! @brief Returns the `GLXWindow` of the specified window. + * + * @return The `GLXWindow` of the specified window, or `None` if an + * [error](@ref error_handling) occurred. + * + * @errors Possible errors include @ref GLFW_NOT_INITIALIZED, @ref + * GLFW_NO_WINDOW_CONTEXT and @ref GLFW_PLATFORM_UNAVAILABLE. + * + * @thread_safety This function may be called from any thread. Access is not + * synchronized. + * + * @since Added in version 3.2. + * + * @ingroup native + */ +GLFWAPI GLXWindow glfwGetGLXWindow(GLFWwindow* window); +#endif + +#if defined(GLFW_EXPOSE_NATIVE_WAYLAND) +/*! @brief Returns the `struct wl_display*` used by GLFW. + * + * @return The `struct wl_display*` used by GLFW, or `NULL` if an + * [error](@ref error_handling) occurred. + * + * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref + * GLFW_PLATFORM_UNAVAILABLE. + * + * @thread_safety This function may be called from any thread. Access is not + * synchronized. + * + * @since Added in version 3.2. + * + * @ingroup native + */ +GLFWAPI struct wl_display* glfwGetWaylandDisplay(void); + +/*! @brief Returns the `struct wl_output*` of the specified monitor. + * + * @return The `struct wl_output*` of the specified monitor, or `NULL` if an + * [error](@ref error_handling) occurred. + * + * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref + * GLFW_PLATFORM_UNAVAILABLE. + * + * @thread_safety This function may be called from any thread. Access is not + * synchronized. + * + * @since Added in version 3.2. + * + * @ingroup native + */ +GLFWAPI struct wl_output* glfwGetWaylandMonitor(GLFWmonitor* monitor); + +/*! @brief Returns the main `struct wl_surface*` of the specified window. + * + * @return The main `struct wl_surface*` of the specified window, or `NULL` if + * an [error](@ref error_handling) occurred. + * + * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref + * GLFW_PLATFORM_UNAVAILABLE. + * + * @thread_safety This function may be called from any thread. Access is not + * synchronized. + * + * @since Added in version 3.2. + * + * @ingroup native + */ +GLFWAPI struct wl_surface* glfwGetWaylandWindow(GLFWwindow* window); +#endif + +#if defined(GLFW_EXPOSE_NATIVE_EGL) +/*! @brief Returns the `EGLDisplay` used by GLFW. + * + * @return The `EGLDisplay` used by GLFW, or `EGL_NO_DISPLAY` if an + * [error](@ref error_handling) occurred. + * + * @errors Possible errors include @ref GLFW_NOT_INITIALIZED. + * + * @remark Because EGL is initialized on demand, this function will return + * `EGL_NO_DISPLAY` until the first context has been created via EGL. + * + * @thread_safety This function may be called from any thread. Access is not + * synchronized. + * + * @since Added in version 3.0. + * + * @ingroup native + */ +GLFWAPI EGLDisplay glfwGetEGLDisplay(void); + +/*! @brief Returns the `EGLContext` of the specified window. + * + * @return The `EGLContext` of the specified window, or `EGL_NO_CONTEXT` if an + * [error](@ref error_handling) occurred. + * + * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref + * GLFW_NO_WINDOW_CONTEXT. + * + * @thread_safety This function may be called from any thread. Access is not + * synchronized. + * + * @since Added in version 3.0. + * + * @ingroup native + */ +GLFWAPI EGLContext glfwGetEGLContext(GLFWwindow* window); + +/*! @brief Returns the `EGLSurface` of the specified window. + * + * @return The `EGLSurface` of the specified window, or `EGL_NO_SURFACE` if an + * [error](@ref error_handling) occurred. + * + * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref + * GLFW_NO_WINDOW_CONTEXT. + * + * @thread_safety This function may be called from any thread. Access is not + * synchronized. + * + * @since Added in version 3.0. + * + * @ingroup native + */ +GLFWAPI EGLSurface glfwGetEGLSurface(GLFWwindow* window); +#endif + +#if defined(GLFW_EXPOSE_NATIVE_OSMESA) +/*! @brief Retrieves the color buffer associated with the specified window. + * + * @param[in] window The window whose color buffer to retrieve. + * @param[out] width Where to store the width of the color buffer, or `NULL`. + * @param[out] height Where to store the height of the color buffer, or `NULL`. + * @param[out] format Where to store the OSMesa pixel format of the color + * buffer, or `NULL`. + * @param[out] buffer Where to store the address of the color buffer, or + * `NULL`. + * @return `GLFW_TRUE` if successful, or `GLFW_FALSE` if an + * [error](@ref error_handling) occurred. + * + * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref + * GLFW_NO_WINDOW_CONTEXT. + * + * @thread_safety This function may be called from any thread. Access is not + * synchronized. + * + * @since Added in version 3.3. + * + * @ingroup native + */ +GLFWAPI int glfwGetOSMesaColorBuffer(GLFWwindow* window, int* width, int* height, int* format, void** buffer); + +/*! @brief Retrieves the depth buffer associated with the specified window. + * + * @param[in] window The window whose depth buffer to retrieve. + * @param[out] width Where to store the width of the depth buffer, or `NULL`. + * @param[out] height Where to store the height of the depth buffer, or `NULL`. + * @param[out] bytesPerValue Where to store the number of bytes per depth + * buffer element, or `NULL`. + * @param[out] buffer Where to store the address of the depth buffer, or + * `NULL`. + * @return `GLFW_TRUE` if successful, or `GLFW_FALSE` if an + * [error](@ref error_handling) occurred. + * + * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref + * GLFW_NO_WINDOW_CONTEXT. + * + * @thread_safety This function may be called from any thread. Access is not + * synchronized. + * + * @since Added in version 3.3. + * + * @ingroup native + */ +GLFWAPI int glfwGetOSMesaDepthBuffer(GLFWwindow* window, int* width, int* height, int* bytesPerValue, void** buffer); + +/*! @brief Returns the `OSMesaContext` of the specified window. + * + * @return The `OSMesaContext` of the specified window, or `NULL` if an + * [error](@ref error_handling) occurred. + * + * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref + * GLFW_NO_WINDOW_CONTEXT. + * + * @thread_safety This function may be called from any thread. Access is not + * synchronized. + * + * @since Added in version 3.3. + * + * @ingroup native + */ +GLFWAPI OSMesaContext glfwGetOSMesaContext(GLFWwindow* window); +#endif + +#ifdef __cplusplus +} +#endif + +#endif /* _glfw3_native_h_ */ + diff --git a/dependencies/includes/KHR/khrplatform.h b/dependencies/includes/KHR/khrplatform.h new file mode 100644 index 0000000..0164644 --- /dev/null +++ b/dependencies/includes/KHR/khrplatform.h @@ -0,0 +1,311 @@ +#ifndef __khrplatform_h_ +#define __khrplatform_h_ + +/* +** Copyright (c) 2008-2018 The Khronos Group Inc. +** +** Permission is hereby granted, free of charge, to any person obtaining a +** copy of this software and/or associated documentation files (the +** "Materials"), to deal in the Materials without restriction, including +** without limitation the rights to use, copy, modify, merge, publish, +** distribute, sublicense, and/or sell copies of the Materials, and to +** permit persons to whom the Materials are furnished to do so, subject to +** the following conditions: +** +** The above copyright notice and this permission notice shall be included +** in all copies or substantial portions of the Materials. +** +** THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +** EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +** MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +** IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +** CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +** TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +** MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS. +*/ + +/* Khronos platform-specific types and definitions. + * + * The master copy of khrplatform.h is maintained in the Khronos EGL + * Registry repository at https://github.com/KhronosGroup/EGL-Registry + * The last semantic modification to khrplatform.h was at commit ID: + * 67a3e0864c2d75ea5287b9f3d2eb74a745936692 + * + * Adopters may modify this file to suit their platform. Adopters are + * encouraged to submit platform specific modifications to the Khronos + * group so that they can be included in future versions of this file. + * Please submit changes by filing pull requests or issues on + * the EGL Registry repository linked above. + * + * + * See the Implementer's Guidelines for information about where this file + * should be located on your system and for more details of its use: + * http://www.khronos.org/registry/implementers_guide.pdf + * + * This file should be included as + * #include + * by Khronos client API header files that use its types and defines. + * + * The types in khrplatform.h should only be used to define API-specific types. + * + * Types defined in khrplatform.h: + * khronos_int8_t signed 8 bit + * khronos_uint8_t unsigned 8 bit + * khronos_int16_t signed 16 bit + * khronos_uint16_t unsigned 16 bit + * khronos_int32_t signed 32 bit + * khronos_uint32_t unsigned 32 bit + * khronos_int64_t signed 64 bit + * khronos_uint64_t unsigned 64 bit + * khronos_intptr_t signed same number of bits as a pointer + * khronos_uintptr_t unsigned same number of bits as a pointer + * khronos_ssize_t signed size + * khronos_usize_t unsigned size + * khronos_float_t signed 32 bit floating point + * khronos_time_ns_t unsigned 64 bit time in nanoseconds + * khronos_utime_nanoseconds_t unsigned time interval or absolute time in + * nanoseconds + * khronos_stime_nanoseconds_t signed time interval in nanoseconds + * khronos_boolean_enum_t enumerated boolean type. This should + * only be used as a base type when a client API's boolean type is + * an enum. Client APIs which use an integer or other type for + * booleans cannot use this as the base type for their boolean. + * + * Tokens defined in khrplatform.h: + * + * KHRONOS_FALSE, KHRONOS_TRUE Enumerated boolean false/true values. + * + * KHRONOS_SUPPORT_INT64 is 1 if 64 bit integers are supported; otherwise 0. + * KHRONOS_SUPPORT_FLOAT is 1 if floats are supported; otherwise 0. + * + * Calling convention macros defined in this file: + * KHRONOS_APICALL + * KHRONOS_APIENTRY + * KHRONOS_APIATTRIBUTES + * + * These may be used in function prototypes as: + * + * KHRONOS_APICALL void KHRONOS_APIENTRY funcname( + * int arg1, + * int arg2) KHRONOS_APIATTRIBUTES; + */ + +#if defined(__SCITECH_SNAP__) && !defined(KHRONOS_STATIC) +# define KHRONOS_STATIC 1 +#endif + +/*------------------------------------------------------------------------- + * Definition of KHRONOS_APICALL + *------------------------------------------------------------------------- + * This precedes the return type of the function in the function prototype. + */ +#if defined(KHRONOS_STATIC) + /* If the preprocessor constant KHRONOS_STATIC is defined, make the + * header compatible with static linking. */ +# define KHRONOS_APICALL +#elif defined(_WIN32) +# define KHRONOS_APICALL __declspec(dllimport) +#elif defined (__SYMBIAN32__) +# define KHRONOS_APICALL IMPORT_C +#elif defined(__ANDROID__) +# define KHRONOS_APICALL __attribute__((visibility("default"))) +#else +# define KHRONOS_APICALL +#endif + +/*------------------------------------------------------------------------- + * Definition of KHRONOS_APIENTRY + *------------------------------------------------------------------------- + * This follows the return type of the function and precedes the function + * name in the function prototype. + */ +#if defined(_WIN32) && !defined(_WIN32_WCE) && !defined(__SCITECH_SNAP__) + /* Win32 but not WinCE */ +# define KHRONOS_APIENTRY __stdcall +#else +# define KHRONOS_APIENTRY +#endif + +/*------------------------------------------------------------------------- + * Definition of KHRONOS_APIATTRIBUTES + *------------------------------------------------------------------------- + * This follows the closing parenthesis of the function prototype arguments. + */ +#if defined (__ARMCC_2__) +#define KHRONOS_APIATTRIBUTES __softfp +#else +#define KHRONOS_APIATTRIBUTES +#endif + +/*------------------------------------------------------------------------- + * basic type definitions + *-----------------------------------------------------------------------*/ +#if (defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L) || defined(__GNUC__) || defined(__SCO__) || defined(__USLC__) + + +/* + * Using + */ +#include +typedef int32_t khronos_int32_t; +typedef uint32_t khronos_uint32_t; +typedef int64_t khronos_int64_t; +typedef uint64_t khronos_uint64_t; +#define KHRONOS_SUPPORT_INT64 1 +#define KHRONOS_SUPPORT_FLOAT 1 +/* + * To support platform where unsigned long cannot be used interchangeably with + * inptr_t (e.g. CHERI-extended ISAs), we can use the stdint.h intptr_t. + * Ideally, we could just use (u)intptr_t everywhere, but this could result in + * ABI breakage if khronos_uintptr_t is changed from unsigned long to + * unsigned long long or similar (this results in different C++ name mangling). + * To avoid changes for existing platforms, we restrict usage of intptr_t to + * platforms where the size of a pointer is larger than the size of long. + */ +#if defined(__SIZEOF_LONG__) && defined(__SIZEOF_POINTER__) +#if __SIZEOF_POINTER__ > __SIZEOF_LONG__ +#define KHRONOS_USE_INTPTR_T +#endif +#endif + +#elif defined(__VMS ) || defined(__sgi) + +/* + * Using + */ +#include +typedef int32_t khronos_int32_t; +typedef uint32_t khronos_uint32_t; +typedef int64_t khronos_int64_t; +typedef uint64_t khronos_uint64_t; +#define KHRONOS_SUPPORT_INT64 1 +#define KHRONOS_SUPPORT_FLOAT 1 + +#elif defined(_WIN32) && !defined(__SCITECH_SNAP__) + +/* + * Win32 + */ +typedef __int32 khronos_int32_t; +typedef unsigned __int32 khronos_uint32_t; +typedef __int64 khronos_int64_t; +typedef unsigned __int64 khronos_uint64_t; +#define KHRONOS_SUPPORT_INT64 1 +#define KHRONOS_SUPPORT_FLOAT 1 + +#elif defined(__sun__) || defined(__digital__) + +/* + * Sun or Digital + */ +typedef int khronos_int32_t; +typedef unsigned int khronos_uint32_t; +#if defined(__arch64__) || defined(_LP64) +typedef long int khronos_int64_t; +typedef unsigned long int khronos_uint64_t; +#else +typedef long long int khronos_int64_t; +typedef unsigned long long int khronos_uint64_t; +#endif /* __arch64__ */ +#define KHRONOS_SUPPORT_INT64 1 +#define KHRONOS_SUPPORT_FLOAT 1 + +#elif 0 + +/* + * Hypothetical platform with no float or int64 support + */ +typedef int khronos_int32_t; +typedef unsigned int khronos_uint32_t; +#define KHRONOS_SUPPORT_INT64 0 +#define KHRONOS_SUPPORT_FLOAT 0 + +#else + +/* + * Generic fallback + */ +#include +typedef int32_t khronos_int32_t; +typedef uint32_t khronos_uint32_t; +typedef int64_t khronos_int64_t; +typedef uint64_t khronos_uint64_t; +#define KHRONOS_SUPPORT_INT64 1 +#define KHRONOS_SUPPORT_FLOAT 1 + +#endif + + +/* + * Types that are (so far) the same on all platforms + */ +typedef signed char khronos_int8_t; +typedef unsigned char khronos_uint8_t; +typedef signed short int khronos_int16_t; +typedef unsigned short int khronos_uint16_t; + +/* + * Types that differ between LLP64 and LP64 architectures - in LLP64, + * pointers are 64 bits, but 'long' is still 32 bits. Win64 appears + * to be the only LLP64 architecture in current use. + */ +#ifdef KHRONOS_USE_INTPTR_T +typedef intptr_t khronos_intptr_t; +typedef uintptr_t khronos_uintptr_t; +#elif defined(_WIN64) +typedef signed long long int khronos_intptr_t; +typedef unsigned long long int khronos_uintptr_t; +#else +typedef signed long int khronos_intptr_t; +typedef unsigned long int khronos_uintptr_t; +#endif + +#if defined(_WIN64) +typedef signed long long int khronos_ssize_t; +typedef unsigned long long int khronos_usize_t; +#else +typedef signed long int khronos_ssize_t; +typedef unsigned long int khronos_usize_t; +#endif + +#if KHRONOS_SUPPORT_FLOAT +/* + * Float type + */ +typedef float khronos_float_t; +#endif + +#if KHRONOS_SUPPORT_INT64 +/* Time types + * + * These types can be used to represent a time interval in nanoseconds or + * an absolute Unadjusted System Time. Unadjusted System Time is the number + * of nanoseconds since some arbitrary system event (e.g. since the last + * time the system booted). The Unadjusted System Time is an unsigned + * 64 bit value that wraps back to 0 every 584 years. Time intervals + * may be either signed or unsigned. + */ +typedef khronos_uint64_t khronos_utime_nanoseconds_t; +typedef khronos_int64_t khronos_stime_nanoseconds_t; +#endif + +/* + * Dummy value used to pad enum types to 32 bits. + */ +#ifndef KHRONOS_MAX_ENUM +#define KHRONOS_MAX_ENUM 0x7FFFFFFF +#endif + +/* + * Enumerated boolean type + * + * Values other than zero should be considered to be true. Therefore + * comparisons should not be made against KHRONOS_TRUE. + */ +typedef enum { + KHRONOS_FALSE = 0, + KHRONOS_TRUE = 1, + KHRONOS_BOOLEAN_ENUM_FORCE_SIZE = KHRONOS_MAX_ENUM +} khronos_boolean_enum_t; + +#endif /* __khrplatform_h_ */ diff --git a/dependencies/includes/assimp/.editorconfig b/dependencies/includes/assimp/.editorconfig new file mode 100644 index 0000000..9ea6642 --- /dev/null +++ b/dependencies/includes/assimp/.editorconfig @@ -0,0 +1,8 @@ +# See for details + +[*.{h,hpp,inl}] +end_of_line = lf +insert_final_newline = true +trim_trailing_whitespace = true +indent_size = 4 +indent_style = space diff --git a/dependencies/includes/assimp/Base64.hpp b/dependencies/includes/assimp/Base64.hpp new file mode 100644 index 0000000..4037238 --- /dev/null +++ b/dependencies/includes/assimp/Base64.hpp @@ -0,0 +1,90 @@ +/* +--------------------------------------------------------------------------- +Open Asset Import Library (assimp) +--------------------------------------------------------------------------- + +Copyright (c) 2006-2022, assimp team + +All rights reserved. + +Redistribution and use of this software in source and binary forms, +with or without modification, are permitted provided that the following +conditions are met: + +* Redistributions of source code must retain the above + copyright notice, this list of conditions and the + following disclaimer. + +* Redistributions in binary form must reproduce the above + copyright notice, this list of conditions and the + following disclaimer in the documentation and/or other + materials provided with the distribution. + +* Neither the name of the assimp team, nor the names of its + contributors may be used to endorse or promote products + derived from this software without specific prior + written permission of the assimp team. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +--------------------------------------------------------------------------- +*/ + +#pragma once +#ifndef AI_BASE64_HPP_INC +#define AI_BASE64_HPP_INC + +#include +#include +#include + +namespace Assimp { +namespace Base64 { + +/// @brief Will encode the given character buffer from UTF64 to ASCII +/// @param in The UTF-64 buffer. +/// @param inLength The size of the buffer +/// @param out The encoded ASCII string. +void Encode(const uint8_t *in, size_t inLength, std::string &out); + +/// @brief Will encode the given character buffer from UTF64 to ASCII. +/// @param in A vector, which contains the buffer for encoding. +/// @param out The encoded ASCII string. +void Encode(const std::vector& in, std::string &out); + +/// @brief Will encode the given character buffer from UTF64 to ASCII. +/// @param in A vector, which contains the buffer for encoding. +/// @return The encoded ASCII string. +std::string Encode(const std::vector& in); + +/// @brief Will decode the given character buffer from ASCII to UTF64. +/// @param in The ASCII buffer to decode. +/// @param inLength The size of the buffer. +/// @param out The decoded buffer. +/// @return The new buffer size. +size_t Decode(const char *in, size_t inLength, uint8_t *&out); + +/// @brief Will decode the given character buffer from ASCII to UTF64. +/// @param in The ASCII buffer to decode as a std::string. +/// @param out The decoded buffer. +/// @return The new buffer size. +size_t Decode(const std::string& in, std::vector& out); + +/// @brief Will decode the given character buffer from ASCII to UTF64. +/// @param in The ASCII string. +/// @return The decoded buffer in a vector. +std::vector Decode(const std::string& in); + +} // namespace Base64 +} // namespace Assimp + +#endif // AI_BASE64_HPP_INC diff --git a/dependencies/includes/assimp/BaseImporter.h b/dependencies/includes/assimp/BaseImporter.h new file mode 100644 index 0000000..5a3c764 --- /dev/null +++ b/dependencies/includes/assimp/BaseImporter.h @@ -0,0 +1,396 @@ +/* +Open Asset Import Library (assimp) +---------------------------------------------------------------------- + +Copyright (c) 2006-2022, assimp team + +All rights reserved. + +Redistribution and use of this software in source and binary forms, +with or without modification, are permitted provided that the +following conditions are met: + +* Redistributions of source code must retain the above + copyright notice, this list of conditions and the + following disclaimer. + +* Redistributions in binary form must reproduce the above + copyright notice, this list of conditions and the + following disclaimer in the documentation and/or other + materials provided with the distribution. + +* Neither the name of the assimp team, nor the names of its + contributors may be used to endorse or promote products + derived from this software without specific prior + written permission of the assimp team. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +---------------------------------------------------------------------- +*/ + +/// @file Definition of the base class for all importer worker classes. + +#pragma once +#ifndef INCLUDED_AI_BASEIMPORTER_H +#define INCLUDED_AI_BASEIMPORTER_H + +#ifdef __GNUC__ +#pragma GCC system_header +#endif + +#include "Exceptional.h" + +#include +#include +#include +#include +#include + +struct aiScene; +struct aiImporterDesc; + +namespace Assimp { + +class Importer; +class IOSystem; +class BaseProcess; +class SharedPostProcessInfo; +class IOStream; + +// utility to do char4 to uint32 in a portable manner +#define AI_MAKE_MAGIC(string) ((uint32_t)((string[0] << 24) + \ + (string[1] << 16) + (string[2] << 8) + string[3])) + +// --------------------------------------------------------------------------- +/** FOR IMPORTER PLUGINS ONLY: The BaseImporter defines a common interface + * for all importer worker classes. + * + * The interface defines two functions: CanRead() is used to check if the + * importer can handle the format of the given file. If an implementation of + * this function returns true, the importer then calls ReadFile() which + * imports the given file. ReadFile is not overridable, it just calls + * InternReadFile() and catches any ImportErrorException that might occur. + */ +class ASSIMP_API BaseImporter { + friend class Importer; + +public: + /** Constructor to be privately used by #Importer */ + BaseImporter() AI_NO_EXCEPT; + + /** Destructor, private as well */ + virtual ~BaseImporter(); + + // ------------------------------------------------------------------- + /** Returns whether the class can handle the format of the given file. + * + * The implementation is expected to perform a full check of the file + * structure, possibly searching the first bytes of the file for magic + * identifiers or keywords. + * + * @param pFile Path and file name of the file to be examined. + * @param pIOHandler The IO handler to use for accessing any file. + * @param checkSig Legacy; do not use. + * @return true if the class can read this file, false if not or if + * unsure. + */ + virtual bool CanRead( + const std::string &pFile, + IOSystem *pIOHandler, + bool checkSig) const = 0; + + // ------------------------------------------------------------------- + /** Imports the given file and returns the imported data. + * If the import succeeds, ownership of the data is transferred to + * the caller. If the import fails, nullptr is returned. The function + * takes care that any partially constructed data is destroyed + * beforehand. + * + * @param pImp #Importer object hosting this loader. + * @param pFile Path of the file to be imported. + * @param pIOHandler IO-Handler used to open this and possible other files. + * @return The imported data or nullptr if failed. If it failed a + * human-readable error description can be retrieved by calling + * GetErrorText() + * + * @note This function is not intended to be overridden. Implement + * InternReadFile() to do the import. If an exception is thrown somewhere + * in InternReadFile(), this function will catch it and transform it into + * a suitable response to the caller. + */ + aiScene *ReadFile( + Importer *pImp, + const std::string &pFile, + IOSystem *pIOHandler); + + // ------------------------------------------------------------------- + /** Returns the error description of the last error that occurred. + * If the error is due to a std::exception, this will return the message. + * Exceptions can also be accessed with GetException(). + * @return A description of the last error that occurred. An empty + * string if there was no error. + */ + const std::string &GetErrorText() const { + return m_ErrorText; + } + + // ------------------------------------------------------------------- + /** Returns the exception of the last exception that occurred. + * Note: Exceptions are not the only source of error details, so GetErrorText + * should be consulted too. + * @return The last exception that occurred. + */ + const std::exception_ptr& GetException() const { + return m_Exception; + } + + // ------------------------------------------------------------------- + /** Called prior to ReadFile(). + * The function is a request to the importer to update its configuration + * basing on the Importer's configuration property list. + * @param pImp Importer instance + */ + virtual void SetupProperties( + const Importer *pImp); + + // ------------------------------------------------------------------- + /** Called by #Importer::GetImporterInfo to get a description of + * some loader features. Importers must provide this information. */ + virtual const aiImporterDesc *GetInfo() const = 0; + + /** + * Will be called only by scale process when scaling is requested. + */ + void SetFileScale(double scale) { + fileScale = scale; + } + + // ------------------------------------------------------------------- + /** Called by #Importer::GetExtensionList for each loaded importer. + * Take the extension list contained in the structure returned by + * #GetInfo and insert all file extensions into the given set. + * @param extension set to collect file extensions in*/ + void GetExtensionList(std::set &extensions); + +protected: + double importerScale = 1.0; + double fileScale = 1.0; + + // ------------------------------------------------------------------- + /** Imports the given file into the given scene structure. The + * function is expected to throw an ImportErrorException if there is + * an error. If it terminates normally, the data in aiScene is + * expected to be correct. Override this function to implement the + * actual importing. + *
    + * The output scene must meet the following requirements:
    + *
      + *
    • At least a root node must be there, even if its only purpose + * is to reference one mesh.
    • + *
    • aiMesh::mPrimitiveTypes may be 0. The types of primitives + * in the mesh are determined automatically in this case.
    • + *
    • the vertex data is stored in a pseudo-indexed "verbose" format. + * In fact this means that every vertex that is referenced by + * a face is unique. Or the other way round: a vertex index may + * not occur twice in a single aiMesh.
    • + *
    • aiAnimation::mDuration may be -1. Assimp determines the length + * of the animation automatically in this case as the length of + * the longest animation channel.
    • + *
    • aiMesh::mBitangents may be nullptr if tangents and normals are + * given. In this case bitangents are computed as the cross product + * between normal and tangent.
    • + *
    • There needn't be a material. If none is there a default material + * is generated. However, it is recommended practice for loaders + * to generate a default material for yourself that matches the + * default material setting for the file format better than Assimp's + * generic default material. Note that default materials *should* + * be named AI_DEFAULT_MATERIAL_NAME if they're just color-shaded + * or AI_DEFAULT_TEXTURED_MATERIAL_NAME if they define a (dummy) + * texture.
    • + *
    + * If the AI_SCENE_FLAGS_INCOMPLETE-Flag is not set:
      + *
    • at least one mesh must be there
    • + *
    • there may be no meshes with 0 vertices or faces
    • + *
    + * This won't be checked (except by the validation step): Assimp will + * crash if one of the conditions is not met! + * + * @param pFile Path of the file to be imported. + * @param pScene The scene object to hold the imported data. + * nullptr is not a valid parameter. + * @param pIOHandler The IO handler to use for any file access. + * nullptr is not a valid parameter. */ + virtual void InternReadFile( + const std::string &pFile, + aiScene *pScene, + IOSystem *pIOHandler) = 0; + +public: // static utilities + // ------------------------------------------------------------------- + /** A utility for CanRead(). + * + * The function searches the header of a file for a specific token + * and returns true if this token is found. This works for text + * files only. There is a rudimentary handling of UNICODE files. + * The comparison is case independent. + * + * @param pIOSystem IO System to work with + * @param file File name of the file + * @param tokens List of tokens to search for + * @param numTokens Size of the token array + * @param searchBytes Number of bytes to be searched for the tokens. + */ + static bool SearchFileHeaderForToken( + IOSystem *pIOSystem, + const std::string &file, + const char **tokens, + std::size_t numTokens, + unsigned int searchBytes = 200, + bool tokensSol = false, + bool noAlphaBeforeTokens = false); + + // ------------------------------------------------------------------- + /** @brief Check whether a file has a specific file extension + * @param pFile Input file + * @param ext0 Extension to check for. Lowercase characters only, no dot! + * @param ext1 Optional second extension + * @param ext2 Optional third extension + * @note Case-insensitive + */ + static bool SimpleExtensionCheck( + const std::string &pFile, + const char *ext0, + const char *ext1 = nullptr, + const char *ext2 = nullptr); + + // ------------------------------------------------------------------- + /** @brief Extract file extension from a string + * @param pFile Input file + * @return Extension without trailing dot, all lowercase + */ + static std::string GetExtension( + const std::string &pFile); + + // ------------------------------------------------------------------- + /** @brief Check whether a file starts with one or more magic tokens + * @param pFile Input file + * @param pIOHandler IO system to be used + * @param magic n magic tokens + * @params num Size of magic + * @param offset Offset from file start where tokens are located + * @param Size of one token, in bytes. Maximally 16 bytes. + * @return true if one of the given tokens was found + * + * @note For convenience, the check is also performed for the + * byte-swapped variant of all tokens (big endian). Only for + * tokens of size 2,4. + */ + static bool CheckMagicToken( + IOSystem *pIOHandler, + const std::string &pFile, + const void *magic, + std::size_t num, + unsigned int offset = 0, + unsigned int size = 4); + + // ------------------------------------------------------------------- + /** An utility for all text file loaders. It converts a file to our + * UTF8 character set. Errors are reported, but ignored. + * + * @param data File buffer to be converted to UTF8 data. The buffer + * is resized as appropriate. */ + static void ConvertToUTF8( + std::vector &data); + + // ------------------------------------------------------------------- + /** An utility for all text file loaders. It converts a file from our + * UTF8 character set back to ISO-8859-1. Errors are reported, but ignored. + * + * @param data File buffer to be converted from UTF8 to ISO-8859-1. The buffer + * is resized as appropriate. */ + static void ConvertUTF8toISO8859_1( + std::string &data); + + // ------------------------------------------------------------------- + /// @brief Enum to define, if empty files are ok or not. + enum TextFileMode { + ALLOW_EMPTY, + FORBID_EMPTY + }; + + // ------------------------------------------------------------------- + /** Utility for text file loaders which copies the contents of the + * file into a memory buffer and converts it to our UTF8 + * representation. + * @param stream Stream to read from. + * @param data Output buffer to be resized and filled with the + * converted text file data. The buffer is terminated with + * a binary 0. + * @param mode Whether it is OK to load empty text files. */ + static void TextFileToBuffer( + IOStream *stream, + std::vector &data, + TextFileMode mode = FORBID_EMPTY); + + // ------------------------------------------------------------------- + /** Utility function to move a std::vector into a aiScene array + * @param vec The vector to be moved + * @param out The output pointer to the allocated array. + * @param numOut The output count of elements copied. */ + template + AI_FORCE_INLINE static void CopyVector( + std::vector &vec, + T *&out, + unsigned int &outLength) { + outLength = unsigned(vec.size()); + if (outLength) { + out = new T[outLength]; + std::swap_ranges(vec.begin(), vec.end(), out); + } + } + + // ------------------------------------------------------------------- + /** Utility function to move a std::vector of unique_ptrs into a aiScene array + * @param vec The vector of unique_ptrs to be moved + * @param out The output pointer to the allocated array. + * @param numOut The output count of elements copied. */ + template + AI_FORCE_INLINE static void CopyVector( + std::vector > &vec, + T **&out, + unsigned int &outLength) { + outLength = unsigned(vec.size()); + if (outLength) { + out = new T*[outLength]; + T** outPtr = out; + std::for_each(vec.begin(), vec.end(), [&outPtr](std::unique_ptr& uPtr){*outPtr = uPtr.release(); ++outPtr; }); + } + } + +private: + /* Pushes state into importer for the importer scale */ + void UpdateImporterScale(Importer *pImp); + +protected: + /// Error description in case there was one. + std::string m_ErrorText; + /// The exception, in case there was one. + std::exception_ptr m_Exception; + /// Currently set progress handler. + ProgressHandler *m_progress; +}; + +} // end of namespace Assimp + +#endif // AI_BASEIMPORTER_H_INC diff --git a/dependencies/includes/assimp/Bitmap.h b/dependencies/includes/assimp/Bitmap.h new file mode 100644 index 0000000..94dd0b8 --- /dev/null +++ b/dependencies/includes/assimp/Bitmap.h @@ -0,0 +1,133 @@ +/* +--------------------------------------------------------------------------- +Open Asset Import Library (assimp) +--------------------------------------------------------------------------- + +Copyright (c) 2006-2022, assimp team + +All rights reserved. + +Redistribution and use of this software in source and binary forms, +with or without modification, are permitted provided that the following +conditions are met: + +* Redistributions of source code must retain the above + copyright notice, this list of conditions and the + following disclaimer. + +* Redistributions in binary form must reproduce the above + copyright notice, this list of conditions and the + following disclaimer in the documentation and/or other + materials provided with the distribution. + +* Neither the name of the assimp team, nor the names of its + contributors may be used to endorse or promote products + derived from this software without specific prior + written permission of the assimp team. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +--------------------------------------------------------------------------- +*/ + +/** @file Bitmap.h + * @brief Defines bitmap format helper for textures + * + * Used for file formats which embed their textures into the model file. + */ +#pragma once +#ifndef AI_BITMAP_H_INC +#define AI_BITMAP_H_INC + +#ifdef __GNUC__ +# pragma GCC system_header +#endif + +#include "defs.h" +#include +#include + +struct aiTexture; + +namespace Assimp { + +class IOStream; + +// --------------------------------------------------------------------------- +/** + * This class is used to store and write bitmap information. + */ +class ASSIMP_API Bitmap { +protected: + + struct Header { + uint16_t type; + uint32_t size; + uint16_t reserved1; + uint16_t reserved2; + uint32_t offset; + + // We define the struct size because sizeof(Header) might return a wrong result because of structure padding. + static constexpr std::size_t header_size = + sizeof(uint16_t) + + sizeof(uint32_t) + + sizeof(uint16_t) + + sizeof(uint16_t) + + sizeof(uint32_t); + }; + + struct DIB { + uint32_t size; + int32_t width; + int32_t height; + uint16_t planes; + uint16_t bits_per_pixel; + uint32_t compression; + uint32_t image_size; + int32_t x_resolution; + int32_t y_resolution; + uint32_t nb_colors; + uint32_t nb_important_colors; + + // We define the struct size because sizeof(DIB) might return a wrong result because of structure padding. + static constexpr std::size_t dib_size = + sizeof(uint32_t) + + sizeof(int32_t) + + sizeof(int32_t) + + sizeof(uint16_t) + + sizeof(uint16_t) + + sizeof(uint32_t) + + sizeof(uint32_t) + + sizeof(int32_t) + + sizeof(int32_t) + + sizeof(uint32_t) + + sizeof(uint32_t); + }; + + static constexpr std::size_t mBytesPerPixel = 4; + +public: + /// @brief Will save an aiTexture instance as a bitmap. + /// @param texture The pointer to the texture instance + /// @param file The filename to save into. + /// @return true if successfully saved, false if not. + static bool Save(aiTexture* texture, IOStream* file); + +protected: + static void WriteHeader(Header& header, IOStream* file); + static void WriteDIB(DIB& dib, IOStream* file); + static void WriteData(aiTexture* texture, IOStream* file); +}; + +} + +#endif // AI_BITMAP_H_INC diff --git a/dependencies/includes/assimp/BlobIOSystem.h b/dependencies/includes/assimp/BlobIOSystem.h new file mode 100644 index 0000000..7e8d46a --- /dev/null +++ b/dependencies/includes/assimp/BlobIOSystem.h @@ -0,0 +1,323 @@ +/* +--------------------------------------------------------------------------- +Open Asset Import Library (assimp) +--------------------------------------------------------------------------- + +Copyright (c) 2006-2022, assimp team + +All rights reserved. + +Redistribution and use of this software in source and binary forms, +with or without modification, are permitted provided that the following +conditions are met: + +* Redistributions of source code must retain the above + copyright notice, this list of conditions and the + following disclaimer. + +* Redistributions in binary form must reproduce the above + copyright notice, this list of conditions and the + following disclaimer in the documentation and/or other + materials provided with the distribution. + +* Neither the name of the assimp team, nor the names of its + contributors may be used to endorse or promote products + derived from this software without specific prior + written permission of the assimp team. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +--------------------------------------------------------------------------- +*/ + +/** @file Provides cheat implementations for IOSystem and IOStream to + * redirect exporter output to a blob chain.*/ + +#pragma once +#ifndef AI_BLOBIOSYSTEM_H_INCLUDED +#define AI_BLOBIOSYSTEM_H_INCLUDED + +#ifdef __GNUC__ +#pragma GCC system_header +#endif + +#include +#include +#include +#include +#include +#include +#include + +namespace Assimp { +class BlobIOSystem; + +// -------------------------------------------------------------------------------------------- +/** Redirect IOStream to a blob */ +// -------------------------------------------------------------------------------------------- +class BlobIOStream : public IOStream { +public: + /// @brief The class constructor with all needed parameters + /// @param creator Pointer to the creator instance + /// @param file The filename + /// @param initial The initial size + BlobIOStream(BlobIOSystem *creator, const std::string &file, size_t initial = 4096) : + buffer(), + cur_size(), + file_size(), + cursor(), + initial(initial), + file(file), + creator(creator) { + // empty + } + + /// @brief The class destructor. + ~BlobIOStream() override; + +public: + // ------------------------------------------------------------------- + aiExportDataBlob *GetBlob() { + aiExportDataBlob *blob = new aiExportDataBlob(); + blob->size = file_size; + blob->data = buffer; + + buffer = nullptr; + + return blob; + } + + // ------------------------------------------------------------------- + size_t Read(void *, size_t, size_t) override { + return 0; + } + + // ------------------------------------------------------------------- + size_t Write(const void *pvBuffer, size_t pSize, size_t pCount) override { + pSize *= pCount; + if (cursor + pSize > cur_size) { + Grow(cursor + pSize); + } + + memcpy(buffer + cursor, pvBuffer, pSize); + cursor += pSize; + + file_size = std::max(file_size, cursor); + return pCount; + } + + // ------------------------------------------------------------------- + aiReturn Seek(size_t pOffset, aiOrigin pOrigin) override { + switch (pOrigin) { + case aiOrigin_CUR: + cursor += pOffset; + break; + + case aiOrigin_END: + cursor = file_size - pOffset; + break; + + case aiOrigin_SET: + cursor = pOffset; + break; + + default: + return AI_FAILURE; + } + + if (cursor > file_size) { + Grow(cursor); + } + + file_size = std::max(cursor, file_size); + + return AI_SUCCESS; + } + + // ------------------------------------------------------------------- + size_t Tell() const override { + return cursor; + } + + // ------------------------------------------------------------------- + size_t FileSize() const override { + return file_size; + } + + // ------------------------------------------------------------------- + void Flush() override { + // ignore + } + +private: + // ------------------------------------------------------------------- + void Grow(size_t need = 0) { + // 1.5 and phi are very heap-friendly growth factors (the first + // allows for frequent re-use of heap blocks, the second + // forms a fibonacci sequence with similar characteristics - + // since this heavily depends on the heap implementation + // and other factors as well, i'll just go with 1.5 since + // it is quicker to compute). + size_t new_size = std::max(initial, std::max(need, cur_size + (cur_size >> 1))); + + const uint8_t *const old = buffer; + buffer = new uint8_t[new_size]; + + if (old) { + memcpy(buffer, old, cur_size); + delete[] old; + } + + cur_size = new_size; + } + +private: + uint8_t *buffer; + size_t cur_size, file_size, cursor, initial; + + const std::string file; + BlobIOSystem *const creator; +}; + +#define AI_BLOBIO_MAGIC "$blobfile" + +// -------------------------------------------------------------------------------------------- +/** Redirect IOSystem to a blob */ +// -------------------------------------------------------------------------------------------- +class BlobIOSystem : public IOSystem { + + friend class BlobIOStream; + typedef std::pair BlobEntry; + + +public: + /// @brief The default class constructor. + BlobIOSystem() : + baseName{AI_BLOBIO_MAGIC} { + } + + /// @brief The class constructor with the base name. + /// @param baseName The base name. + BlobIOSystem(const std::string &baseName) : + baseName(baseName) { + // empty + } + + ~BlobIOSystem() override { + for (BlobEntry &blobby : blobs) { + delete blobby.second; + } + } + +public: + // ------------------------------------------------------------------- + const char *GetMagicFileName() const { + return baseName.c_str(); + } + + // ------------------------------------------------------------------- + aiExportDataBlob *GetBlobChain() { + const auto magicName = std::string(this->GetMagicFileName()); + const bool hasBaseName = baseName != AI_BLOBIO_MAGIC; + + // one must be the master + aiExportDataBlob *master = nullptr, *cur; + + for (const BlobEntry &blobby : blobs) { + if (blobby.first == magicName) { + master = blobby.second; + master->name.Set(hasBaseName ? blobby.first : ""); + break; + } + } + + if (!master) { + ASSIMP_LOG_ERROR("BlobIOSystem: no data written or master file was not closed properly."); + return nullptr; + } + + cur = master; + + for (const BlobEntry &blobby : blobs) { + if (blobby.second == master) { + continue; + } + + cur->next = blobby.second; + cur = cur->next; + + if (hasBaseName) { + cur->name.Set(blobby.first); + } else { + // extract the file extension from the file written + const std::string::size_type s = blobby.first.find_first_of('.'); + cur->name.Set(s == std::string::npos ? blobby.first : blobby.first.substr(s + 1)); + } + } + + // give up blob ownership + blobs.clear(); + return master; + } + +public: + // ------------------------------------------------------------------- + bool Exists(const char *pFile) const override { + return created.find(std::string(pFile)) != created.end(); + } + + // ------------------------------------------------------------------- + char getOsSeparator() const override { + return '/'; + } + + // ------------------------------------------------------------------- + IOStream *Open(const char *pFile, const char *pMode) override { + if (pMode[0] != 'w') { + return nullptr; + } + + created.insert(std::string(pFile)); + return new BlobIOStream(this, std::string(pFile)); + } + + // ------------------------------------------------------------------- + void Close(IOStream *pFile) override { + delete pFile; + } + +private: + // ------------------------------------------------------------------- + void OnDestruct(const std::string &filename, BlobIOStream *child) { + // we don't know in which the files are closed, so we + // can't reliably say that the first must be the master + // file ... + blobs.emplace_back(filename, child->GetBlob()); + } + +private: + std::string baseName; + std::set created; + std::vector blobs; +}; + +// -------------------------------------------------------------------------------------------- +BlobIOStream::~BlobIOStream() { + if (nullptr != creator) { + creator->OnDestruct(file, this); + } + delete[] buffer; +} + +} // namespace Assimp + +#endif diff --git a/dependencies/includes/assimp/ByteSwapper.h b/dependencies/includes/assimp/ByteSwapper.h new file mode 100644 index 0000000..488f7a5 --- /dev/null +++ b/dependencies/includes/assimp/ByteSwapper.h @@ -0,0 +1,292 @@ +/* +Open Asset Import Library (assimp) +---------------------------------------------------------------------- + +Copyright (c) 2006-2022, assimp team + + +All rights reserved. + +Redistribution and use of this software in source and binary forms, +with or without modification, are permitted provided that the +following conditions are met: + +* Redistributions of source code must retain the above + copyright notice, this list of conditions and the + following disclaimer. + +* Redistributions in binary form must reproduce the above + copyright notice, this list of conditions and the + following disclaimer in the documentation and/or other + materials provided with the distribution. + +* Neither the name of the assimp team, nor the names of its + contributors may be used to endorse or promote products + derived from this software without specific prior + written permission of the assimp team. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +---------------------------------------------------------------------- +*/ + +/** @file Helper class tp perform various byte order swappings + (e.g. little to big endian) */ +#pragma once +#ifndef AI_BYTESWAPPER_H_INC +#define AI_BYTESWAPPER_H_INC + +#ifdef __GNUC__ +# pragma GCC system_header +#endif + +#include +#include +#include + +#if _MSC_VER >= 1400 +#include +#endif + +namespace Assimp { +// -------------------------------------------------------------------------------------- +/** Defines some useful byte order swap routines. + * + * This is required to read big-endian model formats on little-endian machines, + * and vice versa. Direct use of this class is DEPRECATED. Use #StreamReader instead. */ +// -------------------------------------------------------------------------------------- +class ByteSwap { + ByteSwap() AI_NO_EXCEPT {} + +public: + + // ---------------------------------------------------------------------- + /** Swap two bytes of data + * @param[inout] _szOut A void* to save the reintcasts for the caller. */ + static inline void Swap2(void* _szOut) + { + ai_assert(_szOut); + +#if _MSC_VER >= 1400 + uint16_t* const szOut = reinterpret_cast(_szOut); + *szOut = _byteswap_ushort(*szOut); +#else + uint8_t* const szOut = reinterpret_cast(_szOut); + std::swap(szOut[0],szOut[1]); +#endif + } + + // ---------------------------------------------------------------------- + /** Swap four bytes of data + * @param[inout] _szOut A void* to save the reintcasts for the caller. */ + static inline void Swap4(void* _szOut) + { + ai_assert(_szOut); + +#if _MSC_VER >= 1400 + uint32_t* const szOut = reinterpret_cast(_szOut); + *szOut = _byteswap_ulong(*szOut); +#else + uint8_t* const szOut = reinterpret_cast(_szOut); + std::swap(szOut[0],szOut[3]); + std::swap(szOut[1],szOut[2]); +#endif + } + + // ---------------------------------------------------------------------- + /** Swap eight bytes of data + * @param[inout] _szOut A void* to save the reintcasts for the caller. */ + static inline void Swap8(void* _szOut) + { + ai_assert(_szOut); + +#if _MSC_VER >= 1400 + uint64_t* const szOut = reinterpret_cast(_szOut); + *szOut = _byteswap_uint64(*szOut); +#else + uint8_t* const szOut = reinterpret_cast(_szOut); + std::swap(szOut[0],szOut[7]); + std::swap(szOut[1],szOut[6]); + std::swap(szOut[2],szOut[5]); + std::swap(szOut[3],szOut[4]); +#endif + } + + // ---------------------------------------------------------------------- + /** ByteSwap a float. Not a joke. + * @param[inout] fOut ehm. .. */ + static inline void Swap(float* fOut) { + Swap4(fOut); + } + + // ---------------------------------------------------------------------- + /** ByteSwap a double. Not a joke. + * @param[inout] fOut ehm. .. */ + static inline void Swap(double* fOut) { + Swap8(fOut); + } + + + // ---------------------------------------------------------------------- + /** ByteSwap an int16t. Not a joke. + * @param[inout] fOut ehm. .. */ + static inline void Swap(int16_t* fOut) { + Swap2(fOut); + } + + static inline void Swap(uint16_t* fOut) { + Swap2(fOut); + } + + // ---------------------------------------------------------------------- + /** ByteSwap an int32t. Not a joke. + * @param[inout] fOut ehm. .. */ + static inline void Swap(int32_t* fOut){ + Swap4(fOut); + } + + static inline void Swap(uint32_t* fOut){ + Swap4(fOut); + } + + // ---------------------------------------------------------------------- + /** ByteSwap an int64t. Not a joke. + * @param[inout] fOut ehm. .. */ + static inline void Swap(int64_t* fOut) { + Swap8(fOut); + } + + static inline void Swap(uint64_t* fOut) { + Swap8(fOut); + } + + // ---------------------------------------------------------------------- + //! Templatized ByteSwap + //! \returns param tOut as swapped + template + static inline Type Swapped(Type tOut) + { + return _swapper()(tOut); + } + +private: + + template struct _swapper; +}; + +template struct ByteSwap::_swapper { + T operator() (T tOut) { + Swap2(&tOut); + return tOut; + } +}; + +template struct ByteSwap::_swapper { + T operator() (T tOut) { + Swap4(&tOut); + return tOut; + } +}; + +template struct ByteSwap::_swapper { + T operator() (T tOut) { + Swap8(&tOut); + return tOut; + } +}; + + +// -------------------------------------------------------------------------------------- +// ByteSwap macros for BigEndian/LittleEndian support +// -------------------------------------------------------------------------------------- +#if (defined AI_BUILD_BIG_ENDIAN) +# define AI_LE(t) (t) +# define AI_BE(t) Assimp::ByteSwap::Swapped(t) +# define AI_LSWAP2(p) +# define AI_LSWAP4(p) +# define AI_LSWAP8(p) +# define AI_LSWAP2P(p) +# define AI_LSWAP4P(p) +# define AI_LSWAP8P(p) +# define LE_NCONST const +# define AI_SWAP2(p) Assimp::ByteSwap::Swap2(&(p)) +# define AI_SWAP4(p) Assimp::ByteSwap::Swap4(&(p)) +# define AI_SWAP8(p) Assimp::ByteSwap::Swap8(&(p)) +# define AI_SWAP2P(p) Assimp::ByteSwap::Swap2((p)) +# define AI_SWAP4P(p) Assimp::ByteSwap::Swap4((p)) +# define AI_SWAP8P(p) Assimp::ByteSwap::Swap8((p)) +# define BE_NCONST +#else +# define AI_BE(t) (t) +# define AI_LE(t) Assimp::ByteSwap::Swapped(t) +# define AI_SWAP2(p) +# define AI_SWAP4(p) +# define AI_SWAP8(p) +# define AI_SWAP2P(p) +# define AI_SWAP4P(p) +# define AI_SWAP8P(p) +# define BE_NCONST const +# define AI_LSWAP2(p) Assimp::ByteSwap::Swap2(&(p)) +# define AI_LSWAP4(p) Assimp::ByteSwap::Swap4(&(p)) +# define AI_LSWAP8(p) Assimp::ByteSwap::Swap8(&(p)) +# define AI_LSWAP2P(p) Assimp::ByteSwap::Swap2((p)) +# define AI_LSWAP4P(p) Assimp::ByteSwap::Swap4((p)) +# define AI_LSWAP8P(p) Assimp::ByteSwap::Swap8((p)) +# define LE_NCONST +#endif + + +namespace Intern { + +// -------------------------------------------------------------------------------------------- +template +struct ByteSwapper { + void operator() (T* inout) { + ByteSwap::Swap(inout); + } +}; + +template +struct ByteSwapper { + void operator() (T*) { + } +}; + +// -------------------------------------------------------------------------------------------- +template +struct Getter { + void operator() (T* inout, bool le) { +#ifdef AI_BUILD_BIG_ENDIAN + le = le; +#else + le = !le; +#endif + if (le) { + ByteSwapper1?true:false)> () (inout); + } + else ByteSwapper () (inout); + } +}; + +template +struct Getter { + + void operator() (T* inout, bool /*le*/) { + // static branch + ByteSwapper1)> () (inout); + } +}; +} // end Intern +} // end Assimp + +#endif //!! AI_BYTESWAPPER_H_INC diff --git a/dependencies/includes/assimp/ColladaMetaData.h b/dependencies/includes/assimp/ColladaMetaData.h new file mode 100644 index 0000000..52eb3c5 --- /dev/null +++ b/dependencies/includes/assimp/ColladaMetaData.h @@ -0,0 +1,56 @@ +/* +Open Asset Import Library (assimp) +---------------------------------------------------------------------- + +Copyright (c) 2006-2022, assimp team + +All rights reserved. + +Redistribution and use of this software in source and binary forms, +with or without modification, are permitted provided that the +following conditions are met: + +* Redistributions of source code must retain the above + copyright notice, this list of conditions and the + following disclaimer. + +* Redistributions in binary form must reproduce the above + copyright notice, this list of conditions and the + following disclaimer in the documentation and/or other + materials provided with the distribution. + +* Neither the name of the assimp team, nor the names of its + contributors may be used to endorse or promote products + derived from this software without specific prior + written permission of the assimp team. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +---------------------------------------------------------------------- +*/ + +/** @file ColladaMetaData.h + * Declares common metadata constants used by Collada files + */ +#pragma once +#ifndef AI_COLLADAMETADATA_H_INC +#define AI_COLLADAMETADATA_H_INC + +#ifdef __GNUC__ +#pragma GCC system_header +#endif + +#define AI_METADATA_COLLADA_ID "Collada_id" +#define AI_METADATA_COLLADA_SID "Collada_sid" + +#endif diff --git a/dependencies/includes/assimp/Compiler/poppack1.h b/dependencies/includes/assimp/Compiler/poppack1.h new file mode 100644 index 0000000..ff501bc --- /dev/null +++ b/dependencies/includes/assimp/Compiler/poppack1.h @@ -0,0 +1,22 @@ + +// =============================================================================== +// May be included multiple times - resets structure packing to the defaults +// for all supported compilers. Reverts the changes made by #include +// +// Currently this works on the following compilers: +// MSVC 7,8,9 +// GCC +// BORLAND (complains about 'pack state changed but not reverted', but works) +// =============================================================================== + +#ifndef AI_PUSHPACK_IS_DEFINED +# error pushpack1.h must be included after poppack1.h +#endif + +// reset packing to the original value +#if (defined(_MSC_VER) && !defined(__clang__)) || defined(__BORLANDC__) || defined (__BCPLUSPLUS__) +# pragma pack( pop ) +#endif +#undef PACK_STRUCT + +#undef AI_PUSHPACK_IS_DEFINED diff --git a/dependencies/includes/assimp/Compiler/pstdint.h b/dependencies/includes/assimp/Compiler/pstdint.h new file mode 100644 index 0000000..4de4ce2 --- /dev/null +++ b/dependencies/includes/assimp/Compiler/pstdint.h @@ -0,0 +1,912 @@ +/* A portable stdint.h + **************************************************************************** + * BSD License: + **************************************************************************** + * + * Copyright (c) 2005-2016 Paul Hsieh + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + **************************************************************************** + * + * Version 0.1.15.4 + * + * The ANSI C standard committee, for the C99 standard, specified the + * inclusion of a new standard include file called stdint.h. This is + * a very useful and long desired include file which contains several + * very precise definitions for integer scalar types that is + * critically important for making portable several classes of + * applications including cryptography, hashing, variable length + * integer libraries and so on. But for most developers its likely + * useful just for programming sanity. + * + * The problem is that some compiler vendors chose to ignore the C99 + * standard and some older compilers have no opportunity to be updated. + * Because of this situation, simply including stdint.h in your code + * makes it unportable. + * + * So that's what this file is all about. Its an attempt to build a + * single universal include file that works on as many platforms as + * possible to deliver what stdint.h is supposed to. Even compilers + * that already come with stdint.h can use this file instead without + * any loss of functionality. A few things that should be noted about + * this file: + * + * 1) It is not guaranteed to be portable and/or present an identical + * interface on all platforms. The extreme variability of the + * ANSI C standard makes this an impossibility right from the + * very get go. Its really only meant to be useful for the vast + * majority of platforms that possess the capability of + * implementing usefully and precisely defined, standard sized + * integer scalars. Systems which are not intrinsically 2s + * complement may produce invalid constants. + * + * 2) There is an unavoidable use of non-reserved symbols. + * + * 3) Other standard include files are invoked. + * + * 4) This file may come in conflict with future platforms that do + * include stdint.h. The hope is that one or the other can be + * used with no real difference. + * + * 5) In the current version, if your platform can't represent + * int32_t, int16_t and int8_t, it just dumps out with a compiler + * error. + * + * 6) 64 bit integers may or may not be defined. Test for their + * presence with the test: #ifdef INT64_MAX or #ifdef UINT64_MAX. + * Note that this is different from the C99 specification which + * requires the existence of 64 bit support in the compiler. If + * this is not defined for your platform, yet it is capable of + * dealing with 64 bits then it is because this file has not yet + * been extended to cover all of your system's capabilities. + * + * 7) (u)intptr_t may or may not be defined. Test for its presence + * with the test: #ifdef PTRDIFF_MAX. If this is not defined + * for your platform, then it is because this file has not yet + * been extended to cover all of your system's capabilities, not + * because its optional. + * + * 8) The following might not been defined even if your platform is + * capable of defining it: + * + * WCHAR_MIN + * WCHAR_MAX + * (u)int64_t + * PTRDIFF_MIN + * PTRDIFF_MAX + * (u)intptr_t + * + * 9) The following have not been defined: + * + * WINT_MIN + * WINT_MAX + * + * 10) The criteria for defining (u)int_least(*)_t isn't clear, + * except for systems which don't have a type that precisely + * defined 8, 16, or 32 bit types (which this include file does + * not support anyways). Default definitions have been given. + * + * 11) The criteria for defining (u)int_fast(*)_t isn't something I + * would trust to any particular compiler vendor or the ANSI C + * committee. It is well known that "compatible systems" are + * commonly created that have very different performance + * characteristics from the systems they are compatible with, + * especially those whose vendors make both the compiler and the + * system. Default definitions have been given, but its strongly + * recommended that users never use these definitions for any + * reason (they do *NOT* deliver any serious guarantee of + * improved performance -- not in this file, nor any vendor's + * stdint.h). + * + * 12) The following macros: + * + * PRINTF_INTMAX_MODIFIER + * PRINTF_INT64_MODIFIER + * PRINTF_INT32_MODIFIER + * PRINTF_INT16_MODIFIER + * PRINTF_LEAST64_MODIFIER + * PRINTF_LEAST32_MODIFIER + * PRINTF_LEAST16_MODIFIER + * PRINTF_INTPTR_MODIFIER + * + * are strings which have been defined as the modifiers required + * for the "d", "u" and "x" printf formats to correctly output + * (u)intmax_t, (u)int64_t, (u)int32_t, (u)int16_t, (u)least64_t, + * (u)least32_t, (u)least16_t and (u)intptr_t types respectively. + * PRINTF_INTPTR_MODIFIER is not defined for some systems which + * provide their own stdint.h. PRINTF_INT64_MODIFIER is not + * defined if INT64_MAX is not defined. These are an extension + * beyond what C99 specifies must be in stdint.h. + * + * In addition, the following macros are defined: + * + * PRINTF_INTMAX_HEX_WIDTH + * PRINTF_INT64_HEX_WIDTH + * PRINTF_INT32_HEX_WIDTH + * PRINTF_INT16_HEX_WIDTH + * PRINTF_INT8_HEX_WIDTH + * PRINTF_INTMAX_DEC_WIDTH + * PRINTF_INT64_DEC_WIDTH + * PRINTF_INT32_DEC_WIDTH + * PRINTF_INT16_DEC_WIDTH + * PRINTF_UINT8_DEC_WIDTH + * PRINTF_UINTMAX_DEC_WIDTH + * PRINTF_UINT64_DEC_WIDTH + * PRINTF_UINT32_DEC_WIDTH + * PRINTF_UINT16_DEC_WIDTH + * PRINTF_UINT8_DEC_WIDTH + * + * Which specifies the maximum number of characters required to + * print the number of that type in either hexadecimal or decimal. + * These are an extension beyond what C99 specifies must be in + * stdint.h. + * + * Compilers tested (all with 0 warnings at their highest respective + * settings): Borland Turbo C 2.0, WATCOM C/C++ 11.0 (16 bits and 32 + * bits), Microsoft Visual C++ 6.0 (32 bit), Microsoft Visual Studio + * .net (VC7), Intel C++ 4.0, GNU gcc v3.3.3 + * + * This file should be considered a work in progress. Suggestions for + * improvements, especially those which increase coverage are strongly + * encouraged. + * + * Acknowledgements + * + * The following people have made significant contributions to the + * development and testing of this file: + * + * Chris Howie + * John Steele Scott + * Dave Thorup + * John Dill + * Florian Wobbe + * Christopher Sean Morrison + * Mikkel Fahnoe Jorgensen + * + */ + +#include +#include +#include + +/* + * For gcc with _STDINT_H, fill in the PRINTF_INT*_MODIFIER macros, and + * do nothing else. On the Mac OS X version of gcc this is _STDINT_H_. + */ + +#if ((defined(__SUNPRO_C) && __SUNPRO_C >= 0x570) || (defined(_MSC_VER) && _MSC_VER >= 1600) || (defined(__STDC__) && __STDC__ && defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L) || (defined (__WATCOMC__) && (defined (_STDINT_H_INCLUDED) || __WATCOMC__ >= 1250)) || (defined(__GNUC__) && (__GNUC__ > 3 || defined(_STDINT_H) || defined(_STDINT_H_) || defined (__UINT_FAST64_TYPE__)) )) && !defined (_PSTDINT_H_INCLUDED) +#include +#define _PSTDINT_H_INCLUDED +# if defined(__GNUC__) && (defined(__x86_64__) || defined(__ppc64__)) && !(defined(__APPLE__) && defined(__MACH__)) +# ifndef PRINTF_INT64_MODIFIER +# define PRINTF_INT64_MODIFIER "l" +# endif +# ifndef PRINTF_INT32_MODIFIER +# define PRINTF_INT32_MODIFIER "" +# endif +# else +# ifndef PRINTF_INT64_MODIFIER +# define PRINTF_INT64_MODIFIER "ll" +# endif +# ifndef PRINTF_INT32_MODIFIER +# if (UINT_MAX == UINT32_MAX) +# define PRINTF_INT32_MODIFIER "" +# else +# define PRINTF_INT32_MODIFIER "l" +# endif +# endif +# endif +# ifndef PRINTF_INT16_MODIFIER +# define PRINTF_INT16_MODIFIER "h" +# endif +# ifndef PRINTF_INTMAX_MODIFIER +# define PRINTF_INTMAX_MODIFIER PRINTF_INT64_MODIFIER +# endif +# ifndef PRINTF_INT64_HEX_WIDTH +# define PRINTF_INT64_HEX_WIDTH "16" +# endif +# ifndef PRINTF_UINT64_HEX_WIDTH +# define PRINTF_UINT64_HEX_WIDTH "16" +# endif +# ifndef PRINTF_INT32_HEX_WIDTH +# define PRINTF_INT32_HEX_WIDTH "8" +# endif +# ifndef PRINTF_UINT32_HEX_WIDTH +# define PRINTF_UINT32_HEX_WIDTH "8" +# endif +# ifndef PRINTF_INT16_HEX_WIDTH +# define PRINTF_INT16_HEX_WIDTH "4" +# endif +# ifndef PRINTF_UINT16_HEX_WIDTH +# define PRINTF_UINT16_HEX_WIDTH "4" +# endif +# ifndef PRINTF_INT8_HEX_WIDTH +# define PRINTF_INT8_HEX_WIDTH "2" +# endif +# ifndef PRINTF_UINT8_HEX_WIDTH +# define PRINTF_UINT8_HEX_WIDTH "2" +# endif +# ifndef PRINTF_INT64_DEC_WIDTH +# define PRINTF_INT64_DEC_WIDTH "19" +# endif +# ifndef PRINTF_UINT64_DEC_WIDTH +# define PRINTF_UINT64_DEC_WIDTH "20" +# endif +# ifndef PRINTF_INT32_DEC_WIDTH +# define PRINTF_INT32_DEC_WIDTH "10" +# endif +# ifndef PRINTF_UINT32_DEC_WIDTH +# define PRINTF_UINT32_DEC_WIDTH "10" +# endif +# ifndef PRINTF_INT16_DEC_WIDTH +# define PRINTF_INT16_DEC_WIDTH "5" +# endif +# ifndef PRINTF_UINT16_DEC_WIDTH +# define PRINTF_UINT16_DEC_WIDTH "5" +# endif +# ifndef PRINTF_INT8_DEC_WIDTH +# define PRINTF_INT8_DEC_WIDTH "3" +# endif +# ifndef PRINTF_UINT8_DEC_WIDTH +# define PRINTF_UINT8_DEC_WIDTH "3" +# endif +# ifndef PRINTF_INTMAX_HEX_WIDTH +# define PRINTF_INTMAX_HEX_WIDTH PRINTF_UINT64_HEX_WIDTH +# endif +# ifndef PRINTF_UINTMAX_HEX_WIDTH +# define PRINTF_UINTMAX_HEX_WIDTH PRINTF_UINT64_HEX_WIDTH +# endif +# ifndef PRINTF_INTMAX_DEC_WIDTH +# define PRINTF_INTMAX_DEC_WIDTH PRINTF_UINT64_DEC_WIDTH +# endif +# ifndef PRINTF_UINTMAX_DEC_WIDTH +# define PRINTF_UINTMAX_DEC_WIDTH PRINTF_UINT64_DEC_WIDTH +# endif + +/* + * Something really weird is going on with Open Watcom. Just pull some of + * these duplicated definitions from Open Watcom's stdint.h file for now. + */ + +# if defined (__WATCOMC__) && __WATCOMC__ >= 1250 +# if !defined (INT64_C) +# define INT64_C(x) (x + (INT64_MAX - INT64_MAX)) +# endif +# if !defined (UINT64_C) +# define UINT64_C(x) (x + (UINT64_MAX - UINT64_MAX)) +# endif +# if !defined (INT32_C) +# define INT32_C(x) (x + (INT32_MAX - INT32_MAX)) +# endif +# if !defined (UINT32_C) +# define UINT32_C(x) (x + (UINT32_MAX - UINT32_MAX)) +# endif +# if !defined (INT16_C) +# define INT16_C(x) (x) +# endif +# if !defined (UINT16_C) +# define UINT16_C(x) (x) +# endif +# if !defined (INT8_C) +# define INT8_C(x) (x) +# endif +# if !defined (UINT8_C) +# define UINT8_C(x) (x) +# endif +# if !defined (UINT64_MAX) +# define UINT64_MAX 18446744073709551615ULL +# endif +# if !defined (INT64_MAX) +# define INT64_MAX 9223372036854775807LL +# endif +# if !defined (UINT32_MAX) +# define UINT32_MAX 4294967295UL +# endif +# if !defined (INT32_MAX) +# define INT32_MAX 2147483647L +# endif +# if !defined (INTMAX_MAX) +# define INTMAX_MAX INT64_MAX +# endif +# if !defined (INTMAX_MIN) +# define INTMAX_MIN INT64_MIN +# endif +# endif +#endif + +/* + * I have no idea what is the truly correct thing to do on older Solaris. + * From some online discussions, this seems to be what is being + * recommended. For people who actually are developing on older Solaris, + * what I would like to know is, does this define all of the relevant + * macros of a complete stdint.h? Remember, in pstdint.h 64 bit is + * considered optional. + */ + +#if (defined(__SUNPRO_C) && __SUNPRO_C >= 0x420) && !defined(_PSTDINT_H_INCLUDED) +#include +#define _PSTDINT_H_INCLUDED +#endif + +#ifndef _PSTDINT_H_INCLUDED +#define _PSTDINT_H_INCLUDED + +#ifndef SIZE_MAX +# define SIZE_MAX (~(size_t)0) +#endif + +/* + * Deduce the type assignments from limits.h under the assumption that + * integer sizes in bits are powers of 2, and follow the ANSI + * definitions. + */ + +#ifndef UINT8_MAX +# define UINT8_MAX 0xff +#endif +#if !defined(uint8_t) && !defined(_UINT8_T) && !defined(vxWorks) +# if (UCHAR_MAX == UINT8_MAX) || defined (S_SPLINT_S) + typedef unsigned char uint8_t; +# define UINT8_C(v) ((uint8_t) v) +# else +# error "Platform not supported" +# endif +#endif + +#ifndef INT8_MAX +# define INT8_MAX 0x7f +#endif +#ifndef INT8_MIN +# define INT8_MIN INT8_C(0x80) +#endif +#if !defined(int8_t) && !defined(_INT8_T) && !defined(vxWorks) +# if (SCHAR_MAX == INT8_MAX) || defined (S_SPLINT_S) + typedef signed char int8_t; +# define INT8_C(v) ((int8_t) v) +# else +# error "Platform not supported" +# endif +#endif + +#ifndef UINT16_MAX +# define UINT16_MAX 0xffff +#endif +#if !defined(uint16_t) && !defined(_UINT16_T) && !defined(vxWorks) +#if (UINT_MAX == UINT16_MAX) || defined (S_SPLINT_S) + typedef unsigned int uint16_t; +# ifndef PRINTF_INT16_MODIFIER +# define PRINTF_INT16_MODIFIER "" +# endif +# define UINT16_C(v) ((uint16_t) (v)) +#elif (USHRT_MAX == UINT16_MAX) + typedef unsigned short uint16_t; +# define UINT16_C(v) ((uint16_t) (v)) +# ifndef PRINTF_INT16_MODIFIER +# define PRINTF_INT16_MODIFIER "h" +# endif +#else +#error "Platform not supported" +#endif +#endif + +#ifndef INT16_MAX +# define INT16_MAX 0x7fff +#endif +#ifndef INT16_MIN +# define INT16_MIN INT16_C(0x8000) +#endif +#if !defined(int16_t) && !defined(_INT16_T) && !defined(vxWorks) +#if (INT_MAX == INT16_MAX) || defined (S_SPLINT_S) + typedef signed int int16_t; +# define INT16_C(v) ((int16_t) (v)) +# ifndef PRINTF_INT16_MODIFIER +# define PRINTF_INT16_MODIFIER "" +# endif +#elif (SHRT_MAX == INT16_MAX) + typedef signed short int16_t; +# define INT16_C(v) ((int16_t) (v)) +# ifndef PRINTF_INT16_MODIFIER +# define PRINTF_INT16_MODIFIER "h" +# endif +#else +#error "Platform not supported" +#endif +#endif + +#ifndef UINT32_MAX +# define UINT32_MAX (0xffffffffUL) +#endif +#if !defined(uint32_t) && !defined(_UINT32_T) && !defined(vxWorks) +#if (ULONG_MAX == UINT32_MAX) || defined (S_SPLINT_S) + typedef unsigned long uint32_t; +# define UINT32_C(v) v ## UL +# ifndef PRINTF_INT32_MODIFIER +# define PRINTF_INT32_MODIFIER "l" +# endif +#elif (UINT_MAX == UINT32_MAX) + typedef unsigned int uint32_t; +# ifndef PRINTF_INT32_MODIFIER +# define PRINTF_INT32_MODIFIER "" +# endif +# define UINT32_C(v) v ## U +#elif (USHRT_MAX == UINT32_MAX) + typedef unsigned short uint32_t; +# define UINT32_C(v) ((unsigned short) (v)) +# ifndef PRINTF_INT32_MODIFIER +# define PRINTF_INT32_MODIFIER "" +# endif +#else +#error "Platform not supported" +#endif +#endif + +#ifndef INT32_MAX +# define INT32_MAX (0x7fffffffL) +#endif +#ifndef INT32_MIN +# define INT32_MIN INT32_C(0x80000000) +#endif +#if !defined(int32_t) && !defined(_INT32_T) && !defined(vxWorks) +#if (LONG_MAX == INT32_MAX) || defined (S_SPLINT_S) + typedef signed long int32_t; +# define INT32_C(v) v ## L +# ifndef PRINTF_INT32_MODIFIER +# define PRINTF_INT32_MODIFIER "l" +# endif +#elif (INT_MAX == INT32_MAX) + typedef signed int int32_t; +# define INT32_C(v) v +# ifndef PRINTF_INT32_MODIFIER +# define PRINTF_INT32_MODIFIER "" +# endif +#elif (SHRT_MAX == INT32_MAX) + typedef signed short int32_t; +# define INT32_C(v) ((short) (v)) +# ifndef PRINTF_INT32_MODIFIER +# define PRINTF_INT32_MODIFIER "" +# endif +#else +#error "Platform not supported" +#endif +#endif + +/* + * The macro stdint_int64_defined is temporarily used to record + * whether or not 64 integer support is available. It must be + * defined for any 64 integer extensions for new platforms that are + * added. + */ + +#undef stdint_int64_defined +#if (defined(__STDC__) && defined(__STDC_VERSION__)) || defined (S_SPLINT_S) +# if (__STDC__ && __STDC_VERSION__ >= 199901L) || defined (S_SPLINT_S) +# define stdint_int64_defined + typedef long long int64_t; + typedef unsigned long long uint64_t; +# define UINT64_C(v) v ## ULL +# define INT64_C(v) v ## LL +# ifndef PRINTF_INT64_MODIFIER +# define PRINTF_INT64_MODIFIER "ll" +# endif +# endif +#endif + +#if !defined (stdint_int64_defined) +# if defined(__GNUC__) && !defined(vxWorks) +# define stdint_int64_defined + __extension__ typedef long long int64_t; + __extension__ typedef unsigned long long uint64_t; +# define UINT64_C(v) v ## ULL +# define INT64_C(v) v ## LL +# ifndef PRINTF_INT64_MODIFIER +# define PRINTF_INT64_MODIFIER "ll" +# endif +# elif defined(__MWERKS__) || defined (__SUNPRO_C) || defined (__SUNPRO_CC) || defined (__APPLE_CC__) || defined (_LONG_LONG) || defined (_CRAYC) || defined (S_SPLINT_S) +# define stdint_int64_defined + typedef long long int64_t; + typedef unsigned long long uint64_t; +# define UINT64_C(v) v ## ULL +# define INT64_C(v) v ## LL +# ifndef PRINTF_INT64_MODIFIER +# define PRINTF_INT64_MODIFIER "ll" +# endif +# elif (defined(__WATCOMC__) && defined(__WATCOM_INT64__)) || (defined(_MSC_VER) && _INTEGRAL_MAX_BITS >= 64) || (defined (__BORLANDC__) && __BORLANDC__ > 0x460) || defined (__alpha) || defined (__DECC) +# define stdint_int64_defined + typedef __int64 int64_t; + typedef unsigned __int64 uint64_t; +# define UINT64_C(v) v ## UI64 +# define INT64_C(v) v ## I64 +# ifndef PRINTF_INT64_MODIFIER +# define PRINTF_INT64_MODIFIER "I64" +# endif +# endif +#endif + +#if !defined (LONG_LONG_MAX) && defined (INT64_C) +# define LONG_LONG_MAX INT64_C (9223372036854775807) +#endif +#ifndef ULONG_LONG_MAX +# define ULONG_LONG_MAX UINT64_C (18446744073709551615) +#endif + +#if !defined (INT64_MAX) && defined (INT64_C) +# define INT64_MAX INT64_C (9223372036854775807) +#endif +#if !defined (INT64_MIN) && defined (INT64_C) +# define INT64_MIN INT64_C (-9223372036854775808) +#endif +#if !defined (UINT64_MAX) && defined (INT64_C) +# define UINT64_MAX UINT64_C (18446744073709551615) +#endif + +/* + * Width of hexadecimal for number field. + */ + +#ifndef PRINTF_INT64_HEX_WIDTH +# define PRINTF_INT64_HEX_WIDTH "16" +#endif +#ifndef PRINTF_INT32_HEX_WIDTH +# define PRINTF_INT32_HEX_WIDTH "8" +#endif +#ifndef PRINTF_INT16_HEX_WIDTH +# define PRINTF_INT16_HEX_WIDTH "4" +#endif +#ifndef PRINTF_INT8_HEX_WIDTH +# define PRINTF_INT8_HEX_WIDTH "2" +#endif +#ifndef PRINTF_INT64_DEC_WIDTH +# define PRINTF_INT64_DEC_WIDTH "19" +#endif +#ifndef PRINTF_INT32_DEC_WIDTH +# define PRINTF_INT32_DEC_WIDTH "10" +#endif +#ifndef PRINTF_INT16_DEC_WIDTH +# define PRINTF_INT16_DEC_WIDTH "5" +#endif +#ifndef PRINTF_INT8_DEC_WIDTH +# define PRINTF_INT8_DEC_WIDTH "3" +#endif +#ifndef PRINTF_UINT64_DEC_WIDTH +# define PRINTF_UINT64_DEC_WIDTH "20" +#endif +#ifndef PRINTF_UINT32_DEC_WIDTH +# define PRINTF_UINT32_DEC_WIDTH "10" +#endif +#ifndef PRINTF_UINT16_DEC_WIDTH +# define PRINTF_UINT16_DEC_WIDTH "5" +#endif +#ifndef PRINTF_UINT8_DEC_WIDTH +# define PRINTF_UINT8_DEC_WIDTH "3" +#endif + +/* + * Ok, lets not worry about 128 bit integers for now. Moore's law says + * we don't need to worry about that until about 2040 at which point + * we'll have bigger things to worry about. + */ + +#ifdef stdint_int64_defined + typedef int64_t intmax_t; + typedef uint64_t uintmax_t; +# define INTMAX_MAX INT64_MAX +# define INTMAX_MIN INT64_MIN +# define UINTMAX_MAX UINT64_MAX +# define UINTMAX_C(v) UINT64_C(v) +# define INTMAX_C(v) INT64_C(v) +# ifndef PRINTF_INTMAX_MODIFIER +# define PRINTF_INTMAX_MODIFIER PRINTF_INT64_MODIFIER +# endif +# ifndef PRINTF_INTMAX_HEX_WIDTH +# define PRINTF_INTMAX_HEX_WIDTH PRINTF_INT64_HEX_WIDTH +# endif +# ifndef PRINTF_INTMAX_DEC_WIDTH +# define PRINTF_INTMAX_DEC_WIDTH PRINTF_INT64_DEC_WIDTH +# endif +#else + typedef int32_t intmax_t; + typedef uint32_t uintmax_t; +# define INTMAX_MAX INT32_MAX +# define UINTMAX_MAX UINT32_MAX +# define UINTMAX_C(v) UINT32_C(v) +# define INTMAX_C(v) INT32_C(v) +# ifndef PRINTF_INTMAX_MODIFIER +# define PRINTF_INTMAX_MODIFIER PRINTF_INT32_MODIFIER +# endif +# ifndef PRINTF_INTMAX_HEX_WIDTH +# define PRINTF_INTMAX_HEX_WIDTH PRINTF_INT32_HEX_WIDTH +# endif +# ifndef PRINTF_INTMAX_DEC_WIDTH +# define PRINTF_INTMAX_DEC_WIDTH PRINTF_INT32_DEC_WIDTH +# endif +#endif + +/* + * Because this file currently only supports platforms which have + * precise powers of 2 as bit sizes for the default integers, the + * least definitions are all trivial. Its possible that a future + * version of this file could have different definitions. + */ + +#ifndef stdint_least_defined + typedef int8_t int_least8_t; + typedef uint8_t uint_least8_t; + typedef int16_t int_least16_t; + typedef uint16_t uint_least16_t; + typedef int32_t int_least32_t; + typedef uint32_t uint_least32_t; +# define PRINTF_LEAST32_MODIFIER PRINTF_INT32_MODIFIER +# define PRINTF_LEAST16_MODIFIER PRINTF_INT16_MODIFIER +# define UINT_LEAST8_MAX UINT8_MAX +# define INT_LEAST8_MAX INT8_MAX +# define UINT_LEAST16_MAX UINT16_MAX +# define INT_LEAST16_MAX INT16_MAX +# define UINT_LEAST32_MAX UINT32_MAX +# define INT_LEAST32_MAX INT32_MAX +# define INT_LEAST8_MIN INT8_MIN +# define INT_LEAST16_MIN INT16_MIN +# define INT_LEAST32_MIN INT32_MIN +# ifdef stdint_int64_defined + typedef int64_t int_least64_t; + typedef uint64_t uint_least64_t; +# define PRINTF_LEAST64_MODIFIER PRINTF_INT64_MODIFIER +# define UINT_LEAST64_MAX UINT64_MAX +# define INT_LEAST64_MAX INT64_MAX +# define INT_LEAST64_MIN INT64_MIN +# endif +#endif +#undef stdint_least_defined + +/* + * The ANSI C committee pretending to know or specify anything about + * performance is the epitome of misguided arrogance. The mandate of + * this file is to *ONLY* ever support that absolute minimum + * definition of the fast integer types, for compatibility purposes. + * No extensions, and no attempt to suggest what may or may not be a + * faster integer type will ever be made in this file. Developers are + * warned to stay away from these types when using this or any other + * stdint.h. + */ + +typedef int_least8_t int_fast8_t; +typedef uint_least8_t uint_fast8_t; +typedef int_least16_t int_fast16_t; +typedef uint_least16_t uint_fast16_t; +typedef int_least32_t int_fast32_t; +typedef uint_least32_t uint_fast32_t; +#define UINT_FAST8_MAX UINT_LEAST8_MAX +#define INT_FAST8_MAX INT_LEAST8_MAX +#define UINT_FAST16_MAX UINT_LEAST16_MAX +#define INT_FAST16_MAX INT_LEAST16_MAX +#define UINT_FAST32_MAX UINT_LEAST32_MAX +#define INT_FAST32_MAX INT_LEAST32_MAX +#define INT_FAST8_MIN INT_LEAST8_MIN +#define INT_FAST16_MIN INT_LEAST16_MIN +#define INT_FAST32_MIN INT_LEAST32_MIN +#ifdef stdint_int64_defined + typedef int_least64_t int_fast64_t; + typedef uint_least64_t uint_fast64_t; +# define UINT_FAST64_MAX UINT_LEAST64_MAX +# define INT_FAST64_MAX INT_LEAST64_MAX +# define INT_FAST64_MIN INT_LEAST64_MIN +#endif + +#undef stdint_int64_defined + +/* + * Whatever piecemeal, per compiler thing we can do about the wchar_t + * type limits. + */ + +#if defined(__WATCOMC__) || defined(_MSC_VER) || defined (__GNUC__) && !defined(vxWorks) +# include +# ifndef WCHAR_MIN +# define WCHAR_MIN 0 +# endif +# ifndef WCHAR_MAX +# define WCHAR_MAX ((wchar_t)-1) +# endif +#endif + +/* + * Whatever piecemeal, per compiler/platform thing we can do about the + * (u)intptr_t types and limits. + */ + +#if (defined (_MSC_VER) && defined (_UINTPTR_T_DEFINED)) || defined (_UINTPTR_T) +# define STDINT_H_UINTPTR_T_DEFINED +#endif + +#ifndef STDINT_H_UINTPTR_T_DEFINED +# if defined (__alpha__) || defined (__ia64__) || defined (__x86_64__) || defined (_WIN64) || defined (__ppc64__) +# define stdint_intptr_bits 64 +# elif defined (__WATCOMC__) || defined (__TURBOC__) +# if defined(__TINY__) || defined(__SMALL__) || defined(__MEDIUM__) +# define stdint_intptr_bits 16 +# else +# define stdint_intptr_bits 32 +# endif +# elif defined (__i386__) || defined (_WIN32) || defined (WIN32) || defined (__ppc64__) +# define stdint_intptr_bits 32 +# elif defined (__INTEL_COMPILER) +/* TODO -- what did Intel do about x86-64? */ +# else +/* #error "This platform might not be supported yet" */ +# endif + +# ifdef stdint_intptr_bits +# define stdint_intptr_glue3_i(a,b,c) a##b##c +# define stdint_intptr_glue3(a,b,c) stdint_intptr_glue3_i(a,b,c) +# ifndef PRINTF_INTPTR_MODIFIER +# define PRINTF_INTPTR_MODIFIER stdint_intptr_glue3(PRINTF_INT,stdint_intptr_bits,_MODIFIER) +# endif +# ifndef PTRDIFF_MAX +# define PTRDIFF_MAX stdint_intptr_glue3(INT,stdint_intptr_bits,_MAX) +# endif +# ifndef PTRDIFF_MIN +# define PTRDIFF_MIN stdint_intptr_glue3(INT,stdint_intptr_bits,_MIN) +# endif +# ifndef UINTPTR_MAX +# define UINTPTR_MAX stdint_intptr_glue3(UINT,stdint_intptr_bits,_MAX) +# endif +# ifndef INTPTR_MAX +# define INTPTR_MAX stdint_intptr_glue3(INT,stdint_intptr_bits,_MAX) +# endif +# ifndef INTPTR_MIN +# define INTPTR_MIN stdint_intptr_glue3(INT,stdint_intptr_bits,_MIN) +# endif +# ifndef INTPTR_C +# define INTPTR_C(x) stdint_intptr_glue3(INT,stdint_intptr_bits,_C)(x) +# endif +# ifndef UINTPTR_C +# define UINTPTR_C(x) stdint_intptr_glue3(UINT,stdint_intptr_bits,_C)(x) +# endif + typedef stdint_intptr_glue3(uint,stdint_intptr_bits,_t) uintptr_t; + typedef stdint_intptr_glue3( int,stdint_intptr_bits,_t) intptr_t; +# else +/* TODO -- This following is likely wrong for some platforms, and does + nothing for the definition of uintptr_t. */ + typedef ptrdiff_t intptr_t; +# endif +# define STDINT_H_UINTPTR_T_DEFINED +#endif + +/* + * Assumes sig_atomic_t is signed and we have a 2s complement machine. + */ + +#ifndef SIG_ATOMIC_MAX +# define SIG_ATOMIC_MAX ((((sig_atomic_t) 1) << (sizeof (sig_atomic_t)*CHAR_BIT-1)) - 1) +#endif + +#endif + +#if defined (__TEST_PSTDINT_FOR_CORRECTNESS) + +/* + * Please compile with the maximum warning settings to make sure macros are + * not defined more than once. + */ + +#include +#include +#include + +#define glue3_aux(x,y,z) x ## y ## z +#define glue3(x,y,z) glue3_aux(x,y,z) + +#define DECLU(bits) glue3(uint,bits,_t) glue3(u,bits,) = glue3(UINT,bits,_C) (0); +#define DECLI(bits) glue3(int,bits,_t) glue3(i,bits,) = glue3(INT,bits,_C) (0); + +#define DECL(us,bits) glue3(DECL,us,) (bits) + +#define TESTUMAX(bits) glue3(u,bits,) = ~glue3(u,bits,); if (glue3(UINT,bits,_MAX) != glue3(u,bits,)) printf ("Something wrong with UINT%d_MAX\n", bits) + +#define REPORTERROR(msg) { err_n++; if (err_first <= 0) err_first = __LINE__; printf msg; } + +int main () { + int err_n = 0; + int err_first = 0; + DECL(I,8) + DECL(U,8) + DECL(I,16) + DECL(U,16) + DECL(I,32) + DECL(U,32) +#ifdef INT64_MAX + DECL(I,64) + DECL(U,64) +#endif + intmax_t imax = INTMAX_C(0); + uintmax_t umax = UINTMAX_C(0); + char str0[256], str1[256]; + + sprintf (str0, "%" PRINTF_INT32_MODIFIER "d", INT32_C(2147483647)); + if (0 != strcmp (str0, "2147483647")) REPORTERROR (("Something wrong with PRINTF_INT32_MODIFIER : %s\n", str0)); + if (atoi(PRINTF_INT32_DEC_WIDTH) != (int) strlen(str0)) REPORTERROR (("Something wrong with PRINTF_INT32_DEC_WIDTH : %s\n", PRINTF_INT32_DEC_WIDTH)); + sprintf (str0, "%" PRINTF_INT32_MODIFIER "u", UINT32_C(4294967295)); + if (0 != strcmp (str0, "4294967295")) REPORTERROR (("Something wrong with PRINTF_INT32_MODIFIER : %s\n", str0)); + if (atoi(PRINTF_UINT32_DEC_WIDTH) != (int) strlen(str0)) REPORTERROR (("Something wrong with PRINTF_UINT32_DEC_WIDTH : %s\n", PRINTF_UINT32_DEC_WIDTH)); +#ifdef INT64_MAX + sprintf (str1, "%" PRINTF_INT64_MODIFIER "d", INT64_C(9223372036854775807)); + if (0 != strcmp (str1, "9223372036854775807")) REPORTERROR (("Something wrong with PRINTF_INT32_MODIFIER : %s\n", str1)); + if (atoi(PRINTF_INT64_DEC_WIDTH) != (int) strlen(str1)) REPORTERROR (("Something wrong with PRINTF_INT64_DEC_WIDTH : %s, %d\n", PRINTF_INT64_DEC_WIDTH, (int) strlen(str1))); + sprintf (str1, "%" PRINTF_INT64_MODIFIER "u", UINT64_C(18446744073709550591)); + if (0 != strcmp (str1, "18446744073709550591")) REPORTERROR (("Something wrong with PRINTF_INT32_MODIFIER : %s\n", str1)); + if (atoi(PRINTF_UINT64_DEC_WIDTH) != (int) strlen(str1)) REPORTERROR (("Something wrong with PRINTF_UINT64_DEC_WIDTH : %s, %d\n", PRINTF_UINT64_DEC_WIDTH, (int) strlen(str1))); +#endif + + sprintf (str0, "%d %x\n", 0, ~0); + + sprintf (str1, "%d %x\n", i8, ~0); + if (0 != strcmp (str0, str1)) REPORTERROR (("Something wrong with i8 : %s\n", str1)); + sprintf (str1, "%u %x\n", u8, ~0); + if (0 != strcmp (str0, str1)) REPORTERROR (("Something wrong with u8 : %s\n", str1)); + sprintf (str1, "%d %x\n", i16, ~0); + if (0 != strcmp (str0, str1)) REPORTERROR (("Something wrong with i16 : %s\n", str1)); + sprintf (str1, "%u %x\n", u16, ~0); + if (0 != strcmp (str0, str1)) REPORTERROR (("Something wrong with u16 : %s\n", str1)); + sprintf (str1, "%" PRINTF_INT32_MODIFIER "d %x\n", i32, ~0); + if (0 != strcmp (str0, str1)) REPORTERROR (("Something wrong with i32 : %s\n", str1)); + sprintf (str1, "%" PRINTF_INT32_MODIFIER "u %x\n", u32, ~0); + if (0 != strcmp (str0, str1)) REPORTERROR (("Something wrong with u32 : %s\n", str1)); +#ifdef INT64_MAX + sprintf (str1, "%" PRINTF_INT64_MODIFIER "d %x\n", i64, ~0); + if (0 != strcmp (str0, str1)) REPORTERROR (("Something wrong with i64 : %s\n", str1)); +#endif + sprintf (str1, "%" PRINTF_INTMAX_MODIFIER "d %x\n", imax, ~0); + if (0 != strcmp (str0, str1)) REPORTERROR (("Something wrong with imax : %s\n", str1)); + sprintf (str1, "%" PRINTF_INTMAX_MODIFIER "u %x\n", umax, ~0); + if (0 != strcmp (str0, str1)) REPORTERROR (("Something wrong with umax : %s\n", str1)); + + TESTUMAX(8); + TESTUMAX(16); + TESTUMAX(32); +#ifdef INT64_MAX + TESTUMAX(64); +#endif + +#define STR(v) #v +#define Q(v) printf ("sizeof " STR(v) " = %u\n", (unsigned) sizeof (v)); + if (err_n) { + printf ("pstdint.h is not correct. Please use sizes below to correct it:\n"); + } + + Q(int) + Q(unsigned) + Q(long int) + Q(short int) + Q(int8_t) + Q(int16_t) + Q(int32_t) +#ifdef INT64_MAX + Q(int64_t) +#endif + + return EXIT_SUCCESS; +} + +#endif diff --git a/dependencies/includes/assimp/Compiler/pushpack1.h b/dependencies/includes/assimp/Compiler/pushpack1.h new file mode 100644 index 0000000..b32ed17 --- /dev/null +++ b/dependencies/includes/assimp/Compiler/pushpack1.h @@ -0,0 +1,43 @@ + + +// =============================================================================== +// May be included multiple times - sets structure packing to 1 +// for all supported compilers. #include reverts the changes. +// +// Currently this works on the following compilers: +// MSVC 7,8,9 +// GCC +// BORLAND (complains about 'pack state changed but not reverted', but works) +// Clang +// +// +// USAGE: +// +// struct StructToBePacked { +// } PACK_STRUCT; +// +// =============================================================================== + +#ifdef AI_PUSHPACK_IS_DEFINED +# error poppack1.h must be included after pushpack1.h +#endif + +#if (defined(_MSC_VER) && !defined(__clang__)) || defined(__BORLANDC__) || defined (__BCPLUSPLUS__) +# pragma pack(push,1) +# define PACK_STRUCT +#elif defined( __GNUC__ ) || defined(__clang__) +# if !defined(HOST_MINGW) +# define PACK_STRUCT __attribute__((__packed__)) +# else +# define PACK_STRUCT __attribute__((gcc_struct, __packed__)) +# endif +#else +# error Compiler not supported +#endif + +#if defined(_MSC_VER) +// C4103: Packing was changed after the inclusion of the header, probably missing #pragma pop +# pragma warning (disable : 4103) +#endif + +#define AI_PUSHPACK_IS_DEFINED diff --git a/dependencies/includes/assimp/CreateAnimMesh.h b/dependencies/includes/assimp/CreateAnimMesh.h new file mode 100644 index 0000000..e5211f5 --- /dev/null +++ b/dependencies/includes/assimp/CreateAnimMesh.h @@ -0,0 +1,77 @@ +/* +Open Asset Import Library (assimp) +---------------------------------------------------------------------- + +Copyright (c) 2006-2022, assimp team + +All rights reserved. + +Redistribution and use of this software in source and binary forms, +with or without modification, are permitted provided that the +following conditions are met: + +* Redistributions of source code must retain the above + copyright notice, this list of conditions and the + following disclaimer. + +* Redistributions in binary form must reproduce the above + copyright notice, this list of conditions and the + following disclaimer in the documentation and/or other + materials provided with the distribution. + +* Neither the name of the assimp team, nor the names of its + contributors may be used to endorse or promote products + derived from this software without specific prior + written permission of the assimp team. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +---------------------------------------------------------------------- +*/ + +/** @file CreateAnimMesh.h + * Create AnimMesh from Mesh + */ +#pragma once +#ifndef INCLUDED_AI_CREATE_ANIM_MESH_H +#define INCLUDED_AI_CREATE_ANIM_MESH_H + +#ifdef __GNUC__ +# pragma GCC system_header +#endif + +#include + +namespace Assimp { + +/** + * Create aiAnimMesh from aiMesh. + * @param mesh The input mesh to create an animated mesh from. + * @param needPositions If true, positions will be copied from. + * @param needNormals If true, normals will be copied from. + * @param needTangents If true, tangents and bitangents will be copied from. + * @param needColors If true, colors will be copied from. + * @param needTexCoords If true, texCoords will be copied from. + * @return The new created animated mesh. + */ +ASSIMP_API aiAnimMesh *aiCreateAnimMesh(const aiMesh *mesh, + bool needPositions = true, + bool needNormals = true, + bool needTangents = true, + bool needColors = true, + bool needTexCoords = true); + +} // end of namespace Assimp + +#endif // INCLUDED_AI_CREATE_ANIM_MESH_H + diff --git a/dependencies/includes/assimp/DefaultIOStream.h b/dependencies/includes/assimp/DefaultIOStream.h new file mode 100644 index 0000000..aa298a6 --- /dev/null +++ b/dependencies/includes/assimp/DefaultIOStream.h @@ -0,0 +1,139 @@ +/* +Open Asset Import Library (assimp) +---------------------------------------------------------------------- + +Copyright (c) 2006-2022, assimp team + +All rights reserved. + +Redistribution and use of this software in source and binary forms, +with or without modification, are permitted provided that the +following conditions are met: + +* Redistributions of source code must retain the above + copyright notice, this list of conditions and the + following disclaimer. + +* Redistributions in binary form must reproduce the above + copyright notice, this list of conditions and the + following disclaimer in the documentation and/or other + materials provided with the distribution. + +* Neither the name of the assimp team, nor the names of its + contributors may be used to endorse or promote products + derived from this software without specific prior + written permission of the assimp team. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +---------------------------------------------------------------------- +*/ + +/** + * @file + * @brief Default file I/O using fXXX()-family of functions + */ +#pragma once +#ifndef AI_DEFAULTIOSTREAM_H_INC +#define AI_DEFAULTIOSTREAM_H_INC + +#ifdef __GNUC__ +# pragma GCC system_header +#endif + +#include +#include +#include + +namespace Assimp { + +// ---------------------------------------------------------------------------------- +//! @class DefaultIOStream +//! @brief Default IO implementation, use standard IO operations +//! @note An instance of this class can exist without a valid file handle +//! attached to it. All calls fail, but the instance can nevertheless be +//! used with no restrictions. +class ASSIMP_API DefaultIOStream : public IOStream { + friend class DefaultIOSystem; +#if __ANDROID__ +# if __ANDROID_API__ > 9 +# if defined(AI_CONFIG_ANDROID_JNI_ASSIMP_MANAGER_SUPPORT) + friend class AndroidJNIIOSystem; +# endif // defined(AI_CONFIG_ANDROID_JNI_ASSIMP_MANAGER_SUPPORT) +# endif // __ANDROID_API__ > 9 +#endif // __ANDROID__ + +protected: + /// @brief + DefaultIOStream() AI_NO_EXCEPT; + + /// @brief The class constructor with the file name and the stream. + /// @param pFile The file-streaam + /// @param strFilename The file name + DefaultIOStream(FILE* pFile, const std::string &strFilename); + +public: + /** Destructor public to allow simple deletion to close the file. */ + ~DefaultIOStream (); + + // ------------------------------------------------------------------- + /// Read from stream + size_t Read(void* pvBuffer, size_t pSize, size_t pCount) override; + + // ------------------------------------------------------------------- + /// Write to stream + size_t Write(const void* pvBuffer, size_t pSize, size_t pCount) override; + + // ------------------------------------------------------------------- + /// Seek specific position + aiReturn Seek(size_t pOffset, aiOrigin pOrigin) override; + + // ------------------------------------------------------------------- + /// Get current seek position + size_t Tell() const override; + + // ------------------------------------------------------------------- + /// Get size of file + size_t FileSize() const override; + + // ------------------------------------------------------------------- + /// Flush file contents + void Flush() override; + +private: + FILE* mFile; + std::string mFilename; + mutable size_t mCachedSize; +}; + +// ---------------------------------------------------------------------------------- +AI_FORCE_INLINE DefaultIOStream::DefaultIOStream() AI_NO_EXCEPT : + mFile(nullptr), + mFilename(), + mCachedSize(SIZE_MAX) { + // empty +} + +// ---------------------------------------------------------------------------------- +AI_FORCE_INLINE DefaultIOStream::DefaultIOStream (FILE* pFile, const std::string &strFilename) : + mFile(pFile), + mFilename(strFilename), + mCachedSize(SIZE_MAX) { + // empty +} + +// ---------------------------------------------------------------------------------- + +} // ns assimp + +#endif //!!AI_DEFAULTIOSTREAM_H_INC diff --git a/dependencies/includes/assimp/DefaultIOSystem.h b/dependencies/includes/assimp/DefaultIOSystem.h new file mode 100644 index 0000000..8545e75 --- /dev/null +++ b/dependencies/includes/assimp/DefaultIOSystem.h @@ -0,0 +1,99 @@ +/* +Open Asset Import Library (assimp) +---------------------------------------------------------------------- + +Copyright (c) 2006-2022, assimp team + +All rights reserved. + +Redistribution and use of this software in source and binary forms, +with or without modification, are permitted provided that the +following conditions are met: + +* Redistributions of source code must retain the above + copyright notice, this list of conditions and the + following disclaimer. + +* Redistributions in binary form must reproduce the above + copyright notice, this list of conditions and the + following disclaimer in the documentation and/or other + materials provided with the distribution. + +* Neither the name of the assimp team, nor the names of its + contributors may be used to endorse or promote products + derived from this software without specific prior + written permission of the assimp team. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +---------------------------------------------------------------------- +*/ + +/** + * @file Default implementation of IOSystem using the standard C file functions + */ +#pragma once +#ifndef AI_DEFAULTIOSYSTEM_H_INC +#define AI_DEFAULTIOSYSTEM_H_INC + +#ifdef __GNUC__ +# pragma GCC system_header +#endif + +#include + +namespace Assimp { + +// --------------------------------------------------------------------------- +/** Default implementation of IOSystem using the standard C file functions */ +class ASSIMP_API DefaultIOSystem : public IOSystem { +public: + // ------------------------------------------------------------------- + /** Tests for the existence of a file at the given path. */ + bool Exists( const char* pFile) const override; + + // ------------------------------------------------------------------- + /** Returns the directory separator. */ + char getOsSeparator() const override; + + // ------------------------------------------------------------------- + /** Open a new file with a given path. */ + IOStream* Open( const char* pFile, const char* pMode = "rb") override; + + // ------------------------------------------------------------------- + /** Closes the given file and releases all resources associated with it. */ + void Close( IOStream* pFile) override; + + // ------------------------------------------------------------------- + /** Compare two paths */ + bool ComparePaths (const char* one, const char* second) const override; + + /** @brief get the file name of a full filepath + * example: /tmp/archive.tar.gz -> archive.tar.gz + */ + static std::string fileName( const std::string &path ); + + /** @brief get the complete base name of a full filepath + * example: /tmp/archive.tar.gz -> archive.tar + */ + static std::string completeBaseName( const std::string &path); + + /** @brief get the path of a full filepath + * example: /tmp/archive.tar.gz -> /tmp/ + */ + static std::string absolutePath( const std::string &path); +}; + +} //!ns Assimp + +#endif //AI_DEFAULTIOSYSTEM_H_INC diff --git a/dependencies/includes/assimp/DefaultLogger.hpp b/dependencies/includes/assimp/DefaultLogger.hpp new file mode 100644 index 0000000..723097f --- /dev/null +++ b/dependencies/includes/assimp/DefaultLogger.hpp @@ -0,0 +1,193 @@ +/* +Open Asset Import Library (assimp) +---------------------------------------------------------------------- + +Copyright (c) 2006-2022, assimp team + +All rights reserved. + +Redistribution and use of this software in source and binary forms, +with or without modification, are permitted provided that the +following conditions are met: + +* Redistributions of source code must retain the above + copyright notice, this list of conditions and the + following disclaimer. + +* Redistributions in binary form must reproduce the above + copyright notice, this list of conditions and the + following disclaimer in the documentation and/or other + materials provided with the distribution. + +* Neither the name of the assimp team, nor the names of its + contributors may be used to endorse or promote products + derived from this software without specific prior + written permission of the assimp team. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +---------------------------------------------------------------------- +*/ + +/** + * @file DefaultLogger.hpp + */ + +#pragma once +#ifndef INCLUDED_AI_DEFAULTLOGGER +#define INCLUDED_AI_DEFAULTLOGGER + +#ifdef __GNUC__ +# pragma GCC system_header +#endif + +#include "LogStream.hpp" +#include "Logger.hpp" +#include "NullLogger.hpp" +#include + +namespace Assimp { +// ------------------------------------------------------------------------------------ +class IOStream; +struct LogStreamInfo; + +/** default name of log-file */ +#define ASSIMP_DEFAULT_LOG_NAME "AssimpLog.txt" + +// ------------------------------------------------------------------------------------ +/** @brief CPP-API: Primary logging facility of Assimp. + * + * The library stores its primary #Logger as a static member of this class. + * #get() returns this primary logger. By default the underlying implementation is + * just a #NullLogger which rejects all log messages. By calling #create(), logging + * is turned on. To capture the log output multiple log streams (#LogStream) can be + * attach to the logger. Some default streams for common streaming locations (such as + * a file, std::cout, OutputDebugString()) are also provided. + * + * If you wish to customize the logging at an even deeper level supply your own + * implementation of #Logger to #set(). + * @note The whole logging stuff causes a small extra overhead for all imports. */ +class ASSIMP_API DefaultLogger : public Logger { +public: + // ---------------------------------------------------------------------- + /** @brief Creates a logging instance. + * @param name Name for log file. Only valid in combination + * with the aiDefaultLogStream_FILE flag. + * @param severity Log severity, DEBUG turns on debug messages and VERBOSE turns on all messages. + * @param defStreams Default log streams to be attached. Any bitwise + * combination of the aiDefaultLogStream enumerated values. + * If #aiDefaultLogStream_FILE is specified but an empty string is + * passed for 'name', no log file is created at all. + * @param io IOSystem to be used to open external files (such as the + * log file). Pass nullptr to rely on the default implementation. + * This replaces the default #NullLogger with a #DefaultLogger instance. */ + static Logger *create(const char *name = ASSIMP_DEFAULT_LOG_NAME, + LogSeverity severity = NORMAL, + unsigned int defStreams = aiDefaultLogStream_DEBUGGER | aiDefaultLogStream_FILE, + IOSystem *io = nullptr); + + // ---------------------------------------------------------------------- + /** @brief Setup a custom #Logger implementation. + * + * Use this if the provided #DefaultLogger class doesn't fit into + * your needs. If the provided message formatting is OK for you, + * it's much easier to use #create() and to attach your own custom + * output streams to it. + * @param logger Pass NULL to setup a default NullLogger*/ + static void set(Logger *logger); + + // ---------------------------------------------------------------------- + /** @brief Getter for singleton instance + * @return Only instance. This is never null, but it could be a + * NullLogger. Use isNullLogger to check this.*/ + static Logger *get(); + + // ---------------------------------------------------------------------- + /** @brief Return whether a #NullLogger is currently active + * @return true if the current logger is a #NullLogger. + * Use create() or set() to setup a logger that does actually do + * something else than just rejecting all log messages. */ + static bool isNullLogger(); + + // ---------------------------------------------------------------------- + /** @brief Kills the current singleton logger and replaces it with a + * #NullLogger instance. */ + static void kill(); + + // ---------------------------------------------------------------------- + /** @copydoc Logger::attachStream */ + bool attachStream(LogStream *pStream, unsigned int severity) override; + + // ---------------------------------------------------------------------- + /** @copydoc Logger::detachStream */ + bool detachStream(LogStream *pStream, unsigned int severity) override; + +private: + // ---------------------------------------------------------------------- + /** @briefPrivate construction for internal use by create(). + * @param severity Logging granularity */ + explicit DefaultLogger(LogSeverity severity); + + // ---------------------------------------------------------------------- + /** @briefDestructor */ + ~DefaultLogger() override; + + /** @brief Logs debug infos, only been written when severity level DEBUG or higher is set */ + void OnDebug(const char *message) override; + + /** @brief Logs debug infos, only been written when severity level VERBOSE is set */ + void OnVerboseDebug(const char *message) override; + + /** @brief Logs an info message */ + void OnInfo(const char *message) override; + + /** @brief Logs a warning message */ + void OnWarn(const char *message) override; + + /** @brief Logs an error message */ + void OnError(const char *message) override; + + // ---------------------------------------------------------------------- + /** @brief Writes a message to all streams */ + void WriteToStreams(const char *message, ErrorSeverity ErrorSev); + + // ---------------------------------------------------------------------- + /** @brief Returns the thread id. + * @note This is an OS specific feature, if not supported, a + * zero will be returned. + */ + unsigned int GetThreadID(); + +private: + // Aliases for stream container + using StreamArray = std::vector; + using StreamIt = std::vector::iterator; + using ConstStreamIt = std::vector::const_iterator; + + //! only logging instance + static Logger *m_pLogger; + static NullLogger s_pNullLogger; + + //! Attached streams + StreamArray m_StreamArray; + + bool noRepeatMsg; + char lastMsg[MAX_LOG_MESSAGE_LENGTH * 2]; + size_t lastLen; +}; + +// ------------------------------------------------------------------------------------ + +} // Namespace Assimp + +#endif // !! INCLUDED_AI_DEFAULTLOGGER diff --git a/dependencies/includes/assimp/Exceptional.h b/dependencies/includes/assimp/Exceptional.h new file mode 100644 index 0000000..ec3d38c --- /dev/null +++ b/dependencies/includes/assimp/Exceptional.h @@ -0,0 +1,182 @@ +/* +Open Asset Import Library (assimp) +---------------------------------------------------------------------- + +Copyright (c) 2006-2022, assimp team +All rights reserved. + +Redistribution and use of this software in source and binary forms, +with or without modification, are permitted provided that the +following conditions are met: + +* Redistributions of source code must retain the above + copyright notice, this list of conditions and the + following disclaimer. + +* Redistributions in binary form must reproduce the above + copyright notice, this list of conditions and the + following disclaimer in the documentation and/or other + materials provided with the distribution. + +* Neither the name of the assimp team, nor the names of its + contributors may be used to endorse or promote products + derived from this software without specific prior + written permission of the assimp team. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +---------------------------------------------------------------------- +*/ + +#pragma once +#ifndef AI_INCLUDED_EXCEPTIONAL_H +#define AI_INCLUDED_EXCEPTIONAL_H + +#ifdef __GNUC__ +#pragma GCC system_header +#endif + +#include +#include +#include + +using std::runtime_error; + +#ifdef _MSC_VER +#pragma warning(disable : 4275) +#endif + +// --------------------------------------------------------------------------- +/** + * The base-class for all other exceptions + */ +class ASSIMP_API DeadlyErrorBase : public runtime_error { +protected: + /// @brief The class constructor with the formatter. + /// @param f The formatter. + DeadlyErrorBase(Assimp::Formatter::format f); + + /// @brief The class constructor with the parameter ellipse. + /// @tparam ...T The type for the ellipse + /// @tparam U The other type + /// @param f The formatter + /// @param u One parameter + /// @param ...args The rest + template + DeadlyErrorBase(Assimp::Formatter::format f, U&& u, T&&... args) : + DeadlyErrorBase(std::move(f << std::forward(u)), std::forward(args)...) {} +}; + +// --------------------------------------------------------------------------- +/** FOR IMPORTER PLUGINS ONLY: Simple exception class to be thrown if an + * unrecoverable error occurs while importing. Loading APIs return + * nullptr instead of a valid aiScene then. */ +class ASSIMP_API DeadlyImportError : public DeadlyErrorBase { +public: + /// @brief The class constructor with the message. + /// @param message The message + DeadlyImportError(const char *message) : + DeadlyErrorBase(Assimp::Formatter::format(), std::forward(message)) { + // empty + } + + /// @brief The class constructor with the parameter ellipse. + /// @tparam ...T The type for the ellipse + /// @param ...args The args + template + explicit DeadlyImportError(T&&... args) : + DeadlyErrorBase(Assimp::Formatter::format(), std::forward(args)...) { + // empty + } +}; + +// --------------------------------------------------------------------------- +/** FOR EXPORTER PLUGINS ONLY: Simple exception class to be thrown if an + * unrecoverable error occurs while exporting. Exporting APIs return + * nullptr instead of a valid aiScene then. */ +class ASSIMP_API DeadlyExportError : public DeadlyErrorBase { +public: + /** Constructor with arguments */ + template + explicit DeadlyExportError(T&&... args) : + DeadlyErrorBase(Assimp::Formatter::format(), std::forward(args)...) {} +}; + +#ifdef _MSC_VER +#pragma warning(default : 4275) +#endif + +// --------------------------------------------------------------------------- +template +struct ExceptionSwallower { + T operator()() const { + return T(); + } +}; + +// --------------------------------------------------------------------------- +template +struct ExceptionSwallower { + T *operator()() const { + return nullptr; + } +}; + +// --------------------------------------------------------------------------- +template <> +struct ExceptionSwallower { + aiReturn operator()() const { + try { + throw; + } catch (std::bad_alloc &) { + return aiReturn_OUTOFMEMORY; + } catch (...) { + return aiReturn_FAILURE; + } + } +}; + +// --------------------------------------------------------------------------- +template <> +struct ExceptionSwallower { + void operator()() const { + return; + } +}; + +#define ASSIMP_BEGIN_EXCEPTION_REGION() \ + { \ + try { + +#define ASSIMP_END_EXCEPTION_REGION_WITH_ERROR_STRING(type, ASSIMP_END_EXCEPTION_REGION_errorString, ASSIMP_END_EXCEPTION_REGION_exception) \ + } \ + catch (const DeadlyImportError &e) { \ + ASSIMP_END_EXCEPTION_REGION_errorString = e.what(); \ + ASSIMP_END_EXCEPTION_REGION_exception = std::current_exception(); \ + return ExceptionSwallower()(); \ + } \ + catch (...) { \ + ASSIMP_END_EXCEPTION_REGION_errorString = "Unknown exception"; \ + ASSIMP_END_EXCEPTION_REGION_exception = std::current_exception(); \ + return ExceptionSwallower()(); \ + } \ +} + +#define ASSIMP_END_EXCEPTION_REGION(type) \ + } \ + catch (...) { \ + return ExceptionSwallower()(); \ + } \ + } + +#endif // AI_INCLUDED_EXCEPTIONAL_H diff --git a/dependencies/includes/assimp/Exporter.hpp b/dependencies/includes/assimp/Exporter.hpp new file mode 100644 index 0000000..09a4594 --- /dev/null +++ b/dependencies/includes/assimp/Exporter.hpp @@ -0,0 +1,509 @@ +/* +--------------------------------------------------------------------------- +Open Asset Import Library (assimp) +--------------------------------------------------------------------------- + +Copyright (c) 2006-2022, assimp team + +All rights reserved. + +Redistribution and use of this software in source and binary forms, +with or without modification, are permitted provided that the following +conditions are met: + +* Redistributions of source code must retain the above +copyright notice, this list of conditions and the +following disclaimer. + +* Redistributions in binary form must reproduce the above +copyright notice, this list of conditions and the +following disclaimer in the documentation and/or other +materials provided with the distribution. + +* Neither the name of the assimp team, nor the names of its +contributors may be used to endorse or promote products +derived from this software without specific prior +written permission of the assimp team. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +--------------------------------------------------------------------------- +*/ + +/** @file Exporter.hpp +* @brief Defines the CPP-API for the Assimp export interface +*/ +#pragma once +#ifndef AI_EXPORT_HPP_INC +#define AI_EXPORT_HPP_INC + +#ifdef __GNUC__ +#pragma GCC system_header +#endif + +#ifndef ASSIMP_BUILD_NO_EXPORT + +#include "cexport.h" +#include +#include + +namespace Assimp { + +class ExporterPimpl; +class IOSystem; +class ProgressHandler; + +// ---------------------------------------------------------------------------------- +/** CPP-API: The Exporter class forms an C++ interface to the export functionality + * of the Open Asset Import Library. Note that the export interface is available + * only if Assimp has been built with ASSIMP_BUILD_NO_EXPORT not defined. + * + * The interface is modeled after the importer interface and mostly + * symmetric. The same rules for threading etc. apply. + * + * In a nutshell, there are two export interfaces: #Export, which writes the + * output file(s) either to the regular file system or to a user-supplied + * #IOSystem, and #ExportToBlob which returns a linked list of memory + * buffers (blob), each referring to one output file (in most cases + * there will be only one output file of course, but this extra complexity is + * needed since Assimp aims at supporting a wide range of file formats). + * + * #ExportToBlob is especially useful if you intend to work + * with the data in-memory. +*/ +class ASSIMP_API ExportProperties; + +class ASSIMP_API Exporter { +public: + /** Function pointer type of a Export worker function */ + typedef void (*fpExportFunc)(const char *, IOSystem *, const aiScene *, const ExportProperties *); + + /** Internal description of an Assimp export format option */ + struct ExportFormatEntry { + /// Public description structure to be returned by aiGetExportFormatDescription() + aiExportFormatDesc mDescription; + + // Worker function to do the actual exporting + fpExportFunc mExportFunction; + + // Post-processing steps to be executed PRIOR to invoking mExportFunction + unsigned int mEnforcePP; + + // Constructor to fill all entries + ExportFormatEntry(const char *pId, const char *pDesc, const char *pExtension, fpExportFunc pFunction, unsigned int pEnforcePP = 0u) { + mDescription.id = pId; + mDescription.description = pDesc; + mDescription.fileExtension = pExtension; + mExportFunction = pFunction; + mEnforcePP = pEnforcePP; + } + + ExportFormatEntry() : + mExportFunction(), + mEnforcePP() { + mDescription.id = nullptr; + mDescription.description = nullptr; + mDescription.fileExtension = nullptr; + } + }; + + /** + * @brief The class constructor. + */ + Exporter(); + + /** + * @brief The class destructor. + */ + ~Exporter(); + + // ------------------------------------------------------------------- + /** Supplies a custom IO handler to the exporter to use to open and + * access files. + * + * If you need #Export to use custom IO logic to access the files, + * you need to supply a custom implementation of IOSystem and + * IOFile to the exporter. + * + * #Exporter takes ownership of the object and will destroy it + * afterwards. The previously assigned handler will be deleted. + * Pass NULL to take again ownership of your IOSystem and reset Assimp + * to use its default implementation, which uses plain file IO. + * + * @param pIOHandler The IO handler to be used in all file accesses + * of the Importer. */ + void SetIOHandler(IOSystem *pIOHandler); + + // ------------------------------------------------------------------- + /** Retrieves the IO handler that is currently set. + * You can use #IsDefaultIOHandler() to check whether the returned + * interface is the default IO handler provided by ASSIMP. The default + * handler is active as long the application doesn't supply its own + * custom IO handler via #SetIOHandler(). + * @return A valid IOSystem interface, never NULL. */ + IOSystem *GetIOHandler() const; + + // ------------------------------------------------------------------- + /** Checks whether a default IO handler is active + * A default handler is active as long the application doesn't + * supply its own custom IO handler via #SetIOHandler(). + * @return true by default */ + bool IsDefaultIOHandler() const; + + // ------------------------------------------------------------------- + /** Supplies a custom progress handler to the exporter. This + * interface exposes an #Update() callback, which is called + * more or less periodically (please don't sue us if it + * isn't as periodically as you'd like it to have ...). + * This can be used to implement progress bars and loading + * timeouts. + * @param pHandler Progress callback interface. Pass nullptr to + * disable progress reporting. + * @note Progress handlers can be used to abort the loading + * at almost any time.*/ + void SetProgressHandler(ProgressHandler *pHandler); + + // ------------------------------------------------------------------- + /** Exports the given scene to a chosen file format. Returns the exported + * data as a binary blob which you can write into a file or something. + * When you're done with the data, simply let the #Exporter instance go + * out of scope to have it released automatically. + * @param pScene The scene to export. Stays in possession of the caller, + * is not changed by the function. + * @param pFormatId ID string to specify to which format you want to + * export to. Use + * #GetExportFormatCount / #GetExportFormatDescription to learn which + * export formats are available. + * @param pPreprocessing See the documentation for #Export + * @return the exported data or nullptr in case of error. + * @note If the Exporter instance did already hold a blob from + * a previous call to #ExportToBlob, it will be disposed. + * Any IO handlers set via #SetIOHandler are ignored here. + * @note Use aiCopyScene() to get a modifiable copy of a previously + * imported scene. */ + const aiExportDataBlob *ExportToBlob(const aiScene *pScene, const char *pFormatId, + unsigned int pPreprocessing = 0u, const ExportProperties *pProperties = nullptr); + const aiExportDataBlob *ExportToBlob(const aiScene *pScene, const std::string &pFormatId, + unsigned int pPreprocessing = 0u, const ExportProperties *pProperties = nullptr); + + // ------------------------------------------------------------------- + /** Convenience function to export directly to a file. Use + * #SetIOSystem to supply a custom IOSystem to gain fine-grained control + * about the output data flow of the export process. + * @param pBlob A data blob obtained from a previous call to #aiExportScene. Must not be nullptr. + * @param pPath Full target file name. Target must be accessible. + * @param pPreprocessing Accepts any choice of the #aiPostProcessSteps enumerated + * flags, but in reality only a subset of them makes sense here. Specifying + * 'preprocessing' flags is useful if the input scene does not conform to + * Assimp's default conventions as specified in the @link data Data Structures Page @endlink. + * In short, this means the geometry data should use a right-handed coordinate systems, face + * winding should be counter-clockwise and the UV coordinate origin is assumed to be in + * the upper left. The #aiProcess_MakeLeftHanded, #aiProcess_FlipUVs and + * #aiProcess_FlipWindingOrder flags are used in the import side to allow users + * to have those defaults automatically adapted to their conventions. Specifying those flags + * for exporting has the opposite effect, respectively. Some other of the + * #aiPostProcessSteps enumerated values may be useful as well, but you'll need + * to try out what their effect on the exported file is. Many formats impose + * their own restrictions on the structure of the geometry stored therein, + * so some preprocessing may have little or no effect at all, or may be + * redundant as exporters would apply them anyhow. A good example + * is triangulation - whilst you can enforce it by specifying + * the #aiProcess_Triangulate flag, most export formats support only + * triangulate data so they would run the step even if it wasn't requested. + * + * If assimp detects that the input scene was directly taken from the importer side of + * the library (i.e. not copied using aiCopyScene and potentially modified afterwards), + * any post-processing steps already applied to the scene will not be applied again, unless + * they show non-idempotent behavior (#aiProcess_MakeLeftHanded, #aiProcess_FlipUVs and + * #aiProcess_FlipWindingOrder). + * @return AI_SUCCESS if everything was fine. + * @note Use aiCopyScene() to get a modifiable copy of a previously + * imported scene.*/ + aiReturn Export(const aiScene *pScene, const char *pFormatId, const char *pPath, + unsigned int pPreprocessing = 0u, const ExportProperties *pProperties = nullptr); + aiReturn Export(const aiScene *pScene, const std::string &pFormatId, const std::string &pPath, + unsigned int pPreprocessing = 0u, const ExportProperties *pProperties = nullptr); + + // ------------------------------------------------------------------- + /** Returns an error description of an error that occurred in #Export + * or #ExportToBlob + * + * Returns an empty string if no error occurred. + * @return A description of the last error, an empty string if no + * error occurred. The string is never nullptr. + * + * @note The returned function remains valid until one of the + * following methods is called: #Export, #ExportToBlob, #FreeBlob */ + const char *GetErrorString() const; + + // ------------------------------------------------------------------- + /** Return the blob obtained from the last call to #ExportToBlob */ + const aiExportDataBlob *GetBlob() const; + + // ------------------------------------------------------------------- + /** Orphan the blob from the last call to #ExportToBlob. This means + * the caller takes ownership and is thus responsible for calling + * the C API function #aiReleaseExportBlob to release it. */ + const aiExportDataBlob *GetOrphanedBlob() const; + + // ------------------------------------------------------------------- + /** Frees the current blob. + * + * The function does nothing if no blob has previously been + * previously produced via #ExportToBlob. #FreeBlob is called + * automatically by the destructor. The only reason to call + * it manually would be to reclaim as much storage as possible + * without giving up the #Exporter instance yet. */ + void FreeBlob(); + + // ------------------------------------------------------------------- + /** Returns the number of export file formats available in the current + * Assimp build. Use #Exporter::GetExportFormatDescription to + * retrieve infos of a specific export format. + * + * This includes built-in exporters as well as exporters registered + * using #RegisterExporter. + **/ + size_t GetExportFormatCount() const; + + // ------------------------------------------------------------------- + /** Returns a description of the nth export file format. Use # + * #Exporter::GetExportFormatCount to learn how many export + * formats are supported. + * + * The returned pointer is of static storage duration if the + * pIndex pertains to a built-in exporter (i.e. one not registered + * via #RegistrerExporter). It is restricted to the life-time of the + * #Exporter instance otherwise. + * + * @param pIndex Index of the export format to retrieve information + * for. Valid range is 0 to #Exporter::GetExportFormatCount + * @return A description of that specific export format. + * NULL if pIndex is out of range. */ + const aiExportFormatDesc *GetExportFormatDescription(size_t pIndex) const; + + // ------------------------------------------------------------------- + /** Register a custom exporter. Custom export formats are limited to + * to the current #Exporter instance and do not affect the + * library globally. The indexes under which the format's + * export format description can be queried are assigned + * monotonously. + * @param desc Exporter description. + * @return aiReturn_SUCCESS if the export format was successfully + * registered. A common cause that would prevent an exporter + * from being registered is that its format id is already + * occupied by another format. */ + aiReturn RegisterExporter(const ExportFormatEntry &desc); + + // ------------------------------------------------------------------- + /** Remove an export format previously registered with #RegisterExporter + * from the #Exporter instance (this can also be used to drop + * built-in exporters because those are implicitly registered + * using #RegisterExporter). + * @param id Format id to be unregistered, this refers to the + * 'id' field of #aiExportFormatDesc. + * @note Calling this method on a format description not yet registered + * has no effect.*/ + void UnregisterExporter(const char *id); + +protected: + // Just because we don't want you to know how we're hacking around. + ExporterPimpl *pimpl; +}; + +class ASSIMP_API ExportProperties { +public: + // Data type to store the key hash + typedef unsigned int KeyType; + + // typedefs for our four configuration maps. + // We don't need more, so there is no need for a generic solution + typedef std::map IntPropertyMap; + typedef std::map FloatPropertyMap; + typedef std::map StringPropertyMap; + typedef std::map MatrixPropertyMap; + typedef std::map> CallbackPropertyMap; + +public: + /** Standard constructor + * @see ExportProperties() + */ + ExportProperties(); + + // ------------------------------------------------------------------- + /** Copy constructor. + * + * This copies the configuration properties of another ExportProperties. + * @see ExportProperties(const ExportProperties& other) + */ + ExportProperties(const ExportProperties &other); + + // ------------------------------------------------------------------- + /** Set an integer configuration property. + * @param szName Name of the property. All supported properties + * are defined in the aiConfig.g header (all constants share the + * prefix AI_CONFIG_XXX and are simple strings). + * @param iValue New value of the property + * @return true if the property was set before. The new value replaces + * the previous value in this case. + * @note Property of different types (float, int, string ..) are kept + * on different stacks, so calling SetPropertyInteger() for a + * floating-point property has no effect - the loader will call + * GetPropertyFloat() to read the property, but it won't be there. + */ + bool SetPropertyInteger(const char *szName, int iValue); + + // ------------------------------------------------------------------- + /** Set a boolean configuration property. Boolean properties + * are stored on the integer stack internally so it's possible + * to set them via #SetPropertyBool and query them with + * #GetPropertyBool and vice versa. + * @see SetPropertyInteger() + */ + bool SetPropertyBool(const char *szName, bool value) { + return SetPropertyInteger(szName, value); + } + + // ------------------------------------------------------------------- + /** Set a floating-point configuration property. + * @see SetPropertyInteger() + */ + bool SetPropertyFloat(const char *szName, ai_real fValue); + + // ------------------------------------------------------------------- + /** Set a string configuration property. + * @see SetPropertyInteger() + */ + bool SetPropertyString(const char *szName, const std::string &sValue); + + // ------------------------------------------------------------------- + /** Set a matrix configuration property. + * @see SetPropertyInteger() + */ + bool SetPropertyMatrix(const char *szName, const aiMatrix4x4 &sValue); + + bool SetPropertyCallback(const char *szName, const std::function &f); + + // ------------------------------------------------------------------- + /** Get a configuration property. + * @param szName Name of the property. All supported properties + * are defined in the aiConfig.g header (all constants share the + * prefix AI_CONFIG_XXX). + * @param iErrorReturn Value that is returned if the property + * is not found. + * @return Current value of the property + * @note Property of different types (float, int, string ..) are kept + * on different lists, so calling SetPropertyInteger() for a + * floating-point property has no effect - the loader will call + * GetPropertyFloat() to read the property, but it won't be there. + */ + int GetPropertyInteger(const char *szName, + int iErrorReturn = 0xffffffff) const; + + // ------------------------------------------------------------------- + /** Get a boolean configuration property. Boolean properties + * are stored on the integer stack internally so it's possible + * to set them via #SetPropertyBool and query them with + * #GetPropertyBool and vice versa. + * @see GetPropertyInteger() + */ + bool GetPropertyBool(const char *szName, bool bErrorReturn = false) const { + return GetPropertyInteger(szName, bErrorReturn) != 0; + } + + // ------------------------------------------------------------------- + /** Get a floating-point configuration property + * @see GetPropertyInteger() + */ + ai_real GetPropertyFloat(const char *szName, + ai_real fErrorReturn = 10e10f) const; + + // ------------------------------------------------------------------- + /** Get a string configuration property + * + * The return value remains valid until the property is modified. + * @see GetPropertyInteger() + */ + const std::string GetPropertyString(const char *szName, + const std::string &sErrorReturn = "") const; + + // ------------------------------------------------------------------- + /** Get a matrix configuration property + * + * The return value remains valid until the property is modified. + * @see GetPropertyInteger() + */ + const aiMatrix4x4 GetPropertyMatrix(const char *szName, + const aiMatrix4x4 &sErrorReturn = aiMatrix4x4()) const; + + std::function GetPropertyCallback(const char* szName) const; + + // ------------------------------------------------------------------- + /** Determine a integer configuration property has been set. + * @see HasPropertyInteger() + */ + bool HasPropertyInteger(const char *szName) const; + + /** Determine a boolean configuration property has been set. + * @see HasPropertyBool() + */ + bool HasPropertyBool(const char *szName) const; + + /** Determine a boolean configuration property has been set. + * @see HasPropertyFloat() + */ + bool HasPropertyFloat(const char *szName) const; + + /** Determine a String configuration property has been set. + * @see HasPropertyString() + */ + bool HasPropertyString(const char *szName) const; + + /** Determine a Matrix configuration property has been set. + * @see HasPropertyMatrix() + */ + bool HasPropertyMatrix(const char *szName) const; + + bool HasPropertyCallback(const char *szName) const; + + /** List of integer properties */ + IntPropertyMap mIntProperties; + + /** List of floating-point properties */ + FloatPropertyMap mFloatProperties; + + /** List of string properties */ + StringPropertyMap mStringProperties; + + /** List of Matrix properties */ + MatrixPropertyMap mMatrixProperties; + + CallbackPropertyMap mCallbackProperties; +}; + +// ---------------------------------------------------------------------------------- +inline const aiExportDataBlob *Exporter::ExportToBlob(const aiScene *pScene, const std::string &pFormatId, + unsigned int pPreprocessing, const ExportProperties *pProperties) { + return ExportToBlob(pScene, pFormatId.c_str(), pPreprocessing, pProperties); +} + +// ---------------------------------------------------------------------------------- +inline aiReturn Exporter ::Export(const aiScene *pScene, const std::string &pFormatId, + const std::string &pPath, unsigned int pPreprocessing, + const ExportProperties *pProperties) { + return Export(pScene, pFormatId.c_str(), pPath.c_str(), pPreprocessing, pProperties); +} + +} // namespace Assimp + +#endif // ASSIMP_BUILD_NO_EXPORT +#endif // AI_EXPORT_HPP_INC diff --git a/dependencies/includes/assimp/GenericProperty.h b/dependencies/includes/assimp/GenericProperty.h new file mode 100644 index 0000000..073d533 --- /dev/null +++ b/dependencies/includes/assimp/GenericProperty.h @@ -0,0 +1,133 @@ +/* +Open Asset Import Library (assimp) +---------------------------------------------------------------------- + +Copyright (c) 2006-2022, assimp team + +All rights reserved. + +Redistribution and use of this software in source and binary forms, +with or without modification, are permitted provided that the +following conditions are met: + +* Redistributions of source code must retain the above + copyright notice, this list of conditions and the + following disclaimer. + +* Redistributions in binary form must reproduce the above + copyright notice, this list of conditions and the + following disclaimer in the documentation and/or other + materials provided with the distribution. + +* Neither the name of the assimp team, nor the names of its + contributors may be used to endorse or promote products + derived from this software without specific prior + written permission of the assimp team. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +---------------------------------------------------------------------- +*/ + +#pragma once +#ifndef AI_GENERIC_PROPERTY_H_INCLUDED +#define AI_GENERIC_PROPERTY_H_INCLUDED + +#ifdef __GNUC__ +# pragma GCC system_header +#endif + +#include +#include +#include + +#include + +// ------------------------------------------------------------------------------------------------ +template +inline bool SetGenericProperty(std::map &list, + const char *szName, const T &value) { + ai_assert(nullptr != szName); + const uint32_t hash = SuperFastHash(szName); + + typename std::map::iterator it = list.find(hash); + if (it == list.end()) { + list.insert(std::pair(hash, value)); + return false; + } + (*it).second = value; + + return true; +} + +// ------------------------------------------------------------------------------------------------ +template +inline const T &GetGenericProperty(const std::map &list, + const char *szName, const T &errorReturn) { + ai_assert(nullptr != szName); + const uint32_t hash = SuperFastHash(szName); + + typename std::map::const_iterator it = list.find(hash); + if (it == list.end()) { + return errorReturn; + } + + return (*it).second; +} + +// ------------------------------------------------------------------------------------------------ +// Special version for pointer types - they will be deleted when replaced with another value +// passing nullptr removes the whole property +template +inline void SetGenericPropertyPtr(std::map &list, + const char *szName, T *value, bool *bWasExisting = nullptr) { + ai_assert(nullptr != szName); + const uint32_t hash = SuperFastHash(szName); + + typename std::map::iterator it = list.find(hash); + if (it == list.end()) { + if (bWasExisting) { + *bWasExisting = false; + } + + list.insert(std::pair(hash, value)); + return; + } + if ((*it).second != value) { + delete (*it).second; + (*it).second = value; + } + if (!value) { + list.erase(it); + } + if (bWasExisting) { + *bWasExisting = true; + } +} + +// ------------------------------------------------------------------------------------------------ +template +inline bool HasGenericProperty(const std::map &list, + const char *szName) { + ai_assert(nullptr != szName); + const uint32_t hash = SuperFastHash(szName); + + typename std::map::const_iterator it = list.find(hash); + if (it == list.end()) { + return false; + } + + return true; +} + +#endif // !! AI_GENERIC_PROPERTY_H_INCLUDED diff --git a/dependencies/includes/assimp/GltfMaterial.h b/dependencies/includes/assimp/GltfMaterial.h new file mode 100644 index 0000000..86ca889 --- /dev/null +++ b/dependencies/includes/assimp/GltfMaterial.h @@ -0,0 +1,74 @@ +/* +--------------------------------------------------------------------------- +Open Asset Import Library (assimp) +--------------------------------------------------------------------------- + +Copyright (c) 2006-2022, assimp team + +All rights reserved. + +Redistribution and use of this software in source and binary forms, +with or without modification, are permitted provided that the following +conditions are met: + +* Redistributions of source code must retain the above + copyright notice, this list of conditions and the + following disclaimer. + +* Redistributions in binary form must reproduce the above + copyright notice, this list of conditions and the + following disclaimer in the documentation and/or other + materials provided with the distribution. + +* Neither the name of the assimp team, nor the names of its + contributors may be used to endorse or promote products + derived from this software without specific prior + written permission of the assimp team. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +--------------------------------------------------------------------------- +*/ + +/** @file GltfMaterial.h + * @brief glTF-specific material macros + * These will be made generic at some future date + */ + +#ifndef AI_GLTFMATERIAL_H_INC +#define AI_GLTFMATERIAL_H_INC + +#ifdef __GNUC__ +# pragma GCC system_header +#endif + +#include + +#define AI_MATKEY_GLTF_PBRMETALLICROUGHNESS_METALLICROUGHNESS_TEXTURE aiTextureType_UNKNOWN, 0 +#define AI_MATKEY_GLTF_ALPHAMODE "$mat.gltf.alphaMode", 0, 0 +#define AI_MATKEY_GLTF_ALPHACUTOFF "$mat.gltf.alphaCutoff", 0, 0 + +#define _AI_MATKEY_GLTF_MAPPINGNAME_BASE "$tex.mappingname" +#define _AI_MATKEY_GLTF_MAPPINGID_BASE "$tex.mappingid" +#define _AI_MATKEY_GLTF_MAPPINGFILTER_MAG_BASE "$tex.mappingfiltermag" +#define _AI_MATKEY_GLTF_MAPPINGFILTER_MIN_BASE "$tex.mappingfiltermin" +#define _AI_MATKEY_GLTF_SCALE_BASE "$tex.scale" +#define _AI_MATKEY_GLTF_STRENGTH_BASE "$tex.strength" + +#define AI_MATKEY_GLTF_MAPPINGNAME(type, N) _AI_MATKEY_GLTF_MAPPINGNAME_BASE, type, N +#define AI_MATKEY_GLTF_MAPPINGID(type, N) _AI_MATKEY_GLTF_MAPPINGID_BASE, type, N +#define AI_MATKEY_GLTF_MAPPINGFILTER_MAG(type, N) _AI_MATKEY_GLTF_MAPPINGFILTER_MAG_BASE, type, N +#define AI_MATKEY_GLTF_MAPPINGFILTER_MIN(type, N) _AI_MATKEY_GLTF_MAPPINGFILTER_MIN_BASE, type, N +#define AI_MATKEY_GLTF_TEXTURE_SCALE(type, N) _AI_MATKEY_GLTF_SCALE_BASE, type, N +#define AI_MATKEY_GLTF_TEXTURE_STRENGTH(type, N) _AI_MATKEY_GLTF_STRENGTH_BASE, type, N + +#endif diff --git a/dependencies/includes/assimp/Hash.h b/dependencies/includes/assimp/Hash.h new file mode 100644 index 0000000..18bd270 --- /dev/null +++ b/dependencies/includes/assimp/Hash.h @@ -0,0 +1,122 @@ +/* +Open Asset Import Library (assimp) +---------------------------------------------------------------------- + +Copyright (c) 2006-2022, assimp team + +All rights reserved. + +Redistribution and use of this software in source and binary forms, +with or without modification, are permitted provided that the +following conditions are met: + +* Redistributions of source code must retain the above + copyright notice, this list of conditions and the + following disclaimer. + +* Redistributions in binary form must reproduce the above + copyright notice, this list of conditions and the + following disclaimer in the documentation and/or other + materials provided with the distribution. + +* Neither the name of the assimp team, nor the names of its + contributors may be used to endorse or promote products + derived from this software without specific prior + written permission of the assimp team. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +---------------------------------------------------------------------- +*/ +#pragma once +#ifndef AI_HASH_H_INCLUDED +#define AI_HASH_H_INCLUDED + +#ifdef __GNUC__ +# pragma GCC system_header +#endif + +#include +#include +#include + +// ------------------------------------------------------------------------------------------------ +// Hashing function taken from +// http://www.azillionmonkeys.com/qed/hash.html +// (incremental version) +// +// This code is Copyright 2004-2008 by Paul Hsieh. It is used here in the belief that +// Assimp's license is considered compatible with Pauls's derivative license as specified +// on his web page. +// +// (stdint.h should have been been included here) +// ------------------------------------------------------------------------------------------------ +#undef get16bits +#if (defined(__GNUC__) && defined(__i386__)) || defined(__WATCOMC__) \ + || defined(_MSC_VER) || defined (__BORLANDC__) || defined (__TURBOC__) +#define get16bits(d) (*((const uint16_t *) (d))) +#endif + +#if !defined (get16bits) +#define get16bits(d) ((((uint32_t)(((const uint8_t *)(d))[1])) << 8)\ + +(uint32_t)(((const uint8_t *)(d))[0]) ) +#endif + +// ------------------------------------------------------------------------------------------------ +inline uint32_t SuperFastHash (const char * data, uint32_t len = 0, uint32_t hash = 0) { + uint32_t tmp; + int rem; + + if (!data) return 0; + if (!len)len = (uint32_t)::strlen(data); + + rem = len & 3; + len >>= 2; + + /* Main loop */ + for (;len > 0; len--) { + hash += get16bits (data); + tmp = (get16bits (data+2) << 11) ^ hash; + hash = (hash << 16) ^ tmp; + data += 2*sizeof (uint16_t); + hash += hash >> 11; + } + + /* Handle end cases */ + switch (rem) { + case 3: hash += get16bits (data); + hash ^= hash << 16; + hash ^= abs(data[sizeof(uint16_t)]) << 18; + hash += hash >> 11; + break; + case 2: hash += get16bits (data); + hash ^= hash << 11; + hash += hash >> 17; + break; + case 1: hash += *data; + hash ^= hash << 10; + hash += hash >> 1; + } + + /* Force "avalanching" of final 127 bits */ + hash ^= hash << 3; + hash += hash >> 5; + hash ^= hash << 4; + hash += hash >> 17; + hash ^= hash << 25; + hash += hash >> 6; + + return hash; +} + +#endif // !! AI_HASH_H_INCLUDED diff --git a/dependencies/includes/assimp/IOStream.hpp b/dependencies/includes/assimp/IOStream.hpp new file mode 100644 index 0000000..3b9b3c3 --- /dev/null +++ b/dependencies/includes/assimp/IOStream.hpp @@ -0,0 +1,142 @@ +/* +--------------------------------------------------------------------------- +Open Asset Import Library (assimp) +--------------------------------------------------------------------------- + +Copyright (c) 2006-2022, assimp team + +All rights reserved. + +Redistribution and use of this software in source and binary forms, +with or without modification, are permitted provided that the following +conditions are met: + +* Redistributions of source code must retain the above + copyright notice, this list of conditions and the + following disclaimer. + +* Redistributions in binary form must reproduce the above + copyright notice, this list of conditions and the + following disclaimer in the documentation and/or other + materials provided with the distribution. + +* Neither the name of the assimp team, nor the names of its + contributors may be used to endorse or promote products + derived from this software without specific prior + written permission of the assimp team. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +--------------------------------------------------------------------------- +*/ +/** @file IOStream.hpp + * @brief File I/O wrappers for C++. + */ + +#pragma once +#ifndef AI_IOSTREAM_H_INC +#define AI_IOSTREAM_H_INC + +#ifdef __GNUC__ +# pragma GCC system_header +#endif + +#include + +#ifndef __cplusplus +# error This header requires C++ to be used. aiFileIO.h is the \ + corresponding C interface. +#endif + +namespace Assimp { + +// ---------------------------------------------------------------------------------- +/** @brief CPP-API: Class to handle file I/O for C++ + * + * Derive an own implementation from this interface to provide custom IO handling + * to the Importer. If you implement this interface, be sure to also provide an + * implementation for IOSystem that creates instances of your custom IO class. +*/ +class ASSIMP_API IOStream +#ifndef SWIG + : public Intern::AllocateFromAssimpHeap +#endif +{ +protected: + /** Constructor protected, use IOSystem::Open() to create an instance. */ + IOStream() AI_NO_EXCEPT; + +public: + // ------------------------------------------------------------------- + /** @brief Destructor. Deleting the object closes the underlying file, + * alternatively you may use IOSystem::Close() to release the file. + */ + virtual ~IOStream(); + + // ------------------------------------------------------------------- + /** @brief Read from the file + * + * See fread() for more details + * This fails for write-only files */ + virtual size_t Read(void* pvBuffer, + size_t pSize, + size_t pCount) = 0; + + // ------------------------------------------------------------------- + /** @brief Write to the file + * + * See fwrite() for more details + * This fails for read-only files */ + virtual size_t Write(const void* pvBuffer, + size_t pSize, + size_t pCount) = 0; + + // ------------------------------------------------------------------- + /** @brief Set the read/write cursor of the file + * + * Note that the offset is _negative_ for aiOrigin_END. + * See fseek() for more details */ + virtual aiReturn Seek(size_t pOffset, + aiOrigin pOrigin) = 0; + + // ------------------------------------------------------------------- + /** @brief Get the current position of the read/write cursor + * + * See ftell() for more details */ + virtual size_t Tell() const = 0; + + // ------------------------------------------------------------------- + /** @brief Returns filesize + * Returns the filesize. */ + virtual size_t FileSize() const = 0; + + // ------------------------------------------------------------------- + /** @brief Flush the contents of the file buffer (for writers) + * See fflush() for more details. + */ + virtual void Flush() = 0; +}; //! class IOStream + +// ---------------------------------------------------------------------------------- +AI_FORCE_INLINE +IOStream::IOStream() AI_NO_EXCEPT { + // empty +} + +// ---------------------------------------------------------------------------------- +AI_FORCE_INLINE +IOStream::~IOStream() = default; +// ---------------------------------------------------------------------------------- + +} //!namespace Assimp + +#endif //!!AI_IOSTREAM_H_INC diff --git a/dependencies/includes/assimp/IOStreamBuffer.h b/dependencies/includes/assimp/IOStreamBuffer.h new file mode 100644 index 0000000..09ca1c9 --- /dev/null +++ b/dependencies/includes/assimp/IOStreamBuffer.h @@ -0,0 +1,352 @@ +/* +Open Asset Import Library (assimp) +---------------------------------------------------------------------- + +Copyright (c) 2006-2022, assimp team + +All rights reserved. + +Redistribution and use of this software in source and binary forms, +with or without modification, are permitted provided that the +following conditions are met: + +* Redistributions of source code must retain the above +copyright notice, this list of conditions and the +following disclaimer. + +* Redistributions in binary form must reproduce the above +copyright notice, this list of conditions and the +following disclaimer in the documentation and/or other +materials provided with the distribution. + +* Neither the name of the assimp team, nor the names of its +contributors may be used to endorse or promote products +derived from this software without specific prior +written permission of the assimp team. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +---------------------------------------------------------------------- +*/ + +#pragma once +#ifndef AI_IOSTREAMBUFFER_H_INC +#define AI_IOSTREAMBUFFER_H_INC + +#ifdef __GNUC__ +#pragma GCC system_header +#endif + +#include +#include +#include + +#include + +namespace Assimp { + +// --------------------------------------------------------------------------- +/** + * Implementation of a cached stream buffer. + */ +template +class IOStreamBuffer { +public: + /// @brief The class constructor. + IOStreamBuffer(size_t cache = 4096 * 4096); + + /// @brief The class destructor. + ~IOStreamBuffer(); + + /// @brief Will open the cached access for a given stream. + /// @param stream The stream to cache. + /// @return true if successful. + bool open(IOStream *stream); + + /// @brief Will close the cached access. + /// @return true if successful. + bool close(); + + /// @brief Returns the file-size. + /// @return The file-size. + size_t size() const; + + /// @brief Returns the cache size. + /// @return The cache size. + size_t cacheSize() const; + + /// @brief Will read the next block. + /// @return true if successful. + bool readNextBlock(); + + /// @brief Returns the number of blocks to read. + /// @return The number of blocks. + size_t getNumBlocks() const; + + /// @brief Returns the current block index. + /// @return The current block index. + size_t getCurrentBlockIndex() const; + + /// @brief Returns the current file pos. + /// @return The current file pos. + size_t getFilePos() const; + + /// @brief Will read the next line. + /// @param buffer The buffer for the next line. + /// @return true if successful. + bool getNextDataLine(std::vector &buffer, T continuationToken); + + /// @brief Will read the next line ascii or binary end line char. + /// @param buffer The buffer for the next line. + /// @return true if successful. + bool getNextLine(std::vector &buffer); + + /// @brief Will read the next block. + /// @param buffer The buffer for the next block. + /// @return true if successful. + bool getNextBlock(std::vector &buffer); + +private: + IOStream *m_stream; + size_t m_filesize; + size_t m_cacheSize; + size_t m_numBlocks; + size_t m_blockIdx; + std::vector m_cache; + size_t m_cachePos; + size_t m_filePos; +}; + +template +AI_FORCE_INLINE IOStreamBuffer::IOStreamBuffer(size_t cache) : + m_stream(nullptr), + m_filesize(0), + m_cacheSize(cache), + m_numBlocks(0), + m_blockIdx(0), + m_cachePos(0), + m_filePos(0) { + m_cache.resize(cache); + std::fill(m_cache.begin(), m_cache.end(), '\n'); +} + +template +AI_FORCE_INLINE IOStreamBuffer::~IOStreamBuffer() { + // empty +} + +template +AI_FORCE_INLINE bool IOStreamBuffer::open(IOStream *stream) { + // file still opened! + if (nullptr != m_stream) { + return false; + } + + // Invalid stream pointer + if (nullptr == stream) { + return false; + } + + m_stream = stream; + m_filesize = m_stream->FileSize(); + if (m_filesize == 0) { + return false; + } + if (m_filesize < m_cacheSize) { + m_cacheSize = m_filesize; + } + + m_numBlocks = m_filesize / m_cacheSize; + if ((m_filesize % m_cacheSize) > 0) { + m_numBlocks++; + } + + return true; +} + +template +AI_FORCE_INLINE bool IOStreamBuffer::close() { + if (nullptr == m_stream) { + return false; + } + + // init counters and state vars + m_stream = nullptr; + m_filesize = 0; + m_numBlocks = 0; + m_blockIdx = 0; + m_cachePos = 0; + m_filePos = 0; + + return true; +} + +template +AI_FORCE_INLINE + size_t + IOStreamBuffer::size() const { + return m_filesize; +} + +template +AI_FORCE_INLINE + size_t + IOStreamBuffer::cacheSize() const { + return m_cacheSize; +} + +template +AI_FORCE_INLINE bool IOStreamBuffer::readNextBlock() { + m_stream->Seek(m_filePos, aiOrigin_SET); + size_t readLen = m_stream->Read(&m_cache[0], sizeof(T), m_cacheSize); + if (readLen == 0) { + return false; + } + if (readLen < m_cacheSize) { + m_cacheSize = readLen; + } + m_filePos += m_cacheSize; + m_cachePos = 0; + m_blockIdx++; + + return true; +} + +template +AI_FORCE_INLINE size_t IOStreamBuffer::getNumBlocks() const { + return m_numBlocks; +} + +template +AI_FORCE_INLINE size_t IOStreamBuffer::getCurrentBlockIndex() const { + return m_blockIdx; +} + +template +AI_FORCE_INLINE size_t IOStreamBuffer::getFilePos() const { + return m_filePos; +} + +template +AI_FORCE_INLINE bool IOStreamBuffer::getNextDataLine(std::vector &buffer, T continuationToken) { + buffer.resize(m_cacheSize); + if (m_cachePos >= m_cacheSize || 0 == m_filePos) { + if (!readNextBlock()) { + return false; + } + } + + size_t i = 0; + for (;;) { + if (continuationToken == m_cache[m_cachePos] && IsLineEnd(m_cache[m_cachePos + 1])) { + ++m_cachePos; + while (m_cache[m_cachePos] != '\n') { + ++m_cachePos; + } + ++m_cachePos; + } else if (IsLineEnd(m_cache[m_cachePos])) { + break; + } + + buffer[i] = m_cache[m_cachePos]; + ++m_cachePos; + ++i; + + if(i == buffer.size()) { + buffer.resize(buffer.size() * 2); + } + + if (m_cachePos >= size()) { + break; + } + if (m_cachePos >= m_cacheSize) { + if (!readNextBlock()) { + return false; + } + } + } + + buffer[i] = '\n'; + ++m_cachePos; + + return true; +} + +static AI_FORCE_INLINE bool isEndOfCache(size_t pos, size_t cacheSize) { + return (pos == cacheSize); +} + +template +AI_FORCE_INLINE bool IOStreamBuffer::getNextLine(std::vector &buffer) { + buffer.resize(m_cacheSize); + if (isEndOfCache(m_cachePos, m_cacheSize) || 0 == m_filePos) { + if (!readNextBlock()) { + return false; + } + } + + if (IsLineEnd(m_cache[m_cachePos])) { + // skip line end + while (m_cache[m_cachePos] != '\n') { + ++m_cachePos; + } + ++m_cachePos; + if (isEndOfCache(m_cachePos, m_cacheSize)) { + if (!readNextBlock()) { + return false; + } + } + } + + size_t i(0); + while (!IsLineEnd(m_cache[m_cachePos])) { + buffer[i] = m_cache[m_cachePos]; + ++m_cachePos; + ++i; + + if(i == buffer.size()) { + buffer.resize(buffer.size() * 2); + } + + if (m_cachePos >= m_cacheSize) { + if (!readNextBlock()) { + return false; + } + } + } + buffer[i] = '\n'; + ++m_cachePos; + + return true; +} + +template +AI_FORCE_INLINE bool IOStreamBuffer::getNextBlock(std::vector &buffer) { + // Return the last block-value if getNextLine was used before + if (0 != m_cachePos) { + buffer = std::vector(m_cache.begin() + m_cachePos, m_cache.end()); + m_cachePos = 0; + } else { + if (!readNextBlock()) { + return false; + } + + buffer = std::vector(m_cache.begin(), m_cache.end()); + } + + return true; +} + +} // namespace Assimp + +#endif // AI_IOSTREAMBUFFER_H_INC diff --git a/dependencies/includes/assimp/IOSystem.hpp b/dependencies/includes/assimp/IOSystem.hpp new file mode 100644 index 0000000..b4531f9 --- /dev/null +++ b/dependencies/includes/assimp/IOSystem.hpp @@ -0,0 +1,342 @@ +/* +--------------------------------------------------------------------------- +Open Asset Import Library (assimp) +--------------------------------------------------------------------------- + +Copyright (c) 2006-2022, assimp team + +All rights reserved. + +Redistribution and use of this software in source and binary forms, +with or without modification, are permitted provided that the following +conditions are met: + +* Redistributions of source code must retain the above + copyright notice, this list of conditions and the + following disclaimer. + +* Redistributions in binary form must reproduce the above + copyright notice, this list of conditions and the + following disclaimer in the documentation and/or other + materials provided with the distribution. + +* Neither the name of the assimp team, nor the names of its + contributors may be used to endorse or promote products + derived from this software without specific prior + written permission of the assimp team. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +--------------------------------------------------------------------------- +*/ + +/** @file IOSystem.hpp + * @brief File system wrapper for C++. Inherit this class to supply + * custom file handling logic to the Import library. +*/ + +#pragma once +#ifndef AI_IOSYSTEM_H_INC +#define AI_IOSYSTEM_H_INC + +#ifdef __GNUC__ +# pragma GCC system_header +#endif + +#ifndef __cplusplus +# error This header requires C++ to be used. aiFileIO.h is the \ + corresponding C interface. +#endif + +#include "types.h" + +#ifdef _WIN32 +# include +# include +# include +#else +# include +# include +# include +#endif // _WIN32 + +#include + +namespace Assimp { + +class IOStream; + +// --------------------------------------------------------------------------- +/** @brief CPP-API: Interface to the file system. + * + * Derive an own implementation from this interface to supply custom file handling + * to the importer library. If you implement this interface, you also want to + * supply a custom implementation for IOStream. + * + * @see Importer::SetIOHandler() + */ +class ASSIMP_API IOSystem +#ifndef SWIG + : public Intern::AllocateFromAssimpHeap +#endif +{ +public: + + // ------------------------------------------------------------------- + /** @brief Default constructor. + * + * Create an instance of your derived class and assign it to an + * #Assimp::Importer instance by calling Importer::SetIOHandler(). + */ + IOSystem() AI_NO_EXCEPT; + + // ------------------------------------------------------------------- + /** @brief Virtual destructor. + * + * It is safe to be called from within DLL Assimp, we're constructed + * on Assimp's heap. + */ + virtual ~IOSystem(); + + // ------------------------------------------------------------------- + /** @brief For backward compatibility + * @see Exists(const char*) + */ + AI_FORCE_INLINE bool Exists( const std::string& pFile) const; + + // ------------------------------------------------------------------- + /** @brief Tests for the existence of a file at the given path. + * + * @param pFile Path to the file + * @return true if there is a file with this path, else false. + */ + virtual bool Exists( const char* pFile) const = 0; + + // ------------------------------------------------------------------- + /** @brief Returns the system specific directory separator + * @return System specific directory separator + */ + virtual char getOsSeparator() const = 0; + + // ------------------------------------------------------------------- + /** @brief Open a new file with a given path. + * + * When the access to the file is finished, call Close() to release + * all associated resources (or the virtual dtor of the IOStream). + * + * @param pFile Path to the file + * @param pMode Desired file I/O mode. Required are: "wb", "w", "wt", + * "rb", "r", "rt". + * + * @return New IOStream interface allowing the lib to access + * the underlying file. + * @note When implementing this class to provide custom IO handling, + * you probably have to supply an own implementation of IOStream as well. + */ + virtual IOStream* Open(const char* pFile, + const char* pMode = "rb") = 0; + + // ------------------------------------------------------------------- + /** @brief For backward compatibility + * @see Open(const char*, const char*) + */ + inline IOStream* Open(const std::string& pFile, + const std::string& pMode = std::string("rb")); + + // ------------------------------------------------------------------- + /** @brief Closes the given file and releases all resources + * associated with it. + * @param pFile The file instance previously created by Open(). + */ + virtual void Close( IOStream* pFile) = 0; + + // ------------------------------------------------------------------- + /** @brief Compares two paths and check whether the point to + * identical files. + * + * The dummy implementation of this virtual member performs a + * case-insensitive comparison of the given strings. The default IO + * system implementation uses OS mechanisms to convert relative into + * absolute paths, so the result can be trusted. + * @param one First file + * @param second Second file + * @return true if the paths point to the same file. The file needn't + * be existing, however. + */ + virtual bool ComparePaths (const char* one, + const char* second) const; + + // ------------------------------------------------------------------- + /** @brief For backward compatibility + * @see ComparePaths(const char*, const char*) + */ + inline bool ComparePaths (const std::string& one, + const std::string& second) const; + + // ------------------------------------------------------------------- + /** @brief Pushes a new directory onto the directory stack. + * @param path Path to push onto the stack. + * @return True, when push was successful, false if path is empty. + */ + virtual bool PushDirectory( const std::string &path ); + + // ------------------------------------------------------------------- + /** @brief Returns the top directory from the stack. + * @return The directory on the top of the stack. + * Returns empty when no directory was pushed to the stack. + */ + virtual const std::string &CurrentDirectory() const; + + // ------------------------------------------------------------------- + /** @brief Returns the number of directories stored on the stack. + * @return The number of directories of the stack. + */ + virtual size_t StackSize() const; + + // ------------------------------------------------------------------- + /** @brief Pops the top directory from the stack. + * @return True, when a directory was on the stack. False if no + * directory was on the stack. + */ + virtual bool PopDirectory(); + + // ------------------------------------------------------------------- + /** @brief CReates an new directory at the given path. + * @param path [in] The path to create. + * @return True, when a directory was created. False if the directory + * cannot be created. + */ + virtual bool CreateDirectory( const std::string &path ); + + // ------------------------------------------------------------------- + /** @brief Will change the current directory to the given path. + * @param path [in] The path to change to. + * @return True, when the directory has changed successfully. + */ + virtual bool ChangeDirectory( const std::string &path ); + + // ------------------------------------------------------------------- + /** + * @brief Will delete the given file. + * @param file [in] The filename + * @return true, if the file wase deleted, false if not. + */ + virtual bool DeleteFile(const std::string &file); + +private: + std::vector m_pathStack; +}; + +// ---------------------------------------------------------------------------- +AI_FORCE_INLINE IOSystem::IOSystem() AI_NO_EXCEPT : + m_pathStack() { + // empty +} + +// ---------------------------------------------------------------------------- +AI_FORCE_INLINE IOSystem::~IOSystem() = default; + +// ---------------------------------------------------------------------------- +// For compatibility, the interface of some functions taking a std::string was +// changed to const char* to avoid crashes between binary incompatible STL +// versions. This code her is inlined, so it shouldn't cause any problems. +// ---------------------------------------------------------------------------- + +// ---------------------------------------------------------------------------- +AI_FORCE_INLINE IOStream* IOSystem::Open(const std::string& pFile, const std::string& pMode) { + // NOTE: + // For compatibility, interface was changed to const char* to + // avoid crashes between binary incompatible STL versions + return Open(pFile.c_str(),pMode.c_str()); +} + +// ---------------------------------------------------------------------------- +AI_FORCE_INLINE bool IOSystem::Exists( const std::string& pFile) const { + // NOTE: + // For compatibility, interface was changed to const char* to + // avoid crashes between binary incompatible STL versions + return Exists(pFile.c_str()); +} + +// ---------------------------------------------------------------------------- +AI_FORCE_INLINE bool IOSystem::ComparePaths(const std::string& one, const std::string& second) const { + // NOTE: + // For compatibility, interface was changed to const char* to + // avoid crashes between binary incompatible STL versions + return ComparePaths(one.c_str(),second.c_str()); +} + +// ---------------------------------------------------------------------------- +AI_FORCE_INLINE bool IOSystem::PushDirectory( const std::string &path ) { + if ( path.empty() ) { + return false; + } + + m_pathStack.push_back( path ); + + return true; +} + +// ---------------------------------------------------------------------------- +AI_FORCE_INLINE size_t IOSystem::StackSize() const { + return m_pathStack.size(); +} + +// ---------------------------------------------------------------------------- +AI_FORCE_INLINE bool IOSystem::PopDirectory() { + if ( m_pathStack.empty() ) { + return false; + } + + m_pathStack.pop_back(); + + return true; +} + +// ---------------------------------------------------------------------------- +AI_FORCE_INLINE bool IOSystem::CreateDirectory( const std::string &path ) { + if ( path.empty() ) { + return false; + } + +#ifdef _WIN32 + return 0 != ::_mkdir( path.c_str() ); +#else + return 0 != ::mkdir( path.c_str(), 0777 ); +#endif // _WIN32 +} + +// ---------------------------------------------------------------------------- +AI_FORCE_INLINE bool IOSystem::ChangeDirectory( const std::string &path ) { + if ( path.empty() ) { + return false; + } + +#ifdef _WIN32 + return 0 != ::_chdir( path.c_str() ); +#else + return 0 != ::chdir( path.c_str() ); +#endif // _WIN32 +} + + +// ---------------------------------------------------------------------------- +AI_FORCE_INLINE bool IOSystem::DeleteFile( const std::string &file ) { + if ( file.empty() ) { + return false; + } + const int retCode( ::remove( file.c_str() ) ); + return ( 0 == retCode ); +} +} //!ns Assimp + +#endif //AI_IOSYSTEM_H_INC diff --git a/dependencies/includes/assimp/Importer.hpp b/dependencies/includes/assimp/Importer.hpp new file mode 100644 index 0000000..05a1513 --- /dev/null +++ b/dependencies/includes/assimp/Importer.hpp @@ -0,0 +1,685 @@ +/* +--------------------------------------------------------------------------- +Open Asset Import Library (assimp) +--------------------------------------------------------------------------- + +Copyright (c) 2006-2022, assimp team + + + +All rights reserved. + +Redistribution and use of this software in source and binary forms, +with or without modification, are permitted provided that the following +conditions are met: + +* Redistributions of source code must retain the above + copyright notice, this list of conditions and the + following disclaimer. + +* Redistributions in binary form must reproduce the above + copyright notice, this list of conditions and the + following disclaimer in the documentation and/or other + materials provided with the distribution. + +* Neither the name of the assimp team, nor the names of its + contributors may be used to endorse or promote products + derived from this software without specific prior + written permission of the assimp team. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +--------------------------------------------------------------------------- +*/ + +/** @file Importer.hpp + * @brief Defines the C++-API to the Open Asset Import Library. + */ +#pragma once +#ifndef AI_ASSIMP_HPP_INC +#define AI_ASSIMP_HPP_INC + +#ifdef __GNUC__ +#pragma GCC system_header +#endif + +#ifndef __cplusplus +#error This header requires C++ to be used. Use assimp.h for plain C. +#endif // __cplusplus + +// Public ASSIMP data structures +#include + +#include + +namespace Assimp { +// ======================================================================= +// Public interface to Assimp +class Importer; +class IOStream; +class IOSystem; +class ProgressHandler; + +// ======================================================================= +// Plugin development +// +// Include the following headers for the declarations: +// BaseImporter.h +// BaseProcess.h +class BaseImporter; +class BaseProcess; +class SharedPostProcessInfo; +class BatchLoader; + +// ======================================================================= +// Holy stuff, only for members of the high council of the Jedi. +class ImporterPimpl; +} // namespace Assimp + +#define AI_PROPERTY_WAS_NOT_EXISTING 0xffffffff + +struct aiScene; + +// importerdesc.h +struct aiImporterDesc; + +/** @namespace Assimp Assimp's CPP-API and all internal APIs */ +namespace Assimp { + +// ---------------------------------------------------------------------------------- +/** CPP-API: The Importer class forms an C++ interface to the functionality of the +* Open Asset Import Library. +* +* Create an object of this class and call ReadFile() to import a file. +* If the import succeeds, the function returns a pointer to the imported data. +* The data remains property of the object, it is intended to be accessed +* read-only. The imported data will be destroyed along with the Importer +* object. If the import fails, ReadFile() returns a nullptr pointer. In this +* case you can retrieve a human-readable error description be calling +* GetErrorString(). You can call ReadFile() multiple times with a single Importer +* instance. Actually, constructing Importer objects involves quite many +* allocations and may take some time, so it's better to reuse them as often as +* possible. +* +* If you need the Importer to do custom file handling to access the files, +* implement IOSystem and IOStream and supply an instance of your custom +* IOSystem implementation by calling SetIOHandler() before calling ReadFile(). +* If you do not assign a custion IO handler, a default handler using the +* standard C++ IO logic will be used. +* +* @note One Importer instance is not thread-safe. If you use multiple +* threads for loading, each thread should maintain its own Importer instance. +*/ +class ASSIMP_API Importer { +public: + /** + * @brief The upper limit for hints. + */ + static const unsigned int MaxLenHint = 200; + +public: + // ------------------------------------------------------------------- + /** Constructor. Creates an empty importer object. + * + * Call ReadFile() to start the import process. The configuration + * property table is initially empty. + */ + Importer(); + + // ------------------------------------------------------------------- + /** Copy constructor. + * + * This copies the configuration properties of another Importer. + * If this Importer owns a scene it won't be copied. + * Call ReadFile() to start the import process. + */ + Importer(const Importer &other) = delete; + + // ------------------------------------------------------------------- + /** Assignment operator has been deleted + */ + Importer &operator=(const Importer &) = delete; + + // ------------------------------------------------------------------- + /** Destructor. The object kept ownership of the imported data, + * which now will be destroyed along with the object. + */ + ~Importer(); + + // ------------------------------------------------------------------- + /** Registers a new loader. + * + * @param pImp Importer to be added. The Importer instance takes + * ownership of the pointer, so it will be automatically deleted + * with the Importer instance. + * @return AI_SUCCESS if the loader has been added. The registration + * fails if there is already a loader for a specific file extension. + */ + aiReturn RegisterLoader(BaseImporter *pImp); + + // ------------------------------------------------------------------- + /** Unregisters a loader. + * + * @param pImp Importer to be unregistered. + * @return AI_SUCCESS if the loader has been removed. The function + * fails if the loader is currently in use (this could happen + * if the #Importer instance is used by more than one thread) or + * if it has not yet been registered. + */ + aiReturn UnregisterLoader(BaseImporter *pImp); + + // ------------------------------------------------------------------- + /** Registers a new post-process step. + * + * At the moment, there's a small limitation: new post processing + * steps are added to end of the list, or in other words, executed + * last, after all built-in steps. + * @param pImp Post-process step to be added. The Importer instance + * takes ownership of the pointer, so it will be automatically + * deleted with the Importer instance. + * @return AI_SUCCESS if the step has been added correctly. + */ + aiReturn RegisterPPStep(BaseProcess *pImp); + + // ------------------------------------------------------------------- + /** Unregisters a post-process step. + * + * @param pImp Step to be unregistered. + * @return AI_SUCCESS if the step has been removed. The function + * fails if the step is currently in use (this could happen + * if the #Importer instance is used by more than one thread) or + * if it has not yet been registered. + */ + aiReturn UnregisterPPStep(BaseProcess *pImp); + + // ------------------------------------------------------------------- + /** Set an integer configuration property. + * @param szName Name of the property. All supported properties + * are defined in the aiConfig.g header (all constants share the + * prefix AI_CONFIG_XXX and are simple strings). + * @param iValue New value of the property + * @return true if the property was set before. The new value replaces + * the previous value in this case. + * @note Property of different types (float, int, string ..) are kept + * on different stacks, so calling SetPropertyInteger() for a + * floating-point property has no effect - the loader will call + * GetPropertyFloat() to read the property, but it won't be there. + */ + bool SetPropertyInteger(const char *szName, int iValue); + + // ------------------------------------------------------------------- + /** Set a boolean configuration property. Boolean properties + * are stored on the integer stack internally so it's possible + * to set them via #SetPropertyBool and query them with + * #GetPropertyBool and vice versa. + * @see SetPropertyInteger() + */ + bool SetPropertyBool(const char *szName, bool value) { + return SetPropertyInteger(szName, value); + } + + // ------------------------------------------------------------------- + /** Set a floating-point configuration property. + * @see SetPropertyInteger() + */ + bool SetPropertyFloat(const char *szName, ai_real fValue); + + // ------------------------------------------------------------------- + /** Set a string configuration property. + * @see SetPropertyInteger() + */ + bool SetPropertyString(const char *szName, const std::string &sValue); + + // ------------------------------------------------------------------- + /** Set a matrix configuration property. + * @see SetPropertyInteger() + */ + bool SetPropertyMatrix(const char *szName, const aiMatrix4x4 &sValue); + + // ------------------------------------------------------------------- + /** Set a pointer configuration property. + * @see SetPropertyInteger() + */ + bool SetPropertyPointer(const char *szName, void *sValue); + + // ------------------------------------------------------------------- + /** Get a configuration property. + * @param szName Name of the property. All supported properties + * are defined in the aiConfig.g header (all constants share the + * prefix AI_CONFIG_XXX). + * @param iErrorReturn Value that is returned if the property + * is not found. + * @return Current value of the property + * @note Property of different types (float, int, string ..) are kept + * on different lists, so calling SetPropertyInteger() for a + * floating-point property has no effect - the loader will call + * GetPropertyFloat() to read the property, but it won't be there. + */ + int GetPropertyInteger(const char *szName, + int iErrorReturn = 0xffffffff) const; + + // ------------------------------------------------------------------- + /** Get a boolean configuration property. Boolean properties + * are stored on the integer stack internally so it's possible + * to set them via #SetPropertyBool and query them with + * #GetPropertyBool and vice versa. + * @see GetPropertyInteger() + */ + bool GetPropertyBool(const char *szName, bool bErrorReturn = false) const { + return GetPropertyInteger(szName, bErrorReturn) != 0; + } + + // ------------------------------------------------------------------- + /** Get a floating-point configuration property + * @see GetPropertyInteger() + */ + ai_real GetPropertyFloat(const char *szName, + ai_real fErrorReturn = 10e10) const; + + // ------------------------------------------------------------------- + /** Get a string configuration property + * + * The return value remains valid until the property is modified. + * @see GetPropertyInteger() + */ + std::string GetPropertyString(const char *szName, + const std::string &sErrorReturn = std::string()) const; + + // ------------------------------------------------------------------- + /** Get a matrix configuration property + * + * The return value remains valid until the property is modified. + * @see GetPropertyInteger() + */ + aiMatrix4x4 GetPropertyMatrix(const char *szName, + const aiMatrix4x4 &sErrorReturn = aiMatrix4x4()) const; + + // ------------------------------------------------------------------- + /** Get a pointer configuration property + * + * The return value remains valid until the property is modified. + * @see GetPropertyInteger() + */ + void* GetPropertyPointer(const char *szName, + void *sErrorReturn = nullptr) const; + + // ------------------------------------------------------------------- + /** Supplies a custom IO handler to the importer to use to open and + * access files. If you need the importer to use custom IO logic to + * access the files, you need to provide a custom implementation of + * IOSystem and IOFile to the importer. Then create an instance of + * your custom IOSystem implementation and supply it by this function. + * + * The Importer takes ownership of the object and will destroy it + * afterwards. The previously assigned handler will be deleted. + * Pass nullptr to take again ownership of your IOSystem and reset Assimp + * to use its default implementation. + * + * @param pIOHandler The IO handler to be used in all file accesses + * of the Importer. + */ + void SetIOHandler(IOSystem *pIOHandler); + + // ------------------------------------------------------------------- + /** Retrieves the IO handler that is currently set. + * You can use #IsDefaultIOHandler() to check whether the returned + * interface is the default IO handler provided by ASSIMP. The default + * handler is active as long the application doesn't supply its own + * custom IO handler via #SetIOHandler(). + * @return A valid IOSystem interface, never nullptr. + */ + IOSystem *GetIOHandler() const; + + // ------------------------------------------------------------------- + /** Checks whether a default IO handler is active + * A default handler is active as long the application doesn't + * supply its own custom IO handler via #SetIOHandler(). + * @return true by default + */ + bool IsDefaultIOHandler() const; + + // ------------------------------------------------------------------- + /** Supplies a custom progress handler to the importer. This + * interface exposes an #Update() callback, which is called + * more or less periodically (please don't sue us if it + * isn't as periodically as you'd like it to have ...). + * This can be used to implement progress bars and loading + * timeouts. + * @param pHandler Progress callback interface. Pass nullptr to + * disable progress reporting. + * @note Progress handlers can be used to abort the loading + * at almost any time.*/ + void SetProgressHandler(ProgressHandler *pHandler); + + // ------------------------------------------------------------------- + /** Retrieves the progress handler that is currently set. + * You can use #IsDefaultProgressHandler() to check whether the returned + * interface is the default handler provided by ASSIMP. The default + * handler is active as long the application doesn't supply its own + * custom handler via #SetProgressHandler(). + * @return A valid ProgressHandler interface, never nullptr. + */ + ProgressHandler *GetProgressHandler() const; + + // ------------------------------------------------------------------- + /** Checks whether a default progress handler is active + * A default handler is active as long the application doesn't + * supply its own custom progress handler via #SetProgressHandler(). + * @return true by default + */ + bool IsDefaultProgressHandler() const; + + // ------------------------------------------------------------------- + /** @brief Check whether a given set of post-processing flags + * is supported. + * + * Some flags are mutually exclusive, others are probably + * not available because your excluded them from your + * Assimp builds. Calling this function is recommended if + * you're unsure. + * + * @param pFlags Bitwise combination of the aiPostProcess flags. + * @return true if this flag combination is fine. + */ + bool ValidateFlags(unsigned int pFlags) const; + + // ------------------------------------------------------------------- + /** Reads the given file and returns its contents if successful. + * + * If the call succeeds, the contents of the file are returned as a + * pointer to an aiScene object. The returned data is intended to be + * read-only, the importer object keeps ownership of the data and will + * destroy it upon destruction. If the import fails, nullptr is returned. + * A human-readable error description can be retrieved by calling + * GetErrorString(). The previous scene will be deleted during this call. + * @param pFile Path and filename to the file to be imported. + * @param pFlags Optional post processing steps to be executed after + * a successful import. Provide a bitwise combination of the + * #aiPostProcessSteps flags. If you wish to inspect the imported + * scene first in order to fine-tune your post-processing setup, + * consider to use #ApplyPostProcessing(). + * @return A pointer to the imported data, nullptr if the import failed. + * The pointer to the scene remains in possession of the Importer + * instance. Use GetOrphanedScene() to take ownership of it. + * + * @note Assimp is able to determine the file format of a file + * automatically. + */ + const aiScene *ReadFile( + const char *pFile, + unsigned int pFlags); + + // ------------------------------------------------------------------- + /** Reads the given file from a memory buffer and returns its + * contents if successful. + * + * If the call succeeds, the contents of the file are returned as a + * pointer to an aiScene object. The returned data is intended to be + * read-only, the importer object keeps ownership of the data and will + * destroy it upon destruction. If the import fails, nullptr is returned. + * A human-readable error description can be retrieved by calling + * GetErrorString(). The previous scene will be deleted during this call. + * Calling this method doesn't affect the active IOSystem. + * @param pBuffer Pointer to the file data + * @param pLength Length of pBuffer, in bytes + * @param pFlags Optional post processing steps to be executed after + * a successful import. Provide a bitwise combination of the + * #aiPostProcessSteps flags. If you wish to inspect the imported + * scene first in order to fine-tune your post-processing setup, + * consider to use #ApplyPostProcessing(). + * @param pHint An additional hint to the library. If this is a non + * empty string, the library looks for a loader to support + * the file extension specified by pHint and passes the file to + * the first matching loader. If this loader is unable to completely + * the request, the library continues and tries to determine the + * file format on its own, a task that may or may not be successful. + * Check the return value, and you'll know ... + * @return A pointer to the imported data, nullptr if the import failed. + * The pointer to the scene remains in possession of the Importer + * instance. Use GetOrphanedScene() to take ownership of it. + * + * @note This is a straightforward way to decode models from memory + * buffers, but it doesn't handle model formats that spread their + * data across multiple files or even directories. Examples include + * OBJ or MD3, which outsource parts of their material info into + * external scripts. If you need full functionality, provide + * a custom IOSystem to make Assimp find these files and use + * the regular ReadFile() API. + */ + const aiScene *ReadFileFromMemory( + const void *pBuffer, + size_t pLength, + unsigned int pFlags, + const char *pHint = ""); + + // ------------------------------------------------------------------- + /** Apply post-processing to an already-imported scene. + * + * This is strictly equivalent to calling #ReadFile() with the same + * flags. However, you can use this separate function to inspect + * the imported scene first to fine-tune your post-processing setup. + * @param pFlags Provide a bitwise combination of the + * #aiPostProcessSteps flags. + * @return A pointer to the post-processed data. This is still the + * same as the pointer returned by #ReadFile(). However, if + * post-processing fails, the scene could now be nullptr. + * That's quite a rare case, post processing steps are not really + * designed to 'fail'. To be exact, the #aiProcess_ValidateDS + * flag is currently the only post processing step which can actually + * cause the scene to be reset to nullptr. + * + * @note The method does nothing if no scene is currently bound + * to the #Importer instance. */ + const aiScene *ApplyPostProcessing(unsigned int pFlags); + + const aiScene *ApplyCustomizedPostProcessing(BaseProcess *rootProcess, bool requestValidation); + + // ------------------------------------------------------------------- + /** @brief Reads the given file and returns its contents if successful. + * + * This function is provided for backward compatibility. + * See the const char* version for detailed docs. + * @see ReadFile(const char*, pFlags) */ + const aiScene *ReadFile( + const std::string &pFile, + unsigned int pFlags); + + // ------------------------------------------------------------------- + /** Frees the current scene. + * + * The function does nothing if no scene has previously been + * read via ReadFile(). FreeScene() is called automatically by the + * destructor and ReadFile() itself. */ + void FreeScene(); + + // ------------------------------------------------------------------- + /** Returns an error description of an error that occurred in ReadFile(). + * + * Returns an empty string if no error occurred. + * @return A description of the last error, an empty string if no + * error occurred. The string is never nullptr. + * + * @note The returned function remains valid until one of the + * following methods is called: #ReadFile(), #FreeScene(). */ + const char *GetErrorString() const; + + // ------------------------------------------------------------------- + /** Returns an exception if one occurred during import. + * + * @return The last exception which occurred. + * + * @note The returned value remains valid until one of the + * following methods is called: #ReadFile(), #FreeScene(). */ + const std::exception_ptr& GetException() const; + + // ------------------------------------------------------------------- + /** Returns the scene loaded by the last successful call to ReadFile() + * + * @return Current scene or nullptr if there is currently no scene loaded */ + const aiScene *GetScene() const; + + // ------------------------------------------------------------------- + /** Returns the scene loaded by the last successful call to ReadFile() + * and releases the scene from the ownership of the Importer + * instance. The application is now responsible for deleting the + * scene. Any further calls to GetScene() or GetOrphanedScene() + * will return nullptr - until a new scene has been loaded via ReadFile(). + * + * @return Current scene or nullptr if there is currently no scene loaded + * @note Use this method with maximal caution, and only if you have to. + * By design, aiScene's are exclusively maintained, allocated and + * deallocated by Assimp and no one else. The reasoning behind this + * is the golden rule that deallocations should always be done + * by the module that did the original allocation because heaps + * are not necessarily shared. GetOrphanedScene() enforces you + * to delete the returned scene by yourself, but this will only + * be fine if and only if you're using the same heap as assimp. + * On Windows, it's typically fine provided everything is linked + * against the multithreaded-dll version of the runtime library. + * It will work as well for static linkage with Assimp.*/ + aiScene *GetOrphanedScene(); + + // ------------------------------------------------------------------- + /** Returns whether a given file extension is supported by ASSIMP. + * + * @param szExtension Extension to be checked. + * Must include a trailing dot '.'. Example: ".3ds", ".md3". + * Cases-insensitive. + * @return true if the extension is supported, false otherwise */ + bool IsExtensionSupported(const char *szExtension) const; + + // ------------------------------------------------------------------- + /** @brief Returns whether a given file extension is supported by ASSIMP. + * + * This function is provided for backward compatibility. + * See the const char* version for detailed and up-to-date docs. + * @see IsExtensionSupported(const char*) */ + inline bool IsExtensionSupported(const std::string &szExtension) const; + + // ------------------------------------------------------------------- + /** Get a full list of all file extensions supported by ASSIMP. + * + * If a file extension is contained in the list this does of course not + * mean that ASSIMP is able to load all files with this extension --- + * it simply means there is an importer loaded which claims to handle + * files with this file extension. + * @param szOut String to receive the extension list. + * Format of the list: "*.3ds;*.obj;*.dae". This is useful for + * use with the WinAPI call GetOpenFileName(Ex). */ + void GetExtensionList(aiString &szOut) const; + + // ------------------------------------------------------------------- + /** @brief Get a full list of all file extensions supported by ASSIMP. + * + * This function is provided for backward compatibility. + * See the aiString version for detailed and up-to-date docs. + * @see GetExtensionList(aiString&)*/ + inline void GetExtensionList(std::string &szOut) const; + + // ------------------------------------------------------------------- + /** Get the number of importers currently registered with Assimp. */ + size_t GetImporterCount() const; + + // ------------------------------------------------------------------- + /** Get meta data for the importer corresponding to a specific index.. + * + * For the declaration of #aiImporterDesc, include . + * @param index Index to query, must be within [0,GetImporterCount()) + * @return Importer meta data structure, nullptr if the index does not + * exist or if the importer doesn't offer meta information ( + * importers may do this at the cost of being hated by their peers).*/ + const aiImporterDesc *GetImporterInfo(size_t index) const; + + // ------------------------------------------------------------------- + /** Find the importer corresponding to a specific index. + * + * @param index Index to query, must be within [0,GetImporterCount()) + * @return Importer instance. nullptr if the index does not + * exist. */ + BaseImporter *GetImporter(size_t index) const; + + // ------------------------------------------------------------------- + /** Find the importer corresponding to a specific file extension. + * + * This is quite similar to #IsExtensionSupported except a + * BaseImporter instance is returned. + * @param szExtension Extension to check for. The following formats + * are recognized (BAH being the file extension): "BAH" (comparison + * is case-insensitive), ".bah", "*.bah" (wild card and dot + * characters at the beginning of the extension are skipped). + * @return nullptr if no importer is found*/ + BaseImporter *GetImporter(const char *szExtension) const; + + // ------------------------------------------------------------------- + /** Find the importer index corresponding to a specific file extension. + * + * @param szExtension Extension to check for. The following formats + * are recognized (BAH being the file extension): "BAH" (comparison + * is case-insensitive), ".bah", "*.bah" (wild card and dot + * characters at the beginning of the extension are skipped). + * @return (size_t)-1 if no importer is found */ + size_t GetImporterIndex(const char *szExtension) const; + + // ------------------------------------------------------------------- + /** Returns the storage allocated by ASSIMP to hold the scene data + * in memory. + * + * This refers to the currently loaded file, see #ReadFile(). + * @param in Data structure to be filled. + * @note The returned memory statistics refer to the actual + * size of the use data of the aiScene. Heap-related overhead + * is (naturally) not included.*/ + void GetMemoryRequirements(aiMemoryInfo &in) const; + + // ------------------------------------------------------------------- + /** Enables "extra verbose" mode. + * + * 'Extra verbose' means the data structure is validated after *every* + * single post processing step to make sure everyone modifies the data + * structure in a well-defined manner. This is a debug feature and not + * intended for use in production environments. */ + void SetExtraVerbose(bool bDo); + + // ------------------------------------------------------------------- + /** Private, do not use. */ + ImporterPimpl *Pimpl() { return pimpl; } + const ImporterPimpl *Pimpl() const { return pimpl; } + +protected: + // Just because we don't want you to know how we're hacking around. + ImporterPimpl *pimpl; +}; //! class Importer + +// ---------------------------------------------------------------------------- +// For compatibility, the interface of some functions taking a std::string was +// changed to const char* to avoid crashes between binary incompatible STL +// versions. This code her is inlined, so it shouldn't cause any problems. +// ---------------------------------------------------------------------------- + +// ---------------------------------------------------------------------------- +AI_FORCE_INLINE const aiScene *Importer::ReadFile(const std::string &pFile, unsigned int pFlags) { + return ReadFile(pFile.c_str(), pFlags); +} +// ---------------------------------------------------------------------------- +AI_FORCE_INLINE void Importer::GetExtensionList(std::string &szOut) const { + aiString s; + GetExtensionList(s); + szOut = s.data; +} +// ---------------------------------------------------------------------------- +AI_FORCE_INLINE bool Importer::IsExtensionSupported(const std::string &szExtension) const { + return IsExtensionSupported(szExtension.c_str()); +} + +} // namespace Assimp + +#endif // AI_ASSIMP_HPP_INC diff --git a/dependencies/includes/assimp/LineSplitter.h b/dependencies/includes/assimp/LineSplitter.h new file mode 100644 index 0000000..a8aa665 --- /dev/null +++ b/dependencies/includes/assimp/LineSplitter.h @@ -0,0 +1,273 @@ +/* +Open Asset Import Library (assimp) +---------------------------------------------------------------------- + +Copyright (c) 2006-2022, assimp team + +All rights reserved. + +Redistribution and use of this software in source and binary forms, +with or without modification, are permitted provided that the +following conditions are met: + +* Redistributions of source code must retain the above + copyright notice, this list of conditions and the + following disclaimer. + +* Redistributions in binary form must reproduce the above + copyright notice, this list of conditions and the + following disclaimer in the documentation and/or other + materials provided with the distribution. + +* Neither the name of the assimp team, nor the names of its + contributors may be used to endorse or promote products + derived from this software without specific prior + written permission of the assimp team. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +---------------------------------------------------------------------- +*/ + +/** @file LineSplitter.h + * @brief LineSplitter, a helper class to iterate through all lines + * of a file easily. Works with StreamReader. + */ +#pragma once +#ifndef INCLUDED_LINE_SPLITTER_H +#define INCLUDED_LINE_SPLITTER_H + +#ifdef __GNUC__ +# pragma GCC system_header +#endif + +#include +#include +#include + +namespace Assimp { + +// ------------------------------------------------------------------------------------------------ +/** Usage: +@code +for(LineSplitter splitter(stream);splitter;++splitter) { + + if (*splitter == "hi!") { + ... + } + else if (splitter->substr(0,5) == "hello") { + ... + // access the third token in the line (tokens are space-separated) + if (strtol(splitter[2]) > 5) { .. } + } + + ASSIMP_LOG_VERBOSE_DEBUG("Current line is: ", splitter.get_index()); +} +@endcode +*/ +// ------------------------------------------------------------------------------------------------ +class LineSplitter { +public: + typedef size_t line_idx; + + // ----------------------------------------- + /** construct from existing stream reader + note: trim is *always* assumed true if skyp_empty_lines==true + */ + LineSplitter(StreamReaderLE& stream, bool skip_empty_lines = true, bool trim = true); + + ~LineSplitter(); + + // ----------------------------------------- + /** pseudo-iterator increment */ + LineSplitter& operator++(); + + // ----------------------------------------- + LineSplitter& operator++(int); + + // ----------------------------------------- + /** get a pointer to the beginning of a particular token */ + const char* operator[] (size_t idx) const; + + // ----------------------------------------- + /** extract the start positions of N tokens from the current line*/ + template + void get_tokens(const char* (&tokens)[N]) const; + + // ----------------------------------------- + /** member access */ + const std::string* operator -> () const; + + std::string operator* () const; + + // ----------------------------------------- + /** boolean context */ + operator bool() const; + + // ----------------------------------------- + /** line indices are zero-based, empty lines are included */ + operator line_idx() const; + + line_idx get_index() const; + + // ----------------------------------------- + /** access the underlying stream object */ + StreamReaderLE& get_stream(); + + // ----------------------------------------- + /** !strcmp((*this)->substr(0,strlen(check)),check) */ + bool match_start(const char* check); + + // ----------------------------------------- + /** swallow the next call to ++, return the previous value. */ + void swallow_next_increment(); + + LineSplitter( const LineSplitter & ) = delete; + LineSplitter(LineSplitter &&) = delete; + LineSplitter &operator = ( const LineSplitter & ) = delete; + +private: + line_idx mIdx; + std::string mCur; + StreamReaderLE& mStream; + bool mSwallow, mSkip_empty_lines, mTrim; +}; + +AI_FORCE_INLINE LineSplitter::LineSplitter(StreamReaderLE& stream, bool skip_empty_lines, bool trim ) : + mIdx(0), + mCur(), + mStream(stream), + mSwallow(), + mSkip_empty_lines(skip_empty_lines), + mTrim(trim) { + mCur.reserve(1024); + operator++(); + mIdx = 0; +} + +AI_FORCE_INLINE LineSplitter::~LineSplitter() { + // empty +} + +AI_FORCE_INLINE LineSplitter& LineSplitter::operator++() { + if (mSwallow) { + mSwallow = false; + return *this; + } + + if (!*this) { + throw std::logic_error("End of file, no more lines to be retrieved."); + } + + char s; + mCur.clear(); + while (mStream.GetRemainingSize() && (s = mStream.GetI1(), 1)) { + if (s == '\n' || s == '\r') { + if (mSkip_empty_lines) { + while (mStream.GetRemainingSize() && ((s = mStream.GetI1()) == ' ' || s == '\r' || s == '\n')); + if (mStream.GetRemainingSize()) { + mStream.IncPtr(-1); + } + } else { + // skip both potential line terminators but don't read past this line. + if (mStream.GetRemainingSize() && (s == '\r' && mStream.GetI1() != '\n')) { + mStream.IncPtr(-1); + } + if (mTrim) { + while (mStream.GetRemainingSize() && ((s = mStream.GetI1()) == ' ' || s == '\t')); + if (mStream.GetRemainingSize()) { + mStream.IncPtr(-1); + } + } + } + break; + } + mCur += s; + } + ++mIdx; + + return *this; +} + +AI_FORCE_INLINE LineSplitter &LineSplitter::operator++(int) { + return ++(*this); +} + +AI_FORCE_INLINE const char *LineSplitter::operator[] (size_t idx) const { + const char* s = operator->()->c_str(); + + SkipSpaces(&s); + for (size_t i = 0; i < idx; ++i) { + for (; !IsSpace(*s); ++s) { + if (IsLineEnd(*s)) { + throw std::range_error("Token index out of range, EOL reached"); + } + } + SkipSpaces(&s); + } + return s; +} + +template +AI_FORCE_INLINE void LineSplitter::get_tokens(const char* (&tokens)[N]) const { + const char* s = operator->()->c_str(); + + SkipSpaces(&s); + for (size_t i = 0; i < N; ++i) { + if (IsLineEnd(*s)) { + throw std::range_error("Token count out of range, EOL reached"); + } + tokens[i] = s; + + for (; *s && !IsSpace(*s); ++s); + SkipSpaces(&s); + } +} + +AI_FORCE_INLINE const std::string* LineSplitter::operator -> () const { + return &mCur; +} + +AI_FORCE_INLINE std::string LineSplitter::operator* () const { + return mCur; +} + +AI_FORCE_INLINE LineSplitter::operator bool() const { + return mStream.GetRemainingSize() > 0; +} + +AI_FORCE_INLINE LineSplitter::operator line_idx() const { + return mIdx; +} + +AI_FORCE_INLINE LineSplitter::line_idx LineSplitter::get_index() const { + return mIdx; +} + +AI_FORCE_INLINE StreamReaderLE &LineSplitter::get_stream() { + return mStream; +} + +AI_FORCE_INLINE bool LineSplitter::match_start(const char* check) { + const size_t len = ::strlen(check); + + return len <= mCur.length() && std::equal(check, check + len, mCur.begin()); +} + +AI_FORCE_INLINE void LineSplitter::swallow_next_increment() { + mSwallow = true; +} + +} // Namespace Assimp + +#endif // INCLUDED_LINE_SPLITTER_H diff --git a/dependencies/includes/assimp/LogAux.h b/dependencies/includes/assimp/LogAux.h new file mode 100644 index 0000000..c7b86a1 --- /dev/null +++ b/dependencies/includes/assimp/LogAux.h @@ -0,0 +1,117 @@ +/* +Open Asset Import Library (assimp) +---------------------------------------------------------------------- + +Copyright (c) 2006-2022, assimp team + +All rights reserved. + +Redistribution and use of this software in source and binary forms, +with or without modification, are permitted provided that the +following conditions are met: + +* Redistributions of source code must retain the above + copyright notice, this list of conditions and the + following disclaimer. + +* Redistributions in binary form must reproduce the above + copyright notice, this list of conditions and the + following disclaimer in the documentation and/or other + materials provided with the distribution. + +* Neither the name of the assimp team, nor the names of its + contributors may be used to endorse or promote products + derived from this software without specific prior + written permission of the assimp team. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +---------------------------------------------------------------------- +*/ + +/** @file LogAux.h + * @brief Common logging usage patterns for importer implementations + */ +#pragma once +#ifndef INCLUDED_AI_LOGAUX_H +#define INCLUDED_AI_LOGAUX_H + +#ifdef __GNUC__ +# pragma GCC system_header +#endif + +#include +#include +#include + +namespace Assimp { + +/// @brief Logger class, which will extend the class by log-functions. +/// @tparam TDeriving +template +class LogFunctions { +public: + // ------------------------------------------------------------------------------------------------ + template + static void ThrowException(T&&... args) + { + throw DeadlyImportError(Prefix(), std::forward(args)...); + } + + // ------------------------------------------------------------------------------------------------ + template + static void LogWarn(T&&... args) { + if (!DefaultLogger::isNullLogger()) { + ASSIMP_LOG_WARN(Prefix(), std::forward(args)...); + } + } + + // ------------------------------------------------------------------------------------------------ + template + static void LogError(T&&... args) { + if (!DefaultLogger::isNullLogger()) { + ASSIMP_LOG_ERROR(Prefix(), std::forward(args)...); + } + } + + // ------------------------------------------------------------------------------------------------ + template + static void LogInfo(T&&... args) { + if (!DefaultLogger::isNullLogger()) { + ASSIMP_LOG_INFO(Prefix(), std::forward(args)...); + } + } + + // ------------------------------------------------------------------------------------------------ + template + static void LogDebug(T&&... args) { + if (!DefaultLogger::isNullLogger()) { + ASSIMP_LOG_DEBUG(Prefix(), std::forward(args)...); + } + } + + // ------------------------------------------------------------------------------------------------ + template + static void LogVerboseDebug(T&&... args) { + if (!DefaultLogger::isNullLogger()) { + ASSIMP_LOG_VERBOSE_DEBUG(Prefix(), std::forward(args)...); + } + } + +private: + static const char* Prefix(); +}; + +} // ! Assimp + +#endif // INCLUDED_AI_LOGAUX_H diff --git a/dependencies/includes/assimp/LogStream.hpp b/dependencies/includes/assimp/LogStream.hpp new file mode 100644 index 0000000..3b17b20 --- /dev/null +++ b/dependencies/includes/assimp/LogStream.hpp @@ -0,0 +1,108 @@ +/* +Open Asset Import Library (assimp) +---------------------------------------------------------------------- + +Copyright (c) 2006-2022, assimp team + +All rights reserved. + +Redistribution and use of this software in source and binary forms, +with or without modification, are permitted provided that the +following conditions are met: + +* Redistributions of source code must retain the above + copyright notice, this list of conditions and the + following disclaimer. + +* Redistributions in binary form must reproduce the above + copyright notice, this list of conditions and the + following disclaimer in the documentation and/or other + materials provided with the distribution. + +* Neither the name of the assimp team, nor the names of its + contributors may be used to endorse or promote products + derived from this software without specific prior + written permission of the assimp team. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +---------------------------------------------------------------------- +*/ + +/** @file LogStream.hpp + * @brief Abstract base class 'LogStream', representing an output log stream. + */ +#pragma once +#ifndef INCLUDED_AI_LOGSTREAM_H +#define INCLUDED_AI_LOGSTREAM_H + +#ifdef __GNUC__ +#pragma GCC system_header +#endif + +#include "types.h" + +namespace Assimp { + +class IOSystem; + +// ------------------------------------------------------------------------------------ +/** @brief CPP-API: Abstract interface for log stream implementations. + * + * Several default implementations are provided, see #aiDefaultLogStream for more + * details. Writing your own implementation of LogStream is just necessary if these + * are not enough for your purpose. */ +class ASSIMP_API LogStream +#ifndef SWIG + : public Intern::AllocateFromAssimpHeap +#endif +{ +protected: + /** @brief Default constructor */ + LogStream() AI_NO_EXCEPT; + +public: + /** @brief Virtual destructor */ + virtual ~LogStream(); + + // ------------------------------------------------------------------- + /** @brief Overwrite this for your own output methods + * + * Log messages *may* consist of multiple lines and you shouldn't + * expect a consistent formatting. If you want custom formatting + * (e.g. generate HTML), supply a custom instance of Logger to + * #DefaultLogger:set(). Usually you can *expect* that a log message + * is exactly one line and terminated with a single \n character. + * @param message Message to be written */ + virtual void write(const char *message) = 0; + + // ------------------------------------------------------------------- + /** @brief Creates a default log stream + * @param streams Type of the default stream + * @param name For aiDefaultLogStream_FILE: name of the output file + * @param io For aiDefaultLogStream_FILE: IOSystem to be used to open the output + * file. Pass nullptr for the default implementation. + * @return New LogStream instance. */ + static LogStream *createDefaultStream(aiDefaultLogStream stream, + const char *name = "AssimpLog.txt", + IOSystem *io = nullptr); + +}; // !class LogStream + +inline LogStream::LogStream() AI_NO_EXCEPT = default; + +inline LogStream::~LogStream() = default; + +} // Namespace Assimp + +#endif // INCLUDED_AI_LOGSTREAM_H diff --git a/dependencies/includes/assimp/Logger.hpp b/dependencies/includes/assimp/Logger.hpp new file mode 100644 index 0000000..e8df64d --- /dev/null +++ b/dependencies/includes/assimp/Logger.hpp @@ -0,0 +1,303 @@ +/* +Open Asset Import Library (assimp) +---------------------------------------------------------------------- + +Copyright (c) 2006-2022, assimp team + +All rights reserved. + +Redistribution and use of this software in source and binary forms, +with or without modification, are permitted provided that the +following conditions are met: + +* Redistributions of source code must retain the above + copyright notice, this list of conditions and the + following disclaimer. + +* Redistributions in binary form must reproduce the above + copyright notice, this list of conditions and the + following disclaimer in the documentation and/or other + materials provided with the distribution. + +* Neither the name of the assimp team, nor the names of its + contributors may be used to endorse or promote products + derived from this software without specific prior + written permission of the assimp team. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +---------------------------------------------------------------------- +*/ + +/** @file Logger.hpp + * @brief Abstract base class 'Logger', base of the logging system. + */ +#pragma once +#ifndef INCLUDED_AI_LOGGER_H +#define INCLUDED_AI_LOGGER_H + +#include +#include + +namespace Assimp { + +class LogStream; + +// Maximum length of a log message. Longer messages are rejected. +#define MAX_LOG_MESSAGE_LENGTH 1024u + +// ---------------------------------------------------------------------------------- +/** @brief CPP-API: Abstract interface for logger implementations. + * Assimp provides a default implementation and uses it for almost all + * logging stuff ('DefaultLogger'). This class defines just basic logging + * behavior and is not of interest for you. Instead, take a look at #DefaultLogger. */ +class ASSIMP_API Logger +#ifndef SWIG + : public Intern::AllocateFromAssimpHeap +#endif +{ +public: + + // ---------------------------------------------------------------------- + /** @enum LogSeverity + * @brief Log severity to describe the granularity of logging. + */ + enum LogSeverity { + NORMAL, ///< Normal granularity of logging + DEBUGGING, ///< Debug messages will be logged, but not verbose debug messages. + VERBOSE ///< All messages will be logged + }; + + // ---------------------------------------------------------------------- + /** @enum ErrorSeverity + * @brief Description for severity of a log message. + * + * Every LogStream has a bitwise combination of these flags. + * A LogStream doesn't receive any messages of a specific type + * if it doesn't specify the corresponding ErrorSeverity flag. + */ + enum ErrorSeverity { + Debugging = 1, //!< Debug log message + Info = 2, //!< Info log message + Warn = 4, //!< Warn log message + Err = 8 //!< Error log message + }; + + /** @brief Virtual destructor */ + virtual ~Logger(); + + // ---------------------------------------------------------------------- + /** @brief Writes a debug message + * @param message Debug message*/ + void debug(const char* message); + + template + void debug(T&&... args) { + debug(formatMessage(std::forward(args)...).c_str()); + } + + // ---------------------------------------------------------------------- + /** @brief Writes a debug message + * @param message Debug message*/ + void verboseDebug(const char* message); + + template + void verboseDebug(T&&... args) { + verboseDebug(formatMessage(std::forward(args)...).c_str()); + } + + // ---------------------------------------------------------------------- + /** @brief Writes a info message + * @param message Info message*/ + void info(const char* message); + + template + void info(T&&... args) { + info(formatMessage(std::forward(args)...).c_str()); + } + + // ---------------------------------------------------------------------- + /** @brief Writes a warning message + * @param message Warn message*/ + void warn(const char* message); + + template + void warn(T&&... args) { + warn(formatMessage(std::forward(args)...).c_str()); + } + + // ---------------------------------------------------------------------- + /** @brief Writes an error message + * @param message Error message*/ + void error(const char* message); + + template + void error(T&&... args) { + error(formatMessage(std::forward(args)...).c_str()); + } + + // ---------------------------------------------------------------------- + /** @brief Set a new log severity. + * @param log_severity New severity for logging*/ + void setLogSeverity(LogSeverity log_severity); + + // ---------------------------------------------------------------------- + /** @brief Get the current log severity*/ + LogSeverity getLogSeverity() const; + + // ---------------------------------------------------------------------- + /** @brief Attach a new log-stream + * + * The logger takes ownership of the stream and is responsible + * for its destruction (which is done using ::delete when the logger + * itself is destroyed). Call detachStream to detach a stream and to + * gain ownership of it again. + * @param pStream Log-stream to attach + * @param severity Message filter, specified which types of log + * messages are dispatched to the stream. Provide a bitwise + * combination of the ErrorSeverity flags. + * @return true if the stream has been attached, false otherwise.*/ + virtual bool attachStream(LogStream *pStream, + unsigned int severity = Debugging | Err | Warn | Info) = 0; + + // ---------------------------------------------------------------------- + /** @brief Detach a still attached stream from the logger (or + * modify the filter flags bits) + * @param pStream Log-stream instance for detaching + * @param severity Provide a bitwise combination of the ErrorSeverity + * flags. This value is &~ed with the current flags of the stream, + * if the result is 0 the stream is detached from the Logger and + * the caller retakes the possession of the stream. + * @return true if the stream has been detached, false otherwise.*/ + virtual bool detachStream(LogStream *pStream, + unsigned int severity = Debugging | Err | Warn | Info) = 0; + +protected: + /** + * Default constructor + */ + Logger() AI_NO_EXCEPT; + + /** + * Construction with a given log severity + */ + explicit Logger(LogSeverity severity); + + // ---------------------------------------------------------------------- + /** + * @brief Called as a request to write a specific debug message + * @param message Debug message. Never longer than + * MAX_LOG_MESSAGE_LENGTH characters (excluding the '0'). + * @note The message string is only valid until the scope of + * the function is left. + */ + virtual void OnDebug(const char* message)= 0; + + // ---------------------------------------------------------------------- + /** + * @brief Called as a request to write a specific verbose debug message + * @param message Debug message. Never longer than + * MAX_LOG_MESSAGE_LENGTH characters (excluding the '0'). + * @note The message string is only valid until the scope of + * the function is left. + */ + virtual void OnVerboseDebug(const char *message) = 0; + + // ---------------------------------------------------------------------- + /** + * @brief Called as a request to write a specific info message + * @param message Info message. Never longer than + * MAX_LOG_MESSAGE_LENGTH characters (ecxluding the '0'). + * @note The message string is only valid until the scope of + * the function is left. + */ + virtual void OnInfo(const char* message) = 0; + + // ---------------------------------------------------------------------- + /** + * @brief Called as a request to write a specific warn message + * @param message Warn message. Never longer than + * MAX_LOG_MESSAGE_LENGTH characters (exluding the '0'). + * @note The message string is only valid until the scope of + * the function is left. + */ + virtual void OnWarn(const char* essage) = 0; + + // ---------------------------------------------------------------------- + /** + * @brief Called as a request to write a specific error message + * @param message Error message. Never longer than + * MAX_LOG_MESSAGE_LENGTH characters (exluding the '0'). + * @note The message string is only valid until the scope of + * the function is left. + */ + virtual void OnError(const char* message) = 0; +protected: + std::string formatMessage(Assimp::Formatter::format f) { + return f; + } + + template + std::string formatMessage(Assimp::Formatter::format f, U&& u, T&&... args) { + return formatMessage(std::move(f << std::forward(u)), std::forward(args)...); + } + +protected: + LogSeverity m_Severity; +}; + +// ---------------------------------------------------------------------------------- +inline Logger::Logger() AI_NO_EXCEPT : + m_Severity(NORMAL) { + // empty +} + +// ---------------------------------------------------------------------------------- +inline Logger::~Logger() = default; + +// ---------------------------------------------------------------------------------- +inline Logger::Logger(LogSeverity severity) : + m_Severity(severity) { + // empty +} + +// ---------------------------------------------------------------------------------- +inline void Logger::setLogSeverity(LogSeverity log_severity){ + m_Severity = log_severity; +} + +// ---------------------------------------------------------------------------------- +// Log severity getter +inline Logger::LogSeverity Logger::getLogSeverity() const { + return m_Severity; +} + +} // Namespace Assimp + +// ------------------------------------------------------------------------------------------------ +#define ASSIMP_LOG_WARN(...) \ + Assimp::DefaultLogger::get()->warn(__VA_ARGS__) + +#define ASSIMP_LOG_ERROR(...) \ + Assimp::DefaultLogger::get()->error(__VA_ARGS__) + +#define ASSIMP_LOG_DEBUG(...) \ + Assimp::DefaultLogger::get()->debug(__VA_ARGS__) + +#define ASSIMP_LOG_VERBOSE_DEBUG(...) \ + Assimp::DefaultLogger::get()->verboseDebug(__VA_ARGS__) + +#define ASSIMP_LOG_INFO(...) \ + Assimp::DefaultLogger::get()->info(__VA_ARGS__) + +#endif // !! INCLUDED_AI_LOGGER_H diff --git a/dependencies/includes/assimp/MathFunctions.h b/dependencies/includes/assimp/MathFunctions.h new file mode 100644 index 0000000..f2a7ccd --- /dev/null +++ b/dependencies/includes/assimp/MathFunctions.h @@ -0,0 +1,105 @@ +/* +--------------------------------------------------------------------------- +Open Asset Import Library (assimp) +--------------------------------------------------------------------------- + +Copyright (c) 2006-2022, assimp team + +All rights reserved. + +Redistribution and use of this software in source and binary forms, +with or without modification, are permitted provided that the following +conditions are met: + +* Redistributions of source code must retain the above + copyright notice, this list of conditions and the + following disclaimer. + +* Redistributions in binary form must reproduce the above + copyright notice, this list of conditions and the + following disclaimer in the documentation and/or other + materials provided with the distribution. + +* Neither the name of the assimp team, nor the names of its + contributors may be used to endorse or promote products + derived from this software without specific prior + written permission of the assimp team. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +--------------------------------------------------------------------------- +*/ + +#pragma once + +#ifdef __GNUC__ +# pragma GCC system_header +#endif + +/** @file MathFunctions.h +* @brief Implementation of math utility functions. + * +*/ + +#include + +namespace Assimp { +namespace Math { + +/// @brief Will return the greatest common divisor. +/// @param a [in] Value a. +/// @param b [in] Value b. +/// @return The greatest common divisor. +template +inline IntegerType gcd( IntegerType a, IntegerType b ) { + const IntegerType zero = (IntegerType)0; + while ( true ) { + if ( a == zero ) { + return b; + } + b %= a; + + if ( b == zero ) { + return a; + } + a %= b; + } +} + +/// @brief Will return the greatest common divisor. +/// @param a [in] Value a. +/// @param b [in] Value b. +/// @return The greatest common divisor. +template < typename IntegerType > +inline IntegerType lcm( IntegerType a, IntegerType b ) { + const IntegerType t = gcd (a,b); + if (!t) { + return t; + } + return a / t * b; +} +/// @brief Will return the smallest epsilon-value for the requested type. +/// @return The numercical limit epsilon depending on its type. +template +inline T getEpsilon() { + return std::numeric_limits::epsilon(); +} + +/// @brief Will return the constant PI for the requested type. +/// @return Pi +template +inline T aiPi() { + return static_cast(3.14159265358979323846); +} + +} // namespace Math +} // namespace Assimp diff --git a/dependencies/includes/assimp/MemoryIOWrapper.h b/dependencies/includes/assimp/MemoryIOWrapper.h new file mode 100644 index 0000000..b4c3776 --- /dev/null +++ b/dependencies/includes/assimp/MemoryIOWrapper.h @@ -0,0 +1,250 @@ +/* +Open Asset Import Library (assimp) +---------------------------------------------------------------------- + +Copyright (c) 2006-2022, assimp team + + +All rights reserved. + +Redistribution and use of this software in source and binary forms, +with or without modification, are permitted provided that the +following conditions are met: + +* Redistributions of source code must retain the above + copyright notice, this list of conditions and the + following disclaimer. + +* Redistributions in binary form must reproduce the above + copyright notice, this list of conditions and the + following disclaimer in the documentation and/or other + materials provided with the distribution. + +* Neither the name of the assimp team, nor the names of its + contributors may be used to endorse or promote products + derived from this software without specific prior + written permission of the assimp team. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +---------------------------------------------------------------------- +*/ + +/** @file MemoryIOWrapper.h + * Handy IOStream/IOSystem implementation to read directly from a memory buffer */ +#pragma once +#ifndef AI_MEMORYIOSTREAM_H_INC +#define AI_MEMORYIOSTREAM_H_INC + +#ifdef __GNUC__ +# pragma GCC system_header +#endif + +#include +#include +#include + +#include + +namespace Assimp { + +#define AI_MEMORYIO_MAGIC_FILENAME "$$$___magic___$$$" +#define AI_MEMORYIO_MAGIC_FILENAME_LENGTH 17 + +// ---------------------------------------------------------------------------------- +/** Implementation of IOStream to read directly from a memory buffer */ +// ---------------------------------------------------------------------------------- +class MemoryIOStream : public IOStream { +public: + MemoryIOStream (const uint8_t* buff, size_t len, bool own = false) + : buffer (buff) + , length(len) + , pos((size_t)0) + , own(own) { + // empty + } + + ~MemoryIOStream () { + if(own) { + delete[] buffer; + } + } + + // ------------------------------------------------------------------- + // Read from stream + size_t Read(void* pvBuffer, size_t pSize, size_t pCount) { + ai_assert(nullptr != pvBuffer); + ai_assert(0 != pSize); + + const size_t cnt = std::min( pCount, (length-pos) / pSize); + const size_t ofs = pSize * cnt; + + ::memcpy(pvBuffer,buffer+pos,ofs); + pos += ofs; + + return cnt; + } + + // ------------------------------------------------------------------- + // Write to stream + size_t Write(const void* /*pvBuffer*/, size_t /*pSize*/,size_t /*pCount*/) { + ai_assert(false); // won't be needed + return 0; + } + + // ------------------------------------------------------------------- + // Seek specific position + aiReturn Seek(size_t pOffset, aiOrigin pOrigin) { + if (aiOrigin_SET == pOrigin) { + if (pOffset > length) { + return AI_FAILURE; + } + pos = pOffset; + } else if (aiOrigin_END == pOrigin) { + if (pOffset > length) { + return AI_FAILURE; + } + pos = length-pOffset; + } else { + if (pOffset+pos > length) { + return AI_FAILURE; + } + pos += pOffset; + } + return AI_SUCCESS; + } + + // ------------------------------------------------------------------- + // Get current seek position + size_t Tell() const { + return pos; + } + + // ------------------------------------------------------------------- + // Get size of file + size_t FileSize() const { + return length; + } + + // ------------------------------------------------------------------- + // Flush file contents + void Flush() { + ai_assert(false); // won't be needed + } + +private: + const uint8_t* buffer; + size_t length,pos; + bool own; +}; + +// --------------------------------------------------------------------------- +/** Dummy IO system to read from a memory buffer */ +class MemoryIOSystem : public IOSystem { +public: + /** Constructor. */ + MemoryIOSystem(const uint8_t* buff, size_t len, IOSystem* io) + : buffer(buff) + , length(len) + , existing_io(io) + , created_streams() { + // empty + } + + /** Destructor. */ + ~MemoryIOSystem() { + } + + // ------------------------------------------------------------------- + /** Tests for the existence of a file at the given path. */ + bool Exists(const char* pFile) const override { + if (0 == strncmp( pFile, AI_MEMORYIO_MAGIC_FILENAME, AI_MEMORYIO_MAGIC_FILENAME_LENGTH ) ) { + return true; + } + return existing_io ? existing_io->Exists(pFile) : false; + } + + // ------------------------------------------------------------------- + /** Returns the directory separator. */ + char getOsSeparator() const override { + return existing_io ? existing_io->getOsSeparator() + : '/'; // why not? it doesn't care + } + + // ------------------------------------------------------------------- + /** Open a new file with a given path. */ + IOStream* Open(const char* pFile, const char* pMode = "rb") override { + if ( 0 == strncmp( pFile, AI_MEMORYIO_MAGIC_FILENAME, AI_MEMORYIO_MAGIC_FILENAME_LENGTH ) ) { + created_streams.emplace_back(new MemoryIOStream(buffer, length)); + return created_streams.back(); + } + return existing_io ? existing_io->Open(pFile, pMode) : NULL; + } + + // ------------------------------------------------------------------- + /** Closes the given file and releases all resources associated with it. */ + void Close( IOStream* pFile) override { + auto it = std::find(created_streams.begin(), created_streams.end(), pFile); + if (it != created_streams.end()) { + delete pFile; + created_streams.erase(it); + } else if (existing_io) { + existing_io->Close(pFile); + } + } + + // ------------------------------------------------------------------- + /** Compare two paths */ + bool ComparePaths(const char* one, const char* second) const override { + return existing_io ? existing_io->ComparePaths(one, second) : false; + } + + bool PushDirectory( const std::string &path ) override { + return existing_io ? existing_io->PushDirectory(path) : false; + } + + const std::string &CurrentDirectory() const override { + static std::string empty; + return existing_io ? existing_io->CurrentDirectory() : empty; + } + + size_t StackSize() const override { + return existing_io ? existing_io->StackSize() : 0; + } + + bool PopDirectory() override { + return existing_io ? existing_io->PopDirectory() : false; + } + + bool CreateDirectory( const std::string &path ) override { + return existing_io ? existing_io->CreateDirectory(path) : false; + } + + bool ChangeDirectory( const std::string &path ) override { + return existing_io ? existing_io->ChangeDirectory(path) : false; + } + + bool DeleteFile( const std::string &file ) override { + return existing_io ? existing_io->DeleteFile(file) : false; + } + +private: + const uint8_t* buffer; + size_t length; + IOSystem* existing_io; + std::vector created_streams; +}; + +} // end namespace Assimp + +#endif diff --git a/dependencies/includes/assimp/NullLogger.hpp b/dependencies/includes/assimp/NullLogger.hpp new file mode 100644 index 0000000..1b594ea --- /dev/null +++ b/dependencies/includes/assimp/NullLogger.hpp @@ -0,0 +1,109 @@ +/* +Open Asset Import Library (assimp) +---------------------------------------------------------------------- + +Copyright (c) 2006-2022, assimp team + + +All rights reserved. + +Redistribution and use of this software in source and binary forms, +with or without modification, are permitted provided that the +following conditions are met: + +* Redistributions of source code must retain the above + copyright notice, this list of conditions and the + following disclaimer. + +* Redistributions in binary form must reproduce the above + copyright notice, this list of conditions and the + following disclaimer in the documentation and/or other + materials provided with the distribution. + +* Neither the name of the assimp team, nor the names of its + contributors may be used to endorse or promote products + derived from this software without specific prior + written permission of the assimp team. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +---------------------------------------------------------------------- +*/ + +/** @file NullLogger.hpp + * @brief Dummy logger +*/ + +#pragma once +#ifndef INCLUDED_AI_NULLLOGGER_H +#define INCLUDED_AI_NULLLOGGER_H + +#ifdef __GNUC__ +#pragma GCC system_header +#endif + +#include "Logger.hpp" + +namespace Assimp { + +// --------------------------------------------------------------------------- +/** @brief CPP-API: Empty logging implementation. + * + * Does nothing! Used by default if the application hasn't requested a + * custom logger via #DefaultLogger::set() or #DefaultLogger::create(); */ +class ASSIMP_API NullLogger + : public Logger { + +public: + + /** @brief Logs a debug message */ + void OnDebug(const char* message) { + (void)message; //this avoids compiler warnings + } + + /** @brief Logs a verbose debug message */ + void OnVerboseDebug(const char *message) { + (void)message; //this avoids compiler warnings + } + + /** @brief Logs an info message */ + void OnInfo(const char* message) { + (void)message; //this avoids compiler warnings + } + + /** @brief Logs a warning message */ + void OnWarn(const char* message) { + (void)message; //this avoids compiler warnings + } + + /** @brief Logs an error message */ + void OnError(const char* message) { + (void)message; //this avoids compiler warnings + } + + /** @brief Detach a still attached stream from logger */ + bool attachStream(LogStream *pStream, unsigned int severity) { + (void)pStream; (void)severity; //this avoids compiler warnings + return false; + } + + /** @brief Detach a still attached stream from logger */ + bool detachStream(LogStream *pStream, unsigned int severity) { + (void)pStream; (void)severity; //this avoids compiler warnings + return false; + } + +private: +}; +} +#endif // !! AI_NULLLOGGER_H_INCLUDED diff --git a/dependencies/includes/assimp/ObjMaterial.h b/dependencies/includes/assimp/ObjMaterial.h new file mode 100644 index 0000000..bba2076 --- /dev/null +++ b/dependencies/includes/assimp/ObjMaterial.h @@ -0,0 +1,84 @@ +/* +--------------------------------------------------------------------------- +Open Asset Import Library (assimp) +--------------------------------------------------------------------------- + +Copyright (c) 2006-2022, assimp team + +All rights reserved. + +Redistribution and use of this software in source and binary forms, +with or without modification, are permitted provided that the following +conditions are met: + +* Redistributions of source code must retain the above + copyright notice, this list of conditions and the + following disclaimer. + +* Redistributions in binary form must reproduce the above + copyright notice, this list of conditions and the + following disclaimer in the documentation and/or other + materials provided with the distribution. + +* Neither the name of the assimp team, nor the names of its + contributors may be used to endorse or promote products + derived from this software without specific prior + written permission of the assimp team. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +--------------------------------------------------------------------------- +*/ + +/** @file OBJMATERIAL.h + * @brief Obj-specific material macros + * + */ + +#ifndef AI_OBJMATERIAL_H_INC +#define AI_OBJMATERIAL_H_INC + +#ifdef __GNUC__ +# pragma GCC system_header +#endif + +#include + +// --------------------------------------------------------------------------- + +// the original illum property +#define AI_MATKEY_OBJ_ILLUM "$mat.illum", 0, 0 + +// --------------------------------------------------------------------------- + +// --------------------------------------------------------------------------- +// Pure key names for all obj texture-related properties +//! @cond MATS_DOC_FULL + +// support for bump -bm +#define _AI_MATKEY_OBJ_BUMPMULT_BASE "$tex.bumpmult" +//! @endcond + +// --------------------------------------------------------------------------- +#define AI_MATKEY_OBJ_BUMPMULT(type, N) _AI_MATKEY_OBJ_BUMPMULT_BASE, type, N + +//! @cond MATS_DOC_FULL +#define AI_MATKEY_OBJ_BUMPMULT_NORMALS(N) \ + AI_MATKEY_OBJ_BUMPMULT(aiTextureType_NORMALS, N) + +#define AI_MATKEY_OBJ_BUMPMULT_HEIGHT(N) \ + AI_MATKEY_OBJ_BUMPMULT(aiTextureType_HEIGHT, N) + +//! @endcond + + +#endif diff --git a/dependencies/includes/assimp/ParsingUtils.h b/dependencies/includes/assimp/ParsingUtils.h new file mode 100644 index 0000000..b08f232 --- /dev/null +++ b/dependencies/includes/assimp/ParsingUtils.h @@ -0,0 +1,272 @@ +/* +Open Asset Import Library (assimp) +---------------------------------------------------------------------- + +Copyright (c) 2006-2022, assimp team + +All rights reserved. + +Redistribution and use of this software in source and binary forms, +with or without modification, are permitted provided that the +following conditions are met: + +* Redistributions of source code must retain the above + copyright notice, this list of conditions and the + following disclaimer. + +* Redistributions in binary form must reproduce the above + copyright notice, this list of conditions and the + following disclaimer in the documentation and/or other + materials provided with the distribution. + +* Neither the name of the assimp team, nor the names of its + contributors may be used to endorse or promote products + derived from this software without specific prior + written permission of the assimp team. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +---------------------------------------------------------------------- +*/ + +/** @file ParsingUtils.h + * @brief Defines helper functions for text parsing + */ +#pragma once +#ifndef AI_PARSING_UTILS_H_INC +#define AI_PARSING_UTILS_H_INC + +#ifdef __GNUC__ +#pragma GCC system_header +#endif + +#include +#include +#include + +#include +#include + +namespace Assimp { + +// NOTE: the functions below are mostly intended as replacement for +// std::upper, std::lower, std::isupper, std::islower, std::isspace. +// we don't bother of locales. We don't want them. We want reliable +// (i.e. identical) results across all locales. + +// The functions below accept any character type, but know only +// about ASCII. However, UTF-32 is the only safe ASCII superset to +// use since it doesn't have multi-byte sequences. + +static const unsigned int BufferSize = 4096; + + +// --------------------------------------------------------------------------------- +template +AI_FORCE_INLINE bool IsUpper(char_t in) { + return (in >= (char_t)'A' && in <= (char_t)'Z'); +} + +// --------------------------------------------------------------------------------- +template +AI_FORCE_INLINE bool IsLower(char_t in) { + return (in >= (char_t)'a' && in <= (char_t)'z'); +} + +// --------------------------------------------------------------------------------- +template +AI_FORCE_INLINE bool IsSpace(char_t in) { + return (in == (char_t)' ' || in == (char_t)'\t'); +} + +// --------------------------------------------------------------------------------- +template +AI_FORCE_INLINE bool IsLineEnd(char_t in) { + return (in == (char_t)'\r' || in == (char_t)'\n' || in == (char_t)'\0' || in == (char_t)'\f'); +} + +// --------------------------------------------------------------------------------- +template +AI_FORCE_INLINE bool IsSpaceOrNewLine(char_t in) { + return IsSpace(in) || IsLineEnd(in); +} + +// --------------------------------------------------------------------------------- +template +AI_FORCE_INLINE bool SkipSpaces(const char_t *in, const char_t **out) { + while (*in == (char_t)' ' || *in == (char_t)'\t') { + ++in; + } + *out = in; + return !IsLineEnd(*in); +} + +// --------------------------------------------------------------------------------- +template +AI_FORCE_INLINE bool SkipSpaces(const char_t **inout) { + return SkipSpaces(*inout, inout); +} + +// --------------------------------------------------------------------------------- +template +AI_FORCE_INLINE bool SkipLine(const char_t *in, const char_t **out) { + while (*in != (char_t)'\r' && *in != (char_t)'\n' && *in != (char_t)'\0') { + ++in; + } + + // files are opened in binary mode. Ergo there are both NL and CR + while (*in == (char_t)'\r' || *in == (char_t)'\n') { + ++in; + } + *out = in; + return *in != (char_t)'\0'; +} + +// --------------------------------------------------------------------------------- +template +AI_FORCE_INLINE bool SkipLine(const char_t **inout) { + return SkipLine(*inout, inout); +} + +// --------------------------------------------------------------------------------- +template +AI_FORCE_INLINE bool SkipSpacesAndLineEnd(const char_t *in, const char_t **out) { + while (*in == (char_t)' ' || *in == (char_t)'\t' || *in == (char_t)'\r' || *in == (char_t)'\n') { + ++in; + } + *out = in; + return *in != '\0'; +} + +// --------------------------------------------------------------------------------- +template +AI_FORCE_INLINE bool SkipSpacesAndLineEnd(const char_t **inout) { + return SkipSpacesAndLineEnd(*inout, inout); +} + +// --------------------------------------------------------------------------------- +template +AI_FORCE_INLINE bool GetNextLine(const char_t *&buffer, char_t out[BufferSize]) { + if ((char_t)'\0' == *buffer) { + return false; + } + + char *_out = out; + char *const end = _out + BufferSize; + while (!IsLineEnd(*buffer) && _out < end) { + *_out++ = *buffer++; + } + *_out = (char_t)'\0'; + + while (IsLineEnd(*buffer) && '\0' != *buffer) { + ++buffer; + } + + return true; +} + +// --------------------------------------------------------------------------------- +template +AI_FORCE_INLINE bool IsNumeric(char_t in) { + return (in >= '0' && in <= '9') || '-' == in || '+' == in; +} + +// --------------------------------------------------------------------------------- +template +AI_FORCE_INLINE bool TokenMatch(char_t *&in, const char *token, unsigned int len) { + if (!::strncmp(token, in, len) && IsSpaceOrNewLine(in[len])) { + if (in[len] != '\0') { + in += len + 1; + } else { + // If EOF after the token make sure we don't go past end of buffer + in += len; + } + return true; + } + + return false; +} +// --------------------------------------------------------------------------------- +/** @brief Case-ignoring version of TokenMatch + * @param in Input + * @param token Token to check for + * @param len Number of characters to check + */ +AI_FORCE_INLINE bool TokenMatchI(const char *&in, const char *token, unsigned int len) { + if (!ASSIMP_strincmp(token, in, len) && IsSpaceOrNewLine(in[len])) { + in += len + 1; + return true; + } + return false; +} + +// --------------------------------------------------------------------------------- +AI_FORCE_INLINE void SkipToken(const char *&in) { + SkipSpaces(&in); + while (!IsSpaceOrNewLine(*in)) { + ++in; + } +} + +// --------------------------------------------------------------------------------- +AI_FORCE_INLINE std::string GetNextToken(const char *&in) { + SkipSpacesAndLineEnd(&in); + const char *cur = in; + while (!IsSpaceOrNewLine(*in)) { + ++in; + } + return std::string(cur, (size_t)(in - cur)); +} + +// --------------------------------------------------------------------------------- +/** @brief Will perform a simple tokenize. + * @param str String to tokenize. + * @param tokens Array with tokens, will be empty if no token was found. + * @param delimiters Delimiter for tokenize. + * @return Number of found token. + */ +template +AI_FORCE_INLINE unsigned int tokenize(const string_type &str, std::vector &tokens, + const string_type &delimiters) { + // Skip delimiters at beginning. + typename string_type::size_type lastPos = str.find_first_not_of(delimiters, 0); + + // Find first "non-delimiter". + typename string_type::size_type pos = str.find_first_of(delimiters, lastPos); + while (string_type::npos != pos || string_type::npos != lastPos) { + // Found a token, add it to the vector. + string_type tmp = str.substr(lastPos, pos - lastPos); + if (!tmp.empty() && ' ' != tmp[0]) + tokens.push_back(tmp); + + // Skip delimiters. Note the "not_of" + lastPos = str.find_first_not_of(delimiters, pos); + + // Find next "non-delimiter" + pos = str.find_first_of(delimiters, lastPos); + } + + return static_cast(tokens.size()); +} + +inline std::string ai_stdStrToLower(const std::string &str) { + std::string out(str); + for (size_t i = 0; i < str.size(); ++i) { + out[i] = (char) tolower((unsigned char)out[i]); + } + return out; +} + +} // namespace Assimp + +#endif // ! AI_PARSING_UTILS_H_INC diff --git a/dependencies/includes/assimp/Profiler.h b/dependencies/includes/assimp/Profiler.h new file mode 100644 index 0000000..fe0ffbb --- /dev/null +++ b/dependencies/includes/assimp/Profiler.h @@ -0,0 +1,103 @@ +/* +Open Asset Import Library (assimp) +---------------------------------------------------------------------- + +Copyright (c) 2006-2022, assimp team + + +All rights reserved. + +Redistribution and use of this software in source and binary forms, +with or without modification, are permitted provided that the +following conditions are met: + +* Redistributions of source code must retain the above + copyright notice, this list of conditions and the + following disclaimer. + +* Redistributions in binary form must reproduce the above + copyright notice, this list of conditions and the + following disclaimer in the documentation and/or other + materials provided with the distribution. + +* Neither the name of the assimp team, nor the names of its + contributors may be used to endorse or promote products + derived from this software without specific prior + written permission of the assimp team. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +---------------------------------------------------------------------- +*/ + +/** @file Profiler.h + * @brief Utility to measure the respective runtime of each import step + */ +#pragma once +#ifndef AI_INCLUDED_PROFILER_H +#define AI_INCLUDED_PROFILER_H + +#ifdef __GNUC__ +# pragma GCC system_header +#endif + +#include +#include +#include + +#include + +namespace Assimp { +namespace Profiling { + +using namespace Formatter; + +// ------------------------------------------------------------------------------------------------ +/** Simple wrapper around boost::timer to simplify reporting. Timings are automatically + * dumped to the log file. + */ +class Profiler { +public: + Profiler() { + // empty + } + + + /** Start a named timer */ + void BeginRegion(const std::string& region) { + regions[region] = std::chrono::system_clock::now(); + ASSIMP_LOG_DEBUG("START `",region,"`"); + } + + + /** End a specific named timer and write its end time to the log */ + void EndRegion(const std::string& region) { + RegionMap::const_iterator it = regions.find(region); + if (it == regions.end()) { + return; + } + + std::chrono::duration elapsedSeconds = std::chrono::system_clock::now() - regions[region]; + ASSIMP_LOG_DEBUG("END `",region,"`, dt= ", elapsedSeconds.count()," s"); + } + +private: + typedef std::map> RegionMap; + RegionMap regions; +}; + +} +} + +#endif // AI_INCLUDED_PROFILER_H + diff --git a/dependencies/includes/assimp/ProgressHandler.hpp b/dependencies/includes/assimp/ProgressHandler.hpp new file mode 100644 index 0000000..1a272bb --- /dev/null +++ b/dependencies/includes/assimp/ProgressHandler.hpp @@ -0,0 +1,150 @@ +/* +Open Asset Import Library (assimp) +---------------------------------------------------------------------- + +Copyright (c) 2006-2022, assimp team + + +All rights reserved. + +Redistribution and use of this software in source and binary forms, +with or without modification, are permitted provided that the +following conditions are met: + +* Redistributions of source code must retain the above + copyright notice, this list of conditions and the + following disclaimer. + +* Redistributions in binary form must reproduce the above + copyright notice, this list of conditions and the + following disclaimer in the documentation and/or other + materials provided with the distribution. + +* Neither the name of the assimp team, nor the names of its + contributors may be used to endorse or promote products + derived from this software without specific prior + written permission of the assimp team. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +---------------------------------------------------------------------- +*/ + +/** @file ProgressHandler.hpp + * @brief Abstract base class 'ProgressHandler'. + */ +#pragma once +#ifndef AI_PROGRESSHANDLER_H_INC +#define AI_PROGRESSHANDLER_H_INC + +#ifdef __GNUC__ +# pragma GCC system_header +#endif + +#include + +namespace Assimp { + +// ------------------------------------------------------------------------------------ +/** @brief CPP-API: Abstract interface for custom progress report receivers. + * + * Each #Importer instance maintains its own #ProgressHandler. The default + * implementation provided by Assimp doesn't do anything at all. */ +class ASSIMP_API ProgressHandler +#ifndef SWIG + : public Intern::AllocateFromAssimpHeap +#endif +{ +protected: + /// @brief Default constructor + ProgressHandler () AI_NO_EXCEPT { + // empty + } + +public: + /// @brief Virtual destructor. + virtual ~ProgressHandler () { + // empty + } + + // ------------------------------------------------------------------- + /** @brief Progress callback. + * @param percentage An estimate of the current loading progress, + * in percent. Or -1.f if such an estimate is not available. + * + * There are restriction on what you may do from within your + * implementation of this method: no exceptions may be thrown and no + * non-const #Importer methods may be called. It is + * not generally possible to predict the number of callbacks + * fired during a single import. + * + * @return Return false to abort loading at the next possible + * occasion (loaders and Assimp are generally allowed to perform + * all needed cleanup tasks prior to returning control to the + * caller). If the loading is aborted, #Importer::ReadFile() + * returns always nullptr. + * */ + virtual bool Update(float percentage = -1.f) = 0; + + // ------------------------------------------------------------------- + /** @brief Progress callback for file loading steps + * @param numberOfSteps The number of total post-processing + * steps + * @param currentStep The index of the current post-processing + * step that will run, or equal to numberOfSteps if all of + * them has finished. This number is always strictly monotone + * increasing, although not necessarily linearly. + * + * @note This is currently only used at the start and the end + * of the file parsing. + * */ + virtual void UpdateFileRead(int currentStep /*= 0*/, int numberOfSteps /*= 0*/) { + float f = numberOfSteps ? currentStep / (float)numberOfSteps : 1.0f; + Update( f * 0.5f ); + } + + // ------------------------------------------------------------------- + /** @brief Progress callback for post-processing steps + * @param numberOfSteps The number of total post-processing + * steps + * @param currentStep The index of the current post-processing + * step that will run, or equal to numberOfSteps if all of + * them has finished. This number is always strictly monotone + * increasing, although not necessarily linearly. + * */ + virtual void UpdatePostProcess(int currentStep /*= 0*/, int numberOfSteps /*= 0*/) { + float f = numberOfSteps ? currentStep / (float)numberOfSteps : 1.0f; + Update( f * 0.5f + 0.5f ); + } + + + // ------------------------------------------------------------------- + /** @brief Progress callback for export steps. + * @param numberOfSteps The number of total processing + * steps + * @param currentStep The index of the current post-processing + * step that will run, or equal to numberOfSteps if all of + * them has finished. This number is always strictly monotone + * increasing, although not necessarily linearly. + * */ + virtual void UpdateFileWrite(int currentStep /*= 0*/, int numberOfSteps /*= 0*/) { + float f = numberOfSteps ? currentStep / (float)numberOfSteps : 1.0f; + Update(f * 0.5f); + } +}; // !class ProgressHandler + +// ------------------------------------------------------------------------------------ + +} // Namespace Assimp + +#endif // AI_PROGRESSHANDLER_H_INC diff --git a/dependencies/includes/assimp/RemoveComments.h b/dependencies/includes/assimp/RemoveComments.h new file mode 100644 index 0000000..c2defff --- /dev/null +++ b/dependencies/includes/assimp/RemoveComments.h @@ -0,0 +1,93 @@ +/* +Open Asset Import Library (assimp) +---------------------------------------------------------------------- + +Copyright (c) 2006-2022, assimp team + +All rights reserved. + +Redistribution and use of this software in source and binary forms, +with or without modification, are permitted provided that the +following conditions are met: + +* Redistributions of source code must retain the above + copyright notice, this list of conditions and the + following disclaimer. + +* Redistributions in binary form must reproduce the above + copyright notice, this list of conditions and the + following disclaimer in the documentation and/or other + materials provided with the distribution. + +* Neither the name of the assimp team, nor the names of its + contributors may be used to endorse or promote products + derived from this software without specific prior + written permission of the assimp team. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +---------------------------------------------------------------------- +*/ + +/** @file Declares a helper class, "CommentRemover", which can be + * used to remove comments (single and multi line) from a text file. + */ +#pragma once +#ifndef AI_REMOVE_COMMENTS_H_INC +#define AI_REMOVE_COMMENTS_H_INC + +#ifdef __GNUC__ +# pragma GCC system_header +#endif + +#include + +namespace Assimp { + +// --------------------------------------------------------------------------- +/** \brief Helper class to remove single and multi line comments from a file + * + * Some mesh formats like MD5 have comments that are quite similar + * to those in C or C++ so this code has been moved to a separate + * module. + */ +class ASSIMP_API CommentRemover { + // class cannot be instanced + CommentRemover() {} + +public: + + //! Remove single-line comments. The end of a line is + //! expected to be either NL or CR or NLCR. + //! \param szComment The start sequence of the comment, e.g. "//" + //! \param szBuffer Buffer to work with + //! \param chReplacement Character to be used as replacement + //! for commented lines. By default this is ' ' + static void RemoveLineComments(const char* szComment, + char* szBuffer, char chReplacement = ' '); + + //! Remove multi-line comments. The end of a line is + //! expected to be either NL or CR or NLCR. Multi-line comments + //! may not be nested (as in C). + //! \param szCommentStart The start sequence of the comment, e.g. "/*" + //! \param szCommentEnd The end sequence of the comment, e.g. "*/" + //! \param szBuffer Buffer to work with + //! \param chReplacement Character to be used as replacement + //! for commented lines. By default this is ' ' + static void RemoveMultiLineComments(const char* szCommentStart, + const char* szCommentEnd,char* szBuffer, + char chReplacement = ' '); +}; +} // ! Assimp + +#endif // !! AI_REMOVE_COMMENTS_H_INC diff --git a/dependencies/includes/assimp/SGSpatialSort.h b/dependencies/includes/assimp/SGSpatialSort.h new file mode 100644 index 0000000..96feefa --- /dev/null +++ b/dependencies/includes/assimp/SGSpatialSort.h @@ -0,0 +1,155 @@ +/* +Open Asset Import Library (assimp) +---------------------------------------------------------------------- + +Copyright (c) 2006-2022, assimp team + + +All rights reserved. + +Redistribution and use of this software in source and binary forms, +with or without modification, are permitted provided that the +following conditions are met: + +* Redistributions of source code must retain the above + copyright notice, this list of conditions and the + following disclaimer. + +* Redistributions in binary form must reproduce the above + copyright notice, this list of conditions and the + following disclaimer in the documentation and/or other + materials provided with the distribution. + +* Neither the name of the assimp team, nor the names of its + contributors may be used to endorse or promote products + derived from this software without specific prior + written permission of the assimp team. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +---------------------------------------------------------------------- +*/ + +/** Small helper classes to optimize finding vertices close to a given location + */ +#pragma once +#ifndef AI_D3DSSPATIALSORT_H_INC +#define AI_D3DSSPATIALSORT_H_INC + +#ifdef __GNUC__ +# pragma GCC system_header +#endif + +#include +#include +#include + +namespace Assimp { + +// ---------------------------------------------------------------------------------- +/** Specialized version of SpatialSort to support smoothing groups + * This is used in by the 3DS, ASE and LWO loaders. 3DS and ASE share their + * normal computation code in SmoothingGroups.inl, the LWO loader has its own + * implementation to handle all details of its file format correctly. + */ +// ---------------------------------------------------------------------------------- +class ASSIMP_API SGSpatialSort +{ +public: + + SGSpatialSort(); + + // ------------------------------------------------------------------- + /** Construction from a given face array, handling smoothing groups + * properly + */ + explicit SGSpatialSort(const std::vector& vPositions); + + // ------------------------------------------------------------------- + /** Add a vertex to the spatial sort + * @param vPosition Vertex position to be added + * @param index Index of the vrtex + * @param smoothingGroup SmoothingGroup for this vertex + */ + void Add(const aiVector3D& vPosition, unsigned int index, + unsigned int smoothingGroup); + + // ------------------------------------------------------------------- + /** Prepare the spatial sorter for use. This step runs in O(logn) + */ + void Prepare(); + + /** Destructor */ + ~SGSpatialSort(); + + // ------------------------------------------------------------------- + /** Returns an iterator for all positions close to the given position. + * @param pPosition The position to look for vertices. + * @param pSG Only included vertices with at least one shared smooth group + * @param pRadius Maximal distance from the position a vertex may have + * to be counted in. + * @param poResults The container to store the indices of the found + * positions. Will be emptied by the call so it may contain anything. + * @param exactMatch Specifies whether smoothing groups are bit masks + * (false) or integral values (true). In the latter case, a vertex + * cannot belong to more than one smoothing group. + * @return An iterator to iterate over all vertices in the given area. + */ + // ------------------------------------------------------------------- + void FindPositions( const aiVector3D& pPosition, uint32_t pSG, + float pRadius, std::vector& poResults, + bool exactMatch = false) const; + +protected: + /** Normal of the sorting plane, normalized. The center is always at (0, 0, 0) */ + aiVector3D mPlaneNormal; + + // ------------------------------------------------------------------- + /** An entry in a spatially sorted position array. Consists of a + * vertex index, its position and its pre-calculated distance from + * the reference plane */ + // ------------------------------------------------------------------- + struct Entry { + unsigned int mIndex; ///< The vertex referred by this entry + aiVector3D mPosition; ///< Position + uint32_t mSmoothGroups; + float mDistance; ///< Distance of this vertex to the sorting plane + + Entry() AI_NO_EXCEPT + : mIndex(0) + , mPosition() + , mSmoothGroups(0) + , mDistance(0.0f) { + // empty + } + + Entry( unsigned int pIndex, const aiVector3D& pPosition, float pDistance,uint32_t pSG) + : mIndex( pIndex) + , mPosition( pPosition) + , mSmoothGroups(pSG) + , mDistance( pDistance) { + // empty + } + + bool operator < (const Entry& e) const { + return mDistance < e.mDistance; + } + }; + + // all positions, sorted by distance to the sorting plane + std::vector mPositions; +}; + +} // end of namespace Assimp + +#endif // AI_SPATIALSORT_H_INC diff --git a/dependencies/includes/assimp/SceneCombiner.h b/dependencies/includes/assimp/SceneCombiner.h new file mode 100644 index 0000000..6da38cd --- /dev/null +++ b/dependencies/includes/assimp/SceneCombiner.h @@ -0,0 +1,389 @@ +/* +Open Asset Import Library (assimp) +---------------------------------------------------------------------- + +Copyright (c) 2006-2022, assimp team + + +All rights reserved. + +Redistribution and use of this software in source and binary forms, +with or without modification, are permitted provided that the +following conditions are met: + +* Redistributions of source code must retain the above + copyright notice, this list of conditions and the + following disclaimer. + +* Redistributions in binary form must reproduce the above + copyright notice, this list of conditions and the + following disclaimer in the documentation and/or other + materials provided with the distribution. + +* Neither the name of the assimp team, nor the names of its + contributors may be used to endorse or promote products + derived from this software without specific prior + written permission of the assimp team. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +---------------------------------------------------------------------- +*/ + +/** @file Declares a helper class, "SceneCombiner" providing various + * utilities to merge scenes. + */ +#pragma once +#ifndef AI_SCENE_COMBINER_H_INC +#define AI_SCENE_COMBINER_H_INC + +#ifdef __GNUC__ +#pragma GCC system_header +#endif + +#include +#include + +#include +#include +#include +#include +#include + +struct aiScene; +struct aiNode; +struct aiMaterial; +struct aiTexture; +struct aiCamera; +struct aiLight; +struct aiMetadata; +struct aiBone; +struct aiMesh; +struct aiAnimMesh; +struct aiAnimation; +struct aiNodeAnim; +struct aiMeshMorphAnim; + +namespace Assimp { + +// --------------------------------------------------------------------------- +/** \brief Helper data structure for SceneCombiner. + * + * Describes to which node a scene must be attached to. + */ +struct AttachmentInfo { + AttachmentInfo() : + scene(nullptr), + attachToNode(nullptr) {} + + AttachmentInfo(aiScene *_scene, aiNode *_attachToNode) : + scene(_scene), attachToNode(_attachToNode) {} + + aiScene *scene; + aiNode *attachToNode; +}; + +// --------------------------------------------------------------------------- +struct NodeAttachmentInfo { + NodeAttachmentInfo() : + node(nullptr), + attachToNode(nullptr), + resolved(false), + src_idx(SIZE_MAX) {} + + NodeAttachmentInfo(aiNode *_scene, aiNode *_attachToNode, size_t idx) : + node(_scene), attachToNode(_attachToNode), resolved(false), src_idx(idx) {} + + aiNode *node; + aiNode *attachToNode; + bool resolved; + size_t src_idx; +}; + +// --------------------------------------------------------------------------- +/** @def AI_INT_MERGE_SCENE_GEN_UNIQUE_NAMES + * Generate unique names for all named scene items + */ +#define AI_INT_MERGE_SCENE_GEN_UNIQUE_NAMES 0x1 + +/** @def AI_INT_MERGE_SCENE_GEN_UNIQUE_MATNAMES + * Generate unique names for materials, too. + * This is not absolutely required to pass the validation. + */ +#define AI_INT_MERGE_SCENE_GEN_UNIQUE_MATNAMES 0x2 + +/** @def AI_INT_MERGE_SCENE_DUPLICATES_DEEP_CPY + * Use deep copies of duplicate scenes + */ +#define AI_INT_MERGE_SCENE_DUPLICATES_DEEP_CPY 0x4 + +/** @def AI_INT_MERGE_SCENE_RESOLVE_CROSS_ATTACHMENTS + * If attachment nodes are not found in the given master scene, + * search the other imported scenes for them in an any order. + */ +#define AI_INT_MERGE_SCENE_RESOLVE_CROSS_ATTACHMENTS 0x8 + +/** @def AI_INT_MERGE_SCENE_GEN_UNIQUE_NAMES_IF_NECESSARY + * Can be combined with AI_INT_MERGE_SCENE_GEN_UNIQUE_NAMES. + * Unique names are generated, but only if this is absolutely + * required to avoid name conflicts. + */ +#define AI_INT_MERGE_SCENE_GEN_UNIQUE_NAMES_IF_NECESSARY 0x10 + +typedef std::pair BoneSrcIndex; + +// --------------------------------------------------------------------------- +/** @brief Helper data structure for SceneCombiner::MergeBones. + */ +struct BoneWithHash : public std::pair { + std::vector pSrcBones; +}; + +// --------------------------------------------------------------------------- +/** @brief Utility for SceneCombiner + */ +struct SceneHelper { + SceneHelper() : + scene(nullptr), + idlen(0) { + id[0] = 0; + } + + explicit SceneHelper(aiScene *_scene) : + scene(_scene), idlen(0) { + id[0] = 0; + } + + AI_FORCE_INLINE aiScene *operator->() const { + return scene; + } + + // scene we're working on + aiScene *scene; + + // prefix to be added to all identifiers in the scene ... + char id[32]; + + // and its strlen() + unsigned int idlen; + + // hash table to quickly check whether a name is contained in the scene + std::set hashes; +}; + +// --------------------------------------------------------------------------- +/** \brief Static helper class providing various utilities to merge two + * scenes. It is intended as internal utility and NOT for use by + * applications. + * + * The class is currently being used by various postprocessing steps + * and loaders (ie. LWS). + */ +class ASSIMP_API SceneCombiner { + // class cannot be instanced + SceneCombiner() { + // empty + } + + ~SceneCombiner() { + // empty + } + +public: + // ------------------------------------------------------------------- + /** Merges two or more scenes. + * + * @param dest Receives a pointer to the destination scene. If the + * pointer doesn't point to nullptr when the function is called, the + * existing scene is cleared and refilled. + * @param src Non-empty list of scenes to be merged. The function + * deletes the input scenes afterwards. There may be duplicate scenes. + * @param flags Combination of the AI_INT_MERGE_SCENE flags defined above + */ + static void MergeScenes(aiScene **dest, std::vector &src, + unsigned int flags = 0); + + // ------------------------------------------------------------------- + /** Merges two or more scenes and attaches all scenes to a specific + * position in the node graph of the master scene. + * + * @param dest Receives a pointer to the destination scene. If the + * pointer doesn't point to nullptr when the function is called, the + * existing scene is cleared and refilled. + * @param master Master scene. It will be deleted afterwards. All + * other scenes will be inserted in its node graph. + * @param src Non-empty list of scenes to be merged along with their + * corresponding attachment points in the master scene. The function + * deletes the input scenes afterwards. There may be duplicate scenes. + * @param flags Combination of the AI_INT_MERGE_SCENE flags defined above + */ + static void MergeScenes(aiScene **dest, aiScene *master, + std::vector &src, + unsigned int flags = 0); + + // ------------------------------------------------------------------- + /** Merges two or more meshes + * + * The meshes should have equal vertex formats. Only components + * that are provided by ALL meshes will be present in the output mesh. + * An exception is made for VColors - they are set to black. The + * meshes should have the same material indices, too. The output + * material index is always the material index of the first mesh. + * + * @param dest Destination mesh. Must be empty. + * @param flags Currently no parameters + * @param begin First mesh to be processed + * @param end Points to the mesh after the last mesh to be processed + */ + static void MergeMeshes(aiMesh **dest, unsigned int flags, + std::vector::const_iterator begin, + std::vector::const_iterator end); + + // ------------------------------------------------------------------- + /** Merges two or more bones + * + * @param out Mesh to receive the output bone list + * @param flags Currently no parameters + * @param begin First mesh to be processed + * @param end Points to the mesh after the last mesh to be processed + */ + static void MergeBones(aiMesh *out, std::vector::const_iterator it, + std::vector::const_iterator end); + + // ------------------------------------------------------------------- + /** Merges two or more materials + * + * The materials should be complementary as much as possible. In case + * of a property present in different materials, the first occurrence + * is used. + * + * @param dest Destination material. Must be empty. + * @param begin First material to be processed + * @param end Points to the material after the last material to be processed + */ + static void MergeMaterials(aiMaterial **dest, + std::vector::const_iterator begin, + std::vector::const_iterator end); + + // ------------------------------------------------------------------- + /** Builds a list of uniquely named bones in a mesh list + * + * @param asBones Receives the output list + * @param it First mesh to be processed + * @param end Last mesh to be processed + */ + static void BuildUniqueBoneList(std::list &asBones, + std::vector::const_iterator it, + std::vector::const_iterator end); + + // ------------------------------------------------------------------- + /** Add a name prefix to all nodes in a scene. + * + * @param Current node. This function is called recursively. + * @param prefix Prefix to be added to all nodes + * @param len STring length + */ + static void AddNodePrefixes(aiNode *node, const char *prefix, + unsigned int len); + + // ------------------------------------------------------------------- + /** Add an offset to all mesh indices in a node graph + * + * @param Current node. This function is called recursively. + * @param offset Offset to be added to all mesh indices + */ + static void OffsetNodeMeshIndices(aiNode *node, unsigned int offset); + + // ------------------------------------------------------------------- + /** Attach a list of node graphs to well-defined nodes in a master + * graph. This is a helper for MergeScenes() + * + * @param master Master scene + * @param srcList List of source scenes along with their attachment + * points. If an attachment point is nullptr (or does not exist in + * the master graph), a scene is attached to the root of the master + * graph (as an additional child node) + * @duplicates List of duplicates. If elem[n] == n the scene is not + * a duplicate. Otherwise elem[n] links scene n to its first occurrence. + */ + static void AttachToGraph(aiScene *master, + std::vector &srcList); + + static void AttachToGraph(aiNode *attach, + std::vector &srcList); + + // ------------------------------------------------------------------- + /** Get a deep copy of a scene + * + * @param dest Receives a pointer to the destination scene + * @param src Source scene - remains unmodified. + */ + static void CopyScene(aiScene **dest, const aiScene *source, bool allocate = true); + + // ------------------------------------------------------------------- + /** Get a flat copy of a scene + * + * Only the first hierarchy layer is copied. All pointer members of + * aiScene are shared by source and destination scene. If the + * pointer doesn't point to nullptr when the function is called, the + * existing scene is cleared and refilled. + * @param dest Receives a pointer to the destination scene + * @param src Source scene - remains unmodified. + */ + static void CopySceneFlat(aiScene **dest, const aiScene *source); + + // ------------------------------------------------------------------- + /** Get a deep copy of a mesh + * + * @param dest Receives a pointer to the destination mesh + * @param src Source mesh - remains unmodified. + */ + static void Copy(aiMesh **dest, const aiMesh *src); + + // similar to Copy(): + static void Copy(aiAnimMesh **dest, const aiAnimMesh *src); + static void Copy(aiMaterial **dest, const aiMaterial *src); + static void Copy(aiTexture **dest, const aiTexture *src); + static void Copy(aiAnimation **dest, const aiAnimation *src); + static void Copy(aiCamera **dest, const aiCamera *src); + static void Copy(aiBone **dest, const aiBone *src); + static void Copy(aiLight **dest, const aiLight *src); + static void Copy(aiNodeAnim **dest, const aiNodeAnim *src); + static void Copy(aiMeshMorphAnim **dest, const aiMeshMorphAnim *src); + static void Copy(aiMetadata **dest, const aiMetadata *src); + static void Copy(aiString **dest, const aiString *src); + + // recursive, of course + static void Copy(aiNode **dest, const aiNode *src); + +private: + // ------------------------------------------------------------------- + // Same as AddNodePrefixes, but with an additional check + static void AddNodePrefixesChecked(aiNode *node, const char *prefix, + unsigned int len, + std::vector &input, + unsigned int cur); + + // ------------------------------------------------------------------- + // Add node identifiers to a hashing set + static void AddNodeHashes(aiNode *node, std::set &hashes); + + // ------------------------------------------------------------------- + // Search for duplicate names + static bool FindNameMatch(const aiString &name, + std::vector &input, unsigned int cur); +}; + +} // namespace Assimp + +#endif // !! AI_SCENE_COMBINER_H_INC diff --git a/dependencies/includes/assimp/SkeletonMeshBuilder.h b/dependencies/includes/assimp/SkeletonMeshBuilder.h new file mode 100644 index 0000000..2929aaa --- /dev/null +++ b/dependencies/includes/assimp/SkeletonMeshBuilder.h @@ -0,0 +1,128 @@ +/** Helper class to construct a dummy mesh for file formats containing only motion data */ + +/* +Open Asset Import Library (assimp) +---------------------------------------------------------------------- + +Copyright (c) 2006-2022, assimp team + +All rights reserved. + +Redistribution and use of this software in source and binary forms, +with or without modification, are permitted provided that the +following conditions are met: + +* Redistributions of source code must retain the above +copyright notice, this list of conditions and the +following disclaimer. + +* Redistributions in binary form must reproduce the above +copyright notice, this list of conditions and the +following disclaimer in the documentation and/or other +materials provided with the distribution. + +* Neither the name of the assimp team, nor the names of its +contributors may be used to endorse or promote products +derived from this software without specific prior +written permission of the assimp team. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +---------------------------------------------------------------------- +*/ + +/** @file SkeletonMeshBuilder.h + * Declares SkeletonMeshBuilder, a tiny utility to build dummy meshes + * for animation skeletons. + */ + +#pragma once +#ifndef AI_SKELETONMESHBUILDER_H_INC +#define AI_SKELETONMESHBUILDER_H_INC + +#ifdef __GNUC__ +#pragma GCC system_header +#endif + +#include +#include + +struct aiMaterial; +struct aiScene; +struct aiNode; + +namespace Assimp { + +// --------------------------------------------------------------------------- +/** + * This little helper class constructs a dummy mesh for a given scene + * the resembles the node hierarchy. This is useful for file formats + * that don't carry any mesh data but only animation data. + */ +class ASSIMP_API SkeletonMeshBuilder { +public: + // ------------------------------------------------------------------- + /** The constructor processes the given scene and adds a mesh there. + * + * Does nothing if the scene already has mesh data. + * @param pScene The scene for which a skeleton mesh should be constructed. + * @param root The node to start with. nullptr is the scene root + * @param bKnobsOnly Set this to true if you don't want the connectors + * between the knobs representing the nodes. + */ + SkeletonMeshBuilder(aiScene *pScene, aiNode *root = nullptr, + bool bKnobsOnly = false); + +protected: + // ------------------------------------------------------------------- + /** Recursively builds a simple mesh representation for the given node + * and also creates a joint for the node that affects this part of + * the mesh. + * @param pNode The node to build geometry for. + */ + void CreateGeometry(const aiNode *pNode); + + // ------------------------------------------------------------------- + /** Creates the mesh from the internally accumulated stuff and returns it. + */ + aiMesh *CreateMesh(); + + // ------------------------------------------------------------------- + /** Creates a dummy material and returns it. */ + aiMaterial *CreateMaterial(); + +private: + /** space to assemble the mesh data: points */ + std::vector mVertices; + + /** faces */ + struct Face { + unsigned int mIndices[3]; + Face(); + Face(unsigned int p0, unsigned int p1, unsigned int p2) { + mIndices[0] = p0; + mIndices[1] = p1; + mIndices[2] = p2; + } + }; + std::vector mFaces; + + /** bones */ + std::vector mBones; + + bool mKnobsOnly; +}; + +} // end of namespace Assimp + +#endif // AI_SKELETONMESHBUILDER_H_INC diff --git a/dependencies/includes/assimp/SmallVector.h b/dependencies/includes/assimp/SmallVector.h new file mode 100644 index 0000000..60ad264 --- /dev/null +++ b/dependencies/includes/assimp/SmallVector.h @@ -0,0 +1,164 @@ +/* +Open Asset Import Library (assimp) +---------------------------------------------------------------------- + +Copyright (c) 2006-2022, assimp team + +All rights reserved. + +Redistribution and use of this software in source and binary forms, +with or without modification, are permitted provided that the +following conditions are met: + +* Redistributions of source code must retain the above + copyright notice, this list of conditions and the + following disclaimer. + +* Redistributions in binary form must reproduce the above + copyright notice, this list of conditions and the + following disclaimer in the documentation and/or other + materials provided with the distribution. + +* Neither the name of the assimp team, nor the names of its + contributors may be used to endorse or promote products + derived from this software without specific prior + written permission of the assimp team. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +---------------------------------------------------------------------- +*/ + +/** @file Defines small vector with inplace storage. +Based on CppCon 2016: Chandler Carruth "High Performance Code 201: Hybrid Data Structures" */ + +#pragma once +#ifndef AI_SMALLVECTOR_H_INC +#define AI_SMALLVECTOR_H_INC + +#ifdef __GNUC__ +# pragma GCC system_header +#endif + +namespace Assimp { + +// -------------------------------------------------------------------------------------------- +/// @brief Small vector with inplace storage. +/// +/// Reduces heap allocations when list is shorter. It uses a small array for a dedicated size. +/// When the growing gets bigger than this small cache a dynamic growing algorithm will be +/// used. +// -------------------------------------------------------------------------------------------- +template +class SmallVector { +public: + /// @brief The default class constructor. + SmallVector() : + mStorage(mInplaceStorage), + mSize(0), + mCapacity(Capacity) { + // empty + } + + /// @brief The class destructor. + ~SmallVector() { + if (mStorage != mInplaceStorage) { + delete [] mStorage; + } + } + + /// @brief Will push a new item. The capacity will grow in case of a too small capacity. + /// @param item [in] The item to push at the end of the vector. + void push_back(const T& item) { + if (mSize < mCapacity) { + mStorage[mSize++] = item; + return; + } + + push_back_and_grow(item); + } + + /// @brief Will resize the vector. + /// @param newSize [in] The new size. + void resize(size_t newSize) { + if (newSize > mCapacity) { + grow(newSize); + } + mSize = newSize; + } + + /// @brief Returns the current size of the vector. + /// @return The current size. + size_t size() const { + return mSize; + } + + /// @brief Returns a pointer to the first item. + /// @return The first item as a pointer. + T* begin() { + return mStorage; + } + + /// @brief Returns a pointer to the end. + /// @return The end as a pointer. + T* end() { + return &mStorage[mSize]; + } + + /// @brief Returns a const pointer to the first item. + /// @return The first item as a const pointer. + T* begin() const { + return mStorage; + } + + /// @brief Returns a const pointer to the end. + /// @return The end as a const pointer. + T* end() const { + return &mStorage[mSize]; + } + + SmallVector(const SmallVector &) = delete; + SmallVector(SmallVector &&) = delete; + SmallVector &operator = (const SmallVector &) = delete; + SmallVector &operator = (SmallVector &&) = delete; + +private: + void grow( size_t newCapacity) { + T* oldStorage = mStorage; + T* newStorage = new T[newCapacity]; + + std::memcpy(newStorage, oldStorage, mSize * sizeof(T)); + + mStorage = newStorage; + mCapacity = newCapacity; + + if (oldStorage != mInplaceStorage) { + delete [] oldStorage; + } + } + + void push_back_and_grow(const T& item) { + grow(mCapacity + Capacity); + + mStorage[mSize++] = item; + } + + T* mStorage; + size_t mSize; + size_t mCapacity; + T mInplaceStorage[Capacity]; +}; + +} // end namespace Assimp + +#endif // !! AI_SMALLVECTOR_H_INC diff --git a/dependencies/includes/assimp/SmoothingGroups.h b/dependencies/includes/assimp/SmoothingGroups.h new file mode 100644 index 0000000..4625a29 --- /dev/null +++ b/dependencies/includes/assimp/SmoothingGroups.h @@ -0,0 +1,114 @@ +/* +Open Asset Import Library (assimp) +---------------------------------------------------------------------- + +Copyright (c) 2006-2022, assimp team + + +All rights reserved. + +Redistribution and use of this software in source and binary forms, +with or without modification, are permitted provided that the +following conditions are met: + +* Redistributions of source code must retain the above + copyright notice, this list of conditions and the + following disclaimer. + +* Redistributions in binary form must reproduce the above + copyright notice, this list of conditions and the + following disclaimer in the documentation and/or other + materials provided with the distribution. + +* Neither the name of the assimp team, nor the names of its + contributors may be used to endorse or promote products + derived from this software without specific prior + written permission of the assimp team. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +---------------------------------------------------------------------- +*/ + +/** @file Defines the helper data structures for importing 3DS files. +http://www.jalix.org/ressources/graphics/3DS/_unofficials/3ds-unofficial.txt */ + +#pragma once +#ifndef AI_SMOOTHINGGROUPS_H_INC +#define AI_SMOOTHINGGROUPS_H_INC + +#ifdef __GNUC__ +# pragma GCC system_header +#endif + +#include + +#include +#include + +// --------------------------------------------------------------------------- +/** Helper structure representing a face with smoothing groups assigned */ +struct FaceWithSmoothingGroup { + FaceWithSmoothingGroup() AI_NO_EXCEPT + : mIndices() + , iSmoothGroup(0) { + // in debug builds set all indices to a common magic value +#ifdef ASSIMP_BUILD_DEBUG + this->mIndices[0] = 0xffffffff; + this->mIndices[1] = 0xffffffff; + this->mIndices[2] = 0xffffffff; +#endif + } + + + //! Indices. .3ds is using uint16. However, after + //! an unique vertex set has been generated, + //! individual index values might exceed 2^16 + uint32_t mIndices[3]; + + //! specifies to which smoothing group the face belongs to + uint32_t iSmoothGroup; +}; + +// --------------------------------------------------------------------------- +/** Helper structure representing a mesh whose faces have smoothing + groups assigned. This allows us to reuse the code for normal computations + from smoothings groups for several loaders (3DS, ASE). All of them + use face structures which inherit from #FaceWithSmoothingGroup, + but as they add extra members and need to be copied by value we + need to use a template here. + */ +template +struct MeshWithSmoothingGroups +{ + //! Vertex positions + std::vector mPositions; + + //! Face lists + std::vector mFaces; + + //! List of normal vectors + std::vector mNormals; +}; + +// --------------------------------------------------------------------------- +/** Computes normal vectors for the mesh + */ +template +void ComputeNormalsWithSmoothingsGroups(MeshWithSmoothingGroups& sMesh); + + +// include implementations +#include "SmoothingGroups.inl" + +#endif // !! AI_SMOOTHINGGROUPS_H_INC diff --git a/dependencies/includes/assimp/SmoothingGroups.inl b/dependencies/includes/assimp/SmoothingGroups.inl new file mode 100644 index 0000000..d5fff5b --- /dev/null +++ b/dependencies/includes/assimp/SmoothingGroups.inl @@ -0,0 +1,141 @@ +/* +--------------------------------------------------------------------------- +Open Asset Import Library (assimp) +--------------------------------------------------------------------------- + +Copyright (c) 2006-2022, assimp team + +All rights reserved. + +Redistribution and use of this software in source and binary forms, +with or without modification, are permitted provided that the following +conditions are met: + +* Redistributions of source code must retain the above + copyright notice, this list of conditions and the + following disclaimer. + +* Redistributions in binary form must reproduce the above + copyright notice, this list of conditions and the + following disclaimer in the documentation and/or other + materials provided with the distribution. + +* Neither the name of the assimp team, nor the names of its + contributors may be used to endorse or promote products + derived from this software without specific prior + written permission of the assimp team. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +--------------------------------------------------------------------------- +*/ + +/** @file Generation of normal vectors basing on smoothing groups */ + +#pragma once +#ifndef AI_SMOOTHINGGROUPS_INL_INCLUDED +#define AI_SMOOTHINGGROUPS_INL_INCLUDED + +#ifdef __GNUC__ +# pragma GCC system_header +#endif + +#include + +#include + +using namespace Assimp; + +// ------------------------------------------------------------------------------------------------ +template +void ComputeNormalsWithSmoothingsGroups(MeshWithSmoothingGroups& sMesh) +{ + // First generate face normals + sMesh.mNormals.resize(sMesh.mPositions.size(),aiVector3D()); + for( unsigned int a = 0; a < sMesh.mFaces.size(); a++) + { + T& face = sMesh.mFaces[a]; + + aiVector3D* pV1 = &sMesh.mPositions[face.mIndices[0]]; + aiVector3D* pV2 = &sMesh.mPositions[face.mIndices[1]]; + aiVector3D* pV3 = &sMesh.mPositions[face.mIndices[2]]; + + aiVector3D pDelta1 = *pV2 - *pV1; + aiVector3D pDelta2 = *pV3 - *pV1; + aiVector3D vNor = pDelta1 ^ pDelta2; + + for (unsigned int c = 0; c < 3;++c) + sMesh.mNormals[face.mIndices[c]] = vNor; + } + + // calculate the position bounds so we have a reliable epsilon to check position differences against + aiVector3D minVec( 1e10f, 1e10f, 1e10f), maxVec( -1e10f, -1e10f, -1e10f); + for( unsigned int a = 0; a < sMesh.mPositions.size(); a++) + { + minVec.x = std::min( minVec.x, sMesh.mPositions[a].x); + minVec.y = std::min( minVec.y, sMesh.mPositions[a].y); + minVec.z = std::min( minVec.z, sMesh.mPositions[a].z); + maxVec.x = std::max( maxVec.x, sMesh.mPositions[a].x); + maxVec.y = std::max( maxVec.y, sMesh.mPositions[a].y); + maxVec.z = std::max( maxVec.z, sMesh.mPositions[a].z); + } + const float posEpsilon = (maxVec - minVec).Length() * 1e-5f; + std::vector avNormals; + avNormals.resize(sMesh.mNormals.size()); + + // now generate the spatial sort tree + SGSpatialSort sSort; + for( typename std::vector::iterator i = sMesh.mFaces.begin(); + i != sMesh.mFaces.end();++i) + { + for (unsigned int c = 0; c < 3;++c) + sSort.Add(sMesh.mPositions[(*i).mIndices[c]],(*i).mIndices[c],(*i).iSmoothGroup); + } + sSort.Prepare(); + + std::vector vertexDone(sMesh.mPositions.size(),false); + for( typename std::vector::iterator i = sMesh.mFaces.begin(); + i != sMesh.mFaces.end();++i) + { + std::vector poResult; + for (unsigned int c = 0; c < 3;++c) + { + unsigned int idx = (*i).mIndices[c]; + if (vertexDone[idx])continue; + + sSort.FindPositions(sMesh.mPositions[idx],(*i).iSmoothGroup, + posEpsilon,poResult); + + aiVector3D vNormals; + for (std::vector::const_iterator + a = poResult.begin(); + a != poResult.end();++a) + { + vNormals += sMesh.mNormals[(*a)]; + } + vNormals.NormalizeSafe(); + + // write back into all affected normals + for (std::vector::const_iterator + a = poResult.begin(); + a != poResult.end();++a) + { + idx = *a; + avNormals [idx] = vNormals; + vertexDone[idx] = true; + } + } + } + sMesh.mNormals = avNormals; +} + +#endif // !! AI_SMOOTHINGGROUPS_INL_INCLUDED diff --git a/dependencies/includes/assimp/SpatialSort.h b/dependencies/includes/assimp/SpatialSort.h new file mode 100644 index 0000000..87b009d --- /dev/null +++ b/dependencies/includes/assimp/SpatialSort.h @@ -0,0 +1,190 @@ +/* +Open Asset Import Library (assimp) +---------------------------------------------------------------------- + +Copyright (c) 2006-2022, assimp team + + +All rights reserved. + +Redistribution and use of this software in source and binary forms, +with or without modification, are permitted provided that the +following conditions are met: + +* Redistributions of source code must retain the above + copyright notice, this list of conditions and the + following disclaimer. + +* Redistributions in binary form must reproduce the above + copyright notice, this list of conditions and the + following disclaimer in the documentation and/or other + materials provided with the distribution. + +* Neither the name of the assimp team, nor the names of its + contributors may be used to endorse or promote products + derived from this software without specific prior + written permission of the assimp team. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +---------------------------------------------------------------------- +*/ + +/** Small helper classes to optimise finding vertizes close to a given location */ +#pragma once +#ifndef AI_SPATIALSORT_H_INC +#define AI_SPATIALSORT_H_INC + +#ifdef __GNUC__ +#pragma GCC system_header +#endif + +#include +#include +#include + +namespace Assimp { + +// ------------------------------------------------------------------------------------------------ +/** A little helper class to quickly find all vertices in the epsilon environment of a given + * position. Construct an instance with an array of positions. The class stores the given positions + * by their indices and sorts them by their distance to an arbitrary chosen plane. + * You can then query the instance for all vertices close to a given position in an average O(log n) + * time, with O(n) worst case complexity when all vertices lay on the plane. The plane is chosen + * so that it avoids common planes in usual data sets. */ +// ------------------------------------------------------------------------------------------------ +class ASSIMP_API SpatialSort { +public: + SpatialSort(); + + // ------------------------------------------------------------------------------------ + /** Constructs a spatially sorted representation from the given position array. + * Supply the positions in its layout in memory, the class will only refer to them + * by index. + * @param pPositions Pointer to the first position vector of the array. + * @param pNumPositions Number of vectors to expect in that array. + * @param pElementOffset Offset in bytes from the beginning of one vector in memory + * to the beginning of the next vector. */ + SpatialSort(const aiVector3D *pPositions, unsigned int pNumPositions, + unsigned int pElementOffset); + + /** Destructor */ + ~SpatialSort(); + + // ------------------------------------------------------------------------------------ + /** Sets the input data for the SpatialSort. This replaces existing data, if any. + * The new data receives new indices in ascending order. + * + * @param pPositions Pointer to the first position vector of the array. + * @param pNumPositions Number of vectors to expect in that array. + * @param pElementOffset Offset in bytes from the beginning of one vector in memory + * to the beginning of the next vector. + * @param pFinalize Specifies whether the SpatialSort's internal representation + * is finalized after the new data has been added. Finalization is + * required in order to use #FindPosition() or #GenerateMappingTable(). + * If you don't finalize yet, you can use #Append() to add data from + * other sources.*/ + void Fill(const aiVector3D *pPositions, unsigned int pNumPositions, + unsigned int pElementOffset, + bool pFinalize = true); + + // ------------------------------------------------------------------------------------ + /** Same as #Fill(), except the method appends to existing data in the #SpatialSort. */ + void Append(const aiVector3D *pPositions, unsigned int pNumPositions, + unsigned int pElementOffset, + bool pFinalize = true); + + // ------------------------------------------------------------------------------------ + /** Finalize the spatial hash data structure. This can be useful after + * multiple calls to #Append() with the pFinalize parameter set to false. + * This is finally required before one of #FindPositions() and #GenerateMappingTable() + * can be called to query the spatial sort.*/ + void Finalize(); + + // ------------------------------------------------------------------------------------ + /** Returns an iterator for all positions close to the given position. + * @param pPosition The position to look for vertices. + * @param pRadius Maximal distance from the position a vertex may have to be counted in. + * @param poResults The container to store the indices of the found positions. + * Will be emptied by the call so it may contain anything. + * @return An iterator to iterate over all vertices in the given area.*/ + void FindPositions(const aiVector3D &pPosition, ai_real pRadius, + std::vector &poResults) const; + + // ------------------------------------------------------------------------------------ + /** Fills an array with indices of all positions identical to the given position. In + * opposite to FindPositions(), not an epsilon is used but a (very low) tolerance of + * four floating-point units. + * @param pPosition The position to look for vertices. + * @param poResults The container to store the indices of the found positions. + * Will be emptied by the call so it may contain anything.*/ + void FindIdenticalPositions(const aiVector3D &pPosition, + std::vector &poResults) const; + + // ------------------------------------------------------------------------------------ + /** Compute a table that maps each vertex ID referring to a spatially close + * enough position to the same output ID. Output IDs are assigned in ascending order + * from 0...n. + * @param fill Will be filled with numPositions entries. + * @param pRadius Maximal distance from the position a vertex may have to + * be counted in. + * @return Number of unique vertices (n). */ + unsigned int GenerateMappingTable(std::vector &fill, + ai_real pRadius) const; + +protected: + /** Return the distance to the sorting plane. */ + ai_real CalculateDistance(const aiVector3D &pPosition) const; + +protected: + /** Normal of the sorting plane, normalized. + */ + aiVector3D mPlaneNormal; + + /** The centroid of the positions, which is used as a point on the sorting plane + * when calculating distance. This value is calculated in Finalize. + */ + aiVector3D mCentroid; + + /** An entry in a spatially sorted position array. Consists of a vertex index, + * its position and its pre-calculated distance from the reference plane */ + struct Entry { + unsigned int mIndex; ///< The vertex referred by this entry + aiVector3D mPosition; ///< Position + /// Distance of this vertex to the sorting plane. This is set by Finalize. + ai_real mDistance; + + Entry() AI_NO_EXCEPT + : mIndex(std::numeric_limits::max()), + mPosition(), + mDistance(std::numeric_limits::max()) { + // empty + } + Entry(unsigned int pIndex, const aiVector3D &pPosition) : + mIndex(pIndex), mPosition(pPosition), mDistance(std::numeric_limits::max()) { + // empty + } + + bool operator<(const Entry &e) const { return mDistance < e.mDistance; } + }; + + // all positions, sorted by distance to the sorting plane + std::vector mPositions; + + /// false until the Finalize method is called. + bool mFinalized; +}; + +} // end of namespace Assimp + +#endif // AI_SPATIALSORT_H_INC diff --git a/dependencies/includes/assimp/StandardShapes.h b/dependencies/includes/assimp/StandardShapes.h new file mode 100644 index 0000000..77880cf --- /dev/null +++ b/dependencies/includes/assimp/StandardShapes.h @@ -0,0 +1,206 @@ +/* +Open Asset Import Library (assimp) +---------------------------------------------------------------------- + +Copyright (c) 2006-2022, assimp team + + +All rights reserved. + +Redistribution and use of this software in source and binary forms, +with or without modification, are permitted provided that the +following conditions are met: + +* Redistributions of source code must retain the above + copyright notice, this list of conditions and the + following disclaimer. + +* Redistributions in binary form must reproduce the above + copyright notice, this list of conditions and the + following disclaimer in the documentation and/or other + materials provided with the distribution. + +* Neither the name of the assimp team, nor the names of its + contributors may be used to endorse or promote products + derived from this software without specific prior + written permission of the assimp team. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +---------------------------------------------------------------------- +*/ + +/** @file Declares a helper class, "StandardShapes" which generates + * vertices for standard shapes, such as cylinders, cones, spheres .. + */ +#pragma once +#ifndef AI_STANDARD_SHAPES_H_INC +#define AI_STANDARD_SHAPES_H_INC + +#ifdef __GNUC__ +# pragma GCC system_header +#endif + +#include +#include +#include + +struct aiMesh; + +namespace Assimp { + +// --------------------------------------------------------------------------- +/** \brief Helper class to generate vertex buffers for standard geometric + * shapes, such as cylinders, cones, boxes, spheres, elipsoids ... . + */ +class ASSIMP_API StandardShapes +{ + // class cannot be instanced + StandardShapes() {} + +public: + + + // ---------------------------------------------------------------- + /** Generates a mesh from an array of vertex positions. + * + * @param positions List of vertex positions + * @param numIndices Number of indices per primitive + * @return Output mesh + */ + static aiMesh* MakeMesh(const std::vector& positions, + unsigned int numIndices); + + + static aiMesh* MakeMesh ( unsigned int (*GenerateFunc) + (std::vector&)); + + static aiMesh* MakeMesh ( unsigned int (*GenerateFunc) + (std::vector&, bool)); + + static aiMesh* MakeMesh ( unsigned int n, void (*GenerateFunc) + (unsigned int,std::vector&)); + + // ---------------------------------------------------------------- + /** @brief Generates a hexahedron (cube) + * + * Hexahedrons can be scaled on all axes. + * @param positions Receives output triangles. + * @param polygons If you pass true here quads will be returned + * @return Number of vertices per face + */ + static unsigned int MakeHexahedron( + std::vector& positions, + bool polygons = false); + + // ---------------------------------------------------------------- + /** @brief Generates an icosahedron + * + * @param positions Receives output triangles. + * @return Number of vertices per face + */ + static unsigned int MakeIcosahedron( + std::vector& positions); + + + // ---------------------------------------------------------------- + /** @brief Generates a dodecahedron + * + * @param positions Receives output triangles + * @param polygons If you pass true here pentagons will be returned + * @return Number of vertices per face + */ + static unsigned int MakeDodecahedron( + std::vector& positions, + bool polygons = false); + + + // ---------------------------------------------------------------- + /** @brief Generates an octahedron + * + * @param positions Receives output triangles. + * @return Number of vertices per face + */ + static unsigned int MakeOctahedron( + std::vector& positions); + + + // ---------------------------------------------------------------- + /** @brief Generates a tetrahedron + * + * @param positions Receives output triangles. + * @return Number of vertices per face + */ + static unsigned int MakeTetrahedron( + std::vector& positions); + + + + // ---------------------------------------------------------------- + /** @brief Generates a sphere + * + * @param tess Number of subdivions - 0 generates a octahedron + * @param positions Receives output triangles. + */ + static void MakeSphere(unsigned int tess, + std::vector& positions); + + + // ---------------------------------------------------------------- + /** @brief Generates a cone or a cylinder, either open or closed. + * + * @code + * + * |-----| <- radius 1 + * + * __x__ <- ] ^ + * / \ | height | + * / \ | Y + * / \ | + * / \ | + * /______x______\ <- ] <- end cap + * + * |-------------| <- radius 2 + * + * @endcode + * + * @param height Height of the cone + * @param radius1 First radius + * @param radius2 Second radius + * @param tess Number of triangles. + * @param bOpened true for an open cone/cylinder. An open shape has + * no 'end caps' + * @param positions Receives output triangles + */ + static void MakeCone(ai_real height,ai_real radius1, + ai_real radius2,unsigned int tess, + std::vector& positions,bool bOpen= false); + + + // ---------------------------------------------------------------- + /** @brief Generates a flat circle + * + * The circle is constructed in the planned formed by the x,z + * axes of the cartesian coordinate system. + * + * @param radius Radius of the circle + * @param tess Number of segments. + * @param positions Receives output triangles. + */ + static void MakeCircle(ai_real radius, unsigned int tess, + std::vector& positions); + +}; +} // ! Assimp + +#endif // !! AI_STANDARD_SHAPES_H_INC diff --git a/dependencies/includes/assimp/StreamReader.h b/dependencies/includes/assimp/StreamReader.h new file mode 100644 index 0000000..44b24a3 --- /dev/null +++ b/dependencies/includes/assimp/StreamReader.h @@ -0,0 +1,344 @@ +/* +--------------------------------------------------------------------------- +Open Asset Import Library (assimp) +--------------------------------------------------------------------------- + +Copyright (c) 2006-2022, assimp team + +All rights reserved. + +Redistribution and use of this software in source and binary forms, +with or without modification, are permitted provided that the following +conditions are met: + +* Redistributions of source code must retain the above + copyright notice, this list of conditions and the + following disclaimer. + +* Redistributions in binary form must reproduce the above + copyright notice, this list of conditions and the + following disclaimer in the documentation and/or other + materials provided with the distribution. + +* Neither the name of the assimp team, nor the names of its + contributors may be used to endorse or promote products + derived from this software without specific prior + written permission of the assimp team. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +--------------------------------------------------------------------------- +*/ + +/** @file Defines the StreamReader class which reads data from + * a binary stream with a well-defined endianness. + */ +#pragma once +#ifndef AI_STREAMREADER_H_INCLUDED +#define AI_STREAMREADER_H_INCLUDED + +#ifdef __GNUC__ +# pragma GCC system_header +#endif + +#include +#include +#include + +#include + +namespace Assimp { + +// -------------------------------------------------------------------------------------------- +/** Wrapper class around IOStream to allow for consistent reading of binary data in both + * little and big endian format. Don't attempt to instance the template directly. Use + * StreamReaderLE to read from a little-endian stream and StreamReaderBE to read from a + * BE stream. The class expects that the endianness of any input data is known at + * compile-time, which should usually be true (#BaseImporter::ConvertToUTF8 implements + * runtime endianness conversions for text files). + * + * XXX switch from unsigned int for size types to size_t? or ptrdiff_t?*/ +// -------------------------------------------------------------------------------------------- +template +class StreamReader { +public: + using diff = size_t; + using pos = size_t; + + // --------------------------------------------------------------------- + /** Construction from a given stream with a well-defined endianness. + * + * The StreamReader holds a permanent strong reference to the + * stream, which is released upon destruction. + * @param stream Input stream. The stream is not restarted if + * its file pointer is not at 0. Instead, the stream reader + * reads from the current position to the end of the stream. + * @param le If @c RuntimeSwitch is true: specifies whether the + * stream is in little endian byte order. Otherwise the + * endianness information is contained in the @c SwapEndianess + * template parameter and this parameter is meaningless. */ + StreamReader(std::shared_ptr stream, bool le = false) : + mStream(stream), + mBuffer(nullptr), + mCurrent(nullptr), + mEnd(nullptr), + mLimit(nullptr), + mLe(le) { + ai_assert(stream); + InternBegin(); + } + + // --------------------------------------------------------------------- + StreamReader(IOStream *stream, bool le = false) : + mStream(std::shared_ptr(stream)), + mBuffer(nullptr), + mCurrent(nullptr), + mEnd(nullptr), + mLimit(nullptr), + mLe(le) { + ai_assert(nullptr != stream); + InternBegin(); + } + + // --------------------------------------------------------------------- + ~StreamReader() { + delete[] mBuffer; + } + + // deprecated, use overloaded operator>> instead + + // --------------------------------------------------------------------- + /// Read a float from the stream. + float GetF4() { + return Get(); + } + + // --------------------------------------------------------------------- + /// Read a double from the stream. + double GetF8() { + return Get(); + } + + // --------------------------------------------------------------------- + /** Read a signed 16 bit integer from the stream */ + int16_t GetI2() { + return Get(); + } + + // --------------------------------------------------------------------- + /** Read a signed 8 bit integer from the stream */ + int8_t GetI1() { + return Get(); + } + + // --------------------------------------------------------------------- + /** Read an signed 32 bit integer from the stream */ + int32_t GetI4() { + return Get(); + } + + // --------------------------------------------------------------------- + /** Read a signed 64 bit integer from the stream */ + int64_t GetI8() { + return Get(); + } + + // --------------------------------------------------------------------- + /** Read a unsigned 16 bit integer from the stream */ + uint16_t GetU2() { + return Get(); + } + + // --------------------------------------------------------------------- + /// Read a unsigned 8 bit integer from the stream + uint8_t GetU1() { + return Get(); + } + + // --------------------------------------------------------------------- + /// Read an unsigned 32 bit integer from the stream + uint32_t GetU4() { + return Get(); + } + + // --------------------------------------------------------------------- + /// Read a unsigned 64 bit integer from the stream + uint64_t GetU8() { + return Get(); + } + + // --------------------------------------------------------------------- + /// Get the remaining stream size (to the end of the stream) + size_t GetRemainingSize() const { + return (unsigned int)(mEnd - mCurrent); + } + + // --------------------------------------------------------------------- + /** Get the remaining stream size (to the current read limit). The + * return value is the remaining size of the stream if no custom + * read limit has been set. */ + size_t GetRemainingSizeToLimit() const { + return (unsigned int)(mLimit - mCurrent); + } + + // --------------------------------------------------------------------- + /** Increase the file pointer (relative seeking) */ + void IncPtr(intptr_t plus) { + mCurrent += plus; + if (mCurrent > mLimit) { + throw DeadlyImportError("End of file or read limit was reached"); + } + } + + // --------------------------------------------------------------------- + /** Get the current file pointer */ + int8_t *GetPtr() const { + return mCurrent; + } + + // --------------------------------------------------------------------- + /** Set current file pointer (Get it from #GetPtr). This is if you + * prefer to do pointer arithmetic on your own or want to copy + * large chunks of data at once. + * @param p The new pointer, which is validated against the size + * limit and buffer boundaries. */ + void SetPtr(int8_t *p) { + mCurrent = p; + if (mCurrent > mLimit || mCurrent < mBuffer) { + throw DeadlyImportError("End of file or read limit was reached"); + } + } + + // --------------------------------------------------------------------- + /** Copy n bytes to an external buffer + * @param out Destination for copying + * @param bytes Number of bytes to copy */ + void CopyAndAdvance(void *out, size_t bytes) { + int8_t *ur = GetPtr(); + SetPtr(ur + bytes); // fire exception if eof + + ::memcpy(out, ur, bytes); + } + + /// @brief Get the current offset from the beginning of the file + int GetCurrentPos() const { + return (unsigned int)(mCurrent - mBuffer); + } + + void SetCurrentPos(size_t pos) { + SetPtr(mBuffer + pos); + } + + // --------------------------------------------------------------------- + /** Setup a temporary read limit + * + * @param limit Maximum number of bytes to be read from + * the beginning of the file. Specifying UINT_MAX + * resets the limit to the original end of the stream. + * Returns the previously set limit. */ + unsigned int SetReadLimit(unsigned int _limit) { + unsigned int prev = GetReadLimit(); + if (UINT_MAX == _limit) { + mLimit = mEnd; + return prev; + } + + mLimit = mBuffer + _limit; + if (mLimit > mEnd) { + throw DeadlyImportError("StreamReader: Invalid read limit"); + } + return prev; + } + + // --------------------------------------------------------------------- + /** Get the current read limit in bytes. Reading over this limit + * accidentally raises an exception. */ + unsigned int GetReadLimit() const { + return (unsigned int)(mLimit - mBuffer); + } + + // --------------------------------------------------------------------- + /** Skip to the read limit in bytes. Reading over this limit + * accidentally raises an exception. */ + void SkipToReadLimit() { + mCurrent = mLimit; + } + + // --------------------------------------------------------------------- + /** overload operator>> and allow chaining of >> ops. */ + template + StreamReader &operator>>(T &f) { + f = Get(); + return *this; + } + + // --------------------------------------------------------------------- + /** Generic read method. ByteSwap::Swap(T*) *must* be defined */ + template + T Get() { + if (mCurrent + sizeof(T) > mLimit) { + throw DeadlyImportError("End of file or stream limit was reached"); + } + + T f; + ::memcpy(&f, mCurrent, sizeof(T)); + Intern::Getter()(&f, mLe); + mCurrent += sizeof(T); + + return f; + } + +private: + // --------------------------------------------------------------------- + void InternBegin() { + if (nullptr == mStream) { + throw DeadlyImportError("StreamReader: Unable to open file"); + } + + const size_t filesize = mStream->FileSize() - mStream->Tell(); + if (0 == filesize) { + throw DeadlyImportError("StreamReader: File is empty or EOF is already reached"); + } + + mCurrent = mBuffer = new int8_t[filesize]; + const size_t read = mStream->Read(mCurrent, 1, filesize); + // (read < s) can only happen if the stream was opened in text mode, in which case FileSize() is not reliable + ai_assert(read <= filesize); + mEnd = mLimit = &mBuffer[read - 1] + 1; + } + +private: + std::shared_ptr mStream; + int8_t *mBuffer; + int8_t *mCurrent; + int8_t *mEnd; + int8_t *mLimit; + bool mLe; +}; + +// -------------------------------------------------------------------------------------------- +// `static` StreamReaders. Their byte order is fixed and they might be a little bit faster. +#ifdef AI_BUILD_BIG_ENDIAN +typedef StreamReader StreamReaderLE; +typedef StreamReader StreamReaderBE; +#else +typedef StreamReader StreamReaderBE; +typedef StreamReader StreamReaderLE; +#endif + +// `dynamic` StreamReader. The byte order of the input data is specified in the +// c'tor. This involves runtime branching and might be a little bit slower. +typedef StreamReader StreamReaderAny; + +} // end namespace Assimp + +#endif // !! AI_STREAMREADER_H_INCLUDED diff --git a/dependencies/includes/assimp/StreamWriter.h b/dependencies/includes/assimp/StreamWriter.h new file mode 100644 index 0000000..1bdfcc6 --- /dev/null +++ b/dependencies/includes/assimp/StreamWriter.h @@ -0,0 +1,307 @@ +/* +--------------------------------------------------------------------------- +Open Asset Import Library (assimp) +--------------------------------------------------------------------------- + +Copyright (c) 2006-2022, assimp team + + + +All rights reserved. + +Redistribution and use of this software in source and binary forms, +with or without modification, are permitted provided that the following +conditions are met: + +* Redistributions of source code must retain the above + copyright notice, this list of conditions and the + following disclaimer. + +* Redistributions in binary form must reproduce the above + copyright notice, this list of conditions and the + following disclaimer in the documentation and/or other + materials provided with the distribution. + +* Neither the name of the assimp team, nor the names of its + contributors may be used to endorse or promote products + derived from this software without specific prior + written permission of the assimp team. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +--------------------------------------------------------------------------- +*/ + +/** @file Defines the StreamWriter class which writes data to + * a binary stream with a well-defined endianness. */ +#pragma once +#ifndef AI_STREAMWRITER_H_INCLUDED +#define AI_STREAMWRITER_H_INCLUDED + +#ifdef __GNUC__ +# pragma GCC system_header +#endif + +#include +#include + +#include +#include + +namespace Assimp { + +// -------------------------------------------------------------------------------------------- +/** Wrapper class around IOStream to allow for consistent writing of binary data in both + * little and big endian format. Don't attempt to instance the template directly. Use + * StreamWriterLE to write to a little-endian stream and StreamWriterBE to write to a + * BE stream. Alternatively, there is StreamWriterAny if the endianness of the output + * stream is to be determined at runtime. + */ +// -------------------------------------------------------------------------------------------- +template +class StreamWriter +{ + enum { + INITIAL_CAPACITY = 1024 + }; + +public: + + // --------------------------------------------------------------------- + /** Construction from a given stream with a well-defined endianness. + * + * The StreamReader holds a permanent strong reference to the + * stream, which is released upon destruction. + * @param stream Input stream. The stream is not re-seeked and writing + continues at the current position of the stream cursor. + * @param le If @c RuntimeSwitch is true: specifies whether the + * stream is in little endian byte order. Otherwise the + * endianness information is defined by the @c SwapEndianess + * template parameter and this parameter is meaningless. */ + StreamWriter(std::shared_ptr stream, bool le = false) + : stream(stream) + , le(le) + , cursor() + { + ai_assert(stream); + buffer.reserve(INITIAL_CAPACITY); + } + + // --------------------------------------------------------------------- + StreamWriter(IOStream* stream, bool le = false) + : stream(std::shared_ptr(stream)) + , le(le) + , cursor() + { + ai_assert(stream); + buffer.reserve(INITIAL_CAPACITY); + } + + // --------------------------------------------------------------------- + ~StreamWriter() { + stream->Write(buffer.data(), 1, buffer.size()); + stream->Flush(); + } + +public: + + // --------------------------------------------------------------------- + /** Flush the contents of the internal buffer, and the output IOStream */ + void Flush() + { + stream->Write(buffer.data(), 1, buffer.size()); + stream->Flush(); + buffer.clear(); + cursor = 0; + } + + // --------------------------------------------------------------------- + /** Seek to the given offset / origin in the output IOStream. + * + * Flushes the internal buffer and the output IOStream prior to seeking. */ + aiReturn Seek(size_t pOffset, aiOrigin pOrigin=aiOrigin_SET) + { + Flush(); + return stream->Seek(pOffset, pOrigin); + } + + // --------------------------------------------------------------------- + /** Tell the current position in the output IOStream. + * + * First flushes the internal buffer and the output IOStream. */ + size_t Tell() + { + Flush(); + return stream->Tell(); + } + +public: + + // --------------------------------------------------------------------- + /** Write a float to the stream */ + void PutF4(float f) + { + Put(f); + } + + // --------------------------------------------------------------------- + /** Write a double to the stream */ + void PutF8(double d) { + Put(d); + } + + // --------------------------------------------------------------------- + /** Write a signed 16 bit integer to the stream */ + void PutI2(int16_t n) { + Put(n); + } + + // --------------------------------------------------------------------- + /** Write a signed 8 bit integer to the stream */ + void PutI1(int8_t n) { + Put(n); + } + + // --------------------------------------------------------------------- + /** Write an signed 32 bit integer to the stream */ + void PutI4(int32_t n) { + Put(n); + } + + // --------------------------------------------------------------------- + /** Write a signed 64 bit integer to the stream */ + void PutI8(int64_t n) { + Put(n); + } + + // --------------------------------------------------------------------- + /** Write a unsigned 16 bit integer to the stream */ + void PutU2(uint16_t n) { + Put(n); + } + + // --------------------------------------------------------------------- + /** Write a unsigned 8 bit integer to the stream */ + void PutU1(uint8_t n) { + Put(n); + } + + // --------------------------------------------------------------------- + /** Write an unsigned 32 bit integer to the stream */ + void PutU4(uint32_t n) { + Put(n); + } + + // --------------------------------------------------------------------- + /** Write a unsigned 64 bit integer to the stream */ + void PutU8(uint64_t n) { + Put(n); + } + + // --------------------------------------------------------------------- + /** Write a single character to the stream */ + void PutChar(char c) { + Put(c); + } + + // --------------------------------------------------------------------- + /** Write an aiString to the stream */ + void PutString(const aiString& s) + { + // as Put(T f) below + if (cursor + s.length >= buffer.size()) { + buffer.resize(cursor + s.length); + } + void* dest = &buffer[cursor]; + ::memcpy(dest, s.C_Str(), s.length); + cursor += s.length; + } + + // --------------------------------------------------------------------- + /** Write a std::string to the stream */ + void PutString(const std::string& s) + { + // as Put(T f) below + if (cursor + s.size() >= buffer.size()) { + buffer.resize(cursor + s.size()); + } + void* dest = &buffer[cursor]; + ::memcpy(dest, s.c_str(), s.size()); + cursor += s.size(); + } + +public: + + // --------------------------------------------------------------------- + /** overload operator<< and allow chaining of MM ops. */ + template + StreamWriter& operator << (T f) { + Put(f); + return *this; + } + + // --------------------------------------------------------------------- + std::size_t GetCurrentPos() const { + return cursor; + } + + // --------------------------------------------------------------------- + void SetCurrentPos(std::size_t new_cursor) { + cursor = new_cursor; + } + + // --------------------------------------------------------------------- + /** Generic write method. ByteSwap::Swap(T*) *must* be defined */ + template + void Put(T f) { + Intern :: Getter() (&f, le); + + if (cursor + sizeof(T) >= buffer.size()) { + buffer.resize(cursor + sizeof(T)); + } + + void* dest = &buffer[cursor]; + + // reinterpret_cast + assignment breaks strict aliasing rules + // and generally causes trouble on platforms such as ARM that + // do not silently ignore alignment faults. + ::memcpy(dest, &f, sizeof(T)); + cursor += sizeof(T); + } + +private: + + std::shared_ptr stream; + bool le; + + std::vector buffer; + std::size_t cursor; +}; + + +// -------------------------------------------------------------------------------------------- +// `static` StreamWriter. Their byte order is fixed and they might be a little bit faster. +#ifdef AI_BUILD_BIG_ENDIAN + typedef StreamWriter StreamWriterLE; + typedef StreamWriter StreamWriterBE; +#else + typedef StreamWriter StreamWriterBE; + typedef StreamWriter StreamWriterLE; +#endif + +// `dynamic` StreamWriter. The byte order of the input data is specified in the +// c'tor. This involves runtime branching and might be a little bit slower. +typedef StreamWriter StreamWriterAny; + +} // end namespace Assimp + +#endif // !! AI_STREAMWriter_H_INCLUDED diff --git a/dependencies/includes/assimp/StringComparison.h b/dependencies/includes/assimp/StringComparison.h new file mode 100644 index 0000000..0518d42 --- /dev/null +++ b/dependencies/includes/assimp/StringComparison.h @@ -0,0 +1,224 @@ +/* +Open Asset Import Library (assimp) +---------------------------------------------------------------------- + +Copyright (c) 2006-2022, assimp team + + +All rights reserved. + +Redistribution and use of this software in source and binary forms, +with or without modification, are permitted provided that the +following conditions are met: + +* Redistributions of source code must retain the above + copyright notice, this list of conditions and the + following disclaimer. + +* Redistributions in binary form must reproduce the above + copyright notice, this list of conditions and the + following disclaimer in the documentation and/or other + materials provided with the distribution. + +* Neither the name of the assimp team, nor the names of its + contributors may be used to endorse or promote products + derived from this software without specific prior + written permission of the assimp team. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +---------------------------------------------------------------------- +*/ + +/** @file Definition of platform independent string workers: + + ASSIMP_itoa10 + ASSIMP_stricmp + ASSIMP_strincmp + + These functions are not consistently available on all platforms, + or the provided implementations behave too differently. +*/ +#pragma once +#ifndef INCLUDED_AI_STRING_WORKERS_H +#define INCLUDED_AI_STRING_WORKERS_H + +#ifdef __GNUC__ +#pragma GCC system_header +#endif + +#include +#include +#include + +#include +#include +#include + +namespace Assimp { + +// ------------------------------------------------------------------------------- +/** @brief itoa with a fixed base 10 + * 'itoa' is not consistently available on all platforms so it is quite useful + * to have a small replacement function here. No need to use a full sprintf() + * if we just want to print a number ... + * @param out Output buffer + * @param max Maximum number of characters to be written, including '\0'. + * This parameter may not be 0. + * @param number Number to be written + * @return Length of the output string, excluding the '\0' + */ +inline unsigned int ASSIMP_itoa10(char *out, unsigned int max, int32_t number) { + ai_assert(nullptr != out); + + // write the unary minus to indicate we have a negative number + unsigned int written = 1u; + if (number < 0 && written < max) { + *out++ = '-'; + ++written; + number = -number; + } + + // We begin with the largest number that is not zero. + int32_t cur = 1000000000; // 2147483648 + bool mustPrint = false; + while (written < max) { + + const unsigned int digit = number / cur; + if (mustPrint || digit > 0 || 1 == cur) { + // print all future zero's from now + mustPrint = true; + + *out++ = '0' + static_cast(digit); + + ++written; + number -= digit * cur; + if (1 == cur) { + break; + } + } + cur /= 10; + } + + // append a terminal zero + *out++ = '\0'; + return written - 1; +} + +// ------------------------------------------------------------------------------- +/** @brief itoa with a fixed base 10 (Secure template overload) + * The compiler should choose this function if he or she is able to determine the + * size of the array automatically. + */ +template +inline unsigned int ASSIMP_itoa10(char (&out)[length], int32_t number) { + return ASSIMP_itoa10(out, length, number); +} + +// ------------------------------------------------------------------------------- +/** @brief Helper function to do platform independent string comparison. + * + * This is required since stricmp() is not consistently available on + * all platforms. Some platforms use the '_' prefix, others don't even + * have such a function. + * + * @param s1 First input string + * @param s2 Second input string + * @return 0 if the given strings are identical + */ +inline int ASSIMP_stricmp(const char *s1, const char *s2) { + ai_assert(nullptr != s1); + ai_assert(nullptr != s2); + +#if (defined _MSC_VER) + + return ::_stricmp(s1, s2); +#else + char c1, c2; + do { + c1 = tolower((unsigned char)*(s1++)); + c2 = tolower((unsigned char)*(s2++)); + } while (c1 && (c1 == c2)); + return c1 - c2; +#endif +} + +// ------------------------------------------------------------------------------- +/** @brief Case independent comparison of two std::strings + * + * @param a First string + * @param b Second string + * @return 0 if a == b + */ +inline int ASSIMP_stricmp(const std::string &a, const std::string &b) { + int i = (int)b.length() - (int)a.length(); + return (i ? i : ASSIMP_stricmp(a.c_str(), b.c_str())); +} + +// ------------------------------------------------------------------------------- +/** @brief Helper function to do platform independent string comparison. + * + * This is required since strincmp() is not consistently available on + * all platforms. Some platforms use the '_' prefix, others don't even + * have such a function. + * + * @param s1 First input string + * @param s2 Second input string + * @param n Maximum number of characters to compare + * @return 0 if the given strings are identical + */ +inline int ASSIMP_strincmp(const char *s1, const char *s2, unsigned int n) { + ai_assert(nullptr != s1); + ai_assert(nullptr != s2); + if (!n) { + return 0; + } + +#if (defined _MSC_VER) + + return ::_strnicmp(s1, s2, n); + +#elif defined(__GNUC__) + + return ::strncasecmp(s1, s2, n); + +#else + char c1, c2; + unsigned int p = 0; + do { + if (p++ >= n) return 0; + c1 = tolower((unsigned char)*(s1++)); + c2 = tolower((unsigned char)*(s2++)); + } while (c1 && (c1 == c2)); + + return c1 - c2; +#endif +} + +// ------------------------------------------------------------------------------- +/** @brief Evaluates an integer power + * + * todo: move somewhere where it fits better in than here + */ +inline unsigned int integer_pow(unsigned int base, unsigned int power) { + unsigned int res = 1; + for (unsigned int i = 0; i < power; ++i) { + res *= base; + } + + return res; +} + +} // namespace Assimp + +#endif // ! AI_STRINGCOMPARISON_H_INC diff --git a/dependencies/includes/assimp/StringUtils.h b/dependencies/includes/assimp/StringUtils.h new file mode 100644 index 0000000..59c6e9e --- /dev/null +++ b/dependencies/includes/assimp/StringUtils.h @@ -0,0 +1,279 @@ +/* +Open Asset Import Library (assimp) +---------------------------------------------------------------------- + +Copyright (c) 2006-2022, assimp team + +All rights reserved. + +Redistribution and use of this software in source and binary forms, +with or without modification, are permitted provided that the +following conditions are met: + +* Redistributions of source code must retain the above +copyright notice, this list of conditions and the +following disclaimer. + +* Redistributions in binary form must reproduce the above +copyright notice, this list of conditions and the +following disclaimer in the documentation and/or other +materials provided with the distribution. + +* Neither the name of the assimp team, nor the names of its +contributors may be used to endorse or promote products +derived from this software without specific prior +written permission of the assimp team. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +---------------------------------------------------------------------- +*/ +#pragma once +#ifndef INCLUDED_AI_STRINGUTILS_H +#define INCLUDED_AI_STRINGUTILS_H + +#ifdef __GNUC__ +#pragma GCC system_header +#endif + +#include + +#include +#include +#include +#include +#include +#include +#include + +#ifdef _MSC_VER +#define AI_SIZEFMT "%Iu" +#else +#define AI_SIZEFMT "%zu" +#endif + +// --------------------------------------------------------------------------------- +/// @fn ai_snprintf +/// @brief The portable version of the function snprintf ( C99 standard ), which +/// works on visual studio compilers 2013 and earlier. +/// @param outBuf The buffer to write in +/// @param size The buffer size +/// @param format The format string +/// @param ap The additional arguments. +/// @return The number of written characters if the buffer size was big enough. +/// If an encoding error occurs, a negative number is returned. +// --------------------------------------------------------------------------------- +#if defined(_MSC_VER) && _MSC_VER < 1900 + +inline int c99_ai_vsnprintf(char *outBuf, size_t size, const char *format, va_list ap) { + int count(-1); + if (0 != size) { + count = _vsnprintf_s(outBuf, size, _TRUNCATE, format, ap); + } + if (count == -1) { + count = _vscprintf(format, ap); + } + + return count; +} + +inline int ai_snprintf(char *outBuf, size_t size, const char *format, ...) { + int count; + va_list ap; + + va_start(ap, format); + count = c99_ai_vsnprintf(outBuf, size, format, ap); + va_end(ap); + + return count; +} + +#elif defined(__MINGW32__) +#define ai_snprintf __mingw_snprintf +#else +#define ai_snprintf snprintf +#endif + +// --------------------------------------------------------------------------------- +/// @fn to_string +/// @brief The portable version of to_string ( some gcc-versions on embedded +/// devices are not supporting this). +/// @param value The value to write into the std::string. +/// @return The value as a std::string +// --------------------------------------------------------------------------------- +template +AI_FORCE_INLINE std::string ai_to_string(T value) { + std::ostringstream os; + os << value; + + return os.str(); +} + +// --------------------------------------------------------------------------------- +/// @fn ai_strtof +/// @brief The portable version of strtof. +/// @param begin The first character of the string. +/// @param end The last character +/// @return The float value, 0.0f in case of an error. +// --------------------------------------------------------------------------------- +AI_FORCE_INLINE +float ai_strtof(const char *begin, const char *end) { + if (nullptr == begin) { + return 0.0f; + } + float val(0.0f); + if (nullptr == end) { + val = static_cast(::atof(begin)); + } else { + std::string::size_type len(end - begin); + std::string token(begin, len); + val = static_cast(::atof(token.c_str())); + } + + return val; +} + +// --------------------------------------------------------------------------------- +/// @fn DecimalToHexa +/// @brief The portable to convert a decimal value into a hexadecimal string. +/// @param toConvert Value to convert +/// @return The hexadecimal string, is empty in case of an error. +// --------------------------------------------------------------------------------- +template +AI_FORCE_INLINE std::string ai_decimal_to_hexa(T toConvert) { + std::string result; + std::stringstream ss; + ss << std::hex << toConvert; + ss >> result; + + for (size_t i = 0; i < result.size(); ++i) { + result[i] = (char)toupper((unsigned char)result[i]); + } + + return result; +} + +// --------------------------------------------------------------------------------- +/// @brief translate RGBA to String +/// @param r aiColor.r +/// @param g aiColor.g +/// @param b aiColor.b +/// @param a aiColor.a +/// @param with_head # +/// @return The hexadecimal string, is empty in case of an error. +// --------------------------------------------------------------------------------- +AI_FORCE_INLINE std::string ai_rgba2hex(int r, int g, int b, int a, bool with_head) { + std::stringstream ss; + if (with_head) { + ss << "#"; + } + ss << std::hex << std::setfill('0') << std::setw(8) << (r << 24 | g << 16 | b << 8 | a); + + return ss.str(); +} + +// --------------------------------------------------------------------------------- +/// @brief Performs a trim from start (in place) +/// @param s string to trim. +AI_FORCE_INLINE void ai_trim_left(std::string &s) { + s.erase(s.begin(), std::find_if(s.begin(), s.end(), [](unsigned char ch) { + return !std::isspace(ch); + })); +} + +// --------------------------------------------------------------------------------- +/// @brief Performs a trim from end (in place). +/// @param s string to trim. +// --------------------------------------------------------------------------------- +// --------------------------------------------------------------------------------- +AI_FORCE_INLINE void ai_trim_right(std::string &s) { + s.erase(std::find_if(s.rbegin(), s.rend(), [](unsigned char ch) { + return !std::isspace(ch); + }).base(), s.end()); +} + +// --------------------------------------------------------------------------------- +/// @brief Performs a trim from both ends (in place). +/// @param s string to trim. +// --------------------------------------------------------------------------------- +AI_FORCE_INLINE std::string ai_trim(std::string &s) { + std::string out(s); + ai_trim_left(out); + ai_trim_right(out); + + return out; +} + +// --------------------------------------------------------------------------------- +template +AI_FORCE_INLINE char_t ai_tolower(char_t in) { + return (in >= (char_t)'A' && in <= (char_t)'Z') ? (char_t)(in + 0x20) : in; +} + +// --------------------------------------------------------------------------------- +/// @brief Performs a ToLower-operation and return the lower-case string. +/// @param in The incoming string. +/// @return The string as lowercase. +// --------------------------------------------------------------------------------- +AI_FORCE_INLINE std::string ai_tolower(const std::string &in) { + std::string out(in); + ai_trim_left(out); + ai_trim_right(out); + std::transform(out.begin(), out.end(), out.begin(), [](unsigned char c) { return ai_tolower(c); }); + return out; +} + +// --------------------------------------------------------------------------------- +template +AI_FORCE_INLINE char_t ai_toupper(char_t in) { + return (in >= (char_t)'a' && in <= (char_t)'z') ? (char_t)(in - 0x20) : in; +} + +// --------------------------------------------------------------------------------- +/// @brief Performs a ToLower-operation and return the upper-case string. +/// @param in The incoming string. +/// @return The string as uppercase. +AI_FORCE_INLINE std::string ai_str_toupper(const std::string &in) { + std::string out(in); + std::transform(out.begin(), out.end(), out.begin(), [](char c) { return ai_toupper(c); }); + return out; +} + +// --------------------------------------------------------------------------------- +/// @brief Make a string printable by replacing all non-printable characters with +/// the specified placeholder character. +/// @param in The incoming string. +/// @param placeholder Placeholder character, default is a question mark. +/// @return The string, with all non-printable characters replaced. +AI_FORCE_INLINE std::string ai_str_toprintable(const std::string &in, char placeholder = '?') { + std::string out(in); + std::transform(out.begin(), out.end(), out.begin(), [placeholder] (unsigned char c) { + return isprint(c) ? (char)c : placeholder; + }); + return out; +} + +// --------------------------------------------------------------------------------- +/// @brief Make a string printable by replacing all non-printable characters with +/// the specified placeholder character. +/// @param in The incoming string. +/// @param len The length of the incoming string. +/// @param placeholder Placeholder character, default is a question mark. +/// @return The string, with all non-printable characters replaced. Will return an +/// empty string if in is null or len is <= 0. +AI_FORCE_INLINE std::string ai_str_toprintable(const char *in, int len, char placeholder = '?') { + return (in && len > 0) ? ai_str_toprintable(std::string(in, len), placeholder) : std::string(); +} + + +#endif // INCLUDED_AI_STRINGUTILS_H diff --git a/dependencies/includes/assimp/Subdivision.h b/dependencies/includes/assimp/Subdivision.h new file mode 100644 index 0000000..1141203 --- /dev/null +++ b/dependencies/includes/assimp/Subdivision.h @@ -0,0 +1,131 @@ +/* +Open Asset Import Library (assimp) +---------------------------------------------------------------------- + +Copyright (c) 2006-2022, assimp team + + +All rights reserved. + +Redistribution and use of this software in source and binary forms, +with or without modification, are permitted provided that the +following conditions are met: + +* Redistributions of source code must retain the above + copyright notice, this list of conditions and the + following disclaimer. + +* Redistributions in binary form must reproduce the above + copyright notice, this list of conditions and the + following disclaimer in the documentation and/or other + materials provided with the distribution. + +* Neither the name of the assimp team, nor the names of its + contributors may be used to endorse or promote products + derived from this software without specific prior + written permission of the assimp team. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +---------------------------------------------------------------------- +*/ + +/** @file Defines a helper class to evaluate subdivision surfaces.*/ +#pragma once +#ifndef AI_SUBDISIVION_H_INC +#define AI_SUBDISIVION_H_INC + +#ifdef __GNUC__ +# pragma GCC system_header +#endif + +#include + +struct aiMesh; + +namespace Assimp { + +// ------------------------------------------------------------------------------ +/** Helper class to evaluate subdivision surfaces. Different algorithms + * are provided for choice. */ +// ------------------------------------------------------------------------------ +class ASSIMP_API Subdivider { +public: + + /** Enumerates all supported subvidision algorithms */ + enum Algorithm { + CATMULL_CLARKE = 0x1 + }; + + virtual ~Subdivider(); + + // --------------------------------------------------------------- + /** Create a subdivider of a specific type + * + * @param algo Algorithm to be used for subdivision + * @return Subdivider instance. */ + static Subdivider* Create (Algorithm algo); + + // --------------------------------------------------------------- + /** Subdivide a mesh using the selected algorithm + * + * @param mesh First mesh to be subdivided. Must be in verbose + * format. + * @param out Receives the output mesh, allocated by me. + * @param num Number of subdivisions to perform. + * @param discard_input If true is passed, the input mesh is + * deleted after the subdivision is complete. This can + * improve performance because it allows the optimization + * to reuse the existing mesh for intermediate results. + * @pre out!=mesh*/ + virtual void Subdivide ( aiMesh* mesh, + aiMesh*& out, unsigned int num, + bool discard_input = false) = 0; + + // --------------------------------------------------------------- + /** Subdivide multiple meshes using the selected algorithm. This + * avoids erroneous smoothing on objects consisting of multiple + * per-material meshes. Usually, most 3d modellers smooth on a + * per-object base, regardless the materials assigned to the + * meshes. + * + * @param smesh Array of meshes to be subdivided. Must be in + * verbose format. + * @param nmesh Number of meshes in smesh. + * @param out Receives the output meshes. The array must be + * sufficiently large (at least @c nmesh elements) and may not + * overlap the input array. Output meshes map one-to-one to + * their corresponding input meshes. The meshes are allocated + * by the function. + * @param discard_input If true is passed, input meshes are + * deleted after the subdivision is complete. This can + * improve performance because it allows the optimization + * of reusing existing meshes for intermediate results. + * @param num Number of subdivisions to perform. + * @pre nmesh != 0, smesh and out may not overlap*/ + virtual void Subdivide ( + aiMesh** smesh, + size_t nmesh, + aiMesh** out, + unsigned int num, + bool discard_input = false) = 0; + +}; + +inline Subdivider::~Subdivider() = default; + +} // end namespace Assimp + + +#endif // !! AI_SUBDISIVION_H_INC + diff --git a/dependencies/includes/assimp/TinyFormatter.h b/dependencies/includes/assimp/TinyFormatter.h new file mode 100644 index 0000000..df2a32e --- /dev/null +++ b/dependencies/includes/assimp/TinyFormatter.h @@ -0,0 +1,181 @@ +/* +Open Asset Import Library (assimp) +---------------------------------------------------------------------- + +Copyright (c) 2006-2022, assimp team + + +All rights reserved. + +Redistribution and use of this software in source and binary forms, +with or without modification, are permitted provided that the +following conditions are met: + +* Redistributions of source code must retain the above + copyright notice, this list of conditions and the + following disclaimer. + +* Redistributions in binary form must reproduce the above + copyright notice, this list of conditions and the + following disclaimer in the documentation and/or other + materials provided with the distribution. + +* Neither the name of the assimp team, nor the names of its + contributors may be used to endorse or promote products + derived from this software without specific prior + written permission of the assimp team. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +---------------------------------------------------------------------- +*/ + +/** @file TinyFormatter.h + * @brief Utility to format log messages more easily. Introduced + * to get rid of the boost::format dependency. Much slinker, + * basically just extends stringstream. + */ +#pragma once +#ifndef INCLUDED_TINY_FORMATTER_H +#define INCLUDED_TINY_FORMATTER_H + +#ifdef __GNUC__ +# pragma GCC system_header +#endif + +#include + +namespace Assimp { +namespace Formatter { + +// ------------------------------------------------------------------------------------------------ +/** stringstream utility. Usage: + * @code + * void writelog(const std::string&s); + * void writelog(const std::wstring&s); + * ... + * writelog(format()<< "hi! this is a number: " << 4); + * writelog(wformat()<< L"hi! this is a number: " << 4); + * + * @endcode */ +template < typename T, + typename CharTraits = std::char_traits, + typename Allocator = std::allocator > +class basic_formatter { +public: + typedef class std::basic_string string; + typedef class std::basic_ostringstream stringstream; + + basic_formatter() { + // empty + } + + /* Allow basic_formatter's to be used almost interchangeably + * with std::(w)string or const (w)char* arguments because the + * conversion c'tor is called implicitly. */ + template + basic_formatter(const TT& sin) { + underlying << sin; + } + + // Same problem as the copy constructor below, but with root cause is that stream move + // is not permitted on older GCC versions. Small performance impact on those platforms. +#if defined(__GNUC__) && (__GNUC__ == 4 && __GNUC_MINOR__ <= 9) + basic_formatter(basic_formatter&& other) { + underlying << (string)other; + } +#else + basic_formatter(basic_formatter&& other) + : underlying(std::move(other.underlying)) { + } +#endif + + // The problem described here: + // https://sourceforge.net/tracker/?func=detail&atid=1067632&aid=3358562&group_id=226462 + // can also cause trouble here. Apparently, older gcc versions sometimes copy temporaries + // being bound to const ref& function parameters. Copying streams is not permitted, though. + // This workaround avoids this by manually specifying a copy ctor. +#if !defined(__GNUC__) || !defined(__APPLE__) || __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6) + explicit basic_formatter(const basic_formatter& other) { + underlying << (string)other; + } +#endif + + operator string () const { + return underlying.str(); + } + + /* note - this is declared const because binding temporaries does only + * work for const references, so many function prototypes will + * include const basic_formatter& s but might still want to + * modify the formatted string without the need for a full copy.*/ + template ::value>::type * = nullptr> + const basic_formatter &operator<<(const TToken &s) const { + underlying << s; + return *this; + } + + template ::value>::type * = nullptr> + const basic_formatter &operator<<(const TToken &s) const { + underlying << s.what(); + return *this; + } + + template ::value>::type * = nullptr> + basic_formatter &operator<<(const TToken &s) { + underlying << s; + return *this; + } + + template ::value>::type * = nullptr> + basic_formatter &operator<<(const TToken &s) { + underlying << s.what(); + return *this; + } + + + // comma operator overloaded as well, choose your preferred way. + template + const basic_formatter& operator, (const TToken& s) const { + *this << s; + return *this; + } + + template + basic_formatter& operator, (const TToken& s) { + *this << s; + return *this; + } + + // Fix for MSVC8 + // See https://sourceforge.net/projects/assimp/forums/forum/817654/topic/4372824 + template + basic_formatter& operator, (TToken& s) { + *this << s; + return *this; + } + + +private: + mutable stringstream underlying; +}; + + +typedef basic_formatter< char > format; +typedef basic_formatter< wchar_t > wformat; + +} // ! namespace Formatter + +} // ! namespace Assimp + +#endif diff --git a/dependencies/includes/assimp/Vertex.h b/dependencies/includes/assimp/Vertex.h new file mode 100644 index 0000000..fd7eb03 --- /dev/null +++ b/dependencies/includes/assimp/Vertex.h @@ -0,0 +1,299 @@ +/* +Open Asset Import Library (assimp) +---------------------------------------------------------------------- + +Copyright (c) 2006-2022, assimp team + + +All rights reserved. + +Redistribution and use of this software in source and binary forms, +with or without modification, are permitted provided that the +following conditions are met: + +* Redistributions of source code must retain the above + copyright notice, this list of conditions and the + following disclaimer. + +* Redistributions in binary form must reproduce the above + copyright notice, this list of conditions and the + following disclaimer in the documentation and/or other + materials provided with the distribution. + +* Neither the name of the assimp team, nor the names of its + contributors may be used to endorse or promote products + derived from this software without specific prior + written permission of the assimp team. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +---------------------------------------------------------------------- +*/ +/** @file Defines a helper class to represent an interleaved vertex + along with arithmetic operations to support vertex operations + such as subdivision, smoothing etc. + + While the code is kept as general as possible, arithmetic operations + that are not currently well-defined (and would cause compile errors + due to missing operators in the math library), are commented. + */ +#pragma once +#ifndef AI_VERTEX_H_INC +#define AI_VERTEX_H_INC + +#ifdef __GNUC__ +# pragma GCC system_header +#endif + +#include +#include +#include + +#include + +namespace Assimp { + + /////////////////////////////////////////////////////////////////////////// + // std::plus-family operates on operands with identical types - we need to + // support all the (vectype op float) combinations in vector maths. + // Providing T(float) would open the way to endless implicit conversions. + /////////////////////////////////////////////////////////////////////////// + namespace Intern { + template struct plus { + TRES operator() (const T0& t0, const T1& t1) const { + return t0+t1; + } + }; + template struct minus { + TRES operator() (const T0& t0, const T1& t1) const { + return t0-t1; + } + }; + template struct multiplies { + TRES operator() (const T0& t0, const T1& t1) const { + return t0*t1; + } + }; + template struct divides { + TRES operator() (const T0& t0, const T1& t1) const { + return t0/t1; + } + }; + } + +// ------------------------------------------------------------------------------------------------ +/** Intermediate description a vertex with all possible components. Defines a full set of + * operators, so you may use such a 'Vertex' in basic arithmetic. All operators are applied + * to *all* vertex components equally. This is useful for stuff like interpolation + * or subdivision, but won't work if special handling is required for some vertex components. */ +// ------------------------------------------------------------------------------------------------ +class Vertex { + friend Vertex operator + (const Vertex&,const Vertex&); + friend Vertex operator - (const Vertex&,const Vertex&); + friend Vertex operator * (const Vertex&,ai_real); + friend Vertex operator / (const Vertex&,ai_real); + friend Vertex operator * (ai_real, const Vertex&); + +public: + Vertex() {} + + // ---------------------------------------------------------------------------- + /** Extract a particular vertex from a mesh and interleave all components */ + explicit Vertex(const aiMesh* msh, unsigned int idx) { + ai_assert(idx < msh->mNumVertices); + position = msh->mVertices[idx]; + + if (msh->HasNormals()) { + normal = msh->mNormals[idx]; + } + + if (msh->HasTangentsAndBitangents()) { + tangent = msh->mTangents[idx]; + bitangent = msh->mBitangents[idx]; + } + + for (unsigned int i = 0; msh->HasTextureCoords(i); ++i) { + texcoords[i] = msh->mTextureCoords[i][idx]; + } + + for (unsigned int i = 0; msh->HasVertexColors(i); ++i) { + colors[i] = msh->mColors[i][idx]; + } + } + + // ---------------------------------------------------------------------------- + /** Extract a particular vertex from a anim mesh and interleave all components */ + explicit Vertex(const aiAnimMesh* msh, unsigned int idx) { + ai_assert(idx < msh->mNumVertices); + if (msh->HasPositions()) { + position = msh->mVertices[idx]; + } + + if (msh->HasNormals()) { + normal = msh->mNormals[idx]; + } + + if (msh->HasTangentsAndBitangents()) { + tangent = msh->mTangents[idx]; + bitangent = msh->mBitangents[idx]; + } + + for (unsigned int i = 0; msh->HasTextureCoords(i); ++i) { + texcoords[i] = msh->mTextureCoords[i][idx]; + } + + for (unsigned int i = 0; msh->HasVertexColors(i); ++i) { + colors[i] = msh->mColors[i][idx]; + } + } + + Vertex& operator += (const Vertex& v) { + *this = *this+v; + return *this; + } + + Vertex& operator -= (const Vertex& v) { + *this = *this-v; + return *this; + } + + Vertex& operator *= (ai_real v) { + *this = *this*v; + return *this; + } + + Vertex& operator /= (ai_real v) { + *this = *this/v; + return *this; + } + + // ---------------------------------------------------------------------------- + /** Convert back to non-interleaved storage */ + void SortBack(aiMesh* out, unsigned int idx) const { + ai_assert(idxmNumVertices); + out->mVertices[idx] = position; + + if (out->HasNormals()) { + out->mNormals[idx] = normal; + } + + if (out->HasTangentsAndBitangents()) { + out->mTangents[idx] = tangent; + out->mBitangents[idx] = bitangent; + } + + for(unsigned int i = 0; out->HasTextureCoords(i); ++i) { + out->mTextureCoords[i][idx] = texcoords[i]; + } + + for(unsigned int i = 0; out->HasVertexColors(i); ++i) { + out->mColors[i][idx] = colors[i]; + } + } + +private: + + // ---------------------------------------------------------------------------- + /** Construct from two operands and a binary operation to combine them */ + template