Skip to content
This repository was archived by the owner on Mar 29, 2026. It is now read-only.
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
ff410dc
add badges to readme
plop91 Mar 24, 2022
4a71ca5
First fully functional build
plop91 Mar 27, 2022
6748334
clean up database handling, add first usage tracker and clean up fun…
plop91 Mar 28, 2022
63bbbda
Added parser shell
jacob-austin Mar 29, 2022
3ce38f0
Converted s2t tests to wav
JTucker2000 Mar 29, 2022
fe9fcac
Update discord.test.js
plop91 Mar 29, 2022
3d406ae
Merge branch 'main' of https://github.com/plop91/Discord-Virtual-Assi…
plop91 Mar 29, 2022
188b460
Fixed s2t tests
JTucker2000 Mar 29, 2022
d5c81cd
Merge branch 'main' of https://github.com/plop91/Discord-Virtual-Assi…
JTucker2000 Mar 29, 2022
e0d1236
Update DiscordVirtualAssistant.yml
plop91 Mar 29, 2022
e82b94e
Fixed typo
JTucker2000 Mar 29, 2022
b712d3e
Figure generation
plop91 Mar 29, 2022
ee8b7c5
Cleanup pass #1
plop91 Mar 29, 2022
5fb3683
Changed parser functionality and tests
jacob-austin Mar 29, 2022
c96408c
Merge branch 'main' of https://github.com/plop91/Discord-Virtual-Assi…
jacob-austin Mar 29, 2022
f809e01
Added 3 more s2t tests
JTucker2000 Mar 29, 2022
72e5c7e
Fixed test that passed sometimes, added empty text and female voice t…
Mar 29, 2022
a5fbc2e
Merge remote-tracking branch 'origin/main'
Mar 29, 2022
29732de
Fixed typos
jacob-austin Mar 29, 2022
5dbc704
Merge branch 'main' of https://github.com/plop91/Discord-Virtual-Assi…
jacob-austin Mar 29, 2022
b0cdf12
Update generate_figures.py
plop91 Mar 29, 2022
5162c9e
add additional command_usage data collection
plop91 Mar 30, 2022
7f14cf9
Update README.md
nickmiceli4 Mar 30, 2022
9da6666
Update README.md
nickmiceli4 Mar 30, 2022
e600202
demo update
plop91 Apr 27, 2022
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .github/workflows/DiscordVirtualAssistant.yml
Original file line number Diff line number Diff line change
Expand Up @@ -33,3 +33,4 @@ jobs:
env:
PRIVATE_KEY: ${{ secrets.PRIVATE_KEY }}
CLIENT_EMAIL: ${{ secrets.CLIENT_EMAIL }}
DISCORD_TOKEN: ${{ secrets.DISCORD_TOKEN }}
4 changes: 3 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -137,4 +137,6 @@ node_modules/
response.mp3
config.json
recordings/
GoogleServiceAccount.json
GoogleServiceAccount.json
token.txt
scripts/figures/*.png
194 changes: 96 additions & 98 deletions README.md

Large diffs are not rendered by default.

85 changes: 72 additions & 13 deletions index.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,46 +6,105 @@
@Description: Main file for program.

@Changelog:
3/19/2022 IS:Convert main loop into async function and add sleep function.
2/25/2022 IS:Added import statement for config file and import for environmental variables as needed.
2/19/2022 IS:Added import statements and basic operation.
3/19/2022 IS: Add audio conversion with ffmpeg.
3/19/2022 IS: Convert main loop into async function and add sleep function.
2/25/2022 IS: Added import statement for config file and import for environmental variables as needed.
2/19/2022 IS: Added import statements and basic operation.
*/
// Discord handler
const DiscordHandler = require('./src/discord');
const Parser = require('./src/parser');
const S2T = require('./src/s2t');
const T2S = require('./src/t2s');
const { execSync } = require('child_process');

const discordclient = new DiscordHandler();
const parser = new Parser(discordclient);
const discord_client = new DiscordHandler();
const parser = new Parser(discord_client);
const speech2text = new S2T();
const text2speech = new T2S();

/**
* Helper function, sleeps for x ms.
* @param ms miliseconds to sleep
* @param ms {int} Milliseconds to sleep
*/
function sleep(ms) {
return new Promise((resolve) => {
setTimeout(resolve, ms);
});
}

/**
* Use ffmpeg to convert audio from signed-16 bit, little endian, 48000hz, 2 channel audio to WAV
* @param audio {string} File name of audio file
* @returns {string} New audio filename
*/
function convert_audio(audio) {
const new_filename = audio.slice(0, -4) + '.wav';
console.log('audio conversion has started');
// use ffmpeg to convert signed-16 bit, little endian, 48000hz, 2 channel audio to WAV
const command = 'ffmpeg -f s16le -ar 48k -ac 2 -i ' + audio + ' ' + new_filename;
console.log(command);
execSync(command);
console.log('audio conversion has ended');
return new_filename;
}

