]> Repos - mime-chat/commitdiff
audio renderer v1
authorriqo <hernandeze2@xavier.edu>
Sun, 13 Dec 2020 21:07:06 +0000 (15:07 -0600)
committerriqo <hernandeze2@xavier.edu>
Sun, 13 Dec 2020 21:07:06 +0000 (15:07 -0600)
src/components/input/inputDetails/audioInput.vue
src/components/input/inputItem.vue
src/composables/inputItem/useInputRenderer.ts
src/composables/streamRecorder/useStreamRecorder.ts

index 7626ac784866b7b1033d8d58547bac1e3bbbc344..d82cb280f365e53809c3ccc1060139a2f05b1660 100644 (file)
@@ -3,28 +3,45 @@
   <g id="Group_126" data-name="Group 126" transform="translate(0 0)">
     <rect id="Rectangle_478" data-name="Rectangle 478" :width="bubbleWidth" height="34" rx="10" transform="translate(0 0)" fill="#b9b9b9"/>
     <g id="Group_125" data-name="Group 125">
-      <!-- <path id="Path_328" data-name="Path 328" d="M0,25v-10" transform="translate(10 0)" fill="none" stroke="#000" stroke-linecap="round" stroke-width="1.5"/>
+
+      <path v-for="(path, index) in paths" 
+        :key="index"
+        :id="path.id" 
+        :data-name="path.name" 
+        :d="path.d" 
+        :transform="path.transform" 
+        fill="none" 
+        stroke="#000" 
+        stroke-linecap="round" 
+        stroke-width="1.5"
+      />
+
+<!--       <path id="Path_328" data-name="Path 328" d="M0,25v-10" transform="translate(10 0)" fill="none" stroke="#000" stroke-linecap="round" stroke-width="1.5"/>
       <path id="Path_328" data-name="Path 328" d="M0,25v-15" transform="translate(15 0)" fill="none" stroke="#000" stroke-linecap="round" stroke-width="1.5"/>
       <path id="Path_328" data-name="Path 328" d="M0,25v-20" transform="translate(20 0)" fill="none" stroke="#000" stroke-linecap="round" stroke-width="1.5"/>
 
       <path id="Path_328" data-name="Path 328" d="M0,25v-15" transform="translate(25 0)" fill="none" stroke="#000" stroke-linecap="round" stroke-width="1.5"/>
       <path id="Path_328" data-name="Path 328" d="M0,25v-10" transform="translate(30 0)" fill="none" stroke="#000" stroke-linecap="round" stroke-width="1.5"/>
 
-      <path id="Path_328" data-name="Path 328" d="M0,25v-5" transform="translate(120 0)" fill="none" stroke="#000" stroke-linecap="round" stroke-width="1.5"/> -->
-    </g>
+      <path id="Path_328" data-name="Path 328" d="M0,25v-5" transform="translate(120 0)" fill="none" stroke="#000" stroke-linecap="round" stroke-width="1.5"/>
-->    </g>
   </g>
 </svg>
 
 </template>
 
 <script lang="ts">
