- 声音

Posted MossGrower

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了- 声音相关的知识,希望对你有一定的参考价值。

Babylon.js 深入 - 第 2 章 - 声音(2)

声音

Babylon.js 声音引擎基于 Web Audio 规范,要使用它,您需要使用与 Web Audio 兼容的浏览器。声音引擎提供环境、空间和定向声音。

创建空间 3D 声音

要将声音转换为空间 3D 声音,您需要通过设置以下选项来实现:

var music = new BABYLON.Sound("music", "music.wav", scene, null, 
    loop: true,
    autoplay: true,
    spatialSound: true
);

空间 3D 声音的默认属性是:

  • distanceModel - 衰减模型 - 默认为 linear (线性)方程,其他选项是 inverse (翻转) 、 exponential (指数)。
  • maxDistance - 最大距离 - 默认为 100,一旦听者距离声音超过 100 个单位,音量将为 0
  • panningModel - 平移模型 - 默认为 equalpower,等功率平移算法通常被认为是简单高效的,另一个可用选项是 HRTF,它是一种更高质量的空间化算法,使用卷积与来自人类受试者的测量脉冲响应。这种平移方法呈现立体声输出。这是使用耳机时的最佳算法。

maxDistance 仅在使用 linear (线性)衰减时使用。否则,您可以使用 rolloffFactorrefDistance 选项调整其他模型的衰减。默认情况下两者都设置为 1,但您可以更改它。

例如:

var music = new BABYLON.Sound("music", "music.wav", scene, null, 
    loop: true,
    autoplay: true,
    spatialSound: true,
    distanceModel: "exponential",
    rolloffFactor: 2
);

声音在 3D 世界中的默认位置是 (0,0,0)。要更改它,请使用 setPosition() 函数:

music.setPosition(new BABYLON.Vector3(100, 0, 0));

3D 空间音效的示例:

示例链接

示例代码:

<!DOCTYPE html>
<html>

<head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
    <title>Babylon.js sample code</title>
    <!-- Babylon.js -->
    <script src="https://cdnjs.cloudflare.com/ajax/libs/dat-gui/0.6.2/dat.gui.min.js"></script>
    <script src="https://assets.babylonjs.com/generated/Assets.js"></script>
    <script src="https://preview.babylonjs.com/ammo.js"></script>
    <script src="https://preview.babylonjs.com/cannon.js"></script>
    <script src="https://preview.babylonjs.com/Oimo.js"></script>
    <script src="https://preview.babylonjs.com/earcut.min.js"></script>
    <script src="https://preview.babylonjs.com/babylon.js"></script>
    <script src="https://preview.babylonjs.com/materialsLibrary/babylonjs.materials.min.js"></script>
    <script src="https://preview.babylonjs.com/proceduralTexturesLibrary/babylonjs.proceduralTextures.min.js"></script>
    <script src="https://preview.babylonjs.com/postProcessesLibrary/babylonjs.postProcess.min.js"></script>
    <script src="https://preview.babylonjs.com/loaders/babylonjs.loaders.js"></script>
    <script src="https://preview.babylonjs.com/serializers/babylonjs.serializers.min.js"></script>
    <script src="https://preview.babylonjs.com/gui/babylon.gui.min.js"></script>
    <script src="https://preview.babylonjs.com/inspector/babylon.inspector.bundle.js"></script>
    <style>
        html,
        body 
            overflow: hidden;
            width: 100%;
            height: 100%;
            margin: 0;
            padding: 0;
        

        #renderCanvas 
            width: 100%;
            height: 100%;
            touch-action: none;
        
    </style>
</head>

