1cabdff1aSopenharmony_ci#!/usr/bin/env perl 2cabdff1aSopenharmony_ci 3cabdff1aSopenharmony_ci# Copyright (c) 2012 Nicolas George 4cabdff1aSopenharmony_ci# 5cabdff1aSopenharmony_ci# This file is part of FFmpeg. 6cabdff1aSopenharmony_ci# 7cabdff1aSopenharmony_ci# FFmpeg is free software; you can redistribute it and/or 8cabdff1aSopenharmony_ci# modify it under the terms of the GNU Lesser General Public 9cabdff1aSopenharmony_ci# License as published by the Free Software Foundation; either 10cabdff1aSopenharmony_ci# version 2.1 of the License, or (at your option) any later version. 11cabdff1aSopenharmony_ci# 12cabdff1aSopenharmony_ci# FFmpeg is distributed in the hope that it will be useful, 13cabdff1aSopenharmony_ci# but WITHOUT ANY WARRANTY; without even the implied warranty of 14cabdff1aSopenharmony_ci# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 15cabdff1aSopenharmony_ci# See the GNU Lesser General Public License for more details. 16cabdff1aSopenharmony_ci# 17cabdff1aSopenharmony_ci# You should have received a copy of the GNU Lesser General Public License 18cabdff1aSopenharmony_ci# along with FFmpeg; if not, write to the Free Software Foundation, Inc., 19cabdff1aSopenharmony_ci# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 20cabdff1aSopenharmony_ci 21cabdff1aSopenharmony_ci=head1 NAME 22cabdff1aSopenharmony_ci 23cabdff1aSopenharmony_cimake_chlayout_test - produce a multichannel test file with the channels 24cabdff1aSopenharmony_ciclearly identified 25cabdff1aSopenharmony_ci 26cabdff1aSopenharmony_ci=head1 SYNOPSIS 27cabdff1aSopenharmony_ci 28cabdff1aSopenharmony_citools/make_chlayout_test I<channels> I<out_options> 29cabdff1aSopenharmony_ci 30cabdff1aSopenharmony_ci=head1 DESCRIPTION 31cabdff1aSopenharmony_ci 32cabdff1aSopenharmony_ciThis script uses B<ffmpeg> and B<libflite> to produce a file with audio 33cabdff1aSopenharmony_cichannels clearly identified by their name. The resulting file can be used to 34cabdff1aSopenharmony_cicheck that the layout and order of channels is correctly handled by a piece 35cabdff1aSopenharmony_ciof software, either a part of B<FFmpeg> or not. 36cabdff1aSopenharmony_ci 37cabdff1aSopenharmony_ciI<channels> is a list of channels or channel layouts, separated by '+'. 38cabdff1aSopenharmony_ci 39cabdff1aSopenharmony_ciI<out_options> is a list of valid ffmpeg outout options, including the 40cabdff1aSopenharmony_cioutput file. 41cabdff1aSopenharmony_ci 42cabdff1aSopenharmony_ciNote that some output codecs or formats can not handle arbitrary channel 43cabdff1aSopenharmony_cilayout. 44cabdff1aSopenharmony_ci 45cabdff1aSopenharmony_ciThis script requires a B<ffmpeg> binary, either in the source tree or in the 46cabdff1aSopenharmony_cisearch path; it must have the flite audio source enabled. 47cabdff1aSopenharmony_ci 48cabdff1aSopenharmony_ci=head1 EXAMPLES 49cabdff1aSopenharmony_ci 50cabdff1aSopenharmony_ciCheck that the speakers are correctly plugged: 51cabdff1aSopenharmony_ci 52cabdff1aSopenharmony_ci tools/make_chlayout_test FL+FR -f alsa default 53cabdff1aSopenharmony_ci 54cabdff1aSopenharmony_ciProduce a 5.1 FLAC file: 55cabdff1aSopenharmony_ci 56cabdff1aSopenharmony_ci tools/make_chlayout_test 5.1 surround.flac 57cabdff1aSopenharmony_ci 58cabdff1aSopenharmony_ci=cut 59cabdff1aSopenharmony_ci 60cabdff1aSopenharmony_ciuse strict; 61cabdff1aSopenharmony_ciuse warnings; 62cabdff1aSopenharmony_ciuse Getopt::Long ":config" => "require_order"; 63cabdff1aSopenharmony_ciuse Pod::Usage; 64cabdff1aSopenharmony_ci 65cabdff1aSopenharmony_ciGetOptions ( 66cabdff1aSopenharmony_ci "help|usage|?|h" => sub { pod2usage({ -verbose => 1, -exitval => 0 }) }, 67cabdff1aSopenharmony_ci "manpage|m" => sub { pod2usage({ -verbose => 2, -exitval => 0 }) }, 68cabdff1aSopenharmony_ci) and @ARGV >= 2 or pod2usage({ -verbose => 1, -exitval => 1 }); 69cabdff1aSopenharmony_ci 70cabdff1aSopenharmony_cimy $channels = shift @ARGV; 71cabdff1aSopenharmony_cimy @out_options = @ARGV; 72cabdff1aSopenharmony_ci 73cabdff1aSopenharmony_cimy $ffmpeg = exists $ENV{FFMPEG} ? $ENV{FFMPEG} : 74cabdff1aSopenharmony_ci $0 =~ /(.*)\// && -e "$1/../ffmpeg" ? "$1/../ffmpeg" : 75cabdff1aSopenharmony_ci "ffmpeg"; 76cabdff1aSopenharmony_ci 77cabdff1aSopenharmony_cimy %channel_label_to_descr; 78cabdff1aSopenharmony_cimy %layout_to_channels; 79cabdff1aSopenharmony_ci 80cabdff1aSopenharmony_ci{ 81cabdff1aSopenharmony_ci open my $stderr, ">&STDERR"; 82cabdff1aSopenharmony_ci open STDERR, ">", "/dev/null"; 83cabdff1aSopenharmony_ci open my $f, "-|", $ffmpeg, "-layouts" or die "$ffmpeg: $!\n"; 84cabdff1aSopenharmony_ci open STDERR, ">&", $stderr; 85cabdff1aSopenharmony_ci while (<$f>) { 86cabdff1aSopenharmony_ci chomp; 87cabdff1aSopenharmony_ci next if /^NAME/ or /:$/ or /^$/; # skip headings 88cabdff1aSopenharmony_ci my ($name, $descr) = split " ", $_, 2; 89cabdff1aSopenharmony_ci next unless $descr; 90cabdff1aSopenharmony_ci if ($descr =~ /^[[:upper:]]+(?:\+[[:upper:]]+)*$/) { 91cabdff1aSopenharmony_ci $layout_to_channels{$name} = [ split /\+/, $descr ]; 92cabdff1aSopenharmony_ci } else { 93cabdff1aSopenharmony_ci $channel_label_to_descr{$name} = $descr; 94cabdff1aSopenharmony_ci } 95cabdff1aSopenharmony_ci } 96cabdff1aSopenharmony_ci} 97cabdff1aSopenharmony_ci 98cabdff1aSopenharmony_cimy @channels = map { @{$layout_to_channels{$_} // [$_]} } split /\+/, $channels; 99cabdff1aSopenharmony_ci 100cabdff1aSopenharmony_cimy $layout = join "+", @channels; 101cabdff1aSopenharmony_cimy $graph = ""; 102cabdff1aSopenharmony_cimy $concat_in = ""; 103cabdff1aSopenharmony_cifor my $i (0 .. $#channels) { 104cabdff1aSopenharmony_ci my $label = $channels[$i]; 105cabdff1aSopenharmony_ci my $descr = $channel_label_to_descr{$label} 106cabdff1aSopenharmony_ci or die "Channel $label not found\n"; 107cabdff1aSopenharmony_ci $graph .= "flite=text='${descr}', aformat=channel_layouts=mono, " . 108cabdff1aSopenharmony_ci "pan=${layout}:${label}=c0 [ch$i] ;\n"; 109cabdff1aSopenharmony_ci $concat_in .= "[ch$i] "; 110cabdff1aSopenharmony_ci} 111cabdff1aSopenharmony_ci$graph .= "${concat_in}concat=v=0:a=1:n=" . scalar(@channels); 112cabdff1aSopenharmony_ci 113cabdff1aSopenharmony_ciexec $ffmpeg, "-f", "lavfi", "-i", $graph, @out_options 114cabdff1aSopenharmony_ci or die "$ffmpeg: $!\n"; 115