#!/usr/bin/env python3 # # Copyright 2024 Google LLC # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # import argparse import lc3 import struct import sys import wave parser = argparse.ArgumentParser(description='LC3 Encoder') parser.add_argument( 'wav_file', nargs='?', help='Input wave file, default is stdin', type=argparse.FileType('rb'), default=sys.stdin.buffer) parser.add_argument( 'lc3_file', nargs='?', help='Output bitstream file, default is stdout', type=argparse.FileType('wb'), default=sys.stdout.buffer) parser.add_argument( '--bitrate', help='Bitrate in bps', type=int, required=True) parser.add_argument( '--frame_duration', help='Frame duration in ms', type=float, default=10) parser.add_argument( '--libpath', help='LC3 Library path') args = parser.parse_args() # --- WAV File input --- f_wav = args.wav_file wavfile = wave.open(f_wav, 'rb') samplerate = wavfile.getframerate() nchannels = wavfile.getnchannels() bitdepth = wavfile.getsampwidth() * 8 stream_length = wavfile.getnframes() # --- Setup encoder --- enc = lc3.Encoder( args.frame_duration, samplerate, nchannels, libpath=args.libpath) frame_size = enc.get_frame_bytes(args.bitrate) frame_length = enc.get_frame_samples() bitrate = enc.resolve_bitrate(frame_size) # --- Setup output --- f_lc3 = args.lc3_file f_lc3.write(struct.pack( '=HHHHHHHI', 0xcc1c, 18, samplerate // 100, bitrate // 100, nchannels, int(args.frame_duration * 100), 0, stream_length)) # --- Encoding loop --- for i in range(0, stream_length, frame_length): f_lc3.write(struct.pack('=H', frame_size)) pcm = wavfile.readframes(frame_length) f_lc3.write(enc.encode(pcm, frame_size, bitdepth=bitdepth)) # --- Cleanup --- wavfile.close() for f in (f_wav, f_lc3): if f is not sys.stdout.buffer: f.close()