Audio

How to get duration of WAV file in Python (minimal example)

Use

duration_seconds = mywav.getnframes() / mywav.getframerate()

to get the duration of a WAV file in seconds.

Full example:

import wave

with wave.open("myaudio.wav") as mywav:
    duration_seconds = mywav.getnframes() / mywav.getframerate()
    print(f"Length of the WAV file: {duration_seconds:.1f} s")

 

Posted by Uli Köhler in Audio, Python

How to auto-set Windows audio balance to a specific L-R difference using Python

When you can’t place your speakers equally far from your ears, you need to adjust the audio balance in order to compensate for the perceived difference in volume.

Windows allows you to compensate the audio volume natively using the system settings – however it has one critical issue: If you ever set your audio volume to zero, your balance settings get lost and you need to click through plenty of dialogs in order to re-configure it.

In our previous post How to set Windows audio balance using Python we showed how tp use the pycaw library to  (see that post for installation instructions etc).

The following Python script can be run to set the audio balance to. It has been designed to keep the mean (i.e. L+R) audio level in dB when adjusting the volume (i.e. it will not change the overall volume and hence avoid blowing out your eardrums) and will not do any adjustment if the balance is already within 0.1 dB.

Set desiredDelta to your desired left-right difference in dB (positive values mean that the left speaker will be louder than the right speaker)!

from ctypes import cast, POINTER
from comtypes import CLSCTX_ALL
from pycaw.pycaw import AudioUtilities, IAudioEndpointVolume
import math

# Get default audio device using PyCAW
devices = AudioUtilities.GetSpeakers()
interface = devices.Activate(
    IAudioEndpointVolume._iid_, CLSCTX_ALL, None)
volume = cast(interface, POINTER(IAudioEndpointVolume))

# Get current volume of the left channel
currentVolumeLeft = volume.GetChannelVolumeLevel(0)
# Set the volume of the right channel to half of the volume of the left channel
volumeL = volume.GetChannelVolumeLevel(0)
volumeR = volume.GetChannelVolumeLevel(1)
print(f"Before adjustment: L={volumeL:.2f} dB, R={volumeR:.2f} dB")

desiredDelta = 6.0 # Desired delta between L and R. Positive means L is louder!

delta = abs(volumeR - volumeL)
mean = (volumeL + volumeR) / 2.

# Re-configure balance if delta is not 
if abs(delta - desiredDelta) > 0.1:
    # Adjust volume
    volume.SetChannelVolumeLevel(0, mean + desiredDelta/2., None) # Left
    volume.SetChannelVolumeLevel(1, mean - desiredDelta/2., None) # Right
    # Get & print new volume
    volumeL = volume.GetChannelVolumeLevel(0)
    volumeR = volume.GetChannelVolumeLevel(1)
    print(f"After adjustment: L={volumeL:.2f} dB, R={volumeR:.2f} dB")
else:
    print("No adjustment neccessary")

 

Posted by Uli Köhler in Audio, Python, Windows

How to set Windows audio balance using Python

In our previous post we showed how to set the Windows audio volume using pycaw.

First, we install the library using

pip install pycaw

Note: pycaw does not work with WSL (Windows Subsystem for Linux)! You actually need to install it using a Python environment running on Windows. I recommend Anaconda.

In order to set the audio balance, we can use volume.SetChannelVolumeLevel(...):

from ctypes import cast, POINTER
from comtypes import CLSCTX_ALL
from pycaw.pycaw import AudioUtilities, IAudioEndpointVolume
import math

# Get default audio device using PyCAW
devices = AudioUtilities.GetSpeakers()
interface = devices.Activate(
    IAudioEndpointVolume._iid_, CLSCTX_ALL, None)
volume = cast(interface, POINTER(IAudioEndpointVolume))

# Get current volume of the left channel
currentVolumeLeft = volume.GetChannelVolumeLevel(0)
# Set the volume of the right channel to half of the volume of the left channel
volume.SetChannelVolumeLevel(1, currentVolumeLeft - 6.0, None)
# NOTE: -6.0 dB = half volume !

Note that by convention, the left channel is channel 0 and the right channel is channel 1. Depending on the type of sound card, there might be as few as 1 channel (e.g. a mono headset) or many channels like in a multichannel USB audio interface. use volume.GetChannelCount() to get the number of channels.

Posted by Uli Köhler in Audio, Python, Windows

How to set Windows audio volume using Python

We can use the pycaw library to set the Windows Audio volume using Python.

First, we install the library using

pip install pycaw

Note: pycaw does not work with WSL (Windows Subsystem for Linux)! You actually need to install it using a Python environment running on Windows. I recommend Anaconda.

Now we can set the volume to half the current volume using this script:

from ctypes import cast, POINTER
from comtypes import CLSCTX_ALL
from pycaw.pycaw import AudioUtilities, IAudioEndpointVolume
import math

# Get default audio device using PyCAW
devices = AudioUtilities.GetSpeakers()
interface = devices.Activate(
    IAudioEndpointVolume._iid_, CLSCTX_ALL, None)
volume = cast(interface, POINTER(IAudioEndpointVolume))

# Get current volume 
currentVolumeDb = volume.GetMasterVolumeLevel()
volume.SetMasterVolumeLevel(currentVolumeDb - 6.0, None)
# NOTE: -6.0 dB = half volume !

 

Posted by Uli Köhler in Audio, Python, Windows

How to re-encode your Audiobooks as Opus

Opus is a modern high-efficiency audio codec that is especially suited to encode speech with very low bitrates.

Therefore, it’s a good fit to compress your Audiobook library so it consumes much less space.

First, choose a bitrate for Opus. I recommend to use 24kbit/s (24k) for general use, or 32 kbit/s (32k) if you want to have higher quality audio, e.g. if you are listening using good-quality headphones.

You can use ffmpeg directly by using this syntax:

ffmpeg -i <input file> -c:a libopus -b:a bitrate <output file>

but I recommend to use this shell function instead:

function audioToOpus { ffmpeg -i "$2" -c:a libopus -b:a "$1" "${2%.*}.opus" ; }

Copy & paste it into your shell, then call it like this:

audioToOpus <bitrate> <input file>

Example:

audioToOpus 24k myaudiobook.mp3

This command will create myaudiobook.opus. myaudiobook.mp3 will not be deleted automatically.

In case you want to have this function available permanently, add the function definition to your ~/.bashrc or ~/.zshrc, depending on which shell you use.

Posted by Uli Köhler in Audio, Linux