im trying to create an audio stream player that will receive audio through TCP, play it and save into file. This is just the player block part. For some reason pyaudio doesnt play the sine wave (sounddevice does, so its fine in the source format at least). Ive tried to play the converted format with sounddevice but without success, so that's probably where the issue lies. Can anyone point me to the right direction? thanks.
import numpy as np
import pyaudio
import sounddevice as sd
from array import array
import wave
sample_rate = 44100
Fs = 50000
f = 5000
sample = 150000
def play_stream(ob):
"converting object to pyauido required format"
tone = ob.astype(np.int16)
bytestream = tone.tobytes()
"playing data with pyaudio"
p = pyaudio.PyAudio()
stream = p.open(format=pyaudio.paInt16,
channels=1,
rate=sample_rate,
output=True)
if len(bytestream)>0:
stream.write(bytestream)
else:
print("no data!")
stream.stop_stream()
stream.close()
print("* stream finished")
p.terminate()
"testing data in alternate method"
sd.play(ob, 44100)
print ("play finished!")
"generating sine wave"
x = np.arange(sample)
ob = np.sin(2 * np.pi * f * x /Fs)
"playing sine wave"
play_stream(ob)
Edit: If i swap the format and data to float 32 it works. No idea why.
np.sin' returns a value in the range of -1 to 1. The 'astype' call is just casting it to a 16-bit integer which will give possible outputs of -1, 0, and 1. To use the full 16-bit range you need to multiply by 32767 before quantization.
scaled = ob * 32767
tone = scaled.totype(np.int16)
I just started working with matplotlib and numpy. I need to add noise to an audio signal, in Python.
In order to do that, I need to receive the original audio signal and the noise amplitude, and then returning the original audio signal with the noise in it.
I have to use the rand function from numpy.random. The amplitude is what is supposed to help me get those values.
So far this is what I have:
import scipy.io.wavfile as spiowf
import sounddevice as sd
import matplotlib.pyplot as plt
import numpy as np
def noise(data, samplerate):
(ns, nc) = data.shape
Ts = 1 / samplerate
dur = ns / samplerate # audio duration
random = np.random.rand(0, 100)
sd.play(data, samplerate, blocking=True)
def main():
fName = "saxriff.wav"
[samplerate, data] = spiowf.read(fName)
if __name__ == "__main__":
main()
How can I do the rest?
I am new learner of audio editing libs - Pydub. I want to change some audio files' playback speed using Pydub(say .wav/mp3 format files), but I don't know how to make it. The only module I saw that could possibly deal with this problem is speedup module in effect.py. However, there is no explanation about how I am supposed to call it.
Could anyone kindly explain how to do this task in Pydub? Many thanks!
(A related question: Pydub - How to change frame rate without changing playback speed, but what I want to do is to change the playback speed without changing the audio quality.)
This can be done using pyrubberband package which requires rubberband library that can stretch audio while keeping the pitch and high quality. I was able to install the library on MacOS using brew, and same on Ubuntu with apt install. For extreme stretching, look into PaulStretch
brew install rubberband
This works simply with librosa package
import librosa
import pyrubberband
import soundfile as sf
y, sr = librosa.load(filepath, sr=None)
y_stretched = pyrubberband.time_stretch(y, sr, 1.5)
sf.write(analyzed_filepath, y_stretched, sr, format='wav')
To make pyrubberband work directly with AudioSegment from pydub without librosa I fiddled this function:
def change_audioseg_tempo(audiosegment, tempo, new_tempo):
y = np.array(audiosegment.get_array_of_samples())
if audiosegment.channels == 2:
y = y.reshape((-1, 2))
sample_rate = audiosegment.frame_rate
tempo_ratio = new_tempo / tempo
print(tempo_ratio)
y_fast = pyrb.time_stretch(y, sample_rate, tempo_ratio)
channels = 2 if (y_fast.ndim == 2 and y_fast.shape[1] == 2) else 1
y = np.int16(y_fast * 2 ** 15)
new_seg = pydub.AudioSegment(y.tobytes(), frame_rate=sample_rate, sample_width=2, channels=channels)
return new_seg
from pydub import AudioSegment
from pydub import effects
root = r'audio.wav'
velocidad_X = 1.5 # No puede estar por debajo de 1.0
sound = AudioSegment.from_file(root)
so = sound.speedup(velocidad_X, 150, 25)
so.export(root[:-4] + '_Out.mp3', format = 'mp3')
I know it's late but I wrote a program to convert mp3 to different playback speed.
First, Convert the .MP3 -> .Wav because PYRubberBand supports only .wav format. Then streach the time and pitch at the same time to avoid chipmunk effect.
import wave
import sys
from pydub import AudioSegment
#sound = AudioSegment.from_file("deviprasadgharpehai.mp3")
sound = AudioSegment.from_mp3(sys.argv[1])
sound.export("file.wav", format="wav")
print(sys.argv[1])
import soundfile as sf
import pyrubberband as pyrb
y, sr = sf.read("file.wav")
# Play back at extra low speed
y_stretch = pyrb.time_stretch(y, sr, 0.5)
# Play back extra low tones
y_shift = pyrb.pitch_shift(y, sr, 0.5)
sf.write("analyzed_filepathX5.wav", y_stretch, sr, format='wav')
sound = AudioSegment.from_wav("analyzed_filepathX5.wav")
sound.export("analyzed_filepathX5.mp3", format="mp3")
# Play back at low speed
y_stretch = pyrb.time_stretch(y, sr, 0.75)
# Play back at low tones
y_shift = pyrb.pitch_shift(y, sr, 0.75)
sf.write("analyzed_filepathX75.wav", y_stretch, sr, format='wav')
sound = AudioSegment.from_wav("analyzed_filepathX75.wav")
sound.export("analyzed_filepathX75.mp3", format="mp3")
# Play back at 1.5X speed
y_stretch = pyrb.time_stretch(y, sr, 1.5)
# Play back two 1.5x tones
y_shift = pyrb.pitch_shift(y, sr, 1.5)
sf.write("analyzed_filepathX105.wav", y_stretch, sr, format='wav')
sound = AudioSegment.from_wav("analyzed_filepathX105.wav")
sound.export("analyzed_filepathX105.mp3", format="mp3")
# Play back at same speed
y_stretch = pyrb.time_stretch(y, sr, 1)
# Play back two smae-tones
y_shift = pyrb.pitch_shift(y, sr, 1)
sf.write("analyzed_filepathXnormal.wav", y_stretch, sr, format='wav')
sound = AudioSegment.from_wav("analyzed_filepathXnormal.wav")
sound.export("analyzed_filepathXnormal.mp3", format="mp3")
**Make Sure to install **
Wave, AudioSegment, FFmpeg, PYRubberBand, Soundfile
To use this Run,
python3 filename.py mp3filename.mp3
To change the speed of the audio without changing the pitch (or creating chipmunk effect). You can use below code.
from pydub import AudioSegment
from pydub.effects import speedup
audio = AudioSegment.from_mp3(song.mp3)
new_file = speedup(audio,1.5,150)
new_file.export("file.mp3", format="mp3")
I want to calculate the single channel data (in order to calculate the audio cross correlation between the channel 1 and channel 4) of this code:
import time
import numpy as np
import pyaudio
import scipy
from scipy import signal, fftpack
pyaud = pyaudio.PyAudio()
#open the stream
stream = pyaud.open(
format = pyaudio.paInt16,
channels = 4,
rate = 16000,
input_device_index = 4,
output = False,
input = True,
frames_per_buffer=2048,)
while True:
rawsamps = stream.read(2048)
samps = np.fromstring(rawsamps, dtype=np.int16)
frames_per_buffer_length = len(samps) / 4 #(channels)
assert frames_per_buffer_length == int(frames_per_buffer_length)
samps = np.reshape(samps, (frames_per_buffer_length, 4)) #4 channels
Assuming that the raw data is interleaved.
This is the function i need to use :
signal.correlate(n1, n2, mode='full')
how can I create an array of data for each channel in order to use the correlate function? are the last lines of the code correct?
Thank you
I found the answer, using print loudness(samps[:,0]), loudness(samps[:,3]). It print in the shell " mic 1 loudness , mic 4 loudness"
I need to apply audio to video at certain time with certain duration, but some audio duration is bigger(or smaller) then needed. How to change speed of audio without changing pitch? I tried to change fps(by multiplying to division of needed duration to audio duration) but it is not work as I want.
original = VideoFileClip("orig.mp4")
clips = [orig.audio.volumex(0.3)]
subs = [] #some array
i = 0
for sub in subs:
clip = AudioFileClip("\\temp{}.mp3")
mult = clip.duration / (sub.end - sub.start) + 0.00001
clip = AudioArrayClip(clip.to_soundarray(buffersize=500, fps=24000/mult), fps=24000).set_start(sub.start).set_end(sub.end)
clips.append(clip)
i += 1
final = CompositeAudioClip(clips)
final.write_audiofile("final.mp3")
you can use librosa module:
from scipy.io import wavfile
import librosa, numpy as np
song, fs = librosa.load("song.wav")
song_2_times_faster = librosa.effects.time_stretch(song, 2)
scipy.io.wavfile.write("song_2_times_faster.wav", fs, song_2_times_faster) # save the song
Using wave: Change the sampling rate
import wave
CHANNELS = 1
swidth = 2
Change_RATE = 2
spf = wave.open('VOZ.wav', 'rb')
RATE=spf.getframerate()
signal = spf.readframes(-1)
wf = wave.open('changed.wav', 'wb')
wf.setnchannels(CHANNELS)
wf.setsampwidth(swidth)
wf.setframerate(RATE*Change_RATE)
wf.writeframes(signal)
wf.close()