Repo created
This commit is contained in:
parent
81b91f4139
commit
f8c34fa5ee
22732 changed files with 4815320 additions and 2 deletions
|
|
@ -0,0 +1,112 @@
|
|||
/*
|
||||
* 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 "modules/audio_coding/codecs/g711/audio_decoder_pcm.h"
|
||||
|
||||
#include <utility>
|
||||
|
||||
#include "modules/audio_coding/codecs/g711/g711_interface.h"
|
||||
#include "modules/audio_coding/codecs/legacy_encoded_audio_frame.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);
|
||||
// Adjust the encoded length down to ensure the same number of samples in each
|
||||
// channel.
|
||||
const size_t encoded_len_adjusted =
|
||||
PacketDuration(encoded, encoded_len) *
|
||||
Channels(); // 1 byte per sample per channel
|
||||
int16_t temp_type = 1; // Default is speech.
|
||||
size_t ret =
|
||||
WebRtcG711_DecodeU(encoded, encoded_len_adjusted, 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());
|
||||
}
|
||||
|
||||
int AudioDecoderPcmU::PacketDurationRedundant(const uint8_t* encoded,
|
||||
size_t encoded_len) const {
|
||||
return PacketDuration(encoded, encoded_len);
|
||||
}
|
||||
|
||||
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);
|
||||
// Adjust the encoded length down to ensure the same number of samples in each
|
||||
// channel.
|
||||
const size_t encoded_len_adjusted =
|
||||
PacketDuration(encoded, encoded_len) *
|
||||
Channels(); // 1 byte per sample per channel
|
||||
int16_t temp_type = 1; // Default is speech.
|
||||
size_t ret =
|
||||
WebRtcG711_DecodeA(encoded, encoded_len_adjusted, 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());
|
||||
}
|
||||
|
||||
int AudioDecoderPcmA::PacketDurationRedundant(const uint8_t* encoded,
|
||||
size_t encoded_len) const {
|
||||
return PacketDuration(encoded, encoded_len);
|
||||
}
|
||||
|
||||
} // namespace webrtc
|
||||
|
|
@ -0,0 +1,85 @@
|
|||
/*
|
||||
* 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 MODULES_AUDIO_CODING_CODECS_G711_AUDIO_DECODER_PCM_H_
|
||||
#define MODULES_AUDIO_CODING_CODECS_G711_AUDIO_DECODER_PCM_H_
|
||||
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#include <vector>
|
||||
|
||||
#include "api/audio_codecs/audio_decoder.h"
|
||||
#include "rtc_base/buffer.h"
|
||||
#include "rtc_base/checks.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);
|
||||
}
|
||||
|
||||
AudioDecoderPcmU(const AudioDecoderPcmU&) = delete;
|
||||
AudioDecoderPcmU& operator=(const AudioDecoderPcmU&) = delete;
|
||||
|
||||
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 PacketDurationRedundant(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_;
|
||||
};
|
||||
|
||||
class AudioDecoderPcmA final : public AudioDecoder {
|
||||
public:
|
||||
explicit AudioDecoderPcmA(size_t num_channels) : num_channels_(num_channels) {
|
||||
RTC_DCHECK_GE(num_channels, 1);
|
||||
}
|
||||
|
||||
AudioDecoderPcmA(const AudioDecoderPcmA&) = delete;
|
||||
AudioDecoderPcmA& operator=(const AudioDecoderPcmA&) = delete;
|
||||
|
||||
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 PacketDurationRedundant(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_;
|
||||
};
|
||||
|
||||
} // namespace webrtc
|
||||
|
||||
#endif // MODULES_AUDIO_CODING_CODECS_G711_AUDIO_DECODER_PCM_H_
|
||||
|
|
@ -0,0 +1,126 @@
|
|||
/*
|
||||
* 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 "modules/audio_coding/codecs/g711/audio_encoder_pcm.h"
|
||||
|
||||
#include <cstdint>
|
||||
|
||||
#include "modules/audio_coding/codecs/g711/g711_interface.h"
|
||||
#include "rtc_base/checks.h"
|
||||
|
||||
namespace webrtc {
|
||||
|
||||
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();
|
||||
}
|
||||
|
||||
absl::optional<std::pair<TimeDelta, TimeDelta>>
|
||||
AudioEncoderPcm::GetFrameLengthRange() const {
|
||||
return {{TimeDelta::Millis(num_10ms_frames_per_packet_ * 10),
|
||||
TimeDelta::Millis(num_10ms_frames_per_packet_ * 10)}};
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
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
|
||||
|
|
@ -0,0 +1,128 @@
|
|||
/*
|
||||
* 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 MODULES_AUDIO_CODING_CODECS_G711_AUDIO_ENCODER_PCM_H_
|
||||
#define MODULES_AUDIO_CODING_CODECS_G711_AUDIO_ENCODER_PCM_H_
|
||||
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
#include "absl/types/optional.h"
|
||||
#include "api/audio_codecs/audio_encoder.h"
|
||||
#include "api/units/time_delta.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;
|
||||
absl::optional<std::pair<TimeDelta, TimeDelta>> GetFrameLengthRange()
|
||||
const 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_;
|
||||
};
|
||||
|
||||
class AudioEncoderPcmA final : public AudioEncoderPcm {
|
||||
public:
|
||||
struct Config : public AudioEncoderPcm::Config {
|
||||
Config() : AudioEncoderPcm::Config(8) {}
|
||||
};
|
||||
|
||||
explicit AudioEncoderPcmA(const Config& config)
|
||||
: AudioEncoderPcm(config, kSampleRateHz) {}
|
||||
|
||||
AudioEncoderPcmA(const AudioEncoderPcmA&) = delete;
|
||||
AudioEncoderPcmA& operator=(const AudioEncoderPcmA&) = delete;
|
||||
|
||||
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;
|
||||
};
|
||||
|
||||
class AudioEncoderPcmU final : public AudioEncoderPcm {
|
||||
public:
|
||||
struct Config : public AudioEncoderPcm::Config {
|
||||
Config() : AudioEncoderPcm::Config(0) {}
|
||||
};
|
||||
|
||||
explicit AudioEncoderPcmU(const Config& config)
|
||||
: AudioEncoderPcm(config, kSampleRateHz) {}
|
||||
|
||||
AudioEncoderPcmU(const AudioEncoderPcmU&) = delete;
|
||||
AudioEncoderPcmU& operator=(const AudioEncoderPcmU&) = delete;
|
||||
|
||||
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;
|
||||
};
|
||||
|
||||
} // namespace webrtc
|
||||
|
||||
#endif // MODULES_AUDIO_CODING_CODECS_G711_AUDIO_ENCODER_PCM_H_
|
||||
|
|
@ -0,0 +1,59 @@
|
|||
/*
|
||||
* 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 "modules/third_party/g711/g711.h"
|
||||
#include "modules/audio_coding/codecs/g711/g711_interface.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;
|
||||
}
|
||||
|
|
@ -0,0 +1,136 @@
|
|||
/*
|
||||
* 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 MODULES_AUDIO_CODING_CODECS_G711_G711_INTERFACE_H_
|
||||
#define MODULES_AUDIO_CODING_CODECS_G711_G711_INTERFACE_H_
|
||||
|
||||
#include <stddef.h>
|
||||
#include <stdint.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 // MODULES_AUDIO_CODING_CODECS_G711_G711_INTERFACE_H_
|
||||
|
|
@ -0,0 +1,168 @@
|
|||
/*
|
||||
* 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 "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;
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue