web-dev-qa-db-fra.com

Python changer la hauteur du fichier wav

J'ai besoin d'une bibliothèque python pour changer la hauteur de mon fichier wav sans aucun traitement de données audio brutes. J'ai passé quelques heures à le trouver, mais je n'ai trouvé que d'étranges extraits de code de traitement de données brutes et vidéo, qui montre un décalage de hauteur en temps réel, mais sans code source.

12

Puisqu'un fichier wav est essentiellement est des données audio brutes, vous ne pourrez pas changer la hauteur sans "traitement audio brut".

Voici ce que vous pourriez faire. Vous aurez besoin des modules wave (bibliothèque standard) et numpy.

import wave
import numpy as np

Ouvrez les fichiers.

wr = wave.open('input.wav', 'r')
# Set the parameters for the output file.
par = list(wr.getparams())
par[3] = 0  # The number of samples will be set by writeframes.
par = Tuple(par)
ww = wave.open('pitch1.wav', 'w')
ww.setparams(par)

Le son doit être traité en petites fractions de seconde. Cela réduit la réverbération. Essayez de définir fr sur 1; vous entendrez des échos gênants.

fr = 20
sz = wr.getframerate()//fr  # Read and process 1/fr second at a time.
# A larger number for fr means less reverb.
c = int(wr.getnframes()/sz)  # count of the whole file
shift = 100//fr  # shifting 100 Hz
for num in range(c):

Lisez les données, divisez-les en canaux gauche et droit (en supposant un fichier WAV stéréo).

    da = np.fromstring(wr.readframes(sz), dtype=np.int16)
    left, right = da[0::2], da[1::2]  # left and right channel

Extrayez les fréquences à l'aide de la transformée de Fourier rapide intégrée à numpy.

    lf, rf = np.fft.rfft(left), np.fft.rfft(right)

Faites rouler le tableau pour augmenter la hauteur.

    lf, rf = np.roll(lf, shift), np.roll(rf, shift)

Les fréquences les plus élevées passent aux plus basses. Ce n'est pas ce que nous voulons, alors mettez-les à zéro.

    lf[0:shift], rf[0:shift] = 0, 0

Utilisez maintenant la transformée de Fourier inverse pour reconvertir le signal en amplitude.

    nl, nr = np.fft.irfft(lf), np.fft.irfft(rf)

Combinez les deux canaux.

    ns = np.column_stack((nl, nr)).ravel().astype(np.int16)

Écrivez les données de sortie.

    ww.writeframes(ns.tostring())

Fermez les fichiers lorsque tous les cadres sont traités.

wr.close()
ww.close()
8
Roland Smith

Vous pouvez essayer pydub pour un changement de hauteur rapide et facile sur tout le fichier audio et pour différents formats (wav, mp3, etc.).

Voici un code de travail. Inspiration de ici et reportez-vous ici pour plus de détails sur le changement de hauteur.

from pydub import AudioSegment
from pydub.playback import play

sound = AudioSegment.from_file('in.wav', format="wav")

# shift the pitch up by half an octave (speed will increase proportionally)
octaves = 0.5

new_sample_rate = int(sound.frame_rate * (2.0 ** octaves))

# keep the same samples but tell the computer they ought to be played at the 
# new, higher sample rate. This file sounds like a chipmunk but has a weird sample rate.
hipitch_sound = sound._spawn(sound.raw_data, overrides={'frame_rate': new_sample_rate})

# now we just convert it to a common sample rate (44.1k - standard audio CD) to 
# make sure it works in regular audio players. Other than potentially losing audio quality (if
# you set it too low - 44.1k is plenty) this should now noticeable change how the audio sounds.
hipitch_sound = hipitch_sound.set_frame_rate(44100)

#Play pitch changed sound
play(hipitch_sound)

#export / save pitch changed sound
hipitch_sound.export("out.wav", format="wav")
5
Anil_M

Je recommande d'essayer la fonction de changement de hauteur de Librosa: https://librosa.github.io/librosa/generated/librosa.effects.pitch_shift.html

import librosa
y, sr = librosa.load('your_file.wav', sr=16000) # y is a numpy array of the wav file, sr = sample rate
y_shifted = librosa.effects.pitch_shift(y, sr, n_steps=4) # shifted by 4 half steps
3
Nic Scozzaro