我循环播放一系列音频文件的方法有误吗?
Is there a mistake in my method of cycling through an array of audio files?
当检测到语音时,会播放第一首曲目,一直播放到最后,然后打开麦克风收听内容,当它听到内容时,会播放第二首曲目,依此类推,直到第十首曲目。
运行 此代码在 ubuntu 中的 chrome 浏览器上:
<script type="text/javascript" src="p5/p5.min.js"></script>
<script type="text/javascript" src="p5/addons/p5.dom.min.js"></script>
<script type="text/javascript" src="p5/addons/p5.sound.min.js"></script>
<script type="text/javascript" src="p5/addons/p5.speech.js"></script>
<script type="text/javascript">
var myRec = new p5.SpeechRec('en-US', parseResult);
myRec.continuous = true;
myRec.interimResults = false;
var songs = ['1.wav', '2.wav', '3.wav', '4.wav', '5.wav', '6.wav', '7.wav', '8.wav', '9.wav', '10.wav'];
var songCount = songs.length;
var currentSong = 0;
var song;
function preload() {
soundFormats('wav');
song = loadSound('audioFiles/' + songs[currentSong]);
}
function setup() {
createCanvas(600, 600);
background(255, 255, 255);
fill(0, 0, 0, 255);
myRec.start();
}
function draw() {
}
function parseResult() {
var mostrecentword = myRec.resultString.split(' ').pop();
if(mostrecentword.indexOf("")!==-1) {
song.playMode('untilDone');
song.play();
background(0, 255, 0);
}
else if(song.isPlaying()) {
myRec.stop();
}
console.log(mostrecentword);
console.log(currentSong);
currentSong = currentSong + 1;
}
</script>
除非您再次调用 preload() ,否则歌曲仍分配给第一个 .wav 文件。因此,当您在 parseResult
中递增 currentSong
时,您仍然需要重新分配下一首歌曲。您可能只需再次调用 preload()
或将 song = loadSound('audioFiles/' + songs[currentSong]);
添加到 parseResult
.
的末尾
为了播放数组中的歌曲,您需要为每个歌曲调用 loadSound。
来自参考页:
If loadSound is called during preload(), the p5.SoundFile will be ready to play in time for setup() and draw(). If called outside of preload, the p5.SoundFile will not be ready immediately, so loadSound accepts a callback as the second parameter.
确保所有歌曲都可用的一种方法是将它们全部加载到 preload()
并将加载的歌曲保存在一个数组中,而不仅仅是歌曲名称。
这是一个完整的脚本,演示了在 preload
中加载声音供以后使用:
var songs = [];
var songNames = ['ir_begin.wav', 'ir_inter.wav', 'ir_end.wav'];
var songCount = songNames.length;
var currentSong = 0;
var song;
function preload() {
for (let i = 0; i < songNames.length; i++){
songs.push(loadSound('audioFiles/' + songNames[i]));
}
}
function setup() {
frameRate(1);
}
function draw(){
songs[currentSong].setVolume(0.9);
songs[currentSong].play();
currentSong++;
if (currentSong >= songs.length){
noLoop();
}
}
在预加载中加载所有歌曲的缺点是您的草图会提前加载所有歌曲。您可以通过仅在需要时加载歌曲来分散延迟时间。
按需加载的代码有点复杂,但像这样就可以完成工作:
var songs = [];
var loadedSongs = [];
var songNames = ['ir_begin.wav', 'ir_inter.wav', 'ir_end.wav'];
var songCount = songNames.length;
var currentSong = 0;
var song;
function preload() {
songs.push(loadSound('audioFiles/' + songNames[currentSong]));
}
function setup() {
frameRate(1);
}
function draw(){
if (currentSong < songs.length){
songs[currentSong].setVolume(0.9);
songs[currentSong].play();
currentSong++;
} else {
loadSong(songNames[currentSong]);
}
if (currentSong >= songCount){
noLoop();
}
}
function loadSong(songName){
for (let i = 0; i < loadedSongs.length; i++){
if (songName === loadedSongs[i]){
return;
}
}
loadSound('audioFiles/' + songName, loadSongCallBack);
loadedSongs.push(songName);
}
function loadSongCallBack(song){
songs.push(song);
}
当检测到语音时,会播放第一首曲目,一直播放到最后,然后打开麦克风收听内容,当它听到内容时,会播放第二首曲目,依此类推,直到第十首曲目。
运行 此代码在 ubuntu 中的 chrome 浏览器上:
<script type="text/javascript" src="p5/p5.min.js"></script>
<script type="text/javascript" src="p5/addons/p5.dom.min.js"></script>
<script type="text/javascript" src="p5/addons/p5.sound.min.js"></script>
<script type="text/javascript" src="p5/addons/p5.speech.js"></script>
<script type="text/javascript">
var myRec = new p5.SpeechRec('en-US', parseResult);
myRec.continuous = true;
myRec.interimResults = false;
var songs = ['1.wav', '2.wav', '3.wav', '4.wav', '5.wav', '6.wav', '7.wav', '8.wav', '9.wav', '10.wav'];
var songCount = songs.length;
var currentSong = 0;
var song;
function preload() {
soundFormats('wav');
song = loadSound('audioFiles/' + songs[currentSong]);
}
function setup() {
createCanvas(600, 600);
background(255, 255, 255);
fill(0, 0, 0, 255);
myRec.start();
}
function draw() {
}
function parseResult() {
var mostrecentword = myRec.resultString.split(' ').pop();
if(mostrecentword.indexOf("")!==-1) {
song.playMode('untilDone');
song.play();
background(0, 255, 0);
}
else if(song.isPlaying()) {
myRec.stop();
}
console.log(mostrecentword);
console.log(currentSong);
currentSong = currentSong + 1;
}
</script>
除非您再次调用 preload() ,否则歌曲仍分配给第一个 .wav 文件。因此,当您在 parseResult
中递增 currentSong
时,您仍然需要重新分配下一首歌曲。您可能只需再次调用 preload()
或将 song = loadSound('audioFiles/' + songs[currentSong]);
添加到 parseResult
.
为了播放数组中的歌曲,您需要为每个歌曲调用 loadSound。
来自参考页:
If loadSound is called during preload(), the p5.SoundFile will be ready to play in time for setup() and draw(). If called outside of preload, the p5.SoundFile will not be ready immediately, so loadSound accepts a callback as the second parameter.
确保所有歌曲都可用的一种方法是将它们全部加载到 preload()
并将加载的歌曲保存在一个数组中,而不仅仅是歌曲名称。
这是一个完整的脚本,演示了在 preload
中加载声音供以后使用:
var songs = [];
var songNames = ['ir_begin.wav', 'ir_inter.wav', 'ir_end.wav'];
var songCount = songNames.length;
var currentSong = 0;
var song;
function preload() {
for (let i = 0; i < songNames.length; i++){
songs.push(loadSound('audioFiles/' + songNames[i]));
}
}
function setup() {
frameRate(1);
}
function draw(){
songs[currentSong].setVolume(0.9);
songs[currentSong].play();
currentSong++;
if (currentSong >= songs.length){
noLoop();
}
}
在预加载中加载所有歌曲的缺点是您的草图会提前加载所有歌曲。您可以通过仅在需要时加载歌曲来分散延迟时间。
按需加载的代码有点复杂,但像这样就可以完成工作:
var songs = [];
var loadedSongs = [];
var songNames = ['ir_begin.wav', 'ir_inter.wav', 'ir_end.wav'];
var songCount = songNames.length;
var currentSong = 0;
var song;
function preload() {
songs.push(loadSound('audioFiles/' + songNames[currentSong]));
}
function setup() {
frameRate(1);
}
function draw(){
if (currentSong < songs.length){
songs[currentSong].setVolume(0.9);
songs[currentSong].play();
currentSong++;
} else {
loadSong(songNames[currentSong]);
}
if (currentSong >= songCount){
noLoop();
}
}
function loadSong(songName){
for (let i = 0; i < loadedSongs.length; i++){
if (songName === loadedSongs[i]){
return;
}
}
loadSound('audioFiles/' + songName, loadSongCallBack);
loadedSongs.push(songName);
}
function loadSongCallBack(song){
songs.push(song);
}