Compare commits
3
Commits
405483a00d
...
master
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
f0a880c64d | ||
|
|
03c58c4572 | ||
|
|
c8d9bad845 |
@@ -434,6 +434,13 @@ Codec::Info OpusCodec::info()
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int OpusCodec::packetTime(std::span<const uint8_t> payload)
|
||||||
|
{
|
||||||
|
int samples = payload.empty() ? 0
|
||||||
|
: opus_packet_get_nb_samples(payload.data(), (opus_int32)payload.size(), mSamplerate);
|
||||||
|
return samples > 0 ? samples * 1000 / mSamplerate : frameTime();
|
||||||
|
}
|
||||||
|
|
||||||
Codec::EncodeResult OpusCodec::encode(std::span<const uint8_t> input, std::span<uint8_t> output)
|
Codec::EncodeResult OpusCodec::encode(std::span<const uint8_t> input, std::span<uint8_t> output)
|
||||||
{
|
{
|
||||||
// opus_encode() takes the frame size in samples per channel and the output
|
// opus_encode() takes the frame size in samples per channel and the output
|
||||||
@@ -1132,13 +1139,15 @@ G722Codec::~G722Codec()
|
|||||||
|
|
||||||
Codec::Info G722Codec::info()
|
Codec::Info G722Codec::info()
|
||||||
{
|
{
|
||||||
// ToDo: double check the G722 calls - remember RFC has bug about samplerate
|
// G.722 decodes to 16 kHz (640 bytes of PCM per 20 ms frame), but RFC 3551 keeps its RTP
|
||||||
|
// clock at 8 kHz for historical reasons: the timestamp unit is 1/8000, not 1/samplerate.
|
||||||
return {.mName = G722_MIME_NAME,
|
return {.mName = G722_MIME_NAME,
|
||||||
.mSamplerate = 8000,
|
.mSamplerate = 16000,
|
||||||
.mChannels = 1,
|
.mChannels = 1,
|
||||||
.mPcmLength = 640,
|
.mPcmLength = 640,
|
||||||
.mFrameTime = 20,
|
.mFrameTime = 20,
|
||||||
.mRtpLength = 160};
|
.mRtpLength = 160,
|
||||||
|
.mTimestampUnit = 1.0f / 8000};
|
||||||
}
|
}
|
||||||
|
|
||||||
Codec::EncodeResult G722Codec::encode(std::span<const uint8_t> input, std::span<uint8_t> output)
|
Codec::EncodeResult G722Codec::encode(std::span<const uint8_t> input, std::span<uint8_t> output)
|
||||||
@@ -1186,7 +1195,8 @@ const char* G722Codec::G722Factory::name()
|
|||||||
|
|
||||||
int G722Codec::G722Factory::samplerate()
|
int G722Codec::G722Factory::samplerate()
|
||||||
{
|
{
|
||||||
// Although G722 uses 16000 as rate for timestamping RTP frames - in fact it is 8KHz codec. So return 8KHz here.
|
// The rate SDP advertises (rtpmap G722/8000) is the RTP clock, 8 kHz by RFC 3551, although the
|
||||||
|
// audio is 16 kHz; see G722Codec::info().
|
||||||
return 8000;
|
return 8000;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -69,6 +69,8 @@ protected:
|
|||||||
int mDecoderChannels = 0;
|
int mDecoderChannels = 0;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
int packetTime(std::span<const uint8_t> payload) override;
|
||||||
|
|
||||||
struct Params
|
struct Params
|
||||||
{
|
{
|
||||||
bool mUseDtx = false, mUseInbandFec = false, mStereo = false;
|
bool mUseDtx = false, mUseInbandFec = false, mStereo = false;
|
||||||
|
|||||||
@@ -520,13 +520,11 @@ Codec* AudioReceiver::add(const std::shared_ptr<jrtplib::RTPPacket>& p)
|
|||||||
|
|
||||||
if (!codec)
|
if (!codec)
|
||||||
time_length = 10;
|
time_length = 10;
|
||||||
else if (!codec->rtpLength())
|
|
||||||
time_length = codec->frameTime();
|
|
||||||
else
|
else
|
||||||
time_length = lround(double(payloadLength) / codec->rtpLength() * codec->frameTime());
|
time_length = codec->packetTime(std::span{p->GetPayloadData(), (size_t)payloadLength});
|
||||||
|
|
||||||
if (codec)
|
if (codec)
|
||||||
samplerate = codec->samplerate();
|
samplerate = codec->rtpClockRate(); // RTP timestamp units, not PCM rate (G.722)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Process jitter anyway - can we decode payload or not
|
// Process jitter anyway - can we decode payload or not
|
||||||
@@ -724,7 +722,7 @@ AudioReceiver::DecodeResult AudioReceiver::decodePacketTo(Audio::DataWindow& out
|
|||||||
if (mLastPacketTimestamp && mLastPacketTimeLength && mCodec)
|
if (mLastPacketTimestamp && mLastPacketTimeLength && mCodec)
|
||||||
{
|
{
|
||||||
int units = rtp.GetTimestamp() - *mLastPacketTimestamp;
|
int units = rtp.GetTimestamp() - *mLastPacketTimestamp;
|
||||||
int milliseconds = units / (mCodec->samplerate() / 1000);
|
int milliseconds = units / (mCodec->rtpClockRate() / 1000);
|
||||||
if (milliseconds > mLastPacketTimeLength)
|
if (milliseconds > mLastPacketTimeLength)
|
||||||
{
|
{
|
||||||
auto silenceLength = std::chrono::milliseconds(milliseconds - mLastPacketTimeLength);
|
auto silenceLength = std::chrono::milliseconds(milliseconds - mLastPacketTimeLength);
|
||||||
@@ -794,8 +792,11 @@ AudioReceiver::DecodeResult AudioReceiver::decodePacketTo(Audio::DataWindow& out
|
|||||||
mFrameCount = mCodec->rtpLength() ? rtp.GetPayloadLength() / mCodec->rtpLength() : 1;
|
mFrameCount = mCodec->rtpLength() ? rtp.GetPayloadLength() / mCodec->rtpLength() : 1;
|
||||||
int frameLength = mCodec->rtpLength() ? mCodec->rtpLength() : (int)rtp.GetPayloadLength();
|
int frameLength = mCodec->rtpLength() ? mCodec->rtpLength() : (int)rtp.GetPayloadLength();
|
||||||
|
|
||||||
// Save last packet time length
|
// Save last packet time length. Taken from the payload, not mFrameCount *
|
||||||
mLastPacketTimeLength = mFrameCount * mCodec->frameTime();
|
// frameTime(): an Opus packet of 40 or 60 ms is one "frame" here, and counting
|
||||||
|
// it as frameTime() (20 ms) made the gap check above emit silence before every
|
||||||
|
// packet and pushed the jitter buffer into discarding about half of them.
|
||||||
|
mLastPacketTimeLength = mCodec->packetTime(std::span{rtp.GetPayloadData(), payload_length});
|
||||||
|
|
||||||
// Decode
|
// Decode
|
||||||
for (int i = 0; i < mFrameCount && !mCodecSettings.mSkipDecode; i++)
|
for (int i = 0; i < mFrameCount && !mCodecSettings.mSkipDecode; i++)
|
||||||
@@ -1157,12 +1158,17 @@ AudioReceiver::MediaInfo AudioReceiver::infoFor(jrtplib::RTPPacket& p)
|
|||||||
|
|
||||||
if (codec->rtpLength() != 0)
|
if (codec->rtpLength() != 0)
|
||||||
{
|
{
|
||||||
int frameCount = static_cast<int>(p.GetPayloadLength() / codec->rtpLength());
|
// A G.729 (PT 18) SID frame is shorter than a voice frame but stands for one; other
|
||||||
if (p.GetPayloadType() == 9 /*G729A silence*/ && p.GetPayloadLength() % codec->rtpLength())
|
// codecs scale with the payload (G.722 at 10 ms ptime carries half a 160-byte frame).
|
||||||
frameCount++;
|
if (p.GetPayloadType() == 18 && p.GetPayloadLength() % codec->rtpLength())
|
||||||
|
{
|
||||||
|
int frameCount = static_cast<int>(p.GetPayloadLength() / codec->rtpLength()) + 1;
|
||||||
packetTime = std::chrono::milliseconds(frameCount * codec->frameTime());
|
packetTime = std::chrono::milliseconds(frameCount * codec->frameTime());
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
packetTime = std::chrono::milliseconds(
|
||||||
|
lround(double(p.GetPayloadLength()) / codec->rtpLength() * codec->frameTime()));
|
||||||
|
}
|
||||||
else if (typeid(*codec) == typeid(OpusCodec))
|
else if (typeid(*codec) == typeid(OpusCodec))
|
||||||
{
|
{
|
||||||
OpusCodec* oc = dynamic_cast<OpusCodec*>(codec);
|
OpusCodec* oc = dynamic_cast<OpusCodec*>(codec);
|
||||||
|
|||||||
@@ -114,7 +114,7 @@ void AudioStream::setTransmittingCodec(Codec::Factory& factory, int payloadType)
|
|||||||
mTransmittingCodec = factory.create();
|
mTransmittingCodec = factory.create();
|
||||||
mTransmittingPayloadType = payloadType;
|
mTransmittingPayloadType = payloadType;
|
||||||
if (mRtpSession.IsActive())
|
if (mRtpSession.IsActive())
|
||||||
mRtpSession.SetTimestampUnit(1.0 / mTransmittingCodec->samplerate());
|
mRtpSession.SetTimestampUnit(mTransmittingCodec->timestampUnit());
|
||||||
}
|
}
|
||||||
|
|
||||||
PCodec AudioStream::transmittingCodec()
|
PCodec AudioStream::transmittingCodec()
|
||||||
@@ -241,7 +241,7 @@ void AudioStream::addData(const void* buffer, int bytes)
|
|||||||
ICELogMedia(<< "Sending RTP packet pt = " << mTransmittingPayloadType
|
ICELogMedia(<< "Sending RTP packet pt = " << mTransmittingPayloadType
|
||||||
<< ", plength = " << (int)mEncodedAudio.size() << " to ");
|
<< ", plength = " << (int)mEncodedAudio.size() << " to ");
|
||||||
mRtpSession.SendPacketEx(mEncodedAudio.data(), mEncodedAudio.size(), mTransmittingPayloadType, false,
|
mRtpSession.SendPacketEx(mEncodedAudio.data(), mEncodedAudio.size(), mTransmittingPayloadType, false,
|
||||||
packetTime * codec->samplerate() / 1000, 0, nullptr, 0);
|
packetTime * codec->rtpClockRate() / 1000, 0, nullptr, 0);
|
||||||
mEncodedAudio.clear();
|
mEncodedAudio.clear();
|
||||||
encodedTime = 0;
|
encodedTime = 0;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,6 +6,7 @@
|
|||||||
#ifndef __MT_CODEC_H
|
#ifndef __MT_CODEC_H
|
||||||
#define __MT_CODEC_H
|
#define __MT_CODEC_H
|
||||||
|
|
||||||
|
#include <cmath>
|
||||||
#include <map>
|
#include <map>
|
||||||
#include <span>
|
#include <span>
|
||||||
|
|
||||||
@@ -66,9 +67,24 @@ public:
|
|||||||
int frameTime() { return info().mFrameTime; }
|
int frameTime() { return info().mFrameTime; }
|
||||||
std::string name() { return info().mName; }
|
std::string name() { return info().mName; }
|
||||||
float timestampUnit() { return info().mTimestampUnit == 0.0f ? 1.0f / info().mSamplerate : info().mTimestampUnit; }
|
float timestampUnit() { return info().mTimestampUnit == 0.0f ? 1.0f / info().mSamplerate : info().mTimestampUnit; }
|
||||||
|
// RTP clock rate in Hz, the unit of RTP timestamps. Equals samplerate() except for codecs
|
||||||
|
// whose RTP clock differs from the decoded audio: G.722 decodes to 16 kHz but its RTP clock
|
||||||
|
// is 8 kHz (RFC 3551). Use it for timestamp arithmetic and jitter, samplerate() for PCM.
|
||||||
|
int rtpClockRate() { return static_cast<int>(1.0f / timestampUnit() + 0.5f); }
|
||||||
|
|
||||||
Audio::Format getAudioFormat() { return Audio::Format(this->info().mSamplerate, this->info().mChannels); }
|
Audio::Format getAudioFormat() { return Audio::Format(this->info().mSamplerate, this->info().mChannels); }
|
||||||
|
|
||||||
|
// Audio duration of one RTP payload, in milliseconds. The default suits fixed-size
|
||||||
|
// frames (rtpLength() bytes per frameTime()); a codec whose packets carry a variable
|
||||||
|
// amount of audio (Opus: 2.5-120 ms, whatever the sender's ptime) reads it from the
|
||||||
|
// payload instead, as frameTime() is only the local ptime.
|
||||||
|
virtual int packetTime(std::span<const uint8_t> payload)
|
||||||
|
{
|
||||||
|
if (!rtpLength())
|
||||||
|
return frameTime();
|
||||||
|
return static_cast<int>(std::lround(double(payload.size()) / rtpLength() * frameTime()));
|
||||||
|
}
|
||||||
|
|
||||||
// Returns size of encoded data (RTP) in bytes
|
// Returns size of encoded data (RTP) in bytes
|
||||||
struct EncodeResult
|
struct EncodeResult
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -1,16 +1,13 @@
|
|||||||
project (g722_codec)
|
project (g722_codec)
|
||||||
|
|
||||||
# Rely on C++ 11
|
|
||||||
set (CMAKE_CXX_STANDARD 20)
|
|
||||||
set (CMAKE_CXX_STANDARD_REQUIRED ON)
|
|
||||||
|
|
||||||
set(CMAKE_POSITION_INDEPENDENT_CODE ON)
|
set(CMAKE_POSITION_INDEPENDENT_CODE ON)
|
||||||
|
|
||||||
|
# G.722 from Asterisk (codecs/g722): Steve Underwood's spandsp code, which he
|
||||||
|
# placed in the public domain, on top of the CMU 1993 codec, whose use "for
|
||||||
|
# any research or commercial purpose, is completely unrestricted". See README.md.
|
||||||
set (G722_SOURCES
|
set (G722_SOURCES
|
||||||
g722_bitstream.c
|
|
||||||
g722_decode.c
|
g722_decode.c
|
||||||
g722_encode.c
|
g722_encode.c
|
||||||
)
|
)
|
||||||
|
|
||||||
add_library(g722_codec ${G722_SOURCES})
|
add_library(g722_codec ${G722_SOURCES})
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,35 @@
|
|||||||
|
# G.722 codec
|
||||||
|
|
||||||
|
Source: Asterisk, `codecs/g722/` (`g722.h`, `g722_encode.c`, `g722_decode.c`),
|
||||||
|
https://github.com/asterisk/asterisk, taken 2026-09-21.
|
||||||
|
|
||||||
|
## Licence
|
||||||
|
|
||||||
|
No copyleft. The code has two layers:
|
||||||
|
|
||||||
|
- **Steve Underwood, 2005** (spandsp): "Despite my general liking of the GPL, I
|
||||||
|
place my own contributions to this code in the public domain for the benefit
|
||||||
|
of all mankind - even the slimy ones who might try to proprietize my work and
|
||||||
|
use it to my detriment." (in each file's header)
|
||||||
|
- **Carnegie Mellon University, 1993** (Chengxiang Lu and Alex Hauptmann, Speech
|
||||||
|
Group): "The Carnegie Mellon ADPCM program is Copyright (c) 1993 by Carnegie
|
||||||
|
Mellon University. Use of this program, for any research or commercial
|
||||||
|
purpose, is completely unrestricted. If you make use of or redistribute this
|
||||||
|
material, we would appreciate acknowlegement of its origin." (the terms as
|
||||||
|
reproduced in sippy's libg722, https://github.com/sippy/libg722, LICENSE)
|
||||||
|
|
||||||
|
This replaces an older copy of the same spandsp code that was offered only
|
||||||
|
under GPL-2 or LGPL-2.1.
|
||||||
|
|
||||||
|
## Behaviour
|
||||||
|
|
||||||
|
Asterisk's version maps 16-bit PCM to the codec's range: the encoder halves its
|
||||||
|
input and the decoder doubles its output. Streams from Asterisk and ffmpeg
|
||||||
|
therefore decode at their original level. The older copy did neither, so it
|
||||||
|
decoded those streams 6 dB too quiet and clipped encoder input above -6 dBFS.
|
||||||
|
|
||||||
|
Local changes:
|
||||||
|
- the decoder saturates its output (`saturate()`) instead of casting. Asterisk's
|
||||||
|
cast wraps loud samples around int16: 259 samples in 11 s of speech peaking
|
||||||
|
at -0.2 dBFS came out as large values of the opposite sign;
|
||||||
|
- `g722.h` includes `<stdint.h>` and maps `__inline__` to `__inline` for MSVC.
|
||||||
+22
-53
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* VoIPcodecs - a series of DSP components for telephony
|
* SpanDSP - a series of DSP components for telephony
|
||||||
*
|
*
|
||||||
* g722.h - The ITU G.722 codec.
|
* g722.h - The ITU G.722 codec.
|
||||||
*
|
*
|
||||||
@@ -7,21 +7,10 @@
|
|||||||
*
|
*
|
||||||
* Copyright (C) 2005 Steve Underwood
|
* Copyright (C) 2005 Steve Underwood
|
||||||
*
|
*
|
||||||
* All rights reserved.
|
* Despite my general liking of the GPL, I place my own contributions
|
||||||
*
|
* to this code in the public domain for the benefit of all mankind -
|
||||||
* This program is free software; you can redistribute it and/or modify
|
* even the slimy ones who might try to proprietize my work and use it
|
||||||
* it under the terms of the GNU General Public License version 2, or
|
* to my detriment.
|
||||||
* the Lesser GNU General Public License version 2.1, as published by
|
|
||||||
* the Free Software Foundation.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
* GNU General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License
|
|
||||||
* along with this program; if not, write to the Free Software
|
|
||||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
|
||||||
*
|
*
|
||||||
* Based on a single channel G.722 codec which is:
|
* Based on a single channel G.722 codec which is:
|
||||||
*
|
*
|
||||||
@@ -29,17 +18,19 @@
|
|||||||
* Computer Science, Speech Group
|
* Computer Science, Speech Group
|
||||||
* Chengxiang Lu and Alex Hauptmann
|
* Chengxiang Lu and Alex Hauptmann
|
||||||
*
|
*
|
||||||
* $Id: g722.h,v 1.17 2008/02/09 15:32:26 steveu Exp $
|
* $Id$
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
/*! \file */
|
/*! \file */
|
||||||
|
|
||||||
#if !defined(_SPANDSP_G722_H_)
|
#if !defined(_G722_H_)
|
||||||
#define _SPANDSP_G722_H_
|
#define _G722_H_
|
||||||
|
|
||||||
#include "inttypes.h"
|
|
||||||
|
|
||||||
|
#include <stdint.h> /* rtphone: the header uses int16_t/uint8_t itself */
|
||||||
|
#if defined(_MSC_VER) && !defined(__inline__)
|
||||||
|
#define __inline__ __inline /* rtphone: MSVC has no __inline__ (the .c files use it) */
|
||||||
|
#endif
|
||||||
|
|
||||||
/*! \page g722_page G.722 encoding and decoding
|
/*! \page g722_page G.722 encoding and decoding
|
||||||
\section g722_page_sec_1 What does it do?
|
\section g722_page_sec_1 What does it do?
|
||||||
@@ -60,6 +51,13 @@ enum
|
|||||||
G722_PACKED = 0x0002
|
G722_PACKED = 0x0002
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#ifndef INT16_MAX
|
||||||
|
#define INT16_MAX 32767
|
||||||
|
#endif
|
||||||
|
#ifndef INT16_MIN
|
||||||
|
#define INT16_MIN (-32768)
|
||||||
|
#endif
|
||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
/*! TRUE if the operating in the special ITU test mode, with the band split filters
|
/*! TRUE if the operating in the special ITU test mode, with the band split filters
|
||||||
@@ -136,48 +134,19 @@ typedef struct
|
|||||||
int out_bits;
|
int out_bits;
|
||||||
} g722_decode_state_t;
|
} g722_decode_state_t;
|
||||||
|
|
||||||
#if defined(__cplusplus)
|
#ifdef __cplusplus
|
||||||
extern "C"
|
extern "C" {
|
||||||
{
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/*! Initialise an G.722 encode context.
|
|
||||||
\param s The G.722 encode context.
|
|
||||||
\param rate The required bit rate for the G.722 data.
|
|
||||||
The valid rates are 64000, 56000 and 48000.
|
|
||||||
\param options
|
|
||||||
\return A pointer to the G.722 encode context, or NULL for error. */
|
|
||||||
g722_encode_state_t *g722_encode_init(g722_encode_state_t *s, int rate, int options);
|
g722_encode_state_t *g722_encode_init(g722_encode_state_t *s, int rate, int options);
|
||||||
|
|
||||||
int g722_encode_release(g722_encode_state_t *s);
|
int g722_encode_release(g722_encode_state_t *s);
|
||||||
|
|
||||||
/*! Encode a buffer of linear PCM data to G.722
|
|
||||||
\param s The G.722 context.
|
|
||||||
\param g722_data The G.722 data produced.
|
|
||||||
\param amp The audio sample buffer.
|
|
||||||
\param len The number of samples in the buffer.
|
|
||||||
\return The number of bytes of G.722 data produced. */
|
|
||||||
int g722_encode(g722_encode_state_t *s, uint8_t g722_data[], const int16_t amp[], int len);
|
int g722_encode(g722_encode_state_t *s, uint8_t g722_data[], const int16_t amp[], int len);
|
||||||
|
|
||||||
/*! Initialise an G.722 decode context.
|
|
||||||
\param s The G.722 decode context.
|
|
||||||
\param rate The bit rate of the G.722 data.
|
|
||||||
The valid rates are 64000, 56000 and 48000.
|
|
||||||
\param options
|
|
||||||
\return A pointer to the G.722 decode context, or NULL for error. */
|
|
||||||
g722_decode_state_t *g722_decode_init(g722_decode_state_t *s, int rate, int options);
|
g722_decode_state_t *g722_decode_init(g722_decode_state_t *s, int rate, int options);
|
||||||
|
|
||||||
int g722_decode_release(g722_decode_state_t *s);
|
int g722_decode_release(g722_decode_state_t *s);
|
||||||
|
|
||||||
/*! Decode a buffer of G.722 data to linear PCM.
|
|
||||||
\param s The G.722 context.
|
|
||||||
\param amp The audio sample buffer.
|
|
||||||
\param g722_data
|
|
||||||
\param len
|
|
||||||
\return The number of samples returned. */
|
|
||||||
int g722_decode(g722_decode_state_t *s, int16_t amp[], const uint8_t g722_data[], int len);
|
int g722_decode(g722_decode_state_t *s, int16_t amp[], const uint8_t g722_data[], int len);
|
||||||
|
|
||||||
#if defined(__cplusplus)
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|||||||
@@ -1,137 +0,0 @@
|
|||||||
/*
|
|
||||||
* VoIPcodecs - a series of DSP components for telephony
|
|
||||||
*
|
|
||||||
* bitstream.c - Bitstream composition and decomposition routines.
|
|
||||||
*
|
|
||||||
* Written by Steve Underwood <steveu@coppice.org>
|
|
||||||
*
|
|
||||||
* Copyright (C) 2006 Steve Underwood
|
|
||||||
*
|
|
||||||
* All rights reserved.
|
|
||||||
*
|
|
||||||
* This program is free software; you can redistribute it and/or modify
|
|
||||||
* it under the terms of the Lesser Lesser GNU General Public License version 2.1.1, as
|
|
||||||
* published by the Free Software Foundation.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
* GNU General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License
|
|
||||||
* along with this program; if not, write to the Free Software
|
|
||||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
|
||||||
*
|
|
||||||
* $Id: bitstream.c,v 1.8 2007/08/20 15:22:21 steveu Exp $
|
|
||||||
*/
|
|
||||||
|
|
||||||
/*! \file */
|
|
||||||
|
|
||||||
#ifdef HAVE_CONFIG_H
|
|
||||||
#include <config.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include "inttypes.h"
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <string.h>
|
|
||||||
#include <assert.h>
|
|
||||||
|
|
||||||
#include "g722_telephony.h"
|
|
||||||
#include "g722_bitstream.h"
|
|
||||||
|
|
||||||
void bitstream_put(bitstream_state_t *s, uint8_t **c, unsigned int value, int bits)
|
|
||||||
{
|
|
||||||
value &= ((1 << bits) - 1);
|
|
||||||
if (s->residue + bits <= 32)
|
|
||||||
{
|
|
||||||
s->bitstream |= (value << s->residue);
|
|
||||||
s->residue += bits;
|
|
||||||
}
|
|
||||||
while (s->residue >= 8)
|
|
||||||
{
|
|
||||||
s->residue -= 8;
|
|
||||||
*(*c)++ = (uint8_t) (s->bitstream & 0xFF);
|
|
||||||
s->bitstream >>= 8;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
/*- End of function --------------------------------------------------------*/
|
|
||||||
|
|
||||||
void bitstream_put2(bitstream_state_t *s, uint8_t **c, unsigned int value, int bits)
|
|
||||||
{
|
|
||||||
value &= ((1 << bits) - 1);
|
|
||||||
if (s->residue + bits <= 32)
|
|
||||||
{
|
|
||||||
s->bitstream = (s->bitstream << bits) | value;
|
|
||||||
s->residue += bits;
|
|
||||||
}
|
|
||||||
while (s->residue >= 8)
|
|
||||||
{
|
|
||||||
s->residue -= 8;
|
|
||||||
*(*c)++ = (uint8_t) ((s->bitstream >> s->residue) & 0xFF);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
/*- End of function --------------------------------------------------------*/
|
|
||||||
|
|
||||||
unsigned int bitstream_get(bitstream_state_t *s, const uint8_t **c, int bits)
|
|
||||||
{
|
|
||||||
unsigned int x;
|
|
||||||
|
|
||||||
while (s->residue < (unsigned int) bits)
|
|
||||||
{
|
|
||||||
x = (unsigned int) *(*c)++;
|
|
||||||
s->bitstream |= (x << s->residue);
|
|
||||||
s->residue += 8;
|
|
||||||
}
|
|
||||||
s->residue -= bits;
|
|
||||||
x = s->bitstream & ((1 << bits) - 1);
|
|
||||||
s->bitstream >>= bits;
|
|
||||||
return x;
|
|
||||||
}
|
|
||||||
/*- End of function --------------------------------------------------------*/
|
|
||||||
|
|
||||||
unsigned int bitstream_get2(bitstream_state_t *s, const uint8_t **c, int bits)
|
|
||||||
{
|
|
||||||
unsigned int x;
|
|
||||||
|
|
||||||
while (s->residue < (unsigned int) bits)
|
|
||||||
{
|
|
||||||
x = (unsigned int) *(*c)++;
|
|
||||||
s->bitstream = (s->bitstream << 8) | x;
|
|
||||||
s->residue += 8;
|
|
||||||
}
|
|
||||||
s->residue -= bits;
|
|
||||||
x = (s->bitstream >> s->residue) & ((1 << bits) - 1);
|
|
||||||
return x;
|
|
||||||
}
|
|
||||||
/*- End of function --------------------------------------------------------*/
|
|
||||||
|
|
||||||
void bitstream_flush(bitstream_state_t *s, uint8_t **c)
|
|
||||||
{
|
|
||||||
if (s->residue > 0)
|
|
||||||
{
|
|
||||||
*(*c)++ = (uint8_t) ((s->bitstream << (8 - s->residue)) & 0xFF);
|
|
||||||
s->residue = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
/*- End of function --------------------------------------------------------*/
|
|
||||||
|
|
||||||
void bitstream_flush2(bitstream_state_t *s, uint8_t **c)
|
|
||||||
{
|
|
||||||
if (s->residue > 0)
|
|
||||||
{
|
|
||||||
*(*c)++ = (uint8_t) ((s->bitstream << (8 - s->residue)) & 0xFF);
|
|
||||||
s->residue = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
/*- End of function --------------------------------------------------------*/
|
|
||||||
|
|
||||||
bitstream_state_t *bitstream_init(bitstream_state_t *s)
|
|
||||||
{
|
|
||||||
if (s == NULL)
|
|
||||||
return NULL;
|
|
||||||
s->bitstream = 0;
|
|
||||||
s->residue = 0;
|
|
||||||
return s;
|
|
||||||
}
|
|
||||||
/*- End of function --------------------------------------------------------*/
|
|
||||||
/*- End of file ------------------------------------------------------------*/
|
|
||||||
@@ -1,89 +0,0 @@
|
|||||||
/*
|
|
||||||
* VoIPcodecs - a series of DSP components for telephony
|
|
||||||
*
|
|
||||||
* bitstream.h - Bitstream composition and decomposition routines.
|
|
||||||
*
|
|
||||||
* Written by Steve Underwood <steveu@coppice.org>
|
|
||||||
*
|
|
||||||
* Copyright (C) 2006 Steve Underwood
|
|
||||||
*
|
|
||||||
* All rights reserved.
|
|
||||||
*
|
|
||||||
* This program is free software; you can redistribute it and/or modify
|
|
||||||
* it under the terms of the Lesser GNU General Public License version 2.1, as
|
|
||||||
* published by the Free Software Foundation.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
* GNU General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License
|
|
||||||
* along with this program; if not, write to the Free Software
|
|
||||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
|
||||||
*
|
|
||||||
* $Id: bitstream.h,v 1.8 2007/12/13 11:31:32 steveu Exp $
|
|
||||||
*/
|
|
||||||
|
|
||||||
/*! \file */
|
|
||||||
|
|
||||||
#if !defined(_SPANDSP_BITSTREAM_H_)
|
|
||||||
#define _SPANDSP_BITSTREAM_H_
|
|
||||||
|
|
||||||
/*! \page bitstream_page Bitstream composition and decomposition
|
|
||||||
\section bitstream_page_sec_1 What does it do?
|
|
||||||
|
|
||||||
\section bitstream_page_sec_2 How does it work?
|
|
||||||
*/
|
|
||||||
|
|
||||||
/*! Bitstream handler state */
|
|
||||||
typedef struct
|
|
||||||
{
|
|
||||||
/*! The bit stream. */
|
|
||||||
unsigned int bitstream;
|
|
||||||
/*! The residual bits in bitstream. */
|
|
||||||
unsigned int residue;
|
|
||||||
} bitstream_state_t;
|
|
||||||
|
|
||||||
|
|
||||||
#if defined(__cplusplus)
|
|
||||||
extern "C"
|
|
||||||
{
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/*! \brief Put a chunk of bits into the output buffer.
|
|
||||||
\param s A pointer to the bitstream context.
|
|
||||||
\param c A pointer to the bitstream output buffer.
|
|
||||||
\param value The value to be pushed into the output buffer.
|
|
||||||
\param bits The number of bits of value to be pushed. 1 to 25 bit is valid. */
|
|
||||||
void bitstream_put(bitstream_state_t *s, uint8_t **c, unsigned int value, int bits);
|
|
||||||
|
|
||||||
void bitstream_put2(bitstream_state_t *s, uint8_t **c, unsigned int value, int bits);
|
|
||||||
|
|
||||||
/*! \brief Get a chunk of bits from the input buffer.
|
|
||||||
\param s A pointer to the bitstream context.
|
|
||||||
\param c A pointer to the bitstream input buffer.
|
|
||||||
\param bits The number of bits of value to be grabbed. 1 to 25 bit is valid.
|
|
||||||
\return The value retrieved from the input buffer. */
|
|
||||||
unsigned int bitstream_get(bitstream_state_t *s, const uint8_t **c, int bits);
|
|
||||||
|
|
||||||
unsigned int bitstream_get2(bitstream_state_t *s, const uint8_t **c, int bits);
|
|
||||||
|
|
||||||
/*! \brief Flush any residual bit to the output buffer.
|
|
||||||
\param s A pointer to the bitstream context.
|
|
||||||
\param c A pointer to the bitstream output buffer. */
|
|
||||||
void bitstream_flush(bitstream_state_t *s, uint8_t **c);
|
|
||||||
|
|
||||||
void bitstream_flush2(bitstream_state_t *s, uint8_t **c);
|
|
||||||
|
|
||||||
/*! \brief Initialise a bitstream context.
|
|
||||||
\param s A pointer to the bitstream context.
|
|
||||||
\return A pointer to the bitstream context. */
|
|
||||||
bitstream_state_t *bitstream_init(bitstream_state_t *s);
|
|
||||||
|
|
||||||
#if defined(__cplusplus)
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif
|
|
||||||
/*- End of file ------------------------------------------------------------*/
|
|
||||||
@@ -1,157 +0,0 @@
|
|||||||
/*
|
|
||||||
* VoIPcodecs - a series of DSP components for telephony
|
|
||||||
*
|
|
||||||
* dc_restore.h - General telephony routines to restore the zero D.C.
|
|
||||||
* level to audio which has a D.C. bias.
|
|
||||||
*
|
|
||||||
* Written by Steve Underwood <steveu@coppice.org>
|
|
||||||
*
|
|
||||||
* Copyright (C) 2001 Steve Underwood
|
|
||||||
*
|
|
||||||
* All rights reserved.
|
|
||||||
*
|
|
||||||
* This program is free software; you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU General Public License version 2, as
|
|
||||||
* published by the Free Software Foundation.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
* GNU General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License
|
|
||||||
* along with this program; if not, write to the Free Software
|
|
||||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
|
||||||
*
|
|
||||||
* $Id: dc_restore.h,v 1.18 2007/04/08 08:16:17 steveu Exp $
|
|
||||||
*/
|
|
||||||
|
|
||||||
/*! \file */
|
|
||||||
|
|
||||||
#if !defined(_SPANDSP_DC_RESTORE_H_)
|
|
||||||
#define _SPANDSP_DC_RESTORE_H_
|
|
||||||
|
|
||||||
/*! \page dc_restore_page Removing DC bias from a signal
|
|
||||||
|
|
||||||
\section dc_restore_page_sec_1 What does it do?
|
|
||||||
|
|
||||||
Telecoms signals often contain considerable DC, but DC upsets a lot of signal
|
|
||||||
processing functions. Placing a zero DC restorer at the front of the processing
|
|
||||||
chain can often simplify the downstream processing.
|
|
||||||
|
|
||||||
\section dc_restore_page_sec_2 How does it work?
|
|
||||||
|
|
||||||
The DC restorer uses a leaky integrator to provide a long-ish term estimate of
|
|
||||||
the DC bias in the signal. A 32 bit estimate is used for the 16 bit audio, so
|
|
||||||
the noise introduced by the estimation can be keep in the lower bits, and the 16
|
|
||||||
bit DC value, which is subtracted from the signal, is fairly clean. The
|
|
||||||
following code fragment shows the algorithm used. dc_bias is a 32 bit integer,
|
|
||||||
while the sample and the resulting clean_sample are 16 bit integers.
|
|
||||||
|
|
||||||
dc_bias += ((((int32_t) sample << 15) - dc_bias) >> 14);
|
|
||||||
clean_sample = sample - (dc_bias >> 15);
|
|
||||||
*/
|
|
||||||
|
|
||||||
/*!
|
|
||||||
Zero DC restoration descriptor. This defines the working state for a single
|
|
||||||
instance of DC content filter.
|
|
||||||
*/
|
|
||||||
typedef struct
|
|
||||||
{
|
|
||||||
int32_t state;
|
|
||||||
} dc_restore_state_t;
|
|
||||||
|
|
||||||
#if defined(__cplusplus)
|
|
||||||
extern "C"
|
|
||||||
{
|
|
||||||
#endif
|
|
||||||
|
|
||||||
static __inline__ void dc_restore_init(dc_restore_state_t *dc)
|
|
||||||
{
|
|
||||||
dc->state = 0;
|
|
||||||
}
|
|
||||||
/*- End of function --------------------------------------------------------*/
|
|
||||||
|
|
||||||
static __inline__ int16_t dc_restore(dc_restore_state_t *dc, int16_t sample)
|
|
||||||
{
|
|
||||||
dc->state += ((((int32_t) sample << 15) - dc->state) >> 14);
|
|
||||||
return (int16_t) (sample - (dc->state >> 15));
|
|
||||||
}
|
|
||||||
/*- End of function --------------------------------------------------------*/
|
|
||||||
|
|
||||||
static __inline__ int16_t dc_restore_estimate(dc_restore_state_t *dc)
|
|
||||||
{
|
|
||||||
return (int16_t) (dc->state >> 15);
|
|
||||||
}
|
|
||||||
/*- End of function --------------------------------------------------------*/
|
|
||||||
|
|
||||||
static __inline__ int16_t saturate(int32_t amp)
|
|
||||||
{
|
|
||||||
int16_t amp16;
|
|
||||||
|
|
||||||
/* Hopefully this is optimised for the common case - not clipping */
|
|
||||||
amp16 = (int16_t) amp;
|
|
||||||
if (amp == amp16)
|
|
||||||
return amp16;
|
|
||||||
if (amp > INT16_MAX)
|
|
||||||
return INT16_MAX;
|
|
||||||
return INT16_MIN;
|
|
||||||
}
|
|
||||||
/*- End of function --------------------------------------------------------*/
|
|
||||||
|
|
||||||
/*#ifdef _MSC_VER
|
|
||||||
__inline float rintf (float flt)
|
|
||||||
{
|
|
||||||
_asm
|
|
||||||
{ fld flt
|
|
||||||
frndint
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
__inline double rint(double dbl)
|
|
||||||
{
|
|
||||||
__asm
|
|
||||||
{
|
|
||||||
fld dbl
|
|
||||||
frndint
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
__inline long lrintf (float flt)
|
|
||||||
{
|
|
||||||
long retval;
|
|
||||||
_asm
|
|
||||||
{ fld flt
|
|
||||||
fistp retval
|
|
||||||
}
|
|
||||||
return retval;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
*/
|
|
||||||
|
|
||||||
static __inline__ int16_t fsaturatef(float famp)
|
|
||||||
{
|
|
||||||
if (famp > 32767.0)
|
|
||||||
return INT16_MAX;
|
|
||||||
if (famp < -32768.0)
|
|
||||||
return INT16_MIN;
|
|
||||||
return (int16_t) rintf(famp);
|
|
||||||
}
|
|
||||||
/*- End of function --------------------------------------------------------*/
|
|
||||||
|
|
||||||
static __inline__ int16_t fsaturate(double damp)
|
|
||||||
{
|
|
||||||
if (damp > 32767.0)
|
|
||||||
return INT16_MAX;
|
|
||||||
if (damp < -32768.0)
|
|
||||||
return INT16_MIN;
|
|
||||||
return (int16_t) rint(damp);
|
|
||||||
}
|
|
||||||
/*- End of function --------------------------------------------------------*/
|
|
||||||
|
|
||||||
#if defined(__cplusplus)
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif
|
|
||||||
/*- End of file ------------------------------------------------------------*/
|
|
||||||
+46
-47
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* VoIPcodecs - a series of DSP components for telephony
|
* SpanDSP - a series of DSP components for telephony
|
||||||
*
|
*
|
||||||
* g722_decode.c - The ITU G.722 codec, decode part.
|
* g722_decode.c - The ITU G.722 codec, decode part.
|
||||||
*
|
*
|
||||||
@@ -7,21 +7,10 @@
|
|||||||
*
|
*
|
||||||
* Copyright (C) 2005 Steve Underwood
|
* Copyright (C) 2005 Steve Underwood
|
||||||
*
|
*
|
||||||
* All rights reserved.
|
* Despite my general liking of the GPL, I place my own contributions
|
||||||
*
|
* to this code in the public domain for the benefit of all mankind -
|
||||||
* This program is free software; you can redistribute it and/or modify
|
* even the slimy ones who might try to proprietize my work and use it
|
||||||
* it under the terms of the GNU General Public License version 2, or
|
* to my detriment.
|
||||||
* the Lesser GNU General Public License version 2.1, as published by
|
|
||||||
* the Free Software Foundation.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
* GNU General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License
|
|
||||||
* along with this program; if not, write to the Free Software
|
|
||||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
|
||||||
*
|
*
|
||||||
* Based in part on a single channel G.722 codec which is:
|
* Based in part on a single channel G.722 codec which is:
|
||||||
*
|
*
|
||||||
@@ -29,7 +18,11 @@
|
|||||||
* Computer Science, Speech Group
|
* Computer Science, Speech Group
|
||||||
* Chengxiang Lu and Alex Hauptmann
|
* Chengxiang Lu and Alex Hauptmann
|
||||||
*
|
*
|
||||||
* $Id: g722_decode.c,v 1.20 2008/02/09 15:32:56 steveu Exp $
|
* $Id$
|
||||||
|
*
|
||||||
|
* rtphone: taken from Asterisk (codecs/g722). The only change is that the
|
||||||
|
* decoder saturates its output instead of letting a corrupt stream wrap
|
||||||
|
* around int16 (Asterisk casts (rlow << 1) and (xout >> 11) directly).
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*! \file */
|
/*! \file */
|
||||||
@@ -38,18 +31,37 @@
|
|||||||
#include <config.h>
|
#include <config.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include "g722_inttypes.h"
|
#include <stdio.h>
|
||||||
|
#include <inttypes.h>
|
||||||
#include <memory.h>
|
#include <memory.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#if defined(HAVE_TGMATH_H)
|
#if 0
|
||||||
#include <tgmath.h>
|
#include <tgmath.h>
|
||||||
#endif
|
#endif
|
||||||
#include <math.h>
|
|
||||||
|
|
||||||
#include "g722_telephony.h"
|
|
||||||
#include "g722_dc_restore.h"
|
|
||||||
#include "g722.h"
|
#include "g722.h"
|
||||||
|
|
||||||
|
#if !defined(FALSE)
|
||||||
|
#define FALSE 0
|
||||||
|
#endif
|
||||||
|
#if !defined(TRUE)
|
||||||
|
#define TRUE (!FALSE)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
static __inline__ int16_t saturate(int32_t amp)
|
||||||
|
{
|
||||||
|
int16_t amp16;
|
||||||
|
|
||||||
|
/* Hopefully this is optimised for the common case - not clipping */
|
||||||
|
amp16 = (int16_t) amp;
|
||||||
|
if (amp == amp16)
|
||||||
|
return amp16;
|
||||||
|
if (amp > INT16_MAX)
|
||||||
|
return INT16_MAX;
|
||||||
|
return INT16_MIN;
|
||||||
|
}
|
||||||
|
/*- End of function --------------------------------------------------------*/
|
||||||
|
|
||||||
static void block4(g722_decode_state_t *s, int band, int d);
|
static void block4(g722_decode_state_t *s, int band, int d);
|
||||||
|
|
||||||
static void block4(g722_decode_state_t *s, int band, int d)
|
static void block4(g722_decode_state_t *s, int band, int d)
|
||||||
@@ -177,14 +189,8 @@ int g722_decode_release(g722_decode_state_t *s)
|
|||||||
|
|
||||||
int g722_decode(g722_decode_state_t *s, int16_t amp[], const uint8_t g722_data[], int len)
|
int g722_decode(g722_decode_state_t *s, int16_t amp[], const uint8_t g722_data[], int len)
|
||||||
{
|
{
|
||||||
static const int wl[8] =
|
static const int wl[8] = {-60, -30, 58, 172, 334, 538, 1198, 3042 };
|
||||||
{
|
static const int rl42[16] = {0, 7, 6, 5, 4, 3, 2, 1, 7, 6, 5, 4, 3, 2, 1, 0 };
|
||||||
-60, -30, 58, 172, 334, 538, 1198, 3042
|
|
||||||
};
|
|
||||||
static const int rl42[16] =
|
|
||||||
{
|
|
||||||
0, 7, 6, 5, 4, 3, 2, 1, 7, 6, 5, 4, 3, 2, 1, 0
|
|
||||||
};
|
|
||||||
static const int ilb[32] =
|
static const int ilb[32] =
|
||||||
{
|
{
|
||||||
2048, 2093, 2139, 2186, 2233, 2282, 2332,
|
2048, 2093, 2139, 2186, 2233, 2282, 2332,
|
||||||
@@ -193,18 +199,9 @@ int g722_decode(g722_decode_state_t *s, int16_t amp[], const uint8_t g722_data[]
|
|||||||
3228, 3298, 3371, 3444, 3520, 3597, 3676,
|
3228, 3298, 3371, 3444, 3520, 3597, 3676,
|
||||||
3756, 3838, 3922, 4008
|
3756, 3838, 3922, 4008
|
||||||
};
|
};
|
||||||
static const int wh[3] =
|
static const int wh[3] = {0, -214, 798};
|
||||||
{
|
static const int rh2[4] = {2, 1, 2, 1};
|
||||||
0, -214, 798
|
static const int qm2[4] = {-7408, -1616, 7408, 1616};
|
||||||
};
|
|
||||||
static const int rh2[4] =
|
|
||||||
{
|
|
||||||
2, 1, 2, 1
|
|
||||||
};
|
|
||||||
static const int qm2[4] =
|
|
||||||
{
|
|
||||||
-7408, -1616, 7408, 1616
|
|
||||||
};
|
|
||||||
static const int qm4[16] =
|
static const int qm4[16] =
|
||||||
{
|
{
|
||||||
0, -20456, -12896, -8968,
|
0, -20456, -12896, -8968,
|
||||||
@@ -246,6 +243,7 @@ int g722_decode(g722_decode_state_t *s, int16_t amp[], const uint8_t g722_data[]
|
|||||||
{
|
{
|
||||||
3, -11, 12, 32, -210, 951, 3876, -805, 362, -156, 53, -11,
|
3, -11, 12, 32, -210, 951, 3876, -805, 362, -156, 53, -11,
|
||||||
};
|
};
|
||||||
|
|
||||||
int dlowt;
|
int dlowt;
|
||||||
int rlow;
|
int rlow;
|
||||||
int ihigh;
|
int ihigh;
|
||||||
@@ -369,19 +367,20 @@ int g722_decode(g722_decode_state_t *s, int16_t amp[], const uint8_t g722_data[]
|
|||||||
|
|
||||||
if (s->itu_test_mode)
|
if (s->itu_test_mode)
|
||||||
{
|
{
|
||||||
amp[outlen++] = (int16_t) (rlow << 1);
|
amp[outlen++] = saturate(rlow << 1);
|
||||||
amp[outlen++] = (int16_t) (rhigh << 1);
|
amp[outlen++] = (int16_t) (rhigh << 1);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (s->eight_k)
|
if (s->eight_k)
|
||||||
{
|
{
|
||||||
amp[outlen++] = (int16_t) rlow;
|
amp[outlen++] = saturate(rlow << 1);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
/* Apply the receive QMF */
|
/* Apply the receive QMF */
|
||||||
memcpy(s->x, &s->x[2], 22*sizeof(s->x[0]));
|
for (i = 0; i < 22; i++)
|
||||||
|
s->x[i] = s->x[i + 2];
|
||||||
s->x[22] = rlow + rhigh;
|
s->x[22] = rlow + rhigh;
|
||||||
s->x[23] = rlow - rhigh;
|
s->x[23] = rlow - rhigh;
|
||||||
|
|
||||||
@@ -392,8 +391,8 @@ int g722_decode(g722_decode_state_t *s, int16_t amp[], const uint8_t g722_data[]
|
|||||||
xout2 += s->x[2*i]*qmf_coeffs[i];
|
xout2 += s->x[2*i]*qmf_coeffs[i];
|
||||||
xout1 += s->x[2*i + 1]*qmf_coeffs[11 - i];
|
xout1 += s->x[2*i + 1]*qmf_coeffs[11 - i];
|
||||||
}
|
}
|
||||||
amp[outlen++] = (int16_t) (xout1 >> 12);
|
amp[outlen++] = saturate(xout1 >> 11);
|
||||||
amp[outlen++] = (int16_t) (xout2 >> 12);
|
amp[outlen++] = saturate(xout2 >> 11);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+35
-24
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* VoIPcodecs - a series of DSP components for telephony
|
* SpanDSP - a series of DSP components for telephony
|
||||||
*
|
*
|
||||||
* g722_encode.c - The ITU G.722 codec, encode part.
|
* g722_encode.c - The ITU G.722 codec, encode part.
|
||||||
*
|
*
|
||||||
@@ -9,19 +9,10 @@
|
|||||||
*
|
*
|
||||||
* All rights reserved.
|
* All rights reserved.
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify
|
* Despite my general liking of the GPL, I place my own contributions
|
||||||
* it under the terms of the GNU General Public License version 2, or
|
* to this code in the public domain for the benefit of all mankind -
|
||||||
* the Lesser GNU General Public License version 2.1, as published by
|
* even the slimy ones who might try to proprietize my work and use it
|
||||||
* the Free Software Foundation.
|
* to my detriment.
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
* GNU General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License
|
|
||||||
* along with this program; if not, write to the Free Software
|
|
||||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
|
||||||
*
|
*
|
||||||
* Based on a single channel 64kbps only G.722 codec which is:
|
* Based on a single channel 64kbps only G.722 codec which is:
|
||||||
*
|
*
|
||||||
@@ -29,7 +20,7 @@
|
|||||||
* Computer Science, Speech Group
|
* Computer Science, Speech Group
|
||||||
* Chengxiang Lu and Alex Hauptmann
|
* Chengxiang Lu and Alex Hauptmann
|
||||||
*
|
*
|
||||||
* $Id: g722_encode.c,v 1.18 2008/02/09 15:32:56 steveu Exp $
|
* $Id$
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*! \file */
|
/*! \file */
|
||||||
@@ -38,18 +29,37 @@
|
|||||||
#include <config.h>
|
#include <config.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include "g722_inttypes.h"
|
#include <stdio.h>
|
||||||
|
#include <inttypes.h>
|
||||||
#include <memory.h>
|
#include <memory.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#if defined(HAVE_TGMATH_H)
|
#if 0
|
||||||
#include <tgmath.h>
|
#include <tgmath.h>
|
||||||
#endif
|
#endif
|
||||||
#include <math.h>
|
|
||||||
|
|
||||||
#include "g722_telephony.h"
|
|
||||||
#include "g722_dc_restore.h"
|
|
||||||
#include "g722.h"
|
#include "g722.h"
|
||||||
|
|
||||||
|
#if !defined(FALSE)
|
||||||
|
#define FALSE 0
|
||||||
|
#endif
|
||||||
|
#if !defined(TRUE)
|
||||||
|
#define TRUE (!FALSE)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
static __inline__ int16_t saturate(int32_t amp)
|
||||||
|
{
|
||||||
|
int16_t amp16;
|
||||||
|
|
||||||
|
/* Hopefully this is optimised for the common case - not clipping */
|
||||||
|
amp16 = (int16_t) amp;
|
||||||
|
if (amp == amp16)
|
||||||
|
return amp16;
|
||||||
|
if (amp > INT16_MAX)
|
||||||
|
return INT16_MAX;
|
||||||
|
return INT16_MIN;
|
||||||
|
}
|
||||||
|
/*- End of function --------------------------------------------------------*/
|
||||||
|
|
||||||
static void block4(g722_encode_state_t *s, int band, int d)
|
static void block4(g722_encode_state_t *s, int band, int d)
|
||||||
{
|
{
|
||||||
int wd1;
|
int wd1;
|
||||||
@@ -269,13 +279,14 @@ int g722_encode(g722_encode_state_t *s, uint8_t g722_data[], const int16_t amp[]
|
|||||||
{
|
{
|
||||||
if (s->eight_k)
|
if (s->eight_k)
|
||||||
{
|
{
|
||||||
xlow = amp[j++];
|
xlow = amp[j++] >> 1;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
/* Apply the transmit QMF */
|
/* Apply the transmit QMF */
|
||||||
/* Shuffle the buffer down */
|
/* Shuffle the buffer down */
|
||||||
memcpy(s->x, &s->x[2], 22*sizeof(s->x[0]));
|
for (i = 0; i < 22; i++)
|
||||||
|
s->x[i] = s->x[i + 2];
|
||||||
s->x[22] = amp[j++];
|
s->x[22] = amp[j++];
|
||||||
s->x[23] = amp[j++];
|
s->x[23] = amp[j++];
|
||||||
|
|
||||||
@@ -287,8 +298,8 @@ int g722_encode(g722_encode_state_t *s, uint8_t g722_data[], const int16_t amp[]
|
|||||||
sumodd += s->x[2*i]*qmf_coeffs[i];
|
sumodd += s->x[2*i]*qmf_coeffs[i];
|
||||||
sumeven += s->x[2*i + 1]*qmf_coeffs[11 - i];
|
sumeven += s->x[2*i + 1]*qmf_coeffs[11 - i];
|
||||||
}
|
}
|
||||||
xlow = (sumeven + sumodd) >> 13;
|
xlow = (sumeven + sumodd) >> 14;
|
||||||
xhigh = (sumeven - sumodd) >> 13;
|
xhigh = (sumeven - sumodd) >> 14;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/* Block 1L, SUBTRA */
|
/* Block 1L, SUBTRA */
|
||||||
|
|||||||
@@ -1,103 +0,0 @@
|
|||||||
/*
|
|
||||||
* SpanDSP - a series of DSP components for telephony
|
|
||||||
*
|
|
||||||
* inttypes.h - a fudge for MSVC, which lacks this header
|
|
||||||
*
|
|
||||||
* Written by Steve Underwood <steveu@coppice.org>
|
|
||||||
*
|
|
||||||
* Copyright (C) 2006 Michael Jerris
|
|
||||||
*
|
|
||||||
*
|
|
||||||
* This file is released in the public domain.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
#if !defined(_INTTYPES_H_)
|
|
||||||
#define _INTTYPES_H_
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
extern "C" {
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef _MSC_VER
|
|
||||||
#if (_MSC_VER >= 1400) // VC8+
|
|
||||||
#ifndef _CRT_SECURE_NO_DEPRECATE
|
|
||||||
#define _CRT_SECURE_NO_DEPRECATE
|
|
||||||
#endif
|
|
||||||
#ifndef _CRT_NONSTDC_NO_DEPRECATE
|
|
||||||
#define _CRT_NONSTDC_NO_DEPRECATE
|
|
||||||
#endif
|
|
||||||
#endif // VC8+
|
|
||||||
|
|
||||||
#include <windows.h>
|
|
||||||
typedef unsigned __int8 uint8_t;
|
|
||||||
typedef unsigned __int16 uint16_t;
|
|
||||||
typedef unsigned __int32 uint32_t;
|
|
||||||
typedef unsigned __int64 uint64_t;
|
|
||||||
typedef __int8 int8_t;
|
|
||||||
typedef __int16 int16_t;
|
|
||||||
typedef __int32 int32_t;
|
|
||||||
typedef __int64 int64_t;
|
|
||||||
#define inline __inline
|
|
||||||
#define __inline__ __inline
|
|
||||||
#define INT16_MAX 0x7fff
|
|
||||||
#define INT16_MIN (-INT16_MAX - 1)
|
|
||||||
#define _MMX_H_
|
|
||||||
|
|
||||||
/* disable the following warnings
|
|
||||||
* C4100: The formal parameter is not referenced in the body of the function. The unreferenced parameter is ignored.
|
|
||||||
* C4200: Non standard extension C zero sized array
|
|
||||||
* C4706: assignment within conditional expression
|
|
||||||
* C4244: conversion from 'type1' to 'type2', possible loss of data
|
|
||||||
* C4295: array is too small to include a terminating null character
|
|
||||||
* C4125: decimal digit terminates octal escape sequence
|
|
||||||
*/
|
|
||||||
#pragma warning(disable:4100 4200 4706 4295 4125)
|
|
||||||
|
|
||||||
//#pragma comment(lib, "ws2_32.lib")
|
|
||||||
|
|
||||||
#define strncasecmp _strnicmp
|
|
||||||
#define strcasecmp _stricmp
|
|
||||||
#define snprintf _snprintf
|
|
||||||
|
|
||||||
#if !defined(INFINITY)
|
|
||||||
#define INFINITY 0x7fffffff
|
|
||||||
#endif
|
|
||||||
#else
|
|
||||||
#include <stdint.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#define PACKAGE "voipcodecs"
|
|
||||||
#define VERSION "0.0.1andabit"
|
|
||||||
|
|
||||||
#ifndef INT32_MAX
|
|
||||||
#define INT32_MAX (2147483647)
|
|
||||||
#endif
|
|
||||||
#ifndef INT32_MIN
|
|
||||||
#define INT32_MIN (-2147483647 - 1)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#define PRId8 "d"
|
|
||||||
#define PRId16 "d"
|
|
||||||
#ifndef PRId32
|
|
||||||
# define PRId32 "ld"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef PRId64
|
|
||||||
# define PRId64 "lld"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#define PRIu8 "u"
|
|
||||||
#define PRIu16 "u"
|
|
||||||
#ifndef PRIu32
|
|
||||||
# define PRIu32 "lu"
|
|
||||||
#endif
|
|
||||||
#ifndef PRIu64
|
|
||||||
# define PRIu64 "llu"
|
|
||||||
#endif
|
|
||||||
#ifdef __cplusplus
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif // _INTTYPES_H_
|
|
||||||
|
|
||||||
@@ -1,74 +0,0 @@
|
|||||||
/*
|
|
||||||
* VoIPcodecs - a series of DSP components for telephony
|
|
||||||
*
|
|
||||||
* telephony.h - some very basic telephony definitions
|
|
||||||
*
|
|
||||||
* Written by Steve Underwood <steveu@coppice.org>
|
|
||||||
*
|
|
||||||
* Copyright (C) 2003 Steve Underwood
|
|
||||||
*
|
|
||||||
* All rights reserved.
|
|
||||||
*
|
|
||||||
* This program is free software; you can redistribute it and/or modify
|
|
||||||
* it under the terms of the Lesser GNU General Public License version 2.1, as
|
|
||||||
* published by the Free Software Foundation.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
* GNU General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License
|
|
||||||
* along with this program; if not, write to the Free Software
|
|
||||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
|
||||||
*
|
|
||||||
* $Id: telephony.h,v 1.10 2007/04/05 19:20:50 steveu Exp $
|
|
||||||
*/
|
|
||||||
|
|
||||||
#if !defined(_SPANDSP_TELEPHONY_H_)
|
|
||||||
#define _SPANDSP_TELEPHONY_H_
|
|
||||||
|
|
||||||
#define SAMPLE_RATE 8000
|
|
||||||
|
|
||||||
/* This is based on A-law, but u-law is only 0.03dB different */
|
|
||||||
#define DBM0_MAX_POWER (3.14f + 3.02f)
|
|
||||||
#define DBM0_MAX_SINE_POWER (3.14f)
|
|
||||||
/* This is based on the ITU definition of dbOv in G.100.1 */
|
|
||||||
#define DBOV_MAX_POWER (0.0f)
|
|
||||||
#define DBOV_MAX_SINE_POWER (-3.02f)
|
|
||||||
|
|
||||||
/*! \brief A handler for pure receive. The buffer cannot be altered. */
|
|
||||||
typedef int (span_rx_handler_t)(void *s, const int16_t amp[], int len);
|
|
||||||
|
|
||||||
/*! \brief A handler for receive, where the buffer can be altered. */
|
|
||||||
typedef int (span_mod_handler_t)(void *s, int16_t amp[], int len);
|
|
||||||
|
|
||||||
/*! \brief A handler for transmit, where the buffer will be filled. */
|
|
||||||
typedef int (span_tx_handler_t)(void *s, int16_t amp[], int max_len);
|
|
||||||
|
|
||||||
#define ms_to_samples(t) (((t)*SAMPLE_RATE)/1000)
|
|
||||||
|
|
||||||
#if !defined(FALSE)
|
|
||||||
#define FALSE 0
|
|
||||||
#endif
|
|
||||||
#if !defined(TRUE)
|
|
||||||
#define TRUE (!FALSE)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include <assert.h>
|
|
||||||
#if (_MSC_VER >= 1400) // VC8+
|
|
||||||
#define vc_assert(expr) assert(expr);__analysis_assume( expr )
|
|
||||||
#else
|
|
||||||
#define vc_assert(expr) assert(expr)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if defined(__cplusplus)
|
|
||||||
/* C++ doesn't seem to have sane rounding functions/macros yet */
|
|
||||||
#ifndef _MSC_VER
|
|
||||||
#define lrint(x) ((long int) (x))
|
|
||||||
#define lrintf(x) ((long int) (x))
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif
|
|
||||||
/*- End of file ------------------------------------------------------------*/
|
|
||||||
@@ -1,300 +0,0 @@
|
|||||||
/*
|
|
||||||
* G.722 Plugin codec for OpenH323/OPAL
|
|
||||||
*
|
|
||||||
* Copyright (C) 2008 by Hermon Labs, All Rights Reserved
|
|
||||||
*
|
|
||||||
* The contents of this file are subject to the Mozilla Public License
|
|
||||||
* Version 1.0 (the "License"); you may not use this file except in
|
|
||||||
* compliance with the License. You may obtain a copy of the License at
|
|
||||||
* http://www.mozilla.org/MPL/
|
|
||||||
*
|
|
||||||
* Software distributed under the License is distributed on an "AS IS"
|
|
||||||
* basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
|
|
||||||
* the License for the specific language governing rights and limitations
|
|
||||||
* under the License.
|
|
||||||
*
|
|
||||||
* The Original Code is Open Phone Abstraction Library.
|
|
||||||
*
|
|
||||||
* The Initial Developer of the Original Code is Eugene Mednikov
|
|
||||||
*
|
|
||||||
* Contributor(s): ______________________________________.
|
|
||||||
*
|
|
||||||
* $Revision: 23265 $
|
|
||||||
* $Author: rjongbloed $
|
|
||||||
* $Date: 2009-08-25 04:25:58 +0300 (вт, 25 серп 2009) $
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef PLUGIN_CODEC_DLL_EXPORTS
|
|
||||||
#include "plugin-config.h"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include <codec/opalplugin.h>
|
|
||||||
|
|
||||||
#include "VoIPCodecs/inttypes.h"
|
|
||||||
#include "VoIPCodecs/g722.h"
|
|
||||||
|
|
||||||
|
|
||||||
#define INCLUDE_SDP_16000_VERSION 0
|
|
||||||
|
|
||||||
/* Due to a spec error, clock rate is 8kHz even though this is 16kHz codec,
|
|
||||||
see RFC3551/4.5.2. So some of these values have to be lied about so that
|
|
||||||
the OPAL system gets it right.
|
|
||||||
*/
|
|
||||||
#define CLOCK_RATE 8000 // Clock rate is not samples/second in this case!
|
|
||||||
#define BITS_PER_SECOND 64000 // raw bits per second
|
|
||||||
#define FRAME_TIME 1000 // Microseconds in a millisecond
|
|
||||||
#define SAMPLES_PER_FRAME 16 // Samples in a millisecond
|
|
||||||
#define BYTES_PER_FRAME 8 // Bytes in a millisecond
|
|
||||||
#define MAX_FRAMES_PER_PACKET 90 // 90 milliseconds, which means RTP packets smaller than 1500 bytes typical LAN maximum
|
|
||||||
#define PREF_FRAMES_PER_PACKET 20 // 20 milliseconds
|
|
||||||
|
|
||||||
static const char L16Desc[] = "PCM-16-16kHz"; // Cannot use "L16" as usual, force 16kHz PCM
|
|
||||||
static const char g722[] = "G.722-64k";
|
|
||||||
static const char sdpG722[] = "G722";
|
|
||||||
|
|
||||||
#if INCLUDE_SDP_16000_VERSION
|
|
||||||
static const char g722_16[] = "G.722-16kHz";
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#define PAYLOAD_CODE 9
|
|
||||||
|
|
||||||
|
|
||||||
/////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
static void * create_encoder(const struct PluginCodec_Definition * codec)
|
|
||||||
{
|
|
||||||
return g722_encode_init(NULL, BITS_PER_SECOND, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void destroy_encoder(const struct PluginCodec_Definition * codec, void * context)
|
|
||||||
{
|
|
||||||
g722_encode_release(context);
|
|
||||||
}
|
|
||||||
|
|
||||||
static int encode(const struct PluginCodec_Definition * codec,
|
|
||||||
void * context,
|
|
||||||
const void * from,
|
|
||||||
unsigned * fromLen,
|
|
||||||
void * to,
|
|
||||||
unsigned * toLen,
|
|
||||||
unsigned int * flag)
|
|
||||||
{
|
|
||||||
g722_encode_state_t * state = context;
|
|
||||||
|
|
||||||
if (*toLen < *fromLen / 4)
|
|
||||||
return 0; // Destination buffer not big enough
|
|
||||||
|
|
||||||
*toLen = g722_encode(state, to, from, *fromLen / 2);
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
static void * create_decoder(const struct PluginCodec_Definition * codec)
|
|
||||||
{
|
|
||||||
return g722_decode_init(NULL, BITS_PER_SECOND, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void destroy_decoder(const struct PluginCodec_Definition * codec, void * context)
|
|
||||||
{
|
|
||||||
g722_decode_release(context);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static int decode(const struct PluginCodec_Definition * codec,
|
|
||||||
void * _context,
|
|
||||||
const void * from,
|
|
||||||
unsigned * fromLen,
|
|
||||||
void * to,
|
|
||||||
unsigned * toLen,
|
|
||||||
unsigned int * flag)
|
|
||||||
{
|
|
||||||
g722_decode_state_t * state = _context;
|
|
||||||
|
|
||||||
if (*toLen < *fromLen * 4)
|
|
||||||
return 0; // Destination buffer not big enough
|
|
||||||
|
|
||||||
*toLen = g722_decode(state, to, from, *fromLen) * 2;
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
static struct PluginCodec_information licenseInfo = {
|
|
||||||
1084181196, // timestamp = Mon 10 May 2004 09:26:36 AM UTC
|
|
||||||
|
|
||||||
"Eugene Mednikov", // source code author
|
|
||||||
"1.0", // source code version
|
|
||||||
"em@hermonlabs.com", // source code email
|
|
||||||
"http://www.hermonlabs.com", // source code URL
|
|
||||||
"Copyright (C) 2008 by Hermon Labs, All Rights Reserved", // source code copyright
|
|
||||||
"MPL 1.0", // source code license
|
|
||||||
PluginCodec_License_MPL, // source code license
|
|
||||||
|
|
||||||
"ITU G.722", // codec description
|
|
||||||
"Steve Underwood", // codec author
|
|
||||||
NULL, // codec version
|
|
||||||
"steveu@coppice.org", // codec email
|
|
||||||
NULL, // codec URL
|
|
||||||
NULL, // codec copyright information
|
|
||||||
NULL, // codec license
|
|
||||||
PluginCodec_License_LGPL // codec license code
|
|
||||||
};
|
|
||||||
|
|
||||||
/////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
static struct PluginCodec_Definition g722CodecDefn[] =
|
|
||||||
{
|
|
||||||
#if INCLUDE_SDP_16000_VERSION
|
|
||||||
// Include a version for SIP/SDP that indicates the more logical, though
|
|
||||||
// incorrect by RFC3551/4.5.2, 16000Hz version of G.722. We use dynamic
|
|
||||||
// payload types to avoid conflict with the compliant 8000Hz version.
|
|
||||||
{
|
|
||||||
// encoder
|
|
||||||
PLUGIN_CODEC_VERSION_WIDEBAND, // codec API version
|
|
||||||
&licenseInfo, // license information
|
|
||||||
|
|
||||||
PluginCodec_MediaTypeAudio | // audio codec
|
|
||||||
PluginCodec_InputTypeRaw | // raw input data
|
|
||||||
PluginCodec_OutputTypeRaw | // raw output data
|
|
||||||
PluginCodec_RTPTypeDynamic, // specified RTP type
|
|
||||||
|
|
||||||
g722_16, // text decription
|
|
||||||
L16Desc, // source format
|
|
||||||
g722_16, // destination format
|
|
||||||
|
|
||||||
0, // user data
|
|
||||||
|
|
||||||
16000, // samples per second
|
|
||||||
BITS_PER_SECOND, // raw bits per second
|
|
||||||
FRAME_TIME, // microseconds per frame
|
|
||||||
SAMPLES_PER_FRAME, // samples per frame
|
|
||||||
BYTES_PER_FRAME, // bytes per frame
|
|
||||||
PREF_FRAMES_PER_PACKET, // recommended number of frames per packet
|
|
||||||
MAX_FRAMES_PER_PACKET, // maximum number of frames per packe
|
|
||||||
PAYLOAD_CODE, // IANA RTP payload code
|
|
||||||
sdpG722, // RTP payload name
|
|
||||||
|
|
||||||
create_encoder, // create codec function
|
|
||||||
destroy_encoder, // destroy codec
|
|
||||||
encode, // encode/decode
|
|
||||||
NULL, // codec controls
|
|
||||||
|
|
||||||
0, // h323CapabilityType
|
|
||||||
NULL // h323CapabilityData
|
|
||||||
},
|
|
||||||
|
|
||||||
{
|
|
||||||
// decoder
|
|
||||||
PLUGIN_CODEC_VERSION_WIDEBAND, // codec API version
|
|
||||||
&licenseInfo, // license information
|
|
||||||
|
|
||||||
PluginCodec_MediaTypeAudio | // audio codec
|
|
||||||
PluginCodec_InputTypeRaw | // raw input data
|
|
||||||
PluginCodec_OutputTypeRaw | // raw output data
|
|
||||||
PluginCodec_RTPTypeDynamic, // specified RTP type
|
|
||||||
|
|
||||||
g722_16, // text decription
|
|
||||||
g722_16, // source format
|
|
||||||
L16Desc, // destination format
|
|
||||||
|
|
||||||
0, // user data
|
|
||||||
|
|
||||||
16000, // samples per second
|
|
||||||
BITS_PER_SECOND, // raw bits per second
|
|
||||||
FRAME_TIME, // microseconds per frame
|
|
||||||
SAMPLES_PER_FRAME, // samples per frame
|
|
||||||
BYTES_PER_FRAME, // bytes per frame
|
|
||||||
PREF_FRAMES_PER_PACKET, // recommended number of frames per packet
|
|
||||||
MAX_FRAMES_PER_PACKET, // maximum number of frames per packe
|
|
||||||
PAYLOAD_CODE, // IANA RTP payload code
|
|
||||||
sdpG722, // RTP payload name
|
|
||||||
|
|
||||||
create_decoder, // create codec function
|
|
||||||
destroy_decoder, // destroy codec
|
|
||||||
decode, // encode/decode
|
|
||||||
NULL, // codec controls
|
|
||||||
|
|
||||||
0, // h323CapabilityType
|
|
||||||
NULL // h323CapabilityData
|
|
||||||
},
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// Standards compliant version
|
|
||||||
{
|
|
||||||
// encoder
|
|
||||||
PLUGIN_CODEC_VERSION_WIDEBAND, // codec API version
|
|
||||||
&licenseInfo, // license information
|
|
||||||
|
|
||||||
PluginCodec_MediaTypeAudio | // audio codec
|
|
||||||
PluginCodec_InputTypeRaw | // raw input data
|
|
||||||
PluginCodec_OutputTypeRaw | // raw output data
|
|
||||||
PluginCodec_RTPTypeExplicit, // specified RTP type
|
|
||||||
|
|
||||||
g722, // text decription
|
|
||||||
L16Desc, // source format
|
|
||||||
g722, // destination format
|
|
||||||
|
|
||||||
0, // user data
|
|
||||||
|
|
||||||
CLOCK_RATE, // samples per second
|
|
||||||
BITS_PER_SECOND, // raw bits per second
|
|
||||||
FRAME_TIME, // microseconds per frame
|
|
||||||
SAMPLES_PER_FRAME, // samples per frame
|
|
||||||
BYTES_PER_FRAME, // bytes per frame
|
|
||||||
PREF_FRAMES_PER_PACKET, // recommended number of frames per packet
|
|
||||||
MAX_FRAMES_PER_PACKET, // maximum number of frames per packe
|
|
||||||
PAYLOAD_CODE, // IANA RTP payload code
|
|
||||||
sdpG722, // RTP payload name
|
|
||||||
|
|
||||||
create_encoder, // create codec function
|
|
||||||
destroy_encoder, // destroy codec
|
|
||||||
encode, // encode/decode
|
|
||||||
NULL, // codec controls
|
|
||||||
|
|
||||||
PluginCodec_H323AudioCodec_g722_64k, // h323CapabilityType
|
|
||||||
NULL // h323CapabilityData
|
|
||||||
},
|
|
||||||
|
|
||||||
{
|
|
||||||
// decoder
|
|
||||||
PLUGIN_CODEC_VERSION_WIDEBAND, // codec API version
|
|
||||||
&licenseInfo, // license information
|
|
||||||
|
|
||||||
PluginCodec_MediaTypeAudio | // audio codec
|
|
||||||
PluginCodec_InputTypeRaw | // raw input data
|
|
||||||
PluginCodec_OutputTypeRaw | // raw output data
|
|
||||||
PluginCodec_RTPTypeExplicit, // specified RTP type
|
|
||||||
|
|
||||||
g722, // text decription
|
|
||||||
g722, // source format
|
|
||||||
L16Desc, // destination format
|
|
||||||
|
|
||||||
0, // user data
|
|
||||||
|
|
||||||
CLOCK_RATE, // samples per second
|
|
||||||
BITS_PER_SECOND, // raw bits per second
|
|
||||||
FRAME_TIME, // microseconds per frame
|
|
||||||
SAMPLES_PER_FRAME, // samples per frame
|
|
||||||
BYTES_PER_FRAME, // bytes per frame
|
|
||||||
PREF_FRAMES_PER_PACKET, // recommended number of frames per packet
|
|
||||||
MAX_FRAMES_PER_PACKET, // maximum number of frames per packe
|
|
||||||
PAYLOAD_CODE, // IANA RTP payload code
|
|
||||||
sdpG722, // RTP payload name
|
|
||||||
|
|
||||||
create_decoder, // create codec function
|
|
||||||
destroy_decoder, // destroy codec
|
|
||||||
decode, // encode/decode
|
|
||||||
NULL, // codec controls
|
|
||||||
|
|
||||||
PluginCodec_H323AudioCodec_g722_64k, // h323CapabilityType
|
|
||||||
NULL // h323CapabilityData
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
PLUGIN_CODEC_IMPLEMENT_ALL(G722, g722CodecDefn, PLUGIN_CODEC_VERSION_WIDEBAND)
|
|
||||||
|
|
||||||
/////////////////////////////////////////////////////////////////////////////
|
|
||||||
Reference in New Issue
Block a user