1#!/usr/bin/env python3 2# 3# Copyright 2024 Google LLC 4# 5# Licensed under the Apache License, Version 2.0 (the "License"); 6# you may not use this file except in compliance with the License. 7# You may obtain a copy of the License at 8# 9# http://www.apache.org/licenses/LICENSE-2.0 10# 11# Unless required by applicable law or agreed to in writing, software 12# distributed under the License is distributed on an "AS IS" BASIS, 13# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14# See the License for the specific language governing permissions and 15# limitations under the License. 16# 17 18import argparse 19import lc3 20import matplotlib 21import matplotlib.pyplot as plt 22import numpy as np 23import scipy.signal as signal 24 25matplotlib.use('QtAgg') 26 27parser = argparse.ArgumentParser(description='LC3 Encoder') 28 29parser.add_argument( 30 '--frame_duration', help='Frame duration (ms)', type=float, default=10) 31 32parser.add_argument( 33 '--sample_rate', help='Sampling frequency (Hz)', type=float, default=48000) 34 35parser.add_argument( 36 '--hrmode', help='Enable high-resolution mode', action='store_true') 37 38parser.add_argument( 39 '--bitrate', help='Bitrate (bps)', type=int, default=96000) 40 41parser.add_argument( 42 '--libpath', help='LC3 Library path') 43 44args = parser.parse_args() 45 46# --- Setup encoder + decoder --- 47 48fs = args.sample_rate 49 50enc = lc3.Encoder( 51 args.frame_duration, fs, hrmode=args.hrmode, libpath=args.libpath) 52dec = lc3.Decoder( 53 args.frame_duration, fs, hrmode=args.hrmode, libpath=args.libpath) 54 55frame_len = enc.get_frame_samples() 56delay_len = enc.get_delay_samples() 57 58# --- Generate 10 seconds chirp --- 59 60n = 10 * int(fs) 61t = np.arange(n - (n % frame_len)) / fs 62s = signal.chirp(t, f0=10, f1=fs/2, t1=t[-1], phi=-90, method='linear') 63 64# --- Encoding / decoding loop --- 65 66frame_size = enc.get_frame_bytes(args.bitrate) 67bitrate = enc.resolve_bitrate(frame_size) 68 69y = np.empty(len(s) + frame_len) 70 71for i in range(0, len(s), frame_len): 72 y[i:i+frame_len] = dec.decode(enc.encode(s[i:i+frame_len], frame_size)) 73 74y[len(s):] = dec.decode(enc.encode(np.zeros(frame_len), frame_size)) 75y = y[delay_len:len(s)+delay_len] 76 77# --- Plot spectrograms --- 78 79fig, (ax1, ax2) = plt.subplots(nrows=2, sharex=True) 80 81NFFT = 512 82for (ax, s) in [(ax1, s), (ax2, y)]: 83 ax.specgram(s, Fs=fs, NFFT=NFFT, pad_to=4*NFFT, noverlap=NFFT//2, 84 vmin=-160, vmax=0) 85 86ax1.set_title('Input signal') 87ax1.set_ylabel('Frequency (Hz)') 88 89ax2.set_title(('Processed signal (%.1f kbps)' % (bitrate/1000))) 90ax2.set_ylabel('Frequency (Hz)') 91 92plt.show() 93