-import { defineComponent, computed } from 'vue'
+import { defineComponent, computed, ref } from 'vue'
 export default defineComponent ({
   name: 'AudioInput',
   props: {
-    bubbleWidth: Number
+    bubbleWidth: Number,
+    paths: Array
   },
   setup(props){
+
+    // need audioPath type/interface
+
     const center = computed(() => {
       if (props.bubbleWidth) {
         return 175 - props.bubbleWidth / 2;
index 16942c4da76d988a93f6f24b704a5ade2108c566..c85a9cd70a2c03588da92d8fa0685db1f9b6f7c0 100644 (file)
@@ -2,6 +2,7 @@
   <audio-input 
     v-if="renderAudio" 
     :bubbleWidth="reactiveWidth" 
+    :paths="paths"
   />
   <text-input 
     v-else 
@@ -20,13 +21,19 @@ export default defineComponent({
   components: {TextInput, AudioInput},
   setup() {
 
-    const { input, renderAudio, reactiveWidth, textInputXoffset } = useInputRenderer();
+    const { 
+      input,
+      renderAudio, 
+      reactiveWidth, 
+      textInputXoffset,
+      paths } = useInputRenderer();
 
     return {
       input,
       textInputXoffset,
       renderAudio,
-      reactiveWidth
+      reactiveWidth,
+      paths
     }
   }
 })
index 34a797bf07db5f1f2bd1a51396fb2d3e84d90634..a6968db07d39ac6267f315779c2c8b555fb7645c 100644 (file)
@@ -10,17 +10,20 @@ export default function useInputRenderer() {
   // program ref varaiables
   const renderAudio = ref(false);
   const reactiveWidth = ref(10);
+  const pathOffset = ref(10);
+  const paths = ref([]);
   
   // get input feedback & handler function
   const { keyDownHandler, input } = useKeyDownHandler();
   // get text Offset and & textRender function
   const { textInputXoffset, renderTextInput } = useTextInput(input, renderAudio);
 
-  // why do we have audio stuff here 
-  let stream: any;
-  const {handleStream} = useStreamRecorder(renderAudio)
+  // why do we have audio stuff here ?
+  let stream: MediaStream;
+  const {renderStream} = useStreamRecorder(renderAudio)
   onMounted(async () => {
-    stream = await useMediaStream()
+    const streamRes = await useMediaStream()
+    stream = streamRes.stream;
   })
 
   // stop stream recording on space keyup event
@@ -30,6 +33,7 @@ export default function useInputRenderer() {
       renderAudio.value = false;
       input.value = "";
       reactiveWidth.value = 10;
+      pathOffset.value = 10;
     }
   }
 
@@ -54,7 +58,7 @@ export default function useInputRenderer() {
     if (input === " " && renderAudio.value === false) {
       console.log("record");
       renderAudio.value = true;
-      handleStream(stream.stream, reactiveWidth);
+      renderStream(stream, reactiveWidth, pathOffset, paths);
       return;
     }           
     renderTextInput();
@@ -64,7 +68,8 @@ export default function useInputRenderer() {
     input,
     renderAudio,
     reactiveWidth,
-    textInputXoffset
+    textInputXoffset,
+    paths
   }
 
 }
\ No newline at end of file
index c53d3d4ae3f640dfcc1894ac0ad9cff580317503..1f625ede8cf60e7035e0977c93b58f32ef7abb71 100644 (file)
@@ -1,23 +1,14 @@
-import { watch, ref, inject } from "vue";
-import useAudioRenderer from "@/composables/audioRenderer/useAudioRenderer";
-import AnimeFunc from "@/types/animejs/index";
-export default function useStreamRecorder(render: any) {
+import {Ref} from '@/types/vueRef/index';
+import { ref } from 'vue';
+export default function useStreamRecorder(render: Ref<boolean>) {
     let streamRecorder: MediaRecorder;
     const chunks: Blob[] = [];
 
-    // imports animejs safely
-    let anime: AnimeFunc;
-    const animeInject: AnimeFunc | undefined = inject("animejs");
-    if (animeInject) anime = animeInject;
-
-    window.AudioContext = window.AudioContext;
-    let audio_context = new AudioContext();
-    const analyzer = audio_context.createAnalyser();
+    // window.AudioContext = window.AudioContext;
+    const audioContext = new AudioContext();
+    const analyzer = audioContext.createAnalyser();
     analyzer.fftSize = 2048;
-    var bufferLengthAlt = analyzer.frequencyBinCount;
-    var dataArrayAlt = new Uint8Array(bufferLengthAlt);
-
-    let source: any;
+    const dataArray = new Uint8Array(analyzer.frequencyBinCount);
 
     const initRecorder = async () => {
         const stream = await navigator.mediaDevices.getUserMedia({ audio: true });
@@ -32,36 +23,76 @@ export default function useStreamRecorder(render: any) {
         }
     }
 
-    function visualize(w: any) {
+    interface AmplitudePath {
+        id: string;
+        name: string;
+        d: string;
+        transform: string;
+    }
+
+    const createAudioPath = (a: number, offset: number) => {
+        const identifier = `path_${offset}`
+        const path: AmplitudePath = {
+           id: identifier,
+           name: identifier,
+           d: `M0,25v${-a}`,
+           transform: `translate(${offset} 0)`
+        }
+         return path;
+    }
+
+    const xInitial = 24;
+    const xFinal = 640;
+
+    function visualize(w: Ref<number>, p: Ref<number>, paths: Ref<any>) {
 
-        function drawAlt() {
+        const amplitude = () => {
+            const dataView = dataArray.slice(xInitial, xFinal);
+            const sum = dataView.reduce((a, b) => a + b);
+            const average = sum / dataView.length;
+            const scaled = average * 0.45; 
+            return scaled;
+        }
+
+        function draw() {
             if (!render.value) {
                return;
             }
-            const drawVisual = requestAnimationFrame(drawAlt);
-            analyzer.getByteTimeDomainData(dataArrayAlt);
+            requestAnimationFrame(draw);
+            analyzer.getByteFrequencyData(dataArray);
 
             // max-width
-            if (w.value === 190) {
+            if (w.value === 300) {
                 return;
             }
 
-            // increase width and center as time passes
-            w.value++;
-            const center = 175 -  w.value / 2;
-            // w.value= center;
+            // increase width as time passes
+
+            // get amplitude
+            const a = amplitude();
+
+            if (a > 1) {
+
+                w.value++;
+                p.value += 5;
+                console.log(a)
+                const path = createAudioPath(a, p.value);
+                paths.value.push(path)
+            }
+
+            // create path item
         }
-        drawAlt();
+        draw();
     }
 
-    function handleStream(s: MediaStream, w: any) {
-        source = audio_context.createMediaStreamSource(s);
+    function renderStream(s: MediaStream, w: Ref<number>, pathOffset: Ref<number>, paths: Ref<any>) {
+        const source = audioContext.createMediaStreamSource(s);
         source.connect(analyzer);
-        visualize(w);
+        visualize(w, pathOffset, paths);
     }
 
     return {
         initRecorder,
-        handleStream
+        renderStream
     }
 }