Voici un exemple de code Python :
Python
Page 2
import sys
import numpy as np
import sounddevice as sd
import soundfile as sf
from PyQt5.QtWidgets import (
    QApplication, QWidget, QVBoxLayout, QLabel, QSlider,
    QPushButton, QFileDialog
)
from PyQt5.QtCore import Qt, QTimer

samplerate = 44100
blocksize = 1024

class VoiceModifier(QWidget):
    def __init__(self):
        super().__init__()
        self.setWindowTitle("Modificateur de voix")
        self.setGeometry(300, 300, 400, 350)

        self.pitch = 1.0
        self.recording = []
        self.is_recording = False

        layout = QVBoxLayout()

        self.label = QLabel("Pitch: 0 (Normal)")
        layout.addWidget(self.label)
        self.slider = QSlider(Qt.Horizontal)
        self.slider.setMinimum(-12)
        self.slider.setMaximum(12)
        self.slider.setValue(0)
        self.slider.valueChanged.connect(self.change_pitch)
        layout.addWidget(self.slider)

        self.female_button = QPushButton("Voix féminine")
        self.female_button.clicked.connect(lambda: self.slider.setValue(6))
        layout.addWidget(self.female_button)

        self.male_button = QPushButton("Voix masculine")
        self.male_button.clicked.connect(lambda: self.slider.setValue(-6))
        layout.addWidget(self.male_button)

        self.record_button = QPushButton("Démarrer l'enregistrement")
        self.record_button.clicked.connect(self.toggle_recording)
        layout.addWidget(self.record_button)

        self.preview_button = QPushButton("Préécouter l'enregistrement")
        self.preview_button.clicked.connect(self.preview_recording)
        layout.addWidget(self.preview_button)

        self.save_button = QPushButton("Enregistrer dans un fichier WAV")
        self.save_button.clicked.connect(self.save_recording)
        layout.addWidget(self.save_button)

        self.setLayout(layout)

        QTimer.singleShot(500, self.start_audio_stream)

    def change_pitch(self, value):
        self.pitch = 2 ** (value / 12.0)
        self.label.setText(f"Pitch: {value} ({'+' if value > 0 else ''}{value} demi-tons)")

    def toggle_recording(self):
        self.is_recording = not self.is_recording
        if self.is_recording:
            self.recording.clear()
            self.record_button.setText("Arrêter l'enregistrement")
        else:
            self.record_button.setText("Démarrer l'enregistrement")

    def preview_recording(self):
        if not self.recording:
            print("Aucun enregistrement à lire.")
            return
        audio_data = np.concatenate(self.recording)
        sd.play(audio_data, samplerate)
        print("Préécoute en cours...")

    def save_recording(self):
        if not self.recording:
            print("Aucun enregistrement disponible.")
            return
        file_path, _ = QFileDialog.getSaveFileName(self, "Enregistrer sous", "", "Fichiers WAV (*.wav)")
        if file_path:
            audio_data = np.concatenate(self.recording)
            sf.write(file_path, audio_data, samplerate)
            print("Enregistrement sauvegardé :", file_path)

    def start_audio_stream(self):
        self.stream = sd.InputStream(
            samplerate=samplerate,
            blocksize=blocksize,
            channels=1,
            dtype='float32',callback=self.audio_callback
        )
        self.stream.start()

    def audio_callback(self, indata, frames, time, status):
        if status:
            print("Status:", status)

        data = indata[:, 0]
        indices = np.arange(0, len(data), self.pitch)
        indices = indices[indices < len(data)].astype(int)
        shifted = data[indices]

        # Adapter à la longueur originale
        if len(shifted) < len(data):
            shifted = np.pad(shifted, (0, len(data) - len(shifted)), mode='constant')
        else:
            shifted = shifted[:len(data)]

        if self.is_recording:
            self.recording.append(np.copy(shifted))


if __name__ == "__main__":
    app = QApplication(sys.argv)
    window = VoiceModifier()
    window.show()
    sys.exit(app.exec_())