discordclient.login().then(async () => {
let cont = true;
discord_client.login().then(async () => {
const cont = true;
while (cont) {
// if the discord client has audio ready to process
if (discordclient.audio_ready) {
if (discord_client.audio_status) {
let audio = await discord_client.audio_clip;
await sleep(1);
audio = convert_audio(audio);

// transcribe the audio using the speech to text module
const transcript = await speech2text.transcribe(discordclient.audio_clip);
const transcript = await speech2text.transcribe(audio);

console.log('Transcript:' + transcript);

// Parse the transcript and preform actions
const status = parser.parse(transcript);

if (!status) {
cont = false;
let test = 'none';
switch (status) {
case 'Played file':
test = 'play';
break;
case 'Stated time':
test = 'time';
break;
case 'Stated weather':
test = 'weather';
break;
case 'Banned user':
test = 'ban';
break;
case 'DMed user':
test = 'dm';
break;
case 'no command found':
test = 'none';
break;
case 'echoed command':
test = 'echo';
break;
}

await discord_client.pool.getConnection()
.then (conn => {
conn.query('USE dva');
conn.query('REPLACE INTO command_usage VALUES (?)', [test]);
return conn.release();
});

// await text2speech.convert(status);

await discord_client.play('response.mp3');
}
await sleep(100);
}
},
).finally(() => {
discordclient.logout().then(() => console.log('Bot shutdown successfully'));
discord_client.logout().then(() => console.log('Bot shutdown successfully'));
});
17 changes: 17 additions & 0 deletions scripts/figures/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
# Figures

## Instructions

### Installation
Figure generation is handled by python if you do not have a python interpreter or the pip package manager they can be downloaded [here](https://www.python.org/downloads/)
1. install required python packages
```shell
python -m pip install -r requirements.txt
```
2. Figure generation requires database access, if you haven't setup database environmental variables please refer to the main README for instructions
### Usage
To run figure generation:
```shell
python generate_figures.py
```
This will save and display a graph which represents the usage of the record function over time.
110 changes: 110 additions & 0 deletions scripts/figures/generate_figures.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,110 @@
import mariadb
import sys
import pandas as pd
import matplotlib.pyplot as plt
import matplotlib.dates as mdates
import os

"""
@Project: Discord Virtual Assistant
@Title: generate_figures.py
@Authors: Ian Sodersjerna, Jacob Austin, Jonathan Tucker, Nick Miceli
@Created: 2/19/2022
@Description: Creates figures to track usage of DVA

@Changelog:
3/29/2022 IS: Basic database connection, data processing, and figure generation
"""

try:
conn = mariadb.connect(
user=os.environ.get('DVA_DATABASE_USER'),
password=os.environ.get('DVA_DATABASE_PASSWORD'),
host=os.environ.get('DVA_DATABASE_HOST'),
database="dva"

)
except mariadb.Error as e:
print(f"Error connecting to MariaDB Platform: {e}")
sys.exit(1)

# Get Cursor
cur = conn.cursor()

cur.execute("SELECT time FROM record_usage")

dates = []
for t in cur:
dates.append(t[0].date())

usage_per_day = []
while len(dates) > 0:
count = 0
d0 = dates[0]

# count occurrences of d0
for d in dates:
if d == d0:
count += 1

# remove all occurrences of d0
dates = [i for i in dates if i != d0]

usage_per_day.append((d0, count))

usage_per_day.sort()

day, usage = zip(*usage_per_day)

plt.bar(day, usage)
plt.title("record command usage")
plt.xlabel('Days')
plt.xticks(rotation='vertical')

plt.gca().xaxis.set_major_formatter(mdates.DateFormatter('%m/%d/%Y'))
plt.gca().xaxis.set_major_locator(mdates.DayLocator())

plt.ylabel('Usage')

plt.autoscale()
plt.subplots_adjust(bottom=0.25)

plt.savefig("record_usage_figure.png")
plt.show()

cur.execute("SELECT command FROM command_usage")

commands = []
for command in cur:
commands.append(command[0])
commands.sort()

commands_usage = []
while len(commands) > 0:
count = 0
c0 = commands[0]

# count occurrences of d0
for d in commands:
if d == c0:
count += 1

# remove all occurrences of d0
commands = [i for i in commands if i != c0]

commands_usage.append((c0, count))

command, usage = zip(*commands_usage)

plt.bar(command, usage)
plt.title("voice command usage")
plt.xlabel('command')


plt.ylabel('Usage')

plt.autoscale()
# plt.subplots_adjust(bottom=0.25)

plt.savefig("command_usage_figure.png")
plt.show()
3 changes: 3 additions & 0 deletions scripts/figures/requirements.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
matplotlib
pandas
mariadb
Loading