<body>
    <canvas id="renderCanvas"></canvas>
    <script>
        var canvas = document.getElementById("renderCanvas");
        var startRenderLoop = function (engine, canvas) 
            engine.runRenderLoop(function () 
                if (sceneToRender && sceneToRender.activeCamera) 
                    sceneToRender.render();
                
            );
        
        var engine = null;
        var scene = null;
        var sceneToRender = null;
        var createDefaultEngine = function () 
            return new BABYLON.Engine(canvas, true, 
                preserveDrawingBuffer: true,
                stencil: true,
                disableWebGL2Support: false
            );
        ;
        var createScene = function () 
            var scene = new BABYLON.Scene(engine);
            var camera = new BABYLON.FreeCamera("FreeCamera", new BABYLON.Vector3(0, 5, 0), scene);
            camera.attachControl(canvas, true);
            var light0 = new BABYLON.DirectionalLight("Omni", new BABYLON.Vector3(0, -5, 2), scene);
            //Ground
            var ground = BABYLON.Mesh.CreatePlane("ground", 600.0, scene);
            ground.material = new BABYLON.StandardMaterial("groundMat", scene);
            ground.material.diffuseColor = new BABYLON.Color3(1, 1, 1);
            ground.material.backFaceCulling = false;
            ground.position = new BABYLON.Vector3(0, 0, 0);
            ground.rotation = new BABYLON.Vector3(Math.PI / 2, 0, 0);
            var sphereMat = new BABYLON.StandardMaterial("sphereMat", scene);
            sphereMat.diffuseColor = BABYLON.Color3.Purple();
            sphereMat.backFaceCulling = false;
            sphereMat.alpha = 0.3;
            var sphereMusic1 = BABYLON.Mesh.CreateSphere("musicsphere", 20, 50, scene);
            sphereMusic1.material = sphereMat;
            sphereMusic1.position = new BABYLON.Vector3(60, 0, 0);
            var sphereMusic2 = BABYLON.Mesh.CreateSphere("musicsphere", 20, 200, scene);
            sphereMusic2.material = sphereMat;
            sphereMusic2.position = new BABYLON.Vector3(-100, 0, 0);
            var sphereMusic3 = BABYLON.Mesh.CreateSphere("musicsphere", 20, 60, scene);
            sphereMusic3.material = sphereMat;
            sphereMusic3.position = new BABYLON.Vector3(0, 0, 100);
            var music1 = new BABYLON.Sound("Violons11", "./violons11.wav", scene,
                null, 
                    loop: true,
                    autoplay: true,
                    spatialSound: true,
                    maxDistance: 25
                );
            music1.setPosition(new BABYLON.Vector3(60, 0, 0));
            var music2 = new BABYLON.Sound("Violons18", "./violons18.wav", scene,
                null, 
                    loop: true,
                    autoplay: true,
                    spatialSound: true
                );
            music2.setPosition(new BABYLON.Vector3(-100, 0, 0));
            var music3 = new BABYLON.Sound("Cellolong", "./cellolong.wav", scene,
                null, 
                    loop: true,
                    autoplay: true,
                    spatialSound: true,
                    maxDistance: 30
                );
            music3.setPosition(new BABYLON.Vector3(0, 0, 100));
            // 为场景设置重力,类似于G力,在Y轴上
            scene.gravity = new BABYLON.Vector3(0, -0.9, 0);
            // 启用碰撞
            scene.collisionsEnabled = true;
            // 然后将碰撞和重力应用于活动摄影机
            camera.checkCollisions = true;
            camera.applyGravity = true;
            // 设置摄像机周围的椭球体
            camera.ellipsoid = new BABYLON.Vector3(1, 1, 1);
            // 最后,指定哪个网格是可碰撞的
            ground.checkCollisions = true;
            return scene;
        ;
        window.initFunction = async function () 
            var asyncEngineCreation = async function () 
                try 
                    return createDefaultEngine();
                 catch (e) 
                    console.log(
                        "the available createEngine function failed. Creating the default engine instead"
                    );
                    return createDefaultEngine();
                
            
            window.engine = await asyncEngineCreation();
            if (!engine) throw 'engine should not be null.';
            startRenderLoop(engine, canvas);
            window.scene = createScene();
        ;
        initFunction().then(() => 
            sceneToRender = scene
        );
        // Resize
        window.addEventListener("resize", function () 
            engine.resize();
        );
    </script>
</body>

</html>

使用键盘和鼠标移动到场景中。每个声音都由一个紫色球体表示。当你进入一个球体时,你会开始听到音乐。声音在球体中心更大,离开球体时下降到 0

将声音附加到网格

这可能是在场景中处理 3D 声音的最简单方法。只需创建一个 BABYLON.Sound,将它附加到现有的网格上就可以了!如果网格在移动,声音也会随之移动。

这是要使用的代码:

var music = new BABYLON.Sound("Violons", "sounds/violons11.wav", scene, null, 
    loop: true,
    autoplay: true
);
// 声音现在将跟随盒子网格位置
music.attachToMesh(box);

对声音调用 attachToMesh() 函数会自动将其转换为空间 3D 声音。使用上面的代码,您将使用默认的 Babylon.js 值:maxDistance100 的线性衰减和 HRTF 类型的平移模型。

附加到网格的声音的示例:

示例链接

示例代码:

<!DOCTYPE html>
<html>

