Adding separate payload types for stereo modes

BUG=Issue 452
TEST=audio_coding_test, voe_auto_test, voe_cmd_test

Edit: adding Patrik to review:
src/modules/rtp_rtcp/source/rtp_receiver.cc
...and Shijing to review:
src/voice_engine/main/source/channel.cc
src/voice_engine/main/test/cmd_test/voe_cmd_test.cc

Review URL: https://webrtc-codereview.appspot.com/540004

git-svn-id: http://webrtc.googlecode.com/svn/trunk@2340 4adac7df-926f-26a2-2b94-8c16560cd09d
This commit is contained in:
tina.legrand@webrtc.org 2012-06-01 09:27:35 +00:00
parent c2722a0e68
commit 4517585db5
23 changed files with 670 additions and 789 deletions

View File

@ -108,42 +108,44 @@ class AudioCodingModule: public Module {
/////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////
// WebRtc_Word32 Codec() // WebRtc_Word32 Codec()
// Get supported codec with the given codec name and sampling frequency. // Get supported codec with the given codec name, sampling frequency, and
// If the sampling frequency is -1 then the search will be only based on // a given number of channels.
// codec name.
// //
// Input: // Input:
// -payloadName : name of the codec. // -payload_name : name of the codec.
// -samplingFreqHz : samling frequency of the codec. // -sampling_freq_hz : sampling frequency of the codec. Note! for RED
// a sampling frequency of -1 is a valid input.
// -channels : number of channels ( 1 - mono, 2 - stereo).
// //
// Output: // Output:
// -codec : a structure where the parameters of the codec, // -codec : a structure where the function returns the
// given by name is written to. // default parameters of the codec.
// //
// Return value: // Return value:
// -1 if the list number (listId) is invalid. // -1 if the list number (listId) is invalid.
// 0 if succeeded. // 0 if succeeded.
// //
static WebRtc_Word32 Codec(const char* payloadName, CodecInst& codec, static WebRtc_Word32 Codec(const char* payload_name, CodecInst& codec,
const WebRtc_Word32 samplingFreqHz = -1); int sampling_freq_hz, int channels);
/////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////
// WebRtc_Word32 Codec() // WebRtc_Word32 Codec()
// //
// Returns the list number of the given codec name and sampling frequency. // Returns the list number of the given codec name, sampling frequency, and
// If the sampling frequency is -1 then the search will be only based on // a given number of channels.
// codec name.
// //
// Input: // Input:
// -payloadName : name of the codec. // -payload_name : name of the codec.
// -samplingFreqHz : samling frequency of the codec. // -sampling_freq_hz : sampling frequency of the codec. Note! for RED
// a sampling frequency of -1 is a valid input.
// -channels : number of channels ( 1 - mono, 2 - stereo).
// //
// Return value: // Return value:
// if the codec is found, the index of the codec in the list, // if the codec is found, the index of the codec in the list,
// -1 if the codec is not found. // -1 if the codec is not found.
// //
static WebRtc_Word32 Codec(const char* payloadName, static WebRtc_Word32 Codec(const char* payload_name, int sampling_freq_hz,
const WebRtc_Word32 samplingFreqHz = -1); int channels);
/////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////
// bool IsCodecValid() // bool IsCodecValid()

View File

@ -223,14 +223,20 @@ int32_t ACMCELT::CodecDef(WebRtcNetEQ_CodecDef& codecDef,
// "SET_CODEC_PAR" and "SET_CELT_FUNCTIONS" or "SET_CELTSLAVE_FUNCTIONS". // "SET_CODEC_PAR" and "SET_CELT_FUNCTIONS" or "SET_CELTSLAVE_FUNCTIONS".
// Then call NetEQ to add the codec to it's // Then call NetEQ to add the codec to it's
// database. // database.
SET_CODEC_PAR((codecDef), kDecoderCELT_32, codecInst.pltype, dec_inst_ptr_, if (codecInst.channels == 1) {
32000); SET_CODEC_PAR(codecDef, kDecoderCELT_32, codecInst.pltype, dec_inst_ptr_,
32000);
} else {
SET_CODEC_PAR(codecDef, kDecoderCELT_32_2ch, codecInst.pltype,
dec_inst_ptr_, 32000);
}
// If this is the master of NetEQ, regular decoder will be added, otherwise // If this is the master of NetEQ, regular decoder will be added, otherwise
// the slave decoder will be used. // the slave decoder will be used.
if (_isMaster) { if (_isMaster) {
SET_CELT_FUNCTIONS((codecDef)); SET_CELT_FUNCTIONS(codecDef);
} else { } else {
SET_CELTSLAVE_FUNCTIONS((codecDef)); SET_CELTSLAVE_FUNCTIONS(codecDef);
} }
return 0; return 0;
} }

View File

@ -101,18 +101,19 @@ namespace webrtc {
// We dynamically allocate some of the dynamic payload types to the defined // We dynamically allocate some of the dynamic payload types to the defined
// codecs. Note! There are a limited number of payload types. If more codecs // codecs. Note! There are a limited number of payload types. If more codecs
// are defined they will receive reserved fixed payload types (values 67-95). // are defined they will receive reserved fixed payload types (values 69-95).
const int kDynamicPayloadtypes[ACMCodecDB::kMaxNumCodecs] = { const int kDynamicPayloadtypes[ACMCodecDB::kMaxNumCodecs] = {
105, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 105, 107, 108, 109, 111, 112, 113, 114, 115, 116, 117, 120,
120, 121, 122, 123, 124, 125, 126, 95, 94, 93, 92, 91, 90, 89, 121, 122, 123, 124, 125, 126, 101, 100, 97, 96, 95, 94,
88, 87, 86, 85, 84, 83, 82, 81, 80, 79, 78, 77, 76, 75, 93, 92, 91, 90, 89, 88, 87, 86, 85, 84, 83, 82,
74, 73, 72, 71, 70, 69, 68, 67 81, 80, 79, 78, 77, 76, 75, 74, 73, 72, 71, 70,
69,
}; };
// Creates database with all supported codec at compile time. // Creates database with all supported codecs at compile time.
// Each entry needs the following parameters in the given order: // Each entry needs the following parameters in the given order:
// payload type, name, sampling frequency, packet size in samples, // payload type, name, sampling frequency, packet size in samples,
// default channel support, and default rate. // number of channels, and default rate.
#if (defined(WEBRTC_CODEC_PCM16) || \ #if (defined(WEBRTC_CODEC_PCM16) || \
defined(WEBRTC_CODEC_AMR) || defined(WEBRTC_CODEC_AMRWB) || \ defined(WEBRTC_CODEC_AMR) || defined(WEBRTC_CODEC_AMRWB) || \
defined(WEBRTC_CODEC_CELT) || defined(WEBRTC_CODEC_G729_1) || \ defined(WEBRTC_CODEC_CELT) || defined(WEBRTC_CODEC_G729_1) || \
@ -129,13 +130,22 @@ const CodecInst ACMCodecDB::database_[] = {
# endif # endif
#endif #endif
#ifdef WEBRTC_CODEC_PCM16 #ifdef WEBRTC_CODEC_PCM16
// Mono
{kDynamicPayloadtypes[count_database++], "L16", 8000, 80, 1, 128000}, {kDynamicPayloadtypes[count_database++], "L16", 8000, 80, 1, 128000},
{kDynamicPayloadtypes[count_database++], "L16", 16000, 160, 1, 256000}, {kDynamicPayloadtypes[count_database++], "L16", 16000, 160, 1, 256000},
{kDynamicPayloadtypes[count_database++], "L16", 32000, 320, 1, 512000}, {kDynamicPayloadtypes[count_database++], "L16", 32000, 320, 1, 512000},
// Stereo
{kDynamicPayloadtypes[count_database++], "L16", 8000, 80, 2, 128000},
{kDynamicPayloadtypes[count_database++], "L16", 16000, 160, 2, 256000},
{kDynamicPayloadtypes[count_database++], "L16", 32000, 320, 2, 512000},
#endif #endif
// G.711, PCM mu-law and A-law. // G.711, PCM mu-law and A-law.
// Mono
{0, "PCMU", 8000, 160, 1, 64000}, {0, "PCMU", 8000, 160, 1, 64000},
{8, "PCMA", 8000, 160, 1, 64000}, {8, "PCMA", 8000, 160, 1, 64000},
// Stereo
{110, "PCMU", 8000, 160, 2, 64000},
{118, "PCMA", 8000, 160, 2, 64000},
#ifdef WEBRTC_CODEC_ILBC #ifdef WEBRTC_CODEC_ILBC
{102, "ILBC", 8000, 240, 1, 13300}, {102, "ILBC", 8000, 240, 1, 13300},
#endif #endif
@ -146,10 +156,16 @@ const CodecInst ACMCodecDB::database_[] = {
{kDynamicPayloadtypes[count_database++], "AMR-WB", 16000, 320, 1, 20000}, {kDynamicPayloadtypes[count_database++], "AMR-WB", 16000, 320, 1, 20000},
#endif #endif
#ifdef WEBRTC_CODEC_CELT #ifdef WEBRTC_CODEC_CELT
// Mono
{kDynamicPayloadtypes[count_database++], "CELT", 32000, 320, 1, 64000},
// Stereo
{kDynamicPayloadtypes[count_database++], "CELT", 32000, 320, 2, 64000}, {kDynamicPayloadtypes[count_database++], "CELT", 32000, 320, 2, 64000},
#endif #endif
#ifdef WEBRTC_CODEC_G722 #ifdef WEBRTC_CODEC_G722
// Mono
{9, "G722", 16000, 320, 1, 64000}, {9, "G722", 16000, 320, 1, 64000},
// Stereo
{119, "G722", 16000, 320, 2, 64000},
#endif #endif
#ifdef WEBRTC_CODEC_G722_1 #ifdef WEBRTC_CODEC_G722_1
{kDynamicPayloadtypes[count_database++], "G7221", 16000, 320, 1, 32000}, {kDynamicPayloadtypes[count_database++], "G7221", 16000, 320, 1, 32000},
@ -200,11 +216,20 @@ const ACMCodecDB::CodecSettings ACMCodecDB::codec_settings_[] = {
# endif # endif
#endif #endif
#ifdef WEBRTC_CODEC_PCM16 #ifdef WEBRTC_CODEC_PCM16
// Mono
{4, {80, 160, 240, 320}, 0, 2},
{4, {160, 320, 480, 640}, 0, 2},
{2, {320, 640}, 0, 2},
// Stereo
{4, {80, 160, 240, 320}, 0, 2}, {4, {80, 160, 240, 320}, 0, 2},
{4, {160, 320, 480, 640}, 0, 2}, {4, {160, 320, 480, 640}, 0, 2},
{2, {320, 640}, 0, 2}, {2, {320, 640}, 0, 2},
#endif #endif
// G.711, PCM mu-law and A-law. // G.711, PCM mu-law and A-law.
// Mono
{6, {80, 160, 240, 320, 400, 480}, 0, 2},
{6, {80, 160, 240, 320, 400, 480}, 0, 2},
// Stereo
{6, {80, 160, 240, 320, 400, 480}, 0, 2}, {6, {80, 160, 240, 320, 400, 480}, 0, 2},
{6, {80, 160, 240, 320, 400, 480}, 0, 2}, {6, {80, 160, 240, 320, 400, 480}, 0, 2},
#ifdef WEBRTC_CODEC_ILBC #ifdef WEBRTC_CODEC_ILBC
@ -217,20 +242,26 @@ const ACMCodecDB::CodecSettings ACMCodecDB::codec_settings_[] = {
{3, {320, 640, 960}, 0, 1}, {3, {320, 640, 960}, 0, 1},
#endif #endif
#ifdef WEBRTC_CODEC_CELT #ifdef WEBRTC_CODEC_CELT
// Mono
{1, {320}, 0, 2},
// Stereo
{1, {320}, 0, 2}, {1, {320}, 0, 2},
#endif #endif
#ifdef WEBRTC_CODEC_G722 #ifdef WEBRTC_CODEC_G722
// Mono
{6, {160, 320, 480, 640, 800, 960}, 0, 2},
// Stereo
{6, {160, 320, 480, 640, 800, 960}, 0, 2}, {6, {160, 320, 480, 640, 800, 960}, 0, 2},
#endif #endif
#ifdef WEBRTC_CODEC_G722_1 #ifdef WEBRTC_CODEC_G722_1
{1, {320}, 320, 2}, {1, {320}, 320, 1},
{1, {320}, 320, 2}, {1, {320}, 320, 1},
{1, {320}, 320, 2}, {1, {320}, 320, 1},
#endif #endif
#ifdef WEBRTC_CODEC_G722_1C #ifdef WEBRTC_CODEC_G722_1C
{1, {640}, 640, 2}, {1, {640}, 640, 1},
{1, {640}, 640, 2}, {1, {640}, 640, 1},
{1, {640}, 640, 2}, {1, {640}, 640, 1},
#endif #endif
#ifdef WEBRTC_CODEC_G729 #ifdef WEBRTC_CODEC_G729
{6, {80, 160, 240, 320, 400, 480}, 0, 1}, {6, {80, 160, 240, 320, 400, 480}, 0, 1},
@ -268,13 +299,22 @@ const WebRtcNetEQDecoder ACMCodecDB::neteq_decoders_[] = {
# endif # endif
#endif #endif
#ifdef WEBRTC_CODEC_PCM16 #ifdef WEBRTC_CODEC_PCM16
// Mono
kDecoderPCM16B, kDecoderPCM16B,
kDecoderPCM16Bwb, kDecoderPCM16Bwb,
kDecoderPCM16Bswb32kHz, kDecoderPCM16Bswb32kHz,
// Stereo
kDecoderPCM16B_2ch,
kDecoderPCM16Bwb_2ch,
kDecoderPCM16Bswb32kHz_2ch,
#endif #endif
// G.711, PCM mu-las and A-law. // G.711, PCM mu-las and A-law.
// Mono
kDecoderPCMu, kDecoderPCMu,
kDecoderPCMa, kDecoderPCMa,
// Stereo
kDecoderPCMu_2ch,
kDecoderPCMa_2ch,
#ifdef WEBRTC_CODEC_ILBC #ifdef WEBRTC_CODEC_ILBC
kDecoderILBC, kDecoderILBC,
#endif #endif
@ -285,10 +325,16 @@ const WebRtcNetEQDecoder ACMCodecDB::neteq_decoders_[] = {
kDecoderAMRWB, kDecoderAMRWB,
#endif #endif
#ifdef WEBRTC_CODEC_CELT #ifdef WEBRTC_CODEC_CELT
// Mono
kDecoderCELT_32, kDecoderCELT_32,
// Stereo
kDecoderCELT_32_2ch,
#endif #endif
#ifdef WEBRTC_CODEC_G722 #ifdef WEBRTC_CODEC_G722
// Mono
kDecoderG722, kDecoderG722,
// Stereo
kDecoderG722_2ch,
#endif #endif
#ifdef WEBRTC_CODEC_G722_1 #ifdef WEBRTC_CODEC_G722_1
kDecoderG722_1_32, kDecoderG722_1_32,
@ -343,7 +389,6 @@ int ACMCodecDB::Codec(int codec_id, CodecInst* codec_inst) {
// Enumerator for error codes when asking for codec database id. // Enumerator for error codes when asking for codec database id.
enum { enum {
kInvalidCodec = -10, kInvalidCodec = -10,
kInvalidFrequency = -20,
kInvalidPayloadtype = -30, kInvalidPayloadtype = -30,
kInvalidPacketSize = -40, kInvalidPacketSize = -40,
kInvalidRate = -50 kInvalidRate = -50
@ -361,12 +406,8 @@ int ACMCodecDB::CodecNumber(const CodecInst* codec_inst, int* mirror_id,
char my_err_msg[1000]; char my_err_msg[1000];
if (codec_id == kInvalidCodec) { if (codec_id == kInvalidCodec) {
sprintf(my_err_msg, "Call to ACMCodecDB::CodecNumber failed, plname=%s " sprintf(my_err_msg, "Call to ACMCodecDB::CodecNumber failed, Codec not "
"is not a valid codec", codec_inst->plname); "found");
} else if (codec_id == kInvalidFrequency) {
sprintf(my_err_msg, "Call to ACMCodecDB::CodecNumber failed, plfreq=%d "
"is not a valid frequency for the codec %s", codec_inst->plfreq,
codec_inst->plname);
} else if (codec_id == kInvalidPayloadtype) { } else if (codec_id == kInvalidPayloadtype) {
sprintf(my_err_msg, "Call to ACMCodecDB::CodecNumber failed, payload " sprintf(my_err_msg, "Call to ACMCodecDB::CodecNumber failed, payload "
"number %d is out of range for %s", codec_inst->pltype, "number %d is out of range for %s", codec_inst->pltype,
@ -396,32 +437,12 @@ int ACMCodecDB::CodecNumber(const CodecInst* codec_inst, int* mirror_id,
// the codec settings, the function will return an error code. // the codec settings, the function will return an error code.
// NOTE! The first mismatch found will generate the return value. // NOTE! The first mismatch found will generate the return value.
int ACMCodecDB::CodecNumber(const CodecInst* codec_inst, int* mirror_id) { int ACMCodecDB::CodecNumber(const CodecInst* codec_inst, int* mirror_id) {
int codec_number = -1; // Look for a matching codec in the database.
bool name_match = false; int codec_id = CodecId(codec_inst);
// Looks for a matching payload name and frequency in the codec list. // Checks if we found a matching codec.
// Need to check both since some codecs have several codec entries with if (codec_id == -1) {
// different frequencies (like iSAC). return kInvalidCodec;
for (int i = 0; i < kNumCodecs; i++) {
if (STR_CASE_CMP(database_[i].plname, codec_inst->plname) == 0) {
// We have found a matching codec name in the list.
name_match = true;
// Checks if frequency match.
if (codec_inst->plfreq == database_[i].plfreq) {
codec_number = i;
break;
}
}
}
// Checks if the error is in the name or in the frequency.
if (codec_number == -1) {
if (!name_match) {
return kInvalidCodec;
} else {
return kInvalidFrequency;
}
} }
// Checks the validity of payload type // Checks the validity of payload type
@ -430,25 +451,25 @@ int ACMCodecDB::CodecNumber(const CodecInst* codec_inst, int* mirror_id) {
} }
// Comfort Noise is special case, packet-size & rate is not checked. // Comfort Noise is special case, packet-size & rate is not checked.
if (STR_CASE_CMP(database_[codec_number].plname, "CN") == 0) { if (STR_CASE_CMP(database_[codec_id].plname, "CN") == 0) {
*mirror_id = codec_number; *mirror_id = codec_id;
return codec_number; return codec_id;
} }
// RED is special case, packet-size & rate is not checked. // RED is special case, packet-size & rate is not checked.
if (STR_CASE_CMP(database_[codec_number].plname, "red") == 0) { if (STR_CASE_CMP(database_[codec_id].plname, "red") == 0) {
*mirror_id = codec_number; *mirror_id = codec_id;
return codec_number; return codec_id;
} }
// Checks the validity of packet size. // Checks the validity of packet size.
if (codec_settings_[codec_number].num_packet_sizes > 0) { if (codec_settings_[codec_id].num_packet_sizes > 0) {
bool packet_size_ok = false; bool packet_size_ok = false;
int i; int i;
int packet_size_samples; int packet_size_samples;
for (i = 0; i < codec_settings_[codec_number].num_packet_sizes; i++) { for (i = 0; i < codec_settings_[codec_id].num_packet_sizes; i++) {
packet_size_samples = packet_size_samples =
codec_settings_[codec_number].packet_sizes_samples[i]; codec_settings_[codec_id].packet_sizes_samples[i];
if (codec_inst->pacsize == packet_size_samples) { if (codec_inst->pacsize == packet_size_samples) {
packet_size_ok = true; packet_size_ok = true;
break; break;
@ -464,73 +485,90 @@ int ACMCodecDB::CodecNumber(const CodecInst* codec_inst, int* mirror_id) {
return kInvalidPacketSize; return kInvalidPacketSize;
} }
// Check the validity of rate. Codecs with multiple rates have their own // Check the validity of rate. Codecs with multiple rates have their own
// function for this. // function for this.
*mirror_id = codec_number; *mirror_id = codec_id;
if (STR_CASE_CMP("isac", codec_inst->plname) == 0) { if (STR_CASE_CMP("isac", codec_inst->plname) == 0) {
if (IsISACRateValid(codec_inst->rate)) { if (IsISACRateValid(codec_inst->rate)) {
// Set mirrorID to iSAC WB which is only created once to be used both for // Set mirrorID to iSAC WB which is only created once to be used both for
// iSAC WB and SWB, because they need to share struct. // iSAC WB and SWB, because they need to share struct.
*mirror_id = kISAC; *mirror_id = kISAC;
return codec_number; return codec_id;
} else { } else {
return kInvalidRate; return kInvalidRate;
} }
} else if (STR_CASE_CMP("ilbc", codec_inst->plname) == 0) { } else if (STR_CASE_CMP("ilbc", codec_inst->plname) == 0) {
return IsILBCRateValid(codec_inst->rate, codec_inst->pacsize) return IsILBCRateValid(codec_inst->rate, codec_inst->pacsize)
? codec_number : kInvalidRate; ? codec_id : kInvalidRate;
} else if (STR_CASE_CMP("amr", codec_inst->plname) == 0) { } else if (STR_CASE_CMP("amr", codec_inst->plname) == 0) {
return IsAMRRateValid(codec_inst->rate) return IsAMRRateValid(codec_inst->rate)
? codec_number : kInvalidRate; ? codec_id : kInvalidRate;
} else if (STR_CASE_CMP("amr-wb", codec_inst->plname) == 0) { } else if (STR_CASE_CMP("amr-wb", codec_inst->plname) == 0) {
return IsAMRwbRateValid(codec_inst->rate) return IsAMRwbRateValid(codec_inst->rate)
? codec_number : kInvalidRate; ? codec_id : kInvalidRate;
} else if (STR_CASE_CMP("g7291", codec_inst->plname) == 0) { } else if (STR_CASE_CMP("g7291", codec_inst->plname) == 0) {
return IsG7291RateValid(codec_inst->rate) return IsG7291RateValid(codec_inst->rate)
? codec_number : kInvalidRate; ? codec_id : kInvalidRate;
} else if (STR_CASE_CMP("speex", codec_inst->plname) == 0) { } else if (STR_CASE_CMP("speex", codec_inst->plname) == 0) {
return IsSpeexRateValid(codec_inst->rate) return IsSpeexRateValid(codec_inst->rate)
? codec_number : kInvalidRate; ? codec_id : kInvalidRate;
} else if (STR_CASE_CMP("celt", codec_inst->plname) == 0) { } else if (STR_CASE_CMP("celt", codec_inst->plname) == 0) {
return IsCeltRateValid(codec_inst->rate) return IsCeltRateValid(codec_inst->rate)
? codec_number : kInvalidRate; ? codec_id : kInvalidRate;
} }
return IsRateValid(codec_number, codec_inst->rate) ? return IsRateValid(codec_id, codec_inst->rate) ?
codec_number : kInvalidRate; codec_id : kInvalidRate;
} }
// Gets codec id number, and mirror id, from database for the receiver. // Looks for a matching payload name, frequency, and channels in the
int ACMCodecDB::ReceiverCodecNumber(const CodecInst* codec_inst, // codec list. Need to check all three since some codecs have several codec
int* mirror_id) { // entries with different frequencies and/or channels.
int codec_number = -1; // Does not check other codec settings, such as payload type and packet size.
// Returns the id of the codec, or -1 if no match is found.
int ACMCodecDB::CodecId(const CodecInst* codec_inst) {
return (CodecId(codec_inst->plname, codec_inst->plfreq,
codec_inst->channels));
}
// Looks for a matching payload name and frequency in the codec list. int ACMCodecDB::CodecId(const char* payload_name, int frequency, int channels) {
// Need to check both since some codecs have several codec entries with for (int id = 0; id < kNumCodecs; id++) {
// different frequencies (like iSAC). bool name_match = false;
for (int i = 0; i < kNumCodecs; i++) { bool frequency_match = false;
if (STR_CASE_CMP(database_[i].plname, codec_inst->plname) == 0) { bool channels_match = false;
// We have found a matching codec name in the list.
// Check if frequency match. // Payload name, sampling frequency and number of channels need to match.
if (codec_inst->plfreq == database_[i].plfreq) { // NOTE! If |frequency| is -1, the frequency is not applicable, and is
codec_number = i; // always treated as true, like for RED.
*mirror_id = codec_number; name_match = (STR_CASE_CMP(database_[id].plname, payload_name) == 0);
frequency_match = (frequency == database_[id].plfreq) || (frequency == -1);
channels_match = (channels == database_[id].channels);
// Check if codec is iSAC, set mirrorID to iSAC WB which is only if (name_match && frequency_match && channels_match) {
// created once to be used both for iSAC WB and SWB, because they need // We have found a matching codec in the list.
// to share struct. return id;
if (STR_CASE_CMP(codec_inst->plname, "ISAC") == 0) {
*mirror_id = kISAC;
}
break;
}
} }
} }
return codec_number; // We didn't find a matching codec.
return -1;
}
// Gets codec id number, and mirror id, from database for the receiver.
int ACMCodecDB::ReceiverCodecNumber(const CodecInst* codec_inst,
int* mirror_id) {
// Look for a matching codec in the database.
int codec_id = CodecId(codec_inst);
// Set |mirror_id| to |codec_id|, except for iSAC. In case of iSAC we always
// set |mirror_id| to iSAC WB (kISAC) which is only created once to be used
// both for iSAC WB and SWB, because they need to share struct.
if (STR_CASE_CMP(codec_inst->plname, "ISAC") != 0) {
*mirror_id = codec_id;
} else {
*mirror_id = kISAC;
}
return codec_id;
} }
// Returns the codec sampling frequency for codec with id = "codec_id" in // Returns the codec sampling frequency for codec with id = "codec_id" in
@ -701,9 +739,17 @@ ACMGenericCodec* ACMCodecDB::CreateCodecInstance(const CodecInst* codec_inst) {
return new ACMISAC(kISAC); return new ACMISAC(kISAC);
#endif #endif
} else if (!STR_CASE_CMP(codec_inst->plname, "PCMU")) { } else if (!STR_CASE_CMP(codec_inst->plname, "PCMU")) {
return new ACMPCMU(kPCMU); if (codec_inst->channels == 1) {
return new ACMPCMU(kPCMU);
} else {
return new ACMPCMU(kPCMU_2ch);
}
} else if (!STR_CASE_CMP(codec_inst->plname, "PCMA")) { } else if (!STR_CASE_CMP(codec_inst->plname, "PCMA")) {
return new ACMPCMA(kPCMA); if (codec_inst->channels == 1) {
return new ACMPCMA(kPCMA);
} else {
return new ACMPCMA(kPCMA_2ch);
}
} else if (!STR_CASE_CMP(codec_inst->plname, "ILBC")) { } else if (!STR_CASE_CMP(codec_inst->plname, "ILBC")) {
#ifdef WEBRTC_CODEC_ILBC #ifdef WEBRTC_CODEC_ILBC
return new ACMILBC(kILBC); return new ACMILBC(kILBC);
@ -718,11 +764,19 @@ ACMGenericCodec* ACMCodecDB::CreateCodecInstance(const CodecInst* codec_inst) {
#endif #endif
} else if (!STR_CASE_CMP(codec_inst->plname, "CELT")) { } else if (!STR_CASE_CMP(codec_inst->plname, "CELT")) {
#ifdef WEBRTC_CODEC_CELT #ifdef WEBRTC_CODEC_CELT
return new ACMCELT(kCELT32); if (codec_inst->channels == 1) {
return new ACMCELT(kCELT32);
} else {
return new ACMCELT(kCELT32_2ch);
}
#endif #endif
} else if (!STR_CASE_CMP(codec_inst->plname, "G722")) { } else if (!STR_CASE_CMP(codec_inst->plname, "G722")) {
#ifdef WEBRTC_CODEC_G722 #ifdef WEBRTC_CODEC_G722
return new ACMG722(kG722); if (codec_inst->channels == 1) {
return new ACMG722(kG722);
} else {
return new ACMG722(kG722_2ch);
}
#endif #endif
} else if (!STR_CASE_CMP(codec_inst->plname, "G7221")) { } else if (!STR_CASE_CMP(codec_inst->plname, "G7221")) {
switch (codec_inst->plfreq) { switch (codec_inst->plfreq) {
@ -845,21 +899,41 @@ ACMGenericCodec* ACMCodecDB::CreateCodecInstance(const CodecInst* codec_inst) {
#ifdef WEBRTC_CODEC_PCM16 #ifdef WEBRTC_CODEC_PCM16
// For L16 we need to check sampling frequency to know what codec to create. // For L16 we need to check sampling frequency to know what codec to create.
int codec_id; int codec_id;
switch (codec_inst->plfreq) { if (codec_inst->channels == 1) {
case 8000: { switch (codec_inst->plfreq) {
codec_id = kPCM16B; case 8000: {
break; codec_id = kPCM16B;
break;
}
case 16000: {
codec_id = kPCM16Bwb;
break;
}
case 32000: {
codec_id = kPCM16Bswb32kHz;
break;
}
default: {
return NULL;
}
} }
case 16000: { } else {
codec_id =kPCM16Bwb; switch (codec_inst->plfreq) {
break; case 8000: {
} codec_id = kPCM16B_2ch;
case 32000: { break;
codec_id = kPCM16Bswb32kHz; }
break; case 16000: {
} codec_id = kPCM16Bwb_2ch;
default: { break;
return NULL; }
case 32000: {
codec_id = kPCM16Bswb32kHz_2ch;
break;
}
default: {
return NULL;
}
} }
} }
return new ACMPCM16B(codec_id); return new ACMPCM16B(codec_id);

View File

@ -36,12 +36,21 @@ class ACMCodecDB {
# endif # endif
#endif #endif
#ifdef WEBRTC_CODEC_PCM16 #ifdef WEBRTC_CODEC_PCM16
// Mono
, kPCM16B , kPCM16B
, kPCM16Bwb , kPCM16Bwb
, kPCM16Bswb32kHz , kPCM16Bswb32kHz
// Stereo
, kPCM16B_2ch
, kPCM16Bwb_2ch
, kPCM16Bswb32kHz_2ch
#endif #endif
// Mono
, kPCMU , kPCMU
, kPCMA , kPCMA
// Stereo
, kPCMU_2ch
, kPCMA_2ch
#ifdef WEBRTC_CODEC_ILBC #ifdef WEBRTC_CODEC_ILBC
, kILBC , kILBC
#endif #endif
@ -52,10 +61,16 @@ class ACMCodecDB {
, kGSMAMRWB , kGSMAMRWB
#endif #endif
#ifdef WEBRTC_CODEC_CELT #ifdef WEBRTC_CODEC_CELT
// Mono
, kCELT32 , kCELT32
// Stereo
, kCELT32_2ch
#endif #endif
#ifdef WEBRTC_CODEC_G722 #ifdef WEBRTC_CODEC_G722
// Mono
, kG722 , kG722
// Stereo
, kG722_2ch
#endif #endif
#ifdef WEBRTC_CODEC_G722_1 #ifdef WEBRTC_CODEC_G722_1
, kG722_1_32 , kG722_1_32
@ -100,9 +115,14 @@ class ACMCodecDB {
# endif # endif
#endif #endif
#ifndef WEBRTC_CODEC_PCM16 #ifndef WEBRTC_CODEC_PCM16
// Mono
enum {kPCM16B = -1}; enum {kPCM16B = -1};
enum {kPCM16Bwb = -1}; enum {kPCM16Bwb = -1};
enum {kPCM16Bswb32kHz = -1}; enum {kPCM16Bswb32kHz = -1};
// Stereo
enum {kPCM16B_2ch = -1};
enum {kPCM16Bwb_2ch = -1};
enum {kPCM16Bswb32kHz_2ch = -1};
#endif #endif
// 48 kHz not supported, always set to -1. // 48 kHz not supported, always set to -1.
enum {kPCM16Bswb48kHz = -1}; enum {kPCM16Bswb48kHz = -1};
@ -116,10 +136,16 @@ class ACMCodecDB {
enum {kGSMAMRWB = -1}; enum {kGSMAMRWB = -1};
#endif #endif
#ifndef WEBRTC_CODEC_CELT #ifndef WEBRTC_CODEC_CELT
// Mono
enum {kCELT32 = -1}; enum {kCELT32 = -1};
// Stereo
enum {kCELT32_2ch = -1};
#endif #endif
#ifndef WEBRTC_CODEC_G722 #ifndef WEBRTC_CODEC_G722
// Mono
enum {kG722 = -1}; enum {kG722 = -1};
// Stereo
enum {kG722_2ch = -1};
#endif #endif
#ifndef WEBRTC_CODEC_G722_1 #ifndef WEBRTC_CODEC_G722_1
enum {kG722_1_32 = -1}; enum {kG722_1_32 = -1};
@ -212,6 +238,8 @@ class ACMCodecDB {
static int CodecNumber(const CodecInst* codec_inst, int* mirror_id, static int CodecNumber(const CodecInst* codec_inst, int* mirror_id,
char* err_message, int max_message_len_byte); char* err_message, int max_message_len_byte);
static int CodecNumber(const CodecInst* codec_inst, int* mirror_id); static int CodecNumber(const CodecInst* codec_inst, int* mirror_id);
static int CodecId(const CodecInst* codec_inst);
static int CodecId(const char* payload_name, int frequency, int channels);
static int ReceiverCodecNumber(const CodecInst* codec_inst, int* mirror_id); static int ReceiverCodecNumber(const CodecInst* codec_inst, int* mirror_id);
// Returns the codec sampling frequency for codec with id = "codec_id" in // Returns the codec sampling frequency for codec with id = "codec_id" in

View File

@ -187,8 +187,8 @@ WebRtc_Word16 ACMG722::InternalEncode(WebRtc_UWord8* bitStream,
// Interleave the 4 bits per sample from left and right channel // Interleave the 4 bits per sample from left and right channel
for (int i = 0, j = 0; i < lenInBytes; i += 2, j++) { for (int i = 0, j = 0; i < lenInBytes; i += 2, j++) {
bitStream[i] = (outRight[j] & 0xF0) + (outLeft[j] >> 4); bitStream[i] = (outLeft[j] & 0xF0) + (outRight[j] >> 4);
bitStream[i + 1] = ((outRight[j] & 0x0F) << 4) + (outLeft[j] & 0x0F); bitStream[i + 1] = ((outLeft[j] & 0x0F) << 4) + (outRight[j] & 0x0F);
} }
} else { } else {
*bitStreamLenByte = WebRtcG722_Encode(_encoderInstPtr, *bitStreamLenByte = WebRtcG722_Encode(_encoderInstPtr,
@ -244,9 +244,14 @@ WebRtc_Word32 ACMG722::CodecDef(WebRtcNetEQ_CodecDef& codecDef,
// "SET_CODEC_PAR" & "SET_G722_FUNCTION." // "SET_CODEC_PAR" & "SET_G722_FUNCTION."
// Then call NetEQ to add the codec to it's // Then call NetEQ to add the codec to it's
// database. // database.
SET_CODEC_PAR((codecDef), kDecoderG722, codecInst.pltype, _decoderInstPtr, if (codecInst.channels == 1) {
16000); SET_CODEC_PAR(codecDef, kDecoderG722, codecInst.pltype, _decoderInstPtr,
SET_G722_FUNCTIONS((codecDef)); 16000);
} else {
SET_CODEC_PAR(codecDef, kDecoderG722_2ch, codecInst.pltype,
_decoderInstPtr, 16000);
}
SET_G722_FUNCTIONS(codecDef);
return 0; return 0;
} }

View File

@ -8,10 +8,11 @@
* be found in the AUTHORS file in the root of the source tree. * be found in the AUTHORS file in the root of the source tree.
*/ */
#include "acm_pcm16b.h"
#include "acm_codec_database.h" #include "acm_codec_database.h"
#include "acm_common_defs.h" #include "acm_common_defs.h"
#include "acm_neteq.h" #include "acm_neteq.h"
#include "acm_pcm16b.h"
#include "trace.h" #include "trace.h"
#include "webrtc_neteq.h" #include "webrtc_neteq.h"
#include "webrtc_neteq_help_macros.h" #include "webrtc_neteq_help_macros.h"
@ -20,267 +21,202 @@
#include "pcm16b.h" #include "pcm16b.h"
#endif #endif
namespace webrtc namespace webrtc {
{
#ifndef WEBRTC_CODEC_PCM16 #ifndef WEBRTC_CODEC_PCM16
ACMPCM16B::ACMPCM16B( ACMPCM16B::ACMPCM16B(WebRtc_Word16 /* codecID */) {
WebRtc_Word16 /* codecID */) return;
{
return;
} }
ACMPCM16B::~ACMPCM16B() {
ACMPCM16B::~ACMPCM16B() return;
{
return;
} }
WebRtc_Word16 ACMPCM16B::InternalEncode(WebRtc_UWord8* /* bitStream */,
WebRtc_Word16 WebRtc_Word16* /* bitStreamLenByte */) {
ACMPCM16B::InternalEncode( return -1;
WebRtc_UWord8* /* bitStream */,
WebRtc_Word16* /* bitStreamLenByte */)
{
return -1;
} }
WebRtc_Word16 ACMPCM16B::DecodeSafe(WebRtc_UWord8* /* bitStream */,
WebRtc_Word16 WebRtc_Word16 /* bitStreamLenByte */,
ACMPCM16B::DecodeSafe( WebRtc_Word16* /* audio */,
WebRtc_UWord8* /* bitStream */, WebRtc_Word16* /* audioSamples */,
WebRtc_Word16 /* bitStreamLenByte */, WebRtc_Word8* /* speechType */) {
WebRtc_Word16* /* audio */, return -1;
WebRtc_Word16* /* audioSamples */,
WebRtc_Word8* /* speechType */)
{
return -1;
} }
WebRtc_Word16 ACMPCM16B::InternalInitEncoder(
WebRtc_Word16 WebRtcACMCodecParams* /* codecParams */) {
ACMPCM16B::InternalInitEncoder( return -1;
WebRtcACMCodecParams* /* codecParams */)
{
return -1;
} }
WebRtc_Word16 ACMPCM16B::InternalInitDecoder(
WebRtc_Word16 WebRtcACMCodecParams* /* codecParams */) {
ACMPCM16B::InternalInitDecoder( return -1;
WebRtcACMCodecParams* /* codecParams */)
{
return -1;
} }
WebRtc_Word32 ACMPCM16B::CodecDef(WebRtcNetEQ_CodecDef& /* codecDef */,
WebRtc_Word32 const CodecInst& /* codecInst */) {
ACMPCM16B::CodecDef( return -1;
WebRtcNetEQ_CodecDef& /* codecDef */,
const CodecInst& /* codecInst */)
{
return -1;
} }
ACMGenericCodec* ACMPCM16B::CreateInstance(void) {
ACMGenericCodec* return NULL;
ACMPCM16B::CreateInstance(void)
{
return NULL;
} }
WebRtc_Word16 ACMPCM16B::InternalCreateEncoder() {
WebRtc_Word16 return -1;
ACMPCM16B::InternalCreateEncoder()
{
return -1;
} }
WebRtc_Word16 ACMPCM16B::InternalCreateDec WEBRTC_CODEC_PCM16oder() {
WebRtc_Word16 return -1;
ACMPCM16B::InternalCreateDecoder()
{
return -1;
} }
void ACMPCM16B::InternalDestructEncoderInst(void* /* ptrInst */) {
void return;
ACMPCM16B::InternalDestructEncoderInst(
void* /* ptrInst */)
{
return;
} }
void ACMPCM16B::DestructEncoderSafe() {
void return;
ACMPCM16B::DestructEncoderSafe()
{
return;
} }
void void ACMPCM16B::DestructDecoderSafe() {
ACMPCM16B::DestructDecoderSafe() return;
{
return;
} }
void ACMPCM16B::SplitStereoPacket(uint8_t* /*payload*/, void ACMPCM16B::SplitStereoPacket(uint8_t* /*payload*/,
int32_t* /*payload_length*/) {} int32_t* /*payload_length*/) {
}
#else //===================== Actual Implementation ======================= #else //===================== Actual Implementation =======================
ACMPCM16B::ACMPCM16B(WebRtc_Word16 codecID) {
ACMPCM16B::ACMPCM16B( _codecID = codecID;
WebRtc_Word16 codecID) _samplingFreqHz = ACMCodecDB::CodecFreq(_codecID);
{
_codecID = codecID;
_samplingFreqHz = ACMCodecDB::CodecFreq(_codecID);
} }
ACMPCM16B::~ACMPCM16B() {
ACMPCM16B::~ACMPCM16B() return;
{
return;
} }
WebRtc_Word16 ACMPCM16B::InternalEncode(WebRtc_UWord8* bitStream,
WebRtc_Word16 WebRtc_Word16* bitStreamLenByte) {
ACMPCM16B::InternalEncode( *bitStreamLenByte = WebRtcPcm16b_Encode(&_inAudio[_inAudioIxRead],
WebRtc_UWord8* bitStream, _frameLenSmpl * _noChannels,
WebRtc_Word16* bitStreamLenByte) bitStream);
{ // Increment the read index to tell the caller that how far
*bitStreamLenByte = WebRtcPcm16b_Encode(&_inAudio[_inAudioIxRead], // we have gone forward in reading the audio buffer.
_frameLenSmpl*_noChannels, _inAudioIxRead += _frameLenSmpl * _noChannels;
bitStream); return *bitStreamLenByte;
// increment the read index to tell the caller that how far
// we have gone forward in reading the audio buffer
_inAudioIxRead += _frameLenSmpl*_noChannels;
return *bitStreamLenByte;
} }
WebRtc_Word16 ACMPCM16B::DecodeSafe(WebRtc_UWord8* /* bitStream */,
WebRtc_Word16 WebRtc_Word16 /* bitStreamLenByte */,
ACMPCM16B::DecodeSafe( WebRtc_Word16* /* audio */,
WebRtc_UWord8* /* bitStream */, WebRtc_Word16* /* audioSamples */,
WebRtc_Word16 /* bitStreamLenByte */, WebRtc_Word8* /* speechType */) {
WebRtc_Word16* /* audio */, return 0;
WebRtc_Word16* /* audioSamples */,
WebRtc_Word8* /* speechType */)
{
return 0;
} }
WebRtc_Word16 ACMPCM16B::InternalInitEncoder(
WebRtc_Word16 WebRtcACMCodecParams* /* codecParams */) {
ACMPCM16B::InternalInitEncoder( // This codec does not need initialization, PCM has no instance.
WebRtcACMCodecParams* /* codecParams */) return 0;
{
// This codec does not need initialization,
// PCM has no instance
return 0;
} }
WebRtc_Word16 ACMPCM16B::InternalInitDecoder(
WebRtc_Word16 WebRtcACMCodecParams* /* codecParams */) {
ACMPCM16B::InternalInitDecoder( // This codec does not need initialization, PCM has no instance.
WebRtcACMCodecParams* /* codecParams */) return 0;
{
// This codec does not need initialization,
// PCM has no instance
return 0;
} }
WebRtc_Word32 ACMPCM16B::CodecDef(WebRtcNetEQ_CodecDef& codecDef,
WebRtc_Word32 const CodecInst& codecInst) {
ACMPCM16B::CodecDef( // Fill up the structure by calling "SET_CODEC_PAR" & "SET_PCMU_FUNCTION".
WebRtcNetEQ_CodecDef& codecDef, // Then call NetEQ to add the codec to it's database.
const CodecInst& codecInst) if (codecInst.channels == 1) {
{ switch(_samplingFreqHz) {
// Fill up the structure by calling case 8000: {
// "SET_CODEC_PAR" & "SET_PCMU_FUNCTION." SET_CODEC_PAR(codecDef, kDecoderPCM16B, codecInst.pltype, NULL, 8000);
// Then call NetEQ to add the codec to it's SET_PCM16B_FUNCTIONS(codecDef);
// database. break;
switch(_samplingFreqHz) }
{ case 16000: {
case 8000: SET_CODEC_PAR(codecDef, kDecoderPCM16Bwb, codecInst.pltype, NULL,
{ 16000);
SET_CODEC_PAR((codecDef), kDecoderPCM16B, codecInst.pltype, SET_PCM16B_WB_FUNCTIONS(codecDef);
NULL, 8000); break;
SET_PCM16B_FUNCTIONS((codecDef)); }
break; case 32000: {
} SET_CODEC_PAR(codecDef, kDecoderPCM16Bswb32kHz, codecInst.pltype,
case 16000: NULL, 32000);
{ SET_PCM16B_SWB32_FUNCTIONS(codecDef);
SET_CODEC_PAR((codecDef), kDecoderPCM16Bwb, codecInst.pltype, break;
NULL, 16000); }
SET_PCM16B_WB_FUNCTIONS((codecDef)); default: {
break; return -1;
} }
case 32000:
{
SET_CODEC_PAR((codecDef), kDecoderPCM16Bswb32kHz,
codecInst.pltype, NULL, 32000);
SET_PCM16B_SWB32_FUNCTIONS((codecDef));
break;
}
default:
{
return -1;
}
} }
return 0; } else {
switch(_samplingFreqHz) {
case 8000: {
SET_CODEC_PAR(codecDef, kDecoderPCM16B_2ch, codecInst.pltype, NULL,
8000);
SET_PCM16B_FUNCTIONS(codecDef);
break;
}
case 16000: {
SET_CODEC_PAR(codecDef, kDecoderPCM16Bwb_2ch, codecInst.pltype,
NULL, 16000);
SET_PCM16B_WB_FUNCTIONS(codecDef);
break;
}
case 32000: {
SET_CODEC_PAR(codecDef, kDecoderPCM16Bswb32kHz_2ch, codecInst.pltype,
NULL, 32000);
SET_PCM16B_SWB32_FUNCTIONS(codecDef);
break;
}
default: {
return -1;
}
}
}
return 0;
} }
ACMGenericCodec* ACMPCM16B::CreateInstance(void) {
ACMGenericCodec* return NULL;
ACMPCM16B::CreateInstance(void)
{
return NULL;
} }
WebRtc_Word16 ACMPCM16B::InternalCreateEncoder() {
WebRtc_Word16 // PCM has no instance.
ACMPCM16B::InternalCreateEncoder() return 0;
{
// PCM has no instance
return 0;
} }
WebRtc_Word16 ACMPCM16B::InternalCreateDecoder() {
WebRtc_Word16 // PCM has no instance.
ACMPCM16B::InternalCreateDecoder() return 0;
{
// PCM has no instance
return 0;
} }
void ACMPCM16B::InternalDestructEncoderInst(void* /* ptrInst */) {
void // PCM has no instance.
ACMPCM16B::InternalDestructEncoderInst( return;
void* /* ptrInst */)
{
// PCM has no instance
return;
} }
void ACMPCM16B::DestructEncoderSafe() {
void // PCM has no instance.
ACMPCM16B::DestructEncoderSafe() _encoderExist = false;
{ _encoderInitialized = false;
// PCM has no instance return;
_encoderExist = false;
_encoderInitialized = false;
return;
} }
void void ACMPCM16B::DestructDecoderSafe() {
ACMPCM16B::DestructDecoderSafe() // PCM has no instance.
{ _decoderExist = false;
// PCM has no instance _decoderInitialized = false;
_decoderExist = false; return;
_decoderInitialized = false;
return;
} }
// Split the stereo packet and place left and right channel after each other // Split the stereo packet and place left and right channel after each other

View File

@ -8,9 +8,10 @@
* be found in the AUTHORS file in the root of the source tree. * be found in the AUTHORS file in the root of the source tree.
*/ */
#include "acm_pcma.h"
#include "acm_common_defs.h" #include "acm_common_defs.h"
#include "acm_neteq.h" #include "acm_neteq.h"
#include "acm_pcma.h"
#include "trace.h" #include "trace.h"
#include "webrtc_neteq.h" #include "webrtc_neteq.h"
#include "webrtc_neteq_help_macros.h" #include "webrtc_neteq_help_macros.h"
@ -18,128 +19,92 @@
// Codec interface // Codec interface
#include "g711_interface.h" #include "g711_interface.h"
namespace webrtc namespace webrtc {
{
ACMPCMA::ACMPCMA(WebRtc_Word16 codecID) ACMPCMA::ACMPCMA(WebRtc_Word16 codecID) {
{ _codecID = codecID;
_codecID = codecID;
} }
ACMPCMA::~ACMPCMA() {
ACMPCMA::~ACMPCMA() return;
{
return;
} }
WebRtc_Word16 ACMPCMA::InternalEncode(WebRtc_UWord8* bitStream,
WebRtc_Word16 WebRtc_Word16* bitStreamLenByte) {
ACMPCMA::InternalEncode( *bitStreamLenByte = WebRtcG711_EncodeA(NULL, &_inAudio[_inAudioIxRead],
WebRtc_UWord8* bitStream, _frameLenSmpl * _noChannels,
WebRtc_Word16* bitStreamLenByte) (WebRtc_Word16*) bitStream);
{ // Increment the read index this tell the caller that how far
*bitStreamLenByte = WebRtcG711_EncodeA(NULL, &_inAudio[_inAudioIxRead], // we have gone forward in reading the audio buffer.
_frameLenSmpl*_noChannels, (WebRtc_Word16*)bitStream); _inAudioIxRead += _frameLenSmpl * _noChannels;
// increment the read index this tell the caller that how far return *bitStreamLenByte;
// we have gone forward in reading the audio buffer
_inAudioIxRead += _frameLenSmpl*_noChannels;
return *bitStreamLenByte;
} }
WebRtc_Word16 ACMPCMA::DecodeSafe(WebRtc_UWord8* /* bitStream */,
WebRtc_Word16 WebRtc_Word16 /* bitStreamLenByte */,
ACMPCMA::DecodeSafe( WebRtc_Word16* /* audio */,
WebRtc_UWord8* /* bitStream */, WebRtc_Word16* /* audioSamples */,
WebRtc_Word16 /* bitStreamLenByte */, WebRtc_Word8* /* speechType */) {
WebRtc_Word16* /* audio */, return 0;
WebRtc_Word16* /* audioSamples */,
WebRtc_Word8* /* speechType */)
{
return 0;
} }
WebRtc_Word16 ACMPCMA::InternalInitEncoder(
WebRtc_Word16 WebRtcACMCodecParams* /* codecParams */) {
ACMPCMA::InternalInitEncoder( // This codec does not need initialization, PCM has no instance.
WebRtcACMCodecParams* /* codecParams */) return 0;
{
// This codec does not need initialization,
// PCM has no instance
return 0;
} }
WebRtc_Word16 ACMPCMA::InternalInitDecoder(
WebRtc_Word16 WebRtcACMCodecParams* /* codecParams */) {
ACMPCMA::InternalInitDecoder( // This codec does not need initialization, PCM has no instance.
WebRtcACMCodecParams* /* codecParams */) return 0;
{
// This codec does not need initialization,
// PCM has no instance
return 0;
} }
WebRtc_Word32 ACMPCMA::CodecDef(WebRtcNetEQ_CodecDef& codecDef,
WebRtc_Word32 ACMPCMA::CodecDef( const CodecInst& codecInst) {
WebRtcNetEQ_CodecDef& codecDef, // Fill up the structure by calling
const CodecInst& codecInst) // "SET_CODEC_PAR" & "SET_PCMA_FUNCTION."
{ // Then call NetEQ to add the codec to it's database.
// Fill up the structure by calling if (codecInst.channels == 1) {
// "SET_CODEC_PAR" & "SET_PCMA_FUNCTION." // Mono mode.
// Then call NetEQ to add the codec to it's SET_CODEC_PAR(codecDef, kDecoderPCMa, codecInst.pltype, NULL, 8000);
// database. } else {
SET_CODEC_PAR((codecDef), kDecoderPCMa, codecInst.pltype, NULL, 8000); // Stereo mode.
SET_PCMA_FUNCTIONS((codecDef)); SET_CODEC_PAR(codecDef, kDecoderPCMa_2ch, codecInst.pltype, NULL, 8000);
return 0; }
SET_PCMA_FUNCTIONS(codecDef);
return 0;
} }
ACMGenericCodec* ACMPCMA::CreateInstance(void) {
ACMGenericCodec* return NULL;
ACMPCMA::CreateInstance(void)
{
return NULL;
} }
WebRtc_Word16 ACMPCMA::InternalCreateEncoder() {
WebRtc_Word16 // PCM has no instance.
ACMPCMA::InternalCreateEncoder() return 0;
{
// PCM has no instance
return 0;
} }
WebRtc_Word16 ACMPCMA::InternalCreateDecoder() {
WebRtc_Word16 // PCM has no instance.
ACMPCMA::InternalCreateDecoder() return 0;
{
// PCM has no instance
return 0;
} }
void ACMPCMA::InternalDestructEncoderInst(void* /* ptrInst */) {
void // PCM has no instance.
ACMPCMA::InternalDestructEncoderInst( return;
void* /* ptrInst */)
{
// PCM has no instance
return;
} }
void ACMPCMA::DestructEncoderSafe() {
void // PCM has no instance.
ACMPCMA::DestructEncoderSafe() return;
{
// PCM has no instance
return;
} }
void ACMPCMA::DestructDecoderSafe() {
void // PCM has no instance.
ACMPCMA::DestructDecoderSafe() _decoderInitialized = false;
{ _decoderExist = false;
// PCM has no instance return;
_decoderInitialized = false;
_decoderExist = false;
return;
} }
// Split the stereo packet and place left and right channel after each other // Split the stereo packet and place left and right channel after each other

View File

@ -8,9 +8,10 @@
* be found in the AUTHORS file in the root of the source tree. * be found in the AUTHORS file in the root of the source tree.
*/ */
#include "acm_pcmu.h"
#include "acm_common_defs.h" #include "acm_common_defs.h"
#include "acm_neteq.h" #include "acm_neteq.h"
#include "acm_pcmu.h"
#include "trace.h" #include "trace.h"
#include "webrtc_neteq.h" #include "webrtc_neteq.h"
#include "webrtc_neteq_help_macros.h" #include "webrtc_neteq_help_macros.h"
@ -18,129 +19,94 @@
// Codec interface // Codec interface
#include "g711_interface.h" #include "g711_interface.h"
namespace webrtc namespace webrtc {
{
ACMPCMU::ACMPCMU(WebRtc_Word16 codecID) ACMPCMU::ACMPCMU(WebRtc_Word16 codecID) {
{ _codecID = codecID;
_codecID = codecID;
} }
ACMPCMU::~ACMPCMU() {
ACMPCMU::~ACMPCMU() return;
{
return;
} }
WebRtc_Word16 ACMPCMU::InternalEncode(WebRtc_UWord8* bitStream,
WebRtc_Word16 WebRtc_Word16* bitStreamLenByte) {
ACMPCMU::InternalEncode( *bitStreamLenByte = WebRtcG711_EncodeU(NULL, &_inAudio[_inAudioIxRead],
WebRtc_UWord8* bitStream, _frameLenSmpl * _noChannels,
WebRtc_Word16* bitStreamLenByte) (WebRtc_Word16*) bitStream);
{ // Increment the read index this tell the caller that how far
*bitStreamLenByte = WebRtcG711_EncodeU(NULL, &_inAudio[_inAudioIxRead], // we have gone forward in reading the audio buffer.
_frameLenSmpl*_noChannels, (WebRtc_Word16*)bitStream); _inAudioIxRead += _frameLenSmpl * _noChannels;
// increment the read index this tell the caller that how far return *bitStreamLenByte;
// we have gone forward in reading the audio buffer
_inAudioIxRead += _frameLenSmpl*_noChannels;
return *bitStreamLenByte;
} }
WebRtc_Word16 ACMPCMU::DecodeSafe(WebRtc_UWord8* /* bitStream */,
WebRtc_Word16 WebRtc_Word16 /* bitStreamLenByte */,
ACMPCMU::DecodeSafe( WebRtc_Word16* /* audio */,
WebRtc_UWord8* /* bitStream */, WebRtc_Word16* /* audioSamples */,
WebRtc_Word16 /* bitStreamLenByte */, WebRtc_Word8* /* speechType */) {
WebRtc_Word16* /* audio */, return 0;
WebRtc_Word16* /* audioSamples */,
WebRtc_Word8* /* speechType */)
{
return 0;
} }
WebRtc_Word16 ACMPCMU::InternalInitEncoder(
WebRtc_Word16 WebRtcACMCodecParams* /* codecParams */) {
ACMPCMU::InternalInitEncoder( // This codec does not need initialization, PCM has no instance.
WebRtcACMCodecParams* /* codecParams */) return 0;
{
// This codec does not need initialization,
// PCM has no instance
return 0;
} }
WebRtc_Word16 ACMPCMU::InternalInitDecoder(
WebRtc_Word16 WebRtcACMCodecParams* /* codecParams */) {
ACMPCMU::InternalInitDecoder( // This codec does not need initialization, PCM has no instance.
WebRtcACMCodecParams* /* codecParams */)
{
// This codec does not need initialization,
// PCM has no instance
return 0; return 0;
} }
WebRtc_Word32 ACMPCMU::CodecDef(WebRtcNetEQ_CodecDef& codecDef,
WebRtc_Word32 const CodecInst& codecInst) {
ACMPCMU::CodecDef( // Fill up the structure by calling
WebRtcNetEQ_CodecDef& codecDef, // "SET_CODEC_PAR" & "SET_PCMU_FUNCTION."
const CodecInst& codecInst) // Then call NetEQ to add the codec to it's database.
{ if (codecInst.channels == 1) {
// Fill up the structure by calling // Mono mode.
// "SET_CODEC_PAR" & "SET_PCMU_FUNCTION." SET_CODEC_PAR(codecDef, kDecoderPCMu, codecInst.pltype, NULL, 8000);
// Then call NetEQ to add the codec to it's } else {
// database. // Stereo mode.
SET_CODEC_PAR((codecDef), kDecoderPCMu, codecInst.pltype, NULL, 8000); SET_CODEC_PAR(codecDef, kDecoderPCMu_2ch, codecInst.pltype, NULL, 8000);
SET_PCMU_FUNCTIONS((codecDef)); }
return 0; SET_PCMU_FUNCTIONS(codecDef);
return 0;
} }
ACMGenericCodec* ACMPCMU::CreateInstance(void) {
ACMGenericCodec* return NULL;
ACMPCMU::CreateInstance(void)
{
return NULL;
} }
WebRtc_Word16 ACMPCMU::InternalCreateEncoder() {
WebRtc_Word16 // PCM has no instance.
ACMPCMU::InternalCreateEncoder() return 0;
{
// PCM has no instance
return 0;
} }
WebRtc_Word16 ACMPCMU::InternalCreateDecoder() {
WebRtc_Word16 // PCM has no instance.
ACMPCMU::InternalCreateDecoder() return 0;
{
// PCM has no instance
return 0;
} }
void ACMPCMU::InternalDestructEncoderInst(void* /* ptrInst */) {
void // PCM has no instance.
ACMPCMU::InternalDestructEncoderInst( return;
void* /* ptrInst */)
{
// PCM has no instance
return;
} }
void ACMPCMU::DestructEncoderSafe() {
void // PCM has no instance.
ACMPCMU::DestructEncoderSafe() _encoderExist = false;
{ _encoderInitialized = false;
// PCM has no instance return;
_encoderExist = false;
_encoderInitialized = false;
return;
} }
void ACMPCMU::DestructDecoderSafe() void ACMPCMU::DestructDecoderSafe() {
{ // PCM has no instance.
// PCM has no instance _decoderInitialized = false;
_decoderInitialized = false; _decoderExist = false;
_decoderExist = false; return;
return;
} }
// Split the stereo packet and place left and right channel after each other // Split the stereo packet and place left and right channel after each other

View File

@ -49,67 +49,37 @@ AudioCodingModule::Codec(
return ACMCodecDB::Codec(listId, &codec); return ACMCodecDB::Codec(listId, &codec);
} }
// Get supported codec Param with name // Get supported codec Param with name, frequency and number of channels.
WebRtc_Word32 WebRtc_Word32 AudioCodingModule::Codec(const char* payload_name,
AudioCodingModule::Codec( CodecInst& codec,
const char* payloadName, int sampling_freq_hz,
CodecInst& codec, int channels) {
const WebRtc_Word32 samplingFreqHz) int codec_id;
{
// Search through codec list for a matching name
for(int codecCntr = 0; codecCntr < ACMCodecDB::kNumCodecs; codecCntr++)
{
// Store codec settings for codec number "codeCntr" in the output struct
ACMCodecDB::Codec(codecCntr, &codec);
if(!STR_CASE_CMP(codec.plname, payloadName)) // Get the id of the codec from the database.
{ codec_id = ACMCodecDB::CodecId(payload_name, sampling_freq_hz, channels);
// If samplingFreqHz is set (!= -1), check if frequency matches if (codec_id < 0) {
if((samplingFreqHz == codec.plfreq) || (samplingFreqHz == -1)) // We couldn't find a matching codec, set the parameterss to unacceptable
{ // values and return.
// We found a match, return OK
return 0;
}
}
}
// if we are here we couldn't find anything
// set the params to unacceptable values
codec.plname[0] = '\0'; codec.plname[0] = '\0';
codec.pltype = -1; codec.pltype = -1;
codec.pacsize = 0; codec.pacsize = 0;
codec.rate = 0; codec.rate = 0;
codec.plfreq = 0; codec.plfreq = 0;
return -1; return -1;
}
// Get default codec settings.
ACMCodecDB::Codec(codec_id, &codec);
return 0;
} }
// Get supported codec Index with name, and frequency if needed // Get supported codec Index with name, frequency and number of channels.
WebRtc_Word32 WebRtc_Word32 AudioCodingModule::Codec(const char* payload_name,
AudioCodingModule::Codec( int sampling_freq_hz,
const char* payloadName, int channels) {
const WebRtc_Word32 samplingFreqHz) return ACMCodecDB::CodecId(payload_name, sampling_freq_hz, channels);
{
CodecInst codec;
// Search through codec list for a matching name
for(int codecCntr = 0; codecCntr < ACMCodecDB::kNumCodecs; codecCntr++)
{
// Temporally store codec settings for codec number "codeCntr" in "codec"
ACMCodecDB::Codec(codecCntr, &codec);
if(!STR_CASE_CMP(codec.plname, payloadName))
{
// If samplingFreqHz is set (!= -1), check if frequency matches
if((samplingFreqHz == codec.plfreq) || (samplingFreqHz == -1))
{
// We found a match, return codec list number (index)
return codecCntr;
}
}
}
// We did not find a matching codec in the list
return -1;
} }
// Checks the validity of the parameters of the given codec // Checks the validity of the parameters of the given codec

View File

@ -978,14 +978,14 @@ WebRtc_Word32 AudioCodingModuleImpl::Add10MsData(
// either mono-to-stereo or stereo-to-mono conversion. // either mono-to-stereo or stereo-to-mono conversion.
WebRtc_Word16 audio[WEBRTC_10MS_PCM_AUDIO]; WebRtc_Word16 audio[WEBRTC_10MS_PCM_AUDIO];
int audio_channels = _sendCodecInst.channels; int audio_channels = _sendCodecInst.channels;
if (audio_frame.num_channels_ != _sendCodecInst.channels) { if (audio_frame.num_channels_ != audio_channels) {
if (_sendCodecInst.channels == 2) { if (audio_channels == 2) {
// Do mono-to-stereo conversion by copying each sample. // Do mono-to-stereo conversion by copying each sample.
for (int k = 0; k < audio_frame.samples_per_channel_; k++) { for (int k = 0; k < audio_frame.samples_per_channel_; k++) {
audio[k * 2] = audio_frame.data_[k]; audio[k * 2] = audio_frame.data_[k];
audio[(k * 2) + 1] = audio_frame.data_[k]; audio[(k * 2) + 1] = audio_frame.data_[k];
} }
} else if (_sendCodecInst.channels == 1) { } else if (audio_channels == 1) {
// Do stereo-to-mono conversion by creating the average of the stereo // Do stereo-to-mono conversion by creating the average of the stereo
// samples. // samples.
for (int k = 0; k < audio_frame.samples_per_channel_; k++) { for (int k = 0; k < audio_frame.samples_per_channel_; k++) {

View File

@ -1495,11 +1495,11 @@ APITest::ChangeCodec(char side)
Wait(1000); Wait(1000);
// After Initialization CN is lost, re-register them // After Initialization CN is lost, re-register them
if(AudioCodingModule::Codec("CN", myCodec, 8000) >= 0) if(AudioCodingModule::Codec("CN", myCodec, 8000, 1) >= 0)
{ {
CHECK_ERROR_MT(myACM->RegisterSendCodec(myCodec)); CHECK_ERROR_MT(myACM->RegisterSendCodec(myCodec));
} }
if(AudioCodingModule::Codec("CN", myCodec, 16000) >= 0) if(AudioCodingModule::Codec("CN", myCodec, 16000, 1) >= 0)
{ {
CHECK_ERROR_MT(myACM->RegisterSendCodec(myCodec)); CHECK_ERROR_MT(myACM->RegisterSendCodec(myCodec));
} }

View File

@ -149,9 +149,6 @@ void Receiver::Setup(AudioCodingModule *acm, RTPStream *rtpStream) {
noOfCodecs = acm->NumberOfCodecs(); noOfCodecs = acm->NumberOfCodecs();
for (int i = 0; i < noOfCodecs; i++) { for (int i = 0; i < noOfCodecs; i++) {
acm->Codec((WebRtc_UWord8) i, recvCodec); acm->Codec((WebRtc_UWord8) i, recvCodec);
if (!strcmp(recvCodec.plname, "CELT")) {
recvCodec.channels = 1;
}
if (acm->RegisterReceiveCodec(recvCodec) != 0) { if (acm->RegisterReceiveCodec(recvCodec) != 0) {
printf("Unable to register codec: for run: codecId: %d\n", codeId); printf("Unable to register codec: for run: codecId: %d\n", codeId);
exit(1); exit(1);
@ -220,7 +217,6 @@ bool Receiver::IncomingPacket() {
if (ok != 0) { if (ok != 0) {
printf("Error when inserting packet to ACM, for run: codecId: %d\n", printf("Error when inserting packet to ACM, for run: codecId: %d\n",
codeId); codeId);
exit(1);
} }
_realPayloadSizeBytes = _rtpStream->Read(&_rtpInfo, _incomingPayload, _realPayloadSizeBytes = _rtpStream->Read(&_rtpInfo, _incomingPayload,
_payloadSizeBytes, &_nextTime); _payloadSizeBytes, &_nextTime);
@ -296,20 +292,24 @@ void EncodeDecodeTest::Perform() {
} }
int numCodecs = 1; int numCodecs = 1;
int codePars[3]; //freq, pacsize, rate int codePars[3]; // Frequency, packet size, rate.
int numPars[52]; //number of codec parameters sets (rate,freq,pacsize)to test, int numPars[52]; // Number of codec parameters sets (freq, pacsize, rate)
//for a given codec // to test, for a given codec.
codePars[0] = 0; codePars[0] = 0;
codePars[1] = 0; codePars[1] = 0;
codePars[2] = 0; codePars[2] = 0;
AudioCodingModule *acmTmp = AudioCodingModule::Create(0);
struct CodecInst sendCodecTmp;
numCodecs = acmTmp->NumberOfCodecs();
AudioCodingModule::Destroy(acmTmp);
if (_testMode == 1) { if (_testMode == 1) {
AudioCodingModule *acmTmp = AudioCodingModule::Create(0);
struct CodecInst sendCodecTmp;
numCodecs = acmTmp->NumberOfCodecs();
printf("List of supported codec.\n"); printf("List of supported codec.\n");
for(int n = 0; n < numCodecs; n++) { }
if (_testMode != 2) {
for (int n = 0; n < numCodecs; n++) {
acmTmp->Codec(n, sendCodecTmp); acmTmp->Codec(n, sendCodecTmp);
if (STR_CASE_CMP(sendCodecTmp.plname, "telephone-event") == 0) { if (STR_CASE_CMP(sendCodecTmp.plname, "telephone-event") == 0) {
numPars[n] = 0; numPars[n] = 0;
@ -317,28 +317,13 @@ void EncodeDecodeTest::Perform() {
numPars[n] = 0; numPars[n] = 0;
} else if (STR_CASE_CMP(sendCodecTmp.plname, "red") == 0) { } else if (STR_CASE_CMP(sendCodecTmp.plname, "red") == 0) {
numPars[n] = 0; numPars[n] = 0;
} else if (sendCodecTmp.channels == 2) {
numPars[n] = 0;
} else { } else {
numPars[n] = 1; numPars[n] = 1;
printf("%d %s\n", n, sendCodecTmp.plname); if (_testMode == 1) {
} printf("%d %s\n", n, sendCodecTmp.plname);
} }
AudioCodingModule::Destroy(acmTmp);
} else if (_testMode == 0) {
AudioCodingModule *acmTmp = AudioCodingModule::Create(0);
numCodecs = acmTmp->NumberOfCodecs();
AudioCodingModule::Destroy(acmTmp);
struct CodecInst dummyCodec;
//chose range of testing for codecs/parameters
for(int i = 0 ; i < numCodecs ; i++) {
numPars[i] = 1;
acmTmp->Codec(i, dummyCodec);
if (STR_CASE_CMP(dummyCodec.plname, "telephone-event") == 0) {
numPars[i] = 0;
} else if (STR_CASE_CMP(dummyCodec.plname, "cn") == 0) {
numPars[i] = 0;
} else if (STR_CASE_CMP(dummyCodec.plname, "red") == 0) {
numPars[i] = 0;
} }
} }
} else { } else {
@ -348,9 +333,9 @@ void EncodeDecodeTest::Perform() {
_receiver.testMode = _testMode; _receiver.testMode = _testMode;
//loop over all codecs: // Loop over all mono codecs:
for (int codeId = 0; codeId < numCodecs; codeId++) { for (int codeId = 0; codeId < numCodecs; codeId++) {
//only encode using real encoders, not telephone-event anc cn // Only encode using real mono encoders, not telephone-event and cng.
for (int loopPars = 1; loopPars <= numPars[codeId]; loopPars++) { for (int loopPars = 1; loopPars <= numPars[codeId]; loopPars++) {
if (_testMode == 1) { if (_testMode == 1) {
printf("\n"); printf("\n");

View File

@ -784,7 +784,8 @@ WebRtc_Word16 TestAllCodecs::RegisterSendCodec(char side,
CodecInst myCodecParam; CodecInst myCodecParam;
// Get all codec paramters before registering // Get all codec paramters before registering
CHECK_ERROR(AudioCodingModule::Codec(codecName, myCodecParam, samplingFreqHz)); CHECK_ERROR(AudioCodingModule::Codec(codecName, myCodecParam,
samplingFreqHz, 1));
myCodecParam.rate = rate; myCodecParam.rate = rate;
myCodecParam.pacsize = packSize; myCodecParam.pacsize = packSize;
CHECK_ERROR(myACM->RegisterSendCodec(myCodecParam)); CHECK_ERROR(myACM->RegisterSendCodec(myCodecParam));

View File

@ -553,7 +553,8 @@ WebRtc_Word16 TestFEC::RegisterSendCodec(char side, char* codecName, WebRtc_Word
} }
CodecInst myCodecParam; CodecInst myCodecParam;
CHECK_ERROR(AudioCodingModule::Codec(codecName, myCodecParam, samplingFreqHz)); CHECK_ERROR(AudioCodingModule::Codec(codecName, myCodecParam,
samplingFreqHz, 1));
CHECK_ERROR(myACM->RegisterSendCodec(myCodecParam)); CHECK_ERROR(myACM->RegisterSendCodec(myCodecParam));

View File

@ -69,7 +69,7 @@ WebRtc_Word32 TestPackStereo::SendData(
rtp_info.type.Audio.channel = (int) kMono; rtp_info.type.Audio.channel = (int) kMono;
} }
status = receiver_acm_->IncomingPacket(payload_data, payload_size, status = receiver_acm_->IncomingPacket(payload_data, payload_size,
rtp_info); rtp_info);
if (frame_type != kAudioFrameCN) { if (frame_type != kAudioFrameCN) {
payload_size_ = payload_size; payload_size_ = payload_size;
@ -122,7 +122,7 @@ TestStereo::TestStereo(int test_mode)
cn_8khz_pltype_(-1), cn_8khz_pltype_(-1),
cn_16khz_pltype_(-1), cn_16khz_pltype_(-1),
cn_32khz_pltype_(-1) { cn_32khz_pltype_(-1) {
// testMode = 0 for silent test (auto test) // test_mode = 0 for silent test (auto test)
test_mode_ = test_mode; test_mode_ = test_mode;
} }
@ -155,57 +155,49 @@ void TestStereo::Perform() {
"---------- TestStereo ----------"); "---------- TestStereo ----------");
} }
// Open both mono and stereo test files in 32 kHz.
strcpy(file_name_stereo, "./data/audio_coding/teststereo32kHz.pcm"); strcpy(file_name_stereo, "./data/audio_coding/teststereo32kHz.pcm");
strcpy(file_name_mono, "./data/audio_coding/testfile32kHz.pcm"); strcpy(file_name_mono, "./data/audio_coding/testfile32kHz.pcm");
frequency_hz = 32000;
frequency_hz = 32000;
in_file_stereo_ = new PCMFile(); in_file_stereo_ = new PCMFile();
in_file_mono_ = new PCMFile(); in_file_mono_ = new PCMFile();
in_file_stereo_->Open(file_name_stereo, frequency_hz, "rb"); in_file_stereo_->Open(file_name_stereo, frequency_hz, "rb");
in_file_stereo_->ReadStereo(true); in_file_stereo_->ReadStereo(true);
in_file_mono_->Open(file_name_mono, frequency_hz, "rb"); in_file_mono_->Open(file_name_mono, frequency_hz, "rb");
in_file_mono_->ReadStereo(false); in_file_mono_->ReadStereo(false);
// Create and initialize two ACMs, one for each side of a one-to-one call.
acm_a_ = AudioCodingModule::Create(0); acm_a_ = AudioCodingModule::Create(0);
acm_b_ = AudioCodingModule::Create(1); acm_b_ = AudioCodingModule::Create(1);
if ((acm_a_ == NULL) || (acm_b_ == NULL)) {
acm_a_->InitializeReceiver(); printf("Failed to create ACM.");
acm_b_->InitializeReceiver(); }
status = acm_a_->InitializeReceiver();
WebRtc_UWord8 num_encoders = acm_a_->NumberOfCodecs(); if (status < 0) {
CodecInst my_codec_param; printf("Error in InitializeReceiver()");
}
// Register receiving codecs, some of them as stereo. status = acm_b_->InitializeReceiver();
for (WebRtc_UWord8 n = 0; n < num_encoders; n++) { if (status < 0) {
acm_b_->Codec(n, my_codec_param); printf("Error in InitializeReceiver()");
if (!strcmp(my_codec_param.plname, "L16")) {
if (my_codec_param.plfreq == 8000) {
l16_8khz_pltype_ = my_codec_param.pltype;
} else if (my_codec_param.plfreq == 16000) {
l16_16khz_pltype_ = my_codec_param.pltype;
} else if (my_codec_param.plfreq == 32000) {
l16_32khz_pltype_ = my_codec_param.pltype;
}
my_codec_param.channels = 2;
} else if (!strcmp(my_codec_param.plname, "PCMA")) {
pcma_pltype_ = my_codec_param.pltype;
my_codec_param.channels = 2;
} else if (!strcmp(my_codec_param.plname, "PCMU")) {
pcmu_pltype_ = my_codec_param.pltype;
my_codec_param.channels = 2;
} else if (!strcmp(my_codec_param.plname, "G722")) {
g722_pltype_ = my_codec_param.pltype;
my_codec_param.channels = 2;
} else if (!strcmp(my_codec_param.plname, "CELT")) {
celt_pltype_ = my_codec_param.pltype;
my_codec_param.channels = 2;
}
acm_b_->RegisterReceiveCodec(my_codec_param);
} }
// Test that unregister all receive codecs works for stereo. // Register all available codes as receiving codecs.
WebRtc_UWord8 num_encoders = acm_a_->NumberOfCodecs();
CodecInst my_codec_param;
for (WebRtc_UWord8 n = 0; n < num_encoders; n++) {
status = acm_b_->Codec(n, my_codec_param);
if (status < 0) {
printf("Error in Codec(), no matching codec found");
}
status = acm_b_->RegisterReceiveCodec(my_codec_param);
if (status < 0) {
printf("Error in RegisterReceiveCodec() for payload type %d",
my_codec_param.pltype);
}
}
// Test that unregister all receive codecs works.
for (WebRtc_UWord8 n = 0; n < num_encoders; n++) { for (WebRtc_UWord8 n = 0; n < num_encoders; n++) {
status = acm_b_->Codec(n, my_codec_param); status = acm_b_->Codec(n, my_codec_param);
if (status < 0) { if (status < 0) {
@ -218,97 +210,40 @@ void TestStereo::Perform() {
} }
} }
// Register receiving mono codecs, except comfort noise. // Register all available codes as receiving codecs once more.
for (WebRtc_UWord8 n = 0; n < num_encoders; n++) { for (WebRtc_UWord8 n = 0; n < num_encoders; n++) {
status = acm_b_->Codec(n, my_codec_param); status = acm_b_->Codec(n, my_codec_param);
if (status < 0) { if (status < 0) {
printf("Error in Codec(), no matching codec found"); printf("Error in Codec(), no matching codec found");
} }
if (!strcmp(my_codec_param.plname, "L16") status = acm_b_->RegisterReceiveCodec(my_codec_param);
|| !strcmp(my_codec_param.plname, "PCMA") if (status < 0) {
|| !strcmp(my_codec_param.plname, "PCMU") printf("Error in RegisterReceiveCodec() for payload type %d",
|| !strcmp(my_codec_param.plname, "G722") my_codec_param.pltype);
|| !strcmp(my_codec_param.plname, "CELT")
|| !strcmp(my_codec_param.plname, "CN")) {
} else {
status = acm_b_->RegisterReceiveCodec(my_codec_param);
if (status < 0) {
printf("Error in UnregisterReceiveCodec() for codec number %d", n);
}
} }
} }
// TODO(tlegrand): Take care of return values of all function calls. // TODO(tlegrand): Take care of return values of all function calls.
// Re-register all stereo codecs needed in the test, with new payload
// numbers.
g722_pltype_ = 117;
l16_8khz_pltype_ = 120;
l16_16khz_pltype_ = 121;
l16_32khz_pltype_ = 122;
pcma_pltype_ = 110;
pcmu_pltype_ = 118;
celt_pltype_ = 119;
cn_8khz_pltype_ = 123;
cn_16khz_pltype_ = 124;
cn_32khz_pltype_ = 125;
// Register all stereo codecs with new payload types. // TODO(tlegrand): Re-register all stereo codecs needed in the test,
#ifdef WEBRTC_CODEC_G722 // with new payload numbers.
// G722 // g722_pltype_ = 117;
acm_b_->Codec("G722", my_codec_param, 16000); // l16_8khz_pltype_ = 120;
my_codec_param.pltype = g722_pltype_; // l16_16khz_pltype_ = 121;
my_codec_param.channels = 2; // l16_32khz_pltype_ = 122;
acm_b_->RegisterReceiveCodec(my_codec_param); // pcma_pltype_ = 110;
#endif // pcmu_pltype_ = 118;
#ifdef WEBRTC_CODEC_PCM16 // celt_pltype_ = 119;
// L16 // cn_8khz_pltype_ = 123;
acm_b_->Codec("L16", my_codec_param, 8000); // cn_16khz_pltype_ = 124;
my_codec_param.pltype = l16_8khz_pltype_; // cn_32khz_pltype_ = 125;
my_codec_param.channels = 2;
acm_b_->RegisterReceiveCodec(my_codec_param);
acm_b_->Codec("L16", my_codec_param, 16000);
my_codec_param.pltype = l16_16khz_pltype_;
my_codec_param.channels = 2;
acm_b_->RegisterReceiveCodec(my_codec_param);
acm_b_->Codec("L16", my_codec_param, 32000);
my_codec_param.pltype = l16_32khz_pltype_;
my_codec_param.channels = 2;
acm_b_->RegisterReceiveCodec(my_codec_param);
#endif
// PCM Alaw and u-law
acm_b_->Codec("PCMA", my_codec_param, 8000);
my_codec_param.pltype = pcma_pltype_;
my_codec_param.channels = 2;
acm_b_->RegisterReceiveCodec(my_codec_param);
acm_b_->Codec("PCMU", my_codec_param, 8000);
my_codec_param.pltype = pcmu_pltype_;
my_codec_param.channels = 2;
acm_b_->RegisterReceiveCodec(my_codec_param);
#ifdef WEBRTC_CODEC_CELT
// Celt
acm_b_->Codec("CELT", my_codec_param, 32000);
my_codec_param.pltype = celt_pltype_;
my_codec_param.channels = 2;
acm_b_->RegisterReceiveCodec(my_codec_param);
#endif
// Register CNG with new payload type on both send and receive side.
acm_b_->Codec("CN", my_codec_param, 8000);
my_codec_param.pltype = cn_8khz_pltype_;
acm_a_->RegisterSendCodec(my_codec_param);
acm_b_->RegisterReceiveCodec(my_codec_param);
acm_b_->Codec("CN", my_codec_param, 16000);
my_codec_param.pltype = cn_16khz_pltype_;
acm_a_->RegisterSendCodec(my_codec_param);
acm_b_->RegisterReceiveCodec(my_codec_param);
acm_b_->Codec("CN", my_codec_param, 32000);
my_codec_param.pltype = cn_32khz_pltype_;
acm_a_->RegisterSendCodec(my_codec_param);
acm_b_->RegisterReceiveCodec(my_codec_param);
// Create and connect the channel. // Create and connect the channel.
channel_a2b_ = new TestPackStereo; channel_a2b_ = new TestPackStereo;
acm_a_->RegisterTransportCallback(channel_a2b_); status = acm_a_->RegisterTransportCallback(channel_a2b_);
if (status < 0) {
printf("Failed to register transport callback.");
}
channel_a2b_->RegisterReceiverACM(acm_b_); channel_a2b_->RegisterReceiverACM(acm_b_);
// //
@ -636,29 +571,6 @@ void TestStereo::Perform() {
codec_channels = 1; codec_channels = 1;
channel_a2b_->set_codec_mode(kMono); channel_a2b_->set_codec_mode(kMono);
// Register receivers as mono.
for (WebRtc_UWord8 n = 0; n < num_encoders; n++) {
acm_b_->Codec(n, my_codec_param);
if (!strcmp(my_codec_param.plname, "L16")) {
if (my_codec_param.plfreq == 8000) {
my_codec_param.pltype = l16_8khz_pltype_;
} else if (my_codec_param.plfreq == 16000) {
my_codec_param.pltype = l16_16khz_pltype_;
} else if (my_codec_param.plfreq == 32000) {
my_codec_param.pltype = l16_32khz_pltype_;
}
} else if (!strcmp(my_codec_param.plname, "PCMA")) {
my_codec_param.pltype = pcma_pltype_;
} else if (!strcmp(my_codec_param.plname, "PCMU")) {
my_codec_param.pltype = pcmu_pltype_;
} else if (!strcmp(my_codec_param.plname, "G722")) {
my_codec_param.pltype = g722_pltype_;
} else if (!strcmp(my_codec_param.plname, "CELT")) {
my_codec_param.pltype = celt_pltype_;
my_codec_param.channels = 1;
}
acm_b_->RegisterReceiveCodec(my_codec_param);
}
#ifdef WEBRTC_CODEC_G722 #ifdef WEBRTC_CODEC_G722
// Run stereo audio and mono codec. // Run stereo audio and mono codec.
if(test_mode_ != 0) { if(test_mode_ != 0) {
@ -818,11 +730,11 @@ WebRtc_Word16 TestStereo::RegisterSendCodec(char side, char* codec_name,
CodecInst my_codec_param; CodecInst my_codec_param;
// Get all codec parameters before registering // Get all codec parameters before registering
CHECK_ERROR(AudioCodingModule::Codec(codec_name, my_codec_param, CHECK_ERROR(AudioCodingModule::Codec(codec_name, my_codec_param,
sampling_freq_hz)); sampling_freq_hz, channels));
my_codec_param.rate = rate; my_codec_param.rate = rate;
my_codec_param.pacsize = pack_size; my_codec_param.pacsize = pack_size;
my_codec_param.pltype = payload_type; // my_codec_param.pltype = payload_type;
my_codec_param.channels = channels; // my_codec_param.channels = channels;
CHECK_ERROR(my_acm->RegisterSendCodec(my_codec_param)); CHECK_ERROR(my_acm->RegisterSendCodec(my_codec_param));
// Initialization was successful. // Initialization was successful.

View File

@ -278,8 +278,8 @@ WebRtc_Word16 TwoWayCommunication::SetUpAutotest()
CodecInst codecInst_B; CodecInst codecInst_B;
CodecInst dummyCodec; CodecInst dummyCodec;
_acmA->Codec("ISAC", codecInst_A, 16000); _acmA->Codec("ISAC", codecInst_A, 16000, 1);
_acmB->Codec("L16", codecInst_B, 8000); _acmB->Codec("L16", codecInst_B, 8000, 1);
_acmA->Codec(6, dummyCodec); _acmA->Codec(6, dummyCodec);
//--- Set A codecs //--- Set A codecs
@ -445,7 +445,7 @@ TwoWayCommunication::Perform()
if(_testMode == 0) if(_testMode == 0)
{ {
WEBRTC_TRACE(kTraceStateInfo, kTraceAudioCoding, -1, WEBRTC_TRACE(kTraceStateInfo, kTraceAudioCoding, -1,
"---------- Errors epected"); "---------- Errors expected");
printf("."); printf(".");
} }
else else
@ -460,7 +460,7 @@ TwoWayCommunication::Perform()
if(_testMode == 0) if(_testMode == 0)
{ {
WEBRTC_TRACE(kTraceStateInfo, kTraceAudioCoding, -1, WEBRTC_TRACE(kTraceStateInfo, kTraceAudioCoding, -1,
"----- END: Errors epected"); "----- END: Errors expected");
printf("."); printf(".");
} }
else else
@ -478,7 +478,7 @@ TwoWayCommunication::Perform()
if(_testMode == 0) if(_testMode == 0)
{ {
WEBRTC_TRACE(kTraceStateInfo, kTraceAudioCoding, -1, WEBRTC_TRACE(kTraceStateInfo, kTraceAudioCoding, -1,
"---------- Errors epected"); "---------- Errors expected");
printf("."); printf(".");
} }
else else
@ -494,7 +494,7 @@ TwoWayCommunication::Perform()
if(_testMode == 0) if(_testMode == 0)
{ {
WEBRTC_TRACE(kTraceStateInfo, kTraceAudioCoding, -1, WEBRTC_TRACE(kTraceStateInfo, kTraceAudioCoding, -1,
"----- END: Errors epected"); "----- END: Errors expected");
printf("."); printf(".");
} }
else else

View File

@ -97,10 +97,13 @@ int WebRtcNetEQ_DbAdd(CodecDbInst_t *inst, enum WebRtcNetEQDecoder codec,
{ {
#ifdef NETEQ_PCM16B_CODEC #ifdef NETEQ_PCM16B_CODEC
case kDecoderPCM16B : case kDecoderPCM16B :
case kDecoderPCM16B_2ch :
#endif #endif
#ifdef NETEQ_G711_CODEC #ifdef NETEQ_G711_CODEC
case kDecoderPCMu : case kDecoderPCMu :
case kDecoderPCMa : case kDecoderPCMa :
case kDecoderPCMu_2ch :
case kDecoderPCMa_2ch :
#endif #endif
#ifdef NETEQ_ILBC_CODEC #ifdef NETEQ_ILBC_CODEC
case kDecoderILBC : case kDecoderILBC :
@ -113,12 +116,15 @@ int WebRtcNetEQ_DbAdd(CodecDbInst_t *inst, enum WebRtcNetEQDecoder codec,
#endif #endif
#ifdef NETEQ_G722_CODEC #ifdef NETEQ_G722_CODEC
case kDecoderG722 : case kDecoderG722 :
case kDecoderG722_2ch :
#endif #endif
#ifdef NETEQ_WIDEBAND #ifdef NETEQ_WIDEBAND
case kDecoderPCM16Bwb : case kDecoderPCM16Bwb :
case kDecoderPCM16Bwb_2ch :
#endif #endif
#ifdef NETEQ_32KHZ_WIDEBAND #ifdef NETEQ_32KHZ_WIDEBAND
case kDecoderPCM16Bswb32kHz : case kDecoderPCM16Bswb32kHz :
case kDecoderPCM16Bswb32kHz_2ch :
#endif #endif
#ifdef NETEQ_CNG_CODEC #ifdef NETEQ_CNG_CODEC
case kDecoderCNG : case kDecoderCNG :
@ -163,6 +169,7 @@ int WebRtcNetEQ_DbAdd(CodecDbInst_t *inst, enum WebRtcNetEQDecoder codec,
#endif #endif
#ifdef NETEQ_CELT_CODEC #ifdef NETEQ_CELT_CODEC
case kDecoderCELT_32 : case kDecoderCELT_32 :
case kDecoderCELT_32_2ch :
#endif #endif
#ifdef NETEQ_GSMFR_CODEC #ifdef NETEQ_GSMFR_CODEC
case kDecoderGSMFR : case kDecoderGSMFR :
@ -473,6 +480,7 @@ int WebRtcNetEQ_DbGetSplitInfo(SplitInfo_t *inst, enum WebRtcNetEQDecoder codecI
#endif #endif
#ifdef NETEQ_CELT_CODEC #ifdef NETEQ_CELT_CODEC
case kDecoderCELT_32 : case kDecoderCELT_32 :
case kDecoderCELT_32_2ch :
#endif #endif
#ifdef NETEQ_G729_1_CODEC #ifdef NETEQ_G729_1_CODEC
case kDecoderG729_1: case kDecoderG729_1:
@ -491,6 +499,8 @@ int WebRtcNetEQ_DbGetSplitInfo(SplitInfo_t *inst, enum WebRtcNetEQDecoder codecI
#if (defined NETEQ_G711_CODEC) #if (defined NETEQ_G711_CODEC)
case kDecoderPCMu: case kDecoderPCMu:
case kDecoderPCMa: case kDecoderPCMa:
case kDecoderPCMu_2ch:
case kDecoderPCMa_2ch:
{ {
inst->deltaBytes = -12; inst->deltaBytes = -12;
inst->deltaTime = 1; inst->deltaTime = 1;
@ -499,6 +509,7 @@ int WebRtcNetEQ_DbGetSplitInfo(SplitInfo_t *inst, enum WebRtcNetEQDecoder codecI
#endif #endif
#if (defined NETEQ_G722_CODEC) #if (defined NETEQ_G722_CODEC)
case kDecoderG722: case kDecoderG722:
case kDecoderG722_2ch:
{ {
inst->deltaBytes = -14; inst->deltaBytes = -14;
inst->deltaTime = 0; inst->deltaTime = 0;
@ -507,6 +518,7 @@ int WebRtcNetEQ_DbGetSplitInfo(SplitInfo_t *inst, enum WebRtcNetEQDecoder codecI
#endif #endif
#if (defined NETEQ_PCM16B_CODEC) #if (defined NETEQ_PCM16B_CODEC)
case kDecoderPCM16B: case kDecoderPCM16B:
case kDecoderPCM16B_2ch:
{ {
inst->deltaBytes = -12; inst->deltaBytes = -12;
inst->deltaTime = 2; inst->deltaTime = 2;
@ -515,6 +527,7 @@ int WebRtcNetEQ_DbGetSplitInfo(SplitInfo_t *inst, enum WebRtcNetEQDecoder codecI
#endif #endif
#if ((defined NETEQ_PCM16B_CODEC)&&(defined NETEQ_WIDEBAND)) #if ((defined NETEQ_PCM16B_CODEC)&&(defined NETEQ_WIDEBAND))
case kDecoderPCM16Bwb: case kDecoderPCM16Bwb:
case kDecoderPCM16Bwb_2ch:
{ {
inst->deltaBytes = -14; inst->deltaBytes = -14;
inst->deltaTime = 2; inst->deltaTime = 2;
@ -523,6 +536,7 @@ int WebRtcNetEQ_DbGetSplitInfo(SplitInfo_t *inst, enum WebRtcNetEQDecoder codecI
#endif #endif
#if ((defined NETEQ_PCM16B_CODEC)&&(defined NETEQ_32KHZ_WIDEBAND)) #if ((defined NETEQ_PCM16B_CODEC)&&(defined NETEQ_32KHZ_WIDEBAND))
case kDecoderPCM16Bswb32kHz: case kDecoderPCM16Bswb32kHz:
case kDecoderPCM16Bswb32kHz_2ch:
{ {
inst->deltaBytes = -18; inst->deltaBytes = -18;
inst->deltaTime = 2; inst->deltaTime = 2;

View File

@ -32,6 +32,8 @@ enum WebRtcNetEQDecoder
kDecoderReservedStart, kDecoderReservedStart,
kDecoderPCMu, kDecoderPCMu,
kDecoderPCMa, kDecoderPCMa,
kDecoderPCMu_2ch,
kDecoderPCMa_2ch,
kDecoderILBC, kDecoderILBC,
kDecoderISAC, kDecoderISAC,
kDecoderISACswb, kDecoderISACswb,
@ -39,7 +41,11 @@ enum WebRtcNetEQDecoder
kDecoderPCM16Bwb, kDecoderPCM16Bwb,
kDecoderPCM16Bswb32kHz, kDecoderPCM16Bswb32kHz,
kDecoderPCM16Bswb48kHz, kDecoderPCM16Bswb48kHz,
kDecoderPCM16B_2ch,
kDecoderPCM16Bwb_2ch,
kDecoderPCM16Bswb32kHz_2ch,
kDecoderG722, kDecoderG722,
kDecoderG722_2ch,
kDecoderRED, kDecoderRED,
kDecoderAVT, kDecoderAVT,
kDecoderCNG, kDecoderCNG,
@ -59,6 +65,7 @@ enum WebRtcNetEQDecoder
kDecoderSPEEX_8, kDecoderSPEEX_8,
kDecoderSPEEX_16, kDecoderSPEEX_16,
kDecoderCELT_32, kDecoderCELT_32,
kDecoderCELT_32_2ch,
kDecoderGSMFR, kDecoderGSMFR,
kDecoderAMR, kDecoderAMR,
kDecoderAMRWB, kDecoderAMRWB,

View File

@ -543,12 +543,13 @@ int WebRtcNetEQ_GetDefaultCodecSettings(const enum WebRtcNetEQDecoder *codecID,
{ {
/* Find current codec and set parameters accordingly */ /* Find current codec and set parameters accordingly */
if (codecID[i] == kDecoderPCMu) if ((codecID[i] == kDecoderPCMu) || (codecID[i] == kDecoderPCMu_2ch))
{ {
codecBytes = 1680; /* Up to 210ms @ 64kbps */ codecBytes = 1680; /* Up to 210ms @ 64kbps */
codecBuffers = 30; /* Down to 5ms frames */ codecBuffers = 30; /* Down to 5ms frames */
} }
else if (codecID[i] == kDecoderPCMa) else if ((codecID[i] == kDecoderPCMa) ||
(codecID[i] == kDecoderPCMa_2ch))
{ {
codecBytes = 1680; /* Up to 210ms @ 64kbps */ codecBytes = 1680; /* Up to 210ms @ 64kbps */
codecBuffers = 30; /* Down to 5ms frames */ codecBuffers = 30; /* Down to 5ms frames */
@ -568,17 +569,20 @@ int WebRtcNetEQ_GetDefaultCodecSettings(const enum WebRtcNetEQDecoder *codecID,
codecBytes = 1560; /* 240ms @ 52kbps (30ms frames) */ codecBytes = 1560; /* 240ms @ 52kbps (30ms frames) */
codecBuffers = 8; codecBuffers = 8;
} }
else if (codecID[i] == kDecoderPCM16B) else if ((codecID[i] == kDecoderPCM16B) ||
(codecID[i] == kDecoderPCM16B_2ch))
{ {
codecBytes = 3360; /* 210ms */ codecBytes = 3360; /* 210ms */
codecBuffers = 15; codecBuffers = 15;
} }
else if (codecID[i] == kDecoderPCM16Bwb) else if ((codecID[i] == kDecoderPCM16Bwb) ||
(codecID[i] == kDecoderPCM16Bwb_2ch))
{ {
codecBytes = 6720; /* 210ms */ codecBytes = 6720; /* 210ms */
codecBuffers = 15; codecBuffers = 15;
} }
else if (codecID[i] == kDecoderPCM16Bswb32kHz) else if ((codecID[i] == kDecoderPCM16Bswb32kHz) ||
(codecID[i] == kDecoderPCM16Bswb32kHz_2ch))
{ {
codecBytes = 13440; /* 210ms */ codecBytes = 13440; /* 210ms */
codecBuffers = 15; codecBuffers = 15;
@ -588,7 +592,8 @@ int WebRtcNetEQ_GetDefaultCodecSettings(const enum WebRtcNetEQDecoder *codecID,
codecBytes = 20160; /* 210ms */ codecBytes = 20160; /* 210ms */
codecBuffers = 15; codecBuffers = 15;
} }
else if (codecID[i] == kDecoderG722) else if ((codecID[i] == kDecoderG722) ||
(codecID[i] == kDecoderG722_2ch))
{ {
codecBytes = 1680; /* 210ms @ 64kbps */ codecBytes = 1680; /* 210ms @ 64kbps */
codecBuffers = 15; codecBuffers = 15;
@ -678,7 +683,8 @@ int WebRtcNetEQ_GetDefaultCodecSettings(const enum WebRtcNetEQDecoder *codecID,
codecBytes = 1250; /* 210ms @ 50kbps */ codecBytes = 1250; /* 210ms @ 50kbps */
codecBuffers = 10; codecBuffers = 10;
} }
else if (codecID[i] == kDecoderCELT_32) else if ((codecID[i] == kDecoderCELT_32) ||
(codecID[i] == kDecoderCELT_32_2ch))
{ {
codecBytes = 1250; /* 210ms @ 50kbps */ codecBytes = 1250; /* 210ms @ 50kbps */
codecBuffers = 10; codecBuffers = 10;

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
* *
* Use of this source code is governed by a BSD-style license * 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 * that can be found in the LICENSE file in the root of the source
@ -364,6 +364,7 @@ int WebRtcNetEQ_GetTimestampScaling(MCUInst_t *MCU_inst, int rtpPayloadType)
switch (codec) switch (codec)
{ {
case kDecoderG722: case kDecoderG722:
case kDecoderG722_2ch:
{ {
/* Use timestamp scaling with factor 2 (two output samples per RTP timestamp) */ /* Use timestamp scaling with factor 2 (two output samples per RTP timestamp) */
MCU_inst->scalingFactor = kTSscalingTwo; MCU_inst->scalingFactor = kTSscalingTwo;

View File

@ -358,7 +358,8 @@ WebRtc_Word32 RTPReceiver::RegisterReceivePayload(
if (payload->audio) { if (payload->audio) {
if (payload->typeSpecific.Audio.frequency == frequency && if (payload->typeSpecific.Audio.frequency == frequency &&
(payload->typeSpecific.Audio.rate == rate || (payload->typeSpecific.Audio.rate == rate ||
payload->typeSpecific.Audio.rate == 0 || rate == 0)) { payload->typeSpecific.Audio.rate == 0 || rate == 0) &&
payload->typeSpecific.Audio.channels == channels) {
// remove old setting // remove old setting
delete payload; delete payload;
_payloadTypeMap.erase(audio_it); _payloadTypeMap.erase(audio_it);

View File

@ -654,7 +654,7 @@ Channel::OnInitializeDecoder(
receiveCodec.rate = rate; receiveCodec.rate = rate;
strncpy(receiveCodec.plname, payloadName, RTP_PAYLOAD_NAME_SIZE - 1); strncpy(receiveCodec.plname, payloadName, RTP_PAYLOAD_NAME_SIZE - 1);
_audioCodingModule.Codec(payloadName, dummyCodec, frequency); _audioCodingModule.Codec(payloadName, dummyCodec, frequency, channels);
receiveCodec.pacsize = dummyCodec.pacsize; receiveCodec.pacsize = dummyCodec.pacsize;
// Register the new codec to the ACM // Register the new codec to the ACM
@ -1423,7 +1423,7 @@ Channel::Init()
} }
// Ensure that PCMU is used as default codec on the sending side // Ensure that PCMU is used as default codec on the sending side
if (!STR_CASE_CMP(codec.plname, "PCMU")) if (!STR_CASE_CMP(codec.plname, "PCMU") && (codec.channels == 1))
{ {
SetSendCodec(codec); SetSendCodec(codec);
} }
@ -2472,12 +2472,13 @@ Channel::SetSendCNPayloadType(int type, PayloadFrequencies frequency)
CodecInst codec; CodecInst codec;
WebRtc_Word32 samplingFreqHz(-1); WebRtc_Word32 samplingFreqHz(-1);
const int kMono = 1;
if (frequency == kFreq32000Hz) if (frequency == kFreq32000Hz)
samplingFreqHz = 32000; samplingFreqHz = 32000;
else if (frequency == kFreq16000Hz) else if (frequency == kFreq16000Hz)
samplingFreqHz = 16000; samplingFreqHz = 16000;
if (_audioCodingModule.Codec("CN", codec, samplingFreqHz) == -1) if (_audioCodingModule.Codec("CN", codec, samplingFreqHz, kMono) == -1)
{ {
_engineStatisticsPtr->SetLastError( _engineStatisticsPtr->SetLastError(
VE_AUDIO_CODING_MODULE_ERROR, kTraceError, VE_AUDIO_CODING_MODULE_ERROR, kTraceError,

View File

@ -338,12 +338,12 @@ void RunTest(std::string out_path) {
res = codec->GetCodec(i, cinst); res = codec->GetCodec(i, cinst);
VALIDATE; VALIDATE;
if (strncmp(cinst.plname, "ISAC", 4) == 0 && cinst.plfreq == 32000) { if (strncmp(cinst.plname, "ISAC", 4) == 0 && cinst.plfreq == 32000) {
printf("%i. ISAC-swb pltype:%i plfreqi:%i\n", i, cinst.pltype, printf("%i. ISAC-swb pltype:%i plfreq:%i channels:%i\n", i, cinst.pltype,
cinst.plfreq); cinst.plfreq, cinst.channels);
} }
else { else {
printf("%i. %s pltype:%i plfreq:%i\n", i, cinst.plname, printf("%i. %s pltype:%i plfreq:%i channels:%i\n", i, cinst.plname,
cinst.pltype, cinst.plfreq); cinst.pltype, cinst.plfreq, cinst.channels);
} }
} }
#ifdef DEBUG #ifdef DEBUG