astrick
astrick

Reputation: 308

How to mix multiple different frequency tones into one

I want to create an audio tone which consists of multiple frequency audios ranging from 2kHz-3kHz using python.

I created these functions to generate audio consisting of 2 tones of different frequency

import numpy as np
from scipy.io.wavfile import write


def generate_hightone():
    samplerate = 44100; fs = 2000
    time = 0.5
    t = np.linspace(0., time, round(samplerate*time))
    amplitude = np.iinfo(np.int16).max
    data = amplitude * np.sin(2. * np.pi * fs * t)
    data = np.int16(data/np.max(np.abs(data)) * 32767)
    return data


def generate_lowtone():
    samplerate = 44100; fs = 2200
    time = 0.5
    t = np.linspace(0., time, round(samplerate*time))
    amplitude = np.iinfo(np.int16).max
    print(amplitude)
    data = amplitude * np.sin(2. * np.pi * fs * t)
    data = np.int16(data/np.max(np.abs(data)) * 32767)
    return data


def freq_mixer(freq1,freq2):
    print(len(freq1),len(freq2))
    return np.round(freq1*0.5).astype(int) + np.round(freq2*0.5).astype(int)


data = freq_mixer(generate_hightone(),generate_lowtone())

write("example.wav", samplerate, data)

From this audio is saved but when I am playing this audio no tone is playing. When I save only single tone it is playing a sound but in case of mixing(output of freq_mixer) no sound is there.

Is there any other way of mixing multiple freq audio?

Output tone should be like this on spectrogramhttps://auditoryneuroscience.com/acoustics/spectrogram

Upvotes: 0

Views: 1160

Answers (2)

zvone
zvone

Reputation: 19352

The audio data should contain int16 values, because it is 16-bit audio.

The original tones are converted to int16 here:

data = np.int16(data/np.max(np.abs(data)) * 32767)

On the other hand, the mixer creates an int (which is same as int64) rather than int16, here:

np.round(freq1*0.5).astype(int) + np.round(freq2*0.5).astype(int)

Converting it to int16 would probably work, but it is in fact easier and faster to never go from int16 to float in the first place and simply do this instead:

freq1 // 2 + freq2 // 2

Upvotes: 1

William Baker Morrison
William Baker Morrison

Reputation: 1789

Change the frequency mixer to float or do a simple addition of the tones:

def freq_mixer(freq1,freq2):
    print(len(freq1),len(freq2))
    return np.round(freq1*0.5).astype(float) + np.round(freq2*0.5).astype(float)


data1 = generate_hightone()
data2 = generate_lowtone()
data3 = data1+data2 #simpler addition
data3 = freq_mixer(generate_hightone(),generate_lowtone())
samplerate = 80000
write("example.wav", samplerate, data3)

Upvotes: 0

Related Questions