Skip to content

Commit

Permalink
Initial commit
Browse files Browse the repository at this point in the history
  • Loading branch information
Ash Martian committed Nov 10, 2022
0 parents commit 4cf0543
Show file tree
Hide file tree
Showing 26 changed files with 3,083 additions and 0 deletions.
24 changes: 24 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
# Logs
logs
*.log
npm-debug.log*
yarn-debug.log*
yarn-error.log*
pnpm-debug.log*
lerna-debug.log*

node_modules
dist
dist-ssr
*.local

# Editor directories and files
.vscode/*
!.vscode/extensions.json
.idea
.DS_Store
*.suo
*.ntvs*
*.njsproj
*.sln
*.sw?
13 changes: 13 additions & 0 deletions index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<link rel="icon" type="image/svg+xml" href="/vite.svg" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Vite + React + TS</title>
</head>
<body>
<div id="root"></div>
<script type="module" src="/src/main.tsx"></script>
</body>
</html>
1,968 changes: 1,968 additions & 0 deletions package-lock.json

Large diffs are not rendered by default.

31 changes: 31 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
{
"name": "voice-feedback",
"private": true,
"version": "0.0.0",
"type": "module",
"scripts": {
"dev": "vite",
"build": "vite build",
"preview": "vite preview"
},
"dependencies": {
"@emotion/react": "^11.10.5",
"@mantine/core": "^5.7.1",
"@mantine/hooks": "^5.7.1",
"@tensorflow/tfjs": "^4.0.0",
"browser": "^0.2.6",
"mic-check": "^1.1.0",
"react": "^18.2.0",
"react-dom": "^18.2.0",
"react-icons": "^4.6.0",
"react-tensorflow": "^2.2.0",
"usehooks-ts": "^2.9.1"
},
"devDependencies": {
"@types/react": "^18.0.24",
"@types/react-dom": "^18.0.8",
"@vitejs/plugin-react": "^2.2.0",
"typescript": "^4.6.4",
"vite": "^3.2.3"
}
}
Binary file added public/model/group1-shard1of1.bin
Binary file not shown.
1 change: 1 addition & 0 deletions public/model/model.json
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{"format": "layers-model", "generatedBy": "keras v2.10.0", "convertedBy": "TensorFlow.js Converter v4.0.0", "modelTopology": {"keras_version": "2.10.0", "backend": "tensorflow", "model_config": {"class_name": "Sequential", "config": {"name": "sequential", "layers": [{"class_name": "InputLayer", "config": {"batch_input_shape": [null, 128], "dtype": "float32", "sparse": false, "ragged": false, "name": "dense_input"}}, {"class_name": "Dense", "config": {"name": "dense", "trainable": true, "batch_input_shape": [null, 128], "dtype": "float32", "units": 256, "activation": "linear", "use_bias": true, "kernel_initializer": {"class_name": "GlorotUniform", "config": {"seed": null}}, "bias_initializer": {"class_name": "Zeros", "config": {}}, "kernel_regularizer": null, "bias_regularizer": null, "activity_regularizer": null, "kernel_constraint": null, "bias_constraint": null}}, {"class_name": "Dropout", "config": {"name": "dropout", "trainable": true, "dtype": "float32", "rate": 0.3, "noise_shape": null, "seed": null}}, {"class_name": "Dense", "config": {"name": "dense_1", "trainable": true, "dtype": "float32", "units": 256, "activation": "relu", "use_bias": true, "kernel_initializer": {"class_name": "GlorotUniform", "config": {"seed": null}}, "bias_initializer": {"class_name": "Zeros", "config": {}}, "kernel_regularizer": null, "bias_regularizer": null, "activity_regularizer": null, "kernel_constraint": null, "bias_constraint": null}}, {"class_name": "Dropout", "config": {"name": "dropout_1", "trainable": true, "dtype": "float32", "rate": 0.3, "noise_shape": null, "seed": null}}, {"class_name": "Dense", "config": {"name": "dense_2", "trainable": true, "dtype": "float32", "units": 128, "activation": "relu", "use_bias": true, "kernel_initializer": {"class_name": "GlorotUniform", "config": {"seed": null}}, "bias_initializer": {"class_name": "Zeros", "config": {}}, "kernel_regularizer": null, "bias_regularizer": null, "activity_regularizer": null, "kernel_constraint": null, "bias_constraint": null}}, {"class_name": "Dropout", "config": {"name": "dropout_2", "trainable": true, "dtype": "float32", "rate": 0.3, "noise_shape": null, "seed": null}}, {"class_name": "Dense", "config": {"name": "dense_3", "trainable": true, "dtype": "float32", "units": 128, "activation": "relu", "use_bias": true, "kernel_initializer": {"class_name": "GlorotUniform", "config": {"seed": null}}, "bias_initializer": {"class_name": "Zeros", "config": {}}, "kernel_regularizer": null, "bias_regularizer": null, "activity_regularizer": null, "kernel_constraint": null, "bias_constraint": null}}, {"class_name": "Dropout", "config": {"name": "dropout_3", "trainable": true, "dtype": "float32", "rate": 0.3, "noise_shape": null, "seed": null}}, {"class_name": "Dense", "config": {"name": "dense_4", "trainable": true, "dtype": "float32", "units": 64, "activation": "relu", "use_bias": true, "kernel_initializer": {"class_name": "GlorotUniform", "config": {"seed": null}}, "bias_initializer": {"class_name": "Zeros", "config": {}}, "kernel_regularizer": null, "bias_regularizer": null, "activity_regularizer": null, "kernel_constraint": null, "bias_constraint": null}}, {"class_name": "Dropout", "config": {"name": "dropout_4", "trainable": true, "dtype": "float32", "rate": 0.3, "noise_shape": null, "seed": null}}, {"class_name": "Dense", "config": {"name": "dense_5", "trainable": true, "dtype": "float32", "units": 1, "activation": "sigmoid", "use_bias": true, "kernel_initializer": {"class_name": "GlorotUniform", "config": {"seed": null}}, "bias_initializer": {"class_name": "Zeros", "config": {}}, "kernel_regularizer": null, "bias_regularizer": null, "activity_regularizer": null, "kernel_constraint": null, "bias_constraint": null}}]}}, "training_config": {"loss": "binary_crossentropy", "metrics": ["accuracy"], "loss_weights": null, "sample_weight_mode": null, "weighted_metrics": null, "optimizer_config": {"class_name": "Adam", "config": {"name": "Adam", "learning_rate": 0.0010000000474974513, "decay": 0.0, "beta_1": 0.8999999761581421, "beta_2": 0.9990000128746033, "epsilon": 1e-07, "amsgrad": false}}}}, "weightsManifest": [{"paths": ["group1-shard1of1.bin"], "weights": [{"name": "dense/kernel", "shape": [128, 256], "dtype": "float32"}, {"name": "dense/bias", "shape": [256], "dtype": "float32"}, {"name": "dense_1/kernel", "shape": [256, 256], "dtype": "float32"}, {"name": "dense_1/bias", "shape": [256], "dtype": "float32"}, {"name": "dense_2/kernel", "shape": [256, 128], "dtype": "float32"}, {"name": "dense_2/bias", "shape": [128], "dtype": "float32"}, {"name": "dense_3/kernel", "shape": [128, 128], "dtype": "float32"}, {"name": "dense_3/bias", "shape": [128], "dtype": "float32"}, {"name": "dense_4/kernel", "shape": [128, 64], "dtype": "float32"}, {"name": "dense_4/bias", "shape": [64], "dtype": "float32"}, {"name": "dense_5/kernel", "shape": [64, 1], "dtype": "float32"}, {"name": "dense_5/bias", "shape": [1], "dtype": "float32"}]}]}
1 change: 1 addition & 0 deletions public/vite.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
38 changes: 38 additions & 0 deletions src/App.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
#root {
margin: 0 auto;
text-align: center;
}

.waveform {
width: 100vw;
}

.note {
font-size: 4em;
}

.prediction {
font-size: 2em;
}

.prediction .percent {
font-size: 0.8em;
}

.prediction .gender {
font-weight: bold;
}

/* past-prediction fade out animation 200s */
.past-prediction {
animation: fadeOut 200s;
}

