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:
Stephan Aßmus 2010-09-14 12:32:04 +00:00
parent 594039f10d
commit 5021eb2421
244 changed files with 51 additions and 70442 deletions

View File

@ -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

View File

@ -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

View File

@ -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];

View File

@ -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"},

View File

@ -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",

View File

@ -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 ;

View File

@ -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

View File

@ -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) ;

View File

@ -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 ;

View File

@ -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

View File

@ -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;
}

View File

@ -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

View File

@ -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;
}

View File

@ -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

View File

@ -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

View File

@ -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;
}

View File

@ -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

View File

@ -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;
}

View File

@ -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

View File

@ -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;
}

View File

@ -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

View File

@ -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

View File

@ -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;
}

View File

@ -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

View File

@ -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

View File

@ -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;
}

View File

@ -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

View File

@ -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;
}

View File

@ -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

View File

@ -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;
}

View File

@ -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

View File

@ -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

View File

@ -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;
}

View File

@ -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

View File

@ -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;
}

View File

@ -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

View File

@ -1,4 +0,0 @@
Monty <monty@xiph.org>
and the rest of the Xiph.Org Foundation.

View File

@ -1,2 +0,0 @@
- Sat Sep 02 2000 Jack Moffitt <jack@icecast.org>
+ separated from vorbis

View File

@ -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.

View File

@ -1,8 +0,0 @@
SubDir HAIKU_TOP src add-ons media plugins ogg libogg ;
SubDirSysHdrs $(SUBDIR) ;
StaticLibrary libogg.a :
bitwise.c
framing.c
;

View File

@ -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

View File

@ -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

View File

@ -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 */

View File

@ -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 */

View File

@ -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.

View File

@ -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.

View File

@ -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

View File

@ -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
;

View File

@ -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 */

View File

@ -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

View File

@ -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__ */

View File

@ -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__ */

View File

@ -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__ */

View File

@ -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 */

View File

@ -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__ */

View File

@ -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__ */

View File

@ -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

View File

@ -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;
}

View File

@ -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__ */

View File

@ -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

View File

@ -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);
}

View File

@ -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;
}

View File

@ -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__ */

View File

@ -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

View File

@ -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 ;

View File

@ -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

View File

@ -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.

View File

@ -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.

View File

@ -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
;

View File

@ -1 +0,0 @@
2002/02/13: Creation of the "Speex" project

View File

@ -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

View File

@ -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

View File

@ -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);
}

View File

@ -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);
}

View File

@ -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

View File

@ -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};

View File

@ -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};

View File

@ -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};

View File

@ -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};

View File

@ -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};

View File

@ -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};

View File

@ -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;
}
}

View File

@ -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

View File

@ -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];
}

View File

@ -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};

View File

@ -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};

View File

@ -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,
};

View File

@ -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,
};

View File

@ -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};

View File

@ -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;
}
}

View File

@ -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

View File

@ -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);
}
}

View File

@ -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__ */

View File

@ -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};

View File

@ -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;
}

View File

@ -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
);

View File

@ -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