Moving src/webrtc into src/.
In order to eliminate the WebRTC Subtree mirror in Chromium, WebRTC is moving the content of the src/webrtc directory up to the src/ directory. NOPRESUBMIT=true NOTREECHECKS=true NOTRY=true TBR=tommi@webrtc.org Bug: chromium:611808 Change-Id: Iac59c5b51b950f174119565bac87955a7994bc38 Reviewed-on: https://webrtc-review.googlesource.com/1560 Commit-Queue: Mirko Bonadei <mbonadei@webrtc.org> Reviewed-by: Henrik Kjellander <kjellander@webrtc.org> Cr-Commit-Position: refs/heads/master@{#19845}
This commit is contained in:
committed by
Commit Bot
parent
6674846b4a
commit
bb547203bf
0
modules/audio_coding/codecs/g711/OWNERS
Normal file
0
modules/audio_coding/codecs/g711/OWNERS
Normal file
88
modules/audio_coding/codecs/g711/audio_decoder_pcm.cc
Normal file
88
modules/audio_coding/codecs/g711/audio_decoder_pcm.cc
Normal file
@ -0,0 +1,88 @@
|
||||
/*
|
||||
* Copyright (c) 2015 The WebRTC project authors. All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license
|
||||
* that can be found in the LICENSE file in the root of the source
|
||||
* tree. An additional intellectual property rights grant can be found
|
||||
* in the file PATENTS. All contributing project authors may
|
||||
* be found in the AUTHORS file in the root of the source tree.
|
||||
*/
|
||||
|
||||
#include "webrtc/modules/audio_coding/codecs/g711/audio_decoder_pcm.h"
|
||||
|
||||
#include "webrtc/modules/audio_coding/codecs/legacy_encoded_audio_frame.h"
|
||||
#include "webrtc/modules/audio_coding/codecs/g711/g711_interface.h"
|
||||
|
||||
namespace webrtc {
|
||||
|
||||
void AudioDecoderPcmU::Reset() {}
|
||||
|
||||
std::vector<AudioDecoder::ParseResult> AudioDecoderPcmU::ParsePayload(
|
||||
rtc::Buffer&& payload,
|
||||
uint32_t timestamp) {
|
||||
return LegacyEncodedAudioFrame::SplitBySamples(
|
||||
this, std::move(payload), timestamp, 8 * num_channels_, 8);
|
||||
}
|
||||
|
||||
int AudioDecoderPcmU::SampleRateHz() const {
|
||||
return 8000;
|
||||
}
|
||||
|
||||
size_t AudioDecoderPcmU::Channels() const {
|
||||
return num_channels_;
|
||||
}
|
||||
|
||||
int AudioDecoderPcmU::DecodeInternal(const uint8_t* encoded,
|
||||
size_t encoded_len,
|
||||
int sample_rate_hz,
|
||||
int16_t* decoded,
|
||||
SpeechType* speech_type) {
|
||||
RTC_DCHECK_EQ(SampleRateHz(), sample_rate_hz);
|
||||
int16_t temp_type = 1; // Default is speech.
|
||||
size_t ret = WebRtcG711_DecodeU(encoded, encoded_len, decoded, &temp_type);
|
||||
*speech_type = ConvertSpeechType(temp_type);
|
||||
return static_cast<int>(ret);
|
||||
}
|
||||
|
||||
int AudioDecoderPcmU::PacketDuration(const uint8_t* encoded,
|
||||
size_t encoded_len) const {
|
||||
// One encoded byte per sample per channel.
|
||||
return static_cast<int>(encoded_len / Channels());
|
||||
}
|
||||
|
||||
void AudioDecoderPcmA::Reset() {}
|
||||
|
||||
std::vector<AudioDecoder::ParseResult> AudioDecoderPcmA::ParsePayload(
|
||||
rtc::Buffer&& payload,
|
||||
uint32_t timestamp) {
|
||||
return LegacyEncodedAudioFrame::SplitBySamples(
|
||||
this, std::move(payload), timestamp, 8 * num_channels_, 8);
|
||||
}
|
||||
|
||||
int AudioDecoderPcmA::SampleRateHz() const {
|
||||
return 8000;
|
||||
}
|
||||
|
||||
size_t AudioDecoderPcmA::Channels() const {
|
||||
return num_channels_;
|
||||
}
|
||||
|
||||
int AudioDecoderPcmA::DecodeInternal(const uint8_t* encoded,
|
||||
size_t encoded_len,
|
||||
int sample_rate_hz,
|
||||
int16_t* decoded,
|
||||
SpeechType* speech_type) {
|
||||
RTC_DCHECK_EQ(SampleRateHz(), sample_rate_hz);
|
||||
int16_t temp_type = 1; // Default is speech.
|
||||
size_t ret = WebRtcG711_DecodeA(encoded, encoded_len, decoded, &temp_type);
|
||||
*speech_type = ConvertSpeechType(temp_type);
|
||||
return static_cast<int>(ret);
|
||||
}
|
||||
|
||||
int AudioDecoderPcmA::PacketDuration(const uint8_t* encoded,
|
||||
size_t encoded_len) const {
|
||||
// One encoded byte per sample per channel.
|
||||
return static_cast<int>(encoded_len / Channels());
|
||||
}
|
||||
|
||||
} // namespace webrtc
|
||||
70
modules/audio_coding/codecs/g711/audio_decoder_pcm.h
Normal file
70
modules/audio_coding/codecs/g711/audio_decoder_pcm.h
Normal file
@ -0,0 +1,70 @@
|
||||
/*
|
||||
* Copyright (c) 2015 The WebRTC project authors. All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license
|
||||
* that can be found in the LICENSE file in the root of the source
|
||||
* tree. An additional intellectual property rights grant can be found
|
||||
* in the file PATENTS. All contributing project authors may
|
||||
* be found in the AUTHORS file in the root of the source tree.
|
||||
*/
|
||||
|
||||
#ifndef WEBRTC_MODULES_AUDIO_CODING_CODECS_G711_AUDIO_DECODER_PCM_H_
|
||||
#define WEBRTC_MODULES_AUDIO_CODING_CODECS_G711_AUDIO_DECODER_PCM_H_
|
||||
|
||||
#include "webrtc/api/audio_codecs/audio_decoder.h"
|
||||
#include "webrtc/rtc_base/checks.h"
|
||||
#include "webrtc/rtc_base/constructormagic.h"
|
||||
|
||||
namespace webrtc {
|
||||
|
||||
class AudioDecoderPcmU final : public AudioDecoder {
|
||||
public:
|
||||
explicit AudioDecoderPcmU(size_t num_channels) : num_channels_(num_channels) {
|
||||
RTC_DCHECK_GE(num_channels, 1);
|
||||
}
|
||||
void Reset() override;
|
||||
std::vector<ParseResult> ParsePayload(rtc::Buffer&& payload,
|
||||
uint32_t timestamp) override;
|
||||
int PacketDuration(const uint8_t* encoded, size_t encoded_len) const override;
|
||||
int SampleRateHz() const override;
|
||||
size_t Channels() const override;
|
||||
|
||||
protected:
|
||||
int DecodeInternal(const uint8_t* encoded,
|
||||
size_t encoded_len,
|
||||
int sample_rate_hz,
|
||||
int16_t* decoded,
|
||||
SpeechType* speech_type) override;
|
||||
|
||||
private:
|
||||
const size_t num_channels_;
|
||||
RTC_DISALLOW_COPY_AND_ASSIGN(AudioDecoderPcmU);
|
||||
};
|
||||
|
||||
class AudioDecoderPcmA final : public AudioDecoder {
|
||||
public:
|
||||
explicit AudioDecoderPcmA(size_t num_channels) : num_channels_(num_channels) {
|
||||
RTC_DCHECK_GE(num_channels, 1);
|
||||
}
|
||||
void Reset() override;
|
||||
std::vector<ParseResult> ParsePayload(rtc::Buffer&& payload,
|
||||
uint32_t timestamp) override;
|
||||
int PacketDuration(const uint8_t* encoded, size_t encoded_len) const override;
|
||||
int SampleRateHz() const override;
|
||||
size_t Channels() const override;
|
||||
|
||||
protected:
|
||||
int DecodeInternal(const uint8_t* encoded,
|
||||
size_t encoded_len,
|
||||
int sample_rate_hz,
|
||||
int16_t* decoded,
|
||||
SpeechType* speech_type) override;
|
||||
|
||||
private:
|
||||
const size_t num_channels_;
|
||||
RTC_DISALLOW_COPY_AND_ASSIGN(AudioDecoderPcmA);
|
||||
};
|
||||
|
||||
} // namespace webrtc
|
||||
|
||||
#endif // WEBRTC_MODULES_AUDIO_CODING_CODECS_G711_AUDIO_DECODER_PCM_H_
|
||||
142
modules/audio_coding/codecs/g711/audio_encoder_pcm.cc
Normal file
142
modules/audio_coding/codecs/g711/audio_encoder_pcm.cc
Normal file
@ -0,0 +1,142 @@
|
||||
/*
|
||||
* Copyright (c) 2014 The WebRTC project authors. All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license
|
||||
* that can be found in the LICENSE file in the root of the source
|
||||
* tree. An additional intellectual property rights grant can be found
|
||||
* in the file PATENTS. All contributing project authors may
|
||||
* be found in the AUTHORS file in the root of the source tree.
|
||||
*/
|
||||
|
||||
#include "webrtc/modules/audio_coding/codecs/g711/audio_encoder_pcm.h"
|
||||
|
||||
#include <algorithm>
|
||||
#include <limits>
|
||||
|
||||
#include "webrtc/common_types.h"
|
||||
#include "webrtc/modules/audio_coding/codecs/g711/g711_interface.h"
|
||||
#include "webrtc/rtc_base/checks.h"
|
||||
|
||||
namespace webrtc {
|
||||
|
||||
namespace {
|
||||
|
||||
template <typename T>
|
||||
typename T::Config CreateConfig(const CodecInst& codec_inst) {
|
||||
typename T::Config config;
|
||||
config.frame_size_ms = codec_inst.pacsize / 8;
|
||||
config.num_channels = codec_inst.channels;
|
||||
config.payload_type = codec_inst.pltype;
|
||||
return config;
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
bool AudioEncoderPcm::Config::IsOk() const {
|
||||
return (frame_size_ms % 10 == 0) && (num_channels >= 1);
|
||||
}
|
||||
|
||||
AudioEncoderPcm::AudioEncoderPcm(const Config& config, int sample_rate_hz)
|
||||
: sample_rate_hz_(sample_rate_hz),
|
||||
num_channels_(config.num_channels),
|
||||
payload_type_(config.payload_type),
|
||||
num_10ms_frames_per_packet_(
|
||||
static_cast<size_t>(config.frame_size_ms / 10)),
|
||||
full_frame_samples_(
|
||||
config.num_channels * config.frame_size_ms * sample_rate_hz / 1000),
|
||||
first_timestamp_in_buffer_(0) {
|
||||
RTC_CHECK_GT(sample_rate_hz, 0) << "Sample rate must be larger than 0 Hz";
|
||||
RTC_CHECK_EQ(config.frame_size_ms % 10, 0)
|
||||
<< "Frame size must be an integer multiple of 10 ms.";
|
||||
speech_buffer_.reserve(full_frame_samples_);
|
||||
}
|
||||
|
||||
AudioEncoderPcm::~AudioEncoderPcm() = default;
|
||||
|
||||
int AudioEncoderPcm::SampleRateHz() const {
|
||||
return sample_rate_hz_;
|
||||
}
|
||||
|
||||
size_t AudioEncoderPcm::NumChannels() const {
|
||||
return num_channels_;
|
||||
}
|
||||
|
||||
size_t AudioEncoderPcm::Num10MsFramesInNextPacket() const {
|
||||
return num_10ms_frames_per_packet_;
|
||||
}
|
||||
|
||||
size_t AudioEncoderPcm::Max10MsFramesInAPacket() const {
|
||||
return num_10ms_frames_per_packet_;
|
||||
}
|
||||
|
||||
int AudioEncoderPcm::GetTargetBitrate() const {
|
||||
return static_cast<int>(
|
||||
8 * BytesPerSample() * SampleRateHz() * NumChannels());
|
||||
}
|
||||
|
||||
AudioEncoder::EncodedInfo AudioEncoderPcm::EncodeImpl(
|
||||
uint32_t rtp_timestamp,
|
||||
rtc::ArrayView<const int16_t> audio,
|
||||
rtc::Buffer* encoded) {
|
||||
if (speech_buffer_.empty()) {
|
||||
first_timestamp_in_buffer_ = rtp_timestamp;
|
||||
}
|
||||
speech_buffer_.insert(speech_buffer_.end(), audio.begin(), audio.end());
|
||||
if (speech_buffer_.size() < full_frame_samples_) {
|
||||
return EncodedInfo();
|
||||
}
|
||||
RTC_CHECK_EQ(speech_buffer_.size(), full_frame_samples_);
|
||||
EncodedInfo info;
|
||||
info.encoded_timestamp = first_timestamp_in_buffer_;
|
||||
info.payload_type = payload_type_;
|
||||
info.encoded_bytes =
|
||||
encoded->AppendData(full_frame_samples_ * BytesPerSample(),
|
||||
[&] (rtc::ArrayView<uint8_t> encoded) {
|
||||
return EncodeCall(&speech_buffer_[0],
|
||||
full_frame_samples_,
|
||||
encoded.data());
|
||||
});
|
||||
speech_buffer_.clear();
|
||||
info.encoder_type = GetCodecType();
|
||||
return info;
|
||||
}
|
||||
|
||||
void AudioEncoderPcm::Reset() {
|
||||
speech_buffer_.clear();
|
||||
}
|
||||
|
||||
AudioEncoderPcmA::AudioEncoderPcmA(const CodecInst& codec_inst)
|
||||
: AudioEncoderPcmA(CreateConfig<AudioEncoderPcmA>(codec_inst)) {}
|
||||
|
||||
size_t AudioEncoderPcmA::EncodeCall(const int16_t* audio,
|
||||
size_t input_len,
|
||||
uint8_t* encoded) {
|
||||
return WebRtcG711_EncodeA(audio, input_len, encoded);
|
||||
}
|
||||
|
||||
size_t AudioEncoderPcmA::BytesPerSample() const {
|
||||
return 1;
|
||||
}
|
||||
|
||||
AudioEncoder::CodecType AudioEncoderPcmA::GetCodecType() const {
|
||||
return AudioEncoder::CodecType::kPcmA;
|
||||
}
|
||||
|
||||
AudioEncoderPcmU::AudioEncoderPcmU(const CodecInst& codec_inst)
|
||||
: AudioEncoderPcmU(CreateConfig<AudioEncoderPcmU>(codec_inst)) {}
|
||||
|
||||
size_t AudioEncoderPcmU::EncodeCall(const int16_t* audio,
|
||||
size_t input_len,
|
||||
uint8_t* encoded) {
|
||||
return WebRtcG711_EncodeU(audio, input_len, encoded);
|
||||
}
|
||||
|
||||
size_t AudioEncoderPcmU::BytesPerSample() const {
|
||||
return 1;
|
||||
}
|
||||
|
||||
AudioEncoder::CodecType AudioEncoderPcmU::GetCodecType() const {
|
||||
return AudioEncoder::CodecType::kPcmU;
|
||||
}
|
||||
|
||||
} // namespace webrtc
|
||||
124
modules/audio_coding/codecs/g711/audio_encoder_pcm.h
Normal file
124
modules/audio_coding/codecs/g711/audio_encoder_pcm.h
Normal file
@ -0,0 +1,124 @@
|
||||
/*
|
||||
* Copyright (c) 2014 The WebRTC project authors. All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license
|
||||
* that can be found in the LICENSE file in the root of the source
|
||||
* tree. An additional intellectual property rights grant can be found
|
||||
* in the file PATENTS. All contributing project authors may
|
||||
* be found in the AUTHORS file in the root of the source tree.
|
||||
*/
|
||||
|
||||
#ifndef WEBRTC_MODULES_AUDIO_CODING_CODECS_G711_AUDIO_ENCODER_PCM_H_
|
||||
#define WEBRTC_MODULES_AUDIO_CODING_CODECS_G711_AUDIO_ENCODER_PCM_H_
|
||||
|
||||
#include <vector>
|
||||
|
||||
#include "webrtc/api/audio_codecs/audio_encoder.h"
|
||||
#include "webrtc/rtc_base/constructormagic.h"
|
||||
|
||||
namespace webrtc {
|
||||
|
||||
class AudioEncoderPcm : public AudioEncoder {
|
||||
public:
|
||||
struct Config {
|
||||
public:
|
||||
bool IsOk() const;
|
||||
|
||||
int frame_size_ms;
|
||||
size_t num_channels;
|
||||
int payload_type;
|
||||
|
||||
protected:
|
||||
explicit Config(int pt)
|
||||
: frame_size_ms(20), num_channels(1), payload_type(pt) {}
|
||||
};
|
||||
|
||||
~AudioEncoderPcm() override;
|
||||
|
||||
int SampleRateHz() const override;
|
||||
size_t NumChannels() const override;
|
||||
size_t Num10MsFramesInNextPacket() const override;
|
||||
size_t Max10MsFramesInAPacket() const override;
|
||||
int GetTargetBitrate() const override;
|
||||
void Reset() override;
|
||||
|
||||
protected:
|
||||
AudioEncoderPcm(const Config& config, int sample_rate_hz);
|
||||
|
||||
EncodedInfo EncodeImpl(uint32_t rtp_timestamp,
|
||||
rtc::ArrayView<const int16_t> audio,
|
||||
rtc::Buffer* encoded) override;
|
||||
|
||||
virtual size_t EncodeCall(const int16_t* audio,
|
||||
size_t input_len,
|
||||
uint8_t* encoded) = 0;
|
||||
|
||||
virtual size_t BytesPerSample() const = 0;
|
||||
|
||||
// Used to set EncodedInfoLeaf::encoder_type in
|
||||
// AudioEncoderPcm::EncodeImpl
|
||||
virtual AudioEncoder::CodecType GetCodecType() const = 0;
|
||||
|
||||
private:
|
||||
const int sample_rate_hz_;
|
||||
const size_t num_channels_;
|
||||
const int payload_type_;
|
||||
const size_t num_10ms_frames_per_packet_;
|
||||
const size_t full_frame_samples_;
|
||||
std::vector<int16_t> speech_buffer_;
|
||||
uint32_t first_timestamp_in_buffer_;
|
||||
};
|
||||
|
||||
struct CodecInst;
|
||||
|
||||
class AudioEncoderPcmA final : public AudioEncoderPcm {
|
||||
public:
|
||||
struct Config : public AudioEncoderPcm::Config {
|
||||
Config() : AudioEncoderPcm::Config(8) {}
|
||||
};
|
||||
|
||||
explicit AudioEncoderPcmA(const Config& config)
|
||||
: AudioEncoderPcm(config, kSampleRateHz) {}
|
||||
explicit AudioEncoderPcmA(const CodecInst& codec_inst);
|
||||
|
||||
protected:
|
||||
size_t EncodeCall(const int16_t* audio,
|
||||
size_t input_len,
|
||||
uint8_t* encoded) override;
|
||||
|
||||
size_t BytesPerSample() const override;
|
||||
|
||||
AudioEncoder::CodecType GetCodecType() const override;
|
||||
|
||||
private:
|
||||
static const int kSampleRateHz = 8000;
|
||||
RTC_DISALLOW_COPY_AND_ASSIGN(AudioEncoderPcmA);
|
||||
};
|
||||
|
||||
class AudioEncoderPcmU final : public AudioEncoderPcm {
|
||||
public:
|
||||
struct Config : public AudioEncoderPcm::Config {
|
||||
Config() : AudioEncoderPcm::Config(0) {}
|
||||
};
|
||||
|
||||
explicit AudioEncoderPcmU(const Config& config)
|
||||
: AudioEncoderPcm(config, kSampleRateHz) {}
|
||||
explicit AudioEncoderPcmU(const CodecInst& codec_inst);
|
||||
|
||||
protected:
|
||||
size_t EncodeCall(const int16_t* audio,
|
||||
size_t input_len,
|
||||
uint8_t* encoded) override;
|
||||
|
||||
size_t BytesPerSample() const override;
|
||||
|
||||
AudioEncoder::CodecType GetCodecType() const override;
|
||||
|
||||
private:
|
||||
static const int kSampleRateHz = 8000;
|
||||
RTC_DISALLOW_COPY_AND_ASSIGN(AudioEncoderPcmU);
|
||||
};
|
||||
|
||||
} // namespace webrtc
|
||||
|
||||
#endif // WEBRTC_MODULES_AUDIO_CODING_CODECS_G711_AUDIO_ENCODER_PCM_H_
|
||||
73
modules/audio_coding/codecs/g711/g711.c
Normal file
73
modules/audio_coding/codecs/g711/g711.c
Normal file
@ -0,0 +1,73 @@
|
||||
/*
|
||||
* SpanDSP - a series of DSP components for telephony
|
||||
*
|
||||
* g711.c - A-law and u-law transcoding routines
|
||||
*
|
||||
* Written by Steve Underwood <steveu@coppice.org>
|
||||
*
|
||||
* Copyright (C) 2006 Steve Underwood
|
||||
*
|
||||
* Despite my general liking of the GPL, I place 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.
|
||||
*
|
||||
* $Id: g711.c,v 1.1 2006/06/07 15:46:39 steveu Exp $
|
||||
*
|
||||
* Modifications for WebRtc, 2011/04/28, by tlegrand:
|
||||
* -Removed unused include files
|
||||
* -Changed to use WebRtc types
|
||||
* -Added option to run encoder bitexact with ITU-T reference implementation
|
||||
*/
|
||||
|
||||
#include "g711.h"
|
||||
#include "webrtc/typedefs.h"
|
||||
|
||||
/* Copied from the CCITT G.711 specification */
|
||||
static const uint8_t ulaw_to_alaw_table[256] = {
|
||||
42, 43, 40, 41, 46, 47, 44, 45, 34, 35, 32, 33, 38, 39, 36,
|
||||
37, 58, 59, 56, 57, 62, 63, 60, 61, 50, 51, 48, 49, 54, 55,
|
||||
52, 53, 10, 11, 8, 9, 14, 15, 12, 13, 2, 3, 0, 1, 6,
|
||||
7, 4, 26, 27, 24, 25, 30, 31, 28, 29, 18, 19, 16, 17, 22,
|
||||
23, 20, 21, 106, 104, 105, 110, 111, 108, 109, 98, 99, 96, 97, 102,
|
||||
103, 100, 101, 122, 120, 126, 127, 124, 125, 114, 115, 112, 113, 118, 119,
|
||||
116, 117, 75, 73, 79, 77, 66, 67, 64, 65, 70, 71, 68, 69, 90,
|
||||
91, 88, 89, 94, 95, 92, 93, 82, 82, 83, 83, 80, 80, 81, 81,
|
||||
86, 86, 87, 87, 84, 84, 85, 85, 170, 171, 168, 169, 174, 175, 172,
|
||||
173, 162, 163, 160, 161, 166, 167, 164, 165, 186, 187, 184, 185, 190, 191,
|
||||
188, 189, 178, 179, 176, 177, 182, 183, 180, 181, 138, 139, 136, 137, 142,
|
||||
143, 140, 141, 130, 131, 128, 129, 134, 135, 132, 154, 155, 152, 153, 158,
|
||||
159, 156, 157, 146, 147, 144, 145, 150, 151, 148, 149, 234, 232, 233, 238,
|
||||
239, 236, 237, 226, 227, 224, 225, 230, 231, 228, 229, 250, 248, 254, 255,
|
||||
252, 253, 242, 243, 240, 241, 246, 247, 244, 245, 203, 201, 207, 205, 194,
|
||||
195, 192, 193, 198, 199, 196, 197, 218, 219, 216, 217, 222, 223, 220, 221,
|
||||
210, 210, 211, 211, 208, 208, 209, 209, 214, 214, 215, 215, 212, 212, 213,
|
||||
213
|
||||
};
|
||||
|
||||
/* These transcoding tables are copied from the CCITT G.711 specification. To
|
||||
achieve optimal results, do not change them. */
|
||||
static const uint8_t alaw_to_ulaw_table[256] = {
|
||||
42, 43, 40, 41, 46, 47, 44, 45, 34, 35, 32, 33, 38, 39, 36,
|
||||
37, 57, 58, 55, 56, 61, 62, 59, 60, 49, 50, 47, 48, 53, 54,
|
||||
51, 52, 10, 11, 8, 9, 14, 15, 12, 13, 2, 3, 0, 1, 6,
|
||||
7, 4, 5, 26, 27, 24, 25, 30, 31, 28, 29, 18, 19, 16, 17,
|
||||
22, 23, 20, 21, 98, 99, 96, 97, 102, 103, 100, 101, 93, 93, 92,
|
||||
92, 95, 95, 94, 94, 116, 118, 112, 114, 124, 126, 120, 122, 106, 107,
|
||||
104, 105, 110, 111, 108, 109, 72, 73, 70, 71, 76, 77, 74, 75, 64,
|
||||
65, 63, 63, 68, 69, 66, 67, 86, 87, 84, 85, 90, 91, 88, 89,
|
||||
79, 79, 78, 78, 82, 83, 80, 81, 170, 171, 168, 169, 174, 175, 172,
|
||||
173, 162, 163, 160, 161, 166, 167, 164, 165, 185, 186, 183, 184, 189, 190,
|
||||
187, 188, 177, 178, 175, 176, 181, 182, 179, 180, 138, 139, 136, 137, 142,
|
||||
143, 140, 141, 130, 131, 128, 129, 134, 135, 132, 133, 154, 155, 152, 153,
|
||||
158, 159, 156, 157, 146, 147, 144, 145, 150, 151, 148, 149, 226, 227, 224,
|
||||
225, 230, 231, 228, 229, 221, 221, 220, 220, 223, 223, 222, 222, 244, 246,
|
||||
240, 242, 252, 254, 248, 250, 234, 235, 232, 233, 238, 239, 236, 237, 200,
|
||||
201, 198, 199, 204, 205, 202, 203, 192, 193, 191, 191, 196, 197, 194, 195,
|
||||
214, 215, 212, 213, 218, 219, 216, 217, 207, 207, 206, 206, 210, 211, 208,
|
||||
209
|
||||
};
|
||||
|
||||
uint8_t alaw_to_ulaw(uint8_t alaw) { return alaw_to_ulaw_table[alaw]; }
|
||||
|
||||
uint8_t ulaw_to_alaw(uint8_t ulaw) { return ulaw_to_alaw_table[ulaw]; }
|
||||
344
modules/audio_coding/codecs/g711/g711.h
Normal file
344
modules/audio_coding/codecs/g711/g711.h
Normal file
@ -0,0 +1,344 @@
|
||||
/*
|
||||
* SpanDSP - a series of DSP components for telephony
|
||||
*
|
||||
* g711.h - In line A-law and u-law conversion routines
|
||||
*
|
||||
* Written by Steve Underwood <steveu@coppice.org>
|
||||
*
|
||||
* Copyright (C) 2001 Steve Underwood
|
||||
*
|
||||
* Despite my general liking of the GPL, I place 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.
|
||||
*
|
||||
* $Id: g711.h,v 1.1 2006/06/07 15:46:39 steveu Exp $
|
||||
*
|
||||
* Modifications for WebRtc, 2011/04/28, by tlegrand:
|
||||
* -Changed to use WebRtc types
|
||||
* -Changed __inline__ to __inline
|
||||
* -Two changes to make implementation bitexact with ITU-T reference implementation
|
||||
*/
|
||||
|
||||
/*! \page g711_page A-law and mu-law handling
|
||||
Lookup tables for A-law and u-law look attractive, until you consider the impact
|
||||
on the CPU cache. If it causes a substantial area of your processor cache to get
|
||||
hit too often, cache sloshing will severely slow things down. The main reason
|
||||
these routines are slow in C, is the lack of direct access to the CPU's "find
|
||||
the first 1" instruction. A little in-line assembler fixes that, and the
|
||||
conversion routines can be faster than lookup tables, in most real world usage.
|
||||
A "find the first 1" instruction is available on most modern CPUs, and is a
|
||||
much underused feature.
|
||||
|
||||
If an assembly language method of bit searching is not available, these routines
|
||||
revert to a method that can be a little slow, so the cache thrashing might not
|
||||
seem so bad :(
|
||||
|
||||
Feel free to submit patches to add fast "find the first 1" support for your own
|
||||
favourite processor.
|
||||
|
||||
Look up tables are used for transcoding between A-law and u-law, since it is
|
||||
difficult to achieve the precise transcoding procedure laid down in the G.711
|
||||
specification by other means.
|
||||
*/
|
||||
|
||||
#if !defined(_G711_H_)
|
||||
#define _G711_H_
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include "webrtc/typedefs.h"
|
||||
|
||||
#if defined(__i386__)
|
||||
/*! \brief Find the bit position of the highest set bit in a word
|
||||
\param bits The word to be searched
|
||||
\return The bit number of the highest set bit, or -1 if the word is zero. */
|
||||
static __inline__ int top_bit(unsigned int bits) {
|
||||
int res;
|
||||
|
||||
__asm__ __volatile__(" movl $-1,%%edx;\n"
|
||||
" bsrl %%eax,%%edx;\n"
|
||||
: "=d" (res)
|
||||
: "a" (bits));
|
||||
return res;
|
||||
}
|
||||
|
||||
/*! \brief Find the bit position of the lowest set bit in a word
|
||||
\param bits The word to be searched
|
||||
\return The bit number of the lowest set bit, or -1 if the word is zero. */
|
||||
static __inline__ int bottom_bit(unsigned int bits) {
|
||||
int res;
|
||||
|
||||
__asm__ __volatile__(" movl $-1,%%edx;\n"
|
||||
" bsfl %%eax,%%edx;\n"
|
||||
: "=d" (res)
|
||||
: "a" (bits));
|
||||
return res;
|
||||
}
|
||||
#elif defined(__x86_64__)
|
||||
static __inline__ int top_bit(unsigned int bits) {
|
||||
int res;
|
||||
|
||||
__asm__ __volatile__(" movq $-1,%%rdx;\n"
|
||||
" bsrq %%rax,%%rdx;\n"
|
||||
: "=d" (res)
|
||||
: "a" (bits));
|
||||
return res;
|
||||
}
|
||||
|
||||
static __inline__ int bottom_bit(unsigned int bits) {
|
||||
int res;
|
||||
|
||||
__asm__ __volatile__(" movq $-1,%%rdx;\n"
|
||||
" bsfq %%rax,%%rdx;\n"
|
||||
: "=d" (res)
|
||||
: "a" (bits));
|
||||
return res;
|
||||
}
|
||||
#else
|
||||
static __inline int top_bit(unsigned int bits) {
|
||||
int i;
|
||||
|
||||
if (bits == 0) {
|
||||
return -1;
|
||||
}
|
||||
i = 0;
|
||||
if (bits & 0xFFFF0000) {
|
||||
bits &= 0xFFFF0000;
|
||||
i += 16;
|
||||
}
|
||||
if (bits & 0xFF00FF00) {
|
||||
bits &= 0xFF00FF00;
|
||||
i += 8;
|
||||
}
|
||||
if (bits & 0xF0F0F0F0) {
|
||||
bits &= 0xF0F0F0F0;
|
||||
i += 4;
|
||||
}
|
||||
if (bits & 0xCCCCCCCC) {
|
||||
bits &= 0xCCCCCCCC;
|
||||
i += 2;
|
||||
}
|
||||
if (bits & 0xAAAAAAAA) {
|
||||
bits &= 0xAAAAAAAA;
|
||||
i += 1;
|
||||
}
|
||||
return i;
|
||||
}
|
||||
|
||||
static __inline int bottom_bit(unsigned int bits) {
|
||||
int i;
|
||||
|
||||
if (bits == 0) {
|
||||
return -1;
|
||||
}
|
||||
i = 32;
|
||||
if (bits & 0x0000FFFF) {
|
||||
bits &= 0x0000FFFF;
|
||||
i -= 16;
|
||||
}
|
||||
if (bits & 0x00FF00FF) {
|
||||
bits &= 0x00FF00FF;
|
||||
i -= 8;
|
||||
}
|
||||
if (bits & 0x0F0F0F0F) {
|
||||
bits &= 0x0F0F0F0F;
|
||||
i -= 4;
|
||||
}
|
||||
if (bits & 0x33333333) {
|
||||
bits &= 0x33333333;
|
||||
i -= 2;
|
||||
}
|
||||
if (bits & 0x55555555) {
|
||||
bits &= 0x55555555;
|
||||
i -= 1;
|
||||
}
|
||||
return i;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* N.B. It is tempting to use look-up tables for A-law and u-law conversion.
|
||||
* However, you should consider the cache footprint.
|
||||
*
|
||||
* A 64K byte table for linear to x-law and a 512 byte table for x-law to
|
||||
* linear sound like peanuts these days, and shouldn't an array lookup be
|
||||
* real fast? No! When the cache sloshes as badly as this one will, a tight
|
||||
* calculation may be better. The messiest part is normally finding the
|
||||
* segment, but a little inline assembly can fix that on an i386, x86_64 and
|
||||
* many other modern processors.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Mu-law is basically as follows:
|
||||
*
|
||||
* Biased Linear Input Code Compressed Code
|
||||
* ------------------------ ---------------
|
||||
* 00000001wxyza 000wxyz
|
||||
* 0000001wxyzab 001wxyz
|
||||
* 000001wxyzabc 010wxyz
|
||||
* 00001wxyzabcd 011wxyz
|
||||
* 0001wxyzabcde 100wxyz
|
||||
* 001wxyzabcdef 101wxyz
|
||||
* 01wxyzabcdefg 110wxyz
|
||||
* 1wxyzabcdefgh 111wxyz
|
||||
*
|
||||
* Each biased linear code has a leading 1 which identifies the segment
|
||||
* number. The value of the segment number is equal to 7 minus the number
|
||||
* of leading 0's. The quantization interval is directly available as the
|
||||
* four bits wxyz. * The trailing bits (a - h) are ignored.
|
||||
*
|
||||
* Ordinarily the complement of the resulting code word is used for
|
||||
* transmission, and so the code word is complemented before it is returned.
|
||||
*
|
||||
* For further information see John C. Bellamy's Digital Telephony, 1982,
|
||||
* John Wiley & Sons, pps 98-111 and 472-476.
|
||||
*/
|
||||
|
||||
//#define ULAW_ZEROTRAP /* turn on the trap as per the MIL-STD */
|
||||
#define ULAW_BIAS 0x84 /* Bias for linear code. */
|
||||
|
||||
/*! \brief Encode a linear sample to u-law
|
||||
\param linear The sample to encode.
|
||||
\return The u-law value.
|
||||
*/
|
||||
static __inline uint8_t linear_to_ulaw(int linear) {
|
||||
uint8_t u_val;
|
||||
int mask;
|
||||
int seg;
|
||||
|
||||
/* Get the sign and the magnitude of the value. */
|
||||
if (linear < 0) {
|
||||
/* WebRtc, tlegrand: -1 added to get bitexact to reference implementation */
|
||||
linear = ULAW_BIAS - linear - 1;
|
||||
mask = 0x7F;
|
||||
} else {
|
||||
linear = ULAW_BIAS + linear;
|
||||
mask = 0xFF;
|
||||
}
|
||||
|
||||
seg = top_bit(linear | 0xFF) - 7;
|
||||
|
||||
/*
|
||||
* Combine the sign, segment, quantization bits,
|
||||
* and complement the code word.
|
||||
*/
|
||||
if (seg >= 8)
|
||||
u_val = (uint8_t)(0x7F ^ mask);
|
||||
else
|
||||
u_val = (uint8_t)(((seg << 4) | ((linear >> (seg + 3)) & 0xF)) ^ mask);
|
||||
#ifdef ULAW_ZEROTRAP
|
||||
/* Optional ITU trap */
|
||||
if (u_val == 0)
|
||||
u_val = 0x02;
|
||||
#endif
|
||||
return u_val;
|
||||
}
|
||||
|
||||
/*! \brief Decode an u-law sample to a linear value.
|
||||
\param ulaw The u-law sample to decode.
|
||||
\return The linear value.
|
||||
*/
|
||||
static __inline int16_t ulaw_to_linear(uint8_t ulaw) {
|
||||
int t;
|
||||
|
||||
/* Complement to obtain normal u-law value. */
|
||||
ulaw = ~ulaw;
|
||||
/*
|
||||
* Extract and bias the quantization bits. Then
|
||||
* shift up by the segment number and subtract out the bias.
|
||||
*/
|
||||
t = (((ulaw & 0x0F) << 3) + ULAW_BIAS) << (((int) ulaw & 0x70) >> 4);
|
||||
return (int16_t)((ulaw & 0x80) ? (ULAW_BIAS - t) : (t - ULAW_BIAS));
|
||||
}
|
||||
|
||||
/*
|
||||
* A-law is basically as follows:
|
||||
*
|
||||
* Linear Input Code Compressed Code
|
||||
* ----------------- ---------------
|
||||
* 0000000wxyza 000wxyz
|
||||
* 0000001wxyza 001wxyz
|
||||
* 000001wxyzab 010wxyz
|
||||
* 00001wxyzabc 011wxyz
|
||||
* 0001wxyzabcd 100wxyz
|
||||
* 001wxyzabcde 101wxyz
|
||||
* 01wxyzabcdef 110wxyz
|
||||
* 1wxyzabcdefg 111wxyz
|
||||
*
|
||||
* For further information see John C. Bellamy's Digital Telephony, 1982,
|
||||
* John Wiley & Sons, pps 98-111 and 472-476.
|
||||
*/
|
||||
|
||||
#define ALAW_AMI_MASK 0x55
|
||||
|
||||
/*! \brief Encode a linear sample to A-law
|
||||
\param linear The sample to encode.
|
||||
\return The A-law value.
|
||||
*/
|
||||
static __inline uint8_t linear_to_alaw(int linear) {
|
||||
int mask;
|
||||
int seg;
|
||||
|
||||
if (linear >= 0) {
|
||||
/* Sign (bit 7) bit = 1 */
|
||||
mask = ALAW_AMI_MASK | 0x80;
|
||||
} else {
|
||||
/* Sign (bit 7) bit = 0 */
|
||||
mask = ALAW_AMI_MASK;
|
||||
/* WebRtc, tlegrand: Changed from -8 to -1 to get bitexact to reference
|
||||
* implementation */
|
||||
linear = -linear - 1;
|
||||
}
|
||||
|
||||
/* Convert the scaled magnitude to segment number. */
|
||||
seg = top_bit(linear | 0xFF) - 7;
|
||||
if (seg >= 8) {
|
||||
if (linear >= 0) {
|
||||
/* Out of range. Return maximum value. */
|
||||
return (uint8_t)(0x7F ^ mask);
|
||||
}
|
||||
/* We must be just a tiny step below zero */
|
||||
return (uint8_t)(0x00 ^ mask);
|
||||
}
|
||||
/* Combine the sign, segment, and quantization bits. */
|
||||
return (uint8_t)(((seg << 4) | ((linear >> ((seg) ? (seg + 3) : 4)) & 0x0F)) ^
|
||||
mask);
|
||||
}
|
||||
|
||||
/*! \brief Decode an A-law sample to a linear value.
|
||||
\param alaw The A-law sample to decode.
|
||||
\return The linear value.
|
||||
*/
|
||||
static __inline int16_t alaw_to_linear(uint8_t alaw) {
|
||||
int i;
|
||||
int seg;
|
||||
|
||||
alaw ^= ALAW_AMI_MASK;
|
||||
i = ((alaw & 0x0F) << 4);
|
||||
seg = (((int) alaw & 0x70) >> 4);
|
||||
if (seg)
|
||||
i = (i + 0x108) << (seg - 1);
|
||||
else
|
||||
i += 8;
|
||||
return (int16_t)((alaw & 0x80) ? i : -i);
|
||||
}
|
||||
|
||||
/*! \brief Transcode from A-law to u-law, using the procedure defined in G.711.
|
||||
\param alaw The A-law sample to transcode.
|
||||
\return The best matching u-law value.
|
||||
*/
|
||||
uint8_t alaw_to_ulaw(uint8_t alaw);
|
||||
|
||||
/*! \brief Transcode from u-law to A-law, using the procedure defined in G.711.
|
||||
\param alaw The u-law sample to transcode.
|
||||
\return The best matching A-law value.
|
||||
*/
|
||||
uint8_t ulaw_to_alaw(uint8_t ulaw);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
58
modules/audio_coding/codecs/g711/g711_interface.c
Normal file
58
modules/audio_coding/codecs/g711/g711_interface.c
Normal file
@ -0,0 +1,58 @@
|
||||
/*
|
||||
* Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license
|
||||
* that can be found in the LICENSE file in the root of the source
|
||||
* tree. An additional intellectual property rights grant can be found
|
||||
* in the file PATENTS. All contributing project authors may
|
||||
* be found in the AUTHORS file in the root of the source tree.
|
||||
*/
|
||||
#include <string.h>
|
||||
#include "g711.h"
|
||||
#include "g711_interface.h"
|
||||
#include "webrtc/typedefs.h"
|
||||
|
||||
size_t WebRtcG711_EncodeA(const int16_t* speechIn,
|
||||
size_t len,
|
||||
uint8_t* encoded) {
|
||||
size_t n;
|
||||
for (n = 0; n < len; n++)
|
||||
encoded[n] = linear_to_alaw(speechIn[n]);
|
||||
return len;
|
||||
}
|
||||
|
||||
size_t WebRtcG711_EncodeU(const int16_t* speechIn,
|
||||
size_t len,
|
||||
uint8_t* encoded) {
|
||||
size_t n;
|
||||
for (n = 0; n < len; n++)
|
||||
encoded[n] = linear_to_ulaw(speechIn[n]);
|
||||
return len;
|
||||
}
|
||||
|
||||
size_t WebRtcG711_DecodeA(const uint8_t* encoded,
|
||||
size_t len,
|
||||
int16_t* decoded,
|
||||
int16_t* speechType) {
|
||||
size_t n;
|
||||
for (n = 0; n < len; n++)
|
||||
decoded[n] = alaw_to_linear(encoded[n]);
|
||||
*speechType = 1;
|
||||
return len;
|
||||
}
|
||||
|
||||
size_t WebRtcG711_DecodeU(const uint8_t* encoded,
|
||||
size_t len,
|
||||
int16_t* decoded,
|
||||
int16_t* speechType) {
|
||||
size_t n;
|
||||
for (n = 0; n < len; n++)
|
||||
decoded[n] = ulaw_to_linear(encoded[n]);
|
||||
*speechType = 1;
|
||||
return len;
|
||||
}
|
||||
|
||||
int16_t WebRtcG711_Version(char* version, int16_t lenBytes) {
|
||||
strncpy(version, "2.0.0", lenBytes);
|
||||
return 0;
|
||||
}
|
||||
135
modules/audio_coding/codecs/g711/g711_interface.h
Normal file
135
modules/audio_coding/codecs/g711/g711_interface.h
Normal file
@ -0,0 +1,135 @@
|
||||
/*
|
||||
* Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license
|
||||
* that can be found in the LICENSE file in the root of the source
|
||||
* tree. An additional intellectual property rights grant can be found
|
||||
* in the file PATENTS. All contributing project authors may
|
||||
* be found in the AUTHORS file in the root of the source tree.
|
||||
*/
|
||||
|
||||
#ifndef WEBRTC_MODULES_AUDIO_CODING_CODECS_G711_G711_INTERFACE_H_
|
||||
#define WEBRTC_MODULES_AUDIO_CODING_CODECS_G711_G711_INTERFACE_H_
|
||||
|
||||
#include "webrtc/typedefs.h"
|
||||
|
||||
// Comfort noise constants
|
||||
#define G711_WEBRTC_SPEECH 1
|
||||
#define G711_WEBRTC_CNG 2
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* WebRtcG711_EncodeA(...)
|
||||
*
|
||||
* This function encodes a G711 A-law frame and inserts it into a packet.
|
||||
* Input speech length has be of any length.
|
||||
*
|
||||
* Input:
|
||||
* - speechIn : Input speech vector
|
||||
* - len : Samples in speechIn
|
||||
*
|
||||
* Output:
|
||||
* - encoded : The encoded data vector
|
||||
*
|
||||
* Return value : Length (in bytes) of coded data.
|
||||
* Always equal to len input parameter.
|
||||
*/
|
||||
|
||||
size_t WebRtcG711_EncodeA(const int16_t* speechIn,
|
||||
size_t len,
|
||||
uint8_t* encoded);
|
||||
|
||||
/****************************************************************************
|
||||
* WebRtcG711_EncodeU(...)
|
||||
*
|
||||
* This function encodes a G711 U-law frame and inserts it into a packet.
|
||||
* Input speech length has be of any length.
|
||||
*
|
||||
* Input:
|
||||
* - speechIn : Input speech vector
|
||||
* - len : Samples in speechIn
|
||||
*
|
||||
* Output:
|
||||
* - encoded : The encoded data vector
|
||||
*
|
||||
* Return value : Length (in bytes) of coded data.
|
||||
* Always equal to len input parameter.
|
||||
*/
|
||||
|
||||
size_t WebRtcG711_EncodeU(const int16_t* speechIn,
|
||||
size_t len,
|
||||
uint8_t* encoded);
|
||||
|
||||
/****************************************************************************
|
||||
* WebRtcG711_DecodeA(...)
|
||||
*
|
||||
* This function decodes a packet G711 A-law frame.
|
||||
*
|
||||
* Input:
|
||||
* - encoded : Encoded data
|
||||
* - len : Bytes in encoded vector
|
||||
*
|
||||
* Output:
|
||||
* - decoded : The decoded vector
|
||||
* - speechType : 1 normal, 2 CNG (for G711 it should
|
||||
* always return 1 since G711 does not have a
|
||||
* built-in DTX/CNG scheme)
|
||||
*
|
||||
* Return value : >0 - Samples in decoded vector
|
||||
* -1 - Error
|
||||
*/
|
||||
|
||||
size_t WebRtcG711_DecodeA(const uint8_t* encoded,
|
||||
size_t len,
|
||||
int16_t* decoded,
|
||||
int16_t* speechType);
|
||||
|
||||
/****************************************************************************
|
||||
* WebRtcG711_DecodeU(...)
|
||||
*
|
||||
* This function decodes a packet G711 U-law frame.
|
||||
*
|
||||
* Input:
|
||||
* - encoded : Encoded data
|
||||
* - len : Bytes in encoded vector
|
||||
*
|
||||
* Output:
|
||||
* - decoded : The decoded vector
|
||||
* - speechType : 1 normal, 2 CNG (for G711 it should
|
||||
* always return 1 since G711 does not have a
|
||||
* built-in DTX/CNG scheme)
|
||||
*
|
||||
* Return value : >0 - Samples in decoded vector
|
||||
* -1 - Error
|
||||
*/
|
||||
|
||||
size_t WebRtcG711_DecodeU(const uint8_t* encoded,
|
||||
size_t len,
|
||||
int16_t* decoded,
|
||||
int16_t* speechType);
|
||||
|
||||
/**********************************************************************
|
||||
* WebRtcG711_Version(...)
|
||||
*
|
||||
* This function gives the version string of the G.711 codec.
|
||||
*
|
||||
* Input:
|
||||
* - lenBytes: the size of Allocated space (in Bytes) where
|
||||
* the version number is written to (in string format).
|
||||
*
|
||||
* Output:
|
||||
* - version: Pointer to a buffer where the version number is
|
||||
* written to.
|
||||
*
|
||||
*/
|
||||
|
||||
int16_t WebRtcG711_Version(char* version, int16_t lenBytes);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // WEBRTC_MODULES_AUDIO_CODING_CODECS_G711_G711_INTERFACE_H_
|
||||
170
modules/audio_coding/codecs/g711/test/testG711.cc
Normal file
170
modules/audio_coding/codecs/g711/test/testG711.cc
Normal file
@ -0,0 +1,170 @@
|
||||
/*
|
||||
* Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license
|
||||
* that can be found in the LICENSE file in the root of the source
|
||||
* tree. An additional intellectual property rights grant can be found
|
||||
* in the file PATENTS. All contributing project authors may
|
||||
* be found in the AUTHORS file in the root of the source tree.
|
||||
*/
|
||||
|
||||
/*
|
||||
* testG711.cpp : Defines the entry point for the console application.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
/* include API */
|
||||
#include "webrtc/modules/audio_coding/codecs/g711/g711_interface.h"
|
||||
|
||||
/* Runtime statistics */
|
||||
#include <time.h>
|
||||
#define CLOCKS_PER_SEC_G711 1000
|
||||
|
||||
/* function for reading audio data from PCM file */
|
||||
bool readframe(int16_t* data, FILE* inp, size_t length) {
|
||||
size_t rlen = fread(data, sizeof(int16_t), length, inp);
|
||||
if (rlen >= length)
|
||||
return false;
|
||||
memset(data + rlen, 0, (length - rlen) * sizeof(int16_t));
|
||||
return true;
|
||||
}
|
||||
|
||||
int main(int argc, char* argv[]) {
|
||||
char inname[80], outname[40], bitname[40];
|
||||
FILE* inp;
|
||||
FILE* outp;
|
||||
FILE* bitp = NULL;
|
||||
int framecnt;
|
||||
bool endfile;
|
||||
|
||||
size_t framelength = 80;
|
||||
|
||||
/* Runtime statistics */
|
||||
double starttime;
|
||||
double runtime;
|
||||
double length_file;
|
||||
|
||||
size_t stream_len = 0;
|
||||
int16_t shortdata[480];
|
||||
int16_t decoded[480];
|
||||
uint8_t streamdata[1000];
|
||||
int16_t speechType[1];
|
||||
char law[2];
|
||||
char versionNumber[40];
|
||||
|
||||
/* handling wrong input arguments in the command line */
|
||||
if ((argc != 5) && (argc != 6)) {
|
||||
printf("\n\nWrong number of arguments or flag values.\n\n");
|
||||
|
||||
printf("\n");
|
||||
printf("\nG.711 test application\n\n");
|
||||
printf("Usage:\n\n");
|
||||
printf("./testG711.exe framelength law infile outfile \n\n");
|
||||
printf("framelength: Framelength in samples.\n");
|
||||
printf("law : Coding law, A och u.\n");
|
||||
printf("infile : Normal speech input file\n");
|
||||
printf("outfile : Speech output file\n\n");
|
||||
printf("outbits : Output bitstream file [optional]\n\n");
|
||||
exit(0);
|
||||
|
||||
}
|
||||
|
||||
/* Get version and print */
|
||||
WebRtcG711_Version(versionNumber, 40);
|
||||
|
||||
printf("-----------------------------------\n");
|
||||
printf("G.711 version: %s\n\n", versionNumber);
|
||||
/* Get frame length */
|
||||
int framelength_int = atoi(argv[1]);
|
||||
if (framelength_int < 0) {
|
||||
printf(" G.722: Invalid framelength %d.\n", framelength_int);
|
||||
exit(1);
|
||||
}
|
||||
framelength = static_cast<size_t>(framelength_int);
|
||||
|
||||
/* Get compression law */
|
||||
strcpy(law, argv[2]);
|
||||
|
||||
/* Get Input and Output files */
|
||||
sscanf(argv[3], "%s", inname);
|
||||
sscanf(argv[4], "%s", outname);
|
||||
if (argc == 6) {
|
||||
sscanf(argv[5], "%s", bitname);
|
||||
if ((bitp = fopen(bitname, "wb")) == NULL) {
|
||||
printf(" G.711: Cannot read file %s.\n", bitname);
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
if ((inp = fopen(inname, "rb")) == NULL) {
|
||||
printf(" G.711: Cannot read file %s.\n", inname);
|
||||
exit(1);
|
||||
}
|
||||
if ((outp = fopen(outname, "wb")) == NULL) {
|
||||
printf(" G.711: Cannot write file %s.\n", outname);
|
||||
exit(1);
|
||||
}
|
||||
printf("\nInput: %s\nOutput: %s\n", inname, outname);
|
||||
if (argc == 6) {
|
||||
printf("\nBitfile: %s\n", bitname);
|
||||
}
|
||||
|
||||
starttime = clock() / (double) CLOCKS_PER_SEC_G711; /* Runtime statistics */
|
||||
|
||||
/* Initialize encoder and decoder */
|
||||
framecnt = 0;
|
||||
endfile = false;
|
||||
while (!endfile) {
|
||||
framecnt++;
|
||||
/* Read speech block */
|
||||
endfile = readframe(shortdata, inp, framelength);
|
||||
|
||||
/* G.711 encoding */
|
||||
if (!strcmp(law, "A")) {
|
||||
/* A-law encoding */
|
||||
stream_len = WebRtcG711_EncodeA(shortdata, framelength, streamdata);
|
||||
if (argc == 6) {
|
||||
/* Write bits to file */
|
||||
if (fwrite(streamdata, sizeof(unsigned char), stream_len, bitp) !=
|
||||
stream_len) {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
WebRtcG711_DecodeA(streamdata, stream_len, decoded, speechType);
|
||||
} else if (!strcmp(law, "u")) {
|
||||
/* u-law encoding */
|
||||
stream_len = WebRtcG711_EncodeU(shortdata, framelength, streamdata);
|
||||
if (argc == 6) {
|
||||
/* Write bits to file */
|
||||
if (fwrite(streamdata, sizeof(unsigned char), stream_len, bitp) !=
|
||||
stream_len) {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
WebRtcG711_DecodeU(streamdata, stream_len, decoded, speechType);
|
||||
} else {
|
||||
printf("Wrong law mode\n");
|
||||
exit(1);
|
||||
}
|
||||
/* Write coded speech to file */
|
||||
if (fwrite(decoded, sizeof(short), framelength, outp) != framelength) {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
runtime = (double)(clock() / (double) CLOCKS_PER_SEC_G711 - starttime);
|
||||
length_file = ((double) framecnt * (double) framelength / 8000);
|
||||
printf("\n\nLength of speech file: %.1f s\n", length_file);
|
||||
printf("Time to run G.711: %.2f s (%.2f %% of realtime)\n\n",
|
||||
runtime,
|
||||
(100 * runtime / length_file));
|
||||
printf("---------------------END----------------------\n");
|
||||
|
||||
fclose(inp);
|
||||
fclose(outp);
|
||||
|
||||
return 0;
|
||||
}
|
||||
Reference in New Issue
Block a user