@keyframes fadeOut {
0% {
opacity: 1;
}
100% {
opacity: 0;
}
}
39 changes: 39 additions & 0 deletions src/App.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
import { Button, createStyles } from '@mantine/core';
import Analyze from './components/Analyze'
import { useMediaStream } from './contexts/MediaStreamContext'
import './App.css'
import Note from './components/Note';
import GenderPrediction from './components/GenderPrediction';

const useStyles = createStyles(() => ({
button: {
borderRadius: '8px',
border: '1px solid transparent',
padding: '0.6em 1.2em',
fontWeight: 500,
fontFamily: 'inherit',
backgroundColor: '#1a1a1a',
cursor: 'pointer',
transition: 'border-color 0.25s',
},
}));

function App() {

const { stream, start, stop } = useMediaStream();

const toggleMic = () => stream ? stop() : start();

const { classes } = useStyles();

return (
<div className="App">
<Button className={classes.button} onClick={toggleMic}>{stream ? 'Stop' : 'Start'} Mic</Button>
<Analyze />
<Note />
<GenderPrediction />
</div>
)
}

export default App
1 change: 1 addition & 0 deletions src/assets/react.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
65 changes: 65 additions & 0 deletions src/components/Analyze.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
import {FC, createRef, useEffect } from "react";
import MediaVerification from "./MediaVerification";
import { useAudioAnalyser } from '../contexts/AudioAnalyserContext';


const Analyze: React.FC = () => {
const canvasRef = createRef<HTMLCanvasElement>();
const { analyser } = useAudioAnalyser();

useEffect(() => {
if (!analyser) {
console.log("No analyzer")
return;
}

let raf: number;

const data = new Uint8Array(analyser.frequencyBinCount);

const draw = () => {
raf = requestAnimationFrame(draw);
analyser.getByteTimeDomainData(data);
const canvas = canvasRef.current;
if (canvas) {
const { height, width } = canvas;
const context = canvas.getContext('2d');
let x = 0;
const sliceWidth = (width * 1.0) / data.length;

if (context) {
context.lineWidth = 2;
context.strokeStyle = '#fff';
// context.fillStyle = "rgba(255,255,255,0.2)";
context.clearRect(0, 0, width, height);

context.beginPath();
context.moveTo(0, height / 2);
for (const item of data) {
const y = (item / 255.0) * height;
context.lineTo(x, y);
x += sliceWidth;
}
context.lineTo(x, height / 2);
context.stroke();
}
}
};
draw();


return () => {
cancelAnimationFrame(raf);
}
}, [canvasRef, analyser]);

if (!analyser) {
return <MediaVerification />;
}

return (
<canvas className="waveform" width="1200" height="200" ref={canvasRef} />
);
};

export default Analyze;
Loading

0 comments on commit 4cf0543

Please sign in to comment.