diff --git a/application/static/datasource.html b/application/static/datasource.html
index 123b48d..7d63b4b 100644
--- a/application/static/datasource.html
+++ b/application/static/datasource.html
@@ -7,32 +7,31 @@ To build a data source, firstly purchase a matching audible & kindle book (typic
Audible to audio
To convert an audible audio book to an audio file (.mp3) I use AaxAudioConverter . Here are the steps to install and use:
- Download the Windows Audible app from the Microsoft store
+ Download and install the Windows Audible app from the Microsoft store
Open the audible app and download the audiobook you wish to convert
Download AaxAudioConverter
Run the application and click "Add" in the top left
+
Select the audiobook you downloaded in the audible app
Select "MP3" as the export format and "Single file per AAX file". Then click convert
+
Kindle to text
-To convert a kindle book to text file (.txt) I developed an extension found in the dataset folder of this project. Here are the steps to install and use:
+To convert a kindle book to text file (.txt):
- Go to chrome://extensions/ in chrome
- Click on "Load unpacked" in the top left and select the "extension" folder in the dataset directory
-
-
- Open the first page of the book you want to scrape in the amazon cloud reader
- Open the extension & click "Scrape book". Wait for the reader to scan through all the pages
-
-
- When the scanner has reached the last page, press "Export book". This will download the text fill needed for step 1
-
+ Download and install Kindle App version 1.17 (NOTE: It must be this version or earlier to work)
+ Open the kindle app and download the book you wish to convert
+ Go to "Documents\My Kindle Content" and find your kindle book (.azw file)
+
+
+ Upload this file to Convert to a txt
+If this doesn't work you can also follow the DeDRM guide
{% endblock %}
diff --git a/application/static/images/kindle_step3.PNG b/application/static/images/kindle_step3.PNG
new file mode 100644
index 0000000..fc09fb6
Binary files /dev/null and b/application/static/images/kindle_step3.PNG differ
diff --git a/application/static/images/step2.PNG b/application/static/images/step2.PNG
deleted file mode 100644
index bb68848..0000000
Binary files a/application/static/images/step2.PNG and /dev/null differ
diff --git a/application/static/images/step4.PNG b/application/static/images/step4.PNG
deleted file mode 100644
index 7f1321f..0000000
Binary files a/application/static/images/step4.PNG and /dev/null differ
diff --git a/application/static/images/step5.PNG b/application/static/images/step5.PNG
deleted file mode 100644
index 0fd8b99..0000000
Binary files a/application/static/images/step5.PNG and /dev/null differ
diff --git a/dataset/extension/main.js b/dataset/extension/main.js
deleted file mode 100644
index 3b783e9..0000000
--- a/dataset/extension/main.js
+++ /dev/null
@@ -1,104 +0,0 @@
-document.addEventListener('DOMContentLoaded', function() {
- var convert = document.getElementById('scrapeBook');
- var download = document.getElementById('exportBook');
-
- convert.addEventListener('click', function() {
- function getBook(){
- function scrapePage(){
- function hashString(str){
- let hash = 0;
- for (let i = 0; i < str.length; i++) {
- hash += Math.pow(str.charCodeAt(i) * 31, str.length - i);
- hash = hash & hash; // Convert to 32bit integer
- }
- return hash;
- }
-
- var hashes = {};
- var content = [];
- function addDiv(div){
- let hash = hashString(div.innerText);
- if (hashes[hash] === undefined) {
- hashes[hash] = true;
- content.push(div.outerHTML);
- }
- }
-
- var appFrame = document.querySelector('#KindleReaderIFrame').contentDocument;
- var contentFrames = Array.from(appFrame.querySelectorAll('iframe')).map(f => f.contentDocument);
- Array.from(contentFrames[1].querySelectorAll('body > div')).forEach(addDiv);
- appFrame.getElementById('kindleReader_pageTurnAreaRight').click();
- return content;
- }
-
- function extractContent(s) {
- var span = document.createElement('span');
- span.innerHTML = s;
- return span.textContent || span.innerText;
- }
-
- function getFooter(){
- var appFrame = document.querySelector('#KindleReaderIFrame').contentDocument;
- return appFrame.getElementById("kindleReader_footer_message").innerHTML.split(" ");
- }
-
- function getCurrentPageNumber(){
- var footer = getFooter();
- return parseInt(footer[3]);
- }
-
- var footer = getFooter();
- var num_pages = parseInt(footer[5]);
- var current_page = parseInt(footer[3]);
- var book = "";
- var last_page = "";
-
- function getPageText(){
- text = "\n\n";
- page = scrapePage();
- for (let i = 0; i < page.length; i++){
- text += extractContent(page[i]) + "\n";
- }
- if(text != last_page){
- book += text;
- last_page = text;
- }
- current_page = getCurrentPageNumber();
- if(current_page == num_pages){
- alert("Extracted "+num_pages+" pages");
- var data = document.getElementById("data");
- if(data){
- data.innerHTML = book;
- } else {
- document.body.innerHTML += ""+book+" ";
- }
- return;
- }
- setTimeout(getPageText, 1000);
- }
-
- getPageText();
- return text;
- }
-
- chrome.tabs.executeScript({
- code: '(' + getBook + ')();'
- }, (result) => {
- console.log(result);
- });
- }, false);
-
- download.addEventListener('click', function() {
- chrome.tabs.executeScript({
- code: '(function getData(){ return document.getElementById("data").innerHTML; })();'
- }, (result) => {
- console.log(result);
- var blob = new Blob([result], {type: "text/plain"});
- var url = URL.createObjectURL(blob);
- chrome.downloads.download({
- url: url,
- filename: "book.txt"
- });
- });
- }, false);
-}, false);
diff --git a/dataset/extension/manifest.json b/dataset/extension/manifest.json
deleted file mode 100644
index ee26cf6..0000000
--- a/dataset/extension/manifest.json
+++ /dev/null
@@ -1,10 +0,0 @@
-{
- "manifest_version": 2,
- "name": "Kindle webscraper",
- "description": "This extension scrapes kindle books for the purpose of voice cloning",
- "version": "1.0",
- "browser_action": {
- "default_popup": "popup.html"
- },
- "permissions": ["downloads", "https://read.amazon.co.uk/*", "https://read.amazon.com/*", "cookies"]
-}
diff --git a/dataset/extension/popup.html b/dataset/extension/popup.html
deleted file mode 100644
index b3c93a6..0000000
--- a/dataset/extension/popup.html
+++ /dev/null
@@ -1,12 +0,0 @@
-
-
-
-
-
-
-
- Kindle Converter
- Scrape book
- Export book
-
-
diff --git a/dataset/extension/style.css b/dataset/extension/style.css
deleted file mode 100644
index 38050a3..0000000
--- a/dataset/extension/style.css
+++ /dev/null
@@ -1,15 +0,0 @@
-h1 {
- font-family:Arial;
- font-size:16px;
-}
-button {
- background-color:#44c767;
- border:1px solid #18ab29;
- color:#ffffff;
- font-family:Arial;
- font-size:16px;
- font-weight:bold;
-}
-button:hover {
- background-color:#5cbf2a;
-}
diff --git a/synthesis/synthesis.md b/synthesis/synthesis.md
index d69d856..3363df0 100644
--- a/synthesis/synthesis.md
+++ b/synthesis/synthesis.md
@@ -3,10 +3,16 @@ With trained model weights we can now implement the TTS app for our generated vo
## Arguments
- **model_path**: The path to your generated model
-- **waveglow_model_path**: The path to your waveglow model ([default found here](https://drive.google.com/file/d/1rpK8CzAAirq9sWZhe9nlfvxMF1dRgFbF/view))
+- **vocoder_type**: The vocoder type, `waveglow` or `hifigan`
+- **vocoder_model_path**: The path to your vocoder model ([default waveglow model found here](https://drive.google.com/file/d/1rpK8CzAAirq9sWZhe9nlfvxMF1dRgFbF/view) [default hifigan model found here](https://drive.google.com/file/d/1qpgI41wNXFcH-iKq1Y42JlBC9j0je8PW/view?usp=sharing))
+- **hifigan_config_path**: The path to your hifigan config ([default higigan config found here](https://drive.google.com/file/d/1pAB2kQunkDuv6W5fcJiQ0CY8xcJKB22e/view?usp=sharing))
- **text**: Text you wish to synthesize
- **graph_output_path (optional)**: Path to save alignment graph to
- **audio_output_path (optional)**: Path to save generated audio to
## How to run
-`python synthesize.py -m checkpoint_500000 -w waveglow_256channels_universal_v5.pt -t "Hello everyone, how are you?" -g graph.png -a audio.wav`
+### Using vocoder waveglow
+`python synthesize.py -vt waveglow -m checkpoint_500000 -vm waveglow_256channels_universal_v5.pt -t "Hello everyone, how are you?" -g graph.png -a audio.wav`
+
+### Using vocoder hifigan
+`python synthesize.py -vt hifigan -m checkpoint_500000 -vm g_02500000 -hc config.json -t "Hello everyone, how are you?" -g graph.png -a audio.wav`
diff --git a/synthesis/synthesize.py b/synthesis/synthesize.py
index de3b305..7d443bc 100644
--- a/synthesis/synthesize.py
+++ b/synthesis/synthesize.py
@@ -2,10 +2,8 @@ import argparse
import os
import inflect
import matplotlib.pyplot as plt
-from training.tacotron2_model import Tacotron2
import torch
import numpy as np
-import glow # noqa
import matplotlib
from os.path import dirname, abspath
import sys
@@ -13,9 +11,11 @@ import sys
sys.path.append(dirname(dirname(abspath(__file__))))
matplotlib.use("Agg")
+import glow # noqa
+from training.tacotron2_model import Tacotron2
from training.clean_text import clean_text
from synthesis.waveglow import load_waveglow_model, generate_audio_waveglow
-from synthesis.hifigan import generate_audio_hifigan
+from synthesis.hifigan import load_hifigan_model, generate_audio_hifigan
def load_model(model_path):
@@ -123,19 +123,28 @@ if __name__ == "__main__":
"""Synthesize audio using model and vocoder"""
parser = argparse.ArgumentParser(description="Synthesize audio using model and vocoder")
parser.add_argument("-m", "--model_path", type=str, help="tacotron2 model path", required=True)
- parser.add_argument("-w", "--waveglow_model_path", type=str, help="waveglow model path", required=True)
+ parser.add_argument("-vt", "--vocoder_type", type=str, help="vocoder type(waveglow or hifigan)", required=True)
+ parser.add_argument("-vm", "--vocoder_model_path", type=str, help="vocoder model path", required=True)
+ parser.add_argument("-hc", "--hifigan_config_path", type=str, help="hifigan_config path", required=False)
parser.add_argument("-t", "--text", type=str, help="text to synthesize", required=True)
parser.add_argument("-g", "--graph_output_path", type=str, help="path to save alignment graph to", required=False)
parser.add_argument("-a", "--audio_output_path", type=str, help="path to save output audio to", required=False)
args = parser.parse_args()
assert os.path.isfile(args.model_path), "Model not found"
- assert os.path.isfile(args.waveglow_model_path), "Waveglow model not found"
+ assert os.path.isfile(args.vocoder_model_path), "vocoder model not found"
model = load_model(args.model_path)
- waveglow_model = load_waveglow_model(args.waveglow_path)
+ vocoder_type = args.vocoder_type
+ vocoder_model = None
+ if vocoder_type == "hifigan":
+ assert os.path.isfile(args.hifigan_config_path), "hifigan config not found"
+ vocoder_model = load_hifigan_model(args.vocoder_model_path, args.hifigan_config_path)
+ elif vocoder_type == "waveglow":
+ vocoder_model = load_waveglow_model(args.vocoder_model_path)
+
inflect_engine = inflect.engine()
synthesize(
- model, args.text, inflect_engine, args.graph_output_path, args.audio_output_path, waveglow_model, "waveglow"
+ model, args.text, inflect_engine, args.graph_output_path, args.audio_output_path, vocoder_model, vocoder_type
)