diff --git a/ISSUE 35 - Audio API tests/audioWorkletProcessor.js b/ISSUE 35 - Audio API tests/audioWorkletProcessor.js
new file mode 100644
index 0000000000000000000000000000000000000000..6d520211d0c2a5fcedb4e2bda3a91389976bfa6b
--- /dev/null
+++ b/ISSUE 35 - Audio API tests/audioWorkletProcessor.js	
@@ -0,0 +1,112 @@
+class Processor extends AudioWorkletProcessor {
+    constructor() {
+      super();
+      this.port.onmessage = e => {
+        console.log("e data ", e.data)
+        if (e.data.type === 'recv-audio-queue') {
+          this.is_paused = e.data.is_paused;
+          this.head = e.data.head;
+          this.tail = e.data.tail;
+          this.can_write = e.data.can_write;
+          this.volume = e.data.volume;
+          this.is_muted = e.data.is_muted;
+          this.storage = e.data.storage;
+        } else {
+          throw 'unexpected.';
+        }
+      };
+    }
+     
+    process(inputs, outputs, parameters) {
+      const output = outputs[0];
+      const nbChannels = output.length;
+      const nbSamples = output[0].length;
+      if (this.head.buffer.byteLength == 0) {
+        throw new Error('wasmMemory grew');
+      }
+      var head = Atomics.load(this.head, 0) / 4;
+      var tail = Atomics.load(this.tail, 0) / 4;
+      var i = 0;
+      //var volume = Atomics.load(this.volume, 0) / 100;
+      if (Atomics.load(this.is_paused, 0) != 0 || Atomics.load(this.is_muted, 0) != 0) {
+        volume = 0;
+      }
+      while (tail != head && i < nbSamples)
+      {
+        for (let c = 0; c < nbChannels; c++) {
+          output[c][i] = this.storage[tail];
+          // output[c][i] = Math.random() * 2 - 1;
+          //output[c][i] = this.storage[tail] * volume;
+          tail++;
+          if (tail == this.storage.length) {
+            tail = 0;
+          }
+        }
+        i++;
+      }
+      Atomics.store(this.tail, 0, tail * 4);
+      //Atomics.store(this.can_write, 0, 1);
+      //Atomics.notify(this.can_write, 0);  
+      return true;
+    }
+    
+    
+    
+    // process (inputs, outputs, parameters) {
+    //   const output = outputs[0]
+
+    //   for (let i = 0; i < output[0].length; i++) {      
+    //     output[0][i] = Math.random() * 2 - 1;
+        
+    //     this.step++;
+    //   }
+    //   return true
+    // }
+  }
+
+//   class SineProcessor extends AudioWorkletProcessor {
+
+//       constructor()
+//       {
+//           super();
+//           this.step = 7500;
+//           console.log(Math.sin(2 * Math.PI * this.step));
+//           this.port.onmessage = e => {
+//             if (e.data.type === 'recv-audio-queue') {
+//               this.is_paused = e.data.is_paused;
+//               this.head = e.data.head;
+//               this.tail = e.data.tail;
+//               this.can_write = e.data.can_write;
+//               this.volume = e.data.volume;
+//               this.is_muted = e.data.is_muted;
+//               this.storage = e.data.storage;
+//             } else {
+//               throw 'unexpected.';
+//             }
+//           };
+//       }
+
+//       process (inputs, outputs, parameters) {
+//           const output = outputs[0]
+//           console.log("nbChannels:", output.length)
+
+//             console.log('NbSamble: ', output[0].length)
+
+//           for (let i = 0; i < output[0].length; i++) {      
+//             output[0][i] = Math.sin((2 * Math.PI * this.step * 440) / 44100);
+            
+//             this.step++;
+//             }
+
+//            output.forEach(channel => {
+//              for (let i = 0; i < channel.length; i++) {      
+//                channel[i] = Math.sin((2 * Math.PI * this.step * 440) / 44100);
+              
+//                this.step++;
+//              }
+//            })
+//           return true
+//       }
+//   }
+
+  registerProcessor('worklet-processor', Processor);
\ No newline at end of file
diff --git a/ISSUE 35 - Audio API tests/index.html b/ISSUE 35 - Audio API tests/index.html
new file mode 100644
index 0000000000000000000000000000000000000000..9e52c6d489799013517b630366589e8c2768df8b
--- /dev/null
+++ b/ISSUE 35 - Audio API tests/index.html	
@@ -0,0 +1,3 @@
+<button id="button">PLAY</button>
+
+<script src="audio.js"></script>
\ No newline at end of file
diff --git a/ISSUE 35 - Audio API tests/main.c b/ISSUE 35 - Audio API tests/main.c
new file mode 100644
index 0000000000000000000000000000000000000000..eb2c400f74ec21794fcddb6458cfbbab27d20940
--- /dev/null
+++ b/ISSUE 35 - Audio API tests/main.c	
@@ -0,0 +1,132 @@
+#include <stdint.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <stdbool.h>
+#include <emscripten.h>
+
+#include "main.h"
+#include <assert.h>
+
+#define STORAGE_SIZE 1024 * 1024
+
+extern sound_buffer_t *init(int sampleRate, int nbChannels, bool aloneMemory);
+
+int push(float *buffer, void *user_data, size_t data_size)
+{
+    printf("PUSH\n");
+    sound_buffer_t *sab = (sound_buffer_t*)user_data;
+
+    float *sab_view = sab->storage;
+    int32_t head = sab->head;
+    int32_t tail = sab->tail;
+    int32_t volume = sab->volume;
+    if (!sab->can_write)
+    {
+        return -1;
+    }
+    printf("%d\n", sab->head);
+    // TODO: check that we do not write on unconsumed data.
+    if (head + data_size > STORAGE_SIZE) {
+    // Copy the part of the data at the buffer end
+        int32_t data_size_copy_end = STORAGE_SIZE - head;
+        memcpy(sab_view + head, buffer, data_size_copy_end);
+        head = 0;
+
+        // Copy the part of the data at the buffer start
+        int32_t data_size_copy_start = data_size - data_size_copy_end;
+        memcpy(sab_view + head, buffer, data_size_copy_start);
+        head = data_size_copy_start;
+    }
+    else {
+        memcpy(sab_view + head, buffer, data_size);
+        head += data_size;
+    }
+    sab->head = head;
+    printf("SAB HEAD: %d\n", sab->head);
+    return 0;  // return success to indicate successful push.
+}
+
+int is_pushed(void *result)
+{
+    if (result == NULL)
+        return 1;
+    return 0;
+}
+
+int main()
+{
+    FILE *fd = fopen( "daft.raw", "r" );
+    if (fd == NULL)
+    {
+        return -1;
+    }
+    
+    sound_buffer_t *sound_buffer = init(44100, 2, true);
+
+	printf("coucou\n");
+
+    /* Go to the end of the file. */
+    if (fseek(fd, 0L, SEEK_END) == 0) {
+        /* Get the size of the file. */
+        long bufsize = ftell(fd);
+        if (bufsize == -1) { /* Error */ }
+
+        // /* Allocate our buffer to that size. */
+        // uint16_t *source = malloc(sizeof(uint16_t) * (bufsize + 1));
+
+        /* Go back to the start of the file. */
+        if (fseek(fd, 0L, SEEK_SET) != 0) { /* Error */ }
+
+        // /* Read the entire file into memory. */
+        // size_t newLen = fread(source, sizeof(uint16_t), bufsize, fd);
+        // if ( ferror( fd ) != 0 ) {
+        //     fputs("Error reading file", stderr);
+        // } 
+        // else {
+        //     source[newLen++] = '\0'; /* Just to be safe. */
+        // }
+
+        /* Loop to push buffers from source */
+        float *buffer = malloc(sizeof(float) * STORAGE_SIZE);
+        
+        long curPos = 0;
+
+        while(curPos < bufsize) {
+            /* Fill the buffer */
+            printf("BUFFER SIZE: %lu\n", bufsize);
+            size_t read_bytes = fread(buffer, STORAGE_SIZE, 1, fd) * STORAGE_SIZE;
+            if (read_bytes == 0)
+            {
+                printf("Quitting loop\n");
+                if (ferror(fd) != 0)
+                {
+                    printf("ERROR\n");
+                }
+                else
+                {
+                    printf("Reached EOF\n");
+                }
+                break;
+            }
+
+            /* Push the buffer in the worklet */
+
+            if (push(buffer, sound_buffer, read_bytes) != 0) { printf("Error pushing\n"); }
+
+            // /* Offset the file pointer by BUFFER_SIZE */
+            // if (fseek(source, STORAGE_SIZE, SEEK_CUR) != 0) { /* Error */ }
+
+            curPos += read_bytes;
+        }
+
+        free(buffer);
+    }
+    fclose(fd);
+
+    // Nous devons passer un pointeur vers soundbuffer poour l'init
+    // On alloue une partie de la mémoire d'un côté et les metadatas de l'autre mais rine ne se met à jour
+    // Revoir les mallocs
+
+    return 0;
+}
\ No newline at end of file
diff --git a/ISSUE 35 - Audio API tests/main.h b/ISSUE 35 - Audio API tests/main.h
new file mode 100644
index 0000000000000000000000000000000000000000..399d3457c5c0f21b03ece4358dcfb08a2a19d3fa
--- /dev/null
+++ b/ISSUE 35 - Audio API tests/main.h	
@@ -0,0 +1,13 @@
+#pragma once
+
+#define STORAGE_SIZE 1024 * 1024
+
+typedef struct sound_buffer_t {
+    int32_t head;
+    int32_t tail;
+    int32_t volume;
+    float storage[STORAGE_SIZE];
+    int32_t is_paused;
+    int32_t can_write;
+    int32_t is_muted;
+} sound_buffer_t;
\ No newline at end of file
diff --git a/ISSUE 35 - Audio API tests/sine.js b/ISSUE 35 - Audio API tests/sine.js
new file mode 100644
index 0000000000000000000000000000000000000000..00d731928f3b545121a334cfa11de5f5e6544699
--- /dev/null
+++ b/ISSUE 35 - Audio API tests/sine.js	
@@ -0,0 +1,98 @@
+const STORAGE_SIZE = 1024 * 1024;
+const STRUCT_SIZE = 28;
+
+mergeInto(LibraryManager.library, {
+  init: function (sampleRate, nbChannels, aloneMemory)
+    {      
+      console.log("INIT");
+      var STORAGE_SIZE = 1024 * 1024;
+      var STRUCT_SIZE = 28;
+
+      var audioCtx = new AudioContext();
+      audioCtx.sampleRate = sampleRate;
+      audioCtx.suspend();
+
+      if (audioCtx.destination.channelCount < nbChannels) {
+        console.log("Max number of channels of the browser is ", audioCtx.destination.channelCount)
+        nbChannels = audioCtx.destination.channelCount;
+      }
+
+      const playButton = document.getElementById('button')
+
+      playButton.onclick = function() {
+        if(audioCtx.state === 'running') {
+          audioCtx.suspend().then(function() {
+            playButton.textContent = 'Resume context';
+          });
+        } else if(audioCtx.state === 'suspended') {
+          audioCtx.resume().then(function() {
+            playButton.textContent = 'Suspend context';
+          });
+        }
+      }
+        if (aloneMemory) {
+            var soundBufferPtr = Module._malloc(STORAGE_SIZE + STRUCT_SIZE);
+        }
+		
+		var offset = soundBufferPtr;
+          // Needs otimization, be careful with the struct and the offset, and the sizes
+          
+          // Offset : if Int32 -> 32/8 * nmem
+          //          if Int8 -> 8/8 * nmem
+          
+          // Offset here is 0
+      var msg = {};
+		  msg["type"] = "recv-audio-queue";
+      msg["head"] = new Int32Array(wasmMemory.buffer, offset, 1);
+      console.log("Offset @head ", offset);
+      offset += (32 / 8) * 1
+      // here 4 * 1 because 0 + 32/8 * 1
+      msg["tail"] = new Int32Array(wasmMemory.buffer, offset, 1);
+      console.log("Offset @tail ", offset);
+      offset += (32 / 8) * 1
+      // here 4 * 2 because 4 + 32/8 * 1
+      msg["volume"] = new Int32Array(wasmMemory.buffer, offset, 1);
+      console.log("Offset @volume ", offset);
+      offset += (32 / 8) * 1
+      // here 4 * 3 because 8 + 32/8 * 1
+      msg["storage"] = new Float32Array(wasmMemory.buffer, offset, STORAGE_SIZE);
+      console.log("Offset @storage ", offset);
+      offset += (32 / 8) * STORAGE_SIZE
+      // here, 12 + (32/8) * (this.STORAGE_SIZE / 4) = 2097164
+      msg["is_paused"] = new Int32Array(wasmMemory.buffer, offset, 1);
+      console.log("Offset @pause ", offset);
+      offset += (32 / 8) * 1
+      msg["can_write"] = new Int32Array(wasmMemory.buffer, offset, 1)
+      msg["can_write"][0] = 1;
+      console.log("Offset @can_write", offset);
+      offset += (32 / 8) * 1
+      msg["is_muted"] = new Int32Array(wasmMemory.buffer, offset, 1);
+      console.log("Offset @is_muted", offset);
+
+      audioCtx.audioWorklet.addModule('audioWorkletProcessor.js')
+        .then(() => {
+          const node = new AudioWorkletNode(audioCtx, 'worklet-processor', {
+            numberOfInputs: 0,
+            numberOfOutputs: 1,
+            outputChannelCount: [2]
+          });
+          node.connect(audioCtx.destination)
+          console.log('Connected')
+         
+          node["port"].postMessage(msg);   
+        })
+
+      
+        // var blob = this.createAudioWorkletBlob()
+        // var url = URL.createObjectURL(blob)
+
+        // await context.audioWorklet.addModule(url)
+        // .then());
+        // const sineNode = new AudioWorkletNode(context, 'sine')
+        // sineNode.connect(context.destination)
+        // console.log('Connected')
+		return (soundBufferPtr);
+    }
+})
+
+// registerProcessor('sine', SineProcessor)
\ No newline at end of file
diff --git a/ISSUE 35 - Audio API tests/snare.raw b/ISSUE 35 - Audio API tests/snare.raw
new file mode 100644
index 0000000000000000000000000000000000000000..f97647bd3318c2e5b30595c78a7731ccc80b26f1
Binary files /dev/null and b/ISSUE 35 - Audio API tests/snare.raw differ
diff --git a/lib/module-loader.js b/lib/module-loader.js
index 1e89cc4e066b681e8e7e6354643e95d3ec92c07e..9ac5fa15cab9142fcdc0fede1b8ac27d7200a5e8 100644
--- a/lib/module-loader.js
+++ b/lib/module-loader.js
@@ -2,9 +2,14 @@ var statusElement = document.getElementById('status');
 var progressElement = document.getElementById('progress');
 var spinnerElement = document.getElementById('spinner');
 
