2. Dealing with multi-channels audio file
[1]:
import pprint
import matplotlib.pyplot as plt
from cutcutcodec.core.classes.layout import AllLayouts
from cutcutcodec.core.compilation.export.compatibility import Compatibilities
from cutcutcodec.core.generation.audio.equation import GeneratorAudioEquation
from cutcutcodec.core.io import write
2.1. All supported audio layouts
2.1.1. Layouts and channels signification and convention
[2]:
# all supported layout by cutcutcodec
pprint.pprint(AllLayouts().layouts, compact=True)
{'2.1': ('fl', 'fr', 'lfe'),
'22.2': ('fl', 'fr', 'fc', 'lfe', 'bl', 'br', 'flc', 'frc', 'bc', 'sl', 'sr',
'tc', 'tfl', 'tfc', 'tfr', 'tbl', 'tbc', 'tbr', 'lfe2', 'tsl', 'tsr',
'bfc', 'bfl', 'bfr'),
'3.0': ('fl', 'fr', 'fc'),
'3.0(back)': ('fl', 'fr', 'bc'),
'3.1': ('fl', 'fr', 'fc', 'lfe'),
'3.1.2': ('fl', 'fr', 'fc', 'lfe', 'tfl', 'tfr'),
'4.0': ('fl', 'fr', 'fc', 'bc'),
'4.1': ('fl', 'fr', 'fc', 'lfe', 'bc'),
'5.0': ('fl', 'fr', 'fc', 'bl', 'br'),
'5.0(side)': ('fl', 'fr', 'fc', 'sl', 'sr'),
'5.1': ('fl', 'fr', 'fc', 'lfe', 'bl', 'br'),
'5.1(side)': ('fl', 'fr', 'fc', 'lfe', 'sl', 'sr'),
'5.1.2': ('fl', 'fr', 'fc', 'lfe', 'sl', 'sr', 'tfl', 'tfr'),
'5.1.2(back)': ('fl', 'fr', 'fc', 'lfe', 'bl', 'br', 'tfl', 'tfr'),
'5.1.4': ('fl', 'fr', 'fc', 'lfe', 'sl', 'sr', 'tfl', 'tfr', 'tbl', 'tbr'),
'6.0': ('fl', 'fr', 'fc', 'bc', 'sl', 'sr'),
'6.0(front)': ('fl', 'fr', 'flc', 'frc', 'sl', 'sr'),
'6.1': ('fl', 'fr', 'fc', 'lfe', 'bc', 'sl', 'sr'),
'6.1(back)': ('fl', 'fr', 'fc', 'lfe', 'bl', 'br', 'bc'),
'6.1(front)': ('fl', 'fr', 'lfe', 'flc', 'frc', 'sl', 'sr'),
'7.0': ('fl', 'fr', 'fc', 'bl', 'br', 'sl', 'sr'),
'7.0(front)': ('fl', 'fr', 'fc', 'flc', 'frc', 'sl', 'sr'),
'7.1': ('fl', 'fr', 'fc', 'lfe', 'bl', 'br', 'sl', 'sr'),
'7.1(wide)': ('fl', 'fr', 'fc', 'lfe', 'bl', 'br', 'flc', 'frc'),
'7.1(wide-side)': ('fl', 'fr', 'fc', 'lfe', 'flc', 'frc', 'sl', 'sr'),
'7.1.2': ('fl', 'fr', 'fc', 'lfe', 'bl', 'br', 'sl', 'sr', 'tfl', 'tfr'),
'7.1.4': ('fl', 'fr', 'fc', 'lfe', 'bl', 'br', 'sl', 'sr', 'tfl', 'tfr', 'tbl',
'tbr'),
'7.2.3': ('fl', 'fr', 'fc', 'lfe', 'bl', 'br', 'sl', 'sr', 'tfl', 'tfr', 'tbc',
'lfe2'),
'9.1.4': ('fl', 'fr', 'fc', 'lfe', 'bl', 'br', 'flc', 'frc', 'sl', 'sr', 'tfl',
'tfr', 'tbl', 'tbr'),
'9.1.6': ('fl', 'fr', 'fc', 'lfe', 'bl', 'br', 'flc', 'frc', 'sl', 'sr', 'tfl',
'tfr', 'tbl', 'tbr', 'tsl', 'tsr'),
'binaural': ('bil', 'bir'),
'cube': ('fl', 'fr', 'bl', 'br', 'tfl', 'tfr', 'tbl', 'tbr'),
'downmix': ('dl', 'dr'),
'hexadecagonal': ('fl', 'fr', 'fc', 'bl', 'br', 'bc', 'sl', 'sr', 'tfl', 'tfc',
'tfr', 'tbl', 'tbc', 'tbr', 'wl', 'wr'),
'hexagonal': ('fl', 'fr', 'fc', 'bl', 'br', 'bc'),
'mono': ('fc',),
'octagonal': ('fl', 'fr', 'fc', 'bl', 'br', 'bc', 'sl', 'sr'),
'quad': ('fl', 'fr', 'bl', 'br'),
'quad(side)': ('fl', 'fr', 'sl', 'sr'),
'stereo': ('fl', 'fr')}
[3]:
# the significance of each channel abreviation
pprint.pprint(AllLayouts().individuals)
{'bc': 'back center',
'bfc': 'bottom front center',
'bfl': 'bottom front left',
'bfr': 'bottom front right',
'bil': 'binaural left',
'bir': 'binaural right',
'bl': 'back left',
'br': 'back right',
'dl': 'downmix left',
'dr': 'downmix right',
'fc': 'front center',
'fl': 'front left',
'flc': 'front left-of-center',
'fr': 'front right',
'frc': 'front right-of-center',
'lfe': 'low frequency',
'lfe2': 'low frequency 2',
'sdl': 'surround direct left',
'sdr': 'surround direct right',
'sl': 'side left',
'sr': 'side right',
'ssl': 'side surround left',
'ssr': 'side surround right',
'tbc': 'top back center',
'tbl': 'top back left',
'tbr': 'top back right',
'tc': 'top center',
'tfc': 'top front center',
'tfl': 'top front left',
'tfr': 'top front right',
'tsl': 'top side left',
'tsr': 'top side right',
'ttl': 'top surround left',
'ttr': 'top surround right',
'wl': 'wide left',
'wr': 'wide right'}
2.1.2. Audio layout and codec compatibility
[4]:
pprint.pprint(Compatibilities().codecs_audio(layout="5.1"), compact=True)
Testing encoder/muxer: 100%|██████████████████████████████████████████████████████████████████████████████████████████████████████████████████| 12775/12775 [00:01<00:00, 6438.82comb/s]
Testing encoder/muxer: 82%|█████████████████████████████████████████████████████████████████████████████████████████████▏ | 10437/12775 [00:01<00:00, 5477.89comb/s]
{'aac': [('aac', '3g2'), ('aac', '3gp'), ('aac', 'adts'), ('aac', 'asf'),
('aac', 'avi'), ('aac', 'f4v'), ('aac', 'flv'), ('aac', 'ipod'),
('aac', 'ismv'), ('aac', 'matroska'), ('aac', 'mov'), ('aac', 'mp4'),
('aac', 'mpegts'), ('aac', 'nut'), ('aac', 'rm'), ('aac', 'w64'),
('aac', 'wav'), ('aac', 'wtv')],
'aac_latm': [('aac', 'latm')],
'alac': [('alac', 'caf'), ('alac', 'ipod'), ('alac', 'ismv'),
('alac', 'matroska'), ('alac', 'mov'), ('alac', 'mp4')],
'vorbis': [('libvorbis', 'asf'), ('libvorbis', 'avi'), ('libvorbis', 'ismv'),
('libvorbis', 'matroska'), ('libvorbis', 'mp4'),
('libvorbis', 'nut'), ('libvorbis', 'oga'), ('libvorbis', 'ogg'),
('libvorbis', 'ogv'), ('libvorbis', 'opus'), ('libvorbis', 'spx'),
('libvorbis', 'w64'), ('libvorbis', 'wav'), ('libvorbis', 'webm'),
('libvorbis', 'wtv')],
'wavpack': [('wavpack', 'matroska'), ('wavpack', 'nut'), ('wavpack', 'wv')]}
2.2. Create multi-channel streams
[5]:
signal_stereo = GeneratorAudioEquation(
"sin(2*pi*220*t)*sin(2*pi*1*t)**2", "sin(2*pi*220*t)*cos(2*pi*1*t)**2"
)
signal_3_1 = GeneratorAudioEquation(
"sin(2*pi*440*t)", # fl
"cos(2*pi*440*t)", # fr
"sin(2*pi*523*t)", # fc
"sin(2.pi*27.5*t)", # lfe
layout="3.1",
)
2.2.1. Combine the channels of the different streams
[6]:
mix = (signal_stereo | signal_3_1).apply_audio_equation( # mix the channels as a 5.1 layer ('fl', 'fr', 'fc', 'lfe', 'bl', 'br'),
"(fl_0+fl_1)/2", # fl
"(fl_0+fl_1)/2", # fr
"0.8*fc_1 + 0.1*fl_0 + 0.1*fr_0", # fc
"lfe_1", # lfe
"(fl_0+fl_1)/2", # bl
"(fr_0+fr_1)/2", # br
)
(mix_stream,) = mix.out_streams
[7]:
frame = mix_stream.snapshot(0, 44100, 1024) # time, sample rate, nbr samples
[8]:
plt.plot(frame.timestamps, frame.T)
plt.xlabel("time (s)")
plt.ylabel("amplitude")
plt.title(
f"{frame.layout.name} audio frame at {frame.rate} Hz "
f"containing {frame.samples} samples starting at time {frame.time} s"
)
plt.show()
2.3. Write a multichannels audio file
[9]:
mix_cut = mix.apply_audio_subclip(0, 10) # select the 10 first seconds
write(mix_cut.out_streams, "/tmp/audio_5.1.opus", [{"encodec": "libvorbis", "rate": 44100}])
Encoding audio_5.1.opus: 100%|█████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████| 10.00s/10.00s [00:00<00:00]