通过Redux

时间:2017-02-04 09:12:31

标签: javascript reactjs redux middleware web-audio

我正在Redux中构建一个步进音序器来帮助我学习。我需要的是一些通用时钟,其作用是“滴答”以提供音乐时序。 所以我计划使用Tone.js库,它建立在Web Audio API之上。 有以下function

Tone.Transport.scheduleRepeat(function(time){
//do something with the time
}, "8n");

您提供了一个回调函数,每次传输到达某个位置时都会调用该函数。 我天真的方法是让回调调度一个动作,增加我商店的滴答计数。 这不起作用,因为操作必须是普通对象。 有什么可能使这个工作?

我仍然在努力正确理解Redux的基本原理,所以我对此不确定,但我能以某种方式 使用中间件捕获回调,并在实际调用它时让它通过?

这是正确的方向吗?我可以研究一下哪些库,示例或概念,以便了解如何做到这一点?

这是否是正确的方向还是应该以不同的方式处理?如果是这样,怎么样?

或者您是否知道在Redux应用程序中为不同组件提供全局计时的最佳方法是什么?

4 个答案:

答案 0 :(得分:2)

我在https://www.html5rocks.com/en/tutorials/audio/scheduling/中详细介绍了很多细节,但简而言之 - 你不应该使用Javascript回调来进行音乐时机。它不够准确。这就是我们进行网络音频调度的原因。

答案 1 :(得分:1)

非常有趣的问题,这是一个我想要解决的宠物项目,但还没有写过一个LOC。 :)

对于计时部分,您可以使用中间件,甚至是<Clock />组件,它会启动scheduler本身并在每个tick上调度一个动作(可能将时间作为有效负载)。

然而,棘手的部分是您的应用程序的整体设计。仔细研究了Tone.js后,我很清楚你必须将音频部分与视觉效果分开。这意味着您的Redux状态应该只关注代表您的步进音序器(我可以看到类似于通道列表(通道/乐器)的内容,并且您的音频逻辑应该保持在它之外。

我会保留一系列通道,每个通道本身都是一个&#34;步骤&#34;定义他们是否活跃&#34;或不。再次,这只是与UI相关。单击要激活它的步骤应该通过动作创建者修改您的状态,并设置您稍后需要与Tone.js一起玩的任何内容。

播放歌曲时,您需要发送该时钟标记以推进当前活动的&#34;步骤&#34;所以你可以在UI中突出显示它。

在这里,令人垂涎的Codepen仿效Roland TR-808来抓住想法:

http://codepen.io/pixelass/details/adyLPR

这里是关于同步音频和用户界面的Tone.js wiki的相关部分:

https://github.com/Tonejs/Tone.js/wiki/Performance#syncing-visuals

抱歉,我无法帮助您,也许您已经领先于我,并且已经有了一些可以分享的工作代码。

答案 2 :(得分:1)

基本上cwilso回答正确。如果你想为音乐时间安排JS函数,你不应该使用回调。

如果您希望根据此时间实现Tone.js功能,请避免使用Redux并直接在回调函数或Tone.Transport.schedule函数中调用这些Tone.js函数。

如果您正在构建一个音序器,我建议根据您想要的长度循环Tone.Transport,并安排在时间线上的某些点上点击音符(如果这是您正在寻找的)。查看文档中的loopStart和loopEnd以获取帮助(http://tonejs.github.io/docs/#Transport)。

如果视觉参考需要此功能,这可能是您需要Redux回调的原因,我可以提供一个示例,说明如何在下面执行此操作:

 var tempMessage = angular.copy(message);
$scope.senderMessage = ""; 
 $http.post(url + 'c_chat/sendSenderMessageJson', {
    'bsid'    : bsid ,
    'srid'    : srid ,
    'message' : tempMessage 

  })

希望这有帮助。

答案 3 :(得分:0)

我正在研究与音频相关的应用程序,并且还遇到了管理Web音频API部分以及redux的问题。

我解决它的方法只是在redux存储中存储音频状态的表示(普通JS对象;你将存储在数据库中并用于初始化应用程序)。此存储的信息用于呈现UI。

我有一个服务'引擎'类,它监听商店中的所有更改,这是创建和存储所有Web音频内容的地方。它基本上包含redux存储中reducers的副本,但将更改应用于Web音频节点。

例如我发送一个动作:

{type:"set-gain", payload:{trackid:3, value:0.7} }

redux存储将简单地将普通JS轨道对象更新为新增益值,引擎将找到关联的增益节点(或使用添加等创建)并在其上设置值。

在您的情况下,您将调度一个动作来设置时间,在redux存储中保存为普通JS对象,在引擎部分中使用Web音频调度来设置它。