From a4bb0acf0da8feda44859549aaff8c073456e92d Mon Sep 17 00:00:00 2001 From: mubashirsharik Date: Mon, 11 Mar 2024 22:56:25 +0530 Subject: [PATCH 1/7] added recording and playback button --- guide/guide.html | 2 +- header-icons/playback.svg | 12 +++++++ header-icons/record.svg | 12 +++++++ js/widgets/sampler.js | 72 +++++++++++++++++++++++++++++++++++++++ 4 files changed, 97 insertions(+), 1 deletion(-) create mode 100644 header-icons/playback.svg create mode 100644 header-icons/record.svg diff --git a/guide/guide.html b/guide/guide.html index b0456948fc..d7112ef227 100644 --- a/guide/guide.html +++ b/guide/guide.html @@ -2564,7 +2564,7 @@

4.2.1 The Phrase MakerRe 4, Mi 4, Sol 4.

-

widget

+

widget

Once you have a group of notes (a "chunk") that you like, click on the Save button (just to the right of the Play button). This will create a diff --git a/header-icons/playback.svg b/header-icons/playback.svg new file mode 100644 index 0000000000..992cf59bb6 --- /dev/null +++ b/header-icons/playback.svg @@ -0,0 +1,12 @@ + + + + + + + + + + + + \ No newline at end of file diff --git a/header-icons/record.svg b/header-icons/record.svg new file mode 100644 index 0000000000..06e1a652d1 --- /dev/null +++ b/header-icons/record.svg @@ -0,0 +1,12 @@ + + + + + + + + + + + + \ No newline at end of file diff --git a/js/widgets/sampler.js b/js/widgets/sampler.js index 1bb43fa386..dad6edbbac 100644 --- a/js/widgets/sampler.js +++ b/js/widgets/sampler.js @@ -429,6 +429,78 @@ function SampleWidget() { } }; + let can_record = false; + let is_recording = false; + let recorder = null; + let chunks = []; + let audioURL = null; + + function setUpAudio() { + if (navigator.mediaDevices && navigator.mediaDevices.getUserMedia) { + console.log("getUserMedia supported"); + navigator.mediaDevices.getUserMedia({ audio: true }) + .then(stream => { + recorder = new MediaRecorder(stream); + recorder.ondataavailable = e => { + chunks.push(e.data); + }; + recorder.onstop = e => { + let blob = new Blob(chunks, { type: 'audio/webm' }); + chunks = []; + audioURL = URL.createObjectURL(blob); + console.log("Recording complete."); + }; + can_record = true; + }) + .catch(err => { + console.log("The following error occurred: " + err); + }); + } + } + + function ToggleMic() { + if (!can_record) return; + + is_recording = !is_recording; + if (is_recording) { + recorder.start(); + console.log("recording started"); + } else { + recorder.stop(); + } + } + + function playAudio() { + if (audioURL) { + const audio = new Audio(audioURL); + audio.play(); + console.log("audio played"); + } else { + console.error("No recorded audio available."); + } + } + + + setUpAudio(); + + widgetWindow.addButton( + "record.svg", + ICONSIZE, + _("Toggle Mic"), + "" + ).onclick = function () { + ToggleMic(); + }; + + widgetWindow.addButton( + "playback.svg", + ICONSIZE, + _("Playback"), + "" + ).onclick = function () { + playAudio(); + }; + widgetWindow.sendToCenter(); this.widgetWindow = widgetWindow; From 783d6a281ae46aef0dc25837b201afd99934c1f1 Mon Sep 17 00:00:00 2001 From: mubashirsharik Date: Mon, 11 Mar 2024 23:01:13 +0530 Subject: [PATCH 2/7] upd --- guide/guide.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/guide/guide.html b/guide/guide.html index d7112ef227..b0456948fc 100644 --- a/guide/guide.html +++ b/guide/guide.html @@ -2564,7 +2564,7 @@

4.2.1 The Phrase MakerRe 4, Mi 4, Sol 4.

