Commit f6195cdc authored by GROSS-AMBLARD David's avatar GROSS-AMBLARD David
Browse files

Adding sound recording example (not yet working)

parent c08c60f9
......@@ -58,8 +58,8 @@
}).addTo(macarte);
// Inialisation de la variable pour stocker les polygones modifiables
var editableLayers = new L.FeatureGroup();
macarte.addLayer(editableLayers);
window.editableLayers = new L.FeatureGroup();
macarte.addLayer(window.editableLayers);
var drawPluginOptions = {
position: "topright",
......@@ -76,20 +76,23 @@
var drawControl = new L.Control.Draw(drawPluginOptions);
macarte.addControl(drawControl);
macarte.on('click', onMapClick);
var editableLayers = new L.FeatureGroup();
macarte.addLayer(editableLayers);
window.editableLayers = new L.FeatureGroup();
//window.test=2;
macarte.addLayer(window.editableLayers);
macarte.on("draw:created", function (e) {
var type = e.layerType,
layer = e.layer;
editableLayers.addLayer(layer);
window.editableLayers.addLayer(layer);
});
function onMapClick(e) {
var geojson = editableLayers.toGeoJSON();
var geojson = window.editableLayers.toGeoJSON();
json = JSON.stringify(geojson);
document.querySelector("#answer").value = json;
//alert(json);
}
</script>
<head>
<meta charset="utf-8" />
</head>
<h2>Please read the following phrase out loud and record it:</h2>
<p>Simply defined, crowdsourcing represents the act of a company or institution taking a function once performed by employees and outsourcing it to an undefined (and generally large) network of people in the form of an open call.
</p>
<br/>
<button type="button" id="startRecordingButton">Record</button>
<button type="button" id="stopRecordingButton">Stop</button>
<button type="button" id="playButton">Play</button>
<button id="submit" type="submit" form="taskAnswerForm" formaction="index.php?mode=showTasks" formmethod="post">Submit</button>
<input type="hidden" id="answer" name="answer" value="[\"3\":\"4\"]"/>
<!-- <button type="button" id="downloadButton" disabled>Download</button> -->
<script>
var startRecordingButton = document.getElementById("startRecordingButton");
var stopRecordingButton = document.getElementById("stopRecordingButton");
var playButton = document.getElementById("playButton");
var downloadButton = document.getElementById("downloadButton");
var leftchannel = [];
var rightchannel = [];
var recorder = null;
var recordingLength = 0;
var volume = null;
var mediaStream = null;
var sampleRate = 44100;
var context = null;
var blob = null;
startRecordingButton.addEventListener("click", function () {
// Initialize recorder
navigator.getUserMedia = navigator.getUserMedia || navigator.webkitGetUserMedia || navigator.mozGetUserMedia || navigator.msGetUserMedia;
navigator.getUserMedia(
{
audio: true
},
function (e) {
console.log("user consent");
// creates the audio context
window.AudioContext = window.AudioContext || window.webkitAudioContext;
context = new AudioContext();
// creates an audio node from the microphone incoming stream
mediaStream = context.createMediaStreamSource(e);
// https://developer.mozilla.org/en-US/docs/Web/API/AudioContext/createScriptProcessor
// bufferSize: the onaudioprocess event is called when the buffer is full
var bufferSize = 2048;
var numberOfInputChannels = 2;
var numberOfOutputChannels = 2;
if (context.createScriptProcessor) {
recorder = context.createScriptProcessor(bufferSize, numberOfInputChannels, numberOfOutputChannels);
} else {
recorder = context.createJavaScriptNode(bufferSize, numberOfInputChannels, numberOfOutputChannels);
}
recorder.onaudioprocess = function (e) {
leftchannel.push(new Float32Array(e.inputBuffer.getChannelData(0)));
rightchannel.push(new Float32Array(e.inputBuffer.getChannelData(1)));
recordingLength += bufferSize;
}
// we connect the recorder
mediaStream.connect(recorder);
recorder.connect(context.destination);
},
function (e) {
console.error(e);
});
console.log(blob);
});
stopRecordingButton.addEventListener("click", function () {
// stop recording
recorder.disconnect(context.destination);
mediaStream.disconnect(recorder);
// we flat the left and right channels down
// Float32Array[] => Float32Array
var leftBuffer = flattenArray(leftchannel, recordingLength);
var rightBuffer = flattenArray(rightchannel, recordingLength);
// we interleave both channels together
// [left[0],right[0],left[1],right[1],...]
var interleaved = interleave(leftBuffer, rightBuffer);
// we create our wav file
var buffer = new ArrayBuffer(44 + interleaved.length * 2);
var view = new DataView(buffer);
// RIFF chunk descriptor
writeUTFBytes(view, 0, 'RIFF');
view.setUint32(4, 44 + interleaved.length * 2, true);
writeUTFBytes(view, 8, 'WAVE');
// FMT sub-chunk
writeUTFBytes(view, 12, 'fmt ');
view.setUint32(16, 16, true); // chunkSize
view.setUint16(20, 1, true); // wFormatTag
view.setUint16(22, 2, true); // wChannels: stereo (2 channels)
view.setUint32(24, sampleRate, true); // dwSamplesPerSec
view.setUint32(28, sampleRate * 4, true); // dwAvgBytesPerSec
view.setUint16(32, 4, true); // wBlockAlign
view.setUint16(34, 16, true); // wBitsPerSample
// data sub-chunk
writeUTFBytes(view, 36, 'data');
view.setUint32(40, interleaved.length * 2, true);
// write the PCM samples
var index = 44;
var volume = 1;
for (var i = 0; i < interleaved.length; i++) {
view.setInt16(index, interleaved[i] * (0x7FFF * volume), true);
index += 2;
}
// our final blob
blob = new Blob([view], { type: 'audio/wav' });
console.log(blob);
let JSONString = JSON.stringify(blob); // TODO Can not work this way
document.querySelector("#answer").value = "{'Blob':'012212...'}"; //JSONString;
});
playButton.addEventListener("click", function () {
if (blob == null) {
return;
}
var url = window.URL.createObjectURL(blob);
var audio = new Audio(url);
audio.play();
console.log(blob);
});
downloadButton.addEventListener("click", function () {
if (blob == null) {
return;
}
var url = URL.createObjectURL(blob);
console.log(url);
var a = document.createElement("a");
document.body.appendChild(a);
a.style = "display: none";
a.href = url;
a.download = "test.wav";
a.click();
window.URL.revokeObjectURL(url);
SaveBlob();
});
/*async function SaveBlob() {
let formData = new FormData();
formData.append("blob", blob);
const ctrl = new AbortController() // timeout
setTimeout(() => ctrl.abort(), 5000);
try {
let r = await fetch('Upload',
{method: "POST", body: formData, signal: ctrl.signal});
console.log('HTTP response code:',r.status);
}
catch(e) {
console.log('ça n'a pas fonctionné...:', e);
}
}*/
function flattenArray(channelBuffer, recordingLength) {
var result = new Float32Array(recordingLength);
var offset = 0;
for (var i = 0; i < channelBuffer.length; i++) {
var buffer = channelBuffer[i];
result.set(buffer, offset);
offset += buffer.length;
}
return result;
}
function interleave(leftChannel, rightChannel) {
var length = leftChannel.length + rightChannel.length;
var result = new Float32Array(length);
var inputIndex = 0;
for (var index = 0; index < length;) {
result[index++] = leftChannel[inputIndex];
result[index++] = rightChannel[inputIndex];
inputIndex++;
}
return result;
}
function writeUTFBytes(view, offset, string) {
for (var i = 0; i < string.length; i++) {
view.setUint8(offset + i, string.charCodeAt(i));
}
}
</script>
</body>
</html>
\ No newline at end of file
......@@ -39,7 +39,7 @@
"actions": [
"delete from Task where artifact=CURRENT_ARTIFACT",
"select @TEMPLATE:=body from Template where id='NewGUI-sound-form'",
"select @TITLE:='Geolocalization - area example'",
"select @TITLE:='Sound identification'",
"select @CHECKER:=NULL",
"select @CHECKERMSG:=NULL",
"select @TYPE:=11",
......@@ -55,12 +55,11 @@
"guard": "select true from Answered where artifact=CURRENT_ARTIFACT and id=3",
"actions": [
"delete from Task where artifact=CURRENT_ARTIFACT",
"select @TEMPLATE:=body from Template where id='headwork-gui-4'",
"select @TITLE:='Drowpdown list'",
"select @TEMPLATE:=body from Template where id='NewGUI-RecordSound'",
"select @TITLE:='Sound recording'",
"select @CHECKER:=NULL",
"select @CHECKERMSG:=NULL",
"select @LIST:='select value as value,value as text from Answer where user=SESSION_USER and idtask=3'",
"select @TYPE:=1",
"select @TYPE:=11",
"insert into Task(id,artifact,title,description,body,checker,checkermsg,type,arg1) values (4,CURRENT_ARTIFACT,'demo',@TITLE,@TEMPLATE,@CHECKER,@CHECKERMSG,@TYPE,@LIST)",
"delete from Profile where idartifact=CURRENT_ARTIFACT",
"insert into Profile values (4,CURRENT_ARTIFACT,1)"
......@@ -72,80 +71,9 @@
"guard": "select true from Answered where artifact=CURRENT_ARTIFACT and id=4",
"actions": [
"delete from Task where artifact=CURRENT_ARTIFACT",
"select @TEMPLATE:=body from Template where id='headwork-gui-5'",
"select @TITLE:='Radio buttons'",
"select @CHECKER:=NULL",
"select @CHECKERMSG:=NULL",
"select @LIST:='select value as value,value as text from Answer where user=SESSION_USER and idtask=3'",
"select @TYPE:=2",
"insert into Task(id,artifact,title,description,body,checker,checkermsg,type,arg1) values (5,CURRENT_ARTIFACT,'demo',@TITLE,@TEMPLATE,@CHECKER,@CHECKERMSG,@TYPE,@LIST)",
"delete from Profile where idartifact=CURRENT_ARTIFACT",
"insert into Profile values (5,CURRENT_ARTIFACT,1)"
]
}
},
"6": {
"7": {
"guard": "select true from Answered where artifact=CURRENT_ARTIFACT and id=5",
"actions": [
"delete from Task where artifact=CURRENT_ARTIFACT",
"select @TEMPLATE:=body from Template where id='headwork-gui-6'",
"select @TITLE:='Radio buttons with alternative free input'",
"select @CHECKER:=NULL",
"select @CHECKERMSG:=NULL",
"select @LIST:='select value as value,value as text from Answer where user=SESSION_USER and idtask=3'",
"select @TYPE:=4",
"insert into Task(id,artifact,title,description,body,checker,checkermsg,type,arg1) values (6,CURRENT_ARTIFACT,'demo',@TITLE,@TEMPLATE,@CHECKER,@CHECKERMSG,@TYPE,@LIST)",
"delete from Profile where idartifact=CURRENT_ARTIFACT",
"insert into Profile values (6,CURRENT_ARTIFACT,1)"
]
}
},
"7": {
"9": {
"guard": "select true from Answered where artifact=CURRENT_ARTIFACT and id=6",
"actions": [
"delete from Task where artifact=CURRENT_ARTIFACT",
"select @TEMPLATE:=''",
"select @TITLE:='Multiple questions at once, with multiple answers'",
"select @CHECKER:=NULL",
"select @CHECKERMSG:='Please toggle a button'",
"select @LIST:='select idtask as id,value as text from Answer where user=SESSION_USER and idtask=3'",
"select @ANS:='select id, id as value, text,class,false as request_feedback from AnswerButton'",
"select @TYPE:=5",
"select @TASKID:=7",
"select @DESCRIPTION:=@TITLE",
"insert into Task(id,artifact,title,description,body,checker,checkermsg,type,arg1,arg2) values (@TASKID,CURRENT_ARTIFACT,@TITLE,@DESCRIPTION,@TEMPLATE,@CHECKER,@CHECKERMSG,@TYPE,@LIST,@ANS)",
"delete from Profile where idartifact=CURRENT_ARTIFACT",
"insert into Profile values (7,CURRENT_ARTIFACT,1)"
]
}
},
"9": {
"10": {
"guard": "select true from Answered where artifact=CURRENT_ARTIFACT and id=7",
"actions": [
"delete from Task where artifact=CURRENT_ARTIFACT",
"select @TEMPLATE:='Your Headwork Basics skill is skyrocketing!'",
"select @TITLE:='Congratulations!'",
"select @CHECKER:=NULL",
"select @CHECKERMSG:=NULL",
"select @TYPE:=0",
"insert into Task(id,artifact,title,description,body,checker,checkermsg,type) values (9,CURRENT_ARTIFACT,'demo',@TITLE,@TEMPLATE,@CHECKER,@CHECKERMSG,@TYPE)",
"delete from Profile where idartifact=CURRENT_ARTIFACT",
"insert into Profile values (9,CURRENT_ARTIFACT,1)"
]
}
},
"10":{
"100": {
"guard": "select true from Answered where artifact=CURRENT_ARTIFACT and id=9",
"actions": [
"delete from Task where artifact=CURRENT_ARTIFACT",
"delete from Profile where idartifact=CURRENT_ARTIFACT",
"update Skills set level=level+20 where iduser=SESSION_USER and idskill=1004"
"delete from Profile where idartifact=CURRENT_ARTIFACT"
]
}
},
"100":{}
"6":{}
}
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment