From b9bd6a0d2a03539515f640a43bad1f54dca8b0b5 Mon Sep 17 00:00:00 2001 From: Marius Gavrilescu Date: Sat, 24 Sep 2016 22:04:10 +0100 Subject: [PATCH] Add Audio::Opusfile::Head --- MANIFEST | 1 + lib/Audio/Opusfile.pm | 2 + lib/Audio/Opusfile/Head.pm | 138 +++++++++++++++++++++++++++++++++++++ t/Audio-Opusfile.t | 17 ++++- 4 files changed, 157 insertions(+), 1 deletion(-) create mode 100644 lib/Audio/Opusfile/Head.pm diff --git a/MANIFEST b/MANIFEST index 6ef40cd..c5ea090 100644 --- a/MANIFEST +++ b/MANIFEST @@ -10,5 +10,6 @@ t/Audio-Opusfile.t fallback/const-c.inc fallback/const-xs.inc lib/Audio/Opusfile.pm +lib/Audio/Opusfile/Head.pm lib/Audio/Opusfile/Tags.pm lib/Audio/Opusfile/PictureTag.pm diff --git a/lib/Audio/Opusfile.pm b/lib/Audio/Opusfile.pm index bc91782..3c6a7c2 100644 --- a/lib/Audio/Opusfile.pm +++ b/lib/Audio/Opusfile.pm @@ -73,6 +73,7 @@ sub AUTOLOAD { require XSLoader; XSLoader::load('Audio::Opusfile', $VERSION); +require Audio::Opusfile::Head; require Audio::Opusfile::Tags; require Audio::Opusfile::PictureTag; @@ -219,6 +220,7 @@ All constants are exported by default: =head1 SEE ALSO +L, L, L, L diff --git a/lib/Audio/Opusfile/Head.pm b/lib/Audio/Opusfile/Head.pm new file mode 100644 index 0000000..a7c5877 --- /dev/null +++ b/lib/Audio/Opusfile/Head.pm @@ -0,0 +1,138 @@ +package Audio::Opusfile::Head; +# Don't load this module directly, load Audio::Opusfile instead + +use 5.014000; +use strict; +use warnings; + +our $VERSION = '0.003'; + +1; +__END__ + +=encoding utf-8 + +=head1 NAME + +Audio::Opusfile::Head - The header of an Ogg Opus file + +=head1 SYNOPSIS + + use blib; + use Audio::Opusfile; + my $of = Audio::Opusfile->new_from_file('empty.opus'); + my $head = $of->head; + say $head->version; # 1 + say $head->channel_count; # 2 + say $head->pre_skip; # 356 + say $head->input_sample_rate; # 44100 + say $head->output_gain; # 0 + say $head->mapping_family; # 0 + say $head->stream_count; # 1 + say $head->coupled_count; # 1 + say $head->mapping(0); # 0 + say $head->mapping(1); # 1 + +=head1 DESCRIPTION + +This module represents the header of an Ogg Opus file. See the +documentation of L for more information. + +=head1 METHODS + +=over + +=item $head->B + +The Ogg Opus format version, in the range 0...255. + +The top 4 bits represent a "major" version, and the bottom four bits +represent backwards-compatible "minor" revisions. + +The current specification describes version 1. + +=item $head->B + +The number of channels, in the range 1...255. + +=item $head->B + +The number of samples that should be discarded from the beginning of +the stream. + +=item $head->B + +The sampling rate of the original input. + +All Opus audio is coded at 48 kHz, and should also be decoded at 48 +kHz for playback (unless the target hardware does not support this +sampling rate). However, this field may be used to resample the audio +back to the original sampling rate, for example, when saving the +output to a file. + +=item $head->B + +The gain to apply to the decoded output, in dB, as a Q8 value in the +range -32768...32767. + +The libopusfile API will automatically apply this gain to the decoded +output before returning it, scaling it by +pow(10,output_gain/(20.0*256)). + +=item $head->B + +The channel mapping family, in the range 0...255. + +Channel mapping family 0 covers mono or stereo in a single stream. +Channel mapping family 1 covers 1 to 8 channels in one or more +streams, using the Vorbis speaker assignments. Channel mapping family +255 covers 1 to 255 channels in one or more streams, but without any +defined speaker assignment. + +=item $head->B + +The number of Opus streams in each Ogg packet, in the range 1...255. + +=item $head->B + +The number of coupled Opus streams in each Ogg packet, in the range +0...127. + +This must satisfy 0 <= coupled_count <= stream_count and coupled_count ++ stream_count <= 255. The coupled streams appear first, before all +uncoupled streams, in an Ogg Opus packet. + +=item $head->B(I<$k>) + +The mapping from coded stream channels to output channels. + +Let C<< index = mapping[k] >> be the value for channel I<$k>. If +C<< index < 2 * coupled_count >>, then it refers to the left channel +from stream C<< (index/2) >> if even, and the right channel from +stream C<< (index/2) >> if odd. Otherwise, it refers to the output of +the uncoupled stream C<< (index-coupled_count) >>. + +Dies if I<$k> is more than OPUS_CHANNEL_COUNT_MAX. + +=back + +=head1 SEE ALSO + +L, +L, +L + +=head1 AUTHOR + +Marius Gavrilescu, Emarius@ieval.roE + +=head1 COPYRIGHT AND LICENSE + +Copyright (C) 2016 by Marius Gavrilescu + +This library is free software; you can redistribute it and/or modify +it under the same terms as Perl itself, either Perl version 5.24.0 or, +at your option, any later version of Perl 5 you may have available. + + +=cut diff --git a/t/Audio-Opusfile.t b/t/Audio-Opusfile.t index ca00190..8ef7793 100644 --- a/t/Audio-Opusfile.t +++ b/t/Audio-Opusfile.t @@ -2,7 +2,7 @@ use strict; use warnings; -use Test::More tests => 12; +use Test::More tests => 23; BEGIN { use_ok('Audio::Opusfile') }; my $fail = 0; @@ -34,6 +34,21 @@ is $of->link_count, 1, 'link_count'; is $of->serialno(0), 1745145935, 'serialno, arg=0'; is $of->serialno(200), 1745145935, 'serialno, arg=200'; is $of->serialno, 1745145935, 'serialno, no arg'; + +my $head = $of->head; +is $head->version, 1, 'head->version'; +is $head->channel_count, 2, 'head->channel_count'; +is $head->pre_skip, 356, 'head->pre_skip'; +is $head->input_sample_rate, 44100, 'head->input_sample_rate'; +is $head->output_gain, 0, 'head->output_gain'; +is $head->mapping_family, 0, 'head->mapping_family'; +is $head->stream_count, 1, 'head->stream_count'; +is $head->coupled_count, 1, 'head->coupled_count'; +is $head->mapping(0), 0, 'head->mapping(0)'; +is $head->mapping(1), 1, 'head->mapping(1)'; +eval { $head->mapping(1000) }; +isn::t $@, '', 'head->mapping(1000) dies'; + my $tags = $of->tags; is $tags->query_count('TITLE'), 1, 'query_count'; is $tags->query('TITLE'), 'Cellule', 'query'; -- 2.30.2