I am streaming audio from a mic to my speaker. But I want to increase the volume of the sound live but I can;t figure out a way and I've searched google for a while.
Her Is my code
import pyaudio
Chunk = 1024
AudioFormat = pyaudio.paInt16
Channels = 2
Rate = 44100
PortAudio = pyaudio.PyAudio()
sourceDevice = PortAudio.open(format=AudioFormat,
channels=Channels,
rate=Rate,
input=True,
input_device_index=2,
frames_per_buffer=Chunk
)
destinationDevice = PortAudio.open(format=AudioFormat,
channels=Channels,
rate=Rate,
output=True,
output_device_index=4,
frames_per_buffer=Chunk
)
while True:
try:
data = sourceDevice.read(Chunk)
except OSError:
data = '\x00' * Chunk
except IOError as ex:
if ex[1] != pyaudio.paInputOverflowed:
raise
data = '\x00' * Chunk
# Doing Something To Data Here To Incrase Volume Of It
data = data # Function Here??
destinationDevice.write(data, Chunk, exception_on_underflow=True)
an example of what the data variable is is (This is Shortened Quite by a lot the original is MASSIVE) b'\xec\x00G\x01\xa7\x01\xbe\x01\x95\x00\xf7\x00+\x00\x91\x00\xa1\x01W\x01\xec\x01\x94\x01n\x00\xac\x00I\x00\xa4\x00\xfb\x00"\x01g\x00\x8d\x00*\x00m\x00\xde\x00\x04\x01\xb2\x00\xc7\x005\x00-\x00(\x01\xb0\x00\xec\x01Q\x01.'
You can use numpy to convert the raw data into numpy arrays, then multiply the array by a volume ratio and write it to the output stream.
from math import sqrt
import numpy as np
# ...
# convert the linear volume to a logarithmic scale (see explanation below)
volumeFactor = 2
multiplier = pow(2, (sqrt(sqrt(sqrt(volumeFactor))) * 192 - 192)/6)
while True:
try:
data = sourceDevice.read(Chunk)
except OSError:
data = '\x00' * Chunk
except IOError as ex:
if ex[1] != pyaudio.paInputOverflowed:
raise
data = '\x00' * Chunk
# Doing Something To Data Here To Incrase Volume Of It
numpy_data = np.fromstring(data, dtype=np.int16)
# double the volume using the factor computed above
np.multiply(numpyData, volumeMultiplier,
out=numpyData, casting="unsafe")
destinationDevice.write(numpy_data.tostring(), Chunk, exception_on_underflow=True)
The concept is that audio data is conceptually an array of samples, each one with a value that depends on the bit "depth". Standard digital audio (as CD audio) is at 44100kHz, 16bit, stereo, which means that each seconds has 88200 samples (since it's stereo) with each sample occupying 2 bytes (8bit + 8bit). If you equally change the value of each of those samples, you will actually change its volume.
Now, the problem is that perceived volume is not linear, but logarithmic. So, if you want to get twice the volume, you can't just double sample values.
I'm using a conversion I found out some years ago (from Ardour sliders, if I recall correctly), which should be accurate enough.
Be careful, though, you could easily get very high levels, which will result in distorted sound.