Removed the "native" ogg, vorbis, theora and speex plugins in favor
of support for these codecs and demuxer in the FFmpeg plugin. The ogg test streams I downloaded play fine now. For example, Big Buck Bunny would play without video before and ogg files natively encoded with the FFmpeg plugin wouldn't play at all. Since the removed plugins were not maintained and were based on external libs themselves, I didn't see the point in keeping them. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@38646 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
parent
594039f10d
commit
5021eb2421
@ -141,10 +141,8 @@ SYSTEM_ADD_ONS_MEDIA = cortex_audioadapter.media_addon
|
||||
;
|
||||
SYSTEM_ADD_ONS_MEDIA_PLUGINS = $(GPL_ONLY)ac3_decoder
|
||||
aiff_reader asf_reader au_reader $(X86_ONLY)ffmpeg
|
||||
mov_reader musepack ogg raw_decoder speex
|
||||
$(X86_ONLY)ape_reader
|
||||
# theora
|
||||
vorbis wav_reader
|
||||
mov_reader musepack raw_decoder $(X86_ONLY)ape_reader
|
||||
wav_reader
|
||||
;
|
||||
SYSTEM_ADD_ONS_PRINT = Canon\ LIPS3\ Compatible Canon\ LIPS4\ Compatible
|
||||
PCL5\ Compatible PCL6\ Compatible PDF\ Writer PS\ Compatible Preview
|
||||
|
@ -12,11 +12,7 @@ SubInclude HAIKU_TOP src add-ons media plugins matroska ;
|
||||
SubInclude HAIKU_TOP src add-ons media plugins mov_reader ;
|
||||
SubInclude HAIKU_TOP src add-ons media plugins mp4_reader ;
|
||||
SubInclude HAIKU_TOP src add-ons media plugins musepack ;
|
||||
SubInclude HAIKU_TOP src add-ons media plugins ogg ;
|
||||
SubInclude HAIKU_TOP src add-ons media plugins raw_decoder ;
|
||||
SubInclude HAIKU_TOP src add-ons media plugins speex ;
|
||||
#SubInclude HAIKU_TOP src add-ons media plugins theora ;
|
||||
SubInclude HAIKU_TOP src add-ons media plugins vorbis ;
|
||||
SubInclude HAIKU_TOP src add-ons media plugins wav_reader ;
|
||||
|
||||
# The following add-ons are GPL licensed, and can only be used with
|
||||
|
@ -446,6 +446,31 @@ AVFormatReader::StreamCookie::Init(int32 virtualIndex)
|
||||
description.family = B_WAV_FORMAT_FAMILY;
|
||||
codecTag = ' DTS';
|
||||
break;
|
||||
case CODEC_ID_THEORA:
|
||||
// Use the same format description as the native Ogg
|
||||
// reader and decoder did.
|
||||
description.family = B_MISC_FORMAT_FAMILY;
|
||||
// TODO: The rest of this plugin (Decoders/Encoders) does not support
|
||||
// this yet, specifying it would throw off the format matching.
|
||||
// description.u.misc.file_format = 'OggS';
|
||||
codecTag = 'theo';
|
||||
break;
|
||||
case CODEC_ID_SPEEX:
|
||||
// Use the same format description as the native Ogg
|
||||
// reader and decoder did.
|
||||
description.family = B_MISC_FORMAT_FAMILY;
|
||||
// TODO: See above.
|
||||
// description.u.misc.file_format = 'OggS';
|
||||
codecTag = 'spex';
|
||||
break;
|
||||
case CODEC_ID_VORBIS:
|
||||
// Use the same format description as the native Ogg
|
||||
// reader and decoder did.
|
||||
description.family = B_MISC_FORMAT_FAMILY;
|
||||
// TODO: See above.
|
||||
// description.u.misc.file_format = 'OggS';
|
||||
codecTag = 'vorb';
|
||||
break;
|
||||
default:
|
||||
fprintf(stderr, "ffmpeg codecTag is null, codec_id "
|
||||
"unknown 0x%x\n", codecContext->codec_id);
|
||||
@ -627,6 +652,8 @@ if (format->u.encoded_video.output.field_rate == 50.0f)
|
||||
= codecContext->width;
|
||||
format->u.encoded_video.output.display.line_count
|
||||
= codecContext->height;
|
||||
TRACE(" width/height: %d/%d\n", codecContext->width,
|
||||
codecContext->height);
|
||||
format->u.encoded_video.output.display.bytes_per_row = 0;
|
||||
format->u.encoded_video.output.display.pixel_offset = 0;
|
||||
format->u.encoded_video.output.display.line_offset = 0;
|
||||
@ -647,10 +674,10 @@ if (format->u.encoded_video.output.field_rate == 50.0f)
|
||||
}
|
||||
|
||||
TRACE(" extradata_size: %d\n", codecContext->extradata_size);
|
||||
TRACE(" intra_matrix: %p\n", codecContext->intra_matrix);
|
||||
TRACE(" inter_matrix: %p\n", codecContext->inter_matrix);
|
||||
TRACE(" get_buffer(): %p\n", codecContext->get_buffer);
|
||||
TRACE(" release_buffer(): %p\n", codecContext->release_buffer);
|
||||
// TRACE(" intra_matrix: %p\n", codecContext->intra_matrix);
|
||||
// TRACE(" inter_matrix: %p\n", codecContext->inter_matrix);
|
||||
// TRACE(" get_buffer(): %p\n", codecContext->get_buffer);
|
||||
// TRACE(" release_buffer(): %p\n", codecContext->release_buffer);
|
||||
|
||||
#ifdef TRACE_AVFORMAT_READER
|
||||
char formatString[512];
|
||||
|
@ -214,6 +214,10 @@ const struct codec_table gCodecTable[] = {
|
||||
{CODEC_ID_INDEO3, B_MEDIA_ENCODED_VIDEO, B_AVI_FORMAT_FAMILY, FOURCC('IV31'), "Indeo 3"},
|
||||
{CODEC_ID_INDEO3, B_MEDIA_ENCODED_VIDEO, B_AVI_FORMAT_FAMILY, FOURCC('IV32'), "Indeo 3"},
|
||||
|
||||
{CODEC_ID_THEORA, B_MEDIA_ENCODED_VIDEO, B_MISC_FORMAT_FAMILY, 'theo', "Theora"},
|
||||
{CODEC_ID_VORBIS, B_MEDIA_ENCODED_AUDIO, B_MISC_FORMAT_FAMILY, 'vorb', "Vorbis"},
|
||||
{CODEC_ID_SPEEX, B_MEDIA_ENCODED_AUDIO, B_MISC_FORMAT_FAMILY, 'spex', "Speex"},
|
||||
|
||||
{CODEC_ID_VP3, B_MEDIA_ENCODED_VIDEO, B_QUICKTIME_FORMAT_FAMILY, 'VP31', "On2 VP3"},
|
||||
{CODEC_ID_VP6F, B_MEDIA_ENCODED_VIDEO, B_QUICKTIME_FORMAT_FAMILY, 'VP6F', "On2 VP6"},
|
||||
|
||||
|
@ -84,6 +84,13 @@ static const DemuxerFormat gDemuxerTable[] = {
|
||||
"nsv", "NSV (NullSoft Video File)", "video/nsv",
|
||||
B_QUICKTIME_FORMAT_FAMILY, B_QUICKTIME_FORMAT_FAMILY
|
||||
},
|
||||
{
|
||||
// Works fine, expect for seeking in clips generated by
|
||||
// native software when the video and audio stream are
|
||||
// not interleaved.
|
||||
"ogg", "Ogg", "video/ogg",
|
||||
B_MISC_FORMAT_FAMILY, B_MISC_FORMAT_FAMILY
|
||||
},
|
||||
{
|
||||
// TODO: untested!
|
||||
"rm", "RM (RealVideo Clip)", "video/vnd.rn-realvideo",
|
||||
|
@ -34,6 +34,7 @@ Addon ffmpeg :
|
||||
libswscale.a
|
||||
|
||||
libvorbis_ffmpeg.a
|
||||
libspeex_ffmpeg.a
|
||||
libtheora_ffmpeg.a
|
||||
libogg_ffmpeg.a
|
||||
|
||||
@ -109,5 +110,6 @@ SubInclude HAIKU_TOP src add-ons media plugins ffmpeg libavformat ;
|
||||
SubInclude HAIKU_TOP src add-ons media plugins ffmpeg libavutil ;
|
||||
SubInclude HAIKU_TOP src add-ons media plugins ffmpeg libogg ;
|
||||
SubInclude HAIKU_TOP src add-ons media plugins ffmpeg libswscale ;
|
||||
SubInclude HAIKU_TOP src add-ons media plugins ffmpeg libspeex ;
|
||||
SubInclude HAIKU_TOP src add-ons media plugins ffmpeg libtheora ;
|
||||
SubInclude HAIKU_TOP src add-ons media plugins ffmpeg libvorbis ;
|
||||
|
@ -195,7 +195,7 @@
|
||||
#define CONFIG_LIBOPENJPEG 0
|
||||
#define CONFIG_LIBRTMP 0
|
||||
#define CONFIG_LIBSCHROEDINGER 0
|
||||
#define CONFIG_LIBSPEEX 0
|
||||
#define CONFIG_LIBSPEEX 1
|
||||
#define CONFIG_LIBTHEORA 1
|
||||
#define CONFIG_LIBVORBIS 1
|
||||
#define CONFIG_LIBVPX 0
|
||||
@ -487,7 +487,7 @@
|
||||
#define CONFIG_LIBOPENCORE_AMRWB_DECODER 0
|
||||
#define CONFIG_LIBOPENJPEG_DECODER 0
|
||||
#define CONFIG_LIBSCHROEDINGER_DECODER 0
|
||||
#define CONFIG_LIBSPEEX_DECODER 0
|
||||
#define CONFIG_LIBSPEEX_DECODER 1
|
||||
#define CONFIG_LIBVPX_DECODER 0
|
||||
#define CONFIG_ASV1_ENCODER 0
|
||||
#define CONFIG_ASV2_ENCODER 0
|
||||
|
@ -7,6 +7,7 @@ SubDirHdrs [ FDirName $(SUBDIR) .. libswscale ] ;
|
||||
SubDirSysHdrs [ FDirName $(SUBDIR) .. libogg include ] ;
|
||||
SubDirSysHdrs [ FDirName $(SUBDIR) .. libtheora include ] ;
|
||||
SubDirSysHdrs [ FDirName $(SUBDIR) .. libvorbis include ] ;
|
||||
SubDirSysHdrs [ FDirName $(SUBDIR) .. libspeex include ] ;
|
||||
|
||||
|
||||
UseLibraryHeaders zlib ;
|
||||
@ -188,6 +189,7 @@ StaticLibrary libavcodec.a :
|
||||
kmvc.c
|
||||
lcldec.c
|
||||
# lclenc.c
|
||||
libspeexdec.c
|
||||
libtheoraenc.c
|
||||
libvorbis.c
|
||||
# ljpegenc.c
|
||||
@ -373,6 +375,7 @@ StaticLibrary libavcodec.a :
|
||||
# per individual file.
|
||||
SourceHdrs libvorbis.c : [ FDirName $(SUBDIR) .. libvorbis include vorbis ] ;
|
||||
SourceHdrs libtheoraenc.c : [ FDirName $(SUBDIR) .. libtheora include theora ] ;
|
||||
SourceHdrs libspeexdec.c : [ FDirName $(SUBDIR) .. libspeex include speex ] ;
|
||||
|
||||
SubInclude HAIKU_TOP src add-ons media plugins ffmpeg libavcodec
|
||||
$(TARGET_ARCH) ;
|
||||
|
@ -1,24 +0,0 @@
|
||||
SubDir HAIKU_TOP src add-ons media plugins ogg ;
|
||||
|
||||
SetSubDirSupportedPlatformsBeOSCompatible ;
|
||||
|
||||
UsePrivateHeaders media ;
|
||||
|
||||
SubDirSysHdrs [ FDirName $(SUBDIR) libogg ] ;
|
||||
|
||||
Addon ogg :
|
||||
OggReaderPlugin.cpp
|
||||
OggTrack.cpp
|
||||
OggStream.cpp
|
||||
OggSeekable.cpp
|
||||
OggSpeexStream.cpp
|
||||
OggSpeexSeekable.cpp
|
||||
OggTheoraStream.cpp
|
||||
OggTobiasStream.cpp
|
||||
OggTobiasSeekable.cpp
|
||||
OggVorbisStream.cpp
|
||||
OggVorbisSeekable.cpp
|
||||
: libogg.a be libmedia.so $(TARGET_LIBSTDC++)
|
||||
;
|
||||
|
||||
SubInclude HAIKU_TOP src add-ons media plugins ogg libogg ;
|
@ -1,10 +0,0 @@
|
||||
#ifndef _OGG_FORMATS_H
|
||||
#define _OGG_FORMATS_H
|
||||
|
||||
//! for use in media_misc_description.file_format
|
||||
const uint32 OGG_FILE_FORMAT = 'OggS';
|
||||
|
||||
//! for use in media_header.user_data_type
|
||||
const uint32 OGG_PACKET_DATA_TYPE = 'OggP';
|
||||
|
||||
#endif // _OGG_FORMATS_H
|
@ -1,418 +0,0 @@
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <malloc.h>
|
||||
#include <stdint.h>
|
||||
#include <Autolock.h>
|
||||
#include <ByteOrder.h>
|
||||
#include <DataIO.h>
|
||||
#include <File.h>
|
||||
#include <InterfaceDefs.h>
|
||||
#include <MediaFormats.h>
|
||||
#include "OggReaderPlugin.h"
|
||||
#include "OggStream.h"
|
||||
#include "OggSeekable.h"
|
||||
|
||||
#define TRACE_THIS 0
|
||||
#if TRACE_THIS
|
||||
#define TRACE printf
|
||||
#else
|
||||
#define TRACE(a...) ((void)0)
|
||||
#endif
|
||||
|
||||
OggReader::OggReader()
|
||||
{
|
||||
TRACE("OggReader::OggReader\n");
|
||||
ogg_sync_init(&fSync);
|
||||
fSeekable = NULL;
|
||||
fFile = NULL;
|
||||
fPosition = 0;
|
||||
}
|
||||
|
||||
|
||||
OggReader::~OggReader()
|
||||
{
|
||||
TRACE("OggReader::~OggReader\n");
|
||||
serialno_OggTrack_map::iterator i = fTracks.begin();
|
||||
while (i != fTracks.end()) {
|
||||
serialno_OggTrack_map::iterator j = i;
|
||||
i++;
|
||||
delete j->second;
|
||||
}
|
||||
ogg_sync_clear(&fSync);
|
||||
}
|
||||
|
||||
|
||||
const char *
|
||||
OggReader::Copyright()
|
||||
{
|
||||
return "ogg reader, " B_UTF8_COPYRIGHT " by Andrew Bachmann";
|
||||
}
|
||||
|
||||
|
||||
// the main page reading hook (stream friendly)
|
||||
ssize_t
|
||||
OggReader::ReadPage(bool first_page)
|
||||
{
|
||||
// TRACE("OggReader::ReadPage\n");
|
||||
int read_size = (first_page ? 4096 : 4*B_PAGE_SIZE);
|
||||
BAutolock autolock(fSyncLock);
|
||||
ogg_page page;
|
||||
retry:
|
||||
int result = ogg_sync_pageout(&fSync, &page); // first read leftovers
|
||||
while (result == 0) {
|
||||
char * buffer = ogg_sync_buffer(&fSync, read_size);
|
||||
ssize_t bytes = Source()->Read(buffer, read_size);
|
||||
if (bytes == 0) {
|
||||
TRACE("OggReader::GetPage: Read: no data\n");
|
||||
return B_LAST_BUFFER_ERROR;
|
||||
}
|
||||
if (bytes < 0) {
|
||||
TRACE("OggReader::GetPage: Read: error\n");
|
||||
return bytes;
|
||||
}
|
||||
if (ogg_sync_wrote(&fSync, bytes) != 0) {
|
||||
TRACE("OggReader::GetPage: ogg_sync_wrote failed?: error\n");
|
||||
return B_ERROR;
|
||||
}
|
||||
result = ogg_sync_pageout(&fSync, &page);
|
||||
if (first_page && (result != 1)) {
|
||||
TRACE("OggReader::GetPage: short first page not found: error\n");
|
||||
return B_ERROR;
|
||||
}
|
||||
}
|
||||
if (result == -1) {
|
||||
TRACE("OggReader::GetPage: ogg_sync_pageout: not synced: error\n");
|
||||
return B_ERROR;
|
||||
}
|
||||
if (ogg_page_version(&page) != 0) {
|
||||
TRACE("OggReader::GetPage: ogg_page_version: error in page encoding: error\n");
|
||||
return B_ERROR;
|
||||
}
|
||||
long serialno = ogg_page_serialno(&page);
|
||||
bool new_serialno = fTracks.find(serialno) == fTracks.end();
|
||||
if (new_serialno) {
|
||||
// this is an unknown serialno
|
||||
if (ogg_page_bos(&page) == 0) {
|
||||
TRACE("OggReader::GetPage: non-bos page with unknown serialno\n");
|
||||
#ifdef STRICT_OGG
|
||||
return B_ERROR;
|
||||
#else
|
||||
// silently discard non-bos packets with unknown serialno
|
||||
goto retry;
|
||||
#endif
|
||||
}
|
||||
#ifdef STRICT_OGG
|
||||
if (ogg_page_continued(&page) != 0) {
|
||||
TRACE("oggReader::GetPage: ogg_page_continued: continued page: not ogg\n");
|
||||
return B_ERROR;
|
||||
}
|
||||
#endif //STRICT_OGG
|
||||
// this is a beginning of stream page
|
||||
ogg_stream_state stream;
|
||||
if (ogg_stream_init(&stream, serialno) != 0) {
|
||||
TRACE("oggReader::GetPage: ogg_stream_init failed?: error\n");
|
||||
return B_ERROR;
|
||||
}
|
||||
if (ogg_stream_pagein(&stream, &page) != 0) {
|
||||
TRACE("oggReader::GetPage: ogg_stream_pagein: failed: error\n");
|
||||
return B_ERROR;
|
||||
}
|
||||
ogg_packet packet;
|
||||
if (ogg_stream_packetout(&stream, &packet) != 1) {
|
||||
#ifdef STRICT_OGG
|
||||
return B_ERROR;
|
||||
#endif //STRICT_OGG
|
||||
}
|
||||
if (fSeekable) {
|
||||
fTracks[serialno] = OggSeekable::makeOggSeekable(fSeekable, &fSeekableLock, serialno, packet);
|
||||
} else {
|
||||
class Interface : public StreamInterface {
|
||||
private:
|
||||
OggReader * reader;
|
||||
public:
|
||||
Interface(OggReader * reader) {
|
||||
this->reader = reader;
|
||||
}
|
||||
virtual ssize_t ReadPage() {
|
||||
return reader->ReadPage();
|
||||
}
|
||||
};
|
||||
fTracks[serialno] = OggStream::makeOggStream(new Interface(this), serialno, packet);
|
||||
}
|
||||
fCookies.push_back(serialno);
|
||||
}
|
||||
// this check ensures that we only push the initial pages into OggSeekables.
|
||||
if (!fSeekable || new_serialno) {
|
||||
status_t status = fTracks[serialno]->AddPage(fPosition, page);
|
||||
if (status != B_OK) {
|
||||
return status;
|
||||
}
|
||||
fPosition += page.header_len + page.body_len;
|
||||
}
|
||||
return page.header_len + page.body_len;
|
||||
}
|
||||
|
||||
|
||||
static BPositionIO *
|
||||
get_seekable(BDataIO * data)
|
||||
{
|
||||
// try to cast to BPositionIO then perform a series of
|
||||
// sanity checks to ensure that seeking is reliable
|
||||
BPositionIO * seekable = dynamic_cast<BPositionIO *>(data);
|
||||
if (seekable == 0) {
|
||||
return 0;
|
||||
}
|
||||
// first try to get our current location
|
||||
off_t current = seekable->Seek(0, SEEK_CUR);
|
||||
if (current < 0) {
|
||||
return 0;
|
||||
}
|
||||
// check it against position
|
||||
if (current != seekable->Position()) {
|
||||
return 0;
|
||||
}
|
||||
// next try to seek to our current location (absolutely)
|
||||
if (seekable->Seek(current, SEEK_SET) < 0) {
|
||||
return 0;
|
||||
}
|
||||
// next try to seek to the start of the stream (absolutely)
|
||||
if (seekable->Seek(0, SEEK_SET) < 0) {
|
||||
return 0;
|
||||
}
|
||||
// then seek back to where we started
|
||||
if (seekable->Seek(current, SEEK_SET) < 0) {
|
||||
// really screwed
|
||||
return 0;
|
||||
}
|
||||
// next try to seek to the end of the stream (absolutely)
|
||||
if (seekable->Seek(0, SEEK_END) < 0) {
|
||||
return 0;
|
||||
}
|
||||
// then seek back to where we started
|
||||
if (seekable->Seek(current, SEEK_SET) < 0) {
|
||||
// really screwed
|
||||
return 0;
|
||||
}
|
||||
return seekable;
|
||||
}
|
||||
|
||||
|
||||
static BFile *
|
||||
get_file(BDataIO * data)
|
||||
{
|
||||
// try to cast to BFile then perform a series of
|
||||
// sanity checks to ensure that the file is okay
|
||||
BFile * file = dynamic_cast<BFile *>(data);
|
||||
if (file == 0) {
|
||||
return 0;
|
||||
}
|
||||
if (file->InitCheck() != B_OK) {
|
||||
return 0;
|
||||
}
|
||||
return file;
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
OggReader::Sniff(int32 *streamCount)
|
||||
{
|
||||
TRACE("OggReader::Sniff\n");
|
||||
#ifdef STRICT_OGG
|
||||
bool first_page = true;
|
||||
#else
|
||||
bool first_page = false;
|
||||
#endif
|
||||
fSeekable = get_seekable(Source());
|
||||
fFile = get_file(Source());
|
||||
|
||||
ssize_t bytes = ReadPage(first_page);
|
||||
if (bytes < 0) {
|
||||
return bytes;
|
||||
}
|
||||
uint count = 1;
|
||||
while (count++ == fCookies.size()) {
|
||||
ssize_t bytes = ReadPage();
|
||||
if (bytes < 0) {
|
||||
return bytes;
|
||||
}
|
||||
}
|
||||
if (fSeekable) {
|
||||
status_t status = FindLastPages();
|
||||
if (status != B_OK) {
|
||||
return status;
|
||||
}
|
||||
}
|
||||
*streamCount = fCookies.size();
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
OggReader::GetFileFormatInfo(media_file_format *mff)
|
||||
{
|
||||
TRACE("OggReader::GetFileFormatInfo\n");
|
||||
mff->capabilities = media_file_format::B_READABLE
|
||||
| media_file_format::B_IMPERFECTLY_SEEKABLE
|
||||
| media_file_format::B_KNOWS_ENCODED_VIDEO
|
||||
| media_file_format::B_KNOWS_ENCODED_AUDIO
|
||||
| media_file_format::B_KNOWS_OTHER;
|
||||
mff->family = B_MISC_FORMAT_FAMILY;
|
||||
mff->version = 100;
|
||||
strcpy(mff->mime_type, "application/ogg");
|
||||
strcpy(mff->file_extension, "ogg");
|
||||
strcpy(mff->short_name, "Ogg");
|
||||
strcpy(mff->pretty_name, "Ogg bitstream");
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
OggReader::AllocateCookie(int32 streamNumber, void **cookie)
|
||||
{
|
||||
TRACE("OggReader::AllocateCookie %ld\n", streamNumber);
|
||||
if (streamNumber < 0 || streamNumber > (signed)fCookies.size()) {
|
||||
TRACE("OggReader::AllocateCookie: invalid streamNumber: bail\n");
|
||||
return B_ERROR;
|
||||
}
|
||||
OggTrack * track = fTracks[fCookies[streamNumber]];
|
||||
// store the cookie
|
||||
*cookie = track;
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
OggReader::FreeCookie(void *cookie)
|
||||
{
|
||||
TRACE("OggReader::FreeCookie\n");
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
OggReader::GetStreamInfo(void *cookie, int64 *frameCount, bigtime_t *duration,
|
||||
media_format *format, const void **infoBuffer, size_t *infoSize)
|
||||
{
|
||||
TRACE("OggReader::GetStreamInfo\n");
|
||||
*infoBuffer = 0;
|
||||
*infoSize = 0;
|
||||
OggTrack * track = static_cast<OggTrack*>(cookie);
|
||||
status_t status = track->GetStreamInfo(frameCount, duration, format);
|
||||
TRACE("OggReader::GetStreamInfo: cookie=%x, frame count = %lld, duration = %lld.%lld seconds\n",
|
||||
*(int*)cookie, *frameCount, (*duration)/1000000, (*duration)%1000000);
|
||||
return status;
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
OggReader::Seek(void *cookie,
|
||||
uint32 seekTo,
|
||||
int64 *frame, bigtime_t *time)
|
||||
{
|
||||
TRACE("OggReader::Seek to %lld : %lld\n", *frame, *time);
|
||||
OggTrack * track = static_cast<OggTrack*>(cookie);
|
||||
return track->Seek(seekTo, frame, time);
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
OggReader::GetNextChunk(void *cookie,
|
||||
const void **chunkBuffer, size_t *chunkSize,
|
||||
media_header *mediaHeader)
|
||||
{
|
||||
// TRACE("OggReader::GetNextChunk\n");
|
||||
OggTrack * track = static_cast<OggTrack*>(cookie);
|
||||
return track->GetNextChunk(chunkBuffer, chunkSize, mediaHeader);
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
OggReader::FindLastPages()
|
||||
{
|
||||
TRACE("OggReader::FindLastPages\n");
|
||||
|
||||
status_t result = B_ERROR;
|
||||
|
||||
const int read_size = 256*256;
|
||||
|
||||
ogg_page page;
|
||||
ogg_sync_state sync;
|
||||
ogg_sync_init(&sync);
|
||||
|
||||
off_t right = fSeekable->Seek(0, SEEK_END);
|
||||
off_t left = right;
|
||||
// we assume the common case is that the last pages are near the end
|
||||
uint serial_count = 0;
|
||||
while (serial_count < fCookies.size()) {
|
||||
int offset;
|
||||
ssize_t bytes = 0;
|
||||
while ((offset = ogg_sync_pageseek(&sync, &page)) <= 0) {
|
||||
left += -offset;
|
||||
if (offset == 0) {
|
||||
off_t pos = fSeekable->Position();
|
||||
if (pos >= right || bytes == 0) {
|
||||
if (left == 0) {
|
||||
TRACE("OggReader::FindLastPages: couldn't find some stream's page!!!\n");
|
||||
goto done;
|
||||
}
|
||||
left = max_c(0, left - read_size);
|
||||
result = fSeekable->Seek(left, SEEK_SET);
|
||||
if (result < 0) {
|
||||
goto done;
|
||||
}
|
||||
ogg_sync_reset(&sync);
|
||||
}
|
||||
char * buffer = ogg_sync_buffer(&sync, read_size);
|
||||
bytes = fSeekable->Read(buffer, read_size);
|
||||
if (bytes < 0) {
|
||||
TRACE("OggReader::FindLastPages: Read: error\n");
|
||||
result = bytes;
|
||||
goto done;
|
||||
}
|
||||
if (ogg_sync_wrote(&sync, bytes) != 0) {
|
||||
TRACE("OggReader::FindLastPages: ogg_sync_wrote failed?: error\n");
|
||||
goto done;
|
||||
}
|
||||
}
|
||||
}
|
||||
off_t current = left;
|
||||
do {
|
||||
// found a page at "current"
|
||||
long serialno = ogg_page_serialno(&page);
|
||||
OggSeekable * track = dynamic_cast<OggSeekable*>(fTracks[serialno]);
|
||||
if (track == 0) {
|
||||
TRACE("OggReader::FindLastPages: unknown serialno == TODO: chaining?\n");
|
||||
} else {
|
||||
if (track->GetLastPagePosition() == 0) {
|
||||
serial_count++;
|
||||
}
|
||||
track->SetLastPagePosition(current);
|
||||
}
|
||||
current += page.header_len + page.body_len;
|
||||
} while ((current < right) && (ogg_sync_pageout(&sync, &page) == 1));
|
||||
right = left;
|
||||
ogg_sync_reset(&sync);
|
||||
}
|
||||
result = B_OK;
|
||||
done:
|
||||
ogg_sync_clear(&sync);
|
||||
TRACE("OggReader::FindLastPages took %lld microseconds\n", system_time() - start_time);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/*
|
||||
* OggReaderPlugin
|
||||
*/
|
||||
|
||||
Reader *
|
||||
OggReaderPlugin::NewReader()
|
||||
{
|
||||
return new OggReader;
|
||||
}
|
||||
|
||||
|
||||
MediaPlugin *
|
||||
instantiate_plugin()
|
||||
{
|
||||
return new OggReaderPlugin;
|
||||
}
|
@ -1,74 +0,0 @@
|
||||
#ifndef _OGG_READER_PLUGIN_H
|
||||
#define _OGG_READER_PLUGIN_H
|
||||
|
||||
#include "ReaderPlugin.h"
|
||||
#include "ogg/ogg.h"
|
||||
|
||||
#include <map>
|
||||
#include <vector>
|
||||
|
||||
class BFile;
|
||||
|
||||
namespace BPrivate { namespace media {
|
||||
|
||||
class OggTrack;
|
||||
|
||||
typedef std::map<long,OggTrack*> serialno_OggTrack_map;
|
||||
typedef std::vector<long> serialno_vector;
|
||||
|
||||
class OggReader : public Reader {
|
||||
public:
|
||||
OggReader();
|
||||
~OggReader();
|
||||
|
||||
const char *Copyright();
|
||||
|
||||
status_t Sniff(int32 *streamCount);
|
||||
|
||||
void GetFileFormatInfo(media_file_format *mff);
|
||||
|
||||
status_t AllocateCookie(int32 streamNumber, void **cookie);
|
||||
status_t FreeCookie(void *cookie);
|
||||
|
||||
// delegated to OggTrack
|
||||
status_t GetStreamInfo(void *cookie, int64 *frameCount, bigtime_t *duration,
|
||||
media_format *format, const void **infoBuffer, size_t *infoSize);
|
||||
status_t Seek(void *cookie, uint32 seekTo, int64 *frame, bigtime_t *time);
|
||||
status_t GetNextChunk(void *cookie, const void **chunkBuffer, size_t *chunkSize,
|
||||
media_header *mediaHeader);
|
||||
|
||||
private:
|
||||
status_t FindLastPages();
|
||||
|
||||
ogg_sync_state fSync;
|
||||
BLocker fSyncLock;
|
||||
serialno_OggTrack_map fTracks;
|
||||
serialno_vector fCookies;
|
||||
|
||||
BPositionIO * fSeekable;
|
||||
BLocker fSeekableLock;
|
||||
BFile * fFile;
|
||||
|
||||
off_t fPosition;
|
||||
|
||||
// interface for OggStreams
|
||||
ssize_t ReadPage(bool first_page = false);
|
||||
|
||||
public:
|
||||
class StreamInterface {
|
||||
public:
|
||||
virtual ~StreamInterface() {};
|
||||
virtual ssize_t ReadPage() = 0;
|
||||
};
|
||||
};
|
||||
|
||||
class OggReaderPlugin : public ReaderPlugin {
|
||||
public:
|
||||
Reader *NewReader();
|
||||
};
|
||||
|
||||
} } // namespace BPrivate::media
|
||||
|
||||
using namespace BPrivate::media;
|
||||
|
||||
#endif // _OGG_READER_PLUGIN_H
|
@ -1,506 +0,0 @@
|
||||
#include "OggSeekable.h"
|
||||
#include "OggSpeexSeekable.h"
|
||||
#include "OggTobiasSeekable.h"
|
||||
#include "OggVorbisSeekable.h"
|
||||
#include "OggFormats.h"
|
||||
#include <Autolock.h>
|
||||
#include <assert.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#define TRACE_THIS 0
|
||||
#if TRACE_THIS
|
||||
#define TRACE printf
|
||||
#else
|
||||
#define TRACE(a...) ((void)0)
|
||||
#endif
|
||||
|
||||
/*
|
||||
* OggSeekable codec identification and instantiation
|
||||
*/
|
||||
|
||||
/* static */ OggSeekable *
|
||||
OggSeekable::makeOggSeekable(BPositionIO * positionIO, BLocker * positionLock,
|
||||
long serialno, const ogg_packet & packet)
|
||||
{
|
||||
TRACE("OggSeekable::makeOggSeekable\n");
|
||||
OggSeekable * stream;
|
||||
if (OggVorbisSeekable::IsValidHeader(packet)) {
|
||||
stream = new OggVorbisSeekable(serialno);
|
||||
} else if (OggTobiasSeekable::IsValidHeader(packet)) {
|
||||
stream = new OggTobiasSeekable(serialno);
|
||||
} else if (OggSpeexSeekable::IsValidHeader(packet)) {
|
||||
stream = new OggSpeexSeekable(serialno);
|
||||
// } else if (OggTheoraSeekable::IsValidHeader(packet)) {
|
||||
// stream = new OggTheoraSeekable(serialno);
|
||||
} else {
|
||||
stream = new OggSeekable(serialno);
|
||||
}
|
||||
stream->fPositionIO = positionIO;
|
||||
stream->fPositionLock = positionLock;
|
||||
return stream;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* OggSeekable generic functions
|
||||
*/
|
||||
|
||||
OggSeekable::OggSeekable(long serialno)
|
||||
: OggTrack(serialno)
|
||||
{
|
||||
TRACE("OggSeekable::OggSeekable\n");
|
||||
ogg_sync_init(&fSync);
|
||||
ogg_stream_init(&fStreamState,serialno);
|
||||
fPosition = 0;
|
||||
fLastPagePosition = 0;
|
||||
|
||||
fCurrentFrame = 0;
|
||||
fCurrentTime = 0;
|
||||
fFirstGranulepos = 0;
|
||||
fFrameRate = 0;
|
||||
}
|
||||
|
||||
|
||||
OggSeekable::~OggSeekable()
|
||||
{
|
||||
// free internal stream state storage
|
||||
ogg_sync_clear(&fSync);
|
||||
ogg_stream_clear(&fStreamState);
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
insert_position(std::vector<off_t> & positions, off_t position)
|
||||
{
|
||||
positions.push_back(position);
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
OggSeekable::AddPage(off_t position, const ogg_page & page)
|
||||
{
|
||||
TRACE("OggSeekable::AddPage\n");
|
||||
insert_position(fPagePositions, position);
|
||||
char * buffer;
|
||||
// copy the header to our local sync
|
||||
buffer = ogg_sync_buffer(&fSync, page.header_len);
|
||||
memcpy(buffer, page.header, page.header_len);
|
||||
ogg_sync_wrote(&fSync, page.header_len);
|
||||
// copy the body to our local sync
|
||||
buffer = ogg_sync_buffer(&fSync, page.body_len);
|
||||
memcpy(buffer, page.body, page.body_len);
|
||||
ogg_sync_wrote(&fSync, page.body_len);
|
||||
fPosition = position + page.header_len + page.body_len;
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
OggSeekable::SetLastPagePosition(off_t position)
|
||||
{
|
||||
fLastPagePosition = max_c(fLastPagePosition, position);
|
||||
}
|
||||
|
||||
|
||||
off_t
|
||||
OggSeekable::GetLastPagePosition()
|
||||
{
|
||||
return fLastPagePosition;
|
||||
}
|
||||
|
||||
|
||||
off_t
|
||||
OggSeekable::Seek(off_t position, int32 mode)
|
||||
{
|
||||
BAutolock autolock(fPositionLock);
|
||||
off_t result = fPositionIO->Seek(position, mode);
|
||||
if (result >= 0) {
|
||||
fPosition = result;
|
||||
ogg_sync_reset(&fSync);
|
||||
ogg_stream_reset(&fStreamState);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
off_t
|
||||
OggSeekable::Position(void) const
|
||||
{
|
||||
return fPosition;
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
OggSeekable::GetSize(off_t * size)
|
||||
{
|
||||
BAutolock autolock(fPositionLock);
|
||||
off_t prior = fPositionIO->Position();
|
||||
off_t result = fPositionIO->Seek(0, SEEK_END);
|
||||
fPositionIO->Seek(prior, SEEK_SET);
|
||||
if (result >= 0) {
|
||||
*size = result;
|
||||
result = B_OK;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
OggSeekable::ReadPage(ogg_page * page, int read_size)
|
||||
{
|
||||
// TRACE("OggSeekable::ReadPage (%llu)\n", fPosition);
|
||||
int result;
|
||||
while ((result = ogg_sync_pageout(&fSync, page)) == 1) {
|
||||
if (ogg_page_serialno(page) == GetSerial()) {
|
||||
return B_OK;
|
||||
}
|
||||
}
|
||||
BAutolock autolock(fPositionLock);
|
||||
// align to page boundary
|
||||
align:
|
||||
int offset;
|
||||
while ((offset = ogg_sync_pageseek(&fSync, page)) <= 0) {
|
||||
if (offset == 0) {
|
||||
char * buffer = ogg_sync_buffer(&fSync, read_size);
|
||||
ssize_t bytes = fPositionIO->ReadAt(fPosition, buffer, read_size);
|
||||
if (bytes == 0) {
|
||||
TRACE("OggSeekable::ReadPage (%llu)\n", fPosition);
|
||||
TRACE("OggSeekable::ReadPage: ReadAt: no data\n");
|
||||
return B_LAST_BUFFER_ERROR;
|
||||
}
|
||||
if (bytes < 0) {
|
||||
TRACE("OggSeekable::ReadPage (%llu)\n", fPosition);
|
||||
TRACE("OggSeekable::ReadPage: ReadAt: error\n");
|
||||
return bytes;
|
||||
}
|
||||
fPosition += bytes;
|
||||
if (ogg_sync_wrote(&fSync, bytes) != 0) {
|
||||
TRACE("OggSeekable::ReadPage (%llu)\n", fPosition);
|
||||
TRACE("OggSeekable::ReadPage: ogg_sync_wrote failed?: error\n");
|
||||
return B_ERROR;
|
||||
}
|
||||
}
|
||||
}
|
||||
// repeat until this is one of our pages
|
||||
while (ogg_page_serialno(page) != GetSerial()) {
|
||||
int result;
|
||||
// read the page
|
||||
while ((result = ogg_sync_pageout(&fSync, page)) == 0) {
|
||||
char * buffer = ogg_sync_buffer(&fSync, read_size);
|
||||
ssize_t bytes = fPositionIO->ReadAt(fPosition, buffer, read_size);
|
||||
if (bytes == 0) {
|
||||
TRACE("OggSeekable::ReadPage (%llu)\n", fPosition);
|
||||
TRACE("OggSeekable::ReadPage: ReadAt 2: no data\n");
|
||||
return B_LAST_BUFFER_ERROR;
|
||||
}
|
||||
if (bytes < 0) {
|
||||
TRACE("OggSeekable::ReadPage (%llu)\n", fPosition);
|
||||
TRACE("OggSeekable::ReadPage: ReadAt 2: error\n");
|
||||
return bytes;
|
||||
}
|
||||
fPosition += bytes;
|
||||
if (ogg_sync_wrote(&fSync, bytes) != 0) {
|
||||
TRACE("OggSeekable::ReadPage (%llu)\n", fPosition);
|
||||
TRACE("OggSeekable::ReadPage: ogg_sync_wrote 2 failed?: error\n");
|
||||
return B_ERROR;
|
||||
}
|
||||
}
|
||||
if (result == -1) {
|
||||
TRACE("OggSeekable::ReadPage (%llu)\n", fPosition);
|
||||
TRACE("OggSeekable::ReadPage: ogg_sync_pageout: not synced... attempt resync\n");
|
||||
goto align;
|
||||
}
|
||||
if (ogg_page_version(page) != 0) {
|
||||
TRACE("OggSeekable::ReadPage (%llu)\n", fPosition);
|
||||
TRACE("OggSeekable::ReadPage: ogg_page_version: error in page encoding??\n");
|
||||
#ifdef STRICT_OGG
|
||||
return B_ERROR;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
OggSeekable::GetStreamInfo(int64 *frameCount, bigtime_t *duration,
|
||||
media_format *format)
|
||||
{
|
||||
TRACE("OggSeekable::GetStreamInfo\n");
|
||||
status_t result = B_OK;
|
||||
ogg_packet packet;
|
||||
if (GetHeaderPackets().size() < 1) {
|
||||
result = GetPacket(&packet);
|
||||
if (result != B_OK) {
|
||||
TRACE("OggSeekable::GetStreamInfo failed to get header packet\n");
|
||||
return result;
|
||||
}
|
||||
SaveHeaderPacket(packet);
|
||||
}
|
||||
packet = GetHeaderPackets()[0];
|
||||
if (!packet.b_o_s) {
|
||||
TRACE("OggSeekable::GetStreamInfo failed : not beginning of stream\n");
|
||||
return B_ERROR; // first packet was not beginning of stream
|
||||
}
|
||||
|
||||
// parse header packet
|
||||
uint32 four_bytes = *(uint32*)(&packet);
|
||||
|
||||
// get the format for the description
|
||||
media_format_description description;
|
||||
description.family = B_MISC_FORMAT_FAMILY;
|
||||
description.u.misc.file_format = OGG_FILE_FORMAT;
|
||||
description.u.misc.codec = four_bytes;
|
||||
BMediaFormats formats;
|
||||
result = formats.InitCheck();
|
||||
if (result == B_OK) {
|
||||
result = formats.GetFormatFor(description, format);
|
||||
}
|
||||
if (result != B_OK) {
|
||||
// ignore the error, allow the user to use ReadChunk interface
|
||||
}
|
||||
|
||||
// fill out format from header packet
|
||||
format->user_data_type = B_CODEC_TYPE_INFO;
|
||||
strncpy((char*)format->user_data, (char*)(&packet), 4);
|
||||
|
||||
format->SetMetaData((void*)&GetHeaderPackets(),sizeof(GetHeaderPackets()));
|
||||
*duration = 140000000;
|
||||
*frameCount = 60000;
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
status_t
|
||||
OggSeekable::Seek(uint32 seekTo, int64 *frame, bigtime_t *time)
|
||||
{
|
||||
status_t status;
|
||||
int64 granulepos;
|
||||
if (seekTo & B_MEDIA_SEEK_TO_TIME) {
|
||||
TRACE("OggSeekable::Seek: seek to time: %lld\n", *time);
|
||||
if ((fFrameRate == 0) && (*time != 0)) {
|
||||
TRACE("OggSeekable::Seek: fFrameRate unset, seek to non-zero time unsupported\n");
|
||||
return B_UNSUPPORTED;
|
||||
}
|
||||
granulepos = fFirstGranulepos + (int64) (*time * (long long)fFrameRate) / 1000000LL;
|
||||
} else if (seekTo & B_MEDIA_SEEK_TO_FRAME) {
|
||||
granulepos = fFirstGranulepos + *frame;
|
||||
} else {
|
||||
TRACE("OggSeekable::Seek: bad seekTo");
|
||||
return B_BAD_VALUE;
|
||||
}
|
||||
TRACE("OggSeekable::Seek: seek to granulepos: %lld\n", granulepos);
|
||||
|
||||
// find the first packet with data in it
|
||||
ogg_page page;
|
||||
off_t left = 0;
|
||||
BAutolock autolock(fPositionLock);
|
||||
off_t pos = Seek(0, SEEK_SET);
|
||||
if (pos < 0) {
|
||||
TRACE("OggSeekable::Seek: Seek = %s\n", strerror(pos));
|
||||
return pos;
|
||||
}
|
||||
uint header_packets_left = GetHeaderPackets().size();
|
||||
while (header_packets_left > 0) {
|
||||
status = ReadPage(&page, B_PAGE_SIZE);
|
||||
if (status != B_OK) {
|
||||
TRACE("OggSeekable::Seek: ReadPage = %s\n", strerror(status));
|
||||
return status;
|
||||
}
|
||||
header_packets_left -= ogg_page_packets(&page);
|
||||
left += page.header_len + page.body_len;
|
||||
}
|
||||
TRACE("OggSeekable::Seek: header packets end after = %llu\n", left);
|
||||
pos = Seek(left, SEEK_SET);
|
||||
if (pos < 0) {
|
||||
TRACE("OggSeekable::Seek: Seek2 = %s\n", strerror(pos));
|
||||
return pos;
|
||||
}
|
||||
status = ReadPage(&page, B_PAGE_SIZE);
|
||||
if (status != B_OK) {
|
||||
TRACE("OggSeekable::Seek: ReadPage2 = %s\n", strerror(status));
|
||||
return status;
|
||||
}
|
||||
if (ogg_page_continued(&page)) {
|
||||
TRACE("OggSeekable::Seek: warning: data packet began in header page!\n");
|
||||
// how to handle this?
|
||||
}
|
||||
|
||||
int64 left_granulepos = 0;
|
||||
int64 right_granulepos = 0;
|
||||
// if not the first, perform a binary search
|
||||
if (granulepos != fFirstGranulepos) {
|
||||
// binary search to find our place
|
||||
off_t right = GetLastPagePosition();
|
||||
// uint width = (uint)log10(max_c(1, fFirstGranulepos + right)) + 2;
|
||||
while (true) {
|
||||
ogg_sync_reset(&fSync);
|
||||
ogg_stream_reset(&fStreamState);
|
||||
if (right - left > B_PAGE_SIZE) {
|
||||
TRACE(" Seek: [%*lld,%*lld]: ", width, left, width, right);
|
||||
fPosition = (right + left) / 2;
|
||||
} else {
|
||||
TRACE(" Seek: [%*lld,...]\n", width, left);
|
||||
fPosition = left;
|
||||
break;
|
||||
}
|
||||
do {
|
||||
status = ReadPage(&page, B_PAGE_SIZE);
|
||||
if (status != B_OK) {
|
||||
TRACE("OggSeekable::Seek: ReadPage = %s\n", strerror(status));
|
||||
return status;
|
||||
}
|
||||
if (ogg_stream_pagein(&fStreamState, &page) != 0) {
|
||||
TRACE("OggSeekable::Seek: ogg_stream_pagein: failed??\n");
|
||||
return B_ERROR;
|
||||
}
|
||||
} while (ogg_page_granulepos(&page) == -1);
|
||||
TRACE("granulepos = %*lld, ", width, ogg_page_granulepos(&page));
|
||||
TRACE("fPosition = %*llu\n", width, fPosition);
|
||||
// check the granulepos of the page against the requested frame
|
||||
if (ogg_page_granulepos(&page) < granulepos) {
|
||||
// The packet that the frame is in is someplace after
|
||||
// the last complete packet in this page. (It may yet
|
||||
// be in this page, but in a packet completed on the
|
||||
// next page.)
|
||||
left = (right + left) / 2;
|
||||
left_granulepos = ogg_page_granulepos(&page);
|
||||
continue;
|
||||
} else {
|
||||
right = (right + left) / 2;
|
||||
right_granulepos = ogg_page_granulepos(&page);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// if not the first, look for a granulepos in a packet
|
||||
if (granulepos != fFirstGranulepos) {
|
||||
ogg_packet packet;
|
||||
do {
|
||||
status = GetPacket(&packet);
|
||||
if (status != B_OK) {
|
||||
TRACE("OggSeekable::Seek: GetPacket = %s\n", strerror(status));
|
||||
return status;
|
||||
}
|
||||
} while (packet.granulepos == -1);
|
||||
granulepos = packet.granulepos;
|
||||
fCurrentFrame = granulepos - fFirstGranulepos;
|
||||
fCurrentTime = (1000000LL * fCurrentFrame) / (long long)fFrameRate;
|
||||
} else {
|
||||
fCurrentFrame = 0;
|
||||
fCurrentTime = 0;
|
||||
Seek(left, SEEK_SET);
|
||||
}
|
||||
TRACE("OggSeekable::Seek done: ");
|
||||
TRACE("[%lld,%lld] => ", left_granulepos, right_granulepos);
|
||||
TRACE("found frame %lld at time %llu\n", fCurrentFrame, fCurrentTime);
|
||||
*frame = fCurrentFrame;
|
||||
*time = fCurrentTime;
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
// The packet that the frame is in is someplace before or
|
||||
// in the last complete packet in this page. (It may be in
|
||||
// a prior page)
|
||||
/* ogg_packet packet;
|
||||
do {
|
||||
switch (ogg_stream_packetpeek(&fStreamState, &packet)) {
|
||||
case 1: // a packet found
|
||||
break;
|
||||
case 0: { // no packets found
|
||||
status_t status = ReadPage(&page, B_PAGE_SIZE);
|
||||
if (status != B_OK) {
|
||||
TRACE("OggSeekable::Seek: ReadPage = %s\n", strerror(status));
|
||||
return status;
|
||||
}
|
||||
if (ogg_stream_pagein(&fStreamState, &page) != 0) {
|
||||
TRACE("OggSeekable::Seek: ogg_stream_pagein: failed??\n");
|
||||
return B_ERROR;
|
||||
}
|
||||
continue;
|
||||
default: // error condition
|
||||
TRACE("OggSeekable::Seek: error peeking for packet\n");
|
||||
continue;
|
||||
}
|
||||
if (packet.granulepos == -1) {
|
||||
// useless packet with no seek info, eat it
|
||||
ogg_stream_packetout(&fStreamState, &packet);
|
||||
}
|
||||
} while (packet.granulepos == -1);
|
||||
if (packet.granulepos
|
||||
*/
|
||||
/* if (ogg_page_granulepos(&page) == *frame) {
|
||||
// The frame is in the last packet to end on this page.
|
||||
// If the last packet on this page was continued from
|
||||
// the prior page, we might need to go back farther to
|
||||
// get the whole packet.
|
||||
if ((ogg_page_packets(&page) == 1) &&
|
||||
(ogg_page_continued(&page)) &&
|
||||
(ogg_stream_packetpeek(&fStreamState, NULL) != 1)) {
|
||||
right = (right + left) / 2;
|
||||
continue;
|
||||
}
|
||||
// The frame is the last frame in the last packet on
|
||||
// this page. If there are more than 1 packet, discard
|
||||
// all but the last and return.
|
||||
for (int i = 0 ; i < packets - 1 ; i++) {
|
||||
ogg_packet packet;
|
||||
GetPacket(&packet);
|
||||
}
|
||||
return B_OK;
|
||||
}*/
|
||||
|
||||
status_t
|
||||
OggSeekable::GetNextChunk(const void **chunkBuffer, size_t *chunkSize,
|
||||
media_header *mediaHeader)
|
||||
{
|
||||
ogg_packet packet;
|
||||
BAutolock autolock(fPositionLock);
|
||||
status_t result = GetPacket(&packet);
|
||||
*chunkBuffer = packet.packet;
|
||||
*chunkSize = packet.bytes;
|
||||
packet.packet = NULL;
|
||||
assert(sizeof(ogg_packet) <= sizeof(mediaHeader->user_data));
|
||||
mediaHeader->user_data_type = OGG_PACKET_DATA_TYPE;
|
||||
memcpy(mediaHeader->user_data, &packet, sizeof(ogg_packet));
|
||||
if (result != B_OK) {
|
||||
TRACE("OggSeekable::GetNextChunk failed: GetPacket = %s\n", strerror(result));
|
||||
return result;
|
||||
}
|
||||
if (packet.granulepos > 0) {
|
||||
fCurrentFrame = packet.granulepos - fFirstGranulepos;
|
||||
fCurrentTime = (bigtime_t)((fCurrentFrame * 1000000LL) / fFrameRate);
|
||||
mediaHeader->start_time = fCurrentTime;
|
||||
} else {
|
||||
mediaHeader->start_time = -1;
|
||||
}
|
||||
mediaHeader->file_pos = fPosition;
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
|
||||
// subclass pull input function
|
||||
status_t
|
||||
OggSeekable::GetPacket(ogg_packet * packet)
|
||||
{
|
||||
// at the end, pull the packet
|
||||
while (ogg_stream_packetpeek(&fStreamState, NULL) != 1) {
|
||||
ogg_page page;
|
||||
status_t status = ReadPage(&page);
|
||||
if (status != B_OK) {
|
||||
TRACE("OggSeekable::GetPacket: ReadPage = %s\n", strerror(status));
|
||||
return status;
|
||||
}
|
||||
if (ogg_stream_pagein(&fStreamState, &page) != 0) {
|
||||
TRACE("OggSeekable::GetPacket: ogg_stream_pagein: failed??\n");
|
||||
return B_ERROR;
|
||||
}
|
||||
}
|
||||
if (ogg_stream_packetout(&fStreamState, packet) != 1) {
|
||||
TRACE("OggSeekable::GetPacket: ogg_stream_packetout failed\n");
|
||||
return B_ERROR;
|
||||
}
|
||||
return B_OK;
|
||||
}
|
||||
|
@ -1,66 +0,0 @@
|
||||
#ifndef _OGG_SEEKABLE_H
|
||||
#define _OGG_SEEKABLE_H
|
||||
|
||||
#include "OggTrack.h"
|
||||
#include "OggReaderPlugin.h"
|
||||
#include <vector>
|
||||
|
||||
namespace BPrivate { namespace media {
|
||||
|
||||
class OggSeekable : public OggTrack {
|
||||
public:
|
||||
static OggSeekable * makeOggSeekable(BPositionIO * positionIO, BLocker * positionLock,
|
||||
long serialno, const ogg_packet & packet);
|
||||
|
||||
// interface for OggReader
|
||||
virtual status_t GetStreamInfo(int64 *frameCount, bigtime_t *duration,
|
||||
media_format *format);
|
||||
virtual status_t Seek(uint32 seekTo, int64 *frame, bigtime_t *time);
|
||||
virtual status_t GetNextChunk(const void **chunkBuffer, size_t *chunkSize,
|
||||
media_header *mediaHeader);
|
||||
|
||||
protected:
|
||||
OggSeekable(long serialno);
|
||||
public:
|
||||
virtual ~OggSeekable();
|
||||
|
||||
// reader push input function
|
||||
status_t AddPage(off_t position, const ogg_page & page);
|
||||
|
||||
void SetLastPagePosition(off_t position);
|
||||
off_t GetLastPagePosition();
|
||||
private:
|
||||
off_t fLastPagePosition;
|
||||
|
||||
protected:
|
||||
off_t Seek(off_t position, int32 mode);
|
||||
off_t Position(void) const;
|
||||
status_t GetSize(off_t * size);
|
||||
status_t ReadPage(ogg_page * page, int read_size = 4*B_PAGE_SIZE);
|
||||
|
||||
// subclass pull input function
|
||||
status_t GetPacket(ogg_packet * packet);
|
||||
|
||||
protected:
|
||||
int64 fCurrentFrame;
|
||||
bigtime_t fCurrentTime;
|
||||
|
||||
int64 fFirstGranulepos;
|
||||
float fFrameRate;
|
||||
|
||||
private:
|
||||
off_t fPosition;
|
||||
std::vector<off_t> fPagePositions;
|
||||
|
||||
private:
|
||||
ogg_sync_state fSync;
|
||||
ogg_stream_state fStreamState;
|
||||
BPositionIO * fPositionIO;
|
||||
BLocker fPositionLock;
|
||||
};
|
||||
|
||||
} } // namespace BPrivate::media
|
||||
|
||||
using namespace BPrivate::media;
|
||||
|
||||
#endif // _OGG_SEEKABLE_H
|
@ -1,46 +0,0 @@
|
||||
#ifndef _OGG_SPEEX_FORMATS_H
|
||||
#define _OGG_SPEEX_FORMATS_H
|
||||
|
||||
#include <MediaFormats.h>
|
||||
#include <ogg/ogg.h>
|
||||
#include <string.h>
|
||||
#include "OggFormats.h"
|
||||
|
||||
/*
|
||||
* speex descriptions/formats
|
||||
*/
|
||||
|
||||
|
||||
static media_format_description
|
||||
speex_description()
|
||||
{
|
||||
media_format_description description;
|
||||
description.family = B_MISC_FORMAT_FAMILY;
|
||||
description.u.misc.file_format = OGG_FILE_FORMAT;
|
||||
description.u.misc.codec = 'Spee';
|
||||
return description;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
init_speex_media_raw_audio_format(media_raw_audio_format * output)
|
||||
{
|
||||
output->format = media_raw_audio_format::B_AUDIO_FLOAT;
|
||||
output->byte_order = B_MEDIA_HOST_ENDIAN;
|
||||
}
|
||||
|
||||
|
||||
static media_format
|
||||
speex_encoded_media_format()
|
||||
{
|
||||
media_format format;
|
||||
format.type = B_MEDIA_ENCODED_AUDIO;
|
||||
format.user_data_type = B_CODEC_TYPE_INFO;
|
||||
strncpy((char*)format.user_data, "Spee", 4);
|
||||
format.u.encoded_audio.frame_size = sizeof(ogg_packet);
|
||||
init_speex_media_raw_audio_format(&format.u.encoded_audio.output);
|
||||
return format;
|
||||
}
|
||||
|
||||
|
||||
#endif //_OGG_SPEEX_FORMATS_H
|
@ -1,181 +0,0 @@
|
||||
#include "OggSpeexFormats.h"
|
||||
#include "OggSpeexSeekable.h"
|
||||
#include <stdio.h>
|
||||
|
||||
#define TRACE_THIS 0
|
||||
#if TRACE_THIS
|
||||
#define TRACE printf
|
||||
#else
|
||||
#define TRACE(a...) ((void)0)
|
||||
#endif
|
||||
|
||||
inline size_t
|
||||
AudioBufferSize(media_raw_audio_format * raf, bigtime_t buffer_duration = 50000 /* 50 ms */)
|
||||
{
|
||||
return (raf->format & 0xf) * (raf->channel_count)
|
||||
* (size_t)((raf->frame_rate * buffer_duration) / 1000000.0);
|
||||
}
|
||||
|
||||
/*
|
||||
* speex header from libspeex/speex_header.h
|
||||
* also documented at http://www.speex.org/manual/node7.html#SECTION00073000000000000000
|
||||
*/
|
||||
|
||||
typedef struct SpeexHeader {
|
||||
char speex_string[8]; /**< Identifies a Speex bit-stream, always set to "Speex " */
|
||||
char speex_version[20]; /**< Speex version */
|
||||
int speex_version_id; /**< Version for Speex (for checking compatibility) */
|
||||
int header_size; /**< Total size of the header ( sizeof(SpeexHeader) ) */
|
||||
int rate; /**< Sampling rate used */
|
||||
int mode; /**< Mode used (0 for narrowband, 1 for wideband) */
|
||||
int mode_bitstream_version; /**< Version ID of the bit-stream */
|
||||
int nb_channels; /**< Number of channels encoded */
|
||||
int bitrate; /**< Bit-rate used */
|
||||
int frame_size; /**< Size of frames */
|
||||
int vbr; /**< 1 for a VBR encoding, 0 otherwise */
|
||||
int frames_per_packet; /**< Number of frames stored per Ogg packet */
|
||||
int extra_headers; /**< Number of additional headers after the comments */
|
||||
int reserved1; /**< Reserved for future use, must be zero */
|
||||
int reserved2; /**< Reserved for future use, must be zero */
|
||||
} SpeexHeader;
|
||||
|
||||
|
||||
/*
|
||||
* OggSpeexSeekable implementations
|
||||
*/
|
||||
|
||||
/* static */ bool
|
||||
OggSpeexSeekable::IsValidHeader(const ogg_packet & packet)
|
||||
{
|
||||
return findIdentifier(packet,"Speex ",0);
|
||||
}
|
||||
|
||||
OggSpeexSeekable::OggSpeexSeekable(long serialno)
|
||||
: OggSeekable(serialno)
|
||||
{
|
||||
TRACE("OggSpeexSeekable::OggSpeexSeekable\n");
|
||||
}
|
||||
|
||||
OggSpeexSeekable::~OggSpeexSeekable()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
status_t
|
||||
OggSpeexSeekable::GetStreamInfo(int64 *frameCount, bigtime_t *duration,
|
||||
media_format *format)
|
||||
{
|
||||
TRACE("OggSpeexSeekable::GetStreamInfo\n");
|
||||
status_t result = B_OK;
|
||||
ogg_packet packet;
|
||||
|
||||
// get header packet
|
||||
if (GetHeaderPackets().size() < 1) {
|
||||
result = GetPacket(&packet);
|
||||
if (result != B_OK) {
|
||||
return result;
|
||||
}
|
||||
SaveHeaderPacket(packet);
|
||||
}
|
||||
packet = GetHeaderPackets()[0];
|
||||
if (!packet.b_o_s) {
|
||||
return B_ERROR; // first packet was not beginning of stream
|
||||
}
|
||||
|
||||
// parse header packet, check size against struct minus optional fields
|
||||
if (packet.bytes < 1 + (signed)sizeof(SpeexHeader) - 2*(signed)sizeof(int)) {
|
||||
return B_ERROR;
|
||||
}
|
||||
void * data = &(packet.packet[0]);
|
||||
SpeexHeader * header = (SpeexHeader *)data;
|
||||
|
||||
// get the format for the description
|
||||
media_format_description description = speex_description();
|
||||
BMediaFormats formats;
|
||||
result = formats.InitCheck();
|
||||
if (result == B_OK) {
|
||||
result = formats.GetFormatFor(description, format);
|
||||
}
|
||||
if (result != B_OK) {
|
||||
*format = speex_encoded_media_format();
|
||||
// ignore error, allow user to use ReadChunk interface
|
||||
}
|
||||
|
||||
// fill out format from header packet
|
||||
if (header->bitrate > 0) {
|
||||
format->u.encoded_audio.bit_rate = header->bitrate;
|
||||
} else {
|
||||
// TODO: manually compute it where possible
|
||||
}
|
||||
if (header->nb_channels == 1) {
|
||||
format->u.encoded_audio.multi_info.channel_mask = B_CHANNEL_LEFT;
|
||||
} else {
|
||||
format->u.encoded_audio.multi_info.channel_mask = B_CHANNEL_LEFT | B_CHANNEL_RIGHT;
|
||||
}
|
||||
fFrameRate = format->u.encoded_audio.output.frame_rate = header->rate;
|
||||
format->u.encoded_audio.output.channel_count = header->nb_channels;
|
||||
// allocate buffer, round up to nearest speex output_length size
|
||||
int buffer_size = AudioBufferSize(&format->u.encoded_audio.output);
|
||||
int output_length = header->frame_size * header->nb_channels *
|
||||
(format->u.encoded_audio.output.format & 0xf);
|
||||
buffer_size = ((buffer_size - 1) / output_length + 1) * output_length;
|
||||
format->u.encoded_audio.output.buffer_size = buffer_size;
|
||||
|
||||
// get comment packet
|
||||
if (GetHeaderPackets().size() < 2) {
|
||||
result = GetPacket(&packet);
|
||||
if (result != B_OK) {
|
||||
return result;
|
||||
}
|
||||
SaveHeaderPacket(packet);
|
||||
}
|
||||
|
||||
// get extra headers
|
||||
while ((signed)GetHeaderPackets().size() < header->extra_headers) {
|
||||
result = GetPacket(&packet);
|
||||
if (result != B_OK) {
|
||||
return result;
|
||||
}
|
||||
SaveHeaderPacket(packet);
|
||||
}
|
||||
|
||||
format->SetMetaData((void*)&GetHeaderPackets(),sizeof(GetHeaderPackets()));
|
||||
|
||||
// TODO: count the frames in the first page.. somehow.. :-/
|
||||
int64 frames = 0;
|
||||
|
||||
ogg_page page;
|
||||
// read the first page
|
||||
result = ReadPage(&page);
|
||||
if (result != B_OK) {
|
||||
return result;
|
||||
}
|
||||
int64 fFirstGranulepos = ogg_page_granulepos(&page);
|
||||
TRACE("OggVorbisSeekable::GetStreamInfo: first granulepos: %lld\n", fFirstGranulepos);
|
||||
// read our last page
|
||||
off_t last = inherited::Seek(GetLastPagePosition(), SEEK_SET);
|
||||
if (last < 0) {
|
||||
return last;
|
||||
}
|
||||
result = ReadPage(&page);
|
||||
if (result != B_OK) {
|
||||
return result;
|
||||
}
|
||||
int64 last_granulepos = ogg_page_granulepos(&page);
|
||||
|
||||
// seek back to the start
|
||||
int64 frame = 0;
|
||||
bigtime_t time = 0;
|
||||
result = Seek(B_MEDIA_SEEK_TO_TIME, &frame, &time);
|
||||
if (result != B_OK) {
|
||||
return result;
|
||||
}
|
||||
|
||||
// compute frame count and duration from sample count
|
||||
frames = last_granulepos - fFirstGranulepos;
|
||||
|
||||
*frameCount = frames;
|
||||
*duration = (1000000LL * frames) / (long long)fFrameRate;
|
||||
|
||||
return B_OK;
|
||||
}
|
@ -1,26 +0,0 @@
|
||||
#ifndef _OGG_SPEEX_SEEKABLE_H
|
||||
#define _OGG_SPEEX_SEEKABLE_H
|
||||
|
||||
#include "OggSeekable.h"
|
||||
|
||||
namespace BPrivate { namespace media {
|
||||
|
||||
class OggSpeexSeekable : public OggSeekable {
|
||||
private:
|
||||
typedef OggSeekable inherited;
|
||||
public:
|
||||
static bool IsValidHeader(const ogg_packet & packet);
|
||||
public:
|
||||
OggSpeexSeekable(long serialno);
|
||||
virtual ~OggSpeexSeekable();
|
||||
|
||||
virtual status_t GetStreamInfo(int64 *frameCount, bigtime_t *duration,
|
||||
media_format *format);
|
||||
|
||||
};
|
||||
|
||||
} } // namespace BPrivate::media
|
||||
|
||||
using namespace BPrivate::media;
|
||||
|
||||
#endif // _OGG_SPEEX_SEEKABLE_H
|
@ -1,161 +0,0 @@
|
||||
#include "OggSpeexFormats.h"
|
||||
#include "OggSpeexStream.h"
|
||||
#include <stdio.h>
|
||||
|
||||
#define TRACE_THIS 0
|
||||
#if TRACE_THIS
|
||||
#define TRACE printf
|
||||
#else
|
||||
#define TRACE(a...) ((void)0)
|
||||
#endif
|
||||
|
||||
inline size_t
|
||||
AudioBufferSize(media_raw_audio_format * raf, bigtime_t buffer_duration = 50000 /* 50 ms */)
|
||||
{
|
||||
return (raf->format & 0xf) * (raf->channel_count)
|
||||
* (size_t)((raf->frame_rate * buffer_duration) / 1000000.0);
|
||||
}
|
||||
|
||||
/*
|
||||
* speex header from libspeex/speex_header.h
|
||||
* also documented at http://www.speex.org/manual/node7.html#SECTION00073000000000000000
|
||||
*/
|
||||
|
||||
typedef struct SpeexHeader {
|
||||
char speex_string[8]; /**< Identifies a Speex bit-stream, always set to "Speex " */
|
||||
char speex_version[20]; /**< Speex version */
|
||||
int speex_version_id; /**< Version for Speex (for checking compatibility) */
|
||||
int header_size; /**< Total size of the header ( sizeof(SpeexHeader) ) */
|
||||
int rate; /**< Sampling rate used */
|
||||
int mode; /**< Mode used (0 for narrowband, 1 for wideband) */
|
||||
int mode_bitstream_version; /**< Version ID of the bit-stream */
|
||||
int nb_channels; /**< Number of channels encoded */
|
||||
int bitrate; /**< Bit-rate used */
|
||||
int frame_size; /**< Size of frames */
|
||||
int vbr; /**< 1 for a VBR encoding, 0 otherwise */
|
||||
int frames_per_packet; /**< Number of frames stored per Ogg packet */
|
||||
int extra_headers; /**< Number of additional headers after the comments */
|
||||
int reserved1; /**< Reserved for future use, must be zero */
|
||||
int reserved2; /**< Reserved for future use, must be zero */
|
||||
} SpeexHeader;
|
||||
|
||||
|
||||
/*
|
||||
* OggSpeexStream implementations
|
||||
*/
|
||||
|
||||
/* static */ bool
|
||||
OggSpeexStream::IsValidHeader(const ogg_packet & packet)
|
||||
{
|
||||
return findIdentifier(packet,"Speex ",0);
|
||||
}
|
||||
|
||||
OggSpeexStream::OggSpeexStream(long serialno)
|
||||
: OggStream(serialno)
|
||||
{
|
||||
TRACE("OggSpeexStream::OggSpeexStream\n");
|
||||
}
|
||||
|
||||
OggSpeexStream::~OggSpeexStream()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
status_t
|
||||
OggSpeexStream::GetStreamInfo(int64 *frameCount, bigtime_t *duration,
|
||||
media_format *format)
|
||||
{
|
||||
TRACE("OggSpeexStream::GetStreamInfo\n");
|
||||
status_t result = B_OK;
|
||||
ogg_packet packet;
|
||||
|
||||
// get header packet
|
||||
if (GetHeaderPackets().size() < 1) {
|
||||
result = GetPacket(&packet);
|
||||
if (result != B_OK) {
|
||||
return result;
|
||||
}
|
||||
SaveHeaderPacket(packet);
|
||||
}
|
||||
packet = GetHeaderPackets()[0];
|
||||
if (!packet.b_o_s) {
|
||||
return B_ERROR; // first packet was not beginning of stream
|
||||
}
|
||||
|
||||
// parse header packet, check size against struct minus optional fields
|
||||
if (packet.bytes < 1 + (signed)sizeof(SpeexHeader) - 2*(signed)sizeof(int)) {
|
||||
return B_ERROR;
|
||||
}
|
||||
void * data = &(packet.packet[0]);
|
||||
SpeexHeader * header = (SpeexHeader *)data;
|
||||
|
||||
// get the format for the description
|
||||
media_format_description description = speex_description();
|
||||
BMediaFormats formats;
|
||||
result = formats.InitCheck();
|
||||
if (result == B_OK) {
|
||||
result = formats.GetFormatFor(description, format);
|
||||
}
|
||||
if (result != B_OK) {
|
||||
*format = speex_encoded_media_format();
|
||||
// ignore error, allow user to use ReadChunk interface
|
||||
}
|
||||
|
||||
// fill out format from header packet
|
||||
if (header->bitrate > 0) {
|
||||
format->u.encoded_audio.bit_rate = header->bitrate;
|
||||
} else {
|
||||
// TODO: manually compute it where possible
|
||||
}
|
||||
if (header->nb_channels == 1) {
|
||||
format->u.encoded_audio.multi_info.channel_mask = B_CHANNEL_LEFT;
|
||||
} else {
|
||||
format->u.encoded_audio.multi_info.channel_mask = B_CHANNEL_LEFT | B_CHANNEL_RIGHT;
|
||||
}
|
||||
format->u.encoded_audio.output.frame_rate = header->rate;
|
||||
format->u.encoded_audio.output.channel_count = header->nb_channels;
|
||||
// allocate buffer, round up to nearest speex output_length size
|
||||
int buffer_size = AudioBufferSize(&format->u.encoded_audio.output);
|
||||
int output_length = header->frame_size * header->nb_channels *
|
||||
(format->u.encoded_audio.output.format & 0xf);
|
||||
buffer_size = ((buffer_size - 1) / output_length + 1) * output_length;
|
||||
format->u.encoded_audio.output.buffer_size = buffer_size;
|
||||
|
||||
// get comment packet
|
||||
if (GetHeaderPackets().size() < 2) {
|
||||
result = GetPacket(&packet);
|
||||
if (result != B_OK) {
|
||||
return result;
|
||||
}
|
||||
SaveHeaderPacket(packet);
|
||||
}
|
||||
|
||||
// get extra headers
|
||||
while ((signed)GetHeaderPackets().size() < header->extra_headers) {
|
||||
result = GetPacket(&packet);
|
||||
if (result != B_OK) {
|
||||
return result;
|
||||
}
|
||||
SaveHeaderPacket(packet);
|
||||
}
|
||||
|
||||
format->SetMetaData((void*)&GetHeaderPackets(),sizeof(GetHeaderPackets()));
|
||||
*duration = 100000000;
|
||||
*frameCount = 60000;
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
OggSpeexStream::GetNextChunk(const void **chunkBuffer, size_t *chunkSize,
|
||||
media_header *mediaHeader)
|
||||
{
|
||||
status_t result = GetPacket(&fChunkPacket);
|
||||
if (result != B_OK) {
|
||||
TRACE("OggSpeexStream::GetNextChunk failed: GetPacket = %s\n", strerror(result));
|
||||
return result;
|
||||
}
|
||||
*chunkBuffer = fChunkPacket.packet;
|
||||
*chunkSize = fChunkPacket.bytes;
|
||||
return B_OK;
|
||||
}
|
@ -1,26 +0,0 @@
|
||||
#ifndef _OGG_SPEEX_STREAM_H
|
||||
#define _OGG_SPEEX_STREAM_H
|
||||
|
||||
#include "OggStream.h"
|
||||
|
||||
namespace BPrivate { namespace media {
|
||||
|
||||
class OggSpeexStream : public OggStream {
|
||||
public:
|
||||
static bool IsValidHeader(const ogg_packet & packet);
|
||||
public:
|
||||
OggSpeexStream(long serialno);
|
||||
virtual ~OggSpeexStream();
|
||||
|
||||
virtual status_t GetStreamInfo(int64 *frameCount, bigtime_t *duration,
|
||||
media_format *format);
|
||||
virtual status_t GetNextChunk(const void **chunkBuffer, size_t *chunkSize,
|
||||
media_header *mediaHeader);
|
||||
|
||||
};
|
||||
|
||||
} } // namespace BPrivate::media
|
||||
|
||||
using namespace BPrivate::media;
|
||||
|
||||
#endif // _OGG_SPEEX_STREAM_H
|
@ -1,181 +0,0 @@
|
||||
#include "OggStream.h"
|
||||
#include "OggSpeexStream.h"
|
||||
#include "OggTheoraStream.h"
|
||||
#include "OggTobiasStream.h"
|
||||
#include "OggVorbisStream.h"
|
||||
#include "OggFormats.h"
|
||||
#include <Autolock.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#define TRACE_THIS 0
|
||||
#if TRACE_THIS
|
||||
#define TRACE printf
|
||||
#else
|
||||
#define TRACE(a...) ((void)0)
|
||||
#endif
|
||||
|
||||
/*
|
||||
* OggStream codec identification and instantiation
|
||||
*/
|
||||
|
||||
/* static */ OggStream *
|
||||
OggStream::makeOggStream(OggReader::StreamInterface * interface,
|
||||
long serialno, const ogg_packet & packet)
|
||||
{
|
||||
TRACE("OggStream::makeOggStream\n");
|
||||
OggStream * stream;
|
||||
if (OggVorbisStream::IsValidHeader(packet)) {
|
||||
stream = new OggVorbisStream(serialno);
|
||||
} else if (OggTobiasStream::IsValidHeader(packet)) {
|
||||
stream = new OggTobiasStream(serialno);
|
||||
} else if (OggSpeexStream::IsValidHeader(packet)) {
|
||||
stream = new OggSpeexStream(serialno);
|
||||
} else if (OggTheoraStream::IsValidHeader(packet)) {
|
||||
stream = new OggTheoraStream(serialno);
|
||||
} else {
|
||||
stream = new OggStream(serialno);
|
||||
}
|
||||
stream->fReaderInterface = interface;
|
||||
return stream;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* OggStream generic functions
|
||||
*/
|
||||
|
||||
OggStream::OggStream(long serialno)
|
||||
: OggTrack(serialno)
|
||||
{
|
||||
TRACE("OggStream::OggStream\n");
|
||||
fCurrentFrame = 0;
|
||||
fCurrentTime = 0;
|
||||
ogg_sync_init(&fSync);
|
||||
ogg_stream_init(&fStreamState,serialno);
|
||||
}
|
||||
|
||||
|
||||
OggStream::~OggStream()
|
||||
{
|
||||
// free internal stream state storage
|
||||
ogg_sync_clear(&fSync);
|
||||
ogg_stream_clear(&fStreamState);
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
OggStream::AddPage(off_t position, const ogg_page & page)
|
||||
{
|
||||
// TRACE("OggStream::AddPage\n");
|
||||
BAutolock autolock(fSyncLock);
|
||||
char * buffer;
|
||||
// copy the header to our local sync
|
||||
buffer = ogg_sync_buffer(&fSync, page.header_len);
|
||||
memcpy(buffer, page.header, page.header_len);
|
||||
ogg_sync_wrote(&fSync, page.header_len);
|
||||
// copy the body to our local sync
|
||||
buffer = ogg_sync_buffer(&fSync, page.body_len);
|
||||
memcpy(buffer, page.body, page.body_len);
|
||||
ogg_sync_wrote(&fSync, page.body_len);
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
OggStream::GetStreamInfo(int64 *frameCount, bigtime_t *duration,
|
||||
media_format *format)
|
||||
{
|
||||
TRACE("OggStream::GetStreamInfo\n");
|
||||
status_t result = B_OK;
|
||||
ogg_packet packet;
|
||||
if (GetHeaderPackets().size() < 1) {
|
||||
result = GetPacket(&packet);
|
||||
if (result != B_OK) {
|
||||
TRACE("OggStream::GetStreamInfo failed to get header packet\n");
|
||||
return result;
|
||||
}
|
||||
SaveHeaderPacket(packet);
|
||||
}
|
||||
packet = GetHeaderPackets()[0];
|
||||
if (!packet.b_o_s) {
|
||||
TRACE("OggStream::GetStreamInfo failed : not beginning of stream\n");
|
||||
return B_ERROR; // first packet was not beginning of stream
|
||||
}
|
||||
|
||||
// parse header packet
|
||||
uint32 four_bytes = *(uint32*)(&packet);
|
||||
|
||||
// get the format for the description
|
||||
media_format_description description;
|
||||
description.family = B_MISC_FORMAT_FAMILY;
|
||||
description.u.misc.file_format = OGG_FILE_FORMAT;
|
||||
description.u.misc.codec = four_bytes;
|
||||
BMediaFormats formats;
|
||||
result = formats.InitCheck();
|
||||
if (result == B_OK) {
|
||||
result = formats.GetFormatFor(description, format);
|
||||
}
|
||||
if (result != B_OK) {
|
||||
// ignore the error, allow the user to use ReadChunk interface
|
||||
}
|
||||
|
||||
// fill out format from header packet
|
||||
format->user_data_type = B_CODEC_TYPE_INFO;
|
||||
strncpy((char*)format->user_data, (char*)(&packet), 4);
|
||||
|
||||
format->SetMetaData((void*)&GetHeaderPackets(),sizeof(GetHeaderPackets()));
|
||||
*duration = 140000000;
|
||||
*frameCount = 60000;
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
|
||||
// the default chunk is an ogg packet
|
||||
status_t
|
||||
OggStream::GetNextChunk(const void **chunkBuffer, size_t *chunkSize,
|
||||
media_header *mediaHeader)
|
||||
{
|
||||
status_t result = GetPacket(&fChunkPacket);
|
||||
if (result != B_OK) {
|
||||
TRACE("OggStream::GetNextChunk failed: GetPacket = %s\n", strerror(result));
|
||||
return result;
|
||||
}
|
||||
*chunkBuffer = &fChunkPacket;
|
||||
*chunkSize = sizeof(fChunkPacket);
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
|
||||
// subclass pull input function
|
||||
status_t
|
||||
OggStream::GetPacket(ogg_packet * packet)
|
||||
{
|
||||
// at the end, pull the packet
|
||||
while (ogg_stream_packetpeek(&fStreamState, NULL) != 1) {
|
||||
BAutolock autolock(fSyncLock);
|
||||
int result;
|
||||
ogg_page page;
|
||||
while ((result = ogg_sync_pageout(&fSync,&page)) == 0) {
|
||||
result = fReaderInterface->ReadPage();
|
||||
if (result < 0) {
|
||||
TRACE("OggStream::GetPacket: GetNextPage = %s\n", strerror(result));
|
||||
return result;
|
||||
}
|
||||
}
|
||||
if (result == -1) {
|
||||
TRACE("OggStream::GetPacket: ogg_sync_pageout: not synced??\n");
|
||||
return B_ERROR;
|
||||
}
|
||||
if (ogg_stream_pagein(&fStreamState,&page) != 0) {
|
||||
TRACE("OggStream::GetPacket: ogg_stream_pagein: failed??\n");
|
||||
return B_ERROR;
|
||||
}
|
||||
}
|
||||
if (ogg_stream_packetout(&fStreamState, packet) != 1) {
|
||||
TRACE("OggStream::GetPacket: ogg_stream_packetout failed\n");
|
||||
return B_ERROR;
|
||||
}
|
||||
return B_OK;
|
||||
}
|
||||
|
@ -1,49 +0,0 @@
|
||||
#ifndef _OGG_STREAM_H
|
||||
#define _OGG_STREAM_H
|
||||
|
||||
#include "OggTrack.h"
|
||||
#include "OggReaderPlugin.h"
|
||||
#include <map>
|
||||
|
||||
namespace BPrivate { namespace media {
|
||||
|
||||
class OggStream : public OggTrack {
|
||||
public:
|
||||
static OggStream * makeOggStream(OggReader::StreamInterface * interface,
|
||||
long serialno, const ogg_packet & packet);
|
||||
|
||||
// interface for OggReader
|
||||
virtual status_t GetStreamInfo(int64 *frameCount, bigtime_t *duration,
|
||||
media_format *format);
|
||||
virtual status_t GetNextChunk(const void **chunkBuffer, size_t *chunkSize,
|
||||
media_header *mediaHeader);
|
||||
|
||||
protected:
|
||||
OggStream(long serialno);
|
||||
public:
|
||||
virtual ~OggStream();
|
||||
|
||||
// reader push input function
|
||||
virtual status_t AddPage(off_t position, const ogg_page & page);
|
||||
|
||||
protected:
|
||||
// subclass pull input function
|
||||
status_t GetPacket(ogg_packet * packet);
|
||||
ogg_packet fChunkPacket;
|
||||
|
||||
protected:
|
||||
int64 fCurrentFrame;
|
||||
bigtime_t fCurrentTime;
|
||||
|
||||
private:
|
||||
ogg_sync_state fSync;
|
||||
BLocker fSyncLock;
|
||||
ogg_stream_state fStreamState;
|
||||
OggReader::StreamInterface * fReaderInterface;
|
||||
};
|
||||
|
||||
} } // namespace BPrivate::media
|
||||
|
||||
using namespace BPrivate::media;
|
||||
|
||||
#endif // _OGG_STREAM_H
|
@ -1,43 +0,0 @@
|
||||
#ifndef _OGG_THEORA_FORMATS_H
|
||||
#define _OGG_THEORA_FORMATS_H
|
||||
|
||||
#include <MediaFormats.h>
|
||||
#include <ogg/ogg.h>
|
||||
#include <string.h>
|
||||
#include "OggFormats.h"
|
||||
|
||||
/*
|
||||
* theora descriptions/formats
|
||||
*/
|
||||
|
||||
|
||||
static media_format_description
|
||||
theora_description()
|
||||
{
|
||||
media_format_description description;
|
||||
description.family = B_MISC_FORMAT_FAMILY;
|
||||
description.u.misc.file_format = OGG_FILE_FORMAT;
|
||||
description.u.misc.codec = 'theo';
|
||||
return description;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
init_theora_media_raw_video_format(media_raw_video_format * output)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
static media_format
|
||||
theora_encoded_media_format()
|
||||
{
|
||||
media_format format;
|
||||
format.type = B_MEDIA_ENCODED_AUDIO;
|
||||
format.user_data_type = B_CODEC_TYPE_INFO;
|
||||
strncpy((char*)format.user_data, "theo", 4);
|
||||
init_theora_media_raw_video_format(&format.u.encoded_video.output);
|
||||
return format;
|
||||
}
|
||||
|
||||
|
||||
#endif //_OGG_THEORA_FORMATS_H
|
@ -1,206 +0,0 @@
|
||||
#include "OggTheoraFormats.h"
|
||||
#include "OggTheoraStream.h"
|
||||
#include <ogg/ogg.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#define TRACE_THIS 0
|
||||
#if TRACE_THIS
|
||||
#define TRACE printf
|
||||
#else
|
||||
#define TRACE(a...) ((void)0)
|
||||
#endif
|
||||
|
||||
inline size_t
|
||||
AudioBufferSize(media_raw_audio_format * raf, bigtime_t buffer_duration = 50000 /* 50 ms */)
|
||||
{
|
||||
return (raf->format & 0xf) * (raf->channel_count)
|
||||
* (size_t)((raf->frame_rate * buffer_duration) / 1000000.0);
|
||||
}
|
||||
|
||||
/*
|
||||
* theora header parsing code from theora/theara.h
|
||||
*/
|
||||
|
||||
typedef enum {
|
||||
OC_CS_UNSPECIFIED,
|
||||
OC_CS_ITU_REC_470M,
|
||||
OC_CS_ITU_REC_470BG,
|
||||
} theora_colorspace;
|
||||
|
||||
typedef struct {
|
||||
ogg_uint32_t width;
|
||||
ogg_uint32_t height;
|
||||
ogg_uint32_t frame_width;
|
||||
ogg_uint32_t frame_height;
|
||||
ogg_uint32_t offset_x;
|
||||
ogg_uint32_t offset_y;
|
||||
ogg_uint32_t fps_numerator;
|
||||
ogg_uint32_t fps_denominator;
|
||||
ogg_uint32_t aspect_numerator;
|
||||
ogg_uint32_t aspect_denominator;
|
||||
theora_colorspace colorspace;
|
||||
int target_bitrate;
|
||||
int quality;
|
||||
int quick_p; /* quick encode/decode */
|
||||
|
||||
/* decode only */
|
||||
unsigned char version_major;
|
||||
unsigned char version_minor;
|
||||
unsigned char version_subminor;
|
||||
|
||||
void *codec_setup;
|
||||
|
||||
/* encode only */
|
||||
int dropframes_p;
|
||||
int keyframe_auto_p;
|
||||
ogg_uint32_t keyframe_frequency;
|
||||
ogg_uint32_t keyframe_frequency_force; /* also used for decode init to
|
||||
get granpos shift correct */
|
||||
ogg_uint32_t keyframe_data_target_bitrate;
|
||||
ogg_int32_t keyframe_auto_threshold;
|
||||
ogg_uint32_t keyframe_mindistance;
|
||||
ogg_int32_t noise_sensitivity;
|
||||
ogg_int32_t sharpness;
|
||||
|
||||
} theora_info;
|
||||
|
||||
// based on theora/lib/toplevel.c _theora_unpack_info
|
||||
|
||||
#define theora_read(x,y,z) ( *z = oggpack_read(x,y) )
|
||||
|
||||
#define OC_BADHEADER -1
|
||||
|
||||
static int _theora_unpack_info(theora_info *ci, oggpack_buffer *opb){
|
||||
long ret;
|
||||
|
||||
theora_read(opb,8,&ret);
|
||||
ci->version_major=(unsigned char)ret;
|
||||
theora_read(opb,8,&ret);
|
||||
ci->version_minor=(unsigned char)ret;
|
||||
theora_read(opb,8,&ret);
|
||||
ci->version_subminor=(unsigned char)ret;
|
||||
|
||||
// if(ci->version_major!=VERSION_MAJOR)return(OC_VERSION);
|
||||
// if(ci->version_minor>VERSION_MINOR)return(OC_VERSION);
|
||||
|
||||
theora_read(opb,16,&ret);
|
||||
ci->width=ret<<4;
|
||||
theora_read(opb,16,&ret);
|
||||
ci->height=ret<<4;
|
||||
theora_read(opb,24,&ret);
|
||||
ci->frame_width=ret;
|
||||
theora_read(opb,24,&ret);
|
||||
ci->frame_height=ret;
|
||||
theora_read(opb,8,&ret);
|
||||
ci->offset_x=ret;
|
||||
theora_read(opb,8,&ret);
|
||||
ci->offset_y=ret;
|
||||
|
||||
theora_read(opb,32,&ret);
|
||||
ci->fps_numerator=ret;
|
||||
theora_read(opb,32,&ret);
|
||||
ci->fps_denominator=ret;
|
||||
theora_read(opb,24,&ret);
|
||||
ci->aspect_numerator=ret;
|
||||
theora_read(opb,24,&ret);
|
||||
ci->aspect_denominator=ret;
|
||||
|
||||
theora_read(opb,8,&ret);
|
||||
ci->colorspace=(theora_colorspace)ret;
|
||||
theora_read(opb,24,&ret);
|
||||
ci->target_bitrate=ret;
|
||||
theora_read(opb,6,&ret);
|
||||
ci->quality=ret=ret;
|
||||
|
||||
theora_read(opb,5,&ret);
|
||||
ci->keyframe_frequency_force=1<<ret;
|
||||
|
||||
/* spare configuration bits */
|
||||
if ( theora_read(opb,5,&ret) == -1 )
|
||||
return (OC_BADHEADER);
|
||||
|
||||
return(0);
|
||||
}
|
||||
|
||||
/*
|
||||
* OggTheoraStream implementations
|
||||
*/
|
||||
|
||||
/* static */ bool
|
||||
OggTheoraStream::IsValidHeader(const ogg_packet & packet)
|
||||
{
|
||||
return findIdentifier(packet,"theora",1);
|
||||
}
|
||||
|
||||
OggTheoraStream::OggTheoraStream(long serialno)
|
||||
: OggStream(serialno)
|
||||
{
|
||||
TRACE("OggTheoraStream::OggTheoraStream\n");
|
||||
}
|
||||
|
||||
OggTheoraStream::~OggTheoraStream()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
status_t
|
||||
OggTheoraStream::GetStreamInfo(int64 *frameCount, bigtime_t *duration,
|
||||
media_format *format)
|
||||
{
|
||||
TRACE("OggTheoraStream::GetStreamInfo\n");
|
||||
status_t result = B_OK;
|
||||
ogg_packet packet;
|
||||
|
||||
// get header packet
|
||||
if (GetHeaderPackets().size() < 1) {
|
||||
result = GetPacket(&packet);
|
||||
if (result != B_OK) {
|
||||
return result;
|
||||
}
|
||||
SaveHeaderPacket(packet);
|
||||
}
|
||||
packet = GetHeaderPackets()[0];
|
||||
if (!packet.b_o_s) {
|
||||
return B_ERROR; // first packet was not beginning of stream
|
||||
}
|
||||
|
||||
// parse header packet
|
||||
// based on libvorbis/info.c vorbis_synthesis_headerin(...)
|
||||
oggpack_buffer opb;
|
||||
oggpack_readinit(&opb, packet.packet, packet.bytes);
|
||||
int typeflag = oggpack_read(&opb, 8);
|
||||
if (typeflag != 0x80) {
|
||||
return B_ERROR; // first packet was not an info packet
|
||||
}
|
||||
// discard theora string
|
||||
for (uint i = 0 ; i < sizeof("theora") - 1 ; i++) {
|
||||
oggpack_read(&opb, 8);
|
||||
}
|
||||
theora_info info;
|
||||
if (_theora_unpack_info(&info, &opb) != 0) {
|
||||
return B_ERROR; // couldn't unpack info
|
||||
}
|
||||
|
||||
// get the format for the description
|
||||
media_format_description description = theora_description();
|
||||
BMediaFormats formats;
|
||||
result = formats.InitCheck();
|
||||
if (result == B_OK) {
|
||||
result = formats.GetFormatFor(description, format);
|
||||
}
|
||||
if (result != B_OK) {
|
||||
*format = theora_encoded_media_format();
|
||||
// ignore error, allow user to use ReadChunk interface
|
||||
}
|
||||
|
||||
// fill out format from header packet
|
||||
format->u.encoded_video.frame_size = info.frame_width * info.frame_height ;
|
||||
format->u.encoded_video.output.display.line_width = info.frame_width;
|
||||
format->u.encoded_video.output.display.line_count = info.frame_height;
|
||||
// TODO: wring more info out of the headers
|
||||
|
||||
format->SetMetaData((void*)&GetHeaderPackets(),sizeof(GetHeaderPackets()));
|
||||
*duration = 80000000;
|
||||
*frameCount = 60000;
|
||||
return B_OK;
|
||||
}
|
@ -1,23 +0,0 @@
|
||||
#ifndef _OGG_THEORA_STREAM_H
|
||||
#define _OGG_THEORA_STREAM_H
|
||||
|
||||
#include "OggStream.h"
|
||||
|
||||
namespace BPrivate { namespace media {
|
||||
|
||||
class OggTheoraStream : public OggStream {
|
||||
public:
|
||||
static bool IsValidHeader(const ogg_packet & packet);
|
||||
public:
|
||||
OggTheoraStream(long serialno);
|
||||
virtual ~OggTheoraStream();
|
||||
|
||||
virtual status_t GetStreamInfo(int64 *frameCount, bigtime_t *duration,
|
||||
media_format *format);
|
||||
};
|
||||
|
||||
} } // namespace BPrivate::media
|
||||
|
||||
using namespace BPrivate::media;
|
||||
|
||||
#endif // _OGG_THEORA_STREAM_H
|
@ -1,92 +0,0 @@
|
||||
#ifndef _OGG_TOBIAS_FORMATS_H
|
||||
#define _OGG_TOBIAS_FORMATS_H
|
||||
|
||||
#include <MediaFormats.h>
|
||||
#include <ogg/ogg.h>
|
||||
#include <string.h>
|
||||
#include "OggFormats.h"
|
||||
|
||||
/*
|
||||
* tobias descriptions/formats
|
||||
*/
|
||||
|
||||
|
||||
// video
|
||||
|
||||
static media_format_description
|
||||
tobias_video_description()
|
||||
{
|
||||
media_format_description description;
|
||||
description.family = B_AVI_FORMAT_FAMILY;
|
||||
return description;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
init_tobias_media_raw_video_format(media_raw_video_format * output)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
|
||||
static media_format
|
||||
tobias_video_encoded_media_format()
|
||||
{
|
||||
media_format format;
|
||||
format.type = B_MEDIA_ENCODED_VIDEO;
|
||||
init_tobias_media_raw_video_format(&format.u.encoded_video.output);
|
||||
return format;
|
||||
}
|
||||
|
||||
// audio
|
||||
|
||||
static media_format_description
|
||||
tobias_audio_description()
|
||||
{
|
||||
media_format_description description;
|
||||
description.family = B_WAV_FORMAT_FAMILY;
|
||||
return description;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
init_tobias_media_raw_audio_format(media_raw_audio_format * output)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
static media_format
|
||||
tobias_audio_encoded_media_format()
|
||||
{
|
||||
media_format format;
|
||||
format.type = B_MEDIA_ENCODED_AUDIO;
|
||||
init_tobias_media_raw_audio_format(&format.u.encoded_audio.output);
|
||||
return format;
|
||||
}
|
||||
|
||||
|
||||
// text
|
||||
|
||||
static media_format_description
|
||||
tobias_text_description()
|
||||
{
|
||||
media_format_description description;
|
||||
description.family = B_MISC_FORMAT_FAMILY;
|
||||
description.u.misc.file_format = OGG_FILE_FORMAT;
|
||||
description.u.misc.codec = 'text';
|
||||
return description;
|
||||
}
|
||||
|
||||
|
||||
static media_format
|
||||
tobias_text_encoded_media_format()
|
||||
{
|
||||
media_format format;
|
||||
format.type = B_MEDIA_HTML;
|
||||
format.user_data_type = B_CODEC_TYPE_INFO;
|
||||
strncpy((char*)format.user_data, "text", 4);
|
||||
return format;
|
||||
}
|
||||
|
||||
|
||||
#endif // _OGG_TOBIAS_FORMATS_H
|
@ -1,318 +0,0 @@
|
||||
#include "OggTobiasFormats.h"
|
||||
#include "OggTobiasSeekable.h"
|
||||
#include <stdio.h>
|
||||
|
||||
#define TRACE_THIS 0
|
||||
#if TRACE_THIS
|
||||
#define TRACE printf
|
||||
#else
|
||||
#define TRACE(a...) ((void)0)
|
||||
#endif
|
||||
|
||||
inline size_t
|
||||
AudioBufferSize(media_raw_audio_format * raf, bigtime_t buffer_duration = 50000 /* 50 ms */)
|
||||
{
|
||||
return (raf->format & 0xf) * (raf->channel_count)
|
||||
* (size_t)((raf->frame_rate * buffer_duration) / 1000000.0);
|
||||
}
|
||||
|
||||
/*
|
||||
* tobias header structs from http://tobias.everwicked.com/packfmt.htm
|
||||
*/
|
||||
|
||||
typedef struct tobias_stream_header_video
|
||||
{
|
||||
ogg_int32_t width;
|
||||
ogg_int32_t height;
|
||||
} tobias_stream_header_video;
|
||||
|
||||
typedef struct tobias_stream_header_audio
|
||||
{
|
||||
ogg_int16_t channels;
|
||||
ogg_int16_t blockalign;
|
||||
ogg_int32_t avgbytespersec;
|
||||
} tobias_stream_header_audio;
|
||||
|
||||
typedef struct tobias_stream_header
|
||||
{
|
||||
char streamtype[8];
|
||||
char subtype[4];
|
||||
|
||||
ogg_int32_t size; // size of the structure
|
||||
|
||||
ogg_int64_t time_unit; // in reference time (100 ns units)
|
||||
ogg_int64_t samples_per_unit;
|
||||
ogg_int32_t default_len; // in media time
|
||||
|
||||
ogg_int32_t buffersize;
|
||||
ogg_int16_t bits_per_sample;
|
||||
|
||||
union {
|
||||
// Video specific
|
||||
tobias_stream_header_video video;
|
||||
// Audio specific
|
||||
tobias_stream_header_audio audio;
|
||||
};
|
||||
} tobias_stream_header;
|
||||
|
||||
/*
|
||||
* OggTobiasSeekable implementations
|
||||
*/
|
||||
|
||||
/* static */ bool
|
||||
OggTobiasSeekable::IsValidHeader(const ogg_packet & packet)
|
||||
{
|
||||
return findIdentifier(packet,"video",1)
|
||||
|| findIdentifier(packet,"audio",1)
|
||||
|| findIdentifier(packet,"text",1);
|
||||
}
|
||||
|
||||
|
||||
OggTobiasSeekable::OggTobiasSeekable(long serialno)
|
||||
: OggSeekable(serialno)
|
||||
{
|
||||
TRACE("OggTobiasSeekable::OggTobiasSeekable\n");
|
||||
fMicrosecPerFrame = 0;
|
||||
}
|
||||
|
||||
|
||||
OggTobiasSeekable::~OggTobiasSeekable()
|
||||
{
|
||||
TRACE("OggTobiasSeekable::~OggTobiasSeekable\n");
|
||||
}
|
||||
|
||||
|
||||
static status_t
|
||||
get_video_format(tobias_stream_header * header, media_format * format)
|
||||
{
|
||||
TRACE(" get_video_format\n");
|
||||
// get the format for the description
|
||||
media_format_description description = tobias_video_description();
|
||||
description.u.avi.codec = header->subtype[3] << 24 | header->subtype[2] << 16
|
||||
| header->subtype[1] << 8 | header->subtype[0];
|
||||
BMediaFormats formats;
|
||||
status_t result = formats.InitCheck();
|
||||
if (result == B_OK) {
|
||||
result = formats.GetFormatFor(description, format);
|
||||
}
|
||||
if (result != B_OK) {
|
||||
*format = tobias_video_encoded_media_format();
|
||||
// ignore error, allow user to use ReadChunk interface
|
||||
}
|
||||
|
||||
// fill out format from header packet
|
||||
format->user_data_type = B_CODEC_TYPE_INFO;
|
||||
strncpy((char*)format->user_data, header->subtype, 4);
|
||||
format->u.encoded_video.frame_size
|
||||
= header->video.width * header->video.height;
|
||||
format->u.encoded_video.output.field_rate = 10000000.0 / header->time_unit;
|
||||
format->u.encoded_video.output.interlace = 1;
|
||||
format->u.encoded_video.output.first_active = 0;
|
||||
format->u.encoded_video.output.last_active = header->video.height - 1;
|
||||
format->u.encoded_video.output.orientation = B_VIDEO_TOP_LEFT_RIGHT;
|
||||
format->u.encoded_video.output.pixel_width_aspect = 1;
|
||||
format->u.encoded_video.output.pixel_height_aspect = 1;
|
||||
format->u.encoded_video.output.display.line_width = header->video.width;
|
||||
format->u.encoded_video.output.display.line_count = header->video.height;
|
||||
format->u.encoded_video.output.display.bytes_per_row = 0;
|
||||
format->u.encoded_video.output.display.pixel_offset = 0;
|
||||
format->u.encoded_video.output.display.line_offset = 0;
|
||||
format->u.encoded_video.output.display.flags = 0;
|
||||
|
||||
// TODO: wring more info out of the headers
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
|
||||
static status_t
|
||||
get_audio_format(tobias_stream_header * header, media_format * format)
|
||||
{
|
||||
TRACE(" get_audio_format\n");
|
||||
// get the format for the description
|
||||
media_format_description description = tobias_audio_description();
|
||||
unsigned int wav_id = 0;
|
||||
sscanf(header->subtype, "%04x", &wav_id);
|
||||
description.u.wav.codec = wav_id;
|
||||
BMediaFormats formats;
|
||||
status_t result = formats.InitCheck();
|
||||
if (result == B_OK) {
|
||||
result = formats.GetFormatFor(description, format);
|
||||
}
|
||||
if (result != B_OK) {
|
||||
*format = tobias_audio_encoded_media_format();
|
||||
// ignore error, allow user to use ReadChunk interface
|
||||
}
|
||||
|
||||
// fill out format from header packet
|
||||
format->user_data_type = B_CODEC_TYPE_INFO;
|
||||
strncpy((char*)format->user_data, header->subtype, 4);
|
||||
format->u.encoded_audio.bit_rate = header->audio.avgbytespersec * 8;
|
||||
if (header->audio.channels == 1) {
|
||||
format->u.encoded_audio.multi_info.channel_mask = B_CHANNEL_LEFT;
|
||||
} else {
|
||||
format->u.encoded_audio.multi_info.channel_mask = B_CHANNEL_LEFT | B_CHANNEL_RIGHT;
|
||||
}
|
||||
format->u.encoded_audio.output.frame_rate = header->samples_per_unit * 10000000.0 / header->time_unit;
|
||||
format->u.encoded_audio.output.channel_count = header->audio.channels;
|
||||
format->u.encoded_audio.output.buffer_size
|
||||
= AudioBufferSize(&format->u.encoded_audio.output);
|
||||
|
||||
// TODO: wring more info out of the headers
|
||||
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
|
||||
static status_t
|
||||
get_text_format(tobias_stream_header * header, media_format * format)
|
||||
{
|
||||
TRACE(" get_text_format\n");
|
||||
// get the format for the description
|
||||
media_format_description description = tobias_text_description();
|
||||
BMediaFormats formats;
|
||||
status_t result = formats.InitCheck();
|
||||
if (result == B_OK) {
|
||||
result = formats.GetFormatFor(description, format);
|
||||
}
|
||||
if (result != B_OK) {
|
||||
*format = tobias_text_encoded_media_format();
|
||||
// ignore error, allow user to use ReadChunk interface
|
||||
}
|
||||
|
||||
// fill out format from header packet
|
||||
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
OggTobiasSeekable::GetStreamInfo(int64 *frameCount, bigtime_t *duration,
|
||||
media_format *format)
|
||||
{
|
||||
TRACE("OggTobiasSeekable::GetStreamInfo\n");
|
||||
status_t result = B_OK;
|
||||
ogg_packet packet;
|
||||
|
||||
// get header packet
|
||||
if (GetHeaderPackets().size() < 1) {
|
||||
result = GetPacket(&packet);
|
||||
if (result != B_OK) {
|
||||
return result;
|
||||
}
|
||||
SaveHeaderPacket(packet);
|
||||
}
|
||||
packet = GetHeaderPackets()[0];
|
||||
if (!packet.b_o_s) {
|
||||
return B_ERROR; // first packet was not beginning of stream
|
||||
}
|
||||
|
||||
// parse header packet
|
||||
if (packet.bytes < 1+(signed)sizeof(tobias_stream_header)) {
|
||||
return B_ERROR;
|
||||
}
|
||||
void * data = &(packet.packet[1]);
|
||||
tobias_stream_header * header = (tobias_stream_header *)data;
|
||||
|
||||
if (strcmp(header->streamtype, "video") == 0) {
|
||||
result = get_video_format(header, format);
|
||||
if (result != B_OK) {
|
||||
return result;
|
||||
}
|
||||
} else if (strcmp(header->streamtype, "audio") == 0) {
|
||||
result = get_audio_format(header, format);
|
||||
if (result != B_OK) {
|
||||
return result;
|
||||
}
|
||||
} else if (strcmp(header->streamtype, "text") == 0) {
|
||||
result = get_text_format(header, format);
|
||||
if (result != B_OK) {
|
||||
return result;
|
||||
}
|
||||
} else {
|
||||
*frameCount = 0;
|
||||
// unknown streamtype
|
||||
return B_BAD_VALUE;
|
||||
}
|
||||
|
||||
// get comment packet
|
||||
if (GetHeaderPackets().size() < 2) {
|
||||
result = GetPacket(&packet);
|
||||
if (result != B_OK) {
|
||||
return result;
|
||||
}
|
||||
SaveHeaderPacket(packet);
|
||||
}
|
||||
|
||||
format->SetMetaData((void*)&GetHeaderPackets(),sizeof(GetHeaderPackets()));
|
||||
fMediaFormat = *format;
|
||||
fMicrosecPerFrame = header->time_unit / 10.0;
|
||||
fFrameRate = header->samples_per_unit * 1000000.0 / fMicrosecPerFrame;
|
||||
|
||||
// TODO: count the frames in the first page.. somehow.. :-/
|
||||
int64 frames = 0;
|
||||
|
||||
ogg_page page;
|
||||
// read the first page
|
||||
result = ReadPage(&page);
|
||||
if (result != B_OK) {
|
||||
return result;
|
||||
}
|
||||
int64 fFirstGranulepos = ogg_page_granulepos(&page);
|
||||
TRACE("OggVorbisSeekable::GetStreamInfo: first granulepos: %lld\n", fFirstGranulepos);
|
||||
// read our last page
|
||||
off_t last = inherited::Seek(GetLastPagePosition(), SEEK_SET);
|
||||
if (last < 0) {
|
||||
return last;
|
||||
}
|
||||
result = ReadPage(&page);
|
||||
if (result != B_OK) {
|
||||
return result;
|
||||
}
|
||||
int64 last_granulepos = ogg_page_granulepos(&page);
|
||||
|
||||
// seek back to the start
|
||||
int64 frame = 0;
|
||||
bigtime_t time = 0;
|
||||
result = Seek(B_MEDIA_SEEK_TO_TIME, &frame, &time);
|
||||
if (result != B_OK) {
|
||||
return result;
|
||||
}
|
||||
|
||||
// compute frame count and duration from sample count
|
||||
frames = last_granulepos - fFirstGranulepos;
|
||||
|
||||
*frameCount = frames;
|
||||
*duration = (long long)((1000000LL * frames) / (double)fFrameRate);
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
OggTobiasSeekable::GetNextChunk(const void **chunkBuffer, size_t *chunkSize,
|
||||
media_header *mediaHeader)
|
||||
{
|
||||
status_t result = inherited::GetNextChunk(chunkBuffer, chunkSize, mediaHeader);
|
||||
if (result != B_OK) {
|
||||
TRACE("OggTobiasSeekable::GetNextChunk failed: GetNextChunk = %s\n", strerror(result));
|
||||
return result;
|
||||
}
|
||||
bool keyframe = ((uint*)chunkBuffer)[0] & (1 << 3); // ??
|
||||
if (fMediaFormat.type == B_MEDIA_ENCODED_VIDEO) {
|
||||
mediaHeader->type = fMediaFormat.type;
|
||||
mediaHeader->u.encoded_video.field_flags = (keyframe ? B_MEDIA_KEY_FRAME : 0);
|
||||
mediaHeader->u.encoded_video.first_active_line
|
||||
= fMediaFormat.u.encoded_video.output.first_active;
|
||||
mediaHeader->u.encoded_video.line_count
|
||||
= fMediaFormat.u.encoded_video.output.display.line_count;
|
||||
}
|
||||
if (fMediaFormat.type == B_MEDIA_ENCODED_AUDIO) {
|
||||
mediaHeader->type = fMediaFormat.type;
|
||||
}
|
||||
if (mediaHeader->start_time < 0) {
|
||||
fCurrentFrame++;
|
||||
fCurrentTime = (bigtime_t)((fCurrentFrame * 1000000LL) / fFrameRate);
|
||||
mediaHeader->start_time = fCurrentTime;
|
||||
}
|
||||
// fprintf(stderr, "current frame = %lld, time = %lld\n", fCurrentFrame, fCurrentTime);
|
||||
return B_OK;
|
||||
}
|
@ -1,31 +0,0 @@
|
||||
#ifndef _OGG_TOBIAS_SEEKABLE_H
|
||||
#define _OGG_TOBIAS_SEEKABLE_H
|
||||
|
||||
#include "OggSeekable.h"
|
||||
|
||||
namespace BPrivate { namespace media {
|
||||
|
||||
class OggTobiasSeekable : public OggSeekable {
|
||||
private:
|
||||
typedef OggSeekable inherited;
|
||||
public:
|
||||
static bool IsValidHeader(const ogg_packet & packet);
|
||||
public:
|
||||
OggTobiasSeekable(long serialno);
|
||||
virtual ~OggTobiasSeekable();
|
||||
|
||||
virtual status_t GetStreamInfo(int64 *frameCount, bigtime_t *duration,
|
||||
media_format *format);
|
||||
virtual status_t GetNextChunk(const void **chunkBuffer, size_t *chunkSize,
|
||||
media_header *mediaHeader);
|
||||
|
||||
private:
|
||||
media_format fMediaFormat;
|
||||
double fMicrosecPerFrame;
|
||||
};
|
||||
|
||||
} } // namespace BPrivate::media
|
||||
|
||||
using namespace BPrivate::media;
|
||||
|
||||
#endif // _OGG_TOBIAS_SEEKABLE_H
|
@ -1,266 +0,0 @@
|
||||
#include "OggTobiasFormats.h"
|
||||
#include "OggTobiasStream.h"
|
||||
#include <stdio.h>
|
||||
|
||||
#define TRACE_THIS 0
|
||||
#if TRACE_THIS
|
||||
#define TRACE printf
|
||||
#else
|
||||
#define TRACE(a...) ((void)0)
|
||||
#endif
|
||||
|
||||
inline size_t
|
||||
AudioBufferSize(media_raw_audio_format * raf, bigtime_t buffer_duration = 50000 /* 50 ms */)
|
||||
{
|
||||
return (raf->format & 0xf) * (raf->channel_count)
|
||||
* (size_t)((raf->frame_rate * buffer_duration) / 1000000.0);
|
||||
}
|
||||
|
||||
/*
|
||||
* tobias header structs from http://tobias.everwicked.com/packfmt.htm
|
||||
*/
|
||||
|
||||
typedef struct tobias_stream_header_video
|
||||
{
|
||||
ogg_int32_t width;
|
||||
ogg_int32_t height;
|
||||
} tobias_stream_header_video;
|
||||
|
||||
typedef struct tobias_stream_header_audio
|
||||
{
|
||||
ogg_int16_t channels;
|
||||
ogg_int16_t blockalign;
|
||||
ogg_int32_t avgbytespersec;
|
||||
} tobias_stream_header_audio;
|
||||
|
||||
typedef struct tobias_stream_header
|
||||
{
|
||||
char streamtype[8];
|
||||
char subtype[4];
|
||||
|
||||
ogg_int32_t size; // size of the structure
|
||||
|
||||
ogg_int64_t time_unit; // in reference time (100 ns units)
|
||||
ogg_int64_t samples_per_unit;
|
||||
ogg_int32_t default_len; // in media time
|
||||
|
||||
ogg_int32_t buffersize;
|
||||
ogg_int16_t bits_per_sample;
|
||||
|
||||
union {
|
||||
// Video specific
|
||||
tobias_stream_header_video video;
|
||||
// Audio specific
|
||||
tobias_stream_header_audio audio;
|
||||
};
|
||||
} tobias_stream_header;
|
||||
|
||||
/*
|
||||
* OggTobiasStream implementations
|
||||
*/
|
||||
|
||||
/* static */ bool
|
||||
OggTobiasStream::IsValidHeader(const ogg_packet & packet)
|
||||
{
|
||||
return findIdentifier(packet,"video",1)
|
||||
|| findIdentifier(packet,"audio",1)
|
||||
|| findIdentifier(packet,"text",1);
|
||||
}
|
||||
|
||||
|
||||
OggTobiasStream::OggTobiasStream(long serialno)
|
||||
: OggStream(serialno)
|
||||
{
|
||||
TRACE("OggTobiasStream::OggTobiasStream\n");
|
||||
fMicrosecPerFrame = 0;
|
||||
}
|
||||
|
||||
|
||||
OggTobiasStream::~OggTobiasStream()
|
||||
{
|
||||
TRACE("OggTobiasStream::~OggTobiasStream\n");
|
||||
}
|
||||
|
||||
|
||||
static status_t
|
||||
get_video_format(tobias_stream_header * header, media_format * format)
|
||||
{
|
||||
TRACE(" get_video_format\n");
|
||||
// get the format for the description
|
||||
media_format_description description = tobias_video_description();
|
||||
description.u.avi.codec = header->subtype[3] << 24 | header->subtype[2] << 16
|
||||
| header->subtype[1] << 8 | header->subtype[0];
|
||||
BMediaFormats formats;
|
||||
status_t result = formats.InitCheck();
|
||||
if (result == B_OK) {
|
||||
result = formats.GetFormatFor(description, format);
|
||||
}
|
||||
if (result != B_OK) {
|
||||
*format = tobias_video_encoded_media_format();
|
||||
// ignore error, allow user to use ReadChunk interface
|
||||
}
|
||||
|
||||
// fill out format from header packet
|
||||
format->user_data_type = B_CODEC_TYPE_INFO;
|
||||
strncpy((char*)format->user_data, header->subtype, 4);
|
||||
format->u.encoded_video.frame_size
|
||||
= header->video.width * header->video.height;
|
||||
format->u.encoded_video.output.field_rate = 10000000.0 / header->time_unit;
|
||||
format->u.encoded_video.output.interlace = 1;
|
||||
format->u.encoded_video.output.first_active = 0;
|
||||
format->u.encoded_video.output.last_active = header->video.height - 1;
|
||||
format->u.encoded_video.output.orientation = B_VIDEO_TOP_LEFT_RIGHT;
|
||||
format->u.encoded_video.output.pixel_width_aspect = 1;
|
||||
format->u.encoded_video.output.pixel_height_aspect = 1;
|
||||
format->u.encoded_video.output.display.line_width = header->video.width;
|
||||
format->u.encoded_video.output.display.line_count = header->video.height;
|
||||
format->u.encoded_video.output.display.bytes_per_row = 0;
|
||||
format->u.encoded_video.output.display.pixel_offset = 0;
|
||||
format->u.encoded_video.output.display.line_offset = 0;
|
||||
format->u.encoded_video.output.display.flags = 0;
|
||||
|
||||
// TODO: wring more info out of the headers
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
|
||||
static status_t
|
||||
get_audio_format(tobias_stream_header * header, media_format * format)
|
||||
{
|
||||
TRACE(" get_audio_format\n");
|
||||
debugger("get_audio_format");
|
||||
return B_UNSUPPORTED;
|
||||
}
|
||||
|
||||
|
||||
static status_t
|
||||
get_text_format(tobias_stream_header * header, media_format * format)
|
||||
{
|
||||
TRACE(" get_text_format\n");
|
||||
// get the format for the description
|
||||
media_format_description description = tobias_text_description();
|
||||
BMediaFormats formats;
|
||||
status_t result = formats.InitCheck();
|
||||
if (result == B_OK) {
|
||||
result = formats.GetFormatFor(description, format);
|
||||
}
|
||||
if (result != B_OK) {
|
||||
*format = tobias_text_encoded_media_format();
|
||||
// ignore error, allow user to use ReadChunk interface
|
||||
}
|
||||
|
||||
// fill out format from header packet
|
||||
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
OggTobiasStream::GetStreamInfo(int64 *frameCount, bigtime_t *duration,
|
||||
media_format *format)
|
||||
{
|
||||
TRACE("OggTobiasStream::GetStreamInfo\n");
|
||||
status_t result = B_OK;
|
||||
ogg_packet packet;
|
||||
|
||||
// get header packet
|
||||
if (GetHeaderPackets().size() < 1) {
|
||||
result = GetPacket(&packet);
|
||||
if (result != B_OK) {
|
||||
return result;
|
||||
}
|
||||
SaveHeaderPacket(packet);
|
||||
}
|
||||
packet = GetHeaderPackets()[0];
|
||||
if (!packet.b_o_s) {
|
||||
return B_ERROR; // first packet was not beginning of stream
|
||||
}
|
||||
|
||||
// parse header packet
|
||||
if (packet.bytes < 1+(signed)sizeof(tobias_stream_header)) {
|
||||
return B_ERROR;
|
||||
}
|
||||
void * data = &(packet.packet[1]);
|
||||
tobias_stream_header * header = (tobias_stream_header *)data;
|
||||
|
||||
if (strcmp(header->streamtype, "video") == 0) {
|
||||
result = get_video_format(header, format);
|
||||
if (result != B_OK) {
|
||||
return result;
|
||||
}
|
||||
*frameCount = (bigtime_t)(3 * 3600 * format->u.encoded_video.output.field_rate);
|
||||
} else if (strcmp(header->streamtype, "audio") == 0) {
|
||||
result = get_audio_format(header, format);
|
||||
if (result != B_OK) {
|
||||
return result;
|
||||
}
|
||||
*frameCount = 2000000;
|
||||
} else if (strcmp(header->streamtype, "text") == 0) {
|
||||
result = get_text_format(header, format);
|
||||
if (result != B_OK) {
|
||||
return result;
|
||||
}
|
||||
*frameCount = 2000000;
|
||||
} else {
|
||||
*frameCount = 0;
|
||||
// unknown streamtype
|
||||
return B_BAD_VALUE;
|
||||
}
|
||||
|
||||
// get comment packet
|
||||
if (GetHeaderPackets().size() < 2) {
|
||||
result = GetPacket(&packet);
|
||||
if (result != B_OK) {
|
||||
return result;
|
||||
}
|
||||
SaveHeaderPacket(packet);
|
||||
}
|
||||
|
||||
format->SetMetaData((void*)&GetHeaderPackets(),sizeof(GetHeaderPackets()));
|
||||
fMediaFormat = *format;
|
||||
fMicrosecPerFrame = header->time_unit / 10.0;
|
||||
*duration = (bigtime_t)(*frameCount * fMicrosecPerFrame);
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
OggTobiasStream::GetNextChunk(const void **chunkBuffer, size_t *chunkSize,
|
||||
media_header *mediaHeader)
|
||||
{
|
||||
status_t result = GetPacket(&fChunkPacket);
|
||||
if (result != B_OK) {
|
||||
TRACE("OggTobiasStream::GetNextChunk failed: GetPacket = %s\n", strerror(result));
|
||||
return result;
|
||||
}
|
||||
*chunkBuffer = fChunkPacket.packet;
|
||||
*chunkSize = fChunkPacket.bytes;
|
||||
bool keyframe = fChunkPacket.packet[0] & (1 << 3); // ??
|
||||
if (fMediaFormat.type == B_MEDIA_ENCODED_VIDEO) {
|
||||
mediaHeader->type = fMediaFormat.type;
|
||||
mediaHeader->start_time = fCurrentTime;
|
||||
mediaHeader->u.encoded_video.field_flags = (keyframe ? B_MEDIA_KEY_FRAME : 0);
|
||||
mediaHeader->u.encoded_video.first_active_line
|
||||
= fMediaFormat.u.encoded_video.output.first_active;
|
||||
mediaHeader->u.encoded_video.line_count
|
||||
= fMediaFormat.u.encoded_video.output.display.line_count;
|
||||
}
|
||||
fCurrentFrame++;
|
||||
fCurrentTime = (bigtime_t)(fCurrentFrame * fMicrosecPerFrame);
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
OggTobiasStream::AddPage(off_t position, const ogg_page & page)
|
||||
{
|
||||
status_t status = OggStream::AddPage(position, page);
|
||||
if (fMediaFormat.type == B_MEDIA_HTML) {
|
||||
ogg_packet packet;
|
||||
GetPacket(&packet);
|
||||
if (packet.bytes > 4) {
|
||||
fprintf(stderr, "%s\n", &(packet.packet[3]));
|
||||
}
|
||||
}
|
||||
return status;
|
||||
}
|
@ -1,32 +0,0 @@
|
||||
#ifndef _OGG_TOBIAS_STREAM_H
|
||||
#define _OGG_TOBIAS_STREAM_H
|
||||
|
||||
#include "OggStream.h"
|
||||
|
||||
namespace BPrivate { namespace media {
|
||||
|
||||
class OggTobiasStream : public OggStream {
|
||||
public:
|
||||
static bool IsValidHeader(const ogg_packet & packet);
|
||||
public:
|
||||
OggTobiasStream(long serialno);
|
||||
virtual ~OggTobiasStream();
|
||||
|
||||
virtual status_t GetStreamInfo(int64 *frameCount, bigtime_t *duration,
|
||||
media_format *format);
|
||||
virtual status_t GetNextChunk(const void **chunkBuffer, size_t *chunkSize,
|
||||
media_header *mediaHeader);
|
||||
|
||||
// reader push input function
|
||||
virtual status_t AddPage(off_t position, const ogg_page & page);
|
||||
|
||||
private:
|
||||
media_format fMediaFormat;
|
||||
double fMicrosecPerFrame;
|
||||
};
|
||||
|
||||
} } // namespace BPrivate::media
|
||||
|
||||
using namespace BPrivate::media;
|
||||
|
||||
#endif // _OGG_TOBIAS_STREAM_H
|
@ -1,96 +0,0 @@
|
||||
#include "OggTrack.h"
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#define TRACE_THIS 0
|
||||
#if TRACE_THIS
|
||||
#define TRACE printf
|
||||
#else
|
||||
#define TRACE(a...) ((void)0)
|
||||
#endif
|
||||
|
||||
/* static */ bool
|
||||
OggTrack::findIdentifier(const ogg_packet & packet, const char * id, uint pos)
|
||||
{
|
||||
uint length = strlen(id);
|
||||
if ((unsigned)packet.bytes < pos+length) {
|
||||
return false;
|
||||
}
|
||||
return !memcmp(&packet.packet[pos], id, length);
|
||||
}
|
||||
|
||||
|
||||
OggTrack::OggTrack(long serialno)
|
||||
{
|
||||
TRACE("OggTrack::OggTrack\n");
|
||||
fSerialno = serialno;
|
||||
}
|
||||
|
||||
|
||||
OggTrack::~OggTrack()
|
||||
{
|
||||
// free internal header packet storage
|
||||
std::vector<ogg_packet>::iterator iter = fHeaderPackets.begin();
|
||||
while (iter != fHeaderPackets.end()) {
|
||||
delete iter->packet;
|
||||
iter++;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
long
|
||||
OggTrack::GetSerial() const
|
||||
{
|
||||
return fSerialno;
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
OggTrack::GetStreamInfo(int64 *frameCount, bigtime_t *duration,
|
||||
media_format *format)
|
||||
{
|
||||
*frameCount = 0;
|
||||
*duration = 0;
|
||||
media_format f;
|
||||
*format = f;
|
||||
return B_UNSUPPORTED;
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
OggTrack::Seek(uint32 seekTo, int64 *frame, bigtime_t *time)
|
||||
{
|
||||
*frame = 0;
|
||||
*time = 0;
|
||||
return B_UNSUPPORTED;
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
OggTrack::GetNextChunk(const void **chunkBuffer, size_t *chunkSize,
|
||||
media_header *mediaHeader)
|
||||
{
|
||||
*chunkBuffer = 0;
|
||||
*chunkSize = 0;
|
||||
media_header mh;
|
||||
*mediaHeader = mh;
|
||||
return B_UNSUPPORTED;
|
||||
}
|
||||
|
||||
|
||||
// GetStreamInfo helpers
|
||||
void
|
||||
OggTrack::SaveHeaderPacket(ogg_packet packet)
|
||||
{
|
||||
uint8 * buffer = new uint8[packet.bytes];
|
||||
memcpy(buffer, packet.packet, packet.bytes);
|
||||
packet.packet = buffer;
|
||||
fHeaderPackets.push_back(packet);
|
||||
}
|
||||
|
||||
|
||||
const std::vector<ogg_packet> &
|
||||
OggTrack::GetHeaderPackets()
|
||||
{
|
||||
return fHeaderPackets;
|
||||
}
|
@ -1,44 +0,0 @@
|
||||
#ifndef _OGG_TRACK_H
|
||||
#define _OGG_TRACK_H
|
||||
|
||||
#include <SupportDefs.h>
|
||||
#include <MediaDefs.h>
|
||||
#include "ogg/ogg.h"
|
||||
#include <vector>
|
||||
|
||||
namespace BPrivate { namespace media {
|
||||
|
||||
class OggTrack {
|
||||
protected:
|
||||
static bool findIdentifier(const ogg_packet & packet,
|
||||
const char * id, uint pos);
|
||||
OggTrack(long serialno);
|
||||
public:
|
||||
virtual ~OggTrack();
|
||||
long GetSerial() const;
|
||||
|
||||
// push interface
|
||||
virtual status_t AddPage(off_t position, const ogg_page & page) = 0;
|
||||
|
||||
// interface for OggReader
|
||||
virtual status_t GetStreamInfo(int64 *frameCount, bigtime_t *duration,
|
||||
media_format *format);
|
||||
virtual status_t Seek(uint32 seekTo, int64 *frame, bigtime_t *time);
|
||||
virtual status_t GetNextChunk(const void **chunkBuffer, size_t *chunkSize,
|
||||
media_header *mediaHeader);
|
||||
|
||||
protected:
|
||||
// GetStreamInfo helpers
|
||||
void SaveHeaderPacket(ogg_packet packet);
|
||||
const std::vector<ogg_packet> & GetHeaderPackets();
|
||||
|
||||
private:
|
||||
std::vector<ogg_packet> fHeaderPackets;
|
||||
long fSerialno;
|
||||
};
|
||||
|
||||
} } // namespace BPrivate::media
|
||||
|
||||
using namespace BPrivate::media;
|
||||
|
||||
#endif // _OGG_TRACK_H
|
@ -1,46 +0,0 @@
|
||||
#ifndef _OGG_VORBIS_FORMATS_H
|
||||
#define _OGG_VORBIS_FORMATS_H
|
||||
|
||||
#include <MediaFormats.h>
|
||||
#include <ogg/ogg.h>
|
||||
#include <string.h>
|
||||
#include "OggFormats.h"
|
||||
|
||||
/*
|
||||
* vorbis descriptions/formats
|
||||
*/
|
||||
|
||||
|
||||
static media_format_description
|
||||
vorbis_description()
|
||||
{
|
||||
media_format_description description;
|
||||
description.family = B_MISC_FORMAT_FAMILY;
|
||||
description.u.misc.file_format = OGG_FILE_FORMAT;
|
||||
description.u.misc.codec = 'vorb';
|
||||
return description;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
init_vorbis_media_raw_audio_format(media_raw_audio_format * output)
|
||||
{
|
||||
output->format = media_raw_audio_format::B_AUDIO_FLOAT;
|
||||
output->byte_order = B_MEDIA_HOST_ENDIAN;
|
||||
}
|
||||
|
||||
|
||||
static media_format
|
||||
vorbis_encoded_media_format()
|
||||
{
|
||||
media_format format;
|
||||
format.type = B_MEDIA_ENCODED_AUDIO;
|
||||
format.user_data_type = B_CODEC_TYPE_INFO;
|
||||
strncpy((char*)format.user_data, "vorb", 4);
|
||||
format.u.encoded_audio.frame_size = sizeof(ogg_packet);
|
||||
init_vorbis_media_raw_audio_format(&format.u.encoded_audio.output);
|
||||
return format;
|
||||
}
|
||||
|
||||
|
||||
#endif //_OGG_VORBIS_FORMATS_H
|
@ -1,230 +0,0 @@
|
||||
#include "OggVorbisFormats.h"
|
||||
#include "OggVorbisSeekable.h"
|
||||
#include <stdio.h>
|
||||
|
||||
#define TRACE_THIS 0
|
||||
#if TRACE_THIS
|
||||
#define TRACE printf
|
||||
#else
|
||||
#define TRACE(a...) ((void)0)
|
||||
#endif
|
||||
|
||||
inline size_t
|
||||
AudioBufferSize(media_raw_audio_format * raf, bigtime_t buffer_duration = 50000 /* 50 ms */)
|
||||
{
|
||||
return (raf->format & 0xf) * (raf->channel_count)
|
||||
* (size_t)((raf->frame_rate * buffer_duration) / 1000000.0);
|
||||
}
|
||||
|
||||
/*
|
||||
* vorbis header parsing code from libvorbis/info.c
|
||||
*/
|
||||
|
||||
typedef struct vorbis_info{
|
||||
int version;
|
||||
int channels;
|
||||
long rate;
|
||||
|
||||
/* The below bitrate declarations are *hints*.
|
||||
Combinations of the three values carry the following implications:
|
||||
|
||||
all three set to the same value:
|
||||
implies a fixed rate bitstream
|
||||
only nominal set:
|
||||
implies a VBR stream that averages the nominal bitrate. No hard
|
||||
upper/lower limit
|
||||
upper and or lower set:
|
||||
implies a VBR bitstream that obeys the bitrate limits. nominal
|
||||
may also be set to give a nominal rate.
|
||||
none set:
|
||||
the coder does not care to speculate.
|
||||
*/
|
||||
|
||||
long bitrate_upper;
|
||||
long bitrate_nominal;
|
||||
long bitrate_lower;
|
||||
long bitrate_window;
|
||||
|
||||
void *codec_setup;
|
||||
} vorbis_info;
|
||||
|
||||
|
||||
// based on libvorbis/info.c _vorbis_unpack_info
|
||||
static int _vorbis_unpack_info(vorbis_info *vi,oggpack_buffer *opb){
|
||||
vi->version = oggpack_read(opb, 32);
|
||||
if (vi->version != 0) {
|
||||
return -1;
|
||||
}
|
||||
vi->channels = oggpack_read(opb, 8);
|
||||
vi->rate = oggpack_read(opb, 32);
|
||||
vi->bitrate_upper = oggpack_read(opb, 32);
|
||||
vi->bitrate_nominal = oggpack_read(opb, 32);
|
||||
vi->bitrate_lower = oggpack_read(opb, 32);
|
||||
long blocksizes0 = oggpack_read(opb, 4);
|
||||
long blocksizes1 = oggpack_read(opb, 4);
|
||||
if (vi->rate < 1) {
|
||||
return -1;
|
||||
}
|
||||
if (vi->channels < 1) {
|
||||
return -1;
|
||||
}
|
||||
if (blocksizes0 < 8) {
|
||||
return -1;
|
||||
}
|
||||
if (blocksizes1 < blocksizes0) {
|
||||
return -1;
|
||||
}
|
||||
if (oggpack_read(opb, 1) != 1) {
|
||||
return -1;
|
||||
} /* EOP check */
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* OggVorbisSeekable implementations
|
||||
*/
|
||||
|
||||
/* static */ bool
|
||||
OggVorbisSeekable::IsValidHeader(const ogg_packet & packet)
|
||||
{
|
||||
return findIdentifier(packet,"vorbis",1);
|
||||
}
|
||||
|
||||
OggVorbisSeekable::OggVorbisSeekable(long serialno)
|
||||
: OggSeekable(serialno)
|
||||
{
|
||||
TRACE("OggVorbisSeekable::OggVorbisSeekable\n");
|
||||
}
|
||||
|
||||
OggVorbisSeekable::~OggVorbisSeekable()
|
||||
{
|
||||
TRACE("OggVorbisSeekable::~OggVorbisSeekable\n");
|
||||
}
|
||||
|
||||
status_t
|
||||
OggVorbisSeekable::GetStreamInfo(int64 *frameCount, bigtime_t *duration,
|
||||
media_format *format)
|
||||
{
|
||||
TRACE("OggVorbisSeekable::GetStreamInfo\n");
|
||||
status_t result = B_OK;
|
||||
ogg_packet packet;
|
||||
|
||||
// get header packet
|
||||
if (GetHeaderPackets().size() < 1) {
|
||||
result = GetPacket(&packet);
|
||||
if (result != B_OK) {
|
||||
return result;
|
||||
}
|
||||
SaveHeaderPacket(packet);
|
||||
}
|
||||
packet = GetHeaderPackets()[0];
|
||||
if (!packet.b_o_s) {
|
||||
return B_ERROR; // first packet was not beginning of stream
|
||||
}
|
||||
|
||||
// parse header packet
|
||||
// based on libvorbis/info.c vorbis_synthesis_headerin(...)
|
||||
oggpack_buffer opb;
|
||||
oggpack_readinit(&opb, packet.packet, packet.bytes);
|
||||
int packtype = oggpack_read(&opb, 8);
|
||||
if (packtype != 0x01) {
|
||||
return B_ERROR; // first packet was not an info packet
|
||||
}
|
||||
// discard vorbis string
|
||||
for (uint i = 0 ; i < sizeof("vorbis") - 1 ; i++) {
|
||||
oggpack_read(&opb, 8);
|
||||
}
|
||||
vorbis_info info;
|
||||
if (_vorbis_unpack_info(&info, &opb) != 0) {
|
||||
return B_ERROR; // couldn't unpack info
|
||||
}
|
||||
|
||||
// get the format for the description
|
||||
media_format_description description = vorbis_description();
|
||||
BMediaFormats formats;
|
||||
result = formats.InitCheck();
|
||||
if (result == B_OK) {
|
||||
result = formats.GetFormatFor(description, format);
|
||||
}
|
||||
if (result != B_OK) {
|
||||
*format = vorbis_encoded_media_format();
|
||||
// ignore error, allow user to use ReadChunk interface
|
||||
}
|
||||
|
||||
// fill out format from header packet
|
||||
if (info.bitrate_nominal > 0) {
|
||||
format->u.encoded_audio.bit_rate = info.bitrate_nominal;
|
||||
} else if (info.bitrate_upper > 0) {
|
||||
format->u.encoded_audio.bit_rate = info.bitrate_upper;
|
||||
} else if (info.bitrate_lower > 0) {
|
||||
format->u.encoded_audio.bit_rate = info.bitrate_lower;
|
||||
}
|
||||
if (info.channels == 1) {
|
||||
format->u.encoded_audio.multi_info.channel_mask = B_CHANNEL_LEFT;
|
||||
} else {
|
||||
format->u.encoded_audio.multi_info.channel_mask = B_CHANNEL_LEFT | B_CHANNEL_RIGHT;
|
||||
}
|
||||
fFrameRate = format->u.encoded_audio.output.frame_rate = (float)info.rate;
|
||||
format->u.encoded_audio.output.channel_count = info.channels;
|
||||
format->u.encoded_audio.output.buffer_size
|
||||
= AudioBufferSize(&format->u.encoded_audio.output);
|
||||
|
||||
// get comment packet
|
||||
if (GetHeaderPackets().size() < 2) {
|
||||
result = GetPacket(&packet);
|
||||
if (result != B_OK) {
|
||||
return result;
|
||||
}
|
||||
SaveHeaderPacket(packet);
|
||||
}
|
||||
|
||||
// get codebook packet
|
||||
if (GetHeaderPackets().size() < 3) {
|
||||
result = GetPacket(&packet);
|
||||
if (result != B_OK) {
|
||||
return result;
|
||||
}
|
||||
SaveHeaderPacket(packet);
|
||||
}
|
||||
|
||||
format->SetMetaData((void*)&GetHeaderPackets(),sizeof(GetHeaderPackets()));
|
||||
|
||||
// TODO: count the frames in the first page.. somehow.. :-/
|
||||
int64 frames = 0;
|
||||
|
||||
ogg_page page;
|
||||
// read the first page
|
||||
result = ReadPage(&page);
|
||||
if (result != B_OK) {
|
||||
return result;
|
||||
}
|
||||
int64 fFirstGranulepos = ogg_page_granulepos(&page);
|
||||
TRACE("OggVorbisSeekable::GetStreamInfo: first granulepos: %lld\n", fFirstGranulepos);
|
||||
// read our last page
|
||||
off_t last = inherited::Seek(GetLastPagePosition(), SEEK_SET);
|
||||
if (last < 0) {
|
||||
return last;
|
||||
}
|
||||
result = ReadPage(&page);
|
||||
if (result != B_OK) {
|
||||
return result;
|
||||
}
|
||||
int64 last_granulepos = ogg_page_granulepos(&page);
|
||||
|
||||
// seek back to the start
|
||||
int64 frame = 0;
|
||||
bigtime_t time = 0;
|
||||
result = Seek(B_MEDIA_SEEK_TO_TIME, &frame, &time);
|
||||
if (result != B_OK) {
|
||||
return result;
|
||||
}
|
||||
|
||||
// compute frame count and duration from sample count
|
||||
frames = last_granulepos - fFirstGranulepos;
|
||||
|
||||
*frameCount = frames;
|
||||
*duration = (1000000LL * frames) / (long long)fFrameRate;
|
||||
|
||||
return B_OK;
|
||||
}
|
@ -1,25 +0,0 @@
|
||||
#ifndef _OGG_VORBIS_SEEKABLE_H
|
||||
#define _OGG_VORBIS_SEEKABLE_H
|
||||
|
||||
#include "OggSeekable.h"
|
||||
|
||||
namespace BPrivate { namespace media {
|
||||
|
||||
class OggVorbisSeekable : public OggSeekable {
|
||||
private:
|
||||
typedef OggSeekable inherited;
|
||||
public:
|
||||
static bool IsValidHeader(const ogg_packet & packet);
|
||||
public:
|
||||
OggVorbisSeekable(long serialno);
|
||||
virtual ~OggVorbisSeekable();
|
||||
|
||||
virtual status_t GetStreamInfo(int64 *frameCount, bigtime_t *duration,
|
||||
media_format *format);
|
||||
};
|
||||
|
||||
} } // namespace BPrivate::media
|
||||
|
||||
using namespace BPrivate::media;
|
||||
|
||||
#endif // _OGG_VORBIS_SEEKABLE_H
|
@ -1,196 +0,0 @@
|
||||
#include "OggVorbisFormats.h"
|
||||
#include "OggVorbisStream.h"
|
||||
#include <stdio.h>
|
||||
|
||||
#define TRACE_THIS 0
|
||||
#if TRACE_THIS
|
||||
#define TRACE printf
|
||||
#else
|
||||
#define TRACE(a...) ((void)0)
|
||||
#endif
|
||||
|
||||
inline size_t
|
||||
AudioBufferSize(media_raw_audio_format * raf, bigtime_t buffer_duration = 50000 /* 50 ms */)
|
||||
{
|
||||
return (raf->format & 0xf) * (raf->channel_count)
|
||||
* (size_t)((raf->frame_rate * buffer_duration) / 1000000.0);
|
||||
}
|
||||
|
||||
/*
|
||||
* vorbis header parsing code from libvorbis/info.c
|
||||
*/
|
||||
|
||||
typedef struct vorbis_info{
|
||||
int version;
|
||||
int channels;
|
||||
long rate;
|
||||
|
||||
/* The below bitrate declarations are *hints*.
|
||||
Combinations of the three values carry the following implications:
|
||||
|
||||
all three set to the same value:
|
||||
implies a fixed rate bitstream
|
||||
only nominal set:
|
||||
implies a VBR stream that averages the nominal bitrate. No hard
|
||||
upper/lower limit
|
||||
upper and or lower set:
|
||||
implies a VBR bitstream that obeys the bitrate limits. nominal
|
||||
may also be set to give a nominal rate.
|
||||
none set:
|
||||
the coder does not care to speculate.
|
||||
*/
|
||||
|
||||
long bitrate_upper;
|
||||
long bitrate_nominal;
|
||||
long bitrate_lower;
|
||||
long bitrate_window;
|
||||
|
||||
void *codec_setup;
|
||||
} vorbis_info;
|
||||
|
||||
// based on libvorbis/info.c _vorbis_unpack_info
|
||||
static int _vorbis_unpack_info(vorbis_info *vi,oggpack_buffer *opb){
|
||||
vi->version = oggpack_read(opb, 32);
|
||||
if (vi->version != 0) {
|
||||
return -1;
|
||||
}
|
||||
vi->channels = oggpack_read(opb, 8);
|
||||
vi->rate = oggpack_read(opb, 32);
|
||||
vi->bitrate_upper = oggpack_read(opb, 32);
|
||||
vi->bitrate_nominal = oggpack_read(opb, 32);
|
||||
vi->bitrate_lower = oggpack_read(opb, 32);
|
||||
long blocksizes0 = oggpack_read(opb, 4);
|
||||
long blocksizes1 = oggpack_read(opb, 4);
|
||||
if (vi->rate < 1) {
|
||||
return -1;
|
||||
}
|
||||
if (vi->channels < 1) {
|
||||
return -1;
|
||||
}
|
||||
if (blocksizes0 < 8) {
|
||||
return -1;
|
||||
}
|
||||
if (blocksizes1 < blocksizes0) {
|
||||
return -1;
|
||||
}
|
||||
if (oggpack_read(opb, 1) != 1) {
|
||||
return -1;
|
||||
} /* EOP check */
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* OggVorbisStream implementations
|
||||
*/
|
||||
|
||||
/* static */ bool
|
||||
OggVorbisStream::IsValidHeader(const ogg_packet & packet)
|
||||
{
|
||||
return findIdentifier(packet,"vorbis",1);
|
||||
}
|
||||
|
||||
OggVorbisStream::OggVorbisStream(long serialno)
|
||||
: OggStream(serialno)
|
||||
{
|
||||
TRACE("OggVorbisStream::OggVorbisStream\n");
|
||||
}
|
||||
|
||||
OggVorbisStream::~OggVorbisStream()
|
||||
{
|
||||
TRACE("OggVorbisStream::~OggVorbisStream\n");
|
||||
}
|
||||
|
||||
status_t
|
||||
OggVorbisStream::GetStreamInfo(int64 *frameCount, bigtime_t *duration,
|
||||
media_format *format)
|
||||
{
|
||||
TRACE("OggVorbisStream::GetStreamInfo\n");
|
||||
status_t result = B_OK;
|
||||
ogg_packet packet;
|
||||
|
||||
// get header packet
|
||||
if (GetHeaderPackets().size() < 1) {
|
||||
result = GetPacket(&packet);
|
||||
if (result != B_OK) {
|
||||
return result;
|
||||
}
|
||||
SaveHeaderPacket(packet);
|
||||
}
|
||||
packet = GetHeaderPackets()[0];
|
||||
if (!packet.b_o_s) {
|
||||
return B_ERROR; // first packet was not beginning of stream
|
||||
}
|
||||
|
||||
// parse header packet
|
||||
// based on libvorbis/info.c vorbis_synthesis_headerin(...)
|
||||
oggpack_buffer opb;
|
||||
oggpack_readinit(&opb, packet.packet, packet.bytes);
|
||||
int packtype = oggpack_read(&opb, 8);
|
||||
if (packtype != 0x01) {
|
||||
return B_ERROR; // first packet was not an info packet
|
||||
}
|
||||
// discard vorbis string
|
||||
for (uint i = 0 ; i < sizeof("vorbis") - 1 ; i++) {
|
||||
oggpack_read(&opb, 8);
|
||||
}
|
||||
vorbis_info info;
|
||||
if (_vorbis_unpack_info(&info, &opb) != 0) {
|
||||
return B_ERROR; // couldn't unpack info
|
||||
}
|
||||
|
||||
// get the format for the description
|
||||
media_format_description description = vorbis_description();
|
||||
BMediaFormats formats;
|
||||
result = formats.InitCheck();
|
||||
if (result == B_OK) {
|
||||
result = formats.GetFormatFor(description, format);
|
||||
}
|
||||
if (result != B_OK) {
|
||||
*format = vorbis_encoded_media_format();
|
||||
// ignore error, allow user to use ReadChunk interface
|
||||
}
|
||||
|
||||
// fill out format from header packet
|
||||
if (info.bitrate_nominal > 0) {
|
||||
format->u.encoded_audio.bit_rate = info.bitrate_nominal;
|
||||
} else if (info.bitrate_upper > 0) {
|
||||
format->u.encoded_audio.bit_rate = info.bitrate_upper;
|
||||
} else if (info.bitrate_lower > 0) {
|
||||
format->u.encoded_audio.bit_rate = info.bitrate_lower;
|
||||
}
|
||||
if (info.channels == 1) {
|
||||
format->u.encoded_audio.multi_info.channel_mask = B_CHANNEL_LEFT;
|
||||
} else {
|
||||
format->u.encoded_audio.multi_info.channel_mask = B_CHANNEL_LEFT | B_CHANNEL_RIGHT;
|
||||
}
|
||||
format->u.encoded_audio.output.frame_rate = (float)info.rate;
|
||||
format->u.encoded_audio.output.channel_count = info.channels;
|
||||
format->u.encoded_audio.output.buffer_size
|
||||
= AudioBufferSize(&format->u.encoded_audio.output);
|
||||
|
||||
// get comment packet
|
||||
if (GetHeaderPackets().size() < 2) {
|
||||
result = GetPacket(&packet);
|
||||
if (result != B_OK) {
|
||||
return result;
|
||||
}
|
||||
SaveHeaderPacket(packet);
|
||||
}
|
||||
|
||||
// get codebook packet
|
||||
if (GetHeaderPackets().size() < 3) {
|
||||
result = GetPacket(&packet);
|
||||
if (result != B_OK) {
|
||||
return result;
|
||||
}
|
||||
SaveHeaderPacket(packet);
|
||||
}
|
||||
|
||||
format->SetMetaData((void*)&GetHeaderPackets(),sizeof(GetHeaderPackets()));
|
||||
|
||||
// compute frame count and duration from sample count
|
||||
*duration = 5 * 60 * 1000000;
|
||||
*frameCount = *duration * (long long)format->u.encoded_audio.output.frame_rate;
|
||||
|
||||
return B_OK;
|
||||
}
|
@ -1,23 +0,0 @@
|
||||
#ifndef _OGG_VORBIS_STREAM_H
|
||||
#define _OGG_VORBIS_STREAM_H
|
||||
|
||||
#include "OggStream.h"
|
||||
|
||||
namespace BPrivate { namespace media {
|
||||
|
||||
class OggVorbisStream : public OggStream {
|
||||
public:
|
||||
static bool IsValidHeader(const ogg_packet & packet);
|
||||
public:
|
||||
OggVorbisStream(long serialno);
|
||||
virtual ~OggVorbisStream();
|
||||
|
||||
virtual status_t GetStreamInfo(int64 *frameCount, bigtime_t *duration,
|
||||
media_format *format);
|
||||
};
|
||||
|
||||
} } // namespace BPrivate::media
|
||||
|
||||
using namespace BPrivate::media;
|
||||
|
||||
#endif // _OGG_VORBIS_STREAM_H
|
@ -1,4 +0,0 @@
|
||||
Monty <monty@xiph.org>
|
||||
|
||||
and the rest of the Xiph.Org Foundation.
|
||||
|
@ -1,2 +0,0 @@
|
||||
- Sat Sep 02 2000 Jack Moffitt <jack@icecast.org>
|
||||
+ separated from vorbis
|
@ -1,28 +0,0 @@
|
||||
Copyright (c) 2002, Xiph.org Foundation
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions
|
||||
are met:
|
||||
|
||||
- Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
|
||||
- Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
|
||||
- Neither the name of the Xiph.org Foundation nor the names of its
|
||||
contributors may be used to endorse or promote products derived from
|
||||
this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION
|
||||
OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
@ -1,8 +0,0 @@
|
||||
SubDir HAIKU_TOP src add-ons media plugins ogg libogg ;
|
||||
|
||||
SubDirSysHdrs $(SUBDIR) ;
|
||||
|
||||
StaticLibrary libogg.a :
|
||||
bitwise.c
|
||||
framing.c
|
||||
;
|
@ -1,782 +0,0 @@
|
||||
/********************************************************************
|
||||
* *
|
||||
* THIS FILE IS PART OF THE OggVorbis SOFTWARE CODEC SOURCE CODE. *
|
||||
* USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS *
|
||||
* GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE *
|
||||
* IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. *
|
||||
* *
|
||||
* THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2002 *
|
||||
* by the Xiph.Org Foundation http://www.xiph.org/ *
|
||||
* *
|
||||
********************************************************************
|
||||
|
||||
function: packing variable sized words into an octet stream
|
||||
last mod: $Id: bitwise.c 6729 2004-02-24 13:52:39Z shatty $
|
||||
|
||||
********************************************************************/
|
||||
|
||||
/* We're 'LSb' endian; if we write a word but read individual bits,
|
||||
then we'll read the lsb first */
|
||||
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <ogg/ogg.h>
|
||||
|
||||
#define BUFFER_INCREMENT 256
|
||||
|
||||
static unsigned long mask[]=
|
||||
{0x00000000,0x00000001,0x00000003,0x00000007,0x0000000f,
|
||||
0x0000001f,0x0000003f,0x0000007f,0x000000ff,0x000001ff,
|
||||
0x000003ff,0x000007ff,0x00000fff,0x00001fff,0x00003fff,
|
||||
0x00007fff,0x0000ffff,0x0001ffff,0x0003ffff,0x0007ffff,
|
||||
0x000fffff,0x001fffff,0x003fffff,0x007fffff,0x00ffffff,
|
||||
0x01ffffff,0x03ffffff,0x07ffffff,0x0fffffff,0x1fffffff,
|
||||
0x3fffffff,0x7fffffff,0xffffffff };
|
||||
|
||||
static unsigned int mask8B[]=
|
||||
{0x00,0x80,0xc0,0xe0,0xf0,0xf8,0xfc,0xfe,0xff};
|
||||
|
||||
void oggpack_writeinit(oggpack_buffer *b){
|
||||
memset(b,0,sizeof(*b));
|
||||
b->ptr=b->buffer=_ogg_malloc(BUFFER_INCREMENT);
|
||||
b->buffer[0]='\0';
|
||||
b->storage=BUFFER_INCREMENT;
|
||||
}
|
||||
|
||||
void oggpackB_writeinit(oggpack_buffer *b){
|
||||
oggpack_writeinit(b);
|
||||
}
|
||||
|
||||
void oggpack_writetrunc(oggpack_buffer *b,long bits){
|
||||
long bytes=bits>>3;
|
||||
bits-=bytes*8;
|
||||
b->ptr=b->buffer+bytes;
|
||||
b->endbit=bits;
|
||||
b->endbyte=bytes;
|
||||
*b->ptr&=mask[bits];
|
||||
}
|
||||
|
||||
void oggpackB_writetrunc(oggpack_buffer *b,long bits){
|
||||
long bytes=bits>>3;
|
||||
bits-=bytes*8;
|
||||
b->ptr=b->buffer+bytes;
|
||||
b->endbit=bits;
|
||||
b->endbyte=bytes;
|
||||
*b->ptr&=mask8B[bits];
|
||||
}
|
||||
|
||||
/* Takes only up to 32 bits. */
|
||||
void oggpack_write(oggpack_buffer *b,unsigned long value,int bits){
|
||||
if(b->endbyte+4>=b->storage){
|
||||
b->buffer=_ogg_realloc(b->buffer,b->storage+BUFFER_INCREMENT);
|
||||
b->storage+=BUFFER_INCREMENT;
|
||||
b->ptr=b->buffer+b->endbyte;
|
||||
}
|
||||
|
||||
value&=mask[bits];
|
||||
bits+=b->endbit;
|
||||
|
||||
b->ptr[0]|=value<<b->endbit;
|
||||
|
||||
if(bits>=8){
|
||||
b->ptr[1]=value>>(8-b->endbit);
|
||||
if(bits>=16){
|
||||
b->ptr[2]=value>>(16-b->endbit);
|
||||
if(bits>=24){
|
||||
b->ptr[3]=value>>(24-b->endbit);
|
||||
if(bits>=32){
|
||||
if(b->endbit)
|
||||
b->ptr[4]=value>>(32-b->endbit);
|
||||
else
|
||||
b->ptr[4]=0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
b->endbyte+=bits/8;
|
||||
b->ptr+=bits/8;
|
||||
b->endbit=bits&7;
|
||||
}
|
||||
|
||||
/* Takes only up to 32 bits. */
|
||||
void oggpackB_write(oggpack_buffer *b,unsigned long value,int bits){
|
||||
if(b->endbyte+4>=b->storage){
|
||||
b->buffer=_ogg_realloc(b->buffer,b->storage+BUFFER_INCREMENT);
|
||||
b->storage+=BUFFER_INCREMENT;
|
||||
b->ptr=b->buffer+b->endbyte;
|
||||
}
|
||||
|
||||
value=(value&mask[bits])<<(32-bits);
|
||||
bits+=b->endbit;
|
||||
|
||||
b->ptr[0]|=value>>(24+b->endbit);
|
||||
|
||||
if(bits>=8){
|
||||
b->ptr[1]=value>>(16+b->endbit);
|
||||
if(bits>=16){
|
||||
b->ptr[2]=value>>(8+b->endbit);
|
||||
if(bits>=24){
|
||||
b->ptr[3]=value>>(b->endbit);
|
||||
if(bits>=32){
|
||||
if(b->endbit)
|
||||
b->ptr[4]=value<<(8-b->endbit);
|
||||
else
|
||||
b->ptr[4]=0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
b->endbyte+=bits/8;
|
||||
b->ptr+=bits/8;
|
||||
b->endbit=bits&7;
|
||||
}
|
||||
|
||||
void oggpack_writealign(oggpack_buffer *b){
|
||||
int bits=8-b->endbit;
|
||||
if(bits<8)
|
||||
oggpack_write(b,0,bits);
|
||||
}
|
||||
|
||||
void oggpackB_writealign(oggpack_buffer *b){
|
||||
int bits=8-b->endbit;
|
||||
if(bits<8)
|
||||
oggpackB_write(b,0,bits);
|
||||
}
|
||||
|
||||
static void oggpack_writecopy_helper(oggpack_buffer *b,
|
||||
void *source,
|
||||
long bits,
|
||||
void (*w)(oggpack_buffer *,
|
||||
unsigned long,
|
||||
int),
|
||||
int msb){
|
||||
unsigned char *ptr=(unsigned char *)source;
|
||||
|
||||
long bytes=bits/8;
|
||||
bits-=bytes*8;
|
||||
|
||||
if(b->endbit){
|
||||
int i;
|
||||
/* unaligned copy. Do it the hard way. */
|
||||
for(i=0;i<bytes;i++)
|
||||
w(b,(unsigned long)(ptr[i]),8);
|
||||
}else{
|
||||
/* aligned block copy */
|
||||
if(b->endbyte+bytes+1>=b->storage){
|
||||
b->storage=b->endbyte+bytes+BUFFER_INCREMENT;
|
||||
b->buffer=_ogg_realloc(b->buffer,b->storage);
|
||||
b->ptr=b->buffer+b->endbyte;
|
||||
}
|
||||
|
||||
memmove(b->ptr,source,bytes);
|
||||
b->ptr+=bytes;
|
||||
b->buffer+=bytes;
|
||||
*b->ptr=0;
|
||||
|
||||
}
|
||||
if(bits){
|
||||
if(msb)
|
||||
w(b,(unsigned long)(ptr[bytes]>>(8-bits)),bits);
|
||||
else
|
||||
w(b,(unsigned long)(ptr[bytes]),bits);
|
||||
}
|
||||
}
|
||||
|
||||
void oggpack_writecopy(oggpack_buffer *b,void *source,long bits){
|
||||
oggpack_writecopy_helper(b,source,bits,oggpack_write,0);
|
||||
}
|
||||
|
||||
void oggpackB_writecopy(oggpack_buffer *b,void *source,long bits){
|
||||
oggpack_writecopy_helper(b,source,bits,oggpackB_write,1);
|
||||
}
|
||||
|
||||
void oggpack_reset(oggpack_buffer *b){
|
||||
b->ptr=b->buffer;
|
||||
b->buffer[0]=0;
|
||||
b->endbit=b->endbyte=0;
|
||||
}
|
||||
|
||||
void oggpackB_reset(oggpack_buffer *b){
|
||||
oggpack_reset(b);
|
||||
}
|
||||
|
||||
void oggpack_writeclear(oggpack_buffer *b){
|
||||
_ogg_free(b->buffer);
|
||||
memset(b,0,sizeof(*b));
|
||||
}
|
||||
|
||||
void oggpackB_writeclear(oggpack_buffer *b){
|
||||
oggpack_writeclear(b);
|
||||
}
|
||||
|
||||
void oggpack_readinit(oggpack_buffer *b,unsigned char *buf,int bytes){
|
||||
memset(b,0,sizeof(*b));
|
||||
b->buffer=b->ptr=buf;
|
||||
b->storage=bytes;
|
||||
}
|
||||
|
||||
void oggpackB_readinit(oggpack_buffer *b,unsigned char *buf,int bytes){
|
||||
oggpack_readinit(b,buf,bytes);
|
||||
}
|
||||
|
||||
/* Read in bits without advancing the bitptr; bits <= 32 */
|
||||
long oggpack_look(oggpack_buffer *b,int bits){
|
||||
unsigned long ret;
|
||||
unsigned long m=mask[bits];
|
||||
|
||||
bits+=b->endbit;
|
||||
|
||||
if(b->endbyte+4>=b->storage){
|
||||
/* not the main path */
|
||||
if(b->endbyte*8+bits>b->storage*8)return(-1);
|
||||
}
|
||||
|
||||
ret=b->ptr[0]>>b->endbit;
|
||||
if(bits>8){
|
||||
ret|=b->ptr[1]<<(8-b->endbit);
|
||||
if(bits>16){
|
||||
ret|=b->ptr[2]<<(16-b->endbit);
|
||||
if(bits>24){
|
||||
ret|=b->ptr[3]<<(24-b->endbit);
|
||||
if(bits>32 && b->endbit)
|
||||
ret|=b->ptr[4]<<(32-b->endbit);
|
||||
}
|
||||
}
|
||||
}
|
||||
return(m&ret);
|
||||
}
|
||||
|
||||
/* Read in bits without advancing the bitptr; bits <= 32 */
|
||||
long oggpackB_look(oggpack_buffer *b,int bits){
|
||||
unsigned long ret;
|
||||
int m=32-bits;
|
||||
|
||||
bits+=b->endbit;
|
||||
|
||||
if(b->endbyte+4>=b->storage){
|
||||
/* not the main path */
|
||||
if(b->endbyte*8+bits>b->storage*8)return(-1);
|
||||
}
|
||||
|
||||
ret=b->ptr[0]<<(24+b->endbit);
|
||||
if(bits>8){
|
||||
ret|=b->ptr[1]<<(16+b->endbit);
|
||||
if(bits>16){
|
||||
ret|=b->ptr[2]<<(8+b->endbit);
|
||||
if(bits>24){
|
||||
ret|=b->ptr[3]<<(b->endbit);
|
||||
if(bits>32 && b->endbit)
|
||||
ret|=b->ptr[4]>>(8-b->endbit);
|
||||
}
|
||||
}
|
||||
}
|
||||
return (ret>>(m>>1))>>((m+1)>>1);
|
||||
}
|
||||
|
||||
long oggpack_look1(oggpack_buffer *b){
|
||||
if(b->endbyte>=b->storage)return(-1);
|
||||
return((b->ptr[0]>>b->endbit)&1);
|
||||
}
|
||||
|
||||
long oggpackB_look1(oggpack_buffer *b){
|
||||
if(b->endbyte>=b->storage)return(-1);
|
||||
return((b->ptr[0]>>(7-b->endbit))&1);
|
||||
}
|
||||
|
||||
void oggpack_adv(oggpack_buffer *b,int bits){
|
||||
bits+=b->endbit;
|
||||
b->ptr+=bits/8;
|
||||
b->endbyte+=bits/8;
|
||||
b->endbit=bits&7;
|
||||
}
|
||||
|
||||
void oggpackB_adv(oggpack_buffer *b,int bits){
|
||||
oggpack_adv(b,bits);
|
||||
}
|
||||
|
||||
void oggpack_adv1(oggpack_buffer *b){
|
||||
if(++(b->endbit)>7){
|
||||
b->endbit=0;
|
||||
b->ptr++;
|
||||
b->endbyte++;
|
||||
}
|
||||
}
|
||||
|
||||
void oggpackB_adv1(oggpack_buffer *b){
|
||||
oggpack_adv1(b);
|
||||
}
|
||||
|
||||
/* bits <= 32 */
|
||||
long oggpack_read(oggpack_buffer *b,int bits){
|
||||
unsigned long ret;
|
||||
unsigned long m=mask[bits];
|
||||
|
||||
bits+=b->endbit;
|
||||
|
||||
if(b->endbyte+4>=b->storage){
|
||||
/* not the main path */
|
||||
ret=-1UL;
|
||||
if(b->endbyte*8+bits>b->storage*8)goto overflow;
|
||||
}
|
||||
|
||||
ret=b->ptr[0]>>b->endbit;
|
||||
if(bits>8){
|
||||
ret|=b->ptr[1]<<(8-b->endbit);
|
||||
if(bits>16){
|
||||
ret|=b->ptr[2]<<(16-b->endbit);
|
||||
if(bits>24){
|
||||
ret|=b->ptr[3]<<(24-b->endbit);
|
||||
if(bits>32 && b->endbit){
|
||||
ret|=b->ptr[4]<<(32-b->endbit);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
ret&=m;
|
||||
|
||||
overflow:
|
||||
|
||||
b->ptr+=bits/8;
|
||||
b->endbyte+=bits/8;
|
||||
b->endbit=bits&7;
|
||||
return(ret);
|
||||
}
|
||||
|
||||
/* bits <= 32 */
|
||||
long oggpackB_read(oggpack_buffer *b,int bits){
|
||||
unsigned long ret;
|
||||
long m=32-bits;
|
||||
|
||||
bits+=b->endbit;
|
||||
|
||||
if(b->endbyte+4>=b->storage){
|
||||
/* not the main path */
|
||||
ret=-1UL;
|
||||
if(b->endbyte*8+bits>b->storage*8)goto overflow;
|
||||
}
|
||||
|
||||
ret=b->ptr[0]<<(24+b->endbit);
|
||||
if(bits>8){
|
||||
ret|=b->ptr[1]<<(16+b->endbit);
|
||||
if(bits>16){
|
||||
ret|=b->ptr[2]<<(8+b->endbit);
|
||||
if(bits>24){
|
||||
ret|=b->ptr[3]<<(b->endbit);
|
||||
if(bits>32 && b->endbit)
|
||||
ret|=b->ptr[4]>>(8-b->endbit);
|
||||
}
|
||||
}
|
||||
}
|
||||
ret=(ret>>(m>>1))>>((m+1)>>1);
|
||||
|
||||
overflow:
|
||||
|
||||
b->ptr+=bits/8;
|
||||
b->endbyte+=bits/8;
|
||||
b->endbit=bits&7;
|
||||
return(ret);
|
||||
}
|
||||
|
||||
long oggpack_read1(oggpack_buffer *b){
|
||||
unsigned long ret;
|
||||
|
||||
if(b->endbyte>=b->storage){
|
||||
/* not the main path */
|
||||
ret=-1UL;
|
||||
goto overflow;
|
||||
}
|
||||
|
||||
ret=(b->ptr[0]>>b->endbit)&1;
|
||||
|
||||
overflow:
|
||||
|
||||
b->endbit++;
|
||||
if(b->endbit>7){
|
||||
b->endbit=0;
|
||||
b->ptr++;
|
||||
b->endbyte++;
|
||||
}
|
||||
return(ret);
|
||||
}
|
||||
|
||||
long oggpackB_read1(oggpack_buffer *b){
|
||||
unsigned long ret;
|
||||
|
||||
if(b->endbyte>=b->storage){
|
||||
/* not the main path */
|
||||
ret=-1UL;
|
||||
goto overflow;
|
||||
}
|
||||
|
||||
ret=(b->ptr[0]>>(7-b->endbit))&1;
|
||||
|
||||
overflow:
|
||||
|
||||
b->endbit++;
|
||||
if(b->endbit>7){
|
||||
b->endbit=0;
|
||||
b->ptr++;
|
||||
b->endbyte++;
|
||||
}
|
||||
return(ret);
|
||||
}
|
||||
|
||||
long oggpack_bytes(oggpack_buffer *b){
|
||||
return(b->endbyte+(b->endbit+7)/8);
|
||||
}
|
||||
|
||||
long oggpack_bits(oggpack_buffer *b){
|
||||
return(b->endbyte*8+b->endbit);
|
||||
}
|
||||
|
||||
long oggpackB_bytes(oggpack_buffer *b){
|
||||
return oggpack_bytes(b);
|
||||
}
|
||||
|
||||
long oggpackB_bits(oggpack_buffer *b){
|
||||
return oggpack_bits(b);
|
||||
}
|
||||
|
||||
unsigned char *oggpack_get_buffer(oggpack_buffer *b){
|
||||
return(b->buffer);
|
||||
}
|
||||
|
||||
unsigned char *oggpackB_get_buffer(oggpack_buffer *b){
|
||||
return oggpack_get_buffer(b);
|
||||
}
|
||||
|
||||
/* Self test of the bitwise routines; everything else is based on
|
||||
them, so they damned well better be solid. */
|
||||
|
||||
#ifdef _V_SELFTEST
|
||||
#include <stdio.h>
|
||||
|
||||
static int ilog(unsigned int v){
|
||||
int ret=0;
|
||||
while(v){
|
||||
ret++;
|
||||
v>>=1;
|
||||
}
|
||||
return(ret);
|
||||
}
|
||||
|
||||
oggpack_buffer o;
|
||||
oggpack_buffer r;
|
||||
|
||||
void report(char *in){
|
||||
fprintf(stderr,"%s",in);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
void cliptest(unsigned long *b,int vals,int bits,int *comp,int compsize){
|
||||
long bytes,i;
|
||||
unsigned char *buffer;
|
||||
|
||||
oggpack_reset(&o);
|
||||
for(i=0;i<vals;i++)
|
||||
oggpack_write(&o,b[i],bits?bits:ilog(b[i]));
|
||||
buffer=oggpack_get_buffer(&o);
|
||||
bytes=oggpack_bytes(&o);
|
||||
if(bytes!=compsize)report("wrong number of bytes!\n");
|
||||
for(i=0;i<bytes;i++)if(buffer[i]!=comp[i]){
|
||||
for(i=0;i<bytes;i++)fprintf(stderr,"%x %x\n",(int)buffer[i],(int)comp[i]);
|
||||
report("wrote incorrect value!\n");
|
||||
}
|
||||
oggpack_readinit(&r,buffer,bytes);
|
||||
for(i=0;i<vals;i++){
|
||||
int tbit=bits?bits:ilog(b[i]);
|
||||
if(oggpack_look(&r,tbit)==-1)
|
||||
report("out of data!\n");
|
||||
if(oggpack_look(&r,tbit)!=(b[i]&mask[tbit]))
|
||||
report("looked at incorrect value!\n");
|
||||
if(tbit==1)
|
||||
if(oggpack_look1(&r)!=(b[i]&mask[tbit]))
|
||||
report("looked at single bit incorrect value!\n");
|
||||
if(tbit==1){
|
||||
if(oggpack_read1(&r)!=(b[i]&mask[tbit]))
|
||||
report("read incorrect single bit value!\n");
|
||||
}else{
|
||||
if(oggpack_read(&r,tbit)!=(b[i]&mask[tbit]))
|
||||
report("read incorrect value!\n");
|
||||
}
|
||||
}
|
||||
if(oggpack_bytes(&r)!=bytes)report("leftover bytes after read!\n");
|
||||
}
|
||||
|
||||
void cliptestB(unsigned long *b,int vals,int bits,int *comp,int compsize){
|
||||
long bytes,i;
|
||||
unsigned char *buffer;
|
||||
|
||||
oggpackB_reset(&o);
|
||||
for(i=0;i<vals;i++)
|
||||
oggpackB_write(&o,b[i],bits?bits:ilog(b[i]));
|
||||
buffer=oggpackB_get_buffer(&o);
|
||||
bytes=oggpackB_bytes(&o);
|
||||
if(bytes!=compsize)report("wrong number of bytes!\n");
|
||||
for(i=0;i<bytes;i++)if(buffer[i]!=comp[i]){
|
||||
for(i=0;i<bytes;i++)fprintf(stderr,"%x %x\n",(int)buffer[i],(int)comp[i]);
|
||||
report("wrote incorrect value!\n");
|
||||
}
|
||||
oggpackB_readinit(&r,buffer,bytes);
|
||||
for(i=0;i<vals;i++){
|
||||
int tbit=bits?bits:ilog(b[i]);
|
||||
if(oggpackB_look(&r,tbit)==-1)
|
||||
report("out of data!\n");
|
||||
if(oggpackB_look(&r,tbit)!=(b[i]&mask[tbit]))
|
||||
report("looked at incorrect value!\n");
|
||||
if(tbit==1)
|
||||
if(oggpackB_look1(&r)!=(b[i]&mask[tbit]))
|
||||
report("looked at single bit incorrect value!\n");
|
||||
if(tbit==1){
|
||||
if(oggpackB_read1(&r)!=(b[i]&mask[tbit]))
|
||||
report("read incorrect single bit value!\n");
|
||||
}else{
|
||||
if(oggpackB_read(&r,tbit)!=(b[i]&mask[tbit]))
|
||||
report("read incorrect value!\n");
|
||||
}
|
||||
}
|
||||
if(oggpackB_bytes(&r)!=bytes)report("leftover bytes after read!\n");
|
||||
}
|
||||
|
||||
int main(void){
|
||||
unsigned char *buffer;
|
||||
long bytes,i;
|
||||
static unsigned long testbuffer1[]=
|
||||
{18,12,103948,4325,543,76,432,52,3,65,4,56,32,42,34,21,1,23,32,546,456,7,
|
||||
567,56,8,8,55,3,52,342,341,4,265,7,67,86,2199,21,7,1,5,1,4};
|
||||
int test1size=43;
|
||||
|
||||
static unsigned long testbuffer2[]=
|
||||
{216531625L,1237861823,56732452,131,3212421,12325343,34547562,12313212,
|
||||
1233432,534,5,346435231,14436467,7869299,76326614,167548585,
|
||||
85525151,0,12321,1,349528352};
|
||||
int test2size=21;
|
||||
|
||||
static unsigned long testbuffer3[]=
|
||||
{1,0,14,0,1,0,12,0,1,0,0,0,1,1,0,1,0,1,0,1,0,1,0,1,0,1,0,0,1,1,1,1,1,0,0,1,
|
||||
0,1,30,1,1,1,0,0,1,0,0,0,12,0,11,0,1,0,0,1};
|
||||
int test3size=56;
|
||||
|
||||
static unsigned long large[]=
|
||||
{2136531625L,2137861823,56732452,131,3212421,12325343,34547562,12313212,
|
||||
1233432,534,5,2146435231,14436467,7869299,76326614,167548585,
|
||||
85525151,0,12321,1,2146528352};
|
||||
|
||||
int onesize=33;
|
||||
static int one[33]={146,25,44,151,195,15,153,176,233,131,196,65,85,172,47,40,
|
||||
34,242,223,136,35,222,211,86,171,50,225,135,214,75,172,
|
||||
223,4};
|
||||
static int oneB[33]={150,101,131,33,203,15,204,216,105,193,156,65,84,85,222,
|
||||
8,139,145,227,126,34,55,244,171,85,100,39,195,173,18,
|
||||
245,251,128};
|
||||
|
||||
int twosize=6;
|
||||
static int two[6]={61,255,255,251,231,29};
|
||||
static int twoB[6]={247,63,255,253,249,120};
|
||||
|
||||
int threesize=54;
|
||||
static int three[54]={169,2,232,252,91,132,156,36,89,13,123,176,144,32,254,
|
||||
142,224,85,59,121,144,79,124,23,67,90,90,216,79,23,83,
|
||||
58,135,196,61,55,129,183,54,101,100,170,37,127,126,10,
|
||||
100,52,4,14,18,86,77,1};
|
||||
static int threeB[54]={206,128,42,153,57,8,183,251,13,89,36,30,32,144,183,
|
||||
130,59,240,121,59,85,223,19,228,180,134,33,107,74,98,
|
||||
233,253,196,135,63,2,110,114,50,155,90,127,37,170,104,
|
||||
200,20,254,4,58,106,176,144,0};
|
||||
|
||||
int foursize=38;
|
||||
static int four[38]={18,6,163,252,97,194,104,131,32,1,7,82,137,42,129,11,72,
|
||||
132,60,220,112,8,196,109,64,179,86,9,137,195,208,122,169,
|
||||
28,2,133,0,1};
|
||||
static int fourB[38]={36,48,102,83,243,24,52,7,4,35,132,10,145,21,2,93,2,41,
|
||||
1,219,184,16,33,184,54,149,170,132,18,30,29,98,229,67,
|
||||
129,10,4,32};
|
||||
|
||||
int fivesize=45;
|
||||
static int five[45]={169,2,126,139,144,172,30,4,80,72,240,59,130,218,73,62,
|
||||
241,24,210,44,4,20,0,248,116,49,135,100,110,130,181,169,
|
||||
84,75,159,2,1,0,132,192,8,0,0,18,22};
|
||||
static int fiveB[45]={1,84,145,111,245,100,128,8,56,36,40,71,126,78,213,226,
|
||||
124,105,12,0,133,128,0,162,233,242,67,152,77,205,77,
|
||||
172,150,169,129,79,128,0,6,4,32,0,27,9,0};
|
||||
|
||||
int sixsize=7;
|
||||
static int six[7]={17,177,170,242,169,19,148};
|
||||
static int sixB[7]={136,141,85,79,149,200,41};
|
||||
|
||||
/* Test read/write together */
|
||||
/* Later we test against pregenerated bitstreams */
|
||||
oggpack_writeinit(&o);
|
||||
|
||||
fprintf(stderr,"\nSmall preclipped packing (LSb): ");
|
||||
cliptest(testbuffer1,test1size,0,one,onesize);
|
||||
fprintf(stderr,"ok.");
|
||||
|
||||
fprintf(stderr,"\nNull bit call (LSb): ");
|
||||
cliptest(testbuffer3,test3size,0,two,twosize);
|
||||
fprintf(stderr,"ok.");
|
||||
|
||||
fprintf(stderr,"\nLarge preclipped packing (LSb): ");
|
||||
cliptest(testbuffer2,test2size,0,three,threesize);
|
||||
fprintf(stderr,"ok.");
|
||||
|
||||
fprintf(stderr,"\n32 bit preclipped packing (LSb): ");
|
||||
oggpack_reset(&o);
|
||||
for(i=0;i<test2size;i++)
|
||||
oggpack_write(&o,large[i],32);
|
||||
buffer=oggpack_get_buffer(&o);
|
||||
bytes=oggpack_bytes(&o);
|
||||
oggpack_readinit(&r,buffer,bytes);
|
||||
for(i=0;i<test2size;i++){
|
||||
if(oggpack_look(&r,32)==-1)report("out of data. failed!");
|
||||
if(oggpack_look(&r,32)!=large[i]){
|
||||
fprintf(stderr,"%ld != %ld (%lx!=%lx):",oggpack_look(&r,32),large[i],
|
||||
oggpack_look(&r,32),large[i]);
|
||||
report("read incorrect value!\n");
|
||||
}
|
||||
oggpack_adv(&r,32);
|
||||
}
|
||||
if(oggpack_bytes(&r)!=bytes)report("leftover bytes after read!\n");
|
||||
fprintf(stderr,"ok.");
|
||||
|
||||
fprintf(stderr,"\nSmall unclipped packing (LSb): ");
|
||||
cliptest(testbuffer1,test1size,7,four,foursize);
|
||||
fprintf(stderr,"ok.");
|
||||
|
||||
fprintf(stderr,"\nLarge unclipped packing (LSb): ");
|
||||
cliptest(testbuffer2,test2size,17,five,fivesize);
|
||||
fprintf(stderr,"ok.");
|
||||
|
||||
fprintf(stderr,"\nSingle bit unclipped packing (LSb): ");
|
||||
cliptest(testbuffer3,test3size,1,six,sixsize);
|
||||
fprintf(stderr,"ok.");
|
||||
|
||||
fprintf(stderr,"\nTesting read past end (LSb): ");
|
||||
oggpack_readinit(&r,"\0\0\0\0\0\0\0\0",8);
|
||||
for(i=0;i<64;i++){
|
||||
if(oggpack_read(&r,1)!=0){
|
||||
fprintf(stderr,"failed; got -1 prematurely.\n");
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
if(oggpack_look(&r,1)!=-1 ||
|
||||
oggpack_read(&r,1)!=-1){
|
||||
fprintf(stderr,"failed; read past end without -1.\n");
|
||||
exit(1);
|
||||
}
|
||||
oggpack_readinit(&r,"\0\0\0\0\0\0\0\0",8);
|
||||
if(oggpack_read(&r,30)!=0 || oggpack_read(&r,16)!=0){
|
||||
fprintf(stderr,"failed 2; got -1 prematurely.\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if(oggpack_look(&r,18)!=0 ||
|
||||
oggpack_look(&r,18)!=0){
|
||||
fprintf(stderr,"failed 3; got -1 prematurely.\n");
|
||||
exit(1);
|
||||
}
|
||||
if(oggpack_look(&r,19)!=-1 ||
|
||||
oggpack_look(&r,19)!=-1){
|
||||
fprintf(stderr,"failed; read past end without -1.\n");
|
||||
exit(1);
|
||||
}
|
||||
if(oggpack_look(&r,32)!=-1 ||
|
||||
oggpack_look(&r,32)!=-1){
|
||||
fprintf(stderr,"failed; read past end without -1.\n");
|
||||
exit(1);
|
||||
}
|
||||
fprintf(stderr,"ok.\n");
|
||||
|
||||
/********** lazy, cut-n-paste retest with MSb packing ***********/
|
||||
|
||||
/* Test read/write together */
|
||||
/* Later we test against pregenerated bitstreams */
|
||||
oggpackB_writeinit(&o);
|
||||
|
||||
fprintf(stderr,"\nSmall preclipped packing (MSb): ");
|
||||
cliptestB(testbuffer1,test1size,0,oneB,onesize);
|
||||
fprintf(stderr,"ok.");
|
||||
|
||||
fprintf(stderr,"\nNull bit call (MSb): ");
|
||||
cliptestB(testbuffer3,test3size,0,twoB,twosize);
|
||||
fprintf(stderr,"ok.");
|
||||
|
||||
fprintf(stderr,"\nLarge preclipped packing (MSb): ");
|
||||
cliptestB(testbuffer2,test2size,0,threeB,threesize);
|
||||
fprintf(stderr,"ok.");
|
||||
|
||||
fprintf(stderr,"\n32 bit preclipped packing (MSb): ");
|
||||
oggpackB_reset(&o);
|
||||
for(i=0;i<test2size;i++)
|
||||
oggpackB_write(&o,large[i],32);
|
||||
buffer=oggpackB_get_buffer(&o);
|
||||
bytes=oggpackB_bytes(&o);
|
||||
oggpackB_readinit(&r,buffer,bytes);
|
||||
for(i=0;i<test2size;i++){
|
||||
if(oggpackB_look(&r,32)==-1)report("out of data. failed!");
|
||||
if(oggpackB_look(&r,32)!=large[i]){
|
||||
fprintf(stderr,"%ld != %ld (%lx!=%lx):",oggpackB_look(&r,32),large[i],
|
||||
oggpackB_look(&r,32),large[i]);
|
||||
report("read incorrect value!\n");
|
||||
}
|
||||
oggpackB_adv(&r,32);
|
||||
}
|
||||
if(oggpackB_bytes(&r)!=bytes)report("leftover bytes after read!\n");
|
||||
fprintf(stderr,"ok.");
|
||||
|
||||
fprintf(stderr,"\nSmall unclipped packing (MSb): ");
|
||||
cliptestB(testbuffer1,test1size,7,fourB,foursize);
|
||||
fprintf(stderr,"ok.");
|
||||
|
||||
fprintf(stderr,"\nLarge unclipped packing (MSb): ");
|
||||
cliptestB(testbuffer2,test2size,17,fiveB,fivesize);
|
||||
fprintf(stderr,"ok.");
|
||||
|
||||
fprintf(stderr,"\nSingle bit unclipped packing (MSb): ");
|
||||
cliptestB(testbuffer3,test3size,1,sixB,sixsize);
|
||||
fprintf(stderr,"ok.");
|
||||
|
||||
fprintf(stderr,"\nTesting read past end (MSb): ");
|
||||
oggpackB_readinit(&r,"\0\0\0\0\0\0\0\0",8);
|
||||
for(i=0;i<64;i++){
|
||||
if(oggpackB_read(&r,1)!=0){
|
||||
fprintf(stderr,"failed; got -1 prematurely.\n");
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
if(oggpackB_look(&r,1)!=-1 ||
|
||||
oggpackB_read(&r,1)!=-1){
|
||||
fprintf(stderr,"failed; read past end without -1.\n");
|
||||
exit(1);
|
||||
}
|
||||
oggpackB_readinit(&r,"\0\0\0\0\0\0\0\0",8);
|
||||
if(oggpackB_read(&r,30)!=0 || oggpackB_read(&r,16)!=0){
|
||||
fprintf(stderr,"failed 2; got -1 prematurely.\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if(oggpackB_look(&r,18)!=0 ||
|
||||
oggpackB_look(&r,18)!=0){
|
||||
fprintf(stderr,"failed 3; got -1 prematurely.\n");
|
||||
exit(1);
|
||||
}
|
||||
if(oggpackB_look(&r,19)!=-1 ||
|
||||
oggpackB_look(&r,19)!=-1){
|
||||
fprintf(stderr,"failed; read past end without -1.\n");
|
||||
exit(1);
|
||||
}
|
||||
if(oggpackB_look(&r,32)!=-1 ||
|
||||
oggpackB_look(&r,32)!=-1){
|
||||
fprintf(stderr,"failed; read past end without -1.\n");
|
||||
exit(1);
|
||||
}
|
||||
fprintf(stderr,"ok.\n\n");
|
||||
|
||||
|
||||
return(0);
|
||||
}
|
||||
#endif /* _V_SELFTEST */
|
||||
|
||||
#undef BUFFER_INCREMENT
|
@ -1,11 +0,0 @@
|
||||
#ifndef __CONFIG_TYPES_H__
|
||||
#define __CONFIG_TYPES_H__
|
||||
|
||||
/* these are filled in by configure */
|
||||
typedef int16_t ogg_int16_t;
|
||||
typedef uint16_t ogg_uint16_t;
|
||||
typedef int32_t ogg_int32_t;
|
||||
typedef uint32_t ogg_uint32_t;
|
||||
typedef int64_t ogg_int64_t;
|
||||
|
||||
#endif
|
File diff suppressed because it is too large
Load Diff
@ -1,202 +0,0 @@
|
||||
/********************************************************************
|
||||
* *
|
||||
* THIS FILE IS PART OF THE OggVorbis SOFTWARE CODEC SOURCE CODE. *
|
||||
* USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS *
|
||||
* GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE *
|
||||
* IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. *
|
||||
* *
|
||||
* THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2002 *
|
||||
* by the Xiph.Org Foundation http://www.xiph.org/ *
|
||||
* *
|
||||
********************************************************************
|
||||
|
||||
function: toplevel libogg include
|
||||
last mod: $Id: ogg.h 6729 2004-02-24 13:52:39Z shatty $
|
||||
|
||||
********************************************************************/
|
||||
#ifndef _OGG_H
|
||||
#define _OGG_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include <ogg/os_types.h>
|
||||
|
||||
typedef struct {
|
||||
long endbyte;
|
||||
int endbit;
|
||||
|
||||
unsigned char *buffer;
|
||||
unsigned char *ptr;
|
||||
long storage;
|
||||
} oggpack_buffer;
|
||||
|
||||
/* ogg_page is used to encapsulate the data in one Ogg bitstream page *****/
|
||||
|
||||
typedef struct {
|
||||
unsigned char *header;
|
||||
long header_len;
|
||||
unsigned char *body;
|
||||
long body_len;
|
||||
} ogg_page;
|
||||
|
||||
/* ogg_stream_state contains the current encode/decode state of a logical
|
||||
Ogg bitstream **********************************************************/
|
||||
|
||||
typedef struct {
|
||||
unsigned char *body_data; /* bytes from packet bodies */
|
||||
long body_storage; /* storage elements allocated */
|
||||
long body_fill; /* elements stored; fill mark */
|
||||
long body_returned; /* elements of fill returned */
|
||||
|
||||
|
||||
int *lacing_vals; /* The values that will go to the segment table */
|
||||
ogg_int64_t *granule_vals; /* granulepos values for headers. Not compact
|
||||
this way, but it is simple coupled to the
|
||||
lacing fifo */
|
||||
long lacing_storage;
|
||||
long lacing_fill;
|
||||
long lacing_packet;
|
||||
long lacing_returned;
|
||||
|
||||
unsigned char header[282]; /* working space for header encode */
|
||||
int header_fill;
|
||||
|
||||
int e_o_s; /* set when we have buffered the last packet in the
|
||||
logical bitstream */
|
||||
int b_o_s; /* set after we've written the initial page
|
||||
of a logical bitstream */
|
||||
long serialno;
|
||||
long pageno;
|
||||
ogg_int64_t packetno; /* sequence number for decode; the framing
|
||||
knows where there's a hole in the data,
|
||||
but we need coupling so that the codec
|
||||
(which is in a seperate abstraction
|
||||
layer) also knows about the gap */
|
||||
ogg_int64_t granulepos;
|
||||
|
||||
} ogg_stream_state;
|
||||
|
||||
/* ogg_packet is used to encapsulate the data and metadata belonging
|
||||
to a single raw Ogg/Vorbis packet *************************************/
|
||||
|
||||
typedef struct {
|
||||
unsigned char *packet;
|
||||
long bytes;
|
||||
long b_o_s;
|
||||
long e_o_s;
|
||||
|
||||
ogg_int64_t granulepos;
|
||||
|
||||
ogg_int64_t packetno; /* sequence number for decode; the framing
|
||||
knows where there's a hole in the data,
|
||||
but we need coupling so that the codec
|
||||
(which is in a seperate abstraction
|
||||
layer) also knows about the gap */
|
||||
} ogg_packet;
|
||||
|
||||
typedef struct {
|
||||
unsigned char *data;
|
||||
int storage;
|
||||
int fill;
|
||||
int returned;
|
||||
|
||||
int unsynced;
|
||||
int headerbytes;
|
||||
int bodybytes;
|
||||
} ogg_sync_state;
|
||||
|
||||
/* Ogg BITSTREAM PRIMITIVES: bitstream ************************/
|
||||
|
||||
extern void oggpack_writeinit(oggpack_buffer *b);
|
||||
extern void oggpack_writetrunc(oggpack_buffer *b,long bits);
|
||||
extern void oggpack_writealign(oggpack_buffer *b);
|
||||
extern void oggpack_writecopy(oggpack_buffer *b,void *source,long bits);
|
||||
extern void oggpack_reset(oggpack_buffer *b);
|
||||
extern void oggpack_writeclear(oggpack_buffer *b);
|
||||
extern void oggpack_readinit(oggpack_buffer *b,unsigned char *buf,int bytes);
|
||||
extern void oggpack_write(oggpack_buffer *b,unsigned long value,int bits);
|
||||
extern long oggpack_look(oggpack_buffer *b,int bits);
|
||||
extern long oggpack_look1(oggpack_buffer *b);
|
||||
extern void oggpack_adv(oggpack_buffer *b,int bits);
|
||||
extern void oggpack_adv1(oggpack_buffer *b);
|
||||
extern long oggpack_read(oggpack_buffer *b,int bits);
|
||||
extern long oggpack_read1(oggpack_buffer *b);
|
||||
extern long oggpack_bytes(oggpack_buffer *b);
|
||||
extern long oggpack_bits(oggpack_buffer *b);
|
||||
extern unsigned char *oggpack_get_buffer(oggpack_buffer *b);
|
||||
|
||||
extern void oggpackB_writeinit(oggpack_buffer *b);
|
||||
extern void oggpackB_writetrunc(oggpack_buffer *b,long bits);
|
||||
extern void oggpackB_writealign(oggpack_buffer *b);
|
||||
extern void oggpackB_writecopy(oggpack_buffer *b,void *source,long bits);
|
||||
extern void oggpackB_reset(oggpack_buffer *b);
|
||||
extern void oggpackB_writeclear(oggpack_buffer *b);
|
||||
extern void oggpackB_readinit(oggpack_buffer *b,unsigned char *buf,int bytes);
|
||||
extern void oggpackB_write(oggpack_buffer *b,unsigned long value,int bits);
|
||||
extern long oggpackB_look(oggpack_buffer *b,int bits);
|
||||
extern long oggpackB_look1(oggpack_buffer *b);
|
||||
extern void oggpackB_adv(oggpack_buffer *b,int bits);
|
||||
extern void oggpackB_adv1(oggpack_buffer *b);
|
||||
extern long oggpackB_read(oggpack_buffer *b,int bits);
|
||||
extern long oggpackB_read1(oggpack_buffer *b);
|
||||
extern long oggpackB_bytes(oggpack_buffer *b);
|
||||
extern long oggpackB_bits(oggpack_buffer *b);
|
||||
extern unsigned char *oggpackB_get_buffer(oggpack_buffer *b);
|
||||
|
||||
/* Ogg BITSTREAM PRIMITIVES: encoding **************************/
|
||||
|
||||
extern int ogg_stream_packetin(ogg_stream_state *os, ogg_packet *op);
|
||||
extern int ogg_stream_pageout(ogg_stream_state *os, ogg_page *og);
|
||||
extern int ogg_stream_flush(ogg_stream_state *os, ogg_page *og);
|
||||
|
||||
/* Ogg BITSTREAM PRIMITIVES: decoding **************************/
|
||||
|
||||
extern int ogg_sync_init(ogg_sync_state *oy);
|
||||
extern int ogg_sync_clear(ogg_sync_state *oy);
|
||||
extern int ogg_sync_reset(ogg_sync_state *oy);
|
||||
extern int ogg_sync_destroy(ogg_sync_state *oy);
|
||||
|
||||
extern char *ogg_sync_buffer(ogg_sync_state *oy, long size);
|
||||
extern int ogg_sync_wrote(ogg_sync_state *oy, long bytes);
|
||||
extern long ogg_sync_pageseek(ogg_sync_state *oy,ogg_page *og);
|
||||
extern int ogg_sync_pageout(ogg_sync_state *oy, ogg_page *og);
|
||||
extern int ogg_stream_pagein(ogg_stream_state *os, ogg_page *og);
|
||||
extern int ogg_stream_packetout(ogg_stream_state *os,ogg_packet *op);
|
||||
extern int ogg_stream_packetpeek(ogg_stream_state *os,ogg_packet *op);
|
||||
|
||||
/* Ogg BITSTREAM PRIMITIVES: general ***************************/
|
||||
|
||||
extern int ogg_stream_init(ogg_stream_state *os,int serialno);
|
||||
extern int ogg_stream_clear(ogg_stream_state *os);
|
||||
extern int ogg_stream_reset(ogg_stream_state *os);
|
||||
extern int ogg_stream_reset_serialno(ogg_stream_state *os,int serialno);
|
||||
extern int ogg_stream_destroy(ogg_stream_state *os);
|
||||
extern int ogg_stream_eos(ogg_stream_state *os);
|
||||
|
||||
extern void ogg_page_checksum_set(ogg_page *og);
|
||||
|
||||
extern int ogg_page_version(ogg_page *og);
|
||||
extern int ogg_page_continued(ogg_page *og);
|
||||
extern int ogg_page_bos(ogg_page *og);
|
||||
extern int ogg_page_eos(ogg_page *og);
|
||||
extern ogg_int64_t ogg_page_granulepos(ogg_page *og);
|
||||
extern int ogg_page_serialno(ogg_page *og);
|
||||
extern long ogg_page_pageno(ogg_page *og);
|
||||
extern int ogg_page_packets(ogg_page *og);
|
||||
|
||||
extern void ogg_packet_clear(ogg_packet *op);
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* _OGG_H */
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
@ -1,106 +0,0 @@
|
||||
/********************************************************************
|
||||
* *
|
||||
* THIS FILE IS PART OF THE OggVorbis SOFTWARE CODEC SOURCE CODE. *
|
||||
* USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS *
|
||||
* GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE *
|
||||
* IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. *
|
||||
* *
|
||||
* THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2002 *
|
||||
* by the Xiph.Org Foundation http://www.xiph.org/ *
|
||||
* *
|
||||
********************************************************************
|
||||
|
||||
function: #ifdef jail to whip a few platforms into the UNIX ideal.
|
||||
last mod: $Id: os_types.h 28305 2008-10-23 21:46:26Z bonefish $
|
||||
|
||||
********************************************************************/
|
||||
#ifndef _OS_TYPES_H
|
||||
#define _OS_TYPES_H
|
||||
|
||||
/* make it easy on the folks that want to compile the libs with a
|
||||
different malloc than stdlib */
|
||||
#define _ogg_malloc malloc
|
||||
#define _ogg_calloc calloc
|
||||
#define _ogg_realloc realloc
|
||||
#define _ogg_free free
|
||||
|
||||
#ifdef _WIN32
|
||||
|
||||
# ifndef __GNUC__
|
||||
/* MSVC/Borland */
|
||||
typedef __int64 ogg_int64_t;
|
||||
typedef __int32 ogg_int32_t;
|
||||
typedef unsigned __int32 ogg_uint32_t;
|
||||
typedef __int16 ogg_int16_t;
|
||||
typedef unsigned __int16 ogg_uint16_t;
|
||||
# else
|
||||
/* Cygwin */
|
||||
#include <_G_config.h>
|
||||
typedef _G_int64_t ogg_int64_t;
|
||||
typedef _G_int32_t ogg_int32_t;
|
||||
typedef _G_uint32_t ogg_uint32_t;
|
||||
typedef _G_int16_t ogg_int16_t;
|
||||
typedef _G_uint16_t ogg_uint16_t;
|
||||
# endif
|
||||
|
||||
#elif defined(__MACOS__)
|
||||
|
||||
# include <sys/types.h>
|
||||
typedef SInt16 ogg_int16_t;
|
||||
typedef UInt16 ogg_uint16_t;
|
||||
typedef SInt32 ogg_int32_t;
|
||||
typedef UInt32 ogg_uint32_t;
|
||||
typedef SInt64 ogg_int64_t;
|
||||
|
||||
#elif defined(__MACOSX__) /* MacOS X Framework build */
|
||||
|
||||
# include <sys/types.h>
|
||||
typedef int16_t ogg_int16_t;
|
||||
typedef u_int16_t ogg_uint16_t;
|
||||
typedef int32_t ogg_int32_t;
|
||||
typedef u_int32_t ogg_uint32_t;
|
||||
typedef int64_t ogg_int64_t;
|
||||
|
||||
#elif (defined(__BEOS__) || defined(__HAIKU__))
|
||||
|
||||
/* Be */
|
||||
# include <inttypes.h>
|
||||
typedef int16_t ogg_int16_t;
|
||||
typedef u_int16_t ogg_uint16_t;
|
||||
typedef int32_t ogg_int32_t;
|
||||
typedef u_int32_t ogg_uint32_t;
|
||||
typedef int64_t ogg_int64_t;
|
||||
|
||||
#elif defined (__EMX__)
|
||||
|
||||
/* OS/2 GCC */
|
||||
typedef short ogg_int16_t;
|
||||
typedef unsigned short ogg_uint16_t;
|
||||
typedef int ogg_int32_t;
|
||||
typedef unsigned int ogg_uint32_t;
|
||||
typedef long long ogg_int64_t;
|
||||
|
||||
#elif defined (DJGPP)
|
||||
|
||||
/* DJGPP */
|
||||
typedef short ogg_int16_t;
|
||||
typedef int ogg_int32_t;
|
||||
typedef unsigned int ogg_uint32_t;
|
||||
typedef long long ogg_int64_t;
|
||||
|
||||
#elif defined(R5900)
|
||||
|
||||
/* PS2 EE */
|
||||
typedef long ogg_int64_t;
|
||||
typedef int ogg_int32_t;
|
||||
typedef unsigned ogg_uint32_t;
|
||||
typedef short ogg_int16_t;
|
||||
|
||||
#else
|
||||
|
||||
# include <sys/types.h>
|
||||
# include <ogg/config_types.h>
|
||||
|
||||
#endif
|
||||
|
||||
#endif /* _OS_TYPES_H */
|
@ -1,11 +0,0 @@
|
||||
Conrad Parker <conrad@metadecks.org>
|
||||
- Design, general implementation
|
||||
|
||||
Silvia Pfeiffer <Silvia.Pfeiffer@CSIRO.AU>
|
||||
- Design, MS Windows porting
|
||||
|
||||
Andre Pang <ozone@algorithm.com.au>
|
||||
- Design, Mac OS X porting
|
||||
|
||||
Zentaro Kavanagh <zen@illiminable.com>
|
||||
- MS Windows Porting and packaging. Windows specific bugfixes.
|
@ -1,29 +0,0 @@
|
||||
Copyright (C) 2003 CSIRO Australia
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions
|
||||
are met:
|
||||
|
||||
- Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
|
||||
- Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
|
||||
- Neither the name of the CSIRO nor the names of its
|
||||
contributors may be used to endorse or promote products derived from
|
||||
this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
|
||||
PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE ORGANISATION OR
|
||||
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
@ -1,17 +0,0 @@
|
||||
Fri May 21 16:48:34 EST 2004 Conrad Parker <conrad@annodex.net>
|
||||
|
||||
* Version 0.8.3
|
||||
* fixes for win32 build procedure
|
||||
* improved API documentation for seeking, OGGZ_AUTO and OggzIO
|
||||
|
||||
Thu Mar 11 11:00:00 EST 2004 Silvia Pfeiffer <silvia.pfeiffer@csiro.au>
|
||||
* Version 0.8.2
|
||||
* fixed up the Makefiles to not include the CVS subdirectories
|
||||
|
||||
Sun Mar 07 16:00:00 EST 2004 Silvia Pfeiffer <silvia.pfeiffer@csiro.au>
|
||||
* Version 0.8.1
|
||||
* includes Windows port with Makefile & VC6 workspace & .NET solution
|
||||
|
||||
Thu Oct 16 21:55:07 EST 2003 Conrad Parker <conrad@annodex.net>
|
||||
|
||||
* split liboggz out from libannodex sources, started ChangeLog
|
@ -1,14 +0,0 @@
|
||||
SubDir HAIKU_TOP src add-ons media plugins ogg liboggz ;
|
||||
|
||||
SubDirHdrs [ FDirName $(SUBDIR) .. libogg ] ;
|
||||
SubDirCcFlags -Wno-missing-prototypes ;
|
||||
|
||||
StaticLibrary liboggz.a :
|
||||
oggz.c
|
||||
oggz_auto.c
|
||||
oggz_io.c
|
||||
oggz_read.c
|
||||
oggz_table.c
|
||||
oggz_vector.c
|
||||
oggz_write.c
|
||||
;
|
@ -1,97 +0,0 @@
|
||||
/* config.h. Generated by configure. */
|
||||
/* config.h.in. Generated from configure.ac by autoheader. */
|
||||
|
||||
/* Define to 1 if you have the <dlfcn.h> header file. */
|
||||
/* #undef HAVE_DLFCN_H */
|
||||
|
||||
/* Define to 1 if you have the <fcntl.h> header file. */
|
||||
#define HAVE_FCNTL_H 1
|
||||
|
||||
/* Define to 1 if you have the 'getopt_long' function */
|
||||
#define HAVE_GETOPT_LONG
|
||||
|
||||
/* Define to 1 if you have the <inttypes.h> header file. */
|
||||
#define HAVE_INTTYPES_H 1
|
||||
|
||||
/* Define to 1 if you have the `memmove' function. */
|
||||
#define HAVE_MEMMOVE 1
|
||||
|
||||
/* Define to 1 if you have the <memory.h> header file. */
|
||||
#define HAVE_MEMORY_H 1
|
||||
|
||||
/* Define to 1 if you have the `random' function. */
|
||||
#define HAVE_RANDOM 1
|
||||
|
||||
/* Define to 1 if your system has a GNU libc compatible `realloc' function,
|
||||
and to 0 otherwise. */
|
||||
#define HAVE_REALLOC 1
|
||||
|
||||
/* Define to 1 if you have the <stdint.h> header file. */
|
||||
#define HAVE_STDINT_H 1
|
||||
|
||||
/* Define to 1 if you have the <stdlib.h> header file. */
|
||||
#define HAVE_STDLIB_H 1
|
||||
|
||||
/* Define to 1 if you have the <strings.h> header file. */
|
||||
#define HAVE_STRINGS_H 1
|
||||
|
||||
/* Define to 1 if you have the <string.h> header file. */
|
||||
#define HAVE_STRING_H 1
|
||||
|
||||
/* Define to 1 if you have the <sys/stat.h> header file. */
|
||||
#define HAVE_SYS_STAT_H 1
|
||||
|
||||
/* Define to 1 if you have the <sys/types.h> header file. */
|
||||
#define HAVE_SYS_TYPES_H 1
|
||||
|
||||
/* Define to 1 if you have the <unistd.h> header file. */
|
||||
#define HAVE_UNISTD_H 1
|
||||
|
||||
/* Define to build experimental code */
|
||||
/* #undef OGGZ_CONFIG_EXPERIMENTAL */
|
||||
|
||||
/* Do not build reading support */
|
||||
#define OGGZ_CONFIG_READ 1
|
||||
|
||||
/* Do not build writing support */
|
||||
#define OGGZ_CONFIG_WRITE 1
|
||||
|
||||
/* Name of package */
|
||||
#define PACKAGE "liboggz"
|
||||
|
||||
/* Define to the address where bug reports for this package should be sent. */
|
||||
#define PACKAGE_BUGREPORT ""
|
||||
|
||||
/* Define to the full name of this package. */
|
||||
#define PACKAGE_NAME ""
|
||||
|
||||
/* Define to the full name and version of this package. */
|
||||
#define PACKAGE_STRING ""
|
||||
|
||||
/* Define to the one symbol short name of this package. */
|
||||
#define PACKAGE_TARNAME ""
|
||||
|
||||
/* Define to the version of this package. */
|
||||
#define PACKAGE_VERSION ""
|
||||
|
||||
/* Define to 1 if you have the ANSI C header files. */
|
||||
#define STDC_HEADERS 1
|
||||
|
||||
/* Version number of package */
|
||||
#define VERSION "0.8.3"
|
||||
|
||||
/* Define to 1 if your processor stores words with the most significant byte
|
||||
first (like Motorola and SPARC, unlike Intel and VAX). */
|
||||
/* #undef WORDS_BIGENDIAN */
|
||||
|
||||
/* Define to empty if `const' does not conform to ANSI C. */
|
||||
/* #undef const */
|
||||
|
||||
/* Define to `long' if <sys/types.h> does not define. */
|
||||
/* #undef off_t */
|
||||
|
||||
/* Define to rpl_realloc if the replacement function should be used. */
|
||||
/* #undef realloc */
|
||||
|
||||
/* Define to `unsigned' if <sys/types.h> does not define. */
|
||||
/* #undef size_t */
|
@ -1,502 +0,0 @@
|
||||
/*
|
||||
Copyright (C) 2003 Commonwealth Scientific and Industrial Research
|
||||
Organisation (CSIRO) Australia
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions
|
||||
are met:
|
||||
|
||||
- Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
|
||||
- Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
|
||||
- Neither the name of CSIRO Australia nor the names of its
|
||||
contributors may be used to endorse or promote products derived from
|
||||
this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
|
||||
PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE ORGANISATION OR
|
||||
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <assert.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
|
||||
#ifdef HAVE_UNISTD_H
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
|
||||
#include <fcntl.h>
|
||||
#include <errno.h>
|
||||
#include <string.h>
|
||||
#include <time.h>
|
||||
|
||||
#include <ogg/ogg.h>
|
||||
|
||||
#include "oggz_compat.h"
|
||||
#include "oggz_private.h"
|
||||
#include "oggz_vector.h"
|
||||
|
||||
/*#define DEBUG*/
|
||||
|
||||
static int
|
||||
oggz_flags_disabled (int flags)
|
||||
{
|
||||
if (flags & OGGZ_WRITE) {
|
||||
if (!OGGZ_CONFIG_WRITE) return OGGZ_ERR_DISABLED;
|
||||
} else {
|
||||
if (!OGGZ_CONFIG_READ) return OGGZ_ERR_DISABLED;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
OGGZ *
|
||||
oggz_new (int flags)
|
||||
{
|
||||
OGGZ * oggz;
|
||||
|
||||
if (oggz_flags_disabled (flags)) return NULL;
|
||||
|
||||
oggz = (OGGZ *) oggz_malloc (sizeof (OGGZ));
|
||||
if (oggz == NULL) return NULL;
|
||||
|
||||
oggz->flags = flags;
|
||||
oggz->file = NULL;
|
||||
oggz->io = NULL;
|
||||
|
||||
oggz->offset = 0;
|
||||
oggz->offset_data_begin = 0;
|
||||
|
||||
oggz->streams = oggz_vector_new ();
|
||||
oggz->all_at_eos = 0;
|
||||
|
||||
oggz->metric = NULL;
|
||||
oggz->metric_user_data = NULL;
|
||||
oggz->metric_internal = 0;
|
||||
|
||||
oggz->order = NULL;
|
||||
oggz->order_user_data = NULL;
|
||||
|
||||
if (OGGZ_CONFIG_WRITE && (oggz->flags & OGGZ_WRITE)) {
|
||||
oggz_write_init (oggz);
|
||||
} else if (OGGZ_CONFIG_READ) {
|
||||
oggz_read_init (oggz);
|
||||
}
|
||||
|
||||
return oggz;
|
||||
}
|
||||
|
||||
OGGZ *
|
||||
oggz_open (char * filename, int flags)
|
||||
{
|
||||
OGGZ * oggz = NULL;
|
||||
FILE * file = NULL;
|
||||
|
||||
if (oggz_flags_disabled (flags)) return NULL;
|
||||
|
||||
if (flags & OGGZ_WRITE) {
|
||||
file = fopen (filename, "wb");
|
||||
} else {
|
||||
file = fopen (filename, "rb");
|
||||
}
|
||||
if (file == NULL) return NULL;
|
||||
|
||||
oggz = oggz_new (flags);
|
||||
oggz->file = file;
|
||||
|
||||
return oggz;
|
||||
}
|
||||
|
||||
OGGZ *
|
||||
oggz_open_stdio (FILE * file, int flags)
|
||||
{
|
||||
OGGZ * oggz = NULL;
|
||||
|
||||
if (oggz_flags_disabled (flags)) return NULL;
|
||||
|
||||
oggz = oggz_new (flags);
|
||||
oggz->file = file;
|
||||
|
||||
return oggz;
|
||||
}
|
||||
|
||||
int
|
||||
oggz_flush (OGGZ * oggz)
|
||||
{
|
||||
if (oggz == NULL) return OGGZ_ERR_BAD_OGGZ;
|
||||
|
||||
return oggz_io_flush (oggz);
|
||||
}
|
||||
|
||||
static int
|
||||
oggz_stream_clear (void * data)
|
||||
{
|
||||
oggz_stream_t * stream = (oggz_stream_t *) data;
|
||||
|
||||
if (stream->ogg_stream.serialno != -1)
|
||||
ogg_stream_clear (&stream->ogg_stream);
|
||||
|
||||
if (stream->metric_internal)
|
||||
oggz_free (stream->metric_user_data);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
oggz_close (OGGZ * oggz)
|
||||
{
|
||||
if (oggz == NULL) return OGGZ_ERR_BAD_OGGZ;
|
||||
|
||||
oggz_vector_foreach (oggz->streams, oggz_stream_clear);
|
||||
oggz_vector_delete (oggz->streams);
|
||||
|
||||
if (OGGZ_CONFIG_WRITE && (oggz->flags & OGGZ_WRITE)) {
|
||||
oggz_write_close (oggz);
|
||||
} else if (OGGZ_CONFIG_READ) {
|
||||
oggz_read_close (oggz);
|
||||
}
|
||||
|
||||
if (oggz->file != NULL) {
|
||||
if (fclose (oggz->file) == EOF) {
|
||||
return OGGZ_ERR_SYSTEM;
|
||||
}
|
||||
}
|
||||
|
||||
oggz_free (oggz);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
off_t
|
||||
oggz_tell (OGGZ * oggz)
|
||||
{
|
||||
if (oggz == NULL) return OGGZ_ERR_BAD_OGGZ;
|
||||
|
||||
return oggz->offset;
|
||||
}
|
||||
|
||||
ogg_int64_t
|
||||
oggz_tell_units (OGGZ * oggz)
|
||||
{
|
||||
OggzReader * reader;
|
||||
|
||||
if (oggz == NULL) return OGGZ_ERR_BAD_OGGZ;
|
||||
|
||||
if (oggz->flags & OGGZ_WRITE) {
|
||||
return OGGZ_ERR_INVALID;
|
||||
}
|
||||
|
||||
reader = &oggz->x.reader;
|
||||
|
||||
if (OGGZ_CONFIG_READ) {
|
||||
return reader->current_unit;
|
||||
} else {
|
||||
return OGGZ_ERR_DISABLED;
|
||||
}
|
||||
}
|
||||
|
||||
/******** oggz_stream management ********/
|
||||
|
||||
static int
|
||||
oggz_find_stream (void * data, long serialno)
|
||||
{
|
||||
oggz_stream_t * stream = (oggz_stream_t *) data;
|
||||
|
||||
return (stream->ogg_stream.serialno == serialno);
|
||||
}
|
||||
|
||||
oggz_stream_t *
|
||||
oggz_get_stream (OGGZ * oggz, long serialno)
|
||||
{
|
||||
if (serialno < 0) return NULL;
|
||||
|
||||
return oggz_vector_find (oggz->streams, oggz_find_stream, serialno);
|
||||
}
|
||||
|
||||
oggz_stream_t *
|
||||
oggz_add_stream (OGGZ * oggz, long serialno)
|
||||
{
|
||||
oggz_stream_t * stream;
|
||||
|
||||
stream = oggz_malloc (sizeof (oggz_stream_t));
|
||||
if (stream == NULL) return NULL;
|
||||
|
||||
ogg_stream_init (&stream->ogg_stream, (int)serialno);
|
||||
|
||||
stream->delivered_non_b_o_s = 0;
|
||||
stream->b_o_s = 1;
|
||||
stream->e_o_s = 0;
|
||||
stream->granulepos = 0;
|
||||
stream->packetno = -1; /* will be incremented on first write */
|
||||
|
||||
stream->metric = NULL;
|
||||
stream->metric_user_data = NULL;
|
||||
stream->metric_internal = 0;
|
||||
stream->order = NULL;
|
||||
stream->order_user_data = NULL;
|
||||
stream->read_packet = NULL;
|
||||
stream->read_user_data = NULL;
|
||||
|
||||
oggz_vector_insert_p (oggz->streams, stream);
|
||||
|
||||
return stream;
|
||||
}
|
||||
|
||||
int
|
||||
oggz_get_bos (OGGZ * oggz, long serialno)
|
||||
{
|
||||
oggz_stream_t * stream;
|
||||
int i, size;
|
||||
|
||||
if (oggz == NULL) return OGGZ_ERR_BAD_OGGZ;
|
||||
|
||||
if (serialno == -1) {
|
||||
size = oggz_vector_size (oggz->streams);
|
||||
for (i = 0; i < size; i++) {
|
||||
stream = (oggz_stream_t *)oggz_vector_nth_p (oggz->streams, i);
|
||||
#if 1
|
||||
/* If this stream has delivered a non bos packet, return FALSE */
|
||||
if (stream->delivered_non_b_o_s) return 0;
|
||||
#else
|
||||
/* If this stream has delivered its bos packet, return FALSE */
|
||||
if (!stream->b_o_s) return 0;
|
||||
#endif
|
||||
}
|
||||
return 1;
|
||||
} else {
|
||||
stream = oggz_get_stream (oggz, serialno);
|
||||
if (stream == NULL)
|
||||
return OGGZ_ERR_BAD_SERIALNO;
|
||||
|
||||
return stream->b_o_s;
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
oggz_get_eos (OGGZ * oggz, long serialno)
|
||||
{
|
||||
oggz_stream_t * stream;
|
||||
int i, size;
|
||||
|
||||
if (oggz == NULL) return OGGZ_ERR_BAD_OGGZ;
|
||||
|
||||
if (serialno == -1) {
|
||||
size = oggz_vector_size (oggz->streams);
|
||||
for (i = 0; i < size; i++) {
|
||||
stream = (oggz_stream_t *)oggz_vector_nth_p (oggz->streams, i);
|
||||
if (!stream->e_o_s) return 0;
|
||||
}
|
||||
return 1;
|
||||
} else {
|
||||
stream = oggz_get_stream (oggz, serialno);
|
||||
if (stream == NULL)
|
||||
return OGGZ_ERR_BAD_SERIALNO;
|
||||
|
||||
return stream->e_o_s;
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
oggz_set_eos (OGGZ * oggz, long serialno)
|
||||
{
|
||||
oggz_stream_t * stream;
|
||||
int i, size;
|
||||
|
||||
if (oggz == NULL) return OGGZ_ERR_BAD_OGGZ;
|
||||
|
||||
if (serialno == -1) {
|
||||
size = oggz_vector_size (oggz->streams);
|
||||
for (i = 0; i < size; i++) {
|
||||
stream = (oggz_stream_t *) oggz_vector_nth_p (oggz->streams, i);
|
||||
stream->e_o_s = 1;
|
||||
}
|
||||
oggz->all_at_eos = 1;
|
||||
} else {
|
||||
stream = oggz_get_stream (oggz, serialno);
|
||||
if (stream == NULL)
|
||||
return OGGZ_ERR_BAD_SERIALNO;
|
||||
|
||||
stream->e_o_s = 1;
|
||||
|
||||
if (oggz_get_eos (oggz, -1))
|
||||
oggz->all_at_eos = 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
long
|
||||
oggz_serialno_new (OGGZ * oggz)
|
||||
{
|
||||
long serialno;
|
||||
|
||||
do {
|
||||
serialno = oggz_random();
|
||||
} while (oggz_get_stream (oggz, serialno) != NULL);
|
||||
|
||||
return serialno;
|
||||
}
|
||||
|
||||
/******** OggzMetric management ********/
|
||||
|
||||
typedef struct {
|
||||
ogg_int64_t gr_n;
|
||||
ogg_int64_t gr_d;
|
||||
} oggz_metric_linear_t;
|
||||
|
||||
static ogg_int64_t
|
||||
oggz_metric_default_linear (OGGZ * oggz, long serialno, ogg_int64_t granulepos,
|
||||
void * user_data)
|
||||
{
|
||||
oggz_metric_linear_t * ldata = (oggz_metric_linear_t *)user_data;
|
||||
|
||||
return (ldata->gr_d * granulepos / ldata->gr_n);
|
||||
}
|
||||
|
||||
int
|
||||
oggz_set_metric_internal (OGGZ * oggz, long serialno,
|
||||
OggzMetric metric, void * user_data, int internal)
|
||||
{
|
||||
oggz_stream_t * stream;
|
||||
|
||||
if (oggz == NULL) return OGGZ_ERR_BAD_OGGZ;
|
||||
|
||||
if (serialno == -1) {
|
||||
if (oggz->metric_internal)
|
||||
oggz_free (oggz->metric_user_data);
|
||||
oggz->metric = metric;
|
||||
oggz->metric_user_data = user_data;
|
||||
oggz->metric_internal = internal;
|
||||
} else {
|
||||
stream = oggz_get_stream (oggz, serialno);
|
||||
if (stream == NULL) return OGGZ_ERR_BAD_SERIALNO;
|
||||
|
||||
if (stream->metric_internal)
|
||||
oggz_free (stream->metric_user_data);
|
||||
stream->metric = metric;
|
||||
stream->metric_user_data = user_data;
|
||||
stream->metric_internal = internal;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
oggz_set_metric (OGGZ * oggz, long serialno,
|
||||
OggzMetric metric, void * user_data)
|
||||
{
|
||||
return oggz_set_metric_internal (oggz, serialno, metric, user_data, 0);
|
||||
}
|
||||
|
||||
int
|
||||
oggz_set_metric_linear (OGGZ * oggz, long serialno,
|
||||
ogg_int64_t granule_rate_numerator,
|
||||
ogg_int64_t granule_rate_denominator)
|
||||
{
|
||||
oggz_metric_linear_t * linear_data;
|
||||
|
||||
/* we divide by the granulerate, ie. mult by gr_d/gr_n, so ensure
|
||||
* numerator is non-zero */
|
||||
if (granule_rate_numerator == 0) {
|
||||
granule_rate_numerator = 1;
|
||||
granule_rate_denominator = 0;
|
||||
}
|
||||
|
||||
linear_data = oggz_malloc (sizeof (oggz_metric_linear_t));
|
||||
linear_data->gr_n = granule_rate_numerator;
|
||||
linear_data->gr_d = granule_rate_denominator;
|
||||
|
||||
return oggz_set_metric_internal (oggz, serialno, oggz_metric_default_linear,
|
||||
linear_data, 1);
|
||||
}
|
||||
|
||||
/*
|
||||
* Check if an oggz has metrics for all streams
|
||||
*/
|
||||
int
|
||||
oggz_has_metrics (OGGZ * oggz)
|
||||
{
|
||||
int i, size;
|
||||
oggz_stream_t * stream;
|
||||
|
||||
if (oggz->metric != NULL) return 1;
|
||||
|
||||
size = oggz_vector_size (oggz->streams);
|
||||
for (i = 0; i < size; i++) {
|
||||
stream = (oggz_stream_t *)oggz_vector_nth_p (oggz->streams, i);
|
||||
if (stream->metric == NULL) return 0;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
ogg_int64_t
|
||||
oggz_get_unit (OGGZ * oggz, long serialno, ogg_int64_t granulepos)
|
||||
{
|
||||
oggz_stream_t * stream;
|
||||
|
||||
if (oggz == NULL) return OGGZ_ERR_BAD_OGGZ;
|
||||
|
||||
if (granulepos == -1) return -1;
|
||||
|
||||
if (serialno == -1) {
|
||||
if (oggz->metric)
|
||||
return oggz->metric (oggz, serialno, granulepos,
|
||||
oggz->metric_user_data);
|
||||
} else {
|
||||
stream = oggz_get_stream (oggz, serialno);
|
||||
if (!stream) return -1;
|
||||
|
||||
if (stream->metric) {
|
||||
return stream->metric (oggz, serialno, granulepos,
|
||||
stream->metric_user_data);
|
||||
} else if (oggz->metric) {
|
||||
return oggz->metric (oggz, serialno, granulepos,
|
||||
oggz->metric_user_data);
|
||||
}
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
int
|
||||
oggz_set_order (OGGZ * oggz, long serialno,
|
||||
OggzOrder order, void * user_data)
|
||||
{
|
||||
oggz_stream_t * stream;
|
||||
|
||||
if (oggz == NULL) return OGGZ_ERR_BAD_OGGZ;
|
||||
|
||||
if (oggz->flags & OGGZ_WRITE) {
|
||||
return OGGZ_ERR_INVALID;
|
||||
}
|
||||
|
||||
if (serialno == -1) {
|
||||
oggz->order = order;
|
||||
oggz->order_user_data = user_data;
|
||||
} else {
|
||||
stream = oggz_get_stream (oggz, serialno);
|
||||
stream->order = order;
|
||||
stream->order_user_data = user_data;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -1,161 +0,0 @@
|
||||
/*
|
||||
Copyright (C) 2003 Commonwealth Scientific and Industrial Research
|
||||
Organisation (CSIRO) Australia
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions
|
||||
are met:
|
||||
|
||||
- Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
|
||||
- Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
|
||||
- Neither the name of CSIRO Australia nor the names of its
|
||||
contributors may be used to endorse or promote products derived from
|
||||
this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
|
||||
PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE ORGANISATION OR
|
||||
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef __OGGZ_CONSTANTS_H__
|
||||
#define __OGGZ_CONSTANTS_H__
|
||||
|
||||
/** \file
|
||||
* General constants used by liboggz.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Flags to oggz_new(), oggz_open(), and oggz_openfd().
|
||||
* Can be or'ed together in the following combinations:
|
||||
* - OGGZ_READ | OGGZ_AUTO
|
||||
* - OGGZ_WRITE | OGGZ_NONSTRICT
|
||||
*/
|
||||
enum OggzFlags {
|
||||
/** Read only */
|
||||
OGGZ_READ = 0x00,
|
||||
|
||||
/** Write only */
|
||||
OGGZ_WRITE = 0x01,
|
||||
|
||||
/** Disable strict adherence to mapping constraints, eg for
|
||||
* handling an incomplete stream */
|
||||
OGGZ_NONSTRICT = 0x10,
|
||||
|
||||
/**
|
||||
* Scan for known headers while reading, and automatically set
|
||||
* metrics appropriately. Opening a file for reading with
|
||||
* \a flags = OGGZ_READ | OGGZ_AUTO will allow seeking on Speex,
|
||||
* Vorbis, Theora and all Annodex streams in units of milliseconds,
|
||||
* once all bos pages have been delivered. */
|
||||
OGGZ_AUTO = 0x20
|
||||
};
|
||||
|
||||
enum OggzStatus {
|
||||
OGGZ_STATUS_INITIALIZED = 0,
|
||||
OGGZ_STATUS_INTERNAL_ERROR = 1,
|
||||
|
||||
OGGZ_STATUS_READ_ACTIVE = 10,
|
||||
OGGZ_STATUS_READ_STOP_OK = 11,
|
||||
OGGZ_STATUS_READ_STOP_ERR = 12,
|
||||
OGGZ_STATUS_READ_EOF = 13
|
||||
};
|
||||
|
||||
enum OggzStopCtl {
|
||||
/** Continue calling read callbacks */
|
||||
OGGZ_CONTINUE = 0,
|
||||
|
||||
/** Stop calling callbacks, but retain buffered packet data */
|
||||
OGGZ_STOP_OK = 1,
|
||||
|
||||
/** Stop calling callbacks, and purge buffered packet data */
|
||||
OGGZ_STOP_ERR = -1
|
||||
};
|
||||
|
||||
/**
|
||||
* Flush options for oggz_write_feed; can be or'ed together
|
||||
*/
|
||||
enum OggzFlushOpts {
|
||||
/** Flush all streams before beginning this packet */
|
||||
OGGZ_FLUSH_BEFORE = 0x01,
|
||||
|
||||
/** Flush after this packet */
|
||||
OGGZ_FLUSH_AFTER = 0x02
|
||||
};
|
||||
|
||||
/**
|
||||
* Definitions of error return values
|
||||
*/
|
||||
enum OggzError {
|
||||
/** No error */
|
||||
OGGZ_ERR_OK = 0,
|
||||
|
||||
/** generic error */
|
||||
OGGZ_ERR_GENERIC = -1,
|
||||
|
||||
/** oggz is not a valid OGGZ */
|
||||
OGGZ_ERR_BAD_OGGZ = -2,
|
||||
|
||||
/** The requested operation is not suitable for this OGGZ */
|
||||
OGGZ_ERR_INVALID = -3,
|
||||
|
||||
/** oggz contains no logical bitstreams */
|
||||
OGGZ_ERR_NO_STREAMS = -4,
|
||||
|
||||
/** Operation is inappropriate for oggz in current bos state */
|
||||
OGGZ_ERR_BOS = -5,
|
||||
|
||||
/** Operation is inappropriate for oggz in current eos state */
|
||||
OGGZ_ERR_EOS = -6,
|
||||
|
||||
/** Operation requires a valid metric, but none has been set */
|
||||
OGGZ_ERR_BAD_METRIC = -7,
|
||||
|
||||
/** System specific error; check errno for details */
|
||||
OGGZ_ERR_SYSTEM = -10,
|
||||
|
||||
/** Functionality disabled at build time */
|
||||
OGGZ_ERR_DISABLED = -11,
|
||||
|
||||
/** Seeking operation is not possible for this OGGZ */
|
||||
OGGZ_ERR_NOSEEK = -13,
|
||||
|
||||
/** The requested serialno does not exist in this OGGZ */
|
||||
OGGZ_ERR_BAD_SERIALNO = -20,
|
||||
|
||||
/** Packet disallowed due to invalid byte length */
|
||||
OGGZ_ERR_BAD_BYTES = -21,
|
||||
|
||||
/** Packet disallowed due to invalid b_o_s (beginning of stream) flag */
|
||||
OGGZ_ERR_BAD_B_O_S = -22,
|
||||
|
||||
/** Packet disallowed due to invalid e_o_s (end of stream) flag */
|
||||
OGGZ_ERR_BAD_E_O_S = -23,
|
||||
|
||||
/** Packet disallowed due to invalid granulepos */
|
||||
OGGZ_ERR_BAD_GRANULEPOS = -24,
|
||||
|
||||
/** Packet disallowed due to invalid packetno */
|
||||
OGGZ_ERR_BAD_PACKETNO = -25,
|
||||
|
||||
/** Guard provided by user has non-zero value */
|
||||
OGGZ_ERR_BAD_GUARD = -210,
|
||||
|
||||
/** Attempt to call oggz_write() or oggz_write_output() from within
|
||||
* a hungry() callback */
|
||||
OGGZ_ERR_RECURSIVE_WRITE = -266
|
||||
};
|
||||
|
||||
#endif /* __OGGZ_CONSTANTS_H__ */
|
@ -1,231 +0,0 @@
|
||||
/*
|
||||
Copyright (C) 2003 Commonwealth Scientific and Industrial Research
|
||||
Organisation (CSIRO) Australia
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions
|
||||
are met:
|
||||
|
||||
- Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
|
||||
- Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
|
||||
- Neither the name of CSIRO Australia nor the names of its
|
||||
contributors may be used to endorse or promote products derived from
|
||||
this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
|
||||
PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE ORGANISATION OR
|
||||
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef __OGGZ_IO_H__
|
||||
#define __OGGZ_IO_H__
|
||||
|
||||
/** \file
|
||||
* Overriding the functions used for input and output of raw data.
|
||||
*
|
||||
* OggzIO provides a way of overriding the functions Oggz uses to access
|
||||
* its raw input or output data. This is required in many situations where
|
||||
* the raw stream cannot be accessed via stdio, but can be accessed by
|
||||
* other means. This is typically useful within media frameworks, where
|
||||
* accessing and moving around in the data is possible only using methods
|
||||
* provided by the framework.
|
||||
*
|
||||
* The functions you provide for overriding IO will be used by Oggz
|
||||
* whenever you call oggz_read() or oggz_write(). They will also be
|
||||
* used repeatedly by Oggz when you call oggz_seek().
|
||||
*
|
||||
* \note Opening a file with oggz_open() or oggz_open_stdio() is equivalent
|
||||
* to calling oggz_new() and setting stdio based functions for data IO.
|
||||
*/
|
||||
|
||||
/**
|
||||
* This is the signature of a function which you provide for Oggz
|
||||
* to call when it needs to acquire raw input data.
|
||||
*
|
||||
* \param user_handle A generic pointer you have provided earlier
|
||||
* \param n The length in bytes that Oggz wants to read
|
||||
* \param buf The buffer that you read data into
|
||||
* \retval "> 0" The number of bytes successfully read into the buffer
|
||||
* \retval 0 to indicate that there is no more data to read (End of file)
|
||||
* \retval "< 0" An error condition
|
||||
*/
|
||||
typedef size_t (*OggzIORead) (void * user_handle, void * buf, size_t n);
|
||||
|
||||
/**
|
||||
* This is the signature of a function which you provide for Oggz
|
||||
* to call when it needs to output raw data.
|
||||
*
|
||||
* \param user_handle A generic pointer you have provided earlier
|
||||
* \param n The length in bytes of the data
|
||||
* \param buf A buffer containing data to write
|
||||
* \retval ">= 0" The number of bytes successfully written (may be less than
|
||||
* \a n if a write error has occurred)
|
||||
* \retval "< 0" An error condition
|
||||
*/
|
||||
typedef size_t (*OggzIOWrite) (void * user_handle, void * buf, size_t n);
|
||||
|
||||
/**
|
||||
* This is the signature of a function which you provide for Oggz
|
||||
* to call when it needs to seek on the raw input or output data.
|
||||
*
|
||||
* \param user_handle A generic pointer you have provided earlier
|
||||
* \param offset The offset in bytes to seek to
|
||||
* \param whence SEEK_SET, SEEK_CUR or SEEK_END (as for stdio.h)
|
||||
* \retval ">= 0" The offset seeked to
|
||||
* \retval "< 0" An error condition
|
||||
*
|
||||
* \note If you provide an OggzIOSeek function, you MUST also provide
|
||||
* an OggzIOTell function, or else all your seeks will fail.
|
||||
*/
|
||||
typedef int (*OggzIOSeek) (void * user_handle, long offset, int whence);
|
||||
|
||||
/**
|
||||
* This is the signature of a function which you provide for Oggz
|
||||
* to call when it needs to determine the current offset of the raw
|
||||
* input or output data.
|
||||
*
|
||||
* \param user_handle A generic pointer you have provided earlier
|
||||
* \retval ">= 0" The offset
|
||||
* \retval "< 0" An error condition
|
||||
*/
|
||||
typedef long (*OggzIOTell) (void * user_handle);
|
||||
|
||||
/**
|
||||
* This is the signature of a function which you provide for Oggz
|
||||
* to call when it needs to flush the output data. The behaviour
|
||||
* of this function is similar to that of fflush() in stdio.
|
||||
*
|
||||
* \param user_handle A generic pointer you have provided earlier
|
||||
* \retval 0 Success
|
||||
* \retval "< 0" An error condition
|
||||
*/
|
||||
typedef int (*OggzIOFlush) (void * user_handle);
|
||||
|
||||
|
||||
/**
|
||||
* Set a function for Oggz to call when it needs to read input data.
|
||||
*
|
||||
* \param oggz An OGGZ handle
|
||||
* \param read Your reading function
|
||||
* \param user_handle Any arbitrary data you wish to pass to the function
|
||||
* \retval 0 Success
|
||||
* \retval OGGZ_ERR_BAD_OGGZ \a oggz does not refer to an existing OGGZ
|
||||
* \retval OGGZ_ERR_INVALID Operation not suitable for this OGGZ; \a oggz not
|
||||
* open for reading.
|
||||
*/
|
||||
int oggz_io_set_read (OGGZ * oggz, OggzIORead read, void * user_handle);
|
||||
|
||||
/**
|
||||
* Retrieve the user_handle associated with the function you have provided
|
||||
* for reading input data.
|
||||
*
|
||||
* \param oggz An OGGZ handle
|
||||
* \returns the associated user_handle
|
||||
*/
|
||||
void * oggz_io_get_read_user_handle (OGGZ * oggz);
|
||||
|
||||
/**
|
||||
* Set a function for Oggz to call when it needs to write output data.
|
||||
*
|
||||
* \param oggz An OGGZ handle
|
||||
* \param write Your writing function
|
||||
* \param user_handle Any arbitrary data you wish to pass to the function
|
||||
* \retval 0 Success
|
||||
* \retval OGGZ_ERR_BAD_OGGZ \a oggz does not refer to an existing OGGZ
|
||||
* \retval OGGZ_ERR_INVALID Operation not suitable for this OGGZ; \a oggz not
|
||||
* open for writing.
|
||||
*/
|
||||
int oggz_io_set_write (OGGZ * oggz, OggzIOWrite write, void * user_handle);
|
||||
|
||||
/**
|
||||
* Retrieve the user_handle associated with the function you have provided
|
||||
* for writing output data.
|
||||
*
|
||||
* \param oggz An OGGZ handle
|
||||
* \returns the associated user_handle
|
||||
*/
|
||||
void * oggz_io_get_write_user_handle (OGGZ * oggz);
|
||||
|
||||
/**
|
||||
* Set a function for Oggz to call when it needs to seek on its raw data.
|
||||
*
|
||||
* \param oggz An OGGZ handle
|
||||
* \param seek Your seeking function
|
||||
* \param user_handle Any arbitrary data you wish to pass to the function
|
||||
* \retval 0 Success
|
||||
* \retval OGGZ_ERR_BAD_OGGZ \a oggz does not refer to an existing OGGZ
|
||||
* \retval OGGZ_ERR_INVALID Operation not suitable for this OGGZ
|
||||
*
|
||||
* \note If you provide an OggzIOSeek function, you MUST also provide
|
||||
* an OggzIOTell function, or else all your seeks will fail.
|
||||
*/
|
||||
int oggz_io_set_seek (OGGZ * oggz, OggzIOSeek seek, void * user_handle);
|
||||
|
||||
/**
|
||||
* Retrieve the user_handle associated with the function you have provided
|
||||
* for seeking on input or output data.
|
||||
*
|
||||
* \param oggz An OGGZ handle
|
||||
* \returns the associated user_handle
|
||||
*/
|
||||
void * oggz_io_get_seek_user_handle (OGGZ * oggz);
|
||||
|
||||
/**
|
||||
* Set a function for Oggz to call when it needs to determine the offset
|
||||
* within its input data (if OGGZ_READ) or output data (if OGGZ_WRITE).
|
||||
*
|
||||
* \param oggz An OGGZ handle
|
||||
* \param tell Your tell function
|
||||
* \param user_handle Any arbitrary data you wish to pass to the function
|
||||
* \retval 0 Success
|
||||
* \retval OGGZ_ERR_BAD_OGGZ \a oggz does not refer to an existing OGGZ
|
||||
* \retval OGGZ_ERR_INVALID Operation not suitable for this OGGZ
|
||||
*/
|
||||
int oggz_io_set_tell (OGGZ * oggz, OggzIOTell tell, void * user_handle);
|
||||
|
||||
/**
|
||||
* Retrieve the user_handle associated with the function you have provided
|
||||
* for determining the current offset in input or output data.
|
||||
*
|
||||
* \param oggz An OGGZ handle
|
||||
* \returns the associated user_handle
|
||||
*/
|
||||
void * oggz_io_get_tell_user_handle (OGGZ * oggz);
|
||||
|
||||
/**
|
||||
* Set a function for Oggz to call when it needs to flush its output. The
|
||||
* meaning of this is similar to that of fflush() in stdio.
|
||||
*
|
||||
* \param oggz An OGGZ handle
|
||||
* \param flush Your flushing function
|
||||
* \param user_handle Any arbitrary data you wish to pass to the function
|
||||
* \retval 0 Success
|
||||
* \retval OGGZ_ERR_BAD_OGGZ \a oggz does not refer to an existing OGGZ
|
||||
* \retval OGGZ_ERR_INVALID Operation not suitable for this OGGZ; \a oggz not
|
||||
* open for writing.
|
||||
*/
|
||||
int oggz_io_set_flush (OGGZ * oggz, OggzIOFlush flush, void * user_handle);
|
||||
|
||||
/**
|
||||
* Retrieve the user_handle associated with the function you have provided
|
||||
* for flushing output.
|
||||
*
|
||||
* \param oggz An OGGZ handle
|
||||
* \returns the associated user_handle
|
||||
*/
|
||||
void * oggz_io_get_flush_user_handle (OGGZ * oggz);
|
||||
|
||||
#endif /* __OGGZ_IO_H__ */
|
@ -1,103 +0,0 @@
|
||||
/*
|
||||
Copyright (C) 2003 Commonwealth Scientific and Industrial Research
|
||||
Organisation (CSIRO) Australia
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions
|
||||
are met:
|
||||
|
||||
- Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
|
||||
- Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
|
||||
- Neither the name of CSIRO Australia nor the names of its
|
||||
contributors may be used to endorse or promote products derived from
|
||||
this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
|
||||
PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE ORGANISATION OR
|
||||
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef __OGGZ_TABLE_H__
|
||||
#define __OGGZ_TABLE_H__
|
||||
|
||||
/** \file
|
||||
* A lookup table.
|
||||
*
|
||||
* OggzTable is provided for convenience to allow the storage of
|
||||
* serialno-specific data.
|
||||
*/
|
||||
|
||||
/**
|
||||
* A table of key-value pairs.
|
||||
*/
|
||||
typedef void OggzTable;
|
||||
|
||||
/**
|
||||
* Instantiate a new OggzTable
|
||||
* \returns A new OggzTable
|
||||
*/
|
||||
OggzTable *
|
||||
oggz_table_new (void);
|
||||
|
||||
/**
|
||||
* Delete an OggzTable
|
||||
* \param table An OggzTable
|
||||
*/
|
||||
void
|
||||
oggz_table_delete (OggzTable * table);
|
||||
|
||||
/**
|
||||
* Insert an element into a table.
|
||||
* \param table An OggzTable
|
||||
* \param key Key to access this data element
|
||||
* \param data The new element to add
|
||||
* \retval data If the element was successfully added
|
||||
* \retval NULL If adding the element failed due to a realloc() error
|
||||
*/
|
||||
void *
|
||||
oggz_table_insert (OggzTable * table, long key, void * data);
|
||||
|
||||
/**
|
||||
* Retrieve the element of an OggzTable indexed by a given key
|
||||
* \param table An OggzTable
|
||||
* \param key a key
|
||||
* \returns The element indexed by \a key
|
||||
* \retval NULL \a table is undefined, or no element is indexed by \a key
|
||||
*/
|
||||
void *
|
||||
oggz_table_lookup (OggzTable * table, long key);
|
||||
|
||||
/**
|
||||
* Query the number of elements in an OggzTable
|
||||
* \param table An OggzTable
|
||||
* \returns the number of elements in \a table
|
||||
*/
|
||||
int
|
||||
oggz_table_size (OggzTable * table);
|
||||
|
||||
/**
|
||||
* Retrieve the nth element of an OggzTable
|
||||
* \param table An OggzTable
|
||||
* \param n An index into the \a table
|
||||
* \param key Return value for key corresponding to nth data element
|
||||
* of \a table
|
||||
* \returns The nth data element of \a table
|
||||
* \retval NULL \a table is undefined, or \a n is out of range
|
||||
*/
|
||||
void *
|
||||
oggz_table_nth (OggzTable * table, int n, long * key);
|
||||
|
||||
#endif /* __OGGZ_TABLE_H__ */
|
@ -1,238 +0,0 @@
|
||||
/*
|
||||
Copyright (C) 2003 Commonwealth Scientific and Industrial Research
|
||||
Organisation (CSIRO) Australia
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions
|
||||
are met:
|
||||
|
||||
- Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
|
||||
- Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
|
||||
- Neither the name of CSIRO Australia nor the names of its
|
||||
contributors may be used to endorse or promote products derived from
|
||||
this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
|
||||
PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE ORGANISATION OR
|
||||
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
/*
|
||||
* oggz_auto.c
|
||||
*
|
||||
* Conrad Parker <conrad@annodex.net>
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#if OGGZ_CONFIG_READ
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <oggz/oggz.h>
|
||||
#include "oggz_auto.h"
|
||||
#include "oggz_byteorder.h"
|
||||
#include "oggz_macros.h"
|
||||
|
||||
#define INT32_LE_AT(x) _le_32((*(ogg_int32_t *)(x)))
|
||||
#define INT32_BE_AT(x) _be_32((*(ogg_int32_t *)(x)))
|
||||
#define INT64_LE_AT(x) _le_64((*(ogg_int64_t *)(x)))
|
||||
|
||||
/*#define DEBUG*/
|
||||
|
||||
#define OGGZ_AUTO_MULT 1000
|
||||
|
||||
static int
|
||||
auto_speex (OGGZ * oggz, ogg_packet * op, long serialno, void * user_data)
|
||||
{
|
||||
unsigned char * header = op->packet;
|
||||
ogg_int64_t granule_rate = 0;
|
||||
|
||||
if (op->bytes < 68) return 0;
|
||||
|
||||
if (strncmp ((char *)header, "Speex ", 8)) return 0;
|
||||
if (!op->b_o_s) return 0;
|
||||
|
||||
granule_rate = (ogg_int64_t) INT32_LE_AT(&header[36]);
|
||||
#ifdef DEBUG
|
||||
printf ("Got speex rate %d\n", (int)granule_rate);
|
||||
#endif
|
||||
|
||||
oggz_set_metric_linear (oggz, serialno, granule_rate, OGGZ_AUTO_MULT);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int
|
||||
auto_vorbis (OGGZ * oggz, ogg_packet * op, long serialno, void * user_data)
|
||||
{
|
||||
unsigned char * header = op->packet;
|
||||
ogg_int64_t granule_rate = 0;
|
||||
|
||||
if (op->bytes < 30) return 0;
|
||||
|
||||
if (header[0] != 0x01) return 0;
|
||||
if (strncmp ((char *)&header[1], "vorbis", 6)) return 0;
|
||||
if (!op->b_o_s) return 0;
|
||||
|
||||
granule_rate = (ogg_int64_t) INT32_LE_AT(&header[12]);
|
||||
#ifdef DEBUG
|
||||
printf ("Got vorbis rate %d\n", (int)granule_rate);
|
||||
#endif
|
||||
|
||||
oggz_set_metric_linear (oggz, serialno, granule_rate, OGGZ_AUTO_MULT);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
typedef struct {
|
||||
ogg_int32_t fps_numerator;
|
||||
ogg_int32_t fps_denominator;
|
||||
int keyframe_shift;
|
||||
} oggz_theora_metric_t;
|
||||
|
||||
static int intlog(int num) {
|
||||
int ret=0;
|
||||
while(num>0){
|
||||
num=num/2;
|
||||
ret=ret+1;
|
||||
}
|
||||
return(ret);
|
||||
}
|
||||
|
||||
static ogg_int64_t
|
||||
auto_theora_metric (OGGZ * oggz, long serialno, ogg_int64_t granulepos,
|
||||
void * user_data)
|
||||
{
|
||||
oggz_theora_metric_t * tdata = (oggz_theora_metric_t *)user_data;
|
||||
ogg_int64_t iframe, pframe;
|
||||
ogg_int64_t units;
|
||||
|
||||
iframe = granulepos >> tdata->keyframe_shift;
|
||||
pframe = granulepos - (iframe << tdata->keyframe_shift);
|
||||
granulepos = (iframe + pframe);
|
||||
|
||||
units = OGGZ_AUTO_MULT * granulepos * tdata->fps_denominator /
|
||||
tdata->fps_numerator;
|
||||
|
||||
return units;
|
||||
}
|
||||
|
||||
static int
|
||||
auto_theora (OGGZ * oggz, ogg_packet * op, long serialno, void * user_data)
|
||||
{
|
||||
unsigned char * header = op->packet;
|
||||
char keyframe_granule_shift = 0;
|
||||
oggz_theora_metric_t * tdata;
|
||||
|
||||
if (op->bytes < 41) return 0;
|
||||
|
||||
if (header[0] != 0x80) return 0;
|
||||
if (strncmp ((char *)&header[1], "theora", 6)) return 0;
|
||||
if (!op->b_o_s) return 0;
|
||||
|
||||
|
||||
tdata = oggz_malloc (sizeof (oggz_theora_metric_t));
|
||||
|
||||
tdata->fps_numerator = INT32_BE_AT(&header[22]);
|
||||
tdata->fps_denominator = INT32_BE_AT(&header[26]);
|
||||
|
||||
#if USE_THEORA_PRE_ALPHA_3_FORMAT
|
||||
/* old header format, used by Theora alpha2 and earlier */
|
||||
keyframe_granule_shift = (header[36] & 0xf8) >> 3;
|
||||
#else
|
||||
keyframe_granule_shift = (header[40] & 0x03) << 3;
|
||||
keyframe_granule_shift |= (header[41] & 0xe0) >> 5;
|
||||
#endif
|
||||
tdata->keyframe_shift = intlog (keyframe_granule_shift - 1);
|
||||
|
||||
#ifdef DEBUG
|
||||
printf ("Got theora fps %d/%d, keyframe_granule_shift %d\n",
|
||||
tdata->fps_numerator, tdata->fps_denominator,
|
||||
keyframe_granule_shift);
|
||||
#endif
|
||||
|
||||
/*oggz_set_metric_internal (oggz, serialno, auto_theora_metric, tdata, 1);*/
|
||||
oggz_set_metric (oggz, serialno, auto_theora_metric, tdata);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int
|
||||
auto_annodex (OGGZ * oggz, ogg_packet * op, long serialno, void * user_data)
|
||||
{
|
||||
unsigned char * header = op->packet;
|
||||
|
||||
if (op->bytes < 8) return 0;
|
||||
|
||||
if (strncmp ((char *)header, "Annodex", 8)) return 0;
|
||||
if (!op->b_o_s) return 0;
|
||||
|
||||
/* Yeah ... set it up with a "linear" metric with numerator 0 :) */
|
||||
oggz_set_metric_linear (oggz, serialno, 0, 1);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int
|
||||
auto_anxdata (OGGZ * oggz, ogg_packet * op, long serialno, void * user_data)
|
||||
{
|
||||
unsigned char * header = op->packet;
|
||||
ogg_int64_t granule_rate_numerator = 0, granule_rate_denominator = 0;
|
||||
|
||||
if (op->bytes < 28) return 0;
|
||||
|
||||
if (strncmp ((char *)header, "AnxData", 8)) return 0;
|
||||
if (!op->b_o_s) return 0;
|
||||
|
||||
granule_rate_numerator = INT64_LE_AT(&header[8]);
|
||||
granule_rate_denominator = INT64_LE_AT(&header[16]);
|
||||
#ifdef DEBUG
|
||||
printf ("Got AnxData rate %lld/%lld\n", granule_rate_numerator,
|
||||
granule_rate_denominator);
|
||||
#endif
|
||||
|
||||
oggz_set_metric_linear (oggz, serialno,
|
||||
granule_rate_numerator,
|
||||
OGGZ_AUTO_MULT * granule_rate_denominator);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static OggzReadPacket auto_readers[] = {
|
||||
auto_speex,
|
||||
auto_vorbis,
|
||||
auto_theora,
|
||||
auto_annodex,
|
||||
auto_anxdata,
|
||||
NULL
|
||||
};
|
||||
|
||||
int
|
||||
oggz_auto (OGGZ * oggz, ogg_packet * op, long serialno, void * user_data)
|
||||
{
|
||||
OggzReadPacket read_packet;
|
||||
int i = 0;
|
||||
|
||||
for (read_packet = auto_readers[0]; read_packet;
|
||||
read_packet = auto_readers[++i]) {
|
||||
if (read_packet (oggz, op, serialno, user_data)) return 0;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif /* OGGZ_CONFIG_READ */
|
@ -1,255 +0,0 @@
|
||||
/*
|
||||
Copyright (C) 2003 Commonwealth Scientific and Industrial Research
|
||||
Organisation (CSIRO) Australia
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions
|
||||
are met:
|
||||
|
||||
- Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
|
||||
- Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
|
||||
- Neither the name of CSIRO Australia nor the names of its
|
||||
contributors may be used to endorse or promote products derived from
|
||||
this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
|
||||
PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE ORGANISATION OR
|
||||
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
/*
|
||||
* oggz_auto.h
|
||||
*
|
||||
* Conrad Parker <conrad@annodex.net>
|
||||
*/
|
||||
|
||||
#ifndef __OGGZ_AUTO_H__
|
||||
#define __OGGZ_AUTO_H__
|
||||
|
||||
#include <ogg/os_types.h>
|
||||
|
||||
/**
|
||||
* Speex
|
||||
*
|
||||
* Default field type: LITTLE ENDIAN unsigned integer
|
||||
|
||||
0 1 2 3
|
||||
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1| Byte
|
||||
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
| speex_string: Identifier char[8]: 'Speex ' | 0-3
|
||||
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
| | 4-7
|
||||
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
| speex_version: char[20] | 8-11
|
||||
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
| | 12-15
|
||||
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
| | 16-19
|
||||
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
| | 20-23
|
||||
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
| | 24-27
|
||||
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
| speex_version_id | 28-31
|
||||
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
| header_size | 32-35
|
||||
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
| rate | 36-39
|
||||
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
| mode | 40-43
|
||||
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
| mode_bitstream_version | 44-47
|
||||
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
| nb_channels | 48-51
|
||||
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
| bitrate | 52-55
|
||||
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
| frame_size | 56-59
|
||||
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
| vbr | 60-63
|
||||
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
| frames_per_packet | 64-67
|
||||
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
| extra_headers | 68-71
|
||||
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
| reserved1 | 72-75
|
||||
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
| reserved2 | 76-79
|
||||
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
|
||||
*/
|
||||
|
||||
/**
|
||||
* Vorbis
|
||||
*
|
||||
* Default field type: LITTLE ENDIAN unsigned integer
|
||||
|
||||
0 1 2 3
|
||||
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1| Byte
|
||||
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
| packtype | Identifier char[6]: 'vorbis' | 0-3
|
||||
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
| | version | 4-7
|
||||
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
| | channels | 8-11
|
||||
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
| rate | 12-15
|
||||
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
| bitrate_upper | 16-19
|
||||
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
| bitrate_nominal | 20-23
|
||||
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
| bitrate_lower | 24-27
|
||||
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
| l2bs0 | l2bs1 |e| 28-31
|
||||
+-+-+-+-+-+-+-+-+-+
|
||||
|
||||
*/
|
||||
|
||||
/**
|
||||
* Theora
|
||||
*
|
||||
* Default field type: BIG ENDIAN unsigned integer
|
||||
*
|
||||
|
||||
Field names in full caps refer to fields described in the Theora I
|
||||
specification. Lowercase refers to theora_info struct members from
|
||||
libtheora.
|
||||
|
||||
This is the Theora header for theora-alpha3:
|
||||
|
||||
(VMAJ=3, VMIN=2, VREV=0)
|
||||
|
||||
0 1 2 3
|
||||
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1| Byte
|
||||
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
| packtype | Identifier char[6]: 'theora' | 0-3
|
||||
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
| | VMAJ | 4-7
|
||||
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
| VMIN | VREV | FMBW: width >> 4 | 8-11
|
||||
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
| FMBH: height >> 4 | PICW: frame_width | 12-15
|
||||
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
| | PICH: frame_height | 16-19
|
||||
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
| PICX: offset_x| PICY: offset_y| FRN: fps_numerator | 20-23
|
||||
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
| | FRD: fps_denominator | 24-27
|
||||
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
| | PARN: aspect_numerator | 28-31
|
||||
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
| | PARD: aspect_denominator | 32-35
|
||||
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
| CS: colorspace| NOMBR: target_bitrate | 36-39
|
||||
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
| QUAL | KFGSHIFT| PF| resv| 40-43
|
||||
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
|
||||
|
||||
This was the Theora header for theora-alpha2:
|
||||
|
||||
0 1 2 3
|
||||
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1| Byte
|
||||
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
| packtype | Identifier char[6]: 'theora' | 0-3
|
||||
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
| | Version major | 4-7
|
||||
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
| Version minor | Version sub | width >> 4 | 8-11
|
||||
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
| height >> 4 | frame_width | 12-15
|
||||
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
| | frame_height | 16-19
|
||||
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
| offset_x | offset_y | fps_numerator | 20-23
|
||||
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
| | fps_denominator | 24-27
|
||||
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
| | aspect_numerator | 28-31
|
||||
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
| | aspect_denominator | 32-35
|
||||
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
| kgshift | colorspace | target_bitrate | 36-39
|
||||
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
| | quality | 40-43
|
||||
+-+-+-+-+-+-+-+-+-+-+-+
|
||||
|
||||
*/
|
||||
|
||||
/**
|
||||
* Annodex
|
||||
*
|
||||
* Default field type: LITTLE ENDIAN unsigned integer
|
||||
|
||||
0 1 2 3
|
||||
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1| Byte
|
||||
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
| Identifier char[8]: 'Annodex\0' | 0-3
|
||||
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
| | 4-7
|
||||
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
| Version major | Version minor | 8-11
|
||||
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
| Timebase numerator | 12-15
|
||||
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
| | 16-19
|
||||
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
| Timebase denominator | 20-23
|
||||
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
| | 24-27
|
||||
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
| UTC | 28-31
|
||||
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
| | 32-35
|
||||
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
| | 36-39
|
||||
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
| | 40-43
|
||||
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
| | 44-47
|
||||
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
|
||||
*/
|
||||
|
||||
/**
|
||||
* AnxData
|
||||
*
|
||||
* Default field type: LITTLE ENDIAN unsigned integer
|
||||
|
||||
0 1 2 3
|
||||
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1| Byte
|
||||
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
| Identifier char[8]: 'AnxData\0' | 0-3
|
||||
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
| | 4-7
|
||||
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
| Granule rate numerator | 8-11
|
||||
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
| | 12-15
|
||||
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
| Granule rate denominator | 16-19
|
||||
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
| | 20-23
|
||||
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
| Number of secondary header pages | 24-27
|
||||
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
| Headers ... | 28-
|
||||
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
|
||||
*/
|
||||
|
||||
#endif /* __OGGZ_AUTO_H__ */
|
@ -1,103 +0,0 @@
|
||||
/*
|
||||
Copyright (C) 2003 Commonwealth Scientific and Industrial Research
|
||||
Organisation (CSIRO) Australia
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions
|
||||
are met:
|
||||
|
||||
- Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
|
||||
- Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
|
||||
- Neither the name of CSIRO Australia nor the names of its
|
||||
contributors may be used to endorse or promote products derived from
|
||||
this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
|
||||
PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE ORGANISATION OR
|
||||
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef __OGGZ_BYTEORDER_H__
|
||||
#define __OGGZ_BYTEORDER_H__
|
||||
|
||||
#ifdef _UNUSED_
|
||||
static unsigned short
|
||||
_le_16 (unsigned short s)
|
||||
{
|
||||
unsigned short ret=s;
|
||||
#ifdef WORDS_BIGENDIAN
|
||||
ret = (s>>8) & 0x00ffU;
|
||||
ret += (s<<8) & 0xff00U;
|
||||
#endif
|
||||
return ret;
|
||||
}
|
||||
#endif
|
||||
|
||||
static ogg_uint32_t
|
||||
_le_32 (ogg_uint32_t i)
|
||||
{
|
||||
ogg_uint32_t ret=i;
|
||||
#ifdef WORDS_BIGENDIAN
|
||||
ret = (i>>24);
|
||||
ret += (i>>8) & 0x0000ff00;
|
||||
ret += (i<<8) & 0x00ff0000;
|
||||
ret += (i<<24);
|
||||
#endif
|
||||
return ret;
|
||||
}
|
||||
|
||||
static ogg_uint32_t
|
||||
_be_32 (ogg_uint32_t i)
|
||||
{
|
||||
ogg_uint32_t ret=i;
|
||||
#ifndef WORDS_BIGENDIAN
|
||||
ret = (i>>24);
|
||||
ret += (i>>8) & 0x0000ff00;
|
||||
ret += (i<<8) & 0x00ff0000;
|
||||
ret += (i<<24);
|
||||
#endif
|
||||
return ret;
|
||||
}
|
||||
|
||||
static ogg_int64_t
|
||||
_le_64 (ogg_int64_t l)
|
||||
{
|
||||
ogg_int64_t ret=l;
|
||||
unsigned char *ucptr = (unsigned char *)&ret;
|
||||
#ifdef WORDS_BIGENDIAN
|
||||
unsigned char temp;
|
||||
|
||||
temp = ucptr [0] ;
|
||||
ucptr [0] = ucptr [7] ;
|
||||
ucptr [7] = temp ;
|
||||
|
||||
temp = ucptr [1] ;
|
||||
ucptr [1] = ucptr [6] ;
|
||||
ucptr [6] = temp ;
|
||||
|
||||
temp = ucptr [2] ;
|
||||
ucptr [2] = ucptr [5] ;
|
||||
ucptr [5] = temp ;
|
||||
|
||||
temp = ucptr [3] ;
|
||||
ucptr [3] = ucptr [4] ;
|
||||
ucptr [4] = temp ;
|
||||
|
||||
#endif
|
||||
return (*(ogg_int64_t *)ucptr);
|
||||
}
|
||||
|
||||
#endif /* __OGGZ_BYTEORDER_H__ */
|
@ -1,45 +0,0 @@
|
||||
/*
|
||||
Copyright (C) 2003 Commonwealth Scientific and Industrial Research
|
||||
Organisation (CSIRO) Australia
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions
|
||||
are met:
|
||||
|
||||
- Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
|
||||
- Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
|
||||
- Neither the name of CSIRO Australia nor the names of its
|
||||
contributors may be used to endorse or promote products derived from
|
||||
this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
|
||||
PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE ORGANISATION OR
|
||||
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#ifdef HAVE_RANDOM
|
||||
# define oggz_random random
|
||||
#else
|
||||
# define oggz_random rand
|
||||
#endif
|
||||
|
||||
#ifndef WIN32
|
||||
# define oggz_stat_regular(mode) (S_ISREG((mode)) || S_ISLNK((mode)))
|
||||
#else
|
||||
# define oggz_stat_regular(mode) ((mode) & S_IFREG)
|
||||
#endif
|
@ -1,307 +0,0 @@
|
||||
/*
|
||||
Copyright (C) 2003 Commonwealth Scientific and Industrial Research
|
||||
Organisation (CSIRO) Australia
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions
|
||||
are met:
|
||||
|
||||
- Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
|
||||
- Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
|
||||
- Neither the name of CSIRO Australia nor the names of its
|
||||
contributors may be used to endorse or promote products derived from
|
||||
this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
|
||||
PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE ORGANISATION OR
|
||||
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
/*
|
||||
* oggz_io.c
|
||||
*
|
||||
* Conrad Parker <conrad@annodex.net>
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include "oggz_compat.h"
|
||||
#include "oggz_private.h"
|
||||
|
||||
/*#define DEBUG*/
|
||||
|
||||
size_t
|
||||
oggz_io_read (OGGZ * oggz, void * buf, size_t n)
|
||||
{
|
||||
OggzIO * io;
|
||||
size_t bytes;
|
||||
|
||||
if (oggz->file != NULL) {
|
||||
if ((bytes = fread (buf, 1, n, oggz->file)) == 0) {
|
||||
if (ferror (oggz->file)) {
|
||||
return OGGZ_ERR_SYSTEM;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
else if ((io = oggz->io) != NULL) {
|
||||
if (io->read == NULL) return -1;
|
||||
bytes = io->read (io->read_user_handle, buf, n);
|
||||
}
|
||||
|
||||
else return OGGZ_ERR_INVALID;
|
||||
|
||||
return bytes;
|
||||
}
|
||||
|
||||
size_t
|
||||
oggz_io_write (OGGZ * oggz, void * buf, size_t n)
|
||||
{
|
||||
OggzIO * io;
|
||||
size_t bytes;
|
||||
|
||||
if (oggz->file != NULL) {
|
||||
bytes = fwrite (buf, 1, n, oggz->file);
|
||||
}
|
||||
|
||||
else if ((io = oggz->io) != NULL) {
|
||||
if (io->write == NULL) return -1;
|
||||
bytes = io->write (io->write_user_handle, buf, n);
|
||||
}
|
||||
|
||||
else return OGGZ_ERR_INVALID;
|
||||
|
||||
return bytes;
|
||||
}
|
||||
|
||||
int
|
||||
oggz_io_seek (OGGZ * oggz, long offset, int whence)
|
||||
{
|
||||
OggzIO * io;
|
||||
|
||||
if (oggz->file != NULL) {
|
||||
if (fseek (oggz->file, offset, whence) == -1) {
|
||||
if (errno == ESPIPE) {
|
||||
/*oggz_set_error (oggz, OGGZ_ERR_NOSEEK);*/
|
||||
} else {
|
||||
/*oggz_set_error (oggz, OGGZ_ERR_SYSTEM);*/
|
||||
}
|
||||
return OGGZ_ERR_SYSTEM;
|
||||
}
|
||||
}
|
||||
|
||||
else if ((io = oggz->io) != NULL) {
|
||||
if (io->seek == NULL) return -1;
|
||||
if (io->seek (io->seek_user_handle, offset, whence) == -1)
|
||||
return -1;
|
||||
}
|
||||
|
||||
else return OGGZ_ERR_INVALID;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
long
|
||||
oggz_io_tell (OGGZ * oggz)
|
||||
{
|
||||
OggzIO * io;
|
||||
long offset;
|
||||
|
||||
if (oggz->file != NULL) {
|
||||
if ((offset = ftell (oggz->file)) == -1) {
|
||||
if (errno == ESPIPE) {
|
||||
/*oggz_set_error (oggz, OGGZ_ERR_NOSEEK);*/
|
||||
} else {
|
||||
/*oggz_set_error (oggz, OGGZ_ERR_SYSTEM);*/
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
else if ((io = oggz->io) != NULL) {
|
||||
if (io->tell == NULL) return -1;
|
||||
if ((offset = io->tell (io->tell_user_handle)) == -1)
|
||||
return -1;
|
||||
}
|
||||
|
||||
else return OGGZ_ERR_INVALID;
|
||||
|
||||
return offset;
|
||||
}
|
||||
|
||||
int
|
||||
oggz_io_flush (OGGZ * oggz)
|
||||
{
|
||||
OggzIO * io;
|
||||
|
||||
if (oggz->file != NULL) {
|
||||
if (fflush (oggz->file) == EOF) {
|
||||
/* check errno for write-related errors */
|
||||
return OGGZ_ERR_SYSTEM;
|
||||
}
|
||||
}
|
||||
|
||||
else if ((io = oggz->io) != NULL) {
|
||||
if (io->flush == NULL) return OGGZ_ERR_INVALID;
|
||||
|
||||
if (io->flush (io->flush_user_handle) == -1) {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
else return OGGZ_ERR_INVALID;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* get/set functions */
|
||||
|
||||
static void
|
||||
oggz_io_init (OGGZ * oggz)
|
||||
{
|
||||
oggz->io = (OggzIO *) oggz_malloc (sizeof (OggzIO));
|
||||
memset (oggz->io, 0, sizeof (OggzIO));
|
||||
}
|
||||
|
||||
int
|
||||
oggz_io_set_read (OGGZ * oggz, OggzIORead read, void * user_handle)
|
||||
{
|
||||
if (oggz == NULL) return OGGZ_ERR_BAD_OGGZ;
|
||||
if (oggz->file != NULL) return OGGZ_ERR_INVALID;
|
||||
|
||||
if (oggz->io == NULL) oggz_io_init (oggz);
|
||||
|
||||
oggz->io->read = read;
|
||||
oggz->io->read_user_handle = user_handle;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void *
|
||||
oggz_io_get_read_user_handle (OGGZ * oggz)
|
||||
{
|
||||
if (oggz == NULL) return NULL;
|
||||
if (oggz->file != NULL) return NULL;
|
||||
|
||||
if (oggz->io == NULL) return NULL;
|
||||
|
||||
return oggz->io->read_user_handle;
|
||||
}
|
||||
|
||||
int
|
||||
oggz_io_set_write (OGGZ * oggz, OggzIOWrite write, void * user_handle)
|
||||
{
|
||||
if (oggz == NULL) return OGGZ_ERR_BAD_OGGZ;
|
||||
if (oggz->file != NULL) return OGGZ_ERR_INVALID;
|
||||
|
||||
if (oggz->io == NULL) oggz_io_init (oggz);
|
||||
|
||||
oggz->io->write = write;
|
||||
oggz->io->write_user_handle = user_handle;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void *
|
||||
oggz_io_get_write_user_handle (OGGZ * oggz)
|
||||
{
|
||||
if (oggz == NULL) return NULL;
|
||||
if (oggz->file != NULL) return NULL;
|
||||
|
||||
if (oggz->io == NULL) return NULL;
|
||||
|
||||
return oggz->io->write_user_handle;
|
||||
}
|
||||
|
||||
int
|
||||
oggz_io_set_seek (OGGZ * oggz, OggzIOSeek seek, void * user_handle)
|
||||
{
|
||||
if (oggz == NULL) return OGGZ_ERR_BAD_OGGZ;
|
||||
if (oggz->file != NULL) return OGGZ_ERR_INVALID;
|
||||
|
||||
if (oggz->io == NULL) oggz_io_init (oggz);
|
||||
|
||||
oggz->io->seek = seek;
|
||||
oggz->io->seek_user_handle = user_handle;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void *
|
||||
oggz_io_get_seek_user_handle (OGGZ * oggz)
|
||||
{
|
||||
if (oggz == NULL) return NULL;
|
||||
if (oggz->file != NULL) return NULL;
|
||||
|
||||
if (oggz->io == NULL) return NULL;
|
||||
|
||||
return oggz->io->seek_user_handle;
|
||||
}
|
||||
|
||||
int
|
||||
oggz_io_set_tell (OGGZ * oggz, OggzIOTell tell, void * user_handle)
|
||||
{
|
||||
if (oggz == NULL) return OGGZ_ERR_BAD_OGGZ;
|
||||
if (oggz->file != NULL) return OGGZ_ERR_INVALID;
|
||||
|
||||
if (oggz->io == NULL) oggz_io_init (oggz);
|
||||
|
||||
oggz->io->tell = tell;
|
||||
oggz->io->tell_user_handle = user_handle;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void *
|
||||
oggz_io_get_tell_user_handle (OGGZ * oggz)
|
||||
{
|
||||
if (oggz == NULL) return NULL;
|
||||
if (oggz->file != NULL) return NULL;
|
||||
|
||||
if (oggz->io == NULL) return NULL;
|
||||
|
||||
return oggz->io->tell_user_handle;
|
||||
}
|
||||
|
||||
int
|
||||
oggz_io_set_flush (OGGZ * oggz, OggzIOFlush flush, void * user_handle)
|
||||
{
|
||||
if (oggz == NULL) return OGGZ_ERR_BAD_OGGZ;
|
||||
if (oggz->file != NULL) return OGGZ_ERR_INVALID;
|
||||
|
||||
if (oggz->io == NULL) oggz_io_init (oggz);
|
||||
|
||||
oggz->io->flush = flush;
|
||||
oggz->io->flush_user_handle = user_handle;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void *
|
||||
oggz_io_get_flush_user_handle (OGGZ * oggz)
|
||||
{
|
||||
if (oggz == NULL) return NULL;
|
||||
if (oggz->file != NULL) return NULL;
|
||||
|
||||
if (oggz->io == NULL) return NULL;
|
||||
|
||||
return oggz->io->flush_user_handle;
|
||||
}
|
@ -1,48 +0,0 @@
|
||||
/*
|
||||
Copyright (C) 2003 Commonwealth Scientific and Industrial Research
|
||||
Organisation (CSIRO) Australia
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions
|
||||
are met:
|
||||
|
||||
- Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
|
||||
- Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
|
||||
- Neither the name of CSIRO Australia nor the names of its
|
||||
contributors may be used to endorse or promote products derived from
|
||||
this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
|
||||
PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE ORGANISATION OR
|
||||
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef __OGGZ_MACROS_H__
|
||||
#define __OGGZ_MACROS_H__
|
||||
|
||||
#include <ogg/ogg.h>
|
||||
|
||||
/* Use the malloc and free used by ogg; defaults are those from stdlib */
|
||||
#define oggz_malloc _ogg_malloc
|
||||
#define oggz_free _ogg_free
|
||||
|
||||
#undef MIN
|
||||
#define MIN(a,b) ((a)<(b)?(a):(b))
|
||||
|
||||
#undef MAX
|
||||
#define MAX(a,b) ((a)>(b)?(a):(b))
|
||||
|
||||
#endif /* __OGGZ_MACROS_H__ */
|
@ -1,222 +0,0 @@
|
||||
/*
|
||||
Copyright (C) 2003 Commonwealth Scientific and Industrial Research
|
||||
Organisation (CSIRO) Australia
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions
|
||||
are met:
|
||||
|
||||
- Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
|
||||
- Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
|
||||
- Neither the name of CSIRO Australia nor the names of its
|
||||
contributors may be used to endorse or promote products derived from
|
||||
this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
|
||||
PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE ORGANISATION OR
|
||||
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef __OGGZ_PRIVATE_H__
|
||||
#define __OGGZ_PRIVATE_H__
|
||||
|
||||
#include <stdio.h>
|
||||
#include <sys/types.h>
|
||||
|
||||
#include <ogg/ogg.h>
|
||||
#include <oggz/oggz_constants.h>
|
||||
|
||||
#include "oggz_macros.h"
|
||||
#include "oggz_vector.h"
|
||||
|
||||
typedef struct _OGGZ OGGZ;
|
||||
typedef struct _OggzIO OggzIO;
|
||||
typedef struct _OggzReader OggzReader;
|
||||
typedef struct _OggzWriter OggzWriter;
|
||||
|
||||
typedef int (*OggzReadPacket) (OGGZ * oggz, ogg_packet * op, long serialno,
|
||||
void * user_data);
|
||||
|
||||
typedef ogg_int64_t (*OggzMetric) (OGGZ * oggz, long serialno,
|
||||
ogg_int64_t granulepos,
|
||||
void * user_data);
|
||||
|
||||
typedef int (*OggzOrder) (OGGZ * oggz, ogg_packet * op, void * target,
|
||||
void * user_data);
|
||||
|
||||
typedef int (*OggzWriteHungry) (OGGZ * oggz, int empty, void * user_data);
|
||||
|
||||
/* oggz_io */
|
||||
typedef size_t (*OggzIORead) (void * user_handle, void * buf, size_t n);
|
||||
typedef size_t (*OggzIOWrite) (void * user_handle, void * buf, size_t n);
|
||||
typedef int (*OggzIOSeek) (void * user_handle, long offset, int whence);
|
||||
typedef long (*OggzIOTell) (void * user_handle);
|
||||
typedef int (*OggzIOFlush) (void * user_handle);
|
||||
|
||||
typedef struct {
|
||||
ogg_stream_state ogg_stream;
|
||||
|
||||
/* non b_o_s packet has been written (not just queued) */
|
||||
int delivered_non_b_o_s;
|
||||
|
||||
int b_o_s; /* beginning of stream */
|
||||
int e_o_s; /* end of stream */
|
||||
ogg_int64_t granulepos;
|
||||
ogg_int64_t packetno;
|
||||
|
||||
OggzMetric metric;
|
||||
void * metric_user_data;
|
||||
int metric_internal;
|
||||
|
||||
OggzOrder order;
|
||||
void * order_user_data;
|
||||
|
||||
OggzReadPacket read_packet;
|
||||
void * read_user_data;
|
||||
} oggz_stream_t;
|
||||
|
||||
struct _OggzReader {
|
||||
ogg_sync_state ogg_sync;
|
||||
|
||||
/* XXX: these two can prolly be removed again :) */
|
||||
ogg_stream_state ogg_stream;
|
||||
long current_serialno;
|
||||
|
||||
OggzReadPacket read_packet;
|
||||
void * read_user_data;
|
||||
|
||||
ogg_int64_t current_unit;
|
||||
|
||||
#if 0
|
||||
off_t offset_page_end; /* offset of end of current page */
|
||||
#endif
|
||||
};
|
||||
|
||||
/**
|
||||
* Bundle a packet with the stream it is being queued for; used in
|
||||
* the packet_queue vector
|
||||
*/
|
||||
typedef struct {
|
||||
ogg_packet op;
|
||||
oggz_stream_t * stream;
|
||||
int flush;
|
||||
int * guard;
|
||||
} oggz_writer_packet_t;
|
||||
|
||||
enum oggz_writer_state {
|
||||
OGGZ_MAKING_PACKETS = 0,
|
||||
OGGZ_WRITING_PAGES = 1
|
||||
};
|
||||
|
||||
struct _OggzWriter {
|
||||
oggz_writer_packet_t * next_zpacket; /* stashed in case of FLUSH_BEFORE */
|
||||
OggzVector * packet_queue;
|
||||
|
||||
OggzWriteHungry hungry;
|
||||
void * hungry_user_data;
|
||||
int hungry_only_when_empty;
|
||||
|
||||
int writing; /* already mid-write; check for recursive writes */
|
||||
int state; /* OGGZ_MAKING_PACKETS or OGGZ_WRITING_PAGES */
|
||||
|
||||
int flushing; /* whether current packet is being flushed or just paged out */
|
||||
|
||||
int eog; /* end of page */
|
||||
#if 0
|
||||
int eop; /* end of packet */
|
||||
#endif
|
||||
int eos; /* end of stream */
|
||||
|
||||
oggz_writer_packet_t * current_zpacket;
|
||||
|
||||
int packet_offset; /* n bytes already copied out of current packet */
|
||||
int page_offset; /* n bytes already copied out of current page */
|
||||
|
||||
ogg_stream_state * current_stream;
|
||||
};
|
||||
|
||||
struct _OggzIO {
|
||||
OggzIORead read;
|
||||
void * read_user_handle;
|
||||
|
||||
OggzIOWrite write;
|
||||
void * write_user_handle;
|
||||
|
||||
OggzIOSeek seek;
|
||||
void * seek_user_handle;
|
||||
|
||||
OggzIOTell tell;
|
||||
void * tell_user_handle;
|
||||
|
||||
OggzIOFlush flush;
|
||||
void * flush_user_handle;
|
||||
};
|
||||
|
||||
struct _OGGZ {
|
||||
int flags;
|
||||
FILE * file;
|
||||
OggzIO * io;
|
||||
|
||||
ogg_packet current_packet;
|
||||
ogg_page current_page;
|
||||
|
||||
off_t offset; /* offset of current page start */
|
||||
off_t offset_data_begin; /* offset of unit 0 page start */
|
||||
|
||||
OggzVector * streams;
|
||||
int all_at_eos; /* all streams are at eos */
|
||||
|
||||
OggzMetric metric;
|
||||
void * metric_user_data;
|
||||
int metric_internal;
|
||||
|
||||
OggzOrder order;
|
||||
void * order_user_data;
|
||||
|
||||
union {
|
||||
OggzReader reader;
|
||||
OggzWriter writer;
|
||||
} x;
|
||||
};
|
||||
|
||||
OGGZ * oggz_read_init (OGGZ * oggz);
|
||||
OGGZ * oggz_read_close (OGGZ * oggz);
|
||||
|
||||
OGGZ * oggz_write_init (OGGZ * oggz);
|
||||
OGGZ * oggz_write_close (OGGZ * oggz);
|
||||
|
||||
oggz_stream_t * oggz_get_stream (OGGZ * oggz, long serialno);
|
||||
oggz_stream_t * oggz_add_stream (OGGZ * oggz, long serialno);
|
||||
|
||||
int oggz_get_bos (OGGZ * oggz, long serialno);
|
||||
ogg_int64_t oggz_get_unit (OGGZ * oggz, long serialno, ogg_int64_t granulepos);
|
||||
|
||||
int oggz_set_metric_internal (OGGZ * oggz, long serialno, OggzMetric metric,
|
||||
void * user_data, int internal);
|
||||
int oggz_has_metrics (OGGZ * oggz);
|
||||
|
||||
int oggz_purge (OGGZ * oggz);
|
||||
|
||||
int oggz_auto (OGGZ * oggz, ogg_packet * op, long serialno, void * user_data);
|
||||
|
||||
/* oggz_io */
|
||||
size_t oggz_io_read (OGGZ * oggz, void * buf, size_t n);
|
||||
size_t oggz_io_write (OGGZ * oggz, void * buf, size_t n);
|
||||
int oggz_io_seek (OGGZ * oggz, long offset, int whence);
|
||||
long oggz_io_tell (OGGZ * oggz);
|
||||
int oggz_io_flush (OGGZ * oggz);
|
||||
|
||||
#endif /* __OGGZ_PRIVATE_H__ */
|
File diff suppressed because it is too large
Load Diff
@ -1,122 +0,0 @@
|
||||
/*
|
||||
Copyright (C) 2003 Commonwealth Scientific and Industrial Research
|
||||
Organisation (CSIRO) Australia
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions
|
||||
are met:
|
||||
|
||||
- Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
|
||||
- Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
|
||||
- Neither the name of CSIRO Australia nor the names of its
|
||||
contributors may be used to endorse or promote products derived from
|
||||
this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
|
||||
PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE ORGANISATION OR
|
||||
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include "oggz_macros.h"
|
||||
#include "oggz_vector.h"
|
||||
|
||||
typedef struct _OggzTable OggzTable;
|
||||
|
||||
struct _OggzTable {
|
||||
OggzVector * keys;
|
||||
OggzVector * data;
|
||||
};
|
||||
|
||||
OggzTable *
|
||||
oggz_table_new (void)
|
||||
{
|
||||
OggzTable * table;
|
||||
|
||||
table = oggz_malloc (sizeof (OggzTable));
|
||||
table->keys = oggz_vector_new ();
|
||||
table->data = oggz_vector_new ();
|
||||
|
||||
return table;
|
||||
}
|
||||
|
||||
void
|
||||
oggz_table_delete (OggzTable * table)
|
||||
{
|
||||
if (table == NULL) return;
|
||||
|
||||
oggz_vector_delete (table->keys);
|
||||
oggz_vector_delete (table->data);
|
||||
oggz_free (table);
|
||||
}
|
||||
|
||||
void *
|
||||
oggz_table_lookup (OggzTable * table, long key)
|
||||
{
|
||||
int i, size;
|
||||
|
||||
size = oggz_vector_size (table->keys);
|
||||
for (i = 0; i < size; i++) {
|
||||
if (oggz_vector_nth_l (table->keys, i) == key) {
|
||||
return oggz_vector_nth_p (table->data, i);
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void *
|
||||
oggz_table_insert (OggzTable * table, long key, void * data)
|
||||
{
|
||||
void * old_data;
|
||||
|
||||
if ((old_data = oggz_table_lookup (table, key)) != NULL) {
|
||||
if (oggz_vector_remove_l (table->keys, key) == NULL)
|
||||
return NULL;
|
||||
|
||||
if (oggz_vector_remove_p (table->data, old_data) == NULL) {
|
||||
/* XXX: This error condition can only happen if the previous
|
||||
* removal succeeded, and this removal failed, ie. there was
|
||||
* an error reallocing table->data->data downwards. */
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
if (oggz_vector_insert_l (table->keys, key) == -1)
|
||||
return NULL;
|
||||
|
||||
if (oggz_vector_insert_p (table->data, data) == NULL) {
|
||||
oggz_vector_remove_l (table->keys, key);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
int
|
||||
oggz_table_size (OggzTable * table)
|
||||
{
|
||||
if (table == NULL) return 0;
|
||||
return oggz_vector_size (table->data);
|
||||
}
|
||||
|
||||
void *
|
||||
oggz_table_nth (OggzTable * table, int n, long * key)
|
||||
{
|
||||
if (table == NULL) return NULL;
|
||||
if (key) *key = oggz_vector_nth_l (table->keys, n);
|
||||
return oggz_vector_nth_p (table->data, n);
|
||||
}
|
@ -1,399 +0,0 @@
|
||||
/*
|
||||
Copyright (C) 2003 Commonwealth Scientific and Industrial Research
|
||||
Organisation (CSIRO) Australia
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions
|
||||
are met:
|
||||
|
||||
- Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
|
||||
- Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
|
||||
- Neither the name of CSIRO Australia nor the names of its
|
||||
contributors may be used to endorse or promote products derived from
|
||||
this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
|
||||
PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE ORGANISATION OR
|
||||
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "oggz_macros.h"
|
||||
|
||||
typedef int (*OggzFunc) (void * data);
|
||||
typedef int (*OggzFindFunc) (void * data, long serialno);
|
||||
typedef int (*OggzCmpFunc) (void * a, void * b, void * user_data);
|
||||
|
||||
typedef struct _OggzVector OggzVector;
|
||||
|
||||
typedef union {
|
||||
void * p;
|
||||
long l;
|
||||
} oggz_data_t;
|
||||
|
||||
struct _OggzVector {
|
||||
int max_elements;
|
||||
int nr_elements;
|
||||
oggz_data_t * data;
|
||||
OggzCmpFunc compare;
|
||||
void * compare_user_data;
|
||||
};
|
||||
|
||||
/*
|
||||
* A vector of void * or long; iff it's a vector of void * objects, it
|
||||
* can be optionally sorted. (The sorting is used to implement the
|
||||
* packet queue; the vector of longs is used to implement OggzTable)
|
||||
*
|
||||
* if you set a comparison function (oggz_vector_set_cmp()), the vector
|
||||
* will be sorted and new elements will be inserted in sorted order.
|
||||
*
|
||||
* if you don't set a comparison function, new elements will be appended
|
||||
* at the tail
|
||||
*
|
||||
* to unset the comparison function, call oggz_vector_set_cmp (NULL,NULL)
|
||||
*/
|
||||
|
||||
OggzVector *
|
||||
oggz_vector_new (void)
|
||||
{
|
||||
OggzVector * vector;
|
||||
|
||||
vector = oggz_malloc (sizeof (OggzVector));
|
||||
|
||||
vector->max_elements = 0;
|
||||
vector->nr_elements = 0;
|
||||
vector->data = NULL;
|
||||
vector->compare = NULL;
|
||||
vector->compare_user_data = NULL;
|
||||
|
||||
return vector;
|
||||
}
|
||||
|
||||
static void
|
||||
oggz_vector_clear (OggzVector * vector)
|
||||
{
|
||||
oggz_free (vector->data);
|
||||
vector->data = NULL;
|
||||
vector->nr_elements = 0;
|
||||
vector->max_elements = 0;
|
||||
}
|
||||
|
||||
void
|
||||
oggz_vector_delete (OggzVector * vector)
|
||||
{
|
||||
oggz_vector_clear (vector);
|
||||
oggz_free (vector);
|
||||
}
|
||||
|
||||
int
|
||||
oggz_vector_size (OggzVector * vector)
|
||||
{
|
||||
if (vector == NULL) return 0;
|
||||
|
||||
return vector->nr_elements;
|
||||
}
|
||||
|
||||
void *
|
||||
oggz_vector_nth_p (OggzVector * vector, int n)
|
||||
{
|
||||
if (vector == NULL) return NULL;
|
||||
|
||||
if (n >= vector->nr_elements) return NULL;
|
||||
|
||||
return vector->data[n].p;
|
||||
}
|
||||
|
||||
long
|
||||
oggz_vector_nth_l (OggzVector * vector, int n)
|
||||
{
|
||||
if (vector == NULL) return -1L;
|
||||
|
||||
if (n >= vector->nr_elements) return -1L;
|
||||
|
||||
return vector->data[n].l;
|
||||
}
|
||||
|
||||
void *
|
||||
oggz_vector_find (OggzVector * vector, OggzFindFunc func, long serialno)
|
||||
{
|
||||
void * data;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < vector->nr_elements; i++) {
|
||||
data = vector->data[i].p;
|
||||
if (func (data, serialno))
|
||||
return data;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int
|
||||
oggz_vector_foreach (OggzVector * vector, OggzFunc func)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < vector->nr_elements; i++) {
|
||||
func (vector->data[i].p);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void
|
||||
_array_swap (oggz_data_t v[], int i, int j)
|
||||
{
|
||||
void * t;
|
||||
|
||||
t = v[i].p;
|
||||
v[i].p = v[j].p;
|
||||
v[j].p = t;
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper function for oggz_vector_insert (). Sorts the vector by
|
||||
* insertion sort, assuming the tail element has just been added and the
|
||||
* rest of the vector is sorted.
|
||||
* \param vector An OggzVector
|
||||
* \pre The vector has just had a new element added to its tail
|
||||
* \pre All elements other than the tail element are already sorted.
|
||||
*/
|
||||
static void
|
||||
oggz_vector_tail_insertion_sort (OggzVector * vector)
|
||||
{
|
||||
int i;
|
||||
|
||||
if (vector->compare == NULL) return;
|
||||
|
||||
for (i = vector->nr_elements-1; i > 0; i--) {
|
||||
if (vector->compare (vector->data[i-1].p, vector->data[i].p,
|
||||
vector->compare_user_data) > 0) {
|
||||
_array_swap (vector->data, i, i-1);
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
static OggzVector *
|
||||
oggz_vector_grow (OggzVector * vector)
|
||||
{
|
||||
void * new_elements;
|
||||
int new_max_elements;
|
||||
|
||||
vector->nr_elements++;
|
||||
|
||||
if (vector->nr_elements > vector->max_elements) {
|
||||
if (vector->max_elements == 0) {
|
||||
new_max_elements = 1;
|
||||
} else {
|
||||
new_max_elements = vector->max_elements * 2;
|
||||
}
|
||||
|
||||
new_elements =
|
||||
realloc (vector->data, (size_t)new_max_elements * sizeof (oggz_data_t));
|
||||
|
||||
if (new_elements == NULL) {
|
||||
vector->nr_elements--;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
vector->max_elements = new_max_elements;
|
||||
vector->data = new_elements;
|
||||
}
|
||||
|
||||
return vector;
|
||||
}
|
||||
|
||||
void *
|
||||
oggz_vector_insert_p (OggzVector * vector, void * data)
|
||||
{
|
||||
if (oggz_vector_grow (vector) == NULL)
|
||||
return NULL;
|
||||
|
||||
vector->data[vector->nr_elements-1].p = data;
|
||||
|
||||
oggz_vector_tail_insertion_sort (vector);
|
||||
|
||||
return data;
|
||||
|
||||
}
|
||||
|
||||
long
|
||||
oggz_vector_insert_l (OggzVector * vector, long ldata)
|
||||
{
|
||||
if (oggz_vector_grow (vector) == NULL)
|
||||
return -1;
|
||||
|
||||
vector->data[vector->nr_elements-1].l = ldata;
|
||||
|
||||
return ldata;
|
||||
}
|
||||
|
||||
static void
|
||||
oggz_vector_qsort (OggzVector * vector, int left, int right)
|
||||
{
|
||||
int i, last;
|
||||
oggz_data_t * v = vector->data;
|
||||
|
||||
if (left >= right) return;
|
||||
|
||||
_array_swap (v, left, (left + right)/2);
|
||||
last = left;
|
||||
for (i = left+1; i <= right; i++) {
|
||||
if (vector->compare (v[i].p, v[left].p, vector->compare_user_data) < 0)
|
||||
_array_swap (v, ++last, i);
|
||||
}
|
||||
_array_swap (v, left, last);
|
||||
oggz_vector_qsort (vector, left, last-1);
|
||||
oggz_vector_qsort (vector, last+1, right);
|
||||
}
|
||||
|
||||
int
|
||||
oggz_vector_set_cmp (OggzVector * vector, OggzCmpFunc compare,
|
||||
void * user_data)
|
||||
{
|
||||
vector->compare = compare;
|
||||
vector->compare_user_data = user_data;
|
||||
|
||||
if (compare) {
|
||||
oggz_vector_qsort (vector, 0, vector->nr_elements-1);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static void *
|
||||
oggz_vector_remove_nth (OggzVector * vector, int n)
|
||||
{
|
||||
int i;
|
||||
oggz_data_t * new_elements;
|
||||
int new_max_elements;
|
||||
|
||||
vector->nr_elements--;
|
||||
|
||||
if (vector->nr_elements == 0) {
|
||||
oggz_vector_clear (vector);
|
||||
} else {
|
||||
for (i = n; i < vector->nr_elements; i++) {
|
||||
vector->data[i] = vector->data[i+1];
|
||||
}
|
||||
|
||||
if (vector->nr_elements < vector->max_elements/2) {
|
||||
new_max_elements = vector->max_elements/2;
|
||||
|
||||
new_elements =
|
||||
realloc (vector->data,
|
||||
(size_t)new_max_elements * sizeof (oggz_data_t));
|
||||
|
||||
if (new_elements == NULL)
|
||||
return NULL;
|
||||
|
||||
vector->max_elements = new_max_elements;
|
||||
vector->data = new_elements;
|
||||
}
|
||||
}
|
||||
|
||||
return vector;
|
||||
}
|
||||
|
||||
OggzVector *
|
||||
oggz_vector_remove_p (OggzVector * vector, void * data)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < vector->nr_elements; i++) {
|
||||
if (vector->data[i].p == data) {
|
||||
return oggz_vector_remove_nth (vector, i);
|
||||
}
|
||||
}
|
||||
|
||||
return vector;
|
||||
}
|
||||
|
||||
OggzVector *
|
||||
oggz_vector_remove_l (OggzVector * vector, long ldata)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < vector->nr_elements; i++) {
|
||||
if (vector->data[i].l == ldata) {
|
||||
return oggz_vector_remove_nth (vector, i);
|
||||
}
|
||||
}
|
||||
|
||||
return vector;
|
||||
}
|
||||
|
||||
void *
|
||||
oggz_vector_pop (OggzVector * vector)
|
||||
{
|
||||
void * data;
|
||||
#if 0
|
||||
void * new_elements;
|
||||
int new_max_elements;
|
||||
#endif
|
||||
|
||||
if (!vector || vector->data == NULL) return NULL;
|
||||
|
||||
data = vector->data[0].p;
|
||||
|
||||
#if 0
|
||||
vector->nr_elements--;
|
||||
|
||||
if (vector->nr_elements == 0) {
|
||||
oggz_vector_clear (vector);
|
||||
} else {
|
||||
#if 0
|
||||
memmove (vector->data, &vector->data[1],
|
||||
vector->nr_elements * sizeof (void *));
|
||||
#else
|
||||
{
|
||||
int i;
|
||||
for (i = 0; i < vector->nr_elements; i++) {
|
||||
vector->data[i].p = vector->data[i+1].p;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
if (vector->nr_elements < vector->max_elements/2) {
|
||||
new_max_elements = vector->max_elements/2;
|
||||
|
||||
new_elements =
|
||||
realloc (vector->data,
|
||||
(size_t)new_max_elements * sizeof (oggz_data_t));
|
||||
|
||||
if (new_elements != NULL) {
|
||||
vector->max_elements = new_max_elements;
|
||||
vector->data = new_elements;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
#else
|
||||
|
||||
oggz_vector_remove_nth (vector, 0);
|
||||
|
||||
#endif
|
||||
|
||||
return data;
|
||||
|
||||
}
|
@ -1,101 +0,0 @@
|
||||
/*
|
||||
Copyright (C) 2003 Commonwealth Scientific and Industrial Research
|
||||
Organisation (CSIRO) Australia
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions
|
||||
are met:
|
||||
|
||||
- Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
|
||||
- Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
|
||||
- Neither the name of CSIRO Australia nor the names of its
|
||||
contributors may be used to endorse or promote products derived from
|
||||
this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
|
||||
PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE ORGANISATION OR
|
||||
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef __OGGZ_VECTOR_H__
|
||||
#define __OGGZ_VECTOR_H__
|
||||
|
||||
typedef void OggzVector;
|
||||
|
||||
typedef int (*OggzFunc) (void * data);
|
||||
typedef int (*OggzFindFunc) (void * data, long serialno);
|
||||
typedef int (*OggzCmpFunc) (void * a, void * b, void * user_data);
|
||||
|
||||
OggzVector *
|
||||
oggz_vector_new (void);
|
||||
|
||||
void
|
||||
oggz_vector_delete (OggzVector * vector);
|
||||
|
||||
void *
|
||||
oggz_vector_find (OggzVector * vector, OggzFindFunc func, long serialno);
|
||||
|
||||
void *
|
||||
oggz_vector_nth_p (OggzVector * vector, int n);
|
||||
|
||||
long
|
||||
oggz_vector_nth_l (OggzVector * vector, int n);
|
||||
|
||||
int
|
||||
oggz_vector_foreach (OggzVector * vector, OggzFunc func);
|
||||
|
||||
int
|
||||
oggz_vector_size (OggzVector * vector);
|
||||
|
||||
/**
|
||||
* Add an element to a vector. If the vector has a comparison function,
|
||||
* the new element is inserted in sorted order, otherwise it is appended
|
||||
* to the tail.
|
||||
* \param vector An OggzVector
|
||||
* \param data The new element to add
|
||||
* \retval data If the element was successfully added
|
||||
* \retval NULL If adding the element failed due to a realloc() error
|
||||
*/
|
||||
void *
|
||||
oggz_vector_insert_p (OggzVector * vector, void * data);
|
||||
|
||||
long
|
||||
oggz_vector_insert_l (OggzVector * vector, long ldata);
|
||||
|
||||
/**
|
||||
* Remove a (void *) element of a vector
|
||||
* \retval \a vector on success
|
||||
* \retval NULL on failure (realloc error)
|
||||
*/
|
||||
OggzVector *
|
||||
oggz_vector_remove_p (OggzVector * vector, void * data);
|
||||
|
||||
/**
|
||||
* Remove a (long) element of a vector
|
||||
* \retval \a vector on success
|
||||
* \retval NULL on failure (realloc error)
|
||||
*/
|
||||
OggzVector *
|
||||
oggz_vector_remove_l (OggzVector * vector, long ldata);
|
||||
|
||||
int
|
||||
oggz_vector_set_cmp (OggzVector * vector, OggzCmpFunc compare,
|
||||
void * user_data);
|
||||
|
||||
void *
|
||||
oggz_vector_pop (OggzVector * vector);
|
||||
|
||||
#endif /* __OGGZ_VECTOR_H__ */
|
@ -1,749 +0,0 @@
|
||||
/*
|
||||
Copyright (C) 2003 Commonwealth Scientific and Industrial Research
|
||||
Organisation (CSIRO) Australia
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions
|
||||
are met:
|
||||
|
||||
- Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
|
||||
- Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
|
||||
- Neither the name of CSIRO Australia nor the names of its
|
||||
contributors may be used to endorse or promote products derived from
|
||||
this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
|
||||
PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE ORGANISATION OR
|
||||
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#if OGGZ_CONFIG_WRITE
|
||||
|
||||
#include <assert.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
|
||||
#ifdef HAVE_UNISTD_H
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
|
||||
#include <fcntl.h>
|
||||
#include <errno.h>
|
||||
#include <string.h>
|
||||
#include <time.h>
|
||||
|
||||
#include <ogg/ogg.h>
|
||||
|
||||
#include "oggz_private.h"
|
||||
#include "oggz_vector.h"
|
||||
|
||||
/* #define DEBUG */
|
||||
|
||||
/* #define ALWAYS_FLUSH */
|
||||
|
||||
/* #define ZPACKET_CMP */
|
||||
|
||||
#ifdef ZPACKET_CMP
|
||||
static int
|
||||
oggz_zpacket_cmp (oggz_writer_packet_t * a, oggz_writer_packet_t * b,
|
||||
void * user_data)
|
||||
{
|
||||
OGGZ * oggz = (OGGZ *)user_data;
|
||||
long serialno_a, serialno_b;
|
||||
ogg_int64_t unit_a, unit_b;
|
||||
|
||||
serialno_a = a->stream->ogg_stream.serialno;
|
||||
serialno_b = b->stream->ogg_stream.serialno;
|
||||
|
||||
unit_a = oggz_get_unit (oggz, serialno_a, a->op.granulepos);
|
||||
unit_b = oggz_get_unit (oggz, serialno_b, b->op.granulepos);
|
||||
|
||||
if (unit_a < unit_b) return -1;
|
||||
else return (unit_a > unit_b);
|
||||
}
|
||||
#endif
|
||||
|
||||
OGGZ *
|
||||
oggz_write_init (OGGZ * oggz)
|
||||
{
|
||||
OggzWriter * writer = &oggz->x.writer;
|
||||
|
||||
writer->next_zpacket = NULL;
|
||||
|
||||
writer->packet_queue = oggz_vector_new ();
|
||||
|
||||
#ifdef ZPACKET_CMP
|
||||
/* XXX: comparison function should only kick in when a metric is set */
|
||||
oggz_vector_set_cmp (writer->packet_queue,
|
||||
(OggzCmpFunc)oggz_zpacket_cmp, oggz);
|
||||
#endif
|
||||
|
||||
writer->hungry = NULL;
|
||||
writer->hungry_user_data = NULL;
|
||||
writer->hungry_only_when_empty = 0;
|
||||
|
||||
writer->writing = 0;
|
||||
writer->state = OGGZ_MAKING_PACKETS;
|
||||
|
||||
writer->flushing = 0;
|
||||
#if 0
|
||||
writer->eog = 1;
|
||||
writer->eop = 1; /* init ready to start next packet */
|
||||
#endif
|
||||
writer->eos = 0;
|
||||
|
||||
writer->current_zpacket = NULL;
|
||||
|
||||
writer->packet_offset = 0;
|
||||
writer->page_offset = 0;
|
||||
|
||||
return oggz;
|
||||
}
|
||||
|
||||
static int
|
||||
oggz_writer_packet_free (oggz_writer_packet_t * zpacket)
|
||||
{
|
||||
if (!zpacket) return 0;
|
||||
|
||||
if (zpacket->guard) {
|
||||
/* managed by user; flag guard */
|
||||
*zpacket->guard = 1;
|
||||
} else {
|
||||
/* managed by oggz; free copied data */
|
||||
oggz_free (zpacket->op.packet);
|
||||
}
|
||||
oggz_free (zpacket);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
OGGZ *
|
||||
oggz_write_close (OGGZ * oggz)
|
||||
{
|
||||
OggzWriter * writer = &oggz->x.writer;
|
||||
|
||||
oggz_vector_foreach (writer->packet_queue,
|
||||
(OggzFunc)oggz_writer_packet_free);
|
||||
oggz_vector_delete (writer->packet_queue);
|
||||
|
||||
return oggz;
|
||||
}
|
||||
|
||||
/******** Packet queueing ********/
|
||||
|
||||
int
|
||||
oggz_write_set_hungry_callback (OGGZ * oggz, OggzWriteHungry hungry,
|
||||
int only_when_empty, void * user_data)
|
||||
{
|
||||
OggzWriter * writer;
|
||||
|
||||
if (oggz == NULL) return OGGZ_ERR_BAD_OGGZ;
|
||||
|
||||
if (!(oggz->flags & OGGZ_WRITE)) {
|
||||
return OGGZ_ERR_INVALID;
|
||||
}
|
||||
|
||||
writer = &oggz->x.writer;
|
||||
|
||||
writer->hungry = hungry;
|
||||
writer->hungry_user_data = user_data;
|
||||
writer->hungry_only_when_empty = only_when_empty;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
oggz_write_feed (OGGZ * oggz, ogg_packet * op, long serialno, int flush,
|
||||
int * guard)
|
||||
{
|
||||
OggzWriter * writer;
|
||||
oggz_stream_t * stream;
|
||||
oggz_writer_packet_t * packet;
|
||||
ogg_packet * new_op;
|
||||
unsigned char * new_buf;
|
||||
int b_o_s, e_o_s, bos_auto;
|
||||
int strict;
|
||||
|
||||
if (oggz == NULL) return OGGZ_ERR_BAD_OGGZ;
|
||||
|
||||
if (!(oggz->flags & OGGZ_WRITE)) {
|
||||
return OGGZ_ERR_INVALID;
|
||||
}
|
||||
|
||||
writer = &oggz->x.writer;
|
||||
|
||||
if (guard && *guard != 0) return OGGZ_ERR_BAD_GUARD;
|
||||
|
||||
#ifdef DEBUG
|
||||
printf ("oggz_write_feed: (%010ld) FLUSH: %d\n", serialno, flush);
|
||||
#endif
|
||||
|
||||
/* Cache strict */
|
||||
strict = !(oggz->flags & OGGZ_NONSTRICT);
|
||||
|
||||
/* Set bos, eos to canonical values */
|
||||
bos_auto = (op->b_o_s == -1) ? 1 : 0;
|
||||
b_o_s = op->b_o_s ? 1 : 0;
|
||||
e_o_s = op->e_o_s ? 1 : 0;
|
||||
|
||||
stream = oggz_get_stream (oggz, serialno);
|
||||
if (stream == NULL) {
|
||||
if (bos_auto) b_o_s = 1;
|
||||
|
||||
if (strict && b_o_s && !oggz_get_bos (oggz, -1)) {
|
||||
return OGGZ_ERR_BOS;
|
||||
}
|
||||
|
||||
if (b_o_s || !strict) {
|
||||
stream = oggz_add_stream (oggz, serialno);
|
||||
} else {
|
||||
return OGGZ_ERR_BAD_SERIALNO;
|
||||
}
|
||||
} else {
|
||||
if (bos_auto) b_o_s = 0;
|
||||
|
||||
if (strict && stream->e_o_s)
|
||||
return OGGZ_ERR_EOS;
|
||||
}
|
||||
|
||||
/* Check packet against mapping restrictions */
|
||||
if (strict) {
|
||||
if (op->bytes < 0) return OGGZ_ERR_BAD_BYTES;
|
||||
if (b_o_s != stream->b_o_s) return OGGZ_ERR_BAD_B_O_S;
|
||||
|
||||
if (op->granulepos != -1 && op->granulepos < stream->granulepos)
|
||||
return OGGZ_ERR_BAD_GRANULEPOS;
|
||||
|
||||
/* Allow packetno == -1 to indicate oggz should fill it in; otherwise:
|
||||
* if op is the first packet in the stream, initialize the stream's
|
||||
* packetno to the given one, otherwise check it for strictness */
|
||||
if (op->packetno != -1) {
|
||||
if (b_o_s) {
|
||||
stream->packetno = op->packetno;
|
||||
} else if (op->packetno <= stream->packetno) {
|
||||
return OGGZ_ERR_BAD_PACKETNO;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* OK -- Update stream's memory of packet details */
|
||||
|
||||
stream->b_o_s = 0; /* The stream is henceforth no longer at bos */
|
||||
stream->e_o_s = e_o_s; /* We believe the eos value */
|
||||
stream->granulepos = op->granulepos; /* and the granulepos */
|
||||
|
||||
/* If the user specified a packetno of -1, fill it in automatically;
|
||||
* otherwise, use the user-specified value */
|
||||
stream->packetno = (op->packetno != -1) ? op->packetno : stream->packetno+1;
|
||||
|
||||
/* Now set up the packet and add it to the queue */
|
||||
if (guard == NULL) {
|
||||
new_buf = oggz_malloc ((size_t)op->bytes);
|
||||
memcpy (new_buf, op->packet, (size_t)op->bytes);
|
||||
} else {
|
||||
new_buf = op->packet;
|
||||
}
|
||||
|
||||
packet = oggz_malloc (sizeof (oggz_writer_packet_t));
|
||||
|
||||
new_op = &packet->op;
|
||||
new_op->packet = new_buf;
|
||||
new_op->bytes = op->bytes;
|
||||
new_op->b_o_s = op->b_o_s;
|
||||
new_op->e_o_s = op->e_o_s;
|
||||
new_op->granulepos = op->granulepos;
|
||||
new_op->packetno = stream->packetno;
|
||||
|
||||
packet->stream = stream;
|
||||
packet->flush = flush;
|
||||
packet->guard = guard;
|
||||
|
||||
#ifdef DEBUG
|
||||
printf ("oggz_write_feed: made packet bos %ld eos %ld (%ld bytes) FLUSH: %d\n",
|
||||
new_op->b_o_s, new_op->e_o_s, new_op->bytes, packet->flush);
|
||||
#endif
|
||||
|
||||
if (oggz_vector_insert_p (writer->packet_queue, packet) == NULL) {
|
||||
oggz_free (packet);
|
||||
if (!guard) oggz_free (new_buf);
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/******** Page creation ********/
|
||||
|
||||
/*
|
||||
*
|
||||
|
||||
____ __________________\___ ____
|
||||
/ \ / Page ready / \ / \
|
||||
| \ /=========\ /=========\ / |
|
||||
Page | || Make || || Write || | Page
|
||||
!ready V || packet || || page || V ready
|
||||
| / \=========/ \=========/ \ |
|
||||
\____/ \___/__________________/ \____/
|
||||
\ Page !ready
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
/*
|
||||
* oggz_page_init (oggz)
|
||||
*
|
||||
* Initialises the next page of the current packet.
|
||||
*
|
||||
* If this returns 0, the page is not ready for writing.
|
||||
*/
|
||||
static long
|
||||
oggz_page_init (OGGZ * oggz)
|
||||
{
|
||||
OggzWriter * writer = &oggz->x.writer;
|
||||
ogg_stream_state * os;
|
||||
ogg_page * og;
|
||||
int ret;
|
||||
|
||||
if (oggz == NULL) return -1;
|
||||
|
||||
os = writer->current_stream;
|
||||
og = &oggz->current_page;
|
||||
|
||||
#ifdef ALWAYS_FLUSH
|
||||
ret = ogg_stream_flush (os, og);
|
||||
#else
|
||||
if (writer->flushing) {
|
||||
#ifdef DEBUG
|
||||
printf ("*** ATTEMPT FLUSH: ");
|
||||
#endif
|
||||
ret = ogg_stream_flush (os, og);
|
||||
} else {
|
||||
#ifdef DEBUG
|
||||
printf ("*** ATTEMPT pageout: ");
|
||||
#endif
|
||||
ret = ogg_stream_pageout (os, og);
|
||||
}
|
||||
#endif
|
||||
|
||||
if (ret) {
|
||||
writer->page_offset = 0;
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
printf ("%s\n", ret ? "OK" : "NO");
|
||||
#endif
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
* oggz_packet_init (oggz, buf, n)
|
||||
*
|
||||
* Initialises the next packet with data from buf, length n
|
||||
*/
|
||||
static long
|
||||
oggz_packet_init (OGGZ * oggz, oggz_writer_packet_t * next_zpacket)
|
||||
{
|
||||
OggzWriter * writer = &oggz->x.writer;
|
||||
oggz_stream_t * stream;
|
||||
ogg_stream_state * os;
|
||||
ogg_packet * op;
|
||||
|
||||
if (oggz == NULL) return -1L;
|
||||
|
||||
writer->current_zpacket = next_zpacket;
|
||||
op = &next_zpacket->op;
|
||||
|
||||
#ifdef DEBUG
|
||||
printf ("oggz_packet_init: %ld bytes\n", (long)op->bytes);
|
||||
#endif
|
||||
|
||||
stream = next_zpacket->stream;
|
||||
|
||||
/* Mark this stream as having delivered a non b_o_s packet if so */
|
||||
if (!op->b_o_s) stream->delivered_non_b_o_s = 1;
|
||||
|
||||
os = &stream->ogg_stream;
|
||||
ogg_stream_packetin (os, op);
|
||||
|
||||
writer->flushing = (next_zpacket->flush & OGGZ_FLUSH_AFTER);
|
||||
#ifdef DEBUG
|
||||
printf ("oggz_packet_init: set flush to %d\n", writer->flushing);
|
||||
#endif
|
||||
writer->current_stream = os;
|
||||
writer->packet_offset = 0;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static long
|
||||
oggz_page_copyout (OGGZ * oggz, unsigned char * buf, long n)
|
||||
{
|
||||
OggzWriter * writer = &oggz->x.writer;
|
||||
long h, b;
|
||||
ogg_page * og;
|
||||
|
||||
if (oggz == NULL) return -1L;
|
||||
|
||||
og = &oggz->current_page;
|
||||
|
||||
h = MIN (n, og->header_len - writer->page_offset);
|
||||
if (h > 0) {
|
||||
memcpy (buf, og->header + writer->page_offset, h);
|
||||
writer->page_offset += h;
|
||||
n -= h;
|
||||
buf += h;
|
||||
} else {
|
||||
h = 0;
|
||||
}
|
||||
|
||||
b = MIN (n, og->header_len + og->body_len - writer->page_offset);
|
||||
if (b > 0) {
|
||||
#ifdef DEBUG
|
||||
{
|
||||
unsigned char * c = &og->body[writer->page_offset - og->header_len];
|
||||
printf ("oggz_page_copyout [%d] (@%ld): %c%c%c%c ...\n",
|
||||
ogg_page_serialno (og), (long) ogg_page_granulepos (og),
|
||||
c[0], c[1], c[2], c[3]);
|
||||
}
|
||||
#endif
|
||||
memcpy (buf, og->body + (writer->page_offset - og->header_len), b);
|
||||
writer->page_offset += b;
|
||||
n -= b;
|
||||
buf += b;
|
||||
} else {
|
||||
b = 0;
|
||||
}
|
||||
|
||||
return h + b;
|
||||
}
|
||||
|
||||
static long
|
||||
oggz_page_writeout (OGGZ * oggz, long n)
|
||||
{
|
||||
OggzWriter * writer = &oggz->x.writer;
|
||||
long h, b, nwritten;
|
||||
ogg_page * og;
|
||||
|
||||
#ifdef OGGZ_WRITE_DIRECT
|
||||
int fd;
|
||||
#endif
|
||||
|
||||
if (oggz == NULL) return -1L;
|
||||
|
||||
og = &oggz->current_page;
|
||||
|
||||
#ifdef OGGZ_WRITE_DIRECT
|
||||
fd = fileno (oggz->file);
|
||||
#endif
|
||||
|
||||
h = MIN (n, og->header_len - writer->page_offset);
|
||||
if (h > 0) {
|
||||
#ifdef OGGZ_WRITE_DIRECT
|
||||
nwritten = write (fd, og->header + writer->page_offset, h);
|
||||
#else
|
||||
nwritten = (long)oggz_io_write (oggz, og->header + writer->page_offset, h);
|
||||
#endif
|
||||
|
||||
#ifdef DEBUG
|
||||
if (nwritten < h) {
|
||||
printf ("oggz_page_writeout: %ld < %ld\n", nwritten, h);
|
||||
}
|
||||
#endif
|
||||
writer->page_offset += h;
|
||||
n -= h;
|
||||
} else {
|
||||
h = 0;
|
||||
}
|
||||
|
||||
b = MIN (n, og->header_len + og->body_len - writer->page_offset);
|
||||
if (b > 0) {
|
||||
#ifdef OGGZ_WRITE_DIRECT
|
||||
nwritten = write (fd,
|
||||
og->body + (writer->page_offset - og->header_len), b);
|
||||
#else
|
||||
nwritten = (long)oggz_io_write (oggz, og->body + (writer->page_offset - og->header_len), b);
|
||||
#endif
|
||||
#ifdef DEBUG
|
||||
if (nwritten < b) {
|
||||
printf ("oggz_page_writeout: %ld < %ld\n", nwritten, b);
|
||||
}
|
||||
#endif
|
||||
writer->page_offset += b;
|
||||
n -= b;
|
||||
} else {
|
||||
b = 0;
|
||||
}
|
||||
|
||||
return h + b;
|
||||
}
|
||||
|
||||
static oggz_writer_packet_t *
|
||||
oggz_dequeue_packet (OGGZ * oggz)
|
||||
{
|
||||
OggzWriter * writer = &oggz->x.writer;
|
||||
oggz_writer_packet_t * next_zpacket;
|
||||
|
||||
if (writer->next_zpacket != NULL) {
|
||||
next_zpacket = writer->next_zpacket;
|
||||
writer->next_zpacket = NULL;
|
||||
} else {
|
||||
next_zpacket = oggz_vector_pop (writer->packet_queue);
|
||||
|
||||
if (next_zpacket == NULL) {
|
||||
if (writer->hungry) {
|
||||
writer->hungry (oggz, 1, writer->hungry_user_data);
|
||||
next_zpacket = oggz_vector_pop (writer->packet_queue);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return next_zpacket;
|
||||
}
|
||||
|
||||
static long
|
||||
oggz_writer_make_packet (OGGZ * oggz)
|
||||
{
|
||||
OggzWriter * writer = &oggz->x.writer;
|
||||
oggz_writer_packet_t * zpacket, * next_zpacket;
|
||||
int cb_ret = 0, ret = 0;
|
||||
|
||||
#ifdef DEBUG
|
||||
printf ("make packet ...\n");
|
||||
#endif
|
||||
|
||||
/* finished with current packet; unguard */
|
||||
zpacket = writer->current_zpacket;
|
||||
oggz_writer_packet_free (zpacket);
|
||||
writer->current_zpacket = NULL;
|
||||
|
||||
/* if the user wants the hungry callback after every packet, give
|
||||
* it to them, marking emptiness appropriately
|
||||
*/
|
||||
if (writer->hungry && !writer->hungry_only_when_empty) {
|
||||
int empty = (oggz_vector_size (writer->packet_queue) == 0);
|
||||
cb_ret = writer->hungry (oggz, empty, writer->hungry_user_data);
|
||||
}
|
||||
|
||||
if (cb_ret == 0) {
|
||||
/* dequeue and init the next packet */
|
||||
if ((next_zpacket = oggz_dequeue_packet (oggz)) == NULL) {
|
||||
/*writer->eos = 1;*/
|
||||
ret = 0;
|
||||
} else {
|
||||
if ((writer->current_stream != NULL) &&
|
||||
(next_zpacket->flush & OGGZ_FLUSH_BEFORE)) {
|
||||
writer->flushing = 1;
|
||||
#ifdef DEBUG
|
||||
printf ("oggz_writer_make_packet: set flush to %d\n",
|
||||
writer->flushing);
|
||||
#endif
|
||||
next_zpacket->flush &= OGGZ_FLUSH_AFTER;
|
||||
writer->next_zpacket = next_zpacket;
|
||||
} else {
|
||||
oggz_packet_init (oggz, next_zpacket);
|
||||
}
|
||||
ret = 1;
|
||||
}
|
||||
} else {
|
||||
ret = 0;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
long
|
||||
oggz_write_output (OGGZ * oggz, unsigned char * buf, long n)
|
||||
{
|
||||
OggzWriter * writer = &oggz->x.writer;
|
||||
long bytes, bytes_written = 1, remaining = n, nwritten = 0;
|
||||
int active = 1;
|
||||
|
||||
if (oggz == NULL) return OGGZ_ERR_BAD_OGGZ;
|
||||
|
||||
if (!(oggz->flags & OGGZ_WRITE)) {
|
||||
return OGGZ_ERR_INVALID;
|
||||
}
|
||||
|
||||
if (writer->writing) return OGGZ_ERR_RECURSIVE_WRITE;
|
||||
writer->writing = 1;
|
||||
|
||||
while (active && remaining > 0) {
|
||||
bytes = MIN (remaining, 1024);
|
||||
|
||||
while (writer->state == OGGZ_MAKING_PACKETS) {
|
||||
if (!oggz_writer_make_packet (oggz)) {
|
||||
active = 0;
|
||||
break;
|
||||
}
|
||||
if (oggz_page_init (oggz)) {
|
||||
writer->state = OGGZ_WRITING_PAGES;
|
||||
}
|
||||
}
|
||||
|
||||
if (writer->state == OGGZ_WRITING_PAGES) {
|
||||
bytes_written = oggz_page_copyout (oggz, buf, bytes);
|
||||
|
||||
if (bytes_written == -1) {
|
||||
active = 0;
|
||||
return OGGZ_ERR_SYSTEM; /* XXX: catch next */
|
||||
} else if (bytes_written == 0) {
|
||||
if (!oggz_page_init (oggz)) {
|
||||
writer->state = OGGZ_MAKING_PACKETS;
|
||||
}
|
||||
}
|
||||
|
||||
buf += bytes_written;
|
||||
|
||||
remaining -= bytes_written;
|
||||
nwritten += bytes_written;
|
||||
}
|
||||
}
|
||||
|
||||
writer->writing = 0;
|
||||
|
||||
return nwritten;
|
||||
}
|
||||
|
||||
long
|
||||
oggz_write (OGGZ * oggz, long n)
|
||||
{
|
||||
OggzWriter * writer = &oggz->x.writer;
|
||||
long bytes, bytes_written = 1, remaining = n, nwritten = 0;
|
||||
int active = 1;
|
||||
|
||||
if (oggz == NULL) return OGGZ_ERR_BAD_OGGZ;
|
||||
|
||||
if (!(oggz->flags & OGGZ_WRITE)) {
|
||||
return OGGZ_ERR_INVALID;
|
||||
}
|
||||
|
||||
if (writer->writing) return OGGZ_ERR_RECURSIVE_WRITE;
|
||||
writer->writing = 1;
|
||||
|
||||
#ifdef DEBUG
|
||||
printf ("oggz_write: IN\n");
|
||||
#endif
|
||||
|
||||
while (active && remaining > 0) {
|
||||
bytes = MIN (remaining, 1024);
|
||||
|
||||
#ifdef DEBUG
|
||||
printf ("oggz_write: write loop (%ld , %ld remain) ...\n", bytes,
|
||||
remaining);
|
||||
#endif
|
||||
|
||||
while (writer->state == OGGZ_MAKING_PACKETS) {
|
||||
if (!oggz_writer_make_packet (oggz)) {
|
||||
active = 0;
|
||||
#ifdef DEBUG
|
||||
printf ("oggz_write: no packets\n");
|
||||
#endif
|
||||
break;
|
||||
}
|
||||
if (oggz_page_init (oggz)) {
|
||||
writer->state = OGGZ_WRITING_PAGES;
|
||||
}
|
||||
}
|
||||
|
||||
if (writer->state == OGGZ_WRITING_PAGES) {
|
||||
bytes_written = oggz_page_writeout (oggz, bytes);
|
||||
|
||||
if (bytes_written == -1) {
|
||||
active = 0;
|
||||
return OGGZ_ERR_SYSTEM; /* XXX: catch next */
|
||||
} else if (bytes_written == 0) {
|
||||
if (!oggz_page_init (oggz)) {
|
||||
#ifdef DEBUG
|
||||
printf ("oggz_write: bytes_written == 0, DONE\n");
|
||||
#endif
|
||||
writer->state = OGGZ_MAKING_PACKETS;
|
||||
}
|
||||
}
|
||||
|
||||
remaining -= bytes_written;
|
||||
nwritten += bytes_written;
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
printf ("oggz_write: OUT %ld\n", nwritten);
|
||||
#endif
|
||||
|
||||
writer->writing = 0;
|
||||
|
||||
return nwritten;
|
||||
}
|
||||
|
||||
long
|
||||
oggz_write_get_next_page_size (OGGZ * oggz)
|
||||
{
|
||||
OggzWriter * writer = &oggz->x.writer;
|
||||
ogg_page * og;
|
||||
|
||||
if (oggz == NULL) return OGGZ_ERR_BAD_OGGZ;
|
||||
|
||||
if (!(oggz->flags & OGGZ_WRITE)) {
|
||||
return OGGZ_ERR_INVALID;
|
||||
}
|
||||
|
||||
og = &oggz->current_page;
|
||||
|
||||
return (og->header_len + og->body_len - (long)writer->page_offset);
|
||||
}
|
||||
|
||||
#else /* OGGZ_CONFIG_WRITE */
|
||||
|
||||
#include <ogg/ogg.h>
|
||||
#include "oggz_private.h"
|
||||
|
||||
int
|
||||
oggz_write_set_hungry_callback (OGGZ * oggz, OggzWriteHungry hungry,
|
||||
int only_when_empty, void * user_data)
|
||||
{
|
||||
return OGGZ_ERR_DISABLED;
|
||||
}
|
||||
|
||||
int
|
||||
oggz_write_feed (OGGZ * oggz, ogg_packet * op, long serialno, int flush,
|
||||
int * guard)
|
||||
{
|
||||
return OGGZ_ERR_DISABLED;
|
||||
}
|
||||
|
||||
long
|
||||
oggz_write_output (OGGZ * oggz, unsigned char * buf, long n)
|
||||
{
|
||||
return OGGZ_ERR_DISABLED;
|
||||
}
|
||||
|
||||
long
|
||||
oggz_write (OGGZ * oggz, long n)
|
||||
{
|
||||
return OGGZ_ERR_DISABLED;
|
||||
}
|
||||
|
||||
long
|
||||
oggz_write_get_next_page_size (OGGZ * oggz)
|
||||
{
|
||||
return OGGZ_ERR_DISABLED;
|
||||
}
|
||||
|
||||
#endif
|
@ -1,17 +0,0 @@
|
||||
SubDir HAIKU_TOP src add-ons media plugins speex ;
|
||||
|
||||
SetSubDirSupportedPlatformsBeOSCompatible ;
|
||||
|
||||
UsePrivateHeaders media ;
|
||||
|
||||
SubDirHdrs $(SUBDIR) .. ogg ;
|
||||
SubDirSysHdrs $(SUBDIR) .. ogg libogg ;
|
||||
SubDirHdrs $(SUBDIR) libspeex ;
|
||||
|
||||
Addon speex :
|
||||
speexCodecPlugin.cpp
|
||||
speexCodecDefaults.cpp
|
||||
: libspeex.a be libmedia.so $(TARGET_LIBSUPC++)
|
||||
;
|
||||
|
||||
SubInclude HAIKU_TOP src add-ons media plugins speex libspeex ;
|
@ -1,15 +0,0 @@
|
||||
Jean-Marc Valin <jean-marc.valin@hermes.usherb.ca>
|
||||
All the code except the following
|
||||
|
||||
David Rowe <david@voicetronix.com.au> via VoiceTronix
|
||||
lsp.c lsp.h
|
||||
Also ideas and feedback
|
||||
|
||||
John Francis Edwards:
|
||||
wave_out.[ch], some #ifdefs for windows port and MSVC project files
|
||||
|
||||
Atsuhiko Yamanaka <ymnk@jcraft.com>:
|
||||
Patch to speexenc.c to add Vorbis comment format
|
||||
|
||||
Radim Kolar <hsn@cybermail.net>:
|
||||
Patch to speexenc.c for supporting more input formats
|
@ -1,26 +0,0 @@
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions
|
||||
are met:
|
||||
|
||||
- Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
|
||||
- Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
|
||||
- Neither the name of the Xiph.org Foundation nor the names of its
|
||||
contributors may be used to endorse or promote products derived from
|
||||
this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR
|
||||
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
@ -1,6 +0,0 @@
|
||||
2002/03/27 Jean-Marc Valin:
|
||||
Working encoder and decoder for both narrowband and wideband.
|
||||
|
||||
2002/02/27 Jean-Marc Valin:
|
||||
Got the basic encoder working as a demo with quantization only on some
|
||||
parameters.
|
@ -1,35 +0,0 @@
|
||||
SubDir HAIKU_TOP src add-ons media plugins speex libspeex ;
|
||||
|
||||
SubDirCcFlags -DVERSION=\\\"1.0.3\\\" ;
|
||||
|
||||
StaticLibrary libspeex.a :
|
||||
nb_celp.c
|
||||
sb_celp.c
|
||||
lpc.c
|
||||
ltp.c
|
||||
lsp.c
|
||||
quant_lsp.c
|
||||
lsp_tables_nb.c
|
||||
gain_table.c
|
||||
gain_table_lbr.c
|
||||
cb_search.c
|
||||
filters.c
|
||||
bits.c
|
||||
modes.c
|
||||
vq.c
|
||||
high_lsp_tables.c
|
||||
vbr.c
|
||||
hexc_table.c
|
||||
exc_5_256_table.c
|
||||
exc_5_64_table.c
|
||||
exc_8_128_table.c
|
||||
exc_10_32_table.c
|
||||
exc_10_16_table.c
|
||||
exc_20_32_table.c
|
||||
hexc_10_32_table.c
|
||||
misc.c
|
||||
speex_header.c
|
||||
speex_callbacks.c
|
||||
math_approx.c
|
||||
stereo.c
|
||||
;
|
@ -1 +0,0 @@
|
||||
2002/02/13: Creation of the "Speex" project
|
@ -1,9 +0,0 @@
|
||||
See INSTALL file for instruction on how to install Speex.
|
||||
|
||||
The Speex is a patent-free, Open Source/Free Software voice codec. Unlike other codecs like MP3 and Ogg Vorbis, Speex is designed to compress voice at bitrates in the 2-45 kbps range. Possible applications include VoIP, internet audio streaming, archiving of speech data (e.g. voice mail), and audio books. In some sense, it is meant to be complementary to the Ogg Vorbis codec.
|
||||
|
||||
To use the Speex command line tools:
|
||||
|
||||
% speexenc [options] input_file.wav compressed_file.spx
|
||||
|
||||
% speexdec [options] compressed_file.spx output_file.wav
|
@ -1,18 +0,0 @@
|
||||
Features
|
||||
-Add maximum/minimum bit-rate control for VBR
|
||||
-Get the encoder to use the rate of packet loss (more conservative pitch gains)
|
||||
|
||||
Long-term quality improvements
|
||||
-Improve perceptual enhancement (including wideband)
|
||||
|
||||
Standards
|
||||
*Complete Speex RTP profile
|
||||
-MIME type registration
|
||||
-MS ACM wrapper
|
||||
|
||||
*required for 1.0
|
||||
|
||||
ideas:
|
||||
Peelable stream (double codebook, higher bands, stereo)
|
||||
LPC from spectral domain
|
||||
Better psycho-acoustics? Masking curve from Vorbis
|
@ -1,363 +0,0 @@
|
||||
/* Copyright (C) 2002 Jean-Marc Valin
|
||||
File: speex_bits.c
|
||||
|
||||
Handles bit packing/unpacking
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions
|
||||
are met:
|
||||
|
||||
- Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
|
||||
- Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
|
||||
- Neither the name of the Xiph.org Foundation nor the names of its
|
||||
contributors may be used to endorse or promote products derived from
|
||||
this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR
|
||||
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
*/
|
||||
|
||||
#include "speex_bits.h"
|
||||
#include "misc.h"
|
||||
|
||||
void speex_bits_init(SpeexBits *bits)
|
||||
{
|
||||
int i;
|
||||
bits->bytes = (char*)speex_alloc(MAX_BYTES_PER_FRAME);
|
||||
bits->buf_size = MAX_BYTES_PER_FRAME;
|
||||
|
||||
for (i=0;i<bits->buf_size;i++)
|
||||
bits->bytes[i]=0;
|
||||
bits->nbBits=0;
|
||||
bits->bytePtr=0;
|
||||
bits->bitPtr=0;
|
||||
bits->owner=1;
|
||||
bits->overflow=0;
|
||||
}
|
||||
|
||||
void speex_bits_init_buffer(SpeexBits *bits, void *buff, int buf_size)
|
||||
{
|
||||
int i;
|
||||
bits->bytes = (char*)buff;
|
||||
bits->buf_size = buf_size;
|
||||
|
||||
for (i=0;i<buf_size;i++)
|
||||
bits->bytes[i]=0;
|
||||
bits->nbBits=0;
|
||||
bits->bytePtr=0;
|
||||
bits->bitPtr=0;
|
||||
bits->owner=0;
|
||||
bits->overflow=0;
|
||||
}
|
||||
|
||||
void speex_bits_destroy(SpeexBits *bits)
|
||||
{
|
||||
if (bits->owner)
|
||||
speex_free(bits->bytes);
|
||||
/* Will do something once the allocation is dynamic */
|
||||
}
|
||||
|
||||
void speex_bits_reset(SpeexBits *bits)
|
||||
{
|
||||
int i;
|
||||
for (i=0;i<bits->buf_size;i++)
|
||||
bits->bytes[i]=0;
|
||||
bits->nbBits=0;
|
||||
bits->bytePtr=0;
|
||||
bits->bitPtr=0;
|
||||
bits->overflow=0;
|
||||
}
|
||||
|
||||
void speex_bits_rewind(SpeexBits *bits)
|
||||
{
|
||||
bits->bytePtr=0;
|
||||
bits->bitPtr=0;
|
||||
bits->overflow=0;
|
||||
}
|
||||
|
||||
void speex_bits_read_from(SpeexBits *bits, char *bytes, int len)
|
||||
{
|
||||
int i;
|
||||
if (len > bits->buf_size)
|
||||
{
|
||||
speex_warning_int("Packet is larger than allocated buffer: ", len);
|
||||
if (bits->owner)
|
||||
{
|
||||
char *tmp = (char*)speex_realloc(bits->bytes, len);
|
||||
if (tmp)
|
||||
{
|
||||
bits->buf_size=len;
|
||||
bits->bytes=tmp;
|
||||
} else {
|
||||
len=bits->buf_size;
|
||||
speex_warning("Could not resize input buffer: truncating input");
|
||||
}
|
||||
} else {
|
||||
speex_warning("Do not own input buffer: truncating input");
|
||||
len=bits->buf_size;
|
||||
}
|
||||
}
|
||||
for (i=0;i<len;i++)
|
||||
bits->bytes[i]=bytes[i];
|
||||
bits->nbBits=len<<3;
|
||||
bits->bytePtr=0;
|
||||
bits->bitPtr=0;
|
||||
bits->overflow=0;
|
||||
}
|
||||
|
||||
static void speex_bits_flush(SpeexBits *bits)
|
||||
{
|
||||
int i;
|
||||
if (bits->bytePtr>0)
|
||||
{
|
||||
for (i=bits->bytePtr;i<((bits->nbBits+7)>>3);i++)
|
||||
bits->bytes[i-bits->bytePtr]=bits->bytes[i];
|
||||
}
|
||||
bits->nbBits -= bits->bytePtr<<3;
|
||||
bits->bytePtr=0;
|
||||
}
|
||||
|
||||
void speex_bits_read_whole_bytes(SpeexBits *bits, char *bytes, int len)
|
||||
{
|
||||
int i,pos;
|
||||
|
||||
if ((bits->nbBits>>3)+len+1 > bits->buf_size)
|
||||
{
|
||||
speex_warning_int("Packet is larger than allocated buffer: ", len);
|
||||
if (bits->owner)
|
||||
{
|
||||
char *tmp = (char*)speex_realloc(bits->bytes, (bits->nbBits>>3)+len+1);
|
||||
if (tmp)
|
||||
{
|
||||
bits->buf_size=(bits->nbBits>>3)+len+1;
|
||||
bits->bytes=tmp;
|
||||
} else {
|
||||
len=bits->buf_size-(bits->nbBits>>3)-1;
|
||||
speex_warning("Could not resize input buffer: truncating input");
|
||||
}
|
||||
} else {
|
||||
speex_warning("Do not own input buffer: truncating input");
|
||||
len=bits->buf_size;
|
||||
}
|
||||
}
|
||||
|
||||
speex_bits_flush(bits);
|
||||
pos=bits->nbBits>>3;
|
||||
for (i=0;i<len;i++)
|
||||
bits->bytes[pos+i]=bytes[i];
|
||||
bits->nbBits+=len<<3;
|
||||
}
|
||||
|
||||
int speex_bits_write(SpeexBits *bits, char *bytes, int max_len)
|
||||
{
|
||||
int i;
|
||||
int bytePtr, bitPtr, nbBits;
|
||||
|
||||
/* Insert terminator, but save the data so we can put it back after */
|
||||
bitPtr=bits->bitPtr;
|
||||
bytePtr=bits->bytePtr;
|
||||
nbBits=bits->nbBits;
|
||||
speex_bits_insert_terminator(bits);
|
||||
bits->bitPtr=bitPtr;
|
||||
bits->bytePtr=bytePtr;
|
||||
bits->nbBits=nbBits;
|
||||
|
||||
if (max_len > ((bits->nbBits+7)>>3))
|
||||
max_len = ((bits->nbBits+7)>>3);
|
||||
for (i=0;i<max_len;i++)
|
||||
bytes[i]=bits->bytes[i];
|
||||
return max_len;
|
||||
}
|
||||
|
||||
int speex_bits_write_whole_bytes(SpeexBits *bits, char *bytes, int max_len)
|
||||
{
|
||||
int i;
|
||||
if (max_len > ((bits->nbBits)>>3))
|
||||
max_len = ((bits->nbBits)>>3);
|
||||
for (i=0;i<max_len;i++)
|
||||
bytes[i]=bits->bytes[i];
|
||||
|
||||
if (bits->bitPtr>0)
|
||||
bits->bytes[0]=bits->bytes[max_len];
|
||||
else
|
||||
bits->bytes[0]=0;
|
||||
for (i=1;i<((bits->nbBits)>>3)+1;i++)
|
||||
bits->bytes[i]=0;
|
||||
bits->bytePtr=0;
|
||||
bits->nbBits &= 7;
|
||||
return max_len;
|
||||
}
|
||||
|
||||
|
||||
void speex_bits_pack(SpeexBits *bits, int data, int nbBits)
|
||||
{
|
||||
int i;
|
||||
unsigned int d=data;
|
||||
|
||||
if (bits->bytePtr+((nbBits+bits->bitPtr)>>3) >= bits->buf_size)
|
||||
{
|
||||
speex_warning("Buffer too small to pack bits");
|
||||
if (bits->owner)
|
||||
{
|
||||
char *tmp = (char*)speex_realloc(bits->bytes, ((bits->buf_size+5)*3)>>1);
|
||||
if (tmp)
|
||||
{
|
||||
for (i=bits->buf_size;i<(((bits->buf_size+5)*3)>>1);i++)
|
||||
tmp[i]=0;
|
||||
bits->buf_size=((bits->buf_size+5)*3)>>1;
|
||||
bits->bytes=tmp;
|
||||
} else {
|
||||
speex_warning("Could not resize input buffer: not packing");
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
speex_warning("Do not own input buffer: not packing");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
while(nbBits)
|
||||
{
|
||||
int bit;
|
||||
bit = (d>>(nbBits-1))&1;
|
||||
bits->bytes[bits->bytePtr] |= bit<<(7-bits->bitPtr);
|
||||
bits->bitPtr++;
|
||||
|
||||
if (bits->bitPtr==8)
|
||||
{
|
||||
bits->bitPtr=0;
|
||||
bits->bytePtr++;
|
||||
}
|
||||
bits->nbBits++;
|
||||
nbBits--;
|
||||
}
|
||||
}
|
||||
|
||||
int speex_bits_unpack_signed(SpeexBits *bits, int nbBits)
|
||||
{
|
||||
unsigned int d=speex_bits_unpack_unsigned(bits,nbBits);
|
||||
/* If number is negative */
|
||||
if (d>>(nbBits-1))
|
||||
{
|
||||
d |= (-1)<<nbBits;
|
||||
}
|
||||
return d;
|
||||
}
|
||||
|
||||
unsigned int speex_bits_unpack_unsigned(SpeexBits *bits, int nbBits)
|
||||
{
|
||||
unsigned int d=0;
|
||||
if ((bits->bytePtr<<3)+bits->bitPtr+nbBits>bits->nbBits)
|
||||
bits->overflow=1;
|
||||
if (bits->overflow)
|
||||
return 0;
|
||||
while(nbBits)
|
||||
{
|
||||
d<<=1;
|
||||
d |= (bits->bytes[bits->bytePtr]>>(7-bits->bitPtr))&1;
|
||||
bits->bitPtr++;
|
||||
if (bits->bitPtr==8)
|
||||
{
|
||||
bits->bitPtr=0;
|
||||
bits->bytePtr++;
|
||||
}
|
||||
nbBits--;
|
||||
}
|
||||
return d;
|
||||
}
|
||||
|
||||
unsigned int speex_bits_peek_unsigned(SpeexBits *bits, int nbBits)
|
||||
{
|
||||
unsigned int d=0;
|
||||
int bitPtr, bytePtr;
|
||||
char *bytes;
|
||||
|
||||
if ((bits->bytePtr<<3)+bits->bitPtr+nbBits>bits->nbBits)
|
||||
bits->overflow=1;
|
||||
if (bits->overflow)
|
||||
return 0;
|
||||
|
||||
bitPtr=bits->bitPtr;
|
||||
bytePtr=bits->bytePtr;
|
||||
bytes = bits->bytes;
|
||||
while(nbBits)
|
||||
{
|
||||
d<<=1;
|
||||
d |= (bytes[bytePtr]>>(7-bitPtr))&1;
|
||||
bitPtr++;
|
||||
if (bitPtr==8)
|
||||
{
|
||||
bitPtr=0;
|
||||
bytePtr++;
|
||||
}
|
||||
nbBits--;
|
||||
}
|
||||
return d;
|
||||
}
|
||||
|
||||
int speex_bits_peek(SpeexBits *bits)
|
||||
{
|
||||
if ((bits->bytePtr<<3)+bits->bitPtr+1>bits->nbBits)
|
||||
bits->overflow=1;
|
||||
if (bits->overflow)
|
||||
return 0;
|
||||
return (bits->bytes[bits->bytePtr]>>(7-bits->bitPtr))&1;
|
||||
}
|
||||
|
||||
void speex_bits_advance(SpeexBits *bits, int n)
|
||||
{
|
||||
int nbytes, nbits;
|
||||
|
||||
if ((bits->bytePtr<<3)+bits->bitPtr+n>bits->nbBits)
|
||||
bits->overflow=1;
|
||||
if (bits->overflow)
|
||||
return;
|
||||
|
||||
nbytes = n >> 3;
|
||||
nbits = n & 7;
|
||||
|
||||
bits->bytePtr += nbytes;
|
||||
bits->bitPtr += nbits;
|
||||
|
||||
if (bits->bitPtr>7)
|
||||
{
|
||||
bits->bitPtr-=8;
|
||||
bits->bytePtr++;
|
||||
}
|
||||
}
|
||||
|
||||
int speex_bits_remaining(SpeexBits *bits)
|
||||
{
|
||||
if (bits->overflow)
|
||||
return -1;
|
||||
else
|
||||
return bits->nbBits-((bits->bytePtr<<3)+bits->bitPtr);
|
||||
}
|
||||
|
||||
int speex_bits_nbytes(SpeexBits *bits)
|
||||
{
|
||||
return ((bits->nbBits+7)>>3);
|
||||
}
|
||||
|
||||
void speex_bits_insert_terminator(SpeexBits *bits)
|
||||
{
|
||||
if (bits->bitPtr<7)
|
||||
speex_bits_pack(bits, 0, 1);
|
||||
while (bits->bitPtr<7)
|
||||
speex_bits_pack(bits, 1, 1);
|
||||
}
|
@ -1,387 +0,0 @@
|
||||
/* Copyright (C) 2002 Jean-Marc Valin
|
||||
File: cb_search.c
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions
|
||||
are met:
|
||||
|
||||
- Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
|
||||
- Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
|
||||
- Neither the name of the Xiph.org Foundation nor the names of its
|
||||
contributors may be used to endorse or promote products derived from
|
||||
this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR
|
||||
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
|
||||
#include "cb_search.h"
|
||||
#include "filters.h"
|
||||
#include "stack_alloc.h"
|
||||
#include "vq.h"
|
||||
#include "misc.h"
|
||||
|
||||
void split_cb_search_shape_sign(
|
||||
float target[], /* target vector */
|
||||
float ak[], /* LPCs for this subframe */
|
||||
float awk1[], /* Weighted LPCs for this subframe */
|
||||
float awk2[], /* Weighted LPCs for this subframe */
|
||||
void *par, /* Codebook/search parameters*/
|
||||
int p, /* number of LPC coeffs */
|
||||
int nsf, /* number of samples in subframe */
|
||||
float *exc,
|
||||
float *r,
|
||||
SpeexBits *bits,
|
||||
char *stack,
|
||||
int complexity
|
||||
)
|
||||
{
|
||||
int i,j,k,m,n,q;
|
||||
float *resp;
|
||||
float *t, *e, *E, *r2;
|
||||
float *tmp;
|
||||
float *ndist, *odist;
|
||||
int *itmp;
|
||||
float **ot, **nt;
|
||||
int **nind, **oind;
|
||||
int *ind;
|
||||
signed char *shape_cb;
|
||||
int shape_cb_size, subvect_size, nb_subvect;
|
||||
split_cb_params *params;
|
||||
int N=2;
|
||||
int *best_index;
|
||||
float *best_dist;
|
||||
int have_sign;
|
||||
|
||||
N=complexity;
|
||||
if (N>10)
|
||||
N=10;
|
||||
|
||||
ot=PUSH(stack, N, float*);
|
||||
nt=PUSH(stack, N, float*);
|
||||
oind=PUSH(stack, N, int*);
|
||||
nind=PUSH(stack, N, int*);
|
||||
|
||||
params = (split_cb_params *) par;
|
||||
subvect_size = params->subvect_size;
|
||||
nb_subvect = params->nb_subvect;
|
||||
shape_cb_size = 1<<params->shape_bits;
|
||||
shape_cb = params->shape_cb;
|
||||
have_sign = params->have_sign;
|
||||
resp = PUSH(stack, shape_cb_size*subvect_size, float);
|
||||
t = PUSH(stack, nsf, float);
|
||||
e = PUSH(stack, nsf, float);
|
||||
r2 = PUSH(stack, nsf, float);
|
||||
E = PUSH(stack, shape_cb_size, float);
|
||||
ind = PUSH(stack, nb_subvect, int);
|
||||
|
||||
tmp = PUSH(stack, 2*N*nsf, float);
|
||||
for (i=0;i<N;i++)
|
||||
{
|
||||
ot[i]=tmp;
|
||||
tmp += nsf;
|
||||
nt[i]=tmp;
|
||||
tmp += nsf;
|
||||
}
|
||||
|
||||
best_index = PUSH(stack, N, int);
|
||||
best_dist = PUSH(stack, N, float);
|
||||
ndist = PUSH(stack, N, float);
|
||||
odist = PUSH(stack, N, float);
|
||||
|
||||
itmp = PUSH(stack, 2*N*nb_subvect, int);
|
||||
for (i=0;i<N;i++)
|
||||
{
|
||||
nind[i]=itmp;
|
||||
itmp+=nb_subvect;
|
||||
oind[i]=itmp;
|
||||
itmp+=nb_subvect;
|
||||
for (j=0;j<nb_subvect;j++)
|
||||
nind[i][j]=oind[i][j]=-1;
|
||||
}
|
||||
|
||||
for (j=0;j<N;j++)
|
||||
for (i=0;i<nsf;i++)
|
||||
ot[j][i]=target[i];
|
||||
|
||||
for (i=0;i<nsf;i++)
|
||||
t[i]=target[i];
|
||||
|
||||
/* Pre-compute codewords response and energy */
|
||||
for (i=0;i<shape_cb_size;i++)
|
||||
{
|
||||
float *res;
|
||||
signed char *shape;
|
||||
|
||||
res = resp+i*subvect_size;
|
||||
shape = shape_cb+i*subvect_size;
|
||||
|
||||
/* Compute codeword response using convolution with impulse response */
|
||||
for(j=0;j<subvect_size;j++)
|
||||
{
|
||||
res[j]=0;
|
||||
for (k=0;k<=j;k++)
|
||||
res[j] += 0.03125*shape[k]*r[j-k];
|
||||
}
|
||||
|
||||
/* Compute codeword energy */
|
||||
E[i]=0;
|
||||
for(j=0;j<subvect_size;j++)
|
||||
E[i]+=res[j]*res[j];
|
||||
}
|
||||
|
||||
for (j=0;j<N;j++)
|
||||
odist[j]=0;
|
||||
/*For all subvectors*/
|
||||
for (i=0;i<nb_subvect;i++)
|
||||
{
|
||||
/*"erase" nbest list*/
|
||||
for (j=0;j<N;j++)
|
||||
ndist[j]=-1;
|
||||
|
||||
/*For all n-bests of previous subvector*/
|
||||
for (j=0;j<N;j++)
|
||||
{
|
||||
float *x=ot[j]+subvect_size*i;
|
||||
/*Find new n-best based on previous n-best j*/
|
||||
if (have_sign)
|
||||
vq_nbest_sign(x, resp, subvect_size, shape_cb_size, E, N, best_index, best_dist);
|
||||
else
|
||||
vq_nbest(x, resp, subvect_size, shape_cb_size, E, N, best_index, best_dist);
|
||||
|
||||
/*For all new n-bests*/
|
||||
for (k=0;k<N;k++)
|
||||
{
|
||||
float *ct;
|
||||
float err=0;
|
||||
ct = ot[j];
|
||||
/*update target*/
|
||||
|
||||
/*previous target*/
|
||||
for (m=i*subvect_size;m<(i+1)*subvect_size;m++)
|
||||
t[m]=ct[m];
|
||||
|
||||
/* New code: update only enough of the target to calculate error*/
|
||||
{
|
||||
int rind;
|
||||
float *res;
|
||||
float sign=1;
|
||||
rind = best_index[k];
|
||||
if (rind>=shape_cb_size)
|
||||
{
|
||||
sign=-1;
|
||||
rind-=shape_cb_size;
|
||||
}
|
||||
res = resp+rind*subvect_size;
|
||||
if (sign>0)
|
||||
for (m=0;m<subvect_size;m++)
|
||||
t[subvect_size*i+m] -= res[m];
|
||||
else
|
||||
for (m=0;m<subvect_size;m++)
|
||||
t[subvect_size*i+m] += res[m];
|
||||
}
|
||||
|
||||
/*compute error (distance)*/
|
||||
err=odist[j];
|
||||
for (m=i*subvect_size;m<(i+1)*subvect_size;m++)
|
||||
err += t[m]*t[m];
|
||||
/*update n-best list*/
|
||||
if (err<ndist[N-1] || ndist[N-1]<-.5)
|
||||
{
|
||||
|
||||
/*previous target (we don't care what happened before*/
|
||||
for (m=(i+1)*subvect_size;m<nsf;m++)
|
||||
t[m]=ct[m];
|
||||
/* New code: update the rest of the target only if it's worth it */
|
||||
for (m=0;m<subvect_size;m++)
|
||||
{
|
||||
float g;
|
||||
int rind;
|
||||
float sign=1;
|
||||
rind = best_index[k];
|
||||
if (rind>=shape_cb_size)
|
||||
{
|
||||
sign=-1;
|
||||
rind-=shape_cb_size;
|
||||
}
|
||||
|
||||
g=sign*0.03125*shape_cb[rind*subvect_size+m];
|
||||
q=subvect_size-m;
|
||||
for (n=subvect_size*(i+1);n<nsf;n++,q++)
|
||||
t[n] -= g*r[q];
|
||||
}
|
||||
|
||||
|
||||
for (m=0;m<N;m++)
|
||||
{
|
||||
if (err < ndist[m] || ndist[m]<-.5)
|
||||
{
|
||||
for (n=N-1;n>m;n--)
|
||||
{
|
||||
for (q=(i+1)*subvect_size;q<nsf;q++)
|
||||
nt[n][q]=nt[n-1][q];
|
||||
for (q=0;q<nb_subvect;q++)
|
||||
nind[n][q]=nind[n-1][q];
|
||||
ndist[n]=ndist[n-1];
|
||||
}
|
||||
for (q=(i+1)*subvect_size;q<nsf;q++)
|
||||
nt[m][q]=t[q];
|
||||
for (q=0;q<nb_subvect;q++)
|
||||
nind[m][q]=oind[j][q];
|
||||
nind[m][i]=best_index[k];
|
||||
ndist[m]=err;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (i==0)
|
||||
break;
|
||||
}
|
||||
|
||||
/*update old-new data*/
|
||||
/* just swap pointers instead of a long copy */
|
||||
{
|
||||
float **tmp2;
|
||||
tmp2=ot;
|
||||
ot=nt;
|
||||
nt=tmp2;
|
||||
}
|
||||
for (j=0;j<N;j++)
|
||||
for (m=0;m<nb_subvect;m++)
|
||||
oind[j][m]=nind[j][m];
|
||||
for (j=0;j<N;j++)
|
||||
odist[j]=ndist[j];
|
||||
}
|
||||
|
||||
/*save indices*/
|
||||
for (i=0;i<nb_subvect;i++)
|
||||
{
|
||||
ind[i]=nind[0][i];
|
||||
speex_bits_pack(bits,ind[i],params->shape_bits+have_sign);
|
||||
}
|
||||
|
||||
/* Put everything back together */
|
||||
for (i=0;i<nb_subvect;i++)
|
||||
{
|
||||
int rind;
|
||||
float sign=1;
|
||||
rind = ind[i];
|
||||
if (rind>=shape_cb_size)
|
||||
{
|
||||
sign=-1;
|
||||
rind-=shape_cb_size;
|
||||
}
|
||||
|
||||
for (j=0;j<subvect_size;j++)
|
||||
e[subvect_size*i+j]=sign*0.03125*shape_cb[rind*subvect_size+j];
|
||||
}
|
||||
/* Update excitation */
|
||||
for (j=0;j<nsf;j++)
|
||||
exc[j]+=e[j];
|
||||
|
||||
/* Update target */
|
||||
syn_percep_zero(e, ak, awk1, awk2, r2, nsf,p, stack);
|
||||
for (j=0;j<nsf;j++)
|
||||
target[j]-=r2[j];
|
||||
|
||||
}
|
||||
|
||||
|
||||
void split_cb_shape_sign_unquant(
|
||||
float *exc,
|
||||
void *par, /* non-overlapping codebook */
|
||||
int nsf, /* number of samples in subframe */
|
||||
SpeexBits *bits,
|
||||
char *stack
|
||||
)
|
||||
{
|
||||
int i,j;
|
||||
int *ind, *signs;
|
||||
signed char *shape_cb;
|
||||
int shape_cb_size, subvect_size, nb_subvect;
|
||||
split_cb_params *params;
|
||||
int have_sign;
|
||||
|
||||
params = (split_cb_params *) par;
|
||||
subvect_size = params->subvect_size;
|
||||
nb_subvect = params->nb_subvect;
|
||||
shape_cb_size = 1<<params->shape_bits;
|
||||
shape_cb = params->shape_cb;
|
||||
have_sign = params->have_sign;
|
||||
|
||||
ind = PUSH(stack, nb_subvect, int);
|
||||
signs = PUSH(stack, nb_subvect, int);
|
||||
|
||||
/* Decode codewords and gains */
|
||||
for (i=0;i<nb_subvect;i++)
|
||||
{
|
||||
if (have_sign)
|
||||
signs[i] = speex_bits_unpack_unsigned(bits, 1);
|
||||
else
|
||||
signs[i] = 0;
|
||||
ind[i] = speex_bits_unpack_unsigned(bits, params->shape_bits);
|
||||
}
|
||||
/* Compute decoded excitation */
|
||||
for (i=0;i<nb_subvect;i++)
|
||||
{
|
||||
float s=1;
|
||||
if (signs[i])
|
||||
s=-1;
|
||||
for (j=0;j<subvect_size;j++)
|
||||
exc[subvect_size*i+j]+=s*0.03125*shape_cb[ind[i]*subvect_size+j];
|
||||
}
|
||||
}
|
||||
|
||||
void noise_codebook_quant(
|
||||
float target[], /* target vector */
|
||||
float ak[], /* LPCs for this subframe */
|
||||
float awk1[], /* Weighted LPCs for this subframe */
|
||||
float awk2[], /* Weighted LPCs for this subframe */
|
||||
void *par, /* Codebook/search parameters*/
|
||||
int p, /* number of LPC coeffs */
|
||||
int nsf, /* number of samples in subframe */
|
||||
float *exc,
|
||||
float *r,
|
||||
SpeexBits *bits,
|
||||
char *stack,
|
||||
int complexity
|
||||
)
|
||||
{
|
||||
int i;
|
||||
float *tmp=PUSH(stack, nsf, float);
|
||||
residue_percep_zero(target, ak, awk1, awk2, tmp, nsf, p, stack);
|
||||
|
||||
for (i=0;i<nsf;i++)
|
||||
exc[i]+=tmp[i];
|
||||
for (i=0;i<nsf;i++)
|
||||
target[i]=0;
|
||||
|
||||
}
|
||||
|
||||
|
||||
void noise_codebook_unquant(
|
||||
float *exc,
|
||||
void *par, /* non-overlapping codebook */
|
||||
int nsf, /* number of samples in subframe */
|
||||
SpeexBits *bits,
|
||||
char *stack
|
||||
)
|
||||
{
|
||||
speex_rand_vec(1, exc, nsf);
|
||||
}
|
@ -1,95 +0,0 @@
|
||||
/* Copyright (C) 2002 Jean-Marc Valin & David Rowe
|
||||
File: cb_search.c
|
||||
Overlapped codebook search
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions
|
||||
are met:
|
||||
|
||||
- Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
|
||||
- Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
|
||||
- Neither the name of the Xiph.org Foundation nor the names of its
|
||||
contributors may be used to endorse or promote products derived from
|
||||
this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR
|
||||
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef CB_SEARCH_H
|
||||
#define CB_SEARCH_H
|
||||
|
||||
#include "speex_bits.h"
|
||||
|
||||
typedef struct split_cb_params {
|
||||
int subvect_size;
|
||||
int nb_subvect;
|
||||
signed char *shape_cb;
|
||||
int shape_bits;
|
||||
int have_sign;
|
||||
} split_cb_params;
|
||||
|
||||
|
||||
void split_cb_search_shape_sign(
|
||||
float target[], /* target vector */
|
||||
float ak[], /* LPCs for this subframe */
|
||||
float awk1[], /* Weighted LPCs for this subframe */
|
||||
float awk2[], /* Weighted LPCs for this subframe */
|
||||
void *par, /* Codebook/search parameters*/
|
||||
int p, /* number of LPC coeffs */
|
||||
int nsf, /* number of samples in subframe */
|
||||
float *exc,
|
||||
float *r,
|
||||
SpeexBits *bits,
|
||||
char *stack,
|
||||
int complexity
|
||||
);
|
||||
|
||||
void split_cb_shape_sign_unquant(
|
||||
float *exc,
|
||||
void *par, /* non-overlapping codebook */
|
||||
int nsf, /* number of samples in subframe */
|
||||
SpeexBits *bits,
|
||||
char *stack
|
||||
);
|
||||
|
||||
|
||||
void noise_codebook_quant(
|
||||
float target[], /* target vector */
|
||||
float ak[], /* LPCs for this subframe */
|
||||
float awk1[], /* Weighted LPCs for this subframe */
|
||||
float awk2[], /* Weighted LPCs for this subframe */
|
||||
void *par, /* Codebook/search parameters*/
|
||||
int p, /* number of LPC coeffs */
|
||||
int nsf, /* number of samples in subframe */
|
||||
float *exc,
|
||||
float *r,
|
||||
SpeexBits *bits,
|
||||
char *stack,
|
||||
int complexity
|
||||
);
|
||||
|
||||
|
||||
void noise_codebook_unquant(
|
||||
float *exc,
|
||||
void *par, /* non-overlapping codebook */
|
||||
int nsf, /* number of samples in subframe */
|
||||
SpeexBits *bits,
|
||||
char *stack
|
||||
);
|
||||
|
||||
#endif
|
@ -1,50 +0,0 @@
|
||||
/* Copyright (C) 2002 Jean-Marc Valin
|
||||
File: exc_10_16_table.c
|
||||
Codebook for excitation in narrowband CELP mode (3200 bps)
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions
|
||||
are met:
|
||||
|
||||
- Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
|
||||
- Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
|
||||
- Neither the name of the Xiph.org Foundation nor the names of its
|
||||
contributors may be used to endorse or promote products derived from
|
||||
this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR
|
||||
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
|
||||
signed char exc_10_16_table[160] = {
|
||||
22,39,14,44,11,35,-2,23,-4,6,
|
||||
46,-28,13,-27,-23,12,4,20,-5,9,
|
||||
37,-18,-23,23,0,9,-6,-20,4,-1,
|
||||
-17,-5,-4,17,0,1,9,-2,1,2,
|
||||
2,-12,8,-25,39,15,9,16,-55,-11,
|
||||
9,11,5,10,-2,-60,8,13,-6,11,
|
||||
-16,27,-47,-12,11,1,16,-7,9,-3,
|
||||
-29,9,-14,25,-19,34,36,12,40,-10,
|
||||
-3,-24,-14,-37,-21,-35,-2,-36,3,-6,
|
||||
67,28,6,-17,-3,-12,-16,-15,-17,-7,
|
||||
-59,-36,-13,1,7,1,2,10,2,11,
|
||||
13,10,8,-2,7,3,5,4,2,2,
|
||||
-3,-8,4,-5,6,7,-42,15,35,-2,
|
||||
-46,38,28,-20,-9,1,7,-3,0,-2,
|
||||
0,0,0,0,0,0,0,0,0,0,
|
||||
-15,-28,52,32,5,-5,-17,-20,-10,-1};
|
@ -1,66 +0,0 @@
|
||||
/* Copyright (C) 2002 Jean-Marc Valin
|
||||
File: exc_10_32_table.c
|
||||
Codebook for excitation in narrowband CELP mode (4000 bps)
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions
|
||||
are met:
|
||||
|
||||
- Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
|
||||
- Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
|
||||
- Neither the name of the Xiph.org Foundation nor the names of its
|
||||
contributors may be used to endorse or promote products derived from
|
||||
this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR
|
||||
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
|
||||
signed char exc_10_32_table[320] = {
|
||||
7,17,17,27,25,22,12,4,-3,0,
|
||||
28,-36,39,-24,-15,3,-9,15,-5,10,
|
||||
31,-28,11,31,-21,9,-11,-11,-2,-7,
|
||||
-25,14,-22,31,4,-14,19,-12,14,-5,
|
||||
4,-7,4,-5,9,0,-2,42,-47,-16,
|
||||
1,8,0,9,23,-57,0,28,-11,6,
|
||||
-31,55,-45,3,-5,4,2,-2,4,-7,
|
||||
-3,6,-2,7,-3,12,5,8,54,-10,
|
||||
8,-7,-8,-24,-25,-27,-14,-5,8,5,
|
||||
44,23,5,-9,-11,-11,-13,-9,-12,-8,
|
||||
-29,-8,-22,6,-15,3,-12,-1,-5,-3,
|
||||
34,-1,29,-16,17,-4,12,2,1,4,
|
||||
-2,-4,2,-1,11,-3,-52,28,30,-9,
|
||||
-32,25,44,-20,-24,4,6,-1,0,0,
|
||||
0,0,0,0,0,0,0,0,0,0,
|
||||
-25,-10,22,29,13,-13,-22,-13,-4,0,
|
||||
-4,-16,10,15,-36,-24,28,25,-1,-3,
|
||||
66,-33,-11,-15,6,0,3,4,-2,5,
|
||||
24,-20,-47,29,19,-2,-4,-1,0,-1,
|
||||
-2,3,1,8,-11,5,5,-57,28,28,
|
||||
0,-16,4,-4,12,-6,-1,2,-20,61,
|
||||
-9,24,-22,-42,29,6,17,8,4,2,
|
||||
-65,15,8,10,5,6,5,3,2,-2,
|
||||
-3,5,-9,4,-5,23,13,23,-3,-63,
|
||||
3,-5,-4,-6,0,-3,23,-36,-46,9,
|
||||
5,5,8,4,9,-5,1,-3,10,1,
|
||||
-6,10,-11,24,-47,31,22,-12,14,-10,
|
||||
6,11,-7,-7,7,-31,51,-12,-6,7,
|
||||
6,-17,9,-11,-20,52,-19,3,-6,-6,
|
||||
-8,-5,23,-41,37,1,-21,10,-14,8,
|
||||
7,5,-15,-15,23,39,-26,-33,7,2,
|
||||
-32,-30,-21,-8,4,12,17,15,14,11};
|
@ -1,66 +0,0 @@
|
||||
/* Copyright (C) 2002 Jean-Marc Valin
|
||||
File: exc_20_32_table.c
|
||||
Codebook for excitation in narrowband CELP mode (2000 bps)
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions
|
||||
are met:
|
||||
|
||||
- Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
|
||||
- Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
|
||||
- Neither the name of the Xiph.org Foundation nor the names of its
|
||||
contributors may be used to endorse or promote products derived from
|
||||
this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR
|
||||
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
|
||||
signed char exc_20_32_table[640] = {
|
||||
12,32,25,46,36,33,9,14,-3,6,1,-8,0,-10,-5,-7,-7,-7,-5,-5,
|
||||
31,-27,24,-32,-4,10,-11,21,-3,19,23,-9,22,24,-10,-1,-10,-13,-7,-11,
|
||||
42,-33,31,19,-8,0,-10,-16,1,-21,-17,10,-8,14,8,4,11,-2,5,-2,
|
||||
-33,11,-16,33,11,-4,9,-4,11,2,6,-5,8,-5,11,-4,-6,26,-36,-16,
|
||||
0,4,-2,-8,12,6,-1,34,-46,-22,9,9,21,9,5,-66,-5,26,2,10,
|
||||
13,2,19,9,12,-81,3,13,13,0,-14,22,-35,6,-7,-4,6,-6,10,-6,
|
||||
-31,38,-33,0,-10,-11,5,-12,12,-17,5,0,-6,13,-9,10,8,25,33,2,
|
||||
-12,8,-6,10,-2,21,7,17,43,5,11,-7,-9,-20,-36,-20,-23,-4,-4,-3,
|
||||
27,-9,-9,-49,-39,-38,-11,-9,6,5,23,25,5,3,3,4,1,2,-3,-1,
|
||||
87,39,17,-21,-9,-19,-9,-15,-13,-14,-17,-11,-10,-11,-8,-6,-1,-3,-3,-1,
|
||||
-54,-34,-27,-8,-11,-4,-5,0,0,4,8,6,9,7,9,7,6,5,5,5,
|
||||
48,10,19,-10,12,-1,9,-3,2,5,-3,2,-2,-2,0,-2,-26,6,9,-7,
|
||||
-16,-9,2,7,7,-5,-43,11,22,-11,-9,34,37,-15,-13,-6,1,-1,1,1,
|
||||
-64,56,52,-11,-27,5,4,3,1,2,1,3,-1,-4,-4,-10,-7,-4,-4,2,
|
||||
-1,-7,-7,-12,-10,-15,-9,-5,-5,-11,-16,-13,6,16,4,-13,-16,-10,-4,2,
|
||||
-47,-13,25,47,19,-14,-20,-8,-17,0,-3,-13,1,6,-17,-14,15,1,10,6,
|
||||
-24,0,-10,19,-69,-8,14,49,17,-5,33,-29,3,-4,0,2,-8,5,-6,2,
|
||||
120,-56,-12,-47,23,-9,6,-5,1,2,-5,1,-10,4,-1,-1,4,-1,0,-3,
|
||||
30,-52,-67,30,22,11,-1,-4,3,0,7,2,0,1,-10,-4,-8,-13,5,1,
|
||||
1,-1,5,13,-9,-3,-10,-62,22,48,-4,-6,2,3,5,1,1,4,1,13,
|
||||
3,-20,10,-9,13,-2,-4,9,-20,44,-1,20,-32,-67,19,0,28,11,8,2,
|
||||
-11,15,-19,-53,31,2,34,10,6,-4,-58,8,10,13,14,1,12,2,0,0,
|
||||
-128,37,-8,44,-9,26,-3,18,2,6,11,-1,9,1,5,3,0,1,1,2,
|
||||
12,3,-2,-3,7,25,9,18,-6,-37,3,-8,-16,3,-10,-7,17,-34,-44,11,
|
||||
17,-15,-3,-16,-1,-13,11,-46,-65,-2,8,13,2,4,4,5,15,5,9,6,
|
||||
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
||||
-9,19,-12,12,-28,38,29,-1,12,2,5,23,-10,3,4,-15,21,-4,3,3,
|
||||
6,17,-9,-4,-8,-20,26,5,-10,6,1,-19,18,-15,-12,47,-6,-2,-7,-9,
|
||||
-1,-17,-2,-2,-14,30,-14,2,-7,-4,-1,-12,11,-25,16,-3,-12,11,-7,7,
|
||||
-17,1,19,-28,31,-7,-10,7,-10,3,12,5,-16,6,24,41,-29,-54,0,1,
|
||||
7,-1,5,-6,13,10,-4,-8,8,-9,-27,-53,-38,-1,10,19,17,16,12,12,
|
||||
0,3,-7,-4,13,12,-31,-14,6,-5,3,5,17,43,50,25,10,1,-6,-2};
|
@ -1,290 +0,0 @@
|
||||
/* Copyright (C) 2002 Jean-Marc Valin
|
||||
File: exc_5_256_table.c
|
||||
Codebook for excitation in narrowband CELP mode (12800 bps)
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions
|
||||
are met:
|
||||
|
||||
- Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
|
||||
- Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
|
||||
- Neither the name of the Xiph.org Foundation nor the names of its
|
||||
contributors may be used to endorse or promote products derived from
|
||||
this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR
|
||||
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
|
||||
signed char exc_5_256_table[1280] = {
|
||||
-8,-37,5,-43,5,
|
||||
73,61,39,12,-3,
|
||||
-61,-32,2,42,30,
|
||||
-3,17,-27,9,34,
|
||||
20,-1,-5,2,23,
|
||||
-7,-46,26,53,-47,
|
||||
20,-2,-33,-89,-51,
|
||||
-64,27,11,15,-34,
|
||||
-5,-56,25,-9,-1,
|
||||
-29,1,40,67,-23,
|
||||
-16,16,33,19,7,
|
||||
14,85,22,-10,-10,
|
||||
-12,-7,-1,52,89,
|
||||
29,11,-20,-37,-46,
|
||||
-15,17,-24,-28,24,
|
||||
2,1,0,23,-101,
|
||||
23,14,-1,-23,-18,
|
||||
9,5,-13,38,1,
|
||||
-28,-28,4,27,51,
|
||||
-26,34,-40,35,47,
|
||||
54,38,-54,-26,-6,
|
||||
42,-25,13,-30,-36,
|
||||
18,41,-4,-33,23,
|
||||
-32,-7,-4,51,-3,
|
||||
17,-52,56,-47,36,
|
||||
-2,-21,36,10,8,
|
||||
-33,31,19,9,-5,
|
||||
-40,10,-9,-21,19,
|
||||
18,-78,-18,-5,0,
|
||||
-26,-36,-47,-51,-44,
|
||||
18,40,27,-2,29,
|
||||
49,-26,2,32,-54,
|
||||
30,-73,54,3,-5,
|
||||
36,22,53,10,-1,
|
||||
-84,-53,-29,-5,3,
|
||||
-44,53,-51,4,22,
|
||||
71,-35,-1,33,-5,
|
||||
-27,-7,36,17,-23,
|
||||
-39,16,-9,-55,-15,
|
||||
-20,39,-35,6,-39,
|
||||
-14,18,48,-64,-17,
|
||||
-15,9,39,81,37,
|
||||
-68,37,47,-21,-6,
|
||||
-104,13,6,9,-2,
|
||||
35,8,-23,18,42,
|
||||
45,21,33,-5,-49,
|
||||
9,-6,-43,-56,39,
|
||||
2,-16,-25,87,1,
|
||||
-3,-9,17,-25,-11,
|
||||
-9,-1,10,2,-14,
|
||||
-14,4,-1,-10,28,
|
||||
-23,40,-32,26,-9,
|
||||
26,4,-27,-23,3,
|
||||
42,-60,1,49,-3,
|
||||
27,10,-52,-40,-2,
|
||||
18,45,-23,17,-44,
|
||||
3,-3,17,-46,52,
|
||||
-40,-47,25,75,31,
|
||||
-49,53,30,-30,-32,
|
||||
-36,38,-6,-15,-16,
|
||||
54,-27,-48,3,38,
|
||||
-29,-32,-22,-14,-4,
|
||||
-23,-13,32,-39,9,
|
||||
8,-45,-13,34,-16,
|
||||
49,40,32,31,28,
|
||||
23,23,32,47,59,
|
||||
-68,8,62,44,25,
|
||||
-14,-24,-65,-16,36,
|
||||
67,-25,-38,-21,4,
|
||||
-33,-2,42,5,-63,
|
||||
40,11,26,-42,-23,
|
||||
-61,79,-31,23,-20,
|
||||
10,-32,53,-25,-36,
|
||||
10,-26,-5,3,0,
|
||||
-71,5,-10,-37,1,
|
||||
-24,21,-54,-17,1,
|
||||
-29,-25,-15,-27,32,
|
||||
68,45,-16,-37,-18,
|
||||
-5,1,0,-77,71,
|
||||
-6,3,-20,71,-67,
|
||||
29,-35,10,-30,19,
|
||||
4,16,17,5,0,
|
||||
-14,19,2,28,26,
|
||||
59,3,2,24,39,
|
||||
55,-50,-45,-18,-17,
|
||||
33,-35,14,-1,1,
|
||||
8,87,-35,-29,0,
|
||||
-27,13,-7,23,-13,
|
||||
37,-40,50,-35,14,
|
||||
19,-7,-14,49,54,
|
||||
-5,22,-2,-29,-8,
|
||||
-27,38,13,27,48,
|
||||
12,-41,-21,-15,28,
|
||||
7,-16,-24,-19,-20,
|
||||
11,-20,9,2,13,
|
||||
23,-20,11,27,-27,
|
||||
71,-69,8,2,-6,
|
||||
22,12,16,16,9,
|
||||
-16,-8,-17,1,25,
|
||||
1,40,-37,-33,66,
|
||||
94,53,4,-22,-25,
|
||||
-41,-42,25,35,-16,
|
||||
-15,57,31,-29,-32,
|
||||
21,16,-60,45,15,
|
||||
-1,7,57,-26,-47,
|
||||
-29,11,8,15,19,
|
||||
-105,-8,54,27,10,
|
||||
-17,6,-12,-1,-10,
|
||||
4,0,23,-10,31,
|
||||
13,11,10,12,-64,
|
||||
23,-3,-8,-19,16,
|
||||
52,24,-40,16,10,
|
||||
40,5,9,0,-13,
|
||||
-7,-21,-8,-6,-7,
|
||||
-21,59,16,-53,18,
|
||||
-60,11,-47,14,-18,
|
||||
25,-13,-24,4,-39,
|
||||
16,-28,54,26,-67,
|
||||
30,27,-20,-52,20,
|
||||
-12,55,12,18,-16,
|
||||
39,-14,-6,-26,56,
|
||||
-88,-55,12,25,26,
|
||||
-37,6,75,0,-34,
|
||||
-81,54,-30,1,-7,
|
||||
49,-23,-14,21,10,
|
||||
-62,-58,-57,-47,-34,
|
||||
15,-4,34,-78,31,
|
||||
25,-11,7,50,-10,
|
||||
42,-63,14,-36,-4,
|
||||
57,55,57,53,42,
|
||||
-42,-1,15,40,37,
|
||||
15,25,-11,6,1,
|
||||
31,-2,-6,-1,-7,
|
||||
-64,34,28,30,-1,
|
||||
3,21,0,-88,-12,
|
||||
-56,25,-28,40,8,
|
||||
-28,-14,9,12,2,
|
||||
-6,-17,22,49,-6,
|
||||
-26,14,28,-20,4,
|
||||
-12,50,35,40,13,
|
||||
-38,-58,-29,17,30,
|
||||
22,60,26,-54,-39,
|
||||
-12,58,-28,-63,10,
|
||||
-21,-8,-12,26,-62,
|
||||
6,-10,-11,-22,-6,
|
||||
-7,4,1,18,2,
|
||||
-70,11,14,4,13,
|
||||
19,-24,-34,24,67,
|
||||
17,51,-21,13,23,
|
||||
54,-30,48,1,-13,
|
||||
80,26,-16,-2,13,
|
||||
-4,6,-30,29,-24,
|
||||
73,-58,30,-27,20,
|
||||
-2,-21,41,45,30,
|
||||
-27,-3,-5,-18,-20,
|
||||
-49,-3,-35,10,42,
|
||||
-19,-67,-53,-11,9,
|
||||
13,-15,-33,-51,-30,
|
||||
15,7,25,-30,4,
|
||||
28,-22,-34,54,-29,
|
||||
39,-46,20,16,34,
|
||||
-4,47,75,1,-44,
|
||||
-55,-24,7,-1,9,
|
||||
-42,50,-8,-36,41,
|
||||
68,0,-4,-10,-23,
|
||||
-15,-50,64,36,-9,
|
||||
-27,12,25,-38,-47,
|
||||
-37,32,-49,51,-36,
|
||||
2,-4,69,-26,19,
|
||||
7,45,67,46,13,
|
||||
-63,46,15,-47,4,
|
||||
-41,13,-6,5,-21,
|
||||
37,26,-55,-7,33,
|
||||
-1,-28,10,-17,-64,
|
||||
-14,0,-36,-17,93,
|
||||
-3,-9,-66,44,-21,
|
||||
3,-12,38,-6,-13,
|
||||
-12,19,13,43,-43,
|
||||
-10,-12,6,-5,9,
|
||||
-49,32,-5,2,4,
|
||||
5,15,-16,10,-21,
|
||||
8,-62,-8,64,8,
|
||||
79,-1,-66,-49,-18,
|
||||
5,40,-5,-30,-45,
|
||||
1,-6,21,-32,93,
|
||||
-18,-30,-21,32,21,
|
||||
-18,22,8,5,-41,
|
||||
-54,80,22,-10,-7,
|
||||
-8,-23,-64,66,56,
|
||||
-14,-30,-41,-46,-14,
|
||||
-29,-37,27,-14,42,
|
||||
-2,-9,-29,34,14,
|
||||
33,-14,22,4,10,
|
||||
26,26,28,32,23,
|
||||
-72,-32,3,0,-14,
|
||||
35,-42,-78,-32,6,
|
||||
29,-18,-45,-5,7,
|
||||
-33,-45,-3,-22,-34,
|
||||
8,-8,4,-51,-25,
|
||||
-9,59,-78,21,-5,
|
||||
-25,-48,66,-15,-17,
|
||||
-24,-49,-13,25,-23,
|
||||
-64,-6,40,-24,-19,
|
||||
-11,57,-33,-8,1,
|
||||
10,-52,-54,28,39,
|
||||
49,34,-11,-61,-41,
|
||||
-43,10,15,-15,51,
|
||||
30,15,-51,32,-34,
|
||||
-2,-34,14,18,16,
|
||||
1,1,-3,-3,1,
|
||||
1,-18,6,16,48,
|
||||
12,-5,-42,7,36,
|
||||
48,7,-20,-10,7,
|
||||
12,2,54,39,-38,
|
||||
37,54,4,-11,-8,
|
||||
-46,-10,5,-10,-34,
|
||||
46,-12,29,-37,39,
|
||||
36,-11,24,56,17,
|
||||
14,20,25,0,-25,
|
||||
-28,55,-7,-5,27,
|
||||
3,9,-26,-8,6,
|
||||
-24,-10,-30,-31,-34,
|
||||
18,4,22,21,40,
|
||||
-1,-29,-37,-8,-21,
|
||||
92,-29,11,-3,11,
|
||||
73,23,22,7,4,
|
||||
-44,-9,-11,21,-13,
|
||||
11,9,-78,-1,47,
|
||||
114,-12,-37,-19,-5,
|
||||
-11,-22,19,12,-30,
|
||||
7,38,45,-21,-8,
|
||||
-9,55,-45,56,-21,
|
||||
7,17,46,-57,-87,
|
||||
-6,27,31,31,7,
|
||||
-56,-12,46,21,-5,
|
||||
-12,36,3,3,-21,
|
||||
43,19,12,-7,9,
|
||||
-14,0,-9,-33,-91,
|
||||
7,26,3,-11,64,
|
||||
83,-31,-46,25,2,
|
||||
9,5,2,2,-1,
|
||||
20,-17,10,-5,-27,
|
||||
-8,20,8,-19,16,
|
||||
-21,-13,-31,5,5,
|
||||
42,24,9,34,-20,
|
||||
28,-61,22,11,-39,
|
||||
64,-20,-1,-30,-9,
|
||||
-20,24,-25,-24,-29,
|
||||
22,-60,6,-5,41,
|
||||
-9,-87,14,34,15,
|
||||
-57,52,69,15,-3,
|
||||
-102,58,16,3,6,
|
||||
60,-75,-32,26,7,
|
||||
-57,-27,-32,-24,-21,
|
||||
-29,-16,62,-46,31,
|
||||
30,-27,-15,7,15};
|
@ -1,98 +0,0 @@
|
||||
/* Copyright (C) 2002 Jean-Marc Valin
|
||||
File: exc_5_64_table.c
|
||||
Codebook for excitation in narrowband CELP mode (9600 bps)
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions
|
||||
are met:
|
||||
|
||||
- Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
|
||||
- Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
|
||||
- Neither the name of the Xiph.org Foundation nor the names of its
|
||||
contributors may be used to endorse or promote products derived from
|
||||
this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR
|
||||
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
|
||||
signed char exc_5_64_table[320]={
|
||||
1,5,-15,49,-66,
|
||||
-48,-4,50,-44,7,
|
||||
37,16,-18,25,-26,
|
||||
-26,-15,19,19,-27,
|
||||
-47,28,57,5,-17,
|
||||
-32,-41,68,21,-2,
|
||||
64,56,8,-16,-13,
|
||||
-26,-9,-16,11,6,
|
||||
-39,25,-19,22,-31,
|
||||
20,-45,55,-43,10,
|
||||
-16,47,-40,40,-20,
|
||||
-51,3,-17,-14,-15,
|
||||
-24,53,-20,-46,46,
|
||||
27,-68,32,3,-18,
|
||||
-5,9,-31,16,-9,
|
||||
-10,-1,-23,48,95,
|
||||
47,25,-41,-32,-3,
|
||||
15,-25,-55,36,41,
|
||||
-27,20,5,13,14,
|
||||
-22,5,2,-23,18,
|
||||
46,-15,17,-18,-34,
|
||||
-5,-8,27,-55,73,
|
||||
16,2,-1,-17,40,
|
||||
-78,33,0,2,19,
|
||||
4,53,-16,-15,-16,
|
||||
-28,-3,-13,49,8,
|
||||
-7,-29,27,-13,32,
|
||||
20,32,-61,16,14,
|
||||
41,44,40,24,20,
|
||||
7,4,48,-60,-77,
|
||||
17,-6,-48,65,-15,
|
||||
32,-30,-71,-10,-3,
|
||||
-6,10,-2,-7,-29,
|
||||
-56,67,-30,7,-5,
|
||||
86,-6,-10,0,5,
|
||||
-31,60,34,-38,-3,
|
||||
24,10,-2,30,23,
|
||||
24,-41,12,70,-43,
|
||||
15,-17,6,13,16,
|
||||
-13,8,30,-15,-8,
|
||||
5,23,-34,-98,-4,
|
||||
-13,13,-48,-31,70,
|
||||
12,31,25,24,-24,
|
||||
26,-7,33,-16,8,
|
||||
5,-11,-14,-8,-65,
|
||||
13,10,-2,-9,0,
|
||||
-3,-68,5,35,7,
|
||||
0,-31,-1,-17,-9,
|
||||
-9,16,-37,-18,-1,
|
||||
69,-48,-28,22,-21,
|
||||
-11,5,49,55,23,
|
||||
-86,-36,16,2,13,
|
||||
63,-51,30,-11,13,
|
||||
24,-18,-6,14,-19,
|
||||
1,41,9,-5,27,
|
||||
-36,-44,-34,-37,-21,
|
||||
-26,31,-39,15,43,
|
||||
5,-8,29,20,-8,
|
||||
-20,-52,-28,-1,13,
|
||||
26,-34,-10,-9,27,
|
||||
-8,8,27,-66,4,
|
||||
12,-22,49,10,-77,
|
||||
32,-18,3,-38,12,
|
||||
-3,-1,2,2,0};
|
@ -1,162 +0,0 @@
|
||||
/* Copyright (C) 2002 Jean-Marc Valin
|
||||
File: exc_8_128_table.c
|
||||
Codebook for excitation in narrowband CELP mode (7000 bps)
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions
|
||||
are met:
|
||||
|
||||
- Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
|
||||
- Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
|
||||
- Neither the name of the Xiph.org Foundation nor the names of its
|
||||
contributors may be used to endorse or promote products derived from
|
||||
this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR
|
||||
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
|
||||
signed char exc_8_128_table[1024] = {
|
||||
-14,9,13,-32,2,-10,31,-10,
|
||||
-8,-8,6,-4,-1,10,-64,23,
|
||||
6,20,13,6,8,-22,16,34,
|
||||
7,42,-49,-28,5,26,4,-15,
|
||||
41,34,41,32,33,24,23,14,
|
||||
8,40,34,4,-24,-41,-19,-15,
|
||||
13,-13,33,-54,24,27,-44,33,
|
||||
27,-15,-15,24,-19,14,-36,14,
|
||||
-9,24,-12,-4,37,-5,16,-34,
|
||||
5,10,33,-15,-54,-16,12,25,
|
||||
12,1,2,0,3,-1,-4,-4,
|
||||
11,2,-56,54,27,-20,13,-6,
|
||||
-46,-41,-33,-11,-5,7,12,14,
|
||||
-14,-5,8,20,6,3,4,-8,
|
||||
-5,-42,11,8,-14,25,-2,2,
|
||||
13,11,-22,39,-9,9,5,-45,
|
||||
-9,7,-9,12,-7,34,-17,-102,
|
||||
7,2,-42,18,35,-9,-34,11,
|
||||
-5,-2,3,22,46,-52,-25,-9,
|
||||
-94,8,11,-5,-5,-5,4,-7,
|
||||
-35,-7,54,5,-32,3,24,-9,
|
||||
-22,8,65,37,-1,-12,-23,-6,
|
||||
-9,-28,55,-33,14,-3,2,18,
|
||||
-60,41,-17,8,-16,17,-11,0,
|
||||
-11,29,-28,37,9,-53,33,-14,
|
||||
-9,7,-25,-7,-11,26,-32,-8,
|
||||
24,-21,22,-19,19,-10,29,-14,
|
||||
0,0,0,0,0,0,0,0,
|
||||
-5,-52,10,41,6,-30,-4,16,
|
||||
32,22,-27,-22,32,-3,-28,-3,
|
||||
3,-35,6,17,23,21,8,2,
|
||||
4,-45,-17,14,23,-4,-31,-11,
|
||||
-3,14,1,19,-11,2,61,-8,
|
||||
9,-12,7,-10,12,-3,-24,99,
|
||||
-48,23,50,-37,-5,-23,0,8,
|
||||
-14,35,-64,-5,46,-25,13,-1,
|
||||
-49,-19,-15,9,34,50,25,11,
|
||||
-6,-9,-16,-20,-32,-33,-32,-27,
|
||||
10,-8,12,-15,56,-14,-32,33,
|
||||
3,-9,1,65,-9,-9,-10,-2,
|
||||
-6,-23,9,17,3,-28,13,-32,
|
||||
4,-2,-10,4,-16,76,12,-52,
|
||||
6,13,33,-6,4,-14,-9,-3,
|
||||
1,-15,-16,28,1,-15,11,16,
|
||||
9,4,-21,-37,-40,-6,22,12,
|
||||
-15,-23,-14,-17,-16,-9,-10,-9,
|
||||
13,-39,41,5,-9,16,-38,25,
|
||||
46,-47,4,49,-14,17,-2,6,
|
||||
18,5,-6,-33,-22,44,50,-2,
|
||||
1,3,-6,7,7,-3,-21,38,
|
||||
-18,34,-14,-41,60,-13,6,16,
|
||||
-24,35,19,-13,-36,24,3,-17,
|
||||
-14,-10,36,44,-44,-29,-3,3,
|
||||
-54,-8,12,55,26,4,-2,-5,
|
||||
2,-11,22,-23,2,22,1,-25,
|
||||
-39,66,-49,21,-8,-2,10,-14,
|
||||
-60,25,6,10,27,-25,16,5,
|
||||
-2,-9,26,-13,-20,58,-2,7,
|
||||
52,-9,2,5,-4,-15,23,-1,
|
||||
-38,23,8,27,-6,0,-27,-7,
|
||||
39,-10,-14,26,11,-45,-12,9,
|
||||
-5,34,4,-35,10,43,-22,-11,
|
||||
56,-7,20,1,10,1,-26,9,
|
||||
94,11,-27,-14,-13,1,-11,0,
|
||||
14,-5,-6,-10,-4,-15,-8,-41,
|
||||
21,-5,1,-28,-8,22,-9,33,
|
||||
-23,-4,-4,-12,39,4,-7,3,
|
||||
-60,80,8,-17,2,-6,12,-5,
|
||||
1,9,15,27,31,30,27,23,
|
||||
61,47,26,10,-5,-8,-12,-13,
|
||||
5,-18,25,-15,-4,-15,-11,12,
|
||||
-2,-2,-16,-2,-6,24,12,11,
|
||||
-4,9,1,-9,14,-45,57,12,
|
||||
20,-35,26,11,-64,32,-10,-10,
|
||||
42,-4,-9,-16,32,24,7,10,
|
||||
52,-11,-57,29,0,8,0,-6,
|
||||
17,-17,-56,-40,7,20,18,12,
|
||||
-6,16,5,7,-1,9,1,10,
|
||||
29,12,16,13,-2,23,7,9,
|
||||
-3,-4,-5,18,-64,13,55,-25,
|
||||
9,-9,24,14,-25,15,-11,-40,
|
||||
-30,37,1,-19,22,-5,-31,13,
|
||||
-2,0,7,-4,16,-67,12,66,
|
||||
-36,24,-8,18,-15,-23,19,0,
|
||||
-45,-7,4,3,-13,13,35,5,
|
||||
13,33,10,27,23,0,-7,-11,
|
||||
43,-74,36,-12,2,5,-8,6,
|
||||
-33,11,-16,-14,-5,-7,-3,17,
|
||||
-34,27,-16,11,-9,15,33,-31,
|
||||
8,-16,7,-6,-7,63,-55,-17,
|
||||
11,-1,20,-46,34,-30,6,9,
|
||||
19,28,-9,5,-24,-8,-23,-2,
|
||||
31,-19,-16,-5,-15,-18,0,26,
|
||||
18,37,-5,-15,-2,17,5,-27,
|
||||
21,-33,44,12,-27,-9,17,11,
|
||||
25,-21,-31,-7,13,33,-8,-25,
|
||||
-7,7,-10,4,-6,-9,48,-82,
|
||||
-23,-8,6,11,-23,3,-3,49,
|
||||
-29,25,31,4,14,16,9,-4,
|
||||
-18,10,-26,3,5,-44,-9,9,
|
||||
-47,-55,15,9,28,1,4,-3,
|
||||
46,6,-6,-38,-29,-31,-15,-6,
|
||||
3,0,14,-6,8,-54,-50,33,
|
||||
-5,1,-14,33,-48,26,-4,-5,
|
||||
-3,-5,-3,-5,-28,-22,77,55,
|
||||
-1,2,10,10,-9,-14,-66,-49,
|
||||
11,-36,-6,-20,10,-10,16,12,
|
||||
4,-1,-16,45,-44,-50,31,-2,
|
||||
25,42,23,-32,-22,0,11,20,
|
||||
-40,-35,-40,-36,-32,-26,-21,-13,
|
||||
52,-22,6,-24,-20,17,-5,-8,
|
||||
36,-25,-11,21,-26,6,34,-8,
|
||||
7,20,-3,5,-25,-8,18,-5,
|
||||
-9,-4,1,-9,20,20,39,48,
|
||||
-24,9,5,-65,22,29,4,3,
|
||||
-43,-11,32,-6,9,19,-27,-10,
|
||||
-47,-14,24,10,-7,-36,-7,-1,
|
||||
-4,-5,-5,16,53,25,-26,-29,
|
||||
-4,-12,45,-58,-34,33,-5,2,
|
||||
-1,27,-48,31,-15,22,-5,4,
|
||||
7,7,-25,-3,11,-22,16,-12,
|
||||
8,-3,7,-11,45,14,-73,-19,
|
||||
56,-46,24,-20,28,-12,-2,-1,
|
||||
-36,-3,-33,19,-6,7,2,-15,
|
||||
5,-31,-45,8,35,13,20,0,
|
||||
-9,48,-13,-43,-3,-13,2,-5,
|
||||
72,-68,-27,2,1,-2,-7,5,
|
||||
36,33,-40,-12,-4,-5,23,19};
|
@ -1,292 +0,0 @@
|
||||
/* Copyright (C) 2002 Jean-Marc Valin
|
||||
File: filters.c
|
||||
Various analysis/synthesis filters
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions
|
||||
are met:
|
||||
|
||||
- Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
|
||||
- Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
|
||||
- Neither the name of the Xiph.org Foundation nor the names of its
|
||||
contributors may be used to endorse or promote products derived from
|
||||
this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR
|
||||
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include "filters.h"
|
||||
#include "stack_alloc.h"
|
||||
#include <math.h>
|
||||
|
||||
|
||||
void bw_lpc(float gamma, float *lpc_in, float *lpc_out, int order)
|
||||
{
|
||||
int i;
|
||||
float tmp=1;
|
||||
for (i=0;i<order+1;i++)
|
||||
{
|
||||
lpc_out[i] = tmp * lpc_in[i];
|
||||
tmp *= gamma;
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef _USE_SSE
|
||||
#include "filters_sse.h"
|
||||
#else
|
||||
void filter_mem2(float *x, float *num, float *den, float *y, int N, int ord, float *mem)
|
||||
{
|
||||
int i,j;
|
||||
float xi,yi;
|
||||
for (i=0;i<N;i++)
|
||||
{
|
||||
xi=x[i];
|
||||
y[i] = num[0]*xi + mem[0];
|
||||
yi=y[i];
|
||||
for (j=0;j<ord-1;j++)
|
||||
{
|
||||
mem[j] = mem[j+1] + num[j+1]*xi - den[j+1]*yi;
|
||||
}
|
||||
mem[ord-1] = num[ord]*xi - den[ord]*yi;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void iir_mem2(float *x, float *den, float *y, int N, int ord, float *mem)
|
||||
{
|
||||
int i,j;
|
||||
for (i=0;i<N;i++)
|
||||
{
|
||||
y[i] = x[i] + mem[0];
|
||||
for (j=0;j<ord-1;j++)
|
||||
{
|
||||
mem[j] = mem[j+1] - den[j+1]*y[i];
|
||||
}
|
||||
mem[ord-1] = - den[ord]*y[i];
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
void fir_mem2(float *x, float *num, float *y, int N, int ord, float *mem)
|
||||
{
|
||||
int i,j;
|
||||
float xi;
|
||||
for (i=0;i<N;i++)
|
||||
{
|
||||
xi=x[i];
|
||||
y[i] = num[0]*xi + mem[0];
|
||||
for (j=0;j<ord-1;j++)
|
||||
{
|
||||
mem[j] = mem[j+1] + num[j+1]*xi;
|
||||
}
|
||||
mem[ord-1] = num[ord]*xi;
|
||||
}
|
||||
}
|
||||
|
||||
void syn_percep_zero(float *xx, float *ak, float *awk1, float *awk2, float *y, int N, int ord, char *stack)
|
||||
{
|
||||
int i;
|
||||
float *mem = PUSH(stack,ord, float);
|
||||
for (i=0;i<ord;i++)
|
||||
mem[i]=0;
|
||||
filter_mem2(xx, awk1, ak, y, N, ord, mem);
|
||||
for (i=0;i<ord;i++)
|
||||
mem[i]=0;
|
||||
iir_mem2(y, awk2, y, N, ord, mem);
|
||||
}
|
||||
|
||||
void residue_percep_zero(float *xx, float *ak, float *awk1, float *awk2, float *y, int N, int ord, char *stack)
|
||||
{
|
||||
int i;
|
||||
float *mem = PUSH(stack,ord, float);
|
||||
for (i=0;i<ord;i++)
|
||||
mem[i]=0;
|
||||
filter_mem2(xx, ak, awk1, y, N, ord, mem);
|
||||
for (i=0;i<ord;i++)
|
||||
mem[i]=0;
|
||||
fir_mem2(y, awk2, y, N, ord, mem);
|
||||
}
|
||||
|
||||
|
||||
void qmf_decomp(float *xx, float *aa, float *y1, float *y2, int N, int M, float *mem, char *stack)
|
||||
{
|
||||
int i,j,k,M2;
|
||||
float *a;
|
||||
float *x;
|
||||
float *x2;
|
||||
|
||||
a = PUSH(stack, M, float);
|
||||
x = PUSH(stack, N+M-1, float);
|
||||
x2=x+M-1;
|
||||
M2=M>>1;
|
||||
for (i=0;i<M;i++)
|
||||
a[M-i-1]=aa[i];
|
||||
for (i=0;i<M-1;i++)
|
||||
x[i]=mem[M-i-2];
|
||||
for (i=0;i<N;i++)
|
||||
x[i+M-1]=xx[i];
|
||||
for (i=0,k=0;i<N;i+=2,k++)
|
||||
{
|
||||
y1[k]=0;
|
||||
y2[k]=0;
|
||||
for (j=0;j<M2;j++)
|
||||
{
|
||||
y1[k]+=a[j]*(x[i+j]+x2[i-j]);
|
||||
y2[k]-=a[j]*(x[i+j]-x2[i-j]);
|
||||
j++;
|
||||
y1[k]+=a[j]*(x[i+j]+x2[i-j]);
|
||||
y2[k]+=a[j]*(x[i+j]-x2[i-j]);
|
||||
}
|
||||
}
|
||||
for (i=0;i<M-1;i++)
|
||||
mem[i]=xx[N-i-1];
|
||||
}
|
||||
|
||||
/* By segher */
|
||||
void fir_mem_up(float *x, float *a, float *y, int N, int M, float *mem, char *stack)
|
||||
/* assumptions:
|
||||
all odd x[i] are zero -- well, actually they are left out of the array now
|
||||
N and M are multiples of 4 */
|
||||
{
|
||||
int i, j;
|
||||
float *xx=PUSH(stack, M+N-1, float);
|
||||
|
||||
for (i = 0; i < N/2; i++)
|
||||
xx[2*i] = x[N/2-1-i];
|
||||
for (i = 0; i < M - 1; i += 2)
|
||||
xx[N+i] = mem[i+1];
|
||||
|
||||
for (i = 0; i < N; i += 4) {
|
||||
float y0, y1, y2, y3;
|
||||
float x0;
|
||||
|
||||
y0 = y1 = y2 = y3 = 0.f;
|
||||
x0 = xx[N-4-i];
|
||||
|
||||
for (j = 0; j < M; j += 4) {
|
||||
float x1;
|
||||
float a0, a1;
|
||||
|
||||
a0 = a[j];
|
||||
a1 = a[j+1];
|
||||
x1 = xx[N-2+j-i];
|
||||
|
||||
y0 += a0 * x1;
|
||||
y1 += a1 * x1;
|
||||
y2 += a0 * x0;
|
||||
y3 += a1 * x0;
|
||||
|
||||
a0 = a[j+2];
|
||||
a1 = a[j+3];
|
||||
x0 = xx[N+j-i];
|
||||
|
||||
y0 += a0 * x0;
|
||||
y1 += a1 * x0;
|
||||
y2 += a0 * x1;
|
||||
y3 += a1 * x1;
|
||||
}
|
||||
y[i] = y0;
|
||||
y[i+1] = y1;
|
||||
y[i+2] = y2;
|
||||
y[i+3] = y3;
|
||||
}
|
||||
|
||||
for (i = 0; i < M - 1; i += 2)
|
||||
mem[i+1] = xx[i];
|
||||
}
|
||||
|
||||
|
||||
void comp_filter_mem_init (CombFilterMem *mem)
|
||||
{
|
||||
mem->last_pitch=0;
|
||||
mem->last_pitch_gain[0]=mem->last_pitch_gain[1]=mem->last_pitch_gain[2]=0;
|
||||
mem->smooth_gain=1;
|
||||
}
|
||||
|
||||
void comb_filter(
|
||||
float *exc, /*decoded excitation*/
|
||||
float *new_exc, /*enhanced excitation*/
|
||||
float *ak, /*LPC filter coefs*/
|
||||
int p, /*LPC order*/
|
||||
int nsf, /*sub-frame size*/
|
||||
int pitch, /*pitch period*/
|
||||
float *pitch_gain, /*pitch gain (3-tap)*/
|
||||
float comb_gain, /*gain of comb filter*/
|
||||
CombFilterMem *mem
|
||||
)
|
||||
{
|
||||
int i;
|
||||
float exc_energy=0, new_exc_energy=0;
|
||||
float gain;
|
||||
float step;
|
||||
float fact;
|
||||
/*Compute excitation energy prior to enhancement*/
|
||||
for (i=0;i<nsf;i++)
|
||||
exc_energy+=exc[i]*exc[i];
|
||||
|
||||
/*Some gain adjustment is pitch is too high or if unvoiced*/
|
||||
{
|
||||
float g=0;
|
||||
g = .5*fabs(pitch_gain[0]+pitch_gain[1]+pitch_gain[2] +
|
||||
mem->last_pitch_gain[0] + mem->last_pitch_gain[1] + mem->last_pitch_gain[2]);
|
||||
if (g>1.3)
|
||||
comb_gain*=1.3/g;
|
||||
if (g<.5)
|
||||
comb_gain*=2*g;
|
||||
}
|
||||
step = 1.0/nsf;
|
||||
fact=0;
|
||||
/*Apply pitch comb-filter (filter out noise between pitch harmonics)*/
|
||||
for (i=0;i<nsf;i++)
|
||||
{
|
||||
fact += step;
|
||||
|
||||
new_exc[i] = exc[i] + comb_gain * fact * (
|
||||
pitch_gain[0]*exc[i-pitch+1] +
|
||||
pitch_gain[1]*exc[i-pitch] +
|
||||
pitch_gain[2]*exc[i-pitch-1]
|
||||
)
|
||||
+ comb_gain * (1-fact) * (
|
||||
mem->last_pitch_gain[0]*exc[i-mem->last_pitch+1] +
|
||||
mem->last_pitch_gain[1]*exc[i-mem->last_pitch] +
|
||||
mem->last_pitch_gain[2]*exc[i-mem->last_pitch-1]
|
||||
);
|
||||
}
|
||||
|
||||
mem->last_pitch_gain[0] = pitch_gain[0];
|
||||
mem->last_pitch_gain[1] = pitch_gain[1];
|
||||
mem->last_pitch_gain[2] = pitch_gain[2];
|
||||
mem->last_pitch = pitch;
|
||||
|
||||
/*Gain after enhancement*/
|
||||
for (i=0;i<nsf;i++)
|
||||
new_exc_energy+=new_exc[i]*new_exc[i];
|
||||
|
||||
/*Compute scaling factor and normalize energy*/
|
||||
gain = sqrt(exc_energy)/sqrt(.1+new_exc_energy);
|
||||
if (gain < .5)
|
||||
gain=.5;
|
||||
if (gain>1)
|
||||
gain=1;
|
||||
|
||||
for (i=0;i<nsf;i++)
|
||||
{
|
||||
mem->smooth_gain = .96*mem->smooth_gain + .04*gain;
|
||||
new_exc[i] *= mem->smooth_gain;
|
||||
}
|
||||
}
|
@ -1,79 +0,0 @@
|
||||
/* Copyright (C) 2002 Jean-Marc Valin
|
||||
File: filters.h
|
||||
Various analysis/synthesis filters
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions
|
||||
are met:
|
||||
|
||||
- Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
|
||||
- Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
|
||||
- Neither the name of the Xiph.org Foundation nor the names of its
|
||||
contributors may be used to endorse or promote products derived from
|
||||
this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR
|
||||
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef FILTERS_H
|
||||
#define FILTERS_H
|
||||
|
||||
|
||||
typedef struct CombFilterMem {
|
||||
int last_pitch;
|
||||
float last_pitch_gain[3];
|
||||
float smooth_gain;
|
||||
} CombFilterMem;
|
||||
|
||||
|
||||
void qmf_decomp(float *xx, float *aa, float *y1, float *y2, int N, int M, float *mem, char *stack);
|
||||
void fir_mem_up(float *x, float *a, float *y, int N, int M, float *mem, char *stack);
|
||||
|
||||
|
||||
void filter_mem2(float *x, float *num, float *den, float *y, int N, int ord, float *mem);
|
||||
void fir_mem2(float *x, float *num, float *y, int N, int ord, float *mem);
|
||||
void iir_mem2(float *x, float *den, float *y, int N, int ord, float *mem);
|
||||
|
||||
/* Apply bandwidth expansion on LPC coef */
|
||||
void bw_lpc(float gamma, float *lpc_in, float *lpc_out, int order);
|
||||
|
||||
|
||||
|
||||
/* FIR filter */
|
||||
void fir_decim_mem(float *x, float *a, float *y, int N, int M, float *mem);
|
||||
|
||||
void syn_percep_zero(float *x, float *ak, float *awk1, float *awk2, float *y, int N, int ord, char *stack);
|
||||
|
||||
void residue_percep_zero(float *xx, float *ak, float *awk1, float *awk2, float *y, int N, int ord, char *stack);
|
||||
|
||||
void comp_filter_mem_init (CombFilterMem *mem);
|
||||
|
||||
void comb_filter(
|
||||
float *exc, /*decoded excitation*/
|
||||
float *new_exc, /*enhanced excitation*/
|
||||
float *ak, /*LPC filter coefs*/
|
||||
int p, /*LPC order*/
|
||||
int nsf, /*sub-frame size*/
|
||||
int pitch, /*pitch period*/
|
||||
float *pitch_gain, /*pitch gain (3-tap)*/
|
||||
float comb_gain, /*gain of comb filter*/
|
||||
CombFilterMem *mem
|
||||
);
|
||||
|
||||
|
||||
#endif
|
@ -1,289 +0,0 @@
|
||||
/* Copyright (C) 2002 Jean-Marc Valin
|
||||
File: filters.c
|
||||
Various analysis/synthesis filters
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions
|
||||
are met:
|
||||
|
||||
- Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
|
||||
- Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
|
||||
- Neither the name of the Xiph.org Foundation nor the names of its
|
||||
contributors may be used to endorse or promote products derived from
|
||||
this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR
|
||||
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
void filter_mem2(float *x, float *_num, float *_den, float *y, int N, int ord, float *_mem)
|
||||
{
|
||||
float __num[20], __den[20], __mem[20];
|
||||
float *num, *den, *mem;
|
||||
int i;
|
||||
|
||||
num = (float*)(((int)(__num+4))&0xfffffff0)-1;
|
||||
den = (float*)(((int)(__den+4))&0xfffffff0)-1;
|
||||
mem = (float*)(((int)(__mem+4))&0xfffffff0)-1;
|
||||
for (i=0;i<=10;i++)
|
||||
num[i]=den[i]=0;
|
||||
for (i=0;i<10;i++)
|
||||
mem[i]=0;
|
||||
|
||||
for (i=0;i<ord+1;i++)
|
||||
{
|
||||
num[i]=_num[i];
|
||||
den[i]=_den[i];
|
||||
}
|
||||
for (i=0;i<ord;i++)
|
||||
mem[i]=_mem[i];
|
||||
for (i=0;i<N;i+=4)
|
||||
{
|
||||
|
||||
__asm__ __volatile__
|
||||
(
|
||||
"\tmovss (%1), %%xmm0\n"
|
||||
"\tmovss (%0), %%xmm1\n"
|
||||
"\taddss %%xmm0, %%xmm1\n"
|
||||
"\tmovss %%xmm1, (%2)\n"
|
||||
"\tshufps $0x00, %%xmm0, %%xmm0\n"
|
||||
"\tshufps $0x00, %%xmm1, %%xmm1\n"
|
||||
|
||||
"\tmovaps 4(%3), %%xmm2\n"
|
||||
"\tmovaps 4(%4), %%xmm3\n"
|
||||
"\tmulps %%xmm0, %%xmm2\n"
|
||||
"\tmulps %%xmm1, %%xmm3\n"
|
||||
"\tmovaps 20(%3), %%xmm4\n"
|
||||
"\tmulps %%xmm0, %%xmm4\n"
|
||||
"\taddps 4(%0), %%xmm2\n"
|
||||
"\tmovaps 20(%4), %%xmm5\n"
|
||||
"\tmulps %%xmm1, %%xmm5\n"
|
||||
"\taddps 20(%0), %%xmm4\n"
|
||||
"\tsubps %%xmm3, %%xmm2\n"
|
||||
"\tmovups %%xmm2, (%0)\n"
|
||||
"\tsubps %%xmm5, %%xmm4\n"
|
||||
"\tmovups %%xmm4, 16(%0)\n"
|
||||
|
||||
"\tmovss 36(%3), %%xmm2\n"
|
||||
"\tmulss %%xmm0, %%xmm2\n"
|
||||
"\tmovss 36(%4), %%xmm3\n"
|
||||
"\tmulss %%xmm1, %%xmm3\n"
|
||||
"\taddss 36(%0), %%xmm2\n"
|
||||
"\tmovss 40(%3), %%xmm4\n"
|
||||
"\tmulss %%xmm0, %%xmm4\n"
|
||||
"\tmovss 40(%4), %%xmm5\n"
|
||||
"\tmulss %%xmm1, %%xmm5\n"
|
||||
"\tsubss %%xmm3, %%xmm2\n"
|
||||
"\tmovss %%xmm2, 32(%0) \n"
|
||||
"\tsubss %%xmm5, %%xmm4\n"
|
||||
"\tmovss %%xmm4, 36(%0)\n"
|
||||
|
||||
|
||||
|
||||
"\tmovss 4(%1), %%xmm0\n"
|
||||
"\tmovss (%0), %%xmm1\n"
|
||||
"\taddss %%xmm0, %%xmm1\n"
|
||||
"\tmovss %%xmm1, 4(%2)\n"
|
||||
"\tshufps $0x00, %%xmm0, %%xmm0\n"
|
||||
"\tshufps $0x00, %%xmm1, %%xmm1\n"
|
||||
|
||||
"\tmovaps 4(%3), %%xmm2\n"
|
||||
"\tmovaps 4(%4), %%xmm3\n"
|
||||
"\tmulps %%xmm0, %%xmm2\n"
|
||||
"\tmulps %%xmm1, %%xmm3\n"
|
||||
"\tmovaps 20(%3), %%xmm4\n"
|
||||
"\tmulps %%xmm0, %%xmm4\n"
|
||||
"\taddps 4(%0), %%xmm2\n"
|
||||
"\tmovaps 20(%4), %%xmm5\n"
|
||||
"\tmulps %%xmm1, %%xmm5\n"
|
||||
"\taddps 20(%0), %%xmm4\n"
|
||||
"\tsubps %%xmm3, %%xmm2\n"
|
||||
"\tmovups %%xmm2, (%0)\n"
|
||||
"\tsubps %%xmm5, %%xmm4\n"
|
||||
"\tmovups %%xmm4, 16(%0)\n"
|
||||
|
||||
"\tmovss 36(%3), %%xmm2\n"
|
||||
"\tmulss %%xmm0, %%xmm2\n"
|
||||
"\tmovss 36(%4), %%xmm3\n"
|
||||
"\tmulss %%xmm1, %%xmm3\n"
|
||||
"\taddss 36(%0), %%xmm2\n"
|
||||
"\tmovss 40(%3), %%xmm4\n"
|
||||
"\tmulss %%xmm0, %%xmm4\n"
|
||||
"\tmovss 40(%4), %%xmm5\n"
|
||||
"\tmulss %%xmm1, %%xmm5\n"
|
||||
"\tsubss %%xmm3, %%xmm2\n"
|
||||
"\tmovss %%xmm2, 32(%0) \n"
|
||||
"\tsubss %%xmm5, %%xmm4\n"
|
||||
"\tmovss %%xmm4, 36(%0)\n"
|
||||
|
||||
|
||||
|
||||
"\tmovss 8(%1), %%xmm0\n"
|
||||
"\tmovss (%0), %%xmm1\n"
|
||||
"\taddss %%xmm0, %%xmm1\n"
|
||||
"\tmovss %%xmm1, 8(%2)\n"
|
||||
"\tshufps $0x00, %%xmm0, %%xmm0\n"
|
||||
"\tshufps $0x00, %%xmm1, %%xmm1\n"
|
||||
|
||||
"\tmovaps 4(%3), %%xmm2\n"
|
||||
"\tmovaps 4(%4), %%xmm3\n"
|
||||
"\tmulps %%xmm0, %%xmm2\n"
|
||||
"\tmulps %%xmm1, %%xmm3\n"
|
||||
"\tmovaps 20(%3), %%xmm4\n"
|
||||
"\tmulps %%xmm0, %%xmm4\n"
|
||||
"\taddps 4(%0), %%xmm2\n"
|
||||
"\tmovaps 20(%4), %%xmm5\n"
|
||||
"\tmulps %%xmm1, %%xmm5\n"
|
||||
"\taddps 20(%0), %%xmm4\n"
|
||||
"\tsubps %%xmm3, %%xmm2\n"
|
||||
"\tmovups %%xmm2, (%0)\n"
|
||||
"\tsubps %%xmm5, %%xmm4\n"
|
||||
"\tmovups %%xmm4, 16(%0)\n"
|
||||
|
||||
"\tmovss 36(%3), %%xmm2\n"
|
||||
"\tmulss %%xmm0, %%xmm2\n"
|
||||
"\tmovss 36(%4), %%xmm3\n"
|
||||
"\tmulss %%xmm1, %%xmm3\n"
|
||||
"\taddss 36(%0), %%xmm2\n"
|
||||
"\tmovss 40(%3), %%xmm4\n"
|
||||
"\tmulss %%xmm0, %%xmm4\n"
|
||||
"\tmovss 40(%4), %%xmm5\n"
|
||||
"\tmulss %%xmm1, %%xmm5\n"
|
||||
"\tsubss %%xmm3, %%xmm2\n"
|
||||
"\tmovss %%xmm2, 32(%0) \n"
|
||||
"\tsubss %%xmm5, %%xmm4\n"
|
||||
"\tmovss %%xmm4, 36(%0)\n"
|
||||
|
||||
|
||||
|
||||
"\tmovss 12(%1), %%xmm0\n"
|
||||
"\tmovss (%0), %%xmm1\n"
|
||||
"\taddss %%xmm0, %%xmm1\n"
|
||||
"\tmovss %%xmm1, 12(%2)\n"
|
||||
"\tshufps $0x00, %%xmm0, %%xmm0\n"
|
||||
"\tshufps $0x00, %%xmm1, %%xmm1\n"
|
||||
|
||||
"\tmovaps 4(%3), %%xmm2\n"
|
||||
"\tmovaps 4(%4), %%xmm3\n"
|
||||
"\tmulps %%xmm0, %%xmm2\n"
|
||||
"\tmulps %%xmm1, %%xmm3\n"
|
||||
"\tmovaps 20(%3), %%xmm4\n"
|
||||
"\tmulps %%xmm0, %%xmm4\n"
|
||||
"\taddps 4(%0), %%xmm2\n"
|
||||
"\tmovaps 20(%4), %%xmm5\n"
|
||||
"\tmulps %%xmm1, %%xmm5\n"
|
||||
"\taddps 20(%0), %%xmm4\n"
|
||||
"\tsubps %%xmm3, %%xmm2\n"
|
||||
"\tmovups %%xmm2, (%0)\n"
|
||||
"\tsubps %%xmm5, %%xmm4\n"
|
||||
"\tmovups %%xmm4, 16(%0)\n"
|
||||
|
||||
"\tmovss 36(%3), %%xmm2\n"
|
||||
"\tmulss %%xmm0, %%xmm2\n"
|
||||
"\tmovss 36(%4), %%xmm3\n"
|
||||
"\tmulss %%xmm1, %%xmm3\n"
|
||||
"\taddss 36(%0), %%xmm2\n"
|
||||
"\tmovss 40(%3), %%xmm4\n"
|
||||
"\tmulss %%xmm0, %%xmm4\n"
|
||||
"\tmovss 40(%4), %%xmm5\n"
|
||||
"\tmulss %%xmm1, %%xmm5\n"
|
||||
"\tsubss %%xmm3, %%xmm2\n"
|
||||
"\tmovss %%xmm2, 32(%0) \n"
|
||||
"\tsubss %%xmm5, %%xmm4\n"
|
||||
"\tmovss %%xmm4, 36(%0)\n"
|
||||
|
||||
: : "r" (mem), "r" (x+i), "r" (y+i), "r" (num), "r" (den)
|
||||
: "memory" );
|
||||
|
||||
}
|
||||
for (i=0;i<ord;i++)
|
||||
_mem[i]=mem[i];
|
||||
|
||||
}
|
||||
|
||||
|
||||
void iir_mem2(float *x, float *_den, float *y, int N, int ord, float *_mem)
|
||||
{
|
||||
float __den[20], __mem[20];
|
||||
float *den, *mem;
|
||||
int i;
|
||||
|
||||
den = (float*)(((int)(__den+4))&0xfffffff0)-1;
|
||||
mem = (float*)(((int)(__mem+4))&0xfffffff0)-1;
|
||||
for (i=0;i<=10;i++)
|
||||
den[i]=0;
|
||||
for (i=0;i<10;i++)
|
||||
mem[i]=0;
|
||||
for (i=0;i<ord+1;i++)
|
||||
{
|
||||
den[i]=_den[i];
|
||||
}
|
||||
for (i=0;i<ord;i++)
|
||||
mem[i]=_mem[i];
|
||||
|
||||
for (i=0;i<N;i++)
|
||||
{
|
||||
#if 0
|
||||
y[i] = x[i] + mem[0];
|
||||
for (j=0;j<ord-1;j++)
|
||||
{
|
||||
mem[j] = mem[j+1] - den[j+1]*y[i];
|
||||
}
|
||||
mem[ord-1] = - den[ord]*y[i];
|
||||
#else
|
||||
__asm__ __volatile__
|
||||
(
|
||||
"\tmovss (%1), %%xmm0\n"
|
||||
"\tmovss (%0), %%xmm1\n"
|
||||
"\taddss %%xmm0, %%xmm1\n"
|
||||
"\tmovss %%xmm1, (%2)\n"
|
||||
"\tshufps $0x00, %%xmm0, %%xmm0\n"
|
||||
"\tshufps $0x00, %%xmm1, %%xmm1\n"
|
||||
|
||||
|
||||
"\tmovaps 4(%3), %%xmm2\n"
|
||||
"\tmovaps 20(%3), %%xmm3\n"
|
||||
"\tmulps %%xmm1, %%xmm2\n"
|
||||
"\tmulps %%xmm1, %%xmm3\n"
|
||||
"\tmovss 36(%3), %%xmm4\n"
|
||||
"\tmovss 40(%3), %%xmm5\n"
|
||||
"\tmulss %%xmm1, %%xmm4\n"
|
||||
"\tmulss %%xmm1, %%xmm5\n"
|
||||
"\tmovaps 4(%0), %%xmm6\n"
|
||||
"\tsubps %%xmm2, %%xmm6\n"
|
||||
"\tmovups %%xmm6, (%0)\n"
|
||||
"\tmovaps 20(%0), %%xmm7\n"
|
||||
"\tsubps %%xmm3, %%xmm7\n"
|
||||
"\tmovups %%xmm7, 16(%0)\n"
|
||||
|
||||
|
||||
"\tmovss 36(%0), %%xmm7\n"
|
||||
"\tsubss %%xmm4, %%xmm7\n"
|
||||
"\tmovss %%xmm7, 32(%0) \n"
|
||||
"\txorps %%xmm2, %%xmm2\n"
|
||||
"\tsubss %%xmm5, %%xmm2\n"
|
||||
"\tmovss %%xmm2, 36(%0)\n"
|
||||
|
||||
: : "r" (mem), "r" (x+i), "r" (y+i), "r" (den)
|
||||
: "memory" );
|
||||
#endif
|
||||
}
|
||||
for (i=0;i<ord;i++)
|
||||
_mem[i]=mem[i];
|
||||
|
||||
}
|
||||
|
@ -1,160 +0,0 @@
|
||||
/* Copyright (C) 2002 Jean-Marc Valin
|
||||
File: gain_table.c
|
||||
Codebook for 3-tap pitch prediction gain (128 entries)
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are
|
||||
met:
|
||||
|
||||
1. Redistributions of source code must retain the above copyright notice,
|
||||
this list of conditions and the following disclaimer.
|
||||
|
||||
2. Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
|
||||
3. The name of the author may not be used to endorse or promote products
|
||||
derived from this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
||||
IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
|
||||
INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||
STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||||
ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
signed char gain_cdbk_nb[384] = {
|
||||
-32,-32,-32,
|
||||
-28,-67,-5,
|
||||
-42,-6,-32,
|
||||
-57,-10,-54,
|
||||
-16,27,-41,
|
||||
19,-19,-40,
|
||||
-45,24,-21,
|
||||
-8,-14,-18,
|
||||
1,14,-58,
|
||||
-18,-88,-39,
|
||||
-38,21,-18,
|
||||
-19,20,-43,
|
||||
10,17,-48,
|
||||
-52,-58,-13,
|
||||
-44,-1,-11,
|
||||
-12,-11,-34,
|
||||
14,0,-46,
|
||||
-37,-35,-34,
|
||||
-25,44,-30,
|
||||
6,-4,-63,
|
||||
-31,43,-41,
|
||||
-23,30,-43,
|
||||
-43,26,-14,
|
||||
-33,1,-13,
|
||||
-13,18,-37,
|
||||
-46,-73,-45,
|
||||
-36,24,-25,
|
||||
-36,-11,-20,
|
||||
-25,12,-18,
|
||||
-36,-69,-59,
|
||||
-45,6,8,
|
||||
-22,-14,-24,
|
||||
-1,13,-44,
|
||||
-39,-48,-26,
|
||||
-32,31,-37,
|
||||
-33,15,-46,
|
||||
-24,30,-36,
|
||||
-41,31,-23,
|
||||
-50,22,-4,
|
||||
-22,2,-21,
|
||||
-17,30,-34,
|
||||
-7,-60,-28,
|
||||
-38,42,-28,
|
||||
-44,-11,21,
|
||||
-16,8,-44,
|
||||
-39,-55,-43,
|
||||
-11,-35,26,
|
||||
-9,0,-34,
|
||||
-8,121,-81,
|
||||
7,-16,-22,
|
||||
-37,33,-31,
|
||||
-27,-7,-36,
|
||||
-34,70,-57,
|
||||
-37,-11,-48,
|
||||
-40,17,-1,
|
||||
-33,6,-6,
|
||||
-9,0,-20,
|
||||
-21,69,-33,
|
||||
-29,33,-31,
|
||||
-55,12,-1,
|
||||
-33,27,-22,
|
||||
-50,-33,-47,
|
||||
-50,54,51,
|
||||
-1,-5,-44,
|
||||
-4,22,-40,
|
||||
-39,-66,-25,
|
||||
-33,1,-26,
|
||||
-24,-23,-25,
|
||||
-11,21,-45,
|
||||
-25,-45,-19,
|
||||
-43,105,-16,
|
||||
5,-21,1,
|
||||
-16,11,-33,
|
||||
-13,-99,-4,
|
||||
-37,33,-15,
|
||||
-25,37,-63,
|
||||
-36,24,-31,
|
||||
-53,-56,-38,
|
||||
-41,-4,4,
|
||||
-33,13,-30,
|
||||
49,52,-94,
|
||||
-5,-30,-15,
|
||||
1,38,-40,
|
||||
-23,12,-36,
|
||||
-17,40,-47,
|
||||
-37,-41,-39,
|
||||
-49,34,0,
|
||||
-18,-7,-4,
|
||||
-16,17,-27,
|
||||
30,5,-62,
|
||||
4,48,-68,
|
||||
-43,11,-11,
|
||||
-18,19,-15,
|
||||
-23,-62,-39,
|
||||
-42,10,-2,
|
||||
-21,-13,-13,
|
||||
-9,13,-47,
|
||||
-23,-62,-24,
|
||||
-44,60,-21,
|
||||
-18,-3,-52,
|
||||
-22,22,-36,
|
||||
-75,57,16,
|
||||
-19,3,10,
|
||||
-29,23,-38,
|
||||
-5,-62,-51,
|
||||
-51,40,-18,
|
||||
-42,13,-24,
|
||||
-34,14,-20,
|
||||
-56,-75,-26,
|
||||
-26,32,15,
|
||||
-26,17,-29,
|
||||
-7,28,-52,
|
||||
-12,-30,5,
|
||||
-5,-48,-5,
|
||||
2,2,-43,
|
||||
21,16,16,
|
||||
-25,-45,-32,
|
||||
-43,18,-10,
|
||||
9,0,-1,
|
||||
-1,7,-30,
|
||||
19,-48,-4,
|
||||
-28,25,-29,
|
||||
-22,0,-31,
|
||||
-32,17,-10,
|
||||
-64,-41,-62,
|
||||
-52,15,16,
|
||||
-30,-22,-32,
|
||||
-7,9,-38};
|
@ -1,64 +0,0 @@
|
||||
/* Copyright (C) 2002 Jean-Marc Valin
|
||||
File: gain_table_lbr.c
|
||||
Codebook for 3-tap pitch prediction gain (32 entries)
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are
|
||||
met:
|
||||
|
||||
1. Redistributions of source code must retain the above copyright notice,
|
||||
this list of conditions and the following disclaimer.
|
||||
|
||||
2. Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
|
||||
3. The name of the author may not be used to endorse or promote products
|
||||
derived from this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
||||
IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
|
||||
INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||
STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||||
ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
signed char gain_cdbk_lbr[96] = {
|
||||
-32,-32,-32,
|
||||
-31,-58,-16,
|
||||
-41,-24,-43,
|
||||
-56,-22,-55,
|
||||
-13,33,-41,
|
||||
-4,-39,-9,
|
||||
-41,15,-12,
|
||||
-8,-15,-12,
|
||||
1,2,-44,
|
||||
-22,-66,-42,
|
||||
-38,28,-23,
|
||||
-21,14,-37,
|
||||
0,21,-50,
|
||||
-53,-71,-27,
|
||||
-37,-1,-19,
|
||||
-19,-5,-28,
|
||||
6,65,-44,
|
||||
-33,-48,-33,
|
||||
-40,57,-14,
|
||||
-17,4,-45,
|
||||
-31,38,-33,
|
||||
-23,28,-40,
|
||||
-43,29,-12,
|
||||
-34,13,-23,
|
||||
-16,15,-27,
|
||||
-14,-82,-15,
|
||||
-31,25,-32,
|
||||
-21,5,-5,
|
||||
-47,-63,-51,
|
||||
-46,12,3,
|
||||
-28,-17,-29,
|
||||
-10,14,-40};
|
@ -1,66 +0,0 @@
|
||||
/* Copyright (C) 2002 Jean-Marc Valin
|
||||
File: hexc_10_32_table.c
|
||||
Codebook for high-band excitation in SB-CELP mode (4000 bps)
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions
|
||||
are met:
|
||||
|
||||
- Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
|
||||
- Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
|
||||
- Neither the name of the Xiph.org Foundation nor the names of its
|
||||
contributors may be used to endorse or promote products derived from
|
||||
this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR
|
||||
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
signed char hexc_10_32_table[320] = {
|
||||
-3, -2, -1, 0, -4, 5, 35, -40, -9, 13,
|
||||
-44, 5, -27, -1, -7, 6, -11, 7, -8, 7,
|
||||
19, -14, 15, -4, 9, -10, 10, -8, 10, -9,
|
||||
-1, 1, 0, 0, 2, 5, -18, 22, -53, 50,
|
||||
1, -23, 50, -36, 15, 3, -13, 14, -10, 6,
|
||||
1, 5, -3, 4, -2, 5, -32, 25, 5, -2,
|
||||
-1, -4, 1, 11, -29, 26, -6, -15, 30, -18,
|
||||
0, 15, -17, 40, -41, 3, 9, -2, -2, 3,
|
||||
-3, -1, -5, 2, 21, -6, -16, -21, 23, 2,
|
||||
60, 15, 16, -16, -9, 14, 9, -1, 7, -9,
|
||||
0, 1, 1, 0, -1, -6, 17, -28, 54, -45,
|
||||
-1, 1, -1, -6, -6, 2, 11, 26, -29, -2,
|
||||
46, -21, 34, 12, -23, 32, -23, 16, -10, 3,
|
||||
66, 19, -20, 24, 7, 11, -3, 0, -3, -1,
|
||||
-50, -46, 2, -18, -3, 4, -1, -2, 3, -3,
|
||||
-19, 41, -36, 9, 11, -24, 21, -16, 9, -3,
|
||||
-25, -3, 10, 18, -9, -2, -5, -1, -5, 6,
|
||||
-4, -3, 2, -26, 21, -19, 35, -15, 7, -13,
|
||||
17, -19, 39, -43, 48, -31, 16, -9, 7, -2,
|
||||
-5, 3, -4, 9, -19, 27, -55, 63, -35, 10,
|
||||
26, -44, -2, 9, 4, 1, -6, 8, -9, 5,
|
||||
-8, -1, -3, -16, 45, -42, 5, 15, -16, 10,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
-16, 24, -55, 47, -38, 27, -19, 7, -3, 1,
|
||||
16, 27, 20, -19, 18, 5, -7, 1, -5, 2,
|
||||
-6, 8, -22, 0, -3, -3, 8, -1, 7, -8,
|
||||
1, -3, 5, 0, 17, -48, 58, -52, 29, -7,
|
||||
-2, 3, -10, 6, -26, 58, -31, 1, -6, 3,
|
||||
93, -29, 39, 3, 17, 5, 6, -1, -1, -1,
|
||||
27, 13, 10, 19, -7, -34, 12, 10, -4, 9,
|
||||
-76, 9, 8, -28, -2, -11, 2, -1, 3, 1,
|
||||
-83, 38, -39, 4, -16, -6, -2, -5, 5, -2,
|
||||
};
|
@ -1,162 +0,0 @@
|
||||
/* Copyright (C) 2002 Jean-Marc Valin
|
||||
File: hexc_table.c
|
||||
Codebook for high-band excitation in SB-CELP mode (8000 bps with sign)
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions
|
||||
are met:
|
||||
|
||||
- Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
|
||||
- Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
|
||||
- Neither the name of the Xiph.org Foundation nor the names of its
|
||||
contributors may be used to endorse or promote products derived from
|
||||
this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR
|
||||
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
signed char hexc_table[1024] = {
|
||||
-24, 21, -20, 5, -5, -7, 14, -10,
|
||||
2, -27, 16, -20, 0, -32, 26, 19,
|
||||
8, -11, -41, 31, 28, -27, -32, 34,
|
||||
42, 34, -17, 22, -10, 13, -29, 18,
|
||||
-12, -26, -24, 11, 22, 5, -5, -5,
|
||||
54, -68, -43, 57, -25, 24, 4, 4,
|
||||
26, -8, -12, -17, 54, 30, -45, 1,
|
||||
10, -15, 18, -41, 11, 68, -67, 37,
|
||||
-16, -24, -16, 38, -22, 6, -29, 30,
|
||||
66, -27, 5, 7, -16, 13, 2, -12,
|
||||
-7, -3, -20, 36, 4, -28, 9, 3,
|
||||
32, 48, 26, 39, 3, 0, 7, -21,
|
||||
-13, 5, -82, -7, 73, -20, 34, -9,
|
||||
-5, 1, -1, 10, -5, -10, -1, 9,
|
||||
1, -9, 10, 0, -14, 11, -1, -2,
|
||||
-1, 11, 20, 96, -81, -22, -12, -9,
|
||||
-58, 9, 24, -30, 26, -35, 27, -12,
|
||||
13, -18, 56, -59, 15, -7, 23, -15,
|
||||
-1, 6, -25, 14, -22, -20, 47, -11,
|
||||
16, 2, 38, -23, -19, -30, -9, 40,
|
||||
-11, 5, 4, -6, 8, 26, -21, -11,
|
||||
127, 4, 1, 6, -9, 2, -7, -2,
|
||||
-3, 7, -5, 10, -19, 7, -106, 91,
|
||||
-3, 9, -4, 21, -8, 26, -80, 8,
|
||||
1, -2, -10, -17, -17, -27, 32, 71,
|
||||
6, -29, 11, -23, 54, -38, 29, -22,
|
||||
39, 87, -31, -12, -20, 3, -2, -2,
|
||||
2, 20, 0, -1, -35, 27, 9, -6,
|
||||
-12, 3, -12, -6, 13, 1, 14, -22,
|
||||
-59, -15, -17, -25, 13, -7, 7, 3,
|
||||
0, 1, -7, 6, -3, 61, -37, -23,
|
||||
-23, -29, 38, -31, 27, 1, -8, 2,
|
||||
-27, 23, -26, 36, -34, 5, 24, -24,
|
||||
-6, 7, 3, -59, 78, -62, 44, -16,
|
||||
1, 6, 0, 17, 8, 45, 0, -110,
|
||||
6, 14, -2, 32, -77, -56, 62, -3,
|
||||
3, -13, 4, -16, 102, -15, -36, -1,
|
||||
9, -113, 6, 23, 0, 9, 9, 5,
|
||||
-8, -1, -14, 5, -12, 121, -53, -27,
|
||||
-8, -9, 22, -13, 3, 2, -3, 1,
|
||||
-2, -71, 95, 38, -19, 15, -16, -5,
|
||||
71, 10, 2, -32, -13, -5, 15, -1,
|
||||
-2, -14, -85, 30, 29, 6, 3, 2,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
2, -65, -56, -9, 18, 18, 23, -14,
|
||||
-2, 0, 12, -29, 26, -12, 1, 2,
|
||||
-12, -64, 90, -6, 4, 1, 5, -5,
|
||||
-110, -3, -31, 22, -29, 9, 0, 8,
|
||||
-40, -5, 21, -5, -5, 13, 10, -18,
|
||||
40, 1, 35, -20, 30, -28, 11, -6,
|
||||
19, 7, 14, 18, -64, 9, -6, 16,
|
||||
51, 68, 8, 16, 12, -8, 0, -9,
|
||||
20, -22, 25, 7, -4, -13, 41, -35,
|
||||
93, -18, -54, 11, -1, 1, -9, 4,
|
||||
-66, 66, -31, 20, -22, 25, -23, 11,
|
||||
10, 9, 19, 15, 11, -5, -31, -10,
|
||||
-23, -28, -6, -6, -3, -4, 5, 3,
|
||||
-28, 22, -11, -42, 25, -25, -16, 41,
|
||||
34, 47, -6, 2, 42, -19, -22, 5,
|
||||
-39, 32, 6, -35, 22, 17, -30, 8,
|
||||
-26, -11, -11, 3, -12, 33, 33, -37,
|
||||
21, -1, 6, -4, 3, 0, -5, 5,
|
||||
12, -12, 57, 27, -61, -3, 20, -17,
|
||||
2, 0, 4, 0, -2, -33, -58, 81,
|
||||
-23, 39, -10, -5, 2, 6, -7, 5,
|
||||
4, -3, -2, -13, -23, -72, 107, 15,
|
||||
-5, 0, -7, -3, -6, 5, -4, 15,
|
||||
47, 12, -31, 25, -16, 8, 22, -25,
|
||||
-62, -56, -18, 14, 28, 12, 2, -11,
|
||||
74, -66, 41, -20, -7, 16, -20, 16,
|
||||
-8, 0, -16, 4, -19, 92, 12, -59,
|
||||
-14, -39, 49, -25, -16, 23, -27, 19,
|
||||
-3, -33, 19, 85, -29, 6, -7, -10,
|
||||
16, -7, -12, 1, -6, 2, 4, -2,
|
||||
64, 10, -25, 41, -2, -31, 15, 0,
|
||||
110, 50, 69, 35, 28, 19, -10, 2,
|
||||
-43, -49, -56, -15, -16, 10, 3, 12,
|
||||
-1, -8, 1, 26, -12, -1, 7, -11,
|
||||
-27, 41, 25, 1, -11, -18, 22, -7,
|
||||
-1, -47, -8, 23, -3, -17, -7, 18,
|
||||
-125, 59, -5, 3, 18, 1, 2, 3,
|
||||
27, -35, 65, -53, 50, -46, 37, -21,
|
||||
-28, 7, 14, -37, -5, -5, 12, 5,
|
||||
-8, 78, -19, 21, -6, -16, 8, -7,
|
||||
5, 2, 7, 2, 10, -6, 12, -60,
|
||||
44, 11, -36, -32, 31, 0, 2, -2,
|
||||
2, 1, -3, 7, -10, 17, -21, 10,
|
||||
6, -2, 19, -2, 59, -38, -86, 38,
|
||||
8, -41, -30, -45, -33, 7, 15, 28,
|
||||
29, -7, 24, -40, 7, 7, 5, -2,
|
||||
9, 24, -23, -18, 6, -29, 30, 2,
|
||||
28, 49, -11, -46, 10, 43, -13, -9,
|
||||
-1, -3, -7, -7, -17, -6, 97, -33,
|
||||
-21, 3, 5, 1, 12, -43, -8, 28,
|
||||
7, -43, -7, 17, -20, 19, -1, 2,
|
||||
-13, 9, 54, 34, 9, -28, -11, -9,
|
||||
-17, 110, -59, 44, -26, 0, 3, -12,
|
||||
-47, 73, -34, -43, 38, -33, 16, -5,
|
||||
-46, -4, -6, -2, -25, 19, -29, 28,
|
||||
-13, 5, 14, 27, -40, -43, 4, 32,
|
||||
-13, -2, -35, -4, 112, -42, 9, -12,
|
||||
37, -28, 17, 14, -19, 35, -39, 23,
|
||||
3, -14, -1, -57, -5, 94, -9, 3,
|
||||
-39, 5, 30, -10, -32, 42, -13, -14,
|
||||
-97, -63, 30, -9, 1, -7, 12, 5,
|
||||
20, 17, -9, -36, -30, 25, 47, -9,
|
||||
-15, 12, -22, 98, -8, -50, 15, -27,
|
||||
21, -16, -11, 2, 12, -10, 10, -3,
|
||||
33, 36, -96, 0, -17, 31, -9, 9,
|
||||
3, -20, 13, -11, 8, -4, 10, -10,
|
||||
9, 1, 112, -70, -27, 5, -21, 2,
|
||||
-57, -3, -29, 10, 19, -21, 21, -10,
|
||||
-66, -3, 91, -35, 30, -12, 0, -7,
|
||||
59, -28, 26, 2, 14, -18, 1, 1,
|
||||
11, 17, 20, -54, -59, 27, 4, 29,
|
||||
32, 5, 19, 12, -4, 1, 7, -10,
|
||||
5, -2, 10, 0, 23, -5, 28, -104,
|
||||
46, 11, 16, 3, 29, 1, -8, -14,
|
||||
1, 7, -50, 88, -62, 26, 8, -17,
|
||||
-14, 50, 0, 32, -12, -3, -27, 18,
|
||||
-8, -5, 8, 3, -20, -11, 37, -12,
|
||||
9, 33, 46, -101, -1, -4, 1, 6,
|
||||
-1, 28, -42, -15, 16, 5, -1, -2,
|
||||
-55, 85, 38, -9, -4, 11, -2, -9,
|
||||
-6, 3, -20, -10, -77, 89, 24, -3,
|
||||
-104, -57, -26, -31, -20, -6, -9, 14,
|
||||
20, -23, 46, -15, -31, 28, 1, -15,
|
||||
-2, 6, -2, 31, 45, -76, 23, -25,
|
||||
};
|
@ -1,163 +0,0 @@
|
||||
/* Copyright (C) 2002 Jean-Marc Valin
|
||||
File: high_lsp_tables.c
|
||||
Codebooks for high-band LSPs in SB-CELP mode
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are
|
||||
met:
|
||||
|
||||
1. Redistributions of source code must retain the above copyright notice,
|
||||
this list of conditions and the following disclaimer.
|
||||
|
||||
2. Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
|
||||
3. The name of the author may not be used to endorse or promote products
|
||||
derived from this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
||||
IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
|
||||
INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||
STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||||
ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
signed char high_lsp_cdbk[512]={
|
||||
39,12,-14,-20,-29,-61,-67,-76,
|
||||
-32,-71,-67,68,77,46,34,5,
|
||||
-13,-48,-46,-72,-81,-84,-60,-58,
|
||||
-40,-28,82,93,68,45,29,3,
|
||||
-19,-47,-28,-43,-35,-30,-8,-13,
|
||||
-39,-91,-91,-123,-96,10,10,-6,
|
||||
-18,-55,-60,-91,-56,-36,-27,-16,
|
||||
-48,-75,40,28,-10,-28,35,9,
|
||||
37,19,1,-20,-31,-41,-18,-25,
|
||||
-35,-68,-80,45,27,-1,47,13,
|
||||
0,-29,-35,-57,-50,-79,-73,-38,
|
||||
-19,5,35,14,-10,-23,16,-8,
|
||||
5,-24,-40,-62,-23,-27,-22,-16,
|
||||
-18,-46,-72,-77,43,21,33,1,
|
||||
-80,-70,-70,-64,-56,-52,-39,-33,
|
||||
-31,-38,-19,-19,-15,32,33,-2,
|
||||
7,-15,-15,-24,-23,-33,-41,-56,
|
||||
-24,-57,5,89,64,41,27,5,
|
||||
-9,-47,-60,-97,-97,-124,-20,-9,
|
||||
-44,-73,31,29,-4,64,48,7,
|
||||
-35,-57,0,-3,-26,-47,-3,-6,
|
||||
-40,-76,-79,-48,12,81,55,10,
|
||||
9,-24,-43,-73,-57,-69,16,5,
|
||||
-28,-53,18,29,20,0,-4,-11,
|
||||
6,-13,23,7,-17,-35,-37,-37,
|
||||
-30,-68,-63,6,24,-9,-14,3,
|
||||
21,-13,-27,-57,-49,-80,-24,-41,
|
||||
-5,-16,-5,1,45,25,12,-7,
|
||||
3,-15,-6,-16,-15,-8,6,-13,
|
||||
-42,-81,-80,-87,14,1,-10,-3,
|
||||
-43,-69,-46,-24,-28,-29,36,6,
|
||||
-43,-56,-12,12,54,79,43,9,
|
||||
54,22,2,8,-12,-43,-46,-52,
|
||||
-38,-69,-89,-5,75,38,33,5,
|
||||
-13,-53,-62,-87,-89,-113,-99,-55,
|
||||
-34,-37,62,55,33,16,21,-2,
|
||||
-17,-46,-29,-38,-38,-48,-39,-42,
|
||||
-36,-75,-72,-88,-48,-30,21,2,
|
||||
-15,-57,-64,-98,-84,-76,25,1,
|
||||
-46,-80,-12,18,-7,3,34,6,
|
||||
38,31,23,4,-1,20,14,-15,
|
||||
-43,-78,-91,-24,14,-3,54,16,
|
||||
0,-27,-28,-44,-56,-83,-92,-89,
|
||||
-3,34,56,41,36,22,20,-8,
|
||||
-7,-35,-42,-62,-49,3,12,-10,
|
||||
-50,-87,-96,-66,92,70,38,9,
|
||||
-70,-71,-62,-42,-39,-43,-11,-7,
|
||||
-50,-79,-58,-50,-31,32,31,-6,
|
||||
-4,-25,7,-17,-38,-70,-58,-27,
|
||||
-43,-83,-28,59,36,20,31,2,
|
||||
-27,-71,-80,-109,-98,-75,-33,-32,
|
||||
-31,-2,33,15,-6,43,33,-5,
|
||||
0,-22,-10,-27,-34,-49,-11,-20,
|
||||
-41,-91,-100,-121,-39,57,41,10,
|
||||
-19,-50,-38,-59,-60,-70,-18,-20,
|
||||
-8,-31,-8,-15,1,-14,-26,-25,
|
||||
33,21,32,17,1,-19,-19,-26,
|
||||
-58,-81,-35,-22,45,30,11,-11,
|
||||
3,-26,-48,-87,-67,-83,-58,3,
|
||||
-1,-26,-20,44,10,25,39,5,
|
||||
-9,-35,-27,-38,7,10,4,-9,
|
||||
-42,-85,-102,-127,52,44,28,10,
|
||||
-47,-61,-40,-39,-17,-1,-10,-33,
|
||||
-42,-74,-48,21,-4,70,52,10};
|
||||
|
||||
|
||||
signed char high_lsp_cdbk2[512]={
|
||||
-36,-62,6,-9,-10,-14,-56,23,
|
||||
1,-26,23,-48,-17,12,8,-7,
|
||||
23,29,-36,-28,-6,-29,-17,-5,
|
||||
40,23,10,10,-46,-13,36,6,
|
||||
4,-30,-29,62,32,-32,-1,22,
|
||||
-14,1,-4,-22,-45,2,54,4,
|
||||
-30,-57,-59,-12,27,-3,-31,8,
|
||||
-9,5,10,-14,32,66,19,9,
|
||||
2,-25,-37,23,-15,18,-38,-31,
|
||||
5,-9,-21,15,0,22,62,30,
|
||||
15,-12,-14,-46,77,21,33,3,
|
||||
34,29,-19,50,2,11,9,-38,
|
||||
-12,-37,62,1,-15,54,32,6,
|
||||
2,-24,20,35,-21,2,19,24,
|
||||
-13,55,4,9,39,-19,30,-1,
|
||||
-21,73,54,33,8,18,3,15,
|
||||
6,-19,-47,6,-3,-48,-50,1,
|
||||
26,20,8,-23,-50,65,-14,-55,
|
||||
-17,-31,-37,-28,53,-1,-17,-53,
|
||||
1,57,11,-8,-25,-30,-37,64,
|
||||
5,-52,-45,15,23,31,15,14,
|
||||
-25,24,33,-2,-44,-56,-18,6,
|
||||
-21,-43,4,-12,17,-37,20,-10,
|
||||
34,15,2,15,55,21,-11,-31,
|
||||
-6,46,25,16,-9,-25,-8,-62,
|
||||
28,17,20,-32,-29,26,30,25,
|
||||
-19,2,-16,-17,26,-51,2,50,
|
||||
42,19,-66,23,29,-2,3,19,
|
||||
-19,-37,32,15,6,30,-34,13,
|
||||
11,-5,40,31,10,-42,4,-9,
|
||||
26,-9,-70,17,-2,-23,20,-22,
|
||||
-55,51,-24,-31,22,-22,15,-13,
|
||||
3,-10,-28,-16,56,4,-63,11,
|
||||
-18,-15,-18,-38,-35,16,-7,34,
|
||||
-1,-21,-49,-47,9,-37,7,8,
|
||||
69,55,20,6,-33,-45,-10,-9,
|
||||
6,-9,12,71,15,-3,-42,-7,
|
||||
-24,32,-35,-2,-42,-17,-5,0,
|
||||
-2,-33,-54,13,-12,-34,47,23,
|
||||
19,55,7,-8,74,31,14,16,
|
||||
-23,-26,19,12,-18,-49,-28,-31,
|
||||
-20,2,-14,-20,-47,78,40,13,
|
||||
-23,-11,21,-6,18,1,47,5,
|
||||
38,35,32,46,22,8,13,16,
|
||||
-14,18,51,19,40,39,11,-26,
|
||||
-1,-17,47,2,-53,-15,31,-22,
|
||||
38,21,-15,-16,5,-33,53,15,
|
||||
-38,86,11,-3,-24,49,13,-4,
|
||||
-11,-18,28,20,-12,-27,-26,35,
|
||||
-25,-35,-3,-20,-61,30,10,-55,
|
||||
-12,-22,-52,-54,-14,19,-32,-12,
|
||||
45,15,-8,-48,-9,11,-32,8,
|
||||
-16,-34,-13,51,18,38,-2,-32,
|
||||
-17,22,-2,-18,-28,-70,59,27,
|
||||
-28,-19,-10,-20,-9,-9,-8,-21,
|
||||
21,-8,35,-2,45,-3,-9,12,
|
||||
0,30,7,-39,43,27,-38,-91,
|
||||
30,26,19,-55,-4,63,14,-17,
|
||||
13,9,13,2,7,4,6,61,
|
||||
72,-1,-17,29,-1,-22,-17,8,
|
||||
-28,-37,63,44,41,3,2,14,
|
||||
9,-6,75,-8,-7,-12,-15,-12,
|
||||
13,9,-4,30,-22,-65,15,0,
|
||||
-45,4,-4,1,5,22,11,23};
|
@ -1,119 +0,0 @@
|
||||
/*
|
||||
Copyright 1992, 1993, 1994 by Jutta Degener and Carsten Bormann,
|
||||
Technische Universitaet Berlin
|
||||
|
||||
Any use of this software is permitted provided that this notice is not
|
||||
removed and that neither the authors nor the Technische Universitaet Berlin
|
||||
are deemed to have made any representations as to the suitability of this
|
||||
software for any purpose nor are held responsible for any defects of
|
||||
this software. THERE IS ABSOLUTELY NO WARRANTY FOR THIS SOFTWARE.
|
||||
|
||||
As a matter of courtesy, the authors request to be informed about uses
|
||||
this software has found, about bugs in this software, and about any
|
||||
improvements that may be of general interest.
|
||||
|
||||
Berlin, 28.11.1994
|
||||
Jutta Degener
|
||||
Carsten Bormann
|
||||
|
||||
|
||||
Code slightly modified by Jean-Marc Valin
|
||||
|
||||
Speex License:
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions
|
||||
are met:
|
||||
|
||||
- Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
|
||||
- Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
|
||||
- Neither the name of the Xiph.org Foundation nor the names of its
|
||||
contributors may be used to endorse or promote products derived from
|
||||
this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR
|
||||
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
|
||||
|
||||
/* LPC- and Reflection Coefficients
|
||||
*
|
||||
* The next two functions calculate linear prediction coefficients
|
||||
* and/or the related reflection coefficients from the first P_MAX+1
|
||||
* values of the autocorrelation function.
|
||||
*/
|
||||
|
||||
/* Invented by N. Levinson in 1947, modified by J. Durbin in 1959.
|
||||
*/
|
||||
|
||||
#include "lpc.h"
|
||||
|
||||
float /* returns minimum mean square error */
|
||||
wld(
|
||||
float * lpc, /* [0...p-1] LPC coefficients */
|
||||
const float * ac, /* in: [0...p] autocorrelation values */
|
||||
float * ref, /* out: [0...p-1] reflection coef's */
|
||||
int p
|
||||
)
|
||||
{
|
||||
int i, j; float r, error = ac[0];
|
||||
|
||||
if (ac[0] == 0) {
|
||||
for (i = 0; i < p; i++) ref[i] = 0; return 0; }
|
||||
|
||||
for (i = 0; i < p; i++) {
|
||||
|
||||
/* Sum up this iteration's reflection coefficient.
|
||||
*/
|
||||
r = -ac[i + 1];
|
||||
for (j = 0; j < i; j++) r -= lpc[j] * ac[i - j];
|
||||
ref[i] = r /= error;
|
||||
|
||||
/* Update LPC coefficients and total error.
|
||||
*/
|
||||
lpc[i] = r;
|
||||
for (j = 0; j < i/2; j++) {
|
||||
float tmp = lpc[j];
|
||||
lpc[j] += r * lpc[i-1-j];
|
||||
lpc[i-1-j] += r * tmp;
|
||||
}
|
||||
if (i % 2) lpc[j] += lpc[j] * r;
|
||||
|
||||
error *= 1.0 - r * r;
|
||||
}
|
||||
return error;
|
||||
}
|
||||
|
||||
|
||||
/* Compute the autocorrelation
|
||||
* ,--,
|
||||
* ac(i) = > x(n) * x(n-i) for all n
|
||||
* `--'
|
||||
* for lags between 0 and lag-1, and x == 0 outside 0...n-1
|
||||
*/
|
||||
void _spx_autocorr(
|
||||
const float * x, /* in: [0...n-1] samples x */
|
||||
float *ac, /* out: [0...lag-1] ac values */
|
||||
int lag, int n)
|
||||
{
|
||||
float d; int i;
|
||||
while (lag--) {
|
||||
for (i = lag, d = 0; i < n; i++) d += x[i] * x[i-lag];
|
||||
ac[lag] = d;
|
||||
}
|
||||
}
|
@ -1,50 +0,0 @@
|
||||
/* Copyright (C) 2002 Jean-Marc Valin
|
||||
File: lpc.h
|
||||
Functions for LPC (Linear Prediction Coefficients) analysis
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions
|
||||
are met:
|
||||
|
||||
- Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
|
||||
- Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
|
||||
- Neither the name of the Xiph.org Foundation nor the names of its
|
||||
contributors may be used to endorse or promote products derived from
|
||||
this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR
|
||||
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef LPC_H
|
||||
#define LPC_H
|
||||
|
||||
void _spx_autocorr(
|
||||
const float * x, /* in: [0...n-1] samples x */
|
||||
float *ac, /* out: [0...lag-1] ac values */
|
||||
int lag, int n);
|
||||
|
||||
float /* returns minimum mean square error */
|
||||
wld(
|
||||
float * lpc, /* [0...p-1] LPC coefficients */
|
||||
const float * ac, /* in: [0...p] autocorrelation values */
|
||||
float * ref, /* out: [0...p-1] reflection coef's */
|
||||
int p
|
||||
);
|
||||
|
||||
|
||||
#endif
|
@ -1,328 +0,0 @@
|
||||
/*---------------------------------------------------------------------------*\
|
||||
Original copyright
|
||||
FILE........: AKSLSPD.C
|
||||
TYPE........: Turbo C
|
||||
COMPANY.....: Voicetronix
|
||||
AUTHOR......: David Rowe
|
||||
DATE CREATED: 24/2/93
|
||||
|
||||
Modified by Jean-Marc Valin
|
||||
|
||||
This file contains functions for converting Linear Prediction
|
||||
Coefficients (LPC) to Line Spectral Pair (LSP) and back. Note that the
|
||||
LSP coefficients are not in radians format but in the x domain of the
|
||||
unit circle.
|
||||
|
||||
Speex License:
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions
|
||||
are met:
|
||||
|
||||
- Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
|
||||
- Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
|
||||
- Neither the name of the Xiph.org Foundation nor the names of its
|
||||
contributors may be used to endorse or promote products derived from
|
||||
this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR
|
||||
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <math.h>
|
||||
#include "lsp.h"
|
||||
#include "stack_alloc.h"
|
||||
|
||||
|
||||
#ifndef M_PI
|
||||
#define M_PI 3.14159265358979323846 /* pi */
|
||||
#endif
|
||||
|
||||
#ifndef NULL
|
||||
#define NULL 0
|
||||
#endif
|
||||
|
||||
/*---------------------------------------------------------------------------*\
|
||||
|
||||
FUNCTION....: cheb_poly_eva()
|
||||
|
||||
AUTHOR......: David Rowe
|
||||
DATE CREATED: 24/2/93
|
||||
|
||||
This function evaluates a series of Chebyshev polynomials
|
||||
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
|
||||
|
||||
static float cheb_poly_eva(float *coef,float x,int m,char *stack)
|
||||
/* float coef[] coefficients of the polynomial to be evaluated */
|
||||
/* float x the point where polynomial is to be evaluated */
|
||||
/* int m order of the polynomial */
|
||||
{
|
||||
int i;
|
||||
float *T,sum;
|
||||
int m2=m>>1;
|
||||
|
||||
/* Allocate memory for Chebyshev series formulation */
|
||||
T=PUSH(stack, m2+1, float);
|
||||
|
||||
/* Initialise values */
|
||||
T[0]=1;
|
||||
T[1]=x;
|
||||
|
||||
/* Evaluate Chebyshev series formulation using iterative approach */
|
||||
/* Evaluate polynomial and return value also free memory space */
|
||||
sum = coef[m2] + coef[m2-1]*x;
|
||||
x *= 2;
|
||||
for(i=2;i<=m2;i++)
|
||||
{
|
||||
T[i] = x*T[i-1] - T[i-2];
|
||||
sum += coef[m2-i] * T[i];
|
||||
}
|
||||
|
||||
return sum;
|
||||
}
|
||||
|
||||
|
||||
/*---------------------------------------------------------------------------*\
|
||||
|
||||
FUNCTION....: lpc_to_lsp()
|
||||
|
||||
AUTHOR......: David Rowe
|
||||
DATE CREATED: 24/2/93
|
||||
|
||||
This function converts LPC coefficients to LSP
|
||||
coefficients.
|
||||
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
|
||||
int lpc_to_lsp (float *a,int lpcrdr,float *freq,int nb,float delta, char *stack)
|
||||
/* float *a lpc coefficients */
|
||||
/* int lpcrdr order of LPC coefficients (10) */
|
||||
/* float *freq LSP frequencies in the x domain */
|
||||
/* int nb number of sub-intervals (4) */
|
||||
/* float delta grid spacing interval (0.02) */
|
||||
|
||||
|
||||
{
|
||||
|
||||
float psuml,psumr,psumm,temp_xr,xl,xr,xm=0;
|
||||
float temp_psumr/*,temp_qsumr*/;
|
||||
int i,j,m,flag,k;
|
||||
float *Q; /* ptrs for memory allocation */
|
||||
float *P;
|
||||
float *px; /* ptrs of respective P'(z) & Q'(z) */
|
||||
float *qx;
|
||||
float *p;
|
||||
float *q;
|
||||
float *pt; /* ptr used for cheb_poly_eval()
|
||||
whether P' or Q' */
|
||||
int roots=0; /* DR 8/2/94: number of roots found */
|
||||
flag = 1; /* program is searching for a root when,
|
||||
1 else has found one */
|
||||
m = lpcrdr/2; /* order of P'(z) & Q'(z) polynomials */
|
||||
|
||||
|
||||
/* Allocate memory space for polynomials */
|
||||
Q = PUSH(stack, (m+1), float);
|
||||
P = PUSH(stack, (m+1), float);
|
||||
|
||||
/* determine P'(z)'s and Q'(z)'s coefficients where
|
||||
P'(z) = P(z)/(1 + z^(-1)) and Q'(z) = Q(z)/(1-z^(-1)) */
|
||||
|
||||
px = P; /* initialise ptrs */
|
||||
qx = Q;
|
||||
p = px;
|
||||
q = qx;
|
||||
*px++ = 1.0;
|
||||
*qx++ = 1.0;
|
||||
for(i=1;i<=m;i++){
|
||||
*px++ = a[i]+a[lpcrdr+1-i]-*p++;
|
||||
*qx++ = a[i]-a[lpcrdr+1-i]+*q++;
|
||||
}
|
||||
px = P;
|
||||
qx = Q;
|
||||
for(i=0;i<m;i++){
|
||||
*px = 2**px;
|
||||
*qx = 2**qx;
|
||||
px++;
|
||||
qx++;
|
||||
}
|
||||
px = P; /* re-initialise ptrs */
|
||||
qx = Q;
|
||||
|
||||
/* Search for a zero in P'(z) polynomial first and then alternate to Q'(z).
|
||||
Keep alternating between the two polynomials as each zero is found */
|
||||
|
||||
xr = 0; /* initialise xr to zero */
|
||||
xl = 1.0; /* start at point xl = 1 */
|
||||
|
||||
|
||||
for(j=0;j<lpcrdr;j++){
|
||||
if(j%2) /* determines whether P' or Q' is eval. */
|
||||
pt = qx;
|
||||
else
|
||||
pt = px;
|
||||
|
||||
psuml = cheb_poly_eva(pt,xl,lpcrdr,stack); /* evals poly. at xl */
|
||||
flag = 1;
|
||||
while(flag && (xr >= -1.0)){
|
||||
float dd;
|
||||
/* Modified by JMV to provide smaller steps around x=+-1 */
|
||||
dd=(delta*(1-.9*xl*xl));
|
||||
if (fabs(psuml)<.2)
|
||||
dd *= .5;
|
||||
|
||||
xr = xl - dd; /* interval spacing */
|
||||
psumr = cheb_poly_eva(pt,xr,lpcrdr,stack);/* poly(xl-delta_x) */
|
||||
temp_psumr = psumr;
|
||||
temp_xr = xr;
|
||||
|
||||
/* if no sign change increment xr and re-evaluate poly(xr). Repeat til
|
||||
sign change.
|
||||
if a sign change has occurred the interval is bisected and then
|
||||
checked again for a sign change which determines in which
|
||||
interval the zero lies in.
|
||||
If there is no sign change between poly(xm) and poly(xl) set interval
|
||||
between xm and xr else set interval between xl and xr and repeat till
|
||||
root is located within the specified limits */
|
||||
|
||||
if((psumr*psuml)<0.0){
|
||||
roots++;
|
||||
|
||||
psumm=psuml;
|
||||
for(k=0;k<=nb;k++){
|
||||
xm = (xl+xr)/2; /* bisect the interval */
|
||||
psumm=cheb_poly_eva(pt,xm,lpcrdr,stack);
|
||||
if(psumm*psuml>0.){
|
||||
psuml=psumm;
|
||||
xl=xm;
|
||||
}
|
||||
else{
|
||||
psumr=psumm;
|
||||
xr=xm;
|
||||
}
|
||||
}
|
||||
|
||||
/* once zero is found, reset initial interval to xr */
|
||||
freq[j] = (xm);
|
||||
xl = xm;
|
||||
flag = 0; /* reset flag for next search */
|
||||
}
|
||||
else{
|
||||
psuml=temp_psumr;
|
||||
xl=temp_xr;
|
||||
}
|
||||
}
|
||||
}
|
||||
return(roots);
|
||||
}
|
||||
|
||||
|
||||
/*---------------------------------------------------------------------------*\
|
||||
|
||||
FUNCTION....: lsp_to_lpc()
|
||||
|
||||
AUTHOR......: David Rowe
|
||||
DATE CREATED: 24/2/93
|
||||
|
||||
lsp_to_lpc: This function converts LSP coefficients to LPC
|
||||
coefficients.
|
||||
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
|
||||
void lsp_to_lpc(float *freq,float *ak,int lpcrdr, char *stack)
|
||||
/* float *freq array of LSP frequencies in the x domain */
|
||||
/* float *ak array of LPC coefficients */
|
||||
/* int lpcrdr order of LPC coefficients */
|
||||
|
||||
|
||||
{
|
||||
int i,j;
|
||||
float xout1,xout2,xin1,xin2;
|
||||
float *Wp;
|
||||
float *pw,*n1,*n2,*n3,*n4=NULL;
|
||||
int m = lpcrdr/2;
|
||||
|
||||
Wp = PUSH(stack, 4*m+2, float);
|
||||
pw = Wp;
|
||||
|
||||
/* initialise contents of array */
|
||||
|
||||
for(i=0;i<=4*m+1;i++){ /* set contents of buffer to 0 */
|
||||
*pw++ = 0.0;
|
||||
}
|
||||
|
||||
/* Set pointers up */
|
||||
|
||||
pw = Wp;
|
||||
xin1 = 1.0;
|
||||
xin2 = 1.0;
|
||||
|
||||
/* reconstruct P(z) and Q(z) by cascading second order
|
||||
polynomials in form 1 - 2xz(-1) +z(-2), where x is the
|
||||
LSP coefficient */
|
||||
|
||||
for(j=0;j<=lpcrdr;j++){
|
||||
int i2=0;
|
||||
for(i=0;i<m;i++,i2+=2){
|
||||
n1 = pw+(i*4);
|
||||
n2 = n1 + 1;
|
||||
n3 = n2 + 1;
|
||||
n4 = n3 + 1;
|
||||
xout1 = xin1 - 2*(freq[i2]) * *n1 + *n2;
|
||||
xout2 = xin2 - 2*(freq[i2+1]) * *n3 + *n4;
|
||||
*n2 = *n1;
|
||||
*n4 = *n3;
|
||||
*n1 = xin1;
|
||||
*n3 = xin2;
|
||||
xin1 = xout1;
|
||||
xin2 = xout2;
|
||||
}
|
||||
xout1 = xin1 + *(n4+1);
|
||||
xout2 = xin2 - *(n4+2);
|
||||
ak[j] = (xout1 + xout2)*0.5;
|
||||
*(n4+1) = xin1;
|
||||
*(n4+2) = xin2;
|
||||
|
||||
xin1 = 0.0;
|
||||
xin2 = 0.0;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/*Added by JMV
|
||||
Makes sure the LSPs are stable*/
|
||||
void lsp_enforce_margin(float *lsp, int len, float margin)
|
||||
{
|
||||
int i;
|
||||
if (lsp[0]<margin)
|
||||
lsp[0]=margin;
|
||||
if (lsp[len-1]>M_PI-margin)
|
||||
lsp[len-1]=M_PI-margin;
|
||||
for (i=1;i<len-1;i++)
|
||||
{
|
||||
if (lsp[i]<lsp[i-1]+margin)
|
||||
lsp[i]=lsp[i-1]+margin;
|
||||
|
||||
if (lsp[i]>lsp[i+1]-margin)
|
||||
lsp[i]= .5* (lsp[i] + lsp[i+1]-margin);
|
||||
}
|
||||
}
|
@ -1,57 +0,0 @@
|
||||
/*---------------------------------------------------------------------------*\
|
||||
Original Copyright
|
||||
FILE........: AK2LSPD.H
|
||||
TYPE........: Turbo C header file
|
||||
COMPANY.....: Voicetronix
|
||||
AUTHOR......: James Whitehall
|
||||
DATE CREATED: 21/11/95
|
||||
|
||||
Modified by Jean-Marc Valin
|
||||
|
||||
This file contains functions for converting Linear Prediction
|
||||
Coefficients (LPC) to Line Spectral Pair (LSP) and back. Note that the
|
||||
LSP coefficients are not in radians format but in the x domain of the
|
||||
unit circle.
|
||||
|
||||
\*---------------------------------------------------------------------------*/
|
||||
/* Speex License:
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions
|
||||
are met:
|
||||
|
||||
- Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
|
||||
- Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
|
||||
- Neither the name of the Xiph.org Foundation nor the names of its
|
||||
contributors may be used to endorse or promote products derived from
|
||||
this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR
|
||||
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef __AK2LSPD__
|
||||
#define __AK2LSPD__
|
||||
|
||||
int lpc_to_lsp (float *a, int lpcrdr, float *freq, int nb, float delta, char *stack);
|
||||
void lsp_to_lpc(float *freq, float *ak, int lpcrdr, char *stack);
|
||||
|
||||
/*Added by JMV*/
|
||||
void lsp_enforce_margin(float *lsp, int len, float margin);
|
||||
|
||||
|
||||
#endif /* __AK2LSPD__ */
|
@ -1,360 +0,0 @@
|
||||
/* Copyright (C) 2002 Jean-Marc Valin
|
||||
File: lsp_tables_nb.c
|
||||
Codebooks for LSPs in narrowband CELP mode
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are
|
||||
met:
|
||||
|
||||
1. Redistributions of source code must retain the above copyright notice,
|
||||
this list of conditions and the following disclaimer.
|
||||
|
||||
2. Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
|
||||
3. The name of the author may not be used to endorse or promote products
|
||||
derived from this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
||||
IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
|
||||
INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||
STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||||
ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
signed char cdbk_nb[640]={
|
||||
30,19,38,34,40,32,46,43,58,43,
|
||||
5,-18,-25,-40,-33,-55,-52,20,34,28,
|
||||
-20,-63,-97,-92,61,53,47,49,53,75,
|
||||
-14,-53,-77,-79,0,-3,-5,19,22,26,
|
||||
-9,-53,-55,66,90,72,85,68,74,52,
|
||||
-4,-41,-58,-31,-18,-31,27,32,30,18,
|
||||
24,3,8,5,-12,-3,26,28,74,63,
|
||||
-2,-39,-67,-77,-106,-74,59,59,73,65,
|
||||
44,40,71,72,82,83,98,88,89,60,
|
||||
-6,-31,-47,-48,-13,-39,-9,7,2,79,
|
||||
-1,-39,-60,-17,87,81,65,50,45,19,
|
||||
-21,-67,-91,-87,-41,-50,7,18,39,74,
|
||||
10,-31,-28,39,24,13,23,5,56,45,
|
||||
29,10,-5,-13,-11,-35,-18,-8,-10,-8,
|
||||
-25,-71,-77,-21,2,16,50,63,87,87,
|
||||
5,-32,-40,-51,-68,0,12,6,54,34,
|
||||
5,-12,32,52,68,64,69,59,65,45,
|
||||
14,-16,-31,-40,-65,-67,41,49,47,37,
|
||||
-11,-52,-75,-84,-4,57,48,42,42,33,
|
||||
-11,-51,-68,-6,13,0,8,-8,26,32,
|
||||
-23,-53,0,36,56,76,97,105,111,97,
|
||||
-1,-28,-39,-40,-43,-54,-44,-40,-18,35,
|
||||
16,-20,-19,-28,-42,29,47,38,74,45,
|
||||
3,-29,-48,-62,-80,-104,-33,56,59,59,
|
||||
10,17,46,72,84,101,117,123,123,106,
|
||||
-7,-33,-49,-51,-70,-67,-27,-31,70,67,
|
||||
-16,-62,-85,-20,82,71,86,80,85,74,
|
||||
-19,-58,-75,-45,-29,-33,-18,-25,45,57,
|
||||
-12,-42,-5,12,28,36,52,64,81,82,
|
||||
13,-9,-27,-28,22,3,2,22,26,6,
|
||||
-6,-44,-51,2,15,10,48,43,49,34,
|
||||
-19,-62,-84,-89,-102,-24,8,17,61,68,
|
||||
39,24,23,19,16,-5,12,15,27,15,
|
||||
-8,-44,-49,-60,-18,-32,-28,52,54,62,
|
||||
-8,-48,-77,-70,66,101,83,63,61,37,
|
||||
-12,-50,-75,-64,33,17,13,25,15,77,
|
||||
1,-42,-29,72,64,46,49,31,61,44,
|
||||
-8,-47,-54,-46,-30,19,20,-1,-16,0,
|
||||
16,-12,-18,-9,-26,-27,-10,-22,53,45,
|
||||
-10,-47,-75,-82,-105,-109,8,25,49,77,
|
||||
50,65,114,117,124,118,115,96,90,61,
|
||||
-9,-45,-63,-60,-75,-57,8,11,20,29,
|
||||
0,-35,-49,-43,40,47,35,40,55,38,
|
||||
-24,-76,-103,-112,-27,3,23,34,52,75,
|
||||
8,-29,-43,12,63,38,35,29,24,8,
|
||||
25,11,1,-15,-18,-43,-7,37,40,21,
|
||||
-20,-56,-19,-19,-4,-2,11,29,51,63,
|
||||
-2,-44,-62,-75,-89,30,57,51,74,51,
|
||||
50,46,68,64,65,52,63,55,65,43,
|
||||
18,-9,-26,-35,-55,-69,3,6,8,17,
|
||||
-15,-61,-86,-97,1,86,93,74,78,67,
|
||||
-1,-38,-66,-48,48,39,29,25,17,-1,
|
||||
13,13,29,39,50,51,69,82,97,98,
|
||||
-2,-36,-46,-27,-16,-30,-13,-4,-7,-4,
|
||||
25,-5,-11,-6,-25,-21,33,12,31,29,
|
||||
-8,-38,-52,-63,-68,-89,-33,-1,10,74,
|
||||
-2,-15,59,91,105,105,101,87,84,62,
|
||||
-7,-33,-50,-35,-54,-47,25,17,82,81,
|
||||
-13,-56,-83,21,58,31,42,25,72,65,
|
||||
-24,-66,-91,-56,9,-2,21,10,69,75,
|
||||
2,-24,11,22,25,28,38,34,48,33,
|
||||
7,-29,-26,17,15,-1,14,0,-2,0,
|
||||
-6,-41,-67,6,-2,-9,19,2,85,74,
|
||||
-22,-67,-84,-71,-50,3,11,-9,2,62};
|
||||
|
||||
signed char cdbk_nb_low1[320]={
|
||||
-34,-52,-15,45,2,
|
||||
23,21,52,24,-33,
|
||||
-9,-1,9,-44,-41,
|
||||
-13,-17,44,22,-17,
|
||||
-6,-4,-1,22,38,
|
||||
26,16,2,50,27,
|
||||
-35,-34,-9,-41,6,
|
||||
0,-16,-34,51,8,
|
||||
-14,-31,-49,15,-33,
|
||||
45,49,33,-11,-37,
|
||||
-62,-54,45,11,-5,
|
||||
-72,11,-1,-12,-11,
|
||||
24,27,-11,-43,46,
|
||||
43,33,-12,-9,-1,
|
||||
1,-4,-23,-57,-71,
|
||||
11,8,16,17,-8,
|
||||
-20,-31,-41,53,48,
|
||||
-16,3,65,-24,-8,
|
||||
-23,-32,-37,-32,-49,
|
||||
-10,-17,6,38,5,
|
||||
-9,-17,-46,8,52,
|
||||
3,6,45,40,39,
|
||||
-7,-6,-34,-74,31,
|
||||
8,1,-16,43,68,
|
||||
-11,-19,-31,4,6,
|
||||
0,-6,-17,-16,-38,
|
||||
-16,-30,2,9,-39,
|
||||
-16,-1,43,-10,48,
|
||||
3,3,-16,-31,-3,
|
||||
62,68,43,13,3,
|
||||
-10,8,20,-56,12,
|
||||
12,-2,-18,22,-15,
|
||||
-40,-36,1,7,41,
|
||||
0,1,46,-6,-62,
|
||||
-4,-12,-2,-11,-83,
|
||||
-13,-2,91,33,-10,
|
||||
0,4,-11,-16,79,
|
||||
32,37,14,9,51,
|
||||
-21,-28,-56,-34,0,
|
||||
21,9,-26,11,28,
|
||||
-42,-54,-23,-2,-15,
|
||||
31,30,8,-39,-66,
|
||||
-39,-36,31,-28,-40,
|
||||
-46,35,40,22,24,
|
||||
33,48,23,-34,14,
|
||||
40,32,17,27,-3,
|
||||
25,26,-13,-61,-17,
|
||||
11,4,31,60,-6,
|
||||
-26,-41,-64,13,16,
|
||||
-26,54,31,-11,-23,
|
||||
-9,-11,-34,-71,-21,
|
||||
-34,-35,55,50,29,
|
||||
-22,-27,-50,-38,57,
|
||||
33,42,57,48,26,
|
||||
11,0,-49,-31,26,
|
||||
-4,-14,5,78,37,
|
||||
17,0,-49,-12,-23,
|
||||
26,14,2,2,-43,
|
||||
-17,-12,10,-8,-4,
|
||||
8,18,12,-6,20,
|
||||
-12,-6,-13,-25,34,
|
||||
15,40,49,7,8,
|
||||
13,20,20,-19,-22,
|
||||
-2,-8,2,51,-51};
|
||||
|
||||
signed char cdbk_nb_low2[320]={
|
||||
-6,53,-21,-24,4,
|
||||
26,17,-4,-37,25,
|
||||
17,-36,-13,31,3,
|
||||
-6,27,15,-10,31,
|
||||
28,26,-10,-10,-40,
|
||||
16,-7,15,13,41,
|
||||
-9,0,-4,50,-6,
|
||||
-7,14,38,22,0,
|
||||
-48,2,1,-13,-19,
|
||||
32,-3,-60,11,-17,
|
||||
-1,-24,-34,-1,35,
|
||||
-5,-27,28,44,13,
|
||||
25,15,42,-11,15,
|
||||
51,35,-36,20,8,
|
||||
-4,-12,-29,19,-47,
|
||||
49,-15,-4,16,-29,
|
||||
-39,14,-30,4,25,
|
||||
-9,-5,-51,-14,-3,
|
||||
-40,-32,38,5,-9,
|
||||
-8,-4,-1,-22,71,
|
||||
-3,14,26,-18,-22,
|
||||
24,-41,-25,-24,6,
|
||||
23,19,-10,39,-26,
|
||||
-27,65,45,2,-7,
|
||||
-26,-8,22,-12,16,
|
||||
15,16,-35,-5,33,
|
||||
-21,-8,0,23,33,
|
||||
34,6,21,36,6,
|
||||
-7,-22,8,-37,-14,
|
||||
31,38,11,-4,-3,
|
||||
-39,-32,-8,32,-23,
|
||||
-6,-12,16,20,-28,
|
||||
-4,23,13,-52,-1,
|
||||
22,6,-33,-40,-6,
|
||||
4,-62,13,5,-26,
|
||||
35,39,11,2,57,
|
||||
-11,9,-20,-28,-33,
|
||||
52,-5,-6,-2,22,
|
||||
-14,-16,-48,35,1,
|
||||
-58,20,13,33,-1,
|
||||
-74,56,-18,-22,-31,
|
||||
12,6,-14,4,-2,
|
||||
-9,-47,10,-3,29,
|
||||
-17,-5,61,14,47,
|
||||
-12,2,72,-39,-17,
|
||||
92,64,-53,-51,-15,
|
||||
-30,-38,-41,-29,-28,
|
||||
27,9,36,9,-35,
|
||||
-42,81,-21,20,25,
|
||||
-16,-5,-17,-35,21,
|
||||
15,-28,48,2,-2,
|
||||
9,-19,29,-40,30,
|
||||
-18,-18,18,-16,-57,
|
||||
15,-20,-12,-15,-37,
|
||||
-15,33,-39,21,-22,
|
||||
-13,35,11,13,-38,
|
||||
-63,29,23,-27,32,
|
||||
18,3,-26,42,33,
|
||||
-64,-66,-17,16,56,
|
||||
2,36,3,31,21,
|
||||
-41,-39,8,-57,14,
|
||||
37,-2,19,-36,-19,
|
||||
-23,-29,-16,1,-3,
|
||||
-8,-10,31,64,-65};
|
||||
|
||||
signed char cdbk_nb_high1[320]={
|
||||
-26,-8,29,21,4,
|
||||
19,-39,33,-7,-36,
|
||||
56,54,48,40,29,
|
||||
-4,-24,-42,-66,-43,
|
||||
-60,19,-2,37,41,
|
||||
-10,-37,-60,-64,18,
|
||||
-22,77,73,40,25,
|
||||
4,19,-19,-66,-2,
|
||||
11,5,21,14,26,
|
||||
-25,-86,-4,18,1,
|
||||
26,-37,10,37,-1,
|
||||
24,-12,-59,-11,20,
|
||||
-6,34,-16,-16,42,
|
||||
19,-28,-51,53,32,
|
||||
4,10,62,21,-12,
|
||||
-34,27,4,-48,-48,
|
||||
-50,-49,31,-7,-21,
|
||||
-42,-25,-4,-43,-22,
|
||||
59,2,27,12,-9,
|
||||
-6,-16,-8,-32,-58,
|
||||
-16,-29,-5,41,23,
|
||||
-30,-33,-46,-13,-10,
|
||||
-38,52,52,1,-17,
|
||||
-9,10,26,-25,-6,
|
||||
33,-20,53,55,25,
|
||||
-32,-5,-42,23,21,
|
||||
66,5,-28,20,9,
|
||||
75,29,-7,-42,-39,
|
||||
15,3,-23,21,6,
|
||||
11,1,-29,14,63,
|
||||
10,54,26,-24,-51,
|
||||
-49,7,-23,-51,15,
|
||||
-66,1,60,25,10,
|
||||
0,-30,-4,-15,17,
|
||||
19,59,40,4,-5,
|
||||
33,6,-22,-58,-70,
|
||||
-5,23,-6,60,44,
|
||||
-29,-16,-47,-29,52,
|
||||
-19,50,28,16,35,
|
||||
31,36,0,-21,6,
|
||||
21,27,22,42,7,
|
||||
-66,-40,-8,7,19,
|
||||
46,0,-4,60,36,
|
||||
45,-7,-29,-6,-32,
|
||||
-39,2,6,-9,33,
|
||||
20,-51,-34,18,-6,
|
||||
19,6,11,5,-19,
|
||||
-29,-2,42,-11,-45,
|
||||
-21,-55,57,37,2,
|
||||
-14,-67,-16,-27,-38,
|
||||
69,48,19,2,-17,
|
||||
20,-20,-16,-34,-17,
|
||||
-25,-61,10,73,45,
|
||||
16,-40,-64,-17,-29,
|
||||
-22,56,17,-39,8,
|
||||
-11,8,-25,-18,-13,
|
||||
-19,8,54,57,36,
|
||||
-17,-26,-4,6,-21,
|
||||
40,42,-4,20,31,
|
||||
53,10,-34,-53,31,
|
||||
-17,35,0,15,-6,
|
||||
-20,-63,-73,22,25,
|
||||
29,17,8,-29,-39,
|
||||
-69,18,15,-15,-5};
|
||||
|
||||
signed char cdbk_nb_high2[320]={
|
||||
11,47,16,-9,-46,
|
||||
-32,26,-64,34,-5,
|
||||
38,-7,47,20,2,
|
||||
-73,-99,-3,-45,20,
|
||||
70,-52,15,-6,-7,
|
||||
-82,31,21,47,51,
|
||||
39,-3,9,0,-41,
|
||||
-7,-15,-54,2,0,
|
||||
27,-31,9,-45,-22,
|
||||
-38,-24,-24,8,-33,
|
||||
23,5,50,-36,-17,
|
||||
-18,-51,-2,13,19,
|
||||
43,12,-15,-12,61,
|
||||
38,38,7,13,0,
|
||||
6,-1,3,62,9,
|
||||
27,22,-33,38,-35,
|
||||
-9,30,-43,-9,-32,
|
||||
-1,4,-4,1,-5,
|
||||
-11,-8,38,31,11,
|
||||
-10,-42,-21,-37,1,
|
||||
43,15,-13,-35,-19,
|
||||
-18,15,23,-26,59,
|
||||
1,-21,53,8,-41,
|
||||
-50,-14,-28,4,21,
|
||||
25,-28,-40,5,-40,
|
||||
-41,4,51,-33,-8,
|
||||
-8,1,17,-60,12,
|
||||
25,-41,17,34,43,
|
||||
19,45,7,-37,24,
|
||||
-15,56,-2,35,-10,
|
||||
48,4,-47,-2,5,
|
||||
-5,-54,5,-3,-33,
|
||||
-10,30,-2,-44,-24,
|
||||
-38,9,-9,42,4,
|
||||
6,-56,44,-16,9,
|
||||
-40,-26,18,-20,10,
|
||||
28,-41,-21,-4,13,
|
||||
-18,32,-30,-3,37,
|
||||
15,22,28,50,-40,
|
||||
3,-29,-64,7,51,
|
||||
-19,-11,17,-27,-40,
|
||||
-64,24,-12,-7,-27,
|
||||
3,37,48,-1,2,
|
||||
-9,-38,-34,46,1,
|
||||
27,-6,19,-13,26,
|
||||
10,34,20,25,40,
|
||||
50,-6,-7,30,9,
|
||||
-24,0,-23,71,-61,
|
||||
22,58,-34,-4,2,
|
||||
-49,-33,25,30,-8,
|
||||
-6,-16,77,2,38,
|
||||
-8,-35,-6,-30,56,
|
||||
78,31,33,-20,13,
|
||||
-39,20,22,4,21,
|
||||
-8,4,-6,10,-83,
|
||||
-41,9,-25,-43,15,
|
||||
-7,-12,-34,-39,-37,
|
||||
-33,19,30,16,-33,
|
||||
42,-25,25,-68,44,
|
||||
-15,-11,-4,23,50,
|
||||
14,4,-39,-43,20,
|
||||
-30,60,9,-20,7,
|
||||
16,19,-33,37,29,
|
||||
16,-35,7,38,-27};
|
@ -1,548 +0,0 @@
|
||||
/* Copyright (C) 2002 Jean-Marc Valin
|
||||
File: ltp.c
|
||||
Long-Term Prediction functions
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions
|
||||
are met:
|
||||
|
||||
- Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
|
||||
- Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
|
||||
- Neither the name of the Xiph.org Foundation nor the names of its
|
||||
contributors may be used to endorse or promote products derived from
|
||||
this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR
|
||||
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <math.h>
|
||||
#include "ltp.h"
|
||||
#include "stack_alloc.h"
|
||||
#include "filters.h"
|
||||
#include "speex_bits.h"
|
||||
|
||||
#ifdef _USE_SSE
|
||||
#include "ltp_sse.h"
|
||||
#else
|
||||
static float inner_prod(float *x, float *y, int len)
|
||||
{
|
||||
int i;
|
||||
float sum1=0,sum2=0,sum3=0,sum4=0;
|
||||
for (i=0;i<len;)
|
||||
{
|
||||
sum1 += x[i]*y[i];
|
||||
sum2 += x[i+1]*y[i+1];
|
||||
sum3 += x[i+2]*y[i+2];
|
||||
sum4 += x[i+3]*y[i+3];
|
||||
i+=4;
|
||||
}
|
||||
return sum1+sum2+sum3+sum4;
|
||||
}
|
||||
#endif
|
||||
|
||||
/*Original, non-optimized version*/
|
||||
/*static float inner_prod(float *x, float *y, int len)
|
||||
{
|
||||
int i;
|
||||
float sum=0;
|
||||
for (i=0;i<len;i++)
|
||||
sum += x[i]*y[i];
|
||||
return sum;
|
||||
}
|
||||
*/
|
||||
|
||||
|
||||
void open_loop_nbest_pitch(float *sw, int start, int end, int len, int *pitch, float *gain, int N, char *stack)
|
||||
{
|
||||
int i,j,k;
|
||||
/*float corr=0;*/
|
||||
/*float energy;*/
|
||||
float *best_score;
|
||||
float e0;
|
||||
float *corr, *energy, *score;
|
||||
|
||||
best_score = PUSH(stack,N, float);
|
||||
corr = PUSH(stack,end-start+1, float);
|
||||
energy = PUSH(stack,end-start+2, float);
|
||||
score = PUSH(stack,end-start+1, float);
|
||||
for (i=0;i<N;i++)
|
||||
{
|
||||
best_score[i]=-1;
|
||||
gain[i]=0;
|
||||
}
|
||||
energy[0]=inner_prod(sw-start, sw-start, len);
|
||||
e0=inner_prod(sw, sw, len);
|
||||
for (i=start;i<=end;i++)
|
||||
{
|
||||
/* Update energy for next pitch*/
|
||||
energy[i-start+1] = energy[i-start] + sw[-i-1]*sw[-i-1] - sw[-i+len-1]*sw[-i+len-1];
|
||||
}
|
||||
for (i=start;i<=end;i++)
|
||||
{
|
||||
corr[i-start]=0;
|
||||
score[i-start]=0;
|
||||
}
|
||||
|
||||
for (i=start;i<=end;i++)
|
||||
{
|
||||
/* Compute correlation*/
|
||||
corr[i-start]=inner_prod(sw, sw-i, len);
|
||||
score[i-start]=corr[i-start]*corr[i-start]/(energy[i-start]+1);
|
||||
}
|
||||
for (i=start;i<=end;i++)
|
||||
{
|
||||
if (score[i-start]>best_score[N-1])
|
||||
{
|
||||
float g1, g;
|
||||
g1 = corr[i-start]/(energy[i-start]+10);
|
||||
g = sqrt(g1*corr[i-start]/(e0+10));
|
||||
if (g>g1)
|
||||
g=g1;
|
||||
if (g<0)
|
||||
g=0;
|
||||
for (j=0;j<N;j++)
|
||||
{
|
||||
if (score[i-start] > best_score[j])
|
||||
{
|
||||
for (k=N-1;k>j;k--)
|
||||
{
|
||||
best_score[k]=best_score[k-1];
|
||||
pitch[k]=pitch[k-1];
|
||||
gain[k] = gain[k-1];
|
||||
}
|
||||
best_score[j]=score[i-start];
|
||||
pitch[j]=i;
|
||||
gain[j]=g;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/** Finds the best quantized 3-tap pitch predictor by analysis by synthesis */
|
||||
float pitch_gain_search_3tap(
|
||||
float target[], /* Target vector */
|
||||
float ak[], /* LPCs for this subframe */
|
||||
float awk1[], /* Weighted LPCs #1 for this subframe */
|
||||
float awk2[], /* Weighted LPCs #2 for this subframe */
|
||||
float exc[], /* Excitation */
|
||||
void *par,
|
||||
int pitch, /* Pitch value */
|
||||
int p, /* Number of LPC coeffs */
|
||||
int nsf, /* Number of samples in subframe */
|
||||
SpeexBits *bits,
|
||||
char *stack,
|
||||
float *exc2,
|
||||
float *r,
|
||||
int *cdbk_index
|
||||
)
|
||||
{
|
||||
int i,j;
|
||||
float *tmp, *tmp2;
|
||||
float *x[3];
|
||||
float *e[3];
|
||||
float corr[3];
|
||||
float A[3][3];
|
||||
float gain[3];
|
||||
int gain_cdbk_size;
|
||||
signed char *gain_cdbk;
|
||||
float err1,err2;
|
||||
|
||||
ltp_params *params;
|
||||
params = (ltp_params*) par;
|
||||
gain_cdbk=params->gain_cdbk;
|
||||
gain_cdbk_size=1<<params->gain_bits;
|
||||
tmp = PUSH(stack, 3*nsf, float);
|
||||
tmp2 = PUSH(stack, 3*nsf, float);
|
||||
|
||||
x[0]=tmp;
|
||||
x[1]=tmp+nsf;
|
||||
x[2]=tmp+2*nsf;
|
||||
|
||||
e[0]=tmp2;
|
||||
e[1]=tmp2+nsf;
|
||||
e[2]=tmp2+2*nsf;
|
||||
|
||||
for (i=2;i>=0;i--)
|
||||
{
|
||||
int pp=pitch+1-i;
|
||||
for (j=0;j<nsf;j++)
|
||||
{
|
||||
if (j-pp<0)
|
||||
e[i][j]=exc2[j-pp];
|
||||
else if (j-pp-pitch<0)
|
||||
e[i][j]=exc2[j-pp-pitch];
|
||||
else
|
||||
e[i][j]=0;
|
||||
}
|
||||
|
||||
if (i==2)
|
||||
syn_percep_zero(e[i], ak, awk1, awk2, x[i], nsf, p, stack);
|
||||
else {
|
||||
for (j=0;j<nsf-1;j++)
|
||||
x[i][j+1]=x[i+1][j];
|
||||
x[i][0]=0;
|
||||
for (j=0;j<nsf;j++)
|
||||
x[i][j]+=e[i][0]*r[j];
|
||||
}
|
||||
}
|
||||
|
||||
for (i=0;i<3;i++)
|
||||
corr[i]=inner_prod(x[i],target,nsf);
|
||||
|
||||
for (i=0;i<3;i++)
|
||||
for (j=0;j<=i;j++)
|
||||
A[i][j]=A[j][i]=inner_prod(x[i],x[j],nsf);
|
||||
|
||||
{
|
||||
float C[9];
|
||||
signed char *ptr=gain_cdbk;
|
||||
int best_cdbk=0;
|
||||
float best_sum=0;
|
||||
C[0]=corr[2];
|
||||
C[1]=corr[1];
|
||||
C[2]=corr[0];
|
||||
C[3]=A[1][2];
|
||||
C[4]=A[0][1];
|
||||
C[5]=A[0][2];
|
||||
C[6]=A[2][2];
|
||||
C[7]=A[1][1];
|
||||
C[8]=A[0][0];
|
||||
|
||||
for (i=0;i<gain_cdbk_size;i++)
|
||||
{
|
||||
float sum=0;
|
||||
float g0,g1,g2;
|
||||
ptr = gain_cdbk+3*i;
|
||||
g0=0.015625*ptr[0]+.5;
|
||||
g1=0.015625*ptr[1]+.5;
|
||||
g2=0.015625*ptr[2]+.5;
|
||||
|
||||
sum += C[0]*g0;
|
||||
sum += C[1]*g1;
|
||||
sum += C[2]*g2;
|
||||
sum -= C[3]*g0*g1;
|
||||
sum -= C[4]*g2*g1;
|
||||
sum -= C[5]*g2*g0;
|
||||
sum -= .5*C[6]*g0*g0;
|
||||
sum -= .5*C[7]*g1*g1;
|
||||
sum -= .5*C[8]*g2*g2;
|
||||
|
||||
/* If 1, force "safe" pitch values to handle packet loss better */
|
||||
if (0) {
|
||||
float tot = fabs(ptr[1]);
|
||||
if (ptr[0]>0)
|
||||
tot+=ptr[0];
|
||||
if (ptr[2]>0)
|
||||
tot+=ptr[2];
|
||||
if (tot>1)
|
||||
continue;
|
||||
}
|
||||
|
||||
if (sum>best_sum || i==0)
|
||||
{
|
||||
best_sum=sum;
|
||||
best_cdbk=i;
|
||||
}
|
||||
}
|
||||
gain[0] = 0.015625*gain_cdbk[best_cdbk*3] + .5;
|
||||
gain[1] = 0.015625*gain_cdbk[best_cdbk*3+1]+ .5;
|
||||
gain[2] = 0.015625*gain_cdbk[best_cdbk*3+2]+ .5;
|
||||
|
||||
*cdbk_index=best_cdbk;
|
||||
}
|
||||
|
||||
for (i=0;i<nsf;i++)
|
||||
exc[i]=gain[0]*e[2][i]+gain[1]*e[1][i]+gain[2]*e[0][i];
|
||||
|
||||
err1=0;
|
||||
err2=0;
|
||||
for (i=0;i<nsf;i++)
|
||||
err1+=target[i]*target[i];
|
||||
for (i=0;i<nsf;i++)
|
||||
err2+=(target[i]-gain[2]*x[0][i]-gain[1]*x[1][i]-gain[0]*x[2][i])
|
||||
* (target[i]-gain[2]*x[0][i]-gain[1]*x[1][i]-gain[0]*x[2][i]);
|
||||
|
||||
return err2;
|
||||
}
|
||||
|
||||
|
||||
/** Finds the best quantized 3-tap pitch predictor by analysis by synthesis */
|
||||
int pitch_search_3tap(
|
||||
float target[], /* Target vector */
|
||||
float *sw,
|
||||
float ak[], /* LPCs for this subframe */
|
||||
float awk1[], /* Weighted LPCs #1 for this subframe */
|
||||
float awk2[], /* Weighted LPCs #2 for this subframe */
|
||||
float exc[], /* Excitation */
|
||||
void *par,
|
||||
int start, /* Smallest pitch value allowed */
|
||||
int end, /* Largest pitch value allowed */
|
||||
float pitch_coef, /* Voicing (pitch) coefficient */
|
||||
int p, /* Number of LPC coeffs */
|
||||
int nsf, /* Number of samples in subframe */
|
||||
SpeexBits *bits,
|
||||
char *stack,
|
||||
float *exc2,
|
||||
float *r,
|
||||
int complexity
|
||||
)
|
||||
{
|
||||
int i,j;
|
||||
int cdbk_index, pitch=0, best_gain_index=0;
|
||||
float *best_exc;
|
||||
int best_pitch=0;
|
||||
float err, best_err=-1;
|
||||
int N;
|
||||
ltp_params *params;
|
||||
int *nbest;
|
||||
float *gains;
|
||||
|
||||
N=complexity;
|
||||
if (N>10)
|
||||
N=10;
|
||||
|
||||
nbest=PUSH(stack, N, int);
|
||||
gains = PUSH(stack, N, float);
|
||||
params = (ltp_params*) par;
|
||||
|
||||
if (N==0 || end<start)
|
||||
{
|
||||
speex_bits_pack(bits, 0, params->pitch_bits);
|
||||
speex_bits_pack(bits, 0, params->gain_bits);
|
||||
for (i=0;i<nsf;i++)
|
||||
exc[i]=0;
|
||||
return start;
|
||||
}
|
||||
|
||||
best_exc=PUSH(stack,nsf, float);
|
||||
|
||||
if (N>end-start+1)
|
||||
N=end-start+1;
|
||||
open_loop_nbest_pitch(sw, start, end, nsf, nbest, gains, N, stack);
|
||||
for (i=0;i<N;i++)
|
||||
{
|
||||
pitch=nbest[i];
|
||||
for (j=0;j<nsf;j++)
|
||||
exc[j]=0;
|
||||
err=pitch_gain_search_3tap(target, ak, awk1, awk2, exc, par, pitch, p, nsf,
|
||||
bits, stack, exc2, r, &cdbk_index);
|
||||
if (err<best_err || best_err<0)
|
||||
{
|
||||
for (j=0;j<nsf;j++)
|
||||
best_exc[j]=exc[j];
|
||||
best_err=err;
|
||||
best_pitch=pitch;
|
||||
best_gain_index=cdbk_index;
|
||||
}
|
||||
}
|
||||
|
||||
/*printf ("pitch: %d %d\n", best_pitch, best_gain_index);*/
|
||||
speex_bits_pack(bits, best_pitch-start, params->pitch_bits);
|
||||
speex_bits_pack(bits, best_gain_index, params->gain_bits);
|
||||
/*printf ("encode pitch: %d %d\n", best_pitch, best_gain_index);*/
|
||||
for (i=0;i<nsf;i++)
|
||||
exc[i]=best_exc[i];
|
||||
|
||||
return pitch;
|
||||
}
|
||||
|
||||
void pitch_unquant_3tap(
|
||||
float exc[], /* Excitation */
|
||||
int start, /* Smallest pitch value allowed */
|
||||
int end, /* Largest pitch value allowed */
|
||||
float pitch_coef, /* Voicing (pitch) coefficient */
|
||||
void *par,
|
||||
int nsf, /* Number of samples in subframe */
|
||||
int *pitch_val,
|
||||
float *gain_val,
|
||||
SpeexBits *bits,
|
||||
char *stack,
|
||||
int count_lost,
|
||||
int subframe_offset,
|
||||
float last_pitch_gain)
|
||||
{
|
||||
int i;
|
||||
int pitch;
|
||||
int gain_index;
|
||||
float gain[3];
|
||||
signed char *gain_cdbk;
|
||||
ltp_params *params;
|
||||
params = (ltp_params*) par;
|
||||
gain_cdbk=params->gain_cdbk;
|
||||
|
||||
pitch = speex_bits_unpack_unsigned(bits, params->pitch_bits);
|
||||
pitch += start;
|
||||
gain_index = speex_bits_unpack_unsigned(bits, params->gain_bits);
|
||||
/*printf ("decode pitch: %d %d\n", pitch, gain_index);*/
|
||||
gain[0] = 0.015625*gain_cdbk[gain_index*3]+.5;
|
||||
gain[1] = 0.015625*gain_cdbk[gain_index*3+1]+.5;
|
||||
gain[2] = 0.015625*gain_cdbk[gain_index*3+2]+.5;
|
||||
|
||||
if (count_lost && pitch > subframe_offset)
|
||||
{
|
||||
float gain_sum;
|
||||
|
||||
if (1) {
|
||||
float tmp = count_lost < 4 ? last_pitch_gain : 0.4 * last_pitch_gain;
|
||||
if (tmp>.95)
|
||||
tmp=.95;
|
||||
gain_sum = fabs(gain[1]);
|
||||
if (gain[0]>0)
|
||||
gain_sum += gain[0];
|
||||
else
|
||||
gain_sum -= .5*gain[0];
|
||||
if (gain[2]>0)
|
||||
gain_sum += gain[2];
|
||||
else
|
||||
gain_sum -= .5*gain[2];
|
||||
if (gain_sum > tmp) {
|
||||
float fact = tmp/gain_sum;
|
||||
for (i=0;i<3;i++)
|
||||
gain[i]*=fact;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if (0) {
|
||||
gain_sum = fabs(gain[0])+fabs(gain[1])+fabs(gain[2]);
|
||||
if (gain_sum>.95) {
|
||||
float fact = .95/gain_sum;
|
||||
for (i=0;i<3;i++)
|
||||
gain[i]*=fact;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
*pitch_val = pitch;
|
||||
/**gain_val = gain[0]+gain[1]+gain[2];*/
|
||||
gain_val[0]=gain[0];
|
||||
gain_val[1]=gain[1];
|
||||
gain_val[2]=gain[2];
|
||||
|
||||
{
|
||||
float *e[3];
|
||||
float *tmp2;
|
||||
tmp2=PUSH(stack, 3*nsf, float);
|
||||
e[0]=tmp2;
|
||||
e[1]=tmp2+nsf;
|
||||
e[2]=tmp2+2*nsf;
|
||||
|
||||
for (i=0;i<3;i++)
|
||||
{
|
||||
int j;
|
||||
int pp=pitch+1-i;
|
||||
#if 0
|
||||
for (j=0;j<nsf;j++)
|
||||
{
|
||||
if (j-pp<0)
|
||||
e[i][j]=exc[j-pp];
|
||||
else if (j-pp-pitch<0)
|
||||
e[i][j]=exc[j-pp-pitch];
|
||||
else
|
||||
e[i][j]=0;
|
||||
}
|
||||
#else
|
||||
{
|
||||
int tmp1, tmp3;
|
||||
tmp1=nsf;
|
||||
if (tmp1>pp)
|
||||
tmp1=pp;
|
||||
for (j=0;j<tmp1;j++)
|
||||
e[i][j]=exc[j-pp];
|
||||
tmp3=nsf;
|
||||
if (tmp3>pp+pitch)
|
||||
tmp3=pp+pitch;
|
||||
for (j=tmp1;j<tmp3;j++)
|
||||
e[i][j]=exc[j-pp-pitch];
|
||||
for (j=tmp3;j<nsf;j++)
|
||||
e[i][j]=0;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
for (i=0;i<nsf;i++)
|
||||
exc[i]=gain[0]*e[2][i]+gain[1]*e[1][i]+gain[2]*e[0][i];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/** Forced pitch delay and gain */
|
||||
int forced_pitch_quant(
|
||||
float target[], /* Target vector */
|
||||
float *sw,
|
||||
float ak[], /* LPCs for this subframe */
|
||||
float awk1[], /* Weighted LPCs #1 for this subframe */
|
||||
float awk2[], /* Weighted LPCs #2 for this subframe */
|
||||
float exc[], /* Excitation */
|
||||
void *par,
|
||||
int start, /* Smallest pitch value allowed */
|
||||
int end, /* Largest pitch value allowed */
|
||||
float pitch_coef, /* Voicing (pitch) coefficient */
|
||||
int p, /* Number of LPC coeffs */
|
||||
int nsf, /* Number of samples in subframe */
|
||||
SpeexBits *bits,
|
||||
char *stack,
|
||||
float *exc2,
|
||||
float *r,
|
||||
int complexity
|
||||
)
|
||||
{
|
||||
int i;
|
||||
if (pitch_coef>.99)
|
||||
pitch_coef=.99;
|
||||
for (i=0;i<nsf;i++)
|
||||
{
|
||||
exc[i]=exc[i-start]*pitch_coef;
|
||||
}
|
||||
return start;
|
||||
}
|
||||
|
||||
/** Unquantize forced pitch delay and gain */
|
||||
void forced_pitch_unquant(
|
||||
float exc[], /* Excitation */
|
||||
int start, /* Smallest pitch value allowed */
|
||||
int end, /* Largest pitch value allowed */
|
||||
float pitch_coef, /* Voicing (pitch) coefficient */
|
||||
void *par,
|
||||
int nsf, /* Number of samples in subframe */
|
||||
int *pitch_val,
|
||||
float *gain_val,
|
||||
SpeexBits *bits,
|
||||
char *stack,
|
||||
int count_lost,
|
||||
int subframe_offset,
|
||||
float last_pitch_gain)
|
||||
{
|
||||
int i;
|
||||
/*pitch_coef=.9;*/
|
||||
if (pitch_coef>.99)
|
||||
pitch_coef=.99;
|
||||
for (i=0;i<nsf;i++)
|
||||
{
|
||||
exc[i]=exc[i-start]*pitch_coef;
|
||||
}
|
||||
*pitch_val = start;
|
||||
gain_val[0]=gain_val[2]=0;
|
||||
gain_val[1] = pitch_coef;
|
||||
}
|
@ -1,138 +0,0 @@
|
||||
/* Copyright (C) 2002 Jean-Marc Valin
|
||||
File: ltp.h
|
||||
Long-Term Prediction functions
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions
|
||||
are met:
|
||||
|
||||
- Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
|
||||
- Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
|
||||
- Neither the name of the Xiph.org Foundation nor the names of its
|
||||
contributors may be used to endorse or promote products derived from
|
||||
this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR
|
||||
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include "speex_bits.h"
|
||||
|
||||
|
||||
typedef struct ltp_params {
|
||||
signed char *gain_cdbk;
|
||||
int gain_bits;
|
||||
int pitch_bits;
|
||||
} ltp_params;
|
||||
|
||||
|
||||
void open_loop_nbest_pitch(float *sw, int start, int end, int len, int *pitch, float *gain, int N, char *stack);
|
||||
|
||||
|
||||
/** Finds the best quantized 3-tap pitch predictor by analysis by synthesis */
|
||||
int pitch_search_3tap(
|
||||
float target[], /* Target vector */
|
||||
float *sw,
|
||||
float ak[], /* LPCs for this subframe */
|
||||
float awk1[], /* Weighted LPCs #1 for this subframe */
|
||||
float awk2[], /* Weighted LPCs #2 for this subframe */
|
||||
float exc[], /* Overlapping codebook */
|
||||
void *par,
|
||||
int start, /* Smallest pitch value allowed */
|
||||
int end, /* Largest pitch value allowed */
|
||||
float pitch_coef, /* Voicing (pitch) coefficient */
|
||||
int p, /* Number of LPC coeffs */
|
||||
int nsf, /* Number of samples in subframe */
|
||||
SpeexBits *bits,
|
||||
char *stack,
|
||||
float *exc2,
|
||||
float *r,
|
||||
int complexity
|
||||
);
|
||||
|
||||
/*Unquantize adaptive codebook and update pitch contribution*/
|
||||
void pitch_unquant_3tap(
|
||||
float exc[], /* Excitation */
|
||||
int start, /* Smallest pitch value allowed */
|
||||
int end, /* Largest pitch value allowed */
|
||||
float pitch_coef, /* Voicing (pitch) coefficient */
|
||||
void *par,
|
||||
int nsf, /* Number of samples in subframe */
|
||||
int *pitch_val,
|
||||
float *gain_val,
|
||||
SpeexBits *bits,
|
||||
char *stack,
|
||||
int lost,
|
||||
int subframe_offset,
|
||||
float last_pitch_gain
|
||||
);
|
||||
|
||||
float pitch_gain_search_3tap(
|
||||
float target[], /* Target vector */
|
||||
float ak[], /* LPCs for this subframe */
|
||||
float awk1[], /* Weighted LPCs #1 for this subframe */
|
||||
float awk2[], /* Weighted LPCs #2 for this subframe */
|
||||
float exc[], /* Excitation */
|
||||
void *par,
|
||||
int pitch, /* Pitch value */
|
||||
int p, /* Number of LPC coeffs */
|
||||
int nsf, /* Number of samples in subframe */
|
||||
SpeexBits *bits,
|
||||
char *stack,
|
||||
float *exc2,
|
||||
float *r,
|
||||
int *cdbk_index
|
||||
);
|
||||
|
||||
|
||||
/** Forced pitch delay and gain */
|
||||
int forced_pitch_quant(
|
||||
float target[], /* Target vector */
|
||||
float *sw,
|
||||
float ak[], /* LPCs for this subframe */
|
||||
float awk1[], /* Weighted LPCs #1 for this subframe */
|
||||
float awk2[], /* Weighted LPCs #2 for this subframe */
|
||||
float exc[], /* Excitation */
|
||||
void *par,
|
||||
int start, /* Smallest pitch value allowed */
|
||||
int end, /* Largest pitch value allowed */
|
||||
float pitch_coef, /* Voicing (pitch) coefficient */
|
||||
int p, /* Number of LPC coeffs */
|
||||
int nsf, /* Number of samples in subframe */
|
||||
SpeexBits *bits,
|
||||
char *stack,
|
||||
float *exc2,
|
||||
float *r,
|
||||
int complexity
|
||||
);
|
||||
|
||||
/** Unquantize forced pitch delay and gain */
|
||||
void forced_pitch_unquant(
|
||||
float exc[], /* Excitation */
|
||||
int start, /* Smallest pitch value allowed */
|
||||
int end, /* Largest pitch value allowed */
|
||||
float pitch_coef, /* Voicing (pitch) coefficient */
|
||||
void *par,
|
||||
int nsf, /* Number of samples in subframe */
|
||||
int *pitch_val,
|
||||
float *gain_val,
|
||||
SpeexBits *bits,
|
||||
char *stack,
|
||||
int lost,
|
||||
int subframe_offset,
|
||||
float last_pitch_gain
|
||||
);
|
@ -1,95 +0,0 @@
|
||||
/* Copyright (C) 2002 Jean-Marc Valin
|
||||
File: ltp.c
|
||||
Lont-Term Prediction functions
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions
|
||||
are met:
|
||||
|
||||
- Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
|
||||
- Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
|
||||
- Neither the name of the Xiph.org Foundation nor the names of its
|
||||
contributors may be used to endorse or promote products derived from
|
||||
this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR
|
||||
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
|
||||
static float inner_prod(float *a, float *b, int len)
|
||||
{
|
||||
float sum;
|
||||
__asm__ __volatile__ (
|
||||
"\tpush %%eax\n"
|
||||
"\tpush %%edi\n"
|
||||
"\tpush %%ecx\n"
|
||||
"\txorps %%xmm3, %%xmm3\n"
|
||||
"\txorps %%xmm4, %%xmm4\n"
|
||||
|
||||
"\tsub $20, %%ecx\n"
|
||||
|
||||
".mul20_loop%=:\n"
|
||||
|
||||
"\tmovups (%%eax), %%xmm0\n"
|
||||
"\tmovups (%%edi), %%xmm1\n"
|
||||
"\tmulps %%xmm0, %%xmm1\n"
|
||||
|
||||
"\tmovups 16(%%eax), %%xmm5\n"
|
||||
"\tmovups 16(%%edi), %%xmm6\n"
|
||||
"\tmulps %%xmm5, %%xmm6\n"
|
||||
"\taddps %%xmm1, %%xmm3\n"
|
||||
|
||||
"\tmovups 32(%%eax), %%xmm0\n"
|
||||
"\tmovups 32(%%edi), %%xmm1\n"
|
||||
"\tmulps %%xmm0, %%xmm1\n"
|
||||
"\taddps %%xmm6, %%xmm4\n"
|
||||
|
||||
"\tmovups 48(%%eax), %%xmm5\n"
|
||||
"\tmovups 48(%%edi), %%xmm6\n"
|
||||
"\tmulps %%xmm5, %%xmm6\n"
|
||||
"\taddps %%xmm1, %%xmm3\n"
|
||||
|
||||
"\tmovups 64(%%eax), %%xmm0\n"
|
||||
"\tmovups 64(%%edi), %%xmm1\n"
|
||||
"\tmulps %%xmm0, %%xmm1\n"
|
||||
"\taddps %%xmm6, %%xmm4\n"
|
||||
"\taddps %%xmm1, %%xmm3\n"
|
||||
|
||||
|
||||
"\tadd $80, %%eax\n"
|
||||
"\tadd $80, %%edi\n"
|
||||
|
||||
"\tsub $20, %%ecx\n"
|
||||
|
||||
"\tjae .mul20_loop%=\n"
|
||||
|
||||
"\taddps %%xmm4, %%xmm3\n"
|
||||
|
||||
"\tmovhlps %%xmm3, %%xmm4\n"
|
||||
"\taddps %%xmm4, %%xmm3\n"
|
||||
"\tmovaps %%xmm3, %%xmm4\n"
|
||||
"\tshufps $0x55, %%xmm4, %%xmm4\n"
|
||||
"\taddss %%xmm4, %%xmm3\n"
|
||||
"\tmovss %%xmm3, (%%edx)\n"
|
||||
|
||||
"\tpop %%ecx\n"
|
||||
"\tpop %%edi\n"
|
||||
"\tpop %%eax\n"
|
||||
: : "a" (a), "D" (b), "c" (len), "d" (&sum) : "memory");
|
||||
return sum;
|
||||
}
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user