+// This should be set to true once the user clicks on the canvas for the first time
+var was_clicked = false;
+
 var VlcModuleExt = {
-  preRun: [],
-  postRun: [ function() {
+  preRun: [ function() {
+    window.display_overlay = true
+  }],
+  onRuntimeInitialized: function() {
     // This should run after the wasm module is instantiated
     // before, the Pthread object won't be available
     VlcModuleExt.PThread.receiveObjectTransfer = function (data) {
@@ -14,7 +19,7 @@ var VlcModuleExt = {
       });
       window.dispatchEvent(event);
     };
-  }],
+  },
 
   print: (function() {
     var element = document.getElementById('output');
@@ -48,16 +53,21 @@ var VlcModuleExt = {
 
     overlay.addEventListener('click', (event) => {
       window.on_overlay_click(overlay, event);
-    });
 
-    // Create a global window.display_overlay variable to track whether
-    // the UI should be visible - see update_overlay function
-    window.display_overlay = true,
-    overlay.addEventListener('mouseenter', e => {
-      window.display_overlay = true;
-    });
-    overlay.addEventListener('mouseleave', e => {
-      window.display_overlay = false;
+      // Should only add EventListeners once
+      if (was_clicked === false) {
+        // Create a global window.display_overlay variable to track whether
+        // the UI should be visible - see update_overlay function
+        overlay.addEventListener('mouseenter', e => {
+          window.display_overlay = true;
+        });
+        overlay.addEventListener('mouseleave', e => {
+          window.display_overlay = false;
+        });
+
+        // Setting to true after first click on the canvas
+        was_clicked = true;
+      }
     });
 
     return canvas;