git-svn-id: http://webrtc.googlecode.com/svn/trunk@2 4adac7df-926f-26a2-2b94-8c16560cd09d

This commit is contained in:
niklase@google.com 2011-05-30 11:19:44 +00:00
parent a24fc54e85
commit 3f0254baab
171 changed files with 19345 additions and 0 deletions

1
common_audio/OWNERS Normal file
View File

@ -0,0 +1 @@
bjornv@google.com

View File

@ -0,0 +1,3 @@
bjornv@google.com
tlegrand@google.com
jks@google.com

View File

@ -0,0 +1,110 @@
/*
* 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.
*/
/*
* A wrapper for resampling a numerous amount of sampling combinations.
*/
#ifndef WEBRTC_RESAMPLER_RESAMPLER_H_
#define WEBRTC_RESAMPLER_RESAMPLER_H_
#include "typedefs.h"
namespace webrtc
{
enum ResamplerType
{
// 4 MSB = Number of channels
// 4 LSB = Synchronous or asynchronous
kResamplerSynchronous = 0x10,
kResamplerAsynchronous = 0x11,
kResamplerSynchronousStereo = 0x20,
kResamplerAsynchronousStereo = 0x21,
kResamplerInvalid = 0xff
};
enum ResamplerMode
{
kResamplerMode1To1,
kResamplerMode1To2,
kResamplerMode1To3,
kResamplerMode1To4,
kResamplerMode1To6,
kResamplerMode2To3,
kResamplerMode2To11,
kResamplerMode4To11,
kResamplerMode8To11,
kResamplerMode11To16,
kResamplerMode11To32,
kResamplerMode2To1,
kResamplerMode3To1,
kResamplerMode4To1,
kResamplerMode6To1,
kResamplerMode3To2,
kResamplerMode11To2,
kResamplerMode11To4,
kResamplerMode11To8
};
class Resampler
{
public:
Resampler();
Resampler(int inFreq, int outFreq, ResamplerType type);
~Resampler();
// Reset all states
int Reset(int inFreq, int outFreq, ResamplerType type);
// Reset all states if any parameter has changed
int ResetIfNeeded(int inFreq, int outFreq, ResamplerType type);
// Synchronous resampling, all output samples are written to samplesOut
int Push(const WebRtc_Word16* samplesIn, int lengthIn, WebRtc_Word16* samplesOut,
int maxLen, int &outLen);
// Asynchronous resampling, input
int Insert(WebRtc_Word16* samplesIn, int lengthIn);
// Asynchronous resampling output, remaining samples are buffered
int Pull(WebRtc_Word16* samplesOut, int desiredLen, int &outLen);
private:
// Generic pointers since we don't know what states we'll need
void* state1_;
void* state2_;
void* state3_;
// Storage if needed
WebRtc_Word16* in_buffer_;
WebRtc_Word16* out_buffer_;
int in_buffer_size_;
int out_buffer_size_;
int in_buffer_size_max_;
int out_buffer_size_max_;
// State
int my_in_frequency_khz_;
int my_out_frequency_khz_;
ResamplerMode my_mode_;
ResamplerType my_type_;
// Extra instance for stereo
Resampler* slave_left_;
Resampler* slave_right_;
};
} // namespace webrtc
#endif // WEBRTC_RESAMPLER_RESAMPLER_H_

View File

@ -0,0 +1,981 @@
/*
* 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.
*/
/*
* A wrapper for resampling a numerous amount of sampling combinations.
*/
#include <stdlib.h>
#include <string.h>
#include "signal_processing_library.h"
#include "resampler.h"
namespace webrtc
{
Resampler::Resampler()
{
state1_ = NULL;
state2_ = NULL;
state3_ = NULL;
in_buffer_ = NULL;
out_buffer_ = NULL;
in_buffer_size_ = 0;
out_buffer_size_ = 0;
in_buffer_size_max_ = 0;
out_buffer_size_max_ = 0;
// we need a reset before we will work
my_in_frequency_khz_ = 0;
my_out_frequency_khz_ = 0;
my_mode_ = kResamplerMode1To1;
my_type_ = kResamplerInvalid;
slave_left_ = NULL;
slave_right_ = NULL;
}
Resampler::Resampler(int inFreq, int outFreq, ResamplerType type)
{
state1_ = NULL;
state2_ = NULL;
state3_ = NULL;
in_buffer_ = NULL;
out_buffer_ = NULL;
in_buffer_size_ = 0;
out_buffer_size_ = 0;
in_buffer_size_max_ = 0;
out_buffer_size_max_ = 0;
// we need a reset before we will work
my_in_frequency_khz_ = 0;
my_out_frequency_khz_ = 0;
my_mode_ = kResamplerMode1To1;
my_type_ = kResamplerInvalid;
slave_left_ = NULL;
slave_right_ = NULL;
int res = Reset(inFreq, outFreq, type);
}
Resampler::~Resampler()
{
if (state1_)
{
free(state1_);
}
if (state2_)
{
free(state2_);
}
if (state3_)
{
free(state3_);
}
if (in_buffer_)
{
free(in_buffer_);
}
if (out_buffer_)
{
free(out_buffer_);
}
if (slave_left_)
{
delete slave_left_;
}
if (slave_right_)
{
delete slave_right_;
}
}
int Resampler::ResetIfNeeded(int inFreq, int outFreq, ResamplerType type)
{
int tmpInFreq_kHz = inFreq / 1000;
int tmpOutFreq_kHz = outFreq / 1000;
if ((tmpInFreq_kHz != my_in_frequency_khz_) || (tmpOutFreq_kHz != my_out_frequency_khz_)
|| (type != my_type_))
{
return Reset(inFreq, outFreq, type);
} else
{
return 0;
}
}
int Resampler::Reset(int inFreq, int outFreq, ResamplerType type)
{
if (state1_)
{
free(state1_);
state1_ = NULL;
}
if (state2_)
{
free(state2_);
state2_ = NULL;
}
if (state3_)
{
free(state3_);
state3_ = NULL;
}
if (in_buffer_)
{
free(in_buffer_);
in_buffer_ = NULL;
}
if (out_buffer_)
{
free(out_buffer_);
out_buffer_ = NULL;
}
if (slave_left_)
{
delete slave_left_;
slave_left_ = NULL;
}
if (slave_right_)
{
delete slave_right_;
slave_right_ = NULL;
}
in_buffer_size_ = 0;
out_buffer_size_ = 0;
in_buffer_size_max_ = 0;
out_buffer_size_max_ = 0;
// This might be overridden if parameters are not accepted.
my_type_ = type;
// Start with a math exercise, Euclid's algorithm to find the gcd:
int a = inFreq;
int b = outFreq;
int c = a % b;
while (c != 0)
{
a = b;
b = c;
c = a % b;
}
// b is now the gcd;
// We need to track what domain we're in.
my_in_frequency_khz_ = inFreq / 1000;
my_out_frequency_khz_ = outFreq / 1000;
// Scale with GCD
inFreq = inFreq / b;
outFreq = outFreq / b;
// Do we need stereo?
if ((my_type_ & 0xf0) == 0x20)
{
// Change type to mono
type = (ResamplerType)((int)type & 0x0f + 0x10);
slave_left_ = new Resampler(inFreq, outFreq, type);
slave_right_ = new Resampler(inFreq, outFreq, type);
}
if (inFreq == outFreq)
{
my_mode_ = kResamplerMode1To1;
} else if (inFreq == 1)
{
switch (outFreq)
{
case 2:
my_mode_ = kResamplerMode1To2;
break;
case 3:
my_mode_ = kResamplerMode1To3;
break;
case 4:
my_mode_ = kResamplerMode1To4;
break;
case 6:
my_mode_ = kResamplerMode1To6;
break;
default:
my_type_ = kResamplerInvalid;
break;
}
} else if (outFreq == 1)
{
switch (inFreq)
{
case 2:
my_mode_ = kResamplerMode2To1;
break;
case 3:
my_mode_ = kResamplerMode3To1;
break;
case 4:
my_mode_ = kResamplerMode4To1;
break;
case 6:
my_mode_ = kResamplerMode6To1;
break;
default:
my_type_ = kResamplerInvalid;
break;
}
} else if ((inFreq == 2) && (outFreq == 3))
{
my_mode_ = kResamplerMode2To3;
} else if ((inFreq == 2) && (outFreq == 11))
{
my_mode_ = kResamplerMode2To11;
} else if ((inFreq == 4) && (outFreq == 11))
{
my_mode_ = kResamplerMode4To11;
} else if ((inFreq == 8) && (outFreq == 11))
{
my_mode_ = kResamplerMode8To11;
} else if ((inFreq == 3) && (outFreq == 2))
{
my_mode_ = kResamplerMode3To2;
} else if ((inFreq == 11) && (outFreq == 2))
{
my_mode_ = kResamplerMode11To2;
} else if ((inFreq == 11) && (outFreq == 4))
{
my_mode_ = kResamplerMode11To4;
} else if ((inFreq == 11) && (outFreq == 16))
{
my_mode_ = kResamplerMode11To16;
} else if ((inFreq == 11) && (outFreq == 32))
{
my_mode_ = kResamplerMode11To32;
} else if ((inFreq == 11) && (outFreq == 8))
{
my_mode_ = kResamplerMode11To8;
} else
{
my_type_ = kResamplerInvalid;
return -1;
}
// Now create the states we need
switch (my_mode_)
{
case kResamplerMode1To1:
// No state needed;
break;
case kResamplerMode1To2:
state1_ = malloc(8 * sizeof(WebRtc_Word32));
memset(state1_, 0, 8 * sizeof(WebRtc_Word32));
break;
case kResamplerMode1To3:
state1_ = malloc(sizeof(WebRtcSpl_State16khzTo48khz));
WebRtcSpl_ResetResample16khzTo48khz((WebRtcSpl_State16khzTo48khz *)state1_);
break;
case kResamplerMode1To4:
// 1:2
state1_ = malloc(8 * sizeof(WebRtc_Word32));
memset(state1_, 0, 8 * sizeof(WebRtc_Word32));
// 2:4
state2_ = malloc(8 * sizeof(WebRtc_Word32));
memset(state2_, 0, 8 * sizeof(WebRtc_Word32));
break;
case kResamplerMode1To6:
// 1:2
state1_ = malloc(8 * sizeof(WebRtc_Word32));
memset(state1_, 0, 8 * sizeof(WebRtc_Word32));
// 2:6
state2_ = malloc(sizeof(WebRtcSpl_State16khzTo48khz));
WebRtcSpl_ResetResample16khzTo48khz((WebRtcSpl_State16khzTo48khz *)state2_);
break;
case kResamplerMode2To3:
// 2:6
state1_ = malloc(sizeof(WebRtcSpl_State16khzTo48khz));
WebRtcSpl_ResetResample16khzTo48khz((WebRtcSpl_State16khzTo48khz *)state1_);
// 6:3
state2_ = malloc(8 * sizeof(WebRtc_Word32));
memset(state2_, 0, 8 * sizeof(WebRtc_Word32));
break;
case kResamplerMode2To11:
state1_ = malloc(8 * sizeof(WebRtc_Word32));
memset(state1_, 0, 8 * sizeof(WebRtc_Word32));
state2_ = malloc(sizeof(WebRtcSpl_State8khzTo22khz));
WebRtcSpl_ResetResample8khzTo22khz((WebRtcSpl_State8khzTo22khz *)state2_);
break;
case kResamplerMode4To11:
state1_ = malloc(sizeof(WebRtcSpl_State8khzTo22khz));
WebRtcSpl_ResetResample8khzTo22khz((WebRtcSpl_State8khzTo22khz *)state1_);
break;
case kResamplerMode8To11:
state1_ = malloc(sizeof(WebRtcSpl_State16khzTo22khz));
WebRtcSpl_ResetResample16khzTo22khz((WebRtcSpl_State16khzTo22khz *)state1_);
break;
case kResamplerMode11To16:
state1_ = malloc(8 * sizeof(WebRtc_Word32));
memset(state1_, 0, 8 * sizeof(WebRtc_Word32));
state2_ = malloc(sizeof(WebRtcSpl_State22khzTo16khz));
WebRtcSpl_ResetResample22khzTo16khz((WebRtcSpl_State22khzTo16khz *)state2_);
break;
case kResamplerMode11To32:
// 11 -> 22
state1_ = malloc(8 * sizeof(WebRtc_Word32));
memset(state1_, 0, 8 * sizeof(WebRtc_Word32));
// 22 -> 16
state2_ = malloc(sizeof(WebRtcSpl_State22khzTo16khz));
WebRtcSpl_ResetResample22khzTo16khz((WebRtcSpl_State22khzTo16khz *)state2_);
// 16 -> 32
state3_ = malloc(8 * sizeof(WebRtc_Word32));
memset(state3_, 0, 8 * sizeof(WebRtc_Word32));
break;
case kResamplerMode2To1:
state1_ = malloc(8 * sizeof(WebRtc_Word32));
memset(state1_, 0, 8 * sizeof(WebRtc_Word32));
break;
case kResamplerMode3To1:
state1_ = malloc(sizeof(WebRtcSpl_State48khzTo16khz));
WebRtcSpl_ResetResample48khzTo16khz((WebRtcSpl_State48khzTo16khz *)state1_);
break;
case kResamplerMode4To1:
// 4:2
state1_ = malloc(8 * sizeof(WebRtc_Word32));
memset(state1_, 0, 8 * sizeof(WebRtc_Word32));
// 2:1
state2_ = malloc(8 * sizeof(WebRtc_Word32));
memset(state2_, 0, 8 * sizeof(WebRtc_Word32));
break;
case kResamplerMode6To1:
// 6:2
state1_ = malloc(sizeof(WebRtcSpl_State48khzTo16khz));
WebRtcSpl_ResetResample48khzTo16khz((WebRtcSpl_State48khzTo16khz *)state1_);
// 2:1
state2_ = malloc(8 * sizeof(WebRtc_Word32));
memset(state2_, 0, 8 * sizeof(WebRtc_Word32));
break;
case kResamplerMode3To2:
// 3:6
state1_ = malloc(8 * sizeof(WebRtc_Word32));
memset(state1_, 0, 8 * sizeof(WebRtc_Word32));
// 6:2
state2_ = malloc(sizeof(WebRtcSpl_State48khzTo16khz));
WebRtcSpl_ResetResample48khzTo16khz((WebRtcSpl_State48khzTo16khz *)state2_);
break;
case kResamplerMode11To2:
state1_ = malloc(sizeof(WebRtcSpl_State22khzTo8khz));
WebRtcSpl_ResetResample22khzTo8khz((WebRtcSpl_State22khzTo8khz *)state1_);
state2_ = malloc(8 * sizeof(WebRtc_Word32));
memset(state2_, 0, 8 * sizeof(WebRtc_Word32));
break;
case kResamplerMode11To4:
state1_ = malloc(sizeof(WebRtcSpl_State22khzTo8khz));
WebRtcSpl_ResetResample22khzTo8khz((WebRtcSpl_State22khzTo8khz *)state1_);
break;
case kResamplerMode11To8:
state1_ = malloc(sizeof(WebRtcSpl_State22khzTo16khz));
WebRtcSpl_ResetResample22khzTo16khz((WebRtcSpl_State22khzTo16khz *)state1_);
break;
}
return 0;
}
// Synchronous resampling, all output samples are written to samplesOut
int Resampler::Push(const WebRtc_Word16 * samplesIn, int lengthIn, WebRtc_Word16* samplesOut,
int maxLen, int &outLen)
{
// Check that the resampler is not in asynchronous mode
if (my_type_ & 0x0f)
{
return -1;
}
// Do we have a stereo signal?
if ((my_type_ & 0xf0) == 0x20)
{
// Split up the signal and call the slave object for each channel
WebRtc_Word16* left = (WebRtc_Word16*)malloc(lengthIn * sizeof(WebRtc_Word16) / 2);
WebRtc_Word16* right = (WebRtc_Word16*)malloc(lengthIn * sizeof(WebRtc_Word16) / 2);
WebRtc_Word16* out_left = (WebRtc_Word16*)malloc(maxLen / 2 * sizeof(WebRtc_Word16));
WebRtc_Word16* out_right =
(WebRtc_Word16*)malloc(maxLen / 2 * sizeof(WebRtc_Word16));
int res = 0;
for (int i = 0; i < lengthIn; i += 2)
{
left[i >> 1] = samplesIn[i];
right[i >> 1] = samplesIn[i + 1];
}
// It's OK to overwrite the local parameter, since it's just a copy
lengthIn = lengthIn / 2;
int actualOutLen_left = 0;
int actualOutLen_right = 0;
// Do resampling for right channel
res |= slave_left_->Push(left, lengthIn, out_left, maxLen / 2, actualOutLen_left);
res |= slave_right_->Push(right, lengthIn, out_right, maxLen / 2, actualOutLen_right);
if (res || (actualOutLen_left != actualOutLen_right))
{
free(left);
free(right);
free(out_left);
free(out_right);
return -1;
}
// Reassemble the signal
for (int i = 0; i < actualOutLen_left; i++)
{
samplesOut[i * 2] = out_left[i];
samplesOut[i * 2 + 1] = out_right[i];
}
outLen = 2 * actualOutLen_left;
free(left);
free(right);
free(out_left);
free(out_right);
return 0;
}
// Container for temp samples
WebRtc_Word16* tmp;
// tmp data for resampling routines
WebRtc_Word32* tmp_mem;
switch (my_mode_)
{
case kResamplerMode1To1:
memcpy(samplesOut, samplesIn, lengthIn * sizeof(WebRtc_Word16));
outLen = lengthIn;
break;
case kResamplerMode1To2:
if (maxLen < (lengthIn * 2))
{
return -1;
}
WebRtcSpl_UpsampleBy2(samplesIn, lengthIn, samplesOut, (WebRtc_Word32*)state1_);
outLen = lengthIn * 2;
return 0;
case kResamplerMode1To3:
// We can only handle blocks of 160 samples
// Can be fixed, but I don't think it's needed
if ((lengthIn % 160) != 0)
{
return -1;
}
if (maxLen < (lengthIn * 3))
{
return -1;
}
tmp_mem = (WebRtc_Word32*)malloc(336 * sizeof(WebRtc_Word32));
for (int i = 0; i < lengthIn; i += 160)
{
WebRtcSpl_Resample16khzTo48khz(samplesIn + i, samplesOut + i * 3,
(WebRtcSpl_State16khzTo48khz *)state1_,
tmp_mem);
}
outLen = lengthIn * 3;
free(tmp_mem);
return 0;
case kResamplerMode1To4:
if (maxLen < (lengthIn * 4))
{
return -1;
}
tmp = (WebRtc_Word16*)malloc(sizeof(WebRtc_Word16) * 2 * lengthIn);
// 1:2
WebRtcSpl_UpsampleBy2(samplesIn, lengthIn, tmp, (WebRtc_Word32*)state1_);
// 2:4
WebRtcSpl_UpsampleBy2(tmp, lengthIn * 2, samplesOut, (WebRtc_Word32*)state2_);
outLen = lengthIn * 4;
free(tmp);
return 0;
case kResamplerMode1To6:
// We can only handle blocks of 80 samples
// Can be fixed, but I don't think it's needed
if ((lengthIn % 80) != 0)
{
return -1;
}
if (maxLen < (lengthIn * 6))
{
return -1;
}
//1:2
tmp_mem = (WebRtc_Word32*)malloc(336 * sizeof(WebRtc_Word32));
tmp = (WebRtc_Word16*)malloc(sizeof(WebRtc_Word16) * 2 * lengthIn);
WebRtcSpl_UpsampleBy2(samplesIn, lengthIn, tmp, (WebRtc_Word32*)state1_);
outLen = lengthIn * 2;
for (int i = 0; i < outLen; i += 160)
{
WebRtcSpl_Resample16khzTo48khz(tmp + i, samplesOut + i * 3,
(WebRtcSpl_State16khzTo48khz *)state2_,
tmp_mem);
}
outLen = outLen * 3;
free(tmp_mem);
free(tmp);
return 0;
case kResamplerMode2To3:
if (maxLen < (lengthIn * 3 / 2))
{
return -1;
}
// 2:6
// We can only handle blocks of 160 samples
// Can be fixed, but I don't think it's needed
if ((lengthIn % 160) != 0)
{
return -1;
}
tmp = static_cast<WebRtc_Word16*> (malloc(sizeof(WebRtc_Word16) * lengthIn * 3));
tmp_mem = (WebRtc_Word32*)malloc(336 * sizeof(WebRtc_Word32));
for (int i = 0; i < lengthIn; i += 160)
{
WebRtcSpl_Resample16khzTo48khz(samplesIn + i, tmp + i * 3,
(WebRtcSpl_State16khzTo48khz *)state1_,
tmp_mem);
}
lengthIn = lengthIn * 3;
// 6:3
WebRtcSpl_DownsampleBy2(tmp, lengthIn, samplesOut, (WebRtc_Word32*)state2_);
outLen = lengthIn / 2;
free(tmp);
free(tmp_mem);
return 0;
case kResamplerMode2To11:
// We can only handle blocks of 80 samples
// Can be fixed, but I don't think it's needed
if ((lengthIn % 80) != 0)
{
return -1;
}
if (maxLen < ((lengthIn * 11) / 2))
{
return -1;
}
tmp = (WebRtc_Word16*)malloc(sizeof(WebRtc_Word16) * 2 * lengthIn);
// 1:2
WebRtcSpl_UpsampleBy2(samplesIn, lengthIn, tmp, (WebRtc_Word32*)state1_);
lengthIn *= 2;
tmp_mem = (WebRtc_Word32*)malloc(98 * sizeof(WebRtc_Word32));
for (int i = 0; i < lengthIn; i += 80)
{
WebRtcSpl_Resample8khzTo22khz(tmp + i, samplesOut + (i * 11) / 4,
(WebRtcSpl_State8khzTo22khz *)state2_,
tmp_mem);
}
outLen = (lengthIn * 11) / 4;
free(tmp_mem);
free(tmp);
return 0;
case kResamplerMode4To11:
// We can only handle blocks of 80 samples
// Can be fixed, but I don't think it's needed
if ((lengthIn % 80) != 0)
{
return -1;
}
if (maxLen < ((lengthIn * 11) / 4))
{
return -1;
}
tmp_mem = (WebRtc_Word32*)malloc(98 * sizeof(WebRtc_Word32));
for (int i = 0; i < lengthIn; i += 80)
{
WebRtcSpl_Resample8khzTo22khz(samplesIn + i, samplesOut + (i * 11) / 4,
(WebRtcSpl_State8khzTo22khz *)state1_,
tmp_mem);
}
outLen = (lengthIn * 11) / 4;
free(tmp_mem);
return 0;
case kResamplerMode8To11:
// We can only handle blocks of 160 samples
// Can be fixed, but I don't think it's needed
if ((lengthIn % 160) != 0)
{
return -1;
}
if (maxLen < ((lengthIn * 11) / 8))
{
return -1;
}
tmp_mem = (WebRtc_Word32*)malloc(88 * sizeof(WebRtc_Word32));
for (int i = 0; i < lengthIn; i += 160)
{
WebRtcSpl_Resample16khzTo22khz(samplesIn + i, samplesOut + (i * 11) / 8,
(WebRtcSpl_State16khzTo22khz *)state1_,
tmp_mem);
}
outLen = (lengthIn * 11) / 8;
free(tmp_mem);
return 0;
case kResamplerMode11To16:
// We can only handle blocks of 110 samples
if ((lengthIn % 110) != 0)
{
return -1;
}
if (maxLen < ((lengthIn * 16) / 11))
{
return -1;
}
tmp_mem = (WebRtc_Word32*)malloc(104 * sizeof(WebRtc_Word32));
tmp = (WebRtc_Word16*)malloc((sizeof(WebRtc_Word16) * lengthIn * 2));
WebRtcSpl_UpsampleBy2(samplesIn, lengthIn, tmp, (WebRtc_Word32*)state1_);
for (int i = 0; i < (lengthIn * 2); i += 220)
{
WebRtcSpl_Resample22khzTo16khz(tmp + i, samplesOut + (i / 220) * 160,
(WebRtcSpl_State22khzTo16khz *)state2_,
tmp_mem);
}
outLen = (lengthIn * 16) / 11;
free(tmp_mem);
free(tmp);
return 0;
case kResamplerMode11To32:
// We can only handle blocks of 110 samples
if ((lengthIn % 110) != 0)
{
return -1;
}
if (maxLen < ((lengthIn * 32) / 11))
{
return -1;
}
tmp_mem = (WebRtc_Word32*)malloc(104 * sizeof(WebRtc_Word32));
tmp = (WebRtc_Word16*)malloc((sizeof(WebRtc_Word16) * lengthIn * 2));
// 11 -> 22 kHz in samplesOut
WebRtcSpl_UpsampleBy2(samplesIn, lengthIn, samplesOut, (WebRtc_Word32*)state1_);
// 22 -> 16 in tmp
for (int i = 0; i < (lengthIn * 2); i += 220)
{
WebRtcSpl_Resample22khzTo16khz(samplesOut + i, tmp + (i / 220) * 160,
(WebRtcSpl_State22khzTo16khz *)state2_,
tmp_mem);
}
// 16 -> 32 in samplesOut
WebRtcSpl_UpsampleBy2(tmp, (lengthIn * 16) / 11, samplesOut,
(WebRtc_Word32*)state3_);
outLen = (lengthIn * 32) / 11;
free(tmp_mem);
free(tmp);
return 0;
case kResamplerMode2To1:
if (maxLen < (lengthIn / 2))
{
return -1;
}
WebRtcSpl_DownsampleBy2(samplesIn, lengthIn, samplesOut, (WebRtc_Word32*)state1_);
outLen = lengthIn / 2;
return 0;
case kResamplerMode3To1:
// We can only handle blocks of 480 samples
// Can be fixed, but I don't think it's needed
if ((lengthIn % 480) != 0)
{
return -1;
}
if (maxLen < (lengthIn / 3))
{
return -1;
}
tmp_mem = (WebRtc_Word32*)malloc(496 * sizeof(WebRtc_Word32));
for (int i = 0; i < lengthIn; i += 480)
{
WebRtcSpl_Resample48khzTo16khz(samplesIn + i, samplesOut + i / 3,
(WebRtcSpl_State48khzTo16khz *)state1_,
tmp_mem);
}
outLen = lengthIn / 3;
free(tmp_mem);
return 0;
case kResamplerMode4To1:
if (maxLen < (lengthIn / 4))
{
return -1;
}
tmp = (WebRtc_Word16*)malloc(sizeof(WebRtc_Word16) * lengthIn / 2);
// 4:2
WebRtcSpl_DownsampleBy2(samplesIn, lengthIn, tmp, (WebRtc_Word32*)state1_);
// 2:1
WebRtcSpl_DownsampleBy2(tmp, lengthIn / 2, samplesOut, (WebRtc_Word32*)state2_);
outLen = lengthIn / 4;
free(tmp);
return 0;
case kResamplerMode6To1:
// We can only handle blocks of 480 samples
// Can be fixed, but I don't think it's needed
if ((lengthIn % 480) != 0)
{
return -1;
}
if (maxLen < (lengthIn / 6))
{
return -1;
}
tmp_mem = (WebRtc_Word32*)malloc(496 * sizeof(WebRtc_Word32));
tmp = (WebRtc_Word16*)malloc((sizeof(WebRtc_Word16) * lengthIn) / 3);
for (int i = 0; i < lengthIn; i += 480)
{
WebRtcSpl_Resample48khzTo16khz(samplesIn + i, tmp + i / 3,
(WebRtcSpl_State48khzTo16khz *)state1_,
tmp_mem);
}
outLen = lengthIn / 3;
free(tmp_mem);
WebRtcSpl_DownsampleBy2(tmp, outLen, samplesOut, (WebRtc_Word32*)state2_);
free(tmp);
outLen = outLen / 2;
return 0;
case kResamplerMode3To2:
if (maxLen < (lengthIn * 2 / 3))
{
return -1;
}
// 3:6
tmp = static_cast<WebRtc_Word16*> (malloc(sizeof(WebRtc_Word16) * lengthIn * 2));
WebRtcSpl_UpsampleBy2(samplesIn, lengthIn, tmp, (WebRtc_Word32*)state1_);
lengthIn *= 2;
// 6:2
// We can only handle blocks of 480 samples
// Can be fixed, but I don't think it's needed
if ((lengthIn % 480) != 0)
{
free(tmp);
return -1;
}
tmp_mem = (WebRtc_Word32*)malloc(496 * sizeof(WebRtc_Word32));
for (int i = 0; i < lengthIn; i += 480)
{
WebRtcSpl_Resample48khzTo16khz(tmp + i, samplesOut + i / 3,
(WebRtcSpl_State48khzTo16khz *)state2_,
tmp_mem);
}
outLen = lengthIn / 3;
free(tmp);
free(tmp_mem);
return 0;
case kResamplerMode11To2:
// We can only handle blocks of 220 samples
// Can be fixed, but I don't think it's needed
if ((lengthIn % 220) != 0)
{
return -1;
}
if (maxLen < ((lengthIn * 2) / 11))
{
return -1;
}
tmp_mem = (WebRtc_Word32*)malloc(126 * sizeof(WebRtc_Word32));
tmp = (WebRtc_Word16*)malloc((lengthIn * 4) / 11 * sizeof(WebRtc_Word16));
for (int i = 0; i < lengthIn; i += 220)
{
WebRtcSpl_Resample22khzTo8khz(samplesIn + i, tmp + (i * 4) / 11,
(WebRtcSpl_State22khzTo8khz *)state1_,
tmp_mem);
}
lengthIn = (lengthIn * 4) / 11;
WebRtcSpl_DownsampleBy2(tmp, lengthIn, samplesOut, (WebRtc_Word32*)state2_);
outLen = lengthIn / 2;
free(tmp_mem);
free(tmp);
return 0;
case kResamplerMode11To4:
// We can only handle blocks of 220 samples
// Can be fixed, but I don't think it's needed
if ((lengthIn % 220) != 0)
{
return -1;
}
if (maxLen < ((lengthIn * 4) / 11))
{
return -1;
}
tmp_mem = (WebRtc_Word32*)malloc(126 * sizeof(WebRtc_Word32));
for (int i = 0; i < lengthIn; i += 220)
{
WebRtcSpl_Resample22khzTo8khz(samplesIn + i, samplesOut + (i * 4) / 11,
(WebRtcSpl_State22khzTo8khz *)state1_,
tmp_mem);
}
outLen = (lengthIn * 4) / 11;
free(tmp_mem);
return 0;
case kResamplerMode11To8:
// We can only handle blocks of 160 samples
// Can be fixed, but I don't think it's needed
if ((lengthIn % 220) != 0)
{
return -1;
}
if (maxLen < ((lengthIn * 8) / 11))
{
return -1;
}
tmp_mem = (WebRtc_Word32*)malloc(104 * sizeof(WebRtc_Word32));
for (int i = 0; i < lengthIn; i += 220)
{
WebRtcSpl_Resample22khzTo16khz(samplesIn + i, samplesOut + (i * 8) / 11,
(WebRtcSpl_State22khzTo16khz *)state1_,
tmp_mem);
}
outLen = (lengthIn * 8) / 11;
free(tmp_mem);
return 0;
break;
}
return 0;
}
// Asynchronous resampling, input
int Resampler::Insert(WebRtc_Word16 * samplesIn, int lengthIn)
{
if (my_type_ != kResamplerAsynchronous)
{
return -1;
}
int sizeNeeded, tenMsblock;
// Determine need for size of outBuffer
sizeNeeded = out_buffer_size_ + ((lengthIn + in_buffer_size_) * my_out_frequency_khz_)
/ my_in_frequency_khz_;
if (sizeNeeded > out_buffer_size_max_)
{
// Round the value upwards to complete 10 ms blocks
tenMsblock = my_out_frequency_khz_ * 10;
sizeNeeded = (sizeNeeded / tenMsblock + 1) * tenMsblock;
out_buffer_ = (WebRtc_Word16*)realloc(out_buffer_, sizeNeeded * sizeof(WebRtc_Word16));
out_buffer_size_max_ = sizeNeeded;
}
// If we need to use inBuffer, make sure all input data fits there.
tenMsblock = my_in_frequency_khz_ * 10;
if (in_buffer_size_ || (lengthIn % tenMsblock))
{
// Check if input buffer size is enough
if ((in_buffer_size_ + lengthIn) > in_buffer_size_max_)
{
// Round the value upwards to complete 10 ms blocks
sizeNeeded = ((in_buffer_size_ + lengthIn) / tenMsblock + 1) * tenMsblock;
in_buffer_ = (WebRtc_Word16*)realloc(in_buffer_,
sizeNeeded * sizeof(WebRtc_Word16));
in_buffer_size_max_ = sizeNeeded;
}
// Copy in data to input buffer
memcpy(in_buffer_ + in_buffer_size_, samplesIn, lengthIn * sizeof(WebRtc_Word16));
// Resample all available 10 ms blocks
int lenOut;
int dataLenToResample = (in_buffer_size_ / tenMsblock) * tenMsblock;
Push(in_buffer_, dataLenToResample, out_buffer_ + out_buffer_size_,
out_buffer_size_max_ - out_buffer_size_, lenOut);
out_buffer_size_ += lenOut;
// Save the rest
memmove(in_buffer_, in_buffer_ + dataLenToResample,
(in_buffer_size_ - dataLenToResample) * sizeof(WebRtc_Word16));
in_buffer_size_ -= dataLenToResample;
} else
{
// Just resample
int lenOut;
Push(in_buffer_, lengthIn, out_buffer_ + out_buffer_size_,
out_buffer_size_max_ - out_buffer_size_, lenOut);
out_buffer_size_ += lenOut;
}
return 0;
}
// Asynchronous resampling output, remaining samples are buffered
int Resampler::Pull(WebRtc_Word16* samplesOut, int desiredLen, int &outLen)
{
if (my_type_ != kResamplerAsynchronous)
{
return -1;
}
// Check that we have enough data
if (desiredLen <= out_buffer_size_)
{
// Give out the date
memcpy(samplesOut, out_buffer_, desiredLen * sizeof(WebRtc_Word32));
// Shuffle down remaining
memmove(out_buffer_, out_buffer_ + desiredLen,
(out_buffer_size_ - desiredLen) * sizeof(WebRtc_Word16));
// Update remaining size
out_buffer_size_ -= desiredLen;
return 0;
} else
{
return -1;
}
}
} // namespace webrtc

View File

@ -0,0 +1,40 @@
# 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.
{
'includes': [
'../../../../common_settings.gypi', # Common settings
],
'targets': [
{
'target_name': 'resampler',
'type': '<(library)',
'dependencies': [
'../../../signal_processing_library/main/source/spl.gyp:spl',
],
'include_dirs': [
'../interface',
],
'direct_dependent_settings': {
'include_dirs': [
'../interface',
],
},
'sources': [
'../interface/resampler.h',
'resampler.cc',
],
},
],
}
# Local Variables:
# tab-width:2
# indent-tabs-mode:nil
# End:
# vim: set expandtab tabstop=2 shiftwidth=2:

View File

@ -0,0 +1,3 @@
bjornv@google.com
tlegrand@google.com
jks@google.com

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,284 @@
/*
* 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.
*/
/*
* This header file includes the inline functions in the fix point signal processing library.
*/
#ifndef WEBRTC_SPL_SPL_INL_H_
#define WEBRTC_SPL_SPL_INL_H_
#ifdef WEBRTC_SPL_INLINE_CALLS
#ifdef ANDROID_ISACOPT
WEBRTC_INLINE WebRtc_Word32 WEBRTC_SPL_MUL(WebRtc_Word32 a, WebRtc_Word32 b)
{
WebRtc_Word32 tmp;
__asm__("mul %0, %1, %2":"=r"(tmp):"r"(a), "r"(b));
return tmp;
}
WEBRTC_INLINE WebRtc_Word32 WEBRTC_SPL_MUL_16_32_RSFT16(WebRtc_Word16 a, WebRtc_Word32 b)
{
WebRtc_Word32 tmp;
__asm__("smulwb %0, %1, %2":"=r"(tmp):"r"(b), "r"(a));
return tmp;
}
WEBRTC_INLINE WebRtc_Word32 WEBRTC_SPL_MUL_32_32_RSFT32(WebRtc_Word16 a,
WebRtc_Word16 b,
WebRtc_Word32 c)
{
WebRtc_Word32 tmp;
__asm__("pkhbt %0, %1, %2, lsl #16" : "=r"(tmp) : "r"(b), "r"(a));
__asm__("smmul %0, %1, %2":"=r"(tmp):"r"(tmp), "r"(c));
return tmp;
}
WEBRTC_INLINE WebRtc_Word32 WEBRTC_SPL_MUL_32_32_RSFT32BI(
WebRtc_Word32 a,
WebRtc_Word32 b)
{
WebRtc_Word32 tmp;
__asm__("smmul %0, %1, %2":"=r"(tmp):"r"(a), "r"(b));
return tmp;
}
WEBRTC_INLINE WebRtc_Word32 WEBRTC_SPL_MUL_16_16(WebRtc_Word16 a,WebRtc_Word16 b)
{
WebRtc_Word32 tmp;
__asm__("smulbb %0, %1, %2":"=r"(tmp):"r"(a), "r"(b));
return tmp;
}
WEBRTC_INLINE WebRtc_Word16 WebRtcSpl_AddSatW16(WebRtc_Word16 a, WebRtc_Word16 b)
{
WebRtc_Word32 s_sum;
__asm__("qadd16 %0, %1, %2":"=r"(s_sum):"r"(a), "r"(b));
return (WebRtc_Word16) s_sum;
}
WEBRTC_INLINE WebRtc_Word32 WebRtcSpl_AddSatW32(WebRtc_Word32 l_var1, WebRtc_Word32 l_var2)
{
WebRtc_Word32 l_sum;
__asm__("qadd %0, %1, %2":"=r"(l_sum):"r"(l_var1), "r"(l_var2));
return l_sum;
}
WEBRTC_INLINE WebRtc_Word16 WebRtcSpl_SubSatW32(WebRtc_Word16 var1, WebRtc_Word16 var2)
{
WebRtc_Word32 s_sub;
__asm__("qsub16 %0, %1, %2":"=r"(s_sub):"r"(var1), "r"(var2));
return (WebRtc_Word16)s_sub;
}
WEBRTC_INLINE WebRtc_Word32 WebRtcSpl_SubSatW32(WebRtc_Word32 l_var1, WebRtc_Word32 l_var2)
{
WebRtc_Word32 l_sub;
__asm__("qsub %0, %1, %2":"=r"(l_sub):"r"(l_var1), "r"(l_var2));
return l_sub;
}
WEBRTC_INLINE WebRtc_Word16 WebRtcSpl_GetSizeInBits(WebRtc_UWord32 n)
{
WebRtc_Word32 tmp;
__asm__("clz %0, %1":"=r"(tmp):"r"(n));
return (WebRtc_Word16)(32 - tmp);
}
WEBRTC_INLINE int WebRtcSpl_NormW32(WebRtc_Word32 a)
{
WebRtc_Word32 tmp;
if (a <= 0) a ^= 0xFFFFFFFF;
__asm__("clz %0, %1":"=r"(tmp):"r"(a));
return tmp - 1;
}
WEBRTC_INLINE int WebRtcSpl_NormW16(WebRtc_Word16 a)
{
int zeros;
if (a <= 0) a ^= 0xFFFF;
if (!(0xFF80 & a)) zeros = 8; else zeros = 0;
if (!(0xF800 & (a << zeros))) zeros += 4;
if (!(0xE000 & (a << zeros))) zeros += 2;
if (!(0xC000 & (a << zeros))) zeros += 1;
return zeros;
}
WEBRTC_INLINE int WebRtcSpl_NormU32(WebRtc_UWord32 a)
{
int tmp;
if (a == 0) return 0;
__asm__("clz %0, %1":"=r"(tmp):"r"(a));
return tmp;
}
#else
WEBRTC_INLINE WebRtc_Word16 WebRtcSpl_AddSatW16(WebRtc_Word16 a, WebRtc_Word16 b)
{
WebRtc_Word32 s_sum = (WebRtc_Word32) a + (WebRtc_Word32) b;
if (s_sum > WEBRTC_SPL_WORD16_MAX)
s_sum = WEBRTC_SPL_WORD16_MAX;
else if (s_sum < WEBRTC_SPL_WORD16_MIN)
s_sum = WEBRTC_SPL_WORD16_MIN;
return (WebRtc_Word16)s_sum;
}
WEBRTC_INLINE WebRtc_Word32 WebRtcSpl_AddSatW32(WebRtc_Word32 l_var1, WebRtc_Word32 l_var2)
{
WebRtc_Word32 l_sum;
// perform long addition
l_sum = l_var1 + l_var2;
// check for under or overflow
if (WEBRTC_SPL_IS_NEG (l_var1))
{
if (WEBRTC_SPL_IS_NEG (l_var2) && !WEBRTC_SPL_IS_NEG (l_sum))
{
l_sum = (WebRtc_Word32)0x80000000;
}
}
else
{
if (!WEBRTC_SPL_IS_NEG (l_var2) && WEBRTC_SPL_IS_NEG (l_sum))
{
l_sum = (WebRtc_Word32)0x7FFFFFFF;
}
}
return l_sum;
}
WEBRTC_INLINE WebRtc_Word16 WebRtcSpl_SubSatW16( WebRtc_Word16 var1, WebRtc_Word16 var2)
{
WebRtc_Word32 l_diff;
WebRtc_Word16 s_diff;
// perform subtraction
l_diff = (WebRtc_Word32)var1 - (WebRtc_Word32)var2;
// default setting
s_diff = (WebRtc_Word16) l_diff;
// check for overflow
if (l_diff > (WebRtc_Word32)32767)
s_diff = (WebRtc_Word16)32767;
// check for underflow
if (l_diff < (WebRtc_Word32)-32768)
s_diff = (WebRtc_Word16)-32768;
return s_diff;
}
WEBRTC_INLINE WebRtc_Word32 WebRtcSpl_SubSatW32(WebRtc_Word32 l_var1, WebRtc_Word32 l_var2)
{
WebRtc_Word32 l_diff;
// perform subtraction
l_diff = l_var1 - l_var2;
// check for underflow
if ((l_var1 < 0) && (l_var2 > 0) && (l_diff > 0))
l_diff = (WebRtc_Word32)0x80000000;
// check for overflow
if ((l_var1 > 0) && (l_var2 < 0) && (l_diff < 0))
l_diff = (WebRtc_Word32)0x7FFFFFFF;
return l_diff;
}
WEBRTC_INLINE WebRtc_Word16 WebRtcSpl_GetSizeInBits(WebRtc_UWord32 n)
{
int bits;
if ((0xFFFF0000 & n)) bits = 16; else bits = 0;
if ((0x0000FF00 & (n >> bits))) bits += 8;
if ((0x000000F0 & (n >> bits))) bits += 4;
if ((0x0000000C & (n >> bits))) bits += 2;
if ((0x00000002 & (n >> bits))) bits += 1;
if ((0x00000001 & (n >> bits))) bits += 1;
return bits;
}
WEBRTC_INLINE int WebRtcSpl_NormW32(WebRtc_Word32 a)
{
int zeros;
if (a <= 0) a ^= 0xFFFFFFFF;
if (!(0xFFFF8000 & a)) zeros = 16; else zeros = 0;
if (!(0xFF800000 & (a << zeros))) zeros += 8;
if (!(0xF8000000 & (a << zeros))) zeros += 4;
if (!(0xE0000000 & (a << zeros))) zeros += 2;
if (!(0xC0000000 & (a << zeros))) zeros += 1;
return zeros;
}
WEBRTC_INLINE int WebRtcSpl_NormW16(WebRtc_Word16 a)
{
int zeros;
if (a <= 0) a ^= 0xFFFF;
if (!(0xFF80 & a)) zeros = 8; else zeros = 0;
if (!(0xF800 & (a << zeros))) zeros += 4;
if (!(0xE000 & (a << zeros))) zeros += 2;
if (!(0xC000 & (a << zeros))) zeros += 1;
return zeros;
}
WEBRTC_INLINE int WebRtcSpl_NormU32(WebRtc_UWord32 a)
{
int zeros;
if (a == 0) return 0;
if (!(0xFFFF0000 & a)) zeros = 16; else zeros = 0;
if (!(0xFF000000 & (a << zeros))) zeros += 8;
if (!(0xF0000000 & (a << zeros))) zeros += 4;
if (!(0xC0000000 & (a << zeros))) zeros += 2;
if (!(0x80000000 & (a << zeros))) zeros += 1;
return zeros;
}
#endif // ANDROID_ISACOPT
#endif // WEBRTC_SPL_INLINE_CALLS
#endif // WEBRTC_SPL_SPL_INL_H_

View File

@ -0,0 +1,11 @@
project(splib)
set(CMAKE_MODULE_PATH ${PROJECT_SOURCE_DIR}/../../../applications/buildtools)
include(Macros)
set(SPLIB_DIR ${PROJECT_SOURCE_DIR})
include(splib.cmake)
include_directories(../../../released/interface)
# Include the generic library module
include(Library)

View File

@ -0,0 +1,26 @@
/*
* add_affine_vector_to_vector.c
*
* This file contains the function WebRtcSpl_AddAffineVectorToVector().
* The description header can be found in signal_processing_library.h
*
*/
#include "signal_processing_library.h"
void WebRtcSpl_AddAffineVectorToVector(WebRtc_Word16 *out, WebRtc_Word16 *in,
WebRtc_Word16 gain, WebRtc_Word32 add_constant,
WebRtc_Word16 right_shifts, int vector_length)
{
WebRtc_Word16 *inPtr;
WebRtc_Word16 *outPtr;
int i;
inPtr = in;
outPtr = out;
for (i = 0; i < vector_length; i++)
{
(*outPtr++) += (WebRtc_Word16)((WEBRTC_SPL_MUL_16_16((*inPtr++), gain)
+ (WebRtc_Word32)add_constant) >> right_shifts);
}
}

View File

@ -0,0 +1,34 @@
/*
* 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.
*/
/*
* This file contains the function WebRtcSpl_AddSatW16().
* The description header can be found in signal_processing_library.h
*
*/
#include "signal_processing_library.h"
#ifndef SPL_NO_DOUBLE_IMPLEMENTATIONS
WebRtc_Word16 WebRtcSpl_AddSatW16(WebRtc_Word16 var1, WebRtc_Word16 var2)
{
WebRtc_Word32 s_sum = (WebRtc_Word32)var1 + (WebRtc_Word32)var2;
if (s_sum > WEBRTC_SPL_WORD16_MAX)
s_sum = WEBRTC_SPL_WORD16_MAX;
else if (s_sum < WEBRTC_SPL_WORD16_MIN)
s_sum = WEBRTC_SPL_WORD16_MIN;
return (WebRtc_Word16)s_sum;
}
#endif

View File

@ -0,0 +1,47 @@
/*
* 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.
*/
/*
* This file contains the function WebRtcSpl_AddSatW32().
* The description header can be found in signal_processing_library.h
*
*/
#include "signal_processing_library.h"
#ifndef SPL_NO_DOUBLE_IMPLEMENTATIONS
WebRtc_Word32 WebRtcSpl_AddSatW32(WebRtc_Word32 var1, WebRtc_Word32 var2)
{
WebRtc_Word32 l_sum;
// perform long addition
l_sum = var1 + var2;
// check for under or overflow
if (WEBRTC_SPL_IS_NEG(var1))
{
if (WEBRTC_SPL_IS_NEG(var2) && !WEBRTC_SPL_IS_NEG(l_sum))
{
l_sum = (WebRtc_Word32)0x80000000;
}
} else
{
if (!WEBRTC_SPL_IS_NEG(var2) && WEBRTC_SPL_IS_NEG(l_sum))
{
l_sum = (WebRtc_Word32)0x7FFFFFFF;
}
}
return l_sum;
}
#endif

View File

@ -0,0 +1,23 @@
/*
* add_vectors_and_shift.c
*
* This file contains the function WebRtcSpl_AddVectorsAndShift().
* The description header can be found in signal_processing_library.h
*
*/
#include "signal_processing_library.h"
void WebRtcSpl_AddVectorsAndShift(WebRtc_Word16 *out, G_CONST WebRtc_Word16 *in1,
G_CONST WebRtc_Word16 *in2, WebRtc_Word16 vector_length,
WebRtc_Word16 right_shifts)
{
int i;
WebRtc_Word16 *outptr = out;
G_CONST WebRtc_Word16 *in1ptr = in1;
G_CONST WebRtc_Word16 *in2ptr = in2;
for (i = vector_length; i > 0; i--)
{
(*outptr++) = (WebRtc_Word16)(((*in1ptr++) + (*in2ptr++)) >> right_shifts);
}
}

View File

@ -0,0 +1,26 @@
/*
* affine_transform_vector.c
*
* This file contains the function WebRtcSpl_AffineTransformVector().
* The description header can be found in signal_processing_library.h
*
*/
#include "signal_processing_library.h"
void WebRtcSpl_AffineTransformVector(WebRtc_Word16 *out, WebRtc_Word16 *in,
WebRtc_Word16 gain, WebRtc_Word32 constAdd,
WebRtc_Word16 Rshifts, int length)
{
WebRtc_Word16 *inPtr;
WebRtc_Word16 *outPtr;
int i;
inPtr = in;
outPtr = out;
for (i = 0; i < length; i++)
{
(*outPtr++) = (WebRtc_Word16)((WEBRTC_SPL_MUL_16_16((*inPtr++), gain)
+ (WebRtc_Word32)constAdd) >> Rshifts);
}
}

View File

@ -0,0 +1,31 @@
/*
* array_shift_w16.c
*
* This file contains the function WebRtcSpl_ArrayShiftW16().
* The description header can be found in signal_processing_library.h
*
*/
#include "signal_processing_library.h"
void WebRtcSpl_ArrayShiftW16(WebRtc_Word16 *res,
WebRtc_Word16 length,
G_CONST WebRtc_Word16 *in,
WebRtc_Word16 right_shifts)
{
int i;
if (right_shifts > 0)
{
for (i = length; i > 0; i--)
{
(*res++) = ((*in++) >> right_shifts);
}
} else
{
for (i = length; i > 0; i--)
{
(*res++) = ((*in++) << (-right_shifts));
}
}
}

View File

@ -0,0 +1,31 @@
/*
* array_shift_w32.c
*
* This file contains the function WebRtcSpl_ArrayShiftW32().
* The description header can be found in signal_processing_library.h
*
*/
#include "signal_processing_library.h"
void WebRtcSpl_ArrayShiftW32(WebRtc_Word32 *out_vector, // (o) Output vector
WebRtc_Word16 vector_length, // (i) Number of samples
G_CONST WebRtc_Word32 *in_vector, // (i) Input vector
WebRtc_Word16 right_shifts) // (i) Number of right shifts
{
int i;
if (right_shifts > 0)
{
for (i = vector_length; i > 0; i--)
{
(*out_vector++) = ((*in_vector++) >> right_shifts);
}
} else
{
for (i = vector_length; i > 0; i--)
{
(*out_vector++) = ((*in_vector++) << (-right_shifts));
}
}
}

View File

@ -0,0 +1,32 @@
/*
* array_shift_w32_to_w16.c
*
* This file contains the function WebRtcSpl_ArrayShiftW32ToW16().
* The description header can be found in signal_processing_library.h
*
*/
#include "signal_processing_library.h"
void WebRtcSpl_ArrayShiftW32ToW16(WebRtc_Word16 *res, // (o) Output vector
WebRtc_Word16 length, // (i) Number of samples
G_CONST WebRtc_Word32 *in, // (i) Input vector
WebRtc_Word16 right_shifts) // (i) Number of right shifts
{
int i;
if (right_shifts >= 0)
{
for (i = length; i > 0; i--)
{
(*res++) = (WebRtc_Word16)((*in++) >> right_shifts);
}
} else
{
WebRtc_Word16 left_shifts = -right_shifts;
for (i = length; i > 0; i--)
{
(*res++) = (WebRtc_Word16)((*in++) << left_shifts);
}
}
}

View File

@ -0,0 +1,111 @@
/*
* auto_corr_to_k_returns_pred_gain.c
*
* This file contains the function WebRtcSpl_AutoCorrToKReturnsPredGain().
* The description header can be found in signal_processing_library.h
*
*/
#include "signal_processing_library.h"
WebRtc_Word16 WebRtcSpl_AutoCorrToKReturnsPredGain(G_CONST WebRtc_Word32 *R, int use_order,
WebRtc_Word16 *K)
{
int i, n;
WebRtc_Word16 tmp, err, gain;
G_CONST WebRtc_Word32 *rptr;
WebRtc_Word32 L_num, L_den;
WebRtc_Word16 *acfptr, *pptr, *wptr, *p1ptr, *w1ptr, ACF[WEBRTC_SPL_MAX_LPC_ORDER],
P[WEBRTC_SPL_MAX_LPC_ORDER], W[WEBRTC_SPL_MAX_LPC_ORDER];
/* In the special case of R[0]==0, return K[i]=0. */
/* This should never happen; right? It doesn't */
/* if called from the LPC... */
/*
if( *R==0 )
{
for( i=use_order; i--; *K++ = 0 );
return;
}
*/
/* Initialize loop and pointers. */
acfptr = ACF;
rptr = R;
pptr = P;
p1ptr = &P[1];
w1ptr = &W[1];
wptr = w1ptr;
/* First loop; n=0. Determine shifting. */
tmp = WebRtcSpl_NormW32( *R);
*acfptr = (WebRtc_Word16)(( *rptr++ << tmp) >> 16);
*pptr++ = *acfptr++;
/* Initialize ACF, P and W. */
for (i = 1; i <= use_order; i++)
{
*acfptr = (WebRtc_Word16)(( *rptr++ << tmp) >> 16);
*wptr++ = *acfptr;
*pptr++ = *acfptr++;
}
/* Compute reflection coefficients. */
for (n = 1; n <= use_order; n++, K++)
{
tmp = WEBRTC_SPL_ABS_W16( *p1ptr );
if ( *P < tmp)
{
for (i = n; i <= use_order; i++)
*K++ = 0;
return 0;
}
// Division: WebRtcSpl_div(tmp, *P)
*K = 0;
if (tmp != 0)
{
L_num = tmp;
L_den = *P;
i = 15;
while (i--)
{
( *K) <<= 1;
L_num <<= 1;
if (L_num >= L_den)
{
L_num -= L_den;
( *K)++;
}
}
if ( *p1ptr > 0)
*K = - *K;
}
/* Schur recursion. */
pptr = P;
wptr = w1ptr;
tmp = (WebRtc_Word16)(((WebRtc_Word32) *p1ptr * (WebRtc_Word32) *K + 16384) >> 15);
*pptr = WEBRTC_SPL_ADD_SAT_W16( *pptr, tmp );
err = *pptr;
pptr++;
/* Last iteration; don't do Schur recursion. */
if (n == use_order)
{
gain = (WebRtc_Word16)WebRtcSpl_DivW32W16((WebRtc_Word32)ACF[0], err);
tmp = (14 - WebRtcSpl_NormW16(gain)) >> 1;
return tmp;
}
for (i = 1; i <= use_order - n; i++)
{
tmp = (WebRtc_Word16)(((WebRtc_Word32) *wptr * (WebRtc_Word32) *K + 16384) >> 15);
*pptr = WEBRTC_SPL_ADD_SAT_W16( *(pptr+1), tmp );
pptr++;
tmp = (WebRtc_Word16)(((WebRtc_Word32) *pptr * (WebRtc_Word32) *K + 16384) >> 15);
*wptr = WEBRTC_SPL_ADD_SAT_W16( *wptr, tmp );
wptr++;
}
}
return 0;
}

View File

@ -0,0 +1,103 @@
/*
* 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.
*/
/*
* This file contains the function WebRtcSpl_AutoCorrToReflCoef().
* The description header can be found in signal_processing_library.h
*
*/
#include "signal_processing_library.h"
void WebRtcSpl_AutoCorrToReflCoef(G_CONST WebRtc_Word32 *R, int use_order, WebRtc_Word16 *K)
{
int i, n;
WebRtc_Word16 tmp;
G_CONST WebRtc_Word32 *rptr;
WebRtc_Word32 L_num, L_den;
WebRtc_Word16 *acfptr, *pptr, *wptr, *p1ptr, *w1ptr, ACF[WEBRTC_SPL_MAX_LPC_ORDER],
P[WEBRTC_SPL_MAX_LPC_ORDER], W[WEBRTC_SPL_MAX_LPC_ORDER];
// Initialize loop and pointers.
acfptr = ACF;
rptr = R;
pptr = P;
p1ptr = &P[1];
w1ptr = &W[1];
wptr = w1ptr;
// First loop; n=0. Determine shifting.
tmp = WebRtcSpl_NormW32(*R);
*acfptr = (WebRtc_Word16)((*rptr++ << tmp) >> 16);
*pptr++ = *acfptr++;
// Initialize ACF, P and W.
for (i = 1; i <= use_order; i++)
{
*acfptr = (WebRtc_Word16)((*rptr++ << tmp) >> 16);
*wptr++ = *acfptr;
*pptr++ = *acfptr++;
}
// Compute reflection coefficients.
for (n = 1; n <= use_order; n++, K++)
{
tmp = WEBRTC_SPL_ABS_W16(*p1ptr);
if (*P < tmp)
{
for (i = n; i <= use_order; i++)
*K++ = 0;
return;
}
// Division: WebRtcSpl_div(tmp, *P)
*K = 0;
if (tmp != 0)
{
L_num = tmp;
L_den = *P;
i = 15;
while (i--)
{
(*K) <<= 1;
L_num <<= 1;
if (L_num >= L_den)
{
L_num -= L_den;
(*K)++;
}
}
if (*p1ptr > 0)
*K = -*K;
}
// Last iteration; don't do Schur recursion.
if (n == use_order)
return;
// Schur recursion.
pptr = P;
wptr = w1ptr;
tmp = (WebRtc_Word16)(((WebRtc_Word32)*p1ptr * (WebRtc_Word32)*K + 16384) >> 15);
*pptr = WEBRTC_SPL_ADD_SAT_W16( *pptr, tmp );
pptr++;
for (i = 1; i <= use_order - n; i++)
{
tmp = (WebRtc_Word16)(((WebRtc_Word32)*wptr * (WebRtc_Word32)*K + 16384) >> 15);
*pptr = WEBRTC_SPL_ADD_SAT_W16( *(pptr+1), tmp );
pptr++;
tmp = (WebRtc_Word16)(((WebRtc_Word32)*pptr * (WebRtc_Word32)*K + 16384) >> 15);
*wptr = WEBRTC_SPL_ADD_SAT_W16( *wptr, tmp );
wptr++;
}
}
}

View File

@ -0,0 +1,141 @@
/*
* 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.
*/
/*
* This file contains the function WebRtcSpl_AutoCorrelation().
* The description header can be found in signal_processing_library.h
*
*/
#include "signal_processing_library.h"
int WebRtcSpl_AutoCorrelation(G_CONST WebRtc_Word16* in_vector,
int in_vector_length,
int order,
WebRtc_Word32* result,
int* scale)
{
WebRtc_Word32 sum;
int i, j;
WebRtc_Word16 smax; // Sample max
G_CONST WebRtc_Word16* xptr1;
G_CONST WebRtc_Word16* xptr2;
WebRtc_Word32* resultptr;
int scaling = 0;
#ifdef _ARM_OPT_
#pragma message("NOTE: _ARM_OPT_ optimizations are used")
WebRtc_Word16 loops4;
#endif
if (order < 0)
order = in_vector_length;
// Find the max. sample
smax = WebRtcSpl_MaxAbsValueW16(in_vector, in_vector_length);
// In order to avoid overflow when computing the sum we should scale the samples so that
// (in_vector_length * smax * smax) will not overflow.
if (smax == 0)
{
scaling = 0;
} else
{
int nbits = WebRtcSpl_GetSizeInBits(in_vector_length); // # of bits in the sum loop
int t = WebRtcSpl_NormW32(WEBRTC_SPL_MUL(smax, smax)); // # of bits to normalize smax
if (t > nbits)
{
scaling = 0;
} else
{
scaling = nbits - t;
}
}
resultptr = result;
// Perform the actual correlation calculation
for (i = 0; i < order + 1; i++)
{
int loops = (in_vector_length - i);
sum = 0;
xptr1 = in_vector;
xptr2 = &in_vector[i];
#ifndef _ARM_OPT_
for (j = loops; j > 0; j--)
{
sum += WEBRTC_SPL_MUL_16_16_RSFT(*xptr1++, *xptr2++, scaling);
}
#else
loops4 = (loops >> 2) << 2;
if (scaling == 0)
{
for (j = 0; j < loops4; j = j + 4)
{
sum += WEBRTC_SPL_MUL_16_16(*xptr1, *xptr2);
xptr1++;
xptr2++;
sum += WEBRTC_SPL_MUL_16_16(*xptr1, *xptr2);
xptr1++;
xptr2++;
sum += WEBRTC_SPL_MUL_16_16(*xptr1, *xptr2);
xptr1++;
xptr2++;
sum += WEBRTC_SPL_MUL_16_16(*xptr1, *xptr2);
xptr1++;
xptr2++;
}
for (j = loops4; j < loops; j++)
{
sum += WEBRTC_SPL_MUL_16_16(*xptr1, *xptr2);
xptr1++;
xptr2++;
}
}
else
{
for (j = 0; j < loops4; j = j + 4)
{
sum += WEBRTC_SPL_MUL_16_16_RSFT(*xptr1, *xptr2, scaling);
xptr1++;
xptr2++;
sum += WEBRTC_SPL_MUL_16_16_RSFT(*xptr1, *xptr2, scaling);
xptr1++;
xptr2++;
sum += WEBRTC_SPL_MUL_16_16_RSFT(*xptr1, *xptr2, scaling);
xptr1++;
xptr2++;
sum += WEBRTC_SPL_MUL_16_16_RSFT(*xptr1, *xptr2, scaling);
xptr1++;
xptr2++;
}
for (j = loops4; j < loops; j++)
{
sum += WEBRTC_SPL_MUL_16_16_RSFT(*xptr1, *xptr2, scaling);
xptr1++;
xptr2++;
}
}
#endif
*resultptr++ = sum;
}
*scale = scaling;
return order + 1;
}

View File

@ -0,0 +1,36 @@
/*
*/
#include <string.h>
#ifdef _DEBUG
#include <stdio.h>
#include <stdlib.h>
#endif
#include "signal_processing_library.h"
WebRtc_Word16 WebRtcSpl_CatArraysU8(G_CONST unsigned char *vector1, WebRtc_Word16 len1,
G_CONST unsigned char *vector2, WebRtc_Word16 len2,
unsigned char *outvector, WebRtc_Word16 maxlen)
{
#ifdef _DEBUG
if (maxlen < len1 + len2)
{
printf("chcatarr : out vector is too short\n");
exit(0);
}
if ((len1 != len2) || (len2 < 0))
{
printf("chcatarr : input vectors are not of equal length\n");
exit(0);
}
#endif
/* Unused input variable */
maxlen = maxlen;
/* Concat the two vectors */
/* A unsigned char is bytes long */
WEBRTC_SPL_MEMCPY_W8(outvector, vector1, len1);
WEBRTC_SPL_MEMCPY_W8(&outvector[len1], vector2, len2);
return (len1 + len2);
}

View File

@ -0,0 +1,36 @@
/*
*/
#include <string.h>
#ifdef _DEBUG
#include <stdio.h>
#include <stdlib.h>
#endif
#include "signal_processing_library.h"
WebRtc_Word16 WebRtcSpl_CatArraysW16(G_CONST WebRtc_Word16 *vector1, WebRtc_Word16 len1,
G_CONST WebRtc_Word16 *vector2, WebRtc_Word16 len2,
WebRtc_Word16 *outvector, WebRtc_Word16 maxlen)
{
#ifdef _DEBUG
if (maxlen < len1 + len2)
{
printf("w16catarr : out vector is too short\n");
exit(0);
}
if ((len1 != len2) || (len2 < 0))
{
printf("w16catarr : input vectors are not of equal length\n");
exit(0);
}
#endif
/* Unused input variable */
maxlen = maxlen;
/* Concat the two vectors */
/* A word16 is 2 bytes long */
WEBRTC_SPL_MEMCPY_W16(outvector, vector1, len1);
WEBRTC_SPL_MEMCPY_W16(&outvector[len1], vector2, len2);
return (len1 + len2);
}

View File

@ -0,0 +1,38 @@
/*
*/
#include <string.h>
#ifdef _DEBUG
#include <stdio.h>
#include <stdlib.h>
#endif
#include "signal_processing_library.h"
WebRtc_Word16 WebRtcSpl_CatArraysW32(G_CONST WebRtc_Word32 *vector1, WebRtc_Word16 len1,
G_CONST WebRtc_Word32 *vector2, WebRtc_Word16 len2,
WebRtc_Word32 *outvector, WebRtc_Word16 maxlen)
{
#ifdef _DEBUG
if (maxlen < len1 + len2)
{
printf("w32catarr : out vector is too short\n");
exit(0);
}
if ((len1 != len2) || (len2 < 0))
{
printf("w32catarr : input vectors are not of equal length\n");
exit(0);
}
#endif
/* Unused input variable */
maxlen = maxlen;
/* Concat the two vectors */
/* A word32 is 4 bytes long */
WEBRTC_SPL_MEMCPY_W32(outvector, vector1, len1);
WEBRTC_SPL_MEMCPY_W32(&outvector[len1], vector2, len2);
return (len1 + len2);
}

View File

@ -0,0 +1,51 @@
/*
* 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.
*/
/*
* This file contains the function WebRtcSpl_ComplexBitReverse().
* The description header can be found in signal_processing_library.h
*
*/
#include "signal_processing_library.h"
void WebRtcSpl_ComplexBitReverse(WebRtc_Word16 frfi[], int stages)
{
int mr, nn, n, l, m;
WebRtc_Word16 tr, ti;
n = 1 << stages;
mr = 0;
nn = n - 1;
// decimation in time - re-order data
for (m = 1; m <= nn; ++m)
{
l = n;
do
{
l >>= 1;
} while (mr + l > nn);
mr = (mr & (l - 1)) + l;
if (mr <= m)
continue;
tr = frfi[2 * m];
frfi[2 * m] = frfi[2 * mr];
frfi[2 * mr] = tr;
ti = frfi[2 * m + 1];
frfi[2 * m + 1] = frfi[2 * mr + 1];
frfi[2 * mr + 1] = ti;
}
}

View File

@ -0,0 +1,140 @@
/*
* 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.
*/
/*
* This file contains the function WebRtcSpl_ComplexFFT().
* The description header can be found in signal_processing_library.h
*
*/
#include "signal_processing_library.h"
#define CFFTSFT 14
#define CFFTRND 1
#define CFFTRND2 16384
#if (defined ARM9E_GCC) || (defined ARM_WINM) || (defined ANDROID_AECOPT)
extern "C" int FFT_4OFQ14(void *src, void *dest, int NC, int shift);
// For detailed description of the fft functions, check the readme files in fft_ARM9E folder.
int WebRtcSpl_ComplexFFT2(WebRtc_Word16 frfi[], WebRtc_Word16 frfiOut[], int stages, int mode)
{
return FFT_4OFQ14(frfi, frfiOut, 1 << stages, 0);
}
#endif
int WebRtcSpl_ComplexFFT(WebRtc_Word16 frfi[], int stages, int mode)
{
int i, j, l, k, istep, n, m;
WebRtc_Word16 wr, wi;
WebRtc_Word32 tr32, ti32, qr32, qi32;
/* The 1024-value is a constant given from the size of WebRtcSpl_kSinTable1024[],
* and should not be changed depending on the input parameter 'stages'
*/
n = 1 << stages;
if (n > 1024)
return -1;
l = 1;
k = 10 - 1; /* Constant for given WebRtcSpl_kSinTable1024[]. Do not change
depending on the input parameter 'stages' */
if (mode == 0)
{
// mode==0: Low-complexity and Low-accuracy mode
while (l < n)
{
istep = l << 1;
for (m = 0; m < l; ++m)
{
j = m << k;
/* The 256-value is a constant given as 1/4 of the size of
* WebRtcSpl_kSinTable1024[], and should not be changed depending on the input
* parameter 'stages'. It will result in 0 <= j < N_SINE_WAVE/2
*/
wr = WebRtcSpl_kSinTable1024[j + 256];
wi = -WebRtcSpl_kSinTable1024[j];
for (i = m; i < n; i += istep)
{
j = i + l;
tr32 = WEBRTC_SPL_RSHIFT_W32((WEBRTC_SPL_MUL_16_16(wr, frfi[2 * j])
- WEBRTC_SPL_MUL_16_16(wi, frfi[2 * j + 1])), 15);
ti32 = WEBRTC_SPL_RSHIFT_W32((WEBRTC_SPL_MUL_16_16(wr, frfi[2 * j + 1])
+ WEBRTC_SPL_MUL_16_16(wi, frfi[2 * j])), 15);
qr32 = (WebRtc_Word32)frfi[2 * i];
qi32 = (WebRtc_Word32)frfi[2 * i + 1];
frfi[2 * j] = (WebRtc_Word16)WEBRTC_SPL_RSHIFT_W32(qr32 - tr32, 1);
frfi[2 * j + 1] = (WebRtc_Word16)WEBRTC_SPL_RSHIFT_W32(qi32 - ti32, 1);
frfi[2 * i] = (WebRtc_Word16)WEBRTC_SPL_RSHIFT_W32(qr32 + tr32, 1);
frfi[2 * i + 1] = (WebRtc_Word16)WEBRTC_SPL_RSHIFT_W32(qi32 + ti32, 1);
}
}
--k;
l = istep;
}
} else
{
// mode==1: High-complexity and High-accuracy mode
while (l < n)
{
istep = l << 1;
for (m = 0; m < l; ++m)
{
j = m << k;
/* The 256-value is a constant given as 1/4 of the size of
* WebRtcSpl_kSinTable1024[], and should not be changed depending on the input
* parameter 'stages'. It will result in 0 <= j < N_SINE_WAVE/2
*/
wr = WebRtcSpl_kSinTable1024[j + 256];
wi = -WebRtcSpl_kSinTable1024[j];
for (i = m; i < n; i += istep)
{
j = i + l;
tr32 = WEBRTC_SPL_RSHIFT_W32((WEBRTC_SPL_MUL_16_16(wr, frfi[2 * j])
- WEBRTC_SPL_MUL_16_16(wi, frfi[2 * j + 1]) + CFFTRND),
15 - CFFTSFT);
ti32 = WEBRTC_SPL_RSHIFT_W32((WEBRTC_SPL_MUL_16_16(wr, frfi[2 * j + 1])
+ WEBRTC_SPL_MUL_16_16(wi, frfi[2 * j]) + CFFTRND), 15 - CFFTSFT);
qr32 = ((WebRtc_Word32)frfi[2 * i]) << CFFTSFT;
qi32 = ((WebRtc_Word32)frfi[2 * i + 1]) << CFFTSFT;
frfi[2 * j] = (WebRtc_Word16)WEBRTC_SPL_RSHIFT_W32(
(qr32 - tr32 + CFFTRND2), 1 + CFFTSFT);
frfi[2 * j + 1] = (WebRtc_Word16)WEBRTC_SPL_RSHIFT_W32(
(qi32 - ti32 + CFFTRND2), 1 + CFFTSFT);
frfi[2 * i] = (WebRtc_Word16)WEBRTC_SPL_RSHIFT_W32(
(qr32 + tr32 + CFFTRND2), 1 + CFFTSFT);
frfi[2 * i + 1] = (WebRtc_Word16)WEBRTC_SPL_RSHIFT_W32(
(qi32 + ti32 + CFFTRND2), 1 + CFFTSFT);
}
}
--k;
l = istep;
}
}
return 0;
}

View File

@ -0,0 +1,155 @@
/*
* 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.
*/
/*
* This file contains the function WebRtcSpl_ComplexIFFT().
* The description header can be found in signal_processing_library.h
*
*/
#include "signal_processing_library.h"
#define CIFFTSFT 14
#define CIFFTRND 1
#if (defined ARM9E_GCC) || (defined ARM_WINM) || (defined ANDROID_AECOPT)
extern "C" int FFT_4OIQ14(void *src, void *dest, int NC, int shift);
// For detailed description of the fft functions, check the readme files in fft_ARM9E folder.
int WebRtcSpl_ComplexIFFT2(WebRtc_Word16 frfi[], WebRtc_Word16 frfiOut[], int stages, int mode)
{
FFT_4OIQ14(frfi, frfiOut, 1 << stages, 0);
return 0;
}
#endif
int WebRtcSpl_ComplexIFFT(WebRtc_Word16 frfi[], int stages, int mode)
{
int i, j, l, k, istep, n, m, scale, shift;
WebRtc_Word16 wr, wi;
WebRtc_Word32 tr32, ti32, qr32, qi32;
WebRtc_Word32 tmp32, round2;
/* The 1024-value is a constant given from the size of WebRtcSpl_kSinTable1024[],
* and should not be changed depending on the input parameter 'stages'
*/
n = 1 << stages;
if (n > 1024)
return -1;
scale = 0;
l = 1;
k = 10 - 1; /* Constant for given WebRtcSpl_kSinTable1024[]. Do not change
depending on the input parameter 'stages' */
while (l < n)
{
// variable scaling, depending upon data
shift = 0;
round2 = 8192;
tmp32 = (WebRtc_Word32)WebRtcSpl_MaxAbsValueW16(frfi, 2 * n);
if (tmp32 > 13573)
{
shift++;
scale++;
round2 <<= 1;
}
if (tmp32 > 27146)
{
shift++;
scale++;
round2 <<= 1;
}
istep = l << 1;
if (mode == 0)
{
// mode==0: Low-complexity and Low-accuracy mode
for (m = 0; m < l; ++m)
{
j = m << k;
/* The 256-value is a constant given as 1/4 of the size of
* WebRtcSpl_kSinTable1024[], and should not be changed depending on the input
* parameter 'stages'. It will result in 0 <= j < N_SINE_WAVE/2
*/
wr = WebRtcSpl_kSinTable1024[j + 256];
wi = WebRtcSpl_kSinTable1024[j];
for (i = m; i < n; i += istep)
{
j = i + l;
tr32 = WEBRTC_SPL_RSHIFT_W32((WEBRTC_SPL_MUL_16_16_RSFT(wr, frfi[2 * j], 0)
- WEBRTC_SPL_MUL_16_16_RSFT(wi, frfi[2 * j + 1], 0)), 15);
ti32 = WEBRTC_SPL_RSHIFT_W32(
(WEBRTC_SPL_MUL_16_16_RSFT(wr, frfi[2 * j + 1], 0)
+ WEBRTC_SPL_MUL_16_16_RSFT(wi,frfi[2*j],0)), 15);
qr32 = (WebRtc_Word32)frfi[2 * i];
qi32 = (WebRtc_Word32)frfi[2 * i + 1];
frfi[2 * j] = (WebRtc_Word16)WEBRTC_SPL_RSHIFT_W32(qr32 - tr32, shift);
frfi[2 * j + 1] = (WebRtc_Word16)WEBRTC_SPL_RSHIFT_W32(qi32 - ti32, shift);
frfi[2 * i] = (WebRtc_Word16)WEBRTC_SPL_RSHIFT_W32(qr32 + tr32, shift);
frfi[2 * i + 1] = (WebRtc_Word16)WEBRTC_SPL_RSHIFT_W32(qi32 + ti32, shift);
}
}
} else
{
// mode==1: High-complexity and High-accuracy mode
for (m = 0; m < l; ++m)
{
j = m << k;
/* The 256-value is a constant given as 1/4 of the size of
* WebRtcSpl_kSinTable1024[], and should not be changed depending on the input
* parameter 'stages'. It will result in 0 <= j < N_SINE_WAVE/2
*/
wr = WebRtcSpl_kSinTable1024[j + 256];
wi = WebRtcSpl_kSinTable1024[j];
for (i = m; i < n; i += istep)
{
j = i + l;
tr32 = WEBRTC_SPL_RSHIFT_W32((WEBRTC_SPL_MUL_16_16_RSFT(wr, frfi[2 * j], 0)
- WEBRTC_SPL_MUL_16_16_RSFT(wi, frfi[2 * j + 1], 0) + CIFFTRND),
15 - CIFFTSFT);
ti32 = WEBRTC_SPL_RSHIFT_W32(
(WEBRTC_SPL_MUL_16_16_RSFT(wr, frfi[2 * j + 1], 0)
+ WEBRTC_SPL_MUL_16_16_RSFT(wi, frfi[2 * j], 0)
+ CIFFTRND), 15 - CIFFTSFT);
qr32 = ((WebRtc_Word32)frfi[2 * i]) << CIFFTSFT;
qi32 = ((WebRtc_Word32)frfi[2 * i + 1]) << CIFFTSFT;
frfi[2 * j] = (WebRtc_Word16)WEBRTC_SPL_RSHIFT_W32((qr32 - tr32+round2),
shift+CIFFTSFT);
frfi[2 * j + 1] = (WebRtc_Word16)WEBRTC_SPL_RSHIFT_W32(
(qi32 - ti32 + round2), shift + CIFFTSFT);
frfi[2 * i] = (WebRtc_Word16)WEBRTC_SPL_RSHIFT_W32((qr32 + tr32 + round2),
shift + CIFFTSFT);
frfi[2 * i + 1] = (WebRtc_Word16)WEBRTC_SPL_RSHIFT_W32(
(qi32 + ti32 + round2), shift + CIFFTSFT);
}
}
}
--k;
l = istep;
}
return scale;
}

View File

@ -0,0 +1,45 @@
/*
* copy_from_begin_u8.c
*
* This file contains the function WebRtcSpl_CopyFromBeginU8().
* The description header can be found in signal_processing_library.h
*
*/
#include <string.h>
#ifdef _DEBUG
#include <stdio.h>
#include <stdlib.h>
#endif
#include "signal_processing_library.h"
WebRtc_Word16 WebRtcSpl_CopyFromBeginU8(G_CONST unsigned char *vector_in,
WebRtc_Word16 length,
WebRtc_Word16 samples,
unsigned char *vector_out,
WebRtc_Word16 max_length)
{
#ifdef _DEBUG
if (length < samples)
{
printf("CopyFromBeginU8 : vector_in shorter than requested length\n");
exit(0);
}
if (max_length < samples)
{
printf("CopyFromBeginU8 : vector_out shorter than requested length\n");
exit(0);
}
#endif
// Unused input variable
max_length = max_length;
length = length;
// Copy the first <samples> of the input vector to vector_out
// A unsigned char is 1 bytes long
WEBRTC_SPL_MEMCPY_W8(vector_out, vector_in, samples);
return samples;
}

View File

@ -0,0 +1,44 @@
/*
* copy_from_begin_w16.c
*
* This file contains the function WebRtcSpl_CopyFromBeginW16().
* The description header can be found in signal_processing_library.h
*
*/
#include <string.h>
#ifdef _DEBUG
#include <stdio.h>
#include <stdlib.h>
#endif
#include "signal_processing_library.h"
WebRtc_Word16 WebRtcSpl_CopyFromBeginW16(G_CONST WebRtc_Word16 *vector_in,
WebRtc_Word16 length,
WebRtc_Word16 samples,
WebRtc_Word16 *vector_out,
WebRtc_Word16 max_length)
{
#ifdef _DEBUG
if (length < samples)
{
printf(" CopyFromBeginW16 : vector_in shorter than requested length\n");
exit(0);
}
if (max_length < samples)
{
printf(" CopyFromBeginW16 : vector_out shorter than requested length\n");
exit(0);
}
#endif
// Unused input variable
length = length;
max_length = max_length;
// Copy the first <samples> of the input vector to vector_out
// A WebRtc_Word16 is 2 bytes long
WEBRTC_SPL_MEMCPY_W16(vector_out, vector_in, samples);
return samples;
}

View File

@ -0,0 +1,45 @@
/*
* copy_from_begin_w32.c
*
* This file contains the function WebRtcSpl_CopyFromBeginW32().
* The description header can be found in signal_processing_library.h
*
*/
#include <string.h>
#ifdef _DEBUG
#include <stdio.h>
#include <stdlib.h>
#endif
#include "signal_processing_library.h"
WebRtc_Word16 WebRtcSpl_CopyFromBeginW32(G_CONST WebRtc_Word32 *vector_in,
WebRtc_Word16 length,
WebRtc_Word16 samples,
WebRtc_Word32 *vector_out,
WebRtc_Word16 max_length)
{
#ifdef _DEBUG
if (length < samples)
{
printf(" CopyFromBeginW32 : invector shorter than requested length\n");
exit(0);
}
if (max_length < samples)
{
printf(" CopyFromBeginW32 : outvector shorter than requested length\n");
exit(0);
}
#endif
// Unused input variable
max_length = max_length;
length = length;
// Copy the first <samples> of the input vector to vector_out
// A WebRtc_Word32 is 4 bytes long
WEBRTC_SPL_MEMCPY_W32(vector_out, vector_in, samples);
return samples;
}

View File

@ -0,0 +1,45 @@
/*
* copy_from_end_u8.c
*
* This file contains the function WebRtcSpl_CopyFromEndU8().
* The description header can be found in signal_processing_library.h
*
*/
#include <string.h>
#include "signal_processing_library.h"
#ifdef _DEBUG
#include <stdio.h>
#include <stdlib.h>
#endif
WebRtc_Word16 WebRtcSpl_CopyFromEndU8(G_CONST unsigned char *vector_in,
WebRtc_Word16 length,
WebRtc_Word16 samples,
unsigned char *vector_out,
WebRtc_Word16 max_length)
{
#ifdef _DEBUG
if (length < samples)
{
printf("CopyFromEndU8 : vector_in shorter than requested length\n");
exit(0);
}
if (max_length < samples)
{
printf("CopyFromEndU8 : vector_out shorter than requested length\n");
exit(0);
}
#endif
// Unused input variable
max_length = max_length;
// Copy the last <samples> of the input vector to vector_out
// An unsigned char is 1 bytes long
WEBRTC_SPL_MEMCPY_W8(vector_out, &vector_in[length - samples], samples);
return samples;
}

View File

@ -0,0 +1,34 @@
/*
* 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.
*/
/*
* This file contains the function WebRtcSpl_CopyFromEndW16().
* The description header can be found in signal_processing_library.h
*
*/
#include <string.h>
#include "signal_processing_library.h"
WebRtc_Word16 WebRtcSpl_CopyFromEndW16(G_CONST WebRtc_Word16 *vector_in,
WebRtc_Word16 length,
WebRtc_Word16 samples,
WebRtc_Word16 *vector_out,
WebRtc_Word16 max_length)
{
// Unused input variable
max_length = max_length;
// Copy the last <samples> of the input vector to vector_out
WEBRTC_SPL_MEMCPY_W16(vector_out, &vector_in[length - samples], samples);
return samples;
}

View File

@ -0,0 +1,44 @@
/*
* copy_from_end_w32.c
*
* This file contains the function WebRtcSpl_CopyFromEndW32().
* The description header can be found in signal_processing_library.h
*
*/
#include <string.h>
#include "signal_processing_library.h"
#ifdef _DEBUG
#include <stdio.h>
#include <stdlib.h>
#endif
WebRtc_Word16 WebRtcSpl_CopyFromEndW32(G_CONST WebRtc_Word32 *vector_in,
WebRtc_Word16 length,
WebRtc_Word16 samples,
WebRtc_Word32 *vector_out,
WebRtc_Word16 max_length)
{
#ifdef _DEBUG
if (length < samples)
{
printf("CopyFromEndW32 : vector_in shorter than requested length\n");
exit(0);
}
if (max_length < samples)
{
printf("CopyFromEndW32 : vector_out shorter than requested length\n");
exit(0);
}
#endif
// Unused input variable
max_length = max_length;
// Copy the last <samples> of the input vector to vector_out
// A WebRtc_Word32 is 4 bytes long
WEBRTC_SPL_MEMCPY_W32(vector_out, &vector_in[length - samples], samples);
return samples;
}

View File

@ -0,0 +1,42 @@
/*
* copy_from_mid_u8.c
*
* This file contains the function WebRtcSpl_CopyFromMidU8().
* The description header can be found in signal_processing_library.h
*
*/
#include <string.h>
#ifdef _DEBUG
#include <stdio.h>
#include <stdlib.h>
#endif
#include "signal_processing_library.h"
WebRtc_Word16 WebRtcSpl_CopyFromMidU8(unsigned char *vector_in, WebRtc_Word16 length,
WebRtc_Word16 startpos, WebRtc_Word16 samples,
unsigned char *vector_out, WebRtc_Word16 max_length)
{
#ifdef _DEBUG
if (length < samples + startpos)
{
printf("chmid : invector copy out of bounds\n");
exit(0);
}
if (max_length < samples)
{
printf("chmid : outvector shorter than requested length\n");
exit(0);
}
#endif
/* Unused input variable */
max_length = max_length;
length = length;
/* Copy the <samples> from pos <start> of the input vector to vector_out */
/* A unsigned char is 1 bytes long */
WEBRTC_SPL_MEMCPY_W8(vector_out,&vector_in[startpos],samples);
return (samples);
}

View File

@ -0,0 +1,36 @@
/*
*/
#include <string.h>
#ifdef _DEBUG
#include <stdio.h>
#include <stdlib.h>
#endif
#include "signal_processing_library.h"
WebRtc_Word16 WebRtcSpl_CopyFromMidW16(G_CONST WebRtc_Word16 *vector_in, WebRtc_Word16 length,
WebRtc_Word16 startpos, WebRtc_Word16 samples,
WebRtc_Word16 *vector_out, WebRtc_Word16 max_length)
{
#ifdef _DEBUG
if (length < samples + startpos)
{
printf("w16mid : invector copy out of bounds\n");
exit(0);
}
if (max_length < samples)
{
printf("w16mid : outvector shorter than requested length\n");
exit(0);
}
#endif
/* Unused input variable */
length = length;
max_length = max_length;
/* Copy the <samples> from pos <start> of the input vector to vector_out */
/* A WebRtc_Word16 is 2 bytes long */
WEBRTC_SPL_MEMCPY_W16(vector_out, &vector_in[startpos], samples);
return (samples);
}

View File

@ -0,0 +1,37 @@
/*
*/
#include <string.h>
#ifdef _DEBUG
#include <stdio.h>
#include <stdlib.h>
#endif
#include "signal_processing_library.h"
WebRtc_Word16 WebRtcSpl_CopyFromMidW32(G_CONST WebRtc_Word32 *vector_in, WebRtc_Word16 length,
WebRtc_Word16 startpos, WebRtc_Word16 samples,
WebRtc_Word32 *vector_out, WebRtc_Word16 max_length)
{
#ifdef _DEBUG
if (length < samples + startpos)
{
printf("w32mid : invector copy out of bounds\n");
exit(0);
}
if (max_length < samples)
{
printf("w32mid : outvector shorter than requested length\n");
exit(0);
}
#endif
/* Unused input variable */
max_length = max_length;
length = length;
/* Copy the <samples> from pos <start> of the input vector to vector_out */
/* A WebRtc_Word32 is 4 bytes long */
WEBRTC_SPL_MEMCPY_W32(vector_out,&vector_in[startpos],samples);
return (samples);
}

View File

@ -0,0 +1,108 @@
/*
* 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.
*/
/*
* This file contains the implementation of functions
* WebRtcSpl_MemSetW16()
* WebRtcSpl_MemSetW32()
* WebRtcSpl_MemCpyReversedOrder()
* WebRtcSpl_CopyFromEndW16()
* WebRtcSpl_ZerosArrayW16()
* WebRtcSpl_ZerosArrayW32()
* WebRtcSpl_OnesArrayW16()
* WebRtcSpl_OnesArrayW32()
*
* The description header can be found in signal_processing_library.h
*
*/
#include <string.h>
#include "signal_processing_library.h"
void WebRtcSpl_MemSetW16(WebRtc_Word16 *ptr, WebRtc_Word16 set_value, int length)
{
int j;
WebRtc_Word16 *arrptr = ptr;
for (j = length; j > 0; j--)
{
*arrptr++ = set_value;
}
}
void WebRtcSpl_MemSetW32(WebRtc_Word32 *ptr, WebRtc_Word32 set_value, int length)
{
int j;
WebRtc_Word32 *arrptr = ptr;
for (j = length; j > 0; j--)
{
*arrptr++ = set_value;
}
}
void WebRtcSpl_MemCpyReversedOrder(WebRtc_Word16* dest, WebRtc_Word16* source, int length)
{
int j;
WebRtc_Word16* destPtr = dest;
WebRtc_Word16* sourcePtr = source;
for (j = 0; j < length; j++)
{
*destPtr-- = *sourcePtr++;
}
}
WebRtc_Word16 WebRtcSpl_CopyFromEndW16(G_CONST WebRtc_Word16 *vector_in,
WebRtc_Word16 length,
WebRtc_Word16 samples,
WebRtc_Word16 *vector_out)
{
// Copy the last <samples> of the input vector to vector_out
WEBRTC_SPL_MEMCPY_W16(vector_out, &vector_in[length - samples], samples);
return samples;
}
WebRtc_Word16 WebRtcSpl_ZerosArrayW16(WebRtc_Word16 *vector, WebRtc_Word16 length)
{
WebRtcSpl_MemSetW16(vector, 0, length);
return length;
}
WebRtc_Word16 WebRtcSpl_ZerosArrayW32(WebRtc_Word32 *vector, WebRtc_Word16 length)
{
WebRtcSpl_MemSetW32(vector, 0, length);
return length;
}
WebRtc_Word16 WebRtcSpl_OnesArrayW16(WebRtc_Word16 *vector, WebRtc_Word16 length)
{
WebRtc_Word16 i;
WebRtc_Word16 *tmpvec = vector;
for (i = 0; i < length; i++)
{
*tmpvec++ = 1;
}
return length;
}
WebRtc_Word16 WebRtcSpl_OnesArrayW32(WebRtc_Word32 *vector, WebRtc_Word16 length)
{
WebRtc_Word16 i;
WebRtc_Word32 *tmpvec = vector;
for (i = 0; i < length; i++)
{
*tmpvec++ = 1;
}
return length;
}

View File

@ -0,0 +1,60 @@
/*
* 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.
*/
/*
* This file contains the 360 degree cos table.
*
*/
#include "signal_processing_library.h"
WebRtc_Word16 WebRtcSpl_kCosTable[] = {
8192, 8190, 8187, 8180, 8172, 8160, 8147, 8130, 8112,
8091, 8067, 8041, 8012, 7982, 7948, 7912, 7874, 7834,
7791, 7745, 7697, 7647, 7595, 7540, 7483, 7424, 7362,
7299, 7233, 7164, 7094, 7021, 6947, 6870, 6791, 6710,
6627, 6542, 6455, 6366, 6275, 6182, 6087, 5991, 5892,
5792, 5690, 5586, 5481, 5374, 5265, 5155, 5043, 4930,
4815, 4698, 4580, 4461, 4341, 4219, 4096, 3971, 3845,
3719, 3591, 3462, 3331, 3200, 3068, 2935, 2801, 2667,
2531, 2395, 2258, 2120, 1981, 1842, 1703, 1563, 1422,
1281, 1140, 998, 856, 713, 571, 428, 285, 142,
0, -142, -285, -428, -571, -713, -856, -998, -1140,
-1281, -1422, -1563, -1703, -1842, -1981, -2120, -2258, -2395,
-2531, -2667, -2801, -2935, -3068, -3200, -3331, -3462, -3591,
-3719, -3845, -3971, -4095, -4219, -4341, -4461, -4580, -4698,
-4815, -4930, -5043, -5155, -5265, -5374, -5481, -5586, -5690,
-5792, -5892, -5991, -6087, -6182, -6275, -6366, -6455, -6542,
-6627, -6710, -6791, -6870, -6947, -7021, -7094, -7164, -7233,
-7299, -7362, -7424, -7483, -7540, -7595, -7647, -7697, -7745,
-7791, -7834, -7874, -7912, -7948, -7982, -8012, -8041, -8067,
-8091, -8112, -8130, -8147, -8160, -8172, -8180, -8187, -8190,
-8191, -8190, -8187, -8180, -8172, -8160, -8147, -8130, -8112,
-8091, -8067, -8041, -8012, -7982, -7948, -7912, -7874, -7834,
-7791, -7745, -7697, -7647, -7595, -7540, -7483, -7424, -7362,
-7299, -7233, -7164, -7094, -7021, -6947, -6870, -6791, -6710,
-6627, -6542, -6455, -6366, -6275, -6182, -6087, -5991, -5892,
-5792, -5690, -5586, -5481, -5374, -5265, -5155, -5043, -4930,
-4815, -4698, -4580, -4461, -4341, -4219, -4096, -3971, -3845,
-3719, -3591, -3462, -3331, -3200, -3068, -2935, -2801, -2667,
-2531, -2395, -2258, -2120, -1981, -1842, -1703, -1563, -1422,
-1281, -1140, -998, -856, -713, -571, -428, -285, -142,
0, 142, 285, 428, 571, 713, 856, 998, 1140,
1281, 1422, 1563, 1703, 1842, 1981, 2120, 2258, 2395,
2531, 2667, 2801, 2935, 3068, 3200, 3331, 3462, 3591,
3719, 3845, 3971, 4095, 4219, 4341, 4461, 4580, 4698,
4815, 4930, 5043, 5155, 5265, 5374, 5481, 5586, 5690,
5792, 5892, 5991, 6087, 6182, 6275, 6366, 6455, 6542,
6627, 6710, 6791, 6870, 6947, 7021, 7094, 7164, 7233,
7299, 7362, 7424, 7483, 7540, 7595, 7647, 7697, 7745,
7791, 7834, 7874, 7912, 7948, 7982, 8012, 8041, 8067,
8091, 8112, 8130, 8147, 8160, 8172, 8180, 8187, 8190
};

View File

@ -0,0 +1,267 @@
/*
* 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.
*/
/*
* This file contains the function WebRtcSpl_CrossCorrelation().
* The description header can be found in signal_processing_library.h
*
*/
#include "signal_processing_library.h"
void WebRtcSpl_CrossCorrelation(WebRtc_Word32* cross_correlation, WebRtc_Word16* seq1,
WebRtc_Word16* seq2, WebRtc_Word16 dim_seq,
WebRtc_Word16 dim_cross_correlation,
WebRtc_Word16 right_shifts,
WebRtc_Word16 step_seq2)
{
int i, j;
WebRtc_Word16* seq1Ptr;
WebRtc_Word16* seq2Ptr;
WebRtc_Word32* CrossCorrPtr;
#ifdef _XSCALE_OPT_
#ifdef _WIN32
#pragma message("NOTE: _XSCALE_OPT_ optimizations are used (overrides _ARM_OPT_ and requires /QRxscale compiler flag)")
#endif
__int64 macc40;
int iseq1[250];
int iseq2[250];
int iseq3[250];
int * iseq1Ptr;
int * iseq2Ptr;
int * iseq3Ptr;
int len, i_len;
seq1Ptr = seq1;
iseq1Ptr = iseq1;
for(i = 0; i < ((dim_seq + 1) >> 1); i++)
{
*iseq1Ptr = (unsigned short)*seq1Ptr++;
*iseq1Ptr++ |= (WebRtc_Word32)*seq1Ptr++ << 16;
}
if(dim_seq%2)
{
*(iseq1Ptr-1) &= 0x0000ffff;
}
*iseq1Ptr = 0;
iseq1Ptr++;
*iseq1Ptr = 0;
iseq1Ptr++;
*iseq1Ptr = 0;
if(step_seq2 < 0)
{
seq2Ptr = seq2 - dim_cross_correlation + 1;
CrossCorrPtr = &cross_correlation[dim_cross_correlation - 1];
}
else
{
seq2Ptr = seq2;
CrossCorrPtr = cross_correlation;
}
len = dim_seq + dim_cross_correlation - 1;
i_len = (len + 1) >> 1;
iseq2Ptr = iseq2;
iseq3Ptr = iseq3;
for(i = 0; i < i_len; i++)
{
*iseq2Ptr = (unsigned short)*seq2Ptr++;
*iseq3Ptr = (unsigned short)*seq2Ptr;
*iseq2Ptr++ |= (WebRtc_Word32)*seq2Ptr++ << 16;
*iseq3Ptr++ |= (WebRtc_Word32)*seq2Ptr << 16;
}
if(len % 2)
{
iseq2[i_len - 1] &= 0x0000ffff;
iseq3[i_len - 1] = 0;
}
else
iseq3[i_len - 1] &= 0x0000ffff;
iseq2[i_len] = 0;
iseq3[i_len] = 0;
iseq2[i_len + 1] = 0;
iseq3[i_len + 1] = 0;
iseq2[i_len + 2] = 0;
iseq3[i_len + 2] = 0;
// Set pointer to start value
iseq2Ptr = iseq2;
iseq3Ptr = iseq3;
i_len = (dim_seq + 7) >> 3;
for (i = 0; i < dim_cross_correlation; i++)
{
iseq1Ptr = iseq1;
macc40 = 0;
_WriteCoProcessor(macc40, 0);
if((i & 1))
{
iseq3Ptr = iseq3 + (i >> 1);
for (j = i_len; j > 0; j--)
{
_SmulAddPack_2SW_ACC(*iseq1Ptr++, *iseq3Ptr++);
_SmulAddPack_2SW_ACC(*iseq1Ptr++, *iseq3Ptr++);
_SmulAddPack_2SW_ACC(*iseq1Ptr++, *iseq3Ptr++);
_SmulAddPack_2SW_ACC(*iseq1Ptr++, *iseq3Ptr++);
}
}
else
{
iseq2Ptr = iseq2 + (i >> 1);
for (j = i_len; j > 0; j--)
{
_SmulAddPack_2SW_ACC(*iseq1Ptr++, *iseq2Ptr++);
_SmulAddPack_2SW_ACC(*iseq1Ptr++, *iseq2Ptr++);
_SmulAddPack_2SW_ACC(*iseq1Ptr++, *iseq2Ptr++);
_SmulAddPack_2SW_ACC(*iseq1Ptr++, *iseq2Ptr++);
}
}
macc40 = _ReadCoProcessor(0);
*CrossCorrPtr = (WebRtc_Word32)(macc40 >> right_shifts);
CrossCorrPtr += step_seq2;
}
#else // #ifdef _XSCALE_OPT_
#ifdef _ARM_OPT_
WebRtc_Word16 dim_seq8 = (dim_seq >> 3) << 3;
#endif
CrossCorrPtr = cross_correlation;
for (i = 0; i < dim_cross_correlation; i++)
{
// Set the pointer to the static vector, set the pointer to the sliding vector
// and initialize cross_correlation
seq1Ptr = seq1;
seq2Ptr = seq2 + (step_seq2 * i);
(*CrossCorrPtr) = 0;
#ifndef _ARM_OPT_
#ifdef _WIN32
#pragma message("NOTE: default implementation is used")
#endif
// Perform the cross correlation
for (j = 0; j < dim_seq; j++)
{
(*CrossCorrPtr) += WEBRTC_SPL_MUL_16_16_RSFT((*seq1Ptr), (*seq2Ptr), right_shifts);
seq1Ptr++;
seq2Ptr++;
}
#else
#ifdef _WIN32
#pragma message("NOTE: _ARM_OPT_ optimizations are used")
#endif
if (right_shifts == 0)
{
// Perform the optimized cross correlation
for (j = 0; j < dim_seq8; j = j + 8)
{
(*CrossCorrPtr) += WEBRTC_SPL_MUL_16_16((*seq1Ptr), (*seq2Ptr));
seq1Ptr++;
seq2Ptr++;
(*CrossCorrPtr) += WEBRTC_SPL_MUL_16_16((*seq1Ptr), (*seq2Ptr));
seq1Ptr++;
seq2Ptr++;
(*CrossCorrPtr) += WEBRTC_SPL_MUL_16_16((*seq1Ptr), (*seq2Ptr));
seq1Ptr++;
seq2Ptr++;
(*CrossCorrPtr) += WEBRTC_SPL_MUL_16_16((*seq1Ptr), (*seq2Ptr));
seq1Ptr++;
seq2Ptr++;
(*CrossCorrPtr) += WEBRTC_SPL_MUL_16_16((*seq1Ptr), (*seq2Ptr));
seq1Ptr++;
seq2Ptr++;
(*CrossCorrPtr) += WEBRTC_SPL_MUL_16_16((*seq1Ptr), (*seq2Ptr));
seq1Ptr++;
seq2Ptr++;
(*CrossCorrPtr) += WEBRTC_SPL_MUL_16_16((*seq1Ptr), (*seq2Ptr));
seq1Ptr++;
seq2Ptr++;
(*CrossCorrPtr) += WEBRTC_SPL_MUL_16_16((*seq1Ptr), (*seq2Ptr));
seq1Ptr++;
seq2Ptr++;
}
for (j = dim_seq8; j < dim_seq; j++)
{
(*CrossCorrPtr) += WEBRTC_SPL_MUL_16_16((*seq1Ptr), (*seq2Ptr));
seq1Ptr++;
seq2Ptr++;
}
}
else // right_shifts != 0
{
// Perform the optimized cross correlation
for (j = 0; j < dim_seq8; j = j + 8)
{
(*CrossCorrPtr) += WEBRTC_SPL_MUL_16_16_RSFT((*seq1Ptr), (*seq2Ptr),
right_shifts);
seq1Ptr++;
seq2Ptr++;
(*CrossCorrPtr) += WEBRTC_SPL_MUL_16_16_RSFT((*seq1Ptr), (*seq2Ptr),
right_shifts);
seq1Ptr++;
seq2Ptr++;
(*CrossCorrPtr) += WEBRTC_SPL_MUL_16_16_RSFT((*seq1Ptr), (*seq2Ptr),
right_shifts);
seq1Ptr++;
seq2Ptr++;
(*CrossCorrPtr) += WEBRTC_SPL_MUL_16_16_RSFT((*seq1Ptr), (*seq2Ptr),
right_shifts);
seq1Ptr++;
seq2Ptr++;
(*CrossCorrPtr) += WEBRTC_SPL_MUL_16_16_RSFT((*seq1Ptr), (*seq2Ptr),
right_shifts);
seq1Ptr++;
seq2Ptr++;
(*CrossCorrPtr) += WEBRTC_SPL_MUL_16_16_RSFT((*seq1Ptr), (*seq2Ptr),
right_shifts);
seq1Ptr++;
seq2Ptr++;
(*CrossCorrPtr) += WEBRTC_SPL_MUL_16_16_RSFT((*seq1Ptr), (*seq2Ptr),
right_shifts);
seq1Ptr++;
seq2Ptr++;
(*CrossCorrPtr) += WEBRTC_SPL_MUL_16_16_RSFT((*seq1Ptr), (*seq2Ptr),
right_shifts);
seq1Ptr++;
seq2Ptr++;
}
for (j = dim_seq8; j < dim_seq; j++)
{
(*CrossCorrPtr) += WEBRTC_SPL_MUL_16_16_RSFT((*seq1Ptr), (*seq2Ptr),
right_shifts);
seq1Ptr++;
seq2Ptr++;
}
}
#endif
CrossCorrPtr++;
}
#endif
}

View File

@ -0,0 +1,48 @@
/*
* div_result_in_q31.c
*
* This file contains the function WebRtcSpl_DivResultInQ31().
* The description header can be found in signal_processing_library.h
*
*/
#include "signal_processing_library.h"
WebRtc_Word32 WebRtcSpl_DivResultInQ31(WebRtc_Word32 num, WebRtc_Word32 den)
{
WebRtc_Word32 L_num = num;
WebRtc_Word32 L_den = den;
WebRtc_Word32 div = 0;
int k = 31;
int change_sign = 0;
if (num == 0)
return 0;
if (num < 0)
{
change_sign++;
L_num = -num;
}
if (den < 0)
{
change_sign++;
L_den = -den;
}
while (k--)
{
div <<= 1;
//L_den <<= 1;
L_num <<= 1;
if (L_num >= L_den)
{
L_num -= L_den;
div++;
}
}
if (change_sign == 1)
{
div = -div;
}
return div;
}

View File

@ -0,0 +1,21 @@
/*
* div_u32_u16.c
*
* This file contains the function WebRtcSpl_DivU32U16().
* The description header can be found in signal_processing_library.h
*
*/
#include "signal_processing_library.h"
WebRtc_UWord32 WebRtcSpl_DivU32U16(WebRtc_UWord32 num, WebRtc_UWord16 den)
{
// Guard against division with 0
if (den != 0)
{
return ((WebRtc_UWord32)(num / den));
} else
{
return ((WebRtc_UWord32)0xFFFFFFFF);
}
}

View File

@ -0,0 +1,55 @@
/*
* div_w32_hi_low.c
*
* This file contains the function WebRtcSpl_DivW32HiLow().
* The description header can be found in signal_processing_library.h
*
*/
#include "signal_processing_library.h"
WebRtc_Word32 WebRtcSpl_DivW32HiLow(WebRtc_Word32 num, WebRtc_Word16 den_hi,
WebRtc_Word16 den_low)
{
WebRtc_Word16 approx, tmp_hi, tmp_low, num_hi, num_low;
WebRtc_Word32 tmpW32;
approx = (WebRtc_Word16)WebRtcSpl_DivW32W16((WebRtc_Word32)0x1FFFFFFF, den_hi);
// result in Q14 (Note: 3FFFFFFF = 0.5 in Q30)
// tmpW32 = 1/den = approx * (2.0 - den * approx) (in Q30)
tmpW32 = (WEBRTC_SPL_MUL_16_16(den_hi, approx) << 1)
+ ((WEBRTC_SPL_MUL_16_16(den_low, approx) >> 15) << 1);
// tmpW32 = den * approx
tmpW32 = (WebRtc_Word32)0x7fffffffL - tmpW32; // result in Q30 (tmpW32 = 2.0-(den*approx))
// Store tmpW32 in hi and low format
tmp_hi = (WebRtc_Word16)WEBRTC_SPL_RSHIFT_W32(tmpW32, 16);
tmp_low = (WebRtc_Word16)WEBRTC_SPL_RSHIFT_W32((tmpW32
- WEBRTC_SPL_LSHIFT_W32((WebRtc_Word32)tmp_hi, 16)), 1);
// tmpW32 = 1/den in Q29
tmpW32 = ((WEBRTC_SPL_MUL_16_16(tmp_hi, approx) + (WEBRTC_SPL_MUL_16_16(tmp_low, approx)
>> 15)) << 1);
// 1/den in hi and low format
tmp_hi = (WebRtc_Word16)WEBRTC_SPL_RSHIFT_W32(tmpW32, 16);
tmp_low = (WebRtc_Word16)WEBRTC_SPL_RSHIFT_W32((tmpW32
- WEBRTC_SPL_LSHIFT_W32((WebRtc_Word32)tmp_hi, 16)), 1);
// Store num in hi and low format
num_hi = (WebRtc_Word16)WEBRTC_SPL_RSHIFT_W32(num, 16);
num_low = (WebRtc_Word16)WEBRTC_SPL_RSHIFT_W32((num
- WEBRTC_SPL_LSHIFT_W32((WebRtc_Word32)num_hi, 16)), 1);
// num * (1/den) by 32 bit multiplication (result in Q28)
tmpW32 = (WEBRTC_SPL_MUL_16_16(num_hi, tmp_hi) + (WEBRTC_SPL_MUL_16_16(num_hi, tmp_low)
>> 15) + (WEBRTC_SPL_MUL_16_16(num_low, tmp_hi) >> 15));
// Put result in Q31 (convert from Q28)
tmpW32 = WEBRTC_SPL_LSHIFT_W32(tmpW32, 3);
return tmpW32;
}

View File

@ -0,0 +1,21 @@
/*
* div_w32_w16.c
*
* This file contains the function WebRtcSpl_DivW32W16().
* The description header can be found in signal_processing_library.h
*
*/
#include "signal_processing_library.h"
WebRtc_Word32 WebRtcSpl_DivW32W16(WebRtc_Word32 num, WebRtc_Word16 den)
{
// Guard against division with 0
if (den != 0)
{
return ((WebRtc_Word32)(num / den));
} else
{
return ((WebRtc_Word32)0x7FFFFFFF);
}
}

View File

@ -0,0 +1,21 @@
/*
* div_w32_w16_res_w16.c
*
* This file contains the function WebRtcSpl_DivW32W16ResW16().
* The description header can be found in signal_processing_library.h
*
*/
#include "signal_processing_library.h"
WebRtc_Word16 WebRtcSpl_DivW32W16ResW16(WebRtc_Word32 num, WebRtc_Word16 den)
{
// Guard against division with 0
if (den != 0)
{
return (WebRtc_Word16)(num / den);
} else
{
return (WebRtc_Word16)0x7FFF;
}
}

View File

@ -0,0 +1,144 @@
/*
* 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.
*/
/*
* This file contains implementations of the divisions
* WebRtcSpl_DivU32U16()
* WebRtcSpl_DivW32W16()
* WebRtcSpl_DivW32W16ResW16()
* WebRtcSpl_DivResultInQ31()
* WebRtcSpl_DivW32HiLow()
*
* The description header can be found in signal_processing_library.h
*
*/
#include "signal_processing_library.h"
WebRtc_UWord32 WebRtcSpl_DivU32U16(WebRtc_UWord32 num, WebRtc_UWord16 den)
{
// Guard against division with 0
if (den != 0)
{
return (WebRtc_UWord32)(num / den);
} else
{
return (WebRtc_UWord32)0xFFFFFFFF;
}
}
WebRtc_Word32 WebRtcSpl_DivW32W16(WebRtc_Word32 num, WebRtc_Word16 den)
{
// Guard against division with 0
if (den != 0)
{
return (WebRtc_Word32)(num / den);
} else
{
return (WebRtc_Word32)0x7FFFFFFF;
}
}
WebRtc_Word16 WebRtcSpl_DivW32W16ResW16(WebRtc_Word32 num, WebRtc_Word16 den)
{
// Guard against division with 0
if (den != 0)
{
return (WebRtc_Word16)(num / den);
} else
{
return (WebRtc_Word16)0x7FFF;
}
}
WebRtc_Word32 WebRtcSpl_DivResultInQ31(WebRtc_Word32 num, WebRtc_Word32 den)
{
WebRtc_Word32 L_num = num;
WebRtc_Word32 L_den = den;
WebRtc_Word32 div = 0;
int k = 31;
int change_sign = 0;
if (num == 0)
return 0;
if (num < 0)
{
change_sign++;
L_num = -num;
}
if (den < 0)
{
change_sign++;
L_den = -den;
}
while (k--)
{
div <<= 1;
L_num <<= 1;
if (L_num >= L_den)
{
L_num -= L_den;
div++;
}
}
if (change_sign == 1)
{
div = -div;
}
return div;
}
WebRtc_Word32 WebRtcSpl_DivW32HiLow(WebRtc_Word32 num, WebRtc_Word16 den_hi,
WebRtc_Word16 den_low)
{
WebRtc_Word16 approx, tmp_hi, tmp_low, num_hi, num_low;
WebRtc_Word32 tmpW32;
approx = (WebRtc_Word16)WebRtcSpl_DivW32W16((WebRtc_Word32)0x1FFFFFFF, den_hi);
// result in Q14 (Note: 3FFFFFFF = 0.5 in Q30)
// tmpW32 = 1/den = approx * (2.0 - den * approx) (in Q30)
tmpW32 = (WEBRTC_SPL_MUL_16_16(den_hi, approx) << 1)
+ ((WEBRTC_SPL_MUL_16_16(den_low, approx) >> 15) << 1);
// tmpW32 = den * approx
tmpW32 = (WebRtc_Word32)0x7fffffffL - tmpW32; // result in Q30 (tmpW32 = 2.0-(den*approx))
// Store tmpW32 in hi and low format
tmp_hi = (WebRtc_Word16)WEBRTC_SPL_RSHIFT_W32(tmpW32, 16);
tmp_low = (WebRtc_Word16)WEBRTC_SPL_RSHIFT_W32((tmpW32
- WEBRTC_SPL_LSHIFT_W32((WebRtc_Word32)tmp_hi, 16)), 1);
// tmpW32 = 1/den in Q29
tmpW32 = ((WEBRTC_SPL_MUL_16_16(tmp_hi, approx) + (WEBRTC_SPL_MUL_16_16(tmp_low, approx)
>> 15)) << 1);
// 1/den in hi and low format
tmp_hi = (WebRtc_Word16)WEBRTC_SPL_RSHIFT_W32(tmpW32, 16);
tmp_low = (WebRtc_Word16)WEBRTC_SPL_RSHIFT_W32((tmpW32
- WEBRTC_SPL_LSHIFT_W32((WebRtc_Word32)tmp_hi, 16)), 1);
// Store num in hi and low format
num_hi = (WebRtc_Word16)WEBRTC_SPL_RSHIFT_W32(num, 16);
num_low = (WebRtc_Word16)WEBRTC_SPL_RSHIFT_W32((num
- WEBRTC_SPL_LSHIFT_W32((WebRtc_Word32)num_hi, 16)), 1);
// num * (1/den) by 32 bit multiplication (result in Q28)
tmpW32 = (WEBRTC_SPL_MUL_16_16(num_hi, tmp_hi) + (WEBRTC_SPL_MUL_16_16(num_hi, tmp_low)
>> 15) + (WEBRTC_SPL_MUL_16_16(num_low, tmp_hi) >> 15));
// Put result in Q31 (convert from Q28)
tmpW32 = WEBRTC_SPL_LSHIFT_W32(tmpW32, 3);
return tmpW32;
}

View File

@ -0,0 +1,23 @@
/*
* dot_product.c
*
* This file contains the function WebRtcSpl_DotProduct().
* The description header can be found in signal_processing_library.h
*
*/
#include "signal_processing_library.h"
WebRtc_Word32 WebRtcSpl_DotProduct(WebRtc_Word16 *vector1, WebRtc_Word16 *vector2, int length)
{
WebRtc_Word32 sum;
int i;
sum = 0;
for (i = 0; i < length; i++)
{
sum += WEBRTC_SPL_MUL_16_16(*vector1++, *vector2++);
}
return sum;
}

View File

@ -0,0 +1,91 @@
/*
* 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.
*/
/*
* This file contains the function WebRtcSpl_DotProductWithScale().
* The description header can be found in signal_processing_library.h
*
*/
#include "signal_processing_library.h"
WebRtc_Word32 WebRtcSpl_DotProductWithScale(WebRtc_Word16 *vector1, WebRtc_Word16 *vector2,
int length, int scaling)
{
WebRtc_Word32 sum;
int i;
#ifdef _ARM_OPT_
#pragma message("NOTE: _ARM_OPT_ optimizations are used")
WebRtc_Word16 len4 = (length >> 2) << 2;
#endif
sum = 0;
#ifndef _ARM_OPT_
for (i = 0; i < length; i++)
{
sum += WEBRTC_SPL_MUL_16_16_RSFT(*vector1++, *vector2++, scaling);
}
#else
if (scaling == 0)
{
for (i = 0; i < len4; i = i + 4)
{
sum += WEBRTC_SPL_MUL_16_16(*vector1, *vector2);
vector1++;
vector2++;
sum += WEBRTC_SPL_MUL_16_16(*vector1, *vector2);
vector1++;
vector2++;
sum += WEBRTC_SPL_MUL_16_16(*vector1, *vector2);
vector1++;
vector2++;
sum += WEBRTC_SPL_MUL_16_16(*vector1, *vector2);
vector1++;
vector2++;
}
for (i = len4; i < length; i++)
{
sum += WEBRTC_SPL_MUL_16_16(*vector1, *vector2);
vector1++;
vector2++;
}
}
else
{
for (i = 0; i < len4; i = i + 4)
{
sum += WEBRTC_SPL_MUL_16_16_RSFT(*vector1, *vector2, scaling);
vector1++;
vector2++;
sum += WEBRTC_SPL_MUL_16_16_RSFT(*vector1, *vector2, scaling);
vector1++;
vector2++;
sum += WEBRTC_SPL_MUL_16_16_RSFT(*vector1, *vector2, scaling);
vector1++;
vector2++;
sum += WEBRTC_SPL_MUL_16_16_RSFT(*vector1, *vector2, scaling);
vector1++;
vector2++;
}
for (i = len4; i < length; i++)
{
sum += WEBRTC_SPL_MUL_16_16_RSFT(*vector1, *vector2, scaling);
vector1++;
vector2++;
}
}
#endif
return sum;
}

View File

@ -0,0 +1,93 @@
/*
* downsample.c
*
* This file contains the function WebRtcSpl_Downsample().
* The description header can be found in signal_processing_library.h
*
*/
#include "signal_processing_library.h"
int WebRtcSpl_Downsample(G_CONST WebRtc_Word16 *b, int b_length,
G_CONST WebRtc_Word16 *signal_in, int signal_length,
WebRtc_Word16 *state, int state_length,
WebRtc_Word16 *signal_downsampled, int max_length, int factor,
int delay)
{
WebRtc_Word32 o;
int i, j, stop;
WebRtc_Word16 *signal_downsampled_ptr = signal_downsampled;
G_CONST WebRtc_Word16 *b_ptr;
G_CONST WebRtc_Word16 *signal_in_ptr;
WebRtc_Word16 *state_ptr;
WebRtc_Word16 inc = 1 << factor;
// Unused input variable
max_length = max_length;
for (i = delay; i < signal_length; i += inc)
{
b_ptr = &b[0];
signal_in_ptr = &signal_in[i];
state_ptr = &state[state_length - 1];
o = (WebRtc_Word32)0;
stop = (i < b_length) ? i + 1 : b_length;
for (j = 0; j < stop; j++)
{
o += WEBRTC_SPL_MUL_16_16(*b_ptr++, *signal_in_ptr--);
}
for (j = i + 1; j < b_length; j++)
{
o += WEBRTC_SPL_MUL_16_16(*b_ptr++, *state_ptr--);
}
// If output is higher than 32768, saturate it. Same with negative side
// 2^27 = 134217728, which corresponds to 32768
if (o < (WebRtc_Word32)-134217728)
o = (WebRtc_Word32)-134217728;
if (o > (WebRtc_Word32)(134217727 - 2048))
o = (WebRtc_Word32)(134217727 - 2048);
*signal_downsampled_ptr++ = (WebRtc_Word16)((o + (WebRtc_Word32)2048) >> 12); //Q12 ops
}
// Get the last delay part.
for (i = ((signal_length >> factor) << factor) + inc; i < signal_length + delay; i += inc)
{
o = 0;
if (i < signal_length)
{
b_ptr = &b[0];
signal_in_ptr = &signal_in[i];
for (j = 0; j < b_length; j++)
{
o += WEBRTC_SPL_MUL_16_16(*b_ptr++, *signal_in_ptr--);
}
} else
{
b_ptr = &b[i - signal_length];
signal_in_ptr = &signal_in[signal_length - 1];
for (j = 0; j < b_length - (i - signal_length); j++)
{
o += WEBRTC_SPL_MUL_16_16(*b_ptr++, *signal_in_ptr--);
}
}
/* If output is higher than 32768, saturate it. Same with negative side
2^27 = 134217728, which corresponds to 32768
*/
if (o < (WebRtc_Word32)-134217728)
o = (WebRtc_Word32)-134217728;
if (o > (WebRtc_Word32)(134217727 - 2048))
o = (WebRtc_Word32)(134217727 - 2048);
*signal_downsampled_ptr++ = (WebRtc_Word16)((o + (WebRtc_Word32)2048) >> 12); //Q12 ops
}
return (signal_length >> factor);
}

View File

@ -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.
*/
/*
* This file contains the function WebRtcSpl_DownsampleFast().
* The description header can be found in signal_processing_library.h
*
*/
#include "signal_processing_library.h"
int WebRtcSpl_DownsampleFast(WebRtc_Word16 *in_ptr, WebRtc_Word16 in_length,
WebRtc_Word16 *out_ptr, WebRtc_Word16 out_length,
WebRtc_Word16 *B, WebRtc_Word16 B_length, WebRtc_Word16 factor,
WebRtc_Word16 delay)
{
WebRtc_Word32 o;
int i, j;
WebRtc_Word16 *downsampled_ptr = out_ptr;
WebRtc_Word16 *b_ptr;
WebRtc_Word16 *x_ptr;
WebRtc_Word16 endpos = delay
+ (WebRtc_Word16)WEBRTC_SPL_MUL_16_16(factor, (out_length - 1)) + 1;
if (in_length < endpos)
{
return -1;
}
for (i = delay; i < endpos; i += factor)
{
b_ptr = &B[0];
x_ptr = &in_ptr[i];
o = (WebRtc_Word32)2048; // Round val
for (j = 0; j < B_length; j++)
{
o += WEBRTC_SPL_MUL_16_16(*b_ptr++, *x_ptr--);
}
o = WEBRTC_SPL_RSHIFT_W32(o, 12);
// If output is higher than 32768, saturate it. Same with negative side
*downsampled_ptr++ = (WebRtc_Word16)WEBRTC_SPL_SAT(32767, o, -32768);
}
return 0;
}

View File

@ -0,0 +1,24 @@
/*
* elementwise_vector_mult.c
*
* This file contains the function WebRtcSpl_ElementwiseVectorMult().
* The description header can be found in signal_processing_library.h
*
*/
#include "signal_processing_library.h"
void WebRtcSpl_ElementwiseVectorMult(WebRtc_Word16 *out, G_CONST WebRtc_Word16 *in,
G_CONST WebRtc_Word16 *win, WebRtc_Word16 vector_length,
WebRtc_Word16 right_shifts)
{
int i;
WebRtc_Word16 *outptr = out;
G_CONST WebRtc_Word16 *inptr = in;
G_CONST WebRtc_Word16 *winptr = win;
for (i = 0; i < vector_length; i++)
{
(*outptr++) = (WebRtc_Word16)WEBRTC_SPL_MUL_16_16_RSFT(*inptr++,
*winptr++, right_shifts);
}
}

View File

@ -0,0 +1,36 @@
/*
* 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.
*/
/*
* This file contains the function WebRtcSpl_Energy().
* The description header can be found in signal_processing_library.h
*
*/
#include "signal_processing_library.h"
WebRtc_Word32 WebRtcSpl_Energy(WebRtc_Word16* vector, int vector_length, int* scale_factor)
{
WebRtc_Word32 en = 0;
int i;
int scaling = WebRtcSpl_GetScalingSquare(vector, vector_length, vector_length);
int looptimes = vector_length;
WebRtc_Word16 *vectorptr = vector;
for (i = 0; i < looptimes; i++)
{
en += WEBRTC_SPL_MUL_16_16_RSFT(*vectorptr, *vectorptr, scaling);
vectorptr++;
}
*scale_factor = scaling;
return en;
}

View File

@ -0,0 +1,51 @@
;// Optimised ARM assembler multi-radix FFT
INCLUDE fft_main_forward.h
MACRO
GENERATE_FFT_FUNCTION $flags
; first work out a readable function name
; based on the flags
FFT_OPTIONS_STRING $flags, name
; Entry:
; r0 = input array
; r1 = output array
; r2 = number of points in FFT
; r3 = pre-scale shift
;
; Exit:
; r0 = 0 if successful
; = 1 if table too small
;
EXPORT FFT_$name
FFT_4OFQ14
STMFD sp!, {r4-r11, r14}
IF "$radix"="4O"
tablename SETS "_8"
tablename SETS "$qname$coeforder$tablename"
ELSE
tablename SETS "_4"
tablename SETS "$qname$coeforder$tablename"
ENDIF
IMPORT s_$tablename
LDR lr, =s_$tablename
LDR lr,[lr]
CMP N, lr
MOVGT r0, #1
LDMGTFD sp!, {r4-r11, pc}
GENERATE_FFT $flags
MOV r0, #0
LDMFD sp!, {r4-r11, pc}
LTORG
MEND
AREA FFTCODE, CODE, READONLY
GENERATE_FFT_FUNCTION FFT_16bit +FFT_RADIX4_8F +FFT_FORWARD ; +FFT_REVERSED
END

View File

@ -0,0 +1,51 @@
;// Optimised ARM assembler multi-radix FFT
INCLUDE fft_main_inverse.h
MACRO
GENERATE_IFFT_FUNCTION $flags
; first work out a readable function name
; based on the flags
FFT_OPTIONS_STRING $flags, name
; Entry:
; r0 = input array
; r1 = output array
; r2 = number of points in FFT
; r3 = pre-scale shift
;
; Exit:
; r0 = 0 if successful
; = 1 if table too small
;
EXPORT FFT_$name
FFT_4OIQ14
STMFD sp!, {r4-r11, r14}
IF "$radix"="4O"
tablename SETS "_8"
tablename SETS "$qname$coeforder$tablename"
ELSE
tablename SETS "_4"
tablename SETS "$qname$coeforder$tablename"
ENDIF
IMPORT s_$tablename
LDR lr, =s_$tablename
LDR lr,[lr]
CMP N, lr
MOVGT r0, #1
LDMGTFD sp!, {r4-r11, pc}
GENERATE_FFT $flags
MOV r0, #0
LDMFD sp!, {r4-r11, pc}
LTORG
MEND
AREA FFTCODE, CODE, READONLY
GENERATE_IFFT_FUNCTION FFT_16bit +FFT_RADIX4_8F +FFT_INVERSE +FFT_NONORM ; +FFT_REVERSED
END

View File

@ -0,0 +1,774 @@
;
; $Copyright:
; ----------------------------------------------------------------
; This confidential and proprietary software may be used only as
; authorised by a licensing agreement from ARM Limited
; (C) COPYRIGHT 2000,2002 ARM Limited
; ALL RIGHTS RESERVED
; The entire notice above must be reproduced on all authorised
; copies and copies may only be made to the extent permitted
; by a licensing agreement from ARM Limited.
; ----------------------------------------------------------------
; File: fft_mac.h,v
; Revision: 1.14
; ----------------------------------------------------------------
; $
;
; Optimised ARM assembler multi-radix FFT
; Please read the readme.txt before this file
;
; Shared macros and interface definition file.
; NB: All the algorithms in this code are Decimation in Time. ARM
; is much better at Decimation in Time (as opposed to Decimation
; in Frequency) due to the position of the barrel shifter. Decimation
; in time has the twiddeling at the start of the butterfly, where as
; decimation in frequency has it at the end of the butterfly. The
; post multiply shifts can be hidden for Decimation in Time.
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;
; FIRST STAGE INTERFACE
;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;
; The FIRST STAGE macros "FS_RAD<R>" have the following interface:
;
; ON ENTRY:
; REGISTERS:
; r0 = inptr => points to the input buffer consisting of N complex
; numbers of size (1<<datainlog) bytes each
; r1 = dptr => points to the output buffer consisting of N complex
; numbers of size (1<<datalog) bytes each
; r2 = N => is the number of points in the transform
; r3 = pscale => shift to prescale input by (if applicable)
; ASSEMBLER VARIABLES:
; reversed => logical variable, true if input data is already bit reversed
; The data needs to be bit reversed otherwise
;
; ACTION:
; The routine should
; (1) Bit reverse the data as required for the whole FFT (unless
; the reversed flag is set)
; (2) Prescale the input data by
; (3) Perform a radix R first stage on the data
; (4) Place the processed data in the output array pointed to be dptr
;
; ON EXIT:
; r1 = dptr => preserved and pointing to the output data
; r2 = dinc => number of bytes per "block" or "Group" in this stage
; this is: R<<datalog
; r3 = count => number of radix-R blocks or groups processed in this stage
; this is: N/R
; r0,r4-r12,r14 corrupted
inptr RN 0 ; input buffer
dptr RN 1 ; output/scratch buffer
N RN 2 ; size of the FFT
dptr RN 1 ; data pointer - points to end (load in reverse order)
dinc RN 2 ; bytes between data elements at this level of FFT
count RN 3 ; (elements per block<<16) | (blocks per stage)
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;
; GENERAL STAGE INTERFACE
;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;
; The GENERAL STAGE macros "GS_RAD<R>" have the following interface.
;
; To describe the arguments, suppose this routine is called as stage j
; in a k-stage FFT with N=R1*R2*...*Rk. This stage is radix R=Rj.
;
; ON ENTRY:
; REGISTERS:
; r0 = cptr => Pointer to twiddle coefficients for this stage consisting
; of complex numbers of size (1<<coeflog) bytes each in some
; stage dependent format.
; The format currently used in described in full in the
; ReadMe file in the tables subdirectory.
; r1 = dptr => points to the working buffer consisting of N complex
; numbers of size (1<<datalog) bytes each
; r2 = dinc => number of bytes per "block" or "Group" in the last stage:
; dinc = (R1*R2*...*R(j-1))<<datalog
; r3 = count => number of blocks or Groups in the last stage:
; count = Rj*R(j+1)*...*Rk
; NB dinc*count = N<<datalog
;
; ACTION:
; The routine should
; (1) Twiddle the input data
; (2) Perform a radix R stage on the data
; (3) Perform the actions in place, result written to the dptr buffer
;
; ON EXIT:
; r0 = cptr => Updated to the end of the coefficients for the stage
; (the coefficients for the next stage will usually follow)
; r1 = dptr => preserved and pointing to the output data
; r2 = dinc => number of bytes per "block" or "Group" in this stage:
; dinc = (R1*R2*..*Rj)<<datalog = (input dinc)*R
; r3 = count => number of radix-R blocks or groups processed in this stage
; count = R(j+1)*...*Rk = (input count)/R
; r0,r4-r12,r14 corrupted
cptr RN 0 ; pointer to twiddle coefficients
dptr RN 1 ; pointer to FFT data working buffer
dinc RN 2 ; bytes per block/group at this stage
count RN 3 ; number of blocks/groups at this stage
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;
; LAST STAGE INTERFACE
;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;
; The LAST STAGE macros "LS_RAD<R>" have the following interface.
;
; ON ENTRY:
; REGISTERS:
; r0 = cptr => Pointer to twiddle coefficients for this stage consisting
; of complex numbers of size (1<<coeflog) bytes each in some
; stage dependent format.
; The format currently used in described in full in the
; ReadMe file in the tables subdirectory.
; There is a possible stride between the coefficients
; specified by cinc
; r1 = dptr => points to the working buffer consisting of N complex
; numbers of size (1<<datalog) bytes each
; r2 = dinc => number of bytes per "block" or "Group" in the last stage:
; dinc = (N/R)<<datalog
; r3 = cinc => Bytes between twiddle values in the array pointed to by cptr
;
; ACTION:
; The routine should
; (1) Twiddle the input data
; (2) Perform a (last stage optimised) radix R stage on the data
; (3) Perform the actions in place, result written to the dptr buffer
;
; ON EXIT:
; r0 = cptr => Updated to point to real-to-complex conversion coefficients
; r1 = dptr => preserved and pointing to the output data
; r2 = dinc => number of bytes per "block" or "Group" in this stage:
; dinc = N<<datalog = (input dinc)*R
; r0,r4-r12,r14 corrupted
cptr RN 0 ; pointer to twiddle coefficients
dptr RN 1 ; pointer to FFT data working buffer
dinc RN 2 ; bytes per block/group at this stage
cinc RN 3 ; stride between twiddle coefficients in bytes
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;
; COMPLEX TO REAL CONVERSION INTERFACE
;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;
; The COMPLEX TO REAL macros "LS_ZTOR" have the following interface.
;
; Suppose that 'w' is the N'th root of unity being used for the real FFT
; (usually exp(-2*pi*i/N) for forward transforms and exp(+2*pi*i/N) for
; the inverse transform).
;
; ON ENTRY:
; REGISTERS:
; r0 = cptr => Pointer to twiddle coefficients for this stage
; This consists of (1,w,w^2,w^3,...,w^(N/4-1)).
; There is a stride between each coeficient specified by cinc
; r1 = dptr => points to the working buffer consisting of N/2 complex
; numbers of size (1<<datalog) bytes each
; r2 = dinc => (N/2)<<datalog, the size of the complex buffer in bytes
; r3 = cinc => Bytes between twiddle value in array pointed to by cptr
; r4 = dout => Output buffer (usually the same as dptr)
;
; ACTION:
; The routine should take the output of an N/2 point complex FFT and convert
; it to the output of an N point real FFT, assuming that the real input
; inputs were packed up into the real,imag,real,imag,... buffers of the complex
; input. The output is N/2 complex numbers of the form:
; y[0]+i*y[N/2], y[1], y[2], ..., y[N/2-1]
; where y[0],...,y[N-1] is the output from a complex transform of the N
; real inputs.
;
; ON EXIT:
; r0-r12,r14 corrupted
cptr RN 0 ; pointer to twiddle coefficients
dptr RN 1 ; pointer to FFT data working buffer
dinc RN 2 ; (N/2)<<datalog, the size of the data in bytes
cinc RN 3 ; bytes between twiddle values in the coefficient buffer
dout RN 4 ; address to write the output (normally the same as dptr)
;;;;;;;;;;;;;;;;;;;;;; END OF INTERFACES ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; first stage/outer loop level
;inptr RN 0
;dptr RN 1
;N RN 2 ; size of FFT
;dinc RN 2 ; bytes between block size when bit reversed (scaling of N)
bitrev RN 3
; inner loop level
;cptr RN 0 ; coefficient pointer for this level
;dptr RN 1 ; data pointer - points to end (load in reverse order)
;dinc RN 2 ; bytes between data elements at this level of FFT
;count RN 3 ; (elements per block<<16) | (blocks per stage)
; data registers
x0r RN 4
x0i RN 5
x1r RN 6
x1i RN 7
x2r RN 8
x2i RN 9
x3r RN 10
x3i RN 11
t0 RN 12 ; these MUST be in correct order (t0<t1) for STM's
t1 RN 14
MACRO
SETREG $prefix,$v0,$v1
GBLS $prefix.r
GBLS $prefix.i
$prefix.r SETS "$v0"
$prefix.i SETS "$v1"
MEND
MACRO
SETREGS $prefix,$v0,$v1,$v2,$v3,$v4,$v5,$v6,$v7
SETREG $prefix.0,$v0,$v1
SETREG $prefix.1,$v2,$v3
SETREG $prefix.2,$v4,$v5
SETREG $prefix.3,$v6,$v7
MEND
MACRO
SET2REGS $prefix,$v0,$v1,$v2,$v3
SETREG $prefix.0,$v0,$v1
SETREG $prefix.1,$v2,$v3
MEND
; Macro to load twiddle coeficients
; Customise according to coeficient format
; Load next 3 complex coeficients into thr given registers
; Update the coeficient pointer
MACRO
LOADCOEFS $cp, $c0r, $c0i, $c1r, $c1i, $c2r, $c2i
IF "$coefformat"="W"
; one word per scalar
LDMIA $cp!, {$c0r, $c0i, $c1r, $c1i, $c2r, $c2i}
MEXIT
ENDIF
IF "$coefformat"="H"
; one half word per scalar
LDRSH $c0r, [$cp], #2
LDRSH $c0i, [$cp], #2
LDRSH $c1r, [$cp], #2
LDRSH $c1i, [$cp], #2
LDRSH $c2r, [$cp], #2
LDRSH $c2i, [$cp], #2
MEXIT
ENDIF
ERROR "Unsupported coeficient format: $coefformat"
MEND
; Macro to load one twiddle coeficient
; $cp = address to load complex data
; $ci = post index to make to address after load
MACRO
LOADCOEF $cp, $ci, $re, $im
IF "$coefformat"="W"
LDR $im, [$cp, #4]
LDR $re, [$cp], $ci
MEXIT
ENDIF
IF "$coefformat"="H"
LDRSH $im, [$cp, #2]
LDRSH $re, [$cp], $ci
MEXIT
ENDIF
ERROR "Unsupported coeficient format: $coefformat"
MEND
; Macro to load one component of one twiddle coeficient
; $cp = address to load complex data
; $ci = post index to make to address after load
MACRO
LOADCOEFR $cp, $re
IF "$coefformat"="W"
LDR $re, [$cp]
MEXIT
ENDIF
IF "$coefformat"="H"
LDRSH $re, [$cp]
MEXIT
ENDIF
ERROR "Unsupported coeficient format: $coefformat"
MEND
; Macro to load data elements in the given format
; $dp = address to load complex data
; $di = post index to make to address after load
MACRO
LOADDATAF $dp, $di, $re, $im, $format
IF "$format"="W"
LDR $im, [$dp, #4]
LDR $re, [$dp], $di
MEXIT
ENDIF
IF "$format"="H"
LDRSH $im, [$dp, #2]
LDRSH $re, [$dp], $di
MEXIT
ENDIF
ERROR "Unsupported load format: $format"
MEND
MACRO
LOADDATAZ $dp, $re, $im
IF "$datainformat"="W"
LDMIA $dp, {$re,$im}
MEXIT
ENDIF
IF "$datainformat"="H"
LDRSH $im, [$dp, #2]
LDRSH $re, [$dp]
MEXIT
ENDIF
ERROR "Unsupported load format: $format"
MEND
; Load a complex data element from the working array
MACRO
LOADDATA $dp, $di, $re, $im
LOADDATAF $dp, $di, $re, $im, $dataformat
MEND
; Load a complex data element from the input array
MACRO
LOADDATAI $dp, $di, $re, $im
LOADDATAF $dp, $di, $re, $im, $datainformat
MEND
MACRO
LOADDATA4 $dp, $re0,$im0, $re1,$im1, $re2,$im2, $re3,$im3
IF "$datainformat"="W"
LDMIA $dp!, {$re0,$im0, $re1,$im1, $re2,$im2, $re3,$im3}
ELSE
LOADDATAI $dp, #1<<$datalog, $re0,$im0
LOADDATAI $dp, #1<<$datalog, $re1,$im1
LOADDATAI $dp, #1<<$datalog, $re2,$im2
LOADDATAI $dp, #1<<$datalog, $re3,$im3
ENDIF
MEND
; Shift data after load
MACRO
SHIFTDATA $dr, $di
IF "$postldshift"<>""
IF "$di"<>""
MOV $di, $di $postldshift
ENDIF
MOV $dr, $dr $postldshift
ENDIF
MEND
; Store a complex data item in the output data buffer
MACRO
STORE $dp, $di, $re, $im
IF "$dataformat"="W"
STR $im, [$dp, #4]
STR $re, [$dp], $di
MEXIT
ENDIF
IF "$dataformat"="H"
STRH $im, [$dp, #2]
STRH $re, [$dp], $di
MEXIT
ENDIF
ERROR "Unsupported save format: $dataformat"
MEND
; Store a complex data item in the output data buffer
MACRO
STOREP $dp, $re, $im
IF "$dataformat"="W"
STMIA $dp!, {$re,$im}
MEXIT
ENDIF
IF "$dataformat"="H"
STRH $im, [$dp, #2]
STRH $re, [$dp], #4
MEXIT
ENDIF
ERROR "Unsupported save format: $dataformat"
MEND
MACRO
STORE3P $dp, $re0, $im0, $re1, $im1, $re2, $im2
IF "$dataformat"="W"
STMIA $dp!, {$re0,$im0, $re1,$im1, $re2,$im2}
MEXIT
ENDIF
IF "$dataformat"="H"
STRH $im0, [$dp, #2]
STRH $re0, [$dp], #4
STRH $im1, [$dp, #2]
STRH $re1, [$dp], #4
STRH $im2, [$dp, #2]
STRH $re2, [$dp], #4
MEXIT
ENDIF
ERROR "Unsupported save format: $dataformat"
MEND
; do different command depending on forward/inverse FFT
MACRO
DOi $for, $bac, $d, $s1, $s2, $shift
IF "$shift"=""
$for $d, $s1, $s2
ELSE
$for $d, $s1, $s2, $shift
ENDIF
MEND
; d = s1 + s2 if w=exp(+2*pi*i/N) j=+i - inverse transform
; d = s1 - s2 if w=exp(-2*pi*i/N) j=-i - forward transform
MACRO
ADDi $d, $s1, $s2, $shift
DOi SUB, ADD, $d, $s1, $s2, $shift
MEND
; d = s1 - s2 if w=exp(+2*pi*i/N) j=+i - inverse transform
; d = s1 + s2 if w=exp(-2*pi*i/N) j=-i - forward transform
MACRO
SUBi $d, $s1, $s2, $shift
DOi ADD, SUB, $d, $s1, $s2, $shift
MEND
; check that $val is in the range -$max to +$max-1
; set carry flag (sicky) if not (2 cycles)
; has the advantage of not needing a separate register
; to store the overflow state
MACRO
CHECKOV $val, $tmp, $max
EOR $tmp, $val, $val, ASR#31
CMPCC $tmp, $max
MEND
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;
; Macro's to perform the twiddle stage (complex multiply by coefficient)
;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; The coefficients are stored in different formats according to the
; precision and processor architecture. The coefficients required
; will be of the form:
;
; c(k) = cos( + k*2*pi*i/N ), s(k) = sin( + k*2*pi*i/N )
;
; c(k) + i*s(k) = exp(+2*pi*k*i/N)
;
; for some k's. The storage formats are:
;
; Format Data
; Q14S (c-s, s) in Q14 format, 16-bits per real
; Q14R (c, s) in Q14 format, 16-bits per real
; Q30S (c-s, s) in Q30 format, 32-bits per real
;
; The operation to be performed is one of:
;
; a+i*b = (x+i*y)*(c-i*s) => forward transform
; OR a+i*b = (x+i*y)*(c+i*s) => inverse transform
;
; For the R format the operation is quite simple - requiring 4 muls
; and 2 adds:
;
; Forward: a = x*c+y*s, b = y*c-x*s
; Inverse: a = x*c-y*s, b = y*c+x*s
;
; For the S format the operations is more complex but only requires
; three multiplies, and is simpler to schedule:
;
; Forward: a = (y-x)*s + x*(c+s) = x*(c-s) + (x+y)*s
; b = (y-x)*s + y*(c-s) = y*(c+s) - (x+y)*s
;
; Inverse: a = (x-y)*s + x*(c-s)
; b = (x-y)*s + y*(c+s)
;
; S advantage 16bit: 1ADD, 1SUB, 1MUL, 2MLA instead of 1SUB, 3MUL, 1MLA
; S advantage 32bit: 2ADD, 1SUB, 2SMULL, 1SMLAL instead of 1RSB, 2SMULL, 2SMLAL
; So S wins except for a very fast multiplier (eg 9E)
;
; NB The coefficients must always be the second operand on processor that
; take a variable number of cycles per multiply - so the FFT time remains constant
; This twiddle takes unpacked real and imaginary values
; Expects (cr,ci) = (c-s,s) on input
; Sets (cr,ci) = (a,b) on output
MACRO
TWIDDLE $xr, $xi, $cr, $ci, $t0, $t1
IF qshift>=0 :LAND: qshift<32
SUB $t1, $xi, $xr ; y-x
MUL $t0, $t1, $ci ; (y-x)*s
ADD $t1, $cr, $ci, LSL #1 ; t1 = c+s allow mul to finish on SA
MLA $ci, $xi, $cr, $t0 ; b
MLA $cr, $xr, $t1, $t0 ; a
ELSE
ADD $t1, $cr, $ci, LSL #1 ; t1 = c+s
SMULL $cr, $t0, $xi, $cr ; t0 = y*(c-s)
SUB $xi, $xi, $xr ; xr = y-x + allow mul to finish on SA
SMULL $ci, $cr, $xi, $ci ; cr = (y-x)*s
ADD $ci, $cr, $t0 ; b + allow mul to finish on SA
SMLAL $t0, $cr, $xr, $t1 ; a
ENDIF
MEND
; The following twiddle variant is similar to the above
; except that it is for an "E" processor varient. A standard
; 4 multiply twiddle is used as it requires the same number
; of cycles and needs less intermediate precision
;
; $co = coeficent real and imaginary (c,s) (packed)
; $xx = input data real and imaginary part (packed)
;
; $xr = destination register for real part of product
; $xi = destination register for imaginary part of product
;
; All registers should be distinct
;
MACRO
TWIDDLE_E $xr, $xi, $c0, $t0, $xx, $xxi
SMULBT $t0, $xx, $c0
SMULBB $xr, $xx, $c0
IF "$xxi"=""
SMULTB $xi, $xx, $c0
SMLATT $xr, $xx, $c0, $xr
ELSE
SMULBB $xi, $xxi, $c0
SMLABT $xr, $xxi, $c0, $xr
ENDIF
SUB $xi, $xi, $t0
MEND
; Scale data value in by the coefficient, writing result to out
; The coeficient must be the second multiplicand
; The post mul shift need not be done so in most cases this
; is just a multiply (unless you need higher precision)
; coef must be preserved
MACRO
SCALE $out, $in, $coef, $tmp
IF qshift>=0 :LAND: qshift<32
MUL $out, $in, $coef
ELSE
SMULL $tmp, $out, $in, $coef
ENDIF
MEND
MACRO
DECODEFORMAT $out, $format
GBLS $out.log
GBLS $out.format
$out.format SETS "$format"
IF "$format"="B"
$out.log SETS "1"
MEXIT
ENDIF
IF "$format"="H"
$out.log SETS "2"
MEXIT
ENDIF
IF "$format"="W"
$out.log SETS "3"
MEXIT
ENDIF
ERROR "Unrecognised format for $out: $format"
MEND
; generate a string in $var of the correct right shift
; amount - negative values = left shift
MACRO
SETSHIFT $var, $value
LCLA svalue
svalue SETA $value
$var SETS ""
IF svalue>0 :LAND: svalue<32
$var SETS ",ASR #0x$svalue"
ENDIF
svalue SETA -svalue
IF svalue>0 :LAND: svalue<32
$var SETS ",LSL #0x$svalue"
ENDIF
MEND
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; ;
; CODE to decipher the FFT options ;
; ;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; The $flags variable specifies the FFT options
; The global string $name is set to a textual version
; The global string $table is set the table name
MACRO
FFT_OPTIONS_STRING $flags, $name
GBLS $name
GBLS qname ; name of the precision (eg Q14, Q30)
GBLS direction ; name of the direction (eg I, F)
GBLS radix ; name of the radix (2, 4E, 4B, 4O etc)
GBLS intype ; name of input data type (if real)
GBLS prescale ; flag to indicate prescale
GBLS outpos ; position for the output data
GBLS datainformat ; bytes per input data item
GBLS dataformat ; bytes per working item
GBLS coefformat ; bytes per coefficient working item
GBLS coeforder ; R=(c,s) S=(c-s,s) storage format
GBLA datainlog ; shift to bytes per input complex
GBLA datalog ; shift to bytes per working complex
GBLA coeflog ; shift to bytes per coefficient complex
GBLA qshift ; right shift after multiply
GBLA norm
GBLA architecture ; 4=Arch4(7TDMI,SA), 5=Arch5TE(ARM9E)
GBLS cdshift
GBLS postmulshift
GBLS postldshift
GBLS postmulshift1
GBLS postldshift1
GBLL reversed ; flag to indicate input is already bit reversed
GBLS tablename
; find what sort of processor we are building the FFT for
architecture SETA 4 ; Architecture 4 (7TDMI, StrongARM etc)
;qname SETS {CPU}
; P $qname
IF ((({ARCHITECTURE}:CC:"aaaa"):LEFT:3="5TE") :LOR: (({ARCHITECTURE}:CC:"aa"):LEFT:1="6"))
architecture SETA 5 ; Architecture 5 (ARM9E, E extensions)
; P arch E
ENDIF
reversed SETL {FALSE}
; decode input order
IF ($flags:AND:FFT_INPUTORDER)=FFT_REVERSED
reversed SETL {TRUE}
ENDIF
; decode radix type to $radix
IF ($flags:AND:FFT_RADIX)=FFT_RADIX4
radix SETS "4E"
ENDIF
IF ($flags:AND:FFT_RADIX)=FFT_RADIX4_8F
radix SETS "4O"
ENDIF
IF ($flags:AND:FFT_RADIX)=FFT_RADIX4_2L
radix SETS "4B"
ENDIF
; decode direction to $direction
direction SETS "F"
; decode data size to $qname, and *log's
IF ($flags:AND:FFT_DATA_SIZES)=FFT_32bit
qname SETS "Q30"
datainlog SETA 3 ; 8 bytes per complex
datalog SETA 3
coeflog SETA 3
datainformat SETS "W"
dataformat SETS "W"
coefformat SETS "W"
qshift SETA -2 ; shift left top word of 32 bit result
ENDIF
IF ($flags:AND:FFT_DATA_SIZES)=FFT_16bit
qname SETS "Q14"
datainlog SETA 2
datalog SETA 2
coeflog SETA 2
datainformat SETS "H"
dataformat SETS "H"
coefformat SETS "H"
qshift SETA 14
ENDIF
; find the coefficient ordering
coeforder SETS "S"
IF (architecture>=5):LAND:(qshift<16)
coeforder SETS "R"
ENDIF
; decode real vs complex input data type
intype SETS ""
IF ($flags:AND:FFT_INPUTTYPE)=FFT_REAL
intype SETS "R"
ENDIF
; decode on outpos
outpos SETS ""
IF ($flags:AND:FFT_OUTPUTPOS)=FFT_OUT_INBUF
outpos SETS "I"
ENDIF
; decode on prescale
prescale SETS ""
IF ($flags:AND:FFT_INPUTSCALE)=FFT_PRESCALE
prescale SETS "P"
ENDIF
; decode on output scale
norm SETA 1
IF ($flags:AND:FFT_OUTPUTSCALE)=FFT_NONORM
norm SETA 0
ENDIF
; calculate shift to convert data offsets to coefficient offsets
SETSHIFT cdshift, ($datalog)-($coeflog)
$name SETS "$radix$direction$qname$intype$outpos$prescale"
MEND
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; ;
; FFT GENERATOR ;
; ;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; FFT options bitfield
FFT_DIRECTION EQU 0x00000001 ; direction select bit
FFT_FORWARD EQU 0x00000000 ; forward exp(-ijkw) coefficient FFT
FFT_INVERSE EQU 0x00000001 ; inverse exp(+ijkw) coefficient FFT
FFT_INPUTORDER EQU 0x00000002 ; input order select field
FFT_BITREV EQU 0x00000000 ; input data is in normal order (bit reverse)
FFT_REVERSED EQU 0x00000002 ; assume input data is already bit revesed
FFT_INPUTSCALE EQU 0x00000004 ; select scale on input data
FFT_NOPRESCALE EQU 0x00000000 ; do not scale input data
FFT_PRESCALE EQU 0x00000004 ; scale input data up by a register amount
FFT_INPUTTYPE EQU 0x00000010 ; selector for real/complex input data
FFT_COMPLEX EQU 0x00000000 ; do complex FFT of N points
FFT_REAL EQU 0x00000010 ; do a 2*N point real FFT
FFT_OUTPUTPOS EQU 0x00000020 ; where is the output placed?
FFT_OUT_OUTBUF EQU 0x00000000 ; default - in the output buffer
FFT_OUT_INBUF EQU 0x00000020 ; copy it back to the input buffer
FFT_RADIX EQU 0x00000F00 ; radix select
FFT_RADIX4 EQU 0x00000000 ; radix 4 (log_2 N must be even)
FFT_RADIX4_8F EQU 0x00000100 ; radix 4 with radix 8 first stage
FFT_RADIX4_2L EQU 0x00000200 ; radix 4 with optional radix 2 last stage
FFT_OUTPUTSCALE EQU 0x00001000 ; select output scale value
FFT_NORMALISE EQU 0x00000000 ; default - divide by N during algorithm
FFT_NONORM EQU 0x00001000 ; calculate the raw sum (no scale)
FFT_DATA_SIZES EQU 0x000F0000
FFT_16bit EQU 0x00000000 ; 16-bit data and Q14 coefs
FFT_32bit EQU 0x00010000 ; 32-bit data and Q30 coefs
END

View File

@ -0,0 +1,774 @@
;
; $Copyright:
; ----------------------------------------------------------------
; This confidential and proprietary software may be used only as
; authorised by a licensing agreement from ARM Limited
; (C) COPYRIGHT 2000,2002 ARM Limited
; ALL RIGHTS RESERVED
; The entire notice above must be reproduced on all authorised
; copies and copies may only be made to the extent permitted
; by a licensing agreement from ARM Limited.
; ----------------------------------------------------------------
; File: fft_mac.h,v
; Revision: 1.14
; ----------------------------------------------------------------
; $
;
; Optimised ARM assembler multi-radix FFT
; Please read the readme.txt before this file
;
; Shared macros and interface definition file.
; NB: All the algorithms in this code are Decimation in Time. ARM
; is much better at Decimation in Time (as opposed to Decimation
; in Frequency) due to the position of the barrel shifter. Decimation
; in time has the twiddeling at the start of the butterfly, where as
; decimation in frequency has it at the end of the butterfly. The
; post multiply shifts can be hidden for Decimation in Time.
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;
; FIRST STAGE INTERFACE
;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;
; The FIRST STAGE macros "FS_RAD<R>" have the following interface:
;
; ON ENTRY:
; REGISTERS:
; r0 = inptr => points to the input buffer consisting of N complex
; numbers of size (1<<datainlog) bytes each
; r1 = dptr => points to the output buffer consisting of N complex
; numbers of size (1<<datalog) bytes each
; r2 = N => is the number of points in the transform
; r3 = pscale => shift to prescale input by (if applicable)
; ASSEMBLER VARIABLES:
; reversed => logical variable, true if input data is already bit reversed
; The data needs to be bit reversed otherwise
;
; ACTION:
; The routine should
; (1) Bit reverse the data as required for the whole FFT (unless
; the reversed flag is set)
; (2) Prescale the input data by
; (3) Perform a radix R first stage on the data
; (4) Place the processed data in the output array pointed to be dptr
;
; ON EXIT:
; r1 = dptr => preserved and pointing to the output data
; r2 = dinc => number of bytes per "block" or "Group" in this stage
; this is: R<<datalog
; r3 = count => number of radix-R blocks or groups processed in this stage
; this is: N/R
; r0,r4-r12,r14 corrupted
inptr RN 0 ; input buffer
dptr RN 1 ; output/scratch buffer
N RN 2 ; size of the FFT
dptr RN 1 ; data pointer - points to end (load in reverse order)
dinc RN 2 ; bytes between data elements at this level of FFT
count RN 3 ; (elements per block<<16) | (blocks per stage)
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;
; GENERAL STAGE INTERFACE
;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;
; The GENERAL STAGE macros "GS_RAD<R>" have the following interface.
;
; To describe the arguments, suppose this routine is called as stage j
; in a k-stage FFT with N=R1*R2*...*Rk. This stage is radix R=Rj.
;
; ON ENTRY:
; REGISTERS:
; r0 = cptr => Pointer to twiddle coefficients for this stage consisting
; of complex numbers of size (1<<coeflog) bytes each in some
; stage dependent format.
; The format currently used in described in full in the
; ReadMe file in the tables subdirectory.
; r1 = dptr => points to the working buffer consisting of N complex
; numbers of size (1<<datalog) bytes each
; r2 = dinc => number of bytes per "block" or "Group" in the last stage:
; dinc = (R1*R2*...*R(j-1))<<datalog
; r3 = count => number of blocks or Groups in the last stage:
; count = Rj*R(j+1)*...*Rk
; NB dinc*count = N<<datalog
;
; ACTION:
; The routine should
; (1) Twiddle the input data
; (2) Perform a radix R stage on the data
; (3) Perform the actions in place, result written to the dptr buffer
;
; ON EXIT:
; r0 = cptr => Updated to the end of the coefficients for the stage
; (the coefficients for the next stage will usually follow)
; r1 = dptr => preserved and pointing to the output data
; r2 = dinc => number of bytes per "block" or "Group" in this stage:
; dinc = (R1*R2*..*Rj)<<datalog = (input dinc)*R
; r3 = count => number of radix-R blocks or groups processed in this stage
; count = R(j+1)*...*Rk = (input count)/R
; r0,r4-r12,r14 corrupted
cptr RN 0 ; pointer to twiddle coefficients
dptr RN 1 ; pointer to FFT data working buffer
dinc RN 2 ; bytes per block/group at this stage
count RN 3 ; number of blocks/groups at this stage
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;
; LAST STAGE INTERFACE
;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;
; The LAST STAGE macros "LS_RAD<R>" have the following interface.
;
; ON ENTRY:
; REGISTERS:
; r0 = cptr => Pointer to twiddle coefficients for this stage consisting
; of complex numbers of size (1<<coeflog) bytes each in some
; stage dependent format.
; The format currently used in described in full in the
; ReadMe file in the tables subdirectory.
; There is a possible stride between the coefficients
; specified by cinc
; r1 = dptr => points to the working buffer consisting of N complex
; numbers of size (1<<datalog) bytes each
; r2 = dinc => number of bytes per "block" or "Group" in the last stage:
; dinc = (N/R)<<datalog
; r3 = cinc => Bytes between twiddle values in the array pointed to by cptr
;
; ACTION:
; The routine should
; (1) Twiddle the input data
; (2) Perform a (last stage optimised) radix R stage on the data
; (3) Perform the actions in place, result written to the dptr buffer
;
; ON EXIT:
; r0 = cptr => Updated to point to real-to-complex conversion coefficients
; r1 = dptr => preserved and pointing to the output data
; r2 = dinc => number of bytes per "block" or "Group" in this stage:
; dinc = N<<datalog = (input dinc)*R
; r0,r4-r12,r14 corrupted
cptr RN 0 ; pointer to twiddle coefficients
dptr RN 1 ; pointer to FFT data working buffer
dinc RN 2 ; bytes per block/group at this stage
cinc RN 3 ; stride between twiddle coefficients in bytes
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;
; COMPLEX TO REAL CONVERSION INTERFACE
;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;
; The COMPLEX TO REAL macros "LS_ZTOR" have the following interface.
;
; Suppose that 'w' is the N'th root of unity being used for the real FFT
; (usually exp(-2*pi*i/N) for forward transforms and exp(+2*pi*i/N) for
; the inverse transform).
;
; ON ENTRY:
; REGISTERS:
; r0 = cptr => Pointer to twiddle coefficients for this stage
; This consists of (1,w,w^2,w^3,...,w^(N/4-1)).
; There is a stride between each coeficient specified by cinc
; r1 = dptr => points to the working buffer consisting of N/2 complex
; numbers of size (1<<datalog) bytes each
; r2 = dinc => (N/2)<<datalog, the size of the complex buffer in bytes
; r3 = cinc => Bytes between twiddle value in array pointed to by cptr
; r4 = dout => Output buffer (usually the same as dptr)
;
; ACTION:
; The routine should take the output of an N/2 point complex FFT and convert
; it to the output of an N point real FFT, assuming that the real input
; inputs were packed up into the real,imag,real,imag,... buffers of the complex
; input. The output is N/2 complex numbers of the form:
; y[0]+i*y[N/2], y[1], y[2], ..., y[N/2-1]
; where y[0],...,y[N-1] is the output from a complex transform of the N
; real inputs.
;
; ON EXIT:
; r0-r12,r14 corrupted
cptr RN 0 ; pointer to twiddle coefficients
dptr RN 1 ; pointer to FFT data working buffer
dinc RN 2 ; (N/2)<<datalog, the size of the data in bytes
cinc RN 3 ; bytes between twiddle values in the coefficient buffer
dout RN 4 ; address to write the output (normally the same as dptr)
;;;;;;;;;;;;;;;;;;;;;; END OF INTERFACES ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; first stage/outer loop level
;inptr RN 0
;dptr RN 1
;N RN 2 ; size of FFT
;dinc RN 2 ; bytes between block size when bit reversed (scaling of N)
bitrev RN 3
; inner loop level
;cptr RN 0 ; coefficient pointer for this level
;dptr RN 1 ; data pointer - points to end (load in reverse order)
;dinc RN 2 ; bytes between data elements at this level of FFT
;count RN 3 ; (elements per block<<16) | (blocks per stage)
; data registers
x0r RN 4
x0i RN 5
x1r RN 6
x1i RN 7
x2r RN 8
x2i RN 9
x3r RN 10
x3i RN 11
t0 RN 12 ; these MUST be in correct order (t0<t1) for STM's
t1 RN 14
MACRO
SETREG $prefix,$v0,$v1
GBLS $prefix.r
GBLS $prefix.i
$prefix.r SETS "$v0"
$prefix.i SETS "$v1"
MEND
MACRO
SETREGS $prefix,$v0,$v1,$v2,$v3,$v4,$v5,$v6,$v7
SETREG $prefix.0,$v0,$v1
SETREG $prefix.1,$v2,$v3
SETREG $prefix.2,$v4,$v5
SETREG $prefix.3,$v6,$v7
MEND
MACRO
SET2REGS $prefix,$v0,$v1,$v2,$v3
SETREG $prefix.0,$v0,$v1
SETREG $prefix.1,$v2,$v3
MEND
; Macro to load twiddle coeficients
; Customise according to coeficient format
; Load next 3 complex coeficients into thr given registers
; Update the coeficient pointer
MACRO
LOADCOEFS $cp, $c0r, $c0i, $c1r, $c1i, $c2r, $c2i
IF "$coefformat"="W"
; one word per scalar
LDMIA $cp!, {$c0r, $c0i, $c1r, $c1i, $c2r, $c2i}
MEXIT
ENDIF
IF "$coefformat"="H"
; one half word per scalar
LDRSH $c0r, [$cp], #2
LDRSH $c0i, [$cp], #2
LDRSH $c1r, [$cp], #2
LDRSH $c1i, [$cp], #2
LDRSH $c2r, [$cp], #2
LDRSH $c2i, [$cp], #2
MEXIT
ENDIF
ERROR "Unsupported coeficient format: $coefformat"
MEND
; Macro to load one twiddle coeficient
; $cp = address to load complex data
; $ci = post index to make to address after load
MACRO
LOADCOEF $cp, $ci, $re, $im
IF "$coefformat"="W"
LDR $im, [$cp, #4]
LDR $re, [$cp], $ci
MEXIT
ENDIF
IF "$coefformat"="H"
LDRSH $im, [$cp, #2]
LDRSH $re, [$cp], $ci
MEXIT
ENDIF
ERROR "Unsupported coeficient format: $coefformat"
MEND
; Macro to load one component of one twiddle coeficient
; $cp = address to load complex data
; $ci = post index to make to address after load
MACRO
LOADCOEFR $cp, $re
IF "$coefformat"="W"
LDR $re, [$cp]
MEXIT
ENDIF
IF "$coefformat"="H"
LDRSH $re, [$cp]
MEXIT
ENDIF
ERROR "Unsupported coeficient format: $coefformat"
MEND
; Macro to load data elements in the given format
; $dp = address to load complex data
; $di = post index to make to address after load
MACRO
LOADDATAF $dp, $di, $re, $im, $format
IF "$format"="W"
LDR $im, [$dp, #4]
LDR $re, [$dp], $di
MEXIT
ENDIF
IF "$format"="H"
LDRSH $im, [$dp, #2]
LDRSH $re, [$dp], $di
MEXIT
ENDIF
ERROR "Unsupported load format: $format"
MEND
MACRO
LOADDATAZ $dp, $re, $im
IF "$datainformat"="W"
LDMIA $dp, {$re,$im}
MEXIT
ENDIF
IF "$datainformat"="H"
LDRSH $im, [$dp, #2]
LDRSH $re, [$dp]
MEXIT
ENDIF
ERROR "Unsupported load format: $format"
MEND
; Load a complex data element from the working array
MACRO
LOADDATA $dp, $di, $re, $im
LOADDATAF $dp, $di, $re, $im, $dataformat
MEND
; Load a complex data element from the input array
MACRO
LOADDATAI $dp, $di, $re, $im
LOADDATAF $dp, $di, $re, $im, $datainformat
MEND
MACRO
LOADDATA4 $dp, $re0,$im0, $re1,$im1, $re2,$im2, $re3,$im3
IF "$datainformat"="W"
LDMIA $dp!, {$re0,$im0, $re1,$im1, $re2,$im2, $re3,$im3}
ELSE
LOADDATAI $dp, #1<<$datalog, $re0,$im0
LOADDATAI $dp, #1<<$datalog, $re1,$im1
LOADDATAI $dp, #1<<$datalog, $re2,$im2
LOADDATAI $dp, #1<<$datalog, $re3,$im3
ENDIF
MEND
; Shift data after load
MACRO
SHIFTDATA $dr, $di
IF "$postldshift"<>""
IF "$di"<>""
MOV $di, $di $postldshift
ENDIF
MOV $dr, $dr $postldshift
ENDIF
MEND
; Store a complex data item in the output data buffer
MACRO
STORE $dp, $di, $re, $im
IF "$dataformat"="W"
STR $im, [$dp, #4]
STR $re, [$dp], $di
MEXIT
ENDIF
IF "$dataformat"="H"
STRH $im, [$dp, #2]
STRH $re, [$dp], $di
MEXIT
ENDIF
ERROR "Unsupported save format: $dataformat"
MEND
; Store a complex data item in the output data buffer
MACRO
STOREP $dp, $re, $im
IF "$dataformat"="W"
STMIA $dp!, {$re,$im}
MEXIT
ENDIF
IF "$dataformat"="H"
STRH $im, [$dp, #2]
STRH $re, [$dp], #4
MEXIT
ENDIF
ERROR "Unsupported save format: $dataformat"
MEND
MACRO
STORE3P $dp, $re0, $im0, $re1, $im1, $re2, $im2
IF "$dataformat"="W"
STMIA $dp!, {$re0,$im0, $re1,$im1, $re2,$im2}
MEXIT
ENDIF
IF "$dataformat"="H"
STRH $im0, [$dp, #2]
STRH $re0, [$dp], #4
STRH $im1, [$dp, #2]
STRH $re1, [$dp], #4
STRH $im2, [$dp, #2]
STRH $re2, [$dp], #4
MEXIT
ENDIF
ERROR "Unsupported save format: $dataformat"
MEND
; do different command depending on forward/inverse FFT
MACRO
DOi $for, $bac, $d, $s1, $s2, $shift
IF "$shift"=""
$bac $d, $s1, $s2
ELSE
$bac $d, $s1, $s2, $shift
ENDIF
MEND
; d = s1 + s2 if w=exp(+2*pi*i/N) j=+i - inverse transform
; d = s1 - s2 if w=exp(-2*pi*i/N) j=-i - forward transform
MACRO
ADDi $d, $s1, $s2, $shift
DOi SUB, ADD, $d, $s1, $s2, $shift
MEND
; d = s1 - s2 if w=exp(+2*pi*i/N) j=+i - inverse transform
; d = s1 + s2 if w=exp(-2*pi*i/N) j=-i - forward transform
MACRO
SUBi $d, $s1, $s2, $shift
DOi ADD, SUB, $d, $s1, $s2, $shift
MEND
; check that $val is in the range -$max to +$max-1
; set carry flag (sicky) if not (2 cycles)
; has the advantage of not needing a separate register
; to store the overflow state
MACRO
CHECKOV $val, $tmp, $max
EOR $tmp, $val, $val, ASR#31
CMPCC $tmp, $max
MEND
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;
; Macro's to perform the twiddle stage (complex multiply by coefficient)
;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; The coefficients are stored in different formats according to the
; precision and processor architecture. The coefficients required
; will be of the form:
;
; c(k) = cos( + k*2*pi*i/N ), s(k) = sin( + k*2*pi*i/N )
;
; c(k) + i*s(k) = exp(+2*pi*k*i/N)
;
; for some k's. The storage formats are:
;
; Format Data
; Q14S (c-s, s) in Q14 format, 16-bits per real
; Q14R (c, s) in Q14 format, 16-bits per real
; Q30S (c-s, s) in Q30 format, 32-bits per real
;
; The operation to be performed is one of:
;
; a+i*b = (x+i*y)*(c-i*s) => forward transform
; OR a+i*b = (x+i*y)*(c+i*s) => inverse transform
;
; For the R format the operation is quite simple - requiring 4 muls
; and 2 adds:
;
; Forward: a = x*c+y*s, b = y*c-x*s
; Inverse: a = x*c-y*s, b = y*c+x*s
;
; For the S format the operations is more complex but only requires
; three multiplies, and is simpler to schedule:
;
; Forward: a = (y-x)*s + x*(c+s) = x*(c-s) + (x+y)*s
; b = (y-x)*s + y*(c-s) = y*(c+s) - (x+y)*s
;
; Inverse: a = (x-y)*s + x*(c-s)
; b = (x-y)*s + y*(c+s)
;
; S advantage 16bit: 1ADD, 1SUB, 1MUL, 2MLA instead of 1SUB, 3MUL, 1MLA
; S advantage 32bit: 2ADD, 1SUB, 2SMULL, 1SMLAL instead of 1RSB, 2SMULL, 2SMLAL
; So S wins except for a very fast multiplier (eg 9E)
;
; NB The coefficients must always be the second operand on processor that
; take a variable number of cycles per multiply - so the FFT time remains constant
; This twiddle takes unpacked real and imaginary values
; Expects (cr,ci) = (c-s,s) on input
; Sets (cr,ci) = (a,b) on output
MACRO
TWIDDLE $xr, $xi, $cr, $ci, $t0, $t1
IF qshift>=0 :LAND: qshift<32
SUB $t1, $xr, $xi ; x-y
MUL $t0, $t1, $ci ; (x-y)*s
ADD $ci, $cr, $ci, LSL #1 ; ci = c+s allow mul to finish on SA
MLA $cr, $xr, $cr, $t0 ; a
MLA $ci, $xi, $ci, $t0 ; b
ELSE
ADD $t1, $cr, $ci, LSL #1 ; c+s
SMULL $t0, $cr, $xr, $cr ; x*(c-s)
SUB $xr, $xr, $xi ; x-y + allow mul to finish on SA
SMULL $t0, $ci, $xr, $ci ; (x-y)*s
ADD $cr, $cr, $ci ; a + allow mul to finish on SA
SMLAL $t0, $ci, $xi, $t1 ; b
ENDIF
MEND
; The following twiddle variant is similar to the above
; except that it is for an "E" processor varient. A standard
; 4 multiply twiddle is used as it requires the same number
; of cycles and needs less intermediate precision
;
; $co = coeficent real and imaginary (c,s) (packed)
; $xx = input data real and imaginary part (packed)
;
; $xr = destination register for real part of product
; $xi = destination register for imaginary part of product
;
; All registers should be distinct
;
MACRO
TWIDDLE_E $xr, $xi, $c0, $t0, $xx, $xxi
SMULBB $t0, $xx, $c0
SMULBT $xi, $xx, $c0
IF "$xxi"=""
SMULTT $xr, $xx, $c0
SMLATB $xi, $xx, $c0, $xi
ELSE
SMULBT $xr, $xxi, $c0
SMLABB $xi, $xxi, $c0, $xi
ENDIF
SUB $xr, $t0, $xr
MEND
; Scale data value in by the coefficient, writing result to out
; The coeficient must be the second multiplicand
; The post mul shift need not be done so in most cases this
; is just a multiply (unless you need higher precision)
; coef must be preserved
MACRO
SCALE $out, $in, $coef, $tmp
IF qshift>=0 :LAND: qshift<32
MUL $out, $in, $coef
ELSE
SMULL $tmp, $out, $in, $coef
ENDIF
MEND
MACRO
DECODEFORMAT $out, $format
GBLS $out.log
GBLS $out.format
$out.format SETS "$format"
IF "$format"="B"
$out.log SETS "1"
MEXIT
ENDIF
IF "$format"="H"
$out.log SETS "2"
MEXIT
ENDIF
IF "$format"="W"
$out.log SETS "3"
MEXIT
ENDIF
ERROR "Unrecognised format for $out: $format"
MEND
; generate a string in $var of the correct right shift
; amount - negative values = left shift
MACRO
SETSHIFT $var, $value
LCLA svalue
svalue SETA $value
$var SETS ""
IF svalue>0 :LAND: svalue<32
$var SETS ",ASR #0x$svalue"
ENDIF
svalue SETA -svalue
IF svalue>0 :LAND: svalue<32
$var SETS ",LSL #0x$svalue"
ENDIF
MEND
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; ;
; CODE to decipher the FFT options ;
; ;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; The $flags variable specifies the FFT options
; The global string $name is set to a textual version
; The global string $table is set the table name
MACRO
FFT_OPTIONS_STRING $flags, $name
GBLS $name
GBLS qname ; name of the precision (eg Q14, Q30)
GBLS direction ; name of the direction (eg I, F)
GBLS radix ; name of the radix (2, 4E, 4B, 4O etc)
GBLS intype ; name of input data type (if real)
GBLS prescale ; flag to indicate prescale
GBLS outpos ; position for the output data
GBLS datainformat ; bytes per input data item
GBLS dataformat ; bytes per working item
GBLS coefformat ; bytes per coefficient working item
GBLS coeforder ; R=(c,s) S=(c-s,s) storage format
GBLA datainlog ; shift to bytes per input complex
GBLA datalog ; shift to bytes per working complex
GBLA coeflog ; shift to bytes per coefficient complex
GBLA qshift ; right shift after multiply
GBLA norm
GBLA architecture ; 4=Arch4(7TDMI,SA), 5=Arch5TE(ARM9E)
GBLS cdshift
GBLS postmulshift
GBLS postldshift
GBLS postmulshift1
GBLS postldshift1
GBLL reversed ; flag to indicate input is already bit reversed
GBLS tablename
; find what sort of processor we are building the FFT for
architecture SETA 4 ; Architecture 4 (7TDMI, StrongARM etc)
;qname SETS {CPU}
; P $qname
IF ((({ARCHITECTURE}:CC:"aaaa"):LEFT:3="5TE") :LOR: (({ARCHITECTURE}:CC:"aa"):LEFT:1="6"))
architecture SETA 5 ; Architecture 5 (ARM9E, E extensions)
; P arch E
ENDIF
reversed SETL {FALSE}
; decode input order
IF ($flags:AND:FFT_INPUTORDER)=FFT_REVERSED
reversed SETL {TRUE}
ENDIF
; decode radix type to $radix
IF ($flags:AND:FFT_RADIX)=FFT_RADIX4
radix SETS "4E"
ENDIF
IF ($flags:AND:FFT_RADIX)=FFT_RADIX4_8F
radix SETS "4O"
ENDIF
IF ($flags:AND:FFT_RADIX)=FFT_RADIX4_2L
radix SETS "4B"
ENDIF
; decode direction to $direction
direction SETS "I"
; decode data size to $qname, and *log's
IF ($flags:AND:FFT_DATA_SIZES)=FFT_32bit
qname SETS "Q30"
datainlog SETA 3 ; 8 bytes per complex
datalog SETA 3
coeflog SETA 3
datainformat SETS "W"
dataformat SETS "W"
coefformat SETS "W"
qshift SETA -2 ; shift left top word of 32 bit result
ENDIF
IF ($flags:AND:FFT_DATA_SIZES)=FFT_16bit
qname SETS "Q14"
datainlog SETA 2
datalog SETA 2
coeflog SETA 2
datainformat SETS "H"
dataformat SETS "H"
coefformat SETS "H"
qshift SETA 14
ENDIF
; find the coefficient ordering
coeforder SETS "S"
IF (architecture>=5):LAND:(qshift<16)
coeforder SETS "R"
ENDIF
; decode real vs complex input data type
intype SETS ""
IF ($flags:AND:FFT_INPUTTYPE)=FFT_REAL
intype SETS "R"
ENDIF
; decode on outpos
outpos SETS ""
IF ($flags:AND:FFT_OUTPUTPOS)=FFT_OUT_INBUF
outpos SETS "I"
ENDIF
; decode on prescale
prescale SETS ""
IF ($flags:AND:FFT_INPUTSCALE)=FFT_PRESCALE
prescale SETS "P"
ENDIF
; decode on output scale
norm SETA 1
IF ($flags:AND:FFT_OUTPUTSCALE)=FFT_NONORM
norm SETA 0
ENDIF
; calculate shift to convert data offsets to coefficient offsets
SETSHIFT cdshift, ($datalog)-($coeflog)
$name SETS "$radix$direction$qname$intype$outpos$prescale"
MEND
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; ;
; FFT GENERATOR ;
; ;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; FFT options bitfield
FFT_DIRECTION EQU 0x00000001 ; direction select bit
FFT_FORWARD EQU 0x00000000 ; forward exp(-ijkw) coefficient FFT
FFT_INVERSE EQU 0x00000001 ; inverse exp(+ijkw) coefficient FFT
FFT_INPUTORDER EQU 0x00000002 ; input order select field
FFT_BITREV EQU 0x00000000 ; input data is in normal order (bit reverse)
FFT_REVERSED EQU 0x00000002 ; assume input data is already bit revesed
FFT_INPUTSCALE EQU 0x00000004 ; select scale on input data
FFT_NOPRESCALE EQU 0x00000000 ; do not scale input data
FFT_PRESCALE EQU 0x00000004 ; scale input data up by a register amount
FFT_INPUTTYPE EQU 0x00000010 ; selector for real/complex input data
FFT_COMPLEX EQU 0x00000000 ; do complex FFT of N points
FFT_REAL EQU 0x00000010 ; do a 2*N point real FFT
FFT_OUTPUTPOS EQU 0x00000020 ; where is the output placed?
FFT_OUT_OUTBUF EQU 0x00000000 ; default - in the output buffer
FFT_OUT_INBUF EQU 0x00000020 ; copy it back to the input buffer
FFT_RADIX EQU 0x00000F00 ; radix select
FFT_RADIX4 EQU 0x00000000 ; radix 4 (log_2 N must be even)
FFT_RADIX4_8F EQU 0x00000100 ; radix 4 with radix 8 first stage
FFT_RADIX4_2L EQU 0x00000200 ; radix 4 with optional radix 2 last stage
FFT_OUTPUTSCALE EQU 0x00001000 ; select output scale value
FFT_NORMALISE EQU 0x00000000 ; default - divide by N during algorithm
FFT_NONORM EQU 0x00001000 ; calculate the raw sum (no scale)
FFT_DATA_SIZES EQU 0x000F0000
FFT_16bit EQU 0x00000000 ; 16-bit data and Q14 coefs
FFT_32bit EQU 0x00010000 ; 32-bit data and Q30 coefs
END

View File

@ -0,0 +1,101 @@
;
; $Copyright:
; ----------------------------------------------------------------
; This confidential and proprietary software may be used only as
; authorised by a licensing agreement from ARM Limited
; (C) COPYRIGHT 2000,2002 ARM Limited
; ALL RIGHTS RESERVED
; The entire notice above must be reproduced on all authorised
; copies and copies may only be made to the extent permitted
; by a licensing agreement from ARM Limited.
; ----------------------------------------------------------------
; File: fft_main.h,v
; Revision: 1.10
; ----------------------------------------------------------------
; $
;
; Optimised ARM assembler multi-radix FFT
; Please read the readme.txt before this file
;
INCLUDE fft_mac_forward.h ; general macros
INCLUDE fs_rad8_forward.h ; first stage, radix 8 macros
INCLUDE gs_rad4.h ; general stage, radix 4 macros
; The macro in this file generates a whole FFT by glueing together
; FFT stage macros. It is designed to handle a range of power-of-2
; FFT's, the power of 2 set at run time.
; The following should be set up:
;
; $flags = a 32-bit integer indicating what FFT code to generate
; formed by a bitmask of the above FFT_* flag definitions
; (see fft_mac.h)
;
; r0 = inptr = address of the input buffer
; r1 = dptr = address of the output buffer
; r2 = N = the number of points in the FFT
; r3 = = optional pre-left shift to apply to the input data
;
; The contents of the input buffer are preserved (provided that the
; input and output buffer are different, which must be the case unless
; no bitreversal is required and the input is provided pre-reversed).
MACRO
GENERATE_FFT $flags
; decode the options word
FFT_OPTIONS_STRING $flags, name
IF "$outpos"<>""
; stack the input buffer address for later on
STMFD sp!, {inptr}
ENDIF
; Do first stage - radix 4 or radix 8 depending on parity
IF "$radix"="4O"
FS_RAD8
tablename SETS "_8"
tablename SETS "$qname$coeforder$tablename"
ELSE
FS_RAD4
tablename SETS "_4"
tablename SETS "$qname$coeforder$tablename"
ENDIF
IMPORT t_$tablename
LDR cptr, =t_$tablename ; coefficient table
CMP count, #1
BEQ %FT10 ; exit for small case
12 ; General stage loop
GS_RAD4
CMP count, #2
BGT %BT12
IF "$radix"="4B"
; support odd parity as well
;BLT %FT10 ; less than 2 left (ie, finished)
;LS_RAD2 ; finish off with a radix 2 stage
ENDIF
10 ; we've finished the complex FFT
IF ($flags:AND:FFT_INPUTTYPE)=FFT_REAL
; convert to a real FFT
IF "$outpos"="I"
LDMFD sp!, {dout}
ELSE
MOV dout, dptr
ENDIF
; dinc = (N/2) >> datalog where N is the number of real points
IMPORT s_$tablename
LDR t0, = s_$tablename
LDR t0, [t0] ; max N handled by the table
MOV t1, dinc, LSR #($datalog-1) ; real N we want to handle
CMP t0, t1
MOV cinc, #3<<$coeflog ; radix 4 table stage
MOVEQ cinc, #1<<$coeflog ; radix 4 table stage
LS_ZTOR
ENDIF
MEND
END

View File

@ -0,0 +1,101 @@
;
; $Copyright:
; ----------------------------------------------------------------
; This confidential and proprietary software may be used only as
; authorised by a licensing agreement from ARM Limited
; (C) COPYRIGHT 2000,2002 ARM Limited
; ALL RIGHTS RESERVED
; The entire notice above must be reproduced on all authorised
; copies and copies may only be made to the extent permitted
; by a licensing agreement from ARM Limited.
; ----------------------------------------------------------------
; File: fft_main.h,v
; Revision: 1.10
; ----------------------------------------------------------------
; $
;
; Optimised ARM assembler multi-radix FFT
; Please read the readme.txt before this file
;
INCLUDE fft_mac_inverse.h ; general macros
INCLUDE fs_rad8_inverse.h ; first stage, radix 8 macros
INCLUDE gs_rad4.h ; general stage, radix 4 macros
; The macro in this file generates a whole FFT by glueing together
; FFT stage macros. It is designed to handle a range of power-of-2
; FFT's, the power of 2 set at run time.
; The following should be set up:
;
; $flags = a 32-bit integer indicating what FFT code to generate
; formed by a bitmask of the above FFT_* flag definitions
; (see fft_mac.h)
;
; r0 = inptr = address of the input buffer
; r1 = dptr = address of the output buffer
; r2 = N = the number of points in the FFT
; r3 = = optional pre-left shift to apply to the input data
;
; The contents of the input buffer are preserved (provided that the
; input and output buffer are different, which must be the case unless
; no bitreversal is required and the input is provided pre-reversed).
MACRO
GENERATE_FFT $flags
; decode the options word
FFT_OPTIONS_STRING $flags, name
IF "$outpos"<>""
; stack the input buffer address for later on
STMFD sp!, {inptr}
ENDIF
; Do first stage - radix 4 or radix 8 depending on parity
IF "$radix"="4O"
FS_RAD8
tablename SETS "_8"
tablename SETS "$qname$coeforder$tablename"
ELSE
FS_RAD4
tablename SETS "_4"
tablename SETS "$qname$coeforder$tablename"
ENDIF
IMPORT t_$tablename
LDR cptr, =t_$tablename ; coefficient table
CMP count, #1
BEQ %FT10 ; exit for small case
12 ; General stage loop
GS_RAD4
CMP count, #2
BGT %BT12
IF "$radix"="4B"
; support odd parity as well
;BLT %FT10 ; less than 2 left (ie, finished)
;LS_RAD2 ; finish off with a radix 2 stage
ENDIF
10 ; we've finished the complex FFT
IF ($flags:AND:FFT_INPUTTYPE)=FFT_REAL
; convert to a real FFT
IF "$outpos"="I"
LDMFD sp!, {dout}
ELSE
MOV dout, dptr
ENDIF
; dinc = (N/2) >> datalog where N is the number of real points
IMPORT s_$tablename
LDR t0, = s_$tablename
LDR t0, [t0] ; max N handled by the table
MOV t1, dinc, LSR #($datalog-1) ; real N we want to handle
CMP t0, t1
MOV cinc, #3<<$coeflog ; radix 4 table stage
MOVEQ cinc, #1<<$coeflog ; radix 4 table stage
LS_ZTOR
ENDIF
MEND
END

View File

@ -0,0 +1,236 @@
;
; $Copyright:
; ----------------------------------------------------------------
; This confidential and proprietary software may be used only as
; authorised by a licensing agreement from ARM Limited
; (C) COPYRIGHT 2000,2002 ARM Limited
; ALL RIGHTS RESERVED
; The entire notice above must be reproduced on all authorised
; copies and copies may only be made to the extent permitted
; by a licensing agreement from ARM Limited.
; ----------------------------------------------------------------
; File: fs_rad8.h,v
; Revision: 1.5
; ----------------------------------------------------------------
; $
;
; Optimised ARM assembler multi-radix FFT
; Please read the readme.txt before this file
;
; This file contains first stage, radix-8 code
; It bit reverses (assuming a power of 2 FFT) and performs the first stage
;
MACRO
FS_RAD8
SETSHIFT postldshift, 3*norm
SETSHIFT postmulshift, 3*norm+qshift
SETSHIFT postldshift1, 3*norm-1
SETSHIFT postmulshift1, 3*norm+qshift-1
IF "$prescale"<>""
STMFD sp!, {dptr, N, r3}
ELSE
STMFD sp!, {dptr, N}
ENDIF
MOV bitrev, #0
MOV dinc, N, LSL #($datalog-2)
12 ; first (radix 8) stage loop
; do first two (radix 2) stages
FIRST_STAGE_RADIX8_ODD dinc, "dinc, LSR #1", bitrev
FIRST_STAGE_RADIX8_EVEN dinc, bitrev
; third (radix 2) stage
LDMFD sp!, {x0r, x0i}
ADD $h0r, $h0r, x0r $postldshift ; standard add
ADD $h0i, $h0i, x0i $postldshift
SUB x0r, $h0r, x0r $postldshift1
SUB x0i, $h0i, x0i $postldshift1
STORE dptr, #1<<$datalog, $h0r, $h0i
LDMFD sp!, {x1r, x1i}
ADD $h1r, $h1r, x1r $postmulshift
ADD $h1i, $h1i, x1i $postmulshift
SUB x1r, $h1r, x1r $postmulshift1
SUB x1i, $h1i, x1i $postmulshift1
STORE dptr, #1<<$datalog, $h1r, $h1i
LDMFD sp!, {x2r, x2i}
SUBi $h2r, $h2r, x2r $postldshift ; note that x2r & x2i were
ADDi $h2i, $h2i, x2i $postldshift ; swapped above
ADDi x2r, $h2r, x2r $postldshift1
SUBi x2i, $h2i, x2i $postldshift1
STORE dptr, #1<<$datalog, $h2r, $h2i
LDMFD sp!, {x3r, x3i}
ADD $h3r, $h3r, x3r $postmulshift
ADD $h3i, $h3i, x3i $postmulshift
SUB x3r, $h3r, x3r $postmulshift1
SUB x3i, $h3i, x3i $postmulshift1
STORE dptr, #1<<$datalog, $h3r, $h3i
STORE dptr, #1<<$datalog, x0r, x0i
STORE dptr, #1<<$datalog, x1r, x1i
STORE dptr, #1<<$datalog, x2r, x2i
STORE dptr, #1<<$datalog, x3r, x3i
IF reversed
SUBS dinc, dinc, #2<<$datalog
BGT %BT12
ELSE
; increment the count in a bit reverse manner
EOR bitrev, bitrev, dinc, LSR #($datalog-2+4) ; t0 = (N/8)>>1
TST bitrev, dinc, LSR #($datalog-2+4)
BNE %BT12
; get here for 1/2 the loops - carry to next bit
EOR bitrev, bitrev, dinc, LSR #($datalog-2+5)
TST bitrev, dinc, LSR #($datalog-2+5)
BNE %BT12
; get here for 1/4 of the loops - stop unrolling
MOV t0, dinc, LSR #($datalog-2+6)
15 ; bit reverse increment loop
EOR bitrev, bitrev, t0
TST bitrev, t0
BNE %BT12
; get here for 1/8 of the loops (or when finished)
MOVS t0, t0, LSR #1 ; move down to next bit
BNE %BT15 ; carry on if we haven't run off the bottom
ENDIF
IF "$prescale"<>""
LDMFD sp!, {dptr, N, r3}
ELSE
LDMFD sp!, {dptr, N}
ENDIF
MOV count, N, LSR #3 ; start with N/8 blocks 8 each
MOV dinc, #8<<$datalog ; initial skip is 8 elements
MEND
MACRO
FIRST_STAGE_RADIX8_ODD $dinc, $dinc_lsr1, $bitrev
IF reversed
; load non bit reversed
ADD t0, inptr, #4<<$datalog
LOADDATAI t0, #1<<$datalog, x0r, x0i
LOADDATAI t0, #1<<$datalog, x1r, x1i
LOADDATAI t0, #1<<$datalog, x2r, x2i
LOADDATAI t0, #1<<$datalog, x3r, x3i
ELSE
; load data elements 1,3,5,7 into register order 1,5,3,7
ADD t0, inptr, $bitrev, LSL #$datalog
ADD t0, t0, $dinc_lsr1 ; load in odd terms first
LOADDATAI t0, $dinc, x0r, x0i
LOADDATAI t0, $dinc, x2r, x2i
LOADDATAI t0, $dinc, x1r, x1i
LOADDATAI t0, $dinc, x3r, x3i
ENDIF
IF "$prescale"="P"
LDR t0, [sp, #8]
MOV x0r, x0r, LSL t0
MOV x0i, x0i, LSL t0
MOV x1r, x1r, LSL t0
MOV x1i, x1i, LSL t0
MOV x2r, x2r, LSL t0
MOV x2i, x2i, LSL t0
MOV x3r, x3r, LSL t0
MOV x3i, x3i, LSL t0
ENDIF
SETREG h2, x3r, x3i
SETREG h3, t0, t1
; first stage (radix 2) butterflies
ADD x0r, x0r, x1r
ADD x0i, x0i, x1i
SUB x1r, x0r, x1r, LSL #1
SUB x1i, x0i, x1i, LSL #1
SUB $h3r, x2r, x3r
SUB $h3i, x2i, x3i
ADD $h2r, x2r, x3r
ADD $h2i, x2i, x3i
; second stage (radix 2) butterflies
SUB x2i, x0r, $h2r ; swap real and imag here
SUB x2r, x0i, $h2i ; for use later
ADD x0r, x0r, $h2r
ADD x0i, x0i, $h2i
ADDi x3r, x1r, $h3i
SUBi x3i, x1i, $h3r
SUBi x1r, x1r, $h3i
ADDi x1i, x1i, $h3r
; do the 1/sqrt(2) (+/-1 +/- i) twiddles for third stage
LCLS tempname
tempname SETS "R_rad8"
IMPORT t_$qname$tempname
LDR t1, =t_$qname$tempname
; IMPORT t_$qname.R_rad8
; LDR t1, =t_$qname.R_rad8
LOADCOEFR t1, t1
STMFD sp!, {dinc} ;;; FIXME!!!
ADD t0, x1r, x1i ; real part when * (1-i)
SCALE x1r, t0, t1, dinc ; scale by 1/sqrt(2)
RSB t0, t0, x1i, LSL #1 ; imag part when * (1-i)
SCALE x1i, t0, t1, dinc ; scale by 1/sqrt(2)
SUB t0, x3i, x3r ; real part when * (-1-i)
SCALE x3r, t0, t1, dinc ; scale by 1/sqrt(2)
SUB t0, t0, x3i, LSL #1 ; imag part when * (-1-i)
SCALE x3i, t0, t1, dinc ; scale by 1/sqrt(2)
LDMFD sp!, {dinc} ;;; FIXME!!!
STMFD sp!, {x0r, x0i, x1r, x1i, x2r, x2i, x3r, x3i}
MEND
MACRO
FIRST_STAGE_RADIX8_EVEN $dinc, $bitrev
; load elements 0,2,4,6 into register order 0,4,2,6
SETREGS h, x1r, x1i, x2r, x2i, x3r, x3i, t0, t1
SETREG g3, x0r, x0i
IF reversed
; load normally
LOADDATAI inptr, #1<<$datalog, $h0r, $h0i
LOADDATAI inptr, #1<<$datalog, $h1r, $h1i
LOADDATAI inptr, #1<<$datalog, $h2r, $h2i
LOADDATAI inptr, #1<<$datalog, $h3r, $h3i
ADD inptr, inptr, #4<<$datalog
ELSE
; load bit reversed
ADD x0r, inptr, $bitrev, LSL #$datalog
LOADDATAI x0r, $dinc, $h0r, $h0i
LOADDATAI x0r, $dinc, $h2r, $h2i
LOADDATAI x0r, $dinc, $h1r, $h1i
LOADDATAI x0r, $dinc, $h3r, $h3i
ENDIF
IF "$prescale"="P"
LDR x0r, [sp, #8+32] ; NB we've stacked 8 extra regs!
MOV $h0r, $h0r, LSL x0r
MOV $h0i, $h0i, LSL x0r
MOV $h1r, $h1r, LSL x0r
MOV $h1i, $h1i, LSL x0r
MOV $h2r, $h2r, LSL x0r
MOV $h2i, $h2i, LSL x0r
MOV $h3r, $h3r, LSL x0r
MOV $h3i, $h3i, LSL x0r
ENDIF
SHIFTDATA $h0r, $h0i
; first stage (radix 2) butterflies
ADD $h0r, $h0r, $h1r $postldshift
ADD $h0i, $h0i, $h1i $postldshift
SUB $h1r, $h0r, $h1r $postldshift1
SUB $h1i, $h0i, $h1i $postldshift1
SUB $g3r, $h2r, $h3r
SUB $g3i, $h2i, $h3i
ADD $h2r, $h2r, $h3r
ADD $h2i, $h2i, $h3i
; second stage (radix 2) butterflies
ADD $h0r, $h0r, $h2r $postldshift
ADD $h0i, $h0i, $h2i $postldshift
SUB $h2r, $h0r, $h2r $postldshift1
SUB $h2i, $h0i, $h2i $postldshift1
ADDi $h3r, $h1r, $g3i $postldshift
SUBi $h3i, $h1i, $g3r $postldshift
SUBi $h1r, $h1r, $g3i $postldshift
ADDi $h1i, $h1i, $g3r $postldshift
MEND
END

View File

@ -0,0 +1,236 @@
;
; $Copyright:
; ----------------------------------------------------------------
; This confidential and proprietary software may be used only as
; authorised by a licensing agreement from ARM Limited
; (C) COPYRIGHT 2000,2002 ARM Limited
; ALL RIGHTS RESERVED
; The entire notice above must be reproduced on all authorised
; copies and copies may only be made to the extent permitted
; by a licensing agreement from ARM Limited.
; ----------------------------------------------------------------
; File: fs_rad8.h,v
; Revision: 1.5
; ----------------------------------------------------------------
; $
;
; Optimised ARM assembler multi-radix FFT
; Please read the readme.txt before this file
;
; This file contains first stage, radix-8 code
; It bit reverses (assuming a power of 2 FFT) and performs the first stage
;
MACRO
FS_RAD8
SETSHIFT postldshift, 3*norm
SETSHIFT postmulshift, 3*norm+qshift
SETSHIFT postldshift1, 3*norm-1
SETSHIFT postmulshift1, 3*norm+qshift-1
IF "$prescale"<>""
STMFD sp!, {dptr, N, r3}
ELSE
STMFD sp!, {dptr, N}
ENDIF
MOV bitrev, #0
MOV dinc, N, LSL #($datalog-2)
12 ; first (radix 8) stage loop
; do first two (radix 2) stages
FIRST_STAGE_RADIX8_ODD dinc, "dinc, LSR #1", bitrev
FIRST_STAGE_RADIX8_EVEN dinc, bitrev
; third (radix 2) stage
LDMFD sp!, {x0r, x0i}
ADD $h0r, $h0r, x0r $postldshift ; standard add
ADD $h0i, $h0i, x0i $postldshift
SUB x0r, $h0r, x0r $postldshift1
SUB x0i, $h0i, x0i $postldshift1
STORE dptr, #1<<$datalog, $h0r, $h0i
LDMFD sp!, {x1r, x1i}
ADD $h1r, $h1r, x1r $postmulshift
ADD $h1i, $h1i, x1i $postmulshift
SUB x1r, $h1r, x1r $postmulshift1
SUB x1i, $h1i, x1i $postmulshift1
STORE dptr, #1<<$datalog, $h1r, $h1i
LDMFD sp!, {x2r, x2i}
SUBi $h2r, $h2r, x2r $postldshift ; note that x2r & x2i were
ADDi $h2i, $h2i, x2i $postldshift ; swapped above
ADDi x2r, $h2r, x2r $postldshift1
SUBi x2i, $h2i, x2i $postldshift1
STORE dptr, #1<<$datalog, $h2r, $h2i
LDMFD sp!, {x3r, x3i}
ADD $h3r, $h3r, x3r $postmulshift
ADD $h3i, $h3i, x3i $postmulshift
SUB x3r, $h3r, x3r $postmulshift1
SUB x3i, $h3i, x3i $postmulshift1
STORE dptr, #1<<$datalog, $h3r, $h3i
STORE dptr, #1<<$datalog, x0r, x0i
STORE dptr, #1<<$datalog, x1r, x1i
STORE dptr, #1<<$datalog, x2r, x2i
STORE dptr, #1<<$datalog, x3r, x3i
IF reversed
SUBS dinc, dinc, #2<<$datalog
BGT %BT12
ELSE
; increment the count in a bit reverse manner
EOR bitrev, bitrev, dinc, LSR #($datalog-2+4) ; t0 = (N/8)>>1
TST bitrev, dinc, LSR #($datalog-2+4)
BNE %BT12
; get here for 1/2 the loops - carry to next bit
EOR bitrev, bitrev, dinc, LSR #($datalog-2+5)
TST bitrev, dinc, LSR #($datalog-2+5)
BNE %BT12
; get here for 1/4 of the loops - stop unrolling
MOV t0, dinc, LSR #($datalog-2+6)
15 ; bit reverse increment loop
EOR bitrev, bitrev, t0
TST bitrev, t0
BNE %BT12
; get here for 1/8 of the loops (or when finished)
MOVS t0, t0, LSR #1 ; move down to next bit
BNE %BT15 ; carry on if we haven't run off the bottom
ENDIF
IF "$prescale"<>""
LDMFD sp!, {dptr, N, r3}
ELSE
LDMFD sp!, {dptr, N}
ENDIF
MOV count, N, LSR #3 ; start with N/8 blocks 8 each
MOV dinc, #8<<$datalog ; initial skip is 8 elements
MEND
MACRO
FIRST_STAGE_RADIX8_ODD $dinc, $dinc_lsr1, $bitrev
IF reversed
; load non bit reversed
ADD t0, inptr, #4<<$datalog
LOADDATAI t0, #1<<$datalog, x0r, x0i
LOADDATAI t0, #1<<$datalog, x1r, x1i
LOADDATAI t0, #1<<$datalog, x2r, x2i
LOADDATAI t0, #1<<$datalog, x3r, x3i
ELSE
; load data elements 1,3,5,7 into register order 1,5,3,7
ADD t0, inptr, $bitrev, LSL #$datalog
ADD t0, t0, $dinc_lsr1 ; load in odd terms first
LOADDATAI t0, $dinc, x0r, x0i
LOADDATAI t0, $dinc, x2r, x2i
LOADDATAI t0, $dinc, x1r, x1i
LOADDATAI t0, $dinc, x3r, x3i
ENDIF
IF "$prescale"="P"
LDR t0, [sp, #8]
MOV x0r, x0r, LSL t0
MOV x0i, x0i, LSL t0
MOV x1r, x1r, LSL t0
MOV x1i, x1i, LSL t0
MOV x2r, x2r, LSL t0
MOV x2i, x2i, LSL t0
MOV x3r, x3r, LSL t0
MOV x3i, x3i, LSL t0
ENDIF
SETREG h2, x3r, x3i
SETREG h3, t0, t1
; first stage (radix 2) butterflies
ADD x0r, x0r, x1r
ADD x0i, x0i, x1i
SUB x1r, x0r, x1r, LSL #1
SUB x1i, x0i, x1i, LSL #1
SUB $h3r, x2r, x3r
SUB $h3i, x2i, x3i
ADD $h2r, x2r, x3r
ADD $h2i, x2i, x3i
; second stage (radix 2) butterflies
SUB x2i, x0r, $h2r ; swap real and imag here
SUB x2r, x0i, $h2i ; for use later
ADD x0r, x0r, $h2r
ADD x0i, x0i, $h2i
ADDi x3r, x1r, $h3i
SUBi x3i, x1i, $h3r
SUBi x1r, x1r, $h3i
ADDi x1i, x1i, $h3r
; do the 1/sqrt(2) (+/-1 +/- i) twiddles for third stage
LCLS tempname
tempname SETS "R_rad8"
IMPORT t_$qname$tempname
LDR t1, =t_$qname$tempname
; IMPORT t_$qname.R_rad8
; LDR t1, =t_$qname.R_rad8
LOADCOEFR t1, t1
STMFD sp!, {dinc} ;;; FIXME!!!
SUB t0, x1r, x1i ; real part when * (1+i)
SCALE x1r, t0, t1, dinc ; scale by 1/sqrt(2)
ADD t0, t0, x1i, LSL #1 ; imag part when * (1+i)
SCALE x1i, t0, t1, dinc ; scale by 1/sqrt(2)
SUB t0, x3r, x3i ; imag part when * (-1+i)
SCALE x3i, t0, t1, dinc ; scale by 1/sqrt(2)
SUB t0, t0, x3r, LSL #1 ; real part when * (-1+i)
SCALE x3r, t0, t1, dinc ; scale by 1/sqrt(2)
LDMFD sp!, {dinc} ;;; FIXME!!!
STMFD sp!, {x0r, x0i, x1r, x1i, x2r, x2i, x3r, x3i}
MEND
MACRO
FIRST_STAGE_RADIX8_EVEN $dinc, $bitrev
; load elements 0,2,4,6 into register order 0,4,2,6
SETREGS h, x1r, x1i, x2r, x2i, x3r, x3i, t0, t1
SETREG g3, x0r, x0i
IF reversed
; load normally
LOADDATAI inptr, #1<<$datalog, $h0r, $h0i
LOADDATAI inptr, #1<<$datalog, $h1r, $h1i
LOADDATAI inptr, #1<<$datalog, $h2r, $h2i
LOADDATAI inptr, #1<<$datalog, $h3r, $h3i
ADD inptr, inptr, #4<<$datalog
ELSE
; load bit reversed
ADD x0r, inptr, $bitrev, LSL #$datalog
LOADDATAI x0r, $dinc, $h0r, $h0i
LOADDATAI x0r, $dinc, $h2r, $h2i
LOADDATAI x0r, $dinc, $h1r, $h1i
LOADDATAI x0r, $dinc, $h3r, $h3i
ENDIF
IF "$prescale"="P"
LDR x0r, [sp, #8+32] ; NB we've stacked 8 extra regs!
MOV $h0r, $h0r, LSL x0r
MOV $h0i, $h0i, LSL x0r
MOV $h1r, $h1r, LSL x0r
MOV $h1i, $h1i, LSL x0r
MOV $h2r, $h2r, LSL x0r
MOV $h2i, $h2i, LSL x0r
MOV $h3r, $h3r, LSL x0r
MOV $h3i, $h3i, LSL x0r
ENDIF
SHIFTDATA $h0r, $h0i
; first stage (radix 2) butterflies
ADD $h0r, $h0r, $h1r $postldshift
ADD $h0i, $h0i, $h1i $postldshift
SUB $h1r, $h0r, $h1r $postldshift1
SUB $h1i, $h0i, $h1i $postldshift1
SUB $g3r, $h2r, $h3r
SUB $g3i, $h2i, $h3i
ADD $h2r, $h2r, $h3r
ADD $h2i, $h2i, $h3i
; second stage (radix 2) butterflies
ADD $h0r, $h0r, $h2r $postldshift
ADD $h0i, $h0i, $h2i $postldshift
SUB $h2r, $h0r, $h2r $postldshift1
SUB $h2i, $h0i, $h2i $postldshift1
ADDi $h3r, $h1r, $g3i $postldshift
SUBi $h3i, $h1i, $g3r $postldshift
SUBi $h1r, $h1r, $g3i $postldshift
ADDi $h1i, $h1i, $g3r $postldshift
MEND
END

View File

@ -0,0 +1,111 @@
;
; $Copyright:
; ----------------------------------------------------------------
; This confidential and proprietary software may be used only as
; authorised by a licensing agreement from ARM Limited
; (C) COPYRIGHT 2000,2002 ARM Limited
; ALL RIGHTS RESERVED
; The entire notice above must be reproduced on all authorised
; copies and copies may only be made to the extent permitted
; by a licensing agreement from ARM Limited.
; ----------------------------------------------------------------
; File: gs_rad4.h,v
; Revision: 1.8
; ----------------------------------------------------------------
; $
;
; Optimised ARM assembler multi-radix FFT
; Please read the readme.txt before this file
;
; This file contains the general stage, radix 4 macro
MACRO
GS_RAD4
SETSHIFT postldshift, 2*norm
SETSHIFT postmulshift, 2*norm+qshift
; dinc contains the number of bytes between the values to read
; for the radix 4 bufferfly
; Thus:
; dinc*4 = number of bytes between the blocks at this level
; dinc>>datalog = number of elements in each block at this level
MOV count, count, LSR #2 ; a quarter the blocks per stage
STMFD sp!, {dptr, count}
ADD t0, dinc, dinc, LSL #1 ; 3*dinc
ADD dptr, dptr, t0 ; move to last of 4 butterflys
SUB count, count, #1<<16 ; prepare top half of counter
12 ; block loop
; set top half of counter to (elements/block - 1)
ADD count, count, dinc, LSL #(16-$datalog)
15 ; butterfly loop
IF (architecture>=5):LAND:(qshift<16)
; E extensions available (21 cycles)
; But needs a different table format
LDMIA cptr!, {x0i, x1i, x2i}
LDR x2r, [dptr], -dinc
LDR x1r, [dptr], -dinc
LDR x0r, [dptr], -dinc
TWIDDLE_E x3r, x3i, x2i, t0, x2r
TWIDDLE_E x2r, x2i, x1i, t0, x1r
TWIDDLE_E x1r, x1i, x0i, t0, x0r
ELSE
; load next three twiddle factors (66 @ 4 cycles/mul)
LOADCOEFS cptr, x1r, x1i, x2r, x2i, x3r, x3i
; load data in reversed order & perform twiddles
LOADDATA dptr, -dinc, x0r, x0i
TWIDDLE x0r, x0i, x3r, x3i, t0, t1
LOADDATA dptr, -dinc, x0r, x0i
TWIDDLE x0r, x0i, x2r, x2i, t0, t1
LOADDATA dptr, -dinc, x0r, x0i
TWIDDLE x0r, x0i, x1r, x1i, t0, t1
ENDIF
LOADDATAZ dptr, x0r, x0i
SHIFTDATA x0r, x0i
; now calculate the h's
; h[0,k] = g[0,k] + g[2,k]
; h[1,k] = g[0,k] - g[2,k]
; h[2,k] = g[1,k] + g[3,k]
; h[3,k] = g[1,k] - g[3,k]
SETREGS h,t0,t1,x0r,x0i,x1r,x1i,x2r,x2i
ADD $h0r, x0r, x1r $postmulshift
ADD $h0i, x0i, x1i $postmulshift
SUB $h1r, x0r, x1r $postmulshift
SUB $h1i, x0i, x1i $postmulshift
ADD $h2r, x2r, x3r
ADD $h2i, x2i, x3i
SUB $h3r, x2r, x3r
SUB $h3i, x2i, x3i
; now calculate the y's and store results
; y[0*N/4+k] = h[0,k] + h[2,k]
; y[1*N/4+k] = h[1,k] + j*h[3,k]
; y[2*N/4+k] = h[0,k] - h[2,k]
; y[3*N/4+k] = h[1,k] - j*h[3,k]
SETREG y0,x3r,x3i
ADD $y0r, $h0r, $h2r $postmulshift
ADD $y0i, $h0i, $h2i $postmulshift
STORE dptr, dinc, $y0r, $y0i
SUBi $y0r, $h1r, $h3i $postmulshift
ADDi $y0i, $h1i, $h3r $postmulshift
STORE dptr, dinc, $y0r, $y0i
SUB $y0r, $h0r, $h2r $postmulshift
SUB $y0i, $h0i, $h2i $postmulshift
STORE dptr, dinc, $y0r, $y0i
ADDi $y0r, $h1r, $h3i $postmulshift
SUBi $y0i, $h1i, $h3r $postmulshift
STOREP dptr, $y0r, $y0i
; continue butterfly loop
SUBS count, count, #1<<16
BGE %BT15
; decrement counts for block loop
ADD t0, dinc, dinc, LSL #1 ; dinc * 3
ADD dptr, dptr, t0 ; move onto next block
SUB cptr, cptr, t0 $cdshift ; move back to coeficients start
SUB count, count, #1 ; done one more block
MOVS t1, count, LSL #16
BNE %BT12 ; still more blocks to do
; finished stage
ADD cptr, cptr, t0 $cdshift ; move onto next stage coeficients
LDMFD sp!, {dptr, count}
MOV dinc, dinc, LSL #2 ; four times the entries per block
MEND
END

View File

@ -0,0 +1,91 @@
# $Copyright:
# ----------------------------------------------------------------
# This confidential and proprietary software may be used only as
# authorised by a licensing agreement from ARM Limited
# (C) COPYRIGHT 2000,2002 ARM Limited
# ALL RIGHTS RESERVED
# The entire notice above must be reproduced on all authorised
# copies and copies may only be made to the extent permitted
# by a licensing agreement from ARM Limited.
# ----------------------------------------------------------------
# File: readme.txt,v
# Revision: 1.4
# ----------------------------------------------------------------
# $
!!! To fully understand the FFT/ARM9E/WIN_MOB implementation in SPLIB,
!!! you have to refer to the full set of files in RVDS' package:
!!! C:\Program Files\ARM\RVDS\Examples\3.0\79\windows\fft_v5te.
ARM Assembler FFT implementation
================================
Overview
========
This implementation has been restructured to allow FFT's of varying radix
rather than the fixed radix-2 or radix-4 versions allowed earlier. The
implementation of an optimised assembler FFT of a given size (N points)
consists of chaining together a sequence of stages 1,2,3,...,k such that the
j'th stage has radix Rj and:
N = R1*R2*R3*...*Rk
For the ARM implementations we keep the size of the Rj's decreasing with
increasing j, EXCEPT that if there are any non power of 2 factors (ie, odd
prime factors) then these come before all the power of 2 factors.
For example:
N=64 would be implemented as stages:
radix 4, radix 4, radix 4
N=128 would be implemented as stages:
radix 8, radix 4, radix 4
OR
radix 4, radix 4, radix 4, radix 2
N=192 would be implemented as stages:
radix 3, radix 4, radix 4, radix 4
The bitreversal is usally combined with the first stage where possible.
Structure
=========
The actual FFT routine is built out of a hierarchy of macros. All stage
macros and filenames are one of:
fs_rad<n> => the macro implements a radix <n> First Stage (usually
including the bit reversal)
gs_rad<n> => the macro implements a radix <n> General Stage (any
stage except the first - includes the twiddle operations)
ls_rad<n> => the macro implements a radix <n> Last Stage (this macro
is like the gs_rad<n> version but is optimised for
efficiency in the last stage)
ls_ztor => this macro converts the output of a complex FFT to
be the first half of the output of a real FFT of
double the number of input points.
Other files are:
fft_mac.h => Macro's and register definitions shared by all radix
implementations
fft_main.h => Main FFT macros drawing together the stage macros
to produce a complete FFT
Interfaces
==========
The register interfaces for the different type of stage macros are described
at the start of fft_mac.h

View File

@ -0,0 +1,695 @@
/*
* Copyright (C) ARM Limited 1998-2002. All rights reserved.
*
* t_01024_8.c
*
*/
extern const int s_Q14S_8;
const int s_Q14S_8 = 1024;
extern const unsigned short t_Q14S_8[2032];
const unsigned short t_Q14S_8[2032] = {
0x4000,0x0000 ,0x4000,0x0000 ,0x4000,0x0000 ,
0x22a3,0x187e ,0x3249,0x0c7c ,0x11a8,0x238e ,
0x0000,0x2d41 ,0x22a3,0x187e ,0xdd5d,0x3b21 ,
0xdd5d,0x3b21 ,0x11a8,0x238e ,0xb4be,0x3ec5 ,
0xc000,0x4000 ,0x0000,0x2d41 ,0xa57e,0x2d41 ,
0xac61,0x3b21 ,0xee58,0x3537 ,0xb4be,0x0c7c ,
0xa57e,0x2d41 ,0xdd5d,0x3b21 ,0xdd5d,0xe782 ,
0xac61,0x187e ,0xcdb7,0x3ec5 ,0x11a8,0xcac9 ,
0x4000,0x0000 ,0x4000,0x0000 ,0x4000,0x0000 ,
0x396b,0x0646 ,0x3cc8,0x0324 ,0x35eb,0x0964 ,
0x3249,0x0c7c ,0x396b,0x0646 ,0x2aaa,0x1294 ,
0x2aaa,0x1294 ,0x35eb,0x0964 ,0x1e7e,0x1b5d ,
0x22a3,0x187e ,0x3249,0x0c7c ,0x11a8,0x238e ,
0x1a46,0x1e2b ,0x2e88,0x0f8d ,0x0471,0x2afb ,
0x11a8,0x238e ,0x2aaa,0x1294 ,0xf721,0x3179 ,
0x08df,0x289a ,0x26b3,0x1590 ,0xea02,0x36e5 ,
0x0000,0x2d41 ,0x22a3,0x187e ,0xdd5d,0x3b21 ,
0xf721,0x3179 ,0x1e7e,0x1b5d ,0xd178,0x3e15 ,
0xee58,0x3537 ,0x1a46,0x1e2b ,0xc695,0x3fb1 ,
0xe5ba,0x3871 ,0x15fe,0x20e7 ,0xbcf0,0x3fec ,
0xdd5d,0x3b21 ,0x11a8,0x238e ,0xb4be,0x3ec5 ,
0xd556,0x3d3f ,0x0d48,0x2620 ,0xae2e,0x3c42 ,
0xcdb7,0x3ec5 ,0x08df,0x289a ,0xa963,0x3871 ,
0xc695,0x3fb1 ,0x0471,0x2afb ,0xa678,0x3368 ,
0xc000,0x4000 ,0x0000,0x2d41 ,0xa57e,0x2d41 ,
0xba09,0x3fb1 ,0xfb8f,0x2f6c ,0xa678,0x2620 ,
0xb4be,0x3ec5 ,0xf721,0x3179 ,0xa963,0x1e2b ,
0xb02d,0x3d3f ,0xf2b8,0x3368 ,0xae2e,0x1590 ,
0xac61,0x3b21 ,0xee58,0x3537 ,0xb4be,0x0c7c ,
0xa963,0x3871 ,0xea02,0x36e5 ,0xbcf0,0x0324 ,
0xa73b,0x3537 ,0xe5ba,0x3871 ,0xc695,0xf9ba ,
0xa5ed,0x3179 ,0xe182,0x39db ,0xd178,0xf073 ,
0xa57e,0x2d41 ,0xdd5d,0x3b21 ,0xdd5d,0xe782 ,
0xa5ed,0x289a ,0xd94d,0x3c42 ,0xea02,0xdf19 ,
0xa73b,0x238e ,0xd556,0x3d3f ,0xf721,0xd766 ,
0xa963,0x1e2b ,0xd178,0x3e15 ,0x0471,0xd094 ,
0xac61,0x187e ,0xcdb7,0x3ec5 ,0x11a8,0xcac9 ,
0xb02d,0x1294 ,0xca15,0x3f4f ,0x1e7e,0xc625 ,
0xb4be,0x0c7c ,0xc695,0x3fb1 ,0x2aaa,0xc2c1 ,
0xba09,0x0646 ,0xc338,0x3fec ,0x35eb,0xc0b1 ,
0x4000,0x0000 ,0x4000,0x0000 ,0x4000,0x0000 ,
0x3e69,0x0192 ,0x3f36,0x00c9 ,0x3d9a,0x025b ,
0x3cc8,0x0324 ,0x3e69,0x0192 ,0x3b1e,0x04b5 ,
0x3b1e,0x04b5 ,0x3d9a,0x025b ,0x388e,0x070e ,
0x396b,0x0646 ,0x3cc8,0x0324 ,0x35eb,0x0964 ,
0x37af,0x07d6 ,0x3bf4,0x03ed ,0x3334,0x0bb7 ,
0x35eb,0x0964 ,0x3b1e,0x04b5 ,0x306c,0x0e06 ,
0x341e,0x0af1 ,0x3a46,0x057e ,0x2d93,0x1050 ,
0x3249,0x0c7c ,0x396b,0x0646 ,0x2aaa,0x1294 ,
0x306c,0x0e06 ,0x388e,0x070e ,0x27b3,0x14d2 ,
0x2e88,0x0f8d ,0x37af,0x07d6 ,0x24ae,0x1709 ,
0x2c9d,0x1112 ,0x36ce,0x089d ,0x219c,0x1937 ,
0x2aaa,0x1294 ,0x35eb,0x0964 ,0x1e7e,0x1b5d ,
0x28b2,0x1413 ,0x3505,0x0a2b ,0x1b56,0x1d79 ,
0x26b3,0x1590 ,0x341e,0x0af1 ,0x1824,0x1f8c ,
0x24ae,0x1709 ,0x3334,0x0bb7 ,0x14ea,0x2193 ,
0x22a3,0x187e ,0x3249,0x0c7c ,0x11a8,0x238e ,
0x2093,0x19ef ,0x315b,0x0d41 ,0x0e61,0x257e ,
0x1e7e,0x1b5d ,0x306c,0x0e06 ,0x0b14,0x2760 ,
0x1c64,0x1cc6 ,0x2f7b,0x0eca ,0x07c4,0x2935 ,
0x1a46,0x1e2b ,0x2e88,0x0f8d ,0x0471,0x2afb ,
0x1824,0x1f8c ,0x2d93,0x1050 ,0x011c,0x2cb2 ,
0x15fe,0x20e7 ,0x2c9d,0x1112 ,0xfdc7,0x2e5a ,
0x13d5,0x223d ,0x2ba4,0x11d3 ,0xfa73,0x2ff2 ,
0x11a8,0x238e ,0x2aaa,0x1294 ,0xf721,0x3179 ,
0x0f79,0x24da ,0x29af,0x1354 ,0xf3d2,0x32ef ,
0x0d48,0x2620 ,0x28b2,0x1413 ,0xf087,0x3453 ,
0x0b14,0x2760 ,0x27b3,0x14d2 ,0xed41,0x35a5 ,
0x08df,0x289a ,0x26b3,0x1590 ,0xea02,0x36e5 ,
0x06a9,0x29ce ,0x25b1,0x164c ,0xe6cb,0x3812 ,
0x0471,0x2afb ,0x24ae,0x1709 ,0xe39c,0x392b ,
0x0239,0x2c21 ,0x23a9,0x17c4 ,0xe077,0x3a30 ,
0x0000,0x2d41 ,0x22a3,0x187e ,0xdd5d,0x3b21 ,
0xfdc7,0x2e5a ,0x219c,0x1937 ,0xda4f,0x3bfd ,
0xfb8f,0x2f6c ,0x2093,0x19ef ,0xd74e,0x3cc5 ,
0xf957,0x3076 ,0x1f89,0x1aa7 ,0xd45c,0x3d78 ,
0xf721,0x3179 ,0x1e7e,0x1b5d ,0xd178,0x3e15 ,
0xf4ec,0x3274 ,0x1d72,0x1c12 ,0xcea5,0x3e9d ,
0xf2b8,0x3368 ,0x1c64,0x1cc6 ,0xcbe2,0x3f0f ,
0xf087,0x3453 ,0x1b56,0x1d79 ,0xc932,0x3f6b ,
0xee58,0x3537 ,0x1a46,0x1e2b ,0xc695,0x3fb1 ,
0xec2b,0x3612 ,0x1935,0x1edc ,0xc40c,0x3fe1 ,
0xea02,0x36e5 ,0x1824,0x1f8c ,0xc197,0x3ffb ,
0xe7dc,0x37b0 ,0x1711,0x203a ,0xbf38,0x3fff ,
0xe5ba,0x3871 ,0x15fe,0x20e7 ,0xbcf0,0x3fec ,
0xe39c,0x392b ,0x14ea,0x2193 ,0xbabf,0x3fc4 ,
0xe182,0x39db ,0x13d5,0x223d ,0xb8a6,0x3f85 ,
0xdf6d,0x3a82 ,0x12bf,0x22e7 ,0xb6a5,0x3f30 ,
0xdd5d,0x3b21 ,0x11a8,0x238e ,0xb4be,0x3ec5 ,
0xdb52,0x3bb6 ,0x1091,0x2435 ,0xb2f2,0x3e45 ,
0xd94d,0x3c42 ,0x0f79,0x24da ,0xb140,0x3daf ,
0xd74e,0x3cc5 ,0x0e61,0x257e ,0xafa9,0x3d03 ,
0xd556,0x3d3f ,0x0d48,0x2620 ,0xae2e,0x3c42 ,
0xd363,0x3daf ,0x0c2e,0x26c1 ,0xacd0,0x3b6d ,
0xd178,0x3e15 ,0x0b14,0x2760 ,0xab8e,0x3a82 ,
0xcf94,0x3e72 ,0x09fa,0x27fe ,0xaa6a,0x3984 ,
0xcdb7,0x3ec5 ,0x08df,0x289a ,0xa963,0x3871 ,
0xcbe2,0x3f0f ,0x07c4,0x2935 ,0xa87b,0x374b ,
0xca15,0x3f4f ,0x06a9,0x29ce ,0xa7b1,0x3612 ,
0xc851,0x3f85 ,0x058d,0x2a65 ,0xa705,0x34c6 ,
0xc695,0x3fb1 ,0x0471,0x2afb ,0xa678,0x3368 ,
0xc4e2,0x3fd4 ,0x0355,0x2b8f ,0xa60b,0x31f8 ,
0xc338,0x3fec ,0x0239,0x2c21 ,0xa5bc,0x3076 ,
0xc197,0x3ffb ,0x011c,0x2cb2 ,0xa58d,0x2ee4 ,
0xc000,0x4000 ,0x0000,0x2d41 ,0xa57e,0x2d41 ,
0xbe73,0x3ffb ,0xfee4,0x2dcf ,0xa58d,0x2b8f ,
0xbcf0,0x3fec ,0xfdc7,0x2e5a ,0xa5bc,0x29ce ,
0xbb77,0x3fd4 ,0xfcab,0x2ee4 ,0xa60b,0x27fe ,
0xba09,0x3fb1 ,0xfb8f,0x2f6c ,0xa678,0x2620 ,
0xb8a6,0x3f85 ,0xfa73,0x2ff2 ,0xa705,0x2435 ,
0xb74d,0x3f4f ,0xf957,0x3076 ,0xa7b1,0x223d ,
0xb600,0x3f0f ,0xf83c,0x30f9 ,0xa87b,0x203a ,
0xb4be,0x3ec5 ,0xf721,0x3179 ,0xa963,0x1e2b ,
0xb388,0x3e72 ,0xf606,0x31f8 ,0xaa6a,0x1c12 ,
0xb25e,0x3e15 ,0xf4ec,0x3274 ,0xab8e,0x19ef ,
0xb140,0x3daf ,0xf3d2,0x32ef ,0xacd0,0x17c4 ,
0xb02d,0x3d3f ,0xf2b8,0x3368 ,0xae2e,0x1590 ,
0xaf28,0x3cc5 ,0xf19f,0x33df ,0xafa9,0x1354 ,
0xae2e,0x3c42 ,0xf087,0x3453 ,0xb140,0x1112 ,
0xad41,0x3bb6 ,0xef6f,0x34c6 ,0xb2f2,0x0eca ,
0xac61,0x3b21 ,0xee58,0x3537 ,0xb4be,0x0c7c ,
0xab8e,0x3a82 ,0xed41,0x35a5 ,0xb6a5,0x0a2b ,
0xaac8,0x39db ,0xec2b,0x3612 ,0xb8a6,0x07d6 ,
0xaa0f,0x392b ,0xeb16,0x367d ,0xbabf,0x057e ,
0xa963,0x3871 ,0xea02,0x36e5 ,0xbcf0,0x0324 ,
0xa8c5,0x37b0 ,0xe8ef,0x374b ,0xbf38,0x00c9 ,
0xa834,0x36e5 ,0xe7dc,0x37b0 ,0xc197,0xfe6e ,
0xa7b1,0x3612 ,0xe6cb,0x3812 ,0xc40c,0xfc13 ,
0xa73b,0x3537 ,0xe5ba,0x3871 ,0xc695,0xf9ba ,
0xa6d3,0x3453 ,0xe4aa,0x38cf ,0xc932,0xf763 ,
0xa678,0x3368 ,0xe39c,0x392b ,0xcbe2,0xf50f ,
0xa62c,0x3274 ,0xe28e,0x3984 ,0xcea5,0xf2bf ,
0xa5ed,0x3179 ,0xe182,0x39db ,0xd178,0xf073 ,
0xa5bc,0x3076 ,0xe077,0x3a30 ,0xd45c,0xee2d ,
0xa599,0x2f6c ,0xdf6d,0x3a82 ,0xd74e,0xebed ,
0xa585,0x2e5a ,0xde64,0x3ad3 ,0xda4f,0xe9b4 ,
0xa57e,0x2d41 ,0xdd5d,0x3b21 ,0xdd5d,0xe782 ,
0xa585,0x2c21 ,0xdc57,0x3b6d ,0xe077,0xe559 ,
0xa599,0x2afb ,0xdb52,0x3bb6 ,0xe39c,0xe33a ,
0xa5bc,0x29ce ,0xda4f,0x3bfd ,0xe6cb,0xe124 ,
0xa5ed,0x289a ,0xd94d,0x3c42 ,0xea02,0xdf19 ,
0xa62c,0x2760 ,0xd84d,0x3c85 ,0xed41,0xdd19 ,
0xa678,0x2620 ,0xd74e,0x3cc5 ,0xf087,0xdb26 ,
0xa6d3,0x24da ,0xd651,0x3d03 ,0xf3d2,0xd93f ,
0xa73b,0x238e ,0xd556,0x3d3f ,0xf721,0xd766 ,
0xa7b1,0x223d ,0xd45c,0x3d78 ,0xfa73,0xd59b ,
0xa834,0x20e7 ,0xd363,0x3daf ,0xfdc7,0xd3df ,
0xa8c5,0x1f8c ,0xd26d,0x3de3 ,0x011c,0xd231 ,
0xa963,0x1e2b ,0xd178,0x3e15 ,0x0471,0xd094 ,
0xaa0f,0x1cc6 ,0xd085,0x3e45 ,0x07c4,0xcf07 ,
0xaac8,0x1b5d ,0xcf94,0x3e72 ,0x0b14,0xcd8c ,
0xab8e,0x19ef ,0xcea5,0x3e9d ,0x0e61,0xcc21 ,
0xac61,0x187e ,0xcdb7,0x3ec5 ,0x11a8,0xcac9 ,
0xad41,0x1709 ,0xcccc,0x3eeb ,0x14ea,0xc983 ,
0xae2e,0x1590 ,0xcbe2,0x3f0f ,0x1824,0xc850 ,
0xaf28,0x1413 ,0xcafb,0x3f30 ,0x1b56,0xc731 ,
0xb02d,0x1294 ,0xca15,0x3f4f ,0x1e7e,0xc625 ,
0xb140,0x1112 ,0xc932,0x3f6b ,0x219c,0xc52d ,
0xb25e,0x0f8d ,0xc851,0x3f85 ,0x24ae,0xc44a ,
0xb388,0x0e06 ,0xc772,0x3f9c ,0x27b3,0xc37b ,
0xb4be,0x0c7c ,0xc695,0x3fb1 ,0x2aaa,0xc2c1 ,
0xb600,0x0af1 ,0xc5ba,0x3fc4 ,0x2d93,0xc21d ,
0xb74d,0x0964 ,0xc4e2,0x3fd4 ,0x306c,0xc18e ,
0xb8a6,0x07d6 ,0xc40c,0x3fe1 ,0x3334,0xc115 ,
0xba09,0x0646 ,0xc338,0x3fec ,0x35eb,0xc0b1 ,
0xbb77,0x04b5 ,0xc266,0x3ff5 ,0x388e,0xc064 ,
0xbcf0,0x0324 ,0xc197,0x3ffb ,0x3b1e,0xc02c ,
0xbe73,0x0192 ,0xc0ca,0x3fff ,0x3d9a,0xc00b ,
0x4000,0x0000 ,0x3f9b,0x0065 ,0x3f36,0x00c9 ,
0x3ed0,0x012e ,0x3e69,0x0192 ,0x3e02,0x01f7 ,
0x3d9a,0x025b ,0x3d31,0x02c0 ,0x3cc8,0x0324 ,
0x3c5f,0x0388 ,0x3bf4,0x03ed ,0x3b8a,0x0451 ,
0x3b1e,0x04b5 ,0x3ab2,0x051a ,0x3a46,0x057e ,
0x39d9,0x05e2 ,0x396b,0x0646 ,0x38fd,0x06aa ,
0x388e,0x070e ,0x381f,0x0772 ,0x37af,0x07d6 ,
0x373f,0x0839 ,0x36ce,0x089d ,0x365d,0x0901 ,
0x35eb,0x0964 ,0x3578,0x09c7 ,0x3505,0x0a2b ,
0x3492,0x0a8e ,0x341e,0x0af1 ,0x33a9,0x0b54 ,
0x3334,0x0bb7 ,0x32bf,0x0c1a ,0x3249,0x0c7c ,
0x31d2,0x0cdf ,0x315b,0x0d41 ,0x30e4,0x0da4 ,
0x306c,0x0e06 ,0x2ff4,0x0e68 ,0x2f7b,0x0eca ,
0x2f02,0x0f2b ,0x2e88,0x0f8d ,0x2e0e,0x0fee ,
0x2d93,0x1050 ,0x2d18,0x10b1 ,0x2c9d,0x1112 ,
0x2c21,0x1173 ,0x2ba4,0x11d3 ,0x2b28,0x1234 ,
0x2aaa,0x1294 ,0x2a2d,0x12f4 ,0x29af,0x1354 ,
0x2931,0x13b4 ,0x28b2,0x1413 ,0x2833,0x1473 ,
0x27b3,0x14d2 ,0x2733,0x1531 ,0x26b3,0x1590 ,
0x2632,0x15ee ,0x25b1,0x164c ,0x252f,0x16ab ,
0x24ae,0x1709 ,0x242b,0x1766 ,0x23a9,0x17c4 ,
0x2326,0x1821 ,0x22a3,0x187e ,0x221f,0x18db ,
0x219c,0x1937 ,0x2117,0x1993 ,0x2093,0x19ef ,
0x200e,0x1a4b ,0x1f89,0x1aa7 ,0x1f04,0x1b02 ,
0x1e7e,0x1b5d ,0x1df8,0x1bb8 ,0x1d72,0x1c12 ,
0x1ceb,0x1c6c ,0x1c64,0x1cc6 ,0x1bdd,0x1d20 ,
0x1b56,0x1d79 ,0x1ace,0x1dd3 ,0x1a46,0x1e2b ,
0x19be,0x1e84 ,0x1935,0x1edc ,0x18ad,0x1f34 ,
0x1824,0x1f8c ,0x179b,0x1fe3 ,0x1711,0x203a ,
0x1688,0x2091 ,0x15fe,0x20e7 ,0x1574,0x213d ,
0x14ea,0x2193 ,0x145f,0x21e8 ,0x13d5,0x223d ,
0x134a,0x2292 ,0x12bf,0x22e7 ,0x1234,0x233b ,
0x11a8,0x238e ,0x111d,0x23e2 ,0x1091,0x2435 ,
0x1005,0x2488 ,0x0f79,0x24da ,0x0eed,0x252c ,
0x0e61,0x257e ,0x0dd4,0x25cf ,0x0d48,0x2620 ,
0x0cbb,0x2671 ,0x0c2e,0x26c1 ,0x0ba1,0x2711 ,
0x0b14,0x2760 ,0x0a87,0x27af ,0x09fa,0x27fe ,
0x096d,0x284c ,0x08df,0x289a ,0x0852,0x28e7 ,
0x07c4,0x2935 ,0x0736,0x2981 ,0x06a9,0x29ce ,
0x061b,0x2a1a ,0x058d,0x2a65 ,0x04ff,0x2ab0 ,
0x0471,0x2afb ,0x03e3,0x2b45 ,0x0355,0x2b8f ,
0x02c7,0x2bd8 ,0x0239,0x2c21 ,0x01aa,0x2c6a ,
0x011c,0x2cb2 ,0x008e,0x2cfa ,0x0000,0x2d41 ,
0xff72,0x2d88 ,0xfee4,0x2dcf ,0xfe56,0x2e15 ,
0xfdc7,0x2e5a ,0xfd39,0x2e9f ,0xfcab,0x2ee4 ,
0xfc1d,0x2f28 ,0xfb8f,0x2f6c ,0xfb01,0x2faf ,
0xfa73,0x2ff2 ,0xf9e5,0x3034 ,0xf957,0x3076 ,
0xf8ca,0x30b8 ,0xf83c,0x30f9 ,0xf7ae,0x3139 ,
0xf721,0x3179 ,0xf693,0x31b9 ,0xf606,0x31f8 ,
0xf579,0x3236 ,0xf4ec,0x3274 ,0xf45f,0x32b2 ,
0xf3d2,0x32ef ,0xf345,0x332c ,0xf2b8,0x3368 ,
0xf22c,0x33a3 ,0xf19f,0x33df ,0xf113,0x3419 ,
0xf087,0x3453 ,0xeffb,0x348d ,0xef6f,0x34c6 ,
0xeee3,0x34ff ,0xee58,0x3537 ,0xedcc,0x356e ,
0xed41,0x35a5 ,0xecb6,0x35dc ,0xec2b,0x3612 ,
0xeba1,0x3648 ,0xeb16,0x367d ,0xea8c,0x36b1 ,
0xea02,0x36e5 ,0xe978,0x3718 ,0xe8ef,0x374b ,
0xe865,0x377e ,0xe7dc,0x37b0 ,0xe753,0x37e1 ,
0xe6cb,0x3812 ,0xe642,0x3842 ,0xe5ba,0x3871 ,
0xe532,0x38a1 ,0xe4aa,0x38cf ,0xe423,0x38fd ,
0xe39c,0x392b ,0xe315,0x3958 ,0xe28e,0x3984 ,
0xe208,0x39b0 ,0xe182,0x39db ,0xe0fc,0x3a06 ,
0xe077,0x3a30 ,0xdff2,0x3a59 ,0xdf6d,0x3a82 ,
0xdee9,0x3aab ,0xde64,0x3ad3 ,0xdde1,0x3afa ,
0xdd5d,0x3b21 ,0xdcda,0x3b47 ,0xdc57,0x3b6d ,
0xdbd5,0x3b92 ,0xdb52,0x3bb6 ,0xdad1,0x3bda ,
0xda4f,0x3bfd ,0xd9ce,0x3c20 ,0xd94d,0x3c42 ,
0xd8cd,0x3c64 ,0xd84d,0x3c85 ,0xd7cd,0x3ca5 ,
0xd74e,0x3cc5 ,0xd6cf,0x3ce4 ,0xd651,0x3d03 ,
0xd5d3,0x3d21 ,0xd556,0x3d3f ,0xd4d8,0x3d5b ,
0xd45c,0x3d78 ,0xd3df,0x3d93 ,0xd363,0x3daf ,
0xd2e8,0x3dc9 ,0xd26d,0x3de3 ,0xd1f2,0x3dfc ,
0xd178,0x3e15 ,0xd0fe,0x3e2d ,0xd085,0x3e45 ,
0xd00c,0x3e5c ,0xcf94,0x3e72 ,0xcf1c,0x3e88 ,
0xcea5,0x3e9d ,0xce2e,0x3eb1 ,0xcdb7,0x3ec5 ,
0xcd41,0x3ed8 ,0xcccc,0x3eeb ,0xcc57,0x3efd ,
0xcbe2,0x3f0f ,0xcb6e,0x3f20 ,0xcafb,0x3f30 ,
0xca88,0x3f40 ,0xca15,0x3f4f ,0xc9a3,0x3f5d ,
0xc932,0x3f6b ,0xc8c1,0x3f78 ,0xc851,0x3f85 ,
0xc7e1,0x3f91 ,0xc772,0x3f9c ,0xc703,0x3fa7 ,
0xc695,0x3fb1 ,0xc627,0x3fbb ,0xc5ba,0x3fc4 ,
0xc54e,0x3fcc ,0xc4e2,0x3fd4 ,0xc476,0x3fdb ,
0xc40c,0x3fe1 ,0xc3a1,0x3fe7 ,0xc338,0x3fec ,
0xc2cf,0x3ff1 ,0xc266,0x3ff5 ,0xc1fe,0x3ff8 ,
0xc197,0x3ffb ,0xc130,0x3ffd ,0xc0ca,0x3fff ,
0xc065,0x4000 ,0xc000,0x4000 ,0xbf9c,0x4000 ,
0xbf38,0x3fff ,0xbed5,0x3ffd ,0xbe73,0x3ffb ,
0xbe11,0x3ff8 ,0xbdb0,0x3ff5 ,0xbd50,0x3ff1 ,
0xbcf0,0x3fec ,0xbc91,0x3fe7 ,0xbc32,0x3fe1 ,
0xbbd4,0x3fdb ,0xbb77,0x3fd4 ,0xbb1b,0x3fcc ,
0xbabf,0x3fc4 ,0xba64,0x3fbb ,0xba09,0x3fb1 ,
0xb9af,0x3fa7 ,0xb956,0x3f9c ,0xb8fd,0x3f91 ,
0xb8a6,0x3f85 ,0xb84f,0x3f78 ,0xb7f8,0x3f6b ,
0xb7a2,0x3f5d ,0xb74d,0x3f4f ,0xb6f9,0x3f40 ,
0xb6a5,0x3f30 ,0xb652,0x3f20 ,0xb600,0x3f0f ,
0xb5af,0x3efd ,0xb55e,0x3eeb ,0xb50e,0x3ed8 ,
0xb4be,0x3ec5 ,0xb470,0x3eb1 ,0xb422,0x3e9d ,
0xb3d5,0x3e88 ,0xb388,0x3e72 ,0xb33d,0x3e5c ,
0xb2f2,0x3e45 ,0xb2a7,0x3e2d ,0xb25e,0x3e15 ,
0xb215,0x3dfc ,0xb1cd,0x3de3 ,0xb186,0x3dc9 ,
0xb140,0x3daf ,0xb0fa,0x3d93 ,0xb0b5,0x3d78 ,
0xb071,0x3d5b ,0xb02d,0x3d3f ,0xafeb,0x3d21 ,
0xafa9,0x3d03 ,0xaf68,0x3ce4 ,0xaf28,0x3cc5 ,
0xaee8,0x3ca5 ,0xaea9,0x3c85 ,0xae6b,0x3c64 ,
0xae2e,0x3c42 ,0xadf2,0x3c20 ,0xadb6,0x3bfd ,
0xad7b,0x3bda ,0xad41,0x3bb6 ,0xad08,0x3b92 ,
0xacd0,0x3b6d ,0xac98,0x3b47 ,0xac61,0x3b21 ,
0xac2b,0x3afa ,0xabf6,0x3ad3 ,0xabc2,0x3aab ,
0xab8e,0x3a82 ,0xab5b,0x3a59 ,0xab29,0x3a30 ,
0xaaf8,0x3a06 ,0xaac8,0x39db ,0xaa98,0x39b0 ,
0xaa6a,0x3984 ,0xaa3c,0x3958 ,0xaa0f,0x392b ,
0xa9e3,0x38fd ,0xa9b7,0x38cf ,0xa98d,0x38a1 ,
0xa963,0x3871 ,0xa93a,0x3842 ,0xa912,0x3812 ,
0xa8eb,0x37e1 ,0xa8c5,0x37b0 ,0xa89f,0x377e ,
0xa87b,0x374b ,0xa857,0x3718 ,0xa834,0x36e5 ,
0xa812,0x36b1 ,0xa7f1,0x367d ,0xa7d0,0x3648 ,
0xa7b1,0x3612 ,0xa792,0x35dc ,0xa774,0x35a5 ,
0xa757,0x356e ,0xa73b,0x3537 ,0xa71f,0x34ff ,
0xa705,0x34c6 ,0xa6eb,0x348d ,0xa6d3,0x3453 ,
0xa6bb,0x3419 ,0xa6a4,0x33df ,0xa68e,0x33a3 ,
0xa678,0x3368 ,0xa664,0x332c ,0xa650,0x32ef ,
0xa63e,0x32b2 ,0xa62c,0x3274 ,0xa61b,0x3236 ,
0xa60b,0x31f8 ,0xa5fb,0x31b9 ,0xa5ed,0x3179 ,
0xa5e0,0x3139 ,0xa5d3,0x30f9 ,0xa5c7,0x30b8 ,
0xa5bc,0x3076 ,0xa5b2,0x3034 ,0xa5a9,0x2ff2 ,
0xa5a1,0x2faf ,0xa599,0x2f6c ,0xa593,0x2f28 ,
0xa58d,0x2ee4 ,0xa588,0x2e9f ,0xa585,0x2e5a ,
0xa581,0x2e15 ,0xa57f,0x2dcf ,0xa57e,0x2d88 ,
0xa57e,0x2d41 ,0xa57e,0x2cfa ,0xa57f,0x2cb2 ,
0xa581,0x2c6a ,0xa585,0x2c21 ,0xa588,0x2bd8 ,
0xa58d,0x2b8f ,0xa593,0x2b45 ,0xa599,0x2afb ,
0xa5a1,0x2ab0 ,0xa5a9,0x2a65 ,0xa5b2,0x2a1a ,
0xa5bc,0x29ce ,0xa5c7,0x2981 ,0xa5d3,0x2935 ,
0xa5e0,0x28e7 ,0xa5ed,0x289a ,0xa5fb,0x284c ,
0xa60b,0x27fe ,0xa61b,0x27af ,0xa62c,0x2760 ,
0xa63e,0x2711 ,0xa650,0x26c1 ,0xa664,0x2671 ,
0xa678,0x2620 ,0xa68e,0x25cf ,0xa6a4,0x257e ,
0xa6bb,0x252c ,0xa6d3,0x24da ,0xa6eb,0x2488 ,
0xa705,0x2435 ,0xa71f,0x23e2 ,0xa73b,0x238e ,
0xa757,0x233b ,0xa774,0x22e7 ,0xa792,0x2292 ,
0xa7b1,0x223d ,0xa7d0,0x21e8 ,0xa7f1,0x2193 ,
0xa812,0x213d ,0xa834,0x20e7 ,0xa857,0x2091 ,
0xa87b,0x203a ,0xa89f,0x1fe3 ,0xa8c5,0x1f8c ,
0xa8eb,0x1f34 ,0xa912,0x1edc ,0xa93a,0x1e84 ,
0xa963,0x1e2b ,0xa98d,0x1dd3 ,0xa9b7,0x1d79 ,
0xa9e3,0x1d20 ,0xaa0f,0x1cc6 ,0xaa3c,0x1c6c ,
0xaa6a,0x1c12 ,0xaa98,0x1bb8 ,0xaac8,0x1b5d ,
0xaaf8,0x1b02 ,0xab29,0x1aa7 ,0xab5b,0x1a4b ,
0xab8e,0x19ef ,0xabc2,0x1993 ,0xabf6,0x1937 ,
0xac2b,0x18db ,0xac61,0x187e ,0xac98,0x1821 ,
0xacd0,0x17c4 ,0xad08,0x1766 ,0xad41,0x1709 ,
0xad7b,0x16ab ,0xadb6,0x164c ,0xadf2,0x15ee ,
0xae2e,0x1590 ,0xae6b,0x1531 ,0xaea9,0x14d2 ,
0xaee8,0x1473 ,0xaf28,0x1413 ,0xaf68,0x13b4 ,
0xafa9,0x1354 ,0xafeb,0x12f4 ,0xb02d,0x1294 ,
0xb071,0x1234 ,0xb0b5,0x11d3 ,0xb0fa,0x1173 ,
0xb140,0x1112 ,0xb186,0x10b1 ,0xb1cd,0x1050 ,
0xb215,0x0fee ,0xb25e,0x0f8d ,0xb2a7,0x0f2b ,
0xb2f2,0x0eca ,0xb33d,0x0e68 ,0xb388,0x0e06 ,
0xb3d5,0x0da4 ,0xb422,0x0d41 ,0xb470,0x0cdf ,
0xb4be,0x0c7c ,0xb50e,0x0c1a ,0xb55e,0x0bb7 ,
0xb5af,0x0b54 ,0xb600,0x0af1 ,0xb652,0x0a8e ,
0xb6a5,0x0a2b ,0xb6f9,0x09c7 ,0xb74d,0x0964 ,
0xb7a2,0x0901 ,0xb7f8,0x089d ,0xb84f,0x0839 ,
0xb8a6,0x07d6 ,0xb8fd,0x0772 ,0xb956,0x070e ,
0xb9af,0x06aa ,0xba09,0x0646 ,0xba64,0x05e2 ,
0xbabf,0x057e ,0xbb1b,0x051a ,0xbb77,0x04b5 ,
0xbbd4,0x0451 ,0xbc32,0x03ed ,0xbc91,0x0388 ,
0xbcf0,0x0324 ,0xbd50,0x02c0 ,0xbdb0,0x025b ,
0xbe11,0x01f7 ,0xbe73,0x0192 ,0xbed5,0x012e ,
0xbf38,0x00c9 ,0xbf9c,0x0065 };
extern const int s_Q14R_8;
const int s_Q14R_8 = 1024;
extern const unsigned short t_Q14R_8[2032];
const unsigned short t_Q14R_8[2032] = {
0x4000,0x0000 ,0x4000,0x0000 ,0x4000,0x0000 ,
0x3b21,0x187e ,0x3ec5,0x0c7c ,0x3537,0x238e ,
0x2d41,0x2d41 ,0x3b21,0x187e ,0x187e,0x3b21 ,
0x187e,0x3b21 ,0x3537,0x238e ,0xf384,0x3ec5 ,
0x0000,0x4000 ,0x2d41,0x2d41 ,0xd2bf,0x2d41 ,
0xe782,0x3b21 ,0x238e,0x3537 ,0xc13b,0x0c7c ,
0xd2bf,0x2d41 ,0x187e,0x3b21 ,0xc4df,0xe782 ,
0xc4df,0x187e ,0x0c7c,0x3ec5 ,0xdc72,0xcac9 ,
0x4000,0x0000 ,0x4000,0x0000 ,0x4000,0x0000 ,
0x3fb1,0x0646 ,0x3fec,0x0324 ,0x3f4f,0x0964 ,
0x3ec5,0x0c7c ,0x3fb1,0x0646 ,0x3d3f,0x1294 ,
0x3d3f,0x1294 ,0x3f4f,0x0964 ,0x39db,0x1b5d ,
0x3b21,0x187e ,0x3ec5,0x0c7c ,0x3537,0x238e ,
0x3871,0x1e2b ,0x3e15,0x0f8d ,0x2f6c,0x2afb ,
0x3537,0x238e ,0x3d3f,0x1294 ,0x289a,0x3179 ,
0x3179,0x289a ,0x3c42,0x1590 ,0x20e7,0x36e5 ,
0x2d41,0x2d41 ,0x3b21,0x187e ,0x187e,0x3b21 ,
0x289a,0x3179 ,0x39db,0x1b5d ,0x0f8d,0x3e15 ,
0x238e,0x3537 ,0x3871,0x1e2b ,0x0646,0x3fb1 ,
0x1e2b,0x3871 ,0x36e5,0x20e7 ,0xfcdc,0x3fec ,
0x187e,0x3b21 ,0x3537,0x238e ,0xf384,0x3ec5 ,
0x1294,0x3d3f ,0x3368,0x2620 ,0xea70,0x3c42 ,
0x0c7c,0x3ec5 ,0x3179,0x289a ,0xe1d5,0x3871 ,
0x0646,0x3fb1 ,0x2f6c,0x2afb ,0xd9e0,0x3368 ,
0x0000,0x4000 ,0x2d41,0x2d41 ,0xd2bf,0x2d41 ,
0xf9ba,0x3fb1 ,0x2afb,0x2f6c ,0xcc98,0x2620 ,
0xf384,0x3ec5 ,0x289a,0x3179 ,0xc78f,0x1e2b ,
0xed6c,0x3d3f ,0x2620,0x3368 ,0xc3be,0x1590 ,
0xe782,0x3b21 ,0x238e,0x3537 ,0xc13b,0x0c7c ,
0xe1d5,0x3871 ,0x20e7,0x36e5 ,0xc014,0x0324 ,
0xdc72,0x3537 ,0x1e2b,0x3871 ,0xc04f,0xf9ba ,
0xd766,0x3179 ,0x1b5d,0x39db ,0xc1eb,0xf073 ,
0xd2bf,0x2d41 ,0x187e,0x3b21 ,0xc4df,0xe782 ,
0xce87,0x289a ,0x1590,0x3c42 ,0xc91b,0xdf19 ,
0xcac9,0x238e ,0x1294,0x3d3f ,0xce87,0xd766 ,
0xc78f,0x1e2b ,0x0f8d,0x3e15 ,0xd505,0xd094 ,
0xc4df,0x187e ,0x0c7c,0x3ec5 ,0xdc72,0xcac9 ,
0xc2c1,0x1294 ,0x0964,0x3f4f ,0xe4a3,0xc625 ,
0xc13b,0x0c7c ,0x0646,0x3fb1 ,0xed6c,0xc2c1 ,
0xc04f,0x0646 ,0x0324,0x3fec ,0xf69c,0xc0b1 ,
0x4000,0x0000 ,0x4000,0x0000 ,0x4000,0x0000 ,
0x3ffb,0x0192 ,0x3fff,0x00c9 ,0x3ff5,0x025b ,
0x3fec,0x0324 ,0x3ffb,0x0192 ,0x3fd4,0x04b5 ,
0x3fd4,0x04b5 ,0x3ff5,0x025b ,0x3f9c,0x070e ,
0x3fb1,0x0646 ,0x3fec,0x0324 ,0x3f4f,0x0964 ,
0x3f85,0x07d6 ,0x3fe1,0x03ed ,0x3eeb,0x0bb7 ,
0x3f4f,0x0964 ,0x3fd4,0x04b5 ,0x3e72,0x0e06 ,
0x3f0f,0x0af1 ,0x3fc4,0x057e ,0x3de3,0x1050 ,
0x3ec5,0x0c7c ,0x3fb1,0x0646 ,0x3d3f,0x1294 ,
0x3e72,0x0e06 ,0x3f9c,0x070e ,0x3c85,0x14d2 ,
0x3e15,0x0f8d ,0x3f85,0x07d6 ,0x3bb6,0x1709 ,
0x3daf,0x1112 ,0x3f6b,0x089d ,0x3ad3,0x1937 ,
0x3d3f,0x1294 ,0x3f4f,0x0964 ,0x39db,0x1b5d ,
0x3cc5,0x1413 ,0x3f30,0x0a2b ,0x38cf,0x1d79 ,
0x3c42,0x1590 ,0x3f0f,0x0af1 ,0x37b0,0x1f8c ,
0x3bb6,0x1709 ,0x3eeb,0x0bb7 ,0x367d,0x2193 ,
0x3b21,0x187e ,0x3ec5,0x0c7c ,0x3537,0x238e ,
0x3a82,0x19ef ,0x3e9d,0x0d41 ,0x33df,0x257e ,
0x39db,0x1b5d ,0x3e72,0x0e06 ,0x3274,0x2760 ,
0x392b,0x1cc6 ,0x3e45,0x0eca ,0x30f9,0x2935 ,
0x3871,0x1e2b ,0x3e15,0x0f8d ,0x2f6c,0x2afb ,
0x37b0,0x1f8c ,0x3de3,0x1050 ,0x2dcf,0x2cb2 ,
0x36e5,0x20e7 ,0x3daf,0x1112 ,0x2c21,0x2e5a ,
0x3612,0x223d ,0x3d78,0x11d3 ,0x2a65,0x2ff2 ,
0x3537,0x238e ,0x3d3f,0x1294 ,0x289a,0x3179 ,
0x3453,0x24da ,0x3d03,0x1354 ,0x26c1,0x32ef ,
0x3368,0x2620 ,0x3cc5,0x1413 ,0x24da,0x3453 ,
0x3274,0x2760 ,0x3c85,0x14d2 ,0x22e7,0x35a5 ,
0x3179,0x289a ,0x3c42,0x1590 ,0x20e7,0x36e5 ,
0x3076,0x29ce ,0x3bfd,0x164c ,0x1edc,0x3812 ,
0x2f6c,0x2afb ,0x3bb6,0x1709 ,0x1cc6,0x392b ,
0x2e5a,0x2c21 ,0x3b6d,0x17c4 ,0x1aa7,0x3a30 ,
0x2d41,0x2d41 ,0x3b21,0x187e ,0x187e,0x3b21 ,
0x2c21,0x2e5a ,0x3ad3,0x1937 ,0x164c,0x3bfd ,
0x2afb,0x2f6c ,0x3a82,0x19ef ,0x1413,0x3cc5 ,
0x29ce,0x3076 ,0x3a30,0x1aa7 ,0x11d3,0x3d78 ,
0x289a,0x3179 ,0x39db,0x1b5d ,0x0f8d,0x3e15 ,
0x2760,0x3274 ,0x3984,0x1c12 ,0x0d41,0x3e9d ,
0x2620,0x3368 ,0x392b,0x1cc6 ,0x0af1,0x3f0f ,
0x24da,0x3453 ,0x38cf,0x1d79 ,0x089d,0x3f6b ,
0x238e,0x3537 ,0x3871,0x1e2b ,0x0646,0x3fb1 ,
0x223d,0x3612 ,0x3812,0x1edc ,0x03ed,0x3fe1 ,
0x20e7,0x36e5 ,0x37b0,0x1f8c ,0x0192,0x3ffb ,
0x1f8c,0x37b0 ,0x374b,0x203a ,0xff37,0x3fff ,
0x1e2b,0x3871 ,0x36e5,0x20e7 ,0xfcdc,0x3fec ,
0x1cc6,0x392b ,0x367d,0x2193 ,0xfa82,0x3fc4 ,
0x1b5d,0x39db ,0x3612,0x223d ,0xf82a,0x3f85 ,
0x19ef,0x3a82 ,0x35a5,0x22e7 ,0xf5d5,0x3f30 ,
0x187e,0x3b21 ,0x3537,0x238e ,0xf384,0x3ec5 ,
0x1709,0x3bb6 ,0x34c6,0x2435 ,0xf136,0x3e45 ,
0x1590,0x3c42 ,0x3453,0x24da ,0xeeee,0x3daf ,
0x1413,0x3cc5 ,0x33df,0x257e ,0xecac,0x3d03 ,
0x1294,0x3d3f ,0x3368,0x2620 ,0xea70,0x3c42 ,
0x1112,0x3daf ,0x32ef,0x26c1 ,0xe83c,0x3b6d ,
0x0f8d,0x3e15 ,0x3274,0x2760 ,0xe611,0x3a82 ,
0x0e06,0x3e72 ,0x31f8,0x27fe ,0xe3ee,0x3984 ,
0x0c7c,0x3ec5 ,0x3179,0x289a ,0xe1d5,0x3871 ,
0x0af1,0x3f0f ,0x30f9,0x2935 ,0xdfc6,0x374b ,
0x0964,0x3f4f ,0x3076,0x29ce ,0xddc3,0x3612 ,
0x07d6,0x3f85 ,0x2ff2,0x2a65 ,0xdbcb,0x34c6 ,
0x0646,0x3fb1 ,0x2f6c,0x2afb ,0xd9e0,0x3368 ,
0x04b5,0x3fd4 ,0x2ee4,0x2b8f ,0xd802,0x31f8 ,
0x0324,0x3fec ,0x2e5a,0x2c21 ,0xd632,0x3076 ,
0x0192,0x3ffb ,0x2dcf,0x2cb2 ,0xd471,0x2ee4 ,
0x0000,0x4000 ,0x2d41,0x2d41 ,0xd2bf,0x2d41 ,
0xfe6e,0x3ffb ,0x2cb2,0x2dcf ,0xd11c,0x2b8f ,
0xfcdc,0x3fec ,0x2c21,0x2e5a ,0xcf8a,0x29ce ,
0xfb4b,0x3fd4 ,0x2b8f,0x2ee4 ,0xce08,0x27fe ,
0xf9ba,0x3fb1 ,0x2afb,0x2f6c ,0xcc98,0x2620 ,
0xf82a,0x3f85 ,0x2a65,0x2ff2 ,0xcb3a,0x2435 ,
0xf69c,0x3f4f ,0x29ce,0x3076 ,0xc9ee,0x223d ,
0xf50f,0x3f0f ,0x2935,0x30f9 ,0xc8b5,0x203a ,
0xf384,0x3ec5 ,0x289a,0x3179 ,0xc78f,0x1e2b ,
0xf1fa,0x3e72 ,0x27fe,0x31f8 ,0xc67c,0x1c12 ,
0xf073,0x3e15 ,0x2760,0x3274 ,0xc57e,0x19ef ,
0xeeee,0x3daf ,0x26c1,0x32ef ,0xc493,0x17c4 ,
0xed6c,0x3d3f ,0x2620,0x3368 ,0xc3be,0x1590 ,
0xebed,0x3cc5 ,0x257e,0x33df ,0xc2fd,0x1354 ,
0xea70,0x3c42 ,0x24da,0x3453 ,0xc251,0x1112 ,
0xe8f7,0x3bb6 ,0x2435,0x34c6 ,0xc1bb,0x0eca ,
0xe782,0x3b21 ,0x238e,0x3537 ,0xc13b,0x0c7c ,
0xe611,0x3a82 ,0x22e7,0x35a5 ,0xc0d0,0x0a2b ,
0xe4a3,0x39db ,0x223d,0x3612 ,0xc07b,0x07d6 ,
0xe33a,0x392b ,0x2193,0x367d ,0xc03c,0x057e ,
0xe1d5,0x3871 ,0x20e7,0x36e5 ,0xc014,0x0324 ,
0xe074,0x37b0 ,0x203a,0x374b ,0xc001,0x00c9 ,
0xdf19,0x36e5 ,0x1f8c,0x37b0 ,0xc005,0xfe6e ,
0xddc3,0x3612 ,0x1edc,0x3812 ,0xc01f,0xfc13 ,
0xdc72,0x3537 ,0x1e2b,0x3871 ,0xc04f,0xf9ba ,
0xdb26,0x3453 ,0x1d79,0x38cf ,0xc095,0xf763 ,
0xd9e0,0x3368 ,0x1cc6,0x392b ,0xc0f1,0xf50f ,
0xd8a0,0x3274 ,0x1c12,0x3984 ,0xc163,0xf2bf ,
0xd766,0x3179 ,0x1b5d,0x39db ,0xc1eb,0xf073 ,
0xd632,0x3076 ,0x1aa7,0x3a30 ,0xc288,0xee2d ,
0xd505,0x2f6c ,0x19ef,0x3a82 ,0xc33b,0xebed ,
0xd3df,0x2e5a ,0x1937,0x3ad3 ,0xc403,0xe9b4 ,
0xd2bf,0x2d41 ,0x187e,0x3b21 ,0xc4df,0xe782 ,
0xd1a6,0x2c21 ,0x17c4,0x3b6d ,0xc5d0,0xe559 ,
0xd094,0x2afb ,0x1709,0x3bb6 ,0xc6d5,0xe33a ,
0xcf8a,0x29ce ,0x164c,0x3bfd ,0xc7ee,0xe124 ,
0xce87,0x289a ,0x1590,0x3c42 ,0xc91b,0xdf19 ,
0xcd8c,0x2760 ,0x14d2,0x3c85 ,0xca5b,0xdd19 ,
0xcc98,0x2620 ,0x1413,0x3cc5 ,0xcbad,0xdb26 ,
0xcbad,0x24da ,0x1354,0x3d03 ,0xcd11,0xd93f ,
0xcac9,0x238e ,0x1294,0x3d3f ,0xce87,0xd766 ,
0xc9ee,0x223d ,0x11d3,0x3d78 ,0xd00e,0xd59b ,
0xc91b,0x20e7 ,0x1112,0x3daf ,0xd1a6,0xd3df ,
0xc850,0x1f8c ,0x1050,0x3de3 ,0xd34e,0xd231 ,
0xc78f,0x1e2b ,0x0f8d,0x3e15 ,0xd505,0xd094 ,
0xc6d5,0x1cc6 ,0x0eca,0x3e45 ,0xd6cb,0xcf07 ,
0xc625,0x1b5d ,0x0e06,0x3e72 ,0xd8a0,0xcd8c ,
0xc57e,0x19ef ,0x0d41,0x3e9d ,0xda82,0xcc21 ,
0xc4df,0x187e ,0x0c7c,0x3ec5 ,0xdc72,0xcac9 ,
0xc44a,0x1709 ,0x0bb7,0x3eeb ,0xde6d,0xc983 ,
0xc3be,0x1590 ,0x0af1,0x3f0f ,0xe074,0xc850 ,
0xc33b,0x1413 ,0x0a2b,0x3f30 ,0xe287,0xc731 ,
0xc2c1,0x1294 ,0x0964,0x3f4f ,0xe4a3,0xc625 ,
0xc251,0x1112 ,0x089d,0x3f6b ,0xe6c9,0xc52d ,
0xc1eb,0x0f8d ,0x07d6,0x3f85 ,0xe8f7,0xc44a ,
0xc18e,0x0e06 ,0x070e,0x3f9c ,0xeb2e,0xc37b ,
0xc13b,0x0c7c ,0x0646,0x3fb1 ,0xed6c,0xc2c1 ,
0xc0f1,0x0af1 ,0x057e,0x3fc4 ,0xefb0,0xc21d ,
0xc0b1,0x0964 ,0x04b5,0x3fd4 ,0xf1fa,0xc18e ,
0xc07b,0x07d6 ,0x03ed,0x3fe1 ,0xf449,0xc115 ,
0xc04f,0x0646 ,0x0324,0x3fec ,0xf69c,0xc0b1 ,
0xc02c,0x04b5 ,0x025b,0x3ff5 ,0xf8f2,0xc064 ,
0xc014,0x0324 ,0x0192,0x3ffb ,0xfb4b,0xc02c ,
0xc005,0x0192 ,0x00c9,0x3fff ,0xfda5,0xc00b ,
0x4000,0x0000 ,0x4000,0x0065 ,0x3fff,0x00c9 ,
0x3ffd,0x012e ,0x3ffb,0x0192 ,0x3ff8,0x01f7 ,
0x3ff5,0x025b ,0x3ff1,0x02c0 ,0x3fec,0x0324 ,
0x3fe7,0x0388 ,0x3fe1,0x03ed ,0x3fdb,0x0451 ,
0x3fd4,0x04b5 ,0x3fcc,0x051a ,0x3fc4,0x057e ,
0x3fbb,0x05e2 ,0x3fb1,0x0646 ,0x3fa7,0x06aa ,
0x3f9c,0x070e ,0x3f91,0x0772 ,0x3f85,0x07d6 ,
0x3f78,0x0839 ,0x3f6b,0x089d ,0x3f5d,0x0901 ,
0x3f4f,0x0964 ,0x3f40,0x09c7 ,0x3f30,0x0a2b ,
0x3f20,0x0a8e ,0x3f0f,0x0af1 ,0x3efd,0x0b54 ,
0x3eeb,0x0bb7 ,0x3ed8,0x0c1a ,0x3ec5,0x0c7c ,
0x3eb1,0x0cdf ,0x3e9d,0x0d41 ,0x3e88,0x0da4 ,
0x3e72,0x0e06 ,0x3e5c,0x0e68 ,0x3e45,0x0eca ,
0x3e2d,0x0f2b ,0x3e15,0x0f8d ,0x3dfc,0x0fee ,
0x3de3,0x1050 ,0x3dc9,0x10b1 ,0x3daf,0x1112 ,
0x3d93,0x1173 ,0x3d78,0x11d3 ,0x3d5b,0x1234 ,
0x3d3f,0x1294 ,0x3d21,0x12f4 ,0x3d03,0x1354 ,
0x3ce4,0x13b4 ,0x3cc5,0x1413 ,0x3ca5,0x1473 ,
0x3c85,0x14d2 ,0x3c64,0x1531 ,0x3c42,0x1590 ,
0x3c20,0x15ee ,0x3bfd,0x164c ,0x3bda,0x16ab ,
0x3bb6,0x1709 ,0x3b92,0x1766 ,0x3b6d,0x17c4 ,
0x3b47,0x1821 ,0x3b21,0x187e ,0x3afa,0x18db ,
0x3ad3,0x1937 ,0x3aab,0x1993 ,0x3a82,0x19ef ,
0x3a59,0x1a4b ,0x3a30,0x1aa7 ,0x3a06,0x1b02 ,
0x39db,0x1b5d ,0x39b0,0x1bb8 ,0x3984,0x1c12 ,
0x3958,0x1c6c ,0x392b,0x1cc6 ,0x38fd,0x1d20 ,
0x38cf,0x1d79 ,0x38a1,0x1dd3 ,0x3871,0x1e2b ,
0x3842,0x1e84 ,0x3812,0x1edc ,0x37e1,0x1f34 ,
0x37b0,0x1f8c ,0x377e,0x1fe3 ,0x374b,0x203a ,
0x3718,0x2091 ,0x36e5,0x20e7 ,0x36b1,0x213d ,
0x367d,0x2193 ,0x3648,0x21e8 ,0x3612,0x223d ,
0x35dc,0x2292 ,0x35a5,0x22e7 ,0x356e,0x233b ,
0x3537,0x238e ,0x34ff,0x23e2 ,0x34c6,0x2435 ,
0x348d,0x2488 ,0x3453,0x24da ,0x3419,0x252c ,
0x33df,0x257e ,0x33a3,0x25cf ,0x3368,0x2620 ,
0x332c,0x2671 ,0x32ef,0x26c1 ,0x32b2,0x2711 ,
0x3274,0x2760 ,0x3236,0x27af ,0x31f8,0x27fe ,
0x31b9,0x284c ,0x3179,0x289a ,0x3139,0x28e7 ,
0x30f9,0x2935 ,0x30b8,0x2981 ,0x3076,0x29ce ,
0x3034,0x2a1a ,0x2ff2,0x2a65 ,0x2faf,0x2ab0 ,
0x2f6c,0x2afb ,0x2f28,0x2b45 ,0x2ee4,0x2b8f ,
0x2e9f,0x2bd8 ,0x2e5a,0x2c21 ,0x2e15,0x2c6a ,
0x2dcf,0x2cb2 ,0x2d88,0x2cfa ,0x2d41,0x2d41 ,
0x2cfa,0x2d88 ,0x2cb2,0x2dcf ,0x2c6a,0x2e15 ,
0x2c21,0x2e5a ,0x2bd8,0x2e9f ,0x2b8f,0x2ee4 ,
0x2b45,0x2f28 ,0x2afb,0x2f6c ,0x2ab0,0x2faf ,
0x2a65,0x2ff2 ,0x2a1a,0x3034 ,0x29ce,0x3076 ,
0x2981,0x30b8 ,0x2935,0x30f9 ,0x28e7,0x3139 ,
0x289a,0x3179 ,0x284c,0x31b9 ,0x27fe,0x31f8 ,
0x27af,0x3236 ,0x2760,0x3274 ,0x2711,0x32b2 ,
0x26c1,0x32ef ,0x2671,0x332c ,0x2620,0x3368 ,
0x25cf,0x33a3 ,0x257e,0x33df ,0x252c,0x3419 ,
0x24da,0x3453 ,0x2488,0x348d ,0x2435,0x34c6 ,
0x23e2,0x34ff ,0x238e,0x3537 ,0x233b,0x356e ,
0x22e7,0x35a5 ,0x2292,0x35dc ,0x223d,0x3612 ,
0x21e8,0x3648 ,0x2193,0x367d ,0x213d,0x36b1 ,
0x20e7,0x36e5 ,0x2091,0x3718 ,0x203a,0x374b ,
0x1fe3,0x377e ,0x1f8c,0x37b0 ,0x1f34,0x37e1 ,
0x1edc,0x3812 ,0x1e84,0x3842 ,0x1e2b,0x3871 ,
0x1dd3,0x38a1 ,0x1d79,0x38cf ,0x1d20,0x38fd ,
0x1cc6,0x392b ,0x1c6c,0x3958 ,0x1c12,0x3984 ,
0x1bb8,0x39b0 ,0x1b5d,0x39db ,0x1b02,0x3a06 ,
0x1aa7,0x3a30 ,0x1a4b,0x3a59 ,0x19ef,0x3a82 ,
0x1993,0x3aab ,0x1937,0x3ad3 ,0x18db,0x3afa ,
0x187e,0x3b21 ,0x1821,0x3b47 ,0x17c4,0x3b6d ,
0x1766,0x3b92 ,0x1709,0x3bb6 ,0x16ab,0x3bda ,
0x164c,0x3bfd ,0x15ee,0x3c20 ,0x1590,0x3c42 ,
0x1531,0x3c64 ,0x14d2,0x3c85 ,0x1473,0x3ca5 ,
0x1413,0x3cc5 ,0x13b4,0x3ce4 ,0x1354,0x3d03 ,
0x12f4,0x3d21 ,0x1294,0x3d3f ,0x1234,0x3d5b ,
0x11d3,0x3d78 ,0x1173,0x3d93 ,0x1112,0x3daf ,
0x10b1,0x3dc9 ,0x1050,0x3de3 ,0x0fee,0x3dfc ,
0x0f8d,0x3e15 ,0x0f2b,0x3e2d ,0x0eca,0x3e45 ,
0x0e68,0x3e5c ,0x0e06,0x3e72 ,0x0da4,0x3e88 ,
0x0d41,0x3e9d ,0x0cdf,0x3eb1 ,0x0c7c,0x3ec5 ,
0x0c1a,0x3ed8 ,0x0bb7,0x3eeb ,0x0b54,0x3efd ,
0x0af1,0x3f0f ,0x0a8e,0x3f20 ,0x0a2b,0x3f30 ,
0x09c7,0x3f40 ,0x0964,0x3f4f ,0x0901,0x3f5d ,
0x089d,0x3f6b ,0x0839,0x3f78 ,0x07d6,0x3f85 ,
0x0772,0x3f91 ,0x070e,0x3f9c ,0x06aa,0x3fa7 ,
0x0646,0x3fb1 ,0x05e2,0x3fbb ,0x057e,0x3fc4 ,
0x051a,0x3fcc ,0x04b5,0x3fd4 ,0x0451,0x3fdb ,
0x03ed,0x3fe1 ,0x0388,0x3fe7 ,0x0324,0x3fec ,
0x02c0,0x3ff1 ,0x025b,0x3ff5 ,0x01f7,0x3ff8 ,
0x0192,0x3ffb ,0x012e,0x3ffd ,0x00c9,0x3fff ,
0x0065,0x4000 ,0x0000,0x4000 ,0xff9b,0x4000 ,
0xff37,0x3fff ,0xfed2,0x3ffd ,0xfe6e,0x3ffb ,
0xfe09,0x3ff8 ,0xfda5,0x3ff5 ,0xfd40,0x3ff1 ,
0xfcdc,0x3fec ,0xfc78,0x3fe7 ,0xfc13,0x3fe1 ,
0xfbaf,0x3fdb ,0xfb4b,0x3fd4 ,0xfae6,0x3fcc ,
0xfa82,0x3fc4 ,0xfa1e,0x3fbb ,0xf9ba,0x3fb1 ,
0xf956,0x3fa7 ,0xf8f2,0x3f9c ,0xf88e,0x3f91 ,
0xf82a,0x3f85 ,0xf7c7,0x3f78 ,0xf763,0x3f6b ,
0xf6ff,0x3f5d ,0xf69c,0x3f4f ,0xf639,0x3f40 ,
0xf5d5,0x3f30 ,0xf572,0x3f20 ,0xf50f,0x3f0f ,
0xf4ac,0x3efd ,0xf449,0x3eeb ,0xf3e6,0x3ed8 ,
0xf384,0x3ec5 ,0xf321,0x3eb1 ,0xf2bf,0x3e9d ,
0xf25c,0x3e88 ,0xf1fa,0x3e72 ,0xf198,0x3e5c ,
0xf136,0x3e45 ,0xf0d5,0x3e2d ,0xf073,0x3e15 ,
0xf012,0x3dfc ,0xefb0,0x3de3 ,0xef4f,0x3dc9 ,
0xeeee,0x3daf ,0xee8d,0x3d93 ,0xee2d,0x3d78 ,
0xedcc,0x3d5b ,0xed6c,0x3d3f ,0xed0c,0x3d21 ,
0xecac,0x3d03 ,0xec4c,0x3ce4 ,0xebed,0x3cc5 ,
0xeb8d,0x3ca5 ,0xeb2e,0x3c85 ,0xeacf,0x3c64 ,
0xea70,0x3c42 ,0xea12,0x3c20 ,0xe9b4,0x3bfd ,
0xe955,0x3bda ,0xe8f7,0x3bb6 ,0xe89a,0x3b92 ,
0xe83c,0x3b6d ,0xe7df,0x3b47 ,0xe782,0x3b21 ,
0xe725,0x3afa ,0xe6c9,0x3ad3 ,0xe66d,0x3aab ,
0xe611,0x3a82 ,0xe5b5,0x3a59 ,0xe559,0x3a30 ,
0xe4fe,0x3a06 ,0xe4a3,0x39db ,0xe448,0x39b0 ,
0xe3ee,0x3984 ,0xe394,0x3958 ,0xe33a,0x392b ,
0xe2e0,0x38fd ,0xe287,0x38cf ,0xe22d,0x38a1 ,
0xe1d5,0x3871 ,0xe17c,0x3842 ,0xe124,0x3812 ,
0xe0cc,0x37e1 ,0xe074,0x37b0 ,0xe01d,0x377e ,
0xdfc6,0x374b ,0xdf6f,0x3718 ,0xdf19,0x36e5 ,
0xdec3,0x36b1 ,0xde6d,0x367d ,0xde18,0x3648 ,
0xddc3,0x3612 ,0xdd6e,0x35dc ,0xdd19,0x35a5 ,
0xdcc5,0x356e ,0xdc72,0x3537 ,0xdc1e,0x34ff ,
0xdbcb,0x34c6 ,0xdb78,0x348d ,0xdb26,0x3453 ,
0xdad4,0x3419 ,0xda82,0x33df ,0xda31,0x33a3 ,
0xd9e0,0x3368 ,0xd98f,0x332c ,0xd93f,0x32ef ,
0xd8ef,0x32b2 ,0xd8a0,0x3274 ,0xd851,0x3236 ,
0xd802,0x31f8 ,0xd7b4,0x31b9 ,0xd766,0x3179 ,
0xd719,0x3139 ,0xd6cb,0x30f9 ,0xd67f,0x30b8 ,
0xd632,0x3076 ,0xd5e6,0x3034 ,0xd59b,0x2ff2 ,
0xd550,0x2faf ,0xd505,0x2f6c ,0xd4bb,0x2f28 ,
0xd471,0x2ee4 ,0xd428,0x2e9f ,0xd3df,0x2e5a ,
0xd396,0x2e15 ,0xd34e,0x2dcf ,0xd306,0x2d88 ,
0xd2bf,0x2d41 ,0xd278,0x2cfa ,0xd231,0x2cb2 ,
0xd1eb,0x2c6a ,0xd1a6,0x2c21 ,0xd161,0x2bd8 ,
0xd11c,0x2b8f ,0xd0d8,0x2b45 ,0xd094,0x2afb ,
0xd051,0x2ab0 ,0xd00e,0x2a65 ,0xcfcc,0x2a1a ,
0xcf8a,0x29ce ,0xcf48,0x2981 ,0xcf07,0x2935 ,
0xcec7,0x28e7 ,0xce87,0x289a ,0xce47,0x284c ,
0xce08,0x27fe ,0xcdca,0x27af ,0xcd8c,0x2760 ,
0xcd4e,0x2711 ,0xcd11,0x26c1 ,0xccd4,0x2671 ,
0xcc98,0x2620 ,0xcc5d,0x25cf ,0xcc21,0x257e ,
0xcbe7,0x252c ,0xcbad,0x24da ,0xcb73,0x2488 ,
0xcb3a,0x2435 ,0xcb01,0x23e2 ,0xcac9,0x238e ,
0xca92,0x233b ,0xca5b,0x22e7 ,0xca24,0x2292 ,
0xc9ee,0x223d ,0xc9b8,0x21e8 ,0xc983,0x2193 ,
0xc94f,0x213d ,0xc91b,0x20e7 ,0xc8e8,0x2091 ,
0xc8b5,0x203a ,0xc882,0x1fe3 ,0xc850,0x1f8c ,
0xc81f,0x1f34 ,0xc7ee,0x1edc ,0xc7be,0x1e84 ,
0xc78f,0x1e2b ,0xc75f,0x1dd3 ,0xc731,0x1d79 ,
0xc703,0x1d20 ,0xc6d5,0x1cc6 ,0xc6a8,0x1c6c ,
0xc67c,0x1c12 ,0xc650,0x1bb8 ,0xc625,0x1b5d ,
0xc5fa,0x1b02 ,0xc5d0,0x1aa7 ,0xc5a7,0x1a4b ,
0xc57e,0x19ef ,0xc555,0x1993 ,0xc52d,0x1937 ,
0xc506,0x18db ,0xc4df,0x187e ,0xc4b9,0x1821 ,
0xc493,0x17c4 ,0xc46e,0x1766 ,0xc44a,0x1709 ,
0xc426,0x16ab ,0xc403,0x164c ,0xc3e0,0x15ee ,
0xc3be,0x1590 ,0xc39c,0x1531 ,0xc37b,0x14d2 ,
0xc35b,0x1473 ,0xc33b,0x1413 ,0xc31c,0x13b4 ,
0xc2fd,0x1354 ,0xc2df,0x12f4 ,0xc2c1,0x1294 ,
0xc2a5,0x1234 ,0xc288,0x11d3 ,0xc26d,0x1173 ,
0xc251,0x1112 ,0xc237,0x10b1 ,0xc21d,0x1050 ,
0xc204,0x0fee ,0xc1eb,0x0f8d ,0xc1d3,0x0f2b ,
0xc1bb,0x0eca ,0xc1a4,0x0e68 ,0xc18e,0x0e06 ,
0xc178,0x0da4 ,0xc163,0x0d41 ,0xc14f,0x0cdf ,
0xc13b,0x0c7c ,0xc128,0x0c1a ,0xc115,0x0bb7 ,
0xc103,0x0b54 ,0xc0f1,0x0af1 ,0xc0e0,0x0a8e ,
0xc0d0,0x0a2b ,0xc0c0,0x09c7 ,0xc0b1,0x0964 ,
0xc0a3,0x0901 ,0xc095,0x089d ,0xc088,0x0839 ,
0xc07b,0x07d6 ,0xc06f,0x0772 ,0xc064,0x070e ,
0xc059,0x06aa ,0xc04f,0x0646 ,0xc045,0x05e2 ,
0xc03c,0x057e ,0xc034,0x051a ,0xc02c,0x04b5 ,
0xc025,0x0451 ,0xc01f,0x03ed ,0xc019,0x0388 ,
0xc014,0x0324 ,0xc00f,0x02c0 ,0xc00b,0x025b ,
0xc008,0x01f7 ,0xc005,0x0192 ,0xc003,0x012e ,
0xc001,0x00c9 ,0xc000,0x0065 };

View File

@ -0,0 +1,19 @@
/*
* Copyright (C) ARM Limited 1998-2000. All rights reserved.
*
* t_rad.c
*
*/
extern const unsigned short t_Q14S_rad8[2];
const unsigned short t_Q14S_rad8[2] = { 0x0000,0x2d41 };
/*
extern const int t_Q30S_rad8[2];
const int t_Q30S_rad8[2] = { 0x00000000,0x2d413ccd };
*/
extern const unsigned short t_Q14R_rad8[2];
const unsigned short t_Q14R_rad8[2] = { 0x2d41,0x2d41 };
/*
extern const int t_Q30R_rad8[2];
const int t_Q30R_rad8[2] = { 0x2d413ccd,0x2d413ccd };
*/

View File

@ -0,0 +1,92 @@
/*
* 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.
*/
/*
* This file contains the function WebRtcSpl_FilterAR().
* The description header can be found in signal_processing_library.h
*
*/
#include "signal_processing_library.h"
int WebRtcSpl_FilterAR(G_CONST WebRtc_Word16* a,
int a_length,
G_CONST WebRtc_Word16* x,
int x_length,
WebRtc_Word16* state,
int state_length,
WebRtc_Word16* state_low,
int state_low_length,
WebRtc_Word16* filtered,
WebRtc_Word16* filtered_low,
int filtered_low_length)
{
WebRtc_Word32 o;
WebRtc_Word32 oLOW;
int i, j, stop;
G_CONST WebRtc_Word16* x_ptr = &x[0];
WebRtc_Word16* filteredFINAL_ptr = filtered;
WebRtc_Word16* filteredFINAL_LOW_ptr = filtered_low;
state_low_length = state_low_length;
filtered_low_length = filtered_low_length;
for (i = 0; i < x_length; i++)
{
// Calculate filtered[i] and filtered_low[i]
G_CONST WebRtc_Word16* a_ptr = &a[1];
WebRtc_Word16* filtered_ptr = &filtered[i - 1];
WebRtc_Word16* filtered_low_ptr = &filtered_low[i - 1];
WebRtc_Word16* state_ptr = &state[state_length - 1];
WebRtc_Word16* state_low_ptr = &state_low[state_length - 1];
o = (WebRtc_Word32)(*x_ptr++) << 12;
oLOW = (WebRtc_Word32)0;
stop = (i < a_length) ? i + 1 : a_length;
for (j = 1; j < stop; j++)
{
o -= WEBRTC_SPL_MUL_16_16(*a_ptr, *filtered_ptr--);
oLOW -= WEBRTC_SPL_MUL_16_16(*a_ptr++, *filtered_low_ptr--);
}
for (j = i + 1; j < a_length; j++)
{
o -= WEBRTC_SPL_MUL_16_16(*a_ptr, *state_ptr--);
oLOW -= WEBRTC_SPL_MUL_16_16(*a_ptr++, *state_low_ptr--);
}
o += (oLOW >> 12);
*filteredFINAL_ptr = (WebRtc_Word16)((o + (WebRtc_Word32)2048) >> 12);
*filteredFINAL_LOW_ptr++ = (WebRtc_Word16)(o - ((WebRtc_Word32)(*filteredFINAL_ptr++)
<< 12));
}
// Save the filter state
if (x_length >= state_length)
{
WebRtcSpl_CopyFromEndW16(filtered, x_length, a_length - 1, state);
WebRtcSpl_CopyFromEndW16(filtered_low, x_length, a_length - 1, state_low);
} else
{
for (i = 0; i < state_length - x_length; i++)
{
state[i] = state[i + x_length];
state_low[i] = state_low[i + x_length];
}
for (i = 0; i < x_length; i++)
{
state[state_length - x_length + i] = filtered[i];
state[state_length - x_length + i] = filtered_low[i];
}
}
return x_length;
}

View File

@ -0,0 +1,130 @@
/*
* filter_ar4.c
*
* This file contains the function WebRtcSpl_FilterAR4().
* The description header can be found in signal_processing_library.h
*
*/
#include "signal_processing_library.h"
#ifdef _DEBUG
#include <stdio.h>
#include <stdlib.h>
#endif
int WebRtcSpl_FilterAR4(G_CONST WebRtc_Word16 *a, int a_length, G_CONST WebRtc_Word16 *x,
int x_length, WebRtc_Word16 *state, int state_length,
WebRtc_Word16 *state_low, int state_low_length,
WebRtc_Word16 *filtered, int max_length, WebRtc_Word16 *filtered_low,
int filtered_low_length)
{
WebRtc_Word32 o;
WebRtc_Word32 oLOW;
int i;
int j;
int stop;
G_CONST WebRtc_Word16 *a_ptr;
WebRtc_Word16 *filtered_ptr;
WebRtc_Word16 *filtered_low_ptr;
WebRtc_Word16 *state_ptr;
WebRtc_Word16 *state_low_ptr;
G_CONST WebRtc_Word16 *x_ptr = &x[0];
WebRtc_Word16 *filteredFINAL_ptr = filtered;
WebRtc_Word16 *filteredFINAL_LOW_ptr = filtered_low;
#ifdef _DEBUG
if (max_length < x_length)
{
printf(" FilterAR4 : out vector is shorter than in vector\n");
exit(0);
}
if (state_length != a_length - 1)
{
printf(" FilterAR4 : state vector does not have the correct length\n");
exit(0);
}
#endif
/* Unused input variable */
max_length = max_length;
state_low_length = state_low_length;
filtered_low_length = filtered_low_length;
for (i = 0; i < 4; i++)
{
a_ptr = &a[1];
filtered_ptr = &filtered[i - 1];
filtered_low_ptr = &filtered_low[i - 1];
state_ptr = &state[state_length - 1];
state_low_ptr = &state_low[state_length - 1];
o = (WebRtc_Word32)(*x_ptr++) << 12; // Q12 operations
oLOW = (WebRtc_Word32)0;
stop = (i < a_length) ? i + 1 : a_length;
for (j = 1; j < stop; j++)
{
o -= WEBRTC_SPL_MUL_16_16(*a_ptr,*filtered_ptr--);
oLOW -= WEBRTC_SPL_MUL_16_16(*a_ptr++,*filtered_low_ptr--);
}
for (j = i + 1; j < a_length; j++)
{
o -= WEBRTC_SPL_MUL_16_16(*a_ptr,*state_ptr--);
oLOW -= WEBRTC_SPL_MUL_16_16(*a_ptr++,*state_low_ptr--);
}
o += (oLOW >> 12); // Q12 operations
*filteredFINAL_ptr = (WebRtc_Word16)((o + (WebRtc_Word32)2048) >> 12);// Q12 operations
*filteredFINAL_LOW_ptr++ = (WebRtc_Word16)(o - ((WebRtc_Word32)(*filteredFINAL_ptr++)
<< 12));
}
for (i = 4; i < x_length; i++)
{
/* Calculate filtered[0] */
a_ptr = &a[1];
filtered_ptr = &filtered[i - 1];
filtered_low_ptr = &filtered_low[i - 1];
o = (WebRtc_Word32)(*x_ptr++) << 12; // Q12 operations
oLOW = 0;
o -= WEBRTC_SPL_MUL_16_16(*a_ptr, *filtered_ptr--);
oLOW -= WEBRTC_SPL_MUL_16_16(*a_ptr++, *filtered_low_ptr--);
o -= WEBRTC_SPL_MUL_16_16(*a_ptr, *filtered_ptr--);
oLOW -= WEBRTC_SPL_MUL_16_16(*a_ptr++, *filtered_low_ptr--);
o -= WEBRTC_SPL_MUL_16_16(*a_ptr, *filtered_ptr--);
oLOW -= WEBRTC_SPL_MUL_16_16(*a_ptr++, *filtered_low_ptr--);
o -= WEBRTC_SPL_MUL_16_16(*a_ptr, *filtered_ptr--);
oLOW -= WEBRTC_SPL_MUL_16_16(*a_ptr++, *filtered_low_ptr--);
o += (oLOW >> 12); // Q12 operations
*filteredFINAL_ptr = (WebRtc_Word16)((o + (WebRtc_Word32)2048) >> 12);// Q12 operations
*filteredFINAL_LOW_ptr++ = (WebRtc_Word16)(o - ((WebRtc_Word32)(*filteredFINAL_ptr++)
<< 12));
}
if (x_length >= state_length)
{
WebRtcSpl_CopyFromEndW16(filtered, x_length, a_length - 1, state, state_length);
WebRtcSpl_CopyFromEndW16(filtered_low, x_length, a_length - 1, state_low, state_length);
} else
{
for (i = 0; i < state_length - x_length; i++)
{
state[i] = state[i + x_length];
state_low[i] = state_low[i + x_length];
}
for (i = 0; i < x_length; i++)
{
state[state_length - x_length + i] = filtered[i];
state[state_length - x_length + i] = filtered_low[i];
}
}
return x_length;
}

View File

@ -0,0 +1,49 @@
/*
* 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.
*/
/*
* This file contains the function WebRtcSpl_FilterARFastQ12().
* The description header can be found in signal_processing_library.h
*
*/
#include "signal_processing_library.h"
void WebRtcSpl_FilterARFastQ12(WebRtc_Word16 *in, WebRtc_Word16 *out, WebRtc_Word16 *A,
WebRtc_Word16 A_length, WebRtc_Word16 length)
{
WebRtc_Word32 o;
int i, j;
WebRtc_Word16 *x_ptr = &in[0];
WebRtc_Word16 *filtered_ptr = &out[0];
for (i = 0; i < length; i++)
{
// Calculate filtered[i]
G_CONST WebRtc_Word16 *a_ptr = &A[0];
WebRtc_Word16 *state_ptr = &out[i - 1];
o = WEBRTC_SPL_MUL_16_16(*x_ptr++, *a_ptr++);
for (j = 1; j < A_length; j++)
{
o -= WEBRTC_SPL_MUL_16_16(*a_ptr++,*state_ptr--);
}
// Saturate the output
o = WEBRTC_SPL_SAT((WebRtc_Word32)134215679, o, (WebRtc_Word32)-134217728);
*filtered_ptr++ = (WebRtc_Word16)((o + (WebRtc_Word32)2048) >> 12);
}
return;
}

View File

@ -0,0 +1,48 @@
/*
* filter_ar_sample_based.c
*
* This file contains the function WebRtcSpl_FilterARSampleBased().
* The description header can be found in signal_processing_library.h
*
*/
#include "signal_processing_library.h"
void WebRtcSpl_FilterARSampleBased(WebRtc_Word16 *InOut, WebRtc_Word16 *InOutLOW,
WebRtc_Word16 *Coef, WebRtc_Word16 orderCoef)
{
int k;
WebRtc_Word32 temp, tempLOW;
WebRtc_Word16 *ptrIn, *ptrInLOW, *ptrCoef;
temp = WEBRTC_SPL_LSHIFT_W32((WebRtc_Word32)*InOut, 12);
tempLOW = WEBRTC_SPL_LSHIFT_W32((WebRtc_Word32)*InOutLOW, 12);
// Filter integer part
ptrIn = InOut - 1;
ptrCoef = Coef + 1;
for (k = 0; k < orderCoef; k++)
{
temp -= WEBRTC_SPL_MUL_16_16((*ptrCoef), (*ptrIn));
ptrCoef++;
ptrIn--;
}
// Filter lower part (Q12)
ptrInLOW = InOutLOW - 1;
ptrCoef = Coef + 1;
for (k = 0; k < orderCoef; k++)
{
tempLOW -= WEBRTC_SPL_MUL_16_16((*ptrCoef), (*ptrInLOW));
ptrCoef++;
ptrInLOW--;
}
temp += WEBRTC_SPL_RSHIFT_W32(tempLOW, 12); // build WebRtc_Word32 result in Q12
// 2048 == (0.5 << 12) for rounding, InOut is in (Q0)
*InOut = (WebRtc_Word16)WEBRTC_SPL_RSHIFT_W32((temp+2048), 12);
// InOutLOW is in Q12
*InOutLOW = (WebRtc_Word16)(temp - (WEBRTC_SPL_LSHIFT_W32((WebRtc_Word32)(*InOut), 12)));
}

View File

@ -0,0 +1,68 @@
/*
* filter_ma.c
*
* This file contains the function WebRtcSpl_FilterMA().
* The description header can be found in signal_processing_library.h
*
*/
#include "signal_processing_library.h"
int WebRtcSpl_FilterMA(G_CONST WebRtc_Word16 *b, int b_length, G_CONST WebRtc_Word16 *x,
int x_length, WebRtc_Word16 *state, int state_length,
WebRtc_Word16 *filtered, int max_length)
{
WebRtc_Word32 o;
int i, j, stop;
WebRtc_Word16 *filtered_ptr = filtered;
/* Unused input variable */
max_length = max_length;
for (i = 0; i < x_length; i++)
{
G_CONST WebRtc_Word16 *b_ptr = &b[0];
G_CONST WebRtc_Word16 *x_ptr = &x[i];
WebRtc_Word16 *state_ptr = &state[state_length - 1];
o = (WebRtc_Word32)0;
stop = (i < b_length) ? i + 1 : b_length;
for (j = 0; j < stop; j++)
{
o += WEBRTC_SPL_MUL_16_16(*b_ptr++, *x_ptr--);
}
for (j = i + 1; j < b_length; j++)
{
o += WEBRTC_SPL_MUL_16_16(*b_ptr++, *state_ptr--);
}
/* If output is higher than 32768, saturate it. Same with negative side
2^27 = 134217728, which corresponds to 32768 in Q12 */
if (o < (WebRtc_Word32)-134217728)
o = (WebRtc_Word32)-134217728;
if (o > (WebRtc_Word32)(134217727 - 2048))
o = (WebRtc_Word32)(134217727 - 2048);
*filtered_ptr++ = (WebRtc_Word16)((o + (WebRtc_Word32)2048) >> 12);
}
/* Save filter state */
if (x_length >= state_length)
{
WebRtcSpl_CopyFromEndW16(x, x_length, b_length - 1, state, state_length);
} else
{
for (i = 0; i < state_length - x_length; i++)
{
state[i] = state[i + x_length];
}
for (i = 0; i < x_length; i++)
{
state[state_length - x_length + i] = x[i];
}
}
return x_length;
}

View File

@ -0,0 +1,120 @@
/*
* filter_ma4.c
*
* This file contains the function WebRtcSpl_FilterMA4().
* The description header can be found in signal_processing_library.h
*
*/
#include "signal_processing_library.h"
#ifdef _DEBUG
#include <stdio.h>
#include <stdlib.h>
#endif
int WebRtcSpl_FilterMA4(G_CONST WebRtc_Word16 *b, int b_length, G_CONST WebRtc_Word16 *x,
int x_length, WebRtc_Word16 *state, int state_length,
WebRtc_Word16 *filtered, int max_length)
{
WebRtc_Word32 o;
int i;
WebRtc_Word16 *filtered_ptr = filtered;
/* Calculate filtered[0] */G_CONST WebRtc_Word16 *b_ptr = &b[0];
G_CONST WebRtc_Word16 *x_ptr = &x[0];
WebRtc_Word16 *state_ptr = &state[state_length - 1];
/* Unused input variable */
max_length = max_length;
o = (WebRtc_Word32)0;
o += WEBRTC_SPL_MUL_16_16(*b_ptr++, *x_ptr--);
o += WEBRTC_SPL_MUL_16_16(*b_ptr++, *state_ptr--);
o += WEBRTC_SPL_MUL_16_16(*b_ptr++, *state_ptr--);
o += WEBRTC_SPL_MUL_16_16(*b_ptr++, *state_ptr--);
o += WEBRTC_SPL_MUL_16_16(*b_ptr++, *state_ptr--);
*filtered_ptr++ = (WebRtc_Word16)((o + (WebRtc_Word32)2048) >> 12); // Q12 operations
#ifdef _DEBUG
if (max_length < x_length)
{
printf("FilterMA4: out vector is shorter than in vector\n");
exit(0);
}
if ((state_length != 4) || (b_length != 5))
{
printf("FilterMA4: state or coefficient vector does not have the correct length\n");
exit(0);
}
#endif
/* Calculate filtered[1] */
b_ptr = &b[0];
x_ptr = &x[1];
state_ptr = &state[state_length - 1];
o = (WebRtc_Word32)0;
o += WEBRTC_SPL_MUL_16_16(*b_ptr++, *x_ptr--);
o += WEBRTC_SPL_MUL_16_16(*b_ptr++, *x_ptr--);
o += WEBRTC_SPL_MUL_16_16(*b_ptr++, *state_ptr--);
o += WEBRTC_SPL_MUL_16_16(*b_ptr++, *state_ptr--);
o += WEBRTC_SPL_MUL_16_16(*b_ptr++, *state_ptr--);
*filtered_ptr++ = (WebRtc_Word16)((o + (WebRtc_Word32)2048) >> 12); // Q12 operations
/* Calculate filtered[2] */
b_ptr = &b[0];
x_ptr = &x[2];
state_ptr = &state[state_length - 1];
o = (WebRtc_Word32)0;
o += WEBRTC_SPL_MUL_16_16(*b_ptr++, *x_ptr--);
o += WEBRTC_SPL_MUL_16_16(*b_ptr++, *x_ptr--);
o += WEBRTC_SPL_MUL_16_16(*b_ptr++, *x_ptr--);
o += WEBRTC_SPL_MUL_16_16(*b_ptr++, *state_ptr--);
o += WEBRTC_SPL_MUL_16_16(*b_ptr++, *state_ptr--);
*filtered_ptr++ = (WebRtc_Word16)((o + (WebRtc_Word32)2048) >> 12); // Q12 operations
/* Calculate filtered[3] */
b_ptr = &b[0];
x_ptr = &x[3];
state_ptr = &state[state_length - 1];
o = (WebRtc_Word32)0;
o += WEBRTC_SPL_MUL_16_16(*b_ptr++, *x_ptr--);
o += WEBRTC_SPL_MUL_16_16(*b_ptr++, *x_ptr--);
o += WEBRTC_SPL_MUL_16_16(*b_ptr++, *x_ptr--);
o += WEBRTC_SPL_MUL_16_16(*b_ptr++, *x_ptr--);
o += WEBRTC_SPL_MUL_16_16(*b_ptr++, *state_ptr--);
*filtered_ptr++ = (WebRtc_Word16)((o + (WebRtc_Word32)2048) >> 12); // Q12 operations
for (i = 4; i < x_length; i++)
{
o = (WebRtc_Word32)0;
b_ptr = &b[0];
x_ptr = &x[i];
o += WEBRTC_SPL_MUL_16_16(*b_ptr++, *x_ptr--);
o += WEBRTC_SPL_MUL_16_16(*b_ptr++, *x_ptr--);
o += WEBRTC_SPL_MUL_16_16(*b_ptr++, *x_ptr--);
o += WEBRTC_SPL_MUL_16_16(*b_ptr++, *x_ptr--);
o += WEBRTC_SPL_MUL_16_16(*b_ptr++, *x_ptr--);
*filtered_ptr++ = (WebRtc_Word16)((o + (WebRtc_Word32)2048) >> 12); // Q12 operations
}
if (x_length >= state_length)
{
WebRtcSpl_CopyFromEndW16(x, x_length, b_length - 1, state, state_length);
} else
{
for (i = 0; i < state_length - x_length; i++)
{
state[i] = state[i + x_length];
}
for (i = 0; i < x_length; i++)
{
state[state_length - x_length + i] = x[i];
}
}
return x_length;
}

View File

@ -0,0 +1,49 @@
/*
* 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.
*/
/*
* This file contains the function WebRtcSpl_FilterMAFastQ12().
* The description header can be found in signal_processing_library.h
*
*/
#include "signal_processing_library.h"
void WebRtcSpl_FilterMAFastQ12(WebRtc_Word16* in_ptr,
WebRtc_Word16* out_ptr,
WebRtc_Word16* B,
WebRtc_Word16 B_length,
WebRtc_Word16 length)
{
WebRtc_Word32 o;
int i, j;
for (i = 0; i < length; i++)
{
G_CONST WebRtc_Word16* b_ptr = &B[0];
G_CONST WebRtc_Word16* x_ptr = &in_ptr[i];
o = (WebRtc_Word32)0;
for (j = 0; j < B_length; j++)
{
o += WEBRTC_SPL_MUL_16_16(*b_ptr++, *x_ptr--);
}
// If output is higher than 32768, saturate it. Same with negative side
// 2^27 = 134217728, which corresponds to 32768 in Q12
// Saturate the output
o = WEBRTC_SPL_SAT((WebRtc_Word32)134215679, o, (WebRtc_Word32)-134217728);
*out_ptr++ = (WebRtc_Word16)((o + (WebRtc_Word32)2048) >> 12);
}
return;
}

View File

@ -0,0 +1,46 @@
/*
* get_column.c
*
* This file contains the function WebRtcSpl_GetColumn().
* The description header can be found in signal_processing_library.h
*
*/
#include "signal_processing_library.h"
#ifdef _DEBUG
#include <stdio.h>
#include <stdlib.h>
#endif
WebRtc_Word16 WebRtcSpl_GetColumn(G_CONST WebRtc_Word32 *matrix, WebRtc_Word16 number_of_rows,
WebRtc_Word16 number_of_cols, WebRtc_Word16 column_chosen,
WebRtc_Word32 *column_out, WebRtc_Word16 max_length)
{
WebRtc_Word16 i;
WebRtc_Word32 *outarrptr = column_out;
G_CONST WebRtc_Word32 *matptr = &matrix[column_chosen];
#ifdef _DEBUG
if (max_length < number_of_rows)
{
printf(" GetColumn : out vector is shorter than the column length\n");
exit(0);
}
if ((column_chosen < 0) || (column_chosen >= number_of_cols))
{
printf(" GetColumn : selected column is negative or larger than the dimension of the matrix\n");
exit(0);
}
#endif
/* Unused input variable */
max_length = max_length;
for (i = 0; i < number_of_rows; i++)
{
(*outarrptr++) = (*matptr);
matptr += number_of_cols;
}
return number_of_rows;
}

View File

@ -0,0 +1,41 @@
/*
* 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.
*/
/*
* This file contains the function WebRtcSpl_GetHanningWindow().
* The description header can be found in signal_processing_library.h
*
*/
#include "signal_processing_library.h"
void WebRtcSpl_GetHanningWindow(WebRtc_Word16 *v, WebRtc_Word16 size)
{
int jj;
WebRtc_Word16 *vptr1;
WebRtc_Word32 index;
WebRtc_Word32 factor = ((WebRtc_Word32)0x40000000);
factor = WebRtcSpl_DivW32W16(factor, size);
if (size < 513)
index = (WebRtc_Word32)-0x200000;
else
index = (WebRtc_Word32)-0x100000;
vptr1 = v;
for (jj = 0; jj < size; jj++)
{
index += factor;
(*vptr1++) = WebRtcSpl_kHanningTable[index >> 22];
}
}

View File

@ -0,0 +1,45 @@
/*
* get_rows.c
*
* This file contains the function WebRtcSpl_GetRow().
* The description header can be found in signal_processing_library.h
*
*/
#include "signal_processing_library.h"
#ifdef _DEBUG
#include <stdio.h>
#include <stdlib.h>
#endif
WebRtc_Word16 WebRtcSpl_GetRow(G_CONST WebRtc_Word32 *matrix, WebRtc_Word16 number_of_rows,
WebRtc_Word16 number_of_cols, WebRtc_Word16 row_chosen,
WebRtc_Word32 *row_out, WebRtc_Word16 max_length)
{
WebRtc_Word16 i;
WebRtc_Word32 *outarrptr = row_out;
G_CONST WebRtc_Word32 *matptr = &matrix[row_chosen * number_of_cols];
#ifdef _DEBUG
if (max_length < number_of_cols)
{
printf(" GetRow : out vector is shorter than the row length\n");
exit(0);
}
if ((row_chosen < 0) || (row_chosen >= number_of_rows))
{
printf(" GetRow : selected row is negative or larger than the dimension of the matrix\n");
exit(0);
}
#endif
/* Unused input variable */
max_length = max_length;
number_of_rows = number_of_rows;
for (i = 0; i < number_of_cols; i++)
{
(*outarrptr++) = (*matptr++);
}
return number_of_cols;
}

View File

@ -0,0 +1,46 @@
/*
* 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.
*/
/*
* This file contains the function WebRtcSpl_GetScaling().
* The description header can be found in signal_processing_library.h
*
*/
#include "signal_processing_library.h"
int WebRtcSpl_GetScaling(WebRtc_Word16 *in_vector, int in_vector_length, int times)
{
int nbits = WebRtcSpl_GetSizeInBits(times);
int i;
WebRtc_Word16 sabs;
int t;
WebRtc_Word16 *sptr = in_vector;
WebRtc_Word16 smax = *sptr++;
for (i = in_vector_length - 1; i > 0; i--)
{
sabs = WEBRTC_SPL_ABS_W16 (*sptr);
sptr++;
if (sabs > smax)
smax = sabs;
}
t = WebRtcSpl_NormW32((WebRtc_Word32)smax << 16);
if (smax == 0)
{
return 0; // Since norm(0) returns 0
} else
{
return (t > nbits) ? 0 : nbits - t;
}
}

View File

@ -0,0 +1,44 @@
/*
* 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.
*/
/*
* This file contains the function WebRtcSpl_GetScalingSquare().
* The description header can be found in signal_processing_library.h
*
*/
#include "signal_processing_library.h"
int WebRtcSpl_GetScalingSquare(WebRtc_Word16 *in_vector, int in_vector_length, int times)
{
int nbits = WebRtcSpl_GetSizeInBits(times);
int i;
WebRtc_Word16 smax = -1;
WebRtc_Word16 sabs;
WebRtc_Word16 *sptr = in_vector;
int t;
int looptimes = in_vector_length;
for (i = looptimes; i > 0; i--)
{
sabs = (*sptr > 0 ? *sptr++ : -*sptr++);
smax = (sabs > smax ? sabs : smax);
}
t = WebRtcSpl_NormW32(WEBRTC_SPL_MUL(smax, smax));
if (smax == 0)
{
return 0; // Since norm(0) returns 0
} else
{
return (t > nbits) ? 0 : nbits - t;
}
}

View File

@ -0,0 +1,44 @@
/*
* 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.
*/
/*
* This file contains the function WebRtcSpl_GetSizeInBits().
* The description header can be found in signal_processing_library.h
*
*/
#include "signal_processing_library.h"
#ifndef SPL_NO_DOUBLE_IMPLEMENTATIONS
WebRtc_Word16 WebRtcSpl_GetSizeInBits(WebRtc_UWord32 value)
{
int bits = 0;
// Fast binary search to find the number of bits used
if ((0xFFFF0000 & value))
bits = 16;
if ((0x0000FF00 & (value >> bits)))
bits += 8;
if ((0x000000F0 & (value >> bits)))
bits += 4;
if ((0x0000000C & (value >> bits)))
bits += 2;
if ((0x00000002 & (value >> bits)))
bits += 1;
if ((0x00000001 & (value >> bits)))
bits += 1;
return bits;
}
#endif

View File

@ -0,0 +1,53 @@
/*
* 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.
*/
/*
* This file contains the Hanning table with 256 entries.
*
*/
#include "signal_processing_library.h"
// Hanning table with 256 entries
WebRtc_Word16 WebRtcSpl_kHanningTable[] = {
1, 2, 6, 10, 15, 22, 30, 39,
50, 62, 75, 89, 104, 121, 138, 157,
178, 199, 222, 246, 271, 297, 324, 353,
383, 413, 446, 479, 513, 549, 586, 624,
663, 703, 744, 787, 830, 875, 920, 967,
1015, 1064, 1114, 1165, 1218, 1271, 1325, 1381,
1437, 1494, 1553, 1612, 1673, 1734, 1796, 1859,
1924, 1989, 2055, 2122, 2190, 2259, 2329, 2399,
2471, 2543, 2617, 2691, 2765, 2841, 2918, 2995,
3073, 3152, 3232, 3312, 3393, 3475, 3558, 3641,
3725, 3809, 3895, 3980, 4067, 4154, 4242, 4330,
4419, 4509, 4599, 4689, 4781, 4872, 4964, 5057,
5150, 5244, 5338, 5432, 5527, 5622, 5718, 5814,
5910, 6007, 6104, 6202, 6299, 6397, 6495, 6594,
6693, 6791, 6891, 6990, 7090, 7189, 7289, 7389,
7489, 7589, 7690, 7790, 7890, 7991, 8091, 8192,
8293, 8393, 8494, 8594, 8694, 8795, 8895, 8995,
9095, 9195, 9294, 9394, 9493, 9593, 9691, 9790,
9889, 9987, 10085, 10182, 10280, 10377, 10474, 10570,
10666, 10762, 10857, 10952, 11046, 11140, 11234, 11327,
11420, 11512, 11603, 11695, 11785, 11875, 11965, 12054,
12142, 12230, 12317, 12404, 12489, 12575, 12659, 12743,
12826, 12909, 12991, 13072, 13152, 13232, 13311, 13389,
13466, 13543, 13619, 13693, 13767, 13841, 13913, 13985,
14055, 14125, 14194, 14262, 14329, 14395, 14460, 14525,
14588, 14650, 14711, 14772, 14831, 14890, 14947, 15003,
15059, 15113, 15166, 15219, 15270, 15320, 15369, 15417,
15464, 15509, 15554, 15597, 15640, 15681, 15721, 15760,
15798, 15835, 15871, 15905, 15938, 15971, 16001, 16031,
16060, 16087, 16113, 16138, 16162, 16185, 16206, 16227,
16246, 16263, 16280, 16295, 16309, 16322, 16334, 16345,
16354, 16362, 16369, 16374, 16378, 16382, 16383, 16384
};

View File

@ -0,0 +1,120 @@
/*
* 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.
*/
/*
* This file contains implementations of the iLBC specific functions
* WebRtcSpl_ScaleAndAddVectorsWithRound()
* WebRtcSpl_ReverseOrderMultArrayElements()
* WebRtcSpl_ElementwiseVectorMult()
* WebRtcSpl_AddVectorsAndShift()
* WebRtcSpl_AddAffineVectorToVector()
* WebRtcSpl_AffineTransformVector()
*
* The description header can be found in signal_processing_library.h
*
*/
#include "signal_processing_library.h"
void WebRtcSpl_ScaleAndAddVectorsWithRound(WebRtc_Word16 *vector1, WebRtc_Word16 scale1,
WebRtc_Word16 *vector2, WebRtc_Word16 scale2,
WebRtc_Word16 right_shifts, WebRtc_Word16 *out,
WebRtc_Word16 vector_length)
{
int i;
WebRtc_Word16 roundVal;
roundVal = 1 << right_shifts;
roundVal = roundVal >> 1;
for (i = 0; i < vector_length; i++)
{
out[i] = (WebRtc_Word16)((WEBRTC_SPL_MUL_16_16(vector1[i], scale1)
+ WEBRTC_SPL_MUL_16_16(vector2[i], scale2) + roundVal) >> right_shifts);
}
}
void WebRtcSpl_ReverseOrderMultArrayElements(WebRtc_Word16 *out, G_CONST WebRtc_Word16 *in,
G_CONST WebRtc_Word16 *win,
WebRtc_Word16 vector_length,
WebRtc_Word16 right_shifts)
{
int i;
WebRtc_Word16 *outptr = out;
G_CONST WebRtc_Word16 *inptr = in;
G_CONST WebRtc_Word16 *winptr = win;
for (i = 0; i < vector_length; i++)
{
(*outptr++) = (WebRtc_Word16)WEBRTC_SPL_MUL_16_16_RSFT(*inptr++,
*winptr--, right_shifts);
}
}
void WebRtcSpl_ElementwiseVectorMult(WebRtc_Word16 *out, G_CONST WebRtc_Word16 *in,
G_CONST WebRtc_Word16 *win, WebRtc_Word16 vector_length,
WebRtc_Word16 right_shifts)
{
int i;
WebRtc_Word16 *outptr = out;
G_CONST WebRtc_Word16 *inptr = in;
G_CONST WebRtc_Word16 *winptr = win;
for (i = 0; i < vector_length; i++)
{
(*outptr++) = (WebRtc_Word16)WEBRTC_SPL_MUL_16_16_RSFT(*inptr++,
*winptr++, right_shifts);
}
}
void WebRtcSpl_AddVectorsAndShift(WebRtc_Word16 *out, G_CONST WebRtc_Word16 *in1,
G_CONST WebRtc_Word16 *in2, WebRtc_Word16 vector_length,
WebRtc_Word16 right_shifts)
{
int i;
WebRtc_Word16 *outptr = out;
G_CONST WebRtc_Word16 *in1ptr = in1;
G_CONST WebRtc_Word16 *in2ptr = in2;
for (i = vector_length; i > 0; i--)
{
(*outptr++) = (WebRtc_Word16)(((*in1ptr++) + (*in2ptr++)) >> right_shifts);
}
}
void WebRtcSpl_AddAffineVectorToVector(WebRtc_Word16 *out, WebRtc_Word16 *in,
WebRtc_Word16 gain, WebRtc_Word32 add_constant,
WebRtc_Word16 right_shifts, int vector_length)
{
WebRtc_Word16 *inPtr;
WebRtc_Word16 *outPtr;
int i;
inPtr = in;
outPtr = out;
for (i = 0; i < vector_length; i++)
{
(*outPtr++) += (WebRtc_Word16)((WEBRTC_SPL_MUL_16_16((*inPtr++), gain)
+ (WebRtc_Word32)add_constant) >> right_shifts);
}
}
void WebRtcSpl_AffineTransformVector(WebRtc_Word16 *out, WebRtc_Word16 *in,
WebRtc_Word16 gain, WebRtc_Word32 add_constant,
WebRtc_Word16 right_shifts, int vector_length)
{
WebRtc_Word16 *inPtr;
WebRtc_Word16 *outPtr;
int i;
inPtr = in;
outPtr = out;
for (i = 0; i < vector_length; i++)
{
(*outPtr++) = (WebRtc_Word16)((WEBRTC_SPL_MUL_16_16((*inPtr++), gain)
+ (WebRtc_Word32)add_constant) >> right_shifts);
}
}

View File

@ -0,0 +1,24 @@
/*
* 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.
*/
/*
* This file contains the function WebRtcSpl_IncreaseSeed().
* The description header can be found in signal_processing_library.h
*
*/
#include "signal_processing_library.h"
WebRtc_UWord32 WebRtcSpl_IncreaseSeed(WebRtc_UWord32 *seed)
{
seed[0] = (seed[0] * ((WebRtc_Word32)69069) + 1) & (WEBRTC_SPL_MAX_SEED_USED - 1);
return seed[0];
}

View File

@ -0,0 +1,51 @@
/*
* refl_coef_to_lpc.c
*
* This file contains the function WebRtcSpl_ReflCoefToLpc().
* The description header can be found in signal_processing_library.h
*
*/
#include "signal_processing_library.h"
void WebRtcSpl_ReflCoefToLpc(G_CONST WebRtc_Word16 *k, int use_order, WebRtc_Word16 *a)
{
WebRtc_Word16 any[WEBRTC_SPL_MAX_LPC_ORDER + 1];
WebRtc_Word16 *aptr, *aptr2, *anyptr;
G_CONST WebRtc_Word16 *kptr;
int m, i;
kptr = k;
*a = 4096; // i.e., (Word16_MAX >> 3)+1.
*any = *a;
a[1] = WEBRTC_SPL_RSHIFT_W16((*k), 3);
for (m = 1; m < use_order; m++)
{
kptr++;
aptr = a;
aptr++;
aptr2 = &a[m];
anyptr = any;
anyptr++;
any[m + 1] = WEBRTC_SPL_RSHIFT_W16((*kptr), 3);
for (i = 0; i < m; i++)
{
*anyptr = (*aptr)
+ (WebRtc_Word16)WEBRTC_SPL_MUL_16_16_RSFT((*aptr2), (*kptr), 15);
anyptr++;
aptr++;
aptr2--;
}
aptr = a;
anyptr = any;
for (i = 0; i < (m + 2); i++)
{
*aptr = *anyptr;
aptr++;
anyptr++;
}
}
}

View File

@ -0,0 +1,54 @@
/*
* 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.
*/
/*
* This file contains the function WebRtcSpl_KToAQScale().
* The description header can be found in signal_processing_library.h
*
*/
#include "signal_processing_library.h"
void WebRtcSpl_KToAQScale(WebRtc_Word16* k, int use_order, int Q, WebRtc_Word16* a)
{
WebRtc_Word16 any[WEBRTC_SPL_MAX_LPC_ORDER];
WebRtc_Word16* aptr;
WebRtc_Word16* aptr2;
WebRtc_Word16* anyptr;
WebRtc_Word16* kptr;
int m, i, Qscale;
Qscale = 15 - Q; // Q-domain for A-coeff
kptr = k;
*a = *k >> Qscale;
for (m = 0; m < (use_order - 1); m++)
{
kptr++;
aptr = a;
aptr2 = &a[m];
anyptr = any;
for (i = 0; i < m + 1; i++)
*anyptr++ = (*aptr++) + (WebRtc_Word16)(((WebRtc_Word32)(*aptr2--)
* (WebRtc_Word32)*kptr) >> 15);
any[m + 1] = *kptr >> Qscale; // compute the next coefficient for next loop
aptr = a;
anyptr = any;
for (i = 0; i < (m + 2); i++)
{
*aptr = *anyptr;
*aptr++;
*anyptr++;
}
}
}

View File

@ -0,0 +1,31 @@
/*
* k_to_lar_w16.c
*
* This file contains the function WebRtcSpl_KToLarW16().
* The description header can be found in signal_processing_library.h
*
*/
#include "signal_processing_library.h"
void WebRtcSpl_KToLarW16(WebRtc_Word16 *kLar, int use_order)
{
// The LARs are computed from the reflection coefficients using
// a linear approximation of the logarithm.
WebRtc_Word16 tmp16;
int i;
for (i = 0; i < use_order; i++, kLar++)
{
tmp16 = WEBRTC_SPL_ABS_W16( *kLar );
if (tmp16 < 22118)
tmp16 >>= 1;
else if (tmp16 < 31130)
tmp16 -= 11059;
else
{
tmp16 -= 26112;
tmp16 <<= 2;
}
*kLar = *kLar < 0 ? -tmp16 : tmp16;
}
}

View File

@ -0,0 +1,31 @@
/*
* k_to_lar_w32.c
*
* This file contains the function WebRtcSpl_KToLarW32().
* The description header can be found in signal_processing_library.h
*
*/
#include "signal_processing_library.h"
void WebRtcSpl_KToLarW32(WebRtc_Word32 *kLar, int use_order)
{
// The LARs are computed from the reflection coefficients using
// a linear approximation of the logarithm.
WebRtc_Word32 tmp;
int i;
for (i = 0; i < use_order; i++, kLar++)
{
tmp = WEBRTC_SPL_ABS_W16(*kLar);
if (tmp < (WebRtc_Word32)1300000000)
tmp >>= 1;
else if (tmp < (WebRtc_Word32)2000000000)
tmp -= 650000000;
else
{
tmp -= 1662500000;
tmp <<= 2;
}
*kLar = *kLar < 0 ? -tmp : tmp;
}
}

View File

@ -0,0 +1,29 @@
/*
* lar_to_refl_coef_w16.c
*
* This file contains the function WebRtcSpl_LarToReflCoefW16().
* The description header can be found in signal_processing_library.h
*
*/
#include "signal_processing_library.h"
void WebRtcSpl_LarToReflCoefW16(WebRtc_Word16 *kLAR, int use_order)
{
int i;
WebRtc_Word16 temp;
for (i = 0; i < use_order; i++, kLAR++)
{
if ( *kLAR < 0)
{
temp = *kLAR == WEBRTC_SPL_WORD16_MIN ? WEBRTC_SPL_WORD16_MAX : -( *kLAR);
*kLAR = -((temp < 11059) ? temp << 1 : ((temp < 20070) ? temp + 11059
: WEBRTC_SPL_ADD_SAT_W16( temp >> 2, 26112 )));
} else
{
temp = *kLAR;
*kLAR = (temp < 11059) ? temp << 1 : ((temp < 20070) ? temp + 11059
: WEBRTC_SPL_ADD_SAT_W16( temp >> 2, 26112 ));
}
}
}

View File

@ -0,0 +1,32 @@
/*
* lar_to_refl_coef_w32.c
*
* This file contains the function WebRtcSpl_LarToReflCoefW32().
* The description header can be found in signal_processing_library.h
*
*/
#include "signal_processing_library.h"
void WebRtcSpl_LarToReflCoefW32(WebRtc_Word32 *kLAR, int use_order)
{
int i;
WebRtc_Word32 temp;
for (i = 0; i < use_order; i++, kLAR++)
{
if (*kLAR < 0)
{
temp = (*kLAR == WEBRTC_SPL_WORD32_MIN) ? WEBRTC_SPL_WORD32_MAX : -(*kLAR);
*kLAR = -((temp < (WebRtc_Word32)650000000) ? temp << 1 : ((temp
< (WebRtc_Word32)1350000000) ? temp + 650000000
: WEBRTC_SPL_ADD_SAT_W32( temp >> 2, 1662500000 )));
} else
{
temp = *kLAR;
*kLAR = (temp < (WebRtc_Word32)650000000) ? temp << 1 : ((temp
< (WebRtc_Word32)1350000000) ? temp + 650000000
: WEBRTC_SPL_ADD_SAT_W32( temp >> 2, 1662500000 ));
}
}
}

View File

@ -0,0 +1,259 @@
/*
* 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.
*/
/*
* This file contains the function WebRtcSpl_LevinsonDurbin().
* The description header can be found in signal_processing_library.h
*
*/
#include "signal_processing_library.h"
#define SPL_LEVINSON_MAXORDER 20
WebRtc_Word16 WebRtcSpl_LevinsonDurbin(WebRtc_Word32 *R, WebRtc_Word16 *A, WebRtc_Word16 *K,
WebRtc_Word16 order)
{
WebRtc_Word16 i, j;
// Auto-correlation coefficients in high precision
WebRtc_Word16 R_hi[SPL_LEVINSON_MAXORDER + 1], R_low[SPL_LEVINSON_MAXORDER + 1];
// LPC coefficients in high precision
WebRtc_Word16 A_hi[SPL_LEVINSON_MAXORDER + 1], A_low[SPL_LEVINSON_MAXORDER + 1];
// LPC coefficients for next iteration
WebRtc_Word16 A_upd_hi[SPL_LEVINSON_MAXORDER + 1], A_upd_low[SPL_LEVINSON_MAXORDER + 1];
// Reflection coefficient in high precision
WebRtc_Word16 K_hi, K_low;
// Prediction gain Alpha in high precision and with scale factor
WebRtc_Word16 Alpha_hi, Alpha_low, Alpha_exp;
WebRtc_Word16 tmp_hi, tmp_low;
WebRtc_Word32 temp1W32, temp2W32, temp3W32;
WebRtc_Word16 norm;
// Normalize the autocorrelation R[0]...R[order+1]
norm = WebRtcSpl_NormW32(R[0]);
for (i = order; i >= 0; i--)
{
temp1W32 = WEBRTC_SPL_LSHIFT_W32(R[i], norm);
// Put R in hi and low format
R_hi[i] = (WebRtc_Word16)WEBRTC_SPL_RSHIFT_W32(temp1W32, 16);
R_low[i] = (WebRtc_Word16)WEBRTC_SPL_RSHIFT_W32((temp1W32
- WEBRTC_SPL_LSHIFT_W32((WebRtc_Word32)R_hi[i], 16)), 1);
}
// K = A[1] = -R[1] / R[0]
temp2W32 = WEBRTC_SPL_LSHIFT_W32((WebRtc_Word32)R_hi[1],16)
+ WEBRTC_SPL_LSHIFT_W32((WebRtc_Word32)R_low[1],1); // R[1] in Q31
temp3W32 = WEBRTC_SPL_ABS_W32(temp2W32); // abs R[1]
temp1W32 = WebRtcSpl_DivW32HiLow(temp3W32, R_hi[0], R_low[0]); // abs(R[1])/R[0] in Q31
// Put back the sign on R[1]
if (temp2W32 > 0)
{
temp1W32 = -temp1W32;
}
// Put K in hi and low format
K_hi = (WebRtc_Word16)WEBRTC_SPL_RSHIFT_W32(temp1W32, 16);
K_low = (WebRtc_Word16)WEBRTC_SPL_RSHIFT_W32((temp1W32
- WEBRTC_SPL_LSHIFT_W32((WebRtc_Word32)K_hi, 16)), 1);
// Store first reflection coefficient
K[0] = K_hi;
temp1W32 = WEBRTC_SPL_RSHIFT_W32(temp1W32, 4); // A[1] in Q27
// Put A[1] in hi and low format
A_hi[1] = (WebRtc_Word16)WEBRTC_SPL_RSHIFT_W32(temp1W32, 16);
A_low[1] = (WebRtc_Word16)WEBRTC_SPL_RSHIFT_W32((temp1W32
- WEBRTC_SPL_LSHIFT_W32((WebRtc_Word32)A_hi[1], 16)), 1);
// Alpha = R[0] * (1-K^2)
temp1W32 = (((WEBRTC_SPL_MUL_16_16(K_hi, K_low) >> 14) + WEBRTC_SPL_MUL_16_16(K_hi, K_hi))
<< 1); // temp1W32 = k^2 in Q31
temp1W32 = WEBRTC_SPL_ABS_W32(temp1W32); // Guard against <0
temp1W32 = (WebRtc_Word32)0x7fffffffL - temp1W32; // temp1W32 = (1 - K[0]*K[0]) in Q31
// Store temp1W32 = 1 - K[0]*K[0] on hi and low format
tmp_hi = (WebRtc_Word16)WEBRTC_SPL_RSHIFT_W32(temp1W32, 16);
tmp_low = (WebRtc_Word16)WEBRTC_SPL_RSHIFT_W32((temp1W32
- WEBRTC_SPL_LSHIFT_W32((WebRtc_Word32)tmp_hi, 16)), 1);
// Calculate Alpha in Q31
temp1W32 = ((WEBRTC_SPL_MUL_16_16(R_hi[0], tmp_hi)
+ (WEBRTC_SPL_MUL_16_16(R_hi[0], tmp_low) >> 15)
+ (WEBRTC_SPL_MUL_16_16(R_low[0], tmp_hi) >> 15)) << 1);
// Normalize Alpha and put it in hi and low format
Alpha_exp = WebRtcSpl_NormW32(temp1W32);
temp1W32 = WEBRTC_SPL_LSHIFT_W32(temp1W32, Alpha_exp);
Alpha_hi = (WebRtc_Word16)WEBRTC_SPL_RSHIFT_W32(temp1W32, 16);
Alpha_low = (WebRtc_Word16)WEBRTC_SPL_RSHIFT_W32((temp1W32
- WEBRTC_SPL_LSHIFT_W32((WebRtc_Word32)Alpha_hi, 16)), 1);
// Perform the iterative calculations in the Levinson-Durbin algorithm
for (i = 2; i <= order; i++)
{
/* ----
temp1W32 = R[i] + > R[j]*A[i-j]
/
----
j=1..i-1
*/
temp1W32 = 0;
for (j = 1; j < i; j++)
{
// temp1W32 is in Q31
temp1W32 += ((WEBRTC_SPL_MUL_16_16(R_hi[j], A_hi[i-j]) << 1)
+ (((WEBRTC_SPL_MUL_16_16(R_hi[j], A_low[i-j]) >> 15)
+ (WEBRTC_SPL_MUL_16_16(R_low[j], A_hi[i-j]) >> 15)) << 1));
}
temp1W32 = WEBRTC_SPL_LSHIFT_W32(temp1W32, 4);
temp1W32 += (WEBRTC_SPL_LSHIFT_W32((WebRtc_Word32)R_hi[i], 16)
+ WEBRTC_SPL_LSHIFT_W32((WebRtc_Word32)R_low[i], 1));
// K = -temp1W32 / Alpha
temp2W32 = WEBRTC_SPL_ABS_W32(temp1W32); // abs(temp1W32)
temp3W32 = WebRtcSpl_DivW32HiLow(temp2W32, Alpha_hi, Alpha_low); // abs(temp1W32)/Alpha
// Put the sign of temp1W32 back again
if (temp1W32 > 0)
{
temp3W32 = -temp3W32;
}
// Use the Alpha shifts from earlier to de-normalize
norm = WebRtcSpl_NormW32(temp3W32);
if ((Alpha_exp <= norm) || (temp3W32 == 0))
{
temp3W32 = WEBRTC_SPL_LSHIFT_W32(temp3W32, Alpha_exp);
} else
{
if (temp3W32 > 0)
{
temp3W32 = (WebRtc_Word32)0x7fffffffL;
} else
{
temp3W32 = (WebRtc_Word32)0x80000000L;
}
}
// Put K on hi and low format
K_hi = (WebRtc_Word16)WEBRTC_SPL_RSHIFT_W32(temp3W32, 16);
K_low = (WebRtc_Word16)WEBRTC_SPL_RSHIFT_W32((temp3W32
- WEBRTC_SPL_LSHIFT_W32((WebRtc_Word32)K_hi, 16)), 1);
// Store Reflection coefficient in Q15
K[i - 1] = K_hi;
// Test for unstable filter.
// If unstable return 0 and let the user decide what to do in that case
if ((WebRtc_Word32)WEBRTC_SPL_ABS_W16(K_hi) > (WebRtc_Word32)32750)
{
return 0; // Unstable filter
}
/*
Compute updated LPC coefficient: Anew[i]
Anew[j]= A[j] + K*A[i-j] for j=1..i-1
Anew[i]= K
*/
for (j = 1; j < i; j++)
{
// temp1W32 = A[j] in Q27
temp1W32 = WEBRTC_SPL_LSHIFT_W32((WebRtc_Word32)A_hi[j],16)
+ WEBRTC_SPL_LSHIFT_W32((WebRtc_Word32)A_low[j],1);
// temp1W32 += K*A[i-j] in Q27
temp1W32 += ((WEBRTC_SPL_MUL_16_16(K_hi, A_hi[i-j])
+ (WEBRTC_SPL_MUL_16_16(K_hi, A_low[i-j]) >> 15)
+ (WEBRTC_SPL_MUL_16_16(K_low, A_hi[i-j]) >> 15)) << 1);
// Put Anew in hi and low format
A_upd_hi[j] = (WebRtc_Word16)WEBRTC_SPL_RSHIFT_W32(temp1W32, 16);
A_upd_low[j] = (WebRtc_Word16)WEBRTC_SPL_RSHIFT_W32((temp1W32
- WEBRTC_SPL_LSHIFT_W32((WebRtc_Word32)A_upd_hi[j], 16)), 1);
}
// temp3W32 = K in Q27 (Convert from Q31 to Q27)
temp3W32 = WEBRTC_SPL_RSHIFT_W32(temp3W32, 4);
// Store Anew in hi and low format
A_upd_hi[i] = (WebRtc_Word16)WEBRTC_SPL_RSHIFT_W32(temp3W32, 16);
A_upd_low[i] = (WebRtc_Word16)WEBRTC_SPL_RSHIFT_W32((temp3W32
- WEBRTC_SPL_LSHIFT_W32((WebRtc_Word32)A_upd_hi[i], 16)), 1);
// Alpha = Alpha * (1-K^2)
temp1W32 = (((WEBRTC_SPL_MUL_16_16(K_hi, K_low) >> 14)
+ WEBRTC_SPL_MUL_16_16(K_hi, K_hi)) << 1); // K*K in Q31
temp1W32 = WEBRTC_SPL_ABS_W32(temp1W32); // Guard against <0
temp1W32 = (WebRtc_Word32)0x7fffffffL - temp1W32; // 1 - K*K in Q31
// Convert 1- K^2 in hi and low format
tmp_hi = (WebRtc_Word16)WEBRTC_SPL_RSHIFT_W32(temp1W32, 16);
tmp_low = (WebRtc_Word16)WEBRTC_SPL_RSHIFT_W32((temp1W32
- WEBRTC_SPL_LSHIFT_W32((WebRtc_Word32)tmp_hi, 16)), 1);
// Calculate Alpha = Alpha * (1-K^2) in Q31
temp1W32 = ((WEBRTC_SPL_MUL_16_16(Alpha_hi, tmp_hi)
+ (WEBRTC_SPL_MUL_16_16(Alpha_hi, tmp_low) >> 15)
+ (WEBRTC_SPL_MUL_16_16(Alpha_low, tmp_hi) >> 15)) << 1);
// Normalize Alpha and store it on hi and low format
norm = WebRtcSpl_NormW32(temp1W32);
temp1W32 = WEBRTC_SPL_LSHIFT_W32(temp1W32, norm);
Alpha_hi = (WebRtc_Word16)WEBRTC_SPL_RSHIFT_W32(temp1W32, 16);
Alpha_low = (WebRtc_Word16)WEBRTC_SPL_RSHIFT_W32((temp1W32
- WEBRTC_SPL_LSHIFT_W32((WebRtc_Word32)Alpha_hi, 16)), 1);
// Update the total normalization of Alpha
Alpha_exp = Alpha_exp + norm;
// Update A[]
for (j = 1; j <= i; j++)
{
A_hi[j] = A_upd_hi[j];
A_low[j] = A_upd_low[j];
}
}
/*
Set A[0] to 1.0 and store the A[i] i=1...order in Q12
(Convert from Q27 and use rounding)
*/
A[0] = 4096;
for (i = 1; i <= order; i++)
{
// temp1W32 in Q27
temp1W32 = WEBRTC_SPL_LSHIFT_W32((WebRtc_Word32)A_hi[i], 16)
+ WEBRTC_SPL_LSHIFT_W32((WebRtc_Word32)A_low[i], 1);
// Round and store upper word
A[i] = (WebRtc_Word16)WEBRTC_SPL_RSHIFT_W32((temp1W32<<1)+(WebRtc_Word32)32768, 16);
}
return 1; // Stable filters
}

View File

@ -0,0 +1,37 @@
/*
* 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.
*/
/*
* This file contains the function WebRtcSpl_Lpc().
* The description header can be found in signal_processing_library.h
*
*/
#include "signal_processing_library.h"
int WebRtcSpl_Lpc(G_CONST WebRtc_Word16 *x, int x_length, int order,
WebRtc_Word16 *lpcvec) // out Q12
{
int cvlen, corrvlen;
int scaleDUMMY;
WebRtc_Word32 corrvector[WEBRTC_SPL_MAX_LPC_ORDER + 1];
WebRtc_Word16 reflCoefs[WEBRTC_SPL_MAX_LPC_ORDER];
cvlen = order + 1;
corrvlen = WebRtcSpl_AutoCorrelation(x, x_length, order, corrvector, &scaleDUMMY);
if (*corrvector == 0)
*corrvector = WEBRTC_SPL_WORD16_MAX;
WebRtcSpl_AutoCorrToReflCoef(corrvector, order, reflCoefs);
WebRtcSpl_ReflCoefToLpc(reflCoefs, order, lpcvec);
return cvlen;
}

View File

@ -0,0 +1,57 @@
/*
* 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.
*/
/*
* This file contains the function WebRtcSpl_LpcToReflCoef().
* The description header can be found in signal_processing_library.h
*
*/
#include "signal_processing_library.h"
#define SPL_LPC_TO_REFL_COEF_MAX_AR_MODEL_ORDER 50
void WebRtcSpl_LpcToReflCoef(WebRtc_Word16* a16, int use_order, WebRtc_Word16* k16)
{
int m, k;
WebRtc_Word32 tmp32[SPL_LPC_TO_REFL_COEF_MAX_AR_MODEL_ORDER];
WebRtc_Word32 tmp_inv_denom32;
WebRtc_Word16 tmp_inv_denom16;
k16[use_order - 1] = WEBRTC_SPL_LSHIFT_W16(a16[use_order], 3); //Q12<<3 => Q15
for (m = use_order - 1; m > 0; m--)
{
// (1 - k^2) in Q30
tmp_inv_denom32 = ((WebRtc_Word32)1073741823) - WEBRTC_SPL_MUL_16_16(k16[m], k16[m]);
// (1 - k^2) in Q15
tmp_inv_denom16 = (WebRtc_Word16)WEBRTC_SPL_RSHIFT_W32(tmp_inv_denom32, 15);
for (k = 1; k <= m; k++)
{
// tmp[k] = (a[k] - RC[m] * a[m-k+1]) / (1.0 - RC[m]*RC[m]);
// [Q12<<16 - (Q15*Q12)<<1] = [Q28 - Q28] = Q28
tmp32[k] = WEBRTC_SPL_LSHIFT_W32((WebRtc_Word32)a16[k], 16)
- WEBRTC_SPL_LSHIFT_W32(WEBRTC_SPL_MUL_16_16(k16[m], a16[m-k+1]), 1);
tmp32[k] = WebRtcSpl_DivW32W16(tmp32[k], tmp_inv_denom16); //Q28/Q15 = Q13
}
for (k = 1; k < m; k++)
{
a16[k] = (WebRtc_Word16)WEBRTC_SPL_RSHIFT_W32(tmp32[k], 1); //Q13>>1 => Q12
}
tmp32[m] = WEBRTC_SPL_SAT(8191, tmp32[m], -8191);
k16[m - 1] = (WebRtc_Word16)WEBRTC_SPL_LSHIFT_W32(tmp32[m], 2); //Q13<<2 => Q15
}
return;
}

View File

@ -0,0 +1,33 @@
/*
* max_abs_index_w16.c
*
* This file contains the function WebRtcSpl_MaxAbsIndexW16().
* The description header can be found in signal_processing_library.h
*
*/
#include "signal_processing_library.h"
WebRtc_Word16 WebRtcSpl_MaxAbsIndexW16(G_CONST WebRtc_Word16* vector,
WebRtc_Word16 vector_length)
{
WebRtc_Word16 tempMax;
WebRtc_Word16 absTemp;
WebRtc_Word16 tempMaxIndex, i;
G_CONST WebRtc_Word16 *tmpvector = vector;
tempMaxIndex = 0;
tempMax = WEBRTC_SPL_ABS_W16(*tmpvector);
tmpvector++;
for (i = 1; i < vector_length; i++)
{
absTemp = WEBRTC_SPL_ABS_W16(*tmpvector);
tmpvector++;
if (absTemp > tempMax)
{
tempMax = absTemp;
tempMaxIndex = i;
}
}
return tempMaxIndex;
}

View File

@ -0,0 +1,75 @@
/*
* max_abs_value_w16.c
*
* This file contains the function WebRtcSpl_MaxAbsValueW16().
* The description header can be found in signal_processing_library.h
*
*/
#include "signal_processing_library.h"
WebRtc_Word16 WebRtcSpl_MaxAbsValueW16(G_CONST WebRtc_Word16 *vector, WebRtc_Word16 length)
{
WebRtc_Word32 tempMax = 0;
WebRtc_Word32 absVal;
WebRtc_Word16 totMax;
int i;
G_CONST WebRtc_Word16 *tmpvector = vector;
#ifdef _ARM_OPT_
#pragma message("NOTE: _ARM_OPT_ optimizations are used")
WebRtc_Word16 len4 = (length >> 2) << 2;
#endif
#ifndef _ARM_OPT_
for (i = 0; i < length; i++)
{
absVal = WEBRTC_SPL_ABS_W32((*tmpvector));
if (absVal > tempMax)
{
tempMax = absVal;
}
tmpvector++;
}
#else
for (i = 0; i < len4; i = i + 4)
{
absVal = WEBRTC_SPL_ABS_W32((*tmpvector));
if (absVal > tempMax)
{
tempMax = absVal;
}
tmpvector++;
absVal = WEBRTC_SPL_ABS_W32((*tmpvector));
if (absVal > tempMax)
{
tempMax = absVal;
}
tmpvector++;
absVal = WEBRTC_SPL_ABS_W32((*tmpvector));
if (absVal > tempMax)
{
tempMax = absVal;
}
tmpvector++;
absVal = WEBRTC_SPL_ABS_W32((*tmpvector));
if (absVal > tempMax)
{
tempMax = absVal;
}
tmpvector++;
}
for (i = len4; i < len; i++)
{
absVal = WEBRTC_SPL_ABS_W32((*tmpvector));
if (absVal > tempMax)
{
tempMax = absVal;
}
tmpvector++;
}
#endif
totMax = (WebRtc_Word16)WEBRTC_SPL_MIN(tempMax, WEBRTC_SPL_WORD16_MAX);
return totMax;
}

View File

@ -0,0 +1,31 @@
/*
* max_abs_value_w32.c
*
* This file contains the function WebRtcSpl_MaxAbsValueW32().
* The description header can be found in signal_processing_library.h
*
*/
#include "signal_processing_library.h"
WebRtc_Word32 WebRtcSpl_MaxAbsValueW32(G_CONST WebRtc_Word32 *vector, // (i) Input vector
WebRtc_Word16 length) // (i) Number of elements
{
WebRtc_UWord32 tempMax = 0;
WebRtc_UWord32 absVal;
WebRtc_Word32 retval;
int i;
G_CONST WebRtc_Word32 *tmpvector = vector;
for (i = 0; i < length; i++)
{
absVal = WEBRTC_SPL_ABS_W32((*tmpvector));
if (absVal > tempMax)
{
tempMax = absVal;
}
tmpvector++;
}
retval = (WebRtc_Word32)(WEBRTC_SPL_MIN(tempMax, WEBRTC_SPL_WORD32_MAX));
return retval;
}

View File

@ -0,0 +1,28 @@
/*
* max_index_w16.c
*
* This file contains the function WebRtcSpl_MaxIndexW16().
* The description header can be found in signal_processing_library.h
*
*/
#include "signal_processing_library.h"
WebRtc_Word16 WebRtcSpl_MaxIndexW16(G_CONST WebRtc_Word16 *vector, WebRtc_Word16 length)
{
WebRtc_Word16 tempMax;
WebRtc_Word16 tempMaxIndex, i;
G_CONST WebRtc_Word16 *tmpvector = vector;
tempMaxIndex = 0;
tempMax = *tmpvector++;
for (i = 1; i < length; i++)
{
if ( *tmpvector++ > tempMax)
{
tempMax = vector[i];
tempMaxIndex = i;
}
}
return tempMaxIndex;
}

View File

@ -0,0 +1,29 @@
/*
* max_index_w32.c
*
* This file contains the function WebRtcSpl_MaxIndexW32().
* The description header can be found in signal_processing_library.h
*
*/
#include "signal_processing_library.h"
WebRtc_Word16 WebRtcSpl_MaxIndexW32(G_CONST WebRtc_Word32* vector, // (i) Input vector
WebRtc_Word16 length) // (i) Number of elements
{
WebRtc_Word32 tempMax;
WebRtc_Word16 tempMaxIndex, i;
G_CONST WebRtc_Word32 *tmpvector = vector;
tempMaxIndex = 0;
tempMax = *tmpvector++;
for (i = 1; i < length; i++)
{
if (*tmpvector++ > tempMax)
{
tempMax = vector[i];
tempMaxIndex = i;
}
}
return tempMaxIndex;
}

View File

@ -0,0 +1,30 @@
/*
* max_value_w16.c
*
* This file contains the function WebRtcSpl_MaxValueW16().
* The description header can be found in signal_processing_library.h
*
*/
#include "signal_processing_library.h"
#ifndef XSCALE_OPT
WebRtc_Word16 WebRtcSpl_MaxValueW16(G_CONST WebRtc_Word16* vector, WebRtc_Word16 length)
{
WebRtc_Word16 tempMax;
WebRtc_Word16 i;
G_CONST WebRtc_Word16 *tmpvector = vector;
tempMax = *tmpvector++;
for (i = 1; i < length; i++)
{
if (*tmpvector++ > tempMax)
tempMax = vector[i];
}
return tempMax;
}
#else
#pragma message(">> max_value_w16.c is excluded from this build")
#endif

View File

@ -0,0 +1,31 @@
/*
* max_value_w32.c
*
* This file contains the function WebRtcSpl_MaxValueW32().
* The description header can be found in signal_processing_library.h
*
*/
#include "signal_processing_library.h"
#ifndef XSCALE_OPT
WebRtc_Word32 WebRtcSpl_MaxValueW32(G_CONST WebRtc_Word32* vector, // (i) Input vector
WebRtc_Word16 length) // (i) Number of elements
{
WebRtc_Word32 tempMax;
WebRtc_Word16 i;
G_CONST WebRtc_Word32 *tmpvector = vector;
tempMax = *tmpvector++;
for (i = 1; i < length; i++)
{
if (*tmpvector++ > tempMax)
tempMax = vector[i];
}
return tempMax;
}
#else
#pragma message(">> max_value_w32.c is excluded from this build")
#endif

View File

@ -0,0 +1,30 @@
/*
* 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.
*/
/*
* This file contains the function WebRtcSpl_MemCpyReversedOrder().
* The description header can be found in signal_processing_library.h
*
*/
#include "signal_processing_library.h"
void WebRtcSpl_MemCpyReversedOrder(WebRtc_Word16* dest, WebRtc_Word16* source, int length)
{
int j;
WebRtc_Word16* destPtr = dest;
WebRtc_Word16* sourcePtr = source;
for (j = 0; j < length; j++)
{
*destPtr-- = *sourcePtr++;
}
}

View File

@ -0,0 +1,29 @@
/*
* 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.
*/
/*
* This file contains the function WebRtcSpl_MemSetW16().
* The description header can be found in signal_processing_library.h
*
*/
#include "signal_processing_library.h"
void WebRtcSpl_MemSetW16(WebRtc_Word16 *ptr, WebRtc_Word16 set_value, int length)
{
int j;
WebRtc_Word16 *arrptr = ptr;
for (j = length; j > 0; j--)
{
*arrptr++ = set_value;
}
}

View File

@ -0,0 +1,29 @@
/*
* 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.
*/
/*
* This file contains the function WebRtcSpl_MemSetW32().
* The description header can be found in signal_processing_library.h
*
*/
#include "signal_processing_library.h"
void WebRtcSpl_MemSetW32(WebRtc_Word32 *ptr, WebRtc_Word32 set_value, int length)
{
int j;
WebRtc_Word32 *arrptr = ptr;
for (j = length; j > 0; j--)
{
*arrptr++ = set_value;
}
}

View File

@ -0,0 +1,35 @@
/*
* min_index_w16.c
*
* This file contains the function WebRtcSpl_MinIndexW16().
* The description header can be found in signal_processing_library.h
*
*/
#include "signal_processing_library.h"
#ifndef XSCALE_OPT
WebRtc_Word16 WebRtcSpl_MinIndexW16(G_CONST WebRtc_Word16* vector, WebRtc_Word16 vector_length)
{
WebRtc_Word16 tempMin;
WebRtc_Word16 tempMinIndex, i;
G_CONST WebRtc_Word16 *tmpvector = vector;
// Find index of smallest value
tempMinIndex = 0;
tempMin = *tmpvector++;
for (i = 1; i < vector_length; i++)
{
if (*tmpvector++ < tempMin)
{
tempMin = vector[i];
tempMinIndex = i;
}
}
return tempMinIndex;
}
#else
#pragma message(">> min_index_w16.c is excluded from this build")
#endif

View File

@ -0,0 +1,36 @@
/*
* min_index_w16.c
*
* This file contains the function WebRtcSpl_MinIndexW16().
* The description header can be found in signal_processing_library.h
*
*/
#include "signal_processing_library.h"
#ifndef XSCALE_OPT
WebRtc_Word16 WebRtcSpl_MinIndexW32(G_CONST WebRtc_Word32* vector, // (i) Input vector
WebRtc_Word16 vector_length) // (i) Number of elements
{
WebRtc_Word32 tempMin;
WebRtc_Word16 tempMinIndex, i;
G_CONST WebRtc_Word32 *tmpvector = vector;
// Find index of smallest value
tempMinIndex = 0;
tempMin = *tmpvector++;
for (i = 1; i < vector_length; i++)
{
if (*tmpvector++ < tempMin)
{
tempMin = vector[i];
tempMinIndex = i;
}
}
return tempMinIndex;
}
#else
#pragma message(">> max_index_w16.c is excluded from this build")
#endif

View File

@ -0,0 +1,305 @@
/*
* 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.
*/
/*
* This file contains the implementation of functions
* WebRtcSpl_MaxAbsValueW16()
* WebRtcSpl_MaxAbsIndexW16()
* WebRtcSpl_MaxAbsValueW32()
* WebRtcSpl_MaxValueW16()
* WebRtcSpl_MaxIndexW16()
* WebRtcSpl_MaxValueW32()
* WebRtcSpl_MaxIndexW32()
* WebRtcSpl_MinValueW16()
* WebRtcSpl_MinIndexW16()
* WebRtcSpl_MinValueW32()
* WebRtcSpl_MinIndexW32()
*
* The description header can be found in signal_processing_library.h.
*
*/
#include "signal_processing_library.h"
// Maximum absolute value of word16 vector.
WebRtc_Word16 WebRtcSpl_MaxAbsValueW16(G_CONST WebRtc_Word16 *vector, WebRtc_Word16 length)
{
WebRtc_Word32 tempMax = 0;
WebRtc_Word32 absVal;
WebRtc_Word16 totMax;
int i;
G_CONST WebRtc_Word16 *tmpvector = vector;
#ifdef _ARM_OPT_
#pragma message("NOTE: _ARM_OPT_ optimizations are used")
WebRtc_Word16 len4 = (length >> 2) << 2;
for (i = 0; i < len4; i = i + 4)
{
absVal = WEBRTC_SPL_ABS_W32((*tmpvector));
if (absVal > tempMax)
{
tempMax = absVal;
}
tmpvector++;
absVal = WEBRTC_SPL_ABS_W32((*tmpvector));
if (absVal > tempMax)
{
tempMax = absVal;
}
tmpvector++;
absVal = WEBRTC_SPL_ABS_W32((*tmpvector));
if (absVal > tempMax)
{
tempMax = absVal;
}
tmpvector++;
absVal = WEBRTC_SPL_ABS_W32((*tmpvector));
if (absVal > tempMax)
{
tempMax = absVal;
}
tmpvector++;
}
for (i = len4; i < len; i++)
{
absVal = WEBRTC_SPL_ABS_W32((*tmpvector));
if (absVal > tempMax)
{
tempMax = absVal;
}
tmpvector++;
}
#else
for (i = 0; i < length; i++)
{
absVal = WEBRTC_SPL_ABS_W32((*tmpvector));
if (absVal > tempMax)
{
tempMax = absVal;
}
tmpvector++;
}
totMax = (WebRtc_Word16)WEBRTC_SPL_MIN(tempMax, WEBRTC_SPL_WORD16_MAX);
return totMax;
#endif
}
// Index of maximum absolute value in a word16 vector.
WebRtc_Word16 WebRtcSpl_MaxAbsIndexW16(G_CONST WebRtc_Word16* vector, WebRtc_Word16 length)
{
WebRtc_Word16 tempMax;
WebRtc_Word16 absTemp;
WebRtc_Word16 tempMaxIndex = 0;
WebRtc_Word16 i = 0;
G_CONST WebRtc_Word16 *tmpvector = vector;
tempMax = WEBRTC_SPL_ABS_W16(*tmpvector);
tmpvector++;
for (i = 1; i < length; i++)
{
absTemp = WEBRTC_SPL_ABS_W16(*tmpvector);
tmpvector++;
if (absTemp > tempMax)
{
tempMax = absTemp;
tempMaxIndex = i;
}
}
return tempMaxIndex;
}
// Maximum absolute value of word32 vector.
WebRtc_Word32 WebRtcSpl_MaxAbsValueW32(G_CONST WebRtc_Word32 *vector, WebRtc_Word16 length)
{
WebRtc_UWord32 tempMax = 0;
WebRtc_UWord32 absVal;
WebRtc_Word32 retval;
int i;
G_CONST WebRtc_Word32 *tmpvector = vector;
for (i = 0; i < length; i++)
{
absVal = WEBRTC_SPL_ABS_W32((*tmpvector));
if (absVal > tempMax)
{
tempMax = absVal;
}
tmpvector++;
}
retval = (WebRtc_Word32)(WEBRTC_SPL_MIN(tempMax, WEBRTC_SPL_WORD32_MAX));
return retval;
}
// Maximum value of word16 vector.
#ifndef XSCALE_OPT
WebRtc_Word16 WebRtcSpl_MaxValueW16(G_CONST WebRtc_Word16* vector, WebRtc_Word16 length)
{
WebRtc_Word16 tempMax;
WebRtc_Word16 i;
G_CONST WebRtc_Word16 *tmpvector = vector;
tempMax = *tmpvector++;
for (i = 1; i < length; i++)
{
if (*tmpvector++ > tempMax)
tempMax = vector[i];
}
return tempMax;
}
#else
#pragma message(">> WebRtcSpl_MaxValueW16 is excluded from this build")
#endif
// Index of maximum value in a word16 vector.
WebRtc_Word16 WebRtcSpl_MaxIndexW16(G_CONST WebRtc_Word16 *vector, WebRtc_Word16 length)
{
WebRtc_Word16 tempMax;
WebRtc_Word16 tempMaxIndex = 0;
WebRtc_Word16 i = 0;
G_CONST WebRtc_Word16 *tmpvector = vector;
tempMax = *tmpvector++;
for (i = 1; i < length; i++)
{
if (*tmpvector++ > tempMax)
{
tempMax = vector[i];
tempMaxIndex = i;
}
}
return tempMaxIndex;
}
// Maximum value of word32 vector.
#ifndef XSCALE_OPT
WebRtc_Word32 WebRtcSpl_MaxValueW32(G_CONST WebRtc_Word32* vector, WebRtc_Word16 length)
{
WebRtc_Word32 tempMax;
WebRtc_Word16 i;
G_CONST WebRtc_Word32 *tmpvector = vector;
tempMax = *tmpvector++;
for (i = 1; i < length; i++)
{
if (*tmpvector++ > tempMax)
tempMax = vector[i];
}
return tempMax;
}
#else
#pragma message(">> WebRtcSpl_MaxValueW32 is excluded from this build")
#endif
// Index of maximum value in a word32 vector.
WebRtc_Word16 WebRtcSpl_MaxIndexW32(G_CONST WebRtc_Word32* vector, WebRtc_Word16 length)
{
WebRtc_Word32 tempMax;
WebRtc_Word16 tempMaxIndex = 0;
WebRtc_Word16 i = 0;
G_CONST WebRtc_Word32 *tmpvector = vector;
tempMax = *tmpvector++;
for (i = 1; i < length; i++)
{
if (*tmpvector++ > tempMax)
{
tempMax = vector[i];
tempMaxIndex = i;
}
}
return tempMaxIndex;
}
// Minimum value of word16 vector.
WebRtc_Word16 WebRtcSpl_MinValueW16(G_CONST WebRtc_Word16 *vector, WebRtc_Word16 length)
{
WebRtc_Word16 tempMin;
WebRtc_Word16 i;
G_CONST WebRtc_Word16 *tmpvector = vector;
// Find the minimum value
tempMin = *tmpvector++;
for (i = 1; i < length; i++)
{
if (*tmpvector++ < tempMin)
tempMin = (vector[i]);
}
return tempMin;
}
// Index of minimum value in a word16 vector.
#ifndef XSCALE_OPT
WebRtc_Word16 WebRtcSpl_MinIndexW16(G_CONST WebRtc_Word16* vector, WebRtc_Word16 length)
{
WebRtc_Word16 tempMin;
WebRtc_Word16 tempMinIndex = 0;
WebRtc_Word16 i = 0;
G_CONST WebRtc_Word16* tmpvector = vector;
// Find index of smallest value
tempMin = *tmpvector++;
for (i = 1; i < length; i++)
{
if (*tmpvector++ < tempMin)
{
tempMin = vector[i];
tempMinIndex = i;
}
}
return tempMinIndex;
}
#else
#pragma message(">> WebRtcSpl_MinIndexW16 is excluded from this build")
#endif
// Minimum value of word32 vector.
WebRtc_Word32 WebRtcSpl_MinValueW32(G_CONST WebRtc_Word32 *vector, WebRtc_Word16 length)
{
WebRtc_Word32 tempMin;
WebRtc_Word16 i;
G_CONST WebRtc_Word32 *tmpvector = vector;
// Find the minimum value
tempMin = *tmpvector++;
for (i = 1; i < length; i++)
{
if (*tmpvector++ < tempMin)
tempMin = (vector[i]);
}
return tempMin;
}
// Index of minimum value in a word32 vector.
#ifndef XSCALE_OPT
WebRtc_Word16 WebRtcSpl_MinIndexW32(G_CONST WebRtc_Word32* vector, WebRtc_Word16 length)
{
WebRtc_Word32 tempMin;
WebRtc_Word16 tempMinIndex = 0;
WebRtc_Word16 i = 0;
G_CONST WebRtc_Word32 *tmpvector = vector;
// Find index of smallest value
tempMin = *tmpvector++;
for (i = 1; i < length; i++)
{
if (*tmpvector++ < tempMin)
{
tempMin = vector[i];
tempMinIndex = i;
}
}
return tempMinIndex;
}
#else
#pragma message(">> WebRtcSpl_MinIndexW32 is excluded from this build")
#endif

Some files were not shown because too many files have changed in this diff Show More