The project is an initiative by art & design
collective Nonhuman Nonsense developed in
@@ -18,11 +21,17 @@ function Contact() {
@nonhuman-nonsense
-
+
nonhuman-nonsense.com
-
+
hello@nonhuman-nonsense.com
diff --git a/client/src/components/Council.jsx b/client/src/components/Council.jsx
index 796ad5a..91ce0bb 100644
--- a/client/src/components/Council.jsx
+++ b/client/src/components/Council.jsx
@@ -17,6 +17,7 @@ function Council({ options }) {
const [activeOverlay, setActiveOverlay] = useState("");
const { width: screenWidth } = useWindowSize();
const [conversation, setConversation] = useState([]); // State to store conversation updates
+ const [audioBuffers, setAudioBuffers] = useState([]); // To store multiple ArrayBuffers
const socketRef = useRef(null); // Using useRef to persist socket instance
const foodsContainerStyle = {
@@ -33,26 +34,30 @@ function Council({ options }) {
useEffect(() => {
socketRef.current = io();
+ // Send initial data to start the conversation
let promptsAndOptions = {
options: {
...globalOptions,
- humanName: humanName,
+ humanName,
raiseHandPrompt: false,
neverMindPrompt: false,
},
name: "New room",
- topic: topic,
+ topic,
characters: foods,
};
-
socketRef.current.emit("start_conversation", promptsAndOptions);
- // Listen for conversation updates
+ // Listen for conversation text updates
socketRef.current.on("conversation_update", (message) => {
- setConversation((prev) => [...prev, message]); // Update conversation state
+ setConversation((prev) => [...prev, message]);
+ });
+
+ // Listen for audio updates
+ socketRef.current.on("audio_update", (audioData) => {
+ setAudioBuffers((prevBuffers) => [...prevBuffers, audioData.audio]);
});
- // Cleanup on component unmount
return () => {
socketRef.current.disconnect();
};
@@ -108,7 +113,10 @@ function Council({ options }) {
className="text-container"
style={{ justifyContent: "end" }}
>
-
+
diff --git a/client/src/components/Output.jsx b/client/src/components/Output.jsx
index 9ea2801..44114d3 100644
--- a/client/src/components/Output.jsx
+++ b/client/src/components/Output.jsx
@@ -3,33 +3,17 @@ import TextOutput from "./TextOutput";
import AudioOutput from "./AudioOutput";
import ConversationControls from "./ConversationControls";
-function Output({ conversation }) {
+function Output({ conversation, audioBuffers }) {
const [currentMessageIndex, setCurrentMessageIndex] = useState(0);
const [currentSnippetIndex, setCurrentSnippetIndex] = useState(0);
const [currentMessageTextSnippet, setCurrentMessageTextSnippet] =
useState("");
const [isPaused, setIsPaused] = useState(false);
- const calculateDisplayTime = (text) => Math.max(3, text.length * 0.05);
-
- function handlePauseResume() {
- setIsPaused(!isPaused); // Toggle pause state
- }
-
- function handleSkipForward() {
- if (conversation.length > currentMessageIndex) {
- const snippets =
- conversation[currentMessageIndex].text.split(/(?<=\.\s)/);
- if (currentSnippetIndex < snippets.length - 1) {
- // Move to the next snippet within the same message
- setCurrentSnippetIndex(currentSnippetIndex + 1);
- } else if (currentMessageIndex < conversation.length - 1) {
- // Move to the first snippet of the next message
- setCurrentMessageIndex(currentMessageIndex + 1);
- setCurrentSnippetIndex(0);
- }
- }
- }
+ useEffect(() => {
+ console.log("Audio buffers length:", audioBuffers.length);
+ console.log("Current audio buffer index:", currentMessageIndex);
+ }, [audioBuffers, currentMessageIndex]);
useEffect(() => {
if (conversation.length > 0 && !isPaused) {
@@ -51,6 +35,27 @@ function Output({ conversation }) {
}
}, [currentMessageIndex, currentSnippetIndex, conversation, isPaused]); // Include isPaused in dependencies
+ const calculateDisplayTime = (text) => Math.max(3, text.length * 0.05);
+
+ function handlePauseResume() {
+ setIsPaused(!isPaused); // Toggle pause state
+ }
+
+ function handleSkipForward() {
+ if (conversation.length > currentMessageIndex) {
+ const snippets =
+ conversation[currentMessageIndex].text.split(/(?<=\.\s)/);
+ if (currentSnippetIndex < snippets.length - 1) {
+ // Move to the next snippet within the same message
+ setCurrentSnippetIndex(currentSnippetIndex + 1);
+ } else if (currentMessageIndex < conversation.length - 1) {
+ // Move to the first snippet of the next message
+ setCurrentMessageIndex(currentMessageIndex + 1);
+ setCurrentSnippetIndex(0);
+ }
+ }
+ }
+
return (
@@ -60,7 +65,7 @@ function Output({ conversation }) {
: ""}
-
+
Date: Sat, 20 Apr 2024 12:34:29 +0200
Subject: [PATCH 3/3] Link audio playback with current message
---
client/src/components/AudioOutput.jsx | 10 +++++-----
client/src/components/Council.jsx | 11 +++++++----
client/src/components/Output.jsx | 16 ++++++++++------
3 files changed, 22 insertions(+), 15 deletions(-)
diff --git a/client/src/components/AudioOutput.jsx b/client/src/components/AudioOutput.jsx
index 50141a9..40c51eb 100644
--- a/client/src/components/AudioOutput.jsx
+++ b/client/src/components/AudioOutput.jsx
@@ -1,16 +1,16 @@
// In the AudioOutput component
import React, { useEffect, useRef } from "react";
-function AudioOutput({ currentAudioBuffer }) {
+function AudioOutput({ currentAudioMessage }) {
const audioRef = useRef(null);
useEffect(() => {
- if (currentAudioBuffer) {
+ if (currentAudioMessage) {
console.log(
"Creating blob with ArrayBuffer of size:",
- currentAudioBuffer.byteLength
+ currentAudioMessage.audio.byteLength
);
- const blob = new Blob([currentAudioBuffer], { type: "audio/mp3" });
+ const blob = new Blob([currentAudioMessage.audio], { type: "audio/mp3" });
const url = URL.createObjectURL(blob);
console.log("Blob URL:", url); // Check the generated URL
audioRef.current.src = url;
@@ -23,7 +23,7 @@ function AudioOutput({ currentAudioBuffer }) {
URL.revokeObjectURL(url);
};
}
- }, [currentAudioBuffer]);
+ }, [currentAudioMessage]);
return (
)}
diff --git a/client/src/components/Output.jsx b/client/src/components/Output.jsx
index 44114d3..5e1b391 100644
--- a/client/src/components/Output.jsx
+++ b/client/src/components/Output.jsx
@@ -3,7 +3,7 @@ import TextOutput from "./TextOutput";
import AudioOutput from "./AudioOutput";
import ConversationControls from "./ConversationControls";
-function Output({ conversation, audioBuffers }) {
+function Output({ conversation, audioMessages }) {
const [currentMessageIndex, setCurrentMessageIndex] = useState(0);
const [currentSnippetIndex, setCurrentSnippetIndex] = useState(0);
const [currentMessageTextSnippet, setCurrentMessageTextSnippet] =
@@ -11,9 +11,9 @@ function Output({ conversation, audioBuffers }) {
const [isPaused, setIsPaused] = useState(false);
useEffect(() => {
- console.log("Audio buffers length:", audioBuffers.length);
+ console.log("Audio buffers length:", audioMessages.length);
console.log("Current audio buffer index:", currentMessageIndex);
- }, [audioBuffers, currentMessageIndex]);
+ }, [audioMessages, currentMessageIndex]);
useEffect(() => {
if (conversation.length > 0 && !isPaused) {
@@ -35,7 +35,7 @@ function Output({ conversation, audioBuffers }) {
}
}, [currentMessageIndex, currentSnippetIndex, conversation, isPaused]); // Include isPaused in dependencies
- const calculateDisplayTime = (text) => Math.max(3, text.length * 0.05);
+ const calculateDisplayTime = (text) => Math.max(3, text.length * 0.065);
function handlePauseResume() {
setIsPaused(!isPaused); // Toggle pause state
@@ -57,7 +57,7 @@ function Output({ conversation, audioBuffers }) {
}
return (
-
+
Speaker:{" "}
{conversation.length > 0
@@ -65,7 +65,11 @@ function Output({ conversation, audioBuffers }) {
: ""}
-
+
a.message_index == currentMessageIndex
+ )}
+ />