-

widget

+

widget

Once you have a group of notes (a "chunk") that you like, click on the Save button (just to the right of the Play button). This will create a From 2fa63bbff83e5009fc81913a6c6edcfde37e6546 Mon Sep 17 00:00:00 2001 From: mubashirsharik Date: Tue, 12 Mar 2024 16:34:49 +0530 Subject: [PATCH 3/7] added recording started,completed msg and button disabled when no url --- js/widgets/sampler.js | 43 ++++++++++++++++++++++++++++++++----------- 1 file changed, 32 insertions(+), 11 deletions(-) diff --git a/js/widgets/sampler.js b/js/widgets/sampler.js index dad6edbbac..eb13002774 100644 --- a/js/widgets/sampler.js +++ b/js/widgets/sampler.js @@ -227,6 +227,24 @@ function SampleWidget() { } }; + + /** + * Displays a message indicating that recording has started. + * @returns {void} + */ + function displayRecordingStartMessage() { + this.activity.textMsg(_("Recording started...")); + } + + /** + * Displays a message indicating that recording has stopped. + * @returns {void} + */ + function displayRecordingStopMessage() { + this.activity.textMsg(_("Recording complete...")); + } + + /** * Displays an error message when the uploaded sample is not a .wav file. * @returns {void} @@ -437,7 +455,6 @@ function SampleWidget() { function setUpAudio() { if (navigator.mediaDevices && navigator.mediaDevices.getUserMedia) { - console.log("getUserMedia supported"); navigator.mediaDevices.getUserMedia({ audio: true }) .then(stream => { recorder = new MediaRecorder(stream); @@ -448,7 +465,7 @@ function SampleWidget() { let blob = new Blob(chunks, { type: 'audio/webm' }); chunks = []; audioURL = URL.createObjectURL(blob); - console.log("Recording complete."); + displayRecordingStopMessage.call(that); }; can_record = true; }) @@ -457,32 +474,29 @@ function SampleWidget() { }); } } - function ToggleMic() { if (!can_record) return; is_recording = !is_recording; if (is_recording) { recorder.start(); - console.log("recording started"); + displayRecordingStartMessage.call(that); } else { recorder.stop(); } } - + function playAudio() { if (audioURL) { const audio = new Audio(audioURL); audio.play(); - console.log("audio played"); } else { console.error("No recorded audio available."); } } - setUpAudio(); - + widgetWindow.addButton( "record.svg", ICONSIZE, @@ -492,12 +506,19 @@ function SampleWidget() { ToggleMic(); }; - widgetWindow.addButton( + + this._playbackBtn= widgetWindow.addButton( "playback.svg", ICONSIZE, _("Playback"), - "" - ).onclick = function () { + ""); + + this._playbackBtn.onclick = () => { + if(!audioURL) + { + this._playbackBtn.disabled = true; + } + else playAudio(); }; From e92b15cb5808510ed9a561f37acacaaa587f956c Mon Sep 17 00:00:00 2001 From: mubashirsharik Date: Thu, 14 Mar 2024 20:53:58 +0530 Subject: [PATCH 4/7] updated icons --- css/activities.css | 5 +++ header-icons/mic.svg | 5 +++ header-icons/record.svg | 14 ++------- js/widgets/sampler.js | 70 +++++++++++++++++++++++------------------ 4 files changed, 53 insertions(+), 41 deletions(-) create mode 100644 header-icons/mic.svg diff --git a/css/activities.css b/css/activities.css index 95ebea992b..a3030b061b 100644 --- a/css/activities.css +++ b/css/activities.css @@ -836,6 +836,11 @@ table { cursor: not-allowed; } +#playbackBtn.disabled { + opacity: 0.5; + cursor: not-allowed; +} + #right-arrow, #left-arrow { position: absolute; diff --git a/header-icons/mic.svg b/header-icons/mic.svg new file mode 100644 index 0000000000..4970f47405 --- /dev/null +++ b/header-icons/mic.svg @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/header-icons/record.svg b/header-icons/record.svg index 06e1a652d1..0b88904f03 100644 --- a/header-icons/record.svg +++ b/header-icons/record.svg @@ -1,12 +1,4 @@ - - - - - - - - - - - + + + \ No newline at end of file diff --git a/js/widgets/sampler.js b/js/widgets/sampler.js index eb13002774..45eddc20c6 100644 --- a/js/widgets/sampler.js +++ b/js/widgets/sampler.js @@ -447,6 +447,37 @@ function SampleWidget() { } }; + this._recordBtn= widgetWindow.addButton( + "mic.svg", + ICONSIZE, + _("Toggle Mic"), + "" + ); + this._recordBtn.onclick = function() { + ToggleMic(this); + }.bind(this._recordBtn); + + this._playbackBtn= widgetWindow.addButton( + "playback.svg", + ICONSIZE, + _("Playback"), + ""); + this._playbackBtn.id="playbackBtn" + this._playbackBtn.classList.add("disabled"); + + + const togglePlaybackButtonState = () => { + if (!audioURL) { + this._playbackBtn.classList.add("disabled"); + } else { + this._playbackBtn.classList.remove("disabled"); + } + }; + + this._playbackBtn.onclick = () => { + playAudio(); + }; + let can_record = false; let is_recording = false; let recorder = null; @@ -466,6 +497,7 @@ function SampleWidget() { chunks = []; audioURL = URL.createObjectURL(blob); displayRecordingStopMessage.call(that); + togglePlaybackButtonState(); }; can_record = true; }) @@ -474,54 +506,32 @@ function SampleWidget() { }); } } - function ToggleMic() { + function ToggleMic(buttonElement) { if (!can_record) return; - + is_recording = !is_recording; if (is_recording) { - recorder.start(); + recorder.start(); + buttonElement.getElementsByTagName('img')[0].src = "header-icons/record.svg"; displayRecordingStartMessage.call(that); } else { recorder.stop(); + buttonElement.getElementsByTagName('img')[0].src = "header-icons/mic.svg"; } } - + function playAudio() { if (audioURL) { const audio = new Audio(audioURL); audio.play(); + console.log("Playing audio."); } else { console.error("No recorded audio available."); } } setUpAudio(); - - widgetWindow.addButton( - "record.svg", - ICONSIZE, - _("Toggle Mic"), - "" - ).onclick = function () { - ToggleMic(); - }; - - - this._playbackBtn= widgetWindow.addButton( - "playback.svg", - ICONSIZE, - _("Playback"), - ""); - - this._playbackBtn.onclick = () => { - if(!audioURL) - { - this._playbackBtn.disabled = true; - } - else - playAudio(); - }; - + widgetWindow.sendToCenter(); this.widgetWindow = widgetWindow; From 12714c972c28b5a0bb2a2022cacdf677d9e2d665 Mon Sep 17 00:00:00 2001 From: mubashirsharik Date: Fri, 15 Mar 2024 23:09:40 +0530 Subject: [PATCH 5/7] added sample for waveform --- js/widgets/sampler.js | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/js/widgets/sampler.js b/js/widgets/sampler.js index 45eddc20c6..a42d96d8f6 100644 --- a/js/widgets/sampler.js +++ b/js/widgets/sampler.js @@ -498,6 +498,11 @@ function SampleWidget() { audioURL = URL.createObjectURL(blob); displayRecordingStopMessage.call(that); togglePlaybackButtonState(); + + const audioData = e.target.result; + that.sampleData = audioData; + that.sampleName = `Recorded Audio ${audioURL}`; + that._addSample(); }; can_record = true; }) From a3fe9219db580b1056b9626f01f2fbe769378152 Mon Sep 17 00:00:00 2001 From: mubashirsharik Date: Thu, 28 Mar 2024 13:39:37 +0530 Subject: [PATCH 6/7] upd --- js/widgets/sampler.js | 50 ++++++++++++++++++++++--------------------- 1 file changed, 26 insertions(+), 24 deletions(-) diff --git a/js/widgets/sampler.js b/js/widgets/sampler.js index a42d96d8f6..6376874217 100644 --- a/js/widgets/sampler.js +++ b/js/widgets/sampler.js @@ -484,31 +484,33 @@ function SampleWidget() { let chunks = []; let audioURL = null; - function setUpAudio() { + async function setUpAudio() { if (navigator.mediaDevices && navigator.mediaDevices.getUserMedia) { - navigator.mediaDevices.getUserMedia({ audio: true }) - .then(stream => { - recorder = new MediaRecorder(stream); - recorder.ondataavailable = e => { - chunks.push(e.data); - }; - recorder.onstop = e => { - let blob = new Blob(chunks, { type: 'audio/webm' }); - chunks = []; - audioURL = URL.createObjectURL(blob); - displayRecordingStopMessage.call(that); - togglePlaybackButtonState(); - - const audioData = e.target.result; - that.sampleData = audioData; - that.sampleName = `Recorded Audio ${audioURL}`; - that._addSample(); - }; - can_record = true; - }) - .catch(err => { - console.log("The following error occurred: " + err); - }); + try { + const stream = await navigator.mediaDevices.getUserMedia({ audio: true }); + recorder = new MediaRecorder(stream); + recorder.ondataavailable = e => { + chunks.push(e.data); + }; + recorder.onstop = async e => { + let blob = new Blob(chunks, { type: 'audio/webm' }); + chunks = []; + audioURL = URL.createObjectURL(blob); + displayRecordingStopMessage.call(that); + togglePlaybackButtonState(); + + const module = await import("https://cdn.jsdelivr.net/npm/webm-to-wav-converter@1.1.0/+esm"); + const getWaveBlob = module.getWaveBlob; + const wavBlob = await getWaveBlob(blob); + const wavAudioURL = URL.createObjectURL(wavBlob); + that.sampleData = wavAudioURL; + that.sampleName = `Recorded Audio ${audioURL}`; + that._addSample(); + }; + can_record = true; + } catch (err) { + console.log("The following error occurred: " + err); + } } } function ToggleMic(buttonElement) { From 73b01d7b88bac20e637a93fb4aa8d91e36e7d781 Mon Sep 17 00:00:00 2001 From: mubashirsharik Date: Thu, 15 Aug 2024 19:32:45 +0530 Subject: [PATCH 7/7] added the required changes,play sample pitch,create sample with setinstrument --- js/widgets/sampler.js | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/js/widgets/sampler.js b/js/widgets/sampler.js index 6376874217..ce3eb9b407 100644 --- a/js/widgets/sampler.js +++ b/js/widgets/sampler.js @@ -264,16 +264,18 @@ function SampleWidget() { that._addSample(); var newStack = [ + [0,"settimbre",100,100,[null,1,null,5]], [ - 0, + 1, ["customsample", { value: [that.sampleName, that.sampleData, "do", 4] }], 100, 100, - [null, 1, 2, 3] + [0, 2, 3, 4] ], - [1, ["audiofile", { value: [that.sampleName, that.sampleData] }], 0, 0, [0]], - [2, ["solfege", { value: that.samplePitch }], 0, 0, [0]], - [3, ["number", { value: that.sampleOctave }], 0, 0, [0]] + [2, ["audiofile", { value: [that.sampleName, that.sampleData] }], 0, 0, [1]], + [3, ["solfege", { value: that.samplePitch }], 0, 0, [1]], + [4, ["number", { value: that.sampleOctave }], 0, 0, [1]], + [5,"hidden",0,0,[0,null]] ]; that.activity.blocks.loadNewBlocks(newStack); @@ -375,8 +377,8 @@ function SampleWidget() { } else { if (!(this.sampleName == "")) { this.resume(); - this._playReferencePitch(); } + this._playReferencePitch(); } };