package Audio::Opusfile;

use 5.014000;
use strict;
use warnings;
use Carp;

use parent qw/Exporter/;
use AutoLoader;

my @constants =
  qw/OPUS_CHANNEL_COUNT_MAX
	 OP_ABSOLUTE_GAIN
	 OP_DEC_FORMAT_FLOAT
	 OP_DEC_FORMAT_SHORT
	 OP_DEC_USE_DEFAULT
	 OP_EBADHEADER
	 OP_EBADLINK
	 OP_EBADPACKET
	 OP_EBADTIMESTAMP
	 OP_EFAULT
	 OP_EIMPL
	 OP_EINVAL
	 OP_ENOSEEK
	 OP_ENOTAUDIO
	 OP_ENOTFORMAT
	 OP_EOF
	 OP_EREAD
	 OP_EVERSION
	 OP_FALSE
	 OP_GET_SERVER_INFO_REQUEST
	 OP_HEADER_GAIN
	 OP_HOLE
	 OP_HTTP_PROXY_HOST_REQUEST
	 OP_HTTP_PROXY_PASS_REQUEST
	 OP_HTTP_PROXY_PORT_REQUEST
	 OP_HTTP_PROXY_USER_REQUEST
	 OP_PIC_FORMAT_GIF
	 OP_PIC_FORMAT_JPEG
	 OP_PIC_FORMAT_PNG
	 OP_PIC_FORMAT_UNKNOWN
	 OP_PIC_FORMAT_URL
	 OP_SSL_SKIP_CERTIFICATE_CHECK_REQUEST
	 OP_TRACK_GAIN/;

our @EXPORT_OK = @constants;
our @EXPORT = @constants;

our $VERSION = '0.003';

sub AUTOLOAD {
    # This AUTOLOAD is used to 'autoload' constants from the constant()
    # XS function.

    my $constname;
    our $AUTOLOAD;
    ($constname = $AUTOLOAD) =~ s/.*:://;
    croak "&Audio::Opusfile::constant not defined" if $constname eq 'constant';
    my ($error, $val) = constant($constname);
    if ($error) { croak $error; }
    {
	no strict 'refs';
	# Fixed between 5.005_53 and 5.005_61
#XXX	if ($] >= 5.00561) {
#XXX	    *$AUTOLOAD = sub () { $val };
#XXX	}
#XXX	else {
	    *$AUTOLOAD = sub { $val };
#XXX	}
    }
    goto &$AUTOLOAD;
}

require XSLoader;
XSLoader::load('Audio::Opusfile', $VERSION);
require Audio::Opusfile::Head;
require Audio::Opusfile::Tags;
require Audio::Opusfile::PictureTag;

# Preloaded methods go here.

sub new_from_file {
	my ($class, $file) = @_;
	open_file($file)
}

sub new_from_memory {
	my ($class, $buf) = @_;
	open_memory($buf)
}

1;
__END__

=encoding utf-8

=head1 NAME

Audio::Opusfile - Very incomplete interface to the libopusfile Ogg Opus library

=head1 SYNOPSIS

  use Audio::Opusfile;
  my $of = Audio::Opusfile->new_from_file('silence.opus');
  my $tags = $of->tags;
  say $tags->query('TITLE'); # Cellule

=head1 DESCRIPTION

Opus is a totally open, royalty-free, highly versatile audio codec.
Opus is unmatched for interactive speech and music transmission over
the Internet, but is also intended for storage and streaming
applications. It is standardized by the Internet Engineering Task
Force (IETF) as RFC 6716 which incorporated technology from Skype's
SILK codec and Xiph.Org's CELT codec.

libopusfile is a library for decoding and basic manipulation of Ogg
Opus files.

Audio::Opusfile is an interface to libopusfile. At the moment its only
function is reading metadata and tags from an Ogg Opus file or buffer.
Future versions will give access to a larger part of the libopusfile
API.

Expect the API to change in future versions.

=head1 METHODS

=over

=item Audio::Opusfile->B<new_from_file>(I<$file>)

Creates a new Audio::Opusfile object from an Ogg Opus file.

Dies if the given file does not exist or is not a valid Ogg Opus file.

=item Audio::Opusfile->B<new_from_memory>(I<$buffer>)

Creates a new Audio::Opusfile object from a buffer containing Ogg Opus
data.

Dies if the given buffer does not contain valid data.

=item Audio::Opusfile::test(I<$buffer>)

Returns true if the given buffer looks like the beginning of a valid
Ogg Opus file, false otherwise.

Dies if the given buffer does not have sufficient data to tell if it
is an Opus stream or if it looks like a Opus stream but parsing it
failed.

=item B<$of>->head

Returns an L<Audio::Opusfile::Head> object corresponding to the file.

=item B<$of>->tags

Returns an L<Audio::Opusfile::Tags> object corresponding to the file.

=item B<$of>->seekable

Returns whether or not the data source being read is seekable.

=item B<$of>->link_count

Returns the number of links in this chained stream. Always returns 1
for unseekable sources.

=item B<$of>->serialno([I<$link_index>])

Get the serial number of the given link in a (possibly-chained) Ogg
Opus stream. If the given index is greater than the total number of
links, this returns the serial number of the last link.

If the source is not seekable, I<$link_index> is negative, or
I<$link_index> is not given, then this function returns the serial
number of the current link.

=back

=head1 EXPORT

All constants are exported by default:

  OPUS_CHANNEL_COUNT_MAX
  OP_ABSOLUTE_GAIN
  OP_DEC_FORMAT_FLOAT
  OP_DEC_FORMAT_SHORT
  OP_DEC_USE_DEFAULT
  OP_EBADHEADER
  OP_EBADLINK
  OP_EBADPACKET
  OP_EBADTIMESTAMP
  OP_EFAULT
  OP_EIMPL
  OP_EINVAL
  OP_ENOSEEK
  OP_ENOTAUDIO
  OP_ENOTFORMAT
  OP_EOF
  OP_EREAD
  OP_EVERSION
  OP_FALSE
  OP_GET_SERVER_INFO_REQUEST
  OP_HEADER_GAIN
  OP_HOLE
  OP_HTTP_PROXY_HOST_REQUEST
  OP_HTTP_PROXY_PASS_REQUEST
  OP_HTTP_PROXY_PORT_REQUEST
  OP_HTTP_PROXY_USER_REQUEST
  OP_PIC_FORMAT_GIF
  OP_PIC_FORMAT_JPEG
  OP_PIC_FORMAT_PNG
  OP_PIC_FORMAT_UNKNOWN
  OP_PIC_FORMAT_URL
  OP_SSL_SKIP_CERTIFICATE_CHECK_REQUEST
  OP_TRACK_GAIN


=head1 SEE ALSO

L<Audio::Opusfile::Head>,
L<Audio::Opusfile::Tags>,
L<http://opus-codec.org/>,
L<http://opus-codec.org/docs/opusfile_api-0.7/index.html>

=head1 AUTHOR

Marius Gavrilescu, E<lt>marius@ieval.roE<gt>

=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
