blob: 9e6ff1f9f706bb69715f00fc7679828c5e4ca189 [file] [log] [blame]
Alex Tawsedaba3cf2023-09-29 15:55:38 +01001# SPDX-FileCopyrightText: Copyright 2021, 2023 Arm Limited and/or its affiliates <open-source-office@arm.com>
Richard Burton00553462021-11-10 16:27:14 +00002# SPDX-License-Identifier: Apache-2.0
3#
4# Licensed under the Apache License, Version 2.0 (the "License");
5# you may not use this file except in compliance with the License.
6# You may obtain a copy of the License at
7#
8# http://www.apache.org/licenses/LICENSE-2.0
9#
10# Unless required by applicable law or agreed to in writing, software
11# distributed under the License is distributed on an "AS IS" BASIS,
12# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13# See the License for the specific language governing permissions and
14# limitations under the License.
Richard Burton00553462021-11-10 16:27:14 +000015"""
16This script can be used with the noise reduction use case to save
17the dumped noise reduced audio to a wav file.
18
19Example use:
20python rnnoise_dump_extractor.py --dump_file output.bin --output_dir ./denoised_wavs/
21"""
Richard Burton17069622022-03-17 10:54:26 +000022
Richard Burton00553462021-11-10 16:27:14 +000023import argparse
Richard Burton00553462021-11-10 16:27:14 +000024import struct
Alex Tawsedaba3cf2023-09-29 15:55:38 +010025import typing
26from os import path
27
28import numpy as np
29import soundfile as sf
Richard Burton00553462021-11-10 16:27:14 +000030
Richard Burton17069622022-03-17 10:54:26 +000031
Alex Tawsedaba3cf2023-09-29 15:55:38 +010032def extract(
33 dump_file: typing.IO,
34 output_dir: str,
35 export_npy: bool
36):
37 """
38 Extract audio file from RNNoise output dump
39
40 @param dump_file: Audio dump file location
41 @param output_dir: Output direction
42 @param export_npy: Whether to export the audio as .npy
43 """
Richard Burton00553462021-11-10 16:27:14 +000044 while True:
Alex Tawsedaba3cf2023-09-29 15:55:38 +010045 filename_length = struct.unpack("i", dump_file.read(4))[0]
Richard Burton00553462021-11-10 16:27:14 +000046
47 if filename_length == -1:
48 return
49
Alex Tawsedaba3cf2023-09-29 15:55:38 +010050 filename = struct \
51 .unpack(f"{filename_length}s", dump_file.read(filename_length))[0] \
52 .decode('ascii')
53
54 audio_clip_length = struct.unpack("I", dump_file.read(4))[0]
55 output_file_name = path.join(output_dir, f"denoised_{filename}")
56 audio_clip = dump_file.read(audio_clip_length)
57
58 with sf.SoundFile(output_file_name, 'w', channels=1, samplerate=48000, subtype="PCM_16",
59 endian="LITTLE") as wav_file:
Richard Burton00553462021-11-10 16:27:14 +000060 wav_file.buffer_write(audio_clip, dtype='int16')
Alex Tawsedaba3cf2023-09-29 15:55:38 +010061 print(f"{output_file_name} written to disk")
Richard Burton00553462021-11-10 16:27:14 +000062
63 if export_npy:
64 output_file_name += ".npy"
Alex Tawsedaba3cf2023-09-29 15:55:38 +010065 pack_format = f"{int(audio_clip_length / 2)}h"
Richard Burton17069622022-03-17 10:54:26 +000066 npdata = np.array(struct.unpack(pack_format, audio_clip)).astype(np.int16)
Richard Burton00553462021-11-10 16:27:14 +000067 np.save(output_file_name, npdata)
Alex Tawsedaba3cf2023-09-29 15:55:38 +010068 print(f"{output_file_name} written to disk")
Richard Burton00553462021-11-10 16:27:14 +000069
Richard Burton17069622022-03-17 10:54:26 +000070
Richard Burton00553462021-11-10 16:27:14 +000071def main(args):
Alex Tawsedaba3cf2023-09-29 15:55:38 +010072 """
73 Run RNNoise audio dump extraction
74 @param args: Parsed args
75 """
Richard Burton00553462021-11-10 16:27:14 +000076 extract(args.dump_file, args.output_dir, args.export_npy)
77
Richard Burton17069622022-03-17 10:54:26 +000078
Richard Burton00553462021-11-10 16:27:14 +000079parser = argparse.ArgumentParser()
Alex Tawsedaba3cf2023-09-29 15:55:38 +010080
81parser.add_argument(
82 "--dump_file",
83 type=argparse.FileType('rb'),
84 help="Dump file with audio files to extract.",
85 required=True
86)
87
88parser.add_argument(
89 "--output_dir",
90 help="Output directory, Warning: Duplicated file names will be overwritten.",
91 required=True
92)
93
94parser.add_argument(
95 "--export_npy",
96 help="Export the audio buffer in NumPy format",
97 action="store_true"
98)
99
100parsed_args = parser.parse_args()
Richard Burton00553462021-11-10 16:27:14 +0000101
Richard Burton17069622022-03-17 10:54:26 +0000102if __name__ == "__main__":
Alex Tawsedaba3cf2023-09-29 15:55:38 +0100103 main(parsed_args)