File size: 5,179 Bytes
8d86cad
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
58512f0
 
8d86cad
b8ccf02
 
 
eb10806
db47987
eb10806
 
58512f0
eb10806
58512f0
eb10806
 
58512f0
eb10806
 
58512f0
36047e5
b8ccf02
bbdce84
36047e5
 
58512f0
eb10806
58512f0
 
 
eb10806
db47987
eb10806
36047e5
db47987
 
eb10806
b8ccf02
eb10806
 
36047e5
b8ccf02
 
36047e5
58512f0
 
 
eb10806
8d86cad
 
db47987
b8ccf02
eb10806
36047e5
58512f0
 
 
 
 
 
 
 
 
 
 
 
8d86cad
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
// Fetch data from JSON file and initialize
fetch('BhagvatGlory.json')
    .then(response => response.json())
    .then(jsonData => initializeApp(jsonData))
    .catch(error => console.error('Error loading JSON:', error));

const skandaList = document.getElementById("skanda-list");
const chapterTitle = document.getElementById("chapter-title");
const slokeContainer = document.getElementById("sloke-container");

function initializeApp(data) {
    // Populate Skanda and Chapter List
    const skandaItem = document.createElement("li");
    skandaItem.textContent = data.skandaTitle;

    const chapterList = document.createElement("ul");
    data.chapters.forEach((chapter, chapterIndex) => {
        const chapterItem = document.createElement("li");
        chapterItem.textContent = chapter.chapterTitle;
        chapterItem.onclick = () => displayChapter(chapter);
        chapterList.appendChild(chapterItem);
    });

    skandaItem.appendChild(chapterList);
    skandaList.appendChild(skandaItem);
}

// Display Slokes
function displayChapter(chapter) {
    chapterTitle.textContent = chapter.chapterTitle;

    slokeContainer.innerHTML = "";
    const slokes = chapter.slokes
        .replace(/श्लोक\s*\d+:/g, "") // Remove "श्लोक-X"
        .trim()
        .split("\n"); // Split by newline

    slokes.forEach((sloke, index) => {
        const slokeItem = document.createElement("div");
        slokeItem.className = "sloke-item";

        const slokeText = document.createElement("p");
        slokeText.textContent = sloke.trim();

        const speakButton = document.createElement("button");
        speakButton.textContent = "Speak";
        speakButton.onclick = () => speakSloke(sloke.trim());

        const downloadButton = document.createElement("button");
        downloadButton.textContent = "Download";
        downloadButton.onclick = () => downloadAudio(sloke.trim(), `sloke-${index + 1}.wav`);

        slokeItem.appendChild(slokeText);
        slokeItem.appendChild(speakButton);
        slokeItem.appendChild(downloadButton);

        slokeContainer.appendChild(slokeItem);
    });
}


// Speak Sloke with Advanced Features
function speakSloke(text) {
    // Normalize and preprocess the text
    const normalizedText = text
        .normalize("NFC")
        .replace(/ऽ/g, " "); // Replace avagraha with a space for better pronunciation

    // Split the text into meaningful phrases
    const phrases = normalizedText.split(/[।॥]/).filter(phrase => phrase.trim().length > 0);

    let phraseIndex = 0;

    function speakNextPhrase() {
        if (phraseIndex >= phrases.length) return;

        const currentPhrase = phrases[phraseIndex].trim();
        const utterance = new SpeechSynthesisUtterance(currentPhrase);

        // Set voice and TTS parameters for a bold, heavy tone
        utterance.lang = "sa-IN";
        utterance.pitch = 0.8; // Lower pitch for a deeper, heavier voice
        utterance.rate = 0.8; // Slower rate for gravitas and clarity
        utterance.volume = 1.0; // Full volume for boldness

        // Select the male Sanskrit voice
        const voices = speechSynthesis.getVoices();
        utterance.voice = voices.find(voice => voice.lang === "sa-IN" && voice.name.includes("Male"));

        // Handle completion of the current phrase
        utterance.onend = () => {
            phraseIndex++;
            setTimeout(speakNextPhrase, 500); // Slightly longer pause for dramatic effect
        };

        // Handle errors gracefully
        utterance.onerror = (error) => {
            console.error(`Error speaking phrase: ${currentPhrase}`, error);
            phraseIndex++;
            setTimeout(speakNextPhrase, 500);
        };

        console.log(`Speaking phrase with bold voice: ${currentPhrase}`); // Debugging
        speechSynthesis.speak(utterance);
    }

    speakNextPhrase(); // Start speaking the sloke
}





// Speak Sloke
// function speakSloke(text) {
//     alert(text)
//     const utterance = new SpeechSynthesisUtterance(text);
//     utterance.lang = "sa-IN";
//     utterance.rate = 0.8;
//     utterance.pitch = 1.0;
//     const voices = speechSynthesis.getVoices();
//     utterance.voice = voices.find(voice => voice.lang === "sa-IN" && voice.name.includes("Male"));
//     speechSynthesis.speak(utterance);
// }

// Download Audio
function downloadAudio(text, filename) {
    const utterance = new SpeechSynthesisUtterance(text);
    utterance.lang = "sa-IN";

    const audioChunks = [];
    const streamDestination = new MediaStreamAudioDestinationNode(new AudioContext());
    const mediaRecorder = new MediaRecorder(streamDestination.stream);

    utterance.onstart = () => mediaRecorder.start();
    utterance.onend = () => {
        mediaRecorder.stop();
        const audioBlob = new Blob(audioChunks, { type: "audio/wav" });
        const audioUrl = URL.createObjectURL(audioBlob);

        const link = document.createElement("a");
        link.href = audioUrl;
        link.download = filename;
        link.click();
    };

    mediaRecorder.ondataavailable = event => audioChunks.push(event.data);
    speechSynthesis.speak(utterance);
}