Merge branch 'without-testtool' into Germany
This commit is contained in:
commit
fd9395dd89
|
@ -102,10 +102,8 @@ if ("${CLANG_TIDY_SUPPORT}" MATCHES "true")
|
|||
message(FATAL_ERROR "You set support clang-tidy, but clang-tidy not found.
|
||||
Check path ${LLVM_PATH}/build/bin, weather clang-tidy exist.
|
||||
How to install tools?
|
||||
See ${IPC_SDK_PATH}/doc/clang-tidy_user_guide.md
|
||||
How to disable clang-tidy tool?
|
||||
Modify: set(CLANG_TIDY_SUPPORT \"false\")
|
||||
See:${IPC_SDK_PATH}/builde/global_config.cmake")
|
||||
Execute : make compile_llvm (in the project root directory)
|
||||
Or see ${CMAKE_SOURCE_DIR_IPCSDK}/doc/clang-tidy_user_guide.md")
|
||||
endif()
|
||||
endif()
|
||||
# find the clang-format tools
|
||||
|
|
|
@ -19,7 +19,7 @@
|
|||
|
||||
```code
|
||||
# 项目根目录执行:
|
||||
$ make install-cmake
|
||||
$ make install_cmake
|
||||
```
|
||||
|
||||
### 1.2.2. llvm工具安装
|
||||
|
|
|
@ -20,6 +20,7 @@ include_directories(
|
|||
${MIDDLEWARE_SOURCE_PATH}/McuAskBase/include
|
||||
${MIDDLEWARE_SOURCE_PATH}/HuntingUpgrade/include
|
||||
${MIDDLEWARE_SOURCE_PATH}/DeviceManager/include
|
||||
${MIDDLEWARE_SOURCE_PATH}/IpcConfig/include
|
||||
)
|
||||
#do not rely on any other library
|
||||
#link_directories(
|
||||
|
@ -30,7 +31,7 @@ aux_source_directory(./src SRC_FILES)
|
|||
set(TARGET_NAME MissionManager)
|
||||
add_library(${TARGET_NAME} STATIC ${SRC_FILES})
|
||||
|
||||
target_link_libraries(${TARGET_NAME} McuAskBase StateMachine MediaManager StorageManager DeviceManager HuntingUpgrade KeyControl LedControl StatusCode Log)
|
||||
target_link_libraries(${TARGET_NAME} McuAskBase StateMachine MediaManager StorageManager DeviceManager HuntingUpgrade KeyControl LedControl IpcConfig StatusCode Log)
|
||||
|
||||
add_custom_target(
|
||||
MissionManager_code_check
|
||||
|
|
|
@ -21,8 +21,9 @@ stateDiagram-v2
|
|||
[*] --> TopState
|
||||
TopState --> PowerOff
|
||||
TopState --> MSDCState
|
||||
TopState --> DeviceAbnormal
|
||||
TopState --> MissionState
|
||||
TopState --> DeviceAbnormal
|
||||
TopState --> FormattingSDCard
|
||||
MissionState --> 空闲
|
||||
MissionState --> 存储管理
|
||||
存储管理 --> EMMC
|
||||
|
@ -79,4 +80,10 @@ end
|
|||
|
||||
## 1.4. MCU监视器
|
||||
|
||||
  MCU监视器必须由其中一个状态继承,只有状态机运行之后才能处理串口命令。
|
||||
  MCU监视器必须由其中一个状态继承,只有状态机运行之后才能处理串口命令。
|
||||
|
||||
## 1.5. 测试启动模式(TestMissionState)
|
||||
|
||||
  面向用户开放的测试模式。
|
||||
|
||||
1. 此状态下,先按下format按键不放,再按下reset按键不放可以关闭喂狗功能;
|
||||
|
|
|
@ -14,8 +14,10 @@
|
|||
*/
|
||||
#include "AppMonitor.h"
|
||||
#include "IAppManager.h"
|
||||
#include "IFilesManager.h"
|
||||
#include "ILog.h"
|
||||
#include "IStorageManager.h"
|
||||
#include "MediaTask.h"
|
||||
#include "StatusCode.h"
|
||||
#include <vector>
|
||||
AppMonitor::AppMonitor() : mMicStatus(SwitchStatus::END)
|
||||
|
@ -100,21 +102,42 @@ StatusCode AppMonitor::GetStorageInfo(std::vector<AppGetStorageInfo> ¶m)
|
|||
}
|
||||
StatusCode AppMonitor::GetStorageFileList(const AppGetFileInfo &fileInfo, std::vector<AppGetFileList> ¶m)
|
||||
{
|
||||
if (StorageFileEvent::LOOP == fileInfo.mEvent) {
|
||||
std::vector<SyncFileInfo> info;
|
||||
if (StorageFileEvent::ALL == fileInfo.mEvent) {
|
||||
IFilesManager::GetInstance()->GetAllFiles(info);
|
||||
}
|
||||
else {
|
||||
std::vector<FileCreateType> types;
|
||||
if (StorageFileEvent::LOOP == fileInfo.mEvent) {
|
||||
types.push_back(FileCreateType::TIMED);
|
||||
types.push_back(FileCreateType::MANUAL_TEST);
|
||||
types.push_back(FileCreateType::MANUAL_PHONE);
|
||||
types.push_back(FileCreateType::TIMED);
|
||||
}
|
||||
if (StorageFileEvent::EMR == fileInfo.mEvent) {
|
||||
types.push_back(FileCreateType::PIR);
|
||||
}
|
||||
if (StorageFileEvent::EVENT == fileInfo.mEvent) {
|
||||
types.push_back(FileCreateType::MANUAL_TEST);
|
||||
types.push_back(FileCreateType::MANUAL_PHONE);
|
||||
}
|
||||
if (StorageFileEvent::PARK == fileInfo.mEvent) {
|
||||
types.push_back(FileCreateType::TIMED);
|
||||
}
|
||||
IFilesManager::GetInstance()->GetFiles(types, info);
|
||||
}
|
||||
const std::string webServerDocumentRoot = IAppManager::GetInstance()->GetFilesSavingRootPath();
|
||||
LogInfo("GetStorageFileList: file size = %d, event = %s.\n",
|
||||
info.size(),
|
||||
IAppManager::GetInstance()->StorageFileEventToString(fileInfo.mEvent));
|
||||
for (auto &oneFileInfo : info) {
|
||||
AppGetFileList file;
|
||||
file.mCreateTime_s = 123456789;
|
||||
file.mDuration = 182;
|
||||
file.mName = "/DCIM/2024/01/15/20240115140207-20240115140509.mp4";
|
||||
file.mSize = 1024 * 182;
|
||||
file.mCreateTime_s = oneFileInfo.mCreateTime_s;
|
||||
file.mDuration = oneFileInfo.mFileDuration;
|
||||
file.mName = RemovePrefix(oneFileInfo.mFileName, webServerDocumentRoot);
|
||||
file.mSize = oneFileInfo.mFileSize;
|
||||
file.mType = StorageFileType::VIDEO;
|
||||
param.push_back(file);
|
||||
AppGetFileList file2;
|
||||
file2.mCreateTime_s = 123456789;
|
||||
file2.mDuration = 0;
|
||||
file2.mName = "/34a396526922a33e97906920dbfef2a5.jpg";
|
||||
file2.mSize = 1024;
|
||||
file2.mType = StorageFileType::PICTURE;
|
||||
param.push_back(file2);
|
||||
}
|
||||
return CreateStatusCode(STATUS_CODE_OK);
|
||||
}
|
||||
|
@ -148,7 +171,10 @@ StatusCode AppMonitor::UploadFile(AppUploadFile ¶m)
|
|||
}
|
||||
StatusCode AppMonitor::GetThumbnail(AppGetThumbnail ¶m)
|
||||
{
|
||||
param.mThumbnail = "./34a396526922a33e97906920dbfef2a5.jpg";
|
||||
// param.mThumbnail = "./34a396526922a33e97906920dbfef2a5.jpg";
|
||||
const std::string webServerDocumentRoot = IAppManager::GetInstance()->GetFilesSavingRootPath();
|
||||
const std::string thumbnailFile = MediaTask::GetThumbnailNameByTargetName(param.mFile);
|
||||
param.mThumbnail = thumbnailFile;
|
||||
return CreateStatusCode(STATUS_CODE_OK);
|
||||
}
|
||||
SdCardStatus AppMonitor::SdCardStatusConvert(const StorageEvent &event)
|
||||
|
@ -163,4 +189,12 @@ SdCardStatus AppMonitor::SdCardStatusConvert(const StorageEvent &event)
|
|||
default:
|
||||
return SdCardStatus::END;
|
||||
}
|
||||
}
|
||||
std::string AppMonitor::RemovePrefix(const std::string &originalStr, const std::string &prefix)
|
||||
{
|
||||
if (originalStr.compare(0, prefix.length(), prefix) == 0) {
|
||||
return originalStr.substr(prefix.length());
|
||||
}
|
||||
LogWarning("Something wrong happened, prefix is %s.\n", prefix.c_str());
|
||||
return originalStr;
|
||||
}
|
|
@ -41,6 +41,7 @@ public:
|
|||
|
||||
private:
|
||||
SdCardStatus SdCardStatusConvert(const StorageEvent &event);
|
||||
std::string RemovePrefix(const std::string &originalStr, const std::string &prefix);
|
||||
|
||||
private:
|
||||
SwitchStatus mMicStatus; // TODO: improve delete.
|
||||
|
|
|
@ -24,12 +24,13 @@ using DataProcessingFunc = std::function<bool(VStateMachineData *)>;
|
|||
enum class InternalStateEvent
|
||||
{
|
||||
STORAGE_HANDLE_STATE_INIT = static_cast<int>(MissionEvent::END),
|
||||
SD_CARD_HANDLE_STATE_SD_STATUS_REPORTED,
|
||||
ANY_STATE_SD_STATUS_PERORIED,
|
||||
SD_CARD_HANDLE_STATE_SD_STATUS_REPORTED, ///< Only SdCardHandleState can process this message.
|
||||
ANY_STATE_SD_STATUS_PERORIED, ///< Use it to notify other statuses.
|
||||
CHECK_UPGRADE_FILE,
|
||||
MEDIA_REPORT_EVENT,
|
||||
MEDIA_REPORT_EVENT, ///< Media events proactively reported by the bottom layer.
|
||||
KEY_EVENT_HANDLE,
|
||||
RESET_KEY_MEDIA_TASK,
|
||||
FORMAT_KEY_FORMAT_SD_CARD,
|
||||
MEDIA_HANDLE_STATE_TASK_TIME_OUT,
|
||||
MEDIA_HANDLE_STATE_TASK_FINISHED,
|
||||
END
|
||||
|
|
93
application/MissionManager/src/FormattingState.cpp
Normal file
93
application/MissionManager/src/FormattingState.cpp
Normal file
|
@ -0,0 +1,93 @@
|
|||
/*
|
||||
* Copyright (c) 2023 Fancy Code.
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
#include "FormattingState.h"
|
||||
#include "DataProcessing.h"
|
||||
#include "IFilesManager.h"
|
||||
#include "ILog.h"
|
||||
#include "IMissionManager.h"
|
||||
#include "IStateMachine.h"
|
||||
#include "IStorageManager.h"
|
||||
#include "LedControl.h"
|
||||
#include "LedsHandle.h"
|
||||
#include "MissionStateMachine.h"
|
||||
#include <functional>
|
||||
#include <memory>
|
||||
using std::placeholders::_1;
|
||||
FormattingState::FormattingState() : State("FormattingState"), mFormatting(false)
|
||||
{
|
||||
mEventHandle[InternalStateEvent::FORMAT_KEY_FORMAT_SD_CARD] =
|
||||
std::bind(&FormattingState::FormatKeyFormattingSDCardHandle, this, _1);
|
||||
mEventHandle[InternalStateEvent::SD_CARD_HANDLE_STATE_SD_STATUS_REPORTED] =
|
||||
std::bind(&FormattingState::ComfirmFormatResult, this, _1);
|
||||
}
|
||||
void FormattingState::GoInState()
|
||||
{
|
||||
LogInfo(" ========== FormattingState::GoInState.\n");
|
||||
}
|
||||
void FormattingState::GoOutState()
|
||||
{
|
||||
LogInfo(" ========== FormattingState::GoOutState.\n");
|
||||
if (mFormattingThread.joinable()) {
|
||||
mFormattingThread.join();
|
||||
}
|
||||
mFormatting = false;
|
||||
LedsHandle::DeleteAllLeds();
|
||||
}
|
||||
bool FormattingState::ExecuteStateMsg(VStateMachineData *msg)
|
||||
{
|
||||
return DataProcessing::EventHandle(msg);
|
||||
}
|
||||
void FormattingState::StateInit(void)
|
||||
{
|
||||
}
|
||||
void FormattingState::StateUnInit(void)
|
||||
{
|
||||
if (mFormattingThread.joinable()) {
|
||||
mFormattingThread.join();
|
||||
}
|
||||
}
|
||||
bool FormattingState::FormatKeyFormattingSDCardHandle(VStateMachineData *msg)
|
||||
{
|
||||
LogInfo("Now formatting SD card.\n");
|
||||
auto formatting = [](std::shared_ptr<FormattingState> impl) {
|
||||
impl->FormattingThread();
|
||||
};
|
||||
mFormatting = true;
|
||||
mFormattingThread = std::thread(formatting, shared_from_this());
|
||||
return EXECUTED;
|
||||
}
|
||||
bool FormattingState::ComfirmFormatResult(VStateMachineData *msg)
|
||||
{
|
||||
std::shared_ptr<MissionMessage> message = std::dynamic_pointer_cast<MissionMessage>(msg->GetMessageObj());
|
||||
std::shared_ptr<VMissionDataV2<StorageEvent>> data =
|
||||
std::dynamic_pointer_cast<VMissionDataV2<StorageEvent>>(message->mMissionData);
|
||||
LogInfo(" SdCardEventHandle event:%s.\n", IStorageManager::GetInstance()->PrintStringStorageEvent(data->mData));
|
||||
if (StorageEvent::SD_CARD_INSERT == data->mData) {
|
||||
LogInfo(" SD card inserted. Format sd card final finished.\n");
|
||||
// MissionStateMachine::GetInstance()->SwitchState(SystemState::IDLE_STATE);
|
||||
MissionStateMachine::GetInstance()->DelayMessage(msg);
|
||||
MissionStateMachine::GetInstance()->SwitchState(SystemState::SD_CARD_HANDLE_STATE);
|
||||
}
|
||||
return EXECUTED;
|
||||
}
|
||||
void FormattingState::FormattingThread(void)
|
||||
{
|
||||
LedsHandle::ControlDeviceStatusLed(DeviceStatus::FORMATTING, KEEP_ALIVE_FOREVER, BLINKING_FAST_MS);
|
||||
IFilesManager::GetInstance()->UnInit();
|
||||
IStorageManager::GetInstance()->FormatSDCardNow();
|
||||
// IFilesManager::GetInstance()->Init();
|
||||
// MissionStateMachine::GetInstance()->SwitchState(SystemState::IDLE_STATE);
|
||||
LogInfo("Formatting SD card done.\n");
|
||||
}
|
50
application/MissionManager/src/FormattingState.h
Normal file
50
application/MissionManager/src/FormattingState.h
Normal file
|
@ -0,0 +1,50 @@
|
|||
/*
|
||||
* Copyright (c) 2023 Fancy Code.
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
#ifndef FORMATTING_STATE_H
|
||||
#define FORMATTING_STATE_H
|
||||
#include "DataProcessing.h"
|
||||
#include "IFilesManager.h"
|
||||
#include "IMediaManager.h"
|
||||
#include "IStateMachine.h"
|
||||
#include "IStorageManager.h"
|
||||
#include "LedsHandle.h"
|
||||
#include "VStateBase.h"
|
||||
#include <thread>
|
||||
class FormattingState : public State,
|
||||
public DataProcessing,
|
||||
public VStateBase,
|
||||
public LedsHandle,
|
||||
public std::enable_shared_from_this<FormattingState>
|
||||
{
|
||||
public:
|
||||
FormattingState();
|
||||
virtual ~FormattingState() = default;
|
||||
void GoInState() override;
|
||||
void GoOutState() override;
|
||||
bool ExecuteStateMsg(VStateMachineData *msg) override;
|
||||
|
||||
protected:
|
||||
void StateInit(void) override;
|
||||
void StateUnInit(void) override;
|
||||
bool FormatKeyFormattingSDCardHandle(VStateMachineData *msg);
|
||||
bool ComfirmFormatResult(VStateMachineData *msg);
|
||||
void FormattingThread(void);
|
||||
|
||||
private:
|
||||
bool mFormatting;
|
||||
std::thread mFormattingThread;
|
||||
};
|
||||
|
||||
#endif
|
|
@ -20,10 +20,9 @@
|
|||
#include <functional>
|
||||
IdleState::IdleState() : State("IdleState")
|
||||
{
|
||||
// mEventHandle[InternalStateEvent::MEDIA_REPORT_EVENT] = std::bind(&IdleState::MediaReportHandle, this, _1);
|
||||
// mEventHandle[InternalStateEvent::SD_CARD_HANDLE_STATE_SD_STATUS_REPORTED] =
|
||||
// std::bind(&IdleState::SdCardEventHandle, this, _1);
|
||||
mEventHandle[InternalStateEvent::RESET_KEY_MEDIA_TASK] = std::bind(&IdleState::ResetKeyMediaTaskHandle, this, _1);
|
||||
mEventHandle[InternalStateEvent::FORMAT_KEY_FORMAT_SD_CARD] =
|
||||
std::bind(&IdleState::FormatKeyFormattingSDCardHandle, this, _1);
|
||||
}
|
||||
void IdleState::GoInState()
|
||||
{
|
||||
|
@ -38,6 +37,12 @@ bool IdleState::ExecuteStateMsg(VStateMachineData *msg)
|
|||
return DataProcessing::EventHandle(msg);
|
||||
}
|
||||
bool IdleState::ResetKeyMediaTaskHandle(VStateMachineData *msg)
|
||||
{
|
||||
MissionStateMachine::GetInstance()->DelayMessage(msg);
|
||||
MissionStateMachine::GetInstance()->SwitchState(SystemState::STORAGE_HANDLE_STATE);
|
||||
return EXECUTED;
|
||||
}
|
||||
bool IdleState::FormatKeyFormattingSDCardHandle(VStateMachineData *msg)
|
||||
{
|
||||
MissionStateMachine::GetInstance()->DelayMessage(msg);
|
||||
MissionStateMachine::GetInstance()->SwitchState(SystemState::STORAGE_HANDLE_STATE);
|
||||
|
|
|
@ -27,6 +27,7 @@ public:
|
|||
|
||||
private:
|
||||
bool ResetKeyMediaTaskHandle(VStateMachineData *msg);
|
||||
bool FormatKeyFormattingSDCardHandle(VStateMachineData *msg);
|
||||
|
||||
private:
|
||||
};
|
||||
|
|
|
@ -16,22 +16,57 @@
|
|||
#include "ILog.h"
|
||||
#include "LedControl.h"
|
||||
#include "SetLedState.h"
|
||||
LedsHandle::LedsHandle() : mDeviceStatusFlag(DeviceStatus::END)
|
||||
{
|
||||
}
|
||||
void LedsHandle::ControlDeviceStatusLed(const DeviceStatus &status, const long int &keepAliveTime,
|
||||
const unsigned int &blinkPeriod)
|
||||
{
|
||||
if (KEEP_ALIVE_FOREVER == keepAliveTime) {
|
||||
/**
|
||||
* @brief For a specific state instance, when controlling the same indicator light, if the permanently
|
||||
* maintained state changes, the original state needs to be overwritten.
|
||||
*/
|
||||
DeleteDeviceStatusLed();
|
||||
}
|
||||
switch (status) {
|
||||
case DeviceStatus::NORMAL:
|
||||
mDeviceStatus = SetLedState::ControlLed("device_status", LedState::GREEN, keepAliveTime, blinkPeriod);
|
||||
break;
|
||||
case DeviceStatus::FORMAT_KEY_HOLD_DOWN_TIPS:
|
||||
// if (DeviceStatus::FORMAT_KEY_HOLD_DOWN_TIPS == mDeviceStatusFlag) {
|
||||
// break;
|
||||
// }
|
||||
mDeviceStatus = SetLedState::ControlLed("device_status", LedState::RED, keepAliveTime, blinkPeriod);
|
||||
break;
|
||||
case DeviceStatus::FORMATTING:
|
||||
mDeviceStatus = SetLedState::ControlLed("device_status", LedState::RED, keepAliveTime, blinkPeriod);
|
||||
break;
|
||||
case DeviceStatus::SD_CARD_REMOVE:
|
||||
mDeviceStatus = SetLedState::ControlLed("device_status", LedState::GREEN, keepAliveTime, blinkPeriod);
|
||||
break;
|
||||
case DeviceStatus::SD_CARD_ABNORMAL:
|
||||
mDeviceStatus = SetLedState::ControlLed("device_status", LedState::RED, keepAliveTime, blinkPeriod);
|
||||
break;
|
||||
case DeviceStatus::TAKING_PICTURE_OR_VIDEO:
|
||||
mDeviceStatus = SetLedState::ControlLed("device_status", LedState::GREEN, keepAliveTime, blinkPeriod);
|
||||
break;
|
||||
case DeviceStatus::CLOSE_WATCHDOG:
|
||||
mDeviceStatus = SetLedState::ControlLed("device_status", LedState::RED, keepAliveTime, blinkPeriod);
|
||||
break;
|
||||
|
||||
default:
|
||||
LogWarning("unknow device status.\n");
|
||||
break;
|
||||
}
|
||||
mDeviceStatusFlag = status;
|
||||
}
|
||||
void inline LedsHandle::DeleteDeviceStatusLed(void)
|
||||
void LedsHandle::DeleteDeviceStatusLed(void)
|
||||
{
|
||||
mDeviceStatus->DeleteState();
|
||||
if (mDeviceStatus) {
|
||||
mDeviceStatus->DeleteState();
|
||||
mDeviceStatus.reset();
|
||||
}
|
||||
}
|
||||
void LedsHandle::DeleteAllLeds(void)
|
||||
{
|
||||
|
|
|
@ -19,12 +19,21 @@ enum class DeviceStatus
|
|||
{
|
||||
NORMAL = 0,
|
||||
TAKING_PICTURE_OR_VIDEO,
|
||||
FORMATTING, ///< Prompt the user that the formatting operation is being performed.
|
||||
FORMAT_KEY_HOLD_DOWN_TIPS, ///< Prompt the user that the format button has been pressed.
|
||||
SD_CARD_REMOVE,
|
||||
SD_CARD_INSERT,
|
||||
SD_CARD_ABNORMAL,
|
||||
CLOSE_WATCHDOG,
|
||||
END
|
||||
};
|
||||
/**
|
||||
* @brief LedsHandle-LED light control class, mainly used to inherit LED light control functions in different states.
|
||||
*/
|
||||
class LedsHandle
|
||||
{
|
||||
public:
|
||||
LedsHandle() = default;
|
||||
LedsHandle();
|
||||
virtual ~LedsHandle() = default;
|
||||
|
||||
protected:
|
||||
|
@ -41,6 +50,12 @@ protected:
|
|||
void DeleteAllLeds(void);
|
||||
|
||||
private:
|
||||
std::shared_ptr<SetLedState> mDeviceStatus;
|
||||
/**
|
||||
* @brief Definitions of various LED indicators.
|
||||
* NOTE: When indicator lights with different functions switch states, the previous light state should be cleared by
|
||||
* calling the DeleteState function.
|
||||
*/
|
||||
std::shared_ptr<SetLedState> mDeviceStatus; ///< Device status indicator.
|
||||
DeviceStatus mDeviceStatusFlag;
|
||||
};
|
||||
#endif
|
|
@ -19,6 +19,8 @@
|
|||
#include "IMediaManager.h"
|
||||
#include "IMissionManager.h"
|
||||
#include "IStateMachine.h"
|
||||
#include "LedControl.h"
|
||||
#include "LedsHandle.h"
|
||||
#include "MediaTask.h"
|
||||
#include "MediaTaskHandle.h"
|
||||
#include "MissionStateMachine.h"
|
||||
|
@ -42,6 +44,7 @@ void MediaHandleState::GoInState()
|
|||
void MediaHandleState::GoOutState()
|
||||
{
|
||||
LogInfo(" ========== MediaHandleState::GoOutState.\n");
|
||||
LedsHandle::DeleteAllLeds();
|
||||
}
|
||||
bool MediaHandleState::ExecuteStateMsg(VStateMachineData *msg)
|
||||
{
|
||||
|
@ -56,6 +59,8 @@ void MediaHandleState::TaskResponse(const MediaTaskInfo &taskinfo)
|
|||
bool MediaHandleState::ResetKeyMediaTaskHandle(VStateMachineData *msg)
|
||||
{
|
||||
MediaTaskHandle::MakeSingleTask(InternalStateEvent::RESET_KEY_MEDIA_TASK, shared_from_this());
|
||||
LedsHandle::ControlDeviceStatusLed(
|
||||
DeviceStatus::TAKING_PICTURE_OR_VIDEO, KEEP_ALIVE_FOREVER, BLINKING_SUPER_FAST_MS);
|
||||
return EXECUTED;
|
||||
}
|
||||
bool MediaHandleState::MediaTaskFinishedHandle(VStateMachineData *msg)
|
||||
|
@ -66,9 +71,18 @@ bool MediaHandleState::MediaTaskFinishedHandle(VStateMachineData *msg)
|
|||
LogInfo("response files = %d.\n", data->mData.mResponse.size());
|
||||
std::vector<SyncFileInfo> files;
|
||||
for (auto &response : data->mData.mResponse) {
|
||||
SyncFileInfo file(data->mData.mSerialNumber, response.mFileName, 0, 0, FileCreateType::END, FileStatus::END);
|
||||
auto fileSize = MediaTask::GetFileSize_KB(response.mFileName.c_str());
|
||||
SyncFileInfo file(data->mData.mSerialNumber,
|
||||
response.mFileName,
|
||||
fileSize,
|
||||
response.mDuration_ms,
|
||||
data->mData.mCreateTime_s,
|
||||
FileCreateType::MANUAL_TEST,
|
||||
FileStatus::FINISHED_RECORD);
|
||||
files.push_back(file);
|
||||
}
|
||||
IFilesManager::GetInstance()->SaveFiles(files);
|
||||
LedsHandle::DeleteDeviceStatusLed();
|
||||
MissionStateMachine::GetInstance()->SwitchState(SystemState::IDLE_STATE);
|
||||
return EXECUTED;
|
||||
}
|
|
@ -16,11 +16,13 @@
|
|||
#define MEDIA_HANDLE_STATE_H
|
||||
#include "DataProcessing.h"
|
||||
#include "IStateMachine.h"
|
||||
#include "LedsHandle.h"
|
||||
#include "MediaTaskHandle.h"
|
||||
class MediaHandleState : public State,
|
||||
public DataProcessing,
|
||||
public MediaTaskHandle,
|
||||
public VMediaTaskIniator,
|
||||
public LedsHandle,
|
||||
public std::enable_shared_from_this<MediaHandleState>
|
||||
{
|
||||
public:
|
||||
|
|
|
@ -14,6 +14,7 @@
|
|||
*/
|
||||
#include "MediaTask.h"
|
||||
#include "DataProcessing.h"
|
||||
#include "IIpcConfig.h"
|
||||
#include "ILog.h"
|
||||
#include "IMediaManager.h"
|
||||
#include <cctype>
|
||||
|
@ -25,32 +26,43 @@
|
|||
#include <memory>
|
||||
#include <sstream>
|
||||
#include <string>
|
||||
#include <sys/stat.h>
|
||||
#include <vector>
|
||||
MediaTask::MediaTask(const MediaTaskType &type, const InternalStateEvent &bindEvent,
|
||||
const std::weak_ptr<VMediaTaskIniator> &iniator, const unsigned long &serialNumber,
|
||||
const std::string &savePath)
|
||||
: mType(type), mBindEvent(bindEvent), mIniator(iniator), mSerialNumber(serialNumber), mSavePath(savePath)
|
||||
: mType(type), mBindEvent(bindEvent), mIniator(iniator), mSerialNumber(serialNumber), mSavePath(savePath),
|
||||
mCreateTime_s(0)
|
||||
{
|
||||
mResponseData.reset();
|
||||
mTargetName.clear();
|
||||
}
|
||||
unsigned int MediaTask::GetTaskTimeOutMs(void)
|
||||
{
|
||||
return MEDIA_TASK_TIMEOUT_MS;
|
||||
}
|
||||
const MediaTaskType MediaTask::GetTaskType(void)
|
||||
{
|
||||
return mType;
|
||||
}
|
||||
std::string MediaTask::GetTargetNameForSaving(void)
|
||||
{
|
||||
if (!mTargetName.empty()) {
|
||||
return mTargetName;
|
||||
}
|
||||
auto now = std::chrono::system_clock::now();
|
||||
time_t t_now = std::chrono::system_clock::to_time_t(now);
|
||||
struct tm tm_now = *std::localtime(&t_now);
|
||||
|
||||
int hour = tm_now.tm_hour;
|
||||
int minute = tm_now.tm_min;
|
||||
int second = tm_now.tm_sec;
|
||||
|
||||
std::ostringstream pathStream;
|
||||
pathStream << mSavePath << std::setw(2) << std::setfill('0') << hour << std::setw(2) << std::setfill('0') << minute
|
||||
<< std::setw(2) << std::setfill('0') << second << ".mp4";
|
||||
return pathStream.str();
|
||||
mCreateTime_s = std::chrono::duration_cast<std::chrono::seconds>(now.time_since_epoch()).count();
|
||||
const std::string fileType = MediaTaskType::TAKE_VIDEO == mType ? ".mp4" : ".jpeg";
|
||||
return CreateFileName(mSerialNumber, mSavePath, fileType);
|
||||
}
|
||||
std::string MediaTask::GetThumbnailNameForSaving(const std::string &targetName)
|
||||
{
|
||||
return MediaTask::GetThumbnailNameByTargetName(targetName);
|
||||
}
|
||||
int MediaTask::GetVideoDuration_ms(void)
|
||||
{
|
||||
return DEFAULT_VIDEO_DURATION_MS;
|
||||
}
|
||||
void MediaTask::Response(const std::vector<MediaTaskResponse> &response)
|
||||
{
|
||||
|
@ -63,6 +75,87 @@ void MediaTask::Response(const std::vector<MediaTaskResponse> &response)
|
|||
MediaTaskInfo info = {
|
||||
.mResponse = response,
|
||||
.mSerialNumber = mSerialNumber,
|
||||
.mCreateTime_s = mCreateTime_s,
|
||||
};
|
||||
iniator->TaskResponse(info);
|
||||
}
|
||||
std::string MediaTask::GetThumbnailNameByTargetName(const std::string &targetName)
|
||||
{
|
||||
// const std::string fileType = MediaTaskType::TAKE_VIDEO == mType ? ".mp4" : ".jpeg";
|
||||
std::string thumbnailName = targetName;
|
||||
size_t dot_pos = thumbnailName.find_last_of('.');
|
||||
if (dot_pos != std::string::npos) {
|
||||
std::string extension = thumbnailName.substr(dot_pos);
|
||||
if (extension == ".mp4" || extension == ".jpeg") {
|
||||
thumbnailName.replace(dot_pos, extension.length(), "-thumbnail.jpeg");
|
||||
LogInfo("GetThumbnailNameForSaving: %s\n", thumbnailName.c_str());
|
||||
return thumbnailName;
|
||||
}
|
||||
}
|
||||
LogError("TargetName is not a mp4 file.\n");
|
||||
std::string unknowFile = "unknow";
|
||||
return unknowFile;
|
||||
}
|
||||
long long MediaTask::GetCreateTime_s(void)
|
||||
{
|
||||
auto now = std::chrono::system_clock::now();
|
||||
// time_t t_now = std::chrono::system_clock::to_time_t(now);
|
||||
// struct tm tm_now = *std::localtime(&t_now);
|
||||
|
||||
return std::chrono::duration_cast<std::chrono::seconds>(now.time_since_epoch()).count();
|
||||
}
|
||||
int MediaTask::GetFileSize_KB(const char *filePath)
|
||||
{
|
||||
struct stat fileInfo;
|
||||
if (stat(filePath, &fileInfo) != 0) {
|
||||
LogError("stat failed.\n");
|
||||
return FILE_SIZE_ERROR;
|
||||
}
|
||||
return static_cast<double>(fileInfo.st_size) / 1024.0;
|
||||
}
|
||||
MediaTaskType MediaTask::WorkModeConvert(const WorkMode &mode)
|
||||
{
|
||||
switch (mode) {
|
||||
case WorkMode::MODE_PIC:
|
||||
return MediaTaskType::TAKE_PICTURE;
|
||||
case WorkMode::MODE_VIDEO:
|
||||
return MediaTaskType::TAKE_VIDEO;
|
||||
case WorkMode::MODE_PIC_VIDEO:
|
||||
return MediaTaskType::TAKE_PICTURE_AND_VIDEO;
|
||||
|
||||
default:
|
||||
LogWarning("unknow work mode.\n");
|
||||
return MediaTaskType::TAKE_PICTURE_AND_VIDEO;
|
||||
}
|
||||
}
|
||||
std::string MediaTask::GetFileNameBySeriaNumber(const unsigned long &serialNumber, const std::string &sourceFile,
|
||||
const std::string &savePaht)
|
||||
{
|
||||
std::string fileType = "";
|
||||
size_t dot_pos = sourceFile.find_last_of('.');
|
||||
if (dot_pos != std::string::npos) {
|
||||
std::string extension = sourceFile.substr(dot_pos);
|
||||
fileType = extension;
|
||||
}
|
||||
return CreateFileName(serialNumber, savePaht, fileType);
|
||||
}
|
||||
std::string MediaTask::CreateFileName(const unsigned long &serialNumber, const std::string &savePaht,
|
||||
const std::string &fileType)
|
||||
{
|
||||
auto now = std::chrono::system_clock::now();
|
||||
time_t t_now = std::chrono::system_clock::to_time_t(now);
|
||||
struct tm tm_now = *std::localtime(&t_now);
|
||||
/**
|
||||
* @brief When the sequence number is 0, it indicates an invalid sequence number and is replaced by "???".
|
||||
*
|
||||
*/
|
||||
const std::string serialNumberString = 0 == serialNumber ? "???" : std::to_string(serialNumber);
|
||||
int hour = tm_now.tm_hour;
|
||||
int minute = tm_now.tm_min;
|
||||
int second = tm_now.tm_sec;
|
||||
std::ostringstream pathStream;
|
||||
pathStream << savePaht << "xak47-" << serialNumberString << "-" << std::setw(2) << std::setfill('0') << hour
|
||||
<< std::setw(2) << std::setfill('0') << minute << std::setw(2) << std::setfill('0') << second
|
||||
<< fileType;
|
||||
return pathStream.str();
|
||||
}
|
|
@ -15,13 +15,18 @@
|
|||
#ifndef MEDIA_TASK_H
|
||||
#define MEDIA_TASK_H
|
||||
#include "DataProcessing.h"
|
||||
#include "IIpcConfig.h"
|
||||
#include "IMediaManager.h"
|
||||
#include <string>
|
||||
#include <vector>
|
||||
constexpr int FILE_SIZE_ERROR = -1;
|
||||
constexpr unsigned int MEDIA_TASK_TIMEOUT_MS = 1000 * 60;
|
||||
constexpr int DEFAULT_VIDEO_DURATION_MS = 1000 * 10;
|
||||
typedef struct media_task_info
|
||||
{
|
||||
const std::vector<MediaTaskResponse> mResponse;
|
||||
const unsigned long mSerialNumber;
|
||||
const long long mCreateTime_s;
|
||||
} MediaTaskInfo;
|
||||
class VMediaTaskIniator
|
||||
{
|
||||
|
@ -38,9 +43,22 @@ public:
|
|||
const std::string &savePath);
|
||||
virtual ~MediaTask() = default;
|
||||
virtual unsigned int GetTaskTimeOutMs(void);
|
||||
const MediaTaskType GetTaskType(void) override;
|
||||
std::string GetTargetNameForSaving(void) override;
|
||||
std::string GetThumbnailNameForSaving(const std::string &targetName) override;
|
||||
int GetVideoDuration_ms(void) override;
|
||||
void Response(const std::vector<MediaTaskResponse> &response) override;
|
||||
|
||||
public:
|
||||
static std::string GetThumbnailNameByTargetName(const std::string &targetName);
|
||||
static long long GetCreateTime_s(void);
|
||||
static int GetFileSize_KB(const char *filePath);
|
||||
static MediaTaskType WorkModeConvert(const WorkMode &mode);
|
||||
static std::string GetFileNameBySeriaNumber(const unsigned long &serialNumber, const std::string &sourceFile,
|
||||
const std::string &savePaht);
|
||||
static std::string CreateFileName(const unsigned long &serialNumber, const std::string &savePaht,
|
||||
const std::string &fileType);
|
||||
|
||||
private:
|
||||
const MediaTaskType mType;
|
||||
const InternalStateEvent mBindEvent;
|
||||
|
@ -49,5 +67,8 @@ private:
|
|||
const std::string mSavePath;
|
||||
bool mFinished = false;
|
||||
std::shared_ptr<MediaTaskResponse> mResponseData;
|
||||
std::string mTargetName;
|
||||
long long mCreateTime_s;
|
||||
std::vector<std::string> mTargetNameList;
|
||||
};
|
||||
#endif
|
|
@ -15,6 +15,7 @@
|
|||
#include "MediaTaskHandle.h"
|
||||
#include "DataProcessing.h"
|
||||
#include "IFilesManager.h"
|
||||
#include "IIpcConfig.h"
|
||||
#include "ILog.h"
|
||||
#include "IMediaManager.h"
|
||||
#include "IMissionManager.h"
|
||||
|
@ -40,8 +41,11 @@ void MediaTaskHandle::MakeSingleTask(const InternalStateEvent &bindEvent,
|
|||
const std::shared_ptr<VMediaTaskIniator> &iniator)
|
||||
{
|
||||
InfoToBeSaved info = IFilesManager::GetInstance()->GetInfoForSavingFiles(1);
|
||||
WorkMode workMode = IIpcConfig::GetInstance()->GetWorkMode();
|
||||
MediaTaskType taskType = MediaTask::WorkModeConvert(workMode);
|
||||
LogInfo("taskType: %s\n", IMediaManager::PrintfTaskType(taskType));
|
||||
std::shared_ptr<VMediaTask> task =
|
||||
std::make_shared<MediaTask>(MediaTaskType::END, bindEvent, iniator, info.mSerialNumber, info.mSavingPath);
|
||||
std::make_shared<MediaTask>(taskType, bindEvent, iniator, info.mSerialNumber, info.mSavingPath);
|
||||
if (!mMediaHandle) {
|
||||
LogError("MediaHandle is null");
|
||||
return;
|
||||
|
|
|
@ -15,6 +15,7 @@
|
|||
#ifndef MEDIA_TASK_HANDLE_H
|
||||
#define MEDIA_TASK_HANDLE_H
|
||||
#include "DataProcessing.h"
|
||||
#include "IIpcConfig.h"
|
||||
#include "IMediaManager.h"
|
||||
#include "MediaTask.h"
|
||||
class MediaTaskHandle
|
||||
|
|
|
@ -13,6 +13,7 @@
|
|||
* limitations under the License.
|
||||
*/
|
||||
#include "MissionManagerMakePtr.h"
|
||||
#include "FormattingState.h"
|
||||
#include "ILog.h"
|
||||
#include "IMcuManager.h"
|
||||
#include "IMissionManager.h"
|
||||
|
@ -120,4 +121,9 @@ std::shared_ptr<State> MissionManagerMakePtr::CreateIdleState(void)
|
|||
{
|
||||
std::shared_ptr<State> state = std::make_shared<IdleState>();
|
||||
return state;
|
||||
}
|
||||
std::shared_ptr<State> MissionManagerMakePtr::CreateFormattingState(void)
|
||||
{
|
||||
std::shared_ptr<State> state = std::make_shared<FormattingState>();
|
||||
return state;
|
||||
}
|
|
@ -33,5 +33,6 @@ public:
|
|||
virtual std::shared_ptr<State> CreateUpgradeState(void);
|
||||
virtual std::shared_ptr<State> CreateMediaHandleState(void);
|
||||
virtual std::shared_ptr<State> CreateIdleState(void);
|
||||
virtual std::shared_ptr<State> CreateFormattingState(void);
|
||||
};
|
||||
#endif
|
|
@ -42,6 +42,25 @@ bool MissionState::ExecuteStateMsg(VStateMachineData *msg)
|
|||
}
|
||||
bool MissionState::MediaReportHandle(VStateMachineData *msg)
|
||||
{
|
||||
LogInfo("Get media file from chip.\n");
|
||||
// std::shared_ptr<MissionMessage> message = std::dynamic_pointer_cast<MissionMessage>(msg->GetMessageObj());
|
||||
// std::shared_ptr<VMissionDataV2<MediaReportEvent>> data =
|
||||
// std::dynamic_pointer_cast<VMissionDataV2<MediaReportEvent>>(message->mMissionData);
|
||||
// if (!data) {
|
||||
// LogError("nullptr pointer.\n");
|
||||
// return NOT_EXECUTED;
|
||||
// }
|
||||
// auto fileSize = MediaTask::GetFileSize_KB(data->mData.mFileName.c_str());
|
||||
// auto createTime = MediaTask::GetCreateTime_s();
|
||||
// auto createType = MissionStateMachine::GetInstance()->GetFileCreateType();
|
||||
// SyncFileInfo file(UNDEFINE_SERIAL_NUMBER,
|
||||
// data->mData.mFileName,
|
||||
// fileSize,
|
||||
// data->mData.mDuration_ms,
|
||||
// createTime,
|
||||
// createType,
|
||||
// FileStatus::FINISHED_RECORD);
|
||||
// mFastStartMediaFiles.push_back(file);
|
||||
MissionStateMachine::GetInstance()->DelayMessage(msg);
|
||||
MissionStateMachine::GetInstance()->SwitchState(SystemState::STORAGE_HANDLE_STATE);
|
||||
return EXECUTED;
|
||||
|
|
|
@ -15,6 +15,7 @@
|
|||
#ifndef MISSION_STATE_H
|
||||
#define MISSION_STATE_H
|
||||
#include "DataProcessing.h"
|
||||
#include "IFilesManager.h"
|
||||
#include "IStateMachine.h"
|
||||
#include "LedsHandle.h"
|
||||
class MissionState : public State,
|
||||
|
@ -33,7 +34,17 @@ protected:
|
|||
bool SdCardEventReportHandle(VStateMachineData *msg);
|
||||
|
||||
private:
|
||||
/**
|
||||
* @brief Processes media events actively reported by the bottom layer, and refers to snapshot or video recording
|
||||
* during quick start.
|
||||
* @param msg
|
||||
* @return true
|
||||
* @return false
|
||||
*/
|
||||
bool MediaReportHandle(VStateMachineData *msg);
|
||||
bool CheckUpgradeFileHandle(VStateMachineData *msg);
|
||||
|
||||
private:
|
||||
std::vector<SyncFileInfo> mFastStartMediaFiles;
|
||||
};
|
||||
#endif
|
|
@ -14,6 +14,7 @@
|
|||
*/
|
||||
#include "MissionStateMachine.h"
|
||||
#include "DataProcessing.h"
|
||||
#include "IFilesManager.h"
|
||||
#include "ILog.h"
|
||||
#include "IMcuManager.h"
|
||||
#include "IMissionManager.h"
|
||||
|
@ -82,6 +83,19 @@ void MissionStateMachine::SwitchState(const SystemState &state)
|
|||
{
|
||||
mStateMachine->SwitchState(mStateTree[state].get());
|
||||
}
|
||||
FileCreateType MissionStateMachine::GetFileCreateType(void)
|
||||
{
|
||||
switch (mStartMission) {
|
||||
case IpcMission::TEST:
|
||||
return FileCreateType::MANUAL_TEST;
|
||||
case IpcMission::PIR_TRIGGERED:
|
||||
return FileCreateType::PIR;
|
||||
|
||||
default:
|
||||
LogError("unknow ipcmission.\n");
|
||||
return FileCreateType::END;
|
||||
}
|
||||
}
|
||||
IpcMission MissionStateMachine::GetStartMission(void)
|
||||
{
|
||||
class McuAskIpcMission : public McuAsk<IpcMission>, public McuAskBase
|
||||
|
@ -108,8 +122,10 @@ void MissionStateMachine::RunStateMachine(const IpcMission &mission)
|
|||
mStateTree[SystemState::UPGRADE_STATE] = MissionManagerMakePtr::GetInstance()->CreateUpgradeState();
|
||||
mStateTree[SystemState::MEDIA_HANDLE_STATE] = MissionManagerMakePtr::GetInstance()->CreateMediaHandleState();
|
||||
mStateTree[SystemState::IDLE_STATE] = MissionManagerMakePtr::GetInstance()->CreateIdleState();
|
||||
mStateTree[SystemState::FORMATTING_STATE] = MissionManagerMakePtr::GetInstance()->CreateFormattingState();
|
||||
mStateMachine->StatePlus(mStateTree[SystemState::TOP_STATE].get(), nullptr);
|
||||
mStateMachine->StatePlus(mStateTree[SystemState::MISSION_STATE].get(), mStateTree[SystemState::TOP_STATE].get());
|
||||
mStateMachine->StatePlus(mStateTree[SystemState::FORMATTING_STATE].get(), mStateTree[SystemState::TOP_STATE].get());
|
||||
mStateMachine->StatePlus(mStateTree[SystemState::STORAGE_HANDLE_STATE].get(),
|
||||
mStateTree[SystemState::MISSION_STATE].get());
|
||||
mStateMachine->StatePlus(mStateTree[SystemState::SD_CARD_HANDLE_STATE].get(),
|
||||
|
@ -121,13 +137,6 @@ void MissionStateMachine::RunStateMachine(const IpcMission &mission)
|
|||
mStateMachine->StatePlus(mStateTree[SystemState::IDLE_STATE].get(), mStateTree[SystemState::MISSION_STATE].get());
|
||||
mStateMachine->SetCurrentState(mStateTree[SystemState::TOP_STATE].get());
|
||||
mStateMachine->StartStateMachine();
|
||||
// /**
|
||||
// * @brief The business can only be processed after the state machine is started.
|
||||
// *
|
||||
// */
|
||||
// std::shared_ptr<VMissionData> message =
|
||||
// std::make_shared<VMissionData>(static_cast<MissionEvent>(InternalStateEvent::STORAGE_HANDLE_STATE_INIT));
|
||||
// SendStateMessage(message);
|
||||
InitAllState();
|
||||
}
|
||||
void MissionStateMachine::InitAllState(void)
|
||||
|
|
|
@ -15,6 +15,7 @@
|
|||
#ifndef MISSION_STATE_MACHINE_H
|
||||
#define MISSION_STATE_MACHINE_H
|
||||
// #include "IDeviceManager.h"
|
||||
#include "IFilesManager.h"
|
||||
#include "IMcuManager.h"
|
||||
#include "IMissionManager.h"
|
||||
#include "IStateMachine.h"
|
||||
|
@ -33,6 +34,7 @@ enum class SystemState
|
|||
UPGRADE_STATE,
|
||||
MEDIA_HANDLE_STATE,
|
||||
IDLE_STATE,
|
||||
FORMATTING_STATE,
|
||||
END
|
||||
};
|
||||
class MissionStateMachine
|
||||
|
@ -47,6 +49,12 @@ public:
|
|||
StatusCode MessageExecutedLater(const std::shared_ptr<VMissionData> &message, long long &delayTimeMs);
|
||||
void DelayMessage(VStateMachineData *msg);
|
||||
void SwitchState(const SystemState &state);
|
||||
/**
|
||||
* @brief Get the type of quick snapshot or video file based on the startup task parameters.
|
||||
*
|
||||
* @return FileCreateType
|
||||
*/
|
||||
FileCreateType GetFileCreateType(void);
|
||||
|
||||
private:
|
||||
IpcMission GetStartMission(void);
|
||||
|
|
|
@ -19,8 +19,6 @@
|
|||
#include "MissionStateMachine.h"
|
||||
OnMissionState::OnMissionState() : MissionState("OnMissionState")
|
||||
{
|
||||
// mEventHandle[InternalStateEvent::ANY_STATE_SD_STATUS_PERORIED] =
|
||||
// std::bind(&OnMissionState::SdCardEventReportSendToApp, this, _1);
|
||||
}
|
||||
void OnMissionState::GoInState()
|
||||
{
|
||||
|
|
|
@ -19,8 +19,6 @@
|
|||
#include "PirTriggeredMissionState.h"
|
||||
PirTriggeredMissionState::PirTriggeredMissionState() : MissionState("PirTriggeredMissionState")
|
||||
{
|
||||
// mEventHandle[InternalStateEvent::ANY_STATE_SD_STATUS_PERORIED] =
|
||||
// std::bind(&PirTriggeredMissionState::SdCardEventReportSendToApp, this, _1);
|
||||
}
|
||||
void PirTriggeredMissionState::GoInState()
|
||||
{
|
||||
|
|
|
@ -20,10 +20,14 @@
|
|||
#include "IMissionManager.h"
|
||||
#include "IStateMachine.h"
|
||||
#include "IStorageManager.h"
|
||||
#include "LedControl.h"
|
||||
#include "LedsHandle.h"
|
||||
#include "MediaTask.h"
|
||||
#include "MissionStateMachine.h"
|
||||
#include "StatusCode.h"
|
||||
#include <functional>
|
||||
#include <memory>
|
||||
#include <vector>
|
||||
using std::placeholders::_1;
|
||||
SdCardHandleState::SdCardHandleState() : State("SdCardHandleState"), mSdCardStatus(StorageEvent::END)
|
||||
{
|
||||
|
@ -32,6 +36,8 @@ SdCardHandleState::SdCardHandleState() : State("SdCardHandleState"), mSdCardStat
|
|||
std::bind(&SdCardHandleState::SdCardEventHandle, this, _1);
|
||||
mEventHandle[InternalStateEvent::RESET_KEY_MEDIA_TASK] =
|
||||
std::bind(&SdCardHandleState::ResetKeyMediaTaskHandle, this, _1);
|
||||
mEventHandle[InternalStateEvent::FORMAT_KEY_FORMAT_SD_CARD] =
|
||||
std::bind(&SdCardHandleState::FormatKeyFormattingSDCardHandle, this, _1);
|
||||
}
|
||||
void SdCardHandleState::GoInState()
|
||||
{
|
||||
|
@ -51,6 +57,7 @@ void SdCardHandleState::StateInit(void)
|
|||
void SdCardHandleState::StateUnInit(void)
|
||||
{
|
||||
IFilesManager::GetInstance()->UnInit();
|
||||
LedsHandle::DeleteAllLeds();
|
||||
}
|
||||
bool SdCardHandleState::MediaReportHandle(VStateMachineData *msg)
|
||||
{
|
||||
|
@ -62,20 +69,37 @@ bool SdCardHandleState::MediaReportHandle(VStateMachineData *msg)
|
|||
LogError("nullptr pointer.\n");
|
||||
return NOT_EXECUTED;
|
||||
}
|
||||
InfoToBeSaved info = IFilesManager::GetInstance()->GetInfoForSavingFiles(1);
|
||||
auto targetFile = MediaTask::GetFileNameBySeriaNumber(info.mSerialNumber, data->mData.mFileName, info.mSavingPath);
|
||||
auto fileSize = MediaTask::GetFileSize_KB(data->mData.mFileName.c_str());
|
||||
auto createTime = MediaTask::GetCreateTime_s();
|
||||
auto createType = MissionStateMachine::GetInstance()->GetFileCreateType();
|
||||
SyncFileInfo file(info.mSerialNumber,
|
||||
// data->mData.mFileName,
|
||||
targetFile,
|
||||
fileSize,
|
||||
data->mData.mDuration_ms,
|
||||
createTime,
|
||||
createType,
|
||||
FileStatus::FINISHED_RECORD);
|
||||
file.mSourceFile = data->mData.mFileName;
|
||||
if (StorageEvent::SD_CARD_INSERT != mSdCardStatus) {
|
||||
/**
|
||||
* @brief The SD card has not been mounted yet, cache the data for the quick start first.
|
||||
*
|
||||
*/
|
||||
LogWarning("Sd card is not inserted, cache data.\n");
|
||||
mFileNeedToSave = std::make_shared<SaveFileInfo>(data->mData.mFileName);
|
||||
// mFileNeedToSave = std::make_shared<SaveFileInfo>(data->mData.mFileName);
|
||||
mFastStartMediaFiles.push_back(file);
|
||||
return EXECUTED;
|
||||
}
|
||||
LogInfo("file = %s.\n", data->mData.mFileName.c_str());
|
||||
SaveFileInfo saveFileInfo(data->mData.mFileName);
|
||||
StatusCode code = IFilesManager::GetInstance()->SaveFile(saveFileInfo);
|
||||
std::vector<SyncFileInfo> files;
|
||||
files.push_back(file);
|
||||
// SaveFileInfo saveFileInfo(data->mData.mFileName);
|
||||
StatusCode code = IFilesManager::GetInstance()->SaveFiles(files);
|
||||
if (IsCodeOK(code) == false) {
|
||||
LogError("SaveFile failed.\n");
|
||||
LogError("SaveFiles failed.\n");
|
||||
}
|
||||
return EXECUTED;
|
||||
}
|
||||
|
@ -85,21 +109,41 @@ bool SdCardHandleState::SdCardEventHandle(VStateMachineData *msg)
|
|||
std::shared_ptr<VMissionDataV2<StorageEvent>> data =
|
||||
std::dynamic_pointer_cast<VMissionDataV2<StorageEvent>>(message->mMissionData);
|
||||
LogInfo(" SdCardEventHandle event:%s.\n", IStorageManager::GetInstance()->PrintStringStorageEvent(data->mData));
|
||||
if (mFileNeedToSave && StorageEvent::SD_CARD_INSERT == data->mData) {
|
||||
LogInfo("Sd card is inserted for the first time.\n");
|
||||
StatusCode code = IFilesManager::GetInstance()->SaveFile(*(mFileNeedToSave.get()));
|
||||
if (IsCodeOK(code) == false) {
|
||||
LogError("SaveFile failed.\n");
|
||||
}
|
||||
mFileNeedToSave.reset();
|
||||
}
|
||||
// if (!mFastStartMediaFiles.empty() && StorageEvent::SD_CARD_INSERT == data->mData) {
|
||||
// LogInfo("Sd card is inserted for the first time.\n");
|
||||
// // StatusCode code = IFilesManager::GetInstance()->SaveFile(*(mFileNeedToSave.get()));
|
||||
// StatusCode code = IFilesManager::GetInstance()->SaveFiles(mFastStartMediaFiles);
|
||||
// if (IsCodeOK(code) == false) {
|
||||
// LogError("SaveFile failed.\n");
|
||||
// }
|
||||
// // mFileNeedToSave.reset();
|
||||
// mFastStartMediaFiles.clear();
|
||||
// }
|
||||
mSdCardStatus = data->mData;
|
||||
/**
|
||||
* @brief The file management uses a database. When the SD card is inserted or removed, the card's file data needs
|
||||
* to be reinitialized.
|
||||
*/
|
||||
if (StorageEvent::SD_CARD_INSERT == mSdCardStatus) {
|
||||
IFilesManager::GetInstance()->Init();
|
||||
std::shared_ptr<VMissionData> message =
|
||||
std::make_shared<VMissionData>(static_cast<MissionEvent>(InternalStateEvent::CHECK_UPGRADE_FILE));
|
||||
MissionStateMachine::GetInstance()->SendStateMessage(message);
|
||||
if (!mFastStartMediaFiles.empty()) {
|
||||
LogInfo("Sd card is inserted for the first time.\n");
|
||||
// StatusCode code = IFilesManager::GetInstance()->SaveFile(*(mFileNeedToSave.get()));
|
||||
StatusCode code = IFilesManager::GetInstance()->SaveFiles(mFastStartMediaFiles);
|
||||
if (IsCodeOK(code) == false) {
|
||||
LogError("SaveFile failed.\n");
|
||||
}
|
||||
// mFileNeedToSave.reset();
|
||||
mFastStartMediaFiles.clear();
|
||||
}
|
||||
}
|
||||
else {
|
||||
IFilesManager::GetInstance()->UnInit();
|
||||
}
|
||||
SetSdCardLedsStatus(mSdCardStatus);
|
||||
return EXECUTED;
|
||||
}
|
||||
bool SdCardHandleState::ResetKeyMediaTaskHandle(VStateMachineData *msg)
|
||||
|
@ -109,4 +153,40 @@ bool SdCardHandleState::ResetKeyMediaTaskHandle(VStateMachineData *msg)
|
|||
}
|
||||
LogWarning("Sd card is not inserted, ignore reset key media task.\n");
|
||||
return HANDLE_HELPESS;
|
||||
}
|
||||
/**
|
||||
* @brief Why do we need to switch status and go through the formatting process here?
|
||||
* This is because the guarantee business requires that the SD card be formatted safely under the condition that the SD
|
||||
* card is not occupied.
|
||||
* @param msg
|
||||
* @return true
|
||||
* @return false
|
||||
*/
|
||||
bool SdCardHandleState::FormatKeyFormattingSDCardHandle(VStateMachineData *msg)
|
||||
{
|
||||
if (StorageEvent::SD_CARD_INSERT == mSdCardStatus || StorageEvent::SD_ABNORMAL == mSdCardStatus) {
|
||||
LogInfo("FormatKeyFormattingSDCardHandle.\n");
|
||||
MissionStateMachine::GetInstance()->DelayMessage(msg);
|
||||
MissionStateMachine::GetInstance()->SwitchState(SystemState::FORMATTING_STATE);
|
||||
return EXECUTED;
|
||||
}
|
||||
LogWarning("Sd card is not inserted, ignore format key.\n");
|
||||
return EXECUTED;
|
||||
}
|
||||
void SdCardHandleState::SetSdCardLedsStatus(const StorageEvent &event)
|
||||
{
|
||||
switch (event) {
|
||||
case StorageEvent::SD_CARD_REMOVE:
|
||||
LedsHandle::ControlDeviceStatusLed(DeviceStatus::SD_CARD_REMOVE, KEEP_ALIVE_FOREVER, BLINKING_SLOW_MS);
|
||||
break;
|
||||
case StorageEvent::SD_CARD_INSERT:
|
||||
LedsHandle::DeleteDeviceStatusLed();
|
||||
break;
|
||||
case StorageEvent::SD_ABNORMAL:
|
||||
LedsHandle::ControlDeviceStatusLed(DeviceStatus::SD_CARD_ABNORMAL, KEEP_ALIVE_FOREVER, BLINKING_SUPER_FAST_MS);
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
|
@ -19,9 +19,11 @@
|
|||
#include "IMediaManager.h"
|
||||
#include "IStateMachine.h"
|
||||
#include "IStorageManager.h"
|
||||
#include "LedsHandle.h"
|
||||
#include "VStateBase.h"
|
||||
class SdCardHandleState : public State,
|
||||
public DataProcessing,
|
||||
public LedsHandle,
|
||||
public VStateBase,
|
||||
public std::enable_shared_from_this<SdCardHandleState>
|
||||
{
|
||||
|
@ -38,9 +40,12 @@ protected:
|
|||
bool MediaReportHandle(VStateMachineData *msg);
|
||||
bool SdCardEventHandle(VStateMachineData *msg);
|
||||
bool ResetKeyMediaTaskHandle(VStateMachineData *msg);
|
||||
bool FormatKeyFormattingSDCardHandle(VStateMachineData *msg);
|
||||
void SetSdCardLedsStatus(const StorageEvent &event);
|
||||
|
||||
private:
|
||||
StorageEvent mSdCardStatus;
|
||||
std::shared_ptr<SaveFileInfo> mFileNeedToSave;
|
||||
std::shared_ptr<SaveFileInfo> mFileNeedToSave; // TODO: delete.
|
||||
std::vector<SyncFileInfo> mFastStartMediaFiles;
|
||||
};
|
||||
#endif
|
|
@ -16,24 +16,35 @@
|
|||
#include "DataProcessing.h"
|
||||
#include "IAppManager.h"
|
||||
#include "ILog.h"
|
||||
#include "IMcuManager.h"
|
||||
#include "IMissionManager.h"
|
||||
#include "IStateMachine.h"
|
||||
#include "IStorageManager.h"
|
||||
#include "LedControl.h"
|
||||
#include "LedsHandle.h"
|
||||
#include "McuAskBase.h"
|
||||
#include "MissionState.h"
|
||||
#include "MissionStateMachine.h"
|
||||
#include <functional>
|
||||
#include <memory>
|
||||
TestMissionState::TestMissionState() : MissionState("TestMissionState")
|
||||
TestMissionState::TestMissionState()
|
||||
: MissionState("TestMissionState"), mFormattingSDCard(SD_CARD_IS_NOT_FORMATTING), mResetKeyHoldTime(0),
|
||||
mFormatKeyHoldTime(0)
|
||||
{
|
||||
mEventHandle[InternalStateEvent::ANY_STATE_SD_STATUS_PERORIED] =
|
||||
std::bind(&TestMissionState::SdCardEventReportSendToApp, this, _1);
|
||||
mEventHandle[InternalStateEvent::RESET_KEY_MEDIA_TASK] =
|
||||
std::bind(&TestMissionState::ResetKeyMediaTaskHandle, this, _1);
|
||||
mKeyClickHandle["reset"] = std::bind(&TestMissionState::ClickResetKey, this, _1);
|
||||
mKeyHoldDownHandle["reset"] = std::bind(&TestMissionState::HoldDownResetKey, this, _1);
|
||||
mKeyHoldDownHandle["format"] = std::bind(&TestMissionState::HoldDownFormatKey, this, _1);
|
||||
mKeyHoldUpHandle["format"] = std::bind(&TestMissionState::HoldUpFormatKey, this, _1);
|
||||
}
|
||||
void TestMissionState::GoInState()
|
||||
{
|
||||
mFormattingSDCard = SD_CARD_IS_NOT_FORMATTING;
|
||||
mFormatKeyHoldTime = 0;
|
||||
mResetKeyHoldTime = 0;
|
||||
MissionState::GoInState();
|
||||
LogInfo(" ========== TestMissionState::GoInState.\n");
|
||||
AppParam mAppParam(APP_MANAGER_DEVICE_IP, APP_MANAGER_HTTP_SERVER_PORT, APP_MANAGER_TCP_SERVER_PORT); // TODO:
|
||||
|
@ -41,10 +52,11 @@ void TestMissionState::GoInState()
|
|||
std::shared_ptr<VAppMonitor> monitor =
|
||||
std::dynamic_pointer_cast<TestMissionState>(MissionState::shared_from_this());
|
||||
IAppManager::GetInstance()->SetAppMonitor(monitor);
|
||||
ControlDeviceStatusLed(DeviceStatus::NORMAL);
|
||||
LedsHandle::ControlDeviceStatusLed(DeviceStatus::NORMAL, KEEP_ALIVE_FOREVER, BLINKING_SLOW_MS);
|
||||
}
|
||||
void TestMissionState::GoOutState()
|
||||
{
|
||||
IAppManager::GetInstance()->UnInit();
|
||||
MissionState::GoOutState();
|
||||
LogInfo(" ========== TestMissionState::GoOutState.\n");
|
||||
}
|
||||
|
@ -67,14 +79,86 @@ bool TestMissionState::ResetKeyMediaTaskHandle(VStateMachineData *msg)
|
|||
bool TestMissionState::ClickResetKey(const KeyEventData &data)
|
||||
{
|
||||
LogInfo("reset key click:make a media task.\n");
|
||||
// std::shared_ptr<VMissionData> message = std::make_shared<VMissionDataV2<MediaReportEvent>>(
|
||||
// static_cast<MissionEvent>(InternalStateEvent::MEDIA_REPORT_EVENT), event);
|
||||
// MissionStateMachine::GetInstance()->SendStateMessage(message);
|
||||
std::shared_ptr<VMissionData> message =
|
||||
std::make_shared<VMissionData>(static_cast<MissionEvent>(InternalStateEvent::RESET_KEY_MEDIA_TASK));
|
||||
MissionStateMachine::GetInstance()->SendStateMessage(message);
|
||||
return EXECUTED;
|
||||
}
|
||||
bool TestMissionState::HoldDownResetKey(const KeyEventData &data)
|
||||
{
|
||||
constexpr int CLOSE_WATCH_DOG_PRESSING_TIME_MS = 1000 * 3;
|
||||
if (mFormatKeyHoldTime > data.mHoldTime && data.mHoldTime >= CLOSE_WATCH_DOG_PRESSING_TIME_MS &&
|
||||
mResetKeyHoldTime == 0) {
|
||||
LogWarning("Close watch dog.\n");
|
||||
constexpr int KEEP_BLINKING_FAST_MS = 1000 * 3;
|
||||
LedsHandle::ControlDeviceStatusLed(DeviceStatus::CLOSE_WATCHDOG, KEEP_BLINKING_FAST_MS, BLINKING_FAST_MS);
|
||||
CloseWatchDog();
|
||||
}
|
||||
if (CLOSE_WATCH_DOG_PRESSING_TIME_MS > data.mHoldTime) {
|
||||
return NOT_EXECUTED;
|
||||
}
|
||||
mFormattingSDCard = DO_NOT_FORMAT_SDCARD_ANYMORE;
|
||||
mResetKeyHoldTime = data.mHoldTime;
|
||||
return EXECUTED;
|
||||
}
|
||||
bool TestMissionState::HoldUpResetKey(const KeyEventData &data)
|
||||
{
|
||||
mFormattingSDCard = SD_CARD_IS_NOT_FORMATTING;
|
||||
mResetKeyHoldTime = 0;
|
||||
return EXECUTED;
|
||||
}
|
||||
bool TestMissionState::HoldDownFormatKey(const KeyEventData &data)
|
||||
{
|
||||
constexpr int FORMAT_SD_CARD_PRESSING_TIME_MS = 1000 * 15;
|
||||
constexpr int MEANS_REALLY_HOLD_DOWN = 1000;
|
||||
if (FORMAT_SD_CARD_PRESSING_TIME_MS <= data.mHoldTime && SD_CARD_IS_NOT_FORMATTING == mFormattingSDCard) {
|
||||
LogInfo("format key down.\n");
|
||||
mFormattingSDCard = DO_NOT_FORMAT_SDCARD_ANYMORE;
|
||||
std::shared_ptr<VMissionData> message =
|
||||
std::make_shared<VMissionData>(static_cast<MissionEvent>(InternalStateEvent::FORMAT_KEY_FORMAT_SD_CARD));
|
||||
MissionStateMachine::GetInstance()->SendStateMessage(message);
|
||||
return EXECUTED;
|
||||
}
|
||||
if (MEANS_REALLY_HOLD_DOWN > data.mHoldTime) {
|
||||
return NOT_EXECUTED;
|
||||
}
|
||||
if (0 == mFormatKeyHoldTime) {
|
||||
constexpr int KEEP_MS = 1000 * 5;
|
||||
LedsHandle::ControlDeviceStatusLed(DeviceStatus::FORMAT_KEY_HOLD_DOWN_TIPS, KEEP_MS, LED_NOT_BLINK);
|
||||
}
|
||||
mFormatKeyHoldTime = data.mHoldTime;
|
||||
return NOT_EXECUTED;
|
||||
}
|
||||
bool TestMissionState::HoldUpFormatKey(const KeyEventData &data)
|
||||
{
|
||||
// mFormattingSDCard = false;
|
||||
mFormatKeyHoldTime = 0;
|
||||
return EXECUTED;
|
||||
}
|
||||
void inline TestMissionState::CloseWatchDog(void)
|
||||
{
|
||||
class McuAskCloseWatchDog : public McuAsk<ASK_RESULT>, public McuAskBase
|
||||
{
|
||||
public:
|
||||
McuAskCloseWatchDog() : McuAskBase(McuAskBlock::NOT_BLOCK, McuAskReply::NEED_REPLY)
|
||||
{
|
||||
} // using McuAskBlock::NOT_BLOCK
|
||||
virtual ~McuAskCloseWatchDog() = default;
|
||||
void ReplyFinished(const bool result) override
|
||||
{
|
||||
McuAskBase::ReplyFinished(result);
|
||||
if (result) {
|
||||
LogInfo("Ask data succeed, mDataReply = %d.\n", static_cast<int>(mDataReply));
|
||||
// Do something here.
|
||||
}
|
||||
else {
|
||||
LogError("Ask data falied.\n");
|
||||
}
|
||||
}
|
||||
};
|
||||
std::shared_ptr<VMcuAsk> ask = std::make_shared<McuAskCloseWatchDog>();
|
||||
IMcuManager::GetInstance()->SetFeedingCycleForWatchDog(ask, CLOSE_WATCH_DOG);
|
||||
}
|
||||
SdCardStatus TestMissionState::SdCardStatusConvert(const StorageEvent &event)
|
||||
{
|
||||
switch (event) {
|
||||
|
|
|
@ -18,6 +18,8 @@
|
|||
#include "IStateMachine.h"
|
||||
#include "IStorageManager.h"
|
||||
#include "MissionState.h"
|
||||
constexpr bool DO_NOT_FORMAT_SDCARD_ANYMORE = true;
|
||||
constexpr bool SD_CARD_IS_NOT_FORMATTING = false;
|
||||
class TestMissionState : public MissionState, public AppMonitor
|
||||
{
|
||||
public:
|
||||
|
@ -30,8 +32,20 @@ private:
|
|||
bool SdCardEventReportSendToApp(VStateMachineData *msg);
|
||||
bool ResetKeyMediaTaskHandle(VStateMachineData *msg);
|
||||
bool ClickResetKey(const KeyEventData &data);
|
||||
bool HoldDownResetKey(const KeyEventData &data);
|
||||
bool HoldUpResetKey(const KeyEventData &data);
|
||||
bool HoldDownFormatKey(const KeyEventData &data);
|
||||
bool HoldUpFormatKey(const KeyEventData &data);
|
||||
|
||||
private:
|
||||
void CloseWatchDog(void);
|
||||
|
||||
private:
|
||||
SdCardStatus SdCardStatusConvert(const StorageEvent &event);
|
||||
|
||||
private:
|
||||
bool mFormattingSDCard;
|
||||
unsigned int mResetKeyHoldTime;
|
||||
unsigned int mFormatKeyHoldTime;
|
||||
};
|
||||
#endif
|
|
@ -51,7 +51,7 @@ bool TopState::ExecuteStateMsg(VStateMachineData *msg)
|
|||
}
|
||||
StatusCode TopState::ReportEvent(const MediaReportEvent &event)
|
||||
{
|
||||
LogInfo(" ReportEvent:\n");
|
||||
LogInfo("Application recv media event(fast start).\n");
|
||||
std::shared_ptr<VMissionData> message = std::make_shared<VMissionDataV2<MediaReportEvent>>(
|
||||
static_cast<MissionEvent>(InternalStateEvent::MEDIA_REPORT_EVENT), event);
|
||||
MissionStateMachine::GetInstance()->SendStateMessage(message);
|
||||
|
|
|
@ -48,7 +48,7 @@ set(LOG_SUPPORT "true")
|
|||
# ------------ build log end ------------ #
|
||||
|
||||
# ------------ build GoAhead ------------ #
|
||||
set(GOAHEAD_DOCUMENTS_PATH "web")
|
||||
set(GOAHEAD_DOCUMENTS_PATH "./sdcard") # web服务器配置文件的根目录,可以访问文件,例如:mp4,jpg,html等
|
||||
set(GOAHEAD_UPLOAD_TMP_PATH "./goahead")
|
||||
set(GOAHEAD_UPLOAD_PATH "${GOAHEAD_UPLOAD_TMP_PATH}")
|
||||
set(GOAHEAD_LIMIT_POST "335544320") # If not defined means using default setting. See goahead-linux-static-fancy.mk
|
||||
|
|
|
@ -14,6 +14,9 @@ set(UTILS_SOURCE_PATH "${CMAKE_SOURCE_DIR_IPCSDK}/utils")
|
|||
set(HAL_SOURCE_PATH "${CMAKE_SOURCE_DIR_IPCSDK}/hal")
|
||||
set(TEST_SOURCE_PATH "${CMAKE_SOURCE_DIR_IPCSDK}/test")
|
||||
set(EXTERNAL_SOURCE_PATH "${CMAKE_SOURCE_DIR_IPCSDK}/external")
|
||||
# TODO: 这里设置CMAKE_INSTALL_PREFIX不是非常合理,
|
||||
# 由于CMAKE_INSTALL_PREFIX被莫名修改成其它值,在这里设置作为临时解决方案
|
||||
set(CMAKE_INSTALL_PREFIX "${PLATFORM_PATH}/${PROJECT_OUTPUT_FOLDER}")
|
||||
|
||||
# -------------------------- clang-tidy tools -------------------------- #
|
||||
set(CLANG_TIDY_CHECKS "-*,\
|
||||
|
|
|
@ -1,10 +1,10 @@
|
|||
# 1. gdb coredump分析
|
||||
|
||||
  本文介绍ubuntu系统环境下coredump文件的分析方法。
|
||||
  本文介绍ubuntu系统环境下coredump文件的分析方法。**重要:此文的场景在Ubuntu每次开机后需要重复设置coredump调试环境,例如开启coredump和设置coredump文件生成路径。**
|
||||
|
||||
**一个coredump示例:**
|
||||
|
||||
```
|
||||
```code
|
||||
$ ../output_files/test/bin/McuManagerTest --gtest_filter=McuManagerTest.RH_INTEGRATION_McuManager_AUTO_OtherSideSendIpcMission
|
||||
Note: Google Test filter = McuManagerTest.RH_INTEGRATION_McuManager_AUTO_OtherSideSendIpcMission
|
||||
[==========] Running 1 test from 1 test suite.
|
||||
|
@ -33,29 +33,31 @@ Aborted (core dumped)
|
|||
|
||||
## 1.1. coredump文件生成路径查询
|
||||
|
||||
```
|
||||
```code
|
||||
$ cat /proc/sys/kernel/core_pattern
|
||||
|/usr/share/apport/apport -p%p -s%s -c%c -d%d -P%P -u%u -g%g -- %E
|
||||
```
|
||||
|
||||
修改coredump文件生成路径:
|
||||
|
||||
```
|
||||
$ sudo sh -c 'echo /home/xiaojiazhu/project/rkipc/battery/ipc-rk1106/ipc-sdk/cmake-shell/core.%e.%p > /proc/sys/kernel/core_pattern'
|
||||
```code
|
||||
$ sudo sh -c 'echo /home/xiaojiazhu/project/ipc-sdk/ipc/cmake-shell/core.%e.%p > /proc/sys/kernel/core_pattern'
|
||||
$ cat /proc/sys/kernel/core_pattern
|
||||
/home/xiaojiazhu/project/rkipc/battery/ipc-rk1106/ipc-sdk/cmake-shell/core.%e.%p
|
||||
```
|
||||
|
||||
命令:
|
||||
sudo sh -c 'echo /path/core.%e.%p > /proc/sys/kernel/core_pattern'
|
||||
|
||||
例如:
|
||||
```
|
||||
例如(根据自己的实际情况写路径参数):
|
||||
|
||||
```code
|
||||
sudo sh -c 'echo /home/xiaojiazhu/project/rkipc/battery/ipc-rk1106/ipc-sdk/cmake-shell/core.%e.%p > /proc/sys/kernel/core_pattern'
|
||||
```
|
||||
|
||||
**发现路径下并未生成coredump文件**
|
||||
|
||||
```
|
||||
```code
|
||||
$ ulimit -a
|
||||
core file size (blocks, -c) 0 // 0表示终端未开启core dump
|
||||
data seg size (kbytes, -d) unlimited
|
||||
|
@ -76,12 +78,11 @@ file locks (-x) unlimited
|
|||
```
|
||||
|
||||
解决:
|
||||
```
|
||||
|
||||
```code
|
||||
$ ulimit -c unlimited
|
||||
```
|
||||
|
||||
sudo echo /home/xiaojiazhu/project/rkipc/battery/ipc-rk1106/ipc-sdk/cmake-shell/core.%e.%p > /proc/sys/kernel/core_pattern
|
||||
|
||||
## 1.2. gdb查看堆栈信息
|
||||
|
||||
**Ubuntu系统需要加sudo执行程序才会生成coredump文件。**
|
||||
|
@ -90,7 +91,7 @@ sudo echo /home/xiaojiazhu/project/rkipc/battery/ipc-rk1106/ipc-sdk/cmake-shell/
|
|||
|
||||
  在gdb中无法识别coredump文件,如下所示:
|
||||
|
||||
```
|
||||
```code
|
||||
$ sudo gdb ../output_files/test/bin/McuManagerTest core.smbd.3390383
|
||||
[sudo] password for xiaojiazhu:
|
||||
Sorry, try again.
|
||||
|
@ -123,11 +124,11 @@ Program terminated with signal SIGABRT, Aborted.
|
|||
#2 0x0000000000000000 in ?? ()
|
||||
```
|
||||
|
||||
由于gdb和asan同时启用会冲突,导致无法识别coredump文件。解决办法如下:
|
||||
**由于gdb和asan同时启用会冲突,导致无法识别coredump文件。解决办法如下:**
|
||||
|
||||
修改://build/sdk_config.cmake
|
||||
|
||||
```
|
||||
```code
|
||||
# Gdb debug
|
||||
if(${TARGET_PLATFORM} MATCHES ${DEFINE_LINUX})
|
||||
message("---------------------------Debug mode.-----------------------")
|
||||
|
@ -149,7 +150,7 @@ endif()
|
|||
|
||||
解决后:
|
||||
|
||||
```
|
||||
```code
|
||||
$ sudo gdb ../output_files/test/bin/McuManagerTest core.McuManagerTest.3406751
|
||||
GNU gdb (Ubuntu 9.2-0ubuntu1~20.04.1) 9.2
|
||||
Copyright (C) 2020 Free Software Foundation, Inc.
|
||||
|
@ -206,4 +207,4 @@ Program terminated with signal SIGABRT, Aborted.
|
|||
#17 main (argc=<optimized out>, argv=<optimized out>)
|
||||
at /home/xiaojiazhu/project/rkipc/battery/ipc-rk1106/ipc-sdk/test/middleware/McuManager/mainTest.cpp:22
|
||||
(gdb)
|
||||
```
|
||||
```
|
||||
|
|
3
external/CMakeLists.txt
vendored
3
external/CMakeLists.txt
vendored
|
@ -26,4 +26,5 @@ add_subdirectory(libhv/libhv-1.3.2)
|
|||
add_subdirectory(ffmpeg)
|
||||
add_subdirectory(fdk-aac)
|
||||
# ================= ffmpeg related end ================= #
|
||||
add_subdirectory(libconfig)
|
||||
add_subdirectory(libconfig)
|
||||
# add_subdirectory(libfaac)
|
5
external/ffmpeg/CMakeLists.txt
vendored
5
external/ffmpeg/CMakeLists.txt
vendored
|
@ -15,11 +15,11 @@ set(FFMPEG_COMMON_CONFIG "--enable-cross-compile --target-os=linux \
|
|||
--disable-mipsdsp --disable-mipsdspr2 \
|
||||
--disable-encoders \
|
||||
--disable-muxers --enable-muxer=mov --enable-muxer=mp4 --enable-encoder=mpeg4 \
|
||||
--enable-decoder=aac --enable-encoder=aac --enable-decoder=pcm_alaw --enable-encoder=pcm_alaw \
|
||||
--enable-decoder=aac --enable-encoder=aac --enable-encoder=libfdk_aac --enable-decoder=pcm_alaw --enable-encoder=pcm_alaw \
|
||||
--enable-demuxer=mov \
|
||||
--disable-protocols --enable-protocol=file \
|
||||
--disable-bsfs --enable-bsf=aac_adtstoasc --enable-bsf=h264_mp4toannexb --enable-bsf=hevc_mp4toannexb \
|
||||
--disable-indevs --disable-outdevs \
|
||||
--disable-indevs --disable-outdevs --enable-muxer=image2 --enable-encoder=mjpeg \
|
||||
--extra-libs=-lm \
|
||||
--extra-cflags=\"-I${EXTERNAL_LIBS_OUTPUT_PATH}/fdk-aac/include\" \
|
||||
--extra-ldflags=\"-L${EXTERNAL_LIBS_OUTPUT_PATH}/fdk-aac/lib\"")
|
||||
|
@ -51,6 +51,7 @@ add_custom_target(
|
|||
add_custom_target(
|
||||
remove_ffmpeg_source_files
|
||||
COMMAND rm -rf ffmpeg-6.1.1
|
||||
COMMAND rm -rf ${FFMPEG_INSTALL_PATH}
|
||||
WORKING_DIRECTORY ${EXTERNAL_SOURCE_PATH}/ffmpeg/
|
||||
)
|
||||
|
||||
|
|
60
external/ffmpeg/README.md
vendored
60
external/ffmpeg/README.md
vendored
|
@ -21,6 +21,66 @@ $ ffplay video.h264
|
|||
$ fmpeg -f mulaw -ar 8000 -i audio.g711a audio.wav
|
||||
```
|
||||
|
||||
* 播放pcm文件
|
||||
|
||||
```code
|
||||
$ ffplay -f s16le -ar 8000 -ac 1 test.pcm
|
||||
```
|
||||
|
||||
* 生成jpeg
|
||||
|
||||
```code
|
||||
$ ./ffmpeg -i test.h264 -vframes 1 -vf "scale=640:480:force_original_aspect_ratio=decrease" -f image2 output.jpeg
|
||||
```
|
||||
|
||||
```code
|
||||
void FfmpegThumbnail::GetDecodeDataCallback(AVFrame *frame)
|
||||
{
|
||||
LogInfo("GetDecodeDataCallback frame->width = %d, frame->height = %d\n", frame->width, frame->height);
|
||||
|
||||
// Allocate output frame for YUV420P format
|
||||
AVFrame *output_frame = av_frame_alloc();
|
||||
output_frame->format = AV_PIX_FMT_YUV420P;
|
||||
output_frame->width = 640;
|
||||
output_frame->height = 480;
|
||||
|
||||
// Calculate buffer size for YUV420P
|
||||
int yuv_buf_size = av_image_get_buffer_size(AV_PIX_FMT_YUV420P, 640, 480, 1);
|
||||
uint8_t *yuv_buf = (uint8_t *)av_malloc(yuv_buf_size);
|
||||
|
||||
// Fill output frame with YUV420P buffer
|
||||
av_image_fill_arrays(output_frame->data, output_frame->linesize, yuv_buf, AV_PIX_FMT_YUV420P, 640, 480, 1);
|
||||
|
||||
// Create SwsContext for pixel format conversion from YUV420P (1920x2160) to YUV420P (640x480)
|
||||
SwsContext *sws_ctx = sws_getContext(frame->width, frame->height, static_cast<AVPixelFormat>(frame->format),
|
||||
output_frame->width, output_frame->height, AV_PIX_FMT_YUV420P,
|
||||
SWS_BILINEAR, nullptr, nullptr, nullptr);
|
||||
if (!sws_ctx) {
|
||||
LogError("Failed to create SwsContext for pixel format conversion\n");
|
||||
av_frame_free(&output_frame);
|
||||
av_free(yuv_buf);
|
||||
return;
|
||||
}
|
||||
|
||||
// Perform pixel format conversion and scaling
|
||||
sws_scale(sws_ctx, frame->data, frame->linesize, 0, frame->height,
|
||||
output_frame->data, output_frame->linesize);
|
||||
|
||||
// Clean up SwsContext
|
||||
sws_freeContext(sws_ctx);
|
||||
|
||||
// Encode the YUV420P frame to JPEG using mEncoder
|
||||
if (mEncoder) {
|
||||
mEncoder->EncodeData(output_frame, mStream, mEncodeCallback);
|
||||
}
|
||||
|
||||
// Free allocated resources
|
||||
av_frame_free(&output_frame);
|
||||
av_free(yuv_buf);
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
* 将h264和wav文件合成mp4文件
|
||||
|
||||
**注意:未发现可以将h264和g711a文件合成mp4文件**
|
||||
|
|
12
external/libfaac/CMakeLists.txt
vendored
Executable file
12
external/libfaac/CMakeLists.txt
vendored
Executable file
|
@ -0,0 +1,12 @@
|
|||
include(${CMAKE_SOURCE_DIR_IPCSDK}/build/global_config.cmake)
|
||||
set(EXECUTABLE_OUTPUT_PATH ${EXEC_OUTPUT_PATH})
|
||||
set(LIBRARY_OUTPUT_PATH ${EXTERNAL_LIBS_OUTPUT_PATH})
|
||||
INCLUDE_DIRECTORIES(libfaac)
|
||||
INCLUDE_DIRECTORIES(./)
|
||||
|
||||
AUX_SOURCE_DIRECTORY(. MODULE_SRC)
|
||||
AUX_SOURCE_DIRECTORY(libfaac MODULE_SRC)
|
||||
|
||||
ADD_LIBRARY(faac STATIC ${MODULE_SRC})
|
||||
|
||||
|
31
external/libfaac/G711AToPcm.cpp
vendored
Normal file
31
external/libfaac/G711AToPcm.cpp
vendored
Normal file
|
@ -0,0 +1,31 @@
|
|||
|
||||
#include "G711AToPcm.h"
|
||||
|
||||
#include "g711.h"
|
||||
|
||||
|
||||
G711AToPcm::G711AToPcm(void)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
G711AToPcm::~G711AToPcm(void)
|
||||
{
|
||||
}
|
||||
unsigned short G711AToPcm::DecodeOneChar(unsigned char data)
|
||||
{
|
||||
return (int16_t)alaw2linear(data);
|
||||
}
|
||||
//-------------------------------------------
|
||||
G711UToPcm::G711UToPcm(void)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
G711UToPcm::~G711UToPcm(void)
|
||||
{
|
||||
}
|
||||
unsigned short G711UToPcm::DecodeOneChar(unsigned char data)
|
||||
{
|
||||
return (int16_t)ulaw2linear(data);
|
||||
}
|
24
external/libfaac/G711AToPcm.h
vendored
Normal file
24
external/libfaac/G711AToPcm.h
vendored
Normal file
|
@ -0,0 +1,24 @@
|
|||
|
||||
#pragma once
|
||||
#include "IDecodeToPcm.h"
|
||||
|
||||
class G711AToPcm :
|
||||
public DecodeToPcmBase
|
||||
{
|
||||
public:
|
||||
G711AToPcm(void);
|
||||
virtual ~G711AToPcm(void);
|
||||
public:
|
||||
virtual unsigned short DecodeOneChar(unsigned char data);
|
||||
};
|
||||
|
||||
|
||||
class G711UToPcm :
|
||||
public DecodeToPcmBase
|
||||
{
|
||||
public:
|
||||
G711UToPcm(void);
|
||||
virtual ~G711UToPcm(void);
|
||||
public:
|
||||
virtual unsigned short DecodeOneChar(unsigned char data);
|
||||
};
|
90
external/libfaac/IDecodeToPcm.cpp
vendored
Normal file
90
external/libfaac/IDecodeToPcm.cpp
vendored
Normal file
|
@ -0,0 +1,90 @@
|
|||
|
||||
#include "IDecodeToPcm.h"
|
||||
#include "audio_buffer.h"
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
|
||||
IDecodeToPcm::IDecodeToPcm(void)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
IDecodeToPcm::~IDecodeToPcm(void)
|
||||
{
|
||||
|
||||
}
|
||||
//------------------------------------------------------------------------------------------------------------------------
|
||||
InAudioInfo::InAudioInfo()
|
||||
{
|
||||
InitParam& initParam = m_initparam;
|
||||
initParam.u32AudioSamplerate=8000;
|
||||
initParam.ucAudioChannel=1;
|
||||
initParam.u32PCMBitSize=16;
|
||||
initParam.ucAudioCodec = Law_ALaw;
|
||||
}
|
||||
InAudioInfo::InAudioInfo(InitParam param):m_initparam(param)
|
||||
{
|
||||
|
||||
}
|
||||
//------------------------------------------------------------------------------------------------------------------------
|
||||
//-------------------------------------------------------------------------------
|
||||
DecodeToPcmBase::DecodeToPcmBase(void)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
|
||||
DecodeToPcmBase::~DecodeToPcmBase(void)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
int DecodeToPcmBase::Init(InAudioInfo info)
|
||||
{
|
||||
m_g7FrameSize = G711_ONE_LEN;
|
||||
return 0;
|
||||
}
|
||||
int DecodeToPcmBase::PCMSize()
|
||||
{
|
||||
return CON_PCM_SIZE;
|
||||
}
|
||||
int DecodeToPcmBase::G7FrameSize()
|
||||
{
|
||||
return m_g7FrameSize;
|
||||
}
|
||||
int DecodeToPcmBase::Decode(unsigned char* pout_buf, unsigned int* pout_len , unsigned char* pin_buf, unsigned int in_len)
|
||||
{
|
||||
int16_t *dst = (int16_t *) pout_buf;
|
||||
uint8_t *src = (uint8_t *) pin_buf;
|
||||
uint32_t i = 0;
|
||||
int Ret = 0;
|
||||
|
||||
if ((NULL == pout_buf) || \
|
||||
(NULL == pout_len) || \
|
||||
(NULL == pin_buf) || \
|
||||
(0 == in_len))
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (*pout_len < 2 * in_len)
|
||||
{
|
||||
return -2;
|
||||
}
|
||||
//---{{{
|
||||
|
||||
for (i = 0; i < in_len; i++)
|
||||
{
|
||||
*(dst++) = (int16_t)DecodeOneChar(*(src++));
|
||||
}
|
||||
|
||||
//---}}}
|
||||
*pout_len = 2 * in_len;
|
||||
|
||||
Ret = 2 * in_len;
|
||||
return Ret;
|
||||
return 0;
|
||||
}
|
100
external/libfaac/IDecodeToPcm.h
vendored
Normal file
100
external/libfaac/IDecodeToPcm.h
vendored
Normal file
|
@ -0,0 +1,100 @@
|
|||
|
||||
#pragma once
|
||||
|
||||
#ifndef _IDECODETOPCM_H
|
||||
#define _IDECODETOPCM_H
|
||||
|
||||
#include "MtAACEncoderAPI.h"
|
||||
|
||||
#define USE_SHOUT_G711PACK 1
|
||||
|
||||
#if USE_SHOUT_G711PACK
|
||||
#define G711_ONE_LEN 160
|
||||
#define G711_ONE_OFFSET 0
|
||||
|
||||
#else
|
||||
#define G711_ONE_LEN 164
|
||||
#define G711_ONE_OFFSET 4
|
||||
#endif
|
||||
|
||||
const int CON_PCM_SIZE = 320;
|
||||
|
||||
class audio_buffer;
|
||||
|
||||
class InAudioInfo
|
||||
{
|
||||
public:
|
||||
InAudioInfo();
|
||||
InAudioInfo(InitParam param);
|
||||
~InAudioInfo(){;}
|
||||
|
||||
unsigned int CodecType()
|
||||
{
|
||||
return m_initparam.ucAudioCodec;
|
||||
//return m_u32AudioCodec;
|
||||
}
|
||||
unsigned int Samplerate()
|
||||
{
|
||||
return m_initparam.u32AudioSamplerate;
|
||||
//return m_u32AudioSamplerate;
|
||||
}
|
||||
unsigned int Channel()
|
||||
{
|
||||
return m_initparam.ucAudioChannel;
|
||||
//return m_u32AudioChannel;
|
||||
}
|
||||
unsigned int PCMBitSize()
|
||||
{
|
||||
return m_initparam.u32PCMBitSize;
|
||||
//return m_nPCMBitSize;
|
||||
}
|
||||
unsigned char G726RateBits()
|
||||
{
|
||||
return m_initparam.g726param.ucRateBits;
|
||||
}
|
||||
private:
|
||||
unsigned int m_u32AudioCodec;
|
||||
unsigned int m_u32AudioSamplerate;
|
||||
unsigned int m_u32AudioChannel;
|
||||
|
||||
unsigned int m_nPCMBitSize;
|
||||
|
||||
InitParam m_initparam;
|
||||
};
|
||||
//----------------------------------------------------------
|
||||
class IDecodeToPcm
|
||||
{
|
||||
public:
|
||||
IDecodeToPcm(void);
|
||||
virtual ~IDecodeToPcm(void);
|
||||
|
||||
public:
|
||||
virtual int Init(InAudioInfo info)=0;
|
||||
virtual int Decode( unsigned char* outbuf, unsigned int* outlen , unsigned char* inbuf, unsigned int inlen)=0;
|
||||
virtual int PCMSize()=0;
|
||||
virtual int G7FrameSize()=0;
|
||||
};
|
||||
//----------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
//-------------------------------------------------------------------------------------------------------------------------
|
||||
class DecodeToPcmBase:public IDecodeToPcm
|
||||
{
|
||||
public:
|
||||
DecodeToPcmBase();
|
||||
virtual ~DecodeToPcmBase();
|
||||
|
||||
int Init(InAudioInfo info);
|
||||
|
||||
public:
|
||||
virtual int Decode(unsigned char* outbuf, unsigned int* outlen , unsigned char* inbuf, unsigned int inlen);
|
||||
virtual int PCMSize();
|
||||
virtual int G7FrameSize();
|
||||
|
||||
virtual unsigned short DecodeOneChar(unsigned char data)=0;
|
||||
|
||||
private:
|
||||
int m_g7FrameSize;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
190
external/libfaac/MtAACEncoder.cpp
vendored
Normal file
190
external/libfaac/MtAACEncoder.cpp
vendored
Normal file
|
@ -0,0 +1,190 @@
|
|||
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "MtAACEncoder.h"
|
||||
#include "MtAACEncoderAPI.h"
|
||||
#include "outDebug.h"
|
||||
#include "G711AToPcm.h"
|
||||
#include "condef.h"
|
||||
|
||||
G7ToAac::G7ToAac()
|
||||
{
|
||||
m_pbPCMBuffer = NULL;
|
||||
m_pbAACBuffer = NULL;
|
||||
m_pbG7FrameBuffer = NULL;
|
||||
m_pbPCMTmpBuffer = NULL;
|
||||
m_audio_buffer_ = NULL;
|
||||
m_pDecodeToPcm = NULL;
|
||||
m_pPCMToAAC = NULL;
|
||||
}
|
||||
|
||||
G7ToAac::~G7ToAac()
|
||||
{
|
||||
/*free the source of malloc*/
|
||||
SAFE_FREE_BUF(m_pbPCMBuffer);
|
||||
SAFE_FREE_BUF(m_pbAACBuffer);
|
||||
SAFE_FREE_BUF(m_pbG7FrameBuffer);
|
||||
SAFE_FREE_BUF(m_pbPCMTmpBuffer);
|
||||
|
||||
SAFE_DELETE_OBJ(m_audio_buffer_);
|
||||
SAFE_DELETE_OBJ(m_pDecodeToPcm);
|
||||
SAFE_DELETE_OBJ(m_pPCMToAAC);
|
||||
}
|
||||
bool G7ToAac::init()
|
||||
{
|
||||
nRet = 0;
|
||||
nTmp = 0;
|
||||
nCount = 0;
|
||||
nStatus = 0;
|
||||
nPCMRead = 0;
|
||||
|
||||
CreateBuffer();
|
||||
return true;
|
||||
}
|
||||
|
||||
bool G7ToAac::init(InAudioInfo info)
|
||||
{
|
||||
m_inAudioInfo = info;
|
||||
|
||||
bool ret=false;
|
||||
ret = CreateDecodePcm();
|
||||
|
||||
ret = CreateEncodeAac();
|
||||
if (!ret)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
return init();
|
||||
}
|
||||
bool G7ToAac::CreateDecodePcm()
|
||||
{
|
||||
if ( Law_ALaw == m_inAudioInfo.CodecType())
|
||||
{
|
||||
m_pDecodeToPcm = new G711AToPcm();
|
||||
}else if ( Law_ULaw == m_inAudioInfo.CodecType() )
|
||||
{
|
||||
m_pDecodeToPcm = new G711UToPcm();
|
||||
}
|
||||
else
|
||||
{
|
||||
m_pDecodeToPcm = new G711AToPcm();
|
||||
}
|
||||
m_pDecodeToPcm->Init(m_inAudioInfo);
|
||||
|
||||
return true;
|
||||
}
|
||||
bool G7ToAac::CreateEncodeAac()
|
||||
{
|
||||
m_pPCMToAAC = new PcmToAac();
|
||||
bool ret = m_pPCMToAAC->Init(&m_inAudioInfo);
|
||||
|
||||
return ret;
|
||||
}
|
||||
bool G7ToAac::CreateBuffer()
|
||||
{
|
||||
m_nPCMBufferSize = m_pPCMToAAC->GetPCMBufferSize();
|
||||
m_pbPCMBuffer = (unsigned char*) malloc(m_nPCMBufferSize * sizeof (unsigned char));
|
||||
memset(m_pbPCMBuffer, 0, m_nPCMBufferSize);
|
||||
|
||||
m_nMaxOutputBytes = m_pPCMToAAC->GetMaxOutputBytes();
|
||||
m_pbAACBuffer = (unsigned char*) malloc(m_nMaxOutputBytes * sizeof (unsigned char));
|
||||
memset(m_pbAACBuffer, 0, m_nMaxOutputBytes);
|
||||
|
||||
m_nG7FrameBufferSize = m_pDecodeToPcm->G7FrameSize();
|
||||
m_pbG7FrameBuffer = (unsigned char *) malloc(m_nG7FrameBufferSize * sizeof (unsigned char));
|
||||
memset(m_pbG7FrameBuffer, 0, m_nG7FrameBufferSize);
|
||||
|
||||
m_nPCMSize = m_pDecodeToPcm->PCMSize();
|
||||
m_pbPCMTmpBuffer = (unsigned char *) malloc(m_nPCMSize * sizeof (unsigned char));
|
||||
memset(m_pbPCMTmpBuffer, 0, m_nPCMSize);
|
||||
|
||||
m_audio_buffer_ = new audio_buffer();
|
||||
|
||||
return true;
|
||||
}
|
||||
int G7ToAac::aac_encode(unsigned char* inbuf, unsigned int inlen, unsigned char* outbuf, unsigned int* outlen)
|
||||
{
|
||||
int encodeLen = 0;
|
||||
|
||||
if (NULL != m_pDecodeToPcm)
|
||||
{
|
||||
encodeLen = aac_encode_obj(inbuf , inlen , outbuf , outlen);
|
||||
}
|
||||
|
||||
return encodeLen;
|
||||
}
|
||||
|
||||
int G7ToAac::aac_encode_obj(unsigned char* inbuf, unsigned int inlen, unsigned char* outbuf, unsigned int* outlen )
|
||||
{
|
||||
m_audio_buffer_->write_data(inbuf, inlen);
|
||||
int buffer_len = 0;
|
||||
*outlen = 0;
|
||||
int nPCMSize = 0;
|
||||
//while ((buffer_len = audio_buffer_->get_data(pbG711ABuffer, /*164*/G711_ONE_LEN)) > 0)
|
||||
while ((buffer_len = m_audio_buffer_->get_data(m_pbG7FrameBuffer, m_nG7FrameBufferSize)) > 0)
|
||||
{
|
||||
if (buffer_len <= 0)
|
||||
{
|
||||
if(AAC_DEBUG) printf("%s:[%d] G711A -> PCM no G711 data !\n", __FUNCTION__, __LINE__);
|
||||
//Sleep(100);
|
||||
return -1;
|
||||
}
|
||||
|
||||
nStatus = 0;
|
||||
memset(m_pbPCMTmpBuffer, 0, m_nPCMSize);
|
||||
nPCMSize = m_nPCMSize;
|
||||
//if ((nPCMRead = m_pDecodeToPcm->Decode(pbPCMTmpBuffer, (unsigned int*)&PCMSize, pbG711ABuffer+/*4*/G711_ONE_OFFSET, buffer_len-/*4*/G711_ONE_OFFSET )) < 0) // TODO: skip 4 byte?
|
||||
if ((nPCMRead = m_pDecodeToPcm->Decode(m_pbPCMTmpBuffer, (unsigned int*)&nPCMSize, m_pbG7FrameBuffer, buffer_len )) < 0) // TODO: skip 4 byte?
|
||||
{
|
||||
if(AAC_DEBUG) printf("%s:[%d] G711A -> PCM failed buffer_len = %d !\n", __FUNCTION__, __LINE__, buffer_len);
|
||||
return -1;
|
||||
}
|
||||
//if(AAC_DEBUG) printf("nPCMRead = %d, PCMSize = %d\n", nPCMRead, PCMSize);
|
||||
|
||||
if ((m_nPCMBufferSize - nCount) < nPCMRead)
|
||||
{
|
||||
//if(AAC_DEBUG) printf("nPCMBufferSize = %d, nCount = %d, nPCMRead = %d\n", nPCMBufferSize, nCount, nPCMRead);
|
||||
nStatus = 1;
|
||||
memset(m_pbAACBuffer, 0, m_nMaxOutputBytes);
|
||||
memcpy(m_pbPCMBuffer + nCount, m_pbPCMTmpBuffer, (m_nPCMBufferSize - nCount));
|
||||
|
||||
nRet = m_pPCMToAAC->Encode( (int32_t*)m_pbPCMBuffer , m_nPCMBufferSize , m_pbAACBuffer, m_nMaxOutputBytes);
|
||||
|
||||
|
||||
memcpy(outbuf + *outlen, m_pbAACBuffer, nRet);
|
||||
*outlen += nRet;
|
||||
|
||||
nTmp = nPCMRead - (m_nPCMBufferSize - nCount);
|
||||
memset(m_pbPCMBuffer, 0, m_nPCMBufferSize);
|
||||
memcpy(m_pbPCMBuffer, m_pbPCMTmpBuffer + (m_nPCMBufferSize - nCount), nTmp);
|
||||
if(AAC_DEBUG) printf("%s:[%d] G711A -> PCM (nPCMBufferSize - nCount) < nPCMRead\n", __FUNCTION__, __LINE__);
|
||||
nCount = 0;
|
||||
nCount += nTmp;
|
||||
}
|
||||
|
||||
if (nStatus == 0)
|
||||
{
|
||||
if(AAC_DEBUG) printf("%s:[%d] G711A -> PCM nStatus = 0...\n", __FUNCTION__, __LINE__);
|
||||
memcpy(m_pbPCMBuffer + nCount, m_pbPCMTmpBuffer, nPCMRead);
|
||||
if(AAC_DEBUG) printf("%s:[%d] G711A -> PCM nStatus = 0\n", __FUNCTION__, __LINE__);
|
||||
nCount += nPCMRead;
|
||||
}
|
||||
|
||||
if (nPCMRead < /*320*/CON_PCM_SIZE)
|
||||
{
|
||||
if(AAC_DEBUG) printf("nPCMRead = %d\n", nPCMRead);
|
||||
|
||||
nRet = m_pPCMToAAC->Encode((int*) m_pbPCMBuffer, nCount , m_pbAACBuffer, m_nMaxOutputBytes);
|
||||
|
||||
|
||||
memcpy(outbuf + *outlen, m_pbAACBuffer, nRet);
|
||||
*outlen += nRet;
|
||||
|
||||
INFO_D(AAC_DEBUG , "G711A -> PCM nPCMRead < 320");
|
||||
}
|
||||
}
|
||||
return *outlen;
|
||||
}
|
55
external/libfaac/MtAACEncoder.h
vendored
Normal file
55
external/libfaac/MtAACEncoder.h
vendored
Normal file
|
@ -0,0 +1,55 @@
|
|||
#ifndef MtAACEncoder_H
|
||||
#define MtAACEncoder_H
|
||||
|
||||
#include "audio_buffer.h"
|
||||
#include "IDecodeToPcm.h"
|
||||
#include "PcmToAac.h"
|
||||
|
||||
class G7ToAac
|
||||
{
|
||||
public:
|
||||
G7ToAac();
|
||||
virtual ~G7ToAac();
|
||||
|
||||
bool init();
|
||||
bool init(InAudioInfo info);
|
||||
|
||||
int aac_encode(unsigned char* inbuf, unsigned int inlen, unsigned char* outbuf, unsigned int* outlen);
|
||||
|
||||
private:
|
||||
int aac_encode_obj(unsigned char* inbuf, unsigned int inlen, unsigned char* outbuf, unsigned int* outlen );
|
||||
|
||||
bool CreateDecodePcm();
|
||||
bool CreateEncodeAac();
|
||||
bool CreateBuffer();
|
||||
private:
|
||||
int nRet;
|
||||
int nTmp;
|
||||
int nCount;
|
||||
int nStatus;
|
||||
int nPCMRead;
|
||||
|
||||
|
||||
|
||||
int m_nPCMBufferSize;
|
||||
unsigned char *m_pbPCMBuffer;
|
||||
|
||||
unsigned long m_nMaxOutputBytes;
|
||||
unsigned char *m_pbAACBuffer;
|
||||
|
||||
int m_nPCMSize;
|
||||
unsigned char *m_pbPCMTmpBuffer;
|
||||
|
||||
unsigned char *m_pbG7FrameBuffer;
|
||||
unsigned long m_nG7FrameBufferSize;
|
||||
|
||||
audio_buffer *m_audio_buffer_;
|
||||
//------
|
||||
InAudioInfo m_inAudioInfo;
|
||||
|
||||
IDecodeToPcm* m_pDecodeToPcm;
|
||||
PcmToAac* m_pPCMToAAC;
|
||||
};
|
||||
|
||||
#endif /* MtAACEncoder_H */
|
||||
|
34
external/libfaac/MtAACEncoderAPI.cpp
vendored
Normal file
34
external/libfaac/MtAACEncoderAPI.cpp
vendored
Normal file
|
@ -0,0 +1,34 @@
|
|||
#include "MtAACEncoderAPI.h"
|
||||
#include "MtAACEncoder.h"
|
||||
#include "condef.h"
|
||||
|
||||
Mt_API MtAACEncoder_Handle Mt_APICALL Mt_AACEncoder_Init(InitParam initPar)
|
||||
{
|
||||
G7ToAac *encoder = new G7ToAac();
|
||||
InAudioInfo info(initPar );
|
||||
bool ret = encoder->init(info);
|
||||
if (!ret)
|
||||
{
|
||||
SAFE_DELETE_OBJ(encoder);
|
||||
}
|
||||
return encoder;
|
||||
}
|
||||
|
||||
Mt_API int Mt_APICALL Mt_AACEncoder_Encode(MtAACEncoder_Handle handle, unsigned char* inbuf, unsigned int inlen, unsigned char* outbuf, unsigned int* outlen)
|
||||
{
|
||||
if(handle == NULL)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
return ((G7ToAac*)handle)->aac_encode(inbuf, inlen, outbuf, outlen);
|
||||
}
|
||||
|
||||
Mt_API void Mt_APICALL Mt_AACEncoder_Release(MtAACEncoder_Handle handle)
|
||||
{
|
||||
if(handle != NULL)
|
||||
{
|
||||
delete ((G7ToAac*)handle);
|
||||
}
|
||||
}
|
||||
|
||||
|
75
external/libfaac/MtAACEncoderAPI.h
vendored
Normal file
75
external/libfaac/MtAACEncoderAPI.h
vendored
Normal file
|
@ -0,0 +1,75 @@
|
|||
|
||||
#ifndef MtAACEncoder_API_H
|
||||
#define MtAACEncoder_API_H
|
||||
|
||||
#ifdef _WIN32
|
||||
#define Mt_API __declspec(dllexport)
|
||||
#define Mt_APICALL __stdcall
|
||||
#else
|
||||
#define Mt_API
|
||||
#define Mt_APICALL
|
||||
#endif
|
||||
|
||||
#define Mt_Handle void*
|
||||
#define MtAACEncoder_Handle void*
|
||||
|
||||
///* Audio Codec */
|
||||
enum Law
|
||||
{
|
||||
Law_ULaw = 0, /**< U law */
|
||||
Law_ALaw = 1, /**< A law */
|
||||
Law_PCM16 = 2, /**< 16 bit uniform PCM values. 原始 pcm 数据 */
|
||||
Law_G726 = 3 /**< G726 */
|
||||
};
|
||||
|
||||
///* Rate Bits */
|
||||
enum Rate
|
||||
{
|
||||
Rate16kBits=2, /**< 16k bits per second (2 bits per ADPCM sample) */
|
||||
Rate24kBits=3, /**< 24k bits per second (3 bits per ADPCM sample) */
|
||||
Rate32kBits=4, /**< 32k bits per second (4 bits per ADPCM sample) */
|
||||
Rate40kBits=5 /**< 40k bits per second (5 bits per ADPCM sample) */
|
||||
};
|
||||
|
||||
typedef struct _g711param
|
||||
{
|
||||
;
|
||||
}G711Param;
|
||||
|
||||
typedef struct _g726param
|
||||
{
|
||||
unsigned char ucRateBits;//Rate16kBits Rate24kBits Rate32kBits Rate40kBits
|
||||
}G726Param;
|
||||
|
||||
typedef struct _initParam
|
||||
{
|
||||
unsigned char ucAudioCodec; // Law_uLaw Law_ALaw Law_PCM16 Law_G726
|
||||
unsigned char ucAudioChannel; //1
|
||||
unsigned int u32AudioSamplerate; //8000
|
||||
unsigned int u32PCMBitSize; //16
|
||||
union
|
||||
{
|
||||
G711Param g711param;
|
||||
G726Param g726param;
|
||||
};
|
||||
|
||||
}InitParam;
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
{
|
||||
#endif
|
||||
/* 创建AAC Encoder 返回为句柄值 */
|
||||
Mt_API MtAACEncoder_Handle Mt_APICALL Mt_AACEncoder_Init(InitParam initPar);
|
||||
|
||||
/* 输入编码数据,返回编码后数据 */
|
||||
Mt_API int Mt_APICALL Mt_AACEncoder_Encode(MtAACEncoder_Handle handle, unsigned char* inbuf, unsigned int inlen, unsigned char* outbuf, unsigned int* outlen);
|
||||
|
||||
/* 释放AAC Encoder */
|
||||
Mt_API void Mt_APICALL Mt_AACEncoder_Release(MtAACEncoder_Handle handle);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* MtAACEncoder_API_H */
|
106
external/libfaac/MtDSSBuffers.cpp
vendored
Normal file
106
external/libfaac/MtDSSBuffers.cpp
vendored
Normal file
|
@ -0,0 +1,106 @@
|
|||
#include "MtDSSBuffers.h"
|
||||
|
||||
int init_buffers(buffers_t * bufs, int bufsize, int bufnum)
|
||||
{
|
||||
int i;
|
||||
bufs->rear = 0;
|
||||
bufs->front = 0;
|
||||
if(bufnum > MAX_BUF_NUM)
|
||||
{
|
||||
bufs->bufnum = MAX_BUF_NUM;
|
||||
}
|
||||
else
|
||||
{
|
||||
bufs->bufnum = bufnum;
|
||||
}
|
||||
for(i = 0; i < bufs->bufnum; i++)
|
||||
{
|
||||
bufs->buf[i].length = 0;
|
||||
bufs->buf[i].start = (char *) calloc(1, bufsize);
|
||||
bufs->buf[i].frame_type = -1;
|
||||
bufs->buf[i].channel = -1;
|
||||
bufs->buf[i].frame_index = 0;
|
||||
if(bufs->buf[i].start == NULL)
|
||||
return -1;
|
||||
}
|
||||
#ifdef WIN32
|
||||
InitializeCriticalSection(&(bufs->cs));
|
||||
#else
|
||||
InitializeCriticalSection(&(bufs->cs), NULL);
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
int free_buffers(buffers_t* bufs)
|
||||
{
|
||||
for(int i = 0; i < bufs->bufnum; i++)
|
||||
{
|
||||
if(bufs->buf[i].start != NULL)
|
||||
free(bufs->buf[i].start);
|
||||
}
|
||||
bufs->pOnVideoData = NULL;
|
||||
DeleteCriticalSection(&(bufs->cs));
|
||||
return 0;
|
||||
}
|
||||
|
||||
int buffers_get_data(void *data, unsigned int *length, buffers_t * bufs, int *type,
|
||||
int *channel, int *frame_index)
|
||||
{
|
||||
int res = -1;
|
||||
EnterCriticalSection(&(bufs->cs));
|
||||
if(bufs->front != bufs->rear)
|
||||
{
|
||||
res = *length = bufs->buf[bufs->front].length;
|
||||
memcpy(data, bufs->buf[bufs->front].start, *length);
|
||||
*type = bufs->buf[bufs->front].frame_type;
|
||||
*channel = bufs->buf[bufs->front].channel;
|
||||
*frame_index = bufs->buf[bufs->front].frame_index;
|
||||
bufs->front = (bufs->front + 1) % bufs->bufnum;
|
||||
//res = 1;
|
||||
}
|
||||
LeaveCriticalSection(&(bufs->cs));
|
||||
return res;
|
||||
}
|
||||
|
||||
int buffers_put_data(void *data, unsigned int length, buffers_t * bufs, int type,
|
||||
int channel, int frame_index)
|
||||
{
|
||||
int res = 0;
|
||||
EnterCriticalSection(&(bufs->cs));
|
||||
|
||||
if(((bufs->rear + 1) % bufs->bufnum) == bufs->front)
|
||||
{
|
||||
res = -1;
|
||||
}
|
||||
else
|
||||
{
|
||||
bufs->buf[bufs->rear].length = length;
|
||||
bufs->buf[bufs->rear].frame_type = type;
|
||||
bufs->buf[bufs->rear].channel = channel;
|
||||
bufs->buf[bufs->rear].frame_index = frame_index;
|
||||
if(length < iBufLen)
|
||||
{
|
||||
memcpy(bufs->buf[bufs->rear].start, data, length);
|
||||
}
|
||||
else
|
||||
{
|
||||
//WriteSystemLog("DataRecv.log", "Frame is too large");
|
||||
printf("Frame is too large, length=%d\r\n", length);
|
||||
}
|
||||
bufs->rear = (bufs->rear + 1) % bufs->bufnum;
|
||||
res = 1;
|
||||
}
|
||||
|
||||
LeaveCriticalSection(&(bufs->cs));
|
||||
return res;
|
||||
}
|
||||
|
||||
void buffers_clear_data(buffers_t * bufs)
|
||||
{
|
||||
EnterCriticalSection(&(bufs->cs));
|
||||
bufs->rear = 0;
|
||||
bufs->front = 0;
|
||||
LeaveCriticalSection(&(bufs->cs));
|
||||
}
|
||||
|
||||
|
170
external/libfaac/MtDSSBuffers.h
vendored
Normal file
170
external/libfaac/MtDSSBuffers.h
vendored
Normal file
|
@ -0,0 +1,170 @@
|
|||
|
||||
#ifndef _EasyDSSBuffers_H_
|
||||
#define _EasyDSSBuffers_H_
|
||||
|
||||
#define _CRT_SECURE_NO_WARNINGS
|
||||
|
||||
#ifdef _WIN32
|
||||
#include <guiddef.h>
|
||||
#include <time.h>
|
||||
#else
|
||||
#include <pthread.h>
|
||||
#include <sys/time.h>
|
||||
#endif
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <list>
|
||||
|
||||
#include <errno.h>
|
||||
#if (defined(_WIN32)) //windows
|
||||
//#define WIN32
|
||||
#ifndef DLL_EXPORT
|
||||
#define JD_API extern "C"__declspec(dllimport)
|
||||
#else
|
||||
#define JD_API extern "C"__declspec(dllexport)
|
||||
#endif
|
||||
#elif defined(__linux__) //linux
|
||||
#define __stdcall
|
||||
#define CALLBACK
|
||||
#define JD_API extern "C"
|
||||
#define WINAPI
|
||||
typedef int HANDLE;
|
||||
typedef int HWND;
|
||||
#endif
|
||||
|
||||
#ifdef _WIN32
|
||||
#include <Windows.h>
|
||||
#endif
|
||||
#include <string>
|
||||
#include <stdlib.h>
|
||||
#include <map>
|
||||
|
||||
using namespace std;
|
||||
|
||||
#define PFRAME 0x00
|
||||
#define IFRAME 0x01
|
||||
|
||||
const int iBufLen = 1024 * 128;
|
||||
const int iRecvBufLen = iBufLen * 2;
|
||||
const int iMaxParamterNum = 128;
|
||||
const int iBufNum = 10;
|
||||
const int MAX_BUF_NUM = 50;
|
||||
const int iCharBufLen = 64;
|
||||
const char BoundTag[] = "\r\n"; //帧间隔标识
|
||||
const int BoundTagLen = sizeof (BoundTag) - 1; //帧间隔标识长度
|
||||
//const char IFrameTag[] = "HISI264I";//录像I帧标志
|
||||
//const char PFrameTag[] = "HISI264P";//录像P帧标志
|
||||
//const int FrameTagLen = sizeof(IFrameTag) - 1;// 录像帧标志长度
|
||||
|
||||
const int MaxWaitTime = 3000; //超时时间
|
||||
const int MaxCameraNum = 24; //最大摄像机数量
|
||||
|
||||
const int AUDIO_BUFFER_SIZE = 960; //定义播放的每一片缓冲都是800个字节
|
||||
const int MAX_AUDIO_BUF = 4; //播放缓冲的通知索引
|
||||
const int BUFFERNOTIFYSIZE = AUDIO_BUFFER_SIZE;/*8192*//*192000*/ //缓冲通知位置的大小,请参见DirectSound应用程序开发快速入门
|
||||
const int SAMPLE_RATE = 8000;/*44100*/ //pcm 的采样率 8k
|
||||
const int N_CHANNEL = 1;/*2*/ //PCM 声道数 单通道
|
||||
const int BITS_PER_SAMPLE = 16; //每个采样点的比特数
|
||||
const int CHANNEL = 1;
|
||||
const int SAMPLES_PER_SECOND = 8000;
|
||||
const int SIZE_AUDIO_FRAME = 960;
|
||||
|
||||
#ifdef WIN32
|
||||
const GUID GUID_YUY2 = {0xc68e1552, 0x4a3f, 0x4706,
|
||||
{0xb2, 0xd4, 0x83, 0x41, 0x4f, 0x15, 0xdc, 0xcc}};
|
||||
//typedef char int8_t;
|
||||
//typedef unsigned char uint8_t;
|
||||
//typedef short int16_t;
|
||||
//typedef unsigned short uint16_t;
|
||||
//typedef int int32_t;
|
||||
//typedef unsigned int uint32_t;
|
||||
//typedef __int64 int64_t;
|
||||
//typedef unsigned __int64 uint64_t;
|
||||
#else
|
||||
typedef pthread_mutex_t CRITICAL_SECTION;
|
||||
#define InitializeCriticalSection pthread_mutex_init
|
||||
#define DeleteCriticalSection pthread_mutex_destroy
|
||||
#define EnterCriticalSection pthread_mutex_lock
|
||||
#define LeaveCriticalSection pthread_mutex_unlock
|
||||
//typedef void* LPVOID;
|
||||
//typedef unsigned long DWORD;
|
||||
//#define CloseHandle close
|
||||
#define Sleep(x) usleep(x*1000)
|
||||
//#define closesocket close
|
||||
//#define TRUE true
|
||||
//#define FALSE false
|
||||
//typedef bool BOOL;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
pthread_mutex_t mtx;
|
||||
pthread_cond_t cond;
|
||||
bool manual_reset;
|
||||
bool signaled;
|
||||
} THANDLE, *PHANDLE;
|
||||
|
||||
#define INFINITE 0xFFFFFFFF
|
||||
#define WAIT_TIMEOUT 0x00000102L
|
||||
#define WAIT_OBJECT_0 0
|
||||
#endif
|
||||
|
||||
#ifndef TRACE
|
||||
#define TRACE printf
|
||||
#endif
|
||||
|
||||
/*!
|
||||
\brief H264码流回调函数指针
|
||||
\param iPlayHandle 播放句柄
|
||||
\param sData 数据缓冲区
|
||||
\param iLen 数据长度
|
||||
\param iDataType 数据类型 0 - 实时数据流, 1 - 录像数据流, 2 - 本地采集的音频流, 3 - 设备发过来的音频流
|
||||
*/
|
||||
typedef void(CALLBACK* fVideoDataCallBack)(int iPlayHandle, char* sData, int iLen, int iDataType, void* pUserData);
|
||||
|
||||
/*!
|
||||
\brief 告警信息回调函数指针
|
||||
\param pAlarmInfo 告警信息T_JD_AlarmInfo结构体指针
|
||||
\param pUserData 用户数据
|
||||
*/
|
||||
typedef void(CALLBACK* fMessageCallBack)(void* pAlarmInfo, void* pUserData);
|
||||
|
||||
typedef struct
|
||||
{
|
||||
char *start;
|
||||
size_t length;
|
||||
int frame_type;
|
||||
int frame_index;
|
||||
int channel;
|
||||
} buffer_t;
|
||||
|
||||
typedef struct _buffers_t
|
||||
{
|
||||
int rear;
|
||||
int front;
|
||||
int bufnum;
|
||||
int fps;
|
||||
CRITICAL_SECTION cs;
|
||||
buffer_t buf[MAX_BUF_NUM];
|
||||
fVideoDataCallBack pOnVideoData; // 数据回调函数指针
|
||||
void* pUserData; //回调函数用户数据
|
||||
|
||||
_buffers_t()
|
||||
{
|
||||
pOnVideoData = NULL;
|
||||
pUserData = NULL;
|
||||
}
|
||||
|
||||
} buffers_t;
|
||||
|
||||
int init_buffers(buffers_t * bufs, int bufsize, int bufnum);
|
||||
|
||||
int free_buffers(buffers_t *bufs);
|
||||
|
||||
int buffers_get_data(void *data, unsigned int *length, buffers_t * bufs, int *type, int *channel, int *frame_index);
|
||||
|
||||
int buffers_put_data(void *data, unsigned int length, buffers_t * bufs, int type, int channel, int frame_index);
|
||||
|
||||
void buffers_clear_data(buffers_t * bufs);
|
||||
|
||||
#endif
|
78
external/libfaac/PcmToAac.cpp
vendored
Normal file
78
external/libfaac/PcmToAac.cpp
vendored
Normal file
|
@ -0,0 +1,78 @@
|
|||
|
||||
#include "PcmToAac.h"
|
||||
|
||||
#include "outDebug.h"
|
||||
|
||||
PcmToAac::PcmToAac(void)
|
||||
{
|
||||
m_nInputSamples=0;
|
||||
m_nMaxOutputBytes=0;
|
||||
m_nPCMBitSize = 16;
|
||||
}
|
||||
|
||||
|
||||
PcmToAac::~PcmToAac(void)
|
||||
{
|
||||
if (NULL != hEncoder)
|
||||
{
|
||||
/*Close FAAC engine*/
|
||||
faacEncClose(hEncoder);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
bool PcmToAac::Init(InAudioInfo* info)
|
||||
{
|
||||
unsigned int objectType = LOW;
|
||||
unsigned int mpegVersion = MPEG2;
|
||||
static unsigned int useTns = 0; //#define DEFAULT_TNS 0
|
||||
|
||||
//TODO: config this
|
||||
unsigned int nChannels = /*1*/info->Channel();
|
||||
|
||||
m_nPCMBitSize = /*16*/ info->PCMBitSize();
|
||||
unsigned long nInputSamples = 0;
|
||||
unsigned long nSampleRate = /*8000*/info->Samplerate();
|
||||
unsigned long nMaxOutputBytes = 0;
|
||||
|
||||
|
||||
/*open FAAC engine*/
|
||||
hEncoder = faacEncOpen(nSampleRate, nChannels, &nInputSamples, &nMaxOutputBytes);
|
||||
if (hEncoder == NULL)
|
||||
{
|
||||
if(AAC_DEBUG) printf("%s:[%d] failed to call faacEncOpen !\n", __FUNCTION__, __LINE__);
|
||||
//return -1;
|
||||
return false;
|
||||
}
|
||||
m_nInputSamples = nInputSamples;
|
||||
m_nMaxOutputBytes = nMaxOutputBytes;
|
||||
|
||||
|
||||
/*get current encoding configuration*/
|
||||
pConfiguration = faacEncGetCurrentConfiguration(hEncoder);
|
||||
pConfiguration->inputFormat = FAAC_INPUT_16BIT;
|
||||
|
||||
/*0 - raw; 1 - ADTS*/
|
||||
pConfiguration->outputFormat = 1;
|
||||
pConfiguration->useTns = useTns;
|
||||
pConfiguration->aacObjectType = objectType;
|
||||
pConfiguration->mpegVersion = mpegVersion;
|
||||
|
||||
/*set encoding configuretion*/
|
||||
faacEncSetConfiguration(hEncoder, pConfiguration);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
int PcmToAac::Encode(int32_t * pbPCMBuffer, unsigned int nPCMBufferSize, unsigned char * pbAACBuffer, unsigned int nMaxOutputBytes)
|
||||
{
|
||||
unsigned int nPCMBitSize = GetPCMBitSize();
|
||||
|
||||
|
||||
unsigned int nInputSamples = (nPCMBufferSize / (nPCMBitSize / 8));
|
||||
if(AAC_DEBUG) printf("%s:[%d] G711A -> PCM faacEncEncode....\n", __FUNCTION__, __LINE__);
|
||||
int nRet = faacEncEncode(hEncoder, (int*) pbPCMBuffer, nInputSamples, pbAACBuffer, nMaxOutputBytes);
|
||||
if(AAC_DEBUG) printf("%s:[%d] G711A -> PCM faacEncEncode\n", __FUNCTION__, __LINE__);
|
||||
|
||||
return nRet;
|
||||
}
|
51
external/libfaac/PcmToAac.h
vendored
Normal file
51
external/libfaac/PcmToAac.h
vendored
Normal file
|
@ -0,0 +1,51 @@
|
|||
|
||||
#pragma once
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include "IDecodeToPcm.h"
|
||||
|
||||
extern "C"
|
||||
{
|
||||
#include <faac.h>
|
||||
}
|
||||
|
||||
class PcmToAac
|
||||
{
|
||||
public:
|
||||
PcmToAac(void);
|
||||
~PcmToAac(void);
|
||||
public:
|
||||
bool Init(InAudioInfo* info);
|
||||
int Encode(int32_t * inputBuffer, unsigned int samplesInput, unsigned char *outputBuffer, unsigned int bufferSize);
|
||||
public:
|
||||
unsigned int GetPCMBitSize()
|
||||
{
|
||||
return m_nPCMBitSize;
|
||||
}
|
||||
unsigned int GetInputSamples()
|
||||
{
|
||||
return m_nInputSamples;
|
||||
}
|
||||
unsigned int GetMaxOutputBytes()
|
||||
{
|
||||
return m_nMaxOutputBytes;
|
||||
}
|
||||
unsigned int GetPCMBufferSize()
|
||||
{
|
||||
return (m_nInputSamples * (m_nPCMBitSize / 8));
|
||||
}
|
||||
|
||||
|
||||
private:
|
||||
faacEncHandle hEncoder;
|
||||
faacEncConfigurationPtr pConfiguration;
|
||||
|
||||
unsigned int m_nPCMBitSize /*= 16*/;
|
||||
|
||||
unsigned long m_nInputSamples /*= 0*/;
|
||||
|
||||
unsigned long m_nMaxOutputBytes /*= 0*/;
|
||||
};
|
||||
|
56
external/libfaac/audio_buffer.cpp
vendored
Normal file
56
external/libfaac/audio_buffer.cpp
vendored
Normal file
|
@ -0,0 +1,56 @@
|
|||
#include "audio_buffer.h"
|
||||
#include "MtDSSBuffers.h"
|
||||
#include "outDebug.h"
|
||||
|
||||
|
||||
audio_buffer::audio_buffer()
|
||||
{
|
||||
data_ = new unsigned char[iBufLen];
|
||||
len_ = 0;
|
||||
}
|
||||
|
||||
audio_buffer::~audio_buffer()
|
||||
{
|
||||
delete []data_;
|
||||
}
|
||||
|
||||
int audio_buffer::write_data(void* data, int len)
|
||||
{
|
||||
if (iBufLen - len_ < len)
|
||||
{
|
||||
if(AAC_DEBUG) printf("audio_buffer full\n");
|
||||
return -1;
|
||||
}
|
||||
if (len > 0)
|
||||
{
|
||||
memcpy(data_ + len_, data, len);
|
||||
len_ += len;
|
||||
return len;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int audio_buffer::get_data(unsigned char* dest, int how_you_want)
|
||||
{
|
||||
if (len_ == 0 || len_ < how_you_want)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
memcpy(dest, data_, how_you_want);
|
||||
memmove(data_, data_ + how_you_want, len_ - how_you_want);
|
||||
len_ -= how_you_want;
|
||||
return how_you_want;
|
||||
}
|
||||
}
|
||||
|
||||
unsigned char* audio_buffer::get_writable_ptr()
|
||||
{
|
||||
return data_ + len_;
|
||||
}
|
||||
|
||||
void audio_buffer::update_data_len(int len)
|
||||
{
|
||||
len_ += len;
|
||||
}
|
21
external/libfaac/audio_buffer.h
vendored
Normal file
21
external/libfaac/audio_buffer.h
vendored
Normal file
|
@ -0,0 +1,21 @@
|
|||
#pragma once
|
||||
|
||||
class audio_buffer
|
||||
{
|
||||
public:
|
||||
audio_buffer(void);
|
||||
~audio_buffer(void);
|
||||
|
||||
int write_data(void *data, int len);
|
||||
|
||||
int get_data(unsigned char *dest, int how_you_want);
|
||||
|
||||
void update_data_len(int len);
|
||||
|
||||
unsigned char *get_writable_ptr();
|
||||
|
||||
private:
|
||||
unsigned char *data_;
|
||||
int len_;
|
||||
};
|
||||
|
11
external/libfaac/condef.h
vendored
Normal file
11
external/libfaac/condef.h
vendored
Normal file
|
@ -0,0 +1,11 @@
|
|||
#ifndef _CONDEF_H
|
||||
#define _CONDEF_H
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#define SAFE_DELETE_OBJ(OBJ) {if(NULL!=OBJ){delete OBJ;OBJ=NULL;}}
|
||||
#define SAFE_FREE_BUF(OBJ) {if(NULL!=OBJ){free(OBJ);OBJ=NULL;}}
|
||||
|
||||
#endif
|
99
external/libfaac/faac.h
vendored
Normal file
99
external/libfaac/faac.h
vendored
Normal file
|
@ -0,0 +1,99 @@
|
|||
/*
|
||||
* FAAC - Freeware Advanced Audio Coder
|
||||
* Copyright (C) 2001 Menno Bakker
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
* $Id: faac.h,v 1.36 2009/01/25 18:50:32 menno Exp $
|
||||
*/
|
||||
|
||||
#ifndef _FAAC_H_
|
||||
#define _FAAC_H_
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif /* __cplusplus */
|
||||
|
||||
#if defined(_WIN32) && !defined(__MINGW32__)
|
||||
# ifndef FAACAPI
|
||||
# define FAACAPI __stdcall
|
||||
# endif
|
||||
#else
|
||||
# ifndef FAACAPI
|
||||
# define FAACAPI
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#pragma pack(push, 1)
|
||||
|
||||
typedef struct {
|
||||
void *ptr;
|
||||
char *name;
|
||||
}
|
||||
psymodellist_t;
|
||||
|
||||
#include "faaccfg.h"
|
||||
|
||||
|
||||
typedef void *faacEncHandle;
|
||||
|
||||
#ifndef HAVE_INT32_T
|
||||
typedef signed int int32_t;
|
||||
#endif
|
||||
|
||||
/*
|
||||
Allows an application to get FAAC version info. This is intended
|
||||
purely for informative purposes.
|
||||
|
||||
Returns FAAC_CFG_VERSION.
|
||||
*/
|
||||
int FAACAPI faacEncGetVersion(char **faac_id_string,
|
||||
char **faac_copyright_string);
|
||||
|
||||
|
||||
faacEncConfigurationPtr FAACAPI
|
||||
faacEncGetCurrentConfiguration(faacEncHandle hEncoder);
|
||||
|
||||
|
||||
int FAACAPI faacEncSetConfiguration(faacEncHandle hEncoder,
|
||||
faacEncConfigurationPtr config);
|
||||
|
||||
|
||||
faacEncHandle FAACAPI faacEncOpen(unsigned long sampleRate,
|
||||
unsigned int numChannels,
|
||||
unsigned long *inputSamples,
|
||||
unsigned long *maxOutputBytes);
|
||||
|
||||
|
||||
int FAACAPI faacEncGetDecoderSpecificInfo(faacEncHandle hEncoder, unsigned char **ppBuffer,
|
||||
unsigned long *pSizeOfDecoderSpecificInfo);
|
||||
|
||||
|
||||
int FAACAPI faacEncEncode(faacEncHandle hEncoder, int32_t * inputBuffer, unsigned int samplesInput,
|
||||
unsigned char *outputBuffer,
|
||||
unsigned int bufferSize);
|
||||
|
||||
|
||||
int FAACAPI faacEncClose(faacEncHandle hEncoder);
|
||||
|
||||
|
||||
|
||||
#pragma pack(pop)
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif /* __cplusplus */
|
||||
|
||||
#endif /* _FAAC_H_ */
|
122
external/libfaac/faaccfg.h
vendored
Normal file
122
external/libfaac/faaccfg.h
vendored
Normal file
|
@ -0,0 +1,122 @@
|
|||
/*
|
||||
* FAAC - Freeware Advanced Audio Coder
|
||||
* Copyright (C) 2001 Menno Bakker
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
* $Id: faaccfg.h,v 1.3 2004/07/04 12:12:05 corrados Exp $
|
||||
*/
|
||||
|
||||
#ifndef _FAACCFG_H_
|
||||
#define _FAACCFG_H_
|
||||
|
||||
#define FAAC_CFG_VERSION 104
|
||||
|
||||
/* MPEG ID's */
|
||||
#define MPEG2 1
|
||||
#define MPEG4 0
|
||||
|
||||
/* AAC object types */
|
||||
#define MAIN 1
|
||||
#define LOW 2
|
||||
#define SSR 3
|
||||
#define LTP 4
|
||||
|
||||
/* Input Formats */
|
||||
#define FAAC_INPUT_NULL 0
|
||||
#define FAAC_INPUT_16BIT 1
|
||||
#define FAAC_INPUT_24BIT 2
|
||||
#define FAAC_INPUT_32BIT 3
|
||||
#define FAAC_INPUT_FLOAT 4
|
||||
|
||||
#define SHORTCTL_NORMAL 0
|
||||
#define SHORTCTL_NOSHORT 1
|
||||
#define SHORTCTL_NOLONG 2
|
||||
|
||||
#pragma pack(push, 1)
|
||||
typedef struct faacEncConfiguration
|
||||
{
|
||||
/* config version */
|
||||
int version;
|
||||
|
||||
/* library version */
|
||||
char *name;
|
||||
|
||||
/* copyright string */
|
||||
char *copyright;
|
||||
|
||||
/* MPEG version, 2 or 4 */
|
||||
unsigned int mpegVersion;
|
||||
|
||||
/* AAC object type */
|
||||
unsigned int aacObjectType;
|
||||
|
||||
/* Allow mid/side coding */
|
||||
unsigned int allowMidside;
|
||||
|
||||
/* Use one of the channels as LFE channel */
|
||||
unsigned int useLfe;
|
||||
|
||||
/* Use Temporal Noise Shaping */
|
||||
unsigned int useTns;
|
||||
|
||||
/* bitrate / channel of AAC file */
|
||||
unsigned long bitRate;
|
||||
|
||||
/* AAC file frequency bandwidth */
|
||||
unsigned int bandWidth;
|
||||
|
||||
/* Quantizer quality */
|
||||
unsigned long quantqual;
|
||||
|
||||
/* Bitstream output format (0 = Raw; 1 = ADTS) */
|
||||
unsigned int outputFormat;
|
||||
|
||||
/* psychoacoustic model list */
|
||||
psymodellist_t *psymodellist;
|
||||
|
||||
/* selected index in psymodellist */
|
||||
unsigned int psymodelidx;
|
||||
|
||||
/*
|
||||
PCM Sample Input Format
|
||||
0 FAAC_INPUT_NULL invalid, signifies a misconfigured config
|
||||
1 FAAC_INPUT_16BIT native endian 16bit
|
||||
2 FAAC_INPUT_24BIT native endian 24bit in 24 bits (not implemented)
|
||||
3 FAAC_INPUT_32BIT native endian 24bit in 32 bits (DEFAULT)
|
||||
4 FAAC_INPUT_FLOAT 32bit floating point
|
||||
*/
|
||||
unsigned int inputFormat;
|
||||
|
||||
/* block type enforcing (SHORTCTL_NORMAL/SHORTCTL_NOSHORT/SHORTCTL_NOLONG) */
|
||||
int shortctl;
|
||||
|
||||
/*
|
||||
Channel Remapping
|
||||
|
||||
Default 0, 1, 2, 3 ... 63 (64 is MAX_CHANNELS in coder.h)
|
||||
|
||||
WAVE 4.0 2, 0, 1, 3
|
||||
WAVE 5.0 2, 0, 1, 3, 4
|
||||
WAVE 5.1 2, 0, 1, 4, 5, 3
|
||||
AIFF 5.1 2, 0, 3, 1, 4, 5
|
||||
*/
|
||||
int channel_map[64];
|
||||
|
||||
} faacEncConfiguration, *faacEncConfigurationPtr;
|
||||
|
||||
#pragma pack(pop)
|
||||
|
||||
#endif /* _FAACCFG_H_ */
|
306
external/libfaac/g711.cpp
vendored
Normal file
306
external/libfaac/g711.cpp
vendored
Normal file
|
@ -0,0 +1,306 @@
|
|||
/*
|
||||
* g711.c
|
||||
*
|
||||
* u-law, A-law and linear PCM conversions.
|
||||
*/
|
||||
|
||||
//#include "stdafx.h"
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include "g711.h"
|
||||
|
||||
#define SIGN_BIT (0x80) /* Sign bit for a A-law byte. */
|
||||
#define QUANT_MASK (0xf) /* Quantization field mask. */
|
||||
#define NSEGS (8) /* Number of A-law segments. */
|
||||
#define SEG_SHIFT (4) /* Left shift for segment number. */
|
||||
#define SEG_MASK (0x70) /* Segment field mask. */
|
||||
|
||||
static short seg_end[8] = {0xFF, 0x1FF, 0x3FF, 0x7FF,
|
||||
0xFFF, 0x1FFF, 0x3FFF, 0x7FFF};
|
||||
|
||||
/* copy from CCITT G.711 specifications */
|
||||
unsigned char _u2a[128] = { /* u- to A-law conversions */
|
||||
1, 1, 2, 2, 3, 3, 4, 4,
|
||||
5, 5, 6, 6, 7, 7, 8, 8,
|
||||
9, 10, 11, 12, 13, 14, 15, 16,
|
||||
17, 18, 19, 20, 21, 22, 23, 24,
|
||||
25, 27, 29, 31, 33, 34, 35, 36,
|
||||
37, 38, 39, 40, 41, 42, 43, 44,
|
||||
46, 48, 49, 50, 51, 52, 53, 54,
|
||||
55, 56, 57, 58, 59, 60, 61, 62,
|
||||
64, 65, 66, 67, 68, 69, 70, 71,
|
||||
72, 73, 74, 75, 76, 77, 78, 79,
|
||||
81, 82, 83, 84, 85, 86, 87, 88,
|
||||
89, 90, 91, 92, 93, 94, 95, 96,
|
||||
97, 98, 99, 100, 101, 102, 103, 104,
|
||||
105, 106, 107, 108, 109, 110, 111, 112,
|
||||
113, 114, 115, 116, 117, 118, 119, 120,
|
||||
121, 122, 123, 124, 125, 126, 127, 128};
|
||||
|
||||
unsigned char _a2u[128] = { /* A- to u-law conversions */
|
||||
1, 3, 5, 7, 9, 11, 13, 15,
|
||||
16, 17, 18, 19, 20, 21, 22, 23,
|
||||
24, 25, 26, 27, 28, 29, 30, 31,
|
||||
32, 32, 33, 33, 34, 34, 35, 35,
|
||||
36, 37, 38, 39, 40, 41, 42, 43,
|
||||
44, 45, 46, 47, 48, 48, 49, 49,
|
||||
50, 51, 52, 53, 54, 55, 56, 57,
|
||||
58, 59, 60, 61, 62, 63, 64, 64,
|
||||
65, 66, 67, 68, 69, 70, 71, 72,
|
||||
73, 74, 75, 76, 77, 78, 79, 79,
|
||||
80, 81, 82, 83, 84, 85, 86, 87,
|
||||
88, 89, 90, 91, 92, 93, 94, 95,
|
||||
96, 97, 98, 99, 100, 101, 102, 103,
|
||||
104, 105, 106, 107, 108, 109, 110, 111,
|
||||
112, 113, 114, 115, 116, 117, 118, 119,
|
||||
120, 121, 122, 123, 124, 125, 126, 127};
|
||||
|
||||
static int
|
||||
search(
|
||||
int val,
|
||||
short *table,
|
||||
int size)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < size; i++) {
|
||||
if (val <= *table++)
|
||||
return (i);
|
||||
}
|
||||
return (size);
|
||||
}
|
||||
|
||||
/*
|
||||
* linear2alaw() - Convert a 16-bit linear PCM value to 8-bit A-law
|
||||
*
|
||||
* linear2alaw() accepts an 16-bit integer and encodes it as A-law data.
|
||||
*
|
||||
* Linear Input Code Compressed Code
|
||||
* ------------------------ ---------------
|
||||
* 0000000wxyza 000wxyz
|
||||
* 0000001wxyza 001wxyz
|
||||
* 000001wxyzab 010wxyz
|
||||
* 00001wxyzabc 011wxyz
|
||||
* 0001wxyzabcd 100wxyz
|
||||
* 001wxyzabcde 101wxyz
|
||||
* 01wxyzabcdef 110wxyz
|
||||
* 1wxyzabcdefg 111wxyz
|
||||
*
|
||||
* For further information see John C. Bellamy's Digital Telephony, 1982,
|
||||
* John Wiley & Sons, pps 98-111 and 472-476.
|
||||
*/
|
||||
unsigned char
|
||||
linear2alaw(
|
||||
int pcm_val) /* 2's complement (16-bit range) */
|
||||
{
|
||||
int mask;
|
||||
int seg;
|
||||
unsigned char aval;
|
||||
|
||||
if (pcm_val >= 0) {
|
||||
mask = 0xD5; /* sign (7th) bit = 1 */
|
||||
} else {
|
||||
mask = 0x55; /* sign bit = 0 */
|
||||
pcm_val = -pcm_val - 8;
|
||||
}
|
||||
|
||||
/* Convert the scaled magnitude to segment number. */
|
||||
seg = search(pcm_val, seg_end, 8);
|
||||
|
||||
/* Combine the sign, segment, and quantization bits. */
|
||||
|
||||
if (seg >= 8) /* out of range, return maximum value. */
|
||||
return (0x7F ^ mask);
|
||||
else {
|
||||
aval = seg << SEG_SHIFT;
|
||||
if (seg < 2)
|
||||
aval |= (pcm_val >> 4) & QUANT_MASK;
|
||||
else
|
||||
aval |= (pcm_val >> (seg + 3)) & QUANT_MASK;
|
||||
return (aval ^ mask);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* alaw2linear() - Convert an A-law value to 16-bit linear PCM
|
||||
*
|
||||
*/
|
||||
int
|
||||
alaw2linear(
|
||||
unsigned char a_val)
|
||||
{
|
||||
int t;
|
||||
int seg;
|
||||
|
||||
a_val ^= 0x55;
|
||||
|
||||
t = (a_val & QUANT_MASK) << 4;
|
||||
seg = ((unsigned)a_val & SEG_MASK) >> SEG_SHIFT;
|
||||
switch (seg) {
|
||||
case 0:
|
||||
t += 8;
|
||||
break;
|
||||
case 1:
|
||||
t += 0x108;
|
||||
break;
|
||||
default:
|
||||
t += 0x108;
|
||||
t <<= seg - 1;
|
||||
}
|
||||
return ((a_val & SIGN_BIT) ? t : -t);
|
||||
}
|
||||
|
||||
#define BIAS (0x84) /* Bias for linear code. */
|
||||
|
||||
/*
|
||||
* linear2ulaw() - Convert a linear PCM value to u-law
|
||||
*
|
||||
* In order to simplify the encoding process, the original linear magnitude
|
||||
* is biased by adding 33 which shifts the encoding range from (0 - 8158) to
|
||||
* (33 - 8191). The result can be seen in the following encoding table:
|
||||
*
|
||||
* Biased Linear Input Code Compressed Code
|
||||
* ------------------------ ---------------
|
||||
* 00000001wxyza 000wxyz
|
||||
* 0000001wxyzab 001wxyz
|
||||
* 000001wxyzabc 010wxyz
|
||||
* 00001wxyzabcd 011wxyz
|
||||
* 0001wxyzabcde 100wxyz
|
||||
* 001wxyzabcdef 101wxyz
|
||||
* 01wxyzabcdefg 110wxyz
|
||||
* 1wxyzabcdefgh 111wxyz
|
||||
*
|
||||
* Each biased linear code has a leading 1 which identifies the segment
|
||||
* number. The value of the segment number is equal to 7 minus the number
|
||||
* of leading 0's. The quantization interval is directly available as the
|
||||
* four bits wxyz. * The trailing bits (a - h) are ignored.
|
||||
*
|
||||
* Ordinarily the complement of the resulting code word is used for
|
||||
* transmission, and so the code word is complemented before it is returned.
|
||||
*
|
||||
* For further information see John C. Bellamy's Digital Telephony, 1982,
|
||||
* John Wiley & Sons, pps 98-111 and 472-476.
|
||||
*/
|
||||
unsigned char
|
||||
linear2ulaw(
|
||||
int pcm_val) /* 2's complement (16-bit range) */
|
||||
{
|
||||
int mask;
|
||||
int seg;
|
||||
unsigned char uval;
|
||||
|
||||
/* Get the sign and the magnitude of the value. */
|
||||
if (pcm_val < 0) {
|
||||
pcm_val = BIAS - pcm_val;
|
||||
mask = 0x7F;
|
||||
} else {
|
||||
pcm_val += BIAS;
|
||||
mask = 0xFF;
|
||||
}
|
||||
|
||||
/* Convert the scaled magnitude to segment number. */
|
||||
seg = search(pcm_val, seg_end, 8);
|
||||
|
||||
/*
|
||||
* Combine the sign, segment, quantization bits;
|
||||
* and complement the code word.
|
||||
*/
|
||||
if (seg >= 8) /* out of range, return maximum value. */
|
||||
return (0x7F ^ mask);
|
||||
else {
|
||||
uval = (seg << 4) | ((pcm_val >> (seg + 3)) & 0xF);
|
||||
return (uval ^ mask);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
* ulaw2linear() - Convert a u-law value to 16-bit linear PCM
|
||||
*
|
||||
* First, a biased linear code is derived from the code word. An unbiased
|
||||
* output can then be obtained by subtracting 33 from the biased code.
|
||||
*
|
||||
* Note that this function expects to be passed the complement of the
|
||||
* original code word. This is in keeping with ISDN conventions.
|
||||
*/
|
||||
int
|
||||
ulaw2linear(
|
||||
unsigned char u_val)
|
||||
{
|
||||
int t;
|
||||
|
||||
/* Complement to obtain normal u-law value. */
|
||||
u_val = ~u_val;
|
||||
|
||||
/*
|
||||
* Extract and bias the quantization bits. Then
|
||||
* shift up by the segment number and subtract out the bias.
|
||||
*/
|
||||
t = ((u_val & QUANT_MASK) << 3) + BIAS;
|
||||
t <<= ((unsigned)u_val & SEG_MASK) >> SEG_SHIFT;
|
||||
|
||||
return ((u_val & SIGN_BIT) ? (BIAS - t) : (t - BIAS));
|
||||
}
|
||||
|
||||
/* A-law to u-law conversion */
|
||||
unsigned char
|
||||
alaw2ulaw(
|
||||
unsigned char aval)
|
||||
{
|
||||
aval &= 0xff;
|
||||
return ((aval & 0x80) ? (0xFF ^ _a2u[aval ^ 0xD5]) :
|
||||
(0x7F ^ _a2u[aval ^ 0x55]));
|
||||
}
|
||||
|
||||
/* u-law to A-law conversion */
|
||||
unsigned char
|
||||
ulaw2alaw(
|
||||
unsigned char uval)
|
||||
{
|
||||
uval &= 0xff;
|
||||
return ((uval & 0x80) ? (0xD5 ^ (_u2a[0xFF ^ uval] - 1)) :
|
||||
(0x55 ^ (_u2a[0x7F ^ uval] - 1)));
|
||||
}
|
||||
|
||||
int g711_decode(void *pout_buf, int *pout_len, const void *pin_buf, const int in_len , int type)
|
||||
{
|
||||
int16_t *dst = (int16_t *) pout_buf;
|
||||
uint8_t *src = (uint8_t *) pin_buf;
|
||||
uint32_t i = 0;
|
||||
int Ret = 0;
|
||||
|
||||
if ((NULL == pout_buf) || \
|
||||
(NULL == pout_len) || \
|
||||
(NULL == pin_buf) || \
|
||||
(0 == in_len))
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (*pout_len < 2 * in_len)
|
||||
{
|
||||
return -2;
|
||||
}
|
||||
//---{{{
|
||||
if (TP_ALAW == type)
|
||||
{
|
||||
for (i = 0; i < in_len; i++)
|
||||
{
|
||||
//*(dst++) = alawtos16[*(src++)];
|
||||
*(dst++) = (int16_t)alaw2linear(*(src++));
|
||||
}
|
||||
}else
|
||||
{
|
||||
for (i = 0; i < in_len; i++)
|
||||
{
|
||||
//*(dst++) = alawtos16[*(src++)];
|
||||
*(dst++) = (int16_t)ulaw2linear(*(src++));
|
||||
}
|
||||
}
|
||||
|
||||
//---}}}
|
||||
*pout_len = 2 * in_len;
|
||||
|
||||
Ret = 2 * in_len;
|
||||
return Ret;
|
||||
}
|
24
external/libfaac/g711.h
vendored
Normal file
24
external/libfaac/g711.h
vendored
Normal file
|
@ -0,0 +1,24 @@
|
|||
|
||||
#ifndef __G_711_H_
|
||||
#define __G_711_H_
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
enum _e_g711_tp
|
||||
{
|
||||
TP_ALAW, //G711A
|
||||
TP_ULAW //G711U
|
||||
};
|
||||
|
||||
unsigned char linear2alaw(int pcm_val); /* 2's complement (16-bit range) */
|
||||
int alaw2linear(unsigned char a_val);
|
||||
|
||||
unsigned char linear2ulaw(int pcm_val); /* 2's complement (16-bit range) */
|
||||
int ulaw2linear(unsigned char u_val);
|
||||
|
||||
unsigned char alaw2ulaw(unsigned char aval);
|
||||
unsigned char ulaw2alaw(unsigned char uval);
|
||||
|
||||
int g711_decode(void *pout_buf, int *pout_len, const void *pin_buf, const int in_len , int type);
|
||||
|
||||
#endif
|
708
external/libfaac/libfaac/aacquant.c
vendored
Normal file
708
external/libfaac/libfaac/aacquant.c
vendored
Normal file
|
@ -0,0 +1,708 @@
|
|||
/*
|
||||
* FAAC - Freeware Advanced Audio Coder
|
||||
* Copyright (C) 2001 Menno Bakker
|
||||
* Copyright (C) 2002, 2003 Krzysztof Nikiel
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
* $Id: aacquant.c,v 1.32 2008/03/23 23:00:25 menno Exp $
|
||||
*/
|
||||
|
||||
#include <math.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "frame.h"
|
||||
#include "aacquant.h"
|
||||
#include "coder.h"
|
||||
#include "huffman.h"
|
||||
#include "psych.h"
|
||||
#include "util.h"
|
||||
|
||||
#define TAKEHIRO_IEEE754_HACK 1
|
||||
|
||||
#define XRPOW_FTOI(src,dest) ((dest) = (int)(src))
|
||||
#define QUANTFAC(rx) adj43[rx]
|
||||
#define ROUNDFAC 0.4054
|
||||
|
||||
static int FixNoise(CoderInfo *coderInfo,
|
||||
const double *xr,
|
||||
double *xr_pow,
|
||||
int *xi,
|
||||
double *xmin,
|
||||
double *pow43,
|
||||
double *adj43);
|
||||
|
||||
static void CalcAllowedDist(CoderInfo *coderInfo, PsyInfo *psyInfo,
|
||||
double *xr, double *xmin, int quality);
|
||||
|
||||
|
||||
void AACQuantizeInit(CoderInfo *coderInfo, unsigned int numChannels,
|
||||
AACQuantCfg *aacquantCfg)
|
||||
{
|
||||
unsigned int channel, i;
|
||||
|
||||
aacquantCfg->pow43 = (double*)AllocMemory(PRECALC_SIZE*sizeof(double));
|
||||
aacquantCfg->adj43 = (double*)AllocMemory(PRECALC_SIZE*sizeof(double));
|
||||
|
||||
aacquantCfg->pow43[0] = 0.0;
|
||||
for(i=1;i<PRECALC_SIZE;i++)
|
||||
aacquantCfg->pow43[i] = pow((double)i, 4.0/3.0);
|
||||
|
||||
#if TAKEHIRO_IEEE754_HACK
|
||||
aacquantCfg->adj43[0] = 0.0;
|
||||
for (i = 1; i < PRECALC_SIZE; i++)
|
||||
aacquantCfg->adj43[i] = i - 0.5 - pow(0.5 * (aacquantCfg->pow43[i - 1] + aacquantCfg->pow43[i]),0.75);
|
||||
#else // !TAKEHIRO_IEEE754_HACK
|
||||
for (i = 0; i < PRECALC_SIZE-1; i++)
|
||||
aacquantCfg->adj43[i] = (i + 1) - pow(0.5 * (aacquantCfg->pow43[i] + aacquantCfg->pow43[i + 1]), 0.75);
|
||||
aacquantCfg->adj43[i] = 0.5;
|
||||
#endif
|
||||
|
||||
for (channel = 0; channel < numChannels; channel++) {
|
||||
coderInfo[channel].requantFreq = (double*)AllocMemory(BLOCK_LEN_LONG*sizeof(double));
|
||||
}
|
||||
}
|
||||
|
||||
void AACQuantizeEnd(CoderInfo *coderInfo, unsigned int numChannels,
|
||||
AACQuantCfg *aacquantCfg)
|
||||
{
|
||||
unsigned int channel;
|
||||
|
||||
if (aacquantCfg->pow43)
|
||||
{
|
||||
FreeMemory(aacquantCfg->pow43);
|
||||
aacquantCfg->pow43 = NULL;
|
||||
}
|
||||
if (aacquantCfg->adj43)
|
||||
{
|
||||
FreeMemory(aacquantCfg->adj43);
|
||||
aacquantCfg->adj43 = NULL;
|
||||
}
|
||||
|
||||
for (channel = 0; channel < numChannels; channel++) {
|
||||
if (coderInfo[channel].requantFreq) FreeMemory(coderInfo[channel].requantFreq);
|
||||
}
|
||||
}
|
||||
|
||||
static void BalanceEnergy(CoderInfo *coderInfo,
|
||||
const double *xr, const int *xi,
|
||||
double *pow43)
|
||||
{
|
||||
const double ifqstep = pow(2.0, 0.25);
|
||||
const double logstep_1 = 1.0 / log(ifqstep);
|
||||
int sb;
|
||||
int nsfb = coderInfo->nr_of_sfb;
|
||||
int start, end;
|
||||
int l;
|
||||
double en0, enq;
|
||||
int shift;
|
||||
|
||||
for (sb = 0; sb < nsfb; sb++)
|
||||
{
|
||||
double qfac_1;
|
||||
|
||||
start = coderInfo->sfb_offset[sb];
|
||||
end = coderInfo->sfb_offset[sb+1];
|
||||
|
||||
qfac_1 = pow(2.0, -0.25*(coderInfo->scale_factor[sb] - coderInfo->global_gain));
|
||||
|
||||
en0 = 0.0;
|
||||
enq = 0.0;
|
||||
for (l = start; l < end; l++)
|
||||
{
|
||||
double xq;
|
||||
|
||||
if (!sb && !xi[l])
|
||||
continue;
|
||||
|
||||
xq = pow43[xi[l]];
|
||||
|
||||
en0 += xr[l] * xr[l];
|
||||
enq += xq * xq;
|
||||
}
|
||||
|
||||
if (enq == 0.0)
|
||||
continue;
|
||||
|
||||
enq *= qfac_1 * qfac_1;
|
||||
|
||||
shift = (int)(log(sqrt(enq / en0)) * logstep_1 + 1000.5);
|
||||
shift -= 1000;
|
||||
|
||||
shift += coderInfo->scale_factor[sb];
|
||||
coderInfo->scale_factor[sb] = shift;
|
||||
}
|
||||
}
|
||||
|
||||
static void UpdateRequant(CoderInfo *coderInfo, int *xi,
|
||||
double *pow43)
|
||||
{
|
||||
double *requant_xr = coderInfo->requantFreq;
|
||||
int sb;
|
||||
int i;
|
||||
|
||||
for (sb = 0; sb < coderInfo->nr_of_sfb; sb++)
|
||||
{
|
||||
double invQuantFac =
|
||||
pow(2.0, -0.25*(coderInfo->scale_factor[sb] - coderInfo->global_gain));
|
||||
int start = coderInfo->sfb_offset[sb];
|
||||
int end = coderInfo->sfb_offset[sb + 1];
|
||||
|
||||
for (i = start; i < end; i++)
|
||||
requant_xr[i] = pow43[xi[i]] * invQuantFac;
|
||||
}
|
||||
}
|
||||
|
||||
int AACQuantize(CoderInfo *coderInfo,
|
||||
PsyInfo *psyInfo,
|
||||
ChannelInfo *channelInfo,
|
||||
int *cb_width,
|
||||
int num_cb,
|
||||
double *xr,
|
||||
AACQuantCfg *aacquantCfg)
|
||||
{
|
||||
int sb, i, do_q = 0;
|
||||
int bits = 0, sign;
|
||||
double xr_pow[FRAME_LEN];
|
||||
double xmin[MAX_SCFAC_BANDS];
|
||||
int xi[FRAME_LEN];
|
||||
|
||||
/* Use local copy's */
|
||||
int *scale_factor = coderInfo->scale_factor;
|
||||
|
||||
/* Set all scalefactors to 0 */
|
||||
coderInfo->global_gain = 0;
|
||||
for (sb = 0; sb < coderInfo->nr_of_sfb; sb++)
|
||||
scale_factor[sb] = 0;
|
||||
|
||||
/* Compute xr_pow */
|
||||
for (i = 0; i < FRAME_LEN; i++) {
|
||||
double temp = fabs(xr[i]);
|
||||
xr_pow[i] = sqrt(temp * sqrt(temp));
|
||||
do_q += (temp > 1E-20);
|
||||
}
|
||||
|
||||
if (do_q) {
|
||||
CalcAllowedDist(coderInfo, psyInfo, xr, xmin, aacquantCfg->quality);
|
||||
coderInfo->global_gain = 0;
|
||||
FixNoise(coderInfo, xr, xr_pow, xi, xmin,
|
||||
aacquantCfg->pow43, aacquantCfg->adj43);
|
||||
BalanceEnergy(coderInfo, xr, xi, aacquantCfg->pow43);
|
||||
UpdateRequant(coderInfo, xi, aacquantCfg->pow43);
|
||||
|
||||
for ( i = 0; i < FRAME_LEN; i++ ) {
|
||||
sign = (xr[i] < 0) ? -1 : 1;
|
||||
xi[i] *= sign;
|
||||
coderInfo->requantFreq[i] *= sign;
|
||||
}
|
||||
} else {
|
||||
coderInfo->global_gain = 0;
|
||||
SetMemory(xi, 0, FRAME_LEN*sizeof(int));
|
||||
}
|
||||
|
||||
BitSearch(coderInfo, xi);
|
||||
|
||||
/* offset the difference of common_scalefac and scalefactors by SF_OFFSET */
|
||||
for (i = 0; i < coderInfo->nr_of_sfb; i++) {
|
||||
if ((coderInfo->book_vector[i]!=INTENSITY_HCB)&&(coderInfo->book_vector[i]!=INTENSITY_HCB2)) {
|
||||
scale_factor[i] = coderInfo->global_gain - scale_factor[i] + SF_OFFSET;
|
||||
}
|
||||
}
|
||||
coderInfo->global_gain = scale_factor[0];
|
||||
#if 0
|
||||
printf("global gain: %d\n", coderInfo->global_gain);
|
||||
for (i = 0; i < coderInfo->nr_of_sfb; i++)
|
||||
printf("sf %d: %d\n", i, coderInfo->scale_factor[i]);
|
||||
#endif
|
||||
// clamp to valid diff range
|
||||
{
|
||||
int previous_scale_factor = coderInfo->global_gain;
|
||||
int previous_is_factor = 0;
|
||||
for (i = 0; i < coderInfo->nr_of_sfb; i++) {
|
||||
if ((coderInfo->book_vector[i]==INTENSITY_HCB) ||
|
||||
(coderInfo->book_vector[i]==INTENSITY_HCB2)) {
|
||||
const int diff = scale_factor[i] - previous_is_factor;
|
||||
if (diff < -60) scale_factor[i] = previous_is_factor - 60;
|
||||
else if (diff > 59) scale_factor[i] = previous_is_factor + 59;
|
||||
previous_is_factor = scale_factor[i];
|
||||
// printf("sf %d: %d diff=%d **\n", i, coderInfo->scale_factor[i], diff);
|
||||
} else if (coderInfo->book_vector[i]) {
|
||||
const int diff = scale_factor[i] - previous_scale_factor;
|
||||
if (diff < -60) scale_factor[i] = previous_scale_factor - 60;
|
||||
else if (diff > 59) scale_factor[i] = previous_scale_factor + 59;
|
||||
previous_scale_factor = scale_factor[i];
|
||||
// printf("sf %d: %d diff=%d\n", i, coderInfo->scale_factor[i], diff);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* place the codewords and their respective lengths in arrays data[] and len[] respectively */
|
||||
/* there are 'counter' elements in each array, and these are variable length arrays depending on the input */
|
||||
#ifdef DRM
|
||||
coderInfo->iLenReordSpData = 0; /* init length of reordered spectral data */
|
||||
coderInfo->iLenLongestCW = 0; /* init length of longest codeword */
|
||||
coderInfo->cur_cw = 0; /* init codeword counter */
|
||||
#endif
|
||||
coderInfo->spectral_count = 0;
|
||||
sb = 0;
|
||||
for(i = 0; i < coderInfo->nr_of_sfb; i++) {
|
||||
OutputBits(
|
||||
coderInfo,
|
||||
#ifdef DRM
|
||||
&coderInfo->book_vector[i], /* needed for VCB11 */
|
||||
#else
|
||||
coderInfo->book_vector[i],
|
||||
#endif
|
||||
xi,
|
||||
coderInfo->sfb_offset[i],
|
||||
coderInfo->sfb_offset[i+1]-coderInfo->sfb_offset[i]);
|
||||
|
||||
if (coderInfo->book_vector[i])
|
||||
sb = i;
|
||||
}
|
||||
|
||||
// FIXME: Check those max_sfb/nr_of_sfb. Isn't it the same?
|
||||
coderInfo->max_sfb = coderInfo->nr_of_sfb = sb + 1;
|
||||
|
||||
return bits;
|
||||
}
|
||||
|
||||
|
||||
#if TAKEHIRO_IEEE754_HACK
|
||||
|
||||
typedef union {
|
||||
float f;
|
||||
int i;
|
||||
} fi_union;
|
||||
|
||||
#define MAGIC_FLOAT (65536*(128))
|
||||
#define MAGIC_INT 0x4b000000
|
||||
|
||||
#if 0
|
||||
static void Quantize(const double *xp, int *pi, double istep)
|
||||
{
|
||||
int j;
|
||||
fi_union *fi;
|
||||
|
||||
fi = (fi_union *)pi;
|
||||
for (j = FRAME_LEN/4 - 1; j >= 0; --j) {
|
||||
double x0 = istep * xp[0];
|
||||
double x1 = istep * xp[1];
|
||||
double x2 = istep * xp[2];
|
||||
double x3 = istep * xp[3];
|
||||
|
||||
x0 += MAGIC_FLOAT; fi[0].f = x0;
|
||||
x1 += MAGIC_FLOAT; fi[1].f = x1;
|
||||
x2 += MAGIC_FLOAT; fi[2].f = x2;
|
||||
x3 += MAGIC_FLOAT; fi[3].f = x3;
|
||||
|
||||
fi[0].f = x0 + (adj43asm - MAGIC_INT)[fi[0].i];
|
||||
fi[1].f = x1 + (adj43asm - MAGIC_INT)[fi[1].i];
|
||||
fi[2].f = x2 + (adj43asm - MAGIC_INT)[fi[2].i];
|
||||
fi[3].f = x3 + (adj43asm - MAGIC_INT)[fi[3].i];
|
||||
|
||||
fi[0].i -= MAGIC_INT;
|
||||
fi[1].i -= MAGIC_INT;
|
||||
fi[2].i -= MAGIC_INT;
|
||||
fi[3].i -= MAGIC_INT;
|
||||
fi += 4;
|
||||
xp += 4;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
static void QuantizeBand(const double *xp, int *pi, double istep,
|
||||
int offset, int end, double *adj43)
|
||||
{
|
||||
int j;
|
||||
fi_union *fi;
|
||||
|
||||
fi = (fi_union *)pi;
|
||||
for (j = offset; j < end; j++)
|
||||
{
|
||||
double x0 = istep * xp[j];
|
||||
|
||||
x0 += MAGIC_FLOAT; fi[j].f = (float)x0;
|
||||
fi[j].f = x0 + (adj43 - MAGIC_INT)[fi[j].i];
|
||||
fi[j].i -= MAGIC_INT;
|
||||
}
|
||||
}
|
||||
#else
|
||||
#if 0
|
||||
static void Quantize(const double *xr, int *ix, double istep)
|
||||
{
|
||||
int j;
|
||||
|
||||
for (j = FRAME_LEN/8; j > 0; --j) {
|
||||
double x1, x2, x3, x4, x5, x6, x7, x8;
|
||||
int rx1, rx2, rx3, rx4, rx5, rx6, rx7, rx8;
|
||||
|
||||
x1 = *xr++ * istep;
|
||||
x2 = *xr++ * istep;
|
||||
XRPOW_FTOI(x1, rx1);
|
||||
x3 = *xr++ * istep;
|
||||
XRPOW_FTOI(x2, rx2);
|
||||
x4 = *xr++ * istep;
|
||||
XRPOW_FTOI(x3, rx3);
|
||||
x5 = *xr++ * istep;
|
||||
XRPOW_FTOI(x4, rx4);
|
||||
x6 = *xr++ * istep;
|
||||
XRPOW_FTOI(x5, rx5);
|
||||
x7 = *xr++ * istep;
|
||||
XRPOW_FTOI(x6, rx6);
|
||||
x8 = *xr++ * istep;
|
||||
XRPOW_FTOI(x7, rx7);
|
||||
x1 += QUANTFAC(rx1);
|
||||
XRPOW_FTOI(x8, rx8);
|
||||
x2 += QUANTFAC(rx2);
|
||||
XRPOW_FTOI(x1,*ix++);
|
||||
x3 += QUANTFAC(rx3);
|
||||
XRPOW_FTOI(x2,*ix++);
|
||||
x4 += QUANTFAC(rx4);
|
||||
XRPOW_FTOI(x3,*ix++);
|
||||
x5 += QUANTFAC(rx5);
|
||||
XRPOW_FTOI(x4,*ix++);
|
||||
x6 += QUANTFAC(rx6);
|
||||
XRPOW_FTOI(x5,*ix++);
|
||||
x7 += QUANTFAC(rx7);
|
||||
XRPOW_FTOI(x6,*ix++);
|
||||
x8 += QUANTFAC(rx8);
|
||||
XRPOW_FTOI(x7,*ix++);
|
||||
XRPOW_FTOI(x8,*ix++);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
static void QuantizeBand(const double *xp, int *ix, double istep,
|
||||
int offset, int end, double *adj43)
|
||||
{
|
||||
int j;
|
||||
|
||||
for (j = offset; j < end; j++)
|
||||
{
|
||||
double x0 = istep * xp[j];
|
||||
x0 += adj43[(int)x0];
|
||||
ix[j] = (int)x0;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
static void CalcAllowedDist(CoderInfo *coderInfo, PsyInfo *psyInfo,
|
||||
double *xr, double *xmin, int quality)
|
||||
{
|
||||
int sfb, start, end, l;
|
||||
const double globalthr = 132.0 / (double)quality;
|
||||
int last = coderInfo->lastx;
|
||||
int lastsb = 0;
|
||||
int *cb_offset = coderInfo->sfb_offset;
|
||||
int num_cb = coderInfo->nr_of_sfb;
|
||||
double avgenrg = coderInfo->avgenrg;
|
||||
|
||||
for (sfb = 0; sfb < num_cb; sfb++)
|
||||
{
|
||||
if (last > cb_offset[sfb])
|
||||
lastsb = sfb;
|
||||
}
|
||||
|
||||
for (sfb = 0; sfb < num_cb; sfb++)
|
||||
{
|
||||
double thr, tmp;
|
||||
double enrg = 0.0;
|
||||
|
||||
start = cb_offset[sfb];
|
||||
end = cb_offset[sfb + 1];
|
||||
|
||||
if (sfb > lastsb)
|
||||
{
|
||||
xmin[sfb] = 0;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (coderInfo->block_type != ONLY_SHORT_WINDOW)
|
||||
{
|
||||
double enmax = -1.0;
|
||||
double lmax;
|
||||
|
||||
lmax = start;
|
||||
for (l = start; l < end; l++)
|
||||
{
|
||||
if (enmax < (xr[l] * xr[l]))
|
||||
{
|
||||
enmax = xr[l] * xr[l];
|
||||
lmax = l;
|
||||
}
|
||||
}
|
||||
|
||||
start = lmax - 2;
|
||||
end = lmax + 3;
|
||||
if (start < 0)
|
||||
start = 0;
|
||||
if (end > last)
|
||||
end = last;
|
||||
}
|
||||
|
||||
for (l = start; l < end; l++)
|
||||
{
|
||||
enrg += xr[l]*xr[l];
|
||||
}
|
||||
|
||||
thr = enrg/((double)(end-start)*avgenrg);
|
||||
thr = pow(thr, 0.1*(lastsb-sfb)/lastsb + 0.3);
|
||||
|
||||
tmp = 1.0 - ((double)start / (double)last);
|
||||
tmp = tmp * tmp * tmp + 0.075;
|
||||
|
||||
thr = 1.0 / (1.4*thr + tmp);
|
||||
|
||||
xmin[sfb] = ((coderInfo->block_type == ONLY_SHORT_WINDOW) ? 0.65 : 1.12)
|
||||
* globalthr * thr;
|
||||
}
|
||||
}
|
||||
|
||||
static int FixNoise(CoderInfo *coderInfo,
|
||||
const double *xr,
|
||||
double *xr_pow,
|
||||
int *xi,
|
||||
double *xmin,
|
||||
double *pow43,
|
||||
double *adj43)
|
||||
{
|
||||
int i, sb;
|
||||
int start, end;
|
||||
double diffvol;
|
||||
double tmp;
|
||||
const double ifqstep = pow(2.0, 0.1875);
|
||||
const double log_ifqstep = 1.0 / log(ifqstep);
|
||||
const double maxstep = 0.05;
|
||||
|
||||
for (sb = 0; sb < coderInfo->nr_of_sfb; sb++)
|
||||
{
|
||||
double sfacfix;
|
||||
double fixstep = 0.25;
|
||||
int sfac;
|
||||
double fac;
|
||||
int dist;
|
||||
double sfacfix0 = 1.0, dist0 = 1e50;
|
||||
double maxx;
|
||||
|
||||
start = coderInfo->sfb_offset[sb];
|
||||
end = coderInfo->sfb_offset[sb+1];
|
||||
|
||||
if (!xmin[sb])
|
||||
goto nullsfb;
|
||||
|
||||
maxx = 0.0;
|
||||
for (i = start; i < end; i++)
|
||||
{
|
||||
if (xr_pow[i] > maxx)
|
||||
maxx = xr_pow[i];
|
||||
}
|
||||
|
||||
//printf("band %d: maxx: %f\n", sb, maxx);
|
||||
if (maxx < 10.0)
|
||||
{
|
||||
nullsfb:
|
||||
for (i = start; i < end; i++)
|
||||
xi[i] = 0;
|
||||
coderInfo->scale_factor[sb] = 10;
|
||||
continue;
|
||||
}
|
||||
|
||||
sfacfix = 1.0 / maxx;
|
||||
sfac = (int)(log(sfacfix) * log_ifqstep - 0.5);
|
||||
for (i = start; i < end; i++)
|
||||
xr_pow[i] *= sfacfix;
|
||||
maxx *= sfacfix;
|
||||
coderInfo->scale_factor[sb] = sfac;
|
||||
QuantizeBand(xr_pow, xi, IPOW20(coderInfo->global_gain), start, end,
|
||||
adj43);
|
||||
//printf("\tsfac: %d\n", sfac);
|
||||
|
||||
calcdist:
|
||||
diffvol = 0.0;
|
||||
for (i = start; i < end; i++)
|
||||
{
|
||||
tmp = xi[i];
|
||||
diffvol += tmp * tmp; // ~x^(3/2)
|
||||
}
|
||||
|
||||
if (diffvol < 1e-6)
|
||||
diffvol = 1e-6;
|
||||
tmp = pow(diffvol / (double)(end - start), -0.666);
|
||||
|
||||
if (fabs(fixstep) > maxstep)
|
||||
{
|
||||
double dd = 0.5*(tmp / xmin[sb] - 1.0);
|
||||
|
||||
if (fabs(dd) < fabs(fixstep))
|
||||
{
|
||||
fixstep = dd;
|
||||
|
||||
if (fabs(fixstep) < maxstep)
|
||||
fixstep = maxstep * ((fixstep > 0) ? 1 : -1);
|
||||
}
|
||||
}
|
||||
|
||||
if (fixstep > 0)
|
||||
{
|
||||
if (tmp < dist0)
|
||||
{
|
||||
dist0 = tmp;
|
||||
sfacfix0 = sfacfix;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (fixstep > .1)
|
||||
fixstep = .1;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
dist0 = tmp;
|
||||
sfacfix0 = sfacfix;
|
||||
}
|
||||
|
||||
dist = (tmp > xmin[sb]);
|
||||
fac = 0.0;
|
||||
if (fabs(fixstep) >= maxstep)
|
||||
{
|
||||
if ((dist && (fixstep < 0))
|
||||
|| (!dist && (fixstep > 0)))
|
||||
{
|
||||
fixstep = -0.5 * fixstep;
|
||||
}
|
||||
|
||||
fac = 1.0 + fixstep;
|
||||
}
|
||||
else if (dist)
|
||||
{
|
||||
fac = 1.0 + fabs(fixstep);
|
||||
}
|
||||
|
||||
if (fac != 0.0)
|
||||
{
|
||||
if (maxx * fac >= IXMAX_VAL)
|
||||
{
|
||||
// restore best noise
|
||||
fac = sfacfix0 / sfacfix;
|
||||
for (i = start; i < end; i++)
|
||||
xr_pow[i] *= fac;
|
||||
maxx *= fac;
|
||||
sfacfix *= fac;
|
||||
coderInfo->scale_factor[sb] = log(sfacfix) * log_ifqstep - 0.5;
|
||||
QuantizeBand(xr_pow, xi, IPOW20(coderInfo->global_gain), start, end,
|
||||
adj43);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (coderInfo->scale_factor[sb] < -10)
|
||||
{
|
||||
for (i = start; i < end; i++)
|
||||
xr_pow[i] *= fac;
|
||||
maxx *= fac;
|
||||
sfacfix *= fac;
|
||||
coderInfo->scale_factor[sb] = log(sfacfix) * log_ifqstep - 0.5;
|
||||
QuantizeBand(xr_pow, xi, IPOW20(coderInfo->global_gain), start, end,
|
||||
adj43);
|
||||
goto calcdist;
|
||||
}
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int SortForGrouping(CoderInfo* coderInfo,
|
||||
PsyInfo *psyInfo,
|
||||
ChannelInfo *channelInfo,
|
||||
int *sfb_width_table,
|
||||
double *xr)
|
||||
{
|
||||
int i,j,ii;
|
||||
int index = 0;
|
||||
double xr_tmp[FRAME_LEN];
|
||||
int group_offset=0;
|
||||
int k=0;
|
||||
int windowOffset = 0;
|
||||
|
||||
|
||||
/* set up local variables for used quantInfo elements */
|
||||
int* sfb_offset = coderInfo->sfb_offset;
|
||||
int* nr_of_sfb = &(coderInfo->nr_of_sfb);
|
||||
int* window_group_length;
|
||||
int num_window_groups;
|
||||
*nr_of_sfb = coderInfo->max_sfb; /* Init to max_sfb */
|
||||
window_group_length = coderInfo->window_group_length;
|
||||
num_window_groups = coderInfo->num_window_groups;
|
||||
|
||||
/* calc org sfb_offset just for shortblock */
|
||||
sfb_offset[k]=0;
|
||||
for (k=1 ; k <*nr_of_sfb+1; k++) {
|
||||
sfb_offset[k] = sfb_offset[k-1] + sfb_width_table[k-1];
|
||||
}
|
||||
|
||||
/* sort the input spectral coefficients */
|
||||
index = 0;
|
||||
group_offset=0;
|
||||
for (i=0; i< num_window_groups; i++) {
|
||||
for (k=0; k<*nr_of_sfb; k++) {
|
||||
for (j=0; j < window_group_length[i]; j++) {
|
||||
for (ii=0;ii< sfb_width_table[k];ii++)
|
||||
xr_tmp[index++] = xr[ii+ sfb_offset[k] + BLOCK_LEN_SHORT*j +group_offset];
|
||||
}
|
||||
}
|
||||
group_offset += BLOCK_LEN_SHORT*window_group_length[i];
|
||||
}
|
||||
|
||||
for (k=0; k<FRAME_LEN; k++){
|
||||
xr[k] = xr_tmp[k];
|
||||
}
|
||||
|
||||
|
||||
/* now calc the new sfb_offset table for the whole p_spectrum vector*/
|
||||
index = 0;
|
||||
sfb_offset[index++] = 0;
|
||||
windowOffset = 0;
|
||||
for (i=0; i < num_window_groups; i++) {
|
||||
for (k=0 ; k <*nr_of_sfb; k++) {
|
||||
sfb_offset[index] = sfb_offset[index-1] + sfb_width_table[k]*window_group_length[i] ;
|
||||
index++;
|
||||
}
|
||||
windowOffset += window_group_length[i];
|
||||
}
|
||||
|
||||
*nr_of_sfb = *nr_of_sfb * num_window_groups; /* Number interleaved bands. */
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void CalcAvgEnrg(CoderInfo *coderInfo,
|
||||
const double *xr)
|
||||
{
|
||||
int end, l;
|
||||
int last = 0;
|
||||
double totenrg = 0.0;
|
||||
|
||||
end = coderInfo->sfb_offset[coderInfo->nr_of_sfb];
|
||||
for (l = 0; l < end; l++)
|
||||
{
|
||||
if (xr[l])
|
||||
{
|
||||
last = l;
|
||||
totenrg += xr[l] * xr[l];
|
||||
}
|
||||
}
|
||||
last++;
|
||||
|
||||
coderInfo->lastx = last;
|
||||
coderInfo->avgenrg = totenrg / last;
|
||||
}
|
74
external/libfaac/libfaac/aacquant.h
vendored
Normal file
74
external/libfaac/libfaac/aacquant.h
vendored
Normal file
|
@ -0,0 +1,74 @@
|
|||
/*
|
||||
* FAAC - Freeware Advanced Audio Coder
|
||||
* Copyright (C) 2001 Menno Bakker
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
* $Id: aacquant.h,v 1.9 2003/10/12 16:43:39 knik Exp $
|
||||
*/
|
||||
|
||||
#ifndef AACQUANT_H
|
||||
#define AACQUANT_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif /* __cplusplus */
|
||||
|
||||
#include "coder.h"
|
||||
#include "psych.h"
|
||||
|
||||
#define IXMAX_VAL 8191
|
||||
#define PRECALC_SIZE (IXMAX_VAL+2)
|
||||
#define LARGE_BITS 100000
|
||||
#define SF_OFFSET 100
|
||||
|
||||
#define POW20(x) pow(2.0,((double)x)*.25)
|
||||
#define IPOW20(x) pow(2.0,-((double)x)*.1875)
|
||||
|
||||
#pragma pack(push, 1)
|
||||
typedef struct
|
||||
{
|
||||
double *pow43;
|
||||
double *adj43;
|
||||
double quality;
|
||||
} AACQuantCfg;
|
||||
#pragma pack(pop)
|
||||
|
||||
void AACQuantizeInit(CoderInfo *coderInfo, unsigned int numChannels,
|
||||
AACQuantCfg *aacquantCfg);
|
||||
void AACQuantizeEnd(CoderInfo *coderInfo, unsigned int numChannels,
|
||||
AACQuantCfg *aacquantCfg);
|
||||
|
||||
int AACQuantize(CoderInfo *coderInfo,
|
||||
PsyInfo *psyInfo,
|
||||
ChannelInfo *channelInfo,
|
||||
int *cb_width,
|
||||
int num_cb,
|
||||
double *xr,
|
||||
AACQuantCfg *aacquantcfg);
|
||||
|
||||
int SortForGrouping(CoderInfo* coderInfo,
|
||||
PsyInfo *psyInfo,
|
||||
ChannelInfo *channelInfo,
|
||||
int *sfb_width_table,
|
||||
double *xr);
|
||||
void CalcAvgEnrg(CoderInfo *coderInfo,
|
||||
const double *xr);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif /* __cplusplus */
|
||||
|
||||
#endif /* AACQUANT_H */
|
381
external/libfaac/libfaac/backpred.c
vendored
Normal file
381
external/libfaac/libfaac/backpred.c
vendored
Normal file
|
@ -0,0 +1,381 @@
|
|||
/**********************************************************************
|
||||
|
||||
This software module was originally developed by
|
||||
and edited by Nokia in the course of
|
||||
development of the MPEG-2 NBC/MPEG-4 Audio standard
|
||||
ISO/IEC 13818-7, 14496-1,2 and 3. This software module is an
|
||||
implementation of a part of one or more MPEG-2 NBC/MPEG-4 Audio tools
|
||||
as specified by the MPEG-2 NBC/MPEG-4 Audio standard. ISO/IEC gives
|
||||
users of the MPEG-2 NBC/MPEG-4 Audio standards free license to this
|
||||
software module or modifications thereof for use in hardware or
|
||||
software products claiming conformance to the MPEG-2 NBC/ MPEG-4 Audio
|
||||
standards. Those intending to use this software module in hardware or
|
||||
software products are advised that this use may infringe existing
|
||||
patents. The original developer of this software module and his/her
|
||||
company, the subsequent editors and their companies, and ISO/IEC have
|
||||
no liability for use of this software module or modifications thereof
|
||||
in an implementation. Copyright is not released for non MPEG-2
|
||||
NBC/MPEG-4 Audio conforming products. The original developer retains
|
||||
full right to use the code for his/her own purpose, assign or donate
|
||||
the code to a third party and to inhibit third party from using the
|
||||
code for non MPEG-2 NBC/MPEG-4 Audio conforming products. This
|
||||
copyright notice must be included in all copies or derivative works.
|
||||
|
||||
Copyright (c) 1997.
|
||||
**********************************************************************/
|
||||
/*
|
||||
* $Id: backpred.c,v 1.5 2001/09/04 18:39:35 menno Exp $
|
||||
*/
|
||||
|
||||
#include <math.h>
|
||||
#include "frame.h"
|
||||
#include "coder.h"
|
||||
#include "channels.h"
|
||||
#include "backpred.h"
|
||||
|
||||
|
||||
void PredInit(faacEncHandle hEncoder)
|
||||
{
|
||||
unsigned int channel;
|
||||
|
||||
for (channel = 0; channel < hEncoder->numChannels; channel++) {
|
||||
BwpInfo *bwpInfo = &(hEncoder->coderInfo[channel].bwpInfo);
|
||||
|
||||
bwpInfo->psy_init_mc = 0;
|
||||
bwpInfo->reset_count_mc = 0;
|
||||
}
|
||||
}
|
||||
|
||||
void PredCalcPrediction(double *act_spec, double *last_spec, int btype,
|
||||
int nsfb,
|
||||
int *isfb_width,
|
||||
CoderInfo *coderInfo,
|
||||
ChannelInfo *channelInfo,
|
||||
int chanNum)
|
||||
{
|
||||
int i, k, j, cb_long;
|
||||
int leftChanNum;
|
||||
int isRightWithCommonWindow;
|
||||
double num_bit, snr[SBMAX_L];
|
||||
double energy[BLOCK_LEN_LONG], snr_p[BLOCK_LEN_LONG], temp1, temp2;
|
||||
ChannelInfo *thisChannel;
|
||||
|
||||
/* Set pointers for specified channel number */
|
||||
/* int psy_init; */
|
||||
int *psy_init;
|
||||
double (*dr)[BLOCK_LEN_LONG],(*e)[BLOCK_LEN_LONG];
|
||||
double (*K)[BLOCK_LEN_LONG], (*R)[BLOCK_LEN_LONG];
|
||||
double (*VAR)[BLOCK_LEN_LONG], (*KOR)[BLOCK_LEN_LONG];
|
||||
double *sb_samples_pred;
|
||||
int *thisLineNeedsResetting;
|
||||
/* int reset_count; */
|
||||
int *reset_count;
|
||||
int *pred_global_flag;
|
||||
int *pred_sfb_flag;
|
||||
int *reset_group;
|
||||
|
||||
/* Set pointers for this chanNum */
|
||||
pred_global_flag = &(coderInfo[chanNum].pred_global_flag);
|
||||
pred_sfb_flag = coderInfo[chanNum].pred_sfb_flag;
|
||||
reset_group = &(coderInfo[chanNum].reset_group_number);
|
||||
psy_init = &coderInfo[chanNum].bwpInfo.psy_init_mc;
|
||||
dr = &coderInfo[chanNum].bwpInfo.dr_mc[0];
|
||||
e = &coderInfo[chanNum].bwpInfo.e_mc[0];
|
||||
K = &coderInfo[chanNum].bwpInfo.K_mc[0];
|
||||
R = &coderInfo[chanNum].bwpInfo.R_mc[0];
|
||||
VAR = &coderInfo[chanNum].bwpInfo.VAR_mc[0];
|
||||
KOR = &coderInfo[chanNum].bwpInfo.KOR_mc[0];
|
||||
sb_samples_pred = &coderInfo[chanNum].bwpInfo.sb_samples_pred_mc[0];
|
||||
thisLineNeedsResetting = &coderInfo[chanNum].bwpInfo.thisLineNeedsResetting_mc[0];
|
||||
reset_count = &coderInfo[chanNum].bwpInfo.reset_count_mc;
|
||||
|
||||
thisChannel = &(channelInfo[chanNum]);
|
||||
*psy_init = (*psy_init && (btype!=2));
|
||||
|
||||
if((*psy_init) == 0) {
|
||||
for (j=0; j<BLOCK_LEN_LONG; j++) {
|
||||
thisLineNeedsResetting[j]=1;
|
||||
}
|
||||
*psy_init = 1;
|
||||
}
|
||||
|
||||
if (btype==2) {
|
||||
pred_global_flag[0]=0;
|
||||
/* SHORT WINDOWS reset all the co-efficients */
|
||||
if (thisChannel->ch_is_left) {
|
||||
(*reset_count)++;
|
||||
if (*reset_count >= 31 * RESET_FRAME)
|
||||
*reset_count = RESET_FRAME;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
/**************************************************/
|
||||
/* Compute state using last_spec */
|
||||
/**************************************************/
|
||||
for (i=0;i<BLOCK_LEN_LONG;i++)
|
||||
{
|
||||
/* e[0][i]=last_spec[i]; */
|
||||
e[0][i]=last_spec[i]+sb_samples_pred[i];
|
||||
|
||||
for(j=1;j<=LPC;j++)
|
||||
e[j][i] = e[j-1][i]-K[j][i]*R[j-1][i];
|
||||
|
||||
for(j=1;j<LPC;j++)
|
||||
dr[j][i] = K[j][i]*e[j-1][i];
|
||||
|
||||
for(j=1;j<=LPC;j++) {
|
||||
VAR[j][i] = ALPHA*VAR[j][i]+.5*(R[j-1][i]*R[j-1][i]+e[j-1][i]*e[j-1][i]);
|
||||
KOR[j][i] = ALPHA*KOR[j][i]+R[j-1][i]*e[j-1][i];
|
||||
}
|
||||
|
||||
for(j=LPC-1;j>=1;j--)
|
||||
R[j][i] = A*(R[j-1][i]-dr[j][i]);
|
||||
R[0][i] = A*e[0][i];
|
||||
}
|
||||
|
||||
|
||||
/**************************************************/
|
||||
/* Reset state here if resets were sent */
|
||||
/**************************************************/
|
||||
for (i=0;i<BLOCK_LEN_LONG;i++) {
|
||||
if (thisLineNeedsResetting[i]) {
|
||||
for (j = 0; j <= LPC; j++)
|
||||
{
|
||||
K[j][i] = 0.0;
|
||||
e[j][i] = 0.0;
|
||||
R[j][i] = 0.0;
|
||||
VAR[j][i] = 1.0;
|
||||
KOR[j][i] = 0.0;
|
||||
dr[j][i] = 0.0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**************************************************/
|
||||
/* Compute predictor coefficients, predicted data */
|
||||
/**************************************************/
|
||||
for (i=0;i<BLOCK_LEN_LONG;i++)
|
||||
{
|
||||
for(j=1;j<=LPC;j++) {
|
||||
if(VAR[j][i]>MINVAR)
|
||||
K[j][i] = KOR[j][i]/VAR[j][i]*B;
|
||||
else
|
||||
K[j][i] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
for (k=0; k<BLOCK_LEN_LONG; k++)
|
||||
{
|
||||
sb_samples_pred[k]=0.0;
|
||||
for (i=1; i<=LPC; i++)
|
||||
sb_samples_pred[k]+=K[i][k]*R[i-1][k];
|
||||
}
|
||||
|
||||
|
||||
/***********************************************************/
|
||||
/* If this is the right channel of a channel_pair_element, */
|
||||
/* AND common_window is 1 in this channel_pair_element, */
|
||||
/* THEN copy predictor data to use from the left channel. */
|
||||
/* ELSE determine independent predictor data and resets. */
|
||||
/***********************************************************/
|
||||
/* BE CAREFUL HERE, this assumes that predictor data has */
|
||||
/* already been determined for the left channel!! */
|
||||
/***********************************************************/
|
||||
isRightWithCommonWindow = 0; /* Is this a right channel with common_window?*/
|
||||
if ((thisChannel->cpe)&&( !(thisChannel->ch_is_left))) {
|
||||
leftChanNum = thisChannel->paired_ch;
|
||||
if (channelInfo[leftChanNum].common_window) {
|
||||
isRightWithCommonWindow = 1;
|
||||
}
|
||||
}
|
||||
|
||||
if (isRightWithCommonWindow) {
|
||||
|
||||
/**************************************************/
|
||||
/* Use predictor data from the left channel. */
|
||||
/**************************************************/
|
||||
CopyPredInfo(&(coderInfo[chanNum]),&(coderInfo[leftChanNum]));
|
||||
|
||||
/* Make sure to turn off bands with intensity stereo */
|
||||
#if 0
|
||||
if (thisChannel->is_info.is_present) {
|
||||
for (i=0; i<nsfb; i++) {
|
||||
if (thisChannel->is_info.is_used[i]) {
|
||||
pred_sfb_flag[i] = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
cb_long=0;
|
||||
for (i=0; i<nsfb; i++)
|
||||
{
|
||||
if (!pred_sfb_flag[i]) {
|
||||
for (j=cb_long; j<cb_long+isfb_width[i]; j++)
|
||||
sb_samples_pred[j]=0.0;
|
||||
}
|
||||
cb_long+=isfb_width[i];
|
||||
}
|
||||
|
||||
/* Disable prediction for bands nsfb through SBMAX_L */
|
||||
for (i=j;i<BLOCK_LEN_LONG;i++) {
|
||||
sb_samples_pred[i]=0.0;
|
||||
}
|
||||
for (i=nsfb;i<SBMAX_L;i++) {
|
||||
pred_sfb_flag[i]=0;
|
||||
}
|
||||
|
||||
/* Is global enable set, if not enabled predicted samples are zeroed */
|
||||
if(!pred_global_flag[0]) {
|
||||
for (j=0; j<BLOCK_LEN_LONG; j++)
|
||||
sb_samples_pred[j]=0.0;
|
||||
}
|
||||
for (j=0; j<BLOCK_LEN_LONG; j++)
|
||||
act_spec[j]-=sb_samples_pred[j];
|
||||
|
||||
} else {
|
||||
|
||||
/**************************************************/
|
||||
/* Determine whether to enable/disable prediction */
|
||||
/**************************************************/
|
||||
|
||||
for (k=0; k<BLOCK_LEN_LONG; k++) {
|
||||
energy[k]=act_spec[k]*act_spec[k];
|
||||
snr_p[k]=(act_spec[k]-sb_samples_pred[k])*(act_spec[k]-sb_samples_pred[k]);
|
||||
}
|
||||
|
||||
cb_long=0;
|
||||
for (i=0; i<nsfb; i++) {
|
||||
pred_sfb_flag[i]=1;
|
||||
temp1=0.0;
|
||||
temp2=0.0;
|
||||
for (j=cb_long; j<cb_long+isfb_width[i]; j++) {
|
||||
temp1+=energy[j];
|
||||
temp2+=snr_p[j];
|
||||
}
|
||||
if(temp2<1.e-20)
|
||||
temp2=1.e-20;
|
||||
if(temp1!=0.0)
|
||||
snr[i]=-10.*log10((double ) temp2/temp1);
|
||||
else
|
||||
snr[i]=0.0;
|
||||
|
||||
if(snr[i]<=0.0) {
|
||||
pred_sfb_flag[i]=0;
|
||||
for (j=cb_long; j<cb_long+isfb_width[i]; j++)
|
||||
sb_samples_pred[j]=0.0;
|
||||
}
|
||||
cb_long+=isfb_width[i];
|
||||
}
|
||||
|
||||
/* Disable prediction for bands nsfb through SBMAX_L */
|
||||
for (i=j;i<BLOCK_LEN_LONG;i++) {
|
||||
sb_samples_pred[i]=0.0;
|
||||
}
|
||||
for (i=nsfb;i<SBMAX_L;i++) {
|
||||
pred_sfb_flag[i]=0;
|
||||
}
|
||||
|
||||
num_bit=0.0;
|
||||
for (i=0; i<nsfb; i++)
|
||||
if(snr[i]>0.0)
|
||||
num_bit+=snr[i]/6.*isfb_width[i];
|
||||
|
||||
/* Determine global enable, if not enabled predicted samples are zeroed */
|
||||
pred_global_flag[0]=1;
|
||||
if(num_bit<50) {
|
||||
pred_global_flag[0]=0; num_bit=0.0;
|
||||
for (j=0; j<BLOCK_LEN_LONG; j++)
|
||||
sb_samples_pred[j]=0.0;
|
||||
}
|
||||
for (j=0; j<BLOCK_LEN_LONG; j++)
|
||||
act_spec[j]-=sb_samples_pred[j];
|
||||
|
||||
}
|
||||
|
||||
/**********************************************************/
|
||||
/* If this is a left channel, determine pred resets. */
|
||||
/* If this is a right channel, using pred reset data from */
|
||||
/* left channel. Keep left and right resets in sync. */
|
||||
/**********************************************************/
|
||||
if ((thisChannel->cpe)&&( !(thisChannel->ch_is_left))) {
|
||||
/* if (!thisChannel->ch_is_left) {*/
|
||||
/**********************************************************/
|
||||
/* Using predictor reset data from the left channel. */
|
||||
/**********************************************************/
|
||||
reset_count = &coderInfo[leftChanNum].bwpInfo.reset_count_mc;
|
||||
/* Reset the frame counter */
|
||||
for (i=0;i<BLOCK_LEN_LONG;i++) {
|
||||
thisLineNeedsResetting[i]=0;
|
||||
}
|
||||
reset_group = &(coderInfo[chanNum].reset_group_number);
|
||||
if (*reset_count % RESET_FRAME == 0)
|
||||
{ /* Send a reset in this frame */
|
||||
*reset_group = *reset_count / 8;
|
||||
for (i = *reset_group - 1; i < BLOCK_LEN_LONG; i += 30)
|
||||
{
|
||||
thisLineNeedsResetting[i]=1;
|
||||
}
|
||||
}
|
||||
else
|
||||
*reset_group = -1;
|
||||
} else {
|
||||
/******************************************************************/
|
||||
/* Determine whether a prediction reset is required - if so, then */
|
||||
/* set reset flag for the appropriate group. */
|
||||
/******************************************************************/
|
||||
|
||||
/* Increase counter on left channel, keep left and right resets in sync */
|
||||
(*reset_count)++;
|
||||
|
||||
/* Reset the frame counter */
|
||||
for (i=0;i<BLOCK_LEN_LONG;i++) {
|
||||
thisLineNeedsResetting[i]=0;
|
||||
}
|
||||
if (*reset_count >= 31 * RESET_FRAME)
|
||||
*reset_count = RESET_FRAME;
|
||||
if (*reset_count % RESET_FRAME == 0)
|
||||
{ /* Send a reset in this frame */
|
||||
*reset_group = *reset_count / 8;
|
||||
for (i = *reset_group - 1; i < BLOCK_LEN_LONG; i += 30)
|
||||
{
|
||||
thisLineNeedsResetting[i]=1;
|
||||
}
|
||||
}
|
||||
else
|
||||
*reset_group = -1;
|
||||
}
|
||||
|
||||
|
||||
/* Ensure that prediction data is sent when there is a prediction
|
||||
* reset.
|
||||
*/
|
||||
if (*reset_group != -1 && pred_global_flag[0] == 0)
|
||||
{
|
||||
pred_global_flag[0] = 1;
|
||||
for (i = 0; i < nsfb; i++)
|
||||
pred_sfb_flag[i] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void CopyPredInfo(CoderInfo *right, CoderInfo *left)
|
||||
{
|
||||
int band;
|
||||
|
||||
right->pred_global_flag = left->pred_global_flag;
|
||||
right->reset_group_number = left->reset_group_number;
|
||||
|
||||
for (band = 0; band<MAX_SCFAC_BANDS; band++) {
|
||||
right->pred_sfb_flag[band] = left->pred_sfb_flag[band];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
51
external/libfaac/libfaac/backpred.h
vendored
Normal file
51
external/libfaac/libfaac/backpred.h
vendored
Normal file
|
@ -0,0 +1,51 @@
|
|||
/*
|
||||
* FAAC - Freeware Advanced Audio Coder
|
||||
* Copyright (C) 2001 Menno Bakker
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
* $Id: backpred.h,v 1.5 2001/06/08 18:01:09 menno Exp $
|
||||
*/
|
||||
|
||||
#ifndef _AAC_BACK_H_INCLUDED
|
||||
#define _AAC_BACK_H_INCLUDED
|
||||
|
||||
#define PRED_ALPHA 0.90625
|
||||
#define PRED_A 0.953125
|
||||
#define PRED_B 0.953125
|
||||
|
||||
#define ALPHA PRED_ALPHA
|
||||
#define A PRED_A
|
||||
#define B PRED_B
|
||||
#define MINVAR 1.e-10
|
||||
|
||||
/* Reset every RESET_FRAME frames. */
|
||||
#define RESET_FRAME 8
|
||||
|
||||
void PredCalcPrediction(double *act_spec,
|
||||
double *last_spec,
|
||||
int btype,
|
||||
int nsfb,
|
||||
int *isfb_width,
|
||||
CoderInfo *coderInfo,
|
||||
ChannelInfo *channelInfo,
|
||||
int chanNum);
|
||||
|
||||
void PredInit(faacEncHandle hEncoder);
|
||||
|
||||
void CopyPredInfo(CoderInfo *right, CoderInfo *left);
|
||||
|
||||
|
||||
#endif
|
1496
external/libfaac/libfaac/bitstream.c
vendored
Normal file
1496
external/libfaac/libfaac/bitstream.c
vendored
Normal file
File diff suppressed because it is too large
Load Diff
172
external/libfaac/libfaac/bitstream.h
vendored
Normal file
172
external/libfaac/libfaac/bitstream.h
vendored
Normal file
|
@ -0,0 +1,172 @@
|
|||
/**********************************************************************
|
||||
MPEG-4 Audio VM
|
||||
Bit stream module
|
||||
|
||||
|
||||
|
||||
This software module was originally developed by
|
||||
|
||||
Heiko Purnhagen (University of Hannover)
|
||||
|
||||
and edited by
|
||||
|
||||
in the course of development of the MPEG-2 NBC/MPEG-4 Audio standard
|
||||
ISO/IEC 13818-7, 14496-1,2 and 3. This software module is an
|
||||
implementation of a part of one or more MPEG-2 NBC/MPEG-4 Audio tools
|
||||
as specified by the MPEG-2 NBC/MPEG-4 Audio standard. ISO/IEC gives
|
||||
users of the MPEG-2 NBC/MPEG-4 Audio standards free license to this
|
||||
software module or modifications thereof for use in hardware or
|
||||
software products claiming conformance to the MPEG-2 NBC/ MPEG-4 Audio
|
||||
standards. Those intending to use this software module in hardware or
|
||||
software products are advised that this use may infringe existing
|
||||
patents. The original developer of this software module and his/her
|
||||
company, the subsequent editors and their companies, and ISO/IEC have
|
||||
no liability for use of this software module or modifications thereof
|
||||
in an implementation. Copyright is not released for non MPEG-2
|
||||
NBC/MPEG-4 Audio conforming products. The original developer retains
|
||||
full right to use the code for his/her own purpose, assign or donate
|
||||
the code to a third party and to inhibit third party from using the
|
||||
code for non MPEG-2 NBC/MPEG-4 Audio conforming products. This
|
||||
copyright notice must be included in all copies or derivative works.
|
||||
|
||||
Copyright (c) 1996.
|
||||
**********************************************************************/
|
||||
/*
|
||||
* $Id: bitstream.h,v 1.14 2004/07/04 12:10:52 corrados Exp $
|
||||
*/
|
||||
|
||||
#ifndef BITSTREAM_H
|
||||
#define BITSTREAM_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif /* __cplusplus */
|
||||
|
||||
#include "frame.h"
|
||||
#include "coder.h"
|
||||
#include "channels.h"
|
||||
|
||||
/*
|
||||
* Raw bitstream constants
|
||||
*/
|
||||
#define LEN_SE_ID 3
|
||||
#define LEN_TAG 4
|
||||
#define LEN_GLOB_GAIN 8
|
||||
#define LEN_COM_WIN 1
|
||||
#define LEN_ICS_RESERV 1
|
||||
#define LEN_WIN_SEQ 2
|
||||
#define LEN_WIN_SH 1
|
||||
#define LEN_MAX_SFBL 6
|
||||
#define LEN_MAX_SFBS 4
|
||||
#define LEN_CB 4
|
||||
#define LEN_SCL_PCM 8
|
||||
#define LEN_PRED_PRES 1
|
||||
#define LEN_PRED_RST 1
|
||||
#define LEN_PRED_RSTGRP 5
|
||||
#define LEN_PRED_ENAB 1
|
||||
#define LEN_MASK_PRES 2
|
||||
#define LEN_MASK 1
|
||||
#define LEN_PULSE_PRES 1
|
||||
|
||||
#define LEN_TNS_PRES 1
|
||||
#define LEN_TNS_NFILTL 2
|
||||
#define LEN_TNS_NFILTS 1
|
||||
#define LEN_TNS_COEFF_RES 1
|
||||
#define LEN_TNS_LENGTHL 6
|
||||
#define LEN_TNS_LENGTHS 4
|
||||
#define LEN_TNS_ORDERL 5
|
||||
#define LEN_TNS_ORDERS 3
|
||||
#define LEN_TNS_DIRECTION 1
|
||||
#define LEN_TNS_COMPRESS 1
|
||||
#define LEN_GAIN_PRES 1
|
||||
|
||||
#define LEN_NEC_NPULSE 2
|
||||
#define LEN_NEC_ST_SFB 6
|
||||
#define LEN_NEC_POFF 5
|
||||
#define LEN_NEC_PAMP 4
|
||||
#define NUM_NEC_LINES 4
|
||||
#define NEC_OFFSET_AMP 4
|
||||
|
||||
#define LEN_NCC 3
|
||||
#define LEN_IS_CPE 1
|
||||
#define LEN_CC_LR 1
|
||||
#define LEN_CC_DOM 1
|
||||
#define LEN_CC_SGN 1
|
||||
#define LEN_CCH_GES 2
|
||||
#define LEN_CCH_CGP 1
|
||||
#define LEN_D_CNT 4
|
||||
#define LEN_D_ESC 12
|
||||
#define LEN_F_CNT 4
|
||||
#define LEN_F_ESC 8
|
||||
#define LEN_BYTE 8
|
||||
#define LEN_PAD_DATA 8
|
||||
|
||||
#define LEN_PC_COMM 8
|
||||
|
||||
#ifdef DRM
|
||||
# define LEN_HCR_REORDSD 14
|
||||
# define LEN_HCR_LONGCW 6
|
||||
# define FIRST_PAIR_HCB 5
|
||||
# define QUAD_LEN 4
|
||||
# define PAIR_LEN 2
|
||||
# define ESC_HCB 11
|
||||
#endif
|
||||
|
||||
#define ID_SCE 0
|
||||
#define ID_CPE 1
|
||||
#define ID_CCE 2
|
||||
#define ID_LFE 3
|
||||
#define ID_DSE 4
|
||||
#define ID_PCE 5
|
||||
#define ID_FIL 6
|
||||
#define ID_END 7
|
||||
|
||||
|
||||
/* MPEG ID's */
|
||||
#define MPEG2 1
|
||||
#define MPEG4 0
|
||||
|
||||
/* AAC object types */
|
||||
#define MAIN 1
|
||||
#define LOW 2
|
||||
#define SSR 3
|
||||
#define LTP 4
|
||||
|
||||
|
||||
#define BYTE_NUMBIT 8 /* bits in byte (char) */
|
||||
#define LONG_NUMBIT 32 /* bits in unsigned long */
|
||||
#define bit2byte(a) (((a)+BYTE_NUMBIT-1)/BYTE_NUMBIT)
|
||||
|
||||
|
||||
typedef struct
|
||||
{
|
||||
unsigned char *data; /* data bits */
|
||||
long numBit; /* number of bits in buffer */
|
||||
long size; /* buffer size in bytes */
|
||||
long currentBit; /* current bit position in bit stream */
|
||||
long numByte; /* number of bytes read/written (only file) */
|
||||
} BitStream;
|
||||
|
||||
|
||||
|
||||
int WriteBitstream(faacEncHandle hEncoder,
|
||||
CoderInfo *coderInfo,
|
||||
ChannelInfo *channelInfo,
|
||||
BitStream *bitStream,
|
||||
int numChannels);
|
||||
|
||||
|
||||
BitStream *OpenBitStream(int size, unsigned char *buffer);
|
||||
|
||||
int CloseBitStream(BitStream *bitStream);
|
||||
|
||||
int PutBit(BitStream *bitStream,
|
||||
unsigned long data,
|
||||
int numBit);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif /* __cplusplus */
|
||||
|
||||
#endif /* BITSTREAM_H */
|
||||
|
110
external/libfaac/libfaac/channels.c
vendored
Normal file
110
external/libfaac/libfaac/channels.c
vendored
Normal file
|
@ -0,0 +1,110 @@
|
|||
/************************* MPEG-2 NBC Audio Decoder **************************
|
||||
* *
|
||||
"This software module was originally developed in the course of
|
||||
development of the MPEG-2 NBC/MPEG-4 Audio standard ISO/IEC 13818-7,
|
||||
14496-1,2 and 3. This software module is an implementation of a part of one or more
|
||||
MPEG-2 NBC/MPEG-4 Audio tools as specified by the MPEG-2 NBC/MPEG-4
|
||||
Audio standard. ISO/IEC gives users of the MPEG-2 NBC/MPEG-4 Audio
|
||||
standards free license to this software module or modifications thereof for use in
|
||||
hardware or software products claiming conformance to the MPEG-2 NBC/MPEG-4
|
||||
Audio standards. Those intending to use this software module in hardware or
|
||||
software products are advised that this use may infringe existing patents.
|
||||
The original developer of this software module and his/her company, the subsequent
|
||||
editors and their companies, and ISO/IEC have no liability for use of this software
|
||||
module or modifications thereof in an implementation. Copyright is not released for
|
||||
non MPEG-2 NBC/MPEG-4 Audio conforming products.The original developer
|
||||
retains full right to use the code for his/her own purpose, assign or donate the
|
||||
code to a third party and to inhibit third party from using the code for non
|
||||
MPEG-2 NBC/MPEG-4 Audio conforming products. This copyright notice must
|
||||
be included in all copies or derivative works."
|
||||
Copyright(c)1996.
|
||||
* *
|
||||
****************************************************************************/
|
||||
/*
|
||||
* $Id: channels.c,v 1.5 2001/09/04 18:39:35 menno Exp $
|
||||
*/
|
||||
|
||||
#include "channels.h"
|
||||
#include "coder.h"
|
||||
#include "util.h"
|
||||
|
||||
/* If LFE present */
|
||||
/* Num channels # of SCE's # of CPE's #of LFE's */
|
||||
/* ============ ========== ========== ========= */
|
||||
/* 1 1 0 0 */
|
||||
/* 2 0 1 0 */
|
||||
/* 3 1 1 0 */
|
||||
/* 4 1 1 1 */
|
||||
/* 5 1 2 0 */
|
||||
/* For more than 5 channels, use the following elements: */
|
||||
/* 2*N 1 2*(N-1) 1 */
|
||||
/* 2*N+1 1 2*N 0 */
|
||||
/* */
|
||||
/* Else: */
|
||||
/* */
|
||||
/* Num channels # of SCE's # of CPE's #of LFE's */
|
||||
/* ============ ========== ========== ========= */
|
||||
/* 1 1 0 0 */
|
||||
/* 2 0 1 0 */
|
||||
/* 3 1 1 0 */
|
||||
/* 4 2 1 0 */
|
||||
/* 5 1 2 0 */
|
||||
/* For more than 5 channels, use the following elements: */
|
||||
/* 2*N 2 2*(N-1) 0 */
|
||||
/* 2*N+1 1 2*N 0 */
|
||||
|
||||
void GetChannelInfo(ChannelInfo *channelInfo, int numChannels, int useLfe)
|
||||
{
|
||||
int sceTag = 0;
|
||||
int lfeTag = 0;
|
||||
int cpeTag = 0;
|
||||
int numChannelsLeft = numChannels;
|
||||
|
||||
|
||||
/* First element is sce, except for 2 channel case */
|
||||
if (numChannelsLeft != 2) {
|
||||
channelInfo[numChannels-numChannelsLeft].present = 1;
|
||||
channelInfo[numChannels-numChannelsLeft].tag = sceTag++;
|
||||
channelInfo[numChannels-numChannelsLeft].cpe = 0;
|
||||
channelInfo[numChannels-numChannelsLeft].lfe = 0;
|
||||
numChannelsLeft--;
|
||||
}
|
||||
|
||||
/* Next elements are cpe's */
|
||||
while (numChannelsLeft > 1) {
|
||||
/* Left channel info */
|
||||
channelInfo[numChannels-numChannelsLeft].present = 1;
|
||||
channelInfo[numChannels-numChannelsLeft].tag = cpeTag++;
|
||||
channelInfo[numChannels-numChannelsLeft].cpe = 1;
|
||||
channelInfo[numChannels-numChannelsLeft].common_window = 0;
|
||||
channelInfo[numChannels-numChannelsLeft].ch_is_left = 1;
|
||||
channelInfo[numChannels-numChannelsLeft].paired_ch = numChannels-numChannelsLeft+1;
|
||||
channelInfo[numChannels-numChannelsLeft].lfe = 0;
|
||||
numChannelsLeft--;
|
||||
|
||||
/* Right channel info */
|
||||
channelInfo[numChannels-numChannelsLeft].present = 1;
|
||||
channelInfo[numChannels-numChannelsLeft].cpe = 1;
|
||||
channelInfo[numChannels-numChannelsLeft].common_window = 0;
|
||||
channelInfo[numChannels-numChannelsLeft].ch_is_left = 0;
|
||||
channelInfo[numChannels-numChannelsLeft].paired_ch = numChannels-numChannelsLeft-1;
|
||||
channelInfo[numChannels-numChannelsLeft].lfe = 0;
|
||||
numChannelsLeft--;
|
||||
}
|
||||
|
||||
/* Is there another channel left ? */
|
||||
if (numChannelsLeft) {
|
||||
if (useLfe) {
|
||||
channelInfo[numChannels-numChannelsLeft].present = 1;
|
||||
channelInfo[numChannels-numChannelsLeft].tag = lfeTag++;
|
||||
channelInfo[numChannels-numChannelsLeft].cpe = 0;
|
||||
channelInfo[numChannels-numChannelsLeft].lfe = 1;
|
||||
} else {
|
||||
channelInfo[numChannels-numChannelsLeft].present = 1;
|
||||
channelInfo[numChannels-numChannelsLeft].tag = sceTag++;
|
||||
channelInfo[numChannels-numChannelsLeft].cpe = 0;
|
||||
channelInfo[numChannels-numChannelsLeft].lfe = 0;
|
||||
}
|
||||
numChannelsLeft--;
|
||||
}
|
||||
}
|
54
external/libfaac/libfaac/channels.h
vendored
Normal file
54
external/libfaac/libfaac/channels.h
vendored
Normal file
|
@ -0,0 +1,54 @@
|
|||
/*
|
||||
* FAAC - Freeware Advanced Audio Coder
|
||||
* Copyright (C) 2001 Menno Bakker
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
* $Id: channels.h,v 1.7 2003/06/26 19:19:41 knik Exp $
|
||||
*/
|
||||
|
||||
#ifndef CHANNEL_H
|
||||
#define CHANNEL_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif /* __cplusplus */
|
||||
|
||||
#include "coder.h"
|
||||
|
||||
typedef struct {
|
||||
int is_present;
|
||||
int ms_used[MAX_SCFAC_BANDS];
|
||||
} MSInfo;
|
||||
|
||||
typedef struct {
|
||||
int tag;
|
||||
int present;
|
||||
int ch_is_left;
|
||||
int paired_ch;
|
||||
int common_window;
|
||||
int cpe;
|
||||
int sce;
|
||||
int lfe;
|
||||
MSInfo msInfo;
|
||||
} ChannelInfo;
|
||||
|
||||
void GetChannelInfo(ChannelInfo *channelInfo, int numChannels, int useLfe);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif /* __cplusplus */
|
||||
|
||||
#endif /* CHANNEL_H */
|
210
external/libfaac/libfaac/coder.h
vendored
Normal file
210
external/libfaac/libfaac/coder.h
vendored
Normal file
|
@ -0,0 +1,210 @@
|
|||
/*
|
||||
* FAAC - Freeware Advanced Audio Coder
|
||||
* Copyright (C) 2001 Menno Bakker
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
* $Id: coder.h,v 1.13 2005/02/02 07:49:10 sur Exp $
|
||||
*/
|
||||
|
||||
#ifndef CODER_H
|
||||
#define CODER_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif /* __cplusplus */
|
||||
|
||||
/* Allow encoding of Digital Radio Mondiale (DRM) */
|
||||
//#define DRM
|
||||
|
||||
/* Allow encoding of Digital Radio Mondiale (DRM) with transform length 1024 */
|
||||
//#define DRM_1024
|
||||
|
||||
#define MAX_CHANNELS 64
|
||||
|
||||
#ifdef DRM
|
||||
#ifdef DRM_1024
|
||||
# define FRAME_LEN 1024
|
||||
# define BLOCK_LEN_LONG 1024
|
||||
# define BLOCK_LEN_SHORT 128
|
||||
#else
|
||||
# define FRAME_LEN 960
|
||||
# define BLOCK_LEN_LONG 960
|
||||
# define BLOCK_LEN_SHORT 120
|
||||
#endif /* DRM_1024 */
|
||||
#else
|
||||
# define FRAME_LEN 1024
|
||||
# define BLOCK_LEN_LONG 1024
|
||||
# define BLOCK_LEN_SHORT 128
|
||||
#endif
|
||||
|
||||
#define NSFB_LONG 51
|
||||
#define NSFB_SHORT 15
|
||||
#define MAX_SHORT_WINDOWS 8
|
||||
#define MAX_SCFAC_BANDS ((NSFB_SHORT+1)*MAX_SHORT_WINDOWS)
|
||||
|
||||
enum WINDOW_TYPE {
|
||||
ONLY_LONG_WINDOW,
|
||||
LONG_SHORT_WINDOW,
|
||||
ONLY_SHORT_WINDOW,
|
||||
SHORT_LONG_WINDOW
|
||||
};
|
||||
|
||||
#define TNS_MAX_ORDER 20
|
||||
#define DEF_TNS_GAIN_THRESH 1.4
|
||||
#define DEF_TNS_COEFF_THRESH 0.1
|
||||
#define DEF_TNS_COEFF_RES 4
|
||||
#define DEF_TNS_RES_OFFSET 3
|
||||
#define LEN_TNS_NFILTL 2
|
||||
#define LEN_TNS_NFILTS 1
|
||||
|
||||
#define DELAY 2048
|
||||
#define LEN_LTP_DATA_PRESENT 1
|
||||
#define LEN_LTP_LAG 11
|
||||
#define LEN_LTP_COEF 3
|
||||
#define LEN_LTP_SHORT_USED 1
|
||||
#define LEN_LTP_SHORT_LAG_PRESENT 1
|
||||
#define LEN_LTP_SHORT_LAG 5
|
||||
#define LTP_LAG_OFFSET 16
|
||||
#define LEN_LTP_LONG_USED 1
|
||||
#define MAX_LT_PRED_LONG_SFB 40
|
||||
#define MAX_LT_PRED_SHORT_SFB 13
|
||||
#define SHORT_SQ_OFFSET (BLOCK_LEN_LONG-(BLOCK_LEN_SHORT*4+BLOCK_LEN_SHORT/2))
|
||||
#define CODESIZE 8
|
||||
#define NOK_LT_BLEN (3 * BLOCK_LEN_LONG)
|
||||
|
||||
#define SBMAX_L 49
|
||||
#define LPC 2
|
||||
|
||||
typedef struct {
|
||||
int order; /* Filter order */
|
||||
int direction; /* Filtering direction */
|
||||
int coefCompress; /* Are coeffs compressed? */
|
||||
int length; /* Length, in bands */
|
||||
double aCoeffs[TNS_MAX_ORDER+1]; /* AR Coefficients */
|
||||
double kCoeffs[TNS_MAX_ORDER+1]; /* Reflection Coefficients */
|
||||
int index[TNS_MAX_ORDER+1]; /* Coefficient indices */
|
||||
} TnsFilterData;
|
||||
|
||||
typedef struct {
|
||||
int numFilters; /* Number of filters */
|
||||
int coefResolution; /* Coefficient resolution */
|
||||
TnsFilterData tnsFilter[1<<LEN_TNS_NFILTL]; /* TNS filters */
|
||||
} TnsWindowData;
|
||||
|
||||
typedef struct {
|
||||
int tnsDataPresent;
|
||||
int tnsMinBandNumberLong;
|
||||
int tnsMinBandNumberShort;
|
||||
int tnsMaxBandsLong;
|
||||
int tnsMaxBandsShort;
|
||||
int tnsMaxOrderLong;
|
||||
int tnsMaxOrderShort;
|
||||
TnsWindowData windowData[MAX_SHORT_WINDOWS]; /* TNS data per window */
|
||||
} TnsInfo;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
int weight_idx;
|
||||
double weight;
|
||||
int sbk_prediction_used[MAX_SHORT_WINDOWS];
|
||||
int sfb_prediction_used[MAX_SCFAC_BANDS];
|
||||
int delay[MAX_SHORT_WINDOWS];
|
||||
int global_pred_flag;
|
||||
int side_info;
|
||||
double *buffer;
|
||||
double *mdct_predicted;
|
||||
|
||||
double *time_buffer;
|
||||
double *ltp_overlap_buffer;
|
||||
} LtpInfo;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
int psy_init_mc;
|
||||
double dr_mc[LPC][BLOCK_LEN_LONG],e_mc[LPC+1+1][BLOCK_LEN_LONG];
|
||||
double K_mc[LPC+1][BLOCK_LEN_LONG], R_mc[LPC+1][BLOCK_LEN_LONG];
|
||||
double VAR_mc[LPC+1][BLOCK_LEN_LONG], KOR_mc[LPC+1][BLOCK_LEN_LONG];
|
||||
double sb_samples_pred_mc[BLOCK_LEN_LONG];
|
||||
int thisLineNeedsResetting_mc[BLOCK_LEN_LONG];
|
||||
int reset_count_mc;
|
||||
} BwpInfo;
|
||||
|
||||
|
||||
typedef struct {
|
||||
int window_shape;
|
||||
int prev_window_shape;
|
||||
int block_type;
|
||||
int desired_block_type;
|
||||
|
||||
int global_gain;
|
||||
int scale_factor[MAX_SCFAC_BANDS];
|
||||
|
||||
int num_window_groups;
|
||||
int window_group_length[8];
|
||||
int max_sfb;
|
||||
int nr_of_sfb;
|
||||
int sfb_offset[250];
|
||||
int lastx;
|
||||
double avgenrg;
|
||||
|
||||
int spectral_count;
|
||||
|
||||
/* Huffman codebook selected for each sf band */
|
||||
int book_vector[MAX_SCFAC_BANDS];
|
||||
|
||||
/* Data of spectral bitstream elements, for each spectral pair,
|
||||
5 elements are required: 1*(esc)+2*(sign)+2*(esc value)=5 */
|
||||
int *data;
|
||||
|
||||
/* Lengths of spectral bitstream elements */
|
||||
int *len;
|
||||
|
||||
#ifdef DRM
|
||||
int *num_data_cw;
|
||||
int cur_cw;
|
||||
int all_sfb;
|
||||
|
||||
int iLenLongestCW;
|
||||
int iLenReordSpData;
|
||||
#endif
|
||||
|
||||
/* Holds the requantized spectrum */
|
||||
double *requantFreq;
|
||||
|
||||
TnsInfo tnsInfo;
|
||||
LtpInfo ltpInfo;
|
||||
BwpInfo bwpInfo;
|
||||
|
||||
int max_pred_sfb;
|
||||
int pred_global_flag;
|
||||
int pred_sfb_flag[MAX_SCFAC_BANDS];
|
||||
int reset_group_number;
|
||||
|
||||
} CoderInfo;
|
||||
|
||||
typedef struct {
|
||||
unsigned long sampling_rate; /* the following entries are for this sampling rate */
|
||||
int num_cb_long;
|
||||
int num_cb_short;
|
||||
int cb_width_long[NSFB_LONG];
|
||||
int cb_width_short[NSFB_SHORT];
|
||||
} SR_INFO;
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif /* __cplusplus */
|
||||
|
||||
#endif /* CODER_H */
|
704
external/libfaac/libfaac/fft.c
vendored
Normal file
704
external/libfaac/libfaac/fft.c
vendored
Normal file
|
@ -0,0 +1,704 @@
|
|||
/*
|
||||
* FAAC - Freeware Advanced Audio Coder
|
||||
* $Id: fft.c,v 1.12 2005/02/02 07:49:55 sur Exp $
|
||||
* Copyright (C) 2002 Krzysztof Nikiel
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
*/
|
||||
|
||||
#include <math.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include "fft.h"
|
||||
#include "util.h"
|
||||
|
||||
#define MAXLOGM 9
|
||||
#define MAXLOGR 8
|
||||
|
||||
#if defined DRM && !defined DRM_1024
|
||||
|
||||
#include "kiss_fft/kiss_fft.h"
|
||||
#include "kiss_fft/kiss_fftr.h"
|
||||
|
||||
static const int logm_to_nfft[] =
|
||||
{
|
||||
/* 0 1 2 3 */
|
||||
0, 0, 0, 0,
|
||||
/* 4 5 6 7 */
|
||||
0, 0, 60, 0,
|
||||
/* 8 9 */
|
||||
240, 480
|
||||
};
|
||||
|
||||
void fft_initialize( FFT_Tables *fft_tables )
|
||||
{
|
||||
memset( fft_tables->cfg, 0, sizeof( fft_tables->cfg ) );
|
||||
}
|
||||
void fft_terminate( FFT_Tables *fft_tables )
|
||||
{
|
||||
unsigned int i;
|
||||
for ( i = 0; i < sizeof( fft_tables->cfg ) / sizeof( fft_tables->cfg[0] ); i++ )
|
||||
{
|
||||
if ( fft_tables->cfg[i][0] )
|
||||
{
|
||||
free( fft_tables->cfg[i][0] );
|
||||
fft_tables->cfg[i][0] = NULL;
|
||||
}
|
||||
if ( fft_tables->cfg[i][1] )
|
||||
{
|
||||
free( fft_tables->cfg[i][1] );
|
||||
fft_tables->cfg[i][1] = NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void rfft( FFT_Tables *fft_tables, double *x, int logm )
|
||||
{
|
||||
#if 0
|
||||
/* sur: do not use real-only optimized FFT */
|
||||
double xi[1 << MAXLOGR];
|
||||
|
||||
int nfft;
|
||||
|
||||
if ( logm > MAXLOGR )
|
||||
{
|
||||
fprintf(stderr, "rfft size too big\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
nfft = logm_to_nfft[logm];
|
||||
|
||||
if ( nfft )
|
||||
{
|
||||
//unsigned int i;
|
||||
//for ( i = 0; i < nfft; i++ )
|
||||
//{
|
||||
// xi[i] = 0.0;
|
||||
//}
|
||||
memset( xi, 0, nfft * sizeof( xi[0] ) );
|
||||
|
||||
fft( fft_tables, x, xi, logm );
|
||||
|
||||
memcpy( x + nfft / 2, xi, ( nfft / 2 ) * sizeof(x[0]) );
|
||||
}
|
||||
else
|
||||
{
|
||||
fprintf( stderr, "bad config for logm = %d\n", logm);
|
||||
exit( 1 );
|
||||
}
|
||||
|
||||
#else
|
||||
/* sur: use real-only optimized FFT */
|
||||
|
||||
int nfft = 0;
|
||||
|
||||
kiss_fft_scalar fin[1 << MAXLOGR];
|
||||
kiss_fft_cpx fout[1 << MAXLOGR];
|
||||
|
||||
if ( logm > MAXLOGR )
|
||||
{
|
||||
fprintf(stderr, "fft size too big\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
nfft = logm_to_nfft[logm];
|
||||
|
||||
if ( fft_tables->cfg[logm][0] == NULL )
|
||||
{
|
||||
if ( nfft )
|
||||
{
|
||||
fft_tables->cfg[logm][0] = kiss_fftr_alloc( nfft, 0, NULL, NULL );
|
||||
}
|
||||
else
|
||||
{
|
||||
fprintf(stderr, "bad logm = %d\n", logm);
|
||||
exit( 1 );
|
||||
}
|
||||
}
|
||||
|
||||
if ( fft_tables->cfg[logm][0] )
|
||||
{
|
||||
unsigned int i;
|
||||
|
||||
for ( i = 0; i < nfft; i++ )
|
||||
{
|
||||
fin[i] = x[i];
|
||||
}
|
||||
|
||||
kiss_fftr( (kiss_fftr_cfg)fft_tables->cfg[logm][0], fin, fout );
|
||||
|
||||
for ( i = 0; i < nfft / 2; i++ )
|
||||
{
|
||||
x[i] = fout[i].r;
|
||||
x[i + nfft / 2] = fout[i].i;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
fprintf( stderr, "bad config for logm = %d\n", logm);
|
||||
exit( 1 );
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void fft( FFT_Tables *fft_tables, double *xr, double *xi, int logm )
|
||||
{
|
||||
int nfft = 0;
|
||||
|
||||
kiss_fft_cpx fin[1 << MAXLOGM];
|
||||
kiss_fft_cpx fout[1 << MAXLOGM];
|
||||
|
||||
if ( logm > MAXLOGM )
|
||||
{
|
||||
fprintf(stderr, "fft size too big\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
nfft = logm_to_nfft[logm];
|
||||
|
||||
if ( fft_tables->cfg[logm][0] == NULL )
|
||||
{
|
||||
if ( nfft )
|
||||
{
|
||||
fft_tables->cfg[logm][0] = kiss_fft_alloc( nfft, 0, NULL, NULL );
|
||||
}
|
||||
else
|
||||
{
|
||||
fprintf(stderr, "bad logm = %d\n", logm);
|
||||
exit( 1 );
|
||||
}
|
||||
}
|
||||
|
||||
if ( fft_tables->cfg[logm][0] )
|
||||
{
|
||||
unsigned int i;
|
||||
|
||||
for ( i = 0; i < nfft; i++ )
|
||||
{
|
||||
fin[i].r = xr[i];
|
||||
fin[i].i = xi[i];
|
||||
}
|
||||
|
||||
kiss_fft( (kiss_fft_cfg)fft_tables->cfg[logm][0], fin, fout );
|
||||
|
||||
for ( i = 0; i < nfft; i++ )
|
||||
{
|
||||
xr[i] = fout[i].r;
|
||||
xi[i] = fout[i].i;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
fprintf( stderr, "bad config for logm = %d\n", logm);
|
||||
exit( 1 );
|
||||
}
|
||||
}
|
||||
|
||||
void ffti( FFT_Tables *fft_tables, double *xr, double *xi, int logm )
|
||||
{
|
||||
int nfft = 0;
|
||||
|
||||
kiss_fft_cpx fin[1 << MAXLOGM];
|
||||
kiss_fft_cpx fout[1 << MAXLOGM];
|
||||
|
||||
if ( logm > MAXLOGM )
|
||||
{
|
||||
fprintf(stderr, "fft size too big\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
nfft = logm_to_nfft[logm];
|
||||
|
||||
if ( fft_tables->cfg[logm][1] == NULL )
|
||||
{
|
||||
if ( nfft )
|
||||
{
|
||||
fft_tables->cfg[logm][1] = kiss_fft_alloc( nfft, 1, NULL, NULL );
|
||||
}
|
||||
else
|
||||
{
|
||||
fprintf(stderr, "bad logm = %d\n", logm);
|
||||
exit( 1 );
|
||||
}
|
||||
}
|
||||
|
||||
if ( fft_tables->cfg[logm][1] )
|
||||
{
|
||||
unsigned int i;
|
||||
double fac = 1.0 / (double)nfft;
|
||||
|
||||
for ( i = 0; i < nfft; i++ )
|
||||
{
|
||||
fin[i].r = xr[i];
|
||||
fin[i].i = xi[i];
|
||||
}
|
||||
|
||||
kiss_fft( (kiss_fft_cfg)fft_tables->cfg[logm][1], fin, fout );
|
||||
|
||||
for ( i = 0; i < nfft; i++ )
|
||||
{
|
||||
xr[i] = fout[i].r * fac;
|
||||
xi[i] = fout[i].i * fac;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
fprintf( stderr, "bad config for logm = %d\n", logm);
|
||||
exit( 1 );
|
||||
}
|
||||
}
|
||||
|
||||
/* sur: Trying to use cfft from libfaad2 -- it does not work 'from scratch' */
|
||||
//
|
||||
//#include "cfft/common.h"
|
||||
//
|
||||
//void fft_initialize( FFT_Tables *fft_tables )
|
||||
//{
|
||||
// memset( fft_tables->cfft, 0, sizeof( fft_tables->cfft ) );
|
||||
//}
|
||||
//void fft_terminate( FFT_Tables *fft_tables )
|
||||
//{
|
||||
// unsigned int i;
|
||||
// for ( i = 0; i < sizeof( fft_tables->cfft ) / sizeof( fft_tables->cfft[0] ); i++ )
|
||||
// {
|
||||
// if ( fft_tables->cfft[i] )
|
||||
// {
|
||||
// cfftu( fft_tables->cfft[i] );
|
||||
// fft_tables->cfft[i] = NULL;
|
||||
// }
|
||||
// }
|
||||
//}
|
||||
//
|
||||
//void rfft( FFT_Tables *fft_tables, double *x, int logm )
|
||||
//{
|
||||
// double xi[1 << MAXLOGR];
|
||||
//
|
||||
// int nfft;
|
||||
//
|
||||
// if ( logm > MAXLOGR )
|
||||
// {
|
||||
// fprintf(stderr, "rfft size too big\n");
|
||||
// exit(1);
|
||||
// }
|
||||
//
|
||||
// nfft = logm_to_nfft[logm];
|
||||
//
|
||||
// if ( nfft )
|
||||
// {
|
||||
// unsigned int i;
|
||||
//
|
||||
// for ( i = 0; i < nfft; i++ )
|
||||
// {
|
||||
// xi[i] = 0.0;
|
||||
// }
|
||||
// //memset( xi, 0, nfft * sizeof( xi[0] ) );
|
||||
//
|
||||
// fft( fft_tables, x, xi, logm );
|
||||
//
|
||||
// memcpy( x + nfft / 2, xi, ( nfft / 2 ) * sizeof(x[0]) );
|
||||
//
|
||||
//#ifdef SUR_DEBUG_FFT
|
||||
// {
|
||||
// FILE* f = fopen( "fft.log", "at" );
|
||||
//
|
||||
// fprintf( f, "RFFT(%d)\n", nfft );
|
||||
//
|
||||
// for ( i = 0; i < nfft; i++ )
|
||||
// {
|
||||
// fprintf( f, ";%d;%g;%g\n", i, x[i], xi[i] );
|
||||
// }
|
||||
//
|
||||
// fclose( f );
|
||||
// }
|
||||
//#endif
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
// fprintf( stderr, "bad config for logm = %d\n", logm);
|
||||
// exit( 1 );
|
||||
// }
|
||||
//}
|
||||
//
|
||||
//void fft( FFT_Tables *fft_tables, double *xr, double *xi, int logm )
|
||||
//{
|
||||
// int nfft;
|
||||
//
|
||||
// complex_t c[1 << MAXLOGM];
|
||||
//
|
||||
// if ( logm > MAXLOGM )
|
||||
// {
|
||||
// fprintf(stderr, "fft size too big\n");
|
||||
// exit(1);
|
||||
// }
|
||||
//
|
||||
// nfft = logm_to_nfft[logm];
|
||||
//
|
||||
// if ( fft_tables->cfft[logm] == NULL )
|
||||
// {
|
||||
// if ( nfft )
|
||||
// {
|
||||
// fft_tables->cfft[logm] = cffti( nfft );
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
// fprintf(stderr, "bad logm = %d\n", logm);
|
||||
// exit( 1 );
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// if ( fft_tables->cfft[logm] )
|
||||
// {
|
||||
// unsigned int i;
|
||||
//
|
||||
// for ( i = 0; i < nfft; i++ )
|
||||
// {
|
||||
// RE( c[i] ) = xr[i];
|
||||
// IM( c[i] ) = xi[i];
|
||||
// }
|
||||
//
|
||||
// cfftf( fft_tables->cfft[logm], c );
|
||||
//
|
||||
// for ( i = 0; i < nfft; i++ )
|
||||
// {
|
||||
// xr[i] = RE( c[i] );
|
||||
// xi[i] = IM( c[i] );
|
||||
// }
|
||||
//
|
||||
//#ifdef SUR_DEBUG_FFT
|
||||
// {
|
||||
// FILE* f = fopen( "fft.log", "at" );
|
||||
//
|
||||
// fprintf( f, "FFT(%d)\n", nfft );
|
||||
//
|
||||
// for ( i = 0; i < nfft; i++ )
|
||||
// {
|
||||
// fprintf( f, ";%d;%g;%g\n", i, xr[i], xi[i] );
|
||||
// }
|
||||
//
|
||||
// fclose( f );
|
||||
// }
|
||||
//#endif
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
// fprintf( stderr, "bad config for logm = %d\n", logm);
|
||||
// exit( 1 );
|
||||
// }
|
||||
//}
|
||||
//
|
||||
//void ffti( FFT_Tables *fft_tables, double *xr, double *xi, int logm )
|
||||
//{
|
||||
// int nfft;
|
||||
//
|
||||
// complex_t c[1 << MAXLOGM];
|
||||
//
|
||||
// if ( logm > MAXLOGM )
|
||||
// {
|
||||
// fprintf(stderr, "fft size too big\n");
|
||||
// exit(1);
|
||||
// }
|
||||
//
|
||||
// nfft = logm_to_nfft[logm];
|
||||
//
|
||||
// if ( fft_tables->cfft[logm] == NULL )
|
||||
// {
|
||||
// if ( nfft )
|
||||
// {
|
||||
// fft_tables->cfft[logm] = cffti( nfft );
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
// fprintf(stderr, "bad logm = %d\n", logm);
|
||||
// exit( 1 );
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// if ( fft_tables->cfft[logm] )
|
||||
// {
|
||||
// unsigned int i;
|
||||
//
|
||||
// for ( i = 0; i < nfft; i++ )
|
||||
// {
|
||||
// RE( c[i] ) = xr[i];
|
||||
// IM( c[i] ) = xi[i];
|
||||
// }
|
||||
//
|
||||
// cfftb( fft_tables->cfft[logm], c );
|
||||
//
|
||||
// for ( i = 0; i < nfft; i++ )
|
||||
// {
|
||||
// xr[i] = RE( c[i] );
|
||||
// xi[i] = IM( c[i] );
|
||||
// }
|
||||
//
|
||||
//#ifdef SUR_DEBUG_FFT
|
||||
// {
|
||||
// FILE* f = fopen( "fft.log", "at" );
|
||||
//
|
||||
// fprintf( f, "FFTI(%d)\n", nfft );
|
||||
//
|
||||
// for ( i = 0; i < nfft; i++ )
|
||||
// {
|
||||
// fprintf( f, ";%d;%g;%g\n", i, xr[i], xi[i] );
|
||||
// }
|
||||
//
|
||||
// fclose( f );
|
||||
// }
|
||||
//#endif
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
// fprintf( stderr, "bad config for logm = %d\n", logm);
|
||||
// exit( 1 );
|
||||
// }
|
||||
//}
|
||||
|
||||
#else /* !defined DRM || defined DRM_1024 */
|
||||
|
||||
void fft_initialize( FFT_Tables *fft_tables )
|
||||
{
|
||||
int i;
|
||||
fft_tables->costbl = AllocMemory( (MAXLOGM+1) * sizeof( fft_tables->costbl[0] ) );
|
||||
fft_tables->negsintbl = AllocMemory( (MAXLOGM+1) * sizeof( fft_tables->negsintbl[0] ) );
|
||||
fft_tables->reordertbl = AllocMemory( (MAXLOGM+1) * sizeof( fft_tables->reordertbl[0] ) );
|
||||
|
||||
for( i = 0; i< MAXLOGM+1; i++ )
|
||||
{
|
||||
fft_tables->costbl[i] = NULL;
|
||||
fft_tables->negsintbl[i] = NULL;
|
||||
fft_tables->reordertbl[i] = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
void fft_terminate( FFT_Tables *fft_tables )
|
||||
{
|
||||
int i;
|
||||
|
||||
for( i = 0; i< MAXLOGM+1; i++ )
|
||||
{
|
||||
if( fft_tables->costbl[i] != NULL )
|
||||
FreeMemory( fft_tables->costbl[i] );
|
||||
|
||||
if( fft_tables->negsintbl[i] != NULL )
|
||||
FreeMemory( fft_tables->negsintbl[i] );
|
||||
|
||||
if( fft_tables->reordertbl[i] != NULL )
|
||||
FreeMemory( fft_tables->reordertbl[i] );
|
||||
}
|
||||
|
||||
FreeMemory( fft_tables->costbl );
|
||||
FreeMemory( fft_tables->negsintbl );
|
||||
FreeMemory( fft_tables->reordertbl );
|
||||
|
||||
fft_tables->costbl = NULL;
|
||||
fft_tables->negsintbl = NULL;
|
||||
fft_tables->reordertbl = NULL;
|
||||
}
|
||||
|
||||
static void reorder( FFT_Tables *fft_tables, double *x, int logm)
|
||||
{
|
||||
int i;
|
||||
int size = 1 << logm;
|
||||
unsigned short *r; //size
|
||||
|
||||
|
||||
if ( fft_tables->reordertbl[logm] == NULL ) // create bit reversing table
|
||||
{
|
||||
fft_tables->reordertbl[logm] = AllocMemory(size * sizeof(*(fft_tables->reordertbl[0])));
|
||||
|
||||
for (i = 0; i < size; i++)
|
||||
{
|
||||
int reversed = 0;
|
||||
int b0;
|
||||
int tmp = i;
|
||||
|
||||
for (b0 = 0; b0 < logm; b0++)
|
||||
{
|
||||
reversed = (reversed << 1) | (tmp & 1);
|
||||
tmp >>= 1;
|
||||
}
|
||||
fft_tables->reordertbl[logm][i] = reversed;
|
||||
}
|
||||
}
|
||||
|
||||
r = fft_tables->reordertbl[logm];
|
||||
|
||||
for (i = 0; i < size; i++)
|
||||
{
|
||||
int j = r[i];
|
||||
double tmp;
|
||||
|
||||
if (j <= i)
|
||||
continue;
|
||||
|
||||
tmp = x[i];
|
||||
x[i] = x[j];
|
||||
x[j] = tmp;
|
||||
}
|
||||
}
|
||||
|
||||
static void fft_proc(
|
||||
double *xr,
|
||||
double *xi,
|
||||
fftfloat *refac,
|
||||
fftfloat *imfac,
|
||||
int size)
|
||||
{
|
||||
int step, shift, pos;
|
||||
int exp, estep;
|
||||
|
||||
estep = size;
|
||||
for (step = 1; step < size; step *= 2)
|
||||
{
|
||||
int x1;
|
||||
int x2 = 0;
|
||||
estep >>= 1;
|
||||
for (pos = 0; pos < size; pos += (2 * step))
|
||||
{
|
||||
x1 = x2;
|
||||
x2 += step;
|
||||
exp = 0;
|
||||
for (shift = 0; shift < step; shift++)
|
||||
{
|
||||
double v2r, v2i;
|
||||
|
||||
v2r = xr[x2] * refac[exp] - xi[x2] * imfac[exp];
|
||||
v2i = xr[x2] * imfac[exp] + xi[x2] * refac[exp];
|
||||
|
||||
xr[x2] = xr[x1] - v2r;
|
||||
xr[x1] += v2r;
|
||||
|
||||
xi[x2] = xi[x1] - v2i;
|
||||
|
||||
xi[x1] += v2i;
|
||||
|
||||
exp += estep;
|
||||
|
||||
x1++;
|
||||
x2++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void check_tables( FFT_Tables *fft_tables, int logm)
|
||||
{
|
||||
if( fft_tables->costbl[logm] == NULL )
|
||||
{
|
||||
int i;
|
||||
int size = 1 << logm;
|
||||
|
||||
if( fft_tables->negsintbl[logm] != NULL )
|
||||
FreeMemory( fft_tables->negsintbl[logm] );
|
||||
|
||||
fft_tables->costbl[logm] = AllocMemory((size / 2) * sizeof(*(fft_tables->costbl[0])));
|
||||
fft_tables->negsintbl[logm] = AllocMemory((size / 2) * sizeof(*(fft_tables->negsintbl[0])));
|
||||
|
||||
for (i = 0; i < (size >> 1); i++)
|
||||
{
|
||||
double theta = 2.0 * M_PI * ((double) i) / (double) size;
|
||||
fft_tables->costbl[logm][i] = cos(theta);
|
||||
fft_tables->negsintbl[logm][i] = -sin(theta);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void fft( FFT_Tables *fft_tables, double *xr, double *xi, int logm)
|
||||
{
|
||||
if (logm > MAXLOGM)
|
||||
{
|
||||
fprintf(stderr, "fft size too big\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if (logm < 1)
|
||||
{
|
||||
//printf("logm < 1\n");
|
||||
return;
|
||||
}
|
||||
|
||||
check_tables( fft_tables, logm);
|
||||
|
||||
reorder( fft_tables, xr, logm);
|
||||
reorder( fft_tables, xi, logm);
|
||||
|
||||
fft_proc( xr, xi, fft_tables->costbl[logm], fft_tables->negsintbl[logm], 1 << logm );
|
||||
}
|
||||
|
||||
void rfft( FFT_Tables *fft_tables, double *x, int logm)
|
||||
{
|
||||
double xi[1 << MAXLOGR];
|
||||
|
||||
if (logm > MAXLOGR)
|
||||
{
|
||||
fprintf(stderr, "rfft size too big\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
memset(xi, 0, (1 << logm) * sizeof(xi[0]));
|
||||
|
||||
fft( fft_tables, x, xi, logm);
|
||||
|
||||
memcpy(x + (1 << (logm - 1)), xi, (1 << (logm - 1)) * sizeof(*x));
|
||||
}
|
||||
|
||||
void ffti( FFT_Tables *fft_tables, double *xr, double *xi, int logm)
|
||||
{
|
||||
int i, size;
|
||||
double fac;
|
||||
double *xrp, *xip;
|
||||
|
||||
fft( fft_tables, xi, xr, logm);
|
||||
|
||||
size = 1 << logm;
|
||||
fac = 1.0 / size;
|
||||
xrp = xr;
|
||||
xip = xi;
|
||||
|
||||
for (i = 0; i < size; i++)
|
||||
{
|
||||
*xrp++ *= fac;
|
||||
*xip++ *= fac;
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* defined DRM && !defined DRM_1024 */
|
||||
|
||||
/*
|
||||
$Log: fft.c,v $
|
||||
Revision 1.12 2005/02/02 07:49:55 sur
|
||||
Added interface to kiss_fft library to implement FFT for 960 transform length.
|
||||
|
||||
Revision 1.11 2004/04/02 14:56:17 danchr
|
||||
fix name clash w/ libavcodec: fft_init -> fft_initialize
|
||||
bump version number to 1.24 beta
|
||||
|
||||
Revision 1.10 2003/11/16 05:02:51 stux
|
||||
moved global tables from fft.c into hEncoder FFT_Tables. Add fft_init and fft_terminate, flowed through all necessary changes. This should remove at least one instance of a memory leak, and fix some thread-safety problems. Version update to 1.23.3
|
||||
|
||||
Revision 1.9 2003/09/07 16:48:01 knik
|
||||
reduced arrays size
|
||||
|
||||
Revision 1.8 2002/11/23 17:32:54 knik
|
||||
rfft: made xi a local variable
|
||||
|
||||
Revision 1.7 2002/08/21 16:52:25 knik
|
||||
new simplier and faster fft routine and correct real fft
|
||||
new real fft is just a complex fft wrapper so it is slower than optimal but
|
||||
by surprise it seems to be at least as fast as the old buggy function
|
||||
|
||||
*/
|
55
external/libfaac/libfaac/fft.h
vendored
Normal file
55
external/libfaac/libfaac/fft.h
vendored
Normal file
|
@ -0,0 +1,55 @@
|
|||
/*
|
||||
* FAAC - Freeware Advanced Audio Coder
|
||||
* $Id: fft.h,v 1.6 2005/02/02 07:50:35 sur Exp $
|
||||
* Copyright (C) 2002 Krzysztof Nikiel
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef _FFT_H_
|
||||
#define _FFT_H_
|
||||
|
||||
typedef float fftfloat;
|
||||
|
||||
#if defined DRM && !defined DRM_1024
|
||||
|
||||
#define MAX_FFT 10
|
||||
|
||||
typedef struct
|
||||
{
|
||||
/* cfg[Max FFT][FFT and inverse FFT] */
|
||||
void* cfg[MAX_FFT][2];
|
||||
} FFT_Tables;
|
||||
|
||||
#else /* use own FFT */
|
||||
|
||||
typedef struct
|
||||
{
|
||||
fftfloat **costbl;
|
||||
fftfloat **negsintbl;
|
||||
unsigned short **reordertbl;
|
||||
} FFT_Tables;
|
||||
|
||||
#endif /* defined DRM && !defined DRM_1024 */
|
||||
|
||||
void fft_initialize ( FFT_Tables *fft_tables );
|
||||
void fft_terminate ( FFT_Tables *fft_tables );
|
||||
|
||||
void rfft ( FFT_Tables *fft_tables, double *x, int logm );
|
||||
void fft ( FFT_Tables *fft_tables, double *xr, double *xi, int logm );
|
||||
void ffti ( FFT_Tables *fft_tables, double *xr, double *xi, int logm );
|
||||
|
||||
#endif
|
578
external/libfaac/libfaac/filtbank.c
vendored
Normal file
578
external/libfaac/libfaac/filtbank.c
vendored
Normal file
|
@ -0,0 +1,578 @@
|
|||
/************************* MPEG-2 NBC Audio Decoder **************************
|
||||
* *
|
||||
"This software module was originally developed by
|
||||
AT&T, Dolby Laboratories, Fraunhofer Gesellschaft IIS in the course of
|
||||
development of the MPEG-2 NBC/MPEG-4 Audio standard ISO/IEC 13818-7,
|
||||
14496-1,2 and 3. This software module is an implementation of a part of one or more
|
||||
MPEG-2 NBC/MPEG-4 Audio tools as specified by the MPEG-2 NBC/MPEG-4
|
||||
Audio standard. ISO/IEC gives users of the MPEG-2 NBC/MPEG-4 Audio
|
||||
standards free license to this software module or modifications thereof for use in
|
||||
hardware or software products claiming conformance to the MPEG-2 NBC/MPEG-4
|
||||
Audio standards. Those intending to use this software module in hardware or
|
||||
software products are advised that this use may infringe existing patents.
|
||||
The original developer of this software module and his/her company, the subsequent
|
||||
editors and their companies, and ISO/IEC have no liability for use of this software
|
||||
module or modifications thereof in an implementation. Copyright is not released for
|
||||
non MPEG-2 NBC/MPEG-4 Audio conforming products.The original developer
|
||||
retains full right to use the code for his/her own purpose, assign or donate the
|
||||
code to a third party and to inhibit third party from using the code for non
|
||||
MPEG-2 NBC/MPEG-4 Audio conforming products. This copyright notice must
|
||||
be included in all copies or derivative works."
|
||||
Copyright(c)1996.
|
||||
* *
|
||||
****************************************************************************/
|
||||
/*
|
||||
* $Id: filtbank.c,v 1.13 2005/02/02 07:51:12 sur Exp $
|
||||
*/
|
||||
|
||||
/*
|
||||
* CHANGES:
|
||||
* 2001/01/17: menno: Added frequency cut off filter.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <math.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "coder.h"
|
||||
#include "filtbank.h"
|
||||
#include "frame.h"
|
||||
#include "fft.h"
|
||||
#include "util.h"
|
||||
|
||||
#define TWOPI 2*M_PI
|
||||
|
||||
|
||||
static void CalculateKBDWindow ( double* win, double alpha, int length );
|
||||
static double Izero ( double x);
|
||||
static void MDCT ( FFT_Tables *fft_tables, double *data, int N );
|
||||
static void IMDCT ( FFT_Tables *fft_tables, double *data, int N );
|
||||
|
||||
|
||||
|
||||
void FilterBankInit(faacEncHandle hEncoder)
|
||||
{
|
||||
unsigned int i, channel;
|
||||
|
||||
for (channel = 0; channel < hEncoder->numChannels; channel++) {
|
||||
hEncoder->freqBuff[channel] = (double*)AllocMemory(2*FRAME_LEN*sizeof(double));
|
||||
hEncoder->overlapBuff[channel] = (double*)AllocMemory(FRAME_LEN*sizeof(double));
|
||||
SetMemory(hEncoder->overlapBuff[channel], 0, FRAME_LEN*sizeof(double));
|
||||
}
|
||||
|
||||
hEncoder->sin_window_long = (double*)AllocMemory(BLOCK_LEN_LONG*sizeof(double));
|
||||
hEncoder->sin_window_short = (double*)AllocMemory(BLOCK_LEN_SHORT*sizeof(double));
|
||||
hEncoder->kbd_window_long = (double*)AllocMemory(BLOCK_LEN_LONG*sizeof(double));
|
||||
hEncoder->kbd_window_short = (double*)AllocMemory(BLOCK_LEN_SHORT*sizeof(double));
|
||||
|
||||
for( i=0; i<BLOCK_LEN_LONG; i++ )
|
||||
hEncoder->sin_window_long[i] = sin((M_PI/(2*BLOCK_LEN_LONG)) * (i + 0.5));
|
||||
for( i=0; i<BLOCK_LEN_SHORT; i++ )
|
||||
hEncoder->sin_window_short[i] = sin((M_PI/(2*BLOCK_LEN_SHORT)) * (i + 0.5));
|
||||
|
||||
CalculateKBDWindow(hEncoder->kbd_window_long, 4, BLOCK_LEN_LONG*2);
|
||||
CalculateKBDWindow(hEncoder->kbd_window_short, 6, BLOCK_LEN_SHORT*2);
|
||||
}
|
||||
|
||||
void FilterBankEnd(faacEncHandle hEncoder)
|
||||
{
|
||||
unsigned int channel;
|
||||
|
||||
for (channel = 0; channel < hEncoder->numChannels; channel++) {
|
||||
if (hEncoder->freqBuff[channel]) FreeMemory(hEncoder->freqBuff[channel]);
|
||||
if (hEncoder->overlapBuff[channel]) FreeMemory(hEncoder->overlapBuff[channel]);
|
||||
}
|
||||
|
||||
if (hEncoder->sin_window_long) FreeMemory(hEncoder->sin_window_long);
|
||||
if (hEncoder->sin_window_short) FreeMemory(hEncoder->sin_window_short);
|
||||
if (hEncoder->kbd_window_long) FreeMemory(hEncoder->kbd_window_long);
|
||||
if (hEncoder->kbd_window_short) FreeMemory(hEncoder->kbd_window_short);
|
||||
}
|
||||
|
||||
void FilterBank(faacEncHandle hEncoder,
|
||||
CoderInfo *coderInfo,
|
||||
double *p_in_data,
|
||||
double *p_out_mdct,
|
||||
double *p_overlap,
|
||||
int overlap_select)
|
||||
{
|
||||
double *p_o_buf, *first_window, *second_window;
|
||||
double *transf_buf;
|
||||
int k, i;
|
||||
int block_type = coderInfo->block_type;
|
||||
|
||||
transf_buf = (double*)AllocMemory(2*BLOCK_LEN_LONG*sizeof(double));
|
||||
|
||||
/* create / shift old values */
|
||||
/* We use p_overlap here as buffer holding the last frame time signal*/
|
||||
if(overlap_select != MNON_OVERLAPPED) {
|
||||
memcpy(transf_buf, p_overlap, FRAME_LEN*sizeof(double));
|
||||
memcpy(transf_buf+BLOCK_LEN_LONG, p_in_data, FRAME_LEN*sizeof(double));
|
||||
memcpy(p_overlap, p_in_data, FRAME_LEN*sizeof(double));
|
||||
} else {
|
||||
memcpy(transf_buf, p_in_data, 2*FRAME_LEN*sizeof(double));
|
||||
}
|
||||
|
||||
/* Window shape processing */
|
||||
if(overlap_select != MNON_OVERLAPPED) {
|
||||
switch (coderInfo->prev_window_shape) {
|
||||
case SINE_WINDOW:
|
||||
if ( (block_type == ONLY_LONG_WINDOW) || (block_type == LONG_SHORT_WINDOW))
|
||||
first_window = hEncoder->sin_window_long;
|
||||
else
|
||||
first_window = hEncoder->sin_window_short;
|
||||
break;
|
||||
case KBD_WINDOW:
|
||||
if ( (block_type == ONLY_LONG_WINDOW) || (block_type == LONG_SHORT_WINDOW))
|
||||
first_window = hEncoder->kbd_window_long;
|
||||
else
|
||||
first_window = hEncoder->kbd_window_short;
|
||||
break;
|
||||
}
|
||||
|
||||
switch (coderInfo->window_shape){
|
||||
case SINE_WINDOW:
|
||||
if ( (block_type == ONLY_LONG_WINDOW) || (block_type == SHORT_LONG_WINDOW))
|
||||
second_window = hEncoder->sin_window_long;
|
||||
else
|
||||
second_window = hEncoder->sin_window_short;
|
||||
break;
|
||||
case KBD_WINDOW:
|
||||
if ( (block_type == ONLY_LONG_WINDOW) || (block_type == SHORT_LONG_WINDOW))
|
||||
second_window = hEncoder->kbd_window_long;
|
||||
else
|
||||
second_window = hEncoder->kbd_window_short;
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
/* Always long block and sine window for LTP */
|
||||
first_window = hEncoder->sin_window_long;
|
||||
second_window = hEncoder->sin_window_long;
|
||||
}
|
||||
|
||||
/* Set ptr to transf-Buffer */
|
||||
p_o_buf = transf_buf;
|
||||
|
||||
/* Separate action for each Block Type */
|
||||
switch (block_type) {
|
||||
case ONLY_LONG_WINDOW :
|
||||
for ( i = 0 ; i < BLOCK_LEN_LONG ; i++){
|
||||
p_out_mdct[i] = p_o_buf[i] * first_window[i];
|
||||
p_out_mdct[i+BLOCK_LEN_LONG] = p_o_buf[i+BLOCK_LEN_LONG] * second_window[BLOCK_LEN_LONG-i-1];
|
||||
}
|
||||
MDCT( &hEncoder->fft_tables, p_out_mdct, 2*BLOCK_LEN_LONG );
|
||||
break;
|
||||
|
||||
case LONG_SHORT_WINDOW :
|
||||
for ( i = 0 ; i < BLOCK_LEN_LONG ; i++)
|
||||
p_out_mdct[i] = p_o_buf[i] * first_window[i];
|
||||
memcpy(p_out_mdct+BLOCK_LEN_LONG,p_o_buf+BLOCK_LEN_LONG,NFLAT_LS*sizeof(double));
|
||||
for ( i = 0 ; i < BLOCK_LEN_SHORT ; i++)
|
||||
p_out_mdct[i+BLOCK_LEN_LONG+NFLAT_LS] = p_o_buf[i+BLOCK_LEN_LONG+NFLAT_LS] * second_window[BLOCK_LEN_SHORT-i-1];
|
||||
SetMemory(p_out_mdct+BLOCK_LEN_LONG+NFLAT_LS+BLOCK_LEN_SHORT,0,NFLAT_LS*sizeof(double));
|
||||
MDCT( &hEncoder->fft_tables, p_out_mdct, 2*BLOCK_LEN_LONG );
|
||||
break;
|
||||
|
||||
case SHORT_LONG_WINDOW :
|
||||
SetMemory(p_out_mdct,0,NFLAT_LS*sizeof(double));
|
||||
for ( i = 0 ; i < BLOCK_LEN_SHORT ; i++)
|
||||
p_out_mdct[i+NFLAT_LS] = p_o_buf[i+NFLAT_LS] * first_window[i];
|
||||
memcpy(p_out_mdct+NFLAT_LS+BLOCK_LEN_SHORT,p_o_buf+NFLAT_LS+BLOCK_LEN_SHORT,NFLAT_LS*sizeof(double));
|
||||
for ( i = 0 ; i < BLOCK_LEN_LONG ; i++)
|
||||
p_out_mdct[i+BLOCK_LEN_LONG] = p_o_buf[i+BLOCK_LEN_LONG] * second_window[BLOCK_LEN_LONG-i-1];
|
||||
MDCT( &hEncoder->fft_tables, p_out_mdct, 2*BLOCK_LEN_LONG );
|
||||
break;
|
||||
|
||||
case ONLY_SHORT_WINDOW :
|
||||
p_o_buf += NFLAT_LS;
|
||||
for ( k=0; k < MAX_SHORT_WINDOWS; k++ ) {
|
||||
for ( i = 0 ; i < BLOCK_LEN_SHORT ; i++ ){
|
||||
p_out_mdct[i] = p_o_buf[i] * first_window[i];
|
||||
p_out_mdct[i+BLOCK_LEN_SHORT] = p_o_buf[i+BLOCK_LEN_SHORT] * second_window[BLOCK_LEN_SHORT-i-1];
|
||||
}
|
||||
MDCT( &hEncoder->fft_tables, p_out_mdct, 2*BLOCK_LEN_SHORT );
|
||||
p_out_mdct += BLOCK_LEN_SHORT;
|
||||
p_o_buf += BLOCK_LEN_SHORT;
|
||||
first_window = second_window;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
if (transf_buf) FreeMemory(transf_buf);
|
||||
}
|
||||
|
||||
void IFilterBank(faacEncHandle hEncoder,
|
||||
CoderInfo *coderInfo,
|
||||
double *p_in_data,
|
||||
double *p_out_data,
|
||||
double *p_overlap,
|
||||
int overlap_select)
|
||||
{
|
||||
double *o_buf, *transf_buf, *overlap_buf;
|
||||
double *first_window, *second_window;
|
||||
|
||||
double *fp;
|
||||
int k, i;
|
||||
int block_type = coderInfo->block_type;
|
||||
|
||||
transf_buf = (double*)AllocMemory(2*BLOCK_LEN_LONG*sizeof(double));
|
||||
overlap_buf = (double*)AllocMemory(2*BLOCK_LEN_LONG*sizeof(double));
|
||||
|
||||
/* Window shape processing */
|
||||
if (overlap_select != MNON_OVERLAPPED) {
|
||||
// switch (coderInfo->prev_window_shape){
|
||||
// case SINE_WINDOW:
|
||||
if ( (block_type == ONLY_LONG_WINDOW) || (block_type == LONG_SHORT_WINDOW))
|
||||
first_window = hEncoder->sin_window_long;
|
||||
else
|
||||
first_window = hEncoder->sin_window_short;
|
||||
// break;
|
||||
// case KBD_WINDOW:
|
||||
// if ( (block_type == ONLY_LONG_WINDOW) || (block_type == LONG_SHORT_WINDOW))
|
||||
// first_window = hEncoder->kbd_window_long;
|
||||
// else
|
||||
// first_window = hEncoder->kbd_window_short;
|
||||
// break;
|
||||
// }
|
||||
|
||||
// switch (coderInfo->window_shape){
|
||||
// case SINE_WINDOW:
|
||||
if ( (block_type == ONLY_LONG_WINDOW) || (block_type == SHORT_LONG_WINDOW))
|
||||
second_window = hEncoder->sin_window_long;
|
||||
else
|
||||
second_window = hEncoder->sin_window_short;
|
||||
// break;
|
||||
// case KBD_WINDOW:
|
||||
// if ( (block_type == ONLY_LONG_WINDOW) || (block_type == SHORT_LONG_WINDOW))
|
||||
// second_window = hEncoder->kbd_window_long;
|
||||
// else
|
||||
// second_window = hEncoder->kbd_window_short;
|
||||
// break;
|
||||
// }
|
||||
} else {
|
||||
/* Always long block and sine window for LTP */
|
||||
first_window = hEncoder->sin_window_long;
|
||||
second_window = hEncoder->sin_window_long;
|
||||
}
|
||||
|
||||
/* Assemble overlap buffer */
|
||||
memcpy(overlap_buf,p_overlap,BLOCK_LEN_LONG*sizeof(double));
|
||||
o_buf = overlap_buf;
|
||||
|
||||
/* Separate action for each Block Type */
|
||||
switch( block_type ) {
|
||||
case ONLY_LONG_WINDOW :
|
||||
memcpy(transf_buf, p_in_data,BLOCK_LEN_LONG*sizeof(double));
|
||||
IMDCT( &hEncoder->fft_tables, transf_buf, 2*BLOCK_LEN_LONG );
|
||||
for ( i = 0 ; i < BLOCK_LEN_LONG ; i++)
|
||||
transf_buf[i] *= first_window[i];
|
||||
if (overlap_select != MNON_OVERLAPPED) {
|
||||
for ( i = 0 ; i < BLOCK_LEN_LONG; i++ ){
|
||||
o_buf[i] += transf_buf[i];
|
||||
o_buf[i+BLOCK_LEN_LONG] = transf_buf[i+BLOCK_LEN_LONG] * second_window[BLOCK_LEN_LONG-i-1];
|
||||
}
|
||||
} else { /* overlap_select == NON_OVERLAPPED */
|
||||
for ( i = 0 ; i < BLOCK_LEN_LONG; i++ )
|
||||
transf_buf[i+BLOCK_LEN_LONG] *= second_window[BLOCK_LEN_LONG-i-1];
|
||||
}
|
||||
break;
|
||||
|
||||
case LONG_SHORT_WINDOW :
|
||||
memcpy(transf_buf, p_in_data,BLOCK_LEN_LONG*sizeof(double));
|
||||
IMDCT( &hEncoder->fft_tables, transf_buf, 2*BLOCK_LEN_LONG );
|
||||
for ( i = 0 ; i < BLOCK_LEN_LONG ; i++)
|
||||
transf_buf[i] *= first_window[i];
|
||||
if (overlap_select != MNON_OVERLAPPED) {
|
||||
for ( i = 0 ; i < BLOCK_LEN_LONG; i++ )
|
||||
o_buf[i] += transf_buf[i];
|
||||
memcpy(o_buf+BLOCK_LEN_LONG,transf_buf+BLOCK_LEN_LONG,NFLAT_LS*sizeof(double));
|
||||
for ( i = 0 ; i < BLOCK_LEN_SHORT ; i++)
|
||||
o_buf[i+BLOCK_LEN_LONG+NFLAT_LS] = transf_buf[i+BLOCK_LEN_LONG+NFLAT_LS] * second_window[BLOCK_LEN_SHORT-i-1];
|
||||
SetMemory(o_buf+BLOCK_LEN_LONG+NFLAT_LS+BLOCK_LEN_SHORT,0,NFLAT_LS*sizeof(double));
|
||||
} else { /* overlap_select == NON_OVERLAPPED */
|
||||
for ( i = 0 ; i < BLOCK_LEN_SHORT ; i++)
|
||||
transf_buf[i+BLOCK_LEN_LONG+NFLAT_LS] *= second_window[BLOCK_LEN_SHORT-i-1];
|
||||
SetMemory(transf_buf+BLOCK_LEN_LONG+NFLAT_LS+BLOCK_LEN_SHORT,0,NFLAT_LS*sizeof(double));
|
||||
}
|
||||
break;
|
||||
|
||||
case SHORT_LONG_WINDOW :
|
||||
memcpy(transf_buf, p_in_data,BLOCK_LEN_LONG*sizeof(double));
|
||||
IMDCT( &hEncoder->fft_tables, transf_buf, 2*BLOCK_LEN_LONG );
|
||||
for ( i = 0 ; i < BLOCK_LEN_SHORT ; i++)
|
||||
transf_buf[i+NFLAT_LS] *= first_window[i];
|
||||
if (overlap_select != MNON_OVERLAPPED) {
|
||||
for ( i = 0 ; i < BLOCK_LEN_SHORT; i++ )
|
||||
o_buf[i+NFLAT_LS] += transf_buf[i+NFLAT_LS];
|
||||
memcpy(o_buf+BLOCK_LEN_SHORT+NFLAT_LS,transf_buf+BLOCK_LEN_SHORT+NFLAT_LS,NFLAT_LS*sizeof(double));
|
||||
for ( i = 0 ; i < BLOCK_LEN_LONG ; i++)
|
||||
o_buf[i+BLOCK_LEN_LONG] = transf_buf[i+BLOCK_LEN_LONG] * second_window[BLOCK_LEN_LONG-i-1];
|
||||
} else { /* overlap_select == NON_OVERLAPPED */
|
||||
SetMemory(transf_buf,0,NFLAT_LS*sizeof(double));
|
||||
for ( i = 0 ; i < BLOCK_LEN_LONG ; i++)
|
||||
transf_buf[i+BLOCK_LEN_LONG] *= second_window[BLOCK_LEN_LONG-i-1];
|
||||
}
|
||||
break;
|
||||
|
||||
case ONLY_SHORT_WINDOW :
|
||||
if (overlap_select != MNON_OVERLAPPED) {
|
||||
fp = o_buf + NFLAT_LS;
|
||||
} else { /* overlap_select == NON_OVERLAPPED */
|
||||
fp = transf_buf;
|
||||
}
|
||||
for ( k=0; k < MAX_SHORT_WINDOWS; k++ ) {
|
||||
memcpy(transf_buf,p_in_data,BLOCK_LEN_SHORT*sizeof(double));
|
||||
IMDCT( &hEncoder->fft_tables, transf_buf, 2*BLOCK_LEN_SHORT );
|
||||
p_in_data += BLOCK_LEN_SHORT;
|
||||
if (overlap_select != MNON_OVERLAPPED) {
|
||||
for ( i = 0 ; i < BLOCK_LEN_SHORT ; i++){
|
||||
transf_buf[i] *= first_window[i];
|
||||
fp[i] += transf_buf[i];
|
||||
fp[i+BLOCK_LEN_SHORT] = transf_buf[i+BLOCK_LEN_SHORT] * second_window[BLOCK_LEN_SHORT-i-1];
|
||||
}
|
||||
fp += BLOCK_LEN_SHORT;
|
||||
} else { /* overlap_select == NON_OVERLAPPED */
|
||||
for ( i = 0 ; i < BLOCK_LEN_SHORT ; i++){
|
||||
fp[i] *= first_window[i];
|
||||
fp[i+BLOCK_LEN_SHORT] *= second_window[BLOCK_LEN_SHORT-i-1];
|
||||
}
|
||||
fp += 2*BLOCK_LEN_SHORT;
|
||||
}
|
||||
first_window = second_window;
|
||||
}
|
||||
SetMemory(o_buf+BLOCK_LEN_LONG+NFLAT_LS+BLOCK_LEN_SHORT,0,NFLAT_LS*sizeof(double));
|
||||
break;
|
||||
}
|
||||
|
||||
if (overlap_select != MNON_OVERLAPPED)
|
||||
memcpy(p_out_data,o_buf,BLOCK_LEN_LONG*sizeof(double));
|
||||
else /* overlap_select == NON_OVERLAPPED */
|
||||
memcpy(p_out_data,transf_buf,2*BLOCK_LEN_LONG*sizeof(double));
|
||||
|
||||
/* save unused output data */
|
||||
memcpy(p_overlap,o_buf+BLOCK_LEN_LONG,BLOCK_LEN_LONG*sizeof(double));
|
||||
|
||||
if (overlap_buf) FreeMemory(overlap_buf);
|
||||
if (transf_buf) FreeMemory(transf_buf);
|
||||
}
|
||||
|
||||
void specFilter(double *freqBuff,
|
||||
int sampleRate,
|
||||
int lowpassFreq,
|
||||
int specLen
|
||||
)
|
||||
{
|
||||
int lowpass,xlowpass;
|
||||
|
||||
/* calculate the last line which is not zero */
|
||||
lowpass = (lowpassFreq * specLen) / (sampleRate>>1) + 1;
|
||||
xlowpass = (lowpass < specLen) ? lowpass : specLen ;
|
||||
|
||||
SetMemory(freqBuff+xlowpass,0,(specLen-xlowpass)*sizeof(double));
|
||||
}
|
||||
|
||||
static double Izero(double x)
|
||||
{
|
||||
const double IzeroEPSILON = 1E-41; /* Max error acceptable in Izero */
|
||||
double sum, u, halfx, temp;
|
||||
int n;
|
||||
|
||||
sum = u = n = 1;
|
||||
halfx = x/2.0;
|
||||
do {
|
||||
temp = halfx/(double)n;
|
||||
n += 1;
|
||||
temp *= temp;
|
||||
u *= temp;
|
||||
sum += u;
|
||||
} while (u >= IzeroEPSILON*sum);
|
||||
|
||||
return(sum);
|
||||
}
|
||||
|
||||
static void CalculateKBDWindow(double* win, double alpha, int length)
|
||||
{
|
||||
int i;
|
||||
double IBeta;
|
||||
double tmp;
|
||||
double sum = 0.0;
|
||||
|
||||
alpha *= M_PI;
|
||||
IBeta = 1.0/Izero(alpha);
|
||||
|
||||
/* calculate lower half of Kaiser Bessel window */
|
||||
for(i=0; i<(length>>1); i++) {
|
||||
tmp = 4.0*(double)i/(double)length - 1.0;
|
||||
win[i] = Izero(alpha*sqrt(1.0-tmp*tmp))*IBeta;
|
||||
sum += win[i];
|
||||
}
|
||||
|
||||
sum = 1.0/sum;
|
||||
tmp = 0.0;
|
||||
|
||||
/* calculate lower half of window */
|
||||
for(i=0; i<(length>>1); i++) {
|
||||
tmp += win[i];
|
||||
win[i] = sqrt(tmp*sum);
|
||||
}
|
||||
}
|
||||
|
||||
static void MDCT( FFT_Tables *fft_tables, double *data, int N )
|
||||
{
|
||||
double *xi, *xr;
|
||||
double tempr, tempi, c, s, cold, cfreq, sfreq; /* temps for pre and post twiddle */
|
||||
double freq = TWOPI / N;
|
||||
double cosfreq8, sinfreq8;
|
||||
int i, n;
|
||||
|
||||
xi = (double*)AllocMemory((N >> 2)*sizeof(double));
|
||||
xr = (double*)AllocMemory((N >> 2)*sizeof(double));
|
||||
|
||||
/* prepare for recurrence relation in pre-twiddle */
|
||||
cfreq = cos (freq);
|
||||
sfreq = sin (freq);
|
||||
cosfreq8 = cos (freq * 0.125);
|
||||
sinfreq8 = sin (freq * 0.125);
|
||||
c = cosfreq8;
|
||||
s = sinfreq8;
|
||||
|
||||
for (i = 0; i < (N >> 2); i++) {
|
||||
/* calculate real and imaginary parts of g(n) or G(p) */
|
||||
n = (N >> 1) - 1 - 2 * i;
|
||||
|
||||
if (i < (N >> 3))
|
||||
tempr = data [(N >> 2) + n] + data [N + (N >> 2) - 1 - n]; /* use second form of e(n) for n = N / 2 - 1 - 2i */
|
||||
else
|
||||
tempr = data [(N >> 2) + n] - data [(N >> 2) - 1 - n]; /* use first form of e(n) for n = N / 2 - 1 - 2i */
|
||||
|
||||
n = 2 * i;
|
||||
if (i < (N >> 3))
|
||||
tempi = data [(N >> 2) + n] - data [(N >> 2) - 1 - n]; /* use first form of e(n) for n=2i */
|
||||
else
|
||||
tempi = data [(N >> 2) + n] + data [N + (N >> 2) - 1 - n]; /* use second form of e(n) for n=2i*/
|
||||
|
||||
/* calculate pre-twiddled FFT input */
|
||||
xr[i] = tempr * c + tempi * s;
|
||||
xi[i] = tempi * c - tempr * s;
|
||||
|
||||
/* use recurrence to prepare cosine and sine for next value of i */
|
||||
cold = c;
|
||||
c = c * cfreq - s * sfreq;
|
||||
s = s * cfreq + cold * sfreq;
|
||||
}
|
||||
|
||||
/* Perform in-place complex FFT of length N/4 */
|
||||
switch (N) {
|
||||
case BLOCK_LEN_SHORT * 2:
|
||||
fft( fft_tables, xr, xi, 6);
|
||||
break;
|
||||
case BLOCK_LEN_LONG * 2:
|
||||
fft( fft_tables, xr, xi, 9);
|
||||
}
|
||||
|
||||
/* prepare for recurrence relations in post-twiddle */
|
||||
c = cosfreq8;
|
||||
s = sinfreq8;
|
||||
|
||||
/* post-twiddle FFT output and then get output data */
|
||||
for (i = 0; i < (N >> 2); i++) {
|
||||
/* get post-twiddled FFT output */
|
||||
tempr = 2. * (xr[i] * c + xi[i] * s);
|
||||
tempi = 2. * (xi[i] * c - xr[i] * s);
|
||||
|
||||
/* fill in output values */
|
||||
data [2 * i] = -tempr; /* first half even */
|
||||
data [(N >> 1) - 1 - 2 * i] = tempi; /* first half odd */
|
||||
data [(N >> 1) + 2 * i] = -tempi; /* second half even */
|
||||
data [N - 1 - 2 * i] = tempr; /* second half odd */
|
||||
|
||||
/* use recurrence to prepare cosine and sine for next value of i */
|
||||
cold = c;
|
||||
c = c * cfreq - s * sfreq;
|
||||
s = s * cfreq + cold * sfreq;
|
||||
}
|
||||
|
||||
if (xr) FreeMemory(xr);
|
||||
if (xi) FreeMemory(xi);
|
||||
}
|
||||
|
||||
static void IMDCT( FFT_Tables *fft_tables, double *data, int N)
|
||||
{
|
||||
double *xi, *xr;
|
||||
double tempr, tempi, c, s, cold, cfreq, sfreq; /* temps for pre and post twiddle */
|
||||
double freq = 2.0 * M_PI / N;
|
||||
double fac, cosfreq8, sinfreq8;
|
||||
int i;
|
||||
|
||||
xi = (double*)AllocMemory((N >> 2)*sizeof(double));
|
||||
xr = (double*)AllocMemory((N >> 2)*sizeof(double));
|
||||
|
||||
/* Choosing to allocate 2/N factor to Inverse Xform! */
|
||||
fac = 2. / N; /* remaining 2/N from 4/N IFFT factor */
|
||||
|
||||
/* prepare for recurrence relation in pre-twiddle */
|
||||
cfreq = cos (freq);
|
||||
sfreq = sin (freq);
|
||||
cosfreq8 = cos (freq * 0.125);
|
||||
sinfreq8 = sin (freq * 0.125);
|
||||
c = cosfreq8;
|
||||
s = sinfreq8;
|
||||
|
||||
for (i = 0; i < (N >> 2); i++) {
|
||||
/* calculate real and imaginary parts of g(n) or G(p) */
|
||||
tempr = -data[2 * i];
|
||||
tempi = data[(N >> 1) - 1 - 2 * i];
|
||||
|
||||
/* calculate pre-twiddled FFT input */
|
||||
xr[i] = tempr * c - tempi * s;
|
||||
xi[i] = tempi * c + tempr * s;
|
||||
|
||||
/* use recurrence to prepare cosine and sine for next value of i */
|
||||
cold = c;
|
||||
c = c * cfreq - s * sfreq;
|
||||
s = s * cfreq + cold * sfreq;
|
||||
}
|
||||
|
||||
/* Perform in-place complex IFFT of length N/4 */
|
||||
switch (N) {
|
||||
case BLOCK_LEN_SHORT * 2:
|
||||
ffti( fft_tables, xr, xi, 6);
|
||||
break;
|
||||
case BLOCK_LEN_LONG * 2:
|
||||
ffti( fft_tables, xr, xi, 9);
|
||||
}
|
||||
|
||||
/* prepare for recurrence relations in post-twiddle */
|
||||
c = cosfreq8;
|
||||
s = sinfreq8;
|
||||
|
||||
/* post-twiddle FFT output and then get output data */
|
||||
for (i = 0; i < (N >> 2); i++) {
|
||||
|
||||
/* get post-twiddled FFT output */
|
||||
tempr = fac * (xr[i] * c - xi[i] * s);
|
||||
tempi = fac * (xi[i] * c + xr[i] * s);
|
||||
|
||||
/* fill in output values */
|
||||
data [(N >> 1) + (N >> 2) - 1 - 2 * i] = tempr;
|
||||
if (i < (N >> 3))
|
||||
data [(N >> 1) + (N >> 2) + 2 * i] = tempr;
|
||||
else
|
||||
data [2 * i - (N >> 2)] = -tempr;
|
||||
|
||||
data [(N >> 2) + 2 * i] = tempi;
|
||||
if (i < (N >> 3))
|
||||
data [(N >> 2) - 1 - 2 * i] = -tempi;
|
||||
else
|
||||
data [(N >> 2) + N - 1 - 2*i] = tempi;
|
||||
|
||||
/* use recurrence to prepare cosine and sine for next value of i */
|
||||
cold = c;
|
||||
c = c * cfreq - s * sfreq;
|
||||
s = s * cfreq + cold * sfreq;
|
||||
}
|
||||
|
||||
if (xr) FreeMemory(xr);
|
||||
if (xi) FreeMemory(xi);
|
||||
}
|
71
external/libfaac/libfaac/filtbank.h
vendored
Normal file
71
external/libfaac/libfaac/filtbank.h
vendored
Normal file
|
@ -0,0 +1,71 @@
|
|||
/*
|
||||
* FAAC - Freeware Advanced Audio Coder
|
||||
* Copyright (C) 2001 Menno Bakker
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
* $Id: filtbank.h,v 1.11 2005/02/02 07:51:49 sur Exp $
|
||||
*/
|
||||
|
||||
#ifndef FILTBANK_H
|
||||
#define FILTBANK_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif /* __cplusplus */
|
||||
|
||||
#include "frame.h"
|
||||
|
||||
#ifdef DRM
|
||||
#define NFLAT_LS (( BLOCK_LEN_LONG - BLOCK_LEN_SHORT ) / 2)
|
||||
#else
|
||||
#define NFLAT_LS 448
|
||||
#endif
|
||||
|
||||
#define MOVERLAPPED 0
|
||||
#define MNON_OVERLAPPED 1
|
||||
|
||||
|
||||
#define SINE_WINDOW 0
|
||||
#define KBD_WINDOW 1
|
||||
|
||||
void FilterBankInit ( faacEncHandle hEncoder );
|
||||
|
||||
void FilterBankEnd ( faacEncHandle hEncoder );
|
||||
|
||||
void FilterBank( faacEncHandle hEncoder,
|
||||
CoderInfo *coderInfo,
|
||||
double *p_in_data,
|
||||
double *p_out_mdct,
|
||||
double *p_overlap,
|
||||
int overlap_select );
|
||||
|
||||
void IFilterBank( faacEncHandle hEncoder,
|
||||
CoderInfo *coderInfo,
|
||||
double *p_in_data,
|
||||
double *p_out_mdct,
|
||||
double *p_overlap,
|
||||
int overlap_select );
|
||||
|
||||
void specFilter( double *freqBuff,
|
||||
int sampleRate,
|
||||
int lowpassFreq,
|
||||
int specLen );
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif /* __cplusplus */
|
||||
|
||||
#endif /* FILTBANK_H */
|
1252
external/libfaac/libfaac/frame.c
vendored
Normal file
1252
external/libfaac/libfaac/frame.c
vendored
Normal file
File diff suppressed because it is too large
Load Diff
160
external/libfaac/libfaac/frame.h
vendored
Normal file
160
external/libfaac/libfaac/frame.h
vendored
Normal file
|
@ -0,0 +1,160 @@
|
|||
/*
|
||||
* FAAC - Freeware Advanced Audio Coder
|
||||
* Copyright (C) 2001 Menno Bakker
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
* $Id: frame.h,v 1.30 2009/01/25 18:50:32 menno Exp $
|
||||
*/
|
||||
|
||||
#ifndef FRAME_H
|
||||
#define FRAME_H
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_SYS_TYPES_H
|
||||
# include <sys/types.h>
|
||||
#endif
|
||||
#ifdef HAVE_INTTYPES_H
|
||||
# include <inttypes.h>
|
||||
#endif
|
||||
#ifdef HAVE_STDINT_H
|
||||
# include <stdint.h>
|
||||
#endif
|
||||
|
||||
#ifndef HAVE_INT32_T
|
||||
typedef signed int int32_t;
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif /* __cplusplus */
|
||||
|
||||
#include "coder.h"
|
||||
#include "channels.h"
|
||||
#include "psych.h"
|
||||
#include "aacquant.h"
|
||||
#include "fft.h"
|
||||
|
||||
#if defined(_WIN32) && !defined(__MINGW32__)
|
||||
#ifndef FAACAPI
|
||||
#define FAACAPI __stdcall
|
||||
#endif
|
||||
#else
|
||||
#ifndef FAACAPI
|
||||
#define FAACAPI
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#pragma pack(push, 1)
|
||||
|
||||
typedef struct {
|
||||
psymodel_t *model;
|
||||
char *name;
|
||||
} psymodellist_t;
|
||||
|
||||
#include <faaccfg.h>
|
||||
|
||||
typedef struct {
|
||||
/* number of channels in AAC file */
|
||||
unsigned int numChannels;
|
||||
|
||||
/* samplerate of AAC file */
|
||||
unsigned long sampleRate;
|
||||
unsigned int sampleRateIdx;
|
||||
|
||||
unsigned int usedBytes;
|
||||
|
||||
/* frame number */
|
||||
unsigned int frameNum;
|
||||
unsigned int flushFrame;
|
||||
|
||||
/* Scalefactorband data */
|
||||
SR_INFO *srInfo;
|
||||
|
||||
/* sample buffers of current next and next next frame*/
|
||||
double *sampleBuff[MAX_CHANNELS];
|
||||
double *nextSampleBuff[MAX_CHANNELS];
|
||||
double *next2SampleBuff[MAX_CHANNELS];
|
||||
double *next3SampleBuff[MAX_CHANNELS];
|
||||
double *ltpTimeBuff[MAX_CHANNELS];
|
||||
|
||||
/* Filterbank buffers */
|
||||
double *sin_window_long;
|
||||
double *sin_window_short;
|
||||
double *kbd_window_long;
|
||||
double *kbd_window_short;
|
||||
double *freqBuff[MAX_CHANNELS];
|
||||
double *overlapBuff[MAX_CHANNELS];
|
||||
|
||||
double *msSpectrum[MAX_CHANNELS];
|
||||
|
||||
/* Channel and Coder data for all channels */
|
||||
CoderInfo coderInfo[MAX_CHANNELS];
|
||||
ChannelInfo channelInfo[MAX_CHANNELS];
|
||||
|
||||
/* Psychoacoustics data */
|
||||
PsyInfo psyInfo[MAX_CHANNELS];
|
||||
GlobalPsyInfo gpsyInfo;
|
||||
|
||||
/* Configuration data */
|
||||
faacEncConfiguration config;
|
||||
|
||||
psymodel_t *psymodel;
|
||||
|
||||
/* quantizer specific config */
|
||||
AACQuantCfg aacquantCfg;
|
||||
|
||||
/* FFT Tables */
|
||||
FFT_Tables fft_tables;
|
||||
|
||||
/* output bits difference in average bitrate mode */
|
||||
int bitDiff;
|
||||
} faacEncStruct, *faacEncHandle;
|
||||
|
||||
int FAACAPI faacEncGetVersion(char **faac_id_string,
|
||||
char **faac_copyright_string);
|
||||
|
||||
int FAACAPI faacEncGetDecoderSpecificInfo(faacEncHandle hEncoder,
|
||||
unsigned char** ppBuffer,
|
||||
unsigned long* pSizeOfDecoderSpecificInfo);
|
||||
|
||||
faacEncConfigurationPtr FAACAPI faacEncGetCurrentConfiguration(faacEncHandle hEncoder);
|
||||
int FAACAPI faacEncSetConfiguration (faacEncHandle hEncoder, faacEncConfigurationPtr config);
|
||||
|
||||
faacEncHandle FAACAPI faacEncOpen(unsigned long sampleRate,
|
||||
unsigned int numChannels,
|
||||
unsigned long *inputSamples,
|
||||
unsigned long *maxOutputBytes);
|
||||
|
||||
int FAACAPI faacEncEncode(faacEncHandle hEncoder,
|
||||
int32_t *inputBuffer,
|
||||
unsigned int samplesInput,
|
||||
unsigned char *outputBuffer,
|
||||
unsigned int bufferSize
|
||||
);
|
||||
|
||||
int FAACAPI faacEncClose(faacEncHandle hEncoder);
|
||||
|
||||
|
||||
#pragma pack(pop)
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif /* __cplusplus */
|
||||
|
||||
#endif /* FRAME_H */
|
1226
external/libfaac/libfaac/huffman.c
vendored
Normal file
1226
external/libfaac/libfaac/huffman.c
vendored
Normal file
File diff suppressed because it is too large
Load Diff
93
external/libfaac/libfaac/huffman.h
vendored
Normal file
93
external/libfaac/libfaac/huffman.h
vendored
Normal file
|
@ -0,0 +1,93 @@
|
|||
/***********
|
||||
|
||||
This software module was originally developed by Dolby
|
||||
Laboratories in the course of development of the MPEG-2 AAC/MPEG-4
|
||||
Audio standard ISO/IEC13818-7, 14496-1, 2 and 3. This software module is an implementation of a part
|
||||
of one or more MPEG-2 AAC/MPEG-4 Audio tools as specified by the
|
||||
MPEG-2 aac/MPEG-4 Audio standard. ISO/IEC gives users of the
|
||||
MPEG-2aac/MPEG-4 Audio standards free license to this software module
|
||||
or modifications thereof for use in hardware or software products
|
||||
claiming conformance to the MPEG-2 aac/MPEG-4 Audio standards. Those
|
||||
intending to use this software module in hardware or software products
|
||||
are advised that this use may infringe existing patents. The original
|
||||
developer of this software module, the subsequent
|
||||
editors and their companies, and ISO/IEC have no liability for use of
|
||||
this software module or modifications thereof in an
|
||||
implementation. Copyright is not released for non MPEG-2 aac/MPEG-4
|
||||
Audio conforming products. The original developer retains full right to
|
||||
use the code for the developer's own purpose, assign or donate the code to a
|
||||
third party and to inhibit third party from using the code for non
|
||||
MPEG-2 aac/MPEG-4 Audio conforming products. This copyright notice
|
||||
must be included in all copies or derivative works. Copyright 1996.
|
||||
|
||||
***********/
|
||||
/*
|
||||
* $Id: huffman.h,v 1.6 2004/07/12 08:46:43 corrados Exp $
|
||||
*/
|
||||
|
||||
#ifndef HUFFMAN_H
|
||||
#define HUFFMAN_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif /* __cplusplus */
|
||||
|
||||
#include "bitstream.h"
|
||||
#include "coder.h"
|
||||
|
||||
/* Huffman tables */
|
||||
#define MAXINDEX 289
|
||||
#define NUMINTAB 2
|
||||
#define FIRSTINTAB 0
|
||||
#define LASTINTAB 1
|
||||
|
||||
#define INTENSITY_HCB 15
|
||||
#define INTENSITY_HCB2 14
|
||||
|
||||
|
||||
#define ABS(A) ((A) < 0 ? (-A) : (A))
|
||||
|
||||
#include "frame.h"
|
||||
|
||||
void HuffmanInit(CoderInfo *coderInfo, unsigned int numChannels);
|
||||
void HuffmanEnd(CoderInfo *coderInfo, unsigned int numChannels);
|
||||
|
||||
int BitSearch(CoderInfo *coderInfo,
|
||||
int *quant);
|
||||
|
||||
int NoiselessBitCount(CoderInfo *coderInfo,
|
||||
int *quant,
|
||||
int hop,
|
||||
int min_book_choice[112][3]);
|
||||
|
||||
static int CalculateEscSequence(int input, int *len_esc_sequence);
|
||||
|
||||
int CalcBits(CoderInfo *coderInfo,
|
||||
int book,
|
||||
int *quant,
|
||||
int offset,
|
||||
int length);
|
||||
|
||||
int OutputBits(CoderInfo *coderInfo,
|
||||
#ifdef DRM
|
||||
int *book, /* we need to change book for VCB11 */
|
||||
#else
|
||||
int book,
|
||||
#endif
|
||||
int *quant,
|
||||
int offset,
|
||||
int length);
|
||||
|
||||
int SortBookNumbers(CoderInfo *coderInfo,
|
||||
BitStream *bitStream,
|
||||
int writeFlag);
|
||||
|
||||
int WriteScalefactors(CoderInfo *coderInfo,
|
||||
BitStream *bitStream,
|
||||
int writeFlag);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif /* __cplusplus */
|
||||
|
||||
#endif /* HUFFMAN_H */
|
331
external/libfaac/libfaac/hufftab.h
vendored
Normal file
331
external/libfaac/libfaac/hufftab.h
vendored
Normal file
|
@ -0,0 +1,331 @@
|
|||
/*
|
||||
* FAAC - Freeware Advanced Audio Coder
|
||||
* Copyright (C) 2001 Menno Bakker
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
* $Id: hufftab.h,v 1.3 2001/06/08 18:01:09 menno Exp $
|
||||
*/
|
||||
|
||||
unsigned short huff1[][2] = {
|
||||
{ 11, 2040},
|
||||
{ 9, 497},{ 11, 2045},{ 10, 1013},{ 7, 104},{ 10, 1008},
|
||||
{ 11, 2039},{ 9, 492},{ 11, 2037},{ 10, 1009},{ 7, 114},
|
||||
{ 10, 1012},{ 7, 116},{ 5, 17},{ 7, 118},{ 9, 491},
|
||||
{ 7, 108},{ 10, 1014},{ 11, 2044},{ 9, 481},{ 11, 2033},
|
||||
{ 9, 496},{ 7, 97},{ 9, 502},{ 11, 2034},{ 9, 490},
|
||||
{ 11, 2043},{ 9, 498},{ 7, 105},{ 9, 493},{ 7, 119},
|
||||
{ 5, 23},{ 7, 111},{ 9, 486},{ 7, 100},{ 9, 485},
|
||||
{ 7, 103},{ 5, 21},{ 7, 98},{ 5, 18},{ 1, 0},
|
||||
{ 5, 20},{ 7, 101},{ 5, 22},{ 7, 109},{ 9, 489},
|
||||
{ 7, 99},{ 9, 484},{ 7, 107},{ 5, 19},{ 7, 113},
|
||||
{ 9, 483},{ 7, 112},{ 9, 499},{ 11, 2046},{ 9, 487},
|
||||
{ 11, 2035},{ 9, 495},{ 7, 96},{ 9, 494},{ 11, 2032},
|
||||
{ 9, 482},{ 11, 2042},{ 10, 1011},{ 7, 106},{ 9, 488},
|
||||
{ 7, 117},{ 5, 16},{ 7, 115},{ 9, 500},{ 7, 110},
|
||||
{ 10, 1015},{ 11, 2038},{ 9, 480},{ 11, 2041},{ 10, 1010},
|
||||
{ 7, 102},{ 9, 501},{ 11, 2047},{ 9, 503},{ 11, 2036}
|
||||
};
|
||||
unsigned short huff2[][2] = {
|
||||
{ 9, 499},
|
||||
{ 7, 111},{ 9, 509},{ 8, 235},{ 6, 35},{ 8, 234},
|
||||
{ 9, 503},{ 8, 232},{ 9, 506},{ 8, 242},{ 6, 45},
|
||||
{ 7, 112},{ 6, 32},{ 5, 6},{ 6, 43},{ 7, 110},
|
||||
{ 6, 40},{ 8, 233},{ 9, 505},{ 7, 102},{ 8, 248},
|
||||
{ 8, 231},{ 6, 27},{ 8, 241},{ 9, 500},{ 7, 107},
|
||||
{ 9, 501},{ 8, 236},{ 6, 42},{ 7, 108},{ 6, 44},
|
||||
{ 5, 10},{ 6, 39},{ 7, 103},{ 6, 26},{ 8, 245},
|
||||
{ 6, 36},{ 5, 8},{ 6, 31},{ 5, 9},{ 3, 0},
|
||||
{ 5, 7},{ 6, 29},{ 5, 11},{ 6, 48},{ 8, 239},
|
||||
{ 6, 28},{ 7, 100},{ 6, 30},{ 5, 12},{ 6, 41},
|
||||
{ 8, 243},{ 6, 47},{ 8, 240},{ 9, 508},{ 7, 113},
|
||||
{ 9, 498},{ 8, 244},{ 6, 33},{ 8, 230},{ 8, 247},
|
||||
{ 7, 104},{ 9, 504},{ 8, 238},{ 6, 34},{ 7, 101},
|
||||
{ 6, 49},{ 4, 2},{ 6, 38},{ 8, 237},{ 6, 37},
|
||||
{ 7, 106},{ 9, 507},{ 7, 114},{ 9, 510},{ 7, 105},
|
||||
{ 6, 46},{ 8, 246},{ 9, 511},{ 7, 109},{ 9, 502}
|
||||
};
|
||||
unsigned short huff3[][2] = {
|
||||
{ 1, 0},
|
||||
{ 4, 9},{ 8, 239},{ 4, 11},{ 5, 25},{ 8, 240},
|
||||
{ 9, 491},{ 9, 486},{ 10, 1010},{ 4, 10},{ 6, 53},
|
||||
{ 9, 495},{ 6, 52},{ 6, 55},{ 9, 489},{ 9, 493},
|
||||
{ 9, 487},{ 10, 1011},{ 9, 494},{ 10, 1005},{ 13, 8186},
|
||||
{ 9, 492},{ 9, 498},{ 11, 2041},{ 11, 2040},{ 10, 1016},
|
||||
{ 12, 4088},{ 4, 8},{ 6, 56},{ 10, 1014},{ 6, 54},
|
||||
{ 7, 117},{ 10, 1009},{ 10, 1003},{ 10, 1004},{ 12, 4084},
|
||||
{ 5, 24},{ 7, 118},{ 11, 2036},{ 6, 57},{ 7, 116},
|
||||
{ 10, 1007},{ 9, 499},{ 9, 500},{ 11, 2038},{ 9, 488},
|
||||
{ 10, 1002},{ 13, 8188},{ 8, 242},{ 9, 497},{ 12, 4091},
|
||||
{ 10, 1013},{ 11, 2035},{ 12, 4092},{ 8, 238},{ 10, 1015},
|
||||
{ 15, 32766},{ 9, 496},{ 11, 2037},{ 15, 32765},{ 13, 8187},
|
||||
{ 14, 16378},{ 16, 65535},{ 8, 241},{ 10, 1008},{ 14, 16380},
|
||||
{ 9, 490},{ 10, 1006},{ 14, 16379},{ 12, 4086},{ 12, 4090},
|
||||
{ 15, 32764},{ 11, 2034},{ 12, 4085},{ 16, 65534},{ 10, 1012},
|
||||
{ 11, 2039},{ 15, 32763},{ 12, 4087},{ 12, 4089},{ 15, 32762}
|
||||
};
|
||||
unsigned short huff4[][2] = {
|
||||
{ 4, 7},
|
||||
{ 5, 22},{ 8, 246},{ 5, 24},{ 4, 8},{ 8, 239},
|
||||
{ 9, 495},{ 8, 243},{ 11, 2040},{ 5, 25},{ 5, 23},
|
||||
{ 8, 237},{ 5, 21},{ 4, 1},{ 8, 226},{ 8, 240},
|
||||
{ 7, 112},{ 10, 1008},{ 9, 494},{ 8, 241},{ 11, 2042},
|
||||
{ 8, 238},{ 8, 228},{ 10, 1010},{ 11, 2038},{ 10, 1007},
|
||||
{ 11, 2045},{ 4, 5},{ 5, 20},{ 8, 242},{ 4, 9},
|
||||
{ 4, 4},{ 8, 229},{ 8, 244},{ 8, 232},{ 10, 1012},
|
||||
{ 4, 6},{ 4, 2},{ 8, 231},{ 4, 3},{ 4, 0},
|
||||
{ 7, 107},{ 8, 227},{ 7, 105},{ 9, 499},{ 8, 235},
|
||||
{ 8, 230},{ 10, 1014},{ 7, 110},{ 7, 106},{ 9, 500},
|
||||
{ 10, 1004},{ 9, 496},{ 10, 1017},{ 8, 245},{ 8, 236},
|
||||
{ 11, 2043},{ 8, 234},{ 7, 111},{ 10, 1015},{ 11, 2041},
|
||||
{ 10, 1011},{ 12, 4095},{ 8, 233},{ 7, 109},{ 10, 1016},
|
||||
{ 7, 108},{ 7, 104},{ 9, 501},{ 10, 1006},{ 9, 498},
|
||||
{ 11, 2036},{ 11, 2039},{ 10, 1009},{ 12, 4094},{ 10, 1005},
|
||||
{ 9, 497},{ 11, 2037},{ 11, 2046},{ 10, 1013},{ 11, 2044}
|
||||
};
|
||||
unsigned short huff5[][2] = {
|
||||
{ 13, 8191},
|
||||
{ 12, 4087},{ 11, 2036},{ 11, 2024},{ 10, 1009},{ 11, 2030},
|
||||
{ 11, 2041},{ 12, 4088},{ 13, 8189},{ 12, 4093},{ 11, 2033},
|
||||
{ 10, 1000},{ 9, 488},{ 8, 240},{ 9, 492},{ 10, 1006},
|
||||
{ 11, 2034},{ 12, 4090},{ 12, 4084},{ 10, 1007},{ 9, 498},
|
||||
{ 8, 232},{ 7, 112},{ 8, 236},{ 9, 496},{ 10, 1002},
|
||||
{ 11, 2035},{ 11, 2027},{ 9, 491},{ 8, 234},{ 5, 26},
|
||||
{ 4, 8},{ 5, 25},{ 8, 238},{ 9, 495},{ 11, 2029},
|
||||
{ 10, 1008},{ 8, 242},{ 7, 115},{ 4, 11},{ 1, 0},
|
||||
{ 4, 10},{ 7, 113},{ 8, 243},{ 11, 2025},{ 11, 2031},
|
||||
{ 9, 494},{ 8, 239},{ 5, 24},{ 4, 9},{ 5, 27},
|
||||
{ 8, 235},{ 9, 489},{ 11, 2028},{ 11, 2038},{ 10, 1003},
|
||||
{ 9, 499},{ 8, 237},{ 7, 114},{ 8, 233},{ 9, 497},
|
||||
{ 10, 1005},{ 11, 2039},{ 12, 4086},{ 11, 2032},{ 10, 1001},
|
||||
{ 9, 493},{ 8, 241},{ 9, 490},{ 10, 1004},{ 11, 2040},
|
||||
{ 12, 4089},{ 13, 8188},{ 12, 4092},{ 12, 4085},{ 11, 2026},
|
||||
{ 10, 1011},{ 10, 1010},{ 11, 2037},{ 12, 4091},{ 13, 8190}
|
||||
};
|
||||
unsigned short huff6[][2] = {
|
||||
{ 11, 2046},
|
||||
{ 10, 1021},{ 9, 497},{ 9, 491},{ 9, 500},{ 9, 490},
|
||||
{ 9, 496},{ 10, 1020},{ 11, 2045},{ 10, 1014},{ 9, 485},
|
||||
{ 8, 234},{ 7, 108},{ 7, 113},{ 7, 104},{ 8, 240},
|
||||
{ 9, 486},{ 10, 1015},{ 9, 499},{ 8, 239},{ 6, 50},
|
||||
{ 6, 39},{ 6, 40},{ 6, 38},{ 6, 49},{ 8, 235},
|
||||
{ 9, 503},{ 9, 488},{ 7, 111},{ 6, 46},{ 4, 8},
|
||||
{ 4, 4},{ 4, 6},{ 6, 41},{ 7, 107},{ 9, 494},
|
||||
{ 9, 495},{ 7, 114},{ 6, 45},{ 4, 2},{ 4, 0},
|
||||
{ 4, 3},{ 6, 47},{ 7, 115},{ 9, 506},{ 9, 487},
|
||||
{ 7, 110},{ 6, 43},{ 4, 7},{ 4, 1},{ 4, 5},
|
||||
{ 6, 44},{ 7, 109},{ 9, 492},{ 9, 505},{ 8, 238},
|
||||
{ 6, 48},{ 6, 36},{ 6, 42},{ 6, 37},{ 6, 51},
|
||||
{ 8, 236},{ 9, 498},{ 10, 1016},{ 9, 484},{ 8, 237},
|
||||
{ 7, 106},{ 7, 112},{ 7, 105},{ 7, 116},{ 8, 241},
|
||||
{ 10, 1018},{ 11, 2047},{ 10, 1017},{ 9, 502},{ 9, 493},
|
||||
{ 9, 504},{ 9, 489},{ 9, 501},{ 10, 1019},{ 11, 2044}
|
||||
};
|
||||
unsigned short huff7[][2] = {
|
||||
{ 1, 0},
|
||||
{ 3, 5},{ 6, 55},{ 7, 116},{ 8, 242},{ 9, 491},
|
||||
{ 10, 1005},{ 11, 2039},{ 3, 4},{ 4, 12},{ 6, 53},
|
||||
{ 7, 113},{ 8, 236},{ 8, 238},{ 9, 494},{ 9, 501},
|
||||
{ 6, 54},{ 6, 52},{ 7, 114},{ 8, 234},{ 8, 241},
|
||||
{ 9, 489},{ 9, 499},{ 10, 1013},{ 7, 115},{ 7, 112},
|
||||
{ 8, 235},{ 8, 240},{ 9, 497},{ 9, 496},{ 10, 1004},
|
||||
{ 10, 1018},{ 8, 243},{ 8, 237},{ 9, 488},{ 9, 495},
|
||||
{ 10, 1007},{ 10, 1009},{ 10, 1017},{ 11, 2043},{ 9, 493},
|
||||
{ 8, 239},{ 9, 490},{ 9, 498},{ 10, 1011},{ 10, 1016},
|
||||
{ 11, 2041},{ 11, 2044},{ 10, 1006},{ 9, 492},{ 9, 500},
|
||||
{ 10, 1012},{ 10, 1015},{ 11, 2040},{ 12, 4093},{ 12, 4094},
|
||||
{ 11, 2038},{ 10, 1008},{ 10, 1010},{ 10, 1014},{ 11, 2042},
|
||||
{ 11, 2045},{ 12, 4092},{ 12, 4095}
|
||||
};
|
||||
unsigned short huff8[][2] = {
|
||||
{ 5, 14},
|
||||
{ 4, 5},{ 5, 16},{ 6, 48},{ 7, 111},{ 8, 241},
|
||||
{ 9, 506},{ 10, 1022},{ 4, 3},{ 3, 0},{ 4, 4},
|
||||
{ 5, 18},{ 6, 44},{ 7, 106},{ 7, 117},{ 8, 248},
|
||||
{ 5, 15},{ 4, 2},{ 4, 6},{ 5, 20},{ 6, 46},
|
||||
{ 7, 105},{ 7, 114},{ 8, 245},{ 6, 47},{ 5, 17},
|
||||
{ 5, 19},{ 6, 42},{ 6, 50},{ 7, 108},{ 8, 236},
|
||||
{ 8, 250},{ 7, 113},{ 6, 43},{ 6, 45},{ 6, 49},
|
||||
{ 7, 109},{ 7, 112},{ 8, 242},{ 9, 505},{ 8, 239},
|
||||
{ 7, 104},{ 6, 51},{ 7, 107},{ 7, 110},{ 8, 238},
|
||||
{ 8, 249},{ 10, 1020},{ 9, 504},{ 7, 116},{ 7, 115},
|
||||
{ 8, 237},{ 8, 240},{ 8, 246},{ 9, 502},{ 9, 509},
|
||||
{ 10, 1021},{ 8, 243},{ 8, 244},{ 8, 247},{ 9, 503},
|
||||
{ 9, 507},{ 9, 508},{ 10, 1023}
|
||||
};
|
||||
unsigned short huff9[][2] = {
|
||||
{ 1, 0},
|
||||
{ 3, 5},{ 6, 55},{ 8, 231},{ 9, 478},{ 10, 974},
|
||||
{ 10, 985},{ 11, 1992},{ 11, 1997},{ 12, 4040},{ 12, 4061},
|
||||
{ 13, 8164},{ 13, 8172},{ 3, 4},{ 4, 12},{ 6, 53},
|
||||
{ 7, 114},{ 8, 234},{ 8, 237},{ 9, 482},{ 10, 977},
|
||||
{ 10, 979},{ 10, 992},{ 11, 2008},{ 12, 4047},{ 12, 4053},
|
||||
{ 6, 54},{ 6, 52},{ 7, 113},{ 8, 232},{ 8, 236},
|
||||
{ 9, 481},{ 10, 975},{ 10, 989},{ 10, 987},{ 11, 2000},
|
||||
{ 12, 4039},{ 12, 4052},{ 12, 4068},{ 8, 230},{ 7, 112},
|
||||
{ 8, 233},{ 9, 477},{ 9, 483},{ 10, 978},{ 10, 988},
|
||||
{ 11, 1996},{ 11, 1994},{ 11, 2014},{ 12, 4056},{ 12, 4074},
|
||||
{ 13, 8155},{ 9, 479},{ 8, 235},{ 9, 476},{ 9, 486},
|
||||
{ 10, 981},{ 10, 990},{ 11, 1995},{ 11, 2013},{ 11, 2012},
|
||||
{ 12, 4045},{ 12, 4066},{ 12, 4071},{ 13, 8161},{ 10, 976},
|
||||
{ 9, 480},{ 9, 484},{ 10, 982},{ 11, 1989},{ 11, 2001},
|
||||
{ 11, 2011},{ 12, 4050},{ 11, 2016},{ 12, 4057},{ 12, 4075},
|
||||
{ 13, 8163},{ 13, 8169},{ 11, 1988},{ 9, 485},{ 10, 983},
|
||||
{ 11, 1990},{ 11, 1999},{ 11, 2010},{ 12, 4043},{ 12, 4058},
|
||||
{ 12, 4067},{ 12, 4073},{ 13, 8166},{ 13, 8179},{ 13, 8183},
|
||||
{ 11, 2003},{ 10, 984},{ 10, 993},{ 11, 2004},{ 11, 2009},
|
||||
{ 12, 4051},{ 12, 4062},{ 13, 8157},{ 13, 8153},{ 13, 8162},
|
||||
{ 13, 8170},{ 13, 8177},{ 13, 8182},{ 11, 2002},{ 10, 980},
|
||||
{ 10, 986},{ 11, 1991},{ 11, 2007},{ 11, 2018},{ 12, 4046},
|
||||
{ 12, 4059},{ 13, 8152},{ 13, 8174},{ 14, 16368},{ 13, 8180},
|
||||
{ 14, 16370},{ 11, 2017},{ 10, 991},{ 11, 1993},{ 11, 2006},
|
||||
{ 12, 4042},{ 12, 4048},{ 12, 4069},{ 12, 4070},{ 13, 8171},
|
||||
{ 13, 8175},{ 14, 16371},{ 14, 16372},{ 14, 16373},{ 12, 4064},
|
||||
{ 11, 1998},{ 11, 2005},{ 12, 4038},{ 12, 4049},{ 12, 4065},
|
||||
{ 13, 8160},{ 13, 8168},{ 13, 8176},{ 14, 16369},{ 14, 16376},
|
||||
{ 14, 16374},{ 15, 32764},{ 12, 4072},{ 11, 2015},{ 12, 4041},
|
||||
{ 12, 4055},{ 12, 4060},{ 13, 8156},{ 13, 8159},{ 13, 8173},
|
||||
{ 13, 8181},{ 14, 16377},{ 14, 16379},{ 15, 32765},{ 15, 32766},
|
||||
{ 13, 8167},{ 12, 4044},{ 12, 4054},{ 12, 4063},{ 13, 8158},
|
||||
{ 13, 8154},{ 13, 8165},{ 13, 8178},{ 14, 16378},{ 14, 16375},
|
||||
{ 14, 16380},{ 14, 16381},{ 15, 32767}
|
||||
};
|
||||
unsigned short huff10[][2] = {
|
||||
{ 6, 34},
|
||||
{ 5, 8},{ 6, 29},{ 6, 38},{ 7, 95},{ 8, 211},
|
||||
{ 9, 463},{ 10, 976},{ 10, 983},{ 10, 1005},{ 11, 2032},
|
||||
{ 11, 2038},{ 12, 4093},{ 5, 7},{ 4, 0},{ 4, 1},
|
||||
{ 5, 9},{ 6, 32},{ 7, 84},{ 7, 96},{ 8, 213},
|
||||
{ 8, 220},{ 9, 468},{ 10, 973},{ 10, 990},{ 11, 2023},
|
||||
{ 6, 28},{ 4, 2},{ 5, 6},{ 5, 12},{ 6, 30},
|
||||
{ 6, 40},{ 7, 91},{ 8, 205},{ 8, 217},{ 9, 462},
|
||||
{ 9, 476},{ 10, 985},{ 10, 1009},{ 6, 37},{ 5, 11},
|
||||
{ 5, 10},{ 5, 13},{ 6, 36},{ 7, 87},{ 7, 97},
|
||||
{ 8, 204},{ 8, 221},{ 9, 460},{ 9, 478},{ 10, 979},
|
||||
{ 10, 999},{ 7, 93},{ 6, 33},{ 6, 31},{ 6, 35},
|
||||
{ 6, 39},{ 7, 89},{ 7, 100},{ 8, 216},{ 8, 223},
|
||||
{ 9, 466},{ 9, 482},{ 10, 989},{ 10, 1006},{ 8, 209},
|
||||
{ 7, 85},{ 6, 41},{ 7, 86},{ 7, 88},{ 7, 98},
|
||||
{ 8, 206},{ 8, 224},{ 8, 226},{ 9, 474},{ 10, 980},
|
||||
{ 10, 995},{ 11, 2027},{ 9, 457},{ 7, 94},{ 7, 90},
|
||||
{ 7, 92},{ 7, 99},{ 8, 202},{ 8, 218},{ 9, 455},
|
||||
{ 9, 458},{ 9, 480},{ 10, 987},{ 10, 1000},{ 11, 2028},
|
||||
{ 9, 483},{ 8, 210},{ 8, 203},{ 8, 208},{ 8, 215},
|
||||
{ 8, 219},{ 9, 454},{ 9, 469},{ 9, 472},{ 10, 970},
|
||||
{ 10, 986},{ 11, 2026},{ 11, 2033},{ 9, 481},{ 8, 212},
|
||||
{ 8, 207},{ 8, 214},{ 8, 222},{ 8, 225},{ 9, 464},
|
||||
{ 9, 470},{ 10, 977},{ 10, 981},{ 10, 1010},{ 11, 2030},
|
||||
{ 11, 2043},{ 10, 1001},{ 9, 461},{ 9, 456},{ 9, 459},
|
||||
{ 9, 465},{ 9, 471},{ 9, 479},{ 10, 975},{ 10, 992},
|
||||
{ 10, 1007},{ 11, 2022},{ 11, 2040},{ 12, 4090},{ 10, 1003},
|
||||
{ 9, 477},{ 9, 467},{ 9, 473},{ 9, 475},{ 10, 978},
|
||||
{ 10, 972},{ 10, 988},{ 10, 1002},{ 11, 2029},{ 11, 2035},
|
||||
{ 11, 2041},{ 12, 4089},{ 11, 2034},{ 10, 974},{ 9, 484},
|
||||
{ 10, 971},{ 10, 984},{ 10, 982},{ 10, 994},{ 10, 997},
|
||||
{ 11, 2024},{ 11, 2036},{ 11, 2037},{ 11, 2039},{ 12, 4091},
|
||||
{ 11, 2042},{ 10, 1004},{ 10, 991},{ 10, 993},{ 10, 996},
|
||||
{ 10, 998},{ 10, 1008},{ 11, 2025},{ 11, 2031},{ 12, 4088},
|
||||
{ 12, 4094},{ 12, 4092},{ 12, 4095}
|
||||
};
|
||||
unsigned short huff11[][2] = {
|
||||
{ 4, 0},
|
||||
{ 5, 6},{ 6, 25},{ 7, 61},{ 8, 156},{ 8, 198},
|
||||
{ 9, 423},{ 10, 912},{ 10, 962},{ 10, 991},{ 11, 2022},
|
||||
{ 11, 2035},{ 12, 4091},{ 11, 2028},{ 12, 4090},{ 12, 4094},
|
||||
{ 10, 910},{ 5, 5},{ 4, 1},{ 5, 8},{ 6, 20},
|
||||
{ 7, 55},{ 7, 66},{ 8, 146},{ 8, 175},{ 9, 401},
|
||||
{ 9, 421},{ 9, 437},{ 10, 926},{ 10, 960},{ 10, 930},
|
||||
{ 10, 973},{ 11, 2006},{ 8, 174},{ 6, 23},{ 5, 7},
|
||||
{ 5, 9},{ 6, 24},{ 7, 57},{ 7, 64},{ 8, 142},
|
||||
{ 8, 163},{ 8, 184},{ 9, 409},{ 9, 428},{ 9, 449},
|
||||
{ 10, 945},{ 10, 918},{ 10, 958},{ 10, 970},{ 8, 157},
|
||||
{ 7, 60},{ 6, 21},{ 6, 22},{ 6, 26},{ 7, 59},
|
||||
{ 7, 68},{ 8, 145},{ 8, 165},{ 8, 190},{ 9, 406},
|
||||
{ 9, 430},{ 9, 441},{ 10, 929},{ 10, 913},{ 10, 933},
|
||||
{ 10, 981},{ 8, 148},{ 8, 154},{ 7, 54},{ 7, 56},
|
||||
{ 7, 58},{ 7, 65},{ 8, 140},{ 8, 155},{ 8, 176},
|
||||
{ 8, 195},{ 9, 414},{ 9, 427},{ 9, 444},{ 10, 927},
|
||||
{ 10, 911},{ 10, 937},{ 10, 975},{ 8, 147},{ 8, 191},
|
||||
{ 7, 62},{ 7, 63},{ 7, 67},{ 7, 69},{ 8, 158},
|
||||
{ 8, 167},{ 8, 185},{ 9, 404},{ 9, 418},{ 9, 442},
|
||||
{ 9, 451},{ 10, 934},{ 10, 935},{ 10, 955},{ 10, 980},
|
||||
{ 8, 159},{ 9, 416},{ 8, 143},{ 8, 141},{ 8, 144},
|
||||
{ 8, 152},{ 8, 166},{ 8, 182},{ 8, 196},{ 9, 415},
|
||||
{ 9, 431},{ 9, 447},{ 10, 921},{ 10, 959},{ 10, 948},
|
||||
{ 10, 969},{ 10, 999},{ 8, 168},{ 9, 438},{ 8, 171},
|
||||
{ 8, 164},{ 8, 170},{ 8, 178},{ 8, 194},{ 8, 197},
|
||||
{ 9, 408},{ 9, 420},{ 9, 440},{ 10, 908},{ 10, 932},
|
||||
{ 10, 964},{ 10, 966},{ 10, 989},{ 10, 1000},{ 8, 173},
|
||||
{ 10, 943},{ 9, 402},{ 8, 189},{ 8, 188},{ 9, 398},
|
||||
{ 9, 407},{ 9, 410},{ 9, 419},{ 9, 433},{ 10, 909},
|
||||
{ 10, 920},{ 10, 951},{ 10, 979},{ 10, 977},{ 10, 987},
|
||||
{ 11, 2013},{ 8, 180},{ 10, 990},{ 9, 425},{ 9, 411},
|
||||
{ 9, 412},{ 9, 417},{ 9, 426},{ 9, 429},{ 9, 435},
|
||||
{ 10, 907},{ 10, 946},{ 10, 952},{ 10, 974},{ 10, 993},
|
||||
{ 10, 992},{ 11, 2002},{ 11, 2021},{ 8, 183},{ 11, 2019},
|
||||
{ 9, 443},{ 9, 424},{ 9, 422},{ 9, 432},{ 9, 434},
|
||||
{ 9, 439},{ 10, 923},{ 10, 922},{ 10, 954},{ 10, 949},
|
||||
{ 10, 982},{ 11, 2007},{ 10, 996},{ 11, 2008},{ 11, 2026},
|
||||
{ 8, 186},{ 11, 2024},{ 10, 928},{ 9, 445},{ 9, 436},
|
||||
{ 10, 906},{ 9, 452},{ 10, 914},{ 10, 938},{ 10, 944},
|
||||
{ 10, 956},{ 10, 983},{ 11, 2004},{ 11, 2012},{ 11, 2011},
|
||||
{ 11, 2005},{ 11, 2032},{ 8, 193},{ 11, 2043},{ 10, 968},
|
||||
{ 10, 931},{ 10, 917},{ 10, 925},{ 10, 940},{ 10, 942},
|
||||
{ 10, 965},{ 10, 984},{ 10, 994},{ 10, 998},{ 11, 2020},
|
||||
{ 11, 2023},{ 11, 2016},{ 11, 2025},{ 11, 2039},{ 9, 400},
|
||||
{ 11, 2034},{ 10, 915},{ 9, 446},{ 9, 448},{ 10, 916},
|
||||
{ 10, 919},{ 10, 941},{ 10, 963},{ 10, 961},{ 10, 978},
|
||||
{ 11, 2010},{ 11, 2009},{ 11, 2015},{ 11, 2027},{ 11, 2036},
|
||||
{ 11, 2042},{ 9, 405},{ 11, 2040},{ 10, 957},{ 10, 924},
|
||||
{ 10, 939},{ 10, 936},{ 10, 947},{ 10, 953},{ 10, 976},
|
||||
{ 10, 995},{ 10, 997},{ 11, 2018},{ 11, 2014},{ 11, 2029},
|
||||
{ 11, 2033},{ 11, 2041},{ 11, 2044},{ 9, 403},{ 12, 4093},
|
||||
{ 10, 988},{ 10, 950},{ 10, 967},{ 10, 972},{ 10, 971},
|
||||
{ 10, 985},{ 10, 986},{ 11, 2003},{ 11, 2017},{ 11, 2030},
|
||||
{ 11, 2031},{ 11, 2037},{ 11, 2038},{ 12, 4092},{ 12, 4095},
|
||||
{ 9, 413},{ 9, 450},{ 8, 181},{ 8, 161},{ 8, 150},
|
||||
{ 8, 151},{ 8, 149},{ 8, 153},{ 8, 160},{ 8, 162},
|
||||
{ 8, 172},{ 8, 169},{ 8, 177},{ 8, 179},{ 8, 187},
|
||||
{ 8, 192},{ 9, 399},{ 5, 4}
|
||||
};
|
||||
unsigned int huff12[][2] = {
|
||||
{ 18, 262120},
|
||||
{ 18, 262118},{ 18, 262119},{ 18, 262117},{ 19, 524277},{ 19, 524273},
|
||||
{ 19, 524269},{ 19, 524278},{ 19, 524270},{ 19, 524271},{ 19, 524272},
|
||||
{ 19, 524284},{ 19, 524285},{ 19, 524287},{ 19, 524286},{ 19, 524279},
|
||||
{ 19, 524280},{ 19, 524283},{ 19, 524281},{ 18, 262116},{ 19, 524282},
|
||||
{ 18, 262115},{ 17, 131055},{ 17, 131056},{ 16, 65525},{ 17, 131054},
|
||||
{ 16, 65522},{ 16, 65523},{ 16, 65524},{ 16, 65521},{ 15, 32758},
|
||||
{ 15, 32759},{ 14, 16377},{ 14, 16373},{ 14, 16375},{ 14, 16371},
|
||||
{ 14, 16374},{ 14, 16370},{ 13, 8183},{ 13, 8181},{ 12, 4089},
|
||||
{ 12, 4087},{ 12, 4086},{ 11, 2041},{ 12, 4084},{ 11, 2040},
|
||||
{ 10, 1017},{ 10, 1015},{ 10, 1013},{ 9, 504},{ 9, 503},
|
||||
{ 8, 250},{ 8, 248},{ 8, 246},{ 7, 121},{ 6, 58},
|
||||
{ 6, 56},{ 5, 26},{ 4, 11},{ 3, 4},{ 1, 0},
|
||||
{ 4, 10},{ 4, 12},{ 5, 27},{ 6, 57},{ 6, 59},
|
||||
{ 7, 120},{ 7, 122},{ 8, 247},{ 8, 249},{ 9, 502},
|
||||
{ 9, 505},{ 10, 1012},{ 10, 1014},{ 10, 1016},{ 11, 2037},
|
||||
{ 11, 2036},{ 11, 2038},{ 11, 2039},{ 12, 4085},{ 12, 4088},
|
||||
{ 13, 8180},{ 13, 8182},{ 13, 8184},{ 14, 16376},{ 14, 16372},
|
||||
{ 16, 65520},{ 15, 32756},{ 16, 65526},{ 15, 32757},{ 18, 262114},
|
||||
{ 19, 524249},{ 19, 524250},{ 19, 524251},{ 19, 524252},{ 19, 524253},
|
||||
{ 19, 524254},{ 19, 524248},{ 19, 524242},{ 19, 524243},{ 19, 524244},
|
||||
{ 19, 524245},{ 19, 524246},{ 19, 524274},{ 19, 524255},{ 19, 524263},
|
||||
{ 19, 524264},{ 19, 524265},{ 19, 524266},{ 19, 524267},{ 19, 524262},
|
||||
{ 19, 524256},{ 19, 524257},{ 19, 524258},{ 19, 524259},{ 19, 524260},
|
||||
{ 19, 524261},{ 19, 524247},{ 19, 524268},{ 19, 524276},{ 19, 524275}
|
||||
};
|
||||
|
||||
|
58
external/libfaac/libfaac/kiss_fft/CHANGELOG
vendored
Normal file
58
external/libfaac/libfaac/kiss_fft/CHANGELOG
vendored
Normal file
|
@ -0,0 +1,58 @@
|
|||
1.2.1 (April 4, 2004)
|
||||
compiles cleanly with just about every -W warning flag under the sun
|
||||
|
||||
reorganized kiss_fft_state so it could be read-only/const. This may be useful for embedded systems
|
||||
that are willing to predeclare twiddle factors, factorization.
|
||||
|
||||
Fixed C_MUL,S_MUL on 16-bit platforms.
|
||||
|
||||
tmpbuf will only be allocated if input & output buffers are same
|
||||
scratchbuf will only be allocated for ffts that are not multiples of 2,3,5
|
||||
|
||||
NOTE: The tmpbuf,scratchbuf changes may require synchronization code for multi-threaded apps.
|
||||
|
||||
|
||||
1.2 (Feb 23, 2004)
|
||||
interface change -- cfg object is forward declaration of struct instead of void*
|
||||
This maintains type saftey and lets the compiler warn/error about stupid mistakes.
|
||||
(prompted by suggestion from Erik de Castro Lopo)
|
||||
|
||||
small speed improvements
|
||||
|
||||
added psdpng.c -- sample utility that will create png spectrum "waterfalls" from an input file
|
||||
( not terribly useful yet)
|
||||
|
||||
1.1.1 (Feb 1, 2004 )
|
||||
minor bug fix -- only affects odd rank, in-place, multi-dimensional FFTs
|
||||
|
||||
1.1 : (Jan 30,2004)
|
||||
split sample_code/ into test/ and tools/
|
||||
|
||||
Removed 2-D fft and added N-D fft (arbitrary)
|
||||
|
||||
modified fftutil.c to allow multi-d FFTs
|
||||
|
||||
Modified core fft routine to allow an input stride via kiss_fft_stride()
|
||||
(eased support of multi-D ffts)
|
||||
|
||||
Added fast convolution filtering (FIR filtering using overlap-scrap method, with tail scrap)
|
||||
|
||||
Add kfc.[ch]: the KISS FFT Cache. It takes care of allocs for you ( suggested by Oscar Lesta ).
|
||||
|
||||
1.0.1 (Dec 15, 2003)
|
||||
fixed bug that occurred when nfft==1
|
||||
|
||||
1.0 : (Dec 14, 2003)
|
||||
changed kiss_fft function from using a single buffer, to two buffers.
|
||||
If the same buffer pointer is supplied for both in and out, kiss will
|
||||
manage the buffer copies.
|
||||
|
||||
added kiss_fft2d and kiss_fftr as separate source files (declarations in kiss_fft.h )
|
||||
|
||||
0.4 :(Nov 4,2003) optimized for radix 2,3,4,5
|
||||
|
||||
0.3 :(Oct 28, 2003) woops, version 2 didn't actually factor out any radices other than 2
|
||||
|
||||
0.2 :(Oct 27, 2003) added mixed radix, only radix 2,4 optimized versions
|
||||
|
||||
0.1 :(May 19 2003) initial release, radix 2 only
|
11
external/libfaac/libfaac/kiss_fft/COPYING
vendored
Normal file
11
external/libfaac/libfaac/kiss_fft/COPYING
vendored
Normal file
|
@ -0,0 +1,11 @@
|
|||
Copyright (c) 2003-2004 Mark Borgerding
|
||||
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
|
||||
* Neither the author nor the names of any contributors may be used to endorse or promote products derived from this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
109
external/libfaac/libfaac/kiss_fft/README
vendored
Normal file
109
external/libfaac/libfaac/kiss_fft/README
vendored
Normal file
|
@ -0,0 +1,109 @@
|
|||
KISS FFT - A mixed-radix Fast Fourier Transform based up on the principle,
|
||||
"Keep It Simple, Stupid."
|
||||
|
||||
There are many great fft libraries already around. Kiss FFT is not trying
|
||||
to be better than any of them. It only attempts to be a reasonably efficient,
|
||||
moderately useful FFT that can use fixed or floating data types and can be
|
||||
incorporated into someone's C program in a few minutes with trivial licensing.
|
||||
|
||||
USAGE:
|
||||
|
||||
The basic usage for 1-d complex FFT is:
|
||||
|
||||
#include "kiss_fft.h"
|
||||
|
||||
kiss_fft_cfg cfg = kiss_fft_alloc( nfft ,inverse_fft );
|
||||
|
||||
while ...
|
||||
|
||||
... // put kth sample in cx_in[k].r and cx_in[k].i
|
||||
|
||||
kiss_fft( cfg , cx_in , cx_out );
|
||||
|
||||
... // transformed. DC is in cx_out[0].r and cx_out[0].i
|
||||
|
||||
free(cfg);
|
||||
|
||||
Note: frequency-domain data is stored from dc up to 2pi.
|
||||
so cx_out[0] is the dc bin of the FFT
|
||||
and cx_out[nfft/2] is the Nyquist bin (if exists)
|
||||
|
||||
Declarations are in "kiss_fft.h", along with a brief description of the
|
||||
functions you'll need to use.
|
||||
|
||||
Code definitions for 1d complex FFTs are in kiss_fft.c.
|
||||
|
||||
You can do other cool stuff with the extras you'll find in tools/
|
||||
|
||||
* arbitrary dimension complex FFTs
|
||||
* 1-d real FFTs
|
||||
* fast convolution FIR filtering
|
||||
* spectrum image creation
|
||||
|
||||
The core fft and most tools/ code can be compiled to use float, double
|
||||
or Q15 short samples. The default is float.
|
||||
|
||||
|
||||
BACKGROUND:
|
||||
|
||||
I started coding this because I couldn't find a fixed point FFT that didn't
|
||||
use assembly code. I started with floating point numbers so I could get the
|
||||
theory straight before working on fixed point issues. In the end, I had a
|
||||
little bit of code that could be recompiled easily to do ffts with short, float
|
||||
or double (other types should be easy too).
|
||||
|
||||
Once I got my FFT working, I was curious about the speed compared to
|
||||
a well respected and highly optimized fft library. I don't want to criticize
|
||||
this great library, so let's call it FFT_BRANDX.
|
||||
During this process, I learned:
|
||||
|
||||
1. FFT_BRANDX has more than 100K lines of code. The core of kiss_fft is about 500 lines (cpx 1-d).
|
||||
2. It took me an embarrassingly long time to get FFT_BRANDX working.
|
||||
3. A simple program using FFT_BRANDX is 522KB. A similar program using kiss_fft is 18KB.
|
||||
4. FFT_BRANDX is roughly twice as fast as KISS FFT.
|
||||
|
||||
It is wonderful that free, highly optimized libraries like FFT_BRANDX exist.
|
||||
But such libraries carry a huge burden of complexity necessary to extract every
|
||||
last bit of performance.
|
||||
|
||||
Sometimes simpler is better, even if it's not better.
|
||||
|
||||
PERFORMANCE:
|
||||
(on Athlon XP 2100+, with gcc 2.96, float data type)
|
||||
|
||||
Kiss performed 10000 1024-pt cpx ffts in .63 s of cpu time.
|
||||
For comparison, it took md5sum twice as long to process the same amount of data.
|
||||
|
||||
Transforming 5 minutes of CD quality audio takes less than a second (nfft=1024).
|
||||
|
||||
DO NOT:
|
||||
... use Kiss if you need the Fastest Fourier Transform in the World
|
||||
... ask me to add features that will bloat the code
|
||||
|
||||
UNDER THE HOOD:
|
||||
|
||||
Kiss FFT uses a time decimation, mixed-radix, out-of-place FFT.
|
||||
No scaling is done. Optimized butterflies are used for factors 2,3,4, and 5.
|
||||
|
||||
The real optimization code only works for even length ffts. It does two half-length
|
||||
FFTs in parallel (packed into real&imag), and then combines them via twiddling.
|
||||
|
||||
The fast convolution filtering uses the overlap-scrap method, slightly
|
||||
modified to put the scrap at the tail.
|
||||
|
||||
LICENSE:
|
||||
BSD, see COPYING for details. Basically, "free to use&change, give credit where due, no guarantees"
|
||||
|
||||
TODO:
|
||||
*) Add real optimization for odd length FFTs (DST?)
|
||||
*) Add real optimization to the n-dimensional FFT
|
||||
*) Add simple windowing function, e.g. Hamming : w(i)=.54-.46*cos(2pi*i/(n-1))
|
||||
*) Make the fixed point scaling and bit shifts more easily configurable.
|
||||
*) Document/revisit the input/output fft scaling
|
||||
*) See if the fixed point code can be optimized a little without adding complexity.
|
||||
*) Make doc describing the overlap (tail) scrap fast convolution filtering in kiss_fastfir.c
|
||||
*) Test all the ./tools/ code with fixed point (kiss_fastfir.c doesn't work, maybe others)
|
||||
|
||||
AUTHOR:
|
||||
Mark Borgerding
|
||||
Mark@Borgerding.net
|
6
external/libfaac/libfaac/kiss_fft/README.kiss_fft
vendored
Normal file
6
external/libfaac/libfaac/kiss_fft/README.kiss_fft
vendored
Normal file
|
@ -0,0 +1,6 @@
|
|||
See README and COPYING files for author and copyright information.
|
||||
|
||||
kiss_fft.c is modified in order to eliminate static variables.
|
||||
|
||||
-- sur.
|
||||
|
23
external/libfaac/libfaac/kiss_fft/TIPS
vendored
Normal file
23
external/libfaac/libfaac/kiss_fft/TIPS
vendored
Normal file
|
@ -0,0 +1,23 @@
|
|||
Speed:
|
||||
* experiment with compiler flags
|
||||
Special thanks to Oscar Lesta. He suggested some compiler flags
|
||||
for gcc that make a big difference. They shave 10-15% off
|
||||
execution time on some systems. Try some combination of:
|
||||
-march=pentiumpro
|
||||
-ffast-math
|
||||
-fomit-frame-pointer
|
||||
|
||||
* If the input data has no imaginary component, use the kiss_fftr code under tools/.
|
||||
Real ffts are roughly twice as fast as complex.
|
||||
|
||||
Reducing code size:
|
||||
* remove some of the butterflies. There are currently butterflies optimized for radices
|
||||
2,3,4,5. It is worth mentioning that you can still use FFT sizes that contain
|
||||
these factors, they just won't be quite as fast. You can decide for yourself
|
||||
whether to keep radix 2 or 4. If you do some work in this area, let me
|
||||
know what you find.
|
||||
|
||||
* For platforms where ROM/code space is more plentiful than RAM,
|
||||
consider creating a hardcoded kiss_fft_state. In other words, decide which
|
||||
FFT size(s) you want and make a structure with the correct factors and twiddles.
|
||||
|
97
external/libfaac/libfaac/kiss_fft/_kiss_fft_guts.h
vendored
Normal file
97
external/libfaac/libfaac/kiss_fft/_kiss_fft_guts.h
vendored
Normal file
|
@ -0,0 +1,97 @@
|
|||
/*
|
||||
Copyright (c) 2003-2004, Mark Borgerding
|
||||
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
|
||||
* Neither the author nor the names of any contributors may be used to endorse or promote products derived from this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
/* kiss_fft.h
|
||||
defines kiss_fft_scalar as either short or a float type
|
||||
and defines
|
||||
typedef struct { kiss_fft_scalar r; kiss_fft_scalar i; }kiss_fft_cpx; */
|
||||
#include "kiss_fft.h"
|
||||
|
||||
|
||||
#define MAXFACTORS 32
|
||||
/* e.g. an fft of length 128 has 4 factors
|
||||
as far as kissfft is concerned
|
||||
4*4*4*2
|
||||
*/
|
||||
|
||||
struct kiss_fft_state{
|
||||
int nfft;
|
||||
int inverse;
|
||||
int factors[2*MAXFACTORS];
|
||||
kiss_fft_cpx twiddles[1];
|
||||
};
|
||||
|
||||
/*
|
||||
Explanation of macros dealing with complex math:
|
||||
|
||||
C_MUL(m,a,b) : m = a*b
|
||||
C_FIXDIV( c , div ) : if a fixed point impl., c /= div. noop otherwise
|
||||
C_SUB( res, a,b) : res = a - b
|
||||
C_SUBFROM( res , a) : res -= a
|
||||
C_ADDTO( res , a) : res += a
|
||||
* */
|
||||
#ifdef FIXED_POINT
|
||||
|
||||
# define smul(a,b) ( (long)(a)*(b) )
|
||||
# define sround( x ) (short)( ( (x) + (1<<14) ) >>15 )
|
||||
|
||||
# define S_MUL(a,b) sround( smul(a,b) )
|
||||
|
||||
# define C_MUL(m,a,b) \
|
||||
do{ (m).r = sround( smul((a).r,(b).r) - smul((a).i,(b).i) ); \
|
||||
(m).i = sround( smul((a).r,(b).i) + smul((a).i,(b).r) ); }while(0)
|
||||
|
||||
# define C_FIXDIV(c,div) \
|
||||
do{ (c).r /= div; (c).i /=div; }while(0)
|
||||
|
||||
# define C_MULBYSCALAR( c, s ) \
|
||||
do{ (c).r = sround( smul( (c).r , s ) ) ;\
|
||||
(c).i = sround( smul( (c).i , s ) ) ; }while(0)
|
||||
|
||||
#else /* not FIXED_POINT*/
|
||||
|
||||
# define S_MUL(a,b) ( (a)*(b) )
|
||||
#define C_MUL(m,a,b) \
|
||||
do{ (m).r = (a).r*(b).r - (a).i*(b).i;\
|
||||
(m).i = (a).r*(b).i + (a).i*(b).r; }while(0)
|
||||
# define C_FIXDIV(c,div) /* NOOP */
|
||||
# define C_MULBYSCALAR( c, s ) \
|
||||
do{ (c).r *= (s);\
|
||||
(c).i *= (s); }while(0)
|
||||
#endif
|
||||
|
||||
#define C_ADD( res, a,b)\
|
||||
do { (res).r=(a).r+(b).r; (res).i=(a).i+(b).i; }while(0)
|
||||
#define C_SUB( res, a,b)\
|
||||
do { (res).r=(a).r-(b).r; (res).i=(a).i-(b).i; }while(0)
|
||||
#define C_ADDTO( res , a)\
|
||||
do { (res).r += (a).r; (res).i += (a).i; }while(0)
|
||||
#define C_SUBFROM( res , a)\
|
||||
do { (res).r -= (a).r; (res).i -= (a).i; }while(0)
|
||||
|
||||
static
|
||||
void kf_cexp(kiss_fft_cpx * x,double phase) /* returns e ** (j*phase) */
|
||||
{
|
||||
#ifdef FIXED_POINT
|
||||
x->r = (kiss_fft_scalar) (32767 * cos (phase));
|
||||
x->i = (kiss_fft_scalar) (32767 * sin (phase));
|
||||
#else
|
||||
x->r = cos (phase);
|
||||
x->i = sin (phase);
|
||||
#endif
|
||||
}
|
||||
|
||||
/* a debugging function */
|
||||
#define pcpx(c)\
|
||||
fprintf(stderr,"%g + %gi\n",(double)((c)->r),(double)((c)->i) )
|
362
external/libfaac/libfaac/kiss_fft/kiss_fft.c
vendored
Normal file
362
external/libfaac/libfaac/kiss_fft/kiss_fft.c
vendored
Normal file
|
@ -0,0 +1,362 @@
|
|||
/*
|
||||
Copyright (c) 2003-2004, Mark Borgerding
|
||||
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
|
||||
* Neither the author nor the names of any contributors may be used to endorse or promote products derived from this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
|
||||
#include "_kiss_fft_guts.h"
|
||||
/* The guts header contains all the multiplication and addition macros that are defined for
|
||||
fixed or floating point complex numbers. It also delares the kf_ internal functions.
|
||||
*/
|
||||
|
||||
static void kf_bfly2(
|
||||
kiss_fft_cpx * Fout,
|
||||
const size_t fstride,
|
||||
const kiss_fft_cfg st,
|
||||
int m
|
||||
)
|
||||
{
|
||||
kiss_fft_cpx * Fout2;
|
||||
kiss_fft_cpx * tw1 = st->twiddles;
|
||||
kiss_fft_cpx t;
|
||||
Fout2 = Fout + m;
|
||||
do{
|
||||
C_FIXDIV(*Fout,2); C_FIXDIV(*Fout2,2);
|
||||
|
||||
C_MUL (t, *Fout2 , *tw1);
|
||||
tw1 += fstride;
|
||||
C_SUB( *Fout2 , *Fout , t );
|
||||
C_ADDTO( *Fout , t );
|
||||
++Fout2;
|
||||
++Fout;
|
||||
}while (--m);
|
||||
}
|
||||
|
||||
static void kf_bfly4(
|
||||
kiss_fft_cpx * Fout,
|
||||
const size_t fstride,
|
||||
const kiss_fft_cfg st,
|
||||
const size_t m
|
||||
)
|
||||
{
|
||||
kiss_fft_cpx *tw1,*tw2,*tw3;
|
||||
kiss_fft_cpx scratch[6];
|
||||
size_t k=m;
|
||||
const size_t m2=2*m;
|
||||
const size_t m3=3*m;
|
||||
|
||||
tw3 = tw2 = tw1 = st->twiddles;
|
||||
|
||||
do {
|
||||
C_FIXDIV(*Fout,4); C_FIXDIV(Fout[m],4); C_FIXDIV(Fout[m2],4); C_FIXDIV(Fout[m3],4);
|
||||
|
||||
C_MUL(scratch[0],Fout[m] , *tw1 );
|
||||
C_MUL(scratch[1],Fout[m2] , *tw2 );
|
||||
C_MUL(scratch[2],Fout[m3] , *tw3 );
|
||||
|
||||
C_SUB( scratch[5] , *Fout, scratch[1] );
|
||||
C_ADDTO(*Fout, scratch[1]);
|
||||
C_ADD( scratch[3] , scratch[0] , scratch[2] );
|
||||
C_SUB( scratch[4] , scratch[0] , scratch[2] );
|
||||
C_SUB( Fout[m2], *Fout, scratch[3] );
|
||||
tw1 += fstride;
|
||||
tw2 += fstride*2;
|
||||
tw3 += fstride*3;
|
||||
C_ADDTO( *Fout , scratch[3] );
|
||||
|
||||
if(st->inverse) {
|
||||
Fout[m].r = scratch[5].r - scratch[4].i;
|
||||
Fout[m].i = scratch[5].i + scratch[4].r;
|
||||
Fout[m3].r = scratch[5].r + scratch[4].i;
|
||||
Fout[m3].i = scratch[5].i - scratch[4].r;
|
||||
}else{
|
||||
Fout[m].r = scratch[5].r + scratch[4].i;
|
||||
Fout[m].i = scratch[5].i - scratch[4].r;
|
||||
Fout[m3].r = scratch[5].r - scratch[4].i;
|
||||
Fout[m3].i = scratch[5].i + scratch[4].r;
|
||||
}
|
||||
++Fout;
|
||||
}while(--k);
|
||||
}
|
||||
|
||||
static void kf_bfly3(
|
||||
kiss_fft_cpx * Fout,
|
||||
const size_t fstride,
|
||||
const kiss_fft_cfg st,
|
||||
size_t m
|
||||
)
|
||||
{
|
||||
size_t k=m;
|
||||
const size_t m2 = 2*m;
|
||||
kiss_fft_cpx *tw1,*tw2;
|
||||
kiss_fft_cpx scratch[5];
|
||||
kiss_fft_cpx epi3;
|
||||
epi3 = st->twiddles[fstride*m];
|
||||
|
||||
tw1=tw2=st->twiddles;
|
||||
|
||||
do{
|
||||
C_FIXDIV(*Fout,3); C_FIXDIV(Fout[m],3); C_FIXDIV(Fout[m2],3);
|
||||
|
||||
C_MUL(scratch[1],Fout[m] , *tw1);
|
||||
C_MUL(scratch[2],Fout[m2] , *tw2);
|
||||
|
||||
C_ADD(scratch[3],scratch[1],scratch[2]);
|
||||
C_SUB(scratch[0],scratch[1],scratch[2]);
|
||||
tw1 += fstride;
|
||||
tw2 += fstride*2;
|
||||
|
||||
Fout[m].r = Fout->r - scratch[3].r/2;
|
||||
Fout[m].i = Fout->i - scratch[3].i/2;
|
||||
|
||||
C_MULBYSCALAR( scratch[0] , epi3.i );
|
||||
|
||||
C_ADDTO(*Fout,scratch[3]);
|
||||
|
||||
Fout[m2].r = Fout[m].r + scratch[0].i;
|
||||
Fout[m2].i = Fout[m].i - scratch[0].r;
|
||||
|
||||
Fout[m].r -= scratch[0].i;
|
||||
Fout[m].i += scratch[0].r;
|
||||
|
||||
++Fout;
|
||||
}while(--k);
|
||||
}
|
||||
|
||||
static void kf_bfly5(
|
||||
kiss_fft_cpx * Fout,
|
||||
const size_t fstride,
|
||||
const kiss_fft_cfg st,
|
||||
int m
|
||||
)
|
||||
{
|
||||
kiss_fft_cpx *Fout0,*Fout1,*Fout2,*Fout3,*Fout4;
|
||||
int u;
|
||||
kiss_fft_cpx scratch[13];
|
||||
kiss_fft_cpx * twiddles = st->twiddles;
|
||||
kiss_fft_cpx *tw;
|
||||
kiss_fft_cpx ya,yb;
|
||||
ya = twiddles[fstride*m];
|
||||
yb = twiddles[fstride*2*m];
|
||||
|
||||
Fout0=Fout;
|
||||
Fout1=Fout0+m;
|
||||
Fout2=Fout0+2*m;
|
||||
Fout3=Fout0+3*m;
|
||||
Fout4=Fout0+4*m;
|
||||
|
||||
tw=st->twiddles;
|
||||
for ( u=0; u<m; ++u ) {
|
||||
C_FIXDIV( *Fout0,5); C_FIXDIV( *Fout1,5); C_FIXDIV( *Fout2,5); C_FIXDIV( *Fout3,5); C_FIXDIV( *Fout4,5);
|
||||
scratch[0] = *Fout0;
|
||||
|
||||
C_MUL(scratch[1] ,*Fout1, tw[u*fstride]);
|
||||
C_MUL(scratch[2] ,*Fout2, tw[2*u*fstride]);
|
||||
C_MUL(scratch[3] ,*Fout3, tw[3*u*fstride]);
|
||||
C_MUL(scratch[4] ,*Fout4, tw[4*u*fstride]);
|
||||
|
||||
C_ADD( scratch[7],scratch[1],scratch[4]);
|
||||
C_SUB( scratch[10],scratch[1],scratch[4]);
|
||||
C_ADD( scratch[8],scratch[2],scratch[3]);
|
||||
C_SUB( scratch[9],scratch[2],scratch[3]);
|
||||
|
||||
Fout0->r += scratch[7].r + scratch[8].r;
|
||||
Fout0->i += scratch[7].i + scratch[8].i;
|
||||
|
||||
scratch[5].r = scratch[0].r + S_MUL(scratch[7].r,ya.r) + S_MUL(scratch[8].r,yb.r);
|
||||
scratch[5].i = scratch[0].i + S_MUL(scratch[7].i,ya.r) + S_MUL(scratch[8].i,yb.r);
|
||||
|
||||
scratch[6].r = S_MUL(scratch[10].i,ya.i) + S_MUL(scratch[9].i,yb.i);
|
||||
scratch[6].i = -S_MUL(scratch[10].r,ya.i) - S_MUL(scratch[9].r,yb.i);
|
||||
|
||||
C_SUB(*Fout1,scratch[5],scratch[6]);
|
||||
C_ADD(*Fout4,scratch[5],scratch[6]);
|
||||
|
||||
scratch[11].r = scratch[0].r + S_MUL(scratch[7].r,yb.r) + S_MUL(scratch[8].r,ya.r);
|
||||
scratch[11].i = scratch[0].i + S_MUL(scratch[7].i,yb.r) + S_MUL(scratch[8].i,ya.r);
|
||||
scratch[12].r = - S_MUL(scratch[10].i,yb.i) + S_MUL(scratch[9].i,ya.i);
|
||||
scratch[12].i = S_MUL(scratch[10].r,yb.i) - S_MUL(scratch[9].r,ya.i);
|
||||
|
||||
C_ADD(*Fout2,scratch[11],scratch[12]);
|
||||
C_SUB(*Fout3,scratch[11],scratch[12]);
|
||||
|
||||
++Fout0;++Fout1;++Fout2;++Fout3;++Fout4;
|
||||
}
|
||||
}
|
||||
|
||||
/* perform the butterfly for one stage of a mixed radix FFT */
|
||||
static void kf_bfly_generic(
|
||||
kiss_fft_cpx * Fout,
|
||||
const size_t fstride,
|
||||
const kiss_fft_cfg st,
|
||||
int m,
|
||||
int p
|
||||
)
|
||||
{
|
||||
int u,k,q1,q;
|
||||
kiss_fft_cpx * twiddles = st->twiddles;
|
||||
kiss_fft_cpx t;
|
||||
int Norig = st->nfft;
|
||||
|
||||
kiss_fft_cpx *scratchbuf=(kiss_fft_cpx *)malloc( sizeof(kiss_fft_cpx) * p );
|
||||
|
||||
for ( u=0; u<m; ++u ) {
|
||||
k=u;
|
||||
for ( q1=0 ; q1<p ; ++q1 ) {
|
||||
scratchbuf[q1] = Fout[ k ];
|
||||
C_FIXDIV(scratchbuf[q1],p);
|
||||
k += m;
|
||||
}
|
||||
|
||||
k=u;
|
||||
for ( q1=0 ; q1<p ; ++q1 ) {
|
||||
int twidx=0;
|
||||
Fout[ k ] = scratchbuf[0];
|
||||
for (q=1;q<p;++q ) {
|
||||
twidx += fstride * k;
|
||||
if (twidx>=Norig) twidx-=Norig;
|
||||
C_MUL(t,scratchbuf[q] , twiddles[twidx] );
|
||||
C_ADDTO( Fout[ k ] ,t);
|
||||
}
|
||||
k += m;
|
||||
}
|
||||
}
|
||||
|
||||
free( scratchbuf );
|
||||
}
|
||||
|
||||
static
|
||||
void kf_work(
|
||||
kiss_fft_cpx * Fout,
|
||||
const kiss_fft_cpx * f,
|
||||
const size_t fstride,
|
||||
int in_stride,
|
||||
int * factors,
|
||||
const kiss_fft_cfg st
|
||||
)
|
||||
{
|
||||
kiss_fft_cpx * Fout_beg=Fout;
|
||||
const int p=*factors++; /* the radix */
|
||||
const int m=*factors++; /* stage's fft length/p */
|
||||
const kiss_fft_cpx * Fout_end = Fout + p*m;
|
||||
|
||||
if (m==1) {
|
||||
do{
|
||||
*Fout = *f;
|
||||
f += fstride*in_stride;
|
||||
}while(++Fout != Fout_end );
|
||||
}else{
|
||||
do{
|
||||
kf_work( Fout , f, fstride*p, in_stride, factors,st);
|
||||
f += fstride*in_stride;
|
||||
}while( (Fout += m) != Fout_end );
|
||||
}
|
||||
|
||||
Fout=Fout_beg;
|
||||
|
||||
switch (p) {
|
||||
case 2: kf_bfly2(Fout,fstride,st,m); break;
|
||||
case 3: kf_bfly3(Fout,fstride,st,m); break;
|
||||
case 4: kf_bfly4(Fout,fstride,st,m); break;
|
||||
case 5: kf_bfly5(Fout,fstride,st,m); break;
|
||||
default: kf_bfly_generic(Fout,fstride,st,m,p); break;
|
||||
}
|
||||
}
|
||||
|
||||
/* facbuf is populated by p1,m1,p2,m2, ...
|
||||
where
|
||||
p[i] * m[i] = m[i-1]
|
||||
m0 = n */
|
||||
static
|
||||
void kf_factor(int n,int * facbuf)
|
||||
{
|
||||
int p=4;
|
||||
double floor_sqrt;
|
||||
floor_sqrt = floor( sqrt((double)n) );
|
||||
|
||||
/*factor out powers of 4, powers of 2, then any remaining primes */
|
||||
do {
|
||||
while (n % p) {
|
||||
switch (p) {
|
||||
case 4: p = 2; break;
|
||||
case 2: p = 3; break;
|
||||
default: p += 2; break;
|
||||
}
|
||||
if (p > floor_sqrt)
|
||||
p = n; /* no more factors, skip to end */
|
||||
}
|
||||
n /= p;
|
||||
*facbuf++ = p;
|
||||
*facbuf++ = n;
|
||||
} while (n > 1);
|
||||
}
|
||||
|
||||
/*
|
||||
*
|
||||
* User-callable function to allocate all necessary storage space for the fft.
|
||||
*
|
||||
* The return value is a contiguous block of memory, allocated with malloc. As such,
|
||||
* It can be freed with free(), rather than a kiss_fft-specific function.
|
||||
* */
|
||||
kiss_fft_cfg kiss_fft_alloc(int nfft,int inverse_fft,void * mem,size_t * lenmem )
|
||||
{
|
||||
kiss_fft_cfg st=NULL;
|
||||
size_t memneeded = sizeof(struct kiss_fft_state)
|
||||
+ sizeof(kiss_fft_cpx)*(nfft-1); /* twiddle factors*/
|
||||
|
||||
if ( lenmem==NULL ) {
|
||||
st = ( kiss_fft_cfg)malloc( memneeded );
|
||||
}else{
|
||||
if (*lenmem >= memneeded)
|
||||
st = (kiss_fft_cfg)mem;
|
||||
*lenmem = memneeded;
|
||||
}
|
||||
if (st) {
|
||||
int i;
|
||||
const double pi=3.14159265358979323846264338327;
|
||||
const double phase0 = -2.0 * pi / (double)( nfft );
|
||||
|
||||
st->nfft=nfft;
|
||||
st->inverse = inverse_fft;
|
||||
|
||||
for (i=0;i<nfft;++i) {
|
||||
double phase = phase0 * i;
|
||||
if (st->inverse)
|
||||
phase *= -1;
|
||||
kf_cexp(st->twiddles+i, phase );
|
||||
}
|
||||
|
||||
kf_factor(nfft,st->factors);
|
||||
}
|
||||
return st;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
void kiss_fft_stride(kiss_fft_cfg st,const kiss_fft_cpx *fin,kiss_fft_cpx *fout,int in_stride)
|
||||
{
|
||||
if (fin == fout) {
|
||||
kiss_fft_cpx *tmpbuf=(kiss_fft_cpx*)malloc( sizeof(kiss_fft_cpx) * st->nfft );
|
||||
kf_work(tmpbuf,fin,1,in_stride, st->factors,st);
|
||||
memcpy(fout,tmpbuf,sizeof(kiss_fft_cpx)*st->nfft);
|
||||
free( tmpbuf );
|
||||
}else{
|
||||
kf_work( fout, fin, 1,in_stride, st->factors,st );
|
||||
}
|
||||
}
|
||||
|
||||
void kiss_fft(kiss_fft_cfg cfg,const kiss_fft_cpx *fin,kiss_fft_cpx *fout)
|
||||
{
|
||||
kiss_fft_stride(cfg,fin,fout,1);
|
||||
}
|
||||
|
94
external/libfaac/libfaac/kiss_fft/kiss_fft.h
vendored
Normal file
94
external/libfaac/libfaac/kiss_fft/kiss_fft.h
vendored
Normal file
|
@ -0,0 +1,94 @@
|
|||
/*
|
||||
Copyright (c) 2013-2016 EasyDarwin.ORG. All rights reserved.
|
||||
Github: https://github.com/EasyDarwin
|
||||
WEChat: EasyDarwin
|
||||
Website: http://www.easydarwin.org
|
||||
*/
|
||||
#ifndef KISS_FFT_H
|
||||
#define KISS_FFT_H
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <math.h>
|
||||
#include <memory.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*
|
||||
ATTENTION!
|
||||
If you would like a :
|
||||
-- a utility that will handle the caching of fft objects
|
||||
-- real-only FFT
|
||||
-- a multi-dimensional FFT
|
||||
-- a command-line utility to perform ffts
|
||||
-- a command-line utility to perform fast-convolution filtering
|
||||
|
||||
then see tools/
|
||||
*/
|
||||
|
||||
#ifdef FIXED_POINT
|
||||
# define kiss_fft_scalar short
|
||||
#else
|
||||
# ifndef kiss_fft_scalar
|
||||
/* default is float */
|
||||
# define kiss_fft_scalar float
|
||||
# endif
|
||||
#endif
|
||||
|
||||
typedef struct {
|
||||
kiss_fft_scalar r;
|
||||
kiss_fft_scalar i;
|
||||
}kiss_fft_cpx;
|
||||
|
||||
typedef struct kiss_fft_state* kiss_fft_cfg;
|
||||
|
||||
/*
|
||||
* kiss_fft_alloc
|
||||
*
|
||||
* Initialize a FFT (or IFFT) algorithm's cfg/state buffer.
|
||||
*
|
||||
* typical usage: kiss_fft_cfg mycfg=kiss_fft_alloc(1024,0,NULL,NULL);
|
||||
*
|
||||
* The return value from fft_alloc is a cfg buffer used internally
|
||||
* by the fft routine or NULL.
|
||||
*
|
||||
* If lenmem is NULL, then kiss_fft_alloc will allocate a cfg buffer using malloc.
|
||||
* The returned value should be free()d when done to avoid memory leaks.
|
||||
*
|
||||
* The state can be placed in a user supplied buffer 'mem':
|
||||
* If lenmem is not NULL and mem is not NULL and *lenmem is large enough,
|
||||
* then the function places the cfg in mem and the size used in *lenmem
|
||||
* and returns mem.
|
||||
*
|
||||
* If lenmem is not NULL and ( mem is NULL or *lenmem is not large enough),
|
||||
* then the function returns NULL and places the minimum cfg
|
||||
* buffer size in *lenmem.
|
||||
* */
|
||||
|
||||
kiss_fft_cfg kiss_fft_alloc(int nfft,int inverse_fft,void * mem,size_t * lenmem);
|
||||
|
||||
/*
|
||||
* kiss_fft(cfg,in_out_buf)
|
||||
*
|
||||
* Perform an FFT on a complex input buffer.
|
||||
* for a forward FFT,
|
||||
* fin should be f[0] , f[1] , ... ,f[nfft-1]
|
||||
* fout will be F[0] , F[1] , ... ,F[nfft-1]
|
||||
* Note that each element is complex and can be accessed like
|
||||
f[k].r and f[k].i
|
||||
* */
|
||||
void kiss_fft(kiss_fft_cfg cfg,const kiss_fft_cpx *fin,kiss_fft_cpx *fout);
|
||||
|
||||
void kiss_fft_stride(kiss_fft_cfg cfg,const kiss_fft_cpx *fin,kiss_fft_cpx *fout,int fin_stride);
|
||||
|
||||
/* If kiss_fft_alloc allocated a buffer, it is one contiguous
|
||||
buffer and can be simply free()d when no longer needed*/
|
||||
#define kiss_fft_free free
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
137
external/libfaac/libfaac/kiss_fft/kiss_fftr.c
vendored
Normal file
137
external/libfaac/libfaac/kiss_fft/kiss_fftr.c
vendored
Normal file
|
@ -0,0 +1,137 @@
|
|||
/*
|
||||
Copyright (c) 2003-2004, Mark Borgerding
|
||||
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
|
||||
* Neither the author nor the names of any contributors may be used to endorse or promote products derived from this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include "kiss_fftr.h"
|
||||
#include "_kiss_fft_guts.h"
|
||||
|
||||
struct kiss_fftr_state{
|
||||
kiss_fft_cfg substate;
|
||||
kiss_fft_cpx * tmpbuf;
|
||||
kiss_fft_cpx * super_twiddles;
|
||||
};
|
||||
|
||||
kiss_fftr_cfg kiss_fftr_alloc(int nfft,int inverse_fft,void * mem,size_t * lenmem)
|
||||
{
|
||||
int i;
|
||||
kiss_fftr_cfg st = NULL;
|
||||
size_t subsize, memneeded;
|
||||
|
||||
if (nfft & 1) {
|
||||
fprintf(stderr,"Real FFT optimization must be even.\n");
|
||||
return NULL;
|
||||
}
|
||||
nfft >>= 1;
|
||||
|
||||
kiss_fft_alloc (nfft, inverse_fft, NULL, &subsize);
|
||||
memneeded = sizeof(struct kiss_fftr_state) + subsize + sizeof(kiss_fft_cpx) * ( nfft * 2);
|
||||
|
||||
if (lenmem == NULL) {
|
||||
st = (kiss_fftr_cfg) malloc (memneeded);
|
||||
} else {
|
||||
if (*lenmem >= memneeded)
|
||||
st = (kiss_fftr_cfg) mem;
|
||||
*lenmem = memneeded;
|
||||
}
|
||||
if (!st)
|
||||
return NULL;
|
||||
|
||||
st->substate = (kiss_fft_cfg) (st + 1); /*just beyond kiss_fftr_state struct */
|
||||
st->tmpbuf = (kiss_fft_cpx *) (((char *) st->substate) + subsize);
|
||||
st->super_twiddles = st->tmpbuf + nfft;
|
||||
kiss_fft_alloc(nfft, inverse_fft, st->substate, &subsize);
|
||||
|
||||
for (i = 0; i < nfft; ++i) {
|
||||
double phase =
|
||||
-3.14159265358979323846264338327 * ((double) i / nfft + .5);
|
||||
if (inverse_fft)
|
||||
phase *= -1;
|
||||
kf_cexp (st->super_twiddles+i,phase);
|
||||
}
|
||||
return st;
|
||||
}
|
||||
|
||||
void kiss_fftr(kiss_fftr_cfg st,const kiss_fft_scalar *timedata,kiss_fft_cpx *freqdata)
|
||||
{
|
||||
/* input buffer timedata is stored row-wise */
|
||||
int k,N;
|
||||
|
||||
if ( st->substate->inverse) {
|
||||
fprintf(stderr,"kiss fft usage error: improper alloc\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
N = st->substate->nfft;
|
||||
|
||||
/*perform the parallel fft of two real signals packed in real,imag*/
|
||||
kiss_fft( st->substate , (const kiss_fft_cpx*)timedata, st->tmpbuf );
|
||||
|
||||
freqdata[0].r = st->tmpbuf[0].r + st->tmpbuf[0].i;
|
||||
freqdata[0].i = 0;
|
||||
C_FIXDIV(freqdata[0],2);
|
||||
|
||||
for (k=1;k <= N/2 ; ++k ) {
|
||||
kiss_fft_cpx fpnk,fpk,f1k,f2k,tw;
|
||||
|
||||
fpk = st->tmpbuf[k];
|
||||
fpnk.r = st->tmpbuf[N-k].r;
|
||||
fpnk.i = -st->tmpbuf[N-k].i;
|
||||
C_FIXDIV(fpk,2);
|
||||
C_FIXDIV(fpnk,2);
|
||||
|
||||
C_ADD( f1k, fpk , fpnk );
|
||||
C_SUB( f2k, fpk , fpnk );
|
||||
C_MUL( tw , f2k , st->super_twiddles[k]);
|
||||
|
||||
C_ADD( freqdata[k] , f1k ,tw);
|
||||
freqdata[k].r = (f1k.r + tw.r) / 2;
|
||||
freqdata[k].i = (f1k.i + tw.i) / 2;
|
||||
|
||||
freqdata[N-k].r = (f1k.r - tw.r)/2;
|
||||
freqdata[N-k].i = - (f1k.i - tw.i)/2;
|
||||
}
|
||||
freqdata[N].r = st->tmpbuf[0].r - st->tmpbuf[0].i;
|
||||
freqdata[N].i = 0;
|
||||
C_FIXDIV(freqdata[N],2);
|
||||
}
|
||||
|
||||
void kiss_fftri(kiss_fftr_cfg st,const kiss_fft_cpx *freqdata,kiss_fft_scalar *timedata)
|
||||
{
|
||||
/* input buffer timedata is stored row-wise */
|
||||
int k, N;
|
||||
|
||||
if (st->substate->inverse == 0) {
|
||||
fprintf (stderr, "kiss fft usage error: improper alloc\n");
|
||||
exit (1);
|
||||
}
|
||||
|
||||
N = st->substate->nfft;
|
||||
|
||||
st->tmpbuf[0].r = freqdata[0].r + freqdata[N].r;
|
||||
st->tmpbuf[0].i = freqdata[0].r - freqdata[N].r;
|
||||
|
||||
for (k = 1; k <= N / 2; ++k) {
|
||||
kiss_fft_cpx fk, fnkc, fek, fok, tmpbuf;
|
||||
fk = freqdata[k];
|
||||
fnkc.r = freqdata[N - k].r;
|
||||
fnkc.i = -freqdata[N - k].i;
|
||||
|
||||
C_ADD (fek, fk, fnkc);
|
||||
C_SUB (tmpbuf, fk, fnkc);
|
||||
C_MUL (fok, tmpbuf, st->super_twiddles[k]);
|
||||
C_ADD (st->tmpbuf[k], fek, fok);
|
||||
C_SUB (st->tmpbuf[N - k], fek, fok);
|
||||
st->tmpbuf[N - k].i *= -1;
|
||||
}
|
||||
kiss_fft (st->substate, st->tmpbuf, (kiss_fft_cpx *) timedata);
|
||||
}
|
52
external/libfaac/libfaac/kiss_fft/kiss_fftr.h
vendored
Normal file
52
external/libfaac/libfaac/kiss_fft/kiss_fftr.h
vendored
Normal file
|
@ -0,0 +1,52 @@
|
|||
/*
|
||||
Copyright (c) 2013-2016 EasyDarwin.ORG. All rights reserved.
|
||||
Github: https://github.com/EasyDarwin
|
||||
WEChat: EasyDarwin
|
||||
Website: http://www.easydarwin.org
|
||||
*/
|
||||
#ifndef KISS_FTR_H
|
||||
#define KISS_FTR_H
|
||||
|
||||
#include "kiss_fft.h"
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
|
||||
/*
|
||||
|
||||
Real optimized version can save about 45% cpu time vs. complex fft of a real seq.
|
||||
|
||||
|
||||
|
||||
*/
|
||||
|
||||
typedef struct kiss_fftr_state *kiss_fftr_cfg;
|
||||
|
||||
|
||||
kiss_fftr_cfg kiss_fftr_alloc(int nfft,int inverse_fft,void * mem, size_t * lenmem);
|
||||
/*
|
||||
nfft must be even
|
||||
|
||||
If you don't care to allocate space, use mem = lenmem = NULL
|
||||
*/
|
||||
|
||||
|
||||
void kiss_fftr(kiss_fftr_cfg cfg,const kiss_fft_scalar *timedata,kiss_fft_cpx *freqdata);
|
||||
/*
|
||||
input timedata has nfft scalar points
|
||||
output freqdata has nfft/2+1 complex points
|
||||
*/
|
||||
|
||||
void kiss_fftri(kiss_fftr_cfg cfg,const kiss_fft_cpx *freqdata,kiss_fft_scalar *timedata);
|
||||
/*
|
||||
input freqdata has nfft/2+1 complex points
|
||||
output timedata has nfft scalar points
|
||||
*/
|
||||
|
||||
#define kiss_fftr_free free
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif
|
420
external/libfaac/libfaac/ltp.c
vendored
Normal file
420
external/libfaac/libfaac/ltp.c
vendored
Normal file
|
@ -0,0 +1,420 @@
|
|||
/**************************************************************************
|
||||
|
||||
This software module was originally developed by
|
||||
Nokia in the course of development of the MPEG-2 AAC/MPEG-4
|
||||
Audio standard ISO/IEC13818-7, 14496-1, 2 and 3.
|
||||
This software module is an implementation of a part
|
||||
of one or more MPEG-2 AAC/MPEG-4 Audio tools as specified by the
|
||||
MPEG-2 aac/MPEG-4 Audio standard. ISO/IEC gives users of the
|
||||
MPEG-2aac/MPEG-4 Audio standards free license to this software module
|
||||
or modifications thereof for use in hardware or software products
|
||||
claiming conformance to the MPEG-2 aac/MPEG-4 Audio standards. Those
|
||||
intending to use this software module in hardware or software products
|
||||
are advised that this use may infringe existing patents. The original
|
||||
developer of this software module, the subsequent
|
||||
editors and their companies, and ISO/IEC have no liability for use of
|
||||
this software module or modifications thereof in an
|
||||
implementation. Copyright is not released for non MPEG-2 aac/MPEG-4
|
||||
Audio conforming products. The original developer retains full right to
|
||||
use the code for the developer's own purpose, assign or donate the code to a
|
||||
third party and to inhibit third party from using the code for non
|
||||
MPEG-2 aac/MPEG-4 Audio conforming products. This copyright notice
|
||||
must be included in all copies or derivative works.
|
||||
Copyright (c)1997.
|
||||
|
||||
***************************************************************************/
|
||||
/*
|
||||
* $Id: ltp.c,v 1.9 2003/06/26 19:20:31 knik Exp $
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <math.h>
|
||||
|
||||
#include "frame.h"
|
||||
#include "coder.h"
|
||||
#include "ltp.h"
|
||||
#include "tns.h"
|
||||
#include "filtbank.h"
|
||||
#include "util.h"
|
||||
|
||||
|
||||
/* short double_to_int(double sig_in); */
|
||||
#define double_to_int(sig_in) \
|
||||
((sig_in) > 32767 ? 32767 : ( \
|
||||
(sig_in) < -32768 ? -32768 : (sig_in)))
|
||||
|
||||
#define _MDCT_SCALE 512
|
||||
|
||||
/* Purpose: Codebook for LTP weight coefficients. */
|
||||
static double codebook[CODESIZE] =
|
||||
{
|
||||
0.570829,
|
||||
0.696616,
|
||||
0.813004,
|
||||
0.911304,
|
||||
0.984900,
|
||||
1.067894,
|
||||
1.194601,
|
||||
1.369533
|
||||
};
|
||||
|
||||
|
||||
static double snr_pred(double *mdct_in, double *mdct_pred, int *sfb_flag, int *sfb_offset,
|
||||
int block_type, int side_info, int num_of_sfb)
|
||||
{
|
||||
int i, j, flen;
|
||||
double snr_limit;
|
||||
double num_bit, snr[NSFB_LONG];
|
||||
double temp1, temp2;
|
||||
double energy[BLOCK_LEN_LONG], snr_p[BLOCK_LEN_LONG];
|
||||
|
||||
if (block_type != ONLY_SHORT_WINDOW)
|
||||
{
|
||||
flen = BLOCK_LEN_LONG;
|
||||
snr_limit = 1.e-30;
|
||||
} else {
|
||||
flen = BLOCK_LEN_SHORT;
|
||||
snr_limit = 1.e-20;
|
||||
}
|
||||
|
||||
for (i = 0; i < flen; i++)
|
||||
{
|
||||
energy[i] = mdct_in[i] * mdct_in[i];
|
||||
snr_p[i] = (mdct_in[i] - mdct_pred[i]) * (mdct_in[i] - mdct_pred[i]);
|
||||
}
|
||||
|
||||
num_bit = 0.0;
|
||||
|
||||
for (i = 0; i < num_of_sfb; i++)
|
||||
{
|
||||
temp1 = 0.0;
|
||||
temp2 = 0.0;
|
||||
for (j = sfb_offset[i]; j < sfb_offset[i + 1]; j++)
|
||||
{
|
||||
temp1 += energy[j];
|
||||
temp2 += snr_p[j];
|
||||
}
|
||||
|
||||
if (temp2 < snr_limit)
|
||||
temp2 = snr_limit;
|
||||
|
||||
if (temp1 > 1.e-20)
|
||||
snr[i] = -10. * log10 (temp2 / temp1);
|
||||
else
|
||||
snr[i] = 0.0;
|
||||
|
||||
sfb_flag[i] = 1;
|
||||
|
||||
if (block_type != ONLY_SHORT_WINDOW)
|
||||
{
|
||||
if (snr[i] <= 0.0)
|
||||
{
|
||||
sfb_flag[i] = 0;
|
||||
for (j = sfb_offset[i]; j < sfb_offset[i + 1]; j++)
|
||||
mdct_pred[j] = 0.0;
|
||||
} else {
|
||||
num_bit += snr[i] / 6. * (sfb_offset[i + 1] - sfb_offset[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (num_bit < side_info)
|
||||
{
|
||||
// printf("LTP not used!, num_bit: %f ", num_bit);
|
||||
num_bit = 0.0;
|
||||
for (j = 0; j < flen; j++)
|
||||
mdct_pred[j] = 0.0;
|
||||
for (i = 0; i < num_of_sfb; i++)
|
||||
sfb_flag[i] = 0;
|
||||
} else {
|
||||
num_bit -= side_info;
|
||||
// printf("LTP used!, num_bit: %f ", num_bit);
|
||||
}
|
||||
|
||||
return (num_bit);
|
||||
}
|
||||
|
||||
static void prediction(double *buffer, double *predicted_samples, double *weight, int lag,
|
||||
int flen)
|
||||
{
|
||||
int i, offset;
|
||||
int num_samples;
|
||||
|
||||
offset = NOK_LT_BLEN - flen / 2 - lag;
|
||||
|
||||
num_samples = flen;
|
||||
if(NOK_LT_BLEN - offset < flen)
|
||||
num_samples = NOK_LT_BLEN - offset;
|
||||
|
||||
for(i = 0; i < num_samples; i++)
|
||||
predicted_samples[i] = *weight * _MDCT_SCALE*buffer[offset++];
|
||||
for( ; i < flen; i++)
|
||||
predicted_samples[i] = 0.0;
|
||||
|
||||
|
||||
}
|
||||
|
||||
static void w_quantize(double *freq, int *ltp_idx)
|
||||
{
|
||||
int i;
|
||||
double dist, low;
|
||||
|
||||
low = 1.0e+10;
|
||||
dist = 0.0;
|
||||
for (i = 0; i < CODESIZE; i++)
|
||||
{
|
||||
dist = (*freq - codebook[i]) * (*freq - codebook[i]);
|
||||
if (dist < low)
|
||||
{
|
||||
low = dist;
|
||||
*ltp_idx = i;
|
||||
}
|
||||
}
|
||||
|
||||
*freq = codebook[*ltp_idx];
|
||||
}
|
||||
|
||||
static int pitch(double *sb_samples, double *x_buffer, int flen, int lag0, int lag1,
|
||||
double *predicted_samples, double *gain, int *cb_idx)
|
||||
{
|
||||
int i, j, delay;
|
||||
double corr1, corr2, lag_corr;
|
||||
double p_max, energy, lag_energy;
|
||||
|
||||
/*
|
||||
* Below is a figure illustrating how the lag and the
|
||||
* samples in the buffer relate to each other.
|
||||
*
|
||||
* ------------------------------------------------------------------
|
||||
* | | | | |
|
||||
* | slot 1 | 2 | 3 | 4 |
|
||||
* | | | | |
|
||||
* ------------------------------------------------------------------
|
||||
*
|
||||
* lag = 0 refers to the end of slot 4 and lag = DELAY refers to the end
|
||||
* of slot 2. The start of the predicted frame is then obtained by
|
||||
* adding the length of the frame to the lag. Remember that slot 4 doesn't
|
||||
* actually exist, since it is always filled with zeros.
|
||||
*
|
||||
* The above short explanation was for long blocks. For short blocks the
|
||||
* zero lag doesn't refer to the end of slot 4 but to the start of slot
|
||||
* 4 - the frame length of a short block.
|
||||
*
|
||||
* Some extra code is then needed to handle those lag values that refer
|
||||
* to slot 4.
|
||||
*/
|
||||
|
||||
p_max = 0.0;
|
||||
lag_corr = lag_energy = 0.0;
|
||||
delay = lag0;
|
||||
|
||||
|
||||
for (i = lag0; i<lag1; i++)
|
||||
{
|
||||
energy = 0.0;
|
||||
corr1 = 0.0;
|
||||
for (j=0; j < flen; j++)
|
||||
{
|
||||
if (j < i+BLOCK_LEN_LONG)
|
||||
{
|
||||
corr1 += sb_samples[j] * _MDCT_SCALE * x_buffer[NOK_LT_BLEN - flen/2 - i + j];
|
||||
energy += _MDCT_SCALE * x_buffer[NOK_LT_BLEN - flen/2 - i + j] * _MDCT_SCALE * x_buffer[NOK_LT_BLEN - flen/2 - i + j];
|
||||
}
|
||||
}
|
||||
if (energy != 0.0)
|
||||
corr2 = corr1 / sqrt(energy);
|
||||
else
|
||||
corr2 = 0.0;
|
||||
|
||||
if (p_max < corr2)
|
||||
{
|
||||
p_max = corr2;
|
||||
delay = i;
|
||||
lag_corr = corr1;
|
||||
lag_energy = energy;
|
||||
}
|
||||
}
|
||||
/* Compute the gain. */
|
||||
if(lag_energy != 0.0)
|
||||
*gain = lag_corr / (1.010 * lag_energy);
|
||||
else
|
||||
*gain = 0.0;
|
||||
|
||||
/* Quantize the gain. */
|
||||
w_quantize(gain, cb_idx);
|
||||
// printf("Delay: %d, Coeff: %f", delay, *gain);
|
||||
|
||||
/* Get the predicted signal. */
|
||||
prediction(x_buffer, predicted_samples, gain, delay, flen);
|
||||
|
||||
|
||||
return (delay);
|
||||
}
|
||||
|
||||
static double ltp_enc_tf(faacEncHandle hEncoder,
|
||||
CoderInfo *coderInfo, double *p_spectrum, double *predicted_samples,
|
||||
double *mdct_predicted, int *sfb_offset,
|
||||
int num_of_sfb, int last_band, int side_info,
|
||||
int *sfb_prediction_used, TnsInfo *tnsInfo)
|
||||
{
|
||||
double bit_gain;
|
||||
|
||||
/* Transform prediction to frequency domain. */
|
||||
FilterBank(hEncoder, coderInfo, predicted_samples, mdct_predicted,
|
||||
NULL, MNON_OVERLAPPED);
|
||||
|
||||
/* Apply TNS analysis filter to the predicted spectrum. */
|
||||
if(tnsInfo != NULL)
|
||||
TnsEncodeFilterOnly(tnsInfo, num_of_sfb, num_of_sfb, coderInfo->block_type, sfb_offset,
|
||||
mdct_predicted);
|
||||
|
||||
/* Get the prediction gain. */
|
||||
bit_gain = snr_pred(p_spectrum, mdct_predicted, sfb_prediction_used,
|
||||
sfb_offset, side_info, last_band, coderInfo->nr_of_sfb);
|
||||
|
||||
return (bit_gain);
|
||||
}
|
||||
|
||||
void LtpInit(faacEncHandle hEncoder)
|
||||
{
|
||||
int i;
|
||||
unsigned int channel;
|
||||
|
||||
for (channel = 0; channel < hEncoder->numChannels; channel++) {
|
||||
LtpInfo *ltpInfo = &(hEncoder->coderInfo[channel].ltpInfo);
|
||||
|
||||
ltpInfo->buffer = AllocMemory(NOK_LT_BLEN * sizeof(double));
|
||||
ltpInfo->mdct_predicted = AllocMemory(2*BLOCK_LEN_LONG*sizeof(double));
|
||||
ltpInfo->time_buffer = AllocMemory(BLOCK_LEN_LONG*sizeof(double));
|
||||
ltpInfo->ltp_overlap_buffer = AllocMemory(BLOCK_LEN_LONG*sizeof(double));
|
||||
|
||||
for (i = 0; i < NOK_LT_BLEN; i++)
|
||||
ltpInfo->buffer[i] = 0;
|
||||
|
||||
ltpInfo->weight_idx = 0;
|
||||
for(i = 0; i < MAX_SHORT_WINDOWS; i++)
|
||||
ltpInfo->sbk_prediction_used[i] = ltpInfo->delay[i] = 0;
|
||||
|
||||
for(i = 0; i < MAX_SCFAC_BANDS; i++)
|
||||
ltpInfo->sfb_prediction_used[i] = 0;
|
||||
|
||||
ltpInfo->side_info = LEN_LTP_DATA_PRESENT;
|
||||
|
||||
for(i = 0; i < 2 * BLOCK_LEN_LONG; i++)
|
||||
ltpInfo->mdct_predicted[i] = 0.0;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
void LtpEnd(faacEncHandle hEncoder)
|
||||
{
|
||||
unsigned int channel;
|
||||
|
||||
for (channel = 0; channel < hEncoder->numChannels; channel++) {
|
||||
LtpInfo *ltpInfo = &(hEncoder->coderInfo[channel].ltpInfo);
|
||||
|
||||
if (ltpInfo->buffer)
|
||||
FreeMemory(ltpInfo->buffer);
|
||||
if (ltpInfo->mdct_predicted)
|
||||
FreeMemory(ltpInfo->mdct_predicted);
|
||||
if (ltpInfo->time_buffer)
|
||||
FreeMemory(ltpInfo->time_buffer);
|
||||
if (ltpInfo->ltp_overlap_buffer)
|
||||
FreeMemory(ltpInfo->ltp_overlap_buffer);
|
||||
}
|
||||
}
|
||||
|
||||
int LtpEncode(faacEncHandle hEncoder,
|
||||
CoderInfo *coderInfo,
|
||||
LtpInfo *ltpInfo,
|
||||
TnsInfo *tnsInfo,
|
||||
double *p_spectrum,
|
||||
double *p_time_signal)
|
||||
{
|
||||
int i, last_band;
|
||||
double num_bit[MAX_SHORT_WINDOWS];
|
||||
double *predicted_samples;
|
||||
|
||||
ltpInfo->global_pred_flag = 0;
|
||||
ltpInfo->side_info = 0;
|
||||
|
||||
predicted_samples = (double*)AllocMemory(2*BLOCK_LEN_LONG*sizeof(double));
|
||||
|
||||
switch(coderInfo->block_type)
|
||||
{
|
||||
case ONLY_LONG_WINDOW:
|
||||
case LONG_SHORT_WINDOW:
|
||||
case SHORT_LONG_WINDOW:
|
||||
last_band = (coderInfo->nr_of_sfb < MAX_LT_PRED_LONG_SFB) ? coderInfo->nr_of_sfb : MAX_LT_PRED_LONG_SFB;
|
||||
|
||||
ltpInfo->delay[0] =
|
||||
pitch(p_time_signal, ltpInfo->buffer, 2 * BLOCK_LEN_LONG,
|
||||
0, 2 * BLOCK_LEN_LONG, predicted_samples, <pInfo->weight,
|
||||
<pInfo->weight_idx);
|
||||
|
||||
|
||||
num_bit[0] =
|
||||
ltp_enc_tf(hEncoder, coderInfo, p_spectrum, predicted_samples,
|
||||
ltpInfo->mdct_predicted,
|
||||
coderInfo->sfb_offset, coderInfo->nr_of_sfb,
|
||||
last_band, ltpInfo->side_info, ltpInfo->sfb_prediction_used,
|
||||
tnsInfo);
|
||||
|
||||
|
||||
ltpInfo->global_pred_flag = (num_bit[0] == 0.0) ? 0 : 1;
|
||||
|
||||
if(ltpInfo->global_pred_flag)
|
||||
for (i = 0; i < coderInfo->sfb_offset[last_band]; i++)
|
||||
p_spectrum[i] -= ltpInfo->mdct_predicted[i];
|
||||
else
|
||||
ltpInfo->side_info = 1;
|
||||
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
if (predicted_samples) FreeMemory(predicted_samples);
|
||||
|
||||
return (ltpInfo->global_pred_flag);
|
||||
}
|
||||
|
||||
void LtpReconstruct(CoderInfo *coderInfo, LtpInfo *ltpInfo, double *p_spectrum)
|
||||
{
|
||||
int i, last_band;
|
||||
|
||||
if(ltpInfo->global_pred_flag)
|
||||
{
|
||||
switch(coderInfo->block_type)
|
||||
{
|
||||
case ONLY_LONG_WINDOW:
|
||||
case LONG_SHORT_WINDOW:
|
||||
case SHORT_LONG_WINDOW:
|
||||
last_band = (coderInfo->nr_of_sfb < MAX_LT_PRED_LONG_SFB) ?
|
||||
coderInfo->nr_of_sfb : MAX_LT_PRED_LONG_SFB;
|
||||
|
||||
for (i = 0; i < coderInfo->sfb_offset[last_band]; i++)
|
||||
p_spectrum[i] += ltpInfo->mdct_predicted[i];
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void LtpUpdate(LtpInfo *ltpInfo, double *time_signal,
|
||||
double *overlap_signal, int block_size_long)
|
||||
{
|
||||
int i;
|
||||
|
||||
for(i = 0; i < NOK_LT_BLEN - 2 * block_size_long; i++)
|
||||
ltpInfo->buffer[i] = ltpInfo->buffer[i + block_size_long];
|
||||
|
||||
for(i = 0; i < block_size_long; i++)
|
||||
{
|
||||
ltpInfo->buffer[NOK_LT_BLEN - 2 * block_size_long + i] = time_signal[i];
|
||||
ltpInfo->buffer[NOK_LT_BLEN - block_size_long + i] = overlap_signal[i];
|
||||
}
|
||||
}
|
48
external/libfaac/libfaac/ltp.h
vendored
Normal file
48
external/libfaac/libfaac/ltp.h
vendored
Normal file
|
@ -0,0 +1,48 @@
|
|||
/*
|
||||
Copyright (c) 2013-2016 EasyDarwin.ORG. All rights reserved.
|
||||
Github: https://github.com/EasyDarwin
|
||||
WEChat: EasyDarwin
|
||||
Website: http://www.easydarwin.org
|
||||
*/
|
||||
/*
|
||||
* FAAC - Freeware Advanced Audio Coder
|
||||
* Copyright (C) 2001 Menno Bakker
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
* $Id: ltp.h,v 1.3 2001/06/08 18:01:09 menno Exp $
|
||||
*/
|
||||
|
||||
#ifndef LTP_H
|
||||
#define LTP_H
|
||||
|
||||
#include "coder.h"
|
||||
|
||||
|
||||
|
||||
void LtpInit(faacEncHandle hEncoder);
|
||||
void LtpEnd(faacEncHandle hEncoder);
|
||||
int LtpEncode(faacEncHandle hEncoder,
|
||||
CoderInfo *coderInfo,
|
||||
LtpInfo *ltpInfo,
|
||||
TnsInfo *tnsInfo,
|
||||
double *p_spectrum,
|
||||
double *p_time_signal);
|
||||
void LtpReconstruct(CoderInfo *coderInfo, LtpInfo *ltpInfo, double *p_spectrum);
|
||||
void LtpUpdate(LtpInfo *ltpInfo, double *time_signal,
|
||||
double *overlap_signal, int block_size_long);
|
||||
|
||||
#endif /* not defined LTP_H */
|
||||
|
169
external/libfaac/libfaac/midside.c
vendored
Normal file
169
external/libfaac/libfaac/midside.c
vendored
Normal file
|
@ -0,0 +1,169 @@
|
|||
/*
|
||||
* FAAC - Freeware Advanced Audio Coder
|
||||
* Copyright (C) 2003 Krzysztof Nikiel
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
* $Id: midside.c,v 1.1 2003/06/26 19:39:54 knik Exp $
|
||||
*/
|
||||
|
||||
#include <math.h>
|
||||
#include "channels.h"
|
||||
#include "util.h"
|
||||
|
||||
|
||||
void MSEncode(CoderInfo *coderInfo,
|
||||
ChannelInfo *channelInfo,
|
||||
double *spectrum[MAX_CHANNELS],
|
||||
int maxchan,
|
||||
int allowms)
|
||||
{
|
||||
int chn;
|
||||
|
||||
for (chn = 0; chn < maxchan; chn++)
|
||||
{
|
||||
if (channelInfo[chn].present)
|
||||
{
|
||||
if ((channelInfo[chn].cpe) && (channelInfo[chn].ch_is_left))
|
||||
{
|
||||
int rch = channelInfo[chn].paired_ch;
|
||||
|
||||
channelInfo[chn].msInfo.is_present = 0;
|
||||
channelInfo[rch].msInfo.is_present = 0;
|
||||
|
||||
/* Perform MS if block_types are the same */
|
||||
if ((coderInfo[chn].block_type == coderInfo[rch].block_type)
|
||||
&& allowms)
|
||||
{
|
||||
int nsfb = coderInfo[chn].nr_of_sfb;
|
||||
MSInfo *msInfoL = &(channelInfo[chn].msInfo);
|
||||
MSInfo *msInfoR = &(channelInfo[rch].msInfo);
|
||||
int sfb;
|
||||
|
||||
channelInfo[chn].common_window = 1; /* Use common window */
|
||||
channelInfo[chn].msInfo.is_present = 1;
|
||||
channelInfo[rch].msInfo.is_present = 1;
|
||||
|
||||
// make the same reference energy in both channels
|
||||
coderInfo[chn].avgenrg = coderInfo[rch].avgenrg =
|
||||
0.5 * (coderInfo[chn].avgenrg + coderInfo[rch].avgenrg);
|
||||
|
||||
for (sfb = 0; sfb < nsfb; sfb++)
|
||||
{
|
||||
int ms = 0;
|
||||
int l, start, end;
|
||||
double sum, diff;
|
||||
double enrgs, enrgd, enrgl, enrgr;
|
||||
double maxs, maxd, maxl, maxr;
|
||||
|
||||
start = coderInfo[chn].sfb_offset[sfb];
|
||||
end = coderInfo[chn].sfb_offset[sfb + 1];
|
||||
|
||||
enrgs = enrgd = enrgl = enrgr = 0.0;
|
||||
maxs = maxd = maxl = maxr = 0.0;
|
||||
for (l = start; l < end; l++)
|
||||
{
|
||||
double lx = spectrum[chn][l];
|
||||
double rx = spectrum[rch][l];
|
||||
|
||||
sum = 0.5 * (lx + rx);
|
||||
diff = 0.5 * (lx - rx);
|
||||
|
||||
enrgs += sum * sum;
|
||||
maxs = max(maxs, fabs(sum));
|
||||
|
||||
enrgd += diff * diff;
|
||||
maxd = max(maxd, fabs(diff));
|
||||
|
||||
enrgl += lx * lx;
|
||||
enrgr += rx * rx;
|
||||
|
||||
maxl = max(maxl, fabs(lx));
|
||||
maxr = max(maxr, fabs(rx));
|
||||
}
|
||||
|
||||
#if 1
|
||||
if ((min(enrgs, enrgd) < min(enrgl, enrgr))
|
||||
&& (min(maxs, maxd) < min(maxl, maxr)))
|
||||
ms = 1;
|
||||
#else
|
||||
if (min(enrgs, enrgd) < min(enrgl, enrgr))
|
||||
ms = 1;
|
||||
#endif
|
||||
|
||||
//printf("%d:%d\n", sfb, ms);
|
||||
|
||||
msInfoR->ms_used[sfb] = msInfoL->ms_used[sfb] = ms;
|
||||
|
||||
if (ms)
|
||||
for (l = start; l < end; l++)
|
||||
{
|
||||
sum = spectrum[chn][l] + spectrum[rch][l];
|
||||
diff = spectrum[chn][l] - spectrum[rch][l];
|
||||
spectrum[chn][l] = 0.5 * sum;
|
||||
spectrum[rch][l] = 0.5 * diff;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void MSReconstruct(CoderInfo *coderInfo,
|
||||
ChannelInfo *channelInfo,
|
||||
int maxchan)
|
||||
{
|
||||
int chn;
|
||||
|
||||
for (chn = 0; chn < maxchan; chn++)
|
||||
{
|
||||
if (channelInfo[chn].present)
|
||||
{
|
||||
if (channelInfo[chn].cpe && channelInfo[chn].ch_is_left)
|
||||
{
|
||||
int rch = channelInfo[chn].paired_ch;
|
||||
|
||||
MSInfo *msInfoL = &(channelInfo[chn].msInfo);
|
||||
|
||||
if (msInfoL->is_present) {
|
||||
int nsfb = coderInfo[chn].nr_of_sfb;
|
||||
int sfb;
|
||||
|
||||
for (sfb = 0; sfb < nsfb; sfb++)
|
||||
{
|
||||
int l, start, end;
|
||||
|
||||
start = coderInfo[chn].sfb_offset[sfb];
|
||||
end = coderInfo[chn].sfb_offset[sfb + 1];
|
||||
|
||||
if (msInfoL->ms_used[sfb])
|
||||
{
|
||||
for (l = start; l < end; l++)
|
||||
{
|
||||
double sum, diff;
|
||||
|
||||
sum = coderInfo[chn].requantFreq[l];
|
||||
diff = coderInfo[rch].requantFreq[l];
|
||||
coderInfo[chn].requantFreq[l] = sum + diff;
|
||||
coderInfo[rch].requantFreq[l] = sum - diff;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
40
external/libfaac/libfaac/midside.h
vendored
Normal file
40
external/libfaac/libfaac/midside.h
vendored
Normal file
|
@ -0,0 +1,40 @@
|
|||
/*
|
||||
* FAAC - Freeware Advanced Audio Coder
|
||||
* Copyright (C) 2003 Krzysztof Nikiel
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
* $Id: midside.h,v 1.1 2003/06/26 19:40:23 knik Exp $
|
||||
*/
|
||||
|
||||
#ifndef _MIDSIDE_H
|
||||
#define _MIDSIDE_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif /* __cplusplus */
|
||||
|
||||
#include "coder.h"
|
||||
|
||||
|
||||
void MSEncode(CoderInfo *coderInfo, ChannelInfo *channelInfo, double *spectrum[MAX_CHANNELS],
|
||||
unsigned int numberOfChannels, unsigned int msenable);
|
||||
void MSReconstruct(CoderInfo *coderInfo, ChannelInfo *channelInfo, int numberOfChannels);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif /* __cplusplus */
|
||||
|
||||
#endif /* _MIDSIDE_H */
|
85
external/libfaac/libfaac/psych.h
vendored
Normal file
85
external/libfaac/libfaac/psych.h
vendored
Normal file
|
@ -0,0 +1,85 @@
|
|||
/*
|
||||
* FAAC - Freeware Advanced Audio Coder
|
||||
* Copyright (C) 2001 Menno Bakker
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
* $Id: psych.h,v 1.14 2005/04/24 19:16:14 rjamorim Exp $
|
||||
*/
|
||||
|
||||
#ifndef PSYCH_H
|
||||
#define PSYCH_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif /* __cplusplus */
|
||||
|
||||
#ifndef M_PI
|
||||
#define M_PI 3.14159265358979323846
|
||||
#endif
|
||||
|
||||
#include "coder.h"
|
||||
#include "channels.h"
|
||||
#include "fft.h"
|
||||
|
||||
typedef struct {
|
||||
int size;
|
||||
int sizeS;
|
||||
|
||||
/* Previous input samples */
|
||||
double *prevSamples;
|
||||
double *prevSamplesS;
|
||||
|
||||
int block_type;
|
||||
|
||||
void *data;
|
||||
} PsyInfo;
|
||||
|
||||
typedef struct {
|
||||
double sampleRate;
|
||||
|
||||
/* Hann window */
|
||||
double *hannWindow;
|
||||
double *hannWindowS;
|
||||
|
||||
void *data;
|
||||
} GlobalPsyInfo;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
void (*PsyInit) (GlobalPsyInfo *gpsyInfo, PsyInfo *psyInfo,
|
||||
unsigned int numChannels, unsigned int sampleRate,
|
||||
int *cb_width_long, int num_cb_long,
|
||||
int *cb_width_short, int num_cb_short);
|
||||
void (*PsyEnd) (GlobalPsyInfo *gpsyInfo, PsyInfo *psyInfo,
|
||||
unsigned int numChannels);
|
||||
void (*PsyCalculate) (ChannelInfo *channelInfo, GlobalPsyInfo *gpsyInfo,
|
||||
PsyInfo *psyInfo, int *cb_width_long, int num_cb_long,
|
||||
int *cb_width_short, int num_cb_short,
|
||||
unsigned int numChannels);
|
||||
void (*PsyBufferUpdate) ( FFT_Tables *fft_tables, GlobalPsyInfo * gpsyInfo, PsyInfo * psyInfo,
|
||||
double *newSamples, unsigned int bandwidth,
|
||||
int *cb_width_short, int num_cb_short);
|
||||
void (*BlockSwitch) (CoderInfo *coderInfo, PsyInfo *psyInfo,
|
||||
unsigned int numChannels);
|
||||
} psymodel_t;
|
||||
|
||||
extern psymodel_t psymodel2;
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif /* __cplusplus */
|
||||
|
||||
#endif /* PSYCH_H */
|
450
external/libfaac/libfaac/psychkni.c
vendored
Normal file
450
external/libfaac/libfaac/psychkni.c
vendored
Normal file
|
@ -0,0 +1,450 @@
|
|||
/*
|
||||
* FAAC - Freeware Advanced Audio Coder
|
||||
* Copyright (C) 2002 Krzysztof Nikiel
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
* $Id: psychkni.c,v 1.17 2005/04/24 19:16:14 rjamorim Exp $
|
||||
*/
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <math.h>
|
||||
|
||||
#include "psych.h"
|
||||
#include "coder.h"
|
||||
#include "fft.h"
|
||||
#include "util.h"
|
||||
#include "frame.h"
|
||||
|
||||
typedef float psyfloat;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
/* bandwidth */
|
||||
int bandS;
|
||||
int lastband;
|
||||
|
||||
/* SFB energy */
|
||||
psyfloat *fftEnrgS[8];
|
||||
psyfloat *fftEnrgNextS[8];
|
||||
psyfloat *fftEnrgNext2S[8];
|
||||
psyfloat *fftEnrgPrevS[8];
|
||||
}
|
||||
psydata_t;
|
||||
|
||||
|
||||
static void Hann(GlobalPsyInfo * gpsyInfo, double *inSamples, int size)
|
||||
{
|
||||
int i;
|
||||
|
||||
/* Applying Hann window */
|
||||
if (size == BLOCK_LEN_LONG * 2)
|
||||
{
|
||||
for (i = 0; i < size; i++)
|
||||
inSamples[i] *= gpsyInfo->hannWindow[i];
|
||||
}
|
||||
else
|
||||
{
|
||||
for (i = 0; i < size; i++)
|
||||
inSamples[i] *= gpsyInfo->hannWindowS[i];
|
||||
}
|
||||
}
|
||||
|
||||
static void PsyCheckShort(PsyInfo * psyInfo)
|
||||
{
|
||||
double totvol = 0.0;
|
||||
double totchg, totchg2;
|
||||
psydata_t *psydata = psyInfo->data;
|
||||
int lastband = psydata->lastband;
|
||||
int firstband = 1;
|
||||
int sfb;
|
||||
|
||||
/* long/short block switch */
|
||||
totchg = totchg2 = 0.0;
|
||||
for (sfb = 0; sfb < lastband; sfb++)
|
||||
{
|
||||
int win;
|
||||
double volb[16];
|
||||
double vavg[13];
|
||||
double maxdif = 0.0;
|
||||
double totmaxdif = 0.0;
|
||||
double e, v;
|
||||
|
||||
// previous frame
|
||||
for (win = 0; win < 4; win++)
|
||||
{
|
||||
e = psydata->fftEnrgPrevS[win + 4][sfb];
|
||||
|
||||
volb[win] = sqrt(e);
|
||||
totvol += e;
|
||||
}
|
||||
|
||||
// current frame
|
||||
for (win = 0; win < 8; win++)
|
||||
{
|
||||
e = psydata->fftEnrgS[win][sfb];
|
||||
|
||||
volb[win + 4] = sqrt(e);
|
||||
totvol += e;
|
||||
}
|
||||
// next frame
|
||||
for (win = 0; win < 4; win++)
|
||||
{
|
||||
e = psydata->fftEnrgNextS[win][sfb];
|
||||
|
||||
volb[win + 12] = sqrt(e);
|
||||
totvol += e;
|
||||
}
|
||||
|
||||
// ignore lowest SFBs
|
||||
if (sfb < firstband)
|
||||
continue;
|
||||
|
||||
v = 0.0;
|
||||
for (win = 0; win < 4; win++)
|
||||
{
|
||||
v += volb[win];
|
||||
}
|
||||
vavg[0] = 0.25 * v;
|
||||
|
||||
for (win = 1; win < 13; win++)
|
||||
{
|
||||
v -= volb[win - 1];
|
||||
v += volb[win + 3];
|
||||
vavg[win] = 0.25 * v;
|
||||
}
|
||||
|
||||
for (win = 0; win < 8; win++)
|
||||
{
|
||||
int i;
|
||||
double mina, maxv;
|
||||
double voldif;
|
||||
double totvoldif;
|
||||
|
||||
mina = vavg[win];
|
||||
for (i = 1; i < 5; i++)
|
||||
mina = min(mina, vavg[win + i]);
|
||||
|
||||
maxv = volb[win + 2];
|
||||
for (i = 3; i < 6; i++)
|
||||
maxv = max(maxv, volb[win + i]);
|
||||
|
||||
if (!maxv || !mina)
|
||||
continue;
|
||||
|
||||
voldif = (maxv - mina) / mina;
|
||||
totvoldif = (maxv - mina) * (maxv - mina);
|
||||
|
||||
if (voldif > maxdif)
|
||||
maxdif = voldif;
|
||||
|
||||
if (totvoldif > totmaxdif)
|
||||
totmaxdif = totvoldif;
|
||||
}
|
||||
totchg += maxdif;
|
||||
totchg2 += totmaxdif;
|
||||
}
|
||||
|
||||
totvol = sqrt(totvol);
|
||||
|
||||
totchg2 = sqrt(totchg2);
|
||||
|
||||
totchg = totchg / lastband;
|
||||
if (totvol)
|
||||
totchg2 /= totvol;
|
||||
else
|
||||
totchg2 = 0.0;
|
||||
|
||||
psyInfo->block_type = ((totchg > 1.0) && (totchg2 > 0.04))
|
||||
? ONLY_SHORT_WINDOW : ONLY_LONG_WINDOW;
|
||||
|
||||
#if 0
|
||||
{
|
||||
static int total = 0, shorts = 0;
|
||||
char *flash = " ";
|
||||
|
||||
total++;
|
||||
if (psyInfo->block_type == ONLY_SHORT_WINDOW)
|
||||
{
|
||||
flash = "****";
|
||||
shorts++;
|
||||
}
|
||||
|
||||
printf("totchg: %s %g %g\t%g\n", flash, totchg, totchg2,
|
||||
(double)shorts/total);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
static void PsyInit(GlobalPsyInfo * gpsyInfo, PsyInfo * psyInfo, unsigned int numChannels,
|
||||
unsigned int sampleRate, int *cb_width_long, int num_cb_long,
|
||||
int *cb_width_short, int num_cb_short)
|
||||
{
|
||||
unsigned int channel;
|
||||
int i, j, size;
|
||||
|
||||
gpsyInfo->hannWindow =
|
||||
(double *) AllocMemory(2 * BLOCK_LEN_LONG * sizeof(double));
|
||||
gpsyInfo->hannWindowS =
|
||||
(double *) AllocMemory(2 * BLOCK_LEN_SHORT * sizeof(double));
|
||||
|
||||
for (i = 0; i < BLOCK_LEN_LONG * 2; i++)
|
||||
gpsyInfo->hannWindow[i] = 0.5 * (1 - cos(2.0 * M_PI * (i + 0.5) /
|
||||
(BLOCK_LEN_LONG * 2)));
|
||||
for (i = 0; i < BLOCK_LEN_SHORT * 2; i++)
|
||||
gpsyInfo->hannWindowS[i] = 0.5 * (1 - cos(2.0 * M_PI * (i + 0.5) /
|
||||
(BLOCK_LEN_SHORT * 2)));
|
||||
gpsyInfo->sampleRate = (double) sampleRate;
|
||||
|
||||
for (channel = 0; channel < numChannels; channel++)
|
||||
{
|
||||
psydata_t *psydata = AllocMemory(sizeof(psydata_t));
|
||||
psyInfo[channel].data = psydata;
|
||||
}
|
||||
|
||||
size = BLOCK_LEN_LONG;
|
||||
for (channel = 0; channel < numChannels; channel++)
|
||||
{
|
||||
psyInfo[channel].size = size;
|
||||
|
||||
psyInfo[channel].prevSamples =
|
||||
(double *) AllocMemory(size * sizeof(double));
|
||||
memset(psyInfo[channel].prevSamples, 0, size * sizeof(double));
|
||||
}
|
||||
|
||||
size = BLOCK_LEN_SHORT;
|
||||
for (channel = 0; channel < numChannels; channel++)
|
||||
{
|
||||
psydata_t *psydata = psyInfo[channel].data;
|
||||
|
||||
psyInfo[channel].sizeS = size;
|
||||
|
||||
psyInfo[channel].prevSamplesS =
|
||||
(double *) AllocMemory(size * sizeof(double));
|
||||
memset(psyInfo[channel].prevSamplesS, 0, size * sizeof(double));
|
||||
|
||||
for (j = 0; j < 8; j++)
|
||||
{
|
||||
psydata->fftEnrgPrevS[j] =
|
||||
(psyfloat *) AllocMemory(NSFB_SHORT * sizeof(psyfloat));
|
||||
memset(psydata->fftEnrgPrevS[j], 0, NSFB_SHORT * sizeof(psyfloat));
|
||||
psydata->fftEnrgS[j] =
|
||||
(psyfloat *) AllocMemory(NSFB_SHORT * sizeof(psyfloat));
|
||||
memset(psydata->fftEnrgS[j], 0, NSFB_SHORT * sizeof(psyfloat));
|
||||
psydata->fftEnrgNextS[j] =
|
||||
(psyfloat *) AllocMemory(NSFB_SHORT * sizeof(psyfloat));
|
||||
memset(psydata->fftEnrgNextS[j], 0, NSFB_SHORT * sizeof(psyfloat));
|
||||
psydata->fftEnrgNext2S[j] =
|
||||
(psyfloat *) AllocMemory(NSFB_SHORT * sizeof(psyfloat));
|
||||
memset(psydata->fftEnrgNext2S[j], 0, NSFB_SHORT * sizeof(psyfloat));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void PsyEnd(GlobalPsyInfo * gpsyInfo, PsyInfo * psyInfo, unsigned int numChannels)
|
||||
{
|
||||
unsigned int channel;
|
||||
int j;
|
||||
|
||||
if (gpsyInfo->hannWindow)
|
||||
FreeMemory(gpsyInfo->hannWindow);
|
||||
if (gpsyInfo->hannWindowS)
|
||||
FreeMemory(gpsyInfo->hannWindowS);
|
||||
|
||||
for (channel = 0; channel < numChannels; channel++)
|
||||
{
|
||||
if (psyInfo[channel].prevSamples)
|
||||
FreeMemory(psyInfo[channel].prevSamples);
|
||||
}
|
||||
|
||||
for (channel = 0; channel < numChannels; channel++)
|
||||
{
|
||||
psydata_t *psydata = psyInfo[channel].data;
|
||||
|
||||
if (psyInfo[channel].prevSamplesS)
|
||||
FreeMemory(psyInfo[channel].prevSamplesS);
|
||||
for (j = 0; j < 8; j++)
|
||||
{
|
||||
if (psydata->fftEnrgPrevS[j])
|
||||
FreeMemory(psydata->fftEnrgPrevS[j]);
|
||||
if (psydata->fftEnrgS[j])
|
||||
FreeMemory(psydata->fftEnrgS[j]);
|
||||
if (psydata->fftEnrgNextS[j])
|
||||
FreeMemory(psydata->fftEnrgNextS[j]);
|
||||
if (psydata->fftEnrgNext2S[j])
|
||||
FreeMemory(psydata->fftEnrgNext2S[j]);
|
||||
}
|
||||
}
|
||||
|
||||
for (channel = 0; channel < numChannels; channel++)
|
||||
{
|
||||
if (psyInfo[channel].data)
|
||||
FreeMemory(psyInfo[channel].data);
|
||||
}
|
||||
}
|
||||
|
||||
/* Do psychoacoustical analysis */
|
||||
static void PsyCalculate(ChannelInfo * channelInfo, GlobalPsyInfo * gpsyInfo,
|
||||
PsyInfo * psyInfo, int *cb_width_long, int
|
||||
num_cb_long, int *cb_width_short,
|
||||
int num_cb_short, unsigned int numChannels)
|
||||
{
|
||||
unsigned int channel;
|
||||
|
||||
for (channel = 0; channel < numChannels; channel++)
|
||||
{
|
||||
if (channelInfo[channel].present)
|
||||
{
|
||||
|
||||
if (channelInfo[channel].cpe &&
|
||||
channelInfo[channel].ch_is_left)
|
||||
{ /* CPE */
|
||||
|
||||
int leftChan = channel;
|
||||
int rightChan = channelInfo[channel].paired_ch;
|
||||
|
||||
PsyCheckShort(&psyInfo[leftChan]);
|
||||
PsyCheckShort(&psyInfo[rightChan]);
|
||||
}
|
||||
else if (!channelInfo[channel].cpe &&
|
||||
channelInfo[channel].lfe)
|
||||
{ /* LFE */
|
||||
// Only set block type and it should be OK
|
||||
psyInfo[channel].block_type = ONLY_LONG_WINDOW;
|
||||
}
|
||||
else if (!channelInfo[channel].cpe)
|
||||
{ /* SCE */
|
||||
PsyCheckShort(&psyInfo[channel]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void PsyBufferUpdate( FFT_Tables *fft_tables, GlobalPsyInfo * gpsyInfo, PsyInfo * psyInfo,
|
||||
double *newSamples, unsigned int bandwidth,
|
||||
int *cb_width_short, int num_cb_short)
|
||||
{
|
||||
int win;
|
||||
double transBuff[2 * BLOCK_LEN_LONG];
|
||||
double transBuffS[2 * BLOCK_LEN_SHORT];
|
||||
psydata_t *psydata = psyInfo->data;
|
||||
psyfloat *tmp;
|
||||
int sfb;
|
||||
|
||||
psydata->bandS = psyInfo->sizeS * bandwidth * 2 / gpsyInfo->sampleRate;
|
||||
|
||||
memcpy(transBuff, psyInfo->prevSamples, psyInfo->size * sizeof(double));
|
||||
memcpy(transBuff + psyInfo->size, newSamples, psyInfo->size * sizeof(double));
|
||||
|
||||
for (win = 0; win < 8; win++)
|
||||
{
|
||||
int first = 0;
|
||||
int last = 0;
|
||||
|
||||
memcpy(transBuffS, transBuff + (win * BLOCK_LEN_SHORT) + (BLOCK_LEN_LONG - BLOCK_LEN_SHORT) / 2,
|
||||
2 * psyInfo->sizeS * sizeof(double));
|
||||
|
||||
Hann(gpsyInfo, transBuffS, 2 * psyInfo->sizeS);
|
||||
rfft( fft_tables, transBuffS, 8);
|
||||
|
||||
// shift bufs
|
||||
tmp = psydata->fftEnrgPrevS[win];
|
||||
psydata->fftEnrgPrevS[win] = psydata->fftEnrgS[win];
|
||||
psydata->fftEnrgS[win] = psydata->fftEnrgNextS[win];
|
||||
psydata->fftEnrgNextS[win] = psydata->fftEnrgNext2S[win];
|
||||
psydata->fftEnrgNext2S[win] = tmp;
|
||||
|
||||
for (sfb = 0; sfb < num_cb_short; sfb++)
|
||||
{
|
||||
double e;
|
||||
int l;
|
||||
|
||||
first = last;
|
||||
last = first + cb_width_short[sfb];
|
||||
|
||||
if (first < 1)
|
||||
first = 1;
|
||||
|
||||
//if (last > psydata->bandS) // band out of range
|
||||
if (first >= psydata->bandS) // band out of range
|
||||
break;
|
||||
|
||||
e = 0.0;
|
||||
for (l = first; l < last; l++)
|
||||
{
|
||||
double a = transBuffS[l];
|
||||
double b = transBuffS[l + psyInfo->sizeS];
|
||||
|
||||
e += a * a + b * b;
|
||||
}
|
||||
|
||||
psydata->fftEnrgNext2S[win][sfb] = e;
|
||||
}
|
||||
psydata->lastband = sfb;
|
||||
for (; sfb < num_cb_short; sfb++)
|
||||
{
|
||||
psydata->fftEnrgNext2S[win][sfb] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
memcpy(psyInfo->prevSamples, newSamples, psyInfo->size * sizeof(double));
|
||||
}
|
||||
|
||||
static void BlockSwitch(CoderInfo * coderInfo, PsyInfo * psyInfo, unsigned int numChannels)
|
||||
{
|
||||
unsigned int channel;
|
||||
int desire = ONLY_LONG_WINDOW;
|
||||
|
||||
/* Use the same block type for all channels
|
||||
If there is 1 channel that wants a short block,
|
||||
use a short block on all channels.
|
||||
*/
|
||||
for (channel = 0; channel < numChannels; channel++)
|
||||
{
|
||||
if (psyInfo[channel].block_type == ONLY_SHORT_WINDOW)
|
||||
desire = ONLY_SHORT_WINDOW;
|
||||
}
|
||||
|
||||
for (channel = 0; channel < numChannels; channel++)
|
||||
{
|
||||
int lasttype = coderInfo[channel].block_type;
|
||||
|
||||
if (desire == ONLY_SHORT_WINDOW
|
||||
|| coderInfo[channel].desired_block_type == ONLY_SHORT_WINDOW)
|
||||
{
|
||||
if (lasttype == ONLY_LONG_WINDOW || lasttype == SHORT_LONG_WINDOW)
|
||||
coderInfo[channel].block_type = LONG_SHORT_WINDOW;
|
||||
else
|
||||
coderInfo[channel].block_type = ONLY_SHORT_WINDOW;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (lasttype == ONLY_SHORT_WINDOW || lasttype == LONG_SHORT_WINDOW)
|
||||
coderInfo[channel].block_type = SHORT_LONG_WINDOW;
|
||||
else
|
||||
coderInfo[channel].block_type = ONLY_LONG_WINDOW;
|
||||
}
|
||||
coderInfo[channel].desired_block_type = desire;
|
||||
}
|
||||
}
|
||||
|
||||
psymodel_t psymodel2 =
|
||||
{
|
||||
PsyInit,
|
||||
PsyEnd,
|
||||
PsyCalculate,
|
||||
PsyBufferUpdate,
|
||||
BlockSwitch
|
||||
};
|
609
external/libfaac/libfaac/tns.c
vendored
Normal file
609
external/libfaac/libfaac/tns.c
vendored
Normal file
|
@ -0,0 +1,609 @@
|
|||
/**********************************************************************
|
||||
|
||||
This software module was originally developed by Texas Instruments
|
||||
and edited by in the course of
|
||||
development of the MPEG-2 NBC/MPEG-4 Audio standard
|
||||
ISO/IEC 13818-7, 14496-1,2 and 3. This software module is an
|
||||
implementation of a part of one or more MPEG-2 NBC/MPEG-4 Audio tools
|
||||
as specified by the MPEG-2 NBC/MPEG-4 Audio standard. ISO/IEC gives
|
||||
users of the MPEG-2 NBC/MPEG-4 Audio standards free license to this
|
||||
software module or modifications thereof for use in hardware or
|
||||
software products claiming conformance to the MPEG-2 NBC/ MPEG-4 Audio
|
||||
standards. Those intending to use this software module in hardware or
|
||||
software products are advised that this use may infringe existing
|
||||
patents. The original developer of this software module and his/her
|
||||
company, the subsequent editors and their companies, and ISO/IEC have
|
||||
no liability for use of this software module or modifications thereof
|
||||
in an implementation. Copyright is not released for non MPEG-2
|
||||
NBC/MPEG-4 Audio conforming products. The original developer retains
|
||||
full right to use the code for his/her own purpose, assign or donate
|
||||
the code to a third party and to inhibit third party from using the
|
||||
code for non MPEG-2 NBC/MPEG-4 Audio conforming products. This
|
||||
copyright notice must be included in all copies or derivative works.
|
||||
|
||||
Copyright (c) 1997.
|
||||
**********************************************************************/
|
||||
/*
|
||||
* $Id: tns.c,v 1.10 2003/11/24 18:08:28 knik Exp $
|
||||
*/
|
||||
|
||||
#include <math.h>
|
||||
#include "frame.h"
|
||||
#include "coder.h"
|
||||
#include "bitstream.h"
|
||||
#include "tns.h"
|
||||
#include "util.h"
|
||||
|
||||
/***********************************************/
|
||||
/* TNS Profile/Frequency Dependent Parameters */
|
||||
/***********************************************/
|
||||
static unsigned long tnsSupportedSamplingRates[13] =
|
||||
{ 96000,88200,64000,48000,44100,32000,24000,22050,16000,12000,11025,8000,0 };
|
||||
|
||||
/* Limit bands to > 2.0 kHz */
|
||||
static unsigned short tnsMinBandNumberLong[12] =
|
||||
{ 11, 12, 15, 16, 17, 20, 25, 26, 24, 28, 30, 31 };
|
||||
static unsigned short tnsMinBandNumberShort[12] =
|
||||
{ 2, 2, 2, 3, 3, 4, 6, 6, 8, 10, 10, 12 };
|
||||
|
||||
/**************************************/
|
||||
/* Main/Low Profile TNS Parameters */
|
||||
/**************************************/
|
||||
static unsigned short tnsMaxBandsLongMainLow[12] =
|
||||
{ 31, 31, 34, 40, 42, 51, 46, 46, 42, 42, 42, 39 };
|
||||
|
||||
static unsigned short tnsMaxBandsShortMainLow[12] =
|
||||
{ 9, 9, 10, 14, 14, 14, 14, 14, 14, 14, 14, 14 };
|
||||
|
||||
static unsigned short tnsMaxOrderLongMain = 20;
|
||||
static unsigned short tnsMaxOrderLongLow = 12;
|
||||
static unsigned short tnsMaxOrderShortMainLow = 7;
|
||||
|
||||
|
||||
/*************************/
|
||||
/* Function prototypes */
|
||||
/*************************/
|
||||
static void Autocorrelation(int maxOrder, /* Maximum autocorr order */
|
||||
int dataSize, /* Size of the data array */
|
||||
double* data, /* Data array */
|
||||
double* rArray); /* Autocorrelation array */
|
||||
|
||||
static double LevinsonDurbin(int maxOrder, /* Maximum filter order */
|
||||
int dataSize, /* Size of the data array */
|
||||
double* data, /* Data array */
|
||||
double* kArray); /* Reflection coeff array */
|
||||
|
||||
static void StepUp(int fOrder, double* kArray, double* aArray);
|
||||
|
||||
static void QuantizeReflectionCoeffs(int fOrder,int coeffRes,double* rArray,int* indexArray);
|
||||
static int TruncateCoeffs(int fOrder,double threshold,double* kArray);
|
||||
static void TnsFilter(int length,double* spec,TnsFilterData* filter);
|
||||
static void TnsInvFilter(int length,double* spec,TnsFilterData* filter);
|
||||
|
||||
|
||||
/*****************************************************/
|
||||
/* InitTns: */
|
||||
/*****************************************************/
|
||||
void TnsInit(faacEncHandle hEncoder)
|
||||
{
|
||||
unsigned int channel;
|
||||
int fsIndex = hEncoder->sampleRateIdx;
|
||||
int profile = hEncoder->config.aacObjectType;
|
||||
|
||||
for (channel = 0; channel < hEncoder->numChannels; channel++) {
|
||||
TnsInfo *tnsInfo = &hEncoder->coderInfo[channel].tnsInfo;
|
||||
|
||||
switch( profile ) {
|
||||
case MAIN:
|
||||
case LTP:
|
||||
tnsInfo->tnsMaxBandsLong = tnsMaxBandsLongMainLow[fsIndex];
|
||||
tnsInfo->tnsMaxBandsShort = tnsMaxBandsShortMainLow[fsIndex];
|
||||
if (hEncoder->config.mpegVersion == 1) { /* MPEG2 */
|
||||
tnsInfo->tnsMaxOrderLong = tnsMaxOrderLongMain;
|
||||
} else { /* MPEG4 */
|
||||
if (fsIndex <= 5) /* fs > 32000Hz */
|
||||
tnsInfo->tnsMaxOrderLong = 12;
|
||||
else
|
||||
tnsInfo->tnsMaxOrderLong = 20;
|
||||
}
|
||||
tnsInfo->tnsMaxOrderShort = tnsMaxOrderShortMainLow;
|
||||
break;
|
||||
case LOW :
|
||||
tnsInfo->tnsMaxBandsLong = tnsMaxBandsLongMainLow[fsIndex];
|
||||
tnsInfo->tnsMaxBandsShort = tnsMaxBandsShortMainLow[fsIndex];
|
||||
if (hEncoder->config.mpegVersion == 1) { /* MPEG2 */
|
||||
tnsInfo->tnsMaxOrderLong = tnsMaxOrderLongLow;
|
||||
} else { /* MPEG4 */
|
||||
if (fsIndex <= 5) /* fs > 32000Hz */
|
||||
tnsInfo->tnsMaxOrderLong = 12;
|
||||
else
|
||||
tnsInfo->tnsMaxOrderLong = 20;
|
||||
}
|
||||
tnsInfo->tnsMaxOrderShort = tnsMaxOrderShortMainLow;
|
||||
break;
|
||||
}
|
||||
tnsInfo->tnsMinBandNumberLong = tnsMinBandNumberLong[fsIndex];
|
||||
tnsInfo->tnsMinBandNumberShort = tnsMinBandNumberShort[fsIndex];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*****************************************************/
|
||||
/* TnsEncode: */
|
||||
/*****************************************************/
|
||||
void TnsEncode(TnsInfo* tnsInfo, /* TNS info */
|
||||
int numberOfBands, /* Number of bands per window */
|
||||
int maxSfb, /* max_sfb */
|
||||
enum WINDOW_TYPE blockType, /* block type */
|
||||
int* sfbOffsetTable, /* Scalefactor band offset table */
|
||||
double* spec) /* Spectral data array */
|
||||
{
|
||||
int numberOfWindows,windowSize;
|
||||
int startBand,stopBand,order; /* Bands over which to apply TNS */
|
||||
int lengthInBands; /* Length to filter, in bands */
|
||||
int w;
|
||||
int startIndex,length;
|
||||
double gain;
|
||||
|
||||
switch( blockType ) {
|
||||
case ONLY_SHORT_WINDOW :
|
||||
|
||||
/* TNS not used for short blocks currently */
|
||||
tnsInfo->tnsDataPresent = 0;
|
||||
return;
|
||||
|
||||
numberOfWindows = MAX_SHORT_WINDOWS;
|
||||
windowSize = BLOCK_LEN_SHORT;
|
||||
startBand = tnsInfo->tnsMinBandNumberShort;
|
||||
stopBand = numberOfBands;
|
||||
lengthInBands = stopBand-startBand;
|
||||
order = tnsInfo->tnsMaxOrderShort;
|
||||
startBand = min(startBand,tnsInfo->tnsMaxBandsShort);
|
||||
stopBand = min(stopBand,tnsInfo->tnsMaxBandsShort);
|
||||
break;
|
||||
|
||||
default:
|
||||
numberOfWindows = 1;
|
||||
windowSize = BLOCK_LEN_SHORT;
|
||||
startBand = tnsInfo->tnsMinBandNumberLong;
|
||||
stopBand = numberOfBands;
|
||||
lengthInBands = stopBand - startBand;
|
||||
order = tnsInfo->tnsMaxOrderLong;
|
||||
startBand = min(startBand,tnsInfo->tnsMaxBandsLong);
|
||||
stopBand = min(stopBand,tnsInfo->tnsMaxBandsLong);
|
||||
break;
|
||||
}
|
||||
|
||||
/* Make sure that start and stop bands < maxSfb */
|
||||
/* Make sure that start and stop bands >= 0 */
|
||||
startBand = min(startBand,maxSfb);
|
||||
stopBand = min(stopBand,maxSfb);
|
||||
startBand = max(startBand,0);
|
||||
stopBand = max(stopBand,0);
|
||||
|
||||
tnsInfo->tnsDataPresent = 0; /* default TNS not used */
|
||||
|
||||
/* Perform analysis and filtering for each window */
|
||||
for (w=0;w<numberOfWindows;w++) {
|
||||
|
||||
TnsWindowData* windowData = &tnsInfo->windowData[w];
|
||||
TnsFilterData* tnsFilter = windowData->tnsFilter;
|
||||
double* k = tnsFilter->kCoeffs; /* reflection coeffs */
|
||||
double* a = tnsFilter->aCoeffs; /* prediction coeffs */
|
||||
|
||||
windowData->numFilters=0;
|
||||
windowData->coefResolution = DEF_TNS_COEFF_RES;
|
||||
startIndex = w * windowSize + sfbOffsetTable[startBand];
|
||||
length = sfbOffsetTable[stopBand] - sfbOffsetTable[startBand];
|
||||
gain = LevinsonDurbin(order,length,&spec[startIndex],k);
|
||||
|
||||
if (gain>DEF_TNS_GAIN_THRESH) { /* Use TNS */
|
||||
int truncatedOrder;
|
||||
windowData->numFilters++;
|
||||
tnsInfo->tnsDataPresent=1;
|
||||
tnsFilter->direction = 0;
|
||||
tnsFilter->coefCompress = 0;
|
||||
tnsFilter->length = lengthInBands;
|
||||
QuantizeReflectionCoeffs(order,DEF_TNS_COEFF_RES,k,tnsFilter->index);
|
||||
truncatedOrder = TruncateCoeffs(order,DEF_TNS_COEFF_THRESH,k);
|
||||
tnsFilter->order = truncatedOrder;
|
||||
StepUp(truncatedOrder,k,a); /* Compute predictor coefficients */
|
||||
TnsInvFilter(length,&spec[startIndex],tnsFilter); /* Filter */
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*****************************************************/
|
||||
/* TnsEncodeFilterOnly: */
|
||||
/* This is a stripped-down version of TnsEncode() */
|
||||
/* which performs TNS analysis filtering only */
|
||||
/*****************************************************/
|
||||
void TnsEncodeFilterOnly(TnsInfo* tnsInfo, /* TNS info */
|
||||
int numberOfBands, /* Number of bands per window */
|
||||
int maxSfb, /* max_sfb */
|
||||
enum WINDOW_TYPE blockType, /* block type */
|
||||
int* sfbOffsetTable, /* Scalefactor band offset table */
|
||||
double* spec) /* Spectral data array */
|
||||
{
|
||||
int numberOfWindows,windowSize;
|
||||
int startBand,stopBand; /* Bands over which to apply TNS */
|
||||
int w;
|
||||
int startIndex,length;
|
||||
|
||||
switch( blockType ) {
|
||||
case ONLY_SHORT_WINDOW :
|
||||
numberOfWindows = MAX_SHORT_WINDOWS;
|
||||
windowSize = BLOCK_LEN_SHORT;
|
||||
startBand = tnsInfo->tnsMinBandNumberShort;
|
||||
stopBand = numberOfBands;
|
||||
startBand = min(startBand,tnsInfo->tnsMaxBandsShort);
|
||||
stopBand = min(stopBand,tnsInfo->tnsMaxBandsShort);
|
||||
break;
|
||||
|
||||
default:
|
||||
numberOfWindows = 1;
|
||||
windowSize = BLOCK_LEN_LONG;
|
||||
startBand = tnsInfo->tnsMinBandNumberLong;
|
||||
stopBand = numberOfBands;
|
||||
startBand = min(startBand,tnsInfo->tnsMaxBandsLong);
|
||||
stopBand = min(stopBand,tnsInfo->tnsMaxBandsLong);
|
||||
break;
|
||||
}
|
||||
|
||||
/* Make sure that start and stop bands < maxSfb */
|
||||
/* Make sure that start and stop bands >= 0 */
|
||||
startBand = min(startBand,maxSfb);
|
||||
stopBand = min(stopBand,maxSfb);
|
||||
startBand = max(startBand,0);
|
||||
stopBand = max(stopBand,0);
|
||||
|
||||
|
||||
/* Perform filtering for each window */
|
||||
for(w=0;w<numberOfWindows;w++)
|
||||
{
|
||||
TnsWindowData* windowData = &tnsInfo->windowData[w];
|
||||
TnsFilterData* tnsFilter = windowData->tnsFilter;
|
||||
|
||||
startIndex = w * windowSize + sfbOffsetTable[startBand];
|
||||
length = sfbOffsetTable[stopBand] - sfbOffsetTable[startBand];
|
||||
|
||||
if (tnsInfo->tnsDataPresent && windowData->numFilters) { /* Use TNS */
|
||||
TnsInvFilter(length,&spec[startIndex],tnsFilter);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*****************************************************/
|
||||
/* TnsDecodeFilterOnly: */
|
||||
/* This is a stripped-down version of TnsEncode() */
|
||||
/* which performs TNS synthesis filtering only */
|
||||
/*****************************************************/
|
||||
void TnsDecodeFilterOnly(TnsInfo* tnsInfo, /* TNS info */
|
||||
int numberOfBands, /* Number of bands per window */
|
||||
int maxSfb, /* max_sfb */
|
||||
enum WINDOW_TYPE blockType, /* block type */
|
||||
int* sfbOffsetTable, /* Scalefactor band offset table */
|
||||
double* spec) /* Spectral data array */
|
||||
{
|
||||
int numberOfWindows,windowSize;
|
||||
int startBand,stopBand; /* Bands over which to apply TNS */
|
||||
int w;
|
||||
int startIndex,length;
|
||||
|
||||
switch( blockType ) {
|
||||
case ONLY_SHORT_WINDOW :
|
||||
numberOfWindows = MAX_SHORT_WINDOWS;
|
||||
windowSize = BLOCK_LEN_SHORT;
|
||||
startBand = tnsInfo->tnsMinBandNumberShort;
|
||||
stopBand = numberOfBands;
|
||||
startBand = min(startBand,tnsInfo->tnsMaxBandsShort);
|
||||
stopBand = min(stopBand,tnsInfo->tnsMaxBandsShort);
|
||||
break;
|
||||
|
||||
default:
|
||||
numberOfWindows = 1;
|
||||
windowSize = BLOCK_LEN_LONG;
|
||||
startBand = tnsInfo->tnsMinBandNumberLong;
|
||||
stopBand = numberOfBands;
|
||||
startBand = min(startBand,tnsInfo->tnsMaxBandsLong);
|
||||
stopBand = min(stopBand,tnsInfo->tnsMaxBandsLong);
|
||||
break;
|
||||
}
|
||||
|
||||
/* Make sure that start and stop bands < maxSfb */
|
||||
/* Make sure that start and stop bands >= 0 */
|
||||
startBand = min(startBand,maxSfb);
|
||||
stopBand = min(stopBand,maxSfb);
|
||||
startBand = max(startBand,0);
|
||||
stopBand = max(stopBand,0);
|
||||
|
||||
|
||||
/* Perform filtering for each window */
|
||||
for(w=0;w<numberOfWindows;w++)
|
||||
{
|
||||
TnsWindowData* windowData = &tnsInfo->windowData[w];
|
||||
TnsFilterData* tnsFilter = windowData->tnsFilter;
|
||||
|
||||
startIndex = w * windowSize + sfbOffsetTable[startBand];
|
||||
length = sfbOffsetTable[stopBand] - sfbOffsetTable[startBand];
|
||||
|
||||
if (tnsInfo->tnsDataPresent && windowData->numFilters) { /* Use TNS */
|
||||
TnsFilter(length,&spec[startIndex],tnsFilter);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*****************************************************/
|
||||
/* TnsFilter: */
|
||||
/* Filter the given spec with specified length */
|
||||
/* using the coefficients specified in filter. */
|
||||
/* Not that the order and direction are specified */
|
||||
/* withing the TNS_FILTER_DATA structure. */
|
||||
/*****************************************************/
|
||||
static void TnsFilter(int length,double* spec,TnsFilterData* filter)
|
||||
{
|
||||
int i,j,k=0;
|
||||
int order=filter->order;
|
||||
double* a=filter->aCoeffs;
|
||||
|
||||
/* Determine loop parameters for given direction */
|
||||
if (filter->direction) {
|
||||
|
||||
/* Startup, initial state is zero */
|
||||
for (i=length-2;i>(length-1-order);i--) {
|
||||
k++;
|
||||
for (j=1;j<=k;j++) {
|
||||
spec[i]-=spec[i+j]*a[j];
|
||||
}
|
||||
}
|
||||
|
||||
/* Now filter completely inplace */
|
||||
for (i=length-1-order;i>=0;i--) {
|
||||
for (j=1;j<=order;j++) {
|
||||
spec[i]-=spec[i+j]*a[j];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
} else {
|
||||
|
||||
/* Startup, initial state is zero */
|
||||
for (i=1;i<order;i++) {
|
||||
for (j=1;j<=i;j++) {
|
||||
spec[i]-=spec[i-j]*a[j];
|
||||
}
|
||||
}
|
||||
|
||||
/* Now filter completely inplace */
|
||||
for (i=order;i<length;i++) {
|
||||
for (j=1;j<=order;j++) {
|
||||
spec[i]-=spec[i-j]*a[j];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/********************************************************/
|
||||
/* TnsInvFilter: */
|
||||
/* Inverse filter the given spec with specified */
|
||||
/* length using the coefficients specified in filter. */
|
||||
/* Not that the order and direction are specified */
|
||||
/* withing the TNS_FILTER_DATA structure. */
|
||||
/********************************************************/
|
||||
static void TnsInvFilter(int length,double* spec,TnsFilterData* filter)
|
||||
{
|
||||
int i,j,k=0;
|
||||
int order=filter->order;
|
||||
double* a=filter->aCoeffs;
|
||||
double* temp;
|
||||
|
||||
temp = (double *)AllocMemory(length * sizeof (double));
|
||||
|
||||
/* Determine loop parameters for given direction */
|
||||
if (filter->direction) {
|
||||
|
||||
/* Startup, initial state is zero */
|
||||
temp[length-1]=spec[length-1];
|
||||
for (i=length-2;i>(length-1-order);i--) {
|
||||
temp[i]=spec[i];
|
||||
k++;
|
||||
for (j=1;j<=k;j++) {
|
||||
spec[i]+=temp[i+j]*a[j];
|
||||
}
|
||||
}
|
||||
|
||||
/* Now filter the rest */
|
||||
for (i=length-1-order;i>=0;i--) {
|
||||
temp[i]=spec[i];
|
||||
for (j=1;j<=order;j++) {
|
||||
spec[i]+=temp[i+j]*a[j];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
} else {
|
||||
|
||||
/* Startup, initial state is zero */
|
||||
temp[0]=spec[0];
|
||||
for (i=1;i<order;i++) {
|
||||
temp[i]=spec[i];
|
||||
for (j=1;j<=i;j++) {
|
||||
spec[i]+=temp[i-j]*a[j];
|
||||
}
|
||||
}
|
||||
|
||||
/* Now filter the rest */
|
||||
for (i=order;i<length;i++) {
|
||||
temp[i]=spec[i];
|
||||
for (j=1;j<=order;j++) {
|
||||
spec[i]+=temp[i-j]*a[j];
|
||||
}
|
||||
}
|
||||
}
|
||||
if (temp) FreeMemory(temp);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/*****************************************************/
|
||||
/* TruncateCoeffs: */
|
||||
/* Truncate the given reflection coeffs by zeroing */
|
||||
/* coefficients in the tail with absolute value */
|
||||
/* less than the specified threshold. Return the */
|
||||
/* truncated filter order. */
|
||||
/*****************************************************/
|
||||
static int TruncateCoeffs(int fOrder,double threshold,double* kArray)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = fOrder; i >= 0; i--) {
|
||||
kArray[i] = (fabs(kArray[i])>threshold) ? kArray[i] : 0.0;
|
||||
if (kArray[i]!=0.0) return i;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*****************************************************/
|
||||
/* QuantizeReflectionCoeffs: */
|
||||
/* Quantize the given array of reflection coeffs */
|
||||
/* to the specified resolution in bits. */
|
||||
/*****************************************************/
|
||||
static void QuantizeReflectionCoeffs(int fOrder,
|
||||
int coeffRes,
|
||||
double* kArray,
|
||||
int* indexArray)
|
||||
{
|
||||
double iqfac,iqfac_m;
|
||||
int i;
|
||||
|
||||
iqfac = ((1<<(coeffRes-1))-0.5)/(M_PI/2);
|
||||
iqfac_m = ((1<<(coeffRes-1))+0.5)/(M_PI/2);
|
||||
|
||||
/* Quantize and inverse quantize */
|
||||
for (i=1;i<=fOrder;i++) {
|
||||
indexArray[i] = (int)(0.5+(asin(kArray[i])*((kArray[i]>=0)?iqfac:iqfac_m)));
|
||||
kArray[i] = sin((double)indexArray[i]/((indexArray[i]>=0)?iqfac:iqfac_m));
|
||||
}
|
||||
}
|
||||
|
||||
/*****************************************************/
|
||||
/* Autocorrelation, */
|
||||
/* Compute the autocorrelation function */
|
||||
/* estimate for the given data. */
|
||||
/*****************************************************/
|
||||
static void Autocorrelation(int maxOrder, /* Maximum autocorr order */
|
||||
int dataSize, /* Size of the data array */
|
||||
double* data, /* Data array */
|
||||
double* rArray) /* Autocorrelation array */
|
||||
{
|
||||
int order,index;
|
||||
|
||||
for (order=0;order<=maxOrder;order++) {
|
||||
rArray[order]=0.0;
|
||||
for (index=0;index<dataSize;index++) {
|
||||
rArray[order]+=data[index]*data[index+order];
|
||||
}
|
||||
dataSize--;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*****************************************************/
|
||||
/* LevinsonDurbin: */
|
||||
/* Compute the reflection coefficients for the */
|
||||
/* given data using LevinsonDurbin recursion. */
|
||||
/* Return the prediction gain. */
|
||||
/*****************************************************/
|
||||
static double LevinsonDurbin(int fOrder, /* Filter order */
|
||||
int dataSize, /* Size of the data array */
|
||||
double* data, /* Data array */
|
||||
double* kArray) /* Reflection coeff array */
|
||||
{
|
||||
int order,i;
|
||||
double signal;
|
||||
double error, kTemp; /* Prediction error */
|
||||
double aArray1[TNS_MAX_ORDER+1]; /* Predictor coeff array */
|
||||
double aArray2[TNS_MAX_ORDER+1]; /* Predictor coeff array 2 */
|
||||
double rArray[TNS_MAX_ORDER+1]; /* Autocorrelation coeffs */
|
||||
double* aPtr = aArray1; /* Ptr to aArray1 */
|
||||
double* aLastPtr = aArray2; /* Ptr to aArray2 */
|
||||
double* aTemp;
|
||||
|
||||
/* Compute autocorrelation coefficients */
|
||||
Autocorrelation(fOrder,dataSize,data,rArray);
|
||||
signal=rArray[0]; /* signal energy */
|
||||
|
||||
/* Set up pointers to current and last iteration */
|
||||
/* predictor coefficients. */
|
||||
aPtr = aArray1;
|
||||
aLastPtr = aArray2;
|
||||
/* If there is no signal energy, return */
|
||||
if (!signal) {
|
||||
kArray[0]=1.0;
|
||||
for (order=1;order<=fOrder;order++) {
|
||||
kArray[order]=0.0;
|
||||
}
|
||||
return 0;
|
||||
|
||||
} else {
|
||||
|
||||
/* Set up first iteration */
|
||||
kArray[0]=1.0;
|
||||
aPtr[0]=1.0; /* Ptr to predictor coeffs, current iteration*/
|
||||
aLastPtr[0]=1.0; /* Ptr to predictor coeffs, last iteration */
|
||||
error=rArray[0];
|
||||
|
||||
/* Now perform recursion */
|
||||
for (order=1;order<=fOrder;order++) {
|
||||
kTemp = aLastPtr[0]*rArray[order-0];
|
||||
for (i=1;i<order;i++) {
|
||||
kTemp += aLastPtr[i]*rArray[order-i];
|
||||
}
|
||||
kTemp = -kTemp/error;
|
||||
kArray[order]=kTemp;
|
||||
aPtr[order]=kTemp;
|
||||
for (i=1;i<order;i++) {
|
||||
aPtr[i] = aLastPtr[i] + kTemp*aLastPtr[order-i];
|
||||
}
|
||||
error = error * (1 - kTemp*kTemp);
|
||||
|
||||
/* Now make current iteration the last one */
|
||||
aTemp=aLastPtr;
|
||||
aLastPtr=aPtr; /* Current becomes last */
|
||||
aPtr=aTemp; /* Last becomes current */
|
||||
}
|
||||
return signal/error; /* return the gain */
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*****************************************************/
|
||||
/* StepUp: */
|
||||
/* Convert reflection coefficients into */
|
||||
/* predictor coefficients. */
|
||||
/*****************************************************/
|
||||
static void StepUp(int fOrder,double* kArray,double* aArray)
|
||||
{
|
||||
double aTemp[TNS_MAX_ORDER+2];
|
||||
int i,order;
|
||||
|
||||
aArray[0]=1.0;
|
||||
aTemp[0]=1.0;
|
||||
for (order=1;order<=fOrder;order++) {
|
||||
aArray[order]=0.0;
|
||||
for (i=1;i<=order;i++) {
|
||||
aTemp[i] = aArray[i] + kArray[order]*aArray[order-i];
|
||||
}
|
||||
for (i=1;i<=order;i++) {
|
||||
aArray[i]=aTemp[i];
|
||||
}
|
||||
}
|
||||
}
|
50
external/libfaac/libfaac/tns.h
vendored
Normal file
50
external/libfaac/libfaac/tns.h
vendored
Normal file
|
@ -0,0 +1,50 @@
|
|||
/**********************************************************************
|
||||
|
||||
This software module was originally developed by
|
||||
and edited by Texas Instruments in the course of
|
||||
development of the MPEG-2 NBC/MPEG-4 Audio standard
|
||||
ISO/IEC 13818-7, 14496-1,2 and 3. This software module is an
|
||||
implementation of a part of one or more MPEG-2 NBC/MPEG-4 Audio tools
|
||||
as specified by the MPEG-2 NBC/MPEG-4 Audio standard. ISO/IEC gives
|
||||
users of the MPEG-2 NBC/MPEG-4 Audio standards free license to this
|
||||
software module or modifications thereof for use in hardware or
|
||||
software products claiming conformance to the MPEG-2 NBC/ MPEG-4 Audio
|
||||
standards. Those intending to use this software module in hardware or
|
||||
software products are advised that this use may infringe existing
|
||||
patents. The original developer of this software module and his/her
|
||||
company, the subsequent editors and their companies, and ISO/IEC have
|
||||
no liability for use of this software module or modifications thereof
|
||||
in an implementation. Copyright is not released for non MPEG-2
|
||||
NBC/MPEG-4 Audio conforming products. The original developer retains
|
||||
full right to use the code for his/her own purpose, assign or donate
|
||||
the code to a third party and to inhibit third party from using the
|
||||
code for non MPEG-2 NBC/MPEG-4 Audio conforming products. This
|
||||
copyright notice must be included in all copies or derivative works.
|
||||
|
||||
Copyright (c) 1997.
|
||||
**********************************************************************/
|
||||
/*
|
||||
* $Id: tns.h,v 1.5 2003/11/24 18:08:28 knik Exp $
|
||||
*/
|
||||
|
||||
#ifndef TNS_H
|
||||
#define TNS_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif /* __cplusplus */
|
||||
|
||||
|
||||
void TnsInit(faacEncHandle hEncoder);
|
||||
void TnsEncode(TnsInfo* tnsInfo, int numberOfBands,int maxSfb,enum WINDOW_TYPE blockType,
|
||||
int* sfbOffsetTable,double* spec);
|
||||
void TnsEncodeFilterOnly(TnsInfo* tnsInfo, int numberOfBands, int maxSfb,
|
||||
enum WINDOW_TYPE blockType, int *sfbOffsetTable, double *spec);
|
||||
void TnsDecodeFilterOnly(TnsInfo* tnsInfo, int numberOfBands, int maxSfb,
|
||||
enum WINDOW_TYPE blockType, int *sfbOffsetTable, double *spec);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif /* __cplusplus */
|
||||
|
||||
#endif /* TNS_H */
|
95
external/libfaac/libfaac/util.c
vendored
Normal file
95
external/libfaac/libfaac/util.c
vendored
Normal file
|
@ -0,0 +1,95 @@
|
|||
/*
|
||||
* FAAC - Freeware Advanced Audio Coder
|
||||
* Copyright (C) 2001 Menno Bakker
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
* $Id: util.c,v 1.10 2005/02/02 07:56:33 sur Exp $
|
||||
*/
|
||||
|
||||
#include <math.h>
|
||||
|
||||
#include "util.h"
|
||||
#include "coder.h" // FRAME_LEN
|
||||
|
||||
/* Returns the sample rate index */
|
||||
int GetSRIndex(unsigned int sampleRate)
|
||||
{
|
||||
if (92017 <= sampleRate) return 0;
|
||||
if (75132 <= sampleRate) return 1;
|
||||
if (55426 <= sampleRate) return 2;
|
||||
if (46009 <= sampleRate) return 3;
|
||||
if (37566 <= sampleRate) return 4;
|
||||
if (27713 <= sampleRate) return 5;
|
||||
if (23004 <= sampleRate) return 6;
|
||||
if (18783 <= sampleRate) return 7;
|
||||
if (13856 <= sampleRate) return 8;
|
||||
if (11502 <= sampleRate) return 9;
|
||||
if (9391 <= sampleRate) return 10;
|
||||
|
||||
return 11;
|
||||
}
|
||||
|
||||
/* Returns the maximum bitrate per channel for that sampling frequency */
|
||||
unsigned int MaxBitrate(unsigned long sampleRate)
|
||||
{
|
||||
/*
|
||||
* Maximum of 6144 bit for a channel
|
||||
*/
|
||||
return (unsigned int)(6144.0 * (double)sampleRate/(double)FRAME_LEN + .5);
|
||||
}
|
||||
|
||||
/* Returns the minimum bitrate per channel for that sampling frequency */
|
||||
unsigned int MinBitrate()
|
||||
{
|
||||
return 8000;
|
||||
}
|
||||
|
||||
|
||||
/* Max prediction band for backward predictionas function of fs index */
|
||||
const int MaxPredSfb[] = { 33, 33, 38, 40, 40, 40, 41, 41, 37, 37, 37, 34, 0 };
|
||||
|
||||
int GetMaxPredSfb(int samplingRateIdx)
|
||||
{
|
||||
return MaxPredSfb[samplingRateIdx];
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* Calculate bit_allocation based on PE */
|
||||
unsigned int BitAllocation(double pe, int short_block)
|
||||
{
|
||||
double pew1;
|
||||
double pew2;
|
||||
double bit_allocation;
|
||||
|
||||
if (short_block) {
|
||||
pew1 = 0.6;
|
||||
pew2 = 24.0;
|
||||
} else {
|
||||
pew1 = 0.3;
|
||||
pew2 = 6.0;
|
||||
}
|
||||
bit_allocation = pew1 * pe + pew2 * sqrt(pe);
|
||||
bit_allocation = min(max(0.0, bit_allocation), 6144.0);
|
||||
|
||||
return (unsigned int)(bit_allocation+0.5);
|
||||
}
|
||||
|
||||
/* Returns the maximum bit reservoir size */
|
||||
unsigned int MaxBitresSize(unsigned long bitRate, unsigned long sampleRate)
|
||||
{
|
||||
return 6144 - (unsigned int)((double)bitRate/(double)sampleRate*(double)FRAME_LEN);
|
||||
}
|
59
external/libfaac/libfaac/util.h
vendored
Normal file
59
external/libfaac/libfaac/util.h
vendored
Normal file
|
@ -0,0 +1,59 @@
|
|||
/*
|
||||
* FAAC - Freeware Advanced Audio Coder
|
||||
* Copyright (C) 2001 Menno Bakker
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
* $Id: util.h,v 1.8 2003/12/20 04:32:48 stux Exp $
|
||||
*/
|
||||
|
||||
#ifndef UTIL_H
|
||||
#define UTIL_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif /* __cplusplus */
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <memory.h>
|
||||
|
||||
#ifndef max
|
||||
#define max(a, b) (((a) > (b)) ? (a) : (b))
|
||||
#endif
|
||||
#ifndef min
|
||||
#define min(a, b) (((a) < (b)) ? (a) : (b))
|
||||
#endif
|
||||
|
||||
#ifndef M_PI
|
||||
#define M_PI 3.14159265358979323846
|
||||
#endif
|
||||
|
||||
/* Memory functions */
|
||||
#define AllocMemory(size) malloc(size)
|
||||
#define FreeMemory(block) free(block)
|
||||
#define SetMemory(block, value, size) memset(block, value, size)
|
||||
|
||||
int GetSRIndex(unsigned int sampleRate);
|
||||
int GetMaxPredSfb(int samplingRateIdx);
|
||||
unsigned int MaxBitrate(unsigned long sampleRate);
|
||||
unsigned int MinBitrate();
|
||||
unsigned int MaxBitresSize(unsigned long bitRate, unsigned long sampleRate);
|
||||
unsigned int BitAllocation(double pe, int short_block);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif /* __cplusplus */
|
||||
|
||||
#endif /* UTIL_H */
|
8
external/libfaac/libfaac/version.h
vendored
Normal file
8
external/libfaac/libfaac/version.h
vendored
Normal file
|
@ -0,0 +1,8 @@
|
|||
#ifndef _VERSION_H_
|
||||
#define _VERSION_H_
|
||||
|
||||
#define FAAC_RELEASE 1
|
||||
|
||||
#define FAAC_VERSION "1.28"
|
||||
|
||||
#endif
|
46
external/libfaac/outDebug.h
vendored
Normal file
46
external/libfaac/outDebug.h
vendored
Normal file
|
@ -0,0 +1,46 @@
|
|||
|
||||
#ifndef _OUTDEBUG_H
|
||||
#define _OUTDEBUG_H
|
||||
|
||||
|
||||
|
||||
#define DBG_MSG_BUFF_SIZE 3000
|
||||
#define FILE_NAME "-EasyAACEncoder-"
|
||||
|
||||
#ifndef __linux__
|
||||
#include <Windows.h>
|
||||
#include <tchar.h>
|
||||
#include <mmsystem.h>
|
||||
|
||||
#define INFO_USE(fmt, ...) \
|
||||
{ \
|
||||
TCHAR traceBuffer[DBG_MSG_BUFF_SIZE]; \
|
||||
_stprintf_s(traceBuffer, _T(FILE_NAME) _T(" :INFO: ") _T(__FUNCTION__) _T("<%d>: ") _T(fmt) _T("\n"), __LINE__, ##__VA_ARGS__); \
|
||||
OutputDebugString(traceBuffer); \
|
||||
}
|
||||
|
||||
|
||||
#define INFO_CHOOSEUSE(fmt, ...) {INFO_USE(fmt, ##__VA_ARGS__);}
|
||||
|
||||
#define INFO_D(OUT,fmt, ...)\
|
||||
{ \
|
||||
if(OUT)\
|
||||
{\
|
||||
INFO_CHOOSEUSE(fmt, ##__VA_ARGS__);\
|
||||
}\
|
||||
}
|
||||
|
||||
#else
|
||||
#define INFO_D(OUT,fmt, ...)\
|
||||
{ \
|
||||
if(OUT)\
|
||||
{\
|
||||
printf(fmt, ##__VA_ARGS__);\
|
||||
}\
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
#define AAC_DEBUG 0
|
||||
|
||||
#endif
|
|
@ -18,8 +18,9 @@
|
|||
#include <map>
|
||||
#include <memory>
|
||||
#include <string>
|
||||
camera_report_event::camera_report_event(const std::string &fileName, const CameraType &cameraType)
|
||||
: mFileName(fileName), mCameraType(cameraType)
|
||||
camera_report_event::camera_report_event(const std::string &fileName, const CameraType &cameraType,
|
||||
const unsigned int &duration_ms)
|
||||
: mFileName(fileName), mCameraType(cameraType), mDuration_ms(duration_ms)
|
||||
{
|
||||
}
|
||||
void VKeyHalMonitor::KeyEventHappened(const std::string &keyName, const VirtualKeyEvent &event,
|
||||
|
@ -72,7 +73,7 @@ StatusCode VCameraTaskContext::TaskFinished(void)
|
|||
LogWarning("STATUS_CODE_VIRTUAL_FUNCTION.\n");
|
||||
return CreateStatusCode(STATUS_CODE_VIRTUAL_FUNCTION);
|
||||
}
|
||||
camera_task_param::camera_task_param(const CameraTaskType &cameraTask) : mCameraTask(cameraTask)
|
||||
camera_task_param::camera_task_param(const CameraTaskType &cameraTask) : mTaskType(cameraTask)
|
||||
{
|
||||
mVideoRecordingTimeMs = DEFAULT_VIDEO_RECORDING_TIME_MS;
|
||||
}
|
||||
|
@ -100,6 +101,11 @@ StatusCode VCameraHal::SetVideoStreamCallback(VideoStreamCallback callback)
|
|||
LogWarning("STATUS_CODE_VIRTUAL_FUNCTION.\n");
|
||||
return CreateStatusCode(STATUS_CODE_VIRTUAL_FUNCTION);
|
||||
}
|
||||
StatusCode VCameraHal::SetJpegEncodeCallback(JpegEncodeCallback callback)
|
||||
{
|
||||
LogWarning("STATUS_CODE_VIRTUAL_FUNCTION.\n");
|
||||
return CreateStatusCode(STATUS_CODE_VIRTUAL_FUNCTION);
|
||||
}
|
||||
void VSdCardHalMonitor::ReportEvent(const SdCardHalStatus &status)
|
||||
{
|
||||
LogWarning("STATUS_CODE_VIRTUAL_FUNCTION.\n");
|
||||
|
@ -133,6 +139,11 @@ StatusCode VSdCardHal::GetCapacity(unsigned long long &totalSizeMB, unsigned lon
|
|||
LogWarning("STATUS_CODE_VIRTUAL_FUNCTION.\n");
|
||||
return CreateStatusCode(STATUS_CODE_VIRTUAL_FUNCTION);
|
||||
}
|
||||
StatusCode VSdCardHal::FormatSDCard(void)
|
||||
{
|
||||
LogWarning("STATUS_CODE_VIRTUAL_FUNCTION.\n");
|
||||
return CreateStatusCode(STATUS_CODE_VIRTUAL_FUNCTION);
|
||||
}
|
||||
StatusCode IHalCpp::Init(void)
|
||||
{
|
||||
LogWarning("STATUS_CODE_VIRTUAL_FUNCTION.\n");
|
||||
|
|
|
@ -50,9 +50,10 @@ enum class CameraTaskType
|
|||
};
|
||||
typedef struct camera_report_event
|
||||
{
|
||||
camera_report_event(const std::string &fileName, const CameraType &cameraType);
|
||||
camera_report_event(const std::string &fileName, const CameraType &cameraType, const unsigned int &duration_ms);
|
||||
const std::string mFileName;
|
||||
const CameraType mCameraType;
|
||||
const unsigned int mDuration_ms;
|
||||
} CameraReportEvent;
|
||||
void CreateHalCppModule(void);
|
||||
void DestroyHalCppModule(void);
|
||||
|
@ -118,14 +119,13 @@ constexpr int DEFAULT_VIDEO_RECORDING_TIME_MS = 10 * 1000;
|
|||
typedef struct camera_task_param
|
||||
{
|
||||
camera_task_param(const CameraTaskType &cameraTask);
|
||||
const CameraTaskType mCameraTask;
|
||||
unsigned int mVideoRecordingTimeMs;
|
||||
const CameraTaskType mTaskType;
|
||||
unsigned int mVideoRecordingTimeMs; // TODO: delete?
|
||||
std::shared_ptr<VCameraTaskContext> mCtx;
|
||||
} CameraTaskParam;
|
||||
// using AudioStreamCallback = void (*)(const void *, const int, const unsigned long long);
|
||||
// using VideoStreamCallback = void (*)(const void *, const int, const unsigned long long);
|
||||
using AudioStreamCallback = std::function<void(const void *, const unsigned int &, const unsigned long long &)>;
|
||||
using VideoStreamCallback = std::function<void(const void *, const unsigned int &, const unsigned long long &)>;
|
||||
using JpegEncodeCallback = std::function<void(const void *, const unsigned int &, const unsigned long long &)>;
|
||||
class VCameraHal
|
||||
{
|
||||
public:
|
||||
|
@ -136,6 +136,7 @@ public:
|
|||
virtual StatusCode StopTask(void);
|
||||
virtual StatusCode SetAudioStreamCallback(AudioStreamCallback callback);
|
||||
virtual StatusCode SetVideoStreamCallback(VideoStreamCallback callback);
|
||||
virtual StatusCode SetJpegEncodeCallback(JpegEncodeCallback callback);
|
||||
};
|
||||
class VSdCardHalMonitor
|
||||
{
|
||||
|
@ -153,6 +154,7 @@ public:
|
|||
virtual SdCardHalStatus GetSdCardStatus(void);
|
||||
virtual StatusCode GetCapacity(unsigned long long &totalSizeMB, unsigned long long &freeSizeMB,
|
||||
unsigned long long &usedSizeMB);
|
||||
virtual StatusCode FormatSDCard(void);
|
||||
};
|
||||
class IHalCpp
|
||||
{
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user