<head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
    <title>Babylon.js sample code</title>
    <!-- Babylon.js -->
    <script src="https://cdnjs.cloudflare.com/ajax/libs/dat-gui/0.6.2/dat.gui.min.js"></script>
    <script src="https://assets.babylonjs.com/generated/Assets.js"></script>
    <script src="https://preview.babylonjs.com/ammo.js"></script>
    <script src="https://preview.babylonjs.com/cannon.js"></script>
    <script src="https://preview.babylonjs.com/Oimo.js"></script>
    <script src="https://preview.babylonjs.com/earcut.min.js"></script>
    <script src="https://preview.babylonjs.com/babylon.js"></script>
    <script src="https://preview.babylonjs.com/materialsLibrary/babylonjs.materials.min.js"></script>
    <script src="https://preview.babylonjs.com/proceduralTexturesLibrary/babylonjs.proceduralTextures.min.js"></script>
    <script src="https://preview.babylonjs.com/postProcessesLibrary/babylonjs.postProcess.min.js"></script>
    <script src="https://preview.babylonjs.com/loaders/babylonjs.loaders.js"></script>
    <script src="https://preview.babylonjs.com/serializers/babylonjs.serializers.min.js"></script>
    <script src="https://preview.babylonjs.com/gui/babylon.gui.min.js"></script>
    <script src="https://preview.babylonjs.com/inspector/babylon.inspector.bundle.js"></script>
    <style>
        html,
        body 
            overflow: hidden;
            width: 100%;
            height: 100%;
            margin: 0;
            padding: 0;
        

        #renderCanvas 
            width: 100%;
            height: 100%;
            touch-action: none;
        
    </style>
</head>

<body>
    <canvas id="renderCanvas"></canvas>
    <script>
        var canvas = document.getElementById("renderCanvas");
        var startRenderLoop = function (engine, canvas) 
            engine.runRenderLoop(function () 
                if (sceneToRender && sceneToRender.activeCamera) 
                    sceneToRender.render();
                
            );
        
        var engine = null;
        var scene = null;
        var sceneToRender = null;
        var 

使用 Python 获取声音输入并查找相似的声音

【中文标题】使用 Python 获取声音输入并查找相似的声音【英文标题】:Get sound input & Find similar sound with Python 【发布时间】:2016-07-21 04:10:17 【问题描述】:

我想做的就像使用 Python 的“Shazam”或“SoundHound”,只有声音版本,而不是音乐。

例如,当我发出声音(例如关门声)时,在声音列表中找到最相似的声音数据。

我不知道你能不能理解,因为我的英语不好,但想象一下“Shazam”的声音版本。

我知道“Shazam”没有开放的 API。 有没有像'Shazam'这样的API? 或者, 如何实现?

【问题讨论】:

【参考方案1】:

您可以使用多个库,但例如,它们都不会将样本归类为“关门”。但是您可以使用这些库进行特征提取并构建/获取声音数据集,构建分类器,对其进行训练并将其用于声音分类。

图书馆:

    Friture - Friture 是一个图形程序,旨在对音频输入进行实时时频分析。它提供了一组可视化小部件来显示音频数据,例如示波器、频谱分析仪、滚动 2D 频谱图。

    LibXtract - LibXtract 是一个简单、便携、轻量级的音频特征提取函数库。该库的目的是提供一组相对详尽的特征提取原语,这些原语被设计为“级联”以创建提取层次结构。

    Yaafe - Yet Another Audio Feature Extractor 是用于音频分析的工具箱。易于使用且高效地同时提取大量音频特征。支持 WAV 和 MP3 文件,或嵌入 C++、Python 或 Matlab 应用程序中。

    Aubio - Aubio 是一种用于从音频信号中提取注释的工具。它的功能包括在每次攻击之前对声音文件进行分段、执行音高检测、敲击节拍以及从现场音频中生成 MIDI 流。

    LibROSA - 用于音频和音乐分析的 python 模块。它易于使用,并实现了许多常用的音乐分析功能。

如果您确实选择使用我上面提到的建议,我建议 scikit-learn 作为机器学习库。它包含许多您可能想要使用的分类器。

【讨论】:

【参考方案2】:

这里的问题是音乐有结构,而你想要找到的声音可能有不同的特征。以门为例,仅门的重量、尺寸和材料就会影响它将产生的声学特征的类型。如果您想通过相似性进行搜索,则功能袋方法可能是一种简单的(ish)方法。但是,有不同的方法,例如通过沿声音频谱图的滑动窗口进行采样,并尝试(通过相似性)与您录制的先前声音匹配,声音分解等......

【讨论】:

以上是关于- 声音的主要内容,如果未能解决你的问题,请参考以下文章

- 声音

通过three.js源码学习计算机图形学/webgl系列之camerarendererscene

WebGL入坑系列:导航方块的制作

WebXR 元宇宙或将基于 Web

探索基础元素---基于WebGL的H5 3D游戏引擎BabylonJS

画布或 webgl 中的声音