diff --git a/src/components/player/SpeedControl.tsx b/src/components/player/SpeedControl.tsx
index e544e14..a76de72 100644
--- a/src/components/player/SpeedControl.tsx
+++ b/src/components/player/SpeedControl.tsx
@@ -5,6 +5,7 @@ import {
ListboxOptions,
} from '@headlessui/react';
import { ChevronUpDownIcon } from '@/components/icons/Icons';
+import { useConfig } from '@/contexts/ConfigContext';
const speedOptions = [
{ value: 0.5, label: '0.5x' },
@@ -22,11 +23,16 @@ export const SpeedControl = ({ speed, setSpeedAndRestart }: {
speed: number;
setSpeedAndRestart: (speed: number) => void;
}) => {
+ const { voiceSpeed } = useConfig();
+
+ // Use voiceSpeed as the source of truth
+ const currentSpeed = voiceSpeed;
+
return (
-
+
- {speed}x
+ {currentSpeed}x
diff --git a/src/components/player/VoicesControl.tsx b/src/components/player/VoicesControl.tsx
index a2e8366..39bb7fa 100644
--- a/src/components/player/VoicesControl.tsx
+++ b/src/components/player/VoicesControl.tsx
@@ -5,17 +5,23 @@ import {
ListboxOptions,
} from '@headlessui/react';
import { ChevronUpDownIcon } from '@/components/icons/Icons';
+import { useConfig } from '@/contexts/ConfigContext';
export const VoicesControl = ({ voice, availableVoices, setVoiceAndRestart }: {
voice: string;
availableVoices: string[];
setVoiceAndRestart: (voice: string) => void;
}) => {
+ const { voice: configVoice } = useConfig();
+
+ // Use configVoice as the source of truth
+ const currentVoice = configVoice;
+
return (
-
+
- {voice}
+ {currentVoice}
diff --git a/src/contexts/TTSContext.tsx b/src/contexts/TTSContext.tsx
index 163f803..aeb03bf 100644
--- a/src/contexts/TTSContext.tsx
+++ b/src/contexts/TTSContext.tsx
@@ -61,7 +61,14 @@ interface TTSContextType {
const TTSContext = createContext(undefined);
export function TTSProvider({ children }: { children: React.ReactNode }) {
- const { apiKey: openApiKey, baseUrl: openApiBaseUrl, isLoading: configIsLoading } = useConfig();
+ const {
+ apiKey: openApiKey,
+ baseUrl: openApiBaseUrl,
+ isLoading: configIsLoading,
+ voiceSpeed,
+ voice: configVoice,
+ updateConfigKey
+ } = useConfig();
// Move openai initialization to a ref to avoid breaking hooks rules
const openaiRef = useRef(null);
@@ -75,8 +82,8 @@ export function TTSProvider({ children }: { children: React.ReactNode }) {
const [activeHowl, setActiveHowl] = useState(null);
const [audioQueue] = useState([]);
const [isProcessing, setIsProcessing] = useState(false);
- const [speed, setSpeed] = useState(1);
- const [voice, setVoice] = useState('alloy');
+ const [speed, setSpeed] = useState(voiceSpeed);
+ const [voice, setVoice] = useState(configVoice);
const [availableVoices, setAvailableVoices] = useState([]);
const [currDocPage, setCurrDocPage] = useState(1);
@@ -422,6 +429,7 @@ export function TTSProvider({ children }: { children: React.ReactNode }) {
const setSpeedAndRestart = useCallback((newSpeed: number) => {
setSpeed(newSpeed);
+ updateConfigKey('voiceSpeed', newSpeed);
// Clear the audio cache since it contains audio at the old speed
audioCacheRef.current.clear();
@@ -431,10 +439,11 @@ export function TTSProvider({ children }: { children: React.ReactNode }) {
setCurrentIndex(currentIdx);
setIsPlaying(true);
}
- }, [isPlaying, currentIndex, stop]);
+ }, [isPlaying, currentIndex, stop, updateConfigKey]);
const setVoiceAndRestart = useCallback((newVoice: string) => {
setVoice(newVoice);
+ updateConfigKey('voice', newVoice);
// Clear the audio cache since it contains audio with the old voice
audioCacheRef.current.clear();
@@ -444,7 +453,7 @@ export function TTSProvider({ children }: { children: React.ReactNode }) {
setCurrentIndex(currentIdx);
setIsPlaying(true);
}
- }, [isPlaying, currentIndex, stop]);
+ }, [isPlaying, currentIndex, stop, updateConfigKey]);
const value = {